From 42f26e543e071b8f64d2ce71b6b7dd40ba009a76 Mon Sep 17 00:00:00 2001 From: seancolyer Date: Sun, 13 Oct 2013 15:39:45 -0400 Subject: [PATCH] Work around key generation. We need to get the signature data-passing platform ironed out for things like certifying keypairs/user ids. --- resources/openpgp.js | 78 +- resources/openpgp.min.js | 10 +- src/crypto/crypto.js | 29 + src/openpgp.js | 12 + src/packet/secret_key.js | 19 +- src/packet/signature.js | 12 +- test/test-bundle.js | 20560 +++++++++++++++++++------------------ 7 files changed, 10723 insertions(+), 9997 deletions(-) diff --git a/resources/openpgp.js b/resources/openpgp.js index 9c9e59e2..ed06dfed 100644 --- a/resources/openpgp.js +++ b/resources/openpgp.js @@ -1329,7 +1329,7 @@ function openpgp_config() { keyserver: "keyserver.linux.it" // "pgp.mit.edu:11371" }; - this.versionstring = "OpenPGP.js v0.0.1.20131009"; + this.versionstring = "OpenPGP.js v0.0.1.20131013"; this.commentstring = "http://openpgpjs.org"; /** * Reads the config out of the HTML5 local storage @@ -4172,6 +4172,35 @@ module.exports = { } }, + generateMpi: function(algo, bits) { + var result = (function() { + switch (algo) { + case 'rsa_encrypt': + case 'rsa_encrypt_sign': + case 'rsa_sign': + //remember "publicKey" refers to the crypto/public_key dir + var rsa = new publicKey.rsa(); + var keyObject = rsa.generate(bits, "10001"); + var output = []; + output.push(keyObject.n); + output.push(keyObject.ee); + output.push(keyObject.d); + output.push(keyObject.p); + output.push(keyObject.q); + output.push(keyObject.u); + return output; + default: + throw new Error('Unsupported algorithm for key generation.'); + } + })(); + + return result.map(function(bn) { + var mpi = new type_mpi(); + mpi.fromBigInteger(bn); + return mpi; + }); + }, + /** * generate random byte prefix as string for the specified algorithm @@ -9138,6 +9167,7 @@ function openpgp_key() { var armor = require('./encoding/armor.js'); var packet = require('./packet'); var util = require('./util'); +var enums = require('./enums.js'); /** * GPG4Browsers Core interface. A single instance is hold @@ -9218,11 +9248,22 @@ function _openpgp() { var packetlist = new packet.list(); var secretKeyPacket = new packet.secret_key(); + secretKeyPacket.algorithm = enums.read(enums.publicKey, keyType); + secretKeyPacket.generate(numBits); + secretKeyPacket.encrypt(passphrase); + var userIdPacket = new packet.userid(); + userIdPacket.read(userId); + var signaturePacket = new packet.signature(); var secretSubkeyPacket = new packet.secret_subkey(); var overallSignaturePacket = new packet.signature(); + packetlist.push(secretKeyPacket); + packetlist.push(userIdPacket); + packetlist.push(signaturePacket); + packetlist.push(secretSubkeyPacket); + packetlist.push(overallSignaturePacket); } /** @@ -9415,7 +9456,7 @@ function _openpgp() { module.exports = new _openpgp(); -},{"./encoding/armor.js":24,"./packet":34,"./util":55}],30:[function(require,module,exports){ +},{"./encoding/armor.js":24,"./enums.js":26,"./packet":34,"./util":55}],30:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH // @@ -10943,7 +10984,7 @@ function packet_secret_key() { else return function(c) { return util.writeNumber(util.calc_checksum(c), 2); - } + }; } // Helper function @@ -11022,7 +11063,7 @@ function packet_secret_key() { this.algorithm)); } - } + }; /* * Creates an OpenPGP key packet for the given key. much @@ -11049,7 +11090,7 @@ function packet_secret_key() { } return bytes; - } + }; @@ -11074,10 +11115,8 @@ function packet_secret_key() { this.encrypted += s2k.write(); this.encrypted += iv; - - this.encrypted += crypto.cfb.normalEncrypt(symmetric, key, cleartext, iv); - } + }; function produceEncryptionKey(s2k, passphrase, algorithm) { return s2k.produce_key(passphrase, @@ -11144,12 +11183,11 @@ function packet_secret_key() { this.mpi = this.mpi.concat(parse_cleartext_mpi(hash, cleartext, this.algorithm)); - } + }; - this.generate = function(bits) { - this.mpi; - - } + this.generate = function(bits, passphrase) { + this.mpi = crypto.generateMpi(this.algorithm, bits); + }; } @@ -11577,7 +11615,7 @@ module.exports = function packet_signature() { // Produces data to produce signature on this.toSign = function(type, data) { - var t = enums.signature + var t = enums.signature; switch (type) { case t.binary: @@ -11589,7 +11627,7 @@ module.exports = function packet_signature() { .replace(/\n/g, '\r\n'); case t.standalone: - return '' + return ''; case t.cert_generic: case t.cert_persona: @@ -11599,19 +11637,17 @@ module.exports = function packet_signature() { { var packet, tag; - if (data.userid != undefined) { + if (data.userid !== undefined) { tag = 0xB4; packet = data.userid; - } else if (data.userattribute != undefined) { - tag = 0xD1 + } else if (data.userattribute !== undefined) { + tag = 0xD1; packet = data.userattribute; } else throw new Error('Either a userid or userattribute packet needs to be ' + 'supplied for certification.'); - var bytes = packet.write(); - return this.toSign(t.key, data) + String.fromCharCode(tag) + util.writeNumber(bytes.length, 4) + @@ -12811,5 +12847,5 @@ var Util = function() { */ module.exports = new Util(); -},{}]},{},[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55]) +},{}]},{},[1,2,3,4,5,6,7,8,9,10,11,13,14,12,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55]) ; \ No newline at end of file diff --git a/resources/openpgp.min.js b/resources/openpgp.min.js index aa5179a2..43e2d1c1 100644 --- a/resources/openpgp.min.js +++ b/resources/openpgp.min.js @@ -1,6 +1,6 @@ -/*! OpenPGPjs.org this is LGPL licensed code, see LICENSE/our website for more information.- v0.0.1 - 2013-10-09 */(function e(t,r,i){function n(o,a){if(!r[o]){if(!t[o]){var h="function"==typeof require&&require;if(!a&&h)return h(o,!0);if(s)return s(o,!0);throw Error("Cannot find module '"+o+"'")}var c=r[o]={exports:{}};t[o][0].call(c.exports,function(r){var e=t[o][1][r];return n(e?e:r)},c,c.exports,e,t,r,i)}return r[o].exports}for(var s="function"==typeof require&&require,o=0;i.length>o;o++)n(i[o]);return n})({1:[function(t,r){JXG={exists:function(t){return function(r){return!(r===t||null===r)}}()},JXG.decompress=function(t){return unescape(new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(t)).unzip()[0][0])},JXG.Util={},JXG.Util.Unzip=function(t){function r(){return D+=8,x.length>P?x[P++]:-1}function e(){N=1}function i(){var t;return D++,t=1&N,N>>=1,0==N&&(N=r(),t=1&N,N=128|N>>1),t}function n(t){for(var r=0,e=t;e--;)r=r<<1|i();return t&&(r=j[r]>>8-t),r}function s(){_=0}function o(t){y++,A[_++]=t,v.push(String.fromCharCode(t)),32768==_&&(_=0)}function a(){this.b0=0,this.b1=0,this.jump=null,this.jumppos=-1}function h(){for(;;){if(q[U]>=V)return-1;if(F[q[U]]==U)return q[U]++;q[U]++}}function c(){var t,r=z[L];if(w&&document.write("
len:"+U+" treepos:"+L),17==U)return-1;if(L++,U++,t=h(),w&&document.write("
IsPat "+t),t>=0)r.b0=t,w&&document.write("
b0 "+r.b0);else if(r.b0=32768,w&&document.write("
b0 "+r.b0),c())return-1;if(t=h(),t>=0)r.b1=t,w&&document.write("
b1 "+r.b1),r.jump=null;else if(r.b1=32768,w&&document.write("
b1 "+r.b1),r.jump=z[L],r.jumppos=L,c())return-1;return U--,0}function u(t,r,e,i){var n;for(w&&document.write("currentTree "+t+" numval "+r+" lengths "+e+" show "+i),z=t,L=0,F=e,V=r,n=0;17>n;n++)q[n]=0;if(U=0,c())return w&&alert("invalid huffman tree\n"),-1;if(w){document.write("
Tree: "+z.length);for(var s=0;32>s;s++)document.write("Places["+s+"].b0="+z[s].b0+"
"),document.write("Places["+s+"].b1="+z[s].b1+"
")}return 0}function p(t){for(var r,e,n,s=0,o=t[s];;)if(n=i(),w&&document.write("b="+n),n){if(!(32768&o.b1))return w&&document.write("ret1"),o.b1;for(o=o.jump,r=t.length,e=0;r>e;e++)if(t[e]===o){s=e;break}}else{if(!(32768&o.b0))return w&&document.write("ret2"),o.b0;s++,o=t[s]}return w&&document.write("ret3"),-1}function l(){var t,h,c,l,f;do{switch(t=i(),c=n(2)){case 0:w&&alert("Stored\n");break;case 1:w&&alert("Fixed Huffman codes\n");break;case 2:w&&alert("Dynamic Huffman codes\n");break;case 3:w&&alert("Reserved block type!!\n");break;default:w&&alert("Unexpected value %d!\n",c)}if(0==c){var d,g;for(e(),d=r(),d|=r()<<8,g=r(),g|=r()<<8,65535&(d^~g)&&document.write("BlockLen checksum mismatch\n");d--;)h=r(),o(h)}else if(1==c)for(var m;;)if(m=j[n(7)]>>1,m>23?(m=m<<1|i(),m>199?(m-=128,m=m<<1|i()):(m-=48,m>143&&(m+=136))):m+=256,256>m)o(m);else{if(256==m)break;var f,y;for(m-=257,f=n(O[m])+T[m],m=j[n(5)]>>3,I[m]>8?(y=n(8),y|=n(I[m]-8)<<8):y=n(I[m]),y+=E[m],m=0;f>m;m++){var h=A[32767&_-y];o(h)}}else if(2==c){var m,b,v,k,C,S=Array(320);for(v=257+n(5),k=1+n(5),C=4+n(4),m=0;19>m;m++)S[m]=0;for(m=0;C>m;m++)S[B[m]]=n(3);for(f=H.length,l=0;f>l;l++)H[l]=new a;if(u(H,19,S,0))return s(),1;if(w){document.write("
distanceTree");for(var x=0;H.length>x;x++)document.write("
"+H[x].b0+" "+H[x].b1+" "+H[x].jump+" "+H[x].jumppos)}b=v+k,l=0;var P=-1;for(w&&document.write("
n="+b+" bits: "+D+"
");b>l;)if(P++,m=p(H),w&&document.write("
"+P+" i:"+l+" decode: "+m+" bits "+D+"
"),16>m)S[l++]=m;else if(16==m){var N;if(m=3+n(2),l+m>b)return s(),1;for(N=l?S[l-1]:0;m--;)S[l++]=N}else{if(m=17==m?3+n(3):11+n(7),l+m>b)return s(),1;for(;m--;)S[l++]=0}for(f=G.length,l=0;f>l;l++)G[l]=new a;if(u(G,v,S,0))return s(),1;for(f=G.length,l=0;f>l;l++)H[l]=new a;var K=[];for(l=v;S.length>l;l++)K[l-v]=S[l];if(u(H,k,K,0))return s(),1;w&&document.write("
literalTree");t:for(;;)if(m=p(G),m>=256){var f,y;if(m-=256,0==m)break;for(m--,f=n(O[m])+T[m],m=p(H),I[m]>8?(y=n(8),y|=n(I[m]-8)<<8):y=n(I[m]),y+=E[m];f--;){if(0>_-y)break t;var h=A[32767&_-y];o(h)}}else o(m)}}while(!t);return s(),e(),0}function f(){w&&alert("NEXTFILE"),v=[];var t=[];if(S=!1,t[0]=r(),t[1]=r(),w&&alert("type: "+t[0]+" "+t[1]),t[0]==parseInt("78",16)&&t[1]==parseInt("da",16)&&(w&&alert("GEONExT-GZIP"),l(),w&&alert(v.join("")),C[k]=Array(2),C[k][0]=v.join(""),C[k][1]="geonext.gxt",k++),t[0]==parseInt("78",16)&&t[1]==parseInt("9c",16)&&(w&&alert("ZLIB"),l(),w&&alert(v.join("")),C[k]=Array(2),C[k][0]=v.join(""),C[k][1]="ZLIB",k++),t[0]==parseInt("1f",16)&&t[1]==parseInt("8b",16)&&(w&&alert("GZIP"),d(),w&&alert(v.join("")),C[k]=Array(2),C[k][0]=v.join(""),C[k][1]="file",k++),t[0]==parseInt("50",16)&&t[1]==parseInt("4b",16)&&(S=!0,t[2]=r(),t[3]=r(),t[2]==parseInt("3",16)&&t[3]==parseInt("4",16))){t[0]=r(),t[1]=r(),w&&alert("ZIP-Version: "+t[1]+" "+t[0]/10+"."+t[0]%10),g=r(),g|=r()<<8,w&&alert("gpflags: "+g);var e=r();e|=r()<<8,w&&alert("method: "+e),r(),r(),r(),r();var i=r();i|=r()<<8,i|=r()<<16,i|=r()<<24;var n=r();n|=r()<<8,n|=r()<<16,n|=r()<<24;var s=r();s|=r()<<8,s|=r()<<16,s|=r()<<24,w&&alert("local CRC: "+i+"\nlocal Size: "+s+"\nlocal CompSize: "+n);var o=r();o|=r()<<8;var a=r();for(a|=r()<<8,w&&alert("filelen "+o),c=0,M=[];o--;){var h=r();"/"==h|":"==h?c=0:K-1>c&&(M[c++]=String.fromCharCode(h))}w&&alert("nameBuf: "+M),b||(b=M);for(var c=0;a>c;)h=r(),c++;m=4294967295,y=0,(s=0)&&w&&alert("skipdir"),8==e&&(l(),w&&alert(v.join("")),C[k]=Array(2),C[k][0]=v.join(""),C[k][1]=M.join(""),k++),d()}}function d(){var t,e,i,n,s,o,a=[];if(8&g&&(a[0]=r(),a[1]=r(),a[2]=r(),a[3]=r(),a[0]==parseInt("50",16)&&a[1]==parseInt("4b",16)&&a[2]==parseInt("07",16)&&a[3]==parseInt("08",16)?(t=r(),t|=r()<<8,t|=r()<<16,t|=r()<<24):t=a[0]|a[1]<<8|a[2]<<16|a[3]<<24,e=r(),e|=r()<<8,e|=r()<<16,e|=r()<<24,i=r(),i|=r()<<8,i|=r()<<16,i|=r()<<24,w&&alert("CRC:")),S&&f(),a[0]=r(),8!=a[0])return w&&alert("Unknown compression method!"),0;if(g=r(),w&&g&~parseInt("1f",16)&&alert("Unknown flags set!"),r(),r(),r(),r(),r(),n=r(),4&g)for(a[0]=r(),a[2]=r(),U=a[0]+256*a[1],w&&alert("Extra field size: "+U),s=0;U>s;s++)r();if(8&g){for(s=0,M=[];o=r();)("7"==o||":"==o)&&(s=0),K-1>s&&(M[s++]=o);w&&alert("original file name: "+M)}if(16&g)for(;o=r(););2&g&&(r(),r()),l(),t=r(),t|=r()<<8,t|=r()<<16,t|=r()<<24,i=r(),i|=r()<<8,i|=r()<<16,i|=r()<<24,S&&f()}var g,m,y,b,v=[],w=!1,k=0,C=[],A=Array(32768),_=0,S=!1,j=[0,128,64,192,32,160,96,224,16,144,80,208,48,176,112,240,8,136,72,200,40,168,104,232,24,152,88,216,56,184,120,248,4,132,68,196,36,164,100,228,20,148,84,212,52,180,116,244,12,140,76,204,44,172,108,236,28,156,92,220,60,188,124,252,2,130,66,194,34,162,98,226,18,146,82,210,50,178,114,242,10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250,6,134,70,198,38,166,102,230,22,150,86,214,54,182,118,246,14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254,1,129,65,193,33,161,97,225,17,145,81,209,49,177,113,241,9,137,73,201,41,169,105,233,25,153,89,217,57,185,121,249,5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245,13,141,77,205,45,173,109,237,29,157,93,221,61,189,125,253,3,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243,11,139,75,203,43,171,107,235,27,155,91,219,59,187,123,251,7,135,71,199,39,167,103,231,23,151,87,215,55,183,119,247,15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255],T=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],O=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,99,99],E=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],I=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],B=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],x=t,P=0,N=1,D=0,K=256,M=[],R=288,G=Array(R),H=Array(32),L=0,z=null;Array(64),Array(64);var U=0,q=Array(17);q[0]=0;var F,V;JXG.Util.Unzip.prototype.unzipFile=function(t){var r;for(this.unzip(),r=0;C.length>r;r++)if(C[r][1]==t)return C[r][0]},JXG.Util.Unzip.prototype.deflate=function(){return v=[],S=!1,l(),w&&alert(v.join("")),C[k]=Array(2),C[k][0]=v.join(""),C[k][1]="DEFLATE",k++,C},JXG.Util.Unzip.prototype.unzip=function(){return w&&alert(x),f(),C}},JXG.Util.Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(t){var r,e,i,n,s,o,a,h=[],c=0;for(t=JXG.Util.Base64._utf8_encode(t);t.length>c;)r=t.charCodeAt(c++),e=t.charCodeAt(c++),i=t.charCodeAt(c++),n=r>>2,s=(3&r)<<4|e>>4,o=(15&e)<<2|i>>6,a=63&i,isNaN(e)?o=a=64:isNaN(i)&&(a=64),h.push([this._keyStr.charAt(n),this._keyStr.charAt(s),this._keyStr.charAt(o),this._keyStr.charAt(a)].join(""));return h.join("")},decode:function(t,r){var e,i,n,s,o,a,h,c=[],u=0;for(t=t.replace(/[^A-Za-z0-9\+\/\=]/g,"");t.length>u;)s=this._keyStr.indexOf(t.charAt(u++)),o=this._keyStr.indexOf(t.charAt(u++)),a=this._keyStr.indexOf(t.charAt(u++)),h=this._keyStr.indexOf(t.charAt(u++)),e=s<<2|o>>4,i=(15&o)<<4|a>>2,n=(3&a)<<6|h,c.push(String.fromCharCode(e)),64!=a&&c.push(String.fromCharCode(i)),64!=h&&c.push(String.fromCharCode(n));return c=c.join(""),r&&(c=JXG.Util.Base64._utf8_decode(c)),c},_utf8_encode:function(t){t=t.replace(/\r\n/g,"\n");for(var r="",e=0;t.length>e;e++){var i=t.charCodeAt(e);128>i?r+=String.fromCharCode(i):i>127&&2048>i?(r+=String.fromCharCode(192|i>>6),r+=String.fromCharCode(128|63&i)):(r+=String.fromCharCode(224|i>>12),r+=String.fromCharCode(128|63&i>>6),r+=String.fromCharCode(128|63&i))}return r},_utf8_decode:function(t){for(var r=[],e=0,i=0,n=0,s=0;t.length>e;)i=t.charCodeAt(e),128>i?(r.push(String.fromCharCode(i)),e++):i>191&&224>i?(n=t.charCodeAt(e+1),r.push(String.fromCharCode((31&i)<<6|63&n)),e+=2):(n=t.charCodeAt(e+1),s=t.charCodeAt(e+2),r.push(String.fromCharCode((15&i)<<12|(63&n)<<6|63&s)),e+=3);return r.join("")},_destrip:function(t,r){var e,i,n=[],s=[];for(null==r&&(r=76),t.replace(/ /g,""),e=t.length/r,i=0;e>i;i++)n[i]=t.substr(i*r,r);for(e!=t.length/r&&(n[n.length]=t.substr(e*r,t.length-e*r)),i=0;n.length>i;i++)s.push(n[i]);return s.join("\n")},decodeAsArray:function(t){var r,e=this.decode(t),i=[];for(r=0;e.length>r;r++)i[r]=e.charCodeAt(r);return i},decodeGEONExT:function(t){return decodeAsArray(destrip(t),!1)}},JXG.Util.asciiCharCodeAt=function(t,r){var e=t.charCodeAt(r);if(e>255)switch(e){case 8364:e=128;break;case 8218:e=130;break;case 402:e=131;break;case 8222:e=132;break;case 8230:e=133;break;case 8224:e=134;break;case 8225:e=135;break;case 710:e=136;break;case 8240:e=137;break;case 352:e=138;break;case 8249:e=139;break;case 338:e=140;break;case 381:e=142;break;case 8216:e=145;break;case 8217:e=146;break;case 8220:e=147;break;case 8221:e=148;break;case 8226:e=149;break;case 8211:e=150;break;case 8212:e=151;break;case 732:e=152;break;case 8482:e=153;break;case 353:e=154;break;case 8250:e=155;break;case 339:e=156;break;case 382:e=158;break;case 376:e=159;break;default:}return e},JXG.Util.utf8Decode=function(t){var r,e=[],i=0,n=0,s=0;if(!JXG.exists(t))return"";for(;t.length>i;)n=t.charCodeAt(i),128>n?(e.push(String.fromCharCode(n)),i++):n>191&&224>n?(s=t.charCodeAt(i+1),e.push(String.fromCharCode((31&n)<<6|63&s)),i+=2):(s=t.charCodeAt(i+1),r=t.charCodeAt(i+2),e.push(String.fromCharCode((15&n)<<12|(63&s)<<6|63&r)),i+=3);return e.join("")},JXG.Util.genUUID=function(){for(var t,r="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=Array(36),i=0,n=0;36>n;n++)8==n||13==n||18==n||23==n?e[n]="-":14==n?e[n]="4":(2>=i&&(i=0|33554432+16777216*Math.random()),t=15&i,i>>=4,e[n]=r[19==n?8|3&t:t]);return e.join("")},r.exports=JXG},{}],2:[function(){},{}],3:[function(t,r){var e=t("../util"),i=t("./cipher");r.exports={encrypt:function(t,r,s,o,a){r=new i[r](o);var h=r.blockSize,c=Array(h),u=Array(h);t=t+t.charAt(h-2)+t.charAt(h-1),e.print_debug("prefixrandom:"+e.hexstrdump(t));for(var p="",l=0;h>l;l++)c[l]=0;u=r.encrypt(c);for(var l=0;h>l;l++)p+=String.fromCharCode(u[l]^t.charCodeAt(l));for(var l=0;h>l;l++)c[l]=p.charCodeAt(l);if(u=r.encrypt(c),p+=String.fromCharCode(u[0]^t.charCodeAt(h)),p+=String.fromCharCode(u[1]^t.charCodeAt(h+1)),a)for(var l=0;h>l;l++)c[l]=p.charCodeAt(l+2);else for(var l=0;h>l;l++)c[l]=p.charCodeAt(l);if(u=r.encrypt(c,o),a){for(var l=0;h>l;l++)p+=String.fromCharCode(u[l]^s.charCodeAt(l));for(n=h+2;s.length>n;n+=h){for(var l=0;h>l;l++)c[l]=p.charCodeAt(n+l);u=r.encrypt(c);for(var l=0;h>l;l++)p+=String.fromCharCode(u[l]^s.charCodeAt(n-2+l))}}else{s=" "+s;for(var l=2;h>l;l++)p+=String.fromCharCode(u[l]^s.charCodeAt(l));var f=p.substring(0,2*h).split(""),d=p.substring(h);for(n=h;s.length>n;n+=h){for(var l=0;h>l;l++)c[l]=d.charCodeAt(l);d="",u=r.encrypt(c);for(var l=0;h>l;l++)f.push(String.fromCharCode(u[l]^s.charCodeAt(n+l))),d+=String.fromCharCode(u[l]^s.charCodeAt(n+l))}p=f.join("")}return p=p.substring(0,s.length+2+h)},mdc:function(t,r,n){t=new i[t](r);var s,o=t.blockSize,a=Array(o),h=Array(o);for(s=0;o>s;s++)a[s]=0;for(a=t.encrypt(a),s=0;o>s;s++)h[s]=n.charCodeAt(s),a[s]^=h[s];return h=t.encrypt(h),e.bin2str(a)+String.fromCharCode(h[0]^n.charCodeAt(o))+String.fromCharCode(h[1]^n.charCodeAt(o+1))},decrypt:function(t,r,e,n){t=new i[t](r);var s,o=t.blockSize,a=Array(o),h=Array(o),c="",u=[];for(s=0;o>s;s++)a[s]=0;for(a=t.encrypt(a,r),s=0;o>s;s++)h[s]=e.charCodeAt(s),a[s]^=h[s];if(h=t.encrypt(h,r),a[o-2]!=(h[0]^e.charCodeAt(o))||a[o-1]!=(h[1]^e.charCodeAt(o+1)))throw Error("Invalid data.");if(n){for(s=0;o>s;s++)a[s]=e.charCodeAt(s+2);for(c=o+2;e.length>c;c+=o)for(h=t.encrypt(a),s=0;o>s&&e.length>s+c;s++)a[s]=e.charCodeAt(c+s),u.push(String.fromCharCode(h[s]^a[s]))}else{for(s=0;o>s;s++)a[s]=e.charCodeAt(s);for(c=o;e.length>c;c+=o)for(h=t.encrypt(a),s=0;o>s&&e.length>s+c;s++)a[s]=e.charCodeAt(c+s),u.push(String.fromCharCode(h[s]^a[s]))}var c=n?0:2;return u=u.join(""),u=u.substring(c,e.length-o-2+c)},normalEncrypt:function(t,r,n,s){t=new i[t](r);var o=t.blockSize,a="",h="",c=0,u=[],p=[];for(h=s.substring(0,o);n.length>o*c;){var l=t.encrypt(e.str2bin(h));a=n.substring(c*o,c*o+o);for(var f=0;a.length>f;f++)p.push(String.fromCharCode(a.charCodeAt(f)^l[f]));h=p.join(""),p=[],u.push(h),c++}return u.join("")},normalDecrypt:function(t,r,n,s){t=new i[t](r);var o=t.blockSize,a="",h=0,c=[],u=0;if(null==s)for(var p=0;o>p;p++)a+=String.fromCharCode(0);else a=s.substring(0,o);for(;n.length>o*h;){var l=t.encrypt(e.str2bin(a));a=n.substring(h*o+u,h*o+o+u);for(var p=0;a.length>p;p++)c.push(String.fromCharCode(a.charCodeAt(p)^l[p]));h++}return c.join("")}}},{"../util":55,"./cipher":8}],4:[function(t,r){function e(t){return 255&t}function i(t){return 255&t>>8}function n(t){return 255&t>>16}function s(t){return 255&t>>24}function o(t,r,e,n){return i(g[255&t])|i(g[255&r>>8])<<8|i(g[255&e>>16])<<16|i(g[n>>>24])<<24}function a(t){var r,e,i=t.length,n=Array(i/4);if(t&&!(i%4)){for(r=0,e=0;i>e;e+=4)n[r++]=t[e]|t[e+1]<<8|t[e+2]<<16|t[e+3]<<24;return n}}function h(t){var r,o=0,a=t.length,h=Array(4*a);for(r=0;a>r;r++)h[o++]=e(t[r]),h[o++]=i(t[r]),h[o++]=n(t[r]),h[o++]=s(t[r]);return h}function c(t){var r,o,a,h,c,u,p=Array(w+1),g=t.length,m=Array(v),y=Array(v),b=0;if(16==g)u=10,r=4;else if(24==g)u=12,r=6;else{if(32!=g)return l.print_error("aes.js: Invalid key-length for AES key:"+g),void 0;u=14,r=8}for(o=0;w+1>o;o++)p[o]=Array(4);for(o=0,a=0;g>a;a++,o+=4)m[a]=t.charCodeAt(o)|t.charCodeAt(o+1)<<8|t.charCodeAt(o+2)<<16|t.charCodeAt(o+3)<<24;for(a=r-1;a>=0;a--)y[a]=m[a];for(h=0,c=0,a=0;r>a&&u+1>h;){for(;r>a&&4>c;a++,c++)p[h][c]=y[a];4==c&&(h++,c=0)}for(;u+1>h;){var k=y[r-1];if(y[0]^=d[i(k)]|d[n(k)]<<8|d[s(k)]<<16|d[e(k)]<<24,y[0]^=f[b++],8!=r)for(a=1;r>a;a++)y[a]^=y[a-1];else{for(a=1;r/2>a;a++)y[a]^=y[a-1];for(k=y[r/2-1],y[r/2]^=d[e(k)]|d[i(k)]<<8|d[n(k)]<<16|d[s(k)]<<24,a=r/2+1;r>a;a++)y[a]^=y[a-1]}for(a=0;r>a&&u+1>h;){for(;r>a&&4>c;a++,c++)p[h][c]=y[a];4==c&&(h++,c=0)}}return this.rounds=u,this.rk=p,this}function u(t,r){var e,i,n,s,c,u=a(t),p=r.rounds,l=u[0],f=u[1],d=u[2],v=u[3];for(e=0;p-1>e;e++)i=l^r.rk[e][0],n=f^r.rk[e][1],s=d^r.rk[e][2],c=v^r.rk[e][3],l=g[255&i]^m[255&n>>8]^y[255&s>>16]^b[c>>>24],f=g[255&n]^m[255&s>>8]^y[255&c>>16]^b[i>>>24],d=g[255&s]^m[255&c>>8]^y[255&i>>16]^b[n>>>24],v=g[255&c]^m[255&i>>8]^y[255&n>>16]^b[s>>>24];return e=p-1,i=l^r.rk[e][0],n=f^r.rk[e][1],s=d^r.rk[e][2],c=v^r.rk[e][3],u[0]=o(i,n,s,c)^r.rk[p][0],u[1]=o(n,s,c,i)^r.rk[p][1],u[2]=o(s,c,i,n)^r.rk[p][2],u[3]=o(c,i,n,s)^r.rk[p][3],h(u)}function p(t){var r=function(t){this.key=c(t),this.encrypt=function(t){return u(t,this.key)}};return r.blockSize=r.prototype.blockSize=16,r.keySize=r.prototype.keySize=t/8,r}var l=t("../../util"),f=[1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145],d=[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22],g=[2774754246,2222750968,2574743534,2373680118,234025727,3177933782,2976870366,1422247313,1345335392,50397442,2842126286,2099981142,436141799,1658312629,3870010189,2591454956,1170918031,2642575903,1086966153,2273148410,368769775,3948501426,3376891790,200339707,3970805057,1742001331,4255294047,3937382213,3214711843,4154762323,2524082916,1539358875,3266819957,486407649,2928907069,1780885068,1513502316,1094664062,49805301,1338821763,1546925160,4104496465,887481809,150073849,2473685474,1943591083,1395732834,1058346282,201589768,1388824469,1696801606,1589887901,672667696,2711000631,251987210,3046808111,151455502,907153956,2608889883,1038279391,652995533,1764173646,3451040383,2675275242,453576978,2659418909,1949051992,773462580,756751158,2993581788,3998898868,4221608027,4132590244,1295727478,1641469623,3467883389,2066295122,1055122397,1898917726,2542044179,4115878822,1758581177,0,753790401,1612718144,536673507,3367088505,3982187446,3194645204,1187761037,3653156455,1262041458,3729410708,3561770136,3898103984,1255133061,1808847035,720367557,3853167183,385612781,3309519750,3612167578,1429418854,2491778321,3477423498,284817897,100794884,2172616702,4031795360,1144798328,3131023141,3819481163,4082192802,4272137053,3225436288,2324664069,2912064063,3164445985,1211644016,83228145,3753688163,3249976951,1977277103,1663115586,806359072,452984805,250868733,1842533055,1288555905,336333848,890442534,804056259,3781124030,2727843637,3427026056,957814574,1472513171,4071073621,2189328124,1195195770,2892260552,3881655738,723065138,2507371494,2690670784,2558624025,3511635870,2145180835,1713513028,2116692564,2878378043,2206763019,3393603212,703524551,3552098411,1007948840,2044649127,3797835452,487262998,1994120109,1004593371,1446130276,1312438900,503974420,3679013266,168166924,1814307912,3831258296,1573044895,1859376061,4021070915,2791465668,2828112185,2761266481,937747667,2339994098,854058965,1137232011,1496790894,3077402074,2358086913,1691735473,3528347292,3769215305,3027004632,4199962284,133494003,636152527,2942657994,2390391540,3920539207,403179536,3585784431,2289596656,1864705354,1915629148,605822008,4054230615,3350508659,1371981463,602466507,2094914977,2624877800,555687742,3712699286,3703422305,2257292045,2240449039,2423288032,1111375484,3300242801,2858837708,3628615824,84083462,32962295,302911004,2741068226,1597322602,4183250862,3501832553,2441512471,1489093017,656219450,3114180135,954327513,335083755,3013122091,856756514,3144247762,1893325225,2307821063,2811532339,3063651117,572399164,2458355477,552200649,1238290055,4283782570,2015897680,2061492133,2408352771,4171342169,2156497161,386731290,3669999461,837215959,3326231172,3093850320,3275833730,2962856233,1999449434,286199582,3417354363,4233385128,3602627437,974525996],m=[1667483301,2088564868,2004348569,2071721613,4076011277,1802229437,1869602481,3318059348,808476752,16843267,1734856361,724260477,4278118169,3621238114,2880130534,1987505306,3402272581,2189565853,3385428288,2105408135,4210749205,1499050731,1195871945,4042324747,2913812972,3570709351,2728550397,2947499498,2627478463,2762232823,1920132246,3233848155,3082253762,4261273884,2475900334,640044138,909536346,1061125697,4160222466,3435955023,875849820,2779075060,3857043764,4059166984,1903288979,3638078323,825320019,353708607,67373068,3351745874,589514341,3284376926,404238376,2526427041,84216335,2593796021,117902857,303178806,2155879323,3806519101,3958099238,656887401,2998042573,1970662047,151589403,2206408094,741103732,437924910,454768173,1852759218,1515893998,2694863867,1381147894,993752653,3604395873,3014884814,690573947,3823361342,791633521,2223248279,1397991157,3520182632,0,3991781676,538984544,4244431647,2981198280,1532737261,1785386174,3419114822,3200149465,960066123,1246401758,1280088276,1482207464,3486483786,3503340395,4025468202,2863288293,4227591446,1128498885,1296931543,859006549,2240090516,1162185423,4193904912,33686534,2139094657,1347461360,1010595908,2678007226,2829601763,1364304627,2745392638,1077969088,2408514954,2459058093,2644320700,943222856,4126535940,3166462943,3065411521,3671764853,555827811,269492272,4294960410,4092853518,3537026925,3452797260,202119188,320022069,3974939439,1600110305,2543269282,1145342156,387395129,3301217111,2812761586,2122251394,1027439175,1684326572,1566423783,421081643,1936975509,1616953504,2172721560,1330618065,3705447295,572671078,707417214,2425371563,2290617219,1179028682,4008625961,3099093971,336865340,3739133817,1583267042,185275933,3688607094,3772832571,842163286,976909390,168432670,1229558491,101059594,606357612,1549580516,3267534685,3553869166,2896970735,1650640038,2442213800,2509582756,3840201527,2038035083,3890730290,3368586051,926379609,1835915959,2374828428,3587551588,1313774802,2846444e3,1819072692,1448520954,4109693703,3941256997,1701169839,2054878350,2930657257,134746136,3132780501,2021191816,623200879,774790258,471611428,2795919345,3031724999,3334903633,3907570467,3722289532,1953818780,522141217,1263245021,3183305180,2341145990,2324303749,1886445712,1044282434,3048567236,1718013098,1212715224,50529797,4143380225,235805714,1633796771,892693087,1465364217,3115936208,2256934801,3250690392,488454695,2661164985,3789674808,4177062675,2560109491,286335539,1768542907,3654920560,2391672713,2492740519,2610638262,505297954,2273777042,3924412704,3469641545,1431677695,673730680,3755976058,2357986191,2711706104,2307459456,218962455,3216991706,3873888049,1111655622,1751699640,1094812355,2576951728,757946999,252648977,2964356043,1414834428,3149622742,370551866],y=[1673962851,2096661628,2012125559,2079755643,4076801522,1809235307,1876865391,3314635973,811618352,16909057,1741597031,727088427,4276558334,3618988759,2874009259,1995217526,3398387146,2183110018,3381215433,2113570685,4209972730,1504897881,1200539975,4042984432,2906778797,3568527316,2724199842,2940594863,2619588508,2756966308,1927583346,3231407040,3077948087,4259388669,2470293139,642542118,913070646,1065238847,4160029431,3431157708,879254580,2773611685,3855693029,4059629809,1910674289,3635114968,828527409,355090197,67636228,3348452039,591815971,3281870531,405809176,2520228246,84545285,2586817946,118360327,304363026,2149292928,3806281186,3956090603,659450151,2994720178,1978310517,152181513,2199756419,743994412,439627290,456535323,1859957358,1521806938,2690382752,1386542674,997608763,3602342358,3011366579,693271337,3822927587,794718511,2215876484,1403450707,3518589137,0,3988860141,541089824,4242743292,2977548465,1538714971,1792327274,3415033547,3194476990,963791673,1251270218,1285084236,1487988824,3481619151,3501943760,4022676207,2857362858,4226619131,1132905795,1301993293,862344499,2232521861,1166724933,4192801017,33818114,2147385727,1352724560,1014514748,2670049951,2823545768,1369633617,2740846243,1082179648,2399505039,2453646738,2636233885,946882616,4126213365,3160661948,3061301686,3668932058,557998881,270544912,4293204735,4093447923,3535760850,3447803085,202904588,321271059,3972214764,1606345055,2536874647,1149815876,388905239,3297990596,2807427751,2130477694,1031423805,1690872932,1572530013,422718233,1944491379,1623236704,2165938305,1335808335,3701702620,574907938,710180394,2419829648,2282455944,1183631942,4006029806,3094074296,338181140,3735517662,1589437022,185998603,3685578459,3772464096,845436466,980700730,169090570,1234361161,101452294,608726052,1555620956,3265224130,3552407251,2890133420,1657054818,2436475025,2503058581,3839047652,2045938553,3889509095,3364570056,929978679,1843050349,2365688973,3585172693,1318900302,2840191145,1826141292,1454176854,4109567988,3939444202,1707781989,2062847610,2923948462,135272456,3127891386,2029029496,625635109,777810478,473441308,2790781350,3027486644,3331805638,3905627112,3718347997,1961401460,524165407,1268178251,3177307325,2332919435,2316273034,1893765232,1048330814,3044132021,1724688998,1217452104,50726147,4143383030,236720654,1640145761,896163637,1471084887,3110719673,2249691526,3248052417,490350365,2653403550,3789109473,4176155640,2553000856,287453969,1775418217,3651760345,2382858638,2486413204,2603464347,507257374,2266337927,3922272489,3464972750,1437269845,676362280,3752164063,2349043596,2707028129,2299101321,219813645,3211123391,3872862694,1115997762,1758509160,1099088705,2569646233,760903469,253628687,2960903088,1420360788,3144537787,371997206],b=[3332727651,4169432188,4003034999,4136467323,4279104242,3602738027,3736170351,2438251973,1615867952,33751297,3467208551,1451043627,3877240574,3043153879,1306962859,3969545846,2403715786,530416258,2302724553,4203183485,4011195130,3001768281,2395555655,4211863792,1106029997,3009926356,1610457762,1173008303,599760028,1408738468,3835064946,2606481600,1975695287,3776773629,1034851219,1282024998,1817851446,2118205247,4110612471,2203045068,1750873140,1374987685,3509904869,4178113009,3801313649,2876496088,1649619249,708777237,135005188,2505230279,1181033251,2640233411,807933976,933336726,168756485,800430746,235472647,607523346,463175808,3745374946,3441880043,1315514151,2144187058,3936318837,303761673,496927619,1484008492,875436570,908925723,3702681198,3035519578,1543217312,2767606354,1984772923,3076642518,2110698419,1383803177,3711886307,1584475951,328696964,2801095507,3110654417,0,3240947181,1080041504,3810524412,2043195825,3069008731,3569248874,2370227147,1742323390,1917532473,2497595978,2564049996,2968016984,2236272591,3144405200,3307925487,1340451498,3977706491,2261074755,2597801293,1716859699,294946181,2328839493,3910203897,67502594,4269899647,2700103760,2017737788,632987551,1273211048,2733855057,1576969123,2160083008,92966799,1068339858,566009245,1883781176,4043634165,1675607228,2009183926,2943736538,1113792801,540020752,3843751935,4245615603,3211645650,2169294285,403966988,641012499,3274697964,3202441055,899848087,2295088196,775493399,2472002756,1441965991,4236410494,2051489085,3366741092,3135724893,841685273,3868554099,3231735904,429425025,2664517455,2743065820,1147544098,1417554474,1001099408,193169544,2362066502,3341414126,1809037496,675025940,2809781982,3168951902,371002123,2910247899,3678134496,1683370546,1951283770,337512970,2463844681,201983494,1215046692,3101973596,2673722050,3178157011,1139780780,3299238498,967348625,832869781,3543655652,4069226873,3576883175,2336475336,1851340599,3669454189,25988493,2976175573,2631028302,1239460265,3635702892,2902087254,4077384948,3475368682,3400492389,4102978170,1206496942,270010376,1876277946,4035475576,1248797989,1550986798,941890588,1475454630,1942467764,2538718918,3408128232,2709315037,3902567540,1042358047,2531085131,1641856445,226921355,260409994,3767562352,2084716094,1908716981,3433719398,2430093384,100991747,4144101110,470945294,3265487201,1784624437,2935576407,1775286713,395413126,2572730817,975641885,666476190,3644383713,3943954680,733190296,573772049,3535497577,2842745305,126455438,866620564,766942107,1008868894,361924487,3374377449,2269761230,2868860245,1350051880,2776293343,59739276,1509466529,159418761,437718285,1708834751,3610371814,2227585602,3501746280,2193834305,699439513,1517759789,504434447,2076946608,2835108948,1842789307,742004246],v=8,w=14;r.exports={};var k=[128,192,256];for(var C in k)r.exports[k[C]]=p(k[C])},{"../../util":55}],5:[function(t,r){function e(){}function i(t){this.bf=new e,this.bf.init(n.str2bin(t)),this.encrypt=function(t){return this.bf.encrypt_block(t)}}e.prototype.BLOCKSIZE=8,e.prototype.SBOXES=[[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946],[1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055],[3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504],[976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462]],e.prototype.PARRAY=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],e.prototype.NN=16,e.prototype._clean=function(t){if(0>t){var r=2147483647&t; +/*! OpenPGPjs.org this is LGPL licensed code, see LICENSE/our website for more information.- v0.0.1 - 2013-10-13 */(function e(t,r,i){function n(o,a){if(!r[o]){if(!t[o]){var h="function"==typeof require&&require;if(!a&&h)return h(o,!0);if(s)return s(o,!0);throw Error("Cannot find module '"+o+"'")}var c=r[o]={exports:{}};t[o][0].call(c.exports,function(r){var e=t[o][1][r];return n(e?e:r)},c,c.exports,e,t,r,i)}return r[o].exports}for(var s="function"==typeof require&&require,o=0;i.length>o;o++)n(i[o]);return n})({1:[function(t,r){JXG={exists:function(t){return function(r){return!(r===t||null===r)}}()},JXG.decompress=function(t){return unescape(new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(t)).unzip()[0][0])},JXG.Util={},JXG.Util.Unzip=function(t){function r(){return D+=8,x.length>P?x[P++]:-1}function e(){N=1}function i(){var t;return D++,t=1&N,N>>=1,0==N&&(N=r(),t=1&N,N=128|N>>1),t}function n(t){for(var r=0,e=t;e--;)r=r<<1|i();return t&&(r=j[r]>>8-t),r}function s(){_=0}function o(t){y++,A[_++]=t,v.push(String.fromCharCode(t)),32768==_&&(_=0)}function a(){this.b0=0,this.b1=0,this.jump=null,this.jumppos=-1}function h(){for(;;){if(q[U]>=V)return-1;if(F[q[U]]==U)return q[U]++;q[U]++}}function c(){var t,r=z[L];if(w&&document.write("
len:"+U+" treepos:"+L),17==U)return-1;if(L++,U++,t=h(),w&&document.write("
IsPat "+t),t>=0)r.b0=t,w&&document.write("
b0 "+r.b0);else if(r.b0=32768,w&&document.write("
b0 "+r.b0),c())return-1;if(t=h(),t>=0)r.b1=t,w&&document.write("
b1 "+r.b1),r.jump=null;else if(r.b1=32768,w&&document.write("
b1 "+r.b1),r.jump=z[L],r.jumppos=L,c())return-1;return U--,0}function u(t,r,e,i){var n;for(w&&document.write("currentTree "+t+" numval "+r+" lengths "+e+" show "+i),z=t,L=0,F=e,V=r,n=0;17>n;n++)q[n]=0;if(U=0,c())return w&&alert("invalid huffman tree\n"),-1;if(w){document.write("
Tree: "+z.length);for(var s=0;32>s;s++)document.write("Places["+s+"].b0="+z[s].b0+"
"),document.write("Places["+s+"].b1="+z[s].b1+"
")}return 0}function p(t){for(var r,e,n,s=0,o=t[s];;)if(n=i(),w&&document.write("b="+n),n){if(!(32768&o.b1))return w&&document.write("ret1"),o.b1;for(o=o.jump,r=t.length,e=0;r>e;e++)if(t[e]===o){s=e;break}}else{if(!(32768&o.b0))return w&&document.write("ret2"),o.b0;s++,o=t[s]}return w&&document.write("ret3"),-1}function l(){var t,h,c,l,f;do{switch(t=i(),c=n(2)){case 0:w&&alert("Stored\n");break;case 1:w&&alert("Fixed Huffman codes\n");break;case 2:w&&alert("Dynamic Huffman codes\n");break;case 3:w&&alert("Reserved block type!!\n");break;default:w&&alert("Unexpected value %d!\n",c)}if(0==c){var d,g;for(e(),d=r(),d|=r()<<8,g=r(),g|=r()<<8,65535&(d^~g)&&document.write("BlockLen checksum mismatch\n");d--;)h=r(),o(h)}else if(1==c)for(var m;;)if(m=j[n(7)]>>1,m>23?(m=m<<1|i(),m>199?(m-=128,m=m<<1|i()):(m-=48,m>143&&(m+=136))):m+=256,256>m)o(m);else{if(256==m)break;var f,y;for(m-=257,f=n(O[m])+T[m],m=j[n(5)]>>3,I[m]>8?(y=n(8),y|=n(I[m]-8)<<8):y=n(I[m]),y+=E[m],m=0;f>m;m++){var h=A[32767&_-y];o(h)}}else if(2==c){var m,b,v,k,C,S=Array(320);for(v=257+n(5),k=1+n(5),C=4+n(4),m=0;19>m;m++)S[m]=0;for(m=0;C>m;m++)S[B[m]]=n(3);for(f=H.length,l=0;f>l;l++)H[l]=new a;if(u(H,19,S,0))return s(),1;if(w){document.write("
distanceTree");for(var x=0;H.length>x;x++)document.write("
"+H[x].b0+" "+H[x].b1+" "+H[x].jump+" "+H[x].jumppos)}b=v+k,l=0;var P=-1;for(w&&document.write("
n="+b+" bits: "+D+"
");b>l;)if(P++,m=p(H),w&&document.write("
"+P+" i:"+l+" decode: "+m+" bits "+D+"
"),16>m)S[l++]=m;else if(16==m){var N;if(m=3+n(2),l+m>b)return s(),1;for(N=l?S[l-1]:0;m--;)S[l++]=N}else{if(m=17==m?3+n(3):11+n(7),l+m>b)return s(),1;for(;m--;)S[l++]=0}for(f=G.length,l=0;f>l;l++)G[l]=new a;if(u(G,v,S,0))return s(),1;for(f=G.length,l=0;f>l;l++)H[l]=new a;var K=[];for(l=v;S.length>l;l++)K[l-v]=S[l];if(u(H,k,K,0))return s(),1;w&&document.write("
literalTree");t:for(;;)if(m=p(G),m>=256){var f,y;if(m-=256,0==m)break;for(m--,f=n(O[m])+T[m],m=p(H),I[m]>8?(y=n(8),y|=n(I[m]-8)<<8):y=n(I[m]),y+=E[m];f--;){if(0>_-y)break t;var h=A[32767&_-y];o(h)}}else o(m)}}while(!t);return s(),e(),0}function f(){w&&alert("NEXTFILE"),v=[];var t=[];if(S=!1,t[0]=r(),t[1]=r(),w&&alert("type: "+t[0]+" "+t[1]),t[0]==parseInt("78",16)&&t[1]==parseInt("da",16)&&(w&&alert("GEONExT-GZIP"),l(),w&&alert(v.join("")),C[k]=Array(2),C[k][0]=v.join(""),C[k][1]="geonext.gxt",k++),t[0]==parseInt("78",16)&&t[1]==parseInt("9c",16)&&(w&&alert("ZLIB"),l(),w&&alert(v.join("")),C[k]=Array(2),C[k][0]=v.join(""),C[k][1]="ZLIB",k++),t[0]==parseInt("1f",16)&&t[1]==parseInt("8b",16)&&(w&&alert("GZIP"),d(),w&&alert(v.join("")),C[k]=Array(2),C[k][0]=v.join(""),C[k][1]="file",k++),t[0]==parseInt("50",16)&&t[1]==parseInt("4b",16)&&(S=!0,t[2]=r(),t[3]=r(),t[2]==parseInt("3",16)&&t[3]==parseInt("4",16))){t[0]=r(),t[1]=r(),w&&alert("ZIP-Version: "+t[1]+" "+t[0]/10+"."+t[0]%10),g=r(),g|=r()<<8,w&&alert("gpflags: "+g);var e=r();e|=r()<<8,w&&alert("method: "+e),r(),r(),r(),r();var i=r();i|=r()<<8,i|=r()<<16,i|=r()<<24;var n=r();n|=r()<<8,n|=r()<<16,n|=r()<<24;var s=r();s|=r()<<8,s|=r()<<16,s|=r()<<24,w&&alert("local CRC: "+i+"\nlocal Size: "+s+"\nlocal CompSize: "+n);var o=r();o|=r()<<8;var a=r();for(a|=r()<<8,w&&alert("filelen "+o),c=0,M=[];o--;){var h=r();"/"==h|":"==h?c=0:K-1>c&&(M[c++]=String.fromCharCode(h))}w&&alert("nameBuf: "+M),b||(b=M);for(var c=0;a>c;)h=r(),c++;m=4294967295,y=0,(s=0)&&w&&alert("skipdir"),8==e&&(l(),w&&alert(v.join("")),C[k]=Array(2),C[k][0]=v.join(""),C[k][1]=M.join(""),k++),d()}}function d(){var t,e,i,n,s,o,a=[];if(8&g&&(a[0]=r(),a[1]=r(),a[2]=r(),a[3]=r(),a[0]==parseInt("50",16)&&a[1]==parseInt("4b",16)&&a[2]==parseInt("07",16)&&a[3]==parseInt("08",16)?(t=r(),t|=r()<<8,t|=r()<<16,t|=r()<<24):t=a[0]|a[1]<<8|a[2]<<16|a[3]<<24,e=r(),e|=r()<<8,e|=r()<<16,e|=r()<<24,i=r(),i|=r()<<8,i|=r()<<16,i|=r()<<24,w&&alert("CRC:")),S&&f(),a[0]=r(),8!=a[0])return w&&alert("Unknown compression method!"),0;if(g=r(),w&&g&~parseInt("1f",16)&&alert("Unknown flags set!"),r(),r(),r(),r(),r(),n=r(),4&g)for(a[0]=r(),a[2]=r(),U=a[0]+256*a[1],w&&alert("Extra field size: "+U),s=0;U>s;s++)r();if(8&g){for(s=0,M=[];o=r();)("7"==o||":"==o)&&(s=0),K-1>s&&(M[s++]=o);w&&alert("original file name: "+M)}if(16&g)for(;o=r(););2&g&&(r(),r()),l(),t=r(),t|=r()<<8,t|=r()<<16,t|=r()<<24,i=r(),i|=r()<<8,i|=r()<<16,i|=r()<<24,S&&f()}var g,m,y,b,v=[],w=!1,k=0,C=[],A=Array(32768),_=0,S=!1,j=[0,128,64,192,32,160,96,224,16,144,80,208,48,176,112,240,8,136,72,200,40,168,104,232,24,152,88,216,56,184,120,248,4,132,68,196,36,164,100,228,20,148,84,212,52,180,116,244,12,140,76,204,44,172,108,236,28,156,92,220,60,188,124,252,2,130,66,194,34,162,98,226,18,146,82,210,50,178,114,242,10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250,6,134,70,198,38,166,102,230,22,150,86,214,54,182,118,246,14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254,1,129,65,193,33,161,97,225,17,145,81,209,49,177,113,241,9,137,73,201,41,169,105,233,25,153,89,217,57,185,121,249,5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245,13,141,77,205,45,173,109,237,29,157,93,221,61,189,125,253,3,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243,11,139,75,203,43,171,107,235,27,155,91,219,59,187,123,251,7,135,71,199,39,167,103,231,23,151,87,215,55,183,119,247,15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255],T=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],O=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,99,99],E=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],I=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],B=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],x=t,P=0,N=1,D=0,K=256,M=[],R=288,G=Array(R),H=Array(32),L=0,z=null;Array(64),Array(64);var U=0,q=Array(17);q[0]=0;var F,V;JXG.Util.Unzip.prototype.unzipFile=function(t){var r;for(this.unzip(),r=0;C.length>r;r++)if(C[r][1]==t)return C[r][0]},JXG.Util.Unzip.prototype.deflate=function(){return v=[],S=!1,l(),w&&alert(v.join("")),C[k]=Array(2),C[k][0]=v.join(""),C[k][1]="DEFLATE",k++,C},JXG.Util.Unzip.prototype.unzip=function(){return w&&alert(x),f(),C}},JXG.Util.Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(t){var r,e,i,n,s,o,a,h=[],c=0;for(t=JXG.Util.Base64._utf8_encode(t);t.length>c;)r=t.charCodeAt(c++),e=t.charCodeAt(c++),i=t.charCodeAt(c++),n=r>>2,s=(3&r)<<4|e>>4,o=(15&e)<<2|i>>6,a=63&i,isNaN(e)?o=a=64:isNaN(i)&&(a=64),h.push([this._keyStr.charAt(n),this._keyStr.charAt(s),this._keyStr.charAt(o),this._keyStr.charAt(a)].join(""));return h.join("")},decode:function(t,r){var e,i,n,s,o,a,h,c=[],u=0;for(t=t.replace(/[^A-Za-z0-9\+\/\=]/g,"");t.length>u;)s=this._keyStr.indexOf(t.charAt(u++)),o=this._keyStr.indexOf(t.charAt(u++)),a=this._keyStr.indexOf(t.charAt(u++)),h=this._keyStr.indexOf(t.charAt(u++)),e=s<<2|o>>4,i=(15&o)<<4|a>>2,n=(3&a)<<6|h,c.push(String.fromCharCode(e)),64!=a&&c.push(String.fromCharCode(i)),64!=h&&c.push(String.fromCharCode(n));return c=c.join(""),r&&(c=JXG.Util.Base64._utf8_decode(c)),c},_utf8_encode:function(t){t=t.replace(/\r\n/g,"\n");for(var r="",e=0;t.length>e;e++){var i=t.charCodeAt(e);128>i?r+=String.fromCharCode(i):i>127&&2048>i?(r+=String.fromCharCode(192|i>>6),r+=String.fromCharCode(128|63&i)):(r+=String.fromCharCode(224|i>>12),r+=String.fromCharCode(128|63&i>>6),r+=String.fromCharCode(128|63&i))}return r},_utf8_decode:function(t){for(var r=[],e=0,i=0,n=0,s=0;t.length>e;)i=t.charCodeAt(e),128>i?(r.push(String.fromCharCode(i)),e++):i>191&&224>i?(n=t.charCodeAt(e+1),r.push(String.fromCharCode((31&i)<<6|63&n)),e+=2):(n=t.charCodeAt(e+1),s=t.charCodeAt(e+2),r.push(String.fromCharCode((15&i)<<12|(63&n)<<6|63&s)),e+=3);return r.join("")},_destrip:function(t,r){var e,i,n=[],s=[];for(null==r&&(r=76),t.replace(/ /g,""),e=t.length/r,i=0;e>i;i++)n[i]=t.substr(i*r,r);for(e!=t.length/r&&(n[n.length]=t.substr(e*r,t.length-e*r)),i=0;n.length>i;i++)s.push(n[i]);return s.join("\n")},decodeAsArray:function(t){var r,e=this.decode(t),i=[];for(r=0;e.length>r;r++)i[r]=e.charCodeAt(r);return i},decodeGEONExT:function(t){return decodeAsArray(destrip(t),!1)}},JXG.Util.asciiCharCodeAt=function(t,r){var e=t.charCodeAt(r);if(e>255)switch(e){case 8364:e=128;break;case 8218:e=130;break;case 402:e=131;break;case 8222:e=132;break;case 8230:e=133;break;case 8224:e=134;break;case 8225:e=135;break;case 710:e=136;break;case 8240:e=137;break;case 352:e=138;break;case 8249:e=139;break;case 338:e=140;break;case 381:e=142;break;case 8216:e=145;break;case 8217:e=146;break;case 8220:e=147;break;case 8221:e=148;break;case 8226:e=149;break;case 8211:e=150;break;case 8212:e=151;break;case 732:e=152;break;case 8482:e=153;break;case 353:e=154;break;case 8250:e=155;break;case 339:e=156;break;case 382:e=158;break;case 376:e=159;break;default:}return e},JXG.Util.utf8Decode=function(t){var r,e=[],i=0,n=0,s=0;if(!JXG.exists(t))return"";for(;t.length>i;)n=t.charCodeAt(i),128>n?(e.push(String.fromCharCode(n)),i++):n>191&&224>n?(s=t.charCodeAt(i+1),e.push(String.fromCharCode((31&n)<<6|63&s)),i+=2):(s=t.charCodeAt(i+1),r=t.charCodeAt(i+2),e.push(String.fromCharCode((15&n)<<12|(63&s)<<6|63&r)),i+=3);return e.join("")},JXG.Util.genUUID=function(){for(var t,r="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=Array(36),i=0,n=0;36>n;n++)8==n||13==n||18==n||23==n?e[n]="-":14==n?e[n]="4":(2>=i&&(i=0|33554432+16777216*Math.random()),t=15&i,i>>=4,e[n]=r[19==n?8|3&t:t]);return e.join("")},r.exports=JXG},{}],2:[function(){},{}],3:[function(t,r){var e=t("../util"),i=t("./cipher");r.exports={encrypt:function(t,r,s,o,a){r=new i[r](o);var h=r.blockSize,c=Array(h),u=Array(h);t=t+t.charAt(h-2)+t.charAt(h-1),e.print_debug("prefixrandom:"+e.hexstrdump(t));for(var p="",l=0;h>l;l++)c[l]=0;u=r.encrypt(c);for(var l=0;h>l;l++)p+=String.fromCharCode(u[l]^t.charCodeAt(l));for(var l=0;h>l;l++)c[l]=p.charCodeAt(l);if(u=r.encrypt(c),p+=String.fromCharCode(u[0]^t.charCodeAt(h)),p+=String.fromCharCode(u[1]^t.charCodeAt(h+1)),a)for(var l=0;h>l;l++)c[l]=p.charCodeAt(l+2);else for(var l=0;h>l;l++)c[l]=p.charCodeAt(l);if(u=r.encrypt(c,o),a){for(var l=0;h>l;l++)p+=String.fromCharCode(u[l]^s.charCodeAt(l));for(n=h+2;s.length>n;n+=h){for(var l=0;h>l;l++)c[l]=p.charCodeAt(n+l);u=r.encrypt(c);for(var l=0;h>l;l++)p+=String.fromCharCode(u[l]^s.charCodeAt(n-2+l))}}else{s=" "+s;for(var l=2;h>l;l++)p+=String.fromCharCode(u[l]^s.charCodeAt(l));var f=p.substring(0,2*h).split(""),d=p.substring(h);for(n=h;s.length>n;n+=h){for(var l=0;h>l;l++)c[l]=d.charCodeAt(l);d="",u=r.encrypt(c);for(var l=0;h>l;l++)f.push(String.fromCharCode(u[l]^s.charCodeAt(n+l))),d+=String.fromCharCode(u[l]^s.charCodeAt(n+l))}p=f.join("")}return p=p.substring(0,s.length+2+h)},mdc:function(t,r,n){t=new i[t](r);var s,o=t.blockSize,a=Array(o),h=Array(o);for(s=0;o>s;s++)a[s]=0;for(a=t.encrypt(a),s=0;o>s;s++)h[s]=n.charCodeAt(s),a[s]^=h[s];return h=t.encrypt(h),e.bin2str(a)+String.fromCharCode(h[0]^n.charCodeAt(o))+String.fromCharCode(h[1]^n.charCodeAt(o+1))},decrypt:function(t,r,e,n){t=new i[t](r);var s,o=t.blockSize,a=Array(o),h=Array(o),c="",u=[];for(s=0;o>s;s++)a[s]=0;for(a=t.encrypt(a,r),s=0;o>s;s++)h[s]=e.charCodeAt(s),a[s]^=h[s];if(h=t.encrypt(h,r),a[o-2]!=(h[0]^e.charCodeAt(o))||a[o-1]!=(h[1]^e.charCodeAt(o+1)))throw Error("Invalid data.");if(n){for(s=0;o>s;s++)a[s]=e.charCodeAt(s+2);for(c=o+2;e.length>c;c+=o)for(h=t.encrypt(a),s=0;o>s&&e.length>s+c;s++)a[s]=e.charCodeAt(c+s),u.push(String.fromCharCode(h[s]^a[s]))}else{for(s=0;o>s;s++)a[s]=e.charCodeAt(s);for(c=o;e.length>c;c+=o)for(h=t.encrypt(a),s=0;o>s&&e.length>s+c;s++)a[s]=e.charCodeAt(c+s),u.push(String.fromCharCode(h[s]^a[s]))}var c=n?0:2;return u=u.join(""),u=u.substring(c,e.length-o-2+c)},normalEncrypt:function(t,r,n,s){t=new i[t](r);var o=t.blockSize,a="",h="",c=0,u=[],p=[];for(h=s.substring(0,o);n.length>o*c;){var l=t.encrypt(e.str2bin(h));a=n.substring(c*o,c*o+o);for(var f=0;a.length>f;f++)p.push(String.fromCharCode(a.charCodeAt(f)^l[f]));h=p.join(""),p=[],u.push(h),c++}return u.join("")},normalDecrypt:function(t,r,n,s){t=new i[t](r);var o=t.blockSize,a="",h=0,c=[],u=0;if(null==s)for(var p=0;o>p;p++)a+=String.fromCharCode(0);else a=s.substring(0,o);for(;n.length>o*h;){var l=t.encrypt(e.str2bin(a));a=n.substring(h*o+u,h*o+o+u);for(var p=0;a.length>p;p++)c.push(String.fromCharCode(a.charCodeAt(p)^l[p]));h++}return c.join("")}}},{"../util":55,"./cipher":8}],4:[function(t,r){function e(t){return 255&t}function i(t){return 255&t>>8}function n(t){return 255&t>>16}function s(t){return 255&t>>24}function o(t,r,e,n){return i(g[255&t])|i(g[255&r>>8])<<8|i(g[255&e>>16])<<16|i(g[n>>>24])<<24}function a(t){var r,e,i=t.length,n=Array(i/4);if(t&&!(i%4)){for(r=0,e=0;i>e;e+=4)n[r++]=t[e]|t[e+1]<<8|t[e+2]<<16|t[e+3]<<24;return n}}function h(t){var r,o=0,a=t.length,h=Array(4*a);for(r=0;a>r;r++)h[o++]=e(t[r]),h[o++]=i(t[r]),h[o++]=n(t[r]),h[o++]=s(t[r]);return h}function c(t){var r,o,a,h,c,u,p=Array(w+1),g=t.length,m=Array(v),y=Array(v),b=0;if(16==g)u=10,r=4;else if(24==g)u=12,r=6;else{if(32!=g)return l.print_error("aes.js: Invalid key-length for AES key:"+g),void 0;u=14,r=8}for(o=0;w+1>o;o++)p[o]=Array(4);for(o=0,a=0;g>a;a++,o+=4)m[a]=t.charCodeAt(o)|t.charCodeAt(o+1)<<8|t.charCodeAt(o+2)<<16|t.charCodeAt(o+3)<<24;for(a=r-1;a>=0;a--)y[a]=m[a];for(h=0,c=0,a=0;r>a&&u+1>h;){for(;r>a&&4>c;a++,c++)p[h][c]=y[a];4==c&&(h++,c=0)}for(;u+1>h;){var k=y[r-1];if(y[0]^=d[i(k)]|d[n(k)]<<8|d[s(k)]<<16|d[e(k)]<<24,y[0]^=f[b++],8!=r)for(a=1;r>a;a++)y[a]^=y[a-1];else{for(a=1;r/2>a;a++)y[a]^=y[a-1];for(k=y[r/2-1],y[r/2]^=d[e(k)]|d[i(k)]<<8|d[n(k)]<<16|d[s(k)]<<24,a=r/2+1;r>a;a++)y[a]^=y[a-1]}for(a=0;r>a&&u+1>h;){for(;r>a&&4>c;a++,c++)p[h][c]=y[a];4==c&&(h++,c=0)}}return this.rounds=u,this.rk=p,this}function u(t,r){var e,i,n,s,c,u=a(t),p=r.rounds,l=u[0],f=u[1],d=u[2],v=u[3];for(e=0;p-1>e;e++)i=l^r.rk[e][0],n=f^r.rk[e][1],s=d^r.rk[e][2],c=v^r.rk[e][3],l=g[255&i]^m[255&n>>8]^y[255&s>>16]^b[c>>>24],f=g[255&n]^m[255&s>>8]^y[255&c>>16]^b[i>>>24],d=g[255&s]^m[255&c>>8]^y[255&i>>16]^b[n>>>24],v=g[255&c]^m[255&i>>8]^y[255&n>>16]^b[s>>>24];return e=p-1,i=l^r.rk[e][0],n=f^r.rk[e][1],s=d^r.rk[e][2],c=v^r.rk[e][3],u[0]=o(i,n,s,c)^r.rk[p][0],u[1]=o(n,s,c,i)^r.rk[p][1],u[2]=o(s,c,i,n)^r.rk[p][2],u[3]=o(c,i,n,s)^r.rk[p][3],h(u)}function p(t){var r=function(t){this.key=c(t),this.encrypt=function(t){return u(t,this.key)}};return r.blockSize=r.prototype.blockSize=16,r.keySize=r.prototype.keySize=t/8,r}var l=t("../../util"),f=[1,2,4,8,16,32,64,128,27,54,108,216,171,77,154,47,94,188,99,198,151,53,106,212,179,125,250,239,197,145],d=[99,124,119,123,242,107,111,197,48,1,103,43,254,215,171,118,202,130,201,125,250,89,71,240,173,212,162,175,156,164,114,192,183,253,147,38,54,63,247,204,52,165,229,241,113,216,49,21,4,199,35,195,24,150,5,154,7,18,128,226,235,39,178,117,9,131,44,26,27,110,90,160,82,59,214,179,41,227,47,132,83,209,0,237,32,252,177,91,106,203,190,57,74,76,88,207,208,239,170,251,67,77,51,133,69,249,2,127,80,60,159,168,81,163,64,143,146,157,56,245,188,182,218,33,16,255,243,210,205,12,19,236,95,151,68,23,196,167,126,61,100,93,25,115,96,129,79,220,34,42,144,136,70,238,184,20,222,94,11,219,224,50,58,10,73,6,36,92,194,211,172,98,145,149,228,121,231,200,55,109,141,213,78,169,108,86,244,234,101,122,174,8,186,120,37,46,28,166,180,198,232,221,116,31,75,189,139,138,112,62,181,102,72,3,246,14,97,53,87,185,134,193,29,158,225,248,152,17,105,217,142,148,155,30,135,233,206,85,40,223,140,161,137,13,191,230,66,104,65,153,45,15,176,84,187,22],g=[2774754246,2222750968,2574743534,2373680118,234025727,3177933782,2976870366,1422247313,1345335392,50397442,2842126286,2099981142,436141799,1658312629,3870010189,2591454956,1170918031,2642575903,1086966153,2273148410,368769775,3948501426,3376891790,200339707,3970805057,1742001331,4255294047,3937382213,3214711843,4154762323,2524082916,1539358875,3266819957,486407649,2928907069,1780885068,1513502316,1094664062,49805301,1338821763,1546925160,4104496465,887481809,150073849,2473685474,1943591083,1395732834,1058346282,201589768,1388824469,1696801606,1589887901,672667696,2711000631,251987210,3046808111,151455502,907153956,2608889883,1038279391,652995533,1764173646,3451040383,2675275242,453576978,2659418909,1949051992,773462580,756751158,2993581788,3998898868,4221608027,4132590244,1295727478,1641469623,3467883389,2066295122,1055122397,1898917726,2542044179,4115878822,1758581177,0,753790401,1612718144,536673507,3367088505,3982187446,3194645204,1187761037,3653156455,1262041458,3729410708,3561770136,3898103984,1255133061,1808847035,720367557,3853167183,385612781,3309519750,3612167578,1429418854,2491778321,3477423498,284817897,100794884,2172616702,4031795360,1144798328,3131023141,3819481163,4082192802,4272137053,3225436288,2324664069,2912064063,3164445985,1211644016,83228145,3753688163,3249976951,1977277103,1663115586,806359072,452984805,250868733,1842533055,1288555905,336333848,890442534,804056259,3781124030,2727843637,3427026056,957814574,1472513171,4071073621,2189328124,1195195770,2892260552,3881655738,723065138,2507371494,2690670784,2558624025,3511635870,2145180835,1713513028,2116692564,2878378043,2206763019,3393603212,703524551,3552098411,1007948840,2044649127,3797835452,487262998,1994120109,1004593371,1446130276,1312438900,503974420,3679013266,168166924,1814307912,3831258296,1573044895,1859376061,4021070915,2791465668,2828112185,2761266481,937747667,2339994098,854058965,1137232011,1496790894,3077402074,2358086913,1691735473,3528347292,3769215305,3027004632,4199962284,133494003,636152527,2942657994,2390391540,3920539207,403179536,3585784431,2289596656,1864705354,1915629148,605822008,4054230615,3350508659,1371981463,602466507,2094914977,2624877800,555687742,3712699286,3703422305,2257292045,2240449039,2423288032,1111375484,3300242801,2858837708,3628615824,84083462,32962295,302911004,2741068226,1597322602,4183250862,3501832553,2441512471,1489093017,656219450,3114180135,954327513,335083755,3013122091,856756514,3144247762,1893325225,2307821063,2811532339,3063651117,572399164,2458355477,552200649,1238290055,4283782570,2015897680,2061492133,2408352771,4171342169,2156497161,386731290,3669999461,837215959,3326231172,3093850320,3275833730,2962856233,1999449434,286199582,3417354363,4233385128,3602627437,974525996],m=[1667483301,2088564868,2004348569,2071721613,4076011277,1802229437,1869602481,3318059348,808476752,16843267,1734856361,724260477,4278118169,3621238114,2880130534,1987505306,3402272581,2189565853,3385428288,2105408135,4210749205,1499050731,1195871945,4042324747,2913812972,3570709351,2728550397,2947499498,2627478463,2762232823,1920132246,3233848155,3082253762,4261273884,2475900334,640044138,909536346,1061125697,4160222466,3435955023,875849820,2779075060,3857043764,4059166984,1903288979,3638078323,825320019,353708607,67373068,3351745874,589514341,3284376926,404238376,2526427041,84216335,2593796021,117902857,303178806,2155879323,3806519101,3958099238,656887401,2998042573,1970662047,151589403,2206408094,741103732,437924910,454768173,1852759218,1515893998,2694863867,1381147894,993752653,3604395873,3014884814,690573947,3823361342,791633521,2223248279,1397991157,3520182632,0,3991781676,538984544,4244431647,2981198280,1532737261,1785386174,3419114822,3200149465,960066123,1246401758,1280088276,1482207464,3486483786,3503340395,4025468202,2863288293,4227591446,1128498885,1296931543,859006549,2240090516,1162185423,4193904912,33686534,2139094657,1347461360,1010595908,2678007226,2829601763,1364304627,2745392638,1077969088,2408514954,2459058093,2644320700,943222856,4126535940,3166462943,3065411521,3671764853,555827811,269492272,4294960410,4092853518,3537026925,3452797260,202119188,320022069,3974939439,1600110305,2543269282,1145342156,387395129,3301217111,2812761586,2122251394,1027439175,1684326572,1566423783,421081643,1936975509,1616953504,2172721560,1330618065,3705447295,572671078,707417214,2425371563,2290617219,1179028682,4008625961,3099093971,336865340,3739133817,1583267042,185275933,3688607094,3772832571,842163286,976909390,168432670,1229558491,101059594,606357612,1549580516,3267534685,3553869166,2896970735,1650640038,2442213800,2509582756,3840201527,2038035083,3890730290,3368586051,926379609,1835915959,2374828428,3587551588,1313774802,2846444e3,1819072692,1448520954,4109693703,3941256997,1701169839,2054878350,2930657257,134746136,3132780501,2021191816,623200879,774790258,471611428,2795919345,3031724999,3334903633,3907570467,3722289532,1953818780,522141217,1263245021,3183305180,2341145990,2324303749,1886445712,1044282434,3048567236,1718013098,1212715224,50529797,4143380225,235805714,1633796771,892693087,1465364217,3115936208,2256934801,3250690392,488454695,2661164985,3789674808,4177062675,2560109491,286335539,1768542907,3654920560,2391672713,2492740519,2610638262,505297954,2273777042,3924412704,3469641545,1431677695,673730680,3755976058,2357986191,2711706104,2307459456,218962455,3216991706,3873888049,1111655622,1751699640,1094812355,2576951728,757946999,252648977,2964356043,1414834428,3149622742,370551866],y=[1673962851,2096661628,2012125559,2079755643,4076801522,1809235307,1876865391,3314635973,811618352,16909057,1741597031,727088427,4276558334,3618988759,2874009259,1995217526,3398387146,2183110018,3381215433,2113570685,4209972730,1504897881,1200539975,4042984432,2906778797,3568527316,2724199842,2940594863,2619588508,2756966308,1927583346,3231407040,3077948087,4259388669,2470293139,642542118,913070646,1065238847,4160029431,3431157708,879254580,2773611685,3855693029,4059629809,1910674289,3635114968,828527409,355090197,67636228,3348452039,591815971,3281870531,405809176,2520228246,84545285,2586817946,118360327,304363026,2149292928,3806281186,3956090603,659450151,2994720178,1978310517,152181513,2199756419,743994412,439627290,456535323,1859957358,1521806938,2690382752,1386542674,997608763,3602342358,3011366579,693271337,3822927587,794718511,2215876484,1403450707,3518589137,0,3988860141,541089824,4242743292,2977548465,1538714971,1792327274,3415033547,3194476990,963791673,1251270218,1285084236,1487988824,3481619151,3501943760,4022676207,2857362858,4226619131,1132905795,1301993293,862344499,2232521861,1166724933,4192801017,33818114,2147385727,1352724560,1014514748,2670049951,2823545768,1369633617,2740846243,1082179648,2399505039,2453646738,2636233885,946882616,4126213365,3160661948,3061301686,3668932058,557998881,270544912,4293204735,4093447923,3535760850,3447803085,202904588,321271059,3972214764,1606345055,2536874647,1149815876,388905239,3297990596,2807427751,2130477694,1031423805,1690872932,1572530013,422718233,1944491379,1623236704,2165938305,1335808335,3701702620,574907938,710180394,2419829648,2282455944,1183631942,4006029806,3094074296,338181140,3735517662,1589437022,185998603,3685578459,3772464096,845436466,980700730,169090570,1234361161,101452294,608726052,1555620956,3265224130,3552407251,2890133420,1657054818,2436475025,2503058581,3839047652,2045938553,3889509095,3364570056,929978679,1843050349,2365688973,3585172693,1318900302,2840191145,1826141292,1454176854,4109567988,3939444202,1707781989,2062847610,2923948462,135272456,3127891386,2029029496,625635109,777810478,473441308,2790781350,3027486644,3331805638,3905627112,3718347997,1961401460,524165407,1268178251,3177307325,2332919435,2316273034,1893765232,1048330814,3044132021,1724688998,1217452104,50726147,4143383030,236720654,1640145761,896163637,1471084887,3110719673,2249691526,3248052417,490350365,2653403550,3789109473,4176155640,2553000856,287453969,1775418217,3651760345,2382858638,2486413204,2603464347,507257374,2266337927,3922272489,3464972750,1437269845,676362280,3752164063,2349043596,2707028129,2299101321,219813645,3211123391,3872862694,1115997762,1758509160,1099088705,2569646233,760903469,253628687,2960903088,1420360788,3144537787,371997206],b=[3332727651,4169432188,4003034999,4136467323,4279104242,3602738027,3736170351,2438251973,1615867952,33751297,3467208551,1451043627,3877240574,3043153879,1306962859,3969545846,2403715786,530416258,2302724553,4203183485,4011195130,3001768281,2395555655,4211863792,1106029997,3009926356,1610457762,1173008303,599760028,1408738468,3835064946,2606481600,1975695287,3776773629,1034851219,1282024998,1817851446,2118205247,4110612471,2203045068,1750873140,1374987685,3509904869,4178113009,3801313649,2876496088,1649619249,708777237,135005188,2505230279,1181033251,2640233411,807933976,933336726,168756485,800430746,235472647,607523346,463175808,3745374946,3441880043,1315514151,2144187058,3936318837,303761673,496927619,1484008492,875436570,908925723,3702681198,3035519578,1543217312,2767606354,1984772923,3076642518,2110698419,1383803177,3711886307,1584475951,328696964,2801095507,3110654417,0,3240947181,1080041504,3810524412,2043195825,3069008731,3569248874,2370227147,1742323390,1917532473,2497595978,2564049996,2968016984,2236272591,3144405200,3307925487,1340451498,3977706491,2261074755,2597801293,1716859699,294946181,2328839493,3910203897,67502594,4269899647,2700103760,2017737788,632987551,1273211048,2733855057,1576969123,2160083008,92966799,1068339858,566009245,1883781176,4043634165,1675607228,2009183926,2943736538,1113792801,540020752,3843751935,4245615603,3211645650,2169294285,403966988,641012499,3274697964,3202441055,899848087,2295088196,775493399,2472002756,1441965991,4236410494,2051489085,3366741092,3135724893,841685273,3868554099,3231735904,429425025,2664517455,2743065820,1147544098,1417554474,1001099408,193169544,2362066502,3341414126,1809037496,675025940,2809781982,3168951902,371002123,2910247899,3678134496,1683370546,1951283770,337512970,2463844681,201983494,1215046692,3101973596,2673722050,3178157011,1139780780,3299238498,967348625,832869781,3543655652,4069226873,3576883175,2336475336,1851340599,3669454189,25988493,2976175573,2631028302,1239460265,3635702892,2902087254,4077384948,3475368682,3400492389,4102978170,1206496942,270010376,1876277946,4035475576,1248797989,1550986798,941890588,1475454630,1942467764,2538718918,3408128232,2709315037,3902567540,1042358047,2531085131,1641856445,226921355,260409994,3767562352,2084716094,1908716981,3433719398,2430093384,100991747,4144101110,470945294,3265487201,1784624437,2935576407,1775286713,395413126,2572730817,975641885,666476190,3644383713,3943954680,733190296,573772049,3535497577,2842745305,126455438,866620564,766942107,1008868894,361924487,3374377449,2269761230,2868860245,1350051880,2776293343,59739276,1509466529,159418761,437718285,1708834751,3610371814,2227585602,3501746280,2193834305,699439513,1517759789,504434447,2076946608,2835108948,1842789307,742004246],v=8,w=14;r.exports={};var k=[128,192,256];for(var C in k)r.exports[k[C]]=p(k[C])},{"../../util":55}],5:[function(t,r){function e(){}function i(t){this.bf=new e,this.bf.init(n.str2bin(t)),this.encrypt=function(t){return this.bf.encrypt_block(t)}}e.prototype.BLOCKSIZE=8,e.prototype.SBOXES=[[3509652390,2564797868,805139163,3491422135,3101798381,1780907670,3128725573,4046225305,614570311,3012652279,134345442,2240740374,1667834072,1901547113,2757295779,4103290238,227898511,1921955416,1904987480,2182433518,2069144605,3260701109,2620446009,720527379,3318853667,677414384,3393288472,3101374703,2390351024,1614419982,1822297739,2954791486,3608508353,3174124327,2024746970,1432378464,3864339955,2857741204,1464375394,1676153920,1439316330,715854006,3033291828,289532110,2706671279,2087905683,3018724369,1668267050,732546397,1947742710,3462151702,2609353502,2950085171,1814351708,2050118529,680887927,999245976,1800124847,3300911131,1713906067,1641548236,4213287313,1216130144,1575780402,4018429277,3917837745,3693486850,3949271944,596196993,3549867205,258830323,2213823033,772490370,2760122372,1774776394,2652871518,566650946,4142492826,1728879713,2882767088,1783734482,3629395816,2517608232,2874225571,1861159788,326777828,3124490320,2130389656,2716951837,967770486,1724537150,2185432712,2364442137,1164943284,2105845187,998989502,3765401048,2244026483,1075463327,1455516326,1322494562,910128902,469688178,1117454909,936433444,3490320968,3675253459,1240580251,122909385,2157517691,634681816,4142456567,3825094682,3061402683,2540495037,79693498,3249098678,1084186820,1583128258,426386531,1761308591,1047286709,322548459,995290223,1845252383,2603652396,3431023940,2942221577,3202600964,3727903485,1712269319,422464435,3234572375,1170764815,3523960633,3117677531,1434042557,442511882,3600875718,1076654713,1738483198,4213154764,2393238008,3677496056,1014306527,4251020053,793779912,2902807211,842905082,4246964064,1395751752,1040244610,2656851899,3396308128,445077038,3742853595,3577915638,679411651,2892444358,2354009459,1767581616,3150600392,3791627101,3102740896,284835224,4246832056,1258075500,768725851,2589189241,3069724005,3532540348,1274779536,3789419226,2764799539,1660621633,3471099624,4011903706,913787905,3497959166,737222580,2514213453,2928710040,3937242737,1804850592,3499020752,2949064160,2386320175,2390070455,2415321851,4061277028,2290661394,2416832540,1336762016,1754252060,3520065937,3014181293,791618072,3188594551,3933548030,2332172193,3852520463,3043980520,413987798,3465142937,3030929376,4245938359,2093235073,3534596313,375366246,2157278981,2479649556,555357303,3870105701,2008414854,3344188149,4221384143,3956125452,2067696032,3594591187,2921233993,2428461,544322398,577241275,1471733935,610547355,4027169054,1432588573,1507829418,2025931657,3646575487,545086370,48609733,2200306550,1653985193,298326376,1316178497,3007786442,2064951626,458293330,2589141269,3591329599,3164325604,727753846,2179363840,146436021,1461446943,4069977195,705550613,3059967265,3887724982,4281599278,3313849956,1404054877,2845806497,146425753,1854211946],[1266315497,3048417604,3681880366,3289982499,290971e4,1235738493,2632868024,2414719590,3970600049,1771706367,1449415276,3266420449,422970021,1963543593,2690192192,3826793022,1062508698,1531092325,1804592342,2583117782,2714934279,4024971509,1294809318,4028980673,1289560198,2221992742,1669523910,35572830,157838143,1052438473,1016535060,1802137761,1753167236,1386275462,3080475397,2857371447,1040679964,2145300060,2390574316,1461121720,2956646967,4031777805,4028374788,33600511,2920084762,1018524850,629373528,3691585981,3515945977,2091462646,2486323059,586499841,988145025,935516892,3367335476,2599673255,2839830854,265290510,3972581182,2759138881,3795373465,1005194799,847297441,406762289,1314163512,1332590856,1866599683,4127851711,750260880,613907577,1450815602,3165620655,3734664991,3650291728,3012275730,3704569646,1427272223,778793252,1343938022,2676280711,2052605720,1946737175,3164576444,3914038668,3967478842,3682934266,1661551462,3294938066,4011595847,840292616,3712170807,616741398,312560963,711312465,1351876610,322626781,1910503582,271666773,2175563734,1594956187,70604529,3617834859,1007753275,1495573769,4069517037,2549218298,2663038764,504708206,2263041392,3941167025,2249088522,1514023603,1998579484,1312622330,694541497,2582060303,2151582166,1382467621,776784248,2618340202,3323268794,2497899128,2784771155,503983604,4076293799,907881277,423175695,432175456,1378068232,4145222326,3954048622,3938656102,3820766613,2793130115,2977904593,26017576,3274890735,3194772133,1700274565,1756076034,4006520079,3677328699,720338349,1533947780,354530856,688349552,3973924725,1637815568,332179504,3949051286,53804574,2852348879,3044236432,1282449977,3583942155,3416972820,4006381244,1617046695,2628476075,3002303598,1686838959,431878346,2686675385,1700445008,1080580658,1009431731,832498133,3223435511,2605976345,2271191193,2516031870,1648197032,4164389018,2548247927,300782431,375919233,238389289,3353747414,2531188641,2019080857,1475708069,455242339,2609103871,448939670,3451063019,1395535956,2413381860,1841049896,1491858159,885456874,4264095073,4001119347,1565136089,3898914787,1108368660,540939232,1173283510,2745871338,3681308437,4207628240,3343053890,4016749493,1699691293,1103962373,3625875870,2256883143,3830138730,1031889488,3479347698,1535977030,4236805024,3251091107,2132092099,1774941330,1199868427,1452454533,157007616,2904115357,342012276,595725824,1480756522,206960106,497939518,591360097,863170706,2375253569,3596610801,1814182875,2094937945,3421402208,1082520231,3463918190,2785509508,435703966,3908032597,1641649973,2842273706,3305899714,1510255612,2148256476,2655287854,3276092548,4258621189,236887753,3681803219,274041037,1734335097,3815195456,3317970021,1899903192,1026095262,4050517792,356393447,2410691914,3873677099,3682840055],[3913112168,2491498743,4132185628,2489919796,1091903735,1979897079,3170134830,3567386728,3557303409,857797738,1136121015,1342202287,507115054,2535736646,337727348,3213592640,1301675037,2528481711,1895095763,1721773893,3216771564,62756741,2142006736,835421444,2531993523,1442658625,3659876326,2882144922,676362277,1392781812,170690266,3921047035,1759253602,3611846912,1745797284,664899054,1329594018,3901205900,3045908486,2062866102,2865634940,3543621612,3464012697,1080764994,553557557,3656615353,3996768171,991055499,499776247,1265440854,648242737,3940784050,980351604,3713745714,1749149687,3396870395,4211799374,3640570775,1161844396,3125318951,1431517754,545492359,4268468663,3499529547,1437099964,2702547544,3433638243,2581715763,2787789398,1060185593,1593081372,2418618748,4260947970,69676912,2159744348,86519011,2512459080,3838209314,1220612927,3339683548,133810670,1090789135,1078426020,1569222167,845107691,3583754449,4072456591,1091646820,628848692,1613405280,3757631651,526609435,236106946,48312990,2942717905,3402727701,1797494240,859738849,992217954,4005476642,2243076622,3870952857,3732016268,765654824,3490871365,2511836413,1685915746,3888969200,1414112111,2273134842,3281911079,4080962846,172450625,2569994100,980381355,4109958455,2819808352,2716589560,2568741196,3681446669,3329971472,1835478071,660984891,3704678404,4045999559,3422617507,3040415634,1762651403,1719377915,3470491036,2693910283,3642056355,3138596744,1364962596,2073328063,1983633131,926494387,3423689081,2150032023,4096667949,1749200295,3328846651,309677260,2016342300,1779581495,3079819751,111262694,1274766160,443224088,298511866,1025883608,3806446537,1145181785,168956806,3641502830,3584813610,1689216846,3666258015,3200248200,1692713982,2646376535,4042768518,1618508792,1610833997,3523052358,4130873264,2001055236,3610705100,2202168115,4028541809,2961195399,1006657119,2006996926,3186142756,1430667929,3210227297,1314452623,4074634658,4101304120,2273951170,1399257539,3367210612,3027628629,1190975929,2062231137,2333990788,2221543033,2438960610,1181637006,548689776,2362791313,3372408396,3104550113,3145860560,296247880,1970579870,3078560182,3769228297,1714227617,3291629107,3898220290,166772364,1251581989,493813264,448347421,195405023,2709975567,677966185,3703036547,1463355134,2715995803,1338867538,1343315457,2802222074,2684532164,233230375,2599980071,2000651841,3277868038,1638401717,4028070440,3237316320,6314154,819756386,300326615,590932579,1405279636,3267499572,3150704214,2428286686,3959192993,3461946742,1862657033,1266418056,963775037,2089974820,2263052895,1917689273,448879540,3550394620,3981727096,150775221,3627908307,1303187396,508620638,2975983352,2726630617,1817252668,1876281319,1457606340,908771278,3720792119,3617206836,2455994898,1729034894,1080033504],[976866871,3556439503,2881648439,1522871579,1555064734,1336096578,3548522304,2579274686,3574697629,3205460757,3593280638,3338716283,3079412587,564236357,2993598910,1781952180,1464380207,3163844217,3332601554,1699332808,1393555694,1183702653,3581086237,1288719814,691649499,2847557200,2895455976,3193889540,2717570544,1781354906,1676643554,2592534050,3230253752,1126444790,2770207658,2633158820,2210423226,2615765581,2414155088,3127139286,673620729,2805611233,1269405062,4015350505,3341807571,4149409754,1057255273,2012875353,2162469141,2276492801,2601117357,993977747,3918593370,2654263191,753973209,36408145,2530585658,25011837,3520020182,2088578344,530523599,2918365339,1524020338,1518925132,3760827505,3759777254,1202760957,3985898139,3906192525,674977740,4174734889,2031300136,2019492241,3983892565,4153806404,3822280332,352677332,2297720250,60907813,90501309,3286998549,1016092578,2535922412,2839152426,457141659,509813237,4120667899,652014361,1966332200,2975202805,55981186,2327461051,676427537,3255491064,2882294119,3433927263,1307055953,942726286,933058658,2468411793,3933900994,4215176142,1361170020,2001714738,2830558078,3274259782,1222529897,1679025792,2729314320,3714953764,1770335741,151462246,3013232138,1682292957,1483529935,471910574,1539241949,458788160,3436315007,1807016891,3718408830,978976581,1043663428,3165965781,1927990952,4200891579,2372276910,3208408903,3533431907,1412390302,2931980059,4132332400,1947078029,3881505623,4168226417,2941484381,1077988104,1320477388,886195818,18198404,3786409e3,2509781533,112762804,3463356488,1866414978,891333506,18488651,661792760,1628790961,3885187036,3141171499,876946877,2693282273,1372485963,791857591,2686433993,3759982718,3167212022,3472953795,2716379847,445679433,3561995674,3504004811,3574258232,54117162,3331405415,2381918588,3769707343,4154350007,1140177722,4074052095,668550556,3214352940,367459370,261225585,2610173221,4209349473,3468074219,3265815641,314222801,3066103646,3808782860,282218597,3406013506,3773591054,379116347,1285071038,846784868,2669647154,3771962079,3550491691,2305946142,453669953,1268987020,3317592352,3279303384,3744833421,2610507566,3859509063,266596637,3847019092,517658769,3462560207,3443424879,370717030,4247526661,2224018117,4143653529,4112773975,2788324899,2477274417,1456262402,2901442914,1517677493,1846949527,2295493580,3734397586,2176403920,1280348187,1908823572,3871786941,846861322,1172426758,3287448474,3383383037,1655181056,3139813346,901632758,1897031941,2986607138,3066810236,3447102507,1393639104,373351379,950779232,625454576,3124240540,4148612726,2007998917,544563296,2244738638,2330496472,2058025392,1291430526,424198748,50039436,29584100,3605783033,2429876329,2791104160,1057563949,3255363231,3075367218,3463963227,1469046755,985887462]],e.prototype.PARRAY=[608135816,2242054355,320440878,57701188,2752067618,698298832,137296536,3964562569,1160258022,953160567,3193202383,887688300,3232508343,3380367581,1065670069,3041331479,2450970073,2306472731],e.prototype.NN=16,e.prototype._clean=function(t){if(0>t){var r=2147483647&t; t=r+2147483648}return t},e.prototype._F=function(t){var r,e,i,n,s;return n=255&t,t>>>=8,i=255&t,t>>>=8,e=255&t,t>>>=8,r=255&t,s=this.sboxes[0][r]+this.sboxes[1][e],s^=this.sboxes[2][i],s+=this.sboxes[3][n]},e.prototype._encrypt_block=function(t){var r,e=t[0],i=t[1];for(r=0;this.NN>r;++r){e^=this.parray[r],i=this._F(e)^i;var n=e;e=i,i=n}e^=this.parray[this.NN+0],i^=this.parray[this.NN+1],t[0]=this._clean(i),t[1]=this._clean(e)},e.prototype.encrypt_block=function(t){var r,e=[0,0],i=this.BLOCKSIZE/2;for(r=0;this.BLOCKSIZE/2>r;++r)e[0]=e[0]<<8|255&t[r+0],e[1]=e[1]<<8|255&t[r+i];this._encrypt_block(e);var n=[];for(r=0;this.BLOCKSIZE/2>r;++r)n[r+0]=255&e[0]>>>24-8*r,n[r+i]=255&e[1]>>>24-8*r;return n},e.prototype._decrypt_block=function(t){var r,e=t[0],i=t[1];for(r=this.NN+1;r>1;--r){e^=this.parray[r],i=this._F(e)^i;var n=e;e=i,i=n}e^=this.parray[1],i^=this.parray[0],t[0]=this._clean(i),t[1]=this._clean(e)},e.prototype.init=function(t){var r,e=0;for(this.parray=[],r=0;this.NN+2>r;++r){var i,n=0;for(i=0;4>i;++i)n=n<<8|255&t[e],++e>=t.length&&(e=0);this.parray[r]=this.PARRAY[r]^n}for(this.sboxes=[],r=0;4>r;++r)for(this.sboxes[r]=[],e=0;256>e;++e)this.sboxes[r][e]=this.SBOXES[r][e];var s=[0,0];for(r=0;this.NN+2>r;r+=2)this._encrypt_block(s),this.parray[r+0]=s[0],this.parray[r+1]=s[1];for(r=0;4>r;++r)for(e=0;256>e;e+=2)this._encrypt_block(s),this.sboxes[r][e+0]=s[0],this.sboxes[r][e+1]=s[1]};var n=t("../../util");r.exports=i,r.exports.keySize=i.prototype.keySize=16,r.exports.blockSize=i.prototype.blockSize=16},{"../../util":55}],6:[function(t,r){function e(){function t(t,r,e){var i=r+t,n=i<>>32-e;return(o[0][n>>>24]^o[1][255&n>>>16])-o[2][255&n>>>8]+o[3][255&n]}function r(t,r,e){var i=r^t,n=i<>>32-e;return o[0][n>>>24]-o[1][255&n>>>16]+o[2][255&n>>>8]^o[3][255&n]}function e(t,r,e){var i=r-t,n=i<>>32-e;return(o[0][n>>>24]+o[1][255&n>>>16]^o[2][255&n>>>8])-o[3][255&n]}this.BlockSize=8,this.KeySize=16,this.setKey=function(t){return this.masking=Array(16),this.rotate=Array(16),this.reset(),t.length!=this.KeySize?(n.print_error("cast5.js: CAST-128: keys must be 16 bytes"),!1):(this.keySchedule(t),!0)},this.reset=function(){for(var t=0;16>t;t++)this.masking[t]=0,this.rotate[t]=0},this.getBlockSize=function(){return BlockSize},this.encrypt=function(i){for(var n=Array(i.length),s=0;i.length>s;s+=8){var o,a=i[s]<<24|i[s+1]<<16|i[s+2]<<8|i[s+3],h=i[s+4]<<24|i[s+5]<<16|i[s+6]<<8|i[s+7];o=h,h=a^t(h,this.masking[0],this.rotate[0]),a=o,o=h,h=a^r(h,this.masking[1],this.rotate[1]),a=o,o=h,h=a^e(h,this.masking[2],this.rotate[2]),a=o,o=h,h=a^t(h,this.masking[3],this.rotate[3]),a=o,o=h,h=a^r(h,this.masking[4],this.rotate[4]),a=o,o=h,h=a^e(h,this.masking[5],this.rotate[5]),a=o,o=h,h=a^t(h,this.masking[6],this.rotate[6]),a=o,o=h,h=a^r(h,this.masking[7],this.rotate[7]),a=o,o=h,h=a^e(h,this.masking[8],this.rotate[8]),a=o,o=h,h=a^t(h,this.masking[9],this.rotate[9]),a=o,o=h,h=a^r(h,this.masking[10],this.rotate[10]),a=o,o=h,h=a^e(h,this.masking[11],this.rotate[11]),a=o,o=h,h=a^t(h,this.masking[12],this.rotate[12]),a=o,o=h,h=a^r(h,this.masking[13],this.rotate[13]),a=o,o=h,h=a^e(h,this.masking[14],this.rotate[14]),a=o,o=h,h=a^t(h,this.masking[15],this.rotate[15]),a=o,n[s]=255&h>>>24,n[s+1]=255&h>>>16,n[s+2]=255&h>>>8,n[s+3]=255&h,n[s+4]=255&a>>>24,n[s+5]=255&a>>>16,n[s+6]=255&a>>>8,n[s+7]=255&a}return n},this.decrypt=function(i){for(var n=Array(i.length),s=0;i.length>s;s+=8){var o,a=i[s]<<24|i[s+1]<<16|i[s+2]<<8|i[s+3],h=i[s+4]<<24|i[s+5]<<16|i[s+6]<<8|i[s+7];o=h,h=a^t(h,this.masking[15],this.rotate[15]),a=o,o=h,h=a^e(h,this.masking[14],this.rotate[14]),a=o,o=h,h=a^r(h,this.masking[13],this.rotate[13]),a=o,o=h,h=a^t(h,this.masking[12],this.rotate[12]),a=o,o=h,h=a^e(h,this.masking[11],this.rotate[11]),a=o,o=h,h=a^r(h,this.masking[10],this.rotate[10]),a=o,o=h,h=a^t(h,this.masking[9],this.rotate[9]),a=o,o=h,h=a^e(h,this.masking[8],this.rotate[8]),a=o,o=h,h=a^r(h,this.masking[7],this.rotate[7]),a=o,o=h,h=a^t(h,this.masking[6],this.rotate[6]),a=o,o=h,h=a^e(h,this.masking[5],this.rotate[5]),a=o,o=h,h=a^r(h,this.masking[4],this.rotate[4]),a=o,o=h,h=a^t(h,this.masking[3],this.rotate[3]),a=o,o=h,h=a^e(h,this.masking[2],this.rotate[2]),a=o,o=h,h=a^r(h,this.masking[1],this.rotate[1]),a=o,o=h,h=a^t(h,this.masking[0],this.rotate[0]),a=o,n[s]=255&h>>>24,n[s+1]=255&h>>>16,n[s+2]=255&h>>>8,n[s+3]=255&h,n[s+4]=255&a>>>24,n[s+5]=255&a>>16,n[s+6]=255&a>>8,n[s+7]=255&a}return n};var i=Array(4);i[0]=Array(4),i[0][0]=[4,0,13,15,12,14,8],i[0][1]=[5,2,16,18,17,19,10],i[0][2]=[6,3,23,22,21,20,9],i[0][3]=[7,1,26,25,27,24,11],i[1]=Array(4),i[1][0]=[0,6,21,23,20,22,16],i[1][1]=[1,4,0,2,1,3,18],i[1][2]=[2,5,7,6,5,4,17],i[1][3]=[3,7,10,9,11,8,19],i[2]=Array(4),i[2][0]=[4,0,13,15,12,14,8],i[2][1]=[5,2,16,18,17,19,10],i[2][2]=[6,3,23,22,21,20,9],i[2][3]=[7,1,26,25,27,24,11],i[3]=Array(4),i[3][0]=[0,6,21,23,20,22,16],i[3][1]=[1,4,0,2,1,3,18],i[3][2]=[2,5,7,6,5,4,17],i[3][3]=[3,7,10,9,11,8,19];var s=Array(4);s[0]=Array(4),s[0][0]=[24,25,23,22,18],s[0][1]=[26,27,21,20,22],s[0][2]=[28,29,19,18,25],s[0][3]=[30,31,17,16,28],s[1]=Array(4),s[1][0]=[3,2,12,13,8],s[1][1]=[1,0,14,15,13],s[1][2]=[7,6,8,9,3],s[1][3]=[5,4,10,11,7],s[2]=Array(4),s[2][0]=[19,18,28,29,25],s[2][1]=[17,16,30,31,28],s[2][2]=[23,22,24,25,18],s[2][3]=[21,20,26,27,22],s[3]=Array(4),s[3][0]=[8,9,7,6,3],s[3][1]=[10,11,5,4,7],s[3][2]=[12,13,3,2,8],s[3][3]=[14,15,1,0,13],this.keySchedule=function(t){for(var r=Array(8),e=Array(32),n=0;4>n;n++){var a=4*n;r[n]=t[a]<<24|t[a+1]<<16|t[a+2]<<8|t[a+3]}for(var h=[6,7,4,5],c=0,u=0;2>u;u++)for(var p=0;4>p;p++){for(var a=0;4>a;a++){var l=i[p][a],f=r[l[1]];f^=o[4][255&r[l[2]>>>2]>>>24-8*(3&l[2])],f^=o[5][255&r[l[3]>>>2]>>>24-8*(3&l[3])],f^=o[6][255&r[l[4]>>>2]>>>24-8*(3&l[4])],f^=o[7][255&r[l[5]>>>2]>>>24-8*(3&l[5])],f^=o[h[a]][255&r[l[6]>>>2]>>>24-8*(3&l[6])],r[l[0]]=f}for(var a=0;4>a;a++){var d=s[p][a],f=o[4][255&r[d[0]>>>2]>>>24-8*(3&d[0])];f^=o[5][255&r[d[1]>>>2]>>>24-8*(3&d[1])],f^=o[6][255&r[d[2]>>>2]>>>24-8*(3&d[2])],f^=o[7][255&r[d[3]>>>2]>>>24-8*(3&d[3])],f^=o[4+a][255&r[d[4]>>>2]>>>24-8*(3&d[4])],e[c]=f,c++}}for(var n=0;16>n;n++)this.masking[n]=e[n],this.rotate[n]=31&e[16+n]};var o=Array(8);o[0]=[821772500,2678128395,1810681135,1059425402,505495343,2617265619,1610868032,3483355465,3218386727,2294005173,3791863952,2563806837,1852023008,365126098,3269944861,584384398,677919599,3229601881,4280515016,2002735330,1136869587,3744433750,2289869850,2731719981,2714362070,879511577,1639411079,575934255,717107937,2857637483,576097850,2731753936,1725645e3,2810460463,5111599,767152862,2543075244,1251459544,1383482551,3052681127,3089939183,3612463449,1878520045,1510570527,2189125840,2431448366,582008916,3163445557,1265446783,1354458274,3529918736,3202711853,3073581712,3912963487,3029263377,1275016285,4249207360,2905708351,3304509486,1442611557,3585198765,2712415662,2731849581,3248163920,2283946226,208555832,2766454743,1331405426,1447828783,3315356441,3108627284,2957404670,2981538698,3339933917,1669711173,286233437,1465092821,1782121619,3862771680,710211251,980974943,1651941557,430374111,2051154026,704238805,4128970897,3144820574,2857402727,948965521,3333752299,2227686284,718756367,2269778983,2731643755,718440111,2857816721,3616097120,1113355533,2478022182,410092745,1811985197,1944238868,2696854588,1415722873,1682284203,1060277122,1998114690,1503841958,82706478,2315155686,1068173648,845149890,2167947013,1768146376,1993038550,3566826697,3390574031,940016341,3355073782,2328040721,904371731,1205506512,4094660742,2816623006,825647681,85914773,2857843460,1249926541,1417871568,3287612,3211054559,3126306446,1975924523,1353700161,2814456437,2438597621,1800716203,722146342,2873936343,1151126914,4160483941,2877670899,458611604,2866078500,3483680063,770352098,2652916994,3367839148,3940505011,3585973912,3809620402,718646636,2504206814,2914927912,3631288169,2857486607,2860018678,575749918,2857478043,718488780,2069512688,3548183469,453416197,1106044049,3032691430,52586708,3378514636,3459808877,3211506028,1785789304,218356169,3571399134,3759170522,1194783844,1523787992,3007827094,1975193539,2555452411,1341901877,3045838698,3776907964,3217423946,2802510864,2889438986,1057244207,1636348243,3761863214,1462225785,2632663439,481089165,718503062,24497053,3332243209,3344655856,3655024856,3960371065,1195698900,2971415156,3710176158,2115785917,4027663609,3525578417,2524296189,2745972565,3564906415,1372086093,1452307862,2780501478,1476592880,3389271281,18495466,2378148571,901398090,891748256,3279637769,3157290713,2560960102,1447622437,4284372637,216884176,2086908623,1879786977,3588903153,2242455666,2938092967,3559082096,2810645491,758861177,1121993112,215018983,642190776,4169236812,1196255959,2081185372,3508738393,941322904,4124243163,2877523539,1848581667,2205260958,3180453958,2589345134,3694731276,550028657,2519456284,3789985535,2973870856,2093648313,443148163,46942275,2734146937,1117713533,1115362972,1523183689,3717140224,1551984063],o[1]=[522195092,4010518363,1776537470,960447360,4267822970,4005896314,1435016340,1929119313,2913464185,1310552629,3579470798,3724818106,2579771631,1594623892,417127293,2715217907,2696228731,1508390405,3994398868,3925858569,3695444102,4019471449,3129199795,3770928635,3520741761,990456497,4187484609,2783367035,21106139,3840405339,631373633,3783325702,532942976,396095098,3548038825,4267192484,2564721535,2011709262,2039648873,620404603,3776170075,2898526339,3612357925,4159332703,1645490516,223693667,1567101217,3362177881,1029951347,3470931136,3570957959,1550265121,119497089,972513919,907948164,3840628539,1613718692,3594177948,465323573,2659255085,654439692,2575596212,2699288441,3127702412,277098644,624404830,4100943870,2717858591,546110314,2403699828,3655377447,1321679412,4236791657,1045293279,4010672264,895050893,2319792268,494945126,1914543101,2777056443,3894764339,2219737618,311263384,4275257268,3458730721,669096869,3584475730,3835122877,3319158237,3949359204,2005142349,2713102337,2228954793,3769984788,569394103,3855636576,1425027204,108000370,2736431443,3671869269,3043122623,1750473702,2211081108,762237499,3972989403,2798899386,3061857628,2943854345,867476300,964413654,1591880597,1594774276,2179821409,552026980,3026064248,3726140315,2283577634,3110545105,2152310760,582474363,1582640421,1383256631,2043843868,3322775884,1217180674,463797851,2763038571,480777679,2718707717,2289164131,3118346187,214354409,200212307,3810608407,3025414197,2674075964,3997296425,1847405948,1342460550,510035443,4080271814,815934613,833030224,1620250387,1945732119,2703661145,3966000196,1388869545,3456054182,2687178561,2092620194,562037615,1356438536,3409922145,3261847397,1688467115,2150901366,631725691,3840332284,549916902,3455104640,394546491,837744717,2114462948,751520235,2221554606,2415360136,3999097078,2063029875,803036379,2702586305,821456707,3019566164,360699898,4018502092,3511869016,3677355358,2402471449,812317050,49299192,2570164949,3259169295,2816732080,3331213574,3101303564,2156015656,3705598920,3546263921,143268808,3200304480,1638124008,3165189453,3341807610,578956953,2193977524,3638120073,2333881532,807278310,658237817,2969561766,1641658566,11683945,3086995007,148645947,1138423386,4158756760,1981396783,2401016740,3699783584,380097457,2680394679,2803068651,3334260286,441530178,4016580796,1375954390,761952171,891809099,2183123478,157052462,3683840763,1592404427,341349109,2438483839,1417898363,644327628,2233032776,2353769706,2201510100,220455161,1815641738,182899273,2995019788,3627381533,3702638151,2890684138,1052606899,588164016,1681439879,4038439418,2405343923,4229449282,167996282,1336969661,1688053129,2739224926,1543734051,1046297529,1138201970,2121126012,115334942,1819067631,1902159161,1941945968,2206692869,1159982321],o[2]=[2381300288,637164959,3952098751,3893414151,1197506559,916448331,2350892612,2932787856,3199334847,4009478890,3905886544,1373570990,2450425862,4037870920,3778841987,2456817877,286293407,124026297,3001279700,1028597854,3115296800,4208886496,2691114635,2188540206,1430237888,1218109995,3572471700,308166588,570424558,2187009021,2455094765,307733056,1310360322,3135275007,1384269543,2388071438,863238079,2359263624,2801553128,3380786597,2831162807,1470087780,1728663345,4072488799,1090516929,532123132,2389430977,1132193179,2578464191,3051079243,1670234342,1434557849,2711078940,1241591150,3314043432,3435360113,3091448339,1812415473,2198440252,267246943,796911696,3619716990,38830015,1526438404,2806502096,374413614,2943401790,1489179520,1603809326,1920779204,168801282,260042626,2358705581,1563175598,2397674057,1356499128,2217211040,514611088,2037363785,2186468373,4022173083,2792511869,2913485016,1173701892,4200428547,3896427269,1334932762,2455136706,602925377,2835607854,1613172210,41346230,2499634548,2457437618,2188827595,41386358,4172255629,1313404830,2405527007,3801973774,2217704835,873260488,2528884354,2478092616,4012915883,2555359016,2006953883,2463913485,575479328,2218240648,2099895446,660001756,2341502190,3038761536,3888151779,3848713377,3286851934,1022894237,1620365795,3449594689,1551255054,15374395,3570825345,4249311020,4151111129,3181912732,310226346,1133119310,530038928,136043402,2476768958,3107506709,2544909567,1036173560,2367337196,1681395281,1758231547,3641649032,306774401,1575354324,3716085866,1990386196,3114533736,2455606671,1262092282,3124342505,2768229131,4210529083,1833535011,423410938,660763973,2187129978,1639812e3,3508421329,3467445492,310289298,272797111,2188552562,2456863912,310240523,677093832,1013118031,901835429,3892695601,1116285435,3036471170,1337354835,243122523,520626091,277223598,4244441197,4194248841,1766575121,594173102,316590669,742362309,3536858622,4176435350,3838792410,2501204839,1229605004,3115755532,1552908988,2312334149,979407927,3959474601,1148277331,176638793,3614686272,2083809052,40992502,1340822838,2731552767,3535757508,3560899520,1354035053,122129617,7215240,2732932949,3118912700,2718203926,2539075635,3609230695,3725561661,1928887091,2882293555,1988674909,2063640240,2491088897,1459647954,4189817080,2302804382,1113892351,2237858528,1927010603,4002880361,1856122846,1594404395,2944033133,3855189863,3474975698,1643104450,4054590833,3431086530,1730235576,2984608721,3084664418,2131803598,4178205752,267404349,1617849798,1616132681,1462223176,736725533,2327058232,551665188,2945899023,1749386277,2575514597,1611482493,674206544,2201269090,3642560800,728599968,1680547377,2620414464,1388111496,453204106,4156223445,1094905244,2754698257,2201108165,3757000246,2704524545,3922940700,3996465027],o[3]=[2645754912,532081118,2814278639,3530793624,1246723035,1689095255,2236679235,4194438865,2116582143,3859789411,157234593,2045505824,4245003587,1687664561,4083425123,605965023,672431967,1336064205,3376611392,214114848,4258466608,3232053071,489488601,605322005,3998028058,264917351,1912574028,756637694,436560991,202637054,135989450,85393697,2152923392,3896401662,2895836408,2145855233,3535335007,115294817,3147733898,1922296357,3464822751,4117858305,1037454084,2725193275,2127856640,1417604070,1148013728,1827919605,642362335,2929772533,909348033,1346338451,3547799649,297154785,1917849091,4161712827,2883604526,3968694238,1469521537,3780077382,3375584256,1763717519,136166297,4290970789,1295325189,2134727907,2798151366,1566297257,3672928234,2677174161,2672173615,965822077,2780786062,289653839,1133871874,3491843819,35685304,1068898316,418943774,672553190,642281022,2346158704,1954014401,3037126780,4079815205,2030668546,3840588673,672283427,1776201016,359975446,3750173538,555499703,2769985273,1324923,69110472,152125443,3176785106,3822147285,1340634837,798073664,1434183902,15393959,216384236,1303690150,3881221631,3711134124,3960975413,106373927,2578434224,1455997841,1801814300,1578393881,1854262133,3188178946,3258078583,2302670060,1539295533,3505142565,3078625975,2372746020,549938159,3278284284,2620926080,181285381,2865321098,3970029511,68876850,488006234,1728155692,2608167508,836007927,2435231793,919367643,3339422534,3655756360,1457871481,40520939,1380155135,797931188,234455205,2255801827,3990488299,397000196,739833055,3077865373,2871719860,4022553888,772369276,390177364,3853951029,557662966,740064294,1640166671,1699928825,3535942136,622006121,3625353122,68743880,1742502,219489963,1664179233,1577743084,1236991741,410585305,2366487942,823226535,1050371084,3426619607,3586839478,212779912,4147118561,1819446015,1911218849,530248558,3486241071,3252585495,2886188651,3410272728,2342195030,20547779,2982490058,3032363469,3631753222,312714466,1870521650,1493008054,3491686656,615382978,4103671749,2534517445,1932181,2196105170,278426614,6369430,3274544417,2913018367,697336853,2143000447,2946413531,701099306,1558357093,2805003052,3500818408,2321334417,3567135975,216290473,3591032198,23009561,1996984579,3735042806,2024298078,3739440863,569400510,2339758983,3016033873,3097871343,3639523026,3844324983,3256173865,795471839,2951117563,4101031090,4091603803,3603732598,971261452,534414648,428311343,3389027175,2844869880,694888862,1227866773,2456207019,3043454569,2614353370,3749578031,3676663836,459166190,4132644070,1794958188,51825668,2252611902,3084671440,2036672799,3436641603,1099053433,2469121526,3059204941,1323291266,2061838604,1018778475,2233344254,2553501054,334295216,3556750194,1065731521,183467730],o[4]=[2127105028,745436345,2601412319,2788391185,3093987327,500390133,1155374404,389092991,150729210,3891597772,3523549952,1935325696,716645080,946045387,2901812282,1774124410,3869435775,4039581901,3293136918,3438657920,948246080,363898952,3867875531,1286266623,1598556673,68334250,630723836,1104211938,1312863373,613332731,2377784574,1101634306,441780740,3129959883,1917973735,2510624549,3238456535,2544211978,3308894634,1299840618,4076074851,1756332096,3977027158,297047435,3790297736,2265573040,3621810518,1311375015,1667687725,47300608,3299642885,2474112369,201668394,1468347890,576830978,3594690761,3742605952,1958042578,1747032512,3558991340,1408974056,3366841779,682131401,1033214337,1545599232,4265137049,206503691,103024618,2855227313,1337551222,2428998917,2963842932,4015366655,3852247746,2796956967,3865723491,3747938335,247794022,3755824572,702416469,2434691994,397379957,851939612,2314769512,218229120,1380406772,62274761,214451378,3170103466,2276210409,3845813286,28563499,446592073,1693330814,3453727194,29968656,3093872512,220656637,2470637031,77972100,1667708854,1358280214,4064765667,2395616961,325977563,4277240721,4220025399,3605526484,3355147721,811859167,3069544926,3962126810,652502677,3075892249,4132761541,3498924215,1217549313,3250244479,3858715919,3053989961,1538642152,2279026266,2875879137,574252750,3324769229,2651358713,1758150215,141295887,2719868960,3515574750,4093007735,4194485238,1082055363,3417560400,395511885,2966884026,179534037,3646028556,3738688086,1092926436,2496269142,257381841,3772900718,1636087230,1477059743,2499234752,3811018894,2675660129,3285975680,90732309,1684827095,1150307763,1723134115,3237045386,1769919919,1240018934,815675215,750138730,2239792499,1234303040,1995484674,138143821,675421338,1145607174,1936608440,3238603024,2345230278,2105974004,323969391,779555213,3004902369,2861610098,1017501463,2098600890,2628620304,2940611490,2682542546,1171473753,3656571411,3687208071,4091869518,393037935,159126506,1662887367,1147106178,391545844,3452332695,1891500680,3016609650,1851642611,546529401,1167818917,3194020571,2848076033,3953471836,575554290,475796850,4134673196,450035699,2351251534,844027695,1080539133,86184846,1554234488,3692025454,1972511363,2018339607,1491841390,1141460869,1061690759,4244549243,2008416118,2351104703,2868147542,1598468138,722020353,1027143159,212344630,1387219594,1725294528,3745187956,2500153616,458938280,4129215917,1828119673,544571780,3503225445,2297937496,1241802790,267843827,2694610800,1397140384,1558801448,3782667683,1806446719,929573330,2234912681,400817706,616011623,4121520928,3603768725,1761550015,1968522284,4053731006,4192232858,4005120285,872482584,3140537016,3894607381,2287405443,1963876937,3663887957,1584857e3,2975024454,1833426440,4025083860],o[5]=[4143615901,749497569,1285769319,3795025788,2514159847,23610292,3974978748,844452780,3214870880,3751928557,2213566365,1676510905,448177848,3730751033,4086298418,2307502392,871450977,3222878141,4110862042,3831651966,2735270553,1310974780,2043402188,1218528103,2736035353,4274605013,2702448458,3936360550,2693061421,162023535,2827510090,687910808,23484817,3784910947,3371371616,779677500,3503626546,3473927188,4157212626,3500679282,4248902014,2466621104,3899384794,1958663117,925738300,1283408968,3669349440,1840910019,137959847,2679828185,1239142320,1315376211,1547541505,1690155329,739140458,3128809933,3933172616,3876308834,905091803,1548541325,4040461708,3095483362,144808038,451078856,676114313,2861728291,2469707347,993665471,373509091,2599041286,4025009006,4170239449,2149739950,3275793571,3749616649,2794760199,1534877388,572371878,2590613551,1753320020,3467782511,1405125690,4270405205,633333386,3026356924,3475123903,632057672,2846462855,1404951397,3882875879,3915906424,195638627,2385783745,3902872553,1233155085,3355999740,2380578713,2702246304,2144565621,3663341248,3894384975,2502479241,4248018925,3094885567,1594115437,572884632,3385116731,767645374,1331858858,1475698373,3793881790,3532746431,1321687957,619889600,1121017241,3440213920,2070816767,2833025776,1933951238,4095615791,890643334,3874130214,859025556,360630002,925594799,1764062180,3920222280,4078305929,979562269,2810700344,4087740022,1949714515,546639971,1165388173,3069891591,1495988560,922170659,1291546247,2107952832,1813327274,3406010024,3306028637,4241950635,153207855,2313154747,1608695416,1150242611,1967526857,721801357,1220138373,3691287617,3356069787,2112743302,3281662835,1111556101,1778980689,250857638,2298507990,673216130,2846488510,3207751581,3562756981,3008625920,3417367384,2198807050,529510932,3547516680,3426503187,2364944742,102533054,2294910856,1617093527,1204784762,3066581635,1019391227,1069574518,1317995090,1691889997,3661132003,510022745,3238594800,1362108837,1817929911,2184153760,805817662,1953603311,3699844737,120799444,2118332377,207536705,2282301548,4120041617,145305846,2508124933,3086745533,3261524335,1877257368,2977164480,3160454186,2503252186,4221677074,759945014,254147243,2767453419,3801518371,629083197,2471014217,907280572,3900796746,940896768,2751021123,2625262786,3161476951,3661752313,3260732218,1425318020,2977912069,1496677566,3988592072,2140652971,3126511541,3069632175,977771578,1392695845,1698528874,1411812681,1369733098,1343739227,3620887944,1142123638,67414216,3102056737,3088749194,1626167401,2546293654,3941374235,697522451,33404913,143560186,2595682037,994885535,1247667115,3859094837,2699155541,3547024625,4114935275,2968073508,3199963069,2732024527,1237921620,951448369,1898488916,1211705605,2790989240,2233243581,3598044975],o[6]=[2246066201,858518887,1714274303,3485882003,713916271,2879113490,3730835617,539548191,36158695,1298409750,419087104,1358007170,749914897,2989680476,1261868530,2995193822,2690628854,3443622377,3780124940,3796824509,2976433025,4259637129,1551479e3,512490819,1296650241,951993153,2436689437,2460458047,144139966,3136204276,310820559,3068840729,643875328,1969602020,1680088954,2185813161,3283332454,672358534,198762408,896343282,276269502,3014846926,84060815,197145886,376173866,3943890818,3813173521,3545068822,1316698879,1598252827,2633424951,1233235075,859989710,2358460855,3503838400,3409603720,1203513385,1193654839,2792018475,2060853022,207403770,1144516871,3068631394,1121114134,177607304,3785736302,326409831,1929119770,2983279095,4183308101,3474579288,3200513878,3228482096,119610148,1170376745,3378393471,3163473169,951863017,3337026068,3135789130,2907618374,1183797387,2015970143,4045674555,2182986399,2952138740,3928772205,384012900,2454997643,10178499,2879818989,2596892536,111523738,2995089006,451689641,3196290696,235406569,1441906262,3890558523,3013735005,4158569349,1644036924,376726067,1006849064,3664579700,2041234796,1021632941,1374734338,2566452058,371631263,4007144233,490221539,206551450,3140638584,1053219195,1853335209,3412429660,3562156231,735133835,1623211703,3104214392,2738312436,4096837757,3366392578,3110964274,3956598718,3196820781,2038037254,3877786376,2339753847,300912036,3766732888,2372630639,1516443558,4200396704,1574567987,4069441456,4122592016,2699739776,146372218,2748961456,2043888151,35287437,2596680554,655490400,1132482787,110692520,1031794116,2188192751,1324057718,1217253157,919197030,686247489,3261139658,1028237775,3135486431,3059715558,2460921700,986174950,2661811465,4062904701,2752986992,3709736643,367056889,1353824391,731860949,1650113154,1778481506,784341916,357075625,3608602432,1074092588,2480052770,3811426202,92751289,877911070,3600361838,1231880047,480201094,3756190983,3094495953,434011822,87971354,363687820,1717726236,1901380172,3926403882,2481662265,400339184,1490350766,2661455099,1389319756,2558787174,784598401,1983468483,30828846,3550527752,2716276238,3841122214,1765724805,1955612312,1277890269,1333098070,1564029816,2704417615,1026694237,3287671188,1260819201,3349086767,1016692350,1582273796,1073413053,1995943182,694588404,1025494639,3323872702,3551898420,4146854327,453260480,1316140391,1435673405,3038941953,3486689407,1622062951,403978347,817677117,950059133,4246079218,3278066075,1486738320,1417279718,481875527,2549965225,3933690356,760697757,1452955855,3897451437,1177426808,1702951038,4085348628,2447005172,1084371187,3516436277,3068336338,1073369276,1027665953,3284188590,1230553676,1368340146,2226246512,267243139,2274220762,4070734279,2497715176,2423353163,2504755875],o[7]=[3793104909,3151888380,2817252029,895778965,2005530807,3871412763,237245952,86829237,296341424,3851759377,3974600970,2475086196,709006108,1994621201,2972577594,937287164,3734691505,168608556,3189338153,2225080640,3139713551,3033610191,3025041904,77524477,185966941,1208824168,2344345178,1721625922,3354191921,1066374631,1927223579,1971335949,2483503697,1551748602,2881383779,2856329572,3003241482,48746954,1398218158,2050065058,313056748,4255789917,393167848,1912293076,940740642,3465845460,3091687853,2522601570,2197016661,1727764327,364383054,492521376,1291706479,3264136376,1474851438,1685747964,2575719748,1619776915,1814040067,970743798,1561002147,2925768690,2123093554,1880132620,3151188041,697884420,2550985770,2607674513,2659114323,110200136,1489731079,997519150,1378877361,3527870668,478029773,2766872923,1022481122,431258168,1112503832,897933369,2635587303,669726182,3383752315,918222264,163866573,3246985393,3776823163,114105080,1903216136,761148244,3571337562,1690750982,3166750252,1037045171,1888456500,2010454850,642736655,616092351,365016990,1185228132,4174898510,1043824992,2023083429,2241598885,3863320456,3279669087,3674716684,108438443,2132974366,830746235,606445527,4173263986,2204105912,1844756978,2532684181,4245352700,2969441100,3796921661,1335562986,4061524517,2720232303,2679424040,634407289,885462008,3294724487,3933892248,2094100220,339117932,4048830727,3202280980,1458155303,2689246273,1022871705,2464987878,3714515309,353796843,2822958815,4256850100,4052777845,551748367,618185374,3778635579,4020649912,1904685140,3069366075,2670879810,3407193292,2954511620,4058283405,2219449317,3135758300,1120655984,3447565834,1474845562,3577699062,550456716,3466908712,2043752612,881257467,869518812,2005220179,938474677,3305539448,3850417126,1315485940,3318264702,226533026,965733244,321539988,1136104718,804158748,573969341,3708209826,937399083,3290727049,2901666755,1461057207,4013193437,4066861423,3242773476,2421326174,1581322155,3028952165,786071460,3900391652,3918438532,1485433313,4023619836,3708277595,3678951060,953673138,1467089153,1930354364,1533292819,2492563023,1346121658,1685000834,1965281866,3765933717,4190206607,2052792609,3515332758,690371149,3125873887,2180283551,2903598061,3933952357,436236910,289419410,14314871,1242357089,2904507907,1616633776,2666382180,585885352,3471299210,2699507360,1432659641,277164553,3354103607,770115018,2303809295,3741942315,3177781868,2853364978,2269453327,3774259834,987383833,1290892879,225909803,1741533526,890078084,1496906255,1111072499,916028167,243534141,1252605537,2204162171,531204876,290011180,3916834213,102027703,237315147,209093447,1486785922,220223953,2758195998,4175039106,82940208,3127791296,2569425252,518464269,1353887104,3941492737,2377294467,3935040926]}function i(t){this.cast5=new e,this.cast5.setKey(n.str2bin(t)),this.encrypt=function(t){return this.cast5.encrypt(t)}}var n=t("../../util");r.exports=i,r.exports.blockSize=i.prototype.blockSize=8,r.exports.keySize=i.prototype.keySize=16},{"../../util":55}],7:[function(t,r){function e(t,r,e,i,n,a){var h,c,u,p,l,f,d,g,m,y,b,v,w,k,C=[16843776,0,65536,16843780,16842756,66564,4,65536,1024,16843776,16843780,1024,16778244,16842756,16777216,4,1028,16778240,16778240,66560,66560,16842752,16842752,16778244,65540,16777220,16777220,65540,0,1028,66564,16777216,65536,16843780,4,16842752,16843776,16777216,16777216,1024,16842756,65536,66560,16777220,1024,4,16778244,66564,16843780,65540,16842752,16778244,16777220,1028,66564,16843776,1028,16778240,16778240,0,65540,66560,0,16842756],A=[-2146402272,-2147450880,32768,1081376,1048576,32,-2146435040,-2147450848,-2147483616,-2146402272,-2146402304,-2147483648,-2147450880,1048576,32,-2146435040,1081344,1048608,-2147450848,0,-2147483648,32768,1081376,-2146435072,1048608,-2147483616,0,1081344,32800,-2146402304,-2146435072,32800,0,1081376,-2146435040,1048576,-2147450848,-2146435072,-2146402304,32768,-2146435072,-2147450880,32,-2146402272,1081376,32,32768,-2147483648,32800,-2146402304,1048576,-2147483616,1048608,-2147450848,-2147483616,1048608,1081344,0,-2147450880,32800,-2147483648,-2146435040,-2146402272,1081344],_=[520,134349312,0,134348808,134218240,0,131592,134218240,131080,134217736,134217736,131072,134349320,131080,134348800,520,134217728,8,134349312,512,131584,134348800,134348808,131592,134218248,131584,131072,134218248,8,134349320,512,134217728,134349312,134217728,131080,520,131072,134349312,134218240,0,512,131080,134349320,134218240,134217736,512,0,134348808,134218248,131072,134217728,134349320,8,131592,131584,134217736,134348800,134218248,520,134348800,131592,8,134348808,131584],S=[8396801,8321,8321,128,8396928,8388737,8388609,8193,0,8396800,8396800,8396929,129,0,8388736,8388609,1,8192,8388608,8396801,128,8388608,8193,8320,8388737,1,8320,8388736,8192,8396928,8396929,129,8388736,8388609,8396800,8396929,129,0,0,8396800,8320,8388736,8388737,1,8396801,8321,8321,128,8396929,129,1,8192,8388609,8193,8396928,8388737,8193,8320,8388608,8396801,128,8388608,8192,8396928],j=[256,34078976,34078720,1107296512,524288,256,1073741824,34078720,1074266368,524288,33554688,1074266368,1107296512,1107820544,524544,1073741824,33554432,1074266112,1074266112,0,1073742080,1107820800,1107820800,33554688,1107820544,1073742080,0,1107296256,34078976,33554432,1107296256,524544,524288,1107296512,256,33554432,1073741824,34078720,1107296512,1074266368,33554688,1073741824,1107820544,34078976,1074266368,256,33554432,1107820544,1107820800,524544,1107296256,1107820800,34078720,0,1074266112,1107296256,524544,33554688,1073742080,524288,0,1074266112,34078976,1073742080],T=[536870928,541065216,16384,541081616,541065216,16,541081616,4194304,536887296,4210704,4194304,536870928,4194320,536887296,536870912,16400,0,4194320,536887312,16384,4210688,536887312,16,541065232,541065232,0,4210704,541081600,16400,4210688,541081600,536870912,536887296,16,541065232,4210688,541081616,4194304,16400,536870928,4194304,536887296,536870912,16400,536870928,541081616,4210688,541065216,4210704,541081600,0,541065232,16,16384,541065216,4210704,16384,4194320,536887312,0,541081600,536870912,4194320,536887312],O=[2097152,69206018,67110914,0,2048,67110914,2099202,69208064,69208066,2097152,0,67108866,2,67108864,69206018,2050,67110912,2099202,2097154,67110912,67108866,69206016,69208064,2097154,69206016,2048,2050,69208066,2099200,2,67108864,2099200,67108864,2099200,2097152,67110914,67110914,69206018,69206018,2,2097154,67108864,67110912,2097152,69208064,2050,2099202,69208064,2050,67108866,69208066,69206016,2099200,0,2,69208066,0,2099202,69206016,2048,67108866,67110912,2048,2097154],E=[268439616,4096,262144,268701760,268435456,268439616,64,268435456,262208,268697600,268701760,266240,268701696,266304,4096,64,268697600,268435520,268439552,4160,266240,262208,268697664,268701696,4160,0,0,268697664,268435520,268439552,266304,262144,266304,262144,268701696,4096,64,268697664,4096,266304,268439552,64,268435520,268697600,268697664,268435456,262144,268439616,0,268701760,262208,268435520,268697600,268439552,268439616,0,268701760,266240,266240,4160,4160,262208,268435456,268701696],I=0,B=r.length,x=0,P=32==t.length?3:9; -for(g=3==P?e?[0,32,2]:[30,-2,-2]:e?[0,32,2,62,30,-2,64,96,2]:[94,62,-2,32,64,2,30,-2,-2],e&&(r=s(r,a),B=r.length),result="",tempresult="",1==i&&(m=n.charCodeAt(I++)<<24|n.charCodeAt(I++)<<16|n.charCodeAt(I++)<<8|n.charCodeAt(I++),b=n.charCodeAt(I++)<<24|n.charCodeAt(I++)<<16|n.charCodeAt(I++)<<8|n.charCodeAt(I++),I=0);B>I;){for(f=r.charCodeAt(I++)<<24|r.charCodeAt(I++)<<16|r.charCodeAt(I++)<<8|r.charCodeAt(I++),d=r.charCodeAt(I++)<<24|r.charCodeAt(I++)<<16|r.charCodeAt(I++)<<8|r.charCodeAt(I++),1==i&&(e?(f^=m,d^=b):(y=m,v=b,m=f,b=d)),u=252645135&(f>>>4^d),d^=u,f^=u<<4,u=65535&(f>>>16^d),d^=u,f^=u<<16,u=858993459&(d>>>2^f),f^=u,d^=u<<2,u=16711935&(d>>>8^f),f^=u,d^=u<<8,u=1431655765&(f>>>1^d),d^=u,f^=u<<1,f=f<<1|f>>>31,d=d<<1|d>>>31,c=0;P>c;c+=3){for(w=g[c+1],k=g[c+2],h=g[c];h!=w;h+=k)p=d^t[h],l=(d>>>4|d<<28)^t[h+1],u=f,f=d,d=u^(A[63&p>>>24]|S[63&p>>>16]|T[63&p>>>8]|E[63&p]|C[63&l>>>24]|_[63&l>>>16]|j[63&l>>>8]|O[63&l]);u=f,f=d,d=u}f=f>>>1|f<<31,d=d>>>1|d<<31,u=1431655765&(f>>>1^d),d^=u,f^=u<<1,u=16711935&(d>>>8^f),f^=u,d^=u<<8,u=858993459&(d>>>2^f),f^=u,d^=u<<2,u=65535&(f>>>16^d),d^=u,f^=u<<16,u=252645135&(f>>>4^d),d^=u,f^=u<<4,1==i&&(e?(m=f,b=d):(f^=y,d^=v)),tempresult+=String.fromCharCode(f>>>24,255&f>>>16,255&f>>>8,255&f,d>>>24,255&d>>>16,255&d>>>8,255&d),x+=8,512==x&&(result+=tempresult,tempresult="",x=0)}return result+=tempresult,e||(result=o(result,a)),result}function n(t){pc2bytes0=[0,4,536870912,536870916,65536,65540,536936448,536936452,512,516,536871424,536871428,66048,66052,536936960,536936964],pc2bytes1=[0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697],pc2bytes2=[0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272],pc2bytes3=[0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952,139264,2236416,134356992,136454144],pc2bytes4=[0,262144,16,262160,0,262144,16,262160,4096,266240,4112,266256,4096,266240,4112,266256],pc2bytes5=[0,1024,32,1056,0,1024,32,1056,33554432,33555456,33554464,33555488,33554432,33555456,33554464,33555488],pc2bytes6=[0,268435456,524288,268959744,2,268435458,524290,268959746,0,268435456,524288,268959744,2,268435458,524290,268959746],pc2bytes7=[0,65536,2048,67584,536870912,536936448,536872960,536938496,131072,196608,133120,198656,537001984,537067520,537004032,537069568],pc2bytes8=[0,262144,0,262144,2,262146,2,262146,33554432,33816576,33554432,33816576,33554434,33816578,33554434,33816578],pc2bytes9=[0,268435456,8,268435464,0,268435456,8,268435464,1024,268436480,1032,268436488,1024,268436480,1032,268436488],pc2bytes10=[0,32,0,32,1048576,1048608,1048576,1048608,8192,8224,8192,8224,1056768,1056800,1056768,1056800],pc2bytes11=[0,16777216,512,16777728,2097152,18874368,2097664,18874880,67108864,83886080,67109376,83886592,69206016,85983232,69206528,85983744],pc2bytes12=[0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128],pc2bytes13=[0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261];for(var r,e,n,s=t.length>8?3:1,o=Array(32*s),a=[0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0],h=0,c=0,u=0;s>u;u++)for(left=t.charCodeAt(h++)<<24|t.charCodeAt(h++)<<16|t.charCodeAt(h++)<<8|t.charCodeAt(h++),right=t.charCodeAt(h++)<<24|t.charCodeAt(h++)<<16|t.charCodeAt(h++)<<8|t.charCodeAt(h++),n=252645135&(left>>>4^right),right^=n,left^=n<<4,n=65535&(right>>>-16^left),left^=n,right^=n<<-16,n=858993459&(left>>>2^right),right^=n,left^=n<<2,n=65535&(right>>>-16^left),left^=n,right^=n<<-16,n=1431655765&(left>>>1^right),right^=n,left^=n<<1,n=16711935&(right>>>8^left),left^=n,right^=n<<8,n=1431655765&(left>>>1^right),right^=n,left^=n<<1,n=left<<8|240&right>>>20,left=right<<24|16711680&right<<8|65280&right>>>8|240&right>>>24,right=n,i=0;a.length>i;i++)a[i]?(left=left<<2|left>>>26,right=right<<2|right>>>26):(left=left<<1|left>>>27,right=right<<1|right>>>27),left&=-15,right&=-15,r=pc2bytes0[left>>>28]|pc2bytes1[15&left>>>24]|pc2bytes2[15&left>>>20]|pc2bytes3[15&left>>>16]|pc2bytes4[15&left>>>12]|pc2bytes5[15&left>>>8]|pc2bytes6[15&left>>>4],e=pc2bytes7[right>>>28]|pc2bytes8[15&right>>>24]|pc2bytes9[15&right>>>20]|pc2bytes10[15&right>>>16]|pc2bytes11[15&right>>>12]|pc2bytes12[15&right>>>8]|pc2bytes13[15&right>>>4],n=65535&(e>>>16^r),o[c++]=r^n,o[c++]=e^n<<16;return o}function s(t,r){var e=8-t.length%8;return 2==r&&8>e?t+=" ".substr(0,e):1==r?t+=String.fromCharCode(e,e,e,e,e,e,e,e).substr(0,e):!r&&8>e&&(t+="\0\0\0\0\0\0\0\0".substr(0,e)),t}function o(t,r){if(2==r)t=t.replace(/ *$/g,"");else if(1==r){var e=t.charCodeAt(t.length-1);t=t.substr(0,t.length-e)}else r||(t=t.replace(/\0*$/g,""));return t}function a(t){this.key=[];for(var r=0;3>r;r++)this.key.push(t.substr(8*r,8));this.encrypt=function(t){return c.str2bin(e(n(this.key[2]),e(n(this.key[1]),e(n(this.key[0]),c.bin2str(t),!0,0,null,null),!1,0,null,null),!0,0,null,null))}}function h(t){this.key=t,this.encrypt=function(t,r){var i=n(this.key);return c.str2bin(e(i,c.bin2str(t),!0,0,null,r))},this.decrypt=function(t,r){var i=n(this.key);return c.str2bin(e(i,c.bin2str(t),!1,0,null,r))}}var c=t("../../util");a.keySize=a.prototype.keySize=24,a.blockSize=a.prototype.blockSize=8,r.exports={des:a,originalDes:h}},{"../../util":55}],8:[function(t,r){var e=t("./des.js");r.exports={des:e.des,originalDes:e.originalDes,cast5:t("./cast5.js"),twofish:t("./twofish.js"),blowfish:t("./blowfish.js")};var i=t("./aes.js");for(var n in i)r.exports["aes"+n]=i[n]},{"./aes.js":4,"./blowfish.js":5,"./cast5.js":6,"./des.js":7,"./twofish.js":9}],9:[function(t,r){function e(t,r){return(t<>>32-r)&h}function i(t,r){return t[r]|t[r+1]<<8|t[r+2]<<16|t[r+3]<<24}function n(t,r,e){t.splice(r,4,255&e,255&e>>>8,255&e>>>16,255&e>>>24)}function s(t,r){return 255&t>>>8*r}function o(){function t(t){function r(t){return t^t>>2^[0,90,180,238][3&t]}function n(t){return t^t>>1^t>>2^[0,238,180,90][3&t]}function o(t,r){var e,i,n;for(e=0;8>e;e++)i=r>>>24,r=r<<8&h|t>>>24,t=t<<8&h,n=i<<1,128&i&&(n^=333),r^=i^n<<16,n^=i>>>1,1&i&&(n^=166),r^=n<<24|n<<8;return r}function a(t,r){var e,i,n,s;return e=r>>4,i=15&r,n=j[t][e^i],s=T[t][I[i]^B[e]],E[t][I[s]^B[n]]<<4|O[t][n^s]}function c(t,r){var e=s(t,0),i=s(t,1),n=s(t,2),o=s(t,3);switch(m){case 4:e=x[1][e]^s(r[3],0),i=x[0][i]^s(r[3],1),n=x[0][n]^s(r[3],2),o=x[1][o]^s(r[3],3);case 3:e=x[1][e]^s(r[2],0),i=x[1][i]^s(r[2],1),n=x[0][n]^s(r[2],2),o=x[0][o]^s(r[2],3);case 2:e=x[0][x[0][e]^s(r[1],0)]^s(r[0],0),i=x[0][x[1][i]^s(r[1],1)]^s(r[0],1),n=x[1][x[0][n]^s(r[1],2)]^s(r[0],2),o=x[1][x[1][o]^s(r[1],3)]^s(r[0],3)}return P[0][e]^P[1][i]^P[2][n]^P[3][o]}d=t;var u,p,l,f,g,m,y,w,k,C=[],A=[],_=[],S=[],j=[[8,1,7,13,6,15,3,2,0,11,5,9,14,12,10,4],[2,8,11,13,15,7,6,14,3,1,9,4,0,10,12,5]],T=[[14,12,11,8,1,2,3,5,15,4,10,6,7,0,9,13],[1,14,2,11,4,12,3,7,6,13,10,5,15,9,0,8]],O=[[11,10,5,14,6,13,9,0,12,8,15,3,2,4,7,1],[4,12,7,5,1,6,9,10,0,14,13,8,2,11,3,15]],E=[[13,7,15,4,1,2,6,14,9,11,3,0,8,5,12,10],[11,9,5,1,12,3,13,14,6,4,7,15,2,0,8,10]],I=[0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15],B=[0,9,2,11,4,13,6,15,8,1,10,3,12,5,14,7],x=[[],[]],P=[[],[],[],[]];for(d=d.slice(0,32),u=d.length;16!=u&&24!=u&&32!=u;)d[u++]=0;for(u=0;d.length>u;u+=4)_[u>>2]=i(d,u);for(u=0;256>u;u++)x[0][u]=a(0,u),x[1][u]=a(1,u);for(u=0;256>u;u++)y=x[1][u],w=r(y),k=n(y),P[0][u]=y+(w<<8)+(k<<16)+(k<<24),P[2][u]=w+(k<<8)+(y<<16)+(k<<24),y=x[0][u],w=r(y),k=n(y),P[1][u]=k+(k<<8)+(w<<16)+(y<<24),P[3][u]=w+(y<<8)+(k<<16)+(w<<24);for(m=_.length/2,u=0;m>u;u++)p=_[u+u],C[u]=p,l=_[u+u+1],A[u]=l,S[m-u-1]=o(p,l);for(u=0;40>u;u+=2)p=16843009*u,l=p+16843009,p=c(p,C),l=e(c(l,A),8),b[u]=p+l&h,b[u+1]=e(p+2*l,9);for(u=0;256>u;u++)switch(p=l=f=g=u,m){case 4:p=x[1][p]^s(S[3],0),l=x[0][l]^s(S[3],1),f=x[0][f]^s(S[3],2),g=x[1][g]^s(S[3],3);case 3:p=x[1][p]^s(S[2],0),l=x[1][l]^s(S[2],1),f=x[0][f]^s(S[2],2),g=x[0][g]^s(S[2],3);case 2:v[0][u]=P[0][x[0][x[0][p]^s(S[1],0)]^s(S[0],0)],v[1][u]=P[1][x[0][x[1][l]^s(S[1],1)]^s(S[0],1)],v[2][u]=P[2][x[1][x[0][f]^s(S[1],2)]^s(S[0],2)],v[3][u]=P[3][x[1][x[1][g]^s(S[1],3)]^s(S[0],3)]}}function r(t){return v[0][s(t,0)]^v[1][s(t,1)]^v[2][s(t,2)]^v[3][s(t,3)]}function o(t){return v[0][s(t,3)]^v[1][s(t,0)]^v[2][s(t,1)]^v[3][s(t,2)]}function a(t,i){var n=r(i[0]),s=o(i[1]);i[2]=e(i[2]^n+s+b[4*t+8]&h,31),i[3]=e(i[3],1)^n+2*s+b[4*t+9]&h,n=r(i[2]),s=o(i[3]),i[0]=e(i[0]^n+s+b[4*t+10]&h,31),i[1]=e(i[1],1)^n+2*s+b[4*t+11]&h}function c(t,i){var n=r(i[0]),s=o(i[1]);i[2]=e(i[2],1)^n+s+b[4*t+10]&h,i[3]=e(i[3]^n+2*s+b[4*t+11]&h,31),n=r(i[2]),s=o(i[3]),i[0]=e(i[0],1)^n+s+b[4*t+8]&h,i[1]=e(i[1]^n+2*s+b[4*t+9]&h,31)}function u(){b=[],v=[[],[],[],[]]}function p(t,r){g=t,m=r;for(var e=[i(g,m)^b[0],i(g,m+4)^b[1],i(g,m+8)^b[2],i(g,m+12)^b[3]],s=0;8>s;s++)a(s,e);return n(g,m,e[2]^b[4]),n(g,m+4,e[3]^b[5]),n(g,m+8,e[0]^b[6]),n(g,m+12,e[1]^b[7]),m+=16,g}function l(t,r){g=t,m=r;for(var e=[i(g,m)^b[4],i(g,m+4)^b[5],i(g,m+8)^b[6],i(g,m+12)^b[7]],s=7;s>=0;s--)c(s,e);n(g,m,e[2]^b[0]),n(g,m+4,e[3]^b[1]),n(g,m+8,e[0]^b[2]),n(g,m+12,e[1]^b[3]),m+=16}function f(){return g}var d=null,g=null,m=-1,y=null;y="twofish";var b=[],v=[[],[],[],[]];return{name:"twofish",blocksize:16,open:t,close:u,encrypt:p,decrypt:l,finalize:f}}function a(t){this.tf=o(),this.tf.open(c.str2bin(t),0),this.encrypt=function(t){return this.tf.encrypt([].concat(t),0)}}var h=4294967295,c=t("../../util");r.exports=a,r.exports.keySize=a.prototype.keySize=32,r.exports.blockSize=a.prototype.blockSize=16},{"../../util":55}],10:[function(t,r){var e=t("./random.js"),i=t("./cipher"),n=t("./public_key"),s=t("../type/mpi.js");r.exports={publicKeyEncrypt:function(t,r,e){var i=function(){switch(t){case"rsa_encrypt":case"rsa_encrypt_sign":var i=new n.rsa,s=r[0].toBigInteger(),o=r[1].toBigInteger(),a=e.toBigInteger();return[i.encrypt(a,o,s)];case"elgamal":var h=new n.elgamal,c=r[0].toBigInteger(),u=r[1].toBigInteger(),p=r[2].toBigInteger(),a=e.toBigInteger();return h.encrypt(a,u,c,p);default:return[]}}();return i.map(function(t){var r=new s;return r.fromBigInteger(t),r})},publicKeyDecrypt:function(t,r,e){var i=function(){switch(t){case"rsa_encrypt_sign":case"rsa_encrypt":var i=new n.rsa,s=r[2].toBigInteger(),o=r[3].toBigInteger(),a=r[4].toBigInteger(),h=r[5].toBigInteger(),c=e[0].toBigInteger();return i.decrypt(c,s,o,a,h);case"elgamal":var u=new n.elgamal,p=r[3].toBigInteger(),l=e[0].toBigInteger(),f=e[1].toBigInteger(),o=r[0].toBigInteger();return u.decrypt(l,f,o,p);default:return null}}(),o=new s;return o.fromBigInteger(i),o},getPrivateMpiCount:function(t){switch(t){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":return 4;case"elgamal":return 1;case"dsa":return 1;default:throw Error("Unknown algorithm")}},getPublicMpiCount:function(t){switch(t){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":return 2;case"elgamal":return 3;case"dsa":return 4;default:throw Error("Unknown algorithm.")}},getPrefixRandom:function(t){return e.getRandomBytes(i[t].blockSize)},generateSessionKey:function(t){return e.getRandomBytes(i[t].keySize)}}},{"../type/mpi.js":53,"./cipher":8,"./public_key":19,"./random.js":22}],11:[function(t,r){var e=t("./sha.js");r.exports={md5:t("./md5.js"),sha1:e.sha1,sha256:e.sha256,sha224:e.sha224,sha384:e.sha384,sha512:e.sha512,ripemd:t("./ripe-md.js"),digest:function(t,r){switch(t){case 1:return this.md5(r);case 2:return this.sha1(r);case 3:return this.ripemd(r);case 8:return this.sha256(r);case 9:return this.sha384(r);case 10:return this.sha512(r);case 11:return this.sha224(r);default:throw Error("Invalid hash function.")}},getHashByteLength:function(t){switch(t){case 1:return 16;case 2:case 3:return 20;case 8:return 32;case 9:return 48;case 10:return 64;case 11:return 28;default:throw Error("Invalid hash algorithm.")}}}},{"./md5.js":12,"./ripe-md.js":13,"./sha.js":14}],12:[function(t,r){function e(t){var r=f(t),e=g.hex2bin(r);return e}function i(t,r){var e=t[0],i=t[1],n=t[2],c=t[3];e=s(e,i,n,c,r[0],7,-680876936),c=s(c,e,i,n,r[1],12,-389564586),n=s(n,c,e,i,r[2],17,606105819),i=s(i,n,c,e,r[3],22,-1044525330),e=s(e,i,n,c,r[4],7,-176418897),c=s(c,e,i,n,r[5],12,1200080426),n=s(n,c,e,i,r[6],17,-1473231341),i=s(i,n,c,e,r[7],22,-45705983),e=s(e,i,n,c,r[8],7,1770035416),c=s(c,e,i,n,r[9],12,-1958414417),n=s(n,c,e,i,r[10],17,-42063),i=s(i,n,c,e,r[11],22,-1990404162),e=s(e,i,n,c,r[12],7,1804603682),c=s(c,e,i,n,r[13],12,-40341101),n=s(n,c,e,i,r[14],17,-1502002290),i=s(i,n,c,e,r[15],22,1236535329),e=o(e,i,n,c,r[1],5,-165796510),c=o(c,e,i,n,r[6],9,-1069501632),n=o(n,c,e,i,r[11],14,643717713),i=o(i,n,c,e,r[0],20,-373897302),e=o(e,i,n,c,r[5],5,-701558691),c=o(c,e,i,n,r[10],9,38016083),n=o(n,c,e,i,r[15],14,-660478335),i=o(i,n,c,e,r[4],20,-405537848),e=o(e,i,n,c,r[9],5,568446438),c=o(c,e,i,n,r[14],9,-1019803690),n=o(n,c,e,i,r[3],14,-187363961),i=o(i,n,c,e,r[8],20,1163531501),e=o(e,i,n,c,r[13],5,-1444681467),c=o(c,e,i,n,r[2],9,-51403784),n=o(n,c,e,i,r[7],14,1735328473),i=o(i,n,c,e,r[12],20,-1926607734),e=a(e,i,n,c,r[5],4,-378558),c=a(c,e,i,n,r[8],11,-2022574463),n=a(n,c,e,i,r[11],16,1839030562),i=a(i,n,c,e,r[14],23,-35309556),e=a(e,i,n,c,r[1],4,-1530992060),c=a(c,e,i,n,r[4],11,1272893353),n=a(n,c,e,i,r[7],16,-155497632),i=a(i,n,c,e,r[10],23,-1094730640),e=a(e,i,n,c,r[13],4,681279174),c=a(c,e,i,n,r[0],11,-358537222),n=a(n,c,e,i,r[3],16,-722521979),i=a(i,n,c,e,r[6],23,76029189),e=a(e,i,n,c,r[9],4,-640364487),c=a(c,e,i,n,r[12],11,-421815835),n=a(n,c,e,i,r[15],16,530742520),i=a(i,n,c,e,r[2],23,-995338651),e=h(e,i,n,c,r[0],6,-198630844),c=h(c,e,i,n,r[7],10,1126891415),n=h(n,c,e,i,r[14],15,-1416354905),i=h(i,n,c,e,r[5],21,-57434055),e=h(e,i,n,c,r[12],6,1700485571),c=h(c,e,i,n,r[3],10,-1894986606),n=h(n,c,e,i,r[10],15,-1051523),i=h(i,n,c,e,r[1],21,-2054922799),e=h(e,i,n,c,r[8],6,1873313359),c=h(c,e,i,n,r[15],10,-30611744),n=h(n,c,e,i,r[6],15,-1560198380),i=h(i,n,c,e,r[13],21,1309151649),e=h(e,i,n,c,r[4],6,-145523070),c=h(c,e,i,n,r[11],10,-1120210379),n=h(n,c,e,i,r[2],15,718787259),i=h(i,n,c,e,r[9],21,-343485551),t[0]=d(e,t[0]),t[1]=d(i,t[1]),t[2]=d(n,t[2]),t[3]=d(c,t[3])}function n(t,r,e,i,n,s){return r=d(d(r,t),d(i,s)),d(r<>>32-n,e)}function s(t,r,e,i,s,o,a){return n(r&e|~r&i,t,r,s,o,a)}function o(t,r,e,i,s,o,a){return n(r&i|e&~i,t,r,s,o,a)}function a(t,r,e,i,s,o,a){return n(r^e^i,t,r,s,o,a)}function h(t,r,e,i,s,o,a){return n(e^(r|~i),t,r,s,o,a)}function c(t){txt="";var r,e=t.length,n=[1732584193,-271733879,-1732584194,271733878];for(r=64;t.length>=r;r+=64)i(n,u(t.substring(r-64,r)));t=t.substring(r-64);var s=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(r=0;t.length>r;r++)s[r>>2]|=t.charCodeAt(r)<<(r%4<<3);if(s[r>>2]|=128<<(r%4<<3),r>55)for(i(n,s),r=0;16>r;r++)s[r]=0;return s[14]=8*e,i(n,s),n}function u(t){var r,e=[];for(r=0;64>r;r+=4)e[r>>2]=t.charCodeAt(r)+(t.charCodeAt(r+1)<<8)+(t.charCodeAt(r+2)<<16)+(t.charCodeAt(r+3)<<24);return e}function p(t){for(var r="",e=0;4>e;e++)r+=m[15&t>>8*e+4]+m[15&t>>8*e];return r}function l(t){for(var r=0;t.length>r;r++)t[r]=p(t[r]);return t.join("")}function f(t){return l(c(t))}function d(t,r){return 4294967295&t+r}function d(t,r){var e=(65535&t)+(65535&r),i=(t>>16)+(r>>16)+(e>>16);return i<<16|65535&e}var g=t("../../util/util.js"),m="0123456789abcdef".split("");"5d41402abc4b2a76b9719d911017c592"!=f("hello"),r.exports=e},{"../../util/util.js":55}],13:[function(t,r){function e(t,r){return new Number(t<>>32-r)}function i(t,r,e){return new Number(t^r^e)}function n(t,r,e){return new Number(t&r|~t&e)}function s(t,r,e){return new Number((t|~r)^e)}function o(t,r,e){return new Number(t&e|r&~e)}function a(t,r,e){return new Number(t^(r|~e))}function h(t,r,h,c,u,p,l,f){switch(f){case 0:t+=i(r,h,c)+p+0;break;case 1:t+=n(r,h,c)+p+1518500249;break;case 2:t+=s(r,h,c)+p+1859775393;break;case 3:t+=o(r,h,c)+p+2400959708;break;case 4:t+=a(r,h,c)+p+2840853838;break;case 5:t+=a(r,h,c)+p+1352829926;break;case 6:t+=o(r,h,c)+p+1548603684;break;case 7:t+=s(r,h,c)+p+1836072691;break;case 8:t+=n(r,h,c)+p+2053994217;break;case 9:t+=i(r,h,c)+p+0;break;default:document.write("Bogus round number")}t=e(t,l)+u,h=e(h,10),t&=4294967295,r&=4294967295,h&=4294967295,c&=4294967295,u&=4294967295;var d=[];return d[0]=t,d[1]=r,d[2]=h,d[3]=c,d[4]=u,d[5]=p,d[6]=l,d}function c(t){t[0]=1732584193,t[1]=4023233417,t[2]=2562383102,t[3]=271733878,t[4]=3285377520}function u(t,r){blockA=[],blockB=[];for(var e,i=0;5>i;i++)blockA[i]=new Number(t[i]),blockB[i]=new Number(t[i]);for(var n=0,s=0;5>s;s++)for(var i=0;16>i;i++)e=h(blockA[(n+0)%5],blockA[(n+1)%5],blockA[(n+2)%5],blockA[(n+3)%5],blockA[(n+4)%5],r[b[s][i]],y[s][i],s),blockA[(n+0)%5]=e[0],blockA[(n+1)%5]=e[1],blockA[(n+2)%5]=e[2],blockA[(n+3)%5]=e[3],blockA[(n+4)%5]=e[4],n+=4;n=0;for(var s=5;10>s;s++)for(var i=0;16>i;i++)e=h(blockB[(n+0)%5],blockB[(n+1)%5],blockB[(n+2)%5],blockB[(n+3)%5],blockB[(n+4)%5],r[b[s][i]],y[s][i],s),blockB[(n+0)%5]=e[0],blockB[(n+1)%5]=e[1],blockB[(n+2)%5]=e[2],blockB[(n+3)%5]=e[3],blockB[(n+4)%5]=e[4],n+=4;blockB[3]+=blockA[2]+t[1],t[1]=t[2]+blockA[3]+blockB[4],t[2]=t[3]+blockA[4]+blockB[0],t[3]=t[4]+blockA[0]+blockB[1],t[4]=t[0]+blockA[1]+blockB[2],t[0]=blockB[3]}function p(t){for(var r=0;16>r;r++)t[r]=0}function l(t,r,e,i){var n=Array(16);p(n);for(var s=0,o=0;(63&e)>o;o++)n[o>>>2]^=(255&r.charCodeAt(s++))<<8*(3&o);if(n[15&e>>>2]^=1<<8*(3&e)+7,(63&e)>55){u(t,n);var n=Array(16);p(n)}n[14]=e<<3,n[15]=e>>>29|i<<3,u(t,n)}function f(t){var r=(255&t.charCodeAt(3))<<24;return r|=(255&t.charCodeAt(2))<<16,r|=(255&t.charCodeAt(1))<<8,r|=255&t.charCodeAt(0)}function d(t){var r,e,i=Array(m/32),n=Array(m/8);c(i),r=t.length;var s=Array(16);p(s);for(var o=0,e=r;e>63;e-=64){for(var a=0;16>a;a++)s[a]=f(t.substr(o,4)),o+=4;u(i,s)}l(i,t.substr(o),r,0);for(var a=0;m/8>a;a+=4)n[a]=255&i[a>>>2],n[a+1]=255&i[a>>>2]>>>8,n[a+2]=255&i[a>>>2]>>>16,n[a+3]=255&i[a>>>2]>>>24;return n}function g(t){for(var r=d(t),e="",i=0;m/8>i;i++)e+=String.fromCharCode(r[i]);return e}var m=160,y=[[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],[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]],b=[[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],[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]];r.exports=g},{}],14:[function(t,r){var e=function(){var t=8,r="",e=0,i=function(t,r){this.highOrder=t,this.lowOrder=r},n=function(r){var e,i=[],n=(1<e;e+=t)i[e>>5]|=(r.charCodeAt(e/t)&n)<<32-t-e%32;return i},s=function(t){var r,e,i=[],n=t.length;for(r=0;n>r;r+=2){if(e=parseInt(t.substr(r,2),16),isNaN(e))return"INVALID HEX STRING";i[r>>3]|=e<<24-4*(r%8)}return i},o=function(t){var r,i,n=e?"0123456789ABCDEF":"0123456789abcdef",s="",o=4*t.length;for(r=0;o>r;r+=1)i=t[r>>2]>>8*(3-r%4),s+=n.charAt(15&i>>4)+n.charAt(15&i);return s},a=function(t){var e,i,n,s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",o="",a=4*t.length;for(e=0;a>e;e+=3)for(n=(255&t[e>>2]>>8*(3-e%4))<<16|(255&t[e+1>>2]>>8*(3-(e+1)%4))<<8|255&t[e+2>>2]>>8*(3-(e+2)%4),i=0;4>i;i+=1)o+=32*t.length>=8*e+6*i?s.charAt(63&n>>6*(3-i)):r;return o},h=function(t){for(var r="",e=255,i=0;32*t.length>i;i+=8)r+=String.fromCharCode(t[i>>5]>>>24-i%32&e);return r},c=function(t,r){return t<>>32-r},u=function(t,r){return t>>>r|t<<32-r},p=function(t,r){return 32>=r?new i(t.highOrder>>>r|t.lowOrder<<32-r,t.lowOrder>>>r|t.highOrder<<32-r):new i(t.lowOrder>>>r|t.highOrder<<32-r,t.highOrder>>>r|t.lowOrder<<32-r)},l=function(t,r){return t>>>r},f=function(t,r){return 32>=r?new i(t.highOrder>>>r,t.lowOrder>>>r|t.highOrder<<32-r):new i(0,t.highOrder<<32-r)},d=function(t,r,e){return t^r^e},g=function(t,r,e){return t&r^~t&e},m=function(t,r,e){return new i(t.highOrder&r.highOrder^~t.highOrder&e.highOrder,t.lowOrder&r.lowOrder^~t.lowOrder&e.lowOrder)},y=function(t,r,e){return t&r^t&e^r&e},b=function(t,r,e){return new i(t.highOrder&r.highOrder^t.highOrder&e.highOrder^r.highOrder&e.highOrder,t.lowOrder&r.lowOrder^t.lowOrder&e.lowOrder^r.lowOrder&e.lowOrder)},v=function(t){return u(t,2)^u(t,13)^u(t,22)},w=function(t){var r=p(t,28),e=p(t,34),n=p(t,39);return new i(r.highOrder^e.highOrder^n.highOrder,r.lowOrder^e.lowOrder^n.lowOrder)},k=function(t){return u(t,6)^u(t,11)^u(t,25)},C=function(t){var r=p(t,14),e=p(t,18),n=p(t,41);return new i(r.highOrder^e.highOrder^n.highOrder,r.lowOrder^e.lowOrder^n.lowOrder)},A=function(t){return u(t,7)^u(t,18)^l(t,3)},_=function(t){var r=p(t,1),e=p(t,8),n=f(t,7);return new i(r.highOrder^e.highOrder^n.highOrder,r.lowOrder^e.lowOrder^n.lowOrder)},S=function(t){return u(t,17)^u(t,19)^l(t,10)},j=function(t){var r=p(t,19),e=p(t,61),n=f(t,6);return new i(r.highOrder^e.highOrder^n.highOrder,r.lowOrder^e.lowOrder^n.lowOrder)},T=function(t,r){var e=(65535&t)+(65535&r),i=(t>>>16)+(r>>>16)+(e>>>16);return(65535&i)<<16|65535&e},O=function(t,r,e,i){var n=(65535&t)+(65535&r)+(65535&e)+(65535&i),s=(t>>>16)+(r>>>16)+(e>>>16)+(i>>>16)+(n>>>16);return(65535&s)<<16|65535&n},E=function(t,r,e,i,n){var s=(65535&t)+(65535&r)+(65535&e)+(65535&i)+(65535&n),o=(t>>>16)+(r>>>16)+(e>>>16)+(i>>>16)+(n>>>16)+(s>>>16);return(65535&o)<<16|65535&s},I=function(t,r){var e,n,s,o;return e=(65535&t.lowOrder)+(65535&r.lowOrder),n=(t.lowOrder>>>16)+(r.lowOrder>>>16)+(e>>>16),s=(65535&n)<<16|65535&e,e=(65535&t.highOrder)+(65535&r.highOrder)+(n>>>16),n=(t.highOrder>>>16)+(r.highOrder>>>16)+(e>>>16),o=(65535&n)<<16|65535&e,new i(o,s)},B=function(t,r,e,n){var s,o,a,h;return s=(65535&t.lowOrder)+(65535&r.lowOrder)+(65535&e.lowOrder)+(65535&n.lowOrder),o=(t.lowOrder>>>16)+(r.lowOrder>>>16)+(e.lowOrder>>>16)+(n.lowOrder>>>16)+(s>>>16),a=(65535&o)<<16|65535&s,s=(65535&t.highOrder)+(65535&r.highOrder)+(65535&e.highOrder)+(65535&n.highOrder)+(o>>>16),o=(t.highOrder>>>16)+(r.highOrder>>>16)+(e.highOrder>>>16)+(n.highOrder>>>16)+(s>>>16),h=(65535&o)<<16|65535&s,new i(h,a)},x=function(t,r,e,n,s){var o,a,h,c;return o=(65535&t.lowOrder)+(65535&r.lowOrder)+(65535&e.lowOrder)+(65535&n.lowOrder)+(65535&s.lowOrder),a=(t.lowOrder>>>16)+(r.lowOrder>>>16)+(e.lowOrder>>>16)+(n.lowOrder>>>16)+(s.lowOrder>>>16)+(o>>>16),h=(65535&a)<<16|65535&o,o=(65535&t.highOrder)+(65535&r.highOrder)+(65535&e.highOrder)+(65535&n.highOrder)+(65535&s.highOrder)+(a>>>16),a=(t.highOrder>>>16)+(r.highOrder>>>16)+(e.highOrder>>>16)+(n.highOrder>>>16)+(s.highOrder>>>16)+(o>>>16),c=(65535&a)<<16|65535&o,new i(c,h)},P=function(t,r){var e,i,n,s,o,a,h,u,p,l=[],f=g,m=d,b=y,v=c,w=T,k=E,C=[1732584193,4023233417,2562383102,271733878,3285377520],A=[1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782];for(t[r>>5]|=128<<24-r%32,t[(r+65>>9<<4)+15]=r,p=t.length,h=0;p>h;h+=16){for(e=C[0],i=C[1],n=C[2],s=C[3],o=C[4],u=0;80>u;u+=1)l[u]=16>u?t[u+h]:v(l[u-3]^l[u-8]^l[u-14]^l[u-16],1),a=20>u?k(v(e,5),f(i,n,s),o,A[u],l[u]):40>u?k(v(e,5),m(i,n,s),o,A[u],l[u]):60>u?k(v(e,5),b(i,n,s),o,A[u],l[u]):k(v(e,5),m(i,n,s),o,A[u],l[u]),o=s,s=n,n=v(i,30),i=e,e=a;C[0]=w(e,C[0]),C[1]=w(i,C[1]),C[2]=w(n,C[2]),C[3]=w(s,C[3]),C[4]=w(o,C[4])}return C},N=function(t,r,e){var n,s,o,a,h,c,u,p,l,f,d,P,N,D,K,M,R,G,H,L,z,U,q,F,V,Z,X,J,Y,W=[];for("SHA-224"===e||"SHA-256"===e?(P=64,N=(r+65>>9<<4)+15,M=16,R=1,X=Number,G=T,H=O,L=E,z=A,U=S,q=v,F=k,Z=y,V=g,J=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],d="SHA-224"===e?[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428]:[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]):("SHA-384"===e||"SHA-512"===e)&&(P=80,N=(r+128>>10<<5)+31,M=32,R=2,X=i,G=I,H=B,L=x,z=_,U=j,q=w,F=C,Z=b,V=m,J=[new X(1116352408,3609767458),new X(1899447441,602891725),new X(3049323471,3964484399),new X(3921009573,2173295548),new X(961987163,4081628472),new X(1508970993,3053834265),new X(2453635748,2937671579),new X(2870763221,3664609560),new X(3624381080,2734883394),new X(310598401,1164996542),new X(607225278,1323610764),new X(1426881987,3590304994),new X(1925078388,4068182383),new X(2162078206,991336113),new X(2614888103,633803317),new X(3248222580,3479774868),new X(3835390401,2666613458),new X(4022224774,944711139),new X(264347078,2341262773),new X(604807628,2007800933),new X(770255983,1495990901),new X(1249150122,1856431235),new X(1555081692,3175218132),new X(1996064986,2198950837),new X(2554220882,3999719339),new X(2821834349,766784016),new X(2952996808,2566594879),new X(3210313671,3203337956),new X(3336571891,1034457026),new X(3584528711,2466948901),new X(113926993,3758326383),new X(338241895,168717936),new X(666307205,1188179964),new X(773529912,1546045734),new X(1294757372,1522805485),new X(1396182291,2643833823),new X(1695183700,2343527390),new X(1986661051,1014477480),new X(2177026350,1206759142),new X(2456956037,344077627),new X(2730485921,1290863460),new X(2820302411,3158454273),new X(3259730800,3505952657),new X(3345764771,106217008),new X(3516065817,3606008344),new X(3600352804,1432725776),new X(4094571909,1467031594),new X(275423344,851169720),new X(430227734,3100823752),new X(506948616,1363258195),new X(659060556,3750685593),new X(883997877,3785050280),new X(958139571,3318307427),new X(1322822218,3812723403),new X(1537002063,2003034995),new X(1747873779,3602036899),new X(1955562222,1575990012),new X(2024104815,1125592928),new X(2227730452,2716904306),new X(2361852424,442776044),new X(2428436474,593698344),new X(2756734187,3733110249),new X(3204031479,2999351573),new X(3329325298,3815920427),new X(3391569614,3928383900),new X(3515267271,566280711),new X(3940187606,3454069534),new X(4118630271,4000239992),new X(116418474,1914138554),new X(174292421,2731055270),new X(289380356,3203993006),new X(460393269,320620315),new X(685471733,587496836),new X(852142971,1086792851),new X(1017036298,365543100),new X(1126000580,2618297676),new X(1288033470,3409855158),new X(1501505948,4234509866),new X(1607167915,987167468),new X(1816402316,1246189591)],d="SHA-384"===e?[new X(3418070365,3238371032),new X(1654270250,914150663),new X(2438529370,812702999),new X(355462360,4144912697),new X(1731405415,4290775857),new X(41048885895,1750603025),new X(3675008525,1694076839),new X(1203062813,3204075428)]:[new X(1779033703,4089235720),new X(3144134277,2227873595),new X(1013904242,4271175723),new X(2773480762,1595750129),new X(1359893119,2917565137),new X(2600822924,725511199),new X(528734635,4215389547),new X(1541459225,327033209)]),t[r>>5]|=128<<24-r%32,t[N]=r,Y=t.length,D=0;Y>D;D+=M){for(n=d[0],s=d[1],o=d[2],a=d[3],h=d[4],c=d[5],u=d[6],p=d[7],K=0;P>K;K+=1)W[K]=16>K?new X(t[K*R+D],t[K*R+D+1]):H(U(W[K-2]),W[K-7],z(W[K-15]),W[K-16]),l=L(p,F(h),V(h,c,u),J[K],W[K]),f=G(q(n),Z(n,s,o)),p=u,u=c,c=h,h=G(a,l),a=o,o=s,s=n,n=G(l,f);d[0]=G(n,d[0]),d[1]=G(s,d[1]),d[2]=G(o,d[2]),d[3]=G(a,d[3]),d[4]=G(h,d[4]),d[5]=G(c,d[5]),d[6]=G(u,d[6]),d[7]=G(p,d[7])}switch(e){case"SHA-224":return[d[0],d[1],d[2],d[3],d[4],d[5],d[6]];case"SHA-256":return d;case"SHA-384":return[d[0].highOrder,d[0].lowOrder,d[1].highOrder,d[1].lowOrder,d[2].highOrder,d[2].lowOrder,d[3].highOrder,d[3].lowOrder,d[4].highOrder,d[4].lowOrder,d[5].highOrder,d[5].lowOrder];case"SHA-512":return[d[0].highOrder,d[0].lowOrder,d[1].highOrder,d[1].lowOrder,d[2].highOrder,d[2].lowOrder,d[3].highOrder,d[3].lowOrder,d[4].highOrder,d[4].lowOrder,d[5].highOrder,d[5].lowOrder,d[6].highOrder,d[6].lowOrder,d[7].highOrder,d[7].lowOrder];default:return[]}},D=function(r,e){if(this.sha1=null,this.sha224=null,this.sha256=null,this.sha384=null,this.sha512=null,this.strBinLen=null,this.strToHash=null,"HEX"===e){if(0!==r.length%2)return"TEXT MUST BE IN BYTE INCREMENTS";this.strBinLen=4*r.length,this.strToHash=s(r)}else{if("ASCII"!==e&&void 0!==e)return"UNKNOWN TEXT INPUT TYPE";this.strBinLen=r.length*t,this.strToHash=n(r)}};return D.prototype={getHash:function(t,r){var e=null,i=this.strToHash.slice();switch(r){case"HEX":e=o;break;case"B64":e=a;break;case"ASCII":e=h;break;default:return"FORMAT NOT RECOGNIZED"}switch(t){case"SHA-1":return null===this.sha1&&(this.sha1=P(i,this.strBinLen)),e(this.sha1);case"SHA-224":return null===this.sha224&&(this.sha224=N(i,this.strBinLen,t)),e(this.sha224);case"SHA-256":return null===this.sha256&&(this.sha256=N(i,this.strBinLen,t)),e(this.sha256);case"SHA-384":return null===this.sha384&&(this.sha384=N(i,this.strBinLen,t)),e(this.sha384);case"SHA-512":return null===this.sha512&&(this.sha512=N(i,this.strBinLen,t)),e(this.sha512);default:return"HASH NOT RECOGNIZED"}},getHMAC:function(r,e,i,c){var u,p,l,f,d,g,m,y,b,v=[],w=[];switch(c){case"HEX":u=o;break;case"B64":u=a;break;case"ASCII":u=h;break;default:return"FORMAT NOT RECOGNIZED"}switch(i){case"SHA-1":l=64,b=160;break;case"SHA-224":l=64,b=224;break;case"SHA-256":l=64,b=256;break;case"SHA-384":l=128,b=384;break;case"SHA-512":l=128,b=512;break;default:return"HASH NOT RECOGNIZED"}if("HEX"===e){if(0!==r.length%2)return"KEY MUST BE IN BYTE INCREMENTS";p=s(r),y=4*r.length}else{if("ASCII"!==e)return"UNKNOWN KEY INPUT TYPE";p=n(r),y=r.length*t}for(f=8*l,m=l/4-1,y/8>l?(p="SHA-1"===i?P(p,y):N(p,y,i),p[m]&=4294967040):l>y/8&&(p[m]&=4294967040),d=0;m>=d;d+=1)v[d]=909522486^p[d],w[d]=1549556828^p[d];return"SHA-1"===i?(g=P(v.concat(this.strToHash),f+this.strBinLen),g=P(w.concat(g),f+b)):(g=N(v.concat(this.strToHash),f+this.strBinLen,i),g=N(w.concat(g),f+b,i)),u(g)}},D}();r.exports={sha1:function(t){var r=new e(t,"ASCII");return r.getHash("SHA-1","ASCII")},sha224:function(t){var r=new e(t,"ASCII");return r.getHash("SHA-224","ASCII")},sha256:function(t){var r=new e(t,"ASCII");return r.getHash("SHA-256","ASCII")},sha384:function(t){var r=new e(t,"ASCII");return r.getHash("SHA-384","ASCII")},sha512:function(t){var r=new e(t,"ASCII");return r.getHash("SHA-512","ASCII")}}},{}],15:[function(t,r){r.exports={cipher:t("./cipher"),hash:t("./hash"),cfb:t("./cfb.js"),publicKey:t("./public_key"),signature:t("./signature.js"),random:t("./random.js"),pkcs1:t("./pkcs1.js")};var e=t("./crypto.js");for(var i in e)r.exports[i]=e[i]},{"./cfb.js":3,"./cipher":8,"./crypto.js":10,"./hash":11,"./pkcs1.js":16,"./public_key":19,"./random.js":22,"./signature.js":23}],16:[function(t,r){hash_headers=[],hash_headers[1]=[48,32,48,12,6,8,42,134,72,134,247,13,2,5,5,0,4,16],hash_headers[3]=[48,33,48,9,6,5,43,36,3,2,1,5,0,4,20],hash_headers[2]=[48,33,48,9,6,5,43,14,3,2,26,5,0,4,20],hash_headers[8]=[48,49,48,13,6,9,96,134,72,1,101,3,4,2,1,5,0,4,32],hash_headers[9]=[48,65,48,13,6,9,96,134,72,1,101,3,4,2,2,5,0,4,48],hash_headers[10]=[48,81,48,13,6,9,96,134,72,1,101,3,4,2,3,5,0,4,64],hash_headers[11]=[48,49,48,13,6,9,96,134,72,1,101,3,4,2,4,5,0,4,28]; -var e=(t("./crypto.js"),t("./random.js")),i=t("../util"),n=t("./public_key/jsbn.js"),s=t("./hash");r.exports={eme:{encode:function(t,r){if(t.length>r-11)return-1;var i="";i+=String.fromCharCode(0),i+=String.fromCharCode(2);for(var n=0;r-t.length-3>n;n++)i+=String.fromCharCode(e.getPseudoRandom(1,255));return i+=String.fromCharCode(0),i+=t},decode:function(t,r){if(r>t.length&&(t=String.fromCharCode(0)+t),12>t.length||0!=t.charCodeAt(0)||2!=t.charCodeAt(1))return-1;for(var e=2;0!=t.charCodeAt(e)&&t.length>e;)e++;return t.substring(e+1,t.length)}},emsa:{encode:function(t,r,e){var o="";o+=String.fromCharCode(0),o+=String.fromCharCode(1);for(var a=0;e-hash_headers[t].length-3-s.getHashByteLength(t)>a;a++)o+=String.fromCharCode(255);o+=String.fromCharCode(0);for(var a=0;hash_headers[t].length>a;a++)o+=String.fromCharCode(hash_headers[t][a]);return o+=s.digest(t,r),new n(i.hexstrdump(o),16)},decode:function(t,r){var e=0;if(0==r.charCodeAt(0))e++;else{if(1!=r.charCodeAt(0))return-1;e++}for(;255==r.charCodeAt(e);)e++;if(0!=r.charCodeAt(e++))return-1;var i=0;for(i=0;hash_headers[t].length>i&&r.length>i+e;i++)if(r.charCodeAt(i+e)!=hash_headers[t][i])return-1;return e+=i,r.substring(e).length11&&10!=r&&8>r?2:r;case 28:return r>11&&8>r?11:r;case 32:return r>10&&8>r?8:r;default:return o.print_debug("DSA select hash algorithm: returning null for an unknown length of q"),null}}function e(t,r,e,n,a,h,c,u){var p=o.getLeftNBits(s.digest(t,n),h.bitLength()),l=new i(o.hexstrdump(p),16);if(i.ZERO.compareTo(r)>0||r.compareTo(h)>0||i.ZERO.compareTo(e)>0||e.compareTo(h)>0)return o.print_error("invalid DSA Signature"),null;var f=e.modInverse(h),d=l.multiply(f).mod(h),g=r.multiply(f).mod(h);return c.modPow(d,a).multiply(u.modPow(g,a)).mod(a).mod(h)}this.select_hash_algorithm=r,this.sign=t,this.verify=e}var i=t("./jsbn.js"),n=t("../random.js"),s=t("../hash"),o=t("../../util");r.exports=e},{"../../util":55,"../hash":11,"../random.js":22,"./jsbn.js":20}],18:[function(t,r){function e(){function t(t,r,e,s){var o=i.ONE.add(i.ONE),a=e.subtract(o),h=n.getRandomBigIntegerInRange(o,a);h=h.mod(a).add(i.ONE);var c=[];return c[0]=r.modPow(h,e),c[1]=s.modPow(h,e).multiply(t).mod(e),c}function r(t,r,e,i){return s.print_debug("Elgamal Decrypt:\nc1:"+s.hexstrdump(t.toMPI())+"\n"+"c2:"+s.hexstrdump(r.toMPI())+"\n"+"p:"+s.hexstrdump(e.toMPI())+"\n"+"x:"+s.hexstrdump(i.toMPI())),t.modPow(i,e).modInverse(e).multiply(r).mod(e)}this.encrypt=t,this.decrypt=r}var i=t("./jsbn.js"),n=t("../random.js"),s=t("../../util");r.exports=e},{"../../util":55,"../random.js":22,"./jsbn.js":20}],19:[function(t,r){r.exports={rsa:t("./rsa.js"),elgamal:t("./elgamal.js"),dsa:t("./dsa.js")}},{"./dsa.js":17,"./elgamal.js":18,"./rsa.js":21}],20:[function(t,r){function e(t,r,e){null!=t&&("number"==typeof t?this.fromNumber(t,r,e):null==r&&"string"!=typeof t?this.fromString(t,256):this.fromString(t,r))}function i(){return new e(null)}function n(t,r,e,i,n,s){for(;--s>=0;){var o=r*this[t++]+e[i]+n;n=Math.floor(o/67108864),e[i++]=67108863&o}return n}function s(t){return ne.charAt(t)}function o(t,r){var e=se[t.charCodeAt(r)];return null==e?-1:e}function a(t){for(var r=this.t-1;r>=0;--r)t[r]=this[r];t.t=this.t,t.s=this.s}function h(t){this.t=1,this.s=0>t?-1:0,t>0?this[0]=t:-1>t?this[0]=t+DV:this.t=0}function c(t){var r=i();return r.fromInt(t),r}function u(t,r){var i;if(16==r)i=4;else if(8==r)i=3;else if(256==r)i=8;else if(2==r)i=1;else if(32==r)i=5;else{if(4!=r)return this.fromRadix(t,r),void 0;i=2}this.t=0,this.s=0;for(var n=t.length,s=!1,a=0;--n>=0;){var h=8==i?255&t[n]:o(t,n);0>h?"-"==t.charAt(n)&&(s=!0):(s=!1,0==a?this[this.t++]=h:a+i>this.DB?(this[this.t-1]|=(h&(1<>this.DB-a):this[this.t-1]|=h<=this.DB&&(a-=this.DB))}8==i&&0!=(128&t[0])&&(this.s=-1,a>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==t;)--this.t}function l(t){if(0>this.s)return"-"+this.negate().toString(t);var r;if(16==t)r=4;else if(8==t)r=3;else if(2==t)r=1;else if(32==t)r=5;else{if(4!=t)return this.toRadix(t);r=2}var e,i=(1<0)for(this.DB>h&&(e=this[a]>>h)>0&&(n=!0,o=s(e));a>=0;)r>h?(e=(this[a]&(1<>(h+=this.DB-r)):(e=this[a]>>(h-=r)&i,0>=h&&(h+=this.DB,--a)),e>0&&(n=!0),n&&(o+=s(e));return n?o:"0"}function f(){var t=i();return e.ZERO.subTo(this,t),t}function d(){return 0>this.s?this.negate():this}function g(t){var r=this.s-t.s;if(0!=r)return r;var e=this.t;if(r=e-t.t,0!=r)return r;for(;--e>=0;)if(0!=(r=this[e]-t[e]))return r;return 0}function m(t){var r,e=1;return 0!=(r=t>>>16)&&(t=r,e+=16),0!=(r=t>>8)&&(t=r,e+=8),0!=(r=t>>4)&&(t=r,e+=4),0!=(r=t>>2)&&(t=r,e+=2),0!=(r=t>>1)&&(t=r,e+=1),e}function y(){return 0>=this.t?0:this.DB*(this.t-1)+m(this[this.t-1]^this.s&this.DM)}function b(t,r){var e;for(e=this.t-1;e>=0;--e)r[e+t]=this[e];for(e=t-1;e>=0;--e)r[e]=0;r.t=this.t+t,r.s=this.s}function v(t,r){for(var e=t;this.t>e;++e)r[e-t]=this[e];r.t=Math.max(this.t-t,0),r.s=this.s}function w(t,r){var e,i=t%this.DB,n=this.DB-i,s=(1<=0;--e)r[e+o+1]=this[e]>>n|a,a=(this[e]&s)<=0;--e)r[e]=0;r[o]=a,r.t=this.t+o+1,r.s=this.s,r.clamp()}function k(t,r){r.s=this.s;var e=Math.floor(t/this.DB);if(e>=this.t)return r.t=0,void 0;var i=t%this.DB,n=this.DB-i,s=(1<>i;for(var o=e+1;this.t>o;++o)r[o-e-1]|=(this[o]&s)<>i;i>0&&(r[this.t-e-1]|=(this.s&s)<e;)i+=this[e]-t[e],r[e++]=i&this.DM,i>>=this.DB;if(t.te;)i+=this[e],r[e++]=i&this.DM,i>>=this.DB;i+=this.s}else{for(i+=this.s;t.t>e;)i-=t[e],r[e++]=i&this.DM,i>>=this.DB;i-=t.s}r.s=0>i?-1:0,-1>i?r[e++]=this.DV+i:i>0&&(r[e++]=i),r.t=e,r.clamp()}function A(t,r){var i=this.abs(),n=t.abs(),s=i.t;for(r.t=s+n.t;--s>=0;)r[s]=0;for(s=0;n.t>s;++s)r[s+i.t]=i.am(0,n[s],r,s,0,i.t);r.s=0,r.clamp(),this.s!=t.s&&e.ZERO.subTo(r,r)}function _(t){for(var r=this.abs(),e=t.t=2*r.t;--e>=0;)t[e]=0;for(e=0;r.t-1>e;++e){var i=r.am(e,r[e],t,2*e,0,1);(t[e+r.t]+=r.am(e+1,2*r[e],t,2*e+1,i,r.t-e-1))>=r.DV&&(t[e+r.t]-=r.DV,t[e+r.t+1]=1)}t.t>0&&(t[t.t-1]+=r.am(e,r[e],t,2*e,0,1)),t.s=0,t.clamp()}function S(t,r,n){var s=t.abs();if(!(0>=s.t)){var o=this.abs();if(o.t0?(s.lShiftTo(u,a),o.lShiftTo(u,n)):(s.copyTo(a),o.copyTo(n));var p=a.t,l=a[p-1];if(0!=l){var f=l*(1<1?a[p-2]>>this.F2:0),d=this.FV/f,g=(1<=0&&(n[n.t++]=1,n.subTo(w,n)),e.ONE.dlShiftTo(p,w),w.subTo(a,a);p>a.t;)a[a.t++]=0;for(;--v>=0;){var k=n[--b]==l?this.DM:Math.floor(n[b]*d+(n[b-1]+y)*g);if(k>(n[b]+=a.am(0,k,n,v,0,p)))for(a.dlShiftTo(v,w),n.subTo(w,n);n[b]<--k;)n.subTo(w,n)}null!=r&&(n.drShiftTo(p,r),h!=c&&e.ZERO.subTo(r,r)),n.t=p,n.clamp(),u>0&&n.rShiftTo(u,n),0>h&&e.ZERO.subTo(n,n)}}}function j(t){var r=i();return this.abs().divRemTo(t,null,r),0>this.s&&r.compareTo(e.ZERO)>0&&t.subTo(r,r),r}function T(t){this.m=t}function O(t){return 0>t.s||t.compareTo(this.m)>=0?t.mod(this.m):t}function E(t){return t}function I(t){t.divRemTo(this.m,null,t)}function B(t,r,e){t.multiplyTo(r,e),this.reduce(e)}function x(t,r){t.squareTo(r),this.reduce(r)}function P(){if(1>this.t)return 0;var t=this[0];if(0==(1&t))return 0;var r=3&t;return r=15&r*(2-(15&t)*r),r=255&r*(2-(255&t)*r),r=65535&r*(2-(65535&(65535&t)*r)),r=r*(2-t*r%this.DV)%this.DV,r>0?this.DV-r:-r}function N(t){this.m=t,this.mp=t.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<t.s&&r.compareTo(e.ZERO)>0&&this.m.subTo(r,r),r}function K(t){var r=i();return t.copyTo(r),this.reduce(r),r}function M(t){for(;t.t<=this.mt2;)t[t.t++]=0;for(var r=0;this.m.t>r;++r){var e=32767&t[r],i=e*this.mpl+((e*this.mph+(t[r]>>15)*this.mpl&this.um)<<15)&t.DM;for(e=r+this.m.t,t[e]+=this.m.am(0,i,t,r,0,this.m.t);t[e]>=t.DV;)t[e]-=t.DV,t[++e]++}t.clamp(),t.drShiftTo(this.m.t,t),t.compareTo(this.m)>=0&&t.subTo(this.m,t)}function R(t,r){t.squareTo(r),this.reduce(r)}function G(t,r,e){t.multiplyTo(r,e),this.reduce(e)}function H(){return 0==(this.t>0?1&this[0]:this.s)}function L(t,r){if(t>4294967295||1>t)return e.ONE;var n=i(),s=i(),o=r.convert(this),a=m(t)-1;for(o.copyTo(n);--a>=0;)if(r.sqrTo(n,s),(t&1<0)r.mulTo(s,o,n);else{var h=n;n=s,s=h}return r.revert(n)}function z(t,r){var e;return e=256>t||r.isEven()?new T(r):new N(r),this.exp(t,e)}function U(){var t=i();return this.copyTo(t),t}function q(){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)<>24}function V(){return 0==this.t?this.s:this[0]<<16>>16}function Z(t){return Math.floor(Math.LN2*this.DB/Math.log(t))}function X(){return 0>this.s?-1:0>=this.t||1==this.t&&0>=this[0]?0:1}function J(t){if(null==t&&(t=10),0==this.signum()||2>t||t>36)return"0";var r=this.chunkSize(t),e=Math.pow(t,r),n=c(e),s=i(),o=i(),a="";for(this.divRemTo(n,s,o);s.signum()>0;)a=(e+o.intValue()).toString(t).substr(1)+a,s.divRemTo(n,s,o);return o.intValue().toString(t)+a}function Y(t,r){this.fromInt(0),null==r&&(r=10);for(var i=this.chunkSize(r),n=Math.pow(r,i),s=!1,a=0,h=0,c=0;t.length>c;++c){var u=o(t,c);0>u?"-"==t.charAt(c)&&0==this.signum()&&(s=!0):(h=r*h+u,++a>=i&&(this.dMultiply(n),this.dAddOffset(h,0),a=0,h=0))}a>0&&(this.dMultiply(Math.pow(r,a)),this.dAddOffset(h,0)),s&&e.ZERO.subTo(this,this)}function W(t,r,i){if("number"==typeof r)if(2>t)this.fromInt(1);else for(this.fromNumber(t,i),this.testBit(t-1)||this.bitwiseTo(e.ONE.shiftLeft(t-1),sr,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(r);)this.dAddOffset(2,0),this.bitLength()>t&&this.subTo(e.ONE.shiftLeft(t-1),this);else{var n=[],s=7&t;n.length=(t>>3)+1,r.nextBytes(n),s>0?n[0]&=(1<0)for(this.DB>i&&(e=this[t]>>i)!=(this.s&this.DM)>>i&&(r[n++]=e|this.s<=0;)8>i?(e=(this[t]&(1<>(i+=this.DB-8)):(e=255&this[t]>>(i-=8),0>=i&&(i+=this.DB,--t)),(n>0||e!=this.s)&&(r[n++]=e);return r}function $(t){return 0==this.compareTo(t)}function tr(t){return 0>this.compareTo(t)?this:t}function rr(t){return this.compareTo(t)>0?this:t}function er(t,r,e){var i,n,s=Math.min(t.t,this.t);for(i=0;s>i;++i)e[i]=r(this[i],t[i]);if(t.ti;++i)e[i]=r(this[i],n);e.t=this.t}else{for(n=this.s&this.DM,i=s;t.t>i;++i)e[i]=r(n,t[i]);e.t=t.t}e.s=r(this.s,t.s),e.clamp()}function ir(t,r){return t&r}function nr(t){var r=i();return this.bitwiseTo(t,ir,r),r}function sr(t,r){return t|r}function or(t){var r=i();return this.bitwiseTo(t,sr,r),r}function ar(t,r){return t^r}function hr(t){var r=i();return this.bitwiseTo(t,ar,r),r}function cr(t,r){return t&~r}function ur(t){var r=i();return this.bitwiseTo(t,cr,r),r}function pr(){for(var t=i(),r=0;this.t>r;++r)t[r]=this.DM&~this[r];return t.t=this.t,t.s=~this.s,t}function lr(t){var r=i();return 0>t?this.rShiftTo(-t,r):this.lShiftTo(t,r),r}function fr(t){var r=i();return 0>t?this.lShiftTo(-t,r):this.rShiftTo(t,r),r}function dr(t){if(0==t)return-1;var r=0;return 0==(65535&t)&&(t>>=16,r+=16),0==(255&t)&&(t>>=8,r+=8),0==(15&t)&&(t>>=4,r+=4),0==(3&t)&&(t>>=2,r+=2),0==(1&t)&&++r,r}function gr(){for(var t=0;this.t>t;++t)if(0!=this[t])return t*this.DB+dr(this[t]);return 0>this.s?this.t*this.DB:-1}function mr(t){for(var r=0;0!=t;)t&=t-1,++r;return r}function yr(){for(var t=0,r=this.s&this.DM,e=0;this.t>e;++e)t+=mr(this[e]^r);return t}function br(t){var r=Math.floor(t/this.DB);return r>=this.t?0!=this.s:0!=(this[r]&1<e;)i+=this[e]+t[e],r[e++]=i&this.DM,i>>=this.DB;if(t.te;)i+=this[e],r[e++]=i&this.DM,i>>=this.DB;i+=this.s}else{for(i+=this.s;t.t>e;)i+=t[e],r[e++]=i&this.DM,i>>=this.DB;i+=t.s}r.s=0>i?-1:0,i>0?r[e++]=i:-1>i&&(r[e++]=this.DV+i),r.t=e,r.clamp()}function _r(t){var r=i();return this.addTo(t,r),r}function Sr(t){var r=i();return this.subTo(t,r),r}function jr(t){var r=i();return this.multiplyTo(t,r),r}function Tr(){var t=i();return this.squareTo(t),t}function Or(t){var r=i();return this.divRemTo(t,r,null),r}function Er(t){var r=i();return this.divRemTo(t,null,r),r}function Ir(t){var r=i(),e=i();return this.divRemTo(t,r,e),[r,e]}function Br(t){this[this.t]=this.am(0,t-1,this,0,0,this.t),++this.t,this.clamp()}function xr(t,r){if(0!=t){for(;r>=this.t;)this[this.t++]=0;for(this[r]+=t;this[r]>=this.DV;)this[r]-=this.DV,++r>=this.t&&(this[this.t++]=0),++this[r]}}function Pr(){}function Nr(t){return t}function Dr(t,r,e){t.multiplyTo(r,e)}function Kr(t,r){t.squareTo(r)}function Mr(t){return this.exp(t,new Pr)}function Rr(t,r,e){var i=Math.min(this.t+t.t,r);for(e.s=0,e.t=i;i>0;)e[--i]=0;var n;for(n=e.t-this.t;n>i;++i)e[i+this.t]=this.am(0,t[i],e,i,0,this.t);for(n=Math.min(t.t,r);n>i;++i)this.am(0,t[i],e,i,0,r-i);e.clamp()}function Gr(t,r,e){--r;var i=e.t=this.t+t.t-r;for(e.s=0;--i>=0;)e[i]=0;for(i=Math.max(r-this.t,0);t.t>i;++i)e[this.t+i-r]=this.am(r-i,t[i],e,0,0,this.t+i-r);e.clamp(),e.drShiftTo(1,e)}function Hr(t){this.r2=i(),this.q3=i(),e.ONE.dlShiftTo(2*t.t,this.r2),this.mu=this.r2.divide(t),this.m=t}function Lr(t){if(0>t.s||t.t>2*this.m.t)return t.mod(this.m);if(0>t.compareTo(this.m))return t;var r=i();return t.copyTo(r),this.reduce(r),r}function zr(t){return t}function Ur(t){for(t.drShiftTo(this.m.t-1,this.r2),t.t>this.m.t+1&&(t.t=this.m.t+1,t.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);0>t.compareTo(this.r2);)t.dAddOffset(1,this.m.t+1);for(t.subTo(this.r2,t);t.compareTo(this.m)>=0;)t.subTo(this.m,t)}function qr(t,r){t.squareTo(r),this.reduce(r)}function Fr(t,r,e){t.multiplyTo(r,e),this.reduce(e)}function Vr(t,r){var e,n,s=t.bitLength(),o=c(1);if(0>=s)return o;e=18>s?1:48>s?3:144>s?4:768>s?5:6,n=8>s?new T(r):r.isEven()?new Hr(r):new N(r);var a=[],h=3,u=e-1,p=(1<1){var l=i();for(n.sqrTo(a[1],l);p>=h;)a[h]=i(),n.mulTo(l,a[h-2],a[h]),h+=2}var f,d,g=t.t-1,y=!0,b=i();for(s=m(t[g])-1;g>=0;){for(s>=u?f=t[g]>>s-u&p:(f=(t[g]&(1<0&&(f|=t[g-1]>>this.DB+s-u)),h=e;0==(1&f);)f>>=1,--h;if(0>(s-=h)&&(s+=this.DB,--g),y)a[f].copyTo(o),y=!1;else{for(;h>1;)n.sqrTo(o,b),n.sqrTo(b,o),h-=2;h>0?n.sqrTo(o,b):(d=o,o=b,b=d),n.mulTo(b,a[f],o)}for(;g>=0&&0==(t[g]&1<--s&&(s=this.DB-1,--g)}return n.revert(o)}function Zr(t){var r=0>this.s?this.negate():this.clone(),e=0>t.s?t.negate():t.clone();if(0>r.compareTo(e)){var i=r;r=e,e=i}var n=r.getLowestSetBit(),s=e.getLowestSetBit();if(0>s)return r;for(s>n&&(s=n),s>0&&(r.rShiftTo(s,r),e.rShiftTo(s,e));r.signum()>0;)(n=r.getLowestSetBit())>0&&r.rShiftTo(n,r),(n=e.getLowestSetBit())>0&&e.rShiftTo(n,e),r.compareTo(e)>=0?(r.subTo(e,r),r.rShiftTo(1,r)):(e.subTo(r,e),e.rShiftTo(1,e));return s>0&&e.lShiftTo(s,e),e}function Xr(t){if(0>=t)return 0;var r=this.DV%t,e=0>this.s?t-1:0;if(this.t>0)if(0==r)e=this[0]%t;else for(var i=this.t-1;i>=0;--i)e=(r*e+this[i])%t;return e}function Jr(t){var r=t.isEven();if(this.isEven()&&r||0==t.signum())return e.ZERO;for(var i=t.clone(),n=this.clone(),s=c(1),o=c(0),a=c(0),h=c(1);0!=i.signum();){for(;i.isEven();)i.rShiftTo(1,i),r?(s.isEven()&&o.isEven()||(s.addTo(this,s),o.subTo(t,o)),s.rShiftTo(1,s)):o.isEven()||o.subTo(t,o),o.rShiftTo(1,o);for(;n.isEven();)n.rShiftTo(1,n),r?(a.isEven()&&h.isEven()||(a.addTo(this,a),h.subTo(t,h)),a.rShiftTo(1,a)):h.isEven()||h.subTo(t,h),h.rShiftTo(1,h);i.compareTo(n)>=0?(i.subTo(n,i),r&&s.subTo(a,s),o.subTo(h,o)):(n.subTo(i,n),r&&a.subTo(s,a),h.subTo(o,h))}return 0!=n.compareTo(e.ONE)?e.ZERO:h.compareTo(t)>=0?h.subtract(t):0>h.signum()?(h.addTo(t,h),0>h.signum()?h.add(t):h):h}function Yr(t){var r,e=this.abs();if(1==e.t&&e[0]<=oe[oe.length-1]){for(r=0;oe.length>r;++r)if(e[0]==oe[r])return!0;return!1}if(e.isEven())return!1;for(r=1;oe.length>r;){for(var i=oe[r],n=r+1;oe.length>n&&ae>i;)i*=oe[n++];for(i=e.modInt(i);n>r;)if(0==i%oe[r++])return!1}return e.millerRabin(t)}function m(t){var r,e=1;return 0!=(r=t>>>16)&&(t=r,e+=16),0!=(r=t>>8)&&(t=r,e+=8),0!=(r=t>>4)&&(t=r,e+=4),0!=(r=t>>2)&&(t=r,e+=2),0!=(r=t>>1)&&(t=r,e+=1),e}function Wr(){var t=this.toByteArray(),r=8*(t.length-1)+m(t[0]),e="";return e+=String.fromCharCode((65280&r)>>8),e+=String.fromCharCode(255&r),e+=te.bin2str(t)}function Qr(t){var r=this.subtract(e.ONE),n=r.getLowestSetBit();if(0>=n)return!1;var s=r.shiftRight(n);t=t+1>>1,t>oe.length&&(t=oe.length);for(var o,a=i(),h=[],c=0;t>c;++c){for(;o=oe[Math.floor(Math.random()*oe.length)],-1!=h.indexOf(o););h.push(o),a.fromInt(o);var u=a.modPow(s,this);if(0!=u.compareTo(e.ONE)&&0!=u.compareTo(r)){for(var o=1;n>o++&&0!=u.compareTo(r);)if(u=u.modPowInt(2,this),0==u.compareTo(e.ONE))return!1;if(0!=u.compareTo(r))return!1}}return!0}var $r,te=t("../../util");e.prototype.am=n,$r=26,e.prototype.DB=$r,e.prototype.DM=(1<<$r)-1,e.prototype.DV=1<<$r;var re=52;e.prototype.FV=Math.pow(2,re),e.prototype.F1=re-$r,e.prototype.F2=2*$r-re;var ee,ie,ne="0123456789abcdefghijklmnopqrstuvwxyz",se=[];for(ee="0".charCodeAt(0),ie=0;9>=ie;++ie)se[ee++]=ie;for(ee="a".charCodeAt(0),ie=10;36>ie;++ie)se[ee++]=ie;for(ee="A".charCodeAt(0),ie=10;36>ie;++ie)se[ee++]=ie;T.prototype.convert=O,T.prototype.revert=E,T.prototype.reduce=I,T.prototype.mulTo=B,T.prototype.sqrTo=x,N.prototype.convert=D,N.prototype.revert=K,N.prototype.reduce=M,N.prototype.mulTo=G,N.prototype.sqrTo=R,e.prototype.copyTo=a,e.prototype.fromInt=h,e.prototype.fromString=u,e.prototype.clamp=p,e.prototype.dlShiftTo=b,e.prototype.drShiftTo=v,e.prototype.lShiftTo=w,e.prototype.rShiftTo=k,e.prototype.subTo=C,e.prototype.multiplyTo=A,e.prototype.squareTo=_,e.prototype.divRemTo=S,e.prototype.invDigit=P,e.prototype.isEven=H,e.prototype.exp=L,e.prototype.toString=l,e.prototype.negate=f,e.prototype.abs=d,e.prototype.compareTo=g,e.prototype.bitLength=y,e.prototype.mod=j,e.prototype.modPowInt=z,e.ZERO=c(0),e.ONE=c(1),r.exports=e,Pr.prototype.convert=Nr,Pr.prototype.revert=Nr,Pr.prototype.mulTo=Dr,Pr.prototype.sqrTo=Kr,Hr.prototype.convert=Lr,Hr.prototype.revert=zr,Hr.prototype.reduce=Ur,Hr.prototype.mulTo=Fr,Hr.prototype.sqrTo=qr;var oe=[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,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],ae=(1<<26)/oe[oe.length-1],e=t("./jsbn.js");e.prototype.chunkSize=Z,e.prototype.toRadix=J,e.prototype.fromRadix=Y,e.prototype.fromNumber=W,e.prototype.bitwiseTo=er,e.prototype.changeBit=vr,e.prototype.addTo=Ar,e.prototype.dMultiply=Br,e.prototype.dAddOffset=xr,e.prototype.multiplyLowerTo=Rr,e.prototype.multiplyUpperTo=Gr,e.prototype.modInt=Xr,e.prototype.millerRabin=Qr,e.prototype.clone=U,e.prototype.intValue=q,e.prototype.byteValue=F,e.prototype.shortValue=V,e.prototype.signum=X,e.prototype.toByteArray=Q,e.prototype.equals=$,e.prototype.min=tr,e.prototype.max=rr,e.prototype.and=nr,e.prototype.or=or,e.prototype.xor=hr,e.prototype.andNot=ur,e.prototype.not=pr,e.prototype.shiftLeft=lr,e.prototype.shiftRight=fr,e.prototype.getLowestSetBit=gr,e.prototype.bitCount=yr,e.prototype.testBit=br,e.prototype.setBit=wr,e.prototype.clearBit=kr,e.prototype.flipBit=Cr,e.prototype.add=_r,e.prototype.subtract=Sr,e.prototype.multiply=jr,e.prototype.divide=Or,e.prototype.remainder=Er,e.prototype.divideAndRemainder=Ir,e.prototype.modPow=Vr,e.prototype.modInverse=Jr,e.prototype.pow=Mr,e.prototype.gcd=Zr,e.prototype.isProbablePrime=Yr,e.prototype.toMPI=Wr,e.prototype.square=Tr},{"../../util":55,"./jsbn.js":20}],21:[function(t,r){function e(){function t(t){for(var r=0;t.length>r;r++)t[r]=o.getSecureRandomOctet()}this.nextBytes=t}function i(){function t(t,r,e,i,o){var a=t.mod(e).modPow(r.mod(e.subtract(n.ONE)),e),h=t.mod(i).modPow(r.mod(i.subtract(n.ONE)),i);s.print_debug("rsa.js decrypt\nxpn:"+s.hexstrdump(a.toMPI())+"\nxqn:"+s.hexstrdump(h.toMPI()));var c=h.subtract(a);return 0==c[0]?(c=a.subtract(h),c=c.multiply(o).mod(i),c=i.subtract(c)):c=c.multiply(o).mod(i),c.multiply(e).add(a)}function r(t,r,e){return t.modPowInt(r,e)}function i(t,r,e){return t.modPow(r,e)}function o(t,r,e){return t.modPowInt(r,e)}function a(){this.n=null,this.e=0,this.ee=null,this.d=null,this.p=null,this.q=null,this.dmp1=null,this.dmq1=null,this.u=null}function h(t,r){var i=new a,s=new e,o=t>>1;for(i.e=parseInt(r,16),i.ee=new n(r,16);;){for(;i.p=new n(t-o,1,s),0!=i.p.subtract(n.ONE).gcd(i.ee).compareTo(n.ONE)||!i.p.isProbablePrime(10););for(;i.q=new n(o,1,s),0!=i.q.subtract(n.ONE).gcd(i.ee).compareTo(n.ONE)||!i.q.isProbablePrime(10););if(0>=i.p.compareTo(i.q)){var h=i.p;i.p=i.q,i.q=h}var c=i.p.subtract(n.ONE),u=i.q.subtract(n.ONE),p=c.multiply(u);if(0==p.gcd(i.ee).compareTo(n.ONE)){i.n=i.p.multiply(i.q),i.d=i.ee.modInverse(p),i.dmp1=i.d.mod(c),i.dmq1=i.d.mod(u),i.u=i.p.modInverse(i.q);break}}return i}this.encrypt=r,this.decrypt=t,this.verify=o,this.sign=i,this.generate=h,this.keyObject=a}var n=t("./jsbn.js"),s=t("../../util"),o=t("../random.js");r.exports=i},{"../../util":55,"../random.js":22,"./jsbn.js":20}],22:[function(t,r){var e=t("../type/mpi.js");r.exports={getRandomBytes:function(t){for(var r="",e=0;t>e;e++)r+=String.fromCharCode(this.getSecureRandomOctet());return r},getPseudoRandom:function(t,r){return Math.round(Math.random()*(r-t))+t},getSecureRandom:function(t,r){var e=new Uint32Array(1);window.crypto.getRandomValues(e);for(var i=(r-t).toString(2).length;(e[0]&Math.pow(2,i)-1)>r-t;)window.crypto.getRandomValues(e);return t+Math.abs(e[0]&Math.pow(2,i)-1)},getSecureRandomOctet:function(){var t=new Uint32Array(1);return window.crypto.getRandomValues(t),255&t[0]},getRandomBigInteger:function(t){if(0>t)return null;var r=Math.floor((t+7)/8),i=this.getRandomBytes(r);t%8>0&&(i=String.fromCharCode(Math.pow(2,t%8)-1&i.charCodeAt(0))+i.substring(1));var n=new e;return n.fromBytes(i),n.toBigInteger()},getRandomBigIntegerInRange:function(t,r){if(!(0>=r.compareTo(t))){for(var e=r.subtract(t),i=this.getRandomBigInteger(e.bitLength());i>e;)i=this.getRandomBigInteger(e.bitLength());return t.add(i)}}}},{"../type/mpi.js":53}],23:[function(t,r){var e=t("./public_key"),i=t("./pkcs1.js"),n=t("./hash");r.exports={verify:function(t,r,s,o,a){var h=n.digest(r,a);switch(t){case 1:case 2:case 3:var c=new e.rsa,u=o[0].toBigInteger(),p=o[1].toBigInteger(),l=s[0].toBigInteger(),f=c.verify(l,p,u),d=i.emsa.decode(r,f.toMPI().substring(2));if(-1==d)throw Error("PKCS1 padding in message or key incorrect. Aborting...");return d==h;case 16:throw Error("signing with Elgamal is not defined in the OpenPGP standard.");case 17:var g=new e.dsa,m=s[0].toBigInteger(),y=s[1].toBigInteger(),b=o[0].toBigInteger(),v=o[1].toBigInteger(),w=o[2].toBigInteger(),k=o[3].toBigInteger(),C=a,f=g.verify(r,m,y,C,b,v,w,k);return 0==f.compareTo(m);default:throw Error("Invalid signature algorithm.")}},sign:function(t,r,n,s){switch(r){case 1:case 2:case 3:var o=new e.rsa,a=n[2].toBigInteger(),h=n[0].toBigInteger(),c=i.emsa.encode(t,s,n[0].byteLength());return o.sign(c,a,h).toMPI();case 17:var u=new e.dsa,p=n[0].toBigInteger(),l=n[1].toBigInteger(),f=n[2].toBigInteger();n[3].toBigInteger();var d=n[4].toBigInteger(),c=s,g=u.sign(t,c,f,p,l,d);return""+g[0]+(""+g[1]);case 16:throw Error("Signing with Elgamal is not defined in the OpenPGP standard.");default:throw Error("Invalid signature algorithm.")}}}},{"./hash":11,"./pkcs1.js":16,"./public_key":19}],24:[function(t,r){function e(t){var r=t.split("-----");return r[1].match(/BEGIN PGP MESSAGE, PART \d+\/\d+/)?0:r[1].match(/BEGIN PGP MESSAGE, PART \d+/)?1:r[1].match(/BEGIN PGP SIGNED MESSAGE/)?2:r[1].match(/BEGIN PGP MESSAGE/)?3:r[1].match(/BEGIN PGP PUBLIC KEY BLOCK/)?4:r[1].match(/BEGIN PGP PRIVATE KEY BLOCK/)?5:void 0}function i(){var t="";return openpgp.config.config.show_version&&(t+="Version: "+openpgp.config.versionstring+"\r\n"),openpgp.config.config.show_comment&&(t+="Comment: "+openpgp.config.commentstring+"\r\n"),t+="\r\n"}function n(t){var r=o(t),e=""+String.fromCharCode(r>>16)+String.fromCharCode(255&r>>8)+String.fromCharCode(255&r);return c.encode(e)}function s(t,r){var e=n(t),i=r;return e[0]==i[0]&&e[1]==i[1]&&e[2]==i[2]}function o(t){for(var r=11994318,e=0;t.length-e>16;)r=r<<8^u[255&(r>>16^t.charCodeAt(e))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+1))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+2))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+3))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+4))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+5))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+6))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+7))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+8))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+9))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+10))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+11))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+12))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+13))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+14))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+15))],e+=16;for(var i=e;t.length>i;i++)r=r<<8^u[255&(r>>16^t.charCodeAt(e++))];return 16777215&r}function a(t){t=t.replace(/\r/g,"");var r=e(t);if(2!=r){var i=t.split("-----"),o={openpgp:c.decode(i[2].split("\n\n")[1].split("\n=")[0].replace(/\n- /g,"\n")),type:r};return s(o.openpgp,i[2].split("\n\n")[1].split("\n=")[1].split("\n")[0])?o:(util.print_error("Ascii armor integrity check on message failed: '"+i[2].split("\n\n")[1].split("\n=")[1].split("\n")[0]+"' should be '"+n(o))+"'",!1)}var i=t.split("-----"),a={text:i[2].replace(/\n- /g,"\n").split("\n\n")[1],openpgp:base64_decode(i[4].split("\n\n")[1].split("\n=")[0]),type:r};return s(a.openpgp,i[4].split("\n\n")[1].split("\n=")[1])?a:(util.print_error("Ascii armor integrity check on message failed"),!1)}function h(t,r,e,s){var o="";switch(t){case 0:o+="-----BEGIN PGP MESSAGE, PART "+e+"/"+s+"-----\r\n",o+=i(),o+=c.encode(r),o+="\r\n="+n(r)+"\r\n",o+="-----END PGP MESSAGE, PART "+e+"/"+s+"-----\r\n";break;case 1:o+="-----BEGIN PGP MESSAGE, PART "+e+"-----\r\n",o+=i(),o+=c.encode(r),o+="\r\n="+n(r)+"\r\n",o+="-----END PGP MESSAGE, PART "+e+"-----\r\n";break;case 2:o+="\r\n-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: "+r.hash+"\r\n\r\n",o+=r.text.replace(/\n-/g,"\n- -"),o+="\r\n-----BEGIN PGP SIGNATURE-----\r\n",o+=i(),o+=c.encode(r.openpgp),o+="\r\n="+n(r.openpgp)+"\r\n",o+="-----END PGP SIGNATURE-----\r\n";break;case 3:o+="-----BEGIN PGP MESSAGE-----\r\n",o+=i(),o+=c.encode(r),o+="\r\n="+n(r)+"\r\n",o+="-----END PGP MESSAGE-----\r\n";break;case 4:o+="-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n",o+=i(),o+=c.encode(r),o+="\r\n="+n(r)+"\r\n",o+="-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n";break;case 5:o+="-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n",o+=i(),o+=c.encode(r),o+="\r\n="+n(r)+"\r\n",o+="-----END PGP PRIVATE KEY BLOCK-----\r\n"}return o}var c=t("./base64.js"),u=[0,8801531,25875725,17603062,60024545,51751450,35206124,44007191,128024889,120049090,103502900,112007375,70412248,78916387,95990485,88014382,264588937,256049778,240098180,248108927,207005800,215016595,232553829,224014750,140824496,149062475,166599357,157832774,200747345,191980970,176028764,184266919,520933865,529177874,512099556,503334943,480196360,471432179,487973381,496217854,414011600,405478443,422020573,430033190,457094705,465107658,448029500,439496647,281648992,273666971,289622637,298124950,324696449,333198714,315665548,307683447,392699481,401494690,383961940,375687087,352057528,343782467,359738805,368533838,1041867730,1050668841,1066628831,1058355748,1032471859,1024199112,1006669886,1015471301,968368875,960392720,942864358,951368477,975946762,984451313,1000411399,992435708,836562267,828023200,810956886,818967725,844041146,852051777,868605623,860066380,914189410,922427545,938981743,930215316,904825475,896059e3,878993294,887231349,555053627,563297984,547333942,538569677,579245274,570480673,588005847,596249900,649392898,640860153,658384399,666397428,623318499,631331096,615366894,606833685,785398962,777416777,794487231,802989380,759421523,767923880,751374174,743392165,695319947,704115056,687564934,679289981,719477610,711202705,728272487,737067676,2083735460,2092239711,2109313705,2101337682,2141233477,2133257662,2116711496,2125215923,2073216669,2064943718,2048398224,2057199467,2013339772,2022141063,2039215473,2030942602,1945504045,1936737750,1920785440,1929023707,1885728716,1893966647,1911503553,1902736954,1951893524,1959904495,1977441561,1968902626,2009362165,2000822798,1984871416,1992881923,1665111629,1673124534,1656046400,1647513531,1621913772,1613380695,1629922721,1637935450,1688082292,1679317903,1695859321,1704103554,1728967061,1737211246,1720132760,1711368291,1828378820,1820103743,1836060105,1844855090,1869168165,1877963486,1860430632,1852155859,1801148925,1809650950,1792118e3,1784135691,1757986588,1750004711,1765960209,1774462698,1110107254,1118611597,1134571899,1126595968,1102643863,1094667884,1077139354,1085643617,1166763343,1158490548,1140961346,1149762745,1176011694,1184812885,1200772771,1192499800,1307552511,1298785796,1281720306,1289958153,1316768798,1325007077,1341561107,1332794856,1246636998,1254647613,1271201483,1262662192,1239272743,1230733788,1213667370,1221678289,1562785183,1570797924,1554833554,1546300521,1588974462,1580441477,1597965939,1605978760,1518843046,1510078557,1527603627,1535847760,1494504007,1502748348,1486784330,1478020017,1390639894,1382365165,1399434779,1408230112,1366334967,1375129868,1358579962,1350304769,1430452783,1438955220,1422405410,1414423513,1456544974,1448562741,1465633219,1474135352];r.exports={encode:h,decode:a}},{"./base64.js":25}],25:[function(t,r){function e(t){var r,e,i,s="",o=0,a=0,h=t.length;for(i=0;h>i;i++)e=t.charCodeAt(i),0==a?(s+=n.charAt(63&e>>2),r=(3&e)<<4):1==a?(s+=n.charAt(r|15&e>>4),r=(15&e)<<2):2==a&&(s+=n.charAt(r|3&e>>6),o+=1,0==o%60&&(s+="\n"),s+=n.charAt(63&e)),o+=1,0==o%60&&(s+="\n"),a+=1,3==a&&(a=0);return a>0&&(s+=n.charAt(r),o+=1,0==o%60&&(s+="\n"),s+="=",o+=1),1==a&&(0==o%60&&(s+="\n"),s+="="),s}function i(t){var r,e,i="",s=0,o=0,a=t.length;for(e=0;a>e;e++)r=n.indexOf(t.charAt(e)),r>=0&&(s&&(i+=String.fromCharCode(o|255&r>>6-s)),s=7&s+2,o=255&r<n;n++){var h=new openpgp_packet_onepasssignature,c="";c=0===n?h.write_packet(1,openpgp.config.config.prefer_hash_algorithm,t,!1):h.write_packet(1,openpgp.config.config.prefer_hash_algorithm,t,!1),s.print_debug_hexstr_dump("onepasssigstr: |"+c+"|\n",c);var u=(new openpgp_packet_signature).write_message_signature(1,e.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"),t);s.print_debug_hexstr_dump("datasignature: |"+u.openpgp+"|\n",u.openpgp),o=0===n?c+a+u.openpgp:c+o+u.openpgp}s.print_debug_hexstr_dump("signed packet: |"+o+"|\n",o);var p=openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher),l="";for(n=0;r.length>n;n++){var f=r[n].getEncryptionKey();if(null===f)return s.print_error("no encryption key found! Key is for signing only."),null;l+=(new openpgp_packet_encryptedsessionkey).write_pub_key_packet(f.getKeyId(),f.MPIs,f.publicKeyAlgorithm,openpgp.config.config.encryption_cipher,p)}return l+=openpgp.config.config.integrity_protect?(new openpgp_packet_encryptedintegrityprotecteddata).write_packet(openpgp.config.config.encryption_cipher,p,o):(new openpgp_packet_encrypteddata).write_packet(openpgp.config.config.encryption_cipher,p,o),i.encode(3,l,null,null)}function h(t,r){var e="",n=(new openpgp_packet_literaldata).write_packet(r.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"));s.print_debug_hexstr_dump("literal_packet: |"+n+"|\n",n),e=n;for(var o=openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher),a="",h=0;t.length>h;h++){var c=t[h].getEncryptionKey();if(null===c)return s.print_error("no encryption key found! Key is for signing only."),null;a+=(new openpgp_packet_encryptedsessionkey).write_pub_key_packet(c.getKeyId(),c.MPIs,c.publicKeyAlgorithm,openpgp.config.config.encryption_cipher,o)}return a+=openpgp.config.config.integrity_protect?(new openpgp_packet_encryptedintegrityprotecteddata).write_packet(openpgp.config.config.encryption_cipher,o,e):(new openpgp_packet_encrypteddata).write_packet(openpgp.config.config.encryption_cipher,o,e),i.encode(3,a,null,null)}function c(t,r){var e=(new openpgp_packet_signature).write_message_signature(1,r.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"),t),n={text:r.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"),openpgp:e.openpgp,hash:e.hash};return i.encode(2,n,null,null)}this.tostring="",this.generateKeyPair=o,this.write_signed_message=c,this.write_signed_and_encrypted_message=a,this.write_encrypted_message=h,this.readArmoredPackets=r,this.readDearmoredPackets=e,this.init=t}var i=t("./encoding/armor.js"),n=t("./packet"),s=t("./util");r.exports=new e},{"./encoding/armor.js":24,"./packet":34,"./util":55}],30:[function(t,r){var e=t("./packet"),i=t("./enums.js"),n=t("./encoding/armor.js"),s=function(){function t(){var t=JSON.parse(window.localStorage.getItem("armoredPacketlists"));(null===t||0===t.length)&&(t=[]),this.armoredPacketlists=t;for(var r,i=0;t.length>i;i++)r=new e.list,r.read(t[i]),this.parsedPacketlists.push(r)}function r(){window.localStorage.setItem("armoredPacketlists",JSON.stringify(this.armoredPacketlists))}function s(t,r){var e,n=!1;return r=r.toLowerCase(),t.tag==i.packet.userid&&(e=t.userid,e=e.split("<")[1].split("<")[0].trim.toLowerCase(),e==r&&(n=!0)),n}function o(t,r){return t.getKeyId&&t.getKeyId()==r?!0:!1}function a(t,r,e,i){for(var n,s=0;i.length>s;s++)if(n=i[s],identityMatch=t(n,r),e?n.tag==e&&(packetMatch=!0):packetMatch=!0,packetMatch&&identityMatch)return!0;return!1}function h(t,r,e){for(var i,n,s,o=[],h=0;this.parsedPacketlists.length>h;h++)n=!1,s=!1,i=this.parsedPacketlists[h],a(t,r,e,i)&&o.push(i);return o}function c(t){return h(s,t,i.packet.public_key)}function u(){return h(s,email,i.packet.secret_key)}function p(t){return this.checkForIdentityAndPacketMatch(o,t)}function l(t){this.armoredPacketlists.push(t);var r=n.decode(t.replace(/\r/g,"")).openpgp;return packetlist=new e.list,packetlist.read(r),this.parsedPacketlists.push(packetlist),!0}function f(t){return this.publicKey[t]}function d(t){var r=this.publicKeys.splice(t,1);return this.store(),r}this.armoredPacketlists=[],this.parsedPacketlists=[],this.init=t,this.store=r,this.checkForIdentityAndPacketMatch=h,this.getPublicKeyForAddress=c,this.getPrivateKeyForAddress=u,this.getPacketlistsForKeyId=p,this.importPacketlist=l,this.exportPublicKey=f,this.removePublicKey=d};r.exports=new s},{"./encoding/armor.js":24,"./enums.js":26,"./packet":34}],31:[function(){},{}],32:[function(t,r){var e=t("../enums.js");r.exports={compressed:t("./compressed.js"),sym_encrypted_integrity_protected:t("./sym_encrypted_integrity_protected.js"),public_key_encrypted_session_key:t("./public_key_encrypted_session_key.js"),sym_encrypted_session_key:t("./sym_encrypted_session_key.js"),literal:t("./literal.js"),public_key:t("./public_key.js"),symmetrically_encrypted:t("./symmetrically_encrypted.js"),marker:t("./marker.js"),public_subkey:t("./public_subkey.js"),user_attribute:t("./user_attribute.js"),one_pass_signature:t("./one_pass_signature.js"),secret_key:t("./secret_key.js"),userid:t("./userid.js"),secret_subkey:t("./secret_subkey.js"),signature:t("./signature.js"),trust:t("./trust.js")};for(var i in e.packet){var n=r.exports[i];void 0!=n&&(n.prototype.tag=e.packet[i])}},{"../enums.js":26,"./compressed.js":33,"./literal.js":35,"./marker.js":36,"./one_pass_signature.js":37,"./public_key.js":40,"./public_key_encrypted_session_key.js":41,"./public_subkey.js":42,"./secret_key.js":43,"./secret_subkey.js":44,"./signature.js":45,"./sym_encrypted_integrity_protected.js":46,"./sym_encrypted_session_key.js":47,"./symmetrically_encrypted.js":48,"./trust.js":49,"./user_attribute.js":50,"./userid.js":51}],33:[function(t,r){var e=t("../enums.js"),i=t("../compression/jxg.js"),n=t("../encoding/base64.js");r.exports=function(){this.packets,this.algorithm="uncompressed",this.compressed=null,this.read=function(t){this.algorithm=e.read(e.compression,t.charCodeAt(0)),this.compressed=t.substr(1),this.decompress()},this.write=function(){return null==this.compressed&&this.compress(),String.fromCharCode(e.write(e.compression,this.algorithm))+this.compressed},this.decompress=function(){var t;switch(this.algorithm){case"uncompressed":t=this.compressed;break;case"zip":var r=this.compressed,e=n.encode(r).replace(/\n/g,""),s=new i.Util.Unzip(i.Util.Base64.decodeAsArray(e));t=unescape(s.deflate()[0][0]);break;case"zlib":var o=this.compressed.charCodeAt(0)%16;if(8==o){var r=this.compressed.substring(0,this.compressed.length-4),e=n.encode(r).replace(/\n/g,"");t=i.decompress(e);break}util.print_error("Compression algorithm ZLIB only supports DEFLATE compression method.");break;case"bzip2":throw Error("Compression algorithm BZip2 [BZ2] is not implemented.");default:throw Error("Compression algorithm unknown :"+this.alogrithm)}this.packets.read(t)},this.compress=function(){switch(this.algorithm){case"uncompressed":this.compressed=this.packets.write();break;case"zip":util.print_error("Compression algorithm ZIP [RFC1951] is not implemented.");break;case"zlib":util.print_error("Compression algorithm ZLIB [RFC1950] is not implemented.");break;case"bzip2":util.print_error("Compression algorithm BZip2 [BZ2] is not implemented.");break;default:util.print_error("Compression algorithm unknown :"+this.type)}}}},{"../compression/jxg.js":1,"../encoding/base64.js":25,"../enums.js":26}],34:[function(t,r){t("../enums.js"),r.exports={list:t("./packetlist.js")};var e=t("./all_packets.js");for(var i in e)r.exports[i]=e[i]},{"../enums.js":26,"./all_packets.js":32,"./packetlist.js":39}],35:[function(t,r){var e=t("../util"),i=t("../enums.js");r.exports=function(){this.format="utf8",this.data="",this.date=new Date,this.set=function(t,r){this.format=r,this.data=t},this.setBytes=function(t,r){this.format=r,"utf8"==r&&(t=e.decode_utf8(t)),this.data=t},this.getBytes=function(){return"utf8"==this.format?e.encode_utf8(this.data):this.data},this.read=function(t){var r=i.read(i.literal,t[0].charCodeAt()),n=t.charCodeAt(1);this.filename=e.decode_utf8(t.substr(2,n)),this.date=e.readDate(t.substr(2+n,4));var s=t.substring(6+n);this.setBytes(s,r)},this.write=function(){var t=e.encode_utf8("msg.txt"),r=this.getBytes(),n="";return n+=String.fromCharCode(i.write(i.literal,this.format)),n+=String.fromCharCode(t.length),n+=t,n+=e.writeDate(this.date),n+=r}}},{"../enums.js":26,"../util":55}],36:[function(t,r){function e(){this.read=function(t){return 80==t[0].charCodeAt()&&71==t[1].charCodeAt()&&80==t[2].charCodeAt()?!0:!1}}r.exports=e},{}],37:[function(t,r){var e=t("../enums.js"),i=t("../type/keyid.js");r.exports=function(){this.version=null,this.type=null,this.hashAlgorithm=null,this.publicKeyAlgorithm=null,this.signingKeyId=null,this.flags=null,this.read=function(t){var r=0;return this.version=t.charCodeAt(r++),this.type=e.read(e.signature,t.charCodeAt(r++)),this.hashAlgorithm=e.read(e.hash,t.charCodeAt(r++)),this.publicKeyAlgorithm=e.read(e.publicKey,t.charCodeAt(r++)),this.signingKeyId=new i,this.signingKeyId.read(t.substr(r)),r+=8,this.flags=t.charCodeAt(r++),this},this.write=function(t,r,i,n,s){var o="";return o+=String.fromCharCode(3),o+=String.fromCharCode(e.write(e.signature,t)),o+=String.fromCharCode(e.write(e.hash,this.hashAlgorithm)),o+=String.fromCharCode(e.write(e.publicKey,i.algorithm)),o+=i.getKeyId(),o+=s?String.fromCharCode(0):String.fromCharCode(1)}}},{"../enums.js":26,"../type/keyid.js":52}],38:[function(t,r){var e=(t("../enums.js"),t("../util"));r.exports={readSimpleLength:function(t){var r,i=0,n=t[0].charCodeAt();return 192>n?(i=t[0].charCodeAt(),r=1):255>n?(i=(t[0].charCodeAt()-192<<8)+t[1].charCodeAt()+192,r=2):255==n&&(i=e.readNumber(t.substr(1,4)),r=5),{len:i,offset:r}},writeSimpleLength:function(t){var r="";return 192>t?r+=String.fromCharCode(t):t>191&&8384>t?(r+=String.fromCharCode((t-192>>8)+192),r+=String.fromCharCode(255&t-192)):(r+=String.fromCharCode(255),r+=e.writeNumber(t,4)),r},writeHeader:function(t,r){var e="";return e+=String.fromCharCode(192|t),e+=this.writeSimpleLength(r)},writeOldHeader:function(t,r){var i="";return 256>r?(i+=String.fromCharCode(128|t<<2),i+=String.fromCharCode(r)):65536>r?(i+=String.fromCharCode(1|(128|t<<2)),i+=e.writeNumber(r,2)):(i+=String.fromCharCode(2|(128|t<<2)),i+=e.writeNumber(r,4)),i},read:function(t,r,i){if(null==t||r>=t.length||2>t.substring(r).length||0==(128&t[r].charCodeAt()))return e.print_error("Error during parsing. This message / key is probably not containing a valid OpenPGP format."),null;var n,s=r,o=-1,a=-1;a=0,0!=(64&t[s].charCodeAt())&&(a=1);var h;a?o=63&t[s].charCodeAt():(o=(63&t[s].charCodeAt())>>2,h=3&t[s].charCodeAt()),s++;var c=null,u=-1;if(a)if(192>t[s].charCodeAt())n=t[s++].charCodeAt(),e.print_debug("1 byte length:"+n);else if(t[s].charCodeAt()>=192&&224>t[s].charCodeAt())n=(t[s++].charCodeAt()-192<<8)+t[s++].charCodeAt()+192,e.print_debug("2 byte length:"+n);else if(t[s].charCodeAt()>223&&255>t[s].charCodeAt()){n=1<<(31&t[s++].charCodeAt()),e.print_debug("4 byte length:"+n);var p=s+n;for(c=t.substring(s,s+n);;){if(192>t[p].charCodeAt()){var l=t[p++].charCodeAt();n+=l,c+=t.substring(p,p+l),p+=l;break}if(t[p].charCodeAt()>=192&&224>t[p].charCodeAt()){var l=(t[p++].charCodeAt()-192<<8)+t[p++].charCodeAt()+192;n+=l,c+=t.substring(p,p+l),p+=l;break}if(!(t[p].charCodeAt()>223&&255>t[p].charCodeAt())){p++;var l=t[p++].charCodeAt()<<24|t[p++].charCodeAt()<<16|t[p++].charCodeAt()<<8|t[p++].charCodeAt();c+=t.substring(p,p+l),n+=l,p+=l;break}var l=1<<(31&t[p++].charCodeAt());n+=l,c+=t.substring(p,p+l),p+=l}u=p}else s++,n=t[s++].charCodeAt()<<24|t[s++].charCodeAt()<<16|t[s++].charCodeAt()<<8|t[s++].charCodeAt();else switch(h){case 0:n=t[s++].charCodeAt();break;case 1:n=t[s++].charCodeAt()<<8|t[s++].charCodeAt();break;case 2:n=t[s++].charCodeAt()<<24|t[s++].charCodeAt()<<16|t[s++].charCodeAt()<<8|t[s++].charCodeAt();break;default:n=i}return-1==u&&(u=n),null==c&&(c=t.substring(s,s+u)),{tag:o,packet:c,offset:s+u}}}},{"../enums.js":26,"../util":55}],39:[function(t,r){var e=t("./packet.js"),i=t("./all_packets.js"),n=t("../enums.js");r.exports=function s(){this.length=0,this.read=function(t){for(var r=0;t.length>r;){var s=e.read(t,r,t.length-r);r=s.offset;var o=n.read(n.packet,s.tag),a=new i[o];this.push(a),a.read(s.packet)}},this.write=function(){for(var t="",r=0;this.length>r;r++){var i=this[r].write();t+=e.writeHeader(this[r].tag,i.length),t+=i}return t},this.push=function(t){t.packets=new s,this[this.length]=t,this.length++}}},{"../enums.js":26,"./all_packets.js":32,"./packet.js":38}],40:[function(t,r){var e=t("../util"),i=t("../type/mpi.js"),n=t("../enums.js"),s=t("../crypto");r.exports=function(){this.created=new Date,this.mpi=[],this.algorithm="rsa_sign",this.readPublicKey=this.read=function(t){var r=t[0].charCodeAt();if(4==r){this.created=e.readDate(t.substr(1,4)),this.algorithm=n.read(n.publicKey,t[5].charCodeAt());var o=s.getPublicMpiCount(this.algorithm);this.mpi=[];for(var a=t.substr(6),h=0,c=0;o>c&&a.length>h;c++)this.mpi[c]=new i,h+=this.mpi[c].read(a.substr(h)),h>a.length&&e.print_error("openpgp.packet.keymaterial.js\nerror reading MPI @:"+h);return h+6}throw Error("Version "+r+" of the key packet is unsupported.")},this.writePublicKey=this.write=function(){var t=String.fromCharCode(4);t+=e.writeDate(this.created),t+=String.fromCharCode(n.write(n.publicKey,this.algorithm));for(var r=s.getPublicMpiCount(this.algorithm),i=0;r>i;i++)t+=this.mpi[i].write();return t},this.writeOld=function(){var t=this.writePublicKey();return String.fromCharCode(153)+e.writeNumber(t.length,2)+t},this.getKeyId=function(){return this.getFingerprint().substr(12,8)},this.getFingerprint=function(){var t=this.writeOld();return s.hash.sha1(t,t.length)}}},{"../crypto":15,"../enums.js":26,"../type/mpi.js":53,"../util":55}],41:[function(t,r){var e=t("../type/keyid.js"),i=t("../util"),n=t("../type/mpi.js"),s=t("../enums.js"),o=t("../crypto");r.exports=function(){this.version=3,this.publicKeyId=new e,this.publicKeyAlgorithm="rsa_encrypt",this.sessionKey=null,this.sessionKeyAlgorithm="aes256",this.encrypted=[],this.read=function(t){this.version=t[0].charCodeAt(),this.publicKeyId.read(t.substr(1)),this.publicKeyAlgorithm=s.read(s.publicKey,t[9].charCodeAt());var r=10,e=function(t){switch(t){case"rsa_encrypt":case"rsa_encrypt_sign":return 1;case"elgamal":return 2;default:throw Error("Invalid algorithm.")}}(this.publicKeyAlgorithm);this.encrypted=[];for(var i=0;e>i;i++){var o=new n;r+=o.read(t.substr(r)),this.encrypted.push(o)}},this.write=function(){var t=String.fromCharCode(this.version);t+=this.publicKeyId.write(),t+=String.fromCharCode(s.write(s.publicKey,this.publicKeyAlgorithm));for(var r=0;this.encrypted.length>r;r++)t+=this.encrypted[r].write();return t},this.encrypt=function(t){var r=String.fromCharCode(s.write(s.symmetric,this.sessionKeyAlgorithm));r+=this.sessionKey;var e=i.calc_checksum(this.sessionKey);r+=i.writeNumber(e,2);var a=new n;a.fromBytes(o.pkcs1.eme.encode(r,t.mpi[0].byteLength())),this.encrypted=o.publicKeyEncrypt(this.publicKeyAlgorithm,t.mpi,a)},this.decrypt=function(t){var r=o.publicKeyDecrypt(this.publicKeyAlgorithm,t.mpi,this.encrypted).toBytes(),e=i.readNumber(r.substr(r.length-2)),n=o.pkcs1.eme.decode(r,t.mpi[0].byteLength()),t=n.substring(1,n.length-2);if(e!=i.calc_checksum(t))throw Error("Checksum mismatch");this.sessionKey=t,this.sessionKeyAlgorithm=s.read(s.symmetric,n.charCodeAt(0))}}},{"../crypto":15,"../enums.js":26,"../type/keyid.js":52,"../type/mpi.js":53,"../util":55}],42:[function(t,r){var e=t("./public_key.js");r.exports=function(){e.call(this)}},{"./public_key.js":40}],43:[function(t,r){function e(){function t(t){return"sha1"==t?20:2}function r(t){return"sha1"==t?o.hash.sha1:function(t){return s.writeNumber(s.calc_checksum(t),2)}}function e(e,i,n){var s=t(e),h=r(e),c=i.substr(i.length-s);i=i.substr(0,i.length-s);var u=h(i);if(u!=c)throw Error("Hash mismatch.");for(var p=o.getPrivateMpiCount(n),l=0,f=[],d=0;p>d&&i.length>l;d++)f[d]=new a,l+=f[d].read(i.substr(l));return f}function c(t,e,i){for(var n="",s=o.getPublicMpiCount(e),a=s;i.length>a;a++)n+=i[a].write();return n+=r(t)(n)}function u(t,r,e){return t.produce_key(r,o.cipher[e].keySize)}i.call(this),this.encrypted=null,this.read=function(t){var r=this.readPublicKey(t);t=t.substr(r);var i=t[0].charCodeAt();i?this.encrypted=t:this.mpi=this.mpi.concat(e("mod",t.substr(1),this.algorithm))},this.write=function(){var t=this.writePublicKey();return this.encrypted?t+=this.encrypted:(t+=String.fromCharCode(0),t+=c("mod",this.algorithm,this.mpi)),t},this.encrypt=function(t){var r=new h,e="aes256",i=c("sha1",this.algorithm,this.mpi),s=u(r,t,e),a=o.cipher[e].blockSize,p=o.random.getRandomBytes(a);this.encrypted="",this.encrypted+=String.fromCharCode(254),this.encrypted+=String.fromCharCode(n.write(n.symmetric,e)),this.encrypted+=r.write(),this.encrypted+=p,this.encrypted+=o.cfb.normalEncrypt(e,s,i,p)},this.decrypt=function(t){if(this.encrypted){var r,i,s=0,a=this.encrypted[s++].charCodeAt();if(255==a||254==a){r=this.encrypted[s++].charCodeAt(),r=n.read(n.symmetric,r);var c=new h;s+=c.read(this.encrypted.substr(s)),i=u(c,t,r)}else r=a,r=n.read(n.symmetric,r),i=o.hash.md5(t);var p=this.encrypted.substr(s,o.cipher[r].blockSize);s+=p.length;var l,f=this.encrypted.substr(s);l=o.cfb.normalDecrypt(r,i,f,p);var d=254==a?"sha1":"mod";this.mpi=this.mpi.concat(e(d,l,this.algorithm))}},this.generate=function(){this.mpi}}var i=t("./public_key.js"),n=t("../enums.js"),s=t("../util"),o=t("../crypto"),a=t("../type/mpi.js"),h=t("../type/s2k.js");e.prototype=new i,r.exports=e},{"../crypto":15,"../enums.js":26,"../type/mpi.js":53,"../type/s2k.js":54,"../util":55,"./public_key.js":40}],44:[function(t,r){var e=t("./secret_key.js");r.exports=function(){e.call(this)}},{"./secret_key.js":43}],45:[function(t,r){var e=t("../util"),i=t("./packet.js"),n=t("../enums.js"),s=t("../crypto"),o=t("../type/mpi.js");r.exports=function a(){this.signatureType=null,this.hashAlgorithm=null,this.publicKeyAlgorithm=null,this.signatureData=null,this.signedHashValue=null,this.mpi=null,this.created=null,this.signatureExpirationTime=null,this.signatureNeverExpires=null,this.exportable=null,this.trustLevel=null,this.trustAmount=null,this.regularExpression=null,this.revocable=null,this.keyExpirationTime=null,this.keyNeverExpires=null,this.preferredSymmetricAlgorithms=null,this.revocationKeyClass=null,this.revocationKeyAlgorithm=null,this.revocationKeyFingerprint=null,this.issuerKeyId=null,this.notation={},this.preferredHashAlgorithms=null,this.preferredCompressionAlgorithms=null,this.keyServerPreferences=null,this.preferredKeyServer=null,this.isPrimaryUserID=null,this.policyURI=null,this.keyFlags=null,this.signersUserId=null,this.reasonForRevocationFlag=null,this.reasonForRevocationString=null,this.signatureTargetPublicKeyAlgorithm=null,this.signatureTargetHashAlgorithm=null,this.signatureTargetHash=null,this.embeddedSignature=null,this.verified=!1,this.read=function(t){function r(t,r){for(var n=e.readNumber(t.substr(0,2)),s=2;2+n>s;){var o=i.readSimpleLength(t.substr(s));s+=o.offset,r&&this.read_sub_packet(t.substr(s,o.len)),s+=o.len}return s}var n=0,s=t[n++].charCodeAt();switch(s){case 3:5!=t[n++].charCodeAt()&&e.print_debug("openpgp.packet.signature.js\ninvalid One-octet length of following hashed material.MUST be 5. @:"+(n-1)),this.signatureType=t[n++].charCodeAt(),this.created=e.readDate(t.substr(n,4)),n+=4,this.signatureData=t.substring(position,n),this.issuerKeyId=t.substring(n,n+8),n+=8,this.publicKeyAlgorithm=t[n++].charCodeAt(),this.hashAlgorithm=t[n++].charCodeAt();break;case 4:this.signatureType=t[n++].charCodeAt(),this.publicKeyAlgorithm=t[n++].charCodeAt(),this.hashAlgorithm=t[n++].charCodeAt(),n+=r.call(this,t.substr(n),!0),this.signatureData=t.substr(0,n),n+=r.call(this,t.substr(n),!1);break;default:throw Error("Version "+s+" of the signature is unsupported.")}this.signedHashValue=t.substr(n,2),n+=2,this.signature=t.substr(n)},this.write=function(){return this.signatureData+e.writeNumber(0,2)+this.signedHashValue+this.signature},this.sign=function(t,r){var i=n.write(n.signature,this.signatureType),o=n.write(n.publicKey,this.publicKeyAlgorithm),a=n.write(n.hash,this.hashAlgorithm),h=String.fromCharCode(4);h+=String.fromCharCode(i),h+=String.fromCharCode(o),h+=String.fromCharCode(a),h+=e.writeNumber(0,2),this.signatureData=h;var c=this.calculateTrailer(),u=this.toSign(i,r)+this.signatureData+c,p=s.hash.digest(a,u);this.signedHashValue=p.substr(0,2),this.signature=s.signature.sign(a,o,t.mpi,u)},this.read_sub_packet=function(t){function r(t,r){this[t]=[];for(var e=0;r.length>e;e++)this[t].push(r[e].charCodeAt())}var i=0,n=127&t[i++].charCodeAt();switch(n){case 2:this.created=e.readDate(t.substr(i));break;case 3:var o=e.readDate(t.substr(i));this.signatureNeverExpires=0==o.getTime(),this.signatureExpirationTime=o;break;case 4:this.exportable=1==t[i++].charCodeAt();break;case 5:this.trustLevel=t[i++].charCodeAt(),this.trustAmount=t[i++].charCodeAt();break;case 6:this.regularExpression=t.substr(i);break;case 7:this.revocable=1==t[i++].charCodeAt();break;case 9:var o=e.readDate(t.substr(i));this.keyExpirationTime=o,this.keyNeverExpires=0==o.getTime();break;case 11:for(this.preferredSymmetricAlgorithms=[];i!=t.length;)this.preferredSymmetricAlgorithms.push(t[i++].charCodeAt());break;case 12:this.revocationKeyClass=t[i++].charCodeAt(),this.revocationKeyAlgorithm=t[i++].charCodeAt(),this.revocationKeyFingerprint=t.substr(i,20);break;case 16:this.issuerKeyId=t.substr(i,8);break;case 20:if(128!=t[i].charCodeAt())throw Error("Unsupported notation flag.");i+=4;var h=e.writeNumber(t.substr(i,2));i+=2;var c=e.writeNumber(t.substr(i,2));i+=2;var u=t.substr(i,h),p=t.substr(i+h,c);this.notation[u]=p;break;case 21:r.call(this,"preferredHashAlgorithms",t.substr(i));break;case 22:r.call(this,"preferredCompressionAlgorithms ",t.substr(i));break;case 23:r.call(this,"keyServerPreferencess",t.substr(i));break;case 24:this.preferredKeyServer=t.substr(i);break;case 25:this.isPrimaryUserID=0!=t[i++];break;case 26:this.policyURI=t.substr(i);break;case 27:r.call(this,"keyFlags",t.substr(i));break;case 28:this.signersUserId+=t.substr(i);break;case 29:this.reasonForRevocationFlag=t[i++].charCodeAt(),this.reasonForRevocationString=t.substr(i);break;case 30:r.call(this,"features",t.substr(i));break;case 31:this.signatureTargetPublicKeyAlgorithm=t[i++].charCodeAt(),this.signatureTargetHashAlgorithm=t[i++].charCodeAt();var l=s.getHashByteLength(this.signatureTargetHashAlgorithm);this.signatureTargetHash=t.substr(i,l);break;case 32:this.embeddedSignature=new a,this.embeddedSignature.read(t.substr(i));break;default:e.print_error("openpgp.packet.signature.js\nunknown signature subpacket type "+n+" @:"+i+" subplen:"+subplen+" len:"+l)}},this.toSign=function(t,r){var i=n.signature;switch(t){case i.binary:return r.getBytes();case i.text:return this.toSign(i.binary,r).replace(/\r\n/g,"\n").replace(/\n/g,"\r\n");case i.standalone:return"";case i.cert_generic:case i.cert_persona:case i.cert_casual:case i.cert_positive:case i.cert_revocation:var s,o;if(void 0!=r.userid)o=180,s=r.userid;else{if(void 0==r.userattribute)throw Error("Either a userid or userattribute packet needs to be supplied for certification.");o=209,s=r.userattribute}var a=s.write();return this.toSign(i.key,r)+String.fromCharCode(o)+e.writeNumber(a.length,4)+a;case i.subkey_binding:case i.key_binding:return this.toSign(i.key,r)+this.toSign(i.key,{key:r.bind});case i.key:if(void 0==r.key)throw Error("Key packet is required for this sigtature.");return r.key.writeOld();case i.key_revocation:case i.subkey_revocation:return this.toSign(i.key,r);case i.timestamp:return"";case i.thrid_party:throw Error("Not implemented");default:throw Error("Unknown signature type.")}},this.calculateTrailer=function(){var t="";return t+=String.fromCharCode(4),t+=String.fromCharCode(255),t+=e.writeNumber(this.signatureData.length,4)},this.verify=function(t,r){var e=n.write(n.signature,this.signatureType),i=n.write(n.publicKey,this.publicKeyAlgorithm),a=n.write(n.hash,this.hashAlgorithm),h=this.toSign(e,r),c=this.calculateTrailer(),u=0;i>0&&4>i?u=1:17==i&&(u=2);for(var p=[],l=0,f=0;u>f;f++)p[f]=new o,l+=p[f].read(this.signature.substr(l));return this.verified=s.signature.verify(i,a,p,t.mpi,h+this.signatureData+c),this.verified}}},{"../crypto":15,"../enums.js":26,"../type/mpi.js":53,"../util":55,"./packet.js":38}],46:[function(t,r){var e=(t("../util"),t("../crypto"));r.exports=function(){this.encrypted=null,this.modification=!1,this.packets,this.read=function(t){var r=t[0].charCodeAt();if(1!=r)throw Error("Invalid packet version.");this.encrypted=t.substr(1)},this.write=function(){return String.fromCharCode(1)+this.encrypted},this.encrypt=function(t,r){var i=this.packets.write(),n=e.getPrefixRandom(t),s=n+n.charAt(n.length-2)+n.charAt(n.length-1),o=i;o+=String.fromCharCode(211),o+=String.fromCharCode(20),o+=e.hash.sha1(s+o),this.encrypted=e.cfb.encrypt(n,t,o,r,!1).substring(0,s.length+o.length)},this.decrypt=function(t,r){var i=e.cfb.decrypt(t,r,this.encrypted,!1);this.hash=e.hash.sha1(e.cfb.mdc(t,r,this.encrypted)+i.substring(0,i.length-20));var n=i.substr(i.length-20,20);if(this.hash!=n)throw Error("Modification detected.");this.packets.read(i.substr(0,i.length-22))}}},{"../crypto":15,"../util":55}],47:[function(t,r){var e=t("../type/s2k.js"),i=t("../enums.js"),n=t("../crypto");r.exports=function(){this.tag=3,this.sessionKeyEncryptionAlgorithm=null,this.sessionKeyAlgorithm="aes256",this.encrypted=null,this.s2k=new e,this.read=function(t){this.version=t[0].charCodeAt();var r=i.read(i.symmetric,t[1].charCodeAt()),e=this.s2k.read(t.substr(2)),n=e+2;t.length>n?(this.encrypted=t.substr(n),this.sessionKeyEncryptionAlgorithm=r):this.sessionKeyAlgorithm=r},this.write=function(){var t=null==this.encrypted?this.sessionKeyAlgorithm:this.sessionKeyEncryptionAlgorithm,r=String.fromCharCode(this.version)+String.fromCharCode(i.write(i.symmetric,t))+this.s2k.write();return null!=this.encrypted&&(r+=this.encrypted),r},this.decrypt=function(t){var r=null!=this.sessionKeyEncryptionAlgorithm?this.sessionKeyEncryptionAlgorithm:this.sessionKeyAlgorithm,e=n.cipher[r].keySize,s=this.s2k.produce_key(t,e);if(null==this.encrypted)this.sessionKey=s;else{var o=n.cfb.decrypt(this.sessionKeyEncryptionAlgorithm,s,this.encrypted,!0);this.sessionKeyAlgorithm=i.read(i.symmetric,o[0].keyCodeAt()),this.sessionKey=o.substr(1)}},this.encrypt=function(t){var r=n.getKeyLength(this.sessionKeyEncryptionAlgorithm),e=this.s2k.produce_key(t,r),s=String.fromCharCode(i.write(i.symmetric,this.sessionKeyAlgorithm))+n.getRandomBytes(n.getKeyLength(this.sessionKeyAlgorithm));this.encrypted=n.cfb.encrypt(n.getPrefixRandom(this.sessionKeyEncryptionAlgorithm),this.sessionKeyEncryptionAlgorithm,e,s,!0)}}},{"../crypto":15,"../enums.js":26,"../type/s2k.js":54}],48:[function(t,r){var e=t("../crypto");r.exports=function(){this.encrypted=null,this.packets,this.read=function(t){this.encrypted=t},this.write=function(){return this.encrypted},this.decrypt=function(t,r){var i=e.cfb.decrypt(t,r,this.encrypted,!0);this.packets.read(i)},this.encrypt=function(t,r){var i=this.packets.write();this.encrypted=e.cfb.encrypt(e.getPrefixRandom(t),t,i,r,!0)}}},{"../crypto":15}],49:[function(t,r){r.exports=function(){}},{}],50:[function(t,r){r.exports=function(){this.tag=17,this.attributes=[],this.read=function(t){for(var r=0;t.length>r;){var e=openpgp_packet.read_simple_length(t);r+=e.offset,this.attributes.push(t.substr(r,e.len)),r+=e.len}}}},{}],51:[function(t,r){var e=t("../util");r.exports=function(){this.userid="",this.read=function(t){this.userid=e.decode_utf8(t)},this.write=function(){return e.encode_utf8(this.userid)}}},{"../util":55}],52:[function(t,r){r.exports=function(){for(var t="",r=0;8>r;r++)t+=String.fromCharCode(0);this.read=function(t){this.bytes=t.substr(0,8)},this.write=function(){return this.bytes}}},{}],53:[function(t,r){var e=t("../crypto/public_key/jsbn.js"),i=t("../util");r.exports=function(){this.data=null,this.read=function(t){var r=t[0].charCodeAt()<<8|t[1].charCodeAt(),e=Math.ceil(r/8),i=t.substr(2,e);return this.fromBytes(i),2+e},this.fromBytes=function(t){this.data=new e(i.hexstrdump(t),16)},this.toBytes=function(){return this.write().substr(2)},this.byteLength=function(){return this.toBytes().length},this.write=function(){return this.data.toMPI()},this.toBigInteger=function(){return this.data.clone()},this.fromBigInteger=function(t){this.data=t.clone()}}},{"../crypto/public_key/jsbn.js":20,"../util":55}],54:[function(t,r){var e=t("../enums.js"),i=t("../util"),n=t("../crypto");r.exports=function(){this.algorithm="sha256",this.type="iterated",this.c=96,this.salt=n.random.getRandomBytes(8);var t=6;this.get_count=function(){return 16+(15&this.c)<<(this.c>>4)+t},this.read=function(t){var r=0;switch(this.type=e.read(e.s2k,t[r++].charCodeAt()),this.algorithm=e.read(e.hash,t[r++].charCodeAt()),this.type){case"simple":break;case"salted":this.salt=t.substr(r,8),r+=8;break;case"iterated":this.salt=t.substr(r,8),r+=8,this.c=t[r++].charCodeAt();break;case"gnu":if("GNU"!=t.substr(r,3))throw Error("Unknown s2k type.");r+=3;var i=1e3+t[r++].charCodeAt();if(1001!=i)throw Error("Unknown s2k gnu protection mode.");this.type=i;break;default:throw Error("Unknown s2k type.")}return r},this.write=function(){var t=String.fromCharCode(e.write(e.s2k,this.type));switch(t+=String.fromCharCode(e.write(e.hash,this.algorithm)),this.type){case"simple":break;case"salted":t+=this.salt;break;case"iterated":t+=this.salt,t+=String.fromCharCode(this.c)}return t},this.produce_key=function(t,r){function s(r,i){var s=e.write(e.hash,i.algorithm);switch(i.type){case"simple":return n.hash.digest(s,r+t);case"salted":return n.hash.digest(s,r+i.salt+t);case"iterated":var o=[],a=i.get_count();for(data=i.salt+t;a>o.length*data.length;)o.push(data);return o=o.join(""),o.length>a&&(o=o.substr(0,a)),n.hash.digest(s,r+o)}}t=i.encode_utf8(t);for(var o="",a="";r>=o.length;)o+=s(a,this),a+=String.fromCharCode(0);return o.substr(0,r)}}},{"../crypto":15,"../enums.js":26,"../util":55}],55:[function(t,r){var e=function(){this.readNumber=function(t){for(var r=0,e=0;t.length>e;e++)r<<=8,r+=t[e].charCodeAt();return r},this.writeNumber=function(t,r){for(var e="",i=0;r>i;i++)e+=String.fromCharCode(255&t>>8*(r-i-1));return e},this.readDate=function(t){var r=this.readNumber(t),e=new Date;return e.setTime(1e3*r),e},this.writeDate=function(t){var r=Math.round(t.getTime()/1e3);return this.writeNumber(r,4)},this.emailRegEx=/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/,this.debug=!1,this.hexdump=function(t){for(var r,e=[],i=t.length,n=0,s=0;i>n;){for(r=t.charCodeAt(n++).toString(16);2>r.length;)r="0"+r;e.push(" "+r),s++,0==s%32&&e.push("\n ")}return e.join("") -},this.hexstrdump=function(t){if(null==t)return"";for(var r,e=[],i=t.length,n=0;i>n;){for(r=t[n++].charCodeAt().toString(16);2>r.length;)r="0"+r;e.push(""+r)}return e.join("")},this.hex2bin=function(t){for(var r="",e=0;t.length>e;e+=2)r+=String.fromCharCode(parseInt(t.substr(e,2),16));return r},this.hexidump=function(t){for(var r,e=[],i=t.length,n=0;i>n;){for(r=t[n++].toString(16);2>r.length;)r="0"+r;e.push(""+r)}return e.join("")},this.encode_utf8=function(t){return unescape(encodeURIComponent(t))},this.decode_utf8=function(t){return decodeURIComponent(escape(t))};var t=function(t,r){for(var e=0;t.length>e;e++)r[e]=t.charCodeAt(e);return r},r=function(t){for(var r=[],e=0;t.length>e;e++)r.push(String.fromCharCode(t[e]));return r.join("")};this.str2bin=function(r){return t(r,Array(r.length))},this.bin2str=r,this.str2Uint8Array=function(r){return t(r,new Uint8Array(new ArrayBuffer(r.length)))},this.Uint8Array2str=r,this.calc_checksum=function(t){for(var r={s:0,add:function(t){this.s=(this.s+t)%65536}},e=0;t.length>e;e++)r.add(t.charCodeAt(e));return r.s},this.print_debug=function(t){this.debug&&console.log(t)},this.print_debug_hexstr_dump=function(t,r){this.debug&&(t+=this.hexstrdump(r),console.log(t))},this.print_error=function(t){if(this.debug)throw t;console.log(t)},this.print_info=function(t){this.debug&&console.log(t)},this.print_warning=function(t){console.log(t)},this.getLeftNBits=function(t,r){var e=r%8;if(0==e)return t.substring(0,r/8);var i=(r-e)/8+1,n=t.substring(0,i);return this.shiftRight(n,8-e)},this.shiftRight=function(t,r){var e=util.str2bin(t);if(0==r%8)return t;for(var i=e.length-1;i>=0;i--)e[i]>>=r%8,i>0&&(e[i]|=255&e[i-1]<<8-r%8);return util.bin2str(e)},this.get_hashAlgorithmString=function(t){switch(t){case 1:return"MD5";case 2:return"SHA1";case 3:return"RIPEMD160";case 8:return"SHA256";case 9:return"SHA384";case 10:return"SHA512";case 11:return"SHA224"}return"unknown"}};r.exports=new e},{}]},{},[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55]); \ No newline at end of file +for(g=3==P?e?[0,32,2]:[30,-2,-2]:e?[0,32,2,62,30,-2,64,96,2]:[94,62,-2,32,64,2,30,-2,-2],e&&(r=s(r,a),B=r.length),result="",tempresult="",1==i&&(m=n.charCodeAt(I++)<<24|n.charCodeAt(I++)<<16|n.charCodeAt(I++)<<8|n.charCodeAt(I++),b=n.charCodeAt(I++)<<24|n.charCodeAt(I++)<<16|n.charCodeAt(I++)<<8|n.charCodeAt(I++),I=0);B>I;){for(f=r.charCodeAt(I++)<<24|r.charCodeAt(I++)<<16|r.charCodeAt(I++)<<8|r.charCodeAt(I++),d=r.charCodeAt(I++)<<24|r.charCodeAt(I++)<<16|r.charCodeAt(I++)<<8|r.charCodeAt(I++),1==i&&(e?(f^=m,d^=b):(y=m,v=b,m=f,b=d)),u=252645135&(f>>>4^d),d^=u,f^=u<<4,u=65535&(f>>>16^d),d^=u,f^=u<<16,u=858993459&(d>>>2^f),f^=u,d^=u<<2,u=16711935&(d>>>8^f),f^=u,d^=u<<8,u=1431655765&(f>>>1^d),d^=u,f^=u<<1,f=f<<1|f>>>31,d=d<<1|d>>>31,c=0;P>c;c+=3){for(w=g[c+1],k=g[c+2],h=g[c];h!=w;h+=k)p=d^t[h],l=(d>>>4|d<<28)^t[h+1],u=f,f=d,d=u^(A[63&p>>>24]|S[63&p>>>16]|T[63&p>>>8]|E[63&p]|C[63&l>>>24]|_[63&l>>>16]|j[63&l>>>8]|O[63&l]);u=f,f=d,d=u}f=f>>>1|f<<31,d=d>>>1|d<<31,u=1431655765&(f>>>1^d),d^=u,f^=u<<1,u=16711935&(d>>>8^f),f^=u,d^=u<<8,u=858993459&(d>>>2^f),f^=u,d^=u<<2,u=65535&(f>>>16^d),d^=u,f^=u<<16,u=252645135&(f>>>4^d),d^=u,f^=u<<4,1==i&&(e?(m=f,b=d):(f^=y,d^=v)),tempresult+=String.fromCharCode(f>>>24,255&f>>>16,255&f>>>8,255&f,d>>>24,255&d>>>16,255&d>>>8,255&d),x+=8,512==x&&(result+=tempresult,tempresult="",x=0)}return result+=tempresult,e||(result=o(result,a)),result}function n(t){pc2bytes0=[0,4,536870912,536870916,65536,65540,536936448,536936452,512,516,536871424,536871428,66048,66052,536936960,536936964],pc2bytes1=[0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697],pc2bytes2=[0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272],pc2bytes3=[0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952,139264,2236416,134356992,136454144],pc2bytes4=[0,262144,16,262160,0,262144,16,262160,4096,266240,4112,266256,4096,266240,4112,266256],pc2bytes5=[0,1024,32,1056,0,1024,32,1056,33554432,33555456,33554464,33555488,33554432,33555456,33554464,33555488],pc2bytes6=[0,268435456,524288,268959744,2,268435458,524290,268959746,0,268435456,524288,268959744,2,268435458,524290,268959746],pc2bytes7=[0,65536,2048,67584,536870912,536936448,536872960,536938496,131072,196608,133120,198656,537001984,537067520,537004032,537069568],pc2bytes8=[0,262144,0,262144,2,262146,2,262146,33554432,33816576,33554432,33816576,33554434,33816578,33554434,33816578],pc2bytes9=[0,268435456,8,268435464,0,268435456,8,268435464,1024,268436480,1032,268436488,1024,268436480,1032,268436488],pc2bytes10=[0,32,0,32,1048576,1048608,1048576,1048608,8192,8224,8192,8224,1056768,1056800,1056768,1056800],pc2bytes11=[0,16777216,512,16777728,2097152,18874368,2097664,18874880,67108864,83886080,67109376,83886592,69206016,85983232,69206528,85983744],pc2bytes12=[0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128],pc2bytes13=[0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261];for(var r,e,n,s=t.length>8?3:1,o=Array(32*s),a=[0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0],h=0,c=0,u=0;s>u;u++)for(left=t.charCodeAt(h++)<<24|t.charCodeAt(h++)<<16|t.charCodeAt(h++)<<8|t.charCodeAt(h++),right=t.charCodeAt(h++)<<24|t.charCodeAt(h++)<<16|t.charCodeAt(h++)<<8|t.charCodeAt(h++),n=252645135&(left>>>4^right),right^=n,left^=n<<4,n=65535&(right>>>-16^left),left^=n,right^=n<<-16,n=858993459&(left>>>2^right),right^=n,left^=n<<2,n=65535&(right>>>-16^left),left^=n,right^=n<<-16,n=1431655765&(left>>>1^right),right^=n,left^=n<<1,n=16711935&(right>>>8^left),left^=n,right^=n<<8,n=1431655765&(left>>>1^right),right^=n,left^=n<<1,n=left<<8|240&right>>>20,left=right<<24|16711680&right<<8|65280&right>>>8|240&right>>>24,right=n,i=0;a.length>i;i++)a[i]?(left=left<<2|left>>>26,right=right<<2|right>>>26):(left=left<<1|left>>>27,right=right<<1|right>>>27),left&=-15,right&=-15,r=pc2bytes0[left>>>28]|pc2bytes1[15&left>>>24]|pc2bytes2[15&left>>>20]|pc2bytes3[15&left>>>16]|pc2bytes4[15&left>>>12]|pc2bytes5[15&left>>>8]|pc2bytes6[15&left>>>4],e=pc2bytes7[right>>>28]|pc2bytes8[15&right>>>24]|pc2bytes9[15&right>>>20]|pc2bytes10[15&right>>>16]|pc2bytes11[15&right>>>12]|pc2bytes12[15&right>>>8]|pc2bytes13[15&right>>>4],n=65535&(e>>>16^r),o[c++]=r^n,o[c++]=e^n<<16;return o}function s(t,r){var e=8-t.length%8;return 2==r&&8>e?t+=" ".substr(0,e):1==r?t+=String.fromCharCode(e,e,e,e,e,e,e,e).substr(0,e):!r&&8>e&&(t+="\0\0\0\0\0\0\0\0".substr(0,e)),t}function o(t,r){if(2==r)t=t.replace(/ *$/g,"");else if(1==r){var e=t.charCodeAt(t.length-1);t=t.substr(0,t.length-e)}else r||(t=t.replace(/\0*$/g,""));return t}function a(t){this.key=[];for(var r=0;3>r;r++)this.key.push(t.substr(8*r,8));this.encrypt=function(t){return c.str2bin(e(n(this.key[2]),e(n(this.key[1]),e(n(this.key[0]),c.bin2str(t),!0,0,null,null),!1,0,null,null),!0,0,null,null))}}function h(t){this.key=t,this.encrypt=function(t,r){var i=n(this.key);return c.str2bin(e(i,c.bin2str(t),!0,0,null,r))},this.decrypt=function(t,r){var i=n(this.key);return c.str2bin(e(i,c.bin2str(t),!1,0,null,r))}}var c=t("../../util");a.keySize=a.prototype.keySize=24,a.blockSize=a.prototype.blockSize=8,r.exports={des:a,originalDes:h}},{"../../util":55}],8:[function(t,r){var e=t("./des.js");r.exports={des:e.des,originalDes:e.originalDes,cast5:t("./cast5.js"),twofish:t("./twofish.js"),blowfish:t("./blowfish.js")};var i=t("./aes.js");for(var n in i)r.exports["aes"+n]=i[n]},{"./aes.js":4,"./blowfish.js":5,"./cast5.js":6,"./des.js":7,"./twofish.js":9}],9:[function(t,r){function e(t,r){return(t<>>32-r)&h}function i(t,r){return t[r]|t[r+1]<<8|t[r+2]<<16|t[r+3]<<24}function n(t,r,e){t.splice(r,4,255&e,255&e>>>8,255&e>>>16,255&e>>>24)}function s(t,r){return 255&t>>>8*r}function o(){function t(t){function r(t){return t^t>>2^[0,90,180,238][3&t]}function n(t){return t^t>>1^t>>2^[0,238,180,90][3&t]}function o(t,r){var e,i,n;for(e=0;8>e;e++)i=r>>>24,r=r<<8&h|t>>>24,t=t<<8&h,n=i<<1,128&i&&(n^=333),r^=i^n<<16,n^=i>>>1,1&i&&(n^=166),r^=n<<24|n<<8;return r}function a(t,r){var e,i,n,s;return e=r>>4,i=15&r,n=j[t][e^i],s=T[t][I[i]^B[e]],E[t][I[s]^B[n]]<<4|O[t][n^s]}function c(t,r){var e=s(t,0),i=s(t,1),n=s(t,2),o=s(t,3);switch(m){case 4:e=x[1][e]^s(r[3],0),i=x[0][i]^s(r[3],1),n=x[0][n]^s(r[3],2),o=x[1][o]^s(r[3],3);case 3:e=x[1][e]^s(r[2],0),i=x[1][i]^s(r[2],1),n=x[0][n]^s(r[2],2),o=x[0][o]^s(r[2],3);case 2:e=x[0][x[0][e]^s(r[1],0)]^s(r[0],0),i=x[0][x[1][i]^s(r[1],1)]^s(r[0],1),n=x[1][x[0][n]^s(r[1],2)]^s(r[0],2),o=x[1][x[1][o]^s(r[1],3)]^s(r[0],3)}return P[0][e]^P[1][i]^P[2][n]^P[3][o]}d=t;var u,p,l,f,g,m,y,w,k,C=[],A=[],_=[],S=[],j=[[8,1,7,13,6,15,3,2,0,11,5,9,14,12,10,4],[2,8,11,13,15,7,6,14,3,1,9,4,0,10,12,5]],T=[[14,12,11,8,1,2,3,5,15,4,10,6,7,0,9,13],[1,14,2,11,4,12,3,7,6,13,10,5,15,9,0,8]],O=[[11,10,5,14,6,13,9,0,12,8,15,3,2,4,7,1],[4,12,7,5,1,6,9,10,0,14,13,8,2,11,3,15]],E=[[13,7,15,4,1,2,6,14,9,11,3,0,8,5,12,10],[11,9,5,1,12,3,13,14,6,4,7,15,2,0,8,10]],I=[0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15],B=[0,9,2,11,4,13,6,15,8,1,10,3,12,5,14,7],x=[[],[]],P=[[],[],[],[]];for(d=d.slice(0,32),u=d.length;16!=u&&24!=u&&32!=u;)d[u++]=0;for(u=0;d.length>u;u+=4)_[u>>2]=i(d,u);for(u=0;256>u;u++)x[0][u]=a(0,u),x[1][u]=a(1,u);for(u=0;256>u;u++)y=x[1][u],w=r(y),k=n(y),P[0][u]=y+(w<<8)+(k<<16)+(k<<24),P[2][u]=w+(k<<8)+(y<<16)+(k<<24),y=x[0][u],w=r(y),k=n(y),P[1][u]=k+(k<<8)+(w<<16)+(y<<24),P[3][u]=w+(y<<8)+(k<<16)+(w<<24);for(m=_.length/2,u=0;m>u;u++)p=_[u+u],C[u]=p,l=_[u+u+1],A[u]=l,S[m-u-1]=o(p,l);for(u=0;40>u;u+=2)p=16843009*u,l=p+16843009,p=c(p,C),l=e(c(l,A),8),b[u]=p+l&h,b[u+1]=e(p+2*l,9);for(u=0;256>u;u++)switch(p=l=f=g=u,m){case 4:p=x[1][p]^s(S[3],0),l=x[0][l]^s(S[3],1),f=x[0][f]^s(S[3],2),g=x[1][g]^s(S[3],3);case 3:p=x[1][p]^s(S[2],0),l=x[1][l]^s(S[2],1),f=x[0][f]^s(S[2],2),g=x[0][g]^s(S[2],3);case 2:v[0][u]=P[0][x[0][x[0][p]^s(S[1],0)]^s(S[0],0)],v[1][u]=P[1][x[0][x[1][l]^s(S[1],1)]^s(S[0],1)],v[2][u]=P[2][x[1][x[0][f]^s(S[1],2)]^s(S[0],2)],v[3][u]=P[3][x[1][x[1][g]^s(S[1],3)]^s(S[0],3)]}}function r(t){return v[0][s(t,0)]^v[1][s(t,1)]^v[2][s(t,2)]^v[3][s(t,3)]}function o(t){return v[0][s(t,3)]^v[1][s(t,0)]^v[2][s(t,1)]^v[3][s(t,2)]}function a(t,i){var n=r(i[0]),s=o(i[1]);i[2]=e(i[2]^n+s+b[4*t+8]&h,31),i[3]=e(i[3],1)^n+2*s+b[4*t+9]&h,n=r(i[2]),s=o(i[3]),i[0]=e(i[0]^n+s+b[4*t+10]&h,31),i[1]=e(i[1],1)^n+2*s+b[4*t+11]&h}function c(t,i){var n=r(i[0]),s=o(i[1]);i[2]=e(i[2],1)^n+s+b[4*t+10]&h,i[3]=e(i[3]^n+2*s+b[4*t+11]&h,31),n=r(i[2]),s=o(i[3]),i[0]=e(i[0],1)^n+s+b[4*t+8]&h,i[1]=e(i[1]^n+2*s+b[4*t+9]&h,31)}function u(){b=[],v=[[],[],[],[]]}function p(t,r){g=t,m=r;for(var e=[i(g,m)^b[0],i(g,m+4)^b[1],i(g,m+8)^b[2],i(g,m+12)^b[3]],s=0;8>s;s++)a(s,e);return n(g,m,e[2]^b[4]),n(g,m+4,e[3]^b[5]),n(g,m+8,e[0]^b[6]),n(g,m+12,e[1]^b[7]),m+=16,g}function l(t,r){g=t,m=r;for(var e=[i(g,m)^b[4],i(g,m+4)^b[5],i(g,m+8)^b[6],i(g,m+12)^b[7]],s=7;s>=0;s--)c(s,e);n(g,m,e[2]^b[0]),n(g,m+4,e[3]^b[1]),n(g,m+8,e[0]^b[2]),n(g,m+12,e[1]^b[3]),m+=16}function f(){return g}var d=null,g=null,m=-1,y=null;y="twofish";var b=[],v=[[],[],[],[]];return{name:"twofish",blocksize:16,open:t,close:u,encrypt:p,decrypt:l,finalize:f}}function a(t){this.tf=o(),this.tf.open(c.str2bin(t),0),this.encrypt=function(t){return this.tf.encrypt([].concat(t),0)}}var h=4294967295,c=t("../../util");r.exports=a,r.exports.keySize=a.prototype.keySize=32,r.exports.blockSize=a.prototype.blockSize=16},{"../../util":55}],10:[function(t,r){var e=t("./random.js"),i=t("./cipher"),n=t("./public_key"),s=t("../type/mpi.js");r.exports={publicKeyEncrypt:function(t,r,e){var i=function(){switch(t){case"rsa_encrypt":case"rsa_encrypt_sign":var i=new n.rsa,s=r[0].toBigInteger(),o=r[1].toBigInteger(),a=e.toBigInteger();return[i.encrypt(a,o,s)];case"elgamal":var h=new n.elgamal,c=r[0].toBigInteger(),u=r[1].toBigInteger(),p=r[2].toBigInteger(),a=e.toBigInteger();return h.encrypt(a,u,c,p);default:return[]}}();return i.map(function(t){var r=new s;return r.fromBigInteger(t),r})},publicKeyDecrypt:function(t,r,e){var i=function(){switch(t){case"rsa_encrypt_sign":case"rsa_encrypt":var i=new n.rsa,s=r[2].toBigInteger(),o=r[3].toBigInteger(),a=r[4].toBigInteger(),h=r[5].toBigInteger(),c=e[0].toBigInteger();return i.decrypt(c,s,o,a,h);case"elgamal":var u=new n.elgamal,p=r[3].toBigInteger(),l=e[0].toBigInteger(),f=e[1].toBigInteger(),o=r[0].toBigInteger();return u.decrypt(l,f,o,p);default:return null}}(),o=new s;return o.fromBigInteger(i),o},getPrivateMpiCount:function(t){switch(t){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":return 4;case"elgamal":return 1;case"dsa":return 1;default:throw Error("Unknown algorithm")}},getPublicMpiCount:function(t){switch(t){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":return 2;case"elgamal":return 3;case"dsa":return 4;default:throw Error("Unknown algorithm.")}},generateMpi:function(t,r){var e=function(){switch(t){case"rsa_encrypt":case"rsa_encrypt_sign":case"rsa_sign":var e=new n.rsa,i=e.generate(r,"10001"),s=[];return s.push(i.n),s.push(i.ee),s.push(i.d),s.push(i.p),s.push(i.q),s.push(i.u),s;default:throw Error("Unsupported algorithm for key generation.")}}();return e.map(function(t){var r=new s;return r.fromBigInteger(t),r})},getPrefixRandom:function(t){return e.getRandomBytes(i[t].blockSize)},generateSessionKey:function(t){return e.getRandomBytes(i[t].keySize)}}},{"../type/mpi.js":53,"./cipher":8,"./public_key":19,"./random.js":22}],11:[function(t,r){var e=t("./sha.js");r.exports={md5:t("./md5.js"),sha1:e.sha1,sha256:e.sha256,sha224:e.sha224,sha384:e.sha384,sha512:e.sha512,ripemd:t("./ripe-md.js"),digest:function(t,r){switch(t){case 1:return this.md5(r);case 2:return this.sha1(r);case 3:return this.ripemd(r);case 8:return this.sha256(r);case 9:return this.sha384(r);case 10:return this.sha512(r);case 11:return this.sha224(r);default:throw Error("Invalid hash function.")}},getHashByteLength:function(t){switch(t){case 1:return 16;case 2:case 3:return 20;case 8:return 32;case 9:return 48;case 10:return 64;case 11:return 28;default:throw Error("Invalid hash algorithm.")}}}},{"./md5.js":12,"./ripe-md.js":13,"./sha.js":14}],12:[function(t,r){function e(t){var r=f(t),e=g.hex2bin(r);return e}function i(t,r){var e=t[0],i=t[1],n=t[2],c=t[3];e=s(e,i,n,c,r[0],7,-680876936),c=s(c,e,i,n,r[1],12,-389564586),n=s(n,c,e,i,r[2],17,606105819),i=s(i,n,c,e,r[3],22,-1044525330),e=s(e,i,n,c,r[4],7,-176418897),c=s(c,e,i,n,r[5],12,1200080426),n=s(n,c,e,i,r[6],17,-1473231341),i=s(i,n,c,e,r[7],22,-45705983),e=s(e,i,n,c,r[8],7,1770035416),c=s(c,e,i,n,r[9],12,-1958414417),n=s(n,c,e,i,r[10],17,-42063),i=s(i,n,c,e,r[11],22,-1990404162),e=s(e,i,n,c,r[12],7,1804603682),c=s(c,e,i,n,r[13],12,-40341101),n=s(n,c,e,i,r[14],17,-1502002290),i=s(i,n,c,e,r[15],22,1236535329),e=o(e,i,n,c,r[1],5,-165796510),c=o(c,e,i,n,r[6],9,-1069501632),n=o(n,c,e,i,r[11],14,643717713),i=o(i,n,c,e,r[0],20,-373897302),e=o(e,i,n,c,r[5],5,-701558691),c=o(c,e,i,n,r[10],9,38016083),n=o(n,c,e,i,r[15],14,-660478335),i=o(i,n,c,e,r[4],20,-405537848),e=o(e,i,n,c,r[9],5,568446438),c=o(c,e,i,n,r[14],9,-1019803690),n=o(n,c,e,i,r[3],14,-187363961),i=o(i,n,c,e,r[8],20,1163531501),e=o(e,i,n,c,r[13],5,-1444681467),c=o(c,e,i,n,r[2],9,-51403784),n=o(n,c,e,i,r[7],14,1735328473),i=o(i,n,c,e,r[12],20,-1926607734),e=a(e,i,n,c,r[5],4,-378558),c=a(c,e,i,n,r[8],11,-2022574463),n=a(n,c,e,i,r[11],16,1839030562),i=a(i,n,c,e,r[14],23,-35309556),e=a(e,i,n,c,r[1],4,-1530992060),c=a(c,e,i,n,r[4],11,1272893353),n=a(n,c,e,i,r[7],16,-155497632),i=a(i,n,c,e,r[10],23,-1094730640),e=a(e,i,n,c,r[13],4,681279174),c=a(c,e,i,n,r[0],11,-358537222),n=a(n,c,e,i,r[3],16,-722521979),i=a(i,n,c,e,r[6],23,76029189),e=a(e,i,n,c,r[9],4,-640364487),c=a(c,e,i,n,r[12],11,-421815835),n=a(n,c,e,i,r[15],16,530742520),i=a(i,n,c,e,r[2],23,-995338651),e=h(e,i,n,c,r[0],6,-198630844),c=h(c,e,i,n,r[7],10,1126891415),n=h(n,c,e,i,r[14],15,-1416354905),i=h(i,n,c,e,r[5],21,-57434055),e=h(e,i,n,c,r[12],6,1700485571),c=h(c,e,i,n,r[3],10,-1894986606),n=h(n,c,e,i,r[10],15,-1051523),i=h(i,n,c,e,r[1],21,-2054922799),e=h(e,i,n,c,r[8],6,1873313359),c=h(c,e,i,n,r[15],10,-30611744),n=h(n,c,e,i,r[6],15,-1560198380),i=h(i,n,c,e,r[13],21,1309151649),e=h(e,i,n,c,r[4],6,-145523070),c=h(c,e,i,n,r[11],10,-1120210379),n=h(n,c,e,i,r[2],15,718787259),i=h(i,n,c,e,r[9],21,-343485551),t[0]=d(e,t[0]),t[1]=d(i,t[1]),t[2]=d(n,t[2]),t[3]=d(c,t[3])}function n(t,r,e,i,n,s){return r=d(d(r,t),d(i,s)),d(r<>>32-n,e)}function s(t,r,e,i,s,o,a){return n(r&e|~r&i,t,r,s,o,a)}function o(t,r,e,i,s,o,a){return n(r&i|e&~i,t,r,s,o,a)}function a(t,r,e,i,s,o,a){return n(r^e^i,t,r,s,o,a)}function h(t,r,e,i,s,o,a){return n(e^(r|~i),t,r,s,o,a)}function c(t){txt="";var r,e=t.length,n=[1732584193,-271733879,-1732584194,271733878];for(r=64;t.length>=r;r+=64)i(n,u(t.substring(r-64,r)));t=t.substring(r-64);var s=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(r=0;t.length>r;r++)s[r>>2]|=t.charCodeAt(r)<<(r%4<<3);if(s[r>>2]|=128<<(r%4<<3),r>55)for(i(n,s),r=0;16>r;r++)s[r]=0;return s[14]=8*e,i(n,s),n}function u(t){var r,e=[];for(r=0;64>r;r+=4)e[r>>2]=t.charCodeAt(r)+(t.charCodeAt(r+1)<<8)+(t.charCodeAt(r+2)<<16)+(t.charCodeAt(r+3)<<24);return e}function p(t){for(var r="",e=0;4>e;e++)r+=m[15&t>>8*e+4]+m[15&t>>8*e];return r}function l(t){for(var r=0;t.length>r;r++)t[r]=p(t[r]);return t.join("")}function f(t){return l(c(t))}function d(t,r){return 4294967295&t+r}function d(t,r){var e=(65535&t)+(65535&r),i=(t>>16)+(r>>16)+(e>>16);return i<<16|65535&e}var g=t("../../util/util.js"),m="0123456789abcdef".split("");"5d41402abc4b2a76b9719d911017c592"!=f("hello"),r.exports=e},{"../../util/util.js":55}],13:[function(t,r){function e(t,r){return new Number(t<>>32-r)}function i(t,r,e){return new Number(t^r^e)}function n(t,r,e){return new Number(t&r|~t&e)}function s(t,r,e){return new Number((t|~r)^e)}function o(t,r,e){return new Number(t&e|r&~e)}function a(t,r,e){return new Number(t^(r|~e))}function h(t,r,h,c,u,p,l,f){switch(f){case 0:t+=i(r,h,c)+p+0;break;case 1:t+=n(r,h,c)+p+1518500249;break;case 2:t+=s(r,h,c)+p+1859775393;break;case 3:t+=o(r,h,c)+p+2400959708;break;case 4:t+=a(r,h,c)+p+2840853838;break;case 5:t+=a(r,h,c)+p+1352829926;break;case 6:t+=o(r,h,c)+p+1548603684;break;case 7:t+=s(r,h,c)+p+1836072691;break;case 8:t+=n(r,h,c)+p+2053994217;break;case 9:t+=i(r,h,c)+p+0;break;default:document.write("Bogus round number")}t=e(t,l)+u,h=e(h,10),t&=4294967295,r&=4294967295,h&=4294967295,c&=4294967295,u&=4294967295;var d=[];return d[0]=t,d[1]=r,d[2]=h,d[3]=c,d[4]=u,d[5]=p,d[6]=l,d}function c(t){t[0]=1732584193,t[1]=4023233417,t[2]=2562383102,t[3]=271733878,t[4]=3285377520}function u(t,r){blockA=[],blockB=[];for(var e,i=0;5>i;i++)blockA[i]=new Number(t[i]),blockB[i]=new Number(t[i]);for(var n=0,s=0;5>s;s++)for(var i=0;16>i;i++)e=h(blockA[(n+0)%5],blockA[(n+1)%5],blockA[(n+2)%5],blockA[(n+3)%5],blockA[(n+4)%5],r[b[s][i]],y[s][i],s),blockA[(n+0)%5]=e[0],blockA[(n+1)%5]=e[1],blockA[(n+2)%5]=e[2],blockA[(n+3)%5]=e[3],blockA[(n+4)%5]=e[4],n+=4;n=0;for(var s=5;10>s;s++)for(var i=0;16>i;i++)e=h(blockB[(n+0)%5],blockB[(n+1)%5],blockB[(n+2)%5],blockB[(n+3)%5],blockB[(n+4)%5],r[b[s][i]],y[s][i],s),blockB[(n+0)%5]=e[0],blockB[(n+1)%5]=e[1],blockB[(n+2)%5]=e[2],blockB[(n+3)%5]=e[3],blockB[(n+4)%5]=e[4],n+=4;blockB[3]+=blockA[2]+t[1],t[1]=t[2]+blockA[3]+blockB[4],t[2]=t[3]+blockA[4]+blockB[0],t[3]=t[4]+blockA[0]+blockB[1],t[4]=t[0]+blockA[1]+blockB[2],t[0]=blockB[3]}function p(t){for(var r=0;16>r;r++)t[r]=0}function l(t,r,e,i){var n=Array(16);p(n);for(var s=0,o=0;(63&e)>o;o++)n[o>>>2]^=(255&r.charCodeAt(s++))<<8*(3&o);if(n[15&e>>>2]^=1<<8*(3&e)+7,(63&e)>55){u(t,n);var n=Array(16);p(n)}n[14]=e<<3,n[15]=e>>>29|i<<3,u(t,n)}function f(t){var r=(255&t.charCodeAt(3))<<24;return r|=(255&t.charCodeAt(2))<<16,r|=(255&t.charCodeAt(1))<<8,r|=255&t.charCodeAt(0)}function d(t){var r,e,i=Array(m/32),n=Array(m/8);c(i),r=t.length;var s=Array(16);p(s);for(var o=0,e=r;e>63;e-=64){for(var a=0;16>a;a++)s[a]=f(t.substr(o,4)),o+=4;u(i,s)}l(i,t.substr(o),r,0);for(var a=0;m/8>a;a+=4)n[a]=255&i[a>>>2],n[a+1]=255&i[a>>>2]>>>8,n[a+2]=255&i[a>>>2]>>>16,n[a+3]=255&i[a>>>2]>>>24;return n}function g(t){for(var r=d(t),e="",i=0;m/8>i;i++)e+=String.fromCharCode(r[i]);return e}var m=160,y=[[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],[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]],b=[[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],[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]];r.exports=g},{}],14:[function(t,r){var e=function(){var t=8,r="",e=0,i=function(t,r){this.highOrder=t,this.lowOrder=r},n=function(r){var e,i=[],n=(1<e;e+=t)i[e>>5]|=(r.charCodeAt(e/t)&n)<<32-t-e%32;return i},s=function(t){var r,e,i=[],n=t.length;for(r=0;n>r;r+=2){if(e=parseInt(t.substr(r,2),16),isNaN(e))return"INVALID HEX STRING";i[r>>3]|=e<<24-4*(r%8)}return i},o=function(t){var r,i,n=e?"0123456789ABCDEF":"0123456789abcdef",s="",o=4*t.length;for(r=0;o>r;r+=1)i=t[r>>2]>>8*(3-r%4),s+=n.charAt(15&i>>4)+n.charAt(15&i);return s},a=function(t){var e,i,n,s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",o="",a=4*t.length;for(e=0;a>e;e+=3)for(n=(255&t[e>>2]>>8*(3-e%4))<<16|(255&t[e+1>>2]>>8*(3-(e+1)%4))<<8|255&t[e+2>>2]>>8*(3-(e+2)%4),i=0;4>i;i+=1)o+=32*t.length>=8*e+6*i?s.charAt(63&n>>6*(3-i)):r;return o},h=function(t){for(var r="",e=255,i=0;32*t.length>i;i+=8)r+=String.fromCharCode(t[i>>5]>>>24-i%32&e);return r},c=function(t,r){return t<>>32-r},u=function(t,r){return t>>>r|t<<32-r},p=function(t,r){return 32>=r?new i(t.highOrder>>>r|t.lowOrder<<32-r,t.lowOrder>>>r|t.highOrder<<32-r):new i(t.lowOrder>>>r|t.highOrder<<32-r,t.highOrder>>>r|t.lowOrder<<32-r)},l=function(t,r){return t>>>r},f=function(t,r){return 32>=r?new i(t.highOrder>>>r,t.lowOrder>>>r|t.highOrder<<32-r):new i(0,t.highOrder<<32-r)},d=function(t,r,e){return t^r^e},g=function(t,r,e){return t&r^~t&e},m=function(t,r,e){return new i(t.highOrder&r.highOrder^~t.highOrder&e.highOrder,t.lowOrder&r.lowOrder^~t.lowOrder&e.lowOrder)},y=function(t,r,e){return t&r^t&e^r&e},b=function(t,r,e){return new i(t.highOrder&r.highOrder^t.highOrder&e.highOrder^r.highOrder&e.highOrder,t.lowOrder&r.lowOrder^t.lowOrder&e.lowOrder^r.lowOrder&e.lowOrder)},v=function(t){return u(t,2)^u(t,13)^u(t,22)},w=function(t){var r=p(t,28),e=p(t,34),n=p(t,39);return new i(r.highOrder^e.highOrder^n.highOrder,r.lowOrder^e.lowOrder^n.lowOrder)},k=function(t){return u(t,6)^u(t,11)^u(t,25)},C=function(t){var r=p(t,14),e=p(t,18),n=p(t,41);return new i(r.highOrder^e.highOrder^n.highOrder,r.lowOrder^e.lowOrder^n.lowOrder)},A=function(t){return u(t,7)^u(t,18)^l(t,3)},_=function(t){var r=p(t,1),e=p(t,8),n=f(t,7);return new i(r.highOrder^e.highOrder^n.highOrder,r.lowOrder^e.lowOrder^n.lowOrder)},S=function(t){return u(t,17)^u(t,19)^l(t,10)},j=function(t){var r=p(t,19),e=p(t,61),n=f(t,6);return new i(r.highOrder^e.highOrder^n.highOrder,r.lowOrder^e.lowOrder^n.lowOrder)},T=function(t,r){var e=(65535&t)+(65535&r),i=(t>>>16)+(r>>>16)+(e>>>16);return(65535&i)<<16|65535&e},O=function(t,r,e,i){var n=(65535&t)+(65535&r)+(65535&e)+(65535&i),s=(t>>>16)+(r>>>16)+(e>>>16)+(i>>>16)+(n>>>16);return(65535&s)<<16|65535&n},E=function(t,r,e,i,n){var s=(65535&t)+(65535&r)+(65535&e)+(65535&i)+(65535&n),o=(t>>>16)+(r>>>16)+(e>>>16)+(i>>>16)+(n>>>16)+(s>>>16);return(65535&o)<<16|65535&s},I=function(t,r){var e,n,s,o;return e=(65535&t.lowOrder)+(65535&r.lowOrder),n=(t.lowOrder>>>16)+(r.lowOrder>>>16)+(e>>>16),s=(65535&n)<<16|65535&e,e=(65535&t.highOrder)+(65535&r.highOrder)+(n>>>16),n=(t.highOrder>>>16)+(r.highOrder>>>16)+(e>>>16),o=(65535&n)<<16|65535&e,new i(o,s)},B=function(t,r,e,n){var s,o,a,h;return s=(65535&t.lowOrder)+(65535&r.lowOrder)+(65535&e.lowOrder)+(65535&n.lowOrder),o=(t.lowOrder>>>16)+(r.lowOrder>>>16)+(e.lowOrder>>>16)+(n.lowOrder>>>16)+(s>>>16),a=(65535&o)<<16|65535&s,s=(65535&t.highOrder)+(65535&r.highOrder)+(65535&e.highOrder)+(65535&n.highOrder)+(o>>>16),o=(t.highOrder>>>16)+(r.highOrder>>>16)+(e.highOrder>>>16)+(n.highOrder>>>16)+(s>>>16),h=(65535&o)<<16|65535&s,new i(h,a)},x=function(t,r,e,n,s){var o,a,h,c;return o=(65535&t.lowOrder)+(65535&r.lowOrder)+(65535&e.lowOrder)+(65535&n.lowOrder)+(65535&s.lowOrder),a=(t.lowOrder>>>16)+(r.lowOrder>>>16)+(e.lowOrder>>>16)+(n.lowOrder>>>16)+(s.lowOrder>>>16)+(o>>>16),h=(65535&a)<<16|65535&o,o=(65535&t.highOrder)+(65535&r.highOrder)+(65535&e.highOrder)+(65535&n.highOrder)+(65535&s.highOrder)+(a>>>16),a=(t.highOrder>>>16)+(r.highOrder>>>16)+(e.highOrder>>>16)+(n.highOrder>>>16)+(s.highOrder>>>16)+(o>>>16),c=(65535&a)<<16|65535&o,new i(c,h)},P=function(t,r){var e,i,n,s,o,a,h,u,p,l=[],f=g,m=d,b=y,v=c,w=T,k=E,C=[1732584193,4023233417,2562383102,271733878,3285377520],A=[1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1518500249,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,1859775393,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,2400959708,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782,3395469782];for(t[r>>5]|=128<<24-r%32,t[(r+65>>9<<4)+15]=r,p=t.length,h=0;p>h;h+=16){for(e=C[0],i=C[1],n=C[2],s=C[3],o=C[4],u=0;80>u;u+=1)l[u]=16>u?t[u+h]:v(l[u-3]^l[u-8]^l[u-14]^l[u-16],1),a=20>u?k(v(e,5),f(i,n,s),o,A[u],l[u]):40>u?k(v(e,5),m(i,n,s),o,A[u],l[u]):60>u?k(v(e,5),b(i,n,s),o,A[u],l[u]):k(v(e,5),m(i,n,s),o,A[u],l[u]),o=s,s=n,n=v(i,30),i=e,e=a;C[0]=w(e,C[0]),C[1]=w(i,C[1]),C[2]=w(n,C[2]),C[3]=w(s,C[3]),C[4]=w(o,C[4])}return C},N=function(t,r,e){var n,s,o,a,h,c,u,p,l,f,d,P,N,D,K,M,R,G,H,L,z,U,q,F,V,Z,X,J,Y,W=[];for("SHA-224"===e||"SHA-256"===e?(P=64,N=(r+65>>9<<4)+15,M=16,R=1,X=Number,G=T,H=O,L=E,z=A,U=S,q=v,F=k,Z=y,V=g,J=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],d="SHA-224"===e?[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428]:[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]):("SHA-384"===e||"SHA-512"===e)&&(P=80,N=(r+128>>10<<5)+31,M=32,R=2,X=i,G=I,H=B,L=x,z=_,U=j,q=w,F=C,Z=b,V=m,J=[new X(1116352408,3609767458),new X(1899447441,602891725),new X(3049323471,3964484399),new X(3921009573,2173295548),new X(961987163,4081628472),new X(1508970993,3053834265),new X(2453635748,2937671579),new X(2870763221,3664609560),new X(3624381080,2734883394),new X(310598401,1164996542),new X(607225278,1323610764),new X(1426881987,3590304994),new X(1925078388,4068182383),new X(2162078206,991336113),new X(2614888103,633803317),new X(3248222580,3479774868),new X(3835390401,2666613458),new X(4022224774,944711139),new X(264347078,2341262773),new X(604807628,2007800933),new X(770255983,1495990901),new X(1249150122,1856431235),new X(1555081692,3175218132),new X(1996064986,2198950837),new X(2554220882,3999719339),new X(2821834349,766784016),new X(2952996808,2566594879),new X(3210313671,3203337956),new X(3336571891,1034457026),new X(3584528711,2466948901),new X(113926993,3758326383),new X(338241895,168717936),new X(666307205,1188179964),new X(773529912,1546045734),new X(1294757372,1522805485),new X(1396182291,2643833823),new X(1695183700,2343527390),new X(1986661051,1014477480),new X(2177026350,1206759142),new X(2456956037,344077627),new X(2730485921,1290863460),new X(2820302411,3158454273),new X(3259730800,3505952657),new X(3345764771,106217008),new X(3516065817,3606008344),new X(3600352804,1432725776),new X(4094571909,1467031594),new X(275423344,851169720),new X(430227734,3100823752),new X(506948616,1363258195),new X(659060556,3750685593),new X(883997877,3785050280),new X(958139571,3318307427),new X(1322822218,3812723403),new X(1537002063,2003034995),new X(1747873779,3602036899),new X(1955562222,1575990012),new X(2024104815,1125592928),new X(2227730452,2716904306),new X(2361852424,442776044),new X(2428436474,593698344),new X(2756734187,3733110249),new X(3204031479,2999351573),new X(3329325298,3815920427),new X(3391569614,3928383900),new X(3515267271,566280711),new X(3940187606,3454069534),new X(4118630271,4000239992),new X(116418474,1914138554),new X(174292421,2731055270),new X(289380356,3203993006),new X(460393269,320620315),new X(685471733,587496836),new X(852142971,1086792851),new X(1017036298,365543100),new X(1126000580,2618297676),new X(1288033470,3409855158),new X(1501505948,4234509866),new X(1607167915,987167468),new X(1816402316,1246189591)],d="SHA-384"===e?[new X(3418070365,3238371032),new X(1654270250,914150663),new X(2438529370,812702999),new X(355462360,4144912697),new X(1731405415,4290775857),new X(41048885895,1750603025),new X(3675008525,1694076839),new X(1203062813,3204075428)]:[new X(1779033703,4089235720),new X(3144134277,2227873595),new X(1013904242,4271175723),new X(2773480762,1595750129),new X(1359893119,2917565137),new X(2600822924,725511199),new X(528734635,4215389547),new X(1541459225,327033209)]),t[r>>5]|=128<<24-r%32,t[N]=r,Y=t.length,D=0;Y>D;D+=M){for(n=d[0],s=d[1],o=d[2],a=d[3],h=d[4],c=d[5],u=d[6],p=d[7],K=0;P>K;K+=1)W[K]=16>K?new X(t[K*R+D],t[K*R+D+1]):H(U(W[K-2]),W[K-7],z(W[K-15]),W[K-16]),l=L(p,F(h),V(h,c,u),J[K],W[K]),f=G(q(n),Z(n,s,o)),p=u,u=c,c=h,h=G(a,l),a=o,o=s,s=n,n=G(l,f);d[0]=G(n,d[0]),d[1]=G(s,d[1]),d[2]=G(o,d[2]),d[3]=G(a,d[3]),d[4]=G(h,d[4]),d[5]=G(c,d[5]),d[6]=G(u,d[6]),d[7]=G(p,d[7])}switch(e){case"SHA-224":return[d[0],d[1],d[2],d[3],d[4],d[5],d[6]];case"SHA-256":return d;case"SHA-384":return[d[0].highOrder,d[0].lowOrder,d[1].highOrder,d[1].lowOrder,d[2].highOrder,d[2].lowOrder,d[3].highOrder,d[3].lowOrder,d[4].highOrder,d[4].lowOrder,d[5].highOrder,d[5].lowOrder];case"SHA-512":return[d[0].highOrder,d[0].lowOrder,d[1].highOrder,d[1].lowOrder,d[2].highOrder,d[2].lowOrder,d[3].highOrder,d[3].lowOrder,d[4].highOrder,d[4].lowOrder,d[5].highOrder,d[5].lowOrder,d[6].highOrder,d[6].lowOrder,d[7].highOrder,d[7].lowOrder];default:return[]}},D=function(r,e){if(this.sha1=null,this.sha224=null,this.sha256=null,this.sha384=null,this.sha512=null,this.strBinLen=null,this.strToHash=null,"HEX"===e){if(0!==r.length%2)return"TEXT MUST BE IN BYTE INCREMENTS";this.strBinLen=4*r.length,this.strToHash=s(r)}else{if("ASCII"!==e&&void 0!==e)return"UNKNOWN TEXT INPUT TYPE";this.strBinLen=r.length*t,this.strToHash=n(r)}};return D.prototype={getHash:function(t,r){var e=null,i=this.strToHash.slice();switch(r){case"HEX":e=o;break;case"B64":e=a;break;case"ASCII":e=h;break;default:return"FORMAT NOT RECOGNIZED"}switch(t){case"SHA-1":return null===this.sha1&&(this.sha1=P(i,this.strBinLen)),e(this.sha1);case"SHA-224":return null===this.sha224&&(this.sha224=N(i,this.strBinLen,t)),e(this.sha224);case"SHA-256":return null===this.sha256&&(this.sha256=N(i,this.strBinLen,t)),e(this.sha256);case"SHA-384":return null===this.sha384&&(this.sha384=N(i,this.strBinLen,t)),e(this.sha384);case"SHA-512":return null===this.sha512&&(this.sha512=N(i,this.strBinLen,t)),e(this.sha512);default:return"HASH NOT RECOGNIZED"}},getHMAC:function(r,e,i,c){var u,p,l,f,d,g,m,y,b,v=[],w=[];switch(c){case"HEX":u=o;break;case"B64":u=a;break;case"ASCII":u=h;break;default:return"FORMAT NOT RECOGNIZED"}switch(i){case"SHA-1":l=64,b=160;break;case"SHA-224":l=64,b=224;break;case"SHA-256":l=64,b=256;break;case"SHA-384":l=128,b=384;break;case"SHA-512":l=128,b=512;break;default:return"HASH NOT RECOGNIZED"}if("HEX"===e){if(0!==r.length%2)return"KEY MUST BE IN BYTE INCREMENTS";p=s(r),y=4*r.length}else{if("ASCII"!==e)return"UNKNOWN KEY INPUT TYPE";p=n(r),y=r.length*t}for(f=8*l,m=l/4-1,y/8>l?(p="SHA-1"===i?P(p,y):N(p,y,i),p[m]&=4294967040):l>y/8&&(p[m]&=4294967040),d=0;m>=d;d+=1)v[d]=909522486^p[d],w[d]=1549556828^p[d];return"SHA-1"===i?(g=P(v.concat(this.strToHash),f+this.strBinLen),g=P(w.concat(g),f+b)):(g=N(v.concat(this.strToHash),f+this.strBinLen,i),g=N(w.concat(g),f+b,i)),u(g)}},D}();r.exports={sha1:function(t){var r=new e(t,"ASCII");return r.getHash("SHA-1","ASCII")},sha224:function(t){var r=new e(t,"ASCII");return r.getHash("SHA-224","ASCII")},sha256:function(t){var r=new e(t,"ASCII");return r.getHash("SHA-256","ASCII")},sha384:function(t){var r=new e(t,"ASCII");return r.getHash("SHA-384","ASCII")},sha512:function(t){var r=new e(t,"ASCII");return r.getHash("SHA-512","ASCII")}}},{}],15:[function(t,r){r.exports={cipher:t("./cipher"),hash:t("./hash"),cfb:t("./cfb.js"),publicKey:t("./public_key"),signature:t("./signature.js"),random:t("./random.js"),pkcs1:t("./pkcs1.js")};var e=t("./crypto.js"); +for(var i in e)r.exports[i]=e[i]},{"./cfb.js":3,"./cipher":8,"./crypto.js":10,"./hash":11,"./pkcs1.js":16,"./public_key":19,"./random.js":22,"./signature.js":23}],16:[function(t,r){hash_headers=[],hash_headers[1]=[48,32,48,12,6,8,42,134,72,134,247,13,2,5,5,0,4,16],hash_headers[3]=[48,33,48,9,6,5,43,36,3,2,1,5,0,4,20],hash_headers[2]=[48,33,48,9,6,5,43,14,3,2,26,5,0,4,20],hash_headers[8]=[48,49,48,13,6,9,96,134,72,1,101,3,4,2,1,5,0,4,32],hash_headers[9]=[48,65,48,13,6,9,96,134,72,1,101,3,4,2,2,5,0,4,48],hash_headers[10]=[48,81,48,13,6,9,96,134,72,1,101,3,4,2,3,5,0,4,64],hash_headers[11]=[48,49,48,13,6,9,96,134,72,1,101,3,4,2,4,5,0,4,28];var e=(t("./crypto.js"),t("./random.js")),i=t("../util"),n=t("./public_key/jsbn.js"),s=t("./hash");r.exports={eme:{encode:function(t,r){if(t.length>r-11)return-1;var i="";i+=String.fromCharCode(0),i+=String.fromCharCode(2);for(var n=0;r-t.length-3>n;n++)i+=String.fromCharCode(e.getPseudoRandom(1,255));return i+=String.fromCharCode(0),i+=t},decode:function(t,r){if(r>t.length&&(t=String.fromCharCode(0)+t),12>t.length||0!=t.charCodeAt(0)||2!=t.charCodeAt(1))return-1;for(var e=2;0!=t.charCodeAt(e)&&t.length>e;)e++;return t.substring(e+1,t.length)}},emsa:{encode:function(t,r,e){var o="";o+=String.fromCharCode(0),o+=String.fromCharCode(1);for(var a=0;e-hash_headers[t].length-3-s.getHashByteLength(t)>a;a++)o+=String.fromCharCode(255);o+=String.fromCharCode(0);for(var a=0;hash_headers[t].length>a;a++)o+=String.fromCharCode(hash_headers[t][a]);return o+=s.digest(t,r),new n(i.hexstrdump(o),16)},decode:function(t,r){var e=0;if(0==r.charCodeAt(0))e++;else{if(1!=r.charCodeAt(0))return-1;e++}for(;255==r.charCodeAt(e);)e++;if(0!=r.charCodeAt(e++))return-1;var i=0;for(i=0;hash_headers[t].length>i&&r.length>i+e;i++)if(r.charCodeAt(i+e)!=hash_headers[t][i])return-1;return e+=i,r.substring(e).length11&&10!=r&&8>r?2:r;case 28:return r>11&&8>r?11:r;case 32:return r>10&&8>r?8:r;default:return o.print_debug("DSA select hash algorithm: returning null for an unknown length of q"),null}}function e(t,r,e,n,a,h,c,u){var p=o.getLeftNBits(s.digest(t,n),h.bitLength()),l=new i(o.hexstrdump(p),16);if(i.ZERO.compareTo(r)>0||r.compareTo(h)>0||i.ZERO.compareTo(e)>0||e.compareTo(h)>0)return o.print_error("invalid DSA Signature"),null;var f=e.modInverse(h),d=l.multiply(f).mod(h),g=r.multiply(f).mod(h);return c.modPow(d,a).multiply(u.modPow(g,a)).mod(a).mod(h)}this.select_hash_algorithm=r,this.sign=t,this.verify=e}var i=t("./jsbn.js"),n=t("../random.js"),s=t("../hash"),o=t("../../util");r.exports=e},{"../../util":55,"../hash":11,"../random.js":22,"./jsbn.js":20}],18:[function(t,r){function e(){function t(t,r,e,s){var o=i.ONE.add(i.ONE),a=e.subtract(o),h=n.getRandomBigIntegerInRange(o,a);h=h.mod(a).add(i.ONE);var c=[];return c[0]=r.modPow(h,e),c[1]=s.modPow(h,e).multiply(t).mod(e),c}function r(t,r,e,i){return s.print_debug("Elgamal Decrypt:\nc1:"+s.hexstrdump(t.toMPI())+"\n"+"c2:"+s.hexstrdump(r.toMPI())+"\n"+"p:"+s.hexstrdump(e.toMPI())+"\n"+"x:"+s.hexstrdump(i.toMPI())),t.modPow(i,e).modInverse(e).multiply(r).mod(e)}this.encrypt=t,this.decrypt=r}var i=t("./jsbn.js"),n=t("../random.js"),s=t("../../util");r.exports=e},{"../../util":55,"../random.js":22,"./jsbn.js":20}],19:[function(t,r){r.exports={rsa:t("./rsa.js"),elgamal:t("./elgamal.js"),dsa:t("./dsa.js")}},{"./dsa.js":17,"./elgamal.js":18,"./rsa.js":21}],20:[function(t,r){function e(t,r,e){null!=t&&("number"==typeof t?this.fromNumber(t,r,e):null==r&&"string"!=typeof t?this.fromString(t,256):this.fromString(t,r))}function i(){return new e(null)}function n(t,r,e,i,n,s){for(;--s>=0;){var o=r*this[t++]+e[i]+n;n=Math.floor(o/67108864),e[i++]=67108863&o}return n}function s(t){return ne.charAt(t)}function o(t,r){var e=se[t.charCodeAt(r)];return null==e?-1:e}function a(t){for(var r=this.t-1;r>=0;--r)t[r]=this[r];t.t=this.t,t.s=this.s}function h(t){this.t=1,this.s=0>t?-1:0,t>0?this[0]=t:-1>t?this[0]=t+DV:this.t=0}function c(t){var r=i();return r.fromInt(t),r}function u(t,r){var i;if(16==r)i=4;else if(8==r)i=3;else if(256==r)i=8;else if(2==r)i=1;else if(32==r)i=5;else{if(4!=r)return this.fromRadix(t,r),void 0;i=2}this.t=0,this.s=0;for(var n=t.length,s=!1,a=0;--n>=0;){var h=8==i?255&t[n]:o(t,n);0>h?"-"==t.charAt(n)&&(s=!0):(s=!1,0==a?this[this.t++]=h:a+i>this.DB?(this[this.t-1]|=(h&(1<>this.DB-a):this[this.t-1]|=h<=this.DB&&(a-=this.DB))}8==i&&0!=(128&t[0])&&(this.s=-1,a>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==t;)--this.t}function l(t){if(0>this.s)return"-"+this.negate().toString(t);var r;if(16==t)r=4;else if(8==t)r=3;else if(2==t)r=1;else if(32==t)r=5;else{if(4!=t)return this.toRadix(t);r=2}var e,i=(1<0)for(this.DB>h&&(e=this[a]>>h)>0&&(n=!0,o=s(e));a>=0;)r>h?(e=(this[a]&(1<>(h+=this.DB-r)):(e=this[a]>>(h-=r)&i,0>=h&&(h+=this.DB,--a)),e>0&&(n=!0),n&&(o+=s(e));return n?o:"0"}function f(){var t=i();return e.ZERO.subTo(this,t),t}function d(){return 0>this.s?this.negate():this}function g(t){var r=this.s-t.s;if(0!=r)return r;var e=this.t;if(r=e-t.t,0!=r)return r;for(;--e>=0;)if(0!=(r=this[e]-t[e]))return r;return 0}function m(t){var r,e=1;return 0!=(r=t>>>16)&&(t=r,e+=16),0!=(r=t>>8)&&(t=r,e+=8),0!=(r=t>>4)&&(t=r,e+=4),0!=(r=t>>2)&&(t=r,e+=2),0!=(r=t>>1)&&(t=r,e+=1),e}function y(){return 0>=this.t?0:this.DB*(this.t-1)+m(this[this.t-1]^this.s&this.DM)}function b(t,r){var e;for(e=this.t-1;e>=0;--e)r[e+t]=this[e];for(e=t-1;e>=0;--e)r[e]=0;r.t=this.t+t,r.s=this.s}function v(t,r){for(var e=t;this.t>e;++e)r[e-t]=this[e];r.t=Math.max(this.t-t,0),r.s=this.s}function w(t,r){var e,i=t%this.DB,n=this.DB-i,s=(1<=0;--e)r[e+o+1]=this[e]>>n|a,a=(this[e]&s)<=0;--e)r[e]=0;r[o]=a,r.t=this.t+o+1,r.s=this.s,r.clamp()}function k(t,r){r.s=this.s;var e=Math.floor(t/this.DB);if(e>=this.t)return r.t=0,void 0;var i=t%this.DB,n=this.DB-i,s=(1<>i;for(var o=e+1;this.t>o;++o)r[o-e-1]|=(this[o]&s)<>i;i>0&&(r[this.t-e-1]|=(this.s&s)<e;)i+=this[e]-t[e],r[e++]=i&this.DM,i>>=this.DB;if(t.te;)i+=this[e],r[e++]=i&this.DM,i>>=this.DB;i+=this.s}else{for(i+=this.s;t.t>e;)i-=t[e],r[e++]=i&this.DM,i>>=this.DB;i-=t.s}r.s=0>i?-1:0,-1>i?r[e++]=this.DV+i:i>0&&(r[e++]=i),r.t=e,r.clamp()}function A(t,r){var i=this.abs(),n=t.abs(),s=i.t;for(r.t=s+n.t;--s>=0;)r[s]=0;for(s=0;n.t>s;++s)r[s+i.t]=i.am(0,n[s],r,s,0,i.t);r.s=0,r.clamp(),this.s!=t.s&&e.ZERO.subTo(r,r)}function _(t){for(var r=this.abs(),e=t.t=2*r.t;--e>=0;)t[e]=0;for(e=0;r.t-1>e;++e){var i=r.am(e,r[e],t,2*e,0,1);(t[e+r.t]+=r.am(e+1,2*r[e],t,2*e+1,i,r.t-e-1))>=r.DV&&(t[e+r.t]-=r.DV,t[e+r.t+1]=1)}t.t>0&&(t[t.t-1]+=r.am(e,r[e],t,2*e,0,1)),t.s=0,t.clamp()}function S(t,r,n){var s=t.abs();if(!(0>=s.t)){var o=this.abs();if(o.t0?(s.lShiftTo(u,a),o.lShiftTo(u,n)):(s.copyTo(a),o.copyTo(n));var p=a.t,l=a[p-1];if(0!=l){var f=l*(1<1?a[p-2]>>this.F2:0),d=this.FV/f,g=(1<=0&&(n[n.t++]=1,n.subTo(w,n)),e.ONE.dlShiftTo(p,w),w.subTo(a,a);p>a.t;)a[a.t++]=0;for(;--v>=0;){var k=n[--b]==l?this.DM:Math.floor(n[b]*d+(n[b-1]+y)*g);if(k>(n[b]+=a.am(0,k,n,v,0,p)))for(a.dlShiftTo(v,w),n.subTo(w,n);n[b]<--k;)n.subTo(w,n)}null!=r&&(n.drShiftTo(p,r),h!=c&&e.ZERO.subTo(r,r)),n.t=p,n.clamp(),u>0&&n.rShiftTo(u,n),0>h&&e.ZERO.subTo(n,n)}}}function j(t){var r=i();return this.abs().divRemTo(t,null,r),0>this.s&&r.compareTo(e.ZERO)>0&&t.subTo(r,r),r}function T(t){this.m=t}function O(t){return 0>t.s||t.compareTo(this.m)>=0?t.mod(this.m):t}function E(t){return t}function I(t){t.divRemTo(this.m,null,t)}function B(t,r,e){t.multiplyTo(r,e),this.reduce(e)}function x(t,r){t.squareTo(r),this.reduce(r)}function P(){if(1>this.t)return 0;var t=this[0];if(0==(1&t))return 0;var r=3&t;return r=15&r*(2-(15&t)*r),r=255&r*(2-(255&t)*r),r=65535&r*(2-(65535&(65535&t)*r)),r=r*(2-t*r%this.DV)%this.DV,r>0?this.DV-r:-r}function N(t){this.m=t,this.mp=t.invDigit(),this.mpl=32767&this.mp,this.mph=this.mp>>15,this.um=(1<t.s&&r.compareTo(e.ZERO)>0&&this.m.subTo(r,r),r}function K(t){var r=i();return t.copyTo(r),this.reduce(r),r}function M(t){for(;t.t<=this.mt2;)t[t.t++]=0;for(var r=0;this.m.t>r;++r){var e=32767&t[r],i=e*this.mpl+((e*this.mph+(t[r]>>15)*this.mpl&this.um)<<15)&t.DM;for(e=r+this.m.t,t[e]+=this.m.am(0,i,t,r,0,this.m.t);t[e]>=t.DV;)t[e]-=t.DV,t[++e]++}t.clamp(),t.drShiftTo(this.m.t,t),t.compareTo(this.m)>=0&&t.subTo(this.m,t)}function R(t,r){t.squareTo(r),this.reduce(r)}function G(t,r,e){t.multiplyTo(r,e),this.reduce(e)}function H(){return 0==(this.t>0?1&this[0]:this.s)}function L(t,r){if(t>4294967295||1>t)return e.ONE;var n=i(),s=i(),o=r.convert(this),a=m(t)-1;for(o.copyTo(n);--a>=0;)if(r.sqrTo(n,s),(t&1<0)r.mulTo(s,o,n);else{var h=n;n=s,s=h}return r.revert(n)}function z(t,r){var e;return e=256>t||r.isEven()?new T(r):new N(r),this.exp(t,e)}function U(){var t=i();return this.copyTo(t),t}function q(){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)<>24}function V(){return 0==this.t?this.s:this[0]<<16>>16}function Z(t){return Math.floor(Math.LN2*this.DB/Math.log(t))}function X(){return 0>this.s?-1:0>=this.t||1==this.t&&0>=this[0]?0:1}function J(t){if(null==t&&(t=10),0==this.signum()||2>t||t>36)return"0";var r=this.chunkSize(t),e=Math.pow(t,r),n=c(e),s=i(),o=i(),a="";for(this.divRemTo(n,s,o);s.signum()>0;)a=(e+o.intValue()).toString(t).substr(1)+a,s.divRemTo(n,s,o);return o.intValue().toString(t)+a}function Y(t,r){this.fromInt(0),null==r&&(r=10);for(var i=this.chunkSize(r),n=Math.pow(r,i),s=!1,a=0,h=0,c=0;t.length>c;++c){var u=o(t,c);0>u?"-"==t.charAt(c)&&0==this.signum()&&(s=!0):(h=r*h+u,++a>=i&&(this.dMultiply(n),this.dAddOffset(h,0),a=0,h=0))}a>0&&(this.dMultiply(Math.pow(r,a)),this.dAddOffset(h,0)),s&&e.ZERO.subTo(this,this)}function W(t,r,i){if("number"==typeof r)if(2>t)this.fromInt(1);else for(this.fromNumber(t,i),this.testBit(t-1)||this.bitwiseTo(e.ONE.shiftLeft(t-1),sr,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(r);)this.dAddOffset(2,0),this.bitLength()>t&&this.subTo(e.ONE.shiftLeft(t-1),this);else{var n=[],s=7&t;n.length=(t>>3)+1,r.nextBytes(n),s>0?n[0]&=(1<0)for(this.DB>i&&(e=this[t]>>i)!=(this.s&this.DM)>>i&&(r[n++]=e|this.s<=0;)8>i?(e=(this[t]&(1<>(i+=this.DB-8)):(e=255&this[t]>>(i-=8),0>=i&&(i+=this.DB,--t)),(n>0||e!=this.s)&&(r[n++]=e);return r}function $(t){return 0==this.compareTo(t)}function tr(t){return 0>this.compareTo(t)?this:t}function rr(t){return this.compareTo(t)>0?this:t}function er(t,r,e){var i,n,s=Math.min(t.t,this.t);for(i=0;s>i;++i)e[i]=r(this[i],t[i]);if(t.ti;++i)e[i]=r(this[i],n);e.t=this.t}else{for(n=this.s&this.DM,i=s;t.t>i;++i)e[i]=r(n,t[i]);e.t=t.t}e.s=r(this.s,t.s),e.clamp()}function ir(t,r){return t&r}function nr(t){var r=i();return this.bitwiseTo(t,ir,r),r}function sr(t,r){return t|r}function or(t){var r=i();return this.bitwiseTo(t,sr,r),r}function ar(t,r){return t^r}function hr(t){var r=i();return this.bitwiseTo(t,ar,r),r}function cr(t,r){return t&~r}function ur(t){var r=i();return this.bitwiseTo(t,cr,r),r}function pr(){for(var t=i(),r=0;this.t>r;++r)t[r]=this.DM&~this[r];return t.t=this.t,t.s=~this.s,t}function lr(t){var r=i();return 0>t?this.rShiftTo(-t,r):this.lShiftTo(t,r),r}function fr(t){var r=i();return 0>t?this.lShiftTo(-t,r):this.rShiftTo(t,r),r}function dr(t){if(0==t)return-1;var r=0;return 0==(65535&t)&&(t>>=16,r+=16),0==(255&t)&&(t>>=8,r+=8),0==(15&t)&&(t>>=4,r+=4),0==(3&t)&&(t>>=2,r+=2),0==(1&t)&&++r,r}function gr(){for(var t=0;this.t>t;++t)if(0!=this[t])return t*this.DB+dr(this[t]);return 0>this.s?this.t*this.DB:-1}function mr(t){for(var r=0;0!=t;)t&=t-1,++r;return r}function yr(){for(var t=0,r=this.s&this.DM,e=0;this.t>e;++e)t+=mr(this[e]^r);return t}function br(t){var r=Math.floor(t/this.DB);return r>=this.t?0!=this.s:0!=(this[r]&1<e;)i+=this[e]+t[e],r[e++]=i&this.DM,i>>=this.DB;if(t.te;)i+=this[e],r[e++]=i&this.DM,i>>=this.DB;i+=this.s}else{for(i+=this.s;t.t>e;)i+=t[e],r[e++]=i&this.DM,i>>=this.DB;i+=t.s}r.s=0>i?-1:0,i>0?r[e++]=i:-1>i&&(r[e++]=this.DV+i),r.t=e,r.clamp()}function _r(t){var r=i();return this.addTo(t,r),r}function Sr(t){var r=i();return this.subTo(t,r),r}function jr(t){var r=i();return this.multiplyTo(t,r),r}function Tr(){var t=i();return this.squareTo(t),t}function Or(t){var r=i();return this.divRemTo(t,r,null),r}function Er(t){var r=i();return this.divRemTo(t,null,r),r}function Ir(t){var r=i(),e=i();return this.divRemTo(t,r,e),[r,e]}function Br(t){this[this.t]=this.am(0,t-1,this,0,0,this.t),++this.t,this.clamp()}function xr(t,r){if(0!=t){for(;r>=this.t;)this[this.t++]=0;for(this[r]+=t;this[r]>=this.DV;)this[r]-=this.DV,++r>=this.t&&(this[this.t++]=0),++this[r]}}function Pr(){}function Nr(t){return t}function Dr(t,r,e){t.multiplyTo(r,e)}function Kr(t,r){t.squareTo(r)}function Mr(t){return this.exp(t,new Pr)}function Rr(t,r,e){var i=Math.min(this.t+t.t,r);for(e.s=0,e.t=i;i>0;)e[--i]=0;var n;for(n=e.t-this.t;n>i;++i)e[i+this.t]=this.am(0,t[i],e,i,0,this.t);for(n=Math.min(t.t,r);n>i;++i)this.am(0,t[i],e,i,0,r-i);e.clamp()}function Gr(t,r,e){--r;var i=e.t=this.t+t.t-r;for(e.s=0;--i>=0;)e[i]=0;for(i=Math.max(r-this.t,0);t.t>i;++i)e[this.t+i-r]=this.am(r-i,t[i],e,0,0,this.t+i-r);e.clamp(),e.drShiftTo(1,e)}function Hr(t){this.r2=i(),this.q3=i(),e.ONE.dlShiftTo(2*t.t,this.r2),this.mu=this.r2.divide(t),this.m=t}function Lr(t){if(0>t.s||t.t>2*this.m.t)return t.mod(this.m);if(0>t.compareTo(this.m))return t;var r=i();return t.copyTo(r),this.reduce(r),r}function zr(t){return t}function Ur(t){for(t.drShiftTo(this.m.t-1,this.r2),t.t>this.m.t+1&&(t.t=this.m.t+1,t.clamp()),this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3),this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);0>t.compareTo(this.r2);)t.dAddOffset(1,this.m.t+1);for(t.subTo(this.r2,t);t.compareTo(this.m)>=0;)t.subTo(this.m,t)}function qr(t,r){t.squareTo(r),this.reduce(r)}function Fr(t,r,e){t.multiplyTo(r,e),this.reduce(e)}function Vr(t,r){var e,n,s=t.bitLength(),o=c(1);if(0>=s)return o;e=18>s?1:48>s?3:144>s?4:768>s?5:6,n=8>s?new T(r):r.isEven()?new Hr(r):new N(r);var a=[],h=3,u=e-1,p=(1<1){var l=i();for(n.sqrTo(a[1],l);p>=h;)a[h]=i(),n.mulTo(l,a[h-2],a[h]),h+=2}var f,d,g=t.t-1,y=!0,b=i();for(s=m(t[g])-1;g>=0;){for(s>=u?f=t[g]>>s-u&p:(f=(t[g]&(1<0&&(f|=t[g-1]>>this.DB+s-u)),h=e;0==(1&f);)f>>=1,--h;if(0>(s-=h)&&(s+=this.DB,--g),y)a[f].copyTo(o),y=!1;else{for(;h>1;)n.sqrTo(o,b),n.sqrTo(b,o),h-=2;h>0?n.sqrTo(o,b):(d=o,o=b,b=d),n.mulTo(b,a[f],o)}for(;g>=0&&0==(t[g]&1<--s&&(s=this.DB-1,--g)}return n.revert(o)}function Zr(t){var r=0>this.s?this.negate():this.clone(),e=0>t.s?t.negate():t.clone();if(0>r.compareTo(e)){var i=r;r=e,e=i}var n=r.getLowestSetBit(),s=e.getLowestSetBit();if(0>s)return r;for(s>n&&(s=n),s>0&&(r.rShiftTo(s,r),e.rShiftTo(s,e));r.signum()>0;)(n=r.getLowestSetBit())>0&&r.rShiftTo(n,r),(n=e.getLowestSetBit())>0&&e.rShiftTo(n,e),r.compareTo(e)>=0?(r.subTo(e,r),r.rShiftTo(1,r)):(e.subTo(r,e),e.rShiftTo(1,e));return s>0&&e.lShiftTo(s,e),e}function Xr(t){if(0>=t)return 0;var r=this.DV%t,e=0>this.s?t-1:0;if(this.t>0)if(0==r)e=this[0]%t;else for(var i=this.t-1;i>=0;--i)e=(r*e+this[i])%t;return e}function Jr(t){var r=t.isEven();if(this.isEven()&&r||0==t.signum())return e.ZERO;for(var i=t.clone(),n=this.clone(),s=c(1),o=c(0),a=c(0),h=c(1);0!=i.signum();){for(;i.isEven();)i.rShiftTo(1,i),r?(s.isEven()&&o.isEven()||(s.addTo(this,s),o.subTo(t,o)),s.rShiftTo(1,s)):o.isEven()||o.subTo(t,o),o.rShiftTo(1,o);for(;n.isEven();)n.rShiftTo(1,n),r?(a.isEven()&&h.isEven()||(a.addTo(this,a),h.subTo(t,h)),a.rShiftTo(1,a)):h.isEven()||h.subTo(t,h),h.rShiftTo(1,h);i.compareTo(n)>=0?(i.subTo(n,i),r&&s.subTo(a,s),o.subTo(h,o)):(n.subTo(i,n),r&&a.subTo(s,a),h.subTo(o,h))}return 0!=n.compareTo(e.ONE)?e.ZERO:h.compareTo(t)>=0?h.subtract(t):0>h.signum()?(h.addTo(t,h),0>h.signum()?h.add(t):h):h}function Yr(t){var r,e=this.abs();if(1==e.t&&e[0]<=oe[oe.length-1]){for(r=0;oe.length>r;++r)if(e[0]==oe[r])return!0;return!1}if(e.isEven())return!1;for(r=1;oe.length>r;){for(var i=oe[r],n=r+1;oe.length>n&&ae>i;)i*=oe[n++];for(i=e.modInt(i);n>r;)if(0==i%oe[r++])return!1}return e.millerRabin(t)}function m(t){var r,e=1;return 0!=(r=t>>>16)&&(t=r,e+=16),0!=(r=t>>8)&&(t=r,e+=8),0!=(r=t>>4)&&(t=r,e+=4),0!=(r=t>>2)&&(t=r,e+=2),0!=(r=t>>1)&&(t=r,e+=1),e}function Wr(){var t=this.toByteArray(),r=8*(t.length-1)+m(t[0]),e="";return e+=String.fromCharCode((65280&r)>>8),e+=String.fromCharCode(255&r),e+=te.bin2str(t)}function Qr(t){var r=this.subtract(e.ONE),n=r.getLowestSetBit();if(0>=n)return!1;var s=r.shiftRight(n);t=t+1>>1,t>oe.length&&(t=oe.length);for(var o,a=i(),h=[],c=0;t>c;++c){for(;o=oe[Math.floor(Math.random()*oe.length)],-1!=h.indexOf(o););h.push(o),a.fromInt(o);var u=a.modPow(s,this);if(0!=u.compareTo(e.ONE)&&0!=u.compareTo(r)){for(var o=1;n>o++&&0!=u.compareTo(r);)if(u=u.modPowInt(2,this),0==u.compareTo(e.ONE))return!1;if(0!=u.compareTo(r))return!1}}return!0}var $r,te=t("../../util");e.prototype.am=n,$r=26,e.prototype.DB=$r,e.prototype.DM=(1<<$r)-1,e.prototype.DV=1<<$r;var re=52;e.prototype.FV=Math.pow(2,re),e.prototype.F1=re-$r,e.prototype.F2=2*$r-re;var ee,ie,ne="0123456789abcdefghijklmnopqrstuvwxyz",se=[];for(ee="0".charCodeAt(0),ie=0;9>=ie;++ie)se[ee++]=ie;for(ee="a".charCodeAt(0),ie=10;36>ie;++ie)se[ee++]=ie;for(ee="A".charCodeAt(0),ie=10;36>ie;++ie)se[ee++]=ie;T.prototype.convert=O,T.prototype.revert=E,T.prototype.reduce=I,T.prototype.mulTo=B,T.prototype.sqrTo=x,N.prototype.convert=D,N.prototype.revert=K,N.prototype.reduce=M,N.prototype.mulTo=G,N.prototype.sqrTo=R,e.prototype.copyTo=a,e.prototype.fromInt=h,e.prototype.fromString=u,e.prototype.clamp=p,e.prototype.dlShiftTo=b,e.prototype.drShiftTo=v,e.prototype.lShiftTo=w,e.prototype.rShiftTo=k,e.prototype.subTo=C,e.prototype.multiplyTo=A,e.prototype.squareTo=_,e.prototype.divRemTo=S,e.prototype.invDigit=P,e.prototype.isEven=H,e.prototype.exp=L,e.prototype.toString=l,e.prototype.negate=f,e.prototype.abs=d,e.prototype.compareTo=g,e.prototype.bitLength=y,e.prototype.mod=j,e.prototype.modPowInt=z,e.ZERO=c(0),e.ONE=c(1),r.exports=e,Pr.prototype.convert=Nr,Pr.prototype.revert=Nr,Pr.prototype.mulTo=Dr,Pr.prototype.sqrTo=Kr,Hr.prototype.convert=Lr,Hr.prototype.revert=zr,Hr.prototype.reduce=Ur,Hr.prototype.mulTo=Fr,Hr.prototype.sqrTo=qr;var oe=[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,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997],ae=(1<<26)/oe[oe.length-1],e=t("./jsbn.js");e.prototype.chunkSize=Z,e.prototype.toRadix=J,e.prototype.fromRadix=Y,e.prototype.fromNumber=W,e.prototype.bitwiseTo=er,e.prototype.changeBit=vr,e.prototype.addTo=Ar,e.prototype.dMultiply=Br,e.prototype.dAddOffset=xr,e.prototype.multiplyLowerTo=Rr,e.prototype.multiplyUpperTo=Gr,e.prototype.modInt=Xr,e.prototype.millerRabin=Qr,e.prototype.clone=U,e.prototype.intValue=q,e.prototype.byteValue=F,e.prototype.shortValue=V,e.prototype.signum=X,e.prototype.toByteArray=Q,e.prototype.equals=$,e.prototype.min=tr,e.prototype.max=rr,e.prototype.and=nr,e.prototype.or=or,e.prototype.xor=hr,e.prototype.andNot=ur,e.prototype.not=pr,e.prototype.shiftLeft=lr,e.prototype.shiftRight=fr,e.prototype.getLowestSetBit=gr,e.prototype.bitCount=yr,e.prototype.testBit=br,e.prototype.setBit=wr,e.prototype.clearBit=kr,e.prototype.flipBit=Cr,e.prototype.add=_r,e.prototype.subtract=Sr,e.prototype.multiply=jr,e.prototype.divide=Or,e.prototype.remainder=Er,e.prototype.divideAndRemainder=Ir,e.prototype.modPow=Vr,e.prototype.modInverse=Jr,e.prototype.pow=Mr,e.prototype.gcd=Zr,e.prototype.isProbablePrime=Yr,e.prototype.toMPI=Wr,e.prototype.square=Tr},{"../../util":55,"./jsbn.js":20}],21:[function(t,r){function e(){function t(t){for(var r=0;t.length>r;r++)t[r]=o.getSecureRandomOctet()}this.nextBytes=t}function i(){function t(t,r,e,i,o){var a=t.mod(e).modPow(r.mod(e.subtract(n.ONE)),e),h=t.mod(i).modPow(r.mod(i.subtract(n.ONE)),i);s.print_debug("rsa.js decrypt\nxpn:"+s.hexstrdump(a.toMPI())+"\nxqn:"+s.hexstrdump(h.toMPI()));var c=h.subtract(a);return 0==c[0]?(c=a.subtract(h),c=c.multiply(o).mod(i),c=i.subtract(c)):c=c.multiply(o).mod(i),c.multiply(e).add(a)}function r(t,r,e){return t.modPowInt(r,e)}function i(t,r,e){return t.modPow(r,e)}function o(t,r,e){return t.modPowInt(r,e)}function a(){this.n=null,this.e=0,this.ee=null,this.d=null,this.p=null,this.q=null,this.dmp1=null,this.dmq1=null,this.u=null}function h(t,r){var i=new a,s=new e,o=t>>1;for(i.e=parseInt(r,16),i.ee=new n(r,16);;){for(;i.p=new n(t-o,1,s),0!=i.p.subtract(n.ONE).gcd(i.ee).compareTo(n.ONE)||!i.p.isProbablePrime(10););for(;i.q=new n(o,1,s),0!=i.q.subtract(n.ONE).gcd(i.ee).compareTo(n.ONE)||!i.q.isProbablePrime(10););if(0>=i.p.compareTo(i.q)){var h=i.p;i.p=i.q,i.q=h}var c=i.p.subtract(n.ONE),u=i.q.subtract(n.ONE),p=c.multiply(u);if(0==p.gcd(i.ee).compareTo(n.ONE)){i.n=i.p.multiply(i.q),i.d=i.ee.modInverse(p),i.dmp1=i.d.mod(c),i.dmq1=i.d.mod(u),i.u=i.p.modInverse(i.q);break}}return i}this.encrypt=r,this.decrypt=t,this.verify=o,this.sign=i,this.generate=h,this.keyObject=a}var n=t("./jsbn.js"),s=t("../../util"),o=t("../random.js");r.exports=i},{"../../util":55,"../random.js":22,"./jsbn.js":20}],22:[function(t,r){var e=t("../type/mpi.js");r.exports={getRandomBytes:function(t){for(var r="",e=0;t>e;e++)r+=String.fromCharCode(this.getSecureRandomOctet());return r},getPseudoRandom:function(t,r){return Math.round(Math.random()*(r-t))+t},getSecureRandom:function(t,r){var e=new Uint32Array(1);window.crypto.getRandomValues(e);for(var i=(r-t).toString(2).length;(e[0]&Math.pow(2,i)-1)>r-t;)window.crypto.getRandomValues(e);return t+Math.abs(e[0]&Math.pow(2,i)-1)},getSecureRandomOctet:function(){var t=new Uint32Array(1);return window.crypto.getRandomValues(t),255&t[0]},getRandomBigInteger:function(t){if(0>t)return null;var r=Math.floor((t+7)/8),i=this.getRandomBytes(r);t%8>0&&(i=String.fromCharCode(Math.pow(2,t%8)-1&i.charCodeAt(0))+i.substring(1));var n=new e;return n.fromBytes(i),n.toBigInteger()},getRandomBigIntegerInRange:function(t,r){if(!(0>=r.compareTo(t))){for(var e=r.subtract(t),i=this.getRandomBigInteger(e.bitLength());i>e;)i=this.getRandomBigInteger(e.bitLength());return t.add(i)}}}},{"../type/mpi.js":53}],23:[function(t,r){var e=t("./public_key"),i=t("./pkcs1.js"),n=t("./hash");r.exports={verify:function(t,r,s,o,a){var h=n.digest(r,a);switch(t){case 1:case 2:case 3:var c=new e.rsa,u=o[0].toBigInteger(),p=o[1].toBigInteger(),l=s[0].toBigInteger(),f=c.verify(l,p,u),d=i.emsa.decode(r,f.toMPI().substring(2));if(-1==d)throw Error("PKCS1 padding in message or key incorrect. Aborting...");return d==h;case 16:throw Error("signing with Elgamal is not defined in the OpenPGP standard.");case 17:var g=new e.dsa,m=s[0].toBigInteger(),y=s[1].toBigInteger(),b=o[0].toBigInteger(),v=o[1].toBigInteger(),w=o[2].toBigInteger(),k=o[3].toBigInteger(),C=a,f=g.verify(r,m,y,C,b,v,w,k);return 0==f.compareTo(m);default:throw Error("Invalid signature algorithm.")}},sign:function(t,r,n,s){switch(r){case 1:case 2:case 3:var o=new e.rsa,a=n[2].toBigInteger(),h=n[0].toBigInteger(),c=i.emsa.encode(t,s,n[0].byteLength());return o.sign(c,a,h).toMPI();case 17:var u=new e.dsa,p=n[0].toBigInteger(),l=n[1].toBigInteger(),f=n[2].toBigInteger();n[3].toBigInteger();var d=n[4].toBigInteger(),c=s,g=u.sign(t,c,f,p,l,d);return""+g[0]+(""+g[1]);case 16:throw Error("Signing with Elgamal is not defined in the OpenPGP standard.");default:throw Error("Invalid signature algorithm.")}}}},{"./hash":11,"./pkcs1.js":16,"./public_key":19}],24:[function(t,r){function e(t){var r=t.split("-----");return r[1].match(/BEGIN PGP MESSAGE, PART \d+\/\d+/)?0:r[1].match(/BEGIN PGP MESSAGE, PART \d+/)?1:r[1].match(/BEGIN PGP SIGNED MESSAGE/)?2:r[1].match(/BEGIN PGP MESSAGE/)?3:r[1].match(/BEGIN PGP PUBLIC KEY BLOCK/)?4:r[1].match(/BEGIN PGP PRIVATE KEY BLOCK/)?5:void 0}function i(){var t="";return openpgp.config.config.show_version&&(t+="Version: "+openpgp.config.versionstring+"\r\n"),openpgp.config.config.show_comment&&(t+="Comment: "+openpgp.config.commentstring+"\r\n"),t+="\r\n"}function n(t){var r=o(t),e=""+String.fromCharCode(r>>16)+String.fromCharCode(255&r>>8)+String.fromCharCode(255&r);return c.encode(e)}function s(t,r){var e=n(t),i=r;return e[0]==i[0]&&e[1]==i[1]&&e[2]==i[2]}function o(t){for(var r=11994318,e=0;t.length-e>16;)r=r<<8^u[255&(r>>16^t.charCodeAt(e))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+1))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+2))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+3))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+4))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+5))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+6))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+7))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+8))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+9))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+10))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+11))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+12))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+13))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+14))],r=r<<8^u[255&(r>>16^t.charCodeAt(e+15))],e+=16;for(var i=e;t.length>i;i++)r=r<<8^u[255&(r>>16^t.charCodeAt(e++))];return 16777215&r}function a(t){t=t.replace(/\r/g,"");var r=e(t);if(2!=r){var i=t.split("-----"),o={openpgp:c.decode(i[2].split("\n\n")[1].split("\n=")[0].replace(/\n- /g,"\n")),type:r};return s(o.openpgp,i[2].split("\n\n")[1].split("\n=")[1].split("\n")[0])?o:(util.print_error("Ascii armor integrity check on message failed: '"+i[2].split("\n\n")[1].split("\n=")[1].split("\n")[0]+"' should be '"+n(o))+"'",!1)}var i=t.split("-----"),a={text:i[2].replace(/\n- /g,"\n").split("\n\n")[1],openpgp:base64_decode(i[4].split("\n\n")[1].split("\n=")[0]),type:r};return s(a.openpgp,i[4].split("\n\n")[1].split("\n=")[1])?a:(util.print_error("Ascii armor integrity check on message failed"),!1)}function h(t,r,e,s){var o="";switch(t){case 0:o+="-----BEGIN PGP MESSAGE, PART "+e+"/"+s+"-----\r\n",o+=i(),o+=c.encode(r),o+="\r\n="+n(r)+"\r\n",o+="-----END PGP MESSAGE, PART "+e+"/"+s+"-----\r\n";break;case 1:o+="-----BEGIN PGP MESSAGE, PART "+e+"-----\r\n",o+=i(),o+=c.encode(r),o+="\r\n="+n(r)+"\r\n",o+="-----END PGP MESSAGE, PART "+e+"-----\r\n";break;case 2:o+="\r\n-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: "+r.hash+"\r\n\r\n",o+=r.text.replace(/\n-/g,"\n- -"),o+="\r\n-----BEGIN PGP SIGNATURE-----\r\n",o+=i(),o+=c.encode(r.openpgp),o+="\r\n="+n(r.openpgp)+"\r\n",o+="-----END PGP SIGNATURE-----\r\n";break;case 3:o+="-----BEGIN PGP MESSAGE-----\r\n",o+=i(),o+=c.encode(r),o+="\r\n="+n(r)+"\r\n",o+="-----END PGP MESSAGE-----\r\n";break;case 4:o+="-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n",o+=i(),o+=c.encode(r),o+="\r\n="+n(r)+"\r\n",o+="-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n";break;case 5:o+="-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n",o+=i(),o+=c.encode(r),o+="\r\n="+n(r)+"\r\n",o+="-----END PGP PRIVATE KEY BLOCK-----\r\n"}return o}var c=t("./base64.js"),u=[0,8801531,25875725,17603062,60024545,51751450,35206124,44007191,128024889,120049090,103502900,112007375,70412248,78916387,95990485,88014382,264588937,256049778,240098180,248108927,207005800,215016595,232553829,224014750,140824496,149062475,166599357,157832774,200747345,191980970,176028764,184266919,520933865,529177874,512099556,503334943,480196360,471432179,487973381,496217854,414011600,405478443,422020573,430033190,457094705,465107658,448029500,439496647,281648992,273666971,289622637,298124950,324696449,333198714,315665548,307683447,392699481,401494690,383961940,375687087,352057528,343782467,359738805,368533838,1041867730,1050668841,1066628831,1058355748,1032471859,1024199112,1006669886,1015471301,968368875,960392720,942864358,951368477,975946762,984451313,1000411399,992435708,836562267,828023200,810956886,818967725,844041146,852051777,868605623,860066380,914189410,922427545,938981743,930215316,904825475,896059e3,878993294,887231349,555053627,563297984,547333942,538569677,579245274,570480673,588005847,596249900,649392898,640860153,658384399,666397428,623318499,631331096,615366894,606833685,785398962,777416777,794487231,802989380,759421523,767923880,751374174,743392165,695319947,704115056,687564934,679289981,719477610,711202705,728272487,737067676,2083735460,2092239711,2109313705,2101337682,2141233477,2133257662,2116711496,2125215923,2073216669,2064943718,2048398224,2057199467,2013339772,2022141063,2039215473,2030942602,1945504045,1936737750,1920785440,1929023707,1885728716,1893966647,1911503553,1902736954,1951893524,1959904495,1977441561,1968902626,2009362165,2000822798,1984871416,1992881923,1665111629,1673124534,1656046400,1647513531,1621913772,1613380695,1629922721,1637935450,1688082292,1679317903,1695859321,1704103554,1728967061,1737211246,1720132760,1711368291,1828378820,1820103743,1836060105,1844855090,1869168165,1877963486,1860430632,1852155859,1801148925,1809650950,1792118e3,1784135691,1757986588,1750004711,1765960209,1774462698,1110107254,1118611597,1134571899,1126595968,1102643863,1094667884,1077139354,1085643617,1166763343,1158490548,1140961346,1149762745,1176011694,1184812885,1200772771,1192499800,1307552511,1298785796,1281720306,1289958153,1316768798,1325007077,1341561107,1332794856,1246636998,1254647613,1271201483,1262662192,1239272743,1230733788,1213667370,1221678289,1562785183,1570797924,1554833554,1546300521,1588974462,1580441477,1597965939,1605978760,1518843046,1510078557,1527603627,1535847760,1494504007,1502748348,1486784330,1478020017,1390639894,1382365165,1399434779,1408230112,1366334967,1375129868,1358579962,1350304769,1430452783,1438955220,1422405410,1414423513,1456544974,1448562741,1465633219,1474135352];r.exports={encode:h,decode:a}},{"./base64.js":25}],25:[function(t,r){function e(t){var r,e,i,s="",o=0,a=0,h=t.length;for(i=0;h>i;i++)e=t.charCodeAt(i),0==a?(s+=n.charAt(63&e>>2),r=(3&e)<<4):1==a?(s+=n.charAt(r|15&e>>4),r=(15&e)<<2):2==a&&(s+=n.charAt(r|3&e>>6),o+=1,0==o%60&&(s+="\n"),s+=n.charAt(63&e)),o+=1,0==o%60&&(s+="\n"),a+=1,3==a&&(a=0); +return a>0&&(s+=n.charAt(r),o+=1,0==o%60&&(s+="\n"),s+="=",o+=1),1==a&&(0==o%60&&(s+="\n"),s+="="),s}function i(t){var r,e,i="",s=0,o=0,a=t.length;for(e=0;a>e;e++)r=n.indexOf(t.charAt(e)),r>=0&&(s&&(i+=String.fromCharCode(o|255&r>>6-s)),s=7&s+2,o=255&r<n;n++){var h=new openpgp_packet_onepasssignature,c="";c=0===n?h.write_packet(1,openpgp.config.config.prefer_hash_algorithm,t,!1):h.write_packet(1,openpgp.config.config.prefer_hash_algorithm,t,!1),s.print_debug_hexstr_dump("onepasssigstr: |"+c+"|\n",c);var u=(new openpgp_packet_signature).write_message_signature(1,e.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"),t);s.print_debug_hexstr_dump("datasignature: |"+u.openpgp+"|\n",u.openpgp),o=0===n?c+a+u.openpgp:c+o+u.openpgp}s.print_debug_hexstr_dump("signed packet: |"+o+"|\n",o);var p=openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher),l="";for(n=0;r.length>n;n++){var f=r[n].getEncryptionKey();if(null===f)return s.print_error("no encryption key found! Key is for signing only."),null;l+=(new openpgp_packet_encryptedsessionkey).write_pub_key_packet(f.getKeyId(),f.MPIs,f.publicKeyAlgorithm,openpgp.config.config.encryption_cipher,p)}return l+=openpgp.config.config.integrity_protect?(new openpgp_packet_encryptedintegrityprotecteddata).write_packet(openpgp.config.config.encryption_cipher,p,o):(new openpgp_packet_encrypteddata).write_packet(openpgp.config.config.encryption_cipher,p,o),i.encode(3,l,null,null)}function c(t,r){var e="",n=(new openpgp_packet_literaldata).write_packet(r.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"));s.print_debug_hexstr_dump("literal_packet: |"+n+"|\n",n),e=n;for(var o=openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher),a="",h=0;t.length>h;h++){var c=t[h].getEncryptionKey();if(null===c)return s.print_error("no encryption key found! Key is for signing only."),null;a+=(new openpgp_packet_encryptedsessionkey).write_pub_key_packet(c.getKeyId(),c.MPIs,c.publicKeyAlgorithm,openpgp.config.config.encryption_cipher,o)}return a+=openpgp.config.config.integrity_protect?(new openpgp_packet_encryptedintegrityprotecteddata).write_packet(openpgp.config.config.encryption_cipher,o,e):(new openpgp_packet_encrypteddata).write_packet(openpgp.config.config.encryption_cipher,o,e),i.encode(3,a,null,null)}function u(t,r){var e=(new openpgp_packet_signature).write_message_signature(1,r.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"),t),n={text:r.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"),openpgp:e.openpgp,hash:e.hash};return i.encode(2,n,null,null)}this.tostring="",this.generateKeyPair=a,this.write_signed_message=u,this.write_signed_and_encrypted_message=h,this.write_encrypted_message=c,this.readArmoredPackets=r,this.readDearmoredPackets=e,this.init=t}var i=t("./encoding/armor.js"),n=t("./packet"),s=t("./util"),o=t("./enums.js");r.exports=new e},{"./encoding/armor.js":24,"./enums.js":26,"./packet":34,"./util":55}],30:[function(t,r){var e=t("./packet"),i=t("./enums.js"),n=t("./encoding/armor.js"),s=function(){function t(){var t=JSON.parse(window.localStorage.getItem("armoredPacketlists"));(null===t||0===t.length)&&(t=[]),this.armoredPacketlists=t;for(var r,i=0;t.length>i;i++)r=new e.list,r.read(t[i]),this.parsedPacketlists.push(r)}function r(){window.localStorage.setItem("armoredPacketlists",JSON.stringify(this.armoredPacketlists))}function s(t,r){var e,n=!1;return r=r.toLowerCase(),t.tag==i.packet.userid&&(e=t.userid,e=e.split("<")[1].split("<")[0].trim.toLowerCase(),e==r&&(n=!0)),n}function o(t,r){return t.getKeyId&&t.getKeyId()==r?!0:!1}function a(t,r,e,i){for(var n,s=0;i.length>s;s++)if(n=i[s],identityMatch=t(n,r),e?n.tag==e&&(packetMatch=!0):packetMatch=!0,packetMatch&&identityMatch)return!0;return!1}function h(t,r,e){for(var i,n,s,o=[],h=0;this.parsedPacketlists.length>h;h++)n=!1,s=!1,i=this.parsedPacketlists[h],a(t,r,e,i)&&o.push(i);return o}function c(t){return h(s,t,i.packet.public_key)}function u(){return h(s,email,i.packet.secret_key)}function p(t){return this.checkForIdentityAndPacketMatch(o,t)}function l(t){this.armoredPacketlists.push(t);var r=n.decode(t.replace(/\r/g,"")).openpgp;return packetlist=new e.list,packetlist.read(r),this.parsedPacketlists.push(packetlist),!0}function f(t){return this.publicKey[t]}function d(t){var r=this.publicKeys.splice(t,1);return this.store(),r}this.armoredPacketlists=[],this.parsedPacketlists=[],this.init=t,this.store=r,this.checkForIdentityAndPacketMatch=h,this.getPublicKeyForAddress=c,this.getPrivateKeyForAddress=u,this.getPacketlistsForKeyId=p,this.importPacketlist=l,this.exportPublicKey=f,this.removePublicKey=d};r.exports=new s},{"./encoding/armor.js":24,"./enums.js":26,"./packet":34}],31:[function(){},{}],32:[function(t,r){var e=t("../enums.js");r.exports={compressed:t("./compressed.js"),sym_encrypted_integrity_protected:t("./sym_encrypted_integrity_protected.js"),public_key_encrypted_session_key:t("./public_key_encrypted_session_key.js"),sym_encrypted_session_key:t("./sym_encrypted_session_key.js"),literal:t("./literal.js"),public_key:t("./public_key.js"),symmetrically_encrypted:t("./symmetrically_encrypted.js"),marker:t("./marker.js"),public_subkey:t("./public_subkey.js"),user_attribute:t("./user_attribute.js"),one_pass_signature:t("./one_pass_signature.js"),secret_key:t("./secret_key.js"),userid:t("./userid.js"),secret_subkey:t("./secret_subkey.js"),signature:t("./signature.js"),trust:t("./trust.js")};for(var i in e.packet){var n=r.exports[i];void 0!=n&&(n.prototype.tag=e.packet[i])}},{"../enums.js":26,"./compressed.js":33,"./literal.js":35,"./marker.js":36,"./one_pass_signature.js":37,"./public_key.js":40,"./public_key_encrypted_session_key.js":41,"./public_subkey.js":42,"./secret_key.js":43,"./secret_subkey.js":44,"./signature.js":45,"./sym_encrypted_integrity_protected.js":46,"./sym_encrypted_session_key.js":47,"./symmetrically_encrypted.js":48,"./trust.js":49,"./user_attribute.js":50,"./userid.js":51}],33:[function(t,r){var e=t("../enums.js"),i=t("../compression/jxg.js"),n=t("../encoding/base64.js");r.exports=function(){this.packets,this.algorithm="uncompressed",this.compressed=null,this.read=function(t){this.algorithm=e.read(e.compression,t.charCodeAt(0)),this.compressed=t.substr(1),this.decompress()},this.write=function(){return null==this.compressed&&this.compress(),String.fromCharCode(e.write(e.compression,this.algorithm))+this.compressed},this.decompress=function(){var t;switch(this.algorithm){case"uncompressed":t=this.compressed;break;case"zip":var r=this.compressed,e=n.encode(r).replace(/\n/g,""),s=new i.Util.Unzip(i.Util.Base64.decodeAsArray(e));t=unescape(s.deflate()[0][0]);break;case"zlib":var o=this.compressed.charCodeAt(0)%16;if(8==o){var r=this.compressed.substring(0,this.compressed.length-4),e=n.encode(r).replace(/\n/g,"");t=i.decompress(e);break}util.print_error("Compression algorithm ZLIB only supports DEFLATE compression method.");break;case"bzip2":throw Error("Compression algorithm BZip2 [BZ2] is not implemented.");default:throw Error("Compression algorithm unknown :"+this.alogrithm)}this.packets.read(t)},this.compress=function(){switch(this.algorithm){case"uncompressed":this.compressed=this.packets.write();break;case"zip":util.print_error("Compression algorithm ZIP [RFC1951] is not implemented.");break;case"zlib":util.print_error("Compression algorithm ZLIB [RFC1950] is not implemented.");break;case"bzip2":util.print_error("Compression algorithm BZip2 [BZ2] is not implemented.");break;default:util.print_error("Compression algorithm unknown :"+this.type)}}}},{"../compression/jxg.js":1,"../encoding/base64.js":25,"../enums.js":26}],34:[function(t,r){t("../enums.js"),r.exports={list:t("./packetlist.js")};var e=t("./all_packets.js");for(var i in e)r.exports[i]=e[i]},{"../enums.js":26,"./all_packets.js":32,"./packetlist.js":39}],35:[function(t,r){var e=t("../util"),i=t("../enums.js");r.exports=function(){this.format="utf8",this.data="",this.date=new Date,this.set=function(t,r){this.format=r,this.data=t},this.setBytes=function(t,r){this.format=r,"utf8"==r&&(t=e.decode_utf8(t)),this.data=t},this.getBytes=function(){return"utf8"==this.format?e.encode_utf8(this.data):this.data},this.read=function(t){var r=i.read(i.literal,t[0].charCodeAt()),n=t.charCodeAt(1);this.filename=e.decode_utf8(t.substr(2,n)),this.date=e.readDate(t.substr(2+n,4));var s=t.substring(6+n);this.setBytes(s,r)},this.write=function(){var t=e.encode_utf8("msg.txt"),r=this.getBytes(),n="";return n+=String.fromCharCode(i.write(i.literal,this.format)),n+=String.fromCharCode(t.length),n+=t,n+=e.writeDate(this.date),n+=r}}},{"../enums.js":26,"../util":55}],36:[function(t,r){function e(){this.read=function(t){return 80==t[0].charCodeAt()&&71==t[1].charCodeAt()&&80==t[2].charCodeAt()?!0:!1}}r.exports=e},{}],37:[function(t,r){var e=t("../enums.js"),i=t("../type/keyid.js");r.exports=function(){this.version=null,this.type=null,this.hashAlgorithm=null,this.publicKeyAlgorithm=null,this.signingKeyId=null,this.flags=null,this.read=function(t){var r=0;return this.version=t.charCodeAt(r++),this.type=e.read(e.signature,t.charCodeAt(r++)),this.hashAlgorithm=e.read(e.hash,t.charCodeAt(r++)),this.publicKeyAlgorithm=e.read(e.publicKey,t.charCodeAt(r++)),this.signingKeyId=new i,this.signingKeyId.read(t.substr(r)),r+=8,this.flags=t.charCodeAt(r++),this},this.write=function(t,r,i,n,s){var o="";return o+=String.fromCharCode(3),o+=String.fromCharCode(e.write(e.signature,t)),o+=String.fromCharCode(e.write(e.hash,this.hashAlgorithm)),o+=String.fromCharCode(e.write(e.publicKey,i.algorithm)),o+=i.getKeyId(),o+=s?String.fromCharCode(0):String.fromCharCode(1)}}},{"../enums.js":26,"../type/keyid.js":52}],38:[function(t,r){var e=(t("../enums.js"),t("../util"));r.exports={readSimpleLength:function(t){var r,i=0,n=t[0].charCodeAt();return 192>n?(i=t[0].charCodeAt(),r=1):255>n?(i=(t[0].charCodeAt()-192<<8)+t[1].charCodeAt()+192,r=2):255==n&&(i=e.readNumber(t.substr(1,4)),r=5),{len:i,offset:r}},writeSimpleLength:function(t){var r="";return 192>t?r+=String.fromCharCode(t):t>191&&8384>t?(r+=String.fromCharCode((t-192>>8)+192),r+=String.fromCharCode(255&t-192)):(r+=String.fromCharCode(255),r+=e.writeNumber(t,4)),r},writeHeader:function(t,r){var e="";return e+=String.fromCharCode(192|t),e+=this.writeSimpleLength(r)},writeOldHeader:function(t,r){var i="";return 256>r?(i+=String.fromCharCode(128|t<<2),i+=String.fromCharCode(r)):65536>r?(i+=String.fromCharCode(1|(128|t<<2)),i+=e.writeNumber(r,2)):(i+=String.fromCharCode(2|(128|t<<2)),i+=e.writeNumber(r,4)),i},read:function(t,r,i){if(null==t||r>=t.length||2>t.substring(r).length||0==(128&t[r].charCodeAt()))return e.print_error("Error during parsing. This message / key is probably not containing a valid OpenPGP format."),null;var n,s=r,o=-1,a=-1;a=0,0!=(64&t[s].charCodeAt())&&(a=1);var h;a?o=63&t[s].charCodeAt():(o=(63&t[s].charCodeAt())>>2,h=3&t[s].charCodeAt()),s++;var c=null,u=-1;if(a)if(192>t[s].charCodeAt())n=t[s++].charCodeAt(),e.print_debug("1 byte length:"+n);else if(t[s].charCodeAt()>=192&&224>t[s].charCodeAt())n=(t[s++].charCodeAt()-192<<8)+t[s++].charCodeAt()+192,e.print_debug("2 byte length:"+n);else if(t[s].charCodeAt()>223&&255>t[s].charCodeAt()){n=1<<(31&t[s++].charCodeAt()),e.print_debug("4 byte length:"+n);var p=s+n;for(c=t.substring(s,s+n);;){if(192>t[p].charCodeAt()){var l=t[p++].charCodeAt();n+=l,c+=t.substring(p,p+l),p+=l;break}if(t[p].charCodeAt()>=192&&224>t[p].charCodeAt()){var l=(t[p++].charCodeAt()-192<<8)+t[p++].charCodeAt()+192;n+=l,c+=t.substring(p,p+l),p+=l;break}if(!(t[p].charCodeAt()>223&&255>t[p].charCodeAt())){p++;var l=t[p++].charCodeAt()<<24|t[p++].charCodeAt()<<16|t[p++].charCodeAt()<<8|t[p++].charCodeAt();c+=t.substring(p,p+l),n+=l,p+=l;break}var l=1<<(31&t[p++].charCodeAt());n+=l,c+=t.substring(p,p+l),p+=l}u=p}else s++,n=t[s++].charCodeAt()<<24|t[s++].charCodeAt()<<16|t[s++].charCodeAt()<<8|t[s++].charCodeAt();else switch(h){case 0:n=t[s++].charCodeAt();break;case 1:n=t[s++].charCodeAt()<<8|t[s++].charCodeAt();break;case 2:n=t[s++].charCodeAt()<<24|t[s++].charCodeAt()<<16|t[s++].charCodeAt()<<8|t[s++].charCodeAt();break;default:n=i}return-1==u&&(u=n),null==c&&(c=t.substring(s,s+u)),{tag:o,packet:c,offset:s+u}}}},{"../enums.js":26,"../util":55}],39:[function(t,r){var e=t("./packet.js"),i=t("./all_packets.js"),n=t("../enums.js");r.exports=function s(){this.length=0,this.read=function(t){for(var r=0;t.length>r;){var s=e.read(t,r,t.length-r);r=s.offset;var o=n.read(n.packet,s.tag),a=new i[o];this.push(a),a.read(s.packet)}},this.write=function(){for(var t="",r=0;this.length>r;r++){var i=this[r].write();t+=e.writeHeader(this[r].tag,i.length),t+=i}return t},this.push=function(t){t.packets=new s,this[this.length]=t,this.length++}}},{"../enums.js":26,"./all_packets.js":32,"./packet.js":38}],40:[function(t,r){var e=t("../util"),i=t("../type/mpi.js"),n=t("../enums.js"),s=t("../crypto");r.exports=function(){this.created=new Date,this.mpi=[],this.algorithm="rsa_sign",this.readPublicKey=this.read=function(t){var r=t[0].charCodeAt();if(4==r){this.created=e.readDate(t.substr(1,4)),this.algorithm=n.read(n.publicKey,t[5].charCodeAt());var o=s.getPublicMpiCount(this.algorithm);this.mpi=[];for(var a=t.substr(6),h=0,c=0;o>c&&a.length>h;c++)this.mpi[c]=new i,h+=this.mpi[c].read(a.substr(h)),h>a.length&&e.print_error("openpgp.packet.keymaterial.js\nerror reading MPI @:"+h);return h+6}throw Error("Version "+r+" of the key packet is unsupported.")},this.writePublicKey=this.write=function(){var t=String.fromCharCode(4);t+=e.writeDate(this.created),t+=String.fromCharCode(n.write(n.publicKey,this.algorithm));for(var r=s.getPublicMpiCount(this.algorithm),i=0;r>i;i++)t+=this.mpi[i].write();return t},this.writeOld=function(){var t=this.writePublicKey();return String.fromCharCode(153)+e.writeNumber(t.length,2)+t},this.getKeyId=function(){return this.getFingerprint().substr(12,8)},this.getFingerprint=function(){var t=this.writeOld();return s.hash.sha1(t,t.length)}}},{"../crypto":15,"../enums.js":26,"../type/mpi.js":53,"../util":55}],41:[function(t,r){var e=t("../type/keyid.js"),i=t("../util"),n=t("../type/mpi.js"),s=t("../enums.js"),o=t("../crypto");r.exports=function(){this.version=3,this.publicKeyId=new e,this.publicKeyAlgorithm="rsa_encrypt",this.sessionKey=null,this.sessionKeyAlgorithm="aes256",this.encrypted=[],this.read=function(t){this.version=t[0].charCodeAt(),this.publicKeyId.read(t.substr(1)),this.publicKeyAlgorithm=s.read(s.publicKey,t[9].charCodeAt());var r=10,e=function(t){switch(t){case"rsa_encrypt":case"rsa_encrypt_sign":return 1;case"elgamal":return 2;default:throw Error("Invalid algorithm.")}}(this.publicKeyAlgorithm);this.encrypted=[];for(var i=0;e>i;i++){var o=new n;r+=o.read(t.substr(r)),this.encrypted.push(o)}},this.write=function(){var t=String.fromCharCode(this.version);t+=this.publicKeyId.write(),t+=String.fromCharCode(s.write(s.publicKey,this.publicKeyAlgorithm));for(var r=0;this.encrypted.length>r;r++)t+=this.encrypted[r].write();return t},this.encrypt=function(t){var r=String.fromCharCode(s.write(s.symmetric,this.sessionKeyAlgorithm));r+=this.sessionKey;var e=i.calc_checksum(this.sessionKey);r+=i.writeNumber(e,2);var a=new n;a.fromBytes(o.pkcs1.eme.encode(r,t.mpi[0].byteLength())),this.encrypted=o.publicKeyEncrypt(this.publicKeyAlgorithm,t.mpi,a)},this.decrypt=function(t){var r=o.publicKeyDecrypt(this.publicKeyAlgorithm,t.mpi,this.encrypted).toBytes(),e=i.readNumber(r.substr(r.length-2)),n=o.pkcs1.eme.decode(r,t.mpi[0].byteLength()),t=n.substring(1,n.length-2);if(e!=i.calc_checksum(t))throw Error("Checksum mismatch");this.sessionKey=t,this.sessionKeyAlgorithm=s.read(s.symmetric,n.charCodeAt(0))}}},{"../crypto":15,"../enums.js":26,"../type/keyid.js":52,"../type/mpi.js":53,"../util":55}],42:[function(t,r){var e=t("./public_key.js");r.exports=function(){e.call(this)}},{"./public_key.js":40}],43:[function(t,r){function e(){function t(t){return"sha1"==t?20:2}function r(t){return"sha1"==t?o.hash.sha1:function(t){return s.writeNumber(s.calc_checksum(t),2)}}function e(e,i,n){var s=t(e),h=r(e),c=i.substr(i.length-s);i=i.substr(0,i.length-s);var u=h(i);if(u!=c)throw Error("Hash mismatch.");for(var p=o.getPrivateMpiCount(n),l=0,f=[],d=0;p>d&&i.length>l;d++)f[d]=new a,l+=f[d].read(i.substr(l));return f}function c(t,e,i){for(var n="",s=o.getPublicMpiCount(e),a=s;i.length>a;a++)n+=i[a].write();return n+=r(t)(n)}function u(t,r,e){return t.produce_key(r,o.cipher[e].keySize)}i.call(this),this.encrypted=null,this.read=function(t){var r=this.readPublicKey(t);t=t.substr(r);var i=t[0].charCodeAt();i?this.encrypted=t:this.mpi=this.mpi.concat(e("mod",t.substr(1),this.algorithm))},this.write=function(){var t=this.writePublicKey();return this.encrypted?t+=this.encrypted:(t+=String.fromCharCode(0),t+=c("mod",this.algorithm,this.mpi)),t},this.encrypt=function(t){var r=new h,e="aes256",i=c("sha1",this.algorithm,this.mpi),s=u(r,t,e),a=o.cipher[e].blockSize,p=o.random.getRandomBytes(a);this.encrypted="",this.encrypted+=String.fromCharCode(254),this.encrypted+=String.fromCharCode(n.write(n.symmetric,e)),this.encrypted+=r.write(),this.encrypted+=p,this.encrypted+=o.cfb.normalEncrypt(e,s,i,p)},this.decrypt=function(t){if(this.encrypted){var r,i,s=0,a=this.encrypted[s++].charCodeAt();if(255==a||254==a){r=this.encrypted[s++].charCodeAt(),r=n.read(n.symmetric,r);var c=new h;s+=c.read(this.encrypted.substr(s)),i=u(c,t,r)}else r=a,r=n.read(n.symmetric,r),i=o.hash.md5(t);var p=this.encrypted.substr(s,o.cipher[r].blockSize);s+=p.length;var l,f=this.encrypted.substr(s);l=o.cfb.normalDecrypt(r,i,f,p);var d=254==a?"sha1":"mod";this.mpi=this.mpi.concat(e(d,l,this.algorithm))}},this.generate=function(t){this.mpi=o.generateMpi(this.algorithm,t)}}var i=t("./public_key.js"),n=t("../enums.js"),s=t("../util"),o=t("../crypto"),a=t("../type/mpi.js"),h=t("../type/s2k.js");e.prototype=new i,r.exports=e},{"../crypto":15,"../enums.js":26,"../type/mpi.js":53,"../type/s2k.js":54,"../util":55,"./public_key.js":40}],44:[function(t,r){var e=t("./secret_key.js");r.exports=function(){e.call(this)}},{"./secret_key.js":43}],45:[function(t,r){var e=t("../util"),i=t("./packet.js"),n=t("../enums.js"),s=t("../crypto"),o=t("../type/mpi.js");r.exports=function a(){this.signatureType=null,this.hashAlgorithm=null,this.publicKeyAlgorithm=null,this.signatureData=null,this.signedHashValue=null,this.mpi=null,this.created=null,this.signatureExpirationTime=null,this.signatureNeverExpires=null,this.exportable=null,this.trustLevel=null,this.trustAmount=null,this.regularExpression=null,this.revocable=null,this.keyExpirationTime=null,this.keyNeverExpires=null,this.preferredSymmetricAlgorithms=null,this.revocationKeyClass=null,this.revocationKeyAlgorithm=null,this.revocationKeyFingerprint=null,this.issuerKeyId=null,this.notation={},this.preferredHashAlgorithms=null,this.preferredCompressionAlgorithms=null,this.keyServerPreferences=null,this.preferredKeyServer=null,this.isPrimaryUserID=null,this.policyURI=null,this.keyFlags=null,this.signersUserId=null,this.reasonForRevocationFlag=null,this.reasonForRevocationString=null,this.signatureTargetPublicKeyAlgorithm=null,this.signatureTargetHashAlgorithm=null,this.signatureTargetHash=null,this.embeddedSignature=null,this.verified=!1,this.read=function(t){function r(t,r){for(var n=e.readNumber(t.substr(0,2)),s=2;2+n>s;){var o=i.readSimpleLength(t.substr(s));s+=o.offset,r&&this.read_sub_packet(t.substr(s,o.len)),s+=o.len}return s}var n=0,s=t[n++].charCodeAt();switch(s){case 3:5!=t[n++].charCodeAt()&&e.print_debug("openpgp.packet.signature.js\ninvalid One-octet length of following hashed material.MUST be 5. @:"+(n-1)),this.signatureType=t[n++].charCodeAt(),this.created=e.readDate(t.substr(n,4)),n+=4,this.signatureData=t.substring(position,n),this.issuerKeyId=t.substring(n,n+8),n+=8,this.publicKeyAlgorithm=t[n++].charCodeAt(),this.hashAlgorithm=t[n++].charCodeAt();break;case 4:this.signatureType=t[n++].charCodeAt(),this.publicKeyAlgorithm=t[n++].charCodeAt(),this.hashAlgorithm=t[n++].charCodeAt(),n+=r.call(this,t.substr(n),!0),this.signatureData=t.substr(0,n),n+=r.call(this,t.substr(n),!1);break;default:throw Error("Version "+s+" of the signature is unsupported.")}this.signedHashValue=t.substr(n,2),n+=2,this.signature=t.substr(n)},this.write=function(){return this.signatureData+e.writeNumber(0,2)+this.signedHashValue+this.signature},this.sign=function(t,r){var i=n.write(n.signature,this.signatureType),o=n.write(n.publicKey,this.publicKeyAlgorithm),a=n.write(n.hash,this.hashAlgorithm),h=String.fromCharCode(4);h+=String.fromCharCode(i),h+=String.fromCharCode(o),h+=String.fromCharCode(a),h+=e.writeNumber(0,2),this.signatureData=h;var c=this.calculateTrailer(),u=this.toSign(i,r)+this.signatureData+c,p=s.hash.digest(a,u);this.signedHashValue=p.substr(0,2),this.signature=s.signature.sign(a,o,t.mpi,u)},this.read_sub_packet=function(t){function r(t,r){this[t]=[];for(var e=0;r.length>e;e++)this[t].push(r[e].charCodeAt())}var i=0,n=127&t[i++].charCodeAt();switch(n){case 2:this.created=e.readDate(t.substr(i));break;case 3:var o=e.readDate(t.substr(i));this.signatureNeverExpires=0==o.getTime(),this.signatureExpirationTime=o;break;case 4:this.exportable=1==t[i++].charCodeAt();break;case 5:this.trustLevel=t[i++].charCodeAt(),this.trustAmount=t[i++].charCodeAt();break;case 6:this.regularExpression=t.substr(i);break;case 7:this.revocable=1==t[i++].charCodeAt();break;case 9:var o=e.readDate(t.substr(i));this.keyExpirationTime=o,this.keyNeverExpires=0==o.getTime();break;case 11:for(this.preferredSymmetricAlgorithms=[];i!=t.length;)this.preferredSymmetricAlgorithms.push(t[i++].charCodeAt());break;case 12:this.revocationKeyClass=t[i++].charCodeAt(),this.revocationKeyAlgorithm=t[i++].charCodeAt(),this.revocationKeyFingerprint=t.substr(i,20);break;case 16:this.issuerKeyId=t.substr(i,8);break;case 20:if(128!=t[i].charCodeAt())throw Error("Unsupported notation flag.");i+=4;var h=e.writeNumber(t.substr(i,2));i+=2;var c=e.writeNumber(t.substr(i,2));i+=2;var u=t.substr(i,h),p=t.substr(i+h,c);this.notation[u]=p;break;case 21:r.call(this,"preferredHashAlgorithms",t.substr(i));break;case 22:r.call(this,"preferredCompressionAlgorithms ",t.substr(i));break;case 23:r.call(this,"keyServerPreferencess",t.substr(i));break;case 24:this.preferredKeyServer=t.substr(i);break;case 25:this.isPrimaryUserID=0!=t[i++];break;case 26:this.policyURI=t.substr(i);break;case 27:r.call(this,"keyFlags",t.substr(i));break;case 28:this.signersUserId+=t.substr(i);break;case 29:this.reasonForRevocationFlag=t[i++].charCodeAt(),this.reasonForRevocationString=t.substr(i);break;case 30:r.call(this,"features",t.substr(i));break;case 31:this.signatureTargetPublicKeyAlgorithm=t[i++].charCodeAt(),this.signatureTargetHashAlgorithm=t[i++].charCodeAt();var l=s.getHashByteLength(this.signatureTargetHashAlgorithm);this.signatureTargetHash=t.substr(i,l);break;case 32:this.embeddedSignature=new a,this.embeddedSignature.read(t.substr(i));break;default:e.print_error("openpgp.packet.signature.js\nunknown signature subpacket type "+n+" @:"+i+" subplen:"+subplen+" len:"+l)}},this.toSign=function(t,r){var i=n.signature;switch(t){case i.binary:return r.getBytes();case i.text:return this.toSign(i.binary,r).replace(/\r\n/g,"\n").replace(/\n/g,"\r\n");case i.standalone:return"";case i.cert_generic:case i.cert_persona:case i.cert_casual:case i.cert_positive:case i.cert_revocation:var s,o;if(void 0!==r.userid)o=180,s=r.userid;else{if(void 0===r.userattribute)throw Error("Either a userid or userattribute packet needs to be supplied for certification.");o=209,s=r.userattribute}var a=s.write();return this.toSign(i.key,r)+String.fromCharCode(o)+e.writeNumber(a.length,4)+a;case i.subkey_binding:case i.key_binding:return this.toSign(i.key,r)+this.toSign(i.key,{key:r.bind});case i.key:if(void 0==r.key)throw Error("Key packet is required for this sigtature.");return r.key.writeOld();case i.key_revocation:case i.subkey_revocation:return this.toSign(i.key,r);case i.timestamp:return"";case i.thrid_party:throw Error("Not implemented");default:throw Error("Unknown signature type.")}},this.calculateTrailer=function(){var t="";return t+=String.fromCharCode(4),t+=String.fromCharCode(255),t+=e.writeNumber(this.signatureData.length,4)},this.verify=function(t,r){var e=n.write(n.signature,this.signatureType),i=n.write(n.publicKey,this.publicKeyAlgorithm),a=n.write(n.hash,this.hashAlgorithm),h=this.toSign(e,r),c=this.calculateTrailer(),u=0;i>0&&4>i?u=1:17==i&&(u=2);for(var p=[],l=0,f=0;u>f;f++)p[f]=new o,l+=p[f].read(this.signature.substr(l));return this.verified=s.signature.verify(i,a,p,t.mpi,h+this.signatureData+c),this.verified}}},{"../crypto":15,"../enums.js":26,"../type/mpi.js":53,"../util":55,"./packet.js":38}],46:[function(t,r){var e=(t("../util"),t("../crypto"));r.exports=function(){this.encrypted=null,this.modification=!1,this.packets,this.read=function(t){var r=t[0].charCodeAt();if(1!=r)throw Error("Invalid packet version.");this.encrypted=t.substr(1)},this.write=function(){return String.fromCharCode(1)+this.encrypted},this.encrypt=function(t,r){var i=this.packets.write(),n=e.getPrefixRandom(t),s=n+n.charAt(n.length-2)+n.charAt(n.length-1),o=i;o+=String.fromCharCode(211),o+=String.fromCharCode(20),o+=e.hash.sha1(s+o),this.encrypted=e.cfb.encrypt(n,t,o,r,!1).substring(0,s.length+o.length)},this.decrypt=function(t,r){var i=e.cfb.decrypt(t,r,this.encrypted,!1);this.hash=e.hash.sha1(e.cfb.mdc(t,r,this.encrypted)+i.substring(0,i.length-20));var n=i.substr(i.length-20,20);if(this.hash!=n)throw Error("Modification detected.");this.packets.read(i.substr(0,i.length-22))}}},{"../crypto":15,"../util":55}],47:[function(t,r){var e=t("../type/s2k.js"),i=t("../enums.js"),n=t("../crypto");r.exports=function(){this.tag=3,this.sessionKeyEncryptionAlgorithm=null,this.sessionKeyAlgorithm="aes256",this.encrypted=null,this.s2k=new e,this.read=function(t){this.version=t[0].charCodeAt();var r=i.read(i.symmetric,t[1].charCodeAt()),e=this.s2k.read(t.substr(2)),n=e+2;t.length>n?(this.encrypted=t.substr(n),this.sessionKeyEncryptionAlgorithm=r):this.sessionKeyAlgorithm=r},this.write=function(){var t=null==this.encrypted?this.sessionKeyAlgorithm:this.sessionKeyEncryptionAlgorithm,r=String.fromCharCode(this.version)+String.fromCharCode(i.write(i.symmetric,t))+this.s2k.write();return null!=this.encrypted&&(r+=this.encrypted),r},this.decrypt=function(t){var r=null!=this.sessionKeyEncryptionAlgorithm?this.sessionKeyEncryptionAlgorithm:this.sessionKeyAlgorithm,e=n.cipher[r].keySize,s=this.s2k.produce_key(t,e);if(null==this.encrypted)this.sessionKey=s;else{var o=n.cfb.decrypt(this.sessionKeyEncryptionAlgorithm,s,this.encrypted,!0);this.sessionKeyAlgorithm=i.read(i.symmetric,o[0].keyCodeAt()),this.sessionKey=o.substr(1)}},this.encrypt=function(t){var r=n.getKeyLength(this.sessionKeyEncryptionAlgorithm),e=this.s2k.produce_key(t,r),s=String.fromCharCode(i.write(i.symmetric,this.sessionKeyAlgorithm))+n.getRandomBytes(n.getKeyLength(this.sessionKeyAlgorithm));this.encrypted=n.cfb.encrypt(n.getPrefixRandom(this.sessionKeyEncryptionAlgorithm),this.sessionKeyEncryptionAlgorithm,e,s,!0)}}},{"../crypto":15,"../enums.js":26,"../type/s2k.js":54}],48:[function(t,r){var e=t("../crypto");r.exports=function(){this.encrypted=null,this.packets,this.read=function(t){this.encrypted=t},this.write=function(){return this.encrypted},this.decrypt=function(t,r){var i=e.cfb.decrypt(t,r,this.encrypted,!0);this.packets.read(i)},this.encrypt=function(t,r){var i=this.packets.write();this.encrypted=e.cfb.encrypt(e.getPrefixRandom(t),t,i,r,!0)}}},{"../crypto":15}],49:[function(t,r){r.exports=function(){}},{}],50:[function(t,r){r.exports=function(){this.tag=17,this.attributes=[],this.read=function(t){for(var r=0;t.length>r;){var e=openpgp_packet.read_simple_length(t);r+=e.offset,this.attributes.push(t.substr(r,e.len)),r+=e.len}}}},{}],51:[function(t,r){var e=t("../util");r.exports=function(){this.userid="",this.read=function(t){this.userid=e.decode_utf8(t)},this.write=function(){return e.encode_utf8(this.userid)}}},{"../util":55}],52:[function(t,r){r.exports=function(){for(var t="",r=0;8>r;r++)t+=String.fromCharCode(0);this.read=function(t){this.bytes=t.substr(0,8)},this.write=function(){return this.bytes}}},{}],53:[function(t,r){var e=t("../crypto/public_key/jsbn.js"),i=t("../util");r.exports=function(){this.data=null,this.read=function(t){var r=t[0].charCodeAt()<<8|t[1].charCodeAt(),e=Math.ceil(r/8),i=t.substr(2,e);return this.fromBytes(i),2+e},this.fromBytes=function(t){this.data=new e(i.hexstrdump(t),16)},this.toBytes=function(){return this.write().substr(2)},this.byteLength=function(){return this.toBytes().length},this.write=function(){return this.data.toMPI()},this.toBigInteger=function(){return this.data.clone()},this.fromBigInteger=function(t){this.data=t.clone()}}},{"../crypto/public_key/jsbn.js":20,"../util":55}],54:[function(t,r){var e=t("../enums.js"),i=t("../util"),n=t("../crypto");r.exports=function(){this.algorithm="sha256",this.type="iterated",this.c=96,this.salt=n.random.getRandomBytes(8);var t=6;this.get_count=function(){return 16+(15&this.c)<<(this.c>>4)+t},this.read=function(t){var r=0;switch(this.type=e.read(e.s2k,t[r++].charCodeAt()),this.algorithm=e.read(e.hash,t[r++].charCodeAt()),this.type){case"simple":break;case"salted":this.salt=t.substr(r,8),r+=8;break;case"iterated":this.salt=t.substr(r,8),r+=8,this.c=t[r++].charCodeAt();break;case"gnu":if("GNU"!=t.substr(r,3))throw Error("Unknown s2k type.");r+=3;var i=1e3+t[r++].charCodeAt(); +if(1001!=i)throw Error("Unknown s2k gnu protection mode.");this.type=i;break;default:throw Error("Unknown s2k type.")}return r},this.write=function(){var t=String.fromCharCode(e.write(e.s2k,this.type));switch(t+=String.fromCharCode(e.write(e.hash,this.algorithm)),this.type){case"simple":break;case"salted":t+=this.salt;break;case"iterated":t+=this.salt,t+=String.fromCharCode(this.c)}return t},this.produce_key=function(t,r){function s(r,i){var s=e.write(e.hash,i.algorithm);switch(i.type){case"simple":return n.hash.digest(s,r+t);case"salted":return n.hash.digest(s,r+i.salt+t);case"iterated":var o=[],a=i.get_count();for(data=i.salt+t;a>o.length*data.length;)o.push(data);return o=o.join(""),o.length>a&&(o=o.substr(0,a)),n.hash.digest(s,r+o)}}t=i.encode_utf8(t);for(var o="",a="";r>=o.length;)o+=s(a,this),a+=String.fromCharCode(0);return o.substr(0,r)}}},{"../crypto":15,"../enums.js":26,"../util":55}],55:[function(t,r){var e=function(){this.readNumber=function(t){for(var r=0,e=0;t.length>e;e++)r<<=8,r+=t[e].charCodeAt();return r},this.writeNumber=function(t,r){for(var e="",i=0;r>i;i++)e+=String.fromCharCode(255&t>>8*(r-i-1));return e},this.readDate=function(t){var r=this.readNumber(t),e=new Date;return e.setTime(1e3*r),e},this.writeDate=function(t){var r=Math.round(t.getTime()/1e3);return this.writeNumber(r,4)},this.emailRegEx=/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/,this.debug=!1,this.hexdump=function(t){for(var r,e=[],i=t.length,n=0,s=0;i>n;){for(r=t.charCodeAt(n++).toString(16);2>r.length;)r="0"+r;e.push(" "+r),s++,0==s%32&&e.push("\n ")}return e.join("")},this.hexstrdump=function(t){if(null==t)return"";for(var r,e=[],i=t.length,n=0;i>n;){for(r=t[n++].charCodeAt().toString(16);2>r.length;)r="0"+r;e.push(""+r)}return e.join("")},this.hex2bin=function(t){for(var r="",e=0;t.length>e;e+=2)r+=String.fromCharCode(parseInt(t.substr(e,2),16));return r},this.hexidump=function(t){for(var r,e=[],i=t.length,n=0;i>n;){for(r=t[n++].toString(16);2>r.length;)r="0"+r;e.push(""+r)}return e.join("")},this.encode_utf8=function(t){return unescape(encodeURIComponent(t))},this.decode_utf8=function(t){return decodeURIComponent(escape(t))};var t=function(t,r){for(var e=0;t.length>e;e++)r[e]=t.charCodeAt(e);return r},r=function(t){for(var r=[],e=0;t.length>e;e++)r.push(String.fromCharCode(t[e]));return r.join("")};this.str2bin=function(r){return t(r,Array(r.length))},this.bin2str=r,this.str2Uint8Array=function(r){return t(r,new Uint8Array(new ArrayBuffer(r.length)))},this.Uint8Array2str=r,this.calc_checksum=function(t){for(var r={s:0,add:function(t){this.s=(this.s+t)%65536}},e=0;t.length>e;e++)r.add(t.charCodeAt(e));return r.s},this.print_debug=function(t){this.debug&&console.log(t)},this.print_debug_hexstr_dump=function(t,r){this.debug&&(t+=this.hexstrdump(r),console.log(t))},this.print_error=function(t){if(this.debug)throw t;console.log(t)},this.print_info=function(t){this.debug&&console.log(t)},this.print_warning=function(t){console.log(t)},this.getLeftNBits=function(t,r){var e=r%8;if(0==e)return t.substring(0,r/8);var i=(r-e)/8+1,n=t.substring(0,i);return this.shiftRight(n,8-e)},this.shiftRight=function(t,r){var e=util.str2bin(t);if(0==r%8)return t;for(var i=e.length-1;i>=0;i--)e[i]>>=r%8,i>0&&(e[i]|=255&e[i-1]<<8-r%8);return util.bin2str(e)},this.get_hashAlgorithmString=function(t){switch(t){case 1:return"MD5";case 2:return"SHA1";case 3:return"RIPEMD160";case 8:return"SHA256";case 9:return"SHA384";case 10:return"SHA512";case 11:return"SHA224"}return"unknown"}};r.exports=new e},{}]},{},[1,2,3,4,5,6,7,8,9,10,11,13,14,12,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55]); \ No newline at end of file diff --git a/src/crypto/crypto.js b/src/crypto/crypto.js index 30bd0aa8..aee203e5 100644 --- a/src/crypto/crypto.js +++ b/src/crypto/crypto.js @@ -164,6 +164,35 @@ module.exports = { } }, + generateMpi: function(algo, bits) { + var result = (function() { + switch (algo) { + case 'rsa_encrypt': + case 'rsa_encrypt_sign': + case 'rsa_sign': + //remember "publicKey" refers to the crypto/public_key dir + var rsa = new publicKey.rsa(); + var keyObject = rsa.generate(bits, "10001"); + var output = []; + output.push(keyObject.n); + output.push(keyObject.ee); + output.push(keyObject.d); + output.push(keyObject.p); + output.push(keyObject.q); + output.push(keyObject.u); + return output; + default: + throw new Error('Unsupported algorithm for key generation.'); + } + })(); + + return result.map(function(bn) { + var mpi = new type_mpi(); + mpi.fromBigInteger(bn); + return mpi; + }); + }, + /** * generate random byte prefix as string for the specified algorithm diff --git a/src/openpgp.js b/src/openpgp.js index 3a8c5f58..ac203721 100644 --- a/src/openpgp.js +++ b/src/openpgp.js @@ -24,6 +24,7 @@ var armor = require('./encoding/armor.js'); var packet = require('./packet'); var util = require('./util'); +var enums = require('./enums.js'); /** * GPG4Browsers Core interface. A single instance is hold @@ -104,11 +105,22 @@ function _openpgp() { var packetlist = new packet.list(); var secretKeyPacket = new packet.secret_key(); + secretKeyPacket.algorithm = enums.read(enums.publicKey, keyType); + secretKeyPacket.generate(numBits); + secretKeyPacket.encrypt(passphrase); + var userIdPacket = new packet.userid(); + userIdPacket.read(userId); + var signaturePacket = new packet.signature(); var secretSubkeyPacket = new packet.secret_subkey(); var overallSignaturePacket = new packet.signature(); + packetlist.push(secretKeyPacket); + packetlist.push(userIdPacket); + packetlist.push(signaturePacket); + packetlist.push(secretSubkeyPacket); + packetlist.push(overallSignaturePacket); } /** diff --git a/src/packet/secret_key.js b/src/packet/secret_key.js index faa3fc0f..858ba5ab 100644 --- a/src/packet/secret_key.js +++ b/src/packet/secret_key.js @@ -50,7 +50,7 @@ function packet_secret_key() { else return function(c) { return util.writeNumber(util.calc_checksum(c), 2); - } + }; } // Helper function @@ -129,7 +129,7 @@ function packet_secret_key() { this.algorithm)); } - } + }; /* * Creates an OpenPGP key packet for the given key. much @@ -156,7 +156,7 @@ function packet_secret_key() { } return bytes; - } + }; @@ -181,10 +181,8 @@ function packet_secret_key() { this.encrypted += s2k.write(); this.encrypted += iv; - - this.encrypted += crypto.cfb.normalEncrypt(symmetric, key, cleartext, iv); - } + }; function produceEncryptionKey(s2k, passphrase, algorithm) { return s2k.produce_key(passphrase, @@ -251,12 +249,11 @@ function packet_secret_key() { this.mpi = this.mpi.concat(parse_cleartext_mpi(hash, cleartext, this.algorithm)); - } + }; - this.generate = function(bits) { - this.mpi; - - } + this.generate = function(bits, passphrase) { + this.mpi = crypto.generateMpi(this.algorithm, bits); + }; } diff --git a/src/packet/signature.js b/src/packet/signature.js index d3d8326f..f065e41a 100644 --- a/src/packet/signature.js +++ b/src/packet/signature.js @@ -393,7 +393,7 @@ module.exports = function packet_signature() { // Produces data to produce signature on this.toSign = function(type, data) { - var t = enums.signature + var t = enums.signature; switch (type) { case t.binary: @@ -405,7 +405,7 @@ module.exports = function packet_signature() { .replace(/\n/g, '\r\n'); case t.standalone: - return '' + return ''; case t.cert_generic: case t.cert_persona: @@ -415,19 +415,17 @@ module.exports = function packet_signature() { { var packet, tag; - if (data.userid != undefined) { + if (data.userid !== undefined) { tag = 0xB4; packet = data.userid; - } else if (data.userattribute != undefined) { - tag = 0xD1 + } else if (data.userattribute !== undefined) { + tag = 0xD1; packet = data.userattribute; } else throw new Error('Either a userid or userattribute packet needs to be ' + 'supplied for certification.'); - var bytes = packet.write(); - return this.toSign(t.key, data) + String.fromCharCode(tag) + util.writeNumber(bytes.length, 4) + diff --git a/test/test-bundle.js b/test/test-bundle.js index 9a11f9b9..a01934d4 100644 --- a/test/test-bundle.js +++ b/test/test-bundle.js @@ -1,6 +1,14 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o"); - return bA[bytepos++]; - } else - return -1; - }; - function byteAlign(){ - bb = 1; - }; - - function readBit(){ - var carry; - bits++; - carry = (bb & 1); - bb >>= 1; - if (bb==0){ - bb = readByte(); - carry = (bb & 1); - bb = (bb>>1) | 0x80; - } - return carry; - }; + function readByte() { + bits += 8; + if (bytepos < bA.length) { + //if (debug) + // document.write(bytepos+": "+bA[bytepos]+"
"); + return bA[bytepos++]; + } else + return -1; + }; - function readBits(a) { - var res = 0, - i = a; - - while(i--) { - res = (res<<1) | readBit(); - } - if(a) { - res = bitReverse[res]>>(8-a); - } - return res; - }; - - function flushBuffer(){ - //document.write('FLUSHBUFFER:'+buf32k); - bIdx = 0; - }; - function addBuffer(a){ - SIZE++; - //CRC=updcrc(a,crc); - buf32k[bIdx++] = a; - outputArr.push(String.fromCharCode(a)); - //output+=String.fromCharCode(a); - if(bIdx==0x8000){ - //document.write('ADDBUFFER:'+buf32k); - bIdx=0; - } - }; - - function HufNode() { - this.b0=0; - this.b1=0; - this.jump = null; - this.jumppos = -1; - }; + function byteAlign() { + bb = 1; + }; - var LITERALS = 288; - - var literalTree = new Array(LITERALS); - var distanceTree = new Array(32); - var treepos=0; - var Places = null; - var Places2 = null; - - var impDistanceTree = new Array(64); - var impLengthTree = new Array(64); - - var len = 0; - var fpos = new Array(17); - fpos[0]=0; - var flens; - var fmax; - - function IsPat() { - while (1) { - if (fpos[len] >= fmax) - return -1; - if (flens[fpos[len]] == len) - return fpos[len]++; - fpos[len]++; - } - }; + function readBit() { + var carry; + bits++; + carry = (bb & 1); + bb >>= 1; + if (bb == 0) { + bb = readByte(); + carry = (bb & 1); + bb = (bb >> 1) | 0x80; + } + return carry; + }; - function Rec() { - var curplace = Places[treepos]; - var tmp; - if (debug) - document.write("
len:"+len+" treepos:"+treepos); - if(len==17) { //war 17 - return -1; - } - treepos++; - len++; - - tmp = IsPat(); - if (debug) - document.write("
IsPat "+tmp); - if(tmp >= 0) { - curplace.b0 = tmp; /* leaf cell for 0-bit */ - if (debug) - document.write("
b0 "+curplace.b0); - } else { - /* Not a Leaf cell */ - curplace.b0 = 0x8000; - if (debug) - document.write("
b0 "+curplace.b0); - if(Rec()) - return -1; - } - tmp = IsPat(); - if(tmp >= 0) { - curplace.b1 = tmp; /* leaf cell for 1-bit */ - if (debug) - document.write("
b1 "+curplace.b1); - curplace.jump = null; /* Just for the display routine */ - } else { - /* Not a Leaf cell */ - curplace.b1 = 0x8000; - if (debug) - document.write("
b1 "+curplace.b1); - curplace.jump = Places[treepos]; - curplace.jumppos = treepos; - if(Rec()) - return -1; - } - len--; - return 0; - }; + function readBits(a) { + var res = 0, + i = a; - function CreateTree(currentTree, numval, lengths, show) { - var i; - /* Create the Huffman decode tree/table */ - //document.write("
createtree
"); - if (debug) - document.write("currentTree "+currentTree+" numval "+numval+" lengths "+lengths+" show "+show); - Places = currentTree; - treepos=0; - flens = lengths; - fmax = numval; - for (i=0;i<17;i++) - fpos[i] = 0; - len = 0; - if(Rec()) { - //fprintf(stderr, "invalid huffman tree\n"); - if (debug) - alert("invalid huffman tree\n"); - return -1; - } - if (debug){ - document.write('
Tree: '+Places.length); - for (var a=0;a<32;a++){ - document.write("Places["+a+"].b0="+Places[a].b0+"
"); - document.write("Places["+a+"].b1="+Places[a].b1+"
"); - } - } - - /*if(show) { + while (i--) { + res = (res << 1) | readBit(); + } + if (a) { + res = bitReverse[res] >> (8 - a); + } + return res; + }; + + function flushBuffer() { + //document.write('FLUSHBUFFER:'+buf32k); + bIdx = 0; + }; + + function addBuffer(a) { + SIZE++; + //CRC=updcrc(a,crc); + buf32k[bIdx++] = a; + outputArr.push(String.fromCharCode(a)); + //output+=String.fromCharCode(a); + if (bIdx == 0x8000) { + //document.write('ADDBUFFER:'+buf32k); + bIdx = 0; + } + }; + + function HufNode() { + this.b0 = 0; + this.b1 = 0; + this.jump = null; + this.jumppos = -1; + }; + + var LITERALS = 288; + + var literalTree = new Array(LITERALS); + var distanceTree = new Array(32); + var treepos = 0; + var Places = null; + var Places2 = null; + + var impDistanceTree = new Array(64); + var impLengthTree = new Array(64); + + var len = 0; + var fpos = new Array(17); + fpos[0] = 0; + var flens; + var fmax; + + function IsPat() { + while (1) { + if (fpos[len] >= fmax) + return -1; + if (flens[fpos[len]] == len) + return fpos[len]++; + fpos[len]++; + } + }; + + function Rec() { + var curplace = Places[treepos]; + var tmp; + if (debug) + document.write("
len:" + len + " treepos:" + treepos); + if (len == 17) { //war 17 + return -1; + } + treepos++; + len++; + + tmp = IsPat(); + if (debug) + document.write("
IsPat " + tmp); + if (tmp >= 0) { + curplace.b0 = tmp; /* leaf cell for 0-bit */ + if (debug) + document.write("
b0 " + curplace.b0); + } else { + /* Not a Leaf cell */ + curplace.b0 = 0x8000; + if (debug) + document.write("
b0 " + curplace.b0); + if (Rec()) + return -1; + } + tmp = IsPat(); + if (tmp >= 0) { + curplace.b1 = tmp; /* leaf cell for 1-bit */ + if (debug) + document.write("
b1 " + curplace.b1); + curplace.jump = null; /* Just for the display routine */ + } else { + /* Not a Leaf cell */ + curplace.b1 = 0x8000; + if (debug) + document.write("
b1 " + curplace.b1); + curplace.jump = Places[treepos]; + curplace.jumppos = treepos; + if (Rec()) + return -1; + } + len--; + return 0; + }; + + function CreateTree(currentTree, numval, lengths, show) { + var i; + /* Create the Huffman decode tree/table */ + //document.write("
createtree
"); + if (debug) + document.write("currentTree " + currentTree + " numval " + numval + " lengths " + lengths + " show " + show); + Places = currentTree; + treepos = 0; + flens = lengths; + fmax = numval; + for (i = 0; i < 17; i++) + fpos[i] = 0; + len = 0; + if (Rec()) { + //fprintf(stderr, "invalid huffman tree\n"); + if (debug) + alert("invalid huffman tree\n"); + return -1; + } + if (debug) { + document.write('
Tree: ' + Places.length); + for (var a = 0; a < 32; a++) { + document.write("Places[" + a + "].b0=" + Places[a].b0 + "
"); + document.write("Places[" + a + "].b1=" + Places[a].b1 + "
"); + } + } + + /*if(show) { var tmp; for(tmp=currentTree;tmpjump?tmp->jump-currentTree:0,(tmp->jump?tmp->jump-currentTree:0)*6+0xcf0); @@ -304,109 +314,109 @@ JXG.Util.Unzip = function (barray){ fprintf(stdout, "\n"); } }*/ - return 0; - }; - - function DecodeValue(currentTree) { - var len, i, - xtreepos=0, - X = currentTree[xtreepos], - b; + return 0; + }; - /* decode one symbol of the data */ - while(1) { - b=readBit(); - if (debug) - document.write("b="+b); - if(b) { - if(!(X.b1 & 0x8000)){ - if (debug) - document.write("ret1"); - return X.b1; /* If leaf node, return data */ - } - X = X.jump; - len = currentTree.length; - for (i=0;i>1); - if(j > 23) { - j = (j<<1) | readBit(); /* 48..255 */ + j = (bitReverse[readBits(7)] >> 1); + if (j > 23) { + j = (j << 1) | readBit(); /* 48..255 */ - if(j > 199) { /* 200..255 */ - j -= 128; /* 72..127 */ - j = (j<<1) | readBit(); /* 144..255 << */ - } else { /* 48..199 */ - j -= 48; /* 0..151 */ - if(j > 143) { - j = j+136; /* 280..287 << */ - /* 0..143 << */ - } - } - } else { /* 0..23 */ - j += 256; /* 256..279 << */ + if (j > 199) { /* 200..255 */ + j -= 128; /* 72..127 */ + j = (j << 1) | readBit(); /* 144..255 << */ + } else { /* 48..199 */ + j -= 48; /* 0..151 */ + if (j > 143) { + j = j + 136; /* 280..287 << */ + /* 0..143 << */ + } } - if(j < 256) { - addBuffer(j); - //document.write("out:"+String.fromCharCode(j)); - /*fprintf(errfp, "@%d %02x\n", SIZE, j);*/ - } else if(j == 256) { - /* EOF */ - break; + } else { /* 0..23 */ + j += 256; /* 256..279 << */ + } + if (j < 256) { + addBuffer(j); + //document.write("out:"+String.fromCharCode(j)); + /*fprintf(errfp, "@%d %02x\n", SIZE, j);*/ + } else if (j == 256) { + /* EOF */ + break; + } else { + var len, dist; + + j -= 256 + 1; /* bytes + EOF */ + len = readBits(cplext[j]) + cplens[j]; + + j = bitReverse[readBits(5)] >> 3; + if (cpdext[j] > 8) { + dist = readBits(8); + dist |= (readBits(cpdext[j] - 8) << 8); } else { - var len, dist; + dist = readBits(cpdext[j]); + } + dist += cpdist[j]; - j -= 256 + 1; /* bytes + EOF */ - len = readBits(cplext[j]) + cplens[j]; + /*fprintf(errfp, "@%d (l%02x,d%04x)\n", SIZE, len, dist);*/ + for (j = 0; j < len; j++) { + var c = buf32k[(bIdx - dist) & 0x7fff]; + addBuffer(c); + } + } + } // while + } else if (type == 2) { + var j, n, literalCodes, distCodes, lenCodes; + var ll = new Array(288 + 32); // "static" just to preserve stack - j = bitReverse[readBits(5)]>>3; - if(cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j]-8)<<8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; + // Dynamic Huffman tables - /*fprintf(errfp, "@%d (l%02x,d%04x)\n", SIZE, len, dist);*/ - for(j=0;jparam: "+literalCodes+" "+distCodes+" "+lenCodes+"
"); - for(j=0; j<19; j++) { - ll[j] = 0; - } - - // Get the decode tree code lengths - - //document.write("
"); - for(j=0; jll:'+ll); - len = distanceTree.length; - for (i=0; idistanceTree"); - for(var a=0;a"+distanceTree[a].b0+" "+distanceTree[a].b1+" "+distanceTree[a].jump+" "+distanceTree[a].jumppos); - /*if (distanceTree[a].jumppos!=-1) + literalCodes = 257 + readBits(5); + distCodes = 1 + readBits(5); + lenCodes = 4 + readBits(4); + //document.write("
param: "+literalCodes+" "+distCodes+" "+lenCodes+"
"); + for (j = 0; j < 19; j++) { + ll[j] = 0; + } + + // Get the decode tree code lengths + + //document.write("
"); + for (j = 0; j < lenCodes; j++) { + ll[border[j]] = readBits(3); + //document.write(ll[border[j]]+" "); + } + //fprintf(errfp, "\n"); + //document.write('
ll:'+ll); + len = distanceTree.length; + for (i = 0; i < len; i++) + distanceTree[i] = new HufNode(); + if (CreateTree(distanceTree, 19, ll, 0)) { + flushBuffer(); + return 1; + } + if (debug) { + document.write("
distanceTree"); + for (var a = 0; a < distanceTree.length; a++) { + document.write("
" + distanceTree[a].b0 + " " + distanceTree[a].b1 + " " + distanceTree[a].jump + " " + + distanceTree[a].jumppos); + /*if (distanceTree[a].jumppos!=-1) document.write(" "+distanceTree[a].jump.b0+" "+distanceTree[a].jump.b1); */ - } + } + } + //document.write('
tree created'); + + //read in literal and distance code lengths + n = literalCodes + distCodes; + i = 0; + var z = -1; + if (debug) + document.write("
n=" + n + " bits: " + bits + "
"); + while (i < n) { + z++; + j = DecodeValue(distanceTree); + if (debug) + document.write("
" + z + " i:" + i + " decode: " + j + " bits " + bits + "
"); + if (j < 16) { // length of code in bits (0..15) + ll[i++] = j; + } else if (j == 16) { // repeat last length 3 to 6 times + var l; + j = 3 + readBits(2); + if (i + j > n) { + flushBuffer(); + return 1; } - //document.write('
tree created'); - - //read in literal and distance code lengths - n = literalCodes + distCodes; - i = 0; - var z=-1; - if (debug) - document.write("
n="+n+" bits: "+bits+"
"); - while(i < n) { - z++; - j = DecodeValue(distanceTree); - if (debug) - document.write("
"+z+" i:"+i+" decode: "+j+" bits "+bits+"
"); - if(j<16) { // length of code in bits (0..15) - ll[i++] = j; - } else if(j==16) { // repeat last length 3 to 6 times - var l; - j = 3 + readBits(2); - if(i+j > n) { - flushBuffer(); - return 1; - } - l = i ? ll[i-1] : 0; - while(j--) { - ll[i++] = l; - } - } else { - if(j==17) { // 3 to 10 zero length codes - j = 3 + readBits(3); - } else { // j == 18: 11 to 138 zero length codes - j = 11 + readBits(7); - } - if(i+j > n) { - flushBuffer(); - return 1; - } - while(j--) { - ll[i++] = 0; - } - } + l = i ? ll[i - 1] : 0; + while (j--) { + ll[i++] = l; } - /*for(j=0; j n) { + flushBuffer(); + return 1; + } + while (j--) { + ll[i++] = 0; + } + } + } + /*for(j=0; jliteralTree"); - outer: - while(1) { - j = DecodeValue(literalTree); - if(j >= 256) { // In C64: if carry set - var len, dist; - j -= 256; - if(j == 0) { - // EOF - break; - } - j--; - len = readBits(cplext[j]) + cplens[j]; - - j = DecodeValue(distanceTree); - if(cpdext[j] > 8) { - dist = readBits(8); - dist |= (readBits(cpdext[j]-8)<<8); - } else { - dist = readBits(cpdext[j]); - } - dist += cpdist[j]; - while(len--) { - if(bIdx - dist < 0) { - break outer; - } - var c = buf32k[(bIdx - dist) & 0x7fff]; - addBuffer(c); - } - } else { - addBuffer(j); - } - } + // Can overwrite tree decode tree as it is not used anymore + len = literalTree.length; + for (i = 0; i < len; i++) + literalTree[i] = new HufNode(); + if (CreateTree(literalTree, literalCodes, ll, 0)) { + flushBuffer(); + return 1; } - } while(!last); + len = literalTree.length; + for (i = 0; i < len; i++) + distanceTree[i] = new HufNode(); + var ll2 = new Array(); + for (i = literalCodes; i < ll.length; i++) { + ll2[i - literalCodes] = ll[i]; + } + if (CreateTree(distanceTree, distCodes, ll2, 0)) { + flushBuffer(); + return 1; + } + if (debug) + document.write("
literalTree"); + outer: while (1) { + j = DecodeValue(literalTree); + if (j >= 256) { // In C64: if carry set + var len, dist; + j -= 256; + if (j == 0) { + // EOF + break; + } + j--; + len = readBits(cplext[j]) + cplens[j]; + + j = DecodeValue(distanceTree); + if (cpdext[j] > 8) { + dist = readBits(8); + dist |= (readBits(cpdext[j] - 8) << 8); + } else { + dist = readBits(cpdext[j]); + } + dist += cpdist[j]; + while (len--) { + if (bIdx - dist < 0) { + break outer; + } + var c = buf32k[(bIdx - dist) & 0x7fff]; + addBuffer(c); + } + } else { + addBuffer(j); + } + } + } + } while (!last); flushBuffer(); byteAlign(); return 0; -}; - -JXG.Util.Unzip.prototype.unzipFile = function(name) { - var i; - this.unzip(); - //alert(unzipped[0][1]); - for (i=0;i"); } */ - //alert(bA); - nextFile(); - return unzipped; + //alert(bA); + nextFile(); + return unzipped; }; - - function nextFile(){ - if (debug) - alert("NEXTFILE"); - outputArr = []; - var tmp = []; - modeZIP = false; - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("type: "+tmp[0]+" "+tmp[1]); - if (tmp[0] == parseInt("78",16) && tmp[1] == parseInt("da",16)){ //GZIP - if (debug) - alert("GEONExT-GZIP"); - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "geonext.gxt"; - files++; - } - if (tmp[0] == parseInt("78",16) && tmp[1] == parseInt("9c",16)){ //ZLIB - if (debug) - alert("ZLIB"); - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "ZLIB"; - files++; - } - if (tmp[0] == parseInt("1f",16) && tmp[1] == parseInt("8b",16)){ //GZIP - if (debug) - alert("GZIP"); - //DeflateLoop(); - skipdir(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = "file"; - files++; - } - if (tmp[0] == parseInt("50",16) && tmp[1] == parseInt("4b",16)){ //ZIP - modeZIP = true; - tmp[2] = readByte(); - tmp[3] = readByte(); - if (tmp[2] == parseInt("3",16) && tmp[3] == parseInt("4",16)){ - //MODE_ZIP - tmp[0] = readByte(); - tmp[1] = readByte(); - if (debug) - alert("ZIP-Version: "+tmp[1]+" "+tmp[0]/10+"."+tmp[0]%10); - - gpflags = readByte(); - gpflags |= (readByte()<<8); - if (debug) - alert("gpflags: "+gpflags); - - var method = readByte(); - method |= (readByte()<<8); - if (debug) - alert("method: "+method); - - readByte(); - readByte(); - readByte(); - readByte(); - - var crc = readByte(); - crc |= (readByte()<<8); - crc |= (readByte()<<16); - crc |= (readByte()<<24); - - var compSize = readByte(); - compSize |= (readByte()<<8); - compSize |= (readByte()<<16); - compSize |= (readByte()<<24); - - var size = readByte(); - size |= (readByte()<<8); - size |= (readByte()<<16); - size |= (readByte()<<24); - - if (debug) - alert("local CRC: "+crc+"\nlocal Size: "+size+"\nlocal CompSize: "+compSize); - - var filelen = readByte(); - filelen |= (readByte()<<8); - - var extralen = readByte(); - extralen |= (readByte()<<8); - - if (debug) - alert("filelen "+filelen); - i = 0; - nameBuf = []; - while (filelen--){ - var c = readByte(); - if (c == "/" | c ==":"){ - i = 0; - } else if (i < NAMEMAX-1) - nameBuf[i++] = String.fromCharCode(c); - } - if (debug) - alert("nameBuf: "+nameBuf); - - //nameBuf[i] = "\0"; - if (!fileout) - fileout = nameBuf; - - var i = 0; - while (i < extralen){ - c = readByte(); - i++; - } - - CRC = 0xffffffff; - SIZE = 0; - - if (size = 0 && fileOut.charAt(fileout.length-1)=="/"){ - //skipdir - if (debug) - alert("skipdir"); - } - if (method == 8){ - DeflateLoop(); - if (debug) - alert(outputArr.join('')); - unzipped[files] = new Array(2); - unzipped[files][0] = outputArr.join(''); - unzipped[files][1] = nameBuf.join(''); - files++; - //return outputArr.join(''); - } - skipdir(); - } - } - }; - -function skipdir(){ - var crc, - tmp = [], - compSize, size, os, i, c; - - if ((gpflags & 8)) { - tmp[0] = readByte(); - tmp[1] = readByte(); - tmp[2] = readByte(); - tmp[3] = readByte(); - - if (tmp[0] == parseInt("50",16) && - tmp[1] == parseInt("4b",16) && - tmp[2] == parseInt("07",16) && - tmp[3] == parseInt("08",16)) - { - crc = readByte(); - crc |= (readByte()<<8); - crc |= (readByte()<<16); - crc |= (readByte()<<24); - } else { - crc = tmp[0] | (tmp[1]<<8) | (tmp[2]<<16) | (tmp[3]<<24); - } - - compSize = readByte(); - compSize |= (readByte()<<8); - compSize |= (readByte()<<16); - compSize |= (readByte()<<24); - - size = readByte(); - size |= (readByte()<<8); - size |= (readByte()<<16); - size |= (readByte()<<24); - - if (debug) - alert("CRC:"); - } - if (modeZIP) - nextFile(); - - tmp[0] = readByte(); - if (tmp[0] != 8) { - if (debug) - alert("Unknown compression method!"); - return 0; - } - - gpflags = readByte(); - if (debug){ - if ((gpflags & ~(parseInt("1f",16)))) - alert("Unknown flags set!"); - } - - readByte(); - readByte(); - readByte(); - readByte(); - - readByte(); - os = readByte(); - - if ((gpflags & 4)){ - tmp[0] = readByte(); - tmp[2] = readByte(); - len = tmp[0] + 256*tmp[1]; - if (debug) - alert("Extra field size: "+len); - for (i=0;i> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; + 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; - } + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } - output.push([this._keyStr.charAt(enc1), - this._keyStr.charAt(enc2), - this._keyStr.charAt(enc3), - this._keyStr.charAt(enc4)].join('')); - } - - return output.join(''); - }, - - // public method for decoding - decode : function (input, utf8) { - var output = [], - chr1, chr2, chr3, - enc1, enc2, enc3, enc4, - i = 0; - - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - while (i < input.length) { - - enc1 = this._keyStr.indexOf(input.charAt(i++)); - enc2 = this._keyStr.indexOf(input.charAt(i++)); - enc3 = this._keyStr.indexOf(input.charAt(i++)); - enc4 = this._keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output.push(String.fromCharCode(chr1)); - - if (enc3 != 64) { - output.push(String.fromCharCode(chr2)); - } - if (enc4 != 64) { - output.push(String.fromCharCode(chr3)); - } - } - - output = output.join(''); - - if (utf8) { - output = JXG.Util.Base64._utf8_decode(output); - } - return output; - - }, - - // private method for UTF-8 encoding - _utf8_encode : function (string) { - string = string.replace(/\r\n/g,"\n"); - var utftext = ""; - - for (var n = 0; n < string.length; n++) { - - var c = string.charCodeAt(n); - - if (c < 128) { - utftext += String.fromCharCode(c); - } - else if((c > 127) && (c < 2048)) { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - - } - - return utftext; - }, - - // private method for UTF-8 decoding - _utf8_decode : function (utftext) { - var string = [], - i = 0, - c = 0, c2 = 0, c3 = 0; - - while ( i < utftext.length ) { - c = utftext.charCodeAt(i); - if (c < 128) { - string.push(String.fromCharCode(c)); - i++; - } - else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); - string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - i += 2; - } - else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - i += 3; - } - } - return string.join(''); - }, - - _destrip: function (stripped, wrap){ - var lines = [], lineno, i, - destripped = []; - - if (wrap==null) - wrap = 76; - - stripped.replace(/ /g, ""); - lineno = stripped.length / wrap; - for (i = 0; i < lineno; i++) - lines[i]=stripped.substr(i * wrap, wrap); - if (lineno != stripped.length / wrap) - lines[lines.length]=stripped.substr(lineno * wrap, stripped.length-(lineno * wrap)); - - for (i = 0; i < lines.length; i++) - destripped.push(lines[i]); - return destripped.join('\n'); - }, - - decodeAsArray: function (input){ - var dec = this.decode(input), - ar = [], i; - for (i=0;i> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output.push(String.fromCharCode(chr1)); + + if (enc3 != 64) { + output.push(String.fromCharCode(chr2)); + } + if (enc4 != 64) { + output.push(String.fromCharCode(chr3)); + } + } + + output = output.join(''); + + if (utf8) { + output = JXG.Util.Base64._utf8_decode(output); + } + return output; + + }, + + // private method for UTF-8 encoding + _utf8_encode: function(string) { + string = string.replace(/\r\n/g, "\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + + var c = string.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } else if ((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + + } + + return utftext; + }, + + // private method for UTF-8 decoding + _utf8_decode: function(utftext) { + var string = [], + i = 0, + c = 0, + c2 = 0, + c3 = 0; + + while (i < utftext.length) { + c = utftext.charCodeAt(i); + if (c < 128) { + string.push(String.fromCharCode(c)); + i++; + } else if ((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i + 1); + string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); + i += 2; + } else { + c2 = utftext.charCodeAt(i + 1); + c3 = utftext.charCodeAt(i + 2); + string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); + i += 3; + } + } + return string.join(''); + }, + + _destrip: function(stripped, wrap) { + var lines = [], + lineno, i, + destripped = []; + + if (wrap == null) + wrap = 76; + + stripped.replace(/ /g, ""); + lineno = stripped.length / wrap; + for (i = 0; i < lineno; i++) + lines[i] = stripped.substr(i * wrap, wrap); + if (lineno != stripped.length / wrap) + lines[lines.length] = stripped.substr(lineno * wrap, stripped.length - (lineno * wrap)); + + for (i = 0; i < lines.length; i++) + destripped.push(lines[i]); + return destripped.join('\n'); + }, + + decodeAsArray: function(input) { + var dec = this.decode(input), + ar = [], + i; + for (i = 0; i < dec.length; i++) { + ar[i] = dec.charCodeAt(i); + } + return ar; + }, + + decodeGEONExT: function(input) { + return decodeAsArray(destrip(input), false); + } }; /** * @private */ -JXG.Util.asciiCharCodeAt = function(str,i){ - var c = str.charCodeAt(i); - if (c>255){ - switch (c) { - case 8364: c=128; - break; - case 8218: c=130; - break; - case 402: c=131; - break; - case 8222: c=132; - break; - case 8230: c=133; - break; - case 8224: c=134; - break; - case 8225: c=135; - break; - case 710: c=136; - break; - case 8240: c=137; - break; - case 352: c=138; - break; - case 8249: c=139; - break; - case 338: c=140; - break; - case 381: c=142; - break; - case 8216: c=145; - break; - case 8217: c=146; - break; - case 8220: c=147; - break; - case 8221: c=148; - break; - case 8226: c=149; - break; - case 8211: c=150; - break; - case 8212: c=151; - break; - case 732: c=152; - break; - case 8482: c=153; - break; - case 353: c=154; - break; - case 8250: c=155; - break; - case 339: c=156; - break; - case 382: c=158; - break; - case 376: c=159; - break; - default: - break; - } - } - return c; +JXG.Util.asciiCharCodeAt = function(str, i) { + var c = str.charCodeAt(i); + if (c > 255) { + switch (c) { + case 8364: + c = 128; + break; + case 8218: + c = 130; + break; + case 402: + c = 131; + break; + case 8222: + c = 132; + break; + case 8230: + c = 133; + break; + case 8224: + c = 134; + break; + case 8225: + c = 135; + break; + case 710: + c = 136; + break; + case 8240: + c = 137; + break; + case 352: + c = 138; + break; + case 8249: + c = 139; + break; + case 338: + c = 140; + break; + case 381: + c = 142; + break; + case 8216: + c = 145; + break; + case 8217: + c = 146; + break; + case 8220: + c = 147; + break; + case 8221: + c = 148; + break; + case 8226: + c = 149; + break; + case 8211: + c = 150; + break; + case 8212: + c = 151; + break; + case 732: + c = 152; + break; + case 8482: + c = 153; + break; + case 353: + c = 154; + break; + case 8250: + c = 155; + break; + case 339: + c = 156; + break; + case 382: + c = 158; + break; + case 376: + c = 159; + break; + default: + break; + } + } + return c; }; /** @@ -1169,22 +1206,25 @@ JXG.Util.asciiCharCodeAt = function(str,i){ JXG.Util.utf8Decode = function(utftext) { var string = []; var i = 0; - var c = 0, c1 = 0, c2 = 0, c3; + var c = 0, + c1 = 0, + c2 = 0, + c3; if (!JXG.exists(utftext)) return ''; - - while ( i < utftext.length ) { + + while (i < utftext.length) { c = utftext.charCodeAt(i); if (c < 128) { string.push(String.fromCharCode(c)); i++; - } else if((c > 191) && (c < 224)) { - c2 = utftext.charCodeAt(i+1); + } else if ((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i + 1); string.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); i += 2; } else { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); + c2 = utftext.charCodeAt(i + 1); + c3 = utftext.charCodeAt(i + 2); string.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); i += 3; } @@ -1205,24 +1245,26 @@ JXG.Util.utf8Decode = function(utftext) { * "92329D39-6F5C-4520-ABFC-AAB64544E172" */ JXG.Util.genUUID = function() { - // Private array of chars to use - var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''), - uuid = new Array(36), rnd=0, r; + // Private array of chars to use + var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''), + uuid = new Array(36), + rnd = 0, + r; - for (var i = 0; i < 36; i++) { - if (i==8 || i==13 || i==18 || i==23) { - uuid[i] = '-'; - } else if (i==14) { - uuid[i] = '4'; - } else { - if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0; - r = rnd & 0xf; - rnd = rnd >> 4; - uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; - } + for (var i = 0; i < 36; i++) { + if (i == 8 || i == 13 || i == 18 || i == 23) { + uuid[i] = '-'; + } else if (i == 14) { + uuid[i] = '4'; + } else { + if (rnd <= 0x02) rnd = 0x2000000 + (Math.random() * 0x1000000) | 0; + r = rnd & 0xf; + rnd = rnd >> 4; + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; } + } - return uuid.join(''); + return uuid.join(''); }; @@ -1247,306 +1289,299 @@ module.exports = JXG; */ var util = require('../util'), - cipher = require('./cipher'); + cipher = require('./cipher'); module.exports = { - /** - * An array of bytes, that is integers with values from 0 to 255 - * @typedef {(Array|Uint8Array)} openpgp_byte_array - */ + /** + * An array of bytes, that is integers with values from 0 to 255 + * @typedef {(Array|Uint8Array)} openpgp_byte_array + */ - /** - * Block cipher function - * @callback openpgp_cipher_block_fn - * @param {openpgp_byte_array} block A block to perform operations on - * @param {openpgp_byte_array} key to use in encryption/decryption - * @return {openpgp_byte_array} Encrypted/decrypted block - */ + /** + * Block cipher function + * @callback openpgp_cipher_block_fn + * @param {openpgp_byte_array} block A block to perform operations on + * @param {openpgp_byte_array} key to use in encryption/decryption + * @return {openpgp_byte_array} Encrypted/decrypted block + */ - // -------------------------------------- - /** - * This function encrypts a given with the specified prefixrandom - * using the specified blockcipher to encrypt a message - * @param {String} prefixrandom random bytes of block_size length provided - * as a string to be used in prefixing the data - * @param {openpgp_cipher_block_fn} blockcipherfn the algorithm encrypt function to encrypt - * data in one block_size encryption. - * @param {Integer} block_size the block size in bytes of the algorithm used - * @param {String} plaintext data to be encrypted provided as a string - * @param {openpgp_byte_array} key key to be used to encrypt the data. This will be passed to the - * blockcipherfn - * @param {Boolean} resync a boolean value specifying if a resync of the - * IV should be used or not. The encrypteddatapacket uses the - * "old" style with a resync. Encryption within an - * encryptedintegrityprotecteddata packet is not resyncing the IV. - * @return {String} a string with the encrypted data - */ - encrypt: function (prefixrandom, cipherfn, plaintext, key, resync) { - cipherfn = new cipher[cipherfn](key); - var block_size = cipherfn.blockSize; + // -------------------------------------- + /** + * This function encrypts a given with the specified prefixrandom + * using the specified blockcipher to encrypt a message + * @param {String} prefixrandom random bytes of block_size length provided + * as a string to be used in prefixing the data + * @param {openpgp_cipher_block_fn} blockcipherfn the algorithm encrypt function to encrypt + * data in one block_size encryption. + * @param {Integer} block_size the block size in bytes of the algorithm used + * @param {String} plaintext data to be encrypted provided as a string + * @param {openpgp_byte_array} key key to be used to encrypt the data. This will be passed to the + * blockcipherfn + * @param {Boolean} resync a boolean value specifying if a resync of the + * IV should be used or not. The encrypteddatapacket uses the + * "old" style with a resync. Encryption within an + * encryptedintegrityprotecteddata packet is not resyncing the IV. + * @return {String} a string with the encrypted data + */ + encrypt: function(prefixrandom, cipherfn, plaintext, key, resync) { + cipherfn = new cipher[cipherfn](key); + var block_size = cipherfn.blockSize; - var FR = new Array(block_size); - var FRE = new Array(block_size); + var FR = new Array(block_size); + var FRE = new Array(block_size); - prefixrandom = prefixrandom + prefixrandom.charAt(block_size-2) +prefixrandom.charAt(block_size-1); - util.print_debug("prefixrandom:"+util.hexstrdump(prefixrandom)); - var ciphertext = ""; - // 1. The feedback register (FR) is set to the IV, which is all zeros. - for (var i = 0; i < block_size; i++) FR[i] = 0; - - // 2. FR is encrypted to produce FRE (FR Encrypted). This is the - // encryption of an all-zero value. - FRE = cipherfn.encrypt(FR); - // 3. FRE is xored with the first BS octets of random data prefixed to - // the plaintext to produce C[1] through C[BS], the first BS octets - // of ciphertext. - for (var i = 0; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ prefixrandom.charCodeAt(i)); - - // 4. FR is loaded with C[1] through C[BS]. - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i); - - // 5. FR is encrypted to produce FRE, the encryption of the first BS - // octets of ciphertext. - FRE = cipherfn.encrypt(FR); + prefixrandom = prefixrandom + prefixrandom.charAt(block_size - 2) + prefixrandom.charAt(block_size - 1); + util.print_debug("prefixrandom:" + util.hexstrdump(prefixrandom)); + var ciphertext = ""; + // 1. The feedback register (FR) is set to the IV, which is all zeros. + for (var i = 0; i < block_size; i++) FR[i] = 0; - // 6. The left two octets of FRE get xored with the next two octets of - // data that were prefixed to the plaintext. This produces C[BS+1] - // and C[BS+2], the next two octets of ciphertext. - ciphertext += String.fromCharCode(FRE[0] ^ prefixrandom.charCodeAt(block_size)); - ciphertext += String.fromCharCode(FRE[1] ^ prefixrandom.charCodeAt(block_size+1)); + // 2. FR is encrypted to produce FRE (FR Encrypted). This is the + // encryption of an all-zero value. + FRE = cipherfn.encrypt(FR); + // 3. FRE is xored with the first BS octets of random data prefixed to + // the plaintext to produce C[1] through C[BS], the first BS octets + // of ciphertext. + for (var i = 0; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ prefixrandom.charCodeAt(i)); - if (resync) { - // 7. (The resync step) FR is loaded with C3-C10. - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i+2); - } else { - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(i); - } - // 8. FR is encrypted to produce FRE. - FRE = cipherfn.encrypt(FR, key); - - if (resync) { - // 9. FRE is xored with the first 8 octets of the given plaintext, now - // that we have finished encrypting the 10 octets of prefixed data. - // This produces C11-C18, the next 8 octets of ciphertext. - for (var i = 0; i < block_size; i++) - ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(i)); - for(n=block_size+2; n < plaintext.length; n+=block_size) { - // 10. FR is loaded with C11-C18 - for (var i = 0; i < block_size; i++) FR[i] = ciphertext.charCodeAt(n+i); - - // 11. FR is encrypted to produce FRE. - FRE = cipherfn.encrypt(FR); - - // 12. FRE is xored with the next 8 octets of plaintext, to produce the - // next 8 octets of ciphertext. These are loaded into FR and the - // process is repeated until the plaintext is used up. - for (var i = 0; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt((n-2)+i)); - } - } - else { - plaintext = " "+plaintext; - // 9. FRE is xored with the first 8 octets of the given plaintext, now - // that we have finished encrypting the 10 octets of prefixed data. - // This produces C11-C18, the next 8 octets of ciphertext. - for (var i = 2; i < block_size; i++) ciphertext += String.fromCharCode(FRE[i] ^ plaintext.charCodeAt(i)); - var tempCiphertext = ciphertext.substring(0,2*block_size).split(''); - var tempCiphertextString = ciphertext.substring(block_size); - for(n=block_size; n block_size*pos) { - var encblock = cipherfn.encrypt(util.str2bin(blockc)); - blocki = plaintext.substring((pos*block_size),(pos*block_size)+block_size); - for (var i=0; i < blocki.length; i++) - tempBlock.push(String.fromCharCode(blocki.charCodeAt(i) ^ encblock[i])); - blockc = tempBlock.join(''); - tempBlock = []; - cyphertext.push(blockc); - pos++; - } - return cyphertext.join(''); - }, - normalDecrypt: function(cipherfn, key, ciphertext, iv) { - cipherfn = new cipher[cipherfn](key); - var block_size = cipherfn.blockSize; + normalEncrypt: function(cipherfn, key, plaintext, iv) { + cipherfn = new cipher[cipherfn](key); + var block_size = cipherfn.blockSize; - var blockp =""; - var pos = 0; - var plaintext = []; - var offset = 0; - if (iv == null) - for (var i = 0; i < block_size; i++) blockp += String.fromCharCode(0); - else - blockp = iv.substring(0,block_size); - while (ciphertext.length > (block_size*pos)) { - var decblock = cipherfn.encrypt(util.str2bin(blockp)); - blockp = ciphertext.substring((pos*(block_size))+offset,(pos*(block_size))+(block_size)+offset); - for (var i=0; i < blockp.length; i++) { - plaintext.push(String.fromCharCode(blockp.charCodeAt(i) ^ decblock[i])); - } - pos++; - } - - return plaintext.join(''); - } + var blocki = ""; + var blockc = ""; + var pos = 0; + var cyphertext = []; + var tempBlock = []; + blockc = iv.substring(0, block_size); + while (plaintext.length > block_size * pos) { + var encblock = cipherfn.encrypt(util.str2bin(blockc)); + blocki = plaintext.substring((pos * block_size), (pos * block_size) + block_size); + for (var i = 0; i < blocki.length; i++) + tempBlock.push(String.fromCharCode(blocki.charCodeAt(i) ^ encblock[i])); + blockc = tempBlock.join(''); + tempBlock = []; + cyphertext.push(blockc); + pos++; + } + return cyphertext.join(''); + }, + + normalDecrypt: function(cipherfn, key, ciphertext, iv) { + cipherfn = new cipher[cipherfn](key); + var block_size = cipherfn.blockSize; + + var blockp = ""; + var pos = 0; + var plaintext = []; + var offset = 0; + if (iv == null) + for (var i = 0; i < block_size; i++) blockp += String.fromCharCode(0); + else + blockp = iv.substring(0, block_size); + while (ciphertext.length > (block_size * pos)) { + var decblock = cipherfn.encrypt(util.str2bin(blockp)); + blockp = ciphertext.substring((pos * (block_size)) + offset, (pos * (block_size)) + (block_size) + offset); + for (var i = 0; i < blockp.length; i++) { + plaintext.push(String.fromCharCode(blockp.charCodeAt(i) ^ decblock[i])); + } + pos++; + } + + return plaintext.join(''); + } } -},{"../util":54,"./cipher":7}],3:[function(require,module,exports){ - +},{"../util":52,"./cipher":7}],3:[function(require,module,exports){ /* Rijndael (AES) Encryption * Copyright 2005 Herbert Hanewinkel, www.haneWIN.de * version 1.1, check www.haneWIN.de for the latest version @@ -1563,329 +1598,343 @@ module.exports = { var util = require('../../util'); // The round constants used in subkey expansion -var Rcon = [ -0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, -0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, -0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 ]; +var Rcon = [ + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, + 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, + 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 +]; // Precomputed lookup table for the SBox var S = [ - 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, -118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, -114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, -216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, -235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, -179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, -190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, -249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, -188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, -23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, -144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, - 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, -141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, - 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, -181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, -248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, -140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, - 22 ]; + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, + 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, + 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, + 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, + 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, + 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, + 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, + 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, + 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, + 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, + 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, + 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, + 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, + 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, + 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, + 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, + 22 +]; var T1 = [ -0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, -0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, -0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, -0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, -0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, -0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, -0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, -0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, -0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, -0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, -0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, -0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, -0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, -0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, -0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, -0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, -0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, -0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, -0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, -0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, -0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, -0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, -0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, -0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, -0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, -0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, -0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, -0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, -0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, -0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, -0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, -0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, -0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, -0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, -0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, -0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, -0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, -0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, -0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, -0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, -0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, -0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, -0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, -0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, -0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, -0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, -0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, -0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, -0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, -0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, -0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, -0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, -0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, -0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, -0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, -0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, -0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, -0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, -0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, -0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, -0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, -0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, -0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, -0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c ]; + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, + 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, + 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, + 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, + 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, + 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, + 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, + 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, + 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, + 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, + 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, + 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, + 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, + 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, + 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, + 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, + 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, + 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, + 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, + 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, + 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, + 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, + 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, + 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, + 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, + 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, + 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, + 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, + 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, + 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, + 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, + 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, + 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, + 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, + 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, + 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, + 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, + 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, + 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, + 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, + 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, + 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, + 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, + 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, + 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, + 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, + 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, + 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, + 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, + 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, + 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, + 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, + 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, + 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, + 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, + 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, + 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, + 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c +]; var T2 = [ -0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, -0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, -0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, -0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, -0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, -0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, -0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, -0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, -0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, -0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, -0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, -0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, -0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, -0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, -0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, -0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, -0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, -0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, -0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, -0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, -0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, -0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, -0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, -0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, -0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, -0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, -0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, -0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, -0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, -0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, -0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, -0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, -0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, -0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, -0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, -0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, -0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, -0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, -0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, -0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, -0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, -0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, -0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, -0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, -0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, -0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, -0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, -0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, -0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, -0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, -0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, -0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, -0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, -0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, -0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, -0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, -0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, -0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, -0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, -0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, -0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, -0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, -0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, -0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a ]; + 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, + 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, + 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, + 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, + 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, + 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, + 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, + 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, + 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, + 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, + 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, + 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, + 0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, + 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, + 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, + 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, + 0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, + 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, + 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, + 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, + 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, + 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, + 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, + 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, + 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, + 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, + 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, + 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, + 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, + 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, + 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, + 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, + 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, + 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, + 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, + 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, + 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, + 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, + 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, + 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, + 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, + 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, + 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, + 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, + 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, + 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, + 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, + 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, + 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, + 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, + 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, + 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, + 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, + 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, + 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, + 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, + 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, + 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, + 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, + 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, + 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, + 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, + 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, + 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a +]; var T3 = [ -0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, -0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, -0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, -0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, -0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, -0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, -0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, -0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, -0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, -0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, -0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, -0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, -0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, -0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, -0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, -0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, -0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, -0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, -0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, -0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, -0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, -0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, -0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, -0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, -0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, -0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, -0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, -0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, -0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, -0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, -0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, -0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, -0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, -0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, -0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, -0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, -0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, -0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, -0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, -0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, -0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, -0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, -0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, -0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, -0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, -0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, -0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, -0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, -0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, -0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, -0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, -0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, -0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, -0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, -0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, -0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, -0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, -0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, -0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, -0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, -0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, -0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, -0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, -0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16 ]; + 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, + 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, + 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, + 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, + 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, + 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, + 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, + 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, + 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, + 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, + 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, + 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, + 0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, + 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, + 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, + 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, + 0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, + 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, + 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, + 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, + 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, + 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, + 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, + 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, + 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, + 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, + 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, + 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, + 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, + 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, + 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, + 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, + 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, + 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, + 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, + 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, + 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, + 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, + 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, + 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, + 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, + 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, + 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, + 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, + 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, + 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, + 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, + 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, + 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, + 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, + 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, + 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, + 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, + 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, + 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, + 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, + 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, + 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, + 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, + 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, + 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, + 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, + 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, + 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16 +]; var T4 = [ -0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, -0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, -0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, -0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, -0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, -0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, -0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, -0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, -0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, -0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, -0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, -0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, -0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, -0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, -0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, -0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, -0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, -0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, -0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, -0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, -0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, -0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, -0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, -0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, -0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, -0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, -0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, -0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, -0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, -0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, -0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, -0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, -0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, -0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, -0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, -0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, -0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, -0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888, -0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, -0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, -0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, -0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, -0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, -0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, -0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, -0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, -0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, -0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, -0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, -0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, -0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, -0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, -0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, -0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, -0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, -0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, -0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, -0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, -0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, -0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, -0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, -0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, -0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, -0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616 ]; + 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, + 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, + 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, + 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, + 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, + 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, + 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, + 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, + 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, + 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, + 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, + 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, + 0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, + 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, + 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, + 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, + 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, + 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, + 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, + 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, + 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, + 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, + 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, + 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, + 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, + 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, + 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, + 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, + 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, + 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, + 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, + 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, + 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, + 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, + 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, + 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, + 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, + 0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888, + 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, + 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, + 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, + 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, + 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, + 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, + 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, + 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, + 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, + 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, + 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, + 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, + 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, + 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, + 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, + 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, + 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, + 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, + 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, + 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, + 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, + 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, + 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, + 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, + 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, + 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616 +]; -function B0(x) { return (x&255); } -function B1(x) { return ((x>>8)&255); } -function B2(x) { return ((x>>16)&255); } -function B3(x) { return ((x>>24)&255); } - -function F1(x0, x1, x2, x3) -{ - return B1(T1[x0&255]) | (B1(T1[(x1>>8)&255])<<8) - | (B1(T1[(x2>>16)&255])<<16) | (B1(T1[x3>>>24])<<24); +function B0(x) { + return (x & 255); } -function packBytes(octets) -{ +function B1(x) { + return ((x >> 8) & 255); +} + +function B2(x) { + return ((x >> 16) & 255); +} + +function B3(x) { + return ((x >> 24) & 255); +} + +function F1(x0, x1, x2, x3) { + return B1(T1[x0 & 255]) | (B1(T1[(x1 >> 8) & 255]) << 8) | (B1(T1[(x2 >> 16) & 255]) << 16) | (B1(T1[x3 >>> 24]) << + 24); +} + +function packBytes(octets) { var i, j; - var len=octets.length; - var b=new Array(len/4); + var len = octets.length; + var b = new Array(len / 4); if (!octets || len % 4) return; - for (i=0, j=0; j=0; j--) tk[j] = k[j]; + for (j = kc - 1; j >= 0; j--) tk[j] = k[j]; - r=0; - t=0; - for(j=0; (j>8)&255] ^ T3[(t2>>16)&255] ^ T4[t3>>>24]; - b1 = T1[t1&255] ^ T2[(t2>>8)&255] ^ T3[(t3>>16)&255] ^ T4[t0>>>24]; - b2 = T1[t2&255] ^ T2[(t3>>8)&255] ^ T3[(t0>>16)&255] ^ T4[t1>>>24]; - b3 = T1[t3&255] ^ T2[(t0>>8)&255] ^ T3[(t1>>16)&255] ^ T4[t2>>>24]; + b0 = T1[t0 & 255] ^ T2[(t1 >> 8) & 255] ^ T3[(t2 >> 16) & 255] ^ T4[t3 >>> 24]; + b1 = T1[t1 & 255] ^ T2[(t2 >> 8) & 255] ^ T3[(t3 >> 16) & 255] ^ T4[t0 >>> 24]; + b2 = T1[t2 & 255] ^ T2[(t3 >> 8) & 255] ^ T3[(t0 >> 16) & 255] ^ T4[t1 >>> 24]; + b3 = T1[t3 & 255] ^ T2[(t0 >> 8) & 255] ^ T3[(t1 >> 16) & 255] ^ T4[t2 >>> 24]; } // last round is special - r = rounds-1; + r = rounds - 1; t0 = b0 ^ ctx.rk[r][0]; t1 = b1 ^ ctx.rk[r][1]; @@ -2035,29 +2068,29 @@ function AESencrypt(block, ctx) function makeClass(length) { - var c = function(key) { - this.key = keyExpansion(key); + var c = function(key) { + this.key = keyExpansion(key); - this.encrypt = function(block) { - return AESencrypt(block, this.key); - } - } + this.encrypt = function(block) { + return AESencrypt(block, this.key); + } + } - c.blockSize = c.prototype.blockSize = 16; - c.keySize = c.prototype.keySize = length / 8; + c.blockSize = c.prototype.blockSize = 16; + c.keySize = c.prototype.keySize = length / 8; - return c; + return c; } module.exports = {} var types = [128, 192, 256]; -for(var i in types ) { - module.exports[types[i]] = makeClass(types[i]); +for (var i in types) { + module.exports[types[i]] = makeClass(types[i]); } -},{"../../util":54}],4:[function(require,module,exports){ +},{"../../util":52}],4:[function(require,module,exports){ /* Modified by Recurity Labs GmbH * * Originally written by nklein software (nklein.com) @@ -2070,8 +2103,7 @@ for(var i in types ) { * The constructor doesn't do much of anything. It's just here * so we can start defining properties and methods and such. */ -function Blowfish() { -}; +function Blowfish() {}; /* * Declare the block size so that protocols know what size @@ -2083,183 +2115,186 @@ Blowfish.prototype.BLOCKSIZE = 8; * These are the default SBOXES. */ Blowfish.prototype.SBOXES = [ - [ - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, - 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, - 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, - 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, - 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, - 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, - 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, - 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, - 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, - 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, - 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, - 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, - 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, - 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, - 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, - 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, - 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, - 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, - 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, - 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, - 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, - 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a - ], [ - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, - 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, - 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, - 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, - 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, - 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, - 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, - 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, - 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, - 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, - 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, - 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, - 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, - 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, - 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, - 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, - 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, - 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, - 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, - 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, - 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, - 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 - ], [ - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, - 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, - 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, - 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, - 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, - 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, - 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, - 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, - 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, - 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, - 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, - 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, - 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, - 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, - 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, - 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, - 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, - 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, - 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, - 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, - 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, - 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 - ], [ - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, - 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, - 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, - 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, - 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, - 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, - 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, - 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, - 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, - 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, - 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, - 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, - 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, - 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, - 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, - 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, - 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, - 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, - 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, - 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, - 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, - 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 - ] + [ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, + 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, + 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, + 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, + 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, + 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, + 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, + 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, + 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, + 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, + 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, + 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, + 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, + 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, + 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, + 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, + 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, + 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, + 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, + 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, + 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, + 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a + ], + [ + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, + 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, + 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, + 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, + 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, + 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, + 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, + 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, + 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, + 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, + 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, + 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, + 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, + 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, + 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, + 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, + 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, + 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, + 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, + 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, + 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, + 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 + ], + [ + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, + 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, + 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, + 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, + 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, + 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, + 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, + 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, + 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, + 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, + 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, + 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, + 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, + 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, + 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, + 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, + 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, + 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, + 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, + 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, + 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, + 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 + ], + [ + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, + 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, + 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, + 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, + 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, + 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, + 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, + 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, + 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, + 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, + 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, + 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, + 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, + 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, + 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, + 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, + 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, + 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, + 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, + 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, + 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, + 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + ] ]; //* @@ -2283,63 +2318,63 @@ Blowfish.prototype.NN = 16; //* equal to ( bb & 0x00FFFFFFFF ) even when they //* agree bit-for-bit for the first 32 bits. //* -Blowfish.prototype._clean = function( xx ) { - if ( xx < 0 ) { - var yy = xx & 0x7FFFFFFF; - xx = yy + 0x80000000; - } - return xx; +Blowfish.prototype._clean = function(xx) { + if (xx < 0) { + var yy = xx & 0x7FFFFFFF; + xx = yy + 0x80000000; + } + return xx; }; //* //* This is the mixing function that uses the sboxes //* -Blowfish.prototype._F = function ( xx ) { - var aa; - var bb; - var cc; - var dd; - var yy; +Blowfish.prototype._F = function(xx) { + var aa; + var bb; + var cc; + var dd; + var yy; - dd = xx & 0x00FF; - xx >>>= 8; - cc = xx & 0x00FF; - xx >>>= 8; - bb = xx & 0x00FF; - xx >>>= 8; - aa = xx & 0x00FF; + dd = xx & 0x00FF; + xx >>>= 8; + cc = xx & 0x00FF; + xx >>>= 8; + bb = xx & 0x00FF; + xx >>>= 8; + aa = xx & 0x00FF; - yy = this.sboxes[ 0 ][ aa ] + this.sboxes[ 1 ][ bb ]; - yy = yy ^ this.sboxes[ 2 ][ cc ]; - yy = yy + this.sboxes[ 3 ][ dd ]; + yy = this.sboxes[0][aa] + this.sboxes[1][bb]; + yy = yy ^ this.sboxes[2][cc]; + yy = yy + this.sboxes[3][dd]; - return yy; + return yy; }; //* //* This method takes an array with two values, left and right //* and does NN rounds of Blowfish on them. //* -Blowfish.prototype._encrypt_block = function ( vals ) { - var dataL = vals[ 0 ]; - var dataR = vals[ 1 ]; +Blowfish.prototype._encrypt_block = function(vals) { + var dataL = vals[0]; + var dataR = vals[1]; - var ii; + var ii; - for ( ii=0; ii < this.NN; ++ii ) { - dataL = dataL ^ this.parray[ ii ]; - dataR = this._F( dataL ) ^ dataR; + for (ii = 0; ii < this.NN; ++ii) { + dataL = dataL ^ this.parray[ii]; + dataR = this._F(dataL) ^ dataR; - var tmp = dataL; - dataL = dataR; - dataR = tmp; - } + var tmp = dataL; + dataL = dataR; + dataR = tmp; + } - dataL = dataL ^ this.parray[ this.NN + 0 ]; - dataR = dataR ^ this.parray[ this.NN + 1 ]; + dataL = dataL ^ this.parray[this.NN + 0]; + dataR = dataR ^ this.parray[this.NN + 1]; - vals[ 0 ] = this._clean( dataR ); - vals[ 1 ] = this._clean( dataL ); + vals[0] = this._clean(dataR); + vals[1] = this._clean(dataL); }; //* @@ -2351,116 +2386,117 @@ Blowfish.prototype._encrypt_block = function ( vals ) { //* instead. That will involve more looping, but it won't require //* the F() method to deconstruct the vector. //* -Blowfish.prototype.encrypt_block = function ( vector ) { - var ii; - var vals = [ 0, 0 ]; - var off = this.BLOCKSIZE/2; - for ( ii = 0; ii < this.BLOCKSIZE/2; ++ii ) { - vals[0] = ( vals[0] << 8 ) | ( vector[ ii + 0 ] & 0x00FF ); - vals[1] = ( vals[1] << 8 ) | ( vector[ ii + off ] & 0x00FF ); - } +Blowfish.prototype.encrypt_block = function(vector) { + var ii; + var vals = [0, 0]; + var off = this.BLOCKSIZE / 2; + for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) { + vals[0] = (vals[0] << 8) | (vector[ii + 0] & 0x00FF); + vals[1] = (vals[1] << 8) | (vector[ii + off] & 0x00FF); + } - this._encrypt_block( vals ); + this._encrypt_block(vals); - var ret = [ ]; - for ( ii = 0; ii < this.BLOCKSIZE/2; ++ii ) { - ret[ ii + 0 ] = ( vals[ 0 ] >>> (24 - 8*(ii)) & 0x00FF ); - ret[ ii + off ] = ( vals[ 1 ] >>> (24 - 8*(ii)) & 0x00FF ); - // vals[ 0 ] = ( vals[ 0 ] >>> 8 ); - // vals[ 1 ] = ( vals[ 1 ] >>> 8 ); - } + var ret = []; + for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) { + ret[ii + 0] = (vals[0] >>> (24 - 8 * (ii)) & 0x00FF); + ret[ii + off] = (vals[1] >>> (24 - 8 * (ii)) & 0x00FF); + // vals[ 0 ] = ( vals[ 0 ] >>> 8 ); + // vals[ 1 ] = ( vals[ 1 ] >>> 8 ); + } - return ret; + return ret; }; //* //* This method takes an array with two values, left and right //* and undoes NN rounds of Blowfish on them. //* -Blowfish.prototype._decrypt_block = function ( vals ) { - var dataL = vals[ 0 ]; - var dataR = vals[ 1 ]; +Blowfish.prototype._decrypt_block = function(vals) { + var dataL = vals[0]; + var dataR = vals[1]; - var ii; + var ii; - for ( ii=this.NN+1; ii > 1; --ii ) { - dataL = dataL ^ this.parray[ ii ]; - dataR = this._F( dataL ) ^ dataR; + for (ii = this.NN + 1; ii > 1; --ii) { + dataL = dataL ^ this.parray[ii]; + dataR = this._F(dataL) ^ dataR; - var tmp = dataL; - dataL = dataR; - dataR = tmp; - } + var tmp = dataL; + dataL = dataR; + dataR = tmp; + } - dataL = dataL ^ this.parray[ 1 ]; - dataR = dataR ^ this.parray[ 0 ]; + dataL = dataL ^ this.parray[1]; + dataR = dataR ^ this.parray[0]; - vals[ 0 ] = this._clean( dataR ); - vals[ 1 ] = this._clean( dataL ); + vals[0] = this._clean(dataR); + vals[1] = this._clean(dataL); }; //* //* This method takes a key array and initializes the //* sboxes and parray for this encryption. //* -Blowfish.prototype.init = function ( key ) { - var ii; - var jj = 0; +Blowfish.prototype.init = function(key) { + var ii; + var jj = 0; - this.parray = []; - for ( ii=0; ii < this.NN + 2; ++ii ) { - var data = 0x00000000; - var kk; - for ( kk=0; kk < 4; ++kk ) { - data = ( data << 8 ) | ( key[ jj ] & 0x00FF ); - if ( ++jj >= key.length ) { - jj = 0; - } - } - this.parray[ ii ] = this.PARRAY[ ii ] ^ data; + this.parray = []; + for (ii = 0; ii < this.NN + 2; ++ii) { + var data = 0x00000000; + var kk; + for (kk = 0; kk < 4; ++kk) { + data = (data << 8) | (key[jj] & 0x00FF); + if (++jj >= key.length) { + jj = 0; + } } + this.parray[ii] = this.PARRAY[ii] ^ data; + } - this.sboxes = []; - for ( ii=0; ii < 4; ++ii ) { - this.sboxes[ ii ] = []; - for ( jj=0; jj < 256; ++jj ) { - this.sboxes[ ii ][ jj ] = this.SBOXES[ ii ][ jj ]; - } + this.sboxes = []; + for (ii = 0; ii < 4; ++ii) { + this.sboxes[ii] = []; + for (jj = 0; jj < 256; ++jj) { + this.sboxes[ii][jj] = this.SBOXES[ii][jj]; } + } - var vals = [ 0x00000000, 0x00000000 ]; + var vals = [0x00000000, 0x00000000]; - for ( ii=0; ii < this.NN+2; ii += 2 ) { - this._encrypt_block( vals ); - this.parray[ ii + 0 ] = vals[ 0 ]; - this.parray[ ii + 1 ] = vals[ 1 ]; - } - - for ( ii=0; ii < 4; ++ii ) { - for ( jj=0; jj < 256; jj += 2 ) { - this._encrypt_block( vals ); - this.sboxes[ ii ][ jj + 0 ] = vals[ 0 ]; - this.sboxes[ ii ][ jj + 1 ] = vals[ 1 ]; - } + for (ii = 0; ii < this.NN + 2; ii += 2) { + this._encrypt_block(vals); + this.parray[ii + 0] = vals[0]; + this.parray[ii + 1] = vals[1]; + } + + for (ii = 0; ii < 4; ++ii) { + for (jj = 0; jj < 256; jj += 2) { + this._encrypt_block(vals); + this.sboxes[ii][jj + 0] = vals[0]; + this.sboxes[ii][jj + 1] = vals[1]; } + } }; var util = require('../../util'); // added by Recurity Labs -function BFencrypt(block,key) { - var bf = new Blowfish(); - bf.init(util.str2bin(key)); - return bf.encrypt_block(block); + +function BFencrypt(block, key) { + var bf = new Blowfish(); + bf.init(util.str2bin(key)); + return bf.encrypt_block(block); } function BF(key) { - this.bf = new Blowfish(); - this.bf.init(util.str2bin(key)); + this.bf = new Blowfish(); + this.bf.init(util.str2bin(key)); - this.encrypt = function(block) { - return this.bf.encrypt_block(block); - } + this.encrypt = function(block) { + return this.bf.encrypt_block(block); + } } @@ -2468,568 +2504,613 @@ module.exports = BF; module.exports.keySize = BF.prototype.keySize = 16; module.exports.blockSize = BF.prototype.blockSize = 16; +},{"../../util":52}],5:[function(require,module,exports){ +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Copyright 2010 pjacobs@xeekr.com . All rights reserved. + +// Modified by Recurity Labs GmbH + +// fixed/modified by Herbert Hanewinkel, www.haneWIN.de +// check www.haneWIN.de for the latest version + +// cast5.js is a Javascript implementation of CAST-128, as defined in RFC 2144. +// CAST-128 is a common OpenPGP cipher. -},{"../../util":54}],5:[function(require,module,exports){ - -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Copyright 2010 pjacobs@xeekr.com . All rights reserved. - -// Modified by Recurity Labs GmbH - -// fixed/modified by Herbert Hanewinkel, www.haneWIN.de -// check www.haneWIN.de for the latest version - -// cast5.js is a Javascript implementation of CAST-128, as defined in RFC 2144. -// CAST-128 is a common OpenPGP cipher. - - -// CAST5 constructor - - - -function openpgp_symenc_cast5() { - this.BlockSize= 8; - this.KeySize = 16; - - this.setKey = function (key) { - this.masking = new Array(16); - this.rotate = new Array(16); - - this.reset(); - - if (key.length == this.KeySize) - { - this.keySchedule(key); - } - else - { - util.print_error('cast5.js: CAST-128: keys must be 16 bytes'); - return false; - } - return true; - }; - - this.reset = function() { - for (var i = 0; i < 16; i++) - { - this.masking[i] = 0; - this.rotate[i] = 0; - } - }; - - this.getBlockSize = function() { - return BlockSize; - }; - - this.encrypt = function(src) { - var dst = new Array(src.length); - - for(var i = 0; i < src.length; i+=8) - { - var l = src[i]<<24 | src[i+1]<<16 | src[i+2]<<8 | src[i+3]; - var r = src[i+4]<<24 | src[i+5]<<16 | src[i+6]<<8 | src[i+7]; - var t; - - t = r; r = l^f1(r, this.masking[0], this.rotate[0]); l = t; - t = r; r = l^f2(r, this.masking[1], this.rotate[1]); l = t; - t = r; r = l^f3(r, this.masking[2], this.rotate[2]); l = t; - t = r; r = l^f1(r, this.masking[3], this.rotate[3]); l = t; - - t = r; r = l^f2(r, this.masking[4], this.rotate[4]); l = t; - t = r; r = l^f3(r, this.masking[5], this.rotate[5]); l = t; - t = r; r = l^f1(r, this.masking[6], this.rotate[6]); l = t; - t = r; r = l^f2(r, this.masking[7], this.rotate[7]); l = t; - - t = r; r = l^f3(r, this.masking[8], this.rotate[8]); l = t; - t = r; r = l^f1(r, this.masking[9], this.rotate[9]); l = t; - t = r; r = l^f2(r, this.masking[10], this.rotate[10]); l = t; - t = r; r = l^f3(r, this.masking[11], this.rotate[11]); l = t; - - t = r; r = l^f1(r, this.masking[12], this.rotate[12]); l = t; - t = r; r = l^f2(r, this.masking[13], this.rotate[13]); l = t; - t = r; r = l^f3(r, this.masking[14], this.rotate[14]); l = t; - t = r; r = l^f1(r, this.masking[15], this.rotate[15]); l = t; - - dst[i] = (r >>> 24)&255; - dst[i+1] = (r >>> 16)&255; - dst[i+2] = (r >>> 8)&255; - dst[i+3] = r&255; - dst[i+4] = (l >>> 24)&255; - dst[i+5] = (l >>> 16)&255; - dst[i+6] = (l >>> 8)&255; - dst[i+7] = l&255; - } - - return dst; - }; - - this.decrypt = function(src) { - var dst = new Array(src.length); - - for(var i = 0; i < src.length; i+=8) - { - var l = src[i]<<24 | src[i+1]<<16 | src[i+2]<<8 | src[i+3]; - var r = src[i+4]<<24 | src[i+5]<<16 | src[i+6]<<8 | src[i+7]; - var t; - - t = r; r = l^f1(r, this.masking[15], this.rotate[15]); l = t; - t = r; r = l^f3(r, this.masking[14], this.rotate[14]); l = t; - t = r; r = l^f2(r, this.masking[13], this.rotate[13]); l = t; - t = r; r = l^f1(r, this.masking[12], this.rotate[12]); l = t; - - t = r; r = l^f3(r, this.masking[11], this.rotate[11]); l = t; - t = r; r = l^f2(r, this.masking[10], this.rotate[10]); l = t; - t = r; r = l^f1(r, this.masking[9], this.rotate[9]); l = t; - t = r; r = l^f3(r, this.masking[8], this.rotate[8]); l = t; - - t = r; r = l^f2(r, this.masking[7], this.rotate[7]); l = t; - t = r; r = l^f1(r, this.masking[6], this.rotate[6]); l = t; - t = r; r = l^f3(r, this.masking[5], this.rotate[5]); l = t; - t = r; r = l^f2(r, this.masking[4], this.rotate[4]); l = t; - - t = r; r = l^f1(r, this.masking[3], this.rotate[3]); l = t; - t = r; r = l^f3(r, this.masking[2], this.rotate[2]); l = t; - t = r; r = l^f2(r, this.masking[1], this.rotate[1]); l = t; - t = r; r = l^f1(r, this.masking[0], this.rotate[0]); l = t; - - dst[i] = (r >>> 24)&255; - dst[i+1] = (r >>> 16)&255; - dst[i+2] = (r >>> 8)&255; - dst[i+3] = r&255; - dst[i+4] = (l >>> 24)&255; - dst[i+5] = (l >> 16)&255; - dst[i+6] = (l >> 8)&255; - dst[i+7] = l&255; - } - - return dst; - }; - var scheduleA = new Array(4); - - scheduleA[0] = new Array(4); - scheduleA[0][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 0x8); - scheduleA[0][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa); - scheduleA[0][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9); - scheduleA[0][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb); - - scheduleA[1] = new Array(4); - scheduleA[1][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0); - scheduleA[1][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2); - scheduleA[1][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1); - scheduleA[1][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3); - - scheduleA[2] = new Array(4); - scheduleA[2][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 8); - scheduleA[2][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa); - scheduleA[2][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9); - scheduleA[2][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb); - - - scheduleA[3] = new Array(4); - scheduleA[3][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0); - scheduleA[3][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2); - scheduleA[3][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1); - scheduleA[3][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3); - - var scheduleB = new Array(4); - - scheduleB[0] = new Array(4); - scheduleB[0][0] = new Array(16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2); - scheduleB[0][1] = new Array(16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6); - scheduleB[0][2] = new Array(16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9); - scheduleB[0][3] = new Array(16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc); - - scheduleB[1] = new Array(4); - scheduleB[1][0] = new Array(3, 2, 0xc, 0xd, 8); - scheduleB[1][1] = new Array(1, 0, 0xe, 0xf, 0xd); - scheduleB[1][2] = new Array(7, 6, 8, 9, 3); - scheduleB[1][3] = new Array(5, 4, 0xa, 0xb, 7); - - - scheduleB[2] = new Array(4); - scheduleB[2][0] = new Array(16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9); - scheduleB[2][1] = new Array(16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc); - scheduleB[2][2] = new Array(16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2); - scheduleB[2][3] = new Array(16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6); - - - scheduleB[3] = new Array(4); - scheduleB[3][0] = new Array(8, 9, 7, 6, 3); - scheduleB[3][1] = new Array(0xa, 0xb, 5, 4, 7); - scheduleB[3][2] = new Array(0xc, 0xd, 3, 2, 8); - scheduleB[3][3] = new Array(0xe, 0xf, 1, 0, 0xd); - - // changed 'in' to 'inn' (in javascript 'in' is a reserved word) - this.keySchedule = function(inn) - { - var t = new Array(8); - var k = new Array(32); - - for (var i = 0; i < 4; i++) - { - var j = i * 4; - t[i] = inn[j]<<24 | inn[j+1]<<16 | inn[j+2]<<8 | inn[j+3]; - } - - var x = [6, 7, 4, 5]; - var ki = 0; - - for (var half = 0; half < 2; half++) - { - for (var round = 0; round < 4; round++) - { - for (var j = 0; j < 4; j++) - { - var a = scheduleA[round][j]; - var w = t[a[1]]; - - w ^= sBox[4][(t[a[2]>>>2]>>>(24-8*(a[2]&3)))&0xff]; - w ^= sBox[5][(t[a[3]>>>2]>>>(24-8*(a[3]&3)))&0xff]; - w ^= sBox[6][(t[a[4]>>>2]>>>(24-8*(a[4]&3)))&0xff]; - w ^= sBox[7][(t[a[5]>>>2]>>>(24-8*(a[5]&3)))&0xff]; - w ^= sBox[x[j]][(t[a[6]>>>2]>>>(24-8*(a[6]&3)))&0xff]; - t[a[0]] = w; - } - - for (var j = 0; j < 4; j++) - { - var b = scheduleB[round][j]; - var w = sBox[4][(t[b[0]>>>2]>>>(24-8*(b[0]&3)))&0xff]; - - w ^= sBox[5][(t[b[1]>>>2]>>>(24-8*(b[1]&3)))&0xff]; - w ^= sBox[6][(t[b[2]>>>2]>>>(24-8*(b[2]&3)))&0xff]; - w ^= sBox[7][(t[b[3]>>>2]>>>(24-8*(b[3]&3)))&0xff]; - w ^= sBox[4+j][(t[b[4]>>>2]>>>(24-8*(b[4]&3)))&0xff]; - k[ki] = w; - ki++; - } - } - } - - for (var i = 0; i < 16; i++) - { - this.masking[i] = k[i]; - this.rotate[i] = k[16+i] & 0x1f; - } - }; - - // These are the three 'f' functions. See RFC 2144, section 2.2. - - function f1(d, m, r) - { - var t = m + d; - var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I>>>24] ^ sBox[1][(I>>>16)&255]) - sBox[2][(I>>>8)&255]) + sBox[3][I&255]; - } - - function f2(d, m, r) - { - var t = m ^ d; - var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I>>>24] - sBox[1][(I>>>16)&255]) + sBox[2][(I>>>8)&255]) ^ sBox[3][I&255]; - } - - function f3(d, m, r) - { - var t = m - d; - var I = (t << r) | (t >>> (32 - r)); - return ((sBox[0][I>>>24] + sBox[1][(I>>>16)&255]) ^ sBox[2][(I>>>8)&255]) - sBox[3][I&255]; - } - - var sBox = new Array(8); - sBox[0] = new Array( - 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, - 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, - 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, - 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, - 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, - 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, - 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, - 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, - 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, - 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, - 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, - 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, - 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, - 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, - 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, - 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, - 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, - 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, - 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, - 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, - 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, - 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, - 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, - 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, - 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, - 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, - 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, - 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, - 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, - 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, - 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, - 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf); - - sBox[1] = new Array( - 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, - 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, - 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, - 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, - 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, - 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, - 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, - 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, - 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, - 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, - 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, - 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, - 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, - 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, - 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, - 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, - 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, - 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, - 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, - 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, - 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, - 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, - 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, - 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, - 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, - 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, - 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, - 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, - 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, - 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, - 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, - 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1); - - sBox[2] = new Array( - 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, - 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, - 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, - 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, - 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, - 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, - 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, - 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, - 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, - 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, - 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, - 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, - 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, - 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, - 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, - 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, - 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, - 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, - 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, - 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, - 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, - 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, - 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, - 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, - 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, - 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, - 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, - 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, - 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, - 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, - 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, - 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783); - - sBox[3] = new Array( - 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, - 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, - 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, - 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, - 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, - 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, - 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, - 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, - 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, - 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, - 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, - 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, - 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, - 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, - 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, - 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, - 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, - 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, - 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, - 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, - 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, - 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, - 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, - 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, - 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, - 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, - 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, - 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, - 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, - 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, - 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, - 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2); - - sBox[4] = new Array( - 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, - 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, - 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, - 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, - 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, - 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, - 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, - 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, - 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, - 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, - 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, - 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, - 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, - 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, - 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, - 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, - 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, - 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, - 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, - 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, - 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, - 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, - 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, - 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, - 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, - 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, - 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, - 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, - 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, - 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, - 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, - 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4); - - sBox[5] = new Array( - 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, - 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, - 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, - 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, - 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, - 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, - 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, - 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, - 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, - 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, - 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, - 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, - 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, - 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, - 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, - 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, - 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, - 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, - 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, - 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, - 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, - 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, - 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, - 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, - 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, - 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, - 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, - 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, - 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, - 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, - 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, - 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f); - - sBox[6] = new Array( - 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, - 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, - 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, - 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, - 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, - 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, - 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, - 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, - 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, - 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, - 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, - 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, - 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, - 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, - 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, - 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, - 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, - 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, - 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, - 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, - 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, - 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, - 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, - 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, - 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, - 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, - 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, - 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, - 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, - 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, - 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, - 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3); - - sBox[7] = new Array( - 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, - 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, - 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, - 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, - 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, - 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, - 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, - 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, - 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, - 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, - 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, - 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, - 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, - 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, - 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, - 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, - 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, - 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, - 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, - 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, - 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, - 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, - 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, - 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, - 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, - 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, - 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, - 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, - 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, - 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, - 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, - 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e); - -}; - -var util = require('../../util'); - -function cast5(key) { - this.cast5 = new openpgp_symenc_cast5(); - this.cast5.setKey(util.str2bin(key)); - - this.encrypt = function(block) { - return this.cast5.encrypt(block); - } -} - -module.exports = cast5; -module.exports.blockSize = cast5.prototype.blockSize = 8; -module.exports.keySize = cast5.prototype.keySize = 16; +// CAST5 constructor -},{"../../util":54}],6:[function(require,module,exports){ + + +function openpgp_symenc_cast5() { + this.BlockSize = 8; + this.KeySize = 16; + + this.setKey = function(key) { + this.masking = new Array(16); + this.rotate = new Array(16); + + this.reset(); + + if (key.length == this.KeySize) { + this.keySchedule(key); + } else { + util.print_error('cast5.js: CAST-128: keys must be 16 bytes'); + return false; + } + return true; + }; + + this.reset = function() { + for (var i = 0; i < 16; i++) { + this.masking[i] = 0; + this.rotate[i] = 0; + } + }; + + this.getBlockSize = function() { + return BlockSize; + }; + + this.encrypt = function(src) { + var dst = new Array(src.length); + + for (var i = 0; i < src.length; i += 8) { + var l = src[i] << 24 | src[i + 1] << 16 | src[i + 2] << 8 | src[i + 3]; + var r = src[i + 4] << 24 | src[i + 5] << 16 | src[i + 6] << 8 | src[i + 7]; + var t; + + t = r; + r = l ^ f1(r, this.masking[0], this.rotate[0]); + l = t; + t = r; + r = l ^ f2(r, this.masking[1], this.rotate[1]); + l = t; + t = r; + r = l ^ f3(r, this.masking[2], this.rotate[2]); + l = t; + t = r; + r = l ^ f1(r, this.masking[3], this.rotate[3]); + l = t; + + t = r; + r = l ^ f2(r, this.masking[4], this.rotate[4]); + l = t; + t = r; + r = l ^ f3(r, this.masking[5], this.rotate[5]); + l = t; + t = r; + r = l ^ f1(r, this.masking[6], this.rotate[6]); + l = t; + t = r; + r = l ^ f2(r, this.masking[7], this.rotate[7]); + l = t; + + t = r; + r = l ^ f3(r, this.masking[8], this.rotate[8]); + l = t; + t = r; + r = l ^ f1(r, this.masking[9], this.rotate[9]); + l = t; + t = r; + r = l ^ f2(r, this.masking[10], this.rotate[10]); + l = t; + t = r; + r = l ^ f3(r, this.masking[11], this.rotate[11]); + l = t; + + t = r; + r = l ^ f1(r, this.masking[12], this.rotate[12]); + l = t; + t = r; + r = l ^ f2(r, this.masking[13], this.rotate[13]); + l = t; + t = r; + r = l ^ f3(r, this.masking[14], this.rotate[14]); + l = t; + t = r; + r = l ^ f1(r, this.masking[15], this.rotate[15]); + l = t; + + dst[i] = (r >>> 24) & 255; + dst[i + 1] = (r >>> 16) & 255; + dst[i + 2] = (r >>> 8) & 255; + dst[i + 3] = r & 255; + dst[i + 4] = (l >>> 24) & 255; + dst[i + 5] = (l >>> 16) & 255; + dst[i + 6] = (l >>> 8) & 255; + dst[i + 7] = l & 255; + } + + return dst; + }; + + this.decrypt = function(src) { + var dst = new Array(src.length); + + for (var i = 0; i < src.length; i += 8) { + var l = src[i] << 24 | src[i + 1] << 16 | src[i + 2] << 8 | src[i + 3]; + var r = src[i + 4] << 24 | src[i + 5] << 16 | src[i + 6] << 8 | src[i + 7]; + var t; + + t = r; + r = l ^ f1(r, this.masking[15], this.rotate[15]); + l = t; + t = r; + r = l ^ f3(r, this.masking[14], this.rotate[14]); + l = t; + t = r; + r = l ^ f2(r, this.masking[13], this.rotate[13]); + l = t; + t = r; + r = l ^ f1(r, this.masking[12], this.rotate[12]); + l = t; + + t = r; + r = l ^ f3(r, this.masking[11], this.rotate[11]); + l = t; + t = r; + r = l ^ f2(r, this.masking[10], this.rotate[10]); + l = t; + t = r; + r = l ^ f1(r, this.masking[9], this.rotate[9]); + l = t; + t = r; + r = l ^ f3(r, this.masking[8], this.rotate[8]); + l = t; + + t = r; + r = l ^ f2(r, this.masking[7], this.rotate[7]); + l = t; + t = r; + r = l ^ f1(r, this.masking[6], this.rotate[6]); + l = t; + t = r; + r = l ^ f3(r, this.masking[5], this.rotate[5]); + l = t; + t = r; + r = l ^ f2(r, this.masking[4], this.rotate[4]); + l = t; + + t = r; + r = l ^ f1(r, this.masking[3], this.rotate[3]); + l = t; + t = r; + r = l ^ f3(r, this.masking[2], this.rotate[2]); + l = t; + t = r; + r = l ^ f2(r, this.masking[1], this.rotate[1]); + l = t; + t = r; + r = l ^ f1(r, this.masking[0], this.rotate[0]); + l = t; + + dst[i] = (r >>> 24) & 255; + dst[i + 1] = (r >>> 16) & 255; + dst[i + 2] = (r >>> 8) & 255; + dst[i + 3] = r & 255; + dst[i + 4] = (l >>> 24) & 255; + dst[i + 5] = (l >> 16) & 255; + dst[i + 6] = (l >> 8) & 255; + dst[i + 7] = l & 255; + } + + return dst; + }; + var scheduleA = new Array(4); + + scheduleA[0] = new Array(4); + scheduleA[0][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 0x8); + scheduleA[0][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa); + scheduleA[0][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9); + scheduleA[0][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb); + + scheduleA[1] = new Array(4); + scheduleA[1][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0); + scheduleA[1][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2); + scheduleA[1][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1); + scheduleA[1][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3); + + scheduleA[2] = new Array(4); + scheduleA[2][0] = new Array(4, 0, 0xd, 0xf, 0xc, 0xe, 8); + scheduleA[2][1] = new Array(5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa); + scheduleA[2][2] = new Array(6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9); + scheduleA[2][3] = new Array(7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb); + + + scheduleA[3] = new Array(4); + scheduleA[3][0] = new Array(0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0); + scheduleA[3][1] = new Array(1, 4, 0, 2, 1, 3, 16 + 2); + scheduleA[3][2] = new Array(2, 5, 7, 6, 5, 4, 16 + 1); + scheduleA[3][3] = new Array(3, 7, 0xa, 9, 0xb, 8, 16 + 3); + + var scheduleB = new Array(4); + + scheduleB[0] = new Array(4); + scheduleB[0][0] = new Array(16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2); + scheduleB[0][1] = new Array(16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6); + scheduleB[0][2] = new Array(16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9); + scheduleB[0][3] = new Array(16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc); + + scheduleB[1] = new Array(4); + scheduleB[1][0] = new Array(3, 2, 0xc, 0xd, 8); + scheduleB[1][1] = new Array(1, 0, 0xe, 0xf, 0xd); + scheduleB[1][2] = new Array(7, 6, 8, 9, 3); + scheduleB[1][3] = new Array(5, 4, 0xa, 0xb, 7); + + + scheduleB[2] = new Array(4); + scheduleB[2][0] = new Array(16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9); + scheduleB[2][1] = new Array(16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc); + scheduleB[2][2] = new Array(16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2); + scheduleB[2][3] = new Array(16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6); + + + scheduleB[3] = new Array(4); + scheduleB[3][0] = new Array(8, 9, 7, 6, 3); + scheduleB[3][1] = new Array(0xa, 0xb, 5, 4, 7); + scheduleB[3][2] = new Array(0xc, 0xd, 3, 2, 8); + scheduleB[3][3] = new Array(0xe, 0xf, 1, 0, 0xd); + + // changed 'in' to 'inn' (in javascript 'in' is a reserved word) + this.keySchedule = function(inn) { + var t = new Array(8); + var k = new Array(32); + + for (var i = 0; i < 4; i++) { + var j = i * 4; + t[i] = inn[j] << 24 | inn[j + 1] << 16 | inn[j + 2] << 8 | inn[j + 3]; + } + + var x = [6, 7, 4, 5]; + var ki = 0; + + for (var half = 0; half < 2; half++) { + for (var round = 0; round < 4; round++) { + for (var j = 0; j < 4; j++) { + var a = scheduleA[round][j]; + var w = t[a[1]]; + + w ^= sBox[4][(t[a[2] >>> 2] >>> (24 - 8 * (a[2] & 3))) & 0xff]; + w ^= sBox[5][(t[a[3] >>> 2] >>> (24 - 8 * (a[3] & 3))) & 0xff]; + w ^= sBox[6][(t[a[4] >>> 2] >>> (24 - 8 * (a[4] & 3))) & 0xff]; + w ^= sBox[7][(t[a[5] >>> 2] >>> (24 - 8 * (a[5] & 3))) & 0xff]; + w ^= sBox[x[j]][(t[a[6] >>> 2] >>> (24 - 8 * (a[6] & 3))) & 0xff]; + t[a[0]] = w; + } + + for (var j = 0; j < 4; j++) { + var b = scheduleB[round][j]; + var w = sBox[4][(t[b[0] >>> 2] >>> (24 - 8 * (b[0] & 3))) & 0xff]; + + w ^= sBox[5][(t[b[1] >>> 2] >>> (24 - 8 * (b[1] & 3))) & 0xff]; + w ^= sBox[6][(t[b[2] >>> 2] >>> (24 - 8 * (b[2] & 3))) & 0xff]; + w ^= sBox[7][(t[b[3] >>> 2] >>> (24 - 8 * (b[3] & 3))) & 0xff]; + w ^= sBox[4 + j][(t[b[4] >>> 2] >>> (24 - 8 * (b[4] & 3))) & 0xff]; + k[ki] = w; + ki++; + } + } + } + + for (var i = 0; i < 16; i++) { + this.masking[i] = k[i]; + this.rotate[i] = k[16 + i] & 0x1f; + } + }; + + // These are the three 'f' functions. See RFC 2144, section 2.2. + + function f1(d, m, r) { + var t = m + d; + var I = (t << r) | (t >>> (32 - r)); + return ((sBox[0][I >>> 24] ^ sBox[1][(I >>> 16) & 255]) - sBox[2][(I >>> 8) & 255]) + sBox[3][I & 255]; + } + + function f2(d, m, r) { + var t = m ^ d; + var I = (t << r) | (t >>> (32 - r)); + return ((sBox[0][I >>> 24] - sBox[1][(I >>> 16) & 255]) + sBox[2][(I >>> 8) & 255]) ^ sBox[3][I & 255]; + } + + function f3(d, m, r) { + var t = m - d; + var I = (t << r) | (t >>> (32 - r)); + return ((sBox[0][I >>> 24] + sBox[1][(I >>> 16) & 255]) ^ sBox[2][(I >>> 8) & 255]) - sBox[3][I & 255]; + } + + var sBox = new Array(8); + sBox[0] = new Array( + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf); + + sBox[1] = new Array( + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1); + + sBox[2] = new Array( + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783); + + sBox[3] = new Array( + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2); + + sBox[4] = new Array( + 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, + 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, + 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, + 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, + 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, + 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, + 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, + 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, + 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, + 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, + 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, + 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, + 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, + 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, + 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, + 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, + 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, + 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, + 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, + 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, + 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, + 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, + 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, + 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, + 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, + 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, + 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, + 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, + 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, + 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, + 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, + 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4); + + sBox[5] = new Array( + 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, + 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, + 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, + 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, + 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, + 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, + 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, + 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, + 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, + 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, + 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, + 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, + 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, + 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, + 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, + 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, + 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, + 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, + 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, + 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, + 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, + 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, + 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, + 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, + 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, + 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, + 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, + 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, + 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, + 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, + 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, + 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f); + + sBox[6] = new Array( + 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, + 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, + 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, + 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, + 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, + 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, + 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, + 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, + 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, + 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, + 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, + 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, + 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, + 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, + 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, + 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, + 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, + 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, + 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, + 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, + 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, + 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, + 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, + 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, + 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, + 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, + 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, + 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, + 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, + 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, + 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, + 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3); + + sBox[7] = new Array( + 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, + 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, + 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, + 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, + 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, + 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, + 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, + 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, + 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, + 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, + 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, + 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, + 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, + 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, + 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, + 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, + 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, + 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, + 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, + 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, + 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, + 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, + 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, + 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, + 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, + 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, + 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, + 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, + 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, + 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, + 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, + 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e); + +}; + +var util = require('../../util'); + +function cast5(key) { + this.cast5 = new openpgp_symenc_cast5(); + this.cast5.setKey(util.str2bin(key)); + + this.encrypt = function(block) { + return this.cast5.encrypt(block); + } +} + +module.exports = cast5; +module.exports.blockSize = cast5.prototype.blockSize = 8; +module.exports.keySize = cast5.prototype.keySize = 16; + +},{"../../util":52}],6:[function(require,module,exports){ //Paul Tero, July 2001 //http://www.tero.co.uk/des/ // @@ -3056,34 +3137,79 @@ module.exports.keySize = cast5.prototype.keySize = 16; -function des (keys, message, encrypt, mode, iv, padding) { +function des(keys, message, encrypt, mode, iv, padding) { //declaring this locally speeds things up a bit - var spfunction1 = new Array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004); - var spfunction2 = new Array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000); - var spfunction3 = new Array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200); - var spfunction4 = new Array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080); - var spfunction5 = new Array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100); - var spfunction6 = new Array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010); - var spfunction7 = new Array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002); - var spfunction8 = new Array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000); + var spfunction1 = new Array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400, + 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000, + 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4, + 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404, + 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400, + 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004); + var spfunction2 = new Array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, - + 0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, - + 0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, - + 0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, - + 0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0, + 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, - + 0x7fef7fe0, 0x108000); + var spfunction3 = new Array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008, + 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000, + 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000, + 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0, + 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208, + 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200); + var spfunction4 = new Array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000, + 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080, + 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0, + 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001, + 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080); + var spfunction5 = new Array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000, + 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000, + 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100, + 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100, + 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100, + 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0, + 0x40080000, 0x2080100, 0x40000100); + var spfunction6 = new Array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000, + 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010, + 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000, + 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000, + 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000, + 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010); + var spfunction7 = new Array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802, + 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, + 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000, + 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000, + 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0, + 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002); + var spfunction8 = new Array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000, + 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000, + 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040, + 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040, + 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000, + 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000); //create the 16 or 48 subkeys we will need - var m=0, i, j, temp, temp2, right1, right2, left, right, looping; + var m = 0, + i, j, temp, temp2, right1, right2, left, right, looping; var cbcleft, cbcleft2, cbcright, cbcright2 var endloop, loopinc; var len = message.length; var chunk = 0; //set up the loops for single and triple des var iterations = keys.length == 32 ? 3 : 9; //single or triple des - if (iterations == 3) {looping = encrypt ? new Array (0, 32, 2) : new Array (30, -2, -2);} - else {looping = encrypt ? new Array (0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array (94, 62, -2, 32, 64, 2, 30, -2, -2);} + if (iterations == 3) { + looping = encrypt ? new Array(0, 32, 2) : new Array(30, -2, -2); + } else { + looping = encrypt ? new Array(0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array(94, 62, -2, 32, 64, 2, 30, -2, -2); + } //pad the message depending on the padding parameter - //only add padding if encrypting - note that you need to use the same padding option for both encrypt and decrypt - if (encrypt) { - message = des_addPadding(message, padding); - len = message.length; - } + //only add padding if encrypting - note that you need to use the same padding option for both encrypt and decrypt + if (encrypt) { + message = des_addPadding(message, padding); + len = message.length; + } //store the result here result = ""; @@ -3092,73 +3218,119 @@ function des (keys, message, encrypt, mode, iv, padding) { if (mode == 1) { //CBC mode cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); - m=0; + m = 0; } //loop through each 64 bit chunk of the message while (m < len) { - left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++); - right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++); + left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message + .charCodeAt(m++); + right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | + message.charCodeAt(m++); //for Cipher Block Chaining mode, xor the message with the previous result - if (mode == 1) {if (encrypt) {left ^= cbcleft; right ^= cbcright;} else {cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = left; cbcright = right;}} + if (mode == 1) { + if (encrypt) { + left ^= cbcleft; + right ^= cbcright; + } else { + cbcleft2 = cbcleft; + cbcright2 = cbcright; + cbcleft = left; + cbcright = right; + } + } //first each 64 but chunk of the message must be permuted according to IP - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); - temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16); - temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); + temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; + right ^= temp; + left ^= (temp << 4); + temp = ((left >>> 16) ^ right) & 0x0000ffff; + right ^= temp; + left ^= (temp << 16); + temp = ((right >>> 2) ^ left) & 0x33333333; + left ^= temp; + right ^= (temp << 2); + temp = ((right >>> 8) ^ left) & 0x00ff00ff; + left ^= temp; + right ^= (temp << 8); + temp = ((left >>> 1) ^ right) & 0x55555555; + right ^= temp; + left ^= (temp << 1); - left = ((left << 1) | (left >>> 31)); - right = ((right << 1) | (right >>> 31)); + left = ((left << 1) | (left >>> 31)); + right = ((right << 1) | (right >>> 31)); //do this either 1 or 3 times for each chunk of the message - for (j=0; j>> 4) | (right << 28)) ^ keys[i+1]; + for (i = looping[j]; i != endloop; i += loopinc) { //for efficiency + right1 = right ^ keys[i]; + right2 = ((right >>> 4) | (right << 28)) ^ keys[i + 1]; //the result is attained by passing these bytes through the S selection functions temp = left; left = right; - right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] - | spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f] - | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f] - | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]); + right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] | spfunction6[(right1 >>> + 8) & 0x3f] | spfunction8[right1 & 0x3f] | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & + 0x3f] | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]); } - temp = left; left = right; right = temp; //unreverse left and right + temp = left; + left = right; + right = temp; //unreverse left and right } //for either 1 or 3 iterations //move then each one bit to the right - left = ((left >>> 1) | (left << 31)); - right = ((right >>> 1) | (right << 31)); + left = ((left >>> 1) | (left << 31)); + right = ((right >>> 1) | (right << 31)); //now perform IP-1, which is IP in the opposite direction - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2); - temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16); - temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); + temp = ((left >>> 1) ^ right) & 0x55555555; + right ^= temp; + left ^= (temp << 1); + temp = ((right >>> 8) ^ left) & 0x00ff00ff; + left ^= temp; + right ^= (temp << 8); + temp = ((right >>> 2) ^ left) & 0x33333333; + left ^= temp; + right ^= (temp << 2); + temp = ((left >>> 16) ^ right) & 0x0000ffff; + right ^= temp; + left ^= (temp << 16); + temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; + right ^= temp; + left ^= (temp << 4); //for Cipher Block Chaining mode, xor the message with the previous result - if (mode == 1) {if (encrypt) {cbcleft = left; cbcright = right;} else {left ^= cbcleft2; right ^= cbcright2;}} - tempresult += String.fromCharCode ((left>>>24), ((left>>>16) & 0xff), ((left>>>8) & 0xff), (left & 0xff), (right>>>24), ((right>>>16) & 0xff), ((right>>>8) & 0xff), (right & 0xff)); + if (mode == 1) { + if (encrypt) { + cbcleft = left; + cbcright = right; + } else { + left ^= cbcleft2; + right ^= cbcright2; + } + } + tempresult += String.fromCharCode((left >>> 24), ((left >>> 16) & 0xff), ((left >>> 8) & 0xff), (left & 0xff), ( + right >>> 24), ((right >>> 16) & 0xff), ((right >>> 8) & 0xff), (right & 0xff)); chunk += 8; - if (chunk == 512) {result += tempresult; tempresult = ""; chunk = 0;} + if (chunk == 512) { + result += tempresult; + tempresult = ""; + chunk = 0; + } } //for every 8 characters, or 64 bits in the message //return the result as an array result += tempresult; - - //only remove padding if decrypting - note that you need to use the same padding option for both encrypt and decrypt - if (!encrypt) { - result = des_removePadding(result, padding); - } - + + //only remove padding if decrypting - note that you need to use the same padding option for both encrypt and decrypt + if (!encrypt) { + result = des_removePadding(result, padding); + } + return result; } //end of des @@ -3167,43 +3339,73 @@ function des (keys, message, encrypt, mode, iv, padding) { //des_createKeys //this takes as input a 64 bit key (even though only 56 bits are used) //as an array of 2 integers, and returns 16 48 bit keys -function des_createKeys (key) { + +function des_createKeys(key) { //declaring this locally speeds things up a bit - pc2bytes0 = new Array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204); - pc2bytes1 = new Array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101); - pc2bytes2 = new Array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808); - pc2bytes3 = new Array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000); - pc2bytes4 = new Array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010); - pc2bytes5 = new Array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420); - pc2bytes6 = new Array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002); - pc2bytes7 = new Array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800); - pc2bytes8 = new Array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002); - pc2bytes9 = new Array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408); - pc2bytes10 = new Array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020); - pc2bytes11 = new Array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200); - pc2bytes12 = new Array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010); - pc2bytes13 = new Array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105); + pc2bytes0 = new Array(0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204, + 0x20000200, 0x20000204, 0x10200, 0x10204, 0x20010200, 0x20010204); + pc2bytes1 = new Array(0, 0x1, 0x100000, 0x100001, 0x4000000, 0x4000001, 0x4100000, 0x4100001, 0x100, 0x101, 0x100100, + 0x100101, 0x4000100, 0x4000101, 0x4100100, 0x4100101); + pc2bytes2 = new Array(0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808, 0, 0x8, 0x800, 0x808, + 0x1000000, 0x1000008, 0x1000800, 0x1000808); + pc2bytes3 = new Array(0, 0x200000, 0x8000000, 0x8200000, 0x2000, 0x202000, 0x8002000, 0x8202000, 0x20000, 0x220000, + 0x8020000, 0x8220000, 0x22000, 0x222000, 0x8022000, 0x8222000); + pc2bytes4 = new Array(0, 0x40000, 0x10, 0x40010, 0, 0x40000, 0x10, 0x40010, 0x1000, 0x41000, 0x1010, 0x41010, 0x1000, + 0x41000, 0x1010, 0x41010); + pc2bytes5 = new Array(0, 0x400, 0x20, 0x420, 0, 0x400, 0x20, 0x420, 0x2000000, 0x2000400, 0x2000020, 0x2000420, + 0x2000000, 0x2000400, 0x2000020, 0x2000420); + pc2bytes6 = new Array(0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002, 0, 0x10000000, + 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002); + pc2bytes7 = new Array(0, 0x10000, 0x800, 0x10800, 0x20000000, 0x20010000, 0x20000800, 0x20010800, 0x20000, 0x30000, + 0x20800, 0x30800, 0x20020000, 0x20030000, 0x20020800, 0x20030800); + pc2bytes8 = new Array(0, 0x40000, 0, 0x40000, 0x2, 0x40002, 0x2, 0x40002, 0x2000000, 0x2040000, 0x2000000, 0x2040000, + 0x2000002, 0x2040002, 0x2000002, 0x2040002); + pc2bytes9 = new Array(0, 0x10000000, 0x8, 0x10000008, 0, 0x10000000, 0x8, 0x10000008, 0x400, 0x10000400, 0x408, + 0x10000408, 0x400, 0x10000400, 0x408, 0x10000408); + pc2bytes10 = new Array(0, 0x20, 0, 0x20, 0x100000, 0x100020, 0x100000, 0x100020, 0x2000, 0x2020, 0x2000, 0x2020, + 0x102000, 0x102020, 0x102000, 0x102020); + pc2bytes11 = new Array(0, 0x1000000, 0x200, 0x1000200, 0x200000, 0x1200000, 0x200200, 0x1200200, 0x4000000, 0x5000000, + 0x4000200, 0x5000200, 0x4200000, 0x5200000, 0x4200200, 0x5200200); + pc2bytes12 = new Array(0, 0x1000, 0x8000000, 0x8001000, 0x80000, 0x81000, 0x8080000, 0x8081000, 0x10, 0x1010, + 0x8000010, 0x8001010, 0x80010, 0x81010, 0x8080010, 0x8081010); + pc2bytes13 = new Array(0, 0x4, 0x100, 0x104, 0, 0x4, 0x100, 0x104, 0x1, 0x5, 0x101, 0x105, 0x1, 0x5, 0x101, 0x105); //how many iterations (1 for des, 3 for triple des) var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys //stores the return keys - var keys = new Array (32 * iterations); + var keys = new Array(32 * iterations); //now define the left shifts which need to be done - var shifts = new Array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0); + var shifts = new Array(0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0); //other variables - var lefttemp, righttemp, m=0, n=0, temp; + var lefttemp, righttemp, m = 0, + n = 0, + temp; - for (var j=0; j>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4); - temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16); - temp = ((left >>> 2) ^ right) & 0x33333333; right ^= temp; left ^= (temp << 2); - temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16); - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); - temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8); - temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1); + temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; + right ^= temp; + left ^= (temp << 4); + temp = ((right >>> -16) ^ left) & 0x0000ffff; + left ^= temp; + right ^= (temp << -16); + temp = ((left >>> 2) ^ right) & 0x33333333; + right ^= temp; + left ^= (temp << 2); + temp = ((right >>> -16) ^ left) & 0x0000ffff; + left ^= temp; + right ^= (temp << -16); + temp = ((left >>> 1) ^ right) & 0x55555555; + right ^= temp; + left ^= (temp << 1); + temp = ((right >>> 8) ^ left) & 0x00ff00ff; + left ^= temp; + right ^= (temp << 8); + temp = ((left >>> 1) ^ right) & 0x55555555; + right ^= temp; + left ^= (temp << 1); //the right side needs to be shifted and to get the last four bits of the left side temp = (left << 8) | ((right >>> 20) & 0x000000f0); @@ -3212,79 +3414,82 @@ function des_createKeys (key) { right = temp; //now go through and perform these shifts on the left and right keys - for (i=0; i < shifts.length; i++) { + for (i = 0; i < shifts.length; i++) { //shift the keys either one or two bits to the left - if (shifts[i]) {left = (left << 2) | (left >>> 26); right = (right << 2) | (right >>> 26);} - else {left = (left << 1) | (left >>> 27); right = (right << 1) | (right >>> 27);} - left &= -0xf; right &= -0xf; + if (shifts[i]) { + left = (left << 2) | (left >>> 26); + right = (right << 2) | (right >>> 26); + } else { + left = (left << 1) | (left >>> 27); + right = (right << 1) | (right >>> 27); + } + left &= -0xf; + right &= -0xf; //now apply PC-2, in such a way that E is easier when encrypting or decrypting //this conversion will look like PC-2 except only the last 6 bits of each byte are used //rather than 48 consecutive bits and the order of lines will be according to //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7 - lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] - | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf] - | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] - | pc2bytes6[(left >>> 4) & 0xf]; - righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] - | pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf] - | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] - | pc2bytes13[(right >>> 4) & 0xf]; - temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff; - keys[n++] = lefttemp ^ temp; keys[n++] = righttemp ^ (temp << 16); + lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[( + left >>> 16) & 0xf] | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] | pc2bytes6[(left >>> 4) & + 0xf]; + righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] | pc2bytes9[(right >>> 20) & 0xf] | + pc2bytes10[(right >>> 16) & 0xf] | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] | + pc2bytes13[(right >>> 4) & 0xf]; + temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff; + keys[n++] = lefttemp ^ temp; + keys[n++] = righttemp ^ (temp << 16); } } //for each iterations //return the keys we've created return keys; } //end of des_createKeys - -function des_addPadding(message, padding) { - var padLength = 8 - (message.length % 8); - if ((padding == 2) && (padLength < 8)) { //pad the message with spaces - message += " ".substr(0, padLength); - } - else if (padding == 1) { //PKCS7 padding - message += String.fromCharCode(padLength, padLength, padLength, padLength, padLength, padLength, padLength, padLength).substr(0, padLength); - } - else if (!padding && (padLength < 8)) { //pad the message out with null bytes - message += "\0\0\0\0\0\0\0\0".substr(0, padLength); - } - return message; -} - -function des_removePadding(message, padding) { - if (padding == 2) { // space padded - message = message.replace(/ *$/g, ""); - } - else if (padding == 1) { // PKCS7 - var padCount = message.charCodeAt(message.length - 1); - message = message.substr(0, message.length - padCount); - } - else if (!padding) { // null padding - message = message.replace(/\0*$/g, ""); - } - return message; -} + +function des_addPadding(message, padding) { + var padLength = 8 - (message.length % 8); + if ((padding == 2) && (padLength < 8)) { //pad the message with spaces + message += " ".substr(0, padLength); + } else if (padding == 1) { //PKCS7 padding + message += String.fromCharCode(padLength, padLength, padLength, padLength, padLength, padLength, padLength, + padLength).substr(0, padLength); + } else if (!padding && (padLength < 8)) { //pad the message out with null bytes + message += "\0\0\0\0\0\0\0\0".substr(0, padLength); + } + return message; +} + +function des_removePadding(message, padding) { + if (padding == 2) { // space padded + message = message.replace(/ *$/g, ""); + } else if (padding == 1) { // PKCS7 + var padCount = message.charCodeAt(message.length - 1); + message = message.substr(0, message.length - padCount); + } else if (!padding) { // null padding + message = message.replace(/\0*$/g, ""); + } + return message; +} var util = require('../../util'); // added by Recurity Labs + function Des(key) { - this.key = []; + this.key = []; - for(var i = 0; i < 3; i++) { - this.key.push(key.substr(i * 8, 8)); - } + for (var i = 0; i < 3; i++) { + this.key.push(key.substr(i * 8, 8)); + } - this.encrypt = function(block) { - return util.str2bin(des(des_createKeys(this.key[2]), - des(des_createKeys(this.key[1]), - des(des_createKeys(this.key[0]), - util.bin2str(block), true, 0,null,null), - false, 0,null,null), true, 0,null,null)); - } + this.encrypt = function(block) { + return util.str2bin(des(des_createKeys(this.key[2]), + des(des_createKeys(this.key[1]), + des(des_createKeys(this.key[0]), + util.bin2str(block), true, 0, null, null), + false, 0, null, null), true, 0, null, null)); + } } Des.keySize = Des.prototype.keySize = 24; @@ -3292,42 +3497,41 @@ Des.blockSize = Des.prototype.blockSize = 8; // This is "original" DES - Des is actually Triple DES. // This is only exported so we can unit test. -function OriginalDes(key) { - this.key = key; - this.encrypt = function (block, padding) { - var keys = des_createKeys(this.key); - return util.str2bin(des(keys, util.bin2str(block), true, 0, null, padding)); - } +function OriginalDes(key) { + this.key = key; - this.decrypt = function (block, padding) { - var keys = des_createKeys(this.key); - return util.str2bin(des(keys, util.bin2str(block), false, 0, null, padding)); - } + this.encrypt = function(block, padding) { + var keys = des_createKeys(this.key); + return util.str2bin(des(keys, util.bin2str(block), true, 0, null, padding)); + } + + this.decrypt = function(block, padding) { + var keys = des_createKeys(this.key); + return util.str2bin(des(keys, util.bin2str(block), false, 0, null, padding)); + } } -module.exports = { - des: Des, - originalDes: OriginalDes +module.exports = { + des: Des, + originalDes: OriginalDes } - -},{"../../util":54}],7:[function(require,module,exports){ - +},{"../../util":52}],7:[function(require,module,exports){ var desModule = require('./des.js'); module.exports = { - des: desModule['des'], - originalDes: desModule['originalDes'], - cast5: require('./cast5.js'), - twofish: require('./twofish.js'), - blowfish: require('./blowfish.js') + des: desModule['des'], + originalDes: desModule['originalDes'], + cast5: require('./cast5.js'), + twofish: require('./twofish.js'), + blowfish: require('./blowfish.js') } var aes = require('./aes.js'); -for(var i in aes) { - module.exports['aes' + i] = aes[i]; +for (var i in aes) { + module.exports['aes' + i] = aes[i]; } },{"./aes.js":3,"./blowfish.js":4,"./cast5.js":5,"./des.js":6,"./twofish.js":8}],8:[function(require,module,exports){ @@ -3359,291 +3563,350 @@ for(var i in aes) { var MAXINT = 0xFFFFFFFF; -function rotb(b,n){ return ( b<>>( 8-n) ) & 0xFF; } -function rotw(w,n){ return ( w<>>(32-n) ) & MAXINT; } -function getW(a,i){ return a[i]|a[i+1]<<8|a[i+2]<<16|a[i+3]<<24; } -function setW(a,i,w){ a.splice(i,4,w&0xFF,(w>>>8)&0xFF,(w>>>16)&0xFF,(w>>>24)&0xFF); } -function setWInv(a,i,w){ a.splice(i,4,(w>>>24)&0xFF,(w>>>16)&0xFF,(w>>>8)&0xFF,w&0xFF); } -function getB(x,n){ return (x>>>(n*8))&0xFF; } +function rotb(b, n) { + return (b << n | b >>> (8 - n)) & 0xFF; +} -function getNrBits(i){ var n=0; while (i>0){ n++; i>>>=1; } return n; } -function getMask(n){ return (1<>> (32 - n)) & MAXINT; +} + +function getW(a, i) { + return a[i] | a[i + 1] << 8 | a[i + 2] << 16 | a[i + 3] << 24; +} + +function setW(a, i, w) { + a.splice(i, 4, w & 0xFF, (w >>> 8) & 0xFF, (w >>> 16) & 0xFF, (w >>> 24) & 0xFF); +} + +function setWInv(a, i, w) { + a.splice(i, 4, (w >>> 24) & 0xFF, (w >>> 16) & 0xFF, (w >>> 8) & 0xFF, w & 0xFF); +} + +function getB(x, n) { + return (x >>> (n * 8)) & 0xFF; +} + +function getNrBits(i) { + var n = 0; + while (i > 0) { + n++; + i >>>= 1; + } + return n; +} + +function getMask(n) { + return (1 << n) - 1; +} //added 2008/11/13 XXX MUST USE ONE-WAY HASH FUNCTION FOR SECURITY REASON + function randByte() { - return Math.floor( Math.random() * 256 ); + return Math.floor(Math.random() * 256); } // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Twofish // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function createTwofish() { - // - var keyBytes = null; - var dataBytes = null; - var dataOffset = -1; - // var dataLength = -1; - var algorithmName = null; - // var idx2 = -1; - // + // + var keyBytes = null; + var dataBytes = null; + var dataOffset = -1; + // var dataLength = -1; + var algorithmName = null; + // var idx2 = -1; + // - algorithmName = "twofish"; + algorithmName = "twofish"; - var tfsKey = []; - var tfsM = [ [], [], [], [] ]; + var tfsKey = []; + var tfsM = [ + [], + [], + [], + [] + ]; - function tfsInit(key) { - keyBytes = key; - var i, a, b, c, d, meKey = [], moKey = [], inKey = []; - var kLen; - var sKey = []; - var f01, f5b, fef; + function tfsInit(key) { + keyBytes = key; + var i, a, b, c, d, meKey = [], + moKey = [], + inKey = []; + var kLen; + var sKey = []; + var f01, f5b, fef; - var q0 = [ [ 8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4 ], - [ 2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5 ] ]; - var q1 = [ [ 14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13 ], - [ 1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8 ] ]; - var q2 = [ [ 11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1 ], - [ 4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15 ] ]; - var q3 = [ [ 13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10 ], - [ 11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10 ] ]; - var ror4 = [ 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 ]; - var ashx = [ 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7 ]; - var q = [ [], [] ]; - var m = [ [], [], [], [] ]; + var q0 = [ + [8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4], + [2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5] + ]; + var q1 = [ + [14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13], + [1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8] + ]; + var q2 = [ + [11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1], + [4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15] + ]; + var q3 = [ + [13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10], + [11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10] + ]; + var ror4 = [0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15]; + var ashx = [0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7]; + var q = [ + [], + [] + ]; + var m = [ + [], + [], + [], + [] + ]; - function ffm5b(x) { - return x ^ (x >> 2) ^ [ 0, 90, 180, 238 ][x & 3]; - } - function ffmEf(x) { - return x ^ (x >> 1) ^ (x >> 2) ^ [ 0, 238, 180, 90 ][x & 3]; - } + function ffm5b(x) { + return x ^ (x >> 2) ^ [0, 90, 180, 238][x & 3]; + } - function mdsRem(p, q) { - var i, t, u; - for (i = 0; i < 8; i++) { - t = q >>> 24; - q = ((q << 8) & MAXINT) | p >>> 24; - p = (p << 8) & MAXINT; - u = t << 1; - if (t & 128) { - u ^= 333; - } - q ^= t ^ (u << 16); - u ^= t >>> 1; - if (t & 1) { - u ^= 166; - } - q ^= u << 24 | u << 8; - } - return q; - } + function ffmEf(x) { + return x ^ (x >> 1) ^ (x >> 2) ^ [0, 238, 180, 90][x & 3]; + } - function qp(n, x) { - var a, b, c, d; - a = x >> 4; - b = x & 15; - c = q0[n][a ^ b]; - d = q1[n][ror4[b] ^ ashx[a]]; - return q3[n][ror4[d] ^ ashx[c]] << 4 | q2[n][c ^ d]; - } + function mdsRem(p, q) { + var i, t, u; + for (i = 0; i < 8; i++) { + t = q >>> 24; + q = ((q << 8) & MAXINT) | p >>> 24; + p = (p << 8) & MAXINT; + u = t << 1; + if (t & 128) { + u ^= 333; + } + q ^= t ^ (u << 16); + u ^= t >>> 1; + if (t & 1) { + u ^= 166; + } + q ^= u << 24 | u << 8; + } + return q; + } - function hFun(x, key) { - var a = getB(x, 0), b = getB(x, 1), c = getB(x, 2), d = getB(x, 3); - switch (kLen) { - case 4: - a = q[1][a] ^ getB(key[3], 0); - b = q[0][b] ^ getB(key[3], 1); - c = q[0][c] ^ getB(key[3], 2); - d = q[1][d] ^ getB(key[3], 3); - case 3: - a = q[1][a] ^ getB(key[2], 0); - b = q[1][b] ^ getB(key[2], 1); - c = q[0][c] ^ getB(key[2], 2); - d = q[0][d] ^ getB(key[2], 3); - case 2: - a = q[0][q[0][a] ^ getB(key[1], 0)] ^ getB(key[0], 0); - b = q[0][q[1][b] ^ getB(key[1], 1)] ^ getB(key[0], 1); - c = q[1][q[0][c] ^ getB(key[1], 2)] ^ getB(key[0], 2); - d = q[1][q[1][d] ^ getB(key[1], 3)] ^ getB(key[0], 3); - } - return m[0][a] ^ m[1][b] ^ m[2][c] ^ m[3][d]; - } + function qp(n, x) { + var a, b, c, d; + a = x >> 4; + b = x & 15; + c = q0[n][a ^ b]; + d = q1[n][ror4[b] ^ ashx[a]]; + return q3[n][ror4[d] ^ ashx[c]] << 4 | q2[n][c ^ d]; + } - keyBytes = keyBytes.slice(0, 32); - i = keyBytes.length; - while (i != 16 && i != 24 && i != 32) - keyBytes[i++] = 0; + function hFun(x, key) { + var a = getB(x, 0), + b = getB(x, 1), + c = getB(x, 2), + d = getB(x, 3); + switch (kLen) { + case 4: + a = q[1][a] ^ getB(key[3], 0); + b = q[0][b] ^ getB(key[3], 1); + c = q[0][c] ^ getB(key[3], 2); + d = q[1][d] ^ getB(key[3], 3); + case 3: + a = q[1][a] ^ getB(key[2], 0); + b = q[1][b] ^ getB(key[2], 1); + c = q[0][c] ^ getB(key[2], 2); + d = q[0][d] ^ getB(key[2], 3); + case 2: + a = q[0][q[0][a] ^ getB(key[1], 0)] ^ getB(key[0], 0); + b = q[0][q[1][b] ^ getB(key[1], 1)] ^ getB(key[0], 1); + c = q[1][q[0][c] ^ getB(key[1], 2)] ^ getB(key[0], 2); + d = q[1][q[1][d] ^ getB(key[1], 3)] ^ getB(key[0], 3); + } + return m[0][a] ^ m[1][b] ^ m[2][c] ^ m[3][d]; + } - for (i = 0; i < keyBytes.length; i += 4) { - inKey[i >> 2] = getW(keyBytes, i); - } - for (i = 0; i < 256; i++) { - q[0][i] = qp(0, i); - q[1][i] = qp(1, i); - } - for (i = 0; i < 256; i++) { - f01 = q[1][i]; - f5b = ffm5b(f01); - fef = ffmEf(f01); - m[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24); - m[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24); - f01 = q[0][i]; - f5b = ffm5b(f01); - fef = ffmEf(f01); - m[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24); - m[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24); - } + keyBytes = keyBytes.slice(0, 32); + i = keyBytes.length; + while (i != 16 && i != 24 && i != 32) + keyBytes[i++] = 0; - kLen = inKey.length / 2; - for (i = 0; i < kLen; i++) { - a = inKey[i + i]; - meKey[i] = a; - b = inKey[i + i + 1]; - moKey[i] = b; - sKey[kLen - i - 1] = mdsRem(a, b); - } - for (i = 0; i < 40; i += 2) { - a = 0x1010101 * i; - b = a + 0x1010101; - a = hFun(a, meKey); - b = rotw(hFun(b, moKey), 8); - tfsKey[i] = (a + b) & MAXINT; - tfsKey[i + 1] = rotw(a + 2 * b, 9); - } - for (i = 0; i < 256; i++) { - a = b = c = d = i; - switch (kLen) { - case 4: - a = q[1][a] ^ getB(sKey[3], 0); - b = q[0][b] ^ getB(sKey[3], 1); - c = q[0][c] ^ getB(sKey[3], 2); - d = q[1][d] ^ getB(sKey[3], 3); - case 3: - a = q[1][a] ^ getB(sKey[2], 0); - b = q[1][b] ^ getB(sKey[2], 1); - c = q[0][c] ^ getB(sKey[2], 2); - d = q[0][d] ^ getB(sKey[2], 3); - case 2: - tfsM[0][i] = m[0][q[0][q[0][a] ^ getB(sKey[1], 0)] - ^ getB(sKey[0], 0)]; - tfsM[1][i] = m[1][q[0][q[1][b] ^ getB(sKey[1], 1)] - ^ getB(sKey[0], 1)]; - tfsM[2][i] = m[2][q[1][q[0][c] ^ getB(sKey[1], 2)] - ^ getB(sKey[0], 2)]; - tfsM[3][i] = m[3][q[1][q[1][d] ^ getB(sKey[1], 3)] - ^ getB(sKey[0], 3)]; - } - } - } + for (i = 0; i < keyBytes.length; i += 4) { + inKey[i >> 2] = getW(keyBytes, i); + } + for (i = 0; i < 256; i++) { + q[0][i] = qp(0, i); + q[1][i] = qp(1, i); + } + for (i = 0; i < 256; i++) { + f01 = q[1][i]; + f5b = ffm5b(f01); + fef = ffmEf(f01); + m[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24); + m[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24); + f01 = q[0][i]; + f5b = ffm5b(f01); + fef = ffmEf(f01); + m[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24); + m[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24); + } - function tfsG0(x) { - return tfsM[0][getB(x, 0)] ^ tfsM[1][getB(x, 1)] ^ tfsM[2][getB(x, 2)] - ^ tfsM[3][getB(x, 3)]; - } - function tfsG1(x) { - return tfsM[0][getB(x, 3)] ^ tfsM[1][getB(x, 0)] ^ tfsM[2][getB(x, 1)] - ^ tfsM[3][getB(x, 2)]; - } + kLen = inKey.length / 2; + for (i = 0; i < kLen; i++) { + a = inKey[i + i]; + meKey[i] = a; + b = inKey[i + i + 1]; + moKey[i] = b; + sKey[kLen - i - 1] = mdsRem(a, b); + } + for (i = 0; i < 40; i += 2) { + a = 0x1010101 * i; + b = a + 0x1010101; + a = hFun(a, meKey); + b = rotw(hFun(b, moKey), 8); + tfsKey[i] = (a + b) & MAXINT; + tfsKey[i + 1] = rotw(a + 2 * b, 9); + } + for (i = 0; i < 256; i++) { + a = b = c = d = i; + switch (kLen) { + case 4: + a = q[1][a] ^ getB(sKey[3], 0); + b = q[0][b] ^ getB(sKey[3], 1); + c = q[0][c] ^ getB(sKey[3], 2); + d = q[1][d] ^ getB(sKey[3], 3); + case 3: + a = q[1][a] ^ getB(sKey[2], 0); + b = q[1][b] ^ getB(sKey[2], 1); + c = q[0][c] ^ getB(sKey[2], 2); + d = q[0][d] ^ getB(sKey[2], 3); + case 2: + tfsM[0][i] = m[0][q[0][q[0][a] ^ getB(sKey[1], 0)] ^ getB(sKey[0], 0)]; + tfsM[1][i] = m[1][q[0][q[1][b] ^ getB(sKey[1], 1)] ^ getB(sKey[0], 1)]; + tfsM[2][i] = m[2][q[1][q[0][c] ^ getB(sKey[1], 2)] ^ getB(sKey[0], 2)]; + tfsM[3][i] = m[3][q[1][q[1][d] ^ getB(sKey[1], 3)] ^ getB(sKey[0], 3)]; + } + } + } - function tfsFrnd(r, blk) { - var a = tfsG0(blk[0]); - var b = tfsG1(blk[1]); - blk[2] = rotw(blk[2] ^ (a + b + tfsKey[4 * r + 8]) & MAXINT, 31); - blk[3] = rotw(blk[3], 1) ^ (a + 2 * b + tfsKey[4 * r + 9]) & MAXINT; - a = tfsG0(blk[2]); - b = tfsG1(blk[3]); - blk[0] = rotw(blk[0] ^ (a + b + tfsKey[4 * r + 10]) & MAXINT, 31); - blk[1] = rotw(blk[1], 1) ^ (a + 2 * b + tfsKey[4 * r + 11]) & MAXINT; - } + function tfsG0(x) { + return tfsM[0][getB(x, 0)] ^ tfsM[1][getB(x, 1)] ^ tfsM[2][getB(x, 2)] ^ tfsM[3][getB(x, 3)]; + } - function tfsIrnd(i, blk) { - var a = tfsG0(blk[0]); - var b = tfsG1(blk[1]); - blk[2] = rotw(blk[2], 1) ^ (a + b + tfsKey[4 * i + 10]) & MAXINT; - blk[3] = rotw(blk[3] ^ (a + 2 * b + tfsKey[4 * i + 11]) & MAXINT, 31); - a = tfsG0(blk[2]); - b = tfsG1(blk[3]); - blk[0] = rotw(blk[0], 1) ^ (a + b + tfsKey[4 * i + 8]) & MAXINT; - blk[1] = rotw(blk[1] ^ (a + 2 * b + tfsKey[4 * i + 9]) & MAXINT, 31); - } + function tfsG1(x) { + return tfsM[0][getB(x, 3)] ^ tfsM[1][getB(x, 0)] ^ tfsM[2][getB(x, 1)] ^ tfsM[3][getB(x, 2)]; + } - function tfsClose() { - tfsKey = []; - tfsM = [ [], [], [], [] ]; - } + function tfsFrnd(r, blk) { + var a = tfsG0(blk[0]); + var b = tfsG1(blk[1]); + blk[2] = rotw(blk[2] ^ (a + b + tfsKey[4 * r + 8]) & MAXINT, 31); + blk[3] = rotw(blk[3], 1) ^ (a + 2 * b + tfsKey[4 * r + 9]) & MAXINT; + a = tfsG0(blk[2]); + b = tfsG1(blk[3]); + blk[0] = rotw(blk[0] ^ (a + b + tfsKey[4 * r + 10]) & MAXINT, 31); + blk[1] = rotw(blk[1], 1) ^ (a + 2 * b + tfsKey[4 * r + 11]) & MAXINT; + } - function tfsEncrypt(data, offset) { - dataBytes = data; - dataOffset = offset; - var blk = [ getW(dataBytes, dataOffset) ^ tfsKey[0], - getW(dataBytes, dataOffset + 4) ^ tfsKey[1], - getW(dataBytes, dataOffset + 8) ^ tfsKey[2], - getW(dataBytes, dataOffset + 12) ^ tfsKey[3] ]; - for ( var j = 0; j < 8; j++) { - tfsFrnd(j, blk); - } - setW(dataBytes, dataOffset, blk[2] ^ tfsKey[4]); - setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[5]); - setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[6]); - setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[7]); - dataOffset += 16; - return dataBytes; - } + function tfsIrnd(i, blk) { + var a = tfsG0(blk[0]); + var b = tfsG1(blk[1]); + blk[2] = rotw(blk[2], 1) ^ (a + b + tfsKey[4 * i + 10]) & MAXINT; + blk[3] = rotw(blk[3] ^ (a + 2 * b + tfsKey[4 * i + 11]) & MAXINT, 31); + a = tfsG0(blk[2]); + b = tfsG1(blk[3]); + blk[0] = rotw(blk[0], 1) ^ (a + b + tfsKey[4 * i + 8]) & MAXINT; + blk[1] = rotw(blk[1] ^ (a + 2 * b + tfsKey[4 * i + 9]) & MAXINT, 31); + } - function tfsDecrypt(data, offset) { - dataBytes = data; - dataOffset = offset; - var blk = [ getW(dataBytes, dataOffset) ^ tfsKey[4], - getW(dataBytes, dataOffset + 4) ^ tfsKey[5], - getW(dataBytes, dataOffset + 8) ^ tfsKey[6], - getW(dataBytes, dataOffset + 12) ^ tfsKey[7] ]; - for ( var j = 7; j >= 0; j--) { - tfsIrnd(j, blk); - } - setW(dataBytes, dataOffset, blk[2] ^ tfsKey[0]); - setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[1]); - setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[2]); - setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[3]); - dataOffset += 16; - } - - // added by Recurity Labs - function tfsFinal() { - return dataBytes; - } + function tfsClose() { + tfsKey = []; + tfsM = [ + [], + [], + [], + [] + ]; + } - return { - name : "twofish", - blocksize : 128 / 8, - open : tfsInit, - close : tfsClose, - encrypt : tfsEncrypt, - decrypt : tfsDecrypt, - // added by Recurity Labs - finalize: tfsFinal - }; + function tfsEncrypt(data, offset) { + dataBytes = data; + dataOffset = offset; + var blk = [getW(dataBytes, dataOffset) ^ tfsKey[0], + getW(dataBytes, dataOffset + 4) ^ tfsKey[1], + getW(dataBytes, dataOffset + 8) ^ tfsKey[2], + getW(dataBytes, dataOffset + 12) ^ tfsKey[3] + ]; + for (var j = 0; j < 8; j++) { + tfsFrnd(j, blk); + } + setW(dataBytes, dataOffset, blk[2] ^ tfsKey[4]); + setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[5]); + setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[6]); + setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[7]); + dataOffset += 16; + return dataBytes; + } + + function tfsDecrypt(data, offset) { + dataBytes = data; + dataOffset = offset; + var blk = [getW(dataBytes, dataOffset) ^ tfsKey[4], + getW(dataBytes, dataOffset + 4) ^ tfsKey[5], + getW(dataBytes, dataOffset + 8) ^ tfsKey[6], + getW(dataBytes, dataOffset + 12) ^ tfsKey[7] + ]; + for (var j = 7; j >= 0; j--) { + tfsIrnd(j, blk); + } + setW(dataBytes, dataOffset, blk[2] ^ tfsKey[0]); + setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[1]); + setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[2]); + setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[3]); + dataOffset += 16; + } + + // added by Recurity Labs + + function tfsFinal() { + return dataBytes; + } + + return { + name: "twofish", + blocksize: 128 / 8, + open: tfsInit, + close: tfsClose, + encrypt: tfsEncrypt, + decrypt: tfsDecrypt, + // added by Recurity Labs + finalize: tfsFinal + }; } var util = require('../../util'); // added by Recurity Labs + function TFencrypt(block, key) { - var block_copy = [].concat(block); - var tf = createTwofish(); - tf.open(util.str2bin(key),0); - var result = tf.encrypt(block_copy, 0); - tf.close(); - return result; + var block_copy = [].concat(block); + var tf = createTwofish(); + tf.open(util.str2bin(key), 0); + var result = tf.encrypt(block_copy, 0); + tf.close(); + return result; } function TF(key) { - this.tf = createTwofish(); - this.tf.open(util.str2bin(key),0); + this.tf = createTwofish(); + this.tf.open(util.str2bin(key), 0); - this.encrypt = function(block) { - return this.tf.encrypt([].concat(block), 0); - } + this.encrypt = function(block) { + return this.tf.encrypt([].concat(block), 0); + } } @@ -3651,7 +3914,7 @@ module.exports = TF; module.exports.keySize = TF.prototype.keySize = 32; module.exports.blockSize = TF.prototype.blockSize = 16; -},{"../../util":54}],9:[function(require,module,exports){ +},{"../../util":52}],9:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH // @@ -3677,237 +3940,278 @@ var random = require('./random.js'), type_mpi = require('../type/mpi.js'); module.exports = { -/** - * Encrypts data using the specified public key multiprecision integers - * and the specified algorithm. - * @param {Integer} algo Algorithm to be used (See RFC4880 9.1) - * @param {openpgp_type_mpi[]} publicMPIs Algorithm dependent multiprecision integers - * @param {openpgp_type_mpi} data Data to be encrypted as MPI - * @return {openpgp_type_mpi[]} if RSA an openpgp_type_mpi; - * if elgamal encryption an array of two openpgp_type_mpi is returned; otherwise null - */ -publicKeyEncrypt: function(algo, publicMPIs, data) { - var result = (function() { - switch(algo) { - case 'rsa_encrypt': - case 'rsa_encrypt_sign': - var rsa = new publicKey.rsa(); - var n = publicMPIs[0].toBigInteger(); - var e = publicMPIs[1].toBigInteger(); - var m = data.toBigInteger(); - return [rsa.encrypt(m,e,n)]; + /** + * Encrypts data using the specified public key multiprecision integers + * and the specified algorithm. + * @param {Integer} algo Algorithm to be used (See RFC4880 9.1) + * @param {openpgp_type_mpi[]} publicMPIs Algorithm dependent multiprecision integers + * @param {openpgp_type_mpi} data Data to be encrypted as MPI + * @return {openpgp_type_mpi[]} if RSA an openpgp_type_mpi; + * if elgamal encryption an array of two openpgp_type_mpi is returned; otherwise null + */ + publicKeyEncrypt: function(algo, publicMPIs, data) { + var result = (function() { + switch (algo) { + case 'rsa_encrypt': + case 'rsa_encrypt_sign': + var rsa = new publicKey.rsa(); + var n = publicMPIs[0].toBigInteger(); + var e = publicMPIs[1].toBigInteger(); + var m = data.toBigInteger(); + return [rsa.encrypt(m, e, n)]; - case 'elgamal': - var elgamal = new publicKey.elgamal(); - var p = publicMPIs[0].toBigInteger(); - var g = publicMPIs[1].toBigInteger(); - var y = publicMPIs[2].toBigInteger(); - var m = data.toBigInteger(); - return elgamal.encrypt(m,g,p,y); + case 'elgamal': + var elgamal = new publicKey.elgamal(); + var p = publicMPIs[0].toBigInteger(); + var g = publicMPIs[1].toBigInteger(); + var y = publicMPIs[2].toBigInteger(); + var m = data.toBigInteger(); + return elgamal.encrypt(m, g, p, y); - default: - return []; + default: + return []; + } + })(); + + return result.map(function(bn) { + var mpi = new type_mpi(); + mpi.fromBigInteger(bn); + return mpi; + }); + }, + + /** + * Decrypts data using the specified public key multiprecision integers of the private key, + * the specified secretMPIs of the private key and the specified algorithm. + * @param {Integer} algo Algorithm to be used (See RFC4880 9.1) + * @param {openpgp_type_mpi[]} publicMPIs Algorithm dependent multiprecision integers + * of the public key part of the private key + * @param {openpgp_type_mpi[]} secretMPIs Algorithm dependent multiprecision integers + * of the private key used + * @param {openpgp_type_mpi} data Data to be encrypted as MPI + * @return {openpgp_type_mpi} returns a big integer containing the decrypted data; otherwise null + */ + + publicKeyDecrypt: function(algo, keyIntegers, dataIntegers) { + var bn = (function() { + switch (algo) { + case 'rsa_encrypt_sign': + case 'rsa_encrypt': + var rsa = new publicKey.rsa(); + // 0 and 1 are the public key. + var d = keyIntegers[2].toBigInteger(); + var p = keyIntegers[3].toBigInteger(); + var q = keyIntegers[4].toBigInteger(); + var u = keyIntegers[5].toBigInteger(); + var m = dataIntegers[0].toBigInteger(); + return rsa.decrypt(m, d, p, q, u); + case 'elgamal': + var elgamal = new publicKey.elgamal(); + var x = keyIntegers[3].toBigInteger(); + var c1 = dataIntegers[0].toBigInteger(); + var c2 = dataIntegers[1].toBigInteger(); + var p = keyIntegers[0].toBigInteger(); + return elgamal.decrypt(c1, c2, p, x); + default: + return null; + } + })(); + + var result = new type_mpi(); + result.fromBigInteger(bn); + return result; + }, + + /** Returns the number of integers comprising the private key of an algorithm + * @param {openpgp.publickey} algo The public key algorithm + * @return {Integer} The number of integers. + */ + getPrivateMpiCount: function(algo) { + switch (algo) { + case 'rsa_encrypt': + case 'rsa_encrypt_sign': + case 'rsa_sign': + // Algorithm-Specific Fields for RSA secret keys: + // - multiprecision integer (MPI) of RSA secret exponent d. + // - MPI of RSA secret prime value p. + // - MPI of RSA secret prime value q (p < q). + // - MPI of u, the multiplicative inverse of p, mod q. + return 4; + case 'elgamal': + // Algorithm-Specific Fields for Elgamal secret keys: + // - MPI of Elgamal secret exponent x. + return 1; + case 'dsa': + // Algorithm-Specific Fields for DSA secret keys: + // - MPI of DSA secret exponent x. + return 1; + default: + throw new Error('Unknown algorithm'); } - })(); + }, - return result.map(function(bn) { - var mpi = new type_mpi(); - mpi.fromBigInteger(bn); - return mpi; - }); -}, + getPublicMpiCount: function(algo) { + // - A series of multiprecision integers comprising the key material: + // Algorithm-Specific Fields for RSA public keys: + // - a multiprecision integer (MPI) of RSA public modulus n; + // - an MPI of RSA public encryption exponent e. + switch (algo) { + case 'rsa_encrypt': + case 'rsa_encrypt_sign': + case 'rsa_sign': + return 2; -/** - * Decrypts data using the specified public key multiprecision integers of the private key, - * the specified secretMPIs of the private key and the specified algorithm. - * @param {Integer} algo Algorithm to be used (See RFC4880 9.1) - * @param {openpgp_type_mpi[]} publicMPIs Algorithm dependent multiprecision integers - * of the public key part of the private key - * @param {openpgp_type_mpi[]} secretMPIs Algorithm dependent multiprecision integers - * of the private key used - * @param {openpgp_type_mpi} data Data to be encrypted as MPI - * @return {openpgp_type_mpi} returns a big integer containing the decrypted data; otherwise null - */ + // Algorithm-Specific Fields for Elgamal public keys: + // - MPI of Elgamal prime p; + // - MPI of Elgamal group generator g; + // - MPI of Elgamal public key value y (= g**x mod p where x is secret). + case 'elgamal': + return 3; -publicKeyDecrypt: function (algo, keyIntegers, dataIntegers) { - var bn = (function() { - switch(algo) { - case 'rsa_encrypt_sign': - case 'rsa_encrypt': - var rsa = new publicKey.rsa(); - // 0 and 1 are the public key. - var d = keyIntegers[2].toBigInteger(); - var p = keyIntegers[3].toBigInteger(); - var q = keyIntegers[4].toBigInteger(); - var u = keyIntegers[5].toBigInteger(); - var m = dataIntegers[0].toBigInteger(); - return rsa.decrypt(m, d, p, q, u); - case 'elgamal': - var elgamal = new publicKey.elgamal(); - var x = keyIntegers[3].toBigInteger(); - var c1 = dataIntegers[0].toBigInteger(); - var c2 = dataIntegers[1].toBigInteger(); - var p = keyIntegers[0].toBigInteger(); - return elgamal.decrypt(c1,c2,p,x); - default: - return null; + // Algorithm-Specific Fields for DSA public keys: + // - MPI of DSA prime p; + // - MPI of DSA group order q (q is a prime divisor of p-1); + // - MPI of DSA group generator g; + // - MPI of DSA public-key value y (= g**x mod p where x is secret). + case 'dsa': + return 4; + + default: + throw new Error('Unknown algorithm.'); } - })(); + }, - var result = new type_mpi(); - result.fromBigInteger(bn); - return result; -}, + generateMpi: function(algo, bits) { + var result = (function() { + switch (algo) { + case 'rsa_encrypt': + case 'rsa_encrypt_sign': + case 'rsa_sign': + //remember "publicKey" refers to the crypto/public_key dir + var rsa = new publicKey.rsa(); + var keyObject = rsa.generate(bits, "10001"); + var output = []; + output.push(keyObject.n); + output.push(keyObject.ee); + output.push(keyObject.d); + output.push(keyObject.p); + output.push(keyObject.q); + output.push(keyObject.u); + return output; + default: + throw new Error('Unsupported algorithm for key generation.'); + } + })(); -/** Returns the number of integers comprising the private key of an algorithm - * @param {openpgp.publickey} algo The public key algorithm - * @return {Integer} The number of integers. - */ -getPrivateMpiCount: function(algo) { - switch(algo) { - case 'rsa_encrypt': - case 'rsa_encrypt_sign': - case 'rsa_sign': - // Algorithm-Specific Fields for RSA secret keys: - // - multiprecision integer (MPI) of RSA secret exponent d. - // - MPI of RSA secret prime value p. - // - MPI of RSA secret prime value q (p < q). - // - MPI of u, the multiplicative inverse of p, mod q. - return 4; - case 'elgamal': - // Algorithm-Specific Fields for Elgamal secret keys: - // - MPI of Elgamal secret exponent x. - return 1; - case 'dsa': - // Algorithm-Specific Fields for DSA secret keys: - // - MPI of DSA secret exponent x. - return 1; - default: - throw new Error('Unknown algorithm'); - } -}, - -getPublicMpiCount: function(algo) { - // - A series of multiprecision integers comprising the key material: - // Algorithm-Specific Fields for RSA public keys: - // - a multiprecision integer (MPI) of RSA public modulus n; - // - an MPI of RSA public encryption exponent e. - switch(algo) { - case 'rsa_encrypt': - case 'rsa_encrypt_sign': - case 'rsa_sign': - return 2; - - // Algorithm-Specific Fields for Elgamal public keys: - // - MPI of Elgamal prime p; - // - MPI of Elgamal group generator g; - // - MPI of Elgamal public key value y (= g**x mod p where x is secret). - case 'elgamal': - return 3; - - // Algorithm-Specific Fields for DSA public keys: - // - MPI of DSA prime p; - // - MPI of DSA group order q (q is a prime divisor of p-1); - // - MPI of DSA group generator g; - // - MPI of DSA public-key value y (= g**x mod p where x is secret). - case 'dsa': - return 4; - - default: - throw new Error('Unknown algorithm.'); - } -}, + return result.map(function(bn) { + var mpi = new type_mpi(); + mpi.fromBigInteger(bn); + return mpi; + }); + }, -/** - * generate random byte prefix as string for the specified algorithm - * @param {Integer} algo Algorithm to use (see RFC4880 9.2) - * @return {String} Random bytes with length equal to the block - * size of the cipher - */ -getPrefixRandom: function(algo) { - return random.getRandomBytes(cipher[algo].blockSize); -}, + /** + * generate random byte prefix as string for the specified algorithm + * @param {Integer} algo Algorithm to use (see RFC4880 9.2) + * @return {String} Random bytes with length equal to the block + * size of the cipher + */ + getPrefixRandom: function(algo) { + return random.getRandomBytes(cipher[algo].blockSize); + }, -/** - * Generating a session key for the specified symmetric algorithm - * @param {Integer} algo Algorithm to use (see RFC4880 9.2) - * @return {String} Random bytes as a string to be used as a key - */ -generateSessionKey: function(algo) { - return random.getRandomBytes(cipher[algo].keySize); -}, + /** + * Generating a session key for the specified symmetric algorithm + * @param {Integer} algo Algorithm to use (see RFC4880 9.2) + * @return {String} Random bytes as a string to be used as a key + */ + generateSessionKey: function(algo) { + return random.getRandomBytes(cipher[algo].keySize); + }, }; -},{"../type/mpi.js":52,"./cipher":7,"./public_key":18,"./random.js":23}],10:[function(require,module,exports){ - +},{"../type/mpi.js":50,"./cipher":7,"./public_key":18,"./random.js":21}],10:[function(require,module,exports){ var sha = require('./sha.js'); module.exports = { - md5: require('./md5.js'), - sha1: sha.sha1, - sha256: sha.sha256, - sha224: sha.sha224, - sha384: sha.sha384, - sha512: sha.sha512, - ripemd: require('./ripe-md.js'), + md5: require('./md5.js'), + sha1: sha.sha1, + sha256: sha.sha256, + sha224: sha.sha224, + sha384: sha.sha384, + sha512: sha.sha512, + ripemd: require('./ripe-md.js'), - /** - * Create a hash on the specified data using the specified algorithm - * @param {Integer} algo Hash algorithm type (see RFC4880 9.4) - * @param {String} data Data to be hashed - * @return {String} hash value - */ - digest: function(algo, data) { - switch(algo) { - case 1: // - MD5 [HAC] - return this.md5(data); - case 2: // - SHA-1 [FIPS180] - return this.sha1(data); - case 3: // - RIPE-MD/160 [HAC] - return this.ripemd(data); - case 8: // - SHA256 [FIPS180] - return this.sha256(data); - case 9: // - SHA384 [FIPS180] - return this.sha384(data); - case 10:// - SHA512 [FIPS180] - return this.sha512(data); - case 11:// - SHA224 [FIPS180] - return this.sha224(data); - default: - throw new Error('Invalid hash function.'); - } - }, + /** + * Create a hash on the specified data using the specified algorithm + * @param {Integer} algo Hash algorithm type (see RFC4880 9.4) + * @param {String} data Data to be hashed + * @return {String} hash value + */ + digest: function(algo, data) { + switch (algo) { + case 1: + // - MD5 [HAC] + return this.md5(data); + case 2: + // - SHA-1 [FIPS180] + return this.sha1(data); + case 3: + // - RIPE-MD/160 [HAC] + return this.ripemd(data); + case 8: + // - SHA256 [FIPS180] + return this.sha256(data); + case 9: + // - SHA384 [FIPS180] + return this.sha384(data); + case 10: + // - SHA512 [FIPS180] + return this.sha512(data); + case 11: + // - SHA224 [FIPS180] + return this.sha224(data); + default: + throw new Error('Invalid hash function.'); + } + }, - /** - * Returns the hash size in bytes of the specified hash algorithm type - * @param {Integer} algo Hash algorithm type (See RFC4880 9.4) - * @return {Integer} Size in bytes of the resulting hash - */ - getHashByteLength: function(algo) { - switch(algo) { - case 1: // - MD5 [HAC] - return 16; - case 2: // - SHA-1 [FIPS180] - case 3: // - RIPE-MD/160 [HAC] - return 20; - case 8: // - SHA256 [FIPS180] - return 32; - case 9: // - SHA384 [FIPS180] - return 48 - case 10:// - SHA512 [FIPS180] - return 64; - case 11:// - SHA224 [FIPS180] - return 28; - default: - throw new Error('Invalid hash algorithm.'); - } - } + /** + * Returns the hash size in bytes of the specified hash algorithm type + * @param {Integer} algo Hash algorithm type (See RFC4880 9.4) + * @return {Integer} Size in bytes of the resulting hash + */ + getHashByteLength: function(algo) { + switch (algo) { + case 1: + // - MD5 [HAC] + return 16; + case 2: + // - SHA-1 [FIPS180] + case 3: + // - RIPE-MD/160 [HAC] + return 20; + case 8: + // - SHA256 [FIPS180] + return 32; + case 9: + // - SHA384 [FIPS180] + return 48 + case 10: + // - SHA512 [FIPS180] + return 64; + case 11: + // - SHA224 [FIPS180] + return 28; + default: + throw new Error('Invalid hash algorithm.'); + } + } } - },{"./md5.js":11,"./ripe-md.js":12,"./sha.js":13}],11:[function(require,module,exports){ /** * A fast MD5 JavaScript implementation @@ -3926,129 +4230,133 @@ module.exports = { var util = require('../../util/util.js'); function MD5(entree) { - var hex = md5(entree); - var bin = util.hex2bin(hex); - return bin; + var hex = md5(entree); + var bin = util.hex2bin(hex); + return bin; } function md5cycle(x, k) { -var a = x[0], b = x[1], c = x[2], d = x[3]; + var a = x[0], + b = x[1], + c = x[2], + d = x[3]; -a = ff(a, b, c, d, k[0], 7, -680876936); -d = ff(d, a, b, c, k[1], 12, -389564586); -c = ff(c, d, a, b, k[2], 17, 606105819); -b = ff(b, c, d, a, k[3], 22, -1044525330); -a = ff(a, b, c, d, k[4], 7, -176418897); -d = ff(d, a, b, c, k[5], 12, 1200080426); -c = ff(c, d, a, b, k[6], 17, -1473231341); -b = ff(b, c, d, a, k[7], 22, -45705983); -a = ff(a, b, c, d, k[8], 7, 1770035416); -d = ff(d, a, b, c, k[9], 12, -1958414417); -c = ff(c, d, a, b, k[10], 17, -42063); -b = ff(b, c, d, a, k[11], 22, -1990404162); -a = ff(a, b, c, d, k[12], 7, 1804603682); -d = ff(d, a, b, c, k[13], 12, -40341101); -c = ff(c, d, a, b, k[14], 17, -1502002290); -b = ff(b, c, d, a, k[15], 22, 1236535329); + a = ff(a, b, c, d, k[0], 7, -680876936); + d = ff(d, a, b, c, k[1], 12, -389564586); + c = ff(c, d, a, b, k[2], 17, 606105819); + b = ff(b, c, d, a, k[3], 22, -1044525330); + a = ff(a, b, c, d, k[4], 7, -176418897); + d = ff(d, a, b, c, k[5], 12, 1200080426); + c = ff(c, d, a, b, k[6], 17, -1473231341); + b = ff(b, c, d, a, k[7], 22, -45705983); + a = ff(a, b, c, d, k[8], 7, 1770035416); + d = ff(d, a, b, c, k[9], 12, -1958414417); + c = ff(c, d, a, b, k[10], 17, -42063); + b = ff(b, c, d, a, k[11], 22, -1990404162); + a = ff(a, b, c, d, k[12], 7, 1804603682); + d = ff(d, a, b, c, k[13], 12, -40341101); + c = ff(c, d, a, b, k[14], 17, -1502002290); + b = ff(b, c, d, a, k[15], 22, 1236535329); -a = gg(a, b, c, d, k[1], 5, -165796510); -d = gg(d, a, b, c, k[6], 9, -1069501632); -c = gg(c, d, a, b, k[11], 14, 643717713); -b = gg(b, c, d, a, k[0], 20, -373897302); -a = gg(a, b, c, d, k[5], 5, -701558691); -d = gg(d, a, b, c, k[10], 9, 38016083); -c = gg(c, d, a, b, k[15], 14, -660478335); -b = gg(b, c, d, a, k[4], 20, -405537848); -a = gg(a, b, c, d, k[9], 5, 568446438); -d = gg(d, a, b, c, k[14], 9, -1019803690); -c = gg(c, d, a, b, k[3], 14, -187363961); -b = gg(b, c, d, a, k[8], 20, 1163531501); -a = gg(a, b, c, d, k[13], 5, -1444681467); -d = gg(d, a, b, c, k[2], 9, -51403784); -c = gg(c, d, a, b, k[7], 14, 1735328473); -b = gg(b, c, d, a, k[12], 20, -1926607734); + a = gg(a, b, c, d, k[1], 5, -165796510); + d = gg(d, a, b, c, k[6], 9, -1069501632); + c = gg(c, d, a, b, k[11], 14, 643717713); + b = gg(b, c, d, a, k[0], 20, -373897302); + a = gg(a, b, c, d, k[5], 5, -701558691); + d = gg(d, a, b, c, k[10], 9, 38016083); + c = gg(c, d, a, b, k[15], 14, -660478335); + b = gg(b, c, d, a, k[4], 20, -405537848); + a = gg(a, b, c, d, k[9], 5, 568446438); + d = gg(d, a, b, c, k[14], 9, -1019803690); + c = gg(c, d, a, b, k[3], 14, -187363961); + b = gg(b, c, d, a, k[8], 20, 1163531501); + a = gg(a, b, c, d, k[13], 5, -1444681467); + d = gg(d, a, b, c, k[2], 9, -51403784); + c = gg(c, d, a, b, k[7], 14, 1735328473); + b = gg(b, c, d, a, k[12], 20, -1926607734); -a = hh(a, b, c, d, k[5], 4, -378558); -d = hh(d, a, b, c, k[8], 11, -2022574463); -c = hh(c, d, a, b, k[11], 16, 1839030562); -b = hh(b, c, d, a, k[14], 23, -35309556); -a = hh(a, b, c, d, k[1], 4, -1530992060); -d = hh(d, a, b, c, k[4], 11, 1272893353); -c = hh(c, d, a, b, k[7], 16, -155497632); -b = hh(b, c, d, a, k[10], 23, -1094730640); -a = hh(a, b, c, d, k[13], 4, 681279174); -d = hh(d, a, b, c, k[0], 11, -358537222); -c = hh(c, d, a, b, k[3], 16, -722521979); -b = hh(b, c, d, a, k[6], 23, 76029189); -a = hh(a, b, c, d, k[9], 4, -640364487); -d = hh(d, a, b, c, k[12], 11, -421815835); -c = hh(c, d, a, b, k[15], 16, 530742520); -b = hh(b, c, d, a, k[2], 23, -995338651); + a = hh(a, b, c, d, k[5], 4, -378558); + d = hh(d, a, b, c, k[8], 11, -2022574463); + c = hh(c, d, a, b, k[11], 16, 1839030562); + b = hh(b, c, d, a, k[14], 23, -35309556); + a = hh(a, b, c, d, k[1], 4, -1530992060); + d = hh(d, a, b, c, k[4], 11, 1272893353); + c = hh(c, d, a, b, k[7], 16, -155497632); + b = hh(b, c, d, a, k[10], 23, -1094730640); + a = hh(a, b, c, d, k[13], 4, 681279174); + d = hh(d, a, b, c, k[0], 11, -358537222); + c = hh(c, d, a, b, k[3], 16, -722521979); + b = hh(b, c, d, a, k[6], 23, 76029189); + a = hh(a, b, c, d, k[9], 4, -640364487); + d = hh(d, a, b, c, k[12], 11, -421815835); + c = hh(c, d, a, b, k[15], 16, 530742520); + b = hh(b, c, d, a, k[2], 23, -995338651); -a = ii(a, b, c, d, k[0], 6, -198630844); -d = ii(d, a, b, c, k[7], 10, 1126891415); -c = ii(c, d, a, b, k[14], 15, -1416354905); -b = ii(b, c, d, a, k[5], 21, -57434055); -a = ii(a, b, c, d, k[12], 6, 1700485571); -d = ii(d, a, b, c, k[3], 10, -1894986606); -c = ii(c, d, a, b, k[10], 15, -1051523); -b = ii(b, c, d, a, k[1], 21, -2054922799); -a = ii(a, b, c, d, k[8], 6, 1873313359); -d = ii(d, a, b, c, k[15], 10, -30611744); -c = ii(c, d, a, b, k[6], 15, -1560198380); -b = ii(b, c, d, a, k[13], 21, 1309151649); -a = ii(a, b, c, d, k[4], 6, -145523070); -d = ii(d, a, b, c, k[11], 10, -1120210379); -c = ii(c, d, a, b, k[2], 15, 718787259); -b = ii(b, c, d, a, k[9], 21, -343485551); + a = ii(a, b, c, d, k[0], 6, -198630844); + d = ii(d, a, b, c, k[7], 10, 1126891415); + c = ii(c, d, a, b, k[14], 15, -1416354905); + b = ii(b, c, d, a, k[5], 21, -57434055); + a = ii(a, b, c, d, k[12], 6, 1700485571); + d = ii(d, a, b, c, k[3], 10, -1894986606); + c = ii(c, d, a, b, k[10], 15, -1051523); + b = ii(b, c, d, a, k[1], 21, -2054922799); + a = ii(a, b, c, d, k[8], 6, 1873313359); + d = ii(d, a, b, c, k[15], 10, -30611744); + c = ii(c, d, a, b, k[6], 15, -1560198380); + b = ii(b, c, d, a, k[13], 21, 1309151649); + a = ii(a, b, c, d, k[4], 6, -145523070); + d = ii(d, a, b, c, k[11], 10, -1120210379); + c = ii(c, d, a, b, k[2], 15, 718787259); + b = ii(b, c, d, a, k[9], 21, -343485551); -x[0] = add32(a, x[0]); -x[1] = add32(b, x[1]); -x[2] = add32(c, x[2]); -x[3] = add32(d, x[3]); + x[0] = add32(a, x[0]); + x[1] = add32(b, x[1]); + x[2] = add32(c, x[2]); + x[3] = add32(d, x[3]); } function cmn(q, a, b, x, s, t) { -a = add32(add32(a, q), add32(x, t)); -return add32((a << s) | (a >>> (32 - s)), b); + a = add32(add32(a, q), add32(x, t)); + return add32((a << s) | (a >>> (32 - s)), b); } function ff(a, b, c, d, x, s, t) { -return cmn((b & c) | ((~b) & d), a, b, x, s, t); + return cmn((b & c) | ((~b) & d), a, b, x, s, t); } function gg(a, b, c, d, x, s, t) { -return cmn((b & d) | (c & (~d)), a, b, x, s, t); + return cmn((b & d) | (c & (~d)), a, b, x, s, t); } function hh(a, b, c, d, x, s, t) { -return cmn(b ^ c ^ d, a, b, x, s, t); + return cmn(b ^ c ^ d, a, b, x, s, t); } function ii(a, b, c, d, x, s, t) { -return cmn(c ^ (b | (~d)), a, b, x, s, t); + return cmn(c ^ (b | (~d)), a, b, x, s, t); } function md51(s) { -txt = ''; -var n = s.length, -state = [1732584193, -271733879, -1732584194, 271733878], i; -for (i=64; i<=s.length; i+=64) { -md5cycle(state, md5blk(s.substring(i-64, i))); -} -s = s.substring(i-64); -var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; -for (i=0; i>2] |= s.charCodeAt(i) << ((i%4) << 3); -tail[i>>2] |= 0x80 << ((i%4) << 3); -if (i > 55) { -md5cycle(state, tail); -for (i=0; i<16; i++) tail[i] = 0; -} -tail[14] = n*8; -md5cycle(state, tail); -return state; + txt = ''; + var n = s.length, + state = [1732584193, -271733879, -1732584194, 271733878], + i; + for (i = 64; i <= s.length; i += 64) { + md5cycle(state, md5blk(s.substring(i - 64, i))); + } + s = s.substring(i - 64); + var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + for (i = 0; i < s.length; i++) + tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3); + tail[i >> 2] |= 0x80 << ((i % 4) << 3); + if (i > 55) { + md5cycle(state, tail); + for (i = 0; i < 16; i++) tail[i] = 0; + } + tail[14] = n * 8; + md5cycle(state, tail); + return state; } /* there needs to be support for Unicode here, @@ -4067,35 +4375,33 @@ return state; * 8-bit unsigned value arrays. */ function md5blk(s) { /* I figured global was faster. */ -var md5blks = [], i; /* Andy King said do it this way. */ -for (i=0; i<64; i+=4) { -md5blks[i>>2] = s.charCodeAt(i) -+ (s.charCodeAt(i+1) << 8) -+ (s.charCodeAt(i+2) << 16) -+ (s.charCodeAt(i+3) << 24); -} -return md5blks; + var md5blks = [], + i; /* Andy King said do it this way. */ + for (i = 0; i < 64; i += 4) { + md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << + 24); + } + return md5blks; } var hex_chr = '0123456789abcdef'.split(''); -function rhex(n) -{ -var s='', j=0; -for(; j<4; j++) -s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] -+ hex_chr[(n >> (j * 8)) & 0x0F]; -return s; +function rhex(n) { + var s = '', + j = 0; + for (; j < 4; j++) + s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F]; + return s; } function hex(x) { -for (var i=0; i> 16) + (y >> 16) + (lsw >> 16); -return (msw << 16) | (lsw & 0xFFFF); -} + function add32(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF), + msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); + } } module.exports = MD5 -},{"../../util/util.js":54}],12:[function(require,module,exports){ +},{"../../util/util.js":52}],12:[function(require,module,exports){ /* * CryptoMX Tools * Copyright (C) 2004 - 2006 Derek Buitenhuis @@ -4141,57 +4447,71 @@ module.exports = MD5 /* Modified by Recurity Labs GmbH */ -var RMDsize = 160; +var RMDsize = 160; var X = new Array(); -function ROL(x, n) -{ - return new Number ((x << n) | ( x >>> (32 - n))); +function ROL(x, n) { + return new Number((x << n) | (x >>> (32 - n))); } -function F(x, y, z) -{ +function F(x, y, z) { return new Number(x ^ y ^ z); } -function G(x, y, z) -{ +function G(x, y, z) { return new Number((x & y) | (~x & z)); } -function H(x, y, z) -{ +function H(x, y, z) { return new Number((x | ~y) ^ z); } -function I(x, y, z) -{ +function I(x, y, z) { return new Number((x & z) | (y & ~z)); } -function J(x, y, z) -{ +function J(x, y, z) { return new Number(x ^ (y | ~z)); } -function mixOneRound(a, b, c, d, e, x, s, roundNumber) -{ - switch (roundNumber) - { - case 0 : a += F(b, c, d) + x + 0x00000000; break; - case 1 : a += G(b, c, d) + x + 0x5a827999; break; - case 2 : a += H(b, c, d) + x + 0x6ed9eba1; break; - case 3 : a += I(b, c, d) + x + 0x8f1bbcdc; break; - case 4 : a += J(b, c, d) + x + 0xa953fd4e; break; - case 5 : a += J(b, c, d) + x + 0x50a28be6; break; - case 6 : a += I(b, c, d) + x + 0x5c4dd124; break; - case 7 : a += H(b, c, d) + x + 0x6d703ef3; break; - case 8 : a += G(b, c, d) + x + 0x7a6d76e9; break; - case 9 : a += F(b, c, d) + x + 0x00000000; break; - - default : document.write("Bogus round number"); break; - } - +function mixOneRound(a, b, c, d, e, x, s, roundNumber) { + switch (roundNumber) { + case 0: + a += F(b, c, d) + x + 0x00000000; + break; + case 1: + a += G(b, c, d) + x + 0x5a827999; + break; + case 2: + a += H(b, c, d) + x + 0x6ed9eba1; + break; + case 3: + a += I(b, c, d) + x + 0x8f1bbcdc; + break; + case 4: + a += J(b, c, d) + x + 0xa953fd4e; + break; + case 5: + a += J(b, c, d) + x + 0x50a28be6; + break; + case 6: + a += I(b, c, d) + x + 0x5c4dd124; + break; + case 7: + a += H(b, c, d) + x + 0x6d703ef3; + break; + case 8: + a += G(b, c, d) + x + 0x7a6d76e9; + break; + case 9: + a += F(b, c, d) + x + 0x00000000; + break; + + default: + document.write("Bogus round number"); + break; + } + a = ROL(a, s) + e; c = ROL(c, 10); @@ -4213,8 +4533,7 @@ function mixOneRound(a, b, c, d, e, x, s, roundNumber) return retBlock; } -function MDinit (MDbuf) -{ +function MDinit(MDbuf) { MDbuf[0] = 0x67452301; MDbuf[1] = 0xefcdab89; MDbuf[2] = 0x98badcfe; @@ -4223,124 +4542,114 @@ function MDinit (MDbuf) } var ROLs = [ - [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], - [ 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] + [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], + [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] ]; var indexes = [ - [ 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], - [ 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] + [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], + [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] ]; -function compress (MDbuf, X) -{ +function compress(MDbuf, X) { blockA = new Array(); blockB = new Array(); var retBlock; - for (var i=0; i < 5; i++) - { + for (var i = 0; i < 5; i++) { blockA[i] = new Number(MDbuf[i]); blockB[i] = new Number(MDbuf[i]); } var step = 0; - for (var j = 0; j < 5; j++) - { - for (var i = 0; i < 16; i++) - { + for (var j = 0; j < 5; j++) { + for (var i = 0; i < 16; i++) { retBlock = mixOneRound( - blockA[(step+0) % 5], - blockA[(step+1) % 5], - blockA[(step+2) % 5], - blockA[(step+3) % 5], - blockA[(step+4) % 5], - X[indexes[j][i]], + blockA[(step + 0) % 5], + blockA[(step + 1) % 5], + blockA[(step + 2) % 5], + blockA[(step + 3) % 5], + blockA[(step + 4) % 5], + X[indexes[j][i]], ROLs[j][i], - j - ); + j); - blockA[(step+0) % 5] = retBlock[0]; - blockA[(step+1) % 5] = retBlock[1]; - blockA[(step+2) % 5] = retBlock[2]; - blockA[(step+3) % 5] = retBlock[3]; - blockA[(step+4) % 5] = retBlock[4]; + blockA[(step + 0) % 5] = retBlock[0]; + blockA[(step + 1) % 5] = retBlock[1]; + blockA[(step + 2) % 5] = retBlock[2]; + blockA[(step + 3) % 5] = retBlock[3]; + blockA[(step + 4) % 5] = retBlock[4]; step += 4; } } step = 0; - for (var j = 5; j < 10; j++) - { - for (var i = 0; i < 16; i++) - { + for (var j = 5; j < 10; j++) { + for (var i = 0; i < 16; i++) { retBlock = mixOneRound( - blockB[(step+0) % 5], - blockB[(step+1) % 5], - blockB[(step+2) % 5], - blockB[(step+3) % 5], - blockB[(step+4) % 5], - X[indexes[j][i]], + blockB[(step + 0) % 5], + blockB[(step + 1) % 5], + blockB[(step + 2) % 5], + blockB[(step + 3) % 5], + blockB[(step + 4) % 5], + X[indexes[j][i]], ROLs[j][i], - j - ); + j); - blockB[(step+0) % 5] = retBlock[0]; - blockB[(step+1) % 5] = retBlock[1]; - blockB[(step+2) % 5] = retBlock[2]; - blockB[(step+3) % 5] = retBlock[3]; - blockB[(step+4) % 5] = retBlock[4]; + blockB[(step + 0) % 5] = retBlock[0]; + blockB[(step + 1) % 5] = retBlock[1]; + blockB[(step + 2) % 5] = retBlock[2]; + blockB[(step + 3) % 5] = retBlock[3]; + blockB[(step + 4) % 5] = retBlock[4]; step += 4; } } blockB[3] += blockA[2] + MDbuf[1]; - MDbuf[1] = MDbuf[2] + blockA[3] + blockB[4]; - MDbuf[2] = MDbuf[3] + blockA[4] + blockB[0]; - MDbuf[3] = MDbuf[4] + blockA[0] + blockB[1]; - MDbuf[4] = MDbuf[0] + blockA[1] + blockB[2]; - MDbuf[0] = blockB[3]; + MDbuf[1] = MDbuf[2] + blockA[3] + blockB[4]; + MDbuf[2] = MDbuf[3] + blockA[4] + blockB[0]; + MDbuf[3] = MDbuf[4] + blockA[0] + blockB[1]; + MDbuf[4] = MDbuf[0] + blockA[1] + blockB[2]; + MDbuf[0] = blockB[3]; } -function zeroX(X) -{ - for (var i = 0; i < 16; i++) { X[i] = 0; } +function zeroX(X) { + for (var i = 0; i < 16; i++) { + X[i] = 0; + } } -function MDfinish (MDbuf, strptr, lswlen, mswlen) -{ +function MDfinish(MDbuf, strptr, lswlen, mswlen) { var X = new Array(16); zeroX(X); var j = 0; - for (var i=0; i < (lswlen & 63); i++) - { + for (var i = 0; i < (lswlen & 63); i++) { X[i >>> 2] ^= (strptr.charCodeAt(j++) & 255) << (8 * (i & 3)); } X[(lswlen >>> 2) & 15] ^= 1 << (8 * (lswlen & 3) + 7); - if ((lswlen & 63) > 55) - { + if ((lswlen & 63) > 55) { compress(MDbuf, X); var X = new Array(16); zeroX(X); @@ -4352,21 +4661,19 @@ function MDfinish (MDbuf, strptr, lswlen, mswlen) compress(MDbuf, X); } -function BYTES_TO_DWORD(fourChars) -{ - var tmp = (fourChars.charCodeAt(3) & 255) << 24; - tmp |= (fourChars.charCodeAt(2) & 255) << 16; - tmp |= (fourChars.charCodeAt(1) & 255) << 8; - tmp |= (fourChars.charCodeAt(0) & 255); +function BYTES_TO_DWORD(fourChars) { + var tmp = (fourChars.charCodeAt(3) & 255) << 24; + tmp |= (fourChars.charCodeAt(2) & 255) << 16; + tmp |= (fourChars.charCodeAt(1) & 255) << 8; + tmp |= (fourChars.charCodeAt(0) & 255); return tmp; } -function RMD(message) -{ - var MDbuf = new Array(RMDsize / 32); - var hashcode = new Array(RMDsize / 8); - var length; +function RMD(message) { + var MDbuf = new Array(RMDsize / 32); + var hashcode = new Array(RMDsize / 8); + var length; var nbytes; MDinit(MDbuf); @@ -4375,11 +4682,9 @@ function RMD(message) var X = new Array(16); zeroX(X); - var j=0; - for (var nbytes=length; nbytes > 63; nbytes -= 64) - { - for (var i=0; i < 16; i++) - { + var j = 0; + for (var nbytes = length; nbytes > 63; nbytes -= 64) { + for (var i = 0; i < 16; i++) { X[i] = BYTES_TO_DWORD(message.substr(j, 4)); j += 4; } @@ -4388,29 +4693,26 @@ function RMD(message) MDfinish(MDbuf, message.substr(j), length, 0); - for (var i=0; i < RMDsize / 8; i += 4) - { - hashcode[i] = MDbuf[i >>> 2] & 255; - hashcode[i+1] = (MDbuf[i >>> 2] >>> 8) & 255; - hashcode[i+2] = (MDbuf[i >>> 2] >>> 16) & 255; - hashcode[i+3] = (MDbuf[i >>> 2] >>> 24) & 255; + for (var i = 0; i < RMDsize / 8; i += 4) { + hashcode[i] = MDbuf[i >>> 2] & 255; + hashcode[i + 1] = (MDbuf[i >>> 2] >>> 8) & 255; + hashcode[i + 2] = (MDbuf[i >>> 2] >>> 16) & 255; + hashcode[i + 3] = (MDbuf[i >>> 2] >>> 24) & 255; } return hashcode; } -function RMDstring(message) -{ +function RMDstring(message) { var hashcode = RMD(message); var retString = ""; - for (var i=0; i < RMDsize/8; i++) - { + for (var i = 0; i < RMDsize / 8; i++) { retString += String.fromCharCode(hashcode[i]); - } + } - return retString; + return retString; } module.exports = RMDstring; @@ -4439,1224 +4741,1118 @@ module.exports = RMDstring; * - str_sha512 */ -var jsSHA = (function () { - - /* - * Configurable variables. Defaults typically work - */ - /* Number of Bits Per character (8 for ASCII, 16 for Unicode) */ - var charSize = 8, - /* base-64 pad character. "=" for strict RFC compliance */ - b64pad = "", - /* hex output format. 0 - lowercase; 1 - uppercase */ - hexCase = 0, +var jsSHA = (function() { - /* - * Int_64 is a object for 2 32-bit numbers emulating a 64-bit number - * - * @constructor - * @param {Number} msint_32 The most significant 32-bits of a 64-bit number - * @param {Number} lsint_32 The least significant 32-bits of a 64-bit number - */ - Int_64 = function (msint_32, lsint_32) - { - this.highOrder = msint_32; - this.lowOrder = lsint_32; - }, + /* + * Configurable variables. Defaults typically work + */ + /* Number of Bits Per character (8 for ASCII, 16 for Unicode) */ + var charSize = 8, + /* base-64 pad character. "=" for strict RFC compliance */ + b64pad = "", + /* hex output format. 0 - lowercase; 1 - uppercase */ + hexCase = 0, - /* - * Convert a string to an array of big-endian words - * If charSize is ASCII, characters >255 have their hi-byte silently - * ignored. - * - * @param {String} str String to be converted to binary representation - * @return Integer array representation of the parameter - */ - str2binb = function (str) - { - var bin = [], mask = (1 << charSize) - 1, - length = str.length * charSize, i; + /* + * Int_64 is a object for 2 32-bit numbers emulating a 64-bit number + * + * @constructor + * @param {Number} msint_32 The most significant 32-bits of a 64-bit number + * @param {Number} lsint_32 The least significant 32-bits of a 64-bit number + */ + Int_64 = function(msint_32, lsint_32) { + this.highOrder = msint_32; + this.lowOrder = lsint_32; + }, - for (i = 0; i < length; i += charSize) - { - bin[i >> 5] |= (str.charCodeAt(i / charSize) & mask) << - (32 - charSize - (i % 32)); - } + /* + * Convert a string to an array of big-endian words + * If charSize is ASCII, characters >255 have their hi-byte silently + * ignored. + * + * @param {String} str String to be converted to binary representation + * @return Integer array representation of the parameter + */ + str2binb = function(str) { + var bin = [], + mask = (1 << charSize) - 1, + length = str.length * charSize, + i; - return bin; - }, + for (i = 0; i < length; i += charSize) { + bin[i >> 5] |= (str.charCodeAt(i / charSize) & mask) << + (32 - charSize - (i % 32)); + } - /* - * Convert a hex string to an array of big-endian words - * - * @param {String} str String to be converted to binary representation - * @return Integer array representation of the parameter - */ - hex2binb = function (str) - { - var bin = [], length = str.length, i, num; + return bin; + }, - for (i = 0; i < length; i += 2) - { - num = parseInt(str.substr(i, 2), 16); - if (!isNaN(num)) - { - bin[i >> 3] |= num << (24 - (4 * (i % 8))); - } - else - { - return "INVALID HEX STRING"; - } - } + /* + * Convert a hex string to an array of big-endian words + * + * @param {String} str String to be converted to binary representation + * @return Integer array representation of the parameter + */ + hex2binb = function(str) { + var bin = [], + length = str.length, + i, num; - return bin; - }, + for (i = 0; i < length; i += 2) { + num = parseInt(str.substr(i, 2), 16); + if (!isNaN(num)) { + bin[i >> 3] |= num << (24 - (4 * (i % 8))); + } else { + return "INVALID HEX STRING"; + } + } - /* - * Convert an array of big-endian words to a hex string. - * - * @private - * @param {Array} binarray Array of integers to be converted to hexidecimal - * representation - * @return Hexidecimal representation of the parameter in String form - */ - binb2hex = function (binarray) - { - var hex_tab = (hexCase) ? "0123456789ABCDEF" : "0123456789abcdef", - str = "", length = binarray.length * 4, i, srcByte; + return bin; + }, - for (i = 0; i < length; i += 1) - { - srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8); - str += hex_tab.charAt((srcByte >> 4) & 0xF) + - hex_tab.charAt(srcByte & 0xF); - } + /* + * Convert an array of big-endian words to a hex string. + * + * @private + * @param {Array} binarray Array of integers to be converted to hexidecimal + * representation + * @return Hexidecimal representation of the parameter in String form + */ + binb2hex = function(binarray) { + var hex_tab = (hexCase) ? "0123456789ABCDEF" : "0123456789abcdef", + str = "", + length = binarray.length * 4, + i, srcByte; - return str; - }, + for (i = 0; i < length; i += 1) { + srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8); + str += hex_tab.charAt((srcByte >> 4) & 0xF) + + hex_tab.charAt(srcByte & 0xF); + } - /* - * Convert an array of big-endian words to a base-64 string - * - * @private - * @param {Array} binarray Array of integers to be converted to base-64 - * representation - * @return Base-64 encoded representation of the parameter in String form - */ - binb2b64 = function (binarray) - { - var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + - "0123456789+/", str = "", length = binarray.length * 4, i, j, - triplet; + return str; + }, - for (i = 0; i < length; i += 3) - { - triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) | - (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) | - ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF); - for (j = 0; j < 4; j += 1) - { - if (i * 8 + j * 6 <= binarray.length * 32) - { - str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F); - } - else - { - str += b64pad; - } - } - } - return str; - }, + /* + * Convert an array of big-endian words to a base-64 string + * + * @private + * @param {Array} binarray Array of integers to be converted to base-64 + * representation + * @return Base-64 encoded representation of the parameter in String form + */ + binb2b64 = function(binarray) { + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + + "0123456789+/", + str = "", + length = binarray.length * 4, + i, j, + triplet; - /* - * Convert an array of big-endian words to a string - */ - binb2str = function (bin) - { - var str = ""; - var mask = (1 << 8) - 1; - for(var i = 0; i < bin.length * 32; i += 8) - str += String.fromCharCode((bin[i>>5] >>> (24 - i%32)) & mask); - return str; - }, - /* - * The 32-bit implementation of circular rotate left - * - * @private - * @param {Number} x The 32-bit integer argument - * @param {Number} n The number of bits to shift - * @return The x shifted circularly by n bits - */ - rotl_32 = function (x, n) - { - return (x << n) | (x >>> (32 - n)); - }, + for (i = 0; i < length; i += 3) { + triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) | + (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) | + ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF); + for (j = 0; j < 4; j += 1) { + if (i * 8 + j * 6 <= binarray.length * 32) { + str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F); + } else { + str += b64pad; + } + } + } + return str; + }, - /* - * The 32-bit implementation of circular rotate right - * - * @private - * @param {Number} x The 32-bit integer argument - * @param {Number} n The number of bits to shift - * @return The x shifted circularly by n bits - */ - rotr_32 = function (x, n) - { - return (x >>> n) | (x << (32 - n)); - }, + /* + * Convert an array of big-endian words to a string + */ + binb2str = function(bin) { + var str = ""; + var mask = (1 << 8) - 1; + for (var i = 0; i < bin.length * 32; i += 8) + str += String.fromCharCode((bin[i >> 5] >>> (24 - i % 32)) & mask); + return str; + }, + /* + * The 32-bit implementation of circular rotate left + * + * @private + * @param {Number} x The 32-bit integer argument + * @param {Number} n The number of bits to shift + * @return The x shifted circularly by n bits + */ + rotl_32 = function(x, n) { + return (x << n) | (x >>> (32 - n)); + }, - /* - * The 64-bit implementation of circular rotate right - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @param {Number} n The number of bits to shift - * @return The x shifted circularly by n bits - */ - rotr_64 = function (x, n) - { - if (n <= 32) - { - return new Int_64( - (x.highOrder >>> n) | (x.lowOrder << (32 - n)), - (x.lowOrder >>> n) | (x.highOrder << (32 - n)) - ); - } - else - { - return new Int_64( - (x.lowOrder >>> n) | (x.highOrder << (32 - n)), - (x.highOrder >>> n) | (x.lowOrder << (32 - n)) - ); - } - }, + /* + * The 32-bit implementation of circular rotate right + * + * @private + * @param {Number} x The 32-bit integer argument + * @param {Number} n The number of bits to shift + * @return The x shifted circularly by n bits + */ + rotr_32 = function(x, n) { + return (x >>> n) | (x << (32 - n)); + }, - /* - * The 32-bit implementation of shift right - * - * @private - * @param {Number} x The 32-bit integer argument - * @param {Number} n The number of bits to shift - * @return The x shifted by n bits - */ - shr_32 = function (x, n) - { - return x >>> n; - }, + /* + * The 64-bit implementation of circular rotate right + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @param {Number} n The number of bits to shift + * @return The x shifted circularly by n bits + */ + rotr_64 = function(x, n) { + if (n <= 32) { + return new Int_64( + (x.highOrder >>> n) | (x.lowOrder << (32 - n)), (x.lowOrder >>> n) | (x.highOrder << (32 - n))); + } else { + return new Int_64( + (x.lowOrder >>> n) | (x.highOrder << (32 - n)), (x.highOrder >>> n) | (x.lowOrder << (32 - n))); + } + }, - /* - * The 64-bit implementation of shift right - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @param {Number} n The number of bits to shift - * @return The x shifted by n bits - */ - shr_64 = function (x, n) - { - if (n <= 32) - { - return new Int_64( - x.highOrder >>> n, - x.lowOrder >>> n | (x.highOrder << (32 - n)) - ); - } - else - { - return new Int_64( - 0, - x.highOrder << (32 - n) - ); - } - }, + /* + * The 32-bit implementation of shift right + * + * @private + * @param {Number} x The 32-bit integer argument + * @param {Number} n The number of bits to shift + * @return The x shifted by n bits + */ + shr_32 = function(x, n) { + return x >>> n; + }, - /* - * The 32-bit implementation of the NIST specified Parity function - * - * @private - * @param {Number} x The first 32-bit integer argument - * @param {Number} y The second 32-bit integer argument - * @param {Number} z The third 32-bit integer argument - * @return The NIST specified output of the function - */ - parity_32 = function (x, y, z) - { - return x ^ y ^ z; - }, + /* + * The 64-bit implementation of shift right + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @param {Number} n The number of bits to shift + * @return The x shifted by n bits + */ + shr_64 = function(x, n) { + if (n <= 32) { + return new Int_64( + x.highOrder >>> n, + x.lowOrder >>> n | (x.highOrder << (32 - n))); + } else { + return new Int_64( + 0, + x.highOrder << (32 - n)); + } + }, - /* - * The 32-bit implementation of the NIST specified Ch function - * - * @private - * @param {Number} x The first 32-bit integer argument - * @param {Number} y The second 32-bit integer argument - * @param {Number} z The third 32-bit integer argument - * @return The NIST specified output of the function - */ - ch_32 = function (x, y, z) - { - return (x & y) ^ (~x & z); - }, + /* + * The 32-bit implementation of the NIST specified Parity function + * + * @private + * @param {Number} x The first 32-bit integer argument + * @param {Number} y The second 32-bit integer argument + * @param {Number} z The third 32-bit integer argument + * @return The NIST specified output of the function + */ + parity_32 = function(x, y, z) { + return x ^ y ^ z; + }, - /* - * The 64-bit implementation of the NIST specified Ch function - * - * @private - * @param {Int_64} x The first 64-bit integer argument - * @param {Int_64} y The second 64-bit integer argument - * @param {Int_64} z The third 64-bit integer argument - * @return The NIST specified output of the function - */ - ch_64 = function (x, y, z) - { - return new Int_64( - (x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder), - (x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder) - ); - }, + /* + * The 32-bit implementation of the NIST specified Ch function + * + * @private + * @param {Number} x The first 32-bit integer argument + * @param {Number} y The second 32-bit integer argument + * @param {Number} z The third 32-bit integer argument + * @return The NIST specified output of the function + */ + ch_32 = function(x, y, z) { + return (x & y) ^ (~x & z); + }, - /* - * The 32-bit implementation of the NIST specified Maj function - * - * @private - * @param {Number} x The first 32-bit integer argument - * @param {Number} y The second 32-bit integer argument - * @param {Number} z The third 32-bit integer argument - * @return The NIST specified output of the function - */ - maj_32 = function (x, y, z) - { - return (x & y) ^ (x & z) ^ (y & z); - }, + /* + * The 64-bit implementation of the NIST specified Ch function + * + * @private + * @param {Int_64} x The first 64-bit integer argument + * @param {Int_64} y The second 64-bit integer argument + * @param {Int_64} z The third 64-bit integer argument + * @return The NIST specified output of the function + */ + ch_64 = function(x, y, z) { + return new Int_64( + (x.highOrder & y.highOrder) ^ (~x.highOrder & z.highOrder), (x.lowOrder & y.lowOrder) ^ (~x.lowOrder & z.lowOrder)); + }, - /* - * The 64-bit implementation of the NIST specified Maj function - * - * @private - * @param {Int_64} x The first 64-bit integer argument - * @param {Int_64} y The second 64-bit integer argument - * @param {Int_64} z The third 64-bit integer argument - * @return The NIST specified output of the function - */ - maj_64 = function (x, y, z) - { - return new Int_64( - (x.highOrder & y.highOrder) ^ - (x.highOrder & z.highOrder) ^ - (y.highOrder & z.highOrder), - (x.lowOrder & y.lowOrder) ^ - (x.lowOrder & z.lowOrder) ^ - (y.lowOrder & z.lowOrder) - ); - }, + /* + * The 32-bit implementation of the NIST specified Maj function + * + * @private + * @param {Number} x The first 32-bit integer argument + * @param {Number} y The second 32-bit integer argument + * @param {Number} z The third 32-bit integer argument + * @return The NIST specified output of the function + */ + maj_32 = function(x, y, z) { + return (x & y) ^ (x & z) ^ (y & z); + }, - /* - * The 32-bit implementation of the NIST specified Sigma0 function - * - * @private - * @param {Number} x The 32-bit integer argument - * @return The NIST specified output of the function - */ - sigma0_32 = function (x) - { - return rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22); - }, + /* + * The 64-bit implementation of the NIST specified Maj function + * + * @private + * @param {Int_64} x The first 64-bit integer argument + * @param {Int_64} y The second 64-bit integer argument + * @param {Int_64} z The third 64-bit integer argument + * @return The NIST specified output of the function + */ + maj_64 = function(x, y, z) { + return new Int_64( + (x.highOrder & y.highOrder) ^ + (x.highOrder & z.highOrder) ^ + (y.highOrder & z.highOrder), (x.lowOrder & y.lowOrder) ^ + (x.lowOrder & z.lowOrder) ^ + (y.lowOrder & z.lowOrder)); + }, - /* - * The 64-bit implementation of the NIST specified Sigma0 function - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @return The NIST specified output of the function - */ - sigma0_64 = function (x) - { - var rotr28 = rotr_64(x, 28), rotr34 = rotr_64(x, 34), - rotr39 = rotr_64(x, 39); + /* + * The 32-bit implementation of the NIST specified Sigma0 function + * + * @private + * @param {Number} x The 32-bit integer argument + * @return The NIST specified output of the function + */ + sigma0_32 = function(x) { + return rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22); + }, - return new Int_64( - rotr28.highOrder ^ rotr34.highOrder ^ rotr39.highOrder, - rotr28.lowOrder ^ rotr34.lowOrder ^ rotr39.lowOrder); - }, + /* + * The 64-bit implementation of the NIST specified Sigma0 function + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @return The NIST specified output of the function + */ + sigma0_64 = function(x) { + var rotr28 = rotr_64(x, 28), + rotr34 = rotr_64(x, 34), + rotr39 = rotr_64(x, 39); - /* - * The 32-bit implementation of the NIST specified Sigma1 function - * - * @private - * @param {Number} x The 32-bit integer argument - * @return The NIST specified output of the function - */ - sigma1_32 = function (x) - { - return rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25); - }, + return new Int_64( + rotr28.highOrder ^ rotr34.highOrder ^ rotr39.highOrder, + rotr28.lowOrder ^ rotr34.lowOrder ^ rotr39.lowOrder); + }, - /* - * The 64-bit implementation of the NIST specified Sigma1 function - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @return The NIST specified output of the function - */ - sigma1_64 = function (x) - { - var rotr14 = rotr_64(x, 14), rotr18 = rotr_64(x, 18), - rotr41 = rotr_64(x, 41); + /* + * The 32-bit implementation of the NIST specified Sigma1 function + * + * @private + * @param {Number} x The 32-bit integer argument + * @return The NIST specified output of the function + */ + sigma1_32 = function(x) { + return rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25); + }, - return new Int_64( - rotr14.highOrder ^ rotr18.highOrder ^ rotr41.highOrder, - rotr14.lowOrder ^ rotr18.lowOrder ^ rotr41.lowOrder); - }, + /* + * The 64-bit implementation of the NIST specified Sigma1 function + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @return The NIST specified output of the function + */ + sigma1_64 = function(x) { + var rotr14 = rotr_64(x, 14), + rotr18 = rotr_64(x, 18), + rotr41 = rotr_64(x, 41); - /* - * The 32-bit implementation of the NIST specified Gamma0 function - * - * @private - * @param {Number} x The 32-bit integer argument - * @return The NIST specified output of the function - */ - gamma0_32 = function (x) - { - return rotr_32(x, 7) ^ rotr_32(x, 18) ^ shr_32(x, 3); - }, + return new Int_64( + rotr14.highOrder ^ rotr18.highOrder ^ rotr41.highOrder, + rotr14.lowOrder ^ rotr18.lowOrder ^ rotr41.lowOrder); + }, - /* - * The 64-bit implementation of the NIST specified Gamma0 function - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @return The NIST specified output of the function - */ - gamma0_64 = function (x) - { - var rotr1 = rotr_64(x, 1), rotr8 = rotr_64(x, 8), shr7 = shr_64(x, 7); + /* + * The 32-bit implementation of the NIST specified Gamma0 function + * + * @private + * @param {Number} x The 32-bit integer argument + * @return The NIST specified output of the function + */ + gamma0_32 = function(x) { + return rotr_32(x, 7) ^ rotr_32(x, 18) ^ shr_32(x, 3); + }, - return new Int_64( - rotr1.highOrder ^ rotr8.highOrder ^ shr7.highOrder, - rotr1.lowOrder ^ rotr8.lowOrder ^ shr7.lowOrder - ); - }, + /* + * The 64-bit implementation of the NIST specified Gamma0 function + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @return The NIST specified output of the function + */ + gamma0_64 = function(x) { + var rotr1 = rotr_64(x, 1), + rotr8 = rotr_64(x, 8), + shr7 = shr_64(x, 7); - /* - * The 32-bit implementation of the NIST specified Gamma1 function - * - * @private - * @param {Number} x The 32-bit integer argument - * @return The NIST specified output of the function - */ - gamma1_32 = function (x) - { - return rotr_32(x, 17) ^ rotr_32(x, 19) ^ shr_32(x, 10); - }, + return new Int_64( + rotr1.highOrder ^ rotr8.highOrder ^ shr7.highOrder, + rotr1.lowOrder ^ rotr8.lowOrder ^ shr7.lowOrder); + }, - /* - * The 64-bit implementation of the NIST specified Gamma1 function - * - * @private - * @param {Int_64} x The 64-bit integer argument - * @return The NIST specified output of the function - */ - gamma1_64 = function (x) - { - var rotr19 = rotr_64(x, 19), rotr61 = rotr_64(x, 61), - shr6 = shr_64(x, 6); + /* + * The 32-bit implementation of the NIST specified Gamma1 function + * + * @private + * @param {Number} x The 32-bit integer argument + * @return The NIST specified output of the function + */ + gamma1_32 = function(x) { + return rotr_32(x, 17) ^ rotr_32(x, 19) ^ shr_32(x, 10); + }, - return new Int_64( - rotr19.highOrder ^ rotr61.highOrder ^ shr6.highOrder, - rotr19.lowOrder ^ rotr61.lowOrder ^ shr6.lowOrder - ); - }, + /* + * The 64-bit implementation of the NIST specified Gamma1 function + * + * @private + * @param {Int_64} x The 64-bit integer argument + * @return The NIST specified output of the function + */ + gamma1_64 = function(x) { + var rotr19 = rotr_64(x, 19), + rotr61 = rotr_64(x, 61), + shr6 = shr_64(x, 6); - /* - * Add two 32-bit integers, wrapping at 2^32. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Number} x The first 32-bit integer argument to be added - * @param {Number} y The second 32-bit integer argument to be added - * @return The sum of x + y - */ - safeAdd_32_2 = function (x, y) - { - var lsw = (x & 0xFFFF) + (y & 0xFFFF), - msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16); + return new Int_64( + rotr19.highOrder ^ rotr61.highOrder ^ shr6.highOrder, + rotr19.lowOrder ^ rotr61.lowOrder ^ shr6.lowOrder); + }, - return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - }, + /* + * Add two 32-bit integers, wrapping at 2^32. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {Number} x The first 32-bit integer argument to be added + * @param {Number} y The second 32-bit integer argument to be added + * @return The sum of x + y + */ + safeAdd_32_2 = function(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF), + msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16); - /* - * Add four 32-bit integers, wrapping at 2^32. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Number} a The first 32-bit integer argument to be added - * @param {Number} b The second 32-bit integer argument to be added - * @param {Number} c The third 32-bit integer argument to be added - * @param {Number} d The fourth 32-bit integer argument to be added - * @return The sum of a + b + c + d - */ - safeAdd_32_4 = function (a, b, c, d) - { - var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF), - msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + - (lsw >>> 16); + return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + }, - return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - }, + /* + * Add four 32-bit integers, wrapping at 2^32. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {Number} a The first 32-bit integer argument to be added + * @param {Number} b The second 32-bit integer argument to be added + * @param {Number} c The third 32-bit integer argument to be added + * @param {Number} d The fourth 32-bit integer argument to be added + * @return The sum of a + b + c + d + */ + safeAdd_32_4 = function(a, b, c, d) { + var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF), + msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + + (lsw >>> 16); - /* - * Add five 32-bit integers, wrapping at 2^32. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Number} a The first 32-bit integer argument to be added - * @param {Number} b The second 32-bit integer argument to be added - * @param {Number} c The third 32-bit integer argument to be added - * @param {Number} d The fourth 32-bit integer argument to be added - * @param {Number} e The fifth 32-bit integer argument to be added - * @return The sum of a + b + c + d + e - */ - safeAdd_32_5 = function (a, b, c, d, e) - { - var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF) + - (e & 0xFFFF), - msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + - (e >>> 16) + (lsw >>> 16); + return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + }, - return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - }, + /* + * Add five 32-bit integers, wrapping at 2^32. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {Number} a The first 32-bit integer argument to be added + * @param {Number} b The second 32-bit integer argument to be added + * @param {Number} c The third 32-bit integer argument to be added + * @param {Number} d The fourth 32-bit integer argument to be added + * @param {Number} e The fifth 32-bit integer argument to be added + * @return The sum of a + b + c + d + e + */ + safeAdd_32_5 = function(a, b, c, d, e) { + var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF) + + (e & 0xFFFF), + msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + + (e >>> 16) + (lsw >>> 16); - /* - * Add two 64-bit integers, wrapping at 2^64. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Int_64} x The first 64-bit integer argument to be added - * @param {Int_64} y The second 64-bit integer argument to be added - * @return The sum of x + y - */ - safeAdd_64_2 = function (x, y) - { - var lsw, msw, lowOrder, highOrder; + return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + }, - lsw = (x.lowOrder & 0xFFFF) + (y.lowOrder & 0xFFFF); - msw = (x.lowOrder >>> 16) + (y.lowOrder >>> 16) + (lsw >>> 16); - lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + /* + * Add two 64-bit integers, wrapping at 2^64. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {Int_64} x The first 64-bit integer argument to be added + * @param {Int_64} y The second 64-bit integer argument to be added + * @return The sum of x + y + */ + safeAdd_64_2 = function(x, y) { + var lsw, msw, lowOrder, highOrder; - lsw = (x.highOrder & 0xFFFF) + (y.highOrder & 0xFFFF) + (msw >>> 16); - msw = (x.highOrder >>> 16) + (y.highOrder >>> 16) + (lsw >>> 16); - highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + lsw = (x.lowOrder & 0xFFFF) + (y.lowOrder & 0xFFFF); + msw = (x.lowOrder >>> 16) + (y.lowOrder >>> 16) + (lsw >>> 16); + lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - return new Int_64(highOrder, lowOrder); - }, + lsw = (x.highOrder & 0xFFFF) + (y.highOrder & 0xFFFF) + (msw >>> 16); + msw = (x.highOrder >>> 16) + (y.highOrder >>> 16) + (lsw >>> 16); + highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - /* - * Add four 64-bit integers, wrapping at 2^64. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Int_64} a The first 64-bit integer argument to be added - * @param {Int_64} b The second 64-bit integer argument to be added - * @param {Int_64} c The third 64-bit integer argument to be added - * @param {Int_64} d The fouth 64-bit integer argument to be added - * @return The sum of a + b + c + d - */ - safeAdd_64_4 = function (a, b, c, d) - { - var lsw, msw, lowOrder, highOrder; + return new Int_64(highOrder, lowOrder); + }, - lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + - (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF); - msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + - (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (lsw >>> 16); - lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + /* + * Add four 64-bit integers, wrapping at 2^64. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {Int_64} a The first 64-bit integer argument to be added + * @param {Int_64} b The second 64-bit integer argument to be added + * @param {Int_64} c The third 64-bit integer argument to be added + * @param {Int_64} d The fouth 64-bit integer argument to be added + * @return The sum of a + b + c + d + */ + safeAdd_64_4 = function(a, b, c, d) { + var lsw, msw, lowOrder, highOrder; - lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + - (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + (msw >>> 16); - msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + - (c.highOrder >>> 16) + (d.highOrder >>> 16) + (lsw >>> 16); - highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + + (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF); + msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + + (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (lsw >>> 16); + lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - return new Int_64(highOrder, lowOrder); - }, + lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + + (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + (msw >>> 16); + msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + + (c.highOrder >>> 16) + (d.highOrder >>> 16) + (lsw >>> 16); + highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - /* - * Add five 64-bit integers, wrapping at 2^64. This uses 16-bit operations - * internally to work around bugs in some JS interpreters. - * - * @private - * @param {Int_64} a The first 64-bit integer argument to be added - * @param {Int_64} b The second 64-bit integer argument to be added - * @param {Int_64} c The third 64-bit integer argument to be added - * @param {Int_64} d The fouth 64-bit integer argument to be added - * @param {Int_64} e The fouth 64-bit integer argument to be added - * @return The sum of a + b + c + d + e - */ - safeAdd_64_5 = function (a, b, c, d, e) - { - var lsw, msw, lowOrder, highOrder; + return new Int_64(highOrder, lowOrder); + }, - lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + - (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF) + - (e.lowOrder & 0xFFFF); - msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + - (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (e.lowOrder >>> 16) + - (lsw >>> 16); - lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + /* + * Add five 64-bit integers, wrapping at 2^64. This uses 16-bit operations + * internally to work around bugs in some JS interpreters. + * + * @private + * @param {Int_64} a The first 64-bit integer argument to be added + * @param {Int_64} b The second 64-bit integer argument to be added + * @param {Int_64} c The third 64-bit integer argument to be added + * @param {Int_64} d The fouth 64-bit integer argument to be added + * @param {Int_64} e The fouth 64-bit integer argument to be added + * @return The sum of a + b + c + d + e + */ + safeAdd_64_5 = function(a, b, c, d, e) { + var lsw, msw, lowOrder, highOrder; - lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + - (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + - (e.highOrder & 0xFFFF) + (msw >>> 16); - msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + - (c.highOrder >>> 16) + (d.highOrder >>> 16) + - (e.highOrder >>> 16) + (lsw >>> 16); - highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); + lsw = (a.lowOrder & 0xFFFF) + (b.lowOrder & 0xFFFF) + + (c.lowOrder & 0xFFFF) + (d.lowOrder & 0xFFFF) + + (e.lowOrder & 0xFFFF); + msw = (a.lowOrder >>> 16) + (b.lowOrder >>> 16) + + (c.lowOrder >>> 16) + (d.lowOrder >>> 16) + (e.lowOrder >>> 16) + + (lsw >>> 16); + lowOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - return new Int_64(highOrder, lowOrder); - }, + lsw = (a.highOrder & 0xFFFF) + (b.highOrder & 0xFFFF) + + (c.highOrder & 0xFFFF) + (d.highOrder & 0xFFFF) + + (e.highOrder & 0xFFFF) + (msw >>> 16); + msw = (a.highOrder >>> 16) + (b.highOrder >>> 16) + + (c.highOrder >>> 16) + (d.highOrder >>> 16) + + (e.highOrder >>> 16) + (lsw >>> 16); + highOrder = ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - /* - * Calculates the SHA-1 hash of the string set at instantiation - * - * @private - * @param {Array} message The binary array representation of the string to - * hash - * @param {Number} messageLen The number of bits in the message - * @return The array of integers representing the SHA-1 hash of message - */ - coreSHA1 = function (message, messageLen) - { - var W = [], a, b, c, d, e, T, ch = ch_32, parity = parity_32, - maj = maj_32, rotl = rotl_32, safeAdd_2 = safeAdd_32_2, i, t, - safeAdd_5 = safeAdd_32_5, appendedMessageLength, - H = [ - 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 - ], - K = [ - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6 - ]; + return new Int_64(highOrder, lowOrder); + }, - /* Append '1' at the end of the binary string */ - message[messageLen >> 5] |= 0x80 << (24 - (messageLen % 32)); - /* Append length of binary string in the position such that the new + /* + * Calculates the SHA-1 hash of the string set at instantiation + * + * @private + * @param {Array} message The binary array representation of the string to + * hash + * @param {Number} messageLen The number of bits in the message + * @return The array of integers representing the SHA-1 hash of message + */ + coreSHA1 = function(message, messageLen) { + var W = [], + a, b, c, d, e, T, ch = ch_32, + parity = parity_32, + maj = maj_32, + rotl = rotl_32, + safeAdd_2 = safeAdd_32_2, + i, t, + safeAdd_5 = safeAdd_32_5, + appendedMessageLength, + H = [ + 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 + ], + K = [ + 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, + 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, + 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, + 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, + 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, + 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, + 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, + 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, + 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, + 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, + 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, + 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, + 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, + 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, + 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, + 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, + 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, + 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, + 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, + 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6 + ]; + + /* Append '1' at the end of the binary string */ + message[messageLen >> 5] |= 0x80 << (24 - (messageLen % 32)); + /* Append length of binary string in the position such that the new length is a multiple of 512. Logic does not work for even multiples of 512 but there can never be even multiples of 512 */ - message[(((messageLen + 65) >> 9) << 4) + 15] = messageLen; + message[(((messageLen + 65) >> 9) << 4) + 15] = messageLen; - appendedMessageLength = message.length; + appendedMessageLength = message.length; - for (i = 0; i < appendedMessageLength; i += 16) - { - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; + for (i = 0; i < appendedMessageLength; i += 16) { + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; - for (t = 0; t < 80; t += 1) - { - if (t < 16) - { - W[t] = message[t + i]; - } - else - { - W[t] = rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); - } + for (t = 0; t < 80; t += 1) { + if (t < 16) { + W[t] = message[t + i]; + } else { + W[t] = rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); + } - if (t < 20) - { - T = safeAdd_5(rotl(a, 5), ch(b, c, d), e, K[t], W[t]); - } - else if (t < 40) - { - T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]); - } - else if (t < 60) - { - T = safeAdd_5(rotl(a, 5), maj(b, c, d), e, K[t], W[t]); - } else { - T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]); - } + if (t < 20) { + T = safeAdd_5(rotl(a, 5), ch(b, c, d), e, K[t], W[t]); + } else if (t < 40) { + T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]); + } else if (t < 60) { + T = safeAdd_5(rotl(a, 5), maj(b, c, d), e, K[t], W[t]); + } else { + T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]); + } - e = d; - d = c; - c = rotl(b, 30); - b = a; - a = T; - } + e = d; + d = c; + c = rotl(b, 30); + b = a; + a = T; + } - H[0] = safeAdd_2(a, H[0]); - H[1] = safeAdd_2(b, H[1]); - H[2] = safeAdd_2(c, H[2]); - H[3] = safeAdd_2(d, H[3]); - H[4] = safeAdd_2(e, H[4]); - } + H[0] = safeAdd_2(a, H[0]); + H[1] = safeAdd_2(b, H[1]); + H[2] = safeAdd_2(c, H[2]); + H[3] = safeAdd_2(d, H[3]); + H[4] = safeAdd_2(e, H[4]); + } - return H; - }, + return H; + }, - /* - * Calculates the desired SHA-2 hash of the string set at instantiation - * - * @private - * @param {Array} The binary array representation of the string to hash - * @param {Number} The number of bits in message - * @param {String} variant The desired SHA-2 variant - * @return The array of integers representing the SHA-2 hash of message - */ - coreSHA2 = function (message, messageLen, variant) - { - var a, b, c, d, e, f, g, h, T1, T2, H, numRounds, lengthPosition, i, t, - binaryStringInc, binaryStringMult, safeAdd_2, safeAdd_4, safeAdd_5, - gamma0, gamma1, sigma0, sigma1, ch, maj, Int, K, W = [], - appendedMessageLength; + /* + * Calculates the desired SHA-2 hash of the string set at instantiation + * + * @private + * @param {Array} The binary array representation of the string to hash + * @param {Number} The number of bits in message + * @param {String} variant The desired SHA-2 variant + * @return The array of integers representing the SHA-2 hash of message + */ + coreSHA2 = function(message, messageLen, variant) { + var a, b, c, d, e, f, g, h, T1, T2, H, numRounds, lengthPosition, i, t, + binaryStringInc, binaryStringMult, safeAdd_2, safeAdd_4, safeAdd_5, + gamma0, gamma1, sigma0, sigma1, ch, maj, Int, K, W = [], + appendedMessageLength; - /* Set up the various function handles and variable for the specific - * variant */ - if (variant === "SHA-224" || variant === "SHA-256") - { - /* 32-bit variant */ - numRounds = 64; - lengthPosition = (((messageLen + 65) >> 9) << 4) + 15; - binaryStringInc = 16; - binaryStringMult = 1; - Int = Number; - safeAdd_2 = safeAdd_32_2; - safeAdd_4 = safeAdd_32_4; - safeAdd_5 = safeAdd_32_5; - gamma0 = gamma0_32; - gamma1 = gamma1_32; - sigma0 = sigma0_32; - sigma1 = sigma1_32; - maj = maj_32; - ch = ch_32; - K = [ - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, - 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, - 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, - 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, - 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, - 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, - 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, - 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 - ]; + /* Set up the various function handles and variable for the specific + * variant */ + if (variant === "SHA-224" || variant === "SHA-256") { + /* 32-bit variant */ + numRounds = 64; + lengthPosition = (((messageLen + 65) >> 9) << 4) + 15; + binaryStringInc = 16; + binaryStringMult = 1; + Int = Number; + safeAdd_2 = safeAdd_32_2; + safeAdd_4 = safeAdd_32_4; + safeAdd_5 = safeAdd_32_5; + gamma0 = gamma0_32; + gamma1 = gamma1_32; + sigma0 = sigma0_32; + sigma1 = sigma1_32; + maj = maj_32; + ch = ch_32; + K = [ + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 + ]; - if (variant === "SHA-224") - { - H = [ - 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, - 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 - ]; - } - else - { - H = [ - 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, - 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 - ]; - } - } - else if (variant === "SHA-384" || variant === "SHA-512") - { - /* 64-bit variant */ - numRounds = 80; - lengthPosition = (((messageLen + 128) >> 10) << 5) + 31; - binaryStringInc = 32; - binaryStringMult = 2; - Int = Int_64; - safeAdd_2 = safeAdd_64_2; - safeAdd_4 = safeAdd_64_4; - safeAdd_5 = safeAdd_64_5; - gamma0 = gamma0_64; - gamma1 = gamma1_64; - sigma0 = sigma0_64; - sigma1 = sigma1_64; - maj = maj_64; - ch = ch_64; + if (variant === "SHA-224") { + H = [ + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 + ]; + } else { + H = [ + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 + ]; + } + } else if (variant === "SHA-384" || variant === "SHA-512") { + /* 64-bit variant */ + numRounds = 80; + lengthPosition = (((messageLen + 128) >> 10) << 5) + 31; + binaryStringInc = 32; + binaryStringMult = 2; + Int = Int_64; + safeAdd_2 = safeAdd_64_2; + safeAdd_4 = safeAdd_64_4; + safeAdd_5 = safeAdd_64_5; + gamma0 = gamma0_64; + gamma1 = gamma1_64; + sigma0 = sigma0_64; + sigma1 = sigma1_64; + maj = maj_64; + ch = ch_64; - K = [ - new Int(0x428a2f98, 0xd728ae22), new Int(0x71374491, 0x23ef65cd), - new Int(0xb5c0fbcf, 0xec4d3b2f), new Int(0xe9b5dba5, 0x8189dbbc), - new Int(0x3956c25b, 0xf348b538), new Int(0x59f111f1, 0xb605d019), - new Int(0x923f82a4, 0xaf194f9b), new Int(0xab1c5ed5, 0xda6d8118), - new Int(0xd807aa98, 0xa3030242), new Int(0x12835b01, 0x45706fbe), - new Int(0x243185be, 0x4ee4b28c), new Int(0x550c7dc3, 0xd5ffb4e2), - new Int(0x72be5d74, 0xf27b896f), new Int(0x80deb1fe, 0x3b1696b1), - new Int(0x9bdc06a7, 0x25c71235), new Int(0xc19bf174, 0xcf692694), - new Int(0xe49b69c1, 0x9ef14ad2), new Int(0xefbe4786, 0x384f25e3), - new Int(0x0fc19dc6, 0x8b8cd5b5), new Int(0x240ca1cc, 0x77ac9c65), - new Int(0x2de92c6f, 0x592b0275), new Int(0x4a7484aa, 0x6ea6e483), - new Int(0x5cb0a9dc, 0xbd41fbd4), new Int(0x76f988da, 0x831153b5), - new Int(0x983e5152, 0xee66dfab), new Int(0xa831c66d, 0x2db43210), - new Int(0xb00327c8, 0x98fb213f), new Int(0xbf597fc7, 0xbeef0ee4), - new Int(0xc6e00bf3, 0x3da88fc2), new Int(0xd5a79147, 0x930aa725), - new Int(0x06ca6351, 0xe003826f), new Int(0x14292967, 0x0a0e6e70), - new Int(0x27b70a85, 0x46d22ffc), new Int(0x2e1b2138, 0x5c26c926), - new Int(0x4d2c6dfc, 0x5ac42aed), new Int(0x53380d13, 0x9d95b3df), - new Int(0x650a7354, 0x8baf63de), new Int(0x766a0abb, 0x3c77b2a8), - new Int(0x81c2c92e, 0x47edaee6), new Int(0x92722c85, 0x1482353b), - new Int(0xa2bfe8a1, 0x4cf10364), new Int(0xa81a664b, 0xbc423001), - new Int(0xc24b8b70, 0xd0f89791), new Int(0xc76c51a3, 0x0654be30), - new Int(0xd192e819, 0xd6ef5218), new Int(0xd6990624, 0x5565a910), - new Int(0xf40e3585, 0x5771202a), new Int(0x106aa070, 0x32bbd1b8), - new Int(0x19a4c116, 0xb8d2d0c8), new Int(0x1e376c08, 0x5141ab53), - new Int(0x2748774c, 0xdf8eeb99), new Int(0x34b0bcb5, 0xe19b48a8), - new Int(0x391c0cb3, 0xc5c95a63), new Int(0x4ed8aa4a, 0xe3418acb), - new Int(0x5b9cca4f, 0x7763e373), new Int(0x682e6ff3, 0xd6b2b8a3), - new Int(0x748f82ee, 0x5defb2fc), new Int(0x78a5636f, 0x43172f60), - new Int(0x84c87814, 0xa1f0ab72), new Int(0x8cc70208, 0x1a6439ec), - new Int(0x90befffa, 0x23631e28), new Int(0xa4506ceb, 0xde82bde9), - new Int(0xbef9a3f7, 0xb2c67915), new Int(0xc67178f2, 0xe372532b), - new Int(0xca273ece, 0xea26619c), new Int(0xd186b8c7, 0x21c0c207), - new Int(0xeada7dd6, 0xcde0eb1e), new Int(0xf57d4f7f, 0xee6ed178), - new Int(0x06f067aa, 0x72176fba), new Int(0x0a637dc5, 0xa2c898a6), - new Int(0x113f9804, 0xbef90dae), new Int(0x1b710b35, 0x131c471b), - new Int(0x28db77f5, 0x23047d84), new Int(0x32caab7b, 0x40c72493), - new Int(0x3c9ebe0a, 0x15c9bebc), new Int(0x431d67c4, 0x9c100d4c), - new Int(0x4cc5d4be, 0xcb3e42b6), new Int(0x597f299c, 0xfc657e2a), - new Int(0x5fcb6fab, 0x3ad6faec), new Int(0x6c44198c, 0x4a475817) - ]; + K = [ + new Int(0x428a2f98, 0xd728ae22), new Int(0x71374491, 0x23ef65cd), + new Int(0xb5c0fbcf, 0xec4d3b2f), new Int(0xe9b5dba5, 0x8189dbbc), + new Int(0x3956c25b, 0xf348b538), new Int(0x59f111f1, 0xb605d019), + new Int(0x923f82a4, 0xaf194f9b), new Int(0xab1c5ed5, 0xda6d8118), + new Int(0xd807aa98, 0xa3030242), new Int(0x12835b01, 0x45706fbe), + new Int(0x243185be, 0x4ee4b28c), new Int(0x550c7dc3, 0xd5ffb4e2), + new Int(0x72be5d74, 0xf27b896f), new Int(0x80deb1fe, 0x3b1696b1), + new Int(0x9bdc06a7, 0x25c71235), new Int(0xc19bf174, 0xcf692694), + new Int(0xe49b69c1, 0x9ef14ad2), new Int(0xefbe4786, 0x384f25e3), + new Int(0x0fc19dc6, 0x8b8cd5b5), new Int(0x240ca1cc, 0x77ac9c65), + new Int(0x2de92c6f, 0x592b0275), new Int(0x4a7484aa, 0x6ea6e483), + new Int(0x5cb0a9dc, 0xbd41fbd4), new Int(0x76f988da, 0x831153b5), + new Int(0x983e5152, 0xee66dfab), new Int(0xa831c66d, 0x2db43210), + new Int(0xb00327c8, 0x98fb213f), new Int(0xbf597fc7, 0xbeef0ee4), + new Int(0xc6e00bf3, 0x3da88fc2), new Int(0xd5a79147, 0x930aa725), + new Int(0x06ca6351, 0xe003826f), new Int(0x14292967, 0x0a0e6e70), + new Int(0x27b70a85, 0x46d22ffc), new Int(0x2e1b2138, 0x5c26c926), + new Int(0x4d2c6dfc, 0x5ac42aed), new Int(0x53380d13, 0x9d95b3df), + new Int(0x650a7354, 0x8baf63de), new Int(0x766a0abb, 0x3c77b2a8), + new Int(0x81c2c92e, 0x47edaee6), new Int(0x92722c85, 0x1482353b), + new Int(0xa2bfe8a1, 0x4cf10364), new Int(0xa81a664b, 0xbc423001), + new Int(0xc24b8b70, 0xd0f89791), new Int(0xc76c51a3, 0x0654be30), + new Int(0xd192e819, 0xd6ef5218), new Int(0xd6990624, 0x5565a910), + new Int(0xf40e3585, 0x5771202a), new Int(0x106aa070, 0x32bbd1b8), + new Int(0x19a4c116, 0xb8d2d0c8), new Int(0x1e376c08, 0x5141ab53), + new Int(0x2748774c, 0xdf8eeb99), new Int(0x34b0bcb5, 0xe19b48a8), + new Int(0x391c0cb3, 0xc5c95a63), new Int(0x4ed8aa4a, 0xe3418acb), + new Int(0x5b9cca4f, 0x7763e373), new Int(0x682e6ff3, 0xd6b2b8a3), + new Int(0x748f82ee, 0x5defb2fc), new Int(0x78a5636f, 0x43172f60), + new Int(0x84c87814, 0xa1f0ab72), new Int(0x8cc70208, 0x1a6439ec), + new Int(0x90befffa, 0x23631e28), new Int(0xa4506ceb, 0xde82bde9), + new Int(0xbef9a3f7, 0xb2c67915), new Int(0xc67178f2, 0xe372532b), + new Int(0xca273ece, 0xea26619c), new Int(0xd186b8c7, 0x21c0c207), + new Int(0xeada7dd6, 0xcde0eb1e), new Int(0xf57d4f7f, 0xee6ed178), + new Int(0x06f067aa, 0x72176fba), new Int(0x0a637dc5, 0xa2c898a6), + new Int(0x113f9804, 0xbef90dae), new Int(0x1b710b35, 0x131c471b), + new Int(0x28db77f5, 0x23047d84), new Int(0x32caab7b, 0x40c72493), + new Int(0x3c9ebe0a, 0x15c9bebc), new Int(0x431d67c4, 0x9c100d4c), + new Int(0x4cc5d4be, 0xcb3e42b6), new Int(0x597f299c, 0xfc657e2a), + new Int(0x5fcb6fab, 0x3ad6faec), new Int(0x6c44198c, 0x4a475817) + ]; - if (variant === "SHA-384") - { - H = [ - new Int(0xcbbb9d5d, 0xc1059ed8), new Int(0x0629a292a, 0x367cd507), - new Int(0x9159015a, 0x3070dd17), new Int(0x0152fecd8, 0xf70e5939), - new Int(0x67332667, 0xffc00b31), new Int(0x98eb44a87, 0x68581511), - new Int(0xdb0c2e0d, 0x64f98fa7), new Int(0x047b5481d, 0xbefa4fa4) - ]; - } - else - { - H = [ - new Int(0x6a09e667, 0xf3bcc908), new Int(0xbb67ae85, 0x84caa73b), - new Int(0x3c6ef372, 0xfe94f82b), new Int(0xa54ff53a, 0x5f1d36f1), - new Int(0x510e527f, 0xade682d1), new Int(0x9b05688c, 0x2b3e6c1f), - new Int(0x1f83d9ab, 0xfb41bd6b), new Int(0x5be0cd19, 0x137e2179) - ]; - } - } + if (variant === "SHA-384") { + H = [ + new Int(0xcbbb9d5d, 0xc1059ed8), new Int(0x0629a292a, 0x367cd507), + new Int(0x9159015a, 0x3070dd17), new Int(0x0152fecd8, 0xf70e5939), + new Int(0x67332667, 0xffc00b31), new Int(0x98eb44a87, 0x68581511), + new Int(0xdb0c2e0d, 0x64f98fa7), new Int(0x047b5481d, 0xbefa4fa4) + ]; + } else { + H = [ + new Int(0x6a09e667, 0xf3bcc908), new Int(0xbb67ae85, 0x84caa73b), + new Int(0x3c6ef372, 0xfe94f82b), new Int(0xa54ff53a, 0x5f1d36f1), + new Int(0x510e527f, 0xade682d1), new Int(0x9b05688c, 0x2b3e6c1f), + new Int(0x1f83d9ab, 0xfb41bd6b), new Int(0x5be0cd19, 0x137e2179) + ]; + } + } - /* Append '1' at the end of the binary string */ - message[messageLen >> 5] |= 0x80 << (24 - messageLen % 32); - /* Append length of binary string in the position such that the new - * length is correct */ - message[lengthPosition] = messageLen; + /* Append '1' at the end of the binary string */ + message[messageLen >> 5] |= 0x80 << (24 - messageLen % 32); + /* Append length of binary string in the position such that the new + * length is correct */ + message[lengthPosition] = messageLen; - appendedMessageLength = message.length; + appendedMessageLength = message.length; - for (i = 0; i < appendedMessageLength; i += binaryStringInc) - { - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - f = H[5]; - g = H[6]; - h = H[7]; + for (i = 0; i < appendedMessageLength; i += binaryStringInc) { + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + f = H[5]; + g = H[6]; + h = H[7]; - for (t = 0; t < numRounds; t += 1) - { - if (t < 16) - { - /* Bit of a hack - for 32-bit, the second term is ignored */ - W[t] = new Int(message[t * binaryStringMult + i], - message[t * binaryStringMult + i + 1]); - } - else - { - W[t] = safeAdd_4( - gamma1(W[t - 2]), W[t - 7], - gamma0(W[t - 15]), W[t - 16] - ); - } + for (t = 0; t < numRounds; t += 1) { + if (t < 16) { + /* Bit of a hack - for 32-bit, the second term is ignored */ + W[t] = new Int(message[t * binaryStringMult + i], + message[t * binaryStringMult + i + 1]); + } else { + W[t] = safeAdd_4( + gamma1(W[t - 2]), W[t - 7], + gamma0(W[t - 15]), W[t - 16]); + } - T1 = safeAdd_5(h, sigma1(e), ch(e, f, g), K[t], W[t]); - T2 = safeAdd_2(sigma0(a), maj(a, b, c)); - h = g; - g = f; - f = e; - e = safeAdd_2(d, T1); - d = c; - c = b; - b = a; - a = safeAdd_2(T1, T2); - } + T1 = safeAdd_5(h, sigma1(e), ch(e, f, g), K[t], W[t]); + T2 = safeAdd_2(sigma0(a), maj(a, b, c)); + h = g; + g = f; + f = e; + e = safeAdd_2(d, T1); + d = c; + c = b; + b = a; + a = safeAdd_2(T1, T2); + } - H[0] = safeAdd_2(a, H[0]); - H[1] = safeAdd_2(b, H[1]); - H[2] = safeAdd_2(c, H[2]); - H[3] = safeAdd_2(d, H[3]); - H[4] = safeAdd_2(e, H[4]); - H[5] = safeAdd_2(f, H[5]); - H[6] = safeAdd_2(g, H[6]); - H[7] = safeAdd_2(h, H[7]); - } + H[0] = safeAdd_2(a, H[0]); + H[1] = safeAdd_2(b, H[1]); + H[2] = safeAdd_2(c, H[2]); + H[3] = safeAdd_2(d, H[3]); + H[4] = safeAdd_2(e, H[4]); + H[5] = safeAdd_2(f, H[5]); + H[6] = safeAdd_2(g, H[6]); + H[7] = safeAdd_2(h, H[7]); + } - switch (variant) - { - case "SHA-224": - return [ - H[0], H[1], H[2], H[3], - H[4], H[5], H[6] - ]; - case "SHA-256": - return H; - case "SHA-384": - return [ - H[0].highOrder, H[0].lowOrder, - H[1].highOrder, H[1].lowOrder, - H[2].highOrder, H[2].lowOrder, - H[3].highOrder, H[3].lowOrder, - H[4].highOrder, H[4].lowOrder, - H[5].highOrder, H[5].lowOrder - ]; - case "SHA-512": - return [ - H[0].highOrder, H[0].lowOrder, - H[1].highOrder, H[1].lowOrder, - H[2].highOrder, H[2].lowOrder, - H[3].highOrder, H[3].lowOrder, - H[4].highOrder, H[4].lowOrder, - H[5].highOrder, H[5].lowOrder, - H[6].highOrder, H[6].lowOrder, - H[7].highOrder, H[7].lowOrder - ]; - default: - /* This should never be reached */ - return []; - } - }, + switch (variant) { + case "SHA-224": + return [ + H[0], H[1], H[2], H[3], + H[4], H[5], H[6]]; + case "SHA-256": + return H; + case "SHA-384": + return [ + H[0].highOrder, H[0].lowOrder, + H[1].highOrder, H[1].lowOrder, + H[2].highOrder, H[2].lowOrder, + H[3].highOrder, H[3].lowOrder, + H[4].highOrder, H[4].lowOrder, + H[5].highOrder, H[5].lowOrder]; + case "SHA-512": + return [ + H[0].highOrder, H[0].lowOrder, + H[1].highOrder, H[1].lowOrder, + H[2].highOrder, H[2].lowOrder, + H[3].highOrder, H[3].lowOrder, + H[4].highOrder, H[4].lowOrder, + H[5].highOrder, H[5].lowOrder, + H[6].highOrder, H[6].lowOrder, + H[7].highOrder, H[7].lowOrder]; + default: + /* This should never be reached */ + return []; + } + }, - /* - * jsSHA is the workhorse of the library. Instantiate it with the string to - * be hashed as the parameter - * - * @constructor - * @param {String} srcString The string to be hashed - * @param {String} inputFormat The format of srcString, ASCII or HEX - */ - jsSHA = function (srcString, inputFormat) - { + /* + * jsSHA is the workhorse of the library. Instantiate it with the string to + * be hashed as the parameter + * + * @constructor + * @param {String} srcString The string to be hashed + * @param {String} inputFormat The format of srcString, ASCII or HEX + */ + jsSHA = function(srcString, inputFormat) { - this.sha1 = null; - this.sha224 = null; - this.sha256 = null; - this.sha384 = null; - this.sha512 = null; + this.sha1 = null; + this.sha224 = null; + this.sha256 = null; + this.sha384 = null; + this.sha512 = null; - this.strBinLen = null; - this.strToHash = null; + this.strBinLen = null; + this.strToHash = null; - /* Convert the input string into the correct type */ - if ("HEX" === inputFormat) - { - if (0 !== (srcString.length % 2)) - { - return "TEXT MUST BE IN BYTE INCREMENTS"; - } - this.strBinLen = srcString.length * 4; - this.strToHash = hex2binb(srcString); - } - else if (("ASCII" === inputFormat) || - ('undefined' === typeof(inputFormat))) - { - this.strBinLen = srcString.length * charSize; - this.strToHash = str2binb(srcString); - } - else - { - return "UNKNOWN TEXT INPUT TYPE"; - } - }; + /* Convert the input string into the correct type */ + if ("HEX" === inputFormat) { + if (0 !== (srcString.length % 2)) { + return "TEXT MUST BE IN BYTE INCREMENTS"; + } + this.strBinLen = srcString.length * 4; + this.strToHash = hex2binb(srcString); + } else if (("ASCII" === inputFormat) || + ('undefined' === typeof(inputFormat))) { + this.strBinLen = srcString.length * charSize; + this.strToHash = str2binb(srcString); + } else { + return "UNKNOWN TEXT INPUT TYPE"; + } + }; - jsSHA.prototype = { - /* - * Returns the desired SHA hash of the string specified at instantiation - * using the specified parameters - * - * @param {String} variant The desired SHA variant (SHA-1, SHA-224, - * SHA-256, SHA-384, or SHA-512) - * @param {String} format The desired output formatting (B64 or HEX) - * @return The string representation of the hash in the format specified - */ - getHash : function (variant, format) - { - var formatFunc = null, message = this.strToHash.slice(); + jsSHA.prototype = { + /* + * Returns the desired SHA hash of the string specified at instantiation + * using the specified parameters + * + * @param {String} variant The desired SHA variant (SHA-1, SHA-224, + * SHA-256, SHA-384, or SHA-512) + * @param {String} format The desired output formatting (B64 or HEX) + * @return The string representation of the hash in the format specified + */ + getHash: function(variant, format) { + var formatFunc = null, + message = this.strToHash.slice(); - switch (format) - { - case "HEX": - formatFunc = binb2hex; - break; - case "B64": - formatFunc = binb2b64; - break; - case "ASCII": - formatFunc = binb2str; - break; - default: - return "FORMAT NOT RECOGNIZED"; - } + switch (format) { + case "HEX": + formatFunc = binb2hex; + break; + case "B64": + formatFunc = binb2b64; + break; + case "ASCII": + formatFunc = binb2str; + break; + default: + return "FORMAT NOT RECOGNIZED"; + } - switch (variant) - { - case "SHA-1": - if (null === this.sha1) - { - this.sha1 = coreSHA1(message, this.strBinLen); - } - return formatFunc(this.sha1); - case "SHA-224": - if (null === this.sha224) - { - this.sha224 = coreSHA2(message, this.strBinLen, variant); - } - return formatFunc(this.sha224); - case "SHA-256": - if (null === this.sha256) - { - this.sha256 = coreSHA2(message, this.strBinLen, variant); - } - return formatFunc(this.sha256); - case "SHA-384": - if (null === this.sha384) - { - this.sha384 = coreSHA2(message, this.strBinLen, variant); - } - return formatFunc(this.sha384); - case "SHA-512": - if (null === this.sha512) - { - this.sha512 = coreSHA2(message, this.strBinLen, variant); - } - return formatFunc(this.sha512); - default: - return "HASH NOT RECOGNIZED"; - } - }, + switch (variant) { + case "SHA-1": + if (null === this.sha1) { + this.sha1 = coreSHA1(message, this.strBinLen); + } + return formatFunc(this.sha1); + case "SHA-224": + if (null === this.sha224) { + this.sha224 = coreSHA2(message, this.strBinLen, variant); + } + return formatFunc(this.sha224); + case "SHA-256": + if (null === this.sha256) { + this.sha256 = coreSHA2(message, this.strBinLen, variant); + } + return formatFunc(this.sha256); + case "SHA-384": + if (null === this.sha384) { + this.sha384 = coreSHA2(message, this.strBinLen, variant); + } + return formatFunc(this.sha384); + case "SHA-512": + if (null === this.sha512) { + this.sha512 = coreSHA2(message, this.strBinLen, variant); + } + return formatFunc(this.sha512); + default: + return "HASH NOT RECOGNIZED"; + } + }, - /* - * Returns the desired HMAC of the string specified at instantiation - * using the key and variant param. - * - * @param {String} key The key used to calculate the HMAC - * @param {String} inputFormat The format of key, ASCII or HEX - * @param {String} variant The desired SHA variant (SHA-1, SHA-224, - * SHA-256, SHA-384, or SHA-512) - * @param {String} outputFormat The desired output formatting - * (B64 or HEX) - * @return The string representation of the hash in the format specified - */ - getHMAC : function (key, inputFormat, variant, outputFormat) - { - var formatFunc, keyToUse, blockByteSize, blockBitSize, i, - retVal, lastArrayIndex, keyBinLen, hashBitSize, - keyWithIPad = [], keyWithOPad = []; + /* + * Returns the desired HMAC of the string specified at instantiation + * using the key and variant param. + * + * @param {String} key The key used to calculate the HMAC + * @param {String} inputFormat The format of key, ASCII or HEX + * @param {String} variant The desired SHA variant (SHA-1, SHA-224, + * SHA-256, SHA-384, or SHA-512) + * @param {String} outputFormat The desired output formatting + * (B64 or HEX) + * @return The string representation of the hash in the format specified + */ + getHMAC: function(key, inputFormat, variant, outputFormat) { + var formatFunc, keyToUse, blockByteSize, blockBitSize, i, + retVal, lastArrayIndex, keyBinLen, hashBitSize, + keyWithIPad = [], + keyWithOPad = []; - /* Validate the output format selection */ - switch (outputFormat) - { - case "HEX": - formatFunc = binb2hex; - break; - case "B64": - formatFunc = binb2b64; - break; - case "ASCII": - formatFunc = binb2str; - break; - default: - return "FORMAT NOT RECOGNIZED"; - } + /* Validate the output format selection */ + switch (outputFormat) { + case "HEX": + formatFunc = binb2hex; + break; + case "B64": + formatFunc = binb2b64; + break; + case "ASCII": + formatFunc = binb2str; + break; + default: + return "FORMAT NOT RECOGNIZED"; + } - /* Validate the hash variant selection and set needed variables */ - switch (variant) - { - case "SHA-1": - blockByteSize = 64; - hashBitSize = 160; - break; - case "SHA-224": - blockByteSize = 64; - hashBitSize = 224; - break; - case "SHA-256": - blockByteSize = 64; - hashBitSize = 256; - break; - case "SHA-384": - blockByteSize = 128; - hashBitSize = 384; - break; - case "SHA-512": - blockByteSize = 128; - hashBitSize = 512; - break; - default: - return "HASH NOT RECOGNIZED"; - } + /* Validate the hash variant selection and set needed variables */ + switch (variant) { + case "SHA-1": + blockByteSize = 64; + hashBitSize = 160; + break; + case "SHA-224": + blockByteSize = 64; + hashBitSize = 224; + break; + case "SHA-256": + blockByteSize = 64; + hashBitSize = 256; + break; + case "SHA-384": + blockByteSize = 128; + hashBitSize = 384; + break; + case "SHA-512": + blockByteSize = 128; + hashBitSize = 512; + break; + default: + return "HASH NOT RECOGNIZED"; + } - /* Validate input format selection */ - if ("HEX" === inputFormat) - { - /* Nibbles must come in pairs */ - if (0 !== (key.length % 2)) - { - return "KEY MUST BE IN BYTE INCREMENTS"; - } - keyToUse = hex2binb(key); - keyBinLen = key.length * 4; - } - else if ("ASCII" === inputFormat) - { - keyToUse = str2binb(key); - keyBinLen = key.length * charSize; - } - else - { - return "UNKNOWN KEY INPUT TYPE"; - } + /* Validate input format selection */ + if ("HEX" === inputFormat) { + /* Nibbles must come in pairs */ + if (0 !== (key.length % 2)) { + return "KEY MUST BE IN BYTE INCREMENTS"; + } + keyToUse = hex2binb(key); + keyBinLen = key.length * 4; + } else if ("ASCII" === inputFormat) { + keyToUse = str2binb(key); + keyBinLen = key.length * charSize; + } else { + return "UNKNOWN KEY INPUT TYPE"; + } - /* These are used multiple times, calculate and store them */ - blockBitSize = blockByteSize * 8; - lastArrayIndex = (blockByteSize / 4) - 1; + /* These are used multiple times, calculate and store them */ + blockBitSize = blockByteSize * 8; + lastArrayIndex = (blockByteSize / 4) - 1; - /* Figure out what to do with the key based on its size relative to - * the hash's block size */ - if (blockByteSize < (keyBinLen / 8)) - { - if ("SHA-1" === variant) - { - keyToUse = coreSHA1(keyToUse, keyBinLen); - } - else - { - keyToUse = coreSHA2(keyToUse, keyBinLen, variant); - } - /* For all variants, the block size is bigger than the output - * size so there will never be a useful byte at the end of the - * string */ - keyToUse[lastArrayIndex] &= 0xFFFFFF00; - } - else if (blockByteSize > (keyBinLen / 8)) - { - /* If the blockByteSize is greater than the key length, there - * will always be at LEAST one "useless" byte at the end of the - * string */ - keyToUse[lastArrayIndex] &= 0xFFFFFF00; - } + /* Figure out what to do with the key based on its size relative to + * the hash's block size */ + if (blockByteSize < (keyBinLen / 8)) { + if ("SHA-1" === variant) { + keyToUse = coreSHA1(keyToUse, keyBinLen); + } else { + keyToUse = coreSHA2(keyToUse, keyBinLen, variant); + } + /* For all variants, the block size is bigger than the output + * size so there will never be a useful byte at the end of the + * string */ + keyToUse[lastArrayIndex] &= 0xFFFFFF00; + } else if (blockByteSize > (keyBinLen / 8)) { + /* If the blockByteSize is greater than the key length, there + * will always be at LEAST one "useless" byte at the end of the + * string */ + keyToUse[lastArrayIndex] &= 0xFFFFFF00; + } - /* Create ipad and opad */ - for (i = 0; i <= lastArrayIndex; i += 1) - { - keyWithIPad[i] = keyToUse[i] ^ 0x36363636; - keyWithOPad[i] = keyToUse[i] ^ 0x5C5C5C5C; - } + /* Create ipad and opad */ + for (i = 0; i <= lastArrayIndex; i += 1) { + keyWithIPad[i] = keyToUse[i] ^ 0x36363636; + keyWithOPad[i] = keyToUse[i] ^ 0x5C5C5C5C; + } - /* Calculate the HMAC */ - if ("SHA-1" === variant) - { - retVal = coreSHA1( - keyWithIPad.concat(this.strToHash), - blockBitSize + this.strBinLen); - retVal = coreSHA1( - keyWithOPad.concat(retVal), - blockBitSize + hashBitSize); - } - else - { - retVal = coreSHA2( - keyWithIPad.concat(this.strToHash), - blockBitSize + this.strBinLen, variant); - retVal = coreSHA2( - keyWithOPad.concat(retVal), - blockBitSize + hashBitSize, variant); - } + /* Calculate the HMAC */ + if ("SHA-1" === variant) { + retVal = coreSHA1( + keyWithIPad.concat(this.strToHash), + blockBitSize + this.strBinLen); + retVal = coreSHA1( + keyWithOPad.concat(retVal), + blockBitSize + hashBitSize); + } else { + retVal = coreSHA2( + keyWithIPad.concat(this.strToHash), + blockBitSize + this.strBinLen, variant); + retVal = coreSHA2( + keyWithOPad.concat(retVal), + blockBitSize + hashBitSize, variant); + } - return (formatFunc(retVal)); - } - }; + return (formatFunc(retVal)); + } + }; - return jsSHA; + return jsSHA; }()); module.exports = { - sha1: function(str) { - var shaObj = new jsSHA(str, "ASCII"); - return shaObj.getHash("SHA-1", "ASCII"); - }, - sha224: function(str) { - var shaObj = new jsSHA(str, "ASCII"); - return shaObj.getHash("SHA-224", "ASCII"); - }, - sha256: function(str) { - var shaObj = new jsSHA(str, "ASCII"); - return shaObj.getHash("SHA-256", "ASCII"); - }, - sha384: function(str) { - var shaObj = new jsSHA(str, "ASCII"); - return shaObj.getHash("SHA-384", "ASCII"); + sha1: function(str) { + var shaObj = new jsSHA(str, "ASCII"); + return shaObj.getHash("SHA-1", "ASCII"); + }, + sha224: function(str) { + var shaObj = new jsSHA(str, "ASCII"); + return shaObj.getHash("SHA-224", "ASCII"); + }, + sha256: function(str) { + var shaObj = new jsSHA(str, "ASCII"); + return shaObj.getHash("SHA-256", "ASCII"); + }, + sha384: function(str) { + var shaObj = new jsSHA(str, "ASCII"); + return shaObj.getHash("SHA-384", "ASCII"); - }, - sha512: function(str) { - var shaObj = new jsSHA(str, "ASCII"); - return shaObj.getHash("SHA-512", "ASCII"); - } + }, + sha512: function(str) { + var shaObj = new jsSHA(str, "ASCII"); + return shaObj.getHash("SHA-512", "ASCII"); + } } },{}],14:[function(require,module,exports){ - module.exports = { - cipher: require('./cipher'), - hash: require('./hash'), - cfb: require('./cfb.js'), - publicKey: require('./public_key'), - signature: require('./signature.js'), - random: require('./random.js'), - pkcs1: require('./pkcs1.js') + cipher: require('./cipher'), + hash: require('./hash'), + cfb: require('./cfb.js'), + publicKey: require('./public_key'), + signature: require('./signature.js'), + random: require('./random.js'), + pkcs1: require('./pkcs1.js') } var crypto = require('./crypto.js'); -for(var i in crypto) - module.exports[i] = crypto[i]; +for (var i in crypto) + module.exports[i] = crypto[i]; - - - -},{"./cfb.js":2,"./cipher":7,"./crypto.js":9,"./hash":10,"./pkcs1.js":15,"./public_key":18,"./random.js":23,"./signature.js":24}],15:[function(require,module,exports){ +},{"./cfb.js":2,"./cipher":7,"./crypto.js":9,"./hash":10,"./pkcs1.js":15,"./public_key":18,"./random.js":21,"./signature.js":22}],15:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH // @@ -5678,112 +5874,122 @@ for(var i in crypto) * ASN1 object identifiers for hashes (See RFC4880 5.2.2) */ hash_headers = new Array(); -hash_headers[1] = [0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10]; -hash_headers[3] = [0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x24,0x03,0x02,0x01,0x05,0x00,0x04,0x14]; -hash_headers[2] = [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14]; -hash_headers[8] = [0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20]; -hash_headers[9] = [0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30]; -hash_headers[10] = [0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40]; -hash_headers[11] = [0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1C]; +hash_headers[1] = [0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, + 0x10 +]; +hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14]; +hash_headers[2] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14]; +hash_headers[8] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, + 0x04, 0x20 +]; +hash_headers[9] = [0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, + 0x04, 0x30 +]; +hash_headers[10] = [0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, + 0x00, 0x04, 0x40 +]; +hash_headers[11] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, + 0x00, 0x04, 0x1C +]; var crypto = require('./crypto.js'), - random = require('./random.js'), - util = require('../util'), - BigInteger = require('./public_key/jsbn.js'), - hash = require('./hash'); - + random = require('./random.js'), + util = require('../util'), + BigInteger = require('./public_key/jsbn.js'), + hash = require('./hash'); + module.exports = { - eme: { - /** - * create a EME-PKCS1-v1_5 padding (See RFC4880 13.1.1) - * @param {String} message message to be padded - * @param {Integer} length Length to the resulting message - * @return {String} EME-PKCS1 padded message - */ - encode: function(message, length) { - if (message.length > length-11) - return -1; - var result = ""; - result += String.fromCharCode(0); - result += String.fromCharCode(2); - for (var i = 0; i < length - message.length - 3; i++) { - result += String.fromCharCode(random.getPseudoRandom(1,255)); - } - result += String.fromCharCode(0); - result += message; - return result; - }, + eme: { + /** + * create a EME-PKCS1-v1_5 padding (See RFC4880 13.1.1) + * @param {String} message message to be padded + * @param {Integer} length Length to the resulting message + * @return {String} EME-PKCS1 padded message + */ + encode: function(message, length) { + if (message.length > length - 11) + return -1; + var result = ""; + result += String.fromCharCode(0); + result += String.fromCharCode(2); + for (var i = 0; i < length - message.length - 3; i++) { + result += String.fromCharCode(random.getPseudoRandom(1, 255)); + } + result += String.fromCharCode(0); + result += message; + return result; + }, - /** - * decodes a EME-PKCS1-v1_5 padding (See RFC4880 13.1.2) - * @param {String} message EME-PKCS1 padded message - * @return {String} decoded message - */ - decode: function(message, len) { - if (message.length < len) - message = String.fromCharCode(0)+message; - if (message.length < 12 || message.charCodeAt(0) != 0 || message.charCodeAt(1) != 2) - return -1; - var i = 2; - while (message.charCodeAt(i) != 0 && message.length > i) - i++; - return message.substring(i+1, message.length); - }, - }, + /** + * decodes a EME-PKCS1-v1_5 padding (See RFC4880 13.1.2) + * @param {String} message EME-PKCS1 padded message + * @return {String} decoded message + */ + decode: function(message, len) { + if (message.length < len) + message = String.fromCharCode(0) + message; + if (message.length < 12 || message.charCodeAt(0) != 0 || message.charCodeAt(1) != 2) + return -1; + var i = 2; + while (message.charCodeAt(i) != 0 && message.length > i) + i++; + return message.substring(i + 1, message.length); + }, + }, - emsa: { + emsa: { - /** - * create a EMSA-PKCS1-v1_5 padding (See RFC4880 13.1.3) - * @param {Integer} algo Hash algorithm type used - * @param {String} data Data to be hashed - * @param {Integer} keylength Key size of the public mpi in bytes - * @returns {String} Hashcode with pkcs1padding as string - */ - encode: function(algo, data, keylength) { - var data2 = ""; - data2 += String.fromCharCode(0x00); - data2 += String.fromCharCode(0x01); - for (var i = 0; i < (keylength - hash_headers[algo].length - 3 - - hash.getHashByteLength(algo)); i++) + /** + * create a EMSA-PKCS1-v1_5 padding (See RFC4880 13.1.3) + * @param {Integer} algo Hash algorithm type used + * @param {String} data Data to be hashed + * @param {Integer} keylength Key size of the public mpi in bytes + * @returns {String} Hashcode with pkcs1padding as string + */ + encode: function(algo, data, keylength) { + var data2 = ""; + data2 += String.fromCharCode(0x00); + data2 += String.fromCharCode(0x01); + for (var i = 0; i < (keylength - hash_headers[algo].length - 3 - + hash.getHashByteLength(algo)); i++) - data2 += String.fromCharCode(0xff); + data2 += String.fromCharCode(0xff); - data2 += String.fromCharCode(0x00); - - for (var i = 0; i < hash_headers[algo].length; i++) - data2 += String.fromCharCode(hash_headers[algo][i]); - - data2 += hash.digest(algo, data); - return new BigInteger(util.hexstrdump(data2),16); - }, + data2 += String.fromCharCode(0x00); - /** - * extract the hash out of an EMSA-PKCS1-v1.5 padding (See RFC4880 13.1.3) - * @param {String} data Hash in pkcs1 encoding - * @returns {String} The hash as string - */ - decode: function(algo, data) { - var i = 0; - if (data.charCodeAt(0) == 0) i++; - else if (data.charCodeAt(0) != 1) return -1; - else i++; + for (var i = 0; i < hash_headers[algo].length; i++) + data2 += String.fromCharCode(hash_headers[algo][i]); - while (data.charCodeAt(i) == 0xFF) i++; - if (data.charCodeAt(i++) != 0) return -1; - var j = 0; - for (j = 0; j < hash_headers[algo].length && j+i < data.length; j++) { - if (data.charCodeAt(j+i) != hash_headers[algo][j]) return -1; - } - i+= j; - if (data.substring(i).length < hash.getHashByteLength(algo)) return -1; - return data.substring(i); - } - } + data2 += hash.digest(algo, data); + return new BigInteger(util.hexstrdump(data2), 16); + }, + + /** + * extract the hash out of an EMSA-PKCS1-v1.5 padding (See RFC4880 13.1.3) + * @param {String} data Hash in pkcs1 encoding + * @returns {String} The hash as string + */ + decode: function(algo, data) { + var i = 0; + if (data.charCodeAt(0) == 0) i++; + else if (data.charCodeAt(0) != 1) return -1; + else i++; + + while (data.charCodeAt(i) == 0xFF) i++; + if (data.charCodeAt(i++) != 0) return -1; + var j = 0; + for (j = 0; j < hash_headers[algo].length && j + i < data.length; j++) { + if (data.charCodeAt(j + i) != hash_headers[algo][j]) return -1; + } + i += j; + if (data.substring(i).length < hash.getHashByteLength(algo)) return -1; + return data.substring(i); + } + } } -},{"../util":54,"./crypto.js":9,"./hash":10,"./public_key/jsbn.js":19,"./random.js":23}],16:[function(require,module,exports){ +},{"../util":52,"./crypto.js":9,"./hash":10,"./public_key/jsbn.js":19,"./random.js":21}],16:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH // @@ -5806,78 +6012,82 @@ module.exports = { var BigInteger = require('./jsbn.js'), random = require('../random.js'), hashModule = require('../hash'), - util = require('../../util'); + util = require('../../util'); function DSA() { - // s1 = ((g**s) mod p) mod q - // s1 = ((s**-1)*(sha-1(m)+(s1*x) mod q) - function sign(hashalgo, m, g, p, q, x) { - // If the output size of the chosen hash is larger than the number of - // bits of q, the hash result is truncated to fit by taking the number - // of leftmost bits equal to the number of bits of q. This (possibly - // truncated) hash function result is treated as a number and used - // directly in the DSA signature algorithm. - var hashed_data = util.getLeftNBits(hashModule.digest(hashalgo,m),q.bitLength()); - var hash = new BigInteger(util.hexstrdump(hashed_data), 16); - var k = random.getRandomBigIntegerInRange(BigInteger.ONE.add(BigInteger.ONE), q.subtract(BigInteger.ONE)); - var s1 = (g.modPow(k,p)).mod(q); - var s2 = (k.modInverse(q).multiply(hash.add(x.multiply(s1)))).mod(q); - var result = new Array(); - result[0] = s1.toMPI(); - result[1] = s2.toMPI(); - return result; - } - function select_hash_algorithm(q) { - var usersetting = openpgp.config.config.prefer_hash_algorithm; - /* - * 1024-bit key, 160-bit q, SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512 hash - * 2048-bit key, 224-bit q, SHA-224, SHA-256, SHA-384, or SHA-512 hash - * 2048-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash - * 3072-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash - */ - switch (Math.round(q.bitLength() / 8)) { - case 20: // 1024 bit - if (usersetting != 2 && - usersetting > 11 && - usersetting != 10 && - usersetting < 8) - return 2; // prefer sha1 - return usersetting; - case 28: // 2048 bit - if (usersetting > 11 && - usersetting < 8) - return 11; - return usersetting; - case 32: // 4096 bit // prefer sha224 - if (usersetting > 10 && - usersetting < 8) - return 8; // prefer sha256 - return usersetting; - default: - util.print_debug("DSA select hash algorithm: returning null for an unknown length of q"); - return null; - - } - } - this.select_hash_algorithm = select_hash_algorithm; - - function verify(hashalgo, s1,s2,m,p,q,g,y) { - var hashed_data = util.getLeftNBits(hashModule.digest(hashalgo,m),q.bitLength()); - var hash = new BigInteger(util.hexstrdump(hashed_data), 16); - if (BigInteger.ZERO.compareTo(s1) > 0 || - s1.compareTo(q) > 0 || - BigInteger.ZERO.compareTo(s2) > 0 || - s2.compareTo(q) > 0) { - util.print_error("invalid DSA Signature"); - return null; - } - var w = s2.modInverse(q); - var u1 = hash.multiply(w).mod(q); - var u2 = s1.multiply(w).mod(q); - return g.modPow(u1,p).multiply(y.modPow(u2,p)).mod(p).mod(q); - } - - /* + // s1 = ((g**s) mod p) mod q + // s1 = ((s**-1)*(sha-1(m)+(s1*x) mod q) + function sign(hashalgo, m, g, p, q, x) { + // If the output size of the chosen hash is larger than the number of + // bits of q, the hash result is truncated to fit by taking the number + // of leftmost bits equal to the number of bits of q. This (possibly + // truncated) hash function result is treated as a number and used + // directly in the DSA signature algorithm. + var hashed_data = util.getLeftNBits(hashModule.digest(hashalgo, m), q.bitLength()); + var hash = new BigInteger(util.hexstrdump(hashed_data), 16); + var k = random.getRandomBigIntegerInRange(BigInteger.ONE.add(BigInteger.ONE), q.subtract(BigInteger.ONE)); + var s1 = (g.modPow(k, p)).mod(q); + var s2 = (k.modInverse(q).multiply(hash.add(x.multiply(s1)))).mod(q); + var result = new Array(); + result[0] = s1.toMPI(); + result[1] = s2.toMPI(); + return result; + } + + function select_hash_algorithm(q) { + var usersetting = openpgp.config.config.prefer_hash_algorithm; + /* + * 1024-bit key, 160-bit q, SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512 hash + * 2048-bit key, 224-bit q, SHA-224, SHA-256, SHA-384, or SHA-512 hash + * 2048-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash + * 3072-bit key, 256-bit q, SHA-256, SHA-384, or SHA-512 hash + */ + switch (Math.round(q.bitLength() / 8)) { + case 20: + // 1024 bit + if (usersetting != 2 && + usersetting > 11 && + usersetting != 10 && + usersetting < 8) + return 2; // prefer sha1 + return usersetting; + case 28: + // 2048 bit + if (usersetting > 11 && + usersetting < 8) + return 11; + return usersetting; + case 32: + // 4096 bit // prefer sha224 + if (usersetting > 10 && + usersetting < 8) + return 8; // prefer sha256 + return usersetting; + default: + util.print_debug("DSA select hash algorithm: returning null for an unknown length of q"); + return null; + + } + } + this.select_hash_algorithm = select_hash_algorithm; + + function verify(hashalgo, s1, s2, m, p, q, g, y) { + var hashed_data = util.getLeftNBits(hashModule.digest(hashalgo, m), q.bitLength()); + var hash = new BigInteger(util.hexstrdump(hashed_data), 16); + if (BigInteger.ZERO.compareTo(s1) > 0 || + s1.compareTo(q) > 0 || + BigInteger.ZERO.compareTo(s2) > 0 || + s2.compareTo(q) > 0) { + util.print_error("invalid DSA Signature"); + return null; + } + var w = s2.modInverse(q); + var u1 = hash.multiply(w).mod(q); + var u2 = s1.multiply(w).mod(q); + return g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q); + } + + /* * unused code. This can be used as a start to write a key generator * function. @@ -5936,14 +6146,14 @@ function DSA() { s = (k.modInverse(q).multiply(hash.add(x.multiply(r)))).mod(q); return s; } */ - this.sign = sign; - this.verify = verify; - // this.generate = generateKey; + this.sign = sign; + this.verify = verify; + // this.generate = generateKey; } module.exports = DSA; -},{"../../util":54,"../hash":10,"../random.js":23,"./jsbn.js":19}],17:[function(require,module,exports){ +},{"../../util":52,"../hash":10,"../random.js":21,"./jsbn.js":19}],17:[function(require,module,exports){ // GPG4Browsers - An OpenPGP implementation in javascript // Copyright (C) 2011 Recurity Labs GmbH // @@ -5969,7 +6179,7 @@ var BigInteger = require('./jsbn.js'), function Elgamal() { - function encrypt(m,g,p,y) { + function encrypt(m, g, p, y) { // choose k in {2,...,p-2} var two = BigInteger.ONE.add(BigInteger.ONE); var pMinus2 = p.subtract(two); @@ -5981,14 +6191,14 @@ function Elgamal() { return c; } - function decrypt(c1,c2,p,x) { - util.print_debug("Elgamal Decrypt:\nc1:"+util.hexstrdump(c1.toMPI())+"\n"+ - "c2:"+util.hexstrdump(c2.toMPI())+"\n"+ - "p:"+util.hexstrdump(p.toMPI())+"\n"+ - "x:"+util.hexstrdump(x.toMPI())); + function decrypt(c1, c2, p, x) { + util.print_debug("Elgamal Decrypt:\nc1:" + util.hexstrdump(c1.toMPI()) + "\n" + + "c2:" + util.hexstrdump(c2.toMPI()) + "\n" + + "p:" + util.hexstrdump(p.toMPI()) + "\n" + + "x:" + util.hexstrdump(x.toMPI())); return (c1.modPow(x, p).modInverse(p)).multiply(c2).mod(p); //var c = c1.pow(x).modInverse(p); // c0^-a mod p - //return c.multiply(c2).mod(p); + //return c.multiply(c2).mod(p); } // signing and signature verification using Elgamal is not required by OpenPGP. @@ -5998,14 +6208,14 @@ function Elgamal() { module.exports = Elgamal; -},{"../../util":54,"../random.js":23,"./jsbn.js":19}],18:[function(require,module,exports){ +},{"../../util":52,"../random.js":21,"./jsbn.js":19}],18:[function(require,module,exports){ module.exports = { - rsa: require('./rsa.js'), - elgamal: require('./elgamal.js'), - dsa: require('./dsa.js') + rsa: require('./rsa.js'), + elgamal: require('./elgamal.js'), + dsa: require('./dsa.js') } -},{"./dsa.js":16,"./elgamal.js":17,"./rsa.js":22}],19:[function(require,module,exports){ +},{"./dsa.js":16,"./elgamal.js":17,"./rsa.js":20}],19:[function(require,module,exports){ /* * Copyright (c) 2003-2005 Tom Wu (tjw@cs.Stanford.EDU) * All Rights Reserved. @@ -6049,18 +6259,22 @@ var dbits; // JavaScript engine analysis var canary = 0xdeadbeefcafe; -var j_lm = ((canary&0xffffff)==0xefcafe); +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); + +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); } + +function nbi() { + return new BigInteger(null); +} // am: Compute w_j += (x*this_i), propagate carries, // c is initial carry, returns final carry. @@ -6070,40 +6284,45 @@ function nbi() { return new BigInteger(null); } // 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; + +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; + +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; + +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; } @@ -6113,8 +6332,8 @@ function am3(i,x,w,j,c,n) { dbits = 30; } else if(j_lm && (navigator != undefined && navigator.appName != "Netscape")) {*/ - BigInteger.prototype.am = am1; - dbits = 26; +BigInteger.prototype.am = am1; +dbits = 26; /*} else { // Mozilla/Netscape seems to prefer am3 BigInteger.prototype.am = am3; @@ -6122,340 +6341,437 @@ else { // Mozilla/Netscape seems to prefer am3 }*/ BigInteger.prototype.DB = dbits; -BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; + 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; + 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; } + +function nbv(i) { + var r = nbi(); + r.fromInt(i); + return r; +} // (protected) set from string and radix -function bnpFromString(s,b) { + +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; } + 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; + 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) + if (sh == 0) this[this.t++] = x; - else if(sh+k > this.DB) { - this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); - } - else - this[this.t-1] |= x< 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 (sh >= this.DB) sh -= this.DB; } - if(k == 8 && (s[0]&0x80) != 0) { + if (k == 8 && (s[0] & 0x80) != 0) { this.s = -1; - if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh; } this.clamp(); - if(mi) BigInteger.ZERO.subTo(this,this); + 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; + 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); + 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; + 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< 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+=this.DB-k); + 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; + } } - else { - d = (this[i]>>(p-=k))&km; - if(p <= 0) { p += this.DB; --i; } - } - if(d > 0) m = true; - if(m) r += int2char(d); + if (d > 0) m = true; + if (m) r += int2char(d); } } - return m?r:"0"; + return m ? r : "0"; } // (public) -this -function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } + +function bnNegate() { + var r = nbi(); + BigInteger.ZERO.subTo(this, r); + return r; +} // (public) |this| -function bnAbs() { return (this.s<0)?this.negate():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 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; + 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; } + 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)); + 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) { + +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; + 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); + +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<= 0; --i) { - r[i+ds+1] = (this[i]>>cbs)|c; - c = (this[i]&bm)<= 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; + for (i = ds - 1; i >= 0; --i) r[i] = 0; r[ds] = c; - r.t = this.t+ds+1; + r.t = this.t + ds + 1; r.s = this.s; r.clamp(); } // (protected) r = this >> n -function bnpRShiftTo(n,r) { + +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; - for(var i = ds+1; i < this.t; ++i) { - r[i-ds-1] |= (this[i]&bm)<>bs; + var ds = Math.floor(n / this.DB); + if (ds >= this.t) { + r.t = 0; + return; } - if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<> 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; + +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) { + if (a.t < this.t) { c -= a.s; - while(i < this.t) { + while (i < this.t) { c += this[i]; - r[i++] = c&this.DM; + r[i++] = c & this.DM; c >>= this.DB; } c += this.s; - } - else { + } else { c += this.s; - while(i < a.t) { + while (i < a.t) { c -= a[i]; - r[i++] = c&this.DM; + 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.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(); + +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.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); + 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; + 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); + 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) { + +function bnpDivRemTo(m, q, r) { var pm = m.abs(); - if(pm.t <= 0) return; + 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); + 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<1)?y[ys-2]>>this.F2:0); - var d1 = this.FV/yt, d2 = (1<= 0) { - r[r.t++] = 1; - r.subTo(t,r); + 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); } - 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) { + 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); + 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); + 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); + 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); + 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 Classic(m) { + this.m = m; +} + function cConvert(x) { - if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); + 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); } + +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; @@ -6473,41 +6789,45 @@ Classic.prototype.sqrTo = cSqrTo; // 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; + 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 + 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 + 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; + 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; + 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); + 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); @@ -6516,29 +6836,41 @@ function montRevert(x) { } // x = x/R mod m (HAC 14.32) + function montReduce(x) { - while(x.t <= this.mt2) // pad x so am has enough room later + 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) { + 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; + 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); + 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]++; } + 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); + 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); } + +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); } + +function montMulTo(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); +} Montgomery.prototype.convert = montConvert; Montgomery.prototype.revert = montRevert; @@ -6547,26 +6879,39 @@ 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; } + +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; + +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< 0) z.mulTo(r2,g,r); - else { var t = r; r = r2; r2 = t; } + 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) { + +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); + if (e < 256 || m.isEven()) z = new Classic(m); + else z = new Montgomery(m); + return this.exp(e, z); } // protected @@ -6659,329 +7004,480 @@ module.exports = BigInteger; // Version 1.2: square() API, isProbablePrime fix // (public) -function bnClone() { var r = nbi(); this.copyTo(r); return r; } +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; + 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))<>24; } + +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; } + +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)); } + +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; + 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"; + 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); + 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) { + +function bnpFromRadix(s, b) { this.fromInt(0); - if(b == null) b = 10; + 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; + 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) { + w = b * w + x; + if (++j >= cs) { this.dMultiply(d); - this.dAddOffset(w,0); + this.dAddOffset(w, 0); j = 0; w = 0; } } - if(j > 0) { - this.dMultiply(Math.pow(b,j)); - this.dAddOffset(w,0); + if (j > 0) { + this.dMultiply(Math.pow(b, j)); + this.dAddOffset(w, 0); } - if(mi) BigInteger.ZERO.subTo(this,this); + if (mi) BigInteger.ZERO.subTo(this, this); } // (protected) alternate constructor -function bnpFromNumber(a,b,c) { - if("number" == typeof b) { + +function bnpFromNumber(a, b, c) { + if ("number" == typeof b) { // new BigInteger(int,int,RNG) - if(a < 2) this.fromInt(1); + 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); + 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 { + } else { // new BigInteger(int,RNG) - var x = new Array(), t = a&7; - x.length = (a>>3)+1; + var x = new Array(), + t = a & 7; + x.length = (a >> 3) + 1; b.nextBytes(x); - if(t > 0) x[0] &= ((1< 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(); + 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+=this.DB-8); - } - else { - d = (this[i]>>(p-=8))&0xff; - if(p <= 0) { p += this.DB; --i; } + 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; + 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; } +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); + +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]); + } 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.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; } + +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; } + +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; } + +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; } + +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]; + 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); + 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); + 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; + 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; + 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; + 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; } + 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); + 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); + 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<>= this.DB; } - if(a.t < this.t) { + if (a.t < this.t) { c += a.s; - while(i < this.t) { + while (i < this.t) { c += this[i]; - r[i++] = c&this.DM; + r[i++] = c & this.DM; c >>= this.DB; } c += this.s; - } - else { + } else { c += this.s; - while(i < a.t) { + while (i < a.t) { c += a[i]; - r[i++] = c&this.DM; + 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.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; } + +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; } + +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; } + +function bnMultiply(a) { + var r = nbi(); + this.multiplyTo(a, r); + return r; +} // (public) this^2 -function bnSquare() { var r = nbi(); this.squareTo(r); return r; } + +function bnSquare() { + var r = nbi(); + this.squareTo(r); + return r; +} // (public) this / a -function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } + +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; } + +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); + 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[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; + +function bnpDAddOffset(n, w) { + if (n == 0) return; + while (this.t <= w) this[this.t++] = 0; this[w] += n; - while(this[w] >= this.DV) { + while (this[w] >= this.DV) { this[w] -= this.DV; - if(++w >= this.t) this[this.t++] = 0; + 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); } + +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; @@ -6989,68 +7485,93 @@ NullExp.prototype.mulTo = nMulTo; NullExp.prototype.sqrTo = nSqrTo; // (public) this^e -function bnPow(e) { return this.exp(e,new NullExp()); } + +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); + +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; + 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); + 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) { + +function bnpMultiplyUpperTo(a, n, r) { --n; - var i = r.t = this.t+a.t-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); + 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); + 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); + 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; } + 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; } +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); + 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); } + +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); } + +function barrettMulTo(x, y, r) { + x.multiplyTo(y, r); + this.reduce(r); +} Barrett.prototype.convert = barrettConvert; Barrett.prototype.revert = barrettRevert; @@ -7059,162 +7580,218 @@ 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; + +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) + if (i < 8) z = new Classic(m); - else if(m.isEven()) + 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< 1) { + if (k > 1) { var g2 = nbi(); - z.sqrTo(g[1],g2); - while(n <= km) { + z.sqrTo(g[1], g2); + while (n <= km) { g[n] = nbi(); - z.mulTo(g2,g[n-2],g[n]); + 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; + 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); + 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 + 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); + } 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<= 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); + 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; } - 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); + 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); + 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; + 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); + 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); + 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 (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; + 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,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]; -var lplim = (1<<26)/lowprimes[lowprimes.length-1]; +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, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, + 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, + 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, + 977, 983, 991, 997 +]; +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; + 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; + 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++]; + 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; + while (i < j) if (m % lowprimes[i++] == 0) return false; } return x.millerRabin(t); } @@ -7222,38 +7799,39 @@ function bnIsProbablePrime(t) { /* added by Recurity Labs */ function nbits(x) { - var n = 1, t; - if ((t = x >>> 16) != 0) { - x = t; - n += 16; - } - if ((t = x >> 8) != 0) { - x = t; - n += 8; - } - if ((t = x >> 4) != 0) { - x = t; - n += 4; - } - if ((t = x >> 2) != 0) { - x = t; - n += 2; - } - if ((t = x >> 1) != 0) { - x = t; - n += 1; - } - return n; + var n = 1, + t; + if ((t = x >>> 16) != 0) { + x = t; + n += 16; + } + if ((t = x >> 8) != 0) { + x = t; + n += 8; + } + if ((t = x >> 4) != 0) { + x = t; + n += 4; + } + if ((t = x >> 2) != 0) { + x = t; + n += 2; + } + if ((t = x >> 1) != 0) { + x = t; + n += 1; + } + return n; } -function bnToMPI () { - var ba = this.toByteArray(); - var size = (ba.length-1)*8+nbits(ba[0]); - var result = ""; - result += String.fromCharCode((size & 0xFF00) >> 8); - result += String.fromCharCode(size & 0xFF); - result += util.bin2str(ba); - return result; +function bnToMPI() { + var ba = this.toByteArray(); + var size = (ba.length - 1) * 8 + nbits(ba[0]); + var result = ""; + result += String.fromCharCode((size & 0xFF00) >> 8); + result += String.fromCharCode(size & 0xFF); + result += util.bin2str(ba); + return result; } /* END of addition */ @@ -7261,22 +7839,28 @@ function bnToMPI () { function bnpMillerRabin(t) { var n1 = this.subtract(BigInteger.ONE); var k = n1.getLowestSetBit(); - if(k <= 0) return false; + if (k <= 0) return false; var r = n1.shiftRight(k); - t = (t+1)>>1; - if(t > lowprimes.length) t = lowprimes.length; + t = (t + 1) >> 1; + if (t > lowprimes.length) t = lowprimes.length; var a = nbi(); - for(var i = 0; i < t; ++i) { + var j, bases = []; + for (var i = 0; i < t; ++i) { //Pick bases at random, instead of starting at 2 - a.fromInt(lowprimes[Math.floor(Math.random()*lowprimes.length)]); - var y = a.modPow(r,this); - if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { + for (;;) { + j = lowprimes[Math.floor(Math.random() * lowprimes.length)]; + if (bases.indexOf(j) == -1) break; + } + bases.push(j); + a.fromInt(j); + 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; + 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; + if (y.compareTo(n1) != 0) return false; } } return true; @@ -7338,9 +7922,4822 @@ BigInteger.prototype.toMPI = bnToMPI; // JSBN-specific extension BigInteger.prototype.square = bnSquare; +},{"../../util":52,"./jsbn.js":19}],20:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// +// RSA implementation + +var BigInteger = require('./jsbn.js'), + util = require('../../util'), + random = require('../random.js'); + +function SecureRandom() { + function nextBytes(byteArray) { + for (var n = 0; n < byteArray.length; n++) { + byteArray[n] = random.getSecureRandomOctet(); + } + } + this.nextBytes = nextBytes; +} + +function RSA() { + /** + * This function uses jsbn Big Num library to decrypt RSA + * @param m + * message + * @param d + * RSA d as BigInteger + * @param p + * RSA p as BigInteger + * @param q + * RSA q as BigInteger + * @param u + * RSA u as BigInteger + * @return {BigInteger} The decrypted value of the message + */ + function decrypt(m, d, p, q, u) { + var xp = m.mod(p).modPow(d.mod(p.subtract(BigInteger.ONE)), p); + var xq = m.mod(q).modPow(d.mod(q.subtract(BigInteger.ONE)), q); + util.print_debug("rsa.js decrypt\nxpn:" + util.hexstrdump(xp.toMPI()) + "\nxqn:" + util.hexstrdump(xq.toMPI())); + + var t = xq.subtract(xp); + if (t[0] == 0) { + t = xp.subtract(xq); + t = t.multiply(u).mod(q); + t = q.subtract(t); + } else { + t = t.multiply(u).mod(q); + } + return t.multiply(p).add(xp); + } + + /** + * encrypt message + * @param m message as BigInteger + * @param e public MPI part as BigInteger + * @param n public MPI part as BigInteger + * @return BigInteger + */ + function encrypt(m, e, n) { + return m.modPowInt(e, n); + } + + /* Sign and Verify */ + function sign(m, d, n) { + return m.modPow(d, n); + } + + function verify(x, e, n) { + return x.modPowInt(e, n); + } + + // "empty" RSA key constructor + + function keyObject() { + this.n = null; + this.e = 0; + this.ee = null; + this.d = null; + this.p = null; + this.q = null; + this.dmp1 = null; + this.dmq1 = null; + this.u = null; + } + + // Generate a new random private key B bits long, using public expt E + + function generate(B, E) { + var key = new keyObject(); + var rng = new SecureRandom(); + var qs = B >> 1; + key.e = parseInt(E, 16); + key.ee = new BigInteger(E, 16); + for (;;) { + for (;;) { + key.p = new BigInteger(B - qs, 1, rng); + if (key.p.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.p.isProbablePrime(10)) + break; + } + for (;;) { + key.q = new BigInteger(qs, 1, rng); + if (key.q.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.q.isProbablePrime(10)) + break; + } + if (key.p.compareTo(key.q) <= 0) { + var t = key.p; + key.p = key.q; + key.q = t; + } + var p1 = key.p.subtract(BigInteger.ONE); + var q1 = key.q.subtract(BigInteger.ONE); + var phi = p1.multiply(q1); + if (phi.gcd(key.ee).compareTo(BigInteger.ONE) == 0) { + key.n = key.p.multiply(key.q); + key.d = key.ee.modInverse(phi); + key.dmp1 = key.d.mod(p1); + key.dmq1 = key.d.mod(q1); + key.u = key.p.modInverse(key.q); + break; + } + } + return key; + } + + this.encrypt = encrypt; + this.decrypt = decrypt; + this.verify = verify; + this.sign = sign; + this.generate = generate; + this.keyObject = keyObject; +} + +module.exports = RSA; + +},{"../../util":52,"../random.js":21,"./jsbn.js":19}],21:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +// The GPG4Browsers crypto interface + +var type_mpi = require('../type/mpi.js'); + +module.exports = { + /** + * Retrieve secure random byte string of the specified length + * @param {Integer} length Length in bytes to generate + * @return {String} Random byte string + */ + getRandomBytes: function(length) { + var result = ''; + for (var i = 0; i < length; i++) { + result += String.fromCharCode(this.getSecureRandomOctet()); + } + return result; + }, + + /** + * Return a pseudo-random number in the specified range + * @param {Integer} from Min of the random number + * @param {Integer} to Max of the random number (max 32bit) + * @return {Integer} A pseudo random number + */ + getPseudoRandom: function(from, to) { + return Math.round(Math.random() * (to - from)) + from; + }, + + /** + * Return a secure random number in the specified range + * @param {Integer} from Min of the random number + * @param {Integer} to Max of the random number (max 32bit) + * @return {Integer} A secure random number + */ + getSecureRandom: function(from, to) { + var buf = new Uint32Array(1); + window.crypto.getRandomValues(buf); + var bits = ((to - from)).toString(2).length; + while ((buf[0] & (Math.pow(2, bits) - 1)) > (to - from)) + window.crypto.getRandomValues(buf); + return from + (Math.abs(buf[0] & (Math.pow(2, bits) - 1))); + }, + + getSecureRandomOctet: function() { + var buf = new Uint32Array(1); + window.crypto.getRandomValues(buf); + return buf[0] & 0xFF; + }, + + /** + * Create a secure random big integer of bits length + * @param {Integer} bits Bit length of the MPI to create + * @return {BigInteger} Resulting big integer + */ + getRandomBigInteger: function(bits) { + if (bits < 0) { + return null; + } + var numBytes = Math.floor((bits + 7) / 8); + + var randomBits = this.getRandomBytes(numBytes); + if (bits % 8 > 0) { + + randomBits = String.fromCharCode( + (Math.pow(2, bits % 8) - 1) & + randomBits.charCodeAt(0)) + + randomBits.substring(1); + } + var mpi = new type_mpi(); + mpi.fromBytes(randomBits); + return mpi.toBigInteger(); + }, + + getRandomBigIntegerInRange: function(min, max) { + if (max.compareTo(min) <= 0) { + return; + } + + var range = max.subtract(min); + var r = this.getRandomBigInteger(range.bitLength()); + while (r > range) { + r = this.getRandomBigInteger(range.bitLength()); + } + return min.add(r); + } + +}; + +},{"../type/mpi.js":50}],22:[function(require,module,exports){ +var publicKey = require('./public_key'), + pkcs1 = require('./pkcs1.js'), + hashModule = require('./hash'); + +module.exports = { + /** + * + * @param {Integer} algo public Key algorithm + * @param {Integer} hash_algo Hash algorithm + * @param {openpgp_type_mpi[]} msg_MPIs Signature multiprecision integers + * @param {openpgp_type_mpi[]} publickey_MPIs Public key multiprecision integers + * @param {String} data Data on where the signature was computed on. + * @return {Boolean} true if signature (sig_data was equal to data over hash) + */ + verify: function(algo, hash_algo, msg_MPIs, publickey_MPIs, data) { + var calc_hash = hashModule.digest(hash_algo, data); + + switch (algo) { + case 1: + // RSA (Encrypt or Sign) [HAC] + case 2: + // RSA Encrypt-Only [HAC] + case 3: + // RSA Sign-Only [HAC] + var rsa = new publicKey.rsa(); + var n = publickey_MPIs[0].toBigInteger(); + var e = publickey_MPIs[1].toBigInteger(); + var x = msg_MPIs[0].toBigInteger(); + var dopublic = rsa.verify(x, e, n); + var hash = pkcs1.emsa.decode(hash_algo, dopublic.toMPI().substring(2)); + if (hash == -1) { + throw new Error('PKCS1 padding in message or key incorrect. Aborting...'); + } + return hash == calc_hash; + + case 16: + // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] + throw new Error("signing with Elgamal is not defined in the OpenPGP standard."); + case 17: + // DSA (Digital Signature Algorithm) [FIPS186] [HAC] + var dsa = new publicKey.dsa(); + var s1 = msg_MPIs[0].toBigInteger(); + var s2 = msg_MPIs[1].toBigInteger(); + var p = publickey_MPIs[0].toBigInteger(); + var q = publickey_MPIs[1].toBigInteger(); + var g = publickey_MPIs[2].toBigInteger(); + var y = publickey_MPIs[3].toBigInteger(); + var m = data; + var dopublic = dsa.verify(hash_algo, s1, s2, m, p, q, g, y); + return dopublic.compareTo(s1) == 0; + default: + throw new Error('Invalid signature algorithm.'); + } + + }, + + /** + * Create a signature on data using the specified algorithm + * @param {Integer} hash_algo hash Algorithm to use (See RFC4880 9.4) + * @param {Integer} algo Asymmetric cipher algorithm to use (See RFC4880 9.1) + * @param {openpgp_type_mpi[]} publicMPIs Public key multiprecision integers + * of the private key + * @param {openpgp_type_mpi[]} secretMPIs Private key multiprecision + * integers which is used to sign the data + * @param {String} data Data to be signed + * @return {openpgp_type_mpi[]} + */ + sign: function(hash_algo, algo, keyIntegers, data) { + + switch (algo) { + case 1: + // RSA (Encrypt or Sign) [HAC] + case 2: + // RSA Encrypt-Only [HAC] + case 3: + // RSA Sign-Only [HAC] + var rsa = new publicKey.rsa(); + var d = keyIntegers[2].toBigInteger(); + var n = keyIntegers[0].toBigInteger(); + var m = pkcs1.emsa.encode(hash_algo, + data, keyIntegers[0].byteLength()); + + return rsa.sign(m, d, n).toMPI(); + + case 17: + // DSA (Digital Signature Algorithm) [FIPS186] [HAC] + var dsa = new publicKey.dsa(); + + var p = keyIntegers[0].toBigInteger(); + var q = keyIntegers[1].toBigInteger(); + var g = keyIntegers[2].toBigInteger(); + var y = keyIntegers[3].toBigInteger(); + var x = keyIntegers[4].toBigInteger(); + var m = data; + var result = dsa.sign(hash_algo, m, g, p, q, x); + + return result[0].toString() + result[1].toString(); + case 16: + // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] + throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.'); + default: + throw new Error('Invalid signature algorithm.'); + } + } +} + +},{"./hash":10,"./pkcs1.js":15,"./public_key":18}],23:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var base64 = require('./base64.js'); -},{"../../util":54,"./jsbn.js":19}],20:[function(require,module,exports){ + +/** + * Finds out which Ascii Armoring type is used. This is an internal function + * @param {String} text [String] ascii armored text + * @returns {Integer} 0 = MESSAGE PART n of m + * 1 = MESSAGE PART n + * 2 = SIGNED MESSAGE + * 3 = PGP MESSAGE + * 4 = PUBLIC KEY BLOCK + * 5 = PRIVATE KEY BLOCK + * null = unknown + */ +function get_type(text) { + var splittedtext = text.split('-----'); + // BEGIN PGP MESSAGE, PART X/Y + // Used for multi-part messages, where the armor is split amongst Y + // parts, and this is the Xth part out of Y. + if (splittedtext[1].match(/BEGIN PGP MESSAGE, PART \d+\/\d+/)) { + return 0; + } else + // BEGIN PGP MESSAGE, PART X + // Used for multi-part messages, where this is the Xth part of an + // unspecified number of parts. Requires the MESSAGE-ID Armor + // Header to be used. + if (splittedtext[1].match(/BEGIN PGP MESSAGE, PART \d+/)) { + return 1; + + } else + // BEGIN PGP SIGNATURE + // Used for detached signatures, OpenPGP/MIME signatures, and + // cleartext signatures. Note that PGP 2.x uses BEGIN PGP MESSAGE + // for detached signatures. + if (splittedtext[1].match(/BEGIN PGP SIGNED MESSAGE/)) { + return 2; + + } else + // BEGIN PGP MESSAGE + // Used for signed, encrypted, or compressed files. + if (splittedtext[1].match(/BEGIN PGP MESSAGE/)) { + return 3; + + } else + // BEGIN PGP PUBLIC KEY BLOCK + // Used for armoring public keys. + if (splittedtext[1].match(/BEGIN PGP PUBLIC KEY BLOCK/)) { + return 4; + + } else + // BEGIN PGP PRIVATE KEY BLOCK + // Used for armoring private keys. + if (splittedtext[1].match(/BEGIN PGP PRIVATE KEY BLOCK/)) { + return 5; + } +} + +/** + * Add additional information to the armor version of an OpenPGP binary + * packet block. + * @author Alex + * @version 2011-12-16 + * @returns {String} The header information + */ +function armor_addheader() { + var result = ""; + if (openpgp.config.config.show_version) { + result += "Version: " + openpgp.config.versionstring + '\r\n'; + } + if (openpgp.config.config.show_comment) { + result += "Comment: " + openpgp.config.commentstring + '\r\n'; + } + result += '\r\n'; + return result; +} + + + +/** + * Calculates a checksum over the given data and returns it base64 encoded + * @param {String} data Data to create a CRC-24 checksum for + * @return {String} Base64 encoded checksum + */ +function getCheckSum(data) { + var c = createcrc24(data); + var str = "" + String.fromCharCode(c >> 16) + + String.fromCharCode((c >> 8) & 0xFF) + + String.fromCharCode(c & 0xFF); + return base64.encode(str); +} + +/** + * Calculates the checksum over the given data and compares it with the + * given base64 encoded checksum + * @param {String} data Data to create a CRC-24 checksum for + * @param {String} checksum Base64 encoded checksum + * @return {Boolean} True if the given checksum is correct; otherwise false + */ +function verifyCheckSum(data, checksum) { + var c = getCheckSum(data); + var d = checksum; + return c[0] == d[0] && c[1] == d[1] && c[2] == d[2]; +} +/** + * Internal function to calculate a CRC-24 checksum over a given string (data) + * @param {String} data Data to create a CRC-24 checksum for + * @return {Integer} The CRC-24 checksum as number + */ +var crc_table = [ + 0x00000000, 0x00864cfb, 0x018ad50d, 0x010c99f6, 0x0393e6e1, 0x0315aa1a, 0x021933ec, 0x029f7f17, 0x07a18139, + 0x0727cdc2, 0x062b5434, 0x06ad18cf, 0x043267d8, 0x04b42b23, 0x05b8b2d5, 0x053efe2e, 0x0fc54e89, 0x0f430272, + 0x0e4f9b84, 0x0ec9d77f, 0x0c56a868, 0x0cd0e493, 0x0ddc7d65, 0x0d5a319e, 0x0864cfb0, 0x08e2834b, 0x09ee1abd, + 0x09685646, 0x0bf72951, 0x0b7165aa, 0x0a7dfc5c, 0x0afbb0a7, 0x1f0cd1e9, 0x1f8a9d12, 0x1e8604e4, 0x1e00481f, + 0x1c9f3708, 0x1c197bf3, 0x1d15e205, 0x1d93aefe, 0x18ad50d0, 0x182b1c2b, 0x192785dd, 0x19a1c926, 0x1b3eb631, + 0x1bb8faca, 0x1ab4633c, 0x1a322fc7, 0x10c99f60, 0x104fd39b, 0x11434a6d, 0x11c50696, 0x135a7981, 0x13dc357a, + 0x12d0ac8c, 0x1256e077, 0x17681e59, 0x17ee52a2, 0x16e2cb54, 0x166487af, 0x14fbf8b8, 0x147db443, 0x15712db5, + 0x15f7614e, 0x3e19a3d2, 0x3e9fef29, 0x3f9376df, 0x3f153a24, 0x3d8a4533, 0x3d0c09c8, 0x3c00903e, 0x3c86dcc5, + 0x39b822eb, 0x393e6e10, 0x3832f7e6, 0x38b4bb1d, 0x3a2bc40a, 0x3aad88f1, 0x3ba11107, 0x3b275dfc, 0x31dced5b, + 0x315aa1a0, + 0x30563856, 0x30d074ad, 0x324f0bba, 0x32c94741, 0x33c5deb7, 0x3343924c, 0x367d6c62, 0x36fb2099, 0x37f7b96f, + 0x3771f594, 0x35ee8a83, 0x3568c678, 0x34645f8e, 0x34e21375, 0x2115723b, 0x21933ec0, 0x209fa736, 0x2019ebcd, + 0x228694da, 0x2200d821, 0x230c41d7, 0x238a0d2c, 0x26b4f302, 0x2632bff9, 0x273e260f, 0x27b86af4, 0x252715e3, + 0x25a15918, 0x24adc0ee, 0x242b8c15, 0x2ed03cb2, 0x2e567049, 0x2f5ae9bf, 0x2fdca544, 0x2d43da53, 0x2dc596a8, + 0x2cc90f5e, 0x2c4f43a5, 0x2971bd8b, 0x29f7f170, 0x28fb6886, 0x287d247d, 0x2ae25b6a, 0x2a641791, 0x2b688e67, + 0x2beec29c, 0x7c3347a4, 0x7cb50b5f, 0x7db992a9, 0x7d3fde52, 0x7fa0a145, 0x7f26edbe, 0x7e2a7448, 0x7eac38b3, + 0x7b92c69d, 0x7b148a66, 0x7a181390, 0x7a9e5f6b, 0x7801207c, 0x78876c87, 0x798bf571, 0x790db98a, 0x73f6092d, + 0x737045d6, 0x727cdc20, 0x72fa90db, 0x7065efcc, 0x70e3a337, 0x71ef3ac1, 0x7169763a, 0x74578814, 0x74d1c4ef, + 0x75dd5d19, 0x755b11e2, 0x77c46ef5, 0x7742220e, 0x764ebbf8, 0x76c8f703, 0x633f964d, 0x63b9dab6, 0x62b54340, + 0x62330fbb, + 0x60ac70ac, 0x602a3c57, 0x6126a5a1, 0x61a0e95a, 0x649e1774, 0x64185b8f, 0x6514c279, 0x65928e82, 0x670df195, + 0x678bbd6e, 0x66872498, 0x66016863, 0x6cfad8c4, 0x6c7c943f, 0x6d700dc9, 0x6df64132, 0x6f693e25, 0x6fef72de, + 0x6ee3eb28, 0x6e65a7d3, 0x6b5b59fd, 0x6bdd1506, 0x6ad18cf0, 0x6a57c00b, 0x68c8bf1c, 0x684ef3e7, 0x69426a11, + 0x69c426ea, 0x422ae476, 0x42aca88d, 0x43a0317b, 0x43267d80, 0x41b90297, 0x413f4e6c, 0x4033d79a, 0x40b59b61, + 0x458b654f, 0x450d29b4, 0x4401b042, 0x4487fcb9, 0x461883ae, 0x469ecf55, 0x479256a3, 0x47141a58, 0x4defaaff, + 0x4d69e604, 0x4c657ff2, 0x4ce33309, 0x4e7c4c1e, 0x4efa00e5, 0x4ff69913, 0x4f70d5e8, 0x4a4e2bc6, 0x4ac8673d, + 0x4bc4fecb, 0x4b42b230, 0x49ddcd27, 0x495b81dc, 0x4857182a, 0x48d154d1, 0x5d26359f, 0x5da07964, 0x5cace092, + 0x5c2aac69, 0x5eb5d37e, 0x5e339f85, 0x5f3f0673, 0x5fb94a88, 0x5a87b4a6, 0x5a01f85d, 0x5b0d61ab, 0x5b8b2d50, + 0x59145247, 0x59921ebc, 0x589e874a, 0x5818cbb1, 0x52e37b16, 0x526537ed, 0x5369ae1b, 0x53efe2e0, 0x51709df7, + 0x51f6d10c, + 0x50fa48fa, 0x507c0401, 0x5542fa2f, 0x55c4b6d4, 0x54c82f22, 0x544e63d9, 0x56d11cce, 0x56575035, 0x575bc9c3, + 0x57dd8538 +]; + +function createcrc24(input) { + var crc = 0xB704CE; + var index = 0; + + while ((input.length - index) > 16) { + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 1)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 2)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 3)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 4)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 5)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 6)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 7)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 8)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 9)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 10)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 11)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 12)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 13)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 14)) & 0xff]; + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index + 15)) & 0xff]; + index += 16; + } + + for (var j = index; j < input.length; j++) { + crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index++)) & 0xff] + } + return crc & 0xffffff; +} + +/** + * DeArmor an OpenPGP armored message; verify the checksum and return + * the encoded bytes + * @param {String} text OpenPGP armored message + * @returns {(Boolean|Object)} Either false in case of an error + * or an object with attribute "text" containing the message text + * and an attribute "openpgp" containing the bytes. + */ +function dearmor(text) { + text = text.replace(/\r/g, '') + + var type = get_type(text); + + if (type != 2) { + var splittedtext = text.split('-----'); + + var data = { + openpgp: base64.decode( + splittedtext[2] + .split('\n\n')[1] + .split("\n=")[0] + .replace(/\n- /g, "\n")), + type: type + }; + + if (verifyCheckSum(data.openpgp, + splittedtext[2] + .split('\n\n')[1] + .split("\n=")[1] + .split('\n')[0])) + + return data; + else { + util.print_error("Ascii armor integrity check on message failed: '" + splittedtext[2] + .split('\n\n')[1] + .split("\n=")[1] + .split('\n')[0] + "' should be '" + getCheckSum(data)) + "'"; + return false; + } + } else { + var splittedtext = text.split('-----'); + + var result = { + text: splittedtext[2] + .replace(/\n- /g, "\n") + .split("\n\n")[1], + openpgp: base64_decode(splittedtext[4] + .split("\n\n")[1] + .split("\n=")[0]), + type: type + }; + + if (verifyCheckSum(result.openpgp, splittedtext[4] + .split("\n\n")[1] + .split("\n=")[1])) + + return result; + else { + util.print_error("Ascii armor integrity check on message failed"); + return false; + } + } +} + + +/** + * Armor an OpenPGP binary packet block + * @param {Integer} messagetype type of the message + * @param data + * @param {Integer} partindex + * @param {Integer} parttotal + * @returns {String} Armored text + */ +function armor(messagetype, data, partindex, parttotal) { + var result = ""; + switch (messagetype) { + case 0: + result += "-----BEGIN PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n"; + result += armor_addheader(); + result += base64.encode(data); + result += "\r\n=" + getCheckSum(data) + "\r\n"; + result += "-----END PGP MESSAGE, PART " + partindex + "/" + parttotal + "-----\r\n"; + break; + case 1: + result += "-----BEGIN PGP MESSAGE, PART " + partindex + "-----\r\n"; + result += armor_addheader(); + result += base64.encode(data); + result += "\r\n=" + getCheckSum(data) + "\r\n"; + result += "-----END PGP MESSAGE, PART " + partindex + "-----\r\n"; + break; + case 2: + result += "\r\n-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: " + data.hash + "\r\n\r\n"; + result += data.text.replace(/\n-/g, "\n- -"); + result += "\r\n-----BEGIN PGP SIGNATURE-----\r\n"; + result += armor_addheader(); + result += base64.encode(data.openpgp); + result += "\r\n=" + getCheckSum(data.openpgp) + "\r\n"; + result += "-----END PGP SIGNATURE-----\r\n"; + break; + case 3: + result += "-----BEGIN PGP MESSAGE-----\r\n"; + result += armor_addheader(); + result += base64.encode(data); + result += "\r\n=" + getCheckSum(data) + "\r\n"; + result += "-----END PGP MESSAGE-----\r\n"; + break; + case 4: + result += "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n"; + result += armor_addheader(); + result += base64.encode(data); + result += "\r\n=" + getCheckSum(data) + "\r\n"; + result += "-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n"; + break; + case 5: + result += "-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n"; + result += armor_addheader(); + result += base64.encode(data); + result += "\r\n=" + getCheckSum(data) + "\r\n"; + result += "-----END PGP PRIVATE KEY BLOCK-----\r\n"; + break; + } + + return result; +} + +module.exports = { + encode: armor, + decode: dearmor +} + +},{"./base64.js":24}],24:[function(require,module,exports){ +/* OpenPGP radix-64/base64 string encoding/decoding + * Copyright 2005 Herbert Hanewinkel, www.haneWIN.de + * version 1.0, check www.haneWIN.de for the latest version + * + * This software is provided as-is, without express or implied warranty. + * Permission to use, copy, modify, distribute or sell this software, with or + * without fee, for any purpose and by any individual or organization, is hereby + * granted, provided that the above copyright notice and this paragraph appear + * in all copies. Distribution as a part of an application or binary must + * include the above copyright notice in the documentation and/or other materials + * provided with the application or distribution. + */ + +var b64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +function s2r(t) { + var a, c, n; + var r = '', + l = 0, + s = 0; + var tl = t.length; + + for (n = 0; n < tl; n++) { + c = t.charCodeAt(n); + if (s == 0) { + r += b64s.charAt((c >> 2) & 63); + a = (c & 3) << 4; + } else if (s == 1) { + r += b64s.charAt((a | (c >> 4) & 15)); + a = (c & 15) << 2; + } else if (s == 2) { + r += b64s.charAt(a | ((c >> 6) & 3)); + l += 1; + if ((l % 60) == 0) + r += "\n"; + r += b64s.charAt(c & 63); + } + l += 1; + if ((l % 60) == 0) + r += "\n"; + + s += 1; + if (s == 3) + s = 0; + } + if (s > 0) { + r += b64s.charAt(a); + l += 1; + if ((l % 60) == 0) + r += "\n"; + r += '='; + l += 1; + } + if (s == 1) { + if ((l % 60) == 0) + r += "\n"; + r += '='; + } + + return r; +} + +function r2s(t) { + var c, n; + var r = '', + s = 0, + a = 0; + var tl = t.length; + + for (n = 0; n < tl; n++) { + c = b64s.indexOf(t.charAt(n)); + if (c >= 0) { + if (s) + r += String.fromCharCode(a | (c >> (6 - s)) & 255); + s = (s + 2) & 7; + a = (c << s) & 255; + } + } + return r; +} + +module.exports = { + encode: s2r, + decode: r2s +} + +},{}],25:[function(require,module,exports){ +var enums = { + + /** A string to key specifier type + * @enum {Integer} + */ + s2k: { + simple: 0, + salted: 1, + iterated: 3, + gnu: 101 + }, + + /** RFC4880, section 9.1 + * @enum {String} + */ + publicKey: { + rsa_encrypt_sign: 1, + rsa_encrypt: 2, + rsa_sign: 3, + elgamal: 16, + dsa: 17 + }, + + /** RFC4880, section 9.2 + * @enum {String} + */ + symmetric: { + plaintext: 0, + /** Not implemented! */ + idea: 1, + tripledes: 2, + cast5: 3, + blowfish: 4, + aes128: 7, + aes192: 8, + aes256: 9, + twofish: 10 + }, + + /** RFC4880, section 9.3 + * @enum {String} + */ + compression: { + uncompressed: 0, + /** RFC1951 */ + zip: 1, + /** RFC1950 */ + zlib: 2, + bzip2: 3 + }, + + /** RFC4880, section 9.4 + * @enum {String} + */ + hash: { + md5: 1, + sha1: 2, + ripemd: 3, + sha256: 8, + sha384: 9, + sha512: 10, + sha224: 11 + }, + + + /** + * @enum {String} + * A list of packet types and numeric tags associated with them. + */ + packet: { + public_key_encrypted_session_key: 1, + signature: 2, + sym_encrypted_session_key: 3, + one_pass_signature: 4, + secret_key: 5, + public_key: 6, + secret_subkey: 7, + compressed: 8, + symmetrically_encrypted: 9, + marker: 10, + literal: 11, + trust: 12, + userid: 13, + public_subkey: 14, + user_attribute: 17, + sym_encrypted_integrity_protected: 18, + modification_detection_code: 19 + }, + + + /** + * Data types in the literal packet + * @readonly + * @enum {String} + */ + literal: { + /** Binary data */ + binary: 'b'.charCodeAt(), + /** Text data */ + text: 't'.charCodeAt(), + /** Utf8 data */ + utf8: 'u'.charCodeAt() + }, + + + /** One pass signature packet type + * @enum {String} */ + signature: { + /** 0x00: Signature of a binary document. */ + binary: 0, + /** 0x01: Signature of a canonical text document. + * Canonicalyzing the document by converting line endings. */ + text: 1, + /** 0x02: Standalone signature. + * This signature is a signature of only its own subpacket contents. + * It is calculated identically to a signature over a zero-lengh + * binary document. Note that it doesn't make sense to have a V3 + * standalone signature. */ + standalone: 2, + /** 0x10: Generic certification of a User ID and Public-Key packet. + * The issuer of this certification does not make any particular + * assertion as to how well the certifier has checked that the owner + * of the key is in fact the person described by the User ID. */ + cert_generic: 16, + /** 0x11: Persona certification of a User ID and Public-Key packet. + * The issuer of this certification has not done any verification of + * the claim that the owner of this key is the User ID specified. */ + cert_persona: 17, + /** 0x12: Casual certification of a User ID and Public-Key packet. + * The issuer of this certification has done some casual + * verification of the claim of identity. */ + cert_casual: 18, + /** 0x13: Positive certification of a User ID and Public-Key packet. + * The issuer of this certification has done substantial + * verification of the claim of identity. + * + * Most OpenPGP implementations make their "key signatures" as 0x10 + * certifications. Some implementations can issue 0x11-0x13 + * certifications, but few differentiate between the types. */ + cert_positive: 19, + /** 0x30: Certification revocation signature + * This signature revokes an earlier User ID certification signature + * (signature class 0x10 through 0x13) or direct-key signature + * (0x1F). It should be issued by the same key that issued the + * revoked signature or an authorized revocation key. The signature + * is computed over the same data as the certificate that it + * revokes, and should have a later creation date than that + * certificate. */ + cert_revocation: 48, + /** 0x18: Subkey Binding Signature + * This signature is a statement by the top-level signing key that + * indicates that it owns the subkey. This signature is calculated + * directly on the primary key and subkey, and not on any User ID or + * other packets. A signature that binds a signing subkey MUST have + * an Embedded Signature subpacket in this binding signature that + * contains a 0x19 signature made by the signing subkey on the + * primary key and subkey. */ + subkey_binding: 24, + /** 0x19: Primary Key Binding Signature + * This signature is a statement by a signing subkey, indicating + * that it is owned by the primary key and subkey. This signature + * is calculated the same way as a 0x18 signature: directly on the + * primary key and subkey, and not on any User ID or other packets. + + * When a signature is made over a key, the hash data starts with the + * octet 0x99, followed by a two-octet length of the key, and then body + * of the key packet. (Note that this is an old-style packet header for + * a key packet with two-octet length.) A subkey binding signature + * (type 0x18) or primary key binding signature (type 0x19) then hashes + * the subkey using the same format as the main key (also using 0x99 as + * the first octet). */ + key_binding: 25, + /** 0x1F: Signature directly on a key + * This signature is calculated directly on a key. It binds the + * information in the Signature subpackets to the key, and is + * appropriate to be used for subpackets that provide information + * about the key, such as the Revocation Key subpacket. It is also + * appropriate for statements that non-self certifiers want to make + * about the key itself, rather than the binding between a key and a + * name. */ + key: 31, + /** 0x20: Key revocation signature + * The signature is calculated directly on the key being revoked. A + * revoked key is not to be used. Only revocation signatures by the + * key being revoked, or by an authorized revocation key, should be + * considered valid revocation signatures.a */ + key_revocation: 32, + /** 0x28: Subkey revocation signature + * The signature is calculated directly on the subkey being revoked. + * A revoked subkey is not to be used. Only revocation signatures + * by the top-level signature key that is bound to this subkey, or + * by an authorized revocation key, should be considered valid + * revocation signatures. + * Key revocation signatures (types 0x20 and 0x28) + * hash only the key being revoked. */ + subkey_revocation: 40, + /** 0x40: Timestamp signature. + * This signature is only meaningful for the timestamp contained in + * it. */ + timestamp: 64, + /** 0x50: Third-Party Confirmation signature. + * This signature is a signature over some other OpenPGP Signature + * packet(s). It is analogous to a notary seal on the signed data. + * A third-party signature SHOULD include Signature Target + * subpacket(s) to give easy identification. Note that we really do + * mean SHOULD. There are plausible uses for this (such as a blind + * party that only sees the signature, not the key or source + * document) that cannot include a target subpacket. */ + third_party: 80 + }, + + // Asserts validity and converts from string/integer to integer. + write: function(type, e) { + if (typeof e == 'number') { + e = this.read(type, e); + } + + if (type[e] != undefined) { + return type[e]; + } else throw new Error('Invalid enum value.'); + }, + // Converts from an integer to string. + read: function(type, e) { + for (var i in type) + if (type[i] == e) return i; + + throw new Error('Invalid enum value.'); + } +} + +module.exports = enums; + +},{}],26:[function(require,module,exports){ +var crypto = require('./crypto'); + +module.exports = require('./openpgp.js'); +module.exports.util = require('./util'); +module.exports.packet = require('./packet'); +module.exports.mpi = require('./type/mpi.js'); +module.exports.s2k = require('./type/s2k.js'); +module.exports.keyid = require('./type/keyid.js'); +module.exports.armor = require('./encoding/armor.js'); +module.exports.enums = require('./enums.js'); + +for (var i in crypto) + module.exports[i] = crypto[i]; + +},{"./crypto":14,"./encoding/armor.js":23,"./enums.js":25,"./openpgp.js":27,"./packet":31,"./type/keyid.js":49,"./type/mpi.js":50,"./type/s2k.js":51,"./util":52}],27:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * @fileoverview The openpgp base class should provide all of the functionality + * to consume the openpgp.js library. All additional classes are documented + * for extending and developing on top of the base library. + */ + +var armor = require('./encoding/armor.js'); +var packet = require('./packet'); +var util = require('./util'); +var enums = require('./enums.js'); + +/** + * GPG4Browsers Core interface. A single instance is hold + * from the beginning. To use this library call "openpgp.init()" + * @alias openpgp + * @class + * @classdesc Main Openpgp.js class. Use this to initiate and make all calls to this library. + */ +function _openpgp() { + this.tostring = ""; + + /** + * initializes the library: + * - reading the keyring from local storage + * - reading the config from local storage + */ + function init() { + this.config = new openpgp_config(); + this.config.read(); + this.keyring = new openpgp_keyring(); + this.keyring.init(); + } + + /** + * reads message packets out of an OpenPGP armored text and + * returns an array of message objects + * @param {String} armoredText text to be parsed + * @return {openpgp_msg_message[]} on error the function + * returns null + */ + function readArmoredPackets(armoredText) { + //TODO how do we want to handle bad text? Exception throwing + var input = armor.decode(armoredText.replace(/\r/g, '')).openpgp; + return readDearmoredPackets(input); + } + + /** + * reads message packets out of an OpenPGP armored text and + * returns an array of message objects. Can be called externally or internally. + * External call will parse a de-armored messaged and return messages found. + * Internal will be called to read packets wrapped in other packets (i.e. compressed) + * @param {String} input dearmored text of OpenPGP packets, to be parsed + * @return {openpgp_msg_message[]} on error the function + * returns null + */ + function readDearmoredPackets(input) { + var packetList = new packet.list(); + packetList.read(input); + return packetList; + } + + function encryptMessage(publicKeyPacketlist, message) { + + } + + function encryptAndSignMessage(publicKeyPacketlist, privateKeyPacketlist, message) { + + } + + function decryptMessage(privateKeyPacketlist, messagePacketlist) { + + } + + function decryptAndVerifyMessage(privateKeyPacketlist, publicKeyPacketlist, messagePacketlist) { + + } + + function verifyMessage(publicKeyPacketlist, messagePacketlist) { + + } + + function signMessage(privateKeyPacketlist, messagePacketlist) { + + } + + function generateKeyPair(keyType, numBits, userId, passphrase) { + debugger; + var packetlist = new packet.list(); + + var secretKeyPacket = new packet.secret_key(); + secretKeyPacket.algorithm = enums.read(enums.publicKey, keyType); + secretKeyPacket.generate(numBits); + secretKeyPacket.encrypt(passphrase); + + var userIdPacket = new packet.userid(); + userIdPacket.read(userId); + + var signaturePacket = new packet.signature(); + var secretSubkeyPacket = new packet.secret_subkey(); + var overallSignaturePacket = new packet.signature(); + + packetlist.push(secretKeyPacket); + packetlist.push(userIdPacket); + packetlist.push(signaturePacket); + packetlist.push(secretSubkeyPacket); + packetlist.push(overallSignaturePacket); + } + + /** + * creates a binary string representation of an encrypted and signed message. + * The message will be encrypted with the public keys specified and signed + * with the specified private key. + * @param {Object} privatekey {obj: [openpgp_msg_privatekey]} Private key + * to be used to sign the message + * @param {Object[]} publickeys An arraf of {obj: [openpgp_msg_publickey]} + * - public keys to be used to encrypt the message + * @param {String} messagetext message text to encrypt and sign + * @return {String} a binary string representation of the message which + * can be OpenPGP armored + */ + function write_signed_and_encrypted_message(privatekey, publickeys, messagetext) { + var result = ""; + var i; + var literal = new openpgp_packet_literaldata().write_packet(messagetext.replace(/\r\n/g, "\n").replace(/\n/g, + "\r\n")); + util.print_debug_hexstr_dump("literal_packet: |" + literal + "|\n", literal); + for (i = 0; i < publickeys.length; i++) { + var onepasssignature = new openpgp_packet_onepasssignature(); + var onepasssigstr = ""; + if (i === 0) + onepasssigstr = onepasssignature.write_packet(1, openpgp.config.config.prefer_hash_algorithm, privatekey, false); + else + onepasssigstr = onepasssignature.write_packet(1, openpgp.config.config.prefer_hash_algorithm, privatekey, false); + util.print_debug_hexstr_dump("onepasssigstr: |" + onepasssigstr + "|\n", onepasssigstr); + var datasignature = new openpgp_packet_signature().write_message_signature(1, messagetext.replace(/\r\n/g, "\n").replace( + /\n/g, "\r\n"), privatekey); + util.print_debug_hexstr_dump("datasignature: |" + datasignature.openpgp + "|\n", datasignature.openpgp); + if (i === 0) { + result = onepasssigstr + literal + datasignature.openpgp; + } else { + result = onepasssigstr + result + datasignature.openpgp; + } + } + + util.print_debug_hexstr_dump("signed packet: |" + result + "|\n", result); + // signatures done.. now encryption + var sessionkey = openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher); + var result2 = ""; + + // creating session keys for each recipient + for (i = 0; i < publickeys.length; i++) { + var pkey = publickeys[i].getEncryptionKey(); + if (pkey === null) { + util.print_error("no encryption key found! Key is for signing only."); + return null; + } + result2 += new openpgp_packet_encryptedsessionkey(). + write_pub_key_packet( + pkey.getKeyId(), + pkey.MPIs, + pkey.publicKeyAlgorithm, + openpgp.config.config.encryption_cipher, + sessionkey); + } + if (openpgp.config.config.integrity_protect) { + result2 += new openpgp_packet_encryptedintegrityprotecteddata().write_packet(openpgp.config.config.encryption_cipher, + sessionkey, result); + } else { + result2 += new openpgp_packet_encrypteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, + result); + } + return armor.encode(3, result2, null, null); + } + /** + * creates a binary string representation of an encrypted message. + * The message will be encrypted with the public keys specified + * @param {Object[]} publickeys An array of {obj: [openpgp_msg_publickey]} + * -public keys to be used to encrypt the message + * @param {String} messagetext message text to encrypt + * @return {String} a binary string representation of the message + * which can be OpenPGP armored + */ + function write_encrypted_message(publickeys, messagetext) { + var result = ""; + var literal = new openpgp_packet_literaldata().write_packet(messagetext.replace(/\r\n/g, "\n").replace(/\n/g, + "\r\n")); + util.print_debug_hexstr_dump("literal_packet: |" + literal + "|\n", literal); + result = literal; + + // signatures done.. now encryption + var sessionkey = openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher); + var result2 = ""; + + // creating session keys for each recipient + for (var i = 0; i < publickeys.length; i++) { + var pkey = publickeys[i].getEncryptionKey(); + if (pkey === null) { + util.print_error("no encryption key found! Key is for signing only."); + return null; + } + result2 += new openpgp_packet_encryptedsessionkey(). + write_pub_key_packet( + pkey.getKeyId(), + pkey.MPIs, + pkey.publicKeyAlgorithm, + openpgp.config.config.encryption_cipher, + sessionkey); + } + if (openpgp.config.config.integrity_protect) { + result2 += new openpgp_packet_encryptedintegrityprotecteddata().write_packet(openpgp.config.config.encryption_cipher, + sessionkey, result); + } else { + result2 += new openpgp_packet_encrypteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, + result); + } + return armor.encode(3, result2, null, null); + } + + /** + * creates a binary string representation a signed message. + * The message will be signed with the specified private key. + * @param {Object} privatekey {obj: [openpgp_msg_privatekey]} + * - the private key to be used to sign the message + * @param {String} messagetext message text to sign + * @return {Object} {Object: text [String]}, openpgp: {String} a binary + * string representation of the message which can be OpenPGP + * armored(openpgp) and a text representation of the message (text). + * This can be directly used to OpenPGP armor the message + */ + function write_signed_message(privatekey, messagetext) { + var sig = new openpgp_packet_signature().write_message_signature(1, messagetext.replace(/\r\n/g, "\n").replace(/\n/, + "\r\n"), privatekey); + var result = { + text: messagetext.replace(/\r\n/g, "\n").replace(/\n/, "\r\n"), + openpgp: sig.openpgp, + hash: sig.hash + }; + return armor.encode(2, result, null, null); + } + + /** + * generates a new key pair for openpgp. Beta stage. Currently only + * supports RSA keys, and no subkeys. + * @param {Integer} keyType to indicate what type of key to make. + * RSA is 1. Follows algorithms outlined in OpenPGP. + * @param {Integer} numBits number of bits for the key creation. (should + * be 1024+, generally) + * @param {String} userId assumes already in form of "User Name + * " + * @param {String} passphrase The passphrase used to encrypt the resulting private key + * @return {Object} {privateKey: [openpgp_msg_privatekey], + * privateKeyArmored: [string], publicKeyArmored: [string]} + */ + function generate_key_pair(keyType, numBits, userId, passphrase) { + var userIdPacket = new openpgp_packet_userid(); + var userIdString = userIdPacket.write_packet(userId); + + var keyPair = openpgp_crypto_generateKeyPair(keyType, numBits, passphrase, openpgp.config.config.prefer_hash_algorithm, + 3); + var privKeyString = keyPair.privateKey; + var privKeyPacket = new openpgp_packet_keymaterial().read_priv_key(privKeyString.string, 3, privKeyString.string.length); + if (!privKeyPacket.decryptSecretMPIs(passphrase)) + util.print_error('Issue creating key. Unable to read resulting private key'); + var privKey = new openpgp_msg_privatekey(); + privKey.privateKeyPacket = privKeyPacket; + privKey.getPreferredSignatureHashAlgorithm = function() { + return openpgp.config.config.prefer_hash_algorithm + }; //need to override this to solve catch 22 to generate signature. 8 is value for SHA256 + + var publicKeyString = privKey.privateKeyPacket.publicKey.data; + var hashData = String.fromCharCode(0x99) + String.fromCharCode(((publicKeyString.length) >> 8) & 0xFF) + String.fromCharCode(( + publicKeyString.length) & 0xFF) + publicKeyString + String.fromCharCode(0xB4) + + String.fromCharCode((userId.length) >> 24) + String.fromCharCode(((userId.length) >> 16) & 0xFF) + String.fromCharCode((( + userId.length) >> 8) & 0xFF) + String.fromCharCode((userId.length) & 0xFF) + userId; + var signature = new openpgp_packet_signature(); + signature = signature.write_message_signature(16, hashData, privKey); + var publicArmored = armor.encode(4, keyPair.publicKey.string + userIdString + signature.openpgp); + + var privArmored = armor.encode(5, privKeyString.string + userIdString + signature.openpgp); + + return { + privateKey: privKey, + privateKeyArmored: privArmored, + publicKeyArmored: publicArmored + }; + } + + this.generateKeyPair = generateKeyPair; + this.write_signed_message = write_signed_message; + this.write_signed_and_encrypted_message = write_signed_and_encrypted_message; + this.write_encrypted_message = write_encrypted_message; + this.readArmoredPackets = readArmoredPackets; + this.readDearmoredPackets = readDearmoredPackets; + this.init = init; +} + +module.exports = new _openpgp(); + +},{"./encoding/armor.js":23,"./enums.js":25,"./packet":31,"./util":52}],28:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var packet = require('./packet'); +var enums = require('./enums.js'); +var armor = require('./encoding/armor.js'); + +/** + * @class + * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. + */ +var keyring = function() { + this.armoredPacketlists = []; + this.parsedPacketlists = []; + + /** + * Initialization routine for the keyring. This method reads the + * keyring from HTML5 local storage and initializes this instance. + * This method is called by openpgp.init(). + */ + function init() { + var armoredPacketlists = JSON.parse(window.localStorage.getItem("armoredPacketlists")); + if (armoredPacketlists === null || armoredPacketlists.length === 0) { + armoredPacketlists = []; + } + this.armoredPacketlists = armoredPacketlists; + + var packetlist; + for (var i = 0; i < armoredPacketlists.length; i++) { + packetlist = new packet.list(); + packetlist.read(armoredPacketlists[i]); + this.parsedPacketlists.push(packetlist); + } + } + this.init = init; + + /** + * Saves the current state of the keyring to HTML5 local storage. + * The privateKeys array and publicKeys array gets Stringified using JSON + */ + function store() { + window.localStorage.setItem("armoredPacketlists", JSON.stringify(this.armoredPacketlists)); + } + this.store = store; + + function emailPacketCheck(packet, email) { + var emailMatch = false; + var packetEmail; + email = email.toLowerCase(); + if (packet.tag == enums.packet.userid) { + packetEmail = packet.userid; + //we need to get just the email from the userid packet + packetEmail = packetEmail.split('<')[1].split('<')[0].trim.toLowerCase(); + if (packetEmail == email) { + emailMatch = true; + } + } + return emailMatch; + } + + function idPacketCheck(packet, id) { + if (packet.getKeyId && packet.getKeyId() == id) { + return true; + } + return false; + } + + function helperCheckIdentityAndPacketMatch(identityFunction, identityInput, packetType, packetlist) { + var packet; + for (var l = 0; l < packetlist.length; l++) { + packet = packetlist[l]; + identityMatch = identityFunction(packet, identityInput); + if (!packetType) { + packetMatch = true; + } else if (packet.tag == packetType) { + packetMatch = true; + } + if (packetMatch && identityMatch) { + return true; + } + } + return false; + } + + function checkForIdentityAndPacketMatch(identityFunction, identityInput, packetType) { + var results = []; + var packetlist; + var identityMatch; + var packetMatch; + for (var p = 0; p < this.parsedPacketlists.length; p++) { + identityMatch = false; + packetMatch = false; + packetlist = this.parsedPacketlists[p]; + if (helperCheckIdentityAndPacketMatch(identityFunction, identityInput, packetType, packetlist)) { + results.push(packetlist); + } + } + return results; + } + this.checkForIdentityAndPacketMatch = checkForIdentityAndPacketMatch; + + /** + * searches all public keys in the keyring matching the address or address part of the user ids + * @param {String} email_address + * @return {openpgp_msg_publickey[]} The public keys associated with provided email address. + */ + function getPublicKeyForAddress(email) { + return checkForIdentityAndPacketMatch(emailPacketCheck, email, enums.packet.public_key); + } + this.getPublicKeyForAddress = getPublicKeyForAddress; + + /** + * Searches the keyring for a private key containing the specified email address + * @param {String} email_address email address to search for + * @return {openpgp_msg_privatekey[]} private keys found + */ + function getPrivateKeyForAddress(email_address) { + return checkForIdentityAndPacketMatch(emailPacketCheck, email, enums.packet.secret_key); + } + this.getPrivateKeyForAddress = getPrivateKeyForAddress; + + /** + * Searches the keyring for public keys having the specified key id + * @param {String} keyId provided as string of hex number (lowercase) + * @return {openpgp_msg_privatekey[]} public keys found + */ + function getPacketlistsForKeyId(keyId) { + return this.checkForIdentityAndPacketMatch(idPacketCheck, keyId); + } + this.getPacketlistsForKeyId = getPacketlistsForKeyId; + + /** + * Imports a packet list (public or private key block) from an ascii armored message + * @param {String} armored message to read the packets/key from + */ + function importPacketlist(armored) { + this.armoredPacketlists.push(armored); + + var dearmored = armor.decode(armored.replace(/\r/g, '')).openpgp; + + packetlist = new packet.list(); + packetlist.read(dearmored); + this.parsedPacketlists.push(packetlist); + + return true; + } + this.importPacketlist = importPacketlist; + + /** + * TODO + * returns the openpgp_msg_privatekey representation of the public key at public key ring index + * @param {Integer} index the index of the public key within the publicKeys array + * @return {openpgp_msg_privatekey} the public key object + */ + function exportPublicKey(index) { + return this.publicKey[index]; + } + this.exportPublicKey = exportPublicKey; + + /** + * TODO + * Removes a public key from the public key keyring at the specified index + * @param {Integer} index the index of the public key within the publicKeys array + * @return {openpgp_msg_privatekey} The public key object which has been removed + */ + function removePublicKey(index) { + var removed = this.publicKeys.splice(index, 1); + this.store(); + return removed; + } + this.removePublicKey = removePublicKey; + +}; + +module.exports = new keyring(); + +},{"./encoding/armor.js":23,"./enums.js":25,"./packet":31}],29:[function(require,module,exports){ +var enums = require('../enums.js'); + +// This is pretty ugly, but browserify needs to have the requires explicitly written. +module.exports = { + compressed: require('./compressed.js'), + sym_encrypted_integrity_protected: require('./sym_encrypted_integrity_protected.js'), + public_key_encrypted_session_key: require('./public_key_encrypted_session_key.js'), + sym_encrypted_session_key: require('./sym_encrypted_session_key.js'), + literal: require('./literal.js'), + public_key: require('./public_key.js'), + symmetrically_encrypted: require('./symmetrically_encrypted.js'), + marker: require('./marker.js'), + public_subkey: require('./public_subkey.js'), + user_attribute: require('./user_attribute.js'), + one_pass_signature: require('./one_pass_signature.js'), + secret_key: require('./secret_key.js'), + userid: require('./userid.js'), + secret_subkey: require('./secret_subkey.js'), + signature: require('./signature.js'), + trust: require('./trust.js') +} + +for (var i in enums.packet) { + var packetClass = module.exports[i]; + + if (packetClass != undefined) + packetClass.prototype.tag = enums.packet[i]; +} + +},{"../enums.js":25,"./compressed.js":30,"./literal.js":32,"./marker.js":33,"./one_pass_signature.js":34,"./public_key.js":37,"./public_key_encrypted_session_key.js":38,"./public_subkey.js":39,"./secret_key.js":40,"./secret_subkey.js":41,"./signature.js":42,"./sym_encrypted_integrity_protected.js":43,"./sym_encrypted_session_key.js":44,"./symmetrically_encrypted.js":45,"./trust.js":46,"./user_attribute.js":47,"./userid.js":48}],30:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var enums = require('../enums.js'), + JXG = require('../compression/jxg.js'), + base64 = require('../encoding/base64.js'); + +/** + * @class + * @classdesc Implementation of the Compressed Data Packet (Tag 8) + * + * RFC4880 5.6: + * The Compressed Data packet contains compressed data. Typically, this + * packet is found as the contents of an encrypted packet, or following + * a Signature or One-Pass Signature packet, and contains a literal data + * packet. + */ +module.exports = function packet_compressed() { + /** @type {packetlist} */ + this.packets; + /** @type {compression} */ + this.algorithm = 'uncompressed'; + + this.compressed = null; + + + /** + * Parsing function for the packet. + * @param {String} input Payload of a tag 8 packet + * @param {Integer} position Position to start reading from the input string + * @parAM {iNTEGER} LEN lENGTH OF the packet or the remaining length of + * input at position + * @return {openpgp_packet_compressed} Object representation + */ + this.read = function(bytes) { + // One octet that gives the algorithm used to compress the packet. + this.algorithm = enums.read(enums.compression, bytes.charCodeAt(0)); + + // Compressed data, which makes up the remainder of the packet. + this.compressed = bytes.substr(1); + + this.decompress(); + } + + + + this.write = function() { + if (this.compressed == null) + this.compress(); + + return String.fromCharCode(enums.write(enums.compression, this.algorithm)) + this.compressed; + } + + + /** + * Decompression method for decompressing the compressed data + * read by read_packet + * @return {String} The decompressed data + */ + this.decompress = function() { + var decompressed; + + switch (this.algorithm) { + case 'uncompressed': + decompressed = this.compressed; + break; + + case 'zip': + var compData = this.compressed; + + var radix = base64.encode(compData).replace(/\n/g, ""); + // no header in this case, directly call deflate + var jxg_obj = new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(radix)); + + decompressed = unescape(jxg_obj.deflate()[0][0]); + break; + + case 'zlib': + //RFC 1950. Bits 0-3 Compression Method + var compressionMethod = this.compressed.charCodeAt(0) % 0x10; + + //Bits 4-7 RFC 1950 are LZ77 Window. Generally this value is 7 == 32k window size. + // 2nd Byte in RFC 1950 is for "FLAGs" Allows for a Dictionary + // (how is this defined). Basic checksum, and compression level. + + if (compressionMethod == 8) { //CM 8 is for DEFLATE, RFC 1951 + // remove 4 bytes ADLER32 checksum from the end + var compData = this.compressed.substring(0, this.compressed.length - 4); + var radix = base64.encode(compData).replace(/\n/g, ""); + //TODO check ADLER32 checksum + decompressed = JXG.decompress(radix); + break; + + } else { + util.print_error("Compression algorithm ZLIB only supports " + + "DEFLATE compression method."); + } + break; + + case 'bzip2': + // TODO: need to implement this + throw new Error('Compression algorithm BZip2 [BZ2] is not implemented.'); + break; + + default: + throw new Error("Compression algorithm unknown :" + this.alogrithm); + break; + } + + this.packets.read(decompressed); + } + + /** + * Compress the packet data (member decompressedData) + * @param {Integer} type Algorithm to be used // See RFC 4880 9.3 + * @param {String} data Data to be compressed + * @return {String} The compressed data stored in attribute compressedData + */ + this.compress = function() { + switch (this.algorithm) { + + case 'uncompressed': + // - Uncompressed + this.compressed = this.packets.write(); + break; + + case 'zip': + // - ZIP [RFC1951] + util.print_error("Compression algorithm ZIP [RFC1951] is not implemented."); + break; + + case 'zlib': + // - ZLIB [RFC1950] + // TODO: need to implement this + util.print_error("Compression algorithm ZLIB [RFC1950] is not implemented."); + break; + + case 'bzip2': + // - BZip2 [BZ2] + // TODO: need to implement this + util.print_error("Compression algorithm BZip2 [BZ2] is not implemented."); + break; + + default: + util.print_error("Compression algorithm unknown :" + this.type); + break; + } + } +}; + +},{"../compression/jxg.js":1,"../encoding/base64.js":24,"../enums.js":25}],31:[function(require,module,exports){ +var enums = require('../enums.js'); + +module.exports = { + list: require('./packetlist.js'), +}; + +var packets = require('./all_packets.js'); + +for (var i in packets) + module.exports[i] = packets[i]; + +},{"../enums.js":25,"./all_packets.js":29,"./packetlist.js":36}],32:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var util = require('../util'), + enums = require('../enums.js'); + +/** + * @class + * @classdesc Implementation of the Literal Data Packet (Tag 11) + * + * RFC4880 5.9: A Literal Data packet contains the body of a message; data that + * is not to be further interpreted. + */ +module.exports = function packet_literal() { + this.format = 'utf8'; + this.data = ''; + this.date = new Date(); + + + /** + * Set the packet data to a javascript native string or a squence of + * bytes. Conversion to a proper utf8 encoding takes place when the + * packet is written. + * @param {String} str Any native javascript string + * @param {openpgp_packet_literaldata.format} format + */ + this.set = function(str, format) { + this.format = format; + this.data = str; + } + + /** + * Set the packet data to value represented by the provided string + * of bytes together with the appropriate conversion format. + * @param {String} bytes The string of bytes + * @param {openpgp_packet_literaldata.format} format + */ + this.setBytes = function(bytes, format) { + this.format = format; + + if (format == 'utf8') + bytes = util.decode_utf8(bytes); + + this.data = bytes; + } + + /** + * Get the byte sequence representing the literal packet data + * @returns {String} A sequence of bytes + */ + this.getBytes = function() { + if (this.format == 'utf8') + return util.encode_utf8(this.data); + else + return this.data; + } + + + + /** + * Parsing function for a literal data packet (tag 11). + * + * @param {String} input Payload of a tag 11 packet + * @param {Integer} position + * Position to start reading from the input string + * @param {Integer} len + * Length of the packet or the remaining length of + * input at position + * @return {openpgp_packet_encrypteddata} object representation + */ + this.read = function(bytes) { + // - A one-octet field that describes how the data is formatted. + + var format = enums.read(enums.literal, bytes[0].charCodeAt()); + + var filename_len = bytes.charCodeAt(1); + this.filename = util.decode_utf8(bytes.substr(2, filename_len)); + + this.date = util.readDate(bytes.substr(2 + filename_len, 4)); + + var data = bytes.substring(6 + filename_len); + + this.setBytes(data, format); + } + + /** + * Creates a string representation of the packet + * + * @param {String} data The data to be inserted as body + * @return {String} string-representation of the packet + */ + this.write = function() { + var filename = util.encode_utf8("msg.txt"); + + var data = this.getBytes(); + + var result = ''; + result += String.fromCharCode(enums.write(enums.literal, this.format)); + result += String.fromCharCode(filename.length); + result += filename; + result += util.writeDate(this.date); + result += data; + return result; + } +} + +},{"../enums.js":25,"../util":52}],33:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * @class + * @classdesc Implementation of the strange "Marker packet" (Tag 10) + * + * RFC4880 5.8: An experimental version of PGP used this packet as the Literal + * packet, but no released version of PGP generated Literal packets with this + * tag. With PGP 5.x, this packet has been reassigned and is reserved for use as + * the Marker packet. + * + * Such a packet MUST be ignored when received. + */ +function packet_marker() { + /** + * Parsing function for a literal data packet (tag 10). + * + * @param {String} input Payload of a tag 10 packet + * @param {Integer} position + * Position to start reading from the input string + * @param {Integer} len + * Length of the packet or the remaining length of + * input at position + * @return {openpgp_packet_encrypteddata} Object representation + */ + this.read = function(bytes) { + if (bytes[0].charCodeAt() == 0x50 && // P + bytes[1].charCodeAt() == 0x47 && // G + bytes[2].charCodeAt() == 0x50) // P + return true; + // marker packet does not contain "PGP" + return false; + } +} + +module.exports = packet_marker; + +},{}],34:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * @class + * @classdesc Implementation of the One-Pass Signature Packets (Tag 4) + * + * RFC4880 5.4: + * The One-Pass Signature packet precedes the signed data and contains + * enough information to allow the receiver to begin calculating any + * hashes needed to verify the signature. It allows the Signature + * packet to be placed at the end of the message, so that the signer + * can compute the entire signed message in one pass. + */ + +var enums = require('../enums.js'), + type_keyid = require('../type/keyid.js'); + +module.exports = function packet_one_pass_signature() { + this.version = null; // A one-octet version number. The current version is 3. + this.type = null; // A one-octet signature type. Signature types are described in RFC4880 Section 5.2.1. + this.hashAlgorithm = null; // A one-octet number describing the hash algorithm used. (See RFC4880 9.4) + this.publicKeyAlgorithm = null; // A one-octet number describing the public-key algorithm used. (See RFC4880 9.1) + this.signingKeyId = null; // An eight-octet number holding the Key ID of the signing key. + this.flags = null; // A one-octet number holding a flag showing whether the signature is nested. A zero value indicates that the next packet is another One-Pass Signature packet that describes another signature to be applied to the same message data. + + /** + * parsing function for a one-pass signature packet (tag 4). + * @param {String} bytes payload of a tag 4 packet + * @param {Integer} position position to start reading from the bytes string + * @param {Integer} len length of the packet or the remaining length of bytes at position + * @return {openpgp_packet_encrypteddata} object representation + */ + this.read = function(bytes) { + var mypos = 0; + // A one-octet version number. The current version is 3. + this.version = bytes.charCodeAt(mypos++); + + // A one-octet signature type. Signature types are described in + // Section 5.2.1. + this.type = enums.read(enums.signature, bytes.charCodeAt(mypos++)); + + // A one-octet number describing the hash algorithm used. + this.hashAlgorithm = enums.read(enums.hash, bytes.charCodeAt(mypos++)); + + // A one-octet number describing the public-key algorithm used. + this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes.charCodeAt(mypos++)); + + // An eight-octet number holding the Key ID of the signing key. + this.signingKeyId = new type_keyid(); + this.signingKeyId.read(bytes.substr(mypos)); + mypos += 8; + + // A one-octet number holding a flag showing whether the signature + // is nested. A zero value indicates that the next packet is + // another One-Pass Signature packet that describes another + // signature to be applied to the same message data. + this.flags = bytes.charCodeAt(mypos++); + return this; + } + + /** + * creates a string representation of a one-pass signature packet + * @param {Integer} type Signature types as described in RFC4880 Section 5.2.1. + * @param {Integer} hashalgorithm the hash algorithm used within the signature + * @param {openpgp_msg_privatekey} privatekey the private key used to generate the signature + * @param {Integer} length length of data to be signed + * @param {boolean} nested boolean showing whether the signature is nested. + * "true" indicates that the next packet is another One-Pass Signature packet + * that describes another signature to be applied to the same message data. + * @return {String} a string representation of a one-pass signature packet + */ + this.write = function(type, hashalgorithm, privatekey, length, nested) { + var result = ""; + + result += String.fromCharCode(3); + result += String.fromCharCode(enums.write(enums.signature, type)); + result += String.fromCharCode(enums.write(enums.hash, this.hashAlgorithm)); + result += String.fromCharCode(enums.write(enums.publicKey, privatekey.algorithm)); + result += privatekey.getKeyId(); + if (nested) + result += String.fromCharCode(0); + else + result += String.fromCharCode(1); + + return result; + } +}; + +},{"../enums.js":25,"../type/keyid.js":49}],35:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var enums = require('../enums.js'), + util = require('../util'); + + +module.exports = { + readSimpleLength: function(bytes) { + var len = 0, + offset, + type = bytes[0].charCodeAt(); + + + if (type < 192) { + len = bytes[0].charCodeAt(); + offset = 1; + } else if (type < 255) { + len = ((bytes[0].charCodeAt() - 192) << 8) + (bytes[1].charCodeAt()) + 192; + offset = 2; + } else if (type == 255) { + len = util.readNumber(bytes.substr(1, 4)); + offset = 5; + } + + return { + len: len, + offset: offset + }; + }, + + /** + * Encodes a given integer of length to the openpgp length specifier to a + * string + * + * @param {Integer} length The length to encode + * @return {String} String with openpgp length representation + */ + writeSimpleLength: function(length) { + var result = ""; + if (length < 192) { + result += String.fromCharCode(length); + } else if (length > 191 && length < 8384) { + /* + * let a = (total data packet length) - 192 let bc = two octet + * representation of a let d = b + 192 + */ + result += String.fromCharCode(((length - 192) >> 8) + 192); + result += String.fromCharCode((length - 192) & 0xFF); + } else { + result += String.fromCharCode(255); + result += util.writeNumber(length, 4); + } + return result; + }, + + /** + * Writes a packet header version 4 with the given tag_type and length to a + * string + * + * @param {Integer} tag_type Tag type + * @param {Integer} length Length of the payload + * @return {String} String of the header + */ + writeHeader: function(tag_type, length) { + /* we're only generating v4 packet headers here */ + var result = ""; + result += String.fromCharCode(0xC0 | tag_type); + result += this.writeSimpleLength(length); + return result; + }, + + /** + * Writes a packet header Version 3 with the given tag_type and length to a + * string + * + * @param {Integer} tag_type Tag type + * @param {Integer} length Length of the payload + * @return {String} String of the header + */ + writeOldHeader: function(tag_type, length) { + var result = ""; + if (length < 256) { + result += String.fromCharCode(0x80 | (tag_type << 2)); + result += String.fromCharCode(length); + } else if (length < 65536) { + result += String.fromCharCode(0x80 | (tag_type << 2) | 1); + result += util.writeNumber(length, 2); + } else { + result += String.fromCharCode(0x80 | (tag_type << 2) | 2); + result += util.writeNumber(length, 4); + } + return result; + }, + + /** + * Generic static Packet Parser function + * + * @param {String} input Input stream as string + * @param {integer} position Position to start parsing + * @param {integer} len Length of the input from position on + * @return {Object} Returns a parsed openpgp_packet + */ + read: function(input, position, len) { + // some sanity checks + if (input == null || input.length <= position || input.substring(position).length < 2 || (input[position].charCodeAt() & + 0x80) == 0) { + util + .print_error("Error during parsing. This message / key is probably not containing a valid OpenPGP format."); + return null; + } + var mypos = position; + var tag = -1; + var format = -1; + var packet_length; + + format = 0; // 0 = old format; 1 = new format + if ((input[mypos].charCodeAt() & 0x40) != 0) { + format = 1; + } + + var packet_length_type; + if (format) { + // new format header + tag = input[mypos].charCodeAt() & 0x3F; // bit 5-0 + } else { + // old format header + tag = (input[mypos].charCodeAt() & 0x3F) >> 2; // bit 5-2 + packet_length_type = input[mypos].charCodeAt() & 0x03; // bit 1-0 + } + + // header octet parsing done + mypos++; + + // parsed length from length field + var bodydata = null; + + // used for partial body lengths + var real_packet_length = -1; + if (!format) { + // 4.2.1. Old Format Packet Lengths + switch (packet_length_type) { + case 0: + // The packet has a one-octet length. The header is 2 octets + // long. + packet_length = input[mypos++].charCodeAt(); + break; + case 1: + // The packet has a two-octet length. The header is 3 octets + // long. + packet_length = (input[mypos++].charCodeAt() << 8) | input[mypos++].charCodeAt(); + break; + case 2: + // The packet has a four-octet length. The header is 5 + // octets long. + packet_length = (input[mypos++].charCodeAt() << 24) | (input[mypos++].charCodeAt() << 16) | (input[mypos++].charCodeAt() << + 8) | input[mypos++].charCodeAt(); + break; + default: + // 3 - The packet is of indeterminate length. The header is 1 + // octet long, and the implementation must determine how long + // the packet is. If the packet is in a file, this means that + // the packet extends until the end of the file. In general, + // an implementation SHOULD NOT use indeterminate-length + // packets except where the end of the data will be clear + // from the context, and even then it is better to use a + // definite length, or a new format header. The new format + // headers described below have a mechanism for precisely + // encoding data of indeterminate length. + packet_length = len; + break; + } + + } else // 4.2.2. New Format Packet Lengths + { + + // 4.2.2.1. One-Octet Lengths + if (input[mypos].charCodeAt() < 192) { + packet_length = input[mypos++].charCodeAt(); + util.print_debug("1 byte length:" + packet_length); + // 4.2.2.2. Two-Octet Lengths + } else if (input[mypos].charCodeAt() >= 192 && input[mypos].charCodeAt() < 224) { + packet_length = ((input[mypos++].charCodeAt() - 192) << 8) + (input[mypos++].charCodeAt()) + 192; + util.print_debug("2 byte length:" + packet_length); + // 4.2.2.4. Partial Body Lengths + } else if (input[mypos].charCodeAt() > 223 && input[mypos].charCodeAt() < 255) { + packet_length = 1 << (input[mypos++].charCodeAt() & 0x1F); + util.print_debug("4 byte length:" + packet_length); + // EEEK, we're reading the full data here... + var mypos2 = mypos + packet_length; + bodydata = input.substring(mypos, mypos + packet_length); + while (true) { + if (input[mypos2].charCodeAt() < 192) { + var tmplen = input[mypos2++].charCodeAt(); + packet_length += tmplen; + bodydata += input.substring(mypos2, mypos2 + tmplen); + mypos2 += tmplen; + break; + } else if (input[mypos2].charCodeAt() >= 192 && input[mypos2].charCodeAt() < 224) { + var tmplen = ((input[mypos2++].charCodeAt() - 192) << 8) + (input[mypos2++].charCodeAt()) + 192; + packet_length += tmplen; + bodydata += input.substring(mypos2, mypos2 + tmplen); + mypos2 += tmplen; + break; + } else if (input[mypos2].charCodeAt() > 223 && input[mypos2].charCodeAt() < 255) { + var tmplen = 1 << (input[mypos2++].charCodeAt() & 0x1F); + packet_length += tmplen; + bodydata += input.substring(mypos2, mypos2 + tmplen); + mypos2 += tmplen; + } else { + mypos2++; + var tmplen = (input[mypos2++].charCodeAt() << 24) | (input[mypos2++].charCodeAt() << 16) | (input[mypos2++] + .charCodeAt() << 8) | input[mypos2++].charCodeAt(); + bodydata += input.substring(mypos2, mypos2 + tmplen); + packet_length += tmplen; + mypos2 += tmplen; + break; + } + } + real_packet_length = mypos2; + // 4.2.2.3. Five-Octet Lengths + } else { + mypos++; + packet_length = (input[mypos++].charCodeAt() << 24) | (input[mypos++].charCodeAt() << 16) | (input[mypos++].charCodeAt() << + 8) | input[mypos++].charCodeAt(); + } + } + + // if there was'nt a partial body length: use the specified + // packet_length + if (real_packet_length == -1) { + real_packet_length = packet_length; + } + + if (bodydata == null) { + bodydata = input.substring(mypos, mypos + real_packet_length); + } + + return { + tag: tag, + packet: bodydata, + offset: mypos + real_packet_length + }; + } +} + +},{"../enums.js":25,"../util":52}],36:[function(require,module,exports){ +var packetParser = require('./packet.js'), + packets = require('./all_packets.js'), + enums = require('../enums.js'); + +/** + * @class + * @classdesc This class represents a list of openpgp packets. + * Take care when iterating over it - the packets themselves + * are stored as numerical indices. + */ +module.exports = function packetlist() { + /** The number of packets contained within the list. + * @readonly + * @type {Integer} */ + this.length = 0; + + + + /** + * Reads a stream of binary data and interprents it as a list of packets. + * @param {openpgp_bytearray} An array of bytes. + */ + this.read = function(bytes) { + var i = 0; + + while (i < bytes.length) { + var parsed = packetParser.read(bytes, i, bytes.length - i); + i = parsed.offset; + + var tag = enums.read(enums.packet, parsed.tag); + var packet = new packets[tag](); + + this.push(packet); + + packet.read(parsed.packet); + } + } + + /** + * Creates a binary representation of openpgp objects contained within the + * class instance. + * @returns {openpgp_bytearray} An array of bytes containing valid openpgp packets. + */ + this.write = function() { + var bytes = ''; + + for (var i = 0; i < this.length; i++) { + var packetbytes = this[i].write(); + bytes += packetParser.writeHeader(this[i].tag, packetbytes.length); + bytes += packetbytes; + } + + return bytes; + } + + /** + * Adds a packet to the list. This is the only supported method of doing so; + * writing to packetlist[i] directly will result in an error. + */ + this.push = function(packet) { + packet.packets = new packetlist(); + + this[this.length] = packet; + this.length++; + } + +} + +},{"../enums.js":25,"./all_packets.js":29,"./packet.js":35}],37:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var util = require('../util'), + type_mpi = require('../type/mpi.js'), + enums = require('../enums.js'), + crypto = require('../crypto'); + +/** + * @class + * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) + * + * RFC4480 5.5: + * A key material packet contains all the information about a public or + * private key. There are four variants of this packet type, and two + * major versions. Consequently, this section is complex. + */ +module.exports = function packet_public_key() { + /** Key creation date. + * @type {Date} */ + this.created = new Date(); + /** A list of multiprecision integers + * @type {openpgp_type_mpi} */ + this.mpi = []; + /** Public key algorithm + * @type {openpgp.publickey} */ + this.algorithm = 'rsa_sign'; + + + /** + * Internal Parser for public keys as specified in RFC 4880 section + * 5.5.2 Public-Key Packet Formats + * called by read_tag<num> + * @param {String} input Input string to read the packet from + * @param {Integer} position Start position for the parser + * @param {Integer} len Length of the packet or remaining length of input + * @return {Object} This object with attributes set by the parser + */ + this.readPublicKey = this.read = function(bytes) { + // A one-octet version number (3 or 4). + var version = bytes[0].charCodeAt(); + + if (version == 4) { + // - A four-octet number denoting the time that the key was created. + this.created = util.readDate(bytes.substr(1, 4)); + + // - A one-octet number denoting the public-key algorithm of this key. + this.algorithm = enums.read(enums.publicKey, bytes[5].charCodeAt()); + + var mpicount = crypto.getPublicMpiCount(this.algorithm); + this.mpi = []; + + var bmpi = bytes.substr(6); + var p = 0; + + for (var i = 0; i < mpicount && p < bmpi.length; i++) { + + this.mpi[i] = new type_mpi(); + + p += this.mpi[i].read(bmpi.substr(p)) + + if (p > bmpi.length) + util.print_error("openpgp.packet.keymaterial.js\n" + 'error reading MPI @:' + p); + } + + return p + 6; + } else { + throw new Error('Version ' + version + ' of the key packet is unsupported.'); + } + } + + /* + * Same as write_private_key, but has less information because of + * public key. + * @param {Integer} keyType Follows the OpenPGP algorithm standard, + * IE 1 corresponds to RSA. + * @param {RSA.keyObject} key + * @param timePacket + * @return {Object} {body: [string]OpenPGP packet body contents, + * header: [string] OpenPGP packet header, string: [string] header+body} + */ + this.writePublicKey = this.write = function() { + // Version + var result = String.fromCharCode(4); + result += util.writeDate(this.created); + result += String.fromCharCode(enums.write(enums.publicKey, this.algorithm)); + + var mpicount = crypto.getPublicMpiCount(this.algorithm); + + for (var i = 0; i < mpicount; i++) { + result += this.mpi[i].write(); + } + + return result; + } + + // Write an old version packet - it's used by some of the internal routines. + this.writeOld = function() { + var bytes = this.writePublicKey(); + + return String.fromCharCode(0x99) + + util.writeNumber(bytes.length, 2) + + bytes; + } + + /** + * Calculates the key id of the key + * @return {String} A 8 byte key id + */ + this.getKeyId = function() { + return this.getFingerprint().substr(12, 8); + } + + /** + * Calculates the fingerprint of the key + * @return {String} A string containing the fingerprint + */ + this.getFingerprint = function() { + var toHash = this.writeOld(); + return crypto.hash.sha1(toHash, toHash.length); + } + +} + +},{"../crypto":14,"../enums.js":25,"../type/mpi.js":50,"../util":52}],38:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var type_keyid = require('../type/keyid.js'), + util = require('../util'), + type_mpi = require('../type/mpi.js'), + enums = require('../enums.js'), + crypto = require('../crypto'); + + +/** + * @class + * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) + * + * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key + * used to encrypt a message. Zero or more Public-Key Encrypted Session Key + * packets and/or Symmetric-Key Encrypted Session Key packets may precede a + * Symmetrically Encrypted Data Packet, which holds an encrypted message. The + * message is encrypted with the session key, and the session key is itself + * encrypted and stored in the Encrypted Session Key packet(s). The + * Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted + * Session Key packet for each OpenPGP key to which the message is encrypted. + * The recipient of the message finds a session key that is encrypted to their + * public key, decrypts the session key, and then uses the session key to + * decrypt the message. + */ +module.exports = function packet_public_key_encrypted_session_key() { + this.version = 3; + + this.publicKeyId = new type_keyid(); + this.publicKeyAlgorithm = 'rsa_encrypt'; + + this.sessionKey = null; + this.sessionKeyAlgorithm = 'aes256'; + + /** @type {openpgp_type_mpi[]} */ + this.encrypted = []; + + /** + * Parsing function for a publickey encrypted session key packet (tag 1). + * + * @param {String} input Payload of a tag 1 packet + * @param {Integer} position Position to start reading from the input string + * @param {Integer} len Length of the packet or the remaining length of + * input at position + * @return {openpgp_packet_encrypteddata} Object representation + */ + this.read = function(bytes) { + + this.version = bytes[0].charCodeAt(); + this.publicKeyId.read(bytes.substr(1)); + this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes[9].charCodeAt()); + + var i = 10; + + var integerCount = (function(algo) { + switch (algo) { + case 'rsa_encrypt': + case 'rsa_encrypt_sign': + return 1; + + case 'elgamal': + return 2; + + default: + throw new Error("Invalid algorithm."); + } + })(this.publicKeyAlgorithm); + + this.encrypted = []; + + for (var j = 0; j < integerCount; j++) { + var mpi = new type_mpi(); + i += mpi.read(bytes.substr(i)); + this.encrypted.push(mpi); + } + } + + /** + * Create a string representation of a tag 1 packet + * + * @param {String} publicKeyId + * The public key id corresponding to publicMPIs key as string + * @param {openpgp_type_mpi[]} publicMPIs + * Multiprecision integer objects describing the public key + * @param {Integer} pubalgo + * The corresponding public key algorithm // See RFC4880 9.1 + * @param {Integer} symmalgo + * The symmetric cipher algorithm used to encrypt the data + * within an encrypteddatapacket or encryptedintegrity- + * protecteddatapacket + * following this packet //See RFC4880 9.2 + * @param {String} sessionkey + * A string of randombytes representing the session key + * @return {String} The string representation + */ + this.write = function() { + + var result = String.fromCharCode(this.version); + result += this.publicKeyId.write(); + result += String.fromCharCode( + enums.write(enums.publicKey, this.publicKeyAlgorithm)); + + for (var i = 0; i < this.encrypted.length; i++) { + result += this.encrypted[i].write() + } + + return result; + } + + this.encrypt = function(key) { + var data = String.fromCharCode( + enums.write(enums.symmetric, this.sessionKeyAlgorithm)); + + data += this.sessionKey; + var checksum = util.calc_checksum(this.sessionKey); + data += util.writeNumber(checksum, 2); + + var mpi = new type_mpi(); + mpi.fromBytes(crypto.pkcs1.eme.encode( + data, + key.mpi[0].byteLength())); + + this.encrypted = crypto.publicKeyEncrypt( + this.publicKeyAlgorithm, + key.mpi, + mpi); + } + + /** + * Decrypts the session key (only for public key encrypted session key + * packets (tag 1) + * + * @param {openpgp_msg_message} msg + * The message object (with member encryptedData + * @param {openpgp_msg_privatekey} key + * Private key with secMPIs unlocked + * @return {String} The unencrypted session key + */ + this.decrypt = function(key) { + var result = crypto.publicKeyDecrypt( + this.publicKeyAlgorithm, + key.mpi, + this.encrypted).toBytes(); + + var checksum = util.readNumber(result.substr(result.length - 2)); + + var decoded = crypto.pkcs1.eme.decode( + result, + key.mpi[0].byteLength()); + + var key = decoded.substring(1, decoded.length - 2); + + if (checksum != util.calc_checksum(key)) { + throw new Error('Checksum mismatch'); + } else { + this.sessionKey = key; + this.sessionKeyAlgorithm = + enums.read(enums.symmetric, decoded.charCodeAt(0)); + } + } +}; + +},{"../crypto":14,"../enums.js":25,"../type/keyid.js":49,"../type/mpi.js":50,"../util":52}],39:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var public_key = require('./public_key.js'); + +module.exports = function public_subkey() { + public_key.call(this); +} + +},{"./public_key.js":37}],40:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var publicKey = require('./public_key.js'), + enums = require('../enums.js'), + util = require('../util'), + crypto = require('../crypto'), + type_mpi = require('../type/mpi.js'), + type_s2k = require('../type/s2k.js'); + +/** + * @class + * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) + * + * RFC4480 5.5: + * A key material packet contains all the information about a public or + * private key. There are four variants of this packet type, and two + * major versions. Consequently, this section is complex. + */ +function packet_secret_key() { + publicKey.call(this); + + this.encrypted = null; + + + function get_hash_len(hash) { + if (hash == 'sha1') + return 20; + else + return 2; + } + + function get_hash_fn(hash) { + if (hash == 'sha1') + return crypto.hash.sha1; + else + return function(c) { + return util.writeNumber(util.calc_checksum(c), 2); + }; + } + + // Helper function + + function parse_cleartext_mpi(hash_algorithm, cleartext, algorithm) { + var hashlen = get_hash_len(hash_algorithm), + hashfn = get_hash_fn(hash_algorithm); + + var hashtext = cleartext.substr(cleartext.length - hashlen); + cleartext = cleartext.substr(0, cleartext.length - hashlen); + + var hash = hashfn(cleartext); + + if (hash != hashtext) + throw new Error("Hash mismatch."); + + var mpis = crypto.getPrivateMpiCount(algorithm); + + var j = 0; + var mpi = []; + + for (var i = 0; i < mpis && j < cleartext.length; i++) { + mpi[i] = new type_mpi(); + j += mpi[i].read(cleartext.substr(j)); + } + + return mpi; + } + + function write_cleartext_mpi(hash_algorithm, algorithm, mpi) { + var bytes = ''; + var discard = crypto.getPublicMpiCount(algorithm); + + for (var i = discard; i < mpi.length; i++) { + bytes += mpi[i].write(); + } + + + bytes += get_hash_fn(hash_algorithm)(bytes); + + return bytes; + } + + + // 5.5.3. Secret-Key Packet Formats + + /** + * Internal parser for private keys as specified in RFC 4880 section 5.5.3 + * @param {String} bytes Input string to read the packet from + * @param {Integer} position Start position for the parser + * @param {Integer} len Length of the packet or remaining length of bytes + * @return {Object} This object with attributes set by the parser + */ + this.read = function(bytes) { + // - A Public-Key or Public-Subkey packet, as described above. + var len = this.readPublicKey(bytes); + + bytes = bytes.substr(len); + + + // - One octet indicating string-to-key usage conventions. Zero + // indicates that the secret-key data is not encrypted. 255 or 254 + // indicates that a string-to-key specifier is being given. Any + // other value is a symmetric-key encryption algorithm identifier. + var isEncrypted = bytes[0].charCodeAt(); + + if (isEncrypted) { + this.encrypted = bytes; + } else { + + // - Plain or encrypted multiprecision integers comprising the secret + // key data. These algorithm-specific fields are as described + // below. + + this.mpi = this.mpi.concat(parse_cleartext_mpi('mod', bytes.substr(1), + this.algorithm)); + } + + }; + + /* + * Creates an OpenPGP key packet for the given key. much + * TODO in regards to s2k, subkeys. + * @param {Integer} keyType Follows the OpenPGP algorithm standard, + * IE 1 corresponds to RSA. + * @param {RSA.keyObject} key + * @param passphrase + * @param s2kHash + * @param symmetricEncryptionAlgorithm + * @param timePacket + * @return {Object} {body: [string]OpenPGP packet body contents, + header: [string] OpenPGP packet header, string: [string] header+body} + */ + this.write = function() { + var bytes = this.writePublicKey(); + + if (!this.encrypted) { + bytes += String.fromCharCode(0); + + bytes += write_cleartext_mpi('mod', this.algorithm, this.mpi); + } else { + bytes += this.encrypted; + } + + return bytes; + }; + + + + + /** Encrypt the payload. By default, we use aes256 and iterated, salted string + * to key specifier + * @param {String} passphrase + */ + this.encrypt = function(passphrase) { + + var s2k = new type_s2k(), + symmetric = 'aes256', + cleartext = write_cleartext_mpi('sha1', this.algorithm, this.mpi), + key = produceEncryptionKey(s2k, passphrase, symmetric), + blockLen = crypto.cipher[symmetric].blockSize, + iv = crypto.random.getRandomBytes(blockLen); + + + this.encrypted = ''; + this.encrypted += String.fromCharCode(254); + this.encrypted += String.fromCharCode(enums.write(enums.symmetric, symmetric)); + this.encrypted += s2k.write(); + this.encrypted += iv; + + this.encrypted += crypto.cfb.normalEncrypt(symmetric, key, cleartext, iv); + }; + + function produceEncryptionKey(s2k, passphrase, algorithm) { + return s2k.produce_key(passphrase, + crypto.cipher[algorithm].keySize); + } + + /** + * Decrypts the private key MPIs which are needed to use the key. + * openpgp_packet_keymaterial.hasUnencryptedSecretKeyData should be + * false otherwise + * a call to this function is not needed + * + * @param {String} str_passphrase The passphrase for this private key + * as string + * @return {Boolean} True if the passphrase was correct; false if not + */ + this.decrypt = function(passphrase) { + if (!this.encrypted) + return; + + var i = 0, + symmetric, + key; + + var s2k_usage = this.encrypted[i++].charCodeAt(); + + // - [Optional] If string-to-key usage octet was 255 or 254, a one- + // octet symmetric encryption algorithm. + if (s2k_usage == 255 || s2k_usage == 254) { + symmetric = this.encrypted[i++].charCodeAt(); + symmetric = enums.read(enums.symmetric, symmetric); + + // - [Optional] If string-to-key usage octet was 255 or 254, a + // string-to-key specifier. The length of the string-to-key + // specifier is implied by its type, as described above. + var s2k = new type_s2k(); + i += s2k.read(this.encrypted.substr(i)); + + key = produceEncryptionKey(s2k, passphrase, symmetric); + } else { + symmetric = s2k_usage; + symmetric = enums.read(enums.symmetric, symmetric); + key = crypto.hash.md5(passphrase); + } + + + // - [Optional] If secret data is encrypted (string-to-key usage octet + // not zero), an Initial Vector (IV) of the same length as the + // cipher's block size. + var iv = this.encrypted.substr(i, + crypto.cipher[symmetric].blockSize); + + i += iv.length; + + var cleartext, + ciphertext = this.encrypted.substr(i); + + cleartext = crypto.cfb.normalDecrypt(symmetric, key, ciphertext, iv); + + var hash = s2k_usage == 254 ? + 'sha1' : + 'mod'; + + + this.mpi = this.mpi.concat(parse_cleartext_mpi(hash, cleartext, + this.algorithm)); + }; + + this.generate = function(bits, passphrase) { + this.mpi = crypto.generateMpi(this.algorithm, bits); + }; + +} + +packet_secret_key.prototype = new publicKey; + +module.exports = packet_secret_key; + +},{"../crypto":14,"../enums.js":25,"../type/mpi.js":50,"../type/s2k.js":51,"../util":52,"./public_key.js":37}],41:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var secret_key = require('./secret_key.js'); + +module.exports = function secret_subkey() { + secret_key.call(this); +} + +},{"./secret_key.js":40}],42:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var util = require('../util'), + packet = require('./packet.js'), + enums = require('../enums.js'), + crypto = require('../crypto'), + type_mpi = require('../type/mpi.js'); + +/** + * @class + * @classdesc Implementation of the Signature Packet (Tag 2) + * + * RFC4480 5.2: + * A Signature packet describes a binding between some public key and + * some data. The most common signatures are a signature of a file or a + * block of text, and a signature that is a certification of a User ID. + */ +module.exports = function packet_signature() { + + this.signatureType = null; + this.hashAlgorithm = null; + this.publicKeyAlgorithm = null; + + this.signatureData = null; + this.signedHashValue = null; + this.mpi = null; + + this.created = null; + this.signatureExpirationTime = null; + this.signatureNeverExpires = null; + this.exportable = null; + this.trustLevel = null; + this.trustAmount = null; + this.regularExpression = null; + this.revocable = null; + this.keyExpirationTime = null; + this.keyNeverExpires = null; + this.preferredSymmetricAlgorithms = null; + this.revocationKeyClass = null; + this.revocationKeyAlgorithm = null; + this.revocationKeyFingerprint = null; + this.issuerKeyId = null; + this.notation = {}; + this.preferredHashAlgorithms = null; + this.preferredCompressionAlgorithms = null; + this.keyServerPreferences = null; + this.preferredKeyServer = null; + this.isPrimaryUserID = null; + this.policyURI = null; + this.keyFlags = null; + this.signersUserId = null; + this.reasonForRevocationFlag = null; + this.reasonForRevocationString = null; + this.signatureTargetPublicKeyAlgorithm = null; + this.signatureTargetHashAlgorithm = null; + this.signatureTargetHash = null; + this.embeddedSignature = null; + + this.verified = false; + + + /** + * parsing function for a signature packet (tag 2). + * @param {String} bytes payload of a tag 2 packet + * @param {Integer} position position to start reading from the bytes string + * @param {Integer} len length of the packet or the remaining length of bytes at position + * @return {openpgp_packet_encrypteddata} object representation + */ + this.read = function(bytes) { + var i = 0; + + var version = bytes[i++].charCodeAt(); + // switch on version (3 and 4) + switch (version) { + case 3: + // One-octet length of following hashed material. MUST be 5. + if (bytes[i++].charCodeAt() != 5) + util.print_debug("openpgp.packet.signature.js\n" + + 'invalid One-octet length of following hashed material.' + + 'MUST be 5. @:' + (i - 1)); + + var sigpos = i; + // One-octet signature type. + this.signatureType = bytes[i++].charCodeAt(); + + // Four-octet creation time. + this.created = util.readDate(bytes.substr(i, 4)); + i += 4; + + // storing data appended to data which gets verified + this.signatureData = bytes.substring(position, i); + + // Eight-octet Key ID of signer. + this.issuerKeyId = bytes.substring(i, i + 8); + i += 8; + + // One-octet public-key algorithm. + this.publicKeyAlgorithm = bytes[i++].charCodeAt(); + + // One-octet hash algorithm. + this.hashAlgorithm = bytes[i++].charCodeAt(); + break; + case 4: + this.signatureType = bytes[i++].charCodeAt(); + this.publicKeyAlgorithm = bytes[i++].charCodeAt(); + this.hashAlgorithm = bytes[i++].charCodeAt(); + + + function subpackets(bytes, signed) { + // Two-octet scalar octet count for following hashed subpacket + // data. + var subpacket_length = util.readNumber( + bytes.substr(0, 2)); + + var i = 2; + + // Hashed subpacket data set (zero or more subpackets) + var subpacked_read = 0; + while (i < 2 + subpacket_length) { + + var len = packet.readSimpleLength(bytes.substr(i)); + i += len.offset; + + // Since it is trivial to add data to the unhashed portion of + // the packet we simply ignore all unauthenticated data. + if (signed) + this.read_sub_packet(bytes.substr(i, len.len)); + + i += len.len; + } + + return i; + } + + i += subpackets.call(this, bytes.substr(i), true); + + // A V4 signature hashes the packet body + // starting from its first field, the version number, through the end + // of the hashed subpacket data. Thus, the fields hashed are the + // signature version, the signature type, the public-key algorithm, the + // hash algorithm, the hashed subpacket length, and the hashed + // subpacket body. + this.signatureData = bytes.substr(0, i); + + i += subpackets.call(this, bytes.substr(i), false); + + break; + default: + throw new Error('Version ' + version + ' of the signature is unsupported.'); + break; + } + + // Two-octet field holding left 16 bits of signed hash value. + this.signedHashValue = bytes.substr(i, 2); + i += 2; + + this.signature = bytes.substr(i); + } + + this.write = function() { + return this.signatureData + + util.writeNumber(0, 2) + // Number of unsigned subpackets. + this.signedHashValue + + this.signature; + } + + /** + * Signs provided data. This needs to be done prior to serialization. + * @param {Object} data Contains packets to be signed. + * @param {openpgp_msg_privatekey} privatekey private key used to sign the message. + */ + this.sign = function(key, data) { + var signatureType = enums.write(enums.signature, this.signatureType), + publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm), + hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm); + + var result = String.fromCharCode(4); + result += String.fromCharCode(signatureType); + result += String.fromCharCode(publicKeyAlgorithm); + result += String.fromCharCode(hashAlgorithm); + + + // Add subpackets here + result += util.writeNumber(0, 2); + + + this.signatureData = result; + + var trailer = this.calculateTrailer(); + + var toHash = this.toSign(signatureType, data) + + this.signatureData + trailer; + + var hash = crypto.hash.digest(hashAlgorithm, toHash); + + this.signedHashValue = hash.substr(0, 2); + + + this.signature = crypto.signature.sign(hashAlgorithm, + publicKeyAlgorithm, key.mpi, toHash); + } + + /** + * creates a string representation of a sub signature packet (See RFC 4880 5.2.3.1) + * @param {Integer} type subpacket signature type. Signature types as described + * in RFC4880 Section 5.2.3.2 + * @param {String} data data to be included + * @return {String} a string-representation of a sub signature packet (See RFC 4880 5.2.3.1) + */ + function write_sub_packet(type, data) { + var result = ""; + result += packet.writeSimpleLength(data.length + 1); + result += String.fromCharCode(type); + result += data; + return result; + } + + // V4 signature sub packets + + this.read_sub_packet = function(bytes) { + var mypos = 0; + + function read_array(prop, bytes) { + this[prop] = []; + + for (var i = 0; i < bytes.length; i++) { + this[prop].push(bytes[i].charCodeAt()); + } + } + + // The leftwost bit denotes a "critical" packet, but we ignore it. + var type = bytes[mypos++].charCodeAt() & 0x7F; + + // subpacket type + switch (type) { + case 2: + // Signature Creation Time + this.created = util.readDate(bytes.substr(mypos)); + break; + case 3: + // Signature Expiration Time + var time = util.readDate(bytes.substr(mypos)); + + this.signatureNeverExpires = time.getTime() == 0; + this.signatureExpirationTime = time; + + break; + case 4: + // Exportable Certification + this.exportable = bytes[mypos++].charCodeAt() == 1; + break; + case 5: + // Trust Signature + this.trustLevel = bytes[mypos++].charCodeAt(); + this.trustAmount = bytes[mypos++].charCodeAt(); + break; + case 6: + // Regular Expression + this.regularExpression = bytes.substr(mypos); + break; + case 7: + // Revocable + this.revocable = bytes[mypos++].charCodeAt() == 1; + break; + case 9: + // Key Expiration Time + var time = util.readDate(bytes.substr(mypos)); + + this.keyExpirationTime = time; + this.keyNeverExpires = time.getTime() == 0; + + break; + case 11: + // Preferred Symmetric Algorithms + this.preferredSymmetricAlgorithms = []; + + while (mypos != bytes.length) { + this.preferredSymmetricAlgorithms.push(bytes[mypos++].charCodeAt()); + } + + break; + case 12: + // Revocation Key + // (1 octet of class, 1 octet of public-key algorithm ID, 20 + // octets of + // fingerprint) + this.revocationKeyClass = bytes[mypos++].charCodeAt(); + this.revocationKeyAlgorithm = bytes[mypos++].charCodeAt(); + this.revocationKeyFingerprint = bytes.substr(mypos, 20); + break; + + case 16: + // Issuer + this.issuerKeyId = bytes.substr(mypos, 8); + break; + + case 20: + // Notation Data + // We don't know how to handle anything but a text flagged data. + if (bytes[mypos].charCodeAt() == 0x80) { + + // We extract key/value tuple from the byte stream. + mypos += 4; + var m = util.writeNumber(bytes.substr(mypos, 2)); + mypos += 2 + var n = util.writeNumber(bytes.substr(mypos, 2)); + mypos += 2 + + var name = bytes.substr(mypos, m), + value = bytes.substr(mypos + m, n); + + this.notation[name] = value; + } else throw new Error("Unsupported notation flag."); + break; + case 21: + // Preferred Hash Algorithms + read_array.call(this, 'preferredHashAlgorithms', bytes.substr(mypos)); + break; + case 22: + // Preferred Compression Algorithms + read_array.call(this, 'preferredCompressionAlgorithms ', bytes.substr(mypos)); + break; + case 23: + // Key Server Preferences + read_array.call(this, 'keyServerPreferencess', bytes.substr(mypos)); + break; + case 24: + // Preferred Key Server + this.preferredKeyServer = bytes.substr(mypos); + break; + case 25: + // Primary User ID + this.isPrimaryUserID = bytes[mypos++] != 0; + break; + case 26: + // Policy URI + this.policyURI = bytes.substr(mypos); + break; + case 27: + // Key Flags + read_array.call(this, 'keyFlags', bytes.substr(mypos)); + break; + case 28: + // Signer's User ID + this.signersUserId += bytes.substr(mypos); + break; + case 29: + // Reason for Revocation + this.reasonForRevocationFlag = bytes[mypos++].charCodeAt(); + this.reasonForRevocationString = bytes.substr(mypos); + break; + case 30: + // Features + read_array.call(this, 'features', bytes.substr(mypos)); + break; + case 31: + // Signature Target + // (1 octet public-key algorithm, 1 octet hash algorithm, N octets hash) + this.signatureTargetPublicKeyAlgorithm = bytes[mypos++].charCodeAt(); + this.signatureTargetHashAlgorithm = bytes[mypos++].charCodeAt(); + + var len = crypto.getHashByteLength(this.signatureTargetHashAlgorithm); + + this.signatureTargetHash = bytes.substr(mypos, len); + break; + case 32: + // Embedded Signature + this.embeddedSignature = new packet_signature(); + this.embeddedSignature.read(bytes.substr(mypos)); + break; + default: + util.print_error("openpgp.packet.signature.js\n" + + 'unknown signature subpacket type ' + type + " @:" + mypos + + " subplen:" + subplen + " len:" + len); + break; + } + }; + + // Produces data to produce signature on + this.toSign = function(type, data) { + var t = enums.signature; + + switch (type) { + case t.binary: + return data.getBytes(); + + case t.text: + return this.toSign(t.binary, data) + .replace(/\r\n/g, '\n') + .replace(/\n/g, '\r\n'); + + case t.standalone: + return ''; + + case t.cert_generic: + case t.cert_persona: + case t.cert_casual: + case t.cert_positive: + case t.cert_revocation: + { + var packet, tag; + + if (data.userid !== undefined) { + tag = 0xB4; + packet = data.userid; + } else if (data.userattribute !== undefined) { + tag = 0xD1; + packet = data.userattribute; + } else throw new Error('Either a userid or userattribute packet needs to be ' + + 'supplied for certification.'); + + var bytes = packet.write(); + + return this.toSign(t.key, data) + + String.fromCharCode(tag) + + util.writeNumber(bytes.length, 4) + + bytes; + } + case t.subkey_binding: + case t.key_binding: + { + return this.toSign(t.key, data) + this.toSign(t.key, { + key: data.bind + }); + } + case t.key: + { + if (data.key == undefined) + throw new Error('Key packet is required for this sigtature.'); + + return data.key.writeOld(); + } + case t.key_revocation: + case t.subkey_revocation: + return this.toSign(t.key, data); + case t.timestamp: + return ''; + case t.thrid_party: + throw new Error('Not implemented'); + break; + default: + throw new Error('Unknown signature type.') + } + } + + + this.calculateTrailer = function() { + // calculating the trailer + var trailer = ''; + trailer += String.fromCharCode(4); // Version + trailer += String.fromCharCode(0xFF); + trailer += util.writeNumber(this.signatureData.length, 4); + return trailer + } + + + /** + * verifys the signature packet. Note: not signature types are implemented + * @param {String} data data which on the signature applies + * @param {openpgp_msg_privatekey} key the public key to verify the signature + * @return {boolean} True if message is verified, else false. + */ + this.verify = function(key, data) { + var signatureType = enums.write(enums.signature, this.signatureType), + publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm), + hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm); + + var bytes = this.toSign(signatureType, data), + trailer = this.calculateTrailer(); + + + var mpicount = 0; + // Algorithm-Specific Fields for RSA signatures: + // - multiprecision number (MPI) of RSA signature value m**d mod n. + if (publicKeyAlgorithm > 0 && publicKeyAlgorithm < 4) + mpicount = 1; + // Algorithm-Specific Fields for DSA signatures: + // - MPI of DSA value r. + // - MPI of DSA value s. + else if (publicKeyAlgorithm == 17) + mpicount = 2; + + var mpi = [], + i = 0; + for (var j = 0; j < mpicount; j++) { + mpi[j] = new type_mpi(); + i += mpi[j].read(this.signature.substr(i)); + } + + this.verified = crypto.signature.verify(publicKeyAlgorithm, + hashAlgorithm, mpi, key.mpi, + bytes + this.signatureData + trailer); + + return this.verified; + } +} + +},{"../crypto":14,"../enums.js":25,"../type/mpi.js":50,"../util":52,"./packet.js":35}],43:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var util = require('../util'), + crypto = require('../crypto'); + +/** + * @class + * @classdesc Implementation of the Sym. Encrypted Integrity Protected Data + * Packet (Tag 18) + * + * RFC4880 5.13: The Symmetrically Encrypted Integrity Protected Data packet is + * a variant of the Symmetrically Encrypted Data packet. It is a new feature + * created for OpenPGP that addresses the problem of detecting a modification to + * encrypted data. It is used in combination with a Modification Detection Code + * packet. + */ + +module.exports = function packet_sym_encrypted_integrity_protected() { + /** The encrypted payload. */ + this.encrypted = null; // string + /** @type {Boolean} + * If after decrypting the packet this is set to true, + * a modification has been detected and thus the contents + * should be discarded. + */ + this.modification = false; + this.packets; + + + this.read = function(bytes) { + // - A one-octet version number. The only currently defined value is + // 1. + var version = bytes[0].charCodeAt(); + + if (version != 1) { + throw new Error('Invalid packet version.'); + } + + // - Encrypted data, the output of the selected symmetric-key cipher + // operating in Cipher Feedback mode with shift amount equal to the + // block size of the cipher (CFB-n where n is the block size). + this.encrypted = bytes.substr(1); + } + + this.write = function() { + + return String.fromCharCode(1) // Version + + this.encrypted; + } + + this.encrypt = function(sessionKeyAlgorithm, key) { + var bytes = this.packets.write() + + var prefixrandom = crypto.getPrefixRandom(sessionKeyAlgorithm); + var prefix = prefixrandom + prefixrandom.charAt(prefixrandom.length - 2) + prefixrandom.charAt(prefixrandom.length - + 1) + + var tohash = bytes; + + + // Modification detection code packet. + tohash += String.fromCharCode(0xD3); + tohash += String.fromCharCode(0x14); + + + tohash += crypto.hash.sha1(prefix + tohash); + + + this.encrypted = crypto.cfb.encrypt(prefixrandom, + sessionKeyAlgorithm, tohash, key, false).substring(0, + prefix.length + tohash.length); + } + + /** + * Decrypts the encrypted data contained in this object read_packet must + * have been called before + * + * @param {Integer} sessionKeyAlgorithm + * The selected symmetric encryption algorithm to be used + * @param {String} key The key of cipher blocksize length to be used + * @return {String} The decrypted data of this packet + */ + this.decrypt = function(sessionKeyAlgorithm, key) { + var decrypted = crypto.cfb.decrypt( + sessionKeyAlgorithm, key, this.encrypted, false); + + + // there must be a modification detection code packet as the + // last packet and everything gets hashed except the hash itself + this.hash = crypto.hash.sha1( + crypto.cfb.mdc(sessionKeyAlgorithm, key, this.encrypted) + decrypted.substring(0, decrypted.length - 20)); + + + var mdc = decrypted.substr(decrypted.length - 20, 20); + + if (this.hash != mdc) { + throw new Error('Modification detected.'); + } else + this.packets.read(decrypted.substr(0, decrypted.length - 22)); + } +}; + +},{"../crypto":14,"../util":52}],44:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var type_s2k = require('../type/s2k.js'), + enums = require('../enums.js'), + crypto = require('../crypto'); + +/** + * @class + * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) + * + * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key + * used to encrypt a message. Zero or more Public-Key Encrypted Session Key + * packets and/or Symmetric-Key Encrypted Session Key packets may precede a + * Symmetrically Encrypted Data Packet, which holds an encrypted message. The + * message is encrypted with the session key, and the session key is itself + * encrypted and stored in the Encrypted Session Key packet(s). The + * Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted + * Session Key packet for each OpenPGP key to which the message is encrypted. + * The recipient of the message finds a session key that is encrypted to their + * public key, decrypts the session key, and then uses the session key to + * decrypt the message. + */ +module.exports = function packet_sym_encrypted_session_key() { + this.tag = 3; + this.sessionKeyEncryptionAlgorithm = null; + this.sessionKeyAlgorithm = 'aes256'; + this.encrypted = null; + this.s2k = new type_s2k(); + + /** + * Parsing function for a symmetric encrypted session key packet (tag 3). + * + * @param {String} input Payload of a tag 1 packet + * @param {Integer} position Position to start reading from the input string + * @param {Integer} len + * Length of the packet or the remaining length of + * input at position + * @return {openpgp_packet_encrypteddata} Object representation + */ + this.read = function(bytes) { + // A one-octet version number. The only currently defined version is 4. + this.version = bytes[0].charCodeAt(); + + // A one-octet number describing the symmetric algorithm used. + var algo = enums.read(enums.symmetric, bytes[1].charCodeAt()); + + // A string-to-key (S2K) specifier, length as defined above. + var s2klength = this.s2k.read(bytes.substr(2)); + + // Optionally, the encrypted session key itself, which is decrypted + // with the string-to-key object. + var done = s2klength + 2; + + if (done < bytes.length) { + this.encrypted = bytes.substr(done); + this.sessionKeyEncryptionAlgorithm = algo + } else + this.sessionKeyAlgorithm = algo; + } + + this.write = function() { + var algo = this.encrypted == null ? + this.sessionKeyAlgorithm : + this.sessionKeyEncryptionAlgorithm; + + var bytes = String.fromCharCode(this.version) + + String.fromCharCode(enums.write(enums.symmetric, algo)) + + this.s2k.write(); + + if (this.encrypted != null) + bytes += this.encrypted; + return bytes; + } + + /** + * Decrypts the session key (only for public key encrypted session key + * packets (tag 1) + * + * @param {openpgp_msg_message} msg + * The message object (with member encryptedData + * @param {openpgp_msg_privatekey} key + * Private key with secMPIs unlocked + * @return {String} The unencrypted session key + */ + this.decrypt = function(passphrase) { + var algo = this.sessionKeyEncryptionAlgorithm != null ? + this.sessionKeyEncryptionAlgorithm : + this.sessionKeyAlgorithm; + + + var length = crypto.cipher[algo].keySize; + var key = this.s2k.produce_key(passphrase, length); + + if (this.encrypted == null) { + this.sessionKey = key; + + } else { + var decrypted = crypto.cfb.decrypt( + this.sessionKeyEncryptionAlgorithm, key, this.encrypted, true); + + this.sessionKeyAlgorithm = enums.read(enums.symmetric, + decrypted[0].keyCodeAt()); + + this.sessionKey = decrypted.substr(1); + } + } + + this.encrypt = function(passphrase) { + var length = crypto.getKeyLength(this.sessionKeyEncryptionAlgorithm); + var key = this.s2k.produce_key(passphrase, length); + + var private_key = String.fromCharCode( + enums.write(enums.symmetric, this.sessionKeyAlgorithm)) + + + crypto.getRandomBytes( + crypto.getKeyLength(this.sessionKeyAlgorithm)); + + this.encrypted = crypto.cfb.encrypt( + crypto.getPrefixRandom(this.sessionKeyEncryptionAlgorithm), + this.sessionKeyEncryptionAlgorithm, key, private_key, true); + } +}; + +},{"../crypto":14,"../enums.js":25,"../type/s2k.js":51}],45:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var crypto = require('../crypto'); + +/** + * @class + * @classdesc Implementation of the Symmetrically Encrypted Data Packet (Tag 9) + * + * RFC4880 5.7: The Symmetrically Encrypted Data packet contains data encrypted + * with a symmetric-key algorithm. When it has been decrypted, it contains other + * packets (usually a literal data packet or compressed data packet, but in + * theory other Symmetrically Encrypted Data packets or sequences of packets + * that form whole OpenPGP messages). + */ + +module.exports = function packet_symmetrically_encrypted() { + this.encrypted = null; + /** Decrypted packets contained within. + * @type {openpgp_packetlist} */ + this.packets; + + this.read = function(bytes) { + this.encrypted = bytes; + } + + this.write = function() { + return this.encrypted; + } + + /** + * Symmetrically decrypt the packet data + * + * @param {Integer} sessionKeyAlgorithm + * Symmetric key algorithm to use // See RFC4880 9.2 + * @param {String} key + * Key as string with the corresponding length to the + * algorithm + * @return The decrypted data; + */ + this.decrypt = function(sessionKeyAlgorithm, key) { + var decrypted = crypto.cfb.decrypt( + sessionKeyAlgorithm, key, this.encrypted, true); + + this.packets.read(decrypted); + } + + this.encrypt = function(algo, key) { + var data = this.packets.write(); + + this.encrypted = crypto.cfb.encrypt( + crypto.getPrefixRandom(algo), algo, data, key, true); + } +}; + +},{"../crypto":14}],46:[function(require,module,exports){ +module.exports = function packet_trust() { + +}; + +},{}],47:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/** + * @class + * @classdesc Implementation of the User Attribute Packet (Tag 17) + * The User Attribute packet is a variation of the User ID packet. It + * is capable of storing more types of data than the User ID packet, + * which is limited to text. Like the User ID packet, a User Attribute + * packet may be certified by the key owner ("self-signed") or any other + * key owner who cares to certify it. Except as noted, a User Attribute + * packet may be used anywhere that a User ID packet may be used. + * + * While User Attribute packets are not a required part of the OpenPGP + * standard, implementations SHOULD provide at least enough + * compatibility to properly handle a certification signature on the + * User Attribute packet. A simple way to do this is by treating the + * User Attribute packet as a User ID packet with opaque contents, but + * an implementation may use any method desired. + */ +module.exports = function packet_user_attribute() { + this.tag = 17; + this.attributes = []; + + /** + * parsing function for a user attribute packet (tag 17). + * @param {String} input payload of a tag 17 packet + * @param {Integer} position position to start reading from the input string + * @param {Integer} len length of the packet or the remaining length of input at position + * @return {openpgp_packet_encrypteddata} object representation + */ + this.read = function(bytes) { + var i = 0; + while (i < bytes.length) { + var len = openpgp_packet.read_simple_length(bytes); + + i += len.offset; + this.attributes.push(bytes.substr(i, len.len)); + i += len.len; + } + } +}; + +},{}],48:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var util = require('../util'); + +/** + * @class + * @classdesc Implementation of the User ID Packet (Tag 13) + * A User ID packet consists of UTF-8 text that is intended to represent + * the name and email address of the key holder. By convention, it + * includes an RFC 2822 [RFC2822] mail name-addr, but there are no + * restrictions on its content. The packet length in the header + * specifies the length of the User ID. + */ +module.exports = function packet_userid() { + /** @type {String} A string containing the user id. Usually in the form + * John Doe + */ + this.userid = ''; + + + /** + * Parsing function for a user id packet (tag 13). + * @param {String} input payload of a tag 13 packet + * @param {Integer} position position to start reading from the input string + * @param {Integer} len length of the packet or the remaining length of input + * at position + * @return {openpgp_packet_encrypteddata} object representation + */ + this.read = function(bytes) { + this.userid = util.decode_utf8(bytes); + } + + /** + * Creates a string representation of the user id packet + * @param {String} user_id the user id as string ("John Doe > 4) + expbias); + } + + /** + * Parsing function for a string-to-key specifier (RFC 4880 3.7). + * @param {String} input Payload of string-to-key specifier + * @return {Integer} Actual length of the object + */ + this.read = function(bytes) { + var i = 0; + this.type = enums.read(enums.s2k, bytes[i++].charCodeAt()); + this.algorithm = enums.read(enums.hash, bytes[i++].charCodeAt()); + + switch (this.type) { + case 'simple': + break; + + case 'salted': + this.salt = bytes.substr(i, 8); + i += 8; + break; + + case 'iterated': + this.salt = bytes.substr(i, 8); + i += 8; + + // Octet 10: count, a one-octet, coded value + this.c = bytes[i++].charCodeAt(); + break; + + case 'gnu': + if (bytes.substr(i, 3) == "GNU") { + i += 3; // GNU + var gnuExtType = 1000 + bytes[i++].charCodeAt(); + if (gnuExtType == 1001) { + this.type = gnuExtType; + // GnuPG extension mode 1001 -- don't write secret key at all + } else { + throw new Error("Unknown s2k gnu protection mode."); + } + } else { + throw new Error("Unknown s2k type."); + } + break; + + default: + throw new Error("Unknown s2k type."); + break; + } + + return i; + } + + + /** + * writes an s2k hash based on the inputs. + * @return {String} Produced key of hashAlgorithm hash length + */ + this.write = function() { + var bytes = String.fromCharCode(enums.write(enums.s2k, this.type)); + bytes += String.fromCharCode(enums.write(enums.hash, this.algorithm)); + + switch (this.type) { + case 'simple': + break; + case 'salted': + bytes += this.salt; + break; + case 'iterated': + bytes += this.salt; + bytes += String.fromCharCode(this.c); + break; + }; + + return bytes; + } + + /** + * Produces a key using the specified passphrase and the defined + * hashAlgorithm + * @param {String} passphrase Passphrase containing user input + * @return {String} Produced key with a length corresponding to + * hashAlgorithm hash length + */ + this.produce_key = function(passphrase, numBytes) { + passphrase = util.encode_utf8(passphrase); + + function round(prefix, s2k) { + var algorithm = enums.write(enums.hash, s2k.algorithm); + + switch (s2k.type) { + case 'simple': + return crypto.hash.digest(algorithm, prefix + passphrase); + + case 'salted': + return crypto.hash.digest(algorithm, + prefix + s2k.salt + passphrase); + + case 'iterated': + var isp = [], + count = s2k.get_count(); + data = s2k.salt + passphrase; + + while (isp.length * data.length < count) + isp.push(data); + + isp = isp.join(''); + + if (isp.length > count) + isp = isp.substr(0, count); + + return crypto.hash.digest(algorithm, prefix + isp); + }; + } + + var result = '', + prefix = ''; + + while (result.length <= numBytes) { + result += round(prefix, this); + prefix += String.fromCharCode(0); + } + + return result.substr(0, numBytes); + } +} + +},{"../crypto":14,"../enums.js":25,"../util":52}],52:[function(require,module,exports){ +// GPG4Browsers - An OpenPGP implementation in javascript +// Copyright (C) 2011 Recurity Labs GmbH +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +var Util = function() { + + this.readNumber = function(bytes) { + var n = 0; + + for (var i = 0; i < bytes.length; i++) { + n <<= 8; + n += bytes[i].charCodeAt(); + } + + return n; + }; + + this.writeNumber = function(n, bytes) { + var b = ''; + for (var i = 0; i < bytes; i++) { + b += String.fromCharCode((n >> (8 * (bytes - i - 1))) & 0xFF); + } + + return b; + }; + + + + this.readDate = function(bytes) { + var n = this.readNumber(bytes); + var d = new Date(); + d.setTime(n * 1000); + return d; + }; + + this.writeDate = function(time) { + var numeric = Math.round(time.getTime() / 1000); + + return this.writeNumber(numeric, 4); + }; + + this.emailRegEx = + /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/; + + this.debug = false; + + this.hexdump = function(str) { + var r = []; + var e = str.length; + var c = 0; + var h; + var i = 0; + while (c < e) { + h = str.charCodeAt(c++).toString(16); + while (h.length < 2) h = "0" + h; + r.push(" " + h); + i++; + if (i % 32 == 0) + r.push("\n "); + } + return r.join(''); + }; + + /** + * Create hexstring from a binary + * @param {String} str String to convert + * @return {String} String containing the hexadecimal values + */ + this.hexstrdump = function(str) { + if (str == null) + return ""; + var r = []; + var e = str.length; + var c = 0; + var h; + while (c < e) { + h = str[c++].charCodeAt().toString(16); + while (h.length < 2) h = "0" + h; + r.push("" + h); + } + return r.join(''); + }; + + /** + * Create binary string from a hex encoded string + * @param {String} str Hex string to convert + * @return {String} String containing the binary values + */ + this.hex2bin = function(hex) { + var str = ''; + for (var i = 0; i < hex.length; i += 2) + str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + return str; + }; + + /** + * Creating a hex string from an binary array of integers (0..255) + * @param {String} str Array of bytes to convert + * @return {String} Hexadecimal representation of the array + */ + this.hexidump = function(str) { + var r = []; + var e = str.length; + var c = 0; + var h; + while (c < e) { + h = str[c++].toString(16); + while (h.length < 2) h = "0" + h; + r.push("" + h); + } + return r.join(''); + }; + + + /** + * Convert a native javascript string to a string of utf8 bytes + * @param {String} str The string to convert + * @return {String} A valid squence of utf8 bytes + */ + this.encode_utf8 = function(str) { + return unescape(encodeURIComponent(str)); + }; + + /** + * Convert a string of utf8 bytes to a native javascript string + * @param {String} utf8 A valid squence of utf8 bytes + * @return {String} A native javascript string + */ + this.decode_utf8 = function(utf8) { + return decodeURIComponent(escape(utf8)); + }; + + var str2bin = function(str, result) { + for (var i = 0; i < str.length; i++) { + result[i] = str.charCodeAt(i); + } + + return result; + }; + + var bin2str = function(bin) { + var result = []; + + for (var i = 0; i < bin.length; i++) { + result.push(String.fromCharCode(bin[i])); + } + + return result.join(''); + }; + + /** + * Convert a string to an array of integers(0.255) + * @param {String} str String to convert + * @return {Integer[]} An array of (binary) integers + */ + this.str2bin = function(str) { + return str2bin(str, new Array(str.length)); + }; + + + /** + * Convert an array of integers(0.255) to a string + * @param {Integer[]} bin An array of (binary) integers to convert + * @return {String} The string representation of the array + */ + this.bin2str = bin2str; + + /** + * Convert a string to a Uint8Array + * @param {String} str String to convert + * @return {Uint8Array} The array of (binary) integers + */ + this.str2Uint8Array = function(str) { + return str2bin(str, new Uint8Array(new ArrayBuffer(str.length))); + }; + + /** + * Convert a Uint8Array to a string. This currently functions + * the same as bin2str. + * @param {Uint8Array} bin An array of (binary) integers to convert + * @return {String} String representation of the array + */ + this.Uint8Array2str = bin2str; + + /** + * Calculates a 16bit sum of a string by adding each character + * codes modulus 65535 + * @param {String} text String to create a sum of + * @return {Integer} An integer containing the sum of all character + * codes % 65535 + */ + this.calc_checksum = function(text) { + var checksum = { + s: 0, + add: function(sadd) { + this.s = (this.s + sadd) % 65536; + } + }; + for (var i = 0; i < text.length; i++) { + checksum.add(text.charCodeAt(i)); + } + return checksum.s; + }; + + /** + * Helper function to print a debug message. Debug + * messages are only printed if + * openpgp.config.debug is set to true. The calling + * Javascript context MUST define + * a "showMessages(text)" function. Line feeds ('\n') + * are automatically converted to HTML line feeds '
' + * @param {String} str String of the debug message + * @return {String} An HTML tt entity containing a paragraph with a + * style attribute where the debug message is HTMLencoded in. + */ + this.print_debug = function(str) { + if (this.debug) { + console.log(str); + } + }; + + /** + * Helper function to print a debug message. Debug + * messages are only printed if + * openpgp.config.debug is set to true. The calling + * Javascript context MUST define + * a "showMessages(text)" function. Line feeds ('\n') + * are automatically converted to HTML line feeds '
' + * Different than print_debug because will call hexstrdump iff necessary. + * @param {String} str String of the debug message + * @return {String} An HTML tt entity containing a paragraph with a + * style attribute where the debug message is HTMLencoded in. + */ + this.print_debug_hexstr_dump = function(str, strToHex) { + if (this.debug) { + str = str + this.hexstrdump(strToHex); + console.log(str); + } + }; + + /** + * Helper function to print an error message. + * The calling Javascript context MUST define + * a "showMessages(text)" function. Line feeds ('\n') + * are automatically converted to HTML line feeds '
' + * @param {String} str String of the error message + * @return {String} A HTML paragraph entity with a style attribute + * containing the HTML encoded error message + */ + this.print_error = function(str) { + if (this.debug) + throw str; + console.log(str); + }; + + /** + * Helper function to print an info message. + * The calling Javascript context MUST define + * a "showMessages(text)" function. Line feeds ('\n') + * are automatically converted to HTML line feeds '
'. + * @param {String} str String of the info message + * @return {String} A HTML paragraph entity with a style attribute + * containing the HTML encoded info message + */ + this.print_info = function(str) { + if (this.debug) + console.log(str); + }; + + this.print_warning = function(str) { + console.log(str); + }; + + this.getLeftNBits = function(string, bitcount) { + var rest = bitcount % 8; + if (rest == 0) + return string.substring(0, bitcount / 8); + var bytes = (bitcount - rest) / 8 + 1; + var result = string.substring(0, bytes); + return this.shiftRight(result, 8 - rest); // +String.fromCharCode(string.charCodeAt(bytes -1) << (8-rest) & 0xFF); + }; + + /** + * Shifting a string to n bits right + * @param {String} value The string to shift + * @param {Integer} bitcount Amount of bits to shift (MUST be smaller + * than 9) + * @return {String} Resulting string. + */ + this.shiftRight = function(value, bitcount) { + var temp = util.str2bin(value); + if (bitcount % 8 != 0) { + for (var i = temp.length - 1; i >= 0; i--) { + temp[i] >>= bitcount % 8; + if (i > 0) + temp[i] |= (temp[i - 1] << (8 - (bitcount % 8))) & 0xFF; + } + } else { + return value; + } + return util.bin2str(temp); + }; + + /** + * Return the algorithm type as string + * @return {String} String representing the message type + */ + this.get_hashAlgorithmString = function(algo) { + switch (algo) { + case 1: + return "MD5"; + case 2: + return "SHA1"; + case 3: + return "RIPEMD160"; + case 8: + return "SHA256"; + case 9: + return "SHA384"; + case 10: + return "SHA512"; + case 11: + return "SHA224"; + } + return "unknown"; + }; + +}; + +/** + * an instance that should be used. + */ +module.exports = new Util(); + +},{}],53:[function(require,module,exports){ +var unit = require('../../unit.js'); + +unit.register("AES Rijndael cipher test with test vectors from ecb_tbl.txt", function() { + var openpgp = require('../../../'); + var util = openpgp.util; + + var result = new Array(); + + function test_aes(input, key, output) { + var aes = new openpgp.cipher.aes128(util.bin2str(key)); + + var result = util.bin2str(aes.encrypt(input)); + + return util.hexstrdump(result) == util.hexstrdump(util.bin2str(output)); + }; + + var testvectors128 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12],[0x50,0x68,0x12,0xA4,0x5F,0x08,0xC8,0x89,0xB9,0x7F,0x59,0x80,0x03,0x8B,0x83,0x59],[0xD8,0xF5,0x32,0x53,0x82,0x89,0xEF,0x7D,0x06,0xB5,0x06,0xA4,0xFD,0x5B,0xE9,0xC9]], + [[0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26],[0x5C,0x6D,0x71,0xCA,0x30,0xDE,0x8B,0x8B,0x00,0x54,0x99,0x84,0xD2,0xEC,0x7D,0x4B],[0x59,0xAB,0x30,0xF4,0xD4,0xEE,0x6E,0x4F,0xF9,0x90,0x7E,0xF6,0x5B,0x1F,0xB6,0x8C]], + [[0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A],[0x53,0xF3,0xF4,0xC6,0x4F,0x86,0x16,0xE4,0xE7,0xC5,0x61,0x99,0xF4,0x8F,0x21,0xF6],[0xBF,0x1E,0xD2,0xFC,0xB2,0xAF,0x3F,0xD4,0x14,0x43,0xB5,0x6D,0x85,0x02,0x5C,0xB1]], + [[0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E],[0xA1,0xEB,0x65,0xA3,0x48,0x71,0x65,0xFB,0x0F,0x1C,0x27,0xFF,0x99,0x59,0xF7,0x03],[0x73,0x16,0x63,0x2D,0x5C,0x32,0x23,0x3E,0xDC,0xB0,0x78,0x05,0x60,0xEA,0xE8,0xB2]], + [[0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58,0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62],[0x35,0x53,0xEC,0xF0,0xB1,0x73,0x95,0x58,0xB0,0x8E,0x35,0x0A,0x98,0xA3,0x9B,0xFA],[0x40,0x8C,0x07,0x3E,0x3E,0x25,0x38,0x07,0x2B,0x72,0x62,0x5E,0x68,0xB8,0x36,0x4B]], + [[0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0x67,0x42,0x99,0x69,0x49,0x0B,0x97,0x11,0xAE,0x2B,0x01,0xDC,0x49,0x7A,0xFD,0xE8],[0xE1,0xF9,0x4D,0xFA,0x77,0x65,0x97,0xBE,0xAC,0xA2,0x62,0xF2,0xF6,0x36,0x6F,0xEA]], + [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A],[0x93,0x38,0x5C,0x1F,0x2A,0xEC,0x8B,0xED,0x19,0x2F,0x5A,0x8E,0x16,0x1D,0xD5,0x08],[0xF2,0x9E,0x98,0x6C,0x6A,0x1C,0x27,0xD7,0xB2,0x9F,0xFD,0x7E,0xE9,0x2B,0x75,0xF1]], + [[0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E],[0xB5,0xBF,0x94,0x6B,0xE1,0x9B,0xEB,0x8D,0xB3,0x98,0x3B,0x5F,0x4C,0x6E,0x8D,0xDB],[0x13,0x1C,0x88,0x6A,0x57,0xF8,0xC2,0xE7,0x13,0xAB,0xA6,0x95,0x5E,0x2B,0x55,0xB5]], + [[0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2],[0x41,0x32,0x1E,0xE1,0x0E,0x21,0xBD,0x90,0x72,0x27,0xC4,0x45,0x0F,0xF4,0x23,0x24],[0xD2,0xAB,0x76,0x62,0xDF,0x9B,0x8C,0x74,0x02,0x10,0xE5,0xEE,0xB6,0x1C,0x19,0x9D]], + [[0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6],[0x00,0xA8,0x2F,0x59,0xC9,0x1C,0x84,0x86,0xD1,0x2C,0x0A,0x80,0x12,0x4F,0x60,0x89],[0x14,0xC1,0x05,0x54,0xB2,0x85,0x9C,0x48,0x4C,0xAB,0x58,0x69,0xBB,0xE7,0xC4,0x70]], + [[0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0,0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA],[0x7C,0xE0,0xFD,0x07,0x67,0x54,0x69,0x1B,0x4B,0xBD,0x9F,0xAF,0x8A,0x13,0x72,0xFE],[0xDB,0x4D,0x49,0x8F,0x0A,0x49,0xCF,0x55,0x44,0x5D,0x50,0x2C,0x1F,0x9A,0xB3,0xB5]], + [[0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0x23,0x60,0x5A,0x82,0x43,0xD0,0x77,0x64,0x54,0x1B,0xC5,0xAD,0x35,0x5B,0x31,0x29],[0x6D,0x96,0xFE,0xF7,0xD6,0x65,0x90,0xA7,0x7A,0x77,0xBB,0x20,0x56,0x66,0x7F,0x7F]], + [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02],[0x12,0xA8,0xCF,0xA2,0x3E,0xA7,0x64,0xFD,0x87,0x62,0x32,0xB4,0xE8,0x42,0xBC,0x44],[0x31,0x6F,0xB6,0x8E,0xDB,0xA7,0x36,0xC5,0x3E,0x78,0x47,0x7B,0xF9,0x13,0x72,0x5C]], + [[0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16],[0xBC,0xAF,0x32,0x41,0x5E,0x83,0x08,0xB3,0x72,0x3E,0x5F,0xDD,0x85,0x3C,0xCC,0x80],[0x69,0x36,0xF2,0xB9,0x3A,0xF8,0x39,0x7F,0xD3,0xA7,0x71,0xFC,0x01,0x1C,0x8C,0x37]], + [[0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E],[0x89,0xAF,0xAE,0x68,0x5D,0x80,0x1A,0xD7,0x47,0xAC,0xE9,0x1F,0xC4,0x9A,0xDD,0xE0],[0xF3,0xF9,0x2F,0x7A,0x9C,0x59,0x17,0x9C,0x1F,0xCC,0x2C,0x2B,0xA0,0xB0,0x82,0xCD]]]; + + var testvectors192 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C],[0x2D,0x33,0xEE,0xF2,0xC0,0x43,0x0A,0x8A,0x9E,0xBF,0x45,0xE8,0x09,0xC4,0x0B,0xB6],[0xDF,0xF4,0x94,0x5E,0x03,0x36,0xDF,0x4C,0x1C,0x56,0xBC,0x70,0x0E,0xFF,0x83,0x7F]], + [[0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26,0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A],[0x6A,0xA3,0x75,0xD1,0xFA,0x15,0x5A,0x61,0xFB,0x72,0x35,0x3E,0x0A,0x5A,0x87,0x56],[0xB6,0xFD,0xDE,0xF4,0x75,0x27,0x65,0xE3,0x47,0xD5,0xD2,0xDC,0x19,0x6D,0x12,0x52]], + [[0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E,0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58],[0xBC,0x37,0x36,0x51,0x8B,0x94,0x90,0xDC,0xB8,0xED,0x60,0xEB,0x26,0x75,0x8E,0xD4],[0xD2,0x36,0x84,0xE3,0xD9,0x63,0xB3,0xAF,0xCF,0x1A,0x11,0x4A,0xCA,0x90,0xCB,0xD6]], + [[0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0xAA,0x21,0x44,0x02,0xB4,0x6C,0xFF,0xB9,0xF7,0x61,0xEC,0x11,0x26,0x3A,0x31,0x1E],[0x3A,0x7A,0xC0,0x27,0x75,0x3E,0x2A,0x18,0xC2,0xCE,0xAB,0x9E,0x17,0xC1,0x1F,0xD0]], + [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94],[0x02,0xAE,0xA8,0x6E,0x57,0x2E,0xEA,0xB6,0x6B,0x2C,0x3A,0xF5,0xE9,0xA4,0x6F,0xD6],[0x8F,0x67,0x86,0xBD,0x00,0x75,0x28,0xBA,0x26,0x60,0x3C,0x16,0x01,0xCD,0xD0,0xD8]], + [[0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2],[0xE2,0xAE,0xF6,0xAC,0xC3,0x3B,0x96,0x5C,0x4F,0xA1,0xF9,0x1C,0x75,0xFF,0x6F,0x36],[0xD1,0x7D,0x07,0x3B,0x01,0xE7,0x15,0x02,0xE2,0x8B,0x47,0xAB,0x55,0x11,0x68,0xB3]], + [[0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0],[0x06,0x59,0xDF,0x46,0x42,0x71,0x62,0xB9,0x43,0x48,0x65,0xDD,0x94,0x99,0xF9,0x1D],[0xA4,0x69,0xDA,0x51,0x71,0x19,0xFA,0xB9,0x58,0x76,0xF4,0x1D,0x06,0xD4,0x0F,0xFA]], + [[0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0x49,0xA4,0x42,0x39,0xC7,0x48,0xFE,0xB4,0x56,0xF5,0x9C,0x27,0x6A,0x56,0x58,0xDF],[0x60,0x91,0xAA,0x3B,0x69,0x5C,0x11,0xF5,0xC0,0xB6,0xAD,0x26,0xD3,0xD8,0x62,0xFF]], + [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02,0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C],[0x66,0x20,0x8F,0x6E,0x9D,0x04,0x52,0x5B,0xDE,0xDB,0x27,0x33,0xB6,0xA6,0xBE,0x37],[0x70,0xF9,0xE6,0x7F,0x9F,0x8D,0xF1,0x29,0x41,0x31,0x66,0x2D,0xC6,0xE6,0x93,0x64]], + [[0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16,0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20,0x22,0x23,0x24,0x25,0x27,0x28,0x29,0x2A],[0x33,0x93,0xF8,0xDF,0xC7,0x29,0xC9,0x7F,0x54,0x80,0xB9,0x50,0xBC,0x96,0x66,0xB0],[0xD1,0x54,0xDC,0xAF,0xAD,0x8B,0x20,0x7F,0xA5,0xCB,0xC9,0x5E,0x99,0x96,0xB5,0x59]], + [[0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E,0x40,0x41,0x42,0x43,0x45,0x46,0x47,0x48],[0x60,0x68,0x34,0xC8,0xCE,0x06,0x3F,0x32,0x34,0xCF,0x11,0x45,0x32,0x5D,0xBD,0x71],[0x49,0x34,0xD5,0x41,0xE8,0xB4,0x6F,0xA3,0x39,0xC8,0x05,0xA7,0xAE,0xB9,0xE5,0xDA]], + [[0x4A,0x4B,0x4C,0x4D,0x4F,0x50,0x51,0x52,0x54,0x55,0x56,0x57,0x59,0x5A,0x5B,0x5C,0x5E,0x5F,0x60,0x61,0x63,0x64,0x65,0x66],[0xFE,0xC1,0xC0,0x4F,0x52,0x9B,0xBD,0x17,0xD8,0xCE,0xCF,0xCC,0x47,0x18,0xB1,0x7F],[0x62,0x56,0x4C,0x73,0x8F,0x3E,0xFE,0x18,0x6E,0x1A,0x12,0x7A,0x0C,0x4D,0x3C,0x61]], + [[0x68,0x69,0x6A,0x6B,0x6D,0x6E,0x6F,0x70,0x72,0x73,0x74,0x75,0x77,0x78,0x79,0x7A,0x7C,0x7D,0x7E,0x7F,0x81,0x82,0x83,0x84],[0x32,0xDF,0x99,0xB4,0x31,0xED,0x5D,0xC5,0xAC,0xF8,0xCA,0xF6,0xDC,0x6C,0xE4,0x75],[0x07,0x80,0x5A,0xA0,0x43,0x98,0x6E,0xB2,0x36,0x93,0xE2,0x3B,0xEF,0x8F,0x34,0x38]], + [[0x86,0x87,0x88,0x89,0x8B,0x8C,0x8D,0x8E,0x90,0x91,0x92,0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,0x9D,0x9F,0xA0,0xA1,0xA2],[0x7F,0xDC,0x2B,0x74,0x6F,0x3F,0x66,0x52,0x96,0x94,0x3B,0x83,0x71,0x0D,0x1F,0x82],[0xDF,0x0B,0x49,0x31,0x03,0x8B,0xAD,0xE8,0x48,0xDE,0xE3,0xB4,0xB8,0x5A,0xA4,0x4B]], + [[0xA4,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0],[0x8F,0xBA,0x15,0x10,0xA3,0xC5,0xB8,0x7E,0x2E,0xAA,0x3F,0x7A,0x91,0x45,0x5C,0xA2],[0x59,0x2D,0x5F,0xDE,0xD7,0x65,0x82,0xE4,0x14,0x3C,0x65,0x09,0x93,0x09,0x47,0x7C]]]; + + var testvectors256 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26],[0x83,0x4E,0xAD,0xFC,0xCA,0xC7,0xE1,0xB3,0x06,0x64,0xB1,0xAB,0xA4,0x48,0x15,0xAB],[0x19,0x46,0xDA,0xBF,0x6A,0x03,0xA2,0xA2,0xC3,0xD0,0xB0,0x50,0x80,0xAE,0xD6,0xFC]], + [[0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A,0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E],[0xD9,0xDC,0x4D,0xBA,0x30,0x21,0xB0,0x5D,0x67,0xC0,0x51,0x8F,0x72,0xB6,0x2B,0xF1],[0x5E,0xD3,0x01,0xD7,0x47,0xD3,0xCC,0x71,0x54,0x45,0xEB,0xDE,0xC6,0x2F,0x2F,0xB4]], + [[0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58,0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0xA2,0x91,0xD8,0x63,0x01,0xA4,0xA7,0x39,0xF7,0x39,0x21,0x73,0xAA,0x3C,0x60,0x4C],[0x65,0x85,0xC8,0xF4,0x3D,0x13,0xA6,0xBE,0xAB,0x64,0x19,0xFC,0x59,0x35,0xB9,0xD0]], + [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E],[0x42,0x64,0xB2,0x69,0x64,0x98,0xDE,0x4D,0xF7,0x97,0x88,0xA9,0xF8,0x3E,0x93,0x90],[0x2A,0x5B,0x56,0xA5,0x96,0x68,0x0F,0xCC,0x0E,0x05,0xF5,0xE0,0xF1,0x51,0xEC,0xAE]], + [[0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2,0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6],[0xEE,0x99,0x32,0xB3,0x72,0x18,0x04,0xD5,0xA8,0x3E,0xF5,0x94,0x92,0x45,0xB6,0xF6],[0xF5,0xD6,0xFF,0x41,0x4F,0xD2,0xC6,0x18,0x14,0x94,0xD2,0x0C,0x37,0xF2,0xB8,0xC4]], + [[0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0,0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0xE6,0x24,0x8F,0x55,0xC5,0xFD,0xCB,0xCA,0x9C,0xBB,0xB0,0x1C,0x88,0xA2,0xEA,0x77],[0x85,0x39,0x9C,0x01,0xF5,0x9F,0xFF,0xB5,0x20,0x4F,0x19,0xF8,0x48,0x2F,0x00,0xB8]], + [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02,0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16],[0xB8,0x35,0x8E,0x41,0xB9,0xDF,0xF6,0x5F,0xD4,0x61,0xD5,0x5A,0x99,0x26,0x62,0x47],[0x92,0x09,0x7B,0x4C,0x88,0xA0,0x41,0xDD,0xF9,0x81,0x44,0xBC,0x8D,0x22,0xE8,0xE7]], + [[0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20,0x22,0x23,0x24,0x25,0x27,0x28,0x29,0x2A,0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E],[0xF0,0xE2,0xD7,0x22,0x60,0xAF,0x58,0xE2,0x1E,0x01,0x5A,0xB3,0xA4,0xC0,0xD9,0x06],[0x89,0xBD,0x5B,0x73,0xB3,0x56,0xAB,0x41,0x2A,0xEF,0x9F,0x76,0xCE,0xA2,0xD6,0x5C]], + [[0x40,0x41,0x42,0x43,0x45,0x46,0x47,0x48,0x4A,0x4B,0x4C,0x4D,0x4F,0x50,0x51,0x52,0x54,0x55,0x56,0x57,0x59,0x5A,0x5B,0x5C,0x5E,0x5F,0x60,0x61,0x63,0x64,0x65,0x66],[0x47,0x5B,0x8B,0x82,0x3C,0xE8,0x89,0x3D,0xB3,0xC4,0x4A,0x9F,0x2A,0x37,0x9F,0xF7],[0x25,0x36,0x96,0x90,0x93,0xC5,0x5F,0xF9,0x45,0x46,0x92,0xF2,0xFA,0xC2,0xF5,0x30]], + [[0x68,0x69,0x6A,0x6B,0x6D,0x6E,0x6F,0x70,0x72,0x73,0x74,0x75,0x77,0x78,0x79,0x7A,0x7C,0x7D,0x7E,0x7F,0x81,0x82,0x83,0x84,0x86,0x87,0x88,0x89,0x8B,0x8C,0x8D,0x8E],[0x68,0x8F,0x52,0x81,0x94,0x58,0x12,0x86,0x2F,0x5F,0x30,0x76,0xCF,0x80,0x41,0x2F],[0x07,0xFC,0x76,0xA8,0x72,0x84,0x3F,0x3F,0x6E,0x00,0x81,0xEE,0x93,0x96,0xD6,0x37]], + [[0x90,0x91,0x92,0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,0x9D,0x9F,0xA0,0xA1,0xA2,0xA4,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,0xB1,0xB3,0xB4,0xB5,0xB6],[0x08,0xD1,0xD2,0xBC,0x75,0x0A,0xF5,0x53,0x36,0x5D,0x35,0xE7,0x5A,0xFA,0xCE,0xAA],[0xE3,0x8B,0xA8,0xEC,0x2A,0xA7,0x41,0x35,0x8D,0xCC,0x93,0xE8,0xF1,0x41,0xC4,0x91]], + [[0xB8,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC5,0xC7,0xC8,0xC9,0xCA,0xCC,0xCD,0xCE,0xCF,0xD1,0xD2,0xD3,0xD4,0xD6,0xD7,0xD8,0xD9,0xDB,0xDC,0xDD,0xDE],[0x87,0x07,0x12,0x1F,0x47,0xCC,0x3E,0xFC,0xEC,0xA5,0xF9,0xA8,0x47,0x49,0x50,0xA1],[0xD0,0x28,0xEE,0x23,0xE4,0xA8,0x90,0x75,0xD0,0xB0,0x3E,0x86,0x8D,0x7D,0x3A,0x42]], + [[0xE0,0xE1,0xE2,0xE3,0xE5,0xE6,0xE7,0xE8,0xEA,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,0xFC,0xFE,0xFE,0x01,0x01,0x03,0x04,0x05,0x06],[0xE5,0x1A,0xA0,0xB1,0x35,0xDB,0xA5,0x66,0x93,0x9C,0x3B,0x63,0x59,0xA9,0x80,0xC5],[0x8C,0xD9,0x42,0x3D,0xFC,0x45,0x9E,0x54,0x71,0x55,0xC5,0xD1,0xD5,0x22,0xE5,0x40]], + [[0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A,0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E],[0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21],[0x08,0x0E,0x95,0x17,0xEB,0x16,0x77,0x71,0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3]], + [[0x30,0x31,0x32,0x33,0x35,0x36,0x37,0x38,0x3A,0x3B,0x3C,0x3D,0x3F,0x40,0x41,0x42,0x44,0x45,0x46,0x47,0x49,0x4A,0x4B,0x4C,0x4E,0x4F,0x50,0x51,0x53,0x54,0x55,0x56],[0x72,0x61,0x65,0xC1,0x72,0x3F,0xBC,0xF6,0xC0,0x26,0xD7,0xD0,0x0B,0x09,0x10,0x27],[0x7C,0x17,0x00,0x21,0x1A,0x39,0x91,0xFC,0x0E,0xCD,0xED,0x0A,0xB3,0xE5,0x76,0xB0]]]; + + var res = true; + var j = 0; + for (var i = 0; i < testvectors128.length; i++) { + var res2 = test_aes(testvectors128[i][1],testvectors128[i][0],testvectors128[i][2]); + res &= res2; + if (!res2) { + result[j] = new unit.result("Testing 128 bit key vector with block "+ + util.hexidump(testvectors128[i][1])+ + " and key "+util.hexidump(testvectors128[i][0])+ + " should be "+util.hexidump(testvectors128[i][2]), + false); + j++; + } + } + if (res) { + result[j] = new unit.result("128 bit key test vectors completed.",true) + j++; + } + + res = true; + for (var i = 0; i < testvectors192.length; i++) { + var res2 = test_aes(testvectors192[i][1],testvectors192[i][0],testvectors192[i][2]); + res &= res2; + if (!res2) { + result[j] = new unit.result("Testing 192 bit key vector with block "+ + util.hexidump(testvectors192[i][1])+ + " and key "+util.hexidump(testvectors192[i][0])+ + " should be "+util.hexidump(testvectors192[i][2]), + false); + j++; + } + } + if (res) { + result[j] = new unit.result("192 bit key test vectors completed.",true) + j++; + } + + res = true; + for (var i = 0; i < testvectors256.length; i++) { + var res2 = test_aes(testvectors256[i][1],testvectors256[i][0],testvectors256[i][2]); + res &= res2; + if (!res2) { + result[j] = new unit.result("Testing 256 bit key vector with block "+ + util.hexidump(testvectors256[i][1])+ + " and key "+util.hexidump(testvectors256[i][0])+ + " should be "+util.hexidump(testvectors256[i][2]), + false); + j++; + } + } + if (res) { + result[j] = new unit.result("256 bit key test vectors completed.", true) + j++; + } + + return result; +}); + +},{"../../../":26,"../../unit.js":66}],54:[function(require,module,exports){ +var unit = require('../../unit.js'); + +unit.register("Blowfish cipher test with test vectors from http://www.schneier.com/code/vectors.txt", function() { + var openpgp = require('../../../'), + util = openpgp.util, + BFencrypt = openpgp.cipher.blowfish; + + var result = []; + function test_bf(input, key, output) { + var blowfish = new openpgp.cipher.blowfish(util.bin2str(key)); + var result = util.bin2str(blowfish.encrypt(input)); + + return (util.hexstrdump(result) == util.hexstrdump(util.bin2str(output))); + } + var testvectors = [[[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78]], + [[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x51,0x86,0x6F,0xD5,0xB8,0x5E,0xCB,0x8A]], + [[0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01],[0x7D,0x85,0x6F,0x9A,0x61,0x30,0x63,0xF2]], + [[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x24,0x66,0xDD,0x87,0x8B,0x96,0x3C,0x9D]], + [[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x61,0xF9,0xC3,0x80,0x22,0x81,0xB0,0x96]], + [[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x7D,0x0C,0xC6,0x30,0xAF,0xDA,0x1E,0xC7]], + [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78]], + [[0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x0A,0xCE,0xAB,0x0F,0xC6,0xA0,0xA2,0x8D]], + [[0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57],[0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42],[0x59,0xC6,0x82,0x45,0xEB,0x05,0x28,0x2B]], + [[0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E],[0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA],[0xB1,0xB8,0xCC,0x0B,0x25,0x0F,0x09,0xA0]], + [[0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86],[0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72],[0x17,0x30,0xE5,0x77,0x8B,0xEA,0x1D,0xA4]], + [[0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E],[0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A],[0xA2,0x5E,0x78,0x56,0xCF,0x26,0x51,0xEB]], + [[0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6],[0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2],[0x35,0x38,0x82,0xB1,0x09,0xCE,0x8F,0x1A]], + [[0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE],[0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A],[0x48,0xF4,0xD0,0x88,0x4C,0x37,0x99,0x18]], + [[0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6],[0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2],[0x43,0x21,0x93,0xB7,0x89,0x51,0xFC,0x98]], + [[0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE],[0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A],[0x13,0xF0,0x41,0x54,0xD6,0x9D,0x1A,0xE5]], + [[0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16],[0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02],[0x2E,0xED,0xDA,0x93,0xFF,0xD3,0x9C,0x79]], + [[0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F],[0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A],[0xD8,0x87,0xE0,0x39,0x3C,0x2D,0xA6,0xE3]], + [[0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46],[0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32],[0x5F,0x99,0xD0,0x4F,0x5B,0x16,0x39,0x69]], + [[0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E],[0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA],[0x4A,0x05,0x7A,0x3B,0x24,0xD3,0x97,0x7B]], + [[0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76],[0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62],[0x45,0x20,0x31,0xC1,0xE4,0xFA,0xDA,0x8E]], + [[0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07],[0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2],[0x75,0x55,0xAE,0x39,0xF5,0x9B,0x87,0xBD]], + [[0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F],[0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA],[0x53,0xC5,0x5F,0x9C,0xB4,0x9F,0xC0,0x19]], + [[0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7],[0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92],[0x7A,0x8E,0x7B,0xFA,0x93,0x7E,0x89,0xA3]], + [[0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF],[0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A],[0xCF,0x9C,0x5D,0x7A,0x49,0x86,0xAD,0xB5]], + [[0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6],[0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2],[0xD1,0xAB,0xB2,0x90,0x65,0x8B,0xC7,0x78]], + [[0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF],[0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A],[0x55,0xCB,0x37,0x74,0xD1,0x3E,0xF2,0x01]], + [[0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0xFA,0x34,0xEC,0x48,0x47,0xB2,0x68,0xB2]], + [[0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0xA7,0x90,0x79,0x51,0x08,0xEA,0x3C,0xAE]], + [[0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0xC3,0x9E,0x07,0x2D,0x9F,0xAC,0x63,0x1D]], + [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x01,0x49,0x33,0xE0,0xCD,0xAF,0xF6,0xE4]], + [[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0xF2,0x1E,0x9A,0x77,0xB7,0x1C,0x49,0xBC]], + [[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x24,0x59,0x46,0x88,0x57,0x54,0x36,0x9A]], + [[0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10],[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x6B,0x5C,0x5A,0x9C,0x5D,0x9E,0x0A,0x5A]]]; + + var res = true; + var j = 0; + for (var i = 0; i < testvectors.length; i++) { + var res2 = test_bf(testvectors[i][1],testvectors[i][0],testvectors[i][2]); + res &= res2; + if (!res2) { + result[j] = new unit.result("Testing vector "+i+" with block "+ + util.hexidump(testvectors[i][0])+ + " and key "+util.hexidump(testvectors[i][1])+ + " should be "+util.hexidump(testvectors[i][2]), false); + j++; + } + } + if (res) { + result[j] = new unit.result("34 test vectors completed ", true); + } + return result; +}); + +},{"../../../":26,"../../unit.js":66}],55:[function(require,module,exports){ +var unit = require('../../unit.js'); + +unit.register("CAST-128 cipher test with test vectors from RFC2144", function() { + var openpgp = require('../../../'), + util = openpgp.util; + + var result = []; + function test_cast(input, key, output) { + var cast5 = new openpgp.cipher.cast5(util.bin2str(key)); + var result = util.bin2str(cast5.encrypt(input)); + + return util.hexstrdump(result) == util.hexstrdump(util.bin2str(output)); + } + + var testvectors = [[[0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x23,0x8B,0x4F,0xE5,0x84,0x7E,0x44,0xB2]]]; + + for (var i = 0; i < testvectors.length; i++) { + result[i] = new unit.result("Testing vector with block "+ + util.hexidump(testvectors[i][0])+ + " and key "+util.hexidump(testvectors[i][1])+ + " should be "+util.hexidump(testvectors[i][2]), + test_cast(testvectors[i][1],testvectors[i][0],testvectors[i][2])); + } + return result; +}); + +},{"../../../":26,"../../unit.js":66}],56:[function(require,module,exports){ var unit = require('../../unit.js'); unit.register("TripleDES (EDE) cipher test with test vectors from http://csrc.nist.gov/publications/nistpubs/800-20/800-20.pdf", function() { @@ -7507,4753 +12904,7 @@ unit.register("DES encrypt/decrypt padding tests", function () { return result; }); -},{"../../../":28,"../../unit.js":66}],"test-bundle.js":[function(require,module,exports){ -module.exports=require('2ZZCcm'); -},{}],22:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// -// RSA implementation - -var BigInteger = require('./jsbn.js'), - util = require('../../util'), - random = require('../random.js'); - -function SecureRandom(){ - function nextBytes(byteArray){ - for(var n = 0; n < byteArray.length;n++){ - byteArray[n] = random.getSecureRandomOctet(); - } - } - this.nextBytes = nextBytes; -} - -function RSA() { - /** - * This function uses jsbn Big Num library to decrypt RSA - * @param m - * message - * @param d - * RSA d as BigInteger - * @param p - * RSA p as BigInteger - * @param q - * RSA q as BigInteger - * @param u - * RSA u as BigInteger - * @return {BigInteger} The decrypted value of the message - */ - function decrypt(m, d, p, q, u) { - var xp = m.mod(p).modPow(d.mod(p.subtract(BigInteger.ONE)), p); - var xq = m.mod(q).modPow(d.mod(q.subtract(BigInteger.ONE)), q); - util.print_debug("rsa.js decrypt\nxpn:"+util.hexstrdump(xp.toMPI())+"\nxqn:"+util.hexstrdump(xq.toMPI())); - - var t = xq.subtract(xp); - if (t[0] == 0) { - t = xp.subtract(xq); - t = t.multiply(u).mod(q); - t = q.subtract(t); - } else { - t = t.multiply(u).mod(q); - } - return t.multiply(p).add(xp); - } - - /** - * encrypt message - * @param m message as BigInteger - * @param e public MPI part as BigInteger - * @param n public MPI part as BigInteger - * @return BigInteger - */ - function encrypt(m,e,n) { - return m.modPowInt(e, n); - } - - /* Sign and Verify */ - function sign(m,d,n) { - return m.modPow(d, n); - } - - function verify(x,e,n) { - return x.modPowInt(e, n); - } - - // "empty" RSA key constructor - function keyObject() { - this.n = null; - this.e = 0; - this.ee = null; - this.d = null; - this.p = null; - this.q = null; - this.dmp1 = null; - this.dmq1 = null; - this.u = null; - } - - // Generate a new random private key B bits long, using public expt E - function generate(B,E) { - var key = new keyObject(); - var rng = new SecureRandom(); - var qs = B>>1; - key.e = parseInt(E,16); - key.ee = new BigInteger(E,16); - for(;;) { - for(;;) { - key.p = new BigInteger(B-qs,1,rng); - if(key.p.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.p.isProbablePrime(10)) break; - } - for(;;) { - key.q = new BigInteger(qs,1,rng); - if(key.q.subtract(BigInteger.ONE).gcd(key.ee).compareTo(BigInteger.ONE) == 0 && key.q.isProbablePrime(10)) break; - } - if(key.p.compareTo(key.q) <= 0) { - var t = key.p; - key.p = key.q; - key.q = t; - } - var p1 = key.p.subtract(BigInteger.ONE); - var q1 = key.q.subtract(BigInteger.ONE); - var phi = p1.multiply(q1); - if(phi.gcd(key.ee).compareTo(BigInteger.ONE) == 0) { - key.n = key.p.multiply(key.q); - key.d = key.ee.modInverse(phi); - key.dmp1 = key.d.mod(p1); - key.dmq1 = key.d.mod(q1); - key.u = key.p.modInverse(key.q); - break; - } - } - return key; - } - - this.encrypt = encrypt; - this.decrypt = decrypt; - this.verify = verify; - this.sign = sign; - this.generate = generate; - this.keyObject = keyObject; -} - -module.exports = RSA; - -},{"../../util":54,"../random.js":23,"./jsbn.js":19}],23:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -// The GPG4Browsers crypto interface - -var type_mpi = require('../type/mpi.js'); - -module.exports = { - /** - * Retrieve secure random byte string of the specified length - * @param {Integer} length Length in bytes to generate - * @return {String} Random byte string - */ - getRandomBytes: function(length) { - var result = ''; - for (var i = 0; i < length; i++) { - result += String.fromCharCode(this.getSecureRandomOctet()); - } - return result; - }, - - /** - * Return a pseudo-random number in the specified range - * @param {Integer} from Min of the random number - * @param {Integer} to Max of the random number (max 32bit) - * @return {Integer} A pseudo random number - */ - getPseudoRandom: function(from, to) { - return Math.round(Math.random()*(to-from))+from; - }, - - /** - * Return a secure random number in the specified range - * @param {Integer} from Min of the random number - * @param {Integer} to Max of the random number (max 32bit) - * @return {Integer} A secure random number - */ - getSecureRandom: function(from, to) { - var buf = new Uint32Array(1); - window.crypto.getRandomValues(buf); - var bits = ((to-from)).toString(2).length; - while ((buf[0] & (Math.pow(2, bits) -1)) > (to-from)) - window.crypto.getRandomValues(buf); - return from+(Math.abs(buf[0] & (Math.pow(2, bits) -1))); - }, - - getSecureRandomOctet: function() { - var buf = new Uint32Array(1); - window.crypto.getRandomValues(buf); - return buf[0] & 0xFF; - }, - - /** - * Create a secure random big integer of bits length - * @param {Integer} bits Bit length of the MPI to create - * @return {BigInteger} Resulting big integer - */ - getRandomBigInteger: function(bits) { - if (bits < 0) { - return null; - } - var numBytes = Math.floor((bits+7)/8); - - var randomBits = this.getRandomBytes(numBytes); - if (bits % 8 > 0) { - - randomBits = String.fromCharCode( - (Math.pow(2,bits % 8)-1) & - randomBits.charCodeAt(0)) + - randomBits.substring(1); - } - var mpi = new type_mpi(); - mpi.fromBytes(randomBits); - return mpi.toBigInteger(); - }, - - getRandomBigIntegerInRange: function(min, max) { - if (max.compareTo(min) <= 0) { - return; - } - - var range = max.subtract(min); - var r = this.getRandomBigInteger(range.bitLength()); - while (r > range) { - r = this.getRandomBigInteger(range.bitLength()); - } - return min.add(r); - } - -}; - -},{"../type/mpi.js":52}],24:[function(require,module,exports){ - -var publicKey = require('./public_key'), - pkcs1 = require('./pkcs1.js'), - hashModule = require('./hash'); - -module.exports = { - /** - * - * @param {Integer} algo public Key algorithm - * @param {Integer} hash_algo Hash algorithm - * @param {openpgp_type_mpi[]} msg_MPIs Signature multiprecision integers - * @param {openpgp_type_mpi[]} publickey_MPIs Public key multiprecision integers - * @param {String} data Data on where the signature was computed on. - * @return {Boolean} true if signature (sig_data was equal to data over hash) - */ - verify: function(algo, hash_algo, msg_MPIs, publickey_MPIs, data) { - var calc_hash = hashModule.digest(hash_algo, data); - - switch(algo) { - case 1: // RSA (Encrypt or Sign) [HAC] - case 2: // RSA Encrypt-Only [HAC] - case 3: // RSA Sign-Only [HAC] - var rsa = new publicKey.rsa(); - var n = publickey_MPIs[0].toBigInteger(); - var e = publickey_MPIs[1].toBigInteger(); - var x = msg_MPIs[0].toBigInteger(); - var dopublic = rsa.verify(x,e,n); - var hash = pkcs1.emsa.decode(hash_algo,dopublic.toMPI().substring(2)); - if (hash == -1) { - throw new Error('PKCS1 padding in message or key incorrect. Aborting...'); - } - return hash == calc_hash; - - case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - throw new Error("signing with Elgamal is not defined in the OpenPGP standard."); - case 17: // DSA (Digital Signature Algorithm) [FIPS186] [HAC] - var dsa = new publicKey.dsa(); - var s1 = msg_MPIs[0].toBigInteger(); - var s2 = msg_MPIs[1].toBigInteger(); - var p = publickey_MPIs[0].toBigInteger(); - var q = publickey_MPIs[1].toBigInteger(); - var g = publickey_MPIs[2].toBigInteger(); - var y = publickey_MPIs[3].toBigInteger(); - var m = data; - var dopublic = dsa.verify(hash_algo,s1,s2,m,p,q,g,y); - return dopublic.compareTo(s1) == 0; - default: - throw new Error('Invalid signature algorithm.'); - } - - }, - - /** - * Create a signature on data using the specified algorithm - * @param {Integer} hash_algo hash Algorithm to use (See RFC4880 9.4) - * @param {Integer} algo Asymmetric cipher algorithm to use (See RFC4880 9.1) - * @param {openpgp_type_mpi[]} publicMPIs Public key multiprecision integers - * of the private key - * @param {openpgp_type_mpi[]} secretMPIs Private key multiprecision - * integers which is used to sign the data - * @param {String} data Data to be signed - * @return {openpgp_type_mpi[]} - */ - sign: function(hash_algo, algo, keyIntegers, data) { - - switch(algo) { - case 1: // RSA (Encrypt or Sign) [HAC] - case 2: // RSA Encrypt-Only [HAC] - case 3: // RSA Sign-Only [HAC] - var rsa = new publicKey.rsa(); - var d = keyIntegers[2].toBigInteger(); - var n = keyIntegers[0].toBigInteger(); - var m = pkcs1.emsa.encode(hash_algo, - data, keyIntegers[0].byteLength()); - - return rsa.sign(m, d, n).toMPI(); - - case 17: // DSA (Digital Signature Algorithm) [FIPS186] [HAC] - var dsa = new publicKey.dsa(); - - var p = keyIntegers[0].toBigInteger(); - var q = keyIntegers[1].toBigInteger(); - var g = keyIntegers[2].toBigInteger(); - var y = keyIntegers[3].toBigInteger(); - var x = keyIntegers[4].toBigInteger(); - var m = data; - var result = dsa.sign(hash_algo,m, g, p, q, x); - - return result[0].toString() + result[1].toString(); - case 16: // Elgamal (Encrypt-Only) [ELGAMAL] [HAC] - throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.'); - default: - throw new Error('Invalid signature algorithm.'); - } - } -} - -},{"./hash":10,"./pkcs1.js":15,"./public_key":18}],25:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var base64 = require('./base64.js'); - - - -/** - * Finds out which Ascii Armoring type is used. This is an internal function - * @param {String} text [String] ascii armored text - * @returns {Integer} 0 = MESSAGE PART n of m - * 1 = MESSAGE PART n - * 2 = SIGNED MESSAGE - * 3 = PGP MESSAGE - * 4 = PUBLIC KEY BLOCK - * 5 = PRIVATE KEY BLOCK - * null = unknown - */ -function get_type(text) { - var splittedtext = text.split('-----'); - // BEGIN PGP MESSAGE, PART X/Y - // Used for multi-part messages, where the armor is split amongst Y - // parts, and this is the Xth part out of Y. - if (splittedtext[1].match(/BEGIN PGP MESSAGE, PART \d+\/\d+/)) { - return 0; - } else - // BEGIN PGP MESSAGE, PART X - // Used for multi-part messages, where this is the Xth part of an - // unspecified number of parts. Requires the MESSAGE-ID Armor - // Header to be used. - if (splittedtext[1].match(/BEGIN PGP MESSAGE, PART \d+/)) { - return 1; - - } else - // BEGIN PGP SIGNATURE - // Used for detached signatures, OpenPGP/MIME signatures, and - // cleartext signatures. Note that PGP 2.x uses BEGIN PGP MESSAGE - // for detached signatures. - if (splittedtext[1].match(/BEGIN PGP SIGNED MESSAGE/)) { - return 2; - - } else - // BEGIN PGP MESSAGE - // Used for signed, encrypted, or compressed files. - if (splittedtext[1].match(/BEGIN PGP MESSAGE/)) { - return 3; - - } else - // BEGIN PGP PUBLIC KEY BLOCK - // Used for armoring public keys. - if (splittedtext[1].match(/BEGIN PGP PUBLIC KEY BLOCK/)) { - return 4; - - } else - // BEGIN PGP PRIVATE KEY BLOCK - // Used for armoring private keys. - if (splittedtext[1].match(/BEGIN PGP PRIVATE KEY BLOCK/)) { - return 5; - } -} - -/** - * Add additional information to the armor version of an OpenPGP binary - * packet block. - * @author Alex - * @version 2011-12-16 - * @returns {String} The header information - */ -function armor_addheader() { - var result = ""; - if (openpgp.config.config.show_version) { - result += "Version: "+openpgp.config.versionstring+'\r\n'; - } - if (openpgp.config.config.show_comment) { - result += "Comment: "+openpgp.config.commentstring+'\r\n'; - } - result += '\r\n'; - return result; -} - - - -/** - * Calculates a checksum over the given data and returns it base64 encoded - * @param {String} data Data to create a CRC-24 checksum for - * @return {String} Base64 encoded checksum - */ -function getCheckSum(data) { - var c = createcrc24(data); - var str = "" + String.fromCharCode(c >> 16)+ - String.fromCharCode((c >> 8) & 0xFF)+ - String.fromCharCode(c & 0xFF); - return base64.encode(str); -} - -/** - * Calculates the checksum over the given data and compares it with the - * given base64 encoded checksum - * @param {String} data Data to create a CRC-24 checksum for - * @param {String} checksum Base64 encoded checksum - * @return {Boolean} True if the given checksum is correct; otherwise false - */ -function verifyCheckSum(data, checksum) { - var c = getCheckSum(data); - var d = checksum; - return c[0] == d[0] && c[1] == d[1] && c[2] == d[2]; -} -/** - * Internal function to calculate a CRC-24 checksum over a given string (data) - * @param {String} data Data to create a CRC-24 checksum for - * @return {Integer} The CRC-24 checksum as number - */ -var crc_table = [ -0x00000000, 0x00864cfb, 0x018ad50d, 0x010c99f6, 0x0393e6e1, 0x0315aa1a, 0x021933ec, 0x029f7f17, 0x07a18139, 0x0727cdc2, 0x062b5434, 0x06ad18cf, 0x043267d8, 0x04b42b23, 0x05b8b2d5, 0x053efe2e, 0x0fc54e89, 0x0f430272, 0x0e4f9b84, 0x0ec9d77f, 0x0c56a868, 0x0cd0e493, 0x0ddc7d65, 0x0d5a319e, 0x0864cfb0, 0x08e2834b, 0x09ee1abd, 0x09685646, 0x0bf72951, 0x0b7165aa, 0x0a7dfc5c, 0x0afbb0a7, 0x1f0cd1e9, 0x1f8a9d12, 0x1e8604e4, 0x1e00481f, 0x1c9f3708, 0x1c197bf3, 0x1d15e205, 0x1d93aefe, 0x18ad50d0, 0x182b1c2b, 0x192785dd, 0x19a1c926, 0x1b3eb631, 0x1bb8faca, 0x1ab4633c, 0x1a322fc7, 0x10c99f60, 0x104fd39b, 0x11434a6d, 0x11c50696, 0x135a7981, 0x13dc357a, 0x12d0ac8c, 0x1256e077, 0x17681e59, 0x17ee52a2, 0x16e2cb54, 0x166487af, 0x14fbf8b8, 0x147db443, 0x15712db5, 0x15f7614e, 0x3e19a3d2, 0x3e9fef29, 0x3f9376df, 0x3f153a24, 0x3d8a4533, 0x3d0c09c8, 0x3c00903e, 0x3c86dcc5, 0x39b822eb, 0x393e6e10, 0x3832f7e6, 0x38b4bb1d, 0x3a2bc40a, 0x3aad88f1, 0x3ba11107, 0x3b275dfc, 0x31dced5b, 0x315aa1a0, -0x30563856, 0x30d074ad, 0x324f0bba, 0x32c94741, 0x33c5deb7, 0x3343924c, 0x367d6c62, 0x36fb2099, 0x37f7b96f, 0x3771f594, 0x35ee8a83, 0x3568c678, 0x34645f8e, 0x34e21375, 0x2115723b, 0x21933ec0, 0x209fa736, 0x2019ebcd, 0x228694da, 0x2200d821, 0x230c41d7, 0x238a0d2c, 0x26b4f302, 0x2632bff9, 0x273e260f, 0x27b86af4, 0x252715e3, 0x25a15918, 0x24adc0ee, 0x242b8c15, 0x2ed03cb2, 0x2e567049, 0x2f5ae9bf, 0x2fdca544, 0x2d43da53, 0x2dc596a8, 0x2cc90f5e, 0x2c4f43a5, 0x2971bd8b, 0x29f7f170, 0x28fb6886, 0x287d247d, 0x2ae25b6a, 0x2a641791, 0x2b688e67, 0x2beec29c, 0x7c3347a4, 0x7cb50b5f, 0x7db992a9, 0x7d3fde52, 0x7fa0a145, 0x7f26edbe, 0x7e2a7448, 0x7eac38b3, 0x7b92c69d, 0x7b148a66, 0x7a181390, 0x7a9e5f6b, 0x7801207c, 0x78876c87, 0x798bf571, 0x790db98a, 0x73f6092d, 0x737045d6, 0x727cdc20, 0x72fa90db, 0x7065efcc, 0x70e3a337, 0x71ef3ac1, 0x7169763a, 0x74578814, 0x74d1c4ef, 0x75dd5d19, 0x755b11e2, 0x77c46ef5, 0x7742220e, 0x764ebbf8, 0x76c8f703, 0x633f964d, 0x63b9dab6, 0x62b54340, 0x62330fbb, -0x60ac70ac, 0x602a3c57, 0x6126a5a1, 0x61a0e95a, 0x649e1774, 0x64185b8f, 0x6514c279, 0x65928e82, 0x670df195, 0x678bbd6e, 0x66872498, 0x66016863, 0x6cfad8c4, 0x6c7c943f, 0x6d700dc9, 0x6df64132, 0x6f693e25, 0x6fef72de, 0x6ee3eb28, 0x6e65a7d3, 0x6b5b59fd, 0x6bdd1506, 0x6ad18cf0, 0x6a57c00b, 0x68c8bf1c, 0x684ef3e7, 0x69426a11, 0x69c426ea, 0x422ae476, 0x42aca88d, 0x43a0317b, 0x43267d80, 0x41b90297, 0x413f4e6c, 0x4033d79a, 0x40b59b61, 0x458b654f, 0x450d29b4, 0x4401b042, 0x4487fcb9, 0x461883ae, 0x469ecf55, 0x479256a3, 0x47141a58, 0x4defaaff, 0x4d69e604, 0x4c657ff2, 0x4ce33309, 0x4e7c4c1e, 0x4efa00e5, 0x4ff69913, 0x4f70d5e8, 0x4a4e2bc6, 0x4ac8673d, 0x4bc4fecb, 0x4b42b230, 0x49ddcd27, 0x495b81dc, 0x4857182a, 0x48d154d1, 0x5d26359f, 0x5da07964, 0x5cace092, 0x5c2aac69, 0x5eb5d37e, 0x5e339f85, 0x5f3f0673, 0x5fb94a88, 0x5a87b4a6, 0x5a01f85d, 0x5b0d61ab, 0x5b8b2d50, 0x59145247, 0x59921ebc, 0x589e874a, 0x5818cbb1, 0x52e37b16, 0x526537ed, 0x5369ae1b, 0x53efe2e0, 0x51709df7, 0x51f6d10c, -0x50fa48fa, 0x507c0401, 0x5542fa2f, 0x55c4b6d4, 0x54c82f22, 0x544e63d9, 0x56d11cce, 0x56575035, 0x575bc9c3, 0x57dd8538]; - -function createcrc24(input) { - var crc = 0xB704CE; - var index = 0; - - while((input.length - index) > 16) { - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+1)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+2)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+3)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+4)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+5)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+6)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+7)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+8)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+9)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+10)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+11)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+12)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+13)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+14)) & 0xff]; - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index+15)) & 0xff]; - index += 16; - } - - for(var j = index; j < input.length; j++) { - crc = (crc << 8) ^ crc_table[((crc >> 16) ^ input.charCodeAt(index++)) & 0xff] - } - return crc & 0xffffff; -} - -/** - * DeArmor an OpenPGP armored message; verify the checksum and return - * the encoded bytes - * @param {String} text OpenPGP armored message - * @returns {(Boolean|Object)} Either false in case of an error - * or an object with attribute "text" containing the message text - * and an attribute "openpgp" containing the bytes. - */ -function dearmor(text) { - text = text.replace(/\r/g, '') - - var type = get_type(text); - - if (type != 2) { - var splittedtext = text.split('-----'); - - var data = { - openpgp: base64.decode( - splittedtext[2] - .split('\n\n')[1] - .split("\n=")[0] - .replace(/\n- /g,"\n")), - type: type - }; - - if (verifyCheckSum(data.openpgp, - splittedtext[2] - .split('\n\n')[1] - .split("\n=")[1] - .split('\n')[0])) - - return data; - else { - util.print_error("Ascii armor integrity check on message failed: '" - + splittedtext[2] - .split('\n\n')[1] - .split("\n=")[1] - .split('\n')[0] - + "' should be '" - + getCheckSum(data)) + "'"; - return false; - } - } else { - var splittedtext = text.split('-----'); - - var result = { - text: splittedtext[2] - .replace(/\n- /g,"\n") - .split("\n\n")[1], - openpgp: base64_decode(splittedtext[4] - .split("\n\n")[1] - .split("\n=")[0]), - type: type - }; - - if (verifyCheckSum(result.openpgp, splittedtext[4] - .split("\n\n")[1] - .split("\n=")[1])) - - return result; - else { - util.print_error("Ascii armor integrity check on message failed"); - return false; - } - } -} - - -/** - * Armor an OpenPGP binary packet block - * @param {Integer} messagetype type of the message - * @param data - * @param {Integer} partindex - * @param {Integer} parttotal - * @returns {String} Armored text - */ -function armor(messagetype, data, partindex, parttotal) { - var result = ""; - switch(messagetype) { - case 0: - result += "-----BEGIN PGP MESSAGE, PART "+partindex+"/"+parttotal+"-----\r\n"; - result += armor_addheader(); - result += base64.encode(data); - result += "\r\n="+getCheckSum(data)+"\r\n"; - result += "-----END PGP MESSAGE, PART "+partindex+"/"+parttotal+"-----\r\n"; - break; - case 1: - result += "-----BEGIN PGP MESSAGE, PART "+partindex+"-----\r\n"; - result += armor_addheader(); - result += base64.encode(data); - result += "\r\n="+getCheckSum(data)+"\r\n"; - result += "-----END PGP MESSAGE, PART "+partindex+"-----\r\n"; - break; - case 2: - result += "\r\n-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: "+data.hash+"\r\n\r\n"; - result += data.text.replace(/\n-/g,"\n- -"); - result += "\r\n-----BEGIN PGP SIGNATURE-----\r\n"; - result += armor_addheader(); - result += base64.encode(data.openpgp); - result += "\r\n="+getCheckSum(data.openpgp)+"\r\n"; - result += "-----END PGP SIGNATURE-----\r\n"; - break; - case 3: - result += "-----BEGIN PGP MESSAGE-----\r\n"; - result += armor_addheader(); - result += base64.encode(data); - result += "\r\n="+getCheckSum(data)+"\r\n"; - result += "-----END PGP MESSAGE-----\r\n"; - break; - case 4: - result += "-----BEGIN PGP PUBLIC KEY BLOCK-----\r\n"; - result += armor_addheader(); - result += base64.encode(data); - result += "\r\n="+getCheckSum(data)+"\r\n"; - result += "-----END PGP PUBLIC KEY BLOCK-----\r\n\r\n"; - break; - case 5: - result += "-----BEGIN PGP PRIVATE KEY BLOCK-----\r\n"; - result += armor_addheader(); - result += base64.encode(data); - result += "\r\n="+getCheckSum(data)+"\r\n"; - result += "-----END PGP PRIVATE KEY BLOCK-----\r\n"; - break; - } - - return result; -} - -module.exports = { - encode: armor, - decode: dearmor -} - -},{"./base64.js":26}],26:[function(require,module,exports){ -/* OpenPGP radix-64/base64 string encoding/decoding - * Copyright 2005 Herbert Hanewinkel, www.haneWIN.de - * version 1.0, check www.haneWIN.de for the latest version - * - * This software is provided as-is, without express or implied warranty. - * Permission to use, copy, modify, distribute or sell this software, with or - * without fee, for any purpose and by any individual or organization, is hereby - * granted, provided that the above copyright notice and this paragraph appear - * in all copies. Distribution as a part of an application or binary must - * include the above copyright notice in the documentation and/or other materials - * provided with the application or distribution. - */ - -var b64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - -function s2r(t) { - var a, c, n; - var r = '', l = 0, s = 0; - var tl = t.length; - - for (n = 0; n < tl; n++) { - c = t.charCodeAt(n); - if (s == 0) { - r += b64s.charAt((c >> 2) & 63); - a = (c & 3) << 4; - } else if (s == 1) { - r += b64s.charAt((a | (c >> 4) & 15)); - a = (c & 15) << 2; - } else if (s == 2) { - r += b64s.charAt(a | ((c >> 6) & 3)); - l += 1; - if ((l % 60) == 0) - r += "\n"; - r += b64s.charAt(c & 63); - } - l += 1; - if ((l % 60) == 0) - r += "\n"; - - s += 1; - if (s == 3) - s = 0; - } - if (s > 0) { - r += b64s.charAt(a); - l += 1; - if ((l % 60) == 0) - r += "\n"; - r += '='; - l += 1; - } - if (s == 1) { - if ((l % 60) == 0) - r += "\n"; - r += '='; - } - - return r; -} - -function r2s(t) { - var c, n; - var r = '', s = 0, a = 0; - var tl = t.length; - - for (n = 0; n < tl; n++) { - c = b64s.indexOf(t.charAt(n)); - if (c >= 0) { - if (s) - r += String.fromCharCode(a | (c >> (6 - s)) & 255); - s = (s + 2) & 7; - a = (c << s) & 255; - } - } - return r; -} - -module.exports = { - encode: s2r, - decode: r2s -} - -},{}],27:[function(require,module,exports){ -var enums = { - - /** A string to key specifier type - * @enum {Integer} - */ - s2k: { - simple: 0, - salted: 1, - iterated: 3, - gnu: 101 - }, - - /** RFC4880, section 9.1 - * @enum {String} - */ - publicKey: { - rsa_encrypt_sign: 1, - rsa_encrypt: 2, - rsa_sign: 3, - elgamal: 16, - dsa: 17 - }, - - /** RFC4880, section 9.2 - * @enum {String} - */ - symmetric: { - plaintext: 0, - /** Not implemented! */ - idea: 1, - tripledes: 2, - cast5: 3, - blowfish: 4, - aes128: 7, - aes192: 8, - aes256: 9, - twofish: 10 - }, - - /** RFC4880, section 9.3 - * @enum {String} - */ - compression: { - uncompressed: 0, - /** RFC1951 */ - zip: 1, - /** RFC1950 */ - zlib: 2, - bzip2: 3 - }, - - /** RFC4880, section 9.4 - * @enum {String} - */ - hash: { - md5: 1, - sha1: 2, - ripemd: 3, - sha256: 8, - sha384: 9, - sha512: 10, - sha224: 11 - }, - - - /** - * @enum {String} - * A list of packet types and numeric tags associated with them. - */ - packet: { - public_key_encrypted_session_key: 1, - signature: 2, - sym_encrypted_session_key: 3, - one_pass_signature: 4, - secret_key: 5, - public_key: 6, - secret_subkey: 7, - compressed: 8, - symmetrically_encrypted: 9, - marker: 10, - literal: 11, - trust: 12, - userid: 13, - public_subkey: 14, - user_attribute: 17, - sym_encrypted_integrity_protected: 18, - modification_detection_code: 19 - }, - - - /** - * Data types in the literal packet - * @readonly - * @enum {String} - */ - literal: { - /** Binary data */ - binary: 'b'.charCodeAt(), - /** Text data */ - text: 't'.charCodeAt(), - /** Utf8 data */ - utf8: 'u'.charCodeAt() - }, - - - /** One pass signature packet type - * @enum {String} */ - signature: { - /** 0x00: Signature of a binary document. */ - binary: 0, - /** 0x01: Signature of a canonical text document. - * Canonicalyzing the document by converting line endings. */ - text: 1, - /** 0x02: Standalone signature. - * This signature is a signature of only its own subpacket contents. - * It is calculated identically to a signature over a zero-lengh - * binary document. Note that it doesn't make sense to have a V3 - * standalone signature. */ - standalone: 2, - /** 0x10: Generic certification of a User ID and Public-Key packet. - * The issuer of this certification does not make any particular - * assertion as to how well the certifier has checked that the owner - * of the key is in fact the person described by the User ID. */ - cert_generic: 16, - /** 0x11: Persona certification of a User ID and Public-Key packet. - * The issuer of this certification has not done any verification of - * the claim that the owner of this key is the User ID specified. */ - cert_persona: 17, - /** 0x12: Casual certification of a User ID and Public-Key packet. - * The issuer of this certification has done some casual - * verification of the claim of identity. */ - cert_casual: 18, - /** 0x13: Positive certification of a User ID and Public-Key packet. - * The issuer of this certification has done substantial - * verification of the claim of identity. - * - * Most OpenPGP implementations make their "key signatures" as 0x10 - * certifications. Some implementations can issue 0x11-0x13 - * certifications, but few differentiate between the types. */ - cert_positive: 19, - /** 0x30: Certification revocation signature - * This signature revokes an earlier User ID certification signature - * (signature class 0x10 through 0x13) or direct-key signature - * (0x1F). It should be issued by the same key that issued the - * revoked signature or an authorized revocation key. The signature - * is computed over the same data as the certificate that it - * revokes, and should have a later creation date than that - * certificate. */ - cert_revocation: 48, - /** 0x18: Subkey Binding Signature - * This signature is a statement by the top-level signing key that - * indicates that it owns the subkey. This signature is calculated - * directly on the primary key and subkey, and not on any User ID or - * other packets. A signature that binds a signing subkey MUST have - * an Embedded Signature subpacket in this binding signature that - * contains a 0x19 signature made by the signing subkey on the - * primary key and subkey. */ - subkey_binding: 24, - /** 0x19: Primary Key Binding Signature - * This signature is a statement by a signing subkey, indicating - * that it is owned by the primary key and subkey. This signature - * is calculated the same way as a 0x18 signature: directly on the - * primary key and subkey, and not on any User ID or other packets. - - * When a signature is made over a key, the hash data starts with the - * octet 0x99, followed by a two-octet length of the key, and then body - * of the key packet. (Note that this is an old-style packet header for - * a key packet with two-octet length.) A subkey binding signature - * (type 0x18) or primary key binding signature (type 0x19) then hashes - * the subkey using the same format as the main key (also using 0x99 as - * the first octet). */ - key_binding: 25, - /** 0x1F: Signature directly on a key - * This signature is calculated directly on a key. It binds the - * information in the Signature subpackets to the key, and is - * appropriate to be used for subpackets that provide information - * about the key, such as the Revocation Key subpacket. It is also - * appropriate for statements that non-self certifiers want to make - * about the key itself, rather than the binding between a key and a - * name. */ - key: 31, - /** 0x20: Key revocation signature - * The signature is calculated directly on the key being revoked. A - * revoked key is not to be used. Only revocation signatures by the - * key being revoked, or by an authorized revocation key, should be - * considered valid revocation signatures.a */ - key_revocation: 32, - /** 0x28: Subkey revocation signature - * The signature is calculated directly on the subkey being revoked. - * A revoked subkey is not to be used. Only revocation signatures - * by the top-level signature key that is bound to this subkey, or - * by an authorized revocation key, should be considered valid - * revocation signatures. - * Key revocation signatures (types 0x20 and 0x28) - * hash only the key being revoked. */ - subkey_revocation: 40, - /** 0x40: Timestamp signature. - * This signature is only meaningful for the timestamp contained in - * it. */ - timestamp: 64, - /** 0x50: Third-Party Confirmation signature. - * This signature is a signature over some other OpenPGP Signature - * packet(s). It is analogous to a notary seal on the signed data. - * A third-party signature SHOULD include Signature Target - * subpacket(s) to give easy identification. Note that we really do - * mean SHOULD. There are plausible uses for this (such as a blind - * party that only sees the signature, not the key or source - * document) that cannot include a target subpacket. */ - third_party: 80 - }, - - // Asserts validity and converts from string/integer to integer. - write: function(type, e) { - if(typeof e == 'number') { - e = this.read(type, e); - } - - if(type[e] != undefined) { - return type[e]; - } else throw new Error('Invalid enum value.'); - }, - // Converts from an integer to string. - read: function(type, e) { - for(var i in type) - if(type[i] == e) return i; - - throw new Error('Invalid enum value.'); - } -} - -module.exports = enums; - -},{}],28:[function(require,module,exports){ -var crypto = require('./crypto'); - -module.exports = require('./openpgp.js'); -module.exports.util = require('./util'); -module.exports.packet = require('./packet'); -module.exports.mpi = require('./type/mpi.js'); -module.exports.s2k = require('./type/s2k.js'); -module.exports.keyid = require('./type/keyid.js'); -module.exports.armor = require('./encoding/armor.js'); -module.exports.enums = require('./enums.js'); - -for(var i in crypto) - module.exports[i] = crypto[i]; - - -},{"./crypto":14,"./encoding/armor.js":25,"./enums.js":27,"./openpgp.js":29,"./packet":33,"./type/keyid.js":51,"./type/mpi.js":52,"./type/s2k.js":53,"./util":54}],29:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @fileoverview The openpgp base class should provide all of the functionality - * to consume the openpgp.js library. All additional classes are documented - * for extending and developing on top of the base library. - */ - -var armor = require('./encoding/armor.js'); -var packet = require('./packet'); -var util = require('./util'); - -/** - * GPG4Browsers Core interface. A single instance is hold - * from the beginning. To use this library call "openpgp.init()" - * @alias openpgp - * @class - * @classdesc Main Openpgp.js class. Use this to initiate and make all calls to this library. - */ -function _openpgp () { - this.tostring = ""; - - /** - * initializes the library: - * - reading the keyring from local storage - * - reading the config from local storage - */ - function init() { - this.config = new openpgp_config(); - this.config.read(); - this.keyring = new openpgp_keyring(); - this.keyring.init(); - } - - /** - * reads message packets out of an OpenPGP armored text and - * returns an array of message objects - * @param {String} armoredText text to be parsed - * @return {openpgp_msg_message[]} on error the function - * returns null - */ - function readArmoredPackets(armoredText) { - //TODO how do we want to handle bad text? Exception throwing - var input = armor.decode(armoredText.replace(/\r/g,'')).openpgp; - return readDearmoredPackets(input); - } - - /** - * reads message packets out of an OpenPGP armored text and - * returns an array of message objects. Can be called externally or internally. - * External call will parse a de-armored messaged and return messages found. - * Internal will be called to read packets wrapped in other packets (i.e. compressed) - * @param {String} input dearmored text of OpenPGP packets, to be parsed - * @return {openpgp_msg_message[]} on error the function - * returns null - */ - function readDearmoredPackets(input){ - var packetList = new packet.list(); - packetList.read(input); - return packetList; - } - - function encryptMessage(publicKeyPacketlist, message) { - - } - - function encryptAndSignMessage(publicKeyPacketlist, privateKeyPacketlist, message) { - - } - - function decryptMessage(privateKeyPacketlist, messagePacketlist) { - - } - - function decryptAndVerifyMessage(privateKeyPacketlist, publicKeyPacketlist, messagePacketlist) { - - } - - function verifyMessage(publicKeyPacketlist, messagePacketlist) { - - } - - function signMessage(privateKeyPacketlist, messagePacketlist) { - - } - - function generateKeyPair(keyType, numBits, userId, passphrase) { - debugger; - var packetlist = new packet.list(); - - var secretKeyPacket = new packet.secret_key(); - var userIdPacket = new packet.userid(); - var signaturePacket = new packet.signature(); - var secretSubkeyPacket = new packet.secret_subkey(); - var overallSignaturePacket = new packet.signature(); - - } - - /** - * creates a binary string representation of an encrypted and signed message. - * The message will be encrypted with the public keys specified and signed - * with the specified private key. - * @param {Object} privatekey {obj: [openpgp_msg_privatekey]} Private key - * to be used to sign the message - * @param {Object[]} publickeys An arraf of {obj: [openpgp_msg_publickey]} - * - public keys to be used to encrypt the message - * @param {String} messagetext message text to encrypt and sign - * @return {String} a binary string representation of the message which - * can be OpenPGP armored - */ - function write_signed_and_encrypted_message(privatekey, publickeys, messagetext) { - var result = ""; - var i; - var literal = new openpgp_packet_literaldata().write_packet(messagetext.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n")); - util.print_debug_hexstr_dump("literal_packet: |"+literal+"|\n",literal); - for (i = 0; i < publickeys.length; i++) { - var onepasssignature = new openpgp_packet_onepasssignature(); - var onepasssigstr = ""; - if (i === 0) - onepasssigstr = onepasssignature.write_packet(1, openpgp.config.config.prefer_hash_algorithm, privatekey, false); - else - onepasssigstr = onepasssignature.write_packet(1, openpgp.config.config.prefer_hash_algorithm, privatekey, false); - util.print_debug_hexstr_dump("onepasssigstr: |"+onepasssigstr+"|\n",onepasssigstr); - var datasignature = new openpgp_packet_signature().write_message_signature(1, messagetext.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"), privatekey); - util.print_debug_hexstr_dump("datasignature: |"+datasignature.openpgp+"|\n",datasignature.openpgp); - if (i === 0) { - result = onepasssigstr+literal+datasignature.openpgp; - } else { - result = onepasssigstr+result+datasignature.openpgp; - } - } - - util.print_debug_hexstr_dump("signed packet: |"+result+"|\n",result); - // signatures done.. now encryption - var sessionkey = openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher); - var result2 = ""; - - // creating session keys for each recipient - for (i = 0; i < publickeys.length; i++) { - var pkey = publickeys[i].getEncryptionKey(); - if (pkey === null) { - util.print_error("no encryption key found! Key is for signing only."); - return null; - } - result2 += new openpgp_packet_encryptedsessionkey(). - write_pub_key_packet( - pkey.getKeyId(), - pkey.MPIs, - pkey.publicKeyAlgorithm, - openpgp.config.config.encryption_cipher, - sessionkey); - } - if (openpgp.config.config.integrity_protect) { - result2 += new openpgp_packet_encryptedintegrityprotecteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); - } else { - result2 += new openpgp_packet_encrypteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); - } - return armor.encode(3,result2,null,null); - } - /** - * creates a binary string representation of an encrypted message. - * The message will be encrypted with the public keys specified - * @param {Object[]} publickeys An array of {obj: [openpgp_msg_publickey]} - * -public keys to be used to encrypt the message - * @param {String} messagetext message text to encrypt - * @return {String} a binary string representation of the message - * which can be OpenPGP armored - */ - function write_encrypted_message(publickeys, messagetext) { - var result = ""; - var literal = new openpgp_packet_literaldata().write_packet(messagetext.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n")); - util.print_debug_hexstr_dump("literal_packet: |"+literal+"|\n",literal); - result = literal; - - // signatures done.. now encryption - var sessionkey = openpgp_crypto_generateSessionKey(openpgp.config.config.encryption_cipher); - var result2 = ""; - - // creating session keys for each recipient - for (var i = 0; i < publickeys.length; i++) { - var pkey = publickeys[i].getEncryptionKey(); - if (pkey === null) { - util.print_error("no encryption key found! Key is for signing only."); - return null; - } - result2 += new openpgp_packet_encryptedsessionkey(). - write_pub_key_packet( - pkey.getKeyId(), - pkey.MPIs, - pkey.publicKeyAlgorithm, - openpgp.config.config.encryption_cipher, - sessionkey); - } - if (openpgp.config.config.integrity_protect) { - result2 += new openpgp_packet_encryptedintegrityprotecteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); - } else { - result2 += new openpgp_packet_encrypteddata().write_packet(openpgp.config.config.encryption_cipher, sessionkey, result); - } - return armor.encode(3,result2,null,null); - } - - /** - * creates a binary string representation a signed message. - * The message will be signed with the specified private key. - * @param {Object} privatekey {obj: [openpgp_msg_privatekey]} - * - the private key to be used to sign the message - * @param {String} messagetext message text to sign - * @return {Object} {Object: text [String]}, openpgp: {String} a binary - * string representation of the message which can be OpenPGP - * armored(openpgp) and a text representation of the message (text). - * This can be directly used to OpenPGP armor the message - */ - function write_signed_message(privatekey, messagetext) { - var sig = new openpgp_packet_signature().write_message_signature(1, messagetext.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"), privatekey); - var result = {text: messagetext.replace(/\r\n/g,"\n").replace(/\n/,"\r\n"), openpgp: sig.openpgp, hash: sig.hash}; - return armor.encode(2,result, null, null); - } - - /** - * generates a new key pair for openpgp. Beta stage. Currently only - * supports RSA keys, and no subkeys. - * @param {Integer} keyType to indicate what type of key to make. - * RSA is 1. Follows algorithms outlined in OpenPGP. - * @param {Integer} numBits number of bits for the key creation. (should - * be 1024+, generally) - * @param {String} userId assumes already in form of "User Name - * " - * @param {String} passphrase The passphrase used to encrypt the resulting private key - * @return {Object} {privateKey: [openpgp_msg_privatekey], - * privateKeyArmored: [string], publicKeyArmored: [string]} - */ - function generate_key_pair(keyType, numBits, userId, passphrase){ - var userIdPacket = new openpgp_packet_userid(); - var userIdString = userIdPacket.write_packet(userId); - - var keyPair = openpgp_crypto_generateKeyPair(keyType,numBits, passphrase, openpgp.config.config.prefer_hash_algorithm, 3); - var privKeyString = keyPair.privateKey; - var privKeyPacket = new openpgp_packet_keymaterial().read_priv_key(privKeyString.string,3,privKeyString.string.length); - if(!privKeyPacket.decryptSecretMPIs(passphrase)) - util.print_error('Issue creating key. Unable to read resulting private key'); - var privKey = new openpgp_msg_privatekey(); - privKey.privateKeyPacket = privKeyPacket; - privKey.getPreferredSignatureHashAlgorithm = function(){return openpgp.config.config.prefer_hash_algorithm};//need to override this to solve catch 22 to generate signature. 8 is value for SHA256 - - var publicKeyString = privKey.privateKeyPacket.publicKey.data; - var hashData = String.fromCharCode(0x99)+ String.fromCharCode(((publicKeyString.length) >> 8) & 0xFF) - + String.fromCharCode((publicKeyString.length) & 0xFF) +publicKeyString+String.fromCharCode(0xB4) + - String.fromCharCode((userId.length) >> 24) +String.fromCharCode(((userId.length) >> 16) & 0xFF) - + String.fromCharCode(((userId.length) >> 8) & 0xFF) + String.fromCharCode((userId.length) & 0xFF) + userId; - var signature = new openpgp_packet_signature(); - signature = signature.write_message_signature(16,hashData, privKey); - var publicArmored = armor.encode(4, keyPair.publicKey.string + userIdString + signature.openpgp ); - - var privArmored = armor.encode(5,privKeyString.string+userIdString+signature.openpgp); - - return {privateKey : privKey, privateKeyArmored: privArmored, publicKeyArmored: publicArmored}; - } - - this.generateKeyPair = generateKeyPair; - this.write_signed_message = write_signed_message; - this.write_signed_and_encrypted_message = write_signed_and_encrypted_message; - this.write_encrypted_message = write_encrypted_message; - this.readArmoredPackets = readArmoredPackets; - this.readDearmoredPackets = readDearmoredPackets; - this.init = init; -} - -module.exports = new _openpgp(); - - -},{"./encoding/armor.js":25,"./packet":33,"./util":54}],30:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var packet = require('./packet'); -var enums = require('./enums.js'); -var armor = require('./encoding/armor.js'); - -/** - * @class - * @classdesc The class that deals with storage of the keyring. Currently the only option is to use HTML5 local storage. - */ -var keyring = function() { - this.armoredPacketlists = []; - this.parsedPacketlists = []; - - /** - * Initialization routine for the keyring. This method reads the - * keyring from HTML5 local storage and initializes this instance. - * This method is called by openpgp.init(). - */ - function init() { - var armoredPacketlists = JSON.parse(window.localStorage.getItem("armoredPacketlists")); - if (armoredPacketlists === null || armoredPacketlists.length === 0) { - armoredPacketlists = []; - } - this.armoredPacketlists = armoredPacketlists; - - var packetlist; - for (var i = 0; i < armoredPacketlists.length; i++) { - packetlist = new packet.list(); - packetlist.read(armoredPacketlists[i]); - this.parsedPacketlists.push(packetlist); - } - } - this.init = init; - - /** - * Saves the current state of the keyring to HTML5 local storage. - * The privateKeys array and publicKeys array gets Stringified using JSON - */ - function store() { - window.localStorage.setItem("armoredPacketlists", JSON.stringify(this.armoredPacketlists)); - } - this.store = store; - - function emailPacketCheck(packet, email) { - var emailMatch = false; - var packetEmail; - email = email.toLowerCase(); - if (packet.tag == enums.packet.userid) { - packetEmail = packet.userid; - //we need to get just the email from the userid packet - packetEmail = packetEmail.split('<')[1].split('<')[0].trim.toLowerCase(); - if (packetEmail == email) { - emailMatch = true; - } - } - return emailMatch; - } - - function idPacketCheck(packet, id) { - if (packet.getKeyId && packet.getKeyId() == id) { - return true; - } - return false; - } - - function helperCheckIdentityAndPacketMatch(identityFunction, identityInput, packetType, packetlist) { - var packet; - for (var l = 0; l < packetlist.length; l++) { - packet = packetlist[l]; - identityMatch = identityFunction(packet, identityInput); - if (!packetType) { - packetMatch = true; - } - else if (packet.tag == packetType) { - packetMatch = true; - } - if (packetMatch && identityMatch) { - return true; - } - } - return false; - } - - function checkForIdentityAndPacketMatch(identityFunction, identityInput, packetType) { - var results = []; - var packetlist; - var identityMatch; - var packetMatch; - for (var p = 0; p < this.parsedPacketlists.length; p++) { - identityMatch = false; - packetMatch = false; - packetlist = this.parsedPacketlists[p]; - if (helperCheckIdentityAndPacketMatch(identityFunction, identityInput, packetType, packetlist)) { - results.push(packetlist); - } - } - return results; - } - this.checkForIdentityAndPacketMatch = checkForIdentityAndPacketMatch; - - /** - * searches all public keys in the keyring matching the address or address part of the user ids - * @param {String} email_address - * @return {openpgp_msg_publickey[]} The public keys associated with provided email address. - */ - function getPublicKeyForAddress(email) { - return checkForIdentityAndPacketMatch(emailPacketCheck, email, enums.packet.public_key); - } - this.getPublicKeyForAddress = getPublicKeyForAddress; - - /** - * Searches the keyring for a private key containing the specified email address - * @param {String} email_address email address to search for - * @return {openpgp_msg_privatekey[]} private keys found - */ - function getPrivateKeyForAddress(email_address) { - return checkForIdentityAndPacketMatch(emailPacketCheck, email, enums.packet.secret_key); - } - this.getPrivateKeyForAddress = getPrivateKeyForAddress; - - /** - * Searches the keyring for public keys having the specified key id - * @param {String} keyId provided as string of hex number (lowercase) - * @return {openpgp_msg_privatekey[]} public keys found - */ - function getPacketlistsForKeyId(keyId) { - return this.checkForIdentityAndPacketMatch(idPacketCheck, keyId); - } - this.getPacketlistsForKeyId = getPacketlistsForKeyId; - - /** - * Imports a packet list (public or private key block) from an ascii armored message - * @param {String} armored message to read the packets/key from - */ - function importPacketlist (armored) { - this.armoredPacketlists.push(armored); - - var dearmored = armor.decode(armored.replace(/\r/g,'')).openpgp; - - packetlist = new packet.list(); - packetlist.read(dearmored); - this.parsedPacketlists.push(packetlist); - - return true; - } - this.importPacketlist = importPacketlist; - - /** - * TODO - * returns the openpgp_msg_privatekey representation of the public key at public key ring index - * @param {Integer} index the index of the public key within the publicKeys array - * @return {openpgp_msg_privatekey} the public key object - */ - function exportPublicKey(index) { - return this.publicKey[index]; - } - this.exportPublicKey = exportPublicKey; - - /** - * TODO - * Removes a public key from the public key keyring at the specified index - * @param {Integer} index the index of the public key within the publicKeys array - * @return {openpgp_msg_privatekey} The public key object which has been removed - */ - function removePublicKey(index) { - var removed = this.publicKeys.splice(index,1); - this.store(); - return removed; - } - this.removePublicKey = removePublicKey; - -}; - -module.exports = new keyring(); - -},{"./encoding/armor.js":25,"./enums.js":27,"./packet":33}],31:[function(require,module,exports){ - -var enums = require('../enums.js'); - -// This is pretty ugly, but browserify needs to have the requires explicitly written. -module.exports = { - compressed: require('./compressed.js'), - sym_encrypted_integrity_protected: require('./sym_encrypted_integrity_protected.js'), - public_key_encrypted_session_key: require('./public_key_encrypted_session_key.js'), - sym_encrypted_session_key: require('./sym_encrypted_session_key.js'), - literal: require('./literal.js'), - public_key: require('./public_key.js'), - symmetrically_encrypted: require('./symmetrically_encrypted.js'), - marker: require('./marker.js'), - public_subkey: require('./public_subkey.js'), - user_attribute: require('./user_attribute.js'), - one_pass_signature: require('./one_pass_signature.js'), - secret_key: require('./secret_key.js'), - userid: require('./userid.js'), - secret_subkey: require('./secret_subkey.js'), - signature: require('./signature.js'), - trust: require('./trust.js') -} - -for(var i in enums.packet) { - var packetClass = module.exports[i]; - - if(packetClass != undefined) - packetClass.prototype.tag = enums.packet[i]; -} - -},{"../enums.js":27,"./compressed.js":32,"./literal.js":34,"./marker.js":35,"./one_pass_signature.js":36,"./public_key.js":39,"./public_key_encrypted_session_key.js":40,"./public_subkey.js":41,"./secret_key.js":42,"./secret_subkey.js":43,"./signature.js":44,"./sym_encrypted_integrity_protected.js":45,"./sym_encrypted_session_key.js":46,"./symmetrically_encrypted.js":47,"./trust.js":48,"./user_attribute.js":49,"./userid.js":50}],32:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var enums = require('../enums.js'), - JXG = require('../compression/jxg.js'), - base64 = require('../encoding/base64.js'); - -/** - * @class - * @classdesc Implementation of the Compressed Data Packet (Tag 8) - * - * RFC4880 5.6: - * The Compressed Data packet contains compressed data. Typically, this - * packet is found as the contents of an encrypted packet, or following - * a Signature or One-Pass Signature packet, and contains a literal data - * packet. - */ -module.exports = function packet_compressed() { - /** @type {packetlist} */ - this.packets; - /** @type {compression} */ - this.algorithm = 'uncompressed'; - - this.compressed = null; - - - /** - * Parsing function for the packet. - * @param {String} input Payload of a tag 8 packet - * @param {Integer} position Position to start reading from the input string - * @parAM {iNTEGER} LEN lENGTH OF the packet or the remaining length of - * input at position - * @return {openpgp_packet_compressed} Object representation - */ - this.read = function(bytes) { - // One octet that gives the algorithm used to compress the packet. - this.algorithm = enums.read(enums.compression, bytes.charCodeAt(0)); - - // Compressed data, which makes up the remainder of the packet. - this.compressed = bytes.substr(1); - - this.decompress(); - } - - - - this.write = function() { - if(this.compressed == null) - this.compress(); - - return String.fromCharCode(enums.write(enums.compression, this.algorithm)) - + this.compressed; - } - - - /** - * Decompression method for decompressing the compressed data - * read by read_packet - * @return {String} The decompressed data - */ - this.decompress = function() { - var decompressed; - - switch (this.algorithm) { - case 'uncompressed': - decompressed = this.compressed; - break; - - case 'zip': - var compData = this.compressed; - - var radix = base64.encode(compData).replace(/\n/g,""); - // no header in this case, directly call deflate - var jxg_obj = new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(radix)); - - decompressed = unescape(jxg_obj.deflate()[0][0]); - break; - - case 'zlib': - //RFC 1950. Bits 0-3 Compression Method - var compressionMethod = this.compressed.charCodeAt(0) % 0x10; - - //Bits 4-7 RFC 1950 are LZ77 Window. Generally this value is 7 == 32k window size. - // 2nd Byte in RFC 1950 is for "FLAGs" Allows for a Dictionary - // (how is this defined). Basic checksum, and compression level. - - if (compressionMethod == 8) { //CM 8 is for DEFLATE, RFC 1951 - // remove 4 bytes ADLER32 checksum from the end - var compData = this.compressed.substring(0, this.compressed.length - 4); - var radix = base64.encode(compData).replace(/\n/g,""); - //TODO check ADLER32 checksum - decompressed = JXG.decompress(radix); - break; - - } else { - util.print_error("Compression algorithm ZLIB only supports " + - "DEFLATE compression method."); - } - break; - - case 'bzip2': - // TODO: need to implement this - throw new Error('Compression algorithm BZip2 [BZ2] is not implemented.'); - break; - - default: - throw new Error("Compression algorithm unknown :" + this.alogrithm); - break; - } - - this.packets.read(decompressed); - } - - /** - * Compress the packet data (member decompressedData) - * @param {Integer} type Algorithm to be used // See RFC 4880 9.3 - * @param {String} data Data to be compressed - * @return {String} The compressed data stored in attribute compressedData - */ - this.compress = function() { - switch (this.algorithm) { - - case 'uncompressed': // - Uncompressed - this.compressed = this.packets.write(); - break; - - case 'zip': // - ZIP [RFC1951] - util.print_error("Compression algorithm ZIP [RFC1951] is not implemented."); - break; - - case 'zlib': // - ZLIB [RFC1950] - // TODO: need to implement this - util.print_error("Compression algorithm ZLIB [RFC1950] is not implemented."); - break; - - case 'bzip2': // - BZip2 [BZ2] - // TODO: need to implement this - util.print_error("Compression algorithm BZip2 [BZ2] is not implemented."); - break; - - default: - util.print_error("Compression algorithm unknown :"+this.type); - break; - } - } -}; - -},{"../compression/jxg.js":1,"../encoding/base64.js":26,"../enums.js":27}],33:[function(require,module,exports){ - -var enums = require('../enums.js'); - -module.exports = { - list: require('./packetlist.js'), -}; - -var packets = require('./all_packets.js'); - -for(var i in packets) - module.exports[i] = packets[i]; - -},{"../enums.js":27,"./all_packets.js":31,"./packetlist.js":38}],34:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var util = require('../util'), - enums = require('../enums.js'); - -/** - * @class - * @classdesc Implementation of the Literal Data Packet (Tag 11) - * - * RFC4880 5.9: A Literal Data packet contains the body of a message; data that - * is not to be further interpreted. - */ -module.exports = function packet_literal() { - this.format = 'utf8'; - this.data = ''; - this.date = new Date(); - - - /** - * Set the packet data to a javascript native string or a squence of - * bytes. Conversion to a proper utf8 encoding takes place when the - * packet is written. - * @param {String} str Any native javascript string - * @param {openpgp_packet_literaldata.format} format - */ - this.set = function(str, format) { - this.format = format; - this.data = str; - } - - /** - * Set the packet data to value represented by the provided string - * of bytes together with the appropriate conversion format. - * @param {String} bytes The string of bytes - * @param {openpgp_packet_literaldata.format} format - */ - this.setBytes = function(bytes, format) { - this.format = format; - - if(format == 'utf8') - bytes = util.decode_utf8(bytes); - - this.data = bytes; - } - - /** - * Get the byte sequence representing the literal packet data - * @returns {String} A sequence of bytes - */ - this.getBytes = function() { - if(this.format == 'utf8') - return util.encode_utf8(this.data); - else - return this.data; - } - - - - /** - * Parsing function for a literal data packet (tag 11). - * - * @param {String} input Payload of a tag 11 packet - * @param {Integer} position - * Position to start reading from the input string - * @param {Integer} len - * Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encrypteddata} object representation - */ - this.read = function(bytes) { - // - A one-octet field that describes how the data is formatted. - - var format = enums.read(enums.literal, bytes[0].charCodeAt()); - - var filename_len = bytes.charCodeAt(1); - this.filename = util.decode_utf8(bytes.substr(2, filename_len)); - - this.date = util.readDate(bytes.substr(2 - + filename_len, 4)); - - var data = bytes.substring(6 + filename_len); - - this.setBytes(data, format); - } - - /** - * Creates a string representation of the packet - * - * @param {String} data The data to be inserted as body - * @return {String} string-representation of the packet - */ - this.write = function() { - var filename = util.encode_utf8("msg.txt"); - - var data = this.getBytes(); - - var result = ''; - result += String.fromCharCode(enums.write(enums.literal, this.format)); - result += String.fromCharCode(filename.length); - result += filename; - result += util.writeDate(this.date); - result += data; - return result; - } -} - -},{"../enums.js":27,"../util":54}],35:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the strange "Marker packet" (Tag 10) - * - * RFC4880 5.8: An experimental version of PGP used this packet as the Literal - * packet, but no released version of PGP generated Literal packets with this - * tag. With PGP 5.x, this packet has been reassigned and is reserved for use as - * the Marker packet. - * - * Such a packet MUST be ignored when received. - */ -function packet_marker() { - /** - * Parsing function for a literal data packet (tag 10). - * - * @param {String} input Payload of a tag 10 packet - * @param {Integer} position - * Position to start reading from the input string - * @param {Integer} len - * Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encrypteddata} Object representation - */ - this.read = function(bytes) { - if (bytes[0].charCodeAt() == 0x50 && // P - bytes[1].charCodeAt() == 0x47 && // G - bytes[2].charCodeAt() == 0x50) // P - return true; - // marker packet does not contain "PGP" - return false; - } -} - -module.exports = packet_marker; - -},{}],36:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the One-Pass Signature Packets (Tag 4) - * - * RFC4880 5.4: - * The One-Pass Signature packet precedes the signed data and contains - * enough information to allow the receiver to begin calculating any - * hashes needed to verify the signature. It allows the Signature - * packet to be placed at the end of the message, so that the signer - * can compute the entire signed message in one pass. - */ - -var enums = require('../enums.js'), - type_keyid = require('../type/keyid.js'); - -module.exports = function packet_one_pass_signature() { - this.version = null; // A one-octet version number. The current version is 3. - this.type = null; // A one-octet signature type. Signature types are described in RFC4880 Section 5.2.1. - this.hashAlgorithm = null; // A one-octet number describing the hash algorithm used. (See RFC4880 9.4) - this.publicKeyAlgorithm = null; // A one-octet number describing the public-key algorithm used. (See RFC4880 9.1) - this.signingKeyId = null; // An eight-octet number holding the Key ID of the signing key. - this.flags = null; // A one-octet number holding a flag showing whether the signature is nested. A zero value indicates that the next packet is another One-Pass Signature packet that describes another signature to be applied to the same message data. - - /** - * parsing function for a one-pass signature packet (tag 4). - * @param {String} bytes payload of a tag 4 packet - * @param {Integer} position position to start reading from the bytes string - * @param {Integer} len length of the packet or the remaining length of bytes at position - * @return {openpgp_packet_encrypteddata} object representation - */ - this.read = function(bytes) { - var mypos = 0; - // A one-octet version number. The current version is 3. - this.version = bytes.charCodeAt(mypos++); - - // A one-octet signature type. Signature types are described in - // Section 5.2.1. - this.type = enums.read(enums.signature, bytes.charCodeAt(mypos++)); - - // A one-octet number describing the hash algorithm used. - this.hashAlgorithm = enums.read(enums.hash, bytes.charCodeAt(mypos++)); - - // A one-octet number describing the public-key algorithm used. - this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes.charCodeAt(mypos++)); - - // An eight-octet number holding the Key ID of the signing key. - this.signingKeyId = new type_keyid(); - this.signingKeyId.read(bytes.substr(mypos)); - mypos += 8; - - // A one-octet number holding a flag showing whether the signature - // is nested. A zero value indicates that the next packet is - // another One-Pass Signature packet that describes another - // signature to be applied to the same message data. - this.flags = bytes.charCodeAt(mypos++); - return this; - } - - /** - * creates a string representation of a one-pass signature packet - * @param {Integer} type Signature types as described in RFC4880 Section 5.2.1. - * @param {Integer} hashalgorithm the hash algorithm used within the signature - * @param {openpgp_msg_privatekey} privatekey the private key used to generate the signature - * @param {Integer} length length of data to be signed - * @param {boolean} nested boolean showing whether the signature is nested. - * "true" indicates that the next packet is another One-Pass Signature packet - * that describes another signature to be applied to the same message data. - * @return {String} a string representation of a one-pass signature packet - */ - this.write = function(type, hashalgorithm, privatekey, length, nested) { - var result =""; - - result += String.fromCharCode(3); - result += String.fromCharCode(enums.write(enums.signature, type)); - result += String.fromCharCode(enums.write(enums.hash, this.hashAlgorithm)); - result += String.fromCharCode(enums.write(enums.publicKey, privatekey.algorithm)); - result += privatekey.getKeyId(); - if (nested) - result += String.fromCharCode(0); - else - result += String.fromCharCode(1); - - return result; - } -}; - -},{"../enums.js":27,"../type/keyid.js":51}],37:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var enums = require('../enums.js'), - util = require('../util'); - - -module.exports = { - readSimpleLength: function(bytes) { - var len = 0, - offset, - type = bytes[0].charCodeAt(); - - - if (type < 192) { - len = bytes[0].charCodeAt(); - offset = 1; - } else if (type < 255) { - len = ((bytes[0].charCodeAt() - 192) << 8) + (bytes[1].charCodeAt()) + 192; - offset = 2; - } else if (type == 255) { - len = util.readNumber(bytes.substr(1, 4)); - offset = 5; - } - - return { len: len, offset: offset }; - }, - - /** - * Encodes a given integer of length to the openpgp length specifier to a - * string - * - * @param {Integer} length The length to encode - * @return {String} String with openpgp length representation - */ - writeSimpleLength: function(length) { - var result = ""; - if (length < 192) { - result += String.fromCharCode(length); - } else if (length > 191 && length < 8384) { - /* - * let a = (total data packet length) - 192 let bc = two octet - * representation of a let d = b + 192 - */ - result += String.fromCharCode(((length - 192) >> 8) + 192); - result += String.fromCharCode((length - 192) & 0xFF); - } else { - result += String.fromCharCode(255); - result += util.writeNumber(length, 4); - } - return result; - }, - - /** - * Writes a packet header version 4 with the given tag_type and length to a - * string - * - * @param {Integer} tag_type Tag type - * @param {Integer} length Length of the payload - * @return {String} String of the header - */ - writeHeader: function(tag_type, length) { - /* we're only generating v4 packet headers here */ - var result = ""; - result += String.fromCharCode(0xC0 | tag_type); - result += this.writeSimpleLength(length); - return result; - }, - - /** - * Writes a packet header Version 3 with the given tag_type and length to a - * string - * - * @param {Integer} tag_type Tag type - * @param {Integer} length Length of the payload - * @return {String} String of the header - */ - writeOldHeader: function(tag_type, length) { - var result = ""; - if (length < 256) { - result += String.fromCharCode(0x80 | (tag_type << 2)); - result += String.fromCharCode(length); - } else if (length < 65536) { - result += String.fromCharCode(0x80 | (tag_type << 2) | 1); - result += util.writeNumber(length, 2); - } else { - result += String.fromCharCode(0x80 | (tag_type << 2) | 2); - result += util.writeNumber(length, 4); - } - return result; - }, - - /** - * Generic static Packet Parser function - * - * @param {String} input Input stream as string - * @param {integer} position Position to start parsing - * @param {integer} len Length of the input from position on - * @return {Object} Returns a parsed openpgp_packet - */ - read: function(input, position, len) { - // some sanity checks - if (input == null || input.length <= position - || input.substring(position).length < 2 - || (input[position].charCodeAt() & 0x80) == 0) { - util - .print_error("Error during parsing. This message / key is probably not containing a valid OpenPGP format."); - return null; - } - var mypos = position; - var tag = -1; - var format = -1; - var packet_length; - - format = 0; // 0 = old format; 1 = new format - if ((input[mypos].charCodeAt() & 0x40) != 0) { - format = 1; - } - - var packet_length_type; - if (format) { - // new format header - tag = input[mypos].charCodeAt() & 0x3F; // bit 5-0 - } else { - // old format header - tag = (input[mypos].charCodeAt() & 0x3F) >> 2; // bit 5-2 - packet_length_type = input[mypos].charCodeAt() & 0x03; // bit 1-0 - } - - // header octet parsing done - mypos++; - - // parsed length from length field - var bodydata = null; - - // used for partial body lengths - var real_packet_length = -1; - if (!format) { - // 4.2.1. Old Format Packet Lengths - switch (packet_length_type) { - case 0: // The packet has a one-octet length. The header is 2 octets - // long. - packet_length = input[mypos++].charCodeAt(); - break; - case 1: // The packet has a two-octet length. The header is 3 octets - // long. - packet_length = (input[mypos++].charCodeAt() << 8) - | input[mypos++].charCodeAt(); - break; - case 2: // The packet has a four-octet length. The header is 5 - // octets long. - packet_length = (input[mypos++].charCodeAt() << 24) - | (input[mypos++].charCodeAt() << 16) - | (input[mypos++].charCodeAt() << 8) - | input[mypos++].charCodeAt(); - break; - default: - // 3 - The packet is of indeterminate length. The header is 1 - // octet long, and the implementation must determine how long - // the packet is. If the packet is in a file, this means that - // the packet extends until the end of the file. In general, - // an implementation SHOULD NOT use indeterminate-length - // packets except where the end of the data will be clear - // from the context, and even then it is better to use a - // definite length, or a new format header. The new format - // headers described below have a mechanism for precisely - // encoding data of indeterminate length. - packet_length = len; - break; - } - - } else // 4.2.2. New Format Packet Lengths - { - - // 4.2.2.1. One-Octet Lengths - if (input[mypos].charCodeAt() < 192) { - packet_length = input[mypos++].charCodeAt(); - util.print_debug("1 byte length:" + packet_length); - // 4.2.2.2. Two-Octet Lengths - } else if (input[mypos].charCodeAt() >= 192 - && input[mypos].charCodeAt() < 224) { - packet_length = ((input[mypos++].charCodeAt() - 192) << 8) - + (input[mypos++].charCodeAt()) + 192; - util.print_debug("2 byte length:" + packet_length); - // 4.2.2.4. Partial Body Lengths - } else if (input[mypos].charCodeAt() > 223 - && input[mypos].charCodeAt() < 255) { - packet_length = 1 << (input[mypos++].charCodeAt() & 0x1F); - util.print_debug("4 byte length:" + packet_length); - // EEEK, we're reading the full data here... - var mypos2 = mypos + packet_length; - bodydata = input.substring(mypos, mypos + packet_length); - while (true) { - if (input[mypos2].charCodeAt() < 192) { - var tmplen = input[mypos2++].charCodeAt(); - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - break; - } else if (input[mypos2].charCodeAt() >= 192 - && input[mypos2].charCodeAt() < 224) { - var tmplen = ((input[mypos2++].charCodeAt() - 192) << 8) - + (input[mypos2++].charCodeAt()) + 192; - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - break; - } else if (input[mypos2].charCodeAt() > 223 - && input[mypos2].charCodeAt() < 255) { - var tmplen = 1 << (input[mypos2++].charCodeAt() & 0x1F); - packet_length += tmplen; - bodydata += input.substring(mypos2, mypos2 + tmplen); - mypos2 += tmplen; - } else { - mypos2++; - var tmplen = (input[mypos2++].charCodeAt() << 24) - | (input[mypos2++].charCodeAt() << 16) - | (input[mypos2++].charCodeAt() << 8) - | input[mypos2++].charCodeAt(); - bodydata += input.substring(mypos2, mypos2 + tmplen); - packet_length += tmplen; - mypos2 += tmplen; - break; - } - } - real_packet_length = mypos2; - // 4.2.2.3. Five-Octet Lengths - } else { - mypos++; - packet_length = (input[mypos++].charCodeAt() << 24) - | (input[mypos++].charCodeAt() << 16) - | (input[mypos++].charCodeAt() << 8) - | input[mypos++].charCodeAt(); - } - } - - // if there was'nt a partial body length: use the specified - // packet_length - if (real_packet_length == -1) { - real_packet_length = packet_length; - } - - if (bodydata == null) { - bodydata = input.substring(mypos, mypos + real_packet_length); - } - - return { - tag: tag, - packet: bodydata, - offset: mypos + real_packet_length - }; - } -} - - -},{"../enums.js":27,"../util":54}],38:[function(require,module,exports){ - - -var packetParser = require('./packet.js'), - packets = require('./all_packets.js'), - enums = require('../enums.js'); - -/** - * @class - * @classdesc This class represents a list of openpgp packets. - * Take care when iterating over it - the packets themselves - * are stored as numerical indices. - */ -module.exports = function packetlist() { - /** The number of packets contained within the list. - * @readonly - * @type {Integer} */ - this.length = 0; - - - - /** - * Reads a stream of binary data and interprents it as a list of packets. - * @param {openpgp_bytearray} An array of bytes. - */ - this.read = function(bytes) { - var i = 0; - - while(i < bytes.length) { - var parsed = packetParser.read(bytes, i, bytes.length - i); - i = parsed.offset; - - var tag = enums.read(enums.packet, parsed.tag); - var packet = new packets[tag](); - - this.push(packet); - - packet.read(parsed.packet); - } - } - - /** - * Creates a binary representation of openpgp objects contained within the - * class instance. - * @returns {openpgp_bytearray} An array of bytes containing valid openpgp packets. - */ - this.write = function() { - var bytes = ''; - - for(var i = 0; i < this.length; i++) { - var packetbytes = this[i].write(); - bytes += packetParser.writeHeader(this[i].tag, packetbytes.length); - bytes += packetbytes; - } - - return bytes; - } - - /** - * Adds a packet to the list. This is the only supported method of doing so; - * writing to packetlist[i] directly will result in an error. - */ - this.push = function(packet) { - packet.packets = new packetlist(); - - this[this.length] = packet; - this.length++; - } - -} - -},{"../enums.js":27,"./all_packets.js":31,"./packet.js":37}],39:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var util = require('../util'), - type_mpi = require('../type/mpi.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - -/** - * @class - * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) - * - * RFC4480 5.5: - * A key material packet contains all the information about a public or - * private key. There are four variants of this packet type, and two - * major versions. Consequently, this section is complex. - */ -module.exports = function packet_public_key() { - /** Key creation date. - * @type {Date} */ - this.created = new Date(); - /** A list of multiprecision integers - * @type {openpgp_type_mpi} */ - this.mpi = []; - /** Public key algorithm - * @type {openpgp.publickey} */ - this.algorithm = 'rsa_sign'; - - - /** - * Internal Parser for public keys as specified in RFC 4880 section - * 5.5.2 Public-Key Packet Formats - * called by read_tag<num> - * @param {String} input Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet or remaining length of input - * @return {Object} This object with attributes set by the parser - */ - this.readPublicKey = this.read = function(bytes) { - // A one-octet version number (3 or 4). - var version = bytes[0].charCodeAt(); - - if (version == 4) { - // - A four-octet number denoting the time that the key was created. - this.created = util.readDate(bytes.substr(1, 4)); - - // - A one-octet number denoting the public-key algorithm of this key. - this.algorithm = enums.read(enums.publicKey, bytes[5].charCodeAt()); - - var mpicount = crypto.getPublicMpiCount(this.algorithm); - this.mpi = []; - - var bmpi = bytes.substr(6); - var p = 0; - - for (var i = 0; - i < mpicount && p < bmpi.length; - i++) { - - this.mpi[i] = new type_mpi(); - - p += this.mpi[i].read(bmpi.substr(p)) - - if(p > bmpi.length) - util.print_error("openpgp.packet.keymaterial.js\n" - +'error reading MPI @:'+p); - } - - return p + 6; - } else { - throw new Error('Version ' + version + ' of the key packet is unsupported.'); - } - } - - /* - * Same as write_private_key, but has less information because of - * public key. - * @param {Integer} keyType Follows the OpenPGP algorithm standard, - * IE 1 corresponds to RSA. - * @param {RSA.keyObject} key - * @param timePacket - * @return {Object} {body: [string]OpenPGP packet body contents, - * header: [string] OpenPGP packet header, string: [string] header+body} - */ - this.writePublicKey = this.write = function() { - // Version - var result = String.fromCharCode(4); - result += util.writeDate(this.created); - result += String.fromCharCode(enums.write(enums.publicKey, this.algorithm)); - - var mpicount = crypto.getPublicMpiCount(this.algorithm); - - for(var i = 0; i < mpicount; i++) { - result += this.mpi[i].write(); - } - - return result; - } - - // Write an old version packet - it's used by some of the internal routines. - this.writeOld = function() { - var bytes = this.writePublicKey(); - - return String.fromCharCode(0x99) + - util.writeNumber(bytes.length, 2) + - bytes; - } - - /** - * Calculates the key id of the key - * @return {String} A 8 byte key id - */ - this.getKeyId = function() { - return this.getFingerprint().substr(12, 8); - } - - /** - * Calculates the fingerprint of the key - * @return {String} A string containing the fingerprint - */ - this.getFingerprint = function() { - var toHash = this.writeOld(); - return crypto.hash.sha1(toHash, toHash.length); - } - -} - -},{"../crypto":14,"../enums.js":27,"../type/mpi.js":52,"../util":54}],40:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var type_keyid = require('../type/keyid.js'), - util = require('../util'), - type_mpi = require('../type/mpi.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - - -/** - * @class - * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) - * - * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key - * used to encrypt a message. Zero or more Public-Key Encrypted Session Key - * packets and/or Symmetric-Key Encrypted Session Key packets may precede a - * Symmetrically Encrypted Data Packet, which holds an encrypted message. The - * message is encrypted with the session key, and the session key is itself - * encrypted and stored in the Encrypted Session Key packet(s). The - * Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted - * Session Key packet for each OpenPGP key to which the message is encrypted. - * The recipient of the message finds a session key that is encrypted to their - * public key, decrypts the session key, and then uses the session key to - * decrypt the message. - */ -module.exports = function packet_public_key_encrypted_session_key() { - this.version = 3; - - this.publicKeyId = new type_keyid(); - this.publicKeyAlgorithm = 'rsa_encrypt'; - - this.sessionKey = null; - this.sessionKeyAlgorithm = 'aes256'; - - /** @type {openpgp_type_mpi[]} */ - this.encrypted = []; - - /** - * Parsing function for a publickey encrypted session key packet (tag 1). - * - * @param {String} input Payload of a tag 1 packet - * @param {Integer} position Position to start reading from the input string - * @param {Integer} len Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encrypteddata} Object representation - */ - this.read = function(bytes) { - - this.version = bytes[0].charCodeAt(); - this.publicKeyId.read(bytes.substr(1)); - this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes[9].charCodeAt()); - - var i = 10; - - var integerCount = (function(algo) { - switch (algo) { - case 'rsa_encrypt': - case 'rsa_encrypt_sign': - return 1; - - case 'elgamal': - return 2; - - default: - throw new Error("Invalid algorithm."); - } - })(this.publicKeyAlgorithm); - - this.encrypted = []; - - for(var j = 0; j < integerCount; j++) { - var mpi = new type_mpi(); - i += mpi.read(bytes.substr(i)); - this.encrypted.push(mpi); - } - } - - /** - * Create a string representation of a tag 1 packet - * - * @param {String} publicKeyId - * The public key id corresponding to publicMPIs key as string - * @param {openpgp_type_mpi[]} publicMPIs - * Multiprecision integer objects describing the public key - * @param {Integer} pubalgo - * The corresponding public key algorithm // See RFC4880 9.1 - * @param {Integer} symmalgo - * The symmetric cipher algorithm used to encrypt the data - * within an encrypteddatapacket or encryptedintegrity- - * protecteddatapacket - * following this packet //See RFC4880 9.2 - * @param {String} sessionkey - * A string of randombytes representing the session key - * @return {String} The string representation - */ - this.write = function() { - - var result = String.fromCharCode(this.version); - result += this.publicKeyId.write(); - result += String.fromCharCode( - enums.write(enums.publicKey, this.publicKeyAlgorithm)); - - for ( var i = 0; i < this.encrypted.length; i++) { - result += this.encrypted[i].write() - } - - return result; - } - - this.encrypt = function(key) { - var data = String.fromCharCode( - enums.write(enums.symmetric, this.sessionKeyAlgorithm)); - - data += this.sessionKey; - var checksum = util.calc_checksum(this.sessionKey); - data += util.writeNumber(checksum, 2); - - var mpi = new type_mpi(); - mpi.fromBytes(crypto.pkcs1.eme.encode( - data, - key.mpi[0].byteLength())); - - this.encrypted = crypto.publicKeyEncrypt( - this.publicKeyAlgorithm, - key.mpi, - mpi); - } - - /** - * Decrypts the session key (only for public key encrypted session key - * packets (tag 1) - * - * @param {openpgp_msg_message} msg - * The message object (with member encryptedData - * @param {openpgp_msg_privatekey} key - * Private key with secMPIs unlocked - * @return {String} The unencrypted session key - */ - this.decrypt = function(key) { - var result = crypto.publicKeyDecrypt( - this.publicKeyAlgorithm, - key.mpi, - this.encrypted).toBytes(); - - var checksum = util.readNumber(result.substr(result.length - 2)); - - var decoded = crypto.pkcs1.eme.decode( - result, - key.mpi[0].byteLength()); - - var key = decoded.substring(1, decoded.length - 2); - - if(checksum != util.calc_checksum(key)) { - throw new Error('Checksum mismatch'); - } - else { - this.sessionKey = key; - this.sessionKeyAlgorithm = - enums.read(enums.symmetric, decoded.charCodeAt(0)); - } - } -}; - - -},{"../crypto":14,"../enums.js":27,"../type/keyid.js":51,"../type/mpi.js":52,"../util":54}],41:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var public_key = require('./public_key.js'); - -module.exports = function public_subkey() { - public_key.call(this); -} - -},{"./public_key.js":39}],42:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var publicKey = require('./public_key.js'), - enums = require('../enums.js'), - util = require('../util'), - crypto = require('../crypto'), - type_mpi = require('../type/mpi.js'), - type_s2k = require('../type/s2k.js'); - -/** - * @class - * @classdesc Implementation of the Key Material Packet (Tag 5,6,7,14) - * - * RFC4480 5.5: - * A key material packet contains all the information about a public or - * private key. There are four variants of this packet type, and two - * major versions. Consequently, this section is complex. - */ -function packet_secret_key() { - publicKey.call(this); - - this.encrypted = null; - - - function get_hash_len(hash) { - if(hash == 'sha1') - return 20; - else - return 2; - } - - function get_hash_fn(hash) { - if(hash == 'sha1') - return crypto.hash.sha1; - else - return function(c) { - return util.writeNumber(util.calc_checksum(c), 2); - } - } - - // Helper function - function parse_cleartext_mpi(hash_algorithm, cleartext, algorithm) { - var hashlen = get_hash_len(hash_algorithm), - hashfn = get_hash_fn(hash_algorithm); - - var hashtext = cleartext.substr(cleartext.length - hashlen); - cleartext = cleartext.substr(0, cleartext.length - hashlen); - - var hash = hashfn(cleartext); - - if(hash != hashtext) - throw new Error("Hash mismatch."); - - var mpis = crypto.getPrivateMpiCount(algorithm); - - var j = 0; - var mpi = []; - - for(var i = 0; i < mpis && j < cleartext.length; i++) { - mpi[i] = new type_mpi(); - j += mpi[i].read(cleartext.substr(j)); - } - - return mpi; - } - - function write_cleartext_mpi(hash_algorithm, algorithm, mpi) { - var bytes= ''; - var discard = crypto.getPublicMpiCount(algorithm); - - for(var i = discard; i < mpi.length; i++) { - bytes += mpi[i].write(); - } - - - bytes += get_hash_fn(hash_algorithm)(bytes); - - return bytes; - } - - - // 5.5.3. Secret-Key Packet Formats - - /** - * Internal parser for private keys as specified in RFC 4880 section 5.5.3 - * @param {String} bytes Input string to read the packet from - * @param {Integer} position Start position for the parser - * @param {Integer} len Length of the packet or remaining length of bytes - * @return {Object} This object with attributes set by the parser - */ - this.read = function(bytes) { - // - A Public-Key or Public-Subkey packet, as described above. - var len = this.readPublicKey(bytes); - - bytes = bytes.substr(len); - - - // - One octet indicating string-to-key usage conventions. Zero - // indicates that the secret-key data is not encrypted. 255 or 254 - // indicates that a string-to-key specifier is being given. Any - // other value is a symmetric-key encryption algorithm identifier. - var isEncrypted = bytes[0].charCodeAt(); - - if(isEncrypted) { - this.encrypted = bytes; - } else { - - // - Plain or encrypted multiprecision integers comprising the secret - // key data. These algorithm-specific fields are as described - // below. - - this.mpi = this.mpi.concat(parse_cleartext_mpi('mod', bytes.substr(1), - this.algorithm)); - } - - } - - /* - * Creates an OpenPGP key packet for the given key. much - * TODO in regards to s2k, subkeys. - * @param {Integer} keyType Follows the OpenPGP algorithm standard, - * IE 1 corresponds to RSA. - * @param {RSA.keyObject} key - * @param passphrase - * @param s2kHash - * @param symmetricEncryptionAlgorithm - * @param timePacket - * @return {Object} {body: [string]OpenPGP packet body contents, - header: [string] OpenPGP packet header, string: [string] header+body} - */ - this.write = function() { - var bytes = this.writePublicKey(); - - if(!this.encrypted) { - bytes += String.fromCharCode(0); - - bytes += write_cleartext_mpi('mod', this.algorithm, this.mpi); - } else { - bytes += this.encrypted; - } - - return bytes; - } - - - - - /** Encrypt the payload. By default, we use aes256 and iterated, salted string - * to key specifier - * @param {String} passphrase - */ - this.encrypt = function(passphrase) { - - var s2k = new type_s2k(), - symmetric = 'aes256', - cleartext = write_cleartext_mpi('sha1', this.algorithm, this.mpi), - key = produceEncryptionKey(s2k, passphrase, symmetric), - blockLen = crypto.cipher[symmetric].blockSize, - iv = crypto.random.getRandomBytes(blockLen); - - - this.encrypted = ''; - this.encrypted += String.fromCharCode(254); - this.encrypted += String.fromCharCode(enums.write(enums.symmetric, symmetric)); - this.encrypted += s2k.write(); - this.encrypted += iv; - - - - this.encrypted += crypto.cfb.normalEncrypt(symmetric, key, cleartext, iv); - } - - function produceEncryptionKey(s2k, passphrase, algorithm) { - return s2k.produce_key(passphrase, - crypto.cipher[algorithm].keySize); - } - - /** - * Decrypts the private key MPIs which are needed to use the key. - * openpgp_packet_keymaterial.hasUnencryptedSecretKeyData should be - * false otherwise - * a call to this function is not needed - * - * @param {String} str_passphrase The passphrase for this private key - * as string - * @return {Boolean} True if the passphrase was correct; false if not - */ - this.decrypt = function(passphrase) { - if (!this.encrypted) - return; - - var i = 0, - symmetric, - key; - - var s2k_usage = this.encrypted[i++].charCodeAt(); - - // - [Optional] If string-to-key usage octet was 255 or 254, a one- - // octet symmetric encryption algorithm. - if (s2k_usage == 255 || s2k_usage == 254) { - symmetric = this.encrypted[i++].charCodeAt(); - symmetric = enums.read(enums.symmetric, symmetric); - - // - [Optional] If string-to-key usage octet was 255 or 254, a - // string-to-key specifier. The length of the string-to-key - // specifier is implied by its type, as described above. - var s2k = new type_s2k(); - i += s2k.read(this.encrypted.substr(i)); - - key = produceEncryptionKey(s2k, passphrase, symmetric); - } else { - symmetric = s2k_usage; - symmetric = enums.read(enums.symmetric, symmetric); - key = crypto.hash.md5(passphrase); - } - - - // - [Optional] If secret data is encrypted (string-to-key usage octet - // not zero), an Initial Vector (IV) of the same length as the - // cipher's block size. - var iv = this.encrypted.substr(i, - crypto.cipher[symmetric].blockSize); - - i += iv.length; - - var cleartext, - ciphertext = this.encrypted.substr(i); - - cleartext = crypto.cfb.normalDecrypt(symmetric, key, ciphertext, iv); - - var hash = s2k_usage == 254 ? - 'sha1' : - 'mod'; - - - this.mpi = this.mpi.concat(parse_cleartext_mpi(hash, cleartext, - this.algorithm)); - } - - this.generate = function(bits) { - - } - -} - -packet_secret_key.prototype = new publicKey; - -module.exports = packet_secret_key; - -},{"../crypto":14,"../enums.js":27,"../type/mpi.js":52,"../type/s2k.js":53,"../util":54,"./public_key.js":39}],43:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var secret_key = require('./secret_key.js'); - -module.exports = function secret_subkey() { - secret_key.call(this); -} - -},{"./secret_key.js":42}],44:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var util = require('../util'), - packet = require('./packet.js'), - enums = require('../enums.js'), - crypto = require('../crypto'), - type_mpi = require('../type/mpi.js'); - -/** - * @class - * @classdesc Implementation of the Signature Packet (Tag 2) - * - * RFC4480 5.2: - * A Signature packet describes a binding between some public key and - * some data. The most common signatures are a signature of a file or a - * block of text, and a signature that is a certification of a User ID. - */ -module.exports = function packet_signature() { - - this.signatureType = null; - this.hashAlgorithm = null; - this.publicKeyAlgorithm = null; - - this.signatureData = null; - this.signedHashValue = null; - this.mpi = null; - - this.created = null; - this.signatureExpirationTime = null; - this.signatureNeverExpires = null; - this.exportable = null; - this.trustLevel = null; - this.trustAmount = null; - this.regularExpression = null; - this.revocable = null; - this.keyExpirationTime = null; - this.keyNeverExpires = null; - this.preferredSymmetricAlgorithms = null; - this.revocationKeyClass = null; - this.revocationKeyAlgorithm = null; - this.revocationKeyFingerprint = null; - this.issuerKeyId = null; - this.notation = {}; - this.preferredHashAlgorithms = null; - this.preferredCompressionAlgorithms = null; - this.keyServerPreferences = null; - this.preferredKeyServer = null; - this.isPrimaryUserID = null; - this.policyURI = null; - this.keyFlags = null; - this.signersUserId = null; - this.reasonForRevocationFlag = null; - this.reasonForRevocationString = null; - this.signatureTargetPublicKeyAlgorithm = null; - this.signatureTargetHashAlgorithm = null; - this.signatureTargetHash = null; - this.embeddedSignature = null; - - this.verified = false; - - - /** - * parsing function for a signature packet (tag 2). - * @param {String} bytes payload of a tag 2 packet - * @param {Integer} position position to start reading from the bytes string - * @param {Integer} len length of the packet or the remaining length of bytes at position - * @return {openpgp_packet_encrypteddata} object representation - */ - this.read = function(bytes) { - var i = 0; - - var version = bytes[i++].charCodeAt(); - // switch on version (3 and 4) - switch (version) { - case 3: - // One-octet length of following hashed material. MUST be 5. - if (bytes[i++].charCodeAt() != 5) - util.print_debug("openpgp.packet.signature.js\n"+ - 'invalid One-octet length of following hashed material.' + - 'MUST be 5. @:'+(i-1)); - - var sigpos = i; - // One-octet signature type. - this.signatureType = bytes[i++].charCodeAt(); - - // Four-octet creation time. - this.created = util.readDate(bytes.substr(i, 4)); - i += 4; - - // storing data appended to data which gets verified - this.signatureData = bytes.substring(position, i); - - // Eight-octet Key ID of signer. - this.issuerKeyId = bytes.substring(i, i +8); - i += 8; - - // One-octet public-key algorithm. - this.publicKeyAlgorithm = bytes[i++].charCodeAt(); - - // One-octet hash algorithm. - this.hashAlgorithm = bytes[i++].charCodeAt(); - break; - case 4: - this.signatureType = bytes[i++].charCodeAt(); - this.publicKeyAlgorithm = bytes[i++].charCodeAt(); - this.hashAlgorithm = bytes[i++].charCodeAt(); - - - function subpackets(bytes, signed) { - // Two-octet scalar octet count for following hashed subpacket - // data. - var subpacket_length = util.readNumber( - bytes.substr(0, 2)); - - var i = 2; - - // Hashed subpacket data set (zero or more subpackets) - var subpacked_read = 0; - while (i < 2 + subpacket_length) { - - var len = packet.readSimpleLength(bytes.substr(i)); - i += len.offset; - - // Since it is trivial to add data to the unhashed portion of - // the packet we simply ignore all unauthenticated data. - if(signed) - this.read_sub_packet(bytes.substr(i, len.len)); - - i += len.len; - } - - return i; - } - - i += subpackets.call(this, bytes.substr(i), true); - - // A V4 signature hashes the packet body - // starting from its first field, the version number, through the end - // of the hashed subpacket data. Thus, the fields hashed are the - // signature version, the signature type, the public-key algorithm, the - // hash algorithm, the hashed subpacket length, and the hashed - // subpacket body. - this.signatureData = bytes.substr(0, i); - - i += subpackets.call(this, bytes.substr(i), false); - - break; - default: - throw new Error('Version ' + version + ' of the signature is unsupported.'); - break; - } - - // Two-octet field holding left 16 bits of signed hash value. - this.signedHashValue = bytes.substr(i, 2); - i += 2; - - this.signature = bytes.substr(i); - } - - this.write = function() { - return this.signatureData + - util.writeNumber(0, 2) + // Number of unsigned subpackets. - this.signedHashValue + - this.signature; - } - - /** - * Signs provided data. This needs to be done prior to serialization. - * @param {Object} data Contains packets to be signed. - * @param {openpgp_msg_privatekey} privatekey private key used to sign the message. - */ - this.sign = function(key, data) { - var signatureType = enums.write(enums.signature, this.signatureType), - publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm), - hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm); - - var result = String.fromCharCode(4); - result += String.fromCharCode(signatureType); - result += String.fromCharCode(publicKeyAlgorithm); - result += String.fromCharCode(hashAlgorithm); - - - // Add subpackets here - result += util.writeNumber(0, 2); - - - this.signatureData = result; - - var trailer = this.calculateTrailer(); - - var toHash = this.toSign(signatureType, data) + - this.signatureData + trailer; - - var hash = crypto.hash.digest(hashAlgorithm, toHash); - - this.signedHashValue = hash.substr(0, 2); - - - this.signature = crypto.signature.sign(hashAlgorithm, - publicKeyAlgorithm, key.mpi, toHash); - } - - /** - * creates a string representation of a sub signature packet (See RFC 4880 5.2.3.1) - * @param {Integer} type subpacket signature type. Signature types as described - * in RFC4880 Section 5.2.3.2 - * @param {String} data data to be included - * @return {String} a string-representation of a sub signature packet (See RFC 4880 5.2.3.1) - */ - function write_sub_packet(type, data) { - var result = ""; - result += packet.writeSimpleLength(data.length+1); - result += String.fromCharCode(type); - result += data; - return result; - } - - // V4 signature sub packets - - this.read_sub_packet = function(bytes) { - var mypos = 0; - - function read_array(prop, bytes) { - this[prop] = []; - - for (var i = 0; i < bytes.length; i++) { - this[prop].push(bytes[i].charCodeAt()); - } - } - - // The leftwost bit denotes a "critical" packet, but we ignore it. - var type = bytes[mypos++].charCodeAt() & 0x7F; - - // subpacket type - switch (type) { - case 2: // Signature Creation Time - this.created = util.readDate(bytes.substr(mypos)); - break; - case 3: // Signature Expiration Time - var time = util.readDate(bytes.substr(mypos)); - - this.signatureNeverExpires = time.getTime() == 0; - this.signatureExpirationTime = time; - - break; - case 4: // Exportable Certification - this.exportable = bytes[mypos++].charCodeAt() == 1; - break; - case 5: // Trust Signature - this.trustLevel = bytes[mypos++].charCodeAt(); - this.trustAmount = bytes[mypos++].charCodeAt(); - break; - case 6: // Regular Expression - this.regularExpression = bytes.substr(mypos); - break; - case 7: // Revocable - this.revocable = bytes[mypos++].charCodeAt() == 1; - break; - case 9: // Key Expiration Time - var time = util.readDate(bytes.substr(mypos)); - - this.keyExpirationTime = time; - this.keyNeverExpires = time.getTime() == 0; - - break; - case 11: // Preferred Symmetric Algorithms - this.preferredSymmetricAlgorithms = []; - - while(mypos != bytes.length) { - this.preferredSymmetricAlgorithms.push(bytes[mypos++].charCodeAt()); - } - - break; - case 12: // Revocation Key - // (1 octet of class, 1 octet of public-key algorithm ID, 20 - // octets of - // fingerprint) - this.revocationKeyClass = bytes[mypos++].charCodeAt(); - this.revocationKeyAlgorithm = bytes[mypos++].charCodeAt(); - this.revocationKeyFingerprint = bytes.substr(mypos, 20); - break; - - case 16: // Issuer - this.issuerKeyId = bytes.substr(mypos, 8); - break; - - case 20: // Notation Data - // We don't know how to handle anything but a text flagged data. - if(bytes[mypos].charCodeAt() == 0x80) { - - // We extract key/value tuple from the byte stream. - mypos += 4; - var m = util.writeNumber(bytes.substr(mypos, 2)); - mypos += 2 - var n = util.writeNumber(bytes.substr(mypos, 2)); - mypos += 2 - - var name = bytes.substr(mypos, m), - value = bytes.substr(mypos + m, n); - - this.notation[name] = value; - } - else throw new Error("Unsupported notation flag."); - break; - case 21: // Preferred Hash Algorithms - read_array.call(this, 'preferredHashAlgorithms', bytes.substr(mypos)); - break; - case 22: // Preferred Compression Algorithms - read_array.call(this, 'preferredCompressionAlgorithms ', bytes.substr(mypos)); - break; - case 23: // Key Server Preferences - read_array.call(this, 'keyServerPreferencess', bytes.substr(mypos)); - break; - case 24: // Preferred Key Server - this.preferredKeyServer = bytes.substr(mypos); - break; - case 25: // Primary User ID - this.isPrimaryUserID = bytes[mypos++] != 0; - break; - case 26: // Policy URI - this.policyURI = bytes.substr(mypos); - break; - case 27: // Key Flags - read_array.call(this, 'keyFlags', bytes.substr(mypos)); - break; - case 28: // Signer's User ID - this.signersUserId += bytes.substr(mypos); - break; - case 29: // Reason for Revocation - this.reasonForRevocationFlag = bytes[mypos++].charCodeAt(); - this.reasonForRevocationString = bytes.substr(mypos); - break; - case 30: // Features - read_array.call(this, 'features', bytes.substr(mypos)); - break; - case 31: // Signature Target - // (1 octet public-key algorithm, 1 octet hash algorithm, N octets hash) - this.signatureTargetPublicKeyAlgorithm = bytes[mypos++].charCodeAt(); - this.signatureTargetHashAlgorithm = bytes[mypos++].charCodeAt(); - - var len = crypto.getHashByteLength(this.signatureTargetHashAlgorithm); - - this.signatureTargetHash = bytes.substr(mypos, len); - break; - case 32: // Embedded Signature - this.embeddedSignature = new packet_signature(); - this.embeddedSignature.read(bytes.substr(mypos)); - break; - default: - util.print_error("openpgp.packet.signature.js\n"+ - 'unknown signature subpacket type '+type+" @:"+mypos+ - " subplen:"+subplen+" len:"+len); - break; - } - }; - - // Produces data to produce signature on - this.toSign = function(type, data) { - var t = enums.signature - - switch(type) { - case t.binary: - return data.getBytes(); - - case t.text: - return this.toSign(t.binary, data) - .replace(/\r\n/g, '\n') - .replace(/\n/g, '\r\n'); - - case t.standalone: - return '' - - case t.cert_generic: - case t.cert_persona: - case t.cert_casual: - case t.cert_positive: - case t.cert_revocation: - { - var packet, tag; - - if(data.userid != undefined) { - tag = 0xB4; - packet = data.userid; - } - else if(data.userattribute != undefined) { - tag = 0xD1 - packet = data.userattribute; - } - else throw new Error('Either a userid or userattribute packet needs to be ' + - 'supplied for certification.'); - - - var bytes = packet.write(); - - - return this.toSign(t.key, data) + - String.fromCharCode(tag) + - util.writeNumber(bytes.length, 4) + - bytes; - } - case t.subkey_binding: - case t.key_binding: - { - return this.toSign(t.key, data) + this.toSign(t.key, { key: data.bind }); - } - case t.key: - { - if(data.key == undefined) - throw new Error('Key packet is required for this sigtature.'); - - return data.key.writeOld(); - } - case t.key_revocation: - case t.subkey_revocation: - return this.toSign(t.key, data); - case t.timestamp: - return ''; - case t.thrid_party: - throw new Error('Not implemented'); - break; - default: - throw new Error('Unknown signature type.') - } - } - - - this.calculateTrailer = function() { - // calculating the trailer - var trailer = ''; - trailer += String.fromCharCode(4); // Version - trailer += String.fromCharCode(0xFF); - trailer += util.writeNumber(this.signatureData.length, 4); - return trailer - } - - - /** - * verifys the signature packet. Note: not signature types are implemented - * @param {String} data data which on the signature applies - * @param {openpgp_msg_privatekey} key the public key to verify the signature - * @return {boolean} True if message is verified, else false. - */ - this.verify = function(key, data) { - var signatureType = enums.write(enums.signature, this.signatureType), - publicKeyAlgorithm = enums.write(enums.publicKey, this.publicKeyAlgorithm), - hashAlgorithm = enums.write(enums.hash, this.hashAlgorithm); - - var bytes = this.toSign(signatureType, data), - trailer = this.calculateTrailer(); - - - var mpicount = 0; - // Algorithm-Specific Fields for RSA signatures: - // - multiprecision number (MPI) of RSA signature value m**d mod n. - if (publicKeyAlgorithm > 0 && publicKeyAlgorithm < 4) - mpicount = 1; - // Algorithm-Specific Fields for DSA signatures: - // - MPI of DSA value r. - // - MPI of DSA value s. - else if (publicKeyAlgorithm == 17) - mpicount = 2; - - var mpi = [], i = 0; - for (var j = 0; j < mpicount; j++) { - mpi[j] = new type_mpi(); - i += mpi[j].read(this.signature.substr(i)); - } - - this.verified = crypto.signature.verify(publicKeyAlgorithm, - hashAlgorithm, mpi, key.mpi, - bytes + this.signatureData + trailer); - - return this.verified; - } -} - - -},{"../crypto":14,"../enums.js":27,"../type/mpi.js":52,"../util":54,"./packet.js":37}],45:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var util = require('../util'), - crypto = require('../crypto'); - -/** - * @class - * @classdesc Implementation of the Sym. Encrypted Integrity Protected Data - * Packet (Tag 18) - * - * RFC4880 5.13: The Symmetrically Encrypted Integrity Protected Data packet is - * a variant of the Symmetrically Encrypted Data packet. It is a new feature - * created for OpenPGP that addresses the problem of detecting a modification to - * encrypted data. It is used in combination with a Modification Detection Code - * packet. - */ - -module.exports = function packet_sym_encrypted_integrity_protected() { - /** The encrypted payload. */ - this.encrypted = null; // string - /** @type {Boolean} - * If after decrypting the packet this is set to true, - * a modification has been detected and thus the contents - * should be discarded. - */ - this.modification = false; - this.packets; - - - this.read = function(bytes) { - // - A one-octet version number. The only currently defined value is - // 1. - var version = bytes[0].charCodeAt(); - - if (version != 1) { - throw new Error('Invalid packet version.'); - } - - // - Encrypted data, the output of the selected symmetric-key cipher - // operating in Cipher Feedback mode with shift amount equal to the - // block size of the cipher (CFB-n where n is the block size). - this.encrypted = bytes.substr(1); - } - - this.write = function() { - - return String.fromCharCode(1) // Version - + this.encrypted; - } - - this.encrypt = function(sessionKeyAlgorithm, key) { - var bytes = this.packets.write() - - var prefixrandom = crypto.getPrefixRandom(sessionKeyAlgorithm); - var prefix = prefixrandom - + prefixrandom.charAt(prefixrandom.length - 2) - + prefixrandom.charAt(prefixrandom.length - 1) - - var tohash = bytes; - - - // Modification detection code packet. - tohash += String.fromCharCode(0xD3); - tohash += String.fromCharCode(0x14); - - - tohash += crypto.hash.sha1(prefix + tohash); - - - this.encrypted = crypto.cfb.encrypt(prefixrandom, - sessionKeyAlgorithm, tohash, key, false).substring(0, - prefix.length + tohash.length); - } - - /** - * Decrypts the encrypted data contained in this object read_packet must - * have been called before - * - * @param {Integer} sessionKeyAlgorithm - * The selected symmetric encryption algorithm to be used - * @param {String} key The key of cipher blocksize length to be used - * @return {String} The decrypted data of this packet - */ - this.decrypt = function(sessionKeyAlgorithm, key) { - var decrypted = crypto.cfb.decrypt( - sessionKeyAlgorithm, key, this.encrypted, false); - - - // there must be a modification detection code packet as the - // last packet and everything gets hashed except the hash itself - this.hash = crypto.hash.sha1( - crypto.cfb.mdc(sessionKeyAlgorithm, key, this.encrypted) - + decrypted.substring(0, decrypted.length - 20)); - - - var mdc = decrypted.substr(decrypted.length - 20, 20); - - if(this.hash != mdc) { - throw new Error('Modification detected.'); - } - else - this.packets.read(decrypted.substr(0, decrypted.length - 22)); - } -}; - -},{"../crypto":14,"../util":54}],46:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var type_s2k = require('../type/s2k.js'), - enums = require('../enums.js'), - crypto = require('../crypto'); - -/** - * @class - * @classdesc Public-Key Encrypted Session Key Packets (Tag 1) - * - * RFC4880 5.1: A Public-Key Encrypted Session Key packet holds the session key - * used to encrypt a message. Zero or more Public-Key Encrypted Session Key - * packets and/or Symmetric-Key Encrypted Session Key packets may precede a - * Symmetrically Encrypted Data Packet, which holds an encrypted message. The - * message is encrypted with the session key, and the session key is itself - * encrypted and stored in the Encrypted Session Key packet(s). The - * Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted - * Session Key packet for each OpenPGP key to which the message is encrypted. - * The recipient of the message finds a session key that is encrypted to their - * public key, decrypts the session key, and then uses the session key to - * decrypt the message. - */ -module.exports = function packet_sym_encrypted_session_key() { - this.tag = 3; - this.sessionKeyEncryptionAlgorithm = null; - this.sessionKeyAlgorithm = 'aes256'; - this.encrypted = null; - this.s2k = new type_s2k(); - - /** - * Parsing function for a symmetric encrypted session key packet (tag 3). - * - * @param {String} input Payload of a tag 1 packet - * @param {Integer} position Position to start reading from the input string - * @param {Integer} len - * Length of the packet or the remaining length of - * input at position - * @return {openpgp_packet_encrypteddata} Object representation - */ - this.read = function(bytes) { - // A one-octet version number. The only currently defined version is 4. - this.version = bytes[0].charCodeAt(); - - // A one-octet number describing the symmetric algorithm used. - var algo = enums.read(enums.symmetric, bytes[1].charCodeAt()); - - // A string-to-key (S2K) specifier, length as defined above. - var s2klength = this.s2k.read(bytes.substr(2)); - - // Optionally, the encrypted session key itself, which is decrypted - // with the string-to-key object. - var done = s2klength + 2; - - if(done < bytes.length) { - this.encrypted = bytes.substr(done); - this.sessionKeyEncryptionAlgorithm = algo - } - else - this.sessionKeyAlgorithm = algo; - } - - this.write = function() { - var algo = this.encrypted == null ? - this.sessionKeyAlgorithm : - this.sessionKeyEncryptionAlgorithm; - - var bytes = String.fromCharCode(this.version) + - String.fromCharCode(enums.write(enums.symmetric, algo)) + - this.s2k.write(); - - if(this.encrypted != null) - bytes += this.encrypted; - return bytes; - } - - /** - * Decrypts the session key (only for public key encrypted session key - * packets (tag 1) - * - * @param {openpgp_msg_message} msg - * The message object (with member encryptedData - * @param {openpgp_msg_privatekey} key - * Private key with secMPIs unlocked - * @return {String} The unencrypted session key - */ - this.decrypt = function(passphrase) { - var algo = this.sessionKeyEncryptionAlgorithm != null ? - this.sessionKeyEncryptionAlgorithm : - this.sessionKeyAlgorithm; - - - var length = crypto.cipher[algo].keySize; - var key = this.s2k.produce_key(passphrase, length); - - if(this.encrypted == null) { - this.sessionKey = key; - - } else { - var decrypted = crypto.cfb.decrypt( - this.sessionKeyEncryptionAlgorithm, key, this.encrypted, true); - - this.sessionKeyAlgorithm = enums.read(enums.symmetric, - decrypted[0].keyCodeAt()); - - this.sessionKey = decrypted.substr(1); - } - } - - this.encrypt = function(passphrase) { - var length = crypto.getKeyLength(this.sessionKeyEncryptionAlgorithm); - var key = this.s2k.produce_key(passphrase, length); - - var private_key = String.fromCharCode( - enums.write(enums.symmetric, this.sessionKeyAlgorithm)) + - - crypto.getRandomBytes( - crypto.getKeyLength(this.sessionKeyAlgorithm)); - - this.encrypted = crypto.cfb.encrypt( - crypto.getPrefixRandom(this.sessionKeyEncryptionAlgorithm), - this.sessionKeyEncryptionAlgorithm, key, private_key, true); - } -}; - - -},{"../crypto":14,"../enums.js":27,"../type/s2k.js":53}],47:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var crypto = require('../crypto'); - -/** - * @class - * @classdesc Implementation of the Symmetrically Encrypted Data Packet (Tag 9) - * - * RFC4880 5.7: The Symmetrically Encrypted Data packet contains data encrypted - * with a symmetric-key algorithm. When it has been decrypted, it contains other - * packets (usually a literal data packet or compressed data packet, but in - * theory other Symmetrically Encrypted Data packets or sequences of packets - * that form whole OpenPGP messages). - */ - -module.exports = function packet_symmetrically_encrypted() { - this.encrypted = null; - /** Decrypted packets contained within. - * @type {openpgp_packetlist} */ - this.packets; - - this.read = function(bytes) { - this.encrypted = bytes; - } - - this.write = function() { - return this.encrypted; - } - - /** - * Symmetrically decrypt the packet data - * - * @param {Integer} sessionKeyAlgorithm - * Symmetric key algorithm to use // See RFC4880 9.2 - * @param {String} key - * Key as string with the corresponding length to the - * algorithm - * @return The decrypted data; - */ - this.decrypt = function(sessionKeyAlgorithm, key) { - var decrypted = crypto.cfb.decrypt( - sessionKeyAlgorithm, key, this.encrypted, true); - - this.packets.read(decrypted); - } - - this.encrypt = function(algo, key) { - var data = this.packets.write(); - - this.encrypted = crypto.cfb.encrypt( - crypto.getPrefixRandom(algo), algo, data, key, true); - } -}; - -},{"../crypto":14}],48:[function(require,module,exports){ - -module.exports = function packet_trust() { - -}; - -},{}],49:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -/** - * @class - * @classdesc Implementation of the User Attribute Packet (Tag 17) - * The User Attribute packet is a variation of the User ID packet. It - * is capable of storing more types of data than the User ID packet, - * which is limited to text. Like the User ID packet, a User Attribute - * packet may be certified by the key owner ("self-signed") or any other - * key owner who cares to certify it. Except as noted, a User Attribute - * packet may be used anywhere that a User ID packet may be used. - * - * While User Attribute packets are not a required part of the OpenPGP - * standard, implementations SHOULD provide at least enough - * compatibility to properly handle a certification signature on the - * User Attribute packet. A simple way to do this is by treating the - * User Attribute packet as a User ID packet with opaque contents, but - * an implementation may use any method desired. - */ -module.exports = function packet_user_attribute() { - this.tag = 17; - this.attributes = []; - - /** - * parsing function for a user attribute packet (tag 17). - * @param {String} input payload of a tag 17 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input at position - * @return {openpgp_packet_encrypteddata} object representation - */ - this.read = function(bytes) { - var i = 0; - while(i < bytes.length) { - var len = openpgp_packet.read_simple_length(bytes); - - i += len.offset; - this.attributes.push(bytes.substr(i, len.len)); - i += len.len; - } - } -}; - -},{}],50:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var util = require('../util'); - -/** - * @class - * @classdesc Implementation of the User ID Packet (Tag 13) - * A User ID packet consists of UTF-8 text that is intended to represent - * the name and email address of the key holder. By convention, it - * includes an RFC 2822 [RFC2822] mail name-addr, but there are no - * restrictions on its content. The packet length in the header - * specifies the length of the User ID. - */ -module.exports = function packet_userid() { - /** @type {String} A string containing the user id. Usually in the form - * John Doe - */ - this.userid = ''; - - - /** - * Parsing function for a user id packet (tag 13). - * @param {String} input payload of a tag 13 packet - * @param {Integer} position position to start reading from the input string - * @param {Integer} len length of the packet or the remaining length of input - * at position - * @return {openpgp_packet_encrypteddata} object representation - */ - this.read = function(bytes) { - this.userid = util.decode_utf8(bytes); - } - - /** - * Creates a string representation of the user id packet - * @param {String} user_id the user id as string ("John Doe > 4) + expbias); - } - - /** - * Parsing function for a string-to-key specifier (RFC 4880 3.7). - * @param {String} input Payload of string-to-key specifier - * @return {Integer} Actual length of the object - */ - this.read = function(bytes) { - var i = 0; - this.type = enums.read(enums.s2k, bytes[i++].charCodeAt()); - this.algorithm = enums.read(enums.hash, bytes[i++].charCodeAt()); - - switch (this.type) { - case 'simple': - break; - - case 'salted': - this.salt = bytes.substr(i, 8); - i += 8; - break; - - case 'iterated': - this.salt = bytes.substr(i, 8); - i += 8; - - // Octet 10: count, a one-octet, coded value - this.c = bytes[i++].charCodeAt(); - break; - - case 'gnu': - if(bytes.substr(i, 3) == "GNU") { - i += 3; // GNU - var gnuExtType = 1000 + bytes[i++].charCodeAt(); - if(gnuExtType == 1001) { - this.type = gnuExtType; - // GnuPG extension mode 1001 -- don't write secret key at all - } else { - throw new Error("Unknown s2k gnu protection mode."); - } - } else { - throw new Error("Unknown s2k type."); - } - break; - - default: - throw new Error("Unknown s2k type."); - break; - } - - return i; - } - - - /** - * writes an s2k hash based on the inputs. - * @return {String} Produced key of hashAlgorithm hash length - */ - this.write = function() { - var bytes = String.fromCharCode(enums.write(enums.s2k, this.type)); - bytes += String.fromCharCode(enums.write(enums.hash, this.algorithm)); - - switch(this.type) { - case 'simple': - break; - case 'salted': - bytes += this.salt; - break; - case 'iterated': - bytes += this.salt; - bytes += String.fromCharCode(this.c); - break; - }; - - return bytes; - } - - /** - * Produces a key using the specified passphrase and the defined - * hashAlgorithm - * @param {String} passphrase Passphrase containing user input - * @return {String} Produced key with a length corresponding to - * hashAlgorithm hash length - */ - this.produce_key = function(passphrase, numBytes) { - passphrase = util.encode_utf8(passphrase); - - function round(prefix, s2k) { - var algorithm = enums.write(enums.hash, s2k.algorithm); - - switch(s2k.type) { - case 'simple': - return crypto.hash.digest(algorithm, prefix + passphrase); - - case 'salted': - return crypto.hash.digest(algorithm, - prefix + s2k.salt + passphrase); - - case 'iterated': - var isp = [], - count = s2k.get_count(); - data = s2k.salt + passphrase; - - while (isp.length * data.length < count) - isp.push(data); - - isp = isp.join(''); - - if (isp.length > count) - isp = isp.substr(0, count); - - return crypto.hash.digest(algorithm, prefix + isp); - }; - } - - var result = '', - prefix = ''; - - while(result.length <= numBytes) { - result += round(prefix, this); - prefix += String.fromCharCode(0); - } - - return result.substr(0, numBytes); - } -} - - - -},{"../crypto":14,"../enums.js":27,"../util":54}],54:[function(require,module,exports){ -// GPG4Browsers - An OpenPGP implementation in javascript -// Copyright (C) 2011 Recurity Labs GmbH -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -var Util = function() { - - this.readNumber = function (bytes) { - var n = 0; - - for(var i = 0; i < bytes.length; i++) { - n <<= 8; - n += bytes[i].charCodeAt(); - } - - return n; - }; - - this.writeNumber = function(n, bytes) { - var b = ''; - for(var i = 0; i < bytes; i++) { - b += String.fromCharCode((n >> (8 * (bytes- i - 1))) & 0xFF); - } - - return b; - }; - - - - this.readDate = function(bytes) { - var n = this.readNumber(bytes); - var d = new Date(); - d.setTime(n * 1000); - return d; - }; - - this.writeDate = function(time) { - var numeric = Math.round(time.getTime() / 1000); - - return this.writeNumber(numeric, 4); - }; - - this.emailRegEx = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/; - - this.debug = false; - - this.hexdump = function(str) { - var r=[]; - var e=str.length; - var c=0; - var h; - var i = 0; - while(c' - * @param {String} str String of the debug message - * @return {String} An HTML tt entity containing a paragraph with a - * style attribute where the debug message is HTMLencoded in. - */ - this.print_debug = function(str) { - if (this.debug) { - console.log(str); - } - }; - - /** - * Helper function to print a debug message. Debug - * messages are only printed if - * openpgp.config.debug is set to true. The calling - * Javascript context MUST define - * a "showMessages(text)" function. Line feeds ('\n') - * are automatically converted to HTML line feeds '
' - * Different than print_debug because will call hexstrdump iff necessary. - * @param {String} str String of the debug message - * @return {String} An HTML tt entity containing a paragraph with a - * style attribute where the debug message is HTMLencoded in. - */ - this.print_debug_hexstr_dump = function(str,strToHex) { - if (this.debug) { - str = str + this.hexstrdump(strToHex); - console.log(str); - } - }; - - /** - * Helper function to print an error message. - * The calling Javascript context MUST define - * a "showMessages(text)" function. Line feeds ('\n') - * are automatically converted to HTML line feeds '
' - * @param {String} str String of the error message - * @return {String} A HTML paragraph entity with a style attribute - * containing the HTML encoded error message - */ - this.print_error = function(str) { - if(this.debug) - throw str; - console.log(str); - }; - - /** - * Helper function to print an info message. - * The calling Javascript context MUST define - * a "showMessages(text)" function. Line feeds ('\n') - * are automatically converted to HTML line feeds '
'. - * @param {String} str String of the info message - * @return {String} A HTML paragraph entity with a style attribute - * containing the HTML encoded info message - */ - this.print_info = function(str) { - if(this.debug) - console.log(str); - }; - - this.print_warning = function(str) { - console.log(str); - }; - - this.getLeftNBits = function (string, bitcount) { - var rest = bitcount % 8; - if (rest == 0) - return string.substring(0, bitcount / 8); - var bytes = (bitcount - rest) / 8 +1; - var result = string.substring(0, bytes); - return this.shiftRight(result, 8-rest); // +String.fromCharCode(string.charCodeAt(bytes -1) << (8-rest) & 0xFF); - }; - - /** - * Shifting a string to n bits right - * @param {String} value The string to shift - * @param {Integer} bitcount Amount of bits to shift (MUST be smaller - * than 9) - * @return {String} Resulting string. - */ - this.shiftRight = function(value, bitcount) { - var temp = util.str2bin(value); - if (bitcount % 8 != 0) { - for (var i = temp.length-1; i >= 0; i--) { - temp[i] >>= bitcount % 8; - if (i > 0) - temp[i] |= (temp[i - 1] << (8 - (bitcount % 8))) & 0xFF; - } - } else { - return value; - } - return util.bin2str(temp); - }; - - /** - * Return the algorithm type as string - * @return {String} String representing the message type - */ - this.get_hashAlgorithmString = function(algo) { - switch(algo) { - case 1: - return "MD5"; - case 2: - return "SHA1"; - case 3: - return "RIPEMD160"; - case 8: - return "SHA256"; - case 9: - return "SHA384"; - case 10: - return "SHA512"; - case 11: - return "SHA224"; - } - return "unknown"; - }; - -}; - -/** - * an instance that should be used. - */ -module.exports = new Util(); - -},{}],55:[function(require,module,exports){ -var unit = require('../../unit.js'); - -unit.register("AES Rijndael cipher test with test vectors from ecb_tbl.txt", function() { - var openpgp = require('../../../'); - var util = openpgp.util; - - var result = new Array(); - - function test_aes(input, key, output) { - var aes = new openpgp.cipher.aes128(util.bin2str(key)); - - var result = util.bin2str(aes.encrypt(input)); - - return util.hexstrdump(result) == util.hexstrdump(util.bin2str(output)); - }; - - var testvectors128 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12],[0x50,0x68,0x12,0xA4,0x5F,0x08,0xC8,0x89,0xB9,0x7F,0x59,0x80,0x03,0x8B,0x83,0x59],[0xD8,0xF5,0x32,0x53,0x82,0x89,0xEF,0x7D,0x06,0xB5,0x06,0xA4,0xFD,0x5B,0xE9,0xC9]], - [[0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26],[0x5C,0x6D,0x71,0xCA,0x30,0xDE,0x8B,0x8B,0x00,0x54,0x99,0x84,0xD2,0xEC,0x7D,0x4B],[0x59,0xAB,0x30,0xF4,0xD4,0xEE,0x6E,0x4F,0xF9,0x90,0x7E,0xF6,0x5B,0x1F,0xB6,0x8C]], - [[0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A],[0x53,0xF3,0xF4,0xC6,0x4F,0x86,0x16,0xE4,0xE7,0xC5,0x61,0x99,0xF4,0x8F,0x21,0xF6],[0xBF,0x1E,0xD2,0xFC,0xB2,0xAF,0x3F,0xD4,0x14,0x43,0xB5,0x6D,0x85,0x02,0x5C,0xB1]], - [[0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E],[0xA1,0xEB,0x65,0xA3,0x48,0x71,0x65,0xFB,0x0F,0x1C,0x27,0xFF,0x99,0x59,0xF7,0x03],[0x73,0x16,0x63,0x2D,0x5C,0x32,0x23,0x3E,0xDC,0xB0,0x78,0x05,0x60,0xEA,0xE8,0xB2]], - [[0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58,0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62],[0x35,0x53,0xEC,0xF0,0xB1,0x73,0x95,0x58,0xB0,0x8E,0x35,0x0A,0x98,0xA3,0x9B,0xFA],[0x40,0x8C,0x07,0x3E,0x3E,0x25,0x38,0x07,0x2B,0x72,0x62,0x5E,0x68,0xB8,0x36,0x4B]], - [[0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0x67,0x42,0x99,0x69,0x49,0x0B,0x97,0x11,0xAE,0x2B,0x01,0xDC,0x49,0x7A,0xFD,0xE8],[0xE1,0xF9,0x4D,0xFA,0x77,0x65,0x97,0xBE,0xAC,0xA2,0x62,0xF2,0xF6,0x36,0x6F,0xEA]], - [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A],[0x93,0x38,0x5C,0x1F,0x2A,0xEC,0x8B,0xED,0x19,0x2F,0x5A,0x8E,0x16,0x1D,0xD5,0x08],[0xF2,0x9E,0x98,0x6C,0x6A,0x1C,0x27,0xD7,0xB2,0x9F,0xFD,0x7E,0xE9,0x2B,0x75,0xF1]], - [[0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E],[0xB5,0xBF,0x94,0x6B,0xE1,0x9B,0xEB,0x8D,0xB3,0x98,0x3B,0x5F,0x4C,0x6E,0x8D,0xDB],[0x13,0x1C,0x88,0x6A,0x57,0xF8,0xC2,0xE7,0x13,0xAB,0xA6,0x95,0x5E,0x2B,0x55,0xB5]], - [[0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2],[0x41,0x32,0x1E,0xE1,0x0E,0x21,0xBD,0x90,0x72,0x27,0xC4,0x45,0x0F,0xF4,0x23,0x24],[0xD2,0xAB,0x76,0x62,0xDF,0x9B,0x8C,0x74,0x02,0x10,0xE5,0xEE,0xB6,0x1C,0x19,0x9D]], - [[0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6],[0x00,0xA8,0x2F,0x59,0xC9,0x1C,0x84,0x86,0xD1,0x2C,0x0A,0x80,0x12,0x4F,0x60,0x89],[0x14,0xC1,0x05,0x54,0xB2,0x85,0x9C,0x48,0x4C,0xAB,0x58,0x69,0xBB,0xE7,0xC4,0x70]], - [[0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0,0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA],[0x7C,0xE0,0xFD,0x07,0x67,0x54,0x69,0x1B,0x4B,0xBD,0x9F,0xAF,0x8A,0x13,0x72,0xFE],[0xDB,0x4D,0x49,0x8F,0x0A,0x49,0xCF,0x55,0x44,0x5D,0x50,0x2C,0x1F,0x9A,0xB3,0xB5]], - [[0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0x23,0x60,0x5A,0x82,0x43,0xD0,0x77,0x64,0x54,0x1B,0xC5,0xAD,0x35,0x5B,0x31,0x29],[0x6D,0x96,0xFE,0xF7,0xD6,0x65,0x90,0xA7,0x7A,0x77,0xBB,0x20,0x56,0x66,0x7F,0x7F]], - [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02],[0x12,0xA8,0xCF,0xA2,0x3E,0xA7,0x64,0xFD,0x87,0x62,0x32,0xB4,0xE8,0x42,0xBC,0x44],[0x31,0x6F,0xB6,0x8E,0xDB,0xA7,0x36,0xC5,0x3E,0x78,0x47,0x7B,0xF9,0x13,0x72,0x5C]], - [[0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16],[0xBC,0xAF,0x32,0x41,0x5E,0x83,0x08,0xB3,0x72,0x3E,0x5F,0xDD,0x85,0x3C,0xCC,0x80],[0x69,0x36,0xF2,0xB9,0x3A,0xF8,0x39,0x7F,0xD3,0xA7,0x71,0xFC,0x01,0x1C,0x8C,0x37]], - [[0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E],[0x89,0xAF,0xAE,0x68,0x5D,0x80,0x1A,0xD7,0x47,0xAC,0xE9,0x1F,0xC4,0x9A,0xDD,0xE0],[0xF3,0xF9,0x2F,0x7A,0x9C,0x59,0x17,0x9C,0x1F,0xCC,0x2C,0x2B,0xA0,0xB0,0x82,0xCD]]]; - - var testvectors192 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C],[0x2D,0x33,0xEE,0xF2,0xC0,0x43,0x0A,0x8A,0x9E,0xBF,0x45,0xE8,0x09,0xC4,0x0B,0xB6],[0xDF,0xF4,0x94,0x5E,0x03,0x36,0xDF,0x4C,0x1C,0x56,0xBC,0x70,0x0E,0xFF,0x83,0x7F]], - [[0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26,0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A],[0x6A,0xA3,0x75,0xD1,0xFA,0x15,0x5A,0x61,0xFB,0x72,0x35,0x3E,0x0A,0x5A,0x87,0x56],[0xB6,0xFD,0xDE,0xF4,0x75,0x27,0x65,0xE3,0x47,0xD5,0xD2,0xDC,0x19,0x6D,0x12,0x52]], - [[0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E,0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58],[0xBC,0x37,0x36,0x51,0x8B,0x94,0x90,0xDC,0xB8,0xED,0x60,0xEB,0x26,0x75,0x8E,0xD4],[0xD2,0x36,0x84,0xE3,0xD9,0x63,0xB3,0xAF,0xCF,0x1A,0x11,0x4A,0xCA,0x90,0xCB,0xD6]], - [[0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0xAA,0x21,0x44,0x02,0xB4,0x6C,0xFF,0xB9,0xF7,0x61,0xEC,0x11,0x26,0x3A,0x31,0x1E],[0x3A,0x7A,0xC0,0x27,0x75,0x3E,0x2A,0x18,0xC2,0xCE,0xAB,0x9E,0x17,0xC1,0x1F,0xD0]], - [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94],[0x02,0xAE,0xA8,0x6E,0x57,0x2E,0xEA,0xB6,0x6B,0x2C,0x3A,0xF5,0xE9,0xA4,0x6F,0xD6],[0x8F,0x67,0x86,0xBD,0x00,0x75,0x28,0xBA,0x26,0x60,0x3C,0x16,0x01,0xCD,0xD0,0xD8]], - [[0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E,0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2],[0xE2,0xAE,0xF6,0xAC,0xC3,0x3B,0x96,0x5C,0x4F,0xA1,0xF9,0x1C,0x75,0xFF,0x6F,0x36],[0xD1,0x7D,0x07,0x3B,0x01,0xE7,0x15,0x02,0xE2,0x8B,0x47,0xAB,0x55,0x11,0x68,0xB3]], - [[0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6,0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0],[0x06,0x59,0xDF,0x46,0x42,0x71,0x62,0xB9,0x43,0x48,0x65,0xDD,0x94,0x99,0xF9,0x1D],[0xA4,0x69,0xDA,0x51,0x71,0x19,0xFA,0xB9,0x58,0x76,0xF4,0x1D,0x06,0xD4,0x0F,0xFA]], - [[0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0x49,0xA4,0x42,0x39,0xC7,0x48,0xFE,0xB4,0x56,0xF5,0x9C,0x27,0x6A,0x56,0x58,0xDF],[0x60,0x91,0xAA,0x3B,0x69,0x5C,0x11,0xF5,0xC0,0xB6,0xAD,0x26,0xD3,0xD8,0x62,0xFF]], - [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02,0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C],[0x66,0x20,0x8F,0x6E,0x9D,0x04,0x52,0x5B,0xDE,0xDB,0x27,0x33,0xB6,0xA6,0xBE,0x37],[0x70,0xF9,0xE6,0x7F,0x9F,0x8D,0xF1,0x29,0x41,0x31,0x66,0x2D,0xC6,0xE6,0x93,0x64]], - [[0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16,0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20,0x22,0x23,0x24,0x25,0x27,0x28,0x29,0x2A],[0x33,0x93,0xF8,0xDF,0xC7,0x29,0xC9,0x7F,0x54,0x80,0xB9,0x50,0xBC,0x96,0x66,0xB0],[0xD1,0x54,0xDC,0xAF,0xAD,0x8B,0x20,0x7F,0xA5,0xCB,0xC9,0x5E,0x99,0x96,0xB5,0x59]], - [[0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E,0x40,0x41,0x42,0x43,0x45,0x46,0x47,0x48],[0x60,0x68,0x34,0xC8,0xCE,0x06,0x3F,0x32,0x34,0xCF,0x11,0x45,0x32,0x5D,0xBD,0x71],[0x49,0x34,0xD5,0x41,0xE8,0xB4,0x6F,0xA3,0x39,0xC8,0x05,0xA7,0xAE,0xB9,0xE5,0xDA]], - [[0x4A,0x4B,0x4C,0x4D,0x4F,0x50,0x51,0x52,0x54,0x55,0x56,0x57,0x59,0x5A,0x5B,0x5C,0x5E,0x5F,0x60,0x61,0x63,0x64,0x65,0x66],[0xFE,0xC1,0xC0,0x4F,0x52,0x9B,0xBD,0x17,0xD8,0xCE,0xCF,0xCC,0x47,0x18,0xB1,0x7F],[0x62,0x56,0x4C,0x73,0x8F,0x3E,0xFE,0x18,0x6E,0x1A,0x12,0x7A,0x0C,0x4D,0x3C,0x61]], - [[0x68,0x69,0x6A,0x6B,0x6D,0x6E,0x6F,0x70,0x72,0x73,0x74,0x75,0x77,0x78,0x79,0x7A,0x7C,0x7D,0x7E,0x7F,0x81,0x82,0x83,0x84],[0x32,0xDF,0x99,0xB4,0x31,0xED,0x5D,0xC5,0xAC,0xF8,0xCA,0xF6,0xDC,0x6C,0xE4,0x75],[0x07,0x80,0x5A,0xA0,0x43,0x98,0x6E,0xB2,0x36,0x93,0xE2,0x3B,0xEF,0x8F,0x34,0x38]], - [[0x86,0x87,0x88,0x89,0x8B,0x8C,0x8D,0x8E,0x90,0x91,0x92,0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,0x9D,0x9F,0xA0,0xA1,0xA2],[0x7F,0xDC,0x2B,0x74,0x6F,0x3F,0x66,0x52,0x96,0x94,0x3B,0x83,0x71,0x0D,0x1F,0x82],[0xDF,0x0B,0x49,0x31,0x03,0x8B,0xAD,0xE8,0x48,0xDE,0xE3,0xB4,0xB8,0x5A,0xA4,0x4B]], - [[0xA4,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,0xB1,0xB3,0xB4,0xB5,0xB6,0xB8,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0],[0x8F,0xBA,0x15,0x10,0xA3,0xC5,0xB8,0x7E,0x2E,0xAA,0x3F,0x7A,0x91,0x45,0x5C,0xA2],[0x59,0x2D,0x5F,0xDE,0xD7,0x65,0x82,0xE4,0x14,0x3C,0x65,0x09,0x93,0x09,0x47,0x7C]]]; - - var testvectors256 = [[[0x00,0x01,0x02,0x03,0x05,0x06,0x07,0x08,0x0A,0x0B,0x0C,0x0D,0x0F,0x10,0x11,0x12,0x14,0x15,0x16,0x17,0x19,0x1A,0x1B,0x1C,0x1E,0x1F,0x20,0x21,0x23,0x24,0x25,0x26],[0x83,0x4E,0xAD,0xFC,0xCA,0xC7,0xE1,0xB3,0x06,0x64,0xB1,0xAB,0xA4,0x48,0x15,0xAB],[0x19,0x46,0xDA,0xBF,0x6A,0x03,0xA2,0xA2,0xC3,0xD0,0xB0,0x50,0x80,0xAE,0xD6,0xFC]], - [[0x28,0x29,0x2A,0x2B,0x2D,0x2E,0x2F,0x30,0x32,0x33,0x34,0x35,0x37,0x38,0x39,0x3A,0x3C,0x3D,0x3E,0x3F,0x41,0x42,0x43,0x44,0x46,0x47,0x48,0x49,0x4B,0x4C,0x4D,0x4E],[0xD9,0xDC,0x4D,0xBA,0x30,0x21,0xB0,0x5D,0x67,0xC0,0x51,0x8F,0x72,0xB6,0x2B,0xF1],[0x5E,0xD3,0x01,0xD7,0x47,0xD3,0xCC,0x71,0x54,0x45,0xEB,0xDE,0xC6,0x2F,0x2F,0xB4]], - [[0x50,0x51,0x52,0x53,0x55,0x56,0x57,0x58,0x5A,0x5B,0x5C,0x5D,0x5F,0x60,0x61,0x62,0x64,0x65,0x66,0x67,0x69,0x6A,0x6B,0x6C,0x6E,0x6F,0x70,0x71,0x73,0x74,0x75,0x76],[0xA2,0x91,0xD8,0x63,0x01,0xA4,0xA7,0x39,0xF7,0x39,0x21,0x73,0xAA,0x3C,0x60,0x4C],[0x65,0x85,0xC8,0xF4,0x3D,0x13,0xA6,0xBE,0xAB,0x64,0x19,0xFC,0x59,0x35,0xB9,0xD0]], - [[0x78,0x79,0x7A,0x7B,0x7D,0x7E,0x7F,0x80,0x82,0x83,0x84,0x85,0x87,0x88,0x89,0x8A,0x8C,0x8D,0x8E,0x8F,0x91,0x92,0x93,0x94,0x96,0x97,0x98,0x99,0x9B,0x9C,0x9D,0x9E],[0x42,0x64,0xB2,0x69,0x64,0x98,0xDE,0x4D,0xF7,0x97,0x88,0xA9,0xF8,0x3E,0x93,0x90],[0x2A,0x5B,0x56,0xA5,0x96,0x68,0x0F,0xCC,0x0E,0x05,0xF5,0xE0,0xF1,0x51,0xEC,0xAE]], - [[0xA0,0xA1,0xA2,0xA3,0xA5,0xA6,0xA7,0xA8,0xAA,0xAB,0xAC,0xAD,0xAF,0xB0,0xB1,0xB2,0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,0xBE,0xBF,0xC0,0xC1,0xC3,0xC4,0xC5,0xC6],[0xEE,0x99,0x32,0xB3,0x72,0x18,0x04,0xD5,0xA8,0x3E,0xF5,0x94,0x92,0x45,0xB6,0xF6],[0xF5,0xD6,0xFF,0x41,0x4F,0xD2,0xC6,0x18,0x14,0x94,0xD2,0x0C,0x37,0xF2,0xB8,0xC4]], - [[0xC8,0xC9,0xCA,0xCB,0xCD,0xCE,0xCF,0xD0,0xD2,0xD3,0xD4,0xD5,0xD7,0xD8,0xD9,0xDA,0xDC,0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE6,0xE7,0xE8,0xE9,0xEB,0xEC,0xED,0xEE],[0xE6,0x24,0x8F,0x55,0xC5,0xFD,0xCB,0xCA,0x9C,0xBB,0xB0,0x1C,0x88,0xA2,0xEA,0x77],[0x85,0x39,0x9C,0x01,0xF5,0x9F,0xFF,0xB5,0x20,0x4F,0x19,0xF8,0x48,0x2F,0x00,0xB8]], - [[0xF0,0xF1,0xF2,0xF3,0xF5,0xF6,0xF7,0xF8,0xFA,0xFB,0xFC,0xFD,0xFE,0x01,0x00,0x02,0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16],[0xB8,0x35,0x8E,0x41,0xB9,0xDF,0xF6,0x5F,0xD4,0x61,0xD5,0x5A,0x99,0x26,0x62,0x47],[0x92,0x09,0x7B,0x4C,0x88,0xA0,0x41,0xDD,0xF9,0x81,0x44,0xBC,0x8D,0x22,0xE8,0xE7]], - [[0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20,0x22,0x23,0x24,0x25,0x27,0x28,0x29,0x2A,0x2C,0x2D,0x2E,0x2F,0x31,0x32,0x33,0x34,0x36,0x37,0x38,0x39,0x3B,0x3C,0x3D,0x3E],[0xF0,0xE2,0xD7,0x22,0x60,0xAF,0x58,0xE2,0x1E,0x01,0x5A,0xB3,0xA4,0xC0,0xD9,0x06],[0x89,0xBD,0x5B,0x73,0xB3,0x56,0xAB,0x41,0x2A,0xEF,0x9F,0x76,0xCE,0xA2,0xD6,0x5C]], - [[0x40,0x41,0x42,0x43,0x45,0x46,0x47,0x48,0x4A,0x4B,0x4C,0x4D,0x4F,0x50,0x51,0x52,0x54,0x55,0x56,0x57,0x59,0x5A,0x5B,0x5C,0x5E,0x5F,0x60,0x61,0x63,0x64,0x65,0x66],[0x47,0x5B,0x8B,0x82,0x3C,0xE8,0x89,0x3D,0xB3,0xC4,0x4A,0x9F,0x2A,0x37,0x9F,0xF7],[0x25,0x36,0x96,0x90,0x93,0xC5,0x5F,0xF9,0x45,0x46,0x92,0xF2,0xFA,0xC2,0xF5,0x30]], - [[0x68,0x69,0x6A,0x6B,0x6D,0x6E,0x6F,0x70,0x72,0x73,0x74,0x75,0x77,0x78,0x79,0x7A,0x7C,0x7D,0x7E,0x7F,0x81,0x82,0x83,0x84,0x86,0x87,0x88,0x89,0x8B,0x8C,0x8D,0x8E],[0x68,0x8F,0x52,0x81,0x94,0x58,0x12,0x86,0x2F,0x5F,0x30,0x76,0xCF,0x80,0x41,0x2F],[0x07,0xFC,0x76,0xA8,0x72,0x84,0x3F,0x3F,0x6E,0x00,0x81,0xEE,0x93,0x96,0xD6,0x37]], - [[0x90,0x91,0x92,0x93,0x95,0x96,0x97,0x98,0x9A,0x9B,0x9C,0x9D,0x9F,0xA0,0xA1,0xA2,0xA4,0xA5,0xA6,0xA7,0xA9,0xAA,0xAB,0xAC,0xAE,0xAF,0xB0,0xB1,0xB3,0xB4,0xB5,0xB6],[0x08,0xD1,0xD2,0xBC,0x75,0x0A,0xF5,0x53,0x36,0x5D,0x35,0xE7,0x5A,0xFA,0xCE,0xAA],[0xE3,0x8B,0xA8,0xEC,0x2A,0xA7,0x41,0x35,0x8D,0xCC,0x93,0xE8,0xF1,0x41,0xC4,0x91]], - [[0xB8,0xB9,0xBA,0xBB,0xBD,0xBE,0xBF,0xC0,0xC2,0xC3,0xC4,0xC5,0xC7,0xC8,0xC9,0xCA,0xCC,0xCD,0xCE,0xCF,0xD1,0xD2,0xD3,0xD4,0xD6,0xD7,0xD8,0xD9,0xDB,0xDC,0xDD,0xDE],[0x87,0x07,0x12,0x1F,0x47,0xCC,0x3E,0xFC,0xEC,0xA5,0xF9,0xA8,0x47,0x49,0x50,0xA1],[0xD0,0x28,0xEE,0x23,0xE4,0xA8,0x90,0x75,0xD0,0xB0,0x3E,0x86,0x8D,0x7D,0x3A,0x42]], - [[0xE0,0xE1,0xE2,0xE3,0xE5,0xE6,0xE7,0xE8,0xEA,0xEB,0xEC,0xED,0xEF,0xF0,0xF1,0xF2,0xF4,0xF5,0xF6,0xF7,0xF9,0xFA,0xFB,0xFC,0xFE,0xFE,0x01,0x01,0x03,0x04,0x05,0x06],[0xE5,0x1A,0xA0,0xB1,0x35,0xDB,0xA5,0x66,0x93,0x9C,0x3B,0x63,0x59,0xA9,0x80,0xC5],[0x8C,0xD9,0x42,0x3D,0xFC,0x45,0x9E,0x54,0x71,0x55,0xC5,0xD1,0xD5,0x22,0xE5,0x40]], - [[0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A,0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E],[0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21],[0x08,0x0E,0x95,0x17,0xEB,0x16,0x77,0x71,0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3]], - [[0x30,0x31,0x32,0x33,0x35,0x36,0x37,0x38,0x3A,0x3B,0x3C,0x3D,0x3F,0x40,0x41,0x42,0x44,0x45,0x46,0x47,0x49,0x4A,0x4B,0x4C,0x4E,0x4F,0x50,0x51,0x53,0x54,0x55,0x56],[0x72,0x61,0x65,0xC1,0x72,0x3F,0xBC,0xF6,0xC0,0x26,0xD7,0xD0,0x0B,0x09,0x10,0x27],[0x7C,0x17,0x00,0x21,0x1A,0x39,0x91,0xFC,0x0E,0xCD,0xED,0x0A,0xB3,0xE5,0x76,0xB0]]]; - - var res = true; - var j = 0; - for (var i = 0; i < testvectors128.length; i++) { - var res2 = test_aes(testvectors128[i][1],testvectors128[i][0],testvectors128[i][2]); - res &= res2; - if (!res2) { - result[j] = new unit.result("Testing 128 bit key vector with block "+ - util.hexidump(testvectors128[i][1])+ - " and key "+util.hexidump(testvectors128[i][0])+ - " should be "+util.hexidump(testvectors128[i][2]), - false); - j++; - } - } - if (res) { - result[j] = new unit.result("128 bit key test vectors completed.",true) - j++; - } - - res = true; - for (var i = 0; i < testvectors192.length; i++) { - var res2 = test_aes(testvectors192[i][1],testvectors192[i][0],testvectors192[i][2]); - res &= res2; - if (!res2) { - result[j] = new unit.result("Testing 192 bit key vector with block "+ - util.hexidump(testvectors192[i][1])+ - " and key "+util.hexidump(testvectors192[i][0])+ - " should be "+util.hexidump(testvectors192[i][2]), - false); - j++; - } - } - if (res) { - result[j] = new unit.result("192 bit key test vectors completed.",true) - j++; - } - - res = true; - for (var i = 0; i < testvectors256.length; i++) { - var res2 = test_aes(testvectors256[i][1],testvectors256[i][0],testvectors256[i][2]); - res &= res2; - if (!res2) { - result[j] = new unit.result("Testing 256 bit key vector with block "+ - util.hexidump(testvectors256[i][1])+ - " and key "+util.hexidump(testvectors256[i][0])+ - " should be "+util.hexidump(testvectors256[i][2]), - false); - j++; - } - } - if (res) { - result[j] = new unit.result("256 bit key test vectors completed.", true) - j++; - } - - return result; -}); - -},{"../../../":28,"../../unit.js":66}],56:[function(require,module,exports){ -var unit = require('../../unit.js'); - -unit.register("Blowfish cipher test with test vectors from http://www.schneier.com/code/vectors.txt", function() { - var openpgp = require('../../../'), - util = openpgp.util, - BFencrypt = openpgp.cipher.blowfish; - - var result = []; - function test_bf(input, key, output) { - var blowfish = new openpgp.cipher.blowfish(util.bin2str(key)); - var result = util.bin2str(blowfish.encrypt(input)); - - return (util.hexstrdump(result) == util.hexstrdump(util.bin2str(output))); - } - var testvectors = [[[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78]], - [[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x51,0x86,0x6F,0xD5,0xB8,0x5E,0xCB,0x8A]], - [[0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01],[0x7D,0x85,0x6F,0x9A,0x61,0x30,0x63,0xF2]], - [[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x24,0x66,0xDD,0x87,0x8B,0x96,0x3C,0x9D]], - [[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x61,0xF9,0xC3,0x80,0x22,0x81,0xB0,0x96]], - [[0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x7D,0x0C,0xC6,0x30,0xAF,0xDA,0x1E,0xC7]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78]], - [[0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x0A,0xCE,0xAB,0x0F,0xC6,0xA0,0xA2,0x8D]], - [[0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57],[0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42],[0x59,0xC6,0x82,0x45,0xEB,0x05,0x28,0x2B]], - [[0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E],[0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA],[0xB1,0xB8,0xCC,0x0B,0x25,0x0F,0x09,0xA0]], - [[0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86],[0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72],[0x17,0x30,0xE5,0x77,0x8B,0xEA,0x1D,0xA4]], - [[0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E],[0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A],[0xA2,0x5E,0x78,0x56,0xCF,0x26,0x51,0xEB]], - [[0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6],[0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2],[0x35,0x38,0x82,0xB1,0x09,0xCE,0x8F,0x1A]], - [[0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE],[0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A],[0x48,0xF4,0xD0,0x88,0x4C,0x37,0x99,0x18]], - [[0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6],[0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2],[0x43,0x21,0x93,0xB7,0x89,0x51,0xFC,0x98]], - [[0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE],[0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A],[0x13,0xF0,0x41,0x54,0xD6,0x9D,0x1A,0xE5]], - [[0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16],[0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02],[0x2E,0xED,0xDA,0x93,0xFF,0xD3,0x9C,0x79]], - [[0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F],[0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A],[0xD8,0x87,0xE0,0x39,0x3C,0x2D,0xA6,0xE3]], - [[0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46],[0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32],[0x5F,0x99,0xD0,0x4F,0x5B,0x16,0x39,0x69]], - [[0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E],[0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA],[0x4A,0x05,0x7A,0x3B,0x24,0xD3,0x97,0x7B]], - [[0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76],[0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62],[0x45,0x20,0x31,0xC1,0xE4,0xFA,0xDA,0x8E]], - [[0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07],[0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2],[0x75,0x55,0xAE,0x39,0xF5,0x9B,0x87,0xBD]], - [[0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F],[0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA],[0x53,0xC5,0x5F,0x9C,0xB4,0x9F,0xC0,0x19]], - [[0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7],[0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92],[0x7A,0x8E,0x7B,0xFA,0x93,0x7E,0x89,0xA3]], - [[0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF],[0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A],[0xCF,0x9C,0x5D,0x7A,0x49,0x86,0xAD,0xB5]], - [[0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6],[0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2],[0xD1,0xAB,0xB2,0x90,0x65,0x8B,0xC7,0x78]], - [[0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF],[0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A],[0x55,0xCB,0x37,0x74,0xD1,0x3E,0xF2,0x01]], - [[0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0xFA,0x34,0xEC,0x48,0x47,0xB2,0x68,0xB2]], - [[0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0xA7,0x90,0x79,0x51,0x08,0xEA,0x3C,0xAE]], - [[0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0xC3,0x9E,0x07,0x2D,0x9F,0xAC,0x63,0x1D]], - [[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x01,0x49,0x33,0xE0,0xCD,0xAF,0xF6,0xE4]], - [[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0xF2,0x1E,0x9A,0x77,0xB7,0x1C,0x49,0xBC]], - [[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x24,0x59,0x46,0x88,0x57,0x54,0x36,0x9A]], - [[0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10],[0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF],[0x6B,0x5C,0x5A,0x9C,0x5D,0x9E,0x0A,0x5A]]]; - - var res = true; - var j = 0; - for (var i = 0; i < testvectors.length; i++) { - var res2 = test_bf(testvectors[i][1],testvectors[i][0],testvectors[i][2]); - res &= res2; - if (!res2) { - result[j] = new unit.result("Testing vector "+i+" with block "+ - util.hexidump(testvectors[i][0])+ - " and key "+util.hexidump(testvectors[i][1])+ - " should be "+util.hexidump(testvectors[i][2]), false); - j++; - } - } - if (res) { - result[j] = new unit.result("34 test vectors completed ", true); - } - return result; -}); - -},{"../../../":28,"../../unit.js":66}],57:[function(require,module,exports){ -var unit = require('../../unit.js'); - -unit.register("CAST-128 cipher test with test vectors from RFC2144", function() { - var openpgp = require('../../../'), - util = openpgp.util; - - var result = []; - function test_cast(input, key, output) { - var cast5 = new openpgp.cipher.cast5(util.bin2str(key)); - var result = util.bin2str(cast5.encrypt(input)); - - return util.hexstrdump(result) == util.hexstrdump(util.bin2str(output)); - } - - var testvectors = [[[0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x23,0x8B,0x4F,0xE5,0x84,0x7E,0x44,0xB2]]]; - - for (var i = 0; i < testvectors.length; i++) { - result[i] = new unit.result("Testing vector with block "+ - util.hexidump(testvectors[i][0])+ - " and key "+util.hexidump(testvectors[i][1])+ - " should be "+util.hexidump(testvectors[i][2]), - test_cast(testvectors[i][1],testvectors[i][0],testvectors[i][2])); - } - return result; -}); - -},{"../../../":28,"../../unit.js":66}],58:[function(require,module,exports){ +},{"../../../":26,"../../unit.js":66}],57:[function(require,module,exports){ var unit = require('../../unit.js'); unit.register("Twofish test with test vectors from http://www.schneier.com/code/ecb_ival.txt", function() { @@ -12323,7 +12974,7 @@ unit.register("Twofish test with test vectors from http://www.schneier.com/code/ return result; }); -},{"../../../":28,"../../unit.js":66}],59:[function(require,module,exports){ +},{"../../../":26,"../../unit.js":66}],58:[function(require,module,exports){ var unit = require('../../unit.js'); unit.register("MD5 test with test vectors from RFC 1321", function() { @@ -12347,7 +12998,7 @@ unit.register("MD5 test with test vectors from RFC 1321", function() { return result; }); -},{"../../../":28,"../../unit.js":66}],60:[function(require,module,exports){ +},{"../../../":26,"../../unit.js":66}],59:[function(require,module,exports){ var unit = require('../../unit.js'); unit.register("RIPE-MD 160 bits test with test vectors from http://homes.esat.kuleuven.be/~bosselae/ripemd160.html", function() { @@ -12368,7 +13019,7 @@ unit.register("RIPE-MD 160 bits test with test vectors from http://homes.esat.ku return result; }); -},{"../../../":28,"../../unit.js":66}],61:[function(require,module,exports){ +},{"../../../":26,"../../unit.js":66}],60:[function(require,module,exports){ var unit = require('../../unit.js'); @@ -12402,7 +13053,7 @@ unit.register("SHA* test with test vectors from NIST FIPS 180-2", function() { return result; }); -},{"../../../":28,"../../unit.js":66}],62:[function(require,module,exports){ +},{"../../../":26,"../../unit.js":66}],61:[function(require,module,exports){ var unit = require('../unit.js'); unit.register("Functional testing of openpgp.crypto.* methods", function() { @@ -12674,7 +13325,7 @@ unit.register("Functional testing of openpgp.crypto.* methods", function() { return result; }); -},{"../../":28,"../unit.js":66}],63:[function(require,module,exports){ +},{"../../":26,"../unit.js":66}],62:[function(require,module,exports){ var unit = require('../unit.js'); unit.register("Testing of binary signature checking", function() { @@ -12847,7 +13498,7 @@ unit.register("Testing of binary signature checking", function() { }); -},{"../../":28,"../../src/openpgp.keyring.js":30,"../unit.js":66}],64:[function(require,module,exports){ +},{"../../":26,"../../src/openpgp.keyring.js":28,"../unit.js":66}],63:[function(require,module,exports){ var unit = require('../unit.js'); unit.register("Encryption/decryption", function() { @@ -12913,7 +13564,10 @@ unit.register("Encryption/decryption", function() { return result; }); -},{"../../":28,"../../src/openpgp.keyring.js":30,"../unit.js":66}],"2ZZCcm":[function(require,module,exports){ + +},{"../../":26,"../../src/openpgp.keyring.js":28,"../unit.js":66}],"test-bundle.js":[function(require,module,exports){ +module.exports=require('2ZZCcm'); +},{}],"2ZZCcm":[function(require,module,exports){ module.exports = require('./unit.js'); @@ -12932,7 +13586,7 @@ require('./crypto/openpgp.sigcheck.js'); require('./general/openpgp.basic.js'); -},{"./crypto/cipher/aes.js":55,"./crypto/cipher/blowfish.js":56,"./crypto/cipher/cast5.js":57,"./crypto/cipher/des.js":20,"./crypto/cipher/twofish.js":58,"./crypto/hash/md5.js":59,"./crypto/hash/ripemd.js":60,"./crypto/hash/sha.js":61,"./crypto/openpgp.crypto.js":62,"./crypto/openpgp.sigcheck.js":63,"./general/openpgp.basic.js":64,"./unit.js":66}],66:[function(require,module,exports){ +},{"./crypto/cipher/aes.js":53,"./crypto/cipher/blowfish.js":54,"./crypto/cipher/cast5.js":55,"./crypto/cipher/des.js":56,"./crypto/cipher/twofish.js":57,"./crypto/hash/md5.js":58,"./crypto/hash/ripemd.js":59,"./crypto/hash/sha.js":60,"./crypto/openpgp.crypto.js":61,"./crypto/openpgp.sigcheck.js":62,"./general/openpgp.basic.js":63,"./unit.js":66}],66:[function(require,module,exports){ var process=require("__browserify_process"); module.exports = { tests: [], @@ -13037,5 +13691,5 @@ process.chdir = function (dir) { }; },{}]},{},[]) -//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jb21wcmVzc2lvbi9qeGcuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vY2ZiLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL2NpcGhlci9hZXMuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vY2lwaGVyL2Jsb3dmaXNoLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL2NpcGhlci9jYXN0NS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9jaXBoZXIvZGVzLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL2NpcGhlci9pbmRleC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9jaXBoZXIvdHdvZmlzaC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9jcnlwdG8uanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vaGFzaC9pbmRleC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9oYXNoL21kNS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9oYXNoL3JpcGUtbWQuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vaGFzaC9zaGEuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vaW5kZXguanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vcGtjczEuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vcHVibGljX2tleS9kc2EuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vcHVibGljX2tleS9lbGdhbWFsLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvaW5kZXguanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vcHVibGljX2tleS9qc2JuLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC90ZXN0L2NyeXB0by9jaXBoZXIvZGVzLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvcnNhLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL3JhbmRvbS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9zaWduYXR1cmUuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9lbmNvZGluZy9hcm1vci5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2VuY29kaW5nL2Jhc2U2NC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2VudW1zLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvaW5kZXguanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9vcGVucGdwLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvb3BlbnBncC5rZXlyaW5nLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L2FsbF9wYWNrZXRzLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L2NvbXByZXNzZWQuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvaW5kZXguanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvbGl0ZXJhbC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3BhY2tldC9tYXJrZXIuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvb25lX3Bhc3Nfc2lnbmF0dXJlLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3BhY2tldC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3BhY2tldC9wYWNrZXRsaXN0LmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3B1YmxpY19rZXkuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvcHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvcHVibGljX3N1YmtleS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3BhY2tldC9zZWNyZXRfa2V5LmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3NlY3JldF9zdWJrZXkuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvc2lnbmF0dXJlLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3N5bV9lbmNyeXB0ZWRfaW50ZWdyaXR5X3Byb3RlY3RlZC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3BhY2tldC9zeW1fZW5jcnlwdGVkX3Nlc3Npb25fa2V5LmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3N5bW1ldHJpY2FsbHlfZW5jcnlwdGVkLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3RydXN0LmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3VzZXJfYXR0cmlidXRlLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3VzZXJpZC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3R5cGUva2V5aWQuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy90eXBlL21waS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3R5cGUvczJrLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvdXRpbC91dGlsLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC90ZXN0L2NyeXB0by9jaXBoZXIvYWVzLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC90ZXN0L2NyeXB0by9jaXBoZXIvYmxvd2Zpc2guanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3Rlc3QvY3J5cHRvL2NpcGhlci9jYXN0NS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvdGVzdC9jcnlwdG8vY2lwaGVyL3R3b2Zpc2guanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3Rlc3QvY3J5cHRvL2hhc2gvbWQ1LmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC90ZXN0L2NyeXB0by9oYXNoL3JpcGVtZC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvdGVzdC9jcnlwdG8vaGFzaC9zaGEuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3Rlc3QvY3J5cHRvL29wZW5wZ3AuY3J5cHRvLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC90ZXN0L2NyeXB0by9vcGVucGdwLnNpZ2NoZWNrLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC90ZXN0L2dlbmVyYWwvb3BlbnBncC5iYXNpYy5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvdGVzdC90ZXN0LWFsbC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvdGVzdC91bml0LmpzIiwiL3Vzci9sb2NhbC9zaGFyZS9ucG0vbGliL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9pbnNlcnQtbW9kdWxlLWdsb2JhbHMvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1c0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5ZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3aUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdlNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcnpDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3JLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM2VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0tBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0tBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzQ29udGVudCI6WyJKWEcgPSB7ZXhpc3RzOiAoZnVuY3Rpb24odW5kZWZpbmVkKXtyZXR1cm4gZnVuY3Rpb24odil7cmV0dXJuICEodj09PXVuZGVmaW5lZCB8fCB2PT09bnVsbCk7fX0pKCl9O1xuSlhHLmRlY29tcHJlc3MgPSBmdW5jdGlvbihzdHIpIHtyZXR1cm4gdW5lc2NhcGUoKG5ldyBKWEcuVXRpbC5VbnppcChKWEcuVXRpbC5CYXNlNjQuZGVjb2RlQXNBcnJheShzdHIpKSkudW56aXAoKVswXVswXSk7fTtcbi8qXG4gICAgQ29weXJpZ2h0IDIwMDgtMjAxMlxuICAgICAgICBNYXR0aGlhcyBFaG1hbm4sXG4gICAgICAgIE1pY2hhZWwgR2VyaGFldXNlcixcbiAgICAgICAgQ2Fyc3RlbiBNaWxsZXIsXG4gICAgICAgIEJpYW5jYSBWYWxlbnRpbixcbiAgICAgICAgQWxmcmVkIFdhc3Nlcm1hbm4sXG4gICAgICAgIFBldGVyIFdpbGZhaHJ0XG5cbiAgICBUaGlzIGZpbGUgaXMgcGFydCBvZiBKU1hHcmFwaC5cbiAgICBcbiAgICBEdWFsIGxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMCwgb3IgTEdQTCBWZXJzaW9uIDMgbGljZW5zZXMuXG5cbiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAgICBhbG9uZyB3aXRoIEpTWENvbXByZXNzb3IuICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gICAgXG4gICAgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgQXBhY2hlIExpY2Vuc2UgYWxvbmcgd2l0aCBKU1hDb21wcmVzc29yLiAgXG4gICAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy8+LlxuXG4qL1xuXG4vKipcbiAgKiBAY2xhc3MgVXRpbCBjbGFzc1xuICAqIEBjbGFzc2Rlc2MgVXRpbGl0aWVzIGZvciB1bmNvbXByZXNzaW5nIGFuZCBiYXNlNjQgZGVjb2RpbmdcbiAgKiBDbGFzcyBmb3IgZ3VuemlwcGluZywgdW56aXBwaW5nIGFuZCBiYXNlNjQgZGVjb2Rpbmcgb2YgZmlsZXMuXG4gICogSXQgaXMgdXNlZCBmb3IgcmVhZGluZyBHRU9ORXhULCBHZW9nZWJyYSBhbmQgSW50ZXJnZW8gZmlsZXMuXG4gICpcbiAgKiBPbmx5IEh1ZmZtYW4gY29kZXMgYXJlIGRlY29kZWQgaW4gZ3VuemlwLlxuICAqIFRoZSBjb2RlIGlzIGJhc2VkIG9uIHRoZSBzb3VyY2UgY29kZSBmb3IgZ3VuemlwLmMgYnkgUGFzaSBPamFsYSBcbiAgKiB7QGxpbmsgaHR0cDovL3d3dy5jcy50dXQuZmkvfmFsYmVydC9EZXYvZ3VuemlwL2d1bnppcC5jfVxuICAqIHtAbGluayBodHRwOi8vd3d3LmNzLnR1dC5maS9+YWxiZXJ0fVxuICAqL1xuSlhHLlV0aWwgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuLyoqXG4gKiBVbnppcCB6aXAgZmlsZXNcbiAqL1xuSlhHLlV0aWwuVW56aXAgPSBmdW5jdGlvbiAoYmFycmF5KXtcbiAgICB2YXIgb3V0cHV0QXJyID0gW10sXG4gICAgICAgIG91dHB1dCA9IFwiXCIsXG4gICAgICAgIGRlYnVnID0gZmFsc2UsXG4gICAgICAgIGdwZmxhZ3MsXG4gICAgICAgIGZpbGVzID0gMCxcbiAgICAgICAgdW56aXBwZWQgPSBbXSxcbiAgICAgICAgY3JjLFxuICAgICAgICBidWYzMmsgPSBuZXcgQXJyYXkoMzI3NjgpLFxuICAgICAgICBiSWR4ID0gMCxcbiAgICAgICAgbW9kZVpJUD1mYWxzZSxcblxuICAgICAgICBDUkMsIFNJWkUsXG4gICAgXG4gICAgICAgIGJpdFJldmVyc2UgPSBbXG4gICAgICAgIDB4MDAsIDB4ODAsIDB4NDAsIDB4YzAsIDB4MjAsIDB4YTAsIDB4NjAsIDB4ZTAsXG4gICAgICAgIDB4MTAsIDB4OTAsIDB4NTAsIDB4ZDAsIDB4MzAsIDB4YjAsIDB4NzAsIDB4ZjAsXG4gICAgICAgIDB4MDgsIDB4ODgsIDB4NDgsIDB4YzgsIDB4MjgsIDB4YTgsIDB4NjgsIDB4ZTgsXG4gICAgICAgIDB4MTgsIDB4OTgsIDB4NTgsIDB4ZDgsIDB4MzgsIDB4YjgsIDB4NzgsIDB4ZjgsXG4gICAgICAgIDB4MDQsIDB4ODQsIDB4NDQsIDB4YzQsIDB4MjQsIDB4YTQsIDB4NjQsIDB4ZTQsXG4gICAgICAgIDB4MTQsIDB4OTQsIDB4NTQsIDB4ZDQsIDB4MzQsIDB4YjQsIDB4NzQsIDB4ZjQsXG4gICAgICAgIDB4MGMsIDB4OGMsIDB4NGMsIDB4Y2MsIDB4MmMsIDB4YWMsIDB4NmMsIDB4ZWMsXG4gICAgICAgIDB4MWMsIDB4OWMsIDB4NWMsIDB4ZGMsIDB4M2MsIDB4YmMsIDB4N2MsIDB4ZmMsXG4gICAgICAgIDB4MDIsIDB4ODIsIDB4NDIsIDB4YzIsIDB4MjIsIDB4YTIsIDB4NjIsIDB4ZTIsXG4gICAgICAgIDB4MTIsIDB4OTIsIDB4NTIsIDB4ZDIsIDB4MzIsIDB4YjIsIDB4NzIsIDB4ZjIsXG4gICAgICAgIDB4MGEsIDB4OGEsIDB4NGEsIDB4Y2EsIDB4MmEsIDB4YWEsIDB4NmEsIDB4ZWEsXG4gICAgICAgIDB4MWEsIDB4OWEsIDB4NWEsIDB4ZGEsIDB4M2EsIDB4YmEsIDB4N2EsIDB4ZmEsXG4gICAgICAgIDB4MDYsIDB4ODYsIDB4NDYsIDB4YzYsIDB4MjYsIDB4YTYsIDB4NjYsIDB4ZTYsXG4gICAgICAgIDB4MTYsIDB4OTYsIDB4NTYsIDB4ZDYsIDB4MzYsIDB4YjYsIDB4NzYsIDB4ZjYsXG4gICAgICAgIDB4MGUsIDB4OGUsIDB4NGUsIDB4Y2UsIDB4MmUsIDB4YWUsIDB4NmUsIDB4ZWUsXG4gICAgICAgIDB4MWUsIDB4OWUsIDB4NWUsIDB4ZGUsIDB4M2UsIDB4YmUsIDB4N2UsIDB4ZmUsXG4gICAgICAgIDB4MDEsIDB4ODEsIDB4NDEsIDB4YzEsIDB4MjEsIDB4YTEsIDB4NjEsIDB4ZTEsXG4gICAgICAgIDB4MTEsIDB4OTEsIDB4NTEsIDB4ZDEsIDB4MzEsIDB4YjEsIDB4NzEsIDB4ZjEsXG4gICAgICAgIDB4MDksIDB4ODksIDB4NDksIDB4YzksIDB4MjksIDB4YTksIDB4NjksIDB4ZTksXG4gICAgICAgIDB4MTksIDB4OTksIDB4NTksIDB4ZDksIDB4MzksIDB4YjksIDB4NzksIDB4ZjksXG4gICAgICAgIDB4MDUsIDB4ODUsIDB4NDUsIDB4YzUsIDB4MjUsIDB4YTUsIDB4NjUsIDB4ZTUsXG4gICAgICAgIDB4MTUsIDB4OTUsIDB4NTUsIDB4ZDUsIDB4MzUsIDB4YjUsIDB4NzUsIDB4ZjUsXG4gICAgICAgIDB4MGQsIDB4OGQsIDB4NGQsIDB4Y2QsIDB4MmQsIDB4YWQsIDB4NmQsIDB4ZWQsXG4gICAgICAgIDB4MWQsIDB4OWQsIDB4NWQsIDB4ZGQsIDB4M2QsIDB4YmQsIDB4N2QsIDB4ZmQsXG4gICAgICAgIDB4MDMsIDB4ODMsIDB4NDMsIDB4YzMsIDB4MjMsIDB4YTMsIDB4NjMsIDB4ZTMsXG4gICAgICAgIDB4MTMsIDB4OTMsIDB4NTMsIDB4ZDMsIDB4MzMsIDB4YjMsIDB4NzMsIDB4ZjMsXG4gICAgICAgIDB4MGIsIDB4OGIsIDB4NGIsIDB4Y2IsIDB4MmIsIDB4YWIsIDB4NmIsIDB4ZWIsXG4gICAgICAgIDB4MWIsIDB4OWIsIDB4NWIsIDB4ZGIsIDB4M2IsIDB4YmIsIDB4N2IsIDB4ZmIsXG4gICAgICAgIDB4MDcsIDB4ODcsIDB4NDcsIDB4YzcsIDB4MjcsIDB4YTcsIDB4NjcsIDB4ZTcsXG4gICAgICAgIDB4MTcsIDB4OTcsIDB4NTcsIDB4ZDcsIDB4MzcsIDB4YjcsIDB4NzcsIDB4ZjcsXG4gICAgICAgIDB4MGYsIDB4OGYsIDB4NGYsIDB4Y2YsIDB4MmYsIDB4YWYsIDB4NmYsIDB4ZWYsXG4gICAgICAgIDB4MWYsIDB4OWYsIDB4NWYsIDB4ZGYsIDB4M2YsIDB4YmYsIDB4N2YsIDB4ZmZcbiAgICBdLFxuICAgIFxuICAgIGNwbGVucyA9IFtcbiAgICAgICAgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMywgMTUsIDE3LCAxOSwgMjMsIDI3LCAzMSxcbiAgICAgICAgMzUsIDQzLCA1MSwgNTksIDY3LCA4MywgOTksIDExNSwgMTMxLCAxNjMsIDE5NSwgMjI3LCAyNTgsIDAsIDBcbiAgICBdLFxuXG4gICAgY3BsZXh0ID0gW1xuICAgICAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAyLCAyLCAyLCAyLFxuICAgICAgICAzLCAzLCAzLCAzLCA0LCA0LCA0LCA0LCA1LCA1LCA1LCA1LCAwLCA5OSwgOTlcbiAgICBdLCAvKiA5OT09aW52YWxpZCAqL1xuXG4gICAgY3BkaXN0ID0gW1xuICAgICAgICAweDAwMDEsIDB4MDAwMiwgMHgwMDAzLCAweDAwMDQsIDB4MDAwNSwgMHgwMDA3LCAweDAwMDksIDB4MDAwZCxcbiAgICAgICAgMHgwMDExLCAweDAwMTksIDB4MDAyMSwgMHgwMDMxLCAweDAwNDEsIDB4MDA2MSwgMHgwMDgxLCAweDAwYzEsXG4gICAgICAgIDB4MDEwMSwgMHgwMTgxLCAweDAyMDEsIDB4MDMwMSwgMHgwNDAxLCAweDA2MDEsIDB4MDgwMSwgMHgwYzAxLFxuICAgICAgICAweDEwMDEsIDB4MTgwMSwgMHgyMDAxLCAweDMwMDEsIDB4NDAwMSwgMHg2MDAxXG4gICAgXSxcblxuICAgIGNwZGV4dCA9IFtcbiAgICAgICAgMCwgIDAsICAwLCAgMCwgIDEsICAxLCAgMiwgIDIsXG4gICAgICAgIDMsICAzLCAgNCwgIDQsICA1LCAgNSwgIDYsICA2LFxuICAgICAgICA3LCAgNywgIDgsICA4LCAgOSwgIDksIDEwLCAxMCxcbiAgICAgICAgMTEsIDExLCAxMiwgMTIsIDEzLCAxM1xuICAgIF0sXG4gICAgXG4gICAgYm9yZGVyID0gWzE2LCAxNywgMTgsIDAsIDgsIDcsIDksIDYsIDEwLCA1LCAxMSwgNCwgMTIsIDMsIDEzLCAyLCAxNCwgMSwgMTVdLFxuICAgIFxuICAgIGJBID0gYmFycmF5LFxuXG4gICAgYnl0ZXBvcz0wLFxuICAgIGJpdHBvcz0wLFxuICAgIGJiID0gMSxcbiAgICBiaXRzPTAsXG4gICAgXG4gICAgTkFNRU1BWCA9IDI1NixcbiAgICBcbiAgICBuYW1lQnVmID0gW10sXG4gICAgXG4gICAgZmlsZW91dDtcbiAgICBcbiAgICBmdW5jdGlvbiByZWFkQnl0ZSgpe1xuICAgICAgICBiaXRzKz04O1xuICAgICAgICBpZiAoYnl0ZXBvczxiQS5sZW5ndGgpe1xuICAgICAgICAgICAgLy9pZiAoZGVidWcpXG4gICAgICAgICAgICAvLyAgICBkb2N1bWVudC53cml0ZShieXRlcG9zK1wiOiBcIitiQVtieXRlcG9zXStcIjxicj5cIik7XG4gICAgICAgICAgICByZXR1cm4gYkFbYnl0ZXBvcysrXTtcbiAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGJ5dGVBbGlnbigpe1xuICAgICAgICBiYiA9IDE7XG4gICAgfTtcbiAgICBcbiAgICBmdW5jdGlvbiByZWFkQml0KCl7XG4gICAgICAgIHZhciBjYXJyeTtcbiAgICAgICAgYml0cysrO1xuICAgICAgICBjYXJyeSA9IChiYiAmIDEpO1xuICAgICAgICBiYiA+Pj0gMTtcbiAgICAgICAgaWYgKGJiPT0wKXtcbiAgICAgICAgICAgIGJiID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgICAgIGNhcnJ5ID0gKGJiICYgMSk7XG4gICAgICAgICAgICBiYiA9IChiYj4+MSkgfCAweDgwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYXJyeTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcmVhZEJpdHMoYSkge1xuICAgICAgICB2YXIgcmVzID0gMCxcbiAgICAgICAgICAgIGkgPSBhO1xuICAgIFxuICAgICAgICB3aGlsZShpLS0pIHtcbiAgICAgICAgICAgIHJlcyA9IChyZXM8PDEpIHwgcmVhZEJpdCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmKGEpIHtcbiAgICAgICAgICAgIHJlcyA9IGJpdFJldmVyc2VbcmVzXT4+KDgtYSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9O1xuICAgICAgICBcbiAgICBmdW5jdGlvbiBmbHVzaEJ1ZmZlcigpe1xuICAgICAgICAvL2RvY3VtZW50LndyaXRlKCdGTFVTSEJVRkZFUjonK2J1ZjMyayk7XG4gICAgICAgIGJJZHggPSAwO1xuICAgIH07XG4gICAgZnVuY3Rpb24gYWRkQnVmZmVyKGEpe1xuICAgICAgICBTSVpFKys7XG4gICAgICAgIC8vQ1JDPXVwZGNyYyhhLGNyYyk7XG4gICAgICAgIGJ1ZjMya1tiSWR4KytdID0gYTtcbiAgICAgICAgb3V0cHV0QXJyLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShhKSk7XG4gICAgICAgIC8vb3V0cHV0Kz1TdHJpbmcuZnJvbUNoYXJDb2RlKGEpO1xuICAgICAgICBpZihiSWR4PT0weDgwMDApe1xuICAgICAgICAgICAgLy9kb2N1bWVudC53cml0ZSgnQUREQlVGRkVSOicrYnVmMzJrKTtcbiAgICAgICAgICAgIGJJZHg9MDtcbiAgICAgICAgfVxuICAgIH07XG4gICAgXG4gICAgZnVuY3Rpb24gSHVmTm9kZSgpIHtcbiAgICAgICAgdGhpcy5iMD0wO1xuICAgICAgICB0aGlzLmIxPTA7XG4gICAgICAgIHRoaXMuanVtcCA9IG51bGw7XG4gICAgICAgIHRoaXMuanVtcHBvcyA9IC0xO1xuICAgIH07XG5cbiAgICB2YXIgTElURVJBTFMgPSAyODg7XG4gICAgXG4gICAgdmFyIGxpdGVyYWxUcmVlID0gbmV3IEFycmF5KExJVEVSQUxTKTtcbiAgICB2YXIgZGlzdGFuY2VUcmVlID0gbmV3IEFycmF5KDMyKTtcbiAgICB2YXIgdHJlZXBvcz0wO1xuICAgIHZhciBQbGFjZXMgPSBudWxsO1xuICAgIHZhciBQbGFjZXMyID0gbnVsbDtcbiAgICBcbiAgICB2YXIgaW1wRGlzdGFuY2VUcmVlID0gbmV3IEFycmF5KDY0KTtcbiAgICB2YXIgaW1wTGVuZ3RoVHJlZSA9IG5ldyBBcnJheSg2NCk7XG4gICAgXG4gICAgdmFyIGxlbiA9IDA7XG4gICAgdmFyIGZwb3MgPSBuZXcgQXJyYXkoMTcpO1xuICAgIGZwb3NbMF09MDtcbiAgICB2YXIgZmxlbnM7XG4gICAgdmFyIGZtYXg7XG4gICAgXG4gICAgZnVuY3Rpb24gSXNQYXQoKSB7XG4gICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBpZiAoZnBvc1tsZW5dID49IGZtYXgpXG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgICAgaWYgKGZsZW5zW2Zwb3NbbGVuXV0gPT0gbGVuKVxuICAgICAgICAgICAgICAgIHJldHVybiBmcG9zW2xlbl0rKztcbiAgICAgICAgICAgIGZwb3NbbGVuXSsrO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIFJlYygpIHtcbiAgICAgICAgdmFyIGN1cnBsYWNlID0gUGxhY2VzW3RyZWVwb3NdO1xuICAgICAgICB2YXIgdG1wO1xuICAgICAgICBpZiAoZGVidWcpXG4gICAgXHRcdGRvY3VtZW50LndyaXRlKFwiPGJyPmxlbjpcIitsZW4rXCIgdHJlZXBvczpcIit0cmVlcG9zKTtcbiAgICAgICAgaWYobGVuPT0xNykgeyAvL3dhciAxN1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICAgIHRyZWVwb3MrKztcbiAgICAgICAgbGVuKys7XG4gICAgXHRcbiAgICAgICAgdG1wID0gSXNQYXQoKTtcbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBcdGRvY3VtZW50LndyaXRlKFwiPGJyPklzUGF0IFwiK3RtcCk7XG4gICAgICAgIGlmKHRtcCA+PSAwKSB7XG4gICAgICAgICAgICBjdXJwbGFjZS5iMCA9IHRtcDsgICAgLyogbGVhZiBjZWxsIGZvciAwLWJpdCAqL1xuICAgICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgXHRkb2N1bWVudC53cml0ZShcIjxicj5iMCBcIitjdXJwbGFjZS5iMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8qIE5vdCBhIExlYWYgY2VsbCAqL1xuICAgICAgICBjdXJwbGFjZS5iMCA9IDB4ODAwMDtcbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBcdGRvY3VtZW50LndyaXRlKFwiPGJyPmIwIFwiK2N1cnBsYWNlLmIwKTtcbiAgICAgICAgaWYoUmVjKCkpXG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgICAgdG1wID0gSXNQYXQoKTtcbiAgICAgICAgaWYodG1wID49IDApIHtcbiAgICAgICAgICAgIGN1cnBsYWNlLmIxID0gdG1wOyAgICAvKiBsZWFmIGNlbGwgZm9yIDEtYml0ICovXG4gICAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBcdGRvY3VtZW50LndyaXRlKFwiPGJyPmIxIFwiK2N1cnBsYWNlLmIxKTtcbiAgICAgICAgICAgIGN1cnBsYWNlLmp1bXAgPSBudWxsOyAgICAvKiBKdXN0IGZvciB0aGUgZGlzcGxheSByb3V0aW5lICovXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvKiBOb3QgYSBMZWFmIGNlbGwgKi9cbiAgICAgICAgICAgIGN1cnBsYWNlLmIxID0gMHg4MDAwO1xuICAgICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgXHRkb2N1bWVudC53cml0ZShcIjxicj5iMSBcIitjdXJwbGFjZS5iMSk7XG4gICAgICAgICAgICBjdXJwbGFjZS5qdW1wID0gUGxhY2VzW3RyZWVwb3NdO1xuICAgICAgICAgICAgY3VycGxhY2UuanVtcHBvcyA9IHRyZWVwb3M7XG4gICAgICAgICAgICBpZihSZWMoKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgICAgbGVuLS07XG4gICAgICAgIHJldHVybiAwO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBDcmVhdGVUcmVlKGN1cnJlbnRUcmVlLCBudW12YWwsIGxlbmd0aHMsIHNob3cpIHtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIC8qIENyZWF0ZSB0aGUgSHVmZm1hbiBkZWNvZGUgdHJlZS90YWJsZSAqL1xuICAgICAgICAvL2RvY3VtZW50LndyaXRlKFwiPGJyPmNyZWF0ZXRyZWU8YnI+XCIpO1xuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgIFx0ZG9jdW1lbnQud3JpdGUoXCJjdXJyZW50VHJlZSBcIitjdXJyZW50VHJlZStcIiBudW12YWwgXCIrbnVtdmFsK1wiIGxlbmd0aHMgXCIrbGVuZ3RocytcIiBzaG93IFwiK3Nob3cpO1xuICAgICAgICBQbGFjZXMgPSBjdXJyZW50VHJlZTtcbiAgICAgICAgdHJlZXBvcz0wO1xuICAgICAgICBmbGVucyA9IGxlbmd0aHM7XG4gICAgICAgIGZtYXggID0gbnVtdmFsO1xuICAgICAgICBmb3IgKGk9MDtpPDE3O2krKylcbiAgICAgICAgICAgIGZwb3NbaV0gPSAwO1xuICAgICAgICBsZW4gPSAwO1xuICAgICAgICBpZihSZWMoKSkge1xuICAgICAgICAgICAgLy9mcHJpbnRmKHN0ZGVyciwgXCJpbnZhbGlkIGh1ZmZtYW4gdHJlZVxcblwiKTtcbiAgICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIFx0YWxlcnQoXCJpbnZhbGlkIGh1ZmZtYW4gdHJlZVxcblwiKTtcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVidWcpe1xuICAgICAgICBcdGRvY3VtZW50LndyaXRlKCc8YnI+VHJlZTogJytQbGFjZXMubGVuZ3RoKTtcbiAgICAgICAgXHRmb3IgKHZhciBhPTA7YTwzMjthKyspe1xuICAgICAgICAgICAgXHRkb2N1bWVudC53cml0ZShcIlBsYWNlc1tcIithK1wiXS5iMD1cIitQbGFjZXNbYV0uYjArXCI8YnI+XCIpO1xuICAgICAgICAgICAgXHRkb2N1bWVudC53cml0ZShcIlBsYWNlc1tcIithK1wiXS5iMT1cIitQbGFjZXNbYV0uYjErXCI8YnI+XCIpO1xuICAgICAgICBcdH1cbiAgICAgICAgfVxuICAgIFxuICAgICAgICAvKmlmKHNob3cpIHtcbiAgICAgICAgICAgIHZhciB0bXA7XG4gICAgICAgICAgICBmb3IodG1wPWN1cnJlbnRUcmVlO3RtcDxQbGFjZXM7dG1wKyspIHtcbiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgXCIweCUwM3ggIDB4JTAzeCAoMHglMDR4KVwiLHRtcC1jdXJyZW50VHJlZSwgdG1wLT5qdW1wP3RtcC0+anVtcC1jdXJyZW50VHJlZTowLCh0bXAtPmp1bXA/dG1wLT5qdW1wLWN1cnJlbnRUcmVlOjApKjYrMHhjZjApO1xuICAgICAgICAgICAgICAgIGlmKCEodG1wLmIwICYgMHg4MDAwKSkge1xuICAgICAgICAgICAgICAgICAgICAvL2ZwcmludGYoc3Rkb3V0LCBcIiAgMHglMDN4ICglYylcIiwgdG1wLT5iMCwodG1wLT5iMDwyNTYgJiYgaXNwcmludCh0bXAtPmIwKSk/dG1wLT5iMDon77+9Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmKCEodG1wLmIxICYgMHg4MDAwKSkge1xuICAgICAgICAgICAgICAgICAgICBpZigodG1wLmIwICYgMHg4MDAwKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCBcIiAgICAgICAgICAgXCIpO1xuICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgXCIgIDB4JTAzeCAoJWMpXCIsIHRtcC0+YjEsKHRtcC0+YjE8MjU2ICYmIGlzcHJpbnQodG1wLT5iMSkpP3RtcC0+YjE6J++/vScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgXCJcXG5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0qL1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9O1xuICAgIFxuICAgIGZ1bmN0aW9uIERlY29kZVZhbHVlKGN1cnJlbnRUcmVlKSB7XG4gICAgICAgIHZhciBsZW4sIGksXG4gICAgICAgICAgICB4dHJlZXBvcz0wLFxuICAgICAgICAgICAgWCA9IGN1cnJlbnRUcmVlW3h0cmVlcG9zXSxcbiAgICAgICAgICAgIGI7XG5cbiAgICAgICAgLyogZGVjb2RlIG9uZSBzeW1ib2wgb2YgdGhlIGRhdGEgKi9cbiAgICAgICAgd2hpbGUoMSkge1xuICAgICAgICAgICAgYj1yZWFkQml0KCk7XG4gICAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBcdGRvY3VtZW50LndyaXRlKFwiYj1cIitiKTtcbiAgICAgICAgICAgIGlmKGIpIHtcbiAgICAgICAgICAgICAgICBpZighKFguYjEgJiAweDgwMDApKXtcbiAgICAgICAgICAgICAgICBcdGlmIChkZWJ1ZylcbiAgICAgICAgICAgICAgICAgICAgXHRkb2N1bWVudC53cml0ZShcInJldDFcIik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBYLmIxOyAgICAvKiBJZiBsZWFmIG5vZGUsIHJldHVybiBkYXRhICovXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIFggPSBYLmp1bXA7XG4gICAgICAgICAgICAgICAgbGVuID0gY3VycmVudFRyZWUubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGZvciAoaT0wO2k8bGVuO2krKyl7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50VHJlZVtpXT09PVgpe1xuICAgICAgICAgICAgICAgICAgICAgICAgeHRyZWVwb3M9aTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8veHRyZWVwb3MrKztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYoIShYLmIwICYgMHg4MDAwKSl7XG4gICAgICAgICAgICAgICAgXHRpZiAoZGVidWcpXG4gICAgICAgICAgICAgICAgICAgIFx0ZG9jdW1lbnQud3JpdGUoXCJyZXQyXCIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gWC5iMDsgICAgLyogSWYgbGVhZiBub2RlLCByZXR1cm4gZGF0YSAqL1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvL1grKzsgLy8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz9cbiAgICAgICAgICAgICAgICB4dHJlZXBvcysrO1xuICAgICAgICAgICAgICAgIFggPSBjdXJyZW50VHJlZVt4dHJlZXBvc107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBcdGRvY3VtZW50LndyaXRlKFwicmV0M1wiKTtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH07XG4gICAgXG4gICAgZnVuY3Rpb24gRGVmbGF0ZUxvb3AoKSB7XG4gICAgdmFyIGxhc3QsIGMsIHR5cGUsIGksIGxlbjtcblxuICAgIGRvIHtcbiAgICAgICAgLyppZigobGFzdCA9IHJlYWRCaXQoKSkpe1xuICAgICAgICAgICAgZnByaW50ZihlcnJmcCwgXCJMYXN0IEJsb2NrOiBcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmcHJpbnRmKGVycmZwLCBcIk5vdCBMYXN0IEJsb2NrOiBcIik7XG4gICAgICAgIH0qL1xuICAgICAgICBsYXN0ID0gcmVhZEJpdCgpO1xuICAgICAgICB0eXBlID0gcmVhZEJpdHMoMik7XG4gICAgICAgIHN3aXRjaCh0eXBlKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICBcdGlmIChkZWJ1ZylcbiAgICAgICAgICAgICAgICBcdGFsZXJ0KFwiU3RvcmVkXFxuXCIpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgXHRpZiAoZGVidWcpXG4gICAgICAgICAgICAgICAgXHRhbGVydChcIkZpeGVkIEh1ZmZtYW4gY29kZXNcXG5cIik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICBcdGlmIChkZWJ1ZylcbiAgICAgICAgICAgICAgICBcdGFsZXJ0KFwiRHluYW1pYyBIdWZmbWFuIGNvZGVzXFxuXCIpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgXHRpZiAoZGVidWcpXG4gICAgICAgICAgICAgICAgXHRhbGVydChcIlJlc2VydmVkIGJsb2NrIHR5cGUhIVxcblwiKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBcdGlmIChkZWJ1ZylcbiAgICAgICAgICAgICAgICBcdGFsZXJ0KFwiVW5leHBlY3RlZCB2YWx1ZSAlZCFcXG5cIiwgdHlwZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZih0eXBlPT0wKSB7XG4gICAgICAgICAgICB2YXIgYmxvY2tMZW4sIGNTdW07XG5cbiAgICAgICAgICAgIC8vIFN0b3JlZCBcbiAgICAgICAgICAgIGJ5dGVBbGlnbigpO1xuICAgICAgICAgICAgYmxvY2tMZW4gPSByZWFkQnl0ZSgpO1xuICAgICAgICAgICAgYmxvY2tMZW4gfD0gKHJlYWRCeXRlKCk8PDgpO1xuXG4gICAgICAgICAgICBjU3VtID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgICAgIGNTdW0gfD0gKHJlYWRCeXRlKCk8PDgpO1xuXG4gICAgICAgICAgICBpZigoKGJsb2NrTGVuIF4gfmNTdW0pICYgMHhmZmZmKSkge1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwiQmxvY2tMZW4gY2hlY2tzdW0gbWlzbWF0Y2hcXG5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB3aGlsZShibG9ja0xlbi0tKSB7XG4gICAgICAgICAgICAgICAgYyA9IHJlYWRCeXRlKCk7XG4gICAgICAgICAgICAgICAgYWRkQnVmZmVyKGMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYodHlwZT09MSkge1xuICAgICAgICAgICAgdmFyIGo7XG5cbiAgICAgICAgICAgIC8qIEZpeGVkIEh1ZmZtYW4gdGFibGVzIC0tIGZpeGVkIGRlY29kZSByb3V0aW5lICovXG4gICAgICAgICAgICB3aGlsZSgxKSB7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgIDI1NiAgICAwMDAwMDAwICAgICAgICAwXG4gICAgICAgICAgICAgICAgOiAgIDogICAgIDpcbiAgICAgICAgICAgICAgICAyNzkgICAgMDAxMDExMSAgICAgICAgMjNcbiAgICAgICAgICAgICAgICAwICAgMDAxMTAwMDAgICAgNDhcbiAgICAgICAgICAgICAgICA6ICAgIDogICAgICA6XG4gICAgICAgICAgICAgICAgMTQzICAgIDEwMTExMTExICAgIDE5MVxuICAgICAgICAgICAgICAgIDI4MCAxMTAwMDAwMCAgICAxOTJcbiAgICAgICAgICAgICAgICA6ICAgIDogICAgICA6XG4gICAgICAgICAgICAgICAgMjg3IDExMDAwMTExICAgIDE5OVxuICAgICAgICAgICAgICAgIDE0NCAgICAxMTAwMTAwMDAgICAgNDAwXG4gICAgICAgICAgICAgICAgOiAgICA6ICAgICAgIDpcbiAgICAgICAgICAgICAgICAyNTUgICAgMTExMTExMTExICAgIDUxMVxuICAgIFxuICAgICAgICAgICAgICAgIE5vdGUgdGhlIGJpdCBvcmRlciFcbiAgICAgICAgICAgICAgICAqL1xuXG4gICAgICAgICAgICBqID0gKGJpdFJldmVyc2VbcmVhZEJpdHMoNyldPj4xKTtcbiAgICAgICAgICAgIGlmKGogPiAyMykge1xuICAgICAgICAgICAgICAgIGogPSAoajw8MSkgfCByZWFkQml0KCk7ICAgIC8qIDQ4Li4yNTUgKi9cblxuICAgICAgICAgICAgICAgIGlmKGogPiAxOTkpIHsgICAgLyogMjAwLi4yNTUgKi9cbiAgICAgICAgICAgICAgICAgICAgaiAtPSAxMjg7ICAgIC8qICA3Mi4uMTI3ICovXG4gICAgICAgICAgICAgICAgICAgIGogPSAoajw8MSkgfCByZWFkQml0KCk7ICAgICAgICAvKiAxNDQuLjI1NSA8PCAqL1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7ICAgICAgICAvKiAgNDguLjE5OSAqL1xuICAgICAgICAgICAgICAgICAgICBqIC09IDQ4OyAgICAvKiAgIDAuLjE1MSAqL1xuICAgICAgICAgICAgICAgICAgICBpZihqID4gMTQzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBqID0gaisxMzY7ICAgIC8qIDI4MC4uMjg3IDw8ICovXG4gICAgICAgICAgICAgICAgICAgICAgICAvKiAgIDAuLjE0MyA8PCAqL1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHsgICAgLyogICAwLi4yMyAqL1xuICAgICAgICAgICAgICAgIGogKz0gMjU2OyAgICAvKiAyNTYuLjI3OSA8PCAqL1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYoaiA8IDI1Nikge1xuICAgICAgICAgICAgICAgIGFkZEJ1ZmZlcihqKTtcbiAgICAgICAgICAgICAgICAvL2RvY3VtZW50LndyaXRlKFwib3V0OlwiK1N0cmluZy5mcm9tQ2hhckNvZGUoaikpO1xuICAgICAgICAgICAgICAgIC8qZnByaW50ZihlcnJmcCwgXCJAJWQgJTAyeFxcblwiLCBTSVpFLCBqKTsqL1xuICAgICAgICAgICAgfSBlbHNlIGlmKGogPT0gMjU2KSB7XG4gICAgICAgICAgICAgICAgLyogRU9GICovXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBsZW4sIGRpc3Q7XG5cbiAgICAgICAgICAgICAgICBqIC09IDI1NiArIDE7ICAgIC8qIGJ5dGVzICsgRU9GICovXG4gICAgICAgICAgICAgICAgbGVuID0gcmVhZEJpdHMoY3BsZXh0W2pdKSArIGNwbGVuc1tqXTtcblxuICAgICAgICAgICAgICAgIGogPSBiaXRSZXZlcnNlW3JlYWRCaXRzKDUpXT4+MztcbiAgICAgICAgICAgICAgICBpZihjcGRleHRbal0gPiA4KSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc3QgPSByZWFkQml0cyg4KTtcbiAgICAgICAgICAgICAgICAgICAgZGlzdCB8PSAocmVhZEJpdHMoY3BkZXh0W2pdLTgpPDw4KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkaXN0ID0gcmVhZEJpdHMoY3BkZXh0W2pdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGlzdCArPSBjcGRpc3Rbal07XG5cbiAgICAgICAgICAgICAgICAvKmZwcmludGYoZXJyZnAsIFwiQCVkIChsJTAyeCxkJTA0eClcXG5cIiwgU0laRSwgbGVuLCBkaXN0KTsqL1xuICAgICAgICAgICAgICAgIGZvcihqPTA7ajxsZW47aisrKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjID0gYnVmMzJrWyhiSWR4IC0gZGlzdCkgJiAweDdmZmZdO1xuICAgICAgICAgICAgICAgICAgICBhZGRCdWZmZXIoYyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSAvLyB3aGlsZVxuICAgICAgICB9IGVsc2UgaWYodHlwZT09Mikge1xuICAgICAgICAgICAgdmFyIGosIG4sIGxpdGVyYWxDb2RlcywgZGlzdENvZGVzLCBsZW5Db2RlcztcbiAgICAgICAgICAgIHZhciBsbCA9IG5ldyBBcnJheSgyODgrMzIpOyAgICAvLyBcInN0YXRpY1wiIGp1c3QgdG8gcHJlc2VydmUgc3RhY2tcbiAgICBcbiAgICAgICAgICAgIC8vIER5bmFtaWMgSHVmZm1hbiB0YWJsZXMgXG4gICAgXG4gICAgICAgICAgICBsaXRlcmFsQ29kZXMgPSAyNTcgKyByZWFkQml0cyg1KTtcbiAgICAgICAgICAgIGRpc3RDb2RlcyA9IDEgKyByZWFkQml0cyg1KTtcbiAgICAgICAgICAgIGxlbkNvZGVzID0gNCArIHJlYWRCaXRzKDQpO1xuICAgICAgICAgICAgLy9kb2N1bWVudC53cml0ZShcIjxicj5wYXJhbTogXCIrbGl0ZXJhbENvZGVzK1wiIFwiK2Rpc3RDb2RlcytcIiBcIitsZW5Db2RlcytcIjxicj5cIik7XG4gICAgICAgICAgICBmb3Ioaj0wOyBqPDE5OyBqKyspIHtcbiAgICAgICAgICAgICAgICBsbFtqXSA9IDA7XG4gICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICAvLyBHZXQgdGhlIGRlY29kZSB0cmVlIGNvZGUgbGVuZ3Roc1xuICAgIFxuICAgICAgICAgICAgLy9kb2N1bWVudC53cml0ZShcIjxicj5cIik7XG4gICAgICAgICAgICBmb3Ioaj0wOyBqPGxlbkNvZGVzOyBqKyspIHtcbiAgICAgICAgICAgICAgICBsbFtib3JkZXJbal1dID0gcmVhZEJpdHMoMyk7XG4gICAgICAgICAgICAgICAgLy9kb2N1bWVudC53cml0ZShsbFtib3JkZXJbal1dK1wiIFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vZnByaW50ZihlcnJmcCwgXCJcXG5cIik7XG4gICAgICAgICAgICAvL2RvY3VtZW50LndyaXRlKCc8YnI+bGw6JytsbCk7XG4gICAgICAgICAgICBsZW4gPSBkaXN0YW5jZVRyZWUubGVuZ3RoO1xuICAgICAgICAgICAgZm9yIChpPTA7IGk8bGVuOyBpKyspXG4gICAgICAgICAgICAgICAgZGlzdGFuY2VUcmVlW2ldPW5ldyBIdWZOb2RlKCk7XG4gICAgICAgICAgICBpZihDcmVhdGVUcmVlKGRpc3RhbmNlVHJlZSwgMTksIGxsLCAwKSkge1xuICAgICAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGVidWcpe1xuICAgICAgICAgICAgXHRkb2N1bWVudC53cml0ZShcIjxicj5kaXN0YW5jZVRyZWVcIik7XG4gICAgICAgICAgICBcdGZvcih2YXIgYT0wO2E8ZGlzdGFuY2VUcmVlLmxlbmd0aDthKyspe1xuICAgICAgICAgICAgICAgIFx0ZG9jdW1lbnQud3JpdGUoXCI8YnI+XCIrZGlzdGFuY2VUcmVlW2FdLmIwK1wiIFwiK2Rpc3RhbmNlVHJlZVthXS5iMStcIiBcIitkaXN0YW5jZVRyZWVbYV0uanVtcCtcIiBcIitkaXN0YW5jZVRyZWVbYV0uanVtcHBvcyk7XG4gICAgICAgICAgICAgICAgXHQvKmlmIChkaXN0YW5jZVRyZWVbYV0uanVtcHBvcyE9LTEpXG4gICAgICAgICAgICAgICAgICAgIFx0ZG9jdW1lbnQud3JpdGUoXCIgXCIrZGlzdGFuY2VUcmVlW2FdLmp1bXAuYjArXCIgXCIrZGlzdGFuY2VUcmVlW2FdLmp1bXAuYjEpO1xuICAgICAgICAgICAgICAgIFx0Ki9cbiAgICAgICAgICAgIFx0fVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy9kb2N1bWVudC53cml0ZSgnPEJSPnRyZWUgY3JlYXRlZCcpO1xuICAgIFxuICAgICAgICAgICAgLy9yZWFkIGluIGxpdGVyYWwgYW5kIGRpc3RhbmNlIGNvZGUgbGVuZ3Roc1xuICAgICAgICAgICAgbiA9IGxpdGVyYWxDb2RlcyArIGRpc3RDb2RlcztcbiAgICAgICAgICAgIGkgPSAwO1xuICAgICAgICAgICAgdmFyIHo9LTE7XG4gICAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBcdGRvY3VtZW50LndyaXRlKFwiPGJyPm49XCIrbitcIiBiaXRzOiBcIitiaXRzK1wiPGJyPlwiKTtcbiAgICAgICAgICAgIHdoaWxlKGkgPCBuKSB7XG4gICAgICAgICAgICAgICAgeisrO1xuICAgICAgICAgICAgICAgIGogPSBEZWNvZGVWYWx1ZShkaXN0YW5jZVRyZWUpO1xuICAgICAgICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgICAgICBcdGRvY3VtZW50LndyaXRlKFwiPGJyPlwiK3orXCIgaTpcIitpK1wiIGRlY29kZTogXCIraitcIiAgICBiaXRzIFwiK2JpdHMrXCI8YnI+XCIpO1xuICAgICAgICAgICAgICAgIGlmKGo8MTYpIHsgICAgLy8gbGVuZ3RoIG9mIGNvZGUgaW4gYml0cyAoMC4uMTUpXG4gICAgICAgICAgICAgICAgICAgICAgIGxsW2krK10gPSBqO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZihqPT0xNikgeyAgICAvLyByZXBlYXQgbGFzdCBsZW5ndGggMyB0byA2IHRpbWVzIFxuICAgICAgICAgICAgICAgICAgICAgICB2YXIgbDtcbiAgICAgICAgICAgICAgICAgICAgaiA9IDMgKyByZWFkQml0cygyKTtcbiAgICAgICAgICAgICAgICAgICAgaWYoaStqID4gbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmx1c2hCdWZmZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGwgPSBpID8gbGxbaS0xXSA6IDA7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlKGotLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGxbaSsrXSA9IGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZihqPT0xNykgeyAgICAgICAgLy8gMyB0byAxMCB6ZXJvIGxlbmd0aCBjb2Rlc1xuICAgICAgICAgICAgICAgICAgICAgICAgaiA9IDMgKyByZWFkQml0cygzKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsgICAgICAgIC8vIGogPT0gMTg6IDExIHRvIDEzOCB6ZXJvIGxlbmd0aCBjb2RlcyBcbiAgICAgICAgICAgICAgICAgICAgICAgIGogPSAxMSArIHJlYWRCaXRzKDcpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmKGkraiA+IG4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB3aGlsZShqLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxsW2krK10gPSAwO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLypmb3Ioaj0wOyBqPGxpdGVyYWxDb2RlcytkaXN0Q29kZXM7IGorKykge1xuICAgICAgICAgICAgICAgIC8vZnByaW50ZihlcnJmcCwgXCIlZCBcIiwgbGxbal0pO1xuICAgICAgICAgICAgICAgIGlmICgoaiY3KT09NylcbiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihlcnJmcCwgXCJcXG5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmcHJpbnRmKGVycmZwLCBcIlxcblwiKTsqL1xuICAgICAgICAgICAgLy8gQ2FuIG92ZXJ3cml0ZSB0cmVlIGRlY29kZSB0cmVlIGFzIGl0IGlzIG5vdCB1c2VkIGFueW1vcmVcbiAgICAgICAgICAgIGxlbiA9IGxpdGVyYWxUcmVlLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAoaT0wOyBpPGxlbjsgaSsrKVxuICAgICAgICAgICAgICAgIGxpdGVyYWxUcmVlW2ldPW5ldyBIdWZOb2RlKCk7XG4gICAgICAgICAgICBpZihDcmVhdGVUcmVlKGxpdGVyYWxUcmVlLCBsaXRlcmFsQ29kZXMsIGxsLCAwKSkge1xuICAgICAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZW4gPSBsaXRlcmFsVHJlZS5sZW5ndGg7XG4gICAgICAgICAgICBmb3IgKGk9MDsgaTxsZW47IGkrKylcbiAgICAgICAgICAgICAgICBkaXN0YW5jZVRyZWVbaV09bmV3IEh1Zk5vZGUoKTtcbiAgICAgICAgICAgIHZhciBsbDIgPSBuZXcgQXJyYXkoKTtcbiAgICAgICAgICAgIGZvciAoaT1saXRlcmFsQ29kZXM7IGkgPGxsLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgICAgICBsbDJbaS1saXRlcmFsQ29kZXNdPWxsW2ldO1xuICAgICAgICAgICAgfSAgICBcbiAgICAgICAgICAgIGlmKENyZWF0ZVRyZWUoZGlzdGFuY2VUcmVlLCBkaXN0Q29kZXMsIGxsMiwgMCkpIHtcbiAgICAgICAgICAgICAgICBmbHVzaEJ1ZmZlcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICBcdFx0ZG9jdW1lbnQud3JpdGUoXCI8YnI+bGl0ZXJhbFRyZWVcIik7XG4gICAgICAgICAgICBvdXRlcjpcbiAgICAgICAgICAgIHdoaWxlKDEpIHtcbiAgICAgICAgICAgICAgICBqID0gRGVjb2RlVmFsdWUobGl0ZXJhbFRyZWUpO1xuICAgICAgICAgICAgICAgIGlmKGogPj0gMjU2KSB7ICAgICAgICAvLyBJbiBDNjQ6IGlmIGNhcnJ5IHNldFxuICAgICAgICAgICAgICAgICAgICB2YXIgbGVuLCBkaXN0O1xuICAgICAgICAgICAgICAgICAgICBqIC09IDI1NjtcbiAgICAgICAgICAgICAgICAgICAgaWYoaiA9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBFT0ZcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGotLTtcbiAgICAgICAgICAgICAgICAgICAgbGVuID0gcmVhZEJpdHMoY3BsZXh0W2pdKSArIGNwbGVuc1tqXTtcbiAgICBcbiAgICAgICAgICAgICAgICAgICAgaiA9IERlY29kZVZhbHVlKGRpc3RhbmNlVHJlZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmKGNwZGV4dFtqXSA+IDgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3QgPSByZWFkQml0cyg4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3QgfD0gKHJlYWRCaXRzKGNwZGV4dFtqXS04KTw8OCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXN0ID0gcmVhZEJpdHMoY3BkZXh0W2pdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBkaXN0ICs9IGNwZGlzdFtqXTtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUobGVuLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmKGJJZHggLSBkaXN0IDwgMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGMgPSBidWYzMmtbKGJJZHggLSBkaXN0KSAmIDB4N2ZmZl07XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRCdWZmZXIoYyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBhZGRCdWZmZXIoaik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSB3aGlsZSghbGFzdCk7XG4gICAgZmx1c2hCdWZmZXIoKTtcblxuICAgIGJ5dGVBbGlnbigpO1xuICAgIHJldHVybiAwO1xufTtcblxuSlhHLlV0aWwuVW56aXAucHJvdG90eXBlLnVuemlwRmlsZSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgaTtcblx0dGhpcy51bnppcCgpO1xuXHQvL2FsZXJ0KHVuemlwcGVkWzBdWzFdKTtcblx0Zm9yIChpPTA7aTx1bnppcHBlZC5sZW5ndGg7aSsrKXtcblx0XHRpZih1bnppcHBlZFtpXVsxXT09bmFtZSkge1xuXHRcdFx0cmV0dXJuIHVuemlwcGVkW2ldWzBdO1xuXHRcdH1cblx0fVxuXHRcbiAgfTtcblxuSlhHLlV0aWwuVW56aXAucHJvdG90eXBlLmRlZmxhdGUgPSBmdW5jdGlvbigpIHtcbiAgICBvdXRwdXRBcnIgPSBbXTtcbiAgICB2YXIgdG1wID0gW107XG4gICAgbW9kZVpJUCA9IGZhbHNlO1xuICAgIERlZmxhdGVMb29wKCk7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChvdXRwdXRBcnIuam9pbignJykpO1xuICAgIHVuemlwcGVkW2ZpbGVzXSA9IG5ldyBBcnJheSgyKTtcbiAgICB1bnppcHBlZFtmaWxlc11bMF0gPSBvdXRwdXRBcnIuam9pbignJyk7XG4gICAgdW56aXBwZWRbZmlsZXNdWzFdID0gXCJERUZMQVRFXCI7XG4gICAgZmlsZXMrKztcbiAgICByZXR1cm4gdW56aXBwZWQ7XG59ICAgIFxuICAgIFxuSlhHLlV0aWwuVW56aXAucHJvdG90eXBlLnVuemlwID0gZnVuY3Rpb24oKSB7XG5cdC8vY29udmVydFRvQnl0ZUFycmF5KGlucHV0KTtcblx0aWYgKGRlYnVnKVxuXHRcdGFsZXJ0KGJBKTtcblx0Lypmb3IgKGk9MDtpPGJBLmxlbmd0aCo4O2krKyl7XG5cdFx0ZG9jdW1lbnQud3JpdGUocmVhZEJpdCgpKTtcblx0XHRpZiAoKGkrMSklOD09MClcblx0XHRcdGRvY3VtZW50LndyaXRlKFwiIFwiKTtcblx0fSovXG5cdC8qZm9yIChpPTA7aTxiQS5sZW5ndGg7aSsrKXtcblx0XHRkb2N1bWVudC53cml0ZShyZWFkQnl0ZSgpK1wiIFwiKTtcblx0XHRpZiAoKGkrMSklOD09MClcblx0XHRcdGRvY3VtZW50LndyaXRlKFwiIFwiKTtcblx0fVxuXHRmb3IgKGk9MDtpPGJBLmxlbmd0aDtpKyspe1xuXHRcdGRvY3VtZW50LndyaXRlKGJBW2ldK1wiIFwiKTtcblx0XHRpZiAoKGkrMSklMTY9PTApXG5cdFx0XHRkb2N1bWVudC53cml0ZShcIjxicj5cIik7XG5cdH1cdFxuXHQqL1xuXHQvL2FsZXJ0KGJBKTtcblx0bmV4dEZpbGUoKTtcblx0cmV0dXJuIHVuemlwcGVkO1xuICB9O1xuICAgIFxuIGZ1bmN0aW9uIG5leHRGaWxlKCl7XG4gXHRpZiAoZGVidWcpXG4gXHRcdGFsZXJ0KFwiTkVYVEZJTEVcIik7XG4gXHRvdXRwdXRBcnIgPSBbXTtcbiBcdHZhciB0bXAgPSBbXTtcbiBcdG1vZGVaSVAgPSBmYWxzZTtcblx0dG1wWzBdID0gcmVhZEJ5dGUoKTtcblx0dG1wWzFdID0gcmVhZEJ5dGUoKTtcblx0aWYgKGRlYnVnKVxuXHRcdGFsZXJ0KFwidHlwZTogXCIrdG1wWzBdK1wiIFwiK3RtcFsxXSk7XG5cdGlmICh0bXBbMF0gPT0gcGFyc2VJbnQoXCI3OFwiLDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCJkYVwiLDE2KSl7IC8vR1pJUFxuXHRcdGlmIChkZWJ1Zylcblx0XHRcdGFsZXJ0KFwiR0VPTkV4VC1HWklQXCIpO1xuXHRcdERlZmxhdGVMb29wKCk7XG5cdFx0aWYgKGRlYnVnKVxuXHRcdFx0YWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcblx0XHR1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7XG4gICAgXHR1bnppcHBlZFtmaWxlc11bMF0gPSBvdXRwdXRBcnIuam9pbignJyk7XG4gICAgXHR1bnppcHBlZFtmaWxlc11bMV0gPSBcImdlb25leHQuZ3h0XCI7XG4gICAgXHRmaWxlcysrO1xuXHR9XG5cdGlmICh0bXBbMF0gPT0gcGFyc2VJbnQoXCI3OFwiLDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCI5Y1wiLDE2KSl7IC8vWkxJQlxuXHRcdGlmIChkZWJ1Zylcblx0XHRcdGFsZXJ0KFwiWkxJQlwiKTtcblx0XHREZWZsYXRlTG9vcCgpO1xuXHRcdGlmIChkZWJ1Zylcblx0XHRcdGFsZXJ0KG91dHB1dEFyci5qb2luKCcnKSk7XG5cdFx0dW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpO1xuICAgIFx0dW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgIFx0dW56aXBwZWRbZmlsZXNdWzFdID0gXCJaTElCXCI7XG4gICAgXHRmaWxlcysrO1xuXHR9XG5cdGlmICh0bXBbMF0gPT0gcGFyc2VJbnQoXCIxZlwiLDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCI4YlwiLDE2KSl7IC8vR1pJUFxuXHRcdGlmIChkZWJ1Zylcblx0XHRcdGFsZXJ0KFwiR1pJUFwiKTtcblx0XHQvL0RlZmxhdGVMb29wKCk7XG5cdFx0c2tpcGRpcigpO1xuXHRcdGlmIChkZWJ1Zylcblx0XHRcdGFsZXJ0KG91dHB1dEFyci5qb2luKCcnKSk7XG5cdFx0dW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpO1xuICAgIFx0dW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgIFx0dW56aXBwZWRbZmlsZXNdWzFdID0gXCJmaWxlXCI7XG4gICAgXHRmaWxlcysrO1xuXHR9XG5cdGlmICh0bXBbMF0gPT0gcGFyc2VJbnQoXCI1MFwiLDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCI0YlwiLDE2KSl7IC8vWklQXG5cdFx0bW9kZVpJUCA9IHRydWU7XG5cdFx0dG1wWzJdID0gcmVhZEJ5dGUoKTtcblx0XHR0bXBbM10gPSByZWFkQnl0ZSgpO1xuXHRcdGlmICh0bXBbMl0gPT0gcGFyc2VJbnQoXCIzXCIsMTYpICYmIHRtcFszXSA9PSBwYXJzZUludChcIjRcIiwxNikpe1xuXHRcdFx0Ly9NT0RFX1pJUFxuXHRcdFx0dG1wWzBdID0gcmVhZEJ5dGUoKTtcblx0XHRcdHRtcFsxXSA9IHJlYWRCeXRlKCk7XG5cdFx0XHRpZiAoZGVidWcpXG5cdFx0XHRcdGFsZXJ0KFwiWklQLVZlcnNpb246IFwiK3RtcFsxXStcIiBcIit0bXBbMF0vMTArXCIuXCIrdG1wWzBdJTEwKTtcblx0XHRcdFxuXHRcdFx0Z3BmbGFncyA9IHJlYWRCeXRlKCk7XG5cdFx0XHRncGZsYWdzIHw9IChyZWFkQnl0ZSgpPDw4KTtcblx0XHRcdGlmIChkZWJ1Zylcblx0XHRcdFx0YWxlcnQoXCJncGZsYWdzOiBcIitncGZsYWdzKTtcblx0XHRcdFxuXHRcdFx0dmFyIG1ldGhvZCA9IHJlYWRCeXRlKCk7XG5cdFx0XHRtZXRob2QgfD0gKHJlYWRCeXRlKCk8PDgpO1xuXHRcdFx0aWYgKGRlYnVnKVxuXHRcdFx0XHRhbGVydChcIm1ldGhvZDogXCIrbWV0aG9kKTtcblx0XHRcdFxuXHRcdFx0cmVhZEJ5dGUoKTtcblx0XHRcdHJlYWRCeXRlKCk7XG5cdFx0XHRyZWFkQnl0ZSgpO1xuXHRcdFx0cmVhZEJ5dGUoKTtcblx0XHRcdFxuXHRcdFx0dmFyIGNyYyA9IHJlYWRCeXRlKCk7XG5cdFx0XHRjcmMgfD0gKHJlYWRCeXRlKCk8PDgpO1xuXHRcdFx0Y3JjIHw9IChyZWFkQnl0ZSgpPDwxNik7XG5cdFx0XHRjcmMgfD0gKHJlYWRCeXRlKCk8PDI0KTtcblx0XHRcdFxuXHRcdFx0dmFyIGNvbXBTaXplID0gcmVhZEJ5dGUoKTtcblx0XHRcdGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpPDw4KTtcblx0XHRcdGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpPDwxNik7XG5cdFx0XHRjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKTw8MjQpO1xuXHRcdFx0XG5cdFx0XHR2YXIgc2l6ZSA9IHJlYWRCeXRlKCk7XG5cdFx0XHRzaXplIHw9IChyZWFkQnl0ZSgpPDw4KTtcblx0XHRcdHNpemUgfD0gKHJlYWRCeXRlKCk8PDE2KTtcblx0XHRcdHNpemUgfD0gKHJlYWRCeXRlKCk8PDI0KTtcblx0XHRcdFxuXHRcdFx0aWYgKGRlYnVnKVxuXHRcdFx0XHRhbGVydChcImxvY2FsIENSQzogXCIrY3JjK1wiXFxubG9jYWwgU2l6ZTogXCIrc2l6ZStcIlxcbmxvY2FsIENvbXBTaXplOiBcIitjb21wU2l6ZSk7XG5cdFx0XHRcblx0XHRcdHZhciBmaWxlbGVuID0gcmVhZEJ5dGUoKTtcblx0XHRcdGZpbGVsZW4gfD0gKHJlYWRCeXRlKCk8PDgpO1xuXHRcdFx0XG5cdFx0XHR2YXIgZXh0cmFsZW4gPSByZWFkQnl0ZSgpO1xuXHRcdFx0ZXh0cmFsZW4gfD0gKHJlYWRCeXRlKCk8PDgpO1xuXHRcdFx0XG5cdFx0XHRpZiAoZGVidWcpXG5cdFx0XHRcdGFsZXJ0KFwiZmlsZWxlbiBcIitmaWxlbGVuKTtcblx0XHRcdGkgPSAwO1xuXHRcdFx0bmFtZUJ1ZiA9IFtdO1xuXHRcdFx0d2hpbGUgKGZpbGVsZW4tLSl7IFxuXHRcdFx0XHR2YXIgYyA9IHJlYWRCeXRlKCk7XG5cdFx0XHRcdGlmIChjID09IFwiL1wiIHwgYyA9PVwiOlwiKXtcblx0XHRcdFx0XHRpID0gMDtcblx0XHRcdFx0fSBlbHNlIGlmIChpIDwgTkFNRU1BWC0xKVxuXHRcdFx0XHRcdG5hbWVCdWZbaSsrXSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoYyk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoZGVidWcpXG5cdFx0XHRcdGFsZXJ0KFwibmFtZUJ1ZjogXCIrbmFtZUJ1Zik7XG5cdFx0XHRcblx0XHRcdC8vbmFtZUJ1ZltpXSA9IFwiXFwwXCI7XG5cdFx0XHRpZiAoIWZpbGVvdXQpXG5cdFx0XHRcdGZpbGVvdXQgPSBuYW1lQnVmO1xuXHRcdFx0XG5cdFx0XHR2YXIgaSA9IDA7XG5cdFx0XHR3aGlsZSAoaSA8IGV4dHJhbGVuKXtcblx0XHRcdFx0YyA9IHJlYWRCeXRlKCk7XG5cdFx0XHRcdGkrKztcblx0XHRcdH1cblx0XHRcdFx0XG5cdFx0XHRDUkMgPSAweGZmZmZmZmZmO1xuXHRcdFx0U0laRSA9IDA7XG5cdFx0XHRcblx0XHRcdGlmIChzaXplID0gMCAmJiBmaWxlT3V0LmNoYXJBdChmaWxlb3V0Lmxlbmd0aC0xKT09XCIvXCIpe1xuXHRcdFx0XHQvL3NraXBkaXJcblx0XHRcdFx0aWYgKGRlYnVnKVxuXHRcdFx0XHRcdGFsZXJ0KFwic2tpcGRpclwiKTtcblx0XHRcdH1cblx0XHRcdGlmIChtZXRob2QgPT0gOCl7XG5cdFx0XHRcdERlZmxhdGVMb29wKCk7XG5cdFx0XHRcdGlmIChkZWJ1Zylcblx0XHRcdFx0XHRhbGVydChvdXRwdXRBcnIuam9pbignJykpO1xuXHRcdFx0XHR1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7XG5cdFx0XHRcdHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICBcdFx0XHR1bnppcHBlZFtmaWxlc11bMV0gPSBuYW1lQnVmLmpvaW4oJycpO1xuICAgIFx0XHRcdGZpbGVzKys7XG5cdFx0XHRcdC8vcmV0dXJuIG91dHB1dEFyci5qb2luKCcnKTtcblx0XHRcdH1cblx0XHRcdHNraXBkaXIoKTtcblx0XHR9XG5cdH1cbiB9O1xuXHRcbmZ1bmN0aW9uIHNraXBkaXIoKXtcbiAgICB2YXIgY3JjLCBcbiAgICAgICAgdG1wID0gW10sXG4gICAgICAgIGNvbXBTaXplLCBzaXplLCBvcywgaSwgYztcbiAgICBcblx0aWYgKChncGZsYWdzICYgOCkpIHtcblx0XHR0bXBbMF0gPSByZWFkQnl0ZSgpO1xuXHRcdHRtcFsxXSA9IHJlYWRCeXRlKCk7XG5cdFx0dG1wWzJdID0gcmVhZEJ5dGUoKTtcblx0XHR0bXBbM10gPSByZWFkQnl0ZSgpO1xuXHRcdFxuXHRcdGlmICh0bXBbMF0gPT0gcGFyc2VJbnQoXCI1MFwiLDE2KSAmJiBcbiAgICAgICAgICAgIHRtcFsxXSA9PSBwYXJzZUludChcIjRiXCIsMTYpICYmIFxuICAgICAgICAgICAgdG1wWzJdID09IHBhcnNlSW50KFwiMDdcIiwxNikgJiYgXG4gICAgICAgICAgICB0bXBbM10gPT0gcGFyc2VJbnQoXCIwOFwiLDE2KSlcbiAgICAgICAge1xuICAgICAgICAgICAgY3JjID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKTw8OCk7XG4gICAgICAgICAgICBjcmMgfD0gKHJlYWRCeXRlKCk8PDE2KTtcbiAgICAgICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKTw8MjQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjcmMgPSB0bXBbMF0gfCAodG1wWzFdPDw4KSB8ICh0bXBbMl08PDE2KSB8ICh0bXBbM108PDI0KTtcblx0XHR9XG5cdFx0XG5cdFx0Y29tcFNpemUgPSByZWFkQnl0ZSgpO1xuXHRcdGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpPDw4KTtcblx0XHRjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKTw8MTYpO1xuXHRcdGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpPDwyNCk7XG5cdFx0XG5cdFx0c2l6ZSA9IHJlYWRCeXRlKCk7XG5cdFx0c2l6ZSB8PSAocmVhZEJ5dGUoKTw8OCk7XG5cdFx0c2l6ZSB8PSAocmVhZEJ5dGUoKTw8MTYpO1xuXHRcdHNpemUgfD0gKHJlYWRCeXRlKCk8PDI0KTtcblx0XHRcblx0XHRpZiAoZGVidWcpXG5cdFx0XHRhbGVydChcIkNSQzpcIik7XG5cdH1cblxuXHRpZiAobW9kZVpJUClcblx0XHRuZXh0RmlsZSgpO1xuXHRcblx0dG1wWzBdID0gcmVhZEJ5dGUoKTtcblx0aWYgKHRtcFswXSAhPSA4KSB7XG5cdFx0aWYgKGRlYnVnKVxuXHRcdFx0YWxlcnQoXCJVbmtub3duIGNvbXByZXNzaW9uIG1ldGhvZCFcIik7XG4gICAgICAgIHJldHVybiAwO1x0XG5cdH1cblx0XG5cdGdwZmxhZ3MgPSByZWFkQnl0ZSgpO1xuXHRpZiAoZGVidWcpe1xuXHRcdGlmICgoZ3BmbGFncyAmIH4ocGFyc2VJbnQoXCIxZlwiLDE2KSkpKVxuXHRcdFx0YWxlcnQoXCJVbmtub3duIGZsYWdzIHNldCFcIik7XG5cdH1cblx0XG5cdHJlYWRCeXRlKCk7XG5cdHJlYWRCeXRlKCk7XG5cdHJlYWRCeXRlKCk7XG5cdHJlYWRCeXRlKCk7XG5cdFxuXHRyZWFkQnl0ZSgpO1xuXHRvcyA9IHJlYWRCeXRlKCk7XG5cdFxuXHRpZiAoKGdwZmxhZ3MgJiA0KSl7XG5cdFx0dG1wWzBdID0gcmVhZEJ5dGUoKTtcblx0XHR0bXBbMl0gPSByZWFkQnl0ZSgpO1xuXHRcdGxlbiA9IHRtcFswXSArIDI1Nip0bXBbMV07XG5cdFx0aWYgKGRlYnVnKVxuXHRcdFx0YWxlcnQoXCJFeHRyYSBmaWVsZCBzaXplOiBcIitsZW4pO1xuXHRcdGZvciAoaT0wO2k8bGVuO2krKylcblx0XHRcdHJlYWRCeXRlKCk7XG5cdH1cblx0XG5cdGlmICgoZ3BmbGFncyAmIDgpKXtcblx0XHRpPTA7XG5cdFx0bmFtZUJ1Zj1bXTtcblx0XHR3aGlsZSAoYz1yZWFkQnl0ZSgpKXtcblx0XHRcdGlmKGMgPT0gXCI3XCIgfHwgYyA9PSBcIjpcIilcblx0XHRcdFx0aT0wO1xuXHRcdFx0aWYgKGk8TkFNRU1BWC0xKVxuXHRcdFx0XHRuYW1lQnVmW2krK10gPSBjO1xuXHRcdH1cblx0XHQvL25hbWVCdWZbaV0gPSBcIlxcMFwiO1xuXHRcdGlmIChkZWJ1Zylcblx0XHRcdGFsZXJ0KFwib3JpZ2luYWwgZmlsZSBuYW1lOiBcIituYW1lQnVmKTtcblx0fVxuXHRcdFxuXHRpZiAoKGdwZmxhZ3MgJiAxNikpe1xuXHRcdHdoaWxlIChjPXJlYWRCeXRlKCkpe1xuXHRcdFx0Ly9GSUxFIENPTU1FTlRcblx0XHR9XG5cdH1cblx0XG5cdGlmICgoZ3BmbGFncyAmIDIpKXtcblx0XHRyZWFkQnl0ZSgpO1xuXHRcdHJlYWRCeXRlKCk7XG5cdH1cblx0XG5cdERlZmxhdGVMb29wKCk7XG5cdFxuXHRjcmMgPSByZWFkQnl0ZSgpO1xuXHRjcmMgfD0gKHJlYWRCeXRlKCk8PDgpO1xuXHRjcmMgfD0gKHJlYWRCeXRlKCk8PDE2KTtcblx0Y3JjIHw9IChyZWFkQnl0ZSgpPDwyNCk7XG5cdFxuXHRzaXplID0gcmVhZEJ5dGUoKTtcblx0c2l6ZSB8PSAocmVhZEJ5dGUoKTw8OCk7XG5cdHNpemUgfD0gKHJlYWRCeXRlKCk8PDE2KTtcblx0c2l6ZSB8PSAocmVhZEJ5dGUoKTw8MjQpO1xuXHRcblx0aWYgKG1vZGVaSVApXG5cdFx0bmV4dEZpbGUoKTtcblx0XG59O1xuXG59O1xuXG4vKipcbiogIEJhc2U2NCBlbmNvZGluZyAvIGRlY29kaW5nXG4qICB7QGxpbmsgaHR0cDovL3d3dy53ZWJ0b29sa2l0LmluZm8vfVxuKi9cbkpYRy5VdGlsLkJhc2U2NCA9IHtcblxuICAgIC8vIHByaXZhdGUgcHJvcGVydHlcbiAgICBfa2V5U3RyIDogXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPVwiLFxuXG4gICAgLy8gcHVibGljIG1ldGhvZCBmb3IgZW5jb2RpbmdcbiAgICBlbmNvZGUgOiBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgdmFyIG91dHB1dCA9IFtdLFxuICAgICAgICAgICAgY2hyMSwgY2hyMiwgY2hyMywgZW5jMSwgZW5jMiwgZW5jMywgZW5jNCxcbiAgICAgICAgICAgIGkgPSAwO1xuXG4gICAgICAgIGlucHV0ID0gSlhHLlV0aWwuQmFzZTY0Ll91dGY4X2VuY29kZShpbnB1dCk7XG5cbiAgICAgICAgd2hpbGUgKGkgPCBpbnB1dC5sZW5ndGgpIHtcblxuICAgICAgICAgICAgY2hyMSA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgICAgICAgIGNocjIgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICAgICAgICBjaHIzID0gaW5wdXQuY2hhckNvZGVBdChpKyspO1xuXG4gICAgICAgICAgICBlbmMxID0gY2hyMSA+PiAyO1xuICAgICAgICAgICAgZW5jMiA9ICgoY2hyMSAmIDMpIDw8IDQpIHwgKGNocjIgPj4gNCk7XG4gICAgICAgICAgICBlbmMzID0gKChjaHIyICYgMTUpIDw8IDIpIHwgKGNocjMgPj4gNik7XG4gICAgICAgICAgICBlbmM0ID0gY2hyMyAmIDYzO1xuXG4gICAgICAgICAgICBpZiAoaXNOYU4oY2hyMikpIHtcbiAgICAgICAgICAgICAgICBlbmMzID0gZW5jNCA9IDY0O1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc05hTihjaHIzKSkge1xuICAgICAgICAgICAgICAgIGVuYzQgPSA2NDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgb3V0cHV0LnB1c2goW3RoaXMuX2tleVN0ci5jaGFyQXQoZW5jMSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fa2V5U3RyLmNoYXJBdChlbmMyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2tleVN0ci5jaGFyQXQoZW5jNCldLmpvaW4oJycpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBvdXRwdXQuam9pbignJyk7XG4gICAgfSxcblxuICAgIC8vIHB1YmxpYyBtZXRob2QgZm9yIGRlY29kaW5nXG4gICAgZGVjb2RlIDogZnVuY3Rpb24gKGlucHV0LCB1dGY4KSB7XG4gICAgICAgIHZhciBvdXRwdXQgPSBbXSxcbiAgICAgICAgICAgIGNocjEsIGNocjIsIGNocjMsXG4gICAgICAgICAgICBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0LFxuICAgICAgICAgICAgaSA9IDA7XG5cbiAgICAgICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKC9bXkEtWmEtejAtOVxcK1xcL1xcPV0vZywgXCJcIik7XG5cbiAgICAgICAgd2hpbGUgKGkgPCBpbnB1dC5sZW5ndGgpIHtcblxuICAgICAgICAgICAgZW5jMSA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcbiAgICAgICAgICAgIGVuYzIgPSB0aGlzLl9rZXlTdHIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICAgICAgICBlbmMzID0gdGhpcy5fa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuICAgICAgICAgICAgZW5jNCA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcblxuICAgICAgICAgICAgY2hyMSA9IChlbmMxIDw8IDIpIHwgKGVuYzIgPj4gNCk7XG4gICAgICAgICAgICBjaHIyID0gKChlbmMyICYgMTUpIDw8IDQpIHwgKGVuYzMgPj4gMik7XG4gICAgICAgICAgICBjaHIzID0gKChlbmMzICYgMykgPDwgNikgfCBlbmM0O1xuXG4gICAgICAgICAgICBvdXRwdXQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGNocjEpKTtcblxuICAgICAgICAgICAgaWYgKGVuYzMgIT0gNjQpIHtcbiAgICAgICAgICAgICAgICBvdXRwdXQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGNocjIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlbmM0ICE9IDY0KSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjaHIzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIG91dHB1dCA9IG91dHB1dC5qb2luKCcnKTsgXG4gICAgICAgIFxuICAgICAgICBpZiAodXRmOCkge1xuICAgICAgICAgICAgb3V0cHV0ID0gSlhHLlV0aWwuQmFzZTY0Ll91dGY4X2RlY29kZShvdXRwdXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXRwdXQ7XG5cbiAgICB9LFxuXG4gICAgLy8gcHJpdmF0ZSBtZXRob2QgZm9yIFVURi04IGVuY29kaW5nXG4gICAgX3V0ZjhfZW5jb2RlIDogZnVuY3Rpb24gKHN0cmluZykge1xuICAgICAgICBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZSgvXFxyXFxuL2csXCJcXG5cIik7XG4gICAgICAgIHZhciB1dGZ0ZXh0ID0gXCJcIjtcblxuICAgICAgICBmb3IgKHZhciBuID0gMDsgbiA8IHN0cmluZy5sZW5ndGg7IG4rKykge1xuXG4gICAgICAgICAgICB2YXIgYyA9IHN0cmluZy5jaGFyQ29kZUF0KG4pO1xuXG4gICAgICAgICAgICBpZiAoYyA8IDEyOCkge1xuICAgICAgICAgICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYoKGMgPiAxMjcpICYmIChjIDwgMjA0OCkpIHtcbiAgICAgICAgICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGMgPj4gNikgfCAxOTIpO1xuICAgICAgICAgICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoYyAmIDYzKSB8IDEyOCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGMgPj4gMTIpIHwgMjI0KTtcbiAgICAgICAgICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChjID4+IDYpICYgNjMpIHwgMTI4KTtcbiAgICAgICAgICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGMgJiA2MykgfCAxMjgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdXRmdGV4dDtcbiAgICB9LFxuXG4gICAgLy8gcHJpdmF0ZSBtZXRob2QgZm9yIFVURi04IGRlY29kaW5nXG4gICAgX3V0ZjhfZGVjb2RlIDogZnVuY3Rpb24gKHV0ZnRleHQpIHtcbiAgICAgICAgdmFyIHN0cmluZyA9IFtdLFxuICAgICAgICAgICAgaSA9IDAsXG4gICAgICAgICAgICBjID0gMCwgYzIgPSAwLCBjMyA9IDA7XG5cbiAgICAgICAgd2hpbGUgKCBpIDwgdXRmdGV4dC5sZW5ndGggKSB7XG4gICAgICAgICAgICBjID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgICAgICAgICAgaWYgKGMgPCAxMjgpIHtcbiAgICAgICAgICAgICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGMpKTtcbiAgICAgICAgICAgICAgICBpKys7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmKChjID4gMTkxKSAmJiAoYyA8IDIyNCkpIHtcbiAgICAgICAgICAgICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpKzEpO1xuICAgICAgICAgICAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoKChjICYgMzEpIDw8IDYpIHwgKGMyICYgNjMpKSk7XG4gICAgICAgICAgICAgICAgaSArPSAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYzIgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSsxKTtcbiAgICAgICAgICAgICAgICBjMyA9IHV0ZnRleHQuY2hhckNvZGVBdChpKzIpO1xuICAgICAgICAgICAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoKChjICYgMTUpIDw8IDEyKSB8ICgoYzIgJiA2MykgPDwgNikgfCAoYzMgJiA2MykpKTtcbiAgICAgICAgICAgICAgICBpICs9IDM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0cmluZy5qb2luKCcnKTtcbiAgICB9LFxuICAgIFxuICAgIF9kZXN0cmlwOiBmdW5jdGlvbiAoc3RyaXBwZWQsIHdyYXApe1xuICAgICAgICB2YXIgbGluZXMgPSBbXSwgbGluZW5vLCBpLFxuICAgICAgICAgICAgZGVzdHJpcHBlZCA9IFtdO1xuICAgICAgICBcbiAgICAgICAgaWYgKHdyYXA9PW51bGwpIFxuICAgICAgICAgICAgd3JhcCA9IDc2O1xuICAgICAgICAgICAgXG4gICAgICAgIHN0cmlwcGVkLnJlcGxhY2UoLyAvZywgXCJcIik7XG4gICAgICAgIGxpbmVubyA9IHN0cmlwcGVkLmxlbmd0aCAvIHdyYXA7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaW5lbm87IGkrKylcbiAgICAgICAgICAgIGxpbmVzW2ldPXN0cmlwcGVkLnN1YnN0cihpICogd3JhcCwgd3JhcCk7XG4gICAgICAgIGlmIChsaW5lbm8gIT0gc3RyaXBwZWQubGVuZ3RoIC8gd3JhcClcbiAgICAgICAgICAgIGxpbmVzW2xpbmVzLmxlbmd0aF09c3RyaXBwZWQuc3Vic3RyKGxpbmVubyAqIHdyYXAsIHN0cmlwcGVkLmxlbmd0aC0obGluZW5vICogd3JhcCkpO1xuICAgICAgICAgICAgXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGRlc3RyaXBwZWQucHVzaChsaW5lc1tpXSk7XG4gICAgICAgIHJldHVybiBkZXN0cmlwcGVkLmpvaW4oJ1xcbicpO1xuICAgIH0sXG4gICAgXG4gICAgZGVjb2RlQXNBcnJheTogZnVuY3Rpb24gKGlucHV0KXtcbiAgICAgICAgdmFyIGRlYyA9IHRoaXMuZGVjb2RlKGlucHV0KSxcbiAgICAgICAgICAgIGFyID0gW10sIGk7XG4gICAgICAgIGZvciAoaT0wO2k8ZGVjLmxlbmd0aDtpKyspe1xuICAgICAgICAgICAgYXJbaV09ZGVjLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFyO1xuICAgIH0sXG4gICAgXG4gICAgZGVjb2RlR0VPTkV4VCA6IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgICAgICByZXR1cm4gZGVjb2RlQXNBcnJheShkZXN0cmlwKGlucHV0KSxmYWxzZSk7XG4gICAgfVxufTtcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5KWEcuVXRpbC5hc2NpaUNoYXJDb2RlQXQgPSBmdW5jdGlvbihzdHIsaSl7XG5cdHZhciBjID0gc3RyLmNoYXJDb2RlQXQoaSk7XG5cdGlmIChjPjI1NSl7XG4gICAgXHRzd2l0Y2ggKGMpIHtcblx0XHRcdGNhc2UgODM2NDogYz0xMjg7XG5cdCAgICBcdGJyZWFrO1xuXHQgICAgXHRjYXNlIDgyMTg6IGM9MTMwO1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0Y2FzZSA0MDI6IGM9MTMxO1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0Y2FzZSA4MjIyOiBjPTEzMjtcblx0ICAgIFx0YnJlYWs7XG5cdCAgICBcdGNhc2UgODIzMDogYz0xMzM7XG5cdCAgICBcdGJyZWFrO1xuXHQgICAgXHRjYXNlIDgyMjQ6IGM9MTM0O1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0Y2FzZSA4MjI1OiBjPTEzNTtcblx0ICAgIFx0YnJlYWs7XG5cdCAgICBcdGNhc2UgNzEwOiBjPTEzNjtcblx0ICAgIFx0YnJlYWs7XG5cdCAgICBcdGNhc2UgODI0MDogYz0xMzc7XG5cdCAgICBcdGJyZWFrO1xuXHQgICAgXHRjYXNlIDM1MjogYz0xMzg7XG5cdCAgICBcdGJyZWFrO1xuXHQgICAgXHRjYXNlIDgyNDk6IGM9MTM5O1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0Y2FzZSAzMzg6IGM9MTQwO1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0Y2FzZSAzODE6IGM9MTQyO1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0Y2FzZSA4MjE2OiBjPTE0NTtcblx0ICAgIFx0YnJlYWs7XG5cdCAgICBcdGNhc2UgODIxNzogYz0xNDY7XG5cdCAgICBcdGJyZWFrO1xuXHQgICAgXHRjYXNlIDgyMjA6IGM9MTQ3O1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0Y2FzZSA4MjIxOiBjPTE0ODtcblx0ICAgIFx0YnJlYWs7XG5cdCAgICBcdGNhc2UgODIyNjogYz0xNDk7XG5cdCAgICBcdGJyZWFrO1xuXHQgICAgXHRjYXNlIDgyMTE6IGM9MTUwO1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0Y2FzZSA4MjEyOiBjPTE1MTtcblx0ICAgIFx0YnJlYWs7XG5cdCAgICBcdGNhc2UgNzMyOiBjPTE1Mjtcblx0ICAgIFx0YnJlYWs7XG5cdCAgICBcdGNhc2UgODQ4MjogYz0xNTM7XG5cdCAgICBcdGJyZWFrO1xuXHQgICAgXHRjYXNlIDM1MzogYz0xNTQ7XG5cdCAgICBcdGJyZWFrO1xuXHQgICAgXHRjYXNlIDgyNTA6IGM9MTU1O1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0Y2FzZSAzMzk6IGM9MTU2O1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0Y2FzZSAzODI6IGM9MTU4O1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0Y2FzZSAzNzY6IGM9MTU5O1xuXHQgICAgXHRicmVhaztcblx0ICAgIFx0ZGVmYXVsdDpcblx0ICAgIFx0YnJlYWs7XG5cdCAgICB9XG5cdH1cblx0cmV0dXJuIGM7XG59O1xuXG4vKipcbiAqIERlY29kaW5nIHN0cmluZyBpbnRvIHV0Zi04XG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyaW5nIHRvIGRlY29kZVxuICogQHJldHVybiB7U3RyaW5nfSB1dGY4IGRlY29kZWQgc3RyaW5nXG4gKi9cbkpYRy5VdGlsLnV0ZjhEZWNvZGUgPSBmdW5jdGlvbih1dGZ0ZXh0KSB7XG4gIHZhciBzdHJpbmcgPSBbXTtcbiAgdmFyIGkgPSAwO1xuICB2YXIgYyA9IDAsIGMxID0gMCwgYzIgPSAwLCBjMztcbiAgaWYgKCFKWEcuZXhpc3RzKHV0ZnRleHQpKSByZXR1cm4gJyc7XG4gIFxuICB3aGlsZSAoIGkgPCB1dGZ0ZXh0Lmxlbmd0aCApIHtcbiAgICBjID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkpO1xuXG4gICAgaWYgKGMgPCAxMjgpIHtcbiAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYykpO1xuICAgICAgaSsrO1xuICAgIH0gZWxzZSBpZigoYyA+IDE5MSkgJiYgKGMgPCAyMjQpKSB7XG4gICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpKzEpO1xuICAgICAgc3RyaW5nLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgJiAzMSkgPDwgNikgfCAoYzIgJiA2MykpKTtcbiAgICAgIGkgKz0gMjtcbiAgICB9IGVsc2Uge1xuICAgICAgYzIgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSsxKTtcbiAgICAgIGMzID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkrMik7XG4gICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAmIDE1KSA8PCAxMikgfCAoKGMyICYgNjMpIDw8IDYpIHwgKGMzICYgNjMpKSk7XG4gICAgICBpICs9IDM7XG4gICAgfVxuICB9O1xuICByZXR1cm4gc3RyaW5nLmpvaW4oJycpO1xufTtcblxuLyoqXG4gKiBHZW5lcmF0ZSBhIHJhbmRvbSB1dWlkLlxuICogaHR0cDovL3d3dy5icm9vZmEuY29tXG4gKiBtYWlsdG86cm9iZXJ0QGJyb29mYS5jb21cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTAgUm9iZXJ0IEtpZWZmZXJcbiAqIER1YWwgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBhbmQgR1BMIGxpY2Vuc2VzLlxuICpcbiAqIEVYQU1QTEVTOlxuICogICA+Pj4gTWF0aC51dWlkKClcbiAqICAgXCI5MjMyOUQzOS02RjVDLTQ1MjAtQUJGQy1BQUI2NDU0NEUxNzJcIlxuICovXG5KWEcuVXRpbC5nZW5VVUlEID0gZnVuY3Rpb24oKSB7XG4gICAgLy8gUHJpdmF0ZSBhcnJheSBvZiBjaGFycyB0byB1c2VcbiAgICB2YXIgY2hhcnMgPSAnMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXonLnNwbGl0KCcnKSxcbiAgICAgICAgdXVpZCA9IG5ldyBBcnJheSgzNiksIHJuZD0wLCByO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAzNjsgaSsrKSB7XG4gICAgICBpZiAoaT09OCB8fCBpPT0xMyB8fCAgaT09MTggfHwgaT09MjMpIHtcbiAgICAgICAgdXVpZFtpXSA9ICctJztcbiAgICAgIH0gZWxzZSBpZiAoaT09MTQpIHtcbiAgICAgICAgdXVpZFtpXSA9ICc0JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChybmQgPD0gMHgwMikgcm5kID0gMHgyMDAwMDAwICsgKE1hdGgucmFuZG9tKCkqMHgxMDAwMDAwKXwwO1xuICAgICAgICByID0gcm5kICYgMHhmO1xuICAgICAgICBybmQgPSBybmQgPj4gNDtcbiAgICAgICAgdXVpZFtpXSA9IGNoYXJzWyhpID09IDE5KSA/IChyICYgMHgzKSB8IDB4OCA6IHJdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB1dWlkLmpvaW4oJycpO1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IEpYRztcbiIsIi8vIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSCBcblxuLy8gbW9kaWZpZWQgdmVyc2lvbiBvZiBodHRwOi8vd3d3LmhhbmV3aW4ubmV0L2VuY3J5cHQvUEdkZWNvZGUuanM6XG5cbi8qIE9wZW5QR1AgZW5jcnlwdGlvbiB1c2luZyBSU0EvQUVTXG4gKiBDb3B5cmlnaHQgMjAwNS0yMDA2IEhlcmJlcnQgSGFuZXdpbmtlbCwgd3d3LmhhbmVXSU4uZGVcbiAqIHZlcnNpb24gMi4wLCBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uXG5cbiAqIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYXMtaXMsIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LiAgXG4gKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlIG9yIHNlbGwgdGhpcyBzb2Z0d2FyZSwgd2l0aCBvclxuICogd2l0aG91dCBmZWUsIGZvciBhbnkgcHVycG9zZSBhbmQgYnkgYW55IGluZGl2aWR1YWwgb3Igb3JnYW5pemF0aW9uLCBpcyBoZXJlYnlcbiAqIGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGFyYWdyYXBoIGFwcGVhciBcbiAqIGluIGFsbCBjb3BpZXMuIERpc3RyaWJ1dGlvbiBhcyBhIHBhcnQgb2YgYW4gYXBwbGljYXRpb24gb3IgYmluYXJ5IG11c3RcbiAqIGluY2x1ZGUgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyXG4gKiBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgYXBwbGljYXRpb24gb3IgZGlzdHJpYnV0aW9uLlxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuXHRjaXBoZXIgPSByZXF1aXJlKCcuL2NpcGhlcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblxuXHQvKipcblx0ICogQW4gYXJyYXkgb2YgYnl0ZXMsIHRoYXQgaXMgaW50ZWdlcnMgd2l0aCB2YWx1ZXMgZnJvbSAwIHRvIDI1NVxuXHQgKiBAdHlwZWRlZiB7KEFycmF5fFVpbnQ4QXJyYXkpfSBvcGVucGdwX2J5dGVfYXJyYXlcblx0ICovXG5cblx0LyoqXG5cdCAqIEJsb2NrIGNpcGhlciBmdW5jdGlvblxuXHQgKiBAY2FsbGJhY2sgb3BlbnBncF9jaXBoZXJfYmxvY2tfZm5cblx0ICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGJsb2NrIEEgYmxvY2sgdG8gcGVyZm9ybSBvcGVyYXRpb25zIG9uXG5cdCAqIEBwYXJhbSB7b3BlbnBncF9ieXRlX2FycmF5fSBrZXkgdG8gdXNlIGluIGVuY3J5cHRpb24vZGVjcnlwdGlvblxuXHQgKiBAcmV0dXJuIHtvcGVucGdwX2J5dGVfYXJyYXl9IEVuY3J5cHRlZC9kZWNyeXB0ZWQgYmxvY2tcblx0ICovXG5cblxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvKipcblx0ICogVGhpcyBmdW5jdGlvbiBlbmNyeXB0cyBhIGdpdmVuIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXhyYW5kb20gXG5cdCAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgYmxvY2tjaXBoZXIgdG8gZW5jcnlwdCBhIG1lc3NhZ2Vcblx0ICogQHBhcmFtIHtTdHJpbmd9IHByZWZpeHJhbmRvbSByYW5kb20gYnl0ZXMgb2YgYmxvY2tfc2l6ZSBsZW5ndGggcHJvdmlkZWQgXG5cdCAqICBhcyBhIHN0cmluZyB0byBiZSB1c2VkIGluIHByZWZpeGluZyB0aGUgZGF0YVxuXHQgKiBAcGFyYW0ge29wZW5wZ3BfY2lwaGVyX2Jsb2NrX2ZufSBibG9ja2NpcGhlcmZuIHRoZSBhbGdvcml0aG0gZW5jcnlwdCBmdW5jdGlvbiB0byBlbmNyeXB0XG5cdCAqICBkYXRhIGluIG9uZSBibG9ja19zaXplIGVuY3J5cHRpb24uIFxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IGJsb2NrX3NpemUgdGhlIGJsb2NrIHNpemUgaW4gYnl0ZXMgb2YgdGhlIGFsZ29yaXRobSB1c2VkXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBwbGFpbnRleHQgZGF0YSB0byBiZSBlbmNyeXB0ZWQgcHJvdmlkZWQgYXMgYSBzdHJpbmdcblx0ICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGtleSBrZXkgdG8gYmUgdXNlZCB0byBlbmNyeXB0IHRoZSBkYXRhLiBUaGlzIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBcblx0ICogIGJsb2NrY2lwaGVyZm5cblx0ICogQHBhcmFtIHtCb29sZWFufSByZXN5bmMgYSBib29sZWFuIHZhbHVlIHNwZWNpZnlpbmcgaWYgYSByZXN5bmMgb2YgdGhlIFxuXHQgKiAgSVYgc2hvdWxkIGJlIHVzZWQgb3Igbm90LiBUaGUgZW5jcnlwdGVkZGF0YXBhY2tldCB1c2VzIHRoZSBcblx0ICogIFwib2xkXCIgc3R5bGUgd2l0aCBhIHJlc3luYy4gRW5jcnlwdGlvbiB3aXRoaW4gYW4gXG5cdCAqICBlbmNyeXB0ZWRpbnRlZ3JpdHlwcm90ZWN0ZWRkYXRhIHBhY2tldCBpcyBub3QgcmVzeW5jaW5nIHRoZSBJVi5cblx0ICogQHJldHVybiB7U3RyaW5nfSBhIHN0cmluZyB3aXRoIHRoZSBlbmNyeXB0ZWQgZGF0YVxuXHQgKi9cblx0ZW5jcnlwdDogZnVuY3Rpb24gKHByZWZpeHJhbmRvbSwgY2lwaGVyZm4sIHBsYWludGV4dCwga2V5LCByZXN5bmMpIHtcblx0XHRjaXBoZXJmbiA9IG5ldyBjaXBoZXJbY2lwaGVyZm5dKGtleSk7XG5cdFx0dmFyIGJsb2NrX3NpemUgPSBjaXBoZXJmbi5ibG9ja1NpemU7XG5cblx0XHR2YXIgRlIgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG5cdFx0dmFyIEZSRSA9IG5ldyBBcnJheShibG9ja19zaXplKTtcblxuXHRcdHByZWZpeHJhbmRvbSA9IHByZWZpeHJhbmRvbSArIHByZWZpeHJhbmRvbS5jaGFyQXQoYmxvY2tfc2l6ZS0yKSArcHJlZml4cmFuZG9tLmNoYXJBdChibG9ja19zaXplLTEpO1xuXHRcdHV0aWwucHJpbnRfZGVidWcoXCJwcmVmaXhyYW5kb206XCIrdXRpbC5oZXhzdHJkdW1wKHByZWZpeHJhbmRvbSkpO1xuXHRcdHZhciBjaXBoZXJ0ZXh0ID0gXCJcIjtcblx0XHQvLyAxLiAgVGhlIGZlZWRiYWNrIHJlZ2lzdGVyIChGUikgaXMgc2V0IHRvIHRoZSBJViwgd2hpY2ggaXMgYWxsIHplcm9zLlxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IDA7XG5cdFx0XG5cdFx0Ly8gMi4gIEZSIGlzIGVuY3J5cHRlZCB0byBwcm9kdWNlIEZSRSAoRlIgRW5jcnlwdGVkKS4gIFRoaXMgaXMgdGhlXG5cdFx0Ly8gICAgIGVuY3J5cHRpb24gb2YgYW4gYWxsLXplcm8gdmFsdWUuXG5cdFx0RlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUik7XG5cdFx0Ly8gMy4gIEZSRSBpcyB4b3JlZCB3aXRoIHRoZSBmaXJzdCBCUyBvY3RldHMgb2YgcmFuZG9tIGRhdGEgcHJlZml4ZWQgdG9cblx0XHQvLyAgICAgdGhlIHBsYWludGV4dCB0byBwcm9kdWNlIENbMV0gdGhyb3VnaCBDW0JTXSwgdGhlIGZpcnN0IEJTIG9jdGV0c1xuXHRcdC8vICAgICBvZiBjaXBoZXJ0ZXh0LlxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcHJlZml4cmFuZG9tLmNoYXJDb2RlQXQoaSkpO1xuXHRcdFxuXHRcdC8vIDQuICBGUiBpcyBsb2FkZWQgd2l0aCBDWzFdIHRocm91Z2ggQ1tCU10uXG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGkpO1xuXHRcdFxuXHRcdC8vIDUuICBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUsIHRoZSBlbmNyeXB0aW9uIG9mIHRoZSBmaXJzdCBCU1xuXHRcdC8vIFx0ICAgb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG5cdFx0RlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUik7XG5cblx0XHQvLyA2LiAgVGhlIGxlZnQgdHdvIG9jdGV0cyBvZiBGUkUgZ2V0IHhvcmVkIHdpdGggdGhlIG5leHQgdHdvIG9jdGV0cyBvZlxuXHRcdC8vICAgICBkYXRhIHRoYXQgd2VyZSBwcmVmaXhlZCB0byB0aGUgcGxhaW50ZXh0LiAgVGhpcyBwcm9kdWNlcyBDW0JTKzFdXG5cdFx0Ly8gICAgIGFuZCBDW0JTKzJdLCB0aGUgbmV4dCB0d28gb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG5cdFx0Y2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVswXSBeIHByZWZpeHJhbmRvbS5jaGFyQ29kZUF0KGJsb2NrX3NpemUpKTtcblx0XHRjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFWzFdIF4gcHJlZml4cmFuZG9tLmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSsxKSk7XG5cblx0XHRpZiAocmVzeW5jKSB7XG5cdFx0XHQvLyA3LiAgKFRoZSByZXN5bmMgc3RlcCkgRlIgaXMgbG9hZGVkIHdpdGggQzMtQzEwLlxuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGkrMik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcblx0XHR9XG5cdFx0Ly8gOC4gIEZSIGlzIGVuY3J5cHRlZCB0byBwcm9kdWNlIEZSRS5cblx0XHRGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSLCBrZXkpO1xuXHRcdFxuXHRcdGlmIChyZXN5bmMpIHtcblx0XHRcdC8vIDkuICBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgZmlyc3QgOCBvY3RldHMgb2YgdGhlIGdpdmVuIHBsYWludGV4dCwgbm93XG5cdFx0XHQvL1x0ICAgdGhhdCB3ZSBoYXZlIGZpbmlzaGVkIGVuY3J5cHRpbmcgdGhlIDEwIG9jdGV0cyBvZiBwcmVmaXhlZCBkYXRhLlxuXHRcdFx0Ly8gXHQgICBUaGlzIHByb2R1Y2VzIEMxMS1DMTgsIHRoZSBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuXG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKylcblx0XHRcdFx0Y2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KGkpKTtcblx0XHRcdGZvcihuPWJsb2NrX3NpemUrMjsgbiA8IHBsYWludGV4dC5sZW5ndGg7IG4rPWJsb2NrX3NpemUpIHtcblx0XHRcdFx0Ly8gMTAuIEZSIGlzIGxvYWRlZCB3aXRoIEMxMS1DMThcblx0XHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KG4raSk7XG5cdFx0XHRcblx0XHRcdFx0Ly8gMTEuIEZSIGlzIGVuY3J5cHRlZCB0byBwcm9kdWNlIEZSRS5cblx0XHRcdFx0RlJFID0gY2lwaGVyZm4uZW5jcnlwdChGUik7XG5cdFx0XHRcblx0XHRcdFx0Ly8gMTIuIEZSRSBpcyB4b3JlZCB3aXRoIHRoZSBuZXh0IDggb2N0ZXRzIG9mIHBsYWludGV4dCwgdG8gcHJvZHVjZSB0aGVcblx0XHRcdFx0Ly8gbmV4dCA4IG9jdGV0cyBvZiBjaXBoZXJ0ZXh0LiAgVGhlc2UgYXJlIGxvYWRlZCBpbnRvIEZSIGFuZCB0aGVcblx0XHRcdFx0Ly8gcHJvY2VzcyBpcyByZXBlYXRlZCB1bnRpbCB0aGUgcGxhaW50ZXh0IGlzIHVzZWQgdXAuXG5cdFx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQoKG4tMikraSkpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdHBsYWludGV4dCA9IFwiICBcIitwbGFpbnRleHQ7XG5cdFx0XHQvLyA5LiAgRlJFIGlzIHhvcmVkIHdpdGggdGhlIGZpcnN0IDggb2N0ZXRzIG9mIHRoZSBnaXZlbiBwbGFpbnRleHQsIG5vd1xuXHRcdFx0Ly9cdCAgIHRoYXQgd2UgaGF2ZSBmaW5pc2hlZCBlbmNyeXB0aW5nIHRoZSAxMCBvY3RldHMgb2YgcHJlZml4ZWQgZGF0YS5cblx0XHRcdC8vIFx0ICAgVGhpcyBwcm9kdWNlcyBDMTEtQzE4LCB0aGUgbmV4dCA4IG9jdGV0cyBvZiBjaXBoZXJ0ZXh0LlxuXHRcdFx0Zm9yICh2YXIgaSA9IDI7IGkgPCBibG9ja19zaXplOyBpKyspIGNpcGhlcnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwbGFpbnRleHQuY2hhckNvZGVBdChpKSk7XG5cdFx0XHR2YXIgdGVtcENpcGhlcnRleHQgPSBjaXBoZXJ0ZXh0LnN1YnN0cmluZygwLDIqYmxvY2tfc2l6ZSkuc3BsaXQoJycpO1xuXHRcdFx0dmFyIHRlbXBDaXBoZXJ0ZXh0U3RyaW5nID0gY2lwaGVydGV4dC5zdWJzdHJpbmcoYmxvY2tfc2l6ZSk7XG5cdFx0XHRmb3Iobj1ibG9ja19zaXplOyBuPHBsYWludGV4dC5sZW5ndGg7IG4rPWJsb2NrX3NpemUpIHtcblx0XHRcdFx0Ly8gMTAuIEZSIGlzIGxvYWRlZCB3aXRoIEMxMS1DMThcblx0XHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gdGVtcENpcGhlcnRleHRTdHJpbmcuY2hhckNvZGVBdChpKTtcblx0XHRcdFx0dGVtcENpcGhlcnRleHRTdHJpbmc9Jyc7XG5cdFx0XHRcdFxuXHRcdFx0XHQvLyAxMS4gRlIgaXMgZW5jcnlwdGVkIHRvIHByb2R1Y2UgRlJFLlxuXHRcdFx0XHRGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSKTtcblx0XHRcdFx0XG5cdFx0XHRcdC8vIDEyLiBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgbmV4dCA4IG9jdGV0cyBvZiBwbGFpbnRleHQsIHRvIHByb2R1Y2UgdGhlXG5cdFx0XHRcdC8vICAgICBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuICBUaGVzZSBhcmUgbG9hZGVkIGludG8gRlIgYW5kIHRoZVxuXHRcdFx0XHQvLyAgICAgcHJvY2VzcyBpcyByZXBlYXRlZCB1bnRpbCB0aGUgcGxhaW50ZXh0IGlzIHVzZWQgdXAuXG5cdFx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKXsgdGVtcENpcGhlcnRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KG4raSkpKTtcblx0XHRcdFx0dGVtcENpcGhlcnRleHRTdHJpbmcgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwbGFpbnRleHQuY2hhckNvZGVBdChuK2kpKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Y2lwaGVydGV4dCA9IHRlbXBDaXBoZXJ0ZXh0LmpvaW4oJycpO1xuXHRcdFx0XG5cdFx0fVxuXG5cdFx0Y2lwaGVydGV4dCA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKDAsIHBsYWludGV4dC5sZW5ndGggKyAyICsgYmxvY2tfc2l6ZSk7XG5cblx0XHRyZXR1cm4gY2lwaGVydGV4dDtcblx0fSxcblxuXHQvKipcblx0ICogRGVjcnlwdHMgdGhlIHByZWZpeGVkIGRhdGEgZm9yIHRoZSBNb2RpZmljYXRpb24gRGV0ZWN0aW9uIENvZGUgKE1EQykgY29tcHV0YXRpb25cblx0ICogQHBhcmFtIHtvcGVucGdwX2Jsb2NrX2NpcGhlcl9mbn0gY2lwaGVyZm4uZW5jcnlwdCBDaXBoZXIgZnVuY3Rpb24gdG8gdXNlXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gYmxvY2tfc2l6ZSBCbG9ja3NpemUgb2YgdGhlIGFsZ29yaXRobVxuXHQgKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZV9hcnJheX0ga2V5IFRoZSBrZXkgZm9yIGVuY3J5cHRpb25cblx0ICogQHBhcmFtIHtTdHJpbmd9IGNpcGhlcnRleHQgVGhlIGVuY3J5cHRlZCBkYXRhXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gcGxhaW50ZXh0IERhdGEgb2YgRChjaXBoZXJ0ZXh0KSB3aXRoIGJsb2Nrc2l6ZSBsZW5ndGggKzJcblx0ICovXG5cdG1kYzogZnVuY3Rpb24gKGNpcGhlcmZuLCBrZXksIGNpcGhlcnRleHQpIHtcblx0XHRjaXBoZXJmbiA9IG5ldyBjaXBoZXJbY2lwaGVyZm5dKGtleSk7XG5cdFx0dmFyIGJsb2NrX3NpemUgPSBjaXBoZXJmbi5ibG9ja1NpemU7XG5cblx0XHR2YXIgaWJsb2NrID0gbmV3IEFycmF5KGJsb2NrX3NpemUpO1xuXHRcdHZhciBhYmxvY2sgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG5cdFx0dmFyIGk7XG5cblxuXHRcdC8vIGluaXRpYWxpc2F0aW9uIHZlY3RvclxuXHRcdGZvcihpPTA7IGkgPCBibG9ja19zaXplOyBpKyspIGlibG9ja1tpXSA9IDA7XG5cblx0XHRpYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KGlibG9jayk7XG5cdFx0Zm9yKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKVxuXHRcdHtcblx0XHRcdGFibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcblx0XHRcdGlibG9ja1tpXSBePSBhYmxvY2tbaV07XG5cdFx0fVxuXG5cdFx0YWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChhYmxvY2spO1xuXG5cdFx0cmV0dXJuIHV0aWwuYmluMnN0cihpYmxvY2spK1xuXHRcdFx0U3RyaW5nLmZyb21DaGFyQ29kZShhYmxvY2tbMF1eY2lwaGVydGV4dC5jaGFyQ29kZUF0KGJsb2NrX3NpemUpKStcblx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoYWJsb2NrWzFdXmNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplKzEpKTtcblx0fSxcblx0LyoqXG5cdCAqIFRoaXMgZnVuY3Rpb24gZGVjcnlwdHMgYSBnaXZlbiBwbGFpbnRleHQgdXNpbmcgdGhlIHNwZWNpZmllZFxuXHQgKiBibG9ja2NpcGhlciB0byBkZWNyeXB0IGEgbWVzc2FnZVxuXHQgKiBAcGFyYW0ge29wZW5wZ3BfY2lwaGVyX2Jsb2NrX2ZufSBibG9ja2NpcGhlcmZuIFRoZSBhbGdvcml0aG0gX2VuY3J5cHRfIGZ1bmN0aW9uIHRvIGVuY3J5cHRcblx0ICogIGRhdGEgaW4gb25lIGJsb2NrX3NpemUgZW5jcnlwdGlvbi5cblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBibG9ja19zaXplIHRoZSBibG9jayBzaXplIGluIGJ5dGVzIG9mIHRoZSBhbGdvcml0aG0gdXNlZFxuXHQgKiBAcGFyYW0ge1N0cmluZ30gcGxhaW50ZXh0IGNpcGhlcnRleHQgdG8gYmUgZGVjcnlwdGVkIHByb3ZpZGVkIGFzIGEgc3RyaW5nXG5cdCAqIEBwYXJhbSB7b3BlbnBncF9ieXRlX2FycmF5fSBrZXkga2V5IHRvIGJlIHVzZWQgdG8gZGVjcnlwdCB0aGUgY2lwaGVydGV4dC4gVGhpcyB3aWxsIGJlIHBhc3NlZCB0byB0aGUgXG5cdCAqICBibG9ja2NpcGhlcmZuXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVzeW5jIGEgYm9vbGVhbiB2YWx1ZSBzcGVjaWZ5aW5nIGlmIGEgcmVzeW5jIG9mIHRoZSBcblx0ICogIElWIHNob3VsZCBiZSB1c2VkIG9yIG5vdC4gVGhlIGVuY3J5cHRlZGRhdGFwYWNrZXQgdXNlcyB0aGUgXG5cdCAqICBcIm9sZFwiIHN0eWxlIHdpdGggYSByZXN5bmMuIERlY3J5cHRpb24gd2l0aGluIGFuIFxuXHQgKiAgZW5jcnlwdGVkaW50ZWdyaXR5cHJvdGVjdGVkZGF0YSBwYWNrZXQgaXMgbm90IHJlc3luY2luZyB0aGUgSVYuXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmcgd2l0aCB0aGUgcGxhaW50ZXh0IGRhdGFcblx0ICovXG5cblx0ZGVjcnlwdDogZnVuY3Rpb24gKGNpcGhlcmZuLCBrZXksIGNpcGhlcnRleHQsIHJlc3luYykge1xuXHRcdGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcblx0XHR2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuXHRcdHZhciBpYmxvY2sgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG5cdFx0dmFyIGFibG9jayA9IG5ldyBBcnJheShibG9ja19zaXplKTtcblx0XHR2YXIgaSwgbiA9ICcnO1xuXHRcdHZhciB0ZXh0ID0gW107XG5cblx0XHQvLyBpbml0aWFsaXNhdGlvbiB2ZWN0b3Jcblx0XHRmb3IoaT0wOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSAwO1xuXG5cdFx0aWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChpYmxvY2ssIGtleSk7XG5cdFx0Zm9yKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKVxuXHRcdHtcblx0XHRcdGFibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcblx0XHRcdGlibG9ja1tpXSBePSBhYmxvY2tbaV07XG5cdFx0fVxuXG5cdFx0YWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChhYmxvY2ssIGtleSk7XG5cblx0XHQvLyB0ZXN0IGNoZWNrIG9jdGV0c1xuXHRcdGlmKGlibG9ja1tibG9ja19zaXplLTJdIT0oYWJsb2NrWzBdXmNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplKSlcblx0XHR8fCBpYmxvY2tbYmxvY2tfc2l6ZS0xXSE9KGFibG9ja1sxXV5jaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSsxKSkpXG5cdFx0e1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGRhdGEuJyk7XG5cdFx0fVxuXHRcdFxuXHRcdC8qICBSRkM0ODgwOiBUYWcgMTggYW5kIFJlc3luYzpcblx0XHQgKiAgWy4uLl0gVW5saWtlIHRoZSBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCwgbm9cblx0XHQgKiAgc3BlY2lhbCBDRkIgcmVzeW5jaHJvbml6YXRpb24gaXMgZG9uZSBhZnRlciBlbmNyeXB0aW5nIHRoaXMgcHJlZml4XG5cdFx0ICogIGRhdGEuICBTZWUgXCJPcGVuUEdQIENGQiBNb2RlXCIgYmVsb3cgZm9yIG1vcmUgZGV0YWlscy5cblxuXHRcdCAqL1xuXHRcdFxuXHRcdGlmIChyZXN5bmMpIHtcblx0XHRcdGZvcihpPTA7IGk8YmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSsyKTtcblx0XHRcdGZvcihuPWJsb2NrX3NpemUrMjsgbjxjaXBoZXJ0ZXh0Lmxlbmd0aDsgbis9YmxvY2tfc2l6ZSlcblx0XHRcdHtcblx0XHRcdFx0YWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChpYmxvY2spO1xuXG5cdFx0XHRcdGZvcihpID0gMDsgaTxibG9ja19zaXplICYmIGkrbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBpKyspXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQobitpKTtcblx0XHRcdFx0XHR0ZXh0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShhYmxvY2tbaV1eaWJsb2NrW2ldKSk7IFxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvcihpPTA7IGk8YmxvY2tfc2l6ZTsgaSsrKSBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSk7XG5cdFx0XHRmb3Iobj1ibG9ja19zaXplOyBuPGNpcGhlcnRleHQubGVuZ3RoOyBuKz1ibG9ja19zaXplKVxuXHRcdFx0e1xuXHRcdFx0XHRhYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KGlibG9jayk7XG5cdFx0XHRcdGZvcihpID0gMDsgaTxibG9ja19zaXplICYmIGkrbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBpKyspXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQobitpKTtcblx0XHRcdFx0XHR0ZXh0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShhYmxvY2tbaV1eaWJsb2NrW2ldKSk7IFxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dmFyIG4gPSByZXN5bmMgPyAwIDogMjtcblxuXHRcdHRleHQgPSB0ZXh0LmpvaW4oJycpO1xuXG5cdFx0dGV4dCA9IHRleHQuc3Vic3RyaW5nKG4sIGNpcGhlcnRleHQubGVuZ3RoIC0gYmxvY2tfc2l6ZSAtIDIgKyBuKTtcblxuXHRcdFxuXHRcdHJldHVybiB0ZXh0O1xuXHR9LFxuXG5cblx0bm9ybWFsRW5jcnlwdDogZnVuY3Rpb24oY2lwaGVyZm4sIGtleSwgcGxhaW50ZXh0LCBpdikge1xuXHRcdGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcblx0XHR2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuXHRcdHZhciBibG9ja2kgPVwiXCI7XG5cdFx0dmFyIGJsb2NrYyA9IFwiXCI7XG5cdFx0dmFyIHBvcyA9IDA7XG5cdFx0dmFyIGN5cGhlcnRleHQgPSBbXTtcblx0XHR2YXIgdGVtcEJsb2NrID0gW107XG5cdFx0YmxvY2tjID0gaXYuc3Vic3RyaW5nKDAsYmxvY2tfc2l6ZSk7XG5cdFx0d2hpbGUgKHBsYWludGV4dC5sZW5ndGggPiBibG9ja19zaXplKnBvcykge1xuXHRcdFx0dmFyIGVuY2Jsb2NrID0gY2lwaGVyZm4uZW5jcnlwdCh1dGlsLnN0cjJiaW4oYmxvY2tjKSk7XG5cdFx0XHRibG9ja2kgPSBwbGFpbnRleHQuc3Vic3RyaW5nKChwb3MqYmxvY2tfc2l6ZSksKHBvcypibG9ja19zaXplKStibG9ja19zaXplKTtcblx0XHRcdGZvciAodmFyIGk9MDsgaSA8IGJsb2NraS5sZW5ndGg7IGkrKylcblx0XHRcdFx0dGVtcEJsb2NrLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShibG9ja2kuY2hhckNvZGVBdChpKSBeIGVuY2Jsb2NrW2ldKSk7XG5cdFx0XHRibG9ja2MgPSB0ZW1wQmxvY2suam9pbignJyk7XG5cdFx0XHR0ZW1wQmxvY2sgPSBbXTtcblx0XHRcdGN5cGhlcnRleHQucHVzaChibG9ja2MpO1xuXHRcdFx0cG9zKys7XG5cdFx0fVxuXHRcdHJldHVybiBjeXBoZXJ0ZXh0LmpvaW4oJycpO1xuXHR9LFxuXG5cdG5vcm1hbERlY3J5cHQ6IGZ1bmN0aW9uKGNpcGhlcmZuLCBrZXksIGNpcGhlcnRleHQsIGl2KSB7IFxuXHRcdGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcblx0XHR2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuXHRcdHZhciBibG9ja3AgPVwiXCI7XG5cdFx0dmFyIHBvcyA9IDA7XG5cdFx0dmFyIHBsYWludGV4dCA9IFtdO1xuXHRcdHZhciBvZmZzZXQgPSAwO1xuXHRcdGlmIChpdiA9PSBudWxsKVxuXHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGJsb2NrcCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuXHRcdGVsc2Vcblx0XHRcdGJsb2NrcCA9IGl2LnN1YnN0cmluZygwLGJsb2NrX3NpemUpO1xuXHRcdHdoaWxlIChjaXBoZXJ0ZXh0Lmxlbmd0aCA+IChibG9ja19zaXplKnBvcykpIHtcblx0XHRcdHZhciBkZWNibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQodXRpbC5zdHIyYmluKGJsb2NrcCkpO1xuXHRcdFx0YmxvY2twID0gY2lwaGVydGV4dC5zdWJzdHJpbmcoKHBvcyooYmxvY2tfc2l6ZSkpK29mZnNldCwocG9zKihibG9ja19zaXplKSkrKGJsb2NrX3NpemUpK29mZnNldCk7XG5cdFx0XHRmb3IgKHZhciBpPTA7IGkgPCBibG9ja3AubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0cGxhaW50ZXh0LnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShibG9ja3AuY2hhckNvZGVBdChpKSBeIGRlY2Jsb2NrW2ldKSk7XG5cdFx0XHR9XG5cdFx0XHRwb3MrKztcblx0XHR9XG5cdFx0XG5cdFx0cmV0dXJuIHBsYWludGV4dC5qb2luKCcnKTtcblx0fVxufVxuIiwiXG4vKiBSaWpuZGFlbCAoQUVTKSBFbmNyeXB0aW9uXG4gKiBDb3B5cmlnaHQgMjAwNSBIZXJiZXJ0IEhhbmV3aW5rZWwsIHd3dy5oYW5lV0lOLmRlXG4gKiB2ZXJzaW9uIDEuMSwgY2hlY2sgd3d3LmhhbmVXSU4uZGUgZm9yIHRoZSBsYXRlc3QgdmVyc2lvblxuXG4gKiBUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkIGFzLWlzLCB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4gIFxuICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSBvciBzZWxsIHRoaXMgc29mdHdhcmUsIHdpdGggb3JcbiAqIHdpdGhvdXQgZmVlLCBmb3IgYW55IHB1cnBvc2UgYW5kIGJ5IGFueSBpbmRpdmlkdWFsIG9yIG9yZ2FuaXphdGlvbiwgaXMgaGVyZWJ5XG4gKiBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBhcmFncmFwaCBhcHBlYXIgXG4gKiBpbiBhbGwgY29waWVzLiBEaXN0cmlidXRpb24gYXMgYSBwYXJ0IG9mIGFuIGFwcGxpY2F0aW9uIG9yIGJpbmFyeSBtdXN0XG4gKiBpbmNsdWRlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlclxuICogbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGFwcGxpY2F0aW9uIG9yIGRpc3RyaWJ1dGlvbi5cbiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuLy8gVGhlIHJvdW5kIGNvbnN0YW50cyB1c2VkIGluIHN1YmtleSBleHBhbnNpb25cbnZhciBSY29uID0gWyBcbjB4MDEsIDB4MDIsIDB4MDQsIDB4MDgsIDB4MTAsIDB4MjAsIDB4NDAsIDB4ODAsIDB4MWIsIDB4MzYsIDB4NmMsIDB4ZDgsIFxuMHhhYiwgMHg0ZCwgMHg5YSwgMHgyZiwgMHg1ZSwgMHhiYywgMHg2MywgMHhjNiwgMHg5NywgMHgzNSwgMHg2YSwgMHhkNCwgXG4weGIzLCAweDdkLCAweGZhLCAweGVmLCAweGM1LCAweDkxIF07XG5cbi8vIFByZWNvbXB1dGVkIGxvb2t1cCB0YWJsZSBmb3IgdGhlIFNCb3hcbnZhciBTID0gW1xuIDk5LCAxMjQsIDExOSwgMTIzLCAyNDIsIDEwNywgMTExLCAxOTcsICA0OCwgICAxLCAxMDMsICA0MywgMjU0LCAyMTUsIDE3MSwgXG4xMTgsIDIwMiwgMTMwLCAyMDEsIDEyNSwgMjUwLCAgODksICA3MSwgMjQwLCAxNzMsIDIxMiwgMTYyLCAxNzUsIDE1NiwgMTY0LCBcbjExNCwgMTkyLCAxODMsIDI1MywgMTQ3LCAgMzgsICA1NCwgIDYzLCAyNDcsIDIwNCwgIDUyLCAxNjUsIDIyOSwgMjQxLCAxMTMsIFxuMjE2LCAgNDksICAyMSwgICA0LCAxOTksICAzNSwgMTk1LCAgMjQsIDE1MCwgICA1LCAxNTQsICAgNywgIDE4LCAxMjgsIDIyNiwgXG4yMzUsICAzOSwgMTc4LCAxMTcsICAgOSwgMTMxLCAgNDQsICAyNiwgIDI3LCAxMTAsICA5MCwgMTYwLCAgODIsICA1OSwgMjE0LCBcbjE3OSwgIDQxLCAyMjcsICA0NywgMTMyLCAgODMsIDIwOSwgICAwLCAyMzcsICAzMiwgMjUyLCAxNzcsICA5MSwgMTA2LCAyMDMsIFxuMTkwLCAgNTcsICA3NCwgIDc2LCAgODgsIDIwNywgMjA4LCAyMzksIDE3MCwgMjUxLCAgNjcsICA3NywgIDUxLCAxMzMsICA2OSwgXG4yNDksICAgMiwgMTI3LCAgODAsICA2MCwgMTU5LCAxNjgsICA4MSwgMTYzLCAgNjQsIDE0MywgMTQ2LCAxNTcsICA1NiwgMjQ1LCBcbjE4OCwgMTgyLCAyMTgsICAzMywgIDE2LCAyNTUsIDI0MywgMjEwLCAyMDUsICAxMiwgIDE5LCAyMzYsICA5NSwgMTUxLCAgNjgsICBcbjIzLCAgMTk2LCAxNjcsIDEyNiwgIDYxLCAxMDAsICA5MywgIDI1LCAxMTUsICA5NiwgMTI5LCAgNzksIDIyMCwgIDM0LCAgNDIsIFxuMTQ0LCAxMzYsICA3MCwgMjM4LCAxODQsICAyMCwgMjIyLCAgOTQsICAxMSwgMjE5LCAyMjQsICA1MCwgIDU4LCAgMTAsICA3MyxcbiAgNiwgIDM2LCAgOTIsIDE5NCwgMjExLCAxNzIsICA5OCwgMTQ1LCAxNDksIDIyOCwgMTIxLCAyMzEsIDIwMCwgIDU1LCAxMDksIFxuMTQxLCAyMTMsICA3OCwgMTY5LCAxMDgsICA4NiwgMjQ0LCAyMzQsIDEwMSwgMTIyLCAxNzQsICAgOCwgMTg2LCAxMjAsICAzNywgIFxuIDQ2LCAgMjgsIDE2NiwgMTgwLCAxOTgsIDIzMiwgMjIxLCAxMTYsICAzMSwgIDc1LCAxODksIDEzOSwgMTM4LCAxMTIsICA2MiwgXG4xODEsIDEwMiwgIDcyLCAgIDMsIDI0NiwgIDE0LCAgOTcsICA1MywgIDg3LCAxODUsIDEzNCwgMTkzLCAgMjksIDE1OCwgMjI1LFxuMjQ4LCAxNTIsICAxNywgMTA1LCAyMTcsIDE0MiwgMTQ4LCAxNTUsICAzMCwgMTM1LCAyMzMsIDIwNiwgIDg1LCAgNDAsIDIyMyxcbjE0MCwgMTYxLCAxMzcsICAxMywgMTkxLCAyMzAsICA2NiwgMTA0LCAgNjUsIDE1MywgIDQ1LCAgMTUsIDE3NiwgIDg0LCAxODcsICBcbiAyMiBdO1xuXG52YXIgVDEgPSBbXG4weGE1NjM2M2M2LCAweDg0N2M3Y2Y4LCAweDk5Nzc3N2VlLCAweDhkN2I3YmY2LFxuMHgwZGYyZjJmZiwgMHhiZDZiNmJkNiwgMHhiMTZmNmZkZSwgMHg1NGM1YzU5MSxcbjB4NTAzMDMwNjAsIDB4MDMwMTAxMDIsIDB4YTk2NzY3Y2UsIDB4N2QyYjJiNTYsXG4weDE5ZmVmZWU3LCAweDYyZDdkN2I1LCAweGU2YWJhYjRkLCAweDlhNzY3NmVjLFxuMHg0NWNhY2E4ZiwgMHg5ZDgyODIxZiwgMHg0MGM5Yzk4OSwgMHg4NzdkN2RmYSxcbjB4MTVmYWZhZWYsIDB4ZWI1OTU5YjIsIDB4Yzk0NzQ3OGUsIDB4MGJmMGYwZmIsXG4weGVjYWRhZDQxLCAweDY3ZDRkNGIzLCAweGZkYTJhMjVmLCAweGVhYWZhZjQ1LFxuMHhiZjljOWMyMywgMHhmN2E0YTQ1MywgMHg5NjcyNzJlNCwgMHg1YmMwYzA5YixcbjB4YzJiN2I3NzUsIDB4MWNmZGZkZTEsIDB4YWU5MzkzM2QsIDB4NmEyNjI2NGMsXG4weDVhMzYzNjZjLCAweDQxM2YzZjdlLCAweDAyZjdmN2Y1LCAweDRmY2NjYzgzLFxuMHg1YzM0MzQ2OCwgMHhmNGE1YTU1MSwgMHgzNGU1ZTVkMSwgMHgwOGYxZjFmOSxcbjB4OTM3MTcxZTIsIDB4NzNkOGQ4YWIsIDB4NTMzMTMxNjIsIDB4M2YxNTE1MmEsXG4weDBjMDQwNDA4LCAweDUyYzdjNzk1LCAweDY1MjMyMzQ2LCAweDVlYzNjMzlkLFxuMHgyODE4MTgzMCwgMHhhMTk2OTYzNywgMHgwZjA1MDUwYSwgMHhiNTlhOWEyZixcbjB4MDkwNzA3MGUsIDB4MzYxMjEyMjQsIDB4OWI4MDgwMWIsIDB4M2RlMmUyZGYsXG4weDI2ZWJlYmNkLCAweDY5MjcyNzRlLCAweGNkYjJiMjdmLCAweDlmNzU3NWVhLFxuMHgxYjA5MDkxMiwgMHg5ZTgzODMxZCwgMHg3NDJjMmM1OCwgMHgyZTFhMWEzNCxcbjB4MmQxYjFiMzYsIDB4YjI2ZTZlZGMsIDB4ZWU1YTVhYjQsIDB4ZmJhMGEwNWIsXG4weGY2NTI1MmE0LCAweDRkM2IzYjc2LCAweDYxZDZkNmI3LCAweGNlYjNiMzdkLFxuMHg3YjI5Mjk1MiwgMHgzZWUzZTNkZCwgMHg3MTJmMmY1ZSwgMHg5Nzg0ODQxMyxcbjB4ZjU1MzUzYTYsIDB4NjhkMWQxYjksIDB4MDAwMDAwMDAsIDB4MmNlZGVkYzEsXG4weDYwMjAyMDQwLCAweDFmZmNmY2UzLCAweGM4YjFiMTc5LCAweGVkNWI1YmI2LFxuMHhiZTZhNmFkNCwgMHg0NmNiY2I4ZCwgMHhkOWJlYmU2NywgMHg0YjM5Mzk3MixcbjB4ZGU0YTRhOTQsIDB4ZDQ0YzRjOTgsIDB4ZTg1ODU4YjAsIDB4NGFjZmNmODUsXG4weDZiZDBkMGJiLCAweDJhZWZlZmM1LCAweGU1YWFhYTRmLCAweDE2ZmJmYmVkLFxuMHhjNTQzNDM4NiwgMHhkNzRkNGQ5YSwgMHg1NTMzMzM2NiwgMHg5NDg1ODUxMSxcbjB4Y2Y0NTQ1OGEsIDB4MTBmOWY5ZTksIDB4MDYwMjAyMDQsIDB4ODE3ZjdmZmUsXG4weGYwNTA1MGEwLCAweDQ0M2MzYzc4LCAweGJhOWY5ZjI1LCAweGUzYThhODRiLFxuMHhmMzUxNTFhMiwgMHhmZWEzYTM1ZCwgMHhjMDQwNDA4MCwgMHg4YThmOGYwNSxcbjB4YWQ5MjkyM2YsIDB4YmM5ZDlkMjEsIDB4NDgzODM4NzAsIDB4MDRmNWY1ZjEsXG4weGRmYmNiYzYzLCAweGMxYjZiNjc3LCAweDc1ZGFkYWFmLCAweDYzMjEyMTQyLFxuMHgzMDEwMTAyMCwgMHgxYWZmZmZlNSwgMHgwZWYzZjNmZCwgMHg2ZGQyZDJiZixcbjB4NGNjZGNkODEsIDB4MTQwYzBjMTgsIDB4MzUxMzEzMjYsIDB4MmZlY2VjYzMsXG4weGUxNWY1ZmJlLCAweGEyOTc5NzM1LCAweGNjNDQ0NDg4LCAweDM5MTcxNzJlLFxuMHg1N2M0YzQ5MywgMHhmMmE3YTc1NSwgMHg4MjdlN2VmYywgMHg0NzNkM2Q3YSxcbjB4YWM2NDY0YzgsIDB4ZTc1ZDVkYmEsIDB4MmIxOTE5MzIsIDB4OTU3MzczZTYsXG4weGEwNjA2MGMwLCAweDk4ODE4MTE5LCAweGQxNGY0ZjllLCAweDdmZGNkY2EzLFxuMHg2NjIyMjI0NCwgMHg3ZTJhMmE1NCwgMHhhYjkwOTAzYiwgMHg4Mzg4ODgwYixcbjB4Y2E0NjQ2OGMsIDB4MjllZWVlYzcsIDB4ZDNiOGI4NmIsIDB4M2MxNDE0MjgsXG4weDc5ZGVkZWE3LCAweGUyNWU1ZWJjLCAweDFkMGIwYjE2LCAweDc2ZGJkYmFkLFxuMHgzYmUwZTBkYiwgMHg1NjMyMzI2NCwgMHg0ZTNhM2E3NCwgMHgxZTBhMGExNCxcbjB4ZGI0OTQ5OTIsIDB4MGEwNjA2MGMsIDB4NmMyNDI0NDgsIDB4ZTQ1YzVjYjgsXG4weDVkYzJjMjlmLCAweDZlZDNkM2JkLCAweGVmYWNhYzQzLCAweGE2NjI2MmM0LFxuMHhhODkxOTEzOSwgMHhhNDk1OTUzMSwgMHgzN2U0ZTRkMywgMHg4Yjc5NzlmMixcbjB4MzJlN2U3ZDUsIDB4NDNjOGM4OGIsIDB4NTkzNzM3NmUsIDB4Yjc2ZDZkZGEsXG4weDhjOGQ4ZDAxLCAweDY0ZDVkNWIxLCAweGQyNGU0ZTljLCAweGUwYTlhOTQ5LFxuMHhiNDZjNmNkOCwgMHhmYTU2NTZhYywgMHgwN2Y0ZjRmMywgMHgyNWVhZWFjZixcbjB4YWY2NTY1Y2EsIDB4OGU3YTdhZjQsIDB4ZTlhZWFlNDcsIDB4MTgwODA4MTAsXG4weGQ1YmFiYTZmLCAweDg4Nzg3OGYwLCAweDZmMjUyNTRhLCAweDcyMmUyZTVjLFxuMHgyNDFjMWMzOCwgMHhmMWE2YTY1NywgMHhjN2I0YjQ3MywgMHg1MWM2YzY5NyxcbjB4MjNlOGU4Y2IsIDB4N2NkZGRkYTEsIDB4OWM3NDc0ZTgsIDB4MjExZjFmM2UsXG4weGRkNGI0Yjk2LCAweGRjYmRiZDYxLCAweDg2OGI4YjBkLCAweDg1OGE4YTBmLFxuMHg5MDcwNzBlMCwgMHg0MjNlM2U3YywgMHhjNGI1YjU3MSwgMHhhYTY2NjZjYyxcbjB4ZDg0ODQ4OTAsIDB4MDUwMzAzMDYsIDB4MDFmNmY2ZjcsIDB4MTIwZTBlMWMsXG4weGEzNjE2MWMyLCAweDVmMzUzNTZhLCAweGY5NTc1N2FlLCAweGQwYjliOTY5LFxuMHg5MTg2ODYxNywgMHg1OGMxYzE5OSwgMHgyNzFkMWQzYSwgMHhiOTllOWUyNyxcbjB4MzhlMWUxZDksIDB4MTNmOGY4ZWIsIDB4YjM5ODk4MmIsIDB4MzMxMTExMjIsXG4weGJiNjk2OWQyLCAweDcwZDlkOWE5LCAweDg5OGU4ZTA3LCAweGE3OTQ5NDMzLFxuMHhiNjliOWIyZCwgMHgyMjFlMWUzYywgMHg5Mjg3ODcxNSwgMHgyMGU5ZTljOSxcbjB4NDljZWNlODcsIDB4ZmY1NTU1YWEsIDB4NzgyODI4NTAsIDB4N2FkZmRmYTUsXG4weDhmOGM4YzAzLCAweGY4YTFhMTU5LCAweDgwODk4OTA5LCAweDE3MGQwZDFhLFxuMHhkYWJmYmY2NSwgMHgzMWU2ZTZkNywgMHhjNjQyNDI4NCwgMHhiODY4NjhkMCxcbjB4YzM0MTQxODIsIDB4YjA5OTk5MjksIDB4NzcyZDJkNWEsIDB4MTEwZjBmMWUsXG4weGNiYjBiMDdiLCAweGZjNTQ1NGE4LCAweGQ2YmJiYjZkLCAweDNhMTYxNjJjIF07XG5cbnZhciBUMiA9IFtcbjB4NjM2M2M2YTUsIDB4N2M3Y2Y4ODQsIDB4Nzc3N2VlOTksIDB4N2I3YmY2OGQsXG4weGYyZjJmZjBkLCAweDZiNmJkNmJkLCAweDZmNmZkZWIxLCAweGM1YzU5MTU0LFxuMHgzMDMwNjA1MCwgMHgwMTAxMDIwMywgMHg2NzY3Y2VhOSwgMHgyYjJiNTY3ZCxcbjB4ZmVmZWU3MTksIDB4ZDdkN2I1NjIsIDB4YWJhYjRkZTYsIDB4NzY3NmVjOWEsXG4weGNhY2E4ZjQ1LCAweDgyODIxZjlkLCAweGM5Yzk4OTQwLCAweDdkN2RmYTg3LFxuMHhmYWZhZWYxNSwgMHg1OTU5YjJlYiwgMHg0NzQ3OGVjOSwgMHhmMGYwZmIwYixcbjB4YWRhZDQxZWMsIDB4ZDRkNGIzNjcsIDB4YTJhMjVmZmQsIDB4YWZhZjQ1ZWEsXG4weDljOWMyM2JmLCAweGE0YTQ1M2Y3LCAweDcyNzJlNDk2LCAweGMwYzA5YjViLFxuMHhiN2I3NzVjMiwgMHhmZGZkZTExYywgMHg5MzkzM2RhZSwgMHgyNjI2NGM2YSxcbjB4MzYzNjZjNWEsIDB4M2YzZjdlNDEsIDB4ZjdmN2Y1MDIsIDB4Y2NjYzgzNGYsXG4weDM0MzQ2ODVjLCAweGE1YTU1MWY0LCAweGU1ZTVkMTM0LCAweGYxZjFmOTA4LFxuMHg3MTcxZTI5MywgMHhkOGQ4YWI3MywgMHgzMTMxNjI1MywgMHgxNTE1MmEzZixcbjB4MDQwNDA4MGMsIDB4YzdjNzk1NTIsIDB4MjMyMzQ2NjUsIDB4YzNjMzlkNWUsXG4weDE4MTgzMDI4LCAweDk2OTYzN2ExLCAweDA1MDUwYTBmLCAweDlhOWEyZmI1LFxuMHgwNzA3MGUwOSwgMHgxMjEyMjQzNiwgMHg4MDgwMWI5YiwgMHhlMmUyZGYzZCxcbjB4ZWJlYmNkMjYsIDB4MjcyNzRlNjksIDB4YjJiMjdmY2QsIDB4NzU3NWVhOWYsXG4weDA5MDkxMjFiLCAweDgzODMxZDllLCAweDJjMmM1ODc0LCAweDFhMWEzNDJlLFxuMHgxYjFiMzYyZCwgMHg2ZTZlZGNiMiwgMHg1YTVhYjRlZSwgMHhhMGEwNWJmYixcbjB4NTI1MmE0ZjYsIDB4M2IzYjc2NGQsIDB4ZDZkNmI3NjEsIDB4YjNiMzdkY2UsXG4weDI5Mjk1MjdiLCAweGUzZTNkZDNlLCAweDJmMmY1ZTcxLCAweDg0ODQxMzk3LFxuMHg1MzUzYTZmNSwgMHhkMWQxYjk2OCwgMHgwMDAwMDAwMCwgMHhlZGVkYzEyYyxcbjB4MjAyMDQwNjAsIDB4ZmNmY2UzMWYsIDB4YjFiMTc5YzgsIDB4NWI1YmI2ZWQsXG4weDZhNmFkNGJlLCAweGNiY2I4ZDQ2LCAweGJlYmU2N2Q5LCAweDM5Mzk3MjRiLFxuMHg0YTRhOTRkZSwgMHg0YzRjOThkNCwgMHg1ODU4YjBlOCwgMHhjZmNmODU0YSxcbjB4ZDBkMGJiNmIsIDB4ZWZlZmM1MmEsIDB4YWFhYTRmZTUsIDB4ZmJmYmVkMTYsXG4weDQzNDM4NmM1LCAweDRkNGQ5YWQ3LCAweDMzMzM2NjU1LCAweDg1ODUxMTk0LFxuMHg0NTQ1OGFjZiwgMHhmOWY5ZTkxMCwgMHgwMjAyMDQwNiwgMHg3ZjdmZmU4MSxcbjB4NTA1MGEwZjAsIDB4M2MzYzc4NDQsIDB4OWY5ZjI1YmEsIDB4YThhODRiZTMsXG4weDUxNTFhMmYzLCAweGEzYTM1ZGZlLCAweDQwNDA4MGMwLCAweDhmOGYwNThhLFxuMHg5MjkyM2ZhZCwgMHg5ZDlkMjFiYywgMHgzODM4NzA0OCwgMHhmNWY1ZjEwNCxcbjB4YmNiYzYzZGYsIDB4YjZiNjc3YzEsIDB4ZGFkYWFmNzUsIDB4MjEyMTQyNjMsXG4weDEwMTAyMDMwLCAweGZmZmZlNTFhLCAweGYzZjNmZDBlLCAweGQyZDJiZjZkLFxuMHhjZGNkODE0YywgMHgwYzBjMTgxNCwgMHgxMzEzMjYzNSwgMHhlY2VjYzMyZixcbjB4NWY1ZmJlZTEsIDB4OTc5NzM1YTIsIDB4NDQ0NDg4Y2MsIDB4MTcxNzJlMzksXG4weGM0YzQ5MzU3LCAweGE3YTc1NWYyLCAweDdlN2VmYzgyLCAweDNkM2Q3YTQ3LFxuMHg2NDY0YzhhYywgMHg1ZDVkYmFlNywgMHgxOTE5MzIyYiwgMHg3MzczZTY5NSxcbjB4NjA2MGMwYTAsIDB4ODE4MTE5OTgsIDB4NGY0ZjllZDEsIDB4ZGNkY2EzN2YsXG4weDIyMjI0NDY2LCAweDJhMmE1NDdlLCAweDkwOTAzYmFiLCAweDg4ODgwYjgzLFxuMHg0NjQ2OGNjYSwgMHhlZWVlYzcyOSwgMHhiOGI4NmJkMywgMHgxNDE0MjgzYyxcbjB4ZGVkZWE3NzksIDB4NWU1ZWJjZTIsIDB4MGIwYjE2MWQsIDB4ZGJkYmFkNzYsXG4weGUwZTBkYjNiLCAweDMyMzI2NDU2LCAweDNhM2E3NDRlLCAweDBhMGExNDFlLFxuMHg0OTQ5OTJkYiwgMHgwNjA2MGMwYSwgMHgyNDI0NDg2YywgMHg1YzVjYjhlNCxcbjB4YzJjMjlmNWQsIDB4ZDNkM2JkNmUsIDB4YWNhYzQzZWYsIDB4NjI2MmM0YTYsXG4weDkxOTEzOWE4LCAweDk1OTUzMWE0LCAweGU0ZTRkMzM3LCAweDc5NzlmMjhiLFxuMHhlN2U3ZDUzMiwgMHhjOGM4OGI0MywgMHgzNzM3NmU1OSwgMHg2ZDZkZGFiNyxcbjB4OGQ4ZDAxOGMsIDB4ZDVkNWIxNjQsIDB4NGU0ZTljZDIsIDB4YTlhOTQ5ZTAsXG4weDZjNmNkOGI0LCAweDU2NTZhY2ZhLCAweGY0ZjRmMzA3LCAweGVhZWFjZjI1LFxuMHg2NTY1Y2FhZiwgMHg3YTdhZjQ4ZSwgMHhhZWFlNDdlOSwgMHgwODA4MTAxOCxcbjB4YmFiYTZmZDUsIDB4Nzg3OGYwODgsIDB4MjUyNTRhNmYsIDB4MmUyZTVjNzIsXG4weDFjMWMzODI0LCAweGE2YTY1N2YxLCAweGI0YjQ3M2M3LCAweGM2YzY5NzUxLFxuMHhlOGU4Y2IyMywgMHhkZGRkYTE3YywgMHg3NDc0ZTg5YywgMHgxZjFmM2UyMSxcbjB4NGI0Yjk2ZGQsIDB4YmRiZDYxZGMsIDB4OGI4YjBkODYsIDB4OGE4YTBmODUsXG4weDcwNzBlMDkwLCAweDNlM2U3YzQyLCAweGI1YjU3MWM0LCAweDY2NjZjY2FhLFxuMHg0ODQ4OTBkOCwgMHgwMzAzMDYwNSwgMHhmNmY2ZjcwMSwgMHgwZTBlMWMxMixcbjB4NjE2MWMyYTMsIDB4MzUzNTZhNWYsIDB4NTc1N2FlZjksIDB4YjliOTY5ZDAsXG4weDg2ODYxNzkxLCAweGMxYzE5OTU4LCAweDFkMWQzYTI3LCAweDllOWUyN2I5LFxuMHhlMWUxZDkzOCwgMHhmOGY4ZWIxMywgMHg5ODk4MmJiMywgMHgxMTExMjIzMyxcbjB4Njk2OWQyYmIsIDB4ZDlkOWE5NzAsIDB4OGU4ZTA3ODksIDB4OTQ5NDMzYTcsXG4weDliOWIyZGI2LCAweDFlMWUzYzIyLCAweDg3ODcxNTkyLCAweGU5ZTljOTIwLFxuMHhjZWNlODc0OSwgMHg1NTU1YWFmZiwgMHgyODI4NTA3OCwgMHhkZmRmYTU3YSxcbjB4OGM4YzAzOGYsIDB4YTFhMTU5ZjgsIDB4ODk4OTA5ODAsIDB4MGQwZDFhMTcsXG4weGJmYmY2NWRhLCAweGU2ZTZkNzMxLCAweDQyNDI4NGM2LCAweDY4NjhkMGI4LFxuMHg0MTQxODJjMywgMHg5OTk5MjliMCwgMHgyZDJkNWE3NywgMHgwZjBmMWUxMSxcbjB4YjBiMDdiY2IsIDB4NTQ1NGE4ZmMsIDB4YmJiYjZkZDYsIDB4MTYxNjJjM2EgXTtcblxudmFyIFQzID0gW1xuMHg2M2M2YTU2MywgMHg3Y2Y4ODQ3YywgMHg3N2VlOTk3NywgMHg3YmY2OGQ3YixcbjB4ZjJmZjBkZjIsIDB4NmJkNmJkNmIsIDB4NmZkZWIxNmYsIDB4YzU5MTU0YzUsXG4weDMwNjA1MDMwLCAweDAxMDIwMzAxLCAweDY3Y2VhOTY3LCAweDJiNTY3ZDJiLFxuMHhmZWU3MTlmZSwgMHhkN2I1NjJkNywgMHhhYjRkZTZhYiwgMHg3NmVjOWE3NixcbjB4Y2E4ZjQ1Y2EsIDB4ODIxZjlkODIsIDB4Yzk4OTQwYzksIDB4N2RmYTg3N2QsXG4weGZhZWYxNWZhLCAweDU5YjJlYjU5LCAweDQ3OGVjOTQ3LCAweGYwZmIwYmYwLFxuMHhhZDQxZWNhZCwgMHhkNGIzNjdkNCwgMHhhMjVmZmRhMiwgMHhhZjQ1ZWFhZixcbjB4OWMyM2JmOWMsIDB4YTQ1M2Y3YTQsIDB4NzJlNDk2NzIsIDB4YzA5YjViYzAsXG4weGI3NzVjMmI3LCAweGZkZTExY2ZkLCAweDkzM2RhZTkzLCAweDI2NGM2YTI2LFxuMHgzNjZjNWEzNiwgMHgzZjdlNDEzZiwgMHhmN2Y1MDJmNywgMHhjYzgzNGZjYyxcbjB4MzQ2ODVjMzQsIDB4YTU1MWY0YTUsIDB4ZTVkMTM0ZTUsIDB4ZjFmOTA4ZjEsXG4weDcxZTI5MzcxLCAweGQ4YWI3M2Q4LCAweDMxNjI1MzMxLCAweDE1MmEzZjE1LFxuMHgwNDA4MGMwNCwgMHhjNzk1NTJjNywgMHgyMzQ2NjUyMywgMHhjMzlkNWVjMyxcbjB4MTgzMDI4MTgsIDB4OTYzN2ExOTYsIDB4MDUwYTBmMDUsIDB4OWEyZmI1OWEsXG4weDA3MGUwOTA3LCAweDEyMjQzNjEyLCAweDgwMWI5YjgwLCAweGUyZGYzZGUyLFxuMHhlYmNkMjZlYiwgMHgyNzRlNjkyNywgMHhiMjdmY2RiMiwgMHg3NWVhOWY3NSxcbjB4MDkxMjFiMDksIDB4ODMxZDllODMsIDB4MmM1ODc0MmMsIDB4MWEzNDJlMWEsXG4weDFiMzYyZDFiLCAweDZlZGNiMjZlLCAweDVhYjRlZTVhLCAweGEwNWJmYmEwLFxuMHg1MmE0ZjY1MiwgMHgzYjc2NGQzYiwgMHhkNmI3NjFkNiwgMHhiMzdkY2ViMyxcbjB4Mjk1MjdiMjksIDB4ZTNkZDNlZTMsIDB4MmY1ZTcxMmYsIDB4ODQxMzk3ODQsXG4weDUzYTZmNTUzLCAweGQxYjk2OGQxLCAweDAwMDAwMDAwLCAweGVkYzEyY2VkLFxuMHgyMDQwNjAyMCwgMHhmY2UzMWZmYywgMHhiMTc5YzhiMSwgMHg1YmI2ZWQ1YixcbjB4NmFkNGJlNmEsIDB4Y2I4ZDQ2Y2IsIDB4YmU2N2Q5YmUsIDB4Mzk3MjRiMzksXG4weDRhOTRkZTRhLCAweDRjOThkNDRjLCAweDU4YjBlODU4LCAweGNmODU0YWNmLFxuMHhkMGJiNmJkMCwgMHhlZmM1MmFlZiwgMHhhYTRmZTVhYSwgMHhmYmVkMTZmYixcbjB4NDM4NmM1NDMsIDB4NGQ5YWQ3NGQsIDB4MzM2NjU1MzMsIDB4ODUxMTk0ODUsXG4weDQ1OGFjZjQ1LCAweGY5ZTkxMGY5LCAweDAyMDQwNjAyLCAweDdmZmU4MTdmLFxuMHg1MGEwZjA1MCwgMHgzYzc4NDQzYywgMHg5ZjI1YmE5ZiwgMHhhODRiZTNhOCxcbjB4NTFhMmYzNTEsIDB4YTM1ZGZlYTMsIDB4NDA4MGMwNDAsIDB4OGYwNThhOGYsXG4weDkyM2ZhZDkyLCAweDlkMjFiYzlkLCAweDM4NzA0ODM4LCAweGY1ZjEwNGY1LFxuMHhiYzYzZGZiYywgMHhiNjc3YzFiNiwgMHhkYWFmNzVkYSwgMHgyMTQyNjMyMSxcbjB4MTAyMDMwMTAsIDB4ZmZlNTFhZmYsIDB4ZjNmZDBlZjMsIDB4ZDJiZjZkZDIsXG4weGNkODE0Y2NkLCAweDBjMTgxNDBjLCAweDEzMjYzNTEzLCAweGVjYzMyZmVjLFxuMHg1ZmJlZTE1ZiwgMHg5NzM1YTI5NywgMHg0NDg4Y2M0NCwgMHgxNzJlMzkxNyxcbjB4YzQ5MzU3YzQsIDB4YTc1NWYyYTcsIDB4N2VmYzgyN2UsIDB4M2Q3YTQ3M2QsXG4weDY0YzhhYzY0LCAweDVkYmFlNzVkLCAweDE5MzIyYjE5LCAweDczZTY5NTczLFxuMHg2MGMwYTA2MCwgMHg4MTE5OTg4MSwgMHg0ZjllZDE0ZiwgMHhkY2EzN2ZkYyxcbjB4MjI0NDY2MjIsIDB4MmE1NDdlMmEsIDB4OTAzYmFiOTAsIDB4ODgwYjgzODgsXG4weDQ2OGNjYTQ2LCAweGVlYzcyOWVlLCAweGI4NmJkM2I4LCAweDE0MjgzYzE0LFxuMHhkZWE3NzlkZSwgMHg1ZWJjZTI1ZSwgMHgwYjE2MWQwYiwgMHhkYmFkNzZkYixcbjB4ZTBkYjNiZTAsIDB4MzI2NDU2MzIsIDB4M2E3NDRlM2EsIDB4MGExNDFlMGEsXG4weDQ5OTJkYjQ5LCAweDA2MGMwYTA2LCAweDI0NDg2YzI0LCAweDVjYjhlNDVjLFxuMHhjMjlmNWRjMiwgMHhkM2JkNmVkMywgMHhhYzQzZWZhYywgMHg2MmM0YTY2MixcbjB4OTEzOWE4OTEsIDB4OTUzMWE0OTUsIDB4ZTRkMzM3ZTQsIDB4NzlmMjhiNzksXG4weGU3ZDUzMmU3LCAweGM4OGI0M2M4LCAweDM3NmU1OTM3LCAweDZkZGFiNzZkLFxuMHg4ZDAxOGM4ZCwgMHhkNWIxNjRkNSwgMHg0ZTljZDI0ZSwgMHhhOTQ5ZTBhOSxcbjB4NmNkOGI0NmMsIDB4NTZhY2ZhNTYsIDB4ZjRmMzA3ZjQsIDB4ZWFjZjI1ZWEsXG4weDY1Y2FhZjY1LCAweDdhZjQ4ZTdhLCAweGFlNDdlOWFlLCAweDA4MTAxODA4LFxuMHhiYTZmZDViYSwgMHg3OGYwODg3OCwgMHgyNTRhNmYyNSwgMHgyZTVjNzIyZSxcbjB4MWMzODI0MWMsIDB4YTY1N2YxYTYsIDB4YjQ3M2M3YjQsIDB4YzY5NzUxYzYsXG4weGU4Y2IyM2U4LCAweGRkYTE3Y2RkLCAweDc0ZTg5Yzc0LCAweDFmM2UyMTFmLFxuMHg0Yjk2ZGQ0YiwgMHhiZDYxZGNiZCwgMHg4YjBkODY4YiwgMHg4YTBmODU4YSxcbjB4NzBlMDkwNzAsIDB4M2U3YzQyM2UsIDB4YjU3MWM0YjUsIDB4NjZjY2FhNjYsXG4weDQ4OTBkODQ4LCAweDAzMDYwNTAzLCAweGY2ZjcwMWY2LCAweDBlMWMxMjBlLFxuMHg2MWMyYTM2MSwgMHgzNTZhNWYzNSwgMHg1N2FlZjk1NywgMHhiOTY5ZDBiOSxcbjB4ODYxNzkxODYsIDB4YzE5OTU4YzEsIDB4MWQzYTI3MWQsIDB4OWUyN2I5OWUsXG4weGUxZDkzOGUxLCAweGY4ZWIxM2Y4LCAweDk4MmJiMzk4LCAweDExMjIzMzExLFxuMHg2OWQyYmI2OSwgMHhkOWE5NzBkOSwgMHg4ZTA3ODk4ZSwgMHg5NDMzYTc5NCxcbjB4OWIyZGI2OWIsIDB4MWUzYzIyMWUsIDB4ODcxNTkyODcsIDB4ZTljOTIwZTksXG4weGNlODc0OWNlLCAweDU1YWFmZjU1LCAweDI4NTA3ODI4LCAweGRmYTU3YWRmLFxuMHg4YzAzOGY4YywgMHhhMTU5ZjhhMSwgMHg4OTA5ODA4OSwgMHgwZDFhMTcwZCxcbjB4YmY2NWRhYmYsIDB4ZTZkNzMxZTYsIDB4NDI4NGM2NDIsIDB4NjhkMGI4NjgsXG4weDQxODJjMzQxLCAweDk5MjliMDk5LCAweDJkNWE3NzJkLCAweDBmMWUxMTBmLFxuMHhiMDdiY2JiMCwgMHg1NGE4ZmM1NCwgMHhiYjZkZDZiYiwgMHgxNjJjM2ExNiBdO1xuXG52YXIgVDQgPSBbXG4weGM2YTU2MzYzLCAweGY4ODQ3YzdjLCAweGVlOTk3Nzc3LCAweGY2OGQ3YjdiLFxuMHhmZjBkZjJmMiwgMHhkNmJkNmI2YiwgMHhkZWIxNmY2ZiwgMHg5MTU0YzVjNSxcbjB4NjA1MDMwMzAsIDB4MDIwMzAxMDEsIDB4Y2VhOTY3NjcsIDB4NTY3ZDJiMmIsXG4weGU3MTlmZWZlLCAweGI1NjJkN2Q3LCAweDRkZTZhYmFiLCAweGVjOWE3Njc2LFxuMHg4ZjQ1Y2FjYSwgMHgxZjlkODI4MiwgMHg4OTQwYzljOSwgMHhmYTg3N2Q3ZCxcbjB4ZWYxNWZhZmEsIDB4YjJlYjU5NTksIDB4OGVjOTQ3NDcsIDB4ZmIwYmYwZjAsXG4weDQxZWNhZGFkLCAweGIzNjdkNGQ0LCAweDVmZmRhMmEyLCAweDQ1ZWFhZmFmLFxuMHgyM2JmOWM5YywgMHg1M2Y3YTRhNCwgMHhlNDk2NzI3MiwgMHg5YjViYzBjMCxcbjB4NzVjMmI3YjcsIDB4ZTExY2ZkZmQsIDB4M2RhZTkzOTMsIDB4NGM2YTI2MjYsXG4weDZjNWEzNjM2LCAweDdlNDEzZjNmLCAweGY1MDJmN2Y3LCAweDgzNGZjY2NjLFxuMHg2ODVjMzQzNCwgMHg1MWY0YTVhNSwgMHhkMTM0ZTVlNSwgMHhmOTA4ZjFmMSxcbjB4ZTI5MzcxNzEsIDB4YWI3M2Q4ZDgsIDB4NjI1MzMxMzEsIDB4MmEzZjE1MTUsXG4weDA4MGMwNDA0LCAweDk1NTJjN2M3LCAweDQ2NjUyMzIzLCAweDlkNWVjM2MzLFxuMHgzMDI4MTgxOCwgMHgzN2ExOTY5NiwgMHgwYTBmMDUwNSwgMHgyZmI1OWE5YSxcbjB4MGUwOTA3MDcsIDB4MjQzNjEyMTIsIDB4MWI5YjgwODAsIDB4ZGYzZGUyZTIsXG4weGNkMjZlYmViLCAweDRlNjkyNzI3LCAweDdmY2RiMmIyLCAweGVhOWY3NTc1LFxuMHgxMjFiMDkwOSwgMHgxZDllODM4MywgMHg1ODc0MmMyYywgMHgzNDJlMWExYSxcbjB4MzYyZDFiMWIsIDB4ZGNiMjZlNmUsIDB4YjRlZTVhNWEsIDB4NWJmYmEwYTAsXG4weGE0ZjY1MjUyLCAweDc2NGQzYjNiLCAweGI3NjFkNmQ2LCAweDdkY2ViM2IzLFxuMHg1MjdiMjkyOSwgMHhkZDNlZTNlMywgMHg1ZTcxMmYyZiwgMHgxMzk3ODQ4NCxcbjB4YTZmNTUzNTMsIDB4Yjk2OGQxZDEsIDB4MDAwMDAwMDAsIDB4YzEyY2VkZWQsXG4weDQwNjAyMDIwLCAweGUzMWZmY2ZjLCAweDc5YzhiMWIxLCAweGI2ZWQ1YjViLFxuMHhkNGJlNmE2YSwgMHg4ZDQ2Y2JjYiwgMHg2N2Q5YmViZSwgMHg3MjRiMzkzOSxcbjB4OTRkZTRhNGEsIDB4OThkNDRjNGMsIDB4YjBlODU4NTgsIDB4ODU0YWNmY2YsXG4weGJiNmJkMGQwLCAweGM1MmFlZmVmLCAweDRmZTVhYWFhLCAweGVkMTZmYmZiLFxuMHg4NmM1NDM0MywgMHg5YWQ3NGQ0ZCwgMHg2NjU1MzMzMywgMHgxMTk0ODU4NSxcbjB4OGFjZjQ1NDUsIDB4ZTkxMGY5ZjksIDB4MDQwNjAyMDIsIDB4ZmU4MTdmN2YsXG4weGEwZjA1MDUwLCAweDc4NDQzYzNjLCAweDI1YmE5ZjlmLCAweDRiZTNhOGE4LFxuMHhhMmYzNTE1MSwgMHg1ZGZlYTNhMywgMHg4MGMwNDA0MCwgMHgwNThhOGY4ZixcbjB4M2ZhZDkyOTIsIDB4MjFiYzlkOWQsIDB4NzA0ODM4MzgsIDB4ZjEwNGY1ZjUsXG4weDYzZGZiY2JjLCAweDc3YzFiNmI2LCAweGFmNzVkYWRhLCAweDQyNjMyMTIxLFxuMHgyMDMwMTAxMCwgMHhlNTFhZmZmZiwgMHhmZDBlZjNmMywgMHhiZjZkZDJkMixcbjB4ODE0Y2NkY2QsIDB4MTgxNDBjMGMsIDB4MjYzNTEzMTMsIDB4YzMyZmVjZWMsXG4weGJlZTE1ZjVmLCAweDM1YTI5Nzk3LCAweDg4Y2M0NDQ0LCAweDJlMzkxNzE3LFxuMHg5MzU3YzRjNCwgMHg1NWYyYTdhNywgMHhmYzgyN2U3ZSwgMHg3YTQ3M2QzZCxcbjB4YzhhYzY0NjQsIDB4YmFlNzVkNWQsIDB4MzIyYjE5MTksIDB4ZTY5NTczNzMsXG4weGMwYTA2MDYwLCAweDE5OTg4MTgxLCAweDllZDE0ZjRmLCAweGEzN2ZkY2RjLFxuMHg0NDY2MjIyMiwgMHg1NDdlMmEyYSwgMHgzYmFiOTA5MCwgMHgwYjgzODg4OCxcbjB4OGNjYTQ2NDYsIDB4YzcyOWVlZWUsIDB4NmJkM2I4YjgsIDB4MjgzYzE0MTQsXG4weGE3NzlkZWRlLCAweGJjZTI1ZTVlLCAweDE2MWQwYjBiLCAweGFkNzZkYmRiLFxuMHhkYjNiZTBlMCwgMHg2NDU2MzIzMiwgMHg3NDRlM2EzYSwgMHgxNDFlMGEwYSxcbjB4OTJkYjQ5NDksIDB4MGMwYTA2MDYsIDB4NDg2YzI0MjQsIDB4YjhlNDVjNWMsXG4weDlmNWRjMmMyLCAweGJkNmVkM2QzLCAweDQzZWZhY2FjLCAweGM0YTY2MjYyLFxuMHgzOWE4OTE5MSwgMHgzMWE0OTU5NSwgMHhkMzM3ZTRlNCwgMHhmMjhiNzk3OSxcbjB4ZDUzMmU3ZTcsIDB4OGI0M2M4YzgsIDB4NmU1OTM3MzcsIDB4ZGFiNzZkNmQsXG4weDAxOGM4ZDhkLCAweGIxNjRkNWQ1LCAweDljZDI0ZTRlLCAweDQ5ZTBhOWE5LFxuMHhkOGI0NmM2YywgMHhhY2ZhNTY1NiwgMHhmMzA3ZjRmNCwgMHhjZjI1ZWFlYSxcbjB4Y2FhZjY1NjUsIDB4ZjQ4ZTdhN2EsIDB4NDdlOWFlYWUsIDB4MTAxODA4MDgsXG4weDZmZDViYWJhLCAweGYwODg3ODc4LCAweDRhNmYyNTI1LCAweDVjNzIyZTJlLFxuMHgzODI0MWMxYywgMHg1N2YxYTZhNiwgMHg3M2M3YjRiNCwgMHg5NzUxYzZjNixcbjB4Y2IyM2U4ZTgsIDB4YTE3Y2RkZGQsIDB4ZTg5Yzc0NzQsIDB4M2UyMTFmMWYsXG4weDk2ZGQ0YjRiLCAweDYxZGNiZGJkLCAweDBkODY4YjhiLCAweDBmODU4YThhLFxuMHhlMDkwNzA3MCwgMHg3YzQyM2UzZSwgMHg3MWM0YjViNSwgMHhjY2FhNjY2NixcbjB4OTBkODQ4NDgsIDB4MDYwNTAzMDMsIDB4ZjcwMWY2ZjYsIDB4MWMxMjBlMGUsXG4weGMyYTM2MTYxLCAweDZhNWYzNTM1LCAweGFlZjk1NzU3LCAweDY5ZDBiOWI5LFxuMHgxNzkxODY4NiwgMHg5OTU4YzFjMSwgMHgzYTI3MWQxZCwgMHgyN2I5OWU5ZSxcbjB4ZDkzOGUxZTEsIDB4ZWIxM2Y4ZjgsIDB4MmJiMzk4OTgsIDB4MjIzMzExMTEsXG4weGQyYmI2OTY5LCAweGE5NzBkOWQ5LCAweDA3ODk4ZThlLCAweDMzYTc5NDk0LFxuMHgyZGI2OWI5YiwgMHgzYzIyMWUxZSwgMHgxNTkyODc4NywgMHhjOTIwZTllOSxcbjB4ODc0OWNlY2UsIDB4YWFmZjU1NTUsIDB4NTA3ODI4MjgsIDB4YTU3YWRmZGYsXG4weDAzOGY4YzhjLCAweDU5ZjhhMWExLCAweDA5ODA4OTg5LCAweDFhMTcwZDBkLFxuMHg2NWRhYmZiZiwgMHhkNzMxZTZlNiwgMHg4NGM2NDI0MiwgMHhkMGI4Njg2OCxcbjB4ODJjMzQxNDEsIDB4MjliMDk5OTksIDB4NWE3NzJkMmQsIDB4MWUxMTBmMGYsXG4weDdiY2JiMGIwLCAweGE4ZmM1NDU0LCAweDZkZDZiYmJiLCAweDJjM2ExNjE2IF07XG5cbmZ1bmN0aW9uIEIwKHgpIHsgcmV0dXJuICh4JjI1NSk7IH1cbmZ1bmN0aW9uIEIxKHgpIHsgcmV0dXJuICgoeD4+OCkmMjU1KTsgfVxuZnVuY3Rpb24gQjIoeCkgeyByZXR1cm4gKCh4Pj4xNikmMjU1KTsgfVxuZnVuY3Rpb24gQjMoeCkgeyByZXR1cm4gKCh4Pj4yNCkmMjU1KTsgfVxuXG5mdW5jdGlvbiBGMSh4MCwgeDEsIHgyLCB4MylcbntcbiAgcmV0dXJuIEIxKFQxW3gwJjI1NV0pIHwgKEIxKFQxWyh4MT4+OCkmMjU1XSk8PDgpXG4gICAgICB8IChCMShUMVsoeDI+PjE2KSYyNTVdKTw8MTYpIHwgKEIxKFQxW3gzPj4+MjRdKTw8MjQpO1xufVxuXG5mdW5jdGlvbiBwYWNrQnl0ZXMob2N0ZXRzKVxue1xuICB2YXIgaSwgajtcbiAgdmFyIGxlbj1vY3RldHMubGVuZ3RoO1xuICB2YXIgYj1uZXcgQXJyYXkobGVuLzQpO1xuXG4gIGlmICghb2N0ZXRzIHx8IGxlbiAlIDQpIHJldHVybjtcblxuICBmb3IgKGk9MCwgaj0wOyBqPGxlbjsgais9IDQpXG4gICAgIGJbaSsrXSA9IG9jdGV0c1tqXSB8IChvY3RldHNbaisxXTw8OCkgfCAob2N0ZXRzW2orMl08PDE2KSB8IChvY3RldHNbaiszXTw8MjQpO1xuXG4gIHJldHVybiBiOyAgXG59XG5cbmZ1bmN0aW9uIHVucGFja0J5dGVzKHBhY2tlZClcbntcbiAgdmFyIGo7XG4gIHZhciBpPTAsIGwgPSBwYWNrZWQubGVuZ3RoO1xuICB2YXIgciA9IG5ldyBBcnJheShsKjQpO1xuXG4gIGZvciAoaj0wOyBqPGw7IGorKylcbiAge1xuICAgIHJbaSsrXSA9IEIwKHBhY2tlZFtqXSk7XG4gICAgcltpKytdID0gQjEocGFja2VkW2pdKTtcbiAgICByW2krK10gPSBCMihwYWNrZWRbal0pO1xuICAgIHJbaSsrXSA9IEIzKHBhY2tlZFtqXSk7XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG52YXIgbWF4a2M9ODtcbnZhciBtYXhyaz0xNDtcblxuZnVuY3Rpb24ga2V5RXhwYW5zaW9uKGtleSlcbntcbiAgdmFyIGtjLCBpLCBqLCByLCB0O1xuICB2YXIgcm91bmRzO1xuICB2YXIga2V5U2NoZWQ9bmV3IEFycmF5KG1heHJrKzEpO1xuICB2YXIga2V5bGVuPWtleS5sZW5ndGg7XG4gIHZhciBrPW5ldyBBcnJheShtYXhrYyk7XG4gIHZhciB0az1uZXcgQXJyYXkobWF4a2MpO1xuICB2YXIgcmNvbnBvaW50ZXI9MDtcblxuICBpZihrZXlsZW49PTE2KVxuICB7XG4gICByb3VuZHM9MTA7XG4gICBrYz00O1xuICB9XG4gIGVsc2UgaWYoa2V5bGVuPT0yNClcbiAge1xuICAgcm91bmRzPTEyO1xuICAga2M9NjtcbiAgfVxuICBlbHNlIGlmKGtleWxlbj09MzIpXG4gIHtcbiAgIHJvdW5kcz0xNDtcbiAgIGtjPTg7XG4gIH1cbiAgZWxzZVxuICB7XG5cdHV0aWwucHJpbnRfZXJyb3IoJ2Flcy5qczogSW52YWxpZCBrZXktbGVuZ3RoIGZvciBBRVMga2V5Oicra2V5bGVuKTtcbiAgIHJldHVybjtcbiAgfVxuXG4gIGZvcihpPTA7IGk8bWF4cmsrMTsgaSsrKSBrZXlTY2hlZFtpXT1uZXcgQXJyYXkoNCk7XG5cbiAgZm9yKGk9MCxqPTA7IGo8a2V5bGVuOyBqKyssaSs9NClcbiAgICBrW2pdID0ga2V5LmNoYXJDb2RlQXQoaSkgfCAoa2V5LmNoYXJDb2RlQXQoaSsxKTw8OClcbiAgICAgICAgICAgICAgICAgICAgIHwgKGtleS5jaGFyQ29kZUF0KGkrMik8PDE2KSB8IChrZXkuY2hhckNvZGVBdChpKzMpPDwyNCk7XG5cbiAgZm9yKGo9a2MtMTsgaj49MDsgai0tKSB0a1tqXSA9IGtbal07XG5cbiAgcj0wO1xuICB0PTA7XG4gIGZvcihqPTA7IChqPGtjKSYmKHI8cm91bmRzKzEpOyApXG4gIHtcbiAgICBmb3IoOyAoajxrYykmJih0PDQpOyBqKyssdCsrKVxuICAgIHtcbiAgICAgIGtleVNjaGVkW3JdW3RdPXRrW2pdO1xuICAgIH1cbiAgICBpZih0PT00KVxuICAgIHtcbiAgICAgIHIrKztcbiAgICAgIHQ9MDtcbiAgICB9XG4gIH1cblxuICB3aGlsZShyPHJvdW5kcysxKVxuICB7XG4gICAgdmFyIHRlbXAgPSB0a1trYy0xXTtcblxuICAgIHRrWzBdIF49IFNbQjEodGVtcCldIHwgKFNbQjIodGVtcCldPDw4KSB8IChTW0IzKHRlbXApXTw8MTYpIHwgKFNbQjAodGVtcCldPDwyNCk7XG4gICAgdGtbMF0gXj0gUmNvbltyY29ucG9pbnRlcisrXTtcblxuICAgIGlmKGtjICE9IDgpXG4gICAge1xuICAgICAgZm9yKGo9MTsgajxrYzsgaisrKSB0a1tqXSBePSB0a1tqLTFdO1xuICAgIH1cbiAgICBlbHNlXG4gICAge1xuICAgICAgZm9yKGo9MTsgajxrYy8yOyBqKyspIHRrW2pdIF49IHRrW2otMV07XG4gXG4gICAgICB0ZW1wID0gdGtba2MvMi0xXTtcbiAgICAgIHRrW2tjLzJdIF49IFNbQjAodGVtcCldIHwgKFNbQjEodGVtcCldPDw4KSB8IChTW0IyKHRlbXApXTw8MTYpIHwgKFNbQjModGVtcCldPDwyNCk7XG5cbiAgICAgIGZvcihqPWtjLzIrMTsgajxrYzsgaisrKSB0a1tqXSBePSB0a1tqLTFdO1xuICAgIH1cblxuICAgIGZvcihqPTA7IChqPGtjKSYmKHI8cm91bmRzKzEpOyApXG4gICAge1xuICAgICAgZm9yKDsgKGo8a2MpJiYodDw0KTsgaisrLHQrKylcbiAgICAgIHtcbiAgICAgICAga2V5U2NoZWRbcl1bdF09dGtbal07XG4gICAgICB9XG4gICAgICBpZih0PT00KVxuICAgICAge1xuICAgICAgICByKys7XG4gICAgICAgIHQ9MDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdGhpcy5yb3VuZHMgPSByb3VuZHM7XG4gIHRoaXMucmsgPSBrZXlTY2hlZDtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIEFFU2VuY3J5cHQoYmxvY2ssIGN0eClcbntcbiAgdmFyIHI7XG4gIHZhciB0MCx0MSx0Mix0MztcblxuICB2YXIgYiA9IHBhY2tCeXRlcyhibG9jayk7XG4gIHZhciByb3VuZHMgPSBjdHgucm91bmRzO1xuICB2YXIgYjAgPSBiWzBdO1xuICB2YXIgYjEgPSBiWzFdO1xuICB2YXIgYjIgPSBiWzJdO1xuICB2YXIgYjMgPSBiWzNdO1xuXG4gIGZvcihyPTA7IHI8cm91bmRzLTE7IHIrKylcbiAge1xuICAgIHQwID0gYjAgXiBjdHgucmtbcl1bMF07XG4gICAgdDEgPSBiMSBeIGN0eC5ya1tyXVsxXTtcbiAgICB0MiA9IGIyIF4gY3R4LnJrW3JdWzJdO1xuICAgIHQzID0gYjMgXiBjdHgucmtbcl1bM107XG5cbiAgICBiMCA9IFQxW3QwJjI1NV0gXiBUMlsodDE+PjgpJjI1NV0gXiBUM1sodDI+PjE2KSYyNTVdIF4gVDRbdDM+Pj4yNF07XG4gICAgYjEgPSBUMVt0MSYyNTVdIF4gVDJbKHQyPj44KSYyNTVdIF4gVDNbKHQzPj4xNikmMjU1XSBeIFQ0W3QwPj4+MjRdO1xuICAgIGIyID0gVDFbdDImMjU1XSBeIFQyWyh0Mz4+OCkmMjU1XSBeIFQzWyh0MD4+MTYpJjI1NV0gXiBUNFt0MT4+PjI0XTtcbiAgICBiMyA9IFQxW3QzJjI1NV0gXiBUMlsodDA+PjgpJjI1NV0gXiBUM1sodDE+PjE2KSYyNTVdIF4gVDRbdDI+Pj4yNF07XG4gIH1cblxuICAvLyBsYXN0IHJvdW5kIGlzIHNwZWNpYWxcbiAgciA9IHJvdW5kcy0xO1xuXG4gIHQwID0gYjAgXiBjdHgucmtbcl1bMF07XG4gIHQxID0gYjEgXiBjdHgucmtbcl1bMV07XG4gIHQyID0gYjIgXiBjdHgucmtbcl1bMl07XG4gIHQzID0gYjMgXiBjdHgucmtbcl1bM107XG5cbiAgYlswXSA9IEYxKHQwLCB0MSwgdDIsIHQzKSBeIGN0eC5ya1tyb3VuZHNdWzBdO1xuICBiWzFdID0gRjEodDEsIHQyLCB0MywgdDApIF4gY3R4LnJrW3JvdW5kc11bMV07XG4gIGJbMl0gPSBGMSh0MiwgdDMsIHQwLCB0MSkgXiBjdHgucmtbcm91bmRzXVsyXTtcbiAgYlszXSA9IEYxKHQzLCB0MCwgdDEsIHQyKSBeIGN0eC5ya1tyb3VuZHNdWzNdO1xuXG4gIHJldHVybiB1bnBhY2tCeXRlcyhiKTtcbn1cblxuZnVuY3Rpb24gbWFrZUNsYXNzKGxlbmd0aCkge1xuXG5cdHZhciBjID0gZnVuY3Rpb24oa2V5KSB7XG5cdFx0dGhpcy5rZXkgPSBrZXlFeHBhbnNpb24oa2V5KTtcblxuXHRcdHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG5cdFx0XHRyZXR1cm4gQUVTZW5jcnlwdChibG9jaywgdGhpcy5rZXkpO1xuXHRcdH1cblx0fVxuXG5cdGMuYmxvY2tTaXplID0gYy5wcm90b3R5cGUuYmxvY2tTaXplID0gMTY7XG5cdGMua2V5U2l6ZSA9IGMucHJvdG90eXBlLmtleVNpemUgPSBsZW5ndGggLyA4O1xuXG5cdHJldHVybiBjO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHt9XG5cbnZhciB0eXBlcyA9IFsxMjgsIDE5MiwgMjU2XTtcblxuZm9yKHZhciBpIGluIHR5cGVzICkge1xuXHRtb2R1bGUuZXhwb3J0c1t0eXBlc1tpXV0gPSBtYWtlQ2xhc3ModHlwZXNbaV0pO1xufVxuIiwiLyogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIIFxuICogXG4gKiBPcmlnaW5hbGx5IHdyaXR0ZW4gYnkgbmtsZWluIHNvZnR3YXJlIChua2xlaW4uY29tKVxuICovXG5cbi8qIFxuICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBiYXNlZCBvbiBCcnVjZSBTY2huZWllcidzIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbi5cbiAqXG4gKlxuICogVGhlIGNvbnN0cnVjdG9yIGRvZXNuJ3QgZG8gbXVjaCBvZiBhbnl0aGluZy4gIEl0J3MganVzdCBoZXJlXG4gKiBzbyB3ZSBjYW4gc3RhcnQgZGVmaW5pbmcgcHJvcGVydGllcyBhbmQgbWV0aG9kcyBhbmQgc3VjaC5cbiAqL1xuZnVuY3Rpb24gQmxvd2Zpc2goKSB7XG59O1xuXG4vKlxuICogRGVjbGFyZSB0aGUgYmxvY2sgc2l6ZSBzbyB0aGF0IHByb3RvY29scyBrbm93IHdoYXQgc2l6ZVxuICogSW5pdGlhbGl6YXRpb24gVmVjdG9yIChJVikgdGhleSB3aWxsIG5lZWQuXG4gKi9cbkJsb3dmaXNoLnByb3RvdHlwZS5CTE9DS1NJWkUgPSA4O1xuXG4vKlxuICogVGhlc2UgYXJlIHRoZSBkZWZhdWx0IFNCT1hFUy5cbiAqL1xuQmxvd2Zpc2gucHJvdG90eXBlLlNCT1hFUyA9IFtcbiAgICBbXG5cdDB4ZDEzMTBiYTYsIDB4OThkZmI1YWMsIDB4MmZmZDcyZGIsIDB4ZDAxYWRmYjcsIDB4YjhlMWFmZWQsIDB4NmEyNjdlOTYsXG5cdDB4YmE3YzkwNDUsIDB4ZjEyYzdmOTksIDB4MjRhMTk5NDcsIDB4YjM5MTZjZjcsIDB4MDgwMWYyZTIsIDB4ODU4ZWZjMTYsXG5cdDB4NjM2OTIwZDgsIDB4NzE1NzRlNjksIDB4YTQ1OGZlYTMsIDB4ZjQ5MzNkN2UsIDB4MGQ5NTc0OGYsIDB4NzI4ZWI2NTgsXG5cdDB4NzE4YmNkNTgsIDB4ODIxNTRhZWUsIDB4N2I1NGE0MWQsIDB4YzI1YTU5YjUsIDB4OWMzMGQ1MzksIDB4MmFmMjYwMTMsXG5cdDB4YzVkMWIwMjMsIDB4Mjg2MDg1ZjAsIDB4Y2E0MTc5MTgsIDB4YjhkYjM4ZWYsIDB4OGU3OWRjYjAsIDB4NjAzYTE4MGUsXG5cdDB4NmM5ZTBlOGIsIDB4YjAxZThhM2UsIDB4ZDcxNTc3YzEsIDB4YmQzMTRiMjcsIDB4NzhhZjJmZGEsIDB4NTU2MDVjNjAsXG5cdDB4ZTY1NTI1ZjMsIDB4YWE1NWFiOTQsIDB4NTc0ODk4NjIsIDB4NjNlODE0NDAsIDB4NTVjYTM5NmEsIDB4MmFhYjEwYjYsXG5cdDB4YjRjYzVjMzQsIDB4MTE0MWU4Y2UsIDB4YTE1NDg2YWYsIDB4N2M3MmU5OTMsIDB4YjNlZTE0MTEsIDB4NjM2ZmJjMmEsXG5cdDB4MmJhOWM1NWQsIDB4NzQxODMxZjYsIDB4Y2U1YzNlMTYsIDB4OWI4NzkzMWUsIDB4YWZkNmJhMzMsIDB4NmMyNGNmNWMsXG5cdDB4N2EzMjUzODEsIDB4Mjg5NTg2NzcsIDB4M2I4ZjQ4OTgsIDB4NmI0YmI5YWYsIDB4YzRiZmU4MWIsIDB4NjYyODIxOTMsXG5cdDB4NjFkODA5Y2MsIDB4ZmIyMWE5OTEsIDB4NDg3Y2FjNjAsIDB4NWRlYzgwMzIsIDB4ZWY4NDVkNWQsIDB4ZTk4NTc1YjEsXG5cdDB4ZGMyNjIzMDIsIDB4ZWI2NTFiODgsIDB4MjM4OTNlODEsIDB4ZDM5NmFjYzUsIDB4MGY2ZDZmZjMsIDB4ODNmNDQyMzksXG5cdDB4MmUwYjQ0ODIsIDB4YTQ4NDIwMDQsIDB4NjljOGYwNGEsIDB4OWUxZjliNWUsIDB4MjFjNjY4NDIsIDB4ZjZlOTZjOWEsXG5cdDB4NjcwYzljNjEsIDB4YWJkMzg4ZjAsIDB4NmE1MWEwZDIsIDB4ZDg1NDJmNjgsIDB4OTYwZmE3MjgsIDB4YWI1MTMzYTMsXG5cdDB4NmVlZjBiNmMsIDB4MTM3YTNiZTQsIDB4YmEzYmYwNTAsIDB4N2VmYjJhOTgsIDB4YTFmMTY1MWQsIDB4MzlhZjAxNzYsXG5cdDB4NjZjYTU5M2UsIDB4ODI0MzBlODgsIDB4OGNlZTg2MTksIDB4NDU2ZjlmYjQsIDB4N2Q4NGE1YzMsIDB4M2I4YjVlYmUsXG5cdDB4ZTA2Zjc1ZDgsIDB4ODVjMTIwNzMsIDB4NDAxYTQ0OWYsIDB4NTZjMTZhYTYsIDB4NGVkM2FhNjIsIDB4MzYzZjc3MDYsXG5cdDB4MWJmZWRmNzIsIDB4NDI5YjAyM2QsIDB4MzdkMGQ3MjQsIDB4ZDAwYTEyNDgsIDB4ZGIwZmVhZDMsIDB4NDlmMWMwOWIsXG5cdDB4MDc1MzcyYzksIDB4ODA5OTFiN2IsIDB4MjVkNDc5ZDgsIDB4ZjZlOGRlZjcsIDB4ZTNmZTUwMWEsIDB4YjY3OTRjM2IsXG5cdDB4OTc2Y2UwYmQsIDB4MDRjMDA2YmEsIDB4YzFhOTRmYjYsIDB4NDA5ZjYwYzQsIDB4NWU1YzllYzIsIDB4MTk2YTI0NjMsXG5cdDB4NjhmYjZmYWYsIDB4M2U2YzUzYjUsIDB4MTMzOWIyZWIsIDB4M2I1MmVjNmYsIDB4NmRmYzUxMWYsIDB4OWIzMDk1MmMsXG5cdDB4Y2M4MTQ1NDQsIDB4YWY1ZWJkMDksIDB4YmVlM2QwMDQsIDB4ZGUzMzRhZmQsIDB4NjYwZjI4MDcsIDB4MTkyZTRiYjMsXG5cdDB4YzBjYmE4NTcsIDB4NDVjODc0MGYsIDB4ZDIwYjVmMzksIDB4YjlkM2ZiZGIsIDB4NTU3OWMwYmQsIDB4MWE2MDMyMGEsXG5cdDB4ZDZhMTAwYzYsIDB4NDAyYzcyNzksIDB4Njc5ZjI1ZmUsIDB4ZmIxZmEzY2MsIDB4OGVhNWU5ZjgsIDB4ZGIzMjIyZjgsXG5cdDB4M2M3NTE2ZGYsIDB4ZmQ2MTZiMTUsIDB4MmY1MDFlYzgsIDB4YWQwNTUyYWIsIDB4MzIzZGI1ZmEsIDB4ZmQyMzg3NjAsXG5cdDB4NTMzMTdiNDgsIDB4M2UwMGRmODIsIDB4OWU1YzU3YmIsIDB4Y2E2ZjhjYTAsIDB4MWE4NzU2MmUsIDB4ZGYxNzY5ZGIsXG5cdDB4ZDU0MmE4ZjYsIDB4Mjg3ZWZmYzMsIDB4YWM2NzMyYzYsIDB4OGM0ZjU1NzMsIDB4Njk1YjI3YjAsIDB4YmJjYTU4YzgsXG5cdDB4ZTFmZmEzNWQsIDB4YjhmMDExYTAsIDB4MTBmYTNkOTgsIDB4ZmQyMTgzYjgsIDB4NGFmY2I1NmMsIDB4MmRkMWQzNWIsXG5cdDB4OWE1M2U0NzksIDB4YjZmODQ1NjUsIDB4ZDI4ZTQ5YmMsIDB4NGJmYjk3OTAsIDB4ZTFkZGYyZGEsIDB4YTRjYjdlMzMsXG5cdDB4NjJmYjEzNDEsIDB4Y2VlNGM2ZTgsIDB4ZWYyMGNhZGEsIDB4MzY3NzRjMDEsIDB4ZDA3ZTllZmUsIDB4MmJmMTFmYjQsXG5cdDB4OTVkYmRhNGQsIDB4YWU5MDkxOTgsIDB4ZWFhZDhlNzEsIDB4NmI5M2Q1YTAsIDB4ZDA4ZWQxZDAsIDB4YWZjNzI1ZTAsXG5cdDB4OGUzYzViMmYsIDB4OGU3NTk0YjcsIDB4OGZmNmUyZmIsIDB4ZjIxMjJiNjQsIDB4ODg4OGI4MTIsIDB4OTAwZGYwMWMsXG5cdDB4NGZhZDVlYTAsIDB4Njg4ZmMzMWMsIDB4ZDFjZmYxOTEsIDB4YjNhOGMxYWQsIDB4MmYyZjIyMTgsIDB4YmUwZTE3NzcsXG5cdDB4ZWE3NTJkZmUsIDB4OGIwMjFmYTEsIDB4ZTVhMGNjMGYsIDB4YjU2Zjc0ZTgsIDB4MThhY2YzZDYsIDB4Y2U4OWUyOTksXG5cdDB4YjRhODRmZTAsIDB4ZmQxM2UwYjcsIDB4N2NjNDNiODEsIDB4ZDJhZGE4ZDksIDB4MTY1ZmEyNjYsIDB4ODA5NTc3MDUsXG5cdDB4OTNjYzczMTQsIDB4MjExYTE0NzcsIDB4ZTZhZDIwNjUsIDB4NzdiNWZhODYsIDB4Yzc1NDQyZjUsIDB4ZmI5ZDM1Y2YsXG5cdDB4ZWJjZGFmMGMsIDB4N2IzZTg5YTAsIDB4ZDY0MTFiZDMsIDB4YWUxZTdlNDksIDB4MDAyNTBlMmQsIDB4MjA3MWIzNWUsXG5cdDB4MjI2ODAwYmIsIDB4NTdiOGUwYWYsIDB4MjQ2NDM2OWIsIDB4ZjAwOWI5MWUsIDB4NTU2MzkxMWQsIDB4NTlkZmE2YWEsXG5cdDB4NzhjMTQzODksIDB4ZDk1YTUzN2YsIDB4MjA3ZDViYTIsIDB4MDJlNWI5YzUsIDB4ODMyNjAzNzYsIDB4NjI5NWNmYTksXG5cdDB4MTFjODE5NjgsIDB4NGU3MzRhNDEsIDB4YjM0NzJkY2EsIDB4N2IxNGE5NGEsIDB4MWI1MTAwNTIsIDB4OWE1MzI5MTUsXG5cdDB4ZDYwZjU3M2YsIDB4YmM5YmM2ZTQsIDB4MmI2MGE0NzYsIDB4ODFlNjc0MDAsIDB4MDhiYTZmYjUsIDB4NTcxYmU5MWYsXG5cdDB4ZjI5NmVjNmIsIDB4MmEwZGQ5MTUsIDB4YjY2MzY1MjEsIDB4ZTdiOWY5YjYsIDB4ZmYzNDA1MmUsIDB4YzU4NTU2NjQsXG5cdDB4NTNiMDJkNWQsIDB4YTk5ZjhmYTEsIDB4MDhiYTQ3OTksIDB4NmU4NTA3NmFcbiAgICBdLCBbXG5cdDB4NGI3YTcwZTksIDB4YjViMzI5NDQsIDB4ZGI3NTA5MmUsIDB4YzQxOTI2MjMsIDB4YWQ2ZWE2YjAsIDB4NDlhN2RmN2QsXG5cdDB4OWNlZTYwYjgsIDB4OGZlZGIyNjYsIDB4ZWNhYThjNzEsIDB4Njk5YTE3ZmYsIDB4NTY2NDUyNmMsIDB4YzJiMTllZTEsXG5cdDB4MTkzNjAyYTUsIDB4NzUwOTRjMjksIDB4YTA1OTEzNDAsIDB4ZTQxODNhM2UsIDB4M2Y1NDk4OWEsIDB4NWI0MjlkNjUsXG5cdDB4NmI4ZmU0ZDYsIDB4OTlmNzNmZDYsIDB4YTFkMjljMDcsIDB4ZWZlODMwZjUsIDB4NGQyZDM4ZTYsIDB4ZjAyNTVkYzEsXG5cdDB4NGNkZDIwODYsIDB4ODQ3MGViMjYsIDB4NjM4MmU5YzYsIDB4MDIxZWNjNWUsIDB4MDk2ODZiM2YsIDB4M2ViYWVmYzksXG5cdDB4M2M5NzE4MTQsIDB4NmI2YTcwYTEsIDB4Njg3ZjM1ODQsIDB4NTJhMGUyODYsIDB4Yjc5YzUzMDUsIDB4YWE1MDA3MzcsXG5cdDB4M2UwNzg0MWMsIDB4N2ZkZWFlNWMsIDB4OGU3ZDQ0ZWMsIDB4NTcxNmYyYjgsIDB4YjAzYWRhMzcsIDB4ZjA1MDBjMGQsXG5cdDB4ZjAxYzFmMDQsIDB4MDIwMGIzZmYsIDB4YWUwY2Y1MWEsIDB4M2NiNTc0YjIsIDB4MjU4MzdhNTgsIDB4ZGMwOTIxYmQsXG5cdDB4ZDE5MTEzZjksIDB4N2NhOTJmZjYsIDB4OTQzMjQ3NzMsIDB4MjJmNTQ3MDEsIDB4M2FlNWU1ODEsIDB4MzdjMmRhZGMsXG5cdDB4YzhiNTc2MzQsIDB4OWFmM2RkYTcsIDB4YTk0NDYxNDYsIDB4MGZkMDAzMGUsIDB4ZWNjOGM3M2UsIDB4YTQ3NTFlNDEsXG5cdDB4ZTIzOGNkOTksIDB4M2JlYTBlMmYsIDB4MzI4MGJiYTEsIDB4MTgzZWIzMzEsIDB4NGU1NDhiMzgsIDB4NGY2ZGI5MDgsXG5cdDB4NmY0MjBkMDMsIDB4ZjYwYTA0YmYsIDB4MmNiODEyOTAsIDB4MjQ5NzdjNzksIDB4NTY3OWIwNzIsIDB4YmNhZjg5YWYsXG5cdDB4ZGU5YTc3MWYsIDB4ZDk5MzA4MTAsIDB4YjM4YmFlMTIsIDB4ZGNjZjNmMmUsIDB4NTUxMjcyMWYsIDB4MmU2YjcxMjQsXG5cdDB4NTAxYWRkZTYsIDB4OWY4NGNkODcsIDB4N2E1ODQ3MTgsIDB4NzQwOGRhMTcsIDB4YmM5ZjlhYmMsIDB4ZTk0YjdkOGMsXG5cdDB4ZWM3YWVjM2EsIDB4ZGI4NTFkZmEsIDB4NjMwOTQzNjYsIDB4YzQ2NGMzZDIsIDB4ZWYxYzE4NDcsIDB4MzIxNWQ5MDgsXG5cdDB4ZGQ0MzNiMzcsIDB4MjRjMmJhMTYsIDB4MTJhMTRkNDMsIDB4MmE2NWM0NTEsIDB4NTA5NDAwMDIsIDB4MTMzYWU0ZGQsXG5cdDB4NzFkZmY4OWUsIDB4MTAzMTRlNTUsIDB4ODFhYzc3ZDYsIDB4NWYxMTE5OWIsIDB4MDQzNTU2ZjEsIDB4ZDdhM2M3NmIsXG5cdDB4M2MxMTE4M2IsIDB4NTkyNGE1MDksIDB4ZjI4ZmU2ZWQsIDB4OTdmMWZiZmEsIDB4OWViYWJmMmMsIDB4MWUxNTNjNmUsXG5cdDB4ODZlMzQ1NzAsIDB4ZWFlOTZmYjEsIDB4ODYwZTVlMGEsIDB4NWEzZTJhYjMsIDB4NzcxZmU3MWMsIDB4NGUzZDA2ZmEsXG5cdDB4Mjk2NWRjYjksIDB4OTllNzFkMGYsIDB4ODAzZTg5ZDYsIDB4NTI2NmM4MjUsIDB4MmU0Y2M5NzgsIDB4OWMxMGIzNmEsXG5cdDB4YzYxNTBlYmEsIDB4OTRlMmVhNzgsIDB4YTVmYzNjNTMsIDB4MWUwYTJkZjQsIDB4ZjJmNzRlYTcsIDB4MzYxZDJiM2QsXG5cdDB4MTkzOTI2MGYsIDB4MTljMjc5NjAsIDB4NTIyM2E3MDgsIDB4ZjcxMzEyYjYsIDB4ZWJhZGZlNmUsIDB4ZWFjMzFmNjYsXG5cdDB4ZTNiYzQ1OTUsIDB4YTY3YmM4ODMsIDB4YjE3ZjM3ZDEsIDB4MDE4Y2ZmMjgsIDB4YzMzMmRkZWYsIDB4YmU2YzVhYTUsXG5cdDB4NjU1ODIxODUsIDB4NjhhYjk4MDIsIDB4ZWVjZWE1MGYsIDB4ZGIyZjk1M2IsIDB4MmFlZjdkYWQsIDB4NWI2ZTJmODQsXG5cdDB4MTUyMWI2MjgsIDB4MjkwNzYxNzAsIDB4ZWNkZDQ3NzUsIDB4NjE5ZjE1MTAsIDB4MTNjY2E4MzAsIDB4ZWI2MWJkOTYsXG5cdDB4MDMzNGZlMWUsIDB4YWEwMzYzY2YsIDB4YjU3MzVjOTAsIDB4NGM3MGEyMzksIDB4ZDU5ZTllMGIsIDB4Y2JhYWRlMTQsXG5cdDB4ZWVjYzg2YmMsIDB4NjA2MjJjYTcsIDB4OWNhYjVjYWIsIDB4YjJmMzg0NmUsIDB4NjQ4YjFlYWYsIDB4MTliZGYwY2EsXG5cdDB4YTAyMzY5YjksIDB4NjU1YWJiNTAsIDB4NDA2ODVhMzIsIDB4M2MyYWI0YjMsIDB4MzE5ZWU5ZDUsIDB4YzAyMWI4ZjcsXG5cdDB4OWI1NDBiMTksIDB4ODc1ZmEwOTksIDB4OTVmNzk5N2UsIDB4NjIzZDdkYTgsIDB4ZjgzNzg4OWEsIDB4OTdlMzJkNzcsXG5cdDB4MTFlZDkzNWYsIDB4MTY2ODEyODEsIDB4MGUzNTg4MjksIDB4YzdlNjFmZDYsIDB4OTZkZWRmYTEsIDB4Nzg1OGJhOTksXG5cdDB4NTdmNTg0YTUsIDB4MWIyMjcyNjMsIDB4OWI4M2MzZmYsIDB4MWFjMjQ2OTYsIDB4Y2RiMzBhZWIsIDB4NTMyZTMwNTQsXG5cdDB4OGZkOTQ4ZTQsIDB4NmRiYzMxMjgsIDB4NThlYmYyZWYsIDB4MzRjNmZmZWEsIDB4ZmUyOGVkNjEsIDB4ZWU3YzNjNzMsXG5cdDB4NWQ0YTE0ZDksIDB4ZTg2NGI3ZTMsIDB4NDIxMDVkMTQsIDB4MjAzZTEzZTAsIDB4NDVlZWUyYjYsIDB4YTNhYWFiZWEsXG5cdDB4ZGI2YzRmMTUsIDB4ZmFjYjRmZDAsIDB4Yzc0MmY0NDIsIDB4ZWY2YWJiYjUsIDB4NjU0ZjNiMWQsIDB4NDFjZDIxMDUsXG5cdDB4ZDgxZTc5OWUsIDB4ODY4NTRkYzcsIDB4ZTQ0YjQ3NmEsIDB4M2Q4MTYyNTAsIDB4Y2Y2MmExZjIsIDB4NWI4ZDI2NDYsXG5cdDB4ZmM4ODgzYTAsIDB4YzFjN2I2YTMsIDB4N2YxNTI0YzMsIDB4NjljYjc0OTIsIDB4NDc4NDhhMGIsIDB4NTY5MmIyODUsXG5cdDB4MDk1YmJmMDAsIDB4YWQxOTQ4OWQsIDB4MTQ2MmIxNzQsIDB4MjM4MjBlMDAsIDB4NTg0MjhkMmEsIDB4MGM1NWY1ZWEsXG5cdDB4MWRhZGY0M2UsIDB4MjMzZjcwNjEsIDB4MzM3MmYwOTIsIDB4OGQ5MzdlNDEsIDB4ZDY1ZmVjZjEsIDB4NmMyMjNiZGIsXG5cdDB4N2NkZTM3NTksIDB4Y2JlZTc0NjAsIDB4NDA4NWYyYTcsIDB4Y2U3NzMyNmUsIDB4YTYwNzgwODQsIDB4MTlmODUwOWUsXG5cdDB4ZThlZmQ4NTUsIDB4NjFkOTk3MzUsIDB4YTk2OWE3YWEsIDB4YzUwYzA2YzIsIDB4NWEwNGFiZmMsIDB4ODAwYmNhZGMsXG5cdDB4OWU0NDdhMmUsIDB4YzM0NTM0ODQsIDB4ZmRkNTY3MDUsIDB4MGUxZTllYzksIDB4ZGI3M2RiZDMsIDB4MTA1NTg4Y2QsXG5cdDB4Njc1ZmRhNzksIDB4ZTM2NzQzNDAsIDB4YzVjNDM0NjUsIDB4NzEzZTM4ZDgsIDB4M2QyOGY4OWUsIDB4ZjE2ZGZmMjAsXG5cdDB4MTUzZTIxZTcsIDB4OGZiMDNkNGEsIDB4ZTZlMzlmMmIsIDB4ZGI4M2FkZjdcbiAgICBdLCBbXG5cdDB4ZTkzZDVhNjgsIDB4OTQ4MTQwZjcsIDB4ZjY0YzI2MWMsIDB4OTQ2OTI5MzQsIDB4NDExNTIwZjcsIDB4NzYwMmQ0ZjcsXG5cdDB4YmNmNDZiMmUsIDB4ZDRhMjAwNjgsIDB4ZDQwODI0NzEsIDB4MzMyMGY0NmEsIDB4NDNiN2Q0YjcsIDB4NTAwMDYxYWYsXG5cdDB4MWUzOWY2MmUsIDB4OTcyNDQ1NDYsIDB4MTQyMTRmNzQsIDB4YmY4Yjg4NDAsIDB4NGQ5NWZjMWQsIDB4OTZiNTkxYWYsXG5cdDB4NzBmNGRkZDMsIDB4NjZhMDJmNDUsIDB4YmZiYzA5ZWMsIDB4MDNiZDk3ODUsIDB4N2ZhYzZkZDAsIDB4MzFjYjg1MDQsXG5cdDB4OTZlYjI3YjMsIDB4NTVmZDM5NDEsIDB4ZGEyNTQ3ZTYsIDB4YWJjYTBhOWEsIDB4Mjg1MDc4MjUsIDB4NTMwNDI5ZjQsXG5cdDB4MGEyYzg2ZGEsIDB4ZTliNjZkZmIsIDB4NjhkYzE0NjIsIDB4ZDc0ODY5MDAsIDB4NjgwZWMwYTQsIDB4MjdhMThkZWUsXG5cdDB4NGYzZmZlYTIsIDB4ZTg4N2FkOGMsIDB4YjU4Y2UwMDYsIDB4N2FmNGQ2YjYsIDB4YWFjZTFlN2MsIDB4ZDMzNzVmZWMsXG5cdDB4Y2U3OGEzOTksIDB4NDA2YjJhNDIsIDB4MjBmZTllMzUsIDB4ZDlmMzg1YjksIDB4ZWUzOWQ3YWIsIDB4M2IxMjRlOGIsXG5cdDB4MWRjOWZhZjcsIDB4NGI2ZDE4NTYsIDB4MjZhMzY2MzEsIDB4ZWFlMzk3YjIsIDB4M2E2ZWZhNzQsIDB4ZGQ1YjQzMzIsXG5cdDB4Njg0MWU3ZjcsIDB4Y2E3ODIwZmIsIDB4ZmIwYWY1NGUsIDB4ZDhmZWIzOTcsIDB4NDU0MDU2YWMsIDB4YmE0ODk1MjcsXG5cdDB4NTU1MzNhM2EsIDB4MjA4MzhkODcsIDB4ZmU2YmE5YjcsIDB4ZDA5Njk1NGIsIDB4NTVhODY3YmMsIDB4YTExNTlhNTgsXG5cdDB4Y2NhOTI5NjMsIDB4OTllMWRiMzMsIDB4YTYyYTRhNTYsIDB4M2YzMTI1ZjksIDB4NWVmNDdlMWMsIDB4OTAyOTMxN2MsXG5cdDB4ZmRmOGU4MDIsIDB4MDQyNzJmNzAsIDB4ODBiYjE1NWMsIDB4MDUyODJjZTMsIDB4OTVjMTE1NDgsIDB4ZTRjNjZkMjIsXG5cdDB4NDhjMTEzM2YsIDB4YzcwZjg2ZGMsIDB4MDdmOWM5ZWUsIDB4NDEwNDFmMGYsIDB4NDA0Nzc5YTQsIDB4NWQ4ODZlMTcsXG5cdDB4MzI1ZjUxZWIsIDB4ZDU5YmMwZDEsIDB4ZjJiY2MxOGYsIDB4NDExMTM1NjQsIDB4MjU3Yjc4MzQsIDB4NjAyYTljNjAsXG5cdDB4ZGZmOGU4YTMsIDB4MWY2MzZjMWIsIDB4MGUxMmI0YzIsIDB4MDJlMTMyOWUsIDB4YWY2NjRmZDEsIDB4Y2FkMTgxMTUsXG5cdDB4NmIyMzk1ZTAsIDB4MzMzZTkyZTEsIDB4M2IyNDBiNjIsIDB4ZWViZWI5MjIsIDB4ODViMmEyMGUsIDB4ZTZiYTBkOTksXG5cdDB4ZGU3MjBjOGMsIDB4MmRhMmY3MjgsIDB4ZDAxMjc4NDUsIDB4OTViNzk0ZmQsIDB4NjQ3ZDA4NjIsIDB4ZTdjY2Y1ZjAsXG5cdDB4NTQ0OWEzNmYsIDB4ODc3ZDQ4ZmEsIDB4YzM5ZGZkMjcsIDB4ZjMzZThkMWUsIDB4MGE0NzYzNDEsIDB4OTkyZWZmNzQsXG5cdDB4M2E2ZjZlYWIsIDB4ZjRmOGZkMzcsIDB4YTgxMmRjNjAsIDB4YTFlYmRkZjgsIDB4OTkxYmUxNGMsIDB4ZGI2ZTZiMGQsXG5cdDB4YzY3YjU1MTAsIDB4NmQ2NzJjMzcsIDB4Mjc2NWQ0M2IsIDB4ZGNkMGU4MDQsIDB4ZjEyOTBkYzcsIDB4Y2MwMGZmYTMsXG5cdDB4YjUzOTBmOTIsIDB4NjkwZmVkMGIsIDB4NjY3YjlmZmIsIDB4Y2VkYjdkOWMsIDB4YTA5MWNmMGIsIDB4ZDkxNTVlYTMsXG5cdDB4YmIxMzJmODgsIDB4NTE1YmFkMjQsIDB4N2I5NDc5YmYsIDB4NzYzYmQ2ZWIsIDB4MzczOTJlYjMsIDB4Y2MxMTU5NzksXG5cdDB4ODAyNmUyOTcsIDB4ZjQyZTMxMmQsIDB4Njg0MmFkYTcsIDB4YzY2YTJiM2IsIDB4MTI3NTRjY2MsIDB4NzgyZWYxMWMsXG5cdDB4NmExMjQyMzcsIDB4Yjc5MjUxZTcsIDB4MDZhMWJiZTYsIDB4NGJmYjYzNTAsIDB4MWE2YjEwMTgsIDB4MTFjYWVkZmEsXG5cdDB4M2QyNWJkZDgsIDB4ZTJlMWMzYzksIDB4NDQ0MjE2NTksIDB4MGExMjEzODYsIDB4ZDkwY2VjNmUsIDB4ZDVhYmVhMmEsXG5cdDB4NjRhZjY3NGUsIDB4ZGE4NmE4NWYsIDB4YmViZmU5ODgsIDB4NjRlNGMzZmUsIDB4OWRiYzgwNTcsIDB4ZjBmN2MwODYsXG5cdDB4NjA3ODdiZjgsIDB4NjAwMzYwNGQsIDB4ZDFmZDgzNDYsIDB4ZjYzODFmYjAsIDB4Nzc0NWFlMDQsIDB4ZDczNmZjY2MsXG5cdDB4ODM0MjZiMzMsIDB4ZjAxZWFiNzEsIDB4YjA4MDQxODcsIDB4M2MwMDVlNWYsIDB4NzdhMDU3YmUsIDB4YmRlOGFlMjQsXG5cdDB4NTU0NjQyOTksIDB4YmY1ODJlNjEsIDB4NGU1OGY0OGYsIDB4ZjJkZGZkYTIsIDB4ZjQ3NGVmMzgsIDB4ODc4OWJkYzIsXG5cdDB4NTM2NmY5YzMsIDB4YzhiMzhlNzQsIDB4YjQ3NWYyNTUsIDB4NDZmY2Q5YjksIDB4N2FlYjI2NjEsIDB4OGIxZGRmODQsXG5cdDB4ODQ2YTBlNzksIDB4OTE1Zjk1ZTIsIDB4NDY2ZTU5OGUsIDB4MjBiNDU3NzAsIDB4OGNkNTU1OTEsIDB4YzkwMmRlNGMsXG5cdDB4YjkwYmFjZTEsIDB4YmI4MjA1ZDAsIDB4MTFhODYyNDgsIDB4NzU3NGE5OWUsIDB4Yjc3ZjE5YjYsIDB4ZTBhOWRjMDksXG5cdDB4NjYyZDA5YTEsIDB4YzQzMjQ2MzMsIDB4ZTg1YTFmMDIsIDB4MDlmMGJlOGMsIDB4NGE5OWEwMjUsIDB4MWQ2ZWZlMTAsXG5cdDB4MWFiOTNkMWQsIDB4MGJhNWE0ZGYsIDB4YTE4NmYyMGYsIDB4Mjg2OGYxNjksIDB4ZGNiN2RhODMsIDB4NTczOTA2ZmUsXG5cdDB4YTFlMmNlOWIsIDB4NGZjZDdmNTIsIDB4NTAxMTVlMDEsIDB4YTcwNjgzZmEsIDB4YTAwMmI1YzQsIDB4MGRlNmQwMjcsXG5cdDB4OWFmODhjMjcsIDB4NzczZjg2NDEsIDB4YzM2MDRjMDYsIDB4NjFhODA2YjUsIDB4ZjAxNzdhMjgsIDB4YzBmNTg2ZTAsXG5cdDB4MDA2MDU4YWEsIDB4MzBkYzdkNjIsIDB4MTFlNjllZDcsIDB4MjMzOGVhNjMsIDB4NTNjMmRkOTQsIDB4YzJjMjE2MzQsXG5cdDB4YmJjYmVlNTYsIDB4OTBiY2I2ZGUsIDB4ZWJmYzdkYTEsIDB4Y2U1OTFkNzYsIDB4NmYwNWU0MDksIDB4NGI3YzAxODgsXG5cdDB4Mzk3MjBhM2QsIDB4N2M5MjdjMjQsIDB4ODZlMzcyNWYsIDB4NzI0ZDlkYjksIDB4MWFjMTViYjQsIDB4ZDM5ZWI4ZmMsXG5cdDB4ZWQ1NDU1NzgsIDB4MDhmY2E1YjUsIDB4ZDgzZDdjZDMsIDB4NGRhZDBmYzQsIDB4MWU1MGVmNWUsIDB4YjE2MWU2ZjgsXG5cdDB4YTI4NTE0ZDksIDB4NmM1MTEzM2MsIDB4NmZkNWM3ZTcsIDB4NTZlMTRlYzQsIDB4MzYyYWJmY2UsIDB4ZGRjNmM4MzcsXG5cdDB4ZDc5YTMyMzQsIDB4OTI2MzgyMTIsIDB4NjcwZWZhOGUsIDB4NDA2MDAwZTBcbiAgICBdLCBbXG5cdDB4M2EzOWNlMzcsIDB4ZDNmYWY1Y2YsIDB4YWJjMjc3MzcsIDB4NWFjNTJkMWIsIDB4NWNiMDY3OWUsIDB4NGZhMzM3NDIsXG5cdDB4ZDM4MjI3NDAsIDB4OTliYzliYmUsIDB4ZDUxMThlOWQsIDB4YmYwZjczMTUsIDB4ZDYyZDFjN2UsIDB4YzcwMGM0N2IsXG5cdDB4Yjc4YzFiNmIsIDB4MjFhMTkwNDUsIDB4YjI2ZWIxYmUsIDB4NmEzNjZlYjQsIDB4NTc0OGFiMmYsIDB4YmM5NDZlNzksXG5cdDB4YzZhMzc2ZDIsIDB4NjU0OWMyYzgsIDB4NTMwZmY4ZWUsIDB4NDY4ZGRlN2QsIDB4ZDU3MzBhMWQsIDB4NGNkMDRkYzYsXG5cdDB4MjkzOWJiZGIsIDB4YTliYTQ2NTAsIDB4YWM5NTI2ZTgsIDB4YmU1ZWUzMDQsIDB4YTFmYWQ1ZjAsIDB4NmEyZDUxOWEsXG5cdDB4NjNlZjhjZTIsIDB4OWE4NmVlMjIsIDB4YzA4OWMyYjgsIDB4NDMyNDJlZjYsIDB4YTUxZTAzYWEsIDB4OWNmMmQwYTQsXG5cdDB4ODNjMDYxYmEsIDB4OWJlOTZhNGQsIDB4OGZlNTE1NTAsIDB4YmE2NDViZDYsIDB4MjgyNmEyZjksIDB4YTczYTNhZTEsXG5cdDB4NGJhOTk1ODYsIDB4ZWY1NTYyZTksIDB4YzcyZmVmZDMsIDB4Zjc1MmY3ZGEsIDB4M2YwNDZmNjksIDB4NzdmYTBhNTksXG5cdDB4ODBlNGE5MTUsIDB4ODdiMDg2MDEsIDB4OWIwOWU2YWQsIDB4M2IzZWU1OTMsIDB4ZTk5MGZkNWEsIDB4OWUzNGQ3OTcsXG5cdDB4MmNmMGI3ZDksIDB4MDIyYjhiNTEsIDB4OTZkNWFjM2EsIDB4MDE3ZGE2N2QsIDB4ZDFjZjNlZDYsIDB4N2M3ZDJkMjgsXG5cdDB4MWY5ZjI1Y2YsIDB4YWRmMmI4OWIsIDB4NWFkNmI0NzIsIDB4NWE4OGY1NGMsIDB4ZTAyOWFjNzEsIDB4ZTAxOWE1ZTYsXG5cdDB4NDdiMGFjZmQsIDB4ZWQ5M2ZhOWIsIDB4ZThkM2M0OGQsIDB4MjgzYjU3Y2MsIDB4ZjhkNTY2MjksIDB4NzkxMzJlMjgsXG5cdDB4Nzg1ZjAxOTEsIDB4ZWQ3NTYwNTUsIDB4Zjc5NjBlNDQsIDB4ZTNkMzVlOGMsIDB4MTUwNTZkZDQsIDB4ODhmNDZkYmEsXG5cdDB4MDNhMTYxMjUsIDB4MDU2NGYwYmQsIDB4YzNlYjllMTUsIDB4M2M5MDU3YTIsIDB4OTcyNzFhZWMsIDB4YTkzYTA3MmEsXG5cdDB4MWIzZjZkOWIsIDB4MWU2MzIxZjUsIDB4ZjU5YzY2ZmIsIDB4MjZkY2YzMTksIDB4NzUzM2Q5MjgsIDB4YjE1NWZkZjUsXG5cdDB4MDM1NjM0ODIsIDB4OGFiYTNjYmIsIDB4Mjg1MTc3MTEsIDB4YzIwYWQ5ZjgsIDB4YWJjYzUxNjcsIDB4Y2NhZDkyNWYsXG5cdDB4NGRlODE3NTEsIDB4MzgzMGRjOGUsIDB4Mzc5ZDU4NjIsIDB4OTMyMGY5OTEsIDB4ZWE3YTkwYzIsIDB4ZmIzZTdiY2UsXG5cdDB4NTEyMWNlNjQsIDB4Nzc0ZmJlMzIsIDB4YThiNmUzN2UsIDB4YzMyOTNkNDYsIDB4NDhkZTUzNjksIDB4NjQxM2U2ODAsXG5cdDB4YTJhZTA4MTAsIDB4ZGQ2ZGIyMjQsIDB4Njk4NTJkZmQsIDB4MDkwNzIxNjYsIDB4YjM5YTQ2MGEsIDB4NjQ0NWMwZGQsXG5cdDB4NTg2Y2RlY2YsIDB4MWMyMGM4YWUsIDB4NWJiZWY3ZGQsIDB4MWI1ODhkNDAsIDB4Y2NkMjAxN2YsIDB4NmJiNGUzYmIsXG5cdDB4ZGRhMjZhN2UsIDB4M2E1OWZmNDUsIDB4M2UzNTBhNDQsIDB4YmNiNGNkZDUsIDB4NzJlYWNlYTgsIDB4ZmE2NDg0YmIsXG5cdDB4OGQ2NjEyYWUsIDB4YmYzYzZmNDcsIDB4ZDI5YmU0NjMsIDB4NTQyZjVkOWUsIDB4YWVjMjc3MWIsIDB4ZjY0ZTYzNzAsXG5cdDB4NzQwZTBkOGQsIDB4ZTc1YjEzNTcsIDB4Zjg3MjE2NzEsIDB4YWY1MzdkNWQsIDB4NDA0MGNiMDgsIDB4NGViNGUyY2MsXG5cdDB4MzRkMjQ2NmEsIDB4MDExNWFmODQsIDB4ZTFiMDA0MjgsIDB4OTU5ODNhMWQsIDB4MDZiODlmYjQsIDB4Y2U2ZWEwNDgsXG5cdDB4NmYzZjNiODIsIDB4MzUyMGFiODIsIDB4MDExYTFkNGIsIDB4Mjc3MjI3ZjgsIDB4NjExNTYwYjEsIDB4ZTc5MzNmZGMsXG5cdDB4YmIzYTc5MmIsIDB4MzQ0NTI1YmQsIDB4YTA4ODM5ZTEsIDB4NTFjZTc5NGIsIDB4MmYzMmM5YjcsIDB4YTAxZmJhYzksXG5cdDB4ZTAxY2M4N2UsIDB4YmNjN2QxZjYsIDB4Y2YwMTExYzMsIDB4YTFlOGFhYzcsIDB4MWE5MDg3NDksIDB4ZDQ0ZmJkOWEsXG5cdDB4ZDBkYWRlY2IsIDB4ZDUwYWRhMzgsIDB4MDMzOWMzMmEsIDB4YzY5MTM2NjcsIDB4OGRmOTMxN2MsIDB4ZTBiMTJiNGYsXG5cdDB4Zjc5ZTU5YjcsIDB4NDNmNWJiM2EsIDB4ZjJkNTE5ZmYsIDB4MjdkOTQ1OWMsIDB4YmY5NzIyMmMsIDB4MTVlNmZjMmEsXG5cdDB4MGY5MWZjNzEsIDB4OWI5NDE1MjUsIDB4ZmFlNTkzNjEsIDB4Y2ViNjljZWIsIDB4YzJhODY0NTksIDB4MTJiYWE4ZDEsXG5cdDB4YjZjMTA3NWUsIDB4ZTMwNTZhMGMsIDB4MTBkMjUwNjUsIDB4Y2IwM2E0NDIsIDB4ZTBlYzZlMGUsIDB4MTY5OGRiM2IsXG5cdDB4NGM5OGEwYmUsIDB4MzI3OGU5NjQsIDB4OWYxZjk1MzIsIDB4ZTBkMzkyZGYsIDB4ZDNhMDM0MmIsIDB4ODk3MWYyMWUsXG5cdDB4MWIwYTc0NDEsIDB4NGJhMzM0OGMsIDB4YzViZTcxMjAsIDB4YzM3NjMyZDgsIDB4ZGYzNTlmOGQsIDB4OWI5OTJmMmUsXG5cdDB4ZTYwYjZmNDcsIDB4MGZlM2YxMWQsIDB4ZTU0Y2RhNTQsIDB4MWVkYWQ4OTEsIDB4Y2U2Mjc5Y2YsIDB4Y2QzZTdlNmYsXG5cdDB4MTYxOGIxNjYsIDB4ZmQyYzFkMDUsIDB4ODQ4ZmQyYzUsIDB4ZjZmYjIyOTksIDB4ZjUyM2YzNTcsIDB4YTYzMjc2MjMsXG5cdDB4OTNhODM1MzEsIDB4NTZjY2NkMDIsIDB4YWNmMDgxNjIsIDB4NWE3NWViYjUsIDB4NmUxNjM2OTcsIDB4ODhkMjczY2MsXG5cdDB4ZGU5NjYyOTIsIDB4ODFiOTQ5ZDAsIDB4NGM1MDkwMWIsIDB4NzFjNjU2MTQsIDB4ZTZjNmM3YmQsIDB4MzI3YTE0MGEsXG5cdDB4NDVlMWQwMDYsIDB4YzNmMjdiOWEsIDB4YzlhYTUzZmQsIDB4NjJhODBmMDAsIDB4YmIyNWJmZTIsIDB4MzViZGQyZjYsXG5cdDB4NzExMjY5MDUsIDB4YjIwNDAyMjIsIDB4YjZjYmNmN2MsIDB4Y2Q3NjljMmIsIDB4NTMxMTNlYzAsIDB4MTY0MGUzZDMsXG5cdDB4MzhhYmJkNjAsIDB4MjU0N2FkZjAsIDB4YmEzODIwOWMsIDB4Zjc0NmNlNzYsIDB4NzdhZmExYzUsIDB4MjA3NTYwNjAsXG5cdDB4ODVjYmZlNGUsIDB4OGFlODhkZDgsIDB4N2FhYWY5YjAsIDB4NGNmOWFhN2UsIDB4MTk0OGMyNWMsIDB4MDJmYjhhOGMsXG5cdDB4MDFjMzZhZTQsIDB4ZDZlYmUxZjksIDB4OTBkNGY4NjksIDB4YTY1Y2RlYTAsIDB4M2YwOTI1MmQsIDB4YzIwOGU2OWYsXG5cdDB4Yjc0ZTYxMzIsIDB4Y2U3N2UyNWIsIDB4NTc4ZmRmZTMsIDB4M2FjMzcyZTZcbiAgICBdXG5dO1xuXG4vLypcbi8vKiBUaGlzIGlzIHRoZSBkZWZhdWx0IFBBUlJBWVxuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuUEFSUkFZID0gW1xuICAgIDB4MjQzZjZhODgsIDB4ODVhMzA4ZDMsIDB4MTMxOThhMmUsIDB4MDM3MDczNDQsIDB4YTQwOTM4MjIsIDB4Mjk5ZjMxZDAsXG4gICAgMHgwODJlZmE5OCwgMHhlYzRlNmM4OSwgMHg0NTI4MjFlNiwgMHgzOGQwMTM3NywgMHhiZTU0NjZjZiwgMHgzNGU5MGM2YyxcbiAgICAweGMwYWMyOWI3LCAweGM5N2M1MGRkLCAweDNmODRkNWI1LCAweGI1NDcwOTE3LCAweDkyMTZkNWQ5LCAweDg5NzlmYjFiXG5dO1xuXG4vLypcbi8vKiBUaGlzIGlzIHRoZSBudW1iZXIgb2Ygcm91bmRzIHRoZSBjaXBoZXIgd2lsbCBnb1xuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuTk4gPSAxNjtcblxuLy8qXG4vLyogVGhpcyBmdW5jdGlvbiBpcyBuZWVkZWQgdG8gZ2V0IHJpZCBvZiBwcm9ibGVtc1xuLy8qIHdpdGggdGhlIGhpZ2gtYml0IGdldHRpbmcgc2V0LiAgSWYgd2UgZG9uJ3QgZG9cbi8vKiB0aGlzLCB0aGVuIHNvbWV0aW1lcyAoIGFhICYgMHgwMEZGRkZGRkZGICkgaXMgbm90XG4vLyogZXF1YWwgdG8gKCBiYiAmIDB4MDBGRkZGRkZGRiApIGV2ZW4gd2hlbiB0aGV5XG4vLyogYWdyZWUgYml0LWZvci1iaXQgZm9yIHRoZSBmaXJzdCAzMiBiaXRzLlxuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuX2NsZWFuID0gZnVuY3Rpb24oIHh4ICkge1xuICAgIGlmICggeHggPCAwICkge1xuXHR2YXIgeXkgPSB4eCAmIDB4N0ZGRkZGRkY7XG5cdHh4ID0geXkgKyAweDgwMDAwMDAwO1xuICAgIH1cbiAgICByZXR1cm4geHg7XG59O1xuXG4vLypcbi8vKiBUaGlzIGlzIHRoZSBtaXhpbmcgZnVuY3Rpb24gdGhhdCB1c2VzIHRoZSBzYm94ZXNcbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLl9GID0gZnVuY3Rpb24gKCB4eCApIHtcbiAgICB2YXIgYWE7XG4gICAgdmFyIGJiO1xuICAgIHZhciBjYztcbiAgICB2YXIgZGQ7XG4gICAgdmFyIHl5O1xuXG4gICAgZGQgPSB4eCAmIDB4MDBGRjtcbiAgICB4eCA+Pj49IDg7XG4gICAgY2MgPSB4eCAmIDB4MDBGRjtcbiAgICB4eCA+Pj49IDg7XG4gICAgYmIgPSB4eCAmIDB4MDBGRjtcbiAgICB4eCA+Pj49IDg7XG4gICAgYWEgPSB4eCAmIDB4MDBGRjtcblxuICAgIHl5ID0gdGhpcy5zYm94ZXNbIDAgXVsgYWEgXSArIHRoaXMuc2JveGVzWyAxIF1bIGJiIF07XG4gICAgeXkgPSB5eSBeIHRoaXMuc2JveGVzWyAyIF1bIGNjIF07XG4gICAgeXkgPSB5eSArIHRoaXMuc2JveGVzWyAzIF1bIGRkIF07XG5cbiAgICByZXR1cm4geXk7XG59O1xuXG4vLypcbi8vKiBUaGlzIG1ldGhvZCB0YWtlcyBhbiBhcnJheSB3aXRoIHR3byB2YWx1ZXMsIGxlZnQgYW5kIHJpZ2h0XG4vLyogYW5kIGRvZXMgTk4gcm91bmRzIG9mIEJsb3dmaXNoIG9uIHRoZW0uXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5fZW5jcnlwdF9ibG9jayA9IGZ1bmN0aW9uICggdmFscyApIHtcbiAgICB2YXIgZGF0YUwgPSB2YWxzWyAwIF07XG4gICAgdmFyIGRhdGFSID0gdmFsc1sgMSBdO1xuXG4gICAgdmFyIGlpO1xuXG4gICAgZm9yICggaWk9MDsgaWkgPCB0aGlzLk5OOyArK2lpICkge1xuXHRkYXRhTCA9IGRhdGFMIF4gdGhpcy5wYXJyYXlbIGlpIF07XG5cdGRhdGFSID0gdGhpcy5fRiggZGF0YUwgKSBeIGRhdGFSO1xuXG5cdHZhciB0bXAgPSBkYXRhTDtcblx0ZGF0YUwgPSBkYXRhUjtcblx0ZGF0YVIgPSB0bXA7XG4gICAgfVxuXG4gICAgZGF0YUwgPSBkYXRhTCBeIHRoaXMucGFycmF5WyB0aGlzLk5OICsgMCBdO1xuICAgIGRhdGFSID0gZGF0YVIgXiB0aGlzLnBhcnJheVsgdGhpcy5OTiArIDEgXTtcblxuICAgIHZhbHNbIDAgXSA9IHRoaXMuX2NsZWFuKCBkYXRhUiApO1xuICAgIHZhbHNbIDEgXSA9IHRoaXMuX2NsZWFuKCBkYXRhTCApO1xufTtcblxuLy8qXG4vLyogVGhpcyBtZXRob2QgdGFrZXMgYSB2ZWN0b3Igb2YgbnVtYmVycyBhbmQgdHVybnMgdGhlbVxuLy8qIGludG8gbG9uZyB3b3JkcyBzbyB0aGF0IHRoZXkgY2FuIGJlIHByb2Nlc3NlZCBieSB0aGVcbi8vKiByZWFsIGFsZ29yaXRobS5cbi8vKlxuLy8qIE1heWJlIEkgc2hvdWxkIG1ha2UgdGhlIHJlYWwgYWxnb3JpdGhtIGFib3ZlIHRha2UgYSB2ZWN0b3Jcbi8vKiBpbnN0ZWFkLiAgVGhhdCB3aWxsIGludm9sdmUgbW9yZSBsb29waW5nLCBidXQgaXQgd29uJ3QgcmVxdWlyZVxuLy8qIHRoZSBGKCkgbWV0aG9kIHRvIGRlY29uc3RydWN0IHRoZSB2ZWN0b3IuXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5lbmNyeXB0X2Jsb2NrID0gZnVuY3Rpb24gKCB2ZWN0b3IgKSB7XG4gICAgdmFyIGlpO1xuICAgIHZhciB2YWxzID0gWyAwLCAwIF07XG4gICAgdmFyIG9mZiAgPSB0aGlzLkJMT0NLU0laRS8yO1xuICAgIGZvciAoIGlpID0gMDsgaWkgPCB0aGlzLkJMT0NLU0laRS8yOyArK2lpICkge1xuXHR2YWxzWzBdID0gKCB2YWxzWzBdIDw8IDggKSB8ICggdmVjdG9yWyBpaSArIDAgICBdICYgMHgwMEZGICk7XG5cdHZhbHNbMV0gPSAoIHZhbHNbMV0gPDwgOCApIHwgKCB2ZWN0b3JbIGlpICsgb2ZmIF0gJiAweDAwRkYgKTtcbiAgICB9XG5cbiAgICB0aGlzLl9lbmNyeXB0X2Jsb2NrKCB2YWxzICk7XG5cbiAgICB2YXIgcmV0ID0gWyBdO1xuICAgIGZvciAoIGlpID0gMDsgaWkgPCB0aGlzLkJMT0NLU0laRS8yOyArK2lpICkge1xuXHRyZXRbIGlpICsgMCAgIF0gPSAoIHZhbHNbIDAgXSA+Pj4gKDI0IC0gOCooaWkpKSAmIDB4MDBGRiApO1xuXHRyZXRbIGlpICsgb2ZmIF0gPSAoIHZhbHNbIDEgXSA+Pj4gKDI0IC0gOCooaWkpKSAmIDB4MDBGRiApO1xuXHQvLyB2YWxzWyAwIF0gPSAoIHZhbHNbIDAgXSA+Pj4gOCApO1xuXHQvLyB2YWxzWyAxIF0gPSAoIHZhbHNbIDEgXSA+Pj4gOCApO1xuICAgIH1cblxuICAgIHJldHVybiByZXQ7XG59O1xuXG4vLypcbi8vKiBUaGlzIG1ldGhvZCB0YWtlcyBhbiBhcnJheSB3aXRoIHR3byB2YWx1ZXMsIGxlZnQgYW5kIHJpZ2h0XG4vLyogYW5kIHVuZG9lcyBOTiByb3VuZHMgb2YgQmxvd2Zpc2ggb24gdGhlbS5cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLl9kZWNyeXB0X2Jsb2NrID0gZnVuY3Rpb24gKCB2YWxzICkge1xuICAgIHZhciBkYXRhTCA9IHZhbHNbIDAgXTtcbiAgICB2YXIgZGF0YVIgPSB2YWxzWyAxIF07XG5cbiAgICB2YXIgaWk7XG5cbiAgICBmb3IgKCBpaT10aGlzLk5OKzE7IGlpID4gMTsgLS1paSApIHtcblx0ZGF0YUwgPSBkYXRhTCBeIHRoaXMucGFycmF5WyBpaSBdO1xuXHRkYXRhUiA9IHRoaXMuX0YoIGRhdGFMICkgXiBkYXRhUjtcblxuXHR2YXIgdG1wID0gZGF0YUw7XG5cdGRhdGFMID0gZGF0YVI7XG5cdGRhdGFSID0gdG1wO1xuICAgIH1cblxuICAgIGRhdGFMID0gZGF0YUwgXiB0aGlzLnBhcnJheVsgMSBdO1xuICAgIGRhdGFSID0gZGF0YVIgXiB0aGlzLnBhcnJheVsgMCBdO1xuXG4gICAgdmFsc1sgMCBdID0gdGhpcy5fY2xlYW4oIGRhdGFSICk7XG4gICAgdmFsc1sgMSBdID0gdGhpcy5fY2xlYW4oIGRhdGFMICk7XG59O1xuXG4vLypcbi8vKiBUaGlzIG1ldGhvZCB0YWtlcyBhIGtleSBhcnJheSBhbmQgaW5pdGlhbGl6ZXMgdGhlXG4vLyogc2JveGVzIGFuZCBwYXJyYXkgZm9yIHRoaXMgZW5jcnlwdGlvbi5cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoIGtleSApIHtcbiAgICB2YXIgaWk7XG4gICAgdmFyIGpqID0gMDtcblxuICAgIHRoaXMucGFycmF5ID0gW107XG4gICAgZm9yICggaWk9MDsgaWkgPCB0aGlzLk5OICsgMjsgKytpaSApIHtcblx0dmFyIGRhdGEgPSAweDAwMDAwMDAwO1xuXHR2YXIga2s7XG5cdGZvciAoIGtrPTA7IGtrIDwgNDsgKytrayApIHtcblx0ICAgIGRhdGEgPSAoIGRhdGEgPDwgOCApIHwgKCBrZXlbIGpqIF0gJiAweDAwRkYgKTtcblx0ICAgIGlmICggKytqaiA+PSBrZXkubGVuZ3RoICkge1xuXHRcdGpqID0gMDtcblx0ICAgIH1cblx0fVxuXHR0aGlzLnBhcnJheVsgaWkgXSA9IHRoaXMuUEFSUkFZWyBpaSBdIF4gZGF0YTtcbiAgICB9XG5cbiAgICB0aGlzLnNib3hlcyA9IFtdO1xuICAgIGZvciAoIGlpPTA7IGlpIDwgNDsgKytpaSApIHtcblx0dGhpcy5zYm94ZXNbIGlpIF0gPSBbXTtcblx0Zm9yICggamo9MDsgamogPCAyNTY7ICsramogKSB7XG5cdCAgICB0aGlzLnNib3hlc1sgaWkgXVsgamogXSA9IHRoaXMuU0JPWEVTWyBpaSBdWyBqaiBdO1xuXHR9XG4gICAgfVxuXG4gICAgdmFyIHZhbHMgPSBbIDB4MDAwMDAwMDAsIDB4MDAwMDAwMDAgXTtcblxuICAgIGZvciAoIGlpPTA7IGlpIDwgdGhpcy5OTisyOyBpaSArPSAyICkge1xuXHR0aGlzLl9lbmNyeXB0X2Jsb2NrKCB2YWxzICk7XG5cdHRoaXMucGFycmF5WyBpaSArIDAgXSA9IHZhbHNbIDAgXTtcblx0dGhpcy5wYXJyYXlbIGlpICsgMSBdID0gdmFsc1sgMSBdO1xuICAgIH1cblxuICAgIGZvciAoIGlpPTA7IGlpIDwgNDsgKytpaSApIHtcblx0Zm9yICggamo9MDsgamogPCAyNTY7IGpqICs9IDIgKSB7XG5cdCAgICB0aGlzLl9lbmNyeXB0X2Jsb2NrKCB2YWxzICk7XG5cdCAgICB0aGlzLnNib3hlc1sgaWkgXVsgamogKyAwIF0gPSB2YWxzWyAwIF07XG5cdCAgICB0aGlzLnNib3hlc1sgaWkgXVsgamogKyAxIF0gPSB2YWxzWyAxIF07XG5cdH1cbiAgICB9XG59O1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuLy8gYWRkZWQgYnkgUmVjdXJpdHkgTGFic1xuZnVuY3Rpb24gQkZlbmNyeXB0KGJsb2NrLGtleSkge1xuXHR2YXIgYmYgPSBuZXcgQmxvd2Zpc2goKTtcblx0YmYuaW5pdCh1dGlsLnN0cjJiaW4oa2V5KSk7XG5cdHJldHVybiBiZi5lbmNyeXB0X2Jsb2NrKGJsb2NrKTtcbn1cblxuZnVuY3Rpb24gQkYoa2V5KSB7XG5cdHRoaXMuYmYgPSBuZXcgQmxvd2Zpc2goKTtcblx0dGhpcy5iZi5pbml0KHV0aWwuc3RyMmJpbihrZXkpKTtcblxuXHR0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaykge1xuXHRcdHJldHVybiB0aGlzLmJmLmVuY3J5cHRfYmxvY2soYmxvY2spO1xuXHR9XG59XG5cblxubW9kdWxlLmV4cG9ydHMgPSBCRjtcbm1vZHVsZS5leHBvcnRzLmtleVNpemUgPSBCRi5wcm90b3R5cGUua2V5U2l6ZSA9IDE2O1xubW9kdWxlLmV4cG9ydHMuYmxvY2tTaXplID0gQkYucHJvdG90eXBlLmJsb2NrU2l6ZSA9IDE2O1xuXG5cbiIsIlxyXG4vLyBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhIEJTRC1zdHlsZVxyXG4vLyBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuXHJcblxyXG4vLyBDb3B5cmlnaHQgMjAxMCBwamFjb2JzQHhlZWtyLmNvbSAuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcblxyXG4vLyBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkhcclxuXHJcbi8vIGZpeGVkL21vZGlmaWVkIGJ5IEhlcmJlcnQgSGFuZXdpbmtlbCwgd3d3LmhhbmVXSU4uZGVcclxuLy8gY2hlY2sgd3d3LmhhbmVXSU4uZGUgZm9yIHRoZSBsYXRlc3QgdmVyc2lvblxyXG5cclxuLy8gY2FzdDUuanMgaXMgYSBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIENBU1QtMTI4LCBhcyBkZWZpbmVkIGluIFJGQyAyMTQ0LlxyXG4vLyBDQVNULTEyOCBpcyBhIGNvbW1vbiBPcGVuUEdQIGNpcGhlci5cclxuXHJcblxyXG4vLyBDQVNUNSBjb25zdHJ1Y3RvclxyXG5cclxuXHJcblxyXG5mdW5jdGlvbiBvcGVucGdwX3N5bWVuY19jYXN0NSgpIHtcclxuXHR0aGlzLkJsb2NrU2l6ZT0gODtcclxuXHR0aGlzLktleVNpemUgPSAxNjtcclxuXHJcblx0dGhpcy5zZXRLZXkgPSBmdW5jdGlvbiAoa2V5KSB7XHJcblx0XHQgdGhpcy5tYXNraW5nID0gbmV3IEFycmF5KDE2KTtcclxuXHRcdCB0aGlzLnJvdGF0ZSA9IG5ldyBBcnJheSgxNik7XHJcblxyXG5cdFx0IHRoaXMucmVzZXQoKTtcclxuXHJcblx0XHQgaWYgKGtleS5sZW5ndGggPT0gdGhpcy5LZXlTaXplKVxyXG5cdFx0IHtcclxuXHRcdCAgIHRoaXMua2V5U2NoZWR1bGUoa2V5KTtcclxuXHRcdCB9XHJcblx0XHQgZWxzZVxyXG5cdFx0IHtcclxuXHRcdCAgIHV0aWwucHJpbnRfZXJyb3IoJ2Nhc3Q1LmpzOiBDQVNULTEyODoga2V5cyBtdXN0IGJlIDE2IGJ5dGVzJyk7XHJcblx0XHQgICByZXR1cm4gZmFsc2U7XHJcblx0XHQgfVxyXG5cdFx0IHJldHVybiB0cnVlO1xyXG5cdH07XHJcblx0XHJcblx0dGhpcy5yZXNldCA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0IGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKylcclxuXHRcdCB7XHJcblx0XHQgIHRoaXMubWFza2luZ1tpXSA9IDA7XHJcblx0XHQgIHRoaXMucm90YXRlW2ldID0gMDtcclxuXHRcdCB9XHJcblx0fTtcclxuXHJcblx0dGhpcy5nZXRCbG9ja1NpemUgPSBmdW5jdGlvbigpIHtcclxuXHRcdCByZXR1cm4gQmxvY2tTaXplO1xyXG5cdH07XHJcblxyXG5cdHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKHNyYykge1xyXG5cdFx0IHZhciBkc3QgPSBuZXcgQXJyYXkoc3JjLmxlbmd0aCk7XHJcblxyXG5cdFx0IGZvcih2YXIgaSA9IDA7IGkgPCBzcmMubGVuZ3RoOyBpKz04KVxyXG5cdFx0IHtcclxuXHRcdCAgdmFyIGwgPSBzcmNbaV08PDI0IHwgc3JjW2krMV08PDE2IHwgc3JjW2krMl08PDggfCBzcmNbaSszXTtcclxuXHRcdCAgdmFyIHIgPSBzcmNbaSs0XTw8MjQgfCBzcmNbaSs1XTw8MTYgfCBzcmNbaSs2XTw8OCB8IHNyY1tpKzddO1xyXG5cdFx0ICB2YXIgdDtcclxuXHJcblx0XHQgIHQgPSByOyByID0gbF5mMShyLCB0aGlzLm1hc2tpbmdbMF0sIHRoaXMucm90YXRlWzBdKTsgbCA9IHQ7XHJcblx0XHQgIHQgPSByOyByID0gbF5mMihyLCB0aGlzLm1hc2tpbmdbMV0sIHRoaXMucm90YXRlWzFdKTsgbCA9IHQ7XHJcblx0XHQgIHQgPSByOyByID0gbF5mMyhyLCB0aGlzLm1hc2tpbmdbMl0sIHRoaXMucm90YXRlWzJdKTsgbCA9IHQ7XHJcblx0XHQgIHQgPSByOyByID0gbF5mMShyLCB0aGlzLm1hc2tpbmdbM10sIHRoaXMucm90YXRlWzNdKTsgbCA9IHQ7XHJcblxyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjIociwgdGhpcy5tYXNraW5nWzRdLCB0aGlzLnJvdGF0ZVs0XSk7IGwgPSB0O1xyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjMociwgdGhpcy5tYXNraW5nWzVdLCB0aGlzLnJvdGF0ZVs1XSk7IGwgPSB0O1xyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjEociwgdGhpcy5tYXNraW5nWzZdLCB0aGlzLnJvdGF0ZVs2XSk7IGwgPSB0O1xyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjIociwgdGhpcy5tYXNraW5nWzddLCB0aGlzLnJvdGF0ZVs3XSk7IGwgPSB0O1xyXG5cclxuXHRcdCAgdCA9IHI7IHIgPSBsXmYzKHIsIHRoaXMubWFza2luZ1s4XSwgdGhpcy5yb3RhdGVbOF0pOyBsID0gdDtcclxuXHRcdCAgdCA9IHI7IHIgPSBsXmYxKHIsIHRoaXMubWFza2luZ1s5XSwgdGhpcy5yb3RhdGVbOV0pOyBsID0gdDtcclxuXHRcdCAgdCA9IHI7IHIgPSBsXmYyKHIsIHRoaXMubWFza2luZ1sxMF0sIHRoaXMucm90YXRlWzEwXSk7IGwgPSB0O1xyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjMociwgdGhpcy5tYXNraW5nWzExXSwgdGhpcy5yb3RhdGVbMTFdKTsgbCA9IHQ7XHJcblxyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjEociwgdGhpcy5tYXNraW5nWzEyXSwgdGhpcy5yb3RhdGVbMTJdKTsgbCA9IHQ7XHJcblx0XHQgIHQgPSByOyByID0gbF5mMihyLCB0aGlzLm1hc2tpbmdbMTNdLCB0aGlzLnJvdGF0ZVsxM10pOyBsID0gdDtcclxuXHRcdCAgdCA9IHI7IHIgPSBsXmYzKHIsIHRoaXMubWFza2luZ1sxNF0sIHRoaXMucm90YXRlWzE0XSk7IGwgPSB0O1xyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjEociwgdGhpcy5tYXNraW5nWzE1XSwgdGhpcy5yb3RhdGVbMTVdKTsgbCA9IHQ7XHJcblxyXG5cdFx0ICBkc3RbaV0gICA9IChyID4+PiAyNCkmMjU1O1xyXG5cdFx0ICBkc3RbaSsxXSA9IChyID4+PiAxNikmMjU1O1xyXG5cdFx0ICBkc3RbaSsyXSA9IChyID4+PiA4KSYyNTU7XHJcblx0XHQgIGRzdFtpKzNdID0gciYyNTU7XHJcblx0XHQgIGRzdFtpKzRdID0gKGwgPj4+IDI0KSYyNTU7XHJcblx0XHQgIGRzdFtpKzVdID0gKGwgPj4+IDE2KSYyNTU7XHJcblx0XHQgIGRzdFtpKzZdID0gKGwgPj4+IDgpJjI1NTtcclxuXHRcdCAgZHN0W2krN10gPSBsJjI1NTtcclxuXHRcdCB9XHJcblxyXG5cdFx0IHJldHVybiBkc3Q7XHJcblx0fTtcclxuXHRcclxuXHR0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihzcmMpIHtcclxuXHRcdCB2YXIgZHN0ID0gbmV3IEFycmF5KHNyYy5sZW5ndGgpO1xyXG5cclxuXHRcdCBmb3IodmFyIGkgPSAwOyBpIDwgc3JjLmxlbmd0aDsgaSs9OClcclxuXHRcdCB7XHJcblx0XHQgIHZhciBsID0gc3JjW2ldPDwyNCB8IHNyY1tpKzFdPDwxNiB8IHNyY1tpKzJdPDw4IHwgc3JjW2krM107XHJcblx0XHQgIHZhciByID0gc3JjW2krNF08PDI0IHwgc3JjW2krNV08PDE2IHwgc3JjW2krNl08PDggfCBzcmNbaSs3XTtcclxuXHRcdCAgdmFyIHQ7XHJcblxyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjEociwgdGhpcy5tYXNraW5nWzE1XSwgdGhpcy5yb3RhdGVbMTVdKTsgbCA9IHQ7XHJcblx0XHQgIHQgPSByOyByID0gbF5mMyhyLCB0aGlzLm1hc2tpbmdbMTRdLCB0aGlzLnJvdGF0ZVsxNF0pOyBsID0gdDtcclxuXHRcdCAgdCA9IHI7IHIgPSBsXmYyKHIsIHRoaXMubWFza2luZ1sxM10sIHRoaXMucm90YXRlWzEzXSk7IGwgPSB0O1xyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjEociwgdGhpcy5tYXNraW5nWzEyXSwgdGhpcy5yb3RhdGVbMTJdKTsgbCA9IHQ7XHJcblxyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjMociwgdGhpcy5tYXNraW5nWzExXSwgdGhpcy5yb3RhdGVbMTFdKTsgbCA9IHQ7XHJcblx0XHQgIHQgPSByOyByID0gbF5mMihyLCB0aGlzLm1hc2tpbmdbMTBdLCB0aGlzLnJvdGF0ZVsxMF0pOyBsID0gdDtcclxuXHRcdCAgdCA9IHI7IHIgPSBsXmYxKHIsIHRoaXMubWFza2luZ1s5XSwgdGhpcy5yb3RhdGVbOV0pOyBsID0gdDtcclxuXHRcdCAgdCA9IHI7IHIgPSBsXmYzKHIsIHRoaXMubWFza2luZ1s4XSwgdGhpcy5yb3RhdGVbOF0pOyBsID0gdDtcclxuXHJcblx0XHQgIHQgPSByOyByID0gbF5mMihyLCB0aGlzLm1hc2tpbmdbN10sIHRoaXMucm90YXRlWzddKTsgbCA9IHQ7XHJcblx0XHQgIHQgPSByOyByID0gbF5mMShyLCB0aGlzLm1hc2tpbmdbNl0sIHRoaXMucm90YXRlWzZdKTsgbCA9IHQ7XHJcblx0XHQgIHQgPSByOyByID0gbF5mMyhyLCB0aGlzLm1hc2tpbmdbNV0sIHRoaXMucm90YXRlWzVdKTsgbCA9IHQ7XHJcblx0XHQgIHQgPSByOyByID0gbF5mMihyLCB0aGlzLm1hc2tpbmdbNF0sIHRoaXMucm90YXRlWzRdKTsgbCA9IHQ7XHJcblxyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjEociwgdGhpcy5tYXNraW5nWzNdLCB0aGlzLnJvdGF0ZVszXSk7IGwgPSB0O1xyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjMociwgdGhpcy5tYXNraW5nWzJdLCB0aGlzLnJvdGF0ZVsyXSk7IGwgPSB0O1xyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjIociwgdGhpcy5tYXNraW5nWzFdLCB0aGlzLnJvdGF0ZVsxXSk7IGwgPSB0O1xyXG5cdFx0ICB0ID0gcjsgciA9IGxeZjEociwgdGhpcy5tYXNraW5nWzBdLCB0aGlzLnJvdGF0ZVswXSk7IGwgPSB0O1xyXG5cclxuXHRcdCAgZHN0W2ldICAgPSAociA+Pj4gMjQpJjI1NTtcclxuXHRcdCAgZHN0W2krMV0gPSAociA+Pj4gMTYpJjI1NTtcclxuXHRcdCAgZHN0W2krMl0gPSAociA+Pj4gOCkmMjU1O1xyXG5cdFx0ICBkc3RbaSszXSA9IHImMjU1O1xyXG5cdFx0ICBkc3RbaSs0XSA9IChsID4+PiAyNCkmMjU1O1xyXG5cdFx0ICBkc3RbaSs1XSA9IChsID4+IDE2KSYyNTU7XHJcblx0XHQgIGRzdFtpKzZdID0gKGwgPj4gOCkmMjU1O1xyXG5cdFx0ICBkc3RbaSs3XSA9IGwmMjU1O1xyXG5cdFx0IH1cclxuXHJcblx0XHQgcmV0dXJuIGRzdDtcclxuXHRcdH07XHJcblx0XHR2YXIgc2NoZWR1bGVBID0gbmV3IEFycmF5KDQpO1xyXG5cclxuXHRcdHNjaGVkdWxlQVswXSA9IG5ldyBBcnJheSg0KTtcclxuXHRcdHNjaGVkdWxlQVswXVswXSA9IG5ldyBBcnJheSg0LCAwLCAweGQsIDB4ZiwgMHhjLCAweGUsIDB4OCk7XHJcblx0XHRzY2hlZHVsZUFbMF1bMV0gPSBuZXcgQXJyYXkoNSwgMiwgMTYgKyAwLCAxNiArIDIsIDE2ICsgMSwgMTYgKyAzLCAweGEpO1xyXG5cdFx0c2NoZWR1bGVBWzBdWzJdID0gbmV3IEFycmF5KDYsIDMsIDE2ICsgNywgMTYgKyA2LCAxNiArIDUsIDE2ICsgNCwgOSk7XHJcblx0XHRzY2hlZHVsZUFbMF1bM10gPSBuZXcgQXJyYXkoNywgMSwgMTYgKyAweGEsIDE2ICsgOSwgMTYgKyAweGIsIDE2ICsgOCwgMHhiKTtcclxuXHJcblx0XHRzY2hlZHVsZUFbMV0gPSBuZXcgQXJyYXkoNCk7XHJcblx0XHRzY2hlZHVsZUFbMV1bMF0gPSBuZXcgQXJyYXkoMCwgNiwgMTYgKyA1LCAxNiArIDcsIDE2ICsgNCwgMTYgKyA2LCAxNiArIDApO1xyXG5cdFx0c2NoZWR1bGVBWzFdWzFdID0gbmV3IEFycmF5KDEsIDQsIDAsIDIsIDEsIDMsIDE2ICsgMik7XHJcblx0XHRzY2hlZHVsZUFbMV1bMl0gPSBuZXcgQXJyYXkoMiwgNSwgNywgNiwgNSwgNCwgMTYgKyAxKTtcclxuXHRcdHNjaGVkdWxlQVsxXVszXSA9IG5ldyBBcnJheSgzLCA3LCAweGEsIDksIDB4YiwgOCwgMTYgKyAzKTtcclxuXHJcblx0XHRzY2hlZHVsZUFbMl0gPSBuZXcgQXJyYXkoNCk7XHJcblx0XHRzY2hlZHVsZUFbMl1bMF0gPSBuZXcgQXJyYXkoNCwgMCwgMHhkLCAweGYsIDB4YywgMHhlLCA4KTtcclxuXHRcdHNjaGVkdWxlQVsyXVsxXSA9IG5ldyBBcnJheSg1LCAyLCAxNiArIDAsIDE2ICsgMiwgMTYgKyAxLCAxNiArIDMsIDB4YSk7XHJcblx0XHRzY2hlZHVsZUFbMl1bMl0gPSBuZXcgQXJyYXkoNiwgMywgMTYgKyA3LCAxNiArIDYsIDE2ICsgNSwgMTYgKyA0LCA5KTtcclxuXHRcdHNjaGVkdWxlQVsyXVszXSA9IG5ldyBBcnJheSg3LCAxLCAxNiArIDB4YSwgMTYgKyA5LCAxNiArIDB4YiwgMTYgKyA4LCAweGIpO1xyXG5cclxuXHJcblx0XHRzY2hlZHVsZUFbM10gPSBuZXcgQXJyYXkoNCk7XHJcblx0XHRzY2hlZHVsZUFbM11bMF0gPSBuZXcgQXJyYXkoMCwgNiwgMTYgKyA1LCAxNiArIDcsIDE2ICsgNCwgMTYgKyA2LCAxNiArIDApO1xyXG5cdFx0c2NoZWR1bGVBWzNdWzFdID0gbmV3IEFycmF5KDEsIDQsIDAsIDIsIDEsIDMsIDE2ICsgMik7XHJcblx0XHRzY2hlZHVsZUFbM11bMl0gPSBuZXcgQXJyYXkoMiwgNSwgNywgNiwgNSwgNCwgMTYgKyAxKTtcclxuXHRcdHNjaGVkdWxlQVszXVszXSA9IG5ldyBBcnJheSgzLCA3LCAweGEsIDksIDB4YiwgOCwgMTYgKyAzKTtcclxuXHJcblx0XHR2YXIgc2NoZWR1bGVCID0gbmV3IEFycmF5KDQpO1xyXG5cclxuXHRcdHNjaGVkdWxlQlswXSA9IG5ldyBBcnJheSg0KTtcclxuXHRcdHNjaGVkdWxlQlswXVswXSA9IG5ldyBBcnJheSgxNiArIDgsIDE2ICsgOSwgMTYgKyA3LCAxNiArIDYsIDE2ICsgMik7XHJcblx0XHRzY2hlZHVsZUJbMF1bMV0gPSBuZXcgQXJyYXkoMTYgKyAweGEsIDE2ICsgMHhiLCAxNiArIDUsIDE2ICsgNCwgMTYgKyA2KTtcclxuXHRcdHNjaGVkdWxlQlswXVsyXSA9IG5ldyBBcnJheSgxNiArIDB4YywgMTYgKyAweGQsIDE2ICsgMywgMTYgKyAyLCAxNiArIDkpO1xyXG5cdFx0c2NoZWR1bGVCWzBdWzNdID0gbmV3IEFycmF5KDE2ICsgMHhlLCAxNiArIDB4ZiwgMTYgKyAxLCAxNiArIDAsIDE2ICsgMHhjKTtcclxuXHJcblx0XHRzY2hlZHVsZUJbMV0gPSBuZXcgQXJyYXkoNCk7XHJcblx0XHRzY2hlZHVsZUJbMV1bMF0gPSBuZXcgQXJyYXkoMywgMiwgMHhjLCAweGQsIDgpO1xyXG5cdFx0c2NoZWR1bGVCWzFdWzFdID0gbmV3IEFycmF5KDEsIDAsIDB4ZSwgMHhmLCAweGQpO1xyXG5cdFx0c2NoZWR1bGVCWzFdWzJdID0gbmV3IEFycmF5KDcsIDYsIDgsIDksIDMpO1xyXG5cdFx0c2NoZWR1bGVCWzFdWzNdID0gbmV3IEFycmF5KDUsIDQsIDB4YSwgMHhiLCA3KTtcclxuXHJcblxyXG5cdFx0c2NoZWR1bGVCWzJdID0gbmV3IEFycmF5KDQpO1xyXG5cdFx0c2NoZWR1bGVCWzJdWzBdID0gbmV3IEFycmF5KDE2ICsgMywgMTYgKyAyLCAxNiArIDB4YywgMTYgKyAweGQsIDE2ICsgOSk7XHJcblx0XHRzY2hlZHVsZUJbMl1bMV0gPSBuZXcgQXJyYXkoMTYgKyAxLCAxNiArIDAsIDE2ICsgMHhlLCAxNiArIDB4ZiwgMTYgKyAweGMpO1xyXG5cdFx0c2NoZWR1bGVCWzJdWzJdID0gbmV3IEFycmF5KDE2ICsgNywgMTYgKyA2LCAxNiArIDgsIDE2ICsgOSwgMTYgKyAyKTtcclxuXHRcdHNjaGVkdWxlQlsyXVszXSA9IG5ldyBBcnJheSgxNiArIDUsIDE2ICsgNCwgMTYgKyAweGEsIDE2ICsgMHhiLCAxNiArIDYpO1xyXG5cclxuXHJcblx0XHRzY2hlZHVsZUJbM10gPSBuZXcgQXJyYXkoNCk7XHJcblx0XHRzY2hlZHVsZUJbM11bMF0gPSBuZXcgQXJyYXkoOCwgOSwgNywgNiwgMyk7XHJcblx0XHRzY2hlZHVsZUJbM11bMV0gPSBuZXcgQXJyYXkoMHhhLCAweGIsIDUsIDQsIDcpO1xyXG5cdFx0c2NoZWR1bGVCWzNdWzJdID0gbmV3IEFycmF5KDB4YywgMHhkLCAzLCAyLCA4KTtcclxuXHRcdHNjaGVkdWxlQlszXVszXSA9IG5ldyBBcnJheSgweGUsIDB4ZiwgMSwgMCwgMHhkKTtcclxuXHJcblx0XHQvLyBjaGFuZ2VkICdpbicgdG8gJ2lubicgKGluIGphdmFzY3JpcHQgJ2luJyBpcyBhIHJlc2VydmVkIHdvcmQpXHJcblx0XHR0aGlzLmtleVNjaGVkdWxlID0gZnVuY3Rpb24oaW5uKVxyXG5cdFx0e1xyXG5cdFx0IHZhciB0ID0gbmV3IEFycmF5KDgpO1xyXG5cdFx0IHZhciBrID0gbmV3IEFycmF5KDMyKTtcclxuXHJcblx0XHQgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspXHJcblx0XHQge1xyXG5cdFx0ICB2YXIgaiA9IGkgKiA0O1xyXG5cdFx0ICB0W2ldID0gaW5uW2pdPDwyNCB8IGlubltqKzFdPDwxNiB8IGlubltqKzJdPDw4IHwgaW5uW2orM107XHJcblx0XHQgfVxyXG5cclxuXHRcdCB2YXIgeCA9IFs2LCA3LCA0LCA1XTtcclxuXHRcdCB2YXIga2kgPSAwO1xyXG5cclxuXHRcdCBmb3IgKHZhciBoYWxmID0gMDsgaGFsZiA8IDI7IGhhbGYrKylcclxuXHRcdCB7XHJcblx0XHQgIGZvciAodmFyIHJvdW5kID0gMDsgcm91bmQgPCA0OyByb3VuZCsrKVxyXG5cdFx0ICB7XHJcblx0XHQgICBmb3IgKHZhciBqID0gMDsgaiA8IDQ7IGorKylcclxuXHRcdCAgIHtcclxuXHRcdCAgICB2YXIgYSA9IHNjaGVkdWxlQVtyb3VuZF1bal07XHJcblx0XHQgICAgdmFyIHcgPSB0W2FbMV1dO1xyXG5cclxuXHRcdCAgICB3IF49IHNCb3hbNF1bKHRbYVsyXT4+PjJdPj4+KDI0LTgqKGFbMl0mMykpKSYweGZmXTtcclxuXHRcdCAgICB3IF49IHNCb3hbNV1bKHRbYVszXT4+PjJdPj4+KDI0LTgqKGFbM10mMykpKSYweGZmXTtcclxuXHRcdCAgICB3IF49IHNCb3hbNl1bKHRbYVs0XT4+PjJdPj4+KDI0LTgqKGFbNF0mMykpKSYweGZmXTtcclxuXHRcdCAgICB3IF49IHNCb3hbN11bKHRbYVs1XT4+PjJdPj4+KDI0LTgqKGFbNV0mMykpKSYweGZmXTtcclxuXHRcdCAgICB3IF49IHNCb3hbeFtqXV1bKHRbYVs2XT4+PjJdPj4+KDI0LTgqKGFbNl0mMykpKSYweGZmXTtcclxuXHRcdCAgICB0W2FbMF1dID0gdztcclxuXHRcdCAgIH1cclxuXHJcblx0XHQgICBmb3IgKHZhciBqID0gMDsgaiA8IDQ7IGorKylcclxuXHRcdCAgIHtcclxuXHRcdCAgICB2YXIgYiA9IHNjaGVkdWxlQltyb3VuZF1bal07XHJcblx0XHQgICAgdmFyIHcgPSBzQm94WzRdWyh0W2JbMF0+Pj4yXT4+PigyNC04KihiWzBdJjMpKSkmMHhmZl07XHJcblxyXG5cdFx0ICAgIHcgXj0gc0JveFs1XVsodFtiWzFdPj4+Ml0+Pj4oMjQtOCooYlsxXSYzKSkpJjB4ZmZdO1xyXG5cdFx0ICAgIHcgXj0gc0JveFs2XVsodFtiWzJdPj4+Ml0+Pj4oMjQtOCooYlsyXSYzKSkpJjB4ZmZdO1xyXG5cdFx0ICAgIHcgXj0gc0JveFs3XVsodFtiWzNdPj4+Ml0+Pj4oMjQtOCooYlszXSYzKSkpJjB4ZmZdO1xyXG5cdFx0ICAgIHcgXj0gc0JveFs0K2pdWyh0W2JbNF0+Pj4yXT4+PigyNC04KihiWzRdJjMpKSkmMHhmZl07XHJcblx0XHQgICAga1traV0gPSB3O1xyXG5cdFx0ICAgIGtpKys7XHJcblx0XHQgICB9XHJcblx0XHQgIH1cclxuXHRcdCB9XHJcblxyXG5cdFx0IGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKylcclxuXHRcdCB7XHJcblx0XHQgIHRoaXMubWFza2luZ1tpXSA9IGtbaV07XHJcblx0XHQgIHRoaXMucm90YXRlW2ldICA9IGtbMTYraV0gJiAweDFmO1xyXG5cdFx0IH1cclxuXHRcdH07XHJcblxyXG5cdFx0Ly8gVGhlc2UgYXJlIHRoZSB0aHJlZSAnZicgZnVuY3Rpb25zLiBTZWUgUkZDIDIxNDQsIHNlY3Rpb24gMi4yLlxyXG5cclxuXHRcdGZ1bmN0aW9uIGYxKGQsIG0sIHIpXHJcblx0XHR7XHJcblx0XHQgdmFyIHQgPSBtICsgZDtcclxuXHRcdCB2YXIgSSA9ICh0IDw8IHIpIHwgKHQgPj4+ICgzMiAtIHIpKTtcclxuXHRcdCByZXR1cm4gKChzQm94WzBdW0k+Pj4yNF0gXiBzQm94WzFdWyhJPj4+MTYpJjI1NV0pIC0gc0JveFsyXVsoST4+PjgpJjI1NV0pICsgc0JveFszXVtJJjI1NV07XHJcblx0XHR9XHJcblxyXG5cdFx0ZnVuY3Rpb24gZjIoZCwgbSwgcilcclxuXHRcdHtcclxuXHRcdCB2YXIgdCA9IG0gXiBkO1xyXG5cdFx0IHZhciBJID0gKHQgPDwgcikgfCAodCA+Pj4gKDMyIC0gcikpO1xyXG5cdFx0IHJldHVybiAoKHNCb3hbMF1bST4+PjI0XSAtIHNCb3hbMV1bKEk+Pj4xNikmMjU1XSkgKyBzQm94WzJdWyhJPj4+OCkmMjU1XSkgXiBzQm94WzNdW0kmMjU1XTtcclxuXHRcdH1cclxuXHJcblx0XHRmdW5jdGlvbiBmMyhkLCBtLCByKVxyXG5cdFx0e1xyXG5cdFx0IHZhciB0ID0gbSAtIGQ7XHJcblx0XHQgdmFyIEkgPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7XHJcblx0XHQgcmV0dXJuICgoc0JveFswXVtJPj4+MjRdICsgc0JveFsxXVsoST4+PjE2KSYyNTVdKSBeIHNCb3hbMl1bKEk+Pj44KSYyNTVdKSAtIHNCb3hbM11bSSYyNTVdO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBzQm94ID0gbmV3IEFycmF5KDgpO1xyXG5cdFx0c0JveFswXSA9IG5ldyBBcnJheShcclxuXHRcdCAgMHgzMGZiNDBkNCwgMHg5ZmEwZmYwYiwgMHg2YmVjY2QyZiwgMHgzZjI1OGM3YSwgMHgxZTIxM2YyZiwgMHg5YzAwNGRkMywgMHg2MDAzZTU0MCwgMHhjZjlmYzk0OSxcclxuXHRcdCAgMHhiZmQ0YWYyNywgMHg4OGJiYmRiNSwgMHhlMjAzNDA5MCwgMHg5OGQwOTY3NSwgMHg2ZTYzYTBlMCwgMHgxNWMzNjFkMiwgMHhjMmU3NjYxZCwgMHgyMmQ0ZmY4ZSxcclxuXHRcdCAgMHgyODY4M2I2ZiwgMHhjMDdmZDA1OSwgMHhmZjIzNzljOCwgMHg3NzVmNTBlMiwgMHg0M2MzNDBkMywgMHhkZjJmODY1NiwgMHg4ODdjYTQxYSwgMHhhMmQyYmQyZCxcclxuXHRcdCAgMHhhMWM5ZTBkNiwgMHgzNDZjNDgxOSwgMHg2MWI3NmQ4NywgMHgyMjU0MGYyZiwgMHgyYWJlMzJlMSwgMHhhYTU0MTY2YiwgMHgyMjU2OGUzYSwgMHhhMmQzNDFkMCxcclxuXHRcdCAgMHg2NmRiNDBjOCwgMHhhNzg0MzkyZiwgMHgwMDRkZmYyZiwgMHgyZGI5ZDJkZSwgMHg5Nzk0M2ZhYywgMHg0YTk3YzFkOCwgMHg1Mjc2NDRiNywgMHhiNWY0MzdhNyxcclxuXHRcdCAgMHhiODJjYmFlZiwgMHhkNzUxZDE1OSwgMHg2ZmY3ZjBlZCwgMHg1YTA5N2ExZiwgMHg4MjdiNjhkMCwgMHg5MGVjZjUyZSwgMHgyMmIwYzA1NCwgMHhiYzhlNTkzNSxcclxuXHRcdCAgMHg0YjZkMmY3ZiwgMHg1MGJiNjRhMiwgMHhkMjY2NDkxMCwgMHhiZWU1ODEyZCwgMHhiNzMzMjI5MCwgMHhlOTNiMTU5ZiwgMHhiNDhlZTQxMSwgMHg0YmZmMzQ1ZCxcclxuXHRcdCAgMHhmZDQ1YzI0MCwgMHhhZDMxOTczZiwgMHhjNGY2ZDAyZSwgMHg1NWZjODE2NSwgMHhkNWIxY2FhZCwgMHhhMWFjMmRhZSwgMHhhMmQ0Yjc2ZCwgMHhjMTliMGM1MCxcclxuXHRcdCAgMHg4ODIyNDBmMiwgMHgwYzZlNGYzOCwgMHhhNGU0YmZkNywgMHg0ZjViYTI3MiwgMHg1NjRjMWQyZiwgMHhjNTljNTMxOSwgMHhiOTQ5ZTM1NCwgMHhiMDQ2NjlmZSxcclxuXHRcdCAgMHhiMWI2YWI4YSwgMHhjNzEzNThkZCwgMHg2Mzg1YzU0NSwgMHgxMTBmOTM1ZCwgMHg1NzUzOGFkNSwgMHg2YTM5MDQ5MywgMHhlNjNkMzdlMCwgMHgyYTU0ZjZiMyxcclxuXHRcdCAgMHgzYTc4N2Q1ZiwgMHg2Mjc2YTBiNSwgMHgxOWE2ZmNkZiwgMHg3YTQyMjA2YSwgMHgyOWY5ZDRkNSwgMHhmNjFiMTg5MSwgMHhiYjcyMjc1ZSwgMHhhYTUwODE2NyxcclxuXHRcdCAgMHgzODkwMTA5MSwgMHhjNmI1MDVlYiwgMHg4NGM3Y2I4YywgMHgyYWQ3NWEwZiwgMHg4NzRhMTQyNywgMHhhMmQxOTM2YiwgMHgyYWQyODZhZiwgMHhhYTU2ZDI5MSxcclxuXHRcdCAgMHhkNzg5NDM2MCwgMHg0MjVjNzUwZCwgMHg5M2IzOWUyNiwgMHgxODcxODRjOSwgMHg2YzAwYjMyZCwgMHg3M2UyYmIxNCwgMHhhMGJlYmMzYywgMHg1NDYyMzc3OSxcclxuXHRcdCAgMHg2NDQ1OWVhYiwgMHgzZjMyOGI4MiwgMHg3NzE4Y2Y4MiwgMHg1OWEyY2VhNiwgMHgwNGVlMDAyZSwgMHg4OWZlNzhlNiwgMHgzZmFiMDk1MCwgMHgzMjVmZjZjMixcclxuXHRcdCAgMHg4MTM4M2YwNSwgMHg2OTYzYzVjOCwgMHg3NmNiNWFkNiwgMHhkNDk5NzRjOSwgMHhjYTE4MGRjZiwgMHgzODA3ODJkNSwgMHhjN2ZhNWNmNiwgMHg4YWMzMTUxMSxcclxuXHRcdCAgMHgzNWU3OWUxMywgMHg0N2RhOTFkMCwgMHhmNDBmOTA4NiwgMHhhN2UyNDE5ZSwgMHgzMTM2NjI0MSwgMHgwNTFlZjQ5NSwgMHhhYTU3M2IwNCwgMHg0YTgwNWQ4ZCxcclxuXHRcdCAgMHg1NDgzMDBkMCwgMHgwMDMyMmEzYywgMHhiZjY0Y2RkZiwgMHhiYTU3YTY4ZSwgMHg3NWM2MzcyYiwgMHg1MGFmZDM0MSwgMHhhN2MxMzI3NSwgMHg5MTVhMGJmNSxcclxuXHRcdCAgMHg2YjU0YmZhYiwgMHgyYjBiMTQyNiwgMHhhYjRjYzlkNywgMHg0NDljY2Q4MiwgMHhmN2ZiZjI2NSwgMHhhYjg1YzVmMywgMHgxYjU1ZGI5NCwgMHhhYWQ0ZTMyNCxcclxuXHRcdCAgMHhjZmE0YmQzZiwgMHgyZGVhYTNlMiwgMHg5ZTIwNGQwMiwgMHhjOGJkMjVhYywgMHhlYWRmNTViMywgMHhkNWJkOWU5OCwgMHhlMzEyMzFiMiwgMHgyYWQ1YWQ2YyxcclxuXHRcdCAgMHg5NTQzMjlkZSwgMHhhZGJlNDUyOCwgMHhkODcxMGY2OSwgMHhhYTUxYzkwZiwgMHhhYTc4NmJmNiwgMHgyMjUxM2YxZSwgMHhhYTUxYTc5YiwgMHgyYWQzNDRjYyxcclxuXHRcdCAgMHg3YjVhNDFmMCwgMHhkMzdjZmJhZCwgMHgxYjA2OTUwNSwgMHg0MWVjZTQ5MSwgMHhiNGMzMzJlNiwgMHgwMzIyNjhkNCwgMHhjOTYwMGFjYywgMHhjZTM4N2U2ZCxcclxuXHRcdCAgMHhiZjZiYjE2YywgMHg2YTcwZmI3OCwgMHgwZDAzZDljOSwgMHhkNGRmMzlkZSwgMHhlMDEwNjNkYSwgMHg0NzM2ZjQ2NCwgMHg1YWQzMjhkOCwgMHhiMzQ3Y2M5NixcclxuXHRcdCAgMHg3NWJiMGZjMywgMHg5ODUxMWJmYiwgMHg0ZmZiY2MzNSwgMHhiNThiY2Y2YSwgMHhlMTFmMGFiYywgMHhiZmM1ZmU0YSwgMHhhNzBhZWMxMCwgMHhhYzM5NTcwYSxcclxuXHRcdCAgMHgzZjA0NDQyZiwgMHg2MTg4YjE1MywgMHhlMDM5N2EyZSwgMHg1NzI3Y2I3OSwgMHg5Y2ViNDE4ZiwgMHgxY2FjZDY4ZCwgMHgyYWQzN2M5NiwgMHgwMTc1Y2I5ZCxcclxuXHRcdCAgMHhjNjlkZmYwOSwgMHhjNzViNjVmMCwgMHhkOWRiNDBkOCwgMHhlYzBlNzc3OSwgMHg0NzQ0ZWFkNCwgMHhiMTFjMzI3NCwgMHhkZDI0Y2I5ZSwgMHg3ZTFjNTRiZCxcclxuXHRcdCAgMHhmMDExNDRmOSwgMHhkMjI0MGViMSwgMHg5Njc1YjNmZCwgMHhhM2FjMzc1NSwgMHhkNDdjMjdhZiwgMHg1MWM4NWY0ZCwgMHg1NjkwNzU5NiwgMHhhNWJiMTVlNixcclxuXHRcdCAgMHg1ODAzMDRmMCwgMHhjYTA0MmNmMSwgMHgwMTFhMzdlYSwgMHg4ZGJmYWFkYiwgMHgzNWJhM2U0YSwgMHgzNTI2ZmZhMCwgMHhjMzdiNGQwOSwgMHhiYzMwNmVkOSxcclxuXHRcdCAgMHg5OGE1MjY2NiwgMHg1NjQ4ZjcyNSwgMHhmZjVlNTY5ZCwgMHgwY2VkNjNkMCwgMHg3YzYzYjJjZiwgMHg3MDBiNDVlMSwgMHhkNWVhNTBmMSwgMHg4NWE5Mjg3MixcclxuXHRcdCAgMHhhZjFmYmRhNywgMHhkNDIzNDg3MCwgMHhhNzg3MGJmMywgMHgyZDNiNGQ3OSwgMHg0MmUwNDE5OCwgMHgwY2QwZWRlNywgMHgyNjQ3MGRiOCwgMHhmODgxODE0YyxcclxuXHRcdCAgMHg0NzRkNmFkNywgMHg3YzBjNWU1YywgMHhkMTIzMTk1OSwgMHgzODFiNzI5OCwgMHhmNWQyZjRkYiwgMHhhYjgzODY1MywgMHg2ZTJmMWUyMywgMHg4MzcxOWM5ZSxcclxuXHRcdCAgMHhiZDkxZTA0NiwgMHg5YTU2NDU2ZSwgMHhkYzM5MjAwYywgMHgyMGM4YzU3MSwgMHg5NjJiZGExYywgMHhlMWU2OTZmZiwgMHhiMTQxYWIwOCwgMHg3Y2NhODliOSxcclxuXHRcdCAgMHgxYTY5ZTc4MywgMHgwMmNjNDg0MywgMHhhMmY3YzU3OSwgMHg0MjllZjQ3ZCwgMHg0MjdiMTY5YywgMHg1YWM5ZjA0OSwgMHhkZDhmMGYwMCwgMHg1YzgxNjViZik7XHJcblxyXG5cdFx0c0JveFsxXSA9IG5ldyBBcnJheShcclxuXHRcdCAgMHgxZjIwMTA5NCwgMHhlZjBiYTc1YiwgMHg2OWUzY2Y3ZSwgMHgzOTNmNDM4MCwgMHhmZTYxY2Y3YSwgMHhlZWM1MjA3YSwgMHg1NTg4OWM5NCwgMHg3MmZjMDY1MSxcclxuXHRcdCAgMHhhZGE3ZWY3OSwgMHg0ZTFkNzIzNSwgMHhkNTVhNjNjZSwgMHhkZTA0MzZiYSwgMHg5OWM0MzBlZiwgMHg1ZjBjMDc5NCwgMHgxOGRjZGI3ZCwgMHhhMWQ2ZWZmMyxcclxuXHRcdCAgMHhhMGI1MmY3YiwgMHg1OWU4MzYwNSwgMHhlZTE1YjA5NCwgMHhlOWZmZDkwOSwgMHhkYzQ0MDA4NiwgMHhlZjk0NDQ1OSwgMHhiYTgzY2NiMywgMHhlMGMzY2RmYixcclxuXHRcdCAgMHhkMWRhNDE4MSwgMHgzYjA5MmFiMSwgMHhmOTk3ZjFjMSwgMHhhNWU2Y2Y3YiwgMHgwMTQyMGRkYiwgMHhlNGU3ZWY1YiwgMHgyNWExZmY0MSwgMHhlMTgwZjgwNixcclxuXHRcdCAgMHgxZmM0MTA4MCwgMHgxNzliZWU3YSwgMHhkMzdhYzZhOSwgMHhmZTU4MzBhNCwgMHg5OGRlOGI3ZiwgMHg3N2U4M2Y0ZSwgMHg3OTkyOTI2OSwgMHgyNGZhOWY3YixcclxuXHRcdCAgMHhlMTEzYzg1YiwgMHhhY2M0MDA4MywgMHhkNzUwMzUyNSwgMHhmN2VhNjE1ZiwgMHg2MjE0MzE1NCwgMHgwZDU1NGI2MywgMHg1ZDY4MTEyMSwgMHhjODY2YzM1OSxcclxuXHRcdCAgMHgzZDYzY2Y3MywgMHhjZWUyMzRjMCwgMHhkNGQ4N2U4NywgMHg1YzY3MmIyMSwgMHgwNzFmNjE4MSwgMHgzOWY3NjI3ZiwgMHgzNjFlMzA4NCwgMHhlNGViNTczYixcclxuXHRcdCAgMHg2MDJmNjRhNCwgMHhkNjNhY2Q5YywgMHgxYmJjNDYzNSwgMHg5ZTgxMDMyZCwgMHgyNzAxZjUwYywgMHg5OTg0N2FiNCwgMHhhMGUzZGY3OSwgMHhiYTZjZjM4YyxcclxuXHRcdCAgMHgxMDg0MzA5NCwgMHgyNTM3YTk1ZSwgMHhmNDZmNmZmZSwgMHhhMWZmM2IxZiwgMHgyMDhjZmI2YSwgMHg4ZjQ1OGM3NCwgMHhkOWUwYTIyNywgMHg0ZWM3M2EzNCxcclxuXHRcdCAgMHhmYzg4NGY2OSwgMHgzZTRkZThkZiwgMHhlZjBlMDA4OCwgMHgzNTU5NjQ4ZCwgMHg4YTQ1Mzg4YywgMHgxZDgwNDM2NiwgMHg3MjFkOWJmZCwgMHhhNTg2ODRiYixcclxuXHRcdCAgMHhlODI1NjMzMywgMHg4NDRlODIxMiwgMHgxMjhkODA5OCwgMHhmZWQzM2ZiNCwgMHhjZTI4MGFlMSwgMHgyN2UxOWJhNSwgMHhkNWE2YzI1MiwgMHhlNDk3NTRiZCxcclxuXHRcdCAgMHhjNWQ2NTVkZCwgMHhlYjY2NzA2NCwgMHg3Nzg0MGI0ZCwgMHhhMWI2YTgwMSwgMHg4NGRiMjZhOSwgMHhlMGI1NjcxNCwgMHgyMWYwNDNiNywgMHhlNWQwNTg2MCxcclxuXHRcdCAgMHg1NGYwMzA4NCwgMHgwNjZmZjQ3MiwgMHhhMzFhYTE1MywgMHhkYWRjNDc1NSwgMHhiNTYyNWRiZiwgMHg2ODU2MWJlNiwgMHg4M2NhNmI5NCwgMHgyZDZlZDIzYixcclxuXHRcdCAgMHhlY2NmMDFkYiwgMHhhNmQzZDBiYSwgMHhiNjgwM2Q1YywgMHhhZjc3YTcwOSwgMHgzM2I0YTM0YywgMHgzOTdiYzhkNiwgMHg1ZWUyMmI5NSwgMHg1ZjBlNTMwNCxcclxuXHRcdCAgMHg4MWVkNmY2MSwgMHgyMGU3NDM2NCwgMHhiNDVlMTM3OCwgMHhkZTE4NjM5YiwgMHg4ODFjYTEyMiwgMHhiOTY3MjZkMSwgMHg4MDQ5YTdlOCwgMHgyMmI3ZGE3YixcclxuXHRcdCAgMHg1ZTU1MmQyNSwgMHg1MjcyZDIzNywgMHg3OWQyOTUxYywgMHhjNjBkODk0YywgMHg0ODhjYjQwMiwgMHgxYmE0ZmU1YiwgMHhhNGIwOWY2YiwgMHgxY2E4MTVjZixcclxuXHRcdCAgMHhhMjBjMzAwNSwgMHg4ODcxZGY2MywgMHhiOWRlMmZjYiwgMHgwY2M2YzllOSwgMHgwYmVlZmY1MywgMHhlMzIxNDUxNywgMHhiNDU0MjgzNSwgMHg5ZjYzMjkzYyxcclxuXHRcdCAgMHhlZTQxZTcyOSwgMHg2ZTFkMmQ3YywgMHg1MDA0NTI4NiwgMHgxZTY2ODVmMywgMHhmMzM0MDFjNiwgMHgzMGEyMmM5NSwgMHgzMWE3MDg1MCwgMHg2MDkzMGYxMyxcclxuXHRcdCAgMHg3M2Y5ODQxNywgMHhhMTI2OTg1OSwgMHhlYzY0NWM0NCwgMHg1MmM4NzdhOSwgMHhjZGZmMzNhNiwgMHhhMDJiMTc0MSwgMHg3Y2JhZDlhMiwgMHgyMTgwMDM2ZixcclxuXHRcdCAgMHg1MGQ5OWMwOCwgMHhjYjNmNDg2MSwgMHhjMjZiZDc2NSwgMHg2NGEzZjZhYiwgMHg4MDM0MjY3NiwgMHgyNWE3NWU3YiwgMHhlNGU2ZDFmYywgMHgyMGM3MTBlNixcclxuXHRcdCAgMHhjZGYwYjY4MCwgMHgxNzg0NGQzYiwgMHgzMWVlZjg0ZCwgMHg3ZTA4MjRlNCwgMHgyY2NiNDllYiwgMHg4NDZhM2JhZSwgMHg4ZmY3Nzg4OCwgMHhlZTVkNjBmNixcclxuXHRcdCAgMHg3YWY3NTY3MywgMHgyZmRkNWNkYiwgMHhhMTE2MzFjMSwgMHgzMGY2NmY0MywgMHhiM2ZhZWM1NCwgMHgxNTdmZDdmYSwgMHhlZjg1NzljYywgMHhkMTUyZGU1OCxcclxuXHRcdCAgMHhkYjJmZmQ1ZSwgMHg4ZjMyY2UxOSwgMHgzMDZhZjk3YSwgMHgwMmYwM2VmOCwgMHg5OTMxOWFkNSwgMHhjMjQyZmEwZiwgMHhhN2UzZWJiMCwgMHhjNjhlNDkwNixcclxuXHRcdCAgMHhiOGRhMjMwYywgMHg4MDgyMzAyOCwgMHhkY2RlZjNjOCwgMHhkMzVmYjE3MSwgMHgwODhhMWJjOCwgMHhiZWMwYzU2MCwgMHg2MWEzYzllOCwgMHhiY2E4ZjU0ZCxcclxuXHRcdCAgMHhjNzJmZWZmYSwgMHgyMjgyMmU5OSwgMHg4MmM1NzBiNCwgMHhkOGQ5NGU4OSwgMHg4YjFjMzRiYywgMHgzMDFlMTZlNiwgMHgyNzNiZTk3OSwgMHhiMGZmZWFhNixcclxuXHRcdCAgMHg2MWQ5YjhjNiwgMHgwMGIyNDg2OSwgMHhiN2ZmY2UzZiwgMHgwOGRjMjgzYiwgMHg0M2RhZjY1YSwgMHhmN2UxOTc5OCwgMHg3NjE5YjcyZiwgMHg4ZjFjOWJhNCxcclxuXHRcdCAgMHhkYzg2MzdhMCwgMHgxNmE3ZDNiMSwgMHg5ZmMzOTNiNywgMHhhNzEzNmVlYiwgMHhjNmJjYzYzZSwgMHgxYTUxMzc0MiwgMHhlZjY4MjhiYywgMHg1MjAzNjVkNixcclxuXHRcdCAgMHgyZDZhNzdhYiwgMHgzNTI3ZWQ0YiwgMHg4MjFmZDIxNiwgMHgwOTVjNmUyZSwgMHhkYjkyZjJmYiwgMHg1ZWVhMjljYiwgMHgxNDU4OTJmNSwgMHg5MTU4NGY3ZixcclxuXHRcdCAgMHg1NDgzNjk3YiwgMHgyNjY3YThjYywgMHg4NTE5NjA0OCwgMHg4YzRiYWNlYSwgMHg4MzM4NjBkNCwgMHgwZDIzZTBmOSwgMHg2YzM4N2U4YSwgMHgwYWU2ZDI0OSxcclxuXHRcdCAgMHhiMjg0NjAwYywgMHhkODM1NzMxZCwgMHhkY2IxYzY0NywgMHhhYzRjNTZlYSwgMHgzZWJkODFiMywgMHgyMzBlYWJiMCwgMHg2NDM4YmM4NywgMHhmMGI1YjFmYSxcclxuXHRcdCAgMHg4ZjVlYTJiMywgMHhmYzE4NDY0MiwgMHgwYTAzNmI3YSwgMHg0ZmIwODliZCwgMHg2NDlkYTU4OSwgMHhhMzQ1NDE1ZSwgMHg1YzAzODMyMywgMHgzZTVkM2JiOSxcclxuXHRcdCAgMHg0M2Q3OTU3MiwgMHg3ZTZkZDA3YywgMHgwNmRmZGYxZSwgMHg2YzZjYzRlZiwgMHg3MTYwYTUzOSwgMHg3M2JmYmU3MCwgMHg4Mzg3NzYwNSwgMHg0NTIzZWNmMSk7XHJcblxyXG5cdFx0c0JveFsyXSA9IG5ldyBBcnJheShcclxuXHRcdCAgMHg4ZGVmYzI0MCwgMHgyNWZhNWQ5ZiwgMHhlYjkwM2RiZiwgMHhlODEwYzkwNywgMHg0NzYwN2ZmZiwgMHgzNjlmZTQ0YiwgMHg4YzFmYzY0NCwgMHhhZWNlY2E5MCxcclxuXHRcdCAgMHhiZWIxZjliZiwgMHhlZWZiY2FlYSwgMHhlOGNmMTk1MCwgMHg1MWRmMDdhZSwgMHg5MjBlODgwNiwgMHhmMGFkMDU0OCwgMHhlMTNjOGQ4MywgMHg5MjcwMTBkNSxcclxuXHRcdCAgMHgxMTEwN2Q5ZiwgMHgwNzY0N2RiOSwgMHhiMmUzZTRkNCwgMHgzZDRmMjg1ZSwgMHhiOWFmYTgyMCwgMHhmYWRlODJlMCwgMHhhMDY3MjY4YiwgMHg4MjcyNzkyZSxcclxuXHRcdCAgMHg1NTNmYjJjMCwgMHg0ODlhZTIyYiwgMHhkNGVmOTc5NCwgMHgxMjVlM2ZiYywgMHgyMWZmZmNlZSwgMHg4MjViMWJmZCwgMHg5MjU1YzVlZCwgMHgxMjU3YTI0MCxcclxuXHRcdCAgMHg0ZTFhODMwMiwgMHhiYWUwN2ZmZiwgMHg1MjgyNDZlNywgMHg4ZTU3MTQwZSwgMHgzMzczZjdiZiwgMHg4YzlmODE4OCwgMHhhNmZjNGVlOCwgMHhjOTgyYjVhNSxcclxuXHRcdCAgMHhhOGMwMWRiNywgMHg1NzlmYzI2NCwgMHg2NzA5NGYzMSwgMHhmMmJkM2Y1ZiwgMHg0MGZmZjdjMSwgMHgxZmI3OGRmYywgMHg4ZTZiZDJjMSwgMHg0MzdiZTU5YixcclxuXHRcdCAgMHg5OWIwM2RiZiwgMHhiNWRiYzY0YiwgMHg2MzhkYzBlNiwgMHg1NTgxOWQ5OSwgMHhhMTk3YzgxYywgMHg0YTAxMmQ2ZSwgMHhjNTg4NGEyOCwgMHhjY2MzNmY3MSxcclxuXHRcdCAgMHhiODQzYzIxMywgMHg2YzA3NDNmMSwgMHg4MzA5ODkzYywgMHgwZmVkZGQ1ZiwgMHgyZjdmZTg1MCwgMHhkN2MwN2Y3ZSwgMHgwMjUwN2ZiZiwgMHg1YWZiOWEwNCxcclxuXHRcdCAgMHhhNzQ3ZDJkMCwgMHgxNjUxMTkyZSwgMHhhZjcwYmYzZSwgMHg1OGMzMTM4MCwgMHg1Zjk4MzAyZSwgMHg3MjdjYzNjNCwgMHgwYTBmYjQwMiwgMHgwZjdmZWY4MixcclxuXHRcdCAgMHg4Yzk2ZmRhZCwgMHg1ZDJjMmFhZSwgMHg4ZWU5OWE0OSwgMHg1MGRhODhiOCwgMHg4NDI3ZjRhMCwgMHgxZWFjNTc5MCwgMHg3OTZmYjQ0OSwgMHg4MjUyZGMxNSxcclxuXHRcdCAgMHhlZmJkN2Q5YiwgMHhhNjcyNTk3ZCwgMHhhZGE4NDBkOCwgMHg0NWY1NDUwNCwgMHhmYTVkNzQwMywgMHhlODNlYzMwNSwgMHg0ZjkxNzUxYSwgMHg5MjU2NjljMixcclxuXHRcdCAgMHgyM2VmZTk0MSwgMHhhOTAzZjEyZSwgMHg2MDI3MGRmMiwgMHgwMjc2ZTRiNiwgMHg5NGZkNjU3NCwgMHg5Mjc5ODViMiwgMHg4Mjc2ZGJjYiwgMHgwMjc3ODE3NixcclxuXHRcdCAgMHhmOGFmOTE4ZCwgMHg0ZTQ4Zjc5ZSwgMHg4ZjYxNmRkZiwgMHhlMjlkODQwZSwgMHg4NDJmN2Q4MywgMHgzNDBjZTVjOCwgMHg5NmJiYjY4MiwgMHg5M2I0YjE0OCxcclxuXHRcdCAgMHhlZjMwM2NhYiwgMHg5ODRmYWYyOCwgMHg3NzlmYWY5YiwgMHg5MmRjNTYwZCwgMHgyMjRkMWUyMCwgMHg4NDM3YWE4OCwgMHg3ZDI5ZGM5NiwgMHgyNzU2ZDNkYyxcclxuXHRcdCAgMHg4YjkwN2NlZSwgMHhiNTFmZDI0MCwgMHhlN2MwN2NlMywgMHhlNTY2YjRhMSwgMHhjM2U5NjE1ZSwgMHgzY2Y4MjA5ZCwgMHg2MDk0ZDFlMywgMHhjZDljYTM0MSxcclxuXHRcdCAgMHg1Yzc2NDYwZSwgMHgwMGVhOTgzYiwgMHhkNGQ2Nzg4MSwgMHhmZDQ3NTcyYywgMHhmNzZjZWRkOSwgMHhiZGE4MjI5YywgMHgxMjdkYWRhYSwgMHg0MzhhMDc0ZSxcclxuXHRcdCAgMHgxZjk3YzA5MCwgMHgwODFiZGI4YSwgMHg5M2EwN2ViZSwgMHhiOTM4Y2ExNSwgMHg5N2IwM2NmZiwgMHgzZGMyYzBmOCwgMHg4ZDFhYjJlYywgMHg2NDM4MGU1MSxcclxuXHRcdCAgMHg2OGNjN2JmYiwgMHhkOTBmMjc4OCwgMHgxMjQ5MDE4MSwgMHg1ZGU1ZmZkNCwgMHhkZDdlZjg2YSwgMHg3NmEyZTIxNCwgMHhiOWE0MDM2OCwgMHg5MjVkOTU4ZixcclxuXHRcdCAgMHg0YjM5ZmZmYSwgMHhiYTM5YWVlOSwgMHhhNGZmZDMwYiwgMHhmYWY3OTMzYiwgMHg2ZDQ5ODYyMywgMHgxOTNjYmNmYSwgMHgyNzYyNzU0NSwgMHg4MjVjZjQ3YSxcclxuXHRcdCAgMHg2MWJkOGJhMCwgMHhkMTFlNDJkMSwgMHhjZWFkMDRmNCwgMHgxMjdlYTM5MiwgMHgxMDQyOGRiNywgMHg4MjcyYTk3MiwgMHg5MjcwYzRhOCwgMHgxMjdkZTUwYixcclxuXHRcdCAgMHgyODViYTFjOCwgMHgzYzYyZjQ0ZiwgMHgzNWMwZWFhNSwgMHhlODA1ZDIzMSwgMHg0Mjg5MjlmYiwgMHhiNGZjZGY4MiwgMHg0ZmI2NmE1MywgMHgwZTdkYzE1YixcclxuXHRcdCAgMHgxZjA4MWZhYiwgMHgxMDg2MThhZSwgMHhmY2ZkMDg2ZCwgMHhmOWZmMjg4OSwgMHg2OTRiY2MxMSwgMHgyMzZhNWNhZSwgMHgxMmRlY2E0ZCwgMHgyYzNmOGNjNSxcclxuXHRcdCAgMHhkMmQwMmRmZSwgMHhmOGVmNTg5NiwgMHhlNGNmNTJkYSwgMHg5NTE1NWI2NywgMHg0OTRhNDg4YywgMHhiOWI2YTgwYywgMHg1YzhmODJiYywgMHg4OWQzNmI0NSxcclxuXHRcdCAgMHgzYTYwOTQzNywgMHhlYzAwYzlhOSwgMHg0NDcxNTI1MywgMHgwYTg3NGI0OSwgMHhkNzczYmM0MCwgMHg3YzM0NjcxYywgMHgwMjcxN2VmNiwgMHg0ZmViNTUzNixcclxuXHRcdCAgMHhhMmQwMmZmZiwgMHhkMmJmNjBjNCwgMHhkNDNmMDNjMCwgMHg1MGI0ZWY2ZCwgMHgwNzQ3OGNkMSwgMHgwMDZlMTg4OCwgMHhhMmU1M2Y1NSwgMHhiOWU2ZDRiYyxcclxuXHRcdCAgMHhhMjA0ODAxNiwgMHg5NzU3MzgzMywgMHhkNzIwN2Q2NywgMHhkZTBmOGYzZCwgMHg3MmY4N2IzMywgMHhhYmNjNGYzMywgMHg3Njg4YzU1ZCwgMHg3YjAwYTZiMCxcclxuXHRcdCAgMHg5NDdiMDAwMSwgMHg1NzAwNzVkMiwgMHhmOWJiODhmOCwgMHg4OTQyMDE5ZSwgMHg0MjY0YTVmZiwgMHg4NTYzMDJlMCwgMHg3MmRiZDkyYiwgMHhlZTk3MWI2OSxcclxuXHRcdCAgMHg2ZWEyMmZkZSwgMHg1ZjA4YWUyYiwgMHhhZjdhNjE2ZCwgMHhlNWM5ODc2NywgMHhjZjFmZWJkMiwgMHg2MWVmYzhjMiwgMHhmMWFjMjU3MSwgMHhjYzgyMzljMixcclxuXHRcdCAgMHg2NzIxNGNiOCwgMHhiMWU1ODNkMSwgMHhiN2RjM2U2MiwgMHg3ZjEwYmRjZSwgMHhmOTBhNWMzOCwgMHgwZmYwNDQzZCwgMHg2MDZlNmRjNiwgMHg2MDU0M2E0OSxcclxuXHRcdCAgMHg1NzI3YzE0OCwgMHgyYmU5OGExZCwgMHg4YWI0MTczOCwgMHgyMGUxYmUyNCwgMHhhZjk2ZGEwZiwgMHg2ODQ1ODQyNSwgMHg5OTgzM2JlNSwgMHg2MDBkNDU3ZCxcclxuXHRcdCAgMHgyODJmOTM1MCwgMHg4MzM0YjM2MiwgMHhkOTFkMTEyMCwgMHgyYjZkOGRhMCwgMHg2NDJiMWUzMSwgMHg5YzMwNWEwMCwgMHg1MmJjZTY4OCwgMHgxYjAzNTg4YSxcclxuXHRcdCAgMHhmN2JhZWZkNSwgMHg0MTQyZWQ5YywgMHhhNDMxNWMxMSwgMHg4MzMyM2VjNSwgMHhkZmVmNDYzNiwgMHhhMTMzYzUwMSwgMHhlOWQzNTMxYywgMHhlZTM1Mzc4Myk7XHJcblxyXG5cdFx0c0JveFszXSA9IG5ldyBBcnJheShcclxuXHRcdCAgMHg5ZGIzMDQyMCwgMHgxZmI2ZTlkZSwgMHhhN2JlN2JlZiwgMHhkMjczYTI5OCwgMHg0YTRmN2JkYiwgMHg2NGFkOGM1NywgMHg4NTUxMDQ0MywgMHhmYTAyMGVkMSxcclxuXHRcdCAgMHg3ZTI4N2FmZiwgMHhlNjBmYjY2MywgMHgwOTVmMzVhMSwgMHg3OWViZjEyMCwgMHhmZDA1OWQ0MywgMHg2NDk3YjdiMSwgMHhmMzY0MWY2MywgMHgyNDFlNGFkZixcclxuXHRcdCAgMHgyODE0N2Y1ZiwgMHg0ZmEyYjhjZCwgMHhjOTQzMDA0MCwgMHgwY2MzMjIyMCwgMHhmZGQzMGIzMCwgMHhjMGE1Mzc0ZiwgMHgxZDJkMDBkOSwgMHgyNDE0N2IxNSxcclxuXHRcdCAgMHhlZTRkMTExYSwgMHgwZmNhNTE2NywgMHg3MWZmOTA0YywgMHgyZDE5NWZmZSwgMHgxYTA1NjQ1ZiwgMHgwYzEzZmVmZSwgMHgwODFiMDhjYSwgMHgwNTE3MDEyMSxcclxuXHRcdCAgMHg4MDUzMDEwMCwgMHhlODNlNWVmZSwgMHhhYzlhZjRmOCwgMHg3ZmU3MjcwMSwgMHhkMmI4ZWU1ZiwgMHgwNmRmNDI2MSwgMHhiYjllOWI4YSwgMHg3MjkzZWEyNSxcclxuXHRcdCAgMHhjZTg0ZmZkZiwgMHhmNTcxODgwMSwgMHgzZGQ2NGIwNCwgMHhhMjZmMjYzYiwgMHg3ZWQ0ODQwMCwgMHg1NDdlZWJlNiwgMHg0NDZkNGNhMCwgMHg2Y2YzZDZmNSxcclxuXHRcdCAgMHgyNjQ5YWJkZiwgMHhhZWEwYzdmNSwgMHgzNjMzOGNjMSwgMHg1MDNmN2U5MywgMHhkMzc3MjA2MSwgMHgxMWI2MzhlMSwgMHg3MjUwMGUwMywgMHhmODBlYjJiYixcclxuXHRcdCAgMHhhYmUwNTAyZSwgMHhlYzhkNzdkZSwgMHg1Nzk3MWU4MSwgMHhlMTRmNjc0NiwgMHhjOTMzNTQwMCwgMHg2OTIwMzE4ZiwgMHgwODFkYmI5OSwgMHhmZmMzMDRhNSxcclxuXHRcdCAgMHg0ZDM1MTgwNSwgMHg3ZjNkNWNlMywgMHhhNmM4NjZjNiwgMHg1ZDViY2NhOSwgMHhkYWVjNmZlYSwgMHg5ZjkyNmY5MSwgMHg5ZjQ2MjIyZiwgMHgzOTkxNDY3ZCxcclxuXHRcdCAgMHhhNWJmNmQ4ZSwgMHgxMTQzYzQ0ZiwgMHg0Mzk1ODMwMiwgMHhkMDIxNGVlYiwgMHgwMjIwODNiOCwgMHgzZmI2MTgwYywgMHgxOGY4OTMxZSwgMHgyODE2NThlNixcclxuXHRcdCAgMHgyNjQ4NmUzZSwgMHg4YmQ3OGE3MCwgMHg3NDc3ZTRjMSwgMHhiNTA2ZTA3YywgMHhmMzJkMGEyNSwgMHg3OTA5OGIwMiwgMHhlNGVhYmI4MSwgMHgyODEyM2IyMyxcclxuXHRcdCAgMHg2OWRlYWQzOCwgMHgxNTc0Y2ExNiwgMHhkZjg3MWI2MiwgMHgyMTFjNDBiNywgMHhhNTFhOWVmOSwgMHgwMDE0Mzc3YiwgMHgwNDFlOGFjOCwgMHgwOTExNDAwMyxcclxuXHRcdCAgMHhiZDU5ZTRkMiwgMHhlM2QxNTZkNSwgMHg0ZmU4NzZkNSwgMHgyZjkxYTM0MCwgMHg1NTdiZThkZSwgMHgwMGVhZTRhNywgMHgwY2U1YzJlYywgMHg0ZGI0YmJhNixcclxuXHRcdCAgMHhlNzU2YmRmZiwgMHhkZDMzNjlhYywgMHhlYzE3YjAzNSwgMHgwNjU3MjMyNywgMHg5OWFmYzhiMCwgMHg1NmM4YzM5MSwgMHg2YjY1ODExYywgMHg1ZTE0NjExOSxcclxuXHRcdCAgMHg2ZTg1Y2I3NSwgMHhiZTA3YzAwMiwgMHhjMjMyNTU3NywgMHg4OTNmZjRlYywgMHg1YmJmYzkyZCwgMHhkMGVjM2IyNSwgMHhiNzgwMWFiNywgMHg4ZDZkM2IyNCxcclxuXHRcdCAgMHgyMGM3NjNlZiwgMHhjMzY2YTVmYywgMHg5YzM4Mjg4MCwgMHgwYWNlMzIwNSwgMHhhYWM5NTQ4YSwgMHhlY2ExZDdjNywgMHgwNDFhZmEzMiwgMHgxZDE2NjI1YSxcclxuXHRcdCAgMHg2NzAxOTAyYywgMHg5Yjc1N2E1NCwgMHgzMWQ0NzdmNywgMHg5MTI2YjAzMSwgMHgzNmNjNmZkYiwgMHhjNzBiOGI0NiwgMHhkOWU2NmE0OCwgMHg1NmU1NWE3OSxcclxuXHRcdCAgMHgwMjZhNGNlYiwgMHg1MjQzN2VmZiwgMHgyZjhmNzZiNCwgMHgwZGY5ODBhNSwgMHg4Njc0Y2RlMywgMHhlZGRhMDRlYiwgMHgxN2E5YmUwNCwgMHgyYzE4ZjRkZixcclxuXHRcdCAgMHhiNzc0N2Y5ZCwgMHhhYjJhZjdiNCwgMHhlZmMzNGQyMCwgMHgyZTA5NmI3YywgMHgxNzQxYTI1NCwgMHhlNWI2YTAzNSwgMHgyMTNkNDJmNiwgMHgyYzFjN2MyNixcclxuXHRcdCAgMHg2MWMyZjUwZiwgMHg2NTUyZGFmOSwgMHhkMmMyMzFmOCwgMHgyNTEzMGY2OSwgMHhkODE2N2ZhMiwgMHgwNDE4ZjJjOCwgMHgwMDFhOTZhNiwgMHgwZDE1MjZhYixcclxuXHRcdCAgMHg2MzMxNWMyMSwgMHg1ZTBhNzJlYywgMHg0OWJhZmVmZCwgMHgxODc5MDhkOSwgMHg4ZDBkYmQ4NiwgMHgzMTExNzBhNywgMHgzZTliNjQwYywgMHhjYzNlMTBkNyxcclxuXHRcdCAgMHhkNWNhZDNiNiwgMHgwY2FlYzM4OCwgMHhmNzMwMDFlMSwgMHg2YzcyOGFmZiwgMHg3MWVhZTJhMSwgMHgxZjlhZjM2ZSwgMHhjZmNiZDEyZiwgMHhjMWRlODQxNyxcclxuXHRcdCAgMHhhYzA3YmU2YiwgMHhjYjQ0YTFkOCwgMHg4YjliMGY1NiwgMHgwMTM5ODhjMywgMHhiMWM1MmZjYSwgMHhiNGJlMzFjZCwgMHhkODc4MjgwNiwgMHgxMmEzYTRlMixcclxuXHRcdCAgMHg2ZjdkZTUzMiwgMHg1OGZkN2ViNiwgMHhkMDFlZTkwMCwgMHgyNGFkZmZjMiwgMHhmNDk5MGZjNSwgMHg5NzExYWFjNSwgMHgwMDFkN2I5NSwgMHg4MmU1ZTdkMixcclxuXHRcdCAgMHgxMDk4NzNmNiwgMHgwMDYxMzA5NiwgMHhjMzJkOTUyMSwgMHhhZGExMjFmZiwgMHgyOTkwODQxNSwgMHg3ZmJiOTc3ZiwgMHhhZjllYjNkYiwgMHgyOWM5ZWQyYSxcclxuXHRcdCAgMHg1Y2UyYTQ2NSwgMHhhNzMwZjMyYywgMHhkMGFhM2ZlOCwgMHg4YTVjYzA5MSwgMHhkNDllMmNlNywgMHgwY2U0NTRhOSwgMHhkNjBhY2Q4NiwgMHgwMTVmMTkxOSxcclxuXHRcdCAgMHg3NzA3OTEwMywgMHhkZWEwM2FmNiwgMHg3OGE4NTY1ZSwgMHhkZWUzNTZkZiwgMHgyMWYwNWNiZSwgMHg4Yjc1ZTM4NywgMHhiM2M1MDY1MSwgMHhiOGE1YzNlZixcclxuXHRcdCAgMHhkOGVlYjZkMiwgMHhlNTIzYmU3NywgMHhjMjE1NDUyOSwgMHgyZjY5ZWZkZiwgMHhhZmU2N2FmYiwgMHhmNDcwYzRiMiwgMHhmM2UwZWI1YiwgMHhkNmNjOTg3NixcclxuXHRcdCAgMHgzOWU0NDYwYywgMHgxZmRhODUzOCwgMHgxOTg3ODMyZiwgMHhjYTAwNzM2NywgMHhhOTkxNDRmOCwgMHgyOTZiMjk5ZSwgMHg0OTJmYzI5NSwgMHg5MjY2YmVhYixcclxuXHRcdCAgMHhiNTY3NmU2OSwgMHg5YmQzZGRkYSwgMHhkZjdlMDUyZiwgMHhkYjI1NzAxYywgMHgxYjVlNTFlZSwgMHhmNjUzMjRlNiwgMHg2YWZjZTM2YywgMHgwMzE2Y2MwNCxcclxuXHRcdCAgMHg4NjQ0MjEzZSwgMHhiN2RjNTlkMCwgMHg3OTY1MjkxZiwgMHhjY2Q2ZmQ0MywgMHg0MTgyMzk3OSwgMHg5MzJiY2RmNiwgMHhiNjU3YzM0ZCwgMHg0ZWRmZDI4MixcclxuXHRcdCAgMHg3YWU1MjkwYywgMHgzY2I5NTM2YiwgMHg4NTFlMjBmZSwgMHg5ODMzNTU3ZSwgMHgxM2VjZjBiMCwgMHhkM2ZmYjM3MiwgMHgzZjg1YzVjMSwgMHgwYWVmN2VkMik7XHJcblxyXG5cdFx0c0JveFs0XSA9IG5ldyBBcnJheShcclxuXHRcdCAgMHg3ZWM5MGMwNCwgMHgyYzZlNzRiOSwgMHg5YjBlNjZkZiwgMHhhNjMzNzkxMSwgMHhiODZhN2ZmZiwgMHgxZGQzNThmNSwgMHg0NGRkOWQ0NCwgMHgxNzMxMTY3ZixcclxuXHRcdCAgMHgwOGZiZjFmYSwgMHhlN2Y1MTFjYywgMHhkMjA1MWIwMCwgMHg3MzVhYmEwMCwgMHgyYWI3MjJkOCwgMHgzODYzODFjYiwgMHhhY2Y2MjQzYSwgMHg2OWJlZmQ3YSxcclxuXHRcdCAgMHhlNmEyZTc3ZiwgMHhmMGM3MjBjZCwgMHhjNDQ5NDgxNiwgMHhjY2Y1YzE4MCwgMHgzODg1MTY0MCwgMHgxNWIwYTg0OCwgMHhlNjhiMThjYiwgMHg0Y2FhZGVmZixcclxuXHRcdCAgMHg1ZjQ4MGEwMSwgMHgwNDEyYjJhYSwgMHgyNTk4MTRmYywgMHg0MWQwZWZlMiwgMHg0ZTQwYjQ4ZCwgMHgyNDhlYjZmYiwgMHg4ZGJhMWNmZSwgMHg0MWE5OWIwMixcclxuXHRcdCAgMHgxYTU1MGEwNCwgMHhiYThmNjVjYiwgMHg3MjUxZjRlNywgMHg5NWE1MTcyNSwgMHhjMTA2ZWNkNywgMHg5N2E1OTgwYSwgMHhjNTM5YjlhYSwgMHg0ZDc5ZmU2YSxcclxuXHRcdCAgMHhmMmYzZjc2MywgMHg2OGFmODA0MCwgMHhlZDBjOWU1NiwgMHgxMWI0OTU4YiwgMHhlMWViNWE4OCwgMHg4NzA5ZTZiMCwgMHhkN2UwNzE1NiwgMHg0ZTI5ZmVhNyxcclxuXHRcdCAgMHg2MzY2ZTUyZCwgMHgwMmQxYzAwMCwgMHhjNGFjOGUwNSwgMHg5Mzc3ZjU3MSwgMHgwYzA1MzcyYSwgMHg1Nzg1MzVmMiwgMHgyMjYxYmUwMiwgMHhkNjQyYTBjOSxcclxuXHRcdCAgMHhkZjEzYTI4MCwgMHg3NGI1NWJkMiwgMHg2ODIxOTljMCwgMHhkNDIxZTVlYywgMHg1M2ZiM2NlOCwgMHhjOGFkZWRiMywgMHgyOGE4N2ZjOSwgMHgzZDk1OTk4MSxcclxuXHRcdCAgMHg1YzFmZjkwMCwgMHhmZTM4ZDM5OSwgMHgwYzRlZmYwYiwgMHgwNjI0MDdlYSwgMHhhYTJmNGZiMSwgMHg0ZmI5Njk3NiwgMHg5MGM3OTUwNSwgMHhiMGE4YTc3NCxcclxuXHRcdCAgMHhlZjU1YTFmZiwgMHhlNTljYTJjMiwgMHhhNmI2MmQyNywgMHhlNjZhNDI2MywgMHhkZjY1MDAxZiwgMHgwZWM1MDk2NiwgMHhkZmRkNTViYywgMHgyOWRlMDY1NSxcclxuXHRcdCAgMHg5MTFlNzM5YSwgMHgxN2FmODk3NSwgMHgzMmM3OTExYywgMHg4OWY4OTQ2OCwgMHgwZDAxZTk4MCwgMHg1MjQ3NTVmNCwgMHgwM2I2M2NjOSwgMHgwY2M4NDRiMixcclxuXHRcdCAgMHhiY2YzZjBhYSwgMHg4N2FjMzZlOSwgMHhlNTNhNzQyNiwgMHgwMWIzZDgyYiwgMHgxYTllNzQ0OSwgMHg2NGVlMmQ3ZSwgMHhjZGRiYjFkYSwgMHgwMWM5NDkxMCxcclxuXHRcdCAgMHhiODY4YmY4MCwgMHgwZDI2ZjNmZCwgMHg5MzQyZWRlNywgMHgwNGE1YzI4NCwgMHg2MzY3MzdiNiwgMHg1MGY1YjYxNiwgMHhmMjQ3NjZlMywgMHg4ZWNhMzZjMSxcclxuXHRcdCAgMHgxMzZlMDVkYiwgMHhmZWYxODM5MSwgMHhmYjg4N2EzNywgMHhkNmU3ZjdkNCwgMHhjN2ZiN2RjOSwgMHgzMDYzZmNkZiwgMHhiNmY1ODlkZSwgMHhlYzI5NDFkYSxcclxuXHRcdCAgMHgyNmU0NjY5NSwgMHhiNzU2NjQxOSwgMHhmNjU0ZWZjNSwgMHhkMDhkNThiNywgMHg0ODkyNTQwMSwgMHhjMWJhY2I3ZiwgMHhlNWZmNTUwZiwgMHhiNjA4MzA0OSxcclxuXHRcdCAgMHg1YmI1ZDBlOCwgMHg4N2Q3MmU1YSwgMHhhYjZhNmVlMSwgMHgyMjNhNjZjZSwgMHhjNjJiZjNjZCwgMHg5ZTA4ODVmOSwgMHg2OGNiM2U0NywgMHgwODZjMDEwZixcclxuXHRcdCAgMHhhMjFkZTgyMCwgMHhkMThiNjlkZSwgMHhmM2Y2NTc3NywgMHhmYTAyYzNmNiwgMHg0MDdlZGFjMywgMHhjYmIzZDU1MCwgMHgxNzkzMDg0ZCwgMHhiMGQ3MGViYSxcclxuXHRcdCAgMHgwYWIzNzhkNSwgMHhkOTUxZmIwYywgMHhkZWQ3ZGE1NiwgMHg0MTI0YmJlNCwgMHg5NGNhMGI1NiwgMHgwZjU3NTVkMSwgMHhlMGUxZTU2ZSwgMHg2MTg0YjViZSxcclxuXHRcdCAgMHg1ODBhMjQ5ZiwgMHg5NGY3NGJjMCwgMHhlMzI3ODg4ZSwgMHg5ZjdiNTU2MSwgMHhjM2RjMDI4MCwgMHgwNTY4NzcxNSwgMHg2NDZjNmJkNywgMHg0NDkwNGRiMyxcclxuXHRcdCAgMHg2NmI0ZjBhMywgMHhjMGYxNjQ4YSwgMHg2OTdlZDVhZiwgMHg0OWU5MmZmNiwgMHgzMDllMzc0ZiwgMHgyY2I2MzU2YSwgMHg4NTgwODU3MywgMHg0OTkxZjg0MCxcclxuXHRcdCAgMHg3NmYwYWUwMiwgMHgwODNiZTg0ZCwgMHgyODQyMWM5YSwgMHg0NDQ4OTQwNiwgMHg3MzZlNGNiOCwgMHhjMTA5MjkxMCwgMHg4YmM5NWZjNiwgMHg3ZDg2OWNmNCxcclxuXHRcdCAgMHgxMzRmNjE2ZiwgMHgyZTc3MTE4ZCwgMHhiMzFiMmJlMSwgMHhhYTkwYjQ3MiwgMHgzY2E1ZDcxNywgMHg3ZDE2MWJiYSwgMHg5Y2FkOTAxMCwgMHhhZjQ2MmJhMixcclxuXHRcdCAgMHg5ZmU0NTlkMiwgMHg0NWQzNDU1OSwgMHhkOWYyZGExMywgMHhkYmM2NTQ4NywgMHhmM2U0Zjk0ZSwgMHgxNzZkNDg2ZiwgMHgwOTdjMTNlYSwgMHg2MzFkYTVjNyxcclxuXHRcdCAgMHg0NDVmNzM4MiwgMHgxNzU2ODNmNCwgMHhjZGM2NmE5NywgMHg3MGJlMDI4OCwgMHhiM2NkY2Y3MiwgMHg2ZTVkZDJmMywgMHgyMDkzNjA3OSwgMHg0NTliODBhNSxcclxuXHRcdCAgMHhiZTYwZTJkYiwgMHhhOWMyMzEwMSwgMHhlYmE1MzE1YywgMHgyMjRlNDJmMiwgMHgxYzVjMTU3MiwgMHhmNjcyMWIyYywgMHgxYWQyZmZmMywgMHg4YzI1NDA0ZSxcclxuXHRcdCAgMHgzMjRlZDcyZiwgMHg0MDY3YjdmZCwgMHgwNTIzMTM4ZSwgMHg1Y2EzYmM3OCwgMHhkYzBmZDY2ZSwgMHg3NTkyMjI4MywgMHg3ODRkNmIxNywgMHg1OGViYjE2ZSxcclxuXHRcdCAgMHg0NDA5NGY4NSwgMHgzZjQ4MWQ4NywgMHhmY2ZlYWU3YiwgMHg3N2I1ZmY3NiwgMHg4YzIzMDJiZiwgMHhhYWY0NzU1NiwgMHg1ZjQ2YjAyYSwgMHgyYjA5MjgwMSxcclxuXHRcdCAgMHgzZDM4ZjVmNywgMHgwY2E4MWYzNiwgMHg1MmFmNGE4YSwgMHg2NmQ1ZTdjMCwgMHhkZjNiMDg3NCwgMHg5NTA1NTExMCwgMHgxYjVhZDdhOCwgMHhmNjFlZDVhZCxcclxuXHRcdCAgMHg2Y2Y2ZTQ3OSwgMHgyMDc1ODE4NCwgMHhkMGNlZmE2NSwgMHg4OGY3YmU1OCwgMHg0YTA0NjgyNiwgMHgwZmY2ZjhmMywgMHhhMDljN2Y3MCwgMHg1MzQ2YWJhMCxcclxuXHRcdCAgMHg1Y2U5NmMyOCwgMHhlMTc2ZWRhMywgMHg2YmFjMzA3ZiwgMHgzNzY4MjlkMiwgMHg4NTM2MGZhOSwgMHgxN2UzZmUyYSwgMHgyNGI3OTc2NywgMHhmNWE5NmIyMCxcclxuXHRcdCAgMHhkNmNkMjU5NSwgMHg2OGZmMWViZiwgMHg3NTU1NDQyYywgMHhmMTlmMDZiZSwgMHhmOWUwNjU5YSwgMHhlZWI5NDkxZCwgMHgzNDAxMDcxOCwgMHhiYjMwY2FiOCxcclxuXHRcdCAgMHhlODIyZmUxNSwgMHg4ODU3MDk4MywgMHg3NTBlNjI0OSwgMHhkYTYyN2U1NSwgMHg1ZTc2ZmZhOCwgMHhiMTUzNDU0NiwgMHg2ZDQ3ZGUwOCwgMHhlZmU5ZTdkNCk7XHJcblxyXG5cdFx0c0JveFs1XSA9IG5ldyBBcnJheShcclxuXHRcdCAgMHhmNmZhOGY5ZCwgMHgyY2FjNmNlMSwgMHg0Y2EzNDg2NywgMHhlMjMzN2Y3YywgMHg5NWRiMDhlNywgMHgwMTY4NDNiNCwgMHhlY2VkNWNiYywgMHgzMjU1NTNhYyxcclxuXHRcdCAgMHhiZjlmMDk2MCwgMHhkZmExZTJlZCwgMHg4M2YwNTc5ZCwgMHg2M2VkODZiOSwgMHgxYWI2YTZiOCwgMHhkZTVlYmUzOSwgMHhmMzhmZjczMiwgMHg4OTg5YjEzOCxcclxuXHRcdCAgMHgzM2YxNDk2MSwgMHhjMDE5MzdiZCwgMHhmNTA2YzZkYSwgMHhlNDYyNWU3ZSwgMHhhMzA4ZWE5OSwgMHg0ZTIzZTMzYywgMHg3OWNiZDdjYywgMHg0OGExNDM2NyxcclxuXHRcdCAgMHhhMzE0OTYxOSwgMHhmZWM5NGJkNSwgMHhhMTE0MTc0YSwgMHhlYWEwMTg2NiwgMHhhMDg0ZGIyZCwgMHgwOWE4NDg2ZiwgMHhhODg4NjE0YSwgMHgyOTAwYWY5OCxcclxuXHRcdCAgMHgwMTY2NTk5MSwgMHhlMTk5Mjg2MywgMHhjOGYzMGM2MCwgMHgyZTc4ZWYzYywgMHhkMGQ1MTkzMiwgMHhjZjBmZWMxNCwgMHhmN2NhMDdkMiwgMHhkMGE4MjA3MixcclxuXHRcdCAgMHhmZDQxMTk3ZSwgMHg5MzA1YTZiMCwgMHhlODZiZTNkYSwgMHg3NGJlZDNjZCwgMHgzNzJkYTUzYywgMHg0YzdmNDQ0OCwgMHhkYWI1ZDQ0MCwgMHg2ZGJhMGVjMyxcclxuXHRcdCAgMHgwODM5MTlhNywgMHg5ZmJhZWVkOSwgMHg0OWRiY2ZiMCwgMHg0ZTY3MGM1MywgMHg1YzNkOWMwMSwgMHg2NGJkYjk0MSwgMHgyYzBlNjM2YSwgMHhiYTdkZDljZCxcclxuXHRcdCAgMHhlYTZmNzM4OCwgMHhlNzBiYzc2MiwgMHgzNWYyOWFkYiwgMHg1YzRjZGQ4ZCwgMHhmMGQ0OGQ4YywgMHhiODgxNTNlMiwgMHgwOGExOTg2NiwgMHgxYWUyZWFjOCxcclxuXHRcdCAgMHgyODRjYWY4OSwgMHhhYTkyODIyMywgMHg5MzM0YmU1MywgMHgzYjNhMjFiZiwgMHgxNjQzNGJlMywgMHg5YWVhMzkwNiwgMHhlZmU4YzM2ZSwgMHhmODkwY2RkOSxcclxuXHRcdCAgMHg4MDIyNmRhZSwgMHhjMzQwYTRhMywgMHhkZjdlOWMwOSwgMHhhNjk0YTgwNywgMHg1YjdjNWVjYywgMHgyMjFkYjNhNiwgMHg5YTY5YTAyZiwgMHg2ODgxOGE1NCxcclxuXHRcdCAgMHhjZWIyMjk2ZiwgMHg1M2MwODQzYSwgMHhmZTg5MzY1NSwgMHgyNWJmZTY4YSwgMHhiNDYyOGFiYywgMHhjZjIyMmViZiwgMHgyNWFjNmY0OCwgMHhhOWE5OTM4NyxcclxuXHRcdCAgMHg1M2JkZGI2NSwgMHhlNzZmZmJlNywgMHhlOTY3ZmQ3OCwgMHgwYmE5MzU2MywgMHg4ZTM0MmJjMSwgMHhlOGExMWJlOSwgMHg0OTgwNzQwZCwgMHhjODA4N2RmYyxcclxuXHRcdCAgMHg4ZGU0YmY5OSwgMHhhMTExMDFhMCwgMHg3ZmQzNzk3NSwgMHhkYTVhMjZjMCwgMHhlODFmOTk0ZiwgMHg5NTI4Y2Q4OSwgMHhmZDMzOWZlZCwgMHhiODc4MzRiZixcclxuXHRcdCAgMHg1ZjA0NDU2ZCwgMHgyMjI1ODY5OCwgMHhjOWM0YzgzYiwgMHgyZGMxNTZiZSwgMHg0ZjYyOGRhYSwgMHg1N2Y1NWVjNSwgMHhlMjIyMGFiZSwgMHhkMjkxNmViZixcclxuXHRcdCAgMHg0ZWM3NWI5NSwgMHgyNGYyYzNjMCwgMHg0MmQxNWQ5OSwgMHhjZDBkN2ZhMCwgMHg3YjZlMjdmZiwgMHhhOGRjOGFmMCwgMHg3MzQ1YzEwNiwgMHhmNDFlMjMyZixcclxuXHRcdCAgMHgzNTE2MjM4NiwgMHhlNmVhODkyNiwgMHgzMzMzYjA5NCwgMHgxNTdlYzZmMiwgMHgzNzJiNzRhZiwgMHg2OTI1NzNlNCwgMHhlOWE5ZDg0OCwgMHhmMzE2MDI4OSxcclxuXHRcdCAgMHgzYTYyZWYxZCwgMHhhNzg3ZTIzOCwgMHhmM2E1ZjY3NiwgMHg3NDM2NDg1MywgMHgyMDk1MTA2MywgMHg0NTc2Njk4ZCwgMHhiNmZhZDQwNywgMHg1OTJhZjk1MCxcclxuXHRcdCAgMHgzNmY3MzUyMywgMHg0Y2ZiNmU4NywgMHg3ZGE0Y2VjMCwgMHg2YzE1MmRhYSwgMHhjYjAzOTZhOCwgMHhjNTBkZmU1ZCwgMHhmY2Q3MDdhYiwgMHgwOTIxYzQyZixcclxuXHRcdCAgMHg4OWRmZjBiYiwgMHg1ZmUyYmU3OCwgMHg0NDhmNGYzMywgMHg3NTQ2MTNjOSwgMHgyYjA1ZDA4ZCwgMHg0OGI5ZDU4NSwgMHhkYzA0OTQ0MSwgMHhjODA5OGY5YixcclxuXHRcdCAgMHg3ZGVkZTc4NiwgMHhjMzlhMzM3MywgMHg0MjQxMDAwNSwgMHg2YTA5MTc1MSwgMHgwZWYzYzhhNiwgMHg4OTAwNzJkNiwgMHgyODIwNzY4MiwgMHhhOWE5ZjdiZSxcclxuXHRcdCAgMHhiZjMyNjc5ZCwgMHhkNDViNWI3NSwgMHhiMzUzZmQwMCwgMHhjYmIwZTM1OCwgMHg4MzBmMjIwYSwgMHgxZjhmYjIxNCwgMHhkMzcyY2YwOCwgMHhjYzNjNGExMyxcclxuXHRcdCAgMHg4Y2Y2MzE2NiwgMHgwNjFjODdiZSwgMHg4OGM5OGY4OCwgMHg2MDYyZTM5NywgMHg0N2NmOGU3YSwgMHhiNmM4NTI4MywgMHgzY2MyYWNmYiwgMHgzZmMwNjk3NixcclxuXHRcdCAgMHg0ZThmMDI1MiwgMHg2NGQ4MzE0ZCwgMHhkYTM4NzBlMywgMHgxZTY2NTQ1OSwgMHhjMTA5MDhmMCwgMHg1MTMwMjFhNSwgMHg2YzViNjhiNywgMHg4MjJmOGFhMCxcclxuXHRcdCAgMHgzMDA3Y2QzZSwgMHg3NDcxOWVlZiwgMHhkYzg3MjY4MSwgMHgwNzMzNDBkNCwgMHg3ZTQzMmZkOSwgMHgwYzVlYzI0MSwgMHg4ODA5Mjg2YywgMHhmNTkyZDg5MSxcclxuXHRcdCAgMHgwOGE5MzBmNiwgMHg5NTdlZjMwNSwgMHhiN2ZiZmZiZCwgMHhjMjY2ZTk2ZiwgMHg2ZmU0YWM5OCwgMHhiMTczZWNjMCwgMHhiYzYwYjQyYSwgMHg5NTM0OThkYSxcclxuXHRcdCAgMHhmYmExYWUxMiwgMHgyZDRiZDczNiwgMHgwZjI1ZmFhYiwgMHhhNGYzZmNlYiwgMHhlMjk2OTEyMywgMHgyNTdmMGMzZCwgMHg5MzQ4YWY0OSwgMHgzNjE0MDBiYyxcclxuXHRcdCAgMHhlODgxNmY0YSwgMHgzODE0ZjIwMCwgMHhhM2Y5NDA0MywgMHg5YzdhNTRjMiwgMHhiYzcwNGY1NywgMHhkYTQxZTdmOSwgMHhjMjVhZDMzYSwgMHg1NGY0YTA4NCxcclxuXHRcdCAgMHhiMTdmNTUwNSwgMHg1OTM1N2NiZSwgMHhlZGJkMTVjOCwgMHg3Zjk3YzVhYiwgMHhiYTVhYzdiNSwgMHhiNmY2ZGVhZiwgMHgzYTQ3OWMzYSwgMHg1MzAyZGEyNSxcclxuXHRcdCAgMHg2NTNkN2U2YSwgMHg1NDI2OGQ0OSwgMHg1MWE0NzdlYSwgMHg1MDE3ZDU1YiwgMHhkN2QyNWQ4OCwgMHg0NDEzNmM3NiwgMHgwNDA0YThjOCwgMHhiOGU1YTEyMSxcclxuXHRcdCAgMHhiODFhOTI4YSwgMHg2MGVkNTg2OSwgMHg5N2M1NWI5NiwgMHhlYWVjOTkxYiwgMHgyOTkzNTkxMywgMHgwMWZkYjdmMSwgMHgwODhlOGRmYSwgMHg5YWI2ZjZmNSxcclxuXHRcdCAgMHgzYjRjYmY5ZiwgMHg0YTVkZTNhYiwgMHhlNjA1MWQzNSwgMHhhMGUxZDg1NSwgMHhkMzZiNGNmMSwgMHhmNTQ0ZWRlYiwgMHhiMGU5MzUyNCwgMHhiZWJiOGZiZCxcclxuXHRcdCAgMHhhMmQ3NjJjZiwgMHg0OWM5MmY1NCwgMHgzOGI1ZjMzMSwgMHg3MTI4YTQ1NCwgMHg0ODM5MjkwNSwgMHhhNjViMWRiOCwgMHg4NTFjOTdiZCwgMHhkNjc1Y2YyZik7XHJcblxyXG5cdFx0c0JveFs2XSA9IG5ldyBBcnJheShcclxuXHRcdCAgMHg4NWUwNDAxOSwgMHgzMzJiZjU2NywgMHg2NjJkYmZmZiwgMHhjZmM2NTY5MywgMHgyYThkN2Y2ZiwgMHhhYjliYzkxMiwgMHhkZTYwMDhhMSwgMHgyMDI4ZGExZixcclxuXHRcdCAgMHgwMjI3YmNlNywgMHg0ZDY0MjkxNiwgMHgxOGZhYzMwMCwgMHg1MGYxOGI4MiwgMHgyY2IyY2IxMSwgMHhiMjMyZTc1YywgMHg0YjM2OTVmMiwgMHhiMjg3MDdkZSxcclxuXHRcdCAgMHhhMDVmYmNmNiwgMHhjZDQxODFlOSwgMHhlMTUwMjEwYywgMHhlMjRlZjFiZCwgMHhiMTY4YzM4MSwgMHhmZGU0ZTc4OSwgMHg1Yzc5YjBkOCwgMHgxZThiZmQ0MyxcclxuXHRcdCAgMHg0ZDQ5NTAwMSwgMHgzOGJlNDM0MSwgMHg5MTNjZWUxZCwgMHg5MmE3OWMzZiwgMHgwODk3NjZiZSwgMHhiYWVlYWRmNCwgMHgxMjg2YmVjZiwgMHhiNmVhY2IxOSxcclxuXHRcdCAgMHgyNjYwYzIwMCwgMHg3NTY1YmRlNCwgMHg2NDI0MWY3YSwgMHg4MjQ4ZGNhOSwgMHhjM2IzYWQ2NiwgMHgyODEzNjA4NiwgMHgwYmQ4ZGZhOCwgMHgzNTZkMWNmMixcclxuXHRcdCAgMHgxMDc3ODliZSwgMHhiM2IyZTljZSwgMHgwNTAyYWE4ZiwgMHgwYmMwMzUxZSwgMHgxNjZiZjUyYSwgMHhlYjEyZmY4MiwgMHhlMzQ4NjkxMSwgMHhkMzRkNzUxNixcclxuXHRcdCAgMHg0ZTdiM2FmZiwgMHg1ZjQzNjcxYiwgMHg5Y2Y2ZTAzNywgMHg0OTgxYWM4MywgMHgzMzQyNjZjZSwgMHg4YzkzNDFiNywgMHhkMGQ4NTRjMCwgMHhjYjNhNmM4OCxcclxuXHRcdCAgMHg0N2JjMjgyOSwgMHg0NzI1YmEzNywgMHhhNjZhZDIyYiwgMHg3YWQ2MWYxZSwgMHgwYzVjYmFmYSwgMHg0NDM3ZjEwNywgMHhiNmU3OTk2MiwgMHg0MmQyZDgxNixcclxuXHRcdCAgMHgwYTk2MTI4OCwgMHhlMWE1YzA2ZSwgMHgxMzc0OWU2NywgMHg3MmZjMDgxYSwgMHhiMWQxMzlmNywgMHhmOTU4Mzc0NSwgMHhjZjE5ZGY1OCwgMHhiZWMzZjc1NixcclxuXHRcdCAgMHhjMDZlYmEzMCwgMHgwNzIxMWIyNCwgMHg0NWMyODgyOSwgMHhjOTVlMzE3ZiwgMHhiYzhlYzUxMSwgMHgzOGJjNDZlOSwgMHhjNmU2ZmExNCwgMHhiYWU4NTg0YSxcclxuXHRcdCAgMHhhZDRlYmM0NiwgMHg0NjhmNTA4YiwgMHg3ODI5NDM1ZiwgMHhmMTI0MTgzYiwgMHg4MjFkYmE5ZiwgMHhhZmY2MGZmNCwgMHhlYTJjNGU2ZCwgMHgxNmUzOTI2NCxcclxuXHRcdCAgMHg5MjU0NGE4YiwgMHgwMDliNGZjMywgMHhhYmE2OGNlZCwgMHg5YWM5NmY3OCwgMHgwNmE1Yjc5YSwgMHhiMjg1NmU2ZSwgMHgxYWVjM2NhOSwgMHhiZTgzODY4OCxcclxuXHRcdCAgMHgwZTA4MDRlOSwgMHg1NWYxYmU1NiwgMHhlN2U1MzYzYiwgMHhiM2ExZjI1ZCwgMHhmN2RlYmI4NSwgMHg2MWZlMDMzYywgMHgxNjc0NjIzMywgMHgzYzAzNGMyOCxcclxuXHRcdCAgMHhkYTZkMGM3NCwgMHg3OWFhYzU2YywgMHgzY2U0ZTFhZCwgMHg1MWYwYzgwMiwgMHg5OGY4ZjM1YSwgMHgxNjI2YTQ5ZiwgMHhlZWQ4MmIyOSwgMHgxZDM4MmZlMyxcclxuXHRcdCAgMHgwYzRmYjk5YSwgMHhiYjMyNTc3OCwgMHgzZWM2ZDk3YiwgMHg2ZTc3YTZhOSwgMHhjYjY1OGI1YywgMHhkNDUyMzBjNywgMHgyYmQxNDA4YiwgMHg2MGMwM2ViNyxcclxuXHRcdCAgMHhiOTA2OGQ3OCwgMHhhMzM3NTRmNCwgMHhmNDMwYzg3ZCwgMHhjOGE3MTMwMiwgMHhiOTZkOGMzMiwgMHhlYmQ0ZTdiZSwgMHhiZThiOWQyZCwgMHg3OTc5ZmIwNixcclxuXHRcdCAgMHhlNzIyNTMwOCwgMHg4Yjc1Y2Y3NywgMHgxMWVmOGRhNCwgMHhlMDgzYzg1OCwgMHg4ZDZiNzg2ZiwgMHg1YTYzMTdhNiwgMHhmYTVjZjdhMCwgMHg1ZGRhMDAzMyxcclxuXHRcdCAgMHhmMjhlYmZiMCwgMHhmNWI5YzMxMCwgMHhhMGVhYzI4MCwgMHgwOGI5NzY3YSwgMHhhM2Q5ZDJiMCwgMHg3OWQzNDIxNywgMHgwMjFhNzE4ZCwgMHg5YWM2MzM2YSxcclxuXHRcdCAgMHgyNzExZmQ2MCwgMHg0MzgwNTBlMywgMHgwNjk5MDhhOCwgMHgzZDdmZWRjNCwgMHg4MjZkMmJlZiwgMHg0ZWViODQ3NiwgMHg0ODhkY2YyNSwgMHgzNmM5ZDU2NixcclxuXHRcdCAgMHgyOGU3NGU0MSwgMHhjMjYxMGFjYSwgMHgzZDQ5YTljZiwgMHhiYWUzYjlkZiwgMHhiNjVmOGRlNiwgMHg5MmFlYWY2NCwgMHgzYWM3ZDVlNiwgMHg5ZWE4MDUwOSxcclxuXHRcdCAgMHhmMjJiMDE3ZCwgMHhhNDE3M2Y3MCwgMHhkZDFlMTZjMywgMHgxNWUwZDdmOSwgMHg1MGIxYjg4NywgMHgyYjlmNGZkNSwgMHg2MjVhYmE4MiwgMHg2YTAxNzk2MixcclxuXHRcdCAgMHgyZWMwMWI5YywgMHgxNTQ4OGFhOSwgMHhkNzE2ZTc0MCwgMHg0MDA1NWEyYywgMHg5M2QyOWEyMiwgMHhlMzJkYmY5YSwgMHgwNTg3NDViOSwgMHgzNDUzZGMxZSxcclxuXHRcdCAgMHhkNjk5Mjk2ZSwgMHg0OTZjZmY2ZiwgMHgxYzlmNDk4NiwgMHhkZmUyZWQwNywgMHhiODcyNDJkMSwgMHgxOWRlN2VhZSwgMHgwNTNlNTYxYSwgMHgxNWFkNmY4YyxcclxuXHRcdCAgMHg2NjYyNmMxYywgMHg3MTU0YzI0YywgMHhlYTA4MmIyYSwgMHg5M2ViMjkzOSwgMHgxN2RjYjBmMCwgMHg1OGQ0ZjJhZSwgMHg5ZWEyOTRmYiwgMHg1MmNmNTY0YyxcclxuXHRcdCAgMHg5ODgzZmU2NiwgMHgyZWM0MDU4MSwgMHg3NjM5NTNjMywgMHgwMWQ2NjkyZSwgMHhkM2EwYzEwOCwgMHhhMWU3MTYwZSwgMHhlNGYyZGZhNiwgMHg2OTNlZDI4NSxcclxuXHRcdCAgMHg3NDkwNDY5OCwgMHg0YzJiMGVkZCwgMHg0Zjc1NzY1NiwgMHg1ZDM5MzM3OCwgMHhhMTMyMjM0ZiwgMHgzZDMyMWM1ZCwgMHhjM2Y1ZTE5NCwgMHg0YjI2OTMwMSxcclxuXHRcdCAgMHhjNzlmMDIyZiwgMHgzYzk5N2U3ZSwgMHg1ZTRmOTUwNCwgMHgzZmZhZmJiZCwgMHg3NmY3YWQwZSwgMHgyOTY2OTNmNCwgMHgzZDFmY2U2ZiwgMHhjNjFlNDViZSxcclxuXHRcdCAgMHhkM2I1YWIzNCwgMHhmNzJiZjliNywgMHgxYjA0MzRjMCwgMHg0ZTcyYjU2NywgMHg1NTkyYTMzZCwgMHhiNTIyOTMwMSwgMHhjZmQyYTg3ZiwgMHg2MGFlYjc2NyxcclxuXHRcdCAgMHgxODE0Mzg2YiwgMHgzMGJjYzMzZCwgMHgzOGEwYzA3ZCwgMHhmZDE2MDZmMiwgMHhjMzYzNTE5YiwgMHg1ODlkZDM5MCwgMHg1NDc5ZjhlNiwgMHgxY2I4ZDY0NyxcclxuXHRcdCAgMHg5N2ZkNjFhOSwgMHhlYTc3NTlmNCwgMHgyZDU3NTM5ZCwgMHg1NjlhNThjZiwgMHhlODRlNjNhZCwgMHg0NjJlMWI3OCwgMHg2NTgwZjg3ZSwgMHhmMzgxNzkxNCxcclxuXHRcdCAgMHg5MWRhNTVmNCwgMHg0MGEyMzBmMywgMHhkMTk4OGYzNSwgMHhiNmUzMThkMiwgMHgzZmZhNTBiYywgMHgzZDQwZjAyMSwgMHhjM2MwYmRhZSwgMHg0OTU4YzI0YyxcclxuXHRcdCAgMHg1MThmMzZiMiwgMHg4NGIxZDM3MCwgMHgwZmVkY2U4MywgMHg4NzhkZGFkYSwgMHhmMmEyNzljNywgMHg5NGUwMWJlOCwgMHg5MDcxNmY0YiwgMHg5NTRiOGFhMyk7XHJcblxyXG5cdFx0c0JveFs3XSA9IG5ldyBBcnJheShcclxuXHRcdCAgMHhlMjE2MzAwZCwgMHhiYmRkZmZmYywgMHhhN2ViZGFiZCwgMHgzNTY0ODA5NSwgMHg3Nzg5ZjhiNywgMHhlNmMxMTIxYiwgMHgwZTI0MTYwMCwgMHgwNTJjZThiNSxcclxuXHRcdCAgMHgxMWE5Y2ZiMCwgMHhlNTk1MmYxMSwgMHhlY2U3OTkwYSwgMHg5Mzg2ZDE3NCwgMHgyYTQyOTMxYywgMHg3NmUzODExMSwgMHhiMTJkZWYzYSwgMHgzN2RkZGRmYyxcclxuXHRcdCAgMHhkZTlhZGViMSwgMHgwYTBjYzMyYywgMHhiZTE5NzAyOSwgMHg4NGEwMDk0MCwgMHhiYjI0M2EwZiwgMHhiNGQxMzdjZiwgMHhiNDRlNzlmMCwgMHgwNDllZWRmZCxcclxuXHRcdCAgMHgwYjE1YTE1ZCwgMHg0ODBkMzE2OCwgMHg4YmJiZGU1YSwgMHg2NjlkZWQ0MiwgMHhjN2VjZTgzMSwgMHgzZjhmOTVlNywgMHg3MmRmMTkxYiwgMHg3NTgwMzMwZCxcclxuXHRcdCAgMHg5NDA3NDI1MSwgMHg1YzdkY2RmYSwgMHhhYmJlNmQ2MywgMHhhYTQwMjE2NCwgMHhiMzAxZDQwYSwgMHgwMmU3ZDFjYSwgMHg1MzU3MWRhZSwgMHg3YTMxODJhMixcclxuXHRcdCAgMHgxMmE4ZGRlYywgMHhmZGFhMzM1ZCwgMHgxNzZmNDNlOCwgMHg3MWZiNDZkNCwgMHgzODEyOTAyMiwgMHhjZTk0OWFkNCwgMHhiODQ3NjlhZCwgMHg5NjViZDg2MixcclxuXHRcdCAgMHg4MmYzZDA1NSwgMHg2NmZiOTc2NywgMHgxNWI4MGI0ZSwgMHgxZDViNDdhMCwgMHg0Y2ZkZTA2ZiwgMHhjMjhlYzRiOCwgMHg1N2U4NzI2ZSwgMHg2NDdhNzhmYyxcclxuXHRcdCAgMHg5OTg2NWQ0NCwgMHg2MDhiZDU5MywgMHg2YzIwMGUwMywgMHgzOWRjNWZmNiwgMHg1ZDBiMDBhMywgMHhhZTYzYWZmMiwgMHg3ZThiZDYzMiwgMHg3MDEwOGMwYyxcclxuXHRcdCAgMHhiYmQzNTA0OSwgMHgyOTk4ZGYwNCwgMHg5ODBjZjQyYSwgMHg5YjZkZjQ5MSwgMHg5ZTdlZGQ1MywgMHgwNjkxODU0OCwgMHg1OGNiN2UwNywgMHgzYjc0ZWYyZSxcclxuXHRcdCAgMHg1MjJmZmZiMSwgMHhkMjQ3MDhjYywgMHgxYzdlMjdjZCwgMHhhNGViMjE1YiwgMHgzY2YxZDJlMiwgMHgxOWI0N2EzOCwgMHg0MjRmNzYxOCwgMHgzNTg1NjAzOSxcclxuXHRcdCAgMHg5ZDE3ZGVlNywgMHgyN2ViMzVlNiwgMHhjOWFmZjY3YiwgMHgzNmJhZjViOCwgMHgwOWM0NjdjZCwgMHhjMTg5MTBiMSwgMHhlMTFkYmY3YiwgMHgwNmNkMWFmOCxcclxuXHRcdCAgMHg3MTcwYzYwOCwgMHgyZDVlMzM1NCwgMHhkNGRlNDk1YSwgMHg2NGM2ZDAwNiwgMHhiY2MwYzYyYywgMHgzZGQwMGRiMywgMHg3MDhmOGYzNCwgMHg3N2Q1MWI0MixcclxuXHRcdCAgMHgyNjRmNjIwZiwgMHgyNGI4ZDJiZiwgMHgxNWMxYjc5ZSwgMHg0NmE1MjU2NCwgMHhmOGQ3ZTU0ZSwgMHgzZTM3ODE2MCwgMHg3ODk1Y2RhNSwgMHg4NTljMTVhNSxcclxuXHRcdCAgMHhlNjQ1OTc4OCwgMHhjMzdiYzc1ZiwgMHhkYjA3YmEwYywgMHgwNjc2YTNhYiwgMHg3ZjIyOWIxZSwgMHgzMTg0MmU3YiwgMHgyNDI1OWZkNywgMHhmOGJlZjQ3MixcclxuXHRcdCAgMHg4MzVmZmNiOCwgMHg2ZGY0YzFmMiwgMHg5NmY1YjE5NSwgMHhmZDBhZjBmYywgMHhiMGZlMTM0YywgMHhlMjUwNmQzZCwgMHg0ZjliMTJlYSwgMHhmMjE1ZjIyNSxcclxuXHRcdCAgMHhhMjIzNzM2ZiwgMHg5ZmI0YzQyOCwgMHgyNWQwNDk3OSwgMHgzNGM3MTNmOCwgMHhjNDYxODE4NywgMHhlYTdhNmU5OCwgMHg3Y2QxNmVmYywgMHgxNDM2ODc2YyxcclxuXHRcdCAgMHhmMTU0NDEwNywgMHhiZWRlZWUxNCwgMHg1NmU5YWYyNywgMHhhMDRhYTQ0MSwgMHgzY2Y3Yzg5OSwgMHg5MmVjYmFlNiwgMHhkZDY3MDE2ZCwgMHgxNTE2ODJlYixcclxuXHRcdCAgMHhhODQyZWVkZiwgMHhmZGJhNjBiNCwgMHhmMTkwN2I3NSwgMHgyMGUzMDMwZiwgMHgyNGQ4YzI5ZSwgMHhlMTM5NjczYiwgMHhlZmE2M2ZiOCwgMHg3MTg3MzA1NCxcclxuXHRcdCAgMHhiNmYyY2YzYiwgMHg5ZjMyNjQ0MiwgMHhjYjE1YTRjYywgMHhiMDFhNDUwNCwgMHhmMWU0N2Q4ZCwgMHg4NDRhMWJlNSwgMHhiYWU3ZGZkYywgMHg0MmNiZGE3MCxcclxuXHRcdCAgMHhjZDdkYWUwYSwgMHg1N2U4NWI3YSwgMHhkNTNmNWFmNiwgMHgyMGNmNGQ4YywgMHhjZWE0ZDQyOCwgMHg3OWQxMzBhNCwgMHgzNDg2ZWJmYiwgMHgzM2QzY2RkYyxcclxuXHRcdCAgMHg3Nzg1M2I1MywgMHgzN2VmZmNiNSwgMHhjNTA2ODc3OCwgMHhlNTgwYjNlNiwgMHg0ZTY4YjhmNCwgMHhjNWM4YjM3ZSwgMHgwZDgwOWVhMiwgMHgzOThmZWI3YyxcclxuXHRcdCAgMHgxMzJhNGY5NCwgMHg0M2I3OTUwZSwgMHgyZmVlN2QxYywgMHgyMjM2MTNiZCwgMHhkZDA2Y2FhMiwgMHgzN2RmOTMyYiwgMHhjNDI0ODI4OSwgMHhhY2YzZWJjMyxcclxuXHRcdCAgMHg1NzE1ZjZiNywgMHhlZjM0NzhkZCwgMHhmMjY3NjE2ZiwgMHhjMTQ4Y2JlNCwgMHg5MDUyODE1ZSwgMHg1ZTQxMGZhYiwgMHhiNDhhMjQ2NSwgMHgyZWRhN2ZhNCxcclxuXHRcdCAgMHhlODdiNDBlNCwgMHhlOThlYTA4NCwgMHg1ODg5ZTllMSwgMHhlZmQzOTBmYywgMHhkZDA3ZDM1YiwgMHhkYjQ4NTY5NCwgMHgzOGQ3ZTViMiwgMHg1NzcyMDEwMSxcclxuXHRcdCAgMHg3MzBlZGViYywgMHg1YjY0MzExMywgMHg5NDkxN2U0ZiwgMHg1MDNjMmZiYSwgMHg2NDZmMTI4MiwgMHg3NTIzZDI0YSwgMHhlMDc3OTY5NSwgMHhmOWMxN2E4ZixcclxuXHRcdCAgMHg3YTViMjEyMSwgMHhkMTg3Yjg5NiwgMHgyOTI2M2E0ZCwgMHhiYTUxMGNkZiwgMHg4MWY0N2M5ZiwgMHhhZDExNjNlZCwgMHhlYTdiNTk2NSwgMHgxYTAwNzI2ZSxcclxuXHRcdCAgMHgxMTQwMzA5MiwgMHgwMGRhNmQ3NywgMHg0YTBjZGQ2MSwgMHhhZDFmNDYwMywgMHg2MDViZGZiMCwgMHg5ZWVkYzM2NCwgMHgyMmViZTZhOCwgMHhjZWU3ZDI4YSxcclxuXHRcdCAgMHhhMGU3MzZhMCwgMHg1NTY0YTZiOSwgMHgxMDg1MzIwOSwgMHhjN2ViOGYzNywgMHgyZGU3MDVjYSwgMHg4OTUxNTcwZiwgMHhkZjA5ODIyYiwgMHhiZDY5MWE2YyxcclxuXHRcdCAgMHhhYTEyZTRmMiwgMHg4NzQ1MWMwZiwgMHhlMGY2YTI3YSwgMHgzYWRhNDgxOSwgMHg0Y2YxNzY0ZiwgMHgwZDc3MWMyYiwgMHg2N2NkYjE1NiwgMHgzNTBkODM4NCxcclxuXHRcdCAgMHg1OTM4ZmEwZiwgMHg0MjM5OWVmMywgMHgzNjk5N2IwNywgMHgwZTg0MDkzZCwgMHg0YWE5M2U2MSwgMHg4MzYwZDg3YiwgMHgxZmE5OGIwYywgMHgxMTQ5MzgyYyxcclxuXHRcdCAgMHhlOTc2MjVhNSwgMHgwNjE0ZDFiNywgMHgwZTI1MjQ0YiwgMHgwYzc2ODM0NywgMHg1ODllOGQ4MiwgMHgwZDIwNTlkMSwgMHhhNDY2YmIxZSwgMHhmOGRhMGE4MixcclxuXHRcdCAgMHgwNGYxOTEzMCwgMHhiYTZlNGVjMCwgMHg5OTI2NTE2NCwgMHgxZWU3MjMwZCwgMHg1MGIyYWQ4MCwgMHhlYWVlNjgwMSwgMHg4ZGIyYTI4MywgMHhlYThiZjU5ZSk7XHJcblxyXG59O1xyXG5cclxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XHJcblxyXG5mdW5jdGlvbiBjYXN0NShrZXkpIHtcclxuXHR0aGlzLmNhc3Q1ID0gbmV3IG9wZW5wZ3Bfc3ltZW5jX2Nhc3Q1KCk7XHJcblx0dGhpcy5jYXN0NS5zZXRLZXkodXRpbC5zdHIyYmluKGtleSkpO1xyXG5cclxuXHR0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaykge1xyXG5cdFx0cmV0dXJuIHRoaXMuY2FzdDUuZW5jcnlwdChibG9jayk7XHJcblx0fVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNhc3Q1O1xyXG5tb2R1bGUuZXhwb3J0cy5ibG9ja1NpemUgPSBjYXN0NS5wcm90b3R5cGUuYmxvY2tTaXplID0gODtcclxubW9kdWxlLmV4cG9ydHMua2V5U2l6ZSA9IGNhc3Q1LnByb3RvdHlwZS5rZXlTaXplID0gMTY7XHJcbiIsIi8vUGF1bCBUZXJvLCBKdWx5IDIwMDFcbi8vaHR0cDovL3d3dy50ZXJvLmNvLnVrL2Rlcy9cbi8vXG4vL09wdGltaXNlZCBmb3IgcGVyZm9ybWFuY2Ugd2l0aCBsYXJnZSBibG9ja3MgYnkgTWljaGFlbCBIYXl3b3J0aCwgTm92ZW1iZXIgMjAwMVxuLy9odHRwOi8vd3d3Lm5ldGRlYWxpbmcuY29tXG4vL1xuLy8gTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIXG5cbi8vVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EXG4vL0FOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRVxuLy9JTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRVxuLy9BUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRVxuLy9GT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTFxuLy9EQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EU1xuLy9PUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTilcbi8vSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1Rcbi8vTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWVxuLy9PVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GXG4vL1NVQ0ggREFNQUdFLlxuXG4vL2Rlc1xuLy90aGlzIHRha2VzIHRoZSBrZXksIHRoZSBtZXNzYWdlLCBhbmQgd2hldGhlciB0byBlbmNyeXB0IG9yIGRlY3J5cHRcblxuXG5cblxuZnVuY3Rpb24gZGVzIChrZXlzLCBtZXNzYWdlLCBlbmNyeXB0LCBtb2RlLCBpdiwgcGFkZGluZykge1xuICAvL2RlY2xhcmluZyB0aGlzIGxvY2FsbHkgc3BlZWRzIHRoaW5ncyB1cCBhIGJpdFxuICB2YXIgc3BmdW5jdGlvbjEgPSBuZXcgQXJyYXkgKDB4MTAxMDQwMCwwLDB4MTAwMDAsMHgxMDEwNDA0LDB4MTAxMDAwNCwweDEwNDA0LDB4NCwweDEwMDAwLDB4NDAwLDB4MTAxMDQwMCwweDEwMTA0MDQsMHg0MDAsMHgxMDAwNDA0LDB4MTAxMDAwNCwweDEwMDAwMDAsMHg0LDB4NDA0LDB4MTAwMDQwMCwweDEwMDA0MDAsMHgxMDQwMCwweDEwNDAwLDB4MTAxMDAwMCwweDEwMTAwMDAsMHgxMDAwNDA0LDB4MTAwMDQsMHgxMDAwMDA0LDB4MTAwMDAwNCwweDEwMDA0LDAsMHg0MDQsMHgxMDQwNCwweDEwMDAwMDAsMHgxMDAwMCwweDEwMTA0MDQsMHg0LDB4MTAxMDAwMCwweDEwMTA0MDAsMHgxMDAwMDAwLDB4MTAwMDAwMCwweDQwMCwweDEwMTAwMDQsMHgxMDAwMCwweDEwNDAwLDB4MTAwMDAwNCwweDQwMCwweDQsMHgxMDAwNDA0LDB4MTA0MDQsMHgxMDEwNDA0LDB4MTAwMDQsMHgxMDEwMDAwLDB4MTAwMDQwNCwweDEwMDAwMDQsMHg0MDQsMHgxMDQwNCwweDEwMTA0MDAsMHg0MDQsMHgxMDAwNDAwLDB4MTAwMDQwMCwwLDB4MTAwMDQsMHgxMDQwMCwwLDB4MTAxMDAwNCk7XG4gIHZhciBzcGZ1bmN0aW9uMiA9IG5ldyBBcnJheSAoLTB4N2ZlZjdmZTAsLTB4N2ZmZjgwMDAsMHg4MDAwLDB4MTA4MDIwLDB4MTAwMDAwLDB4MjAsLTB4N2ZlZmZmZTAsLTB4N2ZmZjdmZTAsLTB4N2ZmZmZmZTAsLTB4N2ZlZjdmZTAsLTB4N2ZlZjgwMDAsLTB4ODAwMDAwMDAsLTB4N2ZmZjgwMDAsMHgxMDAwMDAsMHgyMCwtMHg3ZmVmZmZlMCwweDEwODAwMCwweDEwMDAyMCwtMHg3ZmZmN2ZlMCwwLC0weDgwMDAwMDAwLDB4ODAwMCwweDEwODAyMCwtMHg3ZmYwMDAwMCwweDEwMDAyMCwtMHg3ZmZmZmZlMCwwLDB4MTA4MDAwLDB4ODAyMCwtMHg3ZmVmODAwMCwtMHg3ZmYwMDAwMCwweDgwMjAsMCwweDEwODAyMCwtMHg3ZmVmZmZlMCwweDEwMDAwMCwtMHg3ZmZmN2ZlMCwtMHg3ZmYwMDAwMCwtMHg3ZmVmODAwMCwweDgwMDAsLTB4N2ZmMDAwMDAsLTB4N2ZmZjgwMDAsMHgyMCwtMHg3ZmVmN2ZlMCwweDEwODAyMCwweDIwLDB4ODAwMCwtMHg4MDAwMDAwMCwweDgwMjAsLTB4N2ZlZjgwMDAsMHgxMDAwMDAsLTB4N2ZmZmZmZTAsMHgxMDAwMjAsLTB4N2ZmZjdmZTAsLTB4N2ZmZmZmZTAsMHgxMDAwMjAsMHgxMDgwMDAsMCwtMHg3ZmZmODAwMCwweDgwMjAsLTB4ODAwMDAwMDAsLTB4N2ZlZmZmZTAsLTB4N2ZlZjdmZTAsMHgxMDgwMDApO1xuICB2YXIgc3BmdW5jdGlvbjMgPSBuZXcgQXJyYXkgKDB4MjA4LDB4ODAyMDIwMCwwLDB4ODAyMDAwOCwweDgwMDAyMDAsMCwweDIwMjA4LDB4ODAwMDIwMCwweDIwMDA4LDB4ODAwMDAwOCwweDgwMDAwMDgsMHgyMDAwMCwweDgwMjAyMDgsMHgyMDAwOCwweDgwMjAwMDAsMHgyMDgsMHg4MDAwMDAwLDB4OCwweDgwMjAyMDAsMHgyMDAsMHgyMDIwMCwweDgwMjAwMDAsMHg4MDIwMDA4LDB4MjAyMDgsMHg4MDAwMjA4LDB4MjAyMDAsMHgyMDAwMCwweDgwMDAyMDgsMHg4LDB4ODAyMDIwOCwweDIwMCwweDgwMDAwMDAsMHg4MDIwMjAwLDB4ODAwMDAwMCwweDIwMDA4LDB4MjA4LDB4MjAwMDAsMHg4MDIwMjAwLDB4ODAwMDIwMCwwLDB4MjAwLDB4MjAwMDgsMHg4MDIwMjA4LDB4ODAwMDIwMCwweDgwMDAwMDgsMHgyMDAsMCwweDgwMjAwMDgsMHg4MDAwMjA4LDB4MjAwMDAsMHg4MDAwMDAwLDB4ODAyMDIwOCwweDgsMHgyMDIwOCwweDIwMjAwLDB4ODAwMDAwOCwweDgwMjAwMDAsMHg4MDAwMjA4LDB4MjA4LDB4ODAyMDAwMCwweDIwMjA4LDB4OCwweDgwMjAwMDgsMHgyMDIwMCk7XG4gIHZhciBzcGZ1bmN0aW9uNCA9IG5ldyBBcnJheSAoMHg4MDIwMDEsMHgyMDgxLDB4MjA4MSwweDgwLDB4ODAyMDgwLDB4ODAwMDgxLDB4ODAwMDAxLDB4MjAwMSwwLDB4ODAyMDAwLDB4ODAyMDAwLDB4ODAyMDgxLDB4ODEsMCwweDgwMDA4MCwweDgwMDAwMSwweDEsMHgyMDAwLDB4ODAwMDAwLDB4ODAyMDAxLDB4ODAsMHg4MDAwMDAsMHgyMDAxLDB4MjA4MCwweDgwMDA4MSwweDEsMHgyMDgwLDB4ODAwMDgwLDB4MjAwMCwweDgwMjA4MCwweDgwMjA4MSwweDgxLDB4ODAwMDgwLDB4ODAwMDAxLDB4ODAyMDAwLDB4ODAyMDgxLDB4ODEsMCwwLDB4ODAyMDAwLDB4MjA4MCwweDgwMDA4MCwweDgwMDA4MSwweDEsMHg4MDIwMDEsMHgyMDgxLDB4MjA4MSwweDgwLDB4ODAyMDgxLDB4ODEsMHgxLDB4MjAwMCwweDgwMDAwMSwweDIwMDEsMHg4MDIwODAsMHg4MDAwODEsMHgyMDAxLDB4MjA4MCwweDgwMDAwMCwweDgwMjAwMSwweDgwLDB4ODAwMDAwLDB4MjAwMCwweDgwMjA4MCk7XG4gIHZhciBzcGZ1bmN0aW9uNSA9IG5ldyBBcnJheSAoMHgxMDAsMHgyMDgwMTAwLDB4MjA4MDAwMCwweDQyMDAwMTAwLDB4ODAwMDAsMHgxMDAsMHg0MDAwMDAwMCwweDIwODAwMDAsMHg0MDA4MDEwMCwweDgwMDAwLDB4MjAwMDEwMCwweDQwMDgwMTAwLDB4NDIwMDAxMDAsMHg0MjA4MDAwMCwweDgwMTAwLDB4NDAwMDAwMDAsMHgyMDAwMDAwLDB4NDAwODAwMDAsMHg0MDA4MDAwMCwwLDB4NDAwMDAxMDAsMHg0MjA4MDEwMCwweDQyMDgwMTAwLDB4MjAwMDEwMCwweDQyMDgwMDAwLDB4NDAwMDAxMDAsMCwweDQyMDAwMDAwLDB4MjA4MDEwMCwweDIwMDAwMDAsMHg0MjAwMDAwMCwweDgwMTAwLDB4ODAwMDAsMHg0MjAwMDEwMCwweDEwMCwweDIwMDAwMDAsMHg0MDAwMDAwMCwweDIwODAwMDAsMHg0MjAwMDEwMCwweDQwMDgwMTAwLDB4MjAwMDEwMCwweDQwMDAwMDAwLDB4NDIwODAwMDAsMHgyMDgwMTAwLDB4NDAwODAxMDAsMHgxMDAsMHgyMDAwMDAwLDB4NDIwODAwMDAsMHg0MjA4MDEwMCwweDgwMTAwLDB4NDIwMDAwMDAsMHg0MjA4MDEwMCwweDIwODAwMDAsMCwweDQwMDgwMDAwLDB4NDIwMDAwMDAsMHg4MDEwMCwweDIwMDAxMDAsMHg0MDAwMDEwMCwweDgwMDAwLDAsMHg0MDA4MDAwMCwweDIwODAxMDAsMHg0MDAwMDEwMCk7XG4gIHZhciBzcGZ1bmN0aW9uNiA9IG5ldyBBcnJheSAoMHgyMDAwMDAxMCwweDIwNDAwMDAwLDB4NDAwMCwweDIwNDA0MDEwLDB4MjA0MDAwMDAsMHgxMCwweDIwNDA0MDEwLDB4NDAwMDAwLDB4MjAwMDQwMDAsMHg0MDQwMTAsMHg0MDAwMDAsMHgyMDAwMDAxMCwweDQwMDAxMCwweDIwMDA0MDAwLDB4MjAwMDAwMDAsMHg0MDEwLDAsMHg0MDAwMTAsMHgyMDAwNDAxMCwweDQwMDAsMHg0MDQwMDAsMHgyMDAwNDAxMCwweDEwLDB4MjA0MDAwMTAsMHgyMDQwMDAxMCwwLDB4NDA0MDEwLDB4MjA0MDQwMDAsMHg0MDEwLDB4NDA0MDAwLDB4MjA0MDQwMDAsMHgyMDAwMDAwMCwweDIwMDA0MDAwLDB4MTAsMHgyMDQwMDAxMCwweDQwNDAwMCwweDIwNDA0MDEwLDB4NDAwMDAwLDB4NDAxMCwweDIwMDAwMDEwLDB4NDAwMDAwLDB4MjAwMDQwMDAsMHgyMDAwMDAwMCwweDQwMTAsMHgyMDAwMDAxMCwweDIwNDA0MDEwLDB4NDA0MDAwLDB4MjA0MDAwMDAsMHg0MDQwMTAsMHgyMDQwNDAwMCwwLDB4MjA0MDAwMTAsMHgxMCwweDQwMDAsMHgyMDQwMDAwMCwweDQwNDAxMCwweDQwMDAsMHg0MDAwMTAsMHgyMDAwNDAxMCwwLDB4MjA0MDQwMDAsMHgyMDAwMDAwMCwweDQwMDAxMCwweDIwMDA0MDEwKTtcbiAgdmFyIHNwZnVuY3Rpb243ID0gbmV3IEFycmF5ICgweDIwMDAwMCwweDQyMDAwMDIsMHg0MDAwODAyLDAsMHg4MDAsMHg0MDAwODAyLDB4MjAwODAyLDB4NDIwMDgwMCwweDQyMDA4MDIsMHgyMDAwMDAsMCwweDQwMDAwMDIsMHgyLDB4NDAwMDAwMCwweDQyMDAwMDIsMHg4MDIsMHg0MDAwODAwLDB4MjAwODAyLDB4MjAwMDAyLDB4NDAwMDgwMCwweDQwMDAwMDIsMHg0MjAwMDAwLDB4NDIwMDgwMCwweDIwMDAwMiwweDQyMDAwMDAsMHg4MDAsMHg4MDIsMHg0MjAwODAyLDB4MjAwODAwLDB4MiwweDQwMDAwMDAsMHgyMDA4MDAsMHg0MDAwMDAwLDB4MjAwODAwLDB4MjAwMDAwLDB4NDAwMDgwMiwweDQwMDA4MDIsMHg0MjAwMDAyLDB4NDIwMDAwMiwweDIsMHgyMDAwMDIsMHg0MDAwMDAwLDB4NDAwMDgwMCwweDIwMDAwMCwweDQyMDA4MDAsMHg4MDIsMHgyMDA4MDIsMHg0MjAwODAwLDB4ODAyLDB4NDAwMDAwMiwweDQyMDA4MDIsMHg0MjAwMDAwLDB4MjAwODAwLDAsMHgyLDB4NDIwMDgwMiwwLDB4MjAwODAyLDB4NDIwMDAwMCwweDgwMCwweDQwMDAwMDIsMHg0MDAwODAwLDB4ODAwLDB4MjAwMDAyKTtcbiAgdmFyIHNwZnVuY3Rpb244ID0gbmV3IEFycmF5ICgweDEwMDAxMDQwLDB4MTAwMCwweDQwMDAwLDB4MTAwNDEwNDAsMHgxMDAwMDAwMCwweDEwMDAxMDQwLDB4NDAsMHgxMDAwMDAwMCwweDQwMDQwLDB4MTAwNDAwMDAsMHgxMDA0MTA0MCwweDQxMDAwLDB4MTAwNDEwMDAsMHg0MTA0MCwweDEwMDAsMHg0MCwweDEwMDQwMDAwLDB4MTAwMDAwNDAsMHgxMDAwMTAwMCwweDEwNDAsMHg0MTAwMCwweDQwMDQwLDB4MTAwNDAwNDAsMHgxMDA0MTAwMCwweDEwNDAsMCwwLDB4MTAwNDAwNDAsMHgxMDAwMDA0MCwweDEwMDAxMDAwLDB4NDEwNDAsMHg0MDAwMCwweDQxMDQwLDB4NDAwMDAsMHgxMDA0MTAwMCwweDEwMDAsMHg0MCwweDEwMDQwMDQwLDB4MTAwMCwweDQxMDQwLDB4MTAwMDEwMDAsMHg0MCwweDEwMDAwMDQwLDB4MTAwNDAwMDAsMHgxMDA0MDA0MCwweDEwMDAwMDAwLDB4NDAwMDAsMHgxMDAwMTA0MCwwLDB4MTAwNDEwNDAsMHg0MDA0MCwweDEwMDAwMDQwLDB4MTAwNDAwMDAsMHgxMDAwMTAwMCwweDEwMDAxMDQwLDAsMHgxMDA0MTA0MCwweDQxMDAwLDB4NDEwMDAsMHgxMDQwLDB4MTA0MCwweDQwMDQwLDB4MTAwMDAwMDAsMHgxMDA0MTAwMCk7XG5cbiAgLy9jcmVhdGUgdGhlIDE2IG9yIDQ4IHN1YmtleXMgd2Ugd2lsbCBuZWVkXG4gIHZhciBtPTAsIGksIGosIHRlbXAsIHRlbXAyLCByaWdodDEsIHJpZ2h0MiwgbGVmdCwgcmlnaHQsIGxvb3Bpbmc7XG4gIHZhciBjYmNsZWZ0LCBjYmNsZWZ0MiwgY2JjcmlnaHQsIGNiY3JpZ2h0MlxuICB2YXIgZW5kbG9vcCwgbG9vcGluYztcbiAgdmFyIGxlbiA9IG1lc3NhZ2UubGVuZ3RoO1xuICB2YXIgY2h1bmsgPSAwO1xuICAvL3NldCB1cCB0aGUgbG9vcHMgZm9yIHNpbmdsZSBhbmQgdHJpcGxlIGRlc1xuICB2YXIgaXRlcmF0aW9ucyA9IGtleXMubGVuZ3RoID09IDMyID8gMyA6IDk7IC8vc2luZ2xlIG9yIHRyaXBsZSBkZXNcbiAgaWYgKGl0ZXJhdGlvbnMgPT0gMykge2xvb3BpbmcgPSBlbmNyeXB0ID8gbmV3IEFycmF5ICgwLCAzMiwgMikgOiBuZXcgQXJyYXkgKDMwLCAtMiwgLTIpO31cbiAgZWxzZSB7bG9vcGluZyA9IGVuY3J5cHQgPyBuZXcgQXJyYXkgKDAsIDMyLCAyLCA2MiwgMzAsIC0yLCA2NCwgOTYsIDIpIDogbmV3IEFycmF5ICg5NCwgNjIsIC0yLCAzMiwgNjQsIDIsIDMwLCAtMiwgLTIpO31cblxuICAvL3BhZCB0aGUgbWVzc2FnZSBkZXBlbmRpbmcgb24gdGhlIHBhZGRpbmcgcGFyYW1ldGVyXG4gIC8vb25seSBhZGQgcGFkZGluZyBpZiBlbmNyeXB0aW5nIC0gbm90ZSB0aGF0IHlvdSBuZWVkIHRvIHVzZSB0aGUgc2FtZSBwYWRkaW5nIG9wdGlvbiBmb3IgYm90aCBlbmNyeXB0IGFuZCBkZWNyeXB0XHJcbiAgaWYgKGVuY3J5cHQpIHtcclxuICAgIG1lc3NhZ2UgPSBkZXNfYWRkUGFkZGluZyhtZXNzYWdlLCBwYWRkaW5nKTtcclxuICAgIGxlbiA9IG1lc3NhZ2UubGVuZ3RoO1xyXG4gIH1cclxuXG4gIC8vc3RvcmUgdGhlIHJlc3VsdCBoZXJlXG4gIHJlc3VsdCA9IFwiXCI7XG4gIHRlbXByZXN1bHQgPSBcIlwiO1xuXG4gIGlmIChtb2RlID09IDEpIHsgLy9DQkMgbW9kZVxuICAgIGNiY2xlZnQgPSAoaXYuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgMTYpIHwgKGl2LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGl2LmNoYXJDb2RlQXQobSsrKTtcbiAgICBjYmNyaWdodCA9IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgMjQpIHwgKGl2LmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAoaXYuY2hhckNvZGVBdChtKyspIDw8IDgpIHwgaXYuY2hhckNvZGVBdChtKyspO1xuICAgIG09MDtcbiAgfVxuXG4gIC8vbG9vcCB0aHJvdWdoIGVhY2ggNjQgYml0IGNodW5rIG9mIHRoZSBtZXNzYWdlXG4gIHdoaWxlIChtIDwgbGVuKSB7XG4gICAgbGVmdCA9IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgMTYpIHwgKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDgpIHwgbWVzc2FnZS5jaGFyQ29kZUF0KG0rKyk7XG4gICAgcmlnaHQgPSAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgMjQpIHwgKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IG1lc3NhZ2UuY2hhckNvZGVBdChtKyspO1xuXG4gICAgLy9mb3IgQ2lwaGVyIEJsb2NrIENoYWluaW5nIG1vZGUsIHhvciB0aGUgbWVzc2FnZSB3aXRoIHRoZSBwcmV2aW91cyByZXN1bHRcbiAgICBpZiAobW9kZSA9PSAxKSB7aWYgKGVuY3J5cHQpIHtsZWZ0IF49IGNiY2xlZnQ7IHJpZ2h0IF49IGNiY3JpZ2h0O30gZWxzZSB7Y2JjbGVmdDIgPSBjYmNsZWZ0OyBjYmNyaWdodDIgPSBjYmNyaWdodDsgY2JjbGVmdCA9IGxlZnQ7IGNiY3JpZ2h0ID0gcmlnaHQ7fX1cblxuICAgIC8vZmlyc3QgZWFjaCA2NCBidXQgY2h1bmsgb2YgdGhlIG1lc3NhZ2UgbXVzdCBiZSBwZXJtdXRlZCBhY2NvcmRpbmcgdG8gSVBcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiA0KSBeIHJpZ2h0KSAmIDB4MGYwZjBmMGY7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgNCk7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMTYpIF4gcmlnaHQpICYgMHgwMDAwZmZmZjsgcmlnaHQgXj0gdGVtcDsgbGVmdCBePSAodGVtcCA8PCAxNik7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzOyBsZWZ0IF49IHRlbXA7IHJpZ2h0IF49ICh0ZW1wIDw8IDIpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiA4KSBeIGxlZnQpICYgMHgwMGZmMDBmZjsgbGVmdCBePSB0ZW1wOyByaWdodCBePSAodGVtcCA8PCA4KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgMSk7XG5cbiAgICBsZWZ0ID0gKChsZWZ0IDw8IDEpIHwgKGxlZnQgPj4+IDMxKSk7IFxuICAgIHJpZ2h0ID0gKChyaWdodCA8PCAxKSB8IChyaWdodCA+Pj4gMzEpKTsgXG5cbiAgICAvL2RvIHRoaXMgZWl0aGVyIDEgb3IgMyB0aW1lcyBmb3IgZWFjaCBjaHVuayBvZiB0aGUgbWVzc2FnZVxuICAgIGZvciAoaj0wOyBqPGl0ZXJhdGlvbnM7IGorPTMpIHtcbiAgICAgIGVuZGxvb3AgPSBsb29waW5nW2orMV07XG4gICAgICBsb29waW5jID0gbG9vcGluZ1tqKzJdO1xuICAgICAgLy9ub3cgZ28gdGhyb3VnaCBhbmQgcGVyZm9ybSB0aGUgZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uICBcbiAgICAgIGZvciAoaT1sb29waW5nW2pdOyBpIT1lbmRsb29wOyBpKz1sb29waW5jKSB7IC8vZm9yIGVmZmljaWVuY3lcbiAgICAgICAgcmlnaHQxID0gcmlnaHQgXiBrZXlzW2ldOyBcbiAgICAgICAgcmlnaHQyID0gKChyaWdodCA+Pj4gNCkgfCAocmlnaHQgPDwgMjgpKSBeIGtleXNbaSsxXTtcbiAgICAgICAgLy90aGUgcmVzdWx0IGlzIGF0dGFpbmVkIGJ5IHBhc3NpbmcgdGhlc2UgYnl0ZXMgdGhyb3VnaCB0aGUgUyBzZWxlY3Rpb24gZnVuY3Rpb25zXG4gICAgICAgIHRlbXAgPSBsZWZ0O1xuICAgICAgICBsZWZ0ID0gcmlnaHQ7XG4gICAgICAgIHJpZ2h0ID0gdGVtcCBeIChzcGZ1bmN0aW9uMlsocmlnaHQxID4+PiAyNCkgJiAweDNmXSB8IHNwZnVuY3Rpb240WyhyaWdodDEgPj4+IDE2KSAmIDB4M2ZdXG4gICAgICAgICAgICAgIHwgc3BmdW5jdGlvbjZbKHJpZ2h0MSA+Pj4gIDgpICYgMHgzZl0gfCBzcGZ1bmN0aW9uOFtyaWdodDEgJiAweDNmXVxuICAgICAgICAgICAgICB8IHNwZnVuY3Rpb24xWyhyaWdodDIgPj4+IDI0KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjNbKHJpZ2h0MiA+Pj4gMTYpICYgMHgzZl1cbiAgICAgICAgICAgICAgfCBzcGZ1bmN0aW9uNVsocmlnaHQyID4+PiAgOCkgJiAweDNmXSB8IHNwZnVuY3Rpb243W3JpZ2h0MiAmIDB4M2ZdKTtcbiAgICAgIH1cbiAgICAgIHRlbXAgPSBsZWZ0OyBsZWZ0ID0gcmlnaHQ7IHJpZ2h0ID0gdGVtcDsgLy91bnJldmVyc2UgbGVmdCBhbmQgcmlnaHRcbiAgICB9IC8vZm9yIGVpdGhlciAxIG9yIDMgaXRlcmF0aW9uc1xuXG4gICAgLy9tb3ZlIHRoZW4gZWFjaCBvbmUgYml0IHRvIHRoZSByaWdodFxuICAgIGxlZnQgPSAoKGxlZnQgPj4+IDEpIHwgKGxlZnQgPDwgMzEpKTsgXG4gICAgcmlnaHQgPSAoKHJpZ2h0ID4+PiAxKSB8IChyaWdodCA8PCAzMSkpOyBcblxuICAgIC8vbm93IHBlcmZvcm0gSVAtMSwgd2hpY2ggaXMgSVAgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvblxuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDEpIF4gcmlnaHQpICYgMHg1NTU1NTU1NTsgcmlnaHQgXj0gdGVtcDsgbGVmdCBePSAodGVtcCA8PCAxKTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7IGxlZnQgXj0gdGVtcDsgcmlnaHQgXj0gKHRlbXAgPDwgOCk7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzOyBsZWZ0IF49IHRlbXA7IHJpZ2h0IF49ICh0ZW1wIDw8IDIpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDE2KSBeIHJpZ2h0KSAmIDB4MDAwMGZmZmY7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgMTYpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDQpIF4gcmlnaHQpICYgMHgwZjBmMGYwZjsgcmlnaHQgXj0gdGVtcDsgbGVmdCBePSAodGVtcCA8PCA0KTtcblxuICAgIC8vZm9yIENpcGhlciBCbG9jayBDaGFpbmluZyBtb2RlLCB4b3IgdGhlIG1lc3NhZ2Ugd2l0aCB0aGUgcHJldmlvdXMgcmVzdWx0XG4gICAgaWYgKG1vZGUgPT0gMSkge2lmIChlbmNyeXB0KSB7Y2JjbGVmdCA9IGxlZnQ7IGNiY3JpZ2h0ID0gcmlnaHQ7fSBlbHNlIHtsZWZ0IF49IGNiY2xlZnQyOyByaWdodCBePSBjYmNyaWdodDI7fX1cbiAgICB0ZW1wcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUgKChsZWZ0Pj4+MjQpLCAoKGxlZnQ+Pj4xNikgJiAweGZmKSwgKChsZWZ0Pj4+OCkgJiAweGZmKSwgKGxlZnQgJiAweGZmKSwgKHJpZ2h0Pj4+MjQpLCAoKHJpZ2h0Pj4+MTYpICYgMHhmZiksICgocmlnaHQ+Pj44KSAmIDB4ZmYpLCAocmlnaHQgJiAweGZmKSk7XG5cbiAgICBjaHVuayArPSA4O1xuICAgIGlmIChjaHVuayA9PSA1MTIpIHtyZXN1bHQgKz0gdGVtcHJlc3VsdDsgdGVtcHJlc3VsdCA9IFwiXCI7IGNodW5rID0gMDt9XG4gIH0gLy9mb3IgZXZlcnkgOCBjaGFyYWN0ZXJzLCBvciA2NCBiaXRzIGluIHRoZSBtZXNzYWdlXG5cbiAgLy9yZXR1cm4gdGhlIHJlc3VsdCBhcyBhbiBhcnJheVxuICByZXN1bHQgKz0gdGVtcHJlc3VsdDtcbiAgICBcclxuICAvL29ubHkgcmVtb3ZlIHBhZGRpbmcgaWYgZGVjcnlwdGluZyAtIG5vdGUgdGhhdCB5b3UgbmVlZCB0byB1c2UgdGhlIHNhbWUgcGFkZGluZyBvcHRpb24gZm9yIGJvdGggZW5jcnlwdCBhbmQgZGVjcnlwdFxyXG4gIGlmICghZW5jcnlwdCkge1xyXG4gICAgcmVzdWx0ID0gZGVzX3JlbW92ZVBhZGRpbmcocmVzdWx0LCBwYWRkaW5nKTtcclxuICB9XHJcblxyXG4gIHJldHVybiByZXN1bHQ7XG59IC8vZW5kIG9mIGRlc1xuXG5cblxuLy9kZXNfY3JlYXRlS2V5c1xuLy90aGlzIHRha2VzIGFzIGlucHV0IGEgNjQgYml0IGtleSAoZXZlbiB0aG91Z2ggb25seSA1NiBiaXRzIGFyZSB1c2VkKVxuLy9hcyBhbiBhcnJheSBvZiAyIGludGVnZXJzLCBhbmQgcmV0dXJucyAxNiA0OCBiaXQga2V5c1xuZnVuY3Rpb24gZGVzX2NyZWF0ZUtleXMgKGtleSkge1xuICAvL2RlY2xhcmluZyB0aGlzIGxvY2FsbHkgc3BlZWRzIHRoaW5ncyB1cCBhIGJpdFxuICBwYzJieXRlczAgID0gbmV3IEFycmF5ICgwLDB4NCwweDIwMDAwMDAwLDB4MjAwMDAwMDQsMHgxMDAwMCwweDEwMDA0LDB4MjAwMTAwMDAsMHgyMDAxMDAwNCwweDIwMCwweDIwNCwweDIwMDAwMjAwLDB4MjAwMDAyMDQsMHgxMDIwMCwweDEwMjA0LDB4MjAwMTAyMDAsMHgyMDAxMDIwNCk7XG4gIHBjMmJ5dGVzMSAgPSBuZXcgQXJyYXkgKDAsMHgxLDB4MTAwMDAwLDB4MTAwMDAxLDB4NDAwMDAwMCwweDQwMDAwMDEsMHg0MTAwMDAwLDB4NDEwMDAwMSwweDEwMCwweDEwMSwweDEwMDEwMCwweDEwMDEwMSwweDQwMDAxMDAsMHg0MDAwMTAxLDB4NDEwMDEwMCwweDQxMDAxMDEpO1xuICBwYzJieXRlczIgID0gbmV3IEFycmF5ICgwLDB4OCwweDgwMCwweDgwOCwweDEwMDAwMDAsMHgxMDAwMDA4LDB4MTAwMDgwMCwweDEwMDA4MDgsMCwweDgsMHg4MDAsMHg4MDgsMHgxMDAwMDAwLDB4MTAwMDAwOCwweDEwMDA4MDAsMHgxMDAwODA4KTtcbiAgcGMyYnl0ZXMzICA9IG5ldyBBcnJheSAoMCwweDIwMDAwMCwweDgwMDAwMDAsMHg4MjAwMDAwLDB4MjAwMCwweDIwMjAwMCwweDgwMDIwMDAsMHg4MjAyMDAwLDB4MjAwMDAsMHgyMjAwMDAsMHg4MDIwMDAwLDB4ODIyMDAwMCwweDIyMDAwLDB4MjIyMDAwLDB4ODAyMjAwMCwweDgyMjIwMDApO1xuICBwYzJieXRlczQgID0gbmV3IEFycmF5ICgwLDB4NDAwMDAsMHgxMCwweDQwMDEwLDAsMHg0MDAwMCwweDEwLDB4NDAwMTAsMHgxMDAwLDB4NDEwMDAsMHgxMDEwLDB4NDEwMTAsMHgxMDAwLDB4NDEwMDAsMHgxMDEwLDB4NDEwMTApO1xuICBwYzJieXRlczUgID0gbmV3IEFycmF5ICgwLDB4NDAwLDB4MjAsMHg0MjAsMCwweDQwMCwweDIwLDB4NDIwLDB4MjAwMDAwMCwweDIwMDA0MDAsMHgyMDAwMDIwLDB4MjAwMDQyMCwweDIwMDAwMDAsMHgyMDAwNDAwLDB4MjAwMDAyMCwweDIwMDA0MjApO1xuICBwYzJieXRlczYgID0gbmV3IEFycmF5ICgwLDB4MTAwMDAwMDAsMHg4MDAwMCwweDEwMDgwMDAwLDB4MiwweDEwMDAwMDAyLDB4ODAwMDIsMHgxMDA4MDAwMiwwLDB4MTAwMDAwMDAsMHg4MDAwMCwweDEwMDgwMDAwLDB4MiwweDEwMDAwMDAyLDB4ODAwMDIsMHgxMDA4MDAwMik7XG4gIHBjMmJ5dGVzNyAgPSBuZXcgQXJyYXkgKDAsMHgxMDAwMCwweDgwMCwweDEwODAwLDB4MjAwMDAwMDAsMHgyMDAxMDAwMCwweDIwMDAwODAwLDB4MjAwMTA4MDAsMHgyMDAwMCwweDMwMDAwLDB4MjA4MDAsMHgzMDgwMCwweDIwMDIwMDAwLDB4MjAwMzAwMDAsMHgyMDAyMDgwMCwweDIwMDMwODAwKTtcbiAgcGMyYnl0ZXM4ICA9IG5ldyBBcnJheSAoMCwweDQwMDAwLDAsMHg0MDAwMCwweDIsMHg0MDAwMiwweDIsMHg0MDAwMiwweDIwMDAwMDAsMHgyMDQwMDAwLDB4MjAwMDAwMCwweDIwNDAwMDAsMHgyMDAwMDAyLDB4MjA0MDAwMiwweDIwMDAwMDIsMHgyMDQwMDAyKTtcbiAgcGMyYnl0ZXM5ICA9IG5ldyBBcnJheSAoMCwweDEwMDAwMDAwLDB4OCwweDEwMDAwMDA4LDAsMHgxMDAwMDAwMCwweDgsMHgxMDAwMDAwOCwweDQwMCwweDEwMDAwNDAwLDB4NDA4LDB4MTAwMDA0MDgsMHg0MDAsMHgxMDAwMDQwMCwweDQwOCwweDEwMDAwNDA4KTtcbiAgcGMyYnl0ZXMxMCA9IG5ldyBBcnJheSAoMCwweDIwLDAsMHgyMCwweDEwMDAwMCwweDEwMDAyMCwweDEwMDAwMCwweDEwMDAyMCwweDIwMDAsMHgyMDIwLDB4MjAwMCwweDIwMjAsMHgxMDIwMDAsMHgxMDIwMjAsMHgxMDIwMDAsMHgxMDIwMjApO1xuICBwYzJieXRlczExID0gbmV3IEFycmF5ICgwLDB4MTAwMDAwMCwweDIwMCwweDEwMDAyMDAsMHgyMDAwMDAsMHgxMjAwMDAwLDB4MjAwMjAwLDB4MTIwMDIwMCwweDQwMDAwMDAsMHg1MDAwMDAwLDB4NDAwMDIwMCwweDUwMDAyMDAsMHg0MjAwMDAwLDB4NTIwMDAwMCwweDQyMDAyMDAsMHg1MjAwMjAwKTtcbiAgcGMyYnl0ZXMxMiA9IG5ldyBBcnJheSAoMCwweDEwMDAsMHg4MDAwMDAwLDB4ODAwMTAwMCwweDgwMDAwLDB4ODEwMDAsMHg4MDgwMDAwLDB4ODA4MTAwMCwweDEwLDB4MTAxMCwweDgwMDAwMTAsMHg4MDAxMDEwLDB4ODAwMTAsMHg4MTAxMCwweDgwODAwMTAsMHg4MDgxMDEwKTtcbiAgcGMyYnl0ZXMxMyA9IG5ldyBBcnJheSAoMCwweDQsMHgxMDAsMHgxMDQsMCwweDQsMHgxMDAsMHgxMDQsMHgxLDB4NSwweDEwMSwweDEwNSwweDEsMHg1LDB4MTAxLDB4MTA1KTtcblxuICAvL2hvdyBtYW55IGl0ZXJhdGlvbnMgKDEgZm9yIGRlcywgMyBmb3IgdHJpcGxlIGRlcylcbiAgdmFyIGl0ZXJhdGlvbnMgPSBrZXkubGVuZ3RoID4gOCA/IDMgOiAxOyAvL2NoYW5nZWQgYnkgUGF1bCAxNi82LzIwMDcgdG8gdXNlIFRyaXBsZSBERVMgZm9yIDkrIGJ5dGUga2V5c1xuICAvL3N0b3JlcyB0aGUgcmV0dXJuIGtleXNcbiAgdmFyIGtleXMgPSBuZXcgQXJyYXkgKDMyICogaXRlcmF0aW9ucyk7XG4gIC8vbm93IGRlZmluZSB0aGUgbGVmdCBzaGlmdHMgd2hpY2ggbmVlZCB0byBiZSBkb25lXG4gIHZhciBzaGlmdHMgPSBuZXcgQXJyYXkgKDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDApO1xuICAvL290aGVyIHZhcmlhYmxlc1xuICB2YXIgbGVmdHRlbXAsIHJpZ2h0dGVtcCwgbT0wLCBuPTAsIHRlbXA7XG5cbiAgZm9yICh2YXIgaj0wOyBqPGl0ZXJhdGlvbnM7IGorKykgeyAvL2VpdGhlciAxIG9yIDMgaXRlcmF0aW9uc1xuICAgIGxlZnQgPSAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGtleS5jaGFyQ29kZUF0KG0rKyk7XG4gICAgcmlnaHQgPSAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAyNCkgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAoa2V5LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGtleS5jaGFyQ29kZUF0KG0rKyk7XG5cbiAgICB0ZW1wID0gKChsZWZ0ID4+PiA0KSBeIHJpZ2h0KSAmIDB4MGYwZjBmMGY7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgNCk7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IC0xNikgXiBsZWZ0KSAmIDB4MDAwMGZmZmY7IGxlZnQgXj0gdGVtcDsgcmlnaHQgXj0gKHRlbXAgPDwgLTE2KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAyKSBeIHJpZ2h0KSAmIDB4MzMzMzMzMzM7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgMik7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IC0xNikgXiBsZWZ0KSAmIDB4MDAwMGZmZmY7IGxlZnQgXj0gdGVtcDsgcmlnaHQgXj0gKHRlbXAgPDwgLTE2KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7IHJpZ2h0IF49IHRlbXA7IGxlZnQgXj0gKHRlbXAgPDwgMSk7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmOyBsZWZ0IF49IHRlbXA7IHJpZ2h0IF49ICh0ZW1wIDw8IDgpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDEpIF4gcmlnaHQpICYgMHg1NTU1NTU1NTsgcmlnaHQgXj0gdGVtcDsgbGVmdCBePSAodGVtcCA8PCAxKTtcblxuICAgIC8vdGhlIHJpZ2h0IHNpZGUgbmVlZHMgdG8gYmUgc2hpZnRlZCBhbmQgdG8gZ2V0IHRoZSBsYXN0IGZvdXIgYml0cyBvZiB0aGUgbGVmdCBzaWRlXG4gICAgdGVtcCA9IChsZWZ0IDw8IDgpIHwgKChyaWdodCA+Pj4gMjApICYgMHgwMDAwMDBmMCk7XG4gICAgLy9sZWZ0IG5lZWRzIHRvIGJlIHB1dCB1cHNpZGUgZG93blxuICAgIGxlZnQgPSAocmlnaHQgPDwgMjQpIHwgKChyaWdodCA8PCA4KSAmIDB4ZmYwMDAwKSB8ICgocmlnaHQgPj4+IDgpICYgMHhmZjAwKSB8ICgocmlnaHQgPj4+IDI0KSAmIDB4ZjApO1xuICAgIHJpZ2h0ID0gdGVtcDtcblxuICAgIC8vbm93IGdvIHRocm91Z2ggYW5kIHBlcmZvcm0gdGhlc2Ugc2hpZnRzIG9uIHRoZSBsZWZ0IGFuZCByaWdodCBrZXlzXG4gICAgZm9yIChpPTA7IGkgPCBzaGlmdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIC8vc2hpZnQgdGhlIGtleXMgZWl0aGVyIG9uZSBvciB0d28gYml0cyB0byB0aGUgbGVmdFxuICAgICAgaWYgKHNoaWZ0c1tpXSkge2xlZnQgPSAobGVmdCA8PCAyKSB8IChsZWZ0ID4+PiAyNik7IHJpZ2h0ID0gKHJpZ2h0IDw8IDIpIHwgKHJpZ2h0ID4+PiAyNik7fVxuICAgICAgZWxzZSB7bGVmdCA9IChsZWZ0IDw8IDEpIHwgKGxlZnQgPj4+IDI3KTsgcmlnaHQgPSAocmlnaHQgPDwgMSkgfCAocmlnaHQgPj4+IDI3KTt9XG4gICAgICBsZWZ0ICY9IC0weGY7IHJpZ2h0ICY9IC0weGY7XG5cbiAgICAgIC8vbm93IGFwcGx5IFBDLTIsIGluIHN1Y2ggYSB3YXkgdGhhdCBFIGlzIGVhc2llciB3aGVuIGVuY3J5cHRpbmcgb3IgZGVjcnlwdGluZ1xuICAgICAgLy90aGlzIGNvbnZlcnNpb24gd2lsbCBsb29rIGxpa2UgUEMtMiBleGNlcHQgb25seSB0aGUgbGFzdCA2IGJpdHMgb2YgZWFjaCBieXRlIGFyZSB1c2VkXG4gICAgICAvL3JhdGhlciB0aGFuIDQ4IGNvbnNlY3V0aXZlIGJpdHMgYW5kIHRoZSBvcmRlciBvZiBsaW5lcyB3aWxsIGJlIGFjY29yZGluZyB0byBcbiAgICAgIC8vaG93IHRoZSBTIHNlbGVjdGlvbiBmdW5jdGlvbnMgd2lsbCBiZSBhcHBsaWVkOiBTMiwgUzQsIFM2LCBTOCwgUzEsIFMzLCBTNSwgUzdcbiAgICAgIGxlZnR0ZW1wID0gcGMyYnl0ZXMwW2xlZnQgPj4+IDI4XSB8IHBjMmJ5dGVzMVsobGVmdCA+Pj4gMjQpICYgMHhmXVxuICAgICAgICAgICAgICB8IHBjMmJ5dGVzMlsobGVmdCA+Pj4gMjApICYgMHhmXSB8IHBjMmJ5dGVzM1sobGVmdCA+Pj4gMTYpICYgMHhmXVxuICAgICAgICAgICAgICB8IHBjMmJ5dGVzNFsobGVmdCA+Pj4gMTIpICYgMHhmXSB8IHBjMmJ5dGVzNVsobGVmdCA+Pj4gOCkgJiAweGZdXG4gICAgICAgICAgICAgIHwgcGMyYnl0ZXM2WyhsZWZ0ID4+PiA0KSAmIDB4Zl07XG4gICAgICByaWdodHRlbXAgPSBwYzJieXRlczdbcmlnaHQgPj4+IDI4XSB8IHBjMmJ5dGVzOFsocmlnaHQgPj4+IDI0KSAmIDB4Zl1cbiAgICAgICAgICAgICAgICB8IHBjMmJ5dGVzOVsocmlnaHQgPj4+IDIwKSAmIDB4Zl0gfCBwYzJieXRlczEwWyhyaWdodCA+Pj4gMTYpICYgMHhmXVxuICAgICAgICAgICAgICAgIHwgcGMyYnl0ZXMxMVsocmlnaHQgPj4+IDEyKSAmIDB4Zl0gfCBwYzJieXRlczEyWyhyaWdodCA+Pj4gOCkgJiAweGZdXG4gICAgICAgICAgICAgICAgfCBwYzJieXRlczEzWyhyaWdodCA+Pj4gNCkgJiAweGZdO1xuICAgICAgdGVtcCA9ICgocmlnaHR0ZW1wID4+PiAxNikgXiBsZWZ0dGVtcCkgJiAweDAwMDBmZmZmOyBcbiAgICAgIGtleXNbbisrXSA9IGxlZnR0ZW1wIF4gdGVtcDsga2V5c1tuKytdID0gcmlnaHR0ZW1wIF4gKHRlbXAgPDwgMTYpO1xuICAgIH1cbiAgfSAvL2ZvciBlYWNoIGl0ZXJhdGlvbnNcbiAgLy9yZXR1cm4gdGhlIGtleXMgd2UndmUgY3JlYXRlZFxuICByZXR1cm4ga2V5cztcbn0gLy9lbmQgb2YgZGVzX2NyZWF0ZUtleXNcblxuXHJcbmZ1bmN0aW9uIGRlc19hZGRQYWRkaW5nKG1lc3NhZ2UsIHBhZGRpbmcpIHtcclxuICAgIHZhciBwYWRMZW5ndGggPSA4IC0gKG1lc3NhZ2UubGVuZ3RoICUgOCk7XHJcbiAgICBpZiAoKHBhZGRpbmcgPT0gMikgJiYgKHBhZExlbmd0aCA8IDgpKSB7ICAgICAgICAgICAgLy9wYWQgdGhlIG1lc3NhZ2Ugd2l0aCBzcGFjZXNcclxuICAgICAgICBtZXNzYWdlICs9IFwiICAgICAgICBcIi5zdWJzdHIoMCwgcGFkTGVuZ3RoKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHBhZGRpbmcgPT0gMSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1BLQ1M3IHBhZGRpbmdcclxuICAgICAgICBtZXNzYWdlICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocGFkTGVuZ3RoLCBwYWRMZW5ndGgsIHBhZExlbmd0aCwgcGFkTGVuZ3RoLCBwYWRMZW5ndGgsIHBhZExlbmd0aCwgcGFkTGVuZ3RoLCBwYWRMZW5ndGgpLnN1YnN0cigwLCBwYWRMZW5ndGgpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoIXBhZGRpbmcgJiYgKHBhZExlbmd0aCA8IDgpKSB7ICAgICAgICAgICAgIC8vcGFkIHRoZSBtZXNzYWdlIG91dCB3aXRoIG51bGwgYnl0ZXNcclxuICAgICAgICBtZXNzYWdlICs9IFwiXFwwXFwwXFwwXFwwXFwwXFwwXFwwXFwwXCIuc3Vic3RyKDAsIHBhZExlbmd0aCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbWVzc2FnZTtcclxufVxyXG5cclxuZnVuY3Rpb24gZGVzX3JlbW92ZVBhZGRpbmcobWVzc2FnZSwgcGFkZGluZykge1xyXG4gICAgaWYgKHBhZGRpbmcgPT0gMikgeyAgICAgICAgIC8vIHNwYWNlIHBhZGRlZFxyXG4gICAgICAgIG1lc3NhZ2UgPSBtZXNzYWdlLnJlcGxhY2UoLyAqJC9nLCBcIlwiKTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKHBhZGRpbmcgPT0gMSkgeyAgICAvLyBQS0NTN1xyXG4gICAgICAgIHZhciBwYWRDb3VudCA9IG1lc3NhZ2UuY2hhckNvZGVBdChtZXNzYWdlLmxlbmd0aCAtIDEpO1xyXG4gICAgICAgIG1lc3NhZ2UgPSBtZXNzYWdlLnN1YnN0cigwLCBtZXNzYWdlLmxlbmd0aCAtIHBhZENvdW50KTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKCFwYWRkaW5nKSB7ICAgICAgICAvLyBudWxsIHBhZGRpbmdcclxuICAgICAgICBtZXNzYWdlID0gbWVzc2FnZS5yZXBsYWNlKC9cXDAqJC9nLCBcIlwiKTtcclxuICAgIH1cclxuICAgIHJldHVybiBtZXNzYWdlO1xyXG59XHJcblxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuLy8gYWRkZWQgYnkgUmVjdXJpdHkgTGFic1xuZnVuY3Rpb24gRGVzKGtleSkge1xuXHR0aGlzLmtleSA9IFtdO1xuXG5cdGZvcih2YXIgaSA9IDA7IGkgPCAzOyBpKyspIHtcblx0XHR0aGlzLmtleS5wdXNoKGtleS5zdWJzdHIoaSAqIDgsIDgpKTtcblx0fVxuXG5cdHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG5cdFx0cmV0dXJuIHV0aWwuc3RyMmJpbihkZXMoZGVzX2NyZWF0ZUtleXModGhpcy5rZXlbMl0pLFxuXHRcdFx0ZGVzKGRlc19jcmVhdGVLZXlzKHRoaXMua2V5WzFdKSxcblx0XHRcdGRlcyhkZXNfY3JlYXRlS2V5cyh0aGlzLmtleVswXSksXG5cdFx0XHR1dGlsLmJpbjJzdHIoYmxvY2spLCB0cnVlLCAwLG51bGwsbnVsbCksIFxuXHRcdFx0ZmFsc2UsIDAsbnVsbCxudWxsKSwgdHJ1ZSwgMCxudWxsLG51bGwpKTtcblx0fVxufVxuXG5EZXMua2V5U2l6ZSA9IERlcy5wcm90b3R5cGUua2V5U2l6ZSA9IDI0O1xuRGVzLmJsb2NrU2l6ZSA9IERlcy5wcm90b3R5cGUuYmxvY2tTaXplID0gODtcblxuLy8gVGhpcyBpcyBcIm9yaWdpbmFsXCIgREVTIC0gRGVzIGlzIGFjdHVhbGx5IFRyaXBsZSBERVMuXG4vLyBUaGlzIGlzIG9ubHkgZXhwb3J0ZWQgc28gd2UgY2FuIHVuaXQgdGVzdC5cbmZ1bmN0aW9uIE9yaWdpbmFsRGVzKGtleSkge1xyXG4gICAgdGhpcy5rZXkgPSBrZXk7XG5cbiAgICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbiAoYmxvY2ssIHBhZGRpbmcpIHtcclxuICAgICAgICB2YXIga2V5cyA9IGRlc19jcmVhdGVLZXlzKHRoaXMua2V5KTtcclxuICAgICAgICByZXR1cm4gdXRpbC5zdHIyYmluKGRlcyhrZXlzLCB1dGlsLmJpbjJzdHIoYmxvY2spLCB0cnVlLCAwLCBudWxsLCBwYWRkaW5nKSk7XHJcbiAgICB9XHJcblxuICAgIHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uIChibG9jaywgcGFkZGluZykge1xyXG4gICAgICAgIHZhciBrZXlzID0gZGVzX2NyZWF0ZUtleXModGhpcy5rZXkpO1xyXG4gICAgICAgIHJldHVybiB1dGlsLnN0cjJiaW4oZGVzKGtleXMsIHV0aWwuYmluMnN0cihibG9jayksIGZhbHNlLCAwLCBudWxsLCBwYWRkaW5nKSk7XHJcbiAgICB9XHJcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgICBkZXM6IERlcyxcbiAgICBvcmlnaW5hbERlczogT3JpZ2luYWxEZXNcclxufVxuXG4iLCJcbnZhciBkZXNNb2R1bGUgPSByZXF1aXJlKCcuL2Rlcy5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBkZXM6IGRlc01vZHVsZVsnZGVzJ10sXG4gICAgb3JpZ2luYWxEZXM6IGRlc01vZHVsZVsnb3JpZ2luYWxEZXMnXSxcblx0Y2FzdDU6IHJlcXVpcmUoJy4vY2FzdDUuanMnKSxcblx0dHdvZmlzaDogcmVxdWlyZSgnLi90d29maXNoLmpzJyksXG5cdGJsb3dmaXNoOiByZXF1aXJlKCcuL2Jsb3dmaXNoLmpzJylcbn1cblxudmFyIGFlcyA9IHJlcXVpcmUoJy4vYWVzLmpzJyk7XG5cbmZvcih2YXIgaSBpbiBhZXMpIHtcblx0bW9kdWxlLmV4cG9ydHNbJ2FlcycgKyBpXSA9IGFlc1tpXTtcbn1cbiIsIi8qIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSCBcbiAqIFxuICogQ2lwaGVyLmpzXG4gKiBBIGJsb2NrLWNpcGhlciBhbGdvcml0aG0gaW1wbGVtZW50YXRpb24gb24gSmF2YVNjcmlwdFxuICogU2VlIENpcGhlci5yZWFkbWUudHh0IGZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLlxuICpcbiAqIENvcHlyaWdodChjKSAyMDA5IEF0c3VzaGkgT2thIFsgaHR0cDovL29rYS5udS8gXVxuICogVGhpcyBzY3JpcHQgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTEdQTFxuICpcbiAqIEFDS05PV0xFREdNRU5UXG4gKlxuICogICAgIFRoZSBtYWluIHN1YnJvdXRpbmVzIGFyZSB3cml0dGVuIGJ5IE1pY2hpZWwgdmFuIEV2ZXJkaW5nZW4uXG4gKiBcbiAqICAgICBNaWNoaWVsIHZhbiBFdmVyZGluZ2VuXG4gKiAgICAgaHR0cDovL2hvbWUudmVyc2F0ZWwubmwvTUF2YW5FdmVyZGluZ2VuL2luZGV4Lmh0bWxcbiAqIFxuICogICAgIEFsbCByaWdodHMgZm9yIHRoZXNlIHJvdXRpbmVzIGFyZSByZXNlcnZlZCB0byBNaWNoaWVsIHZhbiBFdmVyZGluZ2VuLlxuICpcbiAqL1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vL01hdGhcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG52YXIgTUFYSU5UID0gMHhGRkZGRkZGRjtcblxuZnVuY3Rpb24gcm90YihiLG4peyByZXR1cm4gKCBiPDxuIHwgYj4+PiggOC1uKSApICYgMHhGRjsgfVxuZnVuY3Rpb24gcm90dyh3LG4peyByZXR1cm4gKCB3PDxuIHwgdz4+PigzMi1uKSApICYgTUFYSU5UOyB9XG5mdW5jdGlvbiBnZXRXKGEsaSl7IHJldHVybiBhW2ldfGFbaSsxXTw8OHxhW2krMl08PDE2fGFbaSszXTw8MjQ7IH1cbmZ1bmN0aW9uIHNldFcoYSxpLHcpeyBhLnNwbGljZShpLDQsdyYweEZGLCh3Pj4+OCkmMHhGRiwodz4+PjE2KSYweEZGLCh3Pj4+MjQpJjB4RkYpOyB9XG5mdW5jdGlvbiBzZXRXSW52KGEsaSx3KXsgYS5zcGxpY2UoaSw0LCh3Pj4+MjQpJjB4RkYsKHc+Pj4xNikmMHhGRiwodz4+PjgpJjB4RkYsdyYweEZGKTsgfVxuZnVuY3Rpb24gZ2V0Qih4LG4peyByZXR1cm4gKHg+Pj4obio4KSkmMHhGRjsgfVxuXG5mdW5jdGlvbiBnZXROckJpdHMoaSl7IHZhciBuPTA7IHdoaWxlIChpPjApeyBuKys7IGk+Pj49MTsgfSByZXR1cm4gbjsgfVxuZnVuY3Rpb24gZ2V0TWFzayhuKXsgcmV0dXJuICgxPDxuKS0xOyB9XG5cbi8vYWRkZWQgMjAwOC8xMS8xMyBYWFggTVVTVCBVU0UgT05FLVdBWSBIQVNIIEZVTkNUSU9OIEZPUiBTRUNVUklUWSBSRUFTT05cbmZ1bmN0aW9uIHJhbmRCeXRlKCkge1xuIHJldHVybiBNYXRoLmZsb29yKCBNYXRoLnJhbmRvbSgpICogMjU2ICk7XG59XG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBUd29maXNoXG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNyZWF0ZVR3b2Zpc2goKSB7XG5cdC8vXG5cdHZhciBrZXlCeXRlcyA9IG51bGw7XG5cdHZhciBkYXRhQnl0ZXMgPSBudWxsO1xuXHR2YXIgZGF0YU9mZnNldCA9IC0xO1xuXHQvLyB2YXIgZGF0YUxlbmd0aCA9IC0xO1xuXHR2YXIgYWxnb3JpdGhtTmFtZSA9IG51bGw7XG5cdC8vIHZhciBpZHgyID0gLTE7XG5cdC8vXG5cblx0YWxnb3JpdGhtTmFtZSA9IFwidHdvZmlzaFwiO1xuXG5cdHZhciB0ZnNLZXkgPSBbXTtcblx0dmFyIHRmc00gPSBbIFtdLCBbXSwgW10sIFtdIF07XG5cblx0ZnVuY3Rpb24gdGZzSW5pdChrZXkpIHtcblx0XHRrZXlCeXRlcyA9IGtleTtcblx0XHR2YXIgaSwgYSwgYiwgYywgZCwgbWVLZXkgPSBbXSwgbW9LZXkgPSBbXSwgaW5LZXkgPSBbXTtcblx0XHR2YXIga0xlbjtcblx0XHR2YXIgc0tleSA9IFtdO1xuXHRcdHZhciBmMDEsIGY1YiwgZmVmO1xuXG5cdFx0dmFyIHEwID0gWyBbIDgsIDEsIDcsIDEzLCA2LCAxNSwgMywgMiwgMCwgMTEsIDUsIDksIDE0LCAxMiwgMTAsIDQgXSxcblx0XHRcdFx0WyAyLCA4LCAxMSwgMTMsIDE1LCA3LCA2LCAxNCwgMywgMSwgOSwgNCwgMCwgMTAsIDEyLCA1IF0gXTtcblx0XHR2YXIgcTEgPSBbIFsgMTQsIDEyLCAxMSwgOCwgMSwgMiwgMywgNSwgMTUsIDQsIDEwLCA2LCA3LCAwLCA5LCAxMyBdLFxuXHRcdFx0XHRbIDEsIDE0LCAyLCAxMSwgNCwgMTIsIDMsIDcsIDYsIDEzLCAxMCwgNSwgMTUsIDksIDAsIDggXSBdO1xuXHRcdHZhciBxMiA9IFsgWyAxMSwgMTAsIDUsIDE0LCA2LCAxMywgOSwgMCwgMTIsIDgsIDE1LCAzLCAyLCA0LCA3LCAxIF0sXG5cdFx0XHRcdFsgNCwgMTIsIDcsIDUsIDEsIDYsIDksIDEwLCAwLCAxNCwgMTMsIDgsIDIsIDExLCAzLCAxNSBdIF07XG5cdFx0dmFyIHEzID0gWyBbIDEzLCA3LCAxNSwgNCwgMSwgMiwgNiwgMTQsIDksIDExLCAzLCAwLCA4LCA1LCAxMiwgMTAgXSxcblx0XHRcdFx0WyAxMSwgOSwgNSwgMSwgMTIsIDMsIDEzLCAxNCwgNiwgNCwgNywgMTUsIDIsIDAsIDgsIDEwIF0gXTtcblx0XHR2YXIgcm9yNCA9IFsgMCwgOCwgMSwgOSwgMiwgMTAsIDMsIDExLCA0LCAxMiwgNSwgMTMsIDYsIDE0LCA3LCAxNSBdO1xuXHRcdHZhciBhc2h4ID0gWyAwLCA5LCAyLCAxMSwgNCwgMTMsIDYsIDE1LCA4LCAxLCAxMCwgMywgMTIsIDUsIDE0LCA3IF07XG5cdFx0dmFyIHEgPSBbIFtdLCBbXSBdO1xuXHRcdHZhciBtID0gWyBbXSwgW10sIFtdLCBbXSBdO1xuXG5cdFx0ZnVuY3Rpb24gZmZtNWIoeCkge1xuXHRcdFx0cmV0dXJuIHggXiAoeCA+PiAyKSBeIFsgMCwgOTAsIDE4MCwgMjM4IF1beCAmIDNdO1xuXHRcdH1cblx0XHRmdW5jdGlvbiBmZm1FZih4KSB7XG5cdFx0XHRyZXR1cm4geCBeICh4ID4+IDEpIF4gKHggPj4gMikgXiBbIDAsIDIzOCwgMTgwLCA5MCBdW3ggJiAzXTtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBtZHNSZW0ocCwgcSkge1xuXHRcdFx0dmFyIGksIHQsIHU7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgODsgaSsrKSB7XG5cdFx0XHRcdHQgPSBxID4+PiAyNDtcblx0XHRcdFx0cSA9ICgocSA8PCA4KSAmIE1BWElOVCkgfCBwID4+PiAyNDtcblx0XHRcdFx0cCA9IChwIDw8IDgpICYgTUFYSU5UO1xuXHRcdFx0XHR1ID0gdCA8PCAxO1xuXHRcdFx0XHRpZiAodCAmIDEyOCkge1xuXHRcdFx0XHRcdHUgXj0gMzMzO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHEgXj0gdCBeICh1IDw8IDE2KTtcblx0XHRcdFx0dSBePSB0ID4+PiAxO1xuXHRcdFx0XHRpZiAodCAmIDEpIHtcblx0XHRcdFx0XHR1IF49IDE2Njtcblx0XHRcdFx0fVxuXHRcdFx0XHRxIF49IHUgPDwgMjQgfCB1IDw8IDg7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcTtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBxcChuLCB4KSB7XG5cdFx0XHR2YXIgYSwgYiwgYywgZDtcblx0XHRcdGEgPSB4ID4+IDQ7XG5cdFx0XHRiID0geCAmIDE1O1xuXHRcdFx0YyA9IHEwW25dW2EgXiBiXTtcblx0XHRcdGQgPSBxMVtuXVtyb3I0W2JdIF4gYXNoeFthXV07XG5cdFx0XHRyZXR1cm4gcTNbbl1bcm9yNFtkXSBeIGFzaHhbY11dIDw8IDQgfCBxMltuXVtjIF4gZF07XG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gaEZ1bih4LCBrZXkpIHtcblx0XHRcdHZhciBhID0gZ2V0Qih4LCAwKSwgYiA9IGdldEIoeCwgMSksIGMgPSBnZXRCKHgsIDIpLCBkID0gZ2V0Qih4LCAzKTtcblx0XHRcdHN3aXRjaCAoa0xlbikge1xuXHRcdFx0Y2FzZSA0OlxuXHRcdFx0XHRhID0gcVsxXVthXSBeIGdldEIoa2V5WzNdLCAwKTtcblx0XHRcdFx0YiA9IHFbMF1bYl0gXiBnZXRCKGtleVszXSwgMSk7XG5cdFx0XHRcdGMgPSBxWzBdW2NdIF4gZ2V0QihrZXlbM10sIDIpO1xuXHRcdFx0XHRkID0gcVsxXVtkXSBeIGdldEIoa2V5WzNdLCAzKTtcblx0XHRcdGNhc2UgMzpcblx0XHRcdFx0YSA9IHFbMV1bYV0gXiBnZXRCKGtleVsyXSwgMCk7XG5cdFx0XHRcdGIgPSBxWzFdW2JdIF4gZ2V0QihrZXlbMl0sIDEpO1xuXHRcdFx0XHRjID0gcVswXVtjXSBeIGdldEIoa2V5WzJdLCAyKTtcblx0XHRcdFx0ZCA9IHFbMF1bZF0gXiBnZXRCKGtleVsyXSwgMyk7XG5cdFx0XHRjYXNlIDI6XG5cdFx0XHRcdGEgPSBxWzBdW3FbMF1bYV0gXiBnZXRCKGtleVsxXSwgMCldIF4gZ2V0QihrZXlbMF0sIDApO1xuXHRcdFx0XHRiID0gcVswXVtxWzFdW2JdIF4gZ2V0QihrZXlbMV0sIDEpXSBeIGdldEIoa2V5WzBdLCAxKTtcblx0XHRcdFx0YyA9IHFbMV1bcVswXVtjXSBeIGdldEIoa2V5WzFdLCAyKV0gXiBnZXRCKGtleVswXSwgMik7XG5cdFx0XHRcdGQgPSBxWzFdW3FbMV1bZF0gXiBnZXRCKGtleVsxXSwgMyldIF4gZ2V0QihrZXlbMF0sIDMpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1bMF1bYV0gXiBtWzFdW2JdIF4gbVsyXVtjXSBeIG1bM11bZF07XG5cdFx0fVxuXG5cdFx0a2V5Qnl0ZXMgPSBrZXlCeXRlcy5zbGljZSgwLCAzMik7XG5cdFx0aSA9IGtleUJ5dGVzLmxlbmd0aDtcblx0XHR3aGlsZSAoaSAhPSAxNiAmJiBpICE9IDI0ICYmIGkgIT0gMzIpXG5cdFx0XHRrZXlCeXRlc1tpKytdID0gMDtcblxuXHRcdGZvciAoaSA9IDA7IGkgPCBrZXlCeXRlcy5sZW5ndGg7IGkgKz0gNCkge1xuXHRcdFx0aW5LZXlbaSA+PiAyXSA9IGdldFcoa2V5Qnl0ZXMsIGkpO1xuXHRcdH1cblx0XHRmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcblx0XHRcdHFbMF1baV0gPSBxcCgwLCBpKTtcblx0XHRcdHFbMV1baV0gPSBxcCgxLCBpKTtcblx0XHR9XG5cdFx0Zm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7XG5cdFx0XHRmMDEgPSBxWzFdW2ldO1xuXHRcdFx0ZjViID0gZmZtNWIoZjAxKTtcblx0XHRcdGZlZiA9IGZmbUVmKGYwMSk7XG5cdFx0XHRtWzBdW2ldID0gZjAxICsgKGY1YiA8PCA4KSArIChmZWYgPDwgMTYpICsgKGZlZiA8PCAyNCk7XG5cdFx0XHRtWzJdW2ldID0gZjViICsgKGZlZiA8PCA4KSArIChmMDEgPDwgMTYpICsgKGZlZiA8PCAyNCk7XG5cdFx0XHRmMDEgPSBxWzBdW2ldO1xuXHRcdFx0ZjViID0gZmZtNWIoZjAxKTtcblx0XHRcdGZlZiA9IGZmbUVmKGYwMSk7XG5cdFx0XHRtWzFdW2ldID0gZmVmICsgKGZlZiA8PCA4KSArIChmNWIgPDwgMTYpICsgKGYwMSA8PCAyNCk7XG5cdFx0XHRtWzNdW2ldID0gZjViICsgKGYwMSA8PCA4KSArIChmZWYgPDwgMTYpICsgKGY1YiA8PCAyNCk7XG5cdFx0fVxuXG5cdFx0a0xlbiA9IGluS2V5Lmxlbmd0aCAvIDI7XG5cdFx0Zm9yIChpID0gMDsgaSA8IGtMZW47IGkrKykge1xuXHRcdFx0YSA9IGluS2V5W2kgKyBpXTtcblx0XHRcdG1lS2V5W2ldID0gYTtcblx0XHRcdGIgPSBpbktleVtpICsgaSArIDFdO1xuXHRcdFx0bW9LZXlbaV0gPSBiO1xuXHRcdFx0c0tleVtrTGVuIC0gaSAtIDFdID0gbWRzUmVtKGEsIGIpO1xuXHRcdH1cblx0XHRmb3IgKGkgPSAwOyBpIDwgNDA7IGkgKz0gMikge1xuXHRcdFx0YSA9IDB4MTAxMDEwMSAqIGk7XG5cdFx0XHRiID0gYSArIDB4MTAxMDEwMTtcblx0XHRcdGEgPSBoRnVuKGEsIG1lS2V5KTtcblx0XHRcdGIgPSByb3R3KGhGdW4oYiwgbW9LZXkpLCA4KTtcblx0XHRcdHRmc0tleVtpXSA9IChhICsgYikgJiBNQVhJTlQ7XG5cdFx0XHR0ZnNLZXlbaSArIDFdID0gcm90dyhhICsgMiAqIGIsIDkpO1xuXHRcdH1cblx0XHRmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcblx0XHRcdGEgPSBiID0gYyA9IGQgPSBpO1xuXHRcdFx0c3dpdGNoIChrTGVuKSB7XG5cdFx0XHRjYXNlIDQ6XG5cdFx0XHRcdGEgPSBxWzFdW2FdIF4gZ2V0QihzS2V5WzNdLCAwKTtcblx0XHRcdFx0YiA9IHFbMF1bYl0gXiBnZXRCKHNLZXlbM10sIDEpO1xuXHRcdFx0XHRjID0gcVswXVtjXSBeIGdldEIoc0tleVszXSwgMik7XG5cdFx0XHRcdGQgPSBxWzFdW2RdIF4gZ2V0QihzS2V5WzNdLCAzKTtcblx0XHRcdGNhc2UgMzpcblx0XHRcdFx0YSA9IHFbMV1bYV0gXiBnZXRCKHNLZXlbMl0sIDApO1xuXHRcdFx0XHRiID0gcVsxXVtiXSBeIGdldEIoc0tleVsyXSwgMSk7XG5cdFx0XHRcdGMgPSBxWzBdW2NdIF4gZ2V0QihzS2V5WzJdLCAyKTtcblx0XHRcdFx0ZCA9IHFbMF1bZF0gXiBnZXRCKHNLZXlbMl0sIDMpO1xuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHR0ZnNNWzBdW2ldID0gbVswXVtxWzBdW3FbMF1bYV0gXiBnZXRCKHNLZXlbMV0sIDApXVxuXHRcdFx0XHRcdFx0XiBnZXRCKHNLZXlbMF0sIDApXTtcblx0XHRcdFx0dGZzTVsxXVtpXSA9IG1bMV1bcVswXVtxWzFdW2JdIF4gZ2V0QihzS2V5WzFdLCAxKV1cblx0XHRcdFx0XHRcdF4gZ2V0QihzS2V5WzBdLCAxKV07XG5cdFx0XHRcdHRmc01bMl1baV0gPSBtWzJdW3FbMV1bcVswXVtjXSBeIGdldEIoc0tleVsxXSwgMildXG5cdFx0XHRcdFx0XHReIGdldEIoc0tleVswXSwgMildO1xuXHRcdFx0XHR0ZnNNWzNdW2ldID0gbVszXVtxWzFdW3FbMV1bZF0gXiBnZXRCKHNLZXlbMV0sIDMpXVxuXHRcdFx0XHRcdFx0XiBnZXRCKHNLZXlbMF0sIDMpXTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRmdW5jdGlvbiB0ZnNHMCh4KSB7XG5cdFx0cmV0dXJuIHRmc01bMF1bZ2V0Qih4LCAwKV0gXiB0ZnNNWzFdW2dldEIoeCwgMSldIF4gdGZzTVsyXVtnZXRCKHgsIDIpXVxuXHRcdFx0XHReIHRmc01bM11bZ2V0Qih4LCAzKV07XG5cdH1cblx0ZnVuY3Rpb24gdGZzRzEoeCkge1xuXHRcdHJldHVybiB0ZnNNWzBdW2dldEIoeCwgMyldIF4gdGZzTVsxXVtnZXRCKHgsIDApXSBeIHRmc01bMl1bZ2V0Qih4LCAxKV1cblx0XHRcdFx0XiB0ZnNNWzNdW2dldEIoeCwgMildO1xuXHR9XG5cblx0ZnVuY3Rpb24gdGZzRnJuZChyLCBibGspIHtcblx0XHR2YXIgYSA9IHRmc0cwKGJsa1swXSk7XG5cdFx0dmFyIGIgPSB0ZnNHMShibGtbMV0pO1xuXHRcdGJsa1syXSA9IHJvdHcoYmxrWzJdIF4gKGEgKyBiICsgdGZzS2V5WzQgKiByICsgOF0pICYgTUFYSU5ULCAzMSk7XG5cdFx0YmxrWzNdID0gcm90dyhibGtbM10sIDEpIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogciArIDldKSAmIE1BWElOVDtcblx0XHRhID0gdGZzRzAoYmxrWzJdKTtcblx0XHRiID0gdGZzRzEoYmxrWzNdKTtcblx0XHRibGtbMF0gPSByb3R3KGJsa1swXSBeIChhICsgYiArIHRmc0tleVs0ICogciArIDEwXSkgJiBNQVhJTlQsIDMxKTtcblx0XHRibGtbMV0gPSByb3R3KGJsa1sxXSwgMSkgXiAoYSArIDIgKiBiICsgdGZzS2V5WzQgKiByICsgMTFdKSAmIE1BWElOVDtcblx0fVxuXG5cdGZ1bmN0aW9uIHRmc0lybmQoaSwgYmxrKSB7XG5cdFx0dmFyIGEgPSB0ZnNHMChibGtbMF0pO1xuXHRcdHZhciBiID0gdGZzRzEoYmxrWzFdKTtcblx0XHRibGtbMl0gPSByb3R3KGJsa1syXSwgMSkgXiAoYSArIGIgKyB0ZnNLZXlbNCAqIGkgKyAxMF0pICYgTUFYSU5UO1xuXHRcdGJsa1szXSA9IHJvdHcoYmxrWzNdIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogaSArIDExXSkgJiBNQVhJTlQsIDMxKTtcblx0XHRhID0gdGZzRzAoYmxrWzJdKTtcblx0XHRiID0gdGZzRzEoYmxrWzNdKTtcblx0XHRibGtbMF0gPSByb3R3KGJsa1swXSwgMSkgXiAoYSArIGIgKyB0ZnNLZXlbNCAqIGkgKyA4XSkgJiBNQVhJTlQ7XG5cdFx0YmxrWzFdID0gcm90dyhibGtbMV0gXiAoYSArIDIgKiBiICsgdGZzS2V5WzQgKiBpICsgOV0pICYgTUFYSU5ULCAzMSk7XG5cdH1cblxuXHRmdW5jdGlvbiB0ZnNDbG9zZSgpIHtcblx0XHR0ZnNLZXkgPSBbXTtcblx0XHR0ZnNNID0gWyBbXSwgW10sIFtdLCBbXSBdO1xuXHR9XG5cblx0ZnVuY3Rpb24gdGZzRW5jcnlwdChkYXRhLCBvZmZzZXQpIHtcblx0XHRkYXRhQnl0ZXMgPSBkYXRhO1xuXHRcdGRhdGFPZmZzZXQgPSBvZmZzZXQ7XG5cdFx0dmFyIGJsayA9IFsgZ2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQpIF4gdGZzS2V5WzBdLFxuXHRcdFx0XHRnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDQpIF4gdGZzS2V5WzFdLFxuXHRcdFx0XHRnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDgpIF4gdGZzS2V5WzJdLFxuXHRcdFx0XHRnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDEyKSBeIHRmc0tleVszXSBdO1xuXHRcdGZvciAoIHZhciBqID0gMDsgaiA8IDg7IGorKykge1xuXHRcdFx0dGZzRnJuZChqLCBibGspO1xuXHRcdH1cblx0XHRzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCwgYmxrWzJdIF4gdGZzS2V5WzRdKTtcblx0XHRzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDQsIGJsa1szXSBeIHRmc0tleVs1XSk7XG5cdFx0c2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA4LCBibGtbMF0gXiB0ZnNLZXlbNl0pO1xuXHRcdHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIsIGJsa1sxXSBeIHRmc0tleVs3XSk7XG5cdFx0ZGF0YU9mZnNldCArPSAxNjtcblx0XHRyZXR1cm4gZGF0YUJ5dGVzO1xuXHR9XG5cblx0ZnVuY3Rpb24gdGZzRGVjcnlwdChkYXRhLCBvZmZzZXQpIHtcblx0XHRkYXRhQnl0ZXMgPSBkYXRhO1xuXHRcdGRhdGFPZmZzZXQgPSBvZmZzZXQ7XG5cdFx0dmFyIGJsayA9IFsgZ2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQpIF4gdGZzS2V5WzRdLFxuXHRcdFx0XHRnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDQpIF4gdGZzS2V5WzVdLFxuXHRcdFx0XHRnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDgpIF4gdGZzS2V5WzZdLFxuXHRcdFx0XHRnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDEyKSBeIHRmc0tleVs3XSBdO1xuXHRcdGZvciAoIHZhciBqID0gNzsgaiA+PSAwOyBqLS0pIHtcblx0XHRcdHRmc0lybmQoaiwgYmxrKTtcblx0XHR9XG5cdFx0c2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQsIGJsa1syXSBeIHRmc0tleVswXSk7XG5cdFx0c2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA0LCBibGtbM10gXiB0ZnNLZXlbMV0pO1xuXHRcdHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCwgYmxrWzBdIF4gdGZzS2V5WzJdKTtcblx0XHRzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDEyLCBibGtbMV0gXiB0ZnNLZXlbM10pO1xuXHRcdGRhdGFPZmZzZXQgKz0gMTY7XG5cdH1cblx0XG5cdC8vIGFkZGVkIGJ5IFJlY3VyaXR5IExhYnNcblx0ZnVuY3Rpb24gdGZzRmluYWwoKSB7XG5cdFx0cmV0dXJuIGRhdGFCeXRlcztcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0bmFtZSA6IFwidHdvZmlzaFwiLFxuXHRcdGJsb2Nrc2l6ZSA6IDEyOCAvIDgsXG5cdFx0b3BlbiA6IHRmc0luaXQsXG5cdFx0Y2xvc2UgOiB0ZnNDbG9zZSxcblx0XHRlbmNyeXB0IDogdGZzRW5jcnlwdCxcblx0XHRkZWNyeXB0IDogdGZzRGVjcnlwdCxcblx0XHQvLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cdFx0ZmluYWxpemU6IHRmc0ZpbmFsXG5cdH07XG59XG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5mdW5jdGlvbiBURmVuY3J5cHQoYmxvY2ssIGtleSkge1xuXHR2YXIgYmxvY2tfY29weSA9IFtdLmNvbmNhdChibG9jayk7XG5cdHZhciB0ZiA9IGNyZWF0ZVR3b2Zpc2goKTtcblx0dGYub3Blbih1dGlsLnN0cjJiaW4oa2V5KSwwKTtcblx0dmFyIHJlc3VsdCA9IHRmLmVuY3J5cHQoYmxvY2tfY29weSwgMCk7XG5cdHRmLmNsb3NlKCk7XG5cdHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIFRGKGtleSkge1xuXHR0aGlzLnRmID0gY3JlYXRlVHdvZmlzaCgpO1xuXHR0aGlzLnRmLm9wZW4odXRpbC5zdHIyYmluKGtleSksMCk7XG5cblx0dGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYmxvY2spIHtcblx0XHRyZXR1cm4gdGhpcy50Zi5lbmNyeXB0KFtdLmNvbmNhdChibG9jayksIDApO1xuXHR9XG59XG5cblxubW9kdWxlLmV4cG9ydHMgPSBURjtcbm1vZHVsZS5leHBvcnRzLmtleVNpemUgPSBURi5wcm90b3R5cGUua2V5U2l6ZSA9IDMyO1xubW9kdWxlLmV4cG9ydHMuYmxvY2tTaXplID0gVEYucHJvdG90eXBlLmJsb2NrU2l6ZSA9IDE2O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0EgXG5cbi8vIFRoZSBHUEc0QnJvd3NlcnMgY3J5cHRvIGludGVyZmFjZVxuXG52YXIgcmFuZG9tID0gcmVxdWlyZSgnLi9yYW5kb20uanMnKSxcbiAgY2lwaGVyID0gcmVxdWlyZSgnLi9jaXBoZXInKSxcbiAgcHVibGljS2V5ID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5JyksXG4gIHR5cGVfbXBpID0gcmVxdWlyZSgnLi4vdHlwZS9tcGkuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4vKipcbiAqIEVuY3J5cHRzIGRhdGEgdXNpbmcgdGhlIHNwZWNpZmllZCBwdWJsaWMga2V5IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICogYW5kIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtLlxuICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEFsZ29yaXRobSB0byBiZSB1c2VkIChTZWUgUkZDNDg4MCA5LjEpXG4gKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gcHVibGljTVBJcyBBbGdvcml0aG0gZGVwZW5kZW50IG11bHRpcHJlY2lzaW9uIGludGVnZXJzXG4gKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGl9IGRhdGEgRGF0YSB0byBiZSBlbmNyeXB0ZWQgYXMgTVBJXG4gKiBAcmV0dXJuIHtvcGVucGdwX3R5cGVfbXBpW119IGlmIFJTQSBhbiBvcGVucGdwX3R5cGVfbXBpOyBcbiAqIGlmIGVsZ2FtYWwgZW5jcnlwdGlvbiBhbiBhcnJheSBvZiB0d28gb3BlbnBncF90eXBlX21waSBpcyByZXR1cm5lZDsgb3RoZXJ3aXNlIG51bGxcbiAqL1xucHVibGljS2V5RW5jcnlwdDogZnVuY3Rpb24oYWxnbywgcHVibGljTVBJcywgZGF0YSkge1xuICB2YXIgcmVzdWx0ID0gKGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaChhbGdvKSB7XG4gICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgIGNhc2UgJ3JzYV9lbmNyeXB0X3NpZ24nOlxuICAgICAgdmFyIHJzYSA9IG5ldyBwdWJsaWNLZXkucnNhKCk7XG4gICAgICB2YXIgbiA9IHB1YmxpY01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICB2YXIgZSA9IHB1YmxpY01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICB2YXIgbSA9IGRhdGEudG9CaWdJbnRlZ2VyKCk7XG4gICAgICByZXR1cm4gW3JzYS5lbmNyeXB0KG0sZSxuKV07XG5cbiAgICBjYXNlICdlbGdhbWFsJzpcbiAgICAgIHZhciBlbGdhbWFsID0gbmV3IHB1YmxpY0tleS5lbGdhbWFsKCk7XG4gICAgICB2YXIgcCA9IHB1YmxpY01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICB2YXIgZyA9IHB1YmxpY01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICB2YXIgeSA9IHB1YmxpY01QSXNbMl0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICB2YXIgbSA9IGRhdGEudG9CaWdJbnRlZ2VyKCk7XG4gICAgICByZXR1cm4gZWxnYW1hbC5lbmNyeXB0KG0sZyxwLHkpO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH0pKCk7XG5cbiAgcmV0dXJuIHJlc3VsdC5tYXAoZnVuY3Rpb24oYm4pIHtcbiAgICB2YXIgbXBpID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgbXBpLmZyb21CaWdJbnRlZ2VyKGJuKTtcbiAgICByZXR1cm4gbXBpO1xuICB9KTtcbn0sXG5cbi8qKlxuICogRGVjcnlwdHMgZGF0YSB1c2luZyB0aGUgc3BlY2lmaWVkIHB1YmxpYyBrZXkgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgb2YgdGhlIHByaXZhdGUga2V5LFxuICogdGhlIHNwZWNpZmllZCBzZWNyZXRNUElzIG9mIHRoZSBwcml2YXRlIGtleSBhbmQgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0uXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIGJlIHVzZWQgKFNlZSBSRkM0ODgwIDkuMSlcbiAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBwdWJsaWNNUElzIEFsZ29yaXRobSBkZXBlbmRlbnQgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG4gKiBvZiB0aGUgcHVibGljIGtleSBwYXJ0IG9mIHRoZSBwcml2YXRlIGtleVxuICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpW119IHNlY3JldE1QSXMgQWxnb3JpdGhtIGRlcGVuZGVudCBtdWx0aXByZWNpc2lvbiBpbnRlZ2VycyBcbiAqIG9mIHRoZSBwcml2YXRlIGtleSB1c2VkXG4gKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGl9IGRhdGEgRGF0YSB0byBiZSBlbmNyeXB0ZWQgYXMgTVBJXG4gKiBAcmV0dXJuIHtvcGVucGdwX3R5cGVfbXBpfSByZXR1cm5zIGEgYmlnIGludGVnZXIgY29udGFpbmluZyB0aGUgZGVjcnlwdGVkIGRhdGE7IG90aGVyd2lzZSBudWxsXG4gKi9cblxucHVibGljS2V5RGVjcnlwdDogZnVuY3Rpb24gKGFsZ28sIGtleUludGVnZXJzLCBkYXRhSW50ZWdlcnMpIHtcbiAgdmFyIGJuID0gKGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaChhbGdvKSB7XG4gICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgICAgdmFyIHJzYSA9IG5ldyBwdWJsaWNLZXkucnNhKCk7XG4gICAgICAvLyAwIGFuZCAxIGFyZSB0aGUgcHVibGljIGtleS5cbiAgICAgIHZhciBkID0ga2V5SW50ZWdlcnNbMl0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICB2YXIgcCA9IGtleUludGVnZXJzWzNdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgdmFyIHEgPSBrZXlJbnRlZ2Vyc1s0XS50b0JpZ0ludGVnZXIoKTtcbiAgICAgIHZhciB1ID0ga2V5SW50ZWdlcnNbNV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICB2YXIgbSA9IGRhdGFJbnRlZ2Vyc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgIHJldHVybiByc2EuZGVjcnlwdChtLCBkLCBwLCBxLCB1KTtcbiAgICBjYXNlICdlbGdhbWFsJzpcbiAgICAgIHZhciBlbGdhbWFsID0gbmV3IHB1YmxpY0tleS5lbGdhbWFsKCk7XG4gICAgICB2YXIgeCA9IGtleUludGVnZXJzWzNdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgdmFyIGMxID0gZGF0YUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgdmFyIGMyID0gZGF0YUludGVnZXJzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgdmFyIHAgPSBrZXlJbnRlZ2Vyc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgIHJldHVybiBlbGdhbWFsLmRlY3J5cHQoYzEsYzIscCx4KTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9KSgpO1xuXG4gIHZhciByZXN1bHQgPSBuZXcgdHlwZV9tcGkoKTtcbiAgcmVzdWx0LmZyb21CaWdJbnRlZ2VyKGJuKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn0sXG5cbi8qKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgaW50ZWdlcnMgY29tcHJpc2luZyB0aGUgcHJpdmF0ZSBrZXkgb2YgYW4gYWxnb3JpdGhtXG4gKiBAcGFyYW0ge29wZW5wZ3AucHVibGlja2V5fSBhbGdvIFRoZSBwdWJsaWMga2V5IGFsZ29yaXRobVxuICogQHJldHVybiB7SW50ZWdlcn0gVGhlIG51bWJlciBvZiBpbnRlZ2Vycy5cbiAqL1xuZ2V0UHJpdmF0ZU1waUNvdW50OiBmdW5jdGlvbihhbGdvKSB7XG4gIHN3aXRjaChhbGdvKSB7XG4gICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgIGNhc2UgJ3JzYV9lbmNyeXB0X3NpZ24nOlxuICAgIGNhc2UgJ3JzYV9zaWduJzpcbiAgICAvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBzZWNyZXQga2V5czpcbiAgICAvLyAgIC0gbXVsdGlwcmVjaXNpb24gaW50ZWdlciAoTVBJKSBvZiBSU0Egc2VjcmV0IGV4cG9uZW50IGQuXG4gICAgLy8gICAtIE1QSSBvZiBSU0Egc2VjcmV0IHByaW1lIHZhbHVlIHAuXG4gICAgLy8gICAtIE1QSSBvZiBSU0Egc2VjcmV0IHByaW1lIHZhbHVlIHEgKHAgPCBxKS5cbiAgICAvLyAgIC0gTVBJIG9mIHUsIHRoZSBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlIG9mIHAsIG1vZCBxLlxuICAgIHJldHVybiA0O1xuICBjYXNlICdlbGdhbWFsJzpcbiAgICAvLyBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBFbGdhbWFsIHNlY3JldCBrZXlzOlxuICAgIC8vICAgLSBNUEkgb2YgRWxnYW1hbCBzZWNyZXQgZXhwb25lbnQgeC5cbiAgICByZXR1cm4gMTtcbiAgY2FzZSAnZHNhJzpcbiAgICAvLyBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBEU0Egc2VjcmV0IGtleXM6XG4gICAgLy8gICAtIE1QSSBvZiBEU0Egc2VjcmV0IGV4cG9uZW50IHguXG4gICAgcmV0dXJuIDE7XG4gIGRlZmF1bHQ6XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGFsZ29yaXRobScpO1xuICB9XG59LFxuICBcbmdldFB1YmxpY01waUNvdW50OiBmdW5jdGlvbihhbGdvKSB7XG4gIC8vIC0gQSBzZXJpZXMgb2YgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgY29tcHJpc2luZyB0aGUga2V5IG1hdGVyaWFsOlxuICAvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBwdWJsaWMga2V5czpcbiAgLy8gICAgICAgLSBhIG11bHRpcHJlY2lzaW9uIGludGVnZXIgKE1QSSkgb2YgUlNBIHB1YmxpYyBtb2R1bHVzIG47XG4gIC8vICAgICAgIC0gYW4gTVBJIG9mIFJTQSBwdWJsaWMgZW5jcnlwdGlvbiBleHBvbmVudCBlLlxuICBzd2l0Y2goYWxnbykge1xuICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICBjYXNlICdyc2FfZW5jcnlwdF9zaWduJzpcbiAgICBjYXNlICdyc2Ffc2lnbic6XG4gICAgcmV0dXJuIDI7XG5cbiAgLy8gICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBFbGdhbWFsIHB1YmxpYyBrZXlzOlxuICAvLyAgICAgLSBNUEkgb2YgRWxnYW1hbCBwcmltZSBwO1xuICAvLyAgICAgLSBNUEkgb2YgRWxnYW1hbCBncm91cCBnZW5lcmF0b3IgZztcbiAgLy8gICAgIC0gTVBJIG9mIEVsZ2FtYWwgcHVibGljIGtleSB2YWx1ZSB5ICg9IGcqKnggbW9kIHAgd2hlcmUgeCAgaXMgc2VjcmV0KS5cbiAgICBjYXNlICdlbGdhbWFsJzpcbiAgICByZXR1cm4gMztcblxuICAvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIERTQSBwdWJsaWMga2V5czpcbiAgLy8gICAgICAgLSBNUEkgb2YgRFNBIHByaW1lIHA7XG4gIC8vICAgICAgIC0gTVBJIG9mIERTQSBncm91cCBvcmRlciBxIChxIGlzIGEgcHJpbWUgZGl2aXNvciBvZiBwLTEpO1xuICAvLyAgICAgICAtIE1QSSBvZiBEU0EgZ3JvdXAgZ2VuZXJhdG9yIGc7XG4gIC8vICAgICAgIC0gTVBJIG9mIERTQSBwdWJsaWMta2V5IHZhbHVlIHkgKD0gZyoqeCBtb2QgcCB3aGVyZSB4ICBpcyBzZWNyZXQpLlxuICAgIGNhc2UgJ2RzYSc6XG4gICAgcmV0dXJuIDQ7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGFsZ29yaXRobS4nKTtcbiAgfVxufSxcblxuXG4vKipcbiAqIGdlbmVyYXRlIHJhbmRvbSBieXRlIHByZWZpeCBhcyBzdHJpbmcgZm9yIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIHVzZSAoc2VlIFJGQzQ4ODAgOS4yKVxuICogQHJldHVybiB7U3RyaW5nfSBSYW5kb20gYnl0ZXMgd2l0aCBsZW5ndGggZXF1YWwgdG8gdGhlIGJsb2NrXG4gKiBzaXplIG9mIHRoZSBjaXBoZXJcbiAqL1xuZ2V0UHJlZml4UmFuZG9tOiBmdW5jdGlvbihhbGdvKSB7XG4gIHJldHVybiByYW5kb20uZ2V0UmFuZG9tQnl0ZXMoY2lwaGVyW2FsZ29dLmJsb2NrU2l6ZSk7XG59LFxuXG4vKipcbiAqIEdlbmVyYXRpbmcgYSBzZXNzaW9uIGtleSBmb3IgdGhlIHNwZWNpZmllZCBzeW1tZXRyaWMgYWxnb3JpdGhtXG4gKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gQWxnb3JpdGhtIHRvIHVzZSAoc2VlIFJGQzQ4ODAgOS4yKVxuICogQHJldHVybiB7U3RyaW5nfSBSYW5kb20gYnl0ZXMgYXMgYSBzdHJpbmcgdG8gYmUgdXNlZCBhcyBhIGtleVxuICovXG5nZW5lcmF0ZVNlc3Npb25LZXk6IGZ1bmN0aW9uKGFsZ28pIHtcbiAgcmV0dXJuIHJhbmRvbS5nZXRSYW5kb21CeXRlcyhjaXBoZXJbYWxnb10ua2V5U2l6ZSk7IFxufSxcblxufTtcbiIsIlxudmFyIHNoYSA9IHJlcXVpcmUoJy4vc2hhLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRtZDU6IHJlcXVpcmUoJy4vbWQ1LmpzJyksXG5cdHNoYTE6IHNoYS5zaGExLFxuXHRzaGEyNTY6IHNoYS5zaGEyNTYsXG5cdHNoYTIyNDogc2hhLnNoYTIyNCxcblx0c2hhMzg0OiBzaGEuc2hhMzg0LFxuXHRzaGE1MTI6IHNoYS5zaGE1MTIsXG5cdHJpcGVtZDogcmVxdWlyZSgnLi9yaXBlLW1kLmpzJyksXG5cblx0LyoqXG5cdCAqIENyZWF0ZSBhIGhhc2ggb24gdGhlIHNwZWNpZmllZCBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBIYXNoIGFsZ29yaXRobSB0eXBlIChzZWUgUkZDNDg4MCA5LjQpXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgaGFzaGVkXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gaGFzaCB2YWx1ZVxuXHQgKi9cblx0ZGlnZXN0OiBmdW5jdGlvbihhbGdvLCBkYXRhKSB7XG5cdFx0c3dpdGNoKGFsZ28pIHtcblx0XHRjYXNlIDE6IC8vIC0gTUQ1IFtIQUNdXG5cdFx0XHRyZXR1cm4gdGhpcy5tZDUoZGF0YSk7XG5cdFx0Y2FzZSAyOiAvLyAtIFNIQS0xIFtGSVBTMTgwXVxuXHRcdFx0cmV0dXJuIHRoaXMuc2hhMShkYXRhKTtcblx0XHRjYXNlIDM6IC8vIC0gUklQRS1NRC8xNjAgW0hBQ11cblx0XHRcdHJldHVybiB0aGlzLnJpcGVtZChkYXRhKTtcblx0XHRjYXNlIDg6IC8vIC0gU0hBMjU2IFtGSVBTMTgwXVxuXHRcdFx0cmV0dXJuIHRoaXMuc2hhMjU2KGRhdGEpO1xuXHRcdGNhc2UgOTogLy8gLSBTSEEzODQgW0ZJUFMxODBdXG5cdFx0XHRyZXR1cm4gdGhpcy5zaGEzODQoZGF0YSk7XG5cdFx0Y2FzZSAxMDovLyAtIFNIQTUxMiBbRklQUzE4MF1cblx0XHRcdHJldHVybiB0aGlzLnNoYTUxMihkYXRhKTtcblx0XHRjYXNlIDExOi8vIC0gU0hBMjI0IFtGSVBTMTgwXVxuXHRcdFx0cmV0dXJuIHRoaXMuc2hhMjI0KGRhdGEpO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGFzaCBmdW5jdGlvbi4nKTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGhhc2ggc2l6ZSBpbiBieXRlcyBvZiB0aGUgc3BlY2lmaWVkIGhhc2ggYWxnb3JpdGhtIHR5cGVcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEhhc2ggYWxnb3JpdGhtIHR5cGUgKFNlZSBSRkM0ODgwIDkuNClcblx0ICogQHJldHVybiB7SW50ZWdlcn0gU2l6ZSBpbiBieXRlcyBvZiB0aGUgcmVzdWx0aW5nIGhhc2hcblx0ICovXG5cdGdldEhhc2hCeXRlTGVuZ3RoOiBmdW5jdGlvbihhbGdvKSB7XG5cdFx0c3dpdGNoKGFsZ28pIHtcblx0XHRjYXNlIDE6IC8vIC0gTUQ1IFtIQUNdXG5cdFx0XHRyZXR1cm4gMTY7XG5cdFx0Y2FzZSAyOiAvLyAtIFNIQS0xIFtGSVBTMTgwXVxuXHRcdGNhc2UgMzogLy8gLSBSSVBFLU1ELzE2MCBbSEFDXVxuXHRcdFx0cmV0dXJuIDIwO1xuXHRcdGNhc2UgODogLy8gLSBTSEEyNTYgW0ZJUFMxODBdXG5cdFx0XHRyZXR1cm4gMzI7XG5cdFx0Y2FzZSA5OiAvLyAtIFNIQTM4NCBbRklQUzE4MF1cblx0XHRcdHJldHVybiA0OFxuXHRcdGNhc2UgMTA6Ly8gLSBTSEE1MTIgW0ZJUFMxODBdXG5cdFx0XHRyZXR1cm4gNjQ7XG5cdFx0Y2FzZSAxMTovLyAtIFNIQTIyNCBbRklQUzE4MF1cblx0XHRcdHJldHVybiAyODtcblx0XHRkZWZhdWx0OlxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhhc2ggYWxnb3JpdGhtLicpO1xuXHRcdH1cblx0fVxuXG59XG5cbiIsIi8qKlxuICogQSBmYXN0IE1ENSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTIgSm9zZXBoIE15ZXJzXG4gKiBodHRwOi8vd3d3Lm15ZXJzZGFpbHkub3JnL2pvc2VwaC9qYXZhc2NyaXB0L21kNS10ZXh0Lmh0bWxcbiAqXG4gKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlXG4gKiBhbmQgaXRzIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlcyBhbmQgd2l0aG91dFxuICogZmVlIGlzIGhlcmVieSBncmFudGVkIHByb3ZpZGVkIHRoYXQgdGhpcyBjb3B5cmlnaHQgbm90aWNlXG4gKiBhcHBlYXJzIGluIGFsbCBjb3BpZXMuXG4gKlxuICogT2YgY291cnNlLCB0aGlzIHNvZnQgaXMgcHJvdmlkZWQgXCJhcyBpc1wiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkXG4gKiB3YXJyYW50eSBvZiBhbnkga2luZC5cbiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvdXRpbC5qcycpO1xuXG5mdW5jdGlvbiBNRDUoZW50cmVlKSB7XG5cdHZhciBoZXggPSBtZDUoZW50cmVlKTtcblx0dmFyIGJpbiA9IHV0aWwuaGV4MmJpbihoZXgpO1xuXHRyZXR1cm4gYmluO1xufVxuXG5mdW5jdGlvbiBtZDVjeWNsZSh4LCBrKSB7XG52YXIgYSA9IHhbMF0sIGIgPSB4WzFdLCBjID0geFsyXSwgZCA9IHhbM107XG5cbmEgPSBmZihhLCBiLCBjLCBkLCBrWzBdLCA3LCAtNjgwODc2OTM2KTtcbmQgPSBmZihkLCBhLCBiLCBjLCBrWzFdLCAxMiwgLTM4OTU2NDU4Nik7XG5jID0gZmYoYywgZCwgYSwgYiwga1syXSwgMTcsICA2MDYxMDU4MTkpO1xuYiA9IGZmKGIsIGMsIGQsIGEsIGtbM10sIDIyLCAtMTA0NDUyNTMzMCk7XG5hID0gZmYoYSwgYiwgYywgZCwga1s0XSwgNywgLTE3NjQxODg5Nyk7XG5kID0gZmYoZCwgYSwgYiwgYywga1s1XSwgMTIsICAxMjAwMDgwNDI2KTtcbmMgPSBmZihjLCBkLCBhLCBiLCBrWzZdLCAxNywgLTE0NzMyMzEzNDEpO1xuYiA9IGZmKGIsIGMsIGQsIGEsIGtbN10sIDIyLCAtNDU3MDU5ODMpO1xuYSA9IGZmKGEsIGIsIGMsIGQsIGtbOF0sIDcsICAxNzcwMDM1NDE2KTtcbmQgPSBmZihkLCBhLCBiLCBjLCBrWzldLCAxMiwgLTE5NTg0MTQ0MTcpO1xuYyA9IGZmKGMsIGQsIGEsIGIsIGtbMTBdLCAxNywgLTQyMDYzKTtcbmIgPSBmZihiLCBjLCBkLCBhLCBrWzExXSwgMjIsIC0xOTkwNDA0MTYyKTtcbmEgPSBmZihhLCBiLCBjLCBkLCBrWzEyXSwgNywgIDE4MDQ2MDM2ODIpO1xuZCA9IGZmKGQsIGEsIGIsIGMsIGtbMTNdLCAxMiwgLTQwMzQxMTAxKTtcbmMgPSBmZihjLCBkLCBhLCBiLCBrWzE0XSwgMTcsIC0xNTAyMDAyMjkwKTtcbmIgPSBmZihiLCBjLCBkLCBhLCBrWzE1XSwgMjIsICAxMjM2NTM1MzI5KTtcblxuYSA9IGdnKGEsIGIsIGMsIGQsIGtbMV0sIDUsIC0xNjU3OTY1MTApO1xuZCA9IGdnKGQsIGEsIGIsIGMsIGtbNl0sIDksIC0xMDY5NTAxNjMyKTtcbmMgPSBnZyhjLCBkLCBhLCBiLCBrWzExXSwgMTQsICA2NDM3MTc3MTMpO1xuYiA9IGdnKGIsIGMsIGQsIGEsIGtbMF0sIDIwLCAtMzczODk3MzAyKTtcbmEgPSBnZyhhLCBiLCBjLCBkLCBrWzVdLCA1LCAtNzAxNTU4NjkxKTtcbmQgPSBnZyhkLCBhLCBiLCBjLCBrWzEwXSwgOSwgIDM4MDE2MDgzKTtcbmMgPSBnZyhjLCBkLCBhLCBiLCBrWzE1XSwgMTQsIC02NjA0NzgzMzUpO1xuYiA9IGdnKGIsIGMsIGQsIGEsIGtbNF0sIDIwLCAtNDA1NTM3ODQ4KTtcbmEgPSBnZyhhLCBiLCBjLCBkLCBrWzldLCA1LCAgNTY4NDQ2NDM4KTtcbmQgPSBnZyhkLCBhLCBiLCBjLCBrWzE0XSwgOSwgLTEwMTk4MDM2OTApO1xuYyA9IGdnKGMsIGQsIGEsIGIsIGtbM10sIDE0LCAtMTg3MzYzOTYxKTtcbmIgPSBnZyhiLCBjLCBkLCBhLCBrWzhdLCAyMCwgIDExNjM1MzE1MDEpO1xuYSA9IGdnKGEsIGIsIGMsIGQsIGtbMTNdLCA1LCAtMTQ0NDY4MTQ2Nyk7XG5kID0gZ2coZCwgYSwgYiwgYywga1syXSwgOSwgLTUxNDAzNzg0KTtcbmMgPSBnZyhjLCBkLCBhLCBiLCBrWzddLCAxNCwgIDE3MzUzMjg0NzMpO1xuYiA9IGdnKGIsIGMsIGQsIGEsIGtbMTJdLCAyMCwgLTE5MjY2MDc3MzQpO1xuXG5hID0gaGgoYSwgYiwgYywgZCwga1s1XSwgNCwgLTM3ODU1OCk7XG5kID0gaGgoZCwgYSwgYiwgYywga1s4XSwgMTEsIC0yMDIyNTc0NDYzKTtcbmMgPSBoaChjLCBkLCBhLCBiLCBrWzExXSwgMTYsICAxODM5MDMwNTYyKTtcbmIgPSBoaChiLCBjLCBkLCBhLCBrWzE0XSwgMjMsIC0zNTMwOTU1Nik7XG5hID0gaGgoYSwgYiwgYywgZCwga1sxXSwgNCwgLTE1MzA5OTIwNjApO1xuZCA9IGhoKGQsIGEsIGIsIGMsIGtbNF0sIDExLCAgMTI3Mjg5MzM1Myk7XG5jID0gaGgoYywgZCwgYSwgYiwga1s3XSwgMTYsIC0xNTU0OTc2MzIpO1xuYiA9IGhoKGIsIGMsIGQsIGEsIGtbMTBdLCAyMywgLTEwOTQ3MzA2NDApO1xuYSA9IGhoKGEsIGIsIGMsIGQsIGtbMTNdLCA0LCAgNjgxMjc5MTc0KTtcbmQgPSBoaChkLCBhLCBiLCBjLCBrWzBdLCAxMSwgLTM1ODUzNzIyMik7XG5jID0gaGgoYywgZCwgYSwgYiwga1szXSwgMTYsIC03MjI1MjE5NzkpO1xuYiA9IGhoKGIsIGMsIGQsIGEsIGtbNl0sIDIzLCAgNzYwMjkxODkpO1xuYSA9IGhoKGEsIGIsIGMsIGQsIGtbOV0sIDQsIC02NDAzNjQ0ODcpO1xuZCA9IGhoKGQsIGEsIGIsIGMsIGtbMTJdLCAxMSwgLTQyMTgxNTgzNSk7XG5jID0gaGgoYywgZCwgYSwgYiwga1sxNV0sIDE2LCAgNTMwNzQyNTIwKTtcbmIgPSBoaChiLCBjLCBkLCBhLCBrWzJdLCAyMywgLTk5NTMzODY1MSk7XG5cbmEgPSBpaShhLCBiLCBjLCBkLCBrWzBdLCA2LCAtMTk4NjMwODQ0KTtcbmQgPSBpaShkLCBhLCBiLCBjLCBrWzddLCAxMCwgIDExMjY4OTE0MTUpO1xuYyA9IGlpKGMsIGQsIGEsIGIsIGtbMTRdLCAxNSwgLTE0MTYzNTQ5MDUpO1xuYiA9IGlpKGIsIGMsIGQsIGEsIGtbNV0sIDIxLCAtNTc0MzQwNTUpO1xuYSA9IGlpKGEsIGIsIGMsIGQsIGtbMTJdLCA2LCAgMTcwMDQ4NTU3MSk7XG5kID0gaWkoZCwgYSwgYiwgYywga1szXSwgMTAsIC0xODk0OTg2NjA2KTtcbmMgPSBpaShjLCBkLCBhLCBiLCBrWzEwXSwgMTUsIC0xMDUxNTIzKTtcbmIgPSBpaShiLCBjLCBkLCBhLCBrWzFdLCAyMSwgLTIwNTQ5MjI3OTkpO1xuYSA9IGlpKGEsIGIsIGMsIGQsIGtbOF0sIDYsICAxODczMzEzMzU5KTtcbmQgPSBpaShkLCBhLCBiLCBjLCBrWzE1XSwgMTAsIC0zMDYxMTc0NCk7XG5jID0gaWkoYywgZCwgYSwgYiwga1s2XSwgMTUsIC0xNTYwMTk4MzgwKTtcbmIgPSBpaShiLCBjLCBkLCBhLCBrWzEzXSwgMjEsICAxMzA5MTUxNjQ5KTtcbmEgPSBpaShhLCBiLCBjLCBkLCBrWzRdLCA2LCAtMTQ1NTIzMDcwKTtcbmQgPSBpaShkLCBhLCBiLCBjLCBrWzExXSwgMTAsIC0xMTIwMjEwMzc5KTtcbmMgPSBpaShjLCBkLCBhLCBiLCBrWzJdLCAxNSwgIDcxODc4NzI1OSk7XG5iID0gaWkoYiwgYywgZCwgYSwga1s5XSwgMjEsIC0zNDM0ODU1NTEpO1xuXG54WzBdID0gYWRkMzIoYSwgeFswXSk7XG54WzFdID0gYWRkMzIoYiwgeFsxXSk7XG54WzJdID0gYWRkMzIoYywgeFsyXSk7XG54WzNdID0gYWRkMzIoZCwgeFszXSk7XG5cbn1cblxuZnVuY3Rpb24gY21uKHEsIGEsIGIsIHgsIHMsIHQpIHtcbmEgPSBhZGQzMihhZGQzMihhLCBxKSwgYWRkMzIoeCwgdCkpO1xucmV0dXJuIGFkZDMyKChhIDw8IHMpIHwgKGEgPj4+ICgzMiAtIHMpKSwgYik7XG59XG5cbmZ1bmN0aW9uIGZmKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbnJldHVybiBjbW4oKGIgJiBjKSB8ICgofmIpICYgZCksIGEsIGIsIHgsIHMsIHQpO1xufVxuXG5mdW5jdGlvbiBnZyhhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG5yZXR1cm4gY21uKChiICYgZCkgfCAoYyAmICh+ZCkpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gaGgoYSwgYiwgYywgZCwgeCwgcywgdCkge1xucmV0dXJuIGNtbihiIF4gYyBeIGQsIGEsIGIsIHgsIHMsIHQpO1xufVxuXG5mdW5jdGlvbiBpaShhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG5yZXR1cm4gY21uKGMgXiAoYiB8ICh+ZCkpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gbWQ1MShzKSB7XG50eHQgPSAnJztcbnZhciBuID0gcy5sZW5ndGgsXG5zdGF0ZSA9IFsxNzMyNTg0MTkzLCAtMjcxNzMzODc5LCAtMTczMjU4NDE5NCwgMjcxNzMzODc4XSwgaTtcbmZvciAoaT02NDsgaTw9cy5sZW5ndGg7IGkrPTY0KSB7XG5tZDVjeWNsZShzdGF0ZSwgbWQ1YmxrKHMuc3Vic3RyaW5nKGktNjQsIGkpKSk7XG59XG5zID0gcy5zdWJzdHJpbmcoaS02NCk7XG52YXIgdGFpbCA9IFswLDAsMCwwLCAwLDAsMCwwLCAwLDAsMCwwLCAwLDAsMCwwXTtcbmZvciAoaT0wOyBpPHMubGVuZ3RoOyBpKyspXG50YWlsW2k+PjJdIHw9IHMuY2hhckNvZGVBdChpKSA8PCAoKGklNCkgPDwgMyk7XG50YWlsW2k+PjJdIHw9IDB4ODAgPDwgKChpJTQpIDw8IDMpO1xuaWYgKGkgPiA1NSkge1xubWQ1Y3ljbGUoc3RhdGUsIHRhaWwpO1xuZm9yIChpPTA7IGk8MTY7IGkrKykgdGFpbFtpXSA9IDA7XG59XG50YWlsWzE0XSA9IG4qODtcbm1kNWN5Y2xlKHN0YXRlLCB0YWlsKTtcbnJldHVybiBzdGF0ZTtcbn1cblxuLyogdGhlcmUgbmVlZHMgdG8gYmUgc3VwcG9ydCBmb3IgVW5pY29kZSBoZXJlLFxuICogdW5sZXNzIHdlIHByZXRlbmQgdGhhdCB3ZSBjYW4gcmVkZWZpbmUgdGhlIE1ELTVcbiAqIGFsZ29yaXRobSBmb3IgbXVsdGktYnl0ZSBjaGFyYWN0ZXJzIChwZXJoYXBzXG4gKiBieSBhZGRpbmcgZXZlcnkgZm91ciAxNi1iaXQgY2hhcmFjdGVycyBhbmRcbiAqIHNob3J0ZW5pbmcgdGhlIHN1bSB0byAzMiBiaXRzKS4gT3RoZXJ3aXNlXG4gKiBJIHN1Z2dlc3QgcGVyZm9ybWluZyBNRC01IGFzIGlmIGV2ZXJ5IGNoYXJhY3RlclxuICogd2FzIHR3byBieXRlcy0tZS5nLiwgMDA0MCAwMDI1ID0gQCUtLWJ1dCB0aGVuXG4gKiBob3cgd2lsbCBhbiBvcmRpbmFyeSBNRC01IHN1bSBiZSBtYXRjaGVkP1xuICogVGhlcmUgaXMgbm8gd2F5IHRvIHN0YW5kYXJkaXplIHRleHQgdG8gc29tZXRoaW5nXG4gKiBsaWtlIFVURi04IGJlZm9yZSB0cmFuc2Zvcm1hdGlvbjsgc3BlZWQgY29zdCBpc1xuICogdXR0ZXJseSBwcm9oaWJpdGl2ZS4gVGhlIEphdmFTY3JpcHQgc3RhbmRhcmRcbiAqIGl0c2VsZiBuZWVkcyB0byBsb29rIGF0IHRoaXM6IGl0IHNob3VsZCBzdGFydFxuICogcHJvdmlkaW5nIGFjY2VzcyB0byBzdHJpbmdzIGFzIHByZWZvcm1lZCBVVEYtOFxuICogOC1iaXQgdW5zaWduZWQgdmFsdWUgYXJyYXlzLlxuICovXG5mdW5jdGlvbiBtZDVibGsocykgeyAvKiBJIGZpZ3VyZWQgZ2xvYmFsIHdhcyBmYXN0ZXIuICAgKi9cbnZhciBtZDVibGtzID0gW10sIGk7IC8qIEFuZHkgS2luZyBzYWlkIGRvIGl0IHRoaXMgd2F5LiAqL1xuZm9yIChpPTA7IGk8NjQ7IGkrPTQpIHtcbm1kNWJsa3NbaT4+Ml0gPSBzLmNoYXJDb2RlQXQoaSlcbisgKHMuY2hhckNvZGVBdChpKzEpIDw8IDgpXG4rIChzLmNoYXJDb2RlQXQoaSsyKSA8PCAxNilcbisgKHMuY2hhckNvZGVBdChpKzMpIDw8IDI0KTtcbn1cbnJldHVybiBtZDVibGtzO1xufVxuXG52YXIgaGV4X2NociA9ICcwMTIzNDU2Nzg5YWJjZGVmJy5zcGxpdCgnJyk7XG5cbmZ1bmN0aW9uIHJoZXgobilcbntcbnZhciBzPScnLCBqPTA7XG5mb3IoOyBqPDQ7IGorKylcbnMgKz0gaGV4X2NoclsobiA+PiAoaiAqIDggKyA0KSkgJiAweDBGXVxuKyBoZXhfY2hyWyhuID4+IChqICogOCkpICYgMHgwRl07XG5yZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gaGV4KHgpIHtcbmZvciAodmFyIGk9MDsgaTx4Lmxlbmd0aDsgaSsrKVxueFtpXSA9IHJoZXgoeFtpXSk7XG5yZXR1cm4geC5qb2luKCcnKTtcbn1cblxuZnVuY3Rpb24gbWQ1KHMpIHtcbnJldHVybiBoZXgobWQ1MShzKSk7XG59XG5cbi8qIHRoaXMgZnVuY3Rpb24gaXMgbXVjaCBmYXN0ZXIsXG5zbyBpZiBwb3NzaWJsZSB3ZSB1c2UgaXQuIFNvbWUgSUVzXG5hcmUgdGhlIG9ubHkgb25lcyBJIGtub3cgb2YgdGhhdFxubmVlZCB0aGUgaWRpb3RpYyBzZWNvbmQgZnVuY3Rpb24sXG5nZW5lcmF0ZWQgYnkgYW4gaWYgY2xhdXNlLiAgKi9cblxuZnVuY3Rpb24gYWRkMzIoYSwgYikge1xucmV0dXJuIChhICsgYikgJiAweEZGRkZGRkZGO1xufVxuXG5pZiAobWQ1KCdoZWxsbycpICE9ICc1ZDQxNDAyYWJjNGIyYTc2Yjk3MTlkOTExMDE3YzU5MicpIHtcbmZ1bmN0aW9uIGFkZDMyKHgsIHkpIHtcbnZhciBsc3cgPSAoeCAmIDB4RkZGRikgKyAoeSAmIDB4RkZGRiksXG5tc3cgPSAoeCA+PiAxNikgKyAoeSA+PiAxNikgKyAobHN3ID4+IDE2KTtcbnJldHVybiAobXN3IDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xufVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IE1ENVxuIiwiLypcbiAqIENyeXB0b01YIFRvb2xzXG4gKiBDb3B5cmlnaHQgKEMpIDIwMDQgLSAyMDA2IERlcmVrIEJ1aXRlbmh1aXNcbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4gKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDJcbiAqIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4gKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcsIFVTQS5cbiAqL1xuXG4vKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkhcbiAqL1xuXG52YXIgUk1Ec2l6ZSAgID0gMTYwO1xudmFyIFggPSBuZXcgQXJyYXkoKTtcblxuZnVuY3Rpb24gUk9MKHgsIG4pXG57XG4gIHJldHVybiBuZXcgTnVtYmVyICgoeCA8PCBuKSB8ICggeCA+Pj4gKDMyIC0gbikpKTtcbn1cblxuZnVuY3Rpb24gRih4LCB5LCB6KVxue1xuICByZXR1cm4gbmV3IE51bWJlcih4IF4geSBeIHopO1xufVxuXG5mdW5jdGlvbiBHKHgsIHksIHopXG57XG4gIHJldHVybiBuZXcgTnVtYmVyKCh4ICYgeSkgfCAofnggJiB6KSk7XG59XG5cbmZ1bmN0aW9uIEgoeCwgeSwgeilcbntcbiAgcmV0dXJuIG5ldyBOdW1iZXIoKHggfCB+eSkgXiB6KTtcbn1cblxuZnVuY3Rpb24gSSh4LCB5LCB6KVxue1xuICByZXR1cm4gbmV3IE51bWJlcigoeCAmIHopIHwgKHkgJiB+eikpO1xufVxuXG5mdW5jdGlvbiBKKHgsIHksIHopXG57XG4gIHJldHVybiBuZXcgTnVtYmVyKHggXiAoeSB8IH56KSk7XG59XG5cbmZ1bmN0aW9uIG1peE9uZVJvdW5kKGEsIGIsIGMsIGQsIGUsIHgsIHMsIHJvdW5kTnVtYmVyKVxue1xuICBzd2l0Y2ggKHJvdW5kTnVtYmVyKVxuICB7XG4gICAgY2FzZSAwIDogYSArPSBGKGIsIGMsIGQpICsgeCArIDB4MDAwMDAwMDA7IGJyZWFrO1xuICAgIGNhc2UgMSA6IGEgKz0gRyhiLCBjLCBkKSArIHggKyAweDVhODI3OTk5OyBicmVhaztcbiAgICBjYXNlIDIgOiBhICs9IEgoYiwgYywgZCkgKyB4ICsgMHg2ZWQ5ZWJhMTsgYnJlYWs7XG4gICAgY2FzZSAzIDogYSArPSBJKGIsIGMsIGQpICsgeCArIDB4OGYxYmJjZGM7IGJyZWFrO1xuICAgIGNhc2UgNCA6IGEgKz0gSihiLCBjLCBkKSArIHggKyAweGE5NTNmZDRlOyBicmVhaztcbiAgICBjYXNlIDUgOiBhICs9IEooYiwgYywgZCkgKyB4ICsgMHg1MGEyOGJlNjsgYnJlYWs7XG4gICAgY2FzZSA2IDogYSArPSBJKGIsIGMsIGQpICsgeCArIDB4NWM0ZGQxMjQ7IGJyZWFrO1xuICAgIGNhc2UgNyA6IGEgKz0gSChiLCBjLCBkKSArIHggKyAweDZkNzAzZWYzOyBicmVhaztcbiAgICBjYXNlIDggOiBhICs9IEcoYiwgYywgZCkgKyB4ICsgMHg3YTZkNzZlOTsgYnJlYWs7XG4gICAgY2FzZSA5IDogYSArPSBGKGIsIGMsIGQpICsgeCArIDB4MDAwMDAwMDA7IGJyZWFrO1xuICAgIFxuICAgIGRlZmF1bHQgOiBkb2N1bWVudC53cml0ZShcIkJvZ3VzIHJvdW5kIG51bWJlclwiKTsgYnJlYWs7XG4gIH0gIFxuICBcbiAgYSA9IFJPTChhLCBzKSArIGU7XG4gIGMgPSBST0woYywgMTApO1xuXG4gIGEgJj0gMHhmZmZmZmZmZjtcbiAgYiAmPSAweGZmZmZmZmZmO1xuICBjICY9IDB4ZmZmZmZmZmY7XG4gIGQgJj0gMHhmZmZmZmZmZjtcbiAgZSAmPSAweGZmZmZmZmZmO1xuXG4gIHZhciByZXRCbG9jayA9IG5ldyBBcnJheSgpO1xuICByZXRCbG9ja1swXSA9IGE7XG4gIHJldEJsb2NrWzFdID0gYjtcbiAgcmV0QmxvY2tbMl0gPSBjO1xuICByZXRCbG9ja1szXSA9IGQ7XG4gIHJldEJsb2NrWzRdID0gZTtcbiAgcmV0QmxvY2tbNV0gPSB4O1xuICByZXRCbG9ja1s2XSA9IHM7XG5cbiAgcmV0dXJuIHJldEJsb2NrO1xufVxuXG5mdW5jdGlvbiBNRGluaXQgKE1EYnVmKVxue1xuICBNRGJ1ZlswXSA9IDB4Njc0NTIzMDE7XG4gIE1EYnVmWzFdID0gMHhlZmNkYWI4OTtcbiAgTURidWZbMl0gPSAweDk4YmFkY2ZlO1xuICBNRGJ1ZlszXSA9IDB4MTAzMjU0NzY7XG4gIE1EYnVmWzRdID0gMHhjM2QyZTFmMDtcbn1cblxudmFyIFJPTHMgPSBbXG4gIFsxMSwgMTQsIDE1LCAxMiwgIDUsICA4LCAgNywgIDksIDExLCAxMywgMTQsIDE1LCAgNiwgIDcsICA5LCAgOF0sXG4gIFsgNywgIDYsICA4LCAxMywgMTEsICA5LCAgNywgMTUsICA3LCAxMiwgMTUsICA5LCAxMSwgIDcsIDEzLCAxMl0sXG4gIFsxMSwgMTMsICA2LCAgNywgMTQsICA5LCAxMywgMTUsIDE0LCAgOCwgMTMsICA2LCAgNSwgMTIsICA3LCAgNV0sXG4gIFsxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCAgOSwgIDgsICA5LCAxNCwgIDUsICA2LCAgOCwgIDYsICA1LCAxMl0sXG4gIFsgOSwgMTUsICA1LCAxMSwgIDYsICA4LCAxMywgMTIsICA1LCAxMiwgMTMsIDE0LCAxMSwgIDgsICA1LCAgNl0sXG4gIFsgOCwgIDksICA5LCAxMSwgMTMsIDE1LCAxNSwgIDUsICA3LCAgNywgIDgsIDExLCAxNCwgMTQsIDEyLCAgNl0sXG4gIFsgOSwgMTMsIDE1LCAgNywgMTIsICA4LCAgOSwgMTEsICA3LCAgNywgMTIsICA3LCAgNiwgMTUsIDEzLCAxMV0sXG4gIFsgOSwgIDcsIDE1LCAxMSwgIDgsICA2LCAgNiwgMTQsIDEyLCAxMywgIDUsIDE0LCAxMywgMTMsICA3LCAgNV0sXG4gIFsxNSwgIDUsICA4LCAxMSwgMTQsIDE0LCAgNiwgMTQsICA2LCAgOSwgMTIsICA5LCAxMiwgIDUsIDE1LCAgOF0sXG4gIFsgOCwgIDUsIDEyLCAgOSwgMTIsICA1LCAxNCwgIDYsICA4LCAxMywgIDYsICA1LCAxNSwgMTMsIDExLCAxMV1cbl07XG5cbnZhciBpbmRleGVzID0gW1xuICBbIDAsICAxLCAgMiwgIDMsICA0LCAgNSwgIDYsICA3LCAgOCwgIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTVdLFxuICBbIDcsICA0LCAxMywgIDEsIDEwLCAgNiwgMTUsICAzLCAxMiwgIDAsICA5LCAgNSwgIDIsIDE0LCAxMSwgIDhdLFxuICBbIDMsIDEwLCAxNCwgIDQsICA5LCAxNSwgIDgsICAxLCAgMiwgIDcsICAwLCAgNiwgMTMsIDExLCAgNSwgMTJdLFxuICBbIDEsICA5LCAxMSwgMTAsICAwLCAgOCwgMTIsICA0LCAxMywgIDMsICA3LCAxNSwgMTQsICA1LCAgNiwgIDJdLFxuICBbIDQsICAwLCAgNSwgIDksICA3LCAxMiwgIDIsIDEwLCAxNCwgIDEsICAzLCAgOCwgMTEsICA2LCAxNSwgMTNdLFxuICBbIDUsIDE0LCAgNywgIDAsICA5LCAgMiwgMTEsICA0LCAxMywgIDYsIDE1LCAgOCwgIDEsIDEwLCAgMywgMTJdLFxuICBbIDYsIDExLCAgMywgIDcsICAwLCAxMywgIDUsIDEwLCAxNCwgMTUsICA4LCAxMiwgIDQsICA5LCAgMSwgIDJdLFxuICBbMTUsICA1LCAgMSwgIDMsICA3LCAxNCwgIDYsICA5LCAxMSwgIDgsIDEyLCAgMiwgMTAsICAwLCAgNCwgMTNdLFxuICBbIDgsICA2LCAgNCwgIDEsICAzLCAxMSwgMTUsICAwLCAgNSwgMTIsICAyLCAxMywgIDksICA3LCAxMCwgMTRdLFxuICBbMTIsIDE1LCAxMCwgIDQsICAxLCAgNSwgIDgsICA3LCAgNiwgIDIsIDEzLCAxNCwgIDAsICAzLCAgOSwgMTFdXG5dO1xuXG5mdW5jdGlvbiBjb21wcmVzcyAoTURidWYsIFgpXG57XG4gIGJsb2NrQSA9IG5ldyBBcnJheSgpO1xuICBibG9ja0IgPSBuZXcgQXJyYXkoKTtcblxuICB2YXIgcmV0QmxvY2s7XG5cbiAgZm9yICh2YXIgaT0wOyBpIDwgNTsgaSsrKVxuICB7XG4gICAgYmxvY2tBW2ldID0gbmV3IE51bWJlcihNRGJ1ZltpXSk7XG4gICAgYmxvY2tCW2ldID0gbmV3IE51bWJlcihNRGJ1ZltpXSk7XG4gIH1cblxuICB2YXIgc3RlcCA9IDA7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgNTsgaisrKVxuICB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKVxuICAgIHtcbiAgICAgIHJldEJsb2NrID0gbWl4T25lUm91bmQoXG4gICAgICAgIGJsb2NrQVsoc3RlcCswKSAlIDVdLFxuICAgICAgICBibG9ja0FbKHN0ZXArMSkgJSA1XSwgICBcbiAgICAgICAgYmxvY2tBWyhzdGVwKzIpICUgNV0sICAgXG4gICAgICAgIGJsb2NrQVsoc3RlcCszKSAlIDVdLCAgIFxuICAgICAgICBibG9ja0FbKHN0ZXArNCkgJSA1XSwgIFxuICAgICAgICBYW2luZGV4ZXNbal1baV1dLCBcbiAgICAgICAgUk9Mc1tqXVtpXSxcbiAgICAgICAgalxuICAgICAgKTtcblxuICAgICAgYmxvY2tBWyhzdGVwKzApICUgNV0gPSByZXRCbG9ja1swXTtcbiAgICAgIGJsb2NrQVsoc3RlcCsxKSAlIDVdID0gcmV0QmxvY2tbMV07XG4gICAgICBibG9ja0FbKHN0ZXArMikgJSA1XSA9IHJldEJsb2NrWzJdO1xuICAgICAgYmxvY2tBWyhzdGVwKzMpICUgNV0gPSByZXRCbG9ja1szXTtcbiAgICAgIGJsb2NrQVsoc3RlcCs0KSAlIDVdID0gcmV0QmxvY2tbNF07XG5cbiAgICAgIHN0ZXAgKz0gNDtcbiAgICB9XG4gIH1cblxuICBzdGVwID0gMDtcbiAgZm9yICh2YXIgaiA9IDU7IGogPCAxMDsgaisrKVxuICB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKVxuICAgIHsgIFxuICAgICAgcmV0QmxvY2sgPSBtaXhPbmVSb3VuZChcbiAgICAgICAgYmxvY2tCWyhzdGVwKzApICUgNV0sIFxuICAgICAgICBibG9ja0JbKHN0ZXArMSkgJSA1XSwgXG4gICAgICAgIGJsb2NrQlsoc3RlcCsyKSAlIDVdLCBcbiAgICAgICAgYmxvY2tCWyhzdGVwKzMpICUgNV0sIFxuICAgICAgICBibG9ja0JbKHN0ZXArNCkgJSA1XSwgIFxuICAgICAgICBYW2luZGV4ZXNbal1baV1dLCBcbiAgICAgICAgUk9Mc1tqXVtpXSxcbiAgICAgICAgalxuICAgICAgKTtcblxuICAgICAgYmxvY2tCWyhzdGVwKzApICUgNV0gPSByZXRCbG9ja1swXTtcbiAgICAgIGJsb2NrQlsoc3RlcCsxKSAlIDVdID0gcmV0QmxvY2tbMV07XG4gICAgICBibG9ja0JbKHN0ZXArMikgJSA1XSA9IHJldEJsb2NrWzJdO1xuICAgICAgYmxvY2tCWyhzdGVwKzMpICUgNV0gPSByZXRCbG9ja1szXTtcbiAgICAgIGJsb2NrQlsoc3RlcCs0KSAlIDVdID0gcmV0QmxvY2tbNF07XG5cbiAgICAgIHN0ZXAgKz0gNDtcbiAgICB9XG4gIH1cblxuICBibG9ja0JbM10gKz0gYmxvY2tBWzJdICsgTURidWZbMV07XG4gIE1EYnVmWzFdICA9IE1EYnVmWzJdICsgYmxvY2tBWzNdICsgYmxvY2tCWzRdO1xuICBNRGJ1ZlsyXSAgPSBNRGJ1ZlszXSArIGJsb2NrQVs0XSArIGJsb2NrQlswXTtcbiAgTURidWZbM10gID0gTURidWZbNF0gKyBibG9ja0FbMF0gKyBibG9ja0JbMV07XG4gIE1EYnVmWzRdICA9IE1EYnVmWzBdICsgYmxvY2tBWzFdICsgYmxvY2tCWzJdO1xuICBNRGJ1ZlswXSAgPSBibG9ja0JbM107XG59XG5cbmZ1bmN0aW9uIHplcm9YKFgpXG57XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykgeyBYW2ldID0gMDsgfVxufVxuXG5mdW5jdGlvbiBNRGZpbmlzaCAoTURidWYsIHN0cnB0ciwgbHN3bGVuLCBtc3dsZW4pXG57XG4gIHZhciBYID0gbmV3IEFycmF5KDE2KTtcbiAgemVyb1goWCk7XG5cbiAgdmFyIGogPSAwO1xuICBmb3IgKHZhciBpPTA7IGkgPCAobHN3bGVuICYgNjMpOyBpKyspXG4gIHtcbiAgICBYW2kgPj4+IDJdIF49IChzdHJwdHIuY2hhckNvZGVBdChqKyspICYgMjU1KSA8PCAoOCAqIChpICYgMykpO1xuICB9XG5cbiAgWFsobHN3bGVuID4+PiAyKSAmIDE1XSBePSAxIDw8ICg4ICogKGxzd2xlbiAmIDMpICsgNyk7XG5cbiAgaWYgKChsc3dsZW4gJiA2MykgPiA1NSlcbiAge1xuICAgIGNvbXByZXNzKE1EYnVmLCBYKTtcbiAgICB2YXIgWCA9IG5ldyBBcnJheSgxNik7XG4gICAgemVyb1goWCk7XG4gIH1cblxuICBYWzE0XSA9IGxzd2xlbiA8PCAzO1xuICBYWzE1XSA9IChsc3dsZW4gPj4+IDI5KSB8IChtc3dsZW4gPDwgMyk7XG5cbiAgY29tcHJlc3MoTURidWYsIFgpO1xufVxuXG5mdW5jdGlvbiBCWVRFU19UT19EV09SRChmb3VyQ2hhcnMpXG57XG4gIHZhciB0bXAgID0gKGZvdXJDaGFycy5jaGFyQ29kZUF0KDMpICYgMjU1KSA8PCAyNDtcbiAgdG1wICAgfD0gKGZvdXJDaGFycy5jaGFyQ29kZUF0KDIpICYgMjU1KSA8PCAxNjtcbiAgdG1wICAgfD0gKGZvdXJDaGFycy5jaGFyQ29kZUF0KDEpICYgMjU1KSA8PCA4O1xuICB0bXAgICB8PSAoZm91ckNoYXJzLmNoYXJDb2RlQXQoMCkgJiAyNTUpOyAgXG5cbiAgcmV0dXJuIHRtcDtcbn1cblxuZnVuY3Rpb24gUk1EKG1lc3NhZ2UpXG57XG4gIHZhciBNRGJ1ZiAgID0gbmV3IEFycmF5KFJNRHNpemUgLyAzMik7XG4gIHZhciBoYXNoY29kZSAgID0gbmV3IEFycmF5KFJNRHNpemUgLyA4KTtcbiAgdmFyIGxlbmd0aDsgIFxuICB2YXIgbmJ5dGVzO1xuXG4gIE1EaW5pdChNRGJ1Zik7XG4gIGxlbmd0aCA9IG1lc3NhZ2UubGVuZ3RoO1xuXG4gIHZhciBYID0gbmV3IEFycmF5KDE2KTtcbiAgemVyb1goWCk7XG5cbiAgdmFyIGo9MDtcbiAgZm9yICh2YXIgbmJ5dGVzPWxlbmd0aDsgbmJ5dGVzID4gNjM7IG5ieXRlcyAtPSA2NClcbiAge1xuICAgIGZvciAodmFyIGk9MDsgaSA8IDE2OyBpKyspXG4gICAge1xuICAgICAgWFtpXSA9IEJZVEVTX1RPX0RXT1JEKG1lc3NhZ2Uuc3Vic3RyKGosIDQpKTtcbiAgICAgIGogKz0gNDtcbiAgICB9XG4gICAgY29tcHJlc3MoTURidWYsIFgpO1xuICB9XG5cbiAgTURmaW5pc2goTURidWYsIG1lc3NhZ2Uuc3Vic3RyKGopLCBsZW5ndGgsIDApO1xuXG4gIGZvciAodmFyIGk9MDsgaSA8IFJNRHNpemUgLyA4OyBpICs9IDQpXG4gIHtcbiAgICBoYXNoY29kZVtpXSAgID0gIE1EYnVmW2kgPj4+IDJdICAgJiAyNTU7XG4gICAgaGFzaGNvZGVbaSsxXSA9IChNRGJ1ZltpID4+PiAyXSA+Pj4gOCkgICAmIDI1NTtcbiAgICBoYXNoY29kZVtpKzJdID0gKE1EYnVmW2kgPj4+IDJdID4+PiAxNikgJiAyNTU7XG4gICAgaGFzaGNvZGVbaSszXSA9IChNRGJ1ZltpID4+PiAyXSA+Pj4gMjQpICYgMjU1O1xuICB9XG5cbiAgcmV0dXJuIGhhc2hjb2RlO1xufVxuXG5cbmZ1bmN0aW9uIFJNRHN0cmluZyhtZXNzYWdlKVxue1xuICB2YXIgaGFzaGNvZGUgPSBSTUQobWVzc2FnZSk7XG4gIHZhciByZXRTdHJpbmcgPSBcIlwiO1xuXG4gIGZvciAodmFyIGk9MDsgaSA8IFJNRHNpemUvODsgaSsrKVxuICB7XG4gICAgcmV0U3RyaW5nICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoaGFzaGNvZGVbaV0pO1xuICB9ICBcblxuICByZXR1cm4gcmV0U3RyaW5nOyAgXG59XG5cbm1vZHVsZS5leHBvcnRzID0gUk1Ec3RyaW5nO1xuIiwiLyogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTSEEgZmFtaWx5IG9mIGhhc2hlcywgYXMgZGVmaW5lZCBpbiBGSVBTIFxuICogUFVCIDE4MC0yIGFzIHdlbGwgYXMgdGhlIGNvcnJlc3BvbmRpbmcgSE1BQyBpbXBsZW1lbnRhdGlvbiBhcyBkZWZpbmVkIGluXG4gKiBGSVBTIFBVQiAxOThhXG4gKlxuICogVmVyc2lvbiAxLjMgQ29weXJpZ2h0IEJyaWFuIFR1cmVrIDIwMDgtMjAxMFxuICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlXG4gKiBTZWUgaHR0cDovL2pzc2hhLnNvdXJjZWZvcmdlLm5ldC8gZm9yIG1vcmUgaW5mb3JtYXRpb25cbiAqXG4gKiBTZXZlcmFsIGZ1bmN0aW9ucyB0YWtlbiBmcm9tIFBhdWwgSm9obnNvblxuICovXG5cbi8qIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSFxuICogXG4gKiBUaGlzIGNvZGUgaGFzIGJlZW4gc2xpZ2h0bHkgbW9kaWZpZWQgZGlyZWN0IHN0cmluZyBvdXRwdXQ6XG4gKiAtIGJpbjJic3RyIGhhcyBiZWVuIGFkZGVkXG4gKiAtIGZvbGxvd2luZyB3cmFwcGVycyBvZiB0aGlzIGxpYnJhcnkgaGF2ZSBiZWVuIGFkZGVkOlxuICogICAtIHN0cl9zaGExXG4gKiAgIC0gc3RyX3NoYTI1NlxuICogICAtIHN0cl9zaGEyMjRcbiAqICAgLSBzdHJfc2hhMzg0XG4gKiAgIC0gc3RyX3NoYTUxMlxuICovXG5cbnZhciBqc1NIQSA9IChmdW5jdGlvbiAoKSB7XG5cdFxuXHQvKlxuXHQgKiBDb25maWd1cmFibGUgdmFyaWFibGVzLiBEZWZhdWx0cyB0eXBpY2FsbHkgd29ya1xuXHQgKi9cblx0LyogTnVtYmVyIG9mIEJpdHMgUGVyIGNoYXJhY3RlciAoOCBmb3IgQVNDSUksIDE2IGZvciBVbmljb2RlKSAqL1xuXHR2YXIgY2hhclNpemUgPSA4LCBcblx0LyogYmFzZS02NCBwYWQgY2hhcmFjdGVyLiBcIj1cIiBmb3Igc3RyaWN0IFJGQyBjb21wbGlhbmNlICovXG5cdGI2NHBhZCA9IFwiXCIsIFxuXHQvKiBoZXggb3V0cHV0IGZvcm1hdC4gMCAtIGxvd2VyY2FzZTsgMSAtIHVwcGVyY2FzZSAqL1xuXHRoZXhDYXNlID0gMCwgXG5cblx0Lypcblx0ICogSW50XzY0IGlzIGEgb2JqZWN0IGZvciAyIDMyLWJpdCBudW1iZXJzIGVtdWxhdGluZyBhIDY0LWJpdCBudW1iZXJcblx0ICpcblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBtc2ludF8zMiBUaGUgbW9zdCBzaWduaWZpY2FudCAzMi1iaXRzIG9mIGEgNjQtYml0IG51bWJlclxuXHQgKiBAcGFyYW0ge051bWJlcn0gbHNpbnRfMzIgVGhlIGxlYXN0IHNpZ25pZmljYW50IDMyLWJpdHMgb2YgYSA2NC1iaXQgbnVtYmVyXG5cdCAqL1xuXHRJbnRfNjQgPSBmdW5jdGlvbiAobXNpbnRfMzIsIGxzaW50XzMyKVxuXHR7XG5cdFx0dGhpcy5oaWdoT3JkZXIgPSBtc2ludF8zMjtcblx0XHR0aGlzLmxvd09yZGVyID0gbHNpbnRfMzI7XG5cdH0sXG5cblx0Lypcblx0ICogQ29udmVydCBhIHN0cmluZyB0byBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzXG5cdCAqIElmIGNoYXJTaXplIGlzIEFTQ0lJLCBjaGFyYWN0ZXJzID4yNTUgaGF2ZSB0aGVpciBoaS1ieXRlIHNpbGVudGx5XG5cdCAqIGlnbm9yZWQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGJlIGNvbnZlcnRlZCB0byBiaW5hcnkgcmVwcmVzZW50YXRpb25cblx0ICogQHJldHVybiBJbnRlZ2VyIGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYXJhbWV0ZXJcblx0ICovXG5cdHN0cjJiaW5iID0gZnVuY3Rpb24gKHN0cilcblx0e1xuXHRcdHZhciBiaW4gPSBbXSwgbWFzayA9ICgxIDw8IGNoYXJTaXplKSAtIDEsXG5cdFx0XHRsZW5ndGggPSBzdHIubGVuZ3RoICogY2hhclNpemUsIGk7XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IGNoYXJTaXplKVxuXHRcdHtcblx0XHRcdGJpbltpID4+IDVdIHw9IChzdHIuY2hhckNvZGVBdChpIC8gY2hhclNpemUpICYgbWFzaykgPDxcblx0XHRcdFx0KDMyIC0gY2hhclNpemUgLSAoaSAlIDMyKSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGJpbjtcblx0fSxcblxuXHQvKlxuXHQgKiBDb252ZXJ0IGEgaGV4IHN0cmluZyB0byBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzXG5cdCAqXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGJlIGNvbnZlcnRlZCB0byBiaW5hcnkgcmVwcmVzZW50YXRpb25cblx0ICogQHJldHVybiBJbnRlZ2VyIGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYXJhbWV0ZXJcblx0ICovXG5cdGhleDJiaW5iID0gZnVuY3Rpb24gKHN0cilcblx0e1xuXHRcdHZhciBiaW4gPSBbXSwgbGVuZ3RoID0gc3RyLmxlbmd0aCwgaSwgbnVtO1xuXG5cdFx0Zm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAyKVxuXHRcdHtcblx0XHRcdG51bSA9IHBhcnNlSW50KHN0ci5zdWJzdHIoaSwgMiksIDE2KTtcblx0XHRcdGlmICghaXNOYU4obnVtKSlcblx0XHRcdHtcblx0XHRcdFx0YmluW2kgPj4gM10gfD0gbnVtIDw8ICgyNCAtICg0ICogKGkgJSA4KSkpO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0XHRyZXR1cm4gXCJJTlZBTElEIEhFWCBTVFJJTkdcIjtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gYmluO1xuXHR9LFxuXG5cdC8qXG5cdCAqIENvbnZlcnQgYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3JkcyB0byBhIGhleCBzdHJpbmcuXG5cdCAqXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGJpbmFycmF5IEFycmF5IG9mIGludGVnZXJzIHRvIGJlIGNvbnZlcnRlZCB0byBoZXhpZGVjaW1hbFxuXHQgKlx0IHJlcHJlc2VudGF0aW9uXG5cdCAqIEByZXR1cm4gSGV4aWRlY2ltYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhcmFtZXRlciBpbiBTdHJpbmcgZm9ybVxuXHQgKi9cblx0YmluYjJoZXggPSBmdW5jdGlvbiAoYmluYXJyYXkpXG5cdHtcblx0XHR2YXIgaGV4X3RhYiA9IChoZXhDYXNlKSA/IFwiMDEyMzQ1Njc4OUFCQ0RFRlwiIDogXCIwMTIzNDU2Nzg5YWJjZGVmXCIsXG5cdFx0XHRzdHIgPSBcIlwiLCBsZW5ndGggPSBiaW5hcnJheS5sZW5ndGggKiA0LCBpLCBzcmNCeXRlO1xuXG5cdFx0Zm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKVxuXHRcdHtcblx0XHRcdHNyY0J5dGUgPSBiaW5hcnJheVtpID4+IDJdID4+ICgoMyAtIChpICUgNCkpICogOCk7XG5cdFx0XHRzdHIgKz0gaGV4X3RhYi5jaGFyQXQoKHNyY0J5dGUgPj4gNCkgJiAweEYpICtcblx0XHRcdFx0aGV4X3RhYi5jaGFyQXQoc3JjQnl0ZSAmIDB4Rik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHN0cjtcblx0fSxcblxuXHQvKlxuXHQgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMgdG8gYSBiYXNlLTY0IHN0cmluZ1xuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge0FycmF5fSBiaW5hcnJheSBBcnJheSBvZiBpbnRlZ2VycyB0byBiZSBjb252ZXJ0ZWQgdG8gYmFzZS02NFxuXHQgKlx0IHJlcHJlc2VudGF0aW9uXG5cdCAqIEByZXR1cm4gQmFzZS02NCBlbmNvZGVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYXJhbWV0ZXIgaW4gU3RyaW5nIGZvcm1cblx0ICovXG5cdGJpbmIyYjY0ID0gZnVuY3Rpb24gKGJpbmFycmF5KVxuXHR7XG5cdFx0dmFyIHRhYiA9IFwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elwiICtcblx0XHRcdFwiMDEyMzQ1Njc4OSsvXCIsIHN0ciA9IFwiXCIsIGxlbmd0aCA9IGJpbmFycmF5Lmxlbmd0aCAqIDQsIGksIGosXG5cdFx0XHR0cmlwbGV0O1xuXG5cdFx0Zm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAzKVxuXHRcdHtcblx0XHRcdHRyaXBsZXQgPSAoKChiaW5hcnJheVtpID4+IDJdID4+IDggKiAoMyAtIGkgJSA0KSkgJiAweEZGKSA8PCAxNikgfFxuXHRcdFx0XHQoKChiaW5hcnJheVtpICsgMSA+PiAyXSA+PiA4ICogKDMgLSAoaSArIDEpICUgNCkpICYgMHhGRikgPDwgOCkgfFxuXHRcdFx0XHQoKGJpbmFycmF5W2kgKyAyID4+IDJdID4+IDggKiAoMyAtIChpICsgMikgJSA0KSkgJiAweEZGKTtcblx0XHRcdGZvciAoaiA9IDA7IGogPCA0OyBqICs9IDEpXG5cdFx0XHR7XG5cdFx0XHRcdGlmIChpICogOCArIGogKiA2IDw9IGJpbmFycmF5Lmxlbmd0aCAqIDMyKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0c3RyICs9IHRhYi5jaGFyQXQoKHRyaXBsZXQgPj4gNiAqICgzIC0gaikpICYgMHgzRik7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0c3RyICs9IGI2NHBhZDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gc3RyO1xuXHR9LFxuXG5cdC8qXG5cdCAqIENvbnZlcnQgYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3JkcyB0byBhIHN0cmluZ1xuXHQgKi9cblx0YmluYjJzdHIgPSBmdW5jdGlvbiAoYmluKVxuXHR7XG5cdCAgdmFyIHN0ciA9IFwiXCI7XG5cdCAgdmFyIG1hc2sgPSAoMSA8PCA4KSAtIDE7XG5cdCAgZm9yKHZhciBpID0gMDsgaSA8IGJpbi5sZW5ndGggKiAzMjsgaSArPSA4KVxuXHQgICAgc3RyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGJpbltpPj41XSA+Pj4gKDI0IC0gaSUzMikpICYgbWFzayk7XG5cdCAgcmV0dXJuIHN0cjtcblx0fSxcblx0Lypcblx0ICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBjaXJjdWxhciByb3RhdGUgbGVmdFxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcblx0ICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG5cdCAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBjaXJjdWxhcmx5IGJ5IG4gYml0c1xuXHQgKi9cblx0cm90bF8zMiA9IGZ1bmN0aW9uICh4LCBuKVxuXHR7XG5cdFx0cmV0dXJuICh4IDw8IG4pIHwgKHggPj4+ICgzMiAtIG4pKTtcblx0fSxcblxuXHQvKlxuXHQgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIGNpcmN1bGFyIHJvdGF0ZSByaWdodFxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcblx0ICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG5cdCAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBjaXJjdWxhcmx5IGJ5IG4gYml0c1xuXHQgKi9cblx0cm90cl8zMiA9IGZ1bmN0aW9uICh4LCBuKVxuXHR7XG5cdFx0cmV0dXJuICh4ID4+PiBuKSB8ICh4IDw8ICgzMiAtIG4pKTtcblx0fSxcblxuXHQvKlxuXHQgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIGNpcmN1bGFyIHJvdGF0ZSByaWdodFxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcblx0ICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG5cdCAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBjaXJjdWxhcmx5IGJ5IG4gYml0c1xuXHQgKi9cblx0cm90cl82NCA9IGZ1bmN0aW9uICh4LCBuKVxuXHR7XG5cdFx0aWYgKG4gPD0gMzIpXG5cdFx0e1xuXHRcdFx0cmV0dXJuIG5ldyBJbnRfNjQoXG5cdFx0XHRcdFx0KHguaGlnaE9yZGVyID4+PiBuKSB8ICh4Lmxvd09yZGVyIDw8ICgzMiAtIG4pKSxcblx0XHRcdFx0XHQoeC5sb3dPcmRlciA+Pj4gbikgfCAoeC5oaWdoT3JkZXIgPDwgKDMyIC0gbikpXG5cdFx0XHRcdCk7XG5cdFx0fVxuXHRcdGVsc2Vcblx0XHR7XG5cdFx0XHRyZXR1cm4gbmV3IEludF82NChcblx0XHRcdFx0XHQoeC5sb3dPcmRlciA+Pj4gbikgfCAoeC5oaWdoT3JkZXIgPDwgKDMyIC0gbikpLFxuXHRcdFx0XHRcdCh4LmhpZ2hPcmRlciA+Pj4gbikgfCAoeC5sb3dPcmRlciA8PCAoMzIgLSBuKSlcblx0XHRcdFx0KTtcblx0XHR9XG5cdH0sXG5cblx0Lypcblx0ICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBzaGlmdCByaWdodFxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcblx0ICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG5cdCAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBieSBuIGJpdHNcblx0ICovXG5cdHNocl8zMiA9IGZ1bmN0aW9uICh4LCBuKVxuXHR7XG5cdFx0cmV0dXJuIHggPj4+IG47XG5cdH0sXG5cblx0Lypcblx0ICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBzaGlmdCByaWdodFxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcblx0ICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG5cdCAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBieSBuIGJpdHNcblx0ICovXG5cdHNocl82NCA9IGZ1bmN0aW9uICh4LCBuKVxuXHR7XG5cdFx0aWYgKG4gPD0gMzIpXG5cdFx0e1xuXHRcdFx0cmV0dXJuIG5ldyBJbnRfNjQoXG5cdFx0XHRcdFx0eC5oaWdoT3JkZXIgPj4+IG4sXG5cdFx0XHRcdFx0eC5sb3dPcmRlciA+Pj4gbiB8ICh4LmhpZ2hPcmRlciA8PCAoMzIgLSBuKSlcblx0XHRcdFx0KTtcblx0XHR9XG5cdFx0ZWxzZVxuXHRcdHtcblx0XHRcdHJldHVybiBuZXcgSW50XzY0KFxuXHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0eC5oaWdoT3JkZXIgPDwgKDMyIC0gbilcblx0XHRcdFx0KTtcblx0XHR9XG5cdH0sXG5cblx0Lypcblx0ICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgUGFyaXR5IGZ1bmN0aW9uXG5cdCAqXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuXHQgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB6IFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuXHQgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG5cdCAqL1xuXHRwYXJpdHlfMzIgPSBmdW5jdGlvbiAoeCwgeSwgeilcblx0e1xuXHRcdHJldHVybiB4IF4geSBeIHo7XG5cdH0sXG5cblx0Lypcblx0ICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgQ2ggZnVuY3Rpb25cblx0ICpcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHogVGhlIHRoaXJkIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cblx0ICovXG5cdGNoXzMyID0gZnVuY3Rpb24gKHgsIHksIHopXG5cdHtcblx0XHRyZXR1cm4gKHggJiB5KSBeICh+eCAmIHopO1xuXHR9LFxuXG5cdC8qXG5cdCAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIENoIGZ1bmN0aW9uXG5cdCAqXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSBmaXJzdCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuXHQgKiBAcGFyYW0ge0ludF82NH0geSBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEBwYXJhbSB7SW50XzY0fSB6IFRoZSB0aGlyZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuXHQgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG5cdCAqL1xuXHRjaF82NCA9IGZ1bmN0aW9uICh4LCB5LCB6KVxuXHR7XG5cdFx0cmV0dXJuIG5ldyBJbnRfNjQoXG5cdFx0XHRcdCh4LmhpZ2hPcmRlciAmIHkuaGlnaE9yZGVyKSBeICh+eC5oaWdoT3JkZXIgJiB6LmhpZ2hPcmRlciksXG5cdFx0XHRcdCh4Lmxvd09yZGVyICYgeS5sb3dPcmRlcikgXiAofngubG93T3JkZXIgJiB6Lmxvd09yZGVyKVxuXHRcdFx0KTtcblx0fSxcblxuXHQvKlxuXHQgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBNYWogZnVuY3Rpb25cblx0ICpcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHogVGhlIHRoaXJkIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cblx0ICovXG5cdG1hal8zMiA9IGZ1bmN0aW9uICh4LCB5LCB6KVxuXHR7XG5cdFx0cmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcblx0fSxcblxuXHQvKlxuXHQgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBNYWogZnVuY3Rpb25cblx0ICpcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIGZpcnN0IDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEBwYXJhbSB7SW50XzY0fSB5IFRoZSBzZWNvbmQgNjQtYml0IGludGVnZXIgYXJndW1lbnRcblx0ICogQHBhcmFtIHtJbnRfNjR9IHogVGhlIHRoaXJkIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cblx0ICovXG5cdG1hal82NCA9IGZ1bmN0aW9uICh4LCB5LCB6KVxuXHR7XG5cdFx0cmV0dXJuIG5ldyBJbnRfNjQoXG5cdFx0XHRcdCh4LmhpZ2hPcmRlciAmIHkuaGlnaE9yZGVyKSBeXG5cdFx0XHRcdCh4LmhpZ2hPcmRlciAmIHouaGlnaE9yZGVyKSBeXG5cdFx0XHRcdCh5LmhpZ2hPcmRlciAmIHouaGlnaE9yZGVyKSxcblx0XHRcdFx0KHgubG93T3JkZXIgJiB5Lmxvd09yZGVyKSBeXG5cdFx0XHRcdCh4Lmxvd09yZGVyICYgei5sb3dPcmRlcikgXlxuXHRcdFx0XHQoeS5sb3dPcmRlciAmIHoubG93T3JkZXIpXG5cdFx0XHQpO1xuXHR9LFxuXG5cdC8qXG5cdCAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIFNpZ21hMCBmdW5jdGlvblxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcblx0ICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuXHQgKi9cblx0c2lnbWEwXzMyID0gZnVuY3Rpb24gKHgpXG5cdHtcblx0XHRyZXR1cm4gcm90cl8zMih4LCAyKSBeIHJvdHJfMzIoeCwgMTMpIF4gcm90cl8zMih4LCAyMik7XG5cdH0sXG5cblx0Lypcblx0ICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgU2lnbWEwIGZ1bmN0aW9uXG5cdCAqXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuXHQgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG5cdCAqL1xuXHRzaWdtYTBfNjQgPSBmdW5jdGlvbiAoeClcblx0e1xuXHRcdHZhciByb3RyMjggPSByb3RyXzY0KHgsIDI4KSwgcm90cjM0ID0gcm90cl82NCh4LCAzNCksXG5cdFx0XHRyb3RyMzkgPSByb3RyXzY0KHgsIDM5KTtcblxuXHRcdHJldHVybiBuZXcgSW50XzY0KFxuXHRcdFx0XHRyb3RyMjguaGlnaE9yZGVyIF4gcm90cjM0LmhpZ2hPcmRlciBeIHJvdHIzOS5oaWdoT3JkZXIsXG5cdFx0XHRcdHJvdHIyOC5sb3dPcmRlciBeIHJvdHIzNC5sb3dPcmRlciBeIHJvdHIzOS5sb3dPcmRlcik7XG5cdH0sXG5cblx0Lypcblx0ICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgU2lnbWExIGZ1bmN0aW9uXG5cdCAqXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuXHQgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG5cdCAqL1xuXHRzaWdtYTFfMzIgPSBmdW5jdGlvbiAoeClcblx0e1xuXHRcdHJldHVybiByb3RyXzMyKHgsIDYpIF4gcm90cl8zMih4LCAxMSkgXiByb3RyXzMyKHgsIDI1KTtcblx0fSxcblxuXHQvKlxuXHQgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBTaWdtYTEgZnVuY3Rpb25cblx0ICpcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cblx0ICovXG5cdHNpZ21hMV82NCA9IGZ1bmN0aW9uICh4KVxuXHR7XG5cdFx0dmFyIHJvdHIxNCA9IHJvdHJfNjQoeCwgMTQpLCByb3RyMTggPSByb3RyXzY0KHgsIDE4KSxcblx0XHRcdHJvdHI0MSA9IHJvdHJfNjQoeCwgNDEpO1xuXG5cdFx0cmV0dXJuIG5ldyBJbnRfNjQoXG5cdFx0XHRcdHJvdHIxNC5oaWdoT3JkZXIgXiByb3RyMTguaGlnaE9yZGVyIF4gcm90cjQxLmhpZ2hPcmRlcixcblx0XHRcdFx0cm90cjE0Lmxvd09yZGVyIF4gcm90cjE4Lmxvd09yZGVyIF4gcm90cjQxLmxvd09yZGVyKTtcblx0fSxcblxuXHQvKlxuXHQgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTAgZnVuY3Rpb25cblx0ICpcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cblx0ICovXG5cdGdhbW1hMF8zMiA9IGZ1bmN0aW9uICh4KVxuXHR7XG5cdFx0cmV0dXJuIHJvdHJfMzIoeCwgNykgXiByb3RyXzMyKHgsIDE4KSBeIHNocl8zMih4LCAzKTtcblx0fSxcblxuXHQvKlxuXHQgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTAgZnVuY3Rpb25cblx0ICpcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cblx0ICovXG5cdGdhbW1hMF82NCA9IGZ1bmN0aW9uICh4KVxuXHR7XG5cdFx0dmFyIHJvdHIxID0gcm90cl82NCh4LCAxKSwgcm90cjggPSByb3RyXzY0KHgsIDgpLCBzaHI3ID0gc2hyXzY0KHgsIDcpO1xuXG5cdFx0cmV0dXJuIG5ldyBJbnRfNjQoXG5cdFx0XHRcdHJvdHIxLmhpZ2hPcmRlciBeIHJvdHI4LmhpZ2hPcmRlciBeIHNocjcuaGlnaE9yZGVyLFxuXHRcdFx0XHRyb3RyMS5sb3dPcmRlciBeIHJvdHI4Lmxvd09yZGVyIF4gc2hyNy5sb3dPcmRlclxuXHRcdFx0KTtcblx0fSxcblxuXHQvKlxuXHQgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTEgZnVuY3Rpb25cblx0ICpcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG5cdCAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cblx0ICovXG5cdGdhbW1hMV8zMiA9IGZ1bmN0aW9uICh4KVxuXHR7XG5cdFx0cmV0dXJuIHJvdHJfMzIoeCwgMTcpIF4gcm90cl8zMih4LCAxOSkgXiBzaHJfMzIoeCwgMTApO1xuXHR9LFxuXG5cdC8qXG5cdCAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIEdhbW1hMSBmdW5jdGlvblxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcblx0ICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuXHQgKi9cblx0Z2FtbWExXzY0ID0gZnVuY3Rpb24gKHgpXG5cdHtcblx0XHR2YXIgcm90cjE5ID0gcm90cl82NCh4LCAxOSksIHJvdHI2MSA9IHJvdHJfNjQoeCwgNjEpLFxuXHRcdFx0c2hyNiA9IHNocl82NCh4LCA2KTtcblxuXHRcdHJldHVybiBuZXcgSW50XzY0KFxuXHRcdFx0XHRyb3RyMTkuaGlnaE9yZGVyIF4gcm90cjYxLmhpZ2hPcmRlciBeIHNocjYuaGlnaE9yZGVyLFxuXHRcdFx0XHRyb3RyMTkubG93T3JkZXIgXiByb3RyNjEubG93T3JkZXIgXiBzaHI2Lmxvd09yZGVyXG5cdFx0XHQpO1xuXHR9LFxuXG5cdC8qXG5cdCAqIEFkZCB0d28gMzItYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjMyLiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcblx0ICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgZmlyc3QgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuXHQgKiBAcmV0dXJuIFRoZSBzdW0gb2YgeCArIHlcblx0ICovXG5cdHNhZmVBZGRfMzJfMiA9IGZ1bmN0aW9uICh4LCB5KVxuXHR7XG5cdFx0dmFyIGxzdyA9ICh4ICYgMHhGRkZGKSArICh5ICYgMHhGRkZGKSxcblx0XHRcdG1zdyA9ICh4ID4+PiAxNikgKyAoeSA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuXG5cdFx0cmV0dXJuICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblx0fSxcblxuXHQvKlxuXHQgKiBBZGQgZm91ciAzMi1iaXQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9uc1xuXHQgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG5cdCAqXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBhIFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuXHQgKiBAcGFyYW0ge051bWJlcn0gYiBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBjIFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuXHQgKiBAcGFyYW0ge051bWJlcn0gZCBUaGUgZm91cnRoIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG5cdCAqIEByZXR1cm4gVGhlIHN1bSBvZiBhICsgYiArIGMgKyBkXG5cdCAqL1xuXHRzYWZlQWRkXzMyXzQgPSBmdW5jdGlvbiAoYSwgYiwgYywgZClcblx0e1xuXHRcdHZhciBsc3cgPSAoYSAmIDB4RkZGRikgKyAoYiAmIDB4RkZGRikgKyAoYyAmIDB4RkZGRikgKyAoZCAmIDB4RkZGRiksXG5cdFx0XHRtc3cgPSAoYSA+Pj4gMTYpICsgKGIgPj4+IDE2KSArIChjID4+PiAxNikgKyAoZCA+Pj4gMTYpICtcblx0XHRcdFx0KGxzdyA+Pj4gMTYpO1xuXG5cdFx0cmV0dXJuICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblx0fSxcblxuXHQvKlxuXHQgKiBBZGQgZml2ZSAzMi1iaXQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9uc1xuXHQgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG5cdCAqXG5cdCAqIEBwcml2YXRlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBhIFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuXHQgKiBAcGFyYW0ge051bWJlcn0gYiBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBjIFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuXHQgKiBAcGFyYW0ge051bWJlcn0gZCBUaGUgZm91cnRoIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBlIFRoZSBmaWZ0aCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuXHQgKiBAcmV0dXJuIFRoZSBzdW0gb2YgYSArIGIgKyBjICsgZCArIGVcblx0ICovXG5cdHNhZmVBZGRfMzJfNSA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkLCBlKVxuXHR7XG5cdFx0dmFyIGxzdyA9IChhICYgMHhGRkZGKSArIChiICYgMHhGRkZGKSArIChjICYgMHhGRkZGKSArIChkICYgMHhGRkZGKSArXG5cdFx0XHRcdChlICYgMHhGRkZGKSxcblx0XHRcdG1zdyA9IChhID4+PiAxNikgKyAoYiA+Pj4gMTYpICsgKGMgPj4+IDE2KSArIChkID4+PiAxNikgK1xuXHRcdFx0XHQoZSA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuXG5cdFx0cmV0dXJuICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblx0fSxcblxuXHQvKlxuXHQgKiBBZGQgdHdvIDY0LWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl42NC4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG5cdCAqIGludGVybmFsbHkgdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cblx0ICpcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIGZpcnN0IDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG5cdCAqIEBwYXJhbSB7SW50XzY0fSB5IFRoZSBzZWNvbmQgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcblx0ICogQHJldHVybiBUaGUgc3VtIG9mIHggKyB5XG5cdCAqL1xuXHRzYWZlQWRkXzY0XzIgPSBmdW5jdGlvbiAoeCwgeSlcblx0e1xuXHRcdHZhciBsc3csIG1zdywgbG93T3JkZXIsIGhpZ2hPcmRlcjtcblxuXHRcdGxzdyA9ICh4Lmxvd09yZGVyICYgMHhGRkZGKSArICh5Lmxvd09yZGVyICYgMHhGRkZGKTtcblx0XHRtc3cgPSAoeC5sb3dPcmRlciA+Pj4gMTYpICsgKHkubG93T3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcblx0XHRsb3dPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuXHRcdGxzdyA9ICh4LmhpZ2hPcmRlciAmIDB4RkZGRikgKyAoeS5oaWdoT3JkZXIgJiAweEZGRkYpICsgKG1zdyA+Pj4gMTYpO1xuXHRcdG1zdyA9ICh4LmhpZ2hPcmRlciA+Pj4gMTYpICsgKHkuaGlnaE9yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG5cdFx0aGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG5cdFx0cmV0dXJuIG5ldyBJbnRfNjQoaGlnaE9yZGVyLCBsb3dPcmRlcik7XG5cdH0sXG5cblx0Lypcblx0ICogQWRkIGZvdXIgNjQtYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjY0LiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcblx0ICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge0ludF82NH0gYSBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcblx0ICogQHBhcmFtIHtJbnRfNjR9IGIgVGhlIHNlY29uZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuXHQgKiBAcGFyYW0ge0ludF82NH0gYyBUaGUgdGhpcmQgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcblx0ICogQHBhcmFtIHtJbnRfNjR9IGQgVGhlIGZvdXRoIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG5cdCAqIEByZXR1cm4gVGhlIHN1bSBvZiBhICsgYiArIGMgKyBkXG5cdCAqL1xuXHRzYWZlQWRkXzY0XzQgPSBmdW5jdGlvbiAoYSwgYiwgYywgZClcblx0e1xuXHRcdHZhciBsc3csIG1zdywgbG93T3JkZXIsIGhpZ2hPcmRlcjtcblxuXHRcdGxzdyA9IChhLmxvd09yZGVyICYgMHhGRkZGKSArIChiLmxvd09yZGVyICYgMHhGRkZGKSArXG5cdFx0XHQoYy5sb3dPcmRlciAmIDB4RkZGRikgKyAoZC5sb3dPcmRlciAmIDB4RkZGRik7XG5cdFx0bXN3ID0gKGEubG93T3JkZXIgPj4+IDE2KSArIChiLmxvd09yZGVyID4+PiAxNikgK1xuXHRcdFx0KGMubG93T3JkZXIgPj4+IDE2KSArIChkLmxvd09yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG5cdFx0bG93T3JkZXIgPSAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG5cblx0XHRsc3cgPSAoYS5oaWdoT3JkZXIgJiAweEZGRkYpICsgKGIuaGlnaE9yZGVyICYgMHhGRkZGKSArXG5cdFx0XHQoYy5oaWdoT3JkZXIgJiAweEZGRkYpICsgKGQuaGlnaE9yZGVyICYgMHhGRkZGKSArIChtc3cgPj4+IDE2KTtcblx0XHRtc3cgPSAoYS5oaWdoT3JkZXIgPj4+IDE2KSArIChiLmhpZ2hPcmRlciA+Pj4gMTYpICtcblx0XHRcdChjLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGQuaGlnaE9yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG5cdFx0aGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG5cdFx0cmV0dXJuIG5ldyBJbnRfNjQoaGlnaE9yZGVyLCBsb3dPcmRlcik7XG5cdH0sXG5cblx0Lypcblx0ICogQWRkIGZpdmUgNjQtYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjY0LiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcblx0ICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge0ludF82NH0gYSBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcblx0ICogQHBhcmFtIHtJbnRfNjR9IGIgVGhlIHNlY29uZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuXHQgKiBAcGFyYW0ge0ludF82NH0gYyBUaGUgdGhpcmQgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcblx0ICogQHBhcmFtIHtJbnRfNjR9IGQgVGhlIGZvdXRoIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG5cdCAqIEBwYXJhbSB7SW50XzY0fSBlIFRoZSBmb3V0aCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuXHQgKiBAcmV0dXJuIFRoZSBzdW0gb2YgYSArIGIgKyBjICsgZCArIGVcblx0ICovXG5cdHNhZmVBZGRfNjRfNSA9IGZ1bmN0aW9uIChhLCBiLCBjLCBkLCBlKVxuXHR7XG5cdFx0dmFyIGxzdywgbXN3LCBsb3dPcmRlciwgaGlnaE9yZGVyO1xuXG5cdFx0bHN3ID0gKGEubG93T3JkZXIgJiAweEZGRkYpICsgKGIubG93T3JkZXIgJiAweEZGRkYpICtcblx0XHRcdChjLmxvd09yZGVyICYgMHhGRkZGKSArIChkLmxvd09yZGVyICYgMHhGRkZGKSArXG5cdFx0XHQoZS5sb3dPcmRlciAmIDB4RkZGRik7XG5cdFx0bXN3ID0gKGEubG93T3JkZXIgPj4+IDE2KSArIChiLmxvd09yZGVyID4+PiAxNikgK1xuXHRcdFx0KGMubG93T3JkZXIgPj4+IDE2KSArIChkLmxvd09yZGVyID4+PiAxNikgKyAoZS5sb3dPcmRlciA+Pj4gMTYpICtcblx0XHRcdChsc3cgPj4+IDE2KTtcblx0XHRsb3dPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuXHRcdGxzdyA9IChhLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAoYi5oaWdoT3JkZXIgJiAweEZGRkYpICtcblx0XHRcdChjLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAoZC5oaWdoT3JkZXIgJiAweEZGRkYpICtcblx0XHRcdChlLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAobXN3ID4+PiAxNik7XG5cdFx0bXN3ID0gKGEuaGlnaE9yZGVyID4+PiAxNikgKyAoYi5oaWdoT3JkZXIgPj4+IDE2KSArXG5cdFx0XHQoYy5oaWdoT3JkZXIgPj4+IDE2KSArIChkLmhpZ2hPcmRlciA+Pj4gMTYpICtcblx0XHRcdChlLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuXHRcdGhpZ2hPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuXHRcdHJldHVybiBuZXcgSW50XzY0KGhpZ2hPcmRlciwgbG93T3JkZXIpO1xuXHR9LFxuXG5cdC8qXG5cdCAqIENhbGN1bGF0ZXMgdGhlIFNIQS0xIGhhc2ggb2YgdGhlIHN0cmluZyBzZXQgYXQgaW5zdGFudGlhdGlvblxuXHQgKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKiBAcGFyYW0ge0FycmF5fSBtZXNzYWdlIFRoZSBiaW5hcnkgYXJyYXkgcmVwcmVzZW50YXRpb24gb2YgdGhlIHN0cmluZyB0b1xuXHQgKlx0IGhhc2hcblx0ICogQHBhcmFtIHtOdW1iZXJ9IG1lc3NhZ2VMZW4gVGhlIG51bWJlciBvZiBiaXRzIGluIHRoZSBtZXNzYWdlXG5cdCAqIEByZXR1cm4gVGhlIGFycmF5IG9mIGludGVnZXJzIHJlcHJlc2VudGluZyB0aGUgU0hBLTEgaGFzaCBvZiBtZXNzYWdlXG5cdCAqL1xuXHRjb3JlU0hBMSA9IGZ1bmN0aW9uIChtZXNzYWdlLCBtZXNzYWdlTGVuKVxuXHR7XG5cdFx0dmFyIFcgPSBbXSwgYSwgYiwgYywgZCwgZSwgVCwgY2ggPSBjaF8zMiwgcGFyaXR5ID0gcGFyaXR5XzMyLFxuXHRcdFx0bWFqID0gbWFqXzMyLCByb3RsID0gcm90bF8zMiwgc2FmZUFkZF8yID0gc2FmZUFkZF8zMl8yLCBpLCB0LFxuXHRcdFx0c2FmZUFkZF81ID0gc2FmZUFkZF8zMl81LCBhcHBlbmRlZE1lc3NhZ2VMZW5ndGgsXG5cdFx0XHRIID0gW1xuXHRcdFx0XHQweDY3NDUyMzAxLCAweGVmY2RhYjg5LCAweDk4YmFkY2ZlLCAweDEwMzI1NDc2LCAweGMzZDJlMWYwXG5cdFx0XHRdLFxuXHRcdFx0SyA9IFtcblx0XHRcdFx0MHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcblx0XHRcdFx0MHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcblx0XHRcdFx0MHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcblx0XHRcdFx0MHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcblx0XHRcdFx0MHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcblx0XHRcdFx0MHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcblx0XHRcdFx0MHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcblx0XHRcdFx0MHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcblx0XHRcdFx0MHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcblx0XHRcdFx0MHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcblx0XHRcdFx0MHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcblx0XHRcdFx0MHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcblx0XHRcdFx0MHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcblx0XHRcdFx0MHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcblx0XHRcdFx0MHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcblx0XHRcdFx0MHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcblx0XHRcdFx0MHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcblx0XHRcdFx0MHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcblx0XHRcdFx0MHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcblx0XHRcdFx0MHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNlxuXHRcdFx0XTtcblxuXHRcdC8qIEFwcGVuZCAnMScgYXQgdGhlIGVuZCBvZiB0aGUgYmluYXJ5IHN0cmluZyAqL1xuXHRcdG1lc3NhZ2VbbWVzc2FnZUxlbiA+PiA1XSB8PSAweDgwIDw8ICgyNCAtIChtZXNzYWdlTGVuICUgMzIpKTtcblx0XHQvKiBBcHBlbmQgbGVuZ3RoIG9mIGJpbmFyeSBzdHJpbmcgaW4gdGhlIHBvc2l0aW9uIHN1Y2ggdGhhdCB0aGUgbmV3XG5cdFx0bGVuZ3RoIGlzIGEgbXVsdGlwbGUgb2YgNTEyLiAgTG9naWMgZG9lcyBub3Qgd29yayBmb3IgZXZlbiBtdWx0aXBsZXNcblx0XHRvZiA1MTIgYnV0IHRoZXJlIGNhbiBuZXZlciBiZSBldmVuIG11bHRpcGxlcyBvZiA1MTIgKi9cblx0XHRtZXNzYWdlWygoKG1lc3NhZ2VMZW4gKyA2NSkgPj4gOSkgPDwgNCkgKyAxNV0gPSBtZXNzYWdlTGVuO1xuXG5cdFx0YXBwZW5kZWRNZXNzYWdlTGVuZ3RoID0gbWVzc2FnZS5sZW5ndGg7XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoOyBpICs9IDE2KVxuXHRcdHtcblx0XHRcdGEgPSBIWzBdO1xuXHRcdFx0YiA9IEhbMV07XG5cdFx0XHRjID0gSFsyXTtcblx0XHRcdGQgPSBIWzNdO1xuXHRcdFx0ZSA9IEhbNF07XG5cblx0XHRcdGZvciAodCA9IDA7IHQgPCA4MDsgdCArPSAxKVxuXHRcdFx0e1xuXHRcdFx0XHRpZiAodCA8IDE2KVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0V1t0XSA9IG1lc3NhZ2VbdCArIGldO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0e1xuXHRcdFx0XHRcdFdbdF0gPSByb3RsKFdbdCAtIDNdIF4gV1t0IC0gOF0gXiBXW3QgLSAxNF0gXiBXW3QgLSAxNl0sIDEpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKHQgPCAyMClcblx0XHRcdFx0e1xuXHRcdFx0XHRcdFQgPSBzYWZlQWRkXzUocm90bChhLCA1KSwgY2goYiwgYywgZCksIGUsIEtbdF0sIFdbdF0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2UgaWYgKHQgPCA0MClcblx0XHRcdFx0e1xuXHRcdFx0XHRcdFQgPSBzYWZlQWRkXzUocm90bChhLCA1KSwgcGFyaXR5KGIsIGMsIGQpLCBlLCBLW3RdLCBXW3RdKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlIGlmICh0IDwgNjApXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRUID0gc2FmZUFkZF81KHJvdGwoYSwgNSksIG1haihiLCBjLCBkKSwgZSwgS1t0XSwgV1t0XSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0VCA9IHNhZmVBZGRfNShyb3RsKGEsIDUpLCBwYXJpdHkoYiwgYywgZCksIGUsIEtbdF0sIFdbdF0pO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZSA9IGQ7XG5cdFx0XHRcdGQgPSBjO1xuXHRcdFx0XHRjID0gcm90bChiLCAzMCk7XG5cdFx0XHRcdGIgPSBhO1xuXHRcdFx0XHRhID0gVDtcblx0XHRcdH1cblxuXHRcdFx0SFswXSA9IHNhZmVBZGRfMihhLCBIWzBdKTtcblx0XHRcdEhbMV0gPSBzYWZlQWRkXzIoYiwgSFsxXSk7XG5cdFx0XHRIWzJdID0gc2FmZUFkZF8yKGMsIEhbMl0pO1xuXHRcdFx0SFszXSA9IHNhZmVBZGRfMihkLCBIWzNdKTtcblx0XHRcdEhbNF0gPSBzYWZlQWRkXzIoZSwgSFs0XSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIEg7XG5cdH0sXG5cblx0Lypcblx0ICogQ2FsY3VsYXRlcyB0aGUgZGVzaXJlZCBTSEEtMiBoYXNoIG9mIHRoZSBzdHJpbmcgc2V0IGF0IGluc3RhbnRpYXRpb25cblx0ICpcblx0ICogQHByaXZhdGVcblx0ICogQHBhcmFtIHtBcnJheX0gVGhlIGJpbmFyeSBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3RyaW5nIHRvIGhhc2hcblx0ICogQHBhcmFtIHtOdW1iZXJ9IFRoZSBudW1iZXIgb2YgYml0cyBpbiBtZXNzYWdlXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSB2YXJpYW50IFRoZSBkZXNpcmVkIFNIQS0yIHZhcmlhbnRcblx0ICogQHJldHVybiBUaGUgYXJyYXkgb2YgaW50ZWdlcnMgcmVwcmVzZW50aW5nIHRoZSBTSEEtMiBoYXNoIG9mIG1lc3NhZ2Vcblx0ICovXG5cdGNvcmVTSEEyID0gZnVuY3Rpb24gKG1lc3NhZ2UsIG1lc3NhZ2VMZW4sIHZhcmlhbnQpXG5cdHtcblx0XHR2YXIgYSwgYiwgYywgZCwgZSwgZiwgZywgaCwgVDEsIFQyLCBILCBudW1Sb3VuZHMsIGxlbmd0aFBvc2l0aW9uLCBpLCB0LFxuXHRcdFx0YmluYXJ5U3RyaW5nSW5jLCBiaW5hcnlTdHJpbmdNdWx0LCBzYWZlQWRkXzIsIHNhZmVBZGRfNCwgc2FmZUFkZF81LFxuXHRcdFx0Z2FtbWEwLCBnYW1tYTEsIHNpZ21hMCwgc2lnbWExLCBjaCwgbWFqLCBJbnQsIEssIFcgPSBbXSxcblx0XHRcdGFwcGVuZGVkTWVzc2FnZUxlbmd0aDtcblxuXHRcdC8qIFNldCB1cCB0aGUgdmFyaW91cyBmdW5jdGlvbiBoYW5kbGVzIGFuZCB2YXJpYWJsZSBmb3IgdGhlIHNwZWNpZmljIFxuXHRcdCAqIHZhcmlhbnQgKi9cblx0XHRpZiAodmFyaWFudCA9PT0gXCJTSEEtMjI0XCIgfHwgdmFyaWFudCA9PT0gXCJTSEEtMjU2XCIpXG5cdFx0e1xuXHRcdFx0LyogMzItYml0IHZhcmlhbnQgKi9cblx0XHRcdG51bVJvdW5kcyA9IDY0O1xuXHRcdFx0bGVuZ3RoUG9zaXRpb24gPSAoKChtZXNzYWdlTGVuICsgNjUpID4+IDkpIDw8IDQpICsgMTU7XG5cdFx0XHRiaW5hcnlTdHJpbmdJbmMgPSAxNjtcblx0XHRcdGJpbmFyeVN0cmluZ011bHQgPSAxO1xuXHRcdFx0SW50ID0gTnVtYmVyO1xuXHRcdFx0c2FmZUFkZF8yID0gc2FmZUFkZF8zMl8yO1xuXHRcdFx0c2FmZUFkZF80ID0gc2FmZUFkZF8zMl80O1xuXHRcdFx0c2FmZUFkZF81ID0gc2FmZUFkZF8zMl81O1xuXHRcdFx0Z2FtbWEwID0gZ2FtbWEwXzMyO1xuXHRcdFx0Z2FtbWExID0gZ2FtbWExXzMyO1xuXHRcdFx0c2lnbWEwID0gc2lnbWEwXzMyO1xuXHRcdFx0c2lnbWExID0gc2lnbWExXzMyO1xuXHRcdFx0bWFqID0gbWFqXzMyO1xuXHRcdFx0Y2ggPSBjaF8zMjtcblx0XHRcdEsgPSBbXG5cdFx0XHRcdFx0MHg0MjhBMkY5OCwgMHg3MTM3NDQ5MSwgMHhCNUMwRkJDRiwgMHhFOUI1REJBNSxcblx0XHRcdFx0XHQweDM5NTZDMjVCLCAweDU5RjExMUYxLCAweDkyM0Y4MkE0LCAweEFCMUM1RUQ1LFxuXHRcdFx0XHRcdDB4RDgwN0FBOTgsIDB4MTI4MzVCMDEsIDB4MjQzMTg1QkUsIDB4NTUwQzdEQzMsXG5cdFx0XHRcdFx0MHg3MkJFNUQ3NCwgMHg4MERFQjFGRSwgMHg5QkRDMDZBNywgMHhDMTlCRjE3NCxcblx0XHRcdFx0XHQweEU0OUI2OUMxLCAweEVGQkU0Nzg2LCAweDBGQzE5REM2LCAweDI0MENBMUNDLFxuXHRcdFx0XHRcdDB4MkRFOTJDNkYsIDB4NEE3NDg0QUEsIDB4NUNCMEE5REMsIDB4NzZGOTg4REEsXG5cdFx0XHRcdFx0MHg5ODNFNTE1MiwgMHhBODMxQzY2RCwgMHhCMDAzMjdDOCwgMHhCRjU5N0ZDNyxcblx0XHRcdFx0XHQweEM2RTAwQkYzLCAweEQ1QTc5MTQ3LCAweDA2Q0E2MzUxLCAweDE0MjkyOTY3LFxuXHRcdFx0XHRcdDB4MjdCNzBBODUsIDB4MkUxQjIxMzgsIDB4NEQyQzZERkMsIDB4NTMzODBEMTMsXG5cdFx0XHRcdFx0MHg2NTBBNzM1NCwgMHg3NjZBMEFCQiwgMHg4MUMyQzkyRSwgMHg5MjcyMkM4NSxcblx0XHRcdFx0XHQweEEyQkZFOEExLCAweEE4MUE2NjRCLCAweEMyNEI4QjcwLCAweEM3NkM1MUEzLFxuXHRcdFx0XHRcdDB4RDE5MkU4MTksIDB4RDY5OTA2MjQsIDB4RjQwRTM1ODUsIDB4MTA2QUEwNzAsXG5cdFx0XHRcdFx0MHgxOUE0QzExNiwgMHgxRTM3NkMwOCwgMHgyNzQ4Nzc0QywgMHgzNEIwQkNCNSxcblx0XHRcdFx0XHQweDM5MUMwQ0IzLCAweDRFRDhBQTRBLCAweDVCOUNDQTRGLCAweDY4MkU2RkYzLFxuXHRcdFx0XHRcdDB4NzQ4RjgyRUUsIDB4NzhBNTYzNkYsIDB4ODRDODc4MTQsIDB4OENDNzAyMDgsXG5cdFx0XHRcdFx0MHg5MEJFRkZGQSwgMHhBNDUwNkNFQiwgMHhCRUY5QTNGNywgMHhDNjcxNzhGMlxuXHRcdFx0XHRdO1xuXG5cdFx0XHRpZiAodmFyaWFudCA9PT0gXCJTSEEtMjI0XCIpXG5cdFx0XHR7XG5cdFx0XHRcdEggPSBbXG5cdFx0XHRcdFx0XHQweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuXHRcdFx0XHRcdFx0MHhmZmMwMGIzMSwgMHg2ODU4MTUxMSwgMHg2NGY5OGZhNywgMHhiZWZhNGZhNFxuXHRcdFx0XHRcdF07XG5cdFx0XHR9XG5cdFx0XHRlbHNlXG5cdFx0XHR7XG5cdFx0XHRcdEggPSBbXG5cdFx0XHRcdFx0XHQweDZBMDlFNjY3LCAweEJCNjdBRTg1LCAweDNDNkVGMzcyLCAweEE1NEZGNTNBLFxuXHRcdFx0XHRcdFx0MHg1MTBFNTI3RiwgMHg5QjA1Njg4QywgMHgxRjgzRDlBQiwgMHg1QkUwQ0QxOVxuXHRcdFx0XHRcdF07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGVsc2UgaWYgKHZhcmlhbnQgPT09IFwiU0hBLTM4NFwiIHx8IHZhcmlhbnQgPT09IFwiU0hBLTUxMlwiKVxuXHRcdHtcblx0XHRcdC8qIDY0LWJpdCB2YXJpYW50ICovXG5cdFx0XHRudW1Sb3VuZHMgPSA4MDtcblx0XHRcdGxlbmd0aFBvc2l0aW9uID0gKCgobWVzc2FnZUxlbiArIDEyOCkgPj4gMTApIDw8IDUpICsgMzE7XG5cdFx0XHRiaW5hcnlTdHJpbmdJbmMgPSAzMjtcblx0XHRcdGJpbmFyeVN0cmluZ011bHQgPSAyO1xuXHRcdFx0SW50ID0gSW50XzY0O1xuXHRcdFx0c2FmZUFkZF8yID0gc2FmZUFkZF82NF8yO1xuXHRcdFx0c2FmZUFkZF80ID0gc2FmZUFkZF82NF80O1xuXHRcdFx0c2FmZUFkZF81ID0gc2FmZUFkZF82NF81O1xuXHRcdFx0Z2FtbWEwID0gZ2FtbWEwXzY0O1xuXHRcdFx0Z2FtbWExID0gZ2FtbWExXzY0O1xuXHRcdFx0c2lnbWEwID0gc2lnbWEwXzY0O1xuXHRcdFx0c2lnbWExID0gc2lnbWExXzY0O1xuXHRcdFx0bWFqID0gbWFqXzY0O1xuXHRcdFx0Y2ggPSBjaF82NDtcblxuXHRcdFx0SyA9IFtcblx0XHRcdFx0bmV3IEludCgweDQyOGEyZjk4LCAweGQ3MjhhZTIyKSwgbmV3IEludCgweDcxMzc0NDkxLCAweDIzZWY2NWNkKSxcblx0XHRcdFx0bmV3IEludCgweGI1YzBmYmNmLCAweGVjNGQzYjJmKSwgbmV3IEludCgweGU5YjVkYmE1LCAweDgxODlkYmJjKSxcblx0XHRcdFx0bmV3IEludCgweDM5NTZjMjViLCAweGYzNDhiNTM4KSwgbmV3IEludCgweDU5ZjExMWYxLCAweGI2MDVkMDE5KSxcblx0XHRcdFx0bmV3IEludCgweDkyM2Y4MmE0LCAweGFmMTk0ZjliKSwgbmV3IEludCgweGFiMWM1ZWQ1LCAweGRhNmQ4MTE4KSxcblx0XHRcdFx0bmV3IEludCgweGQ4MDdhYTk4LCAweGEzMDMwMjQyKSwgbmV3IEludCgweDEyODM1YjAxLCAweDQ1NzA2ZmJlKSxcblx0XHRcdFx0bmV3IEludCgweDI0MzE4NWJlLCAweDRlZTRiMjhjKSwgbmV3IEludCgweDU1MGM3ZGMzLCAweGQ1ZmZiNGUyKSxcblx0XHRcdFx0bmV3IEludCgweDcyYmU1ZDc0LCAweGYyN2I4OTZmKSwgbmV3IEludCgweDgwZGViMWZlLCAweDNiMTY5NmIxKSxcblx0XHRcdFx0bmV3IEludCgweDliZGMwNmE3LCAweDI1YzcxMjM1KSwgbmV3IEludCgweGMxOWJmMTc0LCAweGNmNjkyNjk0KSxcblx0XHRcdFx0bmV3IEludCgweGU0OWI2OWMxLCAweDllZjE0YWQyKSwgbmV3IEludCgweGVmYmU0Nzg2LCAweDM4NGYyNWUzKSxcblx0XHRcdFx0bmV3IEludCgweDBmYzE5ZGM2LCAweDhiOGNkNWI1KSwgbmV3IEludCgweDI0MGNhMWNjLCAweDc3YWM5YzY1KSxcblx0XHRcdFx0bmV3IEludCgweDJkZTkyYzZmLCAweDU5MmIwMjc1KSwgbmV3IEludCgweDRhNzQ4NGFhLCAweDZlYTZlNDgzKSxcblx0XHRcdFx0bmV3IEludCgweDVjYjBhOWRjLCAweGJkNDFmYmQ0KSwgbmV3IEludCgweDc2Zjk4OGRhLCAweDgzMTE1M2I1KSxcblx0XHRcdFx0bmV3IEludCgweDk4M2U1MTUyLCAweGVlNjZkZmFiKSwgbmV3IEludCgweGE4MzFjNjZkLCAweDJkYjQzMjEwKSxcblx0XHRcdFx0bmV3IEludCgweGIwMDMyN2M4LCAweDk4ZmIyMTNmKSwgbmV3IEludCgweGJmNTk3ZmM3LCAweGJlZWYwZWU0KSxcblx0XHRcdFx0bmV3IEludCgweGM2ZTAwYmYzLCAweDNkYTg4ZmMyKSwgbmV3IEludCgweGQ1YTc5MTQ3LCAweDkzMGFhNzI1KSxcblx0XHRcdFx0bmV3IEludCgweDA2Y2E2MzUxLCAweGUwMDM4MjZmKSwgbmV3IEludCgweDE0MjkyOTY3LCAweDBhMGU2ZTcwKSxcblx0XHRcdFx0bmV3IEludCgweDI3YjcwYTg1LCAweDQ2ZDIyZmZjKSwgbmV3IEludCgweDJlMWIyMTM4LCAweDVjMjZjOTI2KSxcblx0XHRcdFx0bmV3IEludCgweDRkMmM2ZGZjLCAweDVhYzQyYWVkKSwgbmV3IEludCgweDUzMzgwZDEzLCAweDlkOTViM2RmKSxcblx0XHRcdFx0bmV3IEludCgweDY1MGE3MzU0LCAweDhiYWY2M2RlKSwgbmV3IEludCgweDc2NmEwYWJiLCAweDNjNzdiMmE4KSxcblx0XHRcdFx0bmV3IEludCgweDgxYzJjOTJlLCAweDQ3ZWRhZWU2KSwgbmV3IEludCgweDkyNzIyYzg1LCAweDE0ODIzNTNiKSxcblx0XHRcdFx0bmV3IEludCgweGEyYmZlOGExLCAweDRjZjEwMzY0KSwgbmV3IEludCgweGE4MWE2NjRiLCAweGJjNDIzMDAxKSxcblx0XHRcdFx0bmV3IEludCgweGMyNGI4YjcwLCAweGQwZjg5NzkxKSwgbmV3IEludCgweGM3NmM1MWEzLCAweDA2NTRiZTMwKSxcblx0XHRcdFx0bmV3IEludCgweGQxOTJlODE5LCAweGQ2ZWY1MjE4KSwgbmV3IEludCgweGQ2OTkwNjI0LCAweDU1NjVhOTEwKSxcblx0XHRcdFx0bmV3IEludCgweGY0MGUzNTg1LCAweDU3NzEyMDJhKSwgbmV3IEludCgweDEwNmFhMDcwLCAweDMyYmJkMWI4KSxcblx0XHRcdFx0bmV3IEludCgweDE5YTRjMTE2LCAweGI4ZDJkMGM4KSwgbmV3IEludCgweDFlMzc2YzA4LCAweDUxNDFhYjUzKSxcblx0XHRcdFx0bmV3IEludCgweDI3NDg3NzRjLCAweGRmOGVlYjk5KSwgbmV3IEludCgweDM0YjBiY2I1LCAweGUxOWI0OGE4KSxcblx0XHRcdFx0bmV3IEludCgweDM5MWMwY2IzLCAweGM1Yzk1YTYzKSwgbmV3IEludCgweDRlZDhhYTRhLCAweGUzNDE4YWNiKSxcblx0XHRcdFx0bmV3IEludCgweDViOWNjYTRmLCAweDc3NjNlMzczKSwgbmV3IEludCgweDY4MmU2ZmYzLCAweGQ2YjJiOGEzKSxcblx0XHRcdFx0bmV3IEludCgweDc0OGY4MmVlLCAweDVkZWZiMmZjKSwgbmV3IEludCgweDc4YTU2MzZmLCAweDQzMTcyZjYwKSxcblx0XHRcdFx0bmV3IEludCgweDg0Yzg3ODE0LCAweGExZjBhYjcyKSwgbmV3IEludCgweDhjYzcwMjA4LCAweDFhNjQzOWVjKSxcblx0XHRcdFx0bmV3IEludCgweDkwYmVmZmZhLCAweDIzNjMxZTI4KSwgbmV3IEludCgweGE0NTA2Y2ViLCAweGRlODJiZGU5KSxcblx0XHRcdFx0bmV3IEludCgweGJlZjlhM2Y3LCAweGIyYzY3OTE1KSwgbmV3IEludCgweGM2NzE3OGYyLCAweGUzNzI1MzJiKSxcblx0XHRcdFx0bmV3IEludCgweGNhMjczZWNlLCAweGVhMjY2MTljKSwgbmV3IEludCgweGQxODZiOGM3LCAweDIxYzBjMjA3KSxcblx0XHRcdFx0bmV3IEludCgweGVhZGE3ZGQ2LCAweGNkZTBlYjFlKSwgbmV3IEludCgweGY1N2Q0ZjdmLCAweGVlNmVkMTc4KSxcblx0XHRcdFx0bmV3IEludCgweDA2ZjA2N2FhLCAweDcyMTc2ZmJhKSwgbmV3IEludCgweDBhNjM3ZGM1LCAweGEyYzg5OGE2KSxcblx0XHRcdFx0bmV3IEludCgweDExM2Y5ODA0LCAweGJlZjkwZGFlKSwgbmV3IEludCgweDFiNzEwYjM1LCAweDEzMWM0NzFiKSxcblx0XHRcdFx0bmV3IEludCgweDI4ZGI3N2Y1LCAweDIzMDQ3ZDg0KSwgbmV3IEludCgweDMyY2FhYjdiLCAweDQwYzcyNDkzKSxcblx0XHRcdFx0bmV3IEludCgweDNjOWViZTBhLCAweDE1YzliZWJjKSwgbmV3IEludCgweDQzMWQ2N2M0LCAweDljMTAwZDRjKSxcblx0XHRcdFx0bmV3IEludCgweDRjYzVkNGJlLCAweGNiM2U0MmI2KSwgbmV3IEludCgweDU5N2YyOTljLCAweGZjNjU3ZTJhKSxcblx0XHRcdFx0bmV3IEludCgweDVmY2I2ZmFiLCAweDNhZDZmYWVjKSwgbmV3IEludCgweDZjNDQxOThjLCAweDRhNDc1ODE3KVxuXHRcdFx0XTtcblxuXHRcdFx0aWYgKHZhcmlhbnQgPT09IFwiU0hBLTM4NFwiKVxuXHRcdFx0e1xuXHRcdFx0XHRIID0gW1xuXHRcdFx0XHRcdG5ldyBJbnQoMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOCksIG5ldyBJbnQoMHgwNjI5YTI5MmEsIDB4MzY3Y2Q1MDcpLFxuXHRcdFx0XHRcdG5ldyBJbnQoMHg5MTU5MDE1YSwgMHgzMDcwZGQxNyksIG5ldyBJbnQoMHgwMTUyZmVjZDgsIDB4ZjcwZTU5MzkpLFxuXHRcdFx0XHRcdG5ldyBJbnQoMHg2NzMzMjY2NywgMHhmZmMwMGIzMSksIG5ldyBJbnQoMHg5OGViNDRhODcsIDB4Njg1ODE1MTEpLFxuXHRcdFx0XHRcdG5ldyBJbnQoMHhkYjBjMmUwZCwgMHg2NGY5OGZhNyksIG5ldyBJbnQoMHgwNDdiNTQ4MWQsIDB4YmVmYTRmYTQpXG5cdFx0XHRcdF07XG5cdFx0XHR9XG5cdFx0XHRlbHNlXG5cdFx0XHR7XG5cdFx0XHRcdEggPSBbXG5cdFx0XHRcdFx0bmV3IEludCgweDZhMDllNjY3LCAweGYzYmNjOTA4KSwgbmV3IEludCgweGJiNjdhZTg1LCAweDg0Y2FhNzNiKSxcblx0XHRcdFx0XHRuZXcgSW50KDB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmIpLCBuZXcgSW50KDB4YTU0ZmY1M2EsIDB4NWYxZDM2ZjEpLFxuXHRcdFx0XHRcdG5ldyBJbnQoMHg1MTBlNTI3ZiwgMHhhZGU2ODJkMSksIG5ldyBJbnQoMHg5YjA1Njg4YywgMHgyYjNlNmMxZiksXG5cdFx0XHRcdFx0bmV3IEludCgweDFmODNkOWFiLCAweGZiNDFiZDZiKSwgbmV3IEludCgweDViZTBjZDE5LCAweDEzN2UyMTc5KVxuXHRcdFx0XHRdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8qIEFwcGVuZCAnMScgYXQgdGhlIGVuZCBvZiB0aGUgYmluYXJ5IHN0cmluZyAqL1xuXHRcdG1lc3NhZ2VbbWVzc2FnZUxlbiA+PiA1XSB8PSAweDgwIDw8ICgyNCAtIG1lc3NhZ2VMZW4gJSAzMik7XG5cdFx0LyogQXBwZW5kIGxlbmd0aCBvZiBiaW5hcnkgc3RyaW5nIGluIHRoZSBwb3NpdGlvbiBzdWNoIHRoYXQgdGhlIG5ld1xuXHRcdCAqIGxlbmd0aCBpcyBjb3JyZWN0ICovXG5cdFx0bWVzc2FnZVtsZW5ndGhQb3NpdGlvbl0gPSBtZXNzYWdlTGVuO1xuXG5cdFx0YXBwZW5kZWRNZXNzYWdlTGVuZ3RoID0gbWVzc2FnZS5sZW5ndGg7XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoOyBpICs9IGJpbmFyeVN0cmluZ0luYylcblx0XHR7XG5cdFx0XHRhID0gSFswXTtcblx0XHRcdGIgPSBIWzFdO1xuXHRcdFx0YyA9IEhbMl07XG5cdFx0XHRkID0gSFszXTtcblx0XHRcdGUgPSBIWzRdO1xuXHRcdFx0ZiA9IEhbNV07XG5cdFx0XHRnID0gSFs2XTtcblx0XHRcdGggPSBIWzddO1xuXG5cdFx0XHRmb3IgKHQgPSAwOyB0IDwgbnVtUm91bmRzOyB0ICs9IDEpXG5cdFx0XHR7XG5cdFx0XHRcdGlmICh0IDwgMTYpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHQvKiBCaXQgb2YgYSBoYWNrIC0gZm9yIDMyLWJpdCwgdGhlIHNlY29uZCB0ZXJtIGlzIGlnbm9yZWQgKi9cblx0XHRcdFx0XHRXW3RdID0gbmV3IEludChtZXNzYWdlW3QgKiBiaW5hcnlTdHJpbmdNdWx0ICsgaV0sXG5cdFx0XHRcdFx0XHRcdG1lc3NhZ2VbdCAqIGJpbmFyeVN0cmluZ011bHQgKyBpICsgMV0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsc2Vcblx0XHRcdFx0e1xuXHRcdFx0XHRcdFdbdF0gPSBzYWZlQWRkXzQoXG5cdFx0XHRcdFx0XHRcdGdhbW1hMShXW3QgLSAyXSksIFdbdCAtIDddLFxuXHRcdFx0XHRcdFx0XHRnYW1tYTAoV1t0IC0gMTVdKSwgV1t0IC0gMTZdXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0VDEgPSBzYWZlQWRkXzUoaCwgc2lnbWExKGUpLCBjaChlLCBmLCBnKSwgS1t0XSwgV1t0XSk7XG5cdFx0XHRcdFQyID0gc2FmZUFkZF8yKHNpZ21hMChhKSwgbWFqKGEsIGIsIGMpKTtcblx0XHRcdFx0aCA9IGc7XG5cdFx0XHRcdGcgPSBmO1xuXHRcdFx0XHRmID0gZTtcblx0XHRcdFx0ZSA9IHNhZmVBZGRfMihkLCBUMSk7XG5cdFx0XHRcdGQgPSBjO1xuXHRcdFx0XHRjID0gYjtcblx0XHRcdFx0YiA9IGE7XG5cdFx0XHRcdGEgPSBzYWZlQWRkXzIoVDEsIFQyKTtcblx0XHRcdH1cblxuXHRcdFx0SFswXSA9IHNhZmVBZGRfMihhLCBIWzBdKTtcblx0XHRcdEhbMV0gPSBzYWZlQWRkXzIoYiwgSFsxXSk7XG5cdFx0XHRIWzJdID0gc2FmZUFkZF8yKGMsIEhbMl0pO1xuXHRcdFx0SFszXSA9IHNhZmVBZGRfMihkLCBIWzNdKTtcblx0XHRcdEhbNF0gPSBzYWZlQWRkXzIoZSwgSFs0XSk7XG5cdFx0XHRIWzVdID0gc2FmZUFkZF8yKGYsIEhbNV0pO1xuXHRcdFx0SFs2XSA9IHNhZmVBZGRfMihnLCBIWzZdKTtcblx0XHRcdEhbN10gPSBzYWZlQWRkXzIoaCwgSFs3XSk7XG5cdFx0fVxuXG5cdFx0c3dpdGNoICh2YXJpYW50KVxuXHRcdHtcblx0XHRjYXNlIFwiU0hBLTIyNFwiOlxuXHRcdFx0cmV0dXJuXHRbXG5cdFx0XHRcdEhbMF0sIEhbMV0sIEhbMl0sIEhbM10sXG5cdFx0XHRcdEhbNF0sIEhbNV0sIEhbNl1cblx0XHRcdF07XG5cdFx0Y2FzZSBcIlNIQS0yNTZcIjpcblx0XHRcdHJldHVybiBIO1xuXHRcdGNhc2UgXCJTSEEtMzg0XCI6XG5cdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRIWzBdLmhpZ2hPcmRlciwgSFswXS5sb3dPcmRlcixcblx0XHRcdFx0SFsxXS5oaWdoT3JkZXIsIEhbMV0ubG93T3JkZXIsXG5cdFx0XHRcdEhbMl0uaGlnaE9yZGVyLCBIWzJdLmxvd09yZGVyLFxuXHRcdFx0XHRIWzNdLmhpZ2hPcmRlciwgSFszXS5sb3dPcmRlcixcblx0XHRcdFx0SFs0XS5oaWdoT3JkZXIsIEhbNF0ubG93T3JkZXIsXG5cdFx0XHRcdEhbNV0uaGlnaE9yZGVyLCBIWzVdLmxvd09yZGVyXG5cdFx0XHRdO1xuXHRcdGNhc2UgXCJTSEEtNTEyXCI6XG5cdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRIWzBdLmhpZ2hPcmRlciwgSFswXS5sb3dPcmRlcixcblx0XHRcdFx0SFsxXS5oaWdoT3JkZXIsIEhbMV0ubG93T3JkZXIsXG5cdFx0XHRcdEhbMl0uaGlnaE9yZGVyLCBIWzJdLmxvd09yZGVyLFxuXHRcdFx0XHRIWzNdLmhpZ2hPcmRlciwgSFszXS5sb3dPcmRlcixcblx0XHRcdFx0SFs0XS5oaWdoT3JkZXIsIEhbNF0ubG93T3JkZXIsXG5cdFx0XHRcdEhbNV0uaGlnaE9yZGVyLCBIWzVdLmxvd09yZGVyLFxuXHRcdFx0XHRIWzZdLmhpZ2hPcmRlciwgSFs2XS5sb3dPcmRlcixcblx0XHRcdFx0SFs3XS5oaWdoT3JkZXIsIEhbN10ubG93T3JkZXJcblx0XHRcdF07XG5cdFx0ZGVmYXVsdDpcblx0XHRcdC8qIFRoaXMgc2hvdWxkIG5ldmVyIGJlIHJlYWNoZWQgKi9cblx0XHRcdHJldHVybiBbXTsgXG5cdFx0fVxuXHR9LFxuXG5cdC8qXG5cdCAqIGpzU0hBIGlzIHRoZSB3b3JraG9yc2Ugb2YgdGhlIGxpYnJhcnkuICBJbnN0YW50aWF0ZSBpdCB3aXRoIHRoZSBzdHJpbmcgdG9cblx0ICogYmUgaGFzaGVkIGFzIHRoZSBwYXJhbWV0ZXJcblx0ICpcblx0ICogQGNvbnN0cnVjdG9yXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzcmNTdHJpbmcgVGhlIHN0cmluZyB0byBiZSBoYXNoZWRcblx0ICogQHBhcmFtIHtTdHJpbmd9IGlucHV0Rm9ybWF0IFRoZSBmb3JtYXQgb2Ygc3JjU3RyaW5nLCBBU0NJSSBvciBIRVhcblx0ICovXG5cdGpzU0hBID0gZnVuY3Rpb24gKHNyY1N0cmluZywgaW5wdXRGb3JtYXQpXG5cdHtcblxuXHRcdHRoaXMuc2hhMSA9IG51bGw7XG5cdFx0dGhpcy5zaGEyMjQgPSBudWxsO1xuXHRcdHRoaXMuc2hhMjU2ID0gbnVsbDtcblx0XHR0aGlzLnNoYTM4NCA9IG51bGw7XG5cdFx0dGhpcy5zaGE1MTIgPSBudWxsO1xuXG5cdFx0dGhpcy5zdHJCaW5MZW4gPSBudWxsO1xuXHRcdHRoaXMuc3RyVG9IYXNoID0gbnVsbDtcblxuXHRcdC8qIENvbnZlcnQgdGhlIGlucHV0IHN0cmluZyBpbnRvIHRoZSBjb3JyZWN0IHR5cGUgKi9cblx0XHRpZiAoXCJIRVhcIiA9PT0gaW5wdXRGb3JtYXQpXG5cdFx0e1xuXHRcdFx0aWYgKDAgIT09IChzcmNTdHJpbmcubGVuZ3RoICUgMikpXG5cdFx0XHR7XG5cdFx0XHRcdHJldHVybiBcIlRFWFQgTVVTVCBCRSBJTiBCWVRFIElOQ1JFTUVOVFNcIjtcblx0XHRcdH1cblx0XHRcdHRoaXMuc3RyQmluTGVuID0gc3JjU3RyaW5nLmxlbmd0aCAqIDQ7XG5cdFx0XHR0aGlzLnN0clRvSGFzaCA9IGhleDJiaW5iKHNyY1N0cmluZyk7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKChcIkFTQ0lJXCIgPT09IGlucHV0Rm9ybWF0KSB8fFxuXHRcdFx0ICgndW5kZWZpbmVkJyA9PT0gdHlwZW9mKGlucHV0Rm9ybWF0KSkpXG5cdFx0e1xuXHRcdFx0dGhpcy5zdHJCaW5MZW4gPSBzcmNTdHJpbmcubGVuZ3RoICogY2hhclNpemU7XG5cdFx0XHR0aGlzLnN0clRvSGFzaCA9IHN0cjJiaW5iKHNyY1N0cmluZyk7XG5cdFx0fVxuXHRcdGVsc2Vcblx0XHR7XG5cdFx0XHRyZXR1cm4gXCJVTktOT1dOIFRFWFQgSU5QVVQgVFlQRVwiO1xuXHRcdH1cblx0fTtcblxuXHRqc1NIQS5wcm90b3R5cGUgPSB7XG5cdFx0Lypcblx0XHQgKiBSZXR1cm5zIHRoZSBkZXNpcmVkIFNIQSBoYXNoIG9mIHRoZSBzdHJpbmcgc3BlY2lmaWVkIGF0IGluc3RhbnRpYXRpb25cblx0XHQgKiB1c2luZyB0aGUgc3BlY2lmaWVkIHBhcmFtZXRlcnNcblx0XHQgKlxuXHRcdCAqIEBwYXJhbSB7U3RyaW5nfSB2YXJpYW50IFRoZSBkZXNpcmVkIFNIQSB2YXJpYW50IChTSEEtMSwgU0hBLTIyNCxcblx0XHQgKlx0IFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIpXG5cdFx0ICogQHBhcmFtIHtTdHJpbmd9IGZvcm1hdCBUaGUgZGVzaXJlZCBvdXRwdXQgZm9ybWF0dGluZyAoQjY0IG9yIEhFWClcblx0XHQgKiBAcmV0dXJuIFRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGhhc2ggaW4gdGhlIGZvcm1hdCBzcGVjaWZpZWRcblx0XHQgKi9cblx0XHRnZXRIYXNoIDogZnVuY3Rpb24gKHZhcmlhbnQsIGZvcm1hdClcblx0XHR7XG5cdFx0XHR2YXIgZm9ybWF0RnVuYyA9IG51bGwsIG1lc3NhZ2UgPSB0aGlzLnN0clRvSGFzaC5zbGljZSgpO1xuXG5cdFx0XHRzd2l0Y2ggKGZvcm1hdClcblx0XHRcdHtcblx0XHRcdGNhc2UgXCJIRVhcIjpcblx0XHRcdFx0Zm9ybWF0RnVuYyA9IGJpbmIyaGV4O1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJCNjRcIjpcblx0XHRcdFx0Zm9ybWF0RnVuYyA9IGJpbmIyYjY0O1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJBU0NJSVwiOlxuXHRcdFx0XHRmb3JtYXRGdW5jID0gYmluYjJzdHI7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0cmV0dXJuIFwiRk9STUFUIE5PVCBSRUNPR05JWkVEXCI7XG5cdFx0XHR9XG5cblx0XHRcdHN3aXRjaCAodmFyaWFudClcblx0XHRcdHtcblx0XHRcdGNhc2UgXCJTSEEtMVwiOlxuXHRcdFx0XHRpZiAobnVsbCA9PT0gdGhpcy5zaGExKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0dGhpcy5zaGExID0gY29yZVNIQTEobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBmb3JtYXRGdW5jKHRoaXMuc2hhMSk7XG5cdFx0XHRjYXNlIFwiU0hBLTIyNFwiOlxuXHRcdFx0XHRpZiAobnVsbCA9PT0gdGhpcy5zaGEyMjQpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHR0aGlzLnNoYTIyNCA9IGNvcmVTSEEyKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTIyNCk7XG5cdFx0XHRjYXNlIFwiU0hBLTI1NlwiOlxuXHRcdFx0XHRpZiAobnVsbCA9PT0gdGhpcy5zaGEyNTYpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHR0aGlzLnNoYTI1NiA9IGNvcmVTSEEyKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTI1Nik7XG5cdFx0XHRjYXNlIFwiU0hBLTM4NFwiOlxuXHRcdFx0XHRpZiAobnVsbCA9PT0gdGhpcy5zaGEzODQpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHR0aGlzLnNoYTM4NCA9IGNvcmVTSEEyKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTM4NCk7XG5cdFx0XHRjYXNlIFwiU0hBLTUxMlwiOlxuXHRcdFx0XHRpZiAobnVsbCA9PT0gdGhpcy5zaGE1MTIpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHR0aGlzLnNoYTUxMiA9IGNvcmVTSEEyKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTUxMik7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRyZXR1cm4gXCJIQVNIIE5PVCBSRUNPR05JWkVEXCI7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdC8qXG5cdFx0ICogUmV0dXJucyB0aGUgZGVzaXJlZCBITUFDIG9mIHRoZSBzdHJpbmcgc3BlY2lmaWVkIGF0IGluc3RhbnRpYXRpb25cblx0XHQgKiB1c2luZyB0aGUga2V5IGFuZCB2YXJpYW50IHBhcmFtLlxuXHRcdCAqXG5cdFx0ICogQHBhcmFtIHtTdHJpbmd9IGtleSBUaGUga2V5IHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBITUFDXG5cdFx0ICogQHBhcmFtIHtTdHJpbmd9IGlucHV0Rm9ybWF0IFRoZSBmb3JtYXQgb2Yga2V5LCBBU0NJSSBvciBIRVhcblx0XHQgKiBAcGFyYW0ge1N0cmluZ30gdmFyaWFudCBUaGUgZGVzaXJlZCBTSEEgdmFyaWFudCAoU0hBLTEsIFNIQS0yMjQsXG5cdFx0ICpcdCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyKVxuXHRcdCAqIEBwYXJhbSB7U3RyaW5nfSBvdXRwdXRGb3JtYXQgVGhlIGRlc2lyZWQgb3V0cHV0IGZvcm1hdHRpbmdcblx0XHQgKlx0IChCNjQgb3IgSEVYKVxuXHRcdCAqIEByZXR1cm4gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaGFzaCBpbiB0aGUgZm9ybWF0IHNwZWNpZmllZFxuXHRcdCAqL1xuXHRcdGdldEhNQUMgOiBmdW5jdGlvbiAoa2V5LCBpbnB1dEZvcm1hdCwgdmFyaWFudCwgb3V0cHV0Rm9ybWF0KVxuXHRcdHtcblx0XHRcdHZhciBmb3JtYXRGdW5jLCBrZXlUb1VzZSwgYmxvY2tCeXRlU2l6ZSwgYmxvY2tCaXRTaXplLCBpLFxuXHRcdFx0XHRyZXRWYWwsIGxhc3RBcnJheUluZGV4LCBrZXlCaW5MZW4sIGhhc2hCaXRTaXplLFxuXHRcdFx0XHRrZXlXaXRoSVBhZCA9IFtdLCBrZXlXaXRoT1BhZCA9IFtdO1xuXG5cdFx0XHQvKiBWYWxpZGF0ZSB0aGUgb3V0cHV0IGZvcm1hdCBzZWxlY3Rpb24gKi9cblx0XHRcdHN3aXRjaCAob3V0cHV0Rm9ybWF0KVxuXHRcdFx0e1xuXHRcdFx0Y2FzZSBcIkhFWFwiOlxuXHRcdFx0XHRmb3JtYXRGdW5jID0gYmluYjJoZXg7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcIkI2NFwiOlxuXHRcdFx0XHRmb3JtYXRGdW5jID0gYmluYjJiNjQ7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcIkFTQ0lJXCI6XG5cdFx0XHRcdGZvcm1hdEZ1bmMgPSBiaW5iMnN0cjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRyZXR1cm4gXCJGT1JNQVQgTk9UIFJFQ09HTklaRURcIjtcblx0XHRcdH1cblxuXHRcdFx0LyogVmFsaWRhdGUgdGhlIGhhc2ggdmFyaWFudCBzZWxlY3Rpb24gYW5kIHNldCBuZWVkZWQgdmFyaWFibGVzICovXG5cdFx0XHRzd2l0Y2ggKHZhcmlhbnQpXG5cdFx0XHR7XG5cdFx0XHRjYXNlIFwiU0hBLTFcIjpcblx0XHRcdFx0YmxvY2tCeXRlU2l6ZSA9IDY0O1xuXHRcdFx0XHRoYXNoQml0U2l6ZSA9IDE2MDtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIFwiU0hBLTIyNFwiOlxuXHRcdFx0XHRibG9ja0J5dGVTaXplID0gNjQ7XG5cdFx0XHRcdGhhc2hCaXRTaXplID0gMjI0O1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgXCJTSEEtMjU2XCI6XG5cdFx0XHRcdGJsb2NrQnl0ZVNpemUgPSA2NDtcblx0XHRcdFx0aGFzaEJpdFNpemUgPSAyNTY7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcIlNIQS0zODRcIjpcblx0XHRcdFx0YmxvY2tCeXRlU2l6ZSA9IDEyODtcblx0XHRcdFx0aGFzaEJpdFNpemUgPSAzODQ7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcIlNIQS01MTJcIjpcblx0XHRcdFx0YmxvY2tCeXRlU2l6ZSA9IDEyODtcblx0XHRcdFx0aGFzaEJpdFNpemUgPSA1MTI7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0cmV0dXJuIFwiSEFTSCBOT1QgUkVDT0dOSVpFRFwiO1xuXHRcdFx0fVxuXG5cdFx0XHQvKiBWYWxpZGF0ZSBpbnB1dCBmb3JtYXQgc2VsZWN0aW9uICovXG5cdFx0XHRpZiAoXCJIRVhcIiA9PT0gaW5wdXRGb3JtYXQpXG5cdFx0XHR7XG5cdFx0XHRcdC8qIE5pYmJsZXMgbXVzdCBjb21lIGluIHBhaXJzICovXG5cdFx0XHRcdGlmICgwICE9PSAoa2V5Lmxlbmd0aCAlIDIpKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0cmV0dXJuIFwiS0VZIE1VU1QgQkUgSU4gQllURSBJTkNSRU1FTlRTXCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0a2V5VG9Vc2UgPSBoZXgyYmluYihrZXkpO1xuXHRcdFx0XHRrZXlCaW5MZW4gPSBrZXkubGVuZ3RoICogNDtcblx0XHRcdH1cblx0XHRcdGVsc2UgaWYgKFwiQVNDSUlcIiA9PT0gaW5wdXRGb3JtYXQpXG5cdFx0XHR7XG5cdFx0XHRcdGtleVRvVXNlID0gc3RyMmJpbmIoa2V5KTtcblx0XHRcdFx0a2V5QmluTGVuID0ga2V5Lmxlbmd0aCAqIGNoYXJTaXplO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0XHRyZXR1cm4gXCJVTktOT1dOIEtFWSBJTlBVVCBUWVBFXCI7XG5cdFx0XHR9XG5cblx0XHRcdC8qIFRoZXNlIGFyZSB1c2VkIG11bHRpcGxlIHRpbWVzLCBjYWxjdWxhdGUgYW5kIHN0b3JlIHRoZW0gKi9cblx0XHRcdGJsb2NrQml0U2l6ZSA9IGJsb2NrQnl0ZVNpemUgKiA4O1xuXHRcdFx0bGFzdEFycmF5SW5kZXggPSAoYmxvY2tCeXRlU2l6ZSAvIDQpIC0gMTtcblxuXHRcdFx0LyogRmlndXJlIG91dCB3aGF0IHRvIGRvIHdpdGggdGhlIGtleSBiYXNlZCBvbiBpdHMgc2l6ZSByZWxhdGl2ZSB0b1xuXHRcdFx0ICogdGhlIGhhc2gncyBibG9jayBzaXplICovXG5cdFx0XHRpZiAoYmxvY2tCeXRlU2l6ZSA8IChrZXlCaW5MZW4gLyA4KSlcblx0XHRcdHtcblx0XHRcdFx0aWYgKFwiU0hBLTFcIiA9PT0gdmFyaWFudClcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGtleVRvVXNlID0gY29yZVNIQTEoa2V5VG9Vc2UsIGtleUJpbkxlbik7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0a2V5VG9Vc2UgPSBjb3JlU0hBMihrZXlUb1VzZSwga2V5QmluTGVuLCB2YXJpYW50KTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvKiBGb3IgYWxsIHZhcmlhbnRzLCB0aGUgYmxvY2sgc2l6ZSBpcyBiaWdnZXIgdGhhbiB0aGUgb3V0cHV0XG5cdFx0XHRcdCAqIHNpemUgc28gdGhlcmUgd2lsbCBuZXZlciBiZSBhIHVzZWZ1bCBieXRlIGF0IHRoZSBlbmQgb2YgdGhlXG5cdFx0XHRcdCAqIHN0cmluZyAqL1xuXHRcdFx0XHRrZXlUb1VzZVtsYXN0QXJyYXlJbmRleF0gJj0gMHhGRkZGRkYwMDtcblx0XHRcdH1cblx0XHRcdGVsc2UgaWYgKGJsb2NrQnl0ZVNpemUgPiAoa2V5QmluTGVuIC8gOCkpXG5cdFx0XHR7XG5cdFx0XHRcdC8qIElmIHRoZSBibG9ja0J5dGVTaXplIGlzIGdyZWF0ZXIgdGhhbiB0aGUga2V5IGxlbmd0aCwgdGhlcmVcblx0XHRcdFx0ICogd2lsbCBhbHdheXMgYmUgYXQgTEVBU1Qgb25lIFwidXNlbGVzc1wiIGJ5dGUgYXQgdGhlIGVuZCBvZiB0aGVcblx0XHRcdFx0ICogc3RyaW5nICovXG5cdFx0XHRcdGtleVRvVXNlW2xhc3RBcnJheUluZGV4XSAmPSAweEZGRkZGRjAwO1xuXHRcdFx0fVxuXG5cdFx0XHQvKiBDcmVhdGUgaXBhZCBhbmQgb3BhZCAqL1xuXHRcdFx0Zm9yIChpID0gMDsgaSA8PSBsYXN0QXJyYXlJbmRleDsgaSArPSAxKVxuXHRcdFx0e1xuXHRcdFx0XHRrZXlXaXRoSVBhZFtpXSA9IGtleVRvVXNlW2ldIF4gMHgzNjM2MzYzNjtcblx0XHRcdFx0a2V5V2l0aE9QYWRbaV0gPSBrZXlUb1VzZVtpXSBeIDB4NUM1QzVDNUM7XG5cdFx0XHR9XG5cblx0XHRcdC8qIENhbGN1bGF0ZSB0aGUgSE1BQyAqL1xuXHRcdFx0aWYgKFwiU0hBLTFcIiA9PT0gdmFyaWFudClcblx0XHRcdHtcblx0XHRcdFx0cmV0VmFsID0gY29yZVNIQTEoXG5cdFx0XHRcdFx0XHRcdGtleVdpdGhJUGFkLmNvbmNhdCh0aGlzLnN0clRvSGFzaCksXG5cdFx0XHRcdFx0XHRcdGJsb2NrQml0U2l6ZSArIHRoaXMuc3RyQmluTGVuKTtcblx0XHRcdFx0cmV0VmFsID0gY29yZVNIQTEoXG5cdFx0XHRcdFx0XHRcdGtleVdpdGhPUGFkLmNvbmNhdChyZXRWYWwpLFxuXHRcdFx0XHRcdFx0XHRibG9ja0JpdFNpemUgKyBoYXNoQml0U2l6ZSk7XG5cdFx0XHR9XG5cdFx0XHRlbHNlXG5cdFx0XHR7XG5cdFx0XHRcdHJldFZhbCA9IGNvcmVTSEEyKFxuXHRcdFx0XHRcdFx0XHRrZXlXaXRoSVBhZC5jb25jYXQodGhpcy5zdHJUb0hhc2gpLFxuXHRcdFx0XHRcdFx0XHRibG9ja0JpdFNpemUgKyB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG5cdFx0XHRcdHJldFZhbCA9IGNvcmVTSEEyKFxuXHRcdFx0XHRcdFx0XHRrZXlXaXRoT1BhZC5jb25jYXQocmV0VmFsKSxcblx0XHRcdFx0XHRcdFx0YmxvY2tCaXRTaXplICsgaGFzaEJpdFNpemUsIHZhcmlhbnQpO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gKGZvcm1hdEZ1bmMocmV0VmFsKSk7XG5cdFx0fVxuXHR9O1xuXG5cdHJldHVybiBqc1NIQTtcbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRzaGExOiBmdW5jdGlvbihzdHIpIHtcblx0XHR2YXIgc2hhT2JqID0gbmV3IGpzU0hBKHN0ciwgXCJBU0NJSVwiKTtcblx0XHRyZXR1cm4gc2hhT2JqLmdldEhhc2goXCJTSEEtMVwiLCBcIkFTQ0lJXCIpO1xuXHR9LFxuXHRzaGEyMjQ6IGZ1bmN0aW9uKHN0cikge1xuXHRcdHZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCBcIkFTQ0lJXCIpO1xuXHRcdHJldHVybiBzaGFPYmouZ2V0SGFzaChcIlNIQS0yMjRcIiwgXCJBU0NJSVwiKTtcblx0fSxcblx0c2hhMjU2OiBmdW5jdGlvbihzdHIpIHtcblx0XHR2YXIgc2hhT2JqID0gbmV3IGpzU0hBKHN0ciwgXCJBU0NJSVwiKTtcblx0XHRyZXR1cm4gc2hhT2JqLmdldEhhc2goXCJTSEEtMjU2XCIsIFwiQVNDSUlcIik7XG5cdH0sXG5cdHNoYTM4NDogZnVuY3Rpb24oc3RyKSB7XG5cdFx0dmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsIFwiQVNDSUlcIik7XG5cdFx0cmV0dXJuIHNoYU9iai5nZXRIYXNoKFwiU0hBLTM4NFwiLCBcIkFTQ0lJXCIpO1xuXG5cdH0sXG5cdHNoYTUxMjogZnVuY3Rpb24oc3RyKSB7XG5cdFx0dmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsIFwiQVNDSUlcIik7XG5cdFx0cmV0dXJuIHNoYU9iai5nZXRIYXNoKFwiU0hBLTUxMlwiLCBcIkFTQ0lJXCIpO1xuXHR9XG59XG4iLCJcbm1vZHVsZS5leHBvcnRzID0ge1xuXHRjaXBoZXI6IHJlcXVpcmUoJy4vY2lwaGVyJyksXG5cdGhhc2g6IHJlcXVpcmUoJy4vaGFzaCcpLFxuXHRjZmI6IHJlcXVpcmUoJy4vY2ZiLmpzJyksXG5cdHB1YmxpY0tleTogcmVxdWlyZSgnLi9wdWJsaWNfa2V5JyksXG5cdHNpZ25hdHVyZTogcmVxdWlyZSgnLi9zaWduYXR1cmUuanMnKSxcblx0cmFuZG9tOiByZXF1aXJlKCcuL3JhbmRvbS5qcycpLFxuXHRwa2NzMTogcmVxdWlyZSgnLi9wa2NzMS5qcycpXG5cbn1cblxudmFyIGNyeXB0byA9IHJlcXVpcmUoJy4vY3J5cHRvLmpzJyk7XG5cbmZvcih2YXIgaSBpbiBjcnlwdG8pXG5cdG1vZHVsZS5leHBvcnRzW2ldID0gY3J5cHRvW2ldO1xuXG5cblxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBBU04xIG9iamVjdCBpZGVudGlmaWVycyBmb3IgaGFzaGVzIChTZWUgUkZDNDg4MCA1LjIuMilcbiAqL1xuaGFzaF9oZWFkZXJzID0gbmV3IEFycmF5KCk7XG5oYXNoX2hlYWRlcnNbMV0gID0gWzB4MzAsMHgyMCwweDMwLDB4MGMsMHgwNiwweDA4LDB4MmEsMHg4NiwweDQ4LDB4ODYsMHhmNywweDBkLDB4MDIsMHgwNSwweDA1LDB4MDAsMHgwNCwweDEwXTtcbmhhc2hfaGVhZGVyc1szXSAgPSBbMHgzMCwweDIxLDB4MzAsMHgwOSwweDA2LDB4MDUsMHgyQiwweDI0LDB4MDMsMHgwMiwweDAxLDB4MDUsMHgwMCwweDA0LDB4MTRdO1xuaGFzaF9oZWFkZXJzWzJdICA9IFsweDMwLDB4MjEsMHgzMCwweDA5LDB4MDYsMHgwNSwweDJiLDB4MGUsMHgwMywweDAyLDB4MWEsMHgwNSwweDAwLDB4MDQsMHgxNF07XG5oYXNoX2hlYWRlcnNbOF0gID0gWzB4MzAsMHgzMSwweDMwLDB4MGQsMHgwNiwweDA5LDB4NjAsMHg4NiwweDQ4LDB4MDEsMHg2NSwweDAzLDB4MDQsMHgwMiwweDAxLDB4MDUsMHgwMCwweDA0LDB4MjBdO1xuaGFzaF9oZWFkZXJzWzldICA9IFsweDMwLDB4NDEsMHgzMCwweDBkLDB4MDYsMHgwOSwweDYwLDB4ODYsMHg0OCwweDAxLDB4NjUsMHgwMywweDA0LDB4MDIsMHgwMiwweDA1LDB4MDAsMHgwNCwweDMwXTtcbmhhc2hfaGVhZGVyc1sxMF0gPSBbMHgzMCwweDUxLDB4MzAsMHgwZCwweDA2LDB4MDksMHg2MCwweDg2LDB4NDgsMHgwMSwweDY1LDB4MDMsMHgwNCwweDAyLDB4MDMsMHgwNSwweDAwLDB4MDQsMHg0MF07XG5oYXNoX2hlYWRlcnNbMTFdID0gWzB4MzAsMHgzMSwweDMwLDB4MGQsMHgwNiwweDA5LDB4NjAsMHg4NiwweDQ4LDB4MDEsMHg2NSwweDAzLDB4MDQsMHgwMiwweDA0LDB4MDUsMHgwMCwweDA0LDB4MUNdO1xuXG5cbnZhciBjcnlwdG8gPSByZXF1aXJlKCcuL2NyeXB0by5qcycpLFxuXHRyYW5kb20gPSByZXF1aXJlKCcuL3JhbmRvbS5qcycpLFxuXHR1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuXHRCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5L2pzYm4uanMnKSxcblx0aGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpO1xuXHRcbm1vZHVsZS5leHBvcnRzID0ge1xuXHRlbWU6IHtcblx0LyoqXG5cdCAqIGNyZWF0ZSBhIEVNRS1QS0NTMS12MV81IHBhZGRpbmcgKFNlZSBSRkM0ODgwIDEzLjEuMSlcblx0ICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgbWVzc2FnZSB0byBiZSBwYWRkZWRcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIHRvIHRoZSByZXN1bHRpbmcgbWVzc2FnZVxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IEVNRS1QS0NTMSBwYWRkZWQgbWVzc2FnZVxuXHQgKi9cblx0ZW5jb2RlOiBmdW5jdGlvbihtZXNzYWdlLCBsZW5ndGgpIHtcblx0XHRpZiAobWVzc2FnZS5sZW5ndGggPiBsZW5ndGgtMTEpXG5cdFx0XHRyZXR1cm4gLTE7XG5cdFx0dmFyIHJlc3VsdCA9IFwiXCI7XG5cdFx0cmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG5cdFx0cmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMik7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGggLSBtZXNzYWdlLmxlbmd0aCAtIDM7IGkrKykge1xuXHRcdFx0cmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocmFuZG9tLmdldFBzZXVkb1JhbmRvbSgxLDI1NSkpO1xuXHRcdH1cblx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcblx0XHRyZXN1bHQgKz0gbWVzc2FnZTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBkZWNvZGVzIGEgRU1FLVBLQ1MxLXYxXzUgcGFkZGluZyAoU2VlIFJGQzQ4ODAgMTMuMS4yKVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBFTUUtUEtDUzEgcGFkZGVkIG1lc3NhZ2Vcblx0ICogQHJldHVybiB7U3RyaW5nfSBkZWNvZGVkIG1lc3NhZ2UgXG5cdCAqL1xuXHQgZGVjb2RlOiBmdW5jdGlvbihtZXNzYWdlLCBsZW4pIHtcblx0XHRpZiAobWVzc2FnZS5sZW5ndGggPCBsZW4pXG5cdFx0XHRtZXNzYWdlID0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKSttZXNzYWdlO1xuXHRcdGlmIChtZXNzYWdlLmxlbmd0aCA8IDEyIHx8IG1lc3NhZ2UuY2hhckNvZGVBdCgwKSAhPSAwIHx8IG1lc3NhZ2UuY2hhckNvZGVBdCgxKSAhPSAyKVxuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdHZhciBpID0gMjtcblx0XHR3aGlsZSAobWVzc2FnZS5jaGFyQ29kZUF0KGkpICE9IDAgJiYgbWVzc2FnZS5sZW5ndGggPiBpKVxuXHRcdFx0aSsrO1xuXHRcdHJldHVybiBtZXNzYWdlLnN1YnN0cmluZyhpKzEsIG1lc3NhZ2UubGVuZ3RoKTtcblx0fSxcblx0fSxcblxuXHRlbXNhOiB7XG5cblx0LyoqXG5cdCAqIGNyZWF0ZSBhIEVNU0EtUEtDUzEtdjFfNSBwYWRkaW5nIChTZWUgUkZDNDg4MCAxMy4xLjMpXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBIYXNoIGFsZ29yaXRobSB0eXBlIHVzZWRcblx0ICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBiZSBoYXNoZWRcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBrZXlsZW5ndGggS2V5IHNpemUgb2YgdGhlIHB1YmxpYyBtcGkgaW4gYnl0ZXNcblx0ICogQHJldHVybnMge1N0cmluZ30gSGFzaGNvZGUgd2l0aCBwa2NzMXBhZGRpbmcgYXMgc3RyaW5nXG5cdCAqL1xuXHRlbmNvZGU6IGZ1bmN0aW9uKGFsZ28sIGRhdGEsIGtleWxlbmd0aCkge1xuXHRcdHZhciBkYXRhMiA9IFwiXCI7XG5cdFx0ZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKTtcblx0XHRkYXRhMiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDEpO1xuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgKGtleWxlbmd0aCAtIGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGggLSAzIC0gXG5cdFx0XHRoYXNoLmdldEhhc2hCeXRlTGVuZ3RoKGFsZ28pKTsgaSsrKVxuXG5cdFx0XHRkYXRhMiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ZmYpO1xuXG5cdFx0ZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKTtcblx0XHRcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGg7IGkrKylcblx0XHRcdGRhdGEyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoaGFzaF9oZWFkZXJzW2FsZ29dW2ldKTtcblx0XHRcblx0XHRkYXRhMiArPSBoYXNoLmRpZ2VzdChhbGdvLCBkYXRhKTtcblx0XHRyZXR1cm4gbmV3IEJpZ0ludGVnZXIodXRpbC5oZXhzdHJkdW1wKGRhdGEyKSwxNik7XG5cdH0sXG5cblx0LyoqXG5cdCAqIGV4dHJhY3QgdGhlIGhhc2ggb3V0IG9mIGFuIEVNU0EtUEtDUzEtdjEuNSBwYWRkaW5nIChTZWUgUkZDNDg4MCAxMy4xLjMpIFxuXHQgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBIYXNoIGluIHBrY3MxIGVuY29kaW5nXG5cdCAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBoYXNoIGFzIHN0cmluZ1xuXHQgKi9cblx0ZGVjb2RlOiBmdW5jdGlvbihhbGdvLCBkYXRhKSB7IFxuXHRcdHZhciBpID0gMDtcblx0XHRpZiAoZGF0YS5jaGFyQ29kZUF0KDApID09IDApIGkrKztcblx0XHRlbHNlIGlmIChkYXRhLmNoYXJDb2RlQXQoMCkgIT0gMSkgcmV0dXJuIC0xO1xuXHRcdGVsc2UgaSsrO1xuXG5cdFx0d2hpbGUgKGRhdGEuY2hhckNvZGVBdChpKSA9PSAweEZGKSBpKys7XG5cdFx0aWYgKGRhdGEuY2hhckNvZGVBdChpKyspICE9IDApIHJldHVybiAtMTtcblx0XHR2YXIgaiA9IDA7XG5cdFx0Zm9yIChqID0gMDsgaiA8IGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGggJiYgaitpIDwgZGF0YS5sZW5ndGg7IGorKykge1xuXHRcdFx0aWYgKGRhdGEuY2hhckNvZGVBdChqK2kpICE9IGhhc2hfaGVhZGVyc1thbGdvXVtqXSkgcmV0dXJuIC0xO1xuXHRcdH1cblx0XHRpKz0gajtcdFxuXHRcdGlmIChkYXRhLnN1YnN0cmluZyhpKS5sZW5ndGggPCBoYXNoLmdldEhhc2hCeXRlTGVuZ3RoKGFsZ28pKSByZXR1cm4gLTE7XG5cdFx0cmV0dXJuIGRhdGEuc3Vic3RyaW5nKGkpO1xuXHR9XG5cdH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG4vL1xuLy8gQSBEaWdpdGFsIHNpZ25hdHVyZSBhbGdvcml0aG0gaW1wbGVtZW50YXRpb25cblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuL2pzYm4uanMnKSxcbiAgcmFuZG9tID0gcmVxdWlyZSgnLi4vcmFuZG9tLmpzJyksXG4gIGhhc2hNb2R1bGUgPSByZXF1aXJlKCcuLi9oYXNoJyksXG5cdHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbmZ1bmN0aW9uIERTQSgpIHtcblx0Ly8gczEgPSAoKGcqKnMpIG1vZCBwKSBtb2QgcVxuXHQvLyBzMSA9ICgocyoqLTEpKihzaGEtMShtKSsoczEqeCkgbW9kIHEpXG5cdGZ1bmN0aW9uIHNpZ24oaGFzaGFsZ28sIG0sIGcsIHAsIHEsIHgpIHtcblx0XHQvLyBJZiB0aGUgb3V0cHV0IHNpemUgb2YgdGhlIGNob3NlbiBoYXNoIGlzIGxhcmdlciB0aGFuIHRoZSBudW1iZXIgb2Zcblx0XHQvLyBiaXRzIG9mIHEsIHRoZSBoYXNoIHJlc3VsdCBpcyB0cnVuY2F0ZWQgdG8gZml0IGJ5IHRha2luZyB0aGUgbnVtYmVyXG5cdFx0Ly8gb2YgbGVmdG1vc3QgYml0cyBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGJpdHMgb2YgcS4gIFRoaXMgKHBvc3NpYmx5XG5cdFx0Ly8gdHJ1bmNhdGVkKSBoYXNoIGZ1bmN0aW9uIHJlc3VsdCBpcyB0cmVhdGVkIGFzIGEgbnVtYmVyIGFuZCB1c2VkXG5cdFx0Ly8gZGlyZWN0bHkgaW4gdGhlIERTQSBzaWduYXR1cmUgYWxnb3JpdGhtLlxuXHRcdHZhciBoYXNoZWRfZGF0YSA9IHV0aWwuZ2V0TGVmdE5CaXRzKGhhc2hNb2R1bGUuZGlnZXN0KGhhc2hhbGdvLG0pLHEuYml0TGVuZ3RoKCkpO1xuXHRcdHZhciBoYXNoID0gbmV3IEJpZ0ludGVnZXIodXRpbC5oZXhzdHJkdW1wKGhhc2hlZF9kYXRhKSwgMTYpO1xuXHRcdHZhciBrID0gcmFuZG9tLmdldFJhbmRvbUJpZ0ludGVnZXJJblJhbmdlKEJpZ0ludGVnZXIuT05FLmFkZChCaWdJbnRlZ2VyLk9ORSksIHEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKTtcblx0XHR2YXIgczEgPSAoZy5tb2RQb3coayxwKSkubW9kKHEpOyBcblx0XHR2YXIgczIgPSAoay5tb2RJbnZlcnNlKHEpLm11bHRpcGx5KGhhc2guYWRkKHgubXVsdGlwbHkoczEpKSkpLm1vZChxKTtcblx0XHR2YXIgcmVzdWx0ID0gbmV3IEFycmF5KCk7XG5cdFx0cmVzdWx0WzBdID0gczEudG9NUEkoKTtcblx0XHRyZXN1bHRbMV0gPSBzMi50b01QSSgpO1xuXHRcdHJldHVybiByZXN1bHQ7XG5cdH1cblx0ZnVuY3Rpb24gc2VsZWN0X2hhc2hfYWxnb3JpdGhtKHEpIHtcblx0XHR2YXIgdXNlcnNldHRpbmcgPSBvcGVucGdwLmNvbmZpZy5jb25maWcucHJlZmVyX2hhc2hfYWxnb3JpdGhtO1xuXHRcdC8qXG5cdFx0ICogMTAyNC1iaXQga2V5LCAxNjAtYml0IHEsIFNIQS0xLCBTSEEtMjI0LCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyIGhhc2hcblx0XHQgKiAyMDQ4LWJpdCBrZXksIDIyNC1iaXQgcSwgU0hBLTIyNCwgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMiBoYXNoXG5cdFx0ICogMjA0OC1iaXQga2V5LCAyNTYtYml0IHEsIFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIgaGFzaFxuXHRcdCAqIDMwNzItYml0IGtleSwgMjU2LWJpdCBxLCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyIGhhc2hcblx0XHQgKi9cblx0XHRzd2l0Y2ggKE1hdGgucm91bmQocS5iaXRMZW5ndGgoKSAvIDgpKSB7XG5cdFx0Y2FzZSAyMDogLy8gMTAyNCBiaXRcblx0XHRcdGlmICh1c2Vyc2V0dGluZyAhPSAyICYmXG5cdFx0XHRcdHVzZXJzZXR0aW5nID4gMTEgJiZcblx0XHRcdFx0dXNlcnNldHRpbmcgIT0gMTAgJiZcblx0XHRcdFx0dXNlcnNldHRpbmcgPCA4KVxuXHRcdFx0XHRyZXR1cm4gMjsgLy8gcHJlZmVyIHNoYTFcblx0XHRcdHJldHVybiB1c2Vyc2V0dGluZztcblx0XHRjYXNlIDI4OiAvLyAyMDQ4IGJpdFxuXHRcdFx0aWYgKHVzZXJzZXR0aW5nID4gMTEgJiZcblx0XHRcdFx0XHR1c2Vyc2V0dGluZyA8IDgpXG5cdFx0XHRcdFx0cmV0dXJuIDExO1xuXHRcdFx0cmV0dXJuIHVzZXJzZXR0aW5nO1xuXHRcdGNhc2UgMzI6IC8vIDQwOTYgYml0IC8vIHByZWZlciBzaGEyMjRcblx0XHRcdGlmICh1c2Vyc2V0dGluZyA+IDEwICYmXG5cdFx0XHRcdFx0dXNlcnNldHRpbmcgPCA4KVxuXHRcdFx0XHRcdHJldHVybiA4OyAvLyBwcmVmZXIgc2hhMjU2XG5cdFx0XHRyZXR1cm4gdXNlcnNldHRpbmc7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdHV0aWwucHJpbnRfZGVidWcoXCJEU0Egc2VsZWN0IGhhc2ggYWxnb3JpdGhtOiByZXR1cm5pbmcgbnVsbCBmb3IgYW4gdW5rbm93biBsZW5ndGggb2YgcVwiKTtcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdFx0XG5cdFx0fVxuXHR9XG5cdHRoaXMuc2VsZWN0X2hhc2hfYWxnb3JpdGhtID0gc2VsZWN0X2hhc2hfYWxnb3JpdGhtO1xuXHRcblx0ZnVuY3Rpb24gdmVyaWZ5KGhhc2hhbGdvLCBzMSxzMixtLHAscSxnLHkpIHtcblx0XHR2YXIgaGFzaGVkX2RhdGEgPSB1dGlsLmdldExlZnROQml0cyhoYXNoTW9kdWxlLmRpZ2VzdChoYXNoYWxnbyxtKSxxLmJpdExlbmd0aCgpKTtcblx0XHR2YXIgaGFzaCA9IG5ldyBCaWdJbnRlZ2VyKHV0aWwuaGV4c3RyZHVtcChoYXNoZWRfZGF0YSksIDE2KTsgXG5cdFx0aWYgKEJpZ0ludGVnZXIuWkVSTy5jb21wYXJlVG8oczEpID4gMCB8fFxuXHRcdFx0XHRzMS5jb21wYXJlVG8ocSkgPiAwIHx8XG5cdFx0XHRcdEJpZ0ludGVnZXIuWkVSTy5jb21wYXJlVG8oczIpID4gMCB8fFxuXHRcdFx0XHRzMi5jb21wYXJlVG8ocSkgPiAwKSB7XG5cdFx0XHR1dGlsLnByaW50X2Vycm9yKFwiaW52YWxpZCBEU0EgU2lnbmF0dXJlXCIpO1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXHRcdHZhciB3ID0gczIubW9kSW52ZXJzZShxKTtcblx0XHR2YXIgdTEgPSBoYXNoLm11bHRpcGx5KHcpLm1vZChxKTtcblx0XHR2YXIgdTIgPSBzMS5tdWx0aXBseSh3KS5tb2QocSk7XG5cdFx0cmV0dXJuIGcubW9kUG93KHUxLHApLm11bHRpcGx5KHkubW9kUG93KHUyLHApKS5tb2QocCkubW9kKHEpO1xuXHR9XG5cdFxuXHQvKlxuXHQgKiB1bnVzZWQgY29kZS4gVGhpcyBjYW4gYmUgdXNlZCBhcyBhIHN0YXJ0IHRvIHdyaXRlIGEga2V5IGdlbmVyYXRvclxuXHQgKiBmdW5jdGlvbi5cblx0XG5cdGZ1bmN0aW9uIGdlbmVyYXRlS2V5KGJpdGNvdW50KSB7XG5cdCAgICB2YXIgcWkgPSBuZXcgQmlnSW50ZWdlcihiaXRjb3VudCwgcHJpbWVDZW50ZXJpZSk7XG5cdCAgICB2YXIgcGkgPSBnZW5lcmF0ZVAocSwgNTEyKTtcblx0ICAgIHZhciBnaSA9IGdlbmVyYXRlRyhwLCBxLCBiaXRjb3VudCk7XG5cdCAgICB2YXIgeGk7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgeGkgPSBuZXcgQmlnSW50ZWdlcihxLmJpdENvdW50KCksIHJhbmQpO1xuXHQgICAgfSB3aGlsZSAoeC5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSAhPSAxICYmIHguY29tcGFyZVRvKHEpICE9IC0xKTtcblx0ICAgIHZhciB5aSA9IGcubW9kUG93KHgsIHApO1xuXHQgICAgcmV0dXJuIHt4OiB4aSwgcTogcWksIHA6IHBpLCBnOiBnaSwgeTogeWl9O1xuXHR9XG5cblx0ZnVuY3Rpb24gZ2VuZXJhdGVQKHEsIGJpdGxlbmd0aCwgcmFuZG9tZm4pIHtcblx0ICAgIGlmIChiaXRsZW5ndGggJSA2NCAhPSAwKSB7XG5cdCAgICBcdHJldHVybiBmYWxzZTtcblx0ICAgIH1cblx0ICAgIHZhciBwVGVtcDtcblx0ICAgIHZhciBwVGVtcDI7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgcFRlbXAgPSByYW5kb21mbihiaXRjb3VudCwgdHJ1ZSk7XG5cdCAgICAgICAgcFRlbXAyID0gcFRlbXAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuXHQgICAgICAgIHBUZW1wID0gcFRlbXAuc3VidHJhY3QocFRlbXAyLnJlbWFpbmRlcihxKSk7XG5cdCAgICB9IHdoaWxlICghcFRlbXAuaXNQcm9iYWJsZVByaW1lKHByaW1lQ2VudGVyaWUpIHx8IHBUZW1wLmJpdExlbmd0aCgpICE9IGwpO1xuXHQgICAgcmV0dXJuIHBUZW1wO1xuXHR9XG5cdFxuXHRmdW5jdGlvbiBnZW5lcmF0ZUcocCwgcSwgYml0bGVuZ3RoLCByYW5kb21mbikge1xuXHQgICAgdmFyIGF1eCA9IHAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpO1xuXHQgICAgdmFyIHBvdyA9IGF1eC5kaXZpZGUocSk7XG5cdCAgICB2YXIgZ1RlbXA7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgZ1RlbXAgPSByYW5kb21mbihiaXRsZW5ndGgpO1xuXHQgICAgfSB3aGlsZSAoZ1RlbXAuY29tcGFyZVRvKGF1eCkgIT0gLTEgJiYgZ1RlbXAuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAxKTtcblx0ICAgIHJldHVybiBnVGVtcC5tb2RQb3cocG93LCBwKTtcblx0fVxuXG5cdGZ1bmN0aW9uIGdlbmVyYXRlSyhxLCBiaXRsZW5ndGgsIHJhbmRvbWZuKSB7XG5cdCAgICB2YXIgdGVtcEs7XG5cdCAgICBkbyB7XG5cdCAgICAgICAgdGVtcEsgPSByYW5kb21mbihiaXRsZW5ndGgsIGZhbHNlKTtcblx0ICAgIH0gd2hpbGUgKHRlbXBLLmNvbXBhcmVUbyhxKSAhPSAtMSAmJiB0ZW1wSy5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSAhPSAxKTtcblx0ICAgIHJldHVybiB0ZW1wSztcblx0fVxuXG5cdGZ1bmN0aW9uIGdlbmVyYXRlUihxLHApIHtcblx0ICAgIGsgPSBnZW5lcmF0ZUsocSk7XG5cdCAgICB2YXIgciA9IGcubW9kUG93KGssIHApLm1vZChxKTtcblx0ICAgIHJldHVybiByO1xuXHR9XG5cblx0ZnVuY3Rpb24gZ2VuZXJhdGVTKGhhc2hmbixrLHIsbSxxLHgpIHtcbiAgICAgICAgdmFyIGhhc2ggPSBoYXNoZm4obSk7XG4gICAgICAgIHMgPSAoay5tb2RJbnZlcnNlKHEpLm11bHRpcGx5KGhhc2guYWRkKHgubXVsdGlwbHkocikpKSkubW9kKHEpO1xuXHQgICAgcmV0dXJuIHM7XG5cdH0gKi9cblx0dGhpcy5zaWduID0gc2lnbjtcblx0dGhpcy52ZXJpZnkgPSB2ZXJpZnk7XG5cdC8vIHRoaXMuZ2VuZXJhdGUgPSBnZW5lcmF0ZUtleTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBEU0E7XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuLy9cbi8vIEVsR2FtYWwgaW1wbGVtZW50YXRpb25cblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuL2pzYm4uanMnKSxcbiAgcmFuZG9tID0gcmVxdWlyZSgnLi4vcmFuZG9tLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbmZ1bmN0aW9uIEVsZ2FtYWwoKSB7XG5cbiAgZnVuY3Rpb24gZW5jcnlwdChtLGcscCx5KSB7XG4gICAgLy8gIGNob29zZSBrIGluIHsyLC4uLixwLTJ9XG4gICAgdmFyIHR3byA9IEJpZ0ludGVnZXIuT05FLmFkZChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgdmFyIHBNaW51czIgPSBwLnN1YnRyYWN0KHR3byk7XG4gICAgdmFyIGsgPSByYW5kb20uZ2V0UmFuZG9tQmlnSW50ZWdlckluUmFuZ2UodHdvLCBwTWludXMyKTtcbiAgICBrID0gay5tb2QocE1pbnVzMikuYWRkKEJpZ0ludGVnZXIuT05FKTtcbiAgICB2YXIgYyA9IFtdO1xuICAgIGNbMF0gPSBnLm1vZFBvdyhrLCBwKTtcbiAgICBjWzFdID0geS5tb2RQb3coaywgcCkubXVsdGlwbHkobSkubW9kKHApO1xuICAgIHJldHVybiBjO1xuICB9XG5cbiAgZnVuY3Rpb24gZGVjcnlwdChjMSxjMixwLHgpIHtcbiAgICB1dGlsLnByaW50X2RlYnVnKFwiRWxnYW1hbCBEZWNyeXB0OlxcbmMxOlwiK3V0aWwuaGV4c3RyZHVtcChjMS50b01QSSgpKStcIlxcblwiK1xuICAgICAgICBcImMyOlwiK3V0aWwuaGV4c3RyZHVtcChjMi50b01QSSgpKStcIlxcblwiK1xuICAgICAgICBcInA6XCIrdXRpbC5oZXhzdHJkdW1wKHAudG9NUEkoKSkrXCJcXG5cIitcbiAgICAgICAgXCJ4OlwiK3V0aWwuaGV4c3RyZHVtcCh4LnRvTVBJKCkpKTtcbiAgICByZXR1cm4gKGMxLm1vZFBvdyh4LCBwKS5tb2RJbnZlcnNlKHApKS5tdWx0aXBseShjMikubW9kKHApO1xuICAgIC8vdmFyIGMgPSBjMS5wb3coeCkubW9kSW52ZXJzZShwKTsgLy8gYzBeLWEgbW9kIHBcbiAgICAgIC8vcmV0dXJuIGMubXVsdGlwbHkoYzIpLm1vZChwKTtcbiAgfVxuXG4gIC8vIHNpZ25pbmcgYW5kIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gdXNpbmcgRWxnYW1hbCBpcyBub3QgcmVxdWlyZWQgYnkgT3BlblBHUC5cbiAgdGhpcy5lbmNyeXB0ID0gZW5jcnlwdDtcbiAgdGhpcy5kZWNyeXB0ID0gZGVjcnlwdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBFbGdhbWFsO1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG5cdHJzYTogcmVxdWlyZSgnLi9yc2EuanMnKSxcblx0ZWxnYW1hbDogcmVxdWlyZSgnLi9lbGdhbWFsLmpzJyksXG5cdGRzYTogcmVxdWlyZSgnLi9kc2EuanMnKVxufVxuIiwiLypcbiAqIENvcHlyaWdodCAoYykgMjAwMy0yMDA1ICBUb20gV3UgKHRqd0Bjcy5TdGFuZm9yZC5FRFUpIFxuICogQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkggXG4gKiBcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZ1xuICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4gKiBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbiAqIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0b1xuICogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvXG4gKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmVcbiAqIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTLUlTXCIgQU5EIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIFxuICogRVhQUkVTUywgSU1QTElFRCBPUiBPVEhFUldJU0UsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04sIEFOWSBcbiAqIFdBUlJBTlRZIE9GIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFxuICpcbiAqIElOIE5PIEVWRU5UIFNIQUxMIFRPTSBXVSBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkNJREVOVEFMLFxuICogSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9GIEFOWSBLSU5ELCBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSXG4gKiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIE9SIE5PVCBBRFZJU0VEIE9GXG4gKiBUSEUgUE9TU0lCSUxJVFkgT0YgREFNQUdFLCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIEFSSVNJTkcgT1VUXG4gKiBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxuICpcbiAqIEluIGFkZGl0aW9uLCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbiBhcHBsaWVzOlxuICpcbiAqIEFsbCByZWRpc3RyaWJ1dGlvbnMgbXVzdCByZXRhaW4gYW4gaW50YWN0IGNvcHkgb2YgdGhpcyBjb3B5cmlnaHQgbm90aWNlXG4gKiBhbmQgZGlzY2xhaW1lci5cbiAqL1xuXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBCYXNpYyBKYXZhU2NyaXB0IEJOIGxpYnJhcnkgLSBzdWJzZXQgdXNlZnVsIGZvciBSU0EgZW5jcnlwdGlvbi5cblxuLy8gQml0cyBwZXIgZGlnaXRcbnZhciBkYml0cztcblxuLy8gSmF2YVNjcmlwdCBlbmdpbmUgYW5hbHlzaXNcbnZhciBjYW5hcnkgPSAweGRlYWRiZWVmY2FmZTtcbnZhciBqX2xtID0gKChjYW5hcnkmMHhmZmZmZmYpPT0weGVmY2FmZSk7XG5cbi8vIChwdWJsaWMpIENvbnN0cnVjdG9yXG5mdW5jdGlvbiBCaWdJbnRlZ2VyKGEsYixjKSB7XG4gIGlmKGEgIT0gbnVsbClcbiAgICBpZihcIm51bWJlclwiID09IHR5cGVvZiBhKSB0aGlzLmZyb21OdW1iZXIoYSxiLGMpO1xuICAgIGVsc2UgaWYoYiA9PSBudWxsICYmIFwic3RyaW5nXCIgIT0gdHlwZW9mIGEpIHRoaXMuZnJvbVN0cmluZyhhLDI1Nik7XG4gICAgZWxzZSB0aGlzLmZyb21TdHJpbmcoYSxiKTtcbn1cblxuLy8gcmV0dXJuIG5ldywgdW5zZXQgQmlnSW50ZWdlclxuZnVuY3Rpb24gbmJpKCkgeyByZXR1cm4gbmV3IEJpZ0ludGVnZXIobnVsbCk7IH1cblxuLy8gYW06IENvbXB1dGUgd19qICs9ICh4KnRoaXNfaSksIHByb3BhZ2F0ZSBjYXJyaWVzLFxuLy8gYyBpcyBpbml0aWFsIGNhcnJ5LCByZXR1cm5zIGZpbmFsIGNhcnJ5LlxuLy8gYyA8IDMqZHZhbHVlLCB4IDwgMipkdmFsdWUsIHRoaXNfaSA8IGR2YWx1ZVxuLy8gV2UgbmVlZCB0byBzZWxlY3QgdGhlIGZhc3Rlc3Qgb25lIHRoYXQgd29ya3MgaW4gdGhpcyBlbnZpcm9ubWVudC5cblxuLy8gYW0xOiB1c2UgYSBzaW5nbGUgbXVsdCBhbmQgZGl2aWRlIHRvIGdldCB0aGUgaGlnaCBiaXRzLFxuLy8gbWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDI2IGJlY2F1c2Vcbi8vIG1heCBpbnRlcm5hbCB2YWx1ZSA9IDIqZHZhbHVlXjItMipkdmFsdWUgKDwgMl41MylcbmZ1bmN0aW9uIGFtMShpLHgsdyxqLGMsbikge1xuICB3aGlsZSgtLW4gPj0gMCkge1xuICAgIHZhciB2ID0geCp0aGlzW2krK10rd1tqXStjO1xuICAgIGMgPSBNYXRoLmZsb29yKHYvMHg0MDAwMDAwKTtcbiAgICB3W2orK10gPSB2JjB4M2ZmZmZmZjtcbiAgfVxuICByZXR1cm4gYztcbn1cbi8vIGFtMiBhdm9pZHMgYSBiaWcgbXVsdC1hbmQtZXh0cmFjdCBjb21wbGV0ZWx5LlxuLy8gTWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDw9IDMwIGJlY2F1c2Ugd2UgZG8gYml0d2lzZSBvcHNcbi8vIG9uIHZhbHVlcyB1cCB0byAyKmhkdmFsdWVeMi1oZHZhbHVlLTEgKDwgMl4zMSlcbmZ1bmN0aW9uIGFtMihpLHgsdyxqLGMsbikge1xuICB2YXIgeGwgPSB4JjB4N2ZmZiwgeGggPSB4Pj4xNTtcbiAgd2hpbGUoLS1uID49IDApIHtcbiAgICB2YXIgbCA9IHRoaXNbaV0mMHg3ZmZmO1xuICAgIHZhciBoID0gdGhpc1tpKytdPj4xNTtcbiAgICB2YXIgbSA9IHhoKmwraCp4bDtcbiAgICBsID0geGwqbCsoKG0mMHg3ZmZmKTw8MTUpK3dbal0rKGMmMHgzZmZmZmZmZik7XG4gICAgYyA9IChsPj4+MzApKyhtPj4+MTUpK3hoKmgrKGM+Pj4zMCk7XG4gICAgd1tqKytdID0gbCYweDNmZmZmZmZmO1xuICB9XG4gIHJldHVybiBjO1xufVxuLy8gQWx0ZXJuYXRlbHksIHNldCBtYXggZGlnaXQgYml0cyB0byAyOCBzaW5jZSBzb21lXG4vLyBicm93c2VycyBzbG93IGRvd24gd2hlbiBkZWFsaW5nIHdpdGggMzItYml0IG51bWJlcnMuXG5mdW5jdGlvbiBhbTMoaSx4LHcsaixjLG4pIHtcbiAgdmFyIHhsID0geCYweDNmZmYsIHhoID0geD4+MTQ7XG4gIHdoaWxlKC0tbiA+PSAwKSB7XG4gICAgdmFyIGwgPSB0aGlzW2ldJjB4M2ZmZjtcbiAgICB2YXIgaCA9IHRoaXNbaSsrXT4+MTQ7XG4gICAgdmFyIG0gPSB4aCpsK2gqeGw7XG4gICAgbCA9IHhsKmwrKChtJjB4M2ZmZik8PDE0KSt3W2pdK2M7XG4gICAgYyA9IChsPj4yOCkrKG0+PjE0KSt4aCpoO1xuICAgIHdbaisrXSA9IGwmMHhmZmZmZmZmO1xuICB9XG4gIHJldHVybiBjO1xufVxuLyppZihqX2xtICYmIChuYXZpZ2F0b3IgIT0gdW5kZWZpbmVkICYmIFxuXHRuYXZpZ2F0b3IuYXBwTmFtZSA9PSBcIk1pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlclwiKSkge1xuICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMjtcbiAgZGJpdHMgPSAzMDtcbn1cbmVsc2UgaWYoal9sbSAmJiAobmF2aWdhdG9yICE9IHVuZGVmaW5lZCAmJiBuYXZpZ2F0b3IuYXBwTmFtZSAhPSBcIk5ldHNjYXBlXCIpKSB7Ki9cbiAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTE7XG4gIGRiaXRzID0gMjY7XG4vKn1cbmVsc2UgeyAvLyBNb3ppbGxhL05ldHNjYXBlIHNlZW1zIHRvIHByZWZlciBhbTNcbiAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTM7XG4gIGRiaXRzID0gMjg7XG59Ki9cblxuQmlnSW50ZWdlci5wcm90b3R5cGUuREIgPSBkYml0cztcbkJpZ0ludGVnZXIucHJvdG90eXBlLkRNID0gKCgxPDxkYml0cyktMSk7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5EViA9ICgxPDxkYml0cyk7XG5cbnZhciBCSV9GUCA9IDUyO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuRlYgPSBNYXRoLnBvdygyLEJJX0ZQKTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLkYxID0gQklfRlAtZGJpdHM7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5GMiA9IDIqZGJpdHMtQklfRlA7XG5cbi8vIERpZ2l0IGNvbnZlcnNpb25zXG52YXIgQklfUk0gPSBcIjAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elwiO1xudmFyIEJJX1JDID0gbmV3IEFycmF5KCk7XG52YXIgcnIsdnY7XG5yciA9IFwiMFwiLmNoYXJDb2RlQXQoMCk7XG5mb3IodnYgPSAwOyB2diA8PSA5OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2O1xucnIgPSBcImFcIi5jaGFyQ29kZUF0KDApO1xuZm9yKHZ2ID0gMTA7IHZ2IDwgMzY7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7XG5yciA9IFwiQVwiLmNoYXJDb2RlQXQoMCk7XG5mb3IodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcblxuZnVuY3Rpb24gaW50MmNoYXIobikgeyByZXR1cm4gQklfUk0uY2hhckF0KG4pOyB9XG5mdW5jdGlvbiBpbnRBdChzLGkpIHtcbiAgdmFyIGMgPSBCSV9SQ1tzLmNoYXJDb2RlQXQoaSldO1xuICByZXR1cm4gKGM9PW51bGwpPy0xOmM7XG59XG5cbi8vIChwcm90ZWN0ZWQpIGNvcHkgdGhpcyB0byByXG5mdW5jdGlvbiBibnBDb3B5VG8ocikge1xuICBmb3IodmFyIGkgPSB0aGlzLnQtMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSB0aGlzW2ldO1xuICByLnQgPSB0aGlzLnQ7XG4gIHIucyA9IHRoaXMucztcbn1cblxuLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gaW50ZWdlciB2YWx1ZSB4LCAtRFYgPD0geCA8IERWXG5mdW5jdGlvbiBibnBGcm9tSW50KHgpIHtcbiAgdGhpcy50ID0gMTtcbiAgdGhpcy5zID0gKHg8MCk/LTE6MDtcbiAgaWYoeCA+IDApIHRoaXNbMF0gPSB4O1xuICBlbHNlIGlmKHggPCAtMSkgdGhpc1swXSA9IHgrRFY7XG4gIGVsc2UgdGhpcy50ID0gMDtcbn1cblxuLy8gcmV0dXJuIGJpZ2ludCBpbml0aWFsaXplZCB0byB2YWx1ZVxuZnVuY3Rpb24gbmJ2KGkpIHsgdmFyIHIgPSBuYmkoKTsgci5mcm9tSW50KGkpOyByZXR1cm4gcjsgfVxuXG4vLyAocHJvdGVjdGVkKSBzZXQgZnJvbSBzdHJpbmcgYW5kIHJhZGl4XG5mdW5jdGlvbiBibnBGcm9tU3RyaW5nKHMsYikge1xuICB2YXIgaztcbiAgaWYoYiA9PSAxNikgayA9IDQ7XG4gIGVsc2UgaWYoYiA9PSA4KSBrID0gMztcbiAgZWxzZSBpZihiID09IDI1NikgayA9IDg7IC8vIGJ5dGUgYXJyYXlcbiAgZWxzZSBpZihiID09IDIpIGsgPSAxO1xuICBlbHNlIGlmKGIgPT0gMzIpIGsgPSA1O1xuICBlbHNlIGlmKGIgPT0gNCkgayA9IDI7XG4gIGVsc2UgeyB0aGlzLmZyb21SYWRpeChzLGIpOyByZXR1cm47IH1cbiAgdGhpcy50ID0gMDtcbiAgdGhpcy5zID0gMDtcbiAgdmFyIGkgPSBzLmxlbmd0aCwgbWkgPSBmYWxzZSwgc2ggPSAwO1xuICB3aGlsZSgtLWkgPj0gMCkge1xuICAgIHZhciB4ID0gKGs9PTgpP3NbaV0mMHhmZjppbnRBdChzLGkpO1xuICAgIGlmKHggPCAwKSB7XG4gICAgICBpZihzLmNoYXJBdChpKSA9PSBcIi1cIikgbWkgPSB0cnVlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIG1pID0gZmFsc2U7XG4gICAgaWYoc2ggPT0gMClcbiAgICAgIHRoaXNbdGhpcy50KytdID0geDtcbiAgICBlbHNlIGlmKHNoK2sgPiB0aGlzLkRCKSB7XG4gICAgICB0aGlzW3RoaXMudC0xXSB8PSAoeCYoKDE8PCh0aGlzLkRCLXNoKSktMSkpPDxzaDtcbiAgICAgIHRoaXNbdGhpcy50KytdID0gKHg+Pih0aGlzLkRCLXNoKSk7XG4gICAgfVxuICAgIGVsc2VcbiAgICAgIHRoaXNbdGhpcy50LTFdIHw9IHg8PHNoO1xuICAgIHNoICs9IGs7XG4gICAgaWYoc2ggPj0gdGhpcy5EQikgc2ggLT0gdGhpcy5EQjtcbiAgfVxuICBpZihrID09IDggJiYgKHNbMF0mMHg4MCkgIT0gMCkge1xuICAgIHRoaXMucyA9IC0xO1xuICAgIGlmKHNoID4gMCkgdGhpc1t0aGlzLnQtMV0gfD0gKCgxPDwodGhpcy5EQi1zaCkpLTEpPDxzaDtcbiAgfVxuICB0aGlzLmNsYW1wKCk7XG4gIGlmKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcyx0aGlzKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgY2xhbXAgb2ZmIGV4Y2VzcyBoaWdoIHdvcmRzXG5mdW5jdGlvbiBibnBDbGFtcCgpIHtcbiAgdmFyIGMgPSB0aGlzLnMmdGhpcy5ETTtcbiAgd2hpbGUodGhpcy50ID4gMCAmJiB0aGlzW3RoaXMudC0xXSA9PSBjKSAtLXRoaXMudDtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHN0cmluZyByZXByZXNlbnRhdGlvbiBpbiBnaXZlbiByYWRpeFxuZnVuY3Rpb24gYm5Ub1N0cmluZyhiKSB7XG4gIGlmKHRoaXMucyA8IDApIHJldHVybiBcIi1cIit0aGlzLm5lZ2F0ZSgpLnRvU3RyaW5nKGIpO1xuICB2YXIgaztcbiAgaWYoYiA9PSAxNikgayA9IDQ7XG4gIGVsc2UgaWYoYiA9PSA4KSBrID0gMztcbiAgZWxzZSBpZihiID09IDIpIGsgPSAxO1xuICBlbHNlIGlmKGIgPT0gMzIpIGsgPSA1O1xuICBlbHNlIGlmKGIgPT0gNCkgayA9IDI7XG4gIGVsc2UgcmV0dXJuIHRoaXMudG9SYWRpeChiKTtcbiAgdmFyIGttID0gKDE8PGspLTEsIGQsIG0gPSBmYWxzZSwgciA9IFwiXCIsIGkgPSB0aGlzLnQ7XG4gIHZhciBwID0gdGhpcy5EQi0oaSp0aGlzLkRCKSVrO1xuICBpZihpLS0gPiAwKSB7XG4gICAgaWYocCA8IHRoaXMuREIgJiYgKGQgPSB0aGlzW2ldPj5wKSA+IDApIHsgbSA9IHRydWU7IHIgPSBpbnQyY2hhcihkKTsgfVxuICAgIHdoaWxlKGkgPj0gMCkge1xuICAgICAgaWYocCA8IGspIHtcbiAgICAgICAgZCA9ICh0aGlzW2ldJigoMTw8cCktMSkpPDwoay1wKTtcbiAgICAgICAgZCB8PSB0aGlzWy0taV0+PihwKz10aGlzLkRCLWspO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGQgPSAodGhpc1tpXT4+KHAtPWspKSZrbTtcbiAgICAgICAgaWYocCA8PSAwKSB7IHAgKz0gdGhpcy5EQjsgLS1pOyB9XG4gICAgICB9XG4gICAgICBpZihkID4gMCkgbSA9IHRydWU7XG4gICAgICBpZihtKSByICs9IGludDJjaGFyKGQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbT9yOlwiMFwiO1xufVxuXG4vLyAocHVibGljKSAtdGhpc1xuZnVuY3Rpb24gYm5OZWdhdGUoKSB7IHZhciByID0gbmJpKCk7IEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHIpOyByZXR1cm4gcjsgfVxuXG4vLyAocHVibGljKSB8dGhpc3xcbmZ1bmN0aW9uIGJuQWJzKCkgeyByZXR1cm4gKHRoaXMuczwwKT90aGlzLm5lZ2F0ZSgpOnRoaXM7IH1cblxuLy8gKHB1YmxpYykgcmV0dXJuICsgaWYgdGhpcyA+IGEsIC0gaWYgdGhpcyA8IGEsIDAgaWYgZXF1YWxcbmZ1bmN0aW9uIGJuQ29tcGFyZVRvKGEpIHtcbiAgdmFyIHIgPSB0aGlzLnMtYS5zO1xuICBpZihyICE9IDApIHJldHVybiByO1xuICB2YXIgaSA9IHRoaXMudDtcbiAgciA9IGktYS50O1xuICBpZihyICE9IDApIHJldHVybiByO1xuICB3aGlsZSgtLWkgPj0gMCkgaWYoKHI9dGhpc1tpXS1hW2ldKSAhPSAwKSByZXR1cm4gcjtcbiAgcmV0dXJuIDA7XG59XG5cbi8vIHJldHVybnMgYml0IGxlbmd0aCBvZiB0aGUgaW50ZWdlciB4XG5mdW5jdGlvbiBuYml0cyh4KSB7XG4gIHZhciByID0gMSwgdDtcbiAgaWYoKHQ9eD4+PjE2KSAhPSAwKSB7IHggPSB0OyByICs9IDE2OyB9XG4gIGlmKCh0PXg+PjgpICE9IDApIHsgeCA9IHQ7IHIgKz0gODsgfVxuICBpZigodD14Pj40KSAhPSAwKSB7IHggPSB0OyByICs9IDQ7IH1cbiAgaWYoKHQ9eD4+MikgIT0gMCkgeyB4ID0gdDsgciArPSAyOyB9XG4gIGlmKCh0PXg+PjEpICE9IDApIHsgeCA9IHQ7IHIgKz0gMTsgfVxuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHRoZSBudW1iZXIgb2YgYml0cyBpbiBcInRoaXNcIlxuZnVuY3Rpb24gYm5CaXRMZW5ndGgoKSB7XG4gIGlmKHRoaXMudCA8PSAwKSByZXR1cm4gMDtcbiAgcmV0dXJuIHRoaXMuREIqKHRoaXMudC0xKStuYml0cyh0aGlzW3RoaXMudC0xXV4odGhpcy5zJnRoaXMuRE0pKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPDwgbipEQlxuZnVuY3Rpb24gYm5wRExTaGlmdFRvKG4scikge1xuICB2YXIgaTtcbiAgZm9yKGkgPSB0aGlzLnQtMTsgaSA+PSAwOyAtLWkpIHJbaStuXSA9IHRoaXNbaV07XG4gIGZvcihpID0gbi0xOyBpID49IDA7IC0taSkgcltpXSA9IDA7XG4gIHIudCA9IHRoaXMudCtuO1xuICByLnMgPSB0aGlzLnM7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzID4+IG4qREJcbmZ1bmN0aW9uIGJucERSU2hpZnRUbyhuLHIpIHtcbiAgZm9yKHZhciBpID0gbjsgaSA8IHRoaXMudDsgKytpKSByW2ktbl0gPSB0aGlzW2ldO1xuICByLnQgPSBNYXRoLm1heCh0aGlzLnQtbiwwKTtcbiAgci5zID0gdGhpcy5zO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA8PCBuXG5mdW5jdGlvbiBibnBMU2hpZnRUbyhuLHIpIHtcbiAgdmFyIGJzID0gbiV0aGlzLkRCO1xuICB2YXIgY2JzID0gdGhpcy5EQi1icztcbiAgdmFyIGJtID0gKDE8PGNicyktMTtcbiAgdmFyIGRzID0gTWF0aC5mbG9vcihuL3RoaXMuREIpLCBjID0gKHRoaXMuczw8YnMpJnRoaXMuRE0sIGk7XG4gIGZvcihpID0gdGhpcy50LTE7IGkgPj0gMDsgLS1pKSB7XG4gICAgcltpK2RzKzFdID0gKHRoaXNbaV0+PmNicyl8YztcbiAgICBjID0gKHRoaXNbaV0mYm0pPDxicztcbiAgfVxuICBmb3IoaSA9IGRzLTE7IGkgPj0gMDsgLS1pKSByW2ldID0gMDtcbiAgcltkc10gPSBjO1xuICByLnQgPSB0aGlzLnQrZHMrMTtcbiAgci5zID0gdGhpcy5zO1xuICByLmNsYW1wKCk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzID4+IG5cbmZ1bmN0aW9uIGJucFJTaGlmdFRvKG4scikge1xuICByLnMgPSB0aGlzLnM7XG4gIHZhciBkcyA9IE1hdGguZmxvb3Iobi90aGlzLkRCKTtcbiAgaWYoZHMgPj0gdGhpcy50KSB7IHIudCA9IDA7IHJldHVybjsgfVxuICB2YXIgYnMgPSBuJXRoaXMuREI7XG4gIHZhciBjYnMgPSB0aGlzLkRCLWJzO1xuICB2YXIgYm0gPSAoMTw8YnMpLTE7XG4gIHJbMF0gPSB0aGlzW2RzXT4+YnM7XG4gIGZvcih2YXIgaSA9IGRzKzE7IGkgPCB0aGlzLnQ7ICsraSkge1xuICAgIHJbaS1kcy0xXSB8PSAodGhpc1tpXSZibSk8PGNicztcbiAgICByW2ktZHNdID0gdGhpc1tpXT4+YnM7XG4gIH1cbiAgaWYoYnMgPiAwKSByW3RoaXMudC1kcy0xXSB8PSAodGhpcy5zJmJtKTw8Y2JzO1xuICByLnQgPSB0aGlzLnQtZHM7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgLSBhXG5mdW5jdGlvbiBibnBTdWJUbyhhLHIpIHtcbiAgdmFyIGkgPSAwLCBjID0gMCwgbSA9IE1hdGgubWluKGEudCx0aGlzLnQpO1xuICB3aGlsZShpIDwgbSkge1xuICAgIGMgKz0gdGhpc1tpXS1hW2ldO1xuICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICBjID4+PSB0aGlzLkRCO1xuICB9XG4gIGlmKGEudCA8IHRoaXMudCkge1xuICAgIGMgLT0gYS5zO1xuICAgIHdoaWxlKGkgPCB0aGlzLnQpIHtcbiAgICAgIGMgKz0gdGhpc1tpXTtcbiAgICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgKz0gdGhpcy5zO1xuICB9XG4gIGVsc2Uge1xuICAgIGMgKz0gdGhpcy5zO1xuICAgIHdoaWxlKGkgPCBhLnQpIHtcbiAgICAgIGMgLT0gYVtpXTtcbiAgICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgLT0gYS5zO1xuICB9XG4gIHIucyA9IChjPDApPy0xOjA7XG4gIGlmKGMgPCAtMSkgcltpKytdID0gdGhpcy5EVitjO1xuICBlbHNlIGlmKGMgPiAwKSByW2krK10gPSBjO1xuICByLnQgPSBpO1xuICByLmNsYW1wKCk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICogYSwgciAhPSB0aGlzLGEgKEhBQyAxNC4xMilcbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cbmZ1bmN0aW9uIGJucE11bHRpcGx5VG8oYSxyKSB7XG4gIHZhciB4ID0gdGhpcy5hYnMoKSwgeSA9IGEuYWJzKCk7XG4gIHZhciBpID0geC50O1xuICByLnQgPSBpK3kudDtcbiAgd2hpbGUoLS1pID49IDApIHJbaV0gPSAwO1xuICBmb3IoaSA9IDA7IGkgPCB5LnQ7ICsraSkgcltpK3gudF0gPSB4LmFtKDAseVtpXSxyLGksMCx4LnQpO1xuICByLnMgPSAwO1xuICByLmNsYW1wKCk7XG4gIGlmKHRoaXMucyAhPSBhLnMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhyLHIpO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpc14yLCByICE9IHRoaXMgKEhBQyAxNC4xNilcbmZ1bmN0aW9uIGJucFNxdWFyZVRvKHIpIHtcbiAgdmFyIHggPSB0aGlzLmFicygpO1xuICB2YXIgaSA9IHIudCA9IDIqeC50O1xuICB3aGlsZSgtLWkgPj0gMCkgcltpXSA9IDA7XG4gIGZvcihpID0gMDsgaSA8IHgudC0xOyArK2kpIHtcbiAgICB2YXIgYyA9IHguYW0oaSx4W2ldLHIsMippLDAsMSk7XG4gICAgaWYoKHJbaSt4LnRdKz14LmFtKGkrMSwyKnhbaV0sciwyKmkrMSxjLHgudC1pLTEpKSA+PSB4LkRWKSB7XG4gICAgICByW2kreC50XSAtPSB4LkRWO1xuICAgICAgcltpK3gudCsxXSA9IDE7XG4gICAgfVxuICB9XG4gIGlmKHIudCA+IDApIHJbci50LTFdICs9IHguYW0oaSx4W2ldLHIsMippLDAsMSk7XG4gIHIucyA9IDA7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgZGl2aWRlIHRoaXMgYnkgbSwgcXVvdGllbnQgYW5kIHJlbWFpbmRlciB0byBxLCByIChIQUMgMTQuMjApXG4vLyByICE9IHEsIHRoaXMgIT0gbS4gIHEgb3IgciBtYXkgYmUgbnVsbC5cbmZ1bmN0aW9uIGJucERpdlJlbVRvKG0scSxyKSB7XG4gIHZhciBwbSA9IG0uYWJzKCk7XG4gIGlmKHBtLnQgPD0gMCkgcmV0dXJuO1xuICB2YXIgcHQgPSB0aGlzLmFicygpO1xuICBpZihwdC50IDwgcG0udCkge1xuICAgIGlmKHEgIT0gbnVsbCkgcS5mcm9tSW50KDApO1xuICAgIGlmKHIgIT0gbnVsbCkgdGhpcy5jb3B5VG8ocik7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmKHIgPT0gbnVsbCkgciA9IG5iaSgpO1xuICB2YXIgeSA9IG5iaSgpLCB0cyA9IHRoaXMucywgbXMgPSBtLnM7XG4gIHZhciBuc2ggPSB0aGlzLkRCLW5iaXRzKHBtW3BtLnQtMV0pO1x0Ly8gbm9ybWFsaXplIG1vZHVsdXNcbiAgaWYobnNoID4gMCkgeyBwbS5sU2hpZnRUbyhuc2gseSk7IHB0LmxTaGlmdFRvKG5zaCxyKTsgfVxuICBlbHNlIHsgcG0uY29weVRvKHkpOyBwdC5jb3B5VG8ocik7IH1cbiAgdmFyIHlzID0geS50O1xuICB2YXIgeTAgPSB5W3lzLTFdO1xuICBpZih5MCA9PSAwKSByZXR1cm47XG4gIHZhciB5dCA9IHkwKigxPDx0aGlzLkYxKSsoKHlzPjEpP3lbeXMtMl0+PnRoaXMuRjI6MCk7XG4gIHZhciBkMSA9IHRoaXMuRlYveXQsIGQyID0gKDE8PHRoaXMuRjEpL3l0LCBlID0gMTw8dGhpcy5GMjtcbiAgdmFyIGkgPSByLnQsIGogPSBpLXlzLCB0ID0gKHE9PW51bGwpP25iaSgpOnE7XG4gIHkuZGxTaGlmdFRvKGosdCk7XG4gIGlmKHIuY29tcGFyZVRvKHQpID49IDApIHtcbiAgICByW3IudCsrXSA9IDE7XG4gICAgci5zdWJUbyh0LHIpO1xuICB9XG4gIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbyh5cyx0KTtcbiAgdC5zdWJUbyh5LHkpO1x0Ly8gXCJuZWdhdGl2ZVwiIHkgc28gd2UgY2FuIHJlcGxhY2Ugc3ViIHdpdGggYW0gbGF0ZXJcbiAgd2hpbGUoeS50IDwgeXMpIHlbeS50KytdID0gMDtcbiAgd2hpbGUoLS1qID49IDApIHtcbiAgICAvLyBFc3RpbWF0ZSBxdW90aWVudCBkaWdpdFxuICAgIHZhciBxZCA9IChyWy0taV09PXkwKT90aGlzLkRNOk1hdGguZmxvb3IocltpXSpkMSsocltpLTFdK2UpKmQyKTtcbiAgICBpZigocltpXSs9eS5hbSgwLHFkLHIsaiwwLHlzKSkgPCBxZCkge1x0Ly8gVHJ5IGl0IG91dFxuICAgICAgeS5kbFNoaWZ0VG8oaix0KTtcbiAgICAgIHIuc3ViVG8odCxyKTtcbiAgICAgIHdoaWxlKHJbaV0gPCAtLXFkKSByLnN1YlRvKHQscik7XG4gICAgfVxuICB9XG4gIGlmKHEgIT0gbnVsbCkge1xuICAgIHIuZHJTaGlmdFRvKHlzLHEpO1xuICAgIGlmKHRzICE9IG1zKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ocSxxKTtcbiAgfVxuICByLnQgPSB5cztcbiAgci5jbGFtcCgpO1xuICBpZihuc2ggPiAwKSByLnJTaGlmdFRvKG5zaCxyKTtcdC8vIERlbm9ybWFsaXplIHJlbWFpbmRlclxuICBpZih0cyA8IDApIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhyLHIpO1xufVxuXG4vLyAocHVibGljKSB0aGlzIG1vZCBhXG5mdW5jdGlvbiBibk1vZChhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYWJzKCkuZGl2UmVtVG8oYSxudWxsLHIpO1xuICBpZih0aGlzLnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSBhLnN1YlRvKHIscik7XG4gIHJldHVybiByO1xufVxuXG4vLyBNb2R1bGFyIHJlZHVjdGlvbiB1c2luZyBcImNsYXNzaWNcIiBhbGdvcml0aG1cbmZ1bmN0aW9uIENsYXNzaWMobSkgeyB0aGlzLm0gPSBtOyB9XG5mdW5jdGlvbiBjQ29udmVydCh4KSB7XG4gIGlmKHgucyA8IDAgfHwgeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSByZXR1cm4geC5tb2QodGhpcy5tKTtcbiAgZWxzZSByZXR1cm4geDtcbn1cbmZ1bmN0aW9uIGNSZXZlcnQoeCkgeyByZXR1cm4geDsgfVxuZnVuY3Rpb24gY1JlZHVjZSh4KSB7IHguZGl2UmVtVG8odGhpcy5tLG51bGwseCk7IH1cbmZ1bmN0aW9uIGNNdWxUbyh4LHkscikgeyB4Lm11bHRpcGx5VG8oeSxyKTsgdGhpcy5yZWR1Y2Uocik7IH1cbmZ1bmN0aW9uIGNTcXJUbyh4LHIpIHsgeC5zcXVhcmVUbyhyKTsgdGhpcy5yZWR1Y2Uocik7IH1cblxuQ2xhc3NpYy5wcm90b3R5cGUuY29udmVydCA9IGNDb252ZXJ0O1xuQ2xhc3NpYy5wcm90b3R5cGUucmV2ZXJ0ID0gY1JldmVydDtcbkNsYXNzaWMucHJvdG90eXBlLnJlZHVjZSA9IGNSZWR1Y2U7XG5DbGFzc2ljLnByb3RvdHlwZS5tdWxUbyA9IGNNdWxUbztcbkNsYXNzaWMucHJvdG90eXBlLnNxclRvID0gY1NxclRvO1xuXG4vLyAocHJvdGVjdGVkKSByZXR1cm4gXCItMS90aGlzICUgMl5EQlwiOyB1c2VmdWwgZm9yIE1vbnQuIHJlZHVjdGlvblxuLy8ganVzdGlmaWNhdGlvbjpcbi8vICAgICAgICAgeHkgPT0gMSAobW9kIG0pXG4vLyAgICAgICAgIHh5ID0gIDEra21cbi8vICAgeHkoMi14eSkgPSAoMStrbSkoMS1rbSlcbi8vIHhbeSgyLXh5KV0gPSAxLWteMm1eMlxuLy8geFt5KDIteHkpXSA9PSAxIChtb2QgbV4yKVxuLy8gaWYgeSBpcyAxL3ggbW9kIG0sIHRoZW4geSgyLXh5KSBpcyAxL3ggbW9kIG1eMlxuLy8gc2hvdWxkIHJlZHVjZSB4IGFuZCB5KDIteHkpIGJ5IG1eMiBhdCBlYWNoIHN0ZXAgdG8ga2VlcCBzaXplIGJvdW5kZWQuXG4vLyBKUyBtdWx0aXBseSBcIm92ZXJmbG93c1wiIGRpZmZlcmVudGx5IGZyb20gQy9DKyssIHNvIGNhcmUgaXMgbmVlZGVkIGhlcmUuXG5mdW5jdGlvbiBibnBJbnZEaWdpdCgpIHtcbiAgaWYodGhpcy50IDwgMSkgcmV0dXJuIDA7XG4gIHZhciB4ID0gdGhpc1swXTtcbiAgaWYoKHgmMSkgPT0gMCkgcmV0dXJuIDA7XG4gIHZhciB5ID0geCYzO1x0XHQvLyB5ID09IDEveCBtb2QgMl4yXG4gIHkgPSAoeSooMi0oeCYweGYpKnkpKSYweGY7XHQvLyB5ID09IDEveCBtb2QgMl40XG4gIHkgPSAoeSooMi0oeCYweGZmKSp5KSkmMHhmZjtcdC8vIHkgPT0gMS94IG1vZCAyXjhcbiAgeSA9ICh5KigyLSgoKHgmMHhmZmZmKSp5KSYweGZmZmYpKSkmMHhmZmZmO1x0Ly8geSA9PSAxL3ggbW9kIDJeMTZcbiAgLy8gbGFzdCBzdGVwIC0gY2FsY3VsYXRlIGludmVyc2UgbW9kIERWIGRpcmVjdGx5O1xuICAvLyBhc3N1bWVzIDE2IDwgREIgPD0gMzIgYW5kIGFzc3VtZXMgYWJpbGl0eSB0byBoYW5kbGUgNDgtYml0IGludHNcbiAgeSA9ICh5KigyLXgqeSV0aGlzLkRWKSkldGhpcy5EVjtcdFx0Ly8geSA9PSAxL3ggbW9kIDJeZGJpdHNcbiAgLy8gd2UgcmVhbGx5IHdhbnQgdGhlIG5lZ2F0aXZlIGludmVyc2UsIGFuZCAtRFYgPCB5IDwgRFZcbiAgcmV0dXJuICh5PjApP3RoaXMuRFYteToteTtcbn1cblxuLy8gTW9udGdvbWVyeSByZWR1Y3Rpb25cbmZ1bmN0aW9uIE1vbnRnb21lcnkobSkge1xuICB0aGlzLm0gPSBtO1xuICB0aGlzLm1wID0gbS5pbnZEaWdpdCgpO1xuICB0aGlzLm1wbCA9IHRoaXMubXAmMHg3ZmZmO1xuICB0aGlzLm1waCA9IHRoaXMubXA+PjE1O1xuICB0aGlzLnVtID0gKDE8PChtLkRCLTE1KSktMTtcbiAgdGhpcy5tdDIgPSAyKm0udDtcbn1cblxuLy8geFIgbW9kIG1cbmZ1bmN0aW9uIG1vbnRDb252ZXJ0KHgpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgeC5hYnMoKS5kbFNoaWZ0VG8odGhpcy5tLnQscik7XG4gIHIuZGl2UmVtVG8odGhpcy5tLG51bGwscik7XG4gIGlmKHgucyA8IDAgJiYgci5jb21wYXJlVG8oQmlnSW50ZWdlci5aRVJPKSA+IDApIHRoaXMubS5zdWJUbyhyLHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8geC9SIG1vZCBtXG5mdW5jdGlvbiBtb250UmV2ZXJ0KHgpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgeC5jb3B5VG8ocik7XG4gIHRoaXMucmVkdWNlKHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8geCA9IHgvUiBtb2QgbSAoSEFDIDE0LjMyKVxuZnVuY3Rpb24gbW9udFJlZHVjZSh4KSB7XG4gIHdoaWxlKHgudCA8PSB0aGlzLm10MilcdC8vIHBhZCB4IHNvIGFtIGhhcyBlbm91Z2ggcm9vbSBsYXRlclxuICAgIHhbeC50KytdID0gMDtcbiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMubS50OyArK2kpIHtcbiAgICAvLyBmYXN0ZXIgd2F5IG9mIGNhbGN1bGF0aW5nIHUwID0geFtpXSptcCBtb2QgRFZcbiAgICB2YXIgaiA9IHhbaV0mMHg3ZmZmO1xuICAgIHZhciB1MCA9IChqKnRoaXMubXBsKygoKGoqdGhpcy5tcGgrKHhbaV0+PjE1KSp0aGlzLm1wbCkmdGhpcy51bSk8PDE1KSkmeC5ETTtcbiAgICAvLyB1c2UgYW0gdG8gY29tYmluZSB0aGUgbXVsdGlwbHktc2hpZnQtYWRkIGludG8gb25lIGNhbGxcbiAgICBqID0gaSt0aGlzLm0udDtcbiAgICB4W2pdICs9IHRoaXMubS5hbSgwLHUwLHgsaSwwLHRoaXMubS50KTtcbiAgICAvLyBwcm9wYWdhdGUgY2FycnlcbiAgICB3aGlsZSh4W2pdID49IHguRFYpIHsgeFtqXSAtPSB4LkRWOyB4Wysral0rKzsgfVxuICB9XG4gIHguY2xhbXAoKTtcbiAgeC5kclNoaWZ0VG8odGhpcy5tLnQseCk7XG4gIGlmKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0seCk7XG59XG5cbi8vIHIgPSBcInheMi9SIG1vZCBtXCI7IHggIT0gclxuZnVuY3Rpb24gbW9udFNxclRvKHgscikgeyB4LnNxdWFyZVRvKHIpOyB0aGlzLnJlZHVjZShyKTsgfVxuXG4vLyByID0gXCJ4eS9SIG1vZCBtXCI7IHgseSAhPSByXG5mdW5jdGlvbiBtb250TXVsVG8oeCx5LHIpIHsgeC5tdWx0aXBseVRvKHkscik7IHRoaXMucmVkdWNlKHIpOyB9XG5cbk1vbnRnb21lcnkucHJvdG90eXBlLmNvbnZlcnQgPSBtb250Q29udmVydDtcbk1vbnRnb21lcnkucHJvdG90eXBlLnJldmVydCA9IG1vbnRSZXZlcnQ7XG5Nb250Z29tZXJ5LnByb3RvdHlwZS5yZWR1Y2UgPSBtb250UmVkdWNlO1xuTW9udGdvbWVyeS5wcm90b3R5cGUubXVsVG8gPSBtb250TXVsVG87XG5Nb250Z29tZXJ5LnByb3RvdHlwZS5zcXJUbyA9IG1vbnRTcXJUbztcblxuLy8gKHByb3RlY3RlZCkgdHJ1ZSBpZmYgdGhpcyBpcyBldmVuXG5mdW5jdGlvbiBibnBJc0V2ZW4oKSB7IHJldHVybiAoKHRoaXMudD4wKT8odGhpc1swXSYxKTp0aGlzLnMpID09IDA7IH1cblxuLy8gKHByb3RlY3RlZCkgdGhpc15lLCBlIDwgMl4zMiwgZG9pbmcgc3FyIGFuZCBtdWwgd2l0aCBcInJcIiAoSEFDIDE0Ljc5KVxuZnVuY3Rpb24gYm5wRXhwKGUseikge1xuICBpZihlID4gMHhmZmZmZmZmZiB8fCBlIDwgMSkgcmV0dXJuIEJpZ0ludGVnZXIuT05FO1xuICB2YXIgciA9IG5iaSgpLCByMiA9IG5iaSgpLCBnID0gei5jb252ZXJ0KHRoaXMpLCBpID0gbmJpdHMoZSktMTtcbiAgZy5jb3B5VG8ocik7XG4gIHdoaWxlKC0taSA+PSAwKSB7XG4gICAgei5zcXJUbyhyLHIyKTtcbiAgICBpZigoZSYoMTw8aSkpID4gMCkgei5tdWxUbyhyMixnLHIpO1xuICAgIGVsc2UgeyB2YXIgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9XG4gIH1cbiAgcmV0dXJuIHoucmV2ZXJ0KHIpO1xufVxuXG4vLyAocHVibGljKSB0aGlzXmUgJSBtLCAwIDw9IGUgPCAyXjMyXG5mdW5jdGlvbiBibk1vZFBvd0ludChlLG0pIHtcbiAgdmFyIHo7XG4gIGlmKGUgPCAyNTYgfHwgbS5pc0V2ZW4oKSkgeiA9IG5ldyBDbGFzc2ljKG0pOyBlbHNlIHogPSBuZXcgTW9udGdvbWVyeShtKTtcbiAgcmV0dXJuIHRoaXMuZXhwKGUseik7XG59XG5cbi8vIHByb3RlY3RlZFxuQmlnSW50ZWdlci5wcm90b3R5cGUuY29weVRvID0gYm5wQ29weVRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbUludCA9IGJucEZyb21JbnQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tU3RyaW5nID0gYm5wRnJvbVN0cmluZztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNsYW1wID0gYm5wQ2xhbXA7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kbFNoaWZ0VG8gPSBibnBETFNoaWZ0VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kclNoaWZ0VG8gPSBibnBEUlNoaWZ0VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5sU2hpZnRUbyA9IGJucExTaGlmdFRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuclNoaWZ0VG8gPSBibnBSU2hpZnRUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLnN1YlRvID0gYm5wU3ViVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseVRvID0gYm5wTXVsdGlwbHlUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNxdWFyZVRvID0gYm5wU3F1YXJlVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZSZW1UbyA9IGJucERpdlJlbVRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuaW52RGlnaXQgPSBibnBJbnZEaWdpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmlzRXZlbiA9IGJucElzRXZlbjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmV4cCA9IGJucEV4cDtcblxuLy8gcHVibGljXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b1N0cmluZyA9IGJuVG9TdHJpbmc7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5uZWdhdGUgPSBibk5lZ2F0ZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmFicyA9IGJuQWJzO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuY29tcGFyZVRvID0gYm5Db21wYXJlVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXRMZW5ndGggPSBibkJpdExlbmd0aDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZCA9IGJuTW9kO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93SW50ID0gYm5Nb2RQb3dJbnQ7XG5cbi8vIFwiY29uc3RhbnRzXCJcbkJpZ0ludGVnZXIuWkVSTyA9IG5idigwKTtcbkJpZ0ludGVnZXIuT05FID0gbmJ2KDEpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEJpZ0ludGVnZXI7XG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cbi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMDMtMjAwNSAgVG9tIFd1ICh0andAY3MuU3RhbmZvcmQuRURVKSBcbiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIXG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nXG4gKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbiAqIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuICogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvXG4gKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG9cbiAqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZVxuICogaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMtSVNcIiBBTkQgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgXG4gKiBFWFBSRVNTLCBJTVBMSUVEIE9SIE9USEVSV0lTRSwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiwgQU5ZIFxuICogV0FSUkFOVFkgT0YgTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgXG4gKlxuICogSU4gTk8gRVZFTlQgU0hBTEwgVE9NIFdVIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElOQ0lERU5UQUwsXG4gKiBJTkRJUkVDVCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT0YgQU5ZIEtJTkQsIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVJcbiAqIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgT1IgTk9UIEFEVklTRUQgT0ZcbiAqIFRIRSBQT1NTSUJJTElUWSBPRiBEQU1BR0UsIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgQVJJU0lORyBPVVRcbiAqIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXG4gKlxuICogSW4gYWRkaXRpb24sIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uIGFwcGxpZXM6XG4gKlxuICogQWxsIHJlZGlzdHJpYnV0aW9ucyBtdXN0IHJldGFpbiBhbiBpbnRhY3QgY29weSBvZiB0aGlzIGNvcHlyaWdodCBub3RpY2VcbiAqIGFuZCBkaXNjbGFpbWVyLlxuICovXG5cblxuLy8gRXh0ZW5kZWQgSmF2YVNjcmlwdCBCTiBmdW5jdGlvbnMsIHJlcXVpcmVkIGZvciBSU0EgcHJpdmF0ZSBvcHMuXG5cbi8vIFZlcnNpb24gMS4xOiBuZXcgQmlnSW50ZWdlcihcIjBcIiwgMTApIHJldHVybnMgXCJwcm9wZXJcIiB6ZXJvXG4vLyBWZXJzaW9uIDEuMjogc3F1YXJlKCkgQVBJLCBpc1Byb2JhYmxlUHJpbWUgZml4XG5cbi8vIChwdWJsaWMpXG5mdW5jdGlvbiBibkNsb25lKCkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmNvcHlUbyhyKTsgcmV0dXJuIHI7IH1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGludGVnZXJcbmZ1bmN0aW9uIGJuSW50VmFsdWUoKSB7XG4gIGlmKHRoaXMucyA8IDApIHtcbiAgICBpZih0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXNbMF0tdGhpcy5EVjtcbiAgICBlbHNlIGlmKHRoaXMudCA9PSAwKSByZXR1cm4gLTE7XG4gIH1cbiAgZWxzZSBpZih0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXNbMF07XG4gIGVsc2UgaWYodGhpcy50ID09IDApIHJldHVybiAwO1xuICAvLyBhc3N1bWVzIDE2IDwgREIgPCAzMlxuICByZXR1cm4gKCh0aGlzWzFdJigoMTw8KDMyLXRoaXMuREIpKS0xKSk8PHRoaXMuREIpfHRoaXNbMF07XG59XG5cbi8vIChwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBieXRlXG5mdW5jdGlvbiBibkJ5dGVWYWx1ZSgpIHsgcmV0dXJuICh0aGlzLnQ9PTApP3RoaXMuczoodGhpc1swXTw8MjQpPj4yNDsgfVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgc2hvcnQgKGFzc3VtZXMgREI+PTE2KVxuZnVuY3Rpb24gYm5TaG9ydFZhbHVlKCkgeyByZXR1cm4gKHRoaXMudD09MCk/dGhpcy5zOih0aGlzWzBdPDwxNik+PjE2OyB9XG5cbi8vIChwcm90ZWN0ZWQpIHJldHVybiB4IHMudC4gcl54IDwgRFZcbmZ1bmN0aW9uIGJucENodW5rU2l6ZShyKSB7IHJldHVybiBNYXRoLmZsb29yKE1hdGguTE4yKnRoaXMuREIvTWF0aC5sb2cocikpOyB9XG5cbi8vIChwdWJsaWMpIDAgaWYgdGhpcyA9PSAwLCAxIGlmIHRoaXMgPiAwXG5mdW5jdGlvbiBiblNpZ051bSgpIHtcbiAgaWYodGhpcy5zIDwgMCkgcmV0dXJuIC0xO1xuICBlbHNlIGlmKHRoaXMudCA8PSAwIHx8ICh0aGlzLnQgPT0gMSAmJiB0aGlzWzBdIDw9IDApKSByZXR1cm4gMDtcbiAgZWxzZSByZXR1cm4gMTtcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCB0byByYWRpeCBzdHJpbmdcbmZ1bmN0aW9uIGJucFRvUmFkaXgoYikge1xuICBpZihiID09IG51bGwpIGIgPSAxMDtcbiAgaWYodGhpcy5zaWdudW0oKSA9PSAwIHx8IGIgPCAyIHx8IGIgPiAzNikgcmV0dXJuIFwiMFwiO1xuICB2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKTtcbiAgdmFyIGEgPSBNYXRoLnBvdyhiLGNzKTtcbiAgdmFyIGQgPSBuYnYoYSksIHkgPSBuYmkoKSwgeiA9IG5iaSgpLCByID0gXCJcIjtcbiAgdGhpcy5kaXZSZW1UbyhkLHkseik7XG4gIHdoaWxlKHkuc2lnbnVtKCkgPiAwKSB7XG4gICAgciA9IChhK3ouaW50VmFsdWUoKSkudG9TdHJpbmcoYikuc3Vic3RyKDEpICsgcjtcbiAgICB5LmRpdlJlbVRvKGQseSx6KTtcbiAgfVxuICByZXR1cm4gei5pbnRWYWx1ZSgpLnRvU3RyaW5nKGIpICsgcjtcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCBmcm9tIHJhZGl4IHN0cmluZ1xuZnVuY3Rpb24gYm5wRnJvbVJhZGl4KHMsYikge1xuICB0aGlzLmZyb21JbnQoMCk7XG4gIGlmKGIgPT0gbnVsbCkgYiA9IDEwO1xuICB2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKTtcbiAgdmFyIGQgPSBNYXRoLnBvdyhiLGNzKSwgbWkgPSBmYWxzZSwgaiA9IDAsIHcgPSAwO1xuICBmb3IodmFyIGkgPSAwOyBpIDwgcy5sZW5ndGg7ICsraSkge1xuICAgIHZhciB4ID0gaW50QXQocyxpKTtcbiAgICBpZih4IDwgMCkge1xuICAgICAgaWYocy5jaGFyQXQoaSkgPT0gXCItXCIgJiYgdGhpcy5zaWdudW0oKSA9PSAwKSBtaSA9IHRydWU7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdyA9IGIqdyt4O1xuICAgIGlmKCsraiA+PSBjcykge1xuICAgICAgdGhpcy5kTXVsdGlwbHkoZCk7XG4gICAgICB0aGlzLmRBZGRPZmZzZXQodywwKTtcbiAgICAgIGogPSAwO1xuICAgICAgdyA9IDA7XG4gICAgfVxuICB9XG4gIGlmKGogPiAwKSB7XG4gICAgdGhpcy5kTXVsdGlwbHkoTWF0aC5wb3coYixqKSk7XG4gICAgdGhpcy5kQWRkT2Zmc2V0KHcsMCk7XG4gIH1cbiAgaWYobWkpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHRoaXMpO1xufVxuXG4vLyAocHJvdGVjdGVkKSBhbHRlcm5hdGUgY29uc3RydWN0b3JcbmZ1bmN0aW9uIGJucEZyb21OdW1iZXIoYSxiLGMpIHtcbiAgaWYoXCJudW1iZXJcIiA9PSB0eXBlb2YgYikge1xuICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxpbnQsUk5HKVxuICAgIGlmKGEgPCAyKSB0aGlzLmZyb21JbnQoMSk7XG4gICAgZWxzZSB7XG4gICAgICB0aGlzLmZyb21OdW1iZXIoYSxjKTtcbiAgICAgIGlmKCF0aGlzLnRlc3RCaXQoYS0xKSlcdC8vIGZvcmNlIE1TQiBzZXRcbiAgICAgICAgdGhpcy5iaXR3aXNlVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGEtMSksb3Bfb3IsdGhpcyk7XG4gICAgICBpZih0aGlzLmlzRXZlbigpKSB0aGlzLmRBZGRPZmZzZXQoMSwwKTsgLy8gZm9yY2Ugb2RkXG4gICAgICB3aGlsZSghdGhpcy5pc1Byb2JhYmxlUHJpbWUoYikpIHtcbiAgICAgICAgdGhpcy5kQWRkT2Zmc2V0KDIsMCk7XG4gICAgICAgIGlmKHRoaXMuYml0TGVuZ3RoKCkgPiBhKSB0aGlzLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhLTEpLHRoaXMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICAvLyBuZXcgQmlnSW50ZWdlcihpbnQsUk5HKVxuICAgIHZhciB4ID0gbmV3IEFycmF5KCksIHQgPSBhJjc7XG4gICAgeC5sZW5ndGggPSAoYT4+MykrMTtcbiAgICBiLm5leHRCeXRlcyh4KTtcbiAgICBpZih0ID4gMCkgeFswXSAmPSAoKDE8PHQpLTEpOyBlbHNlIHhbMF0gPSAwO1xuICAgIHRoaXMuZnJvbVN0cmluZyh4LDI1Nik7XG4gIH1cbn1cblxuLy8gKHB1YmxpYykgY29udmVydCB0byBiaWdlbmRpYW4gYnl0ZSBhcnJheVxuZnVuY3Rpb24gYm5Ub0J5dGVBcnJheSgpIHtcbiAgdmFyIGkgPSB0aGlzLnQsIHIgPSBuZXcgQXJyYXkoKTtcbiAgclswXSA9IHRoaXMucztcbiAgdmFyIHAgPSB0aGlzLkRCLShpKnRoaXMuREIpJTgsIGQsIGsgPSAwO1xuICBpZihpLS0gPiAwKSB7XG4gICAgaWYocCA8IHRoaXMuREIgJiYgKGQgPSB0aGlzW2ldPj5wKSAhPSAodGhpcy5zJnRoaXMuRE0pPj5wKVxuICAgICAgcltrKytdID0gZHwodGhpcy5zPDwodGhpcy5EQi1wKSk7XG4gICAgd2hpbGUoaSA+PSAwKSB7XG4gICAgICBpZihwIDwgOCkge1xuICAgICAgICBkID0gKHRoaXNbaV0mKCgxPDxwKS0xKSk8PCg4LXApO1xuICAgICAgICBkIHw9IHRoaXNbLS1pXT4+KHArPXRoaXMuREItOCk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgZCA9ICh0aGlzW2ldPj4ocC09OCkpJjB4ZmY7XG4gICAgICAgIGlmKHAgPD0gMCkgeyBwICs9IHRoaXMuREI7IC0taTsgfVxuICAgICAgfVxuICAgICAgLy9pZigoZCYweDgwKSAhPSAwKSBkIHw9IC0yNTY7XG4gICAgICAvL2lmKGsgPT0gMCAmJiAodGhpcy5zJjB4ODApICE9IChkJjB4ODApKSArK2s7XG4gICAgICBpZihrID4gMCB8fCBkICE9IHRoaXMucykgcltrKytdID0gZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGJuRXF1YWxzKGEpIHsgcmV0dXJuKHRoaXMuY29tcGFyZVRvKGEpPT0wKTsgfVxuZnVuY3Rpb24gYm5NaW4oYSkgeyByZXR1cm4odGhpcy5jb21wYXJlVG8oYSk8MCk/dGhpczphOyB9XG5mdW5jdGlvbiBibk1heChhKSB7IHJldHVybih0aGlzLmNvbXBhcmVUbyhhKT4wKT90aGlzOmE7IH1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgb3AgYSAoYml0d2lzZSlcbmZ1bmN0aW9uIGJucEJpdHdpc2VUbyhhLG9wLHIpIHtcbiAgdmFyIGksIGYsIG0gPSBNYXRoLm1pbihhLnQsdGhpcy50KTtcbiAgZm9yKGkgPSAwOyBpIDwgbTsgKytpKSByW2ldID0gb3AodGhpc1tpXSxhW2ldKTtcbiAgaWYoYS50IDwgdGhpcy50KSB7XG4gICAgZiA9IGEucyZ0aGlzLkRNO1xuICAgIGZvcihpID0gbTsgaSA8IHRoaXMudDsgKytpKSByW2ldID0gb3AodGhpc1tpXSxmKTtcbiAgICByLnQgPSB0aGlzLnQ7XG4gIH1cbiAgZWxzZSB7XG4gICAgZiA9IHRoaXMucyZ0aGlzLkRNO1xuICAgIGZvcihpID0gbTsgaSA8IGEudDsgKytpKSByW2ldID0gb3AoZixhW2ldKTtcbiAgICByLnQgPSBhLnQ7XG4gIH1cbiAgci5zID0gb3AodGhpcy5zLGEucyk7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyAmIGFcbmZ1bmN0aW9uIG9wX2FuZCh4LHkpIHsgcmV0dXJuIHgmeTsgfVxuZnVuY3Rpb24gYm5BbmQoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmJpdHdpc2VUbyhhLG9wX2FuZCxyKTsgcmV0dXJuIHI7IH1cblxuLy8gKHB1YmxpYykgdGhpcyB8IGFcbmZ1bmN0aW9uIG9wX29yKHgseSkgeyByZXR1cm4geHx5OyB9XG5mdW5jdGlvbiBibk9yKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF9vcixyKTsgcmV0dXJuIHI7IH1cblxuLy8gKHB1YmxpYykgdGhpcyBeIGFcbmZ1bmN0aW9uIG9wX3hvcih4LHkpIHsgcmV0dXJuIHheeTsgfVxuZnVuY3Rpb24gYm5Yb3IoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmJpdHdpc2VUbyhhLG9wX3hvcixyKTsgcmV0dXJuIHI7IH1cblxuLy8gKHB1YmxpYykgdGhpcyAmIH5hXG5mdW5jdGlvbiBvcF9hbmRub3QoeCx5KSB7IHJldHVybiB4Jn55OyB9XG5mdW5jdGlvbiBibkFuZE5vdChhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuYml0d2lzZVRvKGEsb3BfYW5kbm90LHIpOyByZXR1cm4gcjsgfVxuXG4vLyAocHVibGljKSB+dGhpc1xuZnVuY3Rpb24gYm5Ob3QoKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLnQ7ICsraSkgcltpXSA9IHRoaXMuRE0mfnRoaXNbaV07XG4gIHIudCA9IHRoaXMudDtcbiAgci5zID0gfnRoaXMucztcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgPDwgblxuZnVuY3Rpb24gYm5TaGlmdExlZnQobikge1xuICB2YXIgciA9IG5iaSgpO1xuICBpZihuIDwgMCkgdGhpcy5yU2hpZnRUbygtbixyKTsgZWxzZSB0aGlzLmxTaGlmdFRvKG4scik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzID4+IG5cbmZ1bmN0aW9uIGJuU2hpZnRSaWdodChuKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIGlmKG4gPCAwKSB0aGlzLmxTaGlmdFRvKC1uLHIpOyBlbHNlIHRoaXMuclNoaWZ0VG8obixyKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIHJldHVybiBpbmRleCBvZiBsb3dlc3QgMS1iaXQgaW4geCwgeCA8IDJeMzFcbmZ1bmN0aW9uIGxiaXQoeCkge1xuICBpZih4ID09IDApIHJldHVybiAtMTtcbiAgdmFyIHIgPSAwO1xuICBpZigoeCYweGZmZmYpID09IDApIHsgeCA+Pj0gMTY7IHIgKz0gMTY7IH1cbiAgaWYoKHgmMHhmZikgPT0gMCkgeyB4ID4+PSA4OyByICs9IDg7IH1cbiAgaWYoKHgmMHhmKSA9PSAwKSB7IHggPj49IDQ7IHIgKz0gNDsgfVxuICBpZigoeCYzKSA9PSAwKSB7IHggPj49IDI7IHIgKz0gMjsgfVxuICBpZigoeCYxKSA9PSAwKSArK3I7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSByZXR1cm5zIGluZGV4IG9mIGxvd2VzdCAxLWJpdCAob3IgLTEgaWYgbm9uZSlcbmZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCkge1xuICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpXG4gICAgaWYodGhpc1tpXSAhPSAwKSByZXR1cm4gaSp0aGlzLkRCK2xiaXQodGhpc1tpXSk7XG4gIGlmKHRoaXMucyA8IDApIHJldHVybiB0aGlzLnQqdGhpcy5EQjtcbiAgcmV0dXJuIC0xO1xufVxuXG4vLyByZXR1cm4gbnVtYmVyIG9mIDEgYml0cyBpbiB4XG5mdW5jdGlvbiBjYml0KHgpIHtcbiAgdmFyIHIgPSAwO1xuICB3aGlsZSh4ICE9IDApIHsgeCAmPSB4LTE7ICsrcjsgfVxuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIG51bWJlciBvZiBzZXQgYml0c1xuZnVuY3Rpb24gYm5CaXRDb3VudCgpIHtcbiAgdmFyIHIgPSAwLCB4ID0gdGhpcy5zJnRoaXMuRE07XG4gIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLnQ7ICsraSkgciArPSBjYml0KHRoaXNbaV1eeCk7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0cnVlIGlmZiBudGggYml0IGlzIHNldFxuZnVuY3Rpb24gYm5UZXN0Qml0KG4pIHtcbiAgdmFyIGogPSBNYXRoLmZsb29yKG4vdGhpcy5EQik7XG4gIGlmKGogPj0gdGhpcy50KSByZXR1cm4odGhpcy5zIT0wKTtcbiAgcmV0dXJuKCh0aGlzW2pdJigxPDwobiV0aGlzLkRCKSkpIT0wKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyBvcCAoMTw8bilcbmZ1bmN0aW9uIGJucENoYW5nZUJpdChuLG9wKSB7XG4gIHZhciByID0gQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KG4pO1xuICB0aGlzLmJpdHdpc2VUbyhyLG9wLHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyB8ICgxPDxuKVxuZnVuY3Rpb24gYm5TZXRCaXQobikgeyByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobixvcF9vcik7IH1cblxuLy8gKHB1YmxpYykgdGhpcyAmIH4oMTw8bilcbmZ1bmN0aW9uIGJuQ2xlYXJCaXQobikgeyByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobixvcF9hbmRub3QpOyB9XG5cbi8vIChwdWJsaWMpIHRoaXMgXiAoMTw8bilcbmZ1bmN0aW9uIGJuRmxpcEJpdChuKSB7IHJldHVybiB0aGlzLmNoYW5nZUJpdChuLG9wX3hvcik7IH1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgKyBhXG5mdW5jdGlvbiBibnBBZGRUbyhhLHIpIHtcbiAgdmFyIGkgPSAwLCBjID0gMCwgbSA9IE1hdGgubWluKGEudCx0aGlzLnQpO1xuICB3aGlsZShpIDwgbSkge1xuICAgIGMgKz0gdGhpc1tpXSthW2ldO1xuICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICBjID4+PSB0aGlzLkRCO1xuICB9XG4gIGlmKGEudCA8IHRoaXMudCkge1xuICAgIGMgKz0gYS5zO1xuICAgIHdoaWxlKGkgPCB0aGlzLnQpIHtcbiAgICAgIGMgKz0gdGhpc1tpXTtcbiAgICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgKz0gdGhpcy5zO1xuICB9XG4gIGVsc2Uge1xuICAgIGMgKz0gdGhpcy5zO1xuICAgIHdoaWxlKGkgPCBhLnQpIHtcbiAgICAgIGMgKz0gYVtpXTtcbiAgICAgIHJbaSsrXSA9IGMmdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgKz0gYS5zO1xuICB9XG4gIHIucyA9IChjPDApPy0xOjA7XG4gIGlmKGMgPiAwKSByW2krK10gPSBjO1xuICBlbHNlIGlmKGMgPCAtMSkgcltpKytdID0gdGhpcy5EVitjO1xuICByLnQgPSBpO1xuICByLmNsYW1wKCk7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgKyBhXG5mdW5jdGlvbiBibkFkZChhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuYWRkVG8oYSxyKTsgcmV0dXJuIHI7IH1cblxuLy8gKHB1YmxpYykgdGhpcyAtIGFcbmZ1bmN0aW9uIGJuU3VidHJhY3QoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLnN1YlRvKGEscik7IHJldHVybiByOyB9XG5cbi8vIChwdWJsaWMpIHRoaXMgKiBhXG5mdW5jdGlvbiBibk11bHRpcGx5KGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5tdWx0aXBseVRvKGEscik7IHJldHVybiByOyB9XG5cbi8vIChwdWJsaWMpIHRoaXNeMlxuZnVuY3Rpb24gYm5TcXVhcmUoKSB7IHZhciByID0gbmJpKCk7IHRoaXMuc3F1YXJlVG8ocik7IHJldHVybiByOyB9XG5cbi8vIChwdWJsaWMpIHRoaXMgLyBhXG5mdW5jdGlvbiBibkRpdmlkZShhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuZGl2UmVtVG8oYSxyLG51bGwpOyByZXR1cm4gcjsgfVxuXG4vLyAocHVibGljKSB0aGlzICUgYVxuZnVuY3Rpb24gYm5SZW1haW5kZXIoYSkgeyB2YXIgciA9IG5iaSgpOyB0aGlzLmRpdlJlbVRvKGEsbnVsbCxyKTsgcmV0dXJuIHI7IH1cblxuLy8gKHB1YmxpYykgW3RoaXMvYSx0aGlzJWFdXG5mdW5jdGlvbiBibkRpdmlkZUFuZFJlbWFpbmRlcihhKSB7XG4gIHZhciBxID0gbmJpKCksIHIgPSBuYmkoKTtcbiAgdGhpcy5kaXZSZW1UbyhhLHEscik7XG4gIHJldHVybiBuZXcgQXJyYXkocSxyKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyAqPSBuLCB0aGlzID49IDAsIDEgPCBuIDwgRFZcbmZ1bmN0aW9uIGJucERNdWx0aXBseShuKSB7XG4gIHRoaXNbdGhpcy50XSA9IHRoaXMuYW0oMCxuLTEsdGhpcywwLDAsdGhpcy50KTtcbiAgKyt0aGlzLnQ7XG4gIHRoaXMuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyArPSBuIDw8IHcgd29yZHMsIHRoaXMgPj0gMFxuZnVuY3Rpb24gYm5wREFkZE9mZnNldChuLHcpIHtcbiAgaWYobiA9PSAwKSByZXR1cm47XG4gIHdoaWxlKHRoaXMudCA8PSB3KSB0aGlzW3RoaXMudCsrXSA9IDA7XG4gIHRoaXNbd10gKz0gbjtcbiAgd2hpbGUodGhpc1t3XSA+PSB0aGlzLkRWKSB7XG4gICAgdGhpc1t3XSAtPSB0aGlzLkRWO1xuICAgIGlmKCsrdyA+PSB0aGlzLnQpIHRoaXNbdGhpcy50KytdID0gMDtcbiAgICArK3RoaXNbd107XG4gIH1cbn1cblxuLy8gQSBcIm51bGxcIiByZWR1Y2VyXG5mdW5jdGlvbiBOdWxsRXhwKCkge31cbmZ1bmN0aW9uIG5Ob3AoeCkgeyByZXR1cm4geDsgfVxuZnVuY3Rpb24gbk11bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB9XG5mdW5jdGlvbiBuU3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IH1cblxuTnVsbEV4cC5wcm90b3R5cGUuY29udmVydCA9IG5Ob3A7XG5OdWxsRXhwLnByb3RvdHlwZS5yZXZlcnQgPSBuTm9wO1xuTnVsbEV4cC5wcm90b3R5cGUubXVsVG8gPSBuTXVsVG87XG5OdWxsRXhwLnByb3RvdHlwZS5zcXJUbyA9IG5TcXJUbztcblxuLy8gKHB1YmxpYykgdGhpc15lXG5mdW5jdGlvbiBiblBvdyhlKSB7IHJldHVybiB0aGlzLmV4cChlLG5ldyBOdWxsRXhwKCkpOyB9XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSBsb3dlciBuIHdvcmRzIG9mIFwidGhpcyAqIGFcIiwgYS50IDw9IG5cbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cbmZ1bmN0aW9uIGJucE11bHRpcGx5TG93ZXJUbyhhLG4scikge1xuICB2YXIgaSA9IE1hdGgubWluKHRoaXMudCthLnQsbik7XG4gIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDBcbiAgci50ID0gaTtcbiAgd2hpbGUoaSA+IDApIHJbLS1pXSA9IDA7XG4gIHZhciBqO1xuICBmb3IoaiA9IHIudC10aGlzLnQ7IGkgPCBqOyArK2kpIHJbaSt0aGlzLnRdID0gdGhpcy5hbSgwLGFbaV0scixpLDAsdGhpcy50KTtcbiAgZm9yKGogPSBNYXRoLm1pbihhLnQsbik7IGkgPCBqOyArK2kpIHRoaXMuYW0oMCxhW2ldLHIsaSwwLG4taSk7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IFwidGhpcyAqIGFcIiB3aXRob3V0IGxvd2VyIG4gd29yZHMsIG4gPiAwXG4vLyBcInRoaXNcIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuXG5mdW5jdGlvbiBibnBNdWx0aXBseVVwcGVyVG8oYSxuLHIpIHtcbiAgLS1uO1xuICB2YXIgaSA9IHIudCA9IHRoaXMudCthLnQtbjtcbiAgci5zID0gMDsgLy8gYXNzdW1lcyBhLHRoaXMgPj0gMFxuICB3aGlsZSgtLWkgPj0gMCkgcltpXSA9IDA7XG4gIGZvcihpID0gTWF0aC5tYXgobi10aGlzLnQsMCk7IGkgPCBhLnQ7ICsraSlcbiAgICByW3RoaXMudCtpLW5dID0gdGhpcy5hbShuLWksYVtpXSxyLDAsMCx0aGlzLnQraS1uKTtcbiAgci5jbGFtcCgpO1xuICByLmRyU2hpZnRUbygxLHIpO1xufVxuXG4vLyBCYXJyZXR0IG1vZHVsYXIgcmVkdWN0aW9uXG5mdW5jdGlvbiBCYXJyZXR0KG0pIHtcbiAgLy8gc2V0dXAgQmFycmV0dFxuICB0aGlzLnIyID0gbmJpKCk7XG4gIHRoaXMucTMgPSBuYmkoKTtcbiAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKDIqbS50LHRoaXMucjIpO1xuICB0aGlzLm11ID0gdGhpcy5yMi5kaXZpZGUobSk7XG4gIHRoaXMubSA9IG07XG59XG5cbmZ1bmN0aW9uIGJhcnJldHRDb252ZXJ0KHgpIHtcbiAgaWYoeC5zIDwgMCB8fCB4LnQgPiAyKnRoaXMubS50KSByZXR1cm4geC5tb2QodGhpcy5tKTtcbiAgZWxzZSBpZih4LmNvbXBhcmVUbyh0aGlzLm0pIDwgMCkgcmV0dXJuIHg7XG4gIGVsc2UgeyB2YXIgciA9IG5iaSgpOyB4LmNvcHlUbyhyKTsgdGhpcy5yZWR1Y2Uocik7IHJldHVybiByOyB9XG59XG5cbmZ1bmN0aW9uIGJhcnJldHRSZXZlcnQoeCkgeyByZXR1cm4geDsgfVxuXG4vLyB4ID0geCBtb2QgbSAoSEFDIDE0LjQyKVxuZnVuY3Rpb24gYmFycmV0dFJlZHVjZSh4KSB7XG4gIHguZHJTaGlmdFRvKHRoaXMubS50LTEsdGhpcy5yMik7XG4gIGlmKHgudCA+IHRoaXMubS50KzEpIHsgeC50ID0gdGhpcy5tLnQrMTsgeC5jbGFtcCgpOyB9XG4gIHRoaXMubXUubXVsdGlwbHlVcHBlclRvKHRoaXMucjIsdGhpcy5tLnQrMSx0aGlzLnEzKTtcbiAgdGhpcy5tLm11bHRpcGx5TG93ZXJUbyh0aGlzLnEzLHRoaXMubS50KzEsdGhpcy5yMik7XG4gIHdoaWxlKHguY29tcGFyZVRvKHRoaXMucjIpIDwgMCkgeC5kQWRkT2Zmc2V0KDEsdGhpcy5tLnQrMSk7XG4gIHguc3ViVG8odGhpcy5yMix4KTtcbiAgd2hpbGUoeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSB4LnN1YlRvKHRoaXMubSx4KTtcbn1cblxuLy8gciA9IHheMiBtb2QgbTsgeCAhPSByXG5mdW5jdGlvbiBiYXJyZXR0U3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IHRoaXMucmVkdWNlKHIpOyB9XG5cbi8vIHIgPSB4KnkgbW9kIG07IHgseSAhPSByXG5mdW5jdGlvbiBiYXJyZXR0TXVsVG8oeCx5LHIpIHsgeC5tdWx0aXBseVRvKHkscik7IHRoaXMucmVkdWNlKHIpOyB9XG5cbkJhcnJldHQucHJvdG90eXBlLmNvbnZlcnQgPSBiYXJyZXR0Q29udmVydDtcbkJhcnJldHQucHJvdG90eXBlLnJldmVydCA9IGJhcnJldHRSZXZlcnQ7XG5CYXJyZXR0LnByb3RvdHlwZS5yZWR1Y2UgPSBiYXJyZXR0UmVkdWNlO1xuQmFycmV0dC5wcm90b3R5cGUubXVsVG8gPSBiYXJyZXR0TXVsVG87XG5CYXJyZXR0LnByb3RvdHlwZS5zcXJUbyA9IGJhcnJldHRTcXJUbztcblxuLy8gKHB1YmxpYykgdGhpc15lICUgbSAoSEFDIDE0Ljg1KVxuZnVuY3Rpb24gYm5Nb2RQb3coZSxtKSB7XG4gIHZhciBpID0gZS5iaXRMZW5ndGgoKSwgaywgciA9IG5idigxKSwgejtcbiAgaWYoaSA8PSAwKSByZXR1cm4gcjtcbiAgZWxzZSBpZihpIDwgMTgpIGsgPSAxO1xuICBlbHNlIGlmKGkgPCA0OCkgayA9IDM7XG4gIGVsc2UgaWYoaSA8IDE0NCkgayA9IDQ7XG4gIGVsc2UgaWYoaSA8IDc2OCkgayA9IDU7XG4gIGVsc2UgayA9IDY7XG4gIGlmKGkgPCA4KVxuICAgIHogPSBuZXcgQ2xhc3NpYyhtKTtcbiAgZWxzZSBpZihtLmlzRXZlbigpKVxuICAgIHogPSBuZXcgQmFycmV0dChtKTtcbiAgZWxzZVxuICAgIHogPSBuZXcgTW9udGdvbWVyeShtKTtcblxuICAvLyBwcmVjb21wdXRhdGlvblxuICB2YXIgZyA9IG5ldyBBcnJheSgpLCBuID0gMywgazEgPSBrLTEsIGttID0gKDE8PGspLTE7XG4gIGdbMV0gPSB6LmNvbnZlcnQodGhpcyk7XG4gIGlmKGsgPiAxKSB7XG4gICAgdmFyIGcyID0gbmJpKCk7XG4gICAgei5zcXJUbyhnWzFdLGcyKTtcbiAgICB3aGlsZShuIDw9IGttKSB7XG4gICAgICBnW25dID0gbmJpKCk7XG4gICAgICB6Lm11bFRvKGcyLGdbbi0yXSxnW25dKTtcbiAgICAgIG4gKz0gMjtcbiAgICB9XG4gIH1cblxuICB2YXIgaiA9IGUudC0xLCB3LCBpczEgPSB0cnVlLCByMiA9IG5iaSgpLCB0O1xuICBpID0gbmJpdHMoZVtqXSktMTtcbiAgd2hpbGUoaiA+PSAwKSB7XG4gICAgaWYoaSA+PSBrMSkgdyA9IChlW2pdPj4oaS1rMSkpJmttO1xuICAgIGVsc2Uge1xuICAgICAgdyA9IChlW2pdJigoMTw8KGkrMSkpLTEpKTw8KGsxLWkpO1xuICAgICAgaWYoaiA+IDApIHcgfD0gZVtqLTFdPj4odGhpcy5EQitpLWsxKTtcbiAgICB9XG5cbiAgICBuID0gaztcbiAgICB3aGlsZSgodyYxKSA9PSAwKSB7IHcgPj49IDE7IC0tbjsgfVxuICAgIGlmKChpIC09IG4pIDwgMCkgeyBpICs9IHRoaXMuREI7IC0tajsgfVxuICAgIGlmKGlzMSkge1x0Ly8gcmV0ID09IDEsIGRvbid0IGJvdGhlciBzcXVhcmluZyBvciBtdWx0aXBseWluZyBpdFxuICAgICAgZ1t3XS5jb3B5VG8ocik7XG4gICAgICBpczEgPSBmYWxzZTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB3aGlsZShuID4gMSkgeyB6LnNxclRvKHIscjIpOyB6LnNxclRvKHIyLHIpOyBuIC09IDI7IH1cbiAgICAgIGlmKG4gPiAwKSB6LnNxclRvKHIscjIpOyBlbHNlIHsgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9XG4gICAgICB6Lm11bFRvKHIyLGdbd10scik7XG4gICAgfVxuXG4gICAgd2hpbGUoaiA+PSAwICYmIChlW2pdJigxPDxpKSkgPT0gMCkge1xuICAgICAgei5zcXJUbyhyLHIyKTsgdCA9IHI7IHIgPSByMjsgcjIgPSB0O1xuICAgICAgaWYoLS1pIDwgMCkgeyBpID0gdGhpcy5EQi0xOyAtLWo7IH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHoucmV2ZXJ0KHIpO1xufVxuXG4vLyAocHVibGljKSBnY2QodGhpcyxhKSAoSEFDIDE0LjU0KVxuZnVuY3Rpb24gYm5HQ0QoYSkge1xuICB2YXIgeCA9ICh0aGlzLnM8MCk/dGhpcy5uZWdhdGUoKTp0aGlzLmNsb25lKCk7XG4gIHZhciB5ID0gKGEuczwwKT9hLm5lZ2F0ZSgpOmEuY2xvbmUoKTtcbiAgaWYoeC5jb21wYXJlVG8oeSkgPCAwKSB7IHZhciB0ID0geDsgeCA9IHk7IHkgPSB0OyB9XG4gIHZhciBpID0geC5nZXRMb3dlc3RTZXRCaXQoKSwgZyA9IHkuZ2V0TG93ZXN0U2V0Qml0KCk7XG4gIGlmKGcgPCAwKSByZXR1cm4geDtcbiAgaWYoaSA8IGcpIGcgPSBpO1xuICBpZihnID4gMCkge1xuICAgIHguclNoaWZ0VG8oZyx4KTtcbiAgICB5LnJTaGlmdFRvKGcseSk7XG4gIH1cbiAgd2hpbGUoeC5zaWdudW0oKSA+IDApIHtcbiAgICBpZigoaSA9IHguZ2V0TG93ZXN0U2V0Qml0KCkpID4gMCkgeC5yU2hpZnRUbyhpLHgpO1xuICAgIGlmKChpID0geS5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB5LnJTaGlmdFRvKGkseSk7XG4gICAgaWYoeC5jb21wYXJlVG8oeSkgPj0gMCkge1xuICAgICAgeC5zdWJUbyh5LHgpO1xuICAgICAgeC5yU2hpZnRUbygxLHgpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHkuc3ViVG8oeCx5KTtcbiAgICAgIHkuclNoaWZ0VG8oMSx5KTtcbiAgICB9XG4gIH1cbiAgaWYoZyA+IDApIHkubFNoaWZ0VG8oZyx5KTtcbiAgcmV0dXJuIHk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgJSBuLCBuIDwgMl4yNlxuZnVuY3Rpb24gYm5wTW9kSW50KG4pIHtcbiAgaWYobiA8PSAwKSByZXR1cm4gMDtcbiAgdmFyIGQgPSB0aGlzLkRWJW4sIHIgPSAodGhpcy5zPDApP24tMTowO1xuICBpZih0aGlzLnQgPiAwKVxuICAgIGlmKGQgPT0gMCkgciA9IHRoaXNbMF0lbjtcbiAgICBlbHNlIGZvcih2YXIgaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgciA9IChkKnIrdGhpc1tpXSklbjtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIDEvdGhpcyAlIG0gKEhBQyAxNC42MSlcbmZ1bmN0aW9uIGJuTW9kSW52ZXJzZShtKSB7XG4gIHZhciBhYyA9IG0uaXNFdmVuKCk7XG4gIGlmKCh0aGlzLmlzRXZlbigpICYmIGFjKSB8fCBtLnNpZ251bSgpID09IDApIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87XG4gIHZhciB1ID0gbS5jbG9uZSgpLCB2ID0gdGhpcy5jbG9uZSgpO1xuICB2YXIgYSA9IG5idigxKSwgYiA9IG5idigwKSwgYyA9IG5idigwKSwgZCA9IG5idigxKTtcbiAgd2hpbGUodS5zaWdudW0oKSAhPSAwKSB7XG4gICAgd2hpbGUodS5pc0V2ZW4oKSkge1xuICAgICAgdS5yU2hpZnRUbygxLHUpO1xuICAgICAgaWYoYWMpIHtcbiAgICAgICAgaWYoIWEuaXNFdmVuKCkgfHwgIWIuaXNFdmVuKCkpIHsgYS5hZGRUbyh0aGlzLGEpOyBiLnN1YlRvKG0sYik7IH1cbiAgICAgICAgYS5yU2hpZnRUbygxLGEpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZighYi5pc0V2ZW4oKSkgYi5zdWJUbyhtLGIpO1xuICAgICAgYi5yU2hpZnRUbygxLGIpO1xuICAgIH1cbiAgICB3aGlsZSh2LmlzRXZlbigpKSB7XG4gICAgICB2LnJTaGlmdFRvKDEsdik7XG4gICAgICBpZihhYykge1xuICAgICAgICBpZighYy5pc0V2ZW4oKSB8fCAhZC5pc0V2ZW4oKSkgeyBjLmFkZFRvKHRoaXMsYyk7IGQuc3ViVG8obSxkKTsgfVxuICAgICAgICBjLnJTaGlmdFRvKDEsYyk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmKCFkLmlzRXZlbigpKSBkLnN1YlRvKG0sZCk7XG4gICAgICBkLnJTaGlmdFRvKDEsZCk7XG4gICAgfVxuICAgIGlmKHUuY29tcGFyZVRvKHYpID49IDApIHtcbiAgICAgIHUuc3ViVG8odix1KTtcbiAgICAgIGlmKGFjKSBhLnN1YlRvKGMsYSk7XG4gICAgICBiLnN1YlRvKGQsYik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgdi5zdWJUbyh1LHYpO1xuICAgICAgaWYoYWMpIGMuc3ViVG8oYSxjKTtcbiAgICAgIGQuc3ViVG8oYixkKTtcbiAgICB9XG4gIH1cbiAgaWYodi5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDApIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87XG4gIGlmKGQuY29tcGFyZVRvKG0pID49IDApIHJldHVybiBkLnN1YnRyYWN0KG0pO1xuICBpZihkLnNpZ251bSgpIDwgMCkgZC5hZGRUbyhtLGQpOyBlbHNlIHJldHVybiBkO1xuICBpZihkLnNpZ251bSgpIDwgMCkgcmV0dXJuIGQuYWRkKG0pOyBlbHNlIHJldHVybiBkO1xufVxuXG52YXIgbG93cHJpbWVzID0gWzIsMyw1LDcsMTEsMTMsMTcsMTksMjMsMjksMzEsMzcsNDEsNDMsNDcsNTMsNTksNjEsNjcsNzEsNzMsNzksODMsODksOTcsMTAxLDEwMywxMDcsMTA5LDExMywxMjcsMTMxLDEzNywxMzksMTQ5LDE1MSwxNTcsMTYzLDE2NywxNzMsMTc5LDE4MSwxOTEsMTkzLDE5NywxOTksMjExLDIyMywyMjcsMjI5LDIzMywyMzksMjQxLDI1MSwyNTcsMjYzLDI2OSwyNzEsMjc3LDI4MSwyODMsMjkzLDMwNywzMTEsMzEzLDMxNywzMzEsMzM3LDM0NywzNDksMzUzLDM1OSwzNjcsMzczLDM3OSwzODMsMzg5LDM5Nyw0MDEsNDA5LDQxOSw0MjEsNDMxLDQzMyw0MzksNDQzLDQ0OSw0NTcsNDYxLDQ2Myw0NjcsNDc5LDQ4Nyw0OTEsNDk5LDUwMyw1MDksNTIxLDUyMyw1NDEsNTQ3LDU1Nyw1NjMsNTY5LDU3MSw1NzcsNTg3LDU5Myw1OTksNjAxLDYwNyw2MTMsNjE3LDYxOSw2MzEsNjQxLDY0Myw2NDcsNjUzLDY1OSw2NjEsNjczLDY3Nyw2ODMsNjkxLDcwMSw3MDksNzE5LDcyNyw3MzMsNzM5LDc0Myw3NTEsNzU3LDc2MSw3NjksNzczLDc4Nyw3OTcsODA5LDgxMSw4MjEsODIzLDgyNyw4MjksODM5LDg1Myw4NTcsODU5LDg2Myw4NzcsODgxLDg4Myw4ODcsOTA3LDkxMSw5MTksOTI5LDkzNyw5NDEsOTQ3LDk1Myw5NjcsOTcxLDk3Nyw5ODMsOTkxLDk5N107XG52YXIgbHBsaW0gPSAoMTw8MjYpL2xvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoLTFdO1xuXG4vLyAocHVibGljKSB0ZXN0IHByaW1hbGl0eSB3aXRoIGNlcnRhaW50eSA+PSAxLS41XnRcbmZ1bmN0aW9uIGJuSXNQcm9iYWJsZVByaW1lKHQpIHtcbiAgdmFyIGksIHggPSB0aGlzLmFicygpO1xuICBpZih4LnQgPT0gMSAmJiB4WzBdIDw9IGxvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoLTFdKSB7XG4gICAgZm9yKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKVxuICAgICAgaWYoeFswXSA9PSBsb3dwcmltZXNbaV0pIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZih4LmlzRXZlbigpKSByZXR1cm4gZmFsc2U7XG4gIGkgPSAxO1xuICB3aGlsZShpIDwgbG93cHJpbWVzLmxlbmd0aCkge1xuICAgIHZhciBtID0gbG93cHJpbWVzW2ldLCBqID0gaSsxO1xuICAgIHdoaWxlKGogPCBsb3dwcmltZXMubGVuZ3RoICYmIG0gPCBscGxpbSkgbSAqPSBsb3dwcmltZXNbaisrXTtcbiAgICBtID0geC5tb2RJbnQobSk7XG4gICAgd2hpbGUoaSA8IGopIGlmKG0lbG93cHJpbWVzW2krK10gPT0gMCkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB4Lm1pbGxlclJhYmluKHQpO1xufVxuXG4vKiBhZGRlZCBieSBSZWN1cml0eSBMYWJzICovXG5cbmZ1bmN0aW9uIG5iaXRzKHgpIHtcblx0dmFyIG4gPSAxLCB0O1xuXHRpZiAoKHQgPSB4ID4+PiAxNikgIT0gMCkge1xuXHRcdHggPSB0O1xuXHRcdG4gKz0gMTY7XG5cdH1cblx0aWYgKCh0ID0geCA+PiA4KSAhPSAwKSB7XG5cdFx0eCA9IHQ7XG5cdFx0biArPSA4O1xuXHR9XG5cdGlmICgodCA9IHggPj4gNCkgIT0gMCkge1xuXHRcdHggPSB0O1xuXHRcdG4gKz0gNDtcblx0fVxuXHRpZiAoKHQgPSB4ID4+IDIpICE9IDApIHtcblx0XHR4ID0gdDtcblx0XHRuICs9IDI7XG5cdH1cblx0aWYgKCh0ID0geCA+PiAxKSAhPSAwKSB7XG5cdFx0eCA9IHQ7XG5cdFx0biArPSAxO1xuXHR9XG5cdHJldHVybiBuO1xufVxuXG5mdW5jdGlvbiBiblRvTVBJICgpIHtcblx0dmFyIGJhID0gdGhpcy50b0J5dGVBcnJheSgpO1xuXHR2YXIgc2l6ZSA9IChiYS5sZW5ndGgtMSkqOCtuYml0cyhiYVswXSk7XG5cdHZhciByZXN1bHQgPSBcIlwiO1xuXHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoc2l6ZSAmIDB4RkYwMCkgPj4gOCk7XG5cdHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHNpemUgJiAweEZGKTtcblx0cmVzdWx0ICs9IHV0aWwuYmluMnN0cihiYSk7XG5cdHJldHVybiByZXN1bHQ7XG59XG4vKiBFTkQgb2YgYWRkaXRpb24gKi9cblxuLy8gKHByb3RlY3RlZCkgdHJ1ZSBpZiBwcm9iYWJseSBwcmltZSAoSEFDIDQuMjQsIE1pbGxlci1SYWJpbilcbmZ1bmN0aW9uIGJucE1pbGxlclJhYmluKHQpIHtcbiAgdmFyIG4xID0gdGhpcy5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gIHZhciBrID0gbjEuZ2V0TG93ZXN0U2V0Qml0KCk7XG4gIGlmKGsgPD0gMCkgcmV0dXJuIGZhbHNlO1xuICB2YXIgciA9IG4xLnNoaWZ0UmlnaHQoayk7XG4gIHQgPSAodCsxKT4+MTtcbiAgaWYodCA+IGxvd3ByaW1lcy5sZW5ndGgpIHQgPSBsb3dwcmltZXMubGVuZ3RoO1xuICB2YXIgYSA9IG5iaSgpO1xuICBmb3IodmFyIGkgPSAwOyBpIDwgdDsgKytpKSB7XG4gICAgLy9QaWNrIGJhc2VzIGF0IHJhbmRvbSwgaW5zdGVhZCBvZiBzdGFydGluZyBhdCAyXG4gICAgYS5mcm9tSW50KGxvd3ByaW1lc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkqbG93cHJpbWVzLmxlbmd0aCldKTtcbiAgICB2YXIgeSA9IGEubW9kUG93KHIsdGhpcyk7XG4gICAgaWYoeS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDAgJiYgeS5jb21wYXJlVG8objEpICE9IDApIHtcbiAgICAgIHZhciBqID0gMTtcbiAgICAgIHdoaWxlKGorKyA8IGsgJiYgeS5jb21wYXJlVG8objEpICE9IDApIHtcbiAgICAgICAgeSA9IHkubW9kUG93SW50KDIsdGhpcyk7XG4gICAgICAgIGlmKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZih5LmNvbXBhcmVUbyhuMSkgIT0gMCkgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuL2pzYm4uanMnKTtcblxuLy8gcHJvdGVjdGVkXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jaHVua1NpemUgPSBibnBDaHVua1NpemU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b1JhZGl4ID0gYm5wVG9SYWRpeDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21SYWRpeCA9IGJucEZyb21SYWRpeDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21OdW1iZXIgPSBibnBGcm9tTnVtYmVyO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYml0d2lzZVRvID0gYm5wQml0d2lzZVRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuY2hhbmdlQml0ID0gYm5wQ2hhbmdlQml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYWRkVG8gPSBibnBBZGRUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRNdWx0aXBseSA9IGJucERNdWx0aXBseTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRBZGRPZmZzZXQgPSBibnBEQWRkT2Zmc2V0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlMb3dlclRvID0gYm5wTXVsdGlwbHlMb3dlclRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlVcHBlclRvID0gYm5wTXVsdGlwbHlVcHBlclRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubW9kSW50ID0gYm5wTW9kSW50O1xuQmlnSW50ZWdlci5wcm90b3R5cGUubWlsbGVyUmFiaW4gPSBibnBNaWxsZXJSYWJpbjtcblxuLy8gcHVibGljXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jbG9uZSA9IGJuQ2xvbmU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5pbnRWYWx1ZSA9IGJuSW50VmFsdWU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5ieXRlVmFsdWUgPSBibkJ5dGVWYWx1ZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNob3J0VmFsdWUgPSBiblNob3J0VmFsdWU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zaWdudW0gPSBiblNpZ051bTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnRvQnl0ZUFycmF5ID0gYm5Ub0J5dGVBcnJheTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmVxdWFscyA9IGJuRXF1YWxzO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubWluID0gYm5NaW47XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tYXggPSBibk1heDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmFuZCA9IGJuQW5kO1xuQmlnSW50ZWdlci5wcm90b3R5cGUub3IgPSBibk9yO1xuQmlnSW50ZWdlci5wcm90b3R5cGUueG9yID0gYm5Yb3I7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hbmROb3QgPSBibkFuZE5vdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm5vdCA9IGJuTm90O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRMZWZ0ID0gYm5TaGlmdExlZnQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zaGlmdFJpZ2h0ID0gYm5TaGlmdFJpZ2h0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZ2V0TG93ZXN0U2V0Qml0ID0gYm5HZXRMb3dlc3RTZXRCaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXRDb3VudCA9IGJuQml0Q291bnQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50ZXN0Qml0ID0gYm5UZXN0Qml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc2V0Qml0ID0gYm5TZXRCaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGVhckJpdCA9IGJuQ2xlYXJCaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5mbGlwQml0ID0gYm5GbGlwQml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYWRkID0gYm5BZGQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zdWJ0cmFjdCA9IGJuU3VidHJhY3Q7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseSA9IGJuTXVsdGlwbHk7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZpZGUgPSBibkRpdmlkZTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnJlbWFpbmRlciA9IGJuUmVtYWluZGVyO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2aWRlQW5kUmVtYWluZGVyID0gYm5EaXZpZGVBbmRSZW1haW5kZXI7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RQb3cgPSBibk1vZFBvdztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludmVyc2UgPSBibk1vZEludmVyc2U7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5wb3cgPSBiblBvdztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmdjZCA9IGJuR0NEO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuaXNQcm9iYWJsZVByaW1lID0gYm5Jc1Byb2JhYmxlUHJpbWU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b01QSSA9IGJuVG9NUEk7XG5cbi8vIEpTQk4tc3BlY2lmaWMgZXh0ZW5zaW9uXG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmUgPSBiblNxdWFyZTtcblxuXG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uLy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIlRyaXBsZURFUyAoRURFKSBjaXBoZXIgdGVzdCB3aXRoIHRlc3QgdmVjdG9ycyBmcm9tIGh0dHA6Ly9jc3JjLm5pc3QuZ292L3B1YmxpY2F0aW9ucy9uaXN0cHVicy84MDAtMjAvODAwLTIwLnBkZlwiLCBmdW5jdGlvbigpIHtcbiAgdmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8uLi8nKSxcbiAgICB1dGlsID0gb3BlbnBncC51dGlsO1xuXG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIGtleSA9IHV0aWwuYmluMnN0cihbMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDFdKTtcbiAgdmFyIHRlc3R2ZWN0b3JzID0gW1tbMHg4MCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg5NSwweEY4LDB4QTUsMHhFNSwweERELDB4MzEsMHhEOSwweDAwXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4NDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4REQsMHg3RiwweDEyLDB4MUMsMHhBNSwweDAxLDB4NTYsMHgxOV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDIwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDJFLDB4ODYsMHg1MywweDEwLDB4NEYsMHgzOCwweDM0LDB4RUFdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgxMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg0QiwweEQzLDB4ODgsMHhGRiwweDZDLDB4RDgsMHgxRCwweDRGXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDgsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4MjAsMHhCOSwweEU3LDB4NjcsMHhCMiwweEZCLDB4MTQsMHg1Nl1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDA0LDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDU1LDB4NTcsMHg5MywweDgwLDB4RDcsMHg3MSwweDM4LDB4RUZdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMiwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg2QywweEM1LDB4REUsMHhGQSwweEFGLDB4MDQsMHg1MSwweDJGXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDEsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4MEQsMHg5RiwweDI3LDB4OUIsMHhBNSwweEQ4LDB4NzIsMHg2MF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAwLDB4ODAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweEQ5LDB4MDMsMHgxQiwweDAyLDB4NzEsMHhCRCwweDVBLDB4MEFdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDQwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg0MiwweDQyLDB4NTAsMHhCMywweDdDLDB4M0QsMHhEOSwweDUxXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgyMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4QjgsMHgwNiwweDFCLDB4N0UsMHhDRCwweDlBLDB4MjEsMHhFNV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAwLDB4MTAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweEYxLDB4NUQsMHgwRiwweDI4LDB4NkIsMHg2NSwweEJELDB4MjhdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDA4LDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhBRCwweEQwLDB4Q0MsMHg4RCwweDZFLDB4NUQsMHhFQiwweEExXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwNCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RTYsMHhENSwweEY4LDB4MjcsMHg1MiwweEFELDB4NjMsMHhEMV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAwLDB4MDIsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweEVDLDB4QkYsMHhFMywweEJELDB4M0YsMHg1OSwweDFBLDB4NUVdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAxLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhGMywweDU2LDB4ODMsMHg0MywweDc5LDB4RDEsMHg2NSwweENEXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDgwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4MkIsMHg5RiwweDk4LDB4MkYsMHgyMCwweDAzLDB4N0YsMHhBOV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAwLDB4MDAsMHg0MCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDg4LDB4OUQsMHhFMCwweDY4LDB4QTEsMHg2RiwweDBCLDB4RTZdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MjAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhFMSwweDlFLDB4MjcsMHg1RCwweDg0LDB4NkEsMHgxMiwweDk4XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDEwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4MzIsMHg5QSwweDhFLDB4RDUsMHgyMywweEQ3LDB4MUEsMHhFQ11dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAwLDB4MDAsMHgwOCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweEU3LDB4RkMsMHhFMiwweDI1LDB4NTcsMHhEMiwweDNDLDB4OTddXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDQsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHgxMiwweEE5LDB4RjUsMHg4MSwweDdGLDB4RjIsMHhENiwweDVEXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAyLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4QTQsMHg4NCwweEMzLDB4QUQsMHgzOCwweERDLDB4OUMsMHgxOV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAxLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RkIsMHhFMCwweDBBLDB4OEEsMHgxRSwweEY4LDB4QUQsMHg3Ml1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4ODAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4NzUsMHgwRCwweDA3LDB4OTQsMHgwNywweDUyLDB4MTMsMHg2M11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4NDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4NjQsMHhGRSwweEVELDB4OUMsMHg3MiwweDRDLDB4MkYsMHhBRl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MjAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RjAsMHgyQiwweDI2LDB4M0IsMHgzMiwweDhFLDB4MkIsMHg2MF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MTAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4OUQsMHg2NCwweDU1LDB4NUEsMHg5QSwweDEwLDB4QjgsMHg1Ml1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDgsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RDEsMHgwNiwweEZGLDB4MEIsMHhFRCwweDUyLDB4NTUsMHhEN11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDQsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RTEsMHg2NSwweDJDLDB4NkIsMHgxMywweDhDLDB4NjQsMHhBNV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDIsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RTQsMHgyOCwweDU4LDB4MTEsMHg4NiwweEVDLDB4OEYsMHg0Nl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDEsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4QUUsMHhCNSwweEY1LDB4RUQsMHhFMiwweDJELDB4MUEsMHgzNl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHg4MCwweDAwLDB4MDAsMHgwMF0sWzB4RTksMHg0MywweEQ3LDB4NTYsMHg4QSwweEVDLDB4MEMsMHg1Q11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHg0MCwweDAwLDB4MDAsMHgwMF0sWzB4REYsMHg5OCwweEM4LDB4MjcsMHg2RiwweDU0LDB4QjAsMHg0Ql1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgyMCwweDAwLDB4MDAsMHgwMF0sWzB4QjEsMHg2MCwweEU0LDB4NjgsMHgwRiwweDZDLDB4NjksMHg2Rl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgxMCwweDAwLDB4MDAsMHgwMF0sWzB4RkEsMHgwNywweDUyLDB4QjAsMHg3RCwweDlDLDB4NEEsMHhCOF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwOCwweDAwLDB4MDAsMHgwMF0sWzB4Q0EsMHgzQSwweDJCLDB4MDMsMHg2RCwweEJDLDB4ODUsMHgwMl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwNCwweDAwLDB4MDAsMHgwMF0sWzB4NUUsMHgwOSwweDA1LDB4NTEsMHg3QiwweEI1LDB4OUIsMHhDRl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMiwweDAwLDB4MDAsMHgwMF0sWzB4ODEsMHg0RSwweEVCLDB4M0IsMHg5MSwweEQ5LDB4MDcsMHgyNl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMSwweDAwLDB4MDAsMHgwMF0sWzB4NEQsMHg0OSwweERCLDB4MTUsMHgzMiwweDkxLDB4OUMsMHg5Rl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDgwLDB4MDAsMHgwMF0sWzB4MjUsMHhFQiwweDVGLDB4QzMsMHhGOCwweENGLDB4MDYsMHgyMV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDQwLDB4MDAsMHgwMF0sWzB4QUIsMHg2QSwweDIwLDB4QzAsMHg2MiwweDBELDB4MUMsMHg2Rl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDIwLDB4MDAsMHgwMF0sWzB4NzksMHhFOSwweDBELDB4QkMsMHg5OCwweEY5LDB4MkMsMHhDQV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDEwLDB4MDAsMHgwMF0sWzB4ODYsMHg2RSwweENFLDB4REQsMHg4MCwweDcyLDB4QkIsMHgwRV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDA4LDB4MDAsMHgwMF0sWzB4OEIsMHg1NCwweDUzLDB4NkYsMHgyRiwweDNFLDB4NjQsMHhBOF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDA0LDB4MDAsMHgwMF0sWzB4RUEsMHg1MSwweEQzLDB4OTcsMHg1NSwweDk1LDB4QjgsMHg2Ql1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAyLDB4MDAsMHgwMF0sWzB4Q0EsMHhGRiwweEM2LDB4QUMsMHg0NSwweDQyLDB4REUsMHgzMV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAxLDB4MDAsMHgwMF0sWzB4OEQsMHhENCwweDVBLDB4MkQsMHhERiwweDkwLDB4NzksMHg2Q11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4ODAsMHgwMF0sWzB4MTAsMHgyOSwweEQ1LDB4NUUsMHg4OCwweDBFLDB4QzIsMHhEMF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4NDAsMHgwMF0sWzB4NUQsMHg4NiwweENCLDB4MjMsMHg2MywweDlELDB4QkUsMHhBOV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MjAsMHgwMF0sWzB4MUQsMHgxQywweEE4LDB4NTMsMHhBRSwweDdDLDB4MEMsMHg1Rl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MTAsMHgwMF0sWzB4Q0UsMHgzMywweDIzLDB4MjksMHgyNCwweDhGLDB4MzIsMHgyOF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDgsMHgwMF0sWzB4ODQsMHgwNSwweEQxLDB4QUIsMHhFMiwweDRGLDB4QjksMHg0Ml1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDQsMHgwMF0sWzB4RTYsMHg0MywweEQ3LDB4ODAsMHg5MCwweENBLDB4NDIsMHgwN11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDIsMHgwMF0sWzB4NDgsMHgyMiwweDFCLDB4OTksMHgzNywweDc0LDB4OEEsMHgyM11dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDEsMHgwMF0sWzB4REQsMHg3QywweDBCLDB4QkQsMHg2MSwweEZBLDB4RkQsMHg1NF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHg4MF0sWzB4MkYsMHhCQywweDI5LDB4MUEsMHg1NywweDBELDB4QjUsMHhDNF1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHg0MF0sWzB4RTAsMHg3QywweDMwLDB4RDcsMHhFNCwweEUyLDB4NkUsMHgxMl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgyMF0sWzB4MDksMHg1MywweEUyLDB4MjUsMHg4RSwweDhFLDB4OTAsMHhBMV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgxMF0sWzB4NUIsMHg3MSwweDFCLDB4QzQsMHhDRSwweEVCLDB4RjIsMHhFRV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwOF0sWzB4Q0MsMHgwOCwweDNGLDB4MUUsMHg2RCwweDlFLDB4ODUsMHhGNl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwNF0sWzB4RDIsMHhGRCwweDg4LDB4NjcsMHhENSwweDBELDB4MkQsMHhGRV1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMl0sWzB4MDYsMHhFNywweEVBLDB4MjIsMHhDRSwweDkyLDB4NzAsMHg4Rl1dLFxyXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMV0sWzB4MTYsMHg2QiwweDQwLDB4QjQsMHg0QSwweEJBLDB4NEIsMHhENl1dXTtcclxuXG4gIHZhciByZXMgPSB0cnVlO1xuICB2YXIgaiA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGVzdHZlY3RvcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGVzID0gbmV3IG9wZW5wZ3AuY2lwaGVyLmRlcyhrZXkpO1xuXG4gICAgdmFyIGVuY3IgPSB1dGlsLmJpbjJzdHIoZGVzLmVuY3J5cHQodGVzdHZlY3RvcnNbaV1bMF0sIGtleSkpO1xuICAgIHZhciByZXMyID0gZW5jciA9PSB1dGlsLmJpbjJzdHIodGVzdHZlY3RvcnNbaV1bMV0pO1xuXG4gICAgcmVzICY9IHJlczI7XG5cbiAgICBpZiAoIXJlczIpIHtcbiAgICByZXN1bHRbal0gPSBuZXcgdW5pdC5yZXN1bHQoXCJUZXN0aW5nIHZlY3RvciB3aXRoIGJsb2NrIFwiICtcbiAgICAgICAgdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yc1tpXVswXSkgK1xuICAgICAgICBcIiBhbmQga2V5IFwiICsgdXRpbC5oZXhzdHJkdW1wKGtleSkgK1xuICAgICAgICBcIiBzaG91bGQgYmUgXCIgKyB1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzW2ldWzFdKSArIFwiICE9IFwiICtcbiAgICAgICAgdXRpbC5oZXhpZHVtcChlbmNyKSxcbiAgICAgIGZhbHNlKTtcbiAgICBqKys7XG4gICAgfVxuICB9XG4gIGlmIChyZXMpIHtcbiAgICByZXN1bHRbal0gPSBuZXcgdW5pdC5yZXN1bHQoXCJBbGwgM0RFUyBFREUgdGVzdCB2ZWN0b3JzIGNvbXBsZXRlZFwiLCB0cnVlKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufSk7XG5cblxudW5pdC5yZWdpc3RlcihcIkRFUyBlbmNyeXB0L2RlY3J5cHQgcGFkZGluZyB0ZXN0c1wiLCBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLy4uLycpLFxuICAgICAgdXRpbCA9IG9wZW5wZ3AudXRpbDtcblxuICAgIHZhciByZXN1bHQgPSBbXTtcclxuICAgIHZhciBrZXkgPSB1dGlsLmJpbjJzdHIoWzB4MDEsIDB4MjMsIDB4NDUsIDB4NjcsIDB4ODksIDB4QUIsIDB4Q0QsIDB4RUZdKTtcclxuICAgIHZhciB0ZXN0dmVjdG9ycyA9IG5ldyBBcnJheSgpO1xyXG4gICAgdGVzdHZlY3RvcnNbMF0gPSBbW1sweDAxXSwgWzB4MjQsIDB4QzcsIDB4NEEsIDB4OUEsIDB4NzksIDB4NzUsIDB4NEIsIDB4QzddXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDIsIDB4MDNdLCBbMHhBNywgMHg3QSwgMHg5QSwgMHg1OSwgMHg4QSwgMHg4NiwgMHg4NSwgMHhDNV1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwMywgMHgwNCwgMHgwNV0sIFsweDAxLCAweENGLCAweEVCLCAweDZBLCAweDc0LCAweDYwLCAweEY1LCAweDAyXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA0LCAweDA1LCAweDA2LCAweDA3XSwgWzB4QTgsIDB4RjAsIDB4M0QsIDB4NTksIDB4QkEsIDB4NkIsIDB4MEUsIDB4NzZdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDUsIDB4MDYsIDB4MDcsIDB4MDgsIDB4MDldLCBbMHg4NiwgMHg0MCwgMHgzMywgMHg2MSwgMHgzRiwgMHg1NSwgMHg3MywgMHg0OV1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNiwgMHgwNywgMHgwOCwgMHgwOSwgMHgwQSwgMHgwQl0sIFsweDEzLCAweDIxLCAweDNFLCAweDBFLCAweENFLCAweDJDLCAweDk0LCAweDAxXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA3LCAweDA4LCAweDA5LCAweDBBLCAweDBCLCAweDBDLCAweDBEXSwgWzB4MzAsIDB4NDksIDB4OTcsIDB4QzEsIDB4REEsIDB4RDUsIDB4NTksIDB4QTVdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDgsIDB4MDksIDB4MEEsIDB4MEIsIDB4MEMsIDB4MEQsIDB4MEUsIDB4MEZdLCBbMHg4MywgMHgyNSwgMHg3OSwgMHgwNiwgMHg1NCwgMHhBNCwgMHg0NCwgMHhEOV1dXTtcclxuICAgIHRlc3R2ZWN0b3JzWzFdID0gW1tbMHgwMV0sIFsweEYyLCAweEFCLCAweDFDLCAweDlFLCAweDcwLCAweDdELCAweENDLCAweDkyXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDAyLCAweDAzXSwgWzB4NkIsIDB4NEMsIDB4NjcsIDB4MjQsIDB4OUYsIDB4QjcsIDB4NEQsIDB4QUNdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDMsIDB4MDQsIDB4MDVdLCBbMHg2OCwgMHg5NSwgMHhBQiwgMHhBOCwgMHhFQSwgMHg1MywgMHgxMywgMHgyM11dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNCwgMHgwNSwgMHgwNiwgMHgwN10sIFsweEM4LCAweERFLCAweDYwLCAweDhGLCAweEY2LCAweDA5LCAweDkwLCAweEI1XV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA1LCAweDA2LCAweDA3LCAweDA4LCAweDA5XSwgWzB4MTksIDB4MTMsIDB4NTAsIDB4MjAsIDB4NzAsIDB4NDAsIDB4MkUsIDB4MDldXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDYsIDB4MDcsIDB4MDgsIDB4MDksIDB4MEEsIDB4MEJdLCBbMHhBOCwgMHgyMywgMHg0MCwgMHhDNiwgMHgxNywgMHhBNiwgMHgzMSwgMHg0QV1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNywgMHgwOCwgMHgwOSwgMHgwQSwgMHgwQiwgMHgwQywgMHgwRF0sIFsweDM2LCAweDYyLCAweEYyLCAweDk5LCAweDY4LCAweEQ0LCAweEJGLCAweDdDXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA4LCAweDA5LCAweDBBLCAweDBCLCAweDBDLCAweDBELCAweDBFLCAweDBGXSwgWzB4ODMsIDB4MjUsIDB4NzksIDB4MDYsIDB4NTQsIDB4QTQsIDB4NDQsIDB4RDksIDB4MDgsIDB4NkYsIDB4OUEsIDB4MUQsIDB4NzQsIDB4QzksIDB4NEQsIDB4NEVdXV07XHJcbiAgICB0ZXN0dmVjdG9yc1syXSA9IFtbWzB4MDFdLCBbMHg4MywgMHg2OCwgMHhFNCwgMHg5QywgMHg4NCwgMHhDQywgMHhDQiwgMHhGMF1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwMiwgMHgwM10sIFsweEJCLCAweEE4LCAweDBCLCAweDY2LCAweDFCLCAweDYyLCAweEM0LCAweEM4XV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDAzLCAweDA0LCAweDA1XSwgWzB4OUEsIDB4RDcsIDB4NUEsIDB4MjQsIDB4RkQsIDB4M0YsIDB4QkYsIDB4MjJdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDQsIDB4MDUsIDB4MDYsIDB4MDddLCBbMHgxNCwgMHg0RSwgMHg2OCwgMHg2RCwgMHgyRSwgMHhDMSwgMHhCNywgMHg1Ml1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNSwgMHgwNiwgMHgwNywgMHgwOCwgMHgwOV0sIFsweDEyLCAweDBBLCAweDUxLCAweDA4LCAweEY5LCAweEEzLCAweDAzLCAweDc0XV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA2LCAweDA3LCAweDA4LCAweDA5LCAweDBBLCAweDBCXSwgWzB4QjIsIDB4MDcsIDB4RDEsIDB4MDUsIDB4RjYsIDB4NjcsIDB4QUYsIDB4QkFdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDcsIDB4MDgsIDB4MDksIDB4MEEsIDB4MEIsIDB4MEMsIDB4MERdLCBbMHhDQSwgMHg1OSwgMHg2MSwgMHgzQSwgMHg4MywgMHgyMywgMHgyNiwgMHhERF1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwOCwgMHgwOSwgMHgwQSwgMHgwQiwgMHgwQywgMHgwRCwgMHgwRSwgMHgwRl0sIFsweDgzLCAweDI1LCAweDc5LCAweDA2LCAweDU0LCAweEE0LCAweDQ0LCAweEQ5XV1dO1xyXG5cclxuICAgIHZhciBkZXMgPSBuZXcgb3BlbnBncC5jaXBoZXIub3JpZ2luYWxEZXMoa2V5KTtcclxuXHJcbiAgICB2YXIgcmVzID0gdHJ1ZTtcclxuICAgIHZhciBqID0gMDtcclxuXHJcbiAgICBmb3IgKHZhciBwYWRkaW5nID0gMDsgcGFkZGluZyA8IDM7IHBhZGRpbmcrKykge1xyXG4gICAgICAgIHZhciB0aGlzVmVjdG9yU2V0ID0gdGVzdHZlY3RvcnNbcGFkZGluZ107XHJcblxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpc1ZlY3RvclNldC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB2YXIgZW5jcnlwdGVkID0gZGVzLmVuY3J5cHQodGhpc1ZlY3RvclNldFtpXVswXSwgcGFkZGluZyk7XHJcbiAgICAgICAgICAgIHZhciBkZWNyeXB0ZWQgPSBkZXMuZGVjcnlwdChlbmNyeXB0ZWQsIHBhZGRpbmcpO1xyXG5cclxuICAgICAgICAgICAgdmFyIHJlczIgPSAodXRpbC5iaW4yc3RyKGVuY3J5cHRlZCkgPT0gdXRpbC5iaW4yc3RyKHRoaXNWZWN0b3JTZXRbaV1bMV0pKTtcclxuICAgICAgICAgICAgdmFyIHJlczMgPSAodXRpbC5iaW4yc3RyKGRlY3J5cHRlZCkgPT0gdXRpbC5iaW4yc3RyKHRoaXNWZWN0b3JTZXRbaV1bMF0pKTtcclxuICAgICAgICAgICAgcmVzICY9IHJlczI7XHJcbiAgICAgICAgICAgIHJlcyAmPSByZXMzO1xyXG4gICAgICAgICAgICBpZiAoIXJlczIgfHwgIXJlczMpIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcclxuICAgICAgICAgICAgICAgICAgICBcIlRlc3RpbmcgdmVjdG9yIHdpdGggYmxvY2sgW1wiICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdXRpbC5oZXhpZHVtcCh0aGlzVmVjdG9yU2V0W2ldWzBdKSArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiXSBhbmQga2V5IFtcIiArIHV0aWwuaGV4c3RyZHVtcChrZXkpICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXCJdIGFuZCBwYWRkaW5nIFtcIiArIHBhZGRpbmcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcIl0gc2hvdWxkIGJlIFwiICsgdXRpbC5oZXhpZHVtcCh0aGlzVmVjdG9yU2V0W2ldWzFdKSArIFwiIC0gQWN0dWFsbHkgW0VOQzpcIiArIHV0aWwuaGV4aWR1bXAoZW5jcnlwdGVkKSArIFwiLCBERUM6XCIgKyB1dGlsLmhleGlkdW1wKGRlY3J5cHRlZCkgKyBcIl1cIixcclxuICAgICAgICAgICAgICAgICAgICBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICBqKys7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAocmVzKSB7XHJcbiAgICAgICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiQWxsIERFUyB0ZXN0IHZlY3RvcnMgY29tcGxldGVkXCIsIHRydWUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufSk7XHJcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG4vL1xuLy8gUlNBIGltcGxlbWVudGF0aW9uXG5cbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9qc2JuLmpzJyksXG5cdHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyksXG5cdHJhbmRvbSA9IHJlcXVpcmUoJy4uL3JhbmRvbS5qcycpO1xuXG5mdW5jdGlvbiBTZWN1cmVSYW5kb20oKXtcbiAgICBmdW5jdGlvbiBuZXh0Qnl0ZXMoYnl0ZUFycmF5KXtcbiAgICAgICAgZm9yKHZhciBuID0gMDsgbiA8IGJ5dGVBcnJheS5sZW5ndGg7bisrKXtcbiAgICAgICAgICAgIGJ5dGVBcnJheVtuXSA9IHJhbmRvbS5nZXRTZWN1cmVSYW5kb21PY3RldCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHRoaXMubmV4dEJ5dGVzID0gbmV4dEJ5dGVzO1xufVxuXG5mdW5jdGlvbiBSU0EoKSB7XG5cdC8qKlxuXHQgKiBUaGlzIGZ1bmN0aW9uIHVzZXMganNibiBCaWcgTnVtIGxpYnJhcnkgdG8gZGVjcnlwdCBSU0Fcblx0ICogQHBhcmFtIG1cblx0ICogICAgICAgICAgICBtZXNzYWdlXG5cdCAqIEBwYXJhbSBkXG5cdCAqICAgICAgICAgICAgUlNBIGQgYXMgQmlnSW50ZWdlclxuXHQgKiBAcGFyYW0gcFxuXHQgKiAgICAgICAgICAgIFJTQSBwIGFzIEJpZ0ludGVnZXJcblx0ICogQHBhcmFtIHFcblx0ICogICAgICAgICAgICBSU0EgcSBhcyBCaWdJbnRlZ2VyXG5cdCAqIEBwYXJhbSB1XG5cdCAqICAgICAgICAgICAgUlNBIHUgYXMgQmlnSW50ZWdlclxuXHQgKiBAcmV0dXJuIHtCaWdJbnRlZ2VyfSBUaGUgZGVjcnlwdGVkIHZhbHVlIG9mIHRoZSBtZXNzYWdlXG5cdCAqL1xuXHRmdW5jdGlvbiBkZWNyeXB0KG0sIGQsIHAsIHEsIHUpIHtcblx0XHR2YXIgeHAgPSBtLm1vZChwKS5tb2RQb3coZC5tb2QocC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkpLCBwKTtcblx0XHR2YXIgeHEgPSBtLm1vZChxKS5tb2RQb3coZC5tb2QocS5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkpLCBxKTtcblx0XHR1dGlsLnByaW50X2RlYnVnKFwicnNhLmpzIGRlY3J5cHRcXG54cG46XCIrdXRpbC5oZXhzdHJkdW1wKHhwLnRvTVBJKCkpK1wiXFxueHFuOlwiK3V0aWwuaGV4c3RyZHVtcCh4cS50b01QSSgpKSk7XG5cblx0XHR2YXIgdCA9IHhxLnN1YnRyYWN0KHhwKTtcblx0XHRpZiAodFswXSA9PSAwKSB7XG5cdFx0XHR0ID0geHAuc3VidHJhY3QoeHEpO1xuXHRcdFx0dCA9IHQubXVsdGlwbHkodSkubW9kKHEpO1xuXHRcdFx0dCA9IHEuc3VidHJhY3QodCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHQgPSB0Lm11bHRpcGx5KHUpLm1vZChxKTtcblx0XHR9XG5cdFx0cmV0dXJuIHQubXVsdGlwbHkocCkuYWRkKHhwKTtcblx0fVxuXHRcblx0LyoqXG5cdCAqIGVuY3J5cHQgbWVzc2FnZVxuXHQgKiBAcGFyYW0gbSBtZXNzYWdlIGFzIEJpZ0ludGVnZXJcblx0ICogQHBhcmFtIGUgcHVibGljIE1QSSBwYXJ0IGFzIEJpZ0ludGVnZXJcblx0ICogQHBhcmFtIG4gcHVibGljIE1QSSBwYXJ0IGFzIEJpZ0ludGVnZXJcblx0ICogQHJldHVybiBCaWdJbnRlZ2VyXG5cdCAqL1xuXHRmdW5jdGlvbiBlbmNyeXB0KG0sZSxuKSB7XG5cdFx0cmV0dXJuIG0ubW9kUG93SW50KGUsIG4pO1xuXHR9XG5cdFxuXHQvKiBTaWduIGFuZCBWZXJpZnkgKi9cblx0ZnVuY3Rpb24gc2lnbihtLGQsbikge1xuXHRcdHJldHVybiBtLm1vZFBvdyhkLCBuKTtcblx0fVxuXHRcdFxuXHRmdW5jdGlvbiB2ZXJpZnkoeCxlLG4pIHtcblx0XHRyZXR1cm4geC5tb2RQb3dJbnQoZSwgbik7XG5cdH1cblx0XG5cdC8vIFwiZW1wdHlcIiBSU0Ega2V5IGNvbnN0cnVjdG9yXG4gICAgZnVuY3Rpb24ga2V5T2JqZWN0KCkge1xuICAgICAgICB0aGlzLm4gPSBudWxsO1xuICAgICAgICB0aGlzLmUgPSAwO1xuICAgICAgICB0aGlzLmVlID0gbnVsbDtcbiAgICAgICAgdGhpcy5kID0gbnVsbDtcbiAgICAgICAgdGhpcy5wID0gbnVsbDtcbiAgICAgICAgdGhpcy5xID0gbnVsbDtcbiAgICAgICAgdGhpcy5kbXAxID0gbnVsbDtcbiAgICAgICAgdGhpcy5kbXExID0gbnVsbDtcbiAgICAgICAgdGhpcy51ID0gbnVsbDtcbiAgICB9XG5cdFxuXHQvLyBHZW5lcmF0ZSBhIG5ldyByYW5kb20gcHJpdmF0ZSBrZXkgQiBiaXRzIGxvbmcsIHVzaW5nIHB1YmxpYyBleHB0IEVcbiAgICBmdW5jdGlvbiBnZW5lcmF0ZShCLEUpIHtcbiAgICAgICAgdmFyIGtleSA9IG5ldyBrZXlPYmplY3QoKTtcbiAgICAgICAgdmFyIHJuZyA9IG5ldyBTZWN1cmVSYW5kb20oKTtcbiAgICAgICAgdmFyIHFzID0gQj4+MTtcbiAgICAgICAga2V5LmUgPSBwYXJzZUludChFLDE2KTtcbiAgICAgICAga2V5LmVlID0gbmV3IEJpZ0ludGVnZXIoRSwxNik7XG4gICAgICAgIGZvcig7Oykge1xuICAgICAgICAgICAgZm9yKDs7KSB7XG4gICAgICAgICAgICAgICAga2V5LnAgPSBuZXcgQmlnSW50ZWdlcihCLXFzLDEscm5nKTtcbiAgICAgICAgICAgICAgICBpZihrZXkucC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkuZ2NkKGtleS5lZSkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwICYmIGtleS5wLmlzUHJvYmFibGVQcmltZSgxMCkpIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yKDs7KSB7XG4gICAgICAgICAgICAgICAga2V5LnEgPSBuZXcgQmlnSW50ZWdlcihxcywxLHJuZyk7XG4gICAgICAgICAgICAgICAgaWYoa2V5LnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChrZXkuZWUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCAmJiBrZXkucS5pc1Byb2JhYmxlUHJpbWUoMTApKSBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmKGtleS5wLmNvbXBhcmVUbyhrZXkucSkgPD0gMCkge1xuICAgICAgICAgICAgICAgIHZhciB0ID0ga2V5LnA7XG4gICAgICAgICAgICAgICAga2V5LnAgPSBrZXkucTtcbiAgICAgICAgICAgICAgICBrZXkucSA9IHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcDEgPSBrZXkucC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgICAgICAgICB2YXIgcTEgPSBrZXkucS5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgICAgICAgICB2YXIgcGhpID0gcDEubXVsdGlwbHkocTEpO1xuICAgICAgICAgICAgaWYocGhpLmdjZChrZXkuZWUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCkge1xuICAgICAgICAgICAgICAgIGtleS5uID0ga2V5LnAubXVsdGlwbHkoa2V5LnEpO1xuICAgICAgICAgICAgICAgIGtleS5kID0ga2V5LmVlLm1vZEludmVyc2UocGhpKTtcbiAgICAgICAgICAgICAgICBrZXkuZG1wMSA9IGtleS5kLm1vZChwMSk7XG4gICAgICAgICAgICAgICAga2V5LmRtcTEgPSBrZXkuZC5tb2QocTEpO1xuICAgICAgICAgICAgICAgIGtleS51ID0ga2V5LnAubW9kSW52ZXJzZShrZXkucSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGtleTtcbiAgICB9XG5cdFx0XG5cdHRoaXMuZW5jcnlwdCA9IGVuY3J5cHQ7XG5cdHRoaXMuZGVjcnlwdCA9IGRlY3J5cHQ7XG5cdHRoaXMudmVyaWZ5ID0gdmVyaWZ5O1xuXHR0aGlzLnNpZ24gPSBzaWduO1xuXHR0aGlzLmdlbmVyYXRlID0gZ2VuZXJhdGU7XG5cdHRoaXMua2V5T2JqZWN0ID0ga2V5T2JqZWN0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJTQTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBIFxuXG4vLyBUaGUgR1BHNEJyb3dzZXJzIGNyeXB0byBpbnRlcmZhY2VcblxudmFyIHR5cGVfbXBpID0gcmVxdWlyZSgnLi4vdHlwZS9tcGkuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdC8qKlxuXHQgKiBSZXRyaWV2ZSBzZWN1cmUgcmFuZG9tIGJ5dGUgc3RyaW5nIG9mIHRoZSBzcGVjaWZpZWQgbGVuZ3RoXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIExlbmd0aCBpbiBieXRlcyB0byBnZW5lcmF0ZVxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IFJhbmRvbSBieXRlIHN0cmluZ1xuXHQgKi9cblx0Z2V0UmFuZG9tQnl0ZXM6IGZ1bmN0aW9uKGxlbmd0aCkge1xuXHRcdHZhciByZXN1bHQgPSAnJztcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG5cdFx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmdldFNlY3VyZVJhbmRvbU9jdGV0KCkpO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXR1cm4gYSBwc2V1ZG8tcmFuZG9tIG51bWJlciBpbiB0aGUgc3BlY2lmaWVkIHJhbmdlXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gZnJvbSBNaW4gb2YgdGhlIHJhbmRvbSBudW1iZXJcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSB0byBNYXggb2YgdGhlIHJhbmRvbSBudW1iZXIgKG1heCAzMmJpdClcblx0ICogQHJldHVybiB7SW50ZWdlcn0gQSBwc2V1ZG8gcmFuZG9tIG51bWJlclxuXHQgKi9cblx0Z2V0UHNldWRvUmFuZG9tOiBmdW5jdGlvbihmcm9tLCB0bykge1xuXHRcdHJldHVybiBNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkqKHRvLWZyb20pKStmcm9tO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXR1cm4gYSBzZWN1cmUgcmFuZG9tIG51bWJlciBpbiB0aGUgc3BlY2lmaWVkIHJhbmdlXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gZnJvbSBNaW4gb2YgdGhlIHJhbmRvbSBudW1iZXJcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSB0byBNYXggb2YgdGhlIHJhbmRvbSBudW1iZXIgKG1heCAzMmJpdClcblx0ICogQHJldHVybiB7SW50ZWdlcn0gQSBzZWN1cmUgcmFuZG9tIG51bWJlclxuXHQgKi9cblx0Z2V0U2VjdXJlUmFuZG9tOiBmdW5jdGlvbihmcm9tLCB0bykge1xuXHRcdHZhciBidWYgPSBuZXcgVWludDMyQXJyYXkoMSk7XG5cdFx0d2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMoYnVmKTtcblx0XHR2YXIgYml0cyA9ICgodG8tZnJvbSkpLnRvU3RyaW5nKDIpLmxlbmd0aDtcblx0XHR3aGlsZSAoKGJ1ZlswXSAmIChNYXRoLnBvdygyLCBiaXRzKSAtMSkpID4gKHRvLWZyb20pKVxuXHRcdFx0d2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMoYnVmKTtcblx0XHRyZXR1cm4gZnJvbSsoTWF0aC5hYnMoYnVmWzBdICYgKE1hdGgucG93KDIsIGJpdHMpIC0xKSkpO1xuXHR9LFxuXG5cdGdldFNlY3VyZVJhbmRvbU9jdGV0OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgYnVmID0gbmV3IFVpbnQzMkFycmF5KDEpO1xuXHRcdHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGJ1Zik7XG5cdFx0cmV0dXJuIGJ1ZlswXSAmIDB4RkY7XG5cdH0sXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHNlY3VyZSByYW5kb20gYmlnIGludGVnZXIgb2YgYml0cyBsZW5ndGhcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBiaXRzIEJpdCBsZW5ndGggb2YgdGhlIE1QSSB0byBjcmVhdGVcbiAgICogQHJldHVybiB7QmlnSW50ZWdlcn0gUmVzdWx0aW5nIGJpZyBpbnRlZ2VyXG4gICAqL1xuICBnZXRSYW5kb21CaWdJbnRlZ2VyOiBmdW5jdGlvbihiaXRzKSB7XG4gICAgaWYgKGJpdHMgPCAwKSB7XG4gICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHZhciBudW1CeXRlcyA9IE1hdGguZmxvb3IoKGJpdHMrNykvOCk7XG5cbiAgICB2YXIgcmFuZG9tQml0cyA9IHRoaXMuZ2V0UmFuZG9tQnl0ZXMobnVtQnl0ZXMpO1xuICAgIGlmIChiaXRzICUgOCA+IDApIHtcbiAgICAgIFxuICAgICAgcmFuZG9tQml0cyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICAgICAgICAgIChNYXRoLnBvdygyLGJpdHMgJSA4KS0xKSAmXG4gICAgICAgICAgICAgIHJhbmRvbUJpdHMuY2hhckNvZGVBdCgwKSkgK1xuICAgICAgICByYW5kb21CaXRzLnN1YnN0cmluZygxKTtcbiAgICB9XG4gICAgdmFyIG1waSA9IG5ldyB0eXBlX21waSgpO1xuICAgIG1waS5mcm9tQnl0ZXMocmFuZG9tQml0cyk7XG4gICAgcmV0dXJuIG1waS50b0JpZ0ludGVnZXIoKTtcbiAgfSxcblxuICBnZXRSYW5kb21CaWdJbnRlZ2VySW5SYW5nZTogZnVuY3Rpb24obWluLCBtYXgpIHtcbiAgICBpZiAobWF4LmNvbXBhcmVUbyhtaW4pIDw9IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcmFuZ2UgPSBtYXguc3VidHJhY3QobWluKTtcbiAgICB2YXIgciA9IHRoaXMuZ2V0UmFuZG9tQmlnSW50ZWdlcihyYW5nZS5iaXRMZW5ndGgoKSk7XG4gICAgd2hpbGUgKHIgPiByYW5nZSkge1xuICAgICAgciA9IHRoaXMuZ2V0UmFuZG9tQmlnSW50ZWdlcihyYW5nZS5iaXRMZW5ndGgoKSk7XG4gICAgfVxuICAgIHJldHVybiBtaW4uYWRkKHIpO1xuICB9XG5cbn07XG4iLCJcbnZhciBwdWJsaWNLZXkgPSByZXF1aXJlKCcuL3B1YmxpY19rZXknKSxcblx0cGtjczEgPSByZXF1aXJlKCcuL3BrY3MxLmpzJyksXG5cdGhhc2hNb2R1bGUgPSByZXF1aXJlKCcuL2hhc2gnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdC8qKlxuXHQgKiBcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIHB1YmxpYyBLZXkgYWxnb3JpdGhtXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gaGFzaF9hbGdvIEhhc2ggYWxnb3JpdGhtXG5cdCAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBtc2dfTVBJcyBTaWduYXR1cmUgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnNcblx0ICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpW119IHB1YmxpY2tleV9NUElzIFB1YmxpYyBrZXkgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgb24gd2hlcmUgdGhlIHNpZ25hdHVyZSB3YXMgY29tcHV0ZWQgb24uXG5cdCAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgc2lnbmF0dXJlIChzaWdfZGF0YSB3YXMgZXF1YWwgdG8gZGF0YSBvdmVyIGhhc2gpXG5cdCAqL1xuXHR2ZXJpZnk6IGZ1bmN0aW9uKGFsZ28sIGhhc2hfYWxnbywgbXNnX01QSXMsIHB1YmxpY2tleV9NUElzLCBkYXRhKSB7XG5cdFx0dmFyIGNhbGNfaGFzaCA9IGhhc2hNb2R1bGUuZGlnZXN0KGhhc2hfYWxnbywgZGF0YSk7XG5cblx0XHRzd2l0Y2goYWxnbykge1xuXHRcdGNhc2UgMTogLy8gUlNBIChFbmNyeXB0IG9yIFNpZ24pIFtIQUNdICBcblx0XHRjYXNlIDI6IC8vIFJTQSBFbmNyeXB0LU9ubHkgW0hBQ11cblx0XHRjYXNlIDM6IC8vIFJTQSBTaWduLU9ubHkgW0hBQ11cblx0XHRcdHZhciByc2EgPSBuZXcgcHVibGljS2V5LnJzYSgpO1xuXHRcdFx0dmFyIG4gPSBwdWJsaWNrZXlfTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcblx0XHRcdHZhciBlID0gcHVibGlja2V5X01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG5cdFx0XHR2YXIgeCA9IG1zZ19NUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuXHRcdFx0dmFyIGRvcHVibGljID0gcnNhLnZlcmlmeSh4LGUsbik7XG5cdFx0XHR2YXIgaGFzaCAgPSBwa2NzMS5lbXNhLmRlY29kZShoYXNoX2FsZ28sZG9wdWJsaWMudG9NUEkoKS5zdWJzdHJpbmcoMikpO1xuXHRcdFx0aWYgKGhhc2ggPT0gLTEpIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCdQS0NTMSBwYWRkaW5nIGluIG1lc3NhZ2Ugb3Iga2V5IGluY29ycmVjdC4gQWJvcnRpbmcuLi4nKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBoYXNoID09IGNhbGNfaGFzaDtcblx0XHRcdFxuXHRcdGNhc2UgMTY6IC8vIEVsZ2FtYWwgKEVuY3J5cHQtT25seSkgW0VMR0FNQUxdIFtIQUNdXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJzaWduaW5nIHdpdGggRWxnYW1hbCBpcyBub3QgZGVmaW5lZCBpbiB0aGUgT3BlblBHUCBzdGFuZGFyZC5cIik7XG5cdFx0Y2FzZSAxNzogLy8gRFNBIChEaWdpdGFsIFNpZ25hdHVyZSBBbGdvcml0aG0pIFtGSVBTMTg2XSBbSEFDXVxuXHRcdFx0dmFyIGRzYSA9IG5ldyBwdWJsaWNLZXkuZHNhKCk7XG5cdFx0XHR2YXIgczEgPSBtc2dfTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcblx0XHRcdHZhciBzMiA9IG1zZ19NUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuXHRcdFx0dmFyIHAgPSBwdWJsaWNrZXlfTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcblx0XHRcdHZhciBxID0gcHVibGlja2V5X01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG5cdFx0XHR2YXIgZyA9IHB1YmxpY2tleV9NUElzWzJdLnRvQmlnSW50ZWdlcigpO1xuXHRcdFx0dmFyIHkgPSBwdWJsaWNrZXlfTVBJc1szXS50b0JpZ0ludGVnZXIoKTtcblx0XHRcdHZhciBtID0gZGF0YTtcblx0XHRcdHZhciBkb3B1YmxpYyA9IGRzYS52ZXJpZnkoaGFzaF9hbGdvLHMxLHMyLG0scCxxLGcseSk7XG5cdFx0XHRyZXR1cm4gZG9wdWJsaWMuY29tcGFyZVRvKHMxKSA9PSAwO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2lnbmF0dXJlIGFsZ29yaXRobS4nKTtcblx0XHR9XG5cdFx0XG5cdH0sXG5cdCAgIFxuXHQvKipcblx0ICogQ3JlYXRlIGEgc2lnbmF0dXJlIG9uIGRhdGEgdXNpbmcgdGhlIHNwZWNpZmllZCBhbGdvcml0aG1cblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBoYXNoX2FsZ28gaGFzaCBBbGdvcml0aG0gdG8gdXNlIChTZWUgUkZDNDg4MCA5LjQpXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBc3ltbWV0cmljIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlIChTZWUgUkZDNDg4MCA5LjEpXG5cdCAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBwdWJsaWNNUElzIFB1YmxpYyBrZXkgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG5cdCAqIG9mIHRoZSBwcml2YXRlIGtleSBcblx0ICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpW119IHNlY3JldE1QSXMgUHJpdmF0ZSBrZXkgbXVsdGlwcmVjaXNpb24gXG5cdCAqIGludGVnZXJzIHdoaWNoIGlzIHVzZWQgdG8gc2lnbiB0aGUgZGF0YVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGJlIHNpZ25lZFxuXHQgKiBAcmV0dXJuIHtvcGVucGdwX3R5cGVfbXBpW119XG5cdCAqL1xuXHRzaWduOiBmdW5jdGlvbihoYXNoX2FsZ28sIGFsZ28sIGtleUludGVnZXJzLCBkYXRhKSB7XG5cdFx0XG5cdFx0c3dpdGNoKGFsZ28pIHtcblx0XHRjYXNlIDE6IC8vIFJTQSAoRW5jcnlwdCBvciBTaWduKSBbSEFDXSAgXG5cdFx0Y2FzZSAyOiAvLyBSU0EgRW5jcnlwdC1Pbmx5IFtIQUNdXG5cdFx0Y2FzZSAzOiAvLyBSU0EgU2lnbi1Pbmx5IFtIQUNdXG5cdFx0XHR2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcblx0XHRcdHZhciBkID0ga2V5SW50ZWdlcnNbMl0udG9CaWdJbnRlZ2VyKCk7XG5cdFx0XHR2YXIgbiA9IGtleUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuXHRcdFx0dmFyIG0gPSBwa2NzMS5lbXNhLmVuY29kZShoYXNoX2FsZ28sIFxuXHRcdFx0XHRkYXRhLCBrZXlJbnRlZ2Vyc1swXS5ieXRlTGVuZ3RoKCkpO1xuXG5cdFx0XHRyZXR1cm4gcnNhLnNpZ24obSwgZCwgbikudG9NUEkoKTtcblxuXHRcdGNhc2UgMTc6IC8vIERTQSAoRGlnaXRhbCBTaWduYXR1cmUgQWxnb3JpdGhtKSBbRklQUzE4Nl0gW0hBQ11cblx0XHRcdHZhciBkc2EgPSBuZXcgcHVibGljS2V5LmRzYSgpO1xuXG5cdFx0XHR2YXIgcCA9IGtleUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuXHRcdFx0dmFyIHEgPSBrZXlJbnRlZ2Vyc1sxXS50b0JpZ0ludGVnZXIoKTtcblx0XHRcdHZhciBnID0ga2V5SW50ZWdlcnNbMl0udG9CaWdJbnRlZ2VyKCk7XG5cdFx0XHR2YXIgeSA9IGtleUludGVnZXJzWzNdLnRvQmlnSW50ZWdlcigpO1xuXHRcdFx0dmFyIHggPSBrZXlJbnRlZ2Vyc1s0XS50b0JpZ0ludGVnZXIoKTtcblx0XHRcdHZhciBtID0gZGF0YTtcblx0XHRcdHZhciByZXN1bHQgPSBkc2Euc2lnbihoYXNoX2FsZ28sbSwgZywgcCwgcSwgeCk7XG5cblx0XHRcdHJldHVybiByZXN1bHRbMF0udG9TdHJpbmcoKSArIHJlc3VsdFsxXS50b1N0cmluZygpO1xuXHRcdGNhc2UgMTY6IC8vIEVsZ2FtYWwgKEVuY3J5cHQtT25seSkgW0VMR0FNQUxdIFtIQUNdXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ1NpZ25pbmcgd2l0aCBFbGdhbWFsIGlzIG5vdCBkZWZpbmVkIGluIHRoZSBPcGVuUEdQIHN0YW5kYXJkLicpO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2lnbmF0dXJlIGFsZ29yaXRobS4nKTtcblx0XHR9XHRcblx0fVxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vL1xuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJy4vYmFzZTY0LmpzJyk7XG5cblxuXG4vKipcbiAqIEZpbmRzIG91dCB3aGljaCBBc2NpaSBBcm1vcmluZyB0eXBlIGlzIHVzZWQuIFRoaXMgaXMgYW4gaW50ZXJuYWwgZnVuY3Rpb25cbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IFtTdHJpbmddIGFzY2lpIGFybW9yZWQgdGV4dFxuICogQHJldHVybnMge0ludGVnZXJ9IDAgPSBNRVNTQUdFIFBBUlQgbiBvZiBtXG4gKiAgICAgICAgIDEgPSBNRVNTQUdFIFBBUlQgblxuICogICAgICAgICAyID0gU0lHTkVEIE1FU1NBR0VcbiAqICAgICAgICAgMyA9IFBHUCBNRVNTQUdFXG4gKiAgICAgICAgIDQgPSBQVUJMSUMgS0VZIEJMT0NLXG4gKiAgICAgICAgIDUgPSBQUklWQVRFIEtFWSBCTE9DS1xuICogICAgICAgICBudWxsID0gdW5rbm93blxuICovXG5mdW5jdGlvbiBnZXRfdHlwZSh0ZXh0KSB7XG5cdHZhciBzcGxpdHRlZHRleHQgPSB0ZXh0LnNwbGl0KCctLS0tLScpO1xuXHQvLyBCRUdJTiBQR1AgTUVTU0FHRSwgUEFSVCBYL1lcblx0Ly8gVXNlZCBmb3IgbXVsdGktcGFydCBtZXNzYWdlcywgd2hlcmUgdGhlIGFybW9yIGlzIHNwbGl0IGFtb25nc3QgWVxuXHQvLyBwYXJ0cywgYW5kIHRoaXMgaXMgdGhlIFh0aCBwYXJ0IG91dCBvZiBZLlxuXHRpZiAoc3BsaXR0ZWR0ZXh0WzFdLm1hdGNoKC9CRUdJTiBQR1AgTUVTU0FHRSwgUEFSVCBcXGQrXFwvXFxkKy8pKSB7XG5cdFx0cmV0dXJuIDA7XG5cdH0gZWxzZVxuXHRcdC8vIEJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFhcblx0XHQvLyBVc2VkIGZvciBtdWx0aS1wYXJ0IG1lc3NhZ2VzLCB3aGVyZSB0aGlzIGlzIHRoZSBYdGggcGFydCBvZiBhblxuXHRcdC8vIHVuc3BlY2lmaWVkIG51bWJlciBvZiBwYXJ0cy4gUmVxdWlyZXMgdGhlIE1FU1NBR0UtSUQgQXJtb3Jcblx0XHQvLyBIZWFkZXIgdG8gYmUgdXNlZC5cblx0aWYgKHNwbGl0dGVkdGV4dFsxXS5tYXRjaCgvQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgXFxkKy8pKSB7XG5cdFx0cmV0dXJuIDE7XG5cblx0fSBlbHNlXG5cdFx0Ly8gQkVHSU4gUEdQIFNJR05BVFVSRVxuXHRcdC8vIFVzZWQgZm9yIGRldGFjaGVkIHNpZ25hdHVyZXMsIE9wZW5QR1AvTUlNRSBzaWduYXR1cmVzLCBhbmRcblx0XHQvLyBjbGVhcnRleHQgc2lnbmF0dXJlcy4gTm90ZSB0aGF0IFBHUCAyLnggdXNlcyBCRUdJTiBQR1AgTUVTU0FHRVxuXHRcdC8vIGZvciBkZXRhY2hlZCBzaWduYXR1cmVzLlxuXHRpZiAoc3BsaXR0ZWR0ZXh0WzFdLm1hdGNoKC9CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UvKSkge1xuXHRcdHJldHVybiAyO1xuXG5cdH0gZWxzZVxuICBcdCAgICAvLyBCRUdJTiBQR1AgTUVTU0FHRVxuXHQgICAgLy8gVXNlZCBmb3Igc2lnbmVkLCBlbmNyeXB0ZWQsIG9yIGNvbXByZXNzZWQgZmlsZXMuXG5cdGlmIChzcGxpdHRlZHRleHRbMV0ubWF0Y2goL0JFR0lOIFBHUCBNRVNTQUdFLykpIHtcblx0XHRyZXR1cm4gMztcblxuXHR9IGVsc2Vcblx0XHQvLyBCRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DS1xuXHRcdC8vIFVzZWQgZm9yIGFybW9yaW5nIHB1YmxpYyBrZXlzLlxuXHRpZiAoc3BsaXR0ZWR0ZXh0WzFdLm1hdGNoKC9CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy8pKSB7XG5cdFx0cmV0dXJuIDQ7XG5cblx0fSBlbHNlXG5cdFx0Ly8gQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLXG5cdFx0Ly8gVXNlZCBmb3IgYXJtb3JpbmcgcHJpdmF0ZSBrZXlzLlxuXHRpZiAoc3BsaXR0ZWR0ZXh0WzFdLm1hdGNoKC9CRUdJTiBQR1AgUFJJVkFURSBLRVkgQkxPQ0svKSkge1xuXHRcdHJldHVybiA1O1xuXHR9XG59XG5cbi8qKlxuICogQWRkIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gdG8gdGhlIGFybW9yIHZlcnNpb24gb2YgYW4gT3BlblBHUCBiaW5hcnlcbiAqIHBhY2tldCBibG9jay5cbiAqIEBhdXRob3IgIEFsZXhcbiAqIEB2ZXJzaW9uIDIwMTEtMTItMTZcbiAqIEByZXR1cm5zIHtTdHJpbmd9IFRoZSBoZWFkZXIgaW5mb3JtYXRpb25cbiAqL1xuZnVuY3Rpb24gYXJtb3JfYWRkaGVhZGVyKCkge1xuICAgIHZhciByZXN1bHQgPSBcIlwiO1xuXHRpZiAob3BlbnBncC5jb25maWcuY29uZmlnLnNob3dfdmVyc2lvbikge1xuICAgICAgICByZXN1bHQgKz0gXCJWZXJzaW9uOiBcIitvcGVucGdwLmNvbmZpZy52ZXJzaW9uc3RyaW5nKydcXHJcXG4nO1xuICAgIH1cblx0aWYgKG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5zaG93X2NvbW1lbnQpIHtcbiAgICAgICAgcmVzdWx0ICs9IFwiQ29tbWVudDogXCIrb3BlbnBncC5jb25maWcuY29tbWVudHN0cmluZysnXFxyXFxuJztcbiAgICB9XG4gICAgcmVzdWx0ICs9ICdcXHJcXG4nO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5cblxuXG4vKipcbiAqIENhbGN1bGF0ZXMgYSBjaGVja3N1bSBvdmVyIHRoZSBnaXZlbiBkYXRhIGFuZCByZXR1cm5zIGl0IGJhc2U2NCBlbmNvZGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGNyZWF0ZSBhIENSQy0yNCBjaGVja3N1bSBmb3JcbiAqIEByZXR1cm4ge1N0cmluZ30gQmFzZTY0IGVuY29kZWQgY2hlY2tzdW1cbiAqL1xuZnVuY3Rpb24gZ2V0Q2hlY2tTdW0oZGF0YSkge1xuXHR2YXIgYyA9IGNyZWF0ZWNyYzI0KGRhdGEpO1xuXHR2YXIgc3RyID0gXCJcIiArIFN0cmluZy5mcm9tQ2hhckNvZGUoYyA+PiAxNikrXG5cdFx0XHRcdCAgIFN0cmluZy5mcm9tQ2hhckNvZGUoKGMgPj4gOCkgJiAweEZGKStcblx0XHRcdFx0ICAgU3RyaW5nLmZyb21DaGFyQ29kZShjICYgMHhGRik7XG5cdHJldHVybiBiYXNlNjQuZW5jb2RlKHN0cik7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgY2hlY2tzdW0gb3ZlciB0aGUgZ2l2ZW4gZGF0YSBhbmQgY29tcGFyZXMgaXQgd2l0aCB0aGUgXG4gKiBnaXZlbiBiYXNlNjQgZW5jb2RlZCBjaGVja3N1bVxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBjcmVhdGUgYSBDUkMtMjQgY2hlY2tzdW0gZm9yXG4gKiBAcGFyYW0ge1N0cmluZ30gY2hlY2tzdW0gQmFzZTY0IGVuY29kZWQgY2hlY2tzdW1cbiAqIEByZXR1cm4ge0Jvb2xlYW59IFRydWUgaWYgdGhlIGdpdmVuIGNoZWNrc3VtIGlzIGNvcnJlY3Q7IG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiB2ZXJpZnlDaGVja1N1bShkYXRhLCBjaGVja3N1bSkge1xuXHR2YXIgYyA9IGdldENoZWNrU3VtKGRhdGEpO1xuXHR2YXIgZCA9IGNoZWNrc3VtO1xuXHRyZXR1cm4gY1swXSA9PSBkWzBdICYmIGNbMV0gPT0gZFsxXSAmJiBjWzJdID09IGRbMl07XG59XG4vKipcbiAqIEludGVybmFsIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBhIENSQy0yNCBjaGVja3N1bSBvdmVyIGEgZ2l2ZW4gc3RyaW5nIChkYXRhKVxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBjcmVhdGUgYSBDUkMtMjQgY2hlY2tzdW0gZm9yXG4gKiBAcmV0dXJuIHtJbnRlZ2VyfSBUaGUgQ1JDLTI0IGNoZWNrc3VtIGFzIG51bWJlclxuICovXG52YXIgY3JjX3RhYmxlID0gW1xuMHgwMDAwMDAwMCwgMHgwMDg2NGNmYiwgMHgwMThhZDUwZCwgMHgwMTBjOTlmNiwgMHgwMzkzZTZlMSwgMHgwMzE1YWExYSwgMHgwMjE5MzNlYywgMHgwMjlmN2YxNywgMHgwN2ExODEzOSwgMHgwNzI3Y2RjMiwgMHgwNjJiNTQzNCwgMHgwNmFkMThjZiwgMHgwNDMyNjdkOCwgMHgwNGI0MmIyMywgMHgwNWI4YjJkNSwgMHgwNTNlZmUyZSwgMHgwZmM1NGU4OSwgMHgwZjQzMDI3MiwgMHgwZTRmOWI4NCwgMHgwZWM5ZDc3ZiwgMHgwYzU2YTg2OCwgMHgwY2QwZTQ5MywgMHgwZGRjN2Q2NSwgMHgwZDVhMzE5ZSwgMHgwODY0Y2ZiMCwgMHgwOGUyODM0YiwgMHgwOWVlMWFiZCwgMHgwOTY4NTY0NiwgMHgwYmY3Mjk1MSwgMHgwYjcxNjVhYSwgMHgwYTdkZmM1YywgMHgwYWZiYjBhNywgMHgxZjBjZDFlOSwgMHgxZjhhOWQxMiwgMHgxZTg2MDRlNCwgMHgxZTAwNDgxZiwgMHgxYzlmMzcwOCwgMHgxYzE5N2JmMywgMHgxZDE1ZTIwNSwgMHgxZDkzYWVmZSwgMHgxOGFkNTBkMCwgMHgxODJiMWMyYiwgMHgxOTI3ODVkZCwgMHgxOWExYzkyNiwgMHgxYjNlYjYzMSwgMHgxYmI4ZmFjYSwgMHgxYWI0NjMzYywgMHgxYTMyMmZjNywgMHgxMGM5OWY2MCwgMHgxMDRmZDM5YiwgMHgxMTQzNGE2ZCwgMHgxMWM1MDY5NiwgMHgxMzVhNzk4MSwgMHgxM2RjMzU3YSwgMHgxMmQwYWM4YywgMHgxMjU2ZTA3NywgMHgxNzY4MWU1OSwgMHgxN2VlNTJhMiwgMHgxNmUyY2I1NCwgMHgxNjY0ODdhZiwgMHgxNGZiZjhiOCwgMHgxNDdkYjQ0MywgMHgxNTcxMmRiNSwgMHgxNWY3NjE0ZSwgMHgzZTE5YTNkMiwgMHgzZTlmZWYyOSwgMHgzZjkzNzZkZiwgMHgzZjE1M2EyNCwgMHgzZDhhNDUzMywgMHgzZDBjMDljOCwgMHgzYzAwOTAzZSwgMHgzYzg2ZGNjNSwgMHgzOWI4MjJlYiwgMHgzOTNlNmUxMCwgMHgzODMyZjdlNiwgMHgzOGI0YmIxZCwgMHgzYTJiYzQwYSwgMHgzYWFkODhmMSwgMHgzYmExMTEwNywgMHgzYjI3NWRmYywgMHgzMWRjZWQ1YiwgMHgzMTVhYTFhMCxcbjB4MzA1NjM4NTYsIDB4MzBkMDc0YWQsIDB4MzI0ZjBiYmEsIDB4MzJjOTQ3NDEsIDB4MzNjNWRlYjcsIDB4MzM0MzkyNGMsIDB4MzY3ZDZjNjIsIDB4MzZmYjIwOTksIDB4MzdmN2I5NmYsIDB4Mzc3MWY1OTQsIDB4MzVlZThhODMsIDB4MzU2OGM2NzgsIDB4MzQ2NDVmOGUsIDB4MzRlMjEzNzUsIDB4MjExNTcyM2IsIDB4MjE5MzNlYzAsIDB4MjA5ZmE3MzYsIDB4MjAxOWViY2QsIDB4MjI4Njk0ZGEsIDB4MjIwMGQ4MjEsIDB4MjMwYzQxZDcsIDB4MjM4YTBkMmMsIDB4MjZiNGYzMDIsIDB4MjYzMmJmZjksIDB4MjczZTI2MGYsIDB4MjdiODZhZjQsIDB4MjUyNzE1ZTMsIDB4MjVhMTU5MTgsIDB4MjRhZGMwZWUsIDB4MjQyYjhjMTUsIDB4MmVkMDNjYjIsIDB4MmU1NjcwNDksIDB4MmY1YWU5YmYsIDB4MmZkY2E1NDQsIDB4MmQ0M2RhNTMsIDB4MmRjNTk2YTgsIDB4MmNjOTBmNWUsIDB4MmM0ZjQzYTUsIDB4Mjk3MWJkOGIsIDB4MjlmN2YxNzAsIDB4MjhmYjY4ODYsIDB4Mjg3ZDI0N2QsIDB4MmFlMjViNmEsIDB4MmE2NDE3OTEsIDB4MmI2ODhlNjcsIDB4MmJlZWMyOWMsIDB4N2MzMzQ3YTQsIDB4N2NiNTBiNWYsIDB4N2RiOTkyYTksIDB4N2QzZmRlNTIsIDB4N2ZhMGExNDUsIDB4N2YyNmVkYmUsIDB4N2UyYTc0NDgsIDB4N2VhYzM4YjMsIDB4N2I5MmM2OWQsIDB4N2IxNDhhNjYsIDB4N2ExODEzOTAsIDB4N2E5ZTVmNmIsIDB4NzgwMTIwN2MsIDB4Nzg4NzZjODcsIDB4Nzk4YmY1NzEsIDB4NzkwZGI5OGEsIDB4NzNmNjA5MmQsIDB4NzM3MDQ1ZDYsIDB4NzI3Y2RjMjAsIDB4NzJmYTkwZGIsIDB4NzA2NWVmY2MsIDB4NzBlM2EzMzcsIDB4NzFlZjNhYzEsIDB4NzE2OTc2M2EsIDB4NzQ1Nzg4MTQsIDB4NzRkMWM0ZWYsIDB4NzVkZDVkMTksIDB4NzU1YjExZTIsIDB4NzdjNDZlZjUsIDB4Nzc0MjIyMGUsIDB4NzY0ZWJiZjgsIDB4NzZjOGY3MDMsIDB4NjMzZjk2NGQsIDB4NjNiOWRhYjYsIDB4NjJiNTQzNDAsIDB4NjIzMzBmYmIsXG4weDYwYWM3MGFjLCAweDYwMmEzYzU3LCAweDYxMjZhNWExLCAweDYxYTBlOTVhLCAweDY0OWUxNzc0LCAweDY0MTg1YjhmLCAweDY1MTRjMjc5LCAweDY1OTI4ZTgyLCAweDY3MGRmMTk1LCAweDY3OGJiZDZlLCAweDY2ODcyNDk4LCAweDY2MDE2ODYzLCAweDZjZmFkOGM0LCAweDZjN2M5NDNmLCAweDZkNzAwZGM5LCAweDZkZjY0MTMyLCAweDZmNjkzZTI1LCAweDZmZWY3MmRlLCAweDZlZTNlYjI4LCAweDZlNjVhN2QzLCAweDZiNWI1OWZkLCAweDZiZGQxNTA2LCAweDZhZDE4Y2YwLCAweDZhNTdjMDBiLCAweDY4YzhiZjFjLCAweDY4NGVmM2U3LCAweDY5NDI2YTExLCAweDY5YzQyNmVhLCAweDQyMmFlNDc2LCAweDQyYWNhODhkLCAweDQzYTAzMTdiLCAweDQzMjY3ZDgwLCAweDQxYjkwMjk3LCAweDQxM2Y0ZTZjLCAweDQwMzNkNzlhLCAweDQwYjU5YjYxLCAweDQ1OGI2NTRmLCAweDQ1MGQyOWI0LCAweDQ0MDFiMDQyLCAweDQ0ODdmY2I5LCAweDQ2MTg4M2FlLCAweDQ2OWVjZjU1LCAweDQ3OTI1NmEzLCAweDQ3MTQxYTU4LCAweDRkZWZhYWZmLCAweDRkNjllNjA0LCAweDRjNjU3ZmYyLCAweDRjZTMzMzA5LCAweDRlN2M0YzFlLCAweDRlZmEwMGU1LCAweDRmZjY5OTEzLCAweDRmNzBkNWU4LCAweDRhNGUyYmM2LCAweDRhYzg2NzNkLCAweDRiYzRmZWNiLCAweDRiNDJiMjMwLCAweDQ5ZGRjZDI3LCAweDQ5NWI4MWRjLCAweDQ4NTcxODJhLCAweDQ4ZDE1NGQxLCAweDVkMjYzNTlmLCAweDVkYTA3OTY0LCAweDVjYWNlMDkyLCAweDVjMmFhYzY5LCAweDVlYjVkMzdlLCAweDVlMzM5Zjg1LCAweDVmM2YwNjczLCAweDVmYjk0YTg4LCAweDVhODdiNGE2LCAweDVhMDFmODVkLCAweDViMGQ2MWFiLCAweDViOGIyZDUwLCAweDU5MTQ1MjQ3LCAweDU5OTIxZWJjLCAweDU4OWU4NzRhLCAweDU4MThjYmIxLCAweDUyZTM3YjE2LCAweDUyNjUzN2VkLCAweDUzNjlhZTFiLCAweDUzZWZlMmUwLCAweDUxNzA5ZGY3LCAweDUxZjZkMTBjLFxuMHg1MGZhNDhmYSwgMHg1MDdjMDQwMSwgMHg1NTQyZmEyZiwgMHg1NWM0YjZkNCwgMHg1NGM4MmYyMiwgMHg1NDRlNjNkOSwgMHg1NmQxMWNjZSwgMHg1NjU3NTAzNSwgMHg1NzViYzljMywgMHg1N2RkODUzOF07XG5cbmZ1bmN0aW9uIGNyZWF0ZWNyYzI0KGlucHV0KSB7XG4gIHZhciBjcmMgPSAweEI3MDRDRTtcbiAgdmFyIGluZGV4ID0gMDtcblxuICB3aGlsZSgoaW5wdXQubGVuZ3RoIC0gaW5kZXgpID4gMTYpICB7XG4gICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgpKSAmIDB4ZmZdO1xuICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzEpKSAmIDB4ZmZdO1xuICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzIpKSAmIDB4ZmZdO1xuICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzMpKSAmIDB4ZmZdO1xuICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzQpKSAmIDB4ZmZdO1xuICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzUpKSAmIDB4ZmZdO1xuICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzYpKSAmIDB4ZmZdO1xuICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzcpKSAmIDB4ZmZdO1xuICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzgpKSAmIDB4ZmZdO1xuICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzkpKSAmIDB4ZmZdO1xuICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzEwKSkgJiAweGZmXTtcbiAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCsxMSkpICYgMHhmZl07XG4gICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrMTIpKSAmIDB4ZmZdO1xuICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4KzEzKSkgJiAweGZmXTtcbiAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCsxNCkpICYgMHhmZl07XG4gICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrMTUpKSAmIDB4ZmZdO1xuICAgaW5kZXggKz0gMTY7XG4gIH1cblxuICBmb3IodmFyIGogPSBpbmRleDsgaiA8IGlucHV0Lmxlbmd0aDsgaisrKSB7XG4gICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrKykpICYgMHhmZl1cbiAgfVxuICByZXR1cm4gY3JjICYgMHhmZmZmZmY7XG59XG5cbi8qKlxuICogRGVBcm1vciBhbiBPcGVuUEdQIGFybW9yZWQgbWVzc2FnZTsgdmVyaWZ5IHRoZSBjaGVja3N1bSBhbmQgcmV0dXJuIFxuICogdGhlIGVuY29kZWQgYnl0ZXNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IE9wZW5QR1AgYXJtb3JlZCBtZXNzYWdlXG4gKiBAcmV0dXJucyB7KEJvb2xlYW58T2JqZWN0KX0gRWl0aGVyIGZhbHNlIGluIGNhc2Ugb2YgYW4gZXJyb3IgXG4gKiBvciBhbiBvYmplY3Qgd2l0aCBhdHRyaWJ1dGUgXCJ0ZXh0XCIgY29udGFpbmluZyB0aGUgbWVzc2FnZSB0ZXh0XG4gKiBhbmQgYW4gYXR0cmlidXRlIFwib3BlbnBncFwiIGNvbnRhaW5pbmcgdGhlIGJ5dGVzLlxuICovXG5mdW5jdGlvbiBkZWFybW9yKHRleHQpIHtcblx0dGV4dCA9IHRleHQucmVwbGFjZSgvXFxyL2csICcnKVxuXG5cdHZhciB0eXBlID0gZ2V0X3R5cGUodGV4dCk7XG5cblx0aWYgKHR5cGUgIT0gMikge1xuXHRcdHZhciBzcGxpdHRlZHRleHQgPSB0ZXh0LnNwbGl0KCctLS0tLScpO1xuXG5cdFx0dmFyIGRhdGEgPSB7IFxuXHRcdFx0b3BlbnBncDogYmFzZTY0LmRlY29kZShcblx0XHRcdFx0c3BsaXR0ZWR0ZXh0WzJdXG5cdFx0XHRcdFx0LnNwbGl0KCdcXG5cXG4nKVsxXVxuXHRcdFx0XHRcdC5zcGxpdChcIlxcbj1cIilbMF1cblx0XHRcdFx0XHQucmVwbGFjZSgvXFxuLSAvZyxcIlxcblwiKSksXG5cdFx0XHR0eXBlOiB0eXBlXG5cdFx0fTtcblxuXHRcdGlmICh2ZXJpZnlDaGVja1N1bShkYXRhLm9wZW5wZ3AsIFxuXHRcdFx0c3BsaXR0ZWR0ZXh0WzJdXG5cdFx0XHRcdC5zcGxpdCgnXFxuXFxuJylbMV1cblx0XHRcdFx0LnNwbGl0KFwiXFxuPVwiKVsxXVxuXHRcdFx0XHQuc3BsaXQoJ1xcbicpWzBdKSlcblxuXHRcdFx0cmV0dXJuIGRhdGE7XG5cdFx0ZWxzZSB7XG5cdFx0XHR1dGlsLnByaW50X2Vycm9yKFwiQXNjaWkgYXJtb3IgaW50ZWdyaXR5IGNoZWNrIG9uIG1lc3NhZ2UgZmFpbGVkOiAnXCJcblx0XHRcdFx0KyBzcGxpdHRlZHRleHRbMl1cblx0XHRcdFx0XHQuc3BsaXQoJ1xcblxcbicpWzFdXG5cdFx0XHRcdFx0LnNwbGl0KFwiXFxuPVwiKVsxXVxuXHRcdFx0XHRcdC5zcGxpdCgnXFxuJylbMF0gXG5cdFx0XHRcdCsgXCInIHNob3VsZCBiZSAnXCJcblx0XHRcdFx0KyBnZXRDaGVja1N1bShkYXRhKSkgKyBcIidcIjtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0dmFyIHNwbGl0dGVkdGV4dCA9IHRleHQuc3BsaXQoJy0tLS0tJyk7XG5cblx0XHR2YXIgcmVzdWx0ID0ge1xuXHRcdFx0dGV4dDogc3BsaXR0ZWR0ZXh0WzJdXG5cdFx0XHRcdC5yZXBsYWNlKC9cXG4tIC9nLFwiXFxuXCIpXG5cdFx0XHRcdC5zcGxpdChcIlxcblxcblwiKVsxXSxcblx0XHRcdG9wZW5wZ3A6IGJhc2U2NF9kZWNvZGUoc3BsaXR0ZWR0ZXh0WzRdXG5cdFx0XHRcdC5zcGxpdChcIlxcblxcblwiKVsxXVxuXHRcdFx0XHQuc3BsaXQoXCJcXG49XCIpWzBdKSxcblx0XHRcdHR5cGU6IHR5cGVcblx0XHR9O1xuXG5cdFx0aWYgKHZlcmlmeUNoZWNrU3VtKHJlc3VsdC5vcGVucGdwLCBzcGxpdHRlZHRleHRbNF1cblx0XHRcdC5zcGxpdChcIlxcblxcblwiKVsxXVxuXHRcdFx0LnNwbGl0KFwiXFxuPVwiKVsxXSkpXG5cblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRlbHNlIHtcblx0XHRcdHV0aWwucHJpbnRfZXJyb3IoXCJBc2NpaSBhcm1vciBpbnRlZ3JpdHkgY2hlY2sgb24gbWVzc2FnZSBmYWlsZWRcIik7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG59XG5cblxuLyoqXG4gKiBBcm1vciBhbiBPcGVuUEdQIGJpbmFyeSBwYWNrZXQgYmxvY2tcbiAqIEBwYXJhbSB7SW50ZWdlcn0gbWVzc2FnZXR5cGUgdHlwZSBvZiB0aGUgbWVzc2FnZVxuICogQHBhcmFtIGRhdGFcbiAqIEBwYXJhbSB7SW50ZWdlcn0gcGFydGluZGV4XG4gKiBAcGFyYW0ge0ludGVnZXJ9IHBhcnR0b3RhbFxuICogQHJldHVybnMge1N0cmluZ30gQXJtb3JlZCB0ZXh0XG4gKi9cbmZ1bmN0aW9uIGFybW9yKG1lc3NhZ2V0eXBlLCBkYXRhLCBwYXJ0aW5kZXgsIHBhcnR0b3RhbCkge1xuXHR2YXIgcmVzdWx0ID0gXCJcIjtcblx0c3dpdGNoKG1lc3NhZ2V0eXBlKSB7XG5cdGNhc2UgMDpcblx0XHRyZXN1bHQgKz0gXCItLS0tLUJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFwiK3BhcnRpbmRleCtcIi9cIitwYXJ0dG90YWwrXCItLS0tLVxcclxcblwiO1xuXHRcdHJlc3VsdCArPSBhcm1vcl9hZGRoZWFkZXIoKTtcblx0XHRyZXN1bHQgKz0gYmFzZTY0LmVuY29kZShkYXRhKTtcblx0XHRyZXN1bHQgKz0gXCJcXHJcXG49XCIrZ2V0Q2hlY2tTdW0oZGF0YSkrXCJcXHJcXG5cIjtcblx0XHRyZXN1bHQgKz0gXCItLS0tLUVORCBQR1AgTUVTU0FHRSwgUEFSVCBcIitwYXJ0aW5kZXgrXCIvXCIrcGFydHRvdGFsK1wiLS0tLS1cXHJcXG5cIjtcblx0XHRicmVhaztcblx0Y2FzZSAxOlxuXHRcdHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgXCIrcGFydGluZGV4K1wiLS0tLS1cXHJcXG5cIjtcblx0XHRyZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG5cdFx0cmVzdWx0ICs9IGJhc2U2NC5lbmNvZGUoZGF0YSk7XG5cdFx0cmVzdWx0ICs9IFwiXFxyXFxuPVwiK2dldENoZWNrU3VtKGRhdGEpK1wiXFxyXFxuXCI7XG5cdFx0cmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIE1FU1NBR0UsIFBBUlQgXCIrcGFydGluZGV4K1wiLS0tLS1cXHJcXG5cIjtcblx0XHRicmVhaztcblx0Y2FzZSAyOlxuXHRcdHJlc3VsdCArPSBcIlxcclxcbi0tLS0tQkVHSU4gUEdQIFNJR05FRCBNRVNTQUdFLS0tLS1cXHJcXG5IYXNoOiBcIitkYXRhLmhhc2grXCJcXHJcXG5cXHJcXG5cIjtcblx0XHRyZXN1bHQgKz0gZGF0YS50ZXh0LnJlcGxhY2UoL1xcbi0vZyxcIlxcbi0gLVwiKTtcblx0XHRyZXN1bHQgKz0gXCJcXHJcXG4tLS0tLUJFR0lOIFBHUCBTSUdOQVRVUkUtLS0tLVxcclxcblwiO1xuXHRcdHJlc3VsdCArPSBhcm1vcl9hZGRoZWFkZXIoKTtcblx0XHRyZXN1bHQgKz0gYmFzZTY0LmVuY29kZShkYXRhLm9wZW5wZ3ApO1xuXHRcdHJlc3VsdCArPSBcIlxcclxcbj1cIitnZXRDaGVja1N1bShkYXRhLm9wZW5wZ3ApK1wiXFxyXFxuXCI7XG5cdFx0cmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIFNJR05BVFVSRS0tLS0tXFxyXFxuXCI7XG5cdFx0YnJlYWs7XG5cdGNhc2UgMzpcblx0XHRyZXN1bHQgKz0gXCItLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS1cXHJcXG5cIjtcblx0XHRyZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG5cdFx0cmVzdWx0ICs9IGJhc2U2NC5lbmNvZGUoZGF0YSk7XG5cdFx0cmVzdWx0ICs9IFwiXFxyXFxuPVwiK2dldENoZWNrU3VtKGRhdGEpK1wiXFxyXFxuXCI7XG5cdFx0cmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLVxcclxcblwiO1xuXHRcdGJyZWFrO1xuXHRjYXNlIDQ6XG5cdFx0cmVzdWx0ICs9IFwiLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxyXFxuXCI7XG5cdFx0cmVzdWx0ICs9IGFybW9yX2FkZGhlYWRlcigpO1xuXHRcdHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGRhdGEpO1xuXHRcdHJlc3VsdCArPSBcIlxcclxcbj1cIitnZXRDaGVja1N1bShkYXRhKStcIlxcclxcblwiO1xuXHRcdHJlc3VsdCArPSBcIi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXHJcXG5cXHJcXG5cIjtcblx0XHRicmVhaztcblx0Y2FzZSA1OlxuXHRcdHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcblx0XHRyZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG5cdFx0cmVzdWx0ICs9IGJhc2U2NC5lbmNvZGUoZGF0YSk7XG5cdFx0cmVzdWx0ICs9IFwiXFxyXFxuPVwiK2dldENoZWNrU3VtKGRhdGEpK1wiXFxyXFxuXCI7XG5cdFx0cmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcblx0XHRicmVhaztcblx0fVxuXG5cdHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRlbmNvZGU6IGFybW9yLFxuXHRkZWNvZGU6IGRlYXJtb3Jcbn1cbiIsIi8qIE9wZW5QR1AgcmFkaXgtNjQvYmFzZTY0IHN0cmluZyBlbmNvZGluZy9kZWNvZGluZ1xyXG4gKiBDb3B5cmlnaHQgMjAwNSBIZXJiZXJ0IEhhbmV3aW5rZWwsIHd3dy5oYW5lV0lOLmRlXHJcbiAqIHZlcnNpb24gMS4wLCBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uXHJcbiAqXHJcbiAqIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYXMtaXMsIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LiAgXHJcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUgb3Igc2VsbCB0aGlzIHNvZnR3YXJlLCB3aXRoIG9yXHJcbiAqIHdpdGhvdXQgZmVlLCBmb3IgYW55IHB1cnBvc2UgYW5kIGJ5IGFueSBpbmRpdmlkdWFsIG9yIG9yZ2FuaXphdGlvbiwgaXMgaGVyZWJ5XHJcbiAqIGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGFyYWdyYXBoIGFwcGVhciBcclxuICogaW4gYWxsIGNvcGllcy4gRGlzdHJpYnV0aW9uIGFzIGEgcGFydCBvZiBhbiBhcHBsaWNhdGlvbiBvciBiaW5hcnkgbXVzdFxyXG4gKiBpbmNsdWRlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHNcclxuICogcHJvdmlkZWQgd2l0aCB0aGUgYXBwbGljYXRpb24gb3IgZGlzdHJpYnV0aW9uLlxyXG4gKi9cclxuXHJcbnZhciBiNjRzID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xyXG5cclxuZnVuY3Rpb24gczJyKHQpIHtcclxuXHR2YXIgYSwgYywgbjtcclxuXHR2YXIgciA9ICcnLCBsID0gMCwgcyA9IDA7XHJcblx0dmFyIHRsID0gdC5sZW5ndGg7XHJcblxyXG5cdGZvciAobiA9IDA7IG4gPCB0bDsgbisrKSB7XHJcblx0XHRjID0gdC5jaGFyQ29kZUF0KG4pO1xyXG5cdFx0aWYgKHMgPT0gMCkge1xyXG5cdFx0XHRyICs9IGI2NHMuY2hhckF0KChjID4+IDIpICYgNjMpO1xyXG5cdFx0XHRhID0gKGMgJiAzKSA8PCA0O1xyXG5cdFx0fSBlbHNlIGlmIChzID09IDEpIHtcclxuXHRcdFx0ciArPSBiNjRzLmNoYXJBdCgoYSB8IChjID4+IDQpICYgMTUpKTtcclxuXHRcdFx0YSA9IChjICYgMTUpIDw8IDI7XHJcblx0XHR9IGVsc2UgaWYgKHMgPT0gMikge1xyXG5cdFx0XHRyICs9IGI2NHMuY2hhckF0KGEgfCAoKGMgPj4gNikgJiAzKSk7XHJcblx0XHRcdGwgKz0gMTtcclxuXHRcdFx0aWYgKChsICUgNjApID09IDApXHJcblx0XHRcdFx0ciArPSBcIlxcblwiO1xyXG5cdFx0XHRyICs9IGI2NHMuY2hhckF0KGMgJiA2Myk7XHJcblx0XHR9XHJcblx0XHRsICs9IDE7XHJcblx0XHRpZiAoKGwgJSA2MCkgPT0gMClcclxuXHRcdFx0ciArPSBcIlxcblwiO1xyXG5cclxuXHRcdHMgKz0gMTtcclxuXHRcdGlmIChzID09IDMpXHJcblx0XHRcdHMgPSAwO1xyXG5cdH1cclxuXHRpZiAocyA+IDApIHtcclxuXHRcdHIgKz0gYjY0cy5jaGFyQXQoYSk7XHJcblx0XHRsICs9IDE7XHJcblx0XHRpZiAoKGwgJSA2MCkgPT0gMClcclxuXHRcdFx0ciArPSBcIlxcblwiO1xyXG5cdFx0ciArPSAnPSc7XHJcblx0XHRsICs9IDE7XHJcblx0fVxyXG5cdGlmIChzID09IDEpIHtcclxuXHRcdGlmICgobCAlIDYwKSA9PSAwKVxyXG5cdFx0XHRyICs9IFwiXFxuXCI7XHJcblx0XHRyICs9ICc9JztcclxuXHR9XHJcblxyXG5cdHJldHVybiByO1xyXG59XHJcblxyXG5mdW5jdGlvbiByMnModCkge1xyXG5cdHZhciBjLCBuO1xyXG5cdHZhciByID0gJycsIHMgPSAwLCBhID0gMDtcclxuXHR2YXIgdGwgPSB0Lmxlbmd0aDtcclxuXHJcblx0Zm9yIChuID0gMDsgbiA8IHRsOyBuKyspIHtcclxuXHRcdGMgPSBiNjRzLmluZGV4T2YodC5jaGFyQXQobikpO1xyXG5cdFx0aWYgKGMgPj0gMCkge1xyXG5cdFx0XHRpZiAocylcclxuXHRcdFx0XHRyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYSB8IChjID4+ICg2IC0gcykpICYgMjU1KTtcclxuXHRcdFx0cyA9IChzICsgMikgJiA3O1xyXG5cdFx0XHRhID0gKGMgPDwgcykgJiAyNTU7XHJcblx0XHR9XHJcblx0fVxyXG5cdHJldHVybiByO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IHtcclxuXHRlbmNvZGU6IHMycixcclxuXHRkZWNvZGU6IHIyc1xyXG59XHJcbiIsInZhciBlbnVtcyA9IHtcblxuXHQvKiogQSBzdHJpbmcgdG8ga2V5IHNwZWNpZmllciB0eXBlXG5cdCAqIEBlbnVtIHtJbnRlZ2VyfVxuXHQgKi9cblx0czJrOiB7XG5cdFx0c2ltcGxlOiAwLFxuXHRcdHNhbHRlZDogMSxcblx0XHRpdGVyYXRlZDogMyxcblx0XHRnbnU6IDEwMVxuXHR9LFxuXG5cdC8qKiBSRkM0ODgwLCBzZWN0aW9uIDkuMSBcblx0ICogQGVudW0ge1N0cmluZ31cblx0ICovXG5cdHB1YmxpY0tleToge1xuXHRcdHJzYV9lbmNyeXB0X3NpZ246IDEsXG5cdFx0cnNhX2VuY3J5cHQ6IDIsXG5cdFx0cnNhX3NpZ246IDMsXG5cdFx0ZWxnYW1hbDogMTYsXG5cdFx0ZHNhOiAxN1xuXHR9LFxuXG5cdC8qKiBSRkM0ODgwLCBzZWN0aW9uIDkuMiBcblx0ICogQGVudW0ge1N0cmluZ31cblx0ICovXG5cdHN5bW1ldHJpYzoge1xuXHRcdHBsYWludGV4dDogMCxcblx0XHQvKiogTm90IGltcGxlbWVudGVkISAqL1xuXHRcdGlkZWE6IDEsXG5cdFx0dHJpcGxlZGVzOiAyLFxuXHRcdGNhc3Q1OiAzLFxuXHRcdGJsb3dmaXNoOiA0LFxuXHRcdGFlczEyODogNyxcblx0XHRhZXMxOTI6IDgsXG5cdFx0YWVzMjU2OiA5LFxuXHRcdHR3b2Zpc2g6IDEwXG5cdH0sXG5cblx0LyoqIFJGQzQ4ODAsIHNlY3Rpb24gOS4zXG5cdCAqIEBlbnVtIHtTdHJpbmd9XG5cdCAqL1xuXHRjb21wcmVzc2lvbjoge1xuXHRcdHVuY29tcHJlc3NlZDogMCxcblx0XHQvKiogUkZDMTk1MSAqL1xuXHRcdHppcDogMSxcblx0XHQvKiogUkZDMTk1MCAqL1xuXHRcdHpsaWI6IDIsXG5cdFx0YnppcDI6IDNcblx0fSxcblxuXHQvKiogUkZDNDg4MCwgc2VjdGlvbiA5LjRcblx0ICogQGVudW0ge1N0cmluZ31cblx0ICovXG5cdGhhc2g6IHtcblx0XHRtZDU6IDEsXG5cdFx0c2hhMTogMixcblx0XHRyaXBlbWQ6IDMsXG5cdFx0c2hhMjU2OiA4LFxuXHRcdHNoYTM4NDogOSxcblx0XHRzaGE1MTI6IDEwLFxuXHRcdHNoYTIyNDogMTFcblx0fSxcblxuXG5cdC8qKlxuXHQgKiBAZW51bSB7U3RyaW5nfVxuXHQgKiBBIGxpc3Qgb2YgcGFja2V0IHR5cGVzIGFuZCBudW1lcmljIHRhZ3MgYXNzb2NpYXRlZCB3aXRoIHRoZW0uXG5cdCAqL1xuXHRwYWNrZXQ6IHtcblx0XHRwdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleTogMSxcblx0XHRzaWduYXR1cmU6IDIsXG5cdFx0c3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleTogMyxcblx0XHRvbmVfcGFzc19zaWduYXR1cmU6IDQsXG5cdFx0c2VjcmV0X2tleTogNSxcblx0XHRwdWJsaWNfa2V5OiA2LFxuXHRcdHNlY3JldF9zdWJrZXk6IDcsXG5cdFx0Y29tcHJlc3NlZDogOCxcblx0XHRzeW1tZXRyaWNhbGx5X2VuY3J5cHRlZDogOSxcblx0XHRtYXJrZXI6IDEwLFxuXHRcdGxpdGVyYWw6IDExLFxuXHRcdHRydXN0OiAxMixcblx0XHR1c2VyaWQ6IDEzLFxuXHRcdHB1YmxpY19zdWJrZXk6IDE0LFxuXHRcdHVzZXJfYXR0cmlidXRlOiAxNyxcblx0XHRzeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQ6IDE4LFxuXHRcdG1vZGlmaWNhdGlvbl9kZXRlY3Rpb25fY29kZTogMTlcblx0fSxcblxuXG5cdC8qKlxuXHQgKiBEYXRhIHR5cGVzIGluIHRoZSBsaXRlcmFsIHBhY2tldFxuXHQgKiBAcmVhZG9ubHlcblx0ICogQGVudW0ge1N0cmluZ31cblx0ICovXG5cdGxpdGVyYWw6IHtcblx0XHQvKiogQmluYXJ5IGRhdGEgKi9cblx0XHRiaW5hcnk6ICdiJy5jaGFyQ29kZUF0KCksXG5cdFx0LyoqIFRleHQgZGF0YSAqL1xuXHRcdHRleHQ6ICd0Jy5jaGFyQ29kZUF0KCksXG5cdFx0LyoqIFV0ZjggZGF0YSAqL1xuXHRcdHV0Zjg6ICd1Jy5jaGFyQ29kZUF0KClcblx0fSxcblxuXG5cdC8qKiBPbmUgcGFzcyBzaWduYXR1cmUgcGFja2V0IHR5cGVcblx0ICogQGVudW0ge1N0cmluZ30gKi9cblx0c2lnbmF0dXJlOiB7XG5cdFx0LyoqIDB4MDA6IFNpZ25hdHVyZSBvZiBhIGJpbmFyeSBkb2N1bWVudC4gKi9cblx0XHRiaW5hcnk6IDAsXG5cdFx0LyoqIDB4MDE6IFNpZ25hdHVyZSBvZiBhIGNhbm9uaWNhbCB0ZXh0IGRvY3VtZW50LlxuXHRcdCAqIENhbm9uaWNhbHl6aW5nIHRoZSBkb2N1bWVudCBieSBjb252ZXJ0aW5nIGxpbmUgZW5kaW5ncy4gKi9cblx0XHR0ZXh0OiAxLFxuXHRcdC8qKiAweDAyOiBTdGFuZGFsb25lIHNpZ25hdHVyZS5cblx0XHQqIFRoaXMgc2lnbmF0dXJlIGlzIGEgc2lnbmF0dXJlIG9mIG9ubHkgaXRzIG93biBzdWJwYWNrZXQgY29udGVudHMuXG5cdFx0KiBJdCBpcyBjYWxjdWxhdGVkIGlkZW50aWNhbGx5IHRvIGEgc2lnbmF0dXJlIG92ZXIgYSB6ZXJvLWxlbmdoXG5cdFx0KiBiaW5hcnkgZG9jdW1lbnQuICBOb3RlIHRoYXQgaXQgZG9lc24ndCBtYWtlIHNlbnNlIHRvIGhhdmUgYSBWM1xuXHRcdCogc3RhbmRhbG9uZSBzaWduYXR1cmUuICovXG5cdFx0c3RhbmRhbG9uZTogMixcblx0XHQvKiogMHgxMDogR2VuZXJpYyBjZXJ0aWZpY2F0aW9uIG9mIGEgVXNlciBJRCBhbmQgUHVibGljLUtleSBwYWNrZXQuXG5cdFx0KiBUaGUgaXNzdWVyIG9mIHRoaXMgY2VydGlmaWNhdGlvbiBkb2VzIG5vdCBtYWtlIGFueSBwYXJ0aWN1bGFyXG5cdFx0KiBhc3NlcnRpb24gYXMgdG8gaG93IHdlbGwgdGhlIGNlcnRpZmllciBoYXMgY2hlY2tlZCB0aGF0IHRoZSBvd25lclxuXHRcdCogb2YgdGhlIGtleSBpcyBpbiBmYWN0IHRoZSBwZXJzb24gZGVzY3JpYmVkIGJ5IHRoZSBVc2VyIElELiAqL1xuXHRcdGNlcnRfZ2VuZXJpYzogMTYsXG5cdFx0LyoqIDB4MTE6IFBlcnNvbmEgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQgYW5kIFB1YmxpYy1LZXkgcGFja2V0LlxuXHRcdCogVGhlIGlzc3VlciBvZiB0aGlzIGNlcnRpZmljYXRpb24gaGFzIG5vdCBkb25lIGFueSB2ZXJpZmljYXRpb24gb2Zcblx0XHQqIHRoZSBjbGFpbSB0aGF0IHRoZSBvd25lciBvZiB0aGlzIGtleSBpcyB0aGUgVXNlciBJRCBzcGVjaWZpZWQuICovXG5cdFx0Y2VydF9wZXJzb25hOiAxNyxcblx0XHQvKiogMHgxMjogQ2FzdWFsIGNlcnRpZmljYXRpb24gb2YgYSBVc2VyIElEIGFuZCBQdWJsaWMtS2V5IHBhY2tldC5cblx0XHQqIFRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIGhhcyBkb25lIHNvbWUgY2FzdWFsXG5cdFx0KiB2ZXJpZmljYXRpb24gb2YgdGhlIGNsYWltIG9mIGlkZW50aXR5LiAqL1xuXHRcdGNlcnRfY2FzdWFsOiAxOCxcblx0XHQvKiogMHgxMzogUG9zaXRpdmUgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQgYW5kIFB1YmxpYy1LZXkgcGFja2V0LlxuXHRcdCogVGhlIGlzc3VlciBvZiB0aGlzIGNlcnRpZmljYXRpb24gaGFzIGRvbmUgc3Vic3RhbnRpYWxcblx0XHQqIHZlcmlmaWNhdGlvbiBvZiB0aGUgY2xhaW0gb2YgaWRlbnRpdHkuXG5cdFx0KiBcblx0XHQqIE1vc3QgT3BlblBHUCBpbXBsZW1lbnRhdGlvbnMgbWFrZSB0aGVpciBcImtleSBzaWduYXR1cmVzXCIgYXMgMHgxMFxuXHRcdCogY2VydGlmaWNhdGlvbnMuICBTb21lIGltcGxlbWVudGF0aW9ucyBjYW4gaXNzdWUgMHgxMS0weDEzXG5cdFx0KiBjZXJ0aWZpY2F0aW9ucywgYnV0IGZldyBkaWZmZXJlbnRpYXRlIGJldHdlZW4gdGhlIHR5cGVzLiAqL1xuXHRcdGNlcnRfcG9zaXRpdmU6IDE5LFxuXHRcdC8qKiAweDMwOiBDZXJ0aWZpY2F0aW9uIHJldm9jYXRpb24gc2lnbmF0dXJlXG5cdFx0KiBUaGlzIHNpZ25hdHVyZSByZXZva2VzIGFuIGVhcmxpZXIgVXNlciBJRCBjZXJ0aWZpY2F0aW9uIHNpZ25hdHVyZVxuXHRcdCogKHNpZ25hdHVyZSBjbGFzcyAweDEwIHRocm91Z2ggMHgxMykgb3IgZGlyZWN0LWtleSBzaWduYXR1cmVcblx0XHQqICgweDFGKS4gIEl0IHNob3VsZCBiZSBpc3N1ZWQgYnkgdGhlIHNhbWUga2V5IHRoYXQgaXNzdWVkIHRoZVxuXHRcdCogcmV2b2tlZCBzaWduYXR1cmUgb3IgYW4gYXV0aG9yaXplZCByZXZvY2F0aW9uIGtleS4gIFRoZSBzaWduYXR1cmVcblx0XHQqIGlzIGNvbXB1dGVkIG92ZXIgdGhlIHNhbWUgZGF0YSBhcyB0aGUgY2VydGlmaWNhdGUgdGhhdCBpdFxuXHRcdCogcmV2b2tlcywgYW5kIHNob3VsZCBoYXZlIGEgbGF0ZXIgY3JlYXRpb24gZGF0ZSB0aGFuIHRoYXRcblx0XHQqIGNlcnRpZmljYXRlLiAqL1xuXHRcdGNlcnRfcmV2b2NhdGlvbjogNDgsXG5cdFx0LyoqIDB4MTg6IFN1YmtleSBCaW5kaW5nIFNpZ25hdHVyZVxuXHRcdCogVGhpcyBzaWduYXR1cmUgaXMgYSBzdGF0ZW1lbnQgYnkgdGhlIHRvcC1sZXZlbCBzaWduaW5nIGtleSB0aGF0XG5cdFx0KiBpbmRpY2F0ZXMgdGhhdCBpdCBvd25zIHRoZSBzdWJrZXkuICBUaGlzIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkXG5cdFx0KiBkaXJlY3RseSBvbiB0aGUgcHJpbWFyeSBrZXkgYW5kIHN1YmtleSwgYW5kIG5vdCBvbiBhbnkgVXNlciBJRCBvclxuXHRcdCogb3RoZXIgcGFja2V0cy4gIEEgc2lnbmF0dXJlIHRoYXQgYmluZHMgYSBzaWduaW5nIHN1YmtleSBNVVNUIGhhdmVcblx0XHQqIGFuIEVtYmVkZGVkIFNpZ25hdHVyZSBzdWJwYWNrZXQgaW4gdGhpcyBiaW5kaW5nIHNpZ25hdHVyZSB0aGF0XG5cdFx0KiBjb250YWlucyBhIDB4MTkgc2lnbmF0dXJlIG1hZGUgYnkgdGhlIHNpZ25pbmcgc3Via2V5IG9uIHRoZVxuXHRcdCogcHJpbWFyeSBrZXkgYW5kIHN1YmtleS4gKi9cblx0XHRzdWJrZXlfYmluZGluZzogMjQsXG5cdFx0LyoqIDB4MTk6IFByaW1hcnkgS2V5IEJpbmRpbmcgU2lnbmF0dXJlXG5cdFx0KiBUaGlzIHNpZ25hdHVyZSBpcyBhIHN0YXRlbWVudCBieSBhIHNpZ25pbmcgc3Via2V5LCBpbmRpY2F0aW5nXG5cdFx0KiB0aGF0IGl0IGlzIG93bmVkIGJ5IHRoZSBwcmltYXJ5IGtleSBhbmQgc3Via2V5LiAgVGhpcyBzaWduYXR1cmVcblx0XHQqIGlzIGNhbGN1bGF0ZWQgdGhlIHNhbWUgd2F5IGFzIGEgMHgxOCBzaWduYXR1cmU6IGRpcmVjdGx5IG9uIHRoZVxuXHRcdCogcHJpbWFyeSBrZXkgYW5kIHN1YmtleSwgYW5kIG5vdCBvbiBhbnkgVXNlciBJRCBvciBvdGhlciBwYWNrZXRzLlxuXHRcdFxuXHRcdCogV2hlbiBhIHNpZ25hdHVyZSBpcyBtYWRlIG92ZXIgYSBrZXksIHRoZSBoYXNoIGRhdGEgc3RhcnRzIHdpdGggdGhlXG5cdFx0KiBvY3RldCAweDk5LCBmb2xsb3dlZCBieSBhIHR3by1vY3RldCBsZW5ndGggb2YgdGhlIGtleSwgYW5kIHRoZW4gYm9keVxuXHRcdCogb2YgdGhlIGtleSBwYWNrZXQuICAoTm90ZSB0aGF0IHRoaXMgaXMgYW4gb2xkLXN0eWxlIHBhY2tldCBoZWFkZXIgZm9yXG5cdFx0KiBhIGtleSBwYWNrZXQgd2l0aCB0d28tb2N0ZXQgbGVuZ3RoLikgIEEgc3Via2V5IGJpbmRpbmcgc2lnbmF0dXJlXG5cdFx0KiAodHlwZSAweDE4KSBvciBwcmltYXJ5IGtleSBiaW5kaW5nIHNpZ25hdHVyZSAodHlwZSAweDE5KSB0aGVuIGhhc2hlc1xuXHRcdCogdGhlIHN1YmtleSB1c2luZyB0aGUgc2FtZSBmb3JtYXQgYXMgdGhlIG1haW4ga2V5IChhbHNvIHVzaW5nIDB4OTkgYXNcblx0XHQqIHRoZSBmaXJzdCBvY3RldCkuICovXG5cdFx0a2V5X2JpbmRpbmc6IDI1LFxuXHRcdC8qKiAweDFGOiBTaWduYXR1cmUgZGlyZWN0bHkgb24gYSBrZXlcblx0XHQqIFRoaXMgc2lnbmF0dXJlIGlzIGNhbGN1bGF0ZWQgZGlyZWN0bHkgb24gYSBrZXkuICBJdCBiaW5kcyB0aGVcblx0XHQqIGluZm9ybWF0aW9uIGluIHRoZSBTaWduYXR1cmUgc3VicGFja2V0cyB0byB0aGUga2V5LCBhbmQgaXNcblx0XHQqIGFwcHJvcHJpYXRlIHRvIGJlIHVzZWQgZm9yIHN1YnBhY2tldHMgdGhhdCBwcm92aWRlIGluZm9ybWF0aW9uXG5cdFx0KiBhYm91dCB0aGUga2V5LCBzdWNoIGFzIHRoZSBSZXZvY2F0aW9uIEtleSBzdWJwYWNrZXQuICBJdCBpcyBhbHNvXG5cdFx0KiBhcHByb3ByaWF0ZSBmb3Igc3RhdGVtZW50cyB0aGF0IG5vbi1zZWxmIGNlcnRpZmllcnMgd2FudCB0byBtYWtlXG5cdFx0KiBhYm91dCB0aGUga2V5IGl0c2VsZiwgcmF0aGVyIHRoYW4gdGhlIGJpbmRpbmcgYmV0d2VlbiBhIGtleSBhbmQgYVxuXHRcdCogbmFtZS4gKi9cblx0XHRrZXk6IDMxLFxuXHRcdC8qKiAweDIwOiBLZXkgcmV2b2NhdGlvbiBzaWduYXR1cmVcblx0XHQqIFRoZSBzaWduYXR1cmUgaXMgY2FsY3VsYXRlZCBkaXJlY3RseSBvbiB0aGUga2V5IGJlaW5nIHJldm9rZWQuICBBXG5cdFx0KiByZXZva2VkIGtleSBpcyBub3QgdG8gYmUgdXNlZC4gIE9ubHkgcmV2b2NhdGlvbiBzaWduYXR1cmVzIGJ5IHRoZVxuXHRcdCoga2V5IGJlaW5nIHJldm9rZWQsIG9yIGJ5IGFuIGF1dGhvcml6ZWQgcmV2b2NhdGlvbiBrZXksIHNob3VsZCBiZVxuXHRcdCogY29uc2lkZXJlZCB2YWxpZCByZXZvY2F0aW9uIHNpZ25hdHVyZXMuYSAqL1xuXHRcdGtleV9yZXZvY2F0aW9uOiAzMixcblx0XHQvKiogMHgyODogU3Via2V5IHJldm9jYXRpb24gc2lnbmF0dXJlXG5cdFx0KiBUaGUgc2lnbmF0dXJlIGlzIGNhbGN1bGF0ZWQgZGlyZWN0bHkgb24gdGhlIHN1YmtleSBiZWluZyByZXZva2VkLlxuXHRcdCogQSByZXZva2VkIHN1YmtleSBpcyBub3QgdG8gYmUgdXNlZC4gIE9ubHkgcmV2b2NhdGlvbiBzaWduYXR1cmVzXG5cdFx0KiBieSB0aGUgdG9wLWxldmVsIHNpZ25hdHVyZSBrZXkgdGhhdCBpcyBib3VuZCB0byB0aGlzIHN1YmtleSwgb3Jcblx0XHQqIGJ5IGFuIGF1dGhvcml6ZWQgcmV2b2NhdGlvbiBrZXksIHNob3VsZCBiZSBjb25zaWRlcmVkIHZhbGlkXG5cdFx0KiByZXZvY2F0aW9uIHNpZ25hdHVyZXMuXG5cdFx0KiBLZXkgcmV2b2NhdGlvbiBzaWduYXR1cmVzICh0eXBlcyAweDIwIGFuZCAweDI4KVxuXHRcdCogaGFzaCBvbmx5IHRoZSBrZXkgYmVpbmcgcmV2b2tlZC4gKi9cblx0XHRzdWJrZXlfcmV2b2NhdGlvbjogNDAsXG5cdFx0LyoqIDB4NDA6IFRpbWVzdGFtcCBzaWduYXR1cmUuXG5cdFx0KiBUaGlzIHNpZ25hdHVyZSBpcyBvbmx5IG1lYW5pbmdmdWwgZm9yIHRoZSB0aW1lc3RhbXAgY29udGFpbmVkIGluXG5cdFx0KiBpdC4gKi9cblx0XHR0aW1lc3RhbXA6IDY0LFxuXHRcdC8qKiAgICAweDUwOiBUaGlyZC1QYXJ0eSBDb25maXJtYXRpb24gc2lnbmF0dXJlLlxuXHRcdCogVGhpcyBzaWduYXR1cmUgaXMgYSBzaWduYXR1cmUgb3ZlciBzb21lIG90aGVyIE9wZW5QR1AgU2lnbmF0dXJlXG5cdFx0KiBwYWNrZXQocykuICBJdCBpcyBhbmFsb2dvdXMgdG8gYSBub3Rhcnkgc2VhbCBvbiB0aGUgc2lnbmVkIGRhdGEuXG5cdFx0KiBBIHRoaXJkLXBhcnR5IHNpZ25hdHVyZSBTSE9VTEQgaW5jbHVkZSBTaWduYXR1cmUgVGFyZ2V0XG5cdFx0KiBzdWJwYWNrZXQocykgdG8gZ2l2ZSBlYXN5IGlkZW50aWZpY2F0aW9uLiAgTm90ZSB0aGF0IHdlIHJlYWxseSBkb1xuXHRcdCogbWVhbiBTSE9VTEQuICBUaGVyZSBhcmUgcGxhdXNpYmxlIHVzZXMgZm9yIHRoaXMgKHN1Y2ggYXMgYSBibGluZFxuXHRcdCogcGFydHkgdGhhdCBvbmx5IHNlZXMgdGhlIHNpZ25hdHVyZSwgbm90IHRoZSBrZXkgb3Igc291cmNlXG5cdFx0KiBkb2N1bWVudCkgdGhhdCBjYW5ub3QgaW5jbHVkZSBhIHRhcmdldCBzdWJwYWNrZXQuICovXG5cdFx0dGhpcmRfcGFydHk6IDgwXG5cdH0sXG5cblx0Ly8gQXNzZXJ0cyB2YWxpZGl0eSBhbmQgY29udmVydHMgZnJvbSBzdHJpbmcvaW50ZWdlciB0byBpbnRlZ2VyLlxuXHR3cml0ZTogZnVuY3Rpb24odHlwZSwgZSkge1xuXHRcdGlmKHR5cGVvZiBlID09ICdudW1iZXInKSB7XG5cdFx0XHRlID0gdGhpcy5yZWFkKHR5cGUsIGUpO1xuXHRcdH1cblx0XHRcblx0XHRpZih0eXBlW2VdICE9IHVuZGVmaW5lZCkge1xuXHRcdFx0cmV0dXJuIHR5cGVbZV07XG5cdFx0fSBlbHNlIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBlbnVtIHZhbHVlLicpO1xuXHR9LFxuXHQvLyBDb252ZXJ0cyBmcm9tIGFuIGludGVnZXIgdG8gc3RyaW5nLlxuXHRyZWFkOiBmdW5jdGlvbih0eXBlLCBlKSB7XG5cdFx0Zm9yKHZhciBpIGluIHR5cGUpXG5cdFx0XHRpZih0eXBlW2ldID09IGUpIHJldHVybiBpO1xuXG5cdFx0dGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGVudW0gdmFsdWUuJyk7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlbnVtcztcbiIsInZhciBjcnlwdG8gPSByZXF1aXJlKCcuL2NyeXB0bycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vb3BlbnBncC5qcycpO1xubW9kdWxlLmV4cG9ydHMudXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpO1xubW9kdWxlLmV4cG9ydHMucGFja2V0ID0gcmVxdWlyZSgnLi9wYWNrZXQnKTtcbm1vZHVsZS5leHBvcnRzLm1waSA9IHJlcXVpcmUoJy4vdHlwZS9tcGkuanMnKTtcbm1vZHVsZS5leHBvcnRzLnMyayA9IHJlcXVpcmUoJy4vdHlwZS9zMmsuanMnKTtcbm1vZHVsZS5leHBvcnRzLmtleWlkID0gcmVxdWlyZSgnLi90eXBlL2tleWlkLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5hcm1vciA9IHJlcXVpcmUoJy4vZW5jb2RpbmcvYXJtb3IuanMnKTtcbm1vZHVsZS5leHBvcnRzLmVudW1zID0gcmVxdWlyZSgnLi9lbnVtcy5qcycpO1xuXG5mb3IodmFyIGkgaW4gY3J5cHRvKVxuXHRtb2R1bGUuZXhwb3J0c1tpXSA9IGNyeXB0b1tpXTtcblxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IFRoZSBvcGVucGdwIGJhc2UgY2xhc3Mgc2hvdWxkIHByb3ZpZGUgYWxsIG9mIHRoZSBmdW5jdGlvbmFsaXR5IFxuICogdG8gY29uc3VtZSB0aGUgb3BlbnBncC5qcyBsaWJyYXJ5LiBBbGwgYWRkaXRpb25hbCBjbGFzc2VzIGFyZSBkb2N1bWVudGVkIFxuICogZm9yIGV4dGVuZGluZyBhbmQgZGV2ZWxvcGluZyBvbiB0b3Agb2YgdGhlIGJhc2UgbGlicmFyeS5cbiAqL1xuXG52YXIgYXJtb3IgPSByZXF1aXJlKCcuL2VuY29kaW5nL2FybW9yLmpzJyk7XG52YXIgcGFja2V0ID0gcmVxdWlyZSgnLi9wYWNrZXQnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi91dGlsJyk7XG5cbi8qKlxuICogR1BHNEJyb3dzZXJzIENvcmUgaW50ZXJmYWNlLiBBIHNpbmdsZSBpbnN0YW5jZSBpcyBob2xkXG4gKiBmcm9tIHRoZSBiZWdpbm5pbmcuIFRvIHVzZSB0aGlzIGxpYnJhcnkgY2FsbCBcIm9wZW5wZ3AuaW5pdCgpXCJcbiAqIEBhbGlhcyBvcGVucGdwXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgTWFpbiBPcGVucGdwLmpzIGNsYXNzLiBVc2UgdGhpcyB0byBpbml0aWF0ZSBhbmQgbWFrZSBhbGwgY2FsbHMgdG8gdGhpcyBsaWJyYXJ5LlxuICovXG5mdW5jdGlvbiBfb3BlbnBncCAoKSB7XG5cdHRoaXMudG9zdHJpbmcgPSBcIlwiO1xuXHRcblx0LyoqXG5cdCAqIGluaXRpYWxpemVzIHRoZSBsaWJyYXJ5OlxuXHQgKiAtIHJlYWRpbmcgdGhlIGtleXJpbmcgZnJvbSBsb2NhbCBzdG9yYWdlXG5cdCAqIC0gcmVhZGluZyB0aGUgY29uZmlnIGZyb20gbG9jYWwgc3RvcmFnZVxuXHQgKi9cblx0ZnVuY3Rpb24gaW5pdCgpIHtcblx0XHR0aGlzLmNvbmZpZyA9IG5ldyBvcGVucGdwX2NvbmZpZygpO1xuXHRcdHRoaXMuY29uZmlnLnJlYWQoKTtcblx0XHR0aGlzLmtleXJpbmcgPSBuZXcgb3BlbnBncF9rZXlyaW5nKCk7XG5cdFx0dGhpcy5rZXlyaW5nLmluaXQoKTtcblx0fVxuXHRcblx0LyoqXG5cdCAqIHJlYWRzIG1lc3NhZ2UgcGFja2V0cyBvdXQgb2YgYW4gT3BlblBHUCBhcm1vcmVkIHRleHQgYW5kXG5cdCAqIHJldHVybnMgYW4gYXJyYXkgb2YgbWVzc2FnZSBvYmplY3RzXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBhcm1vcmVkVGV4dCB0ZXh0IHRvIGJlIHBhcnNlZFxuXHQgKiBAcmV0dXJuIHtvcGVucGdwX21zZ19tZXNzYWdlW119IG9uIGVycm9yIHRoZSBmdW5jdGlvblxuXHQgKiByZXR1cm5zIG51bGxcblx0ICovXG5cdGZ1bmN0aW9uIHJlYWRBcm1vcmVkUGFja2V0cyhhcm1vcmVkVGV4dCkge1xuICAgIC8vVE9ETyBob3cgZG8gd2Ugd2FudCB0byBoYW5kbGUgYmFkIHRleHQ/IEV4Y2VwdGlvbiB0aHJvd2luZ1xuXHRcdHZhciBpbnB1dCA9IGFybW9yLmRlY29kZShhcm1vcmVkVGV4dC5yZXBsYWNlKC9cXHIvZywnJykpLm9wZW5wZ3A7XG5cdFx0cmV0dXJuIHJlYWREZWFybW9yZWRQYWNrZXRzKGlucHV0KTtcblx0XHR9XG5cdFx0XG5cdC8qKlxuXHQgKiByZWFkcyBtZXNzYWdlIHBhY2tldHMgb3V0IG9mIGFuIE9wZW5QR1AgYXJtb3JlZCB0ZXh0IGFuZFxuXHQgKiByZXR1cm5zIGFuIGFycmF5IG9mIG1lc3NhZ2Ugb2JqZWN0cy4gQ2FuIGJlIGNhbGxlZCBleHRlcm5hbGx5IG9yIGludGVybmFsbHkuXG5cdCAqIEV4dGVybmFsIGNhbGwgd2lsbCBwYXJzZSBhIGRlLWFybW9yZWQgbWVzc2FnZWQgYW5kIHJldHVybiBtZXNzYWdlcyBmb3VuZC5cblx0ICogSW50ZXJuYWwgd2lsbCBiZSBjYWxsZWQgdG8gcmVhZCBwYWNrZXRzIHdyYXBwZWQgaW4gb3RoZXIgcGFja2V0cyAoaS5lLiBjb21wcmVzc2VkKVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgZGVhcm1vcmVkIHRleHQgb2YgT3BlblBHUCBwYWNrZXRzLCB0byBiZSBwYXJzZWRcblx0ICogQHJldHVybiB7b3BlbnBncF9tc2dfbWVzc2FnZVtdfSBvbiBlcnJvciB0aGUgZnVuY3Rpb25cblx0ICogcmV0dXJucyBudWxsXG5cdCAqL1xuXHRmdW5jdGlvbiByZWFkRGVhcm1vcmVkUGFja2V0cyhpbnB1dCl7XG4gICAgdmFyIHBhY2tldExpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgICBwYWNrZXRMaXN0LnJlYWQoaW5wdXQpO1xuICAgIHJldHVybiBwYWNrZXRMaXN0O1xuXHR9XG5cbiAgZnVuY3Rpb24gZW5jcnlwdE1lc3NhZ2UocHVibGljS2V5UGFja2V0bGlzdCwgbWVzc2FnZSkge1xuXG4gIH1cblxuICBmdW5jdGlvbiBlbmNyeXB0QW5kU2lnbk1lc3NhZ2UocHVibGljS2V5UGFja2V0bGlzdCwgcHJpdmF0ZUtleVBhY2tldGxpc3QsIG1lc3NhZ2UpIHtcblxuICB9XG5cbiAgZnVuY3Rpb24gZGVjcnlwdE1lc3NhZ2UocHJpdmF0ZUtleVBhY2tldGxpc3QsIG1lc3NhZ2VQYWNrZXRsaXN0KSB7XG5cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlY3J5cHRBbmRWZXJpZnlNZXNzYWdlKHByaXZhdGVLZXlQYWNrZXRsaXN0LCBwdWJsaWNLZXlQYWNrZXRsaXN0LCBtZXNzYWdlUGFja2V0bGlzdCkge1xuXG4gIH1cblxuICBmdW5jdGlvbiB2ZXJpZnlNZXNzYWdlKHB1YmxpY0tleVBhY2tldGxpc3QsIG1lc3NhZ2VQYWNrZXRsaXN0KSB7XG5cbiAgfVxuXG4gIGZ1bmN0aW9uIHNpZ25NZXNzYWdlKHByaXZhdGVLZXlQYWNrZXRsaXN0LCBtZXNzYWdlUGFja2V0bGlzdCkge1xuXG4gIH1cblxuXHRmdW5jdGlvbiBnZW5lcmF0ZUtleVBhaXIoa2V5VHlwZSwgbnVtQml0cywgdXNlcklkLCBwYXNzcGhyYXNlKSB7XG4gICAgZGVidWdnZXI7XG4gICAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcblxuICAgIHZhciBzZWNyZXRLZXlQYWNrZXQgPSBuZXcgcGFja2V0LnNlY3JldF9rZXkoKTtcbiAgICB2YXIgdXNlcklkUGFja2V0ID0gbmV3IHBhY2tldC51c2VyaWQoKTtcbiAgICB2YXIgc2lnbmF0dXJlUGFja2V0ID0gbmV3IHBhY2tldC5zaWduYXR1cmUoKTtcbiAgICB2YXIgc2VjcmV0U3Via2V5UGFja2V0ID0gbmV3IHBhY2tldC5zZWNyZXRfc3Via2V5KCk7XG4gICAgdmFyIG92ZXJhbGxTaWduYXR1cmVQYWNrZXQgPSBuZXcgcGFja2V0LnNpZ25hdHVyZSgpO1xuXG4gIH1cblx0XG5cdC8qKlxuXHQgKiBjcmVhdGVzIGEgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhbiBlbmNyeXB0ZWQgYW5kIHNpZ25lZCBtZXNzYWdlLlxuXHQgKiBUaGUgbWVzc2FnZSB3aWxsIGJlIGVuY3J5cHRlZCB3aXRoIHRoZSBwdWJsaWMga2V5cyBzcGVjaWZpZWQgYW5kIHNpZ25lZFxuXHQgKiB3aXRoIHRoZSBzcGVjaWZpZWQgcHJpdmF0ZSBrZXkuXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwcml2YXRla2V5IHtvYmo6IFtvcGVucGdwX21zZ19wcml2YXRla2V5XX0gUHJpdmF0ZSBrZXkgXG5cdCAqIHRvIGJlIHVzZWQgdG8gc2lnbiB0aGUgbWVzc2FnZVxuXHQgKiBAcGFyYW0ge09iamVjdFtdfSBwdWJsaWNrZXlzIEFuIGFycmFmIG9mIHtvYmo6IFtvcGVucGdwX21zZ19wdWJsaWNrZXldfVxuXHQgKiAtIHB1YmxpYyBrZXlzIHRvIGJlIHVzZWQgdG8gZW5jcnlwdCB0aGUgbWVzc2FnZSBcblx0ICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2V0ZXh0IG1lc3NhZ2UgdGV4dCB0byBlbmNyeXB0IGFuZCBzaWduXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gYSBiaW5hcnkgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZXNzYWdlIHdoaWNoIFxuXHQgKiBjYW4gYmUgT3BlblBHUCBhcm1vcmVkXG5cdCAqL1xuXHRmdW5jdGlvbiB3cml0ZV9zaWduZWRfYW5kX2VuY3J5cHRlZF9tZXNzYWdlKHByaXZhdGVrZXksIHB1YmxpY2tleXMsIG1lc3NhZ2V0ZXh0KSB7XG5cdFx0dmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgdmFyIGk7XG5cdFx0dmFyIGxpdGVyYWwgPSBuZXcgb3BlbnBncF9wYWNrZXRfbGl0ZXJhbGRhdGEoKS53cml0ZV9wYWNrZXQobWVzc2FnZXRleHQucmVwbGFjZSgvXFxyXFxuL2csXCJcXG5cIikucmVwbGFjZSgvXFxuL2csXCJcXHJcXG5cIikpO1xuXHRcdHV0aWwucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAoXCJsaXRlcmFsX3BhY2tldDogfFwiK2xpdGVyYWwrXCJ8XFxuXCIsbGl0ZXJhbCk7XG5cdFx0Zm9yIChpID0gMDsgaSA8IHB1YmxpY2tleXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBvbmVwYXNzc2lnbmF0dXJlID0gbmV3IG9wZW5wZ3BfcGFja2V0X29uZXBhc3NzaWduYXR1cmUoKTtcblx0XHRcdHZhciBvbmVwYXNzc2lnc3RyID0gXCJcIjtcblx0XHRcdGlmIChpID09PSAwKVxuXHRcdFx0XHRvbmVwYXNzc2lnc3RyID0gb25lcGFzc3NpZ25hdHVyZS53cml0ZV9wYWNrZXQoMSwgb3BlbnBncC5jb25maWcuY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobSwgIHByaXZhdGVrZXksIGZhbHNlKTtcblx0XHRcdGVsc2Vcblx0XHRcdFx0b25lcGFzc3NpZ3N0ciA9IG9uZXBhc3NzaWduYXR1cmUud3JpdGVfcGFja2V0KDEsIG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG0sICBwcml2YXRla2V5LCBmYWxzZSk7XG5cdFx0XHR1dGlsLnByaW50X2RlYnVnX2hleHN0cl9kdW1wKFwib25lcGFzc3NpZ3N0cjogfFwiK29uZXBhc3NzaWdzdHIrXCJ8XFxuXCIsb25lcGFzc3NpZ3N0cik7XG5cdFx0XHR2YXIgZGF0YXNpZ25hdHVyZSA9IG5ldyBvcGVucGdwX3BhY2tldF9zaWduYXR1cmUoKS53cml0ZV9tZXNzYWdlX3NpZ25hdHVyZSgxLCBtZXNzYWdldGV4dC5yZXBsYWNlKC9cXHJcXG4vZyxcIlxcblwiKS5yZXBsYWNlKC9cXG4vZyxcIlxcclxcblwiKSwgcHJpdmF0ZWtleSk7XG5cdFx0XHR1dGlsLnByaW50X2RlYnVnX2hleHN0cl9kdW1wKFwiZGF0YXNpZ25hdHVyZTogfFwiK2RhdGFzaWduYXR1cmUub3BlbnBncCtcInxcXG5cIixkYXRhc2lnbmF0dXJlLm9wZW5wZ3ApO1xuXHRcdFx0aWYgKGkgPT09IDApIHtcblx0XHRcdFx0cmVzdWx0ID0gb25lcGFzc3NpZ3N0citsaXRlcmFsK2RhdGFzaWduYXR1cmUub3BlbnBncDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJlc3VsdCA9IG9uZXBhc3NzaWdzdHIrcmVzdWx0K2RhdGFzaWduYXR1cmUub3BlbnBncDtcblx0XHRcdH1cblx0XHR9XG5cdFx0XG5cdFx0dXRpbC5wcmludF9kZWJ1Z19oZXhzdHJfZHVtcChcInNpZ25lZCBwYWNrZXQ6IHxcIityZXN1bHQrXCJ8XFxuXCIscmVzdWx0KTtcblx0XHQvLyBzaWduYXR1cmVzIGRvbmUuLiBub3cgZW5jcnlwdGlvblxuXHRcdHZhciBzZXNzaW9ua2V5ID0gb3BlbnBncF9jcnlwdG9fZ2VuZXJhdGVTZXNzaW9uS2V5KG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlcik7IFxuXHRcdHZhciByZXN1bHQyID0gXCJcIjtcblx0XHRcblx0XHQvLyBjcmVhdGluZyBzZXNzaW9uIGtleXMgZm9yIGVhY2ggcmVjaXBpZW50XG5cdFx0Zm9yIChpID0gMDsgaSA8IHB1YmxpY2tleXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBwa2V5ID0gcHVibGlja2V5c1tpXS5nZXRFbmNyeXB0aW9uS2V5KCk7XG5cdFx0XHRpZiAocGtleSA9PT0gbnVsbCkge1xuXHRcdFx0XHR1dGlsLnByaW50X2Vycm9yKFwibm8gZW5jcnlwdGlvbiBrZXkgZm91bmQhIEtleSBpcyBmb3Igc2lnbmluZyBvbmx5LlwiKTtcblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHR9XG5cdFx0XHRyZXN1bHQyICs9IG5ldyBvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRzZXNzaW9ua2V5KCkuXG5cdFx0XHRcdFx0d3JpdGVfcHViX2tleV9wYWNrZXQoXG5cdFx0XHRcdFx0XHRwa2V5LmdldEtleUlkKCksXG5cdFx0XHRcdFx0XHRwa2V5Lk1QSXMsXG5cdFx0XHRcdFx0XHRwa2V5LnB1YmxpY0tleUFsZ29yaXRobSxcblx0XHRcdFx0XHRcdG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlcixcblx0XHRcdFx0XHRcdHNlc3Npb25rZXkpO1xuXHRcdH1cblx0XHRpZiAob3BlbnBncC5jb25maWcuY29uZmlnLmludGVncml0eV9wcm90ZWN0KSB7XG5cdFx0XHRyZXN1bHQyICs9IG5ldyBvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRpbnRlZ3JpdHlwcm90ZWN0ZWRkYXRhKCkud3JpdGVfcGFja2V0KG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlciwgc2Vzc2lvbmtleSwgcmVzdWx0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmVzdWx0MiArPSBuZXcgb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YSgpLndyaXRlX3BhY2tldChvcGVucGdwLmNvbmZpZy5jb25maWcuZW5jcnlwdGlvbl9jaXBoZXIsIHNlc3Npb25rZXksIHJlc3VsdCk7XG5cdFx0fVxuXHRcdHJldHVybiBhcm1vci5lbmNvZGUoMyxyZXN1bHQyLG51bGwsbnVsbCk7XG5cdH1cblx0LyoqXG5cdCAqIGNyZWF0ZXMgYSBiaW5hcnkgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGFuIGVuY3J5cHRlZCBtZXNzYWdlLlxuXHQgKiBUaGUgbWVzc2FnZSB3aWxsIGJlIGVuY3J5cHRlZCB3aXRoIHRoZSBwdWJsaWMga2V5cyBzcGVjaWZpZWQgXG5cdCAqIEBwYXJhbSB7T2JqZWN0W119IHB1YmxpY2tleXMgQW4gYXJyYXkgb2Yge29iajogW29wZW5wZ3BfbXNnX3B1YmxpY2tleV19XG5cdCAqIC1wdWJsaWMga2V5cyB0byBiZSB1c2VkIHRvIGVuY3J5cHQgdGhlIG1lc3NhZ2UgXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdldGV4dCBtZXNzYWdlIHRleHQgdG8gZW5jcnlwdFxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IGEgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWVzc2FnZVxuXHQgKiB3aGljaCBjYW4gYmUgT3BlblBHUCBhcm1vcmVkXG5cdCAqL1xuXHRmdW5jdGlvbiB3cml0ZV9lbmNyeXB0ZWRfbWVzc2FnZShwdWJsaWNrZXlzLCBtZXNzYWdldGV4dCkge1xuXHRcdHZhciByZXN1bHQgPSBcIlwiO1xuXHRcdHZhciBsaXRlcmFsID0gbmV3IG9wZW5wZ3BfcGFja2V0X2xpdGVyYWxkYXRhKCkud3JpdGVfcGFja2V0KG1lc3NhZ2V0ZXh0LnJlcGxhY2UoL1xcclxcbi9nLFwiXFxuXCIpLnJlcGxhY2UoL1xcbi9nLFwiXFxyXFxuXCIpKTtcblx0XHR1dGlsLnByaW50X2RlYnVnX2hleHN0cl9kdW1wKFwibGl0ZXJhbF9wYWNrZXQ6IHxcIitsaXRlcmFsK1wifFxcblwiLGxpdGVyYWwpO1xuXHRcdHJlc3VsdCA9IGxpdGVyYWw7XG5cdFx0XG5cdFx0Ly8gc2lnbmF0dXJlcyBkb25lLi4gbm93IGVuY3J5cHRpb25cblx0XHR2YXIgc2Vzc2lvbmtleSA9IG9wZW5wZ3BfY3J5cHRvX2dlbmVyYXRlU2Vzc2lvbktleShvcGVucGdwLmNvbmZpZy5jb25maWcuZW5jcnlwdGlvbl9jaXBoZXIpOyBcblx0XHR2YXIgcmVzdWx0MiA9IFwiXCI7XG5cdFx0XG5cdFx0Ly8gY3JlYXRpbmcgc2Vzc2lvbiBrZXlzIGZvciBlYWNoIHJlY2lwaWVudFxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgcHVibGlja2V5cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0dmFyIHBrZXkgPSBwdWJsaWNrZXlzW2ldLmdldEVuY3J5cHRpb25LZXkoKTtcblx0XHRcdGlmIChwa2V5ID09PSBudWxsKSB7XG5cdFx0XHRcdHV0aWwucHJpbnRfZXJyb3IoXCJubyBlbmNyeXB0aW9uIGtleSBmb3VuZCEgS2V5IGlzIGZvciBzaWduaW5nIG9ubHkuXCIpO1xuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdH1cblx0XHRcdHJlc3VsdDIgKz0gbmV3IG9wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZHNlc3Npb25rZXkoKS5cblx0XHRcdFx0XHR3cml0ZV9wdWJfa2V5X3BhY2tldChcblx0XHRcdFx0XHRcdHBrZXkuZ2V0S2V5SWQoKSxcblx0XHRcdFx0XHRcdHBrZXkuTVBJcyxcblx0XHRcdFx0XHRcdHBrZXkucHVibGljS2V5QWxnb3JpdGhtLFxuXHRcdFx0XHRcdFx0b3BlbnBncC5jb25maWcuY29uZmlnLmVuY3J5cHRpb25fY2lwaGVyLFxuXHRcdFx0XHRcdFx0c2Vzc2lvbmtleSk7XG5cdFx0fVxuXHRcdGlmIChvcGVucGdwLmNvbmZpZy5jb25maWcuaW50ZWdyaXR5X3Byb3RlY3QpIHtcblx0XHRcdHJlc3VsdDIgKz0gbmV3IG9wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGludGVncml0eXByb3RlY3RlZGRhdGEoKS53cml0ZV9wYWNrZXQob3BlbnBncC5jb25maWcuY29uZmlnLmVuY3J5cHRpb25fY2lwaGVyLCBzZXNzaW9ua2V5LCByZXN1bHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXN1bHQyICs9IG5ldyBvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhKCkud3JpdGVfcGFja2V0KG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlciwgc2Vzc2lvbmtleSwgcmVzdWx0KTtcblx0XHR9XG5cdFx0cmV0dXJuIGFybW9yLmVuY29kZSgzLHJlc3VsdDIsbnVsbCxudWxsKTtcblx0fVxuXHRcblx0LyoqXG5cdCAqIGNyZWF0ZXMgYSBiaW5hcnkgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGEgc2lnbmVkIG1lc3NhZ2UuXG5cdCAqIFRoZSBtZXNzYWdlIHdpbGwgYmUgc2lnbmVkIHdpdGggdGhlIHNwZWNpZmllZCBwcml2YXRlIGtleS5cblx0ICogQHBhcmFtIHtPYmplY3R9IHByaXZhdGVrZXkge29iajogW29wZW5wZ3BfbXNnX3ByaXZhdGVrZXldfVxuXHQgKiAtIHRoZSBwcml2YXRlIGtleSB0byBiZSB1c2VkIHRvIHNpZ24gdGhlIG1lc3NhZ2UgXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdldGV4dCBtZXNzYWdlIHRleHQgdG8gc2lnblxuXHQgKiBAcmV0dXJuIHtPYmplY3R9IHtPYmplY3Q6IHRleHQgW1N0cmluZ119LCBvcGVucGdwOiB7U3RyaW5nfSBhIGJpbmFyeVxuXHQgKiAgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZXNzYWdlIHdoaWNoIGNhbiBiZSBPcGVuUEdQXG5cdCAqICAgYXJtb3JlZChvcGVucGdwKSBhbmQgYSB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZXNzYWdlICh0ZXh0KS4gXG5cdCAqIFRoaXMgY2FuIGJlIGRpcmVjdGx5IHVzZWQgdG8gT3BlblBHUCBhcm1vciB0aGUgbWVzc2FnZVxuXHQgKi9cblx0ZnVuY3Rpb24gd3JpdGVfc2lnbmVkX21lc3NhZ2UocHJpdmF0ZWtleSwgbWVzc2FnZXRleHQpIHtcblx0XHR2YXIgc2lnID0gbmV3IG9wZW5wZ3BfcGFja2V0X3NpZ25hdHVyZSgpLndyaXRlX21lc3NhZ2Vfc2lnbmF0dXJlKDEsIG1lc3NhZ2V0ZXh0LnJlcGxhY2UoL1xcclxcbi9nLFwiXFxuXCIpLnJlcGxhY2UoL1xcbi8sXCJcXHJcXG5cIiksIHByaXZhdGVrZXkpO1xuXHRcdHZhciByZXN1bHQgPSB7dGV4dDogbWVzc2FnZXRleHQucmVwbGFjZSgvXFxyXFxuL2csXCJcXG5cIikucmVwbGFjZSgvXFxuLyxcIlxcclxcblwiKSwgb3BlbnBncDogc2lnLm9wZW5wZ3AsIGhhc2g6IHNpZy5oYXNofTtcblx0XHRyZXR1cm4gYXJtb3IuZW5jb2RlKDIscmVzdWx0LCBudWxsLCBudWxsKTtcblx0fVxuXHRcblx0LyoqXG5cdCAqIGdlbmVyYXRlcyBhIG5ldyBrZXkgcGFpciBmb3Igb3BlbnBncC4gQmV0YSBzdGFnZS4gQ3VycmVudGx5IG9ubHkgXG5cdCAqIHN1cHBvcnRzIFJTQSBrZXlzLCBhbmQgbm8gc3Via2V5cy5cblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBrZXlUeXBlIHRvIGluZGljYXRlIHdoYXQgdHlwZSBvZiBrZXkgdG8gbWFrZS4gXG5cdCAqIFJTQSBpcyAxLiBGb2xsb3dzIGFsZ29yaXRobXMgb3V0bGluZWQgaW4gT3BlblBHUC5cblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBudW1CaXRzIG51bWJlciBvZiBiaXRzIGZvciB0aGUga2V5IGNyZWF0aW9uLiAoc2hvdWxkIFxuXHQgKiBiZSAxMDI0KywgZ2VuZXJhbGx5KVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gdXNlcklkIGFzc3VtZXMgYWxyZWFkeSBpbiBmb3JtIG9mIFwiVXNlciBOYW1lIFxuXHQgKiA8dXNlcm5hbWVAZW1haWwuY29tPlwiXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzcGhyYXNlIFRoZSBwYXNzcGhyYXNlIHVzZWQgdG8gZW5jcnlwdCB0aGUgcmVzdWx0aW5nIHByaXZhdGUga2V5XG5cdCAqIEByZXR1cm4ge09iamVjdH0ge3ByaXZhdGVLZXk6IFtvcGVucGdwX21zZ19wcml2YXRla2V5XSwgXG5cdCAqIHByaXZhdGVLZXlBcm1vcmVkOiBbc3RyaW5nXSwgcHVibGljS2V5QXJtb3JlZDogW3N0cmluZ119XG5cdCAqL1xuXHRmdW5jdGlvbiBnZW5lcmF0ZV9rZXlfcGFpcihrZXlUeXBlLCBudW1CaXRzLCB1c2VySWQsIHBhc3NwaHJhc2Upe1xuXHRcdHZhciB1c2VySWRQYWNrZXQgPSBuZXcgb3BlbnBncF9wYWNrZXRfdXNlcmlkKCk7XG5cdFx0dmFyIHVzZXJJZFN0cmluZyA9IHVzZXJJZFBhY2tldC53cml0ZV9wYWNrZXQodXNlcklkKTtcblx0XHRcblx0XHR2YXIga2V5UGFpciA9IG9wZW5wZ3BfY3J5cHRvX2dlbmVyYXRlS2V5UGFpcihrZXlUeXBlLG51bUJpdHMsIHBhc3NwaHJhc2UsIG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG0sIDMpO1xuXHRcdHZhciBwcml2S2V5U3RyaW5nID0ga2V5UGFpci5wcml2YXRlS2V5O1xuXHRcdHZhciBwcml2S2V5UGFja2V0ID0gbmV3IG9wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsKCkucmVhZF9wcml2X2tleShwcml2S2V5U3RyaW5nLnN0cmluZywzLHByaXZLZXlTdHJpbmcuc3RyaW5nLmxlbmd0aCk7XG5cdFx0aWYoIXByaXZLZXlQYWNrZXQuZGVjcnlwdFNlY3JldE1QSXMocGFzc3BocmFzZSkpXG4gICAgICB1dGlsLnByaW50X2Vycm9yKCdJc3N1ZSBjcmVhdGluZyBrZXkuIFVuYWJsZSB0byByZWFkIHJlc3VsdGluZyBwcml2YXRlIGtleScpO1xuXHRcdHZhciBwcml2S2V5ID0gbmV3IG9wZW5wZ3BfbXNnX3ByaXZhdGVrZXkoKTtcblx0XHRwcml2S2V5LnByaXZhdGVLZXlQYWNrZXQgPSBwcml2S2V5UGFja2V0O1xuXHRcdHByaXZLZXkuZ2V0UHJlZmVycmVkU2lnbmF0dXJlSGFzaEFsZ29yaXRobSA9IGZ1bmN0aW9uKCl7cmV0dXJuIG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG19Oy8vbmVlZCB0byBvdmVycmlkZSB0aGlzIHRvIHNvbHZlIGNhdGNoIDIyIHRvIGdlbmVyYXRlIHNpZ25hdHVyZS4gOCBpcyB2YWx1ZSBmb3IgU0hBMjU2XG5cdFx0XG5cdFx0dmFyIHB1YmxpY0tleVN0cmluZyA9IHByaXZLZXkucHJpdmF0ZUtleVBhY2tldC5wdWJsaWNLZXkuZGF0YTtcblx0XHR2YXIgaGFzaERhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4OTkpKyBTdHJpbmcuZnJvbUNoYXJDb2RlKCgocHVibGljS2V5U3RyaW5nLmxlbmd0aCkgPj4gOCkgJiAweEZGKSBcblx0XHRcdCsgU3RyaW5nLmZyb21DaGFyQ29kZSgocHVibGljS2V5U3RyaW5nLmxlbmd0aCkgJiAweEZGKSArcHVibGljS2V5U3RyaW5nK1N0cmluZy5mcm9tQ2hhckNvZGUoMHhCNCkgK1xuXHRcdFx0U3RyaW5nLmZyb21DaGFyQ29kZSgodXNlcklkLmxlbmd0aCkgPj4gMjQpICtTdHJpbmcuZnJvbUNoYXJDb2RlKCgodXNlcklkLmxlbmd0aCkgPj4gMTYpICYgMHhGRikgXG5cdFx0XHQrIFN0cmluZy5mcm9tQ2hhckNvZGUoKCh1c2VySWQubGVuZ3RoKSA+PiA4KSAmIDB4RkYpICsgU3RyaW5nLmZyb21DaGFyQ29kZSgodXNlcklkLmxlbmd0aCkgJiAweEZGKSArIHVzZXJJZDtcblx0XHR2YXIgc2lnbmF0dXJlID0gbmV3IG9wZW5wZ3BfcGFja2V0X3NpZ25hdHVyZSgpO1xuXHRcdHNpZ25hdHVyZSA9IHNpZ25hdHVyZS53cml0ZV9tZXNzYWdlX3NpZ25hdHVyZSgxNixoYXNoRGF0YSwgcHJpdktleSk7XG5cdFx0dmFyIHB1YmxpY0FybW9yZWQgPSBhcm1vci5lbmNvZGUoNCwga2V5UGFpci5wdWJsaWNLZXkuc3RyaW5nICsgdXNlcklkU3RyaW5nICsgc2lnbmF0dXJlLm9wZW5wZ3AgKTtcblxuXHRcdHZhciBwcml2QXJtb3JlZCA9IGFybW9yLmVuY29kZSg1LHByaXZLZXlTdHJpbmcuc3RyaW5nK3VzZXJJZFN0cmluZytzaWduYXR1cmUub3BlbnBncCk7XG5cdFx0XG5cdFx0cmV0dXJuIHtwcml2YXRlS2V5IDogcHJpdktleSwgcHJpdmF0ZUtleUFybW9yZWQ6IHByaXZBcm1vcmVkLCBwdWJsaWNLZXlBcm1vcmVkOiBwdWJsaWNBcm1vcmVkfTtcblx0fVxuXHRcblx0dGhpcy5nZW5lcmF0ZUtleVBhaXIgPSBnZW5lcmF0ZUtleVBhaXI7XG5cdHRoaXMud3JpdGVfc2lnbmVkX21lc3NhZ2UgPSB3cml0ZV9zaWduZWRfbWVzc2FnZTsgXG5cdHRoaXMud3JpdGVfc2lnbmVkX2FuZF9lbmNyeXB0ZWRfbWVzc2FnZSA9IHdyaXRlX3NpZ25lZF9hbmRfZW5jcnlwdGVkX21lc3NhZ2U7XG5cdHRoaXMud3JpdGVfZW5jcnlwdGVkX21lc3NhZ2UgPSB3cml0ZV9lbmNyeXB0ZWRfbWVzc2FnZTtcblx0dGhpcy5yZWFkQXJtb3JlZFBhY2tldHMgPSByZWFkQXJtb3JlZFBhY2tldHM7XG5cdHRoaXMucmVhZERlYXJtb3JlZFBhY2tldHMgPSByZWFkRGVhcm1vcmVkUGFja2V0cztcblx0dGhpcy5pbml0ID0gaW5pdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgX29wZW5wZ3AoKTtcblxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0Jyk7XG52YXIgZW51bXMgPSByZXF1aXJlKCcuL2VudW1zLmpzJyk7XG52YXIgYXJtb3IgPSByZXF1aXJlKCcuL2VuY29kaW5nL2FybW9yLmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIFRoZSBjbGFzcyB0aGF0IGRlYWxzIHdpdGggc3RvcmFnZSBvZiB0aGUga2V5cmluZy4gQ3VycmVudGx5IHRoZSBvbmx5IG9wdGlvbiBpcyB0byB1c2UgSFRNTDUgbG9jYWwgc3RvcmFnZS5cbiAqL1xudmFyIGtleXJpbmcgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5hcm1vcmVkUGFja2V0bGlzdHMgPSBbXTtcbiAgdGhpcy5wYXJzZWRQYWNrZXRsaXN0cyA9IFtdO1xuXHRcdFxuXHQvKipcblx0ICogSW5pdGlhbGl6YXRpb24gcm91dGluZSBmb3IgdGhlIGtleXJpbmcuIFRoaXMgbWV0aG9kIHJlYWRzIHRoZSBcblx0ICoga2V5cmluZyBmcm9tIEhUTUw1IGxvY2FsIHN0b3JhZ2UgYW5kIGluaXRpYWxpemVzIHRoaXMgaW5zdGFuY2UuXG5cdCAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSBvcGVucGdwLmluaXQoKS5cblx0ICovXG5cdGZ1bmN0aW9uIGluaXQoKSB7XG5cdFx0dmFyIGFybW9yZWRQYWNrZXRsaXN0cyA9IEpTT04ucGFyc2Uod2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKFwiYXJtb3JlZFBhY2tldGxpc3RzXCIpKTtcblx0XHRpZiAoYXJtb3JlZFBhY2tldGxpc3RzID09PSBudWxsIHx8IGFybW9yZWRQYWNrZXRsaXN0cy5sZW5ndGggPT09IDApIHtcblx0XHRcdGFybW9yZWRQYWNrZXRsaXN0cyA9IFtdO1xuXHRcdH1cbiAgICB0aGlzLmFybW9yZWRQYWNrZXRsaXN0cyA9IGFybW9yZWRQYWNrZXRsaXN0cztcblxuICAgIHZhciBwYWNrZXRsaXN0O1xuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgYXJtb3JlZFBhY2tldGxpc3RzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRwYWNrZXRsaXN0ID0gbmV3IHBhY2tldC5saXN0KCk7XG4gICAgICBwYWNrZXRsaXN0LnJlYWQoYXJtb3JlZFBhY2tldGxpc3RzW2ldKTtcblx0XHRcdHRoaXMucGFyc2VkUGFja2V0bGlzdHMucHVzaChwYWNrZXRsaXN0KTtcblx0XHR9XG4gIH1cblx0dGhpcy5pbml0ID0gaW5pdDtcblxuXHQvKipcblx0ICogU2F2ZXMgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGtleXJpbmcgdG8gSFRNTDUgbG9jYWwgc3RvcmFnZS5cblx0ICogVGhlIHByaXZhdGVLZXlzIGFycmF5IGFuZCBwdWJsaWNLZXlzIGFycmF5IGdldHMgU3RyaW5naWZpZWQgdXNpbmcgSlNPTlxuXHQgKi9cblx0ZnVuY3Rpb24gc3RvcmUoKSB7IFxuXHRcdHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShcImFybW9yZWRQYWNrZXRsaXN0c1wiLCBKU09OLnN0cmluZ2lmeSh0aGlzLmFybW9yZWRQYWNrZXRsaXN0cykpO1xuXHR9XG5cdHRoaXMuc3RvcmUgPSBzdG9yZTtcblxuICBmdW5jdGlvbiBlbWFpbFBhY2tldENoZWNrKHBhY2tldCwgZW1haWwpIHtcbiAgICB2YXIgZW1haWxNYXRjaCA9IGZhbHNlO1xuICAgIHZhciBwYWNrZXRFbWFpbDtcbiAgICBlbWFpbCA9IGVtYWlsLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKHBhY2tldC50YWcgPT0gZW51bXMucGFja2V0LnVzZXJpZCkge1xuICAgICAgcGFja2V0RW1haWwgPSBwYWNrZXQudXNlcmlkO1xuICAgICAgLy93ZSBuZWVkIHRvIGdldCBqdXN0IHRoZSBlbWFpbCBmcm9tIHRoZSB1c2VyaWQgcGFja2V0XG4gICAgICBwYWNrZXRFbWFpbCA9IHBhY2tldEVtYWlsLnNwbGl0KCc8JylbMV0uc3BsaXQoJzwnKVswXS50cmltLnRvTG93ZXJDYXNlKCk7XG4gICAgICBpZiAocGFja2V0RW1haWwgPT0gZW1haWwpIHtcbiAgICAgICAgZW1haWxNYXRjaCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBlbWFpbE1hdGNoO1xuICB9XG5cbiAgZnVuY3Rpb24gaWRQYWNrZXRDaGVjayhwYWNrZXQsIGlkKSB7XG4gICAgaWYgKHBhY2tldC5nZXRLZXlJZCAmJiBwYWNrZXQuZ2V0S2V5SWQoKSA9PSBpZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhlbHBlckNoZWNrSWRlbnRpdHlBbmRQYWNrZXRNYXRjaChpZGVudGl0eUZ1bmN0aW9uLCBpZGVudGl0eUlucHV0LCBwYWNrZXRUeXBlLCBwYWNrZXRsaXN0KSB7XG4gICAgdmFyIHBhY2tldDtcbiAgICBmb3IgKHZhciBsID0gMDsgbCA8IHBhY2tldGxpc3QubGVuZ3RoOyBsKyspIHtcbiAgICAgIHBhY2tldCA9IHBhY2tldGxpc3RbbF07XG4gICAgICBpZGVudGl0eU1hdGNoID0gaWRlbnRpdHlGdW5jdGlvbihwYWNrZXQsIGlkZW50aXR5SW5wdXQpO1xuICAgICAgaWYgKCFwYWNrZXRUeXBlKSB7XG4gICAgICAgIHBhY2tldE1hdGNoID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHBhY2tldC50YWcgPT0gcGFja2V0VHlwZSkge1xuICAgICAgICBwYWNrZXRNYXRjaCA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAocGFja2V0TWF0Y2ggJiYgaWRlbnRpdHlNYXRjaCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gY2hlY2tGb3JJZGVudGl0eUFuZFBhY2tldE1hdGNoKGlkZW50aXR5RnVuY3Rpb24sIGlkZW50aXR5SW5wdXQsIHBhY2tldFR5cGUpIHtcblx0XHR2YXIgcmVzdWx0cyA9IFtdO1xuICAgIHZhciBwYWNrZXRsaXN0O1xuICAgIHZhciBpZGVudGl0eU1hdGNoO1xuICAgIHZhciBwYWNrZXRNYXRjaDtcbiAgICBmb3IgKHZhciBwID0gMDsgcCA8IHRoaXMucGFyc2VkUGFja2V0bGlzdHMubGVuZ3RoOyBwKyspIHtcbiAgICAgIGlkZW50aXR5TWF0Y2ggPSBmYWxzZTtcbiAgICAgIHBhY2tldE1hdGNoID0gZmFsc2U7XG4gICAgICBwYWNrZXRsaXN0ID0gdGhpcy5wYXJzZWRQYWNrZXRsaXN0c1twXTtcbiAgICAgIGlmIChoZWxwZXJDaGVja0lkZW50aXR5QW5kUGFja2V0TWF0Y2goaWRlbnRpdHlGdW5jdGlvbiwgaWRlbnRpdHlJbnB1dCwgcGFja2V0VHlwZSwgcGFja2V0bGlzdCkpIHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKHBhY2tldGxpc3QpO1xuICAgICAgfVxuICAgIH1cblx0XHRyZXR1cm4gcmVzdWx0cztcbiAgfVxuICB0aGlzLmNoZWNrRm9ySWRlbnRpdHlBbmRQYWNrZXRNYXRjaCA9IGNoZWNrRm9ySWRlbnRpdHlBbmRQYWNrZXRNYXRjaDtcblxuXHQvKipcblx0ICogc2VhcmNoZXMgYWxsIHB1YmxpYyBrZXlzIGluIHRoZSBrZXlyaW5nIG1hdGNoaW5nIHRoZSBhZGRyZXNzIG9yIGFkZHJlc3MgcGFydCBvZiB0aGUgdXNlciBpZHNcblx0ICogQHBhcmFtIHtTdHJpbmd9IGVtYWlsX2FkZHJlc3Ncblx0ICogQHJldHVybiB7b3BlbnBncF9tc2dfcHVibGlja2V5W119IFRoZSBwdWJsaWMga2V5cyBhc3NvY2lhdGVkIHdpdGggcHJvdmlkZWQgZW1haWwgYWRkcmVzcy5cblx0ICovXG5cdGZ1bmN0aW9uIGdldFB1YmxpY0tleUZvckFkZHJlc3MoZW1haWwpIHtcbiAgICByZXR1cm4gY2hlY2tGb3JJZGVudGl0eUFuZFBhY2tldE1hdGNoKGVtYWlsUGFja2V0Q2hlY2ssIGVtYWlsLCBlbnVtcy5wYWNrZXQucHVibGljX2tleSk7XG5cdH1cblx0dGhpcy5nZXRQdWJsaWNLZXlGb3JBZGRyZXNzID0gZ2V0UHVibGljS2V5Rm9yQWRkcmVzcztcblxuXHQvKipcblx0ICogU2VhcmNoZXMgdGhlIGtleXJpbmcgZm9yIGEgcHJpdmF0ZSBrZXkgY29udGFpbmluZyB0aGUgc3BlY2lmaWVkIGVtYWlsIGFkZHJlc3Ncblx0ICogQHBhcmFtIHtTdHJpbmd9IGVtYWlsX2FkZHJlc3MgZW1haWwgYWRkcmVzcyB0byBzZWFyY2ggZm9yXG5cdCAqIEByZXR1cm4ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXlbXX0gcHJpdmF0ZSBrZXlzIGZvdW5kXG5cdCAqL1xuXHRmdW5jdGlvbiBnZXRQcml2YXRlS2V5Rm9yQWRkcmVzcyhlbWFpbF9hZGRyZXNzKSB7XG4gICAgcmV0dXJuIGNoZWNrRm9ySWRlbnRpdHlBbmRQYWNrZXRNYXRjaChlbWFpbFBhY2tldENoZWNrLCBlbWFpbCwgZW51bXMucGFja2V0LnNlY3JldF9rZXkpO1xuXHR9XG5cdHRoaXMuZ2V0UHJpdmF0ZUtleUZvckFkZHJlc3MgPSBnZXRQcml2YXRlS2V5Rm9yQWRkcmVzcztcblxuXHQvKipcblx0ICogU2VhcmNoZXMgdGhlIGtleXJpbmcgZm9yIHB1YmxpYyBrZXlzIGhhdmluZyB0aGUgc3BlY2lmaWVkIGtleSBpZFxuXHQgKiBAcGFyYW0ge1N0cmluZ30ga2V5SWQgcHJvdmlkZWQgYXMgc3RyaW5nIG9mIGhleCBudW1iZXIgKGxvd2VyY2FzZSlcblx0ICogQHJldHVybiB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleVtdfSBwdWJsaWMga2V5cyBmb3VuZFxuXHQgKi9cblx0ZnVuY3Rpb24gZ2V0UGFja2V0bGlzdHNGb3JLZXlJZChrZXlJZCkge1xuICAgIHJldHVybiB0aGlzLmNoZWNrRm9ySWRlbnRpdHlBbmRQYWNrZXRNYXRjaChpZFBhY2tldENoZWNrLCBrZXlJZCk7XG5cdH1cblx0dGhpcy5nZXRQYWNrZXRsaXN0c0ZvcktleUlkID0gZ2V0UGFja2V0bGlzdHNGb3JLZXlJZDtcblx0XG5cdC8qKlxuXHQgKiBJbXBvcnRzIGEgcGFja2V0IGxpc3QgKHB1YmxpYyBvciBwcml2YXRlIGtleSBibG9jaykgZnJvbSBhbiBhc2NpaSBhcm1vcmVkIG1lc3NhZ2UgXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBhcm1vcmVkIG1lc3NhZ2UgdG8gcmVhZCB0aGUgcGFja2V0cy9rZXkgZnJvbVxuXHQgKi9cblx0ZnVuY3Rpb24gaW1wb3J0UGFja2V0bGlzdCAoYXJtb3JlZCkge1xuICAgIHRoaXMuYXJtb3JlZFBhY2tldGxpc3RzLnB1c2goYXJtb3JlZCk7XG5cbiAgICB2YXIgZGVhcm1vcmVkID0gYXJtb3IuZGVjb2RlKGFybW9yZWQucmVwbGFjZSgvXFxyL2csJycpKS5vcGVucGdwO1xuXG4gICAgcGFja2V0bGlzdCA9IG5ldyBwYWNrZXQubGlzdCgpO1xuICAgIHBhY2tldGxpc3QucmVhZChkZWFybW9yZWQpO1xuICAgIHRoaXMucGFyc2VkUGFja2V0bGlzdHMucHVzaChwYWNrZXRsaXN0KTtcblxuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdHRoaXMuaW1wb3J0UGFja2V0bGlzdCA9IGltcG9ydFBhY2tldGxpc3Q7XG5cdFxuXHQvKipcbiAgICogVE9ET1xuXHQgKiByZXR1cm5zIHRoZSBvcGVucGdwX21zZ19wcml2YXRla2V5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwdWJsaWMga2V5IGF0IHB1YmxpYyBrZXkgcmluZyBpbmRleCAgXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBwdWJsaWMga2V5IHdpdGhpbiB0aGUgcHVibGljS2V5cyBhcnJheVxuXHQgKiBAcmV0dXJuIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSB0aGUgcHVibGljIGtleSBvYmplY3Rcblx0ICovXG5cdGZ1bmN0aW9uIGV4cG9ydFB1YmxpY0tleShpbmRleCkge1xuXHRcdHJldHVybiB0aGlzLnB1YmxpY0tleVtpbmRleF07XG5cdH1cblx0dGhpcy5leHBvcnRQdWJsaWNLZXkgPSBleHBvcnRQdWJsaWNLZXk7XG5cdFxuXHQvKipcbiAgICogVE9ET1xuXHQgKiBSZW1vdmVzIGEgcHVibGljIGtleSBmcm9tIHRoZSBwdWJsaWMga2V5IGtleXJpbmcgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIHB1YmxpYyBrZXkgd2l0aGluIHRoZSBwdWJsaWNLZXlzIGFycmF5XG5cdCAqIEByZXR1cm4ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXl9IFRoZSBwdWJsaWMga2V5IG9iamVjdCB3aGljaCBoYXMgYmVlbiByZW1vdmVkXG5cdCAqL1xuXHRmdW5jdGlvbiByZW1vdmVQdWJsaWNLZXkoaW5kZXgpIHtcblx0XHR2YXIgcmVtb3ZlZCA9IHRoaXMucHVibGljS2V5cy5zcGxpY2UoaW5kZXgsMSk7XG5cdFx0dGhpcy5zdG9yZSgpO1xuXHRcdHJldHVybiByZW1vdmVkO1xuXHR9XG5cdHRoaXMucmVtb3ZlUHVibGljS2V5ID0gcmVtb3ZlUHVibGljS2V5O1xuXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBrZXlyaW5nKCk7XG4iLCJcbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyk7XG5cbi8vIFRoaXMgaXMgcHJldHR5IHVnbHksIGJ1dCBicm93c2VyaWZ5IG5lZWRzIHRvIGhhdmUgdGhlIHJlcXVpcmVzIGV4cGxpY2l0bHkgd3JpdHRlbi5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRjb21wcmVzc2VkOiByZXF1aXJlKCcuL2NvbXByZXNzZWQuanMnKSxcblx0c3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkOiByZXF1aXJlKCcuL3N5bV9lbmNyeXB0ZWRfaW50ZWdyaXR5X3Byb3RlY3RlZC5qcycpLFxuXHRwdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleTogcmVxdWlyZSgnLi9wdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleS5qcycpLFxuXHRzeW1fZW5jcnlwdGVkX3Nlc3Npb25fa2V5OiByZXF1aXJlKCcuL3N5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkuanMnKSxcblx0bGl0ZXJhbDogcmVxdWlyZSgnLi9saXRlcmFsLmpzJyksXG5cdHB1YmxpY19rZXk6IHJlcXVpcmUoJy4vcHVibGljX2tleS5qcycpLFxuXHRzeW1tZXRyaWNhbGx5X2VuY3J5cHRlZDogcmVxdWlyZSgnLi9zeW1tZXRyaWNhbGx5X2VuY3J5cHRlZC5qcycpLFxuXHRtYXJrZXI6IHJlcXVpcmUoJy4vbWFya2VyLmpzJyksXG5cdHB1YmxpY19zdWJrZXk6IHJlcXVpcmUoJy4vcHVibGljX3N1YmtleS5qcycpLFxuXHR1c2VyX2F0dHJpYnV0ZTogcmVxdWlyZSgnLi91c2VyX2F0dHJpYnV0ZS5qcycpLFxuXHRvbmVfcGFzc19zaWduYXR1cmU6IHJlcXVpcmUoJy4vb25lX3Bhc3Nfc2lnbmF0dXJlLmpzJyksXG5cdHNlY3JldF9rZXk6IHJlcXVpcmUoJy4vc2VjcmV0X2tleS5qcycpLFxuXHR1c2VyaWQ6IHJlcXVpcmUoJy4vdXNlcmlkLmpzJyksXG5cdHNlY3JldF9zdWJrZXk6IHJlcXVpcmUoJy4vc2VjcmV0X3N1YmtleS5qcycpLFxuXHRzaWduYXR1cmU6IHJlcXVpcmUoJy4vc2lnbmF0dXJlLmpzJyksXG5cdHRydXN0OiByZXF1aXJlKCcuL3RydXN0LmpzJylcbn1cblxuZm9yKHZhciBpIGluIGVudW1zLnBhY2tldCkge1xuXHR2YXIgcGFja2V0Q2xhc3MgPSBtb2R1bGUuZXhwb3J0c1tpXTtcblxuXHRpZihwYWNrZXRDbGFzcyAhPSB1bmRlZmluZWQpXG5cdFx0cGFja2V0Q2xhc3MucHJvdG90eXBlLnRhZyA9IGVudW1zLnBhY2tldFtpXTtcbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG5cdEpYRyA9IHJlcXVpcmUoJy4uL2NvbXByZXNzaW9uL2p4Zy5qcycpLFxuXHRiYXNlNjQgPSByZXF1aXJlKCcuLi9lbmNvZGluZy9iYXNlNjQuanMnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIENvbXByZXNzZWQgRGF0YSBQYWNrZXQgKFRhZyA4KVxuICogXG4gKiBSRkM0ODgwIDUuNjpcbiAqIFRoZSBDb21wcmVzc2VkIERhdGEgcGFja2V0IGNvbnRhaW5zIGNvbXByZXNzZWQgZGF0YS4gIFR5cGljYWxseSwgdGhpc1xuICogcGFja2V0IGlzIGZvdW5kIGFzIHRoZSBjb250ZW50cyBvZiBhbiBlbmNyeXB0ZWQgcGFja2V0LCBvciBmb2xsb3dpbmdcbiAqIGEgU2lnbmF0dXJlIG9yIE9uZS1QYXNzIFNpZ25hdHVyZSBwYWNrZXQsIGFuZCBjb250YWlucyBhIGxpdGVyYWwgZGF0YVxuICogcGFja2V0LlxuICovICAgXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9jb21wcmVzc2VkKCkge1xuXHQvKiogQHR5cGUge3BhY2tldGxpc3R9ICovXG5cdHRoaXMucGFja2V0cztcblx0LyoqIEB0eXBlIHtjb21wcmVzc2lvbn0gKi9cblx0dGhpcy5hbGdvcml0aG0gPSAndW5jb21wcmVzc2VkJztcblxuXHR0aGlzLmNvbXByZXNzZWQgPSBudWxsO1xuXG5cdFxuXHQvKipcblx0ICogUGFyc2luZyBmdW5jdGlvbiBmb3IgdGhlIHBhY2tldC5cblx0ICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFBheWxvYWQgb2YgYSB0YWcgOCBwYWNrZXRcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZ1xuXHQgKiBAcGFyQU0ge2lOVEVHRVJ9IExFTiBsRU5HVEggT0YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBcblx0ICogaW5wdXQgYXQgcG9zaXRpb25cblx0ICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfY29tcHJlc3NlZH0gT2JqZWN0IHJlcHJlc2VudGF0aW9uXG5cdCAqL1xuXHR0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuXHRcdC8vIE9uZSBvY3RldCB0aGF0IGdpdmVzIHRoZSBhbGdvcml0aG0gdXNlZCB0byBjb21wcmVzcyB0aGUgcGFja2V0LlxuXHRcdHRoaXMuYWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5jb21wcmVzc2lvbiwgYnl0ZXMuY2hhckNvZGVBdCgwKSk7XG5cblx0XHQvLyBDb21wcmVzc2VkIGRhdGEsIHdoaWNoIG1ha2VzIHVwIHRoZSByZW1haW5kZXIgb2YgdGhlIHBhY2tldC5cblx0XHR0aGlzLmNvbXByZXNzZWQgPSBieXRlcy5zdWJzdHIoMSk7XG5cblx0XHR0aGlzLmRlY29tcHJlc3MoKTtcblx0fVxuXG5cdFxuXHRcblx0dGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmKHRoaXMuY29tcHJlc3NlZCA9PSBudWxsKVxuXHRcdFx0dGhpcy5jb21wcmVzcygpO1xuXG5cdFx0cmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMuY29tcHJlc3Npb24sIHRoaXMuYWxnb3JpdGhtKSkgXG5cdFx0XHQrIHRoaXMuY29tcHJlc3NlZDtcblx0fVxuXG5cblx0LyoqXG5cdCAqIERlY29tcHJlc3Npb24gbWV0aG9kIGZvciBkZWNvbXByZXNzaW5nIHRoZSBjb21wcmVzc2VkIGRhdGFcblx0ICogcmVhZCBieSByZWFkX3BhY2tldFxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBkZWNvbXByZXNzZWQgZGF0YVxuXHQgKi9cblx0dGhpcy5kZWNvbXByZXNzID0gZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGRlY29tcHJlc3NlZDtcblxuXHRcdHN3aXRjaCAodGhpcy5hbGdvcml0aG0pIHtcblx0XHRjYXNlICd1bmNvbXByZXNzZWQnOlxuXHRcdFx0ZGVjb21wcmVzc2VkID0gdGhpcy5jb21wcmVzc2VkO1xuXHRcdFx0YnJlYWs7XG5cblx0XHRjYXNlICd6aXAnOlxuXHRcdFx0dmFyIGNvbXBEYXRhID0gdGhpcy5jb21wcmVzc2VkO1xuXG5cdFx0XHR2YXIgcmFkaXggPSBiYXNlNjQuZW5jb2RlKGNvbXBEYXRhKS5yZXBsYWNlKC9cXG4vZyxcIlwiKTtcblx0XHRcdC8vIG5vIGhlYWRlciBpbiB0aGlzIGNhc2UsIGRpcmVjdGx5IGNhbGwgZGVmbGF0ZVxuXHRcdFx0dmFyIGp4Z19vYmogPSBuZXcgSlhHLlV0aWwuVW56aXAoSlhHLlV0aWwuQmFzZTY0LmRlY29kZUFzQXJyYXkocmFkaXgpKTtcblxuXHRcdFx0ZGVjb21wcmVzc2VkID0gdW5lc2NhcGUoanhnX29iai5kZWZsYXRlKClbMF1bMF0pO1xuXHRcdFx0YnJlYWs7XG5cblx0XHRjYXNlICd6bGliJzpcblx0XHRcdC8vUkZDIDE5NTAuIEJpdHMgMC0zIENvbXByZXNzaW9uIE1ldGhvZFxuXHRcdFx0dmFyIGNvbXByZXNzaW9uTWV0aG9kID0gdGhpcy5jb21wcmVzc2VkLmNoYXJDb2RlQXQoMCkgJSAweDEwO1xuXG5cdFx0XHQvL0JpdHMgNC03IFJGQyAxOTUwIGFyZSBMWjc3IFdpbmRvdy4gR2VuZXJhbGx5IHRoaXMgdmFsdWUgaXMgNyA9PSAzMmsgd2luZG93IHNpemUuXG5cdFx0XHQvLyAybmQgQnl0ZSBpbiBSRkMgMTk1MCBpcyBmb3IgXCJGTEFHc1wiIEFsbG93cyBmb3IgYSBEaWN0aW9uYXJ5IFxuXHRcdFx0Ly8gKGhvdyBpcyB0aGlzIGRlZmluZWQpLiBCYXNpYyBjaGVja3N1bSwgYW5kIGNvbXByZXNzaW9uIGxldmVsLlxuXG5cdFx0XHRpZiAoY29tcHJlc3Npb25NZXRob2QgPT0gOCkgeyAvL0NNIDggaXMgZm9yIERFRkxBVEUsIFJGQyAxOTUxXG5cdFx0XHRcdC8vIHJlbW92ZSA0IGJ5dGVzIEFETEVSMzIgY2hlY2tzdW0gZnJvbSB0aGUgZW5kXG5cdFx0XHRcdHZhciBjb21wRGF0YSA9IHRoaXMuY29tcHJlc3NlZC5zdWJzdHJpbmcoMCwgdGhpcy5jb21wcmVzc2VkLmxlbmd0aCAtIDQpO1xuXHRcdFx0XHR2YXIgcmFkaXggPSBiYXNlNjQuZW5jb2RlKGNvbXBEYXRhKS5yZXBsYWNlKC9cXG4vZyxcIlwiKTtcblx0XHRcdFx0Ly9UT0RPIGNoZWNrIEFETEVSMzIgY2hlY2tzdW1cblx0XHRcdFx0ZGVjb21wcmVzc2VkID0gSlhHLmRlY29tcHJlc3MocmFkaXgpO1xuXHRcdFx0XHRicmVhaztcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dXRpbC5wcmludF9lcnJvcihcIkNvbXByZXNzaW9uIGFsZ29yaXRobSBaTElCIG9ubHkgc3VwcG9ydHMgXCIgK1xuXHRcdFx0XHRcdFwiREVGTEFURSBjb21wcmVzc2lvbiBtZXRob2QuXCIpO1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cblx0XHRjYXNlICdiemlwMic6XG5cdFx0XHQvLyBUT0RPOiBuZWVkIHRvIGltcGxlbWVudCB0aGlzXG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0NvbXByZXNzaW9uIGFsZ29yaXRobSBCWmlwMiBbQloyXSBpcyBub3QgaW1wbGVtZW50ZWQuJyk7XG5cdFx0XHRicmVhaztcblxuXHRcdGRlZmF1bHQ6XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJDb21wcmVzc2lvbiBhbGdvcml0aG0gdW5rbm93biA6XCIgKyB0aGlzLmFsb2dyaXRobSk7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHR0aGlzLnBhY2tldHMucmVhZChkZWNvbXByZXNzZWQpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENvbXByZXNzIHRoZSBwYWNrZXQgZGF0YSAobWVtYmVyIGRlY29tcHJlc3NlZERhdGEpXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gdHlwZSBBbGdvcml0aG0gdG8gYmUgdXNlZCAvLyBTZWUgUkZDIDQ4ODAgOS4zXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgY29tcHJlc3NlZFxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBjb21wcmVzc2VkIGRhdGEgc3RvcmVkIGluIGF0dHJpYnV0ZSBjb21wcmVzc2VkRGF0YVxuXHQgKi9cblx0dGhpcy5jb21wcmVzcyA9IGZ1bmN0aW9uKCkge1xuXHRcdHN3aXRjaCAodGhpcy5hbGdvcml0aG0pIHtcblxuXHRcdGNhc2UgJ3VuY29tcHJlc3NlZCc6IC8vIC0gVW5jb21wcmVzc2VkXG5cdFx0XHR0aGlzLmNvbXByZXNzZWQgPSB0aGlzLnBhY2tldHMud3JpdGUoKTtcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAnemlwJzogLy8gLSBaSVAgW1JGQzE5NTFdXG5cdFx0XHR1dGlsLnByaW50X2Vycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIFpJUCBbUkZDMTk1MV0gaXMgbm90IGltcGxlbWVudGVkLlwiKTtcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAnemxpYic6IC8vIC0gWkxJQiBbUkZDMTk1MF1cblx0XHRcdC8vIFRPRE86IG5lZWQgdG8gaW1wbGVtZW50IHRoaXNcblx0XHRcdHV0aWwucHJpbnRfZXJyb3IoXCJDb21wcmVzc2lvbiBhbGdvcml0aG0gWkxJQiBbUkZDMTk1MF0gaXMgbm90IGltcGxlbWVudGVkLlwiKTtcblx0XHRcdGJyZWFrO1xuXG5cdFx0Y2FzZSAnYnppcDInOiAvLyAgLSBCWmlwMiBbQloyXVxuXHRcdFx0Ly8gVE9ETzogbmVlZCB0byBpbXBsZW1lbnQgdGhpc1xuXHRcdFx0dXRpbC5wcmludF9lcnJvcihcIkNvbXByZXNzaW9uIGFsZ29yaXRobSBCWmlwMiBbQloyXSBpcyBub3QgaW1wbGVtZW50ZWQuXCIpO1xuXHRcdFx0YnJlYWs7XG5cblx0XHRkZWZhdWx0OlxuXHRcdFx0dXRpbC5wcmludF9lcnJvcihcIkNvbXByZXNzaW9uIGFsZ29yaXRobSB1bmtub3duIDpcIit0aGlzLnR5cGUpO1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG59O1xuIiwiXG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0bGlzdDogcmVxdWlyZSgnLi9wYWNrZXRsaXN0LmpzJyksXG59O1xuXG52YXIgcGFja2V0cyA9IHJlcXVpcmUoJy4vYWxsX3BhY2tldHMuanMnKTtcblxuZm9yKHZhciBpIGluIHBhY2tldHMpXG5cdG1vZHVsZS5leHBvcnRzW2ldID0gcGFja2V0c1tpXTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuXHRlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBMaXRlcmFsIERhdGEgUGFja2V0IChUYWcgMTEpXG4gKiBcbiAqIFJGQzQ4ODAgNS45OiBBIExpdGVyYWwgRGF0YSBwYWNrZXQgY29udGFpbnMgdGhlIGJvZHkgb2YgYSBtZXNzYWdlOyBkYXRhIHRoYXRcbiAqIGlzIG5vdCB0byBiZSBmdXJ0aGVyIGludGVycHJldGVkLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9saXRlcmFsKCkge1xuXHR0aGlzLmZvcm1hdCA9ICd1dGY4Jztcblx0dGhpcy5kYXRhID0gJyc7XG5cdHRoaXMuZGF0ZSA9IG5ldyBEYXRlKCk7XG5cblx0XG5cdC8qKlxuXHQgKiBTZXQgdGhlIHBhY2tldCBkYXRhIHRvIGEgamF2YXNjcmlwdCBuYXRpdmUgc3RyaW5nIG9yIGEgc3F1ZW5jZSBvZiBcblx0ICogYnl0ZXMuIENvbnZlcnNpb24gdG8gYSBwcm9wZXIgdXRmOCBlbmNvZGluZyB0YWtlcyBwbGFjZSB3aGVuIHRoZSBcblx0ICogcGFja2V0IGlzIHdyaXR0ZW4uXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgQW55IG5hdGl2ZSBqYXZhc2NyaXB0IHN0cmluZ1xuXHQgKiBAcGFyYW0ge29wZW5wZ3BfcGFja2V0X2xpdGVyYWxkYXRhLmZvcm1hdH0gZm9ybWF0IFxuXHQgKi9cblx0dGhpcy5zZXQgPSBmdW5jdGlvbihzdHIsIGZvcm1hdCkge1xuXHRcdHRoaXMuZm9ybWF0ID0gZm9ybWF0O1xuXHRcdHRoaXMuZGF0YSA9IHN0cjtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIHBhY2tldCBkYXRhIHRvIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHRoZSBwcm92aWRlZCBzdHJpbmdcblx0ICogb2YgYnl0ZXMgdG9nZXRoZXIgd2l0aCB0aGUgYXBwcm9wcmlhdGUgY29udmVyc2lvbiBmb3JtYXQuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBUaGUgc3RyaW5nIG9mIGJ5dGVzXG5cdCAqIEBwYXJhbSB7b3BlbnBncF9wYWNrZXRfbGl0ZXJhbGRhdGEuZm9ybWF0fSBmb3JtYXRcblx0ICovXG5cdHRoaXMuc2V0Qnl0ZXMgPSBmdW5jdGlvbihieXRlcywgZm9ybWF0KSB7XG5cdFx0dGhpcy5mb3JtYXQgPSBmb3JtYXQ7XG5cblx0XHRpZihmb3JtYXQgPT0gJ3V0ZjgnKVxuXHRcdFx0Ynl0ZXMgPSB1dGlsLmRlY29kZV91dGY4KGJ5dGVzKTtcblxuXHRcdHRoaXMuZGF0YSA9IGJ5dGVzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCB0aGUgYnl0ZSBzZXF1ZW5jZSByZXByZXNlbnRpbmcgdGhlIGxpdGVyYWwgcGFja2V0IGRhdGFcblx0ICogQHJldHVybnMge1N0cmluZ30gQSBzZXF1ZW5jZSBvZiBieXRlc1xuXHQgKi9cblx0dGhpcy5nZXRCeXRlcyA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmKHRoaXMuZm9ybWF0ID09ICd1dGY4Jylcblx0XHRcdHJldHVybiB1dGlsLmVuY29kZV91dGY4KHRoaXMuZGF0YSk7XG5cdFx0ZWxzZVxuXHRcdFx0cmV0dXJuIHRoaXMuZGF0YTtcblx0fVxuXHRcblx0XG5cblx0LyoqXG5cdCAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgbGl0ZXJhbCBkYXRhIHBhY2tldCAodGFnIDExKS5cblx0ICogXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDExIHBhY2tldFxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uXG5cdCAqICAgICAgICAgICAgUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5cblx0ICogICAgICAgICAgICBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZlxuXHQgKiAgICAgICAgICAgIGlucHV0IGF0IHBvc2l0aW9uXG5cdCAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IG9iamVjdCByZXByZXNlbnRhdGlvblxuXHQgKi9cblx0dGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcblx0XHQvLyAtIEEgb25lLW9jdGV0IGZpZWxkIHRoYXQgZGVzY3JpYmVzIGhvdyB0aGUgZGF0YSBpcyBmb3JtYXR0ZWQuXG5cblx0XHR2YXIgZm9ybWF0ID0gZW51bXMucmVhZChlbnVtcy5saXRlcmFsLCBieXRlc1swXS5jaGFyQ29kZUF0KCkpO1xuXG5cdFx0dmFyIGZpbGVuYW1lX2xlbiA9IGJ5dGVzLmNoYXJDb2RlQXQoMSk7XG5cdFx0dGhpcy5maWxlbmFtZSA9IHV0aWwuZGVjb2RlX3V0ZjgoYnl0ZXMuc3Vic3RyKDIsIGZpbGVuYW1lX2xlbikpO1xuXG5cdFx0dGhpcy5kYXRlID0gdXRpbC5yZWFkRGF0ZShieXRlcy5zdWJzdHIoMlxuXHRcdFx0XHQrIGZpbGVuYW1lX2xlbiwgNCkpO1xuXG5cdFx0dmFyIGRhdGEgPSBieXRlcy5zdWJzdHJpbmcoNiArIGZpbGVuYW1lX2xlbik7XG5cdFxuXHRcdHRoaXMuc2V0Qnl0ZXMoZGF0YSwgZm9ybWF0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwYWNrZXRcblx0ICogXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIGJlIGluc2VydGVkIGFzIGJvZHlcblx0ICogQHJldHVybiB7U3RyaW5nfSBzdHJpbmctcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhY2tldFxuXHQgKi9cblx0dGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBmaWxlbmFtZSA9IHV0aWwuZW5jb2RlX3V0ZjgoXCJtc2cudHh0XCIpO1xuXG5cdFx0dmFyIGRhdGEgPSB0aGlzLmdldEJ5dGVzKCk7XG5cblx0XHR2YXIgcmVzdWx0ID0gJyc7XG5cdFx0cmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMubGl0ZXJhbCwgdGhpcy5mb3JtYXQpKTtcblx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShmaWxlbmFtZS5sZW5ndGgpO1xuXHRcdHJlc3VsdCArPSBmaWxlbmFtZTtcblx0XHRyZXN1bHQgKz0gdXRpbC53cml0ZURhdGUodGhpcy5kYXRlKTtcblx0XHRyZXN1bHQgKz0gZGF0YTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgc3RyYW5nZSBcIk1hcmtlciBwYWNrZXRcIiAoVGFnIDEwKVxuICogXG4gKiBSRkM0ODgwIDUuODogQW4gZXhwZXJpbWVudGFsIHZlcnNpb24gb2YgUEdQIHVzZWQgdGhpcyBwYWNrZXQgYXMgdGhlIExpdGVyYWxcbiAqIHBhY2tldCwgYnV0IG5vIHJlbGVhc2VkIHZlcnNpb24gb2YgUEdQIGdlbmVyYXRlZCBMaXRlcmFsIHBhY2tldHMgd2l0aCB0aGlzXG4gKiB0YWcuIFdpdGggUEdQIDUueCwgdGhpcyBwYWNrZXQgaGFzIGJlZW4gcmVhc3NpZ25lZCBhbmQgaXMgcmVzZXJ2ZWQgZm9yIHVzZSBhc1xuICogdGhlIE1hcmtlciBwYWNrZXQuXG4gKiBcbiAqIFN1Y2ggYSBwYWNrZXQgTVVTVCBiZSBpZ25vcmVkIHdoZW4gcmVjZWl2ZWQuXG4gKi9cbmZ1bmN0aW9uIHBhY2tldF9tYXJrZXIoKSB7XG5cdC8qKlxuXHQgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgKHRhZyAxMCkuXG5cdCAqIFxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxMCBwYWNrZXRcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvblxuXHQgKiAgICAgICAgICAgIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuXG5cdCAqICAgICAgICAgICAgTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2Zcblx0ICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvblxuXHQgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBPYmplY3QgcmVwcmVzZW50YXRpb25cblx0ICovXG5cdHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG5cdFx0aWYgKGJ5dGVzWzBdLmNoYXJDb2RlQXQoKSA9PSAweDUwICYmIC8vIFBcblx0XHRcdFx0Ynl0ZXNbMV0uY2hhckNvZGVBdCgpID09IDB4NDcgJiYgLy8gR1xuXHRcdFx0XHRieXRlc1syXS5jaGFyQ29kZUF0KCkgPT0gMHg1MCkgLy8gUFxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0Ly8gbWFya2VyIHBhY2tldCBkb2VzIG5vdCBjb250YWluIFwiUEdQXCJcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBwYWNrZXRfbWFya2VyO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIE9uZS1QYXNzIFNpZ25hdHVyZSBQYWNrZXRzIChUYWcgNClcbiAqIFxuICogUkZDNDg4MCA1LjQ6XG4gKiBUaGUgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCBwcmVjZWRlcyB0aGUgc2lnbmVkIGRhdGEgYW5kIGNvbnRhaW5zXG4gKiBlbm91Z2ggaW5mb3JtYXRpb24gdG8gYWxsb3cgdGhlIHJlY2VpdmVyIHRvIGJlZ2luIGNhbGN1bGF0aW5nIGFueVxuICogaGFzaGVzIG5lZWRlZCB0byB2ZXJpZnkgdGhlIHNpZ25hdHVyZS4gIEl0IGFsbG93cyB0aGUgU2lnbmF0dXJlXG4gKiBwYWNrZXQgdG8gYmUgcGxhY2VkIGF0IHRoZSBlbmQgb2YgdGhlIG1lc3NhZ2UsIHNvIHRoYXQgdGhlIHNpZ25lclxuICogY2FuIGNvbXB1dGUgdGhlIGVudGlyZSBzaWduZWQgbWVzc2FnZSBpbiBvbmUgcGFzcy5cbiAqL1xuXG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuXHR0eXBlX2tleWlkID0gcmVxdWlyZSgnLi4vdHlwZS9rZXlpZC5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9vbmVfcGFzc19zaWduYXR1cmUoKSB7XG5cdHRoaXMudmVyc2lvbiA9IG51bGw7IC8vIEEgb25lLW9jdGV0IHZlcnNpb24gbnVtYmVyLiAgVGhlIGN1cnJlbnQgdmVyc2lvbiBpcyAzLlxuXHR0aGlzLnR5cGUgPSBudWxsOyBcdCAvLyBBIG9uZS1vY3RldCBzaWduYXR1cmUgdHlwZS4gIFNpZ25hdHVyZSB0eXBlcyBhcmUgZGVzY3JpYmVkIGluIFJGQzQ4ODAgU2VjdGlvbiA1LjIuMS5cblx0dGhpcy5oYXNoQWxnb3JpdGhtID0gbnVsbDsgXHQgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgaGFzaCBhbGdvcml0aG0gdXNlZC4gKFNlZSBSRkM0ODgwIDkuNClcblx0dGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBudWxsO1x0ICAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgcHVibGljLWtleSBhbGdvcml0aG0gdXNlZC4gKFNlZSBSRkM0ODgwIDkuMSlcblx0dGhpcy5zaWduaW5nS2V5SWQgPSBudWxsOyAvLyBBbiBlaWdodC1vY3RldCBudW1iZXIgaG9sZGluZyB0aGUgS2V5IElEIG9mIHRoZSBzaWduaW5nIGtleS5cblx0dGhpcy5mbGFncyA9IG51bGw7IFx0Ly8gIEEgb25lLW9jdGV0IG51bWJlciBob2xkaW5nIGEgZmxhZyBzaG93aW5nIHdoZXRoZXIgdGhlIHNpZ25hdHVyZSBpcyBuZXN0ZWQuICBBIHplcm8gdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcGFja2V0IGlzIGFub3RoZXIgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCB0aGF0IGRlc2NyaWJlcyBhbm90aGVyIHNpZ25hdHVyZSB0byBiZSBhcHBsaWVkIHRvIHRoZSBzYW1lIG1lc3NhZ2UgZGF0YS5cblxuXHQvKipcblx0ICogcGFyc2luZyBmdW5jdGlvbiBmb3IgYSBvbmUtcGFzcyBzaWduYXR1cmUgcGFja2V0ICh0YWcgNCkuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBwYXlsb2FkIG9mIGEgdGFnIDQgcGFja2V0XG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gcG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBieXRlcyBzdHJpbmdcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gbGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2YgYnl0ZXMgYXQgcG9zaXRpb25cblx0ICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YX0gb2JqZWN0IHJlcHJlc2VudGF0aW9uXG5cdCAqL1xuXHR0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuXHRcdHZhciBteXBvcyA9IDA7XG5cdFx0Ly8gQSBvbmUtb2N0ZXQgdmVyc2lvbiBudW1iZXIuICBUaGUgY3VycmVudCB2ZXJzaW9uIGlzIDMuXG5cdFx0dGhpcy52ZXJzaW9uID0gYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKTtcblxuXHQgICAgIC8vIEEgb25lLW9jdGV0IHNpZ25hdHVyZSB0eXBlLiAgU2lnbmF0dXJlIHR5cGVzIGFyZSBkZXNjcmliZWQgaW5cblx0ICAgICAvLyAgIFNlY3Rpb24gNS4yLjEuXG5cdFx0dGhpcy50eXBlID0gZW51bXMucmVhZChlbnVtcy5zaWduYXR1cmUsIGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKykpO1xuXG5cdCAgICAgLy8gQSBvbmUtb2N0ZXQgbnVtYmVyIGRlc2NyaWJpbmcgdGhlIGhhc2ggYWxnb3JpdGhtIHVzZWQuXG5cdFx0dGhpcy5oYXNoQWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5oYXNoLCBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspKTtcblxuXHQgICAgIC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBwdWJsaWMta2V5IGFsZ29yaXRobSB1c2VkLlxuXHRcdHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKykpO1xuXG5cdCAgICAgLy8gQW4gZWlnaHQtb2N0ZXQgbnVtYmVyIGhvbGRpbmcgdGhlIEtleSBJRCBvZiB0aGUgc2lnbmluZyBrZXkuXG5cdFx0dGhpcy5zaWduaW5nS2V5SWQgPSBuZXcgdHlwZV9rZXlpZCgpO1xuXHRcdHRoaXMuc2lnbmluZ0tleUlkLnJlYWQoYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG5cdFx0bXlwb3MgKz0gODtcblx0XHRcblx0ICAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgaG9sZGluZyBhIGZsYWcgc2hvd2luZyB3aGV0aGVyIHRoZSBzaWduYXR1cmVcblx0ICAgICAvLyAgIGlzIG5lc3RlZC4gIEEgemVybyB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCB0aGUgbmV4dCBwYWNrZXQgaXNcblx0ICAgICAvLyAgIGFub3RoZXIgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCB0aGF0IGRlc2NyaWJlcyBhbm90aGVyXG5cdCAgICAgLy8gICBzaWduYXR1cmUgdG8gYmUgYXBwbGllZCB0byB0aGUgc2FtZSBtZXNzYWdlIGRhdGEuXG5cdFx0dGhpcy5mbGFncyA9IGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKyk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKipcblx0ICogY3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIG9uZS1wYXNzIHNpZ25hdHVyZSBwYWNrZXRcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSB0eXBlIFNpZ25hdHVyZSB0eXBlcyBhcyBkZXNjcmliZWQgaW4gUkZDNDg4MCBTZWN0aW9uIDUuMi4xLlxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IGhhc2hhbGdvcml0aG0gdGhlIGhhc2ggYWxnb3JpdGhtIHVzZWQgd2l0aGluIHRoZSBzaWduYXR1cmVcblx0ICogQHBhcmFtIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBwcml2YXRla2V5IHRoZSBwcml2YXRlIGtleSB1c2VkIHRvIGdlbmVyYXRlIHRoZSBzaWduYXR1cmVcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggbGVuZ3RoIG9mIGRhdGEgdG8gYmUgc2lnbmVkXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gbmVzdGVkIGJvb2xlYW4gc2hvd2luZyB3aGV0aGVyIHRoZSBzaWduYXR1cmUgaXMgbmVzdGVkLiBcblx0ICogIFwidHJ1ZVwiIGluZGljYXRlcyB0aGF0IHRoZSBuZXh0IHBhY2tldCBpcyBhbm90aGVyIE9uZS1QYXNzIFNpZ25hdHVyZSBwYWNrZXRcblx0ICogICB0aGF0IGRlc2NyaWJlcyBhbm90aGVyIHNpZ25hdHVyZSB0byBiZSBhcHBsaWVkIHRvIHRoZSBzYW1lIG1lc3NhZ2UgZGF0YS4gXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBvbmUtcGFzcyBzaWduYXR1cmUgcGFja2V0XG5cdCAqL1xuXHR0aGlzLndyaXRlID0gZnVuY3Rpb24odHlwZSwgaGFzaGFsZ29yaXRobSwgcHJpdmF0ZWtleSwgbGVuZ3RoLCBuZXN0ZWQpIHtcblx0XHR2YXIgcmVzdWx0ID1cIlwiOyBcblx0XHRcblx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgzKTtcblx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5zaWduYXR1cmUsIHR5cGUpKTtcblx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG0pKTtcblx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHByaXZhdGVrZXkuYWxnb3JpdGhtKSk7XG5cdFx0cmVzdWx0ICs9IHByaXZhdGVrZXkuZ2V0S2V5SWQoKTtcblx0XHRpZiAobmVzdGVkKVxuXHRcdFx0cmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG5cdFx0ZWxzZVxuXHRcdFx0cmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMSk7XG5cdFx0XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG5cdHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdHJlYWRTaW1wbGVMZW5ndGg6IGZ1bmN0aW9uKGJ5dGVzKSB7XG5cdFx0dmFyIGxlbiA9IDAsXG5cdFx0XHRvZmZzZXQsXG5cdFx0XHR0eXBlID0gYnl0ZXNbMF0uY2hhckNvZGVBdCgpO1xuXG5cblx0XHRpZiAodHlwZSA8IDE5Mikge1xuXHRcdFx0bGVuID0gYnl0ZXNbMF0uY2hhckNvZGVBdCgpO1xuXHRcdFx0b2Zmc2V0ID0gMTtcblx0XHR9IGVsc2UgaWYgKHR5cGUgPCAyNTUpIHtcblx0XHRcdGxlbiA9ICgoYnl0ZXNbMF0uY2hhckNvZGVBdCgpIC0gMTkyKSA8PCA4KSArIChieXRlc1sxXS5jaGFyQ29kZUF0KCkpICsgMTkyO1xuXHRcdFx0b2Zmc2V0ID0gMjtcblx0XHR9IGVsc2UgaWYgKHR5cGUgPT0gMjU1KSB7XG5cdFx0XHRsZW4gPSB1dGlsLnJlYWROdW1iZXIoYnl0ZXMuc3Vic3RyKDEsIDQpKTtcblx0XHRcdG9mZnNldCA9IDU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHsgbGVuOiBsZW4sIG9mZnNldDogb2Zmc2V0IH07XG5cdH0sXG5cblx0LyoqXG5cdCAqIEVuY29kZXMgYSBnaXZlbiBpbnRlZ2VyIG9mIGxlbmd0aCB0byB0aGUgb3BlbnBncCBsZW5ndGggc3BlY2lmaWVyIHRvIGFcblx0ICogc3RyaW5nXG5cdCAqIFxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbmd0aCBUaGUgbGVuZ3RoIHRvIGVuY29kZVxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyB3aXRoIG9wZW5wZ3AgbGVuZ3RoIHJlcHJlc2VudGF0aW9uXG5cdCAqL1xuXHR3cml0ZVNpbXBsZUxlbmd0aDogZnVuY3Rpb24obGVuZ3RoKSB7XG5cdFx0dmFyIHJlc3VsdCA9IFwiXCI7XG5cdFx0aWYgKGxlbmd0aCA8IDE5Mikge1xuXHRcdFx0cmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuZ3RoKTtcblx0XHR9IGVsc2UgaWYgKGxlbmd0aCA+IDE5MSAmJiBsZW5ndGggPCA4Mzg0KSB7XG5cdFx0XHQvKlxuXHRcdFx0ICogbGV0IGEgPSAodG90YWwgZGF0YSBwYWNrZXQgbGVuZ3RoKSAtIDE5MiBsZXQgYmMgPSB0d28gb2N0ZXRcblx0XHRcdCAqIHJlcHJlc2VudGF0aW9uIG9mIGEgbGV0IGQgPSBiICsgMTkyXG5cdFx0XHQgKi9cblx0XHRcdHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCgobGVuZ3RoIC0gMTkyKSA+PiA4KSArIDE5Mik7XG5cdFx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgobGVuZ3RoIC0gMTkyKSAmIDB4RkYpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgyNTUpO1xuXHRcdFx0cmVzdWx0ICs9IHV0aWwud3JpdGVOdW1iZXIobGVuZ3RoLCA0KTtcblx0XHR9XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fSxcblxuXHQvKipcblx0ICogV3JpdGVzIGEgcGFja2V0IGhlYWRlciB2ZXJzaW9uIDQgd2l0aCB0aGUgZ2l2ZW4gdGFnX3R5cGUgYW5kIGxlbmd0aCB0byBhXG5cdCAqIHN0cmluZ1xuXHQgKiBcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSB0YWdfdHlwZSBUYWcgdHlwZVxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbmd0aCBMZW5ndGggb2YgdGhlIHBheWxvYWRcblx0ICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgb2YgdGhlIGhlYWRlclxuXHQgKi9cblx0d3JpdGVIZWFkZXI6IGZ1bmN0aW9uKHRhZ190eXBlLCBsZW5ndGgpIHtcblx0XHQvKiB3ZSdyZSBvbmx5IGdlbmVyYXRpbmcgdjQgcGFja2V0IGhlYWRlcnMgaGVyZSAqL1xuXHRcdHZhciByZXN1bHQgPSBcIlwiO1xuXHRcdHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4QzAgfCB0YWdfdHlwZSk7XG5cdFx0cmVzdWx0ICs9IHRoaXMud3JpdGVTaW1wbGVMZW5ndGgobGVuZ3RoKTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBXcml0ZXMgYSBwYWNrZXQgaGVhZGVyIFZlcnNpb24gMyB3aXRoIHRoZSBnaXZlbiB0YWdfdHlwZSBhbmQgbGVuZ3RoIHRvIGFcblx0ICogc3RyaW5nXG5cdCAqIFxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IHRhZ190eXBlIFRhZyB0eXBlXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIExlbmd0aCBvZiB0aGUgcGF5bG9hZFxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyBvZiB0aGUgaGVhZGVyXG5cdCAqL1xuXHR3cml0ZU9sZEhlYWRlcjogZnVuY3Rpb24odGFnX3R5cGUsIGxlbmd0aCkge1xuXHRcdHZhciByZXN1bHQgPSBcIlwiO1xuXHRcdGlmIChsZW5ndGggPCAyNTYpIHtcblx0XHRcdHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ODAgfCAodGFnX3R5cGUgPDwgMikpO1xuXHRcdFx0cmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuZ3RoKTtcblx0XHR9IGVsc2UgaWYgKGxlbmd0aCA8IDY1NTM2KSB7XG5cdFx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDgwIHwgKHRhZ190eXBlIDw8IDIpIHwgMSk7XG5cdFx0XHRyZXN1bHQgKz0gdXRpbC53cml0ZU51bWJlcihsZW5ndGgsIDIpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDgwIHwgKHRhZ190eXBlIDw8IDIpIHwgMik7XG5cdFx0XHRyZXN1bHQgKz0gdXRpbC53cml0ZU51bWJlcihsZW5ndGgsIDQpO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZW5lcmljIHN0YXRpYyBQYWNrZXQgUGFyc2VyIGZ1bmN0aW9uXG5cdCAqIFxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgSW5wdXQgc3RyZWFtIGFzIHN0cmluZ1xuXHQgKiBAcGFyYW0ge2ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHRvIHN0YXJ0IHBhcnNpbmdcblx0ICogQHBhcmFtIHtpbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBpbnB1dCBmcm9tIHBvc2l0aW9uIG9uXG5cdCAqIEByZXR1cm4ge09iamVjdH0gUmV0dXJucyBhIHBhcnNlZCBvcGVucGdwX3BhY2tldFxuXHQgKi9cblx0cmVhZDogZnVuY3Rpb24oaW5wdXQsIHBvc2l0aW9uLCBsZW4pIHtcblx0XHQvLyBzb21lIHNhbml0eSBjaGVja3Ncblx0XHRpZiAoaW5wdXQgPT0gbnVsbCB8fCBpbnB1dC5sZW5ndGggPD0gcG9zaXRpb25cblx0XHRcdFx0fHwgaW5wdXQuc3Vic3RyaW5nKHBvc2l0aW9uKS5sZW5ndGggPCAyXG5cdFx0XHRcdHx8IChpbnB1dFtwb3NpdGlvbl0uY2hhckNvZGVBdCgpICYgMHg4MCkgPT0gMCkge1xuXHRcdFx0dXRpbFxuXHRcdFx0XHRcdC5wcmludF9lcnJvcihcIkVycm9yIGR1cmluZyBwYXJzaW5nLiBUaGlzIG1lc3NhZ2UgLyBrZXkgaXMgcHJvYmFibHkgbm90IGNvbnRhaW5pbmcgYSB2YWxpZCBPcGVuUEdQIGZvcm1hdC5cIik7XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9XG5cdFx0dmFyIG15cG9zID0gcG9zaXRpb247XG5cdFx0dmFyIHRhZyA9IC0xO1xuXHRcdHZhciBmb3JtYXQgPSAtMTtcblx0XHR2YXIgcGFja2V0X2xlbmd0aDtcblxuXHRcdGZvcm1hdCA9IDA7IC8vIDAgPSBvbGQgZm9ybWF0OyAxID0gbmV3IGZvcm1hdFxuXHRcdGlmICgoaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSAmIDB4NDApICE9IDApIHtcblx0XHRcdGZvcm1hdCA9IDE7XG5cdFx0fVxuXG5cdFx0dmFyIHBhY2tldF9sZW5ndGhfdHlwZTtcblx0XHRpZiAoZm9ybWF0KSB7XG5cdFx0XHQvLyBuZXcgZm9ybWF0IGhlYWRlclxuXHRcdFx0dGFnID0gaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSAmIDB4M0Y7IC8vIGJpdCA1LTBcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gb2xkIGZvcm1hdCBoZWFkZXJcblx0XHRcdHRhZyA9IChpbnB1dFtteXBvc10uY2hhckNvZGVBdCgpICYgMHgzRikgPj4gMjsgLy8gYml0IDUtMlxuXHRcdFx0cGFja2V0X2xlbmd0aF90eXBlID0gaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSAmIDB4MDM7IC8vIGJpdCAxLTBcblx0XHR9XG5cblx0XHQvLyBoZWFkZXIgb2N0ZXQgcGFyc2luZyBkb25lXG5cdFx0bXlwb3MrKztcblxuXHRcdC8vIHBhcnNlZCBsZW5ndGggZnJvbSBsZW5ndGggZmllbGRcblx0XHR2YXIgYm9keWRhdGEgPSBudWxsO1xuXG5cdFx0Ly8gdXNlZCBmb3IgcGFydGlhbCBib2R5IGxlbmd0aHNcblx0XHR2YXIgcmVhbF9wYWNrZXRfbGVuZ3RoID0gLTE7XG5cdFx0aWYgKCFmb3JtYXQpIHtcblx0XHRcdC8vIDQuMi4xLiBPbGQgRm9ybWF0IFBhY2tldCBMZW5ndGhzXG5cdFx0XHRzd2l0Y2ggKHBhY2tldF9sZW5ndGhfdHlwZSkge1xuXHRcdFx0Y2FzZSAwOiAvLyBUaGUgcGFja2V0IGhhcyBhIG9uZS1vY3RldCBsZW5ndGguIFRoZSBoZWFkZXIgaXMgMiBvY3RldHNcblx0XHRcdFx0Ly8gbG9uZy5cblx0XHRcdFx0cGFja2V0X2xlbmd0aCA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDE6IC8vIFRoZSBwYWNrZXQgaGFzIGEgdHdvLW9jdGV0IGxlbmd0aC4gVGhlIGhlYWRlciBpcyAzIG9jdGV0c1xuXHRcdFx0XHQvLyBsb25nLlxuXHRcdFx0XHRwYWNrZXRfbGVuZ3RoID0gKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCA4KVxuXHRcdFx0XHRcdFx0fCBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAyOiAvLyBUaGUgcGFja2V0IGhhcyBhIGZvdXItb2N0ZXQgbGVuZ3RoLiBUaGUgaGVhZGVyIGlzIDVcblx0XHRcdFx0Ly8gb2N0ZXRzIGxvbmcuXG5cdFx0XHRcdHBhY2tldF9sZW5ndGggPSAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDI0KVxuXHRcdFx0XHRcdFx0fCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDE2KVxuXHRcdFx0XHRcdFx0fCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDgpXG5cdFx0XHRcdFx0XHR8IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHQvLyAzIC0gVGhlIHBhY2tldCBpcyBvZiBpbmRldGVybWluYXRlIGxlbmd0aC4gVGhlIGhlYWRlciBpcyAxXG5cdFx0XHRcdC8vIG9jdGV0IGxvbmcsIGFuZCB0aGUgaW1wbGVtZW50YXRpb24gbXVzdCBkZXRlcm1pbmUgaG93IGxvbmdcblx0XHRcdFx0Ly8gdGhlIHBhY2tldCBpcy4gSWYgdGhlIHBhY2tldCBpcyBpbiBhIGZpbGUsIHRoaXMgbWVhbnMgdGhhdFxuXHRcdFx0XHQvLyB0aGUgcGFja2V0IGV4dGVuZHMgdW50aWwgdGhlIGVuZCBvZiB0aGUgZmlsZS4gSW4gZ2VuZXJhbCwgXG5cdFx0XHRcdC8vIGFuIGltcGxlbWVudGF0aW9uIFNIT1VMRCBOT1QgdXNlIGluZGV0ZXJtaW5hdGUtbGVuZ3RoIFxuXHRcdFx0XHQvLyBwYWNrZXRzIGV4Y2VwdCB3aGVyZSB0aGUgZW5kIG9mIHRoZSBkYXRhIHdpbGwgYmUgY2xlYXIgXG5cdFx0XHRcdC8vIGZyb20gdGhlIGNvbnRleHQsIGFuZCBldmVuIHRoZW4gaXQgaXMgYmV0dGVyIHRvIHVzZSBhIFxuXHRcdFx0XHQvLyBkZWZpbml0ZSBsZW5ndGgsIG9yIGEgbmV3IGZvcm1hdCBoZWFkZXIuIFRoZSBuZXcgZm9ybWF0IFxuXHRcdFx0XHQvLyBoZWFkZXJzIGRlc2NyaWJlZCBiZWxvdyBoYXZlIGEgbWVjaGFuaXNtIGZvciBwcmVjaXNlbHlcblx0XHRcdFx0Ly8gZW5jb2RpbmcgZGF0YSBvZiBpbmRldGVybWluYXRlIGxlbmd0aC5cblx0XHRcdFx0cGFja2V0X2xlbmd0aCA9IGxlbjtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgLy8gNC4yLjIuIE5ldyBGb3JtYXQgUGFja2V0IExlbmd0aHNcblx0XHR7XG5cblx0XHRcdC8vIDQuMi4yLjEuIE9uZS1PY3RldCBMZW5ndGhzXG5cdFx0XHRpZiAoaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSA8IDE5Mikge1xuXHRcdFx0XHRwYWNrZXRfbGVuZ3RoID0gaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpO1xuXHRcdFx0XHR1dGlsLnByaW50X2RlYnVnKFwiMSBieXRlIGxlbmd0aDpcIiArIHBhY2tldF9sZW5ndGgpO1xuXHRcdFx0XHQvLyA0LjIuMi4yLiBUd28tT2N0ZXQgTGVuZ3Roc1xuXHRcdFx0fSBlbHNlIGlmIChpbnB1dFtteXBvc10uY2hhckNvZGVBdCgpID49IDE5MlxuXHRcdFx0XHRcdCYmIGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPCAyMjQpIHtcblx0XHRcdFx0cGFja2V0X2xlbmd0aCA9ICgoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIC0gMTkyKSA8PCA4KVxuXHRcdFx0XHRcdFx0KyAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpKSArIDE5Mjtcblx0XHRcdFx0dXRpbC5wcmludF9kZWJ1ZyhcIjIgYnl0ZSBsZW5ndGg6XCIgKyBwYWNrZXRfbGVuZ3RoKTtcblx0XHRcdFx0Ly8gNC4yLjIuNC4gUGFydGlhbCBCb2R5IExlbmd0aHNcblx0XHRcdH0gZWxzZSBpZiAoaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSA+IDIyM1xuXHRcdFx0XHRcdCYmIGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPCAyNTUpIHtcblx0XHRcdFx0cGFja2V0X2xlbmd0aCA9IDEgPDwgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSAmIDB4MUYpO1xuXHRcdFx0XHR1dGlsLnByaW50X2RlYnVnKFwiNCBieXRlIGxlbmd0aDpcIiArIHBhY2tldF9sZW5ndGgpO1xuXHRcdFx0XHQvLyBFRUVLLCB3ZSdyZSByZWFkaW5nIHRoZSBmdWxsIGRhdGEgaGVyZS4uLlxuXHRcdFx0XHR2YXIgbXlwb3MyID0gbXlwb3MgKyBwYWNrZXRfbGVuZ3RoO1xuXHRcdFx0XHRib2R5ZGF0YSA9IGlucHV0LnN1YnN0cmluZyhteXBvcywgbXlwb3MgKyBwYWNrZXRfbGVuZ3RoKTtcblx0XHRcdFx0d2hpbGUgKHRydWUpIHtcblx0XHRcdFx0XHRpZiAoaW5wdXRbbXlwb3MyXS5jaGFyQ29kZUF0KCkgPCAxOTIpIHtcblx0XHRcdFx0XHRcdHZhciB0bXBsZW4gPSBpbnB1dFtteXBvczIrK10uY2hhckNvZGVBdCgpO1xuXHRcdFx0XHRcdFx0cGFja2V0X2xlbmd0aCArPSB0bXBsZW47XG5cdFx0XHRcdFx0XHRib2R5ZGF0YSArPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MyLCBteXBvczIgKyB0bXBsZW4pO1xuXHRcdFx0XHRcdFx0bXlwb3MyICs9IHRtcGxlbjtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoaW5wdXRbbXlwb3MyXS5jaGFyQ29kZUF0KCkgPj0gMTkyXG5cdFx0XHRcdFx0XHRcdCYmIGlucHV0W215cG9zMl0uY2hhckNvZGVBdCgpIDwgMjI0KSB7XG5cdFx0XHRcdFx0XHR2YXIgdG1wbGVuID0gKChpbnB1dFtteXBvczIrK10uY2hhckNvZGVBdCgpIC0gMTkyKSA8PCA4KVxuXHRcdFx0XHRcdFx0XHRcdCsgKGlucHV0W215cG9zMisrXS5jaGFyQ29kZUF0KCkpICsgMTkyO1xuXHRcdFx0XHRcdFx0cGFja2V0X2xlbmd0aCArPSB0bXBsZW47XG5cdFx0XHRcdFx0XHRib2R5ZGF0YSArPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MyLCBteXBvczIgKyB0bXBsZW4pO1xuXHRcdFx0XHRcdFx0bXlwb3MyICs9IHRtcGxlbjtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoaW5wdXRbbXlwb3MyXS5jaGFyQ29kZUF0KCkgPiAyMjNcblx0XHRcdFx0XHRcdFx0JiYgaW5wdXRbbXlwb3MyXS5jaGFyQ29kZUF0KCkgPCAyNTUpIHtcblx0XHRcdFx0XHRcdHZhciB0bXBsZW4gPSAxIDw8IChpbnB1dFtteXBvczIrK10uY2hhckNvZGVBdCgpICYgMHgxRik7XG5cdFx0XHRcdFx0XHRwYWNrZXRfbGVuZ3RoICs9IHRtcGxlbjtcblx0XHRcdFx0XHRcdGJvZHlkYXRhICs9IGlucHV0LnN1YnN0cmluZyhteXBvczIsIG15cG9zMiArIHRtcGxlbik7XG5cdFx0XHRcdFx0XHRteXBvczIgKz0gdG1wbGVuO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRteXBvczIrKztcblx0XHRcdFx0XHRcdHZhciB0bXBsZW4gPSAoaW5wdXRbbXlwb3MyKytdLmNoYXJDb2RlQXQoKSA8PCAyNClcblx0XHRcdFx0XHRcdFx0XHR8IChpbnB1dFtteXBvczIrK10uY2hhckNvZGVBdCgpIDw8IDE2KVxuXHRcdFx0XHRcdFx0XHRcdHwgKGlucHV0W215cG9zMisrXS5jaGFyQ29kZUF0KCkgPDwgOClcblx0XHRcdFx0XHRcdFx0XHR8IGlucHV0W215cG9zMisrXS5jaGFyQ29kZUF0KCk7XG5cdFx0XHRcdFx0XHRib2R5ZGF0YSArPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MyLCBteXBvczIgKyB0bXBsZW4pO1xuXHRcdFx0XHRcdFx0cGFja2V0X2xlbmd0aCArPSB0bXBsZW47XG5cdFx0XHRcdFx0XHRteXBvczIgKz0gdG1wbGVuO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJlYWxfcGFja2V0X2xlbmd0aCA9IG15cG9zMjtcblx0XHRcdFx0Ly8gNC4yLjIuMy4gRml2ZS1PY3RldCBMZW5ndGhzXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRteXBvcysrO1xuXHRcdFx0XHRwYWNrZXRfbGVuZ3RoID0gKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCAyNClcblx0XHRcdFx0XHRcdHwgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCAxNilcblx0XHRcdFx0XHRcdHwgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCA4KVxuXHRcdFx0XHRcdFx0fCBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gaWYgdGhlcmUgd2FzJ250IGEgcGFydGlhbCBib2R5IGxlbmd0aDogdXNlIHRoZSBzcGVjaWZpZWRcblx0XHQvLyBwYWNrZXRfbGVuZ3RoXG5cdFx0aWYgKHJlYWxfcGFja2V0X2xlbmd0aCA9PSAtMSkge1xuXHRcdFx0cmVhbF9wYWNrZXRfbGVuZ3RoID0gcGFja2V0X2xlbmd0aDtcblx0XHR9XG5cblx0XHRpZiAoYm9keWRhdGEgPT0gbnVsbCkge1xuXHRcdFx0Ym9keWRhdGEgPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MsIG15cG9zICsgcmVhbF9wYWNrZXRfbGVuZ3RoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4geyBcblx0XHRcdHRhZzogdGFnLFxuXHRcdFx0cGFja2V0OiBib2R5ZGF0YSxcblx0XHRcdG9mZnNldDogbXlwb3MgKyByZWFsX3BhY2tldF9sZW5ndGhcblx0XHR9O1xuXHR9XG59XG5cbiIsIlxuXG52YXIgcGFja2V0UGFyc2VyID0gcmVxdWlyZSgnLi9wYWNrZXQuanMnKSxcblx0cGFja2V0cyA9IHJlcXVpcmUoJy4vYWxsX3BhY2tldHMuanMnKSxcblx0ZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBUaGlzIGNsYXNzIHJlcHJlc2VudHMgYSBsaXN0IG9mIG9wZW5wZ3AgcGFja2V0cy5cbiAqIFRha2UgY2FyZSB3aGVuIGl0ZXJhdGluZyBvdmVyIGl0IC0gdGhlIHBhY2tldHMgdGhlbXNlbHZlc1xuICogYXJlIHN0b3JlZCBhcyBudW1lcmljYWwgaW5kaWNlcy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRsaXN0KCkge1xuXHQvKiogVGhlIG51bWJlciBvZiBwYWNrZXRzIGNvbnRhaW5lZCB3aXRoaW4gdGhlIGxpc3QuXG5cdCAqIEByZWFkb25seVxuXHQgKiBAdHlwZSB7SW50ZWdlcn0gKi9cblx0dGhpcy5sZW5ndGggPSAwO1xuXG5cblxuXHQvKipcblx0ICogUmVhZHMgYSBzdHJlYW0gb2YgYmluYXJ5IGRhdGEgYW5kIGludGVycHJlbnRzIGl0IGFzIGEgbGlzdCBvZiBwYWNrZXRzLlxuXHQgKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZWFycmF5fSBBbiBhcnJheSBvZiBieXRlcy5cblx0ICovXG5cdHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG5cdFx0dmFyIGkgPSAwO1xuXG5cdFx0d2hpbGUoaSA8IGJ5dGVzLmxlbmd0aCkge1xuXHRcdFx0dmFyIHBhcnNlZCA9IHBhY2tldFBhcnNlci5yZWFkKGJ5dGVzLCBpLCBieXRlcy5sZW5ndGggLSBpKTtcblx0XHRcdGkgPSBwYXJzZWQub2Zmc2V0O1xuXG5cdFx0XHR2YXIgdGFnID0gZW51bXMucmVhZChlbnVtcy5wYWNrZXQsIHBhcnNlZC50YWcpO1xuXHRcdFx0dmFyIHBhY2tldCA9IG5ldyBwYWNrZXRzW3RhZ10oKTtcblxuXHRcdFx0dGhpcy5wdXNoKHBhY2tldCk7XG5cblx0XHRcdHBhY2tldC5yZWFkKHBhcnNlZC5wYWNrZXQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgYmluYXJ5IHJlcHJlc2VudGF0aW9uIG9mIG9wZW5wZ3Agb2JqZWN0cyBjb250YWluZWQgd2l0aGluIHRoZVxuXHQgKiBjbGFzcyBpbnN0YW5jZS5cblx0ICogQHJldHVybnMge29wZW5wZ3BfYnl0ZWFycmF5fSBBbiBhcnJheSBvZiBieXRlcyBjb250YWluaW5nIHZhbGlkIG9wZW5wZ3AgcGFja2V0cy5cblx0ICovXG5cdHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcblx0XHR2YXIgYnl0ZXMgPSAnJztcblxuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR2YXIgcGFja2V0Ynl0ZXMgPSB0aGlzW2ldLndyaXRlKCk7XG5cdFx0XHRieXRlcyArPSBwYWNrZXRQYXJzZXIud3JpdGVIZWFkZXIodGhpc1tpXS50YWcsIHBhY2tldGJ5dGVzLmxlbmd0aCk7XG5cdFx0XHRieXRlcyArPSBwYWNrZXRieXRlcztcblx0XHR9XG5cdFx0XG5cdFx0cmV0dXJuIGJ5dGVzO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFkZHMgYSBwYWNrZXQgdG8gdGhlIGxpc3QuIFRoaXMgaXMgdGhlIG9ubHkgc3VwcG9ydGVkIG1ldGhvZCBvZiBkb2luZyBzbztcblx0ICogd3JpdGluZyB0byBwYWNrZXRsaXN0W2ldIGRpcmVjdGx5IHdpbGwgcmVzdWx0IGluIGFuIGVycm9yLlxuXHQgKi9cblx0dGhpcy5wdXNoID0gZnVuY3Rpb24ocGFja2V0KSB7XG5cdFx0cGFja2V0LnBhY2tldHMgPSBuZXcgcGFja2V0bGlzdCgpO1xuXG5cdFx0dGhpc1t0aGlzLmxlbmd0aF0gPSBwYWNrZXQ7XG5cdFx0dGhpcy5sZW5ndGgrKztcblx0fVxuXG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcblx0dHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpLFxuXHRlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG5cdGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgS2V5IE1hdGVyaWFsIFBhY2tldCAoVGFnIDUsNiw3LDE0KVxuICogICBcbiAqIFJGQzQ0ODAgNS41OlxuICogQSBrZXkgbWF0ZXJpYWwgcGFja2V0IGNvbnRhaW5zIGFsbCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgYSBwdWJsaWMgb3JcbiAqIHByaXZhdGUga2V5LiAgVGhlcmUgYXJlIGZvdXIgdmFyaWFudHMgb2YgdGhpcyBwYWNrZXQgdHlwZSwgYW5kIHR3b1xuICogbWFqb3IgdmVyc2lvbnMuICBDb25zZXF1ZW50bHksIHRoaXMgc2VjdGlvbiBpcyBjb21wbGV4LlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9wdWJsaWNfa2V5KCkge1xuXHQvKiogS2V5IGNyZWF0aW9uIGRhdGUuXG5cdCAqIEB0eXBlIHtEYXRlfSAqL1xuXHR0aGlzLmNyZWF0ZWQgPSBuZXcgRGF0ZSgpO1xuXHQvKiogQSBsaXN0IG9mIG11bHRpcHJlY2lzaW9uIGludGVnZXJzXG5cdCAqIEB0eXBlIHtvcGVucGdwX3R5cGVfbXBpfSAqL1xuXHR0aGlzLm1waSA9IFtdO1xuXHQvKiogUHVibGljIGtleSBhbGdvcml0aG1cblx0ICogQHR5cGUge29wZW5wZ3AucHVibGlja2V5fSAqL1xuXHR0aGlzLmFsZ29yaXRobSA9ICdyc2Ffc2lnbic7XG5cblxuXHQvKipcblx0ICogSW50ZXJuYWwgUGFyc2VyIGZvciBwdWJsaWMga2V5cyBhcyBzcGVjaWZpZWQgaW4gUkZDIDQ4ODAgc2VjdGlvbiBcblx0ICogNS41LjIgUHVibGljLUtleSBQYWNrZXQgRm9ybWF0c1xuXHQgKiBjYWxsZWQgYnkgcmVhZF90YWcmbHQ7bnVtJmd0O1xuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgSW5wdXQgc3RyaW5nIHRvIHJlYWQgdGhlIHBhY2tldCBmcm9tXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gU3RhcnQgcG9zaXRpb24gZm9yIHRoZSBwYXJzZXJcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dFxuXHQgKiBAcmV0dXJuIHtPYmplY3R9IFRoaXMgb2JqZWN0IHdpdGggYXR0cmlidXRlcyBzZXQgYnkgdGhlIHBhcnNlclxuXHQgKi8gIFxuXHR0aGlzLnJlYWRQdWJsaWNLZXkgPSB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuXHRcdC8vIEEgb25lLW9jdGV0IHZlcnNpb24gbnVtYmVyICgzIG9yIDQpLlxuXHRcdHZhciB2ZXJzaW9uID0gYnl0ZXNbMF0uY2hhckNvZGVBdCgpO1xuXG5cdFx0aWYgKHZlcnNpb24gPT0gNCkge1xuXHRcdFx0Ly8gLSBBIGZvdXItb2N0ZXQgbnVtYmVyIGRlbm90aW5nIHRoZSB0aW1lIHRoYXQgdGhlIGtleSB3YXMgY3JlYXRlZC5cblx0XHRcdHRoaXMuY3JlYXRlZCA9IHV0aWwucmVhZERhdGUoYnl0ZXMuc3Vic3RyKDEsIDQpKTtcblx0XHRcdFxuXHRcdFx0Ly8gLSBBIG9uZS1vY3RldCBudW1iZXIgZGVub3RpbmcgdGhlIHB1YmxpYy1rZXkgYWxnb3JpdGhtIG9mIHRoaXMga2V5LlxuXHRcdFx0dGhpcy5hbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSwgYnl0ZXNbNV0uY2hhckNvZGVBdCgpKTtcblxuXHRcdFx0dmFyIG1waWNvdW50ID0gY3J5cHRvLmdldFB1YmxpY01waUNvdW50KHRoaXMuYWxnb3JpdGhtKTtcblx0XHRcdHRoaXMubXBpID0gW107XG5cblx0XHRcdHZhciBibXBpID0gYnl0ZXMuc3Vic3RyKDYpO1xuXHRcdFx0dmFyIHAgPSAwO1xuXG5cdFx0XHRmb3IgKHZhciBpID0gMDsgXG5cdFx0XHRcdGkgPCBtcGljb3VudCAmJiBwIDwgYm1waS5sZW5ndGg7IFxuXHRcdFx0XHRpKyspIHtcblxuXHRcdFx0XHR0aGlzLm1waVtpXSA9IG5ldyB0eXBlX21waSgpO1xuXG5cdFx0XHRcdHAgKz0gdGhpcy5tcGlbaV0ucmVhZChibXBpLnN1YnN0cihwKSlcblxuXHRcdFx0XHRpZihwID4gYm1waS5sZW5ndGgpXG5cdFx0XHRcdFx0dXRpbC5wcmludF9lcnJvcihcIm9wZW5wZ3AucGFja2V0LmtleW1hdGVyaWFsLmpzXFxuXCJcblx0XHRcdFx0XHRcdCsnZXJyb3IgcmVhZGluZyBNUEkgQDonK3ApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gcCArIDY7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignVmVyc2lvbiAnICsgdmVyc2lvbiArICcgb2YgdGhlIGtleSBwYWNrZXQgaXMgdW5zdXBwb3J0ZWQuJyk7XG5cdFx0fVxuXHR9XG5cblx0LypcbiAgICAgKiBTYW1lIGFzIHdyaXRlX3ByaXZhdGVfa2V5LCBidXQgaGFzIGxlc3MgaW5mb3JtYXRpb24gYmVjYXVzZSBvZiBcblx0ICogcHVibGljIGtleS5cbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGtleVR5cGUgRm9sbG93cyB0aGUgT3BlblBHUCBhbGdvcml0aG0gc3RhbmRhcmQsIFxuXHQgKiBJRSAxIGNvcnJlc3BvbmRzIHRvIFJTQS5cbiAgICAgKiBAcGFyYW0ge1JTQS5rZXlPYmplY3R9IGtleVxuICAgICAqIEBwYXJhbSB0aW1lUGFja2V0XG4gICAgICogQHJldHVybiB7T2JqZWN0fSB7Ym9keTogW3N0cmluZ11PcGVuUEdQIHBhY2tldCBib2R5IGNvbnRlbnRzLCBcblx0ICogaGVhZGVyOiBbc3RyaW5nXSBPcGVuUEdQIHBhY2tldCBoZWFkZXIsIHN0cmluZzogW3N0cmluZ10gaGVhZGVyK2JvZHl9XG4gICAgICovXG4gICAgdGhpcy53cml0ZVB1YmxpY0tleSA9IHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcblx0XHQvLyBWZXJzaW9uXG5cdFx0dmFyIHJlc3VsdCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoNCk7XG4gICAgICAgIHJlc3VsdCArPSB1dGlsLndyaXRlRGF0ZSh0aGlzLmNyZWF0ZWQpO1xuXHRcdHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnB1YmxpY0tleSwgdGhpcy5hbGdvcml0aG0pKTtcblxuXHRcdHZhciBtcGljb3VudCA9IGNyeXB0by5nZXRQdWJsaWNNcGlDb3VudCh0aGlzLmFsZ29yaXRobSk7XG5cblx0XHRmb3IodmFyIGkgPSAwOyBpIDwgbXBpY291bnQ7IGkrKykge1xuXHRcdFx0cmVzdWx0ICs9IHRoaXMubXBpW2ldLndyaXRlKCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdC8vIFdyaXRlIGFuIG9sZCB2ZXJzaW9uIHBhY2tldCAtIGl0J3MgdXNlZCBieSBzb21lIG9mIHRoZSBpbnRlcm5hbCByb3V0aW5lcy5cblx0dGhpcy53cml0ZU9sZCA9IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBieXRlcyA9IHRoaXMud3JpdGVQdWJsaWNLZXkoKTtcblxuXHRcdHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4OTkpICtcblx0XHRcdHV0aWwud3JpdGVOdW1iZXIoYnl0ZXMubGVuZ3RoLCAyKSArXG5cdFx0XHRieXRlcztcblx0fVxuXG5cdC8qKlxuXHQgKiBDYWxjdWxhdGVzIHRoZSBrZXkgaWQgb2YgdGhlIGtleSBcblx0ICogQHJldHVybiB7U3RyaW5nfSBBIDggYnl0ZSBrZXkgaWRcblx0ICovXG5cdHRoaXMuZ2V0S2V5SWQgPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRGaW5nZXJwcmludCgpLnN1YnN0cigxMiwgOCk7XG5cdH1cblx0XG5cdC8qKlxuXHQgKiBDYWxjdWxhdGVzIHRoZSBmaW5nZXJwcmludCBvZiB0aGUga2V5XG5cdCAqIEByZXR1cm4ge1N0cmluZ30gQSBzdHJpbmcgY29udGFpbmluZyB0aGUgZmluZ2VycHJpbnRcblx0ICovXG5cdHRoaXMuZ2V0RmluZ2VycHJpbnQgPSBmdW5jdGlvbigpIHtcblx0XHR2YXIgdG9IYXNoID0gdGhpcy53cml0ZU9sZCgpO1xuXHRcdHJldHVybiBjcnlwdG8uaGFzaC5zaGExKHRvSGFzaCwgdG9IYXNoLmxlbmd0aCk7XG5cdH1cblxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHR5cGVfa2V5aWQgPSByZXF1aXJlKCcuLi90eXBlL2tleWlkLmpzJyksXG5cdHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG5cdHR5cGVfbXBpID0gcmVxdWlyZSgnLi4vdHlwZS9tcGkuanMnKSxcblx0ZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuXHRjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblx0XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IFBhY2tldHMgKFRhZyAxKVxuICogXG4gKiBSRkM0ODgwIDUuMTogQSBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXQgaG9sZHMgdGhlIHNlc3Npb24ga2V5XG4gKiB1c2VkIHRvIGVuY3J5cHQgYSBtZXNzYWdlLiBaZXJvIG9yIG1vcmUgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXlcbiAqIHBhY2tldHMgYW5kL29yIFN5bW1ldHJpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldHMgbWF5IHByZWNlZGUgYVxuICogU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQsIHdoaWNoIGhvbGRzIGFuIGVuY3J5cHRlZCBtZXNzYWdlLiBUaGVcbiAqIG1lc3NhZ2UgaXMgZW5jcnlwdGVkIHdpdGggdGhlIHNlc3Npb24ga2V5LCBhbmQgdGhlIHNlc3Npb24ga2V5IGlzIGl0c2VsZlxuICogZW5jcnlwdGVkIGFuZCBzdG9yZWQgaW4gdGhlIEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXQocykuIFRoZVxuICogU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQgaXMgcHJlY2VkZWQgYnkgb25lIFB1YmxpYy1LZXkgRW5jcnlwdGVkXG4gKiBTZXNzaW9uIEtleSBwYWNrZXQgZm9yIGVhY2ggT3BlblBHUCBrZXkgdG8gd2hpY2ggdGhlIG1lc3NhZ2UgaXMgZW5jcnlwdGVkLlxuICogVGhlIHJlY2lwaWVudCBvZiB0aGUgbWVzc2FnZSBmaW5kcyBhIHNlc3Npb24ga2V5IHRoYXQgaXMgZW5jcnlwdGVkIHRvIHRoZWlyXG4gKiBwdWJsaWMga2V5LCBkZWNyeXB0cyB0aGUgc2Vzc2lvbiBrZXksIGFuZCB0aGVuIHVzZXMgdGhlIHNlc3Npb24ga2V5IHRvXG4gKiBkZWNyeXB0IHRoZSBtZXNzYWdlLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9wdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleSgpIHtcblx0dGhpcy52ZXJzaW9uID0gMztcblxuXHR0aGlzLnB1YmxpY0tleUlkID0gbmV3IHR5cGVfa2V5aWQoKTtcblx0dGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSAncnNhX2VuY3J5cHQnO1xuXG5cdHRoaXMuc2Vzc2lvbktleSA9IG51bGw7XG5cdHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9ICdhZXMyNTYnO1xuXG5cdC8qKiBAdHlwZSB7b3BlbnBncF90eXBlX21waVtdfSAqL1xuXHR0aGlzLmVuY3J5cHRlZCA9IFtdO1xuXG5cdC8qKlxuXHQgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHB1YmxpY2tleSBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXkgcGFja2V0ICh0YWcgMSkuXG5cdCAqIFxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxIHBhY2tldFxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIExlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mXG5cdCAqICAgICAgICAgICAgaW5wdXQgYXQgcG9zaXRpb25cblx0ICogQHJldHVybiB7b3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkZGF0YX0gT2JqZWN0IHJlcHJlc2VudGF0aW9uXG5cdCAqL1xuXHR0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuXG5cdFx0dGhpcy52ZXJzaW9uID0gYnl0ZXNbMF0uY2hhckNvZGVBdCgpO1xuXHRcdHRoaXMucHVibGljS2V5SWQucmVhZChieXRlcy5zdWJzdHIoMSkpO1xuXHRcdHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIGJ5dGVzWzldLmNoYXJDb2RlQXQoKSk7XG5cblx0XHR2YXIgaSA9IDEwO1xuXG5cdFx0dmFyIGludGVnZXJDb3VudCA9IChmdW5jdGlvbihhbGdvKSB7XG5cdFx0XHRzd2l0Y2ggKGFsZ28pIHtcblx0XHRcdGNhc2UgJ3JzYV9lbmNyeXB0Jzpcblx0XHRcdGNhc2UgJ3JzYV9lbmNyeXB0X3NpZ24nOlxuXHRcdFx0XHRyZXR1cm4gMTtcblxuXHRcdFx0Y2FzZSAnZWxnYW1hbCc6XG5cdFx0XHRcdHJldHVybiAyO1xuXG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGFsZ29yaXRobS5cIik7XG5cdFx0XHR9XG5cdFx0fSkodGhpcy5wdWJsaWNLZXlBbGdvcml0aG0pO1xuXG5cdFx0dGhpcy5lbmNyeXB0ZWQgPSBbXTtcblxuXHRcdGZvcih2YXIgaiA9IDA7IGogPCBpbnRlZ2VyQ291bnQ7IGorKykge1xuXHRcdFx0dmFyIG1waSA9IG5ldyB0eXBlX21waSgpO1xuXHRcdFx0aSArPSBtcGkucmVhZChieXRlcy5zdWJzdHIoaSkpO1xuXHRcdFx0dGhpcy5lbmNyeXB0ZWQucHVzaChtcGkpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSB0YWcgMSBwYWNrZXRcblx0ICogXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBwdWJsaWNLZXlJZFxuXHQgKiAgICAgICAgICAgICBUaGUgcHVibGljIGtleSBpZCBjb3JyZXNwb25kaW5nIHRvIHB1YmxpY01QSXMga2V5IGFzIHN0cmluZ1xuXHQgKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gcHVibGljTVBJc1xuXHQgKiAgICAgICAgICAgIE11bHRpcHJlY2lzaW9uIGludGVnZXIgb2JqZWN0cyBkZXNjcmliaW5nIHRoZSBwdWJsaWMga2V5XG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gcHViYWxnb1xuXHQgKiAgICAgICAgICAgIFRoZSBjb3JyZXNwb25kaW5nIHB1YmxpYyBrZXkgYWxnb3JpdGhtIC8vIFNlZSBSRkM0ODgwIDkuMVxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IHN5bW1hbGdvXG5cdCAqICAgICAgICAgICAgVGhlIHN5bW1ldHJpYyBjaXBoZXIgYWxnb3JpdGhtIHVzZWQgdG8gZW5jcnlwdCB0aGUgZGF0YSBcblx0ICogICAgICAgICAgICB3aXRoaW4gYW4gZW5jcnlwdGVkZGF0YXBhY2tldCBvciBlbmNyeXB0ZWRpbnRlZ3JpdHktXG5cdCAqICAgICAgICAgICAgcHJvdGVjdGVkZGF0YXBhY2tldCBcblx0ICogICAgICAgICAgICBmb2xsb3dpbmcgdGhpcyBwYWNrZXQgLy9TZWUgUkZDNDg4MCA5LjJcblx0ICogQHBhcmFtIHtTdHJpbmd9IHNlc3Npb25rZXlcblx0ICogICAgICAgICAgICBBIHN0cmluZyBvZiByYW5kb21ieXRlcyByZXByZXNlbnRpbmcgdGhlIHNlc3Npb24ga2V5XG5cdCAqIEByZXR1cm4ge1N0cmluZ30gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvblxuXHQgKi9cblx0dGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0dmFyIHJlc3VsdCA9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy52ZXJzaW9uKTtcblx0XHRyZXN1bHQgKz0gdGhpcy5wdWJsaWNLZXlJZC53cml0ZSgpO1xuXHRcdHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuXHRcdFx0ZW51bXMud3JpdGUoZW51bXMucHVibGljS2V5LCB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSkpO1xuXG5cdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgdGhpcy5lbmNyeXB0ZWQubGVuZ3RoOyBpKyspIHtcblx0XHRcdHJlc3VsdCArPSB0aGlzLmVuY3J5cHRlZFtpXS53cml0ZSgpXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGtleSkge1xuXHRcdHZhciBkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZShcblx0XHRcdGVudW1zLndyaXRlKGVudW1zLnN5bW1ldHJpYywgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtKSk7XG5cblx0XHRkYXRhICs9IHRoaXMuc2Vzc2lvbktleTtcblx0XHR2YXIgY2hlY2tzdW0gPSB1dGlsLmNhbGNfY2hlY2tzdW0odGhpcy5zZXNzaW9uS2V5KTtcblx0XHRkYXRhICs9IHV0aWwud3JpdGVOdW1iZXIoY2hlY2tzdW0sIDIpO1xuXG5cdFx0dmFyIG1waSA9IG5ldyB0eXBlX21waSgpO1xuXHRcdG1waS5mcm9tQnl0ZXMoY3J5cHRvLnBrY3MxLmVtZS5lbmNvZGUoXG5cdFx0XHRkYXRhLFxuXHRcdFx0a2V5Lm1waVswXS5ieXRlTGVuZ3RoKCkpKTtcblxuXHRcdHRoaXMuZW5jcnlwdGVkID0gY3J5cHRvLnB1YmxpY0tleUVuY3J5cHQoXG5cdFx0XHR0aGlzLnB1YmxpY0tleUFsZ29yaXRobSwgXG5cdFx0XHRrZXkubXBpLFxuXHRcdFx0bXBpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZWNyeXB0cyB0aGUgc2Vzc2lvbiBrZXkgKG9ubHkgZm9yIHB1YmxpYyBrZXkgZW5jcnlwdGVkIHNlc3Npb24ga2V5XG5cdCAqIHBhY2tldHMgKHRhZyAxKVxuXHQgKiBcblx0ICogQHBhcmFtIHtvcGVucGdwX21zZ19tZXNzYWdlfSBtc2dcblx0ICogICAgICAgICAgICBUaGUgbWVzc2FnZSBvYmplY3QgKHdpdGggbWVtYmVyIGVuY3J5cHRlZERhdGFcblx0ICogQHBhcmFtIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBrZXlcblx0ICogICAgICAgICAgICBQcml2YXRlIGtleSB3aXRoIHNlY01QSXMgdW5sb2NrZWRcblx0ICogQHJldHVybiB7U3RyaW5nfSBUaGUgdW5lbmNyeXB0ZWQgc2Vzc2lvbiBrZXlcblx0ICovXG5cdHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKGtleSkge1xuXHRcdHZhciByZXN1bHQgPSBjcnlwdG8ucHVibGljS2V5RGVjcnlwdChcblx0XHRcdFx0dGhpcy5wdWJsaWNLZXlBbGdvcml0aG0sXG5cdFx0XHRcdGtleS5tcGksXG5cdFx0XHRcdHRoaXMuZW5jcnlwdGVkKS50b0J5dGVzKCk7XG5cblx0XHR2YXIgY2hlY2tzdW0gPSB1dGlsLnJlYWROdW1iZXIocmVzdWx0LnN1YnN0cihyZXN1bHQubGVuZ3RoIC0gMikpO1xuXG5cdFx0dmFyIGRlY29kZWQgPSBjcnlwdG8ucGtjczEuZW1lLmRlY29kZShcblx0XHRcdHJlc3VsdCxcblx0XHRcdGtleS5tcGlbMF0uYnl0ZUxlbmd0aCgpKTtcblxuXHRcdHZhciBrZXkgPSBkZWNvZGVkLnN1YnN0cmluZygxLCBkZWNvZGVkLmxlbmd0aCAtIDIpO1xuXG5cdFx0aWYoY2hlY2tzdW0gIT0gdXRpbC5jYWxjX2NoZWNrc3VtKGtleSkpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignQ2hlY2tzdW0gbWlzbWF0Y2gnKTtcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHR0aGlzLnNlc3Npb25LZXkgPSBrZXk7XG5cdFx0XHR0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0gPSBcblx0XHRcdFx0ZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIGRlY29kZWQuY2hhckNvZGVBdCgwKSk7XG5cdFx0fVxuXHR9XG59O1xuXG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgcHVibGljX2tleSA9IHJlcXVpcmUoJy4vcHVibGljX2tleS5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHB1YmxpY19zdWJrZXkoKSB7XG5cdHB1YmxpY19rZXkuY2FsbCh0aGlzKTtcbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBwdWJsaWNLZXkgPSByZXF1aXJlKCcuL3B1YmxpY19rZXkuanMnKSxcblx0ZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuXHR1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuXHRjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKSxcblx0dHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpLFxuXHR0eXBlX3MyayA9IHJlcXVpcmUoJy4uL3R5cGUvczJrLmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBLZXkgTWF0ZXJpYWwgUGFja2V0IChUYWcgNSw2LDcsMTQpXG4gKiAgIFxuICogUkZDNDQ4MCA1LjU6XG4gKiBBIGtleSBtYXRlcmlhbCBwYWNrZXQgY29udGFpbnMgYWxsIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBhIHB1YmxpYyBvclxuICogcHJpdmF0ZSBrZXkuICBUaGVyZSBhcmUgZm91ciB2YXJpYW50cyBvZiB0aGlzIHBhY2tldCB0eXBlLCBhbmQgdHdvXG4gKiBtYWpvciB2ZXJzaW9ucy4gIENvbnNlcXVlbnRseSwgdGhpcyBzZWN0aW9uIGlzIGNvbXBsZXguXG4gKi9cbmZ1bmN0aW9uIHBhY2tldF9zZWNyZXRfa2V5KCkge1xuXHRwdWJsaWNLZXkuY2FsbCh0aGlzKTtcblxuXHR0aGlzLmVuY3J5cHRlZCA9IG51bGw7XG5cblxuXHRmdW5jdGlvbiBnZXRfaGFzaF9sZW4oaGFzaCkge1xuXHRcdGlmKGhhc2ggPT0gJ3NoYTEnKVxuXHRcdFx0cmV0dXJuIDIwO1xuXHRcdGVsc2Vcblx0XHRcdHJldHVybiAyO1xuXHR9XG5cblx0ZnVuY3Rpb24gZ2V0X2hhc2hfZm4oaGFzaCkge1xuXHRcdGlmKGhhc2ggPT0gJ3NoYTEnKVxuXHRcdFx0cmV0dXJuIGNyeXB0by5oYXNoLnNoYTE7XG5cdFx0ZWxzZVxuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKGMpIHtcblx0XHRcdFx0XHRyZXR1cm4gdXRpbC53cml0ZU51bWJlcih1dGlsLmNhbGNfY2hlY2tzdW0oYyksIDIpO1xuXHRcdFx0XHR9XG5cdH1cblxuXHQvLyBIZWxwZXIgZnVuY3Rpb25cblx0ZnVuY3Rpb24gcGFyc2VfY2xlYXJ0ZXh0X21waShoYXNoX2FsZ29yaXRobSwgY2xlYXJ0ZXh0LCBhbGdvcml0aG0pIHtcblx0XHR2YXIgaGFzaGxlbiA9IGdldF9oYXNoX2xlbihoYXNoX2FsZ29yaXRobSksXG5cdFx0XHRoYXNoZm4gPSBnZXRfaGFzaF9mbihoYXNoX2FsZ29yaXRobSk7XG5cblx0XHR2YXIgaGFzaHRleHQgPSBjbGVhcnRleHQuc3Vic3RyKGNsZWFydGV4dC5sZW5ndGggLSBoYXNobGVuKTtcblx0XHRjbGVhcnRleHQgPSBjbGVhcnRleHQuc3Vic3RyKDAsIGNsZWFydGV4dC5sZW5ndGggLSBoYXNobGVuKTtcblxuXHRcdHZhciBoYXNoID0gaGFzaGZuKGNsZWFydGV4dCk7XG5cblx0XHRpZihoYXNoICE9IGhhc2h0ZXh0KVxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiSGFzaCBtaXNtYXRjaC5cIik7XG5cblx0XHR2YXIgbXBpcyA9IGNyeXB0by5nZXRQcml2YXRlTXBpQ291bnQoYWxnb3JpdGhtKTtcblxuXHRcdHZhciBqID0gMDtcblx0XHR2YXIgbXBpID0gW107XG5cblx0XHRmb3IodmFyIGkgPSAwOyBpIDwgbXBpcyAmJiBqIDwgY2xlYXJ0ZXh0Lmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRtcGlbaV0gPSBuZXcgdHlwZV9tcGkoKTtcblx0XHRcdGogKz0gbXBpW2ldLnJlYWQoY2xlYXJ0ZXh0LnN1YnN0cihqKSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG1waTtcblx0fVxuXG5cdGZ1bmN0aW9uIHdyaXRlX2NsZWFydGV4dF9tcGkoaGFzaF9hbGdvcml0aG0sIGFsZ29yaXRobSwgbXBpKSB7XG5cdFx0dmFyIGJ5dGVzPSAnJztcblx0XHR2YXIgZGlzY2FyZCA9IGNyeXB0by5nZXRQdWJsaWNNcGlDb3VudChhbGdvcml0aG0pO1xuXG5cdFx0Zm9yKHZhciBpID0gZGlzY2FyZDsgaSA8IG1waS5sZW5ndGg7IGkrKykge1xuXHRcdFx0Ynl0ZXMgKz0gbXBpW2ldLndyaXRlKCk7XG5cdFx0fVxuXG5cblx0XHRieXRlcyArPSBnZXRfaGFzaF9mbihoYXNoX2FsZ29yaXRobSkoYnl0ZXMpO1xuXHRcdFxuXHRcdHJldHVybiBieXRlcztcblx0fVxuXHRcdFxuXG5cdC8vIDUuNS4zLiAgU2VjcmV0LUtleSBQYWNrZXQgRm9ybWF0c1xuXHRcblx0LyoqXG5cdCAqIEludGVybmFsIHBhcnNlciBmb3IgcHJpdmF0ZSBrZXlzIGFzIHNwZWNpZmllZCBpbiBSRkMgNDg4MCBzZWN0aW9uIDUuNS4zXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBJbnB1dCBzdHJpbmcgdG8gcmVhZCB0aGUgcGFja2V0IGZyb21cblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBTdGFydCBwb3NpdGlvbiBmb3IgdGhlIHBhcnNlclxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBMZW5ndGggb2YgdGhlIHBhY2tldCBvciByZW1haW5pbmcgbGVuZ3RoIG9mIGJ5dGVzXG5cdCAqIEByZXR1cm4ge09iamVjdH0gVGhpcyBvYmplY3Qgd2l0aCBhdHRyaWJ1dGVzIHNldCBieSB0aGUgcGFyc2VyXG5cdCAqL1xuXHR0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuXHQgICAgLy8gLSBBIFB1YmxpYy1LZXkgb3IgUHVibGljLVN1YmtleSBwYWNrZXQsIGFzIGRlc2NyaWJlZCBhYm92ZS5cblx0XHR2YXIgbGVuID0gdGhpcy5yZWFkUHVibGljS2V5KGJ5dGVzKTtcblxuXHQgICAgYnl0ZXMgPSBieXRlcy5zdWJzdHIobGVuKTtcblxuXHRcdFxuXHQgICAgLy8gLSBPbmUgb2N0ZXQgaW5kaWNhdGluZyBzdHJpbmctdG8ta2V5IHVzYWdlIGNvbnZlbnRpb25zLiAgWmVyb1xuXHQgICAgLy8gICBpbmRpY2F0ZXMgdGhhdCB0aGUgc2VjcmV0LWtleSBkYXRhIGlzIG5vdCBlbmNyeXB0ZWQuICAyNTUgb3IgMjU0XG5cdCAgICAvLyAgIGluZGljYXRlcyB0aGF0IGEgc3RyaW5nLXRvLWtleSBzcGVjaWZpZXIgaXMgYmVpbmcgZ2l2ZW4uICBBbnlcblx0ICAgIC8vICAgb3RoZXIgdmFsdWUgaXMgYSBzeW1tZXRyaWMta2V5IGVuY3J5cHRpb24gYWxnb3JpdGhtIGlkZW50aWZpZXIuXG5cdCAgICB2YXIgaXNFbmNyeXB0ZWQgPSBieXRlc1swXS5jaGFyQ29kZUF0KCk7XG5cblx0XHRpZihpc0VuY3J5cHRlZCkge1xuXHRcdFx0dGhpcy5lbmNyeXB0ZWQgPSBieXRlcztcblx0XHR9IGVsc2Uge1xuXHRcblx0XHRcdC8vIC0gUGxhaW4gb3IgZW5jcnlwdGVkIG11bHRpcHJlY2lzaW9uIGludGVnZXJzIGNvbXByaXNpbmcgdGhlIHNlY3JldFxuXHRcdFx0Ly8gICBrZXkgZGF0YS4gIFRoZXNlIGFsZ29yaXRobS1zcGVjaWZpYyBmaWVsZHMgYXJlIGFzIGRlc2NyaWJlZFxuXHRcdFx0Ly8gICBiZWxvdy5cblxuXHRcdFx0dGhpcy5tcGkgPSB0aGlzLm1waS5jb25jYXQocGFyc2VfY2xlYXJ0ZXh0X21waSgnbW9kJywgYnl0ZXMuc3Vic3RyKDEpLFxuXHRcdFx0XHR0aGlzLmFsZ29yaXRobSkpO1xuXHRcdH0gICAgXG5cblx0fVxuXHRcblx0LypcbiAgICAgKiBDcmVhdGVzIGFuIE9wZW5QR1Aga2V5IHBhY2tldCBmb3IgdGhlIGdpdmVuIGtleS4gbXVjaCBcblx0ICogVE9ETyBpbiByZWdhcmRzIHRvIHMyaywgc3Via2V5cy5cbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGtleVR5cGUgRm9sbG93cyB0aGUgT3BlblBHUCBhbGdvcml0aG0gc3RhbmRhcmQsIFxuXHQgKiBJRSAxIGNvcnJlc3BvbmRzIHRvIFJTQS5cbiAgICAgKiBAcGFyYW0ge1JTQS5rZXlPYmplY3R9IGtleVxuICAgICAqIEBwYXJhbSBwYXNzcGhyYXNlXG4gICAgICogQHBhcmFtIHMya0hhc2hcbiAgICAgKiBAcGFyYW0gc3ltbWV0cmljRW5jcnlwdGlvbkFsZ29yaXRobVxuICAgICAqIEBwYXJhbSB0aW1lUGFja2V0XG4gICAgICogQHJldHVybiB7T2JqZWN0fSB7Ym9keTogW3N0cmluZ11PcGVuUEdQIHBhY2tldCBib2R5IGNvbnRlbnRzLCBcblx0XHRoZWFkZXI6IFtzdHJpbmddIE9wZW5QR1AgcGFja2V0IGhlYWRlciwgc3RyaW5nOiBbc3RyaW5nXSBoZWFkZXIrYm9keX1cbiAgICAgKi9cbiAgICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGJ5dGVzID0gdGhpcy53cml0ZVB1YmxpY0tleSgpO1xuXG5cdFx0aWYoIXRoaXMuZW5jcnlwdGVkKSB7XG5cdFx0XHRieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuXHRcdFx0XG5cdFx0XHRieXRlcyArPSB3cml0ZV9jbGVhcnRleHRfbXBpKCdtb2QnLCB0aGlzLmFsZ29yaXRobSwgdGhpcy5tcGkpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRieXRlcyArPSB0aGlzLmVuY3J5cHRlZDtcblx0XHR9XG5cblx0XHRyZXR1cm4gYnl0ZXM7XG5cdH1cblx0XHRcdFxuXG5cblxuXHQvKiogRW5jcnlwdCB0aGUgcGF5bG9hZC4gQnkgZGVmYXVsdCwgd2UgdXNlIGFlczI1NiBhbmQgaXRlcmF0ZWQsIHNhbHRlZCBzdHJpbmdcblx0ICogdG8ga2V5IHNwZWNpZmllclxuXHQgKiBAcGFyYW0ge1N0cmluZ30gcGFzc3BocmFzZVxuXHQgKi9cbiAgICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihwYXNzcGhyYXNlKSB7XG5cblx0XHR2YXIgczJrID0gbmV3IHR5cGVfczJrKCksXG5cdFx0XHRzeW1tZXRyaWMgPSAnYWVzMjU2Jyxcblx0XHRcdGNsZWFydGV4dCA9IHdyaXRlX2NsZWFydGV4dF9tcGkoJ3NoYTEnLCB0aGlzLmFsZ29yaXRobSwgdGhpcy5tcGkpLFxuXHRcdFx0a2V5ID0gcHJvZHVjZUVuY3J5cHRpb25LZXkoczJrLCBwYXNzcGhyYXNlLCBzeW1tZXRyaWMpLFxuXHRcdFx0YmxvY2tMZW4gPSBjcnlwdG8uY2lwaGVyW3N5bW1ldHJpY10uYmxvY2tTaXplLFxuXHRcdFx0aXYgPSBjcnlwdG8ucmFuZG9tLmdldFJhbmRvbUJ5dGVzKGJsb2NrTGVuKTtcblxuXG5cdFx0dGhpcy5lbmNyeXB0ZWQgPSAnJztcblx0XHR0aGlzLmVuY3J5cHRlZCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDI1NCk7XG5cdFx0dGhpcy5lbmNyeXB0ZWQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIHN5bW1ldHJpYykpO1xuXHRcdHRoaXMuZW5jcnlwdGVkICs9IHMyay53cml0ZSgpO1xuXHRcdHRoaXMuZW5jcnlwdGVkICs9IGl2O1xuXG5cblxuXHRcdHRoaXMuZW5jcnlwdGVkICs9IGNyeXB0by5jZmIubm9ybWFsRW5jcnlwdChzeW1tZXRyaWMsIGtleSwgY2xlYXJ0ZXh0LCBpdik7XG4gICAgfVxuXG5cdGZ1bmN0aW9uIHByb2R1Y2VFbmNyeXB0aW9uS2V5KHMyaywgcGFzc3BocmFzZSwgYWxnb3JpdGhtKSB7XG5cdFx0cmV0dXJuIHMyay5wcm9kdWNlX2tleShwYXNzcGhyYXNlLFxuXHRcdFx0Y3J5cHRvLmNpcGhlclthbGdvcml0aG1dLmtleVNpemUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlY3J5cHRzIHRoZSBwcml2YXRlIGtleSBNUElzIHdoaWNoIGFyZSBuZWVkZWQgdG8gdXNlIHRoZSBrZXkuXG5cdCAqIG9wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsLmhhc1VuZW5jcnlwdGVkU2VjcmV0S2V5RGF0YSBzaG91bGQgYmUgXG5cdCAqIGZhbHNlIG90aGVyd2lzZVxuXHQgKiBhIGNhbGwgdG8gdGhpcyBmdW5jdGlvbiBpcyBub3QgbmVlZGVkXG5cdCAqIFxuXHQgKiBAcGFyYW0ge1N0cmluZ30gc3RyX3Bhc3NwaHJhc2UgVGhlIHBhc3NwaHJhc2UgZm9yIHRoaXMgcHJpdmF0ZSBrZXkgXG5cdCAqIGFzIHN0cmluZ1xuXHQgKiBAcmV0dXJuIHtCb29sZWFufSBUcnVlIGlmIHRoZSBwYXNzcGhyYXNlIHdhcyBjb3JyZWN0OyBmYWxzZSBpZiBub3Rcblx0ICovXG5cdHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UpIHtcblx0XHRpZiAoIXRoaXMuZW5jcnlwdGVkKVxuXHRcdFx0cmV0dXJuO1xuXG5cdFx0dmFyIGkgPSAwLFxuXHRcdFx0c3ltbWV0cmljLFxuXHRcdFx0a2V5O1xuXG5cdFx0dmFyIHMya191c2FnZSA9IHRoaXMuZW5jcnlwdGVkW2krK10uY2hhckNvZGVBdCgpO1xuXG5cdCAgICAvLyAtIFtPcHRpb25hbF0gSWYgc3RyaW5nLXRvLWtleSB1c2FnZSBvY3RldCB3YXMgMjU1IG9yIDI1NCwgYSBvbmUtXG5cdCAgICAvLyAgIG9jdGV0IHN5bW1ldHJpYyBlbmNyeXB0aW9uIGFsZ29yaXRobS5cblx0ICAgIGlmIChzMmtfdXNhZ2UgPT0gMjU1IHx8IHMya191c2FnZSA9PSAyNTQpIHtcblx0ICAgIFx0c3ltbWV0cmljID0gdGhpcy5lbmNyeXB0ZWRbaSsrXS5jaGFyQ29kZUF0KCk7XG5cdFx0XHRzeW1tZXRyaWMgPSBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYywgc3ltbWV0cmljKTtcblx0ICAgICBcblx0XHRcdC8vIC0gW09wdGlvbmFsXSBJZiBzdHJpbmctdG8ta2V5IHVzYWdlIG9jdGV0IHdhcyAyNTUgb3IgMjU0LCBhXG5cdFx0XHQvLyAgIHN0cmluZy10by1rZXkgc3BlY2lmaWVyLiAgVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nLXRvLWtleVxuXHRcdFx0Ly8gICBzcGVjaWZpZXIgaXMgaW1wbGllZCBieSBpdHMgdHlwZSwgYXMgZGVzY3JpYmVkIGFib3ZlLlxuXHQgICAgXHR2YXIgczJrID0gbmV3IHR5cGVfczJrKCk7XG5cdCAgICBcdGkgKz0gczJrLnJlYWQodGhpcy5lbmNyeXB0ZWQuc3Vic3RyKGkpKTtcblxuXHRcdFx0a2V5ID0gcHJvZHVjZUVuY3J5cHRpb25LZXkoczJrLCBwYXNzcGhyYXNlLCBzeW1tZXRyaWMpO1xuXHQgICAgfSBlbHNlIHtcblx0XHRcdHN5bW1ldHJpYyA9IHMya191c2FnZTtcblx0XHRcdHN5bW1ldHJpYyA9IGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBzeW1tZXRyaWMpO1xuXHRcdFx0a2V5ID0gY3J5cHRvLmhhc2gubWQ1KHBhc3NwaHJhc2UpO1xuXHRcdH1cblxuXHQgICAgXG5cdCAgICAvLyAtIFtPcHRpb25hbF0gSWYgc2VjcmV0IGRhdGEgaXMgZW5jcnlwdGVkIChzdHJpbmctdG8ta2V5IHVzYWdlIG9jdGV0XG5cdCAgICAvLyAgIG5vdCB6ZXJvKSwgYW4gSW5pdGlhbCBWZWN0b3IgKElWKSBvZiB0aGUgc2FtZSBsZW5ndGggYXMgdGhlXG5cdCAgICAvLyAgIGNpcGhlcidzIGJsb2NrIHNpemUuXG5cdFx0dmFyIGl2ID0gdGhpcy5lbmNyeXB0ZWQuc3Vic3RyKGksIFxuXHRcdFx0Y3J5cHRvLmNpcGhlcltzeW1tZXRyaWNdLmJsb2NrU2l6ZSk7XG5cblx0XHRpICs9IGl2Lmxlbmd0aDtcblxuXHRcdHZhciBjbGVhcnRleHQsXG5cdFx0XHRjaXBoZXJ0ZXh0ID0gdGhpcy5lbmNyeXB0ZWQuc3Vic3RyKGkpO1xuXG4gXHRcdGNsZWFydGV4dCA9IGNyeXB0by5jZmIubm9ybWFsRGVjcnlwdChzeW1tZXRyaWMsIGtleSwgY2lwaGVydGV4dCwgaXYpO1xuXG5cdFx0dmFyIGhhc2ggPSBzMmtfdXNhZ2UgPT0gMjU0ID9cblx0XHRcdCdzaGExJyA6XG5cdFx0XHQnbW9kJztcblxuICAgXHRcblx0XHR0aGlzLm1waSA9IHRoaXMubXBpLmNvbmNhdChwYXJzZV9jbGVhcnRleHRfbXBpKGhhc2gsIGNsZWFydGV4dCxcblx0XHRcdHRoaXMuYWxnb3JpdGhtKSk7XG5cdH1cblxuXHR0aGlzLmdlbmVyYXRlID0gZnVuY3Rpb24oYml0cykge1xuXG5cdH1cblx0XG59XG5cbnBhY2tldF9zZWNyZXRfa2V5LnByb3RvdHlwZSA9IG5ldyBwdWJsaWNLZXk7XG5cbm1vZHVsZS5leHBvcnRzID0gcGFja2V0X3NlY3JldF9rZXk7XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgc2VjcmV0X2tleSA9IHJlcXVpcmUoJy4vc2VjcmV0X2tleS5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHNlY3JldF9zdWJrZXkoKSB7XG5cdHNlY3JldF9rZXkuY2FsbCh0aGlzKTtcbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuXHRwYWNrZXQgPSByZXF1aXJlKCcuL3BhY2tldC5qcycpLFxuXHRlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG5cdGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpLFxuXHR0eXBlX21waSA9IHJlcXVpcmUoJy4uL3R5cGUvbXBpLmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTaWduYXR1cmUgUGFja2V0IChUYWcgMilcbiAqIFxuICogUkZDNDQ4MCA1LjI6XG4gKiBBIFNpZ25hdHVyZSBwYWNrZXQgZGVzY3JpYmVzIGEgYmluZGluZyBiZXR3ZWVuIHNvbWUgcHVibGljIGtleSBhbmRcbiAqIHNvbWUgZGF0YS4gIFRoZSBtb3N0IGNvbW1vbiBzaWduYXR1cmVzIGFyZSBhIHNpZ25hdHVyZSBvZiBhIGZpbGUgb3IgYVxuICogYmxvY2sgb2YgdGV4dCwgYW5kIGEgc2lnbmF0dXJlIHRoYXQgaXMgYSBjZXJ0aWZpY2F0aW9uIG9mIGEgVXNlciBJRC5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfc2lnbmF0dXJlKCkge1xuXG5cdHRoaXMuc2lnbmF0dXJlVHlwZSA9IG51bGw7XG5cdHRoaXMuaGFzaEFsZ29yaXRobSA9IG51bGw7XG5cdHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gbnVsbDsgXG5cblx0dGhpcy5zaWduYXR1cmVEYXRhID0gbnVsbDtcblx0dGhpcy5zaWduZWRIYXNoVmFsdWUgPSBudWxsO1xuXHR0aGlzLm1waSA9IG51bGw7XG5cblx0dGhpcy5jcmVhdGVkID0gbnVsbDtcblx0dGhpcy5zaWduYXR1cmVFeHBpcmF0aW9uVGltZSA9IG51bGw7XG5cdHRoaXMuc2lnbmF0dXJlTmV2ZXJFeHBpcmVzID0gbnVsbDtcblx0dGhpcy5leHBvcnRhYmxlID0gbnVsbDtcblx0dGhpcy50cnVzdExldmVsID0gbnVsbDtcblx0dGhpcy50cnVzdEFtb3VudCA9IG51bGw7XG5cdHRoaXMucmVndWxhckV4cHJlc3Npb24gPSBudWxsO1xuXHR0aGlzLnJldm9jYWJsZSA9IG51bGw7XG5cdHRoaXMua2V5RXhwaXJhdGlvblRpbWUgPSBudWxsO1xuXHR0aGlzLmtleU5ldmVyRXhwaXJlcyA9IG51bGw7XG5cdHRoaXMucHJlZmVycmVkU3ltbWV0cmljQWxnb3JpdGhtcyA9IG51bGw7XG5cdHRoaXMucmV2b2NhdGlvbktleUNsYXNzID0gbnVsbDtcblx0dGhpcy5yZXZvY2F0aW9uS2V5QWxnb3JpdGhtID0gbnVsbDtcblx0dGhpcy5yZXZvY2F0aW9uS2V5RmluZ2VycHJpbnQgPSBudWxsO1xuXHR0aGlzLmlzc3VlcktleUlkID0gbnVsbDtcblx0dGhpcy5ub3RhdGlvbiA9IHt9O1xuXHR0aGlzLnByZWZlcnJlZEhhc2hBbGdvcml0aG1zID0gbnVsbDtcblx0dGhpcy5wcmVmZXJyZWRDb21wcmVzc2lvbkFsZ29yaXRobXMgPSBudWxsO1xuXHR0aGlzLmtleVNlcnZlclByZWZlcmVuY2VzID0gbnVsbDtcblx0dGhpcy5wcmVmZXJyZWRLZXlTZXJ2ZXIgPSBudWxsO1xuXHR0aGlzLmlzUHJpbWFyeVVzZXJJRCA9IG51bGw7XG5cdHRoaXMucG9saWN5VVJJID0gbnVsbDtcblx0dGhpcy5rZXlGbGFncyA9IG51bGw7XG5cdHRoaXMuc2lnbmVyc1VzZXJJZCA9IG51bGw7XG5cdHRoaXMucmVhc29uRm9yUmV2b2NhdGlvbkZsYWcgPSBudWxsO1xuXHR0aGlzLnJlYXNvbkZvclJldm9jYXRpb25TdHJpbmcgPSBudWxsO1xuXHR0aGlzLnNpZ25hdHVyZVRhcmdldFB1YmxpY0tleUFsZ29yaXRobSA9IG51bGw7XG5cdHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSA9IG51bGw7XG5cdHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaCA9IG51bGw7XG5cdHRoaXMuZW1iZWRkZWRTaWduYXR1cmUgPSBudWxsO1xuXG5cdHRoaXMudmVyaWZpZWQgPSBmYWxzZTtcblx0XG5cblx0LyoqXG5cdCAqIHBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgc2lnbmF0dXJlIHBhY2tldCAodGFnIDIpLlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gYnl0ZXMgcGF5bG9hZCBvZiBhIHRhZyAyIHBhY2tldFxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIHBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgYnl0ZXMgc3RyaW5nXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuIGxlbmd0aCBvZiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mIGJ5dGVzIGF0IHBvc2l0aW9uXG5cdCAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IG9iamVjdCByZXByZXNlbnRhdGlvblxuXHQgKi9cblx0dGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcblx0XHR2YXIgaSA9IDA7XG5cblx0XHR2YXIgdmVyc2lvbiA9IGJ5dGVzW2krK10uY2hhckNvZGVBdCgpO1xuXHRcdC8vIHN3aXRjaCBvbiB2ZXJzaW9uICgzIGFuZCA0KVxuXHRcdHN3aXRjaCAodmVyc2lvbikge1xuXHRcdGNhc2UgMzpcblx0XHRcdC8vIE9uZS1vY3RldCBsZW5ndGggb2YgZm9sbG93aW5nIGhhc2hlZCBtYXRlcmlhbC4gTVVTVCBiZSA1LlxuXHRcdFx0aWYgKGJ5dGVzW2krK10uY2hhckNvZGVBdCgpICE9IDUpXG5cdFx0XHRcdHV0aWwucHJpbnRfZGVidWcoXCJvcGVucGdwLnBhY2tldC5zaWduYXR1cmUuanNcXG5cIitcblx0XHRcdFx0XHQnaW52YWxpZCBPbmUtb2N0ZXQgbGVuZ3RoIG9mIGZvbGxvd2luZyBoYXNoZWQgbWF0ZXJpYWwuJyArXG5cdFx0XHRcdFx0J01VU1QgYmUgNS4gQDonKyhpLTEpKTtcblxuXHRcdFx0dmFyIHNpZ3BvcyA9IGk7XG5cdFx0XHQvLyBPbmUtb2N0ZXQgc2lnbmF0dXJlIHR5cGUuXG5cdFx0XHR0aGlzLnNpZ25hdHVyZVR5cGUgPSBieXRlc1tpKytdLmNoYXJDb2RlQXQoKTtcblxuXHRcdFx0Ly8gRm91ci1vY3RldCBjcmVhdGlvbiB0aW1lLlxuXHRcdFx0dGhpcy5jcmVhdGVkID0gdXRpbC5yZWFkRGF0ZShieXRlcy5zdWJzdHIoaSwgNCkpO1xuXHRcdFx0aSArPSA0O1xuXHRcdFx0XG5cdFx0XHQvLyBzdG9yaW5nIGRhdGEgYXBwZW5kZWQgdG8gZGF0YSB3aGljaCBnZXRzIHZlcmlmaWVkXG5cdFx0XHR0aGlzLnNpZ25hdHVyZURhdGEgPSBieXRlcy5zdWJzdHJpbmcocG9zaXRpb24sIGkpO1xuXHRcdFx0XG5cdFx0XHQvLyBFaWdodC1vY3RldCBLZXkgSUQgb2Ygc2lnbmVyLlxuXHRcdFx0dGhpcy5pc3N1ZXJLZXlJZCA9IGJ5dGVzLnN1YnN0cmluZyhpLCBpICs4KTtcblx0XHRcdGkgKz0gODtcblxuXHRcdFx0Ly8gT25lLW9jdGV0IHB1YmxpYy1rZXkgYWxnb3JpdGhtLlxuXHRcdFx0dGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBieXRlc1tpKytdLmNoYXJDb2RlQXQoKTtcblxuXHRcdFx0Ly8gT25lLW9jdGV0IGhhc2ggYWxnb3JpdGhtLlxuXHRcdFx0dGhpcy5oYXNoQWxnb3JpdGhtID0gYnl0ZXNbaSsrXS5jaGFyQ29kZUF0KCk7XG5cdFx0YnJlYWs7XG5cdFx0Y2FzZSA0OlxuXHRcdFx0dGhpcy5zaWduYXR1cmVUeXBlID0gYnl0ZXNbaSsrXS5jaGFyQ29kZUF0KCk7XG5cdFx0XHR0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IGJ5dGVzW2krK10uY2hhckNvZGVBdCgpO1xuXHRcdFx0dGhpcy5oYXNoQWxnb3JpdGhtID0gYnl0ZXNbaSsrXS5jaGFyQ29kZUF0KCk7XG5cblxuXHRcdFx0ZnVuY3Rpb24gc3VicGFja2V0cyhieXRlcywgc2lnbmVkKSB7XG5cdFx0XHRcdC8vIFR3by1vY3RldCBzY2FsYXIgb2N0ZXQgY291bnQgZm9yIGZvbGxvd2luZyBoYXNoZWQgc3VicGFja2V0XG5cdFx0XHRcdC8vIGRhdGEuXG5cdFx0XHRcdHZhciBzdWJwYWNrZXRfbGVuZ3RoID0gdXRpbC5yZWFkTnVtYmVyKFxuXHRcdFx0XHRcdGJ5dGVzLnN1YnN0cigwLCAyKSk7XG5cblx0XHRcdFx0dmFyIGkgPSAyO1xuXG5cdFx0XHRcdC8vIEhhc2hlZCBzdWJwYWNrZXQgZGF0YSBzZXQgKHplcm8gb3IgbW9yZSBzdWJwYWNrZXRzKVxuXHRcdFx0XHR2YXIgc3VicGFja2VkX3JlYWQgPSAwO1xuXHRcdFx0XHR3aGlsZSAoaSA8IDIgKyBzdWJwYWNrZXRfbGVuZ3RoKSB7XG5cblx0XHRcdFx0XHR2YXIgbGVuID0gcGFja2V0LnJlYWRTaW1wbGVMZW5ndGgoYnl0ZXMuc3Vic3RyKGkpKTtcblx0XHRcdFx0XHRpICs9IGxlbi5vZmZzZXQ7XG5cblx0XHRcdFx0XHQvLyBTaW5jZSBpdCBpcyB0cml2aWFsIHRvIGFkZCBkYXRhIHRvIHRoZSB1bmhhc2hlZCBwb3J0aW9uIG9mIFxuXHRcdFx0XHRcdC8vIHRoZSBwYWNrZXQgd2Ugc2ltcGx5IGlnbm9yZSBhbGwgdW5hdXRoZW50aWNhdGVkIGRhdGEuXG5cdFx0XHRcdFx0aWYoc2lnbmVkKVxuXHRcdFx0XHRcdFx0dGhpcy5yZWFkX3N1Yl9wYWNrZXQoYnl0ZXMuc3Vic3RyKGksIGxlbi5sZW4pKTtcblxuXHRcdFx0XHRcdGkgKz0gbGVuLmxlbjtcblx0XHRcdFx0fVxuXHRcdFx0XHRcblx0XHRcdFx0cmV0dXJuIGk7XG5cdFx0XHR9XG5cdFx0XHRcblx0XHRcdGkgKz0gc3VicGFja2V0cy5jYWxsKHRoaXMsIGJ5dGVzLnN1YnN0cihpKSwgdHJ1ZSk7XG5cblx0XHRcdC8vIEEgVjQgc2lnbmF0dXJlIGhhc2hlcyB0aGUgcGFja2V0IGJvZHlcblx0XHRcdC8vIHN0YXJ0aW5nIGZyb20gaXRzIGZpcnN0IGZpZWxkLCB0aGUgdmVyc2lvbiBudW1iZXIsIHRocm91Z2ggdGhlIGVuZFxuXHRcdFx0Ly8gb2YgdGhlIGhhc2hlZCBzdWJwYWNrZXQgZGF0YS4gIFRodXMsIHRoZSBmaWVsZHMgaGFzaGVkIGFyZSB0aGVcblx0XHRcdC8vIHNpZ25hdHVyZSB2ZXJzaW9uLCB0aGUgc2lnbmF0dXJlIHR5cGUsIHRoZSBwdWJsaWMta2V5IGFsZ29yaXRobSwgdGhlXG5cdFx0XHQvLyBoYXNoIGFsZ29yaXRobSwgdGhlIGhhc2hlZCBzdWJwYWNrZXQgbGVuZ3RoLCBhbmQgdGhlIGhhc2hlZFxuXHRcdFx0Ly8gc3VicGFja2V0IGJvZHkuXG5cdFx0XHR0aGlzLnNpZ25hdHVyZURhdGEgPSBieXRlcy5zdWJzdHIoMCwgaSk7XG5cblx0XHRcdGkgKz0gc3VicGFja2V0cy5jYWxsKHRoaXMsIGJ5dGVzLnN1YnN0cihpKSwgZmFsc2UpO1xuXG5cdFx0XHRicmVhaztcblx0XHRkZWZhdWx0OlxuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdWZXJzaW9uICcgKyB2ZXJzaW9uICsgJyBvZiB0aGUgc2lnbmF0dXJlIGlzIHVuc3VwcG9ydGVkLicpO1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXG5cdFx0Ly8gVHdvLW9jdGV0IGZpZWxkIGhvbGRpbmcgbGVmdCAxNiBiaXRzIG9mIHNpZ25lZCBoYXNoIHZhbHVlLlxuXHRcdHRoaXMuc2lnbmVkSGFzaFZhbHVlID0gYnl0ZXMuc3Vic3RyKGksIDIpO1xuXHRcdGkgKz0gMjtcblxuXHRcdHRoaXMuc2lnbmF0dXJlID0gYnl0ZXMuc3Vic3RyKGkpO1xuXHR9XG5cblx0dGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnNpZ25hdHVyZURhdGEgKyBcblx0XHRcdHV0aWwud3JpdGVOdW1iZXIoMCwgMikgKyAvLyBOdW1iZXIgb2YgdW5zaWduZWQgc3VicGFja2V0cy5cblx0XHRcdHRoaXMuc2lnbmVkSGFzaFZhbHVlICtcblx0XHRcdHRoaXMuc2lnbmF0dXJlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNpZ25zIHByb3ZpZGVkIGRhdGEuIFRoaXMgbmVlZHMgdG8gYmUgZG9uZSBwcmlvciB0byBzZXJpYWxpemF0aW9uLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gZGF0YSBDb250YWlucyBwYWNrZXRzIHRvIGJlIHNpZ25lZC5cblx0ICogQHBhcmFtIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBwcml2YXRla2V5IHByaXZhdGUga2V5IHVzZWQgdG8gc2lnbiB0aGUgbWVzc2FnZS4gXG5cdCAqL1xuXHR0aGlzLnNpZ24gPSBmdW5jdGlvbihrZXksIGRhdGEpIHtcblx0XHR2YXIgc2lnbmF0dXJlVHlwZSA9IGVudW1zLndyaXRlKGVudW1zLnNpZ25hdHVyZSwgdGhpcy5zaWduYXR1cmVUeXBlKSxcblx0XHRcdHB1YmxpY0tleUFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLnB1YmxpY0tleSwgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0pLFxuXHRcdFx0aGFzaEFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLmhhc2gsIHRoaXMuaGFzaEFsZ29yaXRobSk7XG5cblx0XHR2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSg0KTsgXG5cdFx0cmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoc2lnbmF0dXJlVHlwZSk7XG5cdFx0cmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocHVibGljS2V5QWxnb3JpdGhtKTtcblx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShoYXNoQWxnb3JpdGhtKTtcblxuXG5cdFx0Ly8gQWRkIHN1YnBhY2tldHMgaGVyZVxuXHRcdHJlc3VsdCArPSB1dGlsLndyaXRlTnVtYmVyKDAsIDIpO1xuXG5cblx0XHR0aGlzLnNpZ25hdHVyZURhdGEgPSByZXN1bHQ7XG5cblx0XHR2YXIgdHJhaWxlciA9IHRoaXMuY2FsY3VsYXRlVHJhaWxlcigpO1xuXHRcdFxuXHRcdHZhciB0b0hhc2ggPSB0aGlzLnRvU2lnbihzaWduYXR1cmVUeXBlLCBkYXRhKSArIFxuXHRcdFx0dGhpcy5zaWduYXR1cmVEYXRhICsgdHJhaWxlcjtcblxuXHRcdHZhciBoYXNoID0gY3J5cHRvLmhhc2guZGlnZXN0KGhhc2hBbGdvcml0aG0sIHRvSGFzaCk7XG5cdFx0XG5cdFx0dGhpcy5zaWduZWRIYXNoVmFsdWUgPSBoYXNoLnN1YnN0cigwLCAyKTtcblxuXG5cdFx0dGhpcy5zaWduYXR1cmUgPSBjcnlwdG8uc2lnbmF0dXJlLnNpZ24oaGFzaEFsZ29yaXRobSwgXG5cdFx0XHRwdWJsaWNLZXlBbGdvcml0aG0sIGtleS5tcGksIHRvSGFzaCk7XG5cdH1cblxuXHQvKipcblx0ICogY3JlYXRlcyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHN1YiBzaWduYXR1cmUgcGFja2V0IChTZWUgUkZDIDQ4ODAgNS4yLjMuMSlcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSB0eXBlIHN1YnBhY2tldCBzaWduYXR1cmUgdHlwZS4gU2lnbmF0dXJlIHR5cGVzIGFzIGRlc2NyaWJlZCBcblx0ICogaW4gUkZDNDg4MCBTZWN0aW9uIDUuMi4zLjJcblx0ICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgZGF0YSB0byBiZSBpbmNsdWRlZFxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IGEgc3RyaW5nLXJlcHJlc2VudGF0aW9uIG9mIGEgc3ViIHNpZ25hdHVyZSBwYWNrZXQgKFNlZSBSRkMgNDg4MCA1LjIuMy4xKVxuXHQgKi9cblx0ZnVuY3Rpb24gd3JpdGVfc3ViX3BhY2tldCh0eXBlLCBkYXRhKSB7XG5cdFx0dmFyIHJlc3VsdCA9IFwiXCI7XG5cdFx0cmVzdWx0ICs9IHBhY2tldC53cml0ZVNpbXBsZUxlbmd0aChkYXRhLmxlbmd0aCsxKTtcblx0XHRyZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0eXBlKTtcblx0XHRyZXN1bHQgKz0gZGF0YTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cdFxuXHQvLyBWNCBzaWduYXR1cmUgc3ViIHBhY2tldHNcblx0XG5cdHRoaXMucmVhZF9zdWJfcGFja2V0ID0gZnVuY3Rpb24oYnl0ZXMpIHtcblx0XHR2YXIgbXlwb3MgPSAwO1xuXG5cdFx0ZnVuY3Rpb24gcmVhZF9hcnJheShwcm9wLCBieXRlcykge1xuXHRcdFx0dGhpc1twcm9wXSA9IFtdO1xuXG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdHRoaXNbcHJvcF0ucHVzaChieXRlc1tpXS5jaGFyQ29kZUF0KCkpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRcblx0XHQvLyBUaGUgbGVmdHdvc3QgYml0IGRlbm90ZXMgYSBcImNyaXRpY2FsXCIgcGFja2V0LCBidXQgd2UgaWdub3JlIGl0LlxuXHRcdHZhciB0eXBlID0gYnl0ZXNbbXlwb3MrK10uY2hhckNvZGVBdCgpICYgMHg3RjtcblxuXHRcdC8vIHN1YnBhY2tldCB0eXBlXG5cdFx0c3dpdGNoICh0eXBlKSB7XG5cdFx0Y2FzZSAyOiAvLyBTaWduYXR1cmUgQ3JlYXRpb24gVGltZVxuXHRcdFx0dGhpcy5jcmVhdGVkID0gdXRpbC5yZWFkRGF0ZShieXRlcy5zdWJzdHIobXlwb3MpKTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgMzogLy8gU2lnbmF0dXJlIEV4cGlyYXRpb24gVGltZVxuXHRcdFx0dmFyIHRpbWUgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuXG5cdFx0XHR0aGlzLnNpZ25hdHVyZU5ldmVyRXhwaXJlcyA9IHRpbWUuZ2V0VGltZSgpID09IDA7XG5cdFx0XHR0aGlzLnNpZ25hdHVyZUV4cGlyYXRpb25UaW1lID0gdGltZTtcblx0XHRcdFxuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSA0OiAvLyBFeHBvcnRhYmxlIENlcnRpZmljYXRpb25cblx0XHRcdHRoaXMuZXhwb3J0YWJsZSA9IGJ5dGVzW215cG9zKytdLmNoYXJDb2RlQXQoKSA9PSAxO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSA1OiAvLyBUcnVzdCBTaWduYXR1cmVcblx0XHRcdHRoaXMudHJ1c3RMZXZlbCA9IGJ5dGVzW215cG9zKytdLmNoYXJDb2RlQXQoKTtcblx0XHRcdHRoaXMudHJ1c3RBbW91bnQgPSBieXRlc1tteXBvcysrXS5jaGFyQ29kZUF0KCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIDY6IC8vIFJlZ3VsYXIgRXhwcmVzc2lvblxuXHRcdFx0dGhpcy5yZWd1bGFyRXhwcmVzc2lvbiA9IGJ5dGVzLnN1YnN0cihteXBvcyk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIDc6IC8vIFJldm9jYWJsZVxuXHRcdFx0dGhpcy5yZXZvY2FibGUgPSBieXRlc1tteXBvcysrXS5jaGFyQ29kZUF0KCkgPT0gMTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgOTogLy8gS2V5IEV4cGlyYXRpb24gVGltZVxuXHRcdFx0dmFyIHRpbWUgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuXG5cdFx0XHR0aGlzLmtleUV4cGlyYXRpb25UaW1lID0gdGltZTtcblx0XHRcdHRoaXMua2V5TmV2ZXJFeHBpcmVzID0gdGltZS5nZXRUaW1lKCkgPT0gMDtcblxuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAxMTogLy8gUHJlZmVycmVkIFN5bW1ldHJpYyBBbGdvcml0aG1zXG5cdFx0XHR0aGlzLnByZWZlcnJlZFN5bW1ldHJpY0FsZ29yaXRobXMgPSBbXTtcblxuXHRcdFx0d2hpbGUobXlwb3MgIT0gYnl0ZXMubGVuZ3RoKSB7XG5cdFx0XHRcdHRoaXMucHJlZmVycmVkU3ltbWV0cmljQWxnb3JpdGhtcy5wdXNoKGJ5dGVzW215cG9zKytdLmNoYXJDb2RlQXQoKSk7XG5cdFx0XHR9XG5cblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgMTI6IC8vIFJldm9jYXRpb24gS2V5XG5cdFx0XHQvLyAoMSBvY3RldCBvZiBjbGFzcywgMSBvY3RldCBvZiBwdWJsaWMta2V5IGFsZ29yaXRobSBJRCwgMjBcblx0XHRcdC8vIG9jdGV0cyBvZlxuXHRcdFx0Ly8gZmluZ2VycHJpbnQpXG5cdFx0XHR0aGlzLnJldm9jYXRpb25LZXlDbGFzcyA9IGJ5dGVzW215cG9zKytdLmNoYXJDb2RlQXQoKTtcblx0XHRcdHRoaXMucmV2b2NhdGlvbktleUFsZ29yaXRobSA9IGJ5dGVzW215cG9zKytdLmNoYXJDb2RlQXQoKTtcblx0XHRcdHRoaXMucmV2b2NhdGlvbktleUZpbmdlcnByaW50ID0gYnl0ZXMuc3Vic3RyKG15cG9zLCAyMCk7XG5cdFx0XHRicmVhaztcblxuXHRcdGNhc2UgMTY6IC8vIElzc3VlclxuXHRcdFx0dGhpcy5pc3N1ZXJLZXlJZCA9IGJ5dGVzLnN1YnN0cihteXBvcywgOCk7XG5cdFx0XHRicmVhaztcblxuXHRcdGNhc2UgMjA6IC8vIE5vdGF0aW9uIERhdGFcblx0XHRcdC8vIFdlIGRvbid0IGtub3cgaG93IHRvIGhhbmRsZSBhbnl0aGluZyBidXQgYSB0ZXh0IGZsYWdnZWQgZGF0YS5cblx0XHRcdGlmKGJ5dGVzW215cG9zXS5jaGFyQ29kZUF0KCkgPT0gMHg4MCkge1xuXG5cdFx0XHRcdC8vIFdlIGV4dHJhY3Qga2V5L3ZhbHVlIHR1cGxlIGZyb20gdGhlIGJ5dGUgc3RyZWFtLlxuXHRcdFx0XHRteXBvcyArPSA0O1xuXHRcdFx0XHR2YXIgbSA9IHV0aWwud3JpdGVOdW1iZXIoYnl0ZXMuc3Vic3RyKG15cG9zLCAyKSk7XG5cdFx0XHRcdG15cG9zICs9IDJcblx0XHRcdFx0dmFyIG4gPSB1dGlsLndyaXRlTnVtYmVyKGJ5dGVzLnN1YnN0cihteXBvcywgMikpO1xuXHRcdFx0XHRteXBvcyArPSAyXG5cblx0XHRcdFx0dmFyIG5hbWUgPSBieXRlcy5zdWJzdHIobXlwb3MsIG0pLFxuXHRcdFx0XHRcdHZhbHVlID0gYnl0ZXMuc3Vic3RyKG15cG9zICsgbSwgbik7XG5cblx0XHRcdFx0dGhpcy5ub3RhdGlvbltuYW1lXSA9IHZhbHVlO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZSB0aHJvdyBuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBub3RhdGlvbiBmbGFnLlwiKTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgMjE6IC8vIFByZWZlcnJlZCBIYXNoIEFsZ29yaXRobXNcblx0XHRcdHJlYWRfYXJyYXkuY2FsbCh0aGlzLCAncHJlZmVycmVkSGFzaEFsZ29yaXRobXMnLCBieXRlcy5zdWJzdHIobXlwb3MpKTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgMjI6IC8vIFByZWZlcnJlZCBDb21wcmVzc2lvbiBBbGdvcml0aG1zXG5cdFx0XHRyZWFkX2FycmF5LmNhbGwodGhpcywgJ3ByZWZlcnJlZENvbXByZXNzaW9uQWxnb3JpdGhtcyAnLCBieXRlcy5zdWJzdHIobXlwb3MpKTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgMjM6IC8vIEtleSBTZXJ2ZXIgUHJlZmVyZW5jZXNcblx0XHRcdHJlYWRfYXJyYXkuY2FsbCh0aGlzLCAna2V5U2VydmVyUHJlZmVyZW5jZXNzJywgYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIDI0OiAvLyBQcmVmZXJyZWQgS2V5IFNlcnZlclxuXHRcdFx0dGhpcy5wcmVmZXJyZWRLZXlTZXJ2ZXIgPSBieXRlcy5zdWJzdHIobXlwb3MpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAyNTogLy8gUHJpbWFyeSBVc2VyIElEXG5cdFx0XHR0aGlzLmlzUHJpbWFyeVVzZXJJRCA9IGJ5dGVzW215cG9zKytdICE9IDA7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIDI2OiAvLyBQb2xpY3kgVVJJXG5cdFx0XHR0aGlzLnBvbGljeVVSSSA9IGJ5dGVzLnN1YnN0cihteXBvcyk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIDI3OiAvLyBLZXkgRmxhZ3Ncblx0XHRcdHJlYWRfYXJyYXkuY2FsbCh0aGlzLCAna2V5RmxhZ3MnLCBieXRlcy5zdWJzdHIobXlwb3MpKTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgMjg6IC8vIFNpZ25lcidzIFVzZXIgSURcblx0XHRcdHRoaXMuc2lnbmVyc1VzZXJJZCArPSBieXRlcy5zdWJzdHIobXlwb3MpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSAyOTogLy8gUmVhc29uIGZvciBSZXZvY2F0aW9uXG5cdFx0XHR0aGlzLnJlYXNvbkZvclJldm9jYXRpb25GbGFnID0gYnl0ZXNbbXlwb3MrK10uY2hhckNvZGVBdCgpO1xuXHRcdFx0dGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uU3RyaW5nID0gYnl0ZXMuc3Vic3RyKG15cG9zKTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgMzA6IC8vIEZlYXR1cmVzXG5cdFx0XHRyZWFkX2FycmF5LmNhbGwodGhpcywgJ2ZlYXR1cmVzJywgYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIDMxOiAvLyBTaWduYXR1cmUgVGFyZ2V0XG5cdFx0XHQvLyAoMSBvY3RldCBwdWJsaWMta2V5IGFsZ29yaXRobSwgMSBvY3RldCBoYXNoIGFsZ29yaXRobSwgTiBvY3RldHMgaGFzaClcblx0XHRcdHRoaXMuc2lnbmF0dXJlVGFyZ2V0UHVibGljS2V5QWxnb3JpdGhtID0gYnl0ZXNbbXlwb3MrK10uY2hhckNvZGVBdCgpO1xuXHRcdFx0dGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoQWxnb3JpdGhtID0gYnl0ZXNbbXlwb3MrK10uY2hhckNvZGVBdCgpO1xuXG5cdFx0XHR2YXIgbGVuID0gY3J5cHRvLmdldEhhc2hCeXRlTGVuZ3RoKHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSk7XG5cblx0XHRcdHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaCA9IGJ5dGVzLnN1YnN0cihteXBvcywgbGVuKTtcblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgMzI6IC8vIEVtYmVkZGVkIFNpZ25hdHVyZVxuXHRcdFx0dGhpcy5lbWJlZGRlZFNpZ25hdHVyZSA9IG5ldyBwYWNrZXRfc2lnbmF0dXJlKCk7XG5cdFx0XHR0aGlzLmVtYmVkZGVkU2lnbmF0dXJlLnJlYWQoYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG5cdFx0XHRicmVhaztcblx0XHRkZWZhdWx0OlxuXHRcdFx0dXRpbC5wcmludF9lcnJvcihcIm9wZW5wZ3AucGFja2V0LnNpZ25hdHVyZS5qc1xcblwiK1xuXHRcdFx0XHQndW5rbm93biBzaWduYXR1cmUgc3VicGFja2V0IHR5cGUgJyt0eXBlK1wiIEA6XCIrbXlwb3MrXG5cdFx0XHRcdFwiIHN1YnBsZW46XCIrc3VicGxlbitcIiBsZW46XCIrbGVuKTtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fTtcblxuXHQvLyBQcm9kdWNlcyBkYXRhIHRvIHByb2R1Y2Ugc2lnbmF0dXJlIG9uXG5cdHRoaXMudG9TaWduID0gZnVuY3Rpb24odHlwZSwgZGF0YSkge1xuXHRcdHZhciB0ID0gZW51bXMuc2lnbmF0dXJlXG5cblx0XHRzd2l0Y2godHlwZSkge1xuXHRcdGNhc2UgdC5iaW5hcnk6XG5cdFx0XHRyZXR1cm4gZGF0YS5nZXRCeXRlcygpO1xuXG5cdFx0Y2FzZSB0LnRleHQ6XG5cdFx0XHRyZXR1cm4gdGhpcy50b1NpZ24odC5iaW5hcnksIGRhdGEpXG5cdFx0XHRcdC5yZXBsYWNlKC9cXHJcXG4vZywgJ1xcbicpXG5cdFx0XHRcdC5yZXBsYWNlKC9cXG4vZywgJ1xcclxcbicpO1xuXHRcdFx0XHRcblx0XHRjYXNlIHQuc3RhbmRhbG9uZTpcblx0XHRcdHJldHVybiAnJ1xuXG5cdFx0Y2FzZSB0LmNlcnRfZ2VuZXJpYzpcblx0XHRjYXNlIHQuY2VydF9wZXJzb25hOlxuXHRcdGNhc2UgdC5jZXJ0X2Nhc3VhbDpcblx0XHRjYXNlIHQuY2VydF9wb3NpdGl2ZTpcblx0XHRjYXNlIHQuY2VydF9yZXZvY2F0aW9uOlxuXHRcdHtcblx0XHRcdHZhciBwYWNrZXQsIHRhZztcblxuXHRcdFx0aWYoZGF0YS51c2VyaWQgIT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHRhZyA9IDB4QjQ7XG5cdFx0XHRcdHBhY2tldCA9IGRhdGEudXNlcmlkO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZSBpZihkYXRhLnVzZXJhdHRyaWJ1dGUgIT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHRhZyA9IDB4RDFcblx0XHRcdFx0cGFja2V0ID0gZGF0YS51c2VyYXR0cmlidXRlO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ0VpdGhlciBhIHVzZXJpZCBvciB1c2VyYXR0cmlidXRlIHBhY2tldCBuZWVkcyB0byBiZSAnICtcblx0XHRcdFx0J3N1cHBsaWVkIGZvciBjZXJ0aWZpY2F0aW9uLicpO1xuXG5cblx0XHRcdHZhciBieXRlcyA9IHBhY2tldC53cml0ZSgpO1xuXG5cdFx0XHRcblx0XHRcdHJldHVybiB0aGlzLnRvU2lnbih0LmtleSwgZGF0YSkgK1xuXHRcdFx0XHRTdHJpbmcuZnJvbUNoYXJDb2RlKHRhZykgK1xuXHRcdFx0XHR1dGlsLndyaXRlTnVtYmVyKGJ5dGVzLmxlbmd0aCwgNCkgK1xuXHRcdFx0XHRieXRlcztcblx0XHR9XG5cdFx0Y2FzZSB0LnN1YmtleV9iaW5kaW5nOlxuXHRcdGNhc2UgdC5rZXlfYmluZGluZzpcblx0XHR7XG5cdFx0XHRyZXR1cm4gdGhpcy50b1NpZ24odC5rZXksIGRhdGEpICsgdGhpcy50b1NpZ24odC5rZXksIHsga2V5OiBkYXRhLmJpbmQgfSk7XG5cdFx0fVxuXHRcdGNhc2UgdC5rZXk6XG5cdFx0e1xuXHRcdFx0aWYoZGF0YS5rZXkgPT0gdW5kZWZpbmVkKVxuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0tleSBwYWNrZXQgaXMgcmVxdWlyZWQgZm9yIHRoaXMgc2lndGF0dXJlLicpO1xuXHRcdFx0XG5cdFx0XHRyZXR1cm4gZGF0YS5rZXkud3JpdGVPbGQoKTtcblx0XHR9XG5cdFx0Y2FzZSB0LmtleV9yZXZvY2F0aW9uOlxuXHRcdGNhc2UgdC5zdWJrZXlfcmV2b2NhdGlvbjpcblx0XHRcdHJldHVybiB0aGlzLnRvU2lnbih0LmtleSwgZGF0YSk7XG5cdFx0Y2FzZSB0LnRpbWVzdGFtcDpcblx0XHRcdHJldHVybiAnJztcblx0XHRjYXNlIHQudGhyaWRfcGFydHk6XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuXHRcdFx0YnJlYWs7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdHRocm93IG5ldyBFcnJvcignVW5rbm93biBzaWduYXR1cmUgdHlwZS4nKVxuXHRcdH1cblx0fVxuXG5cdFxuXHR0aGlzLmNhbGN1bGF0ZVRyYWlsZXIgPSBmdW5jdGlvbigpIHtcblx0XHQvLyBjYWxjdWxhdGluZyB0aGUgdHJhaWxlclxuXHRcdHZhciB0cmFpbGVyID0gJyc7XG5cdFx0dHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDQpOyAvLyBWZXJzaW9uXG5cdFx0dHJhaWxlciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkYpO1xuXHRcdHRyYWlsZXIgKz0gdXRpbC53cml0ZU51bWJlcih0aGlzLnNpZ25hdHVyZURhdGEubGVuZ3RoLCA0KTtcblx0XHRyZXR1cm4gdHJhaWxlclxuXHR9XG5cblxuXHQvKipcblx0ICogdmVyaWZ5cyB0aGUgc2lnbmF0dXJlIHBhY2tldC4gTm90ZTogbm90IHNpZ25hdHVyZSB0eXBlcyBhcmUgaW1wbGVtZW50ZWRcblx0ICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgZGF0YSB3aGljaCBvbiB0aGUgc2lnbmF0dXJlIGFwcGxpZXNcblx0ICogQHBhcmFtIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBrZXkgdGhlIHB1YmxpYyBrZXkgdG8gdmVyaWZ5IHRoZSBzaWduYXR1cmVcblx0ICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBtZXNzYWdlIGlzIHZlcmlmaWVkLCBlbHNlIGZhbHNlLlxuXHQgKi9cblx0dGhpcy52ZXJpZnkgPSBmdW5jdGlvbihrZXksIGRhdGEpIHtcblx0XHR2YXIgc2lnbmF0dXJlVHlwZSA9IGVudW1zLndyaXRlKGVudW1zLnNpZ25hdHVyZSwgdGhpcy5zaWduYXR1cmVUeXBlKSxcblx0XHRcdHB1YmxpY0tleUFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLnB1YmxpY0tleSwgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0pLFxuXHRcdFx0aGFzaEFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLmhhc2gsIHRoaXMuaGFzaEFsZ29yaXRobSk7XG5cblx0XHR2YXIgYnl0ZXMgPSB0aGlzLnRvU2lnbihzaWduYXR1cmVUeXBlLCBkYXRhKSxcblx0XHRcdHRyYWlsZXIgPSB0aGlzLmNhbGN1bGF0ZVRyYWlsZXIoKTtcblxuXG5cdFx0dmFyIG1waWNvdW50ID0gMDtcblx0XHQvLyBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBSU0Egc2lnbmF0dXJlczpcblx0XHQvLyBcdCAgICAtIG11bHRpcHJlY2lzaW9uIG51bWJlciAoTVBJKSBvZiBSU0Egc2lnbmF0dXJlIHZhbHVlIG0qKmQgbW9kIG4uXG5cdFx0aWYgKHB1YmxpY0tleUFsZ29yaXRobSA+IDAgJiYgcHVibGljS2V5QWxnb3JpdGhtIDwgNClcblx0XHRcdG1waWNvdW50ID0gMTtcblx0XHQvLyAgICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBEU0Egc2lnbmF0dXJlczpcblx0XHQvLyAgICAgIC0gTVBJIG9mIERTQSB2YWx1ZSByLlxuXHRcdC8vICAgICAgLSBNUEkgb2YgRFNBIHZhbHVlIHMuXG5cdFx0ZWxzZSBpZiAocHVibGljS2V5QWxnb3JpdGhtID09IDE3KVxuXHRcdFx0bXBpY291bnQgPSAyO1xuXHRcdFxuXHRcdHZhciBtcGkgPSBbXSwgaSA9IDA7XG5cdFx0Zm9yICh2YXIgaiA9IDA7IGogPCBtcGljb3VudDsgaisrKSB7XG5cdFx0XHRtcGlbal0gPSBuZXcgdHlwZV9tcGkoKTtcblx0XHRcdGkgKz0gbXBpW2pdLnJlYWQodGhpcy5zaWduYXR1cmUuc3Vic3RyKGkpKTtcblx0XHR9XG5cblx0XHR0aGlzLnZlcmlmaWVkID0gY3J5cHRvLnNpZ25hdHVyZS52ZXJpZnkocHVibGljS2V5QWxnb3JpdGhtLCBcblx0XHRcdGhhc2hBbGdvcml0aG0sIG1waSwga2V5Lm1waSwgXG5cdFx0XHRieXRlcyArIHRoaXMuc2lnbmF0dXJlRGF0YSArIHRyYWlsZXIpO1xuXG5cdFx0cmV0dXJuIHRoaXMudmVyaWZpZWQ7XG5cdH1cbn1cblxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG5cdGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3ltLiBFbmNyeXB0ZWQgSW50ZWdyaXR5IFByb3RlY3RlZCBEYXRhIFxuICogUGFja2V0IChUYWcgMTgpXG4gKiBcbiAqIFJGQzQ4ODAgNS4xMzogVGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQgRGF0YSBwYWNrZXQgaXNcbiAqIGEgdmFyaWFudCBvZiB0aGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXQuIEl0IGlzIGEgbmV3IGZlYXR1cmVcbiAqIGNyZWF0ZWQgZm9yIE9wZW5QR1AgdGhhdCBhZGRyZXNzZXMgdGhlIHByb2JsZW0gb2YgZGV0ZWN0aW5nIGEgbW9kaWZpY2F0aW9uIHRvXG4gKiBlbmNyeXB0ZWQgZGF0YS4gSXQgaXMgdXNlZCBpbiBjb21iaW5hdGlvbiB3aXRoIGEgTW9kaWZpY2F0aW9uIERldGVjdGlvbiBDb2RlXG4gKiBwYWNrZXQuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkKCkge1xuXHQvKiogVGhlIGVuY3J5cHRlZCBwYXlsb2FkLiAqL1xuXHR0aGlzLmVuY3J5cHRlZCA9IG51bGw7IC8vIHN0cmluZ1xuXHQvKiogQHR5cGUge0Jvb2xlYW59XG5cdCAqIElmIGFmdGVyIGRlY3J5cHRpbmcgdGhlIHBhY2tldCB0aGlzIGlzIHNldCB0byB0cnVlLFxuXHQgKiBhIG1vZGlmaWNhdGlvbiBoYXMgYmVlbiBkZXRlY3RlZCBhbmQgdGh1cyB0aGUgY29udGVudHNcblx0ICogc2hvdWxkIGJlIGRpc2NhcmRlZC5cblx0ICovXG5cdHRoaXMubW9kaWZpY2F0aW9uID0gZmFsc2U7XG5cdHRoaXMucGFja2V0cztcblxuXG5cdHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG5cdFx0Ly8gLSBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gVGhlIG9ubHkgY3VycmVudGx5IGRlZmluZWQgdmFsdWUgaXNcblx0XHQvLyAxLlxuXHRcdHZhciB2ZXJzaW9uID0gYnl0ZXNbMF0uY2hhckNvZGVBdCgpO1xuXG5cdFx0aWYgKHZlcnNpb24gIT0gMSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHBhY2tldCB2ZXJzaW9uLicpO1xuXHRcdH1cblxuXHRcdC8vIC0gRW5jcnlwdGVkIGRhdGEsIHRoZSBvdXRwdXQgb2YgdGhlIHNlbGVjdGVkIHN5bW1ldHJpYy1rZXkgY2lwaGVyXG5cdFx0Ly8gICBvcGVyYXRpbmcgaW4gQ2lwaGVyIEZlZWRiYWNrIG1vZGUgd2l0aCBzaGlmdCBhbW91bnQgZXF1YWwgdG8gdGhlXG5cdFx0Ly8gICBibG9jayBzaXplIG9mIHRoZSBjaXBoZXIgKENGQi1uIHdoZXJlIG4gaXMgdGhlIGJsb2NrIHNpemUpLlxuXHRcdHRoaXMuZW5jcnlwdGVkID0gYnl0ZXMuc3Vic3RyKDEpO1xuXHR9XG5cblx0dGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFxuXHRcdHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDEpIC8vIFZlcnNpb25cblx0XHRcdCsgdGhpcy5lbmNyeXB0ZWQ7XG5cdH1cblxuXHR0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihzZXNzaW9uS2V5QWxnb3JpdGhtLCBrZXkpIHtcblx0XHR2YXIgYnl0ZXMgPSB0aGlzLnBhY2tldHMud3JpdGUoKVxuXHRcdFxuXHRcdHZhciBwcmVmaXhyYW5kb20gPSBjcnlwdG8uZ2V0UHJlZml4UmFuZG9tKHNlc3Npb25LZXlBbGdvcml0aG0pO1xuXHRcdHZhciBwcmVmaXggPSBwcmVmaXhyYW5kb21cblx0XHRcdFx0KyBwcmVmaXhyYW5kb20uY2hhckF0KHByZWZpeHJhbmRvbS5sZW5ndGggLSAyKVxuXHRcdFx0XHQrIHByZWZpeHJhbmRvbS5jaGFyQXQocHJlZml4cmFuZG9tLmxlbmd0aCAtIDEpXG5cblx0XHR2YXIgdG9oYXNoID0gYnl0ZXM7XG5cblxuXHRcdC8vIE1vZGlmaWNhdGlvbiBkZXRlY3Rpb24gY29kZSBwYWNrZXQuXG5cdFx0dG9oYXNoICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHhEMyk7XG5cdFx0dG9oYXNoICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHgxNCk7XG5cblxuXHRcdHRvaGFzaCArPSBjcnlwdG8uaGFzaC5zaGExKHByZWZpeCArIHRvaGFzaCk7XG5cblxuXHRcdHRoaXMuZW5jcnlwdGVkID0gY3J5cHRvLmNmYi5lbmNyeXB0KHByZWZpeHJhbmRvbSxcblx0XHRcdFx0c2Vzc2lvbktleUFsZ29yaXRobSwgdG9oYXNoLCBrZXksIGZhbHNlKS5zdWJzdHJpbmcoMCxcblx0XHRcdFx0cHJlZml4Lmxlbmd0aCArIHRvaGFzaC5sZW5ndGgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlY3J5cHRzIHRoZSBlbmNyeXB0ZWQgZGF0YSBjb250YWluZWQgaW4gdGhpcyBvYmplY3QgcmVhZF9wYWNrZXQgbXVzdFxuXHQgKiBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZVxuXHQgKiBcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBzZXNzaW9uS2V5QWxnb3JpdGhtXG5cdCAqICAgICAgICAgICAgVGhlIHNlbGVjdGVkIHN5bW1ldHJpYyBlbmNyeXB0aW9uIGFsZ29yaXRobSB0byBiZSB1c2VkXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgVGhlIGtleSBvZiBjaXBoZXIgYmxvY2tzaXplIGxlbmd0aCB0byBiZSB1c2VkXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gVGhlIGRlY3J5cHRlZCBkYXRhIG9mIHRoaXMgcGFja2V0XG5cdCAqL1xuXHR0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihzZXNzaW9uS2V5QWxnb3JpdGhtLCBrZXkpIHtcblx0XHR2YXIgZGVjcnlwdGVkID0gY3J5cHRvLmNmYi5kZWNyeXB0KFxuXHRcdFx0XHRzZXNzaW9uS2V5QWxnb3JpdGhtLCBrZXksIHRoaXMuZW5jcnlwdGVkLCBmYWxzZSk7XG5cblxuXHRcdC8vIHRoZXJlIG11c3QgYmUgYSBtb2RpZmljYXRpb24gZGV0ZWN0aW9uIGNvZGUgcGFja2V0IGFzIHRoZVxuXHRcdC8vIGxhc3QgcGFja2V0IGFuZCBldmVyeXRoaW5nIGdldHMgaGFzaGVkIGV4Y2VwdCB0aGUgaGFzaCBpdHNlbGZcblx0XHR0aGlzLmhhc2ggPSBjcnlwdG8uaGFzaC5zaGExKFxuXHRcdFx0Y3J5cHRvLmNmYi5tZGMoc2Vzc2lvbktleUFsZ29yaXRobSwga2V5LCB0aGlzLmVuY3J5cHRlZClcblx0XHRcdCsgZGVjcnlwdGVkLnN1YnN0cmluZygwLCBkZWNyeXB0ZWQubGVuZ3RoIC0gMjApKTtcblxuXG5cdFx0dmFyIG1kYyA9IGRlY3J5cHRlZC5zdWJzdHIoZGVjcnlwdGVkLmxlbmd0aCAtIDIwLCAyMCk7XG5cblx0XHRpZih0aGlzLmhhc2ggIT0gbWRjKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ01vZGlmaWNhdGlvbiBkZXRlY3RlZC4nKTtcblx0XHR9XG5cdFx0ZWxzZVxuXHRcdFx0dGhpcy5wYWNrZXRzLnJlYWQoZGVjcnlwdGVkLnN1YnN0cigwLCBkZWNyeXB0ZWQubGVuZ3RoIC0gMjIpKTtcblx0fVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciB0eXBlX3MyayA9IHJlcXVpcmUoJy4uL3R5cGUvczJrLmpzJyksXG5cdGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKSxcblx0Y3J5cHRvID0gcmVxdWlyZSgnLi4vY3J5cHRvJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IFBhY2tldHMgKFRhZyAxKVxuICogXG4gKiBSRkM0ODgwIDUuMTogQSBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXQgaG9sZHMgdGhlIHNlc3Npb24ga2V5XG4gKiB1c2VkIHRvIGVuY3J5cHQgYSBtZXNzYWdlLiBaZXJvIG9yIG1vcmUgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXlcbiAqIHBhY2tldHMgYW5kL29yIFN5bW1ldHJpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldHMgbWF5IHByZWNlZGUgYVxuICogU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQsIHdoaWNoIGhvbGRzIGFuIGVuY3J5cHRlZCBtZXNzYWdlLiBUaGVcbiAqIG1lc3NhZ2UgaXMgZW5jcnlwdGVkIHdpdGggdGhlIHNlc3Npb24ga2V5LCBhbmQgdGhlIHNlc3Npb24ga2V5IGlzIGl0c2VsZlxuICogZW5jcnlwdGVkIGFuZCBzdG9yZWQgaW4gdGhlIEVuY3J5cHRlZCBTZXNzaW9uIEtleSBwYWNrZXQocykuIFRoZVxuICogU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQgaXMgcHJlY2VkZWQgYnkgb25lIFB1YmxpYy1LZXkgRW5jcnlwdGVkXG4gKiBTZXNzaW9uIEtleSBwYWNrZXQgZm9yIGVhY2ggT3BlblBHUCBrZXkgdG8gd2hpY2ggdGhlIG1lc3NhZ2UgaXMgZW5jcnlwdGVkLlxuICogVGhlIHJlY2lwaWVudCBvZiB0aGUgbWVzc2FnZSBmaW5kcyBhIHNlc3Npb24ga2V5IHRoYXQgaXMgZW5jcnlwdGVkIHRvIHRoZWlyXG4gKiBwdWJsaWMga2V5LCBkZWNyeXB0cyB0aGUgc2Vzc2lvbiBrZXksIGFuZCB0aGVuIHVzZXMgdGhlIHNlc3Npb24ga2V5IHRvXG4gKiBkZWNyeXB0IHRoZSBtZXNzYWdlLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9zeW1fZW5jcnlwdGVkX3Nlc3Npb25fa2V5KCkge1xuXHR0aGlzLnRhZyA9IDM7XG5cdHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0gPSBudWxsO1xuXHR0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0gPSAnYWVzMjU2Jztcblx0dGhpcy5lbmNyeXB0ZWQgPSBudWxsO1xuXHR0aGlzLnMyayA9IG5ldyB0eXBlX3MyaygpO1xuXG5cdC8qKlxuXHQgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHN5bW1ldHJpYyBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXkgcGFja2V0ICh0YWcgMykuXG5cdCAqIFxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxIHBhY2tldFxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuXG5cdCAqICAgICAgICAgICAgTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2Zcblx0ICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvblxuXHQgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBPYmplY3QgcmVwcmVzZW50YXRpb25cblx0ICovXG5cdHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG5cdFx0Ly8gQSBvbmUtb2N0ZXQgdmVyc2lvbiBudW1iZXIuIFRoZSBvbmx5IGN1cnJlbnRseSBkZWZpbmVkIHZlcnNpb24gaXMgNC5cblx0XHR0aGlzLnZlcnNpb24gPSBieXRlc1swXS5jaGFyQ29kZUF0KCk7XG5cblx0XHQvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgc3ltbWV0cmljIGFsZ29yaXRobSB1c2VkLlxuXHRcdHZhciBhbGdvID0gZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIGJ5dGVzWzFdLmNoYXJDb2RlQXQoKSk7XG5cblx0XHQvLyBBIHN0cmluZy10by1rZXkgKFMySykgc3BlY2lmaWVyLCBsZW5ndGggYXMgZGVmaW5lZCBhYm92ZS5cblx0XHR2YXIgczJrbGVuZ3RoID0gdGhpcy5zMmsucmVhZChieXRlcy5zdWJzdHIoMikpO1xuXG5cdFx0Ly8gT3B0aW9uYWxseSwgdGhlIGVuY3J5cHRlZCBzZXNzaW9uIGtleSBpdHNlbGYsIHdoaWNoIGlzIGRlY3J5cHRlZFxuXHRcdC8vIHdpdGggdGhlIHN0cmluZy10by1rZXkgb2JqZWN0LlxuXHRcdHZhciBkb25lID0gczJrbGVuZ3RoICsgMjtcblxuXHRcdGlmKGRvbmUgPCBieXRlcy5sZW5ndGgpIHtcblx0XHRcdHRoaXMuZW5jcnlwdGVkID0gYnl0ZXMuc3Vic3RyKGRvbmUpO1xuXHRcdFx0dGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSA9IGFsZ29cblx0XHR9XG5cdFx0ZWxzZVxuXHRcdFx0dGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtID0gYWxnbztcblx0fVxuXG5cdHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcblx0XHR2YXIgYWxnbyA9IHRoaXMuZW5jcnlwdGVkID09IG51bGwgPyBcblx0XHRcdHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA6XG5cdFx0XHR0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtO1xuXG5cdFx0dmFyIGJ5dGVzID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnZlcnNpb24pICtcblx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMuc3ltbWV0cmljLCBhbGdvKSkgK1xuXHRcdFx0dGhpcy5zMmsud3JpdGUoKTtcblxuXHRcdGlmKHRoaXMuZW5jcnlwdGVkICE9IG51bGwpXG5cdFx0XHRieXRlcyArPSB0aGlzLmVuY3J5cHRlZDtcblx0XHRyZXR1cm4gYnl0ZXM7XG5cdH1cblxuXHQvKipcblx0ICogRGVjcnlwdHMgdGhlIHNlc3Npb24ga2V5IChvbmx5IGZvciBwdWJsaWMga2V5IGVuY3J5cHRlZCBzZXNzaW9uIGtleVxuXHQgKiBwYWNrZXRzICh0YWcgMSlcblx0ICogXG5cdCAqIEBwYXJhbSB7b3BlbnBncF9tc2dfbWVzc2FnZX0gbXNnXG5cdCAqICAgICAgICAgICAgVGhlIG1lc3NhZ2Ugb2JqZWN0ICh3aXRoIG1lbWJlciBlbmNyeXB0ZWREYXRhXG5cdCAqIEBwYXJhbSB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleX0ga2V5XG5cdCAqICAgICAgICAgICAgUHJpdmF0ZSBrZXkgd2l0aCBzZWNNUElzIHVubG9ja2VkXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gVGhlIHVuZW5jcnlwdGVkIHNlc3Npb24ga2V5XG5cdCAqL1xuXHR0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihwYXNzcGhyYXNlKSB7XG5cdFx0dmFyIGFsZ28gPSB0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtICE9IG51bGwgP1xuXHRcdFx0dGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSA6XG5cdFx0XHR0aGlzLnNlc3Npb25LZXlBbGdvcml0aG07XG5cblxuXHRcdHZhciBsZW5ndGggPSBjcnlwdG8uY2lwaGVyW2FsZ29dLmtleVNpemU7XG5cdFx0dmFyIGtleSA9IHRoaXMuczJrLnByb2R1Y2Vfa2V5KHBhc3NwaHJhc2UsIGxlbmd0aCk7XG5cblx0XHRpZih0aGlzLmVuY3J5cHRlZCA9PSBudWxsKSB7XG5cdFx0XHR0aGlzLnNlc3Npb25LZXkgPSBrZXk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFyIGRlY3J5cHRlZCA9IGNyeXB0by5jZmIuZGVjcnlwdChcblx0XHRcdFx0dGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSwga2V5LCB0aGlzLmVuY3J5cHRlZCwgdHJ1ZSk7XG5cblx0XHRcdHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9IGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLFxuXHRcdFx0XHRkZWNyeXB0ZWRbMF0ua2V5Q29kZUF0KCkpO1xuXG5cdFx0XHR0aGlzLnNlc3Npb25LZXkgPSBkZWNyeXB0ZWQuc3Vic3RyKDEpO1xuXHRcdH1cblx0fVxuXG5cdHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UpIHtcblx0XHR2YXIgbGVuZ3RoID0gY3J5cHRvLmdldEtleUxlbmd0aCh0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtKTtcblx0XHR2YXIga2V5ID0gdGhpcy5zMmsucHJvZHVjZV9rZXkocGFzc3BocmFzZSwgbGVuZ3RoKTtcblxuXHRcdHZhciBwcml2YXRlX2tleSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG5cdFx0XHRlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSkpICtcblxuXHRcdFx0Y3J5cHRvLmdldFJhbmRvbUJ5dGVzKFxuXHRcdFx0XHRjcnlwdG8uZ2V0S2V5TGVuZ3RoKHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSkpO1xuXG5cdFx0dGhpcy5lbmNyeXB0ZWQgPSBjcnlwdG8uY2ZiLmVuY3J5cHQoXG5cdFx0XHRcdGNyeXB0by5nZXRQcmVmaXhSYW5kb20odGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSksIFxuXHRcdFx0XHR0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtLCBrZXksIHByaXZhdGVfa2V5LCB0cnVlKTtcblx0fVxufTtcblxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQgKFRhZyA5KVxuICogXG4gKiBSRkM0ODgwIDUuNzogVGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgcGFja2V0IGNvbnRhaW5zIGRhdGEgZW5jcnlwdGVkXG4gKiB3aXRoIGEgc3ltbWV0cmljLWtleSBhbGdvcml0aG0uIFdoZW4gaXQgaGFzIGJlZW4gZGVjcnlwdGVkLCBpdCBjb250YWlucyBvdGhlclxuICogcGFja2V0cyAodXN1YWxseSBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgb3IgY29tcHJlc3NlZCBkYXRhIHBhY2tldCwgYnV0IGluXG4gKiB0aGVvcnkgb3RoZXIgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXRzIG9yIHNlcXVlbmNlcyBvZiBwYWNrZXRzXG4gKiB0aGF0IGZvcm0gd2hvbGUgT3BlblBHUCBtZXNzYWdlcykuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfc3ltbWV0cmljYWxseV9lbmNyeXB0ZWQoKSB7XG5cdHRoaXMuZW5jcnlwdGVkID0gbnVsbDtcblx0LyoqIERlY3J5cHRlZCBwYWNrZXRzIGNvbnRhaW5lZCB3aXRoaW4uIFxuXHQgKiBAdHlwZSB7b3BlbnBncF9wYWNrZXRsaXN0fSAqL1xuXHR0aGlzLnBhY2tldHM7XG5cblx0dGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcblx0XHR0aGlzLmVuY3J5cHRlZCA9IGJ5dGVzO1xuXHR9XG5cblx0dGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVuY3J5cHRlZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBTeW1tZXRyaWNhbGx5IGRlY3J5cHQgdGhlIHBhY2tldCBkYXRhXG5cdCAqIFxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IHNlc3Npb25LZXlBbGdvcml0aG1cblx0ICogICAgICAgICAgICAgU3ltbWV0cmljIGtleSBhbGdvcml0aG0gdG8gdXNlIC8vIFNlZSBSRkM0ODgwIDkuMlxuXHQgKiBAcGFyYW0ge1N0cmluZ30ga2V5XG5cdCAqICAgICAgICAgICAgIEtleSBhcyBzdHJpbmcgd2l0aCB0aGUgY29ycmVzcG9uZGluZyBsZW5ndGggdG8gdGhlXG5cdCAqICAgICAgICAgICAgYWxnb3JpdGhtXG5cdCAqIEByZXR1cm4gVGhlIGRlY3J5cHRlZCBkYXRhO1xuXHQgKi9cblx0dGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24oc2Vzc2lvbktleUFsZ29yaXRobSwga2V5KSB7XG5cdFx0dmFyIGRlY3J5cHRlZCA9IGNyeXB0by5jZmIuZGVjcnlwdChcblx0XHRcdFx0c2Vzc2lvbktleUFsZ29yaXRobSwga2V5LCB0aGlzLmVuY3J5cHRlZCwgdHJ1ZSk7XG5cblx0XHR0aGlzLnBhY2tldHMucmVhZChkZWNyeXB0ZWQpO1xuXHR9XG5cblx0dGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYWxnbywga2V5KSB7XG5cdFx0dmFyIGRhdGEgPSB0aGlzLnBhY2tldHMud3JpdGUoKTtcblxuXHRcdHRoaXMuZW5jcnlwdGVkID0gY3J5cHRvLmNmYi5lbmNyeXB0KFxuXHRcdFx0XHRjcnlwdG8uZ2V0UHJlZml4UmFuZG9tKGFsZ28pLCBhbGdvLCBkYXRhLCBrZXksIHRydWUpO1xuXHR9XG59O1xuIiwiXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF90cnVzdCgpIHtcblxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKiBcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgVXNlciBBdHRyaWJ1dGUgUGFja2V0IChUYWcgMTcpXG4gKiAgVGhlIFVzZXIgQXR0cmlidXRlIHBhY2tldCBpcyBhIHZhcmlhdGlvbiBvZiB0aGUgVXNlciBJRCBwYWNrZXQuICBJdFxuICogIGlzIGNhcGFibGUgb2Ygc3RvcmluZyBtb3JlIHR5cGVzIG9mIGRhdGEgdGhhbiB0aGUgVXNlciBJRCBwYWNrZXQsXG4gKiAgd2hpY2ggaXMgbGltaXRlZCB0byB0ZXh0LiAgTGlrZSB0aGUgVXNlciBJRCBwYWNrZXQsIGEgVXNlciBBdHRyaWJ1dGVcbiAqICBwYWNrZXQgbWF5IGJlIGNlcnRpZmllZCBieSB0aGUga2V5IG93bmVyIChcInNlbGYtc2lnbmVkXCIpIG9yIGFueSBvdGhlclxuICogIGtleSBvd25lciB3aG8gY2FyZXMgdG8gY2VydGlmeSBpdC4gIEV4Y2VwdCBhcyBub3RlZCwgYSBVc2VyIEF0dHJpYnV0ZVxuICogIHBhY2tldCBtYXkgYmUgdXNlZCBhbnl3aGVyZSB0aGF0IGEgVXNlciBJRCBwYWNrZXQgbWF5IGJlIHVzZWQuXG4gKlxuICogIFdoaWxlIFVzZXIgQXR0cmlidXRlIHBhY2tldHMgYXJlIG5vdCBhIHJlcXVpcmVkIHBhcnQgb2YgdGhlIE9wZW5QR1BcbiAqICBzdGFuZGFyZCwgaW1wbGVtZW50YXRpb25zIFNIT1VMRCBwcm92aWRlIGF0IGxlYXN0IGVub3VnaFxuICogIGNvbXBhdGliaWxpdHkgdG8gcHJvcGVybHkgaGFuZGxlIGEgY2VydGlmaWNhdGlvbiBzaWduYXR1cmUgb24gdGhlXG4gKiAgVXNlciBBdHRyaWJ1dGUgcGFja2V0LiAgQSBzaW1wbGUgd2F5IHRvIGRvIHRoaXMgaXMgYnkgdHJlYXRpbmcgdGhlXG4gKiAgVXNlciBBdHRyaWJ1dGUgcGFja2V0IGFzIGEgVXNlciBJRCBwYWNrZXQgd2l0aCBvcGFxdWUgY29udGVudHMsIGJ1dFxuICogIGFuIGltcGxlbWVudGF0aW9uIG1heSB1c2UgYW55IG1ldGhvZCBkZXNpcmVkLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF91c2VyX2F0dHJpYnV0ZSgpIHtcblx0dGhpcy50YWcgPSAxNztcblx0dGhpcy5hdHRyaWJ1dGVzID0gW107XG5cblx0LyoqXG5cdCAqIHBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgdXNlciBhdHRyaWJ1dGUgcGFja2V0ICh0YWcgMTcpLlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgcGF5bG9hZCBvZiBhIHRhZyAxNyBwYWNrZXRcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZ1xuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBsZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dCBhdCBwb3NpdGlvblxuXHQgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBvYmplY3QgcmVwcmVzZW50YXRpb25cblx0ICovXG5cdHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG5cdFx0dmFyIGkgPSAwO1xuXHRcdHdoaWxlKGkgPCBieXRlcy5sZW5ndGgpIHtcblx0XHRcdHZhciBsZW4gPSBvcGVucGdwX3BhY2tldC5yZWFkX3NpbXBsZV9sZW5ndGgoYnl0ZXMpO1xuXG5cdFx0XHRpICs9IGxlbi5vZmZzZXQ7XG5cdFx0XHR0aGlzLmF0dHJpYnV0ZXMucHVzaChieXRlcy5zdWJzdHIoaSwgbGVuLmxlbikpO1xuXHRcdFx0aSArPSBsZW4ubGVuO1xuXHRcdH1cblx0fVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgVXNlciBJRCBQYWNrZXQgKFRhZyAxMylcbiAqIEEgVXNlciBJRCBwYWNrZXQgY29uc2lzdHMgb2YgVVRGLTggdGV4dCB0aGF0IGlzIGludGVuZGVkIHRvIHJlcHJlc2VudFxuICogdGhlIG5hbWUgYW5kIGVtYWlsIGFkZHJlc3Mgb2YgdGhlIGtleSBob2xkZXIuICBCeSBjb252ZW50aW9uLCBpdFxuICogaW5jbHVkZXMgYW4gUkZDIDI4MjIgW1JGQzI4MjJdIG1haWwgbmFtZS1hZGRyLCBidXQgdGhlcmUgYXJlIG5vXG4gKiByZXN0cmljdGlvbnMgb24gaXRzIGNvbnRlbnQuICBUaGUgcGFja2V0IGxlbmd0aCBpbiB0aGUgaGVhZGVyXG4gKiBzcGVjaWZpZXMgdGhlIGxlbmd0aCBvZiB0aGUgVXNlciBJRC4gXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3VzZXJpZCgpIHtcblx0LyoqIEB0eXBlIHtTdHJpbmd9IEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHVzZXIgaWQuIFVzdWFsbHkgaW4gdGhlIGZvcm1cblx0ICogSm9obiBEb2UgPGpvaG5AZXhhbXBsZS5jb20+IFxuXHQgKi9cblx0dGhpcy51c2VyaWQgPSAnJztcblx0XG5cdFxuXHQvKipcblx0ICogUGFyc2luZyBmdW5jdGlvbiBmb3IgYSB1c2VyIGlkIHBhY2tldCAodGFnIDEzKS5cblx0ICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IHBheWxvYWQgb2YgYSB0YWcgMTMgcGFja2V0XG5cdCAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gcG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcblx0ICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gbGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2YgaW5wdXQgXG5cdCAqIGF0IHBvc2l0aW9uXG5cdCAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IG9iamVjdCByZXByZXNlbnRhdGlvblxuXHQgKi9cblx0dGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcblx0XHR0aGlzLnVzZXJpZCA9IHV0aWwuZGVjb2RlX3V0ZjgoYnl0ZXMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHVzZXIgaWQgcGFja2V0XG5cdCAqIEBwYXJhbSB7U3RyaW5nfSB1c2VyX2lkIHRoZSB1c2VyIGlkIGFzIHN0cmluZyAoXCJKb2huIERvZSA8am9obi5kb2VAbWFpbC51c1wiKVxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvblxuXHQgKi9cblx0dGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB1dGlsLmVuY29kZV91dGY4KHRoaXMudXNlcmlkKTtcblx0fVxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdHlwZSBrZXkgaWQgKFJGQzQ4ODAgMy4zKVxuICogIEEgS2V5IElEIGlzIGFuIGVpZ2h0LW9jdGV0IHNjYWxhciB0aGF0IGlkZW50aWZpZXMgYSBrZXkuXG4gICBJbXBsZW1lbnRhdGlvbnMgU0hPVUxEIE5PVCBhc3N1bWUgdGhhdCBLZXkgSURzIGFyZSB1bmlxdWUuICBUaGVcbiAgIHNlY3Rpb24gXCJFbmhhbmNlZCBLZXkgRm9ybWF0c1wiIGJlbG93IGRlc2NyaWJlcyBob3cgS2V5IElEcyBhcmVcbiAgIGZvcm1lZC5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBrZXlpZCgpIHtcblx0dmFyIGJ5dGVzID0gJyc7XG5cblx0Zm9yKHZhciBpID0gMDsgaSA8IDg7IGkrKylcblx0XHRieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuXHQvKipcblx0ICogUGFyc2luZyBtZXRob2QgZm9yIGEga2V5IGlkXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBJbnB1dCB0byByZWFkIHRoZSBrZXkgaWQgZnJvbSBcblx0ICogQHBhcmFtIHtpbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB3aGVyZSB0byBzdGFydCByZWFkaW5nIHRoZSBrZXkgXG5cdCAqIGlkIGZyb20gaW5wdXRcblx0ICogQHJldHVybiB7b3BlbnBncF90eXBlX2tleWlkfSBUaGlzIG9iamVjdFxuXHQgKi9cblx0dGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcblx0XHR0aGlzLmJ5dGVzID0gYnl0ZXMuc3Vic3RyKDAsIDgpO1xuXHR9XG5cblx0dGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmJ5dGVzO1xuXHR9XG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLy8gSGludDogV2UgaG9sZCBvdXIgTVBJcyBhcyBhbiBhcnJheSBvZiBvY3RldHMgaW4gYmlnIGVuZGlhbiBmb3JtYXQgcHJlY2VlZGluZyBhIHR3b1xuLy8gb2N0ZXQgc2NhbGFyOiBNUEk6IFthLGIsYyxkLGUsZl1cbi8vIC0gTVBJIHNpemU6IChhIDw8IDgpIHwgYiBcbi8vIC0gTVBJID0gYyB8IGQgPDwgOCB8IGUgPDwgKChNUEkubGVuZ3RoIC0yKSo4KSB8IGYgKChNUEkubGVuZ3RoIC0yKSo4KVxuXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4uL2NyeXB0by9wdWJsaWNfa2V5L2pzYm4uanMnKSxcblx0dXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2NJbXBsZW1lbnRhdGlvbiBvZiB0eXBlIE1QSSAoUkZDNDg4MCAzLjIpXG4gKiBNdWx0aXByZWNpc2lvbiBpbnRlZ2VycyAoYWxzbyBjYWxsZWQgTVBJcykgYXJlIHVuc2lnbmVkIGludGVnZXJzIHVzZWRcbiAqIHRvIGhvbGQgbGFyZ2UgaW50ZWdlcnMgc3VjaCBhcyB0aGUgb25lcyB1c2VkIGluIGNyeXB0b2dyYXBoaWNcbiAqIGNhbGN1bGF0aW9ucy5cbiAqIEFuIE1QSSBjb25zaXN0cyBvZiB0d28gcGllY2VzOiBhIHR3by1vY3RldCBzY2FsYXIgdGhhdCBpcyB0aGUgbGVuZ3RoXG4gKiBvZiB0aGUgTVBJIGluIGJpdHMgZm9sbG93ZWQgYnkgYSBzdHJpbmcgb2Ygb2N0ZXRzIHRoYXQgY29udGFpbiB0aGVcbiAqIGFjdHVhbCBpbnRlZ2VyLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG1waSgpIHtcblx0LyoqIEFuIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudCBpbnRlZ2VyICovXG5cdHRoaXMuZGF0YSA9IG51bGw7XG5cblx0LyoqXG5cdCAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgbXBpIChSRkMgNDg4MCAzLjIpLlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBtcGkgZGF0YVxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgXG5cdCAqIHN0cmluZ1xuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBcblx0ICogaW5wdXQgYXQgcG9zaXRpb25cblx0ICogQHJldHVybiB7b3BlbnBncF90eXBlX21waX0gT2JqZWN0IHJlcHJlc2VudGF0aW9uXG5cdCAqL1xuXHR0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuXHRcdHZhciBiaXRzID0gKGJ5dGVzWzBdLmNoYXJDb2RlQXQoKSA8PCA4KSB8IGJ5dGVzWzFdLmNoYXJDb2RlQXQoKTtcblx0XHRcblx0XHQvLyBBZGRpdGlvbmFsIHJ1bGVzOlxuXHRcdC8vXG5cdFx0Ly8gICAgVGhlIHNpemUgb2YgYW4gTVBJIGlzICgoTVBJLmxlbmd0aCArIDcpIC8gOCkgKyAyIG9jdGV0cy5cblx0XHQvL1xuXHRcdC8vICAgIFRoZSBsZW5ndGggZmllbGQgb2YgYW4gTVBJIGRlc2NyaWJlcyB0aGUgbGVuZ3RoIHN0YXJ0aW5nIGZyb20gaXRzXG5cdFx0Ly9cdCAgbW9zdCBzaWduaWZpY2FudCBub24temVybyBiaXQuICBUaHVzLCB0aGUgTVBJIFswMCAwMiAwMV0gaXMgbm90XG5cdFx0Ly8gICAgZm9ybWVkIGNvcnJlY3RseS4gIEl0IHNob3VsZCBiZSBbMDAgMDEgMDFdLlxuXG5cdFx0Ly8gVE9ETzogVmVyaWZpY2F0aW9uIG9mIHRoaXMgc2l6ZSBtZXRob2QhIFRoaXMgc2l6ZSBjYWxjdWxhdGlvbiBhc1xuXHRcdC8vIFx0XHQgc3BlY2lmaWVkIGFib3ZlIGlzIG5vdCBhcHBsaWNhYmxlIGluIEphdmFTY3JpcHRcblx0XHR2YXIgYnl0ZWxlbiA9IE1hdGguY2VpbChiaXRzIC8gOCk7XG5cdFx0XG5cdFx0dmFyIHJhdyA9IGJ5dGVzLnN1YnN0cigyLCBieXRlbGVuKTtcblx0XHR0aGlzLmZyb21CeXRlcyhyYXcpO1xuXG5cdFx0cmV0dXJuIDIgKyBieXRlbGVuO1xuXHR9XG5cblx0dGhpcy5mcm9tQnl0ZXMgPSBmdW5jdGlvbihieXRlcykge1xuXHRcdHRoaXMuZGF0YSA9IG5ldyBCaWdJbnRlZ2VyKHV0aWwuaGV4c3RyZHVtcChieXRlcyksIDE2KTsgXG5cdH1cblxuXHR0aGlzLnRvQnl0ZXMgPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy53cml0ZSgpLnN1YnN0cigyKTtcblx0fVxuXG5cdHRoaXMuYnl0ZUxlbmd0aCA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnRvQnl0ZXMoKS5sZW5ndGg7XG5cdH1cblxuXHQvKipcblx0ICogQ29udmVydHMgdGhlIG1waSBvYmplY3QgdG8gYSBzdHJpbmcgYXMgc3BlY2lmaWVkIGluIFJGQzQ4ODAgMy4yXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gbXBpIEJ5dGUgcmVwcmVzZW50YXRpb25cblx0ICovXG5cdHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5kYXRhLnRvTVBJKCk7XG5cdH1cblxuXHR0aGlzLnRvQmlnSW50ZWdlciA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmRhdGEuY2xvbmUoKTtcblx0fVxuXG5cdHRoaXMuZnJvbUJpZ0ludGVnZXIgPSBmdW5jdGlvbihibikge1xuXHRcdHRoaXMuZGF0YSA9IGJuLmNsb25lKCk7XG5cdH1cbn1cblxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKSxcblx0dXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcblx0Y3J5cHRvID0gcmVxdWlyZSgnLi4vY3J5cHRvJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBTdHJpbmctdG8ta2V5IHNwZWNpZmllciAoUkZDNDg4MCAzLjcpXG4gKiBTdHJpbmctdG8ta2V5IChTMkspIHNwZWNpZmllcnMgYXJlIHVzZWQgdG8gY29udmVydCBwYXNzcGhyYXNlIHN0cmluZ3NcbiAgIGludG8gc3ltbWV0cmljLWtleSBlbmNyeXB0aW9uL2RlY3J5cHRpb24ga2V5cy4gIFRoZXkgYXJlIHVzZWQgaW4gdHdvXG4gICBwbGFjZXMsIGN1cnJlbnRseTogdG8gZW5jcnlwdCB0aGUgc2VjcmV0IHBhcnQgb2YgcHJpdmF0ZSBrZXlzIGluIHRoZVxuICAgcHJpdmF0ZSBrZXlyaW5nLCBhbmQgdG8gY29udmVydCBwYXNzcGhyYXNlcyB0byBlbmNyeXB0aW9uIGtleXMgZm9yXG4gICBzeW1tZXRyaWNhbGx5IGVuY3J5cHRlZCBtZXNzYWdlcy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzMmsoKSB7XG5cdC8qKiBAdHlwZSB7b3BlbnBncC5oYXNofSAqL1xuXHR0aGlzLmFsZ29yaXRobSA9ICdzaGEyNTYnO1xuXHQvKiogQHR5cGUge29wZW5wZ3BfdHlwZV9zMmsudHlwZX0gKi9cblx0dGhpcy50eXBlID0gJ2l0ZXJhdGVkJztcblx0dGhpcy5jID0gOTY7XG5cdC8qKiBAdHlwZSB7b3BlbnBncF9ieXRlYXJyYXl9IFxuXHQgKiBFaWdodCBieXRlcyBvZiBzYWx0LiAqL1xuXHR0aGlzLnNhbHQgPSBjcnlwdG8ucmFuZG9tLmdldFJhbmRvbUJ5dGVzKDgpO1xuXG5cblx0Ly8gRXhwb25lbiBiaWFzLCBkZWZpbmVkIGluIFJGQzQ4ODBcblx0dmFyIGV4cGJpYXMgPSA2O1xuXG5cdHRoaXMuZ2V0X2NvdW50ID0gZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuICgxNiArICh0aGlzLmMgJiAxNSkpIDw8ICgodGhpcy5jID4+IDQpICsgZXhwYmlhcyk7XG5cdH1cblxuXHQvKipcblx0ICogUGFyc2luZyBmdW5jdGlvbiBmb3IgYSBzdHJpbmctdG8ta2V5IHNwZWNpZmllciAoUkZDIDQ4ODAgMy43KS5cblx0ICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFBheWxvYWQgb2Ygc3RyaW5nLXRvLWtleSBzcGVjaWZpZXJcblx0ICogQHJldHVybiB7SW50ZWdlcn0gQWN0dWFsIGxlbmd0aCBvZiB0aGUgb2JqZWN0XG5cdCAqL1xuXHR0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuXHRcdHZhciBpID0gMDtcblx0XHR0aGlzLnR5cGUgPSBlbnVtcy5yZWFkKGVudW1zLnMyaywgYnl0ZXNbaSsrXS5jaGFyQ29kZUF0KCkpO1xuXHRcdHRoaXMuYWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5oYXNoLCBieXRlc1tpKytdLmNoYXJDb2RlQXQoKSk7XG5cblx0XHRzd2l0Y2ggKHRoaXMudHlwZSkge1xuXHRcdGNhc2UgJ3NpbXBsZSc6XG5cdFx0XHRicmVhaztcblxuXHRcdGNhc2UgJ3NhbHRlZCc6XG5cdFx0XHR0aGlzLnNhbHQgPSBieXRlcy5zdWJzdHIoaSwgOCk7XG5cdFx0XHRpICs9IDg7XG5cdFx0XHRicmVhaztcblxuXHRcdGNhc2UgJ2l0ZXJhdGVkJzpcblx0XHRcdHRoaXMuc2FsdCA9IGJ5dGVzLnN1YnN0cihpLCA4KTtcblx0XHRcdGkgKz0gODtcblxuXHRcdFx0Ly8gT2N0ZXQgMTA6IGNvdW50LCBhIG9uZS1vY3RldCwgY29kZWQgdmFsdWVcblx0XHRcdHRoaXMuYyA9IGJ5dGVzW2krK10uY2hhckNvZGVBdCgpO1xuXHRcdFx0YnJlYWs7XG5cblx0XHRjYXNlICdnbnUnOlxuXHRcdFx0aWYoYnl0ZXMuc3Vic3RyKGksIDMpID09IFwiR05VXCIpIHtcblx0XHRcdFx0aSArPSAzOyAvLyBHTlVcblx0XHRcdFx0dmFyIGdudUV4dFR5cGUgPSAxMDAwICsgYnl0ZXNbaSsrXS5jaGFyQ29kZUF0KCk7XG5cdFx0XHRcdGlmKGdudUV4dFR5cGUgPT0gMTAwMSkge1xuXHRcdFx0XHRcdHRoaXMudHlwZSA9IGdudUV4dFR5cGU7XG5cdFx0XHRcdFx0Ly8gR251UEcgZXh0ZW5zaW9uIG1vZGUgMTAwMSAtLSBkb24ndCB3cml0ZSBzZWNyZXQga2V5IGF0IGFsbFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcihcIlVua25vd24gczJrIGdudSBwcm90ZWN0aW9uIG1vZGUuXCIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIHMyayB0eXBlLlwiKTtcblx0XHRcdH1cblx0XHRcdGJyZWFrO1xuXG5cdFx0ZGVmYXVsdDpcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIlVua25vd24gczJrIHR5cGUuXCIpO1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGk7XG5cdH1cblx0XG5cdFxuXHQvKipcblx0ICogd3JpdGVzIGFuIHMyayBoYXNoIGJhc2VkIG9uIHRoZSBpbnB1dHMuXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gUHJvZHVjZWQga2V5IG9mIGhhc2hBbGdvcml0aG0gaGFzaCBsZW5ndGhcblx0ICovXG5cdHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcblx0XHR2YXIgYnl0ZXMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnMyaywgdGhpcy50eXBlKSk7XG5cdFx0Ynl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5oYXNoLCB0aGlzLmFsZ29yaXRobSkpO1xuXG5cdFx0c3dpdGNoKHRoaXMudHlwZSkge1xuXHRcdFx0Y2FzZSAnc2ltcGxlJzpcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdzYWx0ZWQnOlxuXHRcdFx0XHRieXRlcyArPSB0aGlzLnNhbHQ7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnaXRlcmF0ZWQnOlxuXHRcdFx0XHRieXRlcyArPSB0aGlzLnNhbHQ7XG5cdFx0XHRcdGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodGhpcy5jKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0fTtcblxuXHRcdHJldHVybiBieXRlcztcblx0fVxuXG5cdC8qKlxuXHQgKiBQcm9kdWNlcyBhIGtleSB1c2luZyB0aGUgc3BlY2lmaWVkIHBhc3NwaHJhc2UgYW5kIHRoZSBkZWZpbmVkIFxuXHQgKiBoYXNoQWxnb3JpdGhtIFxuXHQgKiBAcGFyYW0ge1N0cmluZ30gcGFzc3BocmFzZSBQYXNzcGhyYXNlIGNvbnRhaW5pbmcgdXNlciBpbnB1dFxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IFByb2R1Y2VkIGtleSB3aXRoIGEgbGVuZ3RoIGNvcnJlc3BvbmRpbmcgdG8gXG5cdCAqIGhhc2hBbGdvcml0aG0gaGFzaCBsZW5ndGhcblx0ICovXG5cdHRoaXMucHJvZHVjZV9rZXkgPSBmdW5jdGlvbihwYXNzcGhyYXNlLCBudW1CeXRlcykge1xuXHRcdHBhc3NwaHJhc2UgPSB1dGlsLmVuY29kZV91dGY4KHBhc3NwaHJhc2UpO1xuXG5cdFx0ZnVuY3Rpb24gcm91bmQocHJlZml4LCBzMmspIHtcblx0XHRcdHZhciBhbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5oYXNoLCBzMmsuYWxnb3JpdGhtKTtcblxuXHRcdFx0c3dpdGNoKHMyay50eXBlKSB7XG5cdFx0XHRcdGNhc2UgJ3NpbXBsZSc6XG5cdFx0XHRcdFx0cmV0dXJuIGNyeXB0by5oYXNoLmRpZ2VzdChhbGdvcml0aG0sIHByZWZpeCArIHBhc3NwaHJhc2UpO1xuXG5cdFx0XHRcdGNhc2UgJ3NhbHRlZCc6XG5cdFx0XHRcdFx0cmV0dXJuIGNyeXB0by5oYXNoLmRpZ2VzdChhbGdvcml0aG0sIFxuXHRcdFx0XHRcdFx0cHJlZml4ICsgczJrLnNhbHQgKyBwYXNzcGhyYXNlKTtcblxuXHRcdFx0XHRjYXNlICdpdGVyYXRlZCc6XG5cdFx0XHRcdFx0dmFyIGlzcCA9IFtdLFxuXHRcdFx0XHRcdFx0Y291bnQgPSBzMmsuZ2V0X2NvdW50KCk7XG5cdFx0XHRcdFx0XHRkYXRhID0gczJrLnNhbHQgKyBwYXNzcGhyYXNlO1xuXG5cdFx0XHRcdFx0d2hpbGUgKGlzcC5sZW5ndGggKiBkYXRhLmxlbmd0aCA8IGNvdW50KVxuXHRcdFx0XHRcdFx0aXNwLnB1c2goZGF0YSk7XG5cblx0XHRcdFx0XHRpc3AgPSBpc3Auam9pbignJyk7XHRcdFx0XG5cblx0XHRcdFx0XHRpZiAoaXNwLmxlbmd0aCA+IGNvdW50KVxuXHRcdFx0XHRcdFx0aXNwID0gaXNwLnN1YnN0cigwLCBjb3VudCk7XG5cblx0XHRcdFx0XHRyZXR1cm4gY3J5cHRvLmhhc2guZGlnZXN0KGFsZ29yaXRobSwgcHJlZml4ICsgaXNwKTtcblx0XHRcdH07XG5cdFx0fVxuXHRcdFxuXHRcdHZhciByZXN1bHQgPSAnJyxcblx0XHRcdHByZWZpeCA9ICcnO1xuXG5cdFx0d2hpbGUocmVzdWx0Lmxlbmd0aCA8PSBudW1CeXRlcykge1xuXHRcdFx0cmVzdWx0ICs9IHJvdW5kKHByZWZpeCwgdGhpcyk7XG5cdFx0XHRwcmVmaXggKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0LnN1YnN0cigwLCBudW1CeXRlcyk7XG5cdH1cbn1cblxuXG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgVXRpbCA9IGZ1bmN0aW9uKCkge1xuXG5cdHRoaXMucmVhZE51bWJlciA9IGZ1bmN0aW9uIChieXRlcykge1xuXHRcdHZhciBuID0gMDtcblxuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0biA8PD0gODtcblx0XHRcdG4gKz0gYnl0ZXNbaV0uY2hhckNvZGVBdCgpO1xuXHRcdH1cblxuXHRcdHJldHVybiBuO1xuXHR9O1xuXG5cdHRoaXMud3JpdGVOdW1iZXIgPSBmdW5jdGlvbihuLCBieXRlcykge1xuXHRcdHZhciBiID0gJyc7XG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IGJ5dGVzOyBpKyspIHtcblx0XHRcdGIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgobiA+PiAoOCAqIChieXRlcy0gaSAtIDEpKSkgJiAweEZGKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gYjtcblx0fTtcblxuXG5cblx0dGhpcy5yZWFkRGF0ZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG5cdFx0dmFyIG4gPSB0aGlzLnJlYWROdW1iZXIoYnl0ZXMpO1xuXHRcdHZhciBkID0gbmV3IERhdGUoKTtcblx0XHRkLnNldFRpbWUobiAqIDEwMDApO1xuXHRcdHJldHVybiBkO1xuXHR9O1xuXG5cdHRoaXMud3JpdGVEYXRlID0gZnVuY3Rpb24odGltZSkge1xuXHRcdHZhciBudW1lcmljID0gTWF0aC5yb3VuZCh0aW1lLmdldFRpbWUoKSAvIDEwMDApO1xuXG5cdFx0cmV0dXJuIHRoaXMud3JpdGVOdW1iZXIobnVtZXJpYywgNCk7XG5cdH07XG5cbiAgICB0aGlzLmVtYWlsUmVnRXggPSAvW2EtejAtOSEjJCUmJyorLz0/Xl9ge3x9fi1dKyg/OlxcLlthLXowLTkhIyQlJicqKy89P15fYHt8fX4tXSspKkAoPzpbYS16MC05XSg/OlthLXowLTktXSpbYS16MC05XSk/XFwuKStbYS16MC05XSg/OlthLXowLTktXSpbYS16MC05XSk/Lztcblx0XG5cdHRoaXMuZGVidWcgPSBmYWxzZTtcblxuXHR0aGlzLmhleGR1bXAgPSBmdW5jdGlvbihzdHIpIHtcblx0ICAgIHZhciByPVtdO1xuXHQgICAgdmFyIGU9c3RyLmxlbmd0aDtcblx0ICAgIHZhciBjPTA7XG5cdCAgICB2YXIgaDtcblx0ICAgIHZhciBpID0gMDtcblx0ICAgIHdoaWxlKGM8ZSl7XG5cdCAgICAgICAgaD1zdHIuY2hhckNvZGVBdChjKyspLnRvU3RyaW5nKDE2KTtcblx0ICAgICAgICB3aGlsZShoLmxlbmd0aDwyKSBoPVwiMFwiK2g7XG5cdCAgICAgICAgci5wdXNoKFwiIFwiK2gpO1xuXHQgICAgICAgIGkrKztcblx0ICAgICAgICBpZiAoaSAlIDMyID09IDApXG5cdCAgICAgICAgXHRyLnB1c2goXCJcXG4gICAgICAgICAgIFwiKTtcblx0ICAgIH1cblx0ICAgIHJldHVybiByLmpvaW4oJycpO1xuXHR9O1xuXHRcblx0LyoqXG5cdCAqIENyZWF0ZSBoZXhzdHJpbmcgZnJvbSBhIGJpbmFyeVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBjb252ZXJ0XG5cdCAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGhleGFkZWNpbWFsIHZhbHVlc1xuXHQgKi9cblx0dGhpcy5oZXhzdHJkdW1wID0gZnVuY3Rpb24oc3RyKSB7XG5cdFx0aWYgKHN0ciA9PSBudWxsKVxuXHRcdFx0cmV0dXJuIFwiXCI7XG5cdCAgICB2YXIgcj1bXTtcblx0ICAgIHZhciBlPXN0ci5sZW5ndGg7XG5cdCAgICB2YXIgYz0wO1xuXHQgICAgdmFyIGg7XG5cdCAgICB3aGlsZShjPGUpe1xuXHQgICAgICAgIGg9c3RyW2MrK10uY2hhckNvZGVBdCgpLnRvU3RyaW5nKDE2KTtcblx0ICAgICAgICB3aGlsZShoLmxlbmd0aDwyKSBoPVwiMFwiK2g7XG5cdCAgICAgICAgci5wdXNoKFwiXCIraCk7XG5cdCAgICB9XG5cdCAgICByZXR1cm4gci5qb2luKCcnKTtcblx0fTtcblx0XG5cdC8qKlxuXHQgKiBDcmVhdGUgYmluYXJ5IHN0cmluZyBmcm9tIGEgaGV4IGVuY29kZWQgc3RyaW5nXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgSGV4IHN0cmluZyB0byBjb252ZXJ0XG5cdCAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIGNvbnRhaW5pbmcgdGhlIGJpbmFyeSB2YWx1ZXNcblx0ICovXG5cdHRoaXMuaGV4MmJpbiA9IGZ1bmN0aW9uKGhleCkge1xuXHQgICAgdmFyIHN0ciA9ICcnO1xuXHQgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZXgubGVuZ3RoOyBpICs9IDIpXG5cdCAgICAgICAgc3RyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocGFyc2VJbnQoaGV4LnN1YnN0cihpLCAyKSwgMTYpKTtcblx0ICAgIHJldHVybiBzdHI7XG5cdH07XG5cdFxuXHQvKipcblx0ICogQ3JlYXRpbmcgYSBoZXggc3RyaW5nIGZyb20gYW4gYmluYXJ5IGFycmF5IG9mIGludGVnZXJzICgwLi4yNTUpXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgQXJyYXkgb2YgYnl0ZXMgdG8gY29udmVydFxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IEhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcnJheVxuXHQgKi9cblx0dGhpcy5oZXhpZHVtcCA9IGZ1bmN0aW9uKHN0cikge1xuXHQgICAgdmFyIHI9W107XG5cdCAgICB2YXIgZT1zdHIubGVuZ3RoO1xuXHQgICAgdmFyIGM9MDtcblx0ICAgIHZhciBoO1xuXHQgICAgd2hpbGUoYzxlKXtcblx0ICAgICAgICBoPXN0cltjKytdLnRvU3RyaW5nKDE2KTtcblx0ICAgICAgICB3aGlsZShoLmxlbmd0aDwyKSBoPVwiMFwiK2g7XG5cdCAgICAgICAgci5wdXNoKFwiXCIraCk7XG5cdCAgICB9XG5cdCAgICByZXR1cm4gci5qb2luKCcnKTtcblx0fTtcblxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0IGEgbmF0aXZlIGphdmFzY3JpcHQgc3RyaW5nIHRvIGEgc3RyaW5nIG9mIHV0ZjggYnl0ZXNcblx0ICogQHBhcmFtIHtTdHJpbmd9IHN0ciBUaGUgc3RyaW5nIHRvIGNvbnZlcnRcblx0ICogQHJldHVybiB7U3RyaW5nfSBBIHZhbGlkIHNxdWVuY2Ugb2YgdXRmOCBieXRlc1xuXHQgKi9cblx0dGhpcy5lbmNvZGVfdXRmOCA9IGZ1bmN0aW9uKHN0cikge1xuXHRcdHJldHVybiB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSk7XG5cdH07XG5cblx0LyoqXG5cdCAqIENvbnZlcnQgYSBzdHJpbmcgb2YgdXRmOCBieXRlcyB0byBhIG5hdGl2ZSBqYXZhc2NyaXB0IHN0cmluZ1xuXHQgKiBAcGFyYW0ge1N0cmluZ30gdXRmOCBBIHZhbGlkIHNxdWVuY2Ugb2YgdXRmOCBieXRlc1xuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IEEgbmF0aXZlIGphdmFzY3JpcHQgc3RyaW5nXG5cdCAqL1xuXHR0aGlzLmRlY29kZV91dGY4ID0gZnVuY3Rpb24odXRmOCkge1xuXHRcdHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHV0ZjgpKTtcblx0fTtcblxuXHR2YXIgc3RyMmJpbiA9IGZ1bmN0aW9uKHN0ciwgcmVzdWx0KSB7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcblx0XHRcdHJlc3VsdFtpXSA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuXHRcdH1cblxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH07XG5cdFxuXHR2YXIgYmluMnN0ciA9IGZ1bmN0aW9uKGJpbikge1xuXHRcdHZhciByZXN1bHQgPSBbXTtcblxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgYmluLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRyZXN1bHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJpbltpXSkpO1xuXHRcdH1cblxuXHRcdHJldHVybiByZXN1bHQuam9pbignJyk7XG5cdH07XG5cblx0LyoqXG5cdCAqIENvbnZlcnQgYSBzdHJpbmcgdG8gYW4gYXJyYXkgb2YgaW50ZWdlcnMoMC4yNTUpXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNvbnZlcnRcblx0ICogQHJldHVybiB7SW50ZWdlcltdfSBBbiBhcnJheSBvZiAoYmluYXJ5KSBpbnRlZ2Vyc1xuXHQgKi9cblx0dGhpcy5zdHIyYmluID0gZnVuY3Rpb24oc3RyKSB7IFxuXHRcdHJldHVybiBzdHIyYmluKHN0ciwgbmV3IEFycmF5KHN0ci5sZW5ndGgpKTtcblx0fTtcblx0XG5cdFxuXHQvKipcblx0ICogQ29udmVydCBhbiBhcnJheSBvZiBpbnRlZ2VycygwLjI1NSkgdG8gYSBzdHJpbmcgXG5cdCAqIEBwYXJhbSB7SW50ZWdlcltdfSBiaW4gQW4gYXJyYXkgb2YgKGJpbmFyeSkgaW50ZWdlcnMgdG8gY29udmVydFxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGFycmF5XG5cdCAqL1xuXHR0aGlzLmJpbjJzdHIgPSBiaW4yc3RyO1xuXHRcblx0LyoqXG5cdCAqIENvbnZlcnQgYSBzdHJpbmcgdG8gYSBVaW50OEFycmF5XG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNvbnZlcnRcblx0ICogQHJldHVybiB7VWludDhBcnJheX0gVGhlIGFycmF5IG9mIChiaW5hcnkpIGludGVnZXJzXG5cdCAqL1xuXHR0aGlzLnN0cjJVaW50OEFycmF5ID0gZnVuY3Rpb24oc3RyKSB7IFxuXHRcdHJldHVybiBzdHIyYmluKHN0ciwgbmV3IFVpbnQ4QXJyYXkobmV3IEFycmF5QnVmZmVyKHN0ci5sZW5ndGgpKSk7IFxuXHR9O1xuXHRcblx0LyoqXG5cdCAqIENvbnZlcnQgYSBVaW50OEFycmF5IHRvIGEgc3RyaW5nLiBUaGlzIGN1cnJlbnRseSBmdW5jdGlvbnMgXG5cdCAqIHRoZSBzYW1lIGFzIGJpbjJzdHIuIFxuXHQgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJpbiBBbiBhcnJheSBvZiAoYmluYXJ5KSBpbnRlZ2VycyB0byBjb252ZXJ0XG5cdCAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcnJheVxuXHQgKi9cblx0dGhpcy5VaW50OEFycmF5MnN0ciA9IGJpbjJzdHI7XG5cdFxuXHQvKipcblx0ICogQ2FsY3VsYXRlcyBhIDE2Yml0IHN1bSBvZiBhIHN0cmluZyBieSBhZGRpbmcgZWFjaCBjaGFyYWN0ZXIgXG5cdCAqIGNvZGVzIG1vZHVsdXMgNjU1MzVcblx0ICogQHBhcmFtIHtTdHJpbmd9IHRleHQgU3RyaW5nIHRvIGNyZWF0ZSBhIHN1bSBvZlxuXHQgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBbiBpbnRlZ2VyIGNvbnRhaW5pbmcgdGhlIHN1bSBvZiBhbGwgY2hhcmFjdGVyIFxuXHQgKiBjb2RlcyAlIDY1NTM1XG5cdCAqL1xuXHR0aGlzLmNhbGNfY2hlY2tzdW0gPSBmdW5jdGlvbih0ZXh0KSB7XG5cdFx0dmFyIGNoZWNrc3VtID0geyAgczogMCwgYWRkOiBmdW5jdGlvbiAoc2FkZCkgeyB0aGlzLnMgPSAodGhpcy5zICsgc2FkZCkgJSA2NTUzNjsgfX07XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRjaGVja3N1bS5hZGQodGV4dC5jaGFyQ29kZUF0KGkpKTtcblx0XHR9XG5cdFx0cmV0dXJuIGNoZWNrc3VtLnM7XG5cdH07XG5cdFxuXHQvKipcblx0ICogSGVscGVyIGZ1bmN0aW9uIHRvIHByaW50IGEgZGVidWcgbWVzc2FnZS4gRGVidWcgXG5cdCAqIG1lc3NhZ2VzIGFyZSBvbmx5IHByaW50ZWQgaWZcblx0ICogb3BlbnBncC5jb25maWcuZGVidWcgaXMgc2V0IHRvIHRydWUuIFRoZSBjYWxsaW5nXG5cdCAqIEphdmFzY3JpcHQgY29udGV4dCBNVVNUIGRlZmluZVxuXHQgKiBhIFwic2hvd01lc3NhZ2VzKHRleHQpXCIgZnVuY3Rpb24uIExpbmUgZmVlZHMgKCdcXG4nKVxuXHQgKiBhcmUgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG8gSFRNTCBsaW5lIGZlZWRzICc8YnIvPidcblx0ICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgb2YgdGhlIGRlYnVnIG1lc3NhZ2Vcblx0ICogQHJldHVybiB7U3RyaW5nfSBBbiBIVE1MIHR0IGVudGl0eSBjb250YWluaW5nIGEgcGFyYWdyYXBoIHdpdGggYSBcblx0ICogc3R5bGUgYXR0cmlidXRlIHdoZXJlIHRoZSBkZWJ1ZyBtZXNzYWdlIGlzIEhUTUxlbmNvZGVkIGluLiBcblx0ICovXG5cdHRoaXMucHJpbnRfZGVidWcgPSBmdW5jdGlvbihzdHIpIHtcblx0XHRpZiAodGhpcy5kZWJ1Zykge1xuXHRcdFx0Y29uc29sZS5sb2coc3RyKTtcblx0XHR9XG5cdH07XG5cdFxuXHQvKipcblx0ICogSGVscGVyIGZ1bmN0aW9uIHRvIHByaW50IGEgZGVidWcgbWVzc2FnZS4gRGVidWcgXG5cdCAqIG1lc3NhZ2VzIGFyZSBvbmx5IHByaW50ZWQgaWZcblx0ICogb3BlbnBncC5jb25maWcuZGVidWcgaXMgc2V0IHRvIHRydWUuIFRoZSBjYWxsaW5nXG5cdCAqIEphdmFzY3JpcHQgY29udGV4dCBNVVNUIGRlZmluZVxuXHQgKiBhIFwic2hvd01lc3NhZ2VzKHRleHQpXCIgZnVuY3Rpb24uIExpbmUgZmVlZHMgKCdcXG4nKVxuXHQgKiBhcmUgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG8gSFRNTCBsaW5lIGZlZWRzICc8YnIvPidcblx0ICogRGlmZmVyZW50IHRoYW4gcHJpbnRfZGVidWcgYmVjYXVzZSB3aWxsIGNhbGwgaGV4c3RyZHVtcCBpZmYgbmVjZXNzYXJ5LlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyBvZiB0aGUgZGVidWcgbWVzc2FnZVxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IEFuIEhUTUwgdHQgZW50aXR5IGNvbnRhaW5pbmcgYSBwYXJhZ3JhcGggd2l0aCBhIFxuXHQgKiBzdHlsZSBhdHRyaWJ1dGUgd2hlcmUgdGhlIGRlYnVnIG1lc3NhZ2UgaXMgSFRNTGVuY29kZWQgaW4uIFxuXHQgKi9cblx0dGhpcy5wcmludF9kZWJ1Z19oZXhzdHJfZHVtcCA9IGZ1bmN0aW9uKHN0cixzdHJUb0hleCkge1xuXHRcdGlmICh0aGlzLmRlYnVnKSB7XG5cdFx0XHRzdHIgPSBzdHIgKyB0aGlzLmhleHN0cmR1bXAoc3RyVG9IZXgpO1xuXHRcdFx0Y29uc29sZS5sb2coc3RyKTtcblx0XHR9XG5cdH07XG5cdFxuXHQvKipcblx0ICogSGVscGVyIGZ1bmN0aW9uIHRvIHByaW50IGFuIGVycm9yIG1lc3NhZ2UuIFxuXHQgKiBUaGUgY2FsbGluZyBKYXZhc2NyaXB0IGNvbnRleHQgTVVTVCBkZWZpbmVcblx0ICogYSBcInNob3dNZXNzYWdlcyh0ZXh0KVwiIGZ1bmN0aW9uLiBMaW5lIGZlZWRzICgnXFxuJylcblx0ICogYXJlIGF1dG9tYXRpY2FsbHkgY29udmVydGVkIHRvIEhUTUwgbGluZSBmZWVkcyAnPGJyLz4nXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBlcnJvciBtZXNzYWdlXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gQSBIVE1MIHBhcmFncmFwaCBlbnRpdHkgd2l0aCBhIHN0eWxlIGF0dHJpYnV0ZSBcblx0ICogY29udGFpbmluZyB0aGUgSFRNTCBlbmNvZGVkIGVycm9yIG1lc3NhZ2Vcblx0ICovXG5cdHRoaXMucHJpbnRfZXJyb3IgPSBmdW5jdGlvbihzdHIpIHtcblx0XHRpZih0aGlzLmRlYnVnKVxuXHRcdFx0dGhyb3cgc3RyO1xuXHRcdGNvbnNvbGUubG9nKHN0cik7XG5cdH07XG5cdFxuXHQvKipcblx0ICogSGVscGVyIGZ1bmN0aW9uIHRvIHByaW50IGFuIGluZm8gbWVzc2FnZS4gXG5cdCAqIFRoZSBjYWxsaW5nIEphdmFzY3JpcHQgY29udGV4dCBNVVNUIGRlZmluZVxuXHQgKiBhIFwic2hvd01lc3NhZ2VzKHRleHQpXCIgZnVuY3Rpb24uIExpbmUgZmVlZHMgKCdcXG4nKVxuXHQgKiBhcmUgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG8gSFRNTCBsaW5lIGZlZWRzICc8YnIvPicuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBpbmZvIG1lc3NhZ2Vcblx0ICogQHJldHVybiB7U3RyaW5nfSBBIEhUTUwgcGFyYWdyYXBoIGVudGl0eSB3aXRoIGEgc3R5bGUgYXR0cmlidXRlIFxuXHQgKiBjb250YWluaW5nIHRoZSBIVE1MIGVuY29kZWQgaW5mbyBtZXNzYWdlXG5cdCAqL1xuXHR0aGlzLnByaW50X2luZm8gPSBmdW5jdGlvbihzdHIpIHtcblx0XHRpZih0aGlzLmRlYnVnKVxuXHRcdFx0Y29uc29sZS5sb2coc3RyKTtcblx0fTtcblx0XG5cdHRoaXMucHJpbnRfd2FybmluZyA9IGZ1bmN0aW9uKHN0cikge1xuXHRcdGNvbnNvbGUubG9nKHN0cik7XG5cdH07XG5cdFxuXHR0aGlzLmdldExlZnROQml0cyA9IGZ1bmN0aW9uIChzdHJpbmcsIGJpdGNvdW50KSB7XG5cdFx0dmFyIHJlc3QgPSBiaXRjb3VudCAlIDg7XG5cdFx0aWYgKHJlc3QgPT0gMClcblx0XHRcdHJldHVybiBzdHJpbmcuc3Vic3RyaW5nKDAsIGJpdGNvdW50IC8gOCk7XG5cdFx0dmFyIGJ5dGVzID0gKGJpdGNvdW50IC0gcmVzdCkgLyA4ICsxO1xuXHRcdHZhciByZXN1bHQgPSBzdHJpbmcuc3Vic3RyaW5nKDAsIGJ5dGVzKTtcblx0XHRyZXR1cm4gdGhpcy5zaGlmdFJpZ2h0KHJlc3VsdCwgOC1yZXN0KTsgLy8gK1N0cmluZy5mcm9tQ2hhckNvZGUoc3RyaW5nLmNoYXJDb2RlQXQoYnl0ZXMgLTEpIDw8ICg4LXJlc3QpICYgMHhGRik7XG5cdH07XG5cblx0LyoqXG5cdCAqIFNoaWZ0aW5nIGEgc3RyaW5nIHRvIG4gYml0cyByaWdodFxuXHQgKiBAcGFyYW0ge1N0cmluZ30gdmFsdWUgVGhlIHN0cmluZyB0byBzaGlmdFxuXHQgKiBAcGFyYW0ge0ludGVnZXJ9IGJpdGNvdW50IEFtb3VudCBvZiBiaXRzIHRvIHNoaWZ0IChNVVNUIGJlIHNtYWxsZXIgXG5cdCAqIHRoYW4gOSlcblx0ICogQHJldHVybiB7U3RyaW5nfSBSZXN1bHRpbmcgc3RyaW5nLiBcblx0ICovXG5cdHRoaXMuc2hpZnRSaWdodCA9IGZ1bmN0aW9uKHZhbHVlLCBiaXRjb3VudCkge1xuXHRcdHZhciB0ZW1wID0gdXRpbC5zdHIyYmluKHZhbHVlKTtcbiAgICAgICAgaWYgKGJpdGNvdW50ICUgOCAhPSAwKSB7XG4gICAgICAgIFx0Zm9yICh2YXIgaSA9IHRlbXAubGVuZ3RoLTE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIFx0XHR0ZW1wW2ldID4+PSBiaXRjb3VudCAlIDg7XG4gICAgICAgIFx0XHRpZiAoaSA+IDApXG4gICAgICAgIFx0XHRcdHRlbXBbaV0gfD0gKHRlbXBbaSAtIDFdIDw8ICg4IC0gKGJpdGNvdW50ICUgOCkpKSAmIDB4RkY7XG4gICAgICAgIFx0fVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICBcdHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXRpbC5iaW4yc3RyKHRlbXApO1xuXHR9O1xuXHRcblx0LyoqXG5cdCAqIFJldHVybiB0aGUgYWxnb3JpdGhtIHR5cGUgYXMgc3RyaW5nXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gU3RyaW5nIHJlcHJlc2VudGluZyB0aGUgbWVzc2FnZSB0eXBlXG5cdCAqL1xuXHR0aGlzLmdldF9oYXNoQWxnb3JpdGhtU3RyaW5nID0gZnVuY3Rpb24oYWxnbykge1xuXHRcdHN3aXRjaChhbGdvKSB7XG5cdFx0Y2FzZSAxOlxuXHRcdFx0cmV0dXJuIFwiTUQ1XCI7XG5cdFx0Y2FzZSAyOlxuXHRcdFx0cmV0dXJuIFwiU0hBMVwiO1xuXHRcdGNhc2UgMzpcblx0XHRcdHJldHVybiBcIlJJUEVNRDE2MFwiO1xuXHRcdGNhc2UgODpcblx0XHRcdHJldHVybiBcIlNIQTI1NlwiO1xuXHRcdGNhc2UgOTpcblx0XHRcdHJldHVybiBcIlNIQTM4NFwiO1xuXHRcdGNhc2UgMTA6XG5cdFx0XHRyZXR1cm4gXCJTSEE1MTJcIjtcblx0XHRjYXNlIDExOlxuXHRcdFx0cmV0dXJuIFwiU0hBMjI0XCI7XG5cdFx0fVxuXHRcdHJldHVybiBcInVua25vd25cIjtcblx0fTtcblxufTtcblxuLyoqXG4gKiBhbiBpbnN0YW5jZSB0aGF0IHNob3VsZCBiZSB1c2VkLiBcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBuZXcgVXRpbCgpO1xuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi8uLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJBRVMgUmlqbmRhZWwgY2lwaGVyIHRlc3Qgd2l0aCB0ZXN0IHZlY3RvcnMgZnJvbSBlY2JfdGJsLnR4dFwiLCBmdW5jdGlvbigpIHtcbiAgdmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8uLi8nKTtcbiAgdmFyIHV0aWwgPSBvcGVucGdwLnV0aWw7XG5cbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheSgpO1xuXG4gIGZ1bmN0aW9uIHRlc3RfYWVzKGlucHV0LCBrZXksIG91dHB1dCkge1xuICAgIHZhciBhZXMgPSBuZXcgb3BlbnBncC5jaXBoZXIuYWVzMTI4KHV0aWwuYmluMnN0cihrZXkpKTtcblxuICAgIHZhciByZXN1bHQgPSB1dGlsLmJpbjJzdHIoYWVzLmVuY3J5cHQoaW5wdXQpKTtcblxuICAgIHJldHVybiB1dGlsLmhleHN0cmR1bXAocmVzdWx0KSA9PSB1dGlsLmhleHN0cmR1bXAodXRpbC5iaW4yc3RyKG91dHB1dCkpO1xuICB9O1xuXG4gIHZhciB0ZXN0dmVjdG9yczEyOCA9IFtbWzB4MDAsMHgwMSwweDAyLDB4MDMsMHgwNSwweDA2LDB4MDcsMHgwOCwweDBBLDB4MEIsMHgwQywweDBELDB4MEYsMHgxMCwweDExLDB4MTJdLFsweDUwLDB4NjgsMHgxMiwweEE0LDB4NUYsMHgwOCwweEM4LDB4ODksMHhCOSwweDdGLDB4NTksMHg4MCwweDAzLDB4OEIsMHg4MywweDU5XSxbMHhEOCwweEY1LDB4MzIsMHg1MywweDgyLDB4ODksMHhFRiwweDdELDB4MDYsMHhCNSwweDA2LDB4QTQsMHhGRCwweDVCLDB4RTksMHhDOV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDE0LDB4MTUsMHgxNiwweDE3LDB4MTksMHgxQSwweDFCLDB4MUMsMHgxRSwweDFGLDB4MjAsMHgyMSwweDIzLDB4MjQsMHgyNSwweDI2XSxbMHg1QywweDZELDB4NzEsMHhDQSwweDMwLDB4REUsMHg4QiwweDhCLDB4MDAsMHg1NCwweDk5LDB4ODQsMHhEMiwweEVDLDB4N0QsMHg0Ql0sWzB4NTksMHhBQiwweDMwLDB4RjQsMHhENCwweEVFLDB4NkUsMHg0RiwweEY5LDB4OTAsMHg3RSwweEY2LDB4NUIsMHgxRiwweEI2LDB4OENdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHgyOCwweDI5LDB4MkEsMHgyQiwweDJELDB4MkUsMHgyRiwweDMwLDB4MzIsMHgzMywweDM0LDB4MzUsMHgzNywweDM4LDB4MzksMHgzQV0sWzB4NTMsMHhGMywweEY0LDB4QzYsMHg0RiwweDg2LDB4MTYsMHhFNCwweEU3LDB4QzUsMHg2MSwweDk5LDB4RjQsMHg4RiwweDIxLDB4RjZdLFsweEJGLDB4MUUsMHhEMiwweEZDLDB4QjIsMHhBRiwweDNGLDB4RDQsMHgxNCwweDQzLDB4QjUsMHg2RCwweDg1LDB4MDIsMHg1QywweEIxXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4M0MsMHgzRCwweDNFLDB4M0YsMHg0MSwweDQyLDB4NDMsMHg0NCwweDQ2LDB4NDcsMHg0OCwweDQ5LDB4NEIsMHg0QywweDRELDB4NEVdLFsweEExLDB4RUIsMHg2NSwweEEzLDB4NDgsMHg3MSwweDY1LDB4RkIsMHgwRiwweDFDLDB4MjcsMHhGRiwweDk5LDB4NTksMHhGNywweDAzXSxbMHg3MywweDE2LDB4NjMsMHgyRCwweDVDLDB4MzIsMHgyMywweDNFLDB4REMsMHhCMCwweDc4LDB4MDUsMHg2MCwweEVBLDB4RTgsMHhCMl1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDUwLDB4NTEsMHg1MiwweDUzLDB4NTUsMHg1NiwweDU3LDB4NTgsMHg1QSwweDVCLDB4NUMsMHg1RCwweDVGLDB4NjAsMHg2MSwweDYyXSxbMHgzNSwweDUzLDB4RUMsMHhGMCwweEIxLDB4NzMsMHg5NSwweDU4LDB4QjAsMHg4RSwweDM1LDB4MEEsMHg5OCwweEEzLDB4OUIsMHhGQV0sWzB4NDAsMHg4QywweDA3LDB4M0UsMHgzRSwweDI1LDB4MzgsMHgwNywweDJCLDB4NzIsMHg2MiwweDVFLDB4NjgsMHhCOCwweDM2LDB4NEJdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHg2NCwweDY1LDB4NjYsMHg2NywweDY5LDB4NkEsMHg2QiwweDZDLDB4NkUsMHg2RiwweDcwLDB4NzEsMHg3MywweDc0LDB4NzUsMHg3Nl0sWzB4NjcsMHg0MiwweDk5LDB4NjksMHg0OSwweDBCLDB4OTcsMHgxMSwweEFFLDB4MkIsMHgwMSwweERDLDB4NDksMHg3QSwweEZELDB4RThdLFsweEUxLDB4RjksMHg0RCwweEZBLDB4NzcsMHg2NSwweDk3LDB4QkUsMHhBQywweEEyLDB4NjIsMHhGMiwweEY2LDB4MzYsMHg2RiwweEVBXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4NzgsMHg3OSwweDdBLDB4N0IsMHg3RCwweDdFLDB4N0YsMHg4MCwweDgyLDB4ODMsMHg4NCwweDg1LDB4ODcsMHg4OCwweDg5LDB4OEFdLFsweDkzLDB4MzgsMHg1QywweDFGLDB4MkEsMHhFQywweDhCLDB4RUQsMHgxOSwweDJGLDB4NUEsMHg4RSwweDE2LDB4MUQsMHhENSwweDA4XSxbMHhGMiwweDlFLDB4OTgsMHg2QywweDZBLDB4MUMsMHgyNywweEQ3LDB4QjIsMHg5RiwweEZELDB4N0UsMHhFOSwweDJCLDB4NzUsMHhGMV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDhDLDB4OEQsMHg4RSwweDhGLDB4OTEsMHg5MiwweDkzLDB4OTQsMHg5NiwweDk3LDB4OTgsMHg5OSwweDlCLDB4OUMsMHg5RCwweDlFXSxbMHhCNSwweEJGLDB4OTQsMHg2QiwweEUxLDB4OUIsMHhFQiwweDhELDB4QjMsMHg5OCwweDNCLDB4NUYsMHg0QywweDZFLDB4OEQsMHhEQl0sWzB4MTMsMHgxQywweDg4LDB4NkEsMHg1NywweEY4LDB4QzIsMHhFNywweDEzLDB4QUIsMHhBNiwweDk1LDB4NUUsMHgyQiwweDU1LDB4QjVdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHhBMCwweEExLDB4QTIsMHhBMywweEE1LDB4QTYsMHhBNywweEE4LDB4QUEsMHhBQiwweEFDLDB4QUQsMHhBRiwweEIwLDB4QjEsMHhCMl0sWzB4NDEsMHgzMiwweDFFLDB4RTEsMHgwRSwweDIxLDB4QkQsMHg5MCwweDcyLDB4MjcsMHhDNCwweDQ1LDB4MEYsMHhGNCwweDIzLDB4MjRdLFsweEQyLDB4QUIsMHg3NiwweDYyLDB4REYsMHg5QiwweDhDLDB4NzQsMHgwMiwweDEwLDB4RTUsMHhFRSwweEI2LDB4MUMsMHgxOSwweDlEXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4QjQsMHhCNSwweEI2LDB4QjcsMHhCOSwweEJBLDB4QkIsMHhCQywweEJFLDB4QkYsMHhDMCwweEMxLDB4QzMsMHhDNCwweEM1LDB4QzZdLFsweDAwLDB4QTgsMHgyRiwweDU5LDB4QzksMHgxQywweDg0LDB4ODYsMHhEMSwweDJDLDB4MEEsMHg4MCwweDEyLDB4NEYsMHg2MCwweDg5XSxbMHgxNCwweEMxLDB4MDUsMHg1NCwweEIyLDB4ODUsMHg5QywweDQ4LDB4NEMsMHhBQiwweDU4LDB4NjksMHhCQiwweEU3LDB4QzQsMHg3MF1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweEM4LDB4QzksMHhDQSwweENCLDB4Q0QsMHhDRSwweENGLDB4RDAsMHhEMiwweEQzLDB4RDQsMHhENSwweEQ3LDB4RDgsMHhEOSwweERBXSxbMHg3QywweEUwLDB4RkQsMHgwNywweDY3LDB4NTQsMHg2OSwweDFCLDB4NEIsMHhCRCwweDlGLDB4QUYsMHg4QSwweDEzLDB4NzIsMHhGRV0sWzB4REIsMHg0RCwweDQ5LDB4OEYsMHgwQSwweDQ5LDB4Q0YsMHg1NSwweDQ0LDB4NUQsMHg1MCwweDJDLDB4MUYsMHg5QSwweEIzLDB4QjVdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHhEQywweERELDB4REUsMHhERiwweEUxLDB4RTIsMHhFMywweEU0LDB4RTYsMHhFNywweEU4LDB4RTksMHhFQiwweEVDLDB4RUQsMHhFRV0sWzB4MjMsMHg2MCwweDVBLDB4ODIsMHg0MywweEQwLDB4NzcsMHg2NCwweDU0LDB4MUIsMHhDNSwweEFELDB4MzUsMHg1QiwweDMxLDB4MjldLFsweDZELDB4OTYsMHhGRSwweEY3LDB4RDYsMHg2NSwweDkwLDB4QTcsMHg3QSwweDc3LDB4QkIsMHgyMCwweDU2LDB4NjYsMHg3RiwweDdGXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4RjAsMHhGMSwweEYyLDB4RjMsMHhGNSwweEY2LDB4RjcsMHhGOCwweEZBLDB4RkIsMHhGQywweEZELDB4RkUsMHgwMSwweDAwLDB4MDJdLFsweDEyLDB4QTgsMHhDRiwweEEyLDB4M0UsMHhBNywweDY0LDB4RkQsMHg4NywweDYyLDB4MzIsMHhCNCwweEU4LDB4NDIsMHhCQywweDQ0XSxbMHgzMSwweDZGLDB4QjYsMHg4RSwweERCLDB4QTcsMHgzNiwweEM1LDB4M0UsMHg3OCwweDQ3LDB4N0IsMHhGOSwweDEzLDB4NzIsMHg1Q11dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDA0LDB4MDUsMHgwNiwweDA3LDB4MDksMHgwQSwweDBCLDB4MEMsMHgwRSwweDBGLDB4MTAsMHgxMSwweDEzLDB4MTQsMHgxNSwweDE2XSxbMHhCQywweEFGLDB4MzIsMHg0MSwweDVFLDB4ODMsMHgwOCwweEIzLDB4NzIsMHgzRSwweDVGLDB4REQsMHg4NSwweDNDLDB4Q0MsMHg4MF0sWzB4NjksMHgzNiwweEYyLDB4QjksMHgzQSwweEY4LDB4MzksMHg3RiwweEQzLDB4QTcsMHg3MSwweEZDLDB4MDEsMHgxQywweDhDLDB4MzddXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHgyQywweDJELDB4MkUsMHgyRiwweDMxLDB4MzIsMHgzMywweDM0LDB4MzYsMHgzNywweDM4LDB4MzksMHgzQiwweDNDLDB4M0QsMHgzRV0sWzB4ODksMHhBRiwweEFFLDB4NjgsMHg1RCwweDgwLDB4MUEsMHhENywweDQ3LDB4QUMsMHhFOSwweDFGLDB4QzQsMHg5QSwweERELDB4RTBdLFsweEYzLDB4RjksMHgyRiwweDdBLDB4OUMsMHg1OSwweDE3LDB4OUMsMHgxRiwweENDLDB4MkMsMHgyQiwweEEwLDB4QjAsMHg4MiwweENEXV1dO1xuICBcbiAgdmFyIHRlc3R2ZWN0b3JzMTkyID0gW1tbMHgwMCwweDAxLDB4MDIsMHgwMywweDA1LDB4MDYsMHgwNywweDA4LDB4MEEsMHgwQiwweDBDLDB4MEQsMHgwRiwweDEwLDB4MTEsMHgxMiwweDE0LDB4MTUsMHgxNiwweDE3LDB4MTksMHgxQSwweDFCLDB4MUNdLFsweDJELDB4MzMsMHhFRSwweEYyLDB4QzAsMHg0MywweDBBLDB4OEEsMHg5RSwweEJGLDB4NDUsMHhFOCwweDA5LDB4QzQsMHgwQiwweEI2XSxbMHhERiwweEY0LDB4OTQsMHg1RSwweDAzLDB4MzYsMHhERiwweDRDLDB4MUMsMHg1NiwweEJDLDB4NzAsMHgwRSwweEZGLDB4ODMsMHg3Rl1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDFFLDB4MUYsMHgyMCwweDIxLDB4MjMsMHgyNCwweDI1LDB4MjYsMHgyOCwweDI5LDB4MkEsMHgyQiwweDJELDB4MkUsMHgyRiwweDMwLDB4MzIsMHgzMywweDM0LDB4MzUsMHgzNywweDM4LDB4MzksMHgzQV0sWzB4NkEsMHhBMywweDc1LDB4RDEsMHhGQSwweDE1LDB4NUEsMHg2MSwweEZCLDB4NzIsMHgzNSwweDNFLDB4MEEsMHg1QSwweDg3LDB4NTZdLFsweEI2LDB4RkQsMHhERSwweEY0LDB4NzUsMHgyNywweDY1LDB4RTMsMHg0NywweEQ1LDB4RDIsMHhEQywweDE5LDB4NkQsMHgxMiwweDUyXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4M0MsMHgzRCwweDNFLDB4M0YsMHg0MSwweDQyLDB4NDMsMHg0NCwweDQ2LDB4NDcsMHg0OCwweDQ5LDB4NEIsMHg0QywweDRELDB4NEUsMHg1MCwweDUxLDB4NTIsMHg1MywweDU1LDB4NTYsMHg1NywweDU4XSxbMHhCQywweDM3LDB4MzYsMHg1MSwweDhCLDB4OTQsMHg5MCwweERDLDB4QjgsMHhFRCwweDYwLDB4RUIsMHgyNiwweDc1LDB4OEUsMHhENF0sWzB4RDIsMHgzNiwweDg0LDB4RTMsMHhEOSwweDYzLDB4QjMsMHhBRiwweENGLDB4MUEsMHgxMSwweDRBLDB4Q0EsMHg5MCwweENCLDB4RDZdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHg1QSwweDVCLDB4NUMsMHg1RCwweDVGLDB4NjAsMHg2MSwweDYyLDB4NjQsMHg2NSwweDY2LDB4NjcsMHg2OSwweDZBLDB4NkIsMHg2QywweDZFLDB4NkYsMHg3MCwweDcxLDB4NzMsMHg3NCwweDc1LDB4NzZdLFsweEFBLDB4MjEsMHg0NCwweDAyLDB4QjQsMHg2QywweEZGLDB4QjksMHhGNywweDYxLDB4RUMsMHgxMSwweDI2LDB4M0EsMHgzMSwweDFFXSxbMHgzQSwweDdBLDB4QzAsMHgyNywweDc1LDB4M0UsMHgyQSwweDE4LDB4QzIsMHhDRSwweEFCLDB4OUUsMHgxNywweEMxLDB4MUYsMHhEMF1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDc4LDB4NzksMHg3QSwweDdCLDB4N0QsMHg3RSwweDdGLDB4ODAsMHg4MiwweDgzLDB4ODQsMHg4NSwweDg3LDB4ODgsMHg4OSwweDhBLDB4OEMsMHg4RCwweDhFLDB4OEYsMHg5MSwweDkyLDB4OTMsMHg5NF0sWzB4MDIsMHhBRSwweEE4LDB4NkUsMHg1NywweDJFLDB4RUEsMHhCNiwweDZCLDB4MkMsMHgzQSwweEY1LDB4RTksMHhBNCwweDZGLDB4RDZdLFsweDhGLDB4NjcsMHg4NiwweEJELDB4MDAsMHg3NSwweDI4LDB4QkEsMHgyNiwweDYwLDB4M0MsMHgxNiwweDAxLDB4Q0QsMHhEMCwweEQ4XV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4OTYsMHg5NywweDk4LDB4OTksMHg5QiwweDlDLDB4OUQsMHg5RSwweEEwLDB4QTEsMHhBMiwweEEzLDB4QTUsMHhBNiwweEE3LDB4QTgsMHhBQSwweEFCLDB4QUMsMHhBRCwweEFGLDB4QjAsMHhCMSwweEIyXSxbMHhFMiwweEFFLDB4RjYsMHhBQywweEMzLDB4M0IsMHg5NiwweDVDLDB4NEYsMHhBMSwweEY5LDB4MUMsMHg3NSwweEZGLDB4NkYsMHgzNl0sWzB4RDEsMHg3RCwweDA3LDB4M0IsMHgwMSwweEU3LDB4MTUsMHgwMiwweEUyLDB4OEIsMHg0NywweEFCLDB4NTUsMHgxMSwweDY4LDB4QjNdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHhCNCwweEI1LDB4QjYsMHhCNywweEI5LDB4QkEsMHhCQiwweEJDLDB4QkUsMHhCRiwweEMwLDB4QzEsMHhDMywweEM0LDB4QzUsMHhDNiwweEM4LDB4QzksMHhDQSwweENCLDB4Q0QsMHhDRSwweENGLDB4RDBdLFsweDA2LDB4NTksMHhERiwweDQ2LDB4NDIsMHg3MSwweDYyLDB4QjksMHg0MywweDQ4LDB4NjUsMHhERCwweDk0LDB4OTksMHhGOSwweDFEXSxbMHhBNCwweDY5LDB4REEsMHg1MSwweDcxLDB4MTksMHhGQSwweEI5LDB4NTgsMHg3NiwweEY0LDB4MUQsMHgwNiwweEQ0LDB4MEYsMHhGQV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweEQyLDB4RDMsMHhENCwweEQ1LDB4RDcsMHhEOCwweEQ5LDB4REEsMHhEQywweERELDB4REUsMHhERiwweEUxLDB4RTIsMHhFMywweEU0LDB4RTYsMHhFNywweEU4LDB4RTksMHhFQiwweEVDLDB4RUQsMHhFRV0sWzB4NDksMHhBNCwweDQyLDB4MzksMHhDNywweDQ4LDB4RkUsMHhCNCwweDU2LDB4RjUsMHg5QywweDI3LDB4NkEsMHg1NiwweDU4LDB4REZdLFsweDYwLDB4OTEsMHhBQSwweDNCLDB4NjksMHg1QywweDExLDB4RjUsMHhDMCwweEI2LDB4QUQsMHgyNiwweEQzLDB4RDgsMHg2MiwweEZGXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4RjAsMHhGMSwweEYyLDB4RjMsMHhGNSwweEY2LDB4RjcsMHhGOCwweEZBLDB4RkIsMHhGQywweEZELDB4RkUsMHgwMSwweDAwLDB4MDIsMHgwNCwweDA1LDB4MDYsMHgwNywweDA5LDB4MEEsMHgwQiwweDBDXSxbMHg2NiwweDIwLDB4OEYsMHg2RSwweDlELDB4MDQsMHg1MiwweDVCLDB4REUsMHhEQiwweDI3LDB4MzMsMHhCNiwweEE2LDB4QkUsMHgzN10sWzB4NzAsMHhGOSwweEU2LDB4N0YsMHg5RiwweDhELDB4RjEsMHgyOSwweDQxLDB4MzEsMHg2NiwweDJELDB4QzYsMHhFNiwweDkzLDB4NjRdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHgwRSwweDBGLDB4MTAsMHgxMSwweDEzLDB4MTQsMHgxNSwweDE2LDB4MTgsMHgxOSwweDFBLDB4MUIsMHgxRCwweDFFLDB4MUYsMHgyMCwweDIyLDB4MjMsMHgyNCwweDI1LDB4MjcsMHgyOCwweDI5LDB4MkFdLFsweDMzLDB4OTMsMHhGOCwweERGLDB4QzcsMHgyOSwweEM5LDB4N0YsMHg1NCwweDgwLDB4QjksMHg1MCwweEJDLDB4OTYsMHg2NiwweEIwXSxbMHhEMSwweDU0LDB4REMsMHhBRiwweEFELDB4OEIsMHgyMCwweDdGLDB4QTUsMHhDQiwweEM5LDB4NUUsMHg5OSwweDk2LDB4QjUsMHg1OV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDJDLDB4MkQsMHgyRSwweDJGLDB4MzEsMHgzMiwweDMzLDB4MzQsMHgzNiwweDM3LDB4MzgsMHgzOSwweDNCLDB4M0MsMHgzRCwweDNFLDB4NDAsMHg0MSwweDQyLDB4NDMsMHg0NSwweDQ2LDB4NDcsMHg0OF0sWzB4NjAsMHg2OCwweDM0LDB4QzgsMHhDRSwweDA2LDB4M0YsMHgzMiwweDM0LDB4Q0YsMHgxMSwweDQ1LDB4MzIsMHg1RCwweEJELDB4NzFdLFsweDQ5LDB4MzQsMHhENSwweDQxLDB4RTgsMHhCNCwweDZGLDB4QTMsMHgzOSwweEM4LDB4MDUsMHhBNywweEFFLDB4QjksMHhFNSwweERBXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4NEEsMHg0QiwweDRDLDB4NEQsMHg0RiwweDUwLDB4NTEsMHg1MiwweDU0LDB4NTUsMHg1NiwweDU3LDB4NTksMHg1QSwweDVCLDB4NUMsMHg1RSwweDVGLDB4NjAsMHg2MSwweDYzLDB4NjQsMHg2NSwweDY2XSxbMHhGRSwweEMxLDB4QzAsMHg0RiwweDUyLDB4OUIsMHhCRCwweDE3LDB4RDgsMHhDRSwweENGLDB4Q0MsMHg0NywweDE4LDB4QjEsMHg3Rl0sWzB4NjIsMHg1NiwweDRDLDB4NzMsMHg4RiwweDNFLDB4RkUsMHgxOCwweDZFLDB4MUEsMHgxMiwweDdBLDB4MEMsMHg0RCwweDNDLDB4NjFdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHg2OCwweDY5LDB4NkEsMHg2QiwweDZELDB4NkUsMHg2RiwweDcwLDB4NzIsMHg3MywweDc0LDB4NzUsMHg3NywweDc4LDB4NzksMHg3QSwweDdDLDB4N0QsMHg3RSwweDdGLDB4ODEsMHg4MiwweDgzLDB4ODRdLFsweDMyLDB4REYsMHg5OSwweEI0LDB4MzEsMHhFRCwweDVELDB4QzUsMHhBQywweEY4LDB4Q0EsMHhGNiwweERDLDB4NkMsMHhFNCwweDc1XSxbMHgwNywweDgwLDB4NUEsMHhBMCwweDQzLDB4OTgsMHg2RSwweEIyLDB4MzYsMHg5MywweEUyLDB4M0IsMHhFRiwweDhGLDB4MzQsMHgzOF1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDg2LDB4ODcsMHg4OCwweDg5LDB4OEIsMHg4QywweDhELDB4OEUsMHg5MCwweDkxLDB4OTIsMHg5MywweDk1LDB4OTYsMHg5NywweDk4LDB4OUEsMHg5QiwweDlDLDB4OUQsMHg5RiwweEEwLDB4QTEsMHhBMl0sWzB4N0YsMHhEQywweDJCLDB4NzQsMHg2RiwweDNGLDB4NjYsMHg1MiwweDk2LDB4OTQsMHgzQiwweDgzLDB4NzEsMHgwRCwweDFGLDB4ODJdLFsweERGLDB4MEIsMHg0OSwweDMxLDB4MDMsMHg4QiwweEFELDB4RTgsMHg0OCwweERFLDB4RTMsMHhCNCwweEI4LDB4NUEsMHhBNCwweDRCXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4QTQsMHhBNSwweEE2LDB4QTcsMHhBOSwweEFBLDB4QUIsMHhBQywweEFFLDB4QUYsMHhCMCwweEIxLDB4QjMsMHhCNCwweEI1LDB4QjYsMHhCOCwweEI5LDB4QkEsMHhCQiwweEJELDB4QkUsMHhCRiwweEMwXSxbMHg4RiwweEJBLDB4MTUsMHgxMCwweEEzLDB4QzUsMHhCOCwweDdFLDB4MkUsMHhBQSwweDNGLDB4N0EsMHg5MSwweDQ1LDB4NUMsMHhBMl0sWzB4NTksMHgyRCwweDVGLDB4REUsMHhENywweDY1LDB4ODIsMHhFNCwweDE0LDB4M0MsMHg2NSwweDA5LDB4OTMsMHgwOSwweDQ3LDB4N0NdXV07XG4gIFxuICB2YXIgdGVzdHZlY3RvcnMyNTYgPSBbW1sweDAwLDB4MDEsMHgwMiwweDAzLDB4MDUsMHgwNiwweDA3LDB4MDgsMHgwQSwweDBCLDB4MEMsMHgwRCwweDBGLDB4MTAsMHgxMSwweDEyLDB4MTQsMHgxNSwweDE2LDB4MTcsMHgxOSwweDFBLDB4MUIsMHgxQywweDFFLDB4MUYsMHgyMCwweDIxLDB4MjMsMHgyNCwweDI1LDB4MjZdLFsweDgzLDB4NEUsMHhBRCwweEZDLDB4Q0EsMHhDNywweEUxLDB4QjMsMHgwNiwweDY0LDB4QjEsMHhBQiwweEE0LDB4NDgsMHgxNSwweEFCXSxbMHgxOSwweDQ2LDB4REEsMHhCRiwweDZBLDB4MDMsMHhBMiwweEEyLDB4QzMsMHhEMCwweEIwLDB4NTAsMHg4MCwweEFFLDB4RDYsMHhGQ11dLFxuICAgICAgICAgICAgICBbWzB4MjgsMHgyOSwweDJBLDB4MkIsMHgyRCwweDJFLDB4MkYsMHgzMCwweDMyLDB4MzMsMHgzNCwweDM1LDB4MzcsMHgzOCwweDM5LDB4M0EsMHgzQywweDNELDB4M0UsMHgzRiwweDQxLDB4NDIsMHg0MywweDQ0LDB4NDYsMHg0NywweDQ4LDB4NDksMHg0QiwweDRDLDB4NEQsMHg0RV0sWzB4RDksMHhEQywweDRELDB4QkEsMHgzMCwweDIxLDB4QjAsMHg1RCwweDY3LDB4QzAsMHg1MSwweDhGLDB4NzIsMHhCNiwweDJCLDB4RjFdLFsweDVFLDB4RDMsMHgwMSwweEQ3LDB4NDcsMHhEMywweENDLDB4NzEsMHg1NCwweDQ1LDB4RUIsMHhERSwweEM2LDB4MkYsMHgyRiwweEI0XV0sXG4gICAgICAgICAgICAgIFtbMHg1MCwweDUxLDB4NTIsMHg1MywweDU1LDB4NTYsMHg1NywweDU4LDB4NUEsMHg1QiwweDVDLDB4NUQsMHg1RiwweDYwLDB4NjEsMHg2MiwweDY0LDB4NjUsMHg2NiwweDY3LDB4NjksMHg2QSwweDZCLDB4NkMsMHg2RSwweDZGLDB4NzAsMHg3MSwweDczLDB4NzQsMHg3NSwweDc2XSxbMHhBMiwweDkxLDB4RDgsMHg2MywweDAxLDB4QTQsMHhBNywweDM5LDB4RjcsMHgzOSwweDIxLDB4NzMsMHhBQSwweDNDLDB4NjAsMHg0Q10sWzB4NjUsMHg4NSwweEM4LDB4RjQsMHgzRCwweDEzLDB4QTYsMHhCRSwweEFCLDB4NjQsMHgxOSwweEZDLDB4NTksMHgzNSwweEI5LDB4RDBdXSxcbiAgICAgICAgICAgICAgW1sweDc4LDB4NzksMHg3QSwweDdCLDB4N0QsMHg3RSwweDdGLDB4ODAsMHg4MiwweDgzLDB4ODQsMHg4NSwweDg3LDB4ODgsMHg4OSwweDhBLDB4OEMsMHg4RCwweDhFLDB4OEYsMHg5MSwweDkyLDB4OTMsMHg5NCwweDk2LDB4OTcsMHg5OCwweDk5LDB4OUIsMHg5QywweDlELDB4OUVdLFsweDQyLDB4NjQsMHhCMiwweDY5LDB4NjQsMHg5OCwweERFLDB4NEQsMHhGNywweDk3LDB4ODgsMHhBOSwweEY4LDB4M0UsMHg5MywweDkwXSxbMHgyQSwweDVCLDB4NTYsMHhBNSwweDk2LDB4NjgsMHgwRiwweENDLDB4MEUsMHgwNSwweEY1LDB4RTAsMHhGMSwweDUxLDB4RUMsMHhBRV1dLFxuICAgICAgICAgICAgICBbWzB4QTAsMHhBMSwweEEyLDB4QTMsMHhBNSwweEE2LDB4QTcsMHhBOCwweEFBLDB4QUIsMHhBQywweEFELDB4QUYsMHhCMCwweEIxLDB4QjIsMHhCNCwweEI1LDB4QjYsMHhCNywweEI5LDB4QkEsMHhCQiwweEJDLDB4QkUsMHhCRiwweEMwLDB4QzEsMHhDMywweEM0LDB4QzUsMHhDNl0sWzB4RUUsMHg5OSwweDMyLDB4QjMsMHg3MiwweDE4LDB4MDQsMHhENSwweEE4LDB4M0UsMHhGNSwweDk0LDB4OTIsMHg0NSwweEI2LDB4RjZdLFsweEY1LDB4RDYsMHhGRiwweDQxLDB4NEYsMHhEMiwweEM2LDB4MTgsMHgxNCwweDk0LDB4RDIsMHgwQywweDM3LDB4RjIsMHhCOCwweEM0XV0sXG4gICAgICAgICAgICAgIFtbMHhDOCwweEM5LDB4Q0EsMHhDQiwweENELDB4Q0UsMHhDRiwweEQwLDB4RDIsMHhEMywweEQ0LDB4RDUsMHhENywweEQ4LDB4RDksMHhEQSwweERDLDB4REQsMHhERSwweERGLDB4RTEsMHhFMiwweEUzLDB4RTQsMHhFNiwweEU3LDB4RTgsMHhFOSwweEVCLDB4RUMsMHhFRCwweEVFXSxbMHhFNiwweDI0LDB4OEYsMHg1NSwweEM1LDB4RkQsMHhDQiwweENBLDB4OUMsMHhCQiwweEIwLDB4MUMsMHg4OCwweEEyLDB4RUEsMHg3N10sWzB4ODUsMHgzOSwweDlDLDB4MDEsMHhGNSwweDlGLDB4RkYsMHhCNSwweDIwLDB4NEYsMHgxOSwweEY4LDB4NDgsMHgyRiwweDAwLDB4QjhdXSxcbiAgICAgICAgICAgICAgW1sweEYwLDB4RjEsMHhGMiwweEYzLDB4RjUsMHhGNiwweEY3LDB4RjgsMHhGQSwweEZCLDB4RkMsMHhGRCwweEZFLDB4MDEsMHgwMCwweDAyLDB4MDQsMHgwNSwweDA2LDB4MDcsMHgwOSwweDBBLDB4MEIsMHgwQywweDBFLDB4MEYsMHgxMCwweDExLDB4MTMsMHgxNCwweDE1LDB4MTZdLFsweEI4LDB4MzUsMHg4RSwweDQxLDB4QjksMHhERiwweEY2LDB4NUYsMHhENCwweDYxLDB4RDUsMHg1QSwweDk5LDB4MjYsMHg2MiwweDQ3XSxbMHg5MiwweDA5LDB4N0IsMHg0QywweDg4LDB4QTAsMHg0MSwweERELDB4RjksMHg4MSwweDQ0LDB4QkMsMHg4RCwweDIyLDB4RTgsMHhFN11dLFxuICAgICAgICAgICAgICBbWzB4MTgsMHgxOSwweDFBLDB4MUIsMHgxRCwweDFFLDB4MUYsMHgyMCwweDIyLDB4MjMsMHgyNCwweDI1LDB4MjcsMHgyOCwweDI5LDB4MkEsMHgyQywweDJELDB4MkUsMHgyRiwweDMxLDB4MzIsMHgzMywweDM0LDB4MzYsMHgzNywweDM4LDB4MzksMHgzQiwweDNDLDB4M0QsMHgzRV0sWzB4RjAsMHhFMiwweEQ3LDB4MjIsMHg2MCwweEFGLDB4NTgsMHhFMiwweDFFLDB4MDEsMHg1QSwweEIzLDB4QTQsMHhDMCwweEQ5LDB4MDZdLFsweDg5LDB4QkQsMHg1QiwweDczLDB4QjMsMHg1NiwweEFCLDB4NDEsMHgyQSwweEVGLDB4OUYsMHg3NiwweENFLDB4QTIsMHhENiwweDVDXV0sXG4gICAgICAgICAgICAgIFtbMHg0MCwweDQxLDB4NDIsMHg0MywweDQ1LDB4NDYsMHg0NywweDQ4LDB4NEEsMHg0QiwweDRDLDB4NEQsMHg0RiwweDUwLDB4NTEsMHg1MiwweDU0LDB4NTUsMHg1NiwweDU3LDB4NTksMHg1QSwweDVCLDB4NUMsMHg1RSwweDVGLDB4NjAsMHg2MSwweDYzLDB4NjQsMHg2NSwweDY2XSxbMHg0NywweDVCLDB4OEIsMHg4MiwweDNDLDB4RTgsMHg4OSwweDNELDB4QjMsMHhDNCwweDRBLDB4OUYsMHgyQSwweDM3LDB4OUYsMHhGN10sWzB4MjUsMHgzNiwweDk2LDB4OTAsMHg5MywweEM1LDB4NUYsMHhGOSwweDQ1LDB4NDYsMHg5MiwweEYyLDB4RkEsMHhDMiwweEY1LDB4MzBdXSxcbiAgICAgICAgICAgICAgW1sweDY4LDB4NjksMHg2QSwweDZCLDB4NkQsMHg2RSwweDZGLDB4NzAsMHg3MiwweDczLDB4NzQsMHg3NSwweDc3LDB4NzgsMHg3OSwweDdBLDB4N0MsMHg3RCwweDdFLDB4N0YsMHg4MSwweDgyLDB4ODMsMHg4NCwweDg2LDB4ODcsMHg4OCwweDg5LDB4OEIsMHg4QywweDhELDB4OEVdLFsweDY4LDB4OEYsMHg1MiwweDgxLDB4OTQsMHg1OCwweDEyLDB4ODYsMHgyRiwweDVGLDB4MzAsMHg3NiwweENGLDB4ODAsMHg0MSwweDJGXSxbMHgwNywweEZDLDB4NzYsMHhBOCwweDcyLDB4ODQsMHgzRiwweDNGLDB4NkUsMHgwMCwweDgxLDB4RUUsMHg5MywweDk2LDB4RDYsMHgzN11dLFxuICAgICAgICAgICAgICBbWzB4OTAsMHg5MSwweDkyLDB4OTMsMHg5NSwweDk2LDB4OTcsMHg5OCwweDlBLDB4OUIsMHg5QywweDlELDB4OUYsMHhBMCwweEExLDB4QTIsMHhBNCwweEE1LDB4QTYsMHhBNywweEE5LDB4QUEsMHhBQiwweEFDLDB4QUUsMHhBRiwweEIwLDB4QjEsMHhCMywweEI0LDB4QjUsMHhCNl0sWzB4MDgsMHhEMSwweEQyLDB4QkMsMHg3NSwweDBBLDB4RjUsMHg1MywweDM2LDB4NUQsMHgzNSwweEU3LDB4NUEsMHhGQSwweENFLDB4QUFdLFsweEUzLDB4OEIsMHhBOCwweEVDLDB4MkEsMHhBNywweDQxLDB4MzUsMHg4RCwweENDLDB4OTMsMHhFOCwweEYxLDB4NDEsMHhDNCwweDkxXV0sXG4gICAgICAgICAgICAgIFtbMHhCOCwweEI5LDB4QkEsMHhCQiwweEJELDB4QkUsMHhCRiwweEMwLDB4QzIsMHhDMywweEM0LDB4QzUsMHhDNywweEM4LDB4QzksMHhDQSwweENDLDB4Q0QsMHhDRSwweENGLDB4RDEsMHhEMiwweEQzLDB4RDQsMHhENiwweEQ3LDB4RDgsMHhEOSwweERCLDB4REMsMHhERCwweERFXSxbMHg4NywweDA3LDB4MTIsMHgxRiwweDQ3LDB4Q0MsMHgzRSwweEZDLDB4RUMsMHhBNSwweEY5LDB4QTgsMHg0NywweDQ5LDB4NTAsMHhBMV0sWzB4RDAsMHgyOCwweEVFLDB4MjMsMHhFNCwweEE4LDB4OTAsMHg3NSwweEQwLDB4QjAsMHgzRSwweDg2LDB4OEQsMHg3RCwweDNBLDB4NDJdXSxcbiAgICAgICAgICAgICAgW1sweEUwLDB4RTEsMHhFMiwweEUzLDB4RTUsMHhFNiwweEU3LDB4RTgsMHhFQSwweEVCLDB4RUMsMHhFRCwweEVGLDB4RjAsMHhGMSwweEYyLDB4RjQsMHhGNSwweEY2LDB4RjcsMHhGOSwweEZBLDB4RkIsMHhGQywweEZFLDB4RkUsMHgwMSwweDAxLDB4MDMsMHgwNCwweDA1LDB4MDZdLFsweEU1LDB4MUEsMHhBMCwweEIxLDB4MzUsMHhEQiwweEE1LDB4NjYsMHg5MywweDlDLDB4M0IsMHg2MywweDU5LDB4QTksMHg4MCwweEM1XSxbMHg4QywweEQ5LDB4NDIsMHgzRCwweEZDLDB4NDUsMHg5RSwweDU0LDB4NzEsMHg1NSwweEM1LDB4RDEsMHhENSwweDIyLDB4RTUsMHg0MF1dLFxuICAgICAgICAgICAgICBbWzB4MDgsMHgwOSwweDBBLDB4MEIsMHgwRCwweDBFLDB4MEYsMHgxMCwweDEyLDB4MTMsMHgxNCwweDE1LDB4MTcsMHgxOCwweDE5LDB4MUEsMHgxQywweDFELDB4MUUsMHgxRiwweDIxLDB4MjIsMHgyMywweDI0LDB4MjYsMHgyNywweDI4LDB4MjksMHgyQiwweDJDLDB4MkQsMHgyRV0sWzB4MDYsMHg5QSwweDAwLDB4N0YsMHhDNywweDZBLDB4NDUsMHg5RiwweDk4LDB4QkEsMHhGOSwweDE3LDB4RkUsMHhERiwweDk1LDB4MjFdLFsweDA4LDB4MEUsMHg5NSwweDE3LDB4RUIsMHgxNiwweDc3LDB4NzEsMHg5QSwweENGLDB4NzIsMHg4MCwweDg2LDB4MDQsMHgwQSwweEUzXV0sXG4gICAgICAgICAgICAgIFtbMHgzMCwweDMxLDB4MzIsMHgzMywweDM1LDB4MzYsMHgzNywweDM4LDB4M0EsMHgzQiwweDNDLDB4M0QsMHgzRiwweDQwLDB4NDEsMHg0MiwweDQ0LDB4NDUsMHg0NiwweDQ3LDB4NDksMHg0QSwweDRCLDB4NEMsMHg0RSwweDRGLDB4NTAsMHg1MSwweDUzLDB4NTQsMHg1NSwweDU2XSxbMHg3MiwweDYxLDB4NjUsMHhDMSwweDcyLDB4M0YsMHhCQywweEY2LDB4QzAsMHgyNiwweEQ3LDB4RDAsMHgwQiwweDA5LDB4MTAsMHgyN10sWzB4N0MsMHgxNywweDAwLDB4MjEsMHgxQSwweDM5LDB4OTEsMHhGQywweDBFLDB4Q0QsMHhFRCwweDBBLDB4QjMsMHhFNSwweDc2LDB4QjBdXV07XG5cbiAgdmFyIHJlcyA9IHRydWU7XG4gIHZhciBqID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXN0dmVjdG9yczEyOC5sZW5ndGg7IGkrKykge1xuICAgIHZhciByZXMyID0gdGVzdF9hZXModGVzdHZlY3RvcnMxMjhbaV1bMV0sdGVzdHZlY3RvcnMxMjhbaV1bMF0sdGVzdHZlY3RvcnMxMjhbaV1bMl0pO1xuICAgIHJlcyAmPSByZXMyO1xuICAgIGlmICghcmVzMikge1xuICAgICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyAxMjggYml0IGtleSB2ZWN0b3Igd2l0aCBibG9jayBcIitcbiAgICAgICAgdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczEyOFtpXVsxXSkrXG4gICAgICAgIFwiIGFuZCBrZXkgXCIrdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczEyOFtpXVswXSkrXG4gICAgICAgIFwiIHNob3VsZCBiZSBcIit1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzMTI4W2ldWzJdKSxcbiAgICAgICAgZmFsc2UpO1xuICAgICAgaisrO1xuICAgIH1cbiAgfVxuICBpZiAocmVzKSB7XG4gICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiMTI4IGJpdCBrZXkgdGVzdCB2ZWN0b3JzIGNvbXBsZXRlZC5cIix0cnVlKVxuICAgIGorKztcbiAgfVxuICBcbiAgcmVzID0gdHJ1ZTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXN0dmVjdG9yczE5Mi5sZW5ndGg7IGkrKykge1xuICAgIHZhciByZXMyID0gdGVzdF9hZXModGVzdHZlY3RvcnMxOTJbaV1bMV0sdGVzdHZlY3RvcnMxOTJbaV1bMF0sdGVzdHZlY3RvcnMxOTJbaV1bMl0pO1xuICAgIHJlcyAmPSByZXMyO1xuICAgIGlmICghcmVzMikge1xuICAgICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyAxOTIgYml0IGtleSB2ZWN0b3Igd2l0aCBibG9jayBcIitcbiAgICAgICAgdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczE5MltpXVsxXSkrXG4gICAgICAgIFwiIGFuZCBrZXkgXCIrdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczE5MltpXVswXSkrXG4gICAgICAgIFwiIHNob3VsZCBiZSBcIit1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzMTkyW2ldWzJdKSxcbiAgICAgICAgZmFsc2UpO1xuICAgICAgaisrO1xuICAgIH1cbiAgfVxuICBpZiAocmVzKSB7XG4gICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiMTkyIGJpdCBrZXkgdGVzdCB2ZWN0b3JzIGNvbXBsZXRlZC5cIix0cnVlKVxuICAgIGorKztcbiAgfVxuXG4gIHJlcyA9IHRydWU7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGVzdHZlY3RvcnMyNTYubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcmVzMiA9IHRlc3RfYWVzKHRlc3R2ZWN0b3JzMjU2W2ldWzFdLHRlc3R2ZWN0b3JzMjU2W2ldWzBdLHRlc3R2ZWN0b3JzMjU2W2ldWzJdKTtcbiAgICByZXMgJj0gcmVzMjtcbiAgICBpZiAoIXJlczIpIHtcbiAgICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3RpbmcgMjU2IGJpdCBrZXkgdmVjdG9yIHdpdGggYmxvY2sgXCIrXG4gICAgICAgIHV0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnMyNTZbaV1bMV0pK1xuICAgICAgICBcIiBhbmQga2V5IFwiK3V0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnMyNTZbaV1bMF0pK1xuICAgICAgICBcIiBzaG91bGQgYmUgXCIrdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczI1NltpXVsyXSksXG4gICAgICAgIGZhbHNlKTtcbiAgICAgIGorKztcbiAgICB9XG4gIH1cbiAgaWYgKHJlcykge1xuICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIjI1NiBiaXQga2V5IHRlc3QgdmVjdG9ycyBjb21wbGV0ZWQuXCIsIHRydWUpXG4gICAgaisrO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn0pO1xuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi8uLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJCbG93ZmlzaCBjaXBoZXIgdGVzdCB3aXRoIHRlc3QgdmVjdG9ycyBmcm9tIGh0dHA6Ly93d3cuc2NobmVpZXIuY29tL2NvZGUvdmVjdG9ycy50eHRcIiwgZnVuY3Rpb24oKSB7XG4gIHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vLi4vJyksXG4gICAgdXRpbCA9IG9wZW5wZ3AudXRpbCxcbiAgICBCRmVuY3J5cHQgPSBvcGVucGdwLmNpcGhlci5ibG93ZmlzaDtcblxuICB2YXIgcmVzdWx0ID0gW107XG4gIGZ1bmN0aW9uIHRlc3RfYmYoaW5wdXQsIGtleSwgb3V0cHV0KSB7XG4gICAgdmFyIGJsb3dmaXNoID0gbmV3IG9wZW5wZ3AuY2lwaGVyLmJsb3dmaXNoKHV0aWwuYmluMnN0cihrZXkpKTtcbiAgICB2YXIgcmVzdWx0ID0gdXRpbC5iaW4yc3RyKGJsb3dmaXNoLmVuY3J5cHQoaW5wdXQpKTtcblxuICAgIHJldHVybiAodXRpbC5oZXhzdHJkdW1wKHJlc3VsdCkgPT0gdXRpbC5oZXhzdHJkdW1wKHV0aWwuYmluMnN0cihvdXRwdXQpKSk7XG4gIH1cbiAgdmFyIHRlc3R2ZWN0b3JzID0gW1tbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg0RSwweEY5LDB4OTcsMHg0NSwweDYxLDB4OTgsMHhERCwweDc4XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRl0sWzB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRl0sWzB4NTEsMHg4NiwweDZGLDB4RDUsMHhCOCwweDVFLDB4Q0IsMHg4QV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDMwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDEwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDFdLFsweDdELDB4ODUsMHg2RiwweDlBLDB4NjEsMHgzMCwweDYzLDB4RjJdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExXSxbMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExXSxbMHgyNCwweDY2LDB4REQsMHg4NywweDhCLDB4OTYsMHgzQywweDlEXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDEsMHgyMywweDQ1LDB4NjcsMHg4OSwweEFCLDB4Q0QsMHhFRl0sWzB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMV0sWzB4NjEsMHhGOSwweEMzLDB4ODAsMHgyMiwweDgxLDB4QjAsMHg5Nl1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTFdLFsweDAxLDB4MjMsMHg0NSwweDY3LDB4ODksMHhBQiwweENELDB4RUZdLFsweDdELDB4MEMsMHhDNiwweDMwLDB4QUYsMHhEQSwweDFFLDB4QzddXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg0RSwweEY5LDB4OTcsMHg0NSwweDYxLDB4OTgsMHhERCwweDc4XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4RkUsMHhEQywweEJBLDB4OTgsMHg3NiwweDU0LDB4MzIsMHgxMF0sWzB4MDEsMHgyMywweDQ1LDB4NjcsMHg4OSwweEFCLDB4Q0QsMHhFRl0sWzB4MEEsMHhDRSwweEFCLDB4MEYsMHhDNiwweEEwLDB4QTIsMHg4RF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDdDLDB4QTEsMHgxMCwweDQ1LDB4NEEsMHgxQSwweDZFLDB4NTddLFsweDAxLDB4QTEsMHhENiwweEQwLDB4MzksMHg3NywweDY3LDB4NDJdLFsweDU5LDB4QzYsMHg4MiwweDQ1LDB4RUIsMHgwNSwweDI4LDB4MkJdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMSwweDMxLDB4RDksMHg2MSwweDlELDB4QzEsMHgzNywweDZFXSxbMHg1QywweEQ1LDB4NEMsMHhBOCwweDNELDB4RUYsMHg1NywweERBXSxbMHhCMSwweEI4LDB4Q0MsMHgwQiwweDI1LDB4MEYsMHgwOSwweEEwXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDcsMHhBMSwweDEzLDB4M0UsMHg0QSwweDBCLDB4MjYsMHg4Nl0sWzB4MDIsMHg0OCwweEQ0LDB4MzgsMHgwNiwweEY2LDB4NzEsMHg3Ml0sWzB4MTcsMHgzMCwweEU1LDB4NzcsMHg4QiwweEVBLDB4MUQsMHhBNF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDM4LDB4NDksMHg2NywweDRDLDB4MjYsMHgwMiwweDMxLDB4OUVdLFsweDUxLDB4NDUsMHg0QiwweDU4LDB4MkQsMHhERiwweDQ0LDB4MEFdLFsweEEyLDB4NUUsMHg3OCwweDU2LDB4Q0YsMHgyNiwweDUxLDB4RUJdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwNCwweEI5LDB4MTUsMHhCQSwweDQzLDB4RkUsMHhCNSwweEI2XSxbMHg0MiwweEZELDB4NDQsMHgzMCwweDU5LDB4NTcsMHg3RiwweEEyXSxbMHgzNSwweDM4LDB4ODIsMHhCMSwweDA5LDB4Q0UsMHg4RiwweDFBXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDEsMHgxMywweEI5LDB4NzAsMHhGRCwweDM0LDB4RjIsMHhDRV0sWzB4MDUsMHg5QiwweDVFLDB4MDgsMHg1MSwweENGLDB4MTQsMHgzQV0sWzB4NDgsMHhGNCwweEQwLDB4ODgsMHg0QywweDM3LDB4OTksMHgxOF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAxLDB4NzAsMHhGMSwweDc1LDB4NDYsMHg4RiwweEI1LDB4RTZdLFsweDA3LDB4NTYsMHhEOCwweEUwLDB4NzcsMHg0NywweDYxLDB4RDJdLFsweDQzLDB4MjEsMHg5MywweEI3LDB4ODksMHg1MSwweEZDLDB4OThdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHg0MywweDI5LDB4N0YsMHhBRCwweDM4LDB4RTMsMHg3MywweEZFXSxbMHg3NiwweDI1LDB4MTQsMHhCOCwweDI5LDB4QkYsMHg0OCwweDZBXSxbMHgxMywweEYwLDB4NDEsMHg1NCwweEQ2LDB4OUQsMHgxQSwweEU1XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDcsMHhBNywweDEzLDB4NzAsMHg0NSwweERBLDB4MkEsMHgxNl0sWzB4M0IsMHhERCwweDExLDB4OTAsMHg0OSwweDM3LDB4MjgsMHgwMl0sWzB4MkUsMHhFRCwweERBLDB4OTMsMHhGRiwweEQzLDB4OUMsMHg3OV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDA0LDB4NjgsMHg5MSwweDA0LDB4QzIsMHhGRCwweDNCLDB4MkZdLFsweDI2LDB4OTUsMHg1RiwweDY4LDB4MzUsMHhBRiwweDYwLDB4OUFdLFsweEQ4LDB4ODcsMHhFMCwweDM5LDB4M0MsMHgyRCwweEE2LDB4RTNdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgzNywweEQwLDB4NkIsMHhCNSwweDE2LDB4Q0IsMHg3NSwweDQ2XSxbMHgxNiwweDRELDB4NUUsMHg0MCwweDRGLDB4MjcsMHg1MiwweDMyXSxbMHg1RiwweDk5LDB4RDAsMHg0RiwweDVCLDB4MTYsMHgzOSwweDY5XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MUYsMHgwOCwweDI2LDB4MEQsMHgxQSwweEMyLDB4NDYsMHg1RV0sWzB4NkIsMHgwNSwweDZFLDB4MTgsMHg3NSwweDlGLDB4NUMsMHhDQV0sWzB4NEEsMHgwNSwweDdBLDB4M0IsMHgyNCwweEQzLDB4OTcsMHg3Ql1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDU4LDB4NDAsMHgyMywweDY0LDB4MUEsMHhCQSwweDYxLDB4NzZdLFsweDAwLDB4NEIsMHhENiwweEVGLDB4MDksMHgxNywweDYwLDB4NjJdLFsweDQ1LDB4MjAsMHgzMSwweEMxLDB4RTQsMHhGQSwweERBLDB4OEVdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMiwweDU4LDB4MTYsMHgxNiwweDQ2LDB4MjksMHhCMCwweDA3XSxbMHg0OCwweDBELDB4MzksMHgwMCwweDZFLDB4RTcsMHg2MiwweEYyXSxbMHg3NSwweDU1LDB4QUUsMHgzOSwweEY1LDB4OUIsMHg4NywweEJEXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4NDksMHg3OSwweDNFLDB4QkMsMHg3OSwweEIzLDB4MjUsMHg4Rl0sWzB4NDMsMHg3NSwweDQwLDB4QzgsMHg2OSwweDhGLDB4M0MsMHhGQV0sWzB4NTMsMHhDNSwweDVGLDB4OUMsMHhCNCwweDlGLDB4QzAsMHgxOV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDRGLDB4QjAsMHg1RSwweDE1LDB4MTUsMHhBQiwweDczLDB4QTddLFsweDA3LDB4MkQsMHg0MywweEEwLDB4NzcsMHgwNywweDUyLDB4OTJdLFsweDdBLDB4OEUsMHg3QiwweEZBLDB4OTMsMHg3RSwweDg5LDB4QTNdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHg0OSwweEU5LDB4NUQsMHg2RCwweDRDLDB4QTIsMHgyOSwweEJGXSxbMHgwMiwweEZFLDB4NTUsMHg3NywweDgxLDB4MTcsMHhGMSwweDJBXSxbMHhDRiwweDlDLDB4NUQsMHg3QSwweDQ5LDB4ODYsMHhBRCwweEI1XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDEsMHg4MywweDEwLDB4REMsMHg0MCwweDlCLDB4MjYsMHhENl0sWzB4MUQsMHg5RCwweDVDLDB4NTAsMHgxOCwweEY3LDB4MjgsMHhDMl0sWzB4RDEsMHhBQiwweEIyLDB4OTAsMHg2NSwweDhCLDB4QzcsMHg3OF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDFDLDB4NTgsMHg3RiwweDFDLDB4MTMsMHg5MiwweDRGLDB4RUZdLFsweDMwLDB4NTUsMHgzMiwweDI4LDB4NkQsMHg2RiwweDI5LDB4NUFdLFsweDU1LDB4Q0IsMHgzNywweDc0LDB4RDEsMHgzRSwweEYyLDB4MDFdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMSwweDAxLDB4MDEsMHgwMSwweDAxLDB4MDEsMHgwMSwweDAxXSxbMHgwMSwweDIzLDB4NDUsMHg2NywweDg5LDB4QUIsMHhDRCwweEVGXSxbMHhGQSwweDM0LDB4RUMsMHg0OCwweDQ3LDB4QjIsMHg2OCwweEIyXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MUYsMHgxRiwweDFGLDB4MUYsMHgwRSwweDBFLDB4MEUsMHgwRV0sWzB4MDEsMHgyMywweDQ1LDB4NjcsMHg4OSwweEFCLDB4Q0QsMHhFRl0sWzB4QTcsMHg5MCwweDc5LDB4NTEsMHgwOCwweEVBLDB4M0MsMHhBRV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweEUwLDB4RkUsMHhFMCwweEZFLDB4RjEsMHhGRSwweEYxLDB4RkVdLFsweDAxLDB4MjMsMHg0NSwweDY3LDB4ODksMHhBQiwweENELDB4RUZdLFsweEMzLDB4OUUsMHgwNywweDJELDB4OUYsMHhBQywweDYzLDB4MURdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGXSxbMHgwMSwweDQ5LDB4MzMsMHhFMCwweENELDB4QUYsMHhGNiwweEU0XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRl0sWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RjIsMHgxRSwweDlBLDB4NzcsMHhCNywweDFDLDB4NDksMHhCQ11dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAxLDB4MjMsMHg0NSwweDY3LDB4ODksMHhBQiwweENELDB4RUZdLFsweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDI0LDB4NTksMHg0NiwweDg4LDB4NTcsMHg1NCwweDM2LDB4OUFdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHhGRSwweERDLDB4QkEsMHg5OCwweDc2LDB4NTQsMHgzMiwweDEwXSxbMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGXSxbMHg2QiwweDVDLDB4NUEsMHg5QywweDVELDB4OUUsMHgwQSwweDVBXV1dO1xuXG4gIHZhciByZXMgPSB0cnVlO1xuICB2YXIgaiA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGVzdHZlY3RvcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcmVzMiA9IHRlc3RfYmYodGVzdHZlY3RvcnNbaV1bMV0sdGVzdHZlY3RvcnNbaV1bMF0sdGVzdHZlY3RvcnNbaV1bMl0pO1xuICAgIHJlcyAmPSByZXMyO1xuICAgIGlmICghcmVzMikge1xuICAgICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyB2ZWN0b3IgXCIraStcIiB3aXRoIGJsb2NrIFwiK1xuICAgICAgICB1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzW2ldWzBdKStcbiAgICAgICAgXCIgYW5kIGtleSBcIit1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzW2ldWzFdKStcbiAgICAgICAgXCIgc2hvdWxkIGJlIFwiK3V0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnNbaV1bMl0pLCBmYWxzZSk7XG4gICAgICBqKys7XG4gICAgfVxuICB9XG4gIGlmIChyZXMpIHtcbiAgICByZXN1bHRbal0gPSBuZXcgdW5pdC5yZXN1bHQoXCIzNCB0ZXN0IHZlY3RvcnMgY29tcGxldGVkIFwiLCB0cnVlKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uLy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIkNBU1QtMTI4IGNpcGhlciB0ZXN0IHdpdGggdGVzdCB2ZWN0b3JzIGZyb20gUkZDMjE0NFwiLCBmdW5jdGlvbigpIHtcblx0dmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8uLi8nKSxcblx0XHR1dGlsID0gb3BlbnBncC51dGlsO1xuXG5cdHZhciByZXN1bHQgPSBbXTtcblx0ZnVuY3Rpb24gdGVzdF9jYXN0KGlucHV0LCBrZXksIG91dHB1dCkge1xuXHRcdHZhciBjYXN0NSA9IG5ldyBvcGVucGdwLmNpcGhlci5jYXN0NSh1dGlsLmJpbjJzdHIoa2V5KSk7XG5cdFx0dmFyIHJlc3VsdCA9IHV0aWwuYmluMnN0cihjYXN0NS5lbmNyeXB0KGlucHV0KSk7XG5cblx0XHRyZXR1cm4gdXRpbC5oZXhzdHJkdW1wKHJlc3VsdCkgPT0gdXRpbC5oZXhzdHJkdW1wKHV0aWwuYmluMnN0cihvdXRwdXQpKTtcblx0fVxuXHRcblx0dmFyIHRlc3R2ZWN0b3JzID0gW1tbMHgwMSwweDIzLDB4NDUsMHg2NywweDEyLDB4MzQsMHg1NiwweDc4LDB4MjMsMHg0NSwweDY3LDB4ODksMHgzNCwweDU2LDB4NzgsMHg5QV0sWzB4MDEsMHgyMywweDQ1LDB4NjcsMHg4OSwweEFCLDB4Q0QsMHhFRl0sWzB4MjMsMHg4QiwweDRGLDB4RTUsMHg4NCwweDdFLDB4NDQsMHhCMl1dXTtcblxuXHRmb3IgKHZhciBpID0gMDsgaSA8IHRlc3R2ZWN0b3JzLmxlbmd0aDsgaSsrKSB7XG5cdFx0cmVzdWx0W2ldID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyB2ZWN0b3Igd2l0aCBibG9jayBcIitcblx0XHRcdFx0dXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yc1tpXVswXSkrXG5cdFx0XHRcdFwiIGFuZCBrZXkgXCIrdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yc1tpXVsxXSkrXG5cdFx0XHRcdFwiIHNob3VsZCBiZSBcIit1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzW2ldWzJdKSxcblx0XHRcdHRlc3RfY2FzdCh0ZXN0dmVjdG9yc1tpXVsxXSx0ZXN0dmVjdG9yc1tpXVswXSx0ZXN0dmVjdG9yc1tpXVsyXSkpO1xuXHR9XG5cdHJldHVybiByZXN1bHQ7XG59KTtcbiIsInZhciB1bml0ID0gcmVxdWlyZSgnLi4vLi4vdW5pdC5qcycpO1xuXG51bml0LnJlZ2lzdGVyKFwiVHdvZmlzaCB0ZXN0IHdpdGggdGVzdCB2ZWN0b3JzIGZyb20gaHR0cDovL3d3dy5zY2huZWllci5jb20vY29kZS9lY2JfaXZhbC50eHRcIiwgZnVuY3Rpb24oKSB7XG4gIHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vLi4vJyksXG4gICAgdXRpbCA9IG9wZW5wZ3AudXRpbDtcblxuICBmdW5jdGlvbiBURmVuY3J5cHQoYmxvY2ssIGtleSkge1xuICAgIHZhciB0ZiA9IG5ldyBvcGVucGdwLmNpcGhlci50d29maXNoKGtleSk7XG5cbiAgICByZXR1cm4gdGYuZW5jcnlwdChibG9jayk7XG4gIH1cblxuXG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIHN0YXJ0ID0gWzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMF07XG4gIHZhciBzdGFydF9zaG9ydCA9IFswLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwXTtcbiAgdmFyIHRlc3R2ZWN0b3JzID0gW1sweDU3LDB4RkYsMHg3MywweDlELDB4NEQsMHhDOSwweDJDLDB4MUIsMHhENywweEZDLDB4MDEsMHg3MCwweDBDLDB4QzgsMHgyMSwweDZGXSxcbiAgICAgICAgICAgIFsweEQ0LDB4M0IsMHhCNywweDU1LDB4NkUsMHhBMywweDJFLDB4NDYsMHhGMiwweEEyLDB4ODIsMHhCNywweEQ0LDB4NUIsMHg0RSwweDBEXSxcbiAgICAgICAgICAgIFsweDkwLDB4QUYsMHhFOSwweDFCLDB4QjIsMHg4OCwweDU0LDB4NEYsMHgyQywweDMyLDB4REMsMHgyMywweDlCLDB4MjYsMHgzNSwweEU2XSxcbiAgICAgICAgICAgIFsweDZDLDB4QjQsMHg1NiwweDFDLDB4NDAsMHhCRiwweDBBLDB4OTcsMHgwNSwweDkzLDB4MUMsMHhCNiwweEQ0LDB4MDgsMHhFNywweEZBXSxcbiAgICAgICAgICAgIFsweDMwLDB4NTksMHhENiwweEQ2LDB4MTcsMHg1MywweEI5LDB4NTgsMHhEOSwweDJGLDB4NDcsMHg4MSwweEM4LDB4NjQsMHgwRSwweDU4XSxcbiAgICAgICAgICAgIFsweEU2LDB4OTQsMHg2NSwweDc3LDB4MDUsMHgwNSwweEQ3LDB4RjgsMHgwRSwweEY2LDB4OEMsMHhBMywweDhBLDB4QjMsMHhBMywweEQ2XSxcbiAgICAgICAgICAgIFsweDVBLDB4QjYsMHg3QSwweDVGLDB4ODUsMHgzOSwweEE0LDB4QTUsMHhGRCwweDlGLDB4MDMsMHg3MywweEJBLDB4NDYsMHgzNCwweDY2XSxcbiAgICAgICAgICAgIFsweERDLDB4MDksMHg2QiwweENELDB4OTksMHhGQywweDcyLDB4RjcsMHg5OSwweDM2LDB4RDQsMHhDNywweDQ4LDB4RTcsMHg1QSwweEY3XSxcbiAgICAgICAgICAgIFsweEM1LDB4QTMsMHhFNywweENFLDB4RTAsMHhGMSwweEI3LDB4MjYsMHgwNSwweDI4LDB4QTYsMHg4RiwweEI0LDB4RUEsMHgwNSwweEYyXSxcbiAgICAgICAgICAgIFsweDQzLDB4RDUsMHhDRSwweEMzLDB4MjcsMHhCMiwweDRBLDB4QjksMHgwQSwweEQzLDB4NEEsMHg3OSwweEQwLDB4NDYsMHg5MSwweDUxXV07XG4gIHRlc3R2ZWN0b3JzWzQ3XSA9ICBbMHg0MywweDEwLDB4NTgsMHhGNCwweERCLDB4QzcsMHhGNywweDM0LDB4REEsMHg0RiwweDAyLDB4RjAsMHg0QywweEM0LDB4RjQsMHg1OV07XG4gIHRlc3R2ZWN0b3JzWzQ4XSA9ICBbMHgzNywweEZFLDB4MjYsMHhGRiwweDFDLDB4RjYsMHg2MSwweDc1LDB4RjUsMHhERCwweEY0LDB4QzMsMHgzQiwweDk3LDB4QTIsMHgwNV07XG4gIHZhciByZXMgPSB0cnVlO1xuICB2YXIgaiA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgNDk7IGkrKykge1xuICAgIHZhciByZXMyID0gZmFsc2U7XG4gICAgdmFyIGJsaywga2V5LCBjdDtcbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgYmxrID0gc3RhcnRfc2hvcnQ7XG4gICAgICBrZXkgPSB1dGlsLmJpbjJzdHIoc3RhcnQpO1xuICAgICAgY3QgPSB0ZXN0dmVjdG9yc1swXTtcbiAgICAgIHJlczIgPSAodXRpbC5iaW4yc3RyKFRGZW5jcnlwdChibGssa2V5KSkgPT0gdXRpbC5iaW4yc3RyKGN0KSk7XG4gICAgfSBlbHNlIGlmIChpID09PSAxKSB7XG4gICAgICBibGsgPSB0ZXN0dmVjdG9yc1swXTtcbiAgICAgIGtleSA9IHV0aWwuYmluMnN0cihzdGFydCk7XG4gICAgICBjdCA9IHRlc3R2ZWN0b3JzWzFdO1xuICAgICAgcmVzMiA9ICh1dGlsLmJpbjJzdHIoVEZlbmNyeXB0KGJsayxrZXkpKSA9PSB1dGlsLmJpbjJzdHIoY3QpKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IDIpIHtcbiAgICAgIGJsayA9IHRlc3R2ZWN0b3JzW2ktMV07XG4gICAgICBrZXkgPSB1dGlsLmJpbjJzdHIodGVzdHZlY3RvcnNbaS0yXS5jb25jYXQoc3RhcnRfc2hvcnQpKTtcbiAgICAgIGN0ID0gdGVzdHZlY3RvcnNbaV07XG4gICAgICByZXMyID0gKHV0aWwuYmluMnN0cihURmVuY3J5cHQoYmxrLGtleSkpID09IHV0aWwuYmluMnN0cihjdCkpO1xuICAgIH0gZWxzZSBpZiAoaSA8IDEwIHx8IGkgPiA0Nikge1xuICAgICAgYmxrID0gdGVzdHZlY3RvcnNbaS0xXTtcbiAgICAgIGtleSA9IHV0aWwuYmluMnN0cih0ZXN0dmVjdG9yc1tpLTJdLmNvbmNhdCh0ZXN0dmVjdG9yc1tpLTNdKSk7XG4gICAgICBjdCA9IHRlc3R2ZWN0b3JzW2ldO1xuICAgICAgcmVzMiA9ICh1dGlsLmJpbjJzdHIoVEZlbmNyeXB0KGJsayxrZXkpKSA9PSB1dGlsLmJpbjJzdHIoY3QpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGVzdHZlY3RvcnNbaV0gPSBURmVuY3J5cHQodGVzdHZlY3RvcnNbaS0xXSx1dGlsLmJpbjJzdHIodGVzdHZlY3RvcnNbaS0yXS5jb25jYXQodGVzdHZlY3RvcnNbaS0zXSkpKTtcbiAgICAgIHJlczIgPSB0cnVlO1xuICAgIH1cbiAgICByZXMgJj0gcmVzMjtcbiAgICBpZiAoIXJlczIpIHtcbiAgICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3RpbmcgdmVjdG9yIHdpdGggYmxvY2sgXCIrdXRpbC5oZXhpZHVtcChibGspK1wiIHdpdGgga2V5IFwiKyB1dGlsLmhleHN0cmR1bXAoa2V5KSArXCIgc2hvdWxkIGJlIFwiK3V0aWwuaGV4aWR1bXAoY3QpK1wiIGJ1dCBpcyBcIit1dGlsLmhleGlkdW1wKFRGZW5jcnlwdChibGssa2V5KSksIGZhbHNlKTtcbiAgICAgIGorKztcbiAgICB9XG4gIH1cbiAgaWYgKHJlcykge1xuICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIjQ5IHRlc3QgdmVjdG9ycyBjb21wbGV0ZWRcIiwgdHJ1ZSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn0pO1xuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi8uLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJNRDUgdGVzdCB3aXRoIHRlc3QgdmVjdG9ycyBmcm9tIFJGQyAxMzIxXCIsIGZ1bmN0aW9uKCkge1xuXHR2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLy4uLycpLFxuXHRcdHV0aWwgPSBvcGVucGdwLnV0aWwsXG5cdFx0TUQ1ID0gb3BlbnBncC5oYXNoLm1kNTtcblxuXHR2YXIgcmVzdWx0ID0gbmV3IEFycmF5KCk7XG5cdHJlc3VsdFswXSA9IG5ldyB1bml0LnJlc3VsdChcIk1ENSAoXFxcIlxcXCIpID0gZDQxZDhjZDk4ZjAwYjIwNGU5ODAwOTk4ZWNmODQyN2VcIixcblx0XHRcdHV0aWwuaGV4c3RyZHVtcChNRDUoXCJcIikpID09IFwiZDQxZDhjZDk4ZjAwYjIwNGU5ODAwOTk4ZWNmODQyN2VcIik7XG5cdHJlc3VsdFsxXSA9IG5ldyB1bml0LnJlc3VsdChcIk1ENSAoXFxcImFcXFwiKSA9IDBjYzE3NWI5YzBmMWI2YTgzMWMzOTllMjY5NzcyNjYxXCIsXG5cdFx0XHR1dGlsLmhleHN0cmR1bXAoTUQ1IChcImFiY1wiKSkgPT0gXCI5MDAxNTA5ODNjZDI0ZmIwZDY5NjNmN2QyOGUxN2Y3MlwiKTtcblx0cmVzdWx0WzJdID0gbmV3IHVuaXQucmVzdWx0KFwiTUQ1IChcXFwibWVzc2FnZSBkaWdlc3RcXFwiKSA9IGY5NmI2OTdkN2NiNzkzOGQ1MjVhMmYzMWFhZjE2MWQwXCIsXG5cdFx0XHR1dGlsLmhleHN0cmR1bXAoTUQ1IChcIm1lc3NhZ2UgZGlnZXN0XCIpKSA9PSBcImY5NmI2OTdkN2NiNzkzOGQ1MjVhMmYzMWFhZjE2MWQwXCIpO1xuXHRyZXN1bHRbM10gPSBuZXcgdW5pdC5yZXN1bHQoXCJNRDUgKFxcXCJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elxcXCIpID0gYzNmY2QzZDc2MTkyZTQwMDdkZmI0OTZjY2E2N2UxM2JcIixcblx0XHRcdHV0aWwuaGV4c3RyZHVtcChNRDUgKFwiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIikpID09IFwiYzNmY2QzZDc2MTkyZTQwMDdkZmI0OTZjY2E2N2UxM2JcIik7XG5cdHJlc3VsdFs0XSA9IG5ldyB1bml0LnJlc3VsdChcIk1ENSAoXFxcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5XFxcIikgPSBkMTc0YWI5OGQyNzdkOWY1YTU2MTFjMmM5ZjQxOWQ5ZlwiLFxuXHRcdFx0dXRpbC5oZXhzdHJkdW1wKE1ENSAoXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OVwiKSkgPT0gXCJkMTc0YWI5OGQyNzdkOWY1YTU2MTFjMmM5ZjQxOWQ5ZlwiKTtcblx0cmVzdWx0WzVdID0gbmV3IHVuaXQucmVzdWx0KFwiTUQ1IChcXFwiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTBcXFwiKSA9IDU3ZWRmNGEyMmJlM2M5NTVhYzQ5ZGEyZTIxMDdiNjdhXCIsXG5cdFx0XHR1dGlsLmhleHN0cmR1bXAoTUQ1IChcIjEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwXCIpKSA9PSBcIjU3ZWRmNGEyMmJlM2M5NTVhYzQ5ZGEyZTIxMDdiNjdhXCIpO1xuXHRyZXR1cm4gcmVzdWx0O1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uLy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIlJJUEUtTUQgMTYwIGJpdHMgdGVzdCB3aXRoIHRlc3QgdmVjdG9ycyBmcm9tIGh0dHA6Ly9ob21lcy5lc2F0Lmt1bGV1dmVuLmJlL35ib3NzZWxhZS9yaXBlbWQxNjAuaHRtbFwiLCBmdW5jdGlvbigpIHtcblxuXHR2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLy4uLycpLFxuXHRcdHV0aWwgPSBvcGVucGdwLnV0aWwsXG5cdFx0Uk1Ec3RyaW5nID0gb3BlbnBncC5oYXNoLnJpcGVtZDtcblxuXHR2YXIgcmVzdWx0ID0gbmV3IEFycmF5KCk7XG5cdHJlc3VsdFswXSA9IG5ldyB1bml0LnJlc3VsdChcIlJNRHN0cmluZyAoXFxcIlxcXCIpID0gOWMxMTg1YTVjNWU5ZmM1NDYxMjgwODk3N2VlOGY1NDhiMjI1OGQzMVwiLFxuXHRcdFx0dXRpbC5oZXhzdHJkdW1wKFJNRHN0cmluZyhcIlwiKSkgPT0gXCI5YzExODVhNWM1ZTlmYzU0NjEyODA4OTc3ZWU4ZjU0OGIyMjU4ZDMxXCIpO1xuXHRyZXN1bHRbMV0gPSBuZXcgdW5pdC5yZXN1bHQoXCJSTURzdHJpbmcgKFxcXCJhXFxcIikgPSAwYmRjOWQyZDI1NmIzZWU5ZGFhZTM0N2JlNmY0ZGM4MzVhNDY3ZmZlXCIsXG5cdFx0XHR1dGlsLmhleHN0cmR1bXAoUk1Ec3RyaW5nKFwiYVwiKSkgPT0gXCIwYmRjOWQyZDI1NmIzZWU5ZGFhZTM0N2JlNmY0ZGM4MzVhNDY3ZmZlXCIpO1xuXHRyZXN1bHRbMl0gPSBuZXcgdW5pdC5yZXN1bHQoXCJSTURzdHJpbmcgKFxcXCJhYmNcXFwiKSA9IDhlYjIwOGY3ZTA1ZDk4N2E5YjA0NGE4ZTk4YzZiMDg3ZjE1YTBiZmNcIixcblx0XHRcdHV0aWwuaGV4c3RyZHVtcChSTURzdHJpbmcoXCJhYmNcIikpID09IFwiOGViMjA4ZjdlMDVkOTg3YTliMDQ0YThlOThjNmIwODdmMTVhMGJmY1wiKTtcblx0cmVzdWx0WzNdID0gbmV3IHVuaXQucmVzdWx0KFwiUk1Ec3RyaW5nIChcXFwibWVzc2FnZSBkaWdlc3RcXFwiKSA9IDVkMDY4OWVmNDlkMmZhZTU3MmI4ODFiMTIzYTg1ZmZhMjE1OTVmMzZcIixcblx0XHRcdHV0aWwuaGV4c3RyZHVtcChSTURzdHJpbmcoXCJtZXNzYWdlIGRpZ2VzdFwiKSkgPT0gXCI1ZDA2ODllZjQ5ZDJmYWU1NzJiODgxYjEyM2E4NWZmYTIxNTk1ZjM2XCIpO1xuXHRyZXR1cm4gcmVzdWx0O1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uLy4uL3VuaXQuanMnKTtcblxuXG51bml0LnJlZ2lzdGVyKFwiU0hBKiB0ZXN0IHdpdGggdGVzdCB2ZWN0b3JzIGZyb20gTklTVCBGSVBTIDE4MC0yXCIsIGZ1bmN0aW9uKCkge1xuXHR2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLy4uLycpLFxuXHRcdHV0aWwgPSBvcGVucGdwLnV0aWwsXG5cdFx0aGFzaCA9IG9wZW5wZ3AuaGFzaDtcblxuXHR2YXIgcmVzdWx0ID0gbmV3IEFycmF5KCk7XG5cdFxuXHRyZXN1bHRbMF0gPSBuZXcgdW5pdC5yZXN1bHQoXCJTSEExIC0gYTk5OTNlMzY0NzA2ODE2YWJhM2UyNTcxNzg1MGMyNmM5Y2QwZDg5ZCA9IGhhc2guc2hhMShcXFwiYWJjXFxcIikgXCIsXG5cdFx0XHRcImE5OTkzZTM2NDcwNjgxNmFiYTNlMjU3MTc4NTBjMjZjOWNkMGQ4OWRcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGExKFwiYWJjXCIpKSk7XG5cdHJlc3VsdFsxXSA9IG5ldyB1bml0LnJlc3VsdChcIlNIQTEgLSA4NDk4M2U0NDFjM2JkMjZlYmFhZTRhYTFmOTUxMjllNWU1NDY3MGYxID0gaGFzaC5zaGExKFxcXCJhYmNkYmNkZWNkZWZkZWZnZWZnaGZnaGlnaGlqaGlqa2lqa2xqa2xta2xtbmxtbm9tbm9wbm9wcVxcXCIpIFwiLFxuXHRcdFx0XCI4NDk4M2U0NDFjM2JkMjZlYmFhZTRhYTFmOTUxMjllNWU1NDY3MGYxXCIgPT0gdXRpbC5oZXhzdHJkdW1wKGhhc2guc2hhMShcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXCIpKSk7XG5cdHJlc3VsdFsyXSA9IG5ldyB1bml0LnJlc3VsdChcIlNIQTIyNCAtIDIzMDk3ZDIyMzQwNWQ4MjI4NjQyYTQ3N2JkYTI1NWIzMmFhZGJjZTRiZGEwYjNmN2UzNmM5ZGE3ID0gaGFzaC5zaGEyMjQoXFxcImFiY1xcXCIpIFwiLFxuXHRcdFx0XCIyMzA5N2QyMjM0MDVkODIyODY0MmE0NzdiZGEyNTViMzJhYWRiY2U0YmRhMGIzZjdlMzZjOWRhN1wiID09IHV0aWwuaGV4c3RyZHVtcChoYXNoLnNoYTIyNChcImFiY1wiKSkpO1xuXHRyZXN1bHRbM10gPSBuZXcgdW5pdC5yZXN1bHQoXCJTSEEyMjQgLSA3NTM4OGIxNjUxMjc3NmNjNWRiYTVkYTFmZDg5MDE1MGIwYzY0NTVjYjRmNThiMTk1MjUyMjUyNSA9IGhhc2guc2hhMjI0KFxcXCJhYmNkYmNkZWNkZWZkZWZnZWZnaGZnaGlnaGlqaGlqa2lqa2xqa2xta2xtbmxtbm9tbm9wbm9wcVxcXCIpIFwiLFxuXHRcdFx0XCI3NTM4OGIxNjUxMjc3NmNjNWRiYTVkYTFmZDg5MDE1MGIwYzY0NTVjYjRmNThiMTk1MjUyMjUyNVwiID09IHV0aWwuaGV4c3RyZHVtcChoYXNoLnNoYTIyNChcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXCIpKSk7XG5cdHJlc3VsdFs0XSA9IG5ldyB1bml0LnJlc3VsdChcIlNIQTI1NiAtIGJhNzgxNmJmOGYwMWNmZWE0MTQxNDBkZTVkYWUyMjIzYjAwMzYxYTM5NjE3N2E5Y2I0MTBmZjYxZjIwMDE1YWQgPSBoYXNoLnNoYTI1NihcXFwiYWJjXFxcIikgXCIsXG5cdFx0XHRcImJhNzgxNmJmOGYwMWNmZWE0MTQxNDBkZTVkYWUyMjIzYjAwMzYxYTM5NjE3N2E5Y2I0MTBmZjYxZjIwMDE1YWRcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGEyNTYoXCJhYmNcIikpKTtcblx0cmVzdWx0WzVdID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBMjU2IC0gMjQ4ZDZhNjFkMjA2MzhiOGU1YzAyNjkzMGMzZTYwMzlhMzNjZTQ1OTY0ZmYyMTY3ZjZlY2VkZDQxOWRiMDZjMSA9IGhhc2guc2hhMjU2KFxcXCJhYmNkYmNkZWNkZWZkZWZnZWZnaGZnaGlnaGlqaGlqa2lqa2xqa2xta2xtbmxtbm9tbm9wbm9wcVxcXCIpIFwiLFxuXHRcdFx0XCIyNDhkNmE2MWQyMDYzOGI4ZTVjMDI2OTMwYzNlNjAzOWEzM2NlNDU5NjRmZjIxNjdmNmVjZWRkNDE5ZGIwNmMxXCIgPT0gdXRpbC5oZXhzdHJkdW1wKGhhc2guc2hhMjU2KFwiYWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHFcIikpKTtcblx0cmVzdWx0WzZdID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBMzg0IC0gY2IwMDc1M2Y0NWEzNWU4YmI1YTAzZDY5OWFjNjUwMDcyNzJjMzJhYjBlZGVkMTYzMWE4YjYwNWE0M2ZmNWJlZDgwODYwNzJiYTFlN2NjMjM1OGJhZWNhMTM0YzgyNWE3ID0gaGFzaC5zaGEzODQoXFxcImFiY1xcXCIpIFwiLFxuXHRcdFx0XCJjYjAwNzUzZjQ1YTM1ZThiYjVhMDNkNjk5YWM2NTAwNzI3MmMzMmFiMGVkZWQxNjMxYThiNjA1YTQzZmY1YmVkODA4NjA3MmJhMWU3Y2MyMzU4YmFlY2ExMzRjODI1YTdcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGEzODQoXCJhYmNcIikpKTtcblx0cmVzdWx0WzddID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBMzg0IC0gMzM5MWZkZGRmYzhkYzczOTM3MDdhNjViMWI0NzA5Mzk3Y2Y4YjFkMTYyYWYwNWFiZmU4ZjQ1MGRlNWYzNmJjNmIwNDU1YTg1MjBiYzRlNmY1ZmU5NWIxZmUzYzg0NTJiID0gc3RyMzg0KFxcXCJhYmNkYmNkZWNkZWZkZWZnZWZnaGZnaGlnaGlqaGlqa2lqa2xqa2xta2xtbmxtbm9tbm9wbm9wcVxcXCIpIFwiLFxuXHRcdFx0XCIzMzkxZmRkZGZjOGRjNzM5MzcwN2E2NWIxYjQ3MDkzOTdjZjhiMWQxNjJhZjA1YWJmZThmNDUwZGU1ZjM2YmM2YjA0NTVhODUyMGJjNGU2ZjVmZTk1YjFmZTNjODQ1MmJcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGEzODQoXCJhYmNkYmNkZWNkZWZkZWZnZWZnaGZnaGlnaGlqaGlqa2lqa2xqa2xta2xtbmxtbm9tbm9wbm9wcVwiKSkpO1x0XHRcdFx0XHRcblx0cmVzdWx0WzhdID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBNTEyIC0gZGRhZjM1YTE5MzYxN2FiYWNjNDE3MzQ5YWUyMDQxMzExMmU2ZmE0ZTg5YTk3ZWEyMGE5ZWVlZTY0YjU1ZDM5YTIxOTI5OTJhMjc0ZmMxYTgzNmJhM2MyM2EzZmVlYmJkNDU0ZDQ0MjM2NDNjZTgwZTJhOWFjOTRmYTU0Y2E0OWYgPSBoYXNoLnNoYTUxMihcXFwiYWJjXFxcIikgXCIsXG5cdFx0XHRcImRkYWYzNWExOTM2MTdhYmFjYzQxNzM0OWFlMjA0MTMxMTJlNmZhNGU4OWE5N2VhMjBhOWVlZWU2NGI1NWQzOWEyMTkyOTkyYTI3NGZjMWE4MzZiYTNjMjNhM2ZlZWJiZDQ1NGQ0NDIzNjQzY2U4MGUyYTlhYzk0ZmE1NGNhNDlmXCIgPT0gdXRpbC5oZXhzdHJkdW1wKGhhc2guc2hhNTEyKFwiYWJjXCIpKSk7XG5cdHJlc3VsdFs5XSA9IG5ldyB1bml0LnJlc3VsdChcIlNIQTUxMiAtIDIwNGE4ZmM2ZGRhODJmMGEwY2VkN2JlYjhlMDhhNDE2NTdjMTZlZjQ2OGIyMjhhODI3OWJlMzMxYTcwM2MzMzU5NmZkMTVjMTNiMWIwN2Y5YWExZDNiZWE1Nzc4OWNhMDMxYWQ4NWM3YTcxZGQ3MDM1NGVjNjMxMjM4Y2EzNDQ1ID0gaGFzaC5zaGE1MTIoXFxcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXFxcIikgXCIsXG5cdFx0XHRcIjIwNGE4ZmM2ZGRhODJmMGEwY2VkN2JlYjhlMDhhNDE2NTdjMTZlZjQ2OGIyMjhhODI3OWJlMzMxYTcwM2MzMzU5NmZkMTVjMTNiMWIwN2Y5YWExZDNiZWE1Nzc4OWNhMDMxYWQ4NWM3YTcxZGQ3MDM1NGVjNjMxMjM4Y2EzNDQ1XCIgPT0gdXRpbC5oZXhzdHJkdW1wKGhhc2guc2hhNTEyKFwiYWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHFcIikpKTtcdFx0XHRcdFx0XG5cdHJldHVybiByZXN1bHQ7XG59KTtcbiIsInZhciB1bml0ID0gcmVxdWlyZSgnLi4vdW5pdC5qcycpO1xuXG51bml0LnJlZ2lzdGVyKFwiRnVuY3Rpb25hbCB0ZXN0aW5nIG9mIG9wZW5wZ3AuY3J5cHRvLiogbWV0aG9kc1wiLCBmdW5jdGlvbigpIHtcblx0dmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8nKTtcbiAgdmFyIHV0aWwgPSBvcGVucGdwLnV0aWw7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIFJTQXB1Yk1QSXN0cnMgPSBbXG4gICAgICAgICAgICAgIHV0aWwuYmluMnN0cihbMHgwOCwweDAwLDB4YWMsMHgxNSwweGIzLDB4ZDYsMHhkMiwweDBmLDB4ZjAsMHg3YSwweGRkLDB4MjEsMHhiNyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGJmLDB4NjEsMHhmYSwweGNhLDB4OTMsMHg4NiwweGM4LDB4NTUsMHg1YSwweDRiLDB4YTYsMHhhNCwweDFhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NjAsMHhhMiwweDNhLDB4MzcsMHgwNiwweDA4LDB4ZDgsMHgxNSwweDhlLDB4ODUsMHg0NSwweGFhLDB4YjcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxZCwweDdiLDB4MGIsMHg3MywweDk0LDB4NTUsMHgwYywweDVjLDB4ZWMsMHhjMCwweDIyLDB4NGIsMHhhMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDY0LDB4MjAsMHg3ZCwweDRkLDB4YTgsMHg5NiwweDFhLDB4NjQsMHgzOCwweDkzLDB4Y2QsMHhlYywweDczLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NWQsMHhmOSwweDg5LDB4ODgsMHgyNCwweDNkLDB4NDgsMHhmZiwweDNiLDB4ODcsMHg2MiwweGQwLDB4ODQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhlYSwweGZmLDB4MzksMHhiNSwweDI3LDB4NzAsMHhlYSwweDRhLDB4YjIsMHgyZSwweDlkLDB4ZjEsMHg3YyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDIzLDB4ZWMsMHhmNCwweDVlLDB4ZWEsMHg2MSwweDNkLDB4ZTUsMHhkOCwweDBkLDB4ZjksMHg1OSwweDZkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjgsMHgwMCwweGViLDB4Y2IsMHhjOSwweDU1LDB4MDAsMHg3MiwweDMwLDB4MWYsMHg2NSwweDlkLDB4ZDYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNywweDU4LDB4NWYsMHhhNiwweDRhLDB4YTAsMHhkZCwweGUxLDB4NzYsMHhmMiwweGVmLDB4MjEsMHg5ZixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDg0LDB4ZmMsMHhhYSwweDViLDB4NTIsMHg2ZSwweGMxLDB4YTIsMHhiOSwweGJkLDB4YjksMHhmNCwweDllLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDksMHg5MiwweGYyLDB4YWYsMHg1NywweDg2LDB4ZjIsMHhlZiwweDcwLDB4YmYsMHg1MSwweDQwLDB4ZmQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhiZiwweDU2LDB4NTEsMHhlOCwweDJjLDB4YTIsMHg0ZiwweGY4LDB4YTQsMHhkNywweDM2LDB4MTgsMHg4NSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGNlLDB4MDksMHgwZCwweGJjLDB4OGQsMHg2NSwweDVlLDB4OGEsMHgxZCwweDk4LDB4YjAsMHg0ZCwweDlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4YzEsMHhjZiwweDgyLDB4ZTEsMHhiNywweDQzLDB4NWQsMHg1YSwweDcyLDB4Y2QsMHg1NSwweGQyLDB4ZmYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhiMSwweGI0LDB4NzgsMHhiZiwweGExLDB4N2QsMHhhYywweGQ5LDB4MWIsMHhjNCwweGZhLDB4MzksMHgzNCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDkyLDB4MDksMHhmOSwweDA4LDB4MmEsMHg2YiwweDlkLDB4MTQsMHg1NiwweDEyLDB4NGMsMHhlOSwweGE2LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjksMHhjMSwweGYzLDB4YTksMHgwYiwweGZjLDB4MzEsMHg3NSwweDU4LDB4NzQsMHgyYSwweDg4LDB4YWYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhlZSwweGM5LDB4YTQsMHhjZCwweDE1LDB4ZGMsMHgxYiwweDhkLDB4NjQsMHhjMSwweDM2LDB4MTcsMHhjNCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDhkLDB4NWUsMHg5OSwweDdhLDB4NWIsMHg5ZiwweDM5LDB4ZDAsMHgwMCwweDZlLDB4ZjldKSxcbiAgICAgICAgICAgICAgdXRpbC5iaW4yc3RyKFsweDAwLDB4MTEsMHgwMSwweDAwLDB4MDFdKV07XG4gIHZhciBSU0FzZWNNUElzdHJzID0gW1xuICAgICAgICAgICAgICB1dGlsLmJpbjJzdHIoWzB4MDcsMHhmZSwweDIzLDB4ZmYsMHhjZSwweDQ1LDB4NmMsMHg2MCwweDY1LDB4NDAsMHg2ZSwweGFlLDB4MzUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxMCwweDU2LDB4NjAsMHhlZSwweGFiLDB4ZmEsMHgxMCwweDQyLDB4YmEsMHhjNywweDA0LDB4YWYsMHg2MyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGNkLDB4M2YsMHg2MiwweGNhLDB4NGIsMHhmYSwweGUxLDB4YTksMHg3MCwweGNkLDB4MzQsMHg4YiwweGM4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MGUsMHhlNCwweGM0LDB4YmEsMHg4MywweDE3LDB4NWYsMHhhNCwweGI4LDB4ZWEsMHg2MCwweGMyLDB4NGQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg5YSwweGYyLDB4YTksMHgwMywweGViLDB4ZjYsMHhhYSwweGMyLDB4YjgsMHg4YiwweDQzLDB4MTIsMHhlOSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGY3LDB4ODgsMHhkMiwweDVhLDB4YTYsMHhhYSwweDIzLDB4NzEsMHgzMSwweDc0LDB4ZGIsMHgxOSwweDIwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MTUsMHg0MSwweDFiLDB4NDMsMHg2OCwweDYyLDB4ZDgsMHhjMCwweDkzLDB4OTEsMHhlOCwweGZjLDB4YjEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhhOSwweDlhLDB4NTIsMHg2YywweGUwLDB4YmYsMHg0MywweDAxLDB4YTgsMHgzNywweDE0LDB4MjgsMHhiZixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDBiLDB4MTUsMHg1NiwweDNlLDB4YTUsMHg3OSwweGEwLDB4YzQsMHg0MiwweDg4LDB4ZWUsMHhlYiwweDFiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZjQsMHg3YSwweDRhLDB4NTgsMHgzMSwweDU4LDB4ODEsMHhkMiwweDNlLDB4ZGUsMHgwNywweDY0LDB4OTIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmMCwweDYwLDB4ZDMsMHg5YSwweDI5LDB4Y2EsMHhjNiwweDY3LDB4NzUsMHgwNywweGNhLDB4OTIsMHgzOSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDU2LDB4ZjYsMHgxMSwweDg0LDB4YmEsMHg2ZCwweDRiLDB4ZTYsMHg2ZiwweDY2LDB4YzIsMHgxNywweGViLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDYsMHg2OSwweDFjLDB4YmIsMHhkZiwweGMwLDB4MzgsMHgwMCwweGQ2LDB4MDEsMHhlNiwweDcwLDB4OWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0YiwweDliLDB4NzAsMHhlZCwweDVjLDB4YjgsMHhjZiwweGU4LDB4NjgsMHg3MSwweGJlLDB4MjQsMHg2ZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGIxLDB4YTMsMHgxMywweGNjLDB4ZjEsMHhiYywweDY3LDB4ZGMsMHhlMCwweDY5LDB4MDksMHg4MiwweDNjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4M2IsMHgwZiwweDE0LDB4OTgsMHg0OCwweDMwLDB4YjIsMHg3MCwweGM2LDB4OWUsMHhmYSwweDQ2LDB4OGYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmMSwweGMwLDB4NjUsMHg4ZSwweGM2LDB4YWUsMHhkYywweDQ3LDB4OTEsMHgxMywweDFlLDB4ZDYsMHg0YSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGYyLDB4YWQsMHhkYSwweGMyLDB4YzcsMHgzOSwweDc4LDB4OTksMHhkZSwweDU3LDB4MTQsMHg0NSwweDdmLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MzIsMHgzOCwweGEzLDB4NDQsMHgwZiwweGU3LDB4MzksMHg0YywweDZmLDB4MGYsMHgzMiwweDdlLDB4ZjEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg1YywweDg0LDB4OTcsMHhkZCwweGEwLDB4MGMsMHg4NywweDY2LDB4N2QsMHg3NSwweDc5XSksXG4gICAgICAgICAgICAgIHV0aWwuYmluMnN0cihbMHgwNCwweDAwLDB4YzIsMHhiYywweDcxLDB4ZjcsMHg0MSwweDRhLDB4MDksMHg2NiwweDcwLDB4MDIsMHg2OCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDhiLDB4ZWIsMHhlMiwweDM0LDB4ZDEsMHgxMiwweDgzLDB4OTMsMHg3NSwweGU5LDB4NzEsMHgzMiwweGUyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZWQsMHgxOCwweDZmLDB4OGUsMHgzYSwweGZmLDB4MjIsMHg3MCwweDI4LDB4MDEsMHhiZiwweDRhLDB4MzksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MSwweGJiLDB4M2MsMHg0YSwweGJjLDB4YjgsMHgxMywweGZjLDB4MTQsMHhmNiwweDcxLDB4YTEsMHg0NCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDFjLDB4MDIsMHhhMSwweDczLDB4ODEsMHhjYywweGEwLDB4MzUsMHgwMiwweDNlLDB4OTcsMHhiNSwweGM0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OTQsMHgzMywweGYxLDB4ZDEsMHhkZiwweDE0LDB4M2YsMHhmYiwweDhmLDB4YjksMHg3NSwweDcwLDB4ZGMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg3NCwweDNmLDB4MDcsMHgzNSwweDhmLDB4NTMsMHhhYSwweGIyLDB4ZDYsMHg4OCwweDUxLDB4NzEsMHg0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDAxLDB4MjQsMHhlYywweDdkLDB4Y2EsMHhmNiwweGEyLDB4YjMsMHhiYiwweGFkLDB4MmUsMHg2MCwweGZiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MWMsMHhlZSwweDQ5LDB4ZDAsMHg0ZSwweDVjLDB4ZTMsMHgxZiwweDg4LDB4NDgsMHhlNCwweDY4LDB4MTQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgzZCwweDcxLDB4YmEsMHhkNywweDRkLDB4MzUsMHgxMCwweDg2LDB4MzcsMHg2MiwweGUwLDB4YTUsMHgwYl0pLFxuICAgICAgICAgICAgICB1dGlsLmJpbjJzdHIoWzB4MDQsMHgwMCwweGUyLDB4MzgsMHhmOSwweGM4LDB4M2MsMHhkMSwweGNmLDB4NjIsMHg5MywweGMzLDB4NzcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg3NiwweDk3LDB4NDQsMHhlOCwweGM4LDB4Y2EsMHg5MywweDlhLDB4ZWYsMHhmMCwweDYzLDB4NzYsMHgyNSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDNiLDB4MWMsMHg0NiwweGZmLDB4OTAsMHgxMywweDkxLDB4MTUsMHg5NywweDdlLDB4ODgsMHg5NSwweGQ0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4N2YsMHgyZiwweDUyLDB4NmUsMHgwZCwweDU1LDB4NTUsMHgyZSwweGYxLDB4NTgsMHg1YywweDdlLDB4NTYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhkNCwweDQ4LDB4YWEsMHhkYiwweDhjLDB4NDQsMHg0ZCwweDg0LDB4NjksMHgzMywweDg3LDB4MDcsMHhiMixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDdlLDB4ZjUsMHhhMCwweDYwLDB4ZmIsMHg3MywweDU5LDB4NDYsMHgyOSwweGNiLDB4MWUsMHgzZiwweDdjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MmYsMHhhNiwweDUzLDB4ZTMsMHg4YywweGVmLDB4ZDUsMHhlYiwweGJiLDB4YzgsMHg5YSwweDhlLDB4NjYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0YSwweDQ3LDB4MmYsMHhlMSwweGJhLDB4NWUsMHgzMiwweGQ0LDB4NTIsMHgwNCwweDg4LDB4OWQsMHg2MyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDNlLDB4YmEsMHg3MSwweDJkLDB4ZjcsMHg2MSwweGQ1LDB4ZmMsMHgyNiwweGJmLDB4ZDgsMHg2MCwweDkyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4N2IsMHg5NCwweGY4LDB4NmYsMHgzZCwweDk3LDB4MGIsMHgwYywweDUyLDB4OGMsMHhiMywweGI2LDB4OGJdKSxcbiAgICAgICAgICAgICAgdXRpbC5iaW4yc3RyKFsweDA0LDB4MDAsMHhiNywweGM1LDB4NGQsMHg2ZSwweDJmLDB4ZGQsMHhlZiwweGVjLDB4MDcsMHg3MCwweGEyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4N2MsMHgxYywweDlkLDB4OGUsMHg2NiwweDYwLDB4N2MsMHg2MSwweDFlLDB4NDUsMHhlOSwweGRjLDB4ODIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgyZiwweGM1LDB4N2UsMHgxYSwweGM2LDB4ZDAsMHg5MiwweGM1LDB4MjIsMHg5YiwweDlhLDB4ZmIsMHg3MyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDk1LDB4OTksMHhmMiwweDdjLDB4ZGIsMHgyYSwweDkzLDB4N2IsMHg1YSwweDI5LDB4NzMsMHgyNCwweDE2LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDEsMHg0OSwweGI1LDB4ZjIsMHg1ZiwweGJlLDB4ZTcsMHg2NCwweDRkLDB4ZGEsMHg1MiwweDllLDB4YzEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MSwweDQwLDB4NWUsMHgwMywweDkyLDB4OGQsMHgzOSwweDk1LDB4MWYsMHg2OCwweDlmLDB4MDAsMHgyZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDBjLDB4NmYsMHhjZiwweGQ5LDB4NmQsMHg2OCwweGY3LDB4MDAsMHg0ZiwweDBlLDB4YzgsMHgwYiwweGZhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NTEsMHhlMCwweDIyLDB4ZjAsMHhmZiwweGE3LDB4NDIsMHhkNCwweGRlLDB4MGIsMHg0NywweDhmLDB4MmIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmNSwweDRkLDB4MDQsMHgzMiwweDkxLDB4ODksMHg0YiwweDBlLDB4MDUsMHg4ZCwweDcwLDB4ZjksMHhiYixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGU3LDB4ZDYsMHg3NiwweGVhLDB4MGUsMHgxYSwweDkwLDB4MzAsMHhmNSwweDk4LDB4MDEsMHhjNSwweDczXSldO1xuICBcbiAgdmFyIERTQXB1Yk1QSXN0cnMgPSBbXG4gICAgICAgICAgdXRpbC5iaW4yc3RyKFsweDA4LDB4MDAsMHhhOCwweDg1LDB4NWMsMHgyOCwweDA1LDB4OTQsMHgwMywweGJlLDB4MDcsMHg2YywweDEzLDB4M2UsMHg2NSxcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4ZmIsMHhiNSwweGUxLDB4OTksMHg3YywweGZhLDB4ODQsMHhlMywweGFjLDB4NDcsMHhhNSwweGM0LDB4NDYsMHhkOCwweDVmLFxuICAgICAgICAgICAgICAgICAgICAgICAgMHg0NCwweGU5LDB4YzEsMHg2YiwweDY5LDB4ZjcsMHgxMCwweDc2LDB4NDksMHhhNywweDI1LDB4ODUsMHhmNCwweDFiLDB4ZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAweGM2LDB4NjAsMHhjNCwweDViLDB4YWEsMHhkNCwweDg3LDB4ZDYsMHg4ZiwweDkyLDB4NTYsMHg3ZCwweDU1LDB4M2YsMHg0NSxcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4YWUsMHgxMiwweDczLDB4ZGEsMHgyOSwweDhjLDB4YmEsMHgzMiwweGNjLDB4ZDcsMHhhNCwweGQwLDB4MjQsMHhiMCwweDdjLFxuICAgICAgICAgICAgICAgICAgICAgICAgMHhkOCwweDBjLDB4M2EsMHg5MSwweDZmLDB4OTgsMHg0MCwweDljLDB4OWEsMHhhOCwweGNjLDB4MjgsMHgyNywweDk1LDB4MGIsXG4gICAgICAgICAgICAgICAgICAgICAgICAweGUxLDB4NWIsMHhiOSwweDNiLDB4MWMsMHgxYywweGQyLDB4ZWMsMHhhYiwweDA3LDB4MjUsMHg4ZCwweDdhLDB4MmEsMHgyYixcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4MTYsMHgxNCwweGU4LDB4ZGEsMHg3MSwweGQyLDB4YWIsMHhiYSwweDg1LDB4MTQsMHgwZCwweGM1LDB4ZTAsMHg4OCwweGViLFxuICAgICAgICAgICAgICAgICAgICAgICAgMHhhNSwweGUyLDB4ZDUsMHg0OCwweDNkLDB4NzQsMHgwYywweDQxLDB4ZWIsMHhmZCwweGI2LDB4NGUsMHhmOSwweDJjLDB4ODIsXG4gICAgICAgICAgICAgICAgICAgICAgICAweDE3LDB4ZGQsMHg2NCwweDFlLDB4MTksMHgzOSwweGEzLDB4N2YsMHhmOSwweDAwLDB4Y2QsMHg5YiwweGRhLDB4MmUsMHhiZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4NzEsMHgxMiwweGRmLDB4MGQsMHg3YywweDBhLDB4NmIsMHgyZCwweDIxLDB4M2IsMHg5YywweDY2LDB4OTMsMHg0YSwweDFlLFxuICAgICAgICAgICAgICAgICAgICAgICAgMHg5MCwweDc5LDB4ZDMsMHg1YSwweDViLDB4ZTUsMHhiOSwweDk0LDB4MWIsMHhlNiwweDQ3LDB4OTksMHgwNiwweDk4LDB4ZDgsXG4gICAgICAgICAgICAgICAgICAgICAgICAweDJhLDB4ZTUsMHhlMiwweGE2LDB4OTUsMHg2YSwweDA3LDB4YzgsMHhhYywweDdjLDB4ZTksMHhmYywweGEyLDB4NmEsMHgxNixcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4MmMsMHg5NCwweDk4LDB4YmQsMHg5MSwweDBhLDB4N2MsMHg3YywweDJjLDB4YjksMHg3ZSwweGEyLDB4NTEsMHg4YiwweDQ1LFxuICAgICAgICAgICAgICAgICAgICAgICAgMHgxZCwweDQ2LDB4MzQsMHhhOCwweDUyLDB4MmIsMHhkZCwweGQ5LDB4YTgsMHhiYywweDQ2LDB4NzgsMHg2NiwweGUxLDB4NzIsXG4gICAgICAgICAgICAgICAgICAgICAgICAweDExLDB4ZjEsMHhjYiwweDFhLDB4YjYsMHg0ZSwweDA1LDB4NTQsMHhmNywweGU5LDB4YmUsMHg0YywweDI1LDB4NTksMHgwOCxcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4OWYsMHhmOCwweGVhLDB4MjUsMHg5NywweDMzLDB4ZDYsMHhjOSwweDBmLDB4NTksMHgwZSwweGZkLDB4OWYsMHhkYywweGUyLFxuICAgICAgICAgICAgICAgICAgICAgICAgMHhjMCwweGNmLDB4MmZdKSxcbiAgICAgIHV0aWwuYmluMnN0cihbMHgwMSwweDAwLDB4ZTEsMHg3MiwweDJjLDB4ZDAsMHhiYiwweDFhLDB4NGYsMHhiNiwweGI2LDB4OTUsMHg3NywweDcxLDB4MmUsXG4gICAgICAgICAgICAgICAgICAgIDB4MDEsMHg0OCwweDNlLDB4MzUsMHg1NCwweDY0LDB4MmIsMHhlZCwweDQwLDB4NWYsMHg2NSwweDBjLDB4NTcsMHgyOCwweDVmLFxuICAgICAgICAgICAgICAgICAgICAweGZkLDB4ZmQsMHhmZiwweGQ3XSksXG4gICAgICB1dGlsLmJpbjJzdHIoWzB4MDcsMHhmZiwweDVkLDB4OWYsMHhjNCwweGI1LDB4NjMsMHgyNSwweDlkLDB4NzIsMHg4OCwweGU1LDB4NTMsMHg0NiwweDk4LFxuICAgICAgICAgICAgICAgICAgICAweGUzLDB4ZTksMHg2MiwweGNiLDB4MGMsMHhhMSwweGI3LDB4NzUsMHg5ZiwweDE4LDB4NDEsMHg5NCwweDMyLDB4MjgsMHgyOSxcbiAgICAgICAgICAgICAgICAgICAgMHg2ZCwweDY5LDB4ZTAsMHgzZiwweDdkLDB4N2IsMHgyYiwweDA2LDB4NWEsMHgzMywweDVjLDB4ZDQsMHgzNiwweDMxLDB4MDksXG4gICAgICAgICAgICAgICAgICAgIDB4NTQsMHg4NSwweDlkLDB4YjgsMHgyMCwweGZlLDB4ZGEsMHhmYywweGNkLDB4MWYsMHhiMSwweDJjLDB4MTUsMHgwOCwweDlkLFxuICAgICAgICAgICAgICAgICAgICAweDMyLDB4NTMsMHgyZiwweGMxLDB4NDIsMHgyMiwweDY5LDB4ZmYsMHg2NywweDJlLDB4MzksMHg5NywweDUwLDB4NjYsMHgzOSxcbiAgICAgICAgICAgICAgICAgICAgMHhkYSwweGNmLDB4ZmQsMHg2NCwweDZmLDB4OTEsMHgwNSwweDY0LDB4MzcsMHhjNSwweDA3LDB4MjQsMHhhYSwweDQwLDB4YTAsXG4gICAgICAgICAgICAgICAgICAgIDB4NzUsMHg4MiwweDFkLDB4OTcsMHg5NiwweDEyLDB4ZjEsMHhiZCwweDllLDB4MDksMHgyNiwweDNjLDB4OTcsMHg1ZCwweDU3LFxuICAgICAgICAgICAgICAgICAgICAweGI4LDB4NWMsMHg3ZCwweDg5LDB4MDMsMHg4MiwweGNkLDB4NDAsMHhlNSwweDAzLDB4ZTYsMHg0YSwweGZiLDB4YmMsMHhkMixcbiAgICAgICAgICAgICAgICAgICAgMHhlZiwweDdhLDB4ODksMHgwMiwweDA4LDB4YzgsMHg1MiwweGZhLDB4OTcsMHg3NCwweDY2LDB4MzIsMHhhZSwweGE2LDB4NTIsXG4gICAgICAgICAgICAgICAgICAgIDB4NGIsMHhlZiwweDVmLDB4Y2UsMHg5MSwweDIzLDB4M2YsMHhhYiwweDlkLDB4NjIsMHgyMSwweGVmLDB4NDgsMHg2ZCwweDA3LFxuICAgICAgICAgICAgICAgICAgICAweDVhLDB4YmEsMHhkZiwweDAwLDB4OTEsMHg1NCwweGVhLDB4NWMsMHhmYSwweDRiLDB4MTYsMHgyOCwweDFhLDB4Y2UsMHg0OCxcbiAgICAgICAgICAgICAgICAgICAgMHhiNywweDVjLDB4NTAsMHhhNSwweDU5LDB4YTQsMHhiNCwweGFmLDB4MWYsMHhlYiwweDhkLDB4NTgsMHgzZiwweDBhLDB4YTUsXG4gICAgICAgICAgICAgICAgICAgIDB4OTcsMHgyYiwweDUxLDB4NTYsMHhlOCwweDg4LDB4ZjYsMHgwNywweGJjLDB4ZGYsMHhmYSwweDJiLDB4N2IsMHg4OCwweGUwLFxuICAgICAgICAgICAgICAgICAgICAweDQ2LDB4YzgsMHg3YSwweDNlLDB4ZDgsMHg4MCwweGRiLDB4NGQsMHg4NywweDYxLDB4NGYsMHg2NCwweGNkLDB4ZWIsMHhlOCxcbiAgICAgICAgICAgICAgICAgICAgMHgwZCwweDg2LDB4MTYsMHhjYywweGRkLDB4NmMsMHg3NiwweDY2LDB4YzEsMHg3MywweGI3LDB4MDgsMHg5OCwweDg5LDB4MmYsXG4gICAgICAgICAgICAgICAgICAgIDB4NjcsMHg2OSwweGQxLDB4ZmMsMHg5NywweDRkLDB4YTIsMHhjZSwweGFkLDB4YmIsMHg2ZiwweGFiLDB4YTUsMHhkNiwweDE4LFxuICAgICAgICAgICAgICAgICAgICAweGIzLDB4MWEsMHg5NiwweDAyLDB4YmMsMHgzMSwweDQyLDB4YTIsMHhhZCwweDc3LDB4ZTgsMHhlMiwweDRjLDB4OTksMHhmOSxcbiAgICAgICAgICAgICAgICAgICAgMHhkZCwweGJlLDB4Y2RdKSxcbiAgICAgIHV0aWwuYmluMnN0cihbMHgwNywweGZmLDB4NWQsMHhmZSwweDljLDB4OTgsMHhlZiwweDNhLDB4YTYsMHg0OSwweGYwLDB4MTAsMHg2NywweDc5LDB4MmEsXG4gICAgICAgICAgICAgICAgICAgIDB4OWQsMHg3OSwweDQzLDB4MDYsMHhhNCwweGE4LDB4NmIsMHgxYSwweDZkLDB4MWYsMHg3NywweDZlLDB4MDAsMHgzMSwweGI5LFxuICAgICAgICAgICAgICAgICAgICAweGVkLDB4YzksMHg2NiwweGZmLDB4ZjEsMHgyMSwweDMyLDB4ZmEsMHg2MiwweDQzLDB4Y2QsMHg5NywweGQzLDB4M2QsMHhhZixcbiAgICAgICAgICAgICAgICAgICAgMHhiNCwweDI5LDB4MjksMHgyNiwweDRlLDB4MWMsMHhhMCwweGFkLDB4MWMsMHgwNywweDI4LDB4M2YsMHhlNSwweDQzLDB4MTAsXG4gICAgICAgICAgICAgICAgICAgIDB4YmEsMHhiNCwweDA4LDB4ZTAsMHhkYywweGEyLDB4YzMsMHg1YiwweDFmLDB4YmQsMHg5NCwweGM3LDB4NDMsMHhlNSwweGYyLFxuICAgICAgICAgICAgICAgICAgICAweDE3LDB4MzAsMHg1NCwweDdmLDB4MTQsMHhiZSwweGY0LDB4YmQsMHg5MSwweDNiLDB4ZTQsMHgzNiwweGE0LDB4NTAsMHg1YixcbiAgICAgICAgICAgICAgICAgICAgMHgzNywweDg5LDB4NWUsMHhjYywweGM3LDB4NzQsMHg1NCwweDMyLDB4MjAsMHgwOSwweDYzLDB4OTgsMHhiNywweGQ5LDB4YWYsXG4gICAgICAgICAgICAgICAgICAgIDB4N2YsMHhiMCwweDZjLDB4MjcsMHg0MywweGZlLDB4NTIsMHhlNiwweDFhLDB4ODgsMHg1OSwweDI1LDB4ZmMsMHhlYiwweDQzLFxuICAgICAgICAgICAgICAgICAgICAweDUwLDB4YzcsMHg2NSwweDQzLDB4YzEsMHg4NiwweDczLDB4NTgsMHg1MywweDNhLDB4Y2YsMHg3YSwweGEzLDB4MWQsMHg1NixcbiAgICAgICAgICAgICAgICAgICAgMHhjOCwweDRhLDB4ODAsMHg3MCwweGI3LDB4YmYsMHhmMiwweGEzLDB4ZWMsMHhlOCwweDc3LDB4MDUsMHgzMywweDA5LDB4OWQsXG4gICAgICAgICAgICAgICAgICAgIDB4YWEsMHhjYSwweGEwLDB4ZTEsMHg2NCwweDY0LDB4NmYsMHg3NiwweDk5LDB4NDEsMHg3NSwweDc4LDB4OTAsMHhmNiwweGU3LFxuICAgICAgICAgICAgICAgICAgICAweDIzLDB4ZTYsMHhlYywweDUwLDB4ZTUsMHg5OSwweGE4LDB4M2UsMHgxYSwweDRiLDB4YzksMHg4OCwweDU4LDB4NjYsMHhhZSxcbiAgICAgICAgICAgICAgICAgICAgMHgxYSwweDUzLDB4NWUsMHhlNCwweGI3LDB4ODYsMHhjZiwweGE2LDB4ZTUsMHhhZCwweGI0LDB4ODAsMHhhMCwweGYxLDB4MGQsXG4gICAgICAgICAgICAgICAgICAgIDB4OTYsMHhiOCwweDQxLDB4ZDAsMHgwNywweDlhLDB4MjEsMHg4ZCwweDUwLDB4N2YsMHg0ZiwweDczLDB4MTMsMHhhMiwweGUyLFxuICAgICAgICAgICAgICAgICAgICAweDAyLDB4MDcsMHhjMywweGEzLDB4MGYsMHgwOSwweDE4LDB4N2YsMHhmNywweDZiLDB4OTAsMHg3MCwweGMwLDB4ZjksMHgwYyxcbiAgICAgICAgICAgICAgICAgICAgMHg2NywweDhkLDB4OWQsMHgxNCwweGI2LDB4OWQsMHgzMiwweDgyLDB4ZDAsMHhiNSwweGM2LDB4NTcsMHhmMCwweDkxLDB4ZDksXG4gICAgICAgICAgICAgICAgICAgIDB4YzMsMHgyNiwweGFlLDB4OWYsMHhhOSwweDY3LDB4NDksMHg5NiwweDVjLDB4MDcsMHgzZSwweDQ3LDB4NWMsMHhlZCwweDYwLFxuICAgICAgICAgICAgICAgICAgICAweDA3LDB4YWMsMHg2YV0pXTtcbiAgdmFyIERTQXNlY01QSXN0cnMgPSBbdXRpbC5iaW4yc3RyKFsweDAxLDB4MDAsMHg5YiwweDU4LDB4YTgsMHhmNCwweDA0LDB4YjEsMHhkNSwweDE0LDB4MDksMHhlMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZTEsMHhhMSwweDhhLDB4MGIsMHhhMywweGMzLDB4YTMsMHg2NiwweGFhLDB4MjcsMHg5OSwweDUwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxYywweDRkLDB4YmEsMHgyNCwweGVlLDB4ZGYsMHhkZiwweGI4LDB4OGUsMHg4ZV0pXTtcbiAgICAgICAgICAgIFxuICB2YXIgRWxnYW1hbHB1Yk1QSXN0cnMgPSBcbiAgICAgICAgICBbdXRpbC5iaW4yc3RyKFsweDA4LDB4MDAsMHhlYSwweGNjLDB4YmUsMHhlMiwweGU0LDB4NWEsMHg1MSwweDE4LDB4OTMsMHhhMSwweDEyLDB4MmYsXG4gICAgICAgICAgICAgICAgICAgICAweDAwLDB4OTksMHg0MiwweGQ4LDB4NWMsMHgxYywweDJmLDB4YjYsMHgzYywweGQ5LDB4OTQsMHg2MSwweGI0LDB4NTUsXG4gICAgICAgICAgICAgICAgICAgICAweDhkLDB4NGUsMHg3MywweGU2LDB4NjksMHhiYywweDFkLDB4MzMsMHhlMywweDJkLDB4OTEsMHgyMywweDY5LDB4OTUsXG4gICAgICAgICAgICAgICAgICAgICAweDk4LDB4ZDcsMHgxOCwweDVhLDB4YWYsMHhhNywweDkzLDB4YzYsMHgwNSwweDkzLDB4M2EsMHhjNywweGVhLDB4ZDAsXG4gICAgICAgICAgICAgICAgICAgICAweGIxLDB4YTksMHhjNywweGFiLDB4NDEsMHg4OSwweGM4LDB4MzgsMHg5OSwweGRjLDB4MWEsMHg1NywweDM1LDB4MWEsXG4gICAgICAgICAgICAgICAgICAgICAweDI3LDB4NjIsMHg0MCwweDcxLDB4OWYsMHgzNiwweDFjLDB4NmQsMHgxOCwweDFjLDB4OTMsMHhmNywweGJhLDB4MzUsXG4gICAgICAgICAgICAgICAgICAgICAweDA2LDB4ZWQsMHgzMCwweGI4LDB4ZDksMHg4YSwweDdjLDB4MDMsMHhhZiwweGJhLDB4NDAsMHgxZiwweDYyLDB4ZjEsXG4gICAgICAgICAgICAgICAgICAgICAweDZkLDB4ODcsMHgyYywweGE2LDB4MmUsMHg0NiwweGIwLDB4YWEsMHhiYywweGJjLDB4OTMsMHhmYSwweDliLDB4NDcsXG4gICAgICAgICAgICAgICAgICAgICAweDNmLDB4NzAsMHgxZiwweDJhLDB4YzIsMHg2NiwweDljLDB4N2MsMHg2OSwweGUwLDB4MmIsMHgwNSwweGVlLDB4YjcsXG4gICAgICAgICAgICAgICAgICAgICAweGE3LDB4N2YsMHhmMywweDIxLDB4NDgsMHg4NSwweGMyLDB4OTUsMHg1ZiwweDZmLDB4MWUsMHhiMywweDliLDB4OTcsXG4gICAgICAgICAgICAgICAgICAgICAweGY4LDB4MTQsMHhjMywweGZmLDB4NGQsMHg5NywweDI1LDB4MjksMHg5NCwweDQxLDB4NGIsMHg5MCwweGQ4LDB4YmEsXG4gICAgICAgICAgICAgICAgICAgICAweDcxLDB4NDUsMHg0YiwweDFlLDB4MmYsMHhjYSwweDgyLDB4NWYsMHg1NiwweDc3LDB4ZTksMHhkMywweDg4LDB4NWQsXG4gICAgICAgICAgICAgICAgICAgICAweDhiLDB4ZWMsMHg5MiwweDhiLDB4OGEsMHgyMywweDg4LDB4MDUsMHhmOCwweDJjLDB4YTgsMHhmMSwweDcwLDB4NzYsXG4gICAgICAgICAgICAgICAgICAgICAweGU3LDB4YmYsMHg3NSwweGE4LDB4MzEsMHgxNCwweDhlLDB4NzYsMHhjOCwweDAxLDB4YTYsMHgyNSwweDI3LDB4NDksXG4gICAgICAgICAgICAgICAgICAgICAweGFmLDB4ZGMsMHhmNCwweGY2LDB4ZjQsMHhjZSwweDkwLDB4ODQsMHgxNSwweDJiLDB4NGQsMHhiMywweGNjLDB4NzcsXG4gICAgICAgICAgICAgICAgICAgICAweGRiLDB4NjUsMHg3MSwweDc1LDB4ZDMsMHgwMCwweDFkLDB4MjIsMHhjNSwweDQyLDB4MmYsMHg1MSwweGZhLDB4N2IsXG4gICAgICAgICAgICAgICAgICAgICAweGViLDB4NmUsMHgwMywweGQ5LDB4NDEsMHhkZCwweDJkLDB4MWEsMHhkZCwweDA3LDB4NzQsMHg4YiwweGI3LDB4YTIsXG4gICAgICAgICAgICAgICAgICAgICAweGZhLDB4YjIsMHg1OSwweDBlLDB4MGUsMHg5NCwweDdjLDB4MDAsMHhhZCwweDk1LDB4MjMsMHg0MiwweDkxLDB4MTgsXG4gICAgICAgICAgICAgICAgICAgICAweDRjLDB4OTcsMHhmMSwweDI3LDB4NjIsMHg3N10pLFxuICAgICAgIHV0aWwuYmluMnN0cihbMHgwMCwweDAzLDB4MDVdKSxcbiAgICAgICB1dGlsLmJpbjJzdHIoWzB4MDcsMHhmZiwweDU3LDB4MTksMHg3NiwweGZjLDB4MDksMHg2YSwweDdhLDB4ZjcsMHhiYSwweGIyLDB4NDIsMHhiZixcbiAgICAgICAgICAgICAgICAgICAgIDB4Y2QsMHgyYiwweGMxLDB4MWEsMHg3OSwweDI1LDB4OGMsMHhhZCwweGY0LDB4M2EsMHgwYSwweDdhLDB4OWIsMHg0YyxcbiAgICAgICAgICAgICAgICAgICAgIDB4NDYsMHgzYywweGUwLDB4NGYsMHhjYywweDZlLDB4ZTUsMHg3YSwweDMzLDB4M2EsMHg0ZSwweDgwLDB4Y2IsMHhkMyxcbiAgICAgICAgICAgICAgICAgICAgIDB4NjIsMHhkNywweDhmLDB4ZTIsMHhjOCwweGIwLDB4ZDAsMHhjYiwweDQ5LDB4YzksMHg5ZSwweDJkLDB4OTcsMHgxNixcbiAgICAgICAgICAgICAgICAgICAgIDB4M2EsMHg3ZCwweGIxLDB4ZTEsMHhkMywweGQ5LDB4ZDcsMHgzZiwweDIwLDB4NjAsMHhlMywweDNlLDB4NzcsMHhlYSxcbiAgICAgICAgICAgICAgICAgICAgIDB4MGMsMHhlNCwweDdiLDB4ZjAsMHgzOSwweDFhLDB4MGQsMHhkOSwweDhmLDB4NzMsMHhkMiwweDUxLDB4YjgsMHgwYyxcbiAgICAgICAgICAgICAgICAgICAgIDB4MGUsMHgxNSwweDFlLDB4YWQsMHg3YywweGQ4LDB4OWQsMHg3NCwweDZlLDB4YTIsMHgxNywweDZiLDB4NTgsMHgxNCxcbiAgICAgICAgICAgICAgICAgICAgIDB4MmIsMHhiNywweGFkLDB4OGEsMHhkNywweDY2LDB4YzAsMHhkZiwweGVhLDB4MmQsMHhmYywweGM0LDB4NmUsMHg2OCxcbiAgICAgICAgICAgICAgICAgICAgIDB4YjYsMHg0YywweDlhLDB4MTYsMHhhNCwweDNkLDB4YzIsMHgyNiwweDBjLDB4YjcsMHhkNCwweDEzLDB4N2IsMHgyMixcbiAgICAgICAgICAgICAgICAgICAgIDB4ZmQsMHg4NCwweGQ3LDB4MGYsMHhkYywweDQyLDB4NzUsMHgwNSwweDg1LDB4MjksMHgwMCwweDMxLDB4MWQsMHhlYyxcbiAgICAgICAgICAgICAgICAgICAgIDB4NGUsMHgyMiwweDhiLDB4ZjYsMHgzNywweDgzLDB4NDUsMHhlNSwweGIzLDB4MzEsMHg2MSwweDJjLDB4MDIsMHhhMSxcbiAgICAgICAgICAgICAgICAgICAgIDB4YzYsMHg5ZCwweGVhLDB4YmEsMHgzZCwweDhhLDB4YWIsMHgwZiwweDYxLDB4NWUsMHgxNCwweDY0LDB4NjksMHgxZSxcbiAgICAgICAgICAgICAgICAgICAgIDB4YTAsMHgxNSwweDQ4LDB4ODYsMHhlNSwweDExLDB4MDYsMHhlOCwweGRlLDB4MzQsMHhjNywweGE3LDB4M2QsMHgzNSxcbiAgICAgICAgICAgICAgICAgICAgIDB4ZDEsMHg3NiwweGMyLDB4YmUsMHgwMSwweDgyLDB4NjEsMHg4ZCwweGU3LDB4N2UsMHgyOCwweDFkLDB4NGUsMHg4YyxcbiAgICAgICAgICAgICAgICAgICAgIDB4YjksMHhlOCwweDdlLDB4YTQsMHg1ZiwweGE2LDB4M2EsMHg5ZSwweDVkLDB4YWMsMHhmMywweDYwLDB4MjIsMHgxNCxcbiAgICAgICAgICAgICAgICAgICAgIDB4ZDUsMHhkNSwweGJlLDB4MWYsMHhmMCwweDE5LDB4ZTYsMHg4MSwweGZkLDB4NWQsMHhlMSwweGY4LDB4NzYsMHg1ZixcbiAgICAgICAgICAgICAgICAgICAgIDB4ZTMsMHhkYSwweGJhLDB4MTksMHhmMywweGNiLDB4MTAsMHhhMCwweDZiLDB4ZDAsMHgyZCwweGJlLDB4NDAsMHg0MixcbiAgICAgICAgICAgICAgICAgICAgIDB4N2IsMHg5YiwweDE1LDB4YTQsMHgyZCwweGVjLDB4Y2YsMHgwOSwweGQ2LDB4ZTMsMHg5MiwweGMzLDB4OGQsMHg2NSxcbiAgICAgICAgICAgICAgICAgICAgIDB4NmIsMHg2MCwweDk3LDB4ZGEsMHg2YiwweGNhXSldO1xuXG4gIHZhciBFbGdhbWFsc2VjTVBJc3RycyA9IFtcbiAgICAgICAgICAgICB1dGlsLmJpbjJzdHIoWzB4MDEsMHg1MiwweDAyLDB4ODAsMHg4NywweGY2LDB4ZTQsMHg0OSwweGQ3LDB4MmUsMHgzZSwweGZlLDB4NjAsMHhiOSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4YTMsMHgyYSwweGYwLDB4NjcsMHg1OCwweGU5LDB4ZjYsMHg0NywweDgzLDB4ZGUsMHg3ZSwweGZiLDB4YmIsMHhiZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZGYsMHg0OCwweDEyLDB4MWIsMHgwNiwweDdkLDB4MTMsMHhiYywweDNiLDB4NDksMHhmOSwweDg2LDB4ZDQsMHg1MyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZWQsMHgyZCwweDY4XSldO1xuXG4gIHZhciBSU0FwdWJNUElzID0gW107XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7XG4gICAgUlNBcHViTVBJc1tpXSA9IG5ldyBvcGVucGdwLm1waSgpO1xuICAgIFJTQXB1Yk1QSXNbaV0ucmVhZChSU0FwdWJNUElzdHJzW2ldKTtcbiAgfVxuXG4gIHZhciBSU0FzZWNNUElzID0gW107XG4gIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICBSU0FzZWNNUElzW2ldID0gbmV3IG9wZW5wZ3AubXBpKCk7XG4gICAgUlNBc2VjTVBJc1tpXS5yZWFkKFJTQXNlY01QSXN0cnNbaV0pO1xuICB9XG4gICAgXG4gIHZhciBEU0FzZWNNUElzID0gW107XG4gIGZvciAoaSA9IDA7IGkgPCAxOyBpKyspIHtcbiAgICBEU0FzZWNNUElzW2ldID0gbmV3IG9wZW5wZ3AubXBpKCk7XG4gICAgRFNBc2VjTVBJc1tpXS5yZWFkKERTQXNlY01QSXN0cnNbaV0pO1xuICB9XG4gICAgXG4gIHZhciBEU0FwdWJNUElzID0gW107XG4gIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICBEU0FwdWJNUElzW2ldID0gbmV3IG9wZW5wZ3AubXBpKCk7XG4gICAgRFNBcHViTVBJc1tpXS5yZWFkKERTQXB1Yk1QSXN0cnNbaV0pO1xuICB9XG4gIHZhciBFbGdhbWFsc2VjTVBJcyA9IFtdO1xuICBmb3IgKGkgPSAwOyBpIDwgMTsgaSsrKSB7XG4gICAgRWxnYW1hbHNlY01QSXNbaV0gPSBuZXcgb3BlbnBncC5tcGkoKTtcbiAgICBFbGdhbWFsc2VjTVBJc1tpXS5yZWFkKEVsZ2FtYWxzZWNNUElzdHJzW2ldKTtcbiAgfVxuICAgIFxuICB2YXIgRWxnYW1hbHB1Yk1QSXMgPSBbXTtcbiAgZm9yIChpID0gMDsgaSA8IDM7IGkrKykge1xuICAgIEVsZ2FtYWxwdWJNUElzW2ldID0gbmV3IG9wZW5wZ3AubXBpKCk7XG4gICAgRWxnYW1hbHB1Yk1QSXNbaV0ucmVhZChFbGdhbWFscHViTVBJc3Ryc1tpXSk7XG4gIH1cblxuICAvL09yaWdpbmFsbHkgd2UgcGFzc2VkIHB1YmxpYyBhbmQgc2VjcmV0IE1QSSBzZXBhcmF0ZWx5LCBub3cgdGhleSBhcmUgam9pbmVkLiBJcyB0aGlzIHdoYXQgd2Ugd2FudCB0byBkbyBsb25nIHRlcm0/XG4gIC8vIFJTQVxuICB2YXIgUlNBc2lnbmVkRGF0YSA9IG9wZW5wZ3Auc2lnbmF0dXJlLnNpZ24oMiwgMSwgUlNBcHViTVBJcy5jb25jYXQoUlNBc2VjTVBJcyksIFwiZm9vYmFyXCIpO1xuICB2YXIgUlNBc2lnbmVkRGF0YU1QSSA9IG5ldyBvcGVucGdwLm1waSgpO1xuICBSU0FzaWduZWREYXRhTVBJLnJlYWQoUlNBc2lnbmVkRGF0YSk7XG4gIHJlc3VsdFswXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3RpbmcgUlNBIFNpZ24gYW5kIFZlcmlmeVwiLFxuICAgICAgb3BlbnBncC5zaWduYXR1cmUudmVyaWZ5KDEsIDIsIFtSU0FzaWduZWREYXRhTVBJXSwgUlNBcHViTVBJcywgXCJmb29iYXJcIikpO1xuXG4gIC8vIERTQSBcbiAgdmFyIERTQXNpZ25lZERhdGEgPSBvcGVucGdwLnNpZ25hdHVyZS5zaWduKDIsIDE3LCBEU0FwdWJNUElzLmNvbmNhdChEU0FzZWNNUElzKSwgXCJmb29iYXJcIik7XG4gIFxuICB2YXIgRFNBbXNnTVBJcyA9IFtdO1xuICAgIERTQW1zZ01QSXNbMF0gPSBuZXcgb3BlbnBncC5tcGkoKTtcbiAgICBEU0Ftc2dNUElzWzFdID0gbmV3IG9wZW5wZ3AubXBpKCk7XG4gICAgRFNBbXNnTVBJc1swXS5yZWFkKERTQXNpZ25lZERhdGEuc3Vic3RyaW5nKDAsMzQpKTtcbiAgICBEU0Ftc2dNUElzWzFdLnJlYWQoRFNBc2lnbmVkRGF0YS5zdWJzdHJpbmcoMzQsNjgpKTtcbiAgcmVzdWx0WzFdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBEU0EgU2lnbiBhbmQgVmVyaWZ5XCIsXG4gICAgICBvcGVucGdwLnNpZ25hdHVyZS52ZXJpZnkoMTcsIDIsIERTQW1zZ01QSXMsIERTQXB1Yk1QSXMsIFwiZm9vYmFyXCIpKTtcbiAgXG4gIHZhciBzeW1tQWxnbyA9IFwiYWVzMjU2XCI7IC8vIEFFUzI1NlxuICB2YXIgc3ltbUtleSA9IG9wZW5wZ3AuZ2VuZXJhdGVTZXNzaW9uS2V5KHN5bW1BbGdvKTtcbiAgdmFyIHN5bW1lbmNEYXRhT0NGQiA9IG9wZW5wZ3AuY2ZiLmVuY3J5cHQob3BlbnBncC5nZXRQcmVmaXhSYW5kb20oc3ltbUFsZ28pLCBzeW1tQWxnbywgXCJmb29iYXJmb29iYXIxMjM0NTY3ODkwXCIsIHN5bW1LZXksIHRydWUpO1xuICB2YXIgc3ltbWVuY0RhdGFDRkIgID0gb3BlbnBncC5jZmIuZW5jcnlwdChvcGVucGdwLmdldFByZWZpeFJhbmRvbShzeW1tQWxnbyksIHN5bW1BbGdvLCBcImZvb2JhcmZvb2JhcjEyMzQ1Njc4OTBcIiwgc3ltbUtleSwgZmFsc2UpO1xuICBcbiAgcmVzdWx0WzJdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBzeW1tZXRyaWMgZW5jcnlwdCBhbmQgZGVjcnlwdCB3aXRoIE9wZW5QR1AgQ0ZCIHJlc3luY1wiLFxuICAgICAgb3BlbnBncC5jZmIuZGVjcnlwdChzeW1tQWxnbyxzeW1tS2V5LHN5bW1lbmNEYXRhT0NGQix0cnVlKSA9PSBcImZvb2JhcmZvb2JhcjEyMzQ1Njc4OTBcIik7XG4gIHJlc3VsdFszXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3Rpbmcgc3ltbWV0cmljIGVuY3J5cHQgYW5kIGRlY3J5cHQgd2l0aG91dCBPcGVuUEdQIENGQiByZXN5bmMgKHVzZWQgaW4gbW9kaWZpY2F0aW9uIGRldGVjdGlvbiBjb2RlIFxcXCJNRENcXFwiIHBhY2tldHMpXCIsXG4gICAgICBvcGVucGdwLmNmYi5kZWNyeXB0KHN5bW1BbGdvLHN5bW1LZXksc3ltbWVuY0RhdGFDRkIsZmFsc2UpID09IFwiZm9vYmFyZm9vYmFyMTIzNDU2Nzg5MFwiKTtcbiAgXG4gIHZhciBSU0FVbmVuY3J5cHRlZERhdGEgPSBuZXcgb3BlbnBncC5tcGkoKTtcbiAgUlNBVW5lbmNyeXB0ZWREYXRhLmZyb21CeXRlcyhvcGVucGdwLnBrY3MxLmVtZS5lbmNvZGUoc3ltbUtleSwgUlNBcHViTVBJc1swXS5ieXRlTGVuZ3RoKCkpKTtcbiAgdmFyIFJTQUVuY3J5cHRlZERhdGEgPSBvcGVucGdwLnB1YmxpY0tleUVuY3J5cHQoXCJyc2FfZW5jcnlwdF9zaWduXCIsIFJTQXB1Yk1QSXMsIFJTQVVuZW5jcnlwdGVkRGF0YSk7XG5cbiAgcmVzdWx0WzRdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBhc3ltbWV0cmljIGVuY3J5cHQgYW5kIGRlY3J5cHQgdXNpbmcgUlNBIHdpdGggZW1lX3BrY3MxIHBhZGRpbmdcIixcbiAgICAgIG9wZW5wZ3AucGtjczEuZW1lLmRlY29kZShvcGVucGdwLnB1YmxpY0tleURlY3J5cHQoXCJyc2FfZW5jcnlwdF9zaWduXCIsIFJTQXB1Yk1QSXMuY29uY2F0KFJTQXNlY01QSXMpLCBSU0FFbmNyeXB0ZWREYXRhKS53cml0ZSgpLnN1YnN0cmluZygyKSwgUlNBcHViTVBJc1swXS5ieXRlTGVuZ3RoKCkpID09IHN5bW1LZXkpO1xuXG4gIHZhciBFbGdhbWFsVW5lbmNyeXB0ZWREYXRhID0gbmV3IG9wZW5wZ3AubXBpKCk7XG4gIEVsZ2FtYWxVbmVuY3J5cHRlZERhdGEuZnJvbUJ5dGVzKG9wZW5wZ3AucGtjczEuZW1lLmVuY29kZShzeW1tS2V5LCBFbGdhbWFscHViTVBJc1swXS5ieXRlTGVuZ3RoKCkpKTtcbiAgdmFyIEVsZ2FtYWxFbmNyeXB0ZWREYXRhID0gb3BlbnBncC5wdWJsaWNLZXlFbmNyeXB0KFwiZWxnYW1hbFwiLCBFbGdhbWFscHViTVBJcywgRWxnYW1hbFVuZW5jcnlwdGVkRGF0YSk7XG5cbiAgcmVzdWx0WzVdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBhc3ltbWV0cmljIGVuY3J5cHQgYW5kIGRlY3J5cHQgdXNpbmcgRWxnYW1hbCB3aXRoIGVtZV9wa2NzMSBwYWRkaW5nXCIsXG4gICAgICBvcGVucGdwLnBrY3MxLmVtZS5kZWNvZGUob3BlbnBncC5wdWJsaWNLZXlEZWNyeXB0KFwiZWxnYW1hbFwiLCBFbGdhbWFscHViTVBJcy5jb25jYXQoRWxnYW1hbHNlY01QSXMpLCBFbGdhbWFsRW5jcnlwdGVkRGF0YSkud3JpdGUoKS5zdWJzdHJpbmcoMiksIEVsZ2FtYWxwdWJNUElzWzBdLmJ5dGVMZW5ndGgoKSkgPT0gc3ltbUtleSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn0pO1xuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJUZXN0aW5nIG9mIGJpbmFyeSBzaWduYXR1cmUgY2hlY2tpbmdcIiwgZnVuY3Rpb24oKSB7XG4gIHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vJyk7XG4gIHZhciBrZXlyaW5nID0gcmVxdWlyZSgnLi4vLi4vc3JjL29wZW5wZ3Aua2V5cmluZy5qcycpO1xuICB2YXIgcmVzdWx0ID0gW107XG4gIHZhciBwcml2X2tleSA9IG9wZW5wZ3AucmVhZEFybW9yZWRQYWNrZXRzKFtcbiAgICAgICAgJy0tLS0tQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS0nLFxuICAgICAgICAnVmVyc2lvbjogR251UEcgdjEuNC4xMSAoR05VL0xpbnV4KScsXG4gICAgICAgICcnLFxuICAgICAgICAnbFFIaEJGRVJuck1SQkFEbU0waElma0kzeW9zamdiV285djBMbnIzQ0NFKzhLc01zemdWUytoQnUwWGZHcmFLbScsXG4gICAgICAgICdpdmNBMmFhSmltSHFWWU9QN2dFbndGQXhIQkJwZVRKY3U1d3pDRnlKd0VZcVZlUzNubmFJaEJQcGxTRjE0RHVmJyxcbiAgICAgICAgJ2k2YkI5UlY3S3hWQWc2YXVubU0ydEF1dHFDK2EweTJyRGFmN2prSm9aOWdXSmUyekkrdnJhRDZmaXdDZ3h2SG8nLFxuICAgICAgICAnM0lnVUxCOVJxSXFwTG9NZ1hmY2pDK2NELzFqZUpsS1JtK243MXJ5WXdUL0VDS3NzcEZ6N1MzNno2cTNYeVM4UScsXG4gICAgICAgICdRZnJzVXoycDFmYkZpY3ZKd0lPSjhCMjBKL04yL25pdDRQMGdCVVRVeHYzUUVhN1hDTS81Ni94ckdreUJ6c2NXJyxcbiAgICAgICAgJ0F6Qm95L0FLOUs3R042ejEzUm96dUFTNjBGMXhPN01RYzZZaTJWVTNlQVNEUUVLaXlML1ViZi9zL3JrWitzR2onLFxuICAgICAgICAneUppekJBQ3R3Q2JRekErejlYQlpOVWF0NU5QZ2NaejVRZWgxbndGOU54bnI2cHlCdjd0a3JMaC8zZ3hSR0hxRycsXG4gICAgICAgICcwNjNkTWJVazhwbVVjSnpCVXlSc05pSVBEb0VVc0xqWTV6bVpabXAvd2FBaHBSRXNuSzI5V0xDYnFMZHBVb3JzJyxcbiAgICAgICAgJ2MxSkpCc09ia0ExSU04VFpZOFlVbXZzTUV2QkxDQ2FudUtwY2xaWlhxZVJBZU9ISjB2NERBd0s4V2Z1VGU1QisnLFxuICAgICAgICAnTTJCT09lWmJOOEJwZmlBMWwvL2ZNTUhMUlMzVXZiTEJ2NFAxKzRTeXZoeVlUUjdNNzZRMHhQYzAzTUZPV0hMKycsXG4gICAgICAgICdTOVZ1bWJRV1ZHVnpkRElnUEhSbGMzUXlRSFJsYzNRdVkyOXRQb2hpQkJNUkFnQWlCUUpSRVo2ekFoc0RCZ3NKJyxcbiAgICAgICAgJ0NBY0RBZ1lWQ0FJSkNnc0VGZ0lEQVFJZUFRSVhnQUFLQ1JBUko1UUR5eGFlK01YTkFLQ3pXU0RSM3RNclRyRGInLFxuICAgICAgICAnVEFyaTczTjFYYjNqMUFDZlNsOXkrU0FhaDJxN0d2bWlSMSs2Ky9la3FKR2RBVmdFVVJHZXN4QUVBTmxwTVpqVycsXG4gICAgICAgICczM2pNeGxLSERkeVJGWHRLT3E4UnJlWGhxMDBwbG9ySGJnejl6RkVXbTRWRjUzK0UvS0dubUhHeVk1Q3k4VEt5JyxcbiAgICAgICAgJ1pqYXVlWlo5WHVHMGh1Wmc1SWY2OGlyRmZOWnR4ZEEyNmp2OC8vUGRaMFVqK1g2SjNSVmEycGVNTEREc3dUWUwnLFxuICAgICAgICAnT0wxWk8xZnhkdERENDBmZEFpSVoxUXlqd0VHMEFQdHo0MUVmQUFNRkJBQzUvZHRnQkJQdEhlOFVqREJhVWU0bicsXG4gICAgICAgICdOekh1VUJCcDZYRStIN2VxSE5GQ3VaQUo3eXFKTEdWSE5JYVFSNDE5Y055MDgvT08vK1lVUTdyZzc4THhqRml2JyxcbiAgICAgICAgJ0NIN0l6aGZVKzZ5dkVMU2JnUk1pY1k2RW5BUDJHVCtiMStNdEZOYTNsQkd0QkhjSmxhNTJjMnJUQUh0aFlaV2snLFxuICAgICAgICAnZlQ1UjVEbkp1UTJjSkhCTVM5SFd5UDREQXdLOFdmdVRlNUIrTTJDN2EvWUpTVXY2U2V4ZEdDYWlhVGNBbTZnLycsXG4gICAgICAgICdQdkE2aHcvRkx6SUVQNjdRY1FTU1RtaGZ0UUl3bmRkdDRTNE15SkpIM1U0ZkphRmZZUTF6Q25pWUpvaEpCQmdSJyxcbiAgICAgICAgJ0FnQUpCUUpSRVo2ekFoc01BQW9KRUJFbmxBUExGcDc0UWJNQW4zVjQ4NTd4d25POS8rdnpJVm5MOTNXM2swLzgnLFxuICAgICAgICAnQUtDOG9tWVBQb21OMUUvVUpGZlhkTERJTWk1TG9BPT0nLFxuICAgICAgICAnPUxTclcnLFxuICAgICAgICAnLS0tLS1FTkQgUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS0nXG4gICAgICBdLmpvaW4oXCJcXG5cIikpO1xuICB2YXIgcHViX2tleSA9IG9wZW5wZ3AucmVhZEFybW9yZWRQYWNrZXRzKFxuICAgICAgWyAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tJyxcbiAgICAgICAgJ1ZlcnNpb246IEdudVBHIHYxLjQuMTEgKEdOVS9MaW51eCknLFxuICAgICAgICAnJyxcbiAgICAgICAgJ21RR2lCRkVSbHc0UkJBRDZCbWNmMncxZHRVbXRDTGtkeGVxWkxBcmszdllvUUFqZGlieEEzZ1hWeXVyN2ZzV2InLFxuICAgICAgICAncm8walZiQkhxT0N0QzZqRHhFMmw1Mk5QOSt0VGxXZVZNYXFxTnZVRTQ3TFNhUHEyREdJOFd4MVJqNmJGM21UcycsXG4gICAgICAgICdvYllFd2hHYkdoL01oSm5NRTlBSE9EYXJ2azhBWmJ6bzArazFFd3JCV0Y2ZFRVQlBmcU83ckdVMmV3Q2c4MFdWJyxcbiAgICAgICAgJ3g1cHQzZXZqOHJSSzNqUThTTUtUTlJzRC8xUGhUZHhkWlRkWEFSQUZ6Y1cxVmFhcnVXVzBScjErWEhLS3dEQ3onLFxuICAgICAgICAnaTdIRTc2U085cWpuUWZaQ1pHNzVDZFF4STBoOEdGZU4zenNEcW1ob2IyaVN6MmFKMWtydGpNK2laMUZCRmQ1NycsXG4gICAgICAgICdPcUNWNndtazVJVDBSQk4xMlp6TVMxOVl2ek4vT05YSHJtVFpsS0V4ZDlNaDlSS0xlVk53K2JmNkpzS1FFemNZJyxcbiAgICAgICAgJ0p6RmtCQUNYOVgraERZY2hPLzJoaVR3eDRpT085RmhzdWg3ZUlXdW1CM2d0K2FVcG0xanJTYmFzL1FMVHltbWsnLFxuICAgICAgICAndVp1UVZYSTROdG5sdnpsTmdXdjRMNXM1UlU1V3FOR0c3V1NhS05kY3J2SlpSQzJkZ2JVSnQwNEo1Q0tyV3A2UicsXG4gICAgICAgICdhSVlhbC84MVV0MTc3OGxVMDFQRXQ1NjNUY1FuVUJsbmpVNU9SMjVLaGZTZU41Q1pZN1FVVkdWemRDQThkR1Z6JyxcbiAgICAgICAgJ2RFQjBaWE4wTG1OdmJUNklZZ1FURVFJQUlnVUNVUkdYRGdJYkF3WUxDUWdIQXdJR0ZRZ0NDUW9MQkJZQ0F3RUMnLFxuICAgICAgICAnSGdFQ0Y0QUFDZ2tRaWtEbFpLL1V2TFNzcGdDZmNOYU9wVGcxVzJ1Y1IxSndCYkJHdmFFUmZ1TUFuUmd0My9ycycsXG4gICAgICAgICdFcGxxRWFrTWNrQ3Rpa0VucHhZZScsXG4gICAgICAgICc9YjJMbicsXG4gICAgICAgICctLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tJ1xuICAgICAgXS5qb2luKFwiXFxuXCIpKTtcbiAgdmFyIG1zZyA9IG9wZW5wZ3AucmVhZEFybW9yZWRQYWNrZXRzKFtcbiAgICAgICAgJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLScsXG4gICAgICAgICdWZXJzaW9uOiBHbnVQRyB2MS40LjExIChHTlUvTGludXgpJyxcbiAgICAgICAgJycsXG4gICAgICAgICdoUUVPQTFONE9DU1NqRUNCRUFQL2RpREpDUW40ZTg4MTkzUGdxaGJmQWtvaGs5UlEwdjBNUG5YcEpiQ1JUSEtPJyxcbiAgICAgICAgJzhyOW54aUFyL1RRdjRaT2luZ1hkQXAySlpFb0U5cFh4WjNyMVVXZXcwNGN6eG1nSjhGUDF6dFpZV1ZGQVdGVmknLFxuICAgICAgICAnVGo5MzBUQkQ3TDFmWS9NRDRmSzZ4akVHN3o1R1Q4azR0bjRtTG0vUHBXTWJhcklnbGZNb3BUeTFNL3B5MmNJRCcsXG4gICAgICAgICcvMlNqN0lraDNVRmlHK3ptNHNWaVljNXJvTmJNeThpeGVvS2l4eGk5OU14OElOYTJjeE5mcWJhYmpibEZ5YzBaJyxcbiAgICAgICAgJ0J3bWJJYytaaVkybWVSTkk1eS90azBnUkQ3aFQ4NElYR0dsNi9tSDAwYnNYL2trV2RLR2VUdno4czVHOFJESGEnLFxuICAgICAgICAnWmE0SGdMYlhJdGtYL1FhcnZSUzlrdmtEMDF1akhmaisxWnZnbU9CdHROZlAwcDhCUUxJSUNxdmcxZVlEOWFQQicsXG4gICAgICAgICcrR3RPWjJGMytrNVZ5Qkw1eUluL3M2NVNCak5POEZxczNhTDB4K3A3czFjZlV6eDhKOGE4bldwcXEvcUlRSXFnJyxcbiAgICAgICAgJ1pKSDZNWlJLdVF3c2N3SDZOV2dzU1Z3Y25WQ0FYbllPcGJIeEZRK2o3UmJGLyt1aXVxVStERkgvUmQ1cGlrOGInLFxuICAgICAgICAnMERxbnAweWZlZnJralEwbnV2dWJnQjZSdjg5bUhwbnZ1SmZGSlJJbnBnNGxySHdMdlJ3ZHBOMkhEb3pGSGNLSycsXG4gICAgICAgICdhT1U9JyxcbiAgICAgICAgJz00aUd0JyxcbiAgICAgICAgJy0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0nXG4gICAgICBdLmpvaW4oXCJcXG5cIikpO1xuICAvL1RPRE8gbmVlZCBib3RoP1xuICBwcml2X2tleVswXS5kZWNyeXB0KFwiYWJjZFwiKTtcbiAgcHJpdl9rZXlbM10uZGVjcnlwdChcImFiY2RcIik7XG4gIG1zZ1swXS5kZWNyeXB0KHByaXZfa2V5WzNdKTtcbiAgbXNnWzFdLmRlY3J5cHQobXNnWzBdLnNlc3Npb25LZXlBbGdvcml0aG0sIG1zZ1swXS5zZXNzaW9uS2V5KTtcbiAgbXNnWzFdLnBhY2tldHNbMl0udmVyaWZ5KHB1Yl9rZXlbMF0sIG1zZ1sxXS5wYWNrZXRzWzFdKTtcbiAgcmVzdWx0WzBdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBzaWduYXR1cmUgY2hlY2tpbmcgb24gQ0FTVDUtZW5jaXBoZXJlZCBtZXNzYWdlXCIsXG4gICAgICAgICAgbXNnWzFdLnBhY2tldHNbMl0udmVyaWZpZWQgPT09IHRydWUpO1xuXG4gIC8vIGV4ZXJjaXNlcyB0aGUgR251UEcgczJrIHR5cGUgMTAwMSBleHRlbnNpb246XG4gIC8vIHRoZSBzZWNyZXRzIG9uIHRoZSBwcmltYXJ5IGtleSBoYXZlIGJlZW4gc3RyaXBwZWQuXG4gIHZhciBwcml2X2tleV9nbnVwZ19leHQgPSBvcGVucGdwLnJlYWRBcm1vcmVkUGFja2V0cyhbXG4gICAgICAgICctLS0tLUJFR0lOIFBHUCBQUklWQVRFIEtFWSBCTE9DSy0tLS0tJyxcbiAgICAgICAgJ1ZlcnNpb246IEdudVBHIHYxLjQuMTEgKEdOVS9MaW51eCknLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2xRR3FCRkVSbnJNUkJBRG1NMGhJZmtJM3lvc2pnYldvOXYwTG5yM0NDRSs4S3NNc3pnVlMraEJ1MFhmR3JhS20nLFxuICAgICAgICAnaXZjQTJhYUppbUhxVllPUDdnRW53RkF4SEJCcGVUSmN1NXd6Q0Z5SndFWXFWZVMzbm5hSWhCUHBsU0YxNER1ZicsXG4gICAgICAgICdpNmJCOVJWN0t4VkFnNmF1bm1NMnRBdXRxQythMHkyckRhZjdqa0pvWjlnV0plMnpJK3ZyYUQ2Zml3Q2d4dkhvJyxcbiAgICAgICAgJzNJZ1VMQjlScUlxcExvTWdYZmNqQytjRC8xamVKbEtSbStuNzFyeVl3VC9FQ0tzc3BGejdTMzZ6NnEzWHlTOFEnLFxuICAgICAgICAnUWZyc1V6MnAxZmJGaWN2SndJT0o4QjIwSi9OMi9uaXQ0UDBnQlVUVXh2M1FFYTdYQ00vNTYveHJHa3lCenNjVycsXG4gICAgICAgICdBekJveS9BSzlLN0dONnoxM1JvenVBUzYwRjF4TzdNUWM2WWkyVlUzZUFTRFFFS2l5TC9VYmYvcy9ya1orc0dqJyxcbiAgICAgICAgJ3lKaXpCQUN0d0NiUXpBK3o5WEJaTlVhdDVOUGdjWno1UWVoMW53RjlOeG5yNnB5QnY3dGtyTGgvM2d4UkdIcUcnLFxuICAgICAgICAnMDYzZE1iVWs4cG1VY0p6QlV5UnNOaUlQRG9FVXNMalk1em1aWm1wL3dhQWhwUkVzbksyOVdMQ2JxTGRwVW9ycycsXG4gICAgICAgICdjMUpKQnNPYmtBMUlNOFRaWThZVW12c01FdkJMQ0NhbnVLcGNsWlpYcWVSQWVPSEowdjREWlFKSFRsVUJ0QlpVJyxcbiAgICAgICAgJ1pYTjBNaUE4ZEdWemRESkFkR1Z6ZEM1amIyMCtpR0lFRXhFQ0FDSUZBbEVSbnJNQ0d3TUdDd2tJQndNQ0JoVUknLFxuICAgICAgICAnQWdrS0N3UVdBZ01CQWg0QkFoZUFBQW9KRUJFbmxBUExGcDc0eGMwQW9MTlpJTkhlMHl0T3NOdE1DdUx2YzNWZCcsXG4gICAgICAgICd2ZVBVQUo5S1gzTDVJQnFIYXJzYSthSkhYN3I3OTZTb2taMEJXQVJSRVo2ekVBUUEyV2t4bU5iZmVNekdVb2NOJyxcbiAgICAgICAgJzNKRVZlMG82cnhHdDVlR3JUU21XaXNkdURQM01VUmFiaFVYbmY0VDhvYWVZY2JKamtMTHhNckptTnE1NWxuMWUnLFxuICAgICAgICAnNGJTRzVtRGtoL3J5S3NWODFtM0YwRGJxTy96Lzg5MW5SU1A1Zm9uZEZWcmFsNHdzTU96Qk5nczR2Vms3Vi9GMicsXG4gICAgICAgICcwTVBqUjkwQ0loblZES1BBUWJRQSszUGpVUjhBQXdVRUFMbjkyMkFFRSswZDd4U01NRnBSN2ljM01lNVFFR25wJyxcbiAgICAgICAgJ2NUNGZ0Nm9jMFVLNWtBbnZLb2tzWlVjMGhwQkhqWDF3M0xUejg0Ny81aFJEdXVEdnd2R01XSzhJZnNqT0Y5VDcnLFxuICAgICAgICAncks4UXRKdUJFeUp4am9TY0EvWVpQNXZYNHkwVTFyZVVFYTBFZHdtVnJuWnphdE1BZTJGaGxhUjlQbEhrT2NtNScsXG4gICAgICAgICdEWndrY0V4TDBkYkkvZ01EQXJ4Wis1TjdrSDR6WUx0cjlnbEpTL3BKN0YwWUpxSnBOd0NicUQ4KzhEcUhEOFV2JyxcbiAgICAgICAgJ01nUS9ydEJ4QkpKT2FGKzFBakNkMTIzaExneklra2ZkVGg4bG9WOWhEWE1LZUpnbWlFa0VHQkVDQUFrRkFsRVInLFxuICAgICAgICAnbnJNQ0d3d0FDZ2tRRVNlVUE4c1dudmhCc3dDZmRYanpudkhDYzczLzYvTWhXY3YzZGJlVFQvd0FvTHlpWmc4KycsXG4gICAgICAgICdpWTNVVDlRa1Y5ZDBzTWd5TGt1ZycsXG4gICAgICAgICc9R1FzWScsXG4gICAgICAgICctLS0tLUVORCBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLScsXG4gICAgICBdLmpvaW4oXCJcXG5cIikpO1xuICBwcml2X2tleV9nbnVwZ19leHRbM10uZGVjcnlwdChcImFiY2RcIik7XG4gIG1zZ1swXS5kZWNyeXB0KHByaXZfa2V5X2dudXBnX2V4dFszXSk7XG4gIG1zZ1sxXS5kZWNyeXB0KG1zZ1swXS5zZXNzaW9uS2V5QWxnb3JpdGhtLCBtc2dbMF0uc2Vzc2lvbktleSk7XG4gIG1zZ1sxXS5wYWNrZXRzWzJdLnZlcmlmeShwdWJfa2V5WzBdLCBtc2dbMV0ucGFja2V0c1sxXSk7XG4gIHJlc3VsdFsxXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3RpbmcgR251UEcgc3RyaXBwZWQta2V5IGV4dGVuc2lvbnNcIixcbiAgICAgICAgICBtc2dbMV0ucGFja2V0c1syXS52ZXJpZmllZCA9PT0gdHJ1ZSk7XG5cbiAgLy8gRXhlcmNpc2VzIHRoZSBhYmlsaXR5IG9mIG9wZW5wZ3Bfa2V5cmluZy5nZXRQdWJsaWNLZXlzRm9yS2V5SWQgdG8gcmV0dXJuIHN1YmtleXNcbiAga2V5cmluZy5pbml0KCk7XG4gIGtleXJpbmcuaW1wb3J0UGFja2V0bGlzdChbXG4gICAgICAgICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0nLFxuICAgICAgICAnVmVyc2lvbjogR251UEcgdjEuNC4xMSAoR05VL0xpbnV4KScsXG4gICAgICAgICcnLFxuICAgICAgICAnbVFHaUJGRVJ2STRSQkFEME0vSEdnbEN0Vk5YUEY3MmVoVDhyaUFYcmwwclNlYzRSSkM2MUJoK1VBT2h4bjUrVScsXG4gICAgICAgICdmRGdvczVwMVNwSXpZbW4rTTg3Sm9TU1ZMQWpmYWtGazBnSGdSOUkzYnU3U0l3cTNCaWtrMVZ3M2dPK3lEU082JyxcbiAgICAgICAgJ1RLcExVRkdZRGlCU1NFMU1HZHhCYWRXTEUxaGxSZjVCMng2MmduR21qU3BTVmJseTMzUEZrb0RtcndDZzlyQXAnLFxuICAgICAgICAnUm1uY25GOUdoV2pPTEZrRW9RdzlZeDhFQU9zeHZxOElnNVoxZ2srWktmRFplZnRwSFJlM0ZkclJ0Ym5oeHZZWScsXG4gICAgICAgICc3eit3OXV6MUVwb1pVd0RSNUc0WDNoVHdKUTdsWG1JT3NrZy8rZVJNTEVBcUVZN2IvN3RXNlJhVUoyZDZFaHNpJyxcbiAgICAgICAgJ2RPUzg5Zkl4RWx3akFPblZPTTVTMjRmMEZEUVRUdG83UUJPb3hjTlRma0VKQ0hYU2xwb09VbUdBUDg1ZlhoM2wnLFxuICAgICAgICAneVBUR0JBQ0pmS2M3NlVuM1VXQzFzV0lSRHhZaXloM1pwWnlORXNrb1Y2RVNXOGpFSTFSbk1udjVUcmZHSkg1SycsXG4gICAgICAgICdFOGpXWDdUVG5vRnlQSnRCVGpsdWNBdGtRYVM0QmI3ZGcxTExqYTE3ekFxS05HT0pLMmI5ZmIyWitsblRqUGlZJyxcbiAgICAgICAgJ2k3RFBIMVhIbmZhRWV4amxoL1U3bVlhNVJyd0lwaFJ4Tmk4Z0N1eHY4NzRaTW1oRW43UVdWR1Z6ZERNZ1BIUmwnLFxuICAgICAgICAnYzNRelFIUmxjM1F1WTI5dFBvaGlCQk1SQWdBaUJRSlJFYnlPQWhzREJnc0pDQWNEQWdZVkNBSUpDZ3NFRmdJRCcsXG4gICAgICAgICdBUUllQVFJWGdBQUtDUkMwdThPME1vYTJKWXh5QUo5T2kyVWxjVVQwVkpOZ3dqeWwvVkY5WGNqZjlnQ2VKUHZ5JyxcbiAgICAgICAgJ2cvZnA0RUFVOE1KSWFOMnlNSThwTEZTNUFhSUVVUkc4bmhFRUFLVmdlTkR1WURQdWZMdUowR3JKVi9DYlhFamonLFxuICAgICAgICAnYUVQQTBpVFVxVjBuVENQZEFmUS9ubUUzZ2g1VWxOTXIvelNISitjNEZRaFlkTHJ6UkdET1N6VittZlBISDN0KycsXG4gICAgICAgICdZVngrd2F0MEJZd0FCcEhBdHNJdUxJVm8yUlFxWVpZSDg1dGF0d0JrbTcxSEhUM2ptbEVBdnI2TkZIMzgrdjNzJyxcbiAgICAgICAgJzN3NFdsMC9zZEh5YWVpU1hBS0N4SjRYMWVPZE43TDFycmJKb3pRL2dEQ0Z1VlFQL2RjVjZLc3NzOEF3NDQzakcnLFxuICAgICAgICAnQVlCTEhXaDZvNEdoQVk2L2gxa2lqRjB4RCt1Yyt0Tm1UUW5RaTF0RU9vVGVJWk1YblNSd3RrOFhFdUpra2JBUCcsXG4gICAgICAgICcrdXl2TWd5VjN3cms5emthVEFpbjducmpBRVJ4ZXpGT2RCRU90bkIxQ292Snh0TW4rUlJ4YU1FR3BDNEduRVR5JyxcbiAgICAgICAgJ041KzZGa0x1TGNOWGlDUVA3NWFqek9BTjFhSUQvanVOalVOcEJiTnBmcUJWN2oxSytLbjBuOUhZVHlRbDlnaHknLFxuICAgICAgICAnMDI2Ky80YzhhZzJIVitiZzNCRDdjMlZUVnU5eEJPREhzZnUwcThRbC9RQjlXOHRtWXVnVTZEZVhNSGFlV1BVSCcsXG4gICAgICAgICdwaDk4Z3VNOWtGMnlISWlSQnZBZDVpN3dPanduK0kvSXI2bkJSMnl4SjNwMzFDRFVuVWxialRQWWc3bXRRdkhXJyxcbiAgICAgICAgJ0VZMkNwNFNXaUpFRUdCRUNBQWtGQWxFUnZKNENHd0lBVWdrUXRMdkR0REtHdGlWSElBUVpFUUlBQmdVQ1VSRzgnLFxuICAgICAgICAnbmdBS0NSQU1pTWVSMjk2WTJTanlBSjlWM3dSSkoyU3phenFhbDRraFdHZkx1NVI2L3dDZlFRSVJEMjR5VmR6OCcsXG4gICAgICAgICcyYSsyZUNyd3lBTFQyR0FpaEFDZlMwbldNM2EwZ3RJVHFuZ3BKc1J3cytFcCtlSUFuMTVxRDJpdHV0eE5iOE5JJyxcbiAgICAgICAgJ2JSMmdCQjVRbVZKMycsXG4gICAgICAgICc9cEdBNicsXG4gICAgICAgICctLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tJ1xuICAgICAgICBdLmpvaW4oXCJcXG5cIikpO1xuXG4gIHZhciBtc2cyID0gb3BlbnBncC5yZWFkQXJtb3JlZFBhY2tldHMoW1xuICAgICAgICAnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tJyxcbiAgICAgICAgJ1ZlcnNpb246IEdudVBHIHYxLjQuMTEgKEdOVS9MaW51eCknLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2tBMERBQUlSRElqSGtkdmVtTmtCckIxaUIyWnZieTUwZUhSUkViejNWRVZUVkNCRVFWUkJJREV5TXpRMU5vaEcnLFxuICAgICAgICAnQkFBUkFnQUdCUUpSRWJ6M0FBb0pFQXlJeDVIYjNwaloyVGNBbjMyTHBERXVIZTlRclNSbHl2U3VSRUtOT0Z3eicsXG4gICAgICAgICdBSjl6aDR6c0s0R0lQdUV1ODFZUE5tSHNqdTdEWWc9PScsXG4gICAgICAgICc9V2FTeCcsXG4gICAgICAgICctLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tJ1xuICAgICAgICBdLmpvaW4oXCJcXG5cIikpO1xuICB2YXIgcGFja2V0bGlzdHMgPSBrZXlyaW5nLmdldFBhY2tldGxpc3RzRm9yS2V5SWQobXNnMlswXS5zaWduaW5nS2V5SWQud3JpdGUoKSk7XG4gIHZhciBwdWJLZXkgPSBwYWNrZXRsaXN0c1swXTtcbiAgbXNnMlsyXS52ZXJpZnkocHViS2V5WzNdLCBtc2cyWzFdKTtcbiAgcmVzdWx0WzJdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBrZXlyaW5nIHB1YmxpYyBzdWJrZXkgc3VwcG9ydFwiLFxuICAgICAgICAgIHBhY2tldGxpc3RzICE9PSBudWxsICYmIFxuICAgICAgICAgIHBhY2tldGxpc3RzLmxlbmd0aCA9PSAxICYmIFxuICAgICAgICAgIG1zZzJbMl0udmVyaWZpZWQpO1xuICByZXR1cm4gcmVzdWx0O1xufSk7XG5cbiIsInZhciB1bml0ID0gcmVxdWlyZSgnLi4vdW5pdC5qcycpO1xuXG51bml0LnJlZ2lzdGVyKFwiRW5jcnlwdGlvbi9kZWNyeXB0aW9uXCIsIGZ1bmN0aW9uKCkge1xuICB2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLycpO1xuICB2YXIga2V5cmluZyA9IHJlcXVpcmUoJy4uLy4uL3NyYy9vcGVucGdwLmtleXJpbmcuanMnKTtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuXHR2YXIga2V5ID0gb3BlbnBncC5nZW5lcmF0ZUtleVBhaXIob3BlbnBncC5lbnVtcy5wdWJsaWNLZXkucnNhX2VuY3J5cHRfc2lnbiwgNTEyLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUZXN0IE1jVGVzdGluZ3RvbiA8dGVzdEBleGFtcGxlLmNvbT4nLCAnaGVsbG8gd29ybGQnKTtcblxuXHR2YXIgaW5mbyA9ICdcXG5wYXNzcGhyYXNlOiAnICsgcGFzc3BocmFzZSArICdcXG4nXG5cdFx0XHQrICd1c2VyaWQ6ICcgKyB1c2VyaWQgKyAnXFxuJ1xuXHRcdFx0KyAnbWVzc2FnZTogJyArIG1lc3NhZ2U7XG5cblx0aWYoIXByaXZfa2V5LmRlY3J5cHRTZWNyZXRNUElzKHBhc3NwaHJhc2UpKSB7XG5cdFx0cmV0dXJuIG5ldyB0ZXN0X3Jlc3VsdCgnR2VuZXJhdGluZyBhIGRlY3J5cHRhYmxlIHByaXZhdGUga2V5IGZhaWxlZCdcblx0XHRcdCsgaW5mbyxcblx0XHRcdGZhbHNlKTtcblx0fVxuXG5cdHZhciBlbmNyeXB0ZWQgPSBvcGVucGdwLndyaXRlX3NpZ25lZF9hbmRfZW5jcnlwdGVkX21lc3NhZ2UocHJpdl9rZXksXG5cdFx0cHViX2tleSwgbWVzc2FnZSk7XG5cblx0b3BlbnBncC5rZXlyaW5nLmltcG9ydFB1YmxpY0tleShrZXkucHVibGljS2V5QXJtb3JlZClcblxuXG5cdHZhciBtc2cgPSBvcGVucGdwLnJlYWRfbWVzc2FnZShlbmNyeXB0ZWQpO1xuXHR2YXIga2V5bWF0ID0gbnVsbDtcblx0dmFyIHNlc3NrZXkgPSBudWxsO1xuXG5cdC8vIEZpbmQgdGhlIHByaXZhdGUgKHN1YilrZXkgZm9yIHRoZSBzZXNzaW9uIGtleSBvZiB0aGUgbWVzc2FnZVxuXHRmb3IgKHZhciBpID0gMDsgaTwgbXNnWzBdLnNlc3Npb25LZXlzLmxlbmd0aDsgaSsrKSB7XG5cdFx0aWYgKHByaXZfa2V5LnByaXZhdGVLZXlQYWNrZXQucHVibGljS2V5LmdldEtleUlkKCkgPT0gbXNnWzBdLnNlc3Npb25LZXlzW2ldLmtleUlkLmJ5dGVzKSB7XG5cdFx0XHRrZXltYXQgPSB7IGtleTogcHJpdl9rZXksIGtleW1hdGVyaWFsOiBwcml2X2tleS5wcml2YXRlS2V5UGFja2V0fTtcblx0XHRcdHNlc3NrZXkgPSBtc2dbMF0uc2Vzc2lvbktleXNbaV07XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdFx0Zm9yICh2YXIgaiA9IDA7IGogPCBwcml2X2tleS5zdWJLZXlzLmxlbmd0aDsgaisrKSB7XG5cdFx0XHRpZiAocHJpdl9rZXkuc3ViS2V5c1tqXS5wdWJsaWNLZXkuZ2V0S2V5SWQoKSA9PSBtc2dbMF0uc2Vzc2lvbktleXNbaV0ua2V5SWQuYnl0ZXMpIHtcblx0XHRcdFx0a2V5bWF0ID0geyBrZXk6IHByaXZfa2V5LCBrZXltYXRlcmlhbDogcHJpdl9rZXkuc3ViS2V5c1tqXX07XG5cdFx0XHRcdHNlc3NrZXkgPSBtc2dbMF0uc2Vzc2lvbktleXNbaV07XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHZhciBkZWNyeXB0ZWQgPSAnJztcblx0aWYgKGtleW1hdCAhPT0gbnVsbCkge1xuXHRcdGlmICgha2V5bWF0LmtleW1hdGVyaWFsLmRlY3J5cHRTZWNyZXRNUElzKHBhc3NwaHJhc2UpKSB7XG5cdFx0XHRyZXR1cm4gbmV3IHRlc3RfcmVzdWx0KFwiUGFzc3dvcmQgZm9yIHNlY3JlY3Qga2V5IHdhcyBpbmNvcnJlY3QhXCIsIFxuXHRcdFx0XHQrIGluZm8sIGZhbHNlKTtcblx0XHR9XG5cblx0XHRkZWNyeXB0ZWQgPSBtc2dbMF0uZGVjcnlwdChrZXltYXQsIHNlc3NrZXkpO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBuZXcgdGVzdF9yZXN1bHQoXCJObyBwcml2YXRlIGtleSBmb3VuZCFcIiArIGluZm8sIGZhbHNlKTtcblx0fVxuXHRcdFxuXHRyZXN1bHQucHVzaChuZXcgdGVzdF9yZXN1bHQobWVzc2FnZSArICcgPT0gJyArIGRlY3J5cHRlZCArIGluZm8sIG1lc3NhZ2UgPT0gZGVjcnlwdGVkKSk7XG5cbiAgLy9yZXN1bHQucHVzaCh0ZXN0KCdwYXNzd29yZCcsICdUZXN0IE1jVGVzdGluZ3RvbiA8dGVzdEBleGFtcGxlLmNvbT4nLCAnaGVsbG8gd29ybGQnKSk7XG4gIC8vcmVzdWx0LnB1c2godGVzdCgn4peP4peP4peP4pePJywgJ+KZlOKZlOKZlOKZlCA8dGVzdEBleGFtcGxlLmNvbT4nLCAnxYLDpMOzxIcnKSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn0pO1xuIiwiXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vdW5pdC5qcycpO1xuXG5yZXF1aXJlKCcuL2NyeXB0by9oYXNoL3NoYS5qcycpO1xucmVxdWlyZSgnLi9jcnlwdG8vaGFzaC9tZDUuanMnKTtcbnJlcXVpcmUoJy4vY3J5cHRvL2hhc2gvcmlwZW1kLmpzJyk7XG5cbnJlcXVpcmUoJy4vY3J5cHRvL2NpcGhlci9hZXMuanMnKTtcbnJlcXVpcmUoJy4vY3J5cHRvL2NpcGhlci9ibG93ZmlzaC5qcycpO1xucmVxdWlyZSgnLi9jcnlwdG8vY2lwaGVyL2Nhc3Q1LmpzJyk7XG5yZXF1aXJlKCcuL2NyeXB0by9jaXBoZXIvZGVzLmpzJyk7XG5yZXF1aXJlKCcuL2NyeXB0by9jaXBoZXIvdHdvZmlzaC5qcycpO1xuXG5yZXF1aXJlKCcuL2NyeXB0by9vcGVucGdwLmNyeXB0by5qcycpO1xucmVxdWlyZSgnLi9jcnlwdG8vb3BlbnBncC5zaWdjaGVjay5qcycpO1xuXG5yZXF1aXJlKCcuL2dlbmVyYWwvb3BlbnBncC5iYXNpYy5qcycpO1xuIiwidmFyIHByb2Nlc3M9cmVxdWlyZShcIl9fYnJvd3NlcmlmeV9wcm9jZXNzXCIpO1xubW9kdWxlLmV4cG9ydHMgPSB7XG5cdHRlc3RzOiBbXSxcblx0cmVnaXN0ZXI6IGZ1bmN0aW9uKHN0cl90aXRsZSwgZnVuY19ydW50ZXN0KSB7XG5cdFx0dGhpcy50ZXN0cy5wdXNoKHsgdGl0bGU6IHN0cl90aXRsZSwgcnVuOiBmdW5jX3J1bnRlc3QgfSk7XG5cdH0sXG5cdFxuXHRydW46IGZ1bmN0aW9uKCkge1xuXHRcdHZhciB0ZXN0ID0gdGhpcy50ZXN0cy5zaGlmdCgpO1xuXG5cdFx0dmFyIHJlc3VsdCA9IHtcblx0XHRcdHRpdGxlOiB0ZXN0LnRpdGxlXG5cdFx0fTtcblxuXG5cdFx0cmVzdWx0LnRlc3RzID0gdGVzdC5ydW4oKTtcblxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH0sXG5cblx0cnVuX2FsbDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIHBhc3NlZCA9IHRydWU7XG5cblx0XHR3aGlsZSh0aGlzLnRlc3RzLmxlbmd0aCA+IDApIHtcblx0XHRcdHZhciByZXN1bHQgPSB0aGlzLnJ1bigpO1xuXG5cdFx0XHRjb25zb2xlLmxvZygnVGVzdDogJyArIHJlc3VsdC50aXRsZSk7XG5cblx0XHRcdGZvcih2YXIgaSBpbiByZXN1bHQudGVzdHMpIHtcblxuXHRcdFx0XHR2YXIgcmVzID0gcmVzdWx0LnRlc3RzW2ldLnJlc3VsdCA/XG5cdFx0XHRcdFx0J1NVQ0NFU1MnIDogJ0ZBSUxFRCc7XG5cblx0XHRcdFx0Y29uc29sZS5sb2cocmVzdWx0LnRlc3RzW2ldLmRlc2NyaXB0aW9uICsgJyAnICsgcmVzKTtcblxuXHRcdFx0XHRwYXNzZWQgPSBwYXNzZWQgJiYgcmVzdWx0LnRlc3RzW2ldLnJlc3VsdDtcblx0XHRcdH1cdFx0XHRcdFxuXHRcdH1cblxuXHRcdGlmKCFwYXNzZWQpIHByb2Nlc3MuZXhpdCgxKTtcblx0fSxcblx0XHRcblx0cmVzdWx0OiBmdW5jdGlvbihzdHJfZGVzY3JpcHRpb24sIGJvb2xlYW5fcmVzdWx0KSB7XG5cdFx0dGhpcy5kZXNjcmlwdGlvbiA9IHN0cl9kZXNjcmlwdGlvbjtcblx0XHR0aGlzLnJlc3VsdCA9IGJvb2xlYW5fcmVzdWx0O1xuXHR9XG59XG5cbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbnByb2Nlc3MubmV4dFRpY2sgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBjYW5TZXRJbW1lZGlhdGUgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5zZXRJbW1lZGlhdGU7XG4gICAgdmFyIGNhblBvc3QgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5wb3N0TWVzc2FnZSAmJiB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lclxuICAgIDtcblxuICAgIGlmIChjYW5TZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChmKSB7IHJldHVybiB3aW5kb3cuc2V0SW1tZWRpYXRlKGYpIH07XG4gICAgfVxuXG4gICAgaWYgKGNhblBvc3QpIHtcbiAgICAgICAgdmFyIHF1ZXVlID0gW107XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICBpZiAoZXYuc291cmNlID09PSB3aW5kb3cgJiYgZXYuZGF0YSA9PT0gJ3Byb2Nlc3MtdGljaycpIHtcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICBpZiAocXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm4gPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdHJ1ZSk7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgICAgICBxdWV1ZS5wdXNoKGZuKTtcbiAgICAgICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgncHJvY2Vzcy10aWNrJywgJyonKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dFRpY2soZm4pIHtcbiAgICAgICAgc2V0VGltZW91dChmbiwgMCk7XG4gICAgfTtcbn0pKCk7XG5cbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuIl19 +//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlcyI6WyIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jb21wcmVzc2lvbi9qeGcuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vY2ZiLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL2NpcGhlci9hZXMuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vY2lwaGVyL2Jsb3dmaXNoLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL2NpcGhlci9jYXN0NS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9jaXBoZXIvZGVzLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL2NpcGhlci9pbmRleC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9jaXBoZXIvdHdvZmlzaC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9jcnlwdG8uanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vaGFzaC9pbmRleC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9oYXNoL21kNS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9oYXNoL3JpcGUtbWQuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vaGFzaC9zaGEuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vaW5kZXguanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vcGtjczEuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vcHVibGljX2tleS9kc2EuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vcHVibGljX2tleS9lbGdhbWFsLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvaW5kZXguanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9jcnlwdG8vcHVibGljX2tleS9qc2JuLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL3B1YmxpY19rZXkvcnNhLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvY3J5cHRvL3JhbmRvbS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2NyeXB0by9zaWduYXR1cmUuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9lbmNvZGluZy9hcm1vci5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2VuY29kaW5nL2Jhc2U2NC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL2VudW1zLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvaW5kZXguanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9vcGVucGdwLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvb3BlbnBncC5rZXlyaW5nLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L2FsbF9wYWNrZXRzLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L2NvbXByZXNzZWQuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvaW5kZXguanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvbGl0ZXJhbC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3BhY2tldC9tYXJrZXIuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvb25lX3Bhc3Nfc2lnbmF0dXJlLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3BhY2tldC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3BhY2tldC9wYWNrZXRsaXN0LmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3B1YmxpY19rZXkuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvcHVibGljX2tleV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvcHVibGljX3N1YmtleS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3BhY2tldC9zZWNyZXRfa2V5LmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3NlY3JldF9zdWJrZXkuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy9wYWNrZXQvc2lnbmF0dXJlLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3N5bV9lbmNyeXB0ZWRfaW50ZWdyaXR5X3Byb3RlY3RlZC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3BhY2tldC9zeW1fZW5jcnlwdGVkX3Nlc3Npb25fa2V5LmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3N5bW1ldHJpY2FsbHlfZW5jcnlwdGVkLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3RydXN0LmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3VzZXJfYXR0cmlidXRlLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvcGFja2V0L3VzZXJpZC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3R5cGUva2V5aWQuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3NyYy90eXBlL21waS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvc3JjL3R5cGUvczJrLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC9zcmMvdXRpbC91dGlsLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC90ZXN0L2NyeXB0by9jaXBoZXIvYWVzLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC90ZXN0L2NyeXB0by9jaXBoZXIvYmxvd2Zpc2guanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3Rlc3QvY3J5cHRvL2NpcGhlci9jYXN0NS5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvdGVzdC9jcnlwdG8vY2lwaGVyL2Rlcy5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvdGVzdC9jcnlwdG8vY2lwaGVyL3R3b2Zpc2guanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3Rlc3QvY3J5cHRvL2hhc2gvbWQ1LmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC90ZXN0L2NyeXB0by9oYXNoL3JpcGVtZC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvdGVzdC9jcnlwdG8vaGFzaC9zaGEuanMiLCIvVXNlcnMvemV1cy9Eb2N1bWVudHMvR2VuZXJhbC9Qcm9qZWN0cy9vcGVucGdwanMvZ2l0L3Rlc3QvY3J5cHRvL29wZW5wZ3AuY3J5cHRvLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC90ZXN0L2NyeXB0by9vcGVucGdwLnNpZ2NoZWNrLmpzIiwiL1VzZXJzL3pldXMvRG9jdW1lbnRzL0dlbmVyYWwvUHJvamVjdHMvb3BlbnBncGpzL2dpdC90ZXN0L2dlbmVyYWwvb3BlbnBncC5iYXNpYy5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvdGVzdC90ZXN0LWFsbC5qcyIsIi9Vc2Vycy96ZXVzL0RvY3VtZW50cy9HZW5lcmFsL1Byb2plY3RzL29wZW5wZ3Bqcy9naXQvdGVzdC91bml0LmpzIiwiL3Vzci9sb2NhbC9zaGFyZS9ucG0vbGliL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9pbnNlcnQtbW9kdWxlLWdsb2JhbHMvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0dkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1WkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1bEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDblNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMVRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25LQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25RQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5UUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0tBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlc0NvbnRlbnQiOlsiSlhHID0ge1xuICBleGlzdHM6IChmdW5jdGlvbih1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24odikge1xuICAgICAgcmV0dXJuICEodiA9PT0gdW5kZWZpbmVkIHx8IHYgPT09IG51bGwpO1xuICAgIH1cbiAgfSkoKVxufTtcbkpYRy5kZWNvbXByZXNzID0gZnVuY3Rpb24oc3RyKSB7XG4gIHJldHVybiB1bmVzY2FwZSgobmV3IEpYRy5VdGlsLlVuemlwKEpYRy5VdGlsLkJhc2U2NC5kZWNvZGVBc0FycmF5KHN0cikpKS51bnppcCgpWzBdWzBdKTtcbn07XG4vKlxuICAgIENvcHlyaWdodCAyMDA4LTIwMTJcbiAgICAgICAgTWF0dGhpYXMgRWhtYW5uLFxuICAgICAgICBNaWNoYWVsIEdlcmhhZXVzZXIsXG4gICAgICAgIENhcnN0ZW4gTWlsbGVyLFxuICAgICAgICBCaWFuY2EgVmFsZW50aW4sXG4gICAgICAgIEFsZnJlZCBXYXNzZXJtYW5uLFxuICAgICAgICBQZXRlciBXaWxmYWhydFxuXG4gICAgVGhpcyBmaWxlIGlzIHBhcnQgb2YgSlNYR3JhcGguXG4gICAgXG4gICAgRHVhbCBsaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UgVmVyc2lvbiAyLjAsIG9yIExHUEwgVmVyc2lvbiAzIGxpY2Vuc2VzLlxuXG4gICAgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gICAgYWxvbmcgd2l0aCBKU1hDb21wcmVzc29yLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICAgIFxuICAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEFwYWNoZSBMaWNlbnNlIGFsb25nIHdpdGggSlNYQ29tcHJlc3Nvci4gIFxuICAgIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvPi5cblxuKi9cblxuLyoqXG4gKiBAY2xhc3MgVXRpbCBjbGFzc1xuICogQGNsYXNzZGVzYyBVdGlsaXRpZXMgZm9yIHVuY29tcHJlc3NpbmcgYW5kIGJhc2U2NCBkZWNvZGluZ1xuICogQ2xhc3MgZm9yIGd1bnppcHBpbmcsIHVuemlwcGluZyBhbmQgYmFzZTY0IGRlY29kaW5nIG9mIGZpbGVzLlxuICogSXQgaXMgdXNlZCBmb3IgcmVhZGluZyBHRU9ORXhULCBHZW9nZWJyYSBhbmQgSW50ZXJnZW8gZmlsZXMuXG4gKlxuICogT25seSBIdWZmbWFuIGNvZGVzIGFyZSBkZWNvZGVkIGluIGd1bnppcC5cbiAqIFRoZSBjb2RlIGlzIGJhc2VkIG9uIHRoZSBzb3VyY2UgY29kZSBmb3IgZ3VuemlwLmMgYnkgUGFzaSBPamFsYSBcbiAqIHtAbGluayBodHRwOi8vd3d3LmNzLnR1dC5maS9+YWxiZXJ0L0Rldi9ndW56aXAvZ3VuemlwLmN9XG4gKiB7QGxpbmsgaHR0cDovL3d3dy5jcy50dXQuZmkvfmFsYmVydH1cbiAqL1xuSlhHLlV0aWwgPSB7fTtcblxuLyoqXG4gKiBVbnppcCB6aXAgZmlsZXNcbiAqL1xuSlhHLlV0aWwuVW56aXAgPSBmdW5jdGlvbihiYXJyYXkpIHtcbiAgdmFyIG91dHB1dEFyciA9IFtdLFxuICAgIG91dHB1dCA9IFwiXCIsXG4gICAgZGVidWcgPSBmYWxzZSxcbiAgICBncGZsYWdzLFxuICAgIGZpbGVzID0gMCxcbiAgICB1bnppcHBlZCA9IFtdLFxuICAgIGNyYyxcbiAgICBidWYzMmsgPSBuZXcgQXJyYXkoMzI3NjgpLFxuICAgIGJJZHggPSAwLFxuICAgIG1vZGVaSVAgPSBmYWxzZSxcblxuICAgIENSQywgU0laRSxcblxuICAgIGJpdFJldmVyc2UgPSBbXG4gICAgICAgIDB4MDAsIDB4ODAsIDB4NDAsIDB4YzAsIDB4MjAsIDB4YTAsIDB4NjAsIDB4ZTAsXG4gICAgICAgIDB4MTAsIDB4OTAsIDB4NTAsIDB4ZDAsIDB4MzAsIDB4YjAsIDB4NzAsIDB4ZjAsXG4gICAgICAgIDB4MDgsIDB4ODgsIDB4NDgsIDB4YzgsIDB4MjgsIDB4YTgsIDB4NjgsIDB4ZTgsXG4gICAgICAgIDB4MTgsIDB4OTgsIDB4NTgsIDB4ZDgsIDB4MzgsIDB4YjgsIDB4NzgsIDB4ZjgsXG4gICAgICAgIDB4MDQsIDB4ODQsIDB4NDQsIDB4YzQsIDB4MjQsIDB4YTQsIDB4NjQsIDB4ZTQsXG4gICAgICAgIDB4MTQsIDB4OTQsIDB4NTQsIDB4ZDQsIDB4MzQsIDB4YjQsIDB4NzQsIDB4ZjQsXG4gICAgICAgIDB4MGMsIDB4OGMsIDB4NGMsIDB4Y2MsIDB4MmMsIDB4YWMsIDB4NmMsIDB4ZWMsXG4gICAgICAgIDB4MWMsIDB4OWMsIDB4NWMsIDB4ZGMsIDB4M2MsIDB4YmMsIDB4N2MsIDB4ZmMsXG4gICAgICAgIDB4MDIsIDB4ODIsIDB4NDIsIDB4YzIsIDB4MjIsIDB4YTIsIDB4NjIsIDB4ZTIsXG4gICAgICAgIDB4MTIsIDB4OTIsIDB4NTIsIDB4ZDIsIDB4MzIsIDB4YjIsIDB4NzIsIDB4ZjIsXG4gICAgICAgIDB4MGEsIDB4OGEsIDB4NGEsIDB4Y2EsIDB4MmEsIDB4YWEsIDB4NmEsIDB4ZWEsXG4gICAgICAgIDB4MWEsIDB4OWEsIDB4NWEsIDB4ZGEsIDB4M2EsIDB4YmEsIDB4N2EsIDB4ZmEsXG4gICAgICAgIDB4MDYsIDB4ODYsIDB4NDYsIDB4YzYsIDB4MjYsIDB4YTYsIDB4NjYsIDB4ZTYsXG4gICAgICAgIDB4MTYsIDB4OTYsIDB4NTYsIDB4ZDYsIDB4MzYsIDB4YjYsIDB4NzYsIDB4ZjYsXG4gICAgICAgIDB4MGUsIDB4OGUsIDB4NGUsIDB4Y2UsIDB4MmUsIDB4YWUsIDB4NmUsIDB4ZWUsXG4gICAgICAgIDB4MWUsIDB4OWUsIDB4NWUsIDB4ZGUsIDB4M2UsIDB4YmUsIDB4N2UsIDB4ZmUsXG4gICAgICAgIDB4MDEsIDB4ODEsIDB4NDEsIDB4YzEsIDB4MjEsIDB4YTEsIDB4NjEsIDB4ZTEsXG4gICAgICAgIDB4MTEsIDB4OTEsIDB4NTEsIDB4ZDEsIDB4MzEsIDB4YjEsIDB4NzEsIDB4ZjEsXG4gICAgICAgIDB4MDksIDB4ODksIDB4NDksIDB4YzksIDB4MjksIDB4YTksIDB4NjksIDB4ZTksXG4gICAgICAgIDB4MTksIDB4OTksIDB4NTksIDB4ZDksIDB4MzksIDB4YjksIDB4NzksIDB4ZjksXG4gICAgICAgIDB4MDUsIDB4ODUsIDB4NDUsIDB4YzUsIDB4MjUsIDB4YTUsIDB4NjUsIDB4ZTUsXG4gICAgICAgIDB4MTUsIDB4OTUsIDB4NTUsIDB4ZDUsIDB4MzUsIDB4YjUsIDB4NzUsIDB4ZjUsXG4gICAgICAgIDB4MGQsIDB4OGQsIDB4NGQsIDB4Y2QsIDB4MmQsIDB4YWQsIDB4NmQsIDB4ZWQsXG4gICAgICAgIDB4MWQsIDB4OWQsIDB4NWQsIDB4ZGQsIDB4M2QsIDB4YmQsIDB4N2QsIDB4ZmQsXG4gICAgICAgIDB4MDMsIDB4ODMsIDB4NDMsIDB4YzMsIDB4MjMsIDB4YTMsIDB4NjMsIDB4ZTMsXG4gICAgICAgIDB4MTMsIDB4OTMsIDB4NTMsIDB4ZDMsIDB4MzMsIDB4YjMsIDB4NzMsIDB4ZjMsXG4gICAgICAgIDB4MGIsIDB4OGIsIDB4NGIsIDB4Y2IsIDB4MmIsIDB4YWIsIDB4NmIsIDB4ZWIsXG4gICAgICAgIDB4MWIsIDB4OWIsIDB4NWIsIDB4ZGIsIDB4M2IsIDB4YmIsIDB4N2IsIDB4ZmIsXG4gICAgICAgIDB4MDcsIDB4ODcsIDB4NDcsIDB4YzcsIDB4MjcsIDB4YTcsIDB4NjcsIDB4ZTcsXG4gICAgICAgIDB4MTcsIDB4OTcsIDB4NTcsIDB4ZDcsIDB4MzcsIDB4YjcsIDB4NzcsIDB4ZjcsXG4gICAgICAgIDB4MGYsIDB4OGYsIDB4NGYsIDB4Y2YsIDB4MmYsIDB4YWYsIDB4NmYsIDB4ZWYsXG4gICAgICAgIDB4MWYsIDB4OWYsIDB4NWYsIDB4ZGYsIDB4M2YsIDB4YmYsIDB4N2YsIDB4ZmZcbiAgICBdLFxuXG4gICAgY3BsZW5zID0gW1xuICAgICAgICAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEzLCAxNSwgMTcsIDE5LCAyMywgMjcsIDMxLFxuICAgICAgICAzNSwgNDMsIDUxLCA1OSwgNjcsIDgzLCA5OSwgMTE1LCAxMzEsIDE2MywgMTk1LCAyMjcsIDI1OCwgMCwgMFxuICAgIF0sXG5cbiAgICBjcGxleHQgPSBbXG4gICAgICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDIsIDIsIDIsIDIsXG4gICAgICAgIDMsIDMsIDMsIDMsIDQsIDQsIDQsIDQsIDUsIDUsIDUsIDUsIDAsIDk5LCA5OVxuICAgIF0sXG4gICAgLyogOTk9PWludmFsaWQgKi9cblxuICAgIGNwZGlzdCA9IFtcbiAgICAgICAgMHgwMDAxLCAweDAwMDIsIDB4MDAwMywgMHgwMDA0LCAweDAwMDUsIDB4MDAwNywgMHgwMDA5LCAweDAwMGQsXG4gICAgICAgIDB4MDAxMSwgMHgwMDE5LCAweDAwMjEsIDB4MDAzMSwgMHgwMDQxLCAweDAwNjEsIDB4MDA4MSwgMHgwMGMxLFxuICAgICAgICAweDAxMDEsIDB4MDE4MSwgMHgwMjAxLCAweDAzMDEsIDB4MDQwMSwgMHgwNjAxLCAweDA4MDEsIDB4MGMwMSxcbiAgICAgICAgMHgxMDAxLCAweDE4MDEsIDB4MjAwMSwgMHgzMDAxLCAweDQwMDEsIDB4NjAwMVxuICAgIF0sXG5cbiAgICBjcGRleHQgPSBbXG4gICAgICAgIDAsIDAsIDAsIDAsIDEsIDEsIDIsIDIsXG4gICAgICAgIDMsIDMsIDQsIDQsIDUsIDUsIDYsIDYsXG4gICAgICAgIDcsIDcsIDgsIDgsIDksIDksIDEwLCAxMCxcbiAgICAgICAgMTEsIDExLCAxMiwgMTIsIDEzLCAxM1xuICAgIF0sXG5cbiAgICBib3JkZXIgPSBbMTYsIDE3LCAxOCwgMCwgOCwgNywgOSwgNiwgMTAsIDUsIDExLCA0LCAxMiwgMywgMTMsIDIsIDE0LCAxLCAxNV0sXG5cbiAgICBiQSA9IGJhcnJheSxcblxuICAgIGJ5dGVwb3MgPSAwLFxuICAgIGJpdHBvcyA9IDAsXG4gICAgYmIgPSAxLFxuICAgIGJpdHMgPSAwLFxuXG4gICAgTkFNRU1BWCA9IDI1NixcblxuICAgIG5hbWVCdWYgPSBbXSxcblxuICAgIGZpbGVvdXQ7XG5cbiAgZnVuY3Rpb24gcmVhZEJ5dGUoKSB7XG4gICAgYml0cyArPSA4O1xuICAgIGlmIChieXRlcG9zIDwgYkEubGVuZ3RoKSB7XG4gICAgICAvL2lmIChkZWJ1ZylcbiAgICAgIC8vICAgIGRvY3VtZW50LndyaXRlKGJ5dGVwb3MrXCI6IFwiK2JBW2J5dGVwb3NdK1wiPGJyPlwiKTtcbiAgICAgIHJldHVybiBiQVtieXRlcG9zKytdO1xuICAgIH0gZWxzZVxuICAgICAgcmV0dXJuIC0xO1xuICB9O1xuXG4gIGZ1bmN0aW9uIGJ5dGVBbGlnbigpIHtcbiAgICBiYiA9IDE7XG4gIH07XG5cbiAgZnVuY3Rpb24gcmVhZEJpdCgpIHtcbiAgICB2YXIgY2Fycnk7XG4gICAgYml0cysrO1xuICAgIGNhcnJ5ID0gKGJiICYgMSk7XG4gICAgYmIgPj49IDE7XG4gICAgaWYgKGJiID09IDApIHtcbiAgICAgIGJiID0gcmVhZEJ5dGUoKTtcbiAgICAgIGNhcnJ5ID0gKGJiICYgMSk7XG4gICAgICBiYiA9IChiYiA+PiAxKSB8IDB4ODA7XG4gICAgfVxuICAgIHJldHVybiBjYXJyeTtcbiAgfTtcblxuICBmdW5jdGlvbiByZWFkQml0cyhhKSB7XG4gICAgdmFyIHJlcyA9IDAsXG4gICAgICBpID0gYTtcblxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHJlcyA9IChyZXMgPDwgMSkgfCByZWFkQml0KCk7XG4gICAgfVxuICAgIGlmIChhKSB7XG4gICAgICByZXMgPSBiaXRSZXZlcnNlW3Jlc10gPj4gKDggLSBhKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcblxuICBmdW5jdGlvbiBmbHVzaEJ1ZmZlcigpIHtcbiAgICAvL2RvY3VtZW50LndyaXRlKCdGTFVTSEJVRkZFUjonK2J1ZjMyayk7XG4gICAgYklkeCA9IDA7XG4gIH07XG5cbiAgZnVuY3Rpb24gYWRkQnVmZmVyKGEpIHtcbiAgICBTSVpFKys7XG4gICAgLy9DUkM9dXBkY3JjKGEsY3JjKTtcbiAgICBidWYzMmtbYklkeCsrXSA9IGE7XG4gICAgb3V0cHV0QXJyLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShhKSk7XG4gICAgLy9vdXRwdXQrPVN0cmluZy5mcm9tQ2hhckNvZGUoYSk7XG4gICAgaWYgKGJJZHggPT0gMHg4MDAwKSB7XG4gICAgICAvL2RvY3VtZW50LndyaXRlKCdBRERCVUZGRVI6JytidWYzMmspO1xuICAgICAgYklkeCA9IDA7XG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIEh1Zk5vZGUoKSB7XG4gICAgdGhpcy5iMCA9IDA7XG4gICAgdGhpcy5iMSA9IDA7XG4gICAgdGhpcy5qdW1wID0gbnVsbDtcbiAgICB0aGlzLmp1bXBwb3MgPSAtMTtcbiAgfTtcblxuICB2YXIgTElURVJBTFMgPSAyODg7XG5cbiAgdmFyIGxpdGVyYWxUcmVlID0gbmV3IEFycmF5KExJVEVSQUxTKTtcbiAgdmFyIGRpc3RhbmNlVHJlZSA9IG5ldyBBcnJheSgzMik7XG4gIHZhciB0cmVlcG9zID0gMDtcbiAgdmFyIFBsYWNlcyA9IG51bGw7XG4gIHZhciBQbGFjZXMyID0gbnVsbDtcblxuICB2YXIgaW1wRGlzdGFuY2VUcmVlID0gbmV3IEFycmF5KDY0KTtcbiAgdmFyIGltcExlbmd0aFRyZWUgPSBuZXcgQXJyYXkoNjQpO1xuXG4gIHZhciBsZW4gPSAwO1xuICB2YXIgZnBvcyA9IG5ldyBBcnJheSgxNyk7XG4gIGZwb3NbMF0gPSAwO1xuICB2YXIgZmxlbnM7XG4gIHZhciBmbWF4O1xuXG4gIGZ1bmN0aW9uIElzUGF0KCkge1xuICAgIHdoaWxlICgxKSB7XG4gICAgICBpZiAoZnBvc1tsZW5dID49IGZtYXgpXG4gICAgICAgIHJldHVybiAtMTtcbiAgICAgIGlmIChmbGVuc1tmcG9zW2xlbl1dID09IGxlbilcbiAgICAgICAgcmV0dXJuIGZwb3NbbGVuXSsrO1xuICAgICAgZnBvc1tsZW5dKys7XG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIFJlYygpIHtcbiAgICB2YXIgY3VycGxhY2UgPSBQbGFjZXNbdHJlZXBvc107XG4gICAgdmFyIHRtcDtcbiAgICBpZiAoZGVidWcpXG4gICAgICBkb2N1bWVudC53cml0ZShcIjxicj5sZW46XCIgKyBsZW4gKyBcIiB0cmVlcG9zOlwiICsgdHJlZXBvcyk7XG4gICAgaWYgKGxlbiA9PSAxNykgeyAvL3dhciAxN1xuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgICB0cmVlcG9zKys7XG4gICAgbGVuKys7XG5cbiAgICB0bXAgPSBJc1BhdCgpO1xuICAgIGlmIChkZWJ1ZylcbiAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPklzUGF0IFwiICsgdG1wKTtcbiAgICBpZiAodG1wID49IDApIHtcbiAgICAgIGN1cnBsYWNlLmIwID0gdG1wOyAvKiBsZWFmIGNlbGwgZm9yIDAtYml0ICovXG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiPGJyPmIwIFwiICsgY3VycGxhY2UuYjApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvKiBOb3QgYSBMZWFmIGNlbGwgKi9cbiAgICAgIGN1cnBsYWNlLmIwID0gMHg4MDAwO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5iMCBcIiArIGN1cnBsYWNlLmIwKTtcbiAgICAgIGlmIChSZWMoKSlcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgICB0bXAgPSBJc1BhdCgpO1xuICAgIGlmICh0bXAgPj0gMCkge1xuICAgICAgY3VycGxhY2UuYjEgPSB0bXA7IC8qIGxlYWYgY2VsbCBmb3IgMS1iaXQgKi9cbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+YjEgXCIgKyBjdXJwbGFjZS5iMSk7XG4gICAgICBjdXJwbGFjZS5qdW1wID0gbnVsbDsgLyogSnVzdCBmb3IgdGhlIGRpc3BsYXkgcm91dGluZSAqL1xuICAgIH0gZWxzZSB7XG4gICAgICAvKiBOb3QgYSBMZWFmIGNlbGwgKi9cbiAgICAgIGN1cnBsYWNlLmIxID0gMHg4MDAwO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5iMSBcIiArIGN1cnBsYWNlLmIxKTtcbiAgICAgIGN1cnBsYWNlLmp1bXAgPSBQbGFjZXNbdHJlZXBvc107XG4gICAgICBjdXJwbGFjZS5qdW1wcG9zID0gdHJlZXBvcztcbiAgICAgIGlmIChSZWMoKSlcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgICBsZW4tLTtcbiAgICByZXR1cm4gMDtcbiAgfTtcblxuICBmdW5jdGlvbiBDcmVhdGVUcmVlKGN1cnJlbnRUcmVlLCBudW12YWwsIGxlbmd0aHMsIHNob3cpIHtcbiAgICB2YXIgaTtcbiAgICAvKiBDcmVhdGUgdGhlIEh1ZmZtYW4gZGVjb2RlIHRyZWUvdGFibGUgKi9cbiAgICAvL2RvY3VtZW50LndyaXRlKFwiPGJyPmNyZWF0ZXRyZWU8YnI+XCIpO1xuICAgIGlmIChkZWJ1ZylcbiAgICAgIGRvY3VtZW50LndyaXRlKFwiY3VycmVudFRyZWUgXCIgKyBjdXJyZW50VHJlZSArIFwiIG51bXZhbCBcIiArIG51bXZhbCArIFwiIGxlbmd0aHMgXCIgKyBsZW5ndGhzICsgXCIgc2hvdyBcIiArIHNob3cpO1xuICAgIFBsYWNlcyA9IGN1cnJlbnRUcmVlO1xuICAgIHRyZWVwb3MgPSAwO1xuICAgIGZsZW5zID0gbGVuZ3RocztcbiAgICBmbWF4ID0gbnVtdmFsO1xuICAgIGZvciAoaSA9IDA7IGkgPCAxNzsgaSsrKVxuICAgICAgZnBvc1tpXSA9IDA7XG4gICAgbGVuID0gMDtcbiAgICBpZiAoUmVjKCkpIHtcbiAgICAgIC8vZnByaW50ZihzdGRlcnIsIFwiaW52YWxpZCBodWZmbWFuIHRyZWVcXG5cIik7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KFwiaW52YWxpZCBodWZmbWFuIHRyZWVcXG5cIik7XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIGlmIChkZWJ1Zykge1xuICAgICAgZG9jdW1lbnQud3JpdGUoJzxicj5UcmVlOiAnICsgUGxhY2VzLmxlbmd0aCk7XG4gICAgICBmb3IgKHZhciBhID0gMDsgYSA8IDMyOyBhKyspIHtcbiAgICAgICAgZG9jdW1lbnQud3JpdGUoXCJQbGFjZXNbXCIgKyBhICsgXCJdLmIwPVwiICsgUGxhY2VzW2FdLmIwICsgXCI8YnI+XCIpO1xuICAgICAgICBkb2N1bWVudC53cml0ZShcIlBsYWNlc1tcIiArIGEgKyBcIl0uYjE9XCIgKyBQbGFjZXNbYV0uYjEgKyBcIjxicj5cIik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyppZihzaG93KSB7XG4gICAgICAgICAgICB2YXIgdG1wO1xuICAgICAgICAgICAgZm9yKHRtcD1jdXJyZW50VHJlZTt0bXA8UGxhY2VzO3RtcCsrKSB7XG4gICAgICAgICAgICAgICAgZnByaW50ZihzdGRvdXQsIFwiMHglMDN4ICAweCUwM3ggKDB4JTA0eClcIix0bXAtY3VycmVudFRyZWUsIHRtcC0+anVtcD90bXAtPmp1bXAtY3VycmVudFRyZWU6MCwodG1wLT5qdW1wP3RtcC0+anVtcC1jdXJyZW50VHJlZTowKSo2KzB4Y2YwKTtcbiAgICAgICAgICAgICAgICBpZighKHRtcC5iMCAmIDB4ODAwMCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy9mcHJpbnRmKHN0ZG91dCwgXCIgIDB4JTAzeCAoJWMpXCIsIHRtcC0+YjAsKHRtcC0+YjA8MjU2ICYmIGlzcHJpbnQodG1wLT5iMCkpP3RtcC0+YjA6J++/vScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZighKHRtcC5iMSAmIDB4ODAwMCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYoKHRtcC5iMCAmIDB4ODAwMCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgXCIgICAgICAgICAgIFwiKTtcbiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRvdXQsIFwiICAweCUwM3ggKCVjKVwiLCB0bXAtPmIxLCh0bXAtPmIxPDI1NiAmJiBpc3ByaW50KHRtcC0+YjEpKT90bXAtPmIxOifvv70nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZnByaW50ZihzdGRvdXQsIFwiXFxuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9Ki9cbiAgICByZXR1cm4gMDtcbiAgfTtcblxuICBmdW5jdGlvbiBEZWNvZGVWYWx1ZShjdXJyZW50VHJlZSkge1xuICAgIHZhciBsZW4sIGksXG4gICAgICB4dHJlZXBvcyA9IDAsXG4gICAgICBYID0gY3VycmVudFRyZWVbeHRyZWVwb3NdLFxuICAgICAgYjtcblxuICAgIC8qIGRlY29kZSBvbmUgc3ltYm9sIG9mIHRoZSBkYXRhICovXG4gICAgd2hpbGUgKDEpIHtcbiAgICAgIGIgPSByZWFkQml0KCk7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGRvY3VtZW50LndyaXRlKFwiYj1cIiArIGIpO1xuICAgICAgaWYgKGIpIHtcbiAgICAgICAgaWYgKCEoWC5iMSAmIDB4ODAwMCkpIHtcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBkb2N1bWVudC53cml0ZShcInJldDFcIik7XG4gICAgICAgICAgcmV0dXJuIFguYjE7IC8qIElmIGxlYWYgbm9kZSwgcmV0dXJuIGRhdGEgKi9cbiAgICAgICAgfVxuICAgICAgICBYID0gWC5qdW1wO1xuICAgICAgICBsZW4gPSBjdXJyZW50VHJlZS5sZW5ndGg7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgIGlmIChjdXJyZW50VHJlZVtpXSA9PT0gWCkge1xuICAgICAgICAgICAgeHRyZWVwb3MgPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8veHRyZWVwb3MrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghKFguYjAgJiAweDgwMDApKSB7XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCJyZXQyXCIpO1xuICAgICAgICAgIHJldHVybiBYLmIwOyAvKiBJZiBsZWFmIG5vZGUsIHJldHVybiBkYXRhICovXG4gICAgICAgIH1cbiAgICAgICAgLy9YKys7IC8vPz8/Pz8/Pz8/Pz8/Pz8/Pz8/XG4gICAgICAgIHh0cmVlcG9zKys7XG4gICAgICAgIFggPSBjdXJyZW50VHJlZVt4dHJlZXBvc107XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChkZWJ1ZylcbiAgICAgIGRvY3VtZW50LndyaXRlKFwicmV0M1wiKTtcbiAgICByZXR1cm4gLTE7XG4gIH07XG5cbiAgZnVuY3Rpb24gRGVmbGF0ZUxvb3AoKSB7XG4gICAgdmFyIGxhc3QsIGMsIHR5cGUsIGksIGxlbjtcblxuICAgIGRvIHtcbiAgICAgIC8qaWYoKGxhc3QgPSByZWFkQml0KCkpKXtcbiAgICAgICAgICAgIGZwcmludGYoZXJyZnAsIFwiTGFzdCBCbG9jazogXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZnByaW50ZihlcnJmcCwgXCJOb3QgTGFzdCBCbG9jazogXCIpO1xuICAgICAgICB9Ki9cbiAgICAgIGxhc3QgPSByZWFkQml0KCk7XG4gICAgICB0eXBlID0gcmVhZEJpdHMoMik7XG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSAwOlxuICAgICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICAgIGFsZXJ0KFwiU3RvcmVkXFxuXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQoXCJGaXhlZCBIdWZmbWFuIGNvZGVzXFxuXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQoXCJEeW5hbWljIEh1ZmZtYW4gY29kZXNcXG5cIik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBhbGVydChcIlJlc2VydmVkIGJsb2NrIHR5cGUhIVxcblwiKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBhbGVydChcIlVuZXhwZWN0ZWQgdmFsdWUgJWQhXFxuXCIsIHR5cGUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZSA9PSAwKSB7XG4gICAgICAgIHZhciBibG9ja0xlbiwgY1N1bTtcblxuICAgICAgICAvLyBTdG9yZWQgXG4gICAgICAgIGJ5dGVBbGlnbigpO1xuICAgICAgICBibG9ja0xlbiA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGJsb2NrTGVuIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuXG4gICAgICAgIGNTdW0gPSByZWFkQnl0ZSgpO1xuICAgICAgICBjU3VtIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuXG4gICAgICAgIGlmICgoKGJsb2NrTGVuIF4gfmNTdW0pICYgMHhmZmZmKSkge1xuICAgICAgICAgIGRvY3VtZW50LndyaXRlKFwiQmxvY2tMZW4gY2hlY2tzdW0gbWlzbWF0Y2hcXG5cIik7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGJsb2NrTGVuLS0pIHtcbiAgICAgICAgICBjID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgICBhZGRCdWZmZXIoYyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PSAxKSB7XG4gICAgICAgIHZhciBqO1xuXG4gICAgICAgIC8qIEZpeGVkIEh1ZmZtYW4gdGFibGVzIC0tIGZpeGVkIGRlY29kZSByb3V0aW5lICovXG4gICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAyNTYgICAgMDAwMDAwMCAgICAgICAgMFxuICAgICAgICAgICAgICAgIDogICA6ICAgICA6XG4gICAgICAgICAgICAgICAgMjc5ICAgIDAwMTAxMTEgICAgICAgIDIzXG4gICAgICAgICAgICAgICAgMCAgIDAwMTEwMDAwICAgIDQ4XG4gICAgICAgICAgICAgICAgOiAgICA6ICAgICAgOlxuICAgICAgICAgICAgICAgIDE0MyAgICAxMDExMTExMSAgICAxOTFcbiAgICAgICAgICAgICAgICAyODAgMTEwMDAwMDAgICAgMTkyXG4gICAgICAgICAgICAgICAgOiAgICA6ICAgICAgOlxuICAgICAgICAgICAgICAgIDI4NyAxMTAwMDExMSAgICAxOTlcbiAgICAgICAgICAgICAgICAxNDQgICAgMTEwMDEwMDAwICAgIDQwMFxuICAgICAgICAgICAgICAgIDogICAgOiAgICAgICA6XG4gICAgICAgICAgICAgICAgMjU1ICAgIDExMTExMTExMSAgICA1MTFcbiAgICBcbiAgICAgICAgICAgICAgICBOb3RlIHRoZSBiaXQgb3JkZXIhXG4gICAgICAgICAgICAgICAgKi9cblxuICAgICAgICAgIGogPSAoYml0UmV2ZXJzZVtyZWFkQml0cyg3KV0gPj4gMSk7XG4gICAgICAgICAgaWYgKGogPiAyMykge1xuICAgICAgICAgICAgaiA9IChqIDw8IDEpIHwgcmVhZEJpdCgpOyAvKiA0OC4uMjU1ICovXG5cbiAgICAgICAgICAgIGlmIChqID4gMTk5KSB7IC8qIDIwMC4uMjU1ICovXG4gICAgICAgICAgICAgIGogLT0gMTI4OyAvKiAgNzIuLjEyNyAqL1xuICAgICAgICAgICAgICBqID0gKGogPDwgMSkgfCByZWFkQml0KCk7IC8qIDE0NC4uMjU1IDw8ICovXG4gICAgICAgICAgICB9IGVsc2UgeyAvKiAgNDguLjE5OSAqL1xuICAgICAgICAgICAgICBqIC09IDQ4OyAvKiAgIDAuLjE1MSAqL1xuICAgICAgICAgICAgICBpZiAoaiA+IDE0Mykge1xuICAgICAgICAgICAgICAgIGogPSBqICsgMTM2OyAvKiAyODAuLjI4NyA8PCAqL1xuICAgICAgICAgICAgICAgIC8qICAgMC4uMTQzIDw8ICovXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgeyAvKiAgIDAuLjIzICovXG4gICAgICAgICAgICBqICs9IDI1NjsgLyogMjU2Li4yNzkgPDwgKi9cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGogPCAyNTYpIHtcbiAgICAgICAgICAgIGFkZEJ1ZmZlcihqKTtcbiAgICAgICAgICAgIC8vZG9jdW1lbnQud3JpdGUoXCJvdXQ6XCIrU3RyaW5nLmZyb21DaGFyQ29kZShqKSk7XG4gICAgICAgICAgICAvKmZwcmludGYoZXJyZnAsIFwiQCVkICUwMnhcXG5cIiwgU0laRSwgaik7Ki9cbiAgICAgICAgICB9IGVsc2UgaWYgKGogPT0gMjU2KSB7XG4gICAgICAgICAgICAvKiBFT0YgKi9cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgbGVuLCBkaXN0O1xuXG4gICAgICAgICAgICBqIC09IDI1NiArIDE7IC8qIGJ5dGVzICsgRU9GICovXG4gICAgICAgICAgICBsZW4gPSByZWFkQml0cyhjcGxleHRbal0pICsgY3BsZW5zW2pdO1xuXG4gICAgICAgICAgICBqID0gYml0UmV2ZXJzZVtyZWFkQml0cyg1KV0gPj4gMztcbiAgICAgICAgICAgIGlmIChjcGRleHRbal0gPiA4KSB7XG4gICAgICAgICAgICAgIGRpc3QgPSByZWFkQml0cyg4KTtcbiAgICAgICAgICAgICAgZGlzdCB8PSAocmVhZEJpdHMoY3BkZXh0W2pdIC0gOCkgPDwgOCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBkaXN0ID0gcmVhZEJpdHMoY3BkZXh0W2pdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRpc3QgKz0gY3BkaXN0W2pdO1xuXG4gICAgICAgICAgICAvKmZwcmludGYoZXJyZnAsIFwiQCVkIChsJTAyeCxkJTA0eClcXG5cIiwgU0laRSwgbGVuLCBkaXN0KTsqL1xuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgICAgIHZhciBjID0gYnVmMzJrWyhiSWR4IC0gZGlzdCkgJiAweDdmZmZdO1xuICAgICAgICAgICAgICBhZGRCdWZmZXIoYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IC8vIHdoaWxlXG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gMikge1xuICAgICAgICB2YXIgaiwgbiwgbGl0ZXJhbENvZGVzLCBkaXN0Q29kZXMsIGxlbkNvZGVzO1xuICAgICAgICB2YXIgbGwgPSBuZXcgQXJyYXkoMjg4ICsgMzIpOyAvLyBcInN0YXRpY1wiIGp1c3QgdG8gcHJlc2VydmUgc3RhY2tcblxuICAgICAgICAvLyBEeW5hbWljIEh1ZmZtYW4gdGFibGVzIFxuXG4gICAgICAgIGxpdGVyYWxDb2RlcyA9IDI1NyArIHJlYWRCaXRzKDUpO1xuICAgICAgICBkaXN0Q29kZXMgPSAxICsgcmVhZEJpdHMoNSk7XG4gICAgICAgIGxlbkNvZGVzID0gNCArIHJlYWRCaXRzKDQpO1xuICAgICAgICAvL2RvY3VtZW50LndyaXRlKFwiPGJyPnBhcmFtOiBcIitsaXRlcmFsQ29kZXMrXCIgXCIrZGlzdENvZGVzK1wiIFwiK2xlbkNvZGVzK1wiPGJyPlwiKTtcbiAgICAgICAgZm9yIChqID0gMDsgaiA8IDE5OyBqKyspIHtcbiAgICAgICAgICBsbFtqXSA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIGRlY29kZSB0cmVlIGNvZGUgbGVuZ3Roc1xuXG4gICAgICAgIC8vZG9jdW1lbnQud3JpdGUoXCI8YnI+XCIpO1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgbGVuQ29kZXM7IGorKykge1xuICAgICAgICAgIGxsW2JvcmRlcltqXV0gPSByZWFkQml0cygzKTtcbiAgICAgICAgICAvL2RvY3VtZW50LndyaXRlKGxsW2JvcmRlcltqXV0rXCIgXCIpO1xuICAgICAgICB9XG4gICAgICAgIC8vZnByaW50ZihlcnJmcCwgXCJcXG5cIik7XG4gICAgICAgIC8vZG9jdW1lbnQud3JpdGUoJzxicj5sbDonK2xsKTtcbiAgICAgICAgbGVuID0gZGlzdGFuY2VUcmVlLmxlbmd0aDtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgIGRpc3RhbmNlVHJlZVtpXSA9IG5ldyBIdWZOb2RlKCk7XG4gICAgICAgIGlmIChDcmVhdGVUcmVlKGRpc3RhbmNlVHJlZSwgMTksIGxsLCAwKSkge1xuICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlYnVnKSB7XG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+ZGlzdGFuY2VUcmVlXCIpO1xuICAgICAgICAgIGZvciAodmFyIGEgPSAwOyBhIDwgZGlzdGFuY2VUcmVlLmxlbmd0aDsgYSsrKSB7XG4gICAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5cIiArIGRpc3RhbmNlVHJlZVthXS5iMCArIFwiIFwiICsgZGlzdGFuY2VUcmVlW2FdLmIxICsgXCIgXCIgKyBkaXN0YW5jZVRyZWVbYV0uanVtcCArIFwiIFwiICtcbiAgICAgICAgICAgICAgZGlzdGFuY2VUcmVlW2FdLmp1bXBwb3MpO1xuICAgICAgICAgICAgLyppZiAoZGlzdGFuY2VUcmVlW2FdLmp1bXBwb3MhPS0xKVxuICAgICAgICAgICAgICAgICAgICBcdGRvY3VtZW50LndyaXRlKFwiIFwiK2Rpc3RhbmNlVHJlZVthXS5qdW1wLmIwK1wiIFwiK2Rpc3RhbmNlVHJlZVthXS5qdW1wLmIxKTtcbiAgICAgICAgICAgICAgICBcdCovXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vZG9jdW1lbnQud3JpdGUoJzxCUj50cmVlIGNyZWF0ZWQnKTtcblxuICAgICAgICAvL3JlYWQgaW4gbGl0ZXJhbCBhbmQgZGlzdGFuY2UgY29kZSBsZW5ndGhzXG4gICAgICAgIG4gPSBsaXRlcmFsQ29kZXMgKyBkaXN0Q29kZXM7XG4gICAgICAgIGkgPSAwO1xuICAgICAgICB2YXIgeiA9IC0xO1xuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+bj1cIiArIG4gKyBcIiBiaXRzOiBcIiArIGJpdHMgKyBcIjxicj5cIik7XG4gICAgICAgIHdoaWxlIChpIDwgbikge1xuICAgICAgICAgIHorKztcbiAgICAgICAgICBqID0gRGVjb2RlVmFsdWUoZGlzdGFuY2VUcmVlKTtcbiAgICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgICBkb2N1bWVudC53cml0ZShcIjxicj5cIiArIHogKyBcIiBpOlwiICsgaSArIFwiIGRlY29kZTogXCIgKyBqICsgXCIgICAgYml0cyBcIiArIGJpdHMgKyBcIjxicj5cIik7XG4gICAgICAgICAgaWYgKGogPCAxNikgeyAvLyBsZW5ndGggb2YgY29kZSBpbiBiaXRzICgwLi4xNSlcbiAgICAgICAgICAgIGxsW2krK10gPSBqO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaiA9PSAxNikgeyAvLyByZXBlYXQgbGFzdCBsZW5ndGggMyB0byA2IHRpbWVzIFxuICAgICAgICAgICAgdmFyIGw7XG4gICAgICAgICAgICBqID0gMyArIHJlYWRCaXRzKDIpO1xuICAgICAgICAgICAgaWYgKGkgKyBqID4gbikge1xuICAgICAgICAgICAgICBmbHVzaEJ1ZmZlcigpO1xuICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGwgPSBpID8gbGxbaSAtIDFdIDogMDtcbiAgICAgICAgICAgIHdoaWxlIChqLS0pIHtcbiAgICAgICAgICAgICAgbGxbaSsrXSA9IGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChqID09IDE3KSB7IC8vIDMgdG8gMTAgemVybyBsZW5ndGggY29kZXNcbiAgICAgICAgICAgICAgaiA9IDMgKyByZWFkQml0cygzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGogPT0gMTg6IDExIHRvIDEzOCB6ZXJvIGxlbmd0aCBjb2RlcyBcbiAgICAgICAgICAgICAgaiA9IDExICsgcmVhZEJpdHMoNyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaSArIGogPiBuKSB7XG4gICAgICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgd2hpbGUgKGotLSkge1xuICAgICAgICAgICAgICBsbFtpKytdID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLypmb3Ioaj0wOyBqPGxpdGVyYWxDb2RlcytkaXN0Q29kZXM7IGorKykge1xuICAgICAgICAgICAgICAgIC8vZnByaW50ZihlcnJmcCwgXCIlZCBcIiwgbGxbal0pO1xuICAgICAgICAgICAgICAgIGlmICgoaiY3KT09NylcbiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihlcnJmcCwgXCJcXG5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmcHJpbnRmKGVycmZwLCBcIlxcblwiKTsqL1xuICAgICAgICAvLyBDYW4gb3ZlcndyaXRlIHRyZWUgZGVjb2RlIHRyZWUgYXMgaXQgaXMgbm90IHVzZWQgYW55bW9yZVxuICAgICAgICBsZW4gPSBsaXRlcmFsVHJlZS5sZW5ndGg7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgICAgICBsaXRlcmFsVHJlZVtpXSA9IG5ldyBIdWZOb2RlKCk7XG4gICAgICAgIGlmIChDcmVhdGVUcmVlKGxpdGVyYWxUcmVlLCBsaXRlcmFsQ29kZXMsIGxsLCAwKSkge1xuICAgICAgICAgIGZsdXNoQnVmZmVyKCk7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgbGVuID0gbGl0ZXJhbFRyZWUubGVuZ3RoO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICAgICAgZGlzdGFuY2VUcmVlW2ldID0gbmV3IEh1Zk5vZGUoKTtcbiAgICAgICAgdmFyIGxsMiA9IG5ldyBBcnJheSgpO1xuICAgICAgICBmb3IgKGkgPSBsaXRlcmFsQ29kZXM7IGkgPCBsbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGxsMltpIC0gbGl0ZXJhbENvZGVzXSA9IGxsW2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChDcmVhdGVUcmVlKGRpc3RhbmNlVHJlZSwgZGlzdENvZGVzLCBsbDIsIDApKSB7XG4gICAgICAgICAgZmx1c2hCdWZmZXIoKTtcbiAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgZG9jdW1lbnQud3JpdGUoXCI8YnI+bGl0ZXJhbFRyZWVcIik7XG4gICAgICAgIG91dGVyOiB3aGlsZSAoMSkge1xuICAgICAgICAgIGogPSBEZWNvZGVWYWx1ZShsaXRlcmFsVHJlZSk7XG4gICAgICAgICAgaWYgKGogPj0gMjU2KSB7IC8vIEluIEM2NDogaWYgY2Fycnkgc2V0XG4gICAgICAgICAgICB2YXIgbGVuLCBkaXN0O1xuICAgICAgICAgICAgaiAtPSAyNTY7XG4gICAgICAgICAgICBpZiAoaiA9PSAwKSB7XG4gICAgICAgICAgICAgIC8vIEVPRlxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGotLTtcbiAgICAgICAgICAgIGxlbiA9IHJlYWRCaXRzKGNwbGV4dFtqXSkgKyBjcGxlbnNbal07XG5cbiAgICAgICAgICAgIGogPSBEZWNvZGVWYWx1ZShkaXN0YW5jZVRyZWUpO1xuICAgICAgICAgICAgaWYgKGNwZGV4dFtqXSA+IDgpIHtcbiAgICAgICAgICAgICAgZGlzdCA9IHJlYWRCaXRzKDgpO1xuICAgICAgICAgICAgICBkaXN0IHw9IChyZWFkQml0cyhjcGRleHRbal0gLSA4KSA8PCA4KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGRpc3QgPSByZWFkQml0cyhjcGRleHRbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGlzdCArPSBjcGRpc3Rbal07XG4gICAgICAgICAgICB3aGlsZSAobGVuLS0pIHtcbiAgICAgICAgICAgICAgaWYgKGJJZHggLSBkaXN0IDwgMCkge1xuICAgICAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHZhciBjID0gYnVmMzJrWyhiSWR4IC0gZGlzdCkgJiAweDdmZmZdO1xuICAgICAgICAgICAgICBhZGRCdWZmZXIoYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFkZEJ1ZmZlcihqKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IHdoaWxlICghbGFzdCk7XG4gICAgZmx1c2hCdWZmZXIoKTtcblxuICAgIGJ5dGVBbGlnbigpO1xuICAgIHJldHVybiAwO1xuICB9O1xuXG4gIEpYRy5VdGlsLlVuemlwLnByb3RvdHlwZS51bnppcEZpbGUgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgdmFyIGk7XG4gICAgdGhpcy51bnppcCgpO1xuICAgIC8vYWxlcnQodW56aXBwZWRbMF1bMV0pO1xuICAgIGZvciAoaSA9IDA7IGkgPCB1bnppcHBlZC5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHVuemlwcGVkW2ldWzFdID09IG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHVuemlwcGVkW2ldWzBdO1xuICAgICAgfVxuICAgIH1cblxuICB9O1xuXG4gIEpYRy5VdGlsLlVuemlwLnByb3RvdHlwZS5kZWZsYXRlID0gZnVuY3Rpb24oKSB7XG4gICAgb3V0cHV0QXJyID0gW107XG4gICAgdmFyIHRtcCA9IFtdO1xuICAgIG1vZGVaSVAgPSBmYWxzZTtcbiAgICBEZWZsYXRlTG9vcCgpO1xuICAgIGlmIChkZWJ1ZylcbiAgICAgIGFsZXJ0KG91dHB1dEFyci5qb2luKCcnKSk7XG4gICAgdW56aXBwZWRbZmlsZXNdID0gbmV3IEFycmF5KDIpO1xuICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICB1bnppcHBlZFtmaWxlc11bMV0gPSBcIkRFRkxBVEVcIjtcbiAgICBmaWxlcysrO1xuICAgIHJldHVybiB1bnppcHBlZDtcbiAgfVxuXG4gIEpYRy5VdGlsLlVuemlwLnByb3RvdHlwZS51bnppcCA9IGZ1bmN0aW9uKCkge1xuICAgIC8vY29udmVydFRvQnl0ZUFycmF5KGlucHV0KTtcbiAgICBpZiAoZGVidWcpXG4gICAgICBhbGVydChiQSk7XG4gICAgLypmb3IgKGk9MDtpPGJBLmxlbmd0aCo4O2krKyl7XG5cdFx0ZG9jdW1lbnQud3JpdGUocmVhZEJpdCgpKTtcblx0XHRpZiAoKGkrMSklOD09MClcblx0XHRcdGRvY3VtZW50LndyaXRlKFwiIFwiKTtcblx0fSovXG4gICAgLypmb3IgKGk9MDtpPGJBLmxlbmd0aDtpKyspe1xuXHRcdGRvY3VtZW50LndyaXRlKHJlYWRCeXRlKCkrXCIgXCIpO1xuXHRcdGlmICgoaSsxKSU4PT0wKVxuXHRcdFx0ZG9jdW1lbnQud3JpdGUoXCIgXCIpO1xuXHR9XG5cdGZvciAoaT0wO2k8YkEubGVuZ3RoO2krKyl7XG5cdFx0ZG9jdW1lbnQud3JpdGUoYkFbaV0rXCIgXCIpO1xuXHRcdGlmICgoaSsxKSUxNj09MClcblx0XHRcdGRvY3VtZW50LndyaXRlKFwiPGJyPlwiKTtcblx0fVx0XG5cdCovXG4gICAgLy9hbGVydChiQSk7XG4gICAgbmV4dEZpbGUoKTtcbiAgICByZXR1cm4gdW56aXBwZWQ7XG4gIH07XG5cbiAgZnVuY3Rpb24gbmV4dEZpbGUoKSB7XG4gICAgaWYgKGRlYnVnKVxuICAgICAgYWxlcnQoXCJORVhURklMRVwiKTtcbiAgICBvdXRwdXRBcnIgPSBbXTtcbiAgICB2YXIgdG1wID0gW107XG4gICAgbW9kZVpJUCA9IGZhbHNlO1xuICAgIHRtcFswXSA9IHJlYWRCeXRlKCk7XG4gICAgdG1wWzFdID0gcmVhZEJ5dGUoKTtcbiAgICBpZiAoZGVidWcpXG4gICAgICBhbGVydChcInR5cGU6IFwiICsgdG1wWzBdICsgXCIgXCIgKyB0bXBbMV0pO1xuICAgIGlmICh0bXBbMF0gPT0gcGFyc2VJbnQoXCI3OFwiLCAxNikgJiYgdG1wWzFdID09IHBhcnNlSW50KFwiZGFcIiwgMTYpKSB7IC8vR1pJUFxuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcIkdFT05FeFQtR1pJUFwiKTtcbiAgICAgIERlZmxhdGVMb29wKCk7XG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KG91dHB1dEFyci5qb2luKCcnKSk7XG4gICAgICB1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7XG4gICAgICB1bnppcHBlZFtmaWxlc11bMF0gPSBvdXRwdXRBcnIuam9pbignJyk7XG4gICAgICB1bnppcHBlZFtmaWxlc11bMV0gPSBcImdlb25leHQuZ3h0XCI7XG4gICAgICBmaWxlcysrO1xuICAgIH1cbiAgICBpZiAodG1wWzBdID09IHBhcnNlSW50KFwiNzhcIiwgMTYpICYmIHRtcFsxXSA9PSBwYXJzZUludChcIjljXCIsIDE2KSkgeyAvL1pMSUJcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJaTElCXCIpO1xuICAgICAgRGVmbGF0ZUxvb3AoKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXSA9IG5ldyBBcnJheSgyKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IFwiWkxJQlwiO1xuICAgICAgZmlsZXMrKztcbiAgICB9XG4gICAgaWYgKHRtcFswXSA9PSBwYXJzZUludChcIjFmXCIsIDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCI4YlwiLCAxNikpIHsgLy9HWklQXG4gICAgICBpZiAoZGVidWcpXG4gICAgICAgIGFsZXJ0KFwiR1pJUFwiKTtcbiAgICAgIC8vRGVmbGF0ZUxvb3AoKTtcbiAgICAgIHNraXBkaXIoKTtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXSA9IG5ldyBBcnJheSgyKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVswXSA9IG91dHB1dEFyci5qb2luKCcnKTtcbiAgICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IFwiZmlsZVwiO1xuICAgICAgZmlsZXMrKztcbiAgICB9XG4gICAgaWYgKHRtcFswXSA9PSBwYXJzZUludChcIjUwXCIsIDE2KSAmJiB0bXBbMV0gPT0gcGFyc2VJbnQoXCI0YlwiLCAxNikpIHsgLy9aSVBcbiAgICAgIG1vZGVaSVAgPSB0cnVlO1xuICAgICAgdG1wWzJdID0gcmVhZEJ5dGUoKTtcbiAgICAgIHRtcFszXSA9IHJlYWRCeXRlKCk7XG4gICAgICBpZiAodG1wWzJdID09IHBhcnNlSW50KFwiM1wiLCAxNikgJiYgdG1wWzNdID09IHBhcnNlSW50KFwiNFwiLCAxNikpIHtcbiAgICAgICAgLy9NT0RFX1pJUFxuICAgICAgICB0bXBbMF0gPSByZWFkQnl0ZSgpO1xuICAgICAgICB0bXBbMV0gPSByZWFkQnl0ZSgpO1xuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgYWxlcnQoXCJaSVAtVmVyc2lvbjogXCIgKyB0bXBbMV0gKyBcIiBcIiArIHRtcFswXSAvIDEwICsgXCIuXCIgKyB0bXBbMF0gJSAxMCk7XG5cbiAgICAgICAgZ3BmbGFncyA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGdwZmxhZ3MgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBhbGVydChcImdwZmxhZ3M6IFwiICsgZ3BmbGFncyk7XG5cbiAgICAgICAgdmFyIG1ldGhvZCA9IHJlYWRCeXRlKCk7XG4gICAgICAgIG1ldGhvZCB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgIGFsZXJ0KFwibWV0aG9kOiBcIiArIG1ldGhvZCk7XG5cbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgICAgcmVhZEJ5dGUoKTtcblxuICAgICAgICB2YXIgY3JjID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgICAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgICAgICBjcmMgfD0gKHJlYWRCeXRlKCkgPDwgMjQpO1xuXG4gICAgICAgIHZhciBjb21wU2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgICAgICBjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgICB2YXIgc2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgMTYpO1xuICAgICAgICBzaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgICBpZiAoZGVidWcpXG4gICAgICAgICAgYWxlcnQoXCJsb2NhbCBDUkM6IFwiICsgY3JjICsgXCJcXG5sb2NhbCBTaXplOiBcIiArIHNpemUgKyBcIlxcbmxvY2FsIENvbXBTaXplOiBcIiArIGNvbXBTaXplKTtcblxuICAgICAgICB2YXIgZmlsZWxlbiA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGZpbGVsZW4gfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG5cbiAgICAgICAgdmFyIGV4dHJhbGVuID0gcmVhZEJ5dGUoKTtcbiAgICAgICAgZXh0cmFsZW4gfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG5cbiAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgIGFsZXJ0KFwiZmlsZWxlbiBcIiArIGZpbGVsZW4pO1xuICAgICAgICBpID0gMDtcbiAgICAgICAgbmFtZUJ1ZiA9IFtdO1xuICAgICAgICB3aGlsZSAoZmlsZWxlbi0tKSB7XG4gICAgICAgICAgdmFyIGMgPSByZWFkQnl0ZSgpO1xuICAgICAgICAgIGlmIChjID09IFwiL1wiIHwgYyA9PSBcIjpcIikge1xuICAgICAgICAgICAgaSA9IDA7XG4gICAgICAgICAgfSBlbHNlIGlmIChpIDwgTkFNRU1BWCAtIDEpXG4gICAgICAgICAgICBuYW1lQnVmW2krK10gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgICBhbGVydChcIm5hbWVCdWY6IFwiICsgbmFtZUJ1Zik7XG5cbiAgICAgICAgLy9uYW1lQnVmW2ldID0gXCJcXDBcIjtcbiAgICAgICAgaWYgKCFmaWxlb3V0KVxuICAgICAgICAgIGZpbGVvdXQgPSBuYW1lQnVmO1xuXG4gICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPCBleHRyYWxlbikge1xuICAgICAgICAgIGMgPSByZWFkQnl0ZSgpO1xuICAgICAgICAgIGkrKztcbiAgICAgICAgfVxuXG4gICAgICAgIENSQyA9IDB4ZmZmZmZmZmY7XG4gICAgICAgIFNJWkUgPSAwO1xuXG4gICAgICAgIGlmIChzaXplID0gMCAmJiBmaWxlT3V0LmNoYXJBdChmaWxlb3V0Lmxlbmd0aCAtIDEpID09IFwiL1wiKSB7XG4gICAgICAgICAgLy9za2lwZGlyXG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQoXCJza2lwZGlyXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRob2QgPT0gOCkge1xuICAgICAgICAgIERlZmxhdGVMb29wKCk7XG4gICAgICAgICAgaWYgKGRlYnVnKVxuICAgICAgICAgICAgYWxlcnQob3V0cHV0QXJyLmpvaW4oJycpKTtcbiAgICAgICAgICB1bnppcHBlZFtmaWxlc10gPSBuZXcgQXJyYXkoMik7XG4gICAgICAgICAgdW56aXBwZWRbZmlsZXNdWzBdID0gb3V0cHV0QXJyLmpvaW4oJycpO1xuICAgICAgICAgIHVuemlwcGVkW2ZpbGVzXVsxXSA9IG5hbWVCdWYuam9pbignJyk7XG4gICAgICAgICAgZmlsZXMrKztcbiAgICAgICAgICAvL3JldHVybiBvdXRwdXRBcnIuam9pbignJyk7XG4gICAgICAgIH1cbiAgICAgICAgc2tpcGRpcigpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBza2lwZGlyKCkge1xuICAgIHZhciBjcmMsXG4gICAgICB0bXAgPSBbXSxcbiAgICAgIGNvbXBTaXplLCBzaXplLCBvcywgaSwgYztcblxuICAgIGlmICgoZ3BmbGFncyAmIDgpKSB7XG4gICAgICB0bXBbMF0gPSByZWFkQnl0ZSgpO1xuICAgICAgdG1wWzFdID0gcmVhZEJ5dGUoKTtcbiAgICAgIHRtcFsyXSA9IHJlYWRCeXRlKCk7XG4gICAgICB0bXBbM10gPSByZWFkQnl0ZSgpO1xuXG4gICAgICBpZiAodG1wWzBdID09IHBhcnNlSW50KFwiNTBcIiwgMTYpICYmXG4gICAgICAgIHRtcFsxXSA9PSBwYXJzZUludChcIjRiXCIsIDE2KSAmJlxuICAgICAgICB0bXBbMl0gPT0gcGFyc2VJbnQoXCIwN1wiLCAxNikgJiZcbiAgICAgICAgdG1wWzNdID09IHBhcnNlSW50KFwiMDhcIiwgMTYpKSB7XG4gICAgICAgIGNyYyA9IHJlYWRCeXRlKCk7XG4gICAgICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDE2KTtcbiAgICAgICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNyYyA9IHRtcFswXSB8ICh0bXBbMV0gPDwgOCkgfCAodG1wWzJdIDw8IDE2KSB8ICh0bXBbM10gPDwgMjQpO1xuICAgICAgfVxuXG4gICAgICBjb21wU2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICBjb21wU2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCA4KTtcbiAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDE2KTtcbiAgICAgIGNvbXBTaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgc2l6ZSA9IHJlYWRCeXRlKCk7XG4gICAgICBzaXplIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgICBzaXplIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcIkNSQzpcIik7XG4gICAgfVxuXG4gICAgaWYgKG1vZGVaSVApXG4gICAgICBuZXh0RmlsZSgpO1xuXG4gICAgdG1wWzBdID0gcmVhZEJ5dGUoKTtcbiAgICBpZiAodG1wWzBdICE9IDgpIHtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJVbmtub3duIGNvbXByZXNzaW9uIG1ldGhvZCFcIik7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBncGZsYWdzID0gcmVhZEJ5dGUoKTtcbiAgICBpZiAoZGVidWcpIHtcbiAgICAgIGlmICgoZ3BmbGFncyAmIH4ocGFyc2VJbnQoXCIxZlwiLCAxNikpKSlcbiAgICAgICAgYWxlcnQoXCJVbmtub3duIGZsYWdzIHNldCFcIik7XG4gICAgfVxuXG4gICAgcmVhZEJ5dGUoKTtcbiAgICByZWFkQnl0ZSgpO1xuICAgIHJlYWRCeXRlKCk7XG4gICAgcmVhZEJ5dGUoKTtcblxuICAgIHJlYWRCeXRlKCk7XG4gICAgb3MgPSByZWFkQnl0ZSgpO1xuXG4gICAgaWYgKChncGZsYWdzICYgNCkpIHtcbiAgICAgIHRtcFswXSA9IHJlYWRCeXRlKCk7XG4gICAgICB0bXBbMl0gPSByZWFkQnl0ZSgpO1xuICAgICAgbGVuID0gdG1wWzBdICsgMjU2ICogdG1wWzFdO1xuICAgICAgaWYgKGRlYnVnKVxuICAgICAgICBhbGVydChcIkV4dHJhIGZpZWxkIHNpemU6IFwiICsgbGVuKTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgICAgcmVhZEJ5dGUoKTtcbiAgICB9XG5cbiAgICBpZiAoKGdwZmxhZ3MgJiA4KSkge1xuICAgICAgaSA9IDA7XG4gICAgICBuYW1lQnVmID0gW107XG4gICAgICB3aGlsZSAoYyA9IHJlYWRCeXRlKCkpIHtcbiAgICAgICAgaWYgKGMgPT0gXCI3XCIgfHwgYyA9PSBcIjpcIilcbiAgICAgICAgICBpID0gMDtcbiAgICAgICAgaWYgKGkgPCBOQU1FTUFYIC0gMSlcbiAgICAgICAgICBuYW1lQnVmW2krK10gPSBjO1xuICAgICAgfVxuICAgICAgLy9uYW1lQnVmW2ldID0gXCJcXDBcIjtcbiAgICAgIGlmIChkZWJ1ZylcbiAgICAgICAgYWxlcnQoXCJvcmlnaW5hbCBmaWxlIG5hbWU6IFwiICsgbmFtZUJ1Zik7XG4gICAgfVxuXG4gICAgaWYgKChncGZsYWdzICYgMTYpKSB7XG4gICAgICB3aGlsZSAoYyA9IHJlYWRCeXRlKCkpIHtcbiAgICAgICAgLy9GSUxFIENPTU1FTlRcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoKGdwZmxhZ3MgJiAyKSkge1xuICAgICAgcmVhZEJ5dGUoKTtcbiAgICAgIHJlYWRCeXRlKCk7XG4gICAgfVxuXG4gICAgRGVmbGF0ZUxvb3AoKTtcblxuICAgIGNyYyA9IHJlYWRCeXRlKCk7XG4gICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDgpO1xuICAgIGNyYyB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgY3JjIHw9IChyZWFkQnl0ZSgpIDw8IDI0KTtcblxuICAgIHNpemUgPSByZWFkQnl0ZSgpO1xuICAgIHNpemUgfD0gKHJlYWRCeXRlKCkgPDwgOCk7XG4gICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAxNik7XG4gICAgc2l6ZSB8PSAocmVhZEJ5dGUoKSA8PCAyNCk7XG5cbiAgICBpZiAobW9kZVpJUClcbiAgICAgIG5leHRGaWxlKCk7XG5cbiAgfTtcblxufTtcblxuLyoqXG4gKiAgQmFzZTY0IGVuY29kaW5nIC8gZGVjb2RpbmdcbiAqICB7QGxpbmsgaHR0cDovL3d3dy53ZWJ0b29sa2l0LmluZm8vfVxuICovXG5KWEcuVXRpbC5CYXNlNjQgPSB7XG5cbiAgLy8gcHJpdmF0ZSBwcm9wZXJ0eVxuICBfa2V5U3RyOiBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89XCIsXG5cbiAgLy8gcHVibGljIG1ldGhvZCBmb3IgZW5jb2RpbmdcbiAgZW5jb2RlOiBmdW5jdGlvbihpbnB1dCkge1xuICAgIHZhciBvdXRwdXQgPSBbXSxcbiAgICAgIGNocjEsIGNocjIsIGNocjMsIGVuYzEsIGVuYzIsIGVuYzMsIGVuYzQsXG4gICAgICBpID0gMDtcblxuICAgIGlucHV0ID0gSlhHLlV0aWwuQmFzZTY0Ll91dGY4X2VuY29kZShpbnB1dCk7XG5cbiAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkge1xuXG4gICAgICBjaHIxID0gaW5wdXQuY2hhckNvZGVBdChpKyspO1xuICAgICAgY2hyMiA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTtcbiAgICAgIGNocjMgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7XG5cbiAgICAgIGVuYzEgPSBjaHIxID4+IDI7XG4gICAgICBlbmMyID0gKChjaHIxICYgMykgPDwgNCkgfCAoY2hyMiA+PiA0KTtcbiAgICAgIGVuYzMgPSAoKGNocjIgJiAxNSkgPDwgMikgfCAoY2hyMyA+PiA2KTtcbiAgICAgIGVuYzQgPSBjaHIzICYgNjM7XG5cbiAgICAgIGlmIChpc05hTihjaHIyKSkge1xuICAgICAgICBlbmMzID0gZW5jNCA9IDY0O1xuICAgICAgfSBlbHNlIGlmIChpc05hTihjaHIzKSkge1xuICAgICAgICBlbmM0ID0gNjQ7XG4gICAgICB9XG5cbiAgICAgIG91dHB1dC5wdXNoKFt0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzEpLFxuICAgICAgICAgIHRoaXMuX2tleVN0ci5jaGFyQXQoZW5jMiksXG4gICAgICAgICAgdGhpcy5fa2V5U3RyLmNoYXJBdChlbmMzKSxcbiAgICAgICAgICB0aGlzLl9rZXlTdHIuY2hhckF0KGVuYzQpXG4gICAgICBdLmpvaW4oJycpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0LmpvaW4oJycpO1xuICB9LFxuXG4gIC8vIHB1YmxpYyBtZXRob2QgZm9yIGRlY29kaW5nXG4gIGRlY29kZTogZnVuY3Rpb24oaW5wdXQsIHV0ZjgpIHtcbiAgICB2YXIgb3V0cHV0ID0gW10sXG4gICAgICBjaHIxLCBjaHIyLCBjaHIzLFxuICAgICAgZW5jMSwgZW5jMiwgZW5jMywgZW5jNCxcbiAgICAgIGkgPSAwO1xuXG4gICAgaW5wdXQgPSBpbnB1dC5yZXBsYWNlKC9bXkEtWmEtejAtOVxcK1xcL1xcPV0vZywgXCJcIik7XG5cbiAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkge1xuXG4gICAgICBlbmMxID0gdGhpcy5fa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuICAgICAgZW5jMiA9IHRoaXMuX2tleVN0ci5pbmRleE9mKGlucHV0LmNoYXJBdChpKyspKTtcbiAgICAgIGVuYzMgPSB0aGlzLl9rZXlTdHIuaW5kZXhPZihpbnB1dC5jaGFyQXQoaSsrKSk7XG4gICAgICBlbmM0ID0gdGhpcy5fa2V5U3RyLmluZGV4T2YoaW5wdXQuY2hhckF0KGkrKykpO1xuXG4gICAgICBjaHIxID0gKGVuYzEgPDwgMikgfCAoZW5jMiA+PiA0KTtcbiAgICAgIGNocjIgPSAoKGVuYzIgJiAxNSkgPDwgNCkgfCAoZW5jMyA+PiAyKTtcbiAgICAgIGNocjMgPSAoKGVuYzMgJiAzKSA8PCA2KSB8IGVuYzQ7XG5cbiAgICAgIG91dHB1dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMSkpO1xuXG4gICAgICBpZiAoZW5jMyAhPSA2NCkge1xuICAgICAgICBvdXRwdXQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGNocjIpKTtcbiAgICAgIH1cbiAgICAgIGlmIChlbmM0ICE9IDY0KSB7XG4gICAgICAgIG91dHB1dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoY2hyMykpO1xuICAgICAgfVxuICAgIH1cblxuICAgIG91dHB1dCA9IG91dHB1dC5qb2luKCcnKTtcblxuICAgIGlmICh1dGY4KSB7XG4gICAgICBvdXRwdXQgPSBKWEcuVXRpbC5CYXNlNjQuX3V0ZjhfZGVjb2RlKG91dHB1dCk7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG5cbiAgfSxcblxuICAvLyBwcml2YXRlIG1ldGhvZCBmb3IgVVRGLTggZW5jb2RpbmdcbiAgX3V0ZjhfZW5jb2RlOiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZSgvXFxyXFxuL2csIFwiXFxuXCIpO1xuICAgIHZhciB1dGZ0ZXh0ID0gXCJcIjtcblxuICAgIGZvciAodmFyIG4gPSAwOyBuIDwgc3RyaW5nLmxlbmd0aDsgbisrKSB7XG5cbiAgICAgIHZhciBjID0gc3RyaW5nLmNoYXJDb2RlQXQobik7XG5cbiAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjKTtcbiAgICAgIH0gZWxzZSBpZiAoKGMgPiAxMjcpICYmIChjIDwgMjA0OCkpIHtcbiAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjID4+IDYpIHwgMTkyKTtcbiAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjICYgNjMpIHwgMTI4KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHV0ZnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoYyA+PiAxMikgfCAyMjQpO1xuICAgICAgICB1dGZ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChjID4+IDYpICYgNjMpIHwgMTI4KTtcbiAgICAgICAgdXRmdGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChjICYgNjMpIHwgMTI4KTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIHJldHVybiB1dGZ0ZXh0O1xuICB9LFxuXG4gIC8vIHByaXZhdGUgbWV0aG9kIGZvciBVVEYtOCBkZWNvZGluZ1xuICBfdXRmOF9kZWNvZGU6IGZ1bmN0aW9uKHV0ZnRleHQpIHtcbiAgICB2YXIgc3RyaW5nID0gW10sXG4gICAgICBpID0gMCxcbiAgICAgIGMgPSAwLFxuICAgICAgYzIgPSAwLFxuICAgICAgYzMgPSAwO1xuXG4gICAgd2hpbGUgKGkgPCB1dGZ0ZXh0Lmxlbmd0aCkge1xuICAgICAgYyA9IHV0ZnRleHQuY2hhckNvZGVBdChpKTtcbiAgICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYykpO1xuICAgICAgICBpKys7XG4gICAgICB9IGVsc2UgaWYgKChjID4gMTkxKSAmJiAoYyA8IDIyNCkpIHtcbiAgICAgICAgYzIgPSB1dGZ0ZXh0LmNoYXJDb2RlQXQoaSArIDEpO1xuICAgICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKCgoYyAmIDMxKSA8PCA2KSB8IChjMiAmIDYzKSkpO1xuICAgICAgICBpICs9IDI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjMiA9IHV0ZnRleHQuY2hhckNvZGVBdChpICsgMSk7XG4gICAgICAgIGMzID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAyKTtcbiAgICAgICAgc3RyaW5nLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZSgoKGMgJiAxNSkgPDwgMTIpIHwgKChjMiAmIDYzKSA8PCA2KSB8IChjMyAmIDYzKSkpO1xuICAgICAgICBpICs9IDM7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzdHJpbmcuam9pbignJyk7XG4gIH0sXG5cbiAgX2Rlc3RyaXA6IGZ1bmN0aW9uKHN0cmlwcGVkLCB3cmFwKSB7XG4gICAgdmFyIGxpbmVzID0gW10sXG4gICAgICBsaW5lbm8sIGksXG4gICAgICBkZXN0cmlwcGVkID0gW107XG5cbiAgICBpZiAod3JhcCA9PSBudWxsKVxuICAgICAgd3JhcCA9IDc2O1xuXG4gICAgc3RyaXBwZWQucmVwbGFjZSgvIC9nLCBcIlwiKTtcbiAgICBsaW5lbm8gPSBzdHJpcHBlZC5sZW5ndGggLyB3cmFwO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsaW5lbm87IGkrKylcbiAgICAgIGxpbmVzW2ldID0gc3RyaXBwZWQuc3Vic3RyKGkgKiB3cmFwLCB3cmFwKTtcbiAgICBpZiAobGluZW5vICE9IHN0cmlwcGVkLmxlbmd0aCAvIHdyYXApXG4gICAgICBsaW5lc1tsaW5lcy5sZW5ndGhdID0gc3RyaXBwZWQuc3Vic3RyKGxpbmVubyAqIHdyYXAsIHN0cmlwcGVkLmxlbmd0aCAtIChsaW5lbm8gKiB3cmFwKSk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspXG4gICAgICBkZXN0cmlwcGVkLnB1c2gobGluZXNbaV0pO1xuICAgIHJldHVybiBkZXN0cmlwcGVkLmpvaW4oJ1xcbicpO1xuICB9LFxuXG4gIGRlY29kZUFzQXJyYXk6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgdmFyIGRlYyA9IHRoaXMuZGVjb2RlKGlucHV0KSxcbiAgICAgIGFyID0gW10sXG4gICAgICBpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBkZWMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGFyW2ldID0gZGVjLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICAgIHJldHVybiBhcjtcbiAgfSxcblxuICBkZWNvZGVHRU9ORXhUOiBmdW5jdGlvbihpbnB1dCkge1xuICAgIHJldHVybiBkZWNvZGVBc0FycmF5KGRlc3RyaXAoaW5wdXQpLCBmYWxzZSk7XG4gIH1cbn07XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuSlhHLlV0aWwuYXNjaWlDaGFyQ29kZUF0ID0gZnVuY3Rpb24oc3RyLCBpKSB7XG4gIHZhciBjID0gc3RyLmNoYXJDb2RlQXQoaSk7XG4gIGlmIChjID4gMjU1KSB7XG4gICAgc3dpdGNoIChjKSB7XG4gICAgICBjYXNlIDgzNjQ6XG4gICAgICAgIGMgPSAxMjg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjE4OlxuICAgICAgICBjID0gMTMwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNDAyOlxuICAgICAgICBjID0gMTMxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyMjpcbiAgICAgICAgYyA9IDEzMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMzA6XG4gICAgICAgIGMgPSAxMzM7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjI0OlxuICAgICAgICBjID0gMTM0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyNTpcbiAgICAgICAgYyA9IDEzNTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDcxMDpcbiAgICAgICAgYyA9IDEzNjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyNDA6XG4gICAgICAgIGMgPSAxMzc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzNTI6XG4gICAgICAgIGMgPSAxMzg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjQ5OlxuICAgICAgICBjID0gMTM5O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzM4OlxuICAgICAgICBjID0gMTQwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzgxOlxuICAgICAgICBjID0gMTQyO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIxNjpcbiAgICAgICAgYyA9IDE0NTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMTc6XG4gICAgICAgIGMgPSAxNDY7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjIwOlxuICAgICAgICBjID0gMTQ3O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIyMTpcbiAgICAgICAgYyA9IDE0ODtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDgyMjY6XG4gICAgICAgIGMgPSAxNDk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjExOlxuICAgICAgICBjID0gMTUwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgODIxMjpcbiAgICAgICAgYyA9IDE1MTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDczMjpcbiAgICAgICAgYyA9IDE1MjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDg0ODI6XG4gICAgICAgIGMgPSAxNTM7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzNTM6XG4gICAgICAgIGMgPSAxNTQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA4MjUwOlxuICAgICAgICBjID0gMTU1O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzM5OlxuICAgICAgICBjID0gMTU2O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzgyOlxuICAgICAgICBjID0gMTU4O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzc2OlxuICAgICAgICBjID0gMTU5O1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYztcbn07XG5cbi8qKlxuICogRGVjb2Rpbmcgc3RyaW5nIGludG8gdXRmLThcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJpbmcgdG8gZGVjb2RlXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHV0ZjggZGVjb2RlZCBzdHJpbmdcbiAqL1xuSlhHLlV0aWwudXRmOERlY29kZSA9IGZ1bmN0aW9uKHV0ZnRleHQpIHtcbiAgdmFyIHN0cmluZyA9IFtdO1xuICB2YXIgaSA9IDA7XG4gIHZhciBjID0gMCxcbiAgICBjMSA9IDAsXG4gICAgYzIgPSAwLFxuICAgIGMzO1xuICBpZiAoIUpYRy5leGlzdHModXRmdGV4dCkpIHJldHVybiAnJztcblxuICB3aGlsZSAoaSA8IHV0ZnRleHQubGVuZ3RoKSB7XG4gICAgYyA9IHV0ZnRleHQuY2hhckNvZGVBdChpKTtcblxuICAgIGlmIChjIDwgMTI4KSB7XG4gICAgICBzdHJpbmcucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGMpKTtcbiAgICAgIGkrKztcbiAgICB9IGVsc2UgaWYgKChjID4gMTkxKSAmJiAoYyA8IDIyNCkpIHtcbiAgICAgIGMyID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAxKTtcbiAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoKChjICYgMzEpIDw8IDYpIHwgKGMyICYgNjMpKSk7XG4gICAgICBpICs9IDI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGMyID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAxKTtcbiAgICAgIGMzID0gdXRmdGV4dC5jaGFyQ29kZUF0KGkgKyAyKTtcbiAgICAgIHN0cmluZy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoKChjICYgMTUpIDw8IDEyKSB8ICgoYzIgJiA2MykgPDwgNikgfCAoYzMgJiA2MykpKTtcbiAgICAgIGkgKz0gMztcbiAgICB9XG4gIH07XG4gIHJldHVybiBzdHJpbmcuam9pbignJyk7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlIGEgcmFuZG9tIHV1aWQuXG4gKiBodHRwOi8vd3d3LmJyb29mYS5jb21cbiAqIG1haWx0bzpyb2JlcnRAYnJvb2ZhLmNvbVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMCBSb2JlcnQgS2llZmZlclxuICogRHVhbCBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGFuZCBHUEwgbGljZW5zZXMuXG4gKlxuICogRVhBTVBMRVM6XG4gKiAgID4+PiBNYXRoLnV1aWQoKVxuICogICBcIjkyMzI5RDM5LTZGNUMtNDUyMC1BQkZDLUFBQjY0NTQ0RTE3MlwiXG4gKi9cbkpYRy5VdGlsLmdlblVVSUQgPSBmdW5jdGlvbigpIHtcbiAgLy8gUHJpdmF0ZSBhcnJheSBvZiBjaGFycyB0byB1c2VcbiAgdmFyIGNoYXJzID0gJzAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6Jy5zcGxpdCgnJyksXG4gICAgdXVpZCA9IG5ldyBBcnJheSgzNiksXG4gICAgcm5kID0gMCxcbiAgICByO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzY7IGkrKykge1xuICAgIGlmIChpID09IDggfHwgaSA9PSAxMyB8fCBpID09IDE4IHx8IGkgPT0gMjMpIHtcbiAgICAgIHV1aWRbaV0gPSAnLSc7XG4gICAgfSBlbHNlIGlmIChpID09IDE0KSB7XG4gICAgICB1dWlkW2ldID0gJzQnO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocm5kIDw9IDB4MDIpIHJuZCA9IDB4MjAwMDAwMCArIChNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwKSB8IDA7XG4gICAgICByID0gcm5kICYgMHhmO1xuICAgICAgcm5kID0gcm5kID4+IDQ7XG4gICAgICB1dWlkW2ldID0gY2hhcnNbKGkgPT0gMTkpID8gKHIgJiAweDMpIHwgMHg4IDogcl07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHV1aWQuam9pbignJyk7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gSlhHO1xuIiwiLy8gTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIIFxuXG4vLyBtb2RpZmllZCB2ZXJzaW9uIG9mIGh0dHA6Ly93d3cuaGFuZXdpbi5uZXQvZW5jcnlwdC9QR2RlY29kZS5qczpcblxuLyogT3BlblBHUCBlbmNyeXB0aW9uIHVzaW5nIFJTQS9BRVNcbiAqIENvcHlyaWdodCAyMDA1LTIwMDYgSGVyYmVydCBIYW5ld2lua2VsLCB3d3cuaGFuZVdJTi5kZVxuICogdmVyc2lvbiAyLjAsIGNoZWNrIHd3dy5oYW5lV0lOLmRlIGZvciB0aGUgbGF0ZXN0IHZlcnNpb25cblxuICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCBhcy1pcywgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuICBcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUgb3Igc2VsbCB0aGlzIHNvZnR3YXJlLCB3aXRoIG9yXG4gKiB3aXRob3V0IGZlZSwgZm9yIGFueSBwdXJwb3NlIGFuZCBieSBhbnkgaW5kaXZpZHVhbCBvciBvcmdhbml6YXRpb24sIGlzIGhlcmVieVxuICogZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwYXJhZ3JhcGggYXBwZWFyIFxuICogaW4gYWxsIGNvcGllcy4gRGlzdHJpYnV0aW9uIGFzIGEgcGFydCBvZiBhbiBhcHBsaWNhdGlvbiBvciBiaW5hcnkgbXVzdFxuICogaW5jbHVkZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXJcbiAqIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBhcHBsaWNhdGlvbiBvciBkaXN0cmlidXRpb24uXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNpcGhlciA9IHJlcXVpcmUoJy4vY2lwaGVyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXG4gIC8qKlxuICAgKiBBbiBhcnJheSBvZiBieXRlcywgdGhhdCBpcyBpbnRlZ2VycyB3aXRoIHZhbHVlcyBmcm9tIDAgdG8gMjU1XG4gICAqIEB0eXBlZGVmIHsoQXJyYXl8VWludDhBcnJheSl9IG9wZW5wZ3BfYnl0ZV9hcnJheVxuICAgKi9cblxuICAvKipcbiAgICogQmxvY2sgY2lwaGVyIGZ1bmN0aW9uXG4gICAqIEBjYWxsYmFjayBvcGVucGdwX2NpcGhlcl9ibG9ja19mblxuICAgKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZV9hcnJheX0gYmxvY2sgQSBibG9jayB0byBwZXJmb3JtIG9wZXJhdGlvbnMgb25cbiAgICogQHBhcmFtIHtvcGVucGdwX2J5dGVfYXJyYXl9IGtleSB0byB1c2UgaW4gZW5jcnlwdGlvbi9kZWNyeXB0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfYnl0ZV9hcnJheX0gRW5jcnlwdGVkL2RlY3J5cHRlZCBibG9ja1xuICAgKi9cblxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGVuY3J5cHRzIGEgZ2l2ZW4gd2l0aCB0aGUgc3BlY2lmaWVkIHByZWZpeHJhbmRvbSBcbiAgICogdXNpbmcgdGhlIHNwZWNpZmllZCBibG9ja2NpcGhlciB0byBlbmNyeXB0IGEgbWVzc2FnZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gcHJlZml4cmFuZG9tIHJhbmRvbSBieXRlcyBvZiBibG9ja19zaXplIGxlbmd0aCBwcm92aWRlZCBcbiAgICogIGFzIGEgc3RyaW5nIHRvIGJlIHVzZWQgaW4gcHJlZml4aW5nIHRoZSBkYXRhXG4gICAqIEBwYXJhbSB7b3BlbnBncF9jaXBoZXJfYmxvY2tfZm59IGJsb2NrY2lwaGVyZm4gdGhlIGFsZ29yaXRobSBlbmNyeXB0IGZ1bmN0aW9uIHRvIGVuY3J5cHRcbiAgICogIGRhdGEgaW4gb25lIGJsb2NrX3NpemUgZW5jcnlwdGlvbi4gXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYmxvY2tfc2l6ZSB0aGUgYmxvY2sgc2l6ZSBpbiBieXRlcyBvZiB0aGUgYWxnb3JpdGhtIHVzZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBsYWludGV4dCBkYXRhIHRvIGJlIGVuY3J5cHRlZCBwcm92aWRlZCBhcyBhIHN0cmluZ1xuICAgKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZV9hcnJheX0ga2V5IGtleSB0byBiZSB1c2VkIHRvIGVuY3J5cHQgdGhlIGRhdGEuIFRoaXMgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIFxuICAgKiAgYmxvY2tjaXBoZXJmblxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlc3luYyBhIGJvb2xlYW4gdmFsdWUgc3BlY2lmeWluZyBpZiBhIHJlc3luYyBvZiB0aGUgXG4gICAqICBJViBzaG91bGQgYmUgdXNlZCBvciBub3QuIFRoZSBlbmNyeXB0ZWRkYXRhcGFja2V0IHVzZXMgdGhlIFxuICAgKiAgXCJvbGRcIiBzdHlsZSB3aXRoIGEgcmVzeW5jLiBFbmNyeXB0aW9uIHdpdGhpbiBhbiBcbiAgICogIGVuY3J5cHRlZGludGVncml0eXByb3RlY3RlZGRhdGEgcGFja2V0IGlzIG5vdCByZXN5bmNpbmcgdGhlIElWLlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGEgc3RyaW5nIHdpdGggdGhlIGVuY3J5cHRlZCBkYXRhXG4gICAqL1xuICBlbmNyeXB0OiBmdW5jdGlvbihwcmVmaXhyYW5kb20sIGNpcGhlcmZuLCBwbGFpbnRleHQsIGtleSwgcmVzeW5jKSB7XG4gICAgY2lwaGVyZm4gPSBuZXcgY2lwaGVyW2NpcGhlcmZuXShrZXkpO1xuICAgIHZhciBibG9ja19zaXplID0gY2lwaGVyZm4uYmxvY2tTaXplO1xuXG4gICAgdmFyIEZSID0gbmV3IEFycmF5KGJsb2NrX3NpemUpO1xuICAgIHZhciBGUkUgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG5cbiAgICBwcmVmaXhyYW5kb20gPSBwcmVmaXhyYW5kb20gKyBwcmVmaXhyYW5kb20uY2hhckF0KGJsb2NrX3NpemUgLSAyKSArIHByZWZpeHJhbmRvbS5jaGFyQXQoYmxvY2tfc2l6ZSAtIDEpO1xuICAgIHV0aWwucHJpbnRfZGVidWcoXCJwcmVmaXhyYW5kb206XCIgKyB1dGlsLmhleHN0cmR1bXAocHJlZml4cmFuZG9tKSk7XG4gICAgdmFyIGNpcGhlcnRleHQgPSBcIlwiO1xuICAgIC8vIDEuICBUaGUgZmVlZGJhY2sgcmVnaXN0ZXIgKEZSKSBpcyBzZXQgdG8gdGhlIElWLCB3aGljaCBpcyBhbGwgemVyb3MuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gMDtcblxuICAgIC8vIDIuICBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUgKEZSIEVuY3J5cHRlZCkuICBUaGlzIGlzIHRoZVxuICAgIC8vICAgICBlbmNyeXB0aW9uIG9mIGFuIGFsbC16ZXJvIHZhbHVlLlxuICAgIEZSRSA9IGNpcGhlcmZuLmVuY3J5cHQoRlIpO1xuICAgIC8vIDMuICBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgZmlyc3QgQlMgb2N0ZXRzIG9mIHJhbmRvbSBkYXRhIHByZWZpeGVkIHRvXG4gICAgLy8gICAgIHRoZSBwbGFpbnRleHQgdG8gcHJvZHVjZSBDWzFdIHRocm91Z2ggQ1tCU10sIHRoZSBmaXJzdCBCUyBvY3RldHNcbiAgICAvLyAgICAgb2YgY2lwaGVydGV4dC5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgY2lwaGVydGV4dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHByZWZpeHJhbmRvbS5jaGFyQ29kZUF0KGkpKTtcblxuICAgIC8vIDQuICBGUiBpcyBsb2FkZWQgd2l0aCBDWzFdIHRocm91Z2ggQ1tCU10uXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGkpO1xuXG4gICAgLy8gNS4gIEZSIGlzIGVuY3J5cHRlZCB0byBwcm9kdWNlIEZSRSwgdGhlIGVuY3J5cHRpb24gb2YgdGhlIGZpcnN0IEJTXG4gICAgLy8gXHQgICBvY3RldHMgb2YgY2lwaGVydGV4dC5cbiAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSKTtcblxuICAgIC8vIDYuICBUaGUgbGVmdCB0d28gb2N0ZXRzIG9mIEZSRSBnZXQgeG9yZWQgd2l0aCB0aGUgbmV4dCB0d28gb2N0ZXRzIG9mXG4gICAgLy8gICAgIGRhdGEgdGhhdCB3ZXJlIHByZWZpeGVkIHRvIHRoZSBwbGFpbnRleHQuICBUaGlzIHByb2R1Y2VzIENbQlMrMV1cbiAgICAvLyAgICAgYW5kIENbQlMrMl0sIHRoZSBuZXh0IHR3byBvY3RldHMgb2YgY2lwaGVydGV4dC5cbiAgICBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFWzBdIF4gcHJlZml4cmFuZG9tLmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSkpO1xuICAgIGNpcGhlcnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbMV0gXiBwcmVmaXhyYW5kb20uY2hhckNvZGVBdChibG9ja19zaXplICsgMSkpO1xuXG4gICAgaWYgKHJlc3luYykge1xuICAgICAgLy8gNy4gIChUaGUgcmVzeW5jIHN0ZXApIEZSIGlzIGxvYWRlZCB3aXRoIEMzLUMxMC5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpICsgMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBGUltpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpKTtcbiAgICB9XG4gICAgLy8gOC4gIEZSIGlzIGVuY3J5cHRlZCB0byBwcm9kdWNlIEZSRS5cbiAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSLCBrZXkpO1xuXG4gICAgaWYgKHJlc3luYykge1xuICAgICAgLy8gOS4gIEZSRSBpcyB4b3JlZCB3aXRoIHRoZSBmaXJzdCA4IG9jdGV0cyBvZiB0aGUgZ2l2ZW4gcGxhaW50ZXh0LCBub3dcbiAgICAgIC8vXHQgICB0aGF0IHdlIGhhdmUgZmluaXNoZWQgZW5jcnlwdGluZyB0aGUgMTAgb2N0ZXRzIG9mIHByZWZpeGVkIGRhdGEuXG4gICAgICAvLyBcdCAgIFRoaXMgcHJvZHVjZXMgQzExLUMxOCwgdGhlIG5leHQgOCBvY3RldHMgb2YgY2lwaGVydGV4dC5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKVxuICAgICAgICBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQoaSkpO1xuICAgICAgZm9yIChuID0gYmxvY2tfc2l6ZSArIDI7IG4gPCBwbGFpbnRleHQubGVuZ3RoOyBuICs9IGJsb2NrX3NpemUpIHtcbiAgICAgICAgLy8gMTAuIEZSIGlzIGxvYWRlZCB3aXRoIEMxMS1DMThcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIEZSW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KG4gKyBpKTtcblxuICAgICAgICAvLyAxMS4gRlIgaXMgZW5jcnlwdGVkIHRvIHByb2R1Y2UgRlJFLlxuICAgICAgICBGUkUgPSBjaXBoZXJmbi5lbmNyeXB0KEZSKTtcblxuICAgICAgICAvLyAxMi4gRlJFIGlzIHhvcmVkIHdpdGggdGhlIG5leHQgOCBvY3RldHMgb2YgcGxhaW50ZXh0LCB0byBwcm9kdWNlIHRoZVxuICAgICAgICAvLyBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuICBUaGVzZSBhcmUgbG9hZGVkIGludG8gRlIgYW5kIHRoZVxuICAgICAgICAvLyBwcm9jZXNzIGlzIHJlcGVhdGVkIHVudGlsIHRoZSBwbGFpbnRleHQgaXMgdXNlZCB1cC5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGNpcGhlcnRleHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShGUkVbaV0gXiBwbGFpbnRleHQuY2hhckNvZGVBdCgobiAtIDIpICtcbiAgICAgICAgICAgIGkpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcGxhaW50ZXh0ID0gXCIgIFwiICsgcGxhaW50ZXh0O1xuICAgICAgLy8gOS4gIEZSRSBpcyB4b3JlZCB3aXRoIHRoZSBmaXJzdCA4IG9jdGV0cyBvZiB0aGUgZ2l2ZW4gcGxhaW50ZXh0LCBub3dcbiAgICAgIC8vXHQgICB0aGF0IHdlIGhhdmUgZmluaXNoZWQgZW5jcnlwdGluZyB0aGUgMTAgb2N0ZXRzIG9mIHByZWZpeGVkIGRhdGEuXG4gICAgICAvLyBcdCAgIFRoaXMgcHJvZHVjZXMgQzExLUMxOCwgdGhlIG5leHQgOCBvY3RldHMgb2YgY2lwaGVydGV4dC5cbiAgICAgIGZvciAodmFyIGkgPSAyOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSBjaXBoZXJ0ZXh0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQoaSkpO1xuICAgICAgdmFyIHRlbXBDaXBoZXJ0ZXh0ID0gY2lwaGVydGV4dC5zdWJzdHJpbmcoMCwgMiAqIGJsb2NrX3NpemUpLnNwbGl0KCcnKTtcbiAgICAgIHZhciB0ZW1wQ2lwaGVydGV4dFN0cmluZyA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKGJsb2NrX3NpemUpO1xuICAgICAgZm9yIChuID0gYmxvY2tfc2l6ZTsgbiA8IHBsYWludGV4dC5sZW5ndGg7IG4gKz0gYmxvY2tfc2l6ZSkge1xuICAgICAgICAvLyAxMC4gRlIgaXMgbG9hZGVkIHdpdGggQzExLUMxOFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgRlJbaV0gPSB0ZW1wQ2lwaGVydGV4dFN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICAgICAgICB0ZW1wQ2lwaGVydGV4dFN0cmluZyA9ICcnO1xuXG4gICAgICAgIC8vIDExLiBGUiBpcyBlbmNyeXB0ZWQgdG8gcHJvZHVjZSBGUkUuXG4gICAgICAgIEZSRSA9IGNpcGhlcmZuLmVuY3J5cHQoRlIpO1xuXG4gICAgICAgIC8vIDEyLiBGUkUgaXMgeG9yZWQgd2l0aCB0aGUgbmV4dCA4IG9jdGV0cyBvZiBwbGFpbnRleHQsIHRvIHByb2R1Y2UgdGhlXG4gICAgICAgIC8vICAgICBuZXh0IDggb2N0ZXRzIG9mIGNpcGhlcnRleHQuICBUaGVzZSBhcmUgbG9hZGVkIGludG8gRlIgYW5kIHRoZVxuICAgICAgICAvLyAgICAgcHJvY2VzcyBpcyByZXBlYXRlZCB1bnRpbCB0aGUgcGxhaW50ZXh0IGlzIHVzZWQgdXAuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSB7XG4gICAgICAgICAgdGVtcENpcGhlcnRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKEZSRVtpXSBeIHBsYWludGV4dC5jaGFyQ29kZUF0KG4gKyBpKSkpO1xuICAgICAgICAgIHRlbXBDaXBoZXJ0ZXh0U3RyaW5nICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoRlJFW2ldIF4gcGxhaW50ZXh0LmNoYXJDb2RlQXQobiArIGkpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY2lwaGVydGV4dCA9IHRlbXBDaXBoZXJ0ZXh0LmpvaW4oJycpO1xuXG4gICAgfVxuXG4gICAgY2lwaGVydGV4dCA9IGNpcGhlcnRleHQuc3Vic3RyaW5nKDAsIHBsYWludGV4dC5sZW5ndGggKyAyICsgYmxvY2tfc2l6ZSk7XG5cbiAgICByZXR1cm4gY2lwaGVydGV4dDtcbiAgfSxcblxuICAvKipcbiAgICogRGVjcnlwdHMgdGhlIHByZWZpeGVkIGRhdGEgZm9yIHRoZSBNb2RpZmljYXRpb24gRGV0ZWN0aW9uIENvZGUgKE1EQykgY29tcHV0YXRpb25cbiAgICogQHBhcmFtIHtvcGVucGdwX2Jsb2NrX2NpcGhlcl9mbn0gY2lwaGVyZm4uZW5jcnlwdCBDaXBoZXIgZnVuY3Rpb24gdG8gdXNlXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYmxvY2tfc2l6ZSBCbG9ja3NpemUgb2YgdGhlIGFsZ29yaXRobVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfYnl0ZV9hcnJheX0ga2V5IFRoZSBrZXkgZm9yIGVuY3J5cHRpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IGNpcGhlcnRleHQgVGhlIGVuY3J5cHRlZCBkYXRhXG4gICAqIEByZXR1cm4ge1N0cmluZ30gcGxhaW50ZXh0IERhdGEgb2YgRChjaXBoZXJ0ZXh0KSB3aXRoIGJsb2Nrc2l6ZSBsZW5ndGggKzJcbiAgICovXG4gIG1kYzogZnVuY3Rpb24oY2lwaGVyZm4sIGtleSwgY2lwaGVydGV4dCkge1xuICAgIGNpcGhlcmZuID0gbmV3IGNpcGhlcltjaXBoZXJmbl0oa2V5KTtcbiAgICB2YXIgYmxvY2tfc2l6ZSA9IGNpcGhlcmZuLmJsb2NrU2l6ZTtcblxuICAgIHZhciBpYmxvY2sgPSBuZXcgQXJyYXkoYmxvY2tfc2l6ZSk7XG4gICAgdmFyIGFibG9jayA9IG5ldyBBcnJheShibG9ja19zaXplKTtcbiAgICB2YXIgaTtcblxuXG4gICAgLy8gaW5pdGlhbGlzYXRpb24gdmVjdG9yXG4gICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgaWJsb2NrW2ldID0gMDtcblxuICAgIGlibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoaWJsb2NrKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSB7XG4gICAgICBhYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSk7XG4gICAgICBpYmxvY2tbaV0gXj0gYWJsb2NrW2ldO1xuICAgIH1cblxuICAgIGFibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoYWJsb2NrKTtcblxuICAgIHJldHVybiB1dGlsLmJpbjJzdHIoaWJsb2NrKSArXG4gICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGFibG9ja1swXSBeIGNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplKSkgK1xuICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZShhYmxvY2tbMV0gXiBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoYmxvY2tfc2l6ZSArIDEpKTtcbiAgfSxcbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gZGVjcnlwdHMgYSBnaXZlbiBwbGFpbnRleHQgdXNpbmcgdGhlIHNwZWNpZmllZFxuICAgKiBibG9ja2NpcGhlciB0byBkZWNyeXB0IGEgbWVzc2FnZVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfY2lwaGVyX2Jsb2NrX2ZufSBibG9ja2NpcGhlcmZuIFRoZSBhbGdvcml0aG0gX2VuY3J5cHRfIGZ1bmN0aW9uIHRvIGVuY3J5cHRcbiAgICogIGRhdGEgaW4gb25lIGJsb2NrX3NpemUgZW5jcnlwdGlvbi5cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBibG9ja19zaXplIHRoZSBibG9jayBzaXplIGluIGJ5dGVzIG9mIHRoZSBhbGdvcml0aG0gdXNlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGxhaW50ZXh0IGNpcGhlcnRleHQgdG8gYmUgZGVjcnlwdGVkIHByb3ZpZGVkIGFzIGEgc3RyaW5nXG4gICAqIEBwYXJhbSB7b3BlbnBncF9ieXRlX2FycmF5fSBrZXkga2V5IHRvIGJlIHVzZWQgdG8gZGVjcnlwdCB0aGUgY2lwaGVydGV4dC4gVGhpcyB3aWxsIGJlIHBhc3NlZCB0byB0aGUgXG4gICAqICBibG9ja2NpcGhlcmZuXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVzeW5jIGEgYm9vbGVhbiB2YWx1ZSBzcGVjaWZ5aW5nIGlmIGEgcmVzeW5jIG9mIHRoZSBcbiAgICogIElWIHNob3VsZCBiZSB1c2VkIG9yIG5vdC4gVGhlIGVuY3J5cHRlZGRhdGFwYWNrZXQgdXNlcyB0aGUgXG4gICAqICBcIm9sZFwiIHN0eWxlIHdpdGggYSByZXN5bmMuIERlY3J5cHRpb24gd2l0aGluIGFuIFxuICAgKiAgZW5jcnlwdGVkaW50ZWdyaXR5cHJvdGVjdGVkZGF0YSBwYWNrZXQgaXMgbm90IHJlc3luY2luZyB0aGUgSVYuXG4gICAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmcgd2l0aCB0aGUgcGxhaW50ZXh0IGRhdGFcbiAgICovXG5cbiAgZGVjcnlwdDogZnVuY3Rpb24oY2lwaGVyZm4sIGtleSwgY2lwaGVydGV4dCwgcmVzeW5jKSB7XG4gICAgY2lwaGVyZm4gPSBuZXcgY2lwaGVyW2NpcGhlcmZuXShrZXkpO1xuICAgIHZhciBibG9ja19zaXplID0gY2lwaGVyZm4uYmxvY2tTaXplO1xuXG4gICAgdmFyIGlibG9jayA9IG5ldyBBcnJheShibG9ja19zaXplKTtcbiAgICB2YXIgYWJsb2NrID0gbmV3IEFycmF5KGJsb2NrX3NpemUpO1xuICAgIHZhciBpLCBuID0gJyc7XG4gICAgdmFyIHRleHQgPSBbXTtcblxuICAgIC8vIGluaXRpYWxpc2F0aW9uIHZlY3RvclxuICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGlibG9ja1tpXSA9IDA7XG5cbiAgICBpYmxvY2sgPSBjaXBoZXJmbi5lbmNyeXB0KGlibG9jaywga2V5KTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZTsgaSsrKSB7XG4gICAgICBhYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQoaSk7XG4gICAgICBpYmxvY2tbaV0gXj0gYWJsb2NrW2ldO1xuICAgIH1cblxuICAgIGFibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQoYWJsb2NrLCBrZXkpO1xuXG4gICAgLy8gdGVzdCBjaGVjayBvY3RldHNcbiAgICBpZiAoaWJsb2NrW2Jsb2NrX3NpemUgLSAyXSAhPSAoYWJsb2NrWzBdIF4gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGJsb2NrX3NpemUpKSB8fCBpYmxvY2tbYmxvY2tfc2l6ZSAtIDFdICE9IChhYmxvY2tbXG4gICAgICAxXSBeIGNpcGhlcnRleHQuY2hhckNvZGVBdChibG9ja19zaXplICsgMSkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgZGF0YS4nKTtcbiAgICB9XG5cbiAgICAvKiAgUkZDNDg4MDogVGFnIDE4IGFuZCBSZXN5bmM6XG5cdFx0ICogIFsuLi5dIFVubGlrZSB0aGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQsIG5vXG5cdFx0ICogIHNwZWNpYWwgQ0ZCIHJlc3luY2hyb25pemF0aW9uIGlzIGRvbmUgYWZ0ZXIgZW5jcnlwdGluZyB0aGlzIHByZWZpeFxuXHRcdCAqICBkYXRhLiAgU2VlIFwiT3BlblBHUCBDRkIgTW9kZVwiIGJlbG93IGZvciBtb3JlIGRldGFpbHMuXG5cblx0XHQgKi9cblxuICAgIGlmIChyZXN5bmMpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGlibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChpICsgMik7XG4gICAgICBmb3IgKG4gPSBibG9ja19zaXplICsgMjsgbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBuICs9IGJsb2NrX3NpemUpIHtcbiAgICAgICAgYWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChpYmxvY2spO1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBibG9ja19zaXplICYmIGkgKyBuIDwgY2lwaGVydGV4dC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlibG9ja1tpXSA9IGNpcGhlcnRleHQuY2hhckNvZGVBdChuICsgaSk7XG4gICAgICAgICAgdGV4dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYWJsb2NrW2ldIF4gaWJsb2NrW2ldKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChpID0gMDsgaSA8IGJsb2NrX3NpemU7IGkrKykgaWJsb2NrW2ldID0gY2lwaGVydGV4dC5jaGFyQ29kZUF0KGkpO1xuICAgICAgZm9yIChuID0gYmxvY2tfc2l6ZTsgbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBuICs9IGJsb2NrX3NpemUpIHtcbiAgICAgICAgYWJsb2NrID0gY2lwaGVyZm4uZW5jcnlwdChpYmxvY2spO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYmxvY2tfc2l6ZSAmJiBpICsgbiA8IGNpcGhlcnRleHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpYmxvY2tbaV0gPSBjaXBoZXJ0ZXh0LmNoYXJDb2RlQXQobiArIGkpO1xuICAgICAgICAgIHRleHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGFibG9ja1tpXSBeIGlibG9ja1tpXSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIG4gPSByZXN5bmMgPyAwIDogMjtcblxuICAgIHRleHQgPSB0ZXh0LmpvaW4oJycpO1xuXG4gICAgdGV4dCA9IHRleHQuc3Vic3RyaW5nKG4sIGNpcGhlcnRleHQubGVuZ3RoIC0gYmxvY2tfc2l6ZSAtIDIgKyBuKTtcblxuXG4gICAgcmV0dXJuIHRleHQ7XG4gIH0sXG5cblxuICBub3JtYWxFbmNyeXB0OiBmdW5jdGlvbihjaXBoZXJmbiwga2V5LCBwbGFpbnRleHQsIGl2KSB7XG4gICAgY2lwaGVyZm4gPSBuZXcgY2lwaGVyW2NpcGhlcmZuXShrZXkpO1xuICAgIHZhciBibG9ja19zaXplID0gY2lwaGVyZm4uYmxvY2tTaXplO1xuXG4gICAgdmFyIGJsb2NraSA9IFwiXCI7XG4gICAgdmFyIGJsb2NrYyA9IFwiXCI7XG4gICAgdmFyIHBvcyA9IDA7XG4gICAgdmFyIGN5cGhlcnRleHQgPSBbXTtcbiAgICB2YXIgdGVtcEJsb2NrID0gW107XG4gICAgYmxvY2tjID0gaXYuc3Vic3RyaW5nKDAsIGJsb2NrX3NpemUpO1xuICAgIHdoaWxlIChwbGFpbnRleHQubGVuZ3RoID4gYmxvY2tfc2l6ZSAqIHBvcykge1xuICAgICAgdmFyIGVuY2Jsb2NrID0gY2lwaGVyZm4uZW5jcnlwdCh1dGlsLnN0cjJiaW4oYmxvY2tjKSk7XG4gICAgICBibG9ja2kgPSBwbGFpbnRleHQuc3Vic3RyaW5nKChwb3MgKiBibG9ja19zaXplKSwgKHBvcyAqIGJsb2NrX3NpemUpICsgYmxvY2tfc2l6ZSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NraS5sZW5ndGg7IGkrKylcbiAgICAgICAgdGVtcEJsb2NrLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShibG9ja2kuY2hhckNvZGVBdChpKSBeIGVuY2Jsb2NrW2ldKSk7XG4gICAgICBibG9ja2MgPSB0ZW1wQmxvY2suam9pbignJyk7XG4gICAgICB0ZW1wQmxvY2sgPSBbXTtcbiAgICAgIGN5cGhlcnRleHQucHVzaChibG9ja2MpO1xuICAgICAgcG9zKys7XG4gICAgfVxuICAgIHJldHVybiBjeXBoZXJ0ZXh0LmpvaW4oJycpO1xuICB9LFxuXG4gIG5vcm1hbERlY3J5cHQ6IGZ1bmN0aW9uKGNpcGhlcmZuLCBrZXksIGNpcGhlcnRleHQsIGl2KSB7XG4gICAgY2lwaGVyZm4gPSBuZXcgY2lwaGVyW2NpcGhlcmZuXShrZXkpO1xuICAgIHZhciBibG9ja19zaXplID0gY2lwaGVyZm4uYmxvY2tTaXplO1xuXG4gICAgdmFyIGJsb2NrcCA9IFwiXCI7XG4gICAgdmFyIHBvcyA9IDA7XG4gICAgdmFyIHBsYWludGV4dCA9IFtdO1xuICAgIHZhciBvZmZzZXQgPSAwO1xuICAgIGlmIChpdiA9PSBudWxsKVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja19zaXplOyBpKyspIGJsb2NrcCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuICAgIGVsc2VcbiAgICAgIGJsb2NrcCA9IGl2LnN1YnN0cmluZygwLCBibG9ja19zaXplKTtcbiAgICB3aGlsZSAoY2lwaGVydGV4dC5sZW5ndGggPiAoYmxvY2tfc2l6ZSAqIHBvcykpIHtcbiAgICAgIHZhciBkZWNibG9jayA9IGNpcGhlcmZuLmVuY3J5cHQodXRpbC5zdHIyYmluKGJsb2NrcCkpO1xuICAgICAgYmxvY2twID0gY2lwaGVydGV4dC5zdWJzdHJpbmcoKHBvcyAqIChibG9ja19zaXplKSkgKyBvZmZzZXQsIChwb3MgKiAoYmxvY2tfc2l6ZSkpICsgKGJsb2NrX3NpemUpICsgb2Zmc2V0KTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2twLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHBsYWludGV4dC5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoYmxvY2twLmNoYXJDb2RlQXQoaSkgXiBkZWNibG9ja1tpXSkpO1xuICAgICAgfVxuICAgICAgcG9zKys7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBsYWludGV4dC5qb2luKCcnKTtcbiAgfVxufVxuIiwiLyogUmlqbmRhZWwgKEFFUykgRW5jcnlwdGlvblxuICogQ29weXJpZ2h0IDIwMDUgSGVyYmVydCBIYW5ld2lua2VsLCB3d3cuaGFuZVdJTi5kZVxuICogdmVyc2lvbiAxLjEsIGNoZWNrIHd3dy5oYW5lV0lOLmRlIGZvciB0aGUgbGF0ZXN0IHZlcnNpb25cblxuICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCBhcy1pcywgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuICBcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUgb3Igc2VsbCB0aGlzIHNvZnR3YXJlLCB3aXRoIG9yXG4gKiB3aXRob3V0IGZlZSwgZm9yIGFueSBwdXJwb3NlIGFuZCBieSBhbnkgaW5kaXZpZHVhbCBvciBvcmdhbml6YXRpb24sIGlzIGhlcmVieVxuICogZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwYXJhZ3JhcGggYXBwZWFyIFxuICogaW4gYWxsIGNvcGllcy4gRGlzdHJpYnV0aW9uIGFzIGEgcGFydCBvZiBhbiBhcHBsaWNhdGlvbiBvciBiaW5hcnkgbXVzdFxuICogaW5jbHVkZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXJcbiAqIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBhcHBsaWNhdGlvbiBvciBkaXN0cmlidXRpb24uXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbi8vIFRoZSByb3VuZCBjb25zdGFudHMgdXNlZCBpbiBzdWJrZXkgZXhwYW5zaW9uXG52YXIgUmNvbiA9IFtcbiAgICAweDAxLCAweDAyLCAweDA0LCAweDA4LCAweDEwLCAweDIwLCAweDQwLCAweDgwLCAweDFiLCAweDM2LCAweDZjLCAweGQ4LFxuICAgIDB4YWIsIDB4NGQsIDB4OWEsIDB4MmYsIDB4NWUsIDB4YmMsIDB4NjMsIDB4YzYsIDB4OTcsIDB4MzUsIDB4NmEsIDB4ZDQsXG4gICAgMHhiMywgMHg3ZCwgMHhmYSwgMHhlZiwgMHhjNSwgMHg5MVxuXTtcblxuLy8gUHJlY29tcHV0ZWQgbG9va3VwIHRhYmxlIGZvciB0aGUgU0JveFxudmFyIFMgPSBbXG4gICAgOTksIDEyNCwgMTE5LCAxMjMsIDI0MiwgMTA3LCAxMTEsIDE5NywgNDgsIDEsIDEwMywgNDMsIDI1NCwgMjE1LCAxNzEsXG4gICAgMTE4LCAyMDIsIDEzMCwgMjAxLCAxMjUsIDI1MCwgODksIDcxLCAyNDAsIDE3MywgMjEyLCAxNjIsIDE3NSwgMTU2LCAxNjQsXG4gICAgMTE0LCAxOTIsIDE4MywgMjUzLCAxNDcsIDM4LCA1NCwgNjMsIDI0NywgMjA0LCA1MiwgMTY1LCAyMjksIDI0MSwgMTEzLFxuICAgIDIxNiwgNDksIDIxLCA0LCAxOTksIDM1LCAxOTUsIDI0LCAxNTAsIDUsIDE1NCwgNywgMTgsIDEyOCwgMjI2LFxuICAgIDIzNSwgMzksIDE3OCwgMTE3LCA5LCAxMzEsIDQ0LCAyNiwgMjcsIDExMCwgOTAsIDE2MCwgODIsIDU5LCAyMTQsXG4gICAgMTc5LCA0MSwgMjI3LCA0NywgMTMyLCA4MywgMjA5LCAwLCAyMzcsIDMyLCAyNTIsIDE3NywgOTEsIDEwNiwgMjAzLFxuICAgIDE5MCwgNTcsIDc0LCA3NiwgODgsIDIwNywgMjA4LCAyMzksIDE3MCwgMjUxLCA2NywgNzcsIDUxLCAxMzMsIDY5LFxuICAgIDI0OSwgMiwgMTI3LCA4MCwgNjAsIDE1OSwgMTY4LCA4MSwgMTYzLCA2NCwgMTQzLCAxNDYsIDE1NywgNTYsIDI0NSxcbiAgICAxODgsIDE4MiwgMjE4LCAzMywgMTYsIDI1NSwgMjQzLCAyMTAsIDIwNSwgMTIsIDE5LCAyMzYsIDk1LCAxNTEsIDY4LFxuICAgIDIzLCAxOTYsIDE2NywgMTI2LCA2MSwgMTAwLCA5MywgMjUsIDExNSwgOTYsIDEyOSwgNzksIDIyMCwgMzQsIDQyLFxuICAgIDE0NCwgMTM2LCA3MCwgMjM4LCAxODQsIDIwLCAyMjIsIDk0LCAxMSwgMjE5LCAyMjQsIDUwLCA1OCwgMTAsIDczLFxuICAgIDYsIDM2LCA5MiwgMTk0LCAyMTEsIDE3MiwgOTgsIDE0NSwgMTQ5LCAyMjgsIDEyMSwgMjMxLCAyMDAsIDU1LCAxMDksXG4gICAgMTQxLCAyMTMsIDc4LCAxNjksIDEwOCwgODYsIDI0NCwgMjM0LCAxMDEsIDEyMiwgMTc0LCA4LCAxODYsIDEyMCwgMzcsXG4gICAgNDYsIDI4LCAxNjYsIDE4MCwgMTk4LCAyMzIsIDIyMSwgMTE2LCAzMSwgNzUsIDE4OSwgMTM5LCAxMzgsIDExMiwgNjIsXG4gICAgMTgxLCAxMDIsIDcyLCAzLCAyNDYsIDE0LCA5NywgNTMsIDg3LCAxODUsIDEzNCwgMTkzLCAyOSwgMTU4LCAyMjUsXG4gICAgMjQ4LCAxNTIsIDE3LCAxMDUsIDIxNywgMTQyLCAxNDgsIDE1NSwgMzAsIDEzNSwgMjMzLCAyMDYsIDg1LCA0MCwgMjIzLFxuICAgIDE0MCwgMTYxLCAxMzcsIDEzLCAxOTEsIDIzMCwgNjYsIDEwNCwgNjUsIDE1MywgNDUsIDE1LCAxNzYsIDg0LCAxODcsXG4gICAgMjJcbl07XG5cbnZhciBUMSA9IFtcbiAgICAweGE1NjM2M2M2LCAweDg0N2M3Y2Y4LCAweDk5Nzc3N2VlLCAweDhkN2I3YmY2LFxuICAgIDB4MGRmMmYyZmYsIDB4YmQ2YjZiZDYsIDB4YjE2ZjZmZGUsIDB4NTRjNWM1OTEsXG4gICAgMHg1MDMwMzA2MCwgMHgwMzAxMDEwMiwgMHhhOTY3NjdjZSwgMHg3ZDJiMmI1NixcbiAgICAweDE5ZmVmZWU3LCAweDYyZDdkN2I1LCAweGU2YWJhYjRkLCAweDlhNzY3NmVjLFxuICAgIDB4NDVjYWNhOGYsIDB4OWQ4MjgyMWYsIDB4NDBjOWM5ODksIDB4ODc3ZDdkZmEsXG4gICAgMHgxNWZhZmFlZiwgMHhlYjU5NTliMiwgMHhjOTQ3NDc4ZSwgMHgwYmYwZjBmYixcbiAgICAweGVjYWRhZDQxLCAweDY3ZDRkNGIzLCAweGZkYTJhMjVmLCAweGVhYWZhZjQ1LFxuICAgIDB4YmY5YzljMjMsIDB4ZjdhNGE0NTMsIDB4OTY3MjcyZTQsIDB4NWJjMGMwOWIsXG4gICAgMHhjMmI3Yjc3NSwgMHgxY2ZkZmRlMSwgMHhhZTkzOTMzZCwgMHg2YTI2MjY0YyxcbiAgICAweDVhMzYzNjZjLCAweDQxM2YzZjdlLCAweDAyZjdmN2Y1LCAweDRmY2NjYzgzLFxuICAgIDB4NWMzNDM0NjgsIDB4ZjRhNWE1NTEsIDB4MzRlNWU1ZDEsIDB4MDhmMWYxZjksXG4gICAgMHg5MzcxNzFlMiwgMHg3M2Q4ZDhhYiwgMHg1MzMxMzE2MiwgMHgzZjE1MTUyYSxcbiAgICAweDBjMDQwNDA4LCAweDUyYzdjNzk1LCAweDY1MjMyMzQ2LCAweDVlYzNjMzlkLFxuICAgIDB4MjgxODE4MzAsIDB4YTE5Njk2MzcsIDB4MGYwNTA1MGEsIDB4YjU5YTlhMmYsXG4gICAgMHgwOTA3MDcwZSwgMHgzNjEyMTIyNCwgMHg5YjgwODAxYiwgMHgzZGUyZTJkZixcbiAgICAweDI2ZWJlYmNkLCAweDY5MjcyNzRlLCAweGNkYjJiMjdmLCAweDlmNzU3NWVhLFxuICAgIDB4MWIwOTA5MTIsIDB4OWU4MzgzMWQsIDB4NzQyYzJjNTgsIDB4MmUxYTFhMzQsXG4gICAgMHgyZDFiMWIzNiwgMHhiMjZlNmVkYywgMHhlZTVhNWFiNCwgMHhmYmEwYTA1YixcbiAgICAweGY2NTI1MmE0LCAweDRkM2IzYjc2LCAweDYxZDZkNmI3LCAweGNlYjNiMzdkLFxuICAgIDB4N2IyOTI5NTIsIDB4M2VlM2UzZGQsIDB4NzEyZjJmNWUsIDB4OTc4NDg0MTMsXG4gICAgMHhmNTUzNTNhNiwgMHg2OGQxZDFiOSwgMHgwMDAwMDAwMCwgMHgyY2VkZWRjMSxcbiAgICAweDYwMjAyMDQwLCAweDFmZmNmY2UzLCAweGM4YjFiMTc5LCAweGVkNWI1YmI2LFxuICAgIDB4YmU2YTZhZDQsIDB4NDZjYmNiOGQsIDB4ZDliZWJlNjcsIDB4NGIzOTM5NzIsXG4gICAgMHhkZTRhNGE5NCwgMHhkNDRjNGM5OCwgMHhlODU4NThiMCwgMHg0YWNmY2Y4NSxcbiAgICAweDZiZDBkMGJiLCAweDJhZWZlZmM1LCAweGU1YWFhYTRmLCAweDE2ZmJmYmVkLFxuICAgIDB4YzU0MzQzODYsIDB4ZDc0ZDRkOWEsIDB4NTUzMzMzNjYsIDB4OTQ4NTg1MTEsXG4gICAgMHhjZjQ1NDU4YSwgMHgxMGY5ZjllOSwgMHgwNjAyMDIwNCwgMHg4MTdmN2ZmZSxcbiAgICAweGYwNTA1MGEwLCAweDQ0M2MzYzc4LCAweGJhOWY5ZjI1LCAweGUzYThhODRiLFxuICAgIDB4ZjM1MTUxYTIsIDB4ZmVhM2EzNWQsIDB4YzA0MDQwODAsIDB4OGE4ZjhmMDUsXG4gICAgMHhhZDkyOTIzZiwgMHhiYzlkOWQyMSwgMHg0ODM4Mzg3MCwgMHgwNGY1ZjVmMSxcbiAgICAweGRmYmNiYzYzLCAweGMxYjZiNjc3LCAweDc1ZGFkYWFmLCAweDYzMjEyMTQyLFxuICAgIDB4MzAxMDEwMjAsIDB4MWFmZmZmZTUsIDB4MGVmM2YzZmQsIDB4NmRkMmQyYmYsXG4gICAgMHg0Y2NkY2Q4MSwgMHgxNDBjMGMxOCwgMHgzNTEzMTMyNiwgMHgyZmVjZWNjMyxcbiAgICAweGUxNWY1ZmJlLCAweGEyOTc5NzM1LCAweGNjNDQ0NDg4LCAweDM5MTcxNzJlLFxuICAgIDB4NTdjNGM0OTMsIDB4ZjJhN2E3NTUsIDB4ODI3ZTdlZmMsIDB4NDczZDNkN2EsXG4gICAgMHhhYzY0NjRjOCwgMHhlNzVkNWRiYSwgMHgyYjE5MTkzMiwgMHg5NTczNzNlNixcbiAgICAweGEwNjA2MGMwLCAweDk4ODE4MTE5LCAweGQxNGY0ZjllLCAweDdmZGNkY2EzLFxuICAgIDB4NjYyMjIyNDQsIDB4N2UyYTJhNTQsIDB4YWI5MDkwM2IsIDB4ODM4ODg4MGIsXG4gICAgMHhjYTQ2NDY4YywgMHgyOWVlZWVjNywgMHhkM2I4Yjg2YiwgMHgzYzE0MTQyOCxcbiAgICAweDc5ZGVkZWE3LCAweGUyNWU1ZWJjLCAweDFkMGIwYjE2LCAweDc2ZGJkYmFkLFxuICAgIDB4M2JlMGUwZGIsIDB4NTYzMjMyNjQsIDB4NGUzYTNhNzQsIDB4MWUwYTBhMTQsXG4gICAgMHhkYjQ5NDk5MiwgMHgwYTA2MDYwYywgMHg2YzI0MjQ0OCwgMHhlNDVjNWNiOCxcbiAgICAweDVkYzJjMjlmLCAweDZlZDNkM2JkLCAweGVmYWNhYzQzLCAweGE2NjI2MmM0LFxuICAgIDB4YTg5MTkxMzksIDB4YTQ5NTk1MzEsIDB4MzdlNGU0ZDMsIDB4OGI3OTc5ZjIsXG4gICAgMHgzMmU3ZTdkNSwgMHg0M2M4Yzg4YiwgMHg1OTM3Mzc2ZSwgMHhiNzZkNmRkYSxcbiAgICAweDhjOGQ4ZDAxLCAweDY0ZDVkNWIxLCAweGQyNGU0ZTljLCAweGUwYTlhOTQ5LFxuICAgIDB4YjQ2YzZjZDgsIDB4ZmE1NjU2YWMsIDB4MDdmNGY0ZjMsIDB4MjVlYWVhY2YsXG4gICAgMHhhZjY1NjVjYSwgMHg4ZTdhN2FmNCwgMHhlOWFlYWU0NywgMHgxODA4MDgxMCxcbiAgICAweGQ1YmFiYTZmLCAweDg4Nzg3OGYwLCAweDZmMjUyNTRhLCAweDcyMmUyZTVjLFxuICAgIDB4MjQxYzFjMzgsIDB4ZjFhNmE2NTcsIDB4YzdiNGI0NzMsIDB4NTFjNmM2OTcsXG4gICAgMHgyM2U4ZThjYiwgMHg3Y2RkZGRhMSwgMHg5Yzc0NzRlOCwgMHgyMTFmMWYzZSxcbiAgICAweGRkNGI0Yjk2LCAweGRjYmRiZDYxLCAweDg2OGI4YjBkLCAweDg1OGE4YTBmLFxuICAgIDB4OTA3MDcwZTAsIDB4NDIzZTNlN2MsIDB4YzRiNWI1NzEsIDB4YWE2NjY2Y2MsXG4gICAgMHhkODQ4NDg5MCwgMHgwNTAzMDMwNiwgMHgwMWY2ZjZmNywgMHgxMjBlMGUxYyxcbiAgICAweGEzNjE2MWMyLCAweDVmMzUzNTZhLCAweGY5NTc1N2FlLCAweGQwYjliOTY5LFxuICAgIDB4OTE4Njg2MTcsIDB4NThjMWMxOTksIDB4MjcxZDFkM2EsIDB4Yjk5ZTllMjcsXG4gICAgMHgzOGUxZTFkOSwgMHgxM2Y4ZjhlYiwgMHhiMzk4OTgyYiwgMHgzMzExMTEyMixcbiAgICAweGJiNjk2OWQyLCAweDcwZDlkOWE5LCAweDg5OGU4ZTA3LCAweGE3OTQ5NDMzLFxuICAgIDB4YjY5YjliMmQsIDB4MjIxZTFlM2MsIDB4OTI4Nzg3MTUsIDB4MjBlOWU5YzksXG4gICAgMHg0OWNlY2U4NywgMHhmZjU1NTVhYSwgMHg3ODI4Mjg1MCwgMHg3YWRmZGZhNSxcbiAgICAweDhmOGM4YzAzLCAweGY4YTFhMTU5LCAweDgwODk4OTA5LCAweDE3MGQwZDFhLFxuICAgIDB4ZGFiZmJmNjUsIDB4MzFlNmU2ZDcsIDB4YzY0MjQyODQsIDB4Yjg2ODY4ZDAsXG4gICAgMHhjMzQxNDE4MiwgMHhiMDk5OTkyOSwgMHg3NzJkMmQ1YSwgMHgxMTBmMGYxZSxcbiAgICAweGNiYjBiMDdiLCAweGZjNTQ1NGE4LCAweGQ2YmJiYjZkLCAweDNhMTYxNjJjXG5dO1xuXG52YXIgVDIgPSBbXG4gICAgMHg2MzYzYzZhNSwgMHg3YzdjZjg4NCwgMHg3Nzc3ZWU5OSwgMHg3YjdiZjY4ZCxcbiAgICAweGYyZjJmZjBkLCAweDZiNmJkNmJkLCAweDZmNmZkZWIxLCAweGM1YzU5MTU0LFxuICAgIDB4MzAzMDYwNTAsIDB4MDEwMTAyMDMsIDB4Njc2N2NlYTksIDB4MmIyYjU2N2QsXG4gICAgMHhmZWZlZTcxOSwgMHhkN2Q3YjU2MiwgMHhhYmFiNGRlNiwgMHg3Njc2ZWM5YSxcbiAgICAweGNhY2E4ZjQ1LCAweDgyODIxZjlkLCAweGM5Yzk4OTQwLCAweDdkN2RmYTg3LFxuICAgIDB4ZmFmYWVmMTUsIDB4NTk1OWIyZWIsIDB4NDc0NzhlYzksIDB4ZjBmMGZiMGIsXG4gICAgMHhhZGFkNDFlYywgMHhkNGQ0YjM2NywgMHhhMmEyNWZmZCwgMHhhZmFmNDVlYSxcbiAgICAweDljOWMyM2JmLCAweGE0YTQ1M2Y3LCAweDcyNzJlNDk2LCAweGMwYzA5YjViLFxuICAgIDB4YjdiNzc1YzIsIDB4ZmRmZGUxMWMsIDB4OTM5MzNkYWUsIDB4MjYyNjRjNmEsXG4gICAgMHgzNjM2NmM1YSwgMHgzZjNmN2U0MSwgMHhmN2Y3ZjUwMiwgMHhjY2NjODM0ZixcbiAgICAweDM0MzQ2ODVjLCAweGE1YTU1MWY0LCAweGU1ZTVkMTM0LCAweGYxZjFmOTA4LFxuICAgIDB4NzE3MWUyOTMsIDB4ZDhkOGFiNzMsIDB4MzEzMTYyNTMsIDB4MTUxNTJhM2YsXG4gICAgMHgwNDA0MDgwYywgMHhjN2M3OTU1MiwgMHgyMzIzNDY2NSwgMHhjM2MzOWQ1ZSxcbiAgICAweDE4MTgzMDI4LCAweDk2OTYzN2ExLCAweDA1MDUwYTBmLCAweDlhOWEyZmI1LFxuICAgIDB4MDcwNzBlMDksIDB4MTIxMjI0MzYsIDB4ODA4MDFiOWIsIDB4ZTJlMmRmM2QsXG4gICAgMHhlYmViY2QyNiwgMHgyNzI3NGU2OSwgMHhiMmIyN2ZjZCwgMHg3NTc1ZWE5ZixcbiAgICAweDA5MDkxMjFiLCAweDgzODMxZDllLCAweDJjMmM1ODc0LCAweDFhMWEzNDJlLFxuICAgIDB4MWIxYjM2MmQsIDB4NmU2ZWRjYjIsIDB4NWE1YWI0ZWUsIDB4YTBhMDViZmIsXG4gICAgMHg1MjUyYTRmNiwgMHgzYjNiNzY0ZCwgMHhkNmQ2Yjc2MSwgMHhiM2IzN2RjZSxcbiAgICAweDI5Mjk1MjdiLCAweGUzZTNkZDNlLCAweDJmMmY1ZTcxLCAweDg0ODQxMzk3LFxuICAgIDB4NTM1M2E2ZjUsIDB4ZDFkMWI5NjgsIDB4MDAwMDAwMDAsIDB4ZWRlZGMxMmMsXG4gICAgMHgyMDIwNDA2MCwgMHhmY2ZjZTMxZiwgMHhiMWIxNzljOCwgMHg1YjViYjZlZCxcbiAgICAweDZhNmFkNGJlLCAweGNiY2I4ZDQ2LCAweGJlYmU2N2Q5LCAweDM5Mzk3MjRiLFxuICAgIDB4NGE0YTk0ZGUsIDB4NGM0Yzk4ZDQsIDB4NTg1OGIwZTgsIDB4Y2ZjZjg1NGEsXG4gICAgMHhkMGQwYmI2YiwgMHhlZmVmYzUyYSwgMHhhYWFhNGZlNSwgMHhmYmZiZWQxNixcbiAgICAweDQzNDM4NmM1LCAweDRkNGQ5YWQ3LCAweDMzMzM2NjU1LCAweDg1ODUxMTk0LFxuICAgIDB4NDU0NThhY2YsIDB4ZjlmOWU5MTAsIDB4MDIwMjA0MDYsIDB4N2Y3ZmZlODEsXG4gICAgMHg1MDUwYTBmMCwgMHgzYzNjNzg0NCwgMHg5ZjlmMjViYSwgMHhhOGE4NGJlMyxcbiAgICAweDUxNTFhMmYzLCAweGEzYTM1ZGZlLCAweDQwNDA4MGMwLCAweDhmOGYwNThhLFxuICAgIDB4OTI5MjNmYWQsIDB4OWQ5ZDIxYmMsIDB4MzgzODcwNDgsIDB4ZjVmNWYxMDQsXG4gICAgMHhiY2JjNjNkZiwgMHhiNmI2NzdjMSwgMHhkYWRhYWY3NSwgMHgyMTIxNDI2MyxcbiAgICAweDEwMTAyMDMwLCAweGZmZmZlNTFhLCAweGYzZjNmZDBlLCAweGQyZDJiZjZkLFxuICAgIDB4Y2RjZDgxNGMsIDB4MGMwYzE4MTQsIDB4MTMxMzI2MzUsIDB4ZWNlY2MzMmYsXG4gICAgMHg1ZjVmYmVlMSwgMHg5Nzk3MzVhMiwgMHg0NDQ0ODhjYywgMHgxNzE3MmUzOSxcbiAgICAweGM0YzQ5MzU3LCAweGE3YTc1NWYyLCAweDdlN2VmYzgyLCAweDNkM2Q3YTQ3LFxuICAgIDB4NjQ2NGM4YWMsIDB4NWQ1ZGJhZTcsIDB4MTkxOTMyMmIsIDB4NzM3M2U2OTUsXG4gICAgMHg2MDYwYzBhMCwgMHg4MTgxMTk5OCwgMHg0ZjRmOWVkMSwgMHhkY2RjYTM3ZixcbiAgICAweDIyMjI0NDY2LCAweDJhMmE1NDdlLCAweDkwOTAzYmFiLCAweDg4ODgwYjgzLFxuICAgIDB4NDY0NjhjY2EsIDB4ZWVlZWM3MjksIDB4YjhiODZiZDMsIDB4MTQxNDI4M2MsXG4gICAgMHhkZWRlYTc3OSwgMHg1ZTVlYmNlMiwgMHgwYjBiMTYxZCwgMHhkYmRiYWQ3NixcbiAgICAweGUwZTBkYjNiLCAweDMyMzI2NDU2LCAweDNhM2E3NDRlLCAweDBhMGExNDFlLFxuICAgIDB4NDk0OTkyZGIsIDB4MDYwNjBjMGEsIDB4MjQyNDQ4NmMsIDB4NWM1Y2I4ZTQsXG4gICAgMHhjMmMyOWY1ZCwgMHhkM2QzYmQ2ZSwgMHhhY2FjNDNlZiwgMHg2MjYyYzRhNixcbiAgICAweDkxOTEzOWE4LCAweDk1OTUzMWE0LCAweGU0ZTRkMzM3LCAweDc5NzlmMjhiLFxuICAgIDB4ZTdlN2Q1MzIsIDB4YzhjODhiNDMsIDB4MzczNzZlNTksIDB4NmQ2ZGRhYjcsXG4gICAgMHg4ZDhkMDE4YywgMHhkNWQ1YjE2NCwgMHg0ZTRlOWNkMiwgMHhhOWE5NDllMCxcbiAgICAweDZjNmNkOGI0LCAweDU2NTZhY2ZhLCAweGY0ZjRmMzA3LCAweGVhZWFjZjI1LFxuICAgIDB4NjU2NWNhYWYsIDB4N2E3YWY0OGUsIDB4YWVhZTQ3ZTksIDB4MDgwODEwMTgsXG4gICAgMHhiYWJhNmZkNSwgMHg3ODc4ZjA4OCwgMHgyNTI1NGE2ZiwgMHgyZTJlNWM3MixcbiAgICAweDFjMWMzODI0LCAweGE2YTY1N2YxLCAweGI0YjQ3M2M3LCAweGM2YzY5NzUxLFxuICAgIDB4ZThlOGNiMjMsIDB4ZGRkZGExN2MsIDB4NzQ3NGU4OWMsIDB4MWYxZjNlMjEsXG4gICAgMHg0YjRiOTZkZCwgMHhiZGJkNjFkYywgMHg4YjhiMGQ4NiwgMHg4YThhMGY4NSxcbiAgICAweDcwNzBlMDkwLCAweDNlM2U3YzQyLCAweGI1YjU3MWM0LCAweDY2NjZjY2FhLFxuICAgIDB4NDg0ODkwZDgsIDB4MDMwMzA2MDUsIDB4ZjZmNmY3MDEsIDB4MGUwZTFjMTIsXG4gICAgMHg2MTYxYzJhMywgMHgzNTM1NmE1ZiwgMHg1NzU3YWVmOSwgMHhiOWI5NjlkMCxcbiAgICAweDg2ODYxNzkxLCAweGMxYzE5OTU4LCAweDFkMWQzYTI3LCAweDllOWUyN2I5LFxuICAgIDB4ZTFlMWQ5MzgsIDB4ZjhmOGViMTMsIDB4OTg5ODJiYjMsIDB4MTExMTIyMzMsXG4gICAgMHg2OTY5ZDJiYiwgMHhkOWQ5YTk3MCwgMHg4ZThlMDc4OSwgMHg5NDk0MzNhNyxcbiAgICAweDliOWIyZGI2LCAweDFlMWUzYzIyLCAweDg3ODcxNTkyLCAweGU5ZTljOTIwLFxuICAgIDB4Y2VjZTg3NDksIDB4NTU1NWFhZmYsIDB4MjgyODUwNzgsIDB4ZGZkZmE1N2EsXG4gICAgMHg4YzhjMDM4ZiwgMHhhMWExNTlmOCwgMHg4OTg5MDk4MCwgMHgwZDBkMWExNyxcbiAgICAweGJmYmY2NWRhLCAweGU2ZTZkNzMxLCAweDQyNDI4NGM2LCAweDY4NjhkMGI4LFxuICAgIDB4NDE0MTgyYzMsIDB4OTk5OTI5YjAsIDB4MmQyZDVhNzcsIDB4MGYwZjFlMTEsXG4gICAgMHhiMGIwN2JjYiwgMHg1NDU0YThmYywgMHhiYmJiNmRkNiwgMHgxNjE2MmMzYVxuXTtcblxudmFyIFQzID0gW1xuICAgIDB4NjNjNmE1NjMsIDB4N2NmODg0N2MsIDB4NzdlZTk5NzcsIDB4N2JmNjhkN2IsXG4gICAgMHhmMmZmMGRmMiwgMHg2YmQ2YmQ2YiwgMHg2ZmRlYjE2ZiwgMHhjNTkxNTRjNSxcbiAgICAweDMwNjA1MDMwLCAweDAxMDIwMzAxLCAweDY3Y2VhOTY3LCAweDJiNTY3ZDJiLFxuICAgIDB4ZmVlNzE5ZmUsIDB4ZDdiNTYyZDcsIDB4YWI0ZGU2YWIsIDB4NzZlYzlhNzYsXG4gICAgMHhjYThmNDVjYSwgMHg4MjFmOWQ4MiwgMHhjOTg5NDBjOSwgMHg3ZGZhODc3ZCxcbiAgICAweGZhZWYxNWZhLCAweDU5YjJlYjU5LCAweDQ3OGVjOTQ3LCAweGYwZmIwYmYwLFxuICAgIDB4YWQ0MWVjYWQsIDB4ZDRiMzY3ZDQsIDB4YTI1ZmZkYTIsIDB4YWY0NWVhYWYsXG4gICAgMHg5YzIzYmY5YywgMHhhNDUzZjdhNCwgMHg3MmU0OTY3MiwgMHhjMDliNWJjMCxcbiAgICAweGI3NzVjMmI3LCAweGZkZTExY2ZkLCAweDkzM2RhZTkzLCAweDI2NGM2YTI2LFxuICAgIDB4MzY2YzVhMzYsIDB4M2Y3ZTQxM2YsIDB4ZjdmNTAyZjcsIDB4Y2M4MzRmY2MsXG4gICAgMHgzNDY4NWMzNCwgMHhhNTUxZjRhNSwgMHhlNWQxMzRlNSwgMHhmMWY5MDhmMSxcbiAgICAweDcxZTI5MzcxLCAweGQ4YWI3M2Q4LCAweDMxNjI1MzMxLCAweDE1MmEzZjE1LFxuICAgIDB4MDQwODBjMDQsIDB4Yzc5NTUyYzcsIDB4MjM0NjY1MjMsIDB4YzM5ZDVlYzMsXG4gICAgMHgxODMwMjgxOCwgMHg5NjM3YTE5NiwgMHgwNTBhMGYwNSwgMHg5YTJmYjU5YSxcbiAgICAweDA3MGUwOTA3LCAweDEyMjQzNjEyLCAweDgwMWI5YjgwLCAweGUyZGYzZGUyLFxuICAgIDB4ZWJjZDI2ZWIsIDB4Mjc0ZTY5MjcsIDB4YjI3ZmNkYjIsIDB4NzVlYTlmNzUsXG4gICAgMHgwOTEyMWIwOSwgMHg4MzFkOWU4MywgMHgyYzU4NzQyYywgMHgxYTM0MmUxYSxcbiAgICAweDFiMzYyZDFiLCAweDZlZGNiMjZlLCAweDVhYjRlZTVhLCAweGEwNWJmYmEwLFxuICAgIDB4NTJhNGY2NTIsIDB4M2I3NjRkM2IsIDB4ZDZiNzYxZDYsIDB4YjM3ZGNlYjMsXG4gICAgMHgyOTUyN2IyOSwgMHhlM2RkM2VlMywgMHgyZjVlNzEyZiwgMHg4NDEzOTc4NCxcbiAgICAweDUzYTZmNTUzLCAweGQxYjk2OGQxLCAweDAwMDAwMDAwLCAweGVkYzEyY2VkLFxuICAgIDB4MjA0MDYwMjAsIDB4ZmNlMzFmZmMsIDB4YjE3OWM4YjEsIDB4NWJiNmVkNWIsXG4gICAgMHg2YWQ0YmU2YSwgMHhjYjhkNDZjYiwgMHhiZTY3ZDliZSwgMHgzOTcyNGIzOSxcbiAgICAweDRhOTRkZTRhLCAweDRjOThkNDRjLCAweDU4YjBlODU4LCAweGNmODU0YWNmLFxuICAgIDB4ZDBiYjZiZDAsIDB4ZWZjNTJhZWYsIDB4YWE0ZmU1YWEsIDB4ZmJlZDE2ZmIsXG4gICAgMHg0Mzg2YzU0MywgMHg0ZDlhZDc0ZCwgMHgzMzY2NTUzMywgMHg4NTExOTQ4NSxcbiAgICAweDQ1OGFjZjQ1LCAweGY5ZTkxMGY5LCAweDAyMDQwNjAyLCAweDdmZmU4MTdmLFxuICAgIDB4NTBhMGYwNTAsIDB4M2M3ODQ0M2MsIDB4OWYyNWJhOWYsIDB4YTg0YmUzYTgsXG4gICAgMHg1MWEyZjM1MSwgMHhhMzVkZmVhMywgMHg0MDgwYzA0MCwgMHg4ZjA1OGE4ZixcbiAgICAweDkyM2ZhZDkyLCAweDlkMjFiYzlkLCAweDM4NzA0ODM4LCAweGY1ZjEwNGY1LFxuICAgIDB4YmM2M2RmYmMsIDB4YjY3N2MxYjYsIDB4ZGFhZjc1ZGEsIDB4MjE0MjYzMjEsXG4gICAgMHgxMDIwMzAxMCwgMHhmZmU1MWFmZiwgMHhmM2ZkMGVmMywgMHhkMmJmNmRkMixcbiAgICAweGNkODE0Y2NkLCAweDBjMTgxNDBjLCAweDEzMjYzNTEzLCAweGVjYzMyZmVjLFxuICAgIDB4NWZiZWUxNWYsIDB4OTczNWEyOTcsIDB4NDQ4OGNjNDQsIDB4MTcyZTM5MTcsXG4gICAgMHhjNDkzNTdjNCwgMHhhNzU1ZjJhNywgMHg3ZWZjODI3ZSwgMHgzZDdhNDczZCxcbiAgICAweDY0YzhhYzY0LCAweDVkYmFlNzVkLCAweDE5MzIyYjE5LCAweDczZTY5NTczLFxuICAgIDB4NjBjMGEwNjAsIDB4ODExOTk4ODEsIDB4NGY5ZWQxNGYsIDB4ZGNhMzdmZGMsXG4gICAgMHgyMjQ0NjYyMiwgMHgyYTU0N2UyYSwgMHg5MDNiYWI5MCwgMHg4ODBiODM4OCxcbiAgICAweDQ2OGNjYTQ2LCAweGVlYzcyOWVlLCAweGI4NmJkM2I4LCAweDE0MjgzYzE0LFxuICAgIDB4ZGVhNzc5ZGUsIDB4NWViY2UyNWUsIDB4MGIxNjFkMGIsIDB4ZGJhZDc2ZGIsXG4gICAgMHhlMGRiM2JlMCwgMHgzMjY0NTYzMiwgMHgzYTc0NGUzYSwgMHgwYTE0MWUwYSxcbiAgICAweDQ5OTJkYjQ5LCAweDA2MGMwYTA2LCAweDI0NDg2YzI0LCAweDVjYjhlNDVjLFxuICAgIDB4YzI5ZjVkYzIsIDB4ZDNiZDZlZDMsIDB4YWM0M2VmYWMsIDB4NjJjNGE2NjIsXG4gICAgMHg5MTM5YTg5MSwgMHg5NTMxYTQ5NSwgMHhlNGQzMzdlNCwgMHg3OWYyOGI3OSxcbiAgICAweGU3ZDUzMmU3LCAweGM4OGI0M2M4LCAweDM3NmU1OTM3LCAweDZkZGFiNzZkLFxuICAgIDB4OGQwMThjOGQsIDB4ZDViMTY0ZDUsIDB4NGU5Y2QyNGUsIDB4YTk0OWUwYTksXG4gICAgMHg2Y2Q4YjQ2YywgMHg1NmFjZmE1NiwgMHhmNGYzMDdmNCwgMHhlYWNmMjVlYSxcbiAgICAweDY1Y2FhZjY1LCAweDdhZjQ4ZTdhLCAweGFlNDdlOWFlLCAweDA4MTAxODA4LFxuICAgIDB4YmE2ZmQ1YmEsIDB4NzhmMDg4NzgsIDB4MjU0YTZmMjUsIDB4MmU1YzcyMmUsXG4gICAgMHgxYzM4MjQxYywgMHhhNjU3ZjFhNiwgMHhiNDczYzdiNCwgMHhjNjk3NTFjNixcbiAgICAweGU4Y2IyM2U4LCAweGRkYTE3Y2RkLCAweDc0ZTg5Yzc0LCAweDFmM2UyMTFmLFxuICAgIDB4NGI5NmRkNGIsIDB4YmQ2MWRjYmQsIDB4OGIwZDg2OGIsIDB4OGEwZjg1OGEsXG4gICAgMHg3MGUwOTA3MCwgMHgzZTdjNDIzZSwgMHhiNTcxYzRiNSwgMHg2NmNjYWE2NixcbiAgICAweDQ4OTBkODQ4LCAweDAzMDYwNTAzLCAweGY2ZjcwMWY2LCAweDBlMWMxMjBlLFxuICAgIDB4NjFjMmEzNjEsIDB4MzU2YTVmMzUsIDB4NTdhZWY5NTcsIDB4Yjk2OWQwYjksXG4gICAgMHg4NjE3OTE4NiwgMHhjMTk5NThjMSwgMHgxZDNhMjcxZCwgMHg5ZTI3Yjk5ZSxcbiAgICAweGUxZDkzOGUxLCAweGY4ZWIxM2Y4LCAweDk4MmJiMzk4LCAweDExMjIzMzExLFxuICAgIDB4NjlkMmJiNjksIDB4ZDlhOTcwZDksIDB4OGUwNzg5OGUsIDB4OTQzM2E3OTQsXG4gICAgMHg5YjJkYjY5YiwgMHgxZTNjMjIxZSwgMHg4NzE1OTI4NywgMHhlOWM5MjBlOSxcbiAgICAweGNlODc0OWNlLCAweDU1YWFmZjU1LCAweDI4NTA3ODI4LCAweGRmYTU3YWRmLFxuICAgIDB4OGMwMzhmOGMsIDB4YTE1OWY4YTEsIDB4ODkwOTgwODksIDB4MGQxYTE3MGQsXG4gICAgMHhiZjY1ZGFiZiwgMHhlNmQ3MzFlNiwgMHg0Mjg0YzY0MiwgMHg2OGQwYjg2OCxcbiAgICAweDQxODJjMzQxLCAweDk5MjliMDk5LCAweDJkNWE3NzJkLCAweDBmMWUxMTBmLFxuICAgIDB4YjA3YmNiYjAsIDB4NTRhOGZjNTQsIDB4YmI2ZGQ2YmIsIDB4MTYyYzNhMTZcbl07XG5cbnZhciBUNCA9IFtcbiAgICAweGM2YTU2MzYzLCAweGY4ODQ3YzdjLCAweGVlOTk3Nzc3LCAweGY2OGQ3YjdiLFxuICAgIDB4ZmYwZGYyZjIsIDB4ZDZiZDZiNmIsIDB4ZGViMTZmNmYsIDB4OTE1NGM1YzUsXG4gICAgMHg2MDUwMzAzMCwgMHgwMjAzMDEwMSwgMHhjZWE5Njc2NywgMHg1NjdkMmIyYixcbiAgICAweGU3MTlmZWZlLCAweGI1NjJkN2Q3LCAweDRkZTZhYmFiLCAweGVjOWE3Njc2LFxuICAgIDB4OGY0NWNhY2EsIDB4MWY5ZDgyODIsIDB4ODk0MGM5YzksIDB4ZmE4NzdkN2QsXG4gICAgMHhlZjE1ZmFmYSwgMHhiMmViNTk1OSwgMHg4ZWM5NDc0NywgMHhmYjBiZjBmMCxcbiAgICAweDQxZWNhZGFkLCAweGIzNjdkNGQ0LCAweDVmZmRhMmEyLCAweDQ1ZWFhZmFmLFxuICAgIDB4MjNiZjljOWMsIDB4NTNmN2E0YTQsIDB4ZTQ5NjcyNzIsIDB4OWI1YmMwYzAsXG4gICAgMHg3NWMyYjdiNywgMHhlMTFjZmRmZCwgMHgzZGFlOTM5MywgMHg0YzZhMjYyNixcbiAgICAweDZjNWEzNjM2LCAweDdlNDEzZjNmLCAweGY1MDJmN2Y3LCAweDgzNGZjY2NjLFxuICAgIDB4Njg1YzM0MzQsIDB4NTFmNGE1YTUsIDB4ZDEzNGU1ZTUsIDB4ZjkwOGYxZjEsXG4gICAgMHhlMjkzNzE3MSwgMHhhYjczZDhkOCwgMHg2MjUzMzEzMSwgMHgyYTNmMTUxNSxcbiAgICAweDA4MGMwNDA0LCAweDk1NTJjN2M3LCAweDQ2NjUyMzIzLCAweDlkNWVjM2MzLFxuICAgIDB4MzAyODE4MTgsIDB4MzdhMTk2OTYsIDB4MGEwZjA1MDUsIDB4MmZiNTlhOWEsXG4gICAgMHgwZTA5MDcwNywgMHgyNDM2MTIxMiwgMHgxYjliODA4MCwgMHhkZjNkZTJlMixcbiAgICAweGNkMjZlYmViLCAweDRlNjkyNzI3LCAweDdmY2RiMmIyLCAweGVhOWY3NTc1LFxuICAgIDB4MTIxYjA5MDksIDB4MWQ5ZTgzODMsIDB4NTg3NDJjMmMsIDB4MzQyZTFhMWEsXG4gICAgMHgzNjJkMWIxYiwgMHhkY2IyNmU2ZSwgMHhiNGVlNWE1YSwgMHg1YmZiYTBhMCxcbiAgICAweGE0ZjY1MjUyLCAweDc2NGQzYjNiLCAweGI3NjFkNmQ2LCAweDdkY2ViM2IzLFxuICAgIDB4NTI3YjI5MjksIDB4ZGQzZWUzZTMsIDB4NWU3MTJmMmYsIDB4MTM5Nzg0ODQsXG4gICAgMHhhNmY1NTM1MywgMHhiOTY4ZDFkMSwgMHgwMDAwMDAwMCwgMHhjMTJjZWRlZCxcbiAgICAweDQwNjAyMDIwLCAweGUzMWZmY2ZjLCAweDc5YzhiMWIxLCAweGI2ZWQ1YjViLFxuICAgIDB4ZDRiZTZhNmEsIDB4OGQ0NmNiY2IsIDB4NjdkOWJlYmUsIDB4NzI0YjM5MzksXG4gICAgMHg5NGRlNGE0YSwgMHg5OGQ0NGM0YywgMHhiMGU4NTg1OCwgMHg4NTRhY2ZjZixcbiAgICAweGJiNmJkMGQwLCAweGM1MmFlZmVmLCAweDRmZTVhYWFhLCAweGVkMTZmYmZiLFxuICAgIDB4ODZjNTQzNDMsIDB4OWFkNzRkNGQsIDB4NjY1NTMzMzMsIDB4MTE5NDg1ODUsXG4gICAgMHg4YWNmNDU0NSwgMHhlOTEwZjlmOSwgMHgwNDA2MDIwMiwgMHhmZTgxN2Y3ZixcbiAgICAweGEwZjA1MDUwLCAweDc4NDQzYzNjLCAweDI1YmE5ZjlmLCAweDRiZTNhOGE4LFxuICAgIDB4YTJmMzUxNTEsIDB4NWRmZWEzYTMsIDB4ODBjMDQwNDAsIDB4MDU4YThmOGYsXG4gICAgMHgzZmFkOTI5MiwgMHgyMWJjOWQ5ZCwgMHg3MDQ4MzgzOCwgMHhmMTA0ZjVmNSxcbiAgICAweDYzZGZiY2JjLCAweDc3YzFiNmI2LCAweGFmNzVkYWRhLCAweDQyNjMyMTIxLFxuICAgIDB4MjAzMDEwMTAsIDB4ZTUxYWZmZmYsIDB4ZmQwZWYzZjMsIDB4YmY2ZGQyZDIsXG4gICAgMHg4MTRjY2RjZCwgMHgxODE0MGMwYywgMHgyNjM1MTMxMywgMHhjMzJmZWNlYyxcbiAgICAweGJlZTE1ZjVmLCAweDM1YTI5Nzk3LCAweDg4Y2M0NDQ0LCAweDJlMzkxNzE3LFxuICAgIDB4OTM1N2M0YzQsIDB4NTVmMmE3YTcsIDB4ZmM4MjdlN2UsIDB4N2E0NzNkM2QsXG4gICAgMHhjOGFjNjQ2NCwgMHhiYWU3NWQ1ZCwgMHgzMjJiMTkxOSwgMHhlNjk1NzM3MyxcbiAgICAweGMwYTA2MDYwLCAweDE5OTg4MTgxLCAweDllZDE0ZjRmLCAweGEzN2ZkY2RjLFxuICAgIDB4NDQ2NjIyMjIsIDB4NTQ3ZTJhMmEsIDB4M2JhYjkwOTAsIDB4MGI4Mzg4ODgsXG4gICAgMHg4Y2NhNDY0NiwgMHhjNzI5ZWVlZSwgMHg2YmQzYjhiOCwgMHgyODNjMTQxNCxcbiAgICAweGE3NzlkZWRlLCAweGJjZTI1ZTVlLCAweDE2MWQwYjBiLCAweGFkNzZkYmRiLFxuICAgIDB4ZGIzYmUwZTAsIDB4NjQ1NjMyMzIsIDB4NzQ0ZTNhM2EsIDB4MTQxZTBhMGEsXG4gICAgMHg5MmRiNDk0OSwgMHgwYzBhMDYwNiwgMHg0ODZjMjQyNCwgMHhiOGU0NWM1YyxcbiAgICAweDlmNWRjMmMyLCAweGJkNmVkM2QzLCAweDQzZWZhY2FjLCAweGM0YTY2MjYyLFxuICAgIDB4MzlhODkxOTEsIDB4MzFhNDk1OTUsIDB4ZDMzN2U0ZTQsIDB4ZjI4Yjc5NzksXG4gICAgMHhkNTMyZTdlNywgMHg4YjQzYzhjOCwgMHg2ZTU5MzczNywgMHhkYWI3NmQ2ZCxcbiAgICAweDAxOGM4ZDhkLCAweGIxNjRkNWQ1LCAweDljZDI0ZTRlLCAweDQ5ZTBhOWE5LFxuICAgIDB4ZDhiNDZjNmMsIDB4YWNmYTU2NTYsIDB4ZjMwN2Y0ZjQsIDB4Y2YyNWVhZWEsXG4gICAgMHhjYWFmNjU2NSwgMHhmNDhlN2E3YSwgMHg0N2U5YWVhZSwgMHgxMDE4MDgwOCxcbiAgICAweDZmZDViYWJhLCAweGYwODg3ODc4LCAweDRhNmYyNTI1LCAweDVjNzIyZTJlLFxuICAgIDB4MzgyNDFjMWMsIDB4NTdmMWE2YTYsIDB4NzNjN2I0YjQsIDB4OTc1MWM2YzYsXG4gICAgMHhjYjIzZThlOCwgMHhhMTdjZGRkZCwgMHhlODljNzQ3NCwgMHgzZTIxMWYxZixcbiAgICAweDk2ZGQ0YjRiLCAweDYxZGNiZGJkLCAweDBkODY4YjhiLCAweDBmODU4YThhLFxuICAgIDB4ZTA5MDcwNzAsIDB4N2M0MjNlM2UsIDB4NzFjNGI1YjUsIDB4Y2NhYTY2NjYsXG4gICAgMHg5MGQ4NDg0OCwgMHgwNjA1MDMwMywgMHhmNzAxZjZmNiwgMHgxYzEyMGUwZSxcbiAgICAweGMyYTM2MTYxLCAweDZhNWYzNTM1LCAweGFlZjk1NzU3LCAweDY5ZDBiOWI5LFxuICAgIDB4MTc5MTg2ODYsIDB4OTk1OGMxYzEsIDB4M2EyNzFkMWQsIDB4MjdiOTllOWUsXG4gICAgMHhkOTM4ZTFlMSwgMHhlYjEzZjhmOCwgMHgyYmIzOTg5OCwgMHgyMjMzMTExMSxcbiAgICAweGQyYmI2OTY5LCAweGE5NzBkOWQ5LCAweDA3ODk4ZThlLCAweDMzYTc5NDk0LFxuICAgIDB4MmRiNjliOWIsIDB4M2MyMjFlMWUsIDB4MTU5Mjg3ODcsIDB4YzkyMGU5ZTksXG4gICAgMHg4NzQ5Y2VjZSwgMHhhYWZmNTU1NSwgMHg1MDc4MjgyOCwgMHhhNTdhZGZkZixcbiAgICAweDAzOGY4YzhjLCAweDU5ZjhhMWExLCAweDA5ODA4OTg5LCAweDFhMTcwZDBkLFxuICAgIDB4NjVkYWJmYmYsIDB4ZDczMWU2ZTYsIDB4ODRjNjQyNDIsIDB4ZDBiODY4NjgsXG4gICAgMHg4MmMzNDE0MSwgMHgyOWIwOTk5OSwgMHg1YTc3MmQyZCwgMHgxZTExMGYwZixcbiAgICAweDdiY2JiMGIwLCAweGE4ZmM1NDU0LCAweDZkZDZiYmJiLCAweDJjM2ExNjE2XG5dO1xuXG5mdW5jdGlvbiBCMCh4KSB7XG4gIHJldHVybiAoeCAmIDI1NSk7XG59XG5cbmZ1bmN0aW9uIEIxKHgpIHtcbiAgcmV0dXJuICgoeCA+PiA4KSAmIDI1NSk7XG59XG5cbmZ1bmN0aW9uIEIyKHgpIHtcbiAgcmV0dXJuICgoeCA+PiAxNikgJiAyNTUpO1xufVxuXG5mdW5jdGlvbiBCMyh4KSB7XG4gIHJldHVybiAoKHggPj4gMjQpICYgMjU1KTtcbn1cblxuZnVuY3Rpb24gRjEoeDAsIHgxLCB4MiwgeDMpIHtcbiAgcmV0dXJuIEIxKFQxW3gwICYgMjU1XSkgfCAoQjEoVDFbKHgxID4+IDgpICYgMjU1XSkgPDwgOCkgfCAoQjEoVDFbKHgyID4+IDE2KSAmIDI1NV0pIDw8IDE2KSB8IChCMShUMVt4MyA+Pj4gMjRdKSA8PFxuICAgIDI0KTtcbn1cblxuZnVuY3Rpb24gcGFja0J5dGVzKG9jdGV0cykge1xuICB2YXIgaSwgajtcbiAgdmFyIGxlbiA9IG9jdGV0cy5sZW5ndGg7XG4gIHZhciBiID0gbmV3IEFycmF5KGxlbiAvIDQpO1xuXG4gIGlmICghb2N0ZXRzIHx8IGxlbiAlIDQpIHJldHVybjtcblxuICBmb3IgKGkgPSAwLCBqID0gMDsgaiA8IGxlbjsgaiArPSA0KVxuICAgIGJbaSsrXSA9IG9jdGV0c1tqXSB8IChvY3RldHNbaiArIDFdIDw8IDgpIHwgKG9jdGV0c1tqICsgMl0gPDwgMTYpIHwgKG9jdGV0c1tqICsgM10gPDwgMjQpO1xuXG4gIHJldHVybiBiO1xufVxuXG5mdW5jdGlvbiB1bnBhY2tCeXRlcyhwYWNrZWQpIHtcbiAgdmFyIGo7XG4gIHZhciBpID0gMCxcbiAgICBsID0gcGFja2VkLmxlbmd0aDtcbiAgdmFyIHIgPSBuZXcgQXJyYXkobCAqIDQpO1xuXG4gIGZvciAoaiA9IDA7IGogPCBsOyBqKyspIHtcbiAgICByW2krK10gPSBCMChwYWNrZWRbal0pO1xuICAgIHJbaSsrXSA9IEIxKHBhY2tlZFtqXSk7XG4gICAgcltpKytdID0gQjIocGFja2VkW2pdKTtcbiAgICByW2krK10gPSBCMyhwYWNrZWRbal0pO1xuICB9XG4gIHJldHVybiByO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxudmFyIG1heGtjID0gODtcbnZhciBtYXhyayA9IDE0O1xuXG5mdW5jdGlvbiBrZXlFeHBhbnNpb24oa2V5KSB7XG4gIHZhciBrYywgaSwgaiwgciwgdDtcbiAgdmFyIHJvdW5kcztcbiAgdmFyIGtleVNjaGVkID0gbmV3IEFycmF5KG1heHJrICsgMSk7XG4gIHZhciBrZXlsZW4gPSBrZXkubGVuZ3RoO1xuICB2YXIgayA9IG5ldyBBcnJheShtYXhrYyk7XG4gIHZhciB0ayA9IG5ldyBBcnJheShtYXhrYyk7XG4gIHZhciByY29ucG9pbnRlciA9IDA7XG5cbiAgaWYgKGtleWxlbiA9PSAxNikge1xuICAgIHJvdW5kcyA9IDEwO1xuICAgIGtjID0gNDtcbiAgfSBlbHNlIGlmIChrZXlsZW4gPT0gMjQpIHtcbiAgICByb3VuZHMgPSAxMjtcbiAgICBrYyA9IDY7XG4gIH0gZWxzZSBpZiAoa2V5bGVuID09IDMyKSB7XG4gICAgcm91bmRzID0gMTQ7XG4gICAga2MgPSA4O1xuICB9IGVsc2Uge1xuICAgIHV0aWwucHJpbnRfZXJyb3IoJ2Flcy5qczogSW52YWxpZCBrZXktbGVuZ3RoIGZvciBBRVMga2V5OicgKyBrZXlsZW4pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvciAoaSA9IDA7IGkgPCBtYXhyayArIDE7IGkrKykga2V5U2NoZWRbaV0gPSBuZXcgQXJyYXkoNCk7XG5cbiAgZm9yIChpID0gMCwgaiA9IDA7IGogPCBrZXlsZW47IGorKywgaSArPSA0KVxuICAgIGtbal0gPSBrZXkuY2hhckNvZGVBdChpKSB8IChrZXkuY2hhckNvZGVBdChpICsgMSkgPDwgOCkgfCAoa2V5LmNoYXJDb2RlQXQoaSArIDIpIDw8IDE2KSB8IChrZXkuY2hhckNvZGVBdChpICsgMykgPDxcbiAgICAgIDI0KTtcblxuICBmb3IgKGogPSBrYyAtIDE7IGogPj0gMDsgai0tKSB0a1tqXSA9IGtbal07XG5cbiAgciA9IDA7XG4gIHQgPSAwO1xuICBmb3IgKGogPSAwO1xuICAoaiA8IGtjKSAmJiAociA8IHJvdW5kcyArIDEpOykge1xuICAgIGZvciAoO1xuICAgIChqIDwga2MpICYmICh0IDwgNCk7IGorKywgdCsrKSB7XG4gICAgICBrZXlTY2hlZFtyXVt0XSA9IHRrW2pdO1xuICAgIH1cbiAgICBpZiAodCA9PSA0KSB7XG4gICAgICByKys7XG4gICAgICB0ID0gMDtcbiAgICB9XG4gIH1cblxuICB3aGlsZSAociA8IHJvdW5kcyArIDEpIHtcbiAgICB2YXIgdGVtcCA9IHRrW2tjIC0gMV07XG5cbiAgICB0a1swXSBePSBTW0IxKHRlbXApXSB8IChTW0IyKHRlbXApXSA8PCA4KSB8IChTW0IzKHRlbXApXSA8PCAxNikgfCAoU1tCMCh0ZW1wKV0gPDwgMjQpO1xuICAgIHRrWzBdIF49IFJjb25bcmNvbnBvaW50ZXIrK107XG5cbiAgICBpZiAoa2MgIT0gOCkge1xuICAgICAgZm9yIChqID0gMTsgaiA8IGtjOyBqKyspIHRrW2pdIF49IHRrW2ogLSAxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChqID0gMTsgaiA8IGtjIC8gMjsgaisrKSB0a1tqXSBePSB0a1tqIC0gMV07XG5cbiAgICAgIHRlbXAgPSB0a1trYyAvIDIgLSAxXTtcbiAgICAgIHRrW2tjIC8gMl0gXj0gU1tCMCh0ZW1wKV0gfCAoU1tCMSh0ZW1wKV0gPDwgOCkgfCAoU1tCMih0ZW1wKV0gPDwgMTYpIHwgKFNbQjModGVtcCldIDw8IDI0KTtcblxuICAgICAgZm9yIChqID0ga2MgLyAyICsgMTsgaiA8IGtjOyBqKyspIHRrW2pdIF49IHRrW2ogLSAxXTtcbiAgICB9XG5cbiAgICBmb3IgKGogPSAwO1xuICAgIChqIDwga2MpICYmIChyIDwgcm91bmRzICsgMSk7KSB7XG4gICAgICBmb3IgKDtcbiAgICAgIChqIDwga2MpICYmICh0IDwgNCk7IGorKywgdCsrKSB7XG4gICAgICAgIGtleVNjaGVkW3JdW3RdID0gdGtbal07XG4gICAgICB9XG4gICAgICBpZiAodCA9PSA0KSB7XG4gICAgICAgIHIrKztcbiAgICAgICAgdCA9IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHRoaXMucm91bmRzID0gcm91bmRzO1xuICB0aGlzLnJrID0ga2V5U2NoZWQ7XG4gIHJldHVybiB0aGlzO1xufVxuXG5mdW5jdGlvbiBBRVNlbmNyeXB0KGJsb2NrLCBjdHgpIHtcbiAgdmFyIHI7XG4gIHZhciB0MCwgdDEsIHQyLCB0MztcblxuICB2YXIgYiA9IHBhY2tCeXRlcyhibG9jayk7XG4gIHZhciByb3VuZHMgPSBjdHgucm91bmRzO1xuICB2YXIgYjAgPSBiWzBdO1xuICB2YXIgYjEgPSBiWzFdO1xuICB2YXIgYjIgPSBiWzJdO1xuICB2YXIgYjMgPSBiWzNdO1xuXG4gIGZvciAociA9IDA7IHIgPCByb3VuZHMgLSAxOyByKyspIHtcbiAgICB0MCA9IGIwIF4gY3R4LnJrW3JdWzBdO1xuICAgIHQxID0gYjEgXiBjdHgucmtbcl1bMV07XG4gICAgdDIgPSBiMiBeIGN0eC5ya1tyXVsyXTtcbiAgICB0MyA9IGIzIF4gY3R4LnJrW3JdWzNdO1xuXG4gICAgYjAgPSBUMVt0MCAmIDI1NV0gXiBUMlsodDEgPj4gOCkgJiAyNTVdIF4gVDNbKHQyID4+IDE2KSAmIDI1NV0gXiBUNFt0MyA+Pj4gMjRdO1xuICAgIGIxID0gVDFbdDEgJiAyNTVdIF4gVDJbKHQyID4+IDgpICYgMjU1XSBeIFQzWyh0MyA+PiAxNikgJiAyNTVdIF4gVDRbdDAgPj4+IDI0XTtcbiAgICBiMiA9IFQxW3QyICYgMjU1XSBeIFQyWyh0MyA+PiA4KSAmIDI1NV0gXiBUM1sodDAgPj4gMTYpICYgMjU1XSBeIFQ0W3QxID4+PiAyNF07XG4gICAgYjMgPSBUMVt0MyAmIDI1NV0gXiBUMlsodDAgPj4gOCkgJiAyNTVdIF4gVDNbKHQxID4+IDE2KSAmIDI1NV0gXiBUNFt0MiA+Pj4gMjRdO1xuICB9XG5cbiAgLy8gbGFzdCByb3VuZCBpcyBzcGVjaWFsXG4gIHIgPSByb3VuZHMgLSAxO1xuXG4gIHQwID0gYjAgXiBjdHgucmtbcl1bMF07XG4gIHQxID0gYjEgXiBjdHgucmtbcl1bMV07XG4gIHQyID0gYjIgXiBjdHgucmtbcl1bMl07XG4gIHQzID0gYjMgXiBjdHgucmtbcl1bM107XG5cbiAgYlswXSA9IEYxKHQwLCB0MSwgdDIsIHQzKSBeIGN0eC5ya1tyb3VuZHNdWzBdO1xuICBiWzFdID0gRjEodDEsIHQyLCB0MywgdDApIF4gY3R4LnJrW3JvdW5kc11bMV07XG4gIGJbMl0gPSBGMSh0MiwgdDMsIHQwLCB0MSkgXiBjdHgucmtbcm91bmRzXVsyXTtcbiAgYlszXSA9IEYxKHQzLCB0MCwgdDEsIHQyKSBeIGN0eC5ya1tyb3VuZHNdWzNdO1xuXG4gIHJldHVybiB1bnBhY2tCeXRlcyhiKTtcbn1cblxuZnVuY3Rpb24gbWFrZUNsYXNzKGxlbmd0aCkge1xuXG4gIHZhciBjID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgdGhpcy5rZXkgPSBrZXlFeHBhbnNpb24oa2V5KTtcblxuICAgIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG4gICAgICByZXR1cm4gQUVTZW5jcnlwdChibG9jaywgdGhpcy5rZXkpO1xuICAgIH1cbiAgfVxuXG4gIGMuYmxvY2tTaXplID0gYy5wcm90b3R5cGUuYmxvY2tTaXplID0gMTY7XG4gIGMua2V5U2l6ZSA9IGMucHJvdG90eXBlLmtleVNpemUgPSBsZW5ndGggLyA4O1xuXG4gIHJldHVybiBjO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHt9XG5cbnZhciB0eXBlcyA9IFsxMjgsIDE5MiwgMjU2XTtcblxuZm9yICh2YXIgaSBpbiB0eXBlcykge1xuICBtb2R1bGUuZXhwb3J0c1t0eXBlc1tpXV0gPSBtYWtlQ2xhc3ModHlwZXNbaV0pO1xufVxuIiwiLyogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIIFxuICogXG4gKiBPcmlnaW5hbGx5IHdyaXR0ZW4gYnkgbmtsZWluIHNvZnR3YXJlIChua2xlaW4uY29tKVxuICovXG5cbi8qIFxuICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBiYXNlZCBvbiBCcnVjZSBTY2huZWllcidzIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbi5cbiAqXG4gKlxuICogVGhlIGNvbnN0cnVjdG9yIGRvZXNuJ3QgZG8gbXVjaCBvZiBhbnl0aGluZy4gIEl0J3MganVzdCBoZXJlXG4gKiBzbyB3ZSBjYW4gc3RhcnQgZGVmaW5pbmcgcHJvcGVydGllcyBhbmQgbWV0aG9kcyBhbmQgc3VjaC5cbiAqL1xuZnVuY3Rpb24gQmxvd2Zpc2goKSB7fTtcblxuLypcbiAqIERlY2xhcmUgdGhlIGJsb2NrIHNpemUgc28gdGhhdCBwcm90b2NvbHMga25vdyB3aGF0IHNpemVcbiAqIEluaXRpYWxpemF0aW9uIFZlY3RvciAoSVYpIHRoZXkgd2lsbCBuZWVkLlxuICovXG5CbG93ZmlzaC5wcm90b3R5cGUuQkxPQ0tTSVpFID0gODtcblxuLypcbiAqIFRoZXNlIGFyZSB0aGUgZGVmYXVsdCBTQk9YRVMuXG4gKi9cbkJsb3dmaXNoLnByb3RvdHlwZS5TQk9YRVMgPSBbXG4gIFtcbiAgICAgIDB4ZDEzMTBiYTYsIDB4OThkZmI1YWMsIDB4MmZmZDcyZGIsIDB4ZDAxYWRmYjcsIDB4YjhlMWFmZWQsIDB4NmEyNjdlOTYsXG4gICAgICAweGJhN2M5MDQ1LCAweGYxMmM3Zjk5LCAweDI0YTE5OTQ3LCAweGIzOTE2Y2Y3LCAweDA4MDFmMmUyLCAweDg1OGVmYzE2LFxuICAgICAgMHg2MzY5MjBkOCwgMHg3MTU3NGU2OSwgMHhhNDU4ZmVhMywgMHhmNDkzM2Q3ZSwgMHgwZDk1NzQ4ZiwgMHg3MjhlYjY1OCxcbiAgICAgIDB4NzE4YmNkNTgsIDB4ODIxNTRhZWUsIDB4N2I1NGE0MWQsIDB4YzI1YTU5YjUsIDB4OWMzMGQ1MzksIDB4MmFmMjYwMTMsXG4gICAgICAweGM1ZDFiMDIzLCAweDI4NjA4NWYwLCAweGNhNDE3OTE4LCAweGI4ZGIzOGVmLCAweDhlNzlkY2IwLCAweDYwM2ExODBlLFxuICAgICAgMHg2YzllMGU4YiwgMHhiMDFlOGEzZSwgMHhkNzE1NzdjMSwgMHhiZDMxNGIyNywgMHg3OGFmMmZkYSwgMHg1NTYwNWM2MCxcbiAgICAgIDB4ZTY1NTI1ZjMsIDB4YWE1NWFiOTQsIDB4NTc0ODk4NjIsIDB4NjNlODE0NDAsIDB4NTVjYTM5NmEsIDB4MmFhYjEwYjYsXG4gICAgICAweGI0Y2M1YzM0LCAweDExNDFlOGNlLCAweGExNTQ4NmFmLCAweDdjNzJlOTkzLCAweGIzZWUxNDExLCAweDYzNmZiYzJhLFxuICAgICAgMHgyYmE5YzU1ZCwgMHg3NDE4MzFmNiwgMHhjZTVjM2UxNiwgMHg5Yjg3OTMxZSwgMHhhZmQ2YmEzMywgMHg2YzI0Y2Y1YyxcbiAgICAgIDB4N2EzMjUzODEsIDB4Mjg5NTg2NzcsIDB4M2I4ZjQ4OTgsIDB4NmI0YmI5YWYsIDB4YzRiZmU4MWIsIDB4NjYyODIxOTMsXG4gICAgICAweDYxZDgwOWNjLCAweGZiMjFhOTkxLCAweDQ4N2NhYzYwLCAweDVkZWM4MDMyLCAweGVmODQ1ZDVkLCAweGU5ODU3NWIxLFxuICAgICAgMHhkYzI2MjMwMiwgMHhlYjY1MWI4OCwgMHgyMzg5M2U4MSwgMHhkMzk2YWNjNSwgMHgwZjZkNmZmMywgMHg4M2Y0NDIzOSxcbiAgICAgIDB4MmUwYjQ0ODIsIDB4YTQ4NDIwMDQsIDB4NjljOGYwNGEsIDB4OWUxZjliNWUsIDB4MjFjNjY4NDIsIDB4ZjZlOTZjOWEsXG4gICAgICAweDY3MGM5YzYxLCAweGFiZDM4OGYwLCAweDZhNTFhMGQyLCAweGQ4NTQyZjY4LCAweDk2MGZhNzI4LCAweGFiNTEzM2EzLFxuICAgICAgMHg2ZWVmMGI2YywgMHgxMzdhM2JlNCwgMHhiYTNiZjA1MCwgMHg3ZWZiMmE5OCwgMHhhMWYxNjUxZCwgMHgzOWFmMDE3NixcbiAgICAgIDB4NjZjYTU5M2UsIDB4ODI0MzBlODgsIDB4OGNlZTg2MTksIDB4NDU2ZjlmYjQsIDB4N2Q4NGE1YzMsIDB4M2I4YjVlYmUsXG4gICAgICAweGUwNmY3NWQ4LCAweDg1YzEyMDczLCAweDQwMWE0NDlmLCAweDU2YzE2YWE2LCAweDRlZDNhYTYyLCAweDM2M2Y3NzA2LFxuICAgICAgMHgxYmZlZGY3MiwgMHg0MjliMDIzZCwgMHgzN2QwZDcyNCwgMHhkMDBhMTI0OCwgMHhkYjBmZWFkMywgMHg0OWYxYzA5YixcbiAgICAgIDB4MDc1MzcyYzksIDB4ODA5OTFiN2IsIDB4MjVkNDc5ZDgsIDB4ZjZlOGRlZjcsIDB4ZTNmZTUwMWEsIDB4YjY3OTRjM2IsXG4gICAgICAweDk3NmNlMGJkLCAweDA0YzAwNmJhLCAweGMxYTk0ZmI2LCAweDQwOWY2MGM0LCAweDVlNWM5ZWMyLCAweDE5NmEyNDYzLFxuICAgICAgMHg2OGZiNmZhZiwgMHgzZTZjNTNiNSwgMHgxMzM5YjJlYiwgMHgzYjUyZWM2ZiwgMHg2ZGZjNTExZiwgMHg5YjMwOTUyYyxcbiAgICAgIDB4Y2M4MTQ1NDQsIDB4YWY1ZWJkMDksIDB4YmVlM2QwMDQsIDB4ZGUzMzRhZmQsIDB4NjYwZjI4MDcsIDB4MTkyZTRiYjMsXG4gICAgICAweGMwY2JhODU3LCAweDQ1Yzg3NDBmLCAweGQyMGI1ZjM5LCAweGI5ZDNmYmRiLCAweDU1NzljMGJkLCAweDFhNjAzMjBhLFxuICAgICAgMHhkNmExMDBjNiwgMHg0MDJjNzI3OSwgMHg2NzlmMjVmZSwgMHhmYjFmYTNjYywgMHg4ZWE1ZTlmOCwgMHhkYjMyMjJmOCxcbiAgICAgIDB4M2M3NTE2ZGYsIDB4ZmQ2MTZiMTUsIDB4MmY1MDFlYzgsIDB4YWQwNTUyYWIsIDB4MzIzZGI1ZmEsIDB4ZmQyMzg3NjAsXG4gICAgICAweDUzMzE3YjQ4LCAweDNlMDBkZjgyLCAweDllNWM1N2JiLCAweGNhNmY4Y2EwLCAweDFhODc1NjJlLCAweGRmMTc2OWRiLFxuICAgICAgMHhkNTQyYThmNiwgMHgyODdlZmZjMywgMHhhYzY3MzJjNiwgMHg4YzRmNTU3MywgMHg2OTViMjdiMCwgMHhiYmNhNThjOCxcbiAgICAgIDB4ZTFmZmEzNWQsIDB4YjhmMDExYTAsIDB4MTBmYTNkOTgsIDB4ZmQyMTgzYjgsIDB4NGFmY2I1NmMsIDB4MmRkMWQzNWIsXG4gICAgICAweDlhNTNlNDc5LCAweGI2Zjg0NTY1LCAweGQyOGU0OWJjLCAweDRiZmI5NzkwLCAweGUxZGRmMmRhLCAweGE0Y2I3ZTMzLFxuICAgICAgMHg2MmZiMTM0MSwgMHhjZWU0YzZlOCwgMHhlZjIwY2FkYSwgMHgzNjc3NGMwMSwgMHhkMDdlOWVmZSwgMHgyYmYxMWZiNCxcbiAgICAgIDB4OTVkYmRhNGQsIDB4YWU5MDkxOTgsIDB4ZWFhZDhlNzEsIDB4NmI5M2Q1YTAsIDB4ZDA4ZWQxZDAsIDB4YWZjNzI1ZTAsXG4gICAgICAweDhlM2M1YjJmLCAweDhlNzU5NGI3LCAweDhmZjZlMmZiLCAweGYyMTIyYjY0LCAweDg4ODhiODEyLCAweDkwMGRmMDFjLFxuICAgICAgMHg0ZmFkNWVhMCwgMHg2ODhmYzMxYywgMHhkMWNmZjE5MSwgMHhiM2E4YzFhZCwgMHgyZjJmMjIxOCwgMHhiZTBlMTc3NyxcbiAgICAgIDB4ZWE3NTJkZmUsIDB4OGIwMjFmYTEsIDB4ZTVhMGNjMGYsIDB4YjU2Zjc0ZTgsIDB4MThhY2YzZDYsIDB4Y2U4OWUyOTksXG4gICAgICAweGI0YTg0ZmUwLCAweGZkMTNlMGI3LCAweDdjYzQzYjgxLCAweGQyYWRhOGQ5LCAweDE2NWZhMjY2LCAweDgwOTU3NzA1LFxuICAgICAgMHg5M2NjNzMxNCwgMHgyMTFhMTQ3NywgMHhlNmFkMjA2NSwgMHg3N2I1ZmE4NiwgMHhjNzU0NDJmNSwgMHhmYjlkMzVjZixcbiAgICAgIDB4ZWJjZGFmMGMsIDB4N2IzZTg5YTAsIDB4ZDY0MTFiZDMsIDB4YWUxZTdlNDksIDB4MDAyNTBlMmQsIDB4MjA3MWIzNWUsXG4gICAgICAweDIyNjgwMGJiLCAweDU3YjhlMGFmLCAweDI0NjQzNjliLCAweGYwMDliOTFlLCAweDU1NjM5MTFkLCAweDU5ZGZhNmFhLFxuICAgICAgMHg3OGMxNDM4OSwgMHhkOTVhNTM3ZiwgMHgyMDdkNWJhMiwgMHgwMmU1YjljNSwgMHg4MzI2MDM3NiwgMHg2Mjk1Y2ZhOSxcbiAgICAgIDB4MTFjODE5NjgsIDB4NGU3MzRhNDEsIDB4YjM0NzJkY2EsIDB4N2IxNGE5NGEsIDB4MWI1MTAwNTIsIDB4OWE1MzI5MTUsXG4gICAgICAweGQ2MGY1NzNmLCAweGJjOWJjNmU0LCAweDJiNjBhNDc2LCAweDgxZTY3NDAwLCAweDA4YmE2ZmI1LCAweDU3MWJlOTFmLFxuICAgICAgMHhmMjk2ZWM2YiwgMHgyYTBkZDkxNSwgMHhiNjYzNjUyMSwgMHhlN2I5ZjliNiwgMHhmZjM0MDUyZSwgMHhjNTg1NTY2NCxcbiAgICAgIDB4NTNiMDJkNWQsIDB4YTk5ZjhmYTEsIDB4MDhiYTQ3OTksIDB4NmU4NTA3NmFcbiAgXSxcbiAgW1xuICAgICAgMHg0YjdhNzBlOSwgMHhiNWIzMjk0NCwgMHhkYjc1MDkyZSwgMHhjNDE5MjYyMywgMHhhZDZlYTZiMCwgMHg0OWE3ZGY3ZCxcbiAgICAgIDB4OWNlZTYwYjgsIDB4OGZlZGIyNjYsIDB4ZWNhYThjNzEsIDB4Njk5YTE3ZmYsIDB4NTY2NDUyNmMsIDB4YzJiMTllZTEsXG4gICAgICAweDE5MzYwMmE1LCAweDc1MDk0YzI5LCAweGEwNTkxMzQwLCAweGU0MTgzYTNlLCAweDNmNTQ5ODlhLCAweDViNDI5ZDY1LFxuICAgICAgMHg2YjhmZTRkNiwgMHg5OWY3M2ZkNiwgMHhhMWQyOWMwNywgMHhlZmU4MzBmNSwgMHg0ZDJkMzhlNiwgMHhmMDI1NWRjMSxcbiAgICAgIDB4NGNkZDIwODYsIDB4ODQ3MGViMjYsIDB4NjM4MmU5YzYsIDB4MDIxZWNjNWUsIDB4MDk2ODZiM2YsIDB4M2ViYWVmYzksXG4gICAgICAweDNjOTcxODE0LCAweDZiNmE3MGExLCAweDY4N2YzNTg0LCAweDUyYTBlMjg2LCAweGI3OWM1MzA1LCAweGFhNTAwNzM3LFxuICAgICAgMHgzZTA3ODQxYywgMHg3ZmRlYWU1YywgMHg4ZTdkNDRlYywgMHg1NzE2ZjJiOCwgMHhiMDNhZGEzNywgMHhmMDUwMGMwZCxcbiAgICAgIDB4ZjAxYzFmMDQsIDB4MDIwMGIzZmYsIDB4YWUwY2Y1MWEsIDB4M2NiNTc0YjIsIDB4MjU4MzdhNTgsIDB4ZGMwOTIxYmQsXG4gICAgICAweGQxOTExM2Y5LCAweDdjYTkyZmY2LCAweDk0MzI0NzczLCAweDIyZjU0NzAxLCAweDNhZTVlNTgxLCAweDM3YzJkYWRjLFxuICAgICAgMHhjOGI1NzYzNCwgMHg5YWYzZGRhNywgMHhhOTQ0NjE0NiwgMHgwZmQwMDMwZSwgMHhlY2M4YzczZSwgMHhhNDc1MWU0MSxcbiAgICAgIDB4ZTIzOGNkOTksIDB4M2JlYTBlMmYsIDB4MzI4MGJiYTEsIDB4MTgzZWIzMzEsIDB4NGU1NDhiMzgsIDB4NGY2ZGI5MDgsXG4gICAgICAweDZmNDIwZDAzLCAweGY2MGEwNGJmLCAweDJjYjgxMjkwLCAweDI0OTc3Yzc5LCAweDU2NzliMDcyLCAweGJjYWY4OWFmLFxuICAgICAgMHhkZTlhNzcxZiwgMHhkOTkzMDgxMCwgMHhiMzhiYWUxMiwgMHhkY2NmM2YyZSwgMHg1NTEyNzIxZiwgMHgyZTZiNzEyNCxcbiAgICAgIDB4NTAxYWRkZTYsIDB4OWY4NGNkODcsIDB4N2E1ODQ3MTgsIDB4NzQwOGRhMTcsIDB4YmM5ZjlhYmMsIDB4ZTk0YjdkOGMsXG4gICAgICAweGVjN2FlYzNhLCAweGRiODUxZGZhLCAweDYzMDk0MzY2LCAweGM0NjRjM2QyLCAweGVmMWMxODQ3LCAweDMyMTVkOTA4LFxuICAgICAgMHhkZDQzM2IzNywgMHgyNGMyYmExNiwgMHgxMmExNGQ0MywgMHgyYTY1YzQ1MSwgMHg1MDk0MDAwMiwgMHgxMzNhZTRkZCxcbiAgICAgIDB4NzFkZmY4OWUsIDB4MTAzMTRlNTUsIDB4ODFhYzc3ZDYsIDB4NWYxMTE5OWIsIDB4MDQzNTU2ZjEsIDB4ZDdhM2M3NmIsXG4gICAgICAweDNjMTExODNiLCAweDU5MjRhNTA5LCAweGYyOGZlNmVkLCAweDk3ZjFmYmZhLCAweDllYmFiZjJjLCAweDFlMTUzYzZlLFxuICAgICAgMHg4NmUzNDU3MCwgMHhlYWU5NmZiMSwgMHg4NjBlNWUwYSwgMHg1YTNlMmFiMywgMHg3NzFmZTcxYywgMHg0ZTNkMDZmYSxcbiAgICAgIDB4Mjk2NWRjYjksIDB4OTllNzFkMGYsIDB4ODAzZTg5ZDYsIDB4NTI2NmM4MjUsIDB4MmU0Y2M5NzgsIDB4OWMxMGIzNmEsXG4gICAgICAweGM2MTUwZWJhLCAweDk0ZTJlYTc4LCAweGE1ZmMzYzUzLCAweDFlMGEyZGY0LCAweGYyZjc0ZWE3LCAweDM2MWQyYjNkLFxuICAgICAgMHgxOTM5MjYwZiwgMHgxOWMyNzk2MCwgMHg1MjIzYTcwOCwgMHhmNzEzMTJiNiwgMHhlYmFkZmU2ZSwgMHhlYWMzMWY2NixcbiAgICAgIDB4ZTNiYzQ1OTUsIDB4YTY3YmM4ODMsIDB4YjE3ZjM3ZDEsIDB4MDE4Y2ZmMjgsIDB4YzMzMmRkZWYsIDB4YmU2YzVhYTUsXG4gICAgICAweDY1NTgyMTg1LCAweDY4YWI5ODAyLCAweGVlY2VhNTBmLCAweGRiMmY5NTNiLCAweDJhZWY3ZGFkLCAweDViNmUyZjg0LFxuICAgICAgMHgxNTIxYjYyOCwgMHgyOTA3NjE3MCwgMHhlY2RkNDc3NSwgMHg2MTlmMTUxMCwgMHgxM2NjYTgzMCwgMHhlYjYxYmQ5NixcbiAgICAgIDB4MDMzNGZlMWUsIDB4YWEwMzYzY2YsIDB4YjU3MzVjOTAsIDB4NGM3MGEyMzksIDB4ZDU5ZTllMGIsIDB4Y2JhYWRlMTQsXG4gICAgICAweGVlY2M4NmJjLCAweDYwNjIyY2E3LCAweDljYWI1Y2FiLCAweGIyZjM4NDZlLCAweDY0OGIxZWFmLCAweDE5YmRmMGNhLFxuICAgICAgMHhhMDIzNjliOSwgMHg2NTVhYmI1MCwgMHg0MDY4NWEzMiwgMHgzYzJhYjRiMywgMHgzMTllZTlkNSwgMHhjMDIxYjhmNyxcbiAgICAgIDB4OWI1NDBiMTksIDB4ODc1ZmEwOTksIDB4OTVmNzk5N2UsIDB4NjIzZDdkYTgsIDB4ZjgzNzg4OWEsIDB4OTdlMzJkNzcsXG4gICAgICAweDExZWQ5MzVmLCAweDE2NjgxMjgxLCAweDBlMzU4ODI5LCAweGM3ZTYxZmQ2LCAweDk2ZGVkZmExLCAweDc4NThiYTk5LFxuICAgICAgMHg1N2Y1ODRhNSwgMHgxYjIyNzI2MywgMHg5YjgzYzNmZiwgMHgxYWMyNDY5NiwgMHhjZGIzMGFlYiwgMHg1MzJlMzA1NCxcbiAgICAgIDB4OGZkOTQ4ZTQsIDB4NmRiYzMxMjgsIDB4NThlYmYyZWYsIDB4MzRjNmZmZWEsIDB4ZmUyOGVkNjEsIDB4ZWU3YzNjNzMsXG4gICAgICAweDVkNGExNGQ5LCAweGU4NjRiN2UzLCAweDQyMTA1ZDE0LCAweDIwM2UxM2UwLCAweDQ1ZWVlMmI2LCAweGEzYWFhYmVhLFxuICAgICAgMHhkYjZjNGYxNSwgMHhmYWNiNGZkMCwgMHhjNzQyZjQ0MiwgMHhlZjZhYmJiNSwgMHg2NTRmM2IxZCwgMHg0MWNkMjEwNSxcbiAgICAgIDB4ZDgxZTc5OWUsIDB4ODY4NTRkYzcsIDB4ZTQ0YjQ3NmEsIDB4M2Q4MTYyNTAsIDB4Y2Y2MmExZjIsIDB4NWI4ZDI2NDYsXG4gICAgICAweGZjODg4M2EwLCAweGMxYzdiNmEzLCAweDdmMTUyNGMzLCAweDY5Y2I3NDkyLCAweDQ3ODQ4YTBiLCAweDU2OTJiMjg1LFxuICAgICAgMHgwOTViYmYwMCwgMHhhZDE5NDg5ZCwgMHgxNDYyYjE3NCwgMHgyMzgyMGUwMCwgMHg1ODQyOGQyYSwgMHgwYzU1ZjVlYSxcbiAgICAgIDB4MWRhZGY0M2UsIDB4MjMzZjcwNjEsIDB4MzM3MmYwOTIsIDB4OGQ5MzdlNDEsIDB4ZDY1ZmVjZjEsIDB4NmMyMjNiZGIsXG4gICAgICAweDdjZGUzNzU5LCAweGNiZWU3NDYwLCAweDQwODVmMmE3LCAweGNlNzczMjZlLCAweGE2MDc4MDg0LCAweDE5Zjg1MDllLFxuICAgICAgMHhlOGVmZDg1NSwgMHg2MWQ5OTczNSwgMHhhOTY5YTdhYSwgMHhjNTBjMDZjMiwgMHg1YTA0YWJmYywgMHg4MDBiY2FkYyxcbiAgICAgIDB4OWU0NDdhMmUsIDB4YzM0NTM0ODQsIDB4ZmRkNTY3MDUsIDB4MGUxZTllYzksIDB4ZGI3M2RiZDMsIDB4MTA1NTg4Y2QsXG4gICAgICAweDY3NWZkYTc5LCAweGUzNjc0MzQwLCAweGM1YzQzNDY1LCAweDcxM2UzOGQ4LCAweDNkMjhmODllLCAweGYxNmRmZjIwLFxuICAgICAgMHgxNTNlMjFlNywgMHg4ZmIwM2Q0YSwgMHhlNmUzOWYyYiwgMHhkYjgzYWRmN1xuICBdLFxuICBbXG4gICAgICAweGU5M2Q1YTY4LCAweDk0ODE0MGY3LCAweGY2NGMyNjFjLCAweDk0NjkyOTM0LCAweDQxMTUyMGY3LCAweDc2MDJkNGY3LFxuICAgICAgMHhiY2Y0NmIyZSwgMHhkNGEyMDA2OCwgMHhkNDA4MjQ3MSwgMHgzMzIwZjQ2YSwgMHg0M2I3ZDRiNywgMHg1MDAwNjFhZixcbiAgICAgIDB4MWUzOWY2MmUsIDB4OTcyNDQ1NDYsIDB4MTQyMTRmNzQsIDB4YmY4Yjg4NDAsIDB4NGQ5NWZjMWQsIDB4OTZiNTkxYWYsXG4gICAgICAweDcwZjRkZGQzLCAweDY2YTAyZjQ1LCAweGJmYmMwOWVjLCAweDAzYmQ5Nzg1LCAweDdmYWM2ZGQwLCAweDMxY2I4NTA0LFxuICAgICAgMHg5NmViMjdiMywgMHg1NWZkMzk0MSwgMHhkYTI1NDdlNiwgMHhhYmNhMGE5YSwgMHgyODUwNzgyNSwgMHg1MzA0MjlmNCxcbiAgICAgIDB4MGEyYzg2ZGEsIDB4ZTliNjZkZmIsIDB4NjhkYzE0NjIsIDB4ZDc0ODY5MDAsIDB4NjgwZWMwYTQsIDB4MjdhMThkZWUsXG4gICAgICAweDRmM2ZmZWEyLCAweGU4ODdhZDhjLCAweGI1OGNlMDA2LCAweDdhZjRkNmI2LCAweGFhY2UxZTdjLCAweGQzMzc1ZmVjLFxuICAgICAgMHhjZTc4YTM5OSwgMHg0MDZiMmE0MiwgMHgyMGZlOWUzNSwgMHhkOWYzODViOSwgMHhlZTM5ZDdhYiwgMHgzYjEyNGU4YixcbiAgICAgIDB4MWRjOWZhZjcsIDB4NGI2ZDE4NTYsIDB4MjZhMzY2MzEsIDB4ZWFlMzk3YjIsIDB4M2E2ZWZhNzQsIDB4ZGQ1YjQzMzIsXG4gICAgICAweDY4NDFlN2Y3LCAweGNhNzgyMGZiLCAweGZiMGFmNTRlLCAweGQ4ZmViMzk3LCAweDQ1NDA1NmFjLCAweGJhNDg5NTI3LFxuICAgICAgMHg1NTUzM2EzYSwgMHgyMDgzOGQ4NywgMHhmZTZiYTliNywgMHhkMDk2OTU0YiwgMHg1NWE4NjdiYywgMHhhMTE1OWE1OCxcbiAgICAgIDB4Y2NhOTI5NjMsIDB4OTllMWRiMzMsIDB4YTYyYTRhNTYsIDB4M2YzMTI1ZjksIDB4NWVmNDdlMWMsIDB4OTAyOTMxN2MsXG4gICAgICAweGZkZjhlODAyLCAweDA0MjcyZjcwLCAweDgwYmIxNTVjLCAweDA1MjgyY2UzLCAweDk1YzExNTQ4LCAweGU0YzY2ZDIyLFxuICAgICAgMHg0OGMxMTMzZiwgMHhjNzBmODZkYywgMHgwN2Y5YzllZSwgMHg0MTA0MWYwZiwgMHg0MDQ3NzlhNCwgMHg1ZDg4NmUxNyxcbiAgICAgIDB4MzI1ZjUxZWIsIDB4ZDU5YmMwZDEsIDB4ZjJiY2MxOGYsIDB4NDExMTM1NjQsIDB4MjU3Yjc4MzQsIDB4NjAyYTljNjAsXG4gICAgICAweGRmZjhlOGEzLCAweDFmNjM2YzFiLCAweDBlMTJiNGMyLCAweDAyZTEzMjllLCAweGFmNjY0ZmQxLCAweGNhZDE4MTE1LFxuICAgICAgMHg2YjIzOTVlMCwgMHgzMzNlOTJlMSwgMHgzYjI0MGI2MiwgMHhlZWJlYjkyMiwgMHg4NWIyYTIwZSwgMHhlNmJhMGQ5OSxcbiAgICAgIDB4ZGU3MjBjOGMsIDB4MmRhMmY3MjgsIDB4ZDAxMjc4NDUsIDB4OTViNzk0ZmQsIDB4NjQ3ZDA4NjIsIDB4ZTdjY2Y1ZjAsXG4gICAgICAweDU0NDlhMzZmLCAweDg3N2Q0OGZhLCAweGMzOWRmZDI3LCAweGYzM2U4ZDFlLCAweDBhNDc2MzQxLCAweDk5MmVmZjc0LFxuICAgICAgMHgzYTZmNmVhYiwgMHhmNGY4ZmQzNywgMHhhODEyZGM2MCwgMHhhMWViZGRmOCwgMHg5OTFiZTE0YywgMHhkYjZlNmIwZCxcbiAgICAgIDB4YzY3YjU1MTAsIDB4NmQ2NzJjMzcsIDB4Mjc2NWQ0M2IsIDB4ZGNkMGU4MDQsIDB4ZjEyOTBkYzcsIDB4Y2MwMGZmYTMsXG4gICAgICAweGI1MzkwZjkyLCAweDY5MGZlZDBiLCAweDY2N2I5ZmZiLCAweGNlZGI3ZDljLCAweGEwOTFjZjBiLCAweGQ5MTU1ZWEzLFxuICAgICAgMHhiYjEzMmY4OCwgMHg1MTViYWQyNCwgMHg3Yjk0NzliZiwgMHg3NjNiZDZlYiwgMHgzNzM5MmViMywgMHhjYzExNTk3OSxcbiAgICAgIDB4ODAyNmUyOTcsIDB4ZjQyZTMxMmQsIDB4Njg0MmFkYTcsIDB4YzY2YTJiM2IsIDB4MTI3NTRjY2MsIDB4NzgyZWYxMWMsXG4gICAgICAweDZhMTI0MjM3LCAweGI3OTI1MWU3LCAweDA2YTFiYmU2LCAweDRiZmI2MzUwLCAweDFhNmIxMDE4LCAweDExY2FlZGZhLFxuICAgICAgMHgzZDI1YmRkOCwgMHhlMmUxYzNjOSwgMHg0NDQyMTY1OSwgMHgwYTEyMTM4NiwgMHhkOTBjZWM2ZSwgMHhkNWFiZWEyYSxcbiAgICAgIDB4NjRhZjY3NGUsIDB4ZGE4NmE4NWYsIDB4YmViZmU5ODgsIDB4NjRlNGMzZmUsIDB4OWRiYzgwNTcsIDB4ZjBmN2MwODYsXG4gICAgICAweDYwNzg3YmY4LCAweDYwMDM2MDRkLCAweGQxZmQ4MzQ2LCAweGY2MzgxZmIwLCAweDc3NDVhZTA0LCAweGQ3MzZmY2NjLFxuICAgICAgMHg4MzQyNmIzMywgMHhmMDFlYWI3MSwgMHhiMDgwNDE4NywgMHgzYzAwNWU1ZiwgMHg3N2EwNTdiZSwgMHhiZGU4YWUyNCxcbiAgICAgIDB4NTU0NjQyOTksIDB4YmY1ODJlNjEsIDB4NGU1OGY0OGYsIDB4ZjJkZGZkYTIsIDB4ZjQ3NGVmMzgsIDB4ODc4OWJkYzIsXG4gICAgICAweDUzNjZmOWMzLCAweGM4YjM4ZTc0LCAweGI0NzVmMjU1LCAweDQ2ZmNkOWI5LCAweDdhZWIyNjYxLCAweDhiMWRkZjg0LFxuICAgICAgMHg4NDZhMGU3OSwgMHg5MTVmOTVlMiwgMHg0NjZlNTk4ZSwgMHgyMGI0NTc3MCwgMHg4Y2Q1NTU5MSwgMHhjOTAyZGU0YyxcbiAgICAgIDB4YjkwYmFjZTEsIDB4YmI4MjA1ZDAsIDB4MTFhODYyNDgsIDB4NzU3NGE5OWUsIDB4Yjc3ZjE5YjYsIDB4ZTBhOWRjMDksXG4gICAgICAweDY2MmQwOWExLCAweGM0MzI0NjMzLCAweGU4NWExZjAyLCAweDA5ZjBiZThjLCAweDRhOTlhMDI1LCAweDFkNmVmZTEwLFxuICAgICAgMHgxYWI5M2QxZCwgMHgwYmE1YTRkZiwgMHhhMTg2ZjIwZiwgMHgyODY4ZjE2OSwgMHhkY2I3ZGE4MywgMHg1NzM5MDZmZSxcbiAgICAgIDB4YTFlMmNlOWIsIDB4NGZjZDdmNTIsIDB4NTAxMTVlMDEsIDB4YTcwNjgzZmEsIDB4YTAwMmI1YzQsIDB4MGRlNmQwMjcsXG4gICAgICAweDlhZjg4YzI3LCAweDc3M2Y4NjQxLCAweGMzNjA0YzA2LCAweDYxYTgwNmI1LCAweGYwMTc3YTI4LCAweGMwZjU4NmUwLFxuICAgICAgMHgwMDYwNThhYSwgMHgzMGRjN2Q2MiwgMHgxMWU2OWVkNywgMHgyMzM4ZWE2MywgMHg1M2MyZGQ5NCwgMHhjMmMyMTYzNCxcbiAgICAgIDB4YmJjYmVlNTYsIDB4OTBiY2I2ZGUsIDB4ZWJmYzdkYTEsIDB4Y2U1OTFkNzYsIDB4NmYwNWU0MDksIDB4NGI3YzAxODgsXG4gICAgICAweDM5NzIwYTNkLCAweDdjOTI3YzI0LCAweDg2ZTM3MjVmLCAweDcyNGQ5ZGI5LCAweDFhYzE1YmI0LCAweGQzOWViOGZjLFxuICAgICAgMHhlZDU0NTU3OCwgMHgwOGZjYTViNSwgMHhkODNkN2NkMywgMHg0ZGFkMGZjNCwgMHgxZTUwZWY1ZSwgMHhiMTYxZTZmOCxcbiAgICAgIDB4YTI4NTE0ZDksIDB4NmM1MTEzM2MsIDB4NmZkNWM3ZTcsIDB4NTZlMTRlYzQsIDB4MzYyYWJmY2UsIDB4ZGRjNmM4MzcsXG4gICAgICAweGQ3OWEzMjM0LCAweDkyNjM4MjEyLCAweDY3MGVmYThlLCAweDQwNjAwMGUwXG4gIF0sXG4gIFtcbiAgICAgIDB4M2EzOWNlMzcsIDB4ZDNmYWY1Y2YsIDB4YWJjMjc3MzcsIDB4NWFjNTJkMWIsIDB4NWNiMDY3OWUsIDB4NGZhMzM3NDIsXG4gICAgICAweGQzODIyNzQwLCAweDk5YmM5YmJlLCAweGQ1MTE4ZTlkLCAweGJmMGY3MzE1LCAweGQ2MmQxYzdlLCAweGM3MDBjNDdiLFxuICAgICAgMHhiNzhjMWI2YiwgMHgyMWExOTA0NSwgMHhiMjZlYjFiZSwgMHg2YTM2NmViNCwgMHg1NzQ4YWIyZiwgMHhiYzk0NmU3OSxcbiAgICAgIDB4YzZhMzc2ZDIsIDB4NjU0OWMyYzgsIDB4NTMwZmY4ZWUsIDB4NDY4ZGRlN2QsIDB4ZDU3MzBhMWQsIDB4NGNkMDRkYzYsXG4gICAgICAweDI5MzliYmRiLCAweGE5YmE0NjUwLCAweGFjOTUyNmU4LCAweGJlNWVlMzA0LCAweGExZmFkNWYwLCAweDZhMmQ1MTlhLFxuICAgICAgMHg2M2VmOGNlMiwgMHg5YTg2ZWUyMiwgMHhjMDg5YzJiOCwgMHg0MzI0MmVmNiwgMHhhNTFlMDNhYSwgMHg5Y2YyZDBhNCxcbiAgICAgIDB4ODNjMDYxYmEsIDB4OWJlOTZhNGQsIDB4OGZlNTE1NTAsIDB4YmE2NDViZDYsIDB4MjgyNmEyZjksIDB4YTczYTNhZTEsXG4gICAgICAweDRiYTk5NTg2LCAweGVmNTU2MmU5LCAweGM3MmZlZmQzLCAweGY3NTJmN2RhLCAweDNmMDQ2ZjY5LCAweDc3ZmEwYTU5LFxuICAgICAgMHg4MGU0YTkxNSwgMHg4N2IwODYwMSwgMHg5YjA5ZTZhZCwgMHgzYjNlZTU5MywgMHhlOTkwZmQ1YSwgMHg5ZTM0ZDc5NyxcbiAgICAgIDB4MmNmMGI3ZDksIDB4MDIyYjhiNTEsIDB4OTZkNWFjM2EsIDB4MDE3ZGE2N2QsIDB4ZDFjZjNlZDYsIDB4N2M3ZDJkMjgsXG4gICAgICAweDFmOWYyNWNmLCAweGFkZjJiODliLCAweDVhZDZiNDcyLCAweDVhODhmNTRjLCAweGUwMjlhYzcxLCAweGUwMTlhNWU2LFxuICAgICAgMHg0N2IwYWNmZCwgMHhlZDkzZmE5YiwgMHhlOGQzYzQ4ZCwgMHgyODNiNTdjYywgMHhmOGQ1NjYyOSwgMHg3OTEzMmUyOCxcbiAgICAgIDB4Nzg1ZjAxOTEsIDB4ZWQ3NTYwNTUsIDB4Zjc5NjBlNDQsIDB4ZTNkMzVlOGMsIDB4MTUwNTZkZDQsIDB4ODhmNDZkYmEsXG4gICAgICAweDAzYTE2MTI1LCAweDA1NjRmMGJkLCAweGMzZWI5ZTE1LCAweDNjOTA1N2EyLCAweDk3MjcxYWVjLCAweGE5M2EwNzJhLFxuICAgICAgMHgxYjNmNmQ5YiwgMHgxZTYzMjFmNSwgMHhmNTljNjZmYiwgMHgyNmRjZjMxOSwgMHg3NTMzZDkyOCwgMHhiMTU1ZmRmNSxcbiAgICAgIDB4MDM1NjM0ODIsIDB4OGFiYTNjYmIsIDB4Mjg1MTc3MTEsIDB4YzIwYWQ5ZjgsIDB4YWJjYzUxNjcsIDB4Y2NhZDkyNWYsXG4gICAgICAweDRkZTgxNzUxLCAweDM4MzBkYzhlLCAweDM3OWQ1ODYyLCAweDkzMjBmOTkxLCAweGVhN2E5MGMyLCAweGZiM2U3YmNlLFxuICAgICAgMHg1MTIxY2U2NCwgMHg3NzRmYmUzMiwgMHhhOGI2ZTM3ZSwgMHhjMzI5M2Q0NiwgMHg0OGRlNTM2OSwgMHg2NDEzZTY4MCxcbiAgICAgIDB4YTJhZTA4MTAsIDB4ZGQ2ZGIyMjQsIDB4Njk4NTJkZmQsIDB4MDkwNzIxNjYsIDB4YjM5YTQ2MGEsIDB4NjQ0NWMwZGQsXG4gICAgICAweDU4NmNkZWNmLCAweDFjMjBjOGFlLCAweDViYmVmN2RkLCAweDFiNTg4ZDQwLCAweGNjZDIwMTdmLCAweDZiYjRlM2JiLFxuICAgICAgMHhkZGEyNmE3ZSwgMHgzYTU5ZmY0NSwgMHgzZTM1MGE0NCwgMHhiY2I0Y2RkNSwgMHg3MmVhY2VhOCwgMHhmYTY0ODRiYixcbiAgICAgIDB4OGQ2NjEyYWUsIDB4YmYzYzZmNDcsIDB4ZDI5YmU0NjMsIDB4NTQyZjVkOWUsIDB4YWVjMjc3MWIsIDB4ZjY0ZTYzNzAsXG4gICAgICAweDc0MGUwZDhkLCAweGU3NWIxMzU3LCAweGY4NzIxNjcxLCAweGFmNTM3ZDVkLCAweDQwNDBjYjA4LCAweDRlYjRlMmNjLFxuICAgICAgMHgzNGQyNDY2YSwgMHgwMTE1YWY4NCwgMHhlMWIwMDQyOCwgMHg5NTk4M2ExZCwgMHgwNmI4OWZiNCwgMHhjZTZlYTA0OCxcbiAgICAgIDB4NmYzZjNiODIsIDB4MzUyMGFiODIsIDB4MDExYTFkNGIsIDB4Mjc3MjI3ZjgsIDB4NjExNTYwYjEsIDB4ZTc5MzNmZGMsXG4gICAgICAweGJiM2E3OTJiLCAweDM0NDUyNWJkLCAweGEwODgzOWUxLCAweDUxY2U3OTRiLCAweDJmMzJjOWI3LCAweGEwMWZiYWM5LFxuICAgICAgMHhlMDFjYzg3ZSwgMHhiY2M3ZDFmNiwgMHhjZjAxMTFjMywgMHhhMWU4YWFjNywgMHgxYTkwODc0OSwgMHhkNDRmYmQ5YSxcbiAgICAgIDB4ZDBkYWRlY2IsIDB4ZDUwYWRhMzgsIDB4MDMzOWMzMmEsIDB4YzY5MTM2NjcsIDB4OGRmOTMxN2MsIDB4ZTBiMTJiNGYsXG4gICAgICAweGY3OWU1OWI3LCAweDQzZjViYjNhLCAweGYyZDUxOWZmLCAweDI3ZDk0NTljLCAweGJmOTcyMjJjLCAweDE1ZTZmYzJhLFxuICAgICAgMHgwZjkxZmM3MSwgMHg5Yjk0MTUyNSwgMHhmYWU1OTM2MSwgMHhjZWI2OWNlYiwgMHhjMmE4NjQ1OSwgMHgxMmJhYThkMSxcbiAgICAgIDB4YjZjMTA3NWUsIDB4ZTMwNTZhMGMsIDB4MTBkMjUwNjUsIDB4Y2IwM2E0NDIsIDB4ZTBlYzZlMGUsIDB4MTY5OGRiM2IsXG4gICAgICAweDRjOThhMGJlLCAweDMyNzhlOTY0LCAweDlmMWY5NTMyLCAweGUwZDM5MmRmLCAweGQzYTAzNDJiLCAweDg5NzFmMjFlLFxuICAgICAgMHgxYjBhNzQ0MSwgMHg0YmEzMzQ4YywgMHhjNWJlNzEyMCwgMHhjMzc2MzJkOCwgMHhkZjM1OWY4ZCwgMHg5Yjk5MmYyZSxcbiAgICAgIDB4ZTYwYjZmNDcsIDB4MGZlM2YxMWQsIDB4ZTU0Y2RhNTQsIDB4MWVkYWQ4OTEsIDB4Y2U2Mjc5Y2YsIDB4Y2QzZTdlNmYsXG4gICAgICAweDE2MThiMTY2LCAweGZkMmMxZDA1LCAweDg0OGZkMmM1LCAweGY2ZmIyMjk5LCAweGY1MjNmMzU3LCAweGE2MzI3NjIzLFxuICAgICAgMHg5M2E4MzUzMSwgMHg1NmNjY2QwMiwgMHhhY2YwODE2MiwgMHg1YTc1ZWJiNSwgMHg2ZTE2MzY5NywgMHg4OGQyNzNjYyxcbiAgICAgIDB4ZGU5NjYyOTIsIDB4ODFiOTQ5ZDAsIDB4NGM1MDkwMWIsIDB4NzFjNjU2MTQsIDB4ZTZjNmM3YmQsIDB4MzI3YTE0MGEsXG4gICAgICAweDQ1ZTFkMDA2LCAweGMzZjI3YjlhLCAweGM5YWE1M2ZkLCAweDYyYTgwZjAwLCAweGJiMjViZmUyLCAweDM1YmRkMmY2LFxuICAgICAgMHg3MTEyNjkwNSwgMHhiMjA0MDIyMiwgMHhiNmNiY2Y3YywgMHhjZDc2OWMyYiwgMHg1MzExM2VjMCwgMHgxNjQwZTNkMyxcbiAgICAgIDB4MzhhYmJkNjAsIDB4MjU0N2FkZjAsIDB4YmEzODIwOWMsIDB4Zjc0NmNlNzYsIDB4NzdhZmExYzUsIDB4MjA3NTYwNjAsXG4gICAgICAweDg1Y2JmZTRlLCAweDhhZTg4ZGQ4LCAweDdhYWFmOWIwLCAweDRjZjlhYTdlLCAweDE5NDhjMjVjLCAweDAyZmI4YThjLFxuICAgICAgMHgwMWMzNmFlNCwgMHhkNmViZTFmOSwgMHg5MGQ0Zjg2OSwgMHhhNjVjZGVhMCwgMHgzZjA5MjUyZCwgMHhjMjA4ZTY5ZixcbiAgICAgIDB4Yjc0ZTYxMzIsIDB4Y2U3N2UyNWIsIDB4NTc4ZmRmZTMsIDB4M2FjMzcyZTZcbiAgXVxuXTtcblxuLy8qXG4vLyogVGhpcyBpcyB0aGUgZGVmYXVsdCBQQVJSQVlcbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLlBBUlJBWSA9IFtcbiAgICAweDI0M2Y2YTg4LCAweDg1YTMwOGQzLCAweDEzMTk4YTJlLCAweDAzNzA3MzQ0LCAweGE0MDkzODIyLCAweDI5OWYzMWQwLFxuICAgIDB4MDgyZWZhOTgsIDB4ZWM0ZTZjODksIDB4NDUyODIxZTYsIDB4MzhkMDEzNzcsIDB4YmU1NDY2Y2YsIDB4MzRlOTBjNmMsXG4gICAgMHhjMGFjMjliNywgMHhjOTdjNTBkZCwgMHgzZjg0ZDViNSwgMHhiNTQ3MDkxNywgMHg5MjE2ZDVkOSwgMHg4OTc5ZmIxYlxuXTtcblxuLy8qXG4vLyogVGhpcyBpcyB0aGUgbnVtYmVyIG9mIHJvdW5kcyB0aGUgY2lwaGVyIHdpbGwgZ29cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLk5OID0gMTY7XG5cbi8vKlxuLy8qIFRoaXMgZnVuY3Rpb24gaXMgbmVlZGVkIHRvIGdldCByaWQgb2YgcHJvYmxlbXNcbi8vKiB3aXRoIHRoZSBoaWdoLWJpdCBnZXR0aW5nIHNldC4gIElmIHdlIGRvbid0IGRvXG4vLyogdGhpcywgdGhlbiBzb21ldGltZXMgKCBhYSAmIDB4MDBGRkZGRkZGRiApIGlzIG5vdFxuLy8qIGVxdWFsIHRvICggYmIgJiAweDAwRkZGRkZGRkYgKSBldmVuIHdoZW4gdGhleVxuLy8qIGFncmVlIGJpdC1mb3ItYml0IGZvciB0aGUgZmlyc3QgMzIgYml0cy5cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLl9jbGVhbiA9IGZ1bmN0aW9uKHh4KSB7XG4gIGlmICh4eCA8IDApIHtcbiAgICB2YXIgeXkgPSB4eCAmIDB4N0ZGRkZGRkY7XG4gICAgeHggPSB5eSArIDB4ODAwMDAwMDA7XG4gIH1cbiAgcmV0dXJuIHh4O1xufTtcblxuLy8qXG4vLyogVGhpcyBpcyB0aGUgbWl4aW5nIGZ1bmN0aW9uIHRoYXQgdXNlcyB0aGUgc2JveGVzXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5fRiA9IGZ1bmN0aW9uKHh4KSB7XG4gIHZhciBhYTtcbiAgdmFyIGJiO1xuICB2YXIgY2M7XG4gIHZhciBkZDtcbiAgdmFyIHl5O1xuXG4gIGRkID0geHggJiAweDAwRkY7XG4gIHh4ID4+Pj0gODtcbiAgY2MgPSB4eCAmIDB4MDBGRjtcbiAgeHggPj4+PSA4O1xuICBiYiA9IHh4ICYgMHgwMEZGO1xuICB4eCA+Pj49IDg7XG4gIGFhID0geHggJiAweDAwRkY7XG5cbiAgeXkgPSB0aGlzLnNib3hlc1swXVthYV0gKyB0aGlzLnNib3hlc1sxXVtiYl07XG4gIHl5ID0geXkgXiB0aGlzLnNib3hlc1syXVtjY107XG4gIHl5ID0geXkgKyB0aGlzLnNib3hlc1szXVtkZF07XG5cbiAgcmV0dXJuIHl5O1xufTtcblxuLy8qXG4vLyogVGhpcyBtZXRob2QgdGFrZXMgYW4gYXJyYXkgd2l0aCB0d28gdmFsdWVzLCBsZWZ0IGFuZCByaWdodFxuLy8qIGFuZCBkb2VzIE5OIHJvdW5kcyBvZiBCbG93ZmlzaCBvbiB0aGVtLlxuLy8qXG5CbG93ZmlzaC5wcm90b3R5cGUuX2VuY3J5cHRfYmxvY2sgPSBmdW5jdGlvbih2YWxzKSB7XG4gIHZhciBkYXRhTCA9IHZhbHNbMF07XG4gIHZhciBkYXRhUiA9IHZhbHNbMV07XG5cbiAgdmFyIGlpO1xuXG4gIGZvciAoaWkgPSAwOyBpaSA8IHRoaXMuTk47ICsraWkpIHtcbiAgICBkYXRhTCA9IGRhdGFMIF4gdGhpcy5wYXJyYXlbaWldO1xuICAgIGRhdGFSID0gdGhpcy5fRihkYXRhTCkgXiBkYXRhUjtcblxuICAgIHZhciB0bXAgPSBkYXRhTDtcbiAgICBkYXRhTCA9IGRhdGFSO1xuICAgIGRhdGFSID0gdG1wO1xuICB9XG5cbiAgZGF0YUwgPSBkYXRhTCBeIHRoaXMucGFycmF5W3RoaXMuTk4gKyAwXTtcbiAgZGF0YVIgPSBkYXRhUiBeIHRoaXMucGFycmF5W3RoaXMuTk4gKyAxXTtcblxuICB2YWxzWzBdID0gdGhpcy5fY2xlYW4oZGF0YVIpO1xuICB2YWxzWzFdID0gdGhpcy5fY2xlYW4oZGF0YUwpO1xufTtcblxuLy8qXG4vLyogVGhpcyBtZXRob2QgdGFrZXMgYSB2ZWN0b3Igb2YgbnVtYmVycyBhbmQgdHVybnMgdGhlbVxuLy8qIGludG8gbG9uZyB3b3JkcyBzbyB0aGF0IHRoZXkgY2FuIGJlIHByb2Nlc3NlZCBieSB0aGVcbi8vKiByZWFsIGFsZ29yaXRobS5cbi8vKlxuLy8qIE1heWJlIEkgc2hvdWxkIG1ha2UgdGhlIHJlYWwgYWxnb3JpdGhtIGFib3ZlIHRha2UgYSB2ZWN0b3Jcbi8vKiBpbnN0ZWFkLiAgVGhhdCB3aWxsIGludm9sdmUgbW9yZSBsb29waW5nLCBidXQgaXQgd29uJ3QgcmVxdWlyZVxuLy8qIHRoZSBGKCkgbWV0aG9kIHRvIGRlY29uc3RydWN0IHRoZSB2ZWN0b3IuXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5lbmNyeXB0X2Jsb2NrID0gZnVuY3Rpb24odmVjdG9yKSB7XG4gIHZhciBpaTtcbiAgdmFyIHZhbHMgPSBbMCwgMF07XG4gIHZhciBvZmYgPSB0aGlzLkJMT0NLU0laRSAvIDI7XG4gIGZvciAoaWkgPSAwOyBpaSA8IHRoaXMuQkxPQ0tTSVpFIC8gMjsgKytpaSkge1xuICAgIHZhbHNbMF0gPSAodmFsc1swXSA8PCA4KSB8ICh2ZWN0b3JbaWkgKyAwXSAmIDB4MDBGRik7XG4gICAgdmFsc1sxXSA9ICh2YWxzWzFdIDw8IDgpIHwgKHZlY3RvcltpaSArIG9mZl0gJiAweDAwRkYpO1xuICB9XG5cbiAgdGhpcy5fZW5jcnlwdF9ibG9jayh2YWxzKTtcblxuICB2YXIgcmV0ID0gW107XG4gIGZvciAoaWkgPSAwOyBpaSA8IHRoaXMuQkxPQ0tTSVpFIC8gMjsgKytpaSkge1xuICAgIHJldFtpaSArIDBdID0gKHZhbHNbMF0gPj4+ICgyNCAtIDggKiAoaWkpKSAmIDB4MDBGRik7XG4gICAgcmV0W2lpICsgb2ZmXSA9ICh2YWxzWzFdID4+PiAoMjQgLSA4ICogKGlpKSkgJiAweDAwRkYpO1xuICAgIC8vIHZhbHNbIDAgXSA9ICggdmFsc1sgMCBdID4+PiA4ICk7XG4gICAgLy8gdmFsc1sgMSBdID0gKCB2YWxzWyAxIF0gPj4+IDggKTtcbiAgfVxuXG4gIHJldHVybiByZXQ7XG59O1xuXG4vLypcbi8vKiBUaGlzIG1ldGhvZCB0YWtlcyBhbiBhcnJheSB3aXRoIHR3byB2YWx1ZXMsIGxlZnQgYW5kIHJpZ2h0XG4vLyogYW5kIHVuZG9lcyBOTiByb3VuZHMgb2YgQmxvd2Zpc2ggb24gdGhlbS5cbi8vKlxuQmxvd2Zpc2gucHJvdG90eXBlLl9kZWNyeXB0X2Jsb2NrID0gZnVuY3Rpb24odmFscykge1xuICB2YXIgZGF0YUwgPSB2YWxzWzBdO1xuICB2YXIgZGF0YVIgPSB2YWxzWzFdO1xuXG4gIHZhciBpaTtcblxuICBmb3IgKGlpID0gdGhpcy5OTiArIDE7IGlpID4gMTsgLS1paSkge1xuICAgIGRhdGFMID0gZGF0YUwgXiB0aGlzLnBhcnJheVtpaV07XG4gICAgZGF0YVIgPSB0aGlzLl9GKGRhdGFMKSBeIGRhdGFSO1xuXG4gICAgdmFyIHRtcCA9IGRhdGFMO1xuICAgIGRhdGFMID0gZGF0YVI7XG4gICAgZGF0YVIgPSB0bXA7XG4gIH1cblxuICBkYXRhTCA9IGRhdGFMIF4gdGhpcy5wYXJyYXlbMV07XG4gIGRhdGFSID0gZGF0YVIgXiB0aGlzLnBhcnJheVswXTtcblxuICB2YWxzWzBdID0gdGhpcy5fY2xlYW4oZGF0YVIpO1xuICB2YWxzWzFdID0gdGhpcy5fY2xlYW4oZGF0YUwpO1xufTtcblxuLy8qXG4vLyogVGhpcyBtZXRob2QgdGFrZXMgYSBrZXkgYXJyYXkgYW5kIGluaXRpYWxpemVzIHRoZVxuLy8qIHNib3hlcyBhbmQgcGFycmF5IGZvciB0aGlzIGVuY3J5cHRpb24uXG4vLypcbkJsb3dmaXNoLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24oa2V5KSB7XG4gIHZhciBpaTtcbiAgdmFyIGpqID0gMDtcblxuICB0aGlzLnBhcnJheSA9IFtdO1xuICBmb3IgKGlpID0gMDsgaWkgPCB0aGlzLk5OICsgMjsgKytpaSkge1xuICAgIHZhciBkYXRhID0gMHgwMDAwMDAwMDtcbiAgICB2YXIga2s7XG4gICAgZm9yIChrayA9IDA7IGtrIDwgNDsgKytraykge1xuICAgICAgZGF0YSA9IChkYXRhIDw8IDgpIHwgKGtleVtqal0gJiAweDAwRkYpO1xuICAgICAgaWYgKCsramogPj0ga2V5Lmxlbmd0aCkge1xuICAgICAgICBqaiA9IDA7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucGFycmF5W2lpXSA9IHRoaXMuUEFSUkFZW2lpXSBeIGRhdGE7XG4gIH1cblxuICB0aGlzLnNib3hlcyA9IFtdO1xuICBmb3IgKGlpID0gMDsgaWkgPCA0OyArK2lpKSB7XG4gICAgdGhpcy5zYm94ZXNbaWldID0gW107XG4gICAgZm9yIChqaiA9IDA7IGpqIDwgMjU2OyArK2pqKSB7XG4gICAgICB0aGlzLnNib3hlc1tpaV1bampdID0gdGhpcy5TQk9YRVNbaWldW2pqXTtcbiAgICB9XG4gIH1cblxuICB2YXIgdmFscyA9IFsweDAwMDAwMDAwLCAweDAwMDAwMDAwXTtcblxuICBmb3IgKGlpID0gMDsgaWkgPCB0aGlzLk5OICsgMjsgaWkgKz0gMikge1xuICAgIHRoaXMuX2VuY3J5cHRfYmxvY2sodmFscyk7XG4gICAgdGhpcy5wYXJyYXlbaWkgKyAwXSA9IHZhbHNbMF07XG4gICAgdGhpcy5wYXJyYXlbaWkgKyAxXSA9IHZhbHNbMV07XG4gIH1cblxuICBmb3IgKGlpID0gMDsgaWkgPCA0OyArK2lpKSB7XG4gICAgZm9yIChqaiA9IDA7IGpqIDwgMjU2OyBqaiArPSAyKSB7XG4gICAgICB0aGlzLl9lbmNyeXB0X2Jsb2NrKHZhbHMpO1xuICAgICAgdGhpcy5zYm94ZXNbaWldW2pqICsgMF0gPSB2YWxzWzBdO1xuICAgICAgdGhpcy5zYm94ZXNbaWldW2pqICsgMV0gPSB2YWxzWzFdO1xuICAgIH1cbiAgfVxufTtcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbi8vIGFkZGVkIGJ5IFJlY3VyaXR5IExhYnNcblxuZnVuY3Rpb24gQkZlbmNyeXB0KGJsb2NrLCBrZXkpIHtcbiAgdmFyIGJmID0gbmV3IEJsb3dmaXNoKCk7XG4gIGJmLmluaXQodXRpbC5zdHIyYmluKGtleSkpO1xuICByZXR1cm4gYmYuZW5jcnlwdF9ibG9jayhibG9jayk7XG59XG5cbmZ1bmN0aW9uIEJGKGtleSkge1xuICB0aGlzLmJmID0gbmV3IEJsb3dmaXNoKCk7XG4gIHRoaXMuYmYuaW5pdCh1dGlsLnN0cjJiaW4oa2V5KSk7XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYmxvY2spIHtcbiAgICByZXR1cm4gdGhpcy5iZi5lbmNyeXB0X2Jsb2NrKGJsb2NrKTtcbiAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gQkY7XG5tb2R1bGUuZXhwb3J0cy5rZXlTaXplID0gQkYucHJvdG90eXBlLmtleVNpemUgPSAxNjtcbm1vZHVsZS5leHBvcnRzLmJsb2NrU2l6ZSA9IEJGLnByb3RvdHlwZS5ibG9ja1NpemUgPSAxNjtcbiIsIi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlXG4vLyBsaWNlbnNlIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUuXG5cbi8vIENvcHlyaWdodCAyMDEwIHBqYWNvYnNAeGVla3IuY29tIC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cblxuLy8gTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIXG5cbi8vIGZpeGVkL21vZGlmaWVkIGJ5IEhlcmJlcnQgSGFuZXdpbmtlbCwgd3d3LmhhbmVXSU4uZGVcbi8vIGNoZWNrIHd3dy5oYW5lV0lOLmRlIGZvciB0aGUgbGF0ZXN0IHZlcnNpb25cblxuLy8gY2FzdDUuanMgaXMgYSBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIENBU1QtMTI4LCBhcyBkZWZpbmVkIGluIFJGQyAyMTQ0LlxuLy8gQ0FTVC0xMjggaXMgYSBjb21tb24gT3BlblBHUCBjaXBoZXIuXG5cblxuLy8gQ0FTVDUgY29uc3RydWN0b3JcblxuXG5cbmZ1bmN0aW9uIG9wZW5wZ3Bfc3ltZW5jX2Nhc3Q1KCkge1xuICB0aGlzLkJsb2NrU2l6ZSA9IDg7XG4gIHRoaXMuS2V5U2l6ZSA9IDE2O1xuXG4gIHRoaXMuc2V0S2V5ID0gZnVuY3Rpb24oa2V5KSB7XG4gICAgdGhpcy5tYXNraW5nID0gbmV3IEFycmF5KDE2KTtcbiAgICB0aGlzLnJvdGF0ZSA9IG5ldyBBcnJheSgxNik7XG5cbiAgICB0aGlzLnJlc2V0KCk7XG5cbiAgICBpZiAoa2V5Lmxlbmd0aCA9PSB0aGlzLktleVNpemUpIHtcbiAgICAgIHRoaXMua2V5U2NoZWR1bGUoa2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXRpbC5wcmludF9lcnJvcignY2FzdDUuanM6IENBU1QtMTI4OiBrZXlzIG11c3QgYmUgMTYgYnl0ZXMnKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgdGhpcy5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgdGhpcy5tYXNraW5nW2ldID0gMDtcbiAgICAgIHRoaXMucm90YXRlW2ldID0gMDtcbiAgICB9XG4gIH07XG5cbiAgdGhpcy5nZXRCbG9ja1NpemUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gQmxvY2tTaXplO1xuICB9O1xuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKHNyYykge1xuICAgIHZhciBkc3QgPSBuZXcgQXJyYXkoc3JjLmxlbmd0aCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNyYy5sZW5ndGg7IGkgKz0gOCkge1xuICAgICAgdmFyIGwgPSBzcmNbaV0gPDwgMjQgfCBzcmNbaSArIDFdIDw8IDE2IHwgc3JjW2kgKyAyXSA8PCA4IHwgc3JjW2kgKyAzXTtcbiAgICAgIHZhciByID0gc3JjW2kgKyA0XSA8PCAyNCB8IHNyY1tpICsgNV0gPDwgMTYgfCBzcmNbaSArIDZdIDw8IDggfCBzcmNbaSArIDddO1xuICAgICAgdmFyIHQ7XG5cbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbMF0sIHRoaXMucm90YXRlWzBdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1sxXSwgdGhpcy5yb3RhdGVbMV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzJdLCB0aGlzLnJvdGF0ZVsyXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbM10sIHRoaXMucm90YXRlWzNdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzRdLCB0aGlzLnJvdGF0ZVs0XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbNV0sIHRoaXMucm90YXRlWzVdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1s2XSwgdGhpcy5yb3RhdGVbNl0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzddLCB0aGlzLnJvdGF0ZVs3XSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1s4XSwgdGhpcy5yb3RhdGVbOF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzldLCB0aGlzLnJvdGF0ZVs5XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbMTBdLCB0aGlzLnJvdGF0ZVsxMF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzExXSwgdGhpcy5yb3RhdGVbMTFdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzEyXSwgdGhpcy5yb3RhdGVbMTJdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYyKHIsIHRoaXMubWFza2luZ1sxM10sIHRoaXMucm90YXRlWzEzXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbMTRdLCB0aGlzLnJvdGF0ZVsxNF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzE1XSwgdGhpcy5yb3RhdGVbMTVdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICBkc3RbaV0gPSAociA+Pj4gMjQpICYgMjU1O1xuICAgICAgZHN0W2kgKyAxXSA9IChyID4+PiAxNikgJiAyNTU7XG4gICAgICBkc3RbaSArIDJdID0gKHIgPj4+IDgpICYgMjU1O1xuICAgICAgZHN0W2kgKyAzXSA9IHIgJiAyNTU7XG4gICAgICBkc3RbaSArIDRdID0gKGwgPj4+IDI0KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgNV0gPSAobCA+Pj4gMTYpICYgMjU1O1xuICAgICAgZHN0W2kgKyA2XSA9IChsID4+PiA4KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgN10gPSBsICYgMjU1O1xuICAgIH1cblxuICAgIHJldHVybiBkc3Q7XG4gIH07XG5cbiAgdGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24oc3JjKSB7XG4gICAgdmFyIGRzdCA9IG5ldyBBcnJheShzcmMubGVuZ3RoKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3JjLmxlbmd0aDsgaSArPSA4KSB7XG4gICAgICB2YXIgbCA9IHNyY1tpXSA8PCAyNCB8IHNyY1tpICsgMV0gPDwgMTYgfCBzcmNbaSArIDJdIDw8IDggfCBzcmNbaSArIDNdO1xuICAgICAgdmFyIHIgPSBzcmNbaSArIDRdIDw8IDI0IHwgc3JjW2kgKyA1XSA8PCAxNiB8IHNyY1tpICsgNl0gPDwgOCB8IHNyY1tpICsgN107XG4gICAgICB2YXIgdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1sxNV0sIHRoaXMucm90YXRlWzE1XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbMTRdLCB0aGlzLnJvdGF0ZVsxNF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzEzXSwgdGhpcy5yb3RhdGVbMTNdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1sxMl0sIHRoaXMucm90YXRlWzEyXSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1sxMV0sIHRoaXMucm90YXRlWzExXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbMTBdLCB0aGlzLnJvdGF0ZVsxMF0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjEociwgdGhpcy5tYXNraW5nWzldLCB0aGlzLnJvdGF0ZVs5XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMyhyLCB0aGlzLm1hc2tpbmdbOF0sIHRoaXMucm90YXRlWzhdKTtcbiAgICAgIGwgPSB0O1xuXG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzddLCB0aGlzLnJvdGF0ZVs3XSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMShyLCB0aGlzLm1hc2tpbmdbNl0sIHRoaXMucm90YXRlWzZdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYzKHIsIHRoaXMubWFza2luZ1s1XSwgdGhpcy5yb3RhdGVbNV0pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjIociwgdGhpcy5tYXNraW5nWzRdLCB0aGlzLnJvdGF0ZVs0XSk7XG4gICAgICBsID0gdDtcblxuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1szXSwgdGhpcy5yb3RhdGVbM10pO1xuICAgICAgbCA9IHQ7XG4gICAgICB0ID0gcjtcbiAgICAgIHIgPSBsIF4gZjMociwgdGhpcy5tYXNraW5nWzJdLCB0aGlzLnJvdGF0ZVsyXSk7XG4gICAgICBsID0gdDtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IGwgXiBmMihyLCB0aGlzLm1hc2tpbmdbMV0sIHRoaXMucm90YXRlWzFdKTtcbiAgICAgIGwgPSB0O1xuICAgICAgdCA9IHI7XG4gICAgICByID0gbCBeIGYxKHIsIHRoaXMubWFza2luZ1swXSwgdGhpcy5yb3RhdGVbMF0pO1xuICAgICAgbCA9IHQ7XG5cbiAgICAgIGRzdFtpXSA9IChyID4+PiAyNCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDFdID0gKHIgPj4+IDE2KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgMl0gPSAociA+Pj4gOCkgJiAyNTU7XG4gICAgICBkc3RbaSArIDNdID0gciAmIDI1NTtcbiAgICAgIGRzdFtpICsgNF0gPSAobCA+Pj4gMjQpICYgMjU1O1xuICAgICAgZHN0W2kgKyA1XSA9IChsID4+IDE2KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgNl0gPSAobCA+PiA4KSAmIDI1NTtcbiAgICAgIGRzdFtpICsgN10gPSBsICYgMjU1O1xuICAgIH1cblxuICAgIHJldHVybiBkc3Q7XG4gIH07XG4gIHZhciBzY2hlZHVsZUEgPSBuZXcgQXJyYXkoNCk7XG5cbiAgc2NoZWR1bGVBWzBdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUFbMF1bMF0gPSBuZXcgQXJyYXkoNCwgMCwgMHhkLCAweGYsIDB4YywgMHhlLCAweDgpO1xuICBzY2hlZHVsZUFbMF1bMV0gPSBuZXcgQXJyYXkoNSwgMiwgMTYgKyAwLCAxNiArIDIsIDE2ICsgMSwgMTYgKyAzLCAweGEpO1xuICBzY2hlZHVsZUFbMF1bMl0gPSBuZXcgQXJyYXkoNiwgMywgMTYgKyA3LCAxNiArIDYsIDE2ICsgNSwgMTYgKyA0LCA5KTtcbiAgc2NoZWR1bGVBWzBdWzNdID0gbmV3IEFycmF5KDcsIDEsIDE2ICsgMHhhLCAxNiArIDksIDE2ICsgMHhiLCAxNiArIDgsIDB4Yik7XG5cbiAgc2NoZWR1bGVBWzFdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUFbMV1bMF0gPSBuZXcgQXJyYXkoMCwgNiwgMTYgKyA1LCAxNiArIDcsIDE2ICsgNCwgMTYgKyA2LCAxNiArIDApO1xuICBzY2hlZHVsZUFbMV1bMV0gPSBuZXcgQXJyYXkoMSwgNCwgMCwgMiwgMSwgMywgMTYgKyAyKTtcbiAgc2NoZWR1bGVBWzFdWzJdID0gbmV3IEFycmF5KDIsIDUsIDcsIDYsIDUsIDQsIDE2ICsgMSk7XG4gIHNjaGVkdWxlQVsxXVszXSA9IG5ldyBBcnJheSgzLCA3LCAweGEsIDksIDB4YiwgOCwgMTYgKyAzKTtcblxuICBzY2hlZHVsZUFbMl0gPSBuZXcgQXJyYXkoNCk7XG4gIHNjaGVkdWxlQVsyXVswXSA9IG5ldyBBcnJheSg0LCAwLCAweGQsIDB4ZiwgMHhjLCAweGUsIDgpO1xuICBzY2hlZHVsZUFbMl1bMV0gPSBuZXcgQXJyYXkoNSwgMiwgMTYgKyAwLCAxNiArIDIsIDE2ICsgMSwgMTYgKyAzLCAweGEpO1xuICBzY2hlZHVsZUFbMl1bMl0gPSBuZXcgQXJyYXkoNiwgMywgMTYgKyA3LCAxNiArIDYsIDE2ICsgNSwgMTYgKyA0LCA5KTtcbiAgc2NoZWR1bGVBWzJdWzNdID0gbmV3IEFycmF5KDcsIDEsIDE2ICsgMHhhLCAxNiArIDksIDE2ICsgMHhiLCAxNiArIDgsIDB4Yik7XG5cblxuICBzY2hlZHVsZUFbM10gPSBuZXcgQXJyYXkoNCk7XG4gIHNjaGVkdWxlQVszXVswXSA9IG5ldyBBcnJheSgwLCA2LCAxNiArIDUsIDE2ICsgNywgMTYgKyA0LCAxNiArIDYsIDE2ICsgMCk7XG4gIHNjaGVkdWxlQVszXVsxXSA9IG5ldyBBcnJheSgxLCA0LCAwLCAyLCAxLCAzLCAxNiArIDIpO1xuICBzY2hlZHVsZUFbM11bMl0gPSBuZXcgQXJyYXkoMiwgNSwgNywgNiwgNSwgNCwgMTYgKyAxKTtcbiAgc2NoZWR1bGVBWzNdWzNdID0gbmV3IEFycmF5KDMsIDcsIDB4YSwgOSwgMHhiLCA4LCAxNiArIDMpO1xuXG4gIHZhciBzY2hlZHVsZUIgPSBuZXcgQXJyYXkoNCk7XG5cbiAgc2NoZWR1bGVCWzBdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUJbMF1bMF0gPSBuZXcgQXJyYXkoMTYgKyA4LCAxNiArIDksIDE2ICsgNywgMTYgKyA2LCAxNiArIDIpO1xuICBzY2hlZHVsZUJbMF1bMV0gPSBuZXcgQXJyYXkoMTYgKyAweGEsIDE2ICsgMHhiLCAxNiArIDUsIDE2ICsgNCwgMTYgKyA2KTtcbiAgc2NoZWR1bGVCWzBdWzJdID0gbmV3IEFycmF5KDE2ICsgMHhjLCAxNiArIDB4ZCwgMTYgKyAzLCAxNiArIDIsIDE2ICsgOSk7XG4gIHNjaGVkdWxlQlswXVszXSA9IG5ldyBBcnJheSgxNiArIDB4ZSwgMTYgKyAweGYsIDE2ICsgMSwgMTYgKyAwLCAxNiArIDB4Yyk7XG5cbiAgc2NoZWR1bGVCWzFdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUJbMV1bMF0gPSBuZXcgQXJyYXkoMywgMiwgMHhjLCAweGQsIDgpO1xuICBzY2hlZHVsZUJbMV1bMV0gPSBuZXcgQXJyYXkoMSwgMCwgMHhlLCAweGYsIDB4ZCk7XG4gIHNjaGVkdWxlQlsxXVsyXSA9IG5ldyBBcnJheSg3LCA2LCA4LCA5LCAzKTtcbiAgc2NoZWR1bGVCWzFdWzNdID0gbmV3IEFycmF5KDUsIDQsIDB4YSwgMHhiLCA3KTtcblxuXG4gIHNjaGVkdWxlQlsyXSA9IG5ldyBBcnJheSg0KTtcbiAgc2NoZWR1bGVCWzJdWzBdID0gbmV3IEFycmF5KDE2ICsgMywgMTYgKyAyLCAxNiArIDB4YywgMTYgKyAweGQsIDE2ICsgOSk7XG4gIHNjaGVkdWxlQlsyXVsxXSA9IG5ldyBBcnJheSgxNiArIDEsIDE2ICsgMCwgMTYgKyAweGUsIDE2ICsgMHhmLCAxNiArIDB4Yyk7XG4gIHNjaGVkdWxlQlsyXVsyXSA9IG5ldyBBcnJheSgxNiArIDcsIDE2ICsgNiwgMTYgKyA4LCAxNiArIDksIDE2ICsgMik7XG4gIHNjaGVkdWxlQlsyXVszXSA9IG5ldyBBcnJheSgxNiArIDUsIDE2ICsgNCwgMTYgKyAweGEsIDE2ICsgMHhiLCAxNiArIDYpO1xuXG5cbiAgc2NoZWR1bGVCWzNdID0gbmV3IEFycmF5KDQpO1xuICBzY2hlZHVsZUJbM11bMF0gPSBuZXcgQXJyYXkoOCwgOSwgNywgNiwgMyk7XG4gIHNjaGVkdWxlQlszXVsxXSA9IG5ldyBBcnJheSgweGEsIDB4YiwgNSwgNCwgNyk7XG4gIHNjaGVkdWxlQlszXVsyXSA9IG5ldyBBcnJheSgweGMsIDB4ZCwgMywgMiwgOCk7XG4gIHNjaGVkdWxlQlszXVszXSA9IG5ldyBBcnJheSgweGUsIDB4ZiwgMSwgMCwgMHhkKTtcblxuICAvLyBjaGFuZ2VkICdpbicgdG8gJ2lubicgKGluIGphdmFzY3JpcHQgJ2luJyBpcyBhIHJlc2VydmVkIHdvcmQpXG4gIHRoaXMua2V5U2NoZWR1bGUgPSBmdW5jdGlvbihpbm4pIHtcbiAgICB2YXIgdCA9IG5ldyBBcnJheSg4KTtcbiAgICB2YXIgayA9IG5ldyBBcnJheSgzMik7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgdmFyIGogPSBpICogNDtcbiAgICAgIHRbaV0gPSBpbm5bal0gPDwgMjQgfCBpbm5baiArIDFdIDw8IDE2IHwgaW5uW2ogKyAyXSA8PCA4IHwgaW5uW2ogKyAzXTtcbiAgICB9XG5cbiAgICB2YXIgeCA9IFs2LCA3LCA0LCA1XTtcbiAgICB2YXIga2kgPSAwO1xuXG4gICAgZm9yICh2YXIgaGFsZiA9IDA7IGhhbGYgPCAyOyBoYWxmKyspIHtcbiAgICAgIGZvciAodmFyIHJvdW5kID0gMDsgcm91bmQgPCA0OyByb3VuZCsrKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgNDsgaisrKSB7XG4gICAgICAgICAgdmFyIGEgPSBzY2hlZHVsZUFbcm91bmRdW2pdO1xuICAgICAgICAgIHZhciB3ID0gdFthWzFdXTtcblxuICAgICAgICAgIHcgXj0gc0JveFs0XVsodFthWzJdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChhWzJdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHcgXj0gc0JveFs1XVsodFthWzNdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChhWzNdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHcgXj0gc0JveFs2XVsodFthWzRdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChhWzRdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHcgXj0gc0JveFs3XVsodFthWzVdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChhWzVdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHcgXj0gc0JveFt4W2pdXVsodFthWzZdID4+PiAyXSA+Pj4gKDI0IC0gOCAqIChhWzZdICYgMykpKSAmIDB4ZmZdO1xuICAgICAgICAgIHRbYVswXV0gPSB3O1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCA0OyBqKyspIHtcbiAgICAgICAgICB2YXIgYiA9IHNjaGVkdWxlQltyb3VuZF1bal07XG4gICAgICAgICAgdmFyIHcgPSBzQm94WzRdWyh0W2JbMF0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGJbMF0gJiAzKSkpICYgMHhmZl07XG5cbiAgICAgICAgICB3IF49IHNCb3hbNV1bKHRbYlsxXSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYlsxXSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbNl1bKHRbYlsyXSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYlsyXSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbN11bKHRbYlszXSA+Pj4gMl0gPj4+ICgyNCAtIDggKiAoYlszXSAmIDMpKSkgJiAweGZmXTtcbiAgICAgICAgICB3IF49IHNCb3hbNCArIGpdWyh0W2JbNF0gPj4+IDJdID4+PiAoMjQgLSA4ICogKGJbNF0gJiAzKSkpICYgMHhmZl07XG4gICAgICAgICAga1traV0gPSB3O1xuICAgICAgICAgIGtpKys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDE2OyBpKyspIHtcbiAgICAgIHRoaXMubWFza2luZ1tpXSA9IGtbaV07XG4gICAgICB0aGlzLnJvdGF0ZVtpXSA9IGtbMTYgKyBpXSAmIDB4MWY7XG4gICAgfVxuICB9O1xuXG4gIC8vIFRoZXNlIGFyZSB0aGUgdGhyZWUgJ2YnIGZ1bmN0aW9ucy4gU2VlIFJGQyAyMTQ0LCBzZWN0aW9uIDIuMi5cblxuICBmdW5jdGlvbiBmMShkLCBtLCByKSB7XG4gICAgdmFyIHQgPSBtICsgZDtcbiAgICB2YXIgSSA9ICh0IDw8IHIpIHwgKHQgPj4+ICgzMiAtIHIpKTtcbiAgICByZXR1cm4gKChzQm94WzBdW0kgPj4+IDI0XSBeIHNCb3hbMV1bKEkgPj4+IDE2KSAmIDI1NV0pIC0gc0JveFsyXVsoSSA+Pj4gOCkgJiAyNTVdKSArIHNCb3hbM11bSSAmIDI1NV07XG4gIH1cblxuICBmdW5jdGlvbiBmMihkLCBtLCByKSB7XG4gICAgdmFyIHQgPSBtIF4gZDtcbiAgICB2YXIgSSA9ICh0IDw8IHIpIHwgKHQgPj4+ICgzMiAtIHIpKTtcbiAgICByZXR1cm4gKChzQm94WzBdW0kgPj4+IDI0XSAtIHNCb3hbMV1bKEkgPj4+IDE2KSAmIDI1NV0pICsgc0JveFsyXVsoSSA+Pj4gOCkgJiAyNTVdKSBeIHNCb3hbM11bSSAmIDI1NV07XG4gIH1cblxuICBmdW5jdGlvbiBmMyhkLCBtLCByKSB7XG4gICAgdmFyIHQgPSBtIC0gZDtcbiAgICB2YXIgSSA9ICh0IDw8IHIpIHwgKHQgPj4+ICgzMiAtIHIpKTtcbiAgICByZXR1cm4gKChzQm94WzBdW0kgPj4+IDI0XSArIHNCb3hbMV1bKEkgPj4+IDE2KSAmIDI1NV0pIF4gc0JveFsyXVsoSSA+Pj4gOCkgJiAyNTVdKSAtIHNCb3hbM11bSSAmIDI1NV07XG4gIH1cblxuICB2YXIgc0JveCA9IG5ldyBBcnJheSg4KTtcbiAgc0JveFswXSA9IG5ldyBBcnJheShcbiAgICAweDMwZmI0MGQ0LCAweDlmYTBmZjBiLCAweDZiZWNjZDJmLCAweDNmMjU4YzdhLCAweDFlMjEzZjJmLCAweDljMDA0ZGQzLCAweDYwMDNlNTQwLCAweGNmOWZjOTQ5LFxuICAgIDB4YmZkNGFmMjcsIDB4ODhiYmJkYjUsIDB4ZTIwMzQwOTAsIDB4OThkMDk2NzUsIDB4NmU2M2EwZTAsIDB4MTVjMzYxZDIsIDB4YzJlNzY2MWQsIDB4MjJkNGZmOGUsXG4gICAgMHgyODY4M2I2ZiwgMHhjMDdmZDA1OSwgMHhmZjIzNzljOCwgMHg3NzVmNTBlMiwgMHg0M2MzNDBkMywgMHhkZjJmODY1NiwgMHg4ODdjYTQxYSwgMHhhMmQyYmQyZCxcbiAgICAweGExYzllMGQ2LCAweDM0NmM0ODE5LCAweDYxYjc2ZDg3LCAweDIyNTQwZjJmLCAweDJhYmUzMmUxLCAweGFhNTQxNjZiLCAweDIyNTY4ZTNhLCAweGEyZDM0MWQwLFxuICAgIDB4NjZkYjQwYzgsIDB4YTc4NDM5MmYsIDB4MDA0ZGZmMmYsIDB4MmRiOWQyZGUsIDB4OTc5NDNmYWMsIDB4NGE5N2MxZDgsIDB4NTI3NjQ0YjcsIDB4YjVmNDM3YTcsXG4gICAgMHhiODJjYmFlZiwgMHhkNzUxZDE1OSwgMHg2ZmY3ZjBlZCwgMHg1YTA5N2ExZiwgMHg4MjdiNjhkMCwgMHg5MGVjZjUyZSwgMHgyMmIwYzA1NCwgMHhiYzhlNTkzNSxcbiAgICAweDRiNmQyZjdmLCAweDUwYmI2NGEyLCAweGQyNjY0OTEwLCAweGJlZTU4MTJkLCAweGI3MzMyMjkwLCAweGU5M2IxNTlmLCAweGI0OGVlNDExLCAweDRiZmYzNDVkLFxuICAgIDB4ZmQ0NWMyNDAsIDB4YWQzMTk3M2YsIDB4YzRmNmQwMmUsIDB4NTVmYzgxNjUsIDB4ZDViMWNhYWQsIDB4YTFhYzJkYWUsIDB4YTJkNGI3NmQsIDB4YzE5YjBjNTAsXG4gICAgMHg4ODIyNDBmMiwgMHgwYzZlNGYzOCwgMHhhNGU0YmZkNywgMHg0ZjViYTI3MiwgMHg1NjRjMWQyZiwgMHhjNTljNTMxOSwgMHhiOTQ5ZTM1NCwgMHhiMDQ2NjlmZSxcbiAgICAweGIxYjZhYjhhLCAweGM3MTM1OGRkLCAweDYzODVjNTQ1LCAweDExMGY5MzVkLCAweDU3NTM4YWQ1LCAweDZhMzkwNDkzLCAweGU2M2QzN2UwLCAweDJhNTRmNmIzLFxuICAgIDB4M2E3ODdkNWYsIDB4NjI3NmEwYjUsIDB4MTlhNmZjZGYsIDB4N2E0MjIwNmEsIDB4MjlmOWQ0ZDUsIDB4ZjYxYjE4OTEsIDB4YmI3MjI3NWUsIDB4YWE1MDgxNjcsXG4gICAgMHgzODkwMTA5MSwgMHhjNmI1MDVlYiwgMHg4NGM3Y2I4YywgMHgyYWQ3NWEwZiwgMHg4NzRhMTQyNywgMHhhMmQxOTM2YiwgMHgyYWQyODZhZiwgMHhhYTU2ZDI5MSxcbiAgICAweGQ3ODk0MzYwLCAweDQyNWM3NTBkLCAweDkzYjM5ZTI2LCAweDE4NzE4NGM5LCAweDZjMDBiMzJkLCAweDczZTJiYjE0LCAweGEwYmViYzNjLCAweDU0NjIzNzc5LFxuICAgIDB4NjQ0NTllYWIsIDB4M2YzMjhiODIsIDB4NzcxOGNmODIsIDB4NTlhMmNlYTYsIDB4MDRlZTAwMmUsIDB4ODlmZTc4ZTYsIDB4M2ZhYjA5NTAsIDB4MzI1ZmY2YzIsXG4gICAgMHg4MTM4M2YwNSwgMHg2OTYzYzVjOCwgMHg3NmNiNWFkNiwgMHhkNDk5NzRjOSwgMHhjYTE4MGRjZiwgMHgzODA3ODJkNSwgMHhjN2ZhNWNmNiwgMHg4YWMzMTUxMSxcbiAgICAweDM1ZTc5ZTEzLCAweDQ3ZGE5MWQwLCAweGY0MGY5MDg2LCAweGE3ZTI0MTllLCAweDMxMzY2MjQxLCAweDA1MWVmNDk1LCAweGFhNTczYjA0LCAweDRhODA1ZDhkLFxuICAgIDB4NTQ4MzAwZDAsIDB4MDAzMjJhM2MsIDB4YmY2NGNkZGYsIDB4YmE1N2E2OGUsIDB4NzVjNjM3MmIsIDB4NTBhZmQzNDEsIDB4YTdjMTMyNzUsIDB4OTE1YTBiZjUsXG4gICAgMHg2YjU0YmZhYiwgMHgyYjBiMTQyNiwgMHhhYjRjYzlkNywgMHg0NDljY2Q4MiwgMHhmN2ZiZjI2NSwgMHhhYjg1YzVmMywgMHgxYjU1ZGI5NCwgMHhhYWQ0ZTMyNCxcbiAgICAweGNmYTRiZDNmLCAweDJkZWFhM2UyLCAweDllMjA0ZDAyLCAweGM4YmQyNWFjLCAweGVhZGY1NWIzLCAweGQ1YmQ5ZTk4LCAweGUzMTIzMWIyLCAweDJhZDVhZDZjLFxuICAgIDB4OTU0MzI5ZGUsIDB4YWRiZTQ1MjgsIDB4ZDg3MTBmNjksIDB4YWE1MWM5MGYsIDB4YWE3ODZiZjYsIDB4MjI1MTNmMWUsIDB4YWE1MWE3OWIsIDB4MmFkMzQ0Y2MsXG4gICAgMHg3YjVhNDFmMCwgMHhkMzdjZmJhZCwgMHgxYjA2OTUwNSwgMHg0MWVjZTQ5MSwgMHhiNGMzMzJlNiwgMHgwMzIyNjhkNCwgMHhjOTYwMGFjYywgMHhjZTM4N2U2ZCxcbiAgICAweGJmNmJiMTZjLCAweDZhNzBmYjc4LCAweDBkMDNkOWM5LCAweGQ0ZGYzOWRlLCAweGUwMTA2M2RhLCAweDQ3MzZmNDY0LCAweDVhZDMyOGQ4LCAweGIzNDdjYzk2LFxuICAgIDB4NzViYjBmYzMsIDB4OTg1MTFiZmIsIDB4NGZmYmNjMzUsIDB4YjU4YmNmNmEsIDB4ZTExZjBhYmMsIDB4YmZjNWZlNGEsIDB4YTcwYWVjMTAsIDB4YWMzOTU3MGEsXG4gICAgMHgzZjA0NDQyZiwgMHg2MTg4YjE1MywgMHhlMDM5N2EyZSwgMHg1NzI3Y2I3OSwgMHg5Y2ViNDE4ZiwgMHgxY2FjZDY4ZCwgMHgyYWQzN2M5NiwgMHgwMTc1Y2I5ZCxcbiAgICAweGM2OWRmZjA5LCAweGM3NWI2NWYwLCAweGQ5ZGI0MGQ4LCAweGVjMGU3Nzc5LCAweDQ3NDRlYWQ0LCAweGIxMWMzMjc0LCAweGRkMjRjYjllLCAweDdlMWM1NGJkLFxuICAgIDB4ZjAxMTQ0ZjksIDB4ZDIyNDBlYjEsIDB4OTY3NWIzZmQsIDB4YTNhYzM3NTUsIDB4ZDQ3YzI3YWYsIDB4NTFjODVmNGQsIDB4NTY5MDc1OTYsIDB4YTViYjE1ZTYsXG4gICAgMHg1ODAzMDRmMCwgMHhjYTA0MmNmMSwgMHgwMTFhMzdlYSwgMHg4ZGJmYWFkYiwgMHgzNWJhM2U0YSwgMHgzNTI2ZmZhMCwgMHhjMzdiNGQwOSwgMHhiYzMwNmVkOSxcbiAgICAweDk4YTUyNjY2LCAweDU2NDhmNzI1LCAweGZmNWU1NjlkLCAweDBjZWQ2M2QwLCAweDdjNjNiMmNmLCAweDcwMGI0NWUxLCAweGQ1ZWE1MGYxLCAweDg1YTkyODcyLFxuICAgIDB4YWYxZmJkYTcsIDB4ZDQyMzQ4NzAsIDB4YTc4NzBiZjMsIDB4MmQzYjRkNzksIDB4NDJlMDQxOTgsIDB4MGNkMGVkZTcsIDB4MjY0NzBkYjgsIDB4Zjg4MTgxNGMsXG4gICAgMHg0NzRkNmFkNywgMHg3YzBjNWU1YywgMHhkMTIzMTk1OSwgMHgzODFiNzI5OCwgMHhmNWQyZjRkYiwgMHhhYjgzODY1MywgMHg2ZTJmMWUyMywgMHg4MzcxOWM5ZSxcbiAgICAweGJkOTFlMDQ2LCAweDlhNTY0NTZlLCAweGRjMzkyMDBjLCAweDIwYzhjNTcxLCAweDk2MmJkYTFjLCAweGUxZTY5NmZmLCAweGIxNDFhYjA4LCAweDdjY2E4OWI5LFxuICAgIDB4MWE2OWU3ODMsIDB4MDJjYzQ4NDMsIDB4YTJmN2M1NzksIDB4NDI5ZWY0N2QsIDB4NDI3YjE2OWMsIDB4NWFjOWYwNDksIDB4ZGQ4ZjBmMDAsIDB4NWM4MTY1YmYpO1xuXG4gIHNCb3hbMV0gPSBuZXcgQXJyYXkoXG4gICAgMHgxZjIwMTA5NCwgMHhlZjBiYTc1YiwgMHg2OWUzY2Y3ZSwgMHgzOTNmNDM4MCwgMHhmZTYxY2Y3YSwgMHhlZWM1MjA3YSwgMHg1NTg4OWM5NCwgMHg3MmZjMDY1MSxcbiAgICAweGFkYTdlZjc5LCAweDRlMWQ3MjM1LCAweGQ1NWE2M2NlLCAweGRlMDQzNmJhLCAweDk5YzQzMGVmLCAweDVmMGMwNzk0LCAweDE4ZGNkYjdkLCAweGExZDZlZmYzLFxuICAgIDB4YTBiNTJmN2IsIDB4NTllODM2MDUsIDB4ZWUxNWIwOTQsIDB4ZTlmZmQ5MDksIDB4ZGM0NDAwODYsIDB4ZWY5NDQ0NTksIDB4YmE4M2NjYjMsIDB4ZTBjM2NkZmIsXG4gICAgMHhkMWRhNDE4MSwgMHgzYjA5MmFiMSwgMHhmOTk3ZjFjMSwgMHhhNWU2Y2Y3YiwgMHgwMTQyMGRkYiwgMHhlNGU3ZWY1YiwgMHgyNWExZmY0MSwgMHhlMTgwZjgwNixcbiAgICAweDFmYzQxMDgwLCAweDE3OWJlZTdhLCAweGQzN2FjNmE5LCAweGZlNTgzMGE0LCAweDk4ZGU4YjdmLCAweDc3ZTgzZjRlLCAweDc5OTI5MjY5LCAweDI0ZmE5ZjdiLFxuICAgIDB4ZTExM2M4NWIsIDB4YWNjNDAwODMsIDB4ZDc1MDM1MjUsIDB4ZjdlYTYxNWYsIDB4NjIxNDMxNTQsIDB4MGQ1NTRiNjMsIDB4NWQ2ODExMjEsIDB4Yzg2NmMzNTksXG4gICAgMHgzZDYzY2Y3MywgMHhjZWUyMzRjMCwgMHhkNGQ4N2U4NywgMHg1YzY3MmIyMSwgMHgwNzFmNjE4MSwgMHgzOWY3NjI3ZiwgMHgzNjFlMzA4NCwgMHhlNGViNTczYixcbiAgICAweDYwMmY2NGE0LCAweGQ2M2FjZDljLCAweDFiYmM0NjM1LCAweDllODEwMzJkLCAweDI3MDFmNTBjLCAweDk5ODQ3YWI0LCAweGEwZTNkZjc5LCAweGJhNmNmMzhjLFxuICAgIDB4MTA4NDMwOTQsIDB4MjUzN2E5NWUsIDB4ZjQ2ZjZmZmUsIDB4YTFmZjNiMWYsIDB4MjA4Y2ZiNmEsIDB4OGY0NThjNzQsIDB4ZDllMGEyMjcsIDB4NGVjNzNhMzQsXG4gICAgMHhmYzg4NGY2OSwgMHgzZTRkZThkZiwgMHhlZjBlMDA4OCwgMHgzNTU5NjQ4ZCwgMHg4YTQ1Mzg4YywgMHgxZDgwNDM2NiwgMHg3MjFkOWJmZCwgMHhhNTg2ODRiYixcbiAgICAweGU4MjU2MzMzLCAweDg0NGU4MjEyLCAweDEyOGQ4MDk4LCAweGZlZDMzZmI0LCAweGNlMjgwYWUxLCAweDI3ZTE5YmE1LCAweGQ1YTZjMjUyLCAweGU0OTc1NGJkLFxuICAgIDB4YzVkNjU1ZGQsIDB4ZWI2NjcwNjQsIDB4Nzc4NDBiNGQsIDB4YTFiNmE4MDEsIDB4ODRkYjI2YTksIDB4ZTBiNTY3MTQsIDB4MjFmMDQzYjcsIDB4ZTVkMDU4NjAsXG4gICAgMHg1NGYwMzA4NCwgMHgwNjZmZjQ3MiwgMHhhMzFhYTE1MywgMHhkYWRjNDc1NSwgMHhiNTYyNWRiZiwgMHg2ODU2MWJlNiwgMHg4M2NhNmI5NCwgMHgyZDZlZDIzYixcbiAgICAweGVjY2YwMWRiLCAweGE2ZDNkMGJhLCAweGI2ODAzZDVjLCAweGFmNzdhNzA5LCAweDMzYjRhMzRjLCAweDM5N2JjOGQ2LCAweDVlZTIyYjk1LCAweDVmMGU1MzA0LFxuICAgIDB4ODFlZDZmNjEsIDB4MjBlNzQzNjQsIDB4YjQ1ZTEzNzgsIDB4ZGUxODYzOWIsIDB4ODgxY2ExMjIsIDB4Yjk2NzI2ZDEsIDB4ODA0OWE3ZTgsIDB4MjJiN2RhN2IsXG4gICAgMHg1ZTU1MmQyNSwgMHg1MjcyZDIzNywgMHg3OWQyOTUxYywgMHhjNjBkODk0YywgMHg0ODhjYjQwMiwgMHgxYmE0ZmU1YiwgMHhhNGIwOWY2YiwgMHgxY2E4MTVjZixcbiAgICAweGEyMGMzMDA1LCAweDg4NzFkZjYzLCAweGI5ZGUyZmNiLCAweDBjYzZjOWU5LCAweDBiZWVmZjUzLCAweGUzMjE0NTE3LCAweGI0NTQyODM1LCAweDlmNjMyOTNjLFxuICAgIDB4ZWU0MWU3MjksIDB4NmUxZDJkN2MsIDB4NTAwNDUyODYsIDB4MWU2Njg1ZjMsIDB4ZjMzNDAxYzYsIDB4MzBhMjJjOTUsIDB4MzFhNzA4NTAsIDB4NjA5MzBmMTMsXG4gICAgMHg3M2Y5ODQxNywgMHhhMTI2OTg1OSwgMHhlYzY0NWM0NCwgMHg1MmM4NzdhOSwgMHhjZGZmMzNhNiwgMHhhMDJiMTc0MSwgMHg3Y2JhZDlhMiwgMHgyMTgwMDM2ZixcbiAgICAweDUwZDk5YzA4LCAweGNiM2Y0ODYxLCAweGMyNmJkNzY1LCAweDY0YTNmNmFiLCAweDgwMzQyNjc2LCAweDI1YTc1ZTdiLCAweGU0ZTZkMWZjLCAweDIwYzcxMGU2LFxuICAgIDB4Y2RmMGI2ODAsIDB4MTc4NDRkM2IsIDB4MzFlZWY4NGQsIDB4N2UwODI0ZTQsIDB4MmNjYjQ5ZWIsIDB4ODQ2YTNiYWUsIDB4OGZmNzc4ODgsIDB4ZWU1ZDYwZjYsXG4gICAgMHg3YWY3NTY3MywgMHgyZmRkNWNkYiwgMHhhMTE2MzFjMSwgMHgzMGY2NmY0MywgMHhiM2ZhZWM1NCwgMHgxNTdmZDdmYSwgMHhlZjg1NzljYywgMHhkMTUyZGU1OCxcbiAgICAweGRiMmZmZDVlLCAweDhmMzJjZTE5LCAweDMwNmFmOTdhLCAweDAyZjAzZWY4LCAweDk5MzE5YWQ1LCAweGMyNDJmYTBmLCAweGE3ZTNlYmIwLCAweGM2OGU0OTA2LFxuICAgIDB4YjhkYTIzMGMsIDB4ODA4MjMwMjgsIDB4ZGNkZWYzYzgsIDB4ZDM1ZmIxNzEsIDB4MDg4YTFiYzgsIDB4YmVjMGM1NjAsIDB4NjFhM2M5ZTgsIDB4YmNhOGY1NGQsXG4gICAgMHhjNzJmZWZmYSwgMHgyMjgyMmU5OSwgMHg4MmM1NzBiNCwgMHhkOGQ5NGU4OSwgMHg4YjFjMzRiYywgMHgzMDFlMTZlNiwgMHgyNzNiZTk3OSwgMHhiMGZmZWFhNixcbiAgICAweDYxZDliOGM2LCAweDAwYjI0ODY5LCAweGI3ZmZjZTNmLCAweDA4ZGMyODNiLCAweDQzZGFmNjVhLCAweGY3ZTE5Nzk4LCAweDc2MTliNzJmLCAweDhmMWM5YmE0LFxuICAgIDB4ZGM4NjM3YTAsIDB4MTZhN2QzYjEsIDB4OWZjMzkzYjcsIDB4YTcxMzZlZWIsIDB4YzZiY2M2M2UsIDB4MWE1MTM3NDIsIDB4ZWY2ODI4YmMsIDB4NTIwMzY1ZDYsXG4gICAgMHgyZDZhNzdhYiwgMHgzNTI3ZWQ0YiwgMHg4MjFmZDIxNiwgMHgwOTVjNmUyZSwgMHhkYjkyZjJmYiwgMHg1ZWVhMjljYiwgMHgxNDU4OTJmNSwgMHg5MTU4NGY3ZixcbiAgICAweDU0ODM2OTdiLCAweDI2NjdhOGNjLCAweDg1MTk2MDQ4LCAweDhjNGJhY2VhLCAweDgzMzg2MGQ0LCAweDBkMjNlMGY5LCAweDZjMzg3ZThhLCAweDBhZTZkMjQ5LFxuICAgIDB4YjI4NDYwMGMsIDB4ZDgzNTczMWQsIDB4ZGNiMWM2NDcsIDB4YWM0YzU2ZWEsIDB4M2ViZDgxYjMsIDB4MjMwZWFiYjAsIDB4NjQzOGJjODcsIDB4ZjBiNWIxZmEsXG4gICAgMHg4ZjVlYTJiMywgMHhmYzE4NDY0MiwgMHgwYTAzNmI3YSwgMHg0ZmIwODliZCwgMHg2NDlkYTU4OSwgMHhhMzQ1NDE1ZSwgMHg1YzAzODMyMywgMHgzZTVkM2JiOSxcbiAgICAweDQzZDc5NTcyLCAweDdlNmRkMDdjLCAweDA2ZGZkZjFlLCAweDZjNmNjNGVmLCAweDcxNjBhNTM5LCAweDczYmZiZTcwLCAweDgzODc3NjA1LCAweDQ1MjNlY2YxKTtcblxuICBzQm94WzJdID0gbmV3IEFycmF5KFxuICAgIDB4OGRlZmMyNDAsIDB4MjVmYTVkOWYsIDB4ZWI5MDNkYmYsIDB4ZTgxMGM5MDcsIDB4NDc2MDdmZmYsIDB4MzY5ZmU0NGIsIDB4OGMxZmM2NDQsIDB4YWVjZWNhOTAsXG4gICAgMHhiZWIxZjliZiwgMHhlZWZiY2FlYSwgMHhlOGNmMTk1MCwgMHg1MWRmMDdhZSwgMHg5MjBlODgwNiwgMHhmMGFkMDU0OCwgMHhlMTNjOGQ4MywgMHg5MjcwMTBkNSxcbiAgICAweDExMTA3ZDlmLCAweDA3NjQ3ZGI5LCAweGIyZTNlNGQ0LCAweDNkNGYyODVlLCAweGI5YWZhODIwLCAweGZhZGU4MmUwLCAweGEwNjcyNjhiLCAweDgyNzI3OTJlLFxuICAgIDB4NTUzZmIyYzAsIDB4NDg5YWUyMmIsIDB4ZDRlZjk3OTQsIDB4MTI1ZTNmYmMsIDB4MjFmZmZjZWUsIDB4ODI1YjFiZmQsIDB4OTI1NWM1ZWQsIDB4MTI1N2EyNDAsXG4gICAgMHg0ZTFhODMwMiwgMHhiYWUwN2ZmZiwgMHg1MjgyNDZlNywgMHg4ZTU3MTQwZSwgMHgzMzczZjdiZiwgMHg4YzlmODE4OCwgMHhhNmZjNGVlOCwgMHhjOTgyYjVhNSxcbiAgICAweGE4YzAxZGI3LCAweDU3OWZjMjY0LCAweDY3MDk0ZjMxLCAweGYyYmQzZjVmLCAweDQwZmZmN2MxLCAweDFmYjc4ZGZjLCAweDhlNmJkMmMxLCAweDQzN2JlNTliLFxuICAgIDB4OTliMDNkYmYsIDB4YjVkYmM2NGIsIDB4NjM4ZGMwZTYsIDB4NTU4MTlkOTksIDB4YTE5N2M4MWMsIDB4NGEwMTJkNmUsIDB4YzU4ODRhMjgsIDB4Y2NjMzZmNzEsXG4gICAgMHhiODQzYzIxMywgMHg2YzA3NDNmMSwgMHg4MzA5ODkzYywgMHgwZmVkZGQ1ZiwgMHgyZjdmZTg1MCwgMHhkN2MwN2Y3ZSwgMHgwMjUwN2ZiZiwgMHg1YWZiOWEwNCxcbiAgICAweGE3NDdkMmQwLCAweDE2NTExOTJlLCAweGFmNzBiZjNlLCAweDU4YzMxMzgwLCAweDVmOTgzMDJlLCAweDcyN2NjM2M0LCAweDBhMGZiNDAyLCAweDBmN2ZlZjgyLFxuICAgIDB4OGM5NmZkYWQsIDB4NWQyYzJhYWUsIDB4OGVlOTlhNDksIDB4NTBkYTg4YjgsIDB4ODQyN2Y0YTAsIDB4MWVhYzU3OTAsIDB4Nzk2ZmI0NDksIDB4ODI1MmRjMTUsXG4gICAgMHhlZmJkN2Q5YiwgMHhhNjcyNTk3ZCwgMHhhZGE4NDBkOCwgMHg0NWY1NDUwNCwgMHhmYTVkNzQwMywgMHhlODNlYzMwNSwgMHg0ZjkxNzUxYSwgMHg5MjU2NjljMixcbiAgICAweDIzZWZlOTQxLCAweGE5MDNmMTJlLCAweDYwMjcwZGYyLCAweDAyNzZlNGI2LCAweDk0ZmQ2NTc0LCAweDkyNzk4NWIyLCAweDgyNzZkYmNiLCAweDAyNzc4MTc2LFxuICAgIDB4ZjhhZjkxOGQsIDB4NGU0OGY3OWUsIDB4OGY2MTZkZGYsIDB4ZTI5ZDg0MGUsIDB4ODQyZjdkODMsIDB4MzQwY2U1YzgsIDB4OTZiYmI2ODIsIDB4OTNiNGIxNDgsXG4gICAgMHhlZjMwM2NhYiwgMHg5ODRmYWYyOCwgMHg3NzlmYWY5YiwgMHg5MmRjNTYwZCwgMHgyMjRkMWUyMCwgMHg4NDM3YWE4OCwgMHg3ZDI5ZGM5NiwgMHgyNzU2ZDNkYyxcbiAgICAweDhiOTA3Y2VlLCAweGI1MWZkMjQwLCAweGU3YzA3Y2UzLCAweGU1NjZiNGExLCAweGMzZTk2MTVlLCAweDNjZjgyMDlkLCAweDYwOTRkMWUzLCAweGNkOWNhMzQxLFxuICAgIDB4NWM3NjQ2MGUsIDB4MDBlYTk4M2IsIDB4ZDRkNjc4ODEsIDB4ZmQ0NzU3MmMsIDB4Zjc2Y2VkZDksIDB4YmRhODIyOWMsIDB4MTI3ZGFkYWEsIDB4NDM4YTA3NGUsXG4gICAgMHgxZjk3YzA5MCwgMHgwODFiZGI4YSwgMHg5M2EwN2ViZSwgMHhiOTM4Y2ExNSwgMHg5N2IwM2NmZiwgMHgzZGMyYzBmOCwgMHg4ZDFhYjJlYywgMHg2NDM4MGU1MSxcbiAgICAweDY4Y2M3YmZiLCAweGQ5MGYyNzg4LCAweDEyNDkwMTgxLCAweDVkZTVmZmQ0LCAweGRkN2VmODZhLCAweDc2YTJlMjE0LCAweGI5YTQwMzY4LCAweDkyNWQ5NThmLFxuICAgIDB4NGIzOWZmZmEsIDB4YmEzOWFlZTksIDB4YTRmZmQzMGIsIDB4ZmFmNzkzM2IsIDB4NmQ0OTg2MjMsIDB4MTkzY2JjZmEsIDB4Mjc2Mjc1NDUsIDB4ODI1Y2Y0N2EsXG4gICAgMHg2MWJkOGJhMCwgMHhkMTFlNDJkMSwgMHhjZWFkMDRmNCwgMHgxMjdlYTM5MiwgMHgxMDQyOGRiNywgMHg4MjcyYTk3MiwgMHg5MjcwYzRhOCwgMHgxMjdkZTUwYixcbiAgICAweDI4NWJhMWM4LCAweDNjNjJmNDRmLCAweDM1YzBlYWE1LCAweGU4MDVkMjMxLCAweDQyODkyOWZiLCAweGI0ZmNkZjgyLCAweDRmYjY2YTUzLCAweDBlN2RjMTViLFxuICAgIDB4MWYwODFmYWIsIDB4MTA4NjE4YWUsIDB4ZmNmZDA4NmQsIDB4ZjlmZjI4ODksIDB4Njk0YmNjMTEsIDB4MjM2YTVjYWUsIDB4MTJkZWNhNGQsIDB4MmMzZjhjYzUsXG4gICAgMHhkMmQwMmRmZSwgMHhmOGVmNTg5NiwgMHhlNGNmNTJkYSwgMHg5NTE1NWI2NywgMHg0OTRhNDg4YywgMHhiOWI2YTgwYywgMHg1YzhmODJiYywgMHg4OWQzNmI0NSxcbiAgICAweDNhNjA5NDM3LCAweGVjMDBjOWE5LCAweDQ0NzE1MjUzLCAweDBhODc0YjQ5LCAweGQ3NzNiYzQwLCAweDdjMzQ2NzFjLCAweDAyNzE3ZWY2LCAweDRmZWI1NTM2LFxuICAgIDB4YTJkMDJmZmYsIDB4ZDJiZjYwYzQsIDB4ZDQzZjAzYzAsIDB4NTBiNGVmNmQsIDB4MDc0NzhjZDEsIDB4MDA2ZTE4ODgsIDB4YTJlNTNmNTUsIDB4YjllNmQ0YmMsXG4gICAgMHhhMjA0ODAxNiwgMHg5NzU3MzgzMywgMHhkNzIwN2Q2NywgMHhkZTBmOGYzZCwgMHg3MmY4N2IzMywgMHhhYmNjNGYzMywgMHg3Njg4YzU1ZCwgMHg3YjAwYTZiMCxcbiAgICAweDk0N2IwMDAxLCAweDU3MDA3NWQyLCAweGY5YmI4OGY4LCAweDg5NDIwMTllLCAweDQyNjRhNWZmLCAweDg1NjMwMmUwLCAweDcyZGJkOTJiLCAweGVlOTcxYjY5LFxuICAgIDB4NmVhMjJmZGUsIDB4NWYwOGFlMmIsIDB4YWY3YTYxNmQsIDB4ZTVjOTg3NjcsIDB4Y2YxZmViZDIsIDB4NjFlZmM4YzIsIDB4ZjFhYzI1NzEsIDB4Y2M4MjM5YzIsXG4gICAgMHg2NzIxNGNiOCwgMHhiMWU1ODNkMSwgMHhiN2RjM2U2MiwgMHg3ZjEwYmRjZSwgMHhmOTBhNWMzOCwgMHgwZmYwNDQzZCwgMHg2MDZlNmRjNiwgMHg2MDU0M2E0OSxcbiAgICAweDU3MjdjMTQ4LCAweDJiZTk4YTFkLCAweDhhYjQxNzM4LCAweDIwZTFiZTI0LCAweGFmOTZkYTBmLCAweDY4NDU4NDI1LCAweDk5ODMzYmU1LCAweDYwMGQ0NTdkLFxuICAgIDB4MjgyZjkzNTAsIDB4ODMzNGIzNjIsIDB4ZDkxZDExMjAsIDB4MmI2ZDhkYTAsIDB4NjQyYjFlMzEsIDB4OWMzMDVhMDAsIDB4NTJiY2U2ODgsIDB4MWIwMzU4OGEsXG4gICAgMHhmN2JhZWZkNSwgMHg0MTQyZWQ5YywgMHhhNDMxNWMxMSwgMHg4MzMyM2VjNSwgMHhkZmVmNDYzNiwgMHhhMTMzYzUwMSwgMHhlOWQzNTMxYywgMHhlZTM1Mzc4Myk7XG5cbiAgc0JveFszXSA9IG5ldyBBcnJheShcbiAgICAweDlkYjMwNDIwLCAweDFmYjZlOWRlLCAweGE3YmU3YmVmLCAweGQyNzNhMjk4LCAweDRhNGY3YmRiLCAweDY0YWQ4YzU3LCAweDg1NTEwNDQzLCAweGZhMDIwZWQxLFxuICAgIDB4N2UyODdhZmYsIDB4ZTYwZmI2NjMsIDB4MDk1ZjM1YTEsIDB4NzllYmYxMjAsIDB4ZmQwNTlkNDMsIDB4NjQ5N2I3YjEsIDB4ZjM2NDFmNjMsIDB4MjQxZTRhZGYsXG4gICAgMHgyODE0N2Y1ZiwgMHg0ZmEyYjhjZCwgMHhjOTQzMDA0MCwgMHgwY2MzMjIyMCwgMHhmZGQzMGIzMCwgMHhjMGE1Mzc0ZiwgMHgxZDJkMDBkOSwgMHgyNDE0N2IxNSxcbiAgICAweGVlNGQxMTFhLCAweDBmY2E1MTY3LCAweDcxZmY5MDRjLCAweDJkMTk1ZmZlLCAweDFhMDU2NDVmLCAweDBjMTNmZWZlLCAweDA4MWIwOGNhLCAweDA1MTcwMTIxLFxuICAgIDB4ODA1MzAxMDAsIDB4ZTgzZTVlZmUsIDB4YWM5YWY0ZjgsIDB4N2ZlNzI3MDEsIDB4ZDJiOGVlNWYsIDB4MDZkZjQyNjEsIDB4YmI5ZTliOGEsIDB4NzI5M2VhMjUsXG4gICAgMHhjZTg0ZmZkZiwgMHhmNTcxODgwMSwgMHgzZGQ2NGIwNCwgMHhhMjZmMjYzYiwgMHg3ZWQ0ODQwMCwgMHg1NDdlZWJlNiwgMHg0NDZkNGNhMCwgMHg2Y2YzZDZmNSxcbiAgICAweDI2NDlhYmRmLCAweGFlYTBjN2Y1LCAweDM2MzM4Y2MxLCAweDUwM2Y3ZTkzLCAweGQzNzcyMDYxLCAweDExYjYzOGUxLCAweDcyNTAwZTAzLCAweGY4MGViMmJiLFxuICAgIDB4YWJlMDUwMmUsIDB4ZWM4ZDc3ZGUsIDB4NTc5NzFlODEsIDB4ZTE0ZjY3NDYsIDB4YzkzMzU0MDAsIDB4NjkyMDMxOGYsIDB4MDgxZGJiOTksIDB4ZmZjMzA0YTUsXG4gICAgMHg0ZDM1MTgwNSwgMHg3ZjNkNWNlMywgMHhhNmM4NjZjNiwgMHg1ZDViY2NhOSwgMHhkYWVjNmZlYSwgMHg5ZjkyNmY5MSwgMHg5ZjQ2MjIyZiwgMHgzOTkxNDY3ZCxcbiAgICAweGE1YmY2ZDhlLCAweDExNDNjNDRmLCAweDQzOTU4MzAyLCAweGQwMjE0ZWViLCAweDAyMjA4M2I4LCAweDNmYjYxODBjLCAweDE4Zjg5MzFlLCAweDI4MTY1OGU2LFxuICAgIDB4MjY0ODZlM2UsIDB4OGJkNzhhNzAsIDB4NzQ3N2U0YzEsIDB4YjUwNmUwN2MsIDB4ZjMyZDBhMjUsIDB4NzkwOThiMDIsIDB4ZTRlYWJiODEsIDB4MjgxMjNiMjMsXG4gICAgMHg2OWRlYWQzOCwgMHgxNTc0Y2ExNiwgMHhkZjg3MWI2MiwgMHgyMTFjNDBiNywgMHhhNTFhOWVmOSwgMHgwMDE0Mzc3YiwgMHgwNDFlOGFjOCwgMHgwOTExNDAwMyxcbiAgICAweGJkNTllNGQyLCAweGUzZDE1NmQ1LCAweDRmZTg3NmQ1LCAweDJmOTFhMzQwLCAweDU1N2JlOGRlLCAweDAwZWFlNGE3LCAweDBjZTVjMmVjLCAweDRkYjRiYmE2LFxuICAgIDB4ZTc1NmJkZmYsIDB4ZGQzMzY5YWMsIDB4ZWMxN2IwMzUsIDB4MDY1NzIzMjcsIDB4OTlhZmM4YjAsIDB4NTZjOGMzOTEsIDB4NmI2NTgxMWMsIDB4NWUxNDYxMTksXG4gICAgMHg2ZTg1Y2I3NSwgMHhiZTA3YzAwMiwgMHhjMjMyNTU3NywgMHg4OTNmZjRlYywgMHg1YmJmYzkyZCwgMHhkMGVjM2IyNSwgMHhiNzgwMWFiNywgMHg4ZDZkM2IyNCxcbiAgICAweDIwYzc2M2VmLCAweGMzNjZhNWZjLCAweDljMzgyODgwLCAweDBhY2UzMjA1LCAweGFhYzk1NDhhLCAweGVjYTFkN2M3LCAweDA0MWFmYTMyLCAweDFkMTY2MjVhLFxuICAgIDB4NjcwMTkwMmMsIDB4OWI3NTdhNTQsIDB4MzFkNDc3ZjcsIDB4OTEyNmIwMzEsIDB4MzZjYzZmZGIsIDB4YzcwYjhiNDYsIDB4ZDllNjZhNDgsIDB4NTZlNTVhNzksXG4gICAgMHgwMjZhNGNlYiwgMHg1MjQzN2VmZiwgMHgyZjhmNzZiNCwgMHgwZGY5ODBhNSwgMHg4Njc0Y2RlMywgMHhlZGRhMDRlYiwgMHgxN2E5YmUwNCwgMHgyYzE4ZjRkZixcbiAgICAweGI3NzQ3ZjlkLCAweGFiMmFmN2I0LCAweGVmYzM0ZDIwLCAweDJlMDk2YjdjLCAweDE3NDFhMjU0LCAweGU1YjZhMDM1LCAweDIxM2Q0MmY2LCAweDJjMWM3YzI2LFxuICAgIDB4NjFjMmY1MGYsIDB4NjU1MmRhZjksIDB4ZDJjMjMxZjgsIDB4MjUxMzBmNjksIDB4ZDgxNjdmYTIsIDB4MDQxOGYyYzgsIDB4MDAxYTk2YTYsIDB4MGQxNTI2YWIsXG4gICAgMHg2MzMxNWMyMSwgMHg1ZTBhNzJlYywgMHg0OWJhZmVmZCwgMHgxODc5MDhkOSwgMHg4ZDBkYmQ4NiwgMHgzMTExNzBhNywgMHgzZTliNjQwYywgMHhjYzNlMTBkNyxcbiAgICAweGQ1Y2FkM2I2LCAweDBjYWVjMzg4LCAweGY3MzAwMWUxLCAweDZjNzI4YWZmLCAweDcxZWFlMmExLCAweDFmOWFmMzZlLCAweGNmY2JkMTJmLCAweGMxZGU4NDE3LFxuICAgIDB4YWMwN2JlNmIsIDB4Y2I0NGExZDgsIDB4OGI5YjBmNTYsIDB4MDEzOTg4YzMsIDB4YjFjNTJmY2EsIDB4YjRiZTMxY2QsIDB4ZDg3ODI4MDYsIDB4MTJhM2E0ZTIsXG4gICAgMHg2ZjdkZTUzMiwgMHg1OGZkN2ViNiwgMHhkMDFlZTkwMCwgMHgyNGFkZmZjMiwgMHhmNDk5MGZjNSwgMHg5NzExYWFjNSwgMHgwMDFkN2I5NSwgMHg4MmU1ZTdkMixcbiAgICAweDEwOTg3M2Y2LCAweDAwNjEzMDk2LCAweGMzMmQ5NTIxLCAweGFkYTEyMWZmLCAweDI5OTA4NDE1LCAweDdmYmI5NzdmLCAweGFmOWViM2RiLCAweDI5YzllZDJhLFxuICAgIDB4NWNlMmE0NjUsIDB4YTczMGYzMmMsIDB4ZDBhYTNmZTgsIDB4OGE1Y2MwOTEsIDB4ZDQ5ZTJjZTcsIDB4MGNlNDU0YTksIDB4ZDYwYWNkODYsIDB4MDE1ZjE5MTksXG4gICAgMHg3NzA3OTEwMywgMHhkZWEwM2FmNiwgMHg3OGE4NTY1ZSwgMHhkZWUzNTZkZiwgMHgyMWYwNWNiZSwgMHg4Yjc1ZTM4NywgMHhiM2M1MDY1MSwgMHhiOGE1YzNlZixcbiAgICAweGQ4ZWViNmQyLCAweGU1MjNiZTc3LCAweGMyMTU0NTI5LCAweDJmNjllZmRmLCAweGFmZTY3YWZiLCAweGY0NzBjNGIyLCAweGYzZTBlYjViLCAweGQ2Y2M5ODc2LFxuICAgIDB4MzllNDQ2MGMsIDB4MWZkYTg1MzgsIDB4MTk4NzgzMmYsIDB4Y2EwMDczNjcsIDB4YTk5MTQ0ZjgsIDB4Mjk2YjI5OWUsIDB4NDkyZmMyOTUsIDB4OTI2NmJlYWIsXG4gICAgMHhiNTY3NmU2OSwgMHg5YmQzZGRkYSwgMHhkZjdlMDUyZiwgMHhkYjI1NzAxYywgMHgxYjVlNTFlZSwgMHhmNjUzMjRlNiwgMHg2YWZjZTM2YywgMHgwMzE2Y2MwNCxcbiAgICAweDg2NDQyMTNlLCAweGI3ZGM1OWQwLCAweDc5NjUyOTFmLCAweGNjZDZmZDQzLCAweDQxODIzOTc5LCAweDkzMmJjZGY2LCAweGI2NTdjMzRkLCAweDRlZGZkMjgyLFxuICAgIDB4N2FlNTI5MGMsIDB4M2NiOTUzNmIsIDB4ODUxZTIwZmUsIDB4OTgzMzU1N2UsIDB4MTNlY2YwYjAsIDB4ZDNmZmIzNzIsIDB4M2Y4NWM1YzEsIDB4MGFlZjdlZDIpO1xuXG4gIHNCb3hbNF0gPSBuZXcgQXJyYXkoXG4gICAgMHg3ZWM5MGMwNCwgMHgyYzZlNzRiOSwgMHg5YjBlNjZkZiwgMHhhNjMzNzkxMSwgMHhiODZhN2ZmZiwgMHgxZGQzNThmNSwgMHg0NGRkOWQ0NCwgMHgxNzMxMTY3ZixcbiAgICAweDA4ZmJmMWZhLCAweGU3ZjUxMWNjLCAweGQyMDUxYjAwLCAweDczNWFiYTAwLCAweDJhYjcyMmQ4LCAweDM4NjM4MWNiLCAweGFjZjYyNDNhLCAweDY5YmVmZDdhLFxuICAgIDB4ZTZhMmU3N2YsIDB4ZjBjNzIwY2QsIDB4YzQ0OTQ4MTYsIDB4Y2NmNWMxODAsIDB4Mzg4NTE2NDAsIDB4MTViMGE4NDgsIDB4ZTY4YjE4Y2IsIDB4NGNhYWRlZmYsXG4gICAgMHg1ZjQ4MGEwMSwgMHgwNDEyYjJhYSwgMHgyNTk4MTRmYywgMHg0MWQwZWZlMiwgMHg0ZTQwYjQ4ZCwgMHgyNDhlYjZmYiwgMHg4ZGJhMWNmZSwgMHg0MWE5OWIwMixcbiAgICAweDFhNTUwYTA0LCAweGJhOGY2NWNiLCAweDcyNTFmNGU3LCAweDk1YTUxNzI1LCAweGMxMDZlY2Q3LCAweDk3YTU5ODBhLCAweGM1MzliOWFhLCAweDRkNzlmZTZhLFxuICAgIDB4ZjJmM2Y3NjMsIDB4NjhhZjgwNDAsIDB4ZWQwYzllNTYsIDB4MTFiNDk1OGIsIDB4ZTFlYjVhODgsIDB4ODcwOWU2YjAsIDB4ZDdlMDcxNTYsIDB4NGUyOWZlYTcsXG4gICAgMHg2MzY2ZTUyZCwgMHgwMmQxYzAwMCwgMHhjNGFjOGUwNSwgMHg5Mzc3ZjU3MSwgMHgwYzA1MzcyYSwgMHg1Nzg1MzVmMiwgMHgyMjYxYmUwMiwgMHhkNjQyYTBjOSxcbiAgICAweGRmMTNhMjgwLCAweDc0YjU1YmQyLCAweDY4MjE5OWMwLCAweGQ0MjFlNWVjLCAweDUzZmIzY2U4LCAweGM4YWRlZGIzLCAweDI4YTg3ZmM5LCAweDNkOTU5OTgxLFxuICAgIDB4NWMxZmY5MDAsIDB4ZmUzOGQzOTksIDB4MGM0ZWZmMGIsIDB4MDYyNDA3ZWEsIDB4YWEyZjRmYjEsIDB4NGZiOTY5NzYsIDB4OTBjNzk1MDUsIDB4YjBhOGE3NzQsXG4gICAgMHhlZjU1YTFmZiwgMHhlNTljYTJjMiwgMHhhNmI2MmQyNywgMHhlNjZhNDI2MywgMHhkZjY1MDAxZiwgMHgwZWM1MDk2NiwgMHhkZmRkNTViYywgMHgyOWRlMDY1NSxcbiAgICAweDkxMWU3MzlhLCAweDE3YWY4OTc1LCAweDMyYzc5MTFjLCAweDg5Zjg5NDY4LCAweDBkMDFlOTgwLCAweDUyNDc1NWY0LCAweDAzYjYzY2M5LCAweDBjYzg0NGIyLFxuICAgIDB4YmNmM2YwYWEsIDB4ODdhYzM2ZTksIDB4ZTUzYTc0MjYsIDB4MDFiM2Q4MmIsIDB4MWE5ZTc0NDksIDB4NjRlZTJkN2UsIDB4Y2RkYmIxZGEsIDB4MDFjOTQ5MTAsXG4gICAgMHhiODY4YmY4MCwgMHgwZDI2ZjNmZCwgMHg5MzQyZWRlNywgMHgwNGE1YzI4NCwgMHg2MzY3MzdiNiwgMHg1MGY1YjYxNiwgMHhmMjQ3NjZlMywgMHg4ZWNhMzZjMSxcbiAgICAweDEzNmUwNWRiLCAweGZlZjE4MzkxLCAweGZiODg3YTM3LCAweGQ2ZTdmN2Q0LCAweGM3ZmI3ZGM5LCAweDMwNjNmY2RmLCAweGI2ZjU4OWRlLCAweGVjMjk0MWRhLFxuICAgIDB4MjZlNDY2OTUsIDB4Yjc1NjY0MTksIDB4ZjY1NGVmYzUsIDB4ZDA4ZDU4YjcsIDB4NDg5MjU0MDEsIDB4YzFiYWNiN2YsIDB4ZTVmZjU1MGYsIDB4YjYwODMwNDksXG4gICAgMHg1YmI1ZDBlOCwgMHg4N2Q3MmU1YSwgMHhhYjZhNmVlMSwgMHgyMjNhNjZjZSwgMHhjNjJiZjNjZCwgMHg5ZTA4ODVmOSwgMHg2OGNiM2U0NywgMHgwODZjMDEwZixcbiAgICAweGEyMWRlODIwLCAweGQxOGI2OWRlLCAweGYzZjY1Nzc3LCAweGZhMDJjM2Y2LCAweDQwN2VkYWMzLCAweGNiYjNkNTUwLCAweDE3OTMwODRkLCAweGIwZDcwZWJhLFxuICAgIDB4MGFiMzc4ZDUsIDB4ZDk1MWZiMGMsIDB4ZGVkN2RhNTYsIDB4NDEyNGJiZTQsIDB4OTRjYTBiNTYsIDB4MGY1NzU1ZDEsIDB4ZTBlMWU1NmUsIDB4NjE4NGI1YmUsXG4gICAgMHg1ODBhMjQ5ZiwgMHg5NGY3NGJjMCwgMHhlMzI3ODg4ZSwgMHg5ZjdiNTU2MSwgMHhjM2RjMDI4MCwgMHgwNTY4NzcxNSwgMHg2NDZjNmJkNywgMHg0NDkwNGRiMyxcbiAgICAweDY2YjRmMGEzLCAweGMwZjE2NDhhLCAweDY5N2VkNWFmLCAweDQ5ZTkyZmY2LCAweDMwOWUzNzRmLCAweDJjYjYzNTZhLCAweDg1ODA4NTczLCAweDQ5OTFmODQwLFxuICAgIDB4NzZmMGFlMDIsIDB4MDgzYmU4NGQsIDB4Mjg0MjFjOWEsIDB4NDQ0ODk0MDYsIDB4NzM2ZTRjYjgsIDB4YzEwOTI5MTAsIDB4OGJjOTVmYzYsIDB4N2Q4NjljZjQsXG4gICAgMHgxMzRmNjE2ZiwgMHgyZTc3MTE4ZCwgMHhiMzFiMmJlMSwgMHhhYTkwYjQ3MiwgMHgzY2E1ZDcxNywgMHg3ZDE2MWJiYSwgMHg5Y2FkOTAxMCwgMHhhZjQ2MmJhMixcbiAgICAweDlmZTQ1OWQyLCAweDQ1ZDM0NTU5LCAweGQ5ZjJkYTEzLCAweGRiYzY1NDg3LCAweGYzZTRmOTRlLCAweDE3NmQ0ODZmLCAweDA5N2MxM2VhLCAweDYzMWRhNWM3LFxuICAgIDB4NDQ1ZjczODIsIDB4MTc1NjgzZjQsIDB4Y2RjNjZhOTcsIDB4NzBiZTAyODgsIDB4YjNjZGNmNzIsIDB4NmU1ZGQyZjMsIDB4MjA5MzYwNzksIDB4NDU5YjgwYTUsXG4gICAgMHhiZTYwZTJkYiwgMHhhOWMyMzEwMSwgMHhlYmE1MzE1YywgMHgyMjRlNDJmMiwgMHgxYzVjMTU3MiwgMHhmNjcyMWIyYywgMHgxYWQyZmZmMywgMHg4YzI1NDA0ZSxcbiAgICAweDMyNGVkNzJmLCAweDQwNjdiN2ZkLCAweDA1MjMxMzhlLCAweDVjYTNiYzc4LCAweGRjMGZkNjZlLCAweDc1OTIyMjgzLCAweDc4NGQ2YjE3LCAweDU4ZWJiMTZlLFxuICAgIDB4NDQwOTRmODUsIDB4M2Y0ODFkODcsIDB4ZmNmZWFlN2IsIDB4NzdiNWZmNzYsIDB4OGMyMzAyYmYsIDB4YWFmNDc1NTYsIDB4NWY0NmIwMmEsIDB4MmIwOTI4MDEsXG4gICAgMHgzZDM4ZjVmNywgMHgwY2E4MWYzNiwgMHg1MmFmNGE4YSwgMHg2NmQ1ZTdjMCwgMHhkZjNiMDg3NCwgMHg5NTA1NTExMCwgMHgxYjVhZDdhOCwgMHhmNjFlZDVhZCxcbiAgICAweDZjZjZlNDc5LCAweDIwNzU4MTg0LCAweGQwY2VmYTY1LCAweDg4ZjdiZTU4LCAweDRhMDQ2ODI2LCAweDBmZjZmOGYzLCAweGEwOWM3ZjcwLCAweDUzNDZhYmEwLFxuICAgIDB4NWNlOTZjMjgsIDB4ZTE3NmVkYTMsIDB4NmJhYzMwN2YsIDB4Mzc2ODI5ZDIsIDB4ODUzNjBmYTksIDB4MTdlM2ZlMmEsIDB4MjRiNzk3NjcsIDB4ZjVhOTZiMjAsXG4gICAgMHhkNmNkMjU5NSwgMHg2OGZmMWViZiwgMHg3NTU1NDQyYywgMHhmMTlmMDZiZSwgMHhmOWUwNjU5YSwgMHhlZWI5NDkxZCwgMHgzNDAxMDcxOCwgMHhiYjMwY2FiOCxcbiAgICAweGU4MjJmZTE1LCAweDg4NTcwOTgzLCAweDc1MGU2MjQ5LCAweGRhNjI3ZTU1LCAweDVlNzZmZmE4LCAweGIxNTM0NTQ2LCAweDZkNDdkZTA4LCAweGVmZTllN2Q0KTtcblxuICBzQm94WzVdID0gbmV3IEFycmF5KFxuICAgIDB4ZjZmYThmOWQsIDB4MmNhYzZjZTEsIDB4NGNhMzQ4NjcsIDB4ZTIzMzdmN2MsIDB4OTVkYjA4ZTcsIDB4MDE2ODQzYjQsIDB4ZWNlZDVjYmMsIDB4MzI1NTUzYWMsXG4gICAgMHhiZjlmMDk2MCwgMHhkZmExZTJlZCwgMHg4M2YwNTc5ZCwgMHg2M2VkODZiOSwgMHgxYWI2YTZiOCwgMHhkZTVlYmUzOSwgMHhmMzhmZjczMiwgMHg4OTg5YjEzOCxcbiAgICAweDMzZjE0OTYxLCAweGMwMTkzN2JkLCAweGY1MDZjNmRhLCAweGU0NjI1ZTdlLCAweGEzMDhlYTk5LCAweDRlMjNlMzNjLCAweDc5Y2JkN2NjLCAweDQ4YTE0MzY3LFxuICAgIDB4YTMxNDk2MTksIDB4ZmVjOTRiZDUsIDB4YTExNDE3NGEsIDB4ZWFhMDE4NjYsIDB4YTA4NGRiMmQsIDB4MDlhODQ4NmYsIDB4YTg4ODYxNGEsIDB4MjkwMGFmOTgsXG4gICAgMHgwMTY2NTk5MSwgMHhlMTk5Mjg2MywgMHhjOGYzMGM2MCwgMHgyZTc4ZWYzYywgMHhkMGQ1MTkzMiwgMHhjZjBmZWMxNCwgMHhmN2NhMDdkMiwgMHhkMGE4MjA3MixcbiAgICAweGZkNDExOTdlLCAweDkzMDVhNmIwLCAweGU4NmJlM2RhLCAweDc0YmVkM2NkLCAweDM3MmRhNTNjLCAweDRjN2Y0NDQ4LCAweGRhYjVkNDQwLCAweDZkYmEwZWMzLFxuICAgIDB4MDgzOTE5YTcsIDB4OWZiYWVlZDksIDB4NDlkYmNmYjAsIDB4NGU2NzBjNTMsIDB4NWMzZDljMDEsIDB4NjRiZGI5NDEsIDB4MmMwZTYzNmEsIDB4YmE3ZGQ5Y2QsXG4gICAgMHhlYTZmNzM4OCwgMHhlNzBiYzc2MiwgMHgzNWYyOWFkYiwgMHg1YzRjZGQ4ZCwgMHhmMGQ0OGQ4YywgMHhiODgxNTNlMiwgMHgwOGExOTg2NiwgMHgxYWUyZWFjOCxcbiAgICAweDI4NGNhZjg5LCAweGFhOTI4MjIzLCAweDkzMzRiZTUzLCAweDNiM2EyMWJmLCAweDE2NDM0YmUzLCAweDlhZWEzOTA2LCAweGVmZThjMzZlLCAweGY4OTBjZGQ5LFxuICAgIDB4ODAyMjZkYWUsIDB4YzM0MGE0YTMsIDB4ZGY3ZTljMDksIDB4YTY5NGE4MDcsIDB4NWI3YzVlY2MsIDB4MjIxZGIzYTYsIDB4OWE2OWEwMmYsIDB4Njg4MThhNTQsXG4gICAgMHhjZWIyMjk2ZiwgMHg1M2MwODQzYSwgMHhmZTg5MzY1NSwgMHgyNWJmZTY4YSwgMHhiNDYyOGFiYywgMHhjZjIyMmViZiwgMHgyNWFjNmY0OCwgMHhhOWE5OTM4NyxcbiAgICAweDUzYmRkYjY1LCAweGU3NmZmYmU3LCAweGU5NjdmZDc4LCAweDBiYTkzNTYzLCAweDhlMzQyYmMxLCAweGU4YTExYmU5LCAweDQ5ODA3NDBkLCAweGM4MDg3ZGZjLFxuICAgIDB4OGRlNGJmOTksIDB4YTExMTAxYTAsIDB4N2ZkMzc5NzUsIDB4ZGE1YTI2YzAsIDB4ZTgxZjk5NGYsIDB4OTUyOGNkODksIDB4ZmQzMzlmZWQsIDB4Yjg3ODM0YmYsXG4gICAgMHg1ZjA0NDU2ZCwgMHgyMjI1ODY5OCwgMHhjOWM0YzgzYiwgMHgyZGMxNTZiZSwgMHg0ZjYyOGRhYSwgMHg1N2Y1NWVjNSwgMHhlMjIyMGFiZSwgMHhkMjkxNmViZixcbiAgICAweDRlYzc1Yjk1LCAweDI0ZjJjM2MwLCAweDQyZDE1ZDk5LCAweGNkMGQ3ZmEwLCAweDdiNmUyN2ZmLCAweGE4ZGM4YWYwLCAweDczNDVjMTA2LCAweGY0MWUyMzJmLFxuICAgIDB4MzUxNjIzODYsIDB4ZTZlYTg5MjYsIDB4MzMzM2IwOTQsIDB4MTU3ZWM2ZjIsIDB4MzcyYjc0YWYsIDB4NjkyNTczZTQsIDB4ZTlhOWQ4NDgsIDB4ZjMxNjAyODksXG4gICAgMHgzYTYyZWYxZCwgMHhhNzg3ZTIzOCwgMHhmM2E1ZjY3NiwgMHg3NDM2NDg1MywgMHgyMDk1MTA2MywgMHg0NTc2Njk4ZCwgMHhiNmZhZDQwNywgMHg1OTJhZjk1MCxcbiAgICAweDM2ZjczNTIzLCAweDRjZmI2ZTg3LCAweDdkYTRjZWMwLCAweDZjMTUyZGFhLCAweGNiMDM5NmE4LCAweGM1MGRmZTVkLCAweGZjZDcwN2FiLCAweDA5MjFjNDJmLFxuICAgIDB4ODlkZmYwYmIsIDB4NWZlMmJlNzgsIDB4NDQ4ZjRmMzMsIDB4NzU0NjEzYzksIDB4MmIwNWQwOGQsIDB4NDhiOWQ1ODUsIDB4ZGMwNDk0NDEsIDB4YzgwOThmOWIsXG4gICAgMHg3ZGVkZTc4NiwgMHhjMzlhMzM3MywgMHg0MjQxMDAwNSwgMHg2YTA5MTc1MSwgMHgwZWYzYzhhNiwgMHg4OTAwNzJkNiwgMHgyODIwNzY4MiwgMHhhOWE5ZjdiZSxcbiAgICAweGJmMzI2NzlkLCAweGQ0NWI1Yjc1LCAweGIzNTNmZDAwLCAweGNiYjBlMzU4LCAweDgzMGYyMjBhLCAweDFmOGZiMjE0LCAweGQzNzJjZjA4LCAweGNjM2M0YTEzLFxuICAgIDB4OGNmNjMxNjYsIDB4MDYxYzg3YmUsIDB4ODhjOThmODgsIDB4NjA2MmUzOTcsIDB4NDdjZjhlN2EsIDB4YjZjODUyODMsIDB4M2NjMmFjZmIsIDB4M2ZjMDY5NzYsXG4gICAgMHg0ZThmMDI1MiwgMHg2NGQ4MzE0ZCwgMHhkYTM4NzBlMywgMHgxZTY2NTQ1OSwgMHhjMTA5MDhmMCwgMHg1MTMwMjFhNSwgMHg2YzViNjhiNywgMHg4MjJmOGFhMCxcbiAgICAweDMwMDdjZDNlLCAweDc0NzE5ZWVmLCAweGRjODcyNjgxLCAweDA3MzM0MGQ0LCAweDdlNDMyZmQ5LCAweDBjNWVjMjQxLCAweDg4MDkyODZjLCAweGY1OTJkODkxLFxuICAgIDB4MDhhOTMwZjYsIDB4OTU3ZWYzMDUsIDB4YjdmYmZmYmQsIDB4YzI2NmU5NmYsIDB4NmZlNGFjOTgsIDB4YjE3M2VjYzAsIDB4YmM2MGI0MmEsIDB4OTUzNDk4ZGEsXG4gICAgMHhmYmExYWUxMiwgMHgyZDRiZDczNiwgMHgwZjI1ZmFhYiwgMHhhNGYzZmNlYiwgMHhlMjk2OTEyMywgMHgyNTdmMGMzZCwgMHg5MzQ4YWY0OSwgMHgzNjE0MDBiYyxcbiAgICAweGU4ODE2ZjRhLCAweDM4MTRmMjAwLCAweGEzZjk0MDQzLCAweDljN2E1NGMyLCAweGJjNzA0ZjU3LCAweGRhNDFlN2Y5LCAweGMyNWFkMzNhLCAweDU0ZjRhMDg0LFxuICAgIDB4YjE3ZjU1MDUsIDB4NTkzNTdjYmUsIDB4ZWRiZDE1YzgsIDB4N2Y5N2M1YWIsIDB4YmE1YWM3YjUsIDB4YjZmNmRlYWYsIDB4M2E0NzljM2EsIDB4NTMwMmRhMjUsXG4gICAgMHg2NTNkN2U2YSwgMHg1NDI2OGQ0OSwgMHg1MWE0NzdlYSwgMHg1MDE3ZDU1YiwgMHhkN2QyNWQ4OCwgMHg0NDEzNmM3NiwgMHgwNDA0YThjOCwgMHhiOGU1YTEyMSxcbiAgICAweGI4MWE5MjhhLCAweDYwZWQ1ODY5LCAweDk3YzU1Yjk2LCAweGVhZWM5OTFiLCAweDI5OTM1OTEzLCAweDAxZmRiN2YxLCAweDA4OGU4ZGZhLCAweDlhYjZmNmY1LFxuICAgIDB4M2I0Y2JmOWYsIDB4NGE1ZGUzYWIsIDB4ZTYwNTFkMzUsIDB4YTBlMWQ4NTUsIDB4ZDM2YjRjZjEsIDB4ZjU0NGVkZWIsIDB4YjBlOTM1MjQsIDB4YmViYjhmYmQsXG4gICAgMHhhMmQ3NjJjZiwgMHg0OWM5MmY1NCwgMHgzOGI1ZjMzMSwgMHg3MTI4YTQ1NCwgMHg0ODM5MjkwNSwgMHhhNjViMWRiOCwgMHg4NTFjOTdiZCwgMHhkNjc1Y2YyZik7XG5cbiAgc0JveFs2XSA9IG5ldyBBcnJheShcbiAgICAweDg1ZTA0MDE5LCAweDMzMmJmNTY3LCAweDY2MmRiZmZmLCAweGNmYzY1NjkzLCAweDJhOGQ3ZjZmLCAweGFiOWJjOTEyLCAweGRlNjAwOGExLCAweDIwMjhkYTFmLFxuICAgIDB4MDIyN2JjZTcsIDB4NGQ2NDI5MTYsIDB4MThmYWMzMDAsIDB4NTBmMThiODIsIDB4MmNiMmNiMTEsIDB4YjIzMmU3NWMsIDB4NGIzNjk1ZjIsIDB4YjI4NzA3ZGUsXG4gICAgMHhhMDVmYmNmNiwgMHhjZDQxODFlOSwgMHhlMTUwMjEwYywgMHhlMjRlZjFiZCwgMHhiMTY4YzM4MSwgMHhmZGU0ZTc4OSwgMHg1Yzc5YjBkOCwgMHgxZThiZmQ0MyxcbiAgICAweDRkNDk1MDAxLCAweDM4YmU0MzQxLCAweDkxM2NlZTFkLCAweDkyYTc5YzNmLCAweDA4OTc2NmJlLCAweGJhZWVhZGY0LCAweDEyODZiZWNmLCAweGI2ZWFjYjE5LFxuICAgIDB4MjY2MGMyMDAsIDB4NzU2NWJkZTQsIDB4NjQyNDFmN2EsIDB4ODI0OGRjYTksIDB4YzNiM2FkNjYsIDB4MjgxMzYwODYsIDB4MGJkOGRmYTgsIDB4MzU2ZDFjZjIsXG4gICAgMHgxMDc3ODliZSwgMHhiM2IyZTljZSwgMHgwNTAyYWE4ZiwgMHgwYmMwMzUxZSwgMHgxNjZiZjUyYSwgMHhlYjEyZmY4MiwgMHhlMzQ4NjkxMSwgMHhkMzRkNzUxNixcbiAgICAweDRlN2IzYWZmLCAweDVmNDM2NzFiLCAweDljZjZlMDM3LCAweDQ5ODFhYzgzLCAweDMzNDI2NmNlLCAweDhjOTM0MWI3LCAweGQwZDg1NGMwLCAweGNiM2E2Yzg4LFxuICAgIDB4NDdiYzI4MjksIDB4NDcyNWJhMzcsIDB4YTY2YWQyMmIsIDB4N2FkNjFmMWUsIDB4MGM1Y2JhZmEsIDB4NDQzN2YxMDcsIDB4YjZlNzk5NjIsIDB4NDJkMmQ4MTYsXG4gICAgMHgwYTk2MTI4OCwgMHhlMWE1YzA2ZSwgMHgxMzc0OWU2NywgMHg3MmZjMDgxYSwgMHhiMWQxMzlmNywgMHhmOTU4Mzc0NSwgMHhjZjE5ZGY1OCwgMHhiZWMzZjc1NixcbiAgICAweGMwNmViYTMwLCAweDA3MjExYjI0LCAweDQ1YzI4ODI5LCAweGM5NWUzMTdmLCAweGJjOGVjNTExLCAweDM4YmM0NmU5LCAweGM2ZTZmYTE0LCAweGJhZTg1ODRhLFxuICAgIDB4YWQ0ZWJjNDYsIDB4NDY4ZjUwOGIsIDB4NzgyOTQzNWYsIDB4ZjEyNDE4M2IsIDB4ODIxZGJhOWYsIDB4YWZmNjBmZjQsIDB4ZWEyYzRlNmQsIDB4MTZlMzkyNjQsXG4gICAgMHg5MjU0NGE4YiwgMHgwMDliNGZjMywgMHhhYmE2OGNlZCwgMHg5YWM5NmY3OCwgMHgwNmE1Yjc5YSwgMHhiMjg1NmU2ZSwgMHgxYWVjM2NhOSwgMHhiZTgzODY4OCxcbiAgICAweDBlMDgwNGU5LCAweDU1ZjFiZTU2LCAweGU3ZTUzNjNiLCAweGIzYTFmMjVkLCAweGY3ZGViYjg1LCAweDYxZmUwMzNjLCAweDE2NzQ2MjMzLCAweDNjMDM0YzI4LFxuICAgIDB4ZGE2ZDBjNzQsIDB4NzlhYWM1NmMsIDB4M2NlNGUxYWQsIDB4NTFmMGM4MDIsIDB4OThmOGYzNWEsIDB4MTYyNmE0OWYsIDB4ZWVkODJiMjksIDB4MWQzODJmZTMsXG4gICAgMHgwYzRmYjk5YSwgMHhiYjMyNTc3OCwgMHgzZWM2ZDk3YiwgMHg2ZTc3YTZhOSwgMHhjYjY1OGI1YywgMHhkNDUyMzBjNywgMHgyYmQxNDA4YiwgMHg2MGMwM2ViNyxcbiAgICAweGI5MDY4ZDc4LCAweGEzMzc1NGY0LCAweGY0MzBjODdkLCAweGM4YTcxMzAyLCAweGI5NmQ4YzMyLCAweGViZDRlN2JlLCAweGJlOGI5ZDJkLCAweDc5NzlmYjA2LFxuICAgIDB4ZTcyMjUzMDgsIDB4OGI3NWNmNzcsIDB4MTFlZjhkYTQsIDB4ZTA4M2M4NTgsIDB4OGQ2Yjc4NmYsIDB4NWE2MzE3YTYsIDB4ZmE1Y2Y3YTAsIDB4NWRkYTAwMzMsXG4gICAgMHhmMjhlYmZiMCwgMHhmNWI5YzMxMCwgMHhhMGVhYzI4MCwgMHgwOGI5NzY3YSwgMHhhM2Q5ZDJiMCwgMHg3OWQzNDIxNywgMHgwMjFhNzE4ZCwgMHg5YWM2MzM2YSxcbiAgICAweDI3MTFmZDYwLCAweDQzODA1MGUzLCAweDA2OTkwOGE4LCAweDNkN2ZlZGM0LCAweDgyNmQyYmVmLCAweDRlZWI4NDc2LCAweDQ4OGRjZjI1LCAweDM2YzlkNTY2LFxuICAgIDB4MjhlNzRlNDEsIDB4YzI2MTBhY2EsIDB4M2Q0OWE5Y2YsIDB4YmFlM2I5ZGYsIDB4YjY1ZjhkZTYsIDB4OTJhZWFmNjQsIDB4M2FjN2Q1ZTYsIDB4OWVhODA1MDksXG4gICAgMHhmMjJiMDE3ZCwgMHhhNDE3M2Y3MCwgMHhkZDFlMTZjMywgMHgxNWUwZDdmOSwgMHg1MGIxYjg4NywgMHgyYjlmNGZkNSwgMHg2MjVhYmE4MiwgMHg2YTAxNzk2MixcbiAgICAweDJlYzAxYjljLCAweDE1NDg4YWE5LCAweGQ3MTZlNzQwLCAweDQwMDU1YTJjLCAweDkzZDI5YTIyLCAweGUzMmRiZjlhLCAweDA1ODc0NWI5LCAweDM0NTNkYzFlLFxuICAgIDB4ZDY5OTI5NmUsIDB4NDk2Y2ZmNmYsIDB4MWM5ZjQ5ODYsIDB4ZGZlMmVkMDcsIDB4Yjg3MjQyZDEsIDB4MTlkZTdlYWUsIDB4MDUzZTU2MWEsIDB4MTVhZDZmOGMsXG4gICAgMHg2NjYyNmMxYywgMHg3MTU0YzI0YywgMHhlYTA4MmIyYSwgMHg5M2ViMjkzOSwgMHgxN2RjYjBmMCwgMHg1OGQ0ZjJhZSwgMHg5ZWEyOTRmYiwgMHg1MmNmNTY0YyxcbiAgICAweDk4ODNmZTY2LCAweDJlYzQwNTgxLCAweDc2Mzk1M2MzLCAweDAxZDY2OTJlLCAweGQzYTBjMTA4LCAweGExZTcxNjBlLCAweGU0ZjJkZmE2LCAweDY5M2VkMjg1LFxuICAgIDB4NzQ5MDQ2OTgsIDB4NGMyYjBlZGQsIDB4NGY3NTc2NTYsIDB4NWQzOTMzNzgsIDB4YTEzMjIzNGYsIDB4M2QzMjFjNWQsIDB4YzNmNWUxOTQsIDB4NGIyNjkzMDEsXG4gICAgMHhjNzlmMDIyZiwgMHgzYzk5N2U3ZSwgMHg1ZTRmOTUwNCwgMHgzZmZhZmJiZCwgMHg3NmY3YWQwZSwgMHgyOTY2OTNmNCwgMHgzZDFmY2U2ZiwgMHhjNjFlNDViZSxcbiAgICAweGQzYjVhYjM0LCAweGY3MmJmOWI3LCAweDFiMDQzNGMwLCAweDRlNzJiNTY3LCAweDU1OTJhMzNkLCAweGI1MjI5MzAxLCAweGNmZDJhODdmLCAweDYwYWViNzY3LFxuICAgIDB4MTgxNDM4NmIsIDB4MzBiY2MzM2QsIDB4MzhhMGMwN2QsIDB4ZmQxNjA2ZjIsIDB4YzM2MzUxOWIsIDB4NTg5ZGQzOTAsIDB4NTQ3OWY4ZTYsIDB4MWNiOGQ2NDcsXG4gICAgMHg5N2ZkNjFhOSwgMHhlYTc3NTlmNCwgMHgyZDU3NTM5ZCwgMHg1NjlhNThjZiwgMHhlODRlNjNhZCwgMHg0NjJlMWI3OCwgMHg2NTgwZjg3ZSwgMHhmMzgxNzkxNCxcbiAgICAweDkxZGE1NWY0LCAweDQwYTIzMGYzLCAweGQxOTg4ZjM1LCAweGI2ZTMxOGQyLCAweDNmZmE1MGJjLCAweDNkNDBmMDIxLCAweGMzYzBiZGFlLCAweDQ5NThjMjRjLFxuICAgIDB4NTE4ZjM2YjIsIDB4ODRiMWQzNzAsIDB4MGZlZGNlODMsIDB4ODc4ZGRhZGEsIDB4ZjJhMjc5YzcsIDB4OTRlMDFiZTgsIDB4OTA3MTZmNGIsIDB4OTU0YjhhYTMpO1xuXG4gIHNCb3hbN10gPSBuZXcgQXJyYXkoXG4gICAgMHhlMjE2MzAwZCwgMHhiYmRkZmZmYywgMHhhN2ViZGFiZCwgMHgzNTY0ODA5NSwgMHg3Nzg5ZjhiNywgMHhlNmMxMTIxYiwgMHgwZTI0MTYwMCwgMHgwNTJjZThiNSxcbiAgICAweDExYTljZmIwLCAweGU1OTUyZjExLCAweGVjZTc5OTBhLCAweDkzODZkMTc0LCAweDJhNDI5MzFjLCAweDc2ZTM4MTExLCAweGIxMmRlZjNhLCAweDM3ZGRkZGZjLFxuICAgIDB4ZGU5YWRlYjEsIDB4MGEwY2MzMmMsIDB4YmUxOTcwMjksIDB4ODRhMDA5NDAsIDB4YmIyNDNhMGYsIDB4YjRkMTM3Y2YsIDB4YjQ0ZTc5ZjAsIDB4MDQ5ZWVkZmQsXG4gICAgMHgwYjE1YTE1ZCwgMHg0ODBkMzE2OCwgMHg4YmJiZGU1YSwgMHg2NjlkZWQ0MiwgMHhjN2VjZTgzMSwgMHgzZjhmOTVlNywgMHg3MmRmMTkxYiwgMHg3NTgwMzMwZCxcbiAgICAweDk0MDc0MjUxLCAweDVjN2RjZGZhLCAweGFiYmU2ZDYzLCAweGFhNDAyMTY0LCAweGIzMDFkNDBhLCAweDAyZTdkMWNhLCAweDUzNTcxZGFlLCAweDdhMzE4MmEyLFxuICAgIDB4MTJhOGRkZWMsIDB4ZmRhYTMzNWQsIDB4MTc2ZjQzZTgsIDB4NzFmYjQ2ZDQsIDB4MzgxMjkwMjIsIDB4Y2U5NDlhZDQsIDB4Yjg0NzY5YWQsIDB4OTY1YmQ4NjIsXG4gICAgMHg4MmYzZDA1NSwgMHg2NmZiOTc2NywgMHgxNWI4MGI0ZSwgMHgxZDViNDdhMCwgMHg0Y2ZkZTA2ZiwgMHhjMjhlYzRiOCwgMHg1N2U4NzI2ZSwgMHg2NDdhNzhmYyxcbiAgICAweDk5ODY1ZDQ0LCAweDYwOGJkNTkzLCAweDZjMjAwZTAzLCAweDM5ZGM1ZmY2LCAweDVkMGIwMGEzLCAweGFlNjNhZmYyLCAweDdlOGJkNjMyLCAweDcwMTA4YzBjLFxuICAgIDB4YmJkMzUwNDksIDB4Mjk5OGRmMDQsIDB4OTgwY2Y0MmEsIDB4OWI2ZGY0OTEsIDB4OWU3ZWRkNTMsIDB4MDY5MTg1NDgsIDB4NThjYjdlMDcsIDB4M2I3NGVmMmUsXG4gICAgMHg1MjJmZmZiMSwgMHhkMjQ3MDhjYywgMHgxYzdlMjdjZCwgMHhhNGViMjE1YiwgMHgzY2YxZDJlMiwgMHgxOWI0N2EzOCwgMHg0MjRmNzYxOCwgMHgzNTg1NjAzOSxcbiAgICAweDlkMTdkZWU3LCAweDI3ZWIzNWU2LCAweGM5YWZmNjdiLCAweDM2YmFmNWI4LCAweDA5YzQ2N2NkLCAweGMxODkxMGIxLCAweGUxMWRiZjdiLCAweDA2Y2QxYWY4LFxuICAgIDB4NzE3MGM2MDgsIDB4MmQ1ZTMzNTQsIDB4ZDRkZTQ5NWEsIDB4NjRjNmQwMDYsIDB4YmNjMGM2MmMsIDB4M2RkMDBkYjMsIDB4NzA4ZjhmMzQsIDB4NzdkNTFiNDIsXG4gICAgMHgyNjRmNjIwZiwgMHgyNGI4ZDJiZiwgMHgxNWMxYjc5ZSwgMHg0NmE1MjU2NCwgMHhmOGQ3ZTU0ZSwgMHgzZTM3ODE2MCwgMHg3ODk1Y2RhNSwgMHg4NTljMTVhNSxcbiAgICAweGU2NDU5Nzg4LCAweGMzN2JjNzVmLCAweGRiMDdiYTBjLCAweDA2NzZhM2FiLCAweDdmMjI5YjFlLCAweDMxODQyZTdiLCAweDI0MjU5ZmQ3LCAweGY4YmVmNDcyLFxuICAgIDB4ODM1ZmZjYjgsIDB4NmRmNGMxZjIsIDB4OTZmNWIxOTUsIDB4ZmQwYWYwZmMsIDB4YjBmZTEzNGMsIDB4ZTI1MDZkM2QsIDB4NGY5YjEyZWEsIDB4ZjIxNWYyMjUsXG4gICAgMHhhMjIzNzM2ZiwgMHg5ZmI0YzQyOCwgMHgyNWQwNDk3OSwgMHgzNGM3MTNmOCwgMHhjNDYxODE4NywgMHhlYTdhNmU5OCwgMHg3Y2QxNmVmYywgMHgxNDM2ODc2YyxcbiAgICAweGYxNTQ0MTA3LCAweGJlZGVlZTE0LCAweDU2ZTlhZjI3LCAweGEwNGFhNDQxLCAweDNjZjdjODk5LCAweDkyZWNiYWU2LCAweGRkNjcwMTZkLCAweDE1MTY4MmViLFxuICAgIDB4YTg0MmVlZGYsIDB4ZmRiYTYwYjQsIDB4ZjE5MDdiNzUsIDB4MjBlMzAzMGYsIDB4MjRkOGMyOWUsIDB4ZTEzOTY3M2IsIDB4ZWZhNjNmYjgsIDB4NzE4NzMwNTQsXG4gICAgMHhiNmYyY2YzYiwgMHg5ZjMyNjQ0MiwgMHhjYjE1YTRjYywgMHhiMDFhNDUwNCwgMHhmMWU0N2Q4ZCwgMHg4NDRhMWJlNSwgMHhiYWU3ZGZkYywgMHg0MmNiZGE3MCxcbiAgICAweGNkN2RhZTBhLCAweDU3ZTg1YjdhLCAweGQ1M2Y1YWY2LCAweDIwY2Y0ZDhjLCAweGNlYTRkNDI4LCAweDc5ZDEzMGE0LCAweDM0ODZlYmZiLCAweDMzZDNjZGRjLFxuICAgIDB4Nzc4NTNiNTMsIDB4MzdlZmZjYjUsIDB4YzUwNjg3NzgsIDB4ZTU4MGIzZTYsIDB4NGU2OGI4ZjQsIDB4YzVjOGIzN2UsIDB4MGQ4MDllYTIsIDB4Mzk4ZmViN2MsXG4gICAgMHgxMzJhNGY5NCwgMHg0M2I3OTUwZSwgMHgyZmVlN2QxYywgMHgyMjM2MTNiZCwgMHhkZDA2Y2FhMiwgMHgzN2RmOTMyYiwgMHhjNDI0ODI4OSwgMHhhY2YzZWJjMyxcbiAgICAweDU3MTVmNmI3LCAweGVmMzQ3OGRkLCAweGYyNjc2MTZmLCAweGMxNDhjYmU0LCAweDkwNTI4MTVlLCAweDVlNDEwZmFiLCAweGI0OGEyNDY1LCAweDJlZGE3ZmE0LFxuICAgIDB4ZTg3YjQwZTQsIDB4ZTk4ZWEwODQsIDB4NTg4OWU5ZTEsIDB4ZWZkMzkwZmMsIDB4ZGQwN2QzNWIsIDB4ZGI0ODU2OTQsIDB4MzhkN2U1YjIsIDB4NTc3MjAxMDEsXG4gICAgMHg3MzBlZGViYywgMHg1YjY0MzExMywgMHg5NDkxN2U0ZiwgMHg1MDNjMmZiYSwgMHg2NDZmMTI4MiwgMHg3NTIzZDI0YSwgMHhlMDc3OTY5NSwgMHhmOWMxN2E4ZixcbiAgICAweDdhNWIyMTIxLCAweGQxODdiODk2LCAweDI5MjYzYTRkLCAweGJhNTEwY2RmLCAweDgxZjQ3YzlmLCAweGFkMTE2M2VkLCAweGVhN2I1OTY1LCAweDFhMDA3MjZlLFxuICAgIDB4MTE0MDMwOTIsIDB4MDBkYTZkNzcsIDB4NGEwY2RkNjEsIDB4YWQxZjQ2MDMsIDB4NjA1YmRmYjAsIDB4OWVlZGMzNjQsIDB4MjJlYmU2YTgsIDB4Y2VlN2QyOGEsXG4gICAgMHhhMGU3MzZhMCwgMHg1NTY0YTZiOSwgMHgxMDg1MzIwOSwgMHhjN2ViOGYzNywgMHgyZGU3MDVjYSwgMHg4OTUxNTcwZiwgMHhkZjA5ODIyYiwgMHhiZDY5MWE2YyxcbiAgICAweGFhMTJlNGYyLCAweDg3NDUxYzBmLCAweGUwZjZhMjdhLCAweDNhZGE0ODE5LCAweDRjZjE3NjRmLCAweDBkNzcxYzJiLCAweDY3Y2RiMTU2LCAweDM1MGQ4Mzg0LFxuICAgIDB4NTkzOGZhMGYsIDB4NDIzOTllZjMsIDB4MzY5OTdiMDcsIDB4MGU4NDA5M2QsIDB4NGFhOTNlNjEsIDB4ODM2MGQ4N2IsIDB4MWZhOThiMGMsIDB4MTE0OTM4MmMsXG4gICAgMHhlOTc2MjVhNSwgMHgwNjE0ZDFiNywgMHgwZTI1MjQ0YiwgMHgwYzc2ODM0NywgMHg1ODllOGQ4MiwgMHgwZDIwNTlkMSwgMHhhNDY2YmIxZSwgMHhmOGRhMGE4MixcbiAgICAweDA0ZjE5MTMwLCAweGJhNmU0ZWMwLCAweDk5MjY1MTY0LCAweDFlZTcyMzBkLCAweDUwYjJhZDgwLCAweGVhZWU2ODAxLCAweDhkYjJhMjgzLCAweGVhOGJmNTllKTtcblxufTtcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi8uLi91dGlsJyk7XG5cbmZ1bmN0aW9uIGNhc3Q1KGtleSkge1xuICB0aGlzLmNhc3Q1ID0gbmV3IG9wZW5wZ3Bfc3ltZW5jX2Nhc3Q1KCk7XG4gIHRoaXMuY2FzdDUuc2V0S2V5KHV0aWwuc3RyMmJpbihrZXkpKTtcblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaykge1xuICAgIHJldHVybiB0aGlzLmNhc3Q1LmVuY3J5cHQoYmxvY2spO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY2FzdDU7XG5tb2R1bGUuZXhwb3J0cy5ibG9ja1NpemUgPSBjYXN0NS5wcm90b3R5cGUuYmxvY2tTaXplID0gODtcbm1vZHVsZS5leHBvcnRzLmtleVNpemUgPSBjYXN0NS5wcm90b3R5cGUua2V5U2l6ZSA9IDE2O1xuIiwiLy9QYXVsIFRlcm8sIEp1bHkgMjAwMVxuLy9odHRwOi8vd3d3LnRlcm8uY28udWsvZGVzL1xuLy9cbi8vT3B0aW1pc2VkIGZvciBwZXJmb3JtYW5jZSB3aXRoIGxhcmdlIGJsb2NrcyBieSBNaWNoYWVsIEhheXdvcnRoLCBOb3ZlbWJlciAyMDAxXG4vL2h0dHA6Ly93d3cubmV0ZGVhbGluZy5jb21cbi8vXG4vLyBNb2RpZmllZCBieSBSZWN1cml0eSBMYWJzIEdtYkhcblxuLy9USElTIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkRcbi8vQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFXG4vL0lNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFXG4vL0FSRSBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFXG4vL0ZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMXG4vL0RBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTXG4vL09SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKVxuLy9IT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVFxuLy9MSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZXG4vL09VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0Zcbi8vU1VDSCBEQU1BR0UuXG5cbi8vZGVzXG4vL3RoaXMgdGFrZXMgdGhlIGtleSwgdGhlIG1lc3NhZ2UsIGFuZCB3aGV0aGVyIHRvIGVuY3J5cHQgb3IgZGVjcnlwdFxuXG5cblxuXG5mdW5jdGlvbiBkZXMoa2V5cywgbWVzc2FnZSwgZW5jcnlwdCwgbW9kZSwgaXYsIHBhZGRpbmcpIHtcbiAgLy9kZWNsYXJpbmcgdGhpcyBsb2NhbGx5IHNwZWVkcyB0aGluZ3MgdXAgYSBiaXRcbiAgdmFyIHNwZnVuY3Rpb24xID0gbmV3IEFycmF5KDB4MTAxMDQwMCwgMCwgMHgxMDAwMCwgMHgxMDEwNDA0LCAweDEwMTAwMDQsIDB4MTA0MDQsIDB4NCwgMHgxMDAwMCwgMHg0MDAsIDB4MTAxMDQwMCxcbiAgICAweDEwMTA0MDQsIDB4NDAwLCAweDEwMDA0MDQsIDB4MTAxMDAwNCwgMHgxMDAwMDAwLCAweDQsIDB4NDA0LCAweDEwMDA0MDAsIDB4MTAwMDQwMCwgMHgxMDQwMCwgMHgxMDQwMCwgMHgxMDEwMDAwLFxuICAgIDB4MTAxMDAwMCwgMHgxMDAwNDA0LCAweDEwMDA0LCAweDEwMDAwMDQsIDB4MTAwMDAwNCwgMHgxMDAwNCwgMCwgMHg0MDQsIDB4MTA0MDQsIDB4MTAwMDAwMCwgMHgxMDAwMCwgMHgxMDEwNDA0LCAweDQsXG4gICAgMHgxMDEwMDAwLCAweDEwMTA0MDAsIDB4MTAwMDAwMCwgMHgxMDAwMDAwLCAweDQwMCwgMHgxMDEwMDA0LCAweDEwMDAwLCAweDEwNDAwLCAweDEwMDAwMDQsIDB4NDAwLCAweDQsIDB4MTAwMDQwNCxcbiAgICAweDEwNDA0LCAweDEwMTA0MDQsIDB4MTAwMDQsIDB4MTAxMDAwMCwgMHgxMDAwNDA0LCAweDEwMDAwMDQsIDB4NDA0LCAweDEwNDA0LCAweDEwMTA0MDAsIDB4NDA0LCAweDEwMDA0MDAsXG4gICAgMHgxMDAwNDAwLCAwLCAweDEwMDA0LCAweDEwNDAwLCAwLCAweDEwMTAwMDQpO1xuICB2YXIgc3BmdW5jdGlvbjIgPSBuZXcgQXJyYXkoLTB4N2ZlZjdmZTAsIC0weDdmZmY4MDAwLCAweDgwMDAsIDB4MTA4MDIwLCAweDEwMDAwMCwgMHgyMCwgLTB4N2ZlZmZmZTAsIC0weDdmZmY3ZmUwLCAtXG4gICAgMHg3ZmZmZmZlMCwgLTB4N2ZlZjdmZTAsIC0weDdmZWY4MDAwLCAtMHg4MDAwMDAwMCwgLTB4N2ZmZjgwMDAsIDB4MTAwMDAwLCAweDIwLCAtMHg3ZmVmZmZlMCwgMHgxMDgwMDAsIDB4MTAwMDIwLCAtXG4gICAgMHg3ZmZmN2ZlMCwgMCwgLTB4ODAwMDAwMDAsIDB4ODAwMCwgMHgxMDgwMjAsIC0weDdmZjAwMDAwLCAweDEwMDAyMCwgLTB4N2ZmZmZmZTAsIDAsIDB4MTA4MDAwLCAweDgwMjAsIC0weDdmZWY4MDAwLCAtXG4gICAgMHg3ZmYwMDAwMCwgMHg4MDIwLCAwLCAweDEwODAyMCwgLTB4N2ZlZmZmZTAsIDB4MTAwMDAwLCAtMHg3ZmZmN2ZlMCwgLTB4N2ZmMDAwMDAsIC0weDdmZWY4MDAwLCAweDgwMDAsIC0weDdmZjAwMDAwLCAtXG4gICAgMHg3ZmZmODAwMCwgMHgyMCwgLTB4N2ZlZjdmZTAsIDB4MTA4MDIwLCAweDIwLCAweDgwMDAsIC0weDgwMDAwMDAwLCAweDgwMjAsIC0weDdmZWY4MDAwLCAweDEwMDAwMCwgLTB4N2ZmZmZmZTAsXG4gICAgMHgxMDAwMjAsIC0weDdmZmY3ZmUwLCAtMHg3ZmZmZmZlMCwgMHgxMDAwMjAsIDB4MTA4MDAwLCAwLCAtMHg3ZmZmODAwMCwgMHg4MDIwLCAtMHg4MDAwMDAwMCwgLTB4N2ZlZmZmZTAsIC1cbiAgICAweDdmZWY3ZmUwLCAweDEwODAwMCk7XG4gIHZhciBzcGZ1bmN0aW9uMyA9IG5ldyBBcnJheSgweDIwOCwgMHg4MDIwMjAwLCAwLCAweDgwMjAwMDgsIDB4ODAwMDIwMCwgMCwgMHgyMDIwOCwgMHg4MDAwMjAwLCAweDIwMDA4LCAweDgwMDAwMDgsXG4gICAgMHg4MDAwMDA4LCAweDIwMDAwLCAweDgwMjAyMDgsIDB4MjAwMDgsIDB4ODAyMDAwMCwgMHgyMDgsIDB4ODAwMDAwMCwgMHg4LCAweDgwMjAyMDAsIDB4MjAwLCAweDIwMjAwLCAweDgwMjAwMDAsXG4gICAgMHg4MDIwMDA4LCAweDIwMjA4LCAweDgwMDAyMDgsIDB4MjAyMDAsIDB4MjAwMDAsIDB4ODAwMDIwOCwgMHg4LCAweDgwMjAyMDgsIDB4MjAwLCAweDgwMDAwMDAsIDB4ODAyMDIwMCwgMHg4MDAwMDAwLFxuICAgIDB4MjAwMDgsIDB4MjA4LCAweDIwMDAwLCAweDgwMjAyMDAsIDB4ODAwMDIwMCwgMCwgMHgyMDAsIDB4MjAwMDgsIDB4ODAyMDIwOCwgMHg4MDAwMjAwLCAweDgwMDAwMDgsIDB4MjAwLCAwLFxuICAgIDB4ODAyMDAwOCwgMHg4MDAwMjA4LCAweDIwMDAwLCAweDgwMDAwMDAsIDB4ODAyMDIwOCwgMHg4LCAweDIwMjA4LCAweDIwMjAwLCAweDgwMDAwMDgsIDB4ODAyMDAwMCwgMHg4MDAwMjA4LCAweDIwOCxcbiAgICAweDgwMjAwMDAsIDB4MjAyMDgsIDB4OCwgMHg4MDIwMDA4LCAweDIwMjAwKTtcbiAgdmFyIHNwZnVuY3Rpb240ID0gbmV3IEFycmF5KDB4ODAyMDAxLCAweDIwODEsIDB4MjA4MSwgMHg4MCwgMHg4MDIwODAsIDB4ODAwMDgxLCAweDgwMDAwMSwgMHgyMDAxLCAwLCAweDgwMjAwMCxcbiAgICAweDgwMjAwMCwgMHg4MDIwODEsIDB4ODEsIDAsIDB4ODAwMDgwLCAweDgwMDAwMSwgMHgxLCAweDIwMDAsIDB4ODAwMDAwLCAweDgwMjAwMSwgMHg4MCwgMHg4MDAwMDAsIDB4MjAwMSwgMHgyMDgwLFxuICAgIDB4ODAwMDgxLCAweDEsIDB4MjA4MCwgMHg4MDAwODAsIDB4MjAwMCwgMHg4MDIwODAsIDB4ODAyMDgxLCAweDgxLCAweDgwMDA4MCwgMHg4MDAwMDEsIDB4ODAyMDAwLCAweDgwMjA4MSwgMHg4MSwgMCxcbiAgICAwLCAweDgwMjAwMCwgMHgyMDgwLCAweDgwMDA4MCwgMHg4MDAwODEsIDB4MSwgMHg4MDIwMDEsIDB4MjA4MSwgMHgyMDgxLCAweDgwLCAweDgwMjA4MSwgMHg4MSwgMHgxLCAweDIwMDAsIDB4ODAwMDAxLFxuICAgIDB4MjAwMSwgMHg4MDIwODAsIDB4ODAwMDgxLCAweDIwMDEsIDB4MjA4MCwgMHg4MDAwMDAsIDB4ODAyMDAxLCAweDgwLCAweDgwMDAwMCwgMHgyMDAwLCAweDgwMjA4MCk7XG4gIHZhciBzcGZ1bmN0aW9uNSA9IG5ldyBBcnJheSgweDEwMCwgMHgyMDgwMTAwLCAweDIwODAwMDAsIDB4NDIwMDAxMDAsIDB4ODAwMDAsIDB4MTAwLCAweDQwMDAwMDAwLCAweDIwODAwMDAsXG4gICAgMHg0MDA4MDEwMCwgMHg4MDAwMCwgMHgyMDAwMTAwLCAweDQwMDgwMTAwLCAweDQyMDAwMTAwLCAweDQyMDgwMDAwLCAweDgwMTAwLCAweDQwMDAwMDAwLCAweDIwMDAwMDAsIDB4NDAwODAwMDAsXG4gICAgMHg0MDA4MDAwMCwgMCwgMHg0MDAwMDEwMCwgMHg0MjA4MDEwMCwgMHg0MjA4MDEwMCwgMHgyMDAwMTAwLCAweDQyMDgwMDAwLCAweDQwMDAwMTAwLCAwLCAweDQyMDAwMDAwLCAweDIwODAxMDAsXG4gICAgMHgyMDAwMDAwLCAweDQyMDAwMDAwLCAweDgwMTAwLCAweDgwMDAwLCAweDQyMDAwMTAwLCAweDEwMCwgMHgyMDAwMDAwLCAweDQwMDAwMDAwLCAweDIwODAwMDAsIDB4NDIwMDAxMDAsXG4gICAgMHg0MDA4MDEwMCwgMHgyMDAwMTAwLCAweDQwMDAwMDAwLCAweDQyMDgwMDAwLCAweDIwODAxMDAsIDB4NDAwODAxMDAsIDB4MTAwLCAweDIwMDAwMDAsIDB4NDIwODAwMDAsIDB4NDIwODAxMDAsXG4gICAgMHg4MDEwMCwgMHg0MjAwMDAwMCwgMHg0MjA4MDEwMCwgMHgyMDgwMDAwLCAwLCAweDQwMDgwMDAwLCAweDQyMDAwMDAwLCAweDgwMTAwLCAweDIwMDAxMDAsIDB4NDAwMDAxMDAsIDB4ODAwMDAsIDAsXG4gICAgMHg0MDA4MDAwMCwgMHgyMDgwMTAwLCAweDQwMDAwMTAwKTtcbiAgdmFyIHNwZnVuY3Rpb242ID0gbmV3IEFycmF5KDB4MjAwMDAwMTAsIDB4MjA0MDAwMDAsIDB4NDAwMCwgMHgyMDQwNDAxMCwgMHgyMDQwMDAwMCwgMHgxMCwgMHgyMDQwNDAxMCwgMHg0MDAwMDAsXG4gICAgMHgyMDAwNDAwMCwgMHg0MDQwMTAsIDB4NDAwMDAwLCAweDIwMDAwMDEwLCAweDQwMDAxMCwgMHgyMDAwNDAwMCwgMHgyMDAwMDAwMCwgMHg0MDEwLCAwLCAweDQwMDAxMCwgMHgyMDAwNDAxMCxcbiAgICAweDQwMDAsIDB4NDA0MDAwLCAweDIwMDA0MDEwLCAweDEwLCAweDIwNDAwMDEwLCAweDIwNDAwMDEwLCAwLCAweDQwNDAxMCwgMHgyMDQwNDAwMCwgMHg0MDEwLCAweDQwNDAwMCwgMHgyMDQwNDAwMCxcbiAgICAweDIwMDAwMDAwLCAweDIwMDA0MDAwLCAweDEwLCAweDIwNDAwMDEwLCAweDQwNDAwMCwgMHgyMDQwNDAxMCwgMHg0MDAwMDAsIDB4NDAxMCwgMHgyMDAwMDAxMCwgMHg0MDAwMDAsIDB4MjAwMDQwMDAsXG4gICAgMHgyMDAwMDAwMCwgMHg0MDEwLCAweDIwMDAwMDEwLCAweDIwNDA0MDEwLCAweDQwNDAwMCwgMHgyMDQwMDAwMCwgMHg0MDQwMTAsIDB4MjA0MDQwMDAsIDAsIDB4MjA0MDAwMTAsIDB4MTAsIDB4NDAwMCxcbiAgICAweDIwNDAwMDAwLCAweDQwNDAxMCwgMHg0MDAwLCAweDQwMDAxMCwgMHgyMDAwNDAxMCwgMCwgMHgyMDQwNDAwMCwgMHgyMDAwMDAwMCwgMHg0MDAwMTAsIDB4MjAwMDQwMTApO1xuICB2YXIgc3BmdW5jdGlvbjcgPSBuZXcgQXJyYXkoMHgyMDAwMDAsIDB4NDIwMDAwMiwgMHg0MDAwODAyLCAwLCAweDgwMCwgMHg0MDAwODAyLCAweDIwMDgwMiwgMHg0MjAwODAwLCAweDQyMDA4MDIsXG4gICAgMHgyMDAwMDAsIDAsIDB4NDAwMDAwMiwgMHgyLCAweDQwMDAwMDAsIDB4NDIwMDAwMiwgMHg4MDIsIDB4NDAwMDgwMCwgMHgyMDA4MDIsIDB4MjAwMDAyLCAweDQwMDA4MDAsIDB4NDAwMDAwMixcbiAgICAweDQyMDAwMDAsIDB4NDIwMDgwMCwgMHgyMDAwMDIsIDB4NDIwMDAwMCwgMHg4MDAsIDB4ODAyLCAweDQyMDA4MDIsIDB4MjAwODAwLCAweDIsIDB4NDAwMDAwMCwgMHgyMDA4MDAsIDB4NDAwMDAwMCxcbiAgICAweDIwMDgwMCwgMHgyMDAwMDAsIDB4NDAwMDgwMiwgMHg0MDAwODAyLCAweDQyMDAwMDIsIDB4NDIwMDAwMiwgMHgyLCAweDIwMDAwMiwgMHg0MDAwMDAwLCAweDQwMDA4MDAsIDB4MjAwMDAwLFxuICAgIDB4NDIwMDgwMCwgMHg4MDIsIDB4MjAwODAyLCAweDQyMDA4MDAsIDB4ODAyLCAweDQwMDAwMDIsIDB4NDIwMDgwMiwgMHg0MjAwMDAwLCAweDIwMDgwMCwgMCwgMHgyLCAweDQyMDA4MDIsIDAsXG4gICAgMHgyMDA4MDIsIDB4NDIwMDAwMCwgMHg4MDAsIDB4NDAwMDAwMiwgMHg0MDAwODAwLCAweDgwMCwgMHgyMDAwMDIpO1xuICB2YXIgc3BmdW5jdGlvbjggPSBuZXcgQXJyYXkoMHgxMDAwMTA0MCwgMHgxMDAwLCAweDQwMDAwLCAweDEwMDQxMDQwLCAweDEwMDAwMDAwLCAweDEwMDAxMDQwLCAweDQwLCAweDEwMDAwMDAwLFxuICAgIDB4NDAwNDAsIDB4MTAwNDAwMDAsIDB4MTAwNDEwNDAsIDB4NDEwMDAsIDB4MTAwNDEwMDAsIDB4NDEwNDAsIDB4MTAwMCwgMHg0MCwgMHgxMDA0MDAwMCwgMHgxMDAwMDA0MCwgMHgxMDAwMTAwMCxcbiAgICAweDEwNDAsIDB4NDEwMDAsIDB4NDAwNDAsIDB4MTAwNDAwNDAsIDB4MTAwNDEwMDAsIDB4MTA0MCwgMCwgMCwgMHgxMDA0MDA0MCwgMHgxMDAwMDA0MCwgMHgxMDAwMTAwMCwgMHg0MTA0MCxcbiAgICAweDQwMDAwLCAweDQxMDQwLCAweDQwMDAwLCAweDEwMDQxMDAwLCAweDEwMDAsIDB4NDAsIDB4MTAwNDAwNDAsIDB4MTAwMCwgMHg0MTA0MCwgMHgxMDAwMTAwMCwgMHg0MCwgMHgxMDAwMDA0MCxcbiAgICAweDEwMDQwMDAwLCAweDEwMDQwMDQwLCAweDEwMDAwMDAwLCAweDQwMDAwLCAweDEwMDAxMDQwLCAwLCAweDEwMDQxMDQwLCAweDQwMDQwLCAweDEwMDAwMDQwLCAweDEwMDQwMDAwLCAweDEwMDAxMDAwLFxuICAgIDB4MTAwMDEwNDAsIDAsIDB4MTAwNDEwNDAsIDB4NDEwMDAsIDB4NDEwMDAsIDB4MTA0MCwgMHgxMDQwLCAweDQwMDQwLCAweDEwMDAwMDAwLCAweDEwMDQxMDAwKTtcblxuICAvL2NyZWF0ZSB0aGUgMTYgb3IgNDggc3Via2V5cyB3ZSB3aWxsIG5lZWRcbiAgdmFyIG0gPSAwLFxuICAgIGksIGosIHRlbXAsIHRlbXAyLCByaWdodDEsIHJpZ2h0MiwgbGVmdCwgcmlnaHQsIGxvb3Bpbmc7XG4gIHZhciBjYmNsZWZ0LCBjYmNsZWZ0MiwgY2JjcmlnaHQsIGNiY3JpZ2h0MlxuICB2YXIgZW5kbG9vcCwgbG9vcGluYztcbiAgdmFyIGxlbiA9IG1lc3NhZ2UubGVuZ3RoO1xuICB2YXIgY2h1bmsgPSAwO1xuICAvL3NldCB1cCB0aGUgbG9vcHMgZm9yIHNpbmdsZSBhbmQgdHJpcGxlIGRlc1xuICB2YXIgaXRlcmF0aW9ucyA9IGtleXMubGVuZ3RoID09IDMyID8gMyA6IDk7IC8vc2luZ2xlIG9yIHRyaXBsZSBkZXNcbiAgaWYgKGl0ZXJhdGlvbnMgPT0gMykge1xuICAgIGxvb3BpbmcgPSBlbmNyeXB0ID8gbmV3IEFycmF5KDAsIDMyLCAyKSA6IG5ldyBBcnJheSgzMCwgLTIsIC0yKTtcbiAgfSBlbHNlIHtcbiAgICBsb29waW5nID0gZW5jcnlwdCA/IG5ldyBBcnJheSgwLCAzMiwgMiwgNjIsIDMwLCAtMiwgNjQsIDk2LCAyKSA6IG5ldyBBcnJheSg5NCwgNjIsIC0yLCAzMiwgNjQsIDIsIDMwLCAtMiwgLTIpO1xuICB9XG5cbiAgLy9wYWQgdGhlIG1lc3NhZ2UgZGVwZW5kaW5nIG9uIHRoZSBwYWRkaW5nIHBhcmFtZXRlclxuICAvL29ubHkgYWRkIHBhZGRpbmcgaWYgZW5jcnlwdGluZyAtIG5vdGUgdGhhdCB5b3UgbmVlZCB0byB1c2UgdGhlIHNhbWUgcGFkZGluZyBvcHRpb24gZm9yIGJvdGggZW5jcnlwdCBhbmQgZGVjcnlwdFxuICBpZiAoZW5jcnlwdCkge1xuICAgIG1lc3NhZ2UgPSBkZXNfYWRkUGFkZGluZyhtZXNzYWdlLCBwYWRkaW5nKTtcbiAgICBsZW4gPSBtZXNzYWdlLmxlbmd0aDtcbiAgfVxuXG4gIC8vc3RvcmUgdGhlIHJlc3VsdCBoZXJlXG4gIHJlc3VsdCA9IFwiXCI7XG4gIHRlbXByZXN1bHQgPSBcIlwiO1xuXG4gIGlmIChtb2RlID09IDEpIHsgLy9DQkMgbW9kZVxuICAgIGNiY2xlZnQgPSAoaXYuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgMTYpIHwgKGl2LmNoYXJDb2RlQXQobSsrKSA8PCA4KSB8IGl2LmNoYXJDb2RlQXQobSsrKTtcbiAgICBjYmNyaWdodCA9IChpdi5jaGFyQ29kZUF0KG0rKykgPDwgMjQpIHwgKGl2LmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAoaXYuY2hhckNvZGVBdChtKyspIDw8IDgpIHwgaXYuY2hhckNvZGVBdChtKyspO1xuICAgIG0gPSAwO1xuICB9XG5cbiAgLy9sb29wIHRocm91Z2ggZWFjaCA2NCBiaXQgY2h1bmsgb2YgdGhlIG1lc3NhZ2VcbiAgd2hpbGUgKG0gPCBsZW4pIHtcbiAgICBsZWZ0ID0gKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfCBtZXNzYWdlXG4gICAgICAuY2hhckNvZGVBdChtKyspO1xuICAgIHJpZ2h0ID0gKG1lc3NhZ2UuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChtZXNzYWdlLmNoYXJDb2RlQXQobSsrKSA8PCAxNikgfCAobWVzc2FnZS5jaGFyQ29kZUF0KG0rKykgPDwgOCkgfFxuICAgICAgbWVzc2FnZS5jaGFyQ29kZUF0KG0rKyk7XG5cbiAgICAvL2ZvciBDaXBoZXIgQmxvY2sgQ2hhaW5pbmcgbW9kZSwgeG9yIHRoZSBtZXNzYWdlIHdpdGggdGhlIHByZXZpb3VzIHJlc3VsdFxuICAgIGlmIChtb2RlID09IDEpIHtcbiAgICAgIGlmIChlbmNyeXB0KSB7XG4gICAgICAgIGxlZnQgXj0gY2JjbGVmdDtcbiAgICAgICAgcmlnaHQgXj0gY2JjcmlnaHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYmNsZWZ0MiA9IGNiY2xlZnQ7XG4gICAgICAgIGNiY3JpZ2h0MiA9IGNiY3JpZ2h0O1xuICAgICAgICBjYmNsZWZ0ID0gbGVmdDtcbiAgICAgICAgY2JjcmlnaHQgPSByaWdodDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvL2ZpcnN0IGVhY2ggNjQgYnV0IGNodW5rIG9mIHRoZSBtZXNzYWdlIG11c3QgYmUgcGVybXV0ZWQgYWNjb3JkaW5nIHRvIElQXG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gNCkgXiByaWdodCkgJiAweDBmMGYwZjBmO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCA0KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxNikgXiByaWdodCkgJiAweDAwMDBmZmZmO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxNik7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzO1xuICAgIGxlZnQgXj0gdGVtcDtcbiAgICByaWdodCBePSAodGVtcCA8PCAyKTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IDgpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDEpIF4gcmlnaHQpICYgMHg1NTU1NTU1NTtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgMSk7XG5cbiAgICBsZWZ0ID0gKChsZWZ0IDw8IDEpIHwgKGxlZnQgPj4+IDMxKSk7XG4gICAgcmlnaHQgPSAoKHJpZ2h0IDw8IDEpIHwgKHJpZ2h0ID4+PiAzMSkpO1xuXG4gICAgLy9kbyB0aGlzIGVpdGhlciAxIG9yIDMgdGltZXMgZm9yIGVhY2ggY2h1bmsgb2YgdGhlIG1lc3NhZ2VcbiAgICBmb3IgKGogPSAwOyBqIDwgaXRlcmF0aW9uczsgaiArPSAzKSB7XG4gICAgICBlbmRsb29wID0gbG9vcGluZ1tqICsgMV07XG4gICAgICBsb29waW5jID0gbG9vcGluZ1tqICsgMl07XG4gICAgICAvL25vdyBnbyB0aHJvdWdoIGFuZCBwZXJmb3JtIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gIFxuICAgICAgZm9yIChpID0gbG9vcGluZ1tqXTsgaSAhPSBlbmRsb29wOyBpICs9IGxvb3BpbmMpIHsgLy9mb3IgZWZmaWNpZW5jeVxuICAgICAgICByaWdodDEgPSByaWdodCBeIGtleXNbaV07XG4gICAgICAgIHJpZ2h0MiA9ICgocmlnaHQgPj4+IDQpIHwgKHJpZ2h0IDw8IDI4KSkgXiBrZXlzW2kgKyAxXTtcbiAgICAgICAgLy90aGUgcmVzdWx0IGlzIGF0dGFpbmVkIGJ5IHBhc3NpbmcgdGhlc2UgYnl0ZXMgdGhyb3VnaCB0aGUgUyBzZWxlY3Rpb24gZnVuY3Rpb25zXG4gICAgICAgIHRlbXAgPSBsZWZ0O1xuICAgICAgICBsZWZ0ID0gcmlnaHQ7XG4gICAgICAgIHJpZ2h0ID0gdGVtcCBeIChzcGZ1bmN0aW9uMlsocmlnaHQxID4+PiAyNCkgJiAweDNmXSB8IHNwZnVuY3Rpb240WyhyaWdodDEgPj4+IDE2KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjZbKHJpZ2h0MSA+Pj5cbiAgICAgICAgICA4KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjhbcmlnaHQxICYgMHgzZl0gfCBzcGZ1bmN0aW9uMVsocmlnaHQyID4+PiAyNCkgJiAweDNmXSB8IHNwZnVuY3Rpb24zWyhyaWdodDIgPj4+IDE2KSAmXG4gICAgICAgICAgMHgzZl0gfCBzcGZ1bmN0aW9uNVsocmlnaHQyID4+PiA4KSAmIDB4M2ZdIHwgc3BmdW5jdGlvbjdbcmlnaHQyICYgMHgzZl0pO1xuICAgICAgfVxuICAgICAgdGVtcCA9IGxlZnQ7XG4gICAgICBsZWZ0ID0gcmlnaHQ7XG4gICAgICByaWdodCA9IHRlbXA7IC8vdW5yZXZlcnNlIGxlZnQgYW5kIHJpZ2h0XG4gICAgfSAvL2ZvciBlaXRoZXIgMSBvciAzIGl0ZXJhdGlvbnNcblxuICAgIC8vbW92ZSB0aGVuIGVhY2ggb25lIGJpdCB0byB0aGUgcmlnaHRcbiAgICBsZWZ0ID0gKChsZWZ0ID4+PiAxKSB8IChsZWZ0IDw8IDMxKSk7XG4gICAgcmlnaHQgPSAoKHJpZ2h0ID4+PiAxKSB8IChyaWdodCA8PCAzMSkpO1xuXG4gICAgLy9ub3cgcGVyZm9ybSBJUC0xLCB3aGljaCBpcyBJUCBpbiB0aGUgb3Bwb3NpdGUgZGlyZWN0aW9uXG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1O1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxKTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IDgpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiAyKSBeIGxlZnQpICYgMHgzMzMzMzMzMztcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgMik7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMTYpIF4gcmlnaHQpICYgMHgwMDAwZmZmZjtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgMTYpO1xuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDQpIF4gcmlnaHQpICYgMHgwZjBmMGYwZjtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgNCk7XG5cbiAgICAvL2ZvciBDaXBoZXIgQmxvY2sgQ2hhaW5pbmcgbW9kZSwgeG9yIHRoZSBtZXNzYWdlIHdpdGggdGhlIHByZXZpb3VzIHJlc3VsdFxuICAgIGlmIChtb2RlID09IDEpIHtcbiAgICAgIGlmIChlbmNyeXB0KSB7XG4gICAgICAgIGNiY2xlZnQgPSBsZWZ0O1xuICAgICAgICBjYmNyaWdodCA9IHJpZ2h0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGVmdCBePSBjYmNsZWZ0MjtcbiAgICAgICAgcmlnaHQgXj0gY2JjcmlnaHQyO1xuICAgICAgfVxuICAgIH1cbiAgICB0ZW1wcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGxlZnQgPj4+IDI0KSwgKChsZWZ0ID4+PiAxNikgJiAweGZmKSwgKChsZWZ0ID4+PiA4KSAmIDB4ZmYpLCAobGVmdCAmIDB4ZmYpLCAoXG4gICAgICByaWdodCA+Pj4gMjQpLCAoKHJpZ2h0ID4+PiAxNikgJiAweGZmKSwgKChyaWdodCA+Pj4gOCkgJiAweGZmKSwgKHJpZ2h0ICYgMHhmZikpO1xuXG4gICAgY2h1bmsgKz0gODtcbiAgICBpZiAoY2h1bmsgPT0gNTEyKSB7XG4gICAgICByZXN1bHQgKz0gdGVtcHJlc3VsdDtcbiAgICAgIHRlbXByZXN1bHQgPSBcIlwiO1xuICAgICAgY2h1bmsgPSAwO1xuICAgIH1cbiAgfSAvL2ZvciBldmVyeSA4IGNoYXJhY3RlcnMsIG9yIDY0IGJpdHMgaW4gdGhlIG1lc3NhZ2VcblxuICAvL3JldHVybiB0aGUgcmVzdWx0IGFzIGFuIGFycmF5XG4gIHJlc3VsdCArPSB0ZW1wcmVzdWx0O1xuXG4gIC8vb25seSByZW1vdmUgcGFkZGluZyBpZiBkZWNyeXB0aW5nIC0gbm90ZSB0aGF0IHlvdSBuZWVkIHRvIHVzZSB0aGUgc2FtZSBwYWRkaW5nIG9wdGlvbiBmb3IgYm90aCBlbmNyeXB0IGFuZCBkZWNyeXB0XG4gIGlmICghZW5jcnlwdCkge1xuICAgIHJlc3VsdCA9IGRlc19yZW1vdmVQYWRkaW5nKHJlc3VsdCwgcGFkZGluZyk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufSAvL2VuZCBvZiBkZXNcblxuXG5cbi8vZGVzX2NyZWF0ZUtleXNcbi8vdGhpcyB0YWtlcyBhcyBpbnB1dCBhIDY0IGJpdCBrZXkgKGV2ZW4gdGhvdWdoIG9ubHkgNTYgYml0cyBhcmUgdXNlZClcbi8vYXMgYW4gYXJyYXkgb2YgMiBpbnRlZ2VycywgYW5kIHJldHVybnMgMTYgNDggYml0IGtleXNcblxuZnVuY3Rpb24gZGVzX2NyZWF0ZUtleXMoa2V5KSB7XG4gIC8vZGVjbGFyaW5nIHRoaXMgbG9jYWxseSBzcGVlZHMgdGhpbmdzIHVwIGEgYml0XG4gIHBjMmJ5dGVzMCA9IG5ldyBBcnJheSgwLCAweDQsIDB4MjAwMDAwMDAsIDB4MjAwMDAwMDQsIDB4MTAwMDAsIDB4MTAwMDQsIDB4MjAwMTAwMDAsIDB4MjAwMTAwMDQsIDB4MjAwLCAweDIwNCxcbiAgICAweDIwMDAwMjAwLCAweDIwMDAwMjA0LCAweDEwMjAwLCAweDEwMjA0LCAweDIwMDEwMjAwLCAweDIwMDEwMjA0KTtcbiAgcGMyYnl0ZXMxID0gbmV3IEFycmF5KDAsIDB4MSwgMHgxMDAwMDAsIDB4MTAwMDAxLCAweDQwMDAwMDAsIDB4NDAwMDAwMSwgMHg0MTAwMDAwLCAweDQxMDAwMDEsIDB4MTAwLCAweDEwMSwgMHgxMDAxMDAsXG4gICAgMHgxMDAxMDEsIDB4NDAwMDEwMCwgMHg0MDAwMTAxLCAweDQxMDAxMDAsIDB4NDEwMDEwMSk7XG4gIHBjMmJ5dGVzMiA9IG5ldyBBcnJheSgwLCAweDgsIDB4ODAwLCAweDgwOCwgMHgxMDAwMDAwLCAweDEwMDAwMDgsIDB4MTAwMDgwMCwgMHgxMDAwODA4LCAwLCAweDgsIDB4ODAwLCAweDgwOCxcbiAgICAweDEwMDAwMDAsIDB4MTAwMDAwOCwgMHgxMDAwODAwLCAweDEwMDA4MDgpO1xuICBwYzJieXRlczMgPSBuZXcgQXJyYXkoMCwgMHgyMDAwMDAsIDB4ODAwMDAwMCwgMHg4MjAwMDAwLCAweDIwMDAsIDB4MjAyMDAwLCAweDgwMDIwMDAsIDB4ODIwMjAwMCwgMHgyMDAwMCwgMHgyMjAwMDAsXG4gICAgMHg4MDIwMDAwLCAweDgyMjAwMDAsIDB4MjIwMDAsIDB4MjIyMDAwLCAweDgwMjIwMDAsIDB4ODIyMjAwMCk7XG4gIHBjMmJ5dGVzNCA9IG5ldyBBcnJheSgwLCAweDQwMDAwLCAweDEwLCAweDQwMDEwLCAwLCAweDQwMDAwLCAweDEwLCAweDQwMDEwLCAweDEwMDAsIDB4NDEwMDAsIDB4MTAxMCwgMHg0MTAxMCwgMHgxMDAwLFxuICAgIDB4NDEwMDAsIDB4MTAxMCwgMHg0MTAxMCk7XG4gIHBjMmJ5dGVzNSA9IG5ldyBBcnJheSgwLCAweDQwMCwgMHgyMCwgMHg0MjAsIDAsIDB4NDAwLCAweDIwLCAweDQyMCwgMHgyMDAwMDAwLCAweDIwMDA0MDAsIDB4MjAwMDAyMCwgMHgyMDAwNDIwLFxuICAgIDB4MjAwMDAwMCwgMHgyMDAwNDAwLCAweDIwMDAwMjAsIDB4MjAwMDQyMCk7XG4gIHBjMmJ5dGVzNiA9IG5ldyBBcnJheSgwLCAweDEwMDAwMDAwLCAweDgwMDAwLCAweDEwMDgwMDAwLCAweDIsIDB4MTAwMDAwMDIsIDB4ODAwMDIsIDB4MTAwODAwMDIsIDAsIDB4MTAwMDAwMDAsXG4gICAgMHg4MDAwMCwgMHgxMDA4MDAwMCwgMHgyLCAweDEwMDAwMDAyLCAweDgwMDAyLCAweDEwMDgwMDAyKTtcbiAgcGMyYnl0ZXM3ID0gbmV3IEFycmF5KDAsIDB4MTAwMDAsIDB4ODAwLCAweDEwODAwLCAweDIwMDAwMDAwLCAweDIwMDEwMDAwLCAweDIwMDAwODAwLCAweDIwMDEwODAwLCAweDIwMDAwLCAweDMwMDAwLFxuICAgIDB4MjA4MDAsIDB4MzA4MDAsIDB4MjAwMjAwMDAsIDB4MjAwMzAwMDAsIDB4MjAwMjA4MDAsIDB4MjAwMzA4MDApO1xuICBwYzJieXRlczggPSBuZXcgQXJyYXkoMCwgMHg0MDAwMCwgMCwgMHg0MDAwMCwgMHgyLCAweDQwMDAyLCAweDIsIDB4NDAwMDIsIDB4MjAwMDAwMCwgMHgyMDQwMDAwLCAweDIwMDAwMDAsIDB4MjA0MDAwMCxcbiAgICAweDIwMDAwMDIsIDB4MjA0MDAwMiwgMHgyMDAwMDAyLCAweDIwNDAwMDIpO1xuICBwYzJieXRlczkgPSBuZXcgQXJyYXkoMCwgMHgxMDAwMDAwMCwgMHg4LCAweDEwMDAwMDA4LCAwLCAweDEwMDAwMDAwLCAweDgsIDB4MTAwMDAwMDgsIDB4NDAwLCAweDEwMDAwNDAwLCAweDQwOCxcbiAgICAweDEwMDAwNDA4LCAweDQwMCwgMHgxMDAwMDQwMCwgMHg0MDgsIDB4MTAwMDA0MDgpO1xuICBwYzJieXRlczEwID0gbmV3IEFycmF5KDAsIDB4MjAsIDAsIDB4MjAsIDB4MTAwMDAwLCAweDEwMDAyMCwgMHgxMDAwMDAsIDB4MTAwMDIwLCAweDIwMDAsIDB4MjAyMCwgMHgyMDAwLCAweDIwMjAsXG4gICAgMHgxMDIwMDAsIDB4MTAyMDIwLCAweDEwMjAwMCwgMHgxMDIwMjApO1xuICBwYzJieXRlczExID0gbmV3IEFycmF5KDAsIDB4MTAwMDAwMCwgMHgyMDAsIDB4MTAwMDIwMCwgMHgyMDAwMDAsIDB4MTIwMDAwMCwgMHgyMDAyMDAsIDB4MTIwMDIwMCwgMHg0MDAwMDAwLCAweDUwMDAwMDAsXG4gICAgMHg0MDAwMjAwLCAweDUwMDAyMDAsIDB4NDIwMDAwMCwgMHg1MjAwMDAwLCAweDQyMDAyMDAsIDB4NTIwMDIwMCk7XG4gIHBjMmJ5dGVzMTIgPSBuZXcgQXJyYXkoMCwgMHgxMDAwLCAweDgwMDAwMDAsIDB4ODAwMTAwMCwgMHg4MDAwMCwgMHg4MTAwMCwgMHg4MDgwMDAwLCAweDgwODEwMDAsIDB4MTAsIDB4MTAxMCxcbiAgICAweDgwMDAwMTAsIDB4ODAwMTAxMCwgMHg4MDAxMCwgMHg4MTAxMCwgMHg4MDgwMDEwLCAweDgwODEwMTApO1xuICBwYzJieXRlczEzID0gbmV3IEFycmF5KDAsIDB4NCwgMHgxMDAsIDB4MTA0LCAwLCAweDQsIDB4MTAwLCAweDEwNCwgMHgxLCAweDUsIDB4MTAxLCAweDEwNSwgMHgxLCAweDUsIDB4MTAxLCAweDEwNSk7XG5cbiAgLy9ob3cgbWFueSBpdGVyYXRpb25zICgxIGZvciBkZXMsIDMgZm9yIHRyaXBsZSBkZXMpXG4gIHZhciBpdGVyYXRpb25zID0ga2V5Lmxlbmd0aCA+IDggPyAzIDogMTsgLy9jaGFuZ2VkIGJ5IFBhdWwgMTYvNi8yMDA3IHRvIHVzZSBUcmlwbGUgREVTIGZvciA5KyBieXRlIGtleXNcbiAgLy9zdG9yZXMgdGhlIHJldHVybiBrZXlzXG4gIHZhciBrZXlzID0gbmV3IEFycmF5KDMyICogaXRlcmF0aW9ucyk7XG4gIC8vbm93IGRlZmluZSB0aGUgbGVmdCBzaGlmdHMgd2hpY2ggbmVlZCB0byBiZSBkb25lXG4gIHZhciBzaGlmdHMgPSBuZXcgQXJyYXkoMCwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMCk7XG4gIC8vb3RoZXIgdmFyaWFibGVzXG4gIHZhciBsZWZ0dGVtcCwgcmlnaHR0ZW1wLCBtID0gMCxcbiAgICBuID0gMCxcbiAgICB0ZW1wO1xuXG4gIGZvciAodmFyIGogPSAwOyBqIDwgaXRlcmF0aW9uczsgaisrKSB7IC8vZWl0aGVyIDEgb3IgMyBpdGVyYXRpb25zXG4gICAgbGVmdCA9IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDgpIHwga2V5LmNoYXJDb2RlQXQobSsrKTtcbiAgICByaWdodCA9IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDI0KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDE2KSB8IChrZXkuY2hhckNvZGVBdChtKyspIDw8IDgpIHwga2V5LmNoYXJDb2RlQXQobSsrKTtcblxuICAgIHRlbXAgPSAoKGxlZnQgPj4+IDQpIF4gcmlnaHQpICYgMHgwZjBmMGYwZjtcbiAgICByaWdodCBePSB0ZW1wO1xuICAgIGxlZnQgXj0gKHRlbXAgPDwgNCk7XG4gICAgdGVtcCA9ICgocmlnaHQgPj4+IC0xNikgXiBsZWZ0KSAmIDB4MDAwMGZmZmY7XG4gICAgbGVmdCBePSB0ZW1wO1xuICAgIHJpZ2h0IF49ICh0ZW1wIDw8IC0xNik7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMikgXiByaWdodCkgJiAweDMzMzMzMzMzO1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAyKTtcbiAgICB0ZW1wID0gKChyaWdodCA+Pj4gLTE2KSBeIGxlZnQpICYgMHgwMDAwZmZmZjtcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgLTE2KTtcbiAgICB0ZW1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7XG4gICAgcmlnaHQgXj0gdGVtcDtcbiAgICBsZWZ0IF49ICh0ZW1wIDw8IDEpO1xuICAgIHRlbXAgPSAoKHJpZ2h0ID4+PiA4KSBeIGxlZnQpICYgMHgwMGZmMDBmZjtcbiAgICBsZWZ0IF49IHRlbXA7XG4gICAgcmlnaHQgXj0gKHRlbXAgPDwgOCk7XG4gICAgdGVtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1O1xuICAgIHJpZ2h0IF49IHRlbXA7XG4gICAgbGVmdCBePSAodGVtcCA8PCAxKTtcblxuICAgIC8vdGhlIHJpZ2h0IHNpZGUgbmVlZHMgdG8gYmUgc2hpZnRlZCBhbmQgdG8gZ2V0IHRoZSBsYXN0IGZvdXIgYml0cyBvZiB0aGUgbGVmdCBzaWRlXG4gICAgdGVtcCA9IChsZWZ0IDw8IDgpIHwgKChyaWdodCA+Pj4gMjApICYgMHgwMDAwMDBmMCk7XG4gICAgLy9sZWZ0IG5lZWRzIHRvIGJlIHB1dCB1cHNpZGUgZG93blxuICAgIGxlZnQgPSAocmlnaHQgPDwgMjQpIHwgKChyaWdodCA8PCA4KSAmIDB4ZmYwMDAwKSB8ICgocmlnaHQgPj4+IDgpICYgMHhmZjAwKSB8ICgocmlnaHQgPj4+IDI0KSAmIDB4ZjApO1xuICAgIHJpZ2h0ID0gdGVtcDtcblxuICAgIC8vbm93IGdvIHRocm91Z2ggYW5kIHBlcmZvcm0gdGhlc2Ugc2hpZnRzIG9uIHRoZSBsZWZ0IGFuZCByaWdodCBrZXlzXG4gICAgZm9yIChpID0gMDsgaSA8IHNoaWZ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgLy9zaGlmdCB0aGUga2V5cyBlaXRoZXIgb25lIG9yIHR3byBiaXRzIHRvIHRoZSBsZWZ0XG4gICAgICBpZiAoc2hpZnRzW2ldKSB7XG4gICAgICAgIGxlZnQgPSAobGVmdCA8PCAyKSB8IChsZWZ0ID4+PiAyNik7XG4gICAgICAgIHJpZ2h0ID0gKHJpZ2h0IDw8IDIpIHwgKHJpZ2h0ID4+PiAyNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZWZ0ID0gKGxlZnQgPDwgMSkgfCAobGVmdCA+Pj4gMjcpO1xuICAgICAgICByaWdodCA9IChyaWdodCA8PCAxKSB8IChyaWdodCA+Pj4gMjcpO1xuICAgICAgfVxuICAgICAgbGVmdCAmPSAtMHhmO1xuICAgICAgcmlnaHQgJj0gLTB4ZjtcblxuICAgICAgLy9ub3cgYXBwbHkgUEMtMiwgaW4gc3VjaCBhIHdheSB0aGF0IEUgaXMgZWFzaWVyIHdoZW4gZW5jcnlwdGluZyBvciBkZWNyeXB0aW5nXG4gICAgICAvL3RoaXMgY29udmVyc2lvbiB3aWxsIGxvb2sgbGlrZSBQQy0yIGV4Y2VwdCBvbmx5IHRoZSBsYXN0IDYgYml0cyBvZiBlYWNoIGJ5dGUgYXJlIHVzZWRcbiAgICAgIC8vcmF0aGVyIHRoYW4gNDggY29uc2VjdXRpdmUgYml0cyBhbmQgdGhlIG9yZGVyIG9mIGxpbmVzIHdpbGwgYmUgYWNjb3JkaW5nIHRvIFxuICAgICAgLy9ob3cgdGhlIFMgc2VsZWN0aW9uIGZ1bmN0aW9ucyB3aWxsIGJlIGFwcGxpZWQ6IFMyLCBTNCwgUzYsIFM4LCBTMSwgUzMsIFM1LCBTN1xuICAgICAgbGVmdHRlbXAgPSBwYzJieXRlczBbbGVmdCA+Pj4gMjhdIHwgcGMyYnl0ZXMxWyhsZWZ0ID4+PiAyNCkgJiAweGZdIHwgcGMyYnl0ZXMyWyhsZWZ0ID4+PiAyMCkgJiAweGZdIHwgcGMyYnl0ZXMzWyhcbiAgICAgICAgbGVmdCA+Pj4gMTYpICYgMHhmXSB8IHBjMmJ5dGVzNFsobGVmdCA+Pj4gMTIpICYgMHhmXSB8IHBjMmJ5dGVzNVsobGVmdCA+Pj4gOCkgJiAweGZdIHwgcGMyYnl0ZXM2WyhsZWZ0ID4+PiA0KSAmXG4gICAgICAgIDB4Zl07XG4gICAgICByaWdodHRlbXAgPSBwYzJieXRlczdbcmlnaHQgPj4+IDI4XSB8IHBjMmJ5dGVzOFsocmlnaHQgPj4+IDI0KSAmIDB4Zl0gfCBwYzJieXRlczlbKHJpZ2h0ID4+PiAyMCkgJiAweGZdIHxcbiAgICAgICAgcGMyYnl0ZXMxMFsocmlnaHQgPj4+IDE2KSAmIDB4Zl0gfCBwYzJieXRlczExWyhyaWdodCA+Pj4gMTIpICYgMHhmXSB8IHBjMmJ5dGVzMTJbKHJpZ2h0ID4+PiA4KSAmIDB4Zl0gfFxuICAgICAgICBwYzJieXRlczEzWyhyaWdodCA+Pj4gNCkgJiAweGZdO1xuICAgICAgdGVtcCA9ICgocmlnaHR0ZW1wID4+PiAxNikgXiBsZWZ0dGVtcCkgJiAweDAwMDBmZmZmO1xuICAgICAga2V5c1tuKytdID0gbGVmdHRlbXAgXiB0ZW1wO1xuICAgICAga2V5c1tuKytdID0gcmlnaHR0ZW1wIF4gKHRlbXAgPDwgMTYpO1xuICAgIH1cbiAgfSAvL2ZvciBlYWNoIGl0ZXJhdGlvbnNcbiAgLy9yZXR1cm4gdGhlIGtleXMgd2UndmUgY3JlYXRlZFxuICByZXR1cm4ga2V5cztcbn0gLy9lbmQgb2YgZGVzX2NyZWF0ZUtleXNcblxuXG5mdW5jdGlvbiBkZXNfYWRkUGFkZGluZyhtZXNzYWdlLCBwYWRkaW5nKSB7XG4gIHZhciBwYWRMZW5ndGggPSA4IC0gKG1lc3NhZ2UubGVuZ3RoICUgOCk7XG4gIGlmICgocGFkZGluZyA9PSAyKSAmJiAocGFkTGVuZ3RoIDwgOCkpIHsgLy9wYWQgdGhlIG1lc3NhZ2Ugd2l0aCBzcGFjZXNcbiAgICBtZXNzYWdlICs9IFwiICAgICAgICBcIi5zdWJzdHIoMCwgcGFkTGVuZ3RoKTtcbiAgfSBlbHNlIGlmIChwYWRkaW5nID09IDEpIHsgLy9QS0NTNyBwYWRkaW5nXG4gICAgbWVzc2FnZSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHBhZExlbmd0aCwgcGFkTGVuZ3RoLCBwYWRMZW5ndGgsIHBhZExlbmd0aCwgcGFkTGVuZ3RoLCBwYWRMZW5ndGgsIHBhZExlbmd0aCxcbiAgICAgIHBhZExlbmd0aCkuc3Vic3RyKDAsIHBhZExlbmd0aCk7XG4gIH0gZWxzZSBpZiAoIXBhZGRpbmcgJiYgKHBhZExlbmd0aCA8IDgpKSB7IC8vcGFkIHRoZSBtZXNzYWdlIG91dCB3aXRoIG51bGwgYnl0ZXNcbiAgICBtZXNzYWdlICs9IFwiXFwwXFwwXFwwXFwwXFwwXFwwXFwwXFwwXCIuc3Vic3RyKDAsIHBhZExlbmd0aCk7XG4gIH1cbiAgcmV0dXJuIG1lc3NhZ2U7XG59XG5cbmZ1bmN0aW9uIGRlc19yZW1vdmVQYWRkaW5nKG1lc3NhZ2UsIHBhZGRpbmcpIHtcbiAgaWYgKHBhZGRpbmcgPT0gMikgeyAvLyBzcGFjZSBwYWRkZWRcbiAgICBtZXNzYWdlID0gbWVzc2FnZS5yZXBsYWNlKC8gKiQvZywgXCJcIik7XG4gIH0gZWxzZSBpZiAocGFkZGluZyA9PSAxKSB7IC8vIFBLQ1M3XG4gICAgdmFyIHBhZENvdW50ID0gbWVzc2FnZS5jaGFyQ29kZUF0KG1lc3NhZ2UubGVuZ3RoIC0gMSk7XG4gICAgbWVzc2FnZSA9IG1lc3NhZ2Uuc3Vic3RyKDAsIG1lc3NhZ2UubGVuZ3RoIC0gcGFkQ291bnQpO1xuICB9IGVsc2UgaWYgKCFwYWRkaW5nKSB7IC8vIG51bGwgcGFkZGluZ1xuICAgIG1lc3NhZ2UgPSBtZXNzYWdlLnJlcGxhY2UoL1xcMCokL2csIFwiXCIpO1xuICB9XG4gIHJldHVybiBtZXNzYWdlO1xufVxuXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbmZ1bmN0aW9uIERlcyhrZXkpIHtcbiAgdGhpcy5rZXkgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDM7IGkrKykge1xuICAgIHRoaXMua2V5LnB1c2goa2V5LnN1YnN0cihpICogOCwgOCkpO1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oYmxvY2spIHtcbiAgICByZXR1cm4gdXRpbC5zdHIyYmluKGRlcyhkZXNfY3JlYXRlS2V5cyh0aGlzLmtleVsyXSksXG4gICAgICBkZXMoZGVzX2NyZWF0ZUtleXModGhpcy5rZXlbMV0pLFxuICAgICAgZGVzKGRlc19jcmVhdGVLZXlzKHRoaXMua2V5WzBdKSxcbiAgICAgIHV0aWwuYmluMnN0cihibG9jayksIHRydWUsIDAsIG51bGwsIG51bGwpLFxuICAgICAgZmFsc2UsIDAsIG51bGwsIG51bGwpLCB0cnVlLCAwLCBudWxsLCBudWxsKSk7XG4gIH1cbn1cblxuRGVzLmtleVNpemUgPSBEZXMucHJvdG90eXBlLmtleVNpemUgPSAyNDtcbkRlcy5ibG9ja1NpemUgPSBEZXMucHJvdG90eXBlLmJsb2NrU2l6ZSA9IDg7XG5cbi8vIFRoaXMgaXMgXCJvcmlnaW5hbFwiIERFUyAtIERlcyBpcyBhY3R1YWxseSBUcmlwbGUgREVTLlxuLy8gVGhpcyBpcyBvbmx5IGV4cG9ydGVkIHNvIHdlIGNhbiB1bml0IHRlc3QuXG5cbmZ1bmN0aW9uIE9yaWdpbmFsRGVzKGtleSkge1xuICB0aGlzLmtleSA9IGtleTtcblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihibG9jaywgcGFkZGluZykge1xuICAgIHZhciBrZXlzID0gZGVzX2NyZWF0ZUtleXModGhpcy5rZXkpO1xuICAgIHJldHVybiB1dGlsLnN0cjJiaW4oZGVzKGtleXMsIHV0aWwuYmluMnN0cihibG9jayksIHRydWUsIDAsIG51bGwsIHBhZGRpbmcpKTtcbiAgfVxuXG4gIHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKGJsb2NrLCBwYWRkaW5nKSB7XG4gICAgdmFyIGtleXMgPSBkZXNfY3JlYXRlS2V5cyh0aGlzLmtleSk7XG4gICAgcmV0dXJuIHV0aWwuc3RyMmJpbihkZXMoa2V5cywgdXRpbC5iaW4yc3RyKGJsb2NrKSwgZmFsc2UsIDAsIG51bGwsIHBhZGRpbmcpKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZGVzOiBEZXMsXG4gIG9yaWdpbmFsRGVzOiBPcmlnaW5hbERlc1xufVxuIiwidmFyIGRlc01vZHVsZSA9IHJlcXVpcmUoJy4vZGVzLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBkZXM6IGRlc01vZHVsZVsnZGVzJ10sXG4gIG9yaWdpbmFsRGVzOiBkZXNNb2R1bGVbJ29yaWdpbmFsRGVzJ10sXG4gIGNhc3Q1OiByZXF1aXJlKCcuL2Nhc3Q1LmpzJyksXG4gIHR3b2Zpc2g6IHJlcXVpcmUoJy4vdHdvZmlzaC5qcycpLFxuICBibG93ZmlzaDogcmVxdWlyZSgnLi9ibG93ZmlzaC5qcycpXG59XG5cbnZhciBhZXMgPSByZXF1aXJlKCcuL2Flcy5qcycpO1xuXG5mb3IgKHZhciBpIGluIGFlcykge1xuICBtb2R1bGUuZXhwb3J0c1snYWVzJyArIGldID0gYWVzW2ldO1xufVxuIiwiLyogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIIFxuICogXG4gKiBDaXBoZXIuanNcbiAqIEEgYmxvY2stY2lwaGVyIGFsZ29yaXRobSBpbXBsZW1lbnRhdGlvbiBvbiBKYXZhU2NyaXB0XG4gKiBTZWUgQ2lwaGVyLnJlYWRtZS50eHQgZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uXG4gKlxuICogQ29weXJpZ2h0KGMpIDIwMDkgQXRzdXNoaSBPa2EgWyBodHRwOi8vb2thLm51LyBdXG4gKiBUaGlzIHNjcmlwdCBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMR1BMXG4gKlxuICogQUNLTk9XTEVER01FTlRcbiAqXG4gKiAgICAgVGhlIG1haW4gc3Vicm91dGluZXMgYXJlIHdyaXR0ZW4gYnkgTWljaGllbCB2YW4gRXZlcmRpbmdlbi5cbiAqIFxuICogICAgIE1pY2hpZWwgdmFuIEV2ZXJkaW5nZW5cbiAqICAgICBodHRwOi8vaG9tZS52ZXJzYXRlbC5ubC9NQXZhbkV2ZXJkaW5nZW4vaW5kZXguaHRtbFxuICogXG4gKiAgICAgQWxsIHJpZ2h0cyBmb3IgdGhlc2Ugcm91dGluZXMgYXJlIHJlc2VydmVkIHRvIE1pY2hpZWwgdmFuIEV2ZXJkaW5nZW4uXG4gKlxuICovXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vTWF0aFxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbnZhciBNQVhJTlQgPSAweEZGRkZGRkZGO1xuXG5mdW5jdGlvbiByb3RiKGIsIG4pIHtcbiAgcmV0dXJuIChiIDw8IG4gfCBiID4+PiAoOCAtIG4pKSAmIDB4RkY7XG59XG5cbmZ1bmN0aW9uIHJvdHcodywgbikge1xuICByZXR1cm4gKHcgPDwgbiB8IHcgPj4+ICgzMiAtIG4pKSAmIE1BWElOVDtcbn1cblxuZnVuY3Rpb24gZ2V0VyhhLCBpKSB7XG4gIHJldHVybiBhW2ldIHwgYVtpICsgMV0gPDwgOCB8IGFbaSArIDJdIDw8IDE2IHwgYVtpICsgM10gPDwgMjQ7XG59XG5cbmZ1bmN0aW9uIHNldFcoYSwgaSwgdykge1xuICBhLnNwbGljZShpLCA0LCB3ICYgMHhGRiwgKHcgPj4+IDgpICYgMHhGRiwgKHcgPj4+IDE2KSAmIDB4RkYsICh3ID4+PiAyNCkgJiAweEZGKTtcbn1cblxuZnVuY3Rpb24gc2V0V0ludihhLCBpLCB3KSB7XG4gIGEuc3BsaWNlKGksIDQsICh3ID4+PiAyNCkgJiAweEZGLCAodyA+Pj4gMTYpICYgMHhGRiwgKHcgPj4+IDgpICYgMHhGRiwgdyAmIDB4RkYpO1xufVxuXG5mdW5jdGlvbiBnZXRCKHgsIG4pIHtcbiAgcmV0dXJuICh4ID4+PiAobiAqIDgpKSAmIDB4RkY7XG59XG5cbmZ1bmN0aW9uIGdldE5yQml0cyhpKSB7XG4gIHZhciBuID0gMDtcbiAgd2hpbGUgKGkgPiAwKSB7XG4gICAgbisrO1xuICAgIGkgPj4+PSAxO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG5mdW5jdGlvbiBnZXRNYXNrKG4pIHtcbiAgcmV0dXJuICgxIDw8IG4pIC0gMTtcbn1cblxuLy9hZGRlZCAyMDA4LzExLzEzIFhYWCBNVVNUIFVTRSBPTkUtV0FZIEhBU0ggRlVOQ1RJT04gRk9SIFNFQ1VSSVRZIFJFQVNPTlxuXG5mdW5jdGlvbiByYW5kQnl0ZSgpIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDI1Nik7XG59XG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBUd29maXNoXG4vLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNyZWF0ZVR3b2Zpc2goKSB7XG4gIC8vXG4gIHZhciBrZXlCeXRlcyA9IG51bGw7XG4gIHZhciBkYXRhQnl0ZXMgPSBudWxsO1xuICB2YXIgZGF0YU9mZnNldCA9IC0xO1xuICAvLyB2YXIgZGF0YUxlbmd0aCA9IC0xO1xuICB2YXIgYWxnb3JpdGhtTmFtZSA9IG51bGw7XG4gIC8vIHZhciBpZHgyID0gLTE7XG4gIC8vXG5cbiAgYWxnb3JpdGhtTmFtZSA9IFwidHdvZmlzaFwiO1xuXG4gIHZhciB0ZnNLZXkgPSBbXTtcbiAgdmFyIHRmc00gPSBbXG4gICAgW10sXG4gICAgW10sXG4gICAgW10sXG4gICAgW11cbiAgXTtcblxuICBmdW5jdGlvbiB0ZnNJbml0KGtleSkge1xuICAgIGtleUJ5dGVzID0ga2V5O1xuICAgIHZhciBpLCBhLCBiLCBjLCBkLCBtZUtleSA9IFtdLFxuICAgICAgbW9LZXkgPSBbXSxcbiAgICAgIGluS2V5ID0gW107XG4gICAgdmFyIGtMZW47XG4gICAgdmFyIHNLZXkgPSBbXTtcbiAgICB2YXIgZjAxLCBmNWIsIGZlZjtcblxuICAgIHZhciBxMCA9IFtcbiAgICAgIFs4LCAxLCA3LCAxMywgNiwgMTUsIDMsIDIsIDAsIDExLCA1LCA5LCAxNCwgMTIsIDEwLCA0XSxcbiAgICAgIFsyLCA4LCAxMSwgMTMsIDE1LCA3LCA2LCAxNCwgMywgMSwgOSwgNCwgMCwgMTAsIDEyLCA1XVxuICAgIF07XG4gICAgdmFyIHExID0gW1xuICAgICAgWzE0LCAxMiwgMTEsIDgsIDEsIDIsIDMsIDUsIDE1LCA0LCAxMCwgNiwgNywgMCwgOSwgMTNdLFxuICAgICAgWzEsIDE0LCAyLCAxMSwgNCwgMTIsIDMsIDcsIDYsIDEzLCAxMCwgNSwgMTUsIDksIDAsIDhdXG4gICAgXTtcbiAgICB2YXIgcTIgPSBbXG4gICAgICBbMTEsIDEwLCA1LCAxNCwgNiwgMTMsIDksIDAsIDEyLCA4LCAxNSwgMywgMiwgNCwgNywgMV0sXG4gICAgICBbNCwgMTIsIDcsIDUsIDEsIDYsIDksIDEwLCAwLCAxNCwgMTMsIDgsIDIsIDExLCAzLCAxNV1cbiAgICBdO1xuICAgIHZhciBxMyA9IFtcbiAgICAgIFsxMywgNywgMTUsIDQsIDEsIDIsIDYsIDE0LCA5LCAxMSwgMywgMCwgOCwgNSwgMTIsIDEwXSxcbiAgICAgIFsxMSwgOSwgNSwgMSwgMTIsIDMsIDEzLCAxNCwgNiwgNCwgNywgMTUsIDIsIDAsIDgsIDEwXVxuICAgIF07XG4gICAgdmFyIHJvcjQgPSBbMCwgOCwgMSwgOSwgMiwgMTAsIDMsIDExLCA0LCAxMiwgNSwgMTMsIDYsIDE0LCA3LCAxNV07XG4gICAgdmFyIGFzaHggPSBbMCwgOSwgMiwgMTEsIDQsIDEzLCA2LCAxNSwgOCwgMSwgMTAsIDMsIDEyLCA1LCAxNCwgN107XG4gICAgdmFyIHEgPSBbXG4gICAgICBbXSxcbiAgICAgIFtdXG4gICAgXTtcbiAgICB2YXIgbSA9IFtcbiAgICAgIFtdLFxuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdXG4gICAgXTtcblxuICAgIGZ1bmN0aW9uIGZmbTViKHgpIHtcbiAgICAgIHJldHVybiB4IF4gKHggPj4gMikgXiBbMCwgOTAsIDE4MCwgMjM4XVt4ICYgM107XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmZtRWYoeCkge1xuICAgICAgcmV0dXJuIHggXiAoeCA+PiAxKSBeICh4ID4+IDIpIF4gWzAsIDIzOCwgMTgwLCA5MF1beCAmIDNdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1kc1JlbShwLCBxKSB7XG4gICAgICB2YXIgaSwgdCwgdTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHtcbiAgICAgICAgdCA9IHEgPj4+IDI0O1xuICAgICAgICBxID0gKChxIDw8IDgpICYgTUFYSU5UKSB8IHAgPj4+IDI0O1xuICAgICAgICBwID0gKHAgPDwgOCkgJiBNQVhJTlQ7XG4gICAgICAgIHUgPSB0IDw8IDE7XG4gICAgICAgIGlmICh0ICYgMTI4KSB7XG4gICAgICAgICAgdSBePSAzMzM7XG4gICAgICAgIH1cbiAgICAgICAgcSBePSB0IF4gKHUgPDwgMTYpO1xuICAgICAgICB1IF49IHQgPj4+IDE7XG4gICAgICAgIGlmICh0ICYgMSkge1xuICAgICAgICAgIHUgXj0gMTY2O1xuICAgICAgICB9XG4gICAgICAgIHEgXj0gdSA8PCAyNCB8IHUgPDwgODtcbiAgICAgIH1cbiAgICAgIHJldHVybiBxO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHFwKG4sIHgpIHtcbiAgICAgIHZhciBhLCBiLCBjLCBkO1xuICAgICAgYSA9IHggPj4gNDtcbiAgICAgIGIgPSB4ICYgMTU7XG4gICAgICBjID0gcTBbbl1bYSBeIGJdO1xuICAgICAgZCA9IHExW25dW3JvcjRbYl0gXiBhc2h4W2FdXTtcbiAgICAgIHJldHVybiBxM1tuXVtyb3I0W2RdIF4gYXNoeFtjXV0gPDwgNCB8IHEyW25dW2MgXiBkXTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoRnVuKHgsIGtleSkge1xuICAgICAgdmFyIGEgPSBnZXRCKHgsIDApLFxuICAgICAgICBiID0gZ2V0Qih4LCAxKSxcbiAgICAgICAgYyA9IGdldEIoeCwgMiksXG4gICAgICAgIGQgPSBnZXRCKHgsIDMpO1xuICAgICAgc3dpdGNoIChrTGVuKSB7XG4gICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBhID0gcVsxXVthXSBeIGdldEIoa2V5WzNdLCAwKTtcbiAgICAgICAgICBiID0gcVswXVtiXSBeIGdldEIoa2V5WzNdLCAxKTtcbiAgICAgICAgICBjID0gcVswXVtjXSBeIGdldEIoa2V5WzNdLCAyKTtcbiAgICAgICAgICBkID0gcVsxXVtkXSBeIGdldEIoa2V5WzNdLCAzKTtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihrZXlbMl0sIDApO1xuICAgICAgICAgIGIgPSBxWzFdW2JdIF4gZ2V0QihrZXlbMl0sIDEpO1xuICAgICAgICAgIGMgPSBxWzBdW2NdIF4gZ2V0QihrZXlbMl0sIDIpO1xuICAgICAgICAgIGQgPSBxWzBdW2RdIF4gZ2V0QihrZXlbMl0sIDMpO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgYSA9IHFbMF1bcVswXVthXSBeIGdldEIoa2V5WzFdLCAwKV0gXiBnZXRCKGtleVswXSwgMCk7XG4gICAgICAgICAgYiA9IHFbMF1bcVsxXVtiXSBeIGdldEIoa2V5WzFdLCAxKV0gXiBnZXRCKGtleVswXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMV1bcVswXVtjXSBeIGdldEIoa2V5WzFdLCAyKV0gXiBnZXRCKGtleVswXSwgMik7XG4gICAgICAgICAgZCA9IHFbMV1bcVsxXVtkXSBeIGdldEIoa2V5WzFdLCAzKV0gXiBnZXRCKGtleVswXSwgMyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbVswXVthXSBeIG1bMV1bYl0gXiBtWzJdW2NdIF4gbVszXVtkXTtcbiAgICB9XG5cbiAgICBrZXlCeXRlcyA9IGtleUJ5dGVzLnNsaWNlKDAsIDMyKTtcbiAgICBpID0ga2V5Qnl0ZXMubGVuZ3RoO1xuICAgIHdoaWxlIChpICE9IDE2ICYmIGkgIT0gMjQgJiYgaSAhPSAzMilcbiAgICAgIGtleUJ5dGVzW2krK10gPSAwO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGtleUJ5dGVzLmxlbmd0aDsgaSArPSA0KSB7XG4gICAgICBpbktleVtpID4+IDJdID0gZ2V0VyhrZXlCeXRlcywgaSk7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgcVswXVtpXSA9IHFwKDAsIGkpO1xuICAgICAgcVsxXVtpXSA9IHFwKDEsIGkpO1xuICAgIH1cbiAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcbiAgICAgIGYwMSA9IHFbMV1baV07XG4gICAgICBmNWIgPSBmZm01YihmMDEpO1xuICAgICAgZmVmID0gZmZtRWYoZjAxKTtcbiAgICAgIG1bMF1baV0gPSBmMDEgKyAoZjViIDw8IDgpICsgKGZlZiA8PCAxNikgKyAoZmVmIDw8IDI0KTtcbiAgICAgIG1bMl1baV0gPSBmNWIgKyAoZmVmIDw8IDgpICsgKGYwMSA8PCAxNikgKyAoZmVmIDw8IDI0KTtcbiAgICAgIGYwMSA9IHFbMF1baV07XG4gICAgICBmNWIgPSBmZm01YihmMDEpO1xuICAgICAgZmVmID0gZmZtRWYoZjAxKTtcbiAgICAgIG1bMV1baV0gPSBmZWYgKyAoZmVmIDw8IDgpICsgKGY1YiA8PCAxNikgKyAoZjAxIDw8IDI0KTtcbiAgICAgIG1bM11baV0gPSBmNWIgKyAoZjAxIDw8IDgpICsgKGZlZiA8PCAxNikgKyAoZjViIDw8IDI0KTtcbiAgICB9XG5cbiAgICBrTGVuID0gaW5LZXkubGVuZ3RoIC8gMjtcbiAgICBmb3IgKGkgPSAwOyBpIDwga0xlbjsgaSsrKSB7XG4gICAgICBhID0gaW5LZXlbaSArIGldO1xuICAgICAgbWVLZXlbaV0gPSBhO1xuICAgICAgYiA9IGluS2V5W2kgKyBpICsgMV07XG4gICAgICBtb0tleVtpXSA9IGI7XG4gICAgICBzS2V5W2tMZW4gLSBpIC0gMV0gPSBtZHNSZW0oYSwgYik7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCA0MDsgaSArPSAyKSB7XG4gICAgICBhID0gMHgxMDEwMTAxICogaTtcbiAgICAgIGIgPSBhICsgMHgxMDEwMTAxO1xuICAgICAgYSA9IGhGdW4oYSwgbWVLZXkpO1xuICAgICAgYiA9IHJvdHcoaEZ1bihiLCBtb0tleSksIDgpO1xuICAgICAgdGZzS2V5W2ldID0gKGEgKyBiKSAmIE1BWElOVDtcbiAgICAgIHRmc0tleVtpICsgMV0gPSByb3R3KGEgKyAyICogYiwgOSk7XG4gICAgfVxuICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykge1xuICAgICAgYSA9IGIgPSBjID0gZCA9IGk7XG4gICAgICBzd2l0Y2ggKGtMZW4pIHtcbiAgICAgICAgY2FzZSA0OlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihzS2V5WzNdLCAwKTtcbiAgICAgICAgICBiID0gcVswXVtiXSBeIGdldEIoc0tleVszXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMF1bY10gXiBnZXRCKHNLZXlbM10sIDIpO1xuICAgICAgICAgIGQgPSBxWzFdW2RdIF4gZ2V0QihzS2V5WzNdLCAzKTtcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgIGEgPSBxWzFdW2FdIF4gZ2V0QihzS2V5WzJdLCAwKTtcbiAgICAgICAgICBiID0gcVsxXVtiXSBeIGdldEIoc0tleVsyXSwgMSk7XG4gICAgICAgICAgYyA9IHFbMF1bY10gXiBnZXRCKHNLZXlbMl0sIDIpO1xuICAgICAgICAgIGQgPSBxWzBdW2RdIF4gZ2V0QihzS2V5WzJdLCAzKTtcbiAgICAgICAgY2FzZSAyOlxuICAgICAgICAgIHRmc01bMF1baV0gPSBtWzBdW3FbMF1bcVswXVthXSBeIGdldEIoc0tleVsxXSwgMCldIF4gZ2V0QihzS2V5WzBdLCAwKV07XG4gICAgICAgICAgdGZzTVsxXVtpXSA9IG1bMV1bcVswXVtxWzFdW2JdIF4gZ2V0QihzS2V5WzFdLCAxKV0gXiBnZXRCKHNLZXlbMF0sIDEpXTtcbiAgICAgICAgICB0ZnNNWzJdW2ldID0gbVsyXVtxWzFdW3FbMF1bY10gXiBnZXRCKHNLZXlbMV0sIDIpXSBeIGdldEIoc0tleVswXSwgMildO1xuICAgICAgICAgIHRmc01bM11baV0gPSBtWzNdW3FbMV1bcVsxXVtkXSBeIGdldEIoc0tleVsxXSwgMyldIF4gZ2V0QihzS2V5WzBdLCAzKV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdGZzRzAoeCkge1xuICAgIHJldHVybiB0ZnNNWzBdW2dldEIoeCwgMCldIF4gdGZzTVsxXVtnZXRCKHgsIDEpXSBeIHRmc01bMl1bZ2V0Qih4LCAyKV0gXiB0ZnNNWzNdW2dldEIoeCwgMyldO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRzEoeCkge1xuICAgIHJldHVybiB0ZnNNWzBdW2dldEIoeCwgMyldIF4gdGZzTVsxXVtnZXRCKHgsIDApXSBeIHRmc01bMl1bZ2V0Qih4LCAxKV0gXiB0ZnNNWzNdW2dldEIoeCwgMildO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRnJuZChyLCBibGspIHtcbiAgICB2YXIgYSA9IHRmc0cwKGJsa1swXSk7XG4gICAgdmFyIGIgPSB0ZnNHMShibGtbMV0pO1xuICAgIGJsa1syXSA9IHJvdHcoYmxrWzJdIF4gKGEgKyBiICsgdGZzS2V5WzQgKiByICsgOF0pICYgTUFYSU5ULCAzMSk7XG4gICAgYmxrWzNdID0gcm90dyhibGtbM10sIDEpIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogciArIDldKSAmIE1BWElOVDtcbiAgICBhID0gdGZzRzAoYmxrWzJdKTtcbiAgICBiID0gdGZzRzEoYmxrWzNdKTtcbiAgICBibGtbMF0gPSByb3R3KGJsa1swXSBeIChhICsgYiArIHRmc0tleVs0ICogciArIDEwXSkgJiBNQVhJTlQsIDMxKTtcbiAgICBibGtbMV0gPSByb3R3KGJsa1sxXSwgMSkgXiAoYSArIDIgKiBiICsgdGZzS2V5WzQgKiByICsgMTFdKSAmIE1BWElOVDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRmc0lybmQoaSwgYmxrKSB7XG4gICAgdmFyIGEgPSB0ZnNHMChibGtbMF0pO1xuICAgIHZhciBiID0gdGZzRzEoYmxrWzFdKTtcbiAgICBibGtbMl0gPSByb3R3KGJsa1syXSwgMSkgXiAoYSArIGIgKyB0ZnNLZXlbNCAqIGkgKyAxMF0pICYgTUFYSU5UO1xuICAgIGJsa1szXSA9IHJvdHcoYmxrWzNdIF4gKGEgKyAyICogYiArIHRmc0tleVs0ICogaSArIDExXSkgJiBNQVhJTlQsIDMxKTtcbiAgICBhID0gdGZzRzAoYmxrWzJdKTtcbiAgICBiID0gdGZzRzEoYmxrWzNdKTtcbiAgICBibGtbMF0gPSByb3R3KGJsa1swXSwgMSkgXiAoYSArIGIgKyB0ZnNLZXlbNCAqIGkgKyA4XSkgJiBNQVhJTlQ7XG4gICAgYmxrWzFdID0gcm90dyhibGtbMV0gXiAoYSArIDIgKiBiICsgdGZzS2V5WzQgKiBpICsgOV0pICYgTUFYSU5ULCAzMSk7XG4gIH1cblxuICBmdW5jdGlvbiB0ZnNDbG9zZSgpIHtcbiAgICB0ZnNLZXkgPSBbXTtcbiAgICB0ZnNNID0gW1xuICAgICAgW10sXG4gICAgICBbXSxcbiAgICAgIFtdLFxuICAgICAgW11cbiAgICBdO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRW5jcnlwdChkYXRhLCBvZmZzZXQpIHtcbiAgICBkYXRhQnl0ZXMgPSBkYXRhO1xuICAgIGRhdGFPZmZzZXQgPSBvZmZzZXQ7XG4gICAgdmFyIGJsayA9IFtnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCkgXiB0ZnNLZXlbMF0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgNCkgXiB0ZnNLZXlbMV0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCkgXiB0ZnNLZXlbMl0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIpIF4gdGZzS2V5WzNdXG4gICAgXTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IDg7IGorKykge1xuICAgICAgdGZzRnJuZChqLCBibGspO1xuICAgIH1cbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCwgYmxrWzJdIF4gdGZzS2V5WzRdKTtcbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDQsIGJsa1szXSBeIHRmc0tleVs1XSk7XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA4LCBibGtbMF0gXiB0ZnNLZXlbNl0pO1xuICAgIHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIsIGJsa1sxXSBeIHRmc0tleVs3XSk7XG4gICAgZGF0YU9mZnNldCArPSAxNjtcbiAgICByZXR1cm4gZGF0YUJ5dGVzO1xuICB9XG5cbiAgZnVuY3Rpb24gdGZzRGVjcnlwdChkYXRhLCBvZmZzZXQpIHtcbiAgICBkYXRhQnl0ZXMgPSBkYXRhO1xuICAgIGRhdGFPZmZzZXQgPSBvZmZzZXQ7XG4gICAgdmFyIGJsayA9IFtnZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCkgXiB0ZnNLZXlbNF0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgNCkgXiB0ZnNLZXlbNV0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCkgXiB0ZnNLZXlbNl0sXG4gICAgICAgIGdldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgMTIpIF4gdGZzS2V5WzddXG4gICAgXTtcbiAgICBmb3IgKHZhciBqID0gNzsgaiA+PSAwOyBqLS0pIHtcbiAgICAgIHRmc0lybmQoaiwgYmxrKTtcbiAgICB9XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQsIGJsa1syXSBeIHRmc0tleVswXSk7XG4gICAgc2V0VyhkYXRhQnl0ZXMsIGRhdGFPZmZzZXQgKyA0LCBibGtbM10gXiB0ZnNLZXlbMV0pO1xuICAgIHNldFcoZGF0YUJ5dGVzLCBkYXRhT2Zmc2V0ICsgOCwgYmxrWzBdIF4gdGZzS2V5WzJdKTtcbiAgICBzZXRXKGRhdGFCeXRlcywgZGF0YU9mZnNldCArIDEyLCBibGtbMV0gXiB0ZnNLZXlbM10pO1xuICAgIGRhdGFPZmZzZXQgKz0gMTY7XG4gIH1cblxuICAvLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbiAgZnVuY3Rpb24gdGZzRmluYWwoKSB7XG4gICAgcmV0dXJuIGRhdGFCeXRlcztcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogXCJ0d29maXNoXCIsXG4gICAgYmxvY2tzaXplOiAxMjggLyA4LFxuICAgIG9wZW46IHRmc0luaXQsXG4gICAgY2xvc2U6IHRmc0Nsb3NlLFxuICAgIGVuY3J5cHQ6IHRmc0VuY3J5cHQsXG4gICAgZGVjcnlwdDogdGZzRGVjcnlwdCxcbiAgICAvLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG4gICAgZmluYWxpemU6IHRmc0ZpbmFsXG4gIH07XG59XG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG4vLyBhZGRlZCBieSBSZWN1cml0eSBMYWJzXG5cbmZ1bmN0aW9uIFRGZW5jcnlwdChibG9jaywga2V5KSB7XG4gIHZhciBibG9ja19jb3B5ID0gW10uY29uY2F0KGJsb2NrKTtcbiAgdmFyIHRmID0gY3JlYXRlVHdvZmlzaCgpO1xuICB0Zi5vcGVuKHV0aWwuc3RyMmJpbihrZXkpLCAwKTtcbiAgdmFyIHJlc3VsdCA9IHRmLmVuY3J5cHQoYmxvY2tfY29weSwgMCk7XG4gIHRmLmNsb3NlKCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIFRGKGtleSkge1xuICB0aGlzLnRmID0gY3JlYXRlVHdvZmlzaCgpO1xuICB0aGlzLnRmLm9wZW4odXRpbC5zdHIyYmluKGtleSksIDApO1xuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGJsb2NrKSB7XG4gICAgcmV0dXJuIHRoaXMudGYuZW5jcnlwdChbXS5jb25jYXQoYmxvY2spLCAwKTtcbiAgfVxufVxuXG5cbm1vZHVsZS5leHBvcnRzID0gVEY7XG5tb2R1bGUuZXhwb3J0cy5rZXlTaXplID0gVEYucHJvdG90eXBlLmtleVNpemUgPSAzMjtcbm1vZHVsZS5leHBvcnRzLmJsb2NrU2l6ZSA9IFRGLnByb3RvdHlwZS5ibG9ja1NpemUgPSAxNjtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBIFxuXG4vLyBUaGUgR1BHNEJyb3dzZXJzIGNyeXB0byBpbnRlcmZhY2VcblxudmFyIHJhbmRvbSA9IHJlcXVpcmUoJy4vcmFuZG9tLmpzJyksXG4gIGNpcGhlciA9IHJlcXVpcmUoJy4vY2lwaGVyJyksXG4gIHB1YmxpY0tleSA9IHJlcXVpcmUoJy4vcHVibGljX2tleScpLFxuICB0eXBlX21waSA9IHJlcXVpcmUoJy4uL3R5cGUvbXBpLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAvKipcbiAgICogRW5jcnlwdHMgZGF0YSB1c2luZyB0aGUgc3BlY2lmaWVkIHB1YmxpYyBrZXkgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG4gICAqIGFuZCB0aGUgc3BlY2lmaWVkIGFsZ29yaXRobS5cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIEFsZ29yaXRobSB0byBiZSB1c2VkIChTZWUgUkZDNDg4MCA5LjEpXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBwdWJsaWNNUElzIEFsZ29yaXRobSBkZXBlbmRlbnQgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnNcbiAgICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpfSBkYXRhIERhdGEgdG8gYmUgZW5jcnlwdGVkIGFzIE1QSVxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3R5cGVfbXBpW119IGlmIFJTQSBhbiBvcGVucGdwX3R5cGVfbXBpOyBcbiAgICogaWYgZWxnYW1hbCBlbmNyeXB0aW9uIGFuIGFycmF5IG9mIHR3byBvcGVucGdwX3R5cGVfbXBpIGlzIHJldHVybmVkOyBvdGhlcndpc2UgbnVsbFxuICAgKi9cbiAgcHVibGljS2V5RW5jcnlwdDogZnVuY3Rpb24oYWxnbywgcHVibGljTVBJcywgZGF0YSkge1xuICAgIHZhciByZXN1bHQgPSAoZnVuY3Rpb24oKSB7XG4gICAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgICAgICBjYXNlICdyc2FfZW5jcnlwdF9zaWduJzpcbiAgICAgICAgICB2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcbiAgICAgICAgICB2YXIgbiA9IHB1YmxpY01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIGUgPSBwdWJsaWNNUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBtID0gZGF0YS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICByZXR1cm4gW3JzYS5lbmNyeXB0KG0sIGUsIG4pXTtcblxuICAgICAgICBjYXNlICdlbGdhbWFsJzpcbiAgICAgICAgICB2YXIgZWxnYW1hbCA9IG5ldyBwdWJsaWNLZXkuZWxnYW1hbCgpO1xuICAgICAgICAgIHZhciBwID0gcHVibGljTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgZyA9IHB1YmxpY01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIHkgPSBwdWJsaWNNUElzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBtID0gZGF0YS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICByZXR1cm4gZWxnYW1hbC5lbmNyeXB0KG0sIGcsIHAsIHkpO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0pKCk7XG5cbiAgICByZXR1cm4gcmVzdWx0Lm1hcChmdW5jdGlvbihibikge1xuICAgICAgdmFyIG1waSA9IG5ldyB0eXBlX21waSgpO1xuICAgICAgbXBpLmZyb21CaWdJbnRlZ2VyKGJuKTtcbiAgICAgIHJldHVybiBtcGk7XG4gICAgfSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIGRhdGEgdXNpbmcgdGhlIHNwZWNpZmllZCBwdWJsaWMga2V5IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIG9mIHRoZSBwcml2YXRlIGtleSxcbiAgICogdGhlIHNwZWNpZmllZCBzZWNyZXRNUElzIG9mIHRoZSBwcml2YXRlIGtleSBhbmQgdGhlIHNwZWNpZmllZCBhbGdvcml0aG0uXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBbGdvcml0aG0gdG8gYmUgdXNlZCAoU2VlIFJGQzQ4ODAgOS4xKVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gcHVibGljTVBJcyBBbGdvcml0aG0gZGVwZW5kZW50IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICAgKiBvZiB0aGUgcHVibGljIGtleSBwYXJ0IG9mIHRoZSBwcml2YXRlIGtleVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGlbXX0gc2VjcmV0TVBJcyBBbGdvcml0aG0gZGVwZW5kZW50IG11bHRpcHJlY2lzaW9uIGludGVnZXJzIFxuICAgKiBvZiB0aGUgcHJpdmF0ZSBrZXkgdXNlZFxuICAgKiBAcGFyYW0ge29wZW5wZ3BfdHlwZV9tcGl9IGRhdGEgRGF0YSB0byBiZSBlbmNyeXB0ZWQgYXMgTVBJXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfdHlwZV9tcGl9IHJldHVybnMgYSBiaWcgaW50ZWdlciBjb250YWluaW5nIHRoZSBkZWNyeXB0ZWQgZGF0YTsgb3RoZXJ3aXNlIG51bGxcbiAgICovXG5cbiAgcHVibGljS2V5RGVjcnlwdDogZnVuY3Rpb24oYWxnbywga2V5SW50ZWdlcnMsIGRhdGFJbnRlZ2Vycykge1xuICAgIHZhciBibiA9IChmdW5jdGlvbigpIHtcbiAgICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgICBjYXNlICdyc2FfZW5jcnlwdF9zaWduJzpcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHQnOlxuICAgICAgICAgIHZhciByc2EgPSBuZXcgcHVibGljS2V5LnJzYSgpO1xuICAgICAgICAgIC8vIDAgYW5kIDEgYXJlIHRoZSBwdWJsaWMga2V5LlxuICAgICAgICAgIHZhciBkID0ga2V5SW50ZWdlcnNbMl0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIHAgPSBrZXlJbnRlZ2Vyc1szXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgcSA9IGtleUludGVnZXJzWzRdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciB1ID0ga2V5SW50ZWdlcnNbNV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIG0gPSBkYXRhSW50ZWdlcnNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgcmV0dXJuIHJzYS5kZWNyeXB0KG0sIGQsIHAsIHEsIHUpO1xuICAgICAgICBjYXNlICdlbGdhbWFsJzpcbiAgICAgICAgICB2YXIgZWxnYW1hbCA9IG5ldyBwdWJsaWNLZXkuZWxnYW1hbCgpO1xuICAgICAgICAgIHZhciB4ID0ga2V5SW50ZWdlcnNbM10udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgICAgdmFyIGMxID0gZGF0YUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHZhciBjMiA9IGRhdGFJbnRlZ2Vyc1sxXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgICB2YXIgcCA9IGtleUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICAgIHJldHVybiBlbGdhbWFsLmRlY3J5cHQoYzEsIGMyLCBwLCB4KTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgdmFyIHJlc3VsdCA9IG5ldyB0eXBlX21waSgpO1xuICAgIHJlc3VsdC5mcm9tQmlnSW50ZWdlcihibik7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcblxuICAvKiogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGludGVnZXJzIGNvbXByaXNpbmcgdGhlIHByaXZhdGUga2V5IG9mIGFuIGFsZ29yaXRobVxuICAgKiBAcGFyYW0ge29wZW5wZ3AucHVibGlja2V5fSBhbGdvIFRoZSBwdWJsaWMga2V5IGFsZ29yaXRobVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBUaGUgbnVtYmVyIG9mIGludGVnZXJzLlxuICAgKi9cbiAgZ2V0UHJpdmF0ZU1waUNvdW50OiBmdW5jdGlvbihhbGdvKSB7XG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlICdyc2FfZW5jcnlwdCc6XG4gICAgICBjYXNlICdyc2FfZW5jcnlwdF9zaWduJzpcbiAgICAgIGNhc2UgJ3JzYV9zaWduJzpcbiAgICAgICAgLy8gICBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBSU0Egc2VjcmV0IGtleXM6XG4gICAgICAgIC8vICAgLSBtdWx0aXByZWNpc2lvbiBpbnRlZ2VyIChNUEkpIG9mIFJTQSBzZWNyZXQgZXhwb25lbnQgZC5cbiAgICAgICAgLy8gICAtIE1QSSBvZiBSU0Egc2VjcmV0IHByaW1lIHZhbHVlIHAuXG4gICAgICAgIC8vICAgLSBNUEkgb2YgUlNBIHNlY3JldCBwcmltZSB2YWx1ZSBxIChwIDwgcSkuXG4gICAgICAgIC8vICAgLSBNUEkgb2YgdSwgdGhlIG11bHRpcGxpY2F0aXZlIGludmVyc2Ugb2YgcCwgbW9kIHEuXG4gICAgICAgIHJldHVybiA0O1xuICAgICAgY2FzZSAnZWxnYW1hbCc6XG4gICAgICAgIC8vIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIEVsZ2FtYWwgc2VjcmV0IGtleXM6XG4gICAgICAgIC8vICAgLSBNUEkgb2YgRWxnYW1hbCBzZWNyZXQgZXhwb25lbnQgeC5cbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICBjYXNlICdkc2EnOlxuICAgICAgICAvLyBBbGdvcml0aG0tU3BlY2lmaWMgRmllbGRzIGZvciBEU0Egc2VjcmV0IGtleXM6XG4gICAgICAgIC8vICAgLSBNUEkgb2YgRFNBIHNlY3JldCBleHBvbmVudCB4LlxuICAgICAgICByZXR1cm4gMTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBhbGdvcml0aG0nKTtcbiAgICB9XG4gIH0sXG5cbiAgZ2V0UHVibGljTXBpQ291bnQ6IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICAvLyAtIEEgc2VyaWVzIG9mIG11bHRpcHJlY2lzaW9uIGludGVnZXJzIGNvbXByaXNpbmcgdGhlIGtleSBtYXRlcmlhbDpcbiAgICAvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBwdWJsaWMga2V5czpcbiAgICAvLyAgICAgICAtIGEgbXVsdGlwcmVjaXNpb24gaW50ZWdlciAoTVBJKSBvZiBSU0EgcHVibGljIG1vZHVsdXMgbjtcbiAgICAvLyAgICAgICAtIGFuIE1QSSBvZiBSU0EgcHVibGljIGVuY3J5cHRpb24gZXhwb25lbnQgZS5cbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0X3NpZ24nOlxuICAgICAgY2FzZSAncnNhX3NpZ24nOlxuICAgICAgICByZXR1cm4gMjtcblxuICAgICAgICAvLyAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIEVsZ2FtYWwgcHVibGljIGtleXM6XG4gICAgICAgIC8vICAgICAtIE1QSSBvZiBFbGdhbWFsIHByaW1lIHA7XG4gICAgICAgIC8vICAgICAtIE1QSSBvZiBFbGdhbWFsIGdyb3VwIGdlbmVyYXRvciBnO1xuICAgICAgICAvLyAgICAgLSBNUEkgb2YgRWxnYW1hbCBwdWJsaWMga2V5IHZhbHVlIHkgKD0gZyoqeCBtb2QgcCB3aGVyZSB4ICBpcyBzZWNyZXQpLlxuICAgICAgY2FzZSAnZWxnYW1hbCc6XG4gICAgICAgIHJldHVybiAzO1xuXG4gICAgICAgIC8vICAgQWxnb3JpdGhtLVNwZWNpZmljIEZpZWxkcyBmb3IgRFNBIHB1YmxpYyBrZXlzOlxuICAgICAgICAvLyAgICAgICAtIE1QSSBvZiBEU0EgcHJpbWUgcDtcbiAgICAgICAgLy8gICAgICAgLSBNUEkgb2YgRFNBIGdyb3VwIG9yZGVyIHEgKHEgaXMgYSBwcmltZSBkaXZpc29yIG9mIHAtMSk7XG4gICAgICAgIC8vICAgICAgIC0gTVBJIG9mIERTQSBncm91cCBnZW5lcmF0b3IgZztcbiAgICAgICAgLy8gICAgICAgLSBNUEkgb2YgRFNBIHB1YmxpYy1rZXkgdmFsdWUgeSAoPSBnKip4IG1vZCBwIHdoZXJlIHggIGlzIHNlY3JldCkuXG4gICAgICBjYXNlICdkc2EnOlxuICAgICAgICByZXR1cm4gNDtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGFsZ29yaXRobS4nKTtcbiAgICB9XG4gIH0sXG5cbiAgZ2VuZXJhdGVNcGk6IGZ1bmN0aW9uKGFsZ28sIGJpdHMpIHtcbiAgICB2YXIgcmVzdWx0ID0gKGZ1bmN0aW9uKCkge1xuICAgICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0JzpcbiAgICAgICAgY2FzZSAncnNhX2VuY3J5cHRfc2lnbic6XG4gICAgICAgIGNhc2UgJ3JzYV9zaWduJzpcbiAgICAgICAgICAvL3JlbWVtYmVyIFwicHVibGljS2V5XCIgcmVmZXJzIHRvIHRoZSBjcnlwdG8vcHVibGljX2tleSBkaXJcbiAgICAgICAgICB2YXIgcnNhID0gbmV3IHB1YmxpY0tleS5yc2EoKTtcbiAgICAgICAgICB2YXIga2V5T2JqZWN0ID0gcnNhLmdlbmVyYXRlKGJpdHMsIFwiMTAwMDFcIik7XG4gICAgICAgICAgdmFyIG91dHB1dCA9IFtdO1xuICAgICAgICAgIG91dHB1dC5wdXNoKGtleU9iamVjdC5uKTtcbiAgICAgICAgICBvdXRwdXQucHVzaChrZXlPYmplY3QuZWUpO1xuICAgICAgICAgIG91dHB1dC5wdXNoKGtleU9iamVjdC5kKTtcbiAgICAgICAgICBvdXRwdXQucHVzaChrZXlPYmplY3QucCk7XG4gICAgICAgICAgb3V0cHV0LnB1c2goa2V5T2JqZWN0LnEpO1xuICAgICAgICAgIG91dHB1dC5wdXNoKGtleU9iamVjdC51KTtcbiAgICAgICAgICByZXR1cm4gb3V0cHV0O1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgYWxnb3JpdGhtIGZvciBrZXkgZ2VuZXJhdGlvbi4nKTtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgcmV0dXJuIHJlc3VsdC5tYXAoZnVuY3Rpb24oYm4pIHtcbiAgICAgIHZhciBtcGkgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICAgIG1waS5mcm9tQmlnSW50ZWdlcihibik7XG4gICAgICByZXR1cm4gbXBpO1xuICAgIH0pO1xuICB9LFxuXG5cbiAgLyoqXG4gICAqIGdlbmVyYXRlIHJhbmRvbSBieXRlIHByZWZpeCBhcyBzdHJpbmcgZm9yIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBbGdvcml0aG0gdG8gdXNlIChzZWUgUkZDNDg4MCA5LjIpXG4gICAqIEByZXR1cm4ge1N0cmluZ30gUmFuZG9tIGJ5dGVzIHdpdGggbGVuZ3RoIGVxdWFsIHRvIHRoZSBibG9ja1xuICAgKiBzaXplIG9mIHRoZSBjaXBoZXJcbiAgICovXG4gIGdldFByZWZpeFJhbmRvbTogZnVuY3Rpb24oYWxnbykge1xuICAgIHJldHVybiByYW5kb20uZ2V0UmFuZG9tQnl0ZXMoY2lwaGVyW2FsZ29dLmJsb2NrU2l6ZSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdlbmVyYXRpbmcgYSBzZXNzaW9uIGtleSBmb3IgdGhlIHNwZWNpZmllZCBzeW1tZXRyaWMgYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBbGdvcml0aG0gdG8gdXNlIChzZWUgUkZDNDg4MCA5LjIpXG4gICAqIEByZXR1cm4ge1N0cmluZ30gUmFuZG9tIGJ5dGVzIGFzIGEgc3RyaW5nIHRvIGJlIHVzZWQgYXMgYSBrZXlcbiAgICovXG4gIGdlbmVyYXRlU2Vzc2lvbktleTogZnVuY3Rpb24oYWxnbykge1xuICAgIHJldHVybiByYW5kb20uZ2V0UmFuZG9tQnl0ZXMoY2lwaGVyW2FsZ29dLmtleVNpemUpO1xuICB9LFxuXG59O1xuIiwidmFyIHNoYSA9IHJlcXVpcmUoJy4vc2hhLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtZDU6IHJlcXVpcmUoJy4vbWQ1LmpzJyksXG4gIHNoYTE6IHNoYS5zaGExLFxuICBzaGEyNTY6IHNoYS5zaGEyNTYsXG4gIHNoYTIyNDogc2hhLnNoYTIyNCxcbiAgc2hhMzg0OiBzaGEuc2hhMzg0LFxuICBzaGE1MTI6IHNoYS5zaGE1MTIsXG4gIHJpcGVtZDogcmVxdWlyZSgnLi9yaXBlLW1kLmpzJyksXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGhhc2ggb24gdGhlIHNwZWNpZmllZCBkYXRhIHVzaW5nIHRoZSBzcGVjaWZpZWQgYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBIYXNoIGFsZ29yaXRobSB0eXBlIChzZWUgUkZDNDg4MCA5LjQpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgaGFzaGVkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gaGFzaCB2YWx1ZVxuICAgKi9cbiAgZGlnZXN0OiBmdW5jdGlvbihhbGdvLCBkYXRhKSB7XG4gICAgc3dpdGNoIChhbGdvKSB7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIC8vIC0gTUQ1IFtIQUNdXG4gICAgICAgIHJldHVybiB0aGlzLm1kNShkYXRhKTtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gLSBTSEEtMSBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2hhMShkYXRhKTtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgLy8gLSBSSVBFLU1ELzE2MCBbSEFDXVxuICAgICAgICByZXR1cm4gdGhpcy5yaXBlbWQoZGF0YSk7XG4gICAgICBjYXNlIDg6XG4gICAgICAgIC8vIC0gU0hBMjU2IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gdGhpcy5zaGEyNTYoZGF0YSk7XG4gICAgICBjYXNlIDk6XG4gICAgICAgIC8vIC0gU0hBMzg0IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gdGhpcy5zaGEzODQoZGF0YSk7XG4gICAgICBjYXNlIDEwOlxuICAgICAgICAvLyAtIFNIQTUxMiBbRklQUzE4MF1cbiAgICAgICAgcmV0dXJuIHRoaXMuc2hhNTEyKGRhdGEpO1xuICAgICAgY2FzZSAxMTpcbiAgICAgICAgLy8gLSBTSEEyMjQgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiB0aGlzLnNoYTIyNChkYXRhKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoYXNoIGZ1bmN0aW9uLicpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgaGFzaCBzaXplIGluIGJ5dGVzIG9mIHRoZSBzcGVjaWZpZWQgaGFzaCBhbGdvcml0aG0gdHlwZVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGFsZ28gSGFzaCBhbGdvcml0aG0gdHlwZSAoU2VlIFJGQzQ4ODAgOS40KVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBTaXplIGluIGJ5dGVzIG9mIHRoZSByZXN1bHRpbmcgaGFzaFxuICAgKi9cbiAgZ2V0SGFzaEJ5dGVMZW5ndGg6IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgLy8gLSBNRDUgW0hBQ11cbiAgICAgICAgcmV0dXJuIDE2O1xuICAgICAgY2FzZSAyOlxuICAgICAgICAvLyAtIFNIQS0xIFtGSVBTMTgwXVxuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyAtIFJJUEUtTUQvMTYwIFtIQUNdXG4gICAgICAgIHJldHVybiAyMDtcbiAgICAgIGNhc2UgODpcbiAgICAgICAgLy8gLSBTSEEyNTYgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiAzMjtcbiAgICAgIGNhc2UgOTpcbiAgICAgICAgLy8gLSBTSEEzODQgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiA0OFxuICAgICAgY2FzZSAxMDpcbiAgICAgICAgLy8gLSBTSEE1MTIgW0ZJUFMxODBdXG4gICAgICAgIHJldHVybiA2NDtcbiAgICAgIGNhc2UgMTE6XG4gICAgICAgIC8vIC0gU0hBMjI0IFtGSVBTMTgwXVxuICAgICAgICByZXR1cm4gMjg7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGFzaCBhbGdvcml0aG0uJyk7XG4gICAgfVxuICB9XG5cbn1cbiIsIi8qKlxuICogQSBmYXN0IE1ENSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTIgSm9zZXBoIE15ZXJzXG4gKiBodHRwOi8vd3d3Lm15ZXJzZGFpbHkub3JnL2pvc2VwaC9qYXZhc2NyaXB0L21kNS10ZXh0Lmh0bWxcbiAqXG4gKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlXG4gKiBhbmQgaXRzIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlcyBhbmQgd2l0aG91dFxuICogZmVlIGlzIGhlcmVieSBncmFudGVkIHByb3ZpZGVkIHRoYXQgdGhpcyBjb3B5cmlnaHQgbm90aWNlXG4gKiBhcHBlYXJzIGluIGFsbCBjb3BpZXMuXG4gKlxuICogT2YgY291cnNlLCB0aGlzIHNvZnQgaXMgcHJvdmlkZWQgXCJhcyBpc1wiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkXG4gKiB3YXJyYW50eSBvZiBhbnkga2luZC5cbiAqL1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwvdXRpbC5qcycpO1xuXG5mdW5jdGlvbiBNRDUoZW50cmVlKSB7XG4gIHZhciBoZXggPSBtZDUoZW50cmVlKTtcbiAgdmFyIGJpbiA9IHV0aWwuaGV4MmJpbihoZXgpO1xuICByZXR1cm4gYmluO1xufVxuXG5mdW5jdGlvbiBtZDVjeWNsZSh4LCBrKSB7XG4gIHZhciBhID0geFswXSxcbiAgICBiID0geFsxXSxcbiAgICBjID0geFsyXSxcbiAgICBkID0geFszXTtcblxuICBhID0gZmYoYSwgYiwgYywgZCwga1swXSwgNywgLTY4MDg3NjkzNik7XG4gIGQgPSBmZihkLCBhLCBiLCBjLCBrWzFdLCAxMiwgLTM4OTU2NDU4Nik7XG4gIGMgPSBmZihjLCBkLCBhLCBiLCBrWzJdLCAxNywgNjA2MTA1ODE5KTtcbiAgYiA9IGZmKGIsIGMsIGQsIGEsIGtbM10sIDIyLCAtMTA0NDUyNTMzMCk7XG4gIGEgPSBmZihhLCBiLCBjLCBkLCBrWzRdLCA3LCAtMTc2NDE4ODk3KTtcbiAgZCA9IGZmKGQsIGEsIGIsIGMsIGtbNV0sIDEyLCAxMjAwMDgwNDI2KTtcbiAgYyA9IGZmKGMsIGQsIGEsIGIsIGtbNl0sIDE3LCAtMTQ3MzIzMTM0MSk7XG4gIGIgPSBmZihiLCBjLCBkLCBhLCBrWzddLCAyMiwgLTQ1NzA1OTgzKTtcbiAgYSA9IGZmKGEsIGIsIGMsIGQsIGtbOF0sIDcsIDE3NzAwMzU0MTYpO1xuICBkID0gZmYoZCwgYSwgYiwgYywga1s5XSwgMTIsIC0xOTU4NDE0NDE3KTtcbiAgYyA9IGZmKGMsIGQsIGEsIGIsIGtbMTBdLCAxNywgLTQyMDYzKTtcbiAgYiA9IGZmKGIsIGMsIGQsIGEsIGtbMTFdLCAyMiwgLTE5OTA0MDQxNjIpO1xuICBhID0gZmYoYSwgYiwgYywgZCwga1sxMl0sIDcsIDE4MDQ2MDM2ODIpO1xuICBkID0gZmYoZCwgYSwgYiwgYywga1sxM10sIDEyLCAtNDAzNDExMDEpO1xuICBjID0gZmYoYywgZCwgYSwgYiwga1sxNF0sIDE3LCAtMTUwMjAwMjI5MCk7XG4gIGIgPSBmZihiLCBjLCBkLCBhLCBrWzE1XSwgMjIsIDEyMzY1MzUzMjkpO1xuXG4gIGEgPSBnZyhhLCBiLCBjLCBkLCBrWzFdLCA1LCAtMTY1Nzk2NTEwKTtcbiAgZCA9IGdnKGQsIGEsIGIsIGMsIGtbNl0sIDksIC0xMDY5NTAxNjMyKTtcbiAgYyA9IGdnKGMsIGQsIGEsIGIsIGtbMTFdLCAxNCwgNjQzNzE3NzEzKTtcbiAgYiA9IGdnKGIsIGMsIGQsIGEsIGtbMF0sIDIwLCAtMzczODk3MzAyKTtcbiAgYSA9IGdnKGEsIGIsIGMsIGQsIGtbNV0sIDUsIC03MDE1NTg2OTEpO1xuICBkID0gZ2coZCwgYSwgYiwgYywga1sxMF0sIDksIDM4MDE2MDgzKTtcbiAgYyA9IGdnKGMsIGQsIGEsIGIsIGtbMTVdLCAxNCwgLTY2MDQ3ODMzNSk7XG4gIGIgPSBnZyhiLCBjLCBkLCBhLCBrWzRdLCAyMCwgLTQwNTUzNzg0OCk7XG4gIGEgPSBnZyhhLCBiLCBjLCBkLCBrWzldLCA1LCA1Njg0NDY0MzgpO1xuICBkID0gZ2coZCwgYSwgYiwgYywga1sxNF0sIDksIC0xMDE5ODAzNjkwKTtcbiAgYyA9IGdnKGMsIGQsIGEsIGIsIGtbM10sIDE0LCAtMTg3MzYzOTYxKTtcbiAgYiA9IGdnKGIsIGMsIGQsIGEsIGtbOF0sIDIwLCAxMTYzNTMxNTAxKTtcbiAgYSA9IGdnKGEsIGIsIGMsIGQsIGtbMTNdLCA1LCAtMTQ0NDY4MTQ2Nyk7XG4gIGQgPSBnZyhkLCBhLCBiLCBjLCBrWzJdLCA5LCAtNTE0MDM3ODQpO1xuICBjID0gZ2coYywgZCwgYSwgYiwga1s3XSwgMTQsIDE3MzUzMjg0NzMpO1xuICBiID0gZ2coYiwgYywgZCwgYSwga1sxMl0sIDIwLCAtMTkyNjYwNzczNCk7XG5cbiAgYSA9IGhoKGEsIGIsIGMsIGQsIGtbNV0sIDQsIC0zNzg1NTgpO1xuICBkID0gaGgoZCwgYSwgYiwgYywga1s4XSwgMTEsIC0yMDIyNTc0NDYzKTtcbiAgYyA9IGhoKGMsIGQsIGEsIGIsIGtbMTFdLCAxNiwgMTgzOTAzMDU2Mik7XG4gIGIgPSBoaChiLCBjLCBkLCBhLCBrWzE0XSwgMjMsIC0zNTMwOTU1Nik7XG4gIGEgPSBoaChhLCBiLCBjLCBkLCBrWzFdLCA0LCAtMTUzMDk5MjA2MCk7XG4gIGQgPSBoaChkLCBhLCBiLCBjLCBrWzRdLCAxMSwgMTI3Mjg5MzM1Myk7XG4gIGMgPSBoaChjLCBkLCBhLCBiLCBrWzddLCAxNiwgLTE1NTQ5NzYzMik7XG4gIGIgPSBoaChiLCBjLCBkLCBhLCBrWzEwXSwgMjMsIC0xMDk0NzMwNjQwKTtcbiAgYSA9IGhoKGEsIGIsIGMsIGQsIGtbMTNdLCA0LCA2ODEyNzkxNzQpO1xuICBkID0gaGgoZCwgYSwgYiwgYywga1swXSwgMTEsIC0zNTg1MzcyMjIpO1xuICBjID0gaGgoYywgZCwgYSwgYiwga1szXSwgMTYsIC03MjI1MjE5NzkpO1xuICBiID0gaGgoYiwgYywgZCwgYSwga1s2XSwgMjMsIDc2MDI5MTg5KTtcbiAgYSA9IGhoKGEsIGIsIGMsIGQsIGtbOV0sIDQsIC02NDAzNjQ0ODcpO1xuICBkID0gaGgoZCwgYSwgYiwgYywga1sxMl0sIDExLCAtNDIxODE1ODM1KTtcbiAgYyA9IGhoKGMsIGQsIGEsIGIsIGtbMTVdLCAxNiwgNTMwNzQyNTIwKTtcbiAgYiA9IGhoKGIsIGMsIGQsIGEsIGtbMl0sIDIzLCAtOTk1MzM4NjUxKTtcblxuICBhID0gaWkoYSwgYiwgYywgZCwga1swXSwgNiwgLTE5ODYzMDg0NCk7XG4gIGQgPSBpaShkLCBhLCBiLCBjLCBrWzddLCAxMCwgMTEyNjg5MTQxNSk7XG4gIGMgPSBpaShjLCBkLCBhLCBiLCBrWzE0XSwgMTUsIC0xNDE2MzU0OTA1KTtcbiAgYiA9IGlpKGIsIGMsIGQsIGEsIGtbNV0sIDIxLCAtNTc0MzQwNTUpO1xuICBhID0gaWkoYSwgYiwgYywgZCwga1sxMl0sIDYsIDE3MDA0ODU1NzEpO1xuICBkID0gaWkoZCwgYSwgYiwgYywga1szXSwgMTAsIC0xODk0OTg2NjA2KTtcbiAgYyA9IGlpKGMsIGQsIGEsIGIsIGtbMTBdLCAxNSwgLTEwNTE1MjMpO1xuICBiID0gaWkoYiwgYywgZCwgYSwga1sxXSwgMjEsIC0yMDU0OTIyNzk5KTtcbiAgYSA9IGlpKGEsIGIsIGMsIGQsIGtbOF0sIDYsIDE4NzMzMTMzNTkpO1xuICBkID0gaWkoZCwgYSwgYiwgYywga1sxNV0sIDEwLCAtMzA2MTE3NDQpO1xuICBjID0gaWkoYywgZCwgYSwgYiwga1s2XSwgMTUsIC0xNTYwMTk4MzgwKTtcbiAgYiA9IGlpKGIsIGMsIGQsIGEsIGtbMTNdLCAyMSwgMTMwOTE1MTY0OSk7XG4gIGEgPSBpaShhLCBiLCBjLCBkLCBrWzRdLCA2LCAtMTQ1NTIzMDcwKTtcbiAgZCA9IGlpKGQsIGEsIGIsIGMsIGtbMTFdLCAxMCwgLTExMjAyMTAzNzkpO1xuICBjID0gaWkoYywgZCwgYSwgYiwga1syXSwgMTUsIDcxODc4NzI1OSk7XG4gIGIgPSBpaShiLCBjLCBkLCBhLCBrWzldLCAyMSwgLTM0MzQ4NTU1MSk7XG5cbiAgeFswXSA9IGFkZDMyKGEsIHhbMF0pO1xuICB4WzFdID0gYWRkMzIoYiwgeFsxXSk7XG4gIHhbMl0gPSBhZGQzMihjLCB4WzJdKTtcbiAgeFszXSA9IGFkZDMyKGQsIHhbM10pO1xuXG59XG5cbmZ1bmN0aW9uIGNtbihxLCBhLCBiLCB4LCBzLCB0KSB7XG4gIGEgPSBhZGQzMihhZGQzMihhLCBxKSwgYWRkMzIoeCwgdCkpO1xuICByZXR1cm4gYWRkMzIoKGEgPDwgcykgfCAoYSA+Pj4gKDMyIC0gcykpLCBiKTtcbn1cblxuZnVuY3Rpb24gZmYoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gY21uKChiICYgYykgfCAoKH5iKSAmIGQpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gZ2coYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gY21uKChiICYgZCkgfCAoYyAmICh+ZCkpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gaGgoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gY21uKGIgXiBjIF4gZCwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIGlpKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIGNtbihjIF4gKGIgfCAofmQpKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIG1kNTEocykge1xuICB0eHQgPSAnJztcbiAgdmFyIG4gPSBzLmxlbmd0aCxcbiAgICBzdGF0ZSA9IFsxNzMyNTg0MTkzLCAtMjcxNzMzODc5LCAtMTczMjU4NDE5NCwgMjcxNzMzODc4XSxcbiAgICBpO1xuICBmb3IgKGkgPSA2NDsgaSA8PSBzLmxlbmd0aDsgaSArPSA2NCkge1xuICAgIG1kNWN5Y2xlKHN0YXRlLCBtZDVibGsocy5zdWJzdHJpbmcoaSAtIDY0LCBpKSkpO1xuICB9XG4gIHMgPSBzLnN1YnN0cmluZyhpIC0gNjQpO1xuICB2YXIgdGFpbCA9IFswLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwXTtcbiAgZm9yIChpID0gMDsgaSA8IHMubGVuZ3RoOyBpKyspXG4gICAgdGFpbFtpID4+IDJdIHw9IHMuY2hhckNvZGVBdChpKSA8PCAoKGkgJSA0KSA8PCAzKTtcbiAgdGFpbFtpID4+IDJdIHw9IDB4ODAgPDwgKChpICUgNCkgPDwgMyk7XG4gIGlmIChpID4gNTUpIHtcbiAgICBtZDVjeWNsZShzdGF0ZSwgdGFpbCk7XG4gICAgZm9yIChpID0gMDsgaSA8IDE2OyBpKyspIHRhaWxbaV0gPSAwO1xuICB9XG4gIHRhaWxbMTRdID0gbiAqIDg7XG4gIG1kNWN5Y2xlKHN0YXRlLCB0YWlsKTtcbiAgcmV0dXJuIHN0YXRlO1xufVxuXG4vKiB0aGVyZSBuZWVkcyB0byBiZSBzdXBwb3J0IGZvciBVbmljb2RlIGhlcmUsXG4gKiB1bmxlc3Mgd2UgcHJldGVuZCB0aGF0IHdlIGNhbiByZWRlZmluZSB0aGUgTUQtNVxuICogYWxnb3JpdGhtIGZvciBtdWx0aS1ieXRlIGNoYXJhY3RlcnMgKHBlcmhhcHNcbiAqIGJ5IGFkZGluZyBldmVyeSBmb3VyIDE2LWJpdCBjaGFyYWN0ZXJzIGFuZFxuICogc2hvcnRlbmluZyB0aGUgc3VtIHRvIDMyIGJpdHMpLiBPdGhlcndpc2VcbiAqIEkgc3VnZ2VzdCBwZXJmb3JtaW5nIE1ELTUgYXMgaWYgZXZlcnkgY2hhcmFjdGVyXG4gKiB3YXMgdHdvIGJ5dGVzLS1lLmcuLCAwMDQwIDAwMjUgPSBAJS0tYnV0IHRoZW5cbiAqIGhvdyB3aWxsIGFuIG9yZGluYXJ5IE1ELTUgc3VtIGJlIG1hdGNoZWQ/XG4gKiBUaGVyZSBpcyBubyB3YXkgdG8gc3RhbmRhcmRpemUgdGV4dCB0byBzb21ldGhpbmdcbiAqIGxpa2UgVVRGLTggYmVmb3JlIHRyYW5zZm9ybWF0aW9uOyBzcGVlZCBjb3N0IGlzXG4gKiB1dHRlcmx5IHByb2hpYml0aXZlLiBUaGUgSmF2YVNjcmlwdCBzdGFuZGFyZFxuICogaXRzZWxmIG5lZWRzIHRvIGxvb2sgYXQgdGhpczogaXQgc2hvdWxkIHN0YXJ0XG4gKiBwcm92aWRpbmcgYWNjZXNzIHRvIHN0cmluZ3MgYXMgcHJlZm9ybWVkIFVURi04XG4gKiA4LWJpdCB1bnNpZ25lZCB2YWx1ZSBhcnJheXMuXG4gKi9cbmZ1bmN0aW9uIG1kNWJsayhzKSB7IC8qIEkgZmlndXJlZCBnbG9iYWwgd2FzIGZhc3Rlci4gICAqL1xuICB2YXIgbWQ1YmxrcyA9IFtdLFxuICAgIGk7IC8qIEFuZHkgS2luZyBzYWlkIGRvIGl0IHRoaXMgd2F5LiAqL1xuICBmb3IgKGkgPSAwOyBpIDwgNjQ7IGkgKz0gNCkge1xuICAgIG1kNWJsa3NbaSA+PiAyXSA9IHMuY2hhckNvZGVBdChpKSArIChzLmNoYXJDb2RlQXQoaSArIDEpIDw8IDgpICsgKHMuY2hhckNvZGVBdChpICsgMikgPDwgMTYpICsgKHMuY2hhckNvZGVBdChpICsgMykgPDxcbiAgICAgIDI0KTtcbiAgfVxuICByZXR1cm4gbWQ1Ymxrcztcbn1cblxudmFyIGhleF9jaHIgPSAnMDEyMzQ1Njc4OWFiY2RlZicuc3BsaXQoJycpO1xuXG5mdW5jdGlvbiByaGV4KG4pIHtcbiAgdmFyIHMgPSAnJyxcbiAgICBqID0gMDtcbiAgZm9yICg7IGogPCA0OyBqKyspXG4gICAgcyArPSBoZXhfY2hyWyhuID4+IChqICogOCArIDQpKSAmIDB4MEZdICsgaGV4X2NoclsobiA+PiAoaiAqIDgpKSAmIDB4MEZdO1xuICByZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gaGV4KHgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSsrKVxuICAgIHhbaV0gPSByaGV4KHhbaV0pO1xuICByZXR1cm4geC5qb2luKCcnKTtcbn1cblxuZnVuY3Rpb24gbWQ1KHMpIHtcbiAgcmV0dXJuIGhleChtZDUxKHMpKTtcbn1cblxuLyogdGhpcyBmdW5jdGlvbiBpcyBtdWNoIGZhc3RlcixcbnNvIGlmIHBvc3NpYmxlIHdlIHVzZSBpdC4gU29tZSBJRXNcbmFyZSB0aGUgb25seSBvbmVzIEkga25vdyBvZiB0aGF0XG5uZWVkIHRoZSBpZGlvdGljIHNlY29uZCBmdW5jdGlvbixcbmdlbmVyYXRlZCBieSBhbiBpZiBjbGF1c2UuICAqL1xuXG5mdW5jdGlvbiBhZGQzMihhLCBiKSB7XG4gIHJldHVybiAoYSArIGIpICYgMHhGRkZGRkZGRjtcbn1cblxuaWYgKG1kNSgnaGVsbG8nKSAhPSAnNWQ0MTQwMmFiYzRiMmE3NmI5NzE5ZDkxMTAxN2M1OTInKSB7XG4gIGZ1bmN0aW9uIGFkZDMyKHgsIHkpIHtcbiAgICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpLFxuICAgICAgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG4gICAgcmV0dXJuIChtc3cgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBNRDVcbiIsIi8qXG4gKiBDcnlwdG9NWCBUb29sc1xuICogQ29weXJpZ2h0IChDKSAyMDA0IC0gMjAwNiBEZXJlayBCdWl0ZW5odWlzXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyXG4gKiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlIC0gU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3LCBVU0EuXG4gKi9cblxuLyogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIXG4gKi9cblxudmFyIFJNRHNpemUgPSAxNjA7XG52YXIgWCA9IG5ldyBBcnJheSgpO1xuXG5mdW5jdGlvbiBST0woeCwgbikge1xuICByZXR1cm4gbmV3IE51bWJlcigoeCA8PCBuKSB8ICh4ID4+PiAoMzIgLSBuKSkpO1xufVxuXG5mdW5jdGlvbiBGKHgsIHksIHopIHtcbiAgcmV0dXJuIG5ldyBOdW1iZXIoeCBeIHkgXiB6KTtcbn1cblxuZnVuY3Rpb24gRyh4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgTnVtYmVyKCh4ICYgeSkgfCAofnggJiB6KSk7XG59XG5cbmZ1bmN0aW9uIEgoeCwgeSwgeikge1xuICByZXR1cm4gbmV3IE51bWJlcigoeCB8IH55KSBeIHopO1xufVxuXG5mdW5jdGlvbiBJKHgsIHksIHopIHtcbiAgcmV0dXJuIG5ldyBOdW1iZXIoKHggJiB6KSB8ICh5ICYgfnopKTtcbn1cblxuZnVuY3Rpb24gSih4LCB5LCB6KSB7XG4gIHJldHVybiBuZXcgTnVtYmVyKHggXiAoeSB8IH56KSk7XG59XG5cbmZ1bmN0aW9uIG1peE9uZVJvdW5kKGEsIGIsIGMsIGQsIGUsIHgsIHMsIHJvdW5kTnVtYmVyKSB7XG4gIHN3aXRjaCAocm91bmROdW1iZXIpIHtcbiAgICBjYXNlIDA6XG4gICAgICBhICs9IEYoYiwgYywgZCkgKyB4ICsgMHgwMDAwMDAwMDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMTpcbiAgICAgIGEgKz0gRyhiLCBjLCBkKSArIHggKyAweDVhODI3OTk5O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAyOlxuICAgICAgYSArPSBIKGIsIGMsIGQpICsgeCArIDB4NmVkOWViYTE7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDM6XG4gICAgICBhICs9IEkoYiwgYywgZCkgKyB4ICsgMHg4ZjFiYmNkYztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNDpcbiAgICAgIGEgKz0gSihiLCBjLCBkKSArIHggKyAweGE5NTNmZDRlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA1OlxuICAgICAgYSArPSBKKGIsIGMsIGQpICsgeCArIDB4NTBhMjhiZTY7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDY6XG4gICAgICBhICs9IEkoYiwgYywgZCkgKyB4ICsgMHg1YzRkZDEyNDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNzpcbiAgICAgIGEgKz0gSChiLCBjLCBkKSArIHggKyAweDZkNzAzZWYzO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA4OlxuICAgICAgYSArPSBHKGIsIGMsIGQpICsgeCArIDB4N2E2ZDc2ZTk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDk6XG4gICAgICBhICs9IEYoYiwgYywgZCkgKyB4ICsgMHgwMDAwMDAwMDtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGRvY3VtZW50LndyaXRlKFwiQm9ndXMgcm91bmQgbnVtYmVyXCIpO1xuICAgICAgYnJlYWs7XG4gIH1cblxuICBhID0gUk9MKGEsIHMpICsgZTtcbiAgYyA9IFJPTChjLCAxMCk7XG5cbiAgYSAmPSAweGZmZmZmZmZmO1xuICBiICY9IDB4ZmZmZmZmZmY7XG4gIGMgJj0gMHhmZmZmZmZmZjtcbiAgZCAmPSAweGZmZmZmZmZmO1xuICBlICY9IDB4ZmZmZmZmZmY7XG5cbiAgdmFyIHJldEJsb2NrID0gbmV3IEFycmF5KCk7XG4gIHJldEJsb2NrWzBdID0gYTtcbiAgcmV0QmxvY2tbMV0gPSBiO1xuICByZXRCbG9ja1syXSA9IGM7XG4gIHJldEJsb2NrWzNdID0gZDtcbiAgcmV0QmxvY2tbNF0gPSBlO1xuICByZXRCbG9ja1s1XSA9IHg7XG4gIHJldEJsb2NrWzZdID0gcztcblxuICByZXR1cm4gcmV0QmxvY2s7XG59XG5cbmZ1bmN0aW9uIE1EaW5pdChNRGJ1Zikge1xuICBNRGJ1ZlswXSA9IDB4Njc0NTIzMDE7XG4gIE1EYnVmWzFdID0gMHhlZmNkYWI4OTtcbiAgTURidWZbMl0gPSAweDk4YmFkY2ZlO1xuICBNRGJ1ZlszXSA9IDB4MTAzMjU0NzY7XG4gIE1EYnVmWzRdID0gMHhjM2QyZTFmMDtcbn1cblxudmFyIFJPTHMgPSBbXG4gIFsxMSwgMTQsIDE1LCAxMiwgNSwgOCwgNywgOSwgMTEsIDEzLCAxNCwgMTUsIDYsIDcsIDksIDhdLFxuICBbNywgNiwgOCwgMTMsIDExLCA5LCA3LCAxNSwgNywgMTIsIDE1LCA5LCAxMSwgNywgMTMsIDEyXSxcbiAgWzExLCAxMywgNiwgNywgMTQsIDksIDEzLCAxNSwgMTQsIDgsIDEzLCA2LCA1LCAxMiwgNywgNV0sXG4gIFsxMSwgMTIsIDE0LCAxNSwgMTQsIDE1LCA5LCA4LCA5LCAxNCwgNSwgNiwgOCwgNiwgNSwgMTJdLFxuICBbOSwgMTUsIDUsIDExLCA2LCA4LCAxMywgMTIsIDUsIDEyLCAxMywgMTQsIDExLCA4LCA1LCA2XSxcbiAgWzgsIDksIDksIDExLCAxMywgMTUsIDE1LCA1LCA3LCA3LCA4LCAxMSwgMTQsIDE0LCAxMiwgNl0sXG4gIFs5LCAxMywgMTUsIDcsIDEyLCA4LCA5LCAxMSwgNywgNywgMTIsIDcsIDYsIDE1LCAxMywgMTFdLFxuICBbOSwgNywgMTUsIDExLCA4LCA2LCA2LCAxNCwgMTIsIDEzLCA1LCAxNCwgMTMsIDEzLCA3LCA1XSxcbiAgWzE1LCA1LCA4LCAxMSwgMTQsIDE0LCA2LCAxNCwgNiwgOSwgMTIsIDksIDEyLCA1LCAxNSwgOF0sXG4gIFs4LCA1LCAxMiwgOSwgMTIsIDUsIDE0LCA2LCA4LCAxMywgNiwgNSwgMTUsIDEzLCAxMSwgMTFdXG5dO1xuXG52YXIgaW5kZXhlcyA9IFtcbiAgWzAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTVdLFxuICBbNywgNCwgMTMsIDEsIDEwLCA2LCAxNSwgMywgMTIsIDAsIDksIDUsIDIsIDE0LCAxMSwgOF0sXG4gIFszLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyXSxcbiAgWzEsIDksIDExLCAxMCwgMCwgOCwgMTIsIDQsIDEzLCAzLCA3LCAxNSwgMTQsIDUsIDYsIDJdLFxuICBbNCwgMCwgNSwgOSwgNywgMTIsIDIsIDEwLCAxNCwgMSwgMywgOCwgMTEsIDYsIDE1LCAxM10sXG4gIFs1LCAxNCwgNywgMCwgOSwgMiwgMTEsIDQsIDEzLCA2LCAxNSwgOCwgMSwgMTAsIDMsIDEyXSxcbiAgWzYsIDExLCAzLCA3LCAwLCAxMywgNSwgMTAsIDE0LCAxNSwgOCwgMTIsIDQsIDksIDEsIDJdLFxuICBbMTUsIDUsIDEsIDMsIDcsIDE0LCA2LCA5LCAxMSwgOCwgMTIsIDIsIDEwLCAwLCA0LCAxM10sXG4gIFs4LCA2LCA0LCAxLCAzLCAxMSwgMTUsIDAsIDUsIDEyLCAyLCAxMywgOSwgNywgMTAsIDE0XSxcbiAgWzEyLCAxNSwgMTAsIDQsIDEsIDUsIDgsIDcsIDYsIDIsIDEzLCAxNCwgMCwgMywgOSwgMTFdXG5dO1xuXG5mdW5jdGlvbiBjb21wcmVzcyhNRGJ1ZiwgWCkge1xuICBibG9ja0EgPSBuZXcgQXJyYXkoKTtcbiAgYmxvY2tCID0gbmV3IEFycmF5KCk7XG5cbiAgdmFyIHJldEJsb2NrO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgNTsgaSsrKSB7XG4gICAgYmxvY2tBW2ldID0gbmV3IE51bWJlcihNRGJ1ZltpXSk7XG4gICAgYmxvY2tCW2ldID0gbmV3IE51bWJlcihNRGJ1ZltpXSk7XG4gIH1cblxuICB2YXIgc3RlcCA9IDA7XG4gIGZvciAodmFyIGogPSAwOyBqIDwgNTsgaisrKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgICByZXRCbG9jayA9IG1peE9uZVJvdW5kKFxuICAgICAgICBibG9ja0FbKHN0ZXAgKyAwKSAlIDVdLFxuICAgICAgICBibG9ja0FbKHN0ZXAgKyAxKSAlIDVdLFxuICAgICAgICBibG9ja0FbKHN0ZXAgKyAyKSAlIDVdLFxuICAgICAgICBibG9ja0FbKHN0ZXAgKyAzKSAlIDVdLFxuICAgICAgICBibG9ja0FbKHN0ZXAgKyA0KSAlIDVdLFxuICAgICAgICBYW2luZGV4ZXNbal1baV1dLFxuICAgICAgICBST0xzW2pdW2ldLFxuICAgICAgICBqKTtcblxuICAgICAgYmxvY2tBWyhzdGVwICsgMCkgJSA1XSA9IHJldEJsb2NrWzBdO1xuICAgICAgYmxvY2tBWyhzdGVwICsgMSkgJSA1XSA9IHJldEJsb2NrWzFdO1xuICAgICAgYmxvY2tBWyhzdGVwICsgMikgJSA1XSA9IHJldEJsb2NrWzJdO1xuICAgICAgYmxvY2tBWyhzdGVwICsgMykgJSA1XSA9IHJldEJsb2NrWzNdO1xuICAgICAgYmxvY2tBWyhzdGVwICsgNCkgJSA1XSA9IHJldEJsb2NrWzRdO1xuXG4gICAgICBzdGVwICs9IDQ7XG4gICAgfVxuICB9XG5cbiAgc3RlcCA9IDA7XG4gIGZvciAodmFyIGogPSA1OyBqIDwgMTA7IGorKykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgcmV0QmxvY2sgPSBtaXhPbmVSb3VuZChcbiAgICAgICAgYmxvY2tCWyhzdGVwICsgMCkgJSA1XSxcbiAgICAgICAgYmxvY2tCWyhzdGVwICsgMSkgJSA1XSxcbiAgICAgICAgYmxvY2tCWyhzdGVwICsgMikgJSA1XSxcbiAgICAgICAgYmxvY2tCWyhzdGVwICsgMykgJSA1XSxcbiAgICAgICAgYmxvY2tCWyhzdGVwICsgNCkgJSA1XSxcbiAgICAgICAgWFtpbmRleGVzW2pdW2ldXSxcbiAgICAgICAgUk9Mc1tqXVtpXSxcbiAgICAgICAgaik7XG5cbiAgICAgIGJsb2NrQlsoc3RlcCArIDApICUgNV0gPSByZXRCbG9ja1swXTtcbiAgICAgIGJsb2NrQlsoc3RlcCArIDEpICUgNV0gPSByZXRCbG9ja1sxXTtcbiAgICAgIGJsb2NrQlsoc3RlcCArIDIpICUgNV0gPSByZXRCbG9ja1syXTtcbiAgICAgIGJsb2NrQlsoc3RlcCArIDMpICUgNV0gPSByZXRCbG9ja1szXTtcbiAgICAgIGJsb2NrQlsoc3RlcCArIDQpICUgNV0gPSByZXRCbG9ja1s0XTtcblxuICAgICAgc3RlcCArPSA0O1xuICAgIH1cbiAgfVxuXG4gIGJsb2NrQlszXSArPSBibG9ja0FbMl0gKyBNRGJ1ZlsxXTtcbiAgTURidWZbMV0gPSBNRGJ1ZlsyXSArIGJsb2NrQVszXSArIGJsb2NrQls0XTtcbiAgTURidWZbMl0gPSBNRGJ1ZlszXSArIGJsb2NrQVs0XSArIGJsb2NrQlswXTtcbiAgTURidWZbM10gPSBNRGJ1Zls0XSArIGJsb2NrQVswXSArIGJsb2NrQlsxXTtcbiAgTURidWZbNF0gPSBNRGJ1ZlswXSArIGJsb2NrQVsxXSArIGJsb2NrQlsyXTtcbiAgTURidWZbMF0gPSBibG9ja0JbM107XG59XG5cbmZ1bmN0aW9uIHplcm9YKFgpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgWFtpXSA9IDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gTURmaW5pc2goTURidWYsIHN0cnB0ciwgbHN3bGVuLCBtc3dsZW4pIHtcbiAgdmFyIFggPSBuZXcgQXJyYXkoMTYpO1xuICB6ZXJvWChYKTtcblxuICB2YXIgaiA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgKGxzd2xlbiAmIDYzKTsgaSsrKSB7XG4gICAgWFtpID4+PiAyXSBePSAoc3RycHRyLmNoYXJDb2RlQXQoaisrKSAmIDI1NSkgPDwgKDggKiAoaSAmIDMpKTtcbiAgfVxuXG4gIFhbKGxzd2xlbiA+Pj4gMikgJiAxNV0gXj0gMSA8PCAoOCAqIChsc3dsZW4gJiAzKSArIDcpO1xuXG4gIGlmICgobHN3bGVuICYgNjMpID4gNTUpIHtcbiAgICBjb21wcmVzcyhNRGJ1ZiwgWCk7XG4gICAgdmFyIFggPSBuZXcgQXJyYXkoMTYpO1xuICAgIHplcm9YKFgpO1xuICB9XG5cbiAgWFsxNF0gPSBsc3dsZW4gPDwgMztcbiAgWFsxNV0gPSAobHN3bGVuID4+PiAyOSkgfCAobXN3bGVuIDw8IDMpO1xuXG4gIGNvbXByZXNzKE1EYnVmLCBYKTtcbn1cblxuZnVuY3Rpb24gQllURVNfVE9fRFdPUkQoZm91ckNoYXJzKSB7XG4gIHZhciB0bXAgPSAoZm91ckNoYXJzLmNoYXJDb2RlQXQoMykgJiAyNTUpIDw8IDI0O1xuICB0bXAgfD0gKGZvdXJDaGFycy5jaGFyQ29kZUF0KDIpICYgMjU1KSA8PCAxNjtcbiAgdG1wIHw9IChmb3VyQ2hhcnMuY2hhckNvZGVBdCgxKSAmIDI1NSkgPDwgODtcbiAgdG1wIHw9IChmb3VyQ2hhcnMuY2hhckNvZGVBdCgwKSAmIDI1NSk7XG5cbiAgcmV0dXJuIHRtcDtcbn1cblxuZnVuY3Rpb24gUk1EKG1lc3NhZ2UpIHtcbiAgdmFyIE1EYnVmID0gbmV3IEFycmF5KFJNRHNpemUgLyAzMik7XG4gIHZhciBoYXNoY29kZSA9IG5ldyBBcnJheShSTURzaXplIC8gOCk7XG4gIHZhciBsZW5ndGg7XG4gIHZhciBuYnl0ZXM7XG5cbiAgTURpbml0KE1EYnVmKTtcbiAgbGVuZ3RoID0gbWVzc2FnZS5sZW5ndGg7XG5cbiAgdmFyIFggPSBuZXcgQXJyYXkoMTYpO1xuICB6ZXJvWChYKTtcblxuICB2YXIgaiA9IDA7XG4gIGZvciAodmFyIG5ieXRlcyA9IGxlbmd0aDsgbmJ5dGVzID4gNjM7IG5ieXRlcyAtPSA2NCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgWFtpXSA9IEJZVEVTX1RPX0RXT1JEKG1lc3NhZ2Uuc3Vic3RyKGosIDQpKTtcbiAgICAgIGogKz0gNDtcbiAgICB9XG4gICAgY29tcHJlc3MoTURidWYsIFgpO1xuICB9XG5cbiAgTURmaW5pc2goTURidWYsIG1lc3NhZ2Uuc3Vic3RyKGopLCBsZW5ndGgsIDApO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgUk1Ec2l6ZSAvIDg7IGkgKz0gNCkge1xuICAgIGhhc2hjb2RlW2ldID0gTURidWZbaSA+Pj4gMl0gJiAyNTU7XG4gICAgaGFzaGNvZGVbaSArIDFdID0gKE1EYnVmW2kgPj4+IDJdID4+PiA4KSAmIDI1NTtcbiAgICBoYXNoY29kZVtpICsgMl0gPSAoTURidWZbaSA+Pj4gMl0gPj4+IDE2KSAmIDI1NTtcbiAgICBoYXNoY29kZVtpICsgM10gPSAoTURidWZbaSA+Pj4gMl0gPj4+IDI0KSAmIDI1NTtcbiAgfVxuXG4gIHJldHVybiBoYXNoY29kZTtcbn1cblxuXG5mdW5jdGlvbiBSTURzdHJpbmcobWVzc2FnZSkge1xuICB2YXIgaGFzaGNvZGUgPSBSTUQobWVzc2FnZSk7XG4gIHZhciByZXRTdHJpbmcgPSBcIlwiO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgUk1Ec2l6ZSAvIDg7IGkrKykge1xuICAgIHJldFN0cmluZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGhhc2hjb2RlW2ldKTtcbiAgfVxuXG4gIHJldHVybiByZXRTdHJpbmc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUk1Ec3RyaW5nO1xuIiwiLyogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTSEEgZmFtaWx5IG9mIGhhc2hlcywgYXMgZGVmaW5lZCBpbiBGSVBTIFxuICogUFVCIDE4MC0yIGFzIHdlbGwgYXMgdGhlIGNvcnJlc3BvbmRpbmcgSE1BQyBpbXBsZW1lbnRhdGlvbiBhcyBkZWZpbmVkIGluXG4gKiBGSVBTIFBVQiAxOThhXG4gKlxuICogVmVyc2lvbiAxLjMgQ29weXJpZ2h0IEJyaWFuIFR1cmVrIDIwMDgtMjAxMFxuICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlXG4gKiBTZWUgaHR0cDovL2pzc2hhLnNvdXJjZWZvcmdlLm5ldC8gZm9yIG1vcmUgaW5mb3JtYXRpb25cbiAqXG4gKiBTZXZlcmFsIGZ1bmN0aW9ucyB0YWtlbiBmcm9tIFBhdWwgSm9obnNvblxuICovXG5cbi8qIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSFxuICogXG4gKiBUaGlzIGNvZGUgaGFzIGJlZW4gc2xpZ2h0bHkgbW9kaWZpZWQgZGlyZWN0IHN0cmluZyBvdXRwdXQ6XG4gKiAtIGJpbjJic3RyIGhhcyBiZWVuIGFkZGVkXG4gKiAtIGZvbGxvd2luZyB3cmFwcGVycyBvZiB0aGlzIGxpYnJhcnkgaGF2ZSBiZWVuIGFkZGVkOlxuICogICAtIHN0cl9zaGExXG4gKiAgIC0gc3RyX3NoYTI1NlxuICogICAtIHN0cl9zaGEyMjRcbiAqICAgLSBzdHJfc2hhMzg0XG4gKiAgIC0gc3RyX3NoYTUxMlxuICovXG5cbnZhciBqc1NIQSA9IChmdW5jdGlvbigpIHtcblxuICAvKlxuICAgKiBDb25maWd1cmFibGUgdmFyaWFibGVzLiBEZWZhdWx0cyB0eXBpY2FsbHkgd29ya1xuICAgKi9cbiAgLyogTnVtYmVyIG9mIEJpdHMgUGVyIGNoYXJhY3RlciAoOCBmb3IgQVNDSUksIDE2IGZvciBVbmljb2RlKSAqL1xuICB2YXIgY2hhclNpemUgPSA4LFxuICAgIC8qIGJhc2UtNjQgcGFkIGNoYXJhY3Rlci4gXCI9XCIgZm9yIHN0cmljdCBSRkMgY29tcGxpYW5jZSAqL1xuICAgIGI2NHBhZCA9IFwiXCIsXG4gICAgLyogaGV4IG91dHB1dCBmb3JtYXQuIDAgLSBsb3dlcmNhc2U7IDEgLSB1cHBlcmNhc2UgKi9cbiAgICBoZXhDYXNlID0gMCxcblxuICAgIC8qXG4gICAgICogSW50XzY0IGlzIGEgb2JqZWN0IGZvciAyIDMyLWJpdCBudW1iZXJzIGVtdWxhdGluZyBhIDY0LWJpdCBudW1iZXJcbiAgICAgKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtc2ludF8zMiBUaGUgbW9zdCBzaWduaWZpY2FudCAzMi1iaXRzIG9mIGEgNjQtYml0IG51bWJlclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBsc2ludF8zMiBUaGUgbGVhc3Qgc2lnbmlmaWNhbnQgMzItYml0cyBvZiBhIDY0LWJpdCBudW1iZXJcbiAgICAgKi9cbiAgICBJbnRfNjQgPSBmdW5jdGlvbihtc2ludF8zMiwgbHNpbnRfMzIpIHtcbiAgICAgIHRoaXMuaGlnaE9yZGVyID0gbXNpbnRfMzI7XG4gICAgICB0aGlzLmxvd09yZGVyID0gbHNpbnRfMzI7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ29udmVydCBhIHN0cmluZyB0byBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzXG4gICAgICogSWYgY2hhclNpemUgaXMgQVNDSUksIGNoYXJhY3RlcnMgPjI1NSBoYXZlIHRoZWlyIGhpLWJ5dGUgc2lsZW50bHlcbiAgICAgKiBpZ25vcmVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gYmUgY29udmVydGVkIHRvIGJpbmFyeSByZXByZXNlbnRhdGlvblxuICAgICAqIEByZXR1cm4gSW50ZWdlciBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyXG4gICAgICovXG4gICAgc3RyMmJpbmIgPSBmdW5jdGlvbihzdHIpIHtcbiAgICAgIHZhciBiaW4gPSBbXSxcbiAgICAgICAgbWFzayA9ICgxIDw8IGNoYXJTaXplKSAtIDEsXG4gICAgICAgIGxlbmd0aCA9IHN0ci5sZW5ndGggKiBjaGFyU2l6ZSxcbiAgICAgICAgaTtcblxuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSArPSBjaGFyU2l6ZSkge1xuICAgICAgICBiaW5baSA+PiA1XSB8PSAoc3RyLmNoYXJDb2RlQXQoaSAvIGNoYXJTaXplKSAmIG1hc2spIDw8XG4gICAgICAgICAgKDMyIC0gY2hhclNpemUgLSAoaSAlIDMyKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBiaW47XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ29udmVydCBhIGhleCBzdHJpbmcgdG8gYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3Jkc1xuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gYmUgY29udmVydGVkIHRvIGJpbmFyeSByZXByZXNlbnRhdGlvblxuICAgICAqIEByZXR1cm4gSW50ZWdlciBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyXG4gICAgICovXG4gICAgaGV4MmJpbmIgPSBmdW5jdGlvbihzdHIpIHtcbiAgICAgIHZhciBiaW4gPSBbXSxcbiAgICAgICAgbGVuZ3RoID0gc3RyLmxlbmd0aCxcbiAgICAgICAgaSwgbnVtO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDIpIHtcbiAgICAgICAgbnVtID0gcGFyc2VJbnQoc3RyLnN1YnN0cihpLCAyKSwgMTYpO1xuICAgICAgICBpZiAoIWlzTmFOKG51bSkpIHtcbiAgICAgICAgICBiaW5baSA+PiAzXSB8PSBudW0gPDwgKDI0IC0gKDQgKiAoaSAlIDgpKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIFwiSU5WQUxJRCBIRVggU1RSSU5HXCI7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGJpbjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMgdG8gYSBoZXggc3RyaW5nLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBiaW5hcnJheSBBcnJheSBvZiBpbnRlZ2VycyB0byBiZSBjb252ZXJ0ZWQgdG8gaGV4aWRlY2ltYWxcbiAgICAgKlx0IHJlcHJlc2VudGF0aW9uXG4gICAgICogQHJldHVybiBIZXhpZGVjaW1hbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFyYW1ldGVyIGluIFN0cmluZyBmb3JtXG4gICAgICovXG4gICAgYmluYjJoZXggPSBmdW5jdGlvbihiaW5hcnJheSkge1xuICAgICAgdmFyIGhleF90YWIgPSAoaGV4Q2FzZSkgPyBcIjAxMjM0NTY3ODlBQkNERUZcIiA6IFwiMDEyMzQ1Njc4OWFiY2RlZlwiLFxuICAgICAgICBzdHIgPSBcIlwiLFxuICAgICAgICBsZW5ndGggPSBiaW5hcnJheS5sZW5ndGggKiA0LFxuICAgICAgICBpLCBzcmNCeXRlO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgc3JjQnl0ZSA9IGJpbmFycmF5W2kgPj4gMl0gPj4gKCgzIC0gKGkgJSA0KSkgKiA4KTtcbiAgICAgICAgc3RyICs9IGhleF90YWIuY2hhckF0KChzcmNCeXRlID4+IDQpICYgMHhGKSArXG4gICAgICAgICAgaGV4X3RhYi5jaGFyQXQoc3JjQnl0ZSAmIDB4Rik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzdHI7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ29udmVydCBhbiBhcnJheSBvZiBiaWctZW5kaWFuIHdvcmRzIHRvIGEgYmFzZS02NCBzdHJpbmdcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gYmluYXJyYXkgQXJyYXkgb2YgaW50ZWdlcnMgdG8gYmUgY29udmVydGVkIHRvIGJhc2UtNjRcbiAgICAgKlx0IHJlcHJlc2VudGF0aW9uXG4gICAgICogQHJldHVybiBCYXNlLTY0IGVuY29kZWQgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhcmFtZXRlciBpbiBTdHJpbmcgZm9ybVxuICAgICAqL1xuICAgIGJpbmIyYjY0ID0gZnVuY3Rpb24oYmluYXJyYXkpIHtcbiAgICAgIHZhciB0YWIgPSBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIiArXG4gICAgICAgIFwiMDEyMzQ1Njc4OSsvXCIsXG4gICAgICAgIHN0ciA9IFwiXCIsXG4gICAgICAgIGxlbmd0aCA9IGJpbmFycmF5Lmxlbmd0aCAqIDQsXG4gICAgICAgIGksIGosXG4gICAgICAgIHRyaXBsZXQ7XG5cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuICAgICAgICB0cmlwbGV0ID0gKCgoYmluYXJyYXlbaSA+PiAyXSA+PiA4ICogKDMgLSBpICUgNCkpICYgMHhGRikgPDwgMTYpIHxcbiAgICAgICAgICAoKChiaW5hcnJheVtpICsgMSA+PiAyXSA+PiA4ICogKDMgLSAoaSArIDEpICUgNCkpICYgMHhGRikgPDwgOCkgfFxuICAgICAgICAgICgoYmluYXJyYXlbaSArIDIgPj4gMl0gPj4gOCAqICgzIC0gKGkgKyAyKSAlIDQpKSAmIDB4RkYpO1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgNDsgaiArPSAxKSB7XG4gICAgICAgICAgaWYgKGkgKiA4ICsgaiAqIDYgPD0gYmluYXJyYXkubGVuZ3RoICogMzIpIHtcbiAgICAgICAgICAgIHN0ciArPSB0YWIuY2hhckF0KCh0cmlwbGV0ID4+IDYgKiAoMyAtIGopKSAmIDB4M0YpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHIgKz0gYjY0cGFkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDb252ZXJ0IGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMgdG8gYSBzdHJpbmdcbiAgICAgKi9cbiAgICBiaW5iMnN0ciA9IGZ1bmN0aW9uKGJpbikge1xuICAgICAgdmFyIHN0ciA9IFwiXCI7XG4gICAgICB2YXIgbWFzayA9ICgxIDw8IDgpIC0gMTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmluLmxlbmd0aCAqIDMyOyBpICs9IDgpXG4gICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChiaW5baSA+PiA1XSA+Pj4gKDI0IC0gaSAlIDMyKSkgJiBtYXNrKTtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfSxcbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgY2lyY3VsYXIgcm90YXRlIGxlZnRcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG4gICAgICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGNpcmN1bGFybHkgYnkgbiBiaXRzXG4gICAgICovXG4gICAgcm90bF8zMiA9IGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgIHJldHVybiAoeCA8PCBuKSB8ICh4ID4+PiAoMzIgLSBuKSk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBjaXJjdWxhciByb3RhdGUgcmlnaHRcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG4gICAgICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGNpcmN1bGFybHkgYnkgbiBiaXRzXG4gICAgICovXG4gICAgcm90cl8zMiA9IGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgIHJldHVybiAoeCA+Pj4gbikgfCAoeCA8PCAoMzIgLSBuKSk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDY0LWJpdCBpbXBsZW1lbnRhdGlvbiBvZiBjaXJjdWxhciByb3RhdGUgcmlnaHRcbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0XG4gICAgICogQHJldHVybiBUaGUgeCBzaGlmdGVkIGNpcmN1bGFybHkgYnkgbiBiaXRzXG4gICAgICovXG4gICAgcm90cl82NCA9IGZ1bmN0aW9uKHgsIG4pIHtcbiAgICAgIGlmIChuIDw9IDMyKSB7XG4gICAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICAoeC5oaWdoT3JkZXIgPj4+IG4pIHwgKHgubG93T3JkZXIgPDwgKDMyIC0gbikpLCAoeC5sb3dPcmRlciA+Pj4gbikgfCAoeC5oaWdoT3JkZXIgPDwgKDMyIC0gbikpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICAoeC5sb3dPcmRlciA+Pj4gbikgfCAoeC5oaWdoT3JkZXIgPDwgKDMyIC0gbikpLCAoeC5oaWdoT3JkZXIgPj4+IG4pIHwgKHgubG93T3JkZXIgPDwgKDMyIC0gbikpKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHNoaWZ0IHJpZ2h0XG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdFxuICAgICAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBieSBuIGJpdHNcbiAgICAgKi9cbiAgICBzaHJfMzIgPSBmdW5jdGlvbih4LCBuKSB7XG4gICAgICByZXR1cm4geCA+Pj4gbjtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHNoaWZ0IHJpZ2h0XG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdFxuICAgICAqIEByZXR1cm4gVGhlIHggc2hpZnRlZCBieSBuIGJpdHNcbiAgICAgKi9cbiAgICBzaHJfNjQgPSBmdW5jdGlvbih4LCBuKSB7XG4gICAgICBpZiAobiA8PSAzMikge1xuICAgICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgICB4LmhpZ2hPcmRlciA+Pj4gbixcbiAgICAgICAgICB4Lmxvd09yZGVyID4+PiBuIHwgKHguaGlnaE9yZGVyIDw8ICgzMiAtIG4pKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgICAwLFxuICAgICAgICAgIHguaGlnaE9yZGVyIDw8ICgzMiAtIG4pKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBQYXJpdHkgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIGZpcnN0IDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIHNlY29uZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB6IFRoZSB0aGlyZCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBwYXJpdHlfMzIgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4geCBeIHkgXiB6O1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIENoIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geiBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgY2hfMzIgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4gKHggJiB5KSBeICh+eCAmIHopO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIENoIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB4IFRoZSBmaXJzdCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB5IFRoZSBzZWNvbmQgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geiBUaGUgdGhpcmQgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgY2hfNjQgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICh4LmhpZ2hPcmRlciAmIHkuaGlnaE9yZGVyKSBeICh+eC5oaWdoT3JkZXIgJiB6LmhpZ2hPcmRlciksICh4Lmxvd09yZGVyICYgeS5sb3dPcmRlcikgXiAofngubG93T3JkZXIgJiB6Lmxvd09yZGVyKSk7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgTWFqIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB5IFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geiBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgbWFqXzMyID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICAgICAgcmV0dXJuICh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBNYWogZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIGZpcnN0IDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHkgVGhlIHNlY29uZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSB6IFRoZSB0aGlyZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBtYWpfNjQgPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICh4LmhpZ2hPcmRlciAmIHkuaGlnaE9yZGVyKSBeXG4gICAgICAgICh4LmhpZ2hPcmRlciAmIHouaGlnaE9yZGVyKSBeXG4gICAgICAgICh5LmhpZ2hPcmRlciAmIHouaGlnaE9yZGVyKSwgKHgubG93T3JkZXIgJiB5Lmxvd09yZGVyKSBeXG4gICAgICAgICh4Lmxvd09yZGVyICYgei5sb3dPcmRlcikgXlxuICAgICAgICAoeS5sb3dPcmRlciAmIHoubG93T3JkZXIpKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBTaWdtYTAgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIHNpZ21hMF8zMiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiByb3RyXzMyKHgsIDIpIF4gcm90cl8zMih4LCAxMykgXiByb3RyXzMyKHgsIDIyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBTaWdtYTAgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIHNpZ21hMF82NCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHZhciByb3RyMjggPSByb3RyXzY0KHgsIDI4KSxcbiAgICAgICAgcm90cjM0ID0gcm90cl82NCh4LCAzNCksXG4gICAgICAgIHJvdHIzOSA9IHJvdHJfNjQoeCwgMzkpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgcm90cjI4LmhpZ2hPcmRlciBeIHJvdHIzNC5oaWdoT3JkZXIgXiByb3RyMzkuaGlnaE9yZGVyLFxuICAgICAgICByb3RyMjgubG93T3JkZXIgXiByb3RyMzQubG93T3JkZXIgXiByb3RyMzkubG93T3JkZXIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSAzMi1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIFNpZ21hMSBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgMzItYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgc2lnbWExXzMyID0gZnVuY3Rpb24oeCkge1xuICAgICAgcmV0dXJuIHJvdHJfMzIoeCwgNikgXiByb3RyXzMyKHgsIDExKSBeIHJvdHJfMzIoeCwgMjUpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIFNpZ21hMSBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgc2lnbWExXzY0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgdmFyIHJvdHIxNCA9IHJvdHJfNjQoeCwgMTQpLFxuICAgICAgICByb3RyMTggPSByb3RyXzY0KHgsIDE4KSxcbiAgICAgICAgcm90cjQxID0gcm90cl82NCh4LCA0MSk7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICByb3RyMTQuaGlnaE9yZGVyIF4gcm90cjE4LmhpZ2hPcmRlciBeIHJvdHI0MS5oaWdoT3JkZXIsXG4gICAgICAgIHJvdHIxNC5sb3dPcmRlciBeIHJvdHIxOC5sb3dPcmRlciBeIHJvdHI0MS5sb3dPcmRlcik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogVGhlIDMyLWJpdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgTklTVCBzcGVjaWZpZWQgR2FtbWEwIGZ1bmN0aW9uXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB4IFRoZSAzMi1iaXQgaW50ZWdlciBhcmd1bWVudFxuICAgICAqIEByZXR1cm4gVGhlIE5JU1Qgc3BlY2lmaWVkIG91dHB1dCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBnYW1tYTBfMzIgPSBmdW5jdGlvbih4KSB7XG4gICAgICByZXR1cm4gcm90cl8zMih4LCA3KSBeIHJvdHJfMzIoeCwgMTgpIF4gc2hyXzMyKHgsIDMpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIFRoZSA2NC1iaXQgaW1wbGVtZW50YXRpb24gb2YgdGhlIE5JU1Qgc3BlY2lmaWVkIEdhbW1hMCBmdW5jdGlvblxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgNjQtYml0IGludGVnZXIgYXJndW1lbnRcbiAgICAgKiBAcmV0dXJuIFRoZSBOSVNUIHNwZWNpZmllZCBvdXRwdXQgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgZ2FtbWEwXzY0ID0gZnVuY3Rpb24oeCkge1xuICAgICAgdmFyIHJvdHIxID0gcm90cl82NCh4LCAxKSxcbiAgICAgICAgcm90cjggPSByb3RyXzY0KHgsIDgpLFxuICAgICAgICBzaHI3ID0gc2hyXzY0KHgsIDcpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChcbiAgICAgICAgcm90cjEuaGlnaE9yZGVyIF4gcm90cjguaGlnaE9yZGVyIF4gc2hyNy5oaWdoT3JkZXIsXG4gICAgICAgIHJvdHIxLmxvd09yZGVyIF4gcm90cjgubG93T3JkZXIgXiBzaHI3Lmxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgMzItYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTEgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIGdhbW1hMV8zMiA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHJldHVybiByb3RyXzMyKHgsIDE3KSBeIHJvdHJfMzIoeCwgMTkpIF4gc2hyXzMyKHgsIDEwKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBUaGUgNjQtYml0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBOSVNUIHNwZWNpZmllZCBHYW1tYTEgZnVuY3Rpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IHggVGhlIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50XG4gICAgICogQHJldHVybiBUaGUgTklTVCBzcGVjaWZpZWQgb3V0cHV0IG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIGdhbW1hMV82NCA9IGZ1bmN0aW9uKHgpIHtcbiAgICAgIHZhciByb3RyMTkgPSByb3RyXzY0KHgsIDE5KSxcbiAgICAgICAgcm90cjYxID0gcm90cl82NCh4LCA2MSksXG4gICAgICAgIHNocjYgPSBzaHJfNjQoeCwgNik7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KFxuICAgICAgICByb3RyMTkuaGlnaE9yZGVyIF4gcm90cjYxLmhpZ2hPcmRlciBeIHNocjYuaGlnaE9yZGVyLFxuICAgICAgICByb3RyMTkubG93T3JkZXIgXiByb3RyNjEubG93T3JkZXIgXiBzaHI2Lmxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgdHdvIDMyLWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgZmlyc3QgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgc2Vjb25kIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIHggKyB5XG4gICAgICovXG4gICAgc2FmZUFkZF8zMl8yID0gZnVuY3Rpb24oeCwgeSkge1xuICAgICAgdmFyIGxzdyA9ICh4ICYgMHhGRkZGKSArICh5ICYgMHhGRkZGKSxcbiAgICAgICAgbXN3ID0gKHggPj4+IDE2KSArICh5ID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG5cbiAgICAgIHJldHVybiAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQWRkIGZvdXIgMzItYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjMyLiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcbiAgICAgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhIFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBiIFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYyBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZCBUaGUgZm91cnRoIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGRcbiAgICAgKi9cbiAgICBzYWZlQWRkXzMyXzQgPSBmdW5jdGlvbihhLCBiLCBjLCBkKSB7XG4gICAgICB2YXIgbHN3ID0gKGEgJiAweEZGRkYpICsgKGIgJiAweEZGRkYpICsgKGMgJiAweEZGRkYpICsgKGQgJiAweEZGRkYpLFxuICAgICAgICBtc3cgPSAoYSA+Pj4gMTYpICsgKGIgPj4+IDE2KSArIChjID4+PiAxNikgKyAoZCA+Pj4gMTYpICtcbiAgICAgICAgICAobHN3ID4+PiAxNik7XG5cbiAgICAgIHJldHVybiAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQWRkIGZpdmUgMzItYml0IGludGVnZXJzLCB3cmFwcGluZyBhdCAyXjMyLiBUaGlzIHVzZXMgMTYtYml0IG9wZXJhdGlvbnNcbiAgICAgKiBpbnRlcm5hbGx5IHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBhIFRoZSBmaXJzdCAzMi1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBiIFRoZSBzZWNvbmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gYyBUaGUgdGhpcmQgMzItYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZCBUaGUgZm91cnRoIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGUgVGhlIGZpZnRoIDMyLWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGQgKyBlXG4gICAgICovXG4gICAgc2FmZUFkZF8zMl81ID0gZnVuY3Rpb24oYSwgYiwgYywgZCwgZSkge1xuICAgICAgdmFyIGxzdyA9IChhICYgMHhGRkZGKSArIChiICYgMHhGRkZGKSArIChjICYgMHhGRkZGKSArIChkICYgMHhGRkZGKSArXG4gICAgICAgIChlICYgMHhGRkZGKSxcbiAgICAgICAgbXN3ID0gKGEgPj4+IDE2KSArIChiID4+PiAxNikgKyAoYyA+Pj4gMTYpICsgKGQgPj4+IDE2KSArXG4gICAgICAgICAgKGUgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcblxuICAgICAgcmV0dXJuICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgdHdvIDY0LWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl42NC4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geCBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0geSBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIHggKyB5XG4gICAgICovXG4gICAgc2FmZUFkZF82NF8yID0gZnVuY3Rpb24oeCwgeSkge1xuICAgICAgdmFyIGxzdywgbXN3LCBsb3dPcmRlciwgaGlnaE9yZGVyO1xuXG4gICAgICBsc3cgPSAoeC5sb3dPcmRlciAmIDB4RkZGRikgKyAoeS5sb3dPcmRlciAmIDB4RkZGRik7XG4gICAgICBtc3cgPSAoeC5sb3dPcmRlciA+Pj4gMTYpICsgKHkubG93T3JkZXIgPj4+IDE2KSArIChsc3cgPj4+IDE2KTtcbiAgICAgIGxvd09yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICBsc3cgPSAoeC5oaWdoT3JkZXIgJiAweEZGRkYpICsgKHkuaGlnaE9yZGVyICYgMHhGRkZGKSArIChtc3cgPj4+IDE2KTtcbiAgICAgIG1zdyA9ICh4LmhpZ2hPcmRlciA+Pj4gMTYpICsgKHkuaGlnaE9yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG4gICAgICBoaWdoT3JkZXIgPSAoKG1zdyAmIDB4RkZGRikgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG5cbiAgICAgIHJldHVybiBuZXcgSW50XzY0KGhpZ2hPcmRlciwgbG93T3JkZXIpO1xuICAgIH0sXG5cbiAgICAvKlxuICAgICAqIEFkZCBmb3VyIDY0LWJpdCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl42NC4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zXG4gICAgICogaW50ZXJuYWxseSB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gYSBUaGUgZmlyc3QgNjQtYml0IGludGVnZXIgYXJndW1lbnQgdG8gYmUgYWRkZWRcbiAgICAgKiBAcGFyYW0ge0ludF82NH0gYiBUaGUgc2Vjb25kIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGMgVGhlIHRoaXJkIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGQgVGhlIGZvdXRoIDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHJldHVybiBUaGUgc3VtIG9mIGEgKyBiICsgYyArIGRcbiAgICAgKi9cbiAgICBzYWZlQWRkXzY0XzQgPSBmdW5jdGlvbihhLCBiLCBjLCBkKSB7XG4gICAgICB2YXIgbHN3LCBtc3csIGxvd09yZGVyLCBoaWdoT3JkZXI7XG5cbiAgICAgIGxzdyA9IChhLmxvd09yZGVyICYgMHhGRkZGKSArIChiLmxvd09yZGVyICYgMHhGRkZGKSArXG4gICAgICAgIChjLmxvd09yZGVyICYgMHhGRkZGKSArIChkLmxvd09yZGVyICYgMHhGRkZGKTtcbiAgICAgIG1zdyA9IChhLmxvd09yZGVyID4+PiAxNikgKyAoYi5sb3dPcmRlciA+Pj4gMTYpICtcbiAgICAgICAgKGMubG93T3JkZXIgPj4+IDE2KSArIChkLmxvd09yZGVyID4+PiAxNikgKyAobHN3ID4+PiAxNik7XG4gICAgICBsb3dPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuICAgICAgbHN3ID0gKGEuaGlnaE9yZGVyICYgMHhGRkZGKSArIChiLmhpZ2hPcmRlciAmIDB4RkZGRikgK1xuICAgICAgICAoYy5oaWdoT3JkZXIgJiAweEZGRkYpICsgKGQuaGlnaE9yZGVyICYgMHhGRkZGKSArIChtc3cgPj4+IDE2KTtcbiAgICAgIG1zdyA9IChhLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGIuaGlnaE9yZGVyID4+PiAxNikgK1xuICAgICAgICAoYy5oaWdoT3JkZXIgPj4+IDE2KSArIChkLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuICAgICAgaGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChoaWdoT3JkZXIsIGxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBBZGQgZml2ZSA2NC1iaXQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeNjQuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9uc1xuICAgICAqIGludGVybmFsbHkgdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGEgVGhlIGZpcnN0IDY0LWJpdCBpbnRlZ2VyIGFyZ3VtZW50IHRvIGJlIGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRfNjR9IGIgVGhlIHNlY29uZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBjIFRoZSB0aGlyZCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBkIFRoZSBmb3V0aCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEBwYXJhbSB7SW50XzY0fSBlIFRoZSBmb3V0aCA2NC1iaXQgaW50ZWdlciBhcmd1bWVudCB0byBiZSBhZGRlZFxuICAgICAqIEByZXR1cm4gVGhlIHN1bSBvZiBhICsgYiArIGMgKyBkICsgZVxuICAgICAqL1xuICAgIHNhZmVBZGRfNjRfNSA9IGZ1bmN0aW9uKGEsIGIsIGMsIGQsIGUpIHtcbiAgICAgIHZhciBsc3csIG1zdywgbG93T3JkZXIsIGhpZ2hPcmRlcjtcblxuICAgICAgbHN3ID0gKGEubG93T3JkZXIgJiAweEZGRkYpICsgKGIubG93T3JkZXIgJiAweEZGRkYpICtcbiAgICAgICAgKGMubG93T3JkZXIgJiAweEZGRkYpICsgKGQubG93T3JkZXIgJiAweEZGRkYpICtcbiAgICAgICAgKGUubG93T3JkZXIgJiAweEZGRkYpO1xuICAgICAgbXN3ID0gKGEubG93T3JkZXIgPj4+IDE2KSArIChiLmxvd09yZGVyID4+PiAxNikgK1xuICAgICAgICAoYy5sb3dPcmRlciA+Pj4gMTYpICsgKGQubG93T3JkZXIgPj4+IDE2KSArIChlLmxvd09yZGVyID4+PiAxNikgK1xuICAgICAgICAobHN3ID4+PiAxNik7XG4gICAgICBsb3dPcmRlciA9ICgobXN3ICYgMHhGRkZGKSA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcblxuICAgICAgbHN3ID0gKGEuaGlnaE9yZGVyICYgMHhGRkZGKSArIChiLmhpZ2hPcmRlciAmIDB4RkZGRikgK1xuICAgICAgICAoYy5oaWdoT3JkZXIgJiAweEZGRkYpICsgKGQuaGlnaE9yZGVyICYgMHhGRkZGKSArXG4gICAgICAgIChlLmhpZ2hPcmRlciAmIDB4RkZGRikgKyAobXN3ID4+PiAxNik7XG4gICAgICBtc3cgPSAoYS5oaWdoT3JkZXIgPj4+IDE2KSArIChiLmhpZ2hPcmRlciA+Pj4gMTYpICtcbiAgICAgICAgKGMuaGlnaE9yZGVyID4+PiAxNikgKyAoZC5oaWdoT3JkZXIgPj4+IDE2KSArXG4gICAgICAgIChlLmhpZ2hPcmRlciA+Pj4gMTYpICsgKGxzdyA+Pj4gMTYpO1xuICAgICAgaGlnaE9yZGVyID0gKChtc3cgJiAweEZGRkYpIDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xuXG4gICAgICByZXR1cm4gbmV3IEludF82NChoaWdoT3JkZXIsIGxvd09yZGVyKTtcbiAgICB9LFxuXG4gICAgLypcbiAgICAgKiBDYWxjdWxhdGVzIHRoZSBTSEEtMSBoYXNoIG9mIHRoZSBzdHJpbmcgc2V0IGF0IGluc3RhbnRpYXRpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gbWVzc2FnZSBUaGUgYmluYXJ5IGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzdHJpbmcgdG9cbiAgICAgKlx0IGhhc2hcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gbWVzc2FnZUxlbiBUaGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIG1lc3NhZ2VcbiAgICAgKiBAcmV0dXJuIFRoZSBhcnJheSBvZiBpbnRlZ2VycyByZXByZXNlbnRpbmcgdGhlIFNIQS0xIGhhc2ggb2YgbWVzc2FnZVxuICAgICAqL1xuICAgIGNvcmVTSEExID0gZnVuY3Rpb24obWVzc2FnZSwgbWVzc2FnZUxlbikge1xuICAgICAgdmFyIFcgPSBbXSxcbiAgICAgICAgYSwgYiwgYywgZCwgZSwgVCwgY2ggPSBjaF8zMixcbiAgICAgICAgcGFyaXR5ID0gcGFyaXR5XzMyLFxuICAgICAgICBtYWogPSBtYWpfMzIsXG4gICAgICAgIHJvdGwgPSByb3RsXzMyLFxuICAgICAgICBzYWZlQWRkXzIgPSBzYWZlQWRkXzMyXzIsXG4gICAgICAgIGksIHQsXG4gICAgICAgIHNhZmVBZGRfNSA9IHNhZmVBZGRfMzJfNSxcbiAgICAgICAgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoLFxuICAgICAgICBIID0gW1xuICAgICAgICAgICAgMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSwgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3NiwgMHhjM2QyZTFmMFxuICAgICAgICBdLFxuICAgICAgICBLID0gW1xuICAgICAgICAgICAgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcbiAgICAgICAgICAgIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksXG4gICAgICAgICAgICAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LCAweDVhODI3OTk5LFxuICAgICAgICAgICAgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSwgMHg1YTgyNzk5OSxcbiAgICAgICAgICAgIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksIDB4NWE4Mjc5OTksXG4gICAgICAgICAgICAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLFxuICAgICAgICAgICAgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcbiAgICAgICAgICAgIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsIDB4NmVkOWViYTEsXG4gICAgICAgICAgICAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLCAweDZlZDllYmExLFxuICAgICAgICAgICAgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSwgMHg2ZWQ5ZWJhMSxcbiAgICAgICAgICAgIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsXG4gICAgICAgICAgICAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLFxuICAgICAgICAgICAgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYywgMHg4ZjFiYmNkYyxcbiAgICAgICAgICAgIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsIDB4OGYxYmJjZGMsXG4gICAgICAgICAgICAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLCAweDhmMWJiY2RjLFxuICAgICAgICAgICAgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcbiAgICAgICAgICAgIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsXG4gICAgICAgICAgICAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LCAweGNhNjJjMWQ2LFxuICAgICAgICAgICAgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNiwgMHhjYTYyYzFkNixcbiAgICAgICAgICAgIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDYsIDB4Y2E2MmMxZDZcbiAgICAgICAgXTtcblxuICAgICAgLyogQXBwZW5kICcxJyBhdCB0aGUgZW5kIG9mIHRoZSBiaW5hcnkgc3RyaW5nICovXG4gICAgICBtZXNzYWdlW21lc3NhZ2VMZW4gPj4gNV0gfD0gMHg4MCA8PCAoMjQgLSAobWVzc2FnZUxlbiAlIDMyKSk7XG4gICAgICAvKiBBcHBlbmQgbGVuZ3RoIG9mIGJpbmFyeSBzdHJpbmcgaW4gdGhlIHBvc2l0aW9uIHN1Y2ggdGhhdCB0aGUgbmV3XG5cdFx0bGVuZ3RoIGlzIGEgbXVsdGlwbGUgb2YgNTEyLiAgTG9naWMgZG9lcyBub3Qgd29yayBmb3IgZXZlbiBtdWx0aXBsZXNcblx0XHRvZiA1MTIgYnV0IHRoZXJlIGNhbiBuZXZlciBiZSBldmVuIG11bHRpcGxlcyBvZiA1MTIgKi9cbiAgICAgIG1lc3NhZ2VbKCgobWVzc2FnZUxlbiArIDY1KSA+PiA5KSA8PCA0KSArIDE1XSA9IG1lc3NhZ2VMZW47XG5cbiAgICAgIGFwcGVuZGVkTWVzc2FnZUxlbmd0aCA9IG1lc3NhZ2UubGVuZ3RoO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoOyBpICs9IDE2KSB7XG4gICAgICAgIGEgPSBIWzBdO1xuICAgICAgICBiID0gSFsxXTtcbiAgICAgICAgYyA9IEhbMl07XG4gICAgICAgIGQgPSBIWzNdO1xuICAgICAgICBlID0gSFs0XTtcblxuICAgICAgICBmb3IgKHQgPSAwOyB0IDwgODA7IHQgKz0gMSkge1xuICAgICAgICAgIGlmICh0IDwgMTYpIHtcbiAgICAgICAgICAgIFdbdF0gPSBtZXNzYWdlW3QgKyBpXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgV1t0XSA9IHJvdGwoV1t0IC0gM10gXiBXW3QgLSA4XSBeIFdbdCAtIDE0XSBeIFdbdCAtIDE2XSwgMSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHQgPCAyMCkge1xuICAgICAgICAgICAgVCA9IHNhZmVBZGRfNShyb3RsKGEsIDUpLCBjaChiLCBjLCBkKSwgZSwgS1t0XSwgV1t0XSk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0IDwgNDApIHtcbiAgICAgICAgICAgIFQgPSBzYWZlQWRkXzUocm90bChhLCA1KSwgcGFyaXR5KGIsIGMsIGQpLCBlLCBLW3RdLCBXW3RdKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHQgPCA2MCkge1xuICAgICAgICAgICAgVCA9IHNhZmVBZGRfNShyb3RsKGEsIDUpLCBtYWooYiwgYywgZCksIGUsIEtbdF0sIFdbdF0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBUID0gc2FmZUFkZF81KHJvdGwoYSwgNSksIHBhcml0eShiLCBjLCBkKSwgZSwgS1t0XSwgV1t0XSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZSA9IGQ7XG4gICAgICAgICAgZCA9IGM7XG4gICAgICAgICAgYyA9IHJvdGwoYiwgMzApO1xuICAgICAgICAgIGIgPSBhO1xuICAgICAgICAgIGEgPSBUO1xuICAgICAgICB9XG5cbiAgICAgICAgSFswXSA9IHNhZmVBZGRfMihhLCBIWzBdKTtcbiAgICAgICAgSFsxXSA9IHNhZmVBZGRfMihiLCBIWzFdKTtcbiAgICAgICAgSFsyXSA9IHNhZmVBZGRfMihjLCBIWzJdKTtcbiAgICAgICAgSFszXSA9IHNhZmVBZGRfMihkLCBIWzNdKTtcbiAgICAgICAgSFs0XSA9IHNhZmVBZGRfMihlLCBIWzRdKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEg7XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgZGVzaXJlZCBTSEEtMiBoYXNoIG9mIHRoZSBzdHJpbmcgc2V0IGF0IGluc3RhbnRpYXRpb25cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gVGhlIGJpbmFyeSBhcnJheSByZXByZXNlbnRhdGlvbiBvZiB0aGUgc3RyaW5nIHRvIGhhc2hcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gVGhlIG51bWJlciBvZiBiaXRzIGluIG1lc3NhZ2VcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdmFyaWFudCBUaGUgZGVzaXJlZCBTSEEtMiB2YXJpYW50XG4gICAgICogQHJldHVybiBUaGUgYXJyYXkgb2YgaW50ZWdlcnMgcmVwcmVzZW50aW5nIHRoZSBTSEEtMiBoYXNoIG9mIG1lc3NhZ2VcbiAgICAgKi9cbiAgICBjb3JlU0hBMiA9IGZ1bmN0aW9uKG1lc3NhZ2UsIG1lc3NhZ2VMZW4sIHZhcmlhbnQpIHtcbiAgICAgIHZhciBhLCBiLCBjLCBkLCBlLCBmLCBnLCBoLCBUMSwgVDIsIEgsIG51bVJvdW5kcywgbGVuZ3RoUG9zaXRpb24sIGksIHQsXG4gICAgICAgIGJpbmFyeVN0cmluZ0luYywgYmluYXJ5U3RyaW5nTXVsdCwgc2FmZUFkZF8yLCBzYWZlQWRkXzQsIHNhZmVBZGRfNSxcbiAgICAgICAgZ2FtbWEwLCBnYW1tYTEsIHNpZ21hMCwgc2lnbWExLCBjaCwgbWFqLCBJbnQsIEssIFcgPSBbXSxcbiAgICAgICAgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoO1xuXG4gICAgICAvKiBTZXQgdXAgdGhlIHZhcmlvdXMgZnVuY3Rpb24gaGFuZGxlcyBhbmQgdmFyaWFibGUgZm9yIHRoZSBzcGVjaWZpYyBcbiAgICAgICAqIHZhcmlhbnQgKi9cbiAgICAgIGlmICh2YXJpYW50ID09PSBcIlNIQS0yMjRcIiB8fCB2YXJpYW50ID09PSBcIlNIQS0yNTZcIikge1xuICAgICAgICAvKiAzMi1iaXQgdmFyaWFudCAqL1xuICAgICAgICBudW1Sb3VuZHMgPSA2NDtcbiAgICAgICAgbGVuZ3RoUG9zaXRpb24gPSAoKChtZXNzYWdlTGVuICsgNjUpID4+IDkpIDw8IDQpICsgMTU7XG4gICAgICAgIGJpbmFyeVN0cmluZ0luYyA9IDE2O1xuICAgICAgICBiaW5hcnlTdHJpbmdNdWx0ID0gMTtcbiAgICAgICAgSW50ID0gTnVtYmVyO1xuICAgICAgICBzYWZlQWRkXzIgPSBzYWZlQWRkXzMyXzI7XG4gICAgICAgIHNhZmVBZGRfNCA9IHNhZmVBZGRfMzJfNDtcbiAgICAgICAgc2FmZUFkZF81ID0gc2FmZUFkZF8zMl81O1xuICAgICAgICBnYW1tYTAgPSBnYW1tYTBfMzI7XG4gICAgICAgIGdhbW1hMSA9IGdhbW1hMV8zMjtcbiAgICAgICAgc2lnbWEwID0gc2lnbWEwXzMyO1xuICAgICAgICBzaWdtYTEgPSBzaWdtYTFfMzI7XG4gICAgICAgIG1haiA9IG1hal8zMjtcbiAgICAgICAgY2ggPSBjaF8zMjtcbiAgICAgICAgSyA9IFtcbiAgICAgICAgICAgIDB4NDI4QTJGOTgsIDB4NzEzNzQ0OTEsIDB4QjVDMEZCQ0YsIDB4RTlCNURCQTUsXG4gICAgICAgICAgICAweDM5NTZDMjVCLCAweDU5RjExMUYxLCAweDkyM0Y4MkE0LCAweEFCMUM1RUQ1LFxuICAgICAgICAgICAgMHhEODA3QUE5OCwgMHgxMjgzNUIwMSwgMHgyNDMxODVCRSwgMHg1NTBDN0RDMyxcbiAgICAgICAgICAgIDB4NzJCRTVENzQsIDB4ODBERUIxRkUsIDB4OUJEQzA2QTcsIDB4QzE5QkYxNzQsXG4gICAgICAgICAgICAweEU0OUI2OUMxLCAweEVGQkU0Nzg2LCAweDBGQzE5REM2LCAweDI0MENBMUNDLFxuICAgICAgICAgICAgMHgyREU5MkM2RiwgMHg0QTc0ODRBQSwgMHg1Q0IwQTlEQywgMHg3NkY5ODhEQSxcbiAgICAgICAgICAgIDB4OTgzRTUxNTIsIDB4QTgzMUM2NkQsIDB4QjAwMzI3QzgsIDB4QkY1OTdGQzcsXG4gICAgICAgICAgICAweEM2RTAwQkYzLCAweEQ1QTc5MTQ3LCAweDA2Q0E2MzUxLCAweDE0MjkyOTY3LFxuICAgICAgICAgICAgMHgyN0I3MEE4NSwgMHgyRTFCMjEzOCwgMHg0RDJDNkRGQywgMHg1MzM4MEQxMyxcbiAgICAgICAgICAgIDB4NjUwQTczNTQsIDB4NzY2QTBBQkIsIDB4ODFDMkM5MkUsIDB4OTI3MjJDODUsXG4gICAgICAgICAgICAweEEyQkZFOEExLCAweEE4MUE2NjRCLCAweEMyNEI4QjcwLCAweEM3NkM1MUEzLFxuICAgICAgICAgICAgMHhEMTkyRTgxOSwgMHhENjk5MDYyNCwgMHhGNDBFMzU4NSwgMHgxMDZBQTA3MCxcbiAgICAgICAgICAgIDB4MTlBNEMxMTYsIDB4MUUzNzZDMDgsIDB4Mjc0ODc3NEMsIDB4MzRCMEJDQjUsXG4gICAgICAgICAgICAweDM5MUMwQ0IzLCAweDRFRDhBQTRBLCAweDVCOUNDQTRGLCAweDY4MkU2RkYzLFxuICAgICAgICAgICAgMHg3NDhGODJFRSwgMHg3OEE1NjM2RiwgMHg4NEM4NzgxNCwgMHg4Q0M3MDIwOCxcbiAgICAgICAgICAgIDB4OTBCRUZGRkEsIDB4QTQ1MDZDRUIsIDB4QkVGOUEzRjcsIDB4QzY3MTc4RjJcbiAgICAgICAgXTtcblxuICAgICAgICBpZiAodmFyaWFudCA9PT0gXCJTSEEtMjI0XCIpIHtcbiAgICAgICAgICBIID0gW1xuICAgICAgICAgICAgICAweGMxMDU5ZWQ4LCAweDM2N2NkNTA3LCAweDMwNzBkZDE3LCAweGY3MGU1OTM5LFxuICAgICAgICAgICAgICAweGZmYzAwYjMxLCAweDY4NTgxNTExLCAweDY0Zjk4ZmE3LCAweGJlZmE0ZmE0XG4gICAgICAgICAgXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBIID0gW1xuICAgICAgICAgICAgICAweDZBMDlFNjY3LCAweEJCNjdBRTg1LCAweDNDNkVGMzcyLCAweEE1NEZGNTNBLFxuICAgICAgICAgICAgICAweDUxMEU1MjdGLCAweDlCMDU2ODhDLCAweDFGODNEOUFCLCAweDVCRTBDRDE5XG4gICAgICAgICAgXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh2YXJpYW50ID09PSBcIlNIQS0zODRcIiB8fCB2YXJpYW50ID09PSBcIlNIQS01MTJcIikge1xuICAgICAgICAvKiA2NC1iaXQgdmFyaWFudCAqL1xuICAgICAgICBudW1Sb3VuZHMgPSA4MDtcbiAgICAgICAgbGVuZ3RoUG9zaXRpb24gPSAoKChtZXNzYWdlTGVuICsgMTI4KSA+PiAxMCkgPDwgNSkgKyAzMTtcbiAgICAgICAgYmluYXJ5U3RyaW5nSW5jID0gMzI7XG4gICAgICAgIGJpbmFyeVN0cmluZ011bHQgPSAyO1xuICAgICAgICBJbnQgPSBJbnRfNjQ7XG4gICAgICAgIHNhZmVBZGRfMiA9IHNhZmVBZGRfNjRfMjtcbiAgICAgICAgc2FmZUFkZF80ID0gc2FmZUFkZF82NF80O1xuICAgICAgICBzYWZlQWRkXzUgPSBzYWZlQWRkXzY0XzU7XG4gICAgICAgIGdhbW1hMCA9IGdhbW1hMF82NDtcbiAgICAgICAgZ2FtbWExID0gZ2FtbWExXzY0O1xuICAgICAgICBzaWdtYTAgPSBzaWdtYTBfNjQ7XG4gICAgICAgIHNpZ21hMSA9IHNpZ21hMV82NDtcbiAgICAgICAgbWFqID0gbWFqXzY0O1xuICAgICAgICBjaCA9IGNoXzY0O1xuXG4gICAgICAgIEsgPSBbXG4gICAgICAgICAgICBuZXcgSW50KDB4NDI4YTJmOTgsIDB4ZDcyOGFlMjIpLCBuZXcgSW50KDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QpLFxuICAgICAgICAgICAgbmV3IEludCgweGI1YzBmYmNmLCAweGVjNGQzYjJmKSwgbmV3IEludCgweGU5YjVkYmE1LCAweDgxODlkYmJjKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgzOTU2YzI1YiwgMHhmMzQ4YjUzOCksIG5ldyBJbnQoMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOSksXG4gICAgICAgICAgICBuZXcgSW50KDB4OTIzZjgyYTQsIDB4YWYxOTRmOWIpLCBuZXcgSW50KDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgpLFxuICAgICAgICAgICAgbmV3IEludCgweGQ4MDdhYTk4LCAweGEzMDMwMjQyKSwgbmV3IEludCgweDEyODM1YjAxLCAweDQ1NzA2ZmJlKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgyNDMxODViZSwgMHg0ZWU0YjI4YyksIG5ldyBJbnQoMHg1NTBjN2RjMywgMHhkNWZmYjRlMiksXG4gICAgICAgICAgICBuZXcgSW50KDB4NzJiZTVkNzQsIDB4ZjI3Yjg5NmYpLCBuZXcgSW50KDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEpLFxuICAgICAgICAgICAgbmV3IEludCgweDliZGMwNmE3LCAweDI1YzcxMjM1KSwgbmV3IEludCgweGMxOWJmMTc0LCAweGNmNjkyNjk0KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhlNDliNjljMSwgMHg5ZWYxNGFkMiksIG5ldyBJbnQoMHhlZmJlNDc4NiwgMHgzODRmMjVlMyksXG4gICAgICAgICAgICBuZXcgSW50KDB4MGZjMTlkYzYsIDB4OGI4Y2Q1YjUpLCBuZXcgSW50KDB4MjQwY2ExY2MsIDB4NzdhYzljNjUpLFxuICAgICAgICAgICAgbmV3IEludCgweDJkZTkyYzZmLCAweDU5MmIwMjc1KSwgbmV3IEludCgweDRhNzQ4NGFhLCAweDZlYTZlNDgzKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg1Y2IwYTlkYywgMHhiZDQxZmJkNCksIG5ldyBJbnQoMHg3NmY5ODhkYSwgMHg4MzExNTNiNSksXG4gICAgICAgICAgICBuZXcgSW50KDB4OTgzZTUxNTIsIDB4ZWU2NmRmYWIpLCBuZXcgSW50KDB4YTgzMWM2NmQsIDB4MmRiNDMyMTApLFxuICAgICAgICAgICAgbmV3IEludCgweGIwMDMyN2M4LCAweDk4ZmIyMTNmKSwgbmV3IEludCgweGJmNTk3ZmM3LCAweGJlZWYwZWU0KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhjNmUwMGJmMywgMHgzZGE4OGZjMiksIG5ldyBJbnQoMHhkNWE3OTE0NywgMHg5MzBhYTcyNSksXG4gICAgICAgICAgICBuZXcgSW50KDB4MDZjYTYzNTEsIDB4ZTAwMzgyNmYpLCBuZXcgSW50KDB4MTQyOTI5NjcsIDB4MGEwZTZlNzApLFxuICAgICAgICAgICAgbmV3IEludCgweDI3YjcwYTg1LCAweDQ2ZDIyZmZjKSwgbmV3IEludCgweDJlMWIyMTM4LCAweDVjMjZjOTI2KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg0ZDJjNmRmYywgMHg1YWM0MmFlZCksIG5ldyBJbnQoMHg1MzM4MGQxMywgMHg5ZDk1YjNkZiksXG4gICAgICAgICAgICBuZXcgSW50KDB4NjUwYTczNTQsIDB4OGJhZjYzZGUpLCBuZXcgSW50KDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgpLFxuICAgICAgICAgICAgbmV3IEludCgweDgxYzJjOTJlLCAweDQ3ZWRhZWU2KSwgbmV3IEludCgweDkyNzIyYzg1LCAweDE0ODIzNTNiKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhhMmJmZThhMSwgMHg0Y2YxMDM2NCksIG5ldyBJbnQoMHhhODFhNjY0YiwgMHhiYzQyMzAwMSksXG4gICAgICAgICAgICBuZXcgSW50KDB4YzI0YjhiNzAsIDB4ZDBmODk3OTEpLCBuZXcgSW50KDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzApLFxuICAgICAgICAgICAgbmV3IEludCgweGQxOTJlODE5LCAweGQ2ZWY1MjE4KSwgbmV3IEludCgweGQ2OTkwNjI0LCAweDU1NjVhOTEwKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhmNDBlMzU4NSwgMHg1NzcxMjAyYSksIG5ldyBJbnQoMHgxMDZhYTA3MCwgMHgzMmJiZDFiOCksXG4gICAgICAgICAgICBuZXcgSW50KDB4MTlhNGMxMTYsIDB4YjhkMmQwYzgpLCBuZXcgSW50KDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMpLFxuICAgICAgICAgICAgbmV3IEludCgweDI3NDg3NzRjLCAweGRmOGVlYjk5KSwgbmV3IEludCgweDM0YjBiY2I1LCAweGUxOWI0OGE4KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgzOTFjMGNiMywgMHhjNWM5NWE2MyksIG5ldyBJbnQoMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYiksXG4gICAgICAgICAgICBuZXcgSW50KDB4NWI5Y2NhNGYsIDB4Nzc2M2UzNzMpLCBuZXcgSW50KDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMpLFxuICAgICAgICAgICAgbmV3IEludCgweDc0OGY4MmVlLCAweDVkZWZiMmZjKSwgbmV3IEludCgweDc4YTU2MzZmLCAweDQzMTcyZjYwKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg4NGM4NzgxNCwgMHhhMWYwYWI3MiksIG5ldyBJbnQoMHg4Y2M3MDIwOCwgMHgxYTY0MzllYyksXG4gICAgICAgICAgICBuZXcgSW50KDB4OTBiZWZmZmEsIDB4MjM2MzFlMjgpLCBuZXcgSW50KDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTkpLFxuICAgICAgICAgICAgbmV3IEludCgweGJlZjlhM2Y3LCAweGIyYzY3OTE1KSwgbmV3IEludCgweGM2NzE3OGYyLCAweGUzNzI1MzJiKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHhjYTI3M2VjZSwgMHhlYTI2NjE5YyksIG5ldyBJbnQoMHhkMTg2YjhjNywgMHgyMWMwYzIwNyksXG4gICAgICAgICAgICBuZXcgSW50KDB4ZWFkYTdkZDYsIDB4Y2RlMGViMWUpLCBuZXcgSW50KDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgpLFxuICAgICAgICAgICAgbmV3IEludCgweDA2ZjA2N2FhLCAweDcyMTc2ZmJhKSwgbmV3IEludCgweDBhNjM3ZGM1LCAweGEyYzg5OGE2KSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHgxMTNmOTgwNCwgMHhiZWY5MGRhZSksIG5ldyBJbnQoMHgxYjcxMGIzNSwgMHgxMzFjNDcxYiksXG4gICAgICAgICAgICBuZXcgSW50KDB4MjhkYjc3ZjUsIDB4MjMwNDdkODQpLCBuZXcgSW50KDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMpLFxuICAgICAgICAgICAgbmV3IEludCgweDNjOWViZTBhLCAweDE1YzliZWJjKSwgbmV3IEludCgweDQzMWQ2N2M0LCAweDljMTAwZDRjKSxcbiAgICAgICAgICAgIG5ldyBJbnQoMHg0Y2M1ZDRiZSwgMHhjYjNlNDJiNiksIG5ldyBJbnQoMHg1OTdmMjk5YywgMHhmYzY1N2UyYSksXG4gICAgICAgICAgICBuZXcgSW50KDB4NWZjYjZmYWIsIDB4M2FkNmZhZWMpLCBuZXcgSW50KDB4NmM0NDE5OGMsIDB4NGE0NzU4MTcpXG4gICAgICAgIF07XG5cbiAgICAgICAgaWYgKHZhcmlhbnQgPT09IFwiU0hBLTM4NFwiKSB7XG4gICAgICAgICAgSCA9IFtcbiAgICAgICAgICAgICAgbmV3IEludCgweGNiYmI5ZDVkLCAweGMxMDU5ZWQ4KSwgbmV3IEludCgweDA2MjlhMjkyYSwgMHgzNjdjZDUwNyksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHg5MTU5MDE1YSwgMHgzMDcwZGQxNyksIG5ldyBJbnQoMHgwMTUyZmVjZDgsIDB4ZjcwZTU5MzkpLFxuICAgICAgICAgICAgICBuZXcgSW50KDB4NjczMzI2NjcsIDB4ZmZjMDBiMzEpLCBuZXcgSW50KDB4OThlYjQ0YTg3LCAweDY4NTgxNTExKSxcbiAgICAgICAgICAgICAgbmV3IEludCgweGRiMGMyZTBkLCAweDY0Zjk4ZmE3KSwgbmV3IEludCgweDA0N2I1NDgxZCwgMHhiZWZhNGZhNClcbiAgICAgICAgICBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIEggPSBbXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCksIG5ldyBJbnQoMHhiYjY3YWU4NSwgMHg4NGNhYTczYiksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHgzYzZlZjM3MiwgMHhmZTk0ZjgyYiksIG5ldyBJbnQoMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHg1MTBlNTI3ZiwgMHhhZGU2ODJkMSksIG5ldyBJbnQoMHg5YjA1Njg4YywgMHgyYjNlNmMxZiksXG4gICAgICAgICAgICAgIG5ldyBJbnQoMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YiksIG5ldyBJbnQoMHg1YmUwY2QxOSwgMHgxMzdlMjE3OSlcbiAgICAgICAgICBdO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8qIEFwcGVuZCAnMScgYXQgdGhlIGVuZCBvZiB0aGUgYmluYXJ5IHN0cmluZyAqL1xuICAgICAgbWVzc2FnZVttZXNzYWdlTGVuID4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gbWVzc2FnZUxlbiAlIDMyKTtcbiAgICAgIC8qIEFwcGVuZCBsZW5ndGggb2YgYmluYXJ5IHN0cmluZyBpbiB0aGUgcG9zaXRpb24gc3VjaCB0aGF0IHRoZSBuZXdcbiAgICAgICAqIGxlbmd0aCBpcyBjb3JyZWN0ICovXG4gICAgICBtZXNzYWdlW2xlbmd0aFBvc2l0aW9uXSA9IG1lc3NhZ2VMZW47XG5cbiAgICAgIGFwcGVuZGVkTWVzc2FnZUxlbmd0aCA9IG1lc3NhZ2UubGVuZ3RoO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgYXBwZW5kZWRNZXNzYWdlTGVuZ3RoOyBpICs9IGJpbmFyeVN0cmluZ0luYykge1xuICAgICAgICBhID0gSFswXTtcbiAgICAgICAgYiA9IEhbMV07XG4gICAgICAgIGMgPSBIWzJdO1xuICAgICAgICBkID0gSFszXTtcbiAgICAgICAgZSA9IEhbNF07XG4gICAgICAgIGYgPSBIWzVdO1xuICAgICAgICBnID0gSFs2XTtcbiAgICAgICAgaCA9IEhbN107XG5cbiAgICAgICAgZm9yICh0ID0gMDsgdCA8IG51bVJvdW5kczsgdCArPSAxKSB7XG4gICAgICAgICAgaWYgKHQgPCAxNikge1xuICAgICAgICAgICAgLyogQml0IG9mIGEgaGFjayAtIGZvciAzMi1iaXQsIHRoZSBzZWNvbmQgdGVybSBpcyBpZ25vcmVkICovXG4gICAgICAgICAgICBXW3RdID0gbmV3IEludChtZXNzYWdlW3QgKiBiaW5hcnlTdHJpbmdNdWx0ICsgaV0sXG4gICAgICAgICAgICAgIG1lc3NhZ2VbdCAqIGJpbmFyeVN0cmluZ011bHQgKyBpICsgMV0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBXW3RdID0gc2FmZUFkZF80KFxuICAgICAgICAgICAgICBnYW1tYTEoV1t0IC0gMl0pLCBXW3QgLSA3XSxcbiAgICAgICAgICAgICAgZ2FtbWEwKFdbdCAtIDE1XSksIFdbdCAtIDE2XSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgVDEgPSBzYWZlQWRkXzUoaCwgc2lnbWExKGUpLCBjaChlLCBmLCBnKSwgS1t0XSwgV1t0XSk7XG4gICAgICAgICAgVDIgPSBzYWZlQWRkXzIoc2lnbWEwKGEpLCBtYWooYSwgYiwgYykpO1xuICAgICAgICAgIGggPSBnO1xuICAgICAgICAgIGcgPSBmO1xuICAgICAgICAgIGYgPSBlO1xuICAgICAgICAgIGUgPSBzYWZlQWRkXzIoZCwgVDEpO1xuICAgICAgICAgIGQgPSBjO1xuICAgICAgICAgIGMgPSBiO1xuICAgICAgICAgIGIgPSBhO1xuICAgICAgICAgIGEgPSBzYWZlQWRkXzIoVDEsIFQyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIEhbMF0gPSBzYWZlQWRkXzIoYSwgSFswXSk7XG4gICAgICAgIEhbMV0gPSBzYWZlQWRkXzIoYiwgSFsxXSk7XG4gICAgICAgIEhbMl0gPSBzYWZlQWRkXzIoYywgSFsyXSk7XG4gICAgICAgIEhbM10gPSBzYWZlQWRkXzIoZCwgSFszXSk7XG4gICAgICAgIEhbNF0gPSBzYWZlQWRkXzIoZSwgSFs0XSk7XG4gICAgICAgIEhbNV0gPSBzYWZlQWRkXzIoZiwgSFs1XSk7XG4gICAgICAgIEhbNl0gPSBzYWZlQWRkXzIoZywgSFs2XSk7XG4gICAgICAgIEhbN10gPSBzYWZlQWRkXzIoaCwgSFs3XSk7XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAodmFyaWFudCkge1xuICAgICAgICBjYXNlIFwiU0hBLTIyNFwiOlxuICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICBIWzBdLCBIWzFdLCBIWzJdLCBIWzNdLFxuICAgICAgICAgICAgSFs0XSwgSFs1XSwgSFs2XV07XG4gICAgICAgIGNhc2UgXCJTSEEtMjU2XCI6XG4gICAgICAgICAgcmV0dXJuIEg7XG4gICAgICAgIGNhc2UgXCJTSEEtMzg0XCI6XG4gICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIEhbMF0uaGlnaE9yZGVyLCBIWzBdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFsxXS5oaWdoT3JkZXIsIEhbMV0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzJdLmhpZ2hPcmRlciwgSFsyXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbM10uaGlnaE9yZGVyLCBIWzNdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs0XS5oaWdoT3JkZXIsIEhbNF0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzVdLmhpZ2hPcmRlciwgSFs1XS5sb3dPcmRlcl07XG4gICAgICAgIGNhc2UgXCJTSEEtNTEyXCI6XG4gICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIEhbMF0uaGlnaE9yZGVyLCBIWzBdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFsxXS5oaWdoT3JkZXIsIEhbMV0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzJdLmhpZ2hPcmRlciwgSFsyXS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbM10uaGlnaE9yZGVyLCBIWzNdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs0XS5oaWdoT3JkZXIsIEhbNF0ubG93T3JkZXIsXG4gICAgICAgICAgICBIWzVdLmhpZ2hPcmRlciwgSFs1XS5sb3dPcmRlcixcbiAgICAgICAgICAgIEhbNl0uaGlnaE9yZGVyLCBIWzZdLmxvd09yZGVyLFxuICAgICAgICAgICAgSFs3XS5oaWdoT3JkZXIsIEhbN10ubG93T3JkZXJdO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8qIFRoaXMgc2hvdWxkIG5ldmVyIGJlIHJlYWNoZWQgKi9cbiAgICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qXG4gICAgICoganNTSEEgaXMgdGhlIHdvcmtob3JzZSBvZiB0aGUgbGlicmFyeS4gIEluc3RhbnRpYXRlIGl0IHdpdGggdGhlIHN0cmluZyB0b1xuICAgICAqIGJlIGhhc2hlZCBhcyB0aGUgcGFyYW1ldGVyXG4gICAgICpcbiAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gc3JjU3RyaW5nIFRoZSBzdHJpbmcgdG8gYmUgaGFzaGVkXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0Rm9ybWF0IFRoZSBmb3JtYXQgb2Ygc3JjU3RyaW5nLCBBU0NJSSBvciBIRVhcbiAgICAgKi9cbiAgICBqc1NIQSA9IGZ1bmN0aW9uKHNyY1N0cmluZywgaW5wdXRGb3JtYXQpIHtcblxuICAgICAgdGhpcy5zaGExID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhMjI0ID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhMjU2ID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhMzg0ID0gbnVsbDtcbiAgICAgIHRoaXMuc2hhNTEyID0gbnVsbDtcblxuICAgICAgdGhpcy5zdHJCaW5MZW4gPSBudWxsO1xuICAgICAgdGhpcy5zdHJUb0hhc2ggPSBudWxsO1xuXG4gICAgICAvKiBDb252ZXJ0IHRoZSBpbnB1dCBzdHJpbmcgaW50byB0aGUgY29ycmVjdCB0eXBlICovXG4gICAgICBpZiAoXCJIRVhcIiA9PT0gaW5wdXRGb3JtYXQpIHtcbiAgICAgICAgaWYgKDAgIT09IChzcmNTdHJpbmcubGVuZ3RoICUgMikpIHtcbiAgICAgICAgICByZXR1cm4gXCJURVhUIE1VU1QgQkUgSU4gQllURSBJTkNSRU1FTlRTXCI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdHJCaW5MZW4gPSBzcmNTdHJpbmcubGVuZ3RoICogNDtcbiAgICAgICAgdGhpcy5zdHJUb0hhc2ggPSBoZXgyYmluYihzcmNTdHJpbmcpO1xuICAgICAgfSBlbHNlIGlmICgoXCJBU0NJSVwiID09PSBpbnB1dEZvcm1hdCkgfHxcbiAgICAgICAgKCd1bmRlZmluZWQnID09PSB0eXBlb2YoaW5wdXRGb3JtYXQpKSkge1xuICAgICAgICB0aGlzLnN0ckJpbkxlbiA9IHNyY1N0cmluZy5sZW5ndGggKiBjaGFyU2l6ZTtcbiAgICAgICAgdGhpcy5zdHJUb0hhc2ggPSBzdHIyYmluYihzcmNTdHJpbmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFwiVU5LTk9XTiBURVhUIElOUFVUIFRZUEVcIjtcbiAgICAgIH1cbiAgICB9O1xuXG4gIGpzU0hBLnByb3RvdHlwZSA9IHtcbiAgICAvKlxuICAgICAqIFJldHVybnMgdGhlIGRlc2lyZWQgU0hBIGhhc2ggb2YgdGhlIHN0cmluZyBzcGVjaWZpZWQgYXQgaW5zdGFudGlhdGlvblxuICAgICAqIHVzaW5nIHRoZSBzcGVjaWZpZWQgcGFyYW1ldGVyc1xuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHZhcmlhbnQgVGhlIGRlc2lyZWQgU0hBIHZhcmlhbnQgKFNIQS0xLCBTSEEtMjI0LFxuICAgICAqXHQgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMilcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZm9ybWF0IFRoZSBkZXNpcmVkIG91dHB1dCBmb3JtYXR0aW5nIChCNjQgb3IgSEVYKVxuICAgICAqIEByZXR1cm4gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaGFzaCBpbiB0aGUgZm9ybWF0IHNwZWNpZmllZFxuICAgICAqL1xuICAgIGdldEhhc2g6IGZ1bmN0aW9uKHZhcmlhbnQsIGZvcm1hdCkge1xuICAgICAgdmFyIGZvcm1hdEZ1bmMgPSBudWxsLFxuICAgICAgICBtZXNzYWdlID0gdGhpcy5zdHJUb0hhc2guc2xpY2UoKTtcblxuICAgICAgc3dpdGNoIChmb3JtYXQpIHtcbiAgICAgICAgY2FzZSBcIkhFWFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmhleDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkI2NFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmI2NDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkFTQ0lJXCI6XG4gICAgICAgICAgZm9ybWF0RnVuYyA9IGJpbmIyc3RyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBcIkZPUk1BVCBOT1QgUkVDT0dOSVpFRFwiO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHZhcmlhbnQpIHtcbiAgICAgICAgY2FzZSBcIlNIQS0xXCI6XG4gICAgICAgICAgaWYgKG51bGwgPT09IHRoaXMuc2hhMSkge1xuICAgICAgICAgICAgdGhpcy5zaGExID0gY29yZVNIQTEobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTEpO1xuICAgICAgICBjYXNlIFwiU0hBLTIyNFwiOlxuICAgICAgICAgIGlmIChudWxsID09PSB0aGlzLnNoYTIyNCkge1xuICAgICAgICAgICAgdGhpcy5zaGEyMjQgPSBjb3JlU0hBMihtZXNzYWdlLCB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmb3JtYXRGdW5jKHRoaXMuc2hhMjI0KTtcbiAgICAgICAgY2FzZSBcIlNIQS0yNTZcIjpcbiAgICAgICAgICBpZiAobnVsbCA9PT0gdGhpcy5zaGEyNTYpIHtcbiAgICAgICAgICAgIHRoaXMuc2hhMjU2ID0gY29yZVNIQTIobWVzc2FnZSwgdGhpcy5zdHJCaW5MZW4sIHZhcmlhbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZm9ybWF0RnVuYyh0aGlzLnNoYTI1Nik7XG4gICAgICAgIGNhc2UgXCJTSEEtMzg0XCI6XG4gICAgICAgICAgaWYgKG51bGwgPT09IHRoaXMuc2hhMzg0KSB7XG4gICAgICAgICAgICB0aGlzLnNoYTM4NCA9IGNvcmVTSEEyKG1lc3NhZ2UsIHRoaXMuc3RyQmluTGVuLCB2YXJpYW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGZvcm1hdEZ1bmModGhpcy5zaGEzODQpO1xuICAgICAgICBjYXNlIFwiU0hBLTUxMlwiOlxuICAgICAgICAgIGlmIChudWxsID09PSB0aGlzLnNoYTUxMikge1xuICAgICAgICAgICAgdGhpcy5zaGE1MTIgPSBjb3JlU0hBMihtZXNzYWdlLCB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmb3JtYXRGdW5jKHRoaXMuc2hhNTEyKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gXCJIQVNIIE5PVCBSRUNPR05JWkVEXCI7XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8qXG4gICAgICogUmV0dXJucyB0aGUgZGVzaXJlZCBITUFDIG9mIHRoZSBzdHJpbmcgc3BlY2lmaWVkIGF0IGluc3RhbnRpYXRpb25cbiAgICAgKiB1c2luZyB0aGUga2V5IGFuZCB2YXJpYW50IHBhcmFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGtleSBUaGUga2V5IHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBITUFDXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0Rm9ybWF0IFRoZSBmb3JtYXQgb2Yga2V5LCBBU0NJSSBvciBIRVhcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdmFyaWFudCBUaGUgZGVzaXJlZCBTSEEgdmFyaWFudCAoU0hBLTEsIFNIQS0yMjQsXG4gICAgICpcdCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyKVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBvdXRwdXRGb3JtYXQgVGhlIGRlc2lyZWQgb3V0cHV0IGZvcm1hdHRpbmdcbiAgICAgKlx0IChCNjQgb3IgSEVYKVxuICAgICAqIEByZXR1cm4gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaGFzaCBpbiB0aGUgZm9ybWF0IHNwZWNpZmllZFxuICAgICAqL1xuICAgIGdldEhNQUM6IGZ1bmN0aW9uKGtleSwgaW5wdXRGb3JtYXQsIHZhcmlhbnQsIG91dHB1dEZvcm1hdCkge1xuICAgICAgdmFyIGZvcm1hdEZ1bmMsIGtleVRvVXNlLCBibG9ja0J5dGVTaXplLCBibG9ja0JpdFNpemUsIGksXG4gICAgICAgIHJldFZhbCwgbGFzdEFycmF5SW5kZXgsIGtleUJpbkxlbiwgaGFzaEJpdFNpemUsXG4gICAgICAgIGtleVdpdGhJUGFkID0gW10sXG4gICAgICAgIGtleVdpdGhPUGFkID0gW107XG5cbiAgICAgIC8qIFZhbGlkYXRlIHRoZSBvdXRwdXQgZm9ybWF0IHNlbGVjdGlvbiAqL1xuICAgICAgc3dpdGNoIChvdXRwdXRGb3JtYXQpIHtcbiAgICAgICAgY2FzZSBcIkhFWFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmhleDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkI2NFwiOlxuICAgICAgICAgIGZvcm1hdEZ1bmMgPSBiaW5iMmI2NDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIkFTQ0lJXCI6XG4gICAgICAgICAgZm9ybWF0RnVuYyA9IGJpbmIyc3RyO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiBcIkZPUk1BVCBOT1QgUkVDT0dOSVpFRFwiO1xuICAgICAgfVxuXG4gICAgICAvKiBWYWxpZGF0ZSB0aGUgaGFzaCB2YXJpYW50IHNlbGVjdGlvbiBhbmQgc2V0IG5lZWRlZCB2YXJpYWJsZXMgKi9cbiAgICAgIHN3aXRjaCAodmFyaWFudCkge1xuICAgICAgICBjYXNlIFwiU0hBLTFcIjpcbiAgICAgICAgICBibG9ja0J5dGVTaXplID0gNjQ7XG4gICAgICAgICAgaGFzaEJpdFNpemUgPSAxNjA7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJTSEEtMjI0XCI6XG4gICAgICAgICAgYmxvY2tCeXRlU2l6ZSA9IDY0O1xuICAgICAgICAgIGhhc2hCaXRTaXplID0gMjI0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiU0hBLTI1NlwiOlxuICAgICAgICAgIGJsb2NrQnl0ZVNpemUgPSA2NDtcbiAgICAgICAgICBoYXNoQml0U2l6ZSA9IDI1NjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcIlNIQS0zODRcIjpcbiAgICAgICAgICBibG9ja0J5dGVTaXplID0gMTI4O1xuICAgICAgICAgIGhhc2hCaXRTaXplID0gMzg0O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiU0hBLTUxMlwiOlxuICAgICAgICAgIGJsb2NrQnl0ZVNpemUgPSAxMjg7XG4gICAgICAgICAgaGFzaEJpdFNpemUgPSA1MTI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIFwiSEFTSCBOT1QgUkVDT0dOSVpFRFwiO1xuICAgICAgfVxuXG4gICAgICAvKiBWYWxpZGF0ZSBpbnB1dCBmb3JtYXQgc2VsZWN0aW9uICovXG4gICAgICBpZiAoXCJIRVhcIiA9PT0gaW5wdXRGb3JtYXQpIHtcbiAgICAgICAgLyogTmliYmxlcyBtdXN0IGNvbWUgaW4gcGFpcnMgKi9cbiAgICAgICAgaWYgKDAgIT09IChrZXkubGVuZ3RoICUgMikpIHtcbiAgICAgICAgICByZXR1cm4gXCJLRVkgTVVTVCBCRSBJTiBCWVRFIElOQ1JFTUVOVFNcIjtcbiAgICAgICAgfVxuICAgICAgICBrZXlUb1VzZSA9IGhleDJiaW5iKGtleSk7XG4gICAgICAgIGtleUJpbkxlbiA9IGtleS5sZW5ndGggKiA0O1xuICAgICAgfSBlbHNlIGlmIChcIkFTQ0lJXCIgPT09IGlucHV0Rm9ybWF0KSB7XG4gICAgICAgIGtleVRvVXNlID0gc3RyMmJpbmIoa2V5KTtcbiAgICAgICAga2V5QmluTGVuID0ga2V5Lmxlbmd0aCAqIGNoYXJTaXplO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFwiVU5LTk9XTiBLRVkgSU5QVVQgVFlQRVwiO1xuICAgICAgfVxuXG4gICAgICAvKiBUaGVzZSBhcmUgdXNlZCBtdWx0aXBsZSB0aW1lcywgY2FsY3VsYXRlIGFuZCBzdG9yZSB0aGVtICovXG4gICAgICBibG9ja0JpdFNpemUgPSBibG9ja0J5dGVTaXplICogODtcbiAgICAgIGxhc3RBcnJheUluZGV4ID0gKGJsb2NrQnl0ZVNpemUgLyA0KSAtIDE7XG5cbiAgICAgIC8qIEZpZ3VyZSBvdXQgd2hhdCB0byBkbyB3aXRoIHRoZSBrZXkgYmFzZWQgb24gaXRzIHNpemUgcmVsYXRpdmUgdG9cbiAgICAgICAqIHRoZSBoYXNoJ3MgYmxvY2sgc2l6ZSAqL1xuICAgICAgaWYgKGJsb2NrQnl0ZVNpemUgPCAoa2V5QmluTGVuIC8gOCkpIHtcbiAgICAgICAgaWYgKFwiU0hBLTFcIiA9PT0gdmFyaWFudCkge1xuICAgICAgICAgIGtleVRvVXNlID0gY29yZVNIQTEoa2V5VG9Vc2UsIGtleUJpbkxlbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2V5VG9Vc2UgPSBjb3JlU0hBMihrZXlUb1VzZSwga2V5QmluTGVuLCB2YXJpYW50KTtcbiAgICAgICAgfVxuICAgICAgICAvKiBGb3IgYWxsIHZhcmlhbnRzLCB0aGUgYmxvY2sgc2l6ZSBpcyBiaWdnZXIgdGhhbiB0aGUgb3V0cHV0XG4gICAgICAgICAqIHNpemUgc28gdGhlcmUgd2lsbCBuZXZlciBiZSBhIHVzZWZ1bCBieXRlIGF0IHRoZSBlbmQgb2YgdGhlXG4gICAgICAgICAqIHN0cmluZyAqL1xuICAgICAgICBrZXlUb1VzZVtsYXN0QXJyYXlJbmRleF0gJj0gMHhGRkZGRkYwMDtcbiAgICAgIH0gZWxzZSBpZiAoYmxvY2tCeXRlU2l6ZSA+IChrZXlCaW5MZW4gLyA4KSkge1xuICAgICAgICAvKiBJZiB0aGUgYmxvY2tCeXRlU2l6ZSBpcyBncmVhdGVyIHRoYW4gdGhlIGtleSBsZW5ndGgsIHRoZXJlXG4gICAgICAgICAqIHdpbGwgYWx3YXlzIGJlIGF0IExFQVNUIG9uZSBcInVzZWxlc3NcIiBieXRlIGF0IHRoZSBlbmQgb2YgdGhlXG4gICAgICAgICAqIHN0cmluZyAqL1xuICAgICAgICBrZXlUb1VzZVtsYXN0QXJyYXlJbmRleF0gJj0gMHhGRkZGRkYwMDtcbiAgICAgIH1cblxuICAgICAgLyogQ3JlYXRlIGlwYWQgYW5kIG9wYWQgKi9cbiAgICAgIGZvciAoaSA9IDA7IGkgPD0gbGFzdEFycmF5SW5kZXg7IGkgKz0gMSkge1xuICAgICAgICBrZXlXaXRoSVBhZFtpXSA9IGtleVRvVXNlW2ldIF4gMHgzNjM2MzYzNjtcbiAgICAgICAga2V5V2l0aE9QYWRbaV0gPSBrZXlUb1VzZVtpXSBeIDB4NUM1QzVDNUM7XG4gICAgICB9XG5cbiAgICAgIC8qIENhbGN1bGF0ZSB0aGUgSE1BQyAqL1xuICAgICAgaWYgKFwiU0hBLTFcIiA9PT0gdmFyaWFudCkge1xuICAgICAgICByZXRWYWwgPSBjb3JlU0hBMShcbiAgICAgICAgICBrZXlXaXRoSVBhZC5jb25jYXQodGhpcy5zdHJUb0hhc2gpLFxuICAgICAgICAgIGJsb2NrQml0U2l6ZSArIHRoaXMuc3RyQmluTGVuKTtcbiAgICAgICAgcmV0VmFsID0gY29yZVNIQTEoXG4gICAgICAgICAga2V5V2l0aE9QYWQuY29uY2F0KHJldFZhbCksXG4gICAgICAgICAgYmxvY2tCaXRTaXplICsgaGFzaEJpdFNpemUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0VmFsID0gY29yZVNIQTIoXG4gICAgICAgICAga2V5V2l0aElQYWQuY29uY2F0KHRoaXMuc3RyVG9IYXNoKSxcbiAgICAgICAgICBibG9ja0JpdFNpemUgKyB0aGlzLnN0ckJpbkxlbiwgdmFyaWFudCk7XG4gICAgICAgIHJldFZhbCA9IGNvcmVTSEEyKFxuICAgICAgICAgIGtleVdpdGhPUGFkLmNvbmNhdChyZXRWYWwpLFxuICAgICAgICAgIGJsb2NrQml0U2l6ZSArIGhhc2hCaXRTaXplLCB2YXJpYW50KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIChmb3JtYXRGdW5jKHJldFZhbCkpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4ganNTSEE7XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2hhMTogZnVuY3Rpb24oc3RyKSB7XG4gICAgdmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsIFwiQVNDSUlcIik7XG4gICAgcmV0dXJuIHNoYU9iai5nZXRIYXNoKFwiU0hBLTFcIiwgXCJBU0NJSVwiKTtcbiAgfSxcbiAgc2hhMjI0OiBmdW5jdGlvbihzdHIpIHtcbiAgICB2YXIgc2hhT2JqID0gbmV3IGpzU0hBKHN0ciwgXCJBU0NJSVwiKTtcbiAgICByZXR1cm4gc2hhT2JqLmdldEhhc2goXCJTSEEtMjI0XCIsIFwiQVNDSUlcIik7XG4gIH0sXG4gIHNoYTI1NjogZnVuY3Rpb24oc3RyKSB7XG4gICAgdmFyIHNoYU9iaiA9IG5ldyBqc1NIQShzdHIsIFwiQVNDSUlcIik7XG4gICAgcmV0dXJuIHNoYU9iai5nZXRIYXNoKFwiU0hBLTI1NlwiLCBcIkFTQ0lJXCIpO1xuICB9LFxuICBzaGEzODQ6IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCBcIkFTQ0lJXCIpO1xuICAgIHJldHVybiBzaGFPYmouZ2V0SGFzaChcIlNIQS0zODRcIiwgXCJBU0NJSVwiKTtcblxuICB9LFxuICBzaGE1MTI6IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciBzaGFPYmogPSBuZXcganNTSEEoc3RyLCBcIkFTQ0lJXCIpO1xuICAgIHJldHVybiBzaGFPYmouZ2V0SGFzaChcIlNIQS01MTJcIiwgXCJBU0NJSVwiKTtcbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIGNpcGhlcjogcmVxdWlyZSgnLi9jaXBoZXInKSxcbiAgaGFzaDogcmVxdWlyZSgnLi9oYXNoJyksXG4gIGNmYjogcmVxdWlyZSgnLi9jZmIuanMnKSxcbiAgcHVibGljS2V5OiByZXF1aXJlKCcuL3B1YmxpY19rZXknKSxcbiAgc2lnbmF0dXJlOiByZXF1aXJlKCcuL3NpZ25hdHVyZS5qcycpLFxuICByYW5kb206IHJlcXVpcmUoJy4vcmFuZG9tLmpzJyksXG4gIHBrY3MxOiByZXF1aXJlKCcuL3BrY3MxLmpzJylcblxufVxuXG52YXIgY3J5cHRvID0gcmVxdWlyZSgnLi9jcnlwdG8uanMnKTtcblxuZm9yICh2YXIgaSBpbiBjcnlwdG8pXG4gIG1vZHVsZS5leHBvcnRzW2ldID0gY3J5cHRvW2ldO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBBU04xIG9iamVjdCBpZGVudGlmaWVycyBmb3IgaGFzaGVzIChTZWUgUkZDNDg4MCA1LjIuMilcbiAqL1xuaGFzaF9oZWFkZXJzID0gbmV3IEFycmF5KCk7XG5oYXNoX2hlYWRlcnNbMV0gPSBbMHgzMCwgMHgyMCwgMHgzMCwgMHgwYywgMHgwNiwgMHgwOCwgMHgyYSwgMHg4NiwgMHg0OCwgMHg4NiwgMHhmNywgMHgwZCwgMHgwMiwgMHgwNSwgMHgwNSwgMHgwMCwgMHgwNCxcbiAgICAweDEwXG5dO1xuaGFzaF9oZWFkZXJzWzNdID0gWzB4MzAsIDB4MjEsIDB4MzAsIDB4MDksIDB4MDYsIDB4MDUsIDB4MkIsIDB4MjQsIDB4MDMsIDB4MDIsIDB4MDEsIDB4MDUsIDB4MDAsIDB4MDQsIDB4MTRdO1xuaGFzaF9oZWFkZXJzWzJdID0gWzB4MzAsIDB4MjEsIDB4MzAsIDB4MDksIDB4MDYsIDB4MDUsIDB4MmIsIDB4MGUsIDB4MDMsIDB4MDIsIDB4MWEsIDB4MDUsIDB4MDAsIDB4MDQsIDB4MTRdO1xuaGFzaF9oZWFkZXJzWzhdID0gWzB4MzAsIDB4MzEsIDB4MzAsIDB4MGQsIDB4MDYsIDB4MDksIDB4NjAsIDB4ODYsIDB4NDgsIDB4MDEsIDB4NjUsIDB4MDMsIDB4MDQsIDB4MDIsIDB4MDEsIDB4MDUsIDB4MDAsXG4gICAgMHgwNCwgMHgyMFxuXTtcbmhhc2hfaGVhZGVyc1s5XSA9IFsweDMwLCAweDQxLCAweDMwLCAweDBkLCAweDA2LCAweDA5LCAweDYwLCAweDg2LCAweDQ4LCAweDAxLCAweDY1LCAweDAzLCAweDA0LCAweDAyLCAweDAyLCAweDA1LCAweDAwLFxuICAgIDB4MDQsIDB4MzBcbl07XG5oYXNoX2hlYWRlcnNbMTBdID0gWzB4MzAsIDB4NTEsIDB4MzAsIDB4MGQsIDB4MDYsIDB4MDksIDB4NjAsIDB4ODYsIDB4NDgsIDB4MDEsIDB4NjUsIDB4MDMsIDB4MDQsIDB4MDIsIDB4MDMsIDB4MDUsXG4gICAgMHgwMCwgMHgwNCwgMHg0MFxuXTtcbmhhc2hfaGVhZGVyc1sxMV0gPSBbMHgzMCwgMHgzMSwgMHgzMCwgMHgwZCwgMHgwNiwgMHgwOSwgMHg2MCwgMHg4NiwgMHg0OCwgMHgwMSwgMHg2NSwgMHgwMywgMHgwNCwgMHgwMiwgMHgwNCwgMHgwNSxcbiAgICAweDAwLCAweDA0LCAweDFDXG5dO1xuXG5cbnZhciBjcnlwdG8gPSByZXF1aXJlKCcuL2NyeXB0by5qcycpLFxuICByYW5kb20gPSByZXF1aXJlKCcuL3JhbmRvbS5qcycpLFxuICB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5L2pzYm4uanMnKSxcbiAgaGFzaCA9IHJlcXVpcmUoJy4vaGFzaCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZW1lOiB7XG4gICAgLyoqXG4gICAgICogY3JlYXRlIGEgRU1FLVBLQ1MxLXYxXzUgcGFkZGluZyAoU2VlIFJGQzQ4ODAgMTMuMS4xKVxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIG1lc3NhZ2UgdG8gYmUgcGFkZGVkXG4gICAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIHRvIHRoZSByZXN1bHRpbmcgbWVzc2FnZVxuICAgICAqIEByZXR1cm4ge1N0cmluZ30gRU1FLVBLQ1MxIHBhZGRlZCBtZXNzYWdlXG4gICAgICovXG4gICAgZW5jb2RlOiBmdW5jdGlvbihtZXNzYWdlLCBsZW5ndGgpIHtcbiAgICAgIGlmIChtZXNzYWdlLmxlbmd0aCA+IGxlbmd0aCAtIDExKVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMik7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aCAtIG1lc3NhZ2UubGVuZ3RoIC0gMzsgaSsrKSB7XG4gICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHJhbmRvbS5nZXRQc2V1ZG9SYW5kb20oMSwgMjU1KSk7XG4gICAgICB9XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICAgIHJlc3VsdCArPSBtZXNzYWdlO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogZGVjb2RlcyBhIEVNRS1QS0NTMS12MV81IHBhZGRpbmcgKFNlZSBSRkM0ODgwIDEzLjEuMilcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSBFTUUtUEtDUzEgcGFkZGVkIG1lc3NhZ2VcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IGRlY29kZWQgbWVzc2FnZSBcbiAgICAgKi9cbiAgICBkZWNvZGU6IGZ1bmN0aW9uKG1lc3NhZ2UsIGxlbikge1xuICAgICAgaWYgKG1lc3NhZ2UubGVuZ3RoIDwgbGVuKVxuICAgICAgICBtZXNzYWdlID0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKSArIG1lc3NhZ2U7XG4gICAgICBpZiAobWVzc2FnZS5sZW5ndGggPCAxMiB8fCBtZXNzYWdlLmNoYXJDb2RlQXQoMCkgIT0gMCB8fCBtZXNzYWdlLmNoYXJDb2RlQXQoMSkgIT0gMilcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgdmFyIGkgPSAyO1xuICAgICAgd2hpbGUgKG1lc3NhZ2UuY2hhckNvZGVBdChpKSAhPSAwICYmIG1lc3NhZ2UubGVuZ3RoID4gaSlcbiAgICAgICAgaSsrO1xuICAgICAgcmV0dXJuIG1lc3NhZ2Uuc3Vic3RyaW5nKGkgKyAxLCBtZXNzYWdlLmxlbmd0aCk7XG4gICAgfSxcbiAgfSxcblxuICBlbXNhOiB7XG5cbiAgICAvKipcbiAgICAgKiBjcmVhdGUgYSBFTVNBLVBLQ1MxLXYxXzUgcGFkZGluZyAoU2VlIFJGQzQ4ODAgMTMuMS4zKVxuICAgICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBIYXNoIGFsZ29yaXRobSB0eXBlIHVzZWRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGJlIGhhc2hlZFxuICAgICAqIEBwYXJhbSB7SW50ZWdlcn0ga2V5bGVuZ3RoIEtleSBzaXplIG9mIHRoZSBwdWJsaWMgbXBpIGluIGJ5dGVzXG4gICAgICogQHJldHVybnMge1N0cmluZ30gSGFzaGNvZGUgd2l0aCBwa2NzMXBhZGRpbmcgYXMgc3RyaW5nXG4gICAgICovXG4gICAgZW5jb2RlOiBmdW5jdGlvbihhbGdvLCBkYXRhLCBrZXlsZW5ndGgpIHtcbiAgICAgIHZhciBkYXRhMiA9IFwiXCI7XG4gICAgICBkYXRhMiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApO1xuICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDAxKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgKGtleWxlbmd0aCAtIGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGggLSAzIC1cbiAgICAgICAgaGFzaC5nZXRIYXNoQnl0ZUxlbmd0aChhbGdvKSk7IGkrKylcblxuICAgICAgICBkYXRhMiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ZmYpO1xuXG4gICAgICBkYXRhMiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhhc2hfaGVhZGVyc1thbGdvXS5sZW5ndGg7IGkrKylcbiAgICAgICAgZGF0YTIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShoYXNoX2hlYWRlcnNbYWxnb11baV0pO1xuXG4gICAgICBkYXRhMiArPSBoYXNoLmRpZ2VzdChhbGdvLCBkYXRhKTtcbiAgICAgIHJldHVybiBuZXcgQmlnSW50ZWdlcih1dGlsLmhleHN0cmR1bXAoZGF0YTIpLCAxNik7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGV4dHJhY3QgdGhlIGhhc2ggb3V0IG9mIGFuIEVNU0EtUEtDUzEtdjEuNSBwYWRkaW5nIChTZWUgUkZDNDg4MCAxMy4xLjMpIFxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIEhhc2ggaW4gcGtjczEgZW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgaGFzaCBhcyBzdHJpbmdcbiAgICAgKi9cbiAgICBkZWNvZGU6IGZ1bmN0aW9uKGFsZ28sIGRhdGEpIHtcbiAgICAgIHZhciBpID0gMDtcbiAgICAgIGlmIChkYXRhLmNoYXJDb2RlQXQoMCkgPT0gMCkgaSsrO1xuICAgICAgZWxzZSBpZiAoZGF0YS5jaGFyQ29kZUF0KDApICE9IDEpIHJldHVybiAtMTtcbiAgICAgIGVsc2UgaSsrO1xuXG4gICAgICB3aGlsZSAoZGF0YS5jaGFyQ29kZUF0KGkpID09IDB4RkYpIGkrKztcbiAgICAgIGlmIChkYXRhLmNoYXJDb2RlQXQoaSsrKSAhPSAwKSByZXR1cm4gLTE7XG4gICAgICB2YXIgaiA9IDA7XG4gICAgICBmb3IgKGogPSAwOyBqIDwgaGFzaF9oZWFkZXJzW2FsZ29dLmxlbmd0aCAmJiBqICsgaSA8IGRhdGEubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKGRhdGEuY2hhckNvZGVBdChqICsgaSkgIT0gaGFzaF9oZWFkZXJzW2FsZ29dW2pdKSByZXR1cm4gLTE7XG4gICAgICB9XG4gICAgICBpICs9IGo7XG4gICAgICBpZiAoZGF0YS5zdWJzdHJpbmcoaSkubGVuZ3RoIDwgaGFzaC5nZXRIYXNoQnl0ZUxlbmd0aChhbGdvKSkgcmV0dXJuIC0xO1xuICAgICAgcmV0dXJuIGRhdGEuc3Vic3RyaW5nKGkpO1xuICAgIH1cbiAgfVxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0Fcbi8vXG4vLyBBIERpZ2l0YWwgc2lnbmF0dXJlIGFsZ29yaXRobSBpbXBsZW1lbnRhdGlvblxuXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vanNibi5qcycpLFxuICByYW5kb20gPSByZXF1aXJlKCcuLi9yYW5kb20uanMnKSxcbiAgaGFzaE1vZHVsZSA9IHJlcXVpcmUoJy4uL2hhc2gnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuZnVuY3Rpb24gRFNBKCkge1xuICAvLyBzMSA9ICgoZyoqcykgbW9kIHApIG1vZCBxXG4gIC8vIHMxID0gKChzKiotMSkqKHNoYS0xKG0pKyhzMSp4KSBtb2QgcSlcbiAgZnVuY3Rpb24gc2lnbihoYXNoYWxnbywgbSwgZywgcCwgcSwgeCkge1xuICAgIC8vIElmIHRoZSBvdXRwdXQgc2l6ZSBvZiB0aGUgY2hvc2VuIGhhc2ggaXMgbGFyZ2VyIHRoYW4gdGhlIG51bWJlciBvZlxuICAgIC8vIGJpdHMgb2YgcSwgdGhlIGhhc2ggcmVzdWx0IGlzIHRydW5jYXRlZCB0byBmaXQgYnkgdGFraW5nIHRoZSBudW1iZXJcbiAgICAvLyBvZiBsZWZ0bW9zdCBiaXRzIGVxdWFsIHRvIHRoZSBudW1iZXIgb2YgYml0cyBvZiBxLiAgVGhpcyAocG9zc2libHlcbiAgICAvLyB0cnVuY2F0ZWQpIGhhc2ggZnVuY3Rpb24gcmVzdWx0IGlzIHRyZWF0ZWQgYXMgYSBudW1iZXIgYW5kIHVzZWRcbiAgICAvLyBkaXJlY3RseSBpbiB0aGUgRFNBIHNpZ25hdHVyZSBhbGdvcml0aG0uXG4gICAgdmFyIGhhc2hlZF9kYXRhID0gdXRpbC5nZXRMZWZ0TkJpdHMoaGFzaE1vZHVsZS5kaWdlc3QoaGFzaGFsZ28sIG0pLCBxLmJpdExlbmd0aCgpKTtcbiAgICB2YXIgaGFzaCA9IG5ldyBCaWdJbnRlZ2VyKHV0aWwuaGV4c3RyZHVtcChoYXNoZWRfZGF0YSksIDE2KTtcbiAgICB2YXIgayA9IHJhbmRvbS5nZXRSYW5kb21CaWdJbnRlZ2VySW5SYW5nZShCaWdJbnRlZ2VyLk9ORS5hZGQoQmlnSW50ZWdlci5PTkUpLCBxLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKSk7XG4gICAgdmFyIHMxID0gKGcubW9kUG93KGssIHApKS5tb2QocSk7XG4gICAgdmFyIHMyID0gKGsubW9kSW52ZXJzZShxKS5tdWx0aXBseShoYXNoLmFkZCh4Lm11bHRpcGx5KHMxKSkpKS5tb2QocSk7XG4gICAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheSgpO1xuICAgIHJlc3VsdFswXSA9IHMxLnRvTVBJKCk7XG4gICAgcmVzdWx0WzFdID0gczIudG9NUEkoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gc2VsZWN0X2hhc2hfYWxnb3JpdGhtKHEpIHtcbiAgICB2YXIgdXNlcnNldHRpbmcgPSBvcGVucGdwLmNvbmZpZy5jb25maWcucHJlZmVyX2hhc2hfYWxnb3JpdGhtO1xuICAgIC8qXG4gICAgICogMTAyNC1iaXQga2V5LCAxNjAtYml0IHEsIFNIQS0xLCBTSEEtMjI0LCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyIGhhc2hcbiAgICAgKiAyMDQ4LWJpdCBrZXksIDIyNC1iaXQgcSwgU0hBLTIyNCwgU0hBLTI1NiwgU0hBLTM4NCwgb3IgU0hBLTUxMiBoYXNoXG4gICAgICogMjA0OC1iaXQga2V5LCAyNTYtYml0IHEsIFNIQS0yNTYsIFNIQS0zODQsIG9yIFNIQS01MTIgaGFzaFxuICAgICAqIDMwNzItYml0IGtleSwgMjU2LWJpdCBxLCBTSEEtMjU2LCBTSEEtMzg0LCBvciBTSEEtNTEyIGhhc2hcbiAgICAgKi9cbiAgICBzd2l0Y2ggKE1hdGgucm91bmQocS5iaXRMZW5ndGgoKSAvIDgpKSB7XG4gICAgICBjYXNlIDIwOlxuICAgICAgICAvLyAxMDI0IGJpdFxuICAgICAgICBpZiAodXNlcnNldHRpbmcgIT0gMiAmJlxuICAgICAgICAgIHVzZXJzZXR0aW5nID4gMTEgJiZcbiAgICAgICAgICB1c2Vyc2V0dGluZyAhPSAxMCAmJlxuICAgICAgICAgIHVzZXJzZXR0aW5nIDwgOClcbiAgICAgICAgICByZXR1cm4gMjsgLy8gcHJlZmVyIHNoYTFcbiAgICAgICAgcmV0dXJuIHVzZXJzZXR0aW5nO1xuICAgICAgY2FzZSAyODpcbiAgICAgICAgLy8gMjA0OCBiaXRcbiAgICAgICAgaWYgKHVzZXJzZXR0aW5nID4gMTEgJiZcbiAgICAgICAgICB1c2Vyc2V0dGluZyA8IDgpXG4gICAgICAgICAgcmV0dXJuIDExO1xuICAgICAgICByZXR1cm4gdXNlcnNldHRpbmc7XG4gICAgICBjYXNlIDMyOlxuICAgICAgICAvLyA0MDk2IGJpdCAvLyBwcmVmZXIgc2hhMjI0XG4gICAgICAgIGlmICh1c2Vyc2V0dGluZyA+IDEwICYmXG4gICAgICAgICAgdXNlcnNldHRpbmcgPCA4KVxuICAgICAgICAgIHJldHVybiA4OyAvLyBwcmVmZXIgc2hhMjU2XG4gICAgICAgIHJldHVybiB1c2Vyc2V0dGluZztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCJEU0Egc2VsZWN0IGhhc2ggYWxnb3JpdGhtOiByZXR1cm5pbmcgbnVsbCBmb3IgYW4gdW5rbm93biBsZW5ndGggb2YgcVwiKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICB9XG4gIH1cbiAgdGhpcy5zZWxlY3RfaGFzaF9hbGdvcml0aG0gPSBzZWxlY3RfaGFzaF9hbGdvcml0aG07XG5cbiAgZnVuY3Rpb24gdmVyaWZ5KGhhc2hhbGdvLCBzMSwgczIsIG0sIHAsIHEsIGcsIHkpIHtcbiAgICB2YXIgaGFzaGVkX2RhdGEgPSB1dGlsLmdldExlZnROQml0cyhoYXNoTW9kdWxlLmRpZ2VzdChoYXNoYWxnbywgbSksIHEuYml0TGVuZ3RoKCkpO1xuICAgIHZhciBoYXNoID0gbmV3IEJpZ0ludGVnZXIodXRpbC5oZXhzdHJkdW1wKGhhc2hlZF9kYXRhKSwgMTYpO1xuICAgIGlmIChCaWdJbnRlZ2VyLlpFUk8uY29tcGFyZVRvKHMxKSA+IDAgfHxcbiAgICAgIHMxLmNvbXBhcmVUbyhxKSA+IDAgfHxcbiAgICAgIEJpZ0ludGVnZXIuWkVSTy5jb21wYXJlVG8oczIpID4gMCB8fFxuICAgICAgczIuY29tcGFyZVRvKHEpID4gMCkge1xuICAgICAgdXRpbC5wcmludF9lcnJvcihcImludmFsaWQgRFNBIFNpZ25hdHVyZVwiKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgdyA9IHMyLm1vZEludmVyc2UocSk7XG4gICAgdmFyIHUxID0gaGFzaC5tdWx0aXBseSh3KS5tb2QocSk7XG4gICAgdmFyIHUyID0gczEubXVsdGlwbHkodykubW9kKHEpO1xuICAgIHJldHVybiBnLm1vZFBvdyh1MSwgcCkubXVsdGlwbHkoeS5tb2RQb3codTIsIHApKS5tb2QocCkubW9kKHEpO1xuICB9XG5cbiAgLypcblx0ICogdW51c2VkIGNvZGUuIFRoaXMgY2FuIGJlIHVzZWQgYXMgYSBzdGFydCB0byB3cml0ZSBhIGtleSBnZW5lcmF0b3Jcblx0ICogZnVuY3Rpb24uXG5cdFxuXHRmdW5jdGlvbiBnZW5lcmF0ZUtleShiaXRjb3VudCkge1xuXHQgICAgdmFyIHFpID0gbmV3IEJpZ0ludGVnZXIoYml0Y291bnQsIHByaW1lQ2VudGVyaWUpO1xuXHQgICAgdmFyIHBpID0gZ2VuZXJhdGVQKHEsIDUxMik7XG5cdCAgICB2YXIgZ2kgPSBnZW5lcmF0ZUcocCwgcSwgYml0Y291bnQpO1xuXHQgICAgdmFyIHhpO1xuXHQgICAgZG8ge1xuXHQgICAgICAgIHhpID0gbmV3IEJpZ0ludGVnZXIocS5iaXRDb3VudCgpLCByYW5kKTtcblx0ICAgIH0gd2hpbGUgKHguY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgIT0gMSAmJiB4LmNvbXBhcmVUbyhxKSAhPSAtMSk7XG5cdCAgICB2YXIgeWkgPSBnLm1vZFBvdyh4LCBwKTtcblx0ICAgIHJldHVybiB7eDogeGksIHE6IHFpLCBwOiBwaSwgZzogZ2ksIHk6IHlpfTtcblx0fVxuXG5cdGZ1bmN0aW9uIGdlbmVyYXRlUChxLCBiaXRsZW5ndGgsIHJhbmRvbWZuKSB7XG5cdCAgICBpZiAoYml0bGVuZ3RoICUgNjQgIT0gMCkge1xuXHQgICAgXHRyZXR1cm4gZmFsc2U7XG5cdCAgICB9XG5cdCAgICB2YXIgcFRlbXA7XG5cdCAgICB2YXIgcFRlbXAyO1xuXHQgICAgZG8ge1xuXHQgICAgICAgIHBUZW1wID0gcmFuZG9tZm4oYml0Y291bnQsIHRydWUpO1xuXHQgICAgICAgIHBUZW1wMiA9IHBUZW1wLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTtcblx0ICAgICAgICBwVGVtcCA9IHBUZW1wLnN1YnRyYWN0KHBUZW1wMi5yZW1haW5kZXIocSkpO1xuXHQgICAgfSB3aGlsZSAoIXBUZW1wLmlzUHJvYmFibGVQcmltZShwcmltZUNlbnRlcmllKSB8fCBwVGVtcC5iaXRMZW5ndGgoKSAhPSBsKTtcblx0ICAgIHJldHVybiBwVGVtcDtcblx0fVxuXHRcblx0ZnVuY3Rpb24gZ2VuZXJhdGVHKHAsIHEsIGJpdGxlbmd0aCwgcmFuZG9tZm4pIHtcblx0ICAgIHZhciBhdXggPSBwLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTtcblx0ICAgIHZhciBwb3cgPSBhdXguZGl2aWRlKHEpO1xuXHQgICAgdmFyIGdUZW1wO1xuXHQgICAgZG8ge1xuXHQgICAgICAgIGdUZW1wID0gcmFuZG9tZm4oYml0bGVuZ3RoKTtcblx0ICAgIH0gd2hpbGUgKGdUZW1wLmNvbXBhcmVUbyhhdXgpICE9IC0xICYmIGdUZW1wLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMSk7XG5cdCAgICByZXR1cm4gZ1RlbXAubW9kUG93KHBvdywgcCk7XG5cdH1cblxuXHRmdW5jdGlvbiBnZW5lcmF0ZUsocSwgYml0bGVuZ3RoLCByYW5kb21mbikge1xuXHQgICAgdmFyIHRlbXBLO1xuXHQgICAgZG8ge1xuXHQgICAgICAgIHRlbXBLID0gcmFuZG9tZm4oYml0bGVuZ3RoLCBmYWxzZSk7XG5cdCAgICB9IHdoaWxlICh0ZW1wSy5jb21wYXJlVG8ocSkgIT0gLTEgJiYgdGVtcEsuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgIT0gMSk7XG5cdCAgICByZXR1cm4gdGVtcEs7XG5cdH1cblxuXHRmdW5jdGlvbiBnZW5lcmF0ZVIocSxwKSB7XG5cdCAgICBrID0gZ2VuZXJhdGVLKHEpO1xuXHQgICAgdmFyIHIgPSBnLm1vZFBvdyhrLCBwKS5tb2QocSk7XG5cdCAgICByZXR1cm4gcjtcblx0fVxuXG5cdGZ1bmN0aW9uIGdlbmVyYXRlUyhoYXNoZm4sayxyLG0scSx4KSB7XG4gICAgICAgIHZhciBoYXNoID0gaGFzaGZuKG0pO1xuICAgICAgICBzID0gKGsubW9kSW52ZXJzZShxKS5tdWx0aXBseShoYXNoLmFkZCh4Lm11bHRpcGx5KHIpKSkpLm1vZChxKTtcblx0ICAgIHJldHVybiBzO1xuXHR9ICovXG4gIHRoaXMuc2lnbiA9IHNpZ247XG4gIHRoaXMudmVyaWZ5ID0gdmVyaWZ5O1xuICAvLyB0aGlzLmdlbmVyYXRlID0gZ2VuZXJhdGVLZXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRFNBO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0Fcbi8vXG4vLyBFbEdhbWFsIGltcGxlbWVudGF0aW9uXG5cbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9qc2JuLmpzJyksXG4gIHJhbmRvbSA9IHJlcXVpcmUoJy4uL3JhbmRvbS5qcycpLFxuICB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpO1xuXG5mdW5jdGlvbiBFbGdhbWFsKCkge1xuXG4gIGZ1bmN0aW9uIGVuY3J5cHQobSwgZywgcCwgeSkge1xuICAgIC8vICBjaG9vc2UgayBpbiB7MiwuLi4scC0yfVxuICAgIHZhciB0d28gPSBCaWdJbnRlZ2VyLk9ORS5hZGQoQmlnSW50ZWdlci5PTkUpO1xuICAgIHZhciBwTWludXMyID0gcC5zdWJ0cmFjdCh0d28pO1xuICAgIHZhciBrID0gcmFuZG9tLmdldFJhbmRvbUJpZ0ludGVnZXJJblJhbmdlKHR3bywgcE1pbnVzMik7XG4gICAgayA9IGsubW9kKHBNaW51czIpLmFkZChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgdmFyIGMgPSBbXTtcbiAgICBjWzBdID0gZy5tb2RQb3coaywgcCk7XG4gICAgY1sxXSA9IHkubW9kUG93KGssIHApLm11bHRpcGx5KG0pLm1vZChwKTtcbiAgICByZXR1cm4gYztcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlY3J5cHQoYzEsIGMyLCBwLCB4KSB7XG4gICAgdXRpbC5wcmludF9kZWJ1ZyhcIkVsZ2FtYWwgRGVjcnlwdDpcXG5jMTpcIiArIHV0aWwuaGV4c3RyZHVtcChjMS50b01QSSgpKSArIFwiXFxuXCIgK1xuICAgICAgXCJjMjpcIiArIHV0aWwuaGV4c3RyZHVtcChjMi50b01QSSgpKSArIFwiXFxuXCIgK1xuICAgICAgXCJwOlwiICsgdXRpbC5oZXhzdHJkdW1wKHAudG9NUEkoKSkgKyBcIlxcblwiICtcbiAgICAgIFwieDpcIiArIHV0aWwuaGV4c3RyZHVtcCh4LnRvTVBJKCkpKTtcbiAgICByZXR1cm4gKGMxLm1vZFBvdyh4LCBwKS5tb2RJbnZlcnNlKHApKS5tdWx0aXBseShjMikubW9kKHApO1xuICAgIC8vdmFyIGMgPSBjMS5wb3coeCkubW9kSW52ZXJzZShwKTsgLy8gYzBeLWEgbW9kIHBcbiAgICAvL3JldHVybiBjLm11bHRpcGx5KGMyKS5tb2QocCk7XG4gIH1cblxuICAvLyBzaWduaW5nIGFuZCBzaWduYXR1cmUgdmVyaWZpY2F0aW9uIHVzaW5nIEVsZ2FtYWwgaXMgbm90IHJlcXVpcmVkIGJ5IE9wZW5QR1AuXG4gIHRoaXMuZW5jcnlwdCA9IGVuY3J5cHQ7XG4gIHRoaXMuZGVjcnlwdCA9IGRlY3J5cHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gRWxnYW1hbDtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICByc2E6IHJlcXVpcmUoJy4vcnNhLmpzJyksXG4gIGVsZ2FtYWw6IHJlcXVpcmUoJy4vZWxnYW1hbC5qcycpLFxuICBkc2E6IHJlcXVpcmUoJy4vZHNhLmpzJylcbn1cbiIsIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMDMtMjAwNSAgVG9tIFd1ICh0andAY3MuU3RhbmZvcmQuRURVKSBcbiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogTW9kaWZpZWQgYnkgUmVjdXJpdHkgTGFicyBHbWJIIFxuICogXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmdcbiAqIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuICogXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4gKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4gKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG9cbiAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0b1xuICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlXG4gKiBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUy1JU1wiIEFORCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBcbiAqIEVYUFJFU1MsIElNUExJRUQgT1IgT1RIRVJXSVNFLCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkgXG4gKiBXQVJSQU5UWSBPRiBNRVJDSEFOVEFCSUxJVFkgT1IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBcbiAqXG4gKiBJTiBOTyBFVkVOVCBTSEFMTCBUT00gV1UgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5DSURFTlRBTCxcbiAqIElORElSRUNUIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPRiBBTlkgS0lORCwgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUlxuICogUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBPUiBOT1QgQURWSVNFRCBPRlxuICogVEhFIFBPU1NJQklMSVRZIE9GIERBTUFHRSwgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBBUklTSU5HIE9VVFxuICogT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cbiAqXG4gKiBJbiBhZGRpdGlvbiwgdGhlIGZvbGxvd2luZyBjb25kaXRpb24gYXBwbGllczpcbiAqXG4gKiBBbGwgcmVkaXN0cmlidXRpb25zIG11c3QgcmV0YWluIGFuIGludGFjdCBjb3B5IG9mIHRoaXMgY29weXJpZ2h0IG5vdGljZVxuICogYW5kIGRpc2NsYWltZXIuXG4gKi9cblxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uLy4uL3V0aWwnKTtcblxuLy8gQmFzaWMgSmF2YVNjcmlwdCBCTiBsaWJyYXJ5IC0gc3Vic2V0IHVzZWZ1bCBmb3IgUlNBIGVuY3J5cHRpb24uXG5cbi8vIEJpdHMgcGVyIGRpZ2l0XG52YXIgZGJpdHM7XG5cbi8vIEphdmFTY3JpcHQgZW5naW5lIGFuYWx5c2lzXG52YXIgY2FuYXJ5ID0gMHhkZWFkYmVlZmNhZmU7XG52YXIgal9sbSA9ICgoY2FuYXJ5ICYgMHhmZmZmZmYpID09IDB4ZWZjYWZlKTtcblxuLy8gKHB1YmxpYykgQ29uc3RydWN0b3JcblxuZnVuY3Rpb24gQmlnSW50ZWdlcihhLCBiLCBjKSB7XG4gIGlmIChhICE9IG51bGwpXG4gICAgaWYgKFwibnVtYmVyXCIgPT0gdHlwZW9mIGEpIHRoaXMuZnJvbU51bWJlcihhLCBiLCBjKTtcbiAgICBlbHNlIGlmIChiID09IG51bGwgJiYgXCJzdHJpbmdcIiAhPSB0eXBlb2YgYSkgdGhpcy5mcm9tU3RyaW5nKGEsIDI1Nik7XG4gIGVsc2UgdGhpcy5mcm9tU3RyaW5nKGEsIGIpO1xufVxuXG4vLyByZXR1cm4gbmV3LCB1bnNldCBCaWdJbnRlZ2VyXG5cbmZ1bmN0aW9uIG5iaSgpIHtcbiAgcmV0dXJuIG5ldyBCaWdJbnRlZ2VyKG51bGwpO1xufVxuXG4vLyBhbTogQ29tcHV0ZSB3X2ogKz0gKHgqdGhpc19pKSwgcHJvcGFnYXRlIGNhcnJpZXMsXG4vLyBjIGlzIGluaXRpYWwgY2FycnksIHJldHVybnMgZmluYWwgY2FycnkuXG4vLyBjIDwgMypkdmFsdWUsIHggPCAyKmR2YWx1ZSwgdGhpc19pIDwgZHZhbHVlXG4vLyBXZSBuZWVkIHRvIHNlbGVjdCB0aGUgZmFzdGVzdCBvbmUgdGhhdCB3b3JrcyBpbiB0aGlzIGVudmlyb25tZW50LlxuXG4vLyBhbTE6IHVzZSBhIHNpbmdsZSBtdWx0IGFuZCBkaXZpZGUgdG8gZ2V0IHRoZSBoaWdoIGJpdHMsXG4vLyBtYXggZGlnaXQgYml0cyBzaG91bGQgYmUgMjYgYmVjYXVzZVxuLy8gbWF4IGludGVybmFsIHZhbHVlID0gMipkdmFsdWVeMi0yKmR2YWx1ZSAoPCAyXjUzKVxuXG5mdW5jdGlvbiBhbTEoaSwgeCwgdywgaiwgYywgbikge1xuICB3aGlsZSAoLS1uID49IDApIHtcbiAgICB2YXIgdiA9IHggKiB0aGlzW2krK10gKyB3W2pdICsgYztcbiAgICBjID0gTWF0aC5mbG9vcih2IC8gMHg0MDAwMDAwKTtcbiAgICB3W2orK10gPSB2ICYgMHgzZmZmZmZmO1xuICB9XG4gIHJldHVybiBjO1xufVxuLy8gYW0yIGF2b2lkcyBhIGJpZyBtdWx0LWFuZC1leHRyYWN0IGNvbXBsZXRlbHkuXG4vLyBNYXggZGlnaXQgYml0cyBzaG91bGQgYmUgPD0gMzAgYmVjYXVzZSB3ZSBkbyBiaXR3aXNlIG9wc1xuLy8gb24gdmFsdWVzIHVwIHRvIDIqaGR2YWx1ZV4yLWhkdmFsdWUtMSAoPCAyXjMxKVxuXG5mdW5jdGlvbiBhbTIoaSwgeCwgdywgaiwgYywgbikge1xuICB2YXIgeGwgPSB4ICYgMHg3ZmZmLFxuICAgIHhoID0geCA+PiAxNTtcbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgdmFyIGwgPSB0aGlzW2ldICYgMHg3ZmZmO1xuICAgIHZhciBoID0gdGhpc1tpKytdID4+IDE1O1xuICAgIHZhciBtID0geGggKiBsICsgaCAqIHhsO1xuICAgIGwgPSB4bCAqIGwgKyAoKG0gJiAweDdmZmYpIDw8IDE1KSArIHdbal0gKyAoYyAmIDB4M2ZmZmZmZmYpO1xuICAgIGMgPSAobCA+Pj4gMzApICsgKG0gPj4+IDE1KSArIHhoICogaCArIChjID4+PiAzMCk7XG4gICAgd1tqKytdID0gbCAmIDB4M2ZmZmZmZmY7XG4gIH1cbiAgcmV0dXJuIGM7XG59XG4vLyBBbHRlcm5hdGVseSwgc2V0IG1heCBkaWdpdCBiaXRzIHRvIDI4IHNpbmNlIHNvbWVcbi8vIGJyb3dzZXJzIHNsb3cgZG93biB3aGVuIGRlYWxpbmcgd2l0aCAzMi1iaXQgbnVtYmVycy5cblxuZnVuY3Rpb24gYW0zKGksIHgsIHcsIGosIGMsIG4pIHtcbiAgdmFyIHhsID0geCAmIDB4M2ZmZixcbiAgICB4aCA9IHggPj4gMTQ7XG4gIHdoaWxlICgtLW4gPj0gMCkge1xuICAgIHZhciBsID0gdGhpc1tpXSAmIDB4M2ZmZjtcbiAgICB2YXIgaCA9IHRoaXNbaSsrXSA+PiAxNDtcbiAgICB2YXIgbSA9IHhoICogbCArIGggKiB4bDtcbiAgICBsID0geGwgKiBsICsgKChtICYgMHgzZmZmKSA8PCAxNCkgKyB3W2pdICsgYztcbiAgICBjID0gKGwgPj4gMjgpICsgKG0gPj4gMTQpICsgeGggKiBoO1xuICAgIHdbaisrXSA9IGwgJiAweGZmZmZmZmY7XG4gIH1cbiAgcmV0dXJuIGM7XG59XG4vKmlmKGpfbG0gJiYgKG5hdmlnYXRvciAhPSB1bmRlZmluZWQgJiYgXG5cdG5hdmlnYXRvci5hcHBOYW1lID09IFwiTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyXCIpKSB7XG4gIEJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0yO1xuICBkYml0cyA9IDMwO1xufVxuZWxzZSBpZihqX2xtICYmIChuYXZpZ2F0b3IgIT0gdW5kZWZpbmVkICYmIG5hdmlnYXRvci5hcHBOYW1lICE9IFwiTmV0c2NhcGVcIikpIHsqL1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTE7XG5kYml0cyA9IDI2O1xuLyp9XG5lbHNlIHsgLy8gTW96aWxsYS9OZXRzY2FwZSBzZWVtcyB0byBwcmVmZXIgYW0zXG4gIEJpZ0ludGVnZXIucHJvdG90eXBlLmFtID0gYW0zO1xuICBkYml0cyA9IDI4O1xufSovXG5cbkJpZ0ludGVnZXIucHJvdG90eXBlLkRCID0gZGJpdHM7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5ETSA9ICgoMSA8PCBkYml0cykgLSAxKTtcbkJpZ0ludGVnZXIucHJvdG90eXBlLkRWID0gKDEgPDwgZGJpdHMpO1xuXG52YXIgQklfRlAgPSA1MjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLkZWID0gTWF0aC5wb3coMiwgQklfRlApO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuRjEgPSBCSV9GUCAtIGRiaXRzO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuRjIgPSAyICogZGJpdHMgLSBCSV9GUDtcblxuLy8gRGlnaXQgY29udmVyc2lvbnNcbnZhciBCSV9STSA9IFwiMDEyMzQ1Njc4OWFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6XCI7XG52YXIgQklfUkMgPSBuZXcgQXJyYXkoKTtcbnZhciByciwgdnY7XG5yciA9IFwiMFwiLmNoYXJDb2RlQXQoMCk7XG5mb3IgKHZ2ID0gMDsgdnYgPD0gOTsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcbnJyID0gXCJhXCIuY2hhckNvZGVBdCgwKTtcbmZvciAodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcbnJyID0gXCJBXCIuY2hhckNvZGVBdCgwKTtcbmZvciAodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djtcblxuZnVuY3Rpb24gaW50MmNoYXIobikge1xuICByZXR1cm4gQklfUk0uY2hhckF0KG4pO1xufVxuXG5mdW5jdGlvbiBpbnRBdChzLCBpKSB7XG4gIHZhciBjID0gQklfUkNbcy5jaGFyQ29kZUF0KGkpXTtcbiAgcmV0dXJuIChjID09IG51bGwpID8gLTEgOiBjO1xufVxuXG4vLyAocHJvdGVjdGVkKSBjb3B5IHRoaXMgdG8gclxuXG5mdW5jdGlvbiBibnBDb3B5VG8ocikge1xuICBmb3IgKHZhciBpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHJbaV0gPSB0aGlzW2ldO1xuICByLnQgPSB0aGlzLnQ7XG4gIHIucyA9IHRoaXMucztcbn1cblxuLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gaW50ZWdlciB2YWx1ZSB4LCAtRFYgPD0geCA8IERWXG5cbmZ1bmN0aW9uIGJucEZyb21JbnQoeCkge1xuICB0aGlzLnQgPSAxO1xuICB0aGlzLnMgPSAoeCA8IDApID8gLTEgOiAwO1xuICBpZiAoeCA+IDApIHRoaXNbMF0gPSB4O1xuICBlbHNlIGlmICh4IDwgLTEpIHRoaXNbMF0gPSB4ICsgRFY7XG4gIGVsc2UgdGhpcy50ID0gMDtcbn1cblxuLy8gcmV0dXJuIGJpZ2ludCBpbml0aWFsaXplZCB0byB2YWx1ZVxuXG5mdW5jdGlvbiBuYnYoaSkge1xuICB2YXIgciA9IG5iaSgpO1xuICByLmZyb21JbnQoaSk7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHJvdGVjdGVkKSBzZXQgZnJvbSBzdHJpbmcgYW5kIHJhZGl4XG5cbmZ1bmN0aW9uIGJucEZyb21TdHJpbmcocywgYikge1xuICB2YXIgaztcbiAgaWYgKGIgPT0gMTYpIGsgPSA0O1xuICBlbHNlIGlmIChiID09IDgpIGsgPSAzO1xuICBlbHNlIGlmIChiID09IDI1NikgayA9IDg7IC8vIGJ5dGUgYXJyYXlcbiAgZWxzZSBpZiAoYiA9PSAyKSBrID0gMTtcbiAgZWxzZSBpZiAoYiA9PSAzMikgayA9IDU7XG4gIGVsc2UgaWYgKGIgPT0gNCkgayA9IDI7XG4gIGVsc2Uge1xuICAgIHRoaXMuZnJvbVJhZGl4KHMsIGIpO1xuICAgIHJldHVybjtcbiAgfVxuICB0aGlzLnQgPSAwO1xuICB0aGlzLnMgPSAwO1xuICB2YXIgaSA9IHMubGVuZ3RoLFxuICAgIG1pID0gZmFsc2UsXG4gICAgc2ggPSAwO1xuICB3aGlsZSAoLS1pID49IDApIHtcbiAgICB2YXIgeCA9IChrID09IDgpID8gc1tpXSAmIDB4ZmYgOiBpbnRBdChzLCBpKTtcbiAgICBpZiAoeCA8IDApIHtcbiAgICAgIGlmIChzLmNoYXJBdChpKSA9PSBcIi1cIikgbWkgPSB0cnVlO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIG1pID0gZmFsc2U7XG4gICAgaWYgKHNoID09IDApXG4gICAgICB0aGlzW3RoaXMudCsrXSA9IHg7XG4gICAgZWxzZSBpZiAoc2ggKyBrID4gdGhpcy5EQikge1xuICAgICAgdGhpc1t0aGlzLnQgLSAxXSB8PSAoeCAmICgoMSA8PCAodGhpcy5EQiAtIHNoKSkgLSAxKSkgPDwgc2g7XG4gICAgICB0aGlzW3RoaXMudCsrXSA9ICh4ID4+ICh0aGlzLkRCIC0gc2gpKTtcbiAgICB9IGVsc2VcbiAgICAgIHRoaXNbdGhpcy50IC0gMV0gfD0geCA8PCBzaDtcbiAgICBzaCArPSBrO1xuICAgIGlmIChzaCA+PSB0aGlzLkRCKSBzaCAtPSB0aGlzLkRCO1xuICB9XG4gIGlmIChrID09IDggJiYgKHNbMF0gJiAweDgwKSAhPSAwKSB7XG4gICAgdGhpcy5zID0gLTE7XG4gICAgaWYgKHNoID4gMCkgdGhpc1t0aGlzLnQgLSAxXSB8PSAoKDEgPDwgKHRoaXMuREIgLSBzaCkpIC0gMSkgPDwgc2g7XG4gIH1cbiAgdGhpcy5jbGFtcCgpO1xuICBpZiAobWkpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLCB0aGlzKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgY2xhbXAgb2ZmIGV4Y2VzcyBoaWdoIHdvcmRzXG5cbmZ1bmN0aW9uIGJucENsYW1wKCkge1xuICB2YXIgYyA9IHRoaXMucyAmIHRoaXMuRE07XG4gIHdoaWxlICh0aGlzLnQgPiAwICYmIHRoaXNbdGhpcy50IC0gMV0gPT0gYyktLXRoaXMudDtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHN0cmluZyByZXByZXNlbnRhdGlvbiBpbiBnaXZlbiByYWRpeFxuXG5mdW5jdGlvbiBiblRvU3RyaW5nKGIpIHtcbiAgaWYgKHRoaXMucyA8IDApIHJldHVybiBcIi1cIiArIHRoaXMubmVnYXRlKCkudG9TdHJpbmcoYik7XG4gIHZhciBrO1xuICBpZiAoYiA9PSAxNikgayA9IDQ7XG4gIGVsc2UgaWYgKGIgPT0gOCkgayA9IDM7XG4gIGVsc2UgaWYgKGIgPT0gMikgayA9IDE7XG4gIGVsc2UgaWYgKGIgPT0gMzIpIGsgPSA1O1xuICBlbHNlIGlmIChiID09IDQpIGsgPSAyO1xuICBlbHNlIHJldHVybiB0aGlzLnRvUmFkaXgoYik7XG4gIHZhciBrbSA9ICgxIDw8IGspIC0gMSxcbiAgICBkLCBtID0gZmFsc2UsXG4gICAgciA9IFwiXCIsXG4gICAgaSA9IHRoaXMudDtcbiAgdmFyIHAgPSB0aGlzLkRCIC0gKGkgKiB0aGlzLkRCKSAlIGs7XG4gIGlmIChpLS0gPiAwKSB7XG4gICAgaWYgKHAgPCB0aGlzLkRCICYmIChkID0gdGhpc1tpXSA+PiBwKSA+IDApIHtcbiAgICAgIG0gPSB0cnVlO1xuICAgICAgciA9IGludDJjaGFyKGQpO1xuICAgIH1cbiAgICB3aGlsZSAoaSA+PSAwKSB7XG4gICAgICBpZiAocCA8IGspIHtcbiAgICAgICAgZCA9ICh0aGlzW2ldICYgKCgxIDw8IHApIC0gMSkpIDw8IChrIC0gcCk7XG4gICAgICAgIGQgfD0gdGhpc1stLWldID4+IChwICs9IHRoaXMuREIgLSBrKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGQgPSAodGhpc1tpXSA+PiAocCAtPSBrKSkgJiBrbTtcbiAgICAgICAgaWYgKHAgPD0gMCkge1xuICAgICAgICAgIHAgKz0gdGhpcy5EQjtcbiAgICAgICAgICAtLWk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChkID4gMCkgbSA9IHRydWU7XG4gICAgICBpZiAobSkgciArPSBpbnQyY2hhcihkKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG0gPyByIDogXCIwXCI7XG59XG5cbi8vIChwdWJsaWMpIC10aGlzXG5cbmZ1bmN0aW9uIGJuTmVnYXRlKCkge1xuICB2YXIgciA9IG5iaSgpO1xuICBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcywgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB8dGhpc3xcblxuZnVuY3Rpb24gYm5BYnMoKSB7XG4gIHJldHVybiAodGhpcy5zIDwgMCkgPyB0aGlzLm5lZ2F0ZSgpIDogdGhpcztcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuICsgaWYgdGhpcyA+IGEsIC0gaWYgdGhpcyA8IGEsIDAgaWYgZXF1YWxcblxuZnVuY3Rpb24gYm5Db21wYXJlVG8oYSkge1xuICB2YXIgciA9IHRoaXMucyAtIGEucztcbiAgaWYgKHIgIT0gMCkgcmV0dXJuIHI7XG4gIHZhciBpID0gdGhpcy50O1xuICByID0gaSAtIGEudDtcbiAgaWYgKHIgIT0gMCkgcmV0dXJuIHI7XG4gIHdoaWxlICgtLWkgPj0gMCkgaWYgKChyID0gdGhpc1tpXSAtIGFbaV0pICE9IDApIHJldHVybiByO1xuICByZXR1cm4gMDtcbn1cblxuLy8gcmV0dXJucyBiaXQgbGVuZ3RoIG9mIHRoZSBpbnRlZ2VyIHhcblxuZnVuY3Rpb24gbmJpdHMoeCkge1xuICB2YXIgciA9IDEsXG4gICAgdDtcbiAgaWYgKCh0ID0geCA+Pj4gMTYpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICByICs9IDE2O1xuICB9XG4gIGlmICgodCA9IHggPj4gOCkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIHIgKz0gODtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDQpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICByICs9IDQ7XG4gIH1cbiAgaWYgKCh0ID0geCA+PiAyKSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgciArPSAyO1xuICB9XG4gIGlmICgodCA9IHggPj4gMSkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIHIgKz0gMTtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHRoZSBudW1iZXIgb2YgYml0cyBpbiBcInRoaXNcIlxuXG5mdW5jdGlvbiBibkJpdExlbmd0aCgpIHtcbiAgaWYgKHRoaXMudCA8PSAwKSByZXR1cm4gMDtcbiAgcmV0dXJuIHRoaXMuREIgKiAodGhpcy50IC0gMSkgKyBuYml0cyh0aGlzW3RoaXMudCAtIDFdIF4gKHRoaXMucyAmIHRoaXMuRE0pKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPDwgbipEQlxuXG5mdW5jdGlvbiBibnBETFNoaWZ0VG8obiwgcikge1xuICB2YXIgaTtcbiAgZm9yIChpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHJbaSArIG5dID0gdGhpc1tpXTtcbiAgZm9yIChpID0gbiAtIDE7IGkgPj0gMDsgLS1pKSByW2ldID0gMDtcbiAgci50ID0gdGhpcy50ICsgbjtcbiAgci5zID0gdGhpcy5zO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuKkRCXG5cbmZ1bmN0aW9uIGJucERSU2hpZnRUbyhuLCByKSB7XG4gIGZvciAodmFyIGkgPSBuOyBpIDwgdGhpcy50OyArK2kpIHJbaSAtIG5dID0gdGhpc1tpXTtcbiAgci50ID0gTWF0aC5tYXgodGhpcy50IC0gbiwgMCk7XG4gIHIucyA9IHRoaXMucztcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPDwgblxuXG5mdW5jdGlvbiBibnBMU2hpZnRUbyhuLCByKSB7XG4gIHZhciBicyA9IG4gJSB0aGlzLkRCO1xuICB2YXIgY2JzID0gdGhpcy5EQiAtIGJzO1xuICB2YXIgYm0gPSAoMSA8PCBjYnMpIC0gMTtcbiAgdmFyIGRzID0gTWF0aC5mbG9vcihuIC8gdGhpcy5EQiksXG4gICAgYyA9ICh0aGlzLnMgPDwgYnMpICYgdGhpcy5ETSxcbiAgICBpO1xuICBmb3IgKGkgPSB0aGlzLnQgLSAxOyBpID49IDA7IC0taSkge1xuICAgIHJbaSArIGRzICsgMV0gPSAodGhpc1tpXSA+PiBjYnMpIHwgYztcbiAgICBjID0gKHRoaXNbaV0gJiBibSkgPDwgYnM7XG4gIH1cbiAgZm9yIChpID0gZHMgLSAxOyBpID49IDA7IC0taSkgcltpXSA9IDA7XG4gIHJbZHNdID0gYztcbiAgci50ID0gdGhpcy50ICsgZHMgKyAxO1xuICByLnMgPSB0aGlzLnM7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gblxuXG5mdW5jdGlvbiBibnBSU2hpZnRUbyhuLCByKSB7XG4gIHIucyA9IHRoaXMucztcbiAgdmFyIGRzID0gTWF0aC5mbG9vcihuIC8gdGhpcy5EQik7XG4gIGlmIChkcyA+PSB0aGlzLnQpIHtcbiAgICByLnQgPSAwO1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgYnMgPSBuICUgdGhpcy5EQjtcbiAgdmFyIGNicyA9IHRoaXMuREIgLSBicztcbiAgdmFyIGJtID0gKDEgPDwgYnMpIC0gMTtcbiAgclswXSA9IHRoaXNbZHNdID4+IGJzO1xuICBmb3IgKHZhciBpID0gZHMgKyAxOyBpIDwgdGhpcy50OyArK2kpIHtcbiAgICByW2kgLSBkcyAtIDFdIHw9ICh0aGlzW2ldICYgYm0pIDw8IGNicztcbiAgICByW2kgLSBkc10gPSB0aGlzW2ldID4+IGJzO1xuICB9XG4gIGlmIChicyA+IDApIHJbdGhpcy50IC0gZHMgLSAxXSB8PSAodGhpcy5zICYgYm0pIDw8IGNicztcbiAgci50ID0gdGhpcy50IC0gZHM7XG4gIHIuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgLSBhXG5cbmZ1bmN0aW9uIGJucFN1YlRvKGEsIHIpIHtcbiAgdmFyIGkgPSAwLFxuICAgIGMgPSAwLFxuICAgIG0gPSBNYXRoLm1pbihhLnQsIHRoaXMudCk7XG4gIHdoaWxlIChpIDwgbSkge1xuICAgIGMgKz0gdGhpc1tpXSAtIGFbaV07XG4gICAgcltpKytdID0gYyAmIHRoaXMuRE07XG4gICAgYyA+Pj0gdGhpcy5EQjtcbiAgfVxuICBpZiAoYS50IDwgdGhpcy50KSB7XG4gICAgYyAtPSBhLnM7XG4gICAgd2hpbGUgKGkgPCB0aGlzLnQpIHtcbiAgICAgIGMgKz0gdGhpc1tpXTtcbiAgICAgIHJbaSsrXSA9IGMgJiB0aGlzLkRNO1xuICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICB9XG4gICAgYyArPSB0aGlzLnM7XG4gIH0gZWxzZSB7XG4gICAgYyArPSB0aGlzLnM7XG4gICAgd2hpbGUgKGkgPCBhLnQpIHtcbiAgICAgIGMgLT0gYVtpXTtcbiAgICAgIHJbaSsrXSA9IGMgJiB0aGlzLkRNO1xuICAgICAgYyA+Pj0gdGhpcy5EQjtcbiAgICB9XG4gICAgYyAtPSBhLnM7XG4gIH1cbiAgci5zID0gKGMgPCAwKSA/IC0xIDogMDtcbiAgaWYgKGMgPCAtMSkgcltpKytdID0gdGhpcy5EViArIGM7XG4gIGVsc2UgaWYgKGMgPiAwKSByW2krK10gPSBjO1xuICByLnQgPSBpO1xuICByLmNsYW1wKCk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICogYSwgciAhPSB0aGlzLGEgKEhBQyAxNC4xMilcbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cblxuZnVuY3Rpb24gYm5wTXVsdGlwbHlUbyhhLCByKSB7XG4gIHZhciB4ID0gdGhpcy5hYnMoKSxcbiAgICB5ID0gYS5hYnMoKTtcbiAgdmFyIGkgPSB4LnQ7XG4gIHIudCA9IGkgKyB5LnQ7XG4gIHdoaWxlICgtLWkgPj0gMCkgcltpXSA9IDA7XG4gIGZvciAoaSA9IDA7IGkgPCB5LnQ7ICsraSkgcltpICsgeC50XSA9IHguYW0oMCwgeVtpXSwgciwgaSwgMCwgeC50KTtcbiAgci5zID0gMDtcbiAgci5jbGFtcCgpO1xuICBpZiAodGhpcy5zICE9IGEucykgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIsIHIpO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gdGhpc14yLCByICE9IHRoaXMgKEhBQyAxNC4xNilcblxuZnVuY3Rpb24gYm5wU3F1YXJlVG8ocikge1xuICB2YXIgeCA9IHRoaXMuYWJzKCk7XG4gIHZhciBpID0gci50ID0gMiAqIHgudDtcbiAgd2hpbGUgKC0taSA+PSAwKSByW2ldID0gMDtcbiAgZm9yIChpID0gMDsgaSA8IHgudCAtIDE7ICsraSkge1xuICAgIHZhciBjID0geC5hbShpLCB4W2ldLCByLCAyICogaSwgMCwgMSk7XG4gICAgaWYgKChyW2kgKyB4LnRdICs9IHguYW0oaSArIDEsIDIgKiB4W2ldLCByLCAyICogaSArIDEsIGMsIHgudCAtIGkgLSAxKSkgPj0geC5EVikge1xuICAgICAgcltpICsgeC50XSAtPSB4LkRWO1xuICAgICAgcltpICsgeC50ICsgMV0gPSAxO1xuICAgIH1cbiAgfVxuICBpZiAoci50ID4gMCkgcltyLnQgLSAxXSArPSB4LmFtKGksIHhbaV0sIHIsIDIgKiBpLCAwLCAxKTtcbiAgci5zID0gMDtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHJvdGVjdGVkKSBkaXZpZGUgdGhpcyBieSBtLCBxdW90aWVudCBhbmQgcmVtYWluZGVyIHRvIHEsIHIgKEhBQyAxNC4yMClcbi8vIHIgIT0gcSwgdGhpcyAhPSBtLiAgcSBvciByIG1heSBiZSBudWxsLlxuXG5mdW5jdGlvbiBibnBEaXZSZW1UbyhtLCBxLCByKSB7XG4gIHZhciBwbSA9IG0uYWJzKCk7XG4gIGlmIChwbS50IDw9IDApIHJldHVybjtcbiAgdmFyIHB0ID0gdGhpcy5hYnMoKTtcbiAgaWYgKHB0LnQgPCBwbS50KSB7XG4gICAgaWYgKHEgIT0gbnVsbCkgcS5mcm9tSW50KDApO1xuICAgIGlmIChyICE9IG51bGwpIHRoaXMuY29weVRvKHIpO1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAociA9PSBudWxsKSByID0gbmJpKCk7XG4gIHZhciB5ID0gbmJpKCksXG4gICAgdHMgPSB0aGlzLnMsXG4gICAgbXMgPSBtLnM7XG4gIHZhciBuc2ggPSB0aGlzLkRCIC0gbmJpdHMocG1bcG0udCAtIDFdKTsgLy8gbm9ybWFsaXplIG1vZHVsdXNcbiAgaWYgKG5zaCA+IDApIHtcbiAgICBwbS5sU2hpZnRUbyhuc2gsIHkpO1xuICAgIHB0LmxTaGlmdFRvKG5zaCwgcik7XG4gIH0gZWxzZSB7XG4gICAgcG0uY29weVRvKHkpO1xuICAgIHB0LmNvcHlUbyhyKTtcbiAgfVxuICB2YXIgeXMgPSB5LnQ7XG4gIHZhciB5MCA9IHlbeXMgLSAxXTtcbiAgaWYgKHkwID09IDApIHJldHVybjtcbiAgdmFyIHl0ID0geTAgKiAoMSA8PCB0aGlzLkYxKSArICgoeXMgPiAxKSA/IHlbeXMgLSAyXSA+PiB0aGlzLkYyIDogMCk7XG4gIHZhciBkMSA9IHRoaXMuRlYgLyB5dCxcbiAgICBkMiA9ICgxIDw8IHRoaXMuRjEpIC8geXQsXG4gICAgZSA9IDEgPDwgdGhpcy5GMjtcbiAgdmFyIGkgPSByLnQsXG4gICAgaiA9IGkgLSB5cyxcbiAgICB0ID0gKHEgPT0gbnVsbCkgPyBuYmkoKSA6IHE7XG4gIHkuZGxTaGlmdFRvKGosIHQpO1xuICBpZiAoci5jb21wYXJlVG8odCkgPj0gMCkge1xuICAgIHJbci50KytdID0gMTtcbiAgICByLnN1YlRvKHQsIHIpO1xuICB9XG4gIEJpZ0ludGVnZXIuT05FLmRsU2hpZnRUbyh5cywgdCk7XG4gIHQuc3ViVG8oeSwgeSk7IC8vIFwibmVnYXRpdmVcIiB5IHNvIHdlIGNhbiByZXBsYWNlIHN1YiB3aXRoIGFtIGxhdGVyXG4gIHdoaWxlICh5LnQgPCB5cykgeVt5LnQrK10gPSAwO1xuICB3aGlsZSAoLS1qID49IDApIHtcbiAgICAvLyBFc3RpbWF0ZSBxdW90aWVudCBkaWdpdFxuICAgIHZhciBxZCA9IChyWy0taV0gPT0geTApID8gdGhpcy5ETSA6IE1hdGguZmxvb3IocltpXSAqIGQxICsgKHJbaSAtIDFdICsgZSkgKiBkMik7XG4gICAgaWYgKChyW2ldICs9IHkuYW0oMCwgcWQsIHIsIGosIDAsIHlzKSkgPCBxZCkgeyAvLyBUcnkgaXQgb3V0XG4gICAgICB5LmRsU2hpZnRUbyhqLCB0KTtcbiAgICAgIHIuc3ViVG8odCwgcik7XG4gICAgICB3aGlsZSAocltpXSA8IC0tcWQpIHIuc3ViVG8odCwgcik7XG4gICAgfVxuICB9XG4gIGlmIChxICE9IG51bGwpIHtcbiAgICByLmRyU2hpZnRUbyh5cywgcSk7XG4gICAgaWYgKHRzICE9IG1zKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ocSwgcSk7XG4gIH1cbiAgci50ID0geXM7XG4gIHIuY2xhbXAoKTtcbiAgaWYgKG5zaCA+IDApIHIuclNoaWZ0VG8obnNoLCByKTsgLy8gRGVub3JtYWxpemUgcmVtYWluZGVyXG4gIGlmICh0cyA8IDApIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhyLCByKTtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBtb2QgYVxuXG5mdW5jdGlvbiBibk1vZChhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYWJzKCkuZGl2UmVtVG8oYSwgbnVsbCwgcik7XG4gIGlmICh0aGlzLnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSBhLnN1YlRvKHIsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gTW9kdWxhciByZWR1Y3Rpb24gdXNpbmcgXCJjbGFzc2ljXCIgYWxnb3JpdGhtXG5cbmZ1bmN0aW9uIENsYXNzaWMobSkge1xuICB0aGlzLm0gPSBtO1xufVxuXG5mdW5jdGlvbiBjQ29udmVydCh4KSB7XG4gIGlmICh4LnMgPCAwIHx8IHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgcmV0dXJuIHgubW9kKHRoaXMubSk7XG4gIGVsc2UgcmV0dXJuIHg7XG59XG5cbmZ1bmN0aW9uIGNSZXZlcnQoeCkge1xuICByZXR1cm4geDtcbn1cblxuZnVuY3Rpb24gY1JlZHVjZSh4KSB7XG4gIHguZGl2UmVtVG8odGhpcy5tLCBudWxsLCB4KTtcbn1cblxuZnVuY3Rpb24gY011bFRvKHgsIHksIHIpIHtcbiAgeC5tdWx0aXBseVRvKHksIHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuZnVuY3Rpb24gY1NxclRvKHgsIHIpIHtcbiAgeC5zcXVhcmVUbyhyKTtcbiAgdGhpcy5yZWR1Y2Uocik7XG59XG5cbkNsYXNzaWMucHJvdG90eXBlLmNvbnZlcnQgPSBjQ29udmVydDtcbkNsYXNzaWMucHJvdG90eXBlLnJldmVydCA9IGNSZXZlcnQ7XG5DbGFzc2ljLnByb3RvdHlwZS5yZWR1Y2UgPSBjUmVkdWNlO1xuQ2xhc3NpYy5wcm90b3R5cGUubXVsVG8gPSBjTXVsVG87XG5DbGFzc2ljLnByb3RvdHlwZS5zcXJUbyA9IGNTcXJUbztcblxuLy8gKHByb3RlY3RlZCkgcmV0dXJuIFwiLTEvdGhpcyAlIDJeREJcIjsgdXNlZnVsIGZvciBNb250LiByZWR1Y3Rpb25cbi8vIGp1c3RpZmljYXRpb246XG4vLyAgICAgICAgIHh5ID09IDEgKG1vZCBtKVxuLy8gICAgICAgICB4eSA9ICAxK2ttXG4vLyAgIHh5KDIteHkpID0gKDEra20pKDEta20pXG4vLyB4W3koMi14eSldID0gMS1rXjJtXjJcbi8vIHhbeSgyLXh5KV0gPT0gMSAobW9kIG1eMilcbi8vIGlmIHkgaXMgMS94IG1vZCBtLCB0aGVuIHkoMi14eSkgaXMgMS94IG1vZCBtXjJcbi8vIHNob3VsZCByZWR1Y2UgeCBhbmQgeSgyLXh5KSBieSBtXjIgYXQgZWFjaCBzdGVwIHRvIGtlZXAgc2l6ZSBib3VuZGVkLlxuLy8gSlMgbXVsdGlwbHkgXCJvdmVyZmxvd3NcIiBkaWZmZXJlbnRseSBmcm9tIEMvQysrLCBzbyBjYXJlIGlzIG5lZWRlZCBoZXJlLlxuXG5mdW5jdGlvbiBibnBJbnZEaWdpdCgpIHtcbiAgaWYgKHRoaXMudCA8IDEpIHJldHVybiAwO1xuICB2YXIgeCA9IHRoaXNbMF07XG4gIGlmICgoeCAmIDEpID09IDApIHJldHVybiAwO1xuICB2YXIgeSA9IHggJiAzOyAvLyB5ID09IDEveCBtb2QgMl4yXG4gIHkgPSAoeSAqICgyIC0gKHggJiAweGYpICogeSkpICYgMHhmOyAvLyB5ID09IDEveCBtb2QgMl40XG4gIHkgPSAoeSAqICgyIC0gKHggJiAweGZmKSAqIHkpKSAmIDB4ZmY7IC8vIHkgPT0gMS94IG1vZCAyXjhcbiAgeSA9ICh5ICogKDIgLSAoKCh4ICYgMHhmZmZmKSAqIHkpICYgMHhmZmZmKSkpICYgMHhmZmZmOyAvLyB5ID09IDEveCBtb2QgMl4xNlxuICAvLyBsYXN0IHN0ZXAgLSBjYWxjdWxhdGUgaW52ZXJzZSBtb2QgRFYgZGlyZWN0bHk7XG4gIC8vIGFzc3VtZXMgMTYgPCBEQiA8PSAzMiBhbmQgYXNzdW1lcyBhYmlsaXR5IHRvIGhhbmRsZSA0OC1iaXQgaW50c1xuICB5ID0gKHkgKiAoMiAtIHggKiB5ICUgdGhpcy5EVikpICUgdGhpcy5EVjsgLy8geSA9PSAxL3ggbW9kIDJeZGJpdHNcbiAgLy8gd2UgcmVhbGx5IHdhbnQgdGhlIG5lZ2F0aXZlIGludmVyc2UsIGFuZCAtRFYgPCB5IDwgRFZcbiAgcmV0dXJuICh5ID4gMCkgPyB0aGlzLkRWIC0geSA6IC15O1xufVxuXG4vLyBNb250Z29tZXJ5IHJlZHVjdGlvblxuXG5mdW5jdGlvbiBNb250Z29tZXJ5KG0pIHtcbiAgdGhpcy5tID0gbTtcbiAgdGhpcy5tcCA9IG0uaW52RGlnaXQoKTtcbiAgdGhpcy5tcGwgPSB0aGlzLm1wICYgMHg3ZmZmO1xuICB0aGlzLm1waCA9IHRoaXMubXAgPj4gMTU7XG4gIHRoaXMudW0gPSAoMSA8PCAobS5EQiAtIDE1KSkgLSAxO1xuICB0aGlzLm10MiA9IDIgKiBtLnQ7XG59XG5cbi8vIHhSIG1vZCBtXG5cbmZ1bmN0aW9uIG1vbnRDb252ZXJ0KHgpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgeC5hYnMoKS5kbFNoaWZ0VG8odGhpcy5tLnQsIHIpO1xuICByLmRpdlJlbVRvKHRoaXMubSwgbnVsbCwgcik7XG4gIGlmICh4LnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSB0aGlzLm0uc3ViVG8ociwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyB4L1IgbW9kIG1cblxuZnVuY3Rpb24gbW9udFJldmVydCh4KSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHguY29weVRvKHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIHggPSB4L1IgbW9kIG0gKEhBQyAxNC4zMilcblxuZnVuY3Rpb24gbW9udFJlZHVjZSh4KSB7XG4gIHdoaWxlICh4LnQgPD0gdGhpcy5tdDIpIC8vIHBhZCB4IHNvIGFtIGhhcyBlbm91Z2ggcm9vbSBsYXRlclxuICAgIHhbeC50KytdID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm0udDsgKytpKSB7XG4gICAgLy8gZmFzdGVyIHdheSBvZiBjYWxjdWxhdGluZyB1MCA9IHhbaV0qbXAgbW9kIERWXG4gICAgdmFyIGogPSB4W2ldICYgMHg3ZmZmO1xuICAgIHZhciB1MCA9IChqICogdGhpcy5tcGwgKyAoKChqICogdGhpcy5tcGggKyAoeFtpXSA+PiAxNSkgKiB0aGlzLm1wbCkgJiB0aGlzLnVtKSA8PCAxNSkpICYgeC5ETTtcbiAgICAvLyB1c2UgYW0gdG8gY29tYmluZSB0aGUgbXVsdGlwbHktc2hpZnQtYWRkIGludG8gb25lIGNhbGxcbiAgICBqID0gaSArIHRoaXMubS50O1xuICAgIHhbal0gKz0gdGhpcy5tLmFtKDAsIHUwLCB4LCBpLCAwLCB0aGlzLm0udCk7XG4gICAgLy8gcHJvcGFnYXRlIGNhcnJ5XG4gICAgd2hpbGUgKHhbal0gPj0geC5EVikge1xuICAgICAgeFtqXSAtPSB4LkRWO1xuICAgICAgeFsrK2pdKys7XG4gICAgfVxuICB9XG4gIHguY2xhbXAoKTtcbiAgeC5kclNoaWZ0VG8odGhpcy5tLnQsIHgpO1xuICBpZiAoeC5jb21wYXJlVG8odGhpcy5tKSA+PSAwKSB4LnN1YlRvKHRoaXMubSwgeCk7XG59XG5cbi8vIHIgPSBcInheMi9SIG1vZCBtXCI7IHggIT0gclxuXG5mdW5jdGlvbiBtb250U3FyVG8oeCwgcikge1xuICB4LnNxdWFyZVRvKHIpO1xuICB0aGlzLnJlZHVjZShyKTtcbn1cblxuLy8gciA9IFwieHkvUiBtb2QgbVwiOyB4LHkgIT0gclxuXG5mdW5jdGlvbiBtb250TXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcik7XG4gIHRoaXMucmVkdWNlKHIpO1xufVxuXG5Nb250Z29tZXJ5LnByb3RvdHlwZS5jb252ZXJ0ID0gbW9udENvbnZlcnQ7XG5Nb250Z29tZXJ5LnByb3RvdHlwZS5yZXZlcnQgPSBtb250UmV2ZXJ0O1xuTW9udGdvbWVyeS5wcm90b3R5cGUucmVkdWNlID0gbW9udFJlZHVjZTtcbk1vbnRnb21lcnkucHJvdG90eXBlLm11bFRvID0gbW9udE11bFRvO1xuTW9udGdvbWVyeS5wcm90b3R5cGUuc3FyVG8gPSBtb250U3FyVG87XG5cbi8vIChwcm90ZWN0ZWQpIHRydWUgaWZmIHRoaXMgaXMgZXZlblxuXG5mdW5jdGlvbiBibnBJc0V2ZW4oKSB7XG4gIHJldHVybiAoKHRoaXMudCA+IDApID8gKHRoaXNbMF0gJiAxKSA6IHRoaXMucykgPT0gMDtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpc15lLCBlIDwgMl4zMiwgZG9pbmcgc3FyIGFuZCBtdWwgd2l0aCBcInJcIiAoSEFDIDE0Ljc5KVxuXG5mdW5jdGlvbiBibnBFeHAoZSwgeikge1xuICBpZiAoZSA+IDB4ZmZmZmZmZmYgfHwgZSA8IDEpIHJldHVybiBCaWdJbnRlZ2VyLk9ORTtcbiAgdmFyIHIgPSBuYmkoKSxcbiAgICByMiA9IG5iaSgpLFxuICAgIGcgPSB6LmNvbnZlcnQodGhpcyksXG4gICAgaSA9IG5iaXRzKGUpIC0gMTtcbiAgZy5jb3B5VG8ocik7XG4gIHdoaWxlICgtLWkgPj0gMCkge1xuICAgIHouc3FyVG8ociwgcjIpO1xuICAgIGlmICgoZSAmICgxIDw8IGkpKSA+IDApIHoubXVsVG8ocjIsIGcsIHIpO1xuICAgIGVsc2Uge1xuICAgICAgdmFyIHQgPSByO1xuICAgICAgciA9IHIyO1xuICAgICAgcjIgPSB0O1xuICAgIH1cbiAgfVxuICByZXR1cm4gei5yZXZlcnQocik7XG59XG5cbi8vIChwdWJsaWMpIHRoaXNeZSAlIG0sIDAgPD0gZSA8IDJeMzJcblxuZnVuY3Rpb24gYm5Nb2RQb3dJbnQoZSwgbSkge1xuICB2YXIgejtcbiAgaWYgKGUgPCAyNTYgfHwgbS5pc0V2ZW4oKSkgeiA9IG5ldyBDbGFzc2ljKG0pO1xuICBlbHNlIHogPSBuZXcgTW9udGdvbWVyeShtKTtcbiAgcmV0dXJuIHRoaXMuZXhwKGUsIHopO1xufVxuXG4vLyBwcm90ZWN0ZWRcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNvcHlUbyA9IGJucENvcHlUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21JbnQgPSBibnBGcm9tSW50O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZnJvbVN0cmluZyA9IGJucEZyb21TdHJpbmc7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGFtcCA9IGJucENsYW1wO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZGxTaGlmdFRvID0gYm5wRExTaGlmdFRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZHJTaGlmdFRvID0gYm5wRFJTaGlmdFRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubFNoaWZ0VG8gPSBibnBMU2hpZnRUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLnJTaGlmdFRvID0gYm5wUlNoaWZ0VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zdWJUbyA9IGJucFN1YlRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlUbyA9IGJucE11bHRpcGx5VG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmVUbyA9IGJucFNxdWFyZVRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2UmVtVG8gPSBibnBEaXZSZW1UbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmludkRpZ2l0ID0gYm5wSW52RGlnaXQ7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5pc0V2ZW4gPSBibnBJc0V2ZW47XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5leHAgPSBibnBFeHA7XG5cbi8vIHB1YmxpY1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9TdHJpbmcgPSBiblRvU3RyaW5nO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubmVnYXRlID0gYm5OZWdhdGU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hYnMgPSBibkFicztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNvbXBhcmVUbyA9IGJuQ29tcGFyZVRvO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYml0TGVuZ3RoID0gYm5CaXRMZW5ndGg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2QgPSBibk1vZDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZFBvd0ludCA9IGJuTW9kUG93SW50O1xuXG4vLyBcImNvbnN0YW50c1wiXG5CaWdJbnRlZ2VyLlpFUk8gPSBuYnYoMCk7XG5CaWdJbnRlZ2VyLk9ORSA9IG5idigxKTtcblxubW9kdWxlLmV4cG9ydHMgPSBCaWdJbnRlZ2VyO1xuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG4vKlxuICogQ29weXJpZ2h0IChjKSAyMDAzLTIwMDUgIFRvbSBXdSAodGp3QGNzLlN0YW5mb3JkLkVEVSkgXG4gKiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIE1vZGlmaWVkIGJ5IFJlY3VyaXR5IExhYnMgR21iSFxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZ1xuICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4gKiBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbiAqIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0b1xuICogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvXG4gKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmVcbiAqIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTLUlTXCIgQU5EIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIFxuICogRVhQUkVTUywgSU1QTElFRCBPUiBPVEhFUldJU0UsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04sIEFOWSBcbiAqIFdBUlJBTlRZIE9GIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFxuICpcbiAqIElOIE5PIEVWRU5UIFNIQUxMIFRPTSBXVSBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBJTkNJREVOVEFMLFxuICogSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9GIEFOWSBLSU5ELCBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSXG4gKiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIE9SIE5PVCBBRFZJU0VEIE9GXG4gKiBUSEUgUE9TU0lCSUxJVFkgT0YgREFNQUdFLCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIEFSSVNJTkcgT1VUXG4gKiBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxuICpcbiAqIEluIGFkZGl0aW9uLCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbiBhcHBsaWVzOlxuICpcbiAqIEFsbCByZWRpc3RyaWJ1dGlvbnMgbXVzdCByZXRhaW4gYW4gaW50YWN0IGNvcHkgb2YgdGhpcyBjb3B5cmlnaHQgbm90aWNlXG4gKiBhbmQgZGlzY2xhaW1lci5cbiAqL1xuXG5cbi8vIEV4dGVuZGVkIEphdmFTY3JpcHQgQk4gZnVuY3Rpb25zLCByZXF1aXJlZCBmb3IgUlNBIHByaXZhdGUgb3BzLlxuXG4vLyBWZXJzaW9uIDEuMTogbmV3IEJpZ0ludGVnZXIoXCIwXCIsIDEwKSByZXR1cm5zIFwicHJvcGVyXCIgemVyb1xuLy8gVmVyc2lvbiAxLjI6IHNxdWFyZSgpIEFQSSwgaXNQcm9iYWJsZVByaW1lIGZpeFxuXG4vLyAocHVibGljKVxuZnVuY3Rpb24gYm5DbG9uZSgpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5jb3B5VG8ocik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgaW50ZWdlclxuXG5mdW5jdGlvbiBibkludFZhbHVlKCkge1xuICBpZiAodGhpcy5zIDwgMCkge1xuICAgIGlmICh0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXNbMF0gLSB0aGlzLkRWO1xuICAgIGVsc2UgaWYgKHRoaXMudCA9PSAwKSByZXR1cm4gLTE7XG4gIH0gZWxzZSBpZiAodGhpcy50ID09IDEpIHJldHVybiB0aGlzWzBdO1xuICBlbHNlIGlmICh0aGlzLnQgPT0gMCkgcmV0dXJuIDA7XG4gIC8vIGFzc3VtZXMgMTYgPCBEQiA8IDMyXG4gIHJldHVybiAoKHRoaXNbMV0gJiAoKDEgPDwgKDMyIC0gdGhpcy5EQikpIC0gMSkpIDw8IHRoaXMuREIpIHwgdGhpc1swXTtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGJ5dGVcblxuZnVuY3Rpb24gYm5CeXRlVmFsdWUoKSB7XG4gIHJldHVybiAodGhpcy50ID09IDApID8gdGhpcy5zIDogKHRoaXNbMF0gPDwgMjQpID4+IDI0O1xufVxuXG4vLyAocHVibGljKSByZXR1cm4gdmFsdWUgYXMgc2hvcnQgKGFzc3VtZXMgREI+PTE2KVxuXG5mdW5jdGlvbiBiblNob3J0VmFsdWUoKSB7XG4gIHJldHVybiAodGhpcy50ID09IDApID8gdGhpcy5zIDogKHRoaXNbMF0gPDwgMTYpID4+IDE2O1xufVxuXG4vLyAocHJvdGVjdGVkKSByZXR1cm4geCBzLnQuIHJeeCA8IERWXG5cbmZ1bmN0aW9uIGJucENodW5rU2l6ZShyKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKE1hdGguTE4yICogdGhpcy5EQiAvIE1hdGgubG9nKHIpKTtcbn1cblxuLy8gKHB1YmxpYykgMCBpZiB0aGlzID09IDAsIDEgaWYgdGhpcyA+IDBcblxuZnVuY3Rpb24gYm5TaWdOdW0oKSB7XG4gIGlmICh0aGlzLnMgPCAwKSByZXR1cm4gLTE7XG4gIGVsc2UgaWYgKHRoaXMudCA8PSAwIHx8ICh0aGlzLnQgPT0gMSAmJiB0aGlzWzBdIDw9IDApKSByZXR1cm4gMDtcbiAgZWxzZSByZXR1cm4gMTtcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCB0byByYWRpeCBzdHJpbmdcblxuZnVuY3Rpb24gYm5wVG9SYWRpeChiKSB7XG4gIGlmIChiID09IG51bGwpIGIgPSAxMDtcbiAgaWYgKHRoaXMuc2lnbnVtKCkgPT0gMCB8fCBiIDwgMiB8fCBiID4gMzYpIHJldHVybiBcIjBcIjtcbiAgdmFyIGNzID0gdGhpcy5jaHVua1NpemUoYik7XG4gIHZhciBhID0gTWF0aC5wb3coYiwgY3MpO1xuICB2YXIgZCA9IG5idihhKSxcbiAgICB5ID0gbmJpKCksXG4gICAgeiA9IG5iaSgpLFxuICAgIHIgPSBcIlwiO1xuICB0aGlzLmRpdlJlbVRvKGQsIHksIHopO1xuICB3aGlsZSAoeS5zaWdudW0oKSA+IDApIHtcbiAgICByID0gKGEgKyB6LmludFZhbHVlKCkpLnRvU3RyaW5nKGIpLnN1YnN0cigxKSArIHI7XG4gICAgeS5kaXZSZW1UbyhkLCB5LCB6KTtcbiAgfVxuICByZXR1cm4gei5pbnRWYWx1ZSgpLnRvU3RyaW5nKGIpICsgcjtcbn1cblxuLy8gKHByb3RlY3RlZCkgY29udmVydCBmcm9tIHJhZGl4IHN0cmluZ1xuXG5mdW5jdGlvbiBibnBGcm9tUmFkaXgocywgYikge1xuICB0aGlzLmZyb21JbnQoMCk7XG4gIGlmIChiID09IG51bGwpIGIgPSAxMDtcbiAgdmFyIGNzID0gdGhpcy5jaHVua1NpemUoYik7XG4gIHZhciBkID0gTWF0aC5wb3coYiwgY3MpLFxuICAgIG1pID0gZmFsc2UsXG4gICAgaiA9IDAsXG4gICAgdyA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcy5sZW5ndGg7ICsraSkge1xuICAgIHZhciB4ID0gaW50QXQocywgaSk7XG4gICAgaWYgKHggPCAwKSB7XG4gICAgICBpZiAocy5jaGFyQXQoaSkgPT0gXCItXCIgJiYgdGhpcy5zaWdudW0oKSA9PSAwKSBtaSA9IHRydWU7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdyA9IGIgKiB3ICsgeDtcbiAgICBpZiAoKytqID49IGNzKSB7XG4gICAgICB0aGlzLmRNdWx0aXBseShkKTtcbiAgICAgIHRoaXMuZEFkZE9mZnNldCh3LCAwKTtcbiAgICAgIGogPSAwO1xuICAgICAgdyA9IDA7XG4gICAgfVxuICB9XG4gIGlmIChqID4gMCkge1xuICAgIHRoaXMuZE11bHRpcGx5KE1hdGgucG93KGIsIGopKTtcbiAgICB0aGlzLmRBZGRPZmZzZXQodywgMCk7XG4gIH1cbiAgaWYgKG1pKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8odGhpcywgdGhpcyk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIGFsdGVybmF0ZSBjb25zdHJ1Y3RvclxuXG5mdW5jdGlvbiBibnBGcm9tTnVtYmVyKGEsIGIsIGMpIHtcbiAgaWYgKFwibnVtYmVyXCIgPT0gdHlwZW9mIGIpIHtcbiAgICAvLyBuZXcgQmlnSW50ZWdlcihpbnQsaW50LFJORylcbiAgICBpZiAoYSA8IDIpIHRoaXMuZnJvbUludCgxKTtcbiAgICBlbHNlIHtcbiAgICAgIHRoaXMuZnJvbU51bWJlcihhLCBjKTtcbiAgICAgIGlmICghdGhpcy50ZXN0Qml0KGEgLSAxKSkgLy8gZm9yY2UgTVNCIHNldFxuICAgICAgICB0aGlzLmJpdHdpc2VUbyhCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoYSAtIDEpLCBvcF9vciwgdGhpcyk7XG4gICAgICBpZiAodGhpcy5pc0V2ZW4oKSkgdGhpcy5kQWRkT2Zmc2V0KDEsIDApOyAvLyBmb3JjZSBvZGRcbiAgICAgIHdoaWxlICghdGhpcy5pc1Byb2JhYmxlUHJpbWUoYikpIHtcbiAgICAgICAgdGhpcy5kQWRkT2Zmc2V0KDIsIDApO1xuICAgICAgICBpZiAodGhpcy5iaXRMZW5ndGgoKSA+IGEpIHRoaXMuc3ViVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGEgLSAxKSwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxSTkcpXG4gICAgdmFyIHggPSBuZXcgQXJyYXkoKSxcbiAgICAgIHQgPSBhICYgNztcbiAgICB4Lmxlbmd0aCA9IChhID4+IDMpICsgMTtcbiAgICBiLm5leHRCeXRlcyh4KTtcbiAgICBpZiAodCA+IDApIHhbMF0gJj0gKCgxIDw8IHQpIC0gMSk7XG4gICAgZWxzZSB4WzBdID0gMDtcbiAgICB0aGlzLmZyb21TdHJpbmcoeCwgMjU2KTtcbiAgfVxufVxuXG4vLyAocHVibGljKSBjb252ZXJ0IHRvIGJpZ2VuZGlhbiBieXRlIGFycmF5XG5cbmZ1bmN0aW9uIGJuVG9CeXRlQXJyYXkoKSB7XG4gIHZhciBpID0gdGhpcy50LFxuICAgIHIgPSBuZXcgQXJyYXkoKTtcbiAgclswXSA9IHRoaXMucztcbiAgdmFyIHAgPSB0aGlzLkRCIC0gKGkgKiB0aGlzLkRCKSAlIDgsXG4gICAgZCwgayA9IDA7XG4gIGlmIChpLS0gPiAwKSB7XG4gICAgaWYgKHAgPCB0aGlzLkRCICYmIChkID0gdGhpc1tpXSA+PiBwKSAhPSAodGhpcy5zICYgdGhpcy5ETSkgPj4gcClcbiAgICAgIHJbaysrXSA9IGQgfCAodGhpcy5zIDw8ICh0aGlzLkRCIC0gcCkpO1xuICAgIHdoaWxlIChpID49IDApIHtcbiAgICAgIGlmIChwIDwgOCkge1xuICAgICAgICBkID0gKHRoaXNbaV0gJiAoKDEgPDwgcCkgLSAxKSkgPDwgKDggLSBwKTtcbiAgICAgICAgZCB8PSB0aGlzWy0taV0gPj4gKHAgKz0gdGhpcy5EQiAtIDgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZCA9ICh0aGlzW2ldID4+IChwIC09IDgpKSAmIDB4ZmY7XG4gICAgICAgIGlmIChwIDw9IDApIHtcbiAgICAgICAgICBwICs9IHRoaXMuREI7XG4gICAgICAgICAgLS1pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvL2lmKChkJjB4ODApICE9IDApIGQgfD0gLTI1NjtcbiAgICAgIC8vaWYoayA9PSAwICYmICh0aGlzLnMmMHg4MCkgIT0gKGQmMHg4MCkpICsraztcbiAgICAgIGlmIChrID4gMCB8fCBkICE9IHRoaXMucykgcltrKytdID0gZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIGJuRXF1YWxzKGEpIHtcbiAgcmV0dXJuICh0aGlzLmNvbXBhcmVUbyhhKSA9PSAwKTtcbn1cblxuZnVuY3Rpb24gYm5NaW4oYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpIDwgMCkgPyB0aGlzIDogYTtcbn1cblxuZnVuY3Rpb24gYm5NYXgoYSkge1xuICByZXR1cm4gKHRoaXMuY29tcGFyZVRvKGEpID4gMCkgPyB0aGlzIDogYTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgb3AgYSAoYml0d2lzZSlcblxuZnVuY3Rpb24gYm5wQml0d2lzZVRvKGEsIG9wLCByKSB7XG4gIHZhciBpLCBmLCBtID0gTWF0aC5taW4oYS50LCB0aGlzLnQpO1xuICBmb3IgKGkgPSAwOyBpIDwgbTsgKytpKSByW2ldID0gb3AodGhpc1tpXSwgYVtpXSk7XG4gIGlmIChhLnQgPCB0aGlzLnQpIHtcbiAgICBmID0gYS5zICYgdGhpcy5ETTtcbiAgICBmb3IgKGkgPSBtOyBpIDwgdGhpcy50OyArK2kpIHJbaV0gPSBvcCh0aGlzW2ldLCBmKTtcbiAgICByLnQgPSB0aGlzLnQ7XG4gIH0gZWxzZSB7XG4gICAgZiA9IHRoaXMucyAmIHRoaXMuRE07XG4gICAgZm9yIChpID0gbTsgaSA8IGEudDsgKytpKSByW2ldID0gb3AoZiwgYVtpXSk7XG4gICAgci50ID0gYS50O1xuICB9XG4gIHIucyA9IG9wKHRoaXMucywgYS5zKTtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHVibGljKSB0aGlzICYgYVxuXG5mdW5jdGlvbiBvcF9hbmQoeCwgeSkge1xuICByZXR1cm4geCAmIHk7XG59XG5cbmZ1bmN0aW9uIGJuQW5kKGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3BfYW5kLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgfCBhXG5cbmZ1bmN0aW9uIG9wX29yKHgsIHkpIHtcbiAgcmV0dXJuIHggfCB5O1xufVxuXG5mdW5jdGlvbiBibk9yKGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5iaXR3aXNlVG8oYSwgb3Bfb3IsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgdGhpcyBeIGFcblxuZnVuY3Rpb24gb3BfeG9yKHgsIHkpIHtcbiAgcmV0dXJuIHggXiB5O1xufVxuXG5mdW5jdGlvbiBiblhvcihhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYml0d2lzZVRvKGEsIG9wX3hvciwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzICYgfmFcblxuZnVuY3Rpb24gb3BfYW5kbm90KHgsIHkpIHtcbiAgcmV0dXJuIHggJiB+eTtcbn1cblxuZnVuY3Rpb24gYm5BbmROb3QoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLmJpdHdpc2VUbyhhLCBvcF9hbmRub3QsIHIpO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgfnRoaXNcblxuZnVuY3Rpb24gYm5Ob3QoKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHJbaV0gPSB0aGlzLkRNICYgfnRoaXNbaV07XG4gIHIudCA9IHRoaXMudDtcbiAgci5zID0gfnRoaXMucztcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgPDwgblxuXG5mdW5jdGlvbiBiblNoaWZ0TGVmdChuKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIGlmIChuIDwgMCkgdGhpcy5yU2hpZnRUbygtbiwgcik7XG4gIGVsc2UgdGhpcy5sU2hpZnRUbyhuLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgPj4gblxuXG5mdW5jdGlvbiBiblNoaWZ0UmlnaHQobikge1xuICB2YXIgciA9IG5iaSgpO1xuICBpZiAobiA8IDApIHRoaXMubFNoaWZ0VG8oLW4sIHIpO1xuICBlbHNlIHRoaXMuclNoaWZ0VG8obiwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyByZXR1cm4gaW5kZXggb2YgbG93ZXN0IDEtYml0IGluIHgsIHggPCAyXjMxXG5cbmZ1bmN0aW9uIGxiaXQoeCkge1xuICBpZiAoeCA9PSAwKSByZXR1cm4gLTE7XG4gIHZhciByID0gMDtcbiAgaWYgKCh4ICYgMHhmZmZmKSA9PSAwKSB7XG4gICAgeCA+Pj0gMTY7XG4gICAgciArPSAxNjtcbiAgfVxuICBpZiAoKHggJiAweGZmKSA9PSAwKSB7XG4gICAgeCA+Pj0gODtcbiAgICByICs9IDg7XG4gIH1cbiAgaWYgKCh4ICYgMHhmKSA9PSAwKSB7XG4gICAgeCA+Pj0gNDtcbiAgICByICs9IDQ7XG4gIH1cbiAgaWYgKCh4ICYgMykgPT0gMCkge1xuICAgIHggPj49IDI7XG4gICAgciArPSAyO1xuICB9XG4gIGlmICgoeCAmIDEpID09IDApKytyO1xuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJucyBpbmRleCBvZiBsb3dlc3QgMS1iaXQgKG9yIC0xIGlmIG5vbmUpXG5cbmZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKVxuICAgIGlmICh0aGlzW2ldICE9IDApIHJldHVybiBpICogdGhpcy5EQiArIGxiaXQodGhpc1tpXSk7XG4gIGlmICh0aGlzLnMgPCAwKSByZXR1cm4gdGhpcy50ICogdGhpcy5EQjtcbiAgcmV0dXJuIC0xO1xufVxuXG4vLyByZXR1cm4gbnVtYmVyIG9mIDEgYml0cyBpbiB4XG5cbmZ1bmN0aW9uIGNiaXQoeCkge1xuICB2YXIgciA9IDA7XG4gIHdoaWxlICh4ICE9IDApIHtcbiAgICB4ICY9IHggLSAxO1xuICAgICsrcjtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuLy8gKHB1YmxpYykgcmV0dXJuIG51bWJlciBvZiBzZXQgYml0c1xuXG5mdW5jdGlvbiBibkJpdENvdW50KCkge1xuICB2YXIgciA9IDAsXG4gICAgeCA9IHRoaXMucyAmIHRoaXMuRE07XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHIgKz0gY2JpdCh0aGlzW2ldIF4geCk7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0cnVlIGlmZiBudGggYml0IGlzIHNldFxuXG5mdW5jdGlvbiBiblRlc3RCaXQobikge1xuICB2YXIgaiA9IE1hdGguZmxvb3IobiAvIHRoaXMuREIpO1xuICBpZiAoaiA+PSB0aGlzLnQpIHJldHVybiAodGhpcy5zICE9IDApO1xuICByZXR1cm4gKCh0aGlzW2pdICYgKDEgPDwgKG4gJSB0aGlzLkRCKSkpICE9IDApO1xufVxuXG4vLyAocHJvdGVjdGVkKSB0aGlzIG9wICgxPDxuKVxuXG5mdW5jdGlvbiBibnBDaGFuZ2VCaXQobiwgb3ApIHtcbiAgdmFyIHIgPSBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQobik7XG4gIHRoaXMuYml0d2lzZVRvKHIsIG9wLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgfCAoMTw8bilcblxuZnVuY3Rpb24gYm5TZXRCaXQobikge1xuICByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobiwgb3Bfb3IpO1xufVxuXG4vLyAocHVibGljKSB0aGlzICYgfigxPDxuKVxuXG5mdW5jdGlvbiBibkNsZWFyQml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX2FuZG5vdCk7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgXiAoMTw8bilcblxuZnVuY3Rpb24gYm5GbGlwQml0KG4pIHtcbiAgcmV0dXJuIHRoaXMuY2hhbmdlQml0KG4sIG9wX3hvcik7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzICsgYVxuXG5mdW5jdGlvbiBibnBBZGRUbyhhLCByKSB7XG4gIHZhciBpID0gMCxcbiAgICBjID0gMCxcbiAgICBtID0gTWF0aC5taW4oYS50LCB0aGlzLnQpO1xuICB3aGlsZSAoaSA8IG0pIHtcbiAgICBjICs9IHRoaXNbaV0gKyBhW2ldO1xuICAgIHJbaSsrXSA9IGMgJiB0aGlzLkRNO1xuICAgIGMgPj49IHRoaXMuREI7XG4gIH1cbiAgaWYgKGEudCA8IHRoaXMudCkge1xuICAgIGMgKz0gYS5zO1xuICAgIHdoaWxlIChpIDwgdGhpcy50KSB7XG4gICAgICBjICs9IHRoaXNbaV07XG4gICAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgKz0gdGhpcy5zO1xuICB9IGVsc2Uge1xuICAgIGMgKz0gdGhpcy5zO1xuICAgIHdoaWxlIChpIDwgYS50KSB7XG4gICAgICBjICs9IGFbaV07XG4gICAgICByW2krK10gPSBjICYgdGhpcy5ETTtcbiAgICAgIGMgPj49IHRoaXMuREI7XG4gICAgfVxuICAgIGMgKz0gYS5zO1xuICB9XG4gIHIucyA9IChjIDwgMCkgPyAtMSA6IDA7XG4gIGlmIChjID4gMCkgcltpKytdID0gYztcbiAgZWxzZSBpZiAoYyA8IC0xKSByW2krK10gPSB0aGlzLkRWICsgYztcbiAgci50ID0gaTtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHVibGljKSB0aGlzICsgYVxuXG5mdW5jdGlvbiBibkFkZChhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuYWRkVG8oYSwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIC0gYVxuXG5mdW5jdGlvbiBiblN1YnRyYWN0KGEpIHtcbiAgdmFyIHIgPSBuYmkoKTtcbiAgdGhpcy5zdWJUbyhhLCByKTtcbiAgcmV0dXJuIHI7XG59XG5cbi8vIChwdWJsaWMpIHRoaXMgKiBhXG5cbmZ1bmN0aW9uIGJuTXVsdGlwbHkoYSkge1xuICB2YXIgciA9IG5iaSgpO1xuICB0aGlzLm11bHRpcGx5VG8oYSwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzXjJcblxuZnVuY3Rpb24gYm5TcXVhcmUoKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuc3F1YXJlVG8ocik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzIC8gYVxuXG5mdW5jdGlvbiBibkRpdmlkZShhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuZGl2UmVtVG8oYSwgciwgbnVsbCk7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSB0aGlzICUgYVxuXG5mdW5jdGlvbiBiblJlbWFpbmRlcihhKSB7XG4gIHZhciByID0gbmJpKCk7XG4gIHRoaXMuZGl2UmVtVG8oYSwgbnVsbCwgcik7XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSBbdGhpcy9hLHRoaXMlYV1cblxuZnVuY3Rpb24gYm5EaXZpZGVBbmRSZW1haW5kZXIoYSkge1xuICB2YXIgcSA9IG5iaSgpLFxuICAgIHIgPSBuYmkoKTtcbiAgdGhpcy5kaXZSZW1UbyhhLCBxLCByKTtcbiAgcmV0dXJuIG5ldyBBcnJheShxLCByKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyAqPSBuLCB0aGlzID49IDAsIDEgPCBuIDwgRFZcblxuZnVuY3Rpb24gYm5wRE11bHRpcGx5KG4pIHtcbiAgdGhpc1t0aGlzLnRdID0gdGhpcy5hbSgwLCBuIC0gMSwgdGhpcywgMCwgMCwgdGhpcy50KTtcbiAgKyt0aGlzLnQ7XG4gIHRoaXMuY2xhbXAoKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgdGhpcyArPSBuIDw8IHcgd29yZHMsIHRoaXMgPj0gMFxuXG5mdW5jdGlvbiBibnBEQWRkT2Zmc2V0KG4sIHcpIHtcbiAgaWYgKG4gPT0gMCkgcmV0dXJuO1xuICB3aGlsZSAodGhpcy50IDw9IHcpIHRoaXNbdGhpcy50KytdID0gMDtcbiAgdGhpc1t3XSArPSBuO1xuICB3aGlsZSAodGhpc1t3XSA+PSB0aGlzLkRWKSB7XG4gICAgdGhpc1t3XSAtPSB0aGlzLkRWO1xuICAgIGlmICgrK3cgPj0gdGhpcy50KSB0aGlzW3RoaXMudCsrXSA9IDA7XG4gICAgKyt0aGlzW3ddO1xuICB9XG59XG5cbi8vIEEgXCJudWxsXCIgcmVkdWNlclxuXG5mdW5jdGlvbiBOdWxsRXhwKCkge31cblxuZnVuY3Rpb24gbk5vcCh4KSB7XG4gIHJldHVybiB4O1xufVxuXG5mdW5jdGlvbiBuTXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcik7XG59XG5cbmZ1bmN0aW9uIG5TcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocik7XG59XG5cbk51bGxFeHAucHJvdG90eXBlLmNvbnZlcnQgPSBuTm9wO1xuTnVsbEV4cC5wcm90b3R5cGUucmV2ZXJ0ID0gbk5vcDtcbk51bGxFeHAucHJvdG90eXBlLm11bFRvID0gbk11bFRvO1xuTnVsbEV4cC5wcm90b3R5cGUuc3FyVG8gPSBuU3FyVG87XG5cbi8vIChwdWJsaWMpIHRoaXNeZVxuXG5mdW5jdGlvbiBiblBvdyhlKSB7XG4gIHJldHVybiB0aGlzLmV4cChlLCBuZXcgTnVsbEV4cCgpKTtcbn1cblxuLy8gKHByb3RlY3RlZCkgciA9IGxvd2VyIG4gd29yZHMgb2YgXCJ0aGlzICogYVwiLCBhLnQgPD0gblxuLy8gXCJ0aGlzXCIgc2hvdWxkIGJlIHRoZSBsYXJnZXIgb25lIGlmIGFwcHJvcHJpYXRlLlxuXG5mdW5jdGlvbiBibnBNdWx0aXBseUxvd2VyVG8oYSwgbiwgcikge1xuICB2YXIgaSA9IE1hdGgubWluKHRoaXMudCArIGEudCwgbik7XG4gIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDBcbiAgci50ID0gaTtcbiAgd2hpbGUgKGkgPiAwKSByWy0taV0gPSAwO1xuICB2YXIgajtcbiAgZm9yIChqID0gci50IC0gdGhpcy50OyBpIDwgajsgKytpKSByW2kgKyB0aGlzLnRdID0gdGhpcy5hbSgwLCBhW2ldLCByLCBpLCAwLCB0aGlzLnQpO1xuICBmb3IgKGogPSBNYXRoLm1pbihhLnQsIG4pOyBpIDwgajsgKytpKSB0aGlzLmFtKDAsIGFbaV0sIHIsIGksIDAsIG4gLSBpKTtcbiAgci5jbGFtcCgpO1xufVxuXG4vLyAocHJvdGVjdGVkKSByID0gXCJ0aGlzICogYVwiIHdpdGhvdXQgbG93ZXIgbiB3b3JkcywgbiA+IDBcbi8vIFwidGhpc1wiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS5cblxuZnVuY3Rpb24gYm5wTXVsdGlwbHlVcHBlclRvKGEsIG4sIHIpIHtcbiAgLS1uO1xuICB2YXIgaSA9IHIudCA9IHRoaXMudCArIGEudCAtIG47XG4gIHIucyA9IDA7IC8vIGFzc3VtZXMgYSx0aGlzID49IDBcbiAgd2hpbGUgKC0taSA+PSAwKSByW2ldID0gMDtcbiAgZm9yIChpID0gTWF0aC5tYXgobiAtIHRoaXMudCwgMCk7IGkgPCBhLnQ7ICsraSlcbiAgICByW3RoaXMudCArIGkgLSBuXSA9IHRoaXMuYW0obiAtIGksIGFbaV0sIHIsIDAsIDAsIHRoaXMudCArIGkgLSBuKTtcbiAgci5jbGFtcCgpO1xuICByLmRyU2hpZnRUbygxLCByKTtcbn1cblxuLy8gQmFycmV0dCBtb2R1bGFyIHJlZHVjdGlvblxuXG5mdW5jdGlvbiBCYXJyZXR0KG0pIHtcbiAgLy8gc2V0dXAgQmFycmV0dFxuICB0aGlzLnIyID0gbmJpKCk7XG4gIHRoaXMucTMgPSBuYmkoKTtcbiAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKDIgKiBtLnQsIHRoaXMucjIpO1xuICB0aGlzLm11ID0gdGhpcy5yMi5kaXZpZGUobSk7XG4gIHRoaXMubSA9IG07XG59XG5cbmZ1bmN0aW9uIGJhcnJldHRDb252ZXJ0KHgpIHtcbiAgaWYgKHgucyA8IDAgfHwgeC50ID4gMiAqIHRoaXMubS50KSByZXR1cm4geC5tb2QodGhpcy5tKTtcbiAgZWxzZSBpZiAoeC5jb21wYXJlVG8odGhpcy5tKSA8IDApIHJldHVybiB4O1xuICBlbHNlIHtcbiAgICB2YXIgciA9IG5iaSgpO1xuICAgIHguY29weVRvKHIpO1xuICAgIHRoaXMucmVkdWNlKHIpO1xuICAgIHJldHVybiByO1xuICB9XG59XG5cbmZ1bmN0aW9uIGJhcnJldHRSZXZlcnQoeCkge1xuICByZXR1cm4geDtcbn1cblxuLy8geCA9IHggbW9kIG0gKEhBQyAxNC40MilcblxuZnVuY3Rpb24gYmFycmV0dFJlZHVjZSh4KSB7XG4gIHguZHJTaGlmdFRvKHRoaXMubS50IC0gMSwgdGhpcy5yMik7XG4gIGlmICh4LnQgPiB0aGlzLm0udCArIDEpIHtcbiAgICB4LnQgPSB0aGlzLm0udCArIDE7XG4gICAgeC5jbGFtcCgpO1xuICB9XG4gIHRoaXMubXUubXVsdGlwbHlVcHBlclRvKHRoaXMucjIsIHRoaXMubS50ICsgMSwgdGhpcy5xMyk7XG4gIHRoaXMubS5tdWx0aXBseUxvd2VyVG8odGhpcy5xMywgdGhpcy5tLnQgKyAxLCB0aGlzLnIyKTtcbiAgd2hpbGUgKHguY29tcGFyZVRvKHRoaXMucjIpIDwgMCkgeC5kQWRkT2Zmc2V0KDEsIHRoaXMubS50ICsgMSk7XG4gIHguc3ViVG8odGhpcy5yMiwgeCk7XG4gIHdoaWxlICh4LmNvbXBhcmVUbyh0aGlzLm0pID49IDApIHguc3ViVG8odGhpcy5tLCB4KTtcbn1cblxuLy8gciA9IHheMiBtb2QgbTsgeCAhPSByXG5cbmZ1bmN0aW9uIGJhcnJldHRTcXJUbyh4LCByKSB7XG4gIHguc3F1YXJlVG8ocik7XG4gIHRoaXMucmVkdWNlKHIpO1xufVxuXG4vLyByID0geCp5IG1vZCBtOyB4LHkgIT0gclxuXG5mdW5jdGlvbiBiYXJyZXR0TXVsVG8oeCwgeSwgcikge1xuICB4Lm11bHRpcGx5VG8oeSwgcik7XG4gIHRoaXMucmVkdWNlKHIpO1xufVxuXG5CYXJyZXR0LnByb3RvdHlwZS5jb252ZXJ0ID0gYmFycmV0dENvbnZlcnQ7XG5CYXJyZXR0LnByb3RvdHlwZS5yZXZlcnQgPSBiYXJyZXR0UmV2ZXJ0O1xuQmFycmV0dC5wcm90b3R5cGUucmVkdWNlID0gYmFycmV0dFJlZHVjZTtcbkJhcnJldHQucHJvdG90eXBlLm11bFRvID0gYmFycmV0dE11bFRvO1xuQmFycmV0dC5wcm90b3R5cGUuc3FyVG8gPSBiYXJyZXR0U3FyVG87XG5cbi8vIChwdWJsaWMpIHRoaXNeZSAlIG0gKEhBQyAxNC44NSlcblxuZnVuY3Rpb24gYm5Nb2RQb3coZSwgbSkge1xuICB2YXIgaSA9IGUuYml0TGVuZ3RoKCksXG4gICAgaywgciA9IG5idigxKSxcbiAgICB6O1xuICBpZiAoaSA8PSAwKSByZXR1cm4gcjtcbiAgZWxzZSBpZiAoaSA8IDE4KSBrID0gMTtcbiAgZWxzZSBpZiAoaSA8IDQ4KSBrID0gMztcbiAgZWxzZSBpZiAoaSA8IDE0NCkgayA9IDQ7XG4gIGVsc2UgaWYgKGkgPCA3NjgpIGsgPSA1O1xuICBlbHNlIGsgPSA2O1xuICBpZiAoaSA8IDgpXG4gICAgeiA9IG5ldyBDbGFzc2ljKG0pO1xuICBlbHNlIGlmIChtLmlzRXZlbigpKVxuICAgIHogPSBuZXcgQmFycmV0dChtKTtcbiAgZWxzZVxuICAgIHogPSBuZXcgTW9udGdvbWVyeShtKTtcblxuICAvLyBwcmVjb21wdXRhdGlvblxuICB2YXIgZyA9IG5ldyBBcnJheSgpLFxuICAgIG4gPSAzLFxuICAgIGsxID0gayAtIDEsXG4gICAga20gPSAoMSA8PCBrKSAtIDE7XG4gIGdbMV0gPSB6LmNvbnZlcnQodGhpcyk7XG4gIGlmIChrID4gMSkge1xuICAgIHZhciBnMiA9IG5iaSgpO1xuICAgIHouc3FyVG8oZ1sxXSwgZzIpO1xuICAgIHdoaWxlIChuIDw9IGttKSB7XG4gICAgICBnW25dID0gbmJpKCk7XG4gICAgICB6Lm11bFRvKGcyLCBnW24gLSAyXSwgZ1tuXSk7XG4gICAgICBuICs9IDI7XG4gICAgfVxuICB9XG5cbiAgdmFyIGogPSBlLnQgLSAxLFxuICAgIHcsIGlzMSA9IHRydWUsXG4gICAgcjIgPSBuYmkoKSxcbiAgICB0O1xuICBpID0gbmJpdHMoZVtqXSkgLSAxO1xuICB3aGlsZSAoaiA+PSAwKSB7XG4gICAgaWYgKGkgPj0gazEpIHcgPSAoZVtqXSA+PiAoaSAtIGsxKSkgJiBrbTtcbiAgICBlbHNlIHtcbiAgICAgIHcgPSAoZVtqXSAmICgoMSA8PCAoaSArIDEpKSAtIDEpKSA8PCAoazEgLSBpKTtcbiAgICAgIGlmIChqID4gMCkgdyB8PSBlW2ogLSAxXSA+PiAodGhpcy5EQiArIGkgLSBrMSk7XG4gICAgfVxuXG4gICAgbiA9IGs7XG4gICAgd2hpbGUgKCh3ICYgMSkgPT0gMCkge1xuICAgICAgdyA+Pj0gMTtcbiAgICAgIC0tbjtcbiAgICB9XG4gICAgaWYgKChpIC09IG4pIDwgMCkge1xuICAgICAgaSArPSB0aGlzLkRCO1xuICAgICAgLS1qO1xuICAgIH1cbiAgICBpZiAoaXMxKSB7IC8vIHJldCA9PSAxLCBkb24ndCBib3RoZXIgc3F1YXJpbmcgb3IgbXVsdGlwbHlpbmcgaXRcbiAgICAgIGdbd10uY29weVRvKHIpO1xuICAgICAgaXMxID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoaWxlIChuID4gMSkge1xuICAgICAgICB6LnNxclRvKHIsIHIyKTtcbiAgICAgICAgei5zcXJUbyhyMiwgcik7XG4gICAgICAgIG4gLT0gMjtcbiAgICAgIH1cbiAgICAgIGlmIChuID4gMCkgei5zcXJUbyhyLCByMik7XG4gICAgICBlbHNlIHtcbiAgICAgICAgdCA9IHI7XG4gICAgICAgIHIgPSByMjtcbiAgICAgICAgcjIgPSB0O1xuICAgICAgfVxuICAgICAgei5tdWxUbyhyMiwgZ1t3XSwgcik7XG4gICAgfVxuXG4gICAgd2hpbGUgKGogPj0gMCAmJiAoZVtqXSAmICgxIDw8IGkpKSA9PSAwKSB7XG4gICAgICB6LnNxclRvKHIsIHIyKTtcbiAgICAgIHQgPSByO1xuICAgICAgciA9IHIyO1xuICAgICAgcjIgPSB0O1xuICAgICAgaWYgKC0taSA8IDApIHtcbiAgICAgICAgaSA9IHRoaXMuREIgLSAxO1xuICAgICAgICAtLWo7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB6LnJldmVydChyKTtcbn1cblxuLy8gKHB1YmxpYykgZ2NkKHRoaXMsYSkgKEhBQyAxNC41NClcblxuZnVuY3Rpb24gYm5HQ0QoYSkge1xuICB2YXIgeCA9ICh0aGlzLnMgPCAwKSA/IHRoaXMubmVnYXRlKCkgOiB0aGlzLmNsb25lKCk7XG4gIHZhciB5ID0gKGEucyA8IDApID8gYS5uZWdhdGUoKSA6IGEuY2xvbmUoKTtcbiAgaWYgKHguY29tcGFyZVRvKHkpIDwgMCkge1xuICAgIHZhciB0ID0geDtcbiAgICB4ID0geTtcbiAgICB5ID0gdDtcbiAgfVxuICB2YXIgaSA9IHguZ2V0TG93ZXN0U2V0Qml0KCksXG4gICAgZyA9IHkuZ2V0TG93ZXN0U2V0Qml0KCk7XG4gIGlmIChnIDwgMCkgcmV0dXJuIHg7XG4gIGlmIChpIDwgZykgZyA9IGk7XG4gIGlmIChnID4gMCkge1xuICAgIHguclNoaWZ0VG8oZywgeCk7XG4gICAgeS5yU2hpZnRUbyhnLCB5KTtcbiAgfVxuICB3aGlsZSAoeC5zaWdudW0oKSA+IDApIHtcbiAgICBpZiAoKGkgPSB4LmdldExvd2VzdFNldEJpdCgpKSA+IDApIHguclNoaWZ0VG8oaSwgeCk7XG4gICAgaWYgKChpID0geS5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB5LnJTaGlmdFRvKGksIHkpO1xuICAgIGlmICh4LmNvbXBhcmVUbyh5KSA+PSAwKSB7XG4gICAgICB4LnN1YlRvKHksIHgpO1xuICAgICAgeC5yU2hpZnRUbygxLCB4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgeS5zdWJUbyh4LCB5KTtcbiAgICAgIHkuclNoaWZ0VG8oMSwgeSk7XG4gICAgfVxuICB9XG4gIGlmIChnID4gMCkgeS5sU2hpZnRUbyhnLCB5KTtcbiAgcmV0dXJuIHk7XG59XG5cbi8vIChwcm90ZWN0ZWQpIHRoaXMgJSBuLCBuIDwgMl4yNlxuXG5mdW5jdGlvbiBibnBNb2RJbnQobikge1xuICBpZiAobiA8PSAwKSByZXR1cm4gMDtcbiAgdmFyIGQgPSB0aGlzLkRWICUgbixcbiAgICByID0gKHRoaXMucyA8IDApID8gbiAtIDEgOiAwO1xuICBpZiAodGhpcy50ID4gMClcbiAgICBpZiAoZCA9PSAwKSByID0gdGhpc1swXSAlIG47XG4gICAgZWxzZSBmb3IgKHZhciBpID0gdGhpcy50IC0gMTsgaSA+PSAwOyAtLWkpIHIgPSAoZCAqIHIgKyB0aGlzW2ldKSAlIG47XG4gIHJldHVybiByO1xufVxuXG4vLyAocHVibGljKSAxL3RoaXMgJSBtIChIQUMgMTQuNjEpXG5cbmZ1bmN0aW9uIGJuTW9kSW52ZXJzZShtKSB7XG4gIHZhciBhYyA9IG0uaXNFdmVuKCk7XG4gIGlmICgodGhpcy5pc0V2ZW4oKSAmJiBhYykgfHwgbS5zaWdudW0oKSA9PSAwKSByZXR1cm4gQmlnSW50ZWdlci5aRVJPO1xuICB2YXIgdSA9IG0uY2xvbmUoKSxcbiAgICB2ID0gdGhpcy5jbG9uZSgpO1xuICB2YXIgYSA9IG5idigxKSxcbiAgICBiID0gbmJ2KDApLFxuICAgIGMgPSBuYnYoMCksXG4gICAgZCA9IG5idigxKTtcbiAgd2hpbGUgKHUuc2lnbnVtKCkgIT0gMCkge1xuICAgIHdoaWxlICh1LmlzRXZlbigpKSB7XG4gICAgICB1LnJTaGlmdFRvKDEsIHUpO1xuICAgICAgaWYgKGFjKSB7XG4gICAgICAgIGlmICghYS5pc0V2ZW4oKSB8fCAhYi5pc0V2ZW4oKSkge1xuICAgICAgICAgIGEuYWRkVG8odGhpcywgYSk7XG4gICAgICAgICAgYi5zdWJUbyhtLCBiKTtcbiAgICAgICAgfVxuICAgICAgICBhLnJTaGlmdFRvKDEsIGEpO1xuICAgICAgfSBlbHNlIGlmICghYi5pc0V2ZW4oKSkgYi5zdWJUbyhtLCBiKTtcbiAgICAgIGIuclNoaWZ0VG8oMSwgYik7XG4gICAgfVxuICAgIHdoaWxlICh2LmlzRXZlbigpKSB7XG4gICAgICB2LnJTaGlmdFRvKDEsIHYpO1xuICAgICAgaWYgKGFjKSB7XG4gICAgICAgIGlmICghYy5pc0V2ZW4oKSB8fCAhZC5pc0V2ZW4oKSkge1xuICAgICAgICAgIGMuYWRkVG8odGhpcywgYyk7XG4gICAgICAgICAgZC5zdWJUbyhtLCBkKTtcbiAgICAgICAgfVxuICAgICAgICBjLnJTaGlmdFRvKDEsIGMpO1xuICAgICAgfSBlbHNlIGlmICghZC5pc0V2ZW4oKSkgZC5zdWJUbyhtLCBkKTtcbiAgICAgIGQuclNoaWZ0VG8oMSwgZCk7XG4gICAgfVxuICAgIGlmICh1LmNvbXBhcmVUbyh2KSA+PSAwKSB7XG4gICAgICB1LnN1YlRvKHYsIHUpO1xuICAgICAgaWYgKGFjKSBhLnN1YlRvKGMsIGEpO1xuICAgICAgYi5zdWJUbyhkLCBiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdi5zdWJUbyh1LCB2KTtcbiAgICAgIGlmIChhYykgYy5zdWJUbyhhLCBjKTtcbiAgICAgIGQuc3ViVG8oYiwgZCk7XG4gICAgfVxuICB9XG4gIGlmICh2LmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVSTztcbiAgaWYgKGQuY29tcGFyZVRvKG0pID49IDApIHJldHVybiBkLnN1YnRyYWN0KG0pO1xuICBpZiAoZC5zaWdudW0oKSA8IDApIGQuYWRkVG8obSwgZCk7XG4gIGVsc2UgcmV0dXJuIGQ7XG4gIGlmIChkLnNpZ251bSgpIDwgMCkgcmV0dXJuIGQuYWRkKG0pO1xuICBlbHNlIHJldHVybiBkO1xufVxuXG52YXIgbG93cHJpbWVzID0gWzIsIDMsIDUsIDcsIDExLCAxMywgMTcsIDE5LCAyMywgMjksIDMxLCAzNywgNDEsIDQzLCA0NywgNTMsIDU5LCA2MSwgNjcsIDcxLCA3MywgNzksIDgzLCA4OSwgOTcsIDEwMSxcbiAgICAxMDMsIDEwNywgMTA5LCAxMTMsIDEyNywgMTMxLCAxMzcsIDEzOSwgMTQ5LCAxNTEsIDE1NywgMTYzLCAxNjcsIDE3MywgMTc5LCAxODEsIDE5MSwgMTkzLCAxOTcsIDE5OSwgMjExLCAyMjMsIDIyNyxcbiAgICAyMjksIDIzMywgMjM5LCAyNDEsIDI1MSwgMjU3LCAyNjMsIDI2OSwgMjcxLCAyNzcsIDI4MSwgMjgzLCAyOTMsIDMwNywgMzExLCAzMTMsIDMxNywgMzMxLCAzMzcsIDM0NywgMzQ5LCAzNTMsIDM1OSxcbiAgICAzNjcsIDM3MywgMzc5LCAzODMsIDM4OSwgMzk3LCA0MDEsIDQwOSwgNDE5LCA0MjEsIDQzMSwgNDMzLCA0MzksIDQ0MywgNDQ5LCA0NTcsIDQ2MSwgNDYzLCA0NjcsIDQ3OSwgNDg3LCA0OTEsIDQ5OSxcbiAgICA1MDMsIDUwOSwgNTIxLCA1MjMsIDU0MSwgNTQ3LCA1NTcsIDU2MywgNTY5LCA1NzEsIDU3NywgNTg3LCA1OTMsIDU5OSwgNjAxLCA2MDcsIDYxMywgNjE3LCA2MTksIDYzMSwgNjQxLCA2NDMsIDY0NyxcbiAgICA2NTMsIDY1OSwgNjYxLCA2NzMsIDY3NywgNjgzLCA2OTEsIDcwMSwgNzA5LCA3MTksIDcyNywgNzMzLCA3MzksIDc0MywgNzUxLCA3NTcsIDc2MSwgNzY5LCA3NzMsIDc4NywgNzk3LCA4MDksIDgxMSxcbiAgICA4MjEsIDgyMywgODI3LCA4MjksIDgzOSwgODUzLCA4NTcsIDg1OSwgODYzLCA4NzcsIDg4MSwgODgzLCA4ODcsIDkwNywgOTExLCA5MTksIDkyOSwgOTM3LCA5NDEsIDk0NywgOTUzLCA5NjcsIDk3MSxcbiAgICA5NzcsIDk4MywgOTkxLCA5OTdcbl07XG52YXIgbHBsaW0gPSAoMSA8PCAyNikgLyBsb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aCAtIDFdO1xuXG4vLyAocHVibGljKSB0ZXN0IHByaW1hbGl0eSB3aXRoIGNlcnRhaW50eSA+PSAxLS41XnRcblxuZnVuY3Rpb24gYm5Jc1Byb2JhYmxlUHJpbWUodCkge1xuICB2YXIgaSwgeCA9IHRoaXMuYWJzKCk7XG4gIGlmICh4LnQgPT0gMSAmJiB4WzBdIDw9IGxvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoIC0gMV0pIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKVxuICAgICAgaWYgKHhbMF0gPT0gbG93cHJpbWVzW2ldKSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHguaXNFdmVuKCkpIHJldHVybiBmYWxzZTtcbiAgaSA9IDE7XG4gIHdoaWxlIChpIDwgbG93cHJpbWVzLmxlbmd0aCkge1xuICAgIHZhciBtID0gbG93cHJpbWVzW2ldLFxuICAgICAgaiA9IGkgKyAxO1xuICAgIHdoaWxlIChqIDwgbG93cHJpbWVzLmxlbmd0aCAmJiBtIDwgbHBsaW0pIG0gKj0gbG93cHJpbWVzW2orK107XG4gICAgbSA9IHgubW9kSW50KG0pO1xuICAgIHdoaWxlIChpIDwgaikgaWYgKG0gJSBsb3dwcmltZXNbaSsrXSA9PSAwKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHgubWlsbGVyUmFiaW4odCk7XG59XG5cbi8qIGFkZGVkIGJ5IFJlY3VyaXR5IExhYnMgKi9cblxuZnVuY3Rpb24gbmJpdHMoeCkge1xuICB2YXIgbiA9IDEsXG4gICAgdDtcbiAgaWYgKCh0ID0geCA+Pj4gMTYpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICBuICs9IDE2O1xuICB9XG4gIGlmICgodCA9IHggPj4gOCkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIG4gKz0gODtcbiAgfVxuICBpZiAoKHQgPSB4ID4+IDQpICE9IDApIHtcbiAgICB4ID0gdDtcbiAgICBuICs9IDQ7XG4gIH1cbiAgaWYgKCh0ID0geCA+PiAyKSAhPSAwKSB7XG4gICAgeCA9IHQ7XG4gICAgbiArPSAyO1xuICB9XG4gIGlmICgodCA9IHggPj4gMSkgIT0gMCkge1xuICAgIHggPSB0O1xuICAgIG4gKz0gMTtcbiAgfVxuICByZXR1cm4gbjtcbn1cblxuZnVuY3Rpb24gYm5Ub01QSSgpIHtcbiAgdmFyIGJhID0gdGhpcy50b0J5dGVBcnJheSgpO1xuICB2YXIgc2l6ZSA9IChiYS5sZW5ndGggLSAxKSAqIDggKyBuYml0cyhiYVswXSk7XG4gIHZhciByZXN1bHQgPSBcIlwiO1xuICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoc2l6ZSAmIDB4RkYwMCkgPj4gOCk7XG4gIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHNpemUgJiAweEZGKTtcbiAgcmVzdWx0ICs9IHV0aWwuYmluMnN0cihiYSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG4vKiBFTkQgb2YgYWRkaXRpb24gKi9cblxuLy8gKHByb3RlY3RlZCkgdHJ1ZSBpZiBwcm9iYWJseSBwcmltZSAoSEFDIDQuMjQsIE1pbGxlci1SYWJpbilcbmZ1bmN0aW9uIGJucE1pbGxlclJhYmluKHQpIHtcbiAgdmFyIG4xID0gdGhpcy5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gIHZhciBrID0gbjEuZ2V0TG93ZXN0U2V0Qml0KCk7XG4gIGlmIChrIDw9IDApIHJldHVybiBmYWxzZTtcbiAgdmFyIHIgPSBuMS5zaGlmdFJpZ2h0KGspO1xuICB0ID0gKHQgKyAxKSA+PiAxO1xuICBpZiAodCA+IGxvd3ByaW1lcy5sZW5ndGgpIHQgPSBsb3dwcmltZXMubGVuZ3RoO1xuICB2YXIgYSA9IG5iaSgpO1xuICB2YXIgaiwgYmFzZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0OyArK2kpIHtcbiAgICAvL1BpY2sgYmFzZXMgYXQgcmFuZG9tLCBpbnN0ZWFkIG9mIHN0YXJ0aW5nIGF0IDJcbiAgICBmb3IgKDs7KSB7XG4gICAgICBqID0gbG93cHJpbWVzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGxvd3ByaW1lcy5sZW5ndGgpXTtcbiAgICAgIGlmIChiYXNlcy5pbmRleE9mKGopID09IC0xKSBicmVhaztcbiAgICB9XG4gICAgYmFzZXMucHVzaChqKTtcbiAgICBhLmZyb21JbnQoaik7XG4gICAgdmFyIHkgPSBhLm1vZFBvdyhyLCB0aGlzKTtcbiAgICBpZiAoeS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDAgJiYgeS5jb21wYXJlVG8objEpICE9IDApIHtcbiAgICAgIHZhciBqID0gMTtcbiAgICAgIHdoaWxlIChqKysgPCBrICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7XG4gICAgICAgIHkgPSB5Lm1vZFBvd0ludCgyLCB0aGlzKTtcbiAgICAgICAgaWYgKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoeS5jb21wYXJlVG8objEpICE9IDApIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbnZhciBCaWdJbnRlZ2VyID0gcmVxdWlyZSgnLi9qc2JuLmpzJyk7XG5cbi8vIHByb3RlY3RlZFxuQmlnSW50ZWdlci5wcm90b3R5cGUuY2h1bmtTaXplID0gYm5wQ2h1bmtTaXplO1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9SYWRpeCA9IGJucFRvUmFkaXg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tUmFkaXggPSBibnBGcm9tUmFkaXg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tTnVtYmVyID0gYm5wRnJvbU51bWJlcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmJpdHdpc2VUbyA9IGJucEJpdHdpc2VUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLmNoYW5nZUJpdCA9IGJucENoYW5nZUJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmFkZFRvID0gYm5wQWRkVG87XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kTXVsdGlwbHkgPSBibnBETXVsdGlwbHk7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5kQWRkT2Zmc2V0ID0gYm5wREFkZE9mZnNldDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5TG93ZXJUbyA9IGJucE11bHRpcGx5TG93ZXJUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VXBwZXJUbyA9IGJucE11bHRpcGx5VXBwZXJUbztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludCA9IGJucE1vZEludDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1pbGxlclJhYmluID0gYm5wTWlsbGVyUmFiaW47XG5cbi8vIHB1YmxpY1xuQmlnSW50ZWdlci5wcm90b3R5cGUuY2xvbmUgPSBibkNsb25lO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuaW50VmFsdWUgPSBibkludFZhbHVlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYnl0ZVZhbHVlID0gYm5CeXRlVmFsdWU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5zaG9ydFZhbHVlID0gYm5TaG9ydFZhbHVlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc2lnbnVtID0gYm5TaWdOdW07XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS50b0J5dGVBcnJheSA9IGJuVG9CeXRlQXJyYXk7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5lcXVhbHMgPSBibkVxdWFscztcbkJpZ0ludGVnZXIucHJvdG90eXBlLm1pbiA9IGJuTWluO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubWF4ID0gYm5NYXg7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5hbmQgPSBibkFuZDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLm9yID0gYm5PcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnhvciA9IGJuWG9yO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kTm90ID0gYm5BbmROb3Q7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5ub3QgPSBibk5vdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0TGVmdCA9IGJuU2hpZnRMZWZ0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRSaWdodCA9IGJuU2hpZnRSaWdodDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmdldExvd2VzdFNldEJpdCA9IGJuR2V0TG93ZXN0U2V0Qml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuYml0Q291bnQgPSBibkJpdENvdW50O1xuQmlnSW50ZWdlci5wcm90b3R5cGUudGVzdEJpdCA9IGJuVGVzdEJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLnNldEJpdCA9IGJuU2V0Qml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuY2xlYXJCaXQgPSBibkNsZWFyQml0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZmxpcEJpdCA9IGJuRmxpcEJpdDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmFkZCA9IGJuQWRkO1xuQmlnSW50ZWdlci5wcm90b3R5cGUuc3VidHJhY3QgPSBiblN1YnRyYWN0O1xuQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHkgPSBibk11bHRpcGx5O1xuQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2aWRlID0gYm5EaXZpZGU7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5yZW1haW5kZXIgPSBiblJlbWFpbmRlcjtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmRpdmlkZUFuZFJlbWFpbmRlciA9IGJuRGl2aWRlQW5kUmVtYWluZGVyO1xuQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93ID0gYm5Nb2RQb3c7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2RJbnZlcnNlID0gYm5Nb2RJbnZlcnNlO1xuQmlnSW50ZWdlci5wcm90b3R5cGUucG93ID0gYm5Qb3c7XG5CaWdJbnRlZ2VyLnByb3RvdHlwZS5nY2QgPSBibkdDRDtcbkJpZ0ludGVnZXIucHJvdG90eXBlLmlzUHJvYmFibGVQcmltZSA9IGJuSXNQcm9iYWJsZVByaW1lO1xuQmlnSW50ZWdlci5wcm90b3R5cGUudG9NUEkgPSBiblRvTVBJO1xuXG4vLyBKU0JOLXNwZWNpZmljIGV4dGVuc2lvblxuQmlnSW50ZWdlci5wcm90b3R5cGUuc3F1YXJlID0gYm5TcXVhcmU7XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuLy9cbi8vIFJTQSBpbXBsZW1lbnRhdGlvblxuXG52YXIgQmlnSW50ZWdlciA9IHJlcXVpcmUoJy4vanNibi5qcycpLFxuICB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbCcpLFxuICByYW5kb20gPSByZXF1aXJlKCcuLi9yYW5kb20uanMnKTtcblxuZnVuY3Rpb24gU2VjdXJlUmFuZG9tKCkge1xuICBmdW5jdGlvbiBuZXh0Qnl0ZXMoYnl0ZUFycmF5KSB7XG4gICAgZm9yICh2YXIgbiA9IDA7IG4gPCBieXRlQXJyYXkubGVuZ3RoOyBuKyspIHtcbiAgICAgIGJ5dGVBcnJheVtuXSA9IHJhbmRvbS5nZXRTZWN1cmVSYW5kb21PY3RldCgpO1xuICAgIH1cbiAgfVxuICB0aGlzLm5leHRCeXRlcyA9IG5leHRCeXRlcztcbn1cblxuZnVuY3Rpb24gUlNBKCkge1xuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiB1c2VzIGpzYm4gQmlnIE51bSBsaWJyYXJ5IHRvIGRlY3J5cHQgUlNBXG4gICAqIEBwYXJhbSBtXG4gICAqICAgICAgICAgICAgbWVzc2FnZVxuICAgKiBAcGFyYW0gZFxuICAgKiAgICAgICAgICAgIFJTQSBkIGFzIEJpZ0ludGVnZXJcbiAgICogQHBhcmFtIHBcbiAgICogICAgICAgICAgICBSU0EgcCBhcyBCaWdJbnRlZ2VyXG4gICAqIEBwYXJhbSBxXG4gICAqICAgICAgICAgICAgUlNBIHEgYXMgQmlnSW50ZWdlclxuICAgKiBAcGFyYW0gdVxuICAgKiAgICAgICAgICAgIFJTQSB1IGFzIEJpZ0ludGVnZXJcbiAgICogQHJldHVybiB7QmlnSW50ZWdlcn0gVGhlIGRlY3J5cHRlZCB2YWx1ZSBvZiB0aGUgbWVzc2FnZVxuICAgKi9cbiAgZnVuY3Rpb24gZGVjcnlwdChtLCBkLCBwLCBxLCB1KSB7XG4gICAgdmFyIHhwID0gbS5tb2QocCkubW9kUG93KGQubW9kKHAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKSwgcCk7XG4gICAgdmFyIHhxID0gbS5tb2QocSkubW9kUG93KGQubW9kKHEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKSwgcSk7XG4gICAgdXRpbC5wcmludF9kZWJ1ZyhcInJzYS5qcyBkZWNyeXB0XFxueHBuOlwiICsgdXRpbC5oZXhzdHJkdW1wKHhwLnRvTVBJKCkpICsgXCJcXG54cW46XCIgKyB1dGlsLmhleHN0cmR1bXAoeHEudG9NUEkoKSkpO1xuXG4gICAgdmFyIHQgPSB4cS5zdWJ0cmFjdCh4cCk7XG4gICAgaWYgKHRbMF0gPT0gMCkge1xuICAgICAgdCA9IHhwLnN1YnRyYWN0KHhxKTtcbiAgICAgIHQgPSB0Lm11bHRpcGx5KHUpLm1vZChxKTtcbiAgICAgIHQgPSBxLnN1YnRyYWN0KHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0ID0gdC5tdWx0aXBseSh1KS5tb2QocSk7XG4gICAgfVxuICAgIHJldHVybiB0Lm11bHRpcGx5KHApLmFkZCh4cCk7XG4gIH1cblxuICAvKipcbiAgICogZW5jcnlwdCBtZXNzYWdlXG4gICAqIEBwYXJhbSBtIG1lc3NhZ2UgYXMgQmlnSW50ZWdlclxuICAgKiBAcGFyYW0gZSBwdWJsaWMgTVBJIHBhcnQgYXMgQmlnSW50ZWdlclxuICAgKiBAcGFyYW0gbiBwdWJsaWMgTVBJIHBhcnQgYXMgQmlnSW50ZWdlclxuICAgKiBAcmV0dXJuIEJpZ0ludGVnZXJcbiAgICovXG4gIGZ1bmN0aW9uIGVuY3J5cHQobSwgZSwgbikge1xuICAgIHJldHVybiBtLm1vZFBvd0ludChlLCBuKTtcbiAgfVxuXG4gIC8qIFNpZ24gYW5kIFZlcmlmeSAqL1xuICBmdW5jdGlvbiBzaWduKG0sIGQsIG4pIHtcbiAgICByZXR1cm4gbS5tb2RQb3coZCwgbik7XG4gIH1cblxuICBmdW5jdGlvbiB2ZXJpZnkoeCwgZSwgbikge1xuICAgIHJldHVybiB4Lm1vZFBvd0ludChlLCBuKTtcbiAgfVxuXG4gIC8vIFwiZW1wdHlcIiBSU0Ega2V5IGNvbnN0cnVjdG9yXG5cbiAgZnVuY3Rpb24ga2V5T2JqZWN0KCkge1xuICAgIHRoaXMubiA9IG51bGw7XG4gICAgdGhpcy5lID0gMDtcbiAgICB0aGlzLmVlID0gbnVsbDtcbiAgICB0aGlzLmQgPSBudWxsO1xuICAgIHRoaXMucCA9IG51bGw7XG4gICAgdGhpcy5xID0gbnVsbDtcbiAgICB0aGlzLmRtcDEgPSBudWxsO1xuICAgIHRoaXMuZG1xMSA9IG51bGw7XG4gICAgdGhpcy51ID0gbnVsbDtcbiAgfVxuXG4gIC8vIEdlbmVyYXRlIGEgbmV3IHJhbmRvbSBwcml2YXRlIGtleSBCIGJpdHMgbG9uZywgdXNpbmcgcHVibGljIGV4cHQgRVxuXG4gIGZ1bmN0aW9uIGdlbmVyYXRlKEIsIEUpIHtcbiAgICB2YXIga2V5ID0gbmV3IGtleU9iamVjdCgpO1xuICAgIHZhciBybmcgPSBuZXcgU2VjdXJlUmFuZG9tKCk7XG4gICAgdmFyIHFzID0gQiA+PiAxO1xuICAgIGtleS5lID0gcGFyc2VJbnQoRSwgMTYpO1xuICAgIGtleS5lZSA9IG5ldyBCaWdJbnRlZ2VyKEUsIDE2KTtcbiAgICBmb3IgKDs7KSB7XG4gICAgICBmb3IgKDs7KSB7XG4gICAgICAgIGtleS5wID0gbmV3IEJpZ0ludGVnZXIoQiAtIHFzLCAxLCBybmcpO1xuICAgICAgICBpZiAoa2V5LnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChrZXkuZWUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCAmJiBrZXkucC5pc1Byb2JhYmxlUHJpbWUoMTApKVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZm9yICg7Oykge1xuICAgICAgICBrZXkucSA9IG5ldyBCaWdJbnRlZ2VyKHFzLCAxLCBybmcpO1xuICAgICAgICBpZiAoa2V5LnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChrZXkuZWUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT0gMCAmJiBrZXkucS5pc1Byb2JhYmxlUHJpbWUoMTApKVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKGtleS5wLmNvbXBhcmVUbyhrZXkucSkgPD0gMCkge1xuICAgICAgICB2YXIgdCA9IGtleS5wO1xuICAgICAgICBrZXkucCA9IGtleS5xO1xuICAgICAgICBrZXkucSA9IHQ7XG4gICAgICB9XG4gICAgICB2YXIgcDEgPSBrZXkucC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgICB2YXIgcTEgPSBrZXkucS5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSk7XG4gICAgICB2YXIgcGhpID0gcDEubXVsdGlwbHkocTEpO1xuICAgICAgaWYgKHBoaS5nY2Qoa2V5LmVlKS5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpID09IDApIHtcbiAgICAgICAga2V5Lm4gPSBrZXkucC5tdWx0aXBseShrZXkucSk7XG4gICAgICAgIGtleS5kID0ga2V5LmVlLm1vZEludmVyc2UocGhpKTtcbiAgICAgICAga2V5LmRtcDEgPSBrZXkuZC5tb2QocDEpO1xuICAgICAgICBrZXkuZG1xMSA9IGtleS5kLm1vZChxMSk7XG4gICAgICAgIGtleS51ID0ga2V5LnAubW9kSW52ZXJzZShrZXkucSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ga2V5O1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZW5jcnlwdDtcbiAgdGhpcy5kZWNyeXB0ID0gZGVjcnlwdDtcbiAgdGhpcy52ZXJpZnkgPSB2ZXJpZnk7XG4gIHRoaXMuc2lnbiA9IHNpZ247XG4gIHRoaXMuZ2VuZXJhdGUgPSBnZW5lcmF0ZTtcbiAgdGhpcy5rZXlPYmplY3QgPSBrZXlPYmplY3Q7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUlNBO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0EgXG5cbi8vIFRoZSBHUEc0QnJvd3NlcnMgY3J5cHRvIGludGVyZmFjZVxuXG52YXIgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgLyoqXG4gICAqIFJldHJpZXZlIHNlY3VyZSByYW5kb20gYnl0ZSBzdHJpbmcgb2YgdGhlIHNwZWNpZmllZCBsZW5ndGhcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5ndGggTGVuZ3RoIGluIGJ5dGVzIHRvIGdlbmVyYXRlXG4gICAqIEByZXR1cm4ge1N0cmluZ30gUmFuZG9tIGJ5dGUgc3RyaW5nXG4gICAqL1xuICBnZXRSYW5kb21CeXRlczogZnVuY3Rpb24obGVuZ3RoKSB7XG4gICAgdmFyIHJlc3VsdCA9ICcnO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMuZ2V0U2VjdXJlUmFuZG9tT2N0ZXQoKSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHBzZXVkby1yYW5kb20gbnVtYmVyIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2VcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBmcm9tIE1pbiBvZiB0aGUgcmFuZG9tIG51bWJlclxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRvIE1heCBvZiB0aGUgcmFuZG9tIG51bWJlciAobWF4IDMyYml0KVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBIHBzZXVkbyByYW5kb20gbnVtYmVyXG4gICAqL1xuICBnZXRQc2V1ZG9SYW5kb206IGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoTWF0aC5yYW5kb20oKSAqICh0byAtIGZyb20pKSArIGZyb207XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHVybiBhIHNlY3VyZSByYW5kb20gbnVtYmVyIGluIHRoZSBzcGVjaWZpZWQgcmFuZ2VcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBmcm9tIE1pbiBvZiB0aGUgcmFuZG9tIG51bWJlclxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRvIE1heCBvZiB0aGUgcmFuZG9tIG51bWJlciAobWF4IDMyYml0KVxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBIHNlY3VyZSByYW5kb20gbnVtYmVyXG4gICAqL1xuICBnZXRTZWN1cmVSYW5kb206IGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBVaW50MzJBcnJheSgxKTtcbiAgICB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpO1xuICAgIHZhciBiaXRzID0gKCh0byAtIGZyb20pKS50b1N0cmluZygyKS5sZW5ndGg7XG4gICAgd2hpbGUgKChidWZbMF0gJiAoTWF0aC5wb3coMiwgYml0cykgLSAxKSkgPiAodG8gLSBmcm9tKSlcbiAgICAgIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGJ1Zik7XG4gICAgcmV0dXJuIGZyb20gKyAoTWF0aC5hYnMoYnVmWzBdICYgKE1hdGgucG93KDIsIGJpdHMpIC0gMSkpKTtcbiAgfSxcblxuICBnZXRTZWN1cmVSYW5kb21PY3RldDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ1ZiA9IG5ldyBVaW50MzJBcnJheSgxKTtcbiAgICB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhidWYpO1xuICAgIHJldHVybiBidWZbMF0gJiAweEZGO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBzZWN1cmUgcmFuZG9tIGJpZyBpbnRlZ2VyIG9mIGJpdHMgbGVuZ3RoXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYml0cyBCaXQgbGVuZ3RoIG9mIHRoZSBNUEkgdG8gY3JlYXRlXG4gICAqIEByZXR1cm4ge0JpZ0ludGVnZXJ9IFJlc3VsdGluZyBiaWcgaW50ZWdlclxuICAgKi9cbiAgZ2V0UmFuZG9tQmlnSW50ZWdlcjogZnVuY3Rpb24oYml0cykge1xuICAgIGlmIChiaXRzIDwgMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHZhciBudW1CeXRlcyA9IE1hdGguZmxvb3IoKGJpdHMgKyA3KSAvIDgpO1xuXG4gICAgdmFyIHJhbmRvbUJpdHMgPSB0aGlzLmdldFJhbmRvbUJ5dGVzKG51bUJ5dGVzKTtcbiAgICBpZiAoYml0cyAlIDggPiAwKSB7XG5cbiAgICAgIHJhbmRvbUJpdHMgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuICAgICAgKE1hdGgucG93KDIsIGJpdHMgJSA4KSAtIDEpICZcbiAgICAgICAgcmFuZG9tQml0cy5jaGFyQ29kZUF0KDApKSArXG4gICAgICAgIHJhbmRvbUJpdHMuc3Vic3RyaW5nKDEpO1xuICAgIH1cbiAgICB2YXIgbXBpID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgbXBpLmZyb21CeXRlcyhyYW5kb21CaXRzKTtcbiAgICByZXR1cm4gbXBpLnRvQmlnSW50ZWdlcigpO1xuICB9LFxuXG4gIGdldFJhbmRvbUJpZ0ludGVnZXJJblJhbmdlOiBmdW5jdGlvbihtaW4sIG1heCkge1xuICAgIGlmIChtYXguY29tcGFyZVRvKG1pbikgPD0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciByYW5nZSA9IG1heC5zdWJ0cmFjdChtaW4pO1xuICAgIHZhciByID0gdGhpcy5nZXRSYW5kb21CaWdJbnRlZ2VyKHJhbmdlLmJpdExlbmd0aCgpKTtcbiAgICB3aGlsZSAociA+IHJhbmdlKSB7XG4gICAgICByID0gdGhpcy5nZXRSYW5kb21CaWdJbnRlZ2VyKHJhbmdlLmJpdExlbmd0aCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIG1pbi5hZGQocik7XG4gIH1cblxufTtcbiIsInZhciBwdWJsaWNLZXkgPSByZXF1aXJlKCcuL3B1YmxpY19rZXknKSxcbiAgcGtjczEgPSByZXF1aXJlKCcuL3BrY3MxLmpzJyksXG4gIGhhc2hNb2R1bGUgPSByZXF1aXJlKCcuL2hhc2gnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIC8qKlxuICAgKiBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBhbGdvIHB1YmxpYyBLZXkgYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaGFzaF9hbGdvIEhhc2ggYWxnb3JpdGhtXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBtc2dfTVBJcyBTaWduYXR1cmUgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnNcbiAgICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpW119IHB1YmxpY2tleV9NUElzIFB1YmxpYyBrZXkgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgb24gd2hlcmUgdGhlIHNpZ25hdHVyZSB3YXMgY29tcHV0ZWQgb24uXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgc2lnbmF0dXJlIChzaWdfZGF0YSB3YXMgZXF1YWwgdG8gZGF0YSBvdmVyIGhhc2gpXG4gICAqL1xuICB2ZXJpZnk6IGZ1bmN0aW9uKGFsZ28sIGhhc2hfYWxnbywgbXNnX01QSXMsIHB1YmxpY2tleV9NUElzLCBkYXRhKSB7XG4gICAgdmFyIGNhbGNfaGFzaCA9IGhhc2hNb2R1bGUuZGlnZXN0KGhhc2hfYWxnbywgZGF0YSk7XG5cbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgLy8gUlNBIChFbmNyeXB0IG9yIFNpZ24pIFtIQUNdICBcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gUlNBIEVuY3J5cHQtT25seSBbSEFDXVxuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyBSU0EgU2lnbi1Pbmx5IFtIQUNdXG4gICAgICAgIHZhciByc2EgPSBuZXcgcHVibGljS2V5LnJzYSgpO1xuICAgICAgICB2YXIgbiA9IHB1YmxpY2tleV9NUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgZSA9IHB1YmxpY2tleV9NUElzWzFdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgeCA9IG1zZ19NUElzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgZG9wdWJsaWMgPSByc2EudmVyaWZ5KHgsIGUsIG4pO1xuICAgICAgICB2YXIgaGFzaCA9IHBrY3MxLmVtc2EuZGVjb2RlKGhhc2hfYWxnbywgZG9wdWJsaWMudG9NUEkoKS5zdWJzdHJpbmcoMikpO1xuICAgICAgICBpZiAoaGFzaCA9PSAtMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUzEgcGFkZGluZyBpbiBtZXNzYWdlIG9yIGtleSBpbmNvcnJlY3QuIEFib3J0aW5nLi4uJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhhc2ggPT0gY2FsY19oYXNoO1xuXG4gICAgICBjYXNlIDE2OlxuICAgICAgICAvLyBFbGdhbWFsIChFbmNyeXB0LU9ubHkpIFtFTEdBTUFMXSBbSEFDXVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJzaWduaW5nIHdpdGggRWxnYW1hbCBpcyBub3QgZGVmaW5lZCBpbiB0aGUgT3BlblBHUCBzdGFuZGFyZC5cIik7XG4gICAgICBjYXNlIDE3OlxuICAgICAgICAvLyBEU0EgKERpZ2l0YWwgU2lnbmF0dXJlIEFsZ29yaXRobSkgW0ZJUFMxODZdIFtIQUNdXG4gICAgICAgIHZhciBkc2EgPSBuZXcgcHVibGljS2V5LmRzYSgpO1xuICAgICAgICB2YXIgczEgPSBtc2dfTVBJc1swXS50b0JpZ0ludGVnZXIoKTtcbiAgICAgICAgdmFyIHMyID0gbXNnX01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBwID0gcHVibGlja2V5X01QSXNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBxID0gcHVibGlja2V5X01QSXNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBnID0gcHVibGlja2V5X01QSXNbMl0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciB5ID0gcHVibGlja2V5X01QSXNbM10udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBtID0gZGF0YTtcbiAgICAgICAgdmFyIGRvcHVibGljID0gZHNhLnZlcmlmeShoYXNoX2FsZ28sIHMxLCBzMiwgbSwgcCwgcSwgZywgeSk7XG4gICAgICAgIHJldHVybiBkb3B1YmxpYy5jb21wYXJlVG8oczEpID09IDA7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2lnbmF0dXJlIGFsZ29yaXRobS4nKTtcbiAgICB9XG5cbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlIGEgc2lnbmF0dXJlIG9uIGRhdGEgdXNpbmcgdGhlIHNwZWNpZmllZCBhbGdvcml0aG1cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBoYXNoX2FsZ28gaGFzaCBBbGdvcml0aG0gdG8gdXNlIChTZWUgUkZDNDg4MCA5LjQpXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYWxnbyBBc3ltbWV0cmljIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlIChTZWUgUkZDNDg4MCA5LjEpXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBwdWJsaWNNUElzIFB1YmxpYyBrZXkgbXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgXG4gICAqIG9mIHRoZSBwcml2YXRlIGtleSBcbiAgICogQHBhcmFtIHtvcGVucGdwX3R5cGVfbXBpW119IHNlY3JldE1QSXMgUHJpdmF0ZSBrZXkgbXVsdGlwcmVjaXNpb24gXG4gICAqIGludGVnZXJzIHdoaWNoIGlzIHVzZWQgdG8gc2lnbiB0aGUgZGF0YVxuICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGJlIHNpZ25lZFxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3R5cGVfbXBpW119XG4gICAqL1xuICBzaWduOiBmdW5jdGlvbihoYXNoX2FsZ28sIGFsZ28sIGtleUludGVnZXJzLCBkYXRhKSB7XG5cbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgLy8gUlNBIChFbmNyeXB0IG9yIFNpZ24pIFtIQUNdICBcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gUlNBIEVuY3J5cHQtT25seSBbSEFDXVxuICAgICAgY2FzZSAzOlxuICAgICAgICAvLyBSU0EgU2lnbi1Pbmx5IFtIQUNdXG4gICAgICAgIHZhciByc2EgPSBuZXcgcHVibGljS2V5LnJzYSgpO1xuICAgICAgICB2YXIgZCA9IGtleUludGVnZXJzWzJdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgbiA9IGtleUludGVnZXJzWzBdLnRvQmlnSW50ZWdlcigpO1xuICAgICAgICB2YXIgbSA9IHBrY3MxLmVtc2EuZW5jb2RlKGhhc2hfYWxnbyxcbiAgICAgICAgICBkYXRhLCBrZXlJbnRlZ2Vyc1swXS5ieXRlTGVuZ3RoKCkpO1xuXG4gICAgICAgIHJldHVybiByc2Euc2lnbihtLCBkLCBuKS50b01QSSgpO1xuXG4gICAgICBjYXNlIDE3OlxuICAgICAgICAvLyBEU0EgKERpZ2l0YWwgU2lnbmF0dXJlIEFsZ29yaXRobSkgW0ZJUFMxODZdIFtIQUNdXG4gICAgICAgIHZhciBkc2EgPSBuZXcgcHVibGljS2V5LmRzYSgpO1xuXG4gICAgICAgIHZhciBwID0ga2V5SW50ZWdlcnNbMF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBxID0ga2V5SW50ZWdlcnNbMV0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBnID0ga2V5SW50ZWdlcnNbMl0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciB5ID0ga2V5SW50ZWdlcnNbM10udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciB4ID0ga2V5SW50ZWdlcnNbNF0udG9CaWdJbnRlZ2VyKCk7XG4gICAgICAgIHZhciBtID0gZGF0YTtcbiAgICAgICAgdmFyIHJlc3VsdCA9IGRzYS5zaWduKGhhc2hfYWxnbywgbSwgZywgcCwgcSwgeCk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdFswXS50b1N0cmluZygpICsgcmVzdWx0WzFdLnRvU3RyaW5nKCk7XG4gICAgICBjYXNlIDE2OlxuICAgICAgICAvLyBFbGdhbWFsIChFbmNyeXB0LU9ubHkpIFtFTEdBTUFMXSBbSEFDXVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NpZ25pbmcgd2l0aCBFbGdhbWFsIGlzIG5vdCBkZWZpbmVkIGluIHRoZSBPcGVuUEdQIHN0YW5kYXJkLicpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25hdHVyZSBhbGdvcml0aG0uJyk7XG4gICAgfVxuICB9XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy9cbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy9cbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnLi9iYXNlNjQuanMnKTtcblxuXG5cbi8qKlxuICogRmluZHMgb3V0IHdoaWNoIEFzY2lpIEFybW9yaW5nIHR5cGUgaXMgdXNlZC4gVGhpcyBpcyBhbiBpbnRlcm5hbCBmdW5jdGlvblxuICogQHBhcmFtIHtTdHJpbmd9IHRleHQgW1N0cmluZ10gYXNjaWkgYXJtb3JlZCB0ZXh0XG4gKiBAcmV0dXJucyB7SW50ZWdlcn0gMCA9IE1FU1NBR0UgUEFSVCBuIG9mIG1cbiAqICAgICAgICAgMSA9IE1FU1NBR0UgUEFSVCBuXG4gKiAgICAgICAgIDIgPSBTSUdORUQgTUVTU0FHRVxuICogICAgICAgICAzID0gUEdQIE1FU1NBR0VcbiAqICAgICAgICAgNCA9IFBVQkxJQyBLRVkgQkxPQ0tcbiAqICAgICAgICAgNSA9IFBSSVZBVEUgS0VZIEJMT0NLXG4gKiAgICAgICAgIG51bGwgPSB1bmtub3duXG4gKi9cbmZ1bmN0aW9uIGdldF90eXBlKHRleHQpIHtcbiAgdmFyIHNwbGl0dGVkdGV4dCA9IHRleHQuc3BsaXQoJy0tLS0tJyk7XG4gIC8vIEJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFgvWVxuICAvLyBVc2VkIGZvciBtdWx0aS1wYXJ0IG1lc3NhZ2VzLCB3aGVyZSB0aGUgYXJtb3IgaXMgc3BsaXQgYW1vbmdzdCBZXG4gIC8vIHBhcnRzLCBhbmQgdGhpcyBpcyB0aGUgWHRoIHBhcnQgb3V0IG9mIFkuXG4gIGlmIChzcGxpdHRlZHRleHRbMV0ubWF0Y2goL0JFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFxcZCtcXC9cXGQrLykpIHtcbiAgICByZXR1cm4gMDtcbiAgfSBlbHNlXG4gIC8vIEJFR0lOIFBHUCBNRVNTQUdFLCBQQVJUIFhcbiAgLy8gVXNlZCBmb3IgbXVsdGktcGFydCBtZXNzYWdlcywgd2hlcmUgdGhpcyBpcyB0aGUgWHRoIHBhcnQgb2YgYW5cbiAgLy8gdW5zcGVjaWZpZWQgbnVtYmVyIG9mIHBhcnRzLiBSZXF1aXJlcyB0aGUgTUVTU0FHRS1JRCBBcm1vclxuICAvLyBIZWFkZXIgdG8gYmUgdXNlZC5cbiAgaWYgKHNwbGl0dGVkdGV4dFsxXS5tYXRjaCgvQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgXFxkKy8pKSB7XG4gICAgcmV0dXJuIDE7XG5cbiAgfSBlbHNlXG4gIC8vIEJFR0lOIFBHUCBTSUdOQVRVUkVcbiAgLy8gVXNlZCBmb3IgZGV0YWNoZWQgc2lnbmF0dXJlcywgT3BlblBHUC9NSU1FIHNpZ25hdHVyZXMsIGFuZFxuICAvLyBjbGVhcnRleHQgc2lnbmF0dXJlcy4gTm90ZSB0aGF0IFBHUCAyLnggdXNlcyBCRUdJTiBQR1AgTUVTU0FHRVxuICAvLyBmb3IgZGV0YWNoZWQgc2lnbmF0dXJlcy5cbiAgaWYgKHNwbGl0dGVkdGV4dFsxXS5tYXRjaCgvQkVHSU4gUEdQIFNJR05FRCBNRVNTQUdFLykpIHtcbiAgICByZXR1cm4gMjtcblxuICB9IGVsc2VcbiAgLy8gQkVHSU4gUEdQIE1FU1NBR0VcbiAgLy8gVXNlZCBmb3Igc2lnbmVkLCBlbmNyeXB0ZWQsIG9yIGNvbXByZXNzZWQgZmlsZXMuXG4gIGlmIChzcGxpdHRlZHRleHRbMV0ubWF0Y2goL0JFR0lOIFBHUCBNRVNTQUdFLykpIHtcbiAgICByZXR1cm4gMztcblxuICB9IGVsc2VcbiAgLy8gQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0tcbiAgLy8gVXNlZCBmb3IgYXJtb3JpbmcgcHVibGljIGtleXMuXG4gIGlmIChzcGxpdHRlZHRleHRbMV0ubWF0Y2goL0JFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLykpIHtcbiAgICByZXR1cm4gNDtcblxuICB9IGVsc2VcbiAgLy8gQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLXG4gIC8vIFVzZWQgZm9yIGFybW9yaW5nIHByaXZhdGUga2V5cy5cbiAgaWYgKHNwbGl0dGVkdGV4dFsxXS5tYXRjaCgvQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLykpIHtcbiAgICByZXR1cm4gNTtcbiAgfVxufVxuXG4vKipcbiAqIEFkZCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRvIHRoZSBhcm1vciB2ZXJzaW9uIG9mIGFuIE9wZW5QR1AgYmluYXJ5XG4gKiBwYWNrZXQgYmxvY2suXG4gKiBAYXV0aG9yICBBbGV4XG4gKiBAdmVyc2lvbiAyMDExLTEyLTE2XG4gKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgaGVhZGVyIGluZm9ybWF0aW9uXG4gKi9cbmZ1bmN0aW9uIGFybW9yX2FkZGhlYWRlcigpIHtcbiAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gIGlmIChvcGVucGdwLmNvbmZpZy5jb25maWcuc2hvd192ZXJzaW9uKSB7XG4gICAgcmVzdWx0ICs9IFwiVmVyc2lvbjogXCIgKyBvcGVucGdwLmNvbmZpZy52ZXJzaW9uc3RyaW5nICsgJ1xcclxcbic7XG4gIH1cbiAgaWYgKG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5zaG93X2NvbW1lbnQpIHtcbiAgICByZXN1bHQgKz0gXCJDb21tZW50OiBcIiArIG9wZW5wZ3AuY29uZmlnLmNvbW1lbnRzdHJpbmcgKyAnXFxyXFxuJztcbiAgfVxuICByZXN1bHQgKz0gJ1xcclxcbic7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuXG4vKipcbiAqIENhbGN1bGF0ZXMgYSBjaGVja3N1bSBvdmVyIHRoZSBnaXZlbiBkYXRhIGFuZCByZXR1cm5zIGl0IGJhc2U2NCBlbmNvZGVkXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBEYXRhIHRvIGNyZWF0ZSBhIENSQy0yNCBjaGVja3N1bSBmb3JcbiAqIEByZXR1cm4ge1N0cmluZ30gQmFzZTY0IGVuY29kZWQgY2hlY2tzdW1cbiAqL1xuZnVuY3Rpb24gZ2V0Q2hlY2tTdW0oZGF0YSkge1xuICB2YXIgYyA9IGNyZWF0ZWNyYzI0KGRhdGEpO1xuICB2YXIgc3RyID0gXCJcIiArIFN0cmluZy5mcm9tQ2hhckNvZGUoYyA+PiAxNikgK1xuICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoKGMgPj4gOCkgJiAweEZGKSArXG4gICAgU3RyaW5nLmZyb21DaGFyQ29kZShjICYgMHhGRik7XG4gIHJldHVybiBiYXNlNjQuZW5jb2RlKHN0cik7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgY2hlY2tzdW0gb3ZlciB0aGUgZ2l2ZW4gZGF0YSBhbmQgY29tcGFyZXMgaXQgd2l0aCB0aGUgXG4gKiBnaXZlbiBiYXNlNjQgZW5jb2RlZCBjaGVja3N1bVxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBjcmVhdGUgYSBDUkMtMjQgY2hlY2tzdW0gZm9yXG4gKiBAcGFyYW0ge1N0cmluZ30gY2hlY2tzdW0gQmFzZTY0IGVuY29kZWQgY2hlY2tzdW1cbiAqIEByZXR1cm4ge0Jvb2xlYW59IFRydWUgaWYgdGhlIGdpdmVuIGNoZWNrc3VtIGlzIGNvcnJlY3Q7IG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiB2ZXJpZnlDaGVja1N1bShkYXRhLCBjaGVja3N1bSkge1xuICB2YXIgYyA9IGdldENoZWNrU3VtKGRhdGEpO1xuICB2YXIgZCA9IGNoZWNrc3VtO1xuICByZXR1cm4gY1swXSA9PSBkWzBdICYmIGNbMV0gPT0gZFsxXSAmJiBjWzJdID09IGRbMl07XG59XG4vKipcbiAqIEludGVybmFsIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBhIENSQy0yNCBjaGVja3N1bSBvdmVyIGEgZ2l2ZW4gc3RyaW5nIChkYXRhKVxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgRGF0YSB0byBjcmVhdGUgYSBDUkMtMjQgY2hlY2tzdW0gZm9yXG4gKiBAcmV0dXJuIHtJbnRlZ2VyfSBUaGUgQ1JDLTI0IGNoZWNrc3VtIGFzIG51bWJlclxuICovXG52YXIgY3JjX3RhYmxlID0gW1xuICAgIDB4MDAwMDAwMDAsIDB4MDA4NjRjZmIsIDB4MDE4YWQ1MGQsIDB4MDEwYzk5ZjYsIDB4MDM5M2U2ZTEsIDB4MDMxNWFhMWEsIDB4MDIxOTMzZWMsIDB4MDI5ZjdmMTcsIDB4MDdhMTgxMzksXG4gICAgMHgwNzI3Y2RjMiwgMHgwNjJiNTQzNCwgMHgwNmFkMThjZiwgMHgwNDMyNjdkOCwgMHgwNGI0MmIyMywgMHgwNWI4YjJkNSwgMHgwNTNlZmUyZSwgMHgwZmM1NGU4OSwgMHgwZjQzMDI3MixcbiAgICAweDBlNGY5Yjg0LCAweDBlYzlkNzdmLCAweDBjNTZhODY4LCAweDBjZDBlNDkzLCAweDBkZGM3ZDY1LCAweDBkNWEzMTllLCAweDA4NjRjZmIwLCAweDA4ZTI4MzRiLCAweDA5ZWUxYWJkLFxuICAgIDB4MDk2ODU2NDYsIDB4MGJmNzI5NTEsIDB4MGI3MTY1YWEsIDB4MGE3ZGZjNWMsIDB4MGFmYmIwYTcsIDB4MWYwY2QxZTksIDB4MWY4YTlkMTIsIDB4MWU4NjA0ZTQsIDB4MWUwMDQ4MWYsXG4gICAgMHgxYzlmMzcwOCwgMHgxYzE5N2JmMywgMHgxZDE1ZTIwNSwgMHgxZDkzYWVmZSwgMHgxOGFkNTBkMCwgMHgxODJiMWMyYiwgMHgxOTI3ODVkZCwgMHgxOWExYzkyNiwgMHgxYjNlYjYzMSxcbiAgICAweDFiYjhmYWNhLCAweDFhYjQ2MzNjLCAweDFhMzIyZmM3LCAweDEwYzk5ZjYwLCAweDEwNGZkMzliLCAweDExNDM0YTZkLCAweDExYzUwNjk2LCAweDEzNWE3OTgxLCAweDEzZGMzNTdhLFxuICAgIDB4MTJkMGFjOGMsIDB4MTI1NmUwNzcsIDB4MTc2ODFlNTksIDB4MTdlZTUyYTIsIDB4MTZlMmNiNTQsIDB4MTY2NDg3YWYsIDB4MTRmYmY4YjgsIDB4MTQ3ZGI0NDMsIDB4MTU3MTJkYjUsXG4gICAgMHgxNWY3NjE0ZSwgMHgzZTE5YTNkMiwgMHgzZTlmZWYyOSwgMHgzZjkzNzZkZiwgMHgzZjE1M2EyNCwgMHgzZDhhNDUzMywgMHgzZDBjMDljOCwgMHgzYzAwOTAzZSwgMHgzYzg2ZGNjNSxcbiAgICAweDM5YjgyMmViLCAweDM5M2U2ZTEwLCAweDM4MzJmN2U2LCAweDM4YjRiYjFkLCAweDNhMmJjNDBhLCAweDNhYWQ4OGYxLCAweDNiYTExMTA3LCAweDNiMjc1ZGZjLCAweDMxZGNlZDViLFxuICAgIDB4MzE1YWExYTAsXG4gICAgMHgzMDU2Mzg1NiwgMHgzMGQwNzRhZCwgMHgzMjRmMGJiYSwgMHgzMmM5NDc0MSwgMHgzM2M1ZGViNywgMHgzMzQzOTI0YywgMHgzNjdkNmM2MiwgMHgzNmZiMjA5OSwgMHgzN2Y3Yjk2ZixcbiAgICAweDM3NzFmNTk0LCAweDM1ZWU4YTgzLCAweDM1NjhjNjc4LCAweDM0NjQ1ZjhlLCAweDM0ZTIxMzc1LCAweDIxMTU3MjNiLCAweDIxOTMzZWMwLCAweDIwOWZhNzM2LCAweDIwMTllYmNkLFxuICAgIDB4MjI4Njk0ZGEsIDB4MjIwMGQ4MjEsIDB4MjMwYzQxZDcsIDB4MjM4YTBkMmMsIDB4MjZiNGYzMDIsIDB4MjYzMmJmZjksIDB4MjczZTI2MGYsIDB4MjdiODZhZjQsIDB4MjUyNzE1ZTMsXG4gICAgMHgyNWExNTkxOCwgMHgyNGFkYzBlZSwgMHgyNDJiOGMxNSwgMHgyZWQwM2NiMiwgMHgyZTU2NzA0OSwgMHgyZjVhZTliZiwgMHgyZmRjYTU0NCwgMHgyZDQzZGE1MywgMHgyZGM1OTZhOCxcbiAgICAweDJjYzkwZjVlLCAweDJjNGY0M2E1LCAweDI5NzFiZDhiLCAweDI5ZjdmMTcwLCAweDI4ZmI2ODg2LCAweDI4N2QyNDdkLCAweDJhZTI1YjZhLCAweDJhNjQxNzkxLCAweDJiNjg4ZTY3LFxuICAgIDB4MmJlZWMyOWMsIDB4N2MzMzQ3YTQsIDB4N2NiNTBiNWYsIDB4N2RiOTkyYTksIDB4N2QzZmRlNTIsIDB4N2ZhMGExNDUsIDB4N2YyNmVkYmUsIDB4N2UyYTc0NDgsIDB4N2VhYzM4YjMsXG4gICAgMHg3YjkyYzY5ZCwgMHg3YjE0OGE2NiwgMHg3YTE4MTM5MCwgMHg3YTllNWY2YiwgMHg3ODAxMjA3YywgMHg3ODg3NmM4NywgMHg3OThiZjU3MSwgMHg3OTBkYjk4YSwgMHg3M2Y2MDkyZCxcbiAgICAweDczNzA0NWQ2LCAweDcyN2NkYzIwLCAweDcyZmE5MGRiLCAweDcwNjVlZmNjLCAweDcwZTNhMzM3LCAweDcxZWYzYWMxLCAweDcxNjk3NjNhLCAweDc0NTc4ODE0LCAweDc0ZDFjNGVmLFxuICAgIDB4NzVkZDVkMTksIDB4NzU1YjExZTIsIDB4NzdjNDZlZjUsIDB4Nzc0MjIyMGUsIDB4NzY0ZWJiZjgsIDB4NzZjOGY3MDMsIDB4NjMzZjk2NGQsIDB4NjNiOWRhYjYsIDB4NjJiNTQzNDAsXG4gICAgMHg2MjMzMGZiYixcbiAgICAweDYwYWM3MGFjLCAweDYwMmEzYzU3LCAweDYxMjZhNWExLCAweDYxYTBlOTVhLCAweDY0OWUxNzc0LCAweDY0MTg1YjhmLCAweDY1MTRjMjc5LCAweDY1OTI4ZTgyLCAweDY3MGRmMTk1LFxuICAgIDB4Njc4YmJkNmUsIDB4NjY4NzI0OTgsIDB4NjYwMTY4NjMsIDB4NmNmYWQ4YzQsIDB4NmM3Yzk0M2YsIDB4NmQ3MDBkYzksIDB4NmRmNjQxMzIsIDB4NmY2OTNlMjUsIDB4NmZlZjcyZGUsXG4gICAgMHg2ZWUzZWIyOCwgMHg2ZTY1YTdkMywgMHg2YjViNTlmZCwgMHg2YmRkMTUwNiwgMHg2YWQxOGNmMCwgMHg2YTU3YzAwYiwgMHg2OGM4YmYxYywgMHg2ODRlZjNlNywgMHg2OTQyNmExMSxcbiAgICAweDY5YzQyNmVhLCAweDQyMmFlNDc2LCAweDQyYWNhODhkLCAweDQzYTAzMTdiLCAweDQzMjY3ZDgwLCAweDQxYjkwMjk3LCAweDQxM2Y0ZTZjLCAweDQwMzNkNzlhLCAweDQwYjU5YjYxLFxuICAgIDB4NDU4YjY1NGYsIDB4NDUwZDI5YjQsIDB4NDQwMWIwNDIsIDB4NDQ4N2ZjYjksIDB4NDYxODgzYWUsIDB4NDY5ZWNmNTUsIDB4NDc5MjU2YTMsIDB4NDcxNDFhNTgsIDB4NGRlZmFhZmYsXG4gICAgMHg0ZDY5ZTYwNCwgMHg0YzY1N2ZmMiwgMHg0Y2UzMzMwOSwgMHg0ZTdjNGMxZSwgMHg0ZWZhMDBlNSwgMHg0ZmY2OTkxMywgMHg0ZjcwZDVlOCwgMHg0YTRlMmJjNiwgMHg0YWM4NjczZCxcbiAgICAweDRiYzRmZWNiLCAweDRiNDJiMjMwLCAweDQ5ZGRjZDI3LCAweDQ5NWI4MWRjLCAweDQ4NTcxODJhLCAweDQ4ZDE1NGQxLCAweDVkMjYzNTlmLCAweDVkYTA3OTY0LCAweDVjYWNlMDkyLFxuICAgIDB4NWMyYWFjNjksIDB4NWViNWQzN2UsIDB4NWUzMzlmODUsIDB4NWYzZjA2NzMsIDB4NWZiOTRhODgsIDB4NWE4N2I0YTYsIDB4NWEwMWY4NWQsIDB4NWIwZDYxYWIsIDB4NWI4YjJkNTAsXG4gICAgMHg1OTE0NTI0NywgMHg1OTkyMWViYywgMHg1ODllODc0YSwgMHg1ODE4Y2JiMSwgMHg1MmUzN2IxNiwgMHg1MjY1MzdlZCwgMHg1MzY5YWUxYiwgMHg1M2VmZTJlMCwgMHg1MTcwOWRmNyxcbiAgICAweDUxZjZkMTBjLFxuICAgIDB4NTBmYTQ4ZmEsIDB4NTA3YzA0MDEsIDB4NTU0MmZhMmYsIDB4NTVjNGI2ZDQsIDB4NTRjODJmMjIsIDB4NTQ0ZTYzZDksIDB4NTZkMTFjY2UsIDB4NTY1NzUwMzUsIDB4NTc1YmM5YzMsXG4gICAgMHg1N2RkODUzOFxuXTtcblxuZnVuY3Rpb24gY3JlYXRlY3JjMjQoaW5wdXQpIHtcbiAgdmFyIGNyYyA9IDB4QjcwNENFO1xuICB2YXIgaW5kZXggPSAwO1xuXG4gIHdoaWxlICgoaW5wdXQubGVuZ3RoIC0gaW5kZXgpID4gMTYpIHtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDEpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDIpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDMpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDQpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDUpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDYpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDcpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDgpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDkpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDEwKSkgJiAweGZmXTtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXggKyAxMSkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMTIpKSAmIDB4ZmZdO1xuICAgIGNyYyA9IChjcmMgPDwgOCkgXiBjcmNfdGFibGVbKChjcmMgPj4gMTYpIF4gaW5wdXQuY2hhckNvZGVBdChpbmRleCArIDEzKSkgJiAweGZmXTtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXggKyAxNCkpICYgMHhmZl07XG4gICAgY3JjID0gKGNyYyA8PCA4KSBeIGNyY190YWJsZVsoKGNyYyA+PiAxNikgXiBpbnB1dC5jaGFyQ29kZUF0KGluZGV4ICsgMTUpKSAmIDB4ZmZdO1xuICAgIGluZGV4ICs9IDE2O1xuICB9XG5cbiAgZm9yICh2YXIgaiA9IGluZGV4OyBqIDwgaW5wdXQubGVuZ3RoOyBqKyspIHtcbiAgICBjcmMgPSAoY3JjIDw8IDgpIF4gY3JjX3RhYmxlWygoY3JjID4+IDE2KSBeIGlucHV0LmNoYXJDb2RlQXQoaW5kZXgrKykpICYgMHhmZl1cbiAgfVxuICByZXR1cm4gY3JjICYgMHhmZmZmZmY7XG59XG5cbi8qKlxuICogRGVBcm1vciBhbiBPcGVuUEdQIGFybW9yZWQgbWVzc2FnZTsgdmVyaWZ5IHRoZSBjaGVja3N1bSBhbmQgcmV0dXJuIFxuICogdGhlIGVuY29kZWQgYnl0ZXNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IE9wZW5QR1AgYXJtb3JlZCBtZXNzYWdlXG4gKiBAcmV0dXJucyB7KEJvb2xlYW58T2JqZWN0KX0gRWl0aGVyIGZhbHNlIGluIGNhc2Ugb2YgYW4gZXJyb3IgXG4gKiBvciBhbiBvYmplY3Qgd2l0aCBhdHRyaWJ1dGUgXCJ0ZXh0XCIgY29udGFpbmluZyB0aGUgbWVzc2FnZSB0ZXh0XG4gKiBhbmQgYW4gYXR0cmlidXRlIFwib3BlbnBncFwiIGNvbnRhaW5pbmcgdGhlIGJ5dGVzLlxuICovXG5mdW5jdGlvbiBkZWFybW9yKHRleHQpIHtcbiAgdGV4dCA9IHRleHQucmVwbGFjZSgvXFxyL2csICcnKVxuXG4gIHZhciB0eXBlID0gZ2V0X3R5cGUodGV4dCk7XG5cbiAgaWYgKHR5cGUgIT0gMikge1xuICAgIHZhciBzcGxpdHRlZHRleHQgPSB0ZXh0LnNwbGl0KCctLS0tLScpO1xuXG4gICAgdmFyIGRhdGEgPSB7XG4gICAgICBvcGVucGdwOiBiYXNlNjQuZGVjb2RlKFxuICAgICAgICBzcGxpdHRlZHRleHRbMl1cbiAgICAgICAgLnNwbGl0KCdcXG5cXG4nKVsxXVxuICAgICAgICAuc3BsaXQoXCJcXG49XCIpWzBdXG4gICAgICAgIC5yZXBsYWNlKC9cXG4tIC9nLCBcIlxcblwiKSksXG4gICAgICB0eXBlOiB0eXBlXG4gICAgfTtcblxuICAgIGlmICh2ZXJpZnlDaGVja1N1bShkYXRhLm9wZW5wZ3AsXG4gICAgICBzcGxpdHRlZHRleHRbMl1cbiAgICAgIC5zcGxpdCgnXFxuXFxuJylbMV1cbiAgICAgIC5zcGxpdChcIlxcbj1cIilbMV1cbiAgICAgIC5zcGxpdCgnXFxuJylbMF0pKVxuXG4gICAgICByZXR1cm4gZGF0YTtcbiAgICBlbHNlIHtcbiAgICAgIHV0aWwucHJpbnRfZXJyb3IoXCJBc2NpaSBhcm1vciBpbnRlZ3JpdHkgY2hlY2sgb24gbWVzc2FnZSBmYWlsZWQ6ICdcIiArIHNwbGl0dGVkdGV4dFsyXVxuICAgICAgICAuc3BsaXQoJ1xcblxcbicpWzFdXG4gICAgICAgIC5zcGxpdChcIlxcbj1cIilbMV1cbiAgICAgICAgLnNwbGl0KCdcXG4nKVswXSArIFwiJyBzaG91bGQgYmUgJ1wiICsgZ2V0Q2hlY2tTdW0oZGF0YSkpICsgXCInXCI7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhciBzcGxpdHRlZHRleHQgPSB0ZXh0LnNwbGl0KCctLS0tLScpO1xuXG4gICAgdmFyIHJlc3VsdCA9IHtcbiAgICAgIHRleHQ6IHNwbGl0dGVkdGV4dFsyXVxuICAgICAgICAucmVwbGFjZSgvXFxuLSAvZywgXCJcXG5cIilcbiAgICAgICAgLnNwbGl0KFwiXFxuXFxuXCIpWzFdLFxuICAgICAgb3BlbnBncDogYmFzZTY0X2RlY29kZShzcGxpdHRlZHRleHRbNF1cbiAgICAgICAgLnNwbGl0KFwiXFxuXFxuXCIpWzFdXG4gICAgICAgIC5zcGxpdChcIlxcbj1cIilbMF0pLFxuICAgICAgdHlwZTogdHlwZVxuICAgIH07XG5cbiAgICBpZiAodmVyaWZ5Q2hlY2tTdW0ocmVzdWx0Lm9wZW5wZ3AsIHNwbGl0dGVkdGV4dFs0XVxuICAgICAgLnNwbGl0KFwiXFxuXFxuXCIpWzFdXG4gICAgICAuc3BsaXQoXCJcXG49XCIpWzFdKSlcblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICBlbHNlIHtcbiAgICAgIHV0aWwucHJpbnRfZXJyb3IoXCJBc2NpaSBhcm1vciBpbnRlZ3JpdHkgY2hlY2sgb24gbWVzc2FnZSBmYWlsZWRcIik7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59XG5cblxuLyoqXG4gKiBBcm1vciBhbiBPcGVuUEdQIGJpbmFyeSBwYWNrZXQgYmxvY2tcbiAqIEBwYXJhbSB7SW50ZWdlcn0gbWVzc2FnZXR5cGUgdHlwZSBvZiB0aGUgbWVzc2FnZVxuICogQHBhcmFtIGRhdGFcbiAqIEBwYXJhbSB7SW50ZWdlcn0gcGFydGluZGV4XG4gKiBAcGFyYW0ge0ludGVnZXJ9IHBhcnR0b3RhbFxuICogQHJldHVybnMge1N0cmluZ30gQXJtb3JlZCB0ZXh0XG4gKi9cbmZ1bmN0aW9uIGFybW9yKG1lc3NhZ2V0eXBlLCBkYXRhLCBwYXJ0aW5kZXgsIHBhcnR0b3RhbCkge1xuICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgc3dpdGNoIChtZXNzYWdldHlwZSkge1xuICAgIGNhc2UgMDpcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgXCIgKyBwYXJ0aW5kZXggKyBcIi9cIiArIHBhcnR0b3RhbCArIFwiLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhcm1vcl9hZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGRhdGEpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oZGF0YSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIE1FU1NBR0UsIFBBUlQgXCIgKyBwYXJ0aW5kZXggKyBcIi9cIiArIHBhcnR0b3RhbCArIFwiLS0tLS1cXHJcXG5cIjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMTpcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UsIFBBUlQgXCIgKyBwYXJ0aW5kZXggKyBcIi0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG4gICAgICByZXN1bHQgKz0gYmFzZTY0LmVuY29kZShkYXRhKTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbj1cIiArIGdldENoZWNrU3VtKGRhdGEpICsgXCJcXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tRU5EIFBHUCBNRVNTQUdFLCBQQVJUIFwiICsgcGFydGluZGV4ICsgXCItLS0tLVxcclxcblwiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAyOlxuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuLS0tLS1CRUdJTiBQR1AgU0lHTkVEIE1FU1NBR0UtLS0tLVxcclxcbkhhc2g6IFwiICsgZGF0YS5oYXNoICsgXCJcXHJcXG5cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBkYXRhLnRleHQucmVwbGFjZSgvXFxuLS9nLCBcIlxcbi0gLVwiKTtcbiAgICAgIHJlc3VsdCArPSBcIlxcclxcbi0tLS0tQkVHSU4gUEdQIFNJR05BVFVSRS0tLS0tXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gYXJtb3JfYWRkaGVhZGVyKCk7XG4gICAgICByZXN1bHQgKz0gYmFzZTY0LmVuY29kZShkYXRhLm9wZW5wZ3ApO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oZGF0YS5vcGVucGdwKSArIFwiXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUVORCBQR1AgU0lHTkFUVVJFLS0tLS1cXHJcXG5cIjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMzpcbiAgICAgIHJlc3VsdCArPSBcIi0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IGFybW9yX2FkZGhlYWRlcigpO1xuICAgICAgcmVzdWx0ICs9IGJhc2U2NC5lbmNvZGUoZGF0YSk7XG4gICAgICByZXN1bHQgKz0gXCJcXHJcXG49XCIgKyBnZXRDaGVja1N1bShkYXRhKSArIFwiXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxyXFxuXCI7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDQ6XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXHJcXG5cIjtcbiAgICAgIHJlc3VsdCArPSBhcm1vcl9hZGRoZWFkZXIoKTtcbiAgICAgIHJlc3VsdCArPSBiYXNlNjQuZW5jb2RlKGRhdGEpO1xuICAgICAgcmVzdWx0ICs9IFwiXFxyXFxuPVwiICsgZ2V0Q2hlY2tTdW0oZGF0YSkgKyBcIlxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcclxcblxcclxcblwiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA1OlxuICAgICAgcmVzdWx0ICs9IFwiLS0tLS1CRUdJTiBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLVxcclxcblwiO1xuICAgICAgcmVzdWx0ICs9IGFybW9yX2FkZGhlYWRlcigpO1xuICAgICAgcmVzdWx0ICs9IGJhc2U2NC5lbmNvZGUoZGF0YSk7XG4gICAgICByZXN1bHQgKz0gXCJcXHJcXG49XCIgKyBnZXRDaGVja1N1bShkYXRhKSArIFwiXFxyXFxuXCI7XG4gICAgICByZXN1bHQgKz0gXCItLS0tLUVORCBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLVxcclxcblwiO1xuICAgICAgYnJlYWs7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZW5jb2RlOiBhcm1vcixcbiAgZGVjb2RlOiBkZWFybW9yXG59XG4iLCIvKiBPcGVuUEdQIHJhZGl4LTY0L2Jhc2U2NCBzdHJpbmcgZW5jb2RpbmcvZGVjb2RpbmdcbiAqIENvcHlyaWdodCAyMDA1IEhlcmJlcnQgSGFuZXdpbmtlbCwgd3d3LmhhbmVXSU4uZGVcbiAqIHZlcnNpb24gMS4wLCBjaGVjayB3d3cuaGFuZVdJTi5kZSBmb3IgdGhlIGxhdGVzdCB2ZXJzaW9uXG4gKlxuICogVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCBhcy1pcywgd2l0aG91dCBleHByZXNzIG9yIGltcGxpZWQgd2FycmFudHkuICBcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUgb3Igc2VsbCB0aGlzIHNvZnR3YXJlLCB3aXRoIG9yXG4gKiB3aXRob3V0IGZlZSwgZm9yIGFueSBwdXJwb3NlIGFuZCBieSBhbnkgaW5kaXZpZHVhbCBvciBvcmdhbml6YXRpb24sIGlzIGhlcmVieVxuICogZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwYXJhZ3JhcGggYXBwZWFyIFxuICogaW4gYWxsIGNvcGllcy4gRGlzdHJpYnV0aW9uIGFzIGEgcGFydCBvZiBhbiBhcHBsaWNhdGlvbiBvciBiaW5hcnkgbXVzdFxuICogaW5jbHVkZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzXG4gKiBwcm92aWRlZCB3aXRoIHRoZSBhcHBsaWNhdGlvbiBvciBkaXN0cmlidXRpb24uXG4gKi9cblxudmFyIGI2NHMgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7XG5cbmZ1bmN0aW9uIHMycih0KSB7XG4gIHZhciBhLCBjLCBuO1xuICB2YXIgciA9ICcnLFxuICAgIGwgPSAwLFxuICAgIHMgPSAwO1xuICB2YXIgdGwgPSB0Lmxlbmd0aDtcblxuICBmb3IgKG4gPSAwOyBuIDwgdGw7IG4rKykge1xuICAgIGMgPSB0LmNoYXJDb2RlQXQobik7XG4gICAgaWYgKHMgPT0gMCkge1xuICAgICAgciArPSBiNjRzLmNoYXJBdCgoYyA+PiAyKSAmIDYzKTtcbiAgICAgIGEgPSAoYyAmIDMpIDw8IDQ7XG4gICAgfSBlbHNlIGlmIChzID09IDEpIHtcbiAgICAgIHIgKz0gYjY0cy5jaGFyQXQoKGEgfCAoYyA+PiA0KSAmIDE1KSk7XG4gICAgICBhID0gKGMgJiAxNSkgPDwgMjtcbiAgICB9IGVsc2UgaWYgKHMgPT0gMikge1xuICAgICAgciArPSBiNjRzLmNoYXJBdChhIHwgKChjID4+IDYpICYgMykpO1xuICAgICAgbCArPSAxO1xuICAgICAgaWYgKChsICUgNjApID09IDApXG4gICAgICAgIHIgKz0gXCJcXG5cIjtcbiAgICAgIHIgKz0gYjY0cy5jaGFyQXQoYyAmIDYzKTtcbiAgICB9XG4gICAgbCArPSAxO1xuICAgIGlmICgobCAlIDYwKSA9PSAwKVxuICAgICAgciArPSBcIlxcblwiO1xuXG4gICAgcyArPSAxO1xuICAgIGlmIChzID09IDMpXG4gICAgICBzID0gMDtcbiAgfVxuICBpZiAocyA+IDApIHtcbiAgICByICs9IGI2NHMuY2hhckF0KGEpO1xuICAgIGwgKz0gMTtcbiAgICBpZiAoKGwgJSA2MCkgPT0gMClcbiAgICAgIHIgKz0gXCJcXG5cIjtcbiAgICByICs9ICc9JztcbiAgICBsICs9IDE7XG4gIH1cbiAgaWYgKHMgPT0gMSkge1xuICAgIGlmICgobCAlIDYwKSA9PSAwKVxuICAgICAgciArPSBcIlxcblwiO1xuICAgIHIgKz0gJz0nO1xuICB9XG5cbiAgcmV0dXJuIHI7XG59XG5cbmZ1bmN0aW9uIHIycyh0KSB7XG4gIHZhciBjLCBuO1xuICB2YXIgciA9ICcnLFxuICAgIHMgPSAwLFxuICAgIGEgPSAwO1xuICB2YXIgdGwgPSB0Lmxlbmd0aDtcblxuICBmb3IgKG4gPSAwOyBuIDwgdGw7IG4rKykge1xuICAgIGMgPSBiNjRzLmluZGV4T2YodC5jaGFyQXQobikpO1xuICAgIGlmIChjID49IDApIHtcbiAgICAgIGlmIChzKVxuICAgICAgICByICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYSB8IChjID4+ICg2IC0gcykpICYgMjU1KTtcbiAgICAgIHMgPSAocyArIDIpICYgNztcbiAgICAgIGEgPSAoYyA8PCBzKSAmIDI1NTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBlbmNvZGU6IHMycixcbiAgZGVjb2RlOiByMnNcbn1cbiIsInZhciBlbnVtcyA9IHtcblxuICAvKiogQSBzdHJpbmcgdG8ga2V5IHNwZWNpZmllciB0eXBlXG4gICAqIEBlbnVtIHtJbnRlZ2VyfVxuICAgKi9cbiAgczJrOiB7XG4gICAgc2ltcGxlOiAwLFxuICAgIHNhbHRlZDogMSxcbiAgICBpdGVyYXRlZDogMyxcbiAgICBnbnU6IDEwMVxuICB9LFxuXG4gIC8qKiBSRkM0ODgwLCBzZWN0aW9uIDkuMSBcbiAgICogQGVudW0ge1N0cmluZ31cbiAgICovXG4gIHB1YmxpY0tleToge1xuICAgIHJzYV9lbmNyeXB0X3NpZ246IDEsXG4gICAgcnNhX2VuY3J5cHQ6IDIsXG4gICAgcnNhX3NpZ246IDMsXG4gICAgZWxnYW1hbDogMTYsXG4gICAgZHNhOiAxN1xuICB9LFxuXG4gIC8qKiBSRkM0ODgwLCBzZWN0aW9uIDkuMiBcbiAgICogQGVudW0ge1N0cmluZ31cbiAgICovXG4gIHN5bW1ldHJpYzoge1xuICAgIHBsYWludGV4dDogMCxcbiAgICAvKiogTm90IGltcGxlbWVudGVkISAqL1xuICAgIGlkZWE6IDEsXG4gICAgdHJpcGxlZGVzOiAyLFxuICAgIGNhc3Q1OiAzLFxuICAgIGJsb3dmaXNoOiA0LFxuICAgIGFlczEyODogNyxcbiAgICBhZXMxOTI6IDgsXG4gICAgYWVzMjU2OiA5LFxuICAgIHR3b2Zpc2g6IDEwXG4gIH0sXG5cbiAgLyoqIFJGQzQ4ODAsIHNlY3Rpb24gOS4zXG4gICAqIEBlbnVtIHtTdHJpbmd9XG4gICAqL1xuICBjb21wcmVzc2lvbjoge1xuICAgIHVuY29tcHJlc3NlZDogMCxcbiAgICAvKiogUkZDMTk1MSAqL1xuICAgIHppcDogMSxcbiAgICAvKiogUkZDMTk1MCAqL1xuICAgIHpsaWI6IDIsXG4gICAgYnppcDI6IDNcbiAgfSxcblxuICAvKiogUkZDNDg4MCwgc2VjdGlvbiA5LjRcbiAgICogQGVudW0ge1N0cmluZ31cbiAgICovXG4gIGhhc2g6IHtcbiAgICBtZDU6IDEsXG4gICAgc2hhMTogMixcbiAgICByaXBlbWQ6IDMsXG4gICAgc2hhMjU2OiA4LFxuICAgIHNoYTM4NDogOSxcbiAgICBzaGE1MTI6IDEwLFxuICAgIHNoYTIyNDogMTFcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBAZW51bSB7U3RyaW5nfVxuICAgKiBBIGxpc3Qgb2YgcGFja2V0IHR5cGVzIGFuZCBudW1lcmljIHRhZ3MgYXNzb2NpYXRlZCB3aXRoIHRoZW0uXG4gICAqL1xuICBwYWNrZXQ6IHtcbiAgICBwdWJsaWNfa2V5X2VuY3J5cHRlZF9zZXNzaW9uX2tleTogMSxcbiAgICBzaWduYXR1cmU6IDIsXG4gICAgc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleTogMyxcbiAgICBvbmVfcGFzc19zaWduYXR1cmU6IDQsXG4gICAgc2VjcmV0X2tleTogNSxcbiAgICBwdWJsaWNfa2V5OiA2LFxuICAgIHNlY3JldF9zdWJrZXk6IDcsXG4gICAgY29tcHJlc3NlZDogOCxcbiAgICBzeW1tZXRyaWNhbGx5X2VuY3J5cHRlZDogOSxcbiAgICBtYXJrZXI6IDEwLFxuICAgIGxpdGVyYWw6IDExLFxuICAgIHRydXN0OiAxMixcbiAgICB1c2VyaWQ6IDEzLFxuICAgIHB1YmxpY19zdWJrZXk6IDE0LFxuICAgIHVzZXJfYXR0cmlidXRlOiAxNyxcbiAgICBzeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQ6IDE4LFxuICAgIG1vZGlmaWNhdGlvbl9kZXRlY3Rpb25fY29kZTogMTlcbiAgfSxcblxuXG4gIC8qKlxuICAgKiBEYXRhIHR5cGVzIGluIHRoZSBsaXRlcmFsIHBhY2tldFxuICAgKiBAcmVhZG9ubHlcbiAgICogQGVudW0ge1N0cmluZ31cbiAgICovXG4gIGxpdGVyYWw6IHtcbiAgICAvKiogQmluYXJ5IGRhdGEgKi9cbiAgICBiaW5hcnk6ICdiJy5jaGFyQ29kZUF0KCksXG4gICAgLyoqIFRleHQgZGF0YSAqL1xuICAgIHRleHQ6ICd0Jy5jaGFyQ29kZUF0KCksXG4gICAgLyoqIFV0ZjggZGF0YSAqL1xuICAgIHV0Zjg6ICd1Jy5jaGFyQ29kZUF0KClcbiAgfSxcblxuXG4gIC8qKiBPbmUgcGFzcyBzaWduYXR1cmUgcGFja2V0IHR5cGVcbiAgICogQGVudW0ge1N0cmluZ30gKi9cbiAgc2lnbmF0dXJlOiB7XG4gICAgLyoqIDB4MDA6IFNpZ25hdHVyZSBvZiBhIGJpbmFyeSBkb2N1bWVudC4gKi9cbiAgICBiaW5hcnk6IDAsXG4gICAgLyoqIDB4MDE6IFNpZ25hdHVyZSBvZiBhIGNhbm9uaWNhbCB0ZXh0IGRvY3VtZW50LlxuICAgICAqIENhbm9uaWNhbHl6aW5nIHRoZSBkb2N1bWVudCBieSBjb252ZXJ0aW5nIGxpbmUgZW5kaW5ncy4gKi9cbiAgICB0ZXh0OiAxLFxuICAgIC8qKiAweDAyOiBTdGFuZGFsb25lIHNpZ25hdHVyZS5cbiAgICAgKiBUaGlzIHNpZ25hdHVyZSBpcyBhIHNpZ25hdHVyZSBvZiBvbmx5IGl0cyBvd24gc3VicGFja2V0IGNvbnRlbnRzLlxuICAgICAqIEl0IGlzIGNhbGN1bGF0ZWQgaWRlbnRpY2FsbHkgdG8gYSBzaWduYXR1cmUgb3ZlciBhIHplcm8tbGVuZ2hcbiAgICAgKiBiaW5hcnkgZG9jdW1lbnQuICBOb3RlIHRoYXQgaXQgZG9lc24ndCBtYWtlIHNlbnNlIHRvIGhhdmUgYSBWM1xuICAgICAqIHN0YW5kYWxvbmUgc2lnbmF0dXJlLiAqL1xuICAgIHN0YW5kYWxvbmU6IDIsXG4gICAgLyoqIDB4MTA6IEdlbmVyaWMgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQgYW5kIFB1YmxpYy1LZXkgcGFja2V0LlxuICAgICAqIFRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIGRvZXMgbm90IG1ha2UgYW55IHBhcnRpY3VsYXJcbiAgICAgKiBhc3NlcnRpb24gYXMgdG8gaG93IHdlbGwgdGhlIGNlcnRpZmllciBoYXMgY2hlY2tlZCB0aGF0IHRoZSBvd25lclxuICAgICAqIG9mIHRoZSBrZXkgaXMgaW4gZmFjdCB0aGUgcGVyc29uIGRlc2NyaWJlZCBieSB0aGUgVXNlciBJRC4gKi9cbiAgICBjZXJ0X2dlbmVyaWM6IDE2LFxuICAgIC8qKiAweDExOiBQZXJzb25hIGNlcnRpZmljYXRpb24gb2YgYSBVc2VyIElEIGFuZCBQdWJsaWMtS2V5IHBhY2tldC5cbiAgICAgKiBUaGUgaXNzdWVyIG9mIHRoaXMgY2VydGlmaWNhdGlvbiBoYXMgbm90IGRvbmUgYW55IHZlcmlmaWNhdGlvbiBvZlxuICAgICAqIHRoZSBjbGFpbSB0aGF0IHRoZSBvd25lciBvZiB0aGlzIGtleSBpcyB0aGUgVXNlciBJRCBzcGVjaWZpZWQuICovXG4gICAgY2VydF9wZXJzb25hOiAxNyxcbiAgICAvKiogMHgxMjogQ2FzdWFsIGNlcnRpZmljYXRpb24gb2YgYSBVc2VyIElEIGFuZCBQdWJsaWMtS2V5IHBhY2tldC5cbiAgICAgKiBUaGUgaXNzdWVyIG9mIHRoaXMgY2VydGlmaWNhdGlvbiBoYXMgZG9uZSBzb21lIGNhc3VhbFxuICAgICAqIHZlcmlmaWNhdGlvbiBvZiB0aGUgY2xhaW0gb2YgaWRlbnRpdHkuICovXG4gICAgY2VydF9jYXN1YWw6IDE4LFxuICAgIC8qKiAweDEzOiBQb3NpdGl2ZSBjZXJ0aWZpY2F0aW9uIG9mIGEgVXNlciBJRCBhbmQgUHVibGljLUtleSBwYWNrZXQuXG4gICAgICogVGhlIGlzc3VlciBvZiB0aGlzIGNlcnRpZmljYXRpb24gaGFzIGRvbmUgc3Vic3RhbnRpYWxcbiAgICAgKiB2ZXJpZmljYXRpb24gb2YgdGhlIGNsYWltIG9mIGlkZW50aXR5LlxuICAgICAqIFxuICAgICAqIE1vc3QgT3BlblBHUCBpbXBsZW1lbnRhdGlvbnMgbWFrZSB0aGVpciBcImtleSBzaWduYXR1cmVzXCIgYXMgMHgxMFxuICAgICAqIGNlcnRpZmljYXRpb25zLiAgU29tZSBpbXBsZW1lbnRhdGlvbnMgY2FuIGlzc3VlIDB4MTEtMHgxM1xuICAgICAqIGNlcnRpZmljYXRpb25zLCBidXQgZmV3IGRpZmZlcmVudGlhdGUgYmV0d2VlbiB0aGUgdHlwZXMuICovXG4gICAgY2VydF9wb3NpdGl2ZTogMTksXG4gICAgLyoqIDB4MzA6IENlcnRpZmljYXRpb24gcmV2b2NhdGlvbiBzaWduYXR1cmVcbiAgICAgKiBUaGlzIHNpZ25hdHVyZSByZXZva2VzIGFuIGVhcmxpZXIgVXNlciBJRCBjZXJ0aWZpY2F0aW9uIHNpZ25hdHVyZVxuICAgICAqIChzaWduYXR1cmUgY2xhc3MgMHgxMCB0aHJvdWdoIDB4MTMpIG9yIGRpcmVjdC1rZXkgc2lnbmF0dXJlXG4gICAgICogKDB4MUYpLiAgSXQgc2hvdWxkIGJlIGlzc3VlZCBieSB0aGUgc2FtZSBrZXkgdGhhdCBpc3N1ZWQgdGhlXG4gICAgICogcmV2b2tlZCBzaWduYXR1cmUgb3IgYW4gYXV0aG9yaXplZCByZXZvY2F0aW9uIGtleS4gIFRoZSBzaWduYXR1cmVcbiAgICAgKiBpcyBjb21wdXRlZCBvdmVyIHRoZSBzYW1lIGRhdGEgYXMgdGhlIGNlcnRpZmljYXRlIHRoYXQgaXRcbiAgICAgKiByZXZva2VzLCBhbmQgc2hvdWxkIGhhdmUgYSBsYXRlciBjcmVhdGlvbiBkYXRlIHRoYW4gdGhhdFxuICAgICAqIGNlcnRpZmljYXRlLiAqL1xuICAgIGNlcnRfcmV2b2NhdGlvbjogNDgsXG4gICAgLyoqIDB4MTg6IFN1YmtleSBCaW5kaW5nIFNpZ25hdHVyZVxuICAgICAqIFRoaXMgc2lnbmF0dXJlIGlzIGEgc3RhdGVtZW50IGJ5IHRoZSB0b3AtbGV2ZWwgc2lnbmluZyBrZXkgdGhhdFxuICAgICAqIGluZGljYXRlcyB0aGF0IGl0IG93bnMgdGhlIHN1YmtleS4gIFRoaXMgc2lnbmF0dXJlIGlzIGNhbGN1bGF0ZWRcbiAgICAgKiBkaXJlY3RseSBvbiB0aGUgcHJpbWFyeSBrZXkgYW5kIHN1YmtleSwgYW5kIG5vdCBvbiBhbnkgVXNlciBJRCBvclxuICAgICAqIG90aGVyIHBhY2tldHMuICBBIHNpZ25hdHVyZSB0aGF0IGJpbmRzIGEgc2lnbmluZyBzdWJrZXkgTVVTVCBoYXZlXG4gICAgICogYW4gRW1iZWRkZWQgU2lnbmF0dXJlIHN1YnBhY2tldCBpbiB0aGlzIGJpbmRpbmcgc2lnbmF0dXJlIHRoYXRcbiAgICAgKiBjb250YWlucyBhIDB4MTkgc2lnbmF0dXJlIG1hZGUgYnkgdGhlIHNpZ25pbmcgc3Via2V5IG9uIHRoZVxuICAgICAqIHByaW1hcnkga2V5IGFuZCBzdWJrZXkuICovXG4gICAgc3Via2V5X2JpbmRpbmc6IDI0LFxuICAgIC8qKiAweDE5OiBQcmltYXJ5IEtleSBCaW5kaW5nIFNpZ25hdHVyZVxuXHRcdCogVGhpcyBzaWduYXR1cmUgaXMgYSBzdGF0ZW1lbnQgYnkgYSBzaWduaW5nIHN1YmtleSwgaW5kaWNhdGluZ1xuXHRcdCogdGhhdCBpdCBpcyBvd25lZCBieSB0aGUgcHJpbWFyeSBrZXkgYW5kIHN1YmtleS4gIFRoaXMgc2lnbmF0dXJlXG5cdFx0KiBpcyBjYWxjdWxhdGVkIHRoZSBzYW1lIHdheSBhcyBhIDB4MTggc2lnbmF0dXJlOiBkaXJlY3RseSBvbiB0aGVcblx0XHQqIHByaW1hcnkga2V5IGFuZCBzdWJrZXksIGFuZCBub3Qgb24gYW55IFVzZXIgSUQgb3Igb3RoZXIgcGFja2V0cy5cblx0XHRcblx0XHQqIFdoZW4gYSBzaWduYXR1cmUgaXMgbWFkZSBvdmVyIGEga2V5LCB0aGUgaGFzaCBkYXRhIHN0YXJ0cyB3aXRoIHRoZVxuXHRcdCogb2N0ZXQgMHg5OSwgZm9sbG93ZWQgYnkgYSB0d28tb2N0ZXQgbGVuZ3RoIG9mIHRoZSBrZXksIGFuZCB0aGVuIGJvZHlcblx0XHQqIG9mIHRoZSBrZXkgcGFja2V0LiAgKE5vdGUgdGhhdCB0aGlzIGlzIGFuIG9sZC1zdHlsZSBwYWNrZXQgaGVhZGVyIGZvclxuXHRcdCogYSBrZXkgcGFja2V0IHdpdGggdHdvLW9jdGV0IGxlbmd0aC4pICBBIHN1YmtleSBiaW5kaW5nIHNpZ25hdHVyZVxuXHRcdCogKHR5cGUgMHgxOCkgb3IgcHJpbWFyeSBrZXkgYmluZGluZyBzaWduYXR1cmUgKHR5cGUgMHgxOSkgdGhlbiBoYXNoZXNcblx0XHQqIHRoZSBzdWJrZXkgdXNpbmcgdGhlIHNhbWUgZm9ybWF0IGFzIHRoZSBtYWluIGtleSAoYWxzbyB1c2luZyAweDk5IGFzXG5cdFx0KiB0aGUgZmlyc3Qgb2N0ZXQpLiAqL1xuICAgIGtleV9iaW5kaW5nOiAyNSxcbiAgICAvKiogMHgxRjogU2lnbmF0dXJlIGRpcmVjdGx5IG9uIGEga2V5XG4gICAgICogVGhpcyBzaWduYXR1cmUgaXMgY2FsY3VsYXRlZCBkaXJlY3RseSBvbiBhIGtleS4gIEl0IGJpbmRzIHRoZVxuICAgICAqIGluZm9ybWF0aW9uIGluIHRoZSBTaWduYXR1cmUgc3VicGFja2V0cyB0byB0aGUga2V5LCBhbmQgaXNcbiAgICAgKiBhcHByb3ByaWF0ZSB0byBiZSB1c2VkIGZvciBzdWJwYWNrZXRzIHRoYXQgcHJvdmlkZSBpbmZvcm1hdGlvblxuICAgICAqIGFib3V0IHRoZSBrZXksIHN1Y2ggYXMgdGhlIFJldm9jYXRpb24gS2V5IHN1YnBhY2tldC4gIEl0IGlzIGFsc29cbiAgICAgKiBhcHByb3ByaWF0ZSBmb3Igc3RhdGVtZW50cyB0aGF0IG5vbi1zZWxmIGNlcnRpZmllcnMgd2FudCB0byBtYWtlXG4gICAgICogYWJvdXQgdGhlIGtleSBpdHNlbGYsIHJhdGhlciB0aGFuIHRoZSBiaW5kaW5nIGJldHdlZW4gYSBrZXkgYW5kIGFcbiAgICAgKiBuYW1lLiAqL1xuICAgIGtleTogMzEsXG4gICAgLyoqIDB4MjA6IEtleSByZXZvY2F0aW9uIHNpZ25hdHVyZVxuICAgICAqIFRoZSBzaWduYXR1cmUgaXMgY2FsY3VsYXRlZCBkaXJlY3RseSBvbiB0aGUga2V5IGJlaW5nIHJldm9rZWQuICBBXG4gICAgICogcmV2b2tlZCBrZXkgaXMgbm90IHRvIGJlIHVzZWQuICBPbmx5IHJldm9jYXRpb24gc2lnbmF0dXJlcyBieSB0aGVcbiAgICAgKiBrZXkgYmVpbmcgcmV2b2tlZCwgb3IgYnkgYW4gYXV0aG9yaXplZCByZXZvY2F0aW9uIGtleSwgc2hvdWxkIGJlXG4gICAgICogY29uc2lkZXJlZCB2YWxpZCByZXZvY2F0aW9uIHNpZ25hdHVyZXMuYSAqL1xuICAgIGtleV9yZXZvY2F0aW9uOiAzMixcbiAgICAvKiogMHgyODogU3Via2V5IHJldm9jYXRpb24gc2lnbmF0dXJlXG4gICAgICogVGhlIHNpZ25hdHVyZSBpcyBjYWxjdWxhdGVkIGRpcmVjdGx5IG9uIHRoZSBzdWJrZXkgYmVpbmcgcmV2b2tlZC5cbiAgICAgKiBBIHJldm9rZWQgc3Via2V5IGlzIG5vdCB0byBiZSB1c2VkLiAgT25seSByZXZvY2F0aW9uIHNpZ25hdHVyZXNcbiAgICAgKiBieSB0aGUgdG9wLWxldmVsIHNpZ25hdHVyZSBrZXkgdGhhdCBpcyBib3VuZCB0byB0aGlzIHN1YmtleSwgb3JcbiAgICAgKiBieSBhbiBhdXRob3JpemVkIHJldm9jYXRpb24ga2V5LCBzaG91bGQgYmUgY29uc2lkZXJlZCB2YWxpZFxuICAgICAqIHJldm9jYXRpb24gc2lnbmF0dXJlcy5cbiAgICAgKiBLZXkgcmV2b2NhdGlvbiBzaWduYXR1cmVzICh0eXBlcyAweDIwIGFuZCAweDI4KVxuICAgICAqIGhhc2ggb25seSB0aGUga2V5IGJlaW5nIHJldm9rZWQuICovXG4gICAgc3Via2V5X3Jldm9jYXRpb246IDQwLFxuICAgIC8qKiAweDQwOiBUaW1lc3RhbXAgc2lnbmF0dXJlLlxuICAgICAqIFRoaXMgc2lnbmF0dXJlIGlzIG9ubHkgbWVhbmluZ2Z1bCBmb3IgdGhlIHRpbWVzdGFtcCBjb250YWluZWQgaW5cbiAgICAgKiBpdC4gKi9cbiAgICB0aW1lc3RhbXA6IDY0LFxuICAgIC8qKiAgICAweDUwOiBUaGlyZC1QYXJ0eSBDb25maXJtYXRpb24gc2lnbmF0dXJlLlxuICAgICAqIFRoaXMgc2lnbmF0dXJlIGlzIGEgc2lnbmF0dXJlIG92ZXIgc29tZSBvdGhlciBPcGVuUEdQIFNpZ25hdHVyZVxuICAgICAqIHBhY2tldChzKS4gIEl0IGlzIGFuYWxvZ291cyB0byBhIG5vdGFyeSBzZWFsIG9uIHRoZSBzaWduZWQgZGF0YS5cbiAgICAgKiBBIHRoaXJkLXBhcnR5IHNpZ25hdHVyZSBTSE9VTEQgaW5jbHVkZSBTaWduYXR1cmUgVGFyZ2V0XG4gICAgICogc3VicGFja2V0KHMpIHRvIGdpdmUgZWFzeSBpZGVudGlmaWNhdGlvbi4gIE5vdGUgdGhhdCB3ZSByZWFsbHkgZG9cbiAgICAgKiBtZWFuIFNIT1VMRC4gIFRoZXJlIGFyZSBwbGF1c2libGUgdXNlcyBmb3IgdGhpcyAoc3VjaCBhcyBhIGJsaW5kXG4gICAgICogcGFydHkgdGhhdCBvbmx5IHNlZXMgdGhlIHNpZ25hdHVyZSwgbm90IHRoZSBrZXkgb3Igc291cmNlXG4gICAgICogZG9jdW1lbnQpIHRoYXQgY2Fubm90IGluY2x1ZGUgYSB0YXJnZXQgc3VicGFja2V0LiAqL1xuICAgIHRoaXJkX3BhcnR5OiA4MFxuICB9LFxuXG4gIC8vIEFzc2VydHMgdmFsaWRpdHkgYW5kIGNvbnZlcnRzIGZyb20gc3RyaW5nL2ludGVnZXIgdG8gaW50ZWdlci5cbiAgd3JpdGU6IGZ1bmN0aW9uKHR5cGUsIGUpIHtcbiAgICBpZiAodHlwZW9mIGUgPT0gJ251bWJlcicpIHtcbiAgICAgIGUgPSB0aGlzLnJlYWQodHlwZSwgZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVbZV0gIT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdHlwZVtlXTtcbiAgICB9IGVsc2UgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGVudW0gdmFsdWUuJyk7XG4gIH0sXG4gIC8vIENvbnZlcnRzIGZyb20gYW4gaW50ZWdlciB0byBzdHJpbmcuXG4gIHJlYWQ6IGZ1bmN0aW9uKHR5cGUsIGUpIHtcbiAgICBmb3IgKHZhciBpIGluIHR5cGUpXG4gICAgICBpZiAodHlwZVtpXSA9PSBlKSByZXR1cm4gaTtcblxuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBlbnVtIHZhbHVlLicpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZW51bXM7XG4iLCJ2YXIgY3J5cHRvID0gcmVxdWlyZSgnLi9jcnlwdG8nKTtcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL29wZW5wZ3AuanMnKTtcbm1vZHVsZS5leHBvcnRzLnV0aWwgPSByZXF1aXJlKCcuL3V0aWwnKTtcbm1vZHVsZS5leHBvcnRzLnBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0Jyk7XG5tb2R1bGUuZXhwb3J0cy5tcGkgPSByZXF1aXJlKCcuL3R5cGUvbXBpLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5zMmsgPSByZXF1aXJlKCcuL3R5cGUvczJrLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5rZXlpZCA9IHJlcXVpcmUoJy4vdHlwZS9rZXlpZC5qcycpO1xubW9kdWxlLmV4cG9ydHMuYXJtb3IgPSByZXF1aXJlKCcuL2VuY29kaW5nL2FybW9yLmpzJyk7XG5tb2R1bGUuZXhwb3J0cy5lbnVtcyA9IHJlcXVpcmUoJy4vZW51bXMuanMnKTtcblxuZm9yICh2YXIgaSBpbiBjcnlwdG8pXG4gIG1vZHVsZS5leHBvcnRzW2ldID0gY3J5cHRvW2ldO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IFRoZSBvcGVucGdwIGJhc2UgY2xhc3Mgc2hvdWxkIHByb3ZpZGUgYWxsIG9mIHRoZSBmdW5jdGlvbmFsaXR5IFxuICogdG8gY29uc3VtZSB0aGUgb3BlbnBncC5qcyBsaWJyYXJ5LiBBbGwgYWRkaXRpb25hbCBjbGFzc2VzIGFyZSBkb2N1bWVudGVkIFxuICogZm9yIGV4dGVuZGluZyBhbmQgZGV2ZWxvcGluZyBvbiB0b3Agb2YgdGhlIGJhc2UgbGlicmFyeS5cbiAqL1xuXG52YXIgYXJtb3IgPSByZXF1aXJlKCcuL2VuY29kaW5nL2FybW9yLmpzJyk7XG52YXIgcGFja2V0ID0gcmVxdWlyZSgnLi9wYWNrZXQnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgnLi91dGlsJyk7XG52YXIgZW51bXMgPSByZXF1aXJlKCcuL2VudW1zLmpzJyk7XG5cbi8qKlxuICogR1BHNEJyb3dzZXJzIENvcmUgaW50ZXJmYWNlLiBBIHNpbmdsZSBpbnN0YW5jZSBpcyBob2xkXG4gKiBmcm9tIHRoZSBiZWdpbm5pbmcuIFRvIHVzZSB0aGlzIGxpYnJhcnkgY2FsbCBcIm9wZW5wZ3AuaW5pdCgpXCJcbiAqIEBhbGlhcyBvcGVucGdwXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgTWFpbiBPcGVucGdwLmpzIGNsYXNzLiBVc2UgdGhpcyB0byBpbml0aWF0ZSBhbmQgbWFrZSBhbGwgY2FsbHMgdG8gdGhpcyBsaWJyYXJ5LlxuICovXG5mdW5jdGlvbiBfb3BlbnBncCgpIHtcbiAgdGhpcy50b3N0cmluZyA9IFwiXCI7XG5cbiAgLyoqXG4gICAqIGluaXRpYWxpemVzIHRoZSBsaWJyYXJ5OlxuICAgKiAtIHJlYWRpbmcgdGhlIGtleXJpbmcgZnJvbSBsb2NhbCBzdG9yYWdlXG4gICAqIC0gcmVhZGluZyB0aGUgY29uZmlnIGZyb20gbG9jYWwgc3RvcmFnZVxuICAgKi9cbiAgZnVuY3Rpb24gaW5pdCgpIHtcbiAgICB0aGlzLmNvbmZpZyA9IG5ldyBvcGVucGdwX2NvbmZpZygpO1xuICAgIHRoaXMuY29uZmlnLnJlYWQoKTtcbiAgICB0aGlzLmtleXJpbmcgPSBuZXcgb3BlbnBncF9rZXlyaW5nKCk7XG4gICAgdGhpcy5rZXlyaW5nLmluaXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiByZWFkcyBtZXNzYWdlIHBhY2tldHMgb3V0IG9mIGFuIE9wZW5QR1AgYXJtb3JlZCB0ZXh0IGFuZFxuICAgKiByZXR1cm5zIGFuIGFycmF5IG9mIG1lc3NhZ2Ugb2JqZWN0c1xuICAgKiBAcGFyYW0ge1N0cmluZ30gYXJtb3JlZFRleHQgdGV4dCB0byBiZSBwYXJzZWRcbiAgICogQHJldHVybiB7b3BlbnBncF9tc2dfbWVzc2FnZVtdfSBvbiBlcnJvciB0aGUgZnVuY3Rpb25cbiAgICogcmV0dXJucyBudWxsXG4gICAqL1xuICBmdW5jdGlvbiByZWFkQXJtb3JlZFBhY2tldHMoYXJtb3JlZFRleHQpIHtcbiAgICAvL1RPRE8gaG93IGRvIHdlIHdhbnQgdG8gaGFuZGxlIGJhZCB0ZXh0PyBFeGNlcHRpb24gdGhyb3dpbmdcbiAgICB2YXIgaW5wdXQgPSBhcm1vci5kZWNvZGUoYXJtb3JlZFRleHQucmVwbGFjZSgvXFxyL2csICcnKSkub3BlbnBncDtcbiAgICByZXR1cm4gcmVhZERlYXJtb3JlZFBhY2tldHMoaW5wdXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIHJlYWRzIG1lc3NhZ2UgcGFja2V0cyBvdXQgb2YgYW4gT3BlblBHUCBhcm1vcmVkIHRleHQgYW5kXG4gICAqIHJldHVybnMgYW4gYXJyYXkgb2YgbWVzc2FnZSBvYmplY3RzLiBDYW4gYmUgY2FsbGVkIGV4dGVybmFsbHkgb3IgaW50ZXJuYWxseS5cbiAgICogRXh0ZXJuYWwgY2FsbCB3aWxsIHBhcnNlIGEgZGUtYXJtb3JlZCBtZXNzYWdlZCBhbmQgcmV0dXJuIG1lc3NhZ2VzIGZvdW5kLlxuICAgKiBJbnRlcm5hbCB3aWxsIGJlIGNhbGxlZCB0byByZWFkIHBhY2tldHMgd3JhcHBlZCBpbiBvdGhlciBwYWNrZXRzIChpLmUuIGNvbXByZXNzZWQpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBkZWFybW9yZWQgdGV4dCBvZiBPcGVuUEdQIHBhY2tldHMsIHRvIGJlIHBhcnNlZFxuICAgKiBAcmV0dXJuIHtvcGVucGdwX21zZ19tZXNzYWdlW119IG9uIGVycm9yIHRoZSBmdW5jdGlvblxuICAgKiByZXR1cm5zIG51bGxcbiAgICovXG4gIGZ1bmN0aW9uIHJlYWREZWFybW9yZWRQYWNrZXRzKGlucHV0KSB7XG4gICAgdmFyIHBhY2tldExpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgICBwYWNrZXRMaXN0LnJlYWQoaW5wdXQpO1xuICAgIHJldHVybiBwYWNrZXRMaXN0O1xuICB9XG5cbiAgZnVuY3Rpb24gZW5jcnlwdE1lc3NhZ2UocHVibGljS2V5UGFja2V0bGlzdCwgbWVzc2FnZSkge1xuXG4gIH1cblxuICBmdW5jdGlvbiBlbmNyeXB0QW5kU2lnbk1lc3NhZ2UocHVibGljS2V5UGFja2V0bGlzdCwgcHJpdmF0ZUtleVBhY2tldGxpc3QsIG1lc3NhZ2UpIHtcblxuICB9XG5cbiAgZnVuY3Rpb24gZGVjcnlwdE1lc3NhZ2UocHJpdmF0ZUtleVBhY2tldGxpc3QsIG1lc3NhZ2VQYWNrZXRsaXN0KSB7XG5cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlY3J5cHRBbmRWZXJpZnlNZXNzYWdlKHByaXZhdGVLZXlQYWNrZXRsaXN0LCBwdWJsaWNLZXlQYWNrZXRsaXN0LCBtZXNzYWdlUGFja2V0bGlzdCkge1xuXG4gIH1cblxuICBmdW5jdGlvbiB2ZXJpZnlNZXNzYWdlKHB1YmxpY0tleVBhY2tldGxpc3QsIG1lc3NhZ2VQYWNrZXRsaXN0KSB7XG5cbiAgfVxuXG4gIGZ1bmN0aW9uIHNpZ25NZXNzYWdlKHByaXZhdGVLZXlQYWNrZXRsaXN0LCBtZXNzYWdlUGFja2V0bGlzdCkge1xuXG4gIH1cblxuICBmdW5jdGlvbiBnZW5lcmF0ZUtleVBhaXIoa2V5VHlwZSwgbnVtQml0cywgdXNlcklkLCBwYXNzcGhyYXNlKSB7XG4gICAgZGVidWdnZXI7XG4gICAgdmFyIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcblxuICAgIHZhciBzZWNyZXRLZXlQYWNrZXQgPSBuZXcgcGFja2V0LnNlY3JldF9rZXkoKTtcbiAgICBzZWNyZXRLZXlQYWNrZXQuYWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIGtleVR5cGUpO1xuICAgIHNlY3JldEtleVBhY2tldC5nZW5lcmF0ZShudW1CaXRzKTtcbiAgICBzZWNyZXRLZXlQYWNrZXQuZW5jcnlwdChwYXNzcGhyYXNlKTtcblxuICAgIHZhciB1c2VySWRQYWNrZXQgPSBuZXcgcGFja2V0LnVzZXJpZCgpO1xuICAgIHVzZXJJZFBhY2tldC5yZWFkKHVzZXJJZCk7XG5cbiAgICB2YXIgc2lnbmF0dXJlUGFja2V0ID0gbmV3IHBhY2tldC5zaWduYXR1cmUoKTtcbiAgICB2YXIgc2VjcmV0U3Via2V5UGFja2V0ID0gbmV3IHBhY2tldC5zZWNyZXRfc3Via2V5KCk7XG4gICAgdmFyIG92ZXJhbGxTaWduYXR1cmVQYWNrZXQgPSBuZXcgcGFja2V0LnNpZ25hdHVyZSgpO1xuXG4gICAgcGFja2V0bGlzdC5wdXNoKHNlY3JldEtleVBhY2tldCk7XG4gICAgcGFja2V0bGlzdC5wdXNoKHVzZXJJZFBhY2tldCk7XG4gICAgcGFja2V0bGlzdC5wdXNoKHNpZ25hdHVyZVBhY2tldCk7XG4gICAgcGFja2V0bGlzdC5wdXNoKHNlY3JldFN1YmtleVBhY2tldCk7XG4gICAgcGFja2V0bGlzdC5wdXNoKG92ZXJhbGxTaWduYXR1cmVQYWNrZXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIGNyZWF0ZXMgYSBiaW5hcnkgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGFuIGVuY3J5cHRlZCBhbmQgc2lnbmVkIG1lc3NhZ2UuXG4gICAqIFRoZSBtZXNzYWdlIHdpbGwgYmUgZW5jcnlwdGVkIHdpdGggdGhlIHB1YmxpYyBrZXlzIHNwZWNpZmllZCBhbmQgc2lnbmVkXG4gICAqIHdpdGggdGhlIHNwZWNpZmllZCBwcml2YXRlIGtleS5cbiAgICogQHBhcmFtIHtPYmplY3R9IHByaXZhdGVrZXkge29iajogW29wZW5wZ3BfbXNnX3ByaXZhdGVrZXldfSBQcml2YXRlIGtleSBcbiAgICogdG8gYmUgdXNlZCB0byBzaWduIHRoZSBtZXNzYWdlXG4gICAqIEBwYXJhbSB7T2JqZWN0W119IHB1YmxpY2tleXMgQW4gYXJyYWYgb2Yge29iajogW29wZW5wZ3BfbXNnX3B1YmxpY2tleV19XG4gICAqIC0gcHVibGljIGtleXMgdG8gYmUgdXNlZCB0byBlbmNyeXB0IHRoZSBtZXNzYWdlIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZXRleHQgbWVzc2FnZSB0ZXh0IHRvIGVuY3J5cHQgYW5kIHNpZ25cbiAgICogQHJldHVybiB7U3RyaW5nfSBhIGJpbmFyeSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1lc3NhZ2Ugd2hpY2ggXG4gICAqIGNhbiBiZSBPcGVuUEdQIGFybW9yZWRcbiAgICovXG4gIGZ1bmN0aW9uIHdyaXRlX3NpZ25lZF9hbmRfZW5jcnlwdGVkX21lc3NhZ2UocHJpdmF0ZWtleSwgcHVibGlja2V5cywgbWVzc2FnZXRleHQpIHtcbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICB2YXIgaTtcbiAgICB2YXIgbGl0ZXJhbCA9IG5ldyBvcGVucGdwX3BhY2tldF9saXRlcmFsZGF0YSgpLndyaXRlX3BhY2tldChtZXNzYWdldGV4dC5yZXBsYWNlKC9cXHJcXG4vZywgXCJcXG5cIikucmVwbGFjZSgvXFxuL2csXG4gICAgICBcIlxcclxcblwiKSk7XG4gICAgdXRpbC5wcmludF9kZWJ1Z19oZXhzdHJfZHVtcChcImxpdGVyYWxfcGFja2V0OiB8XCIgKyBsaXRlcmFsICsgXCJ8XFxuXCIsIGxpdGVyYWwpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBwdWJsaWNrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgb25lcGFzc3NpZ25hdHVyZSA9IG5ldyBvcGVucGdwX3BhY2tldF9vbmVwYXNzc2lnbmF0dXJlKCk7XG4gICAgICB2YXIgb25lcGFzc3NpZ3N0ciA9IFwiXCI7XG4gICAgICBpZiAoaSA9PT0gMClcbiAgICAgICAgb25lcGFzc3NpZ3N0ciA9IG9uZXBhc3NzaWduYXR1cmUud3JpdGVfcGFja2V0KDEsIG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG0sIHByaXZhdGVrZXksIGZhbHNlKTtcbiAgICAgIGVsc2VcbiAgICAgICAgb25lcGFzc3NpZ3N0ciA9IG9uZXBhc3NzaWduYXR1cmUud3JpdGVfcGFja2V0KDEsIG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5wcmVmZXJfaGFzaF9hbGdvcml0aG0sIHByaXZhdGVrZXksIGZhbHNlKTtcbiAgICAgIHV0aWwucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAoXCJvbmVwYXNzc2lnc3RyOiB8XCIgKyBvbmVwYXNzc2lnc3RyICsgXCJ8XFxuXCIsIG9uZXBhc3NzaWdzdHIpO1xuICAgICAgdmFyIGRhdGFzaWduYXR1cmUgPSBuZXcgb3BlbnBncF9wYWNrZXRfc2lnbmF0dXJlKCkud3JpdGVfbWVzc2FnZV9zaWduYXR1cmUoMSwgbWVzc2FnZXRleHQucmVwbGFjZSgvXFxyXFxuL2csIFwiXFxuXCIpLnJlcGxhY2UoXG4gICAgICAgIC9cXG4vZywgXCJcXHJcXG5cIiksIHByaXZhdGVrZXkpO1xuICAgICAgdXRpbC5wcmludF9kZWJ1Z19oZXhzdHJfZHVtcChcImRhdGFzaWduYXR1cmU6IHxcIiArIGRhdGFzaWduYXR1cmUub3BlbnBncCArIFwifFxcblwiLCBkYXRhc2lnbmF0dXJlLm9wZW5wZ3ApO1xuICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgcmVzdWx0ID0gb25lcGFzc3NpZ3N0ciArIGxpdGVyYWwgKyBkYXRhc2lnbmF0dXJlLm9wZW5wZ3A7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQgPSBvbmVwYXNzc2lnc3RyICsgcmVzdWx0ICsgZGF0YXNpZ25hdHVyZS5vcGVucGdwO1xuICAgICAgfVxuICAgIH1cblxuICAgIHV0aWwucHJpbnRfZGVidWdfaGV4c3RyX2R1bXAoXCJzaWduZWQgcGFja2V0OiB8XCIgKyByZXN1bHQgKyBcInxcXG5cIiwgcmVzdWx0KTtcbiAgICAvLyBzaWduYXR1cmVzIGRvbmUuLiBub3cgZW5jcnlwdGlvblxuICAgIHZhciBzZXNzaW9ua2V5ID0gb3BlbnBncF9jcnlwdG9fZ2VuZXJhdGVTZXNzaW9uS2V5KG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlcik7XG4gICAgdmFyIHJlc3VsdDIgPSBcIlwiO1xuXG4gICAgLy8gY3JlYXRpbmcgc2Vzc2lvbiBrZXlzIGZvciBlYWNoIHJlY2lwaWVudFxuICAgIGZvciAoaSA9IDA7IGkgPCBwdWJsaWNrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcGtleSA9IHB1YmxpY2tleXNbaV0uZ2V0RW5jcnlwdGlvbktleSgpO1xuICAgICAgaWYgKHBrZXkgPT09IG51bGwpIHtcbiAgICAgICAgdXRpbC5wcmludF9lcnJvcihcIm5vIGVuY3J5cHRpb24ga2V5IGZvdW5kISBLZXkgaXMgZm9yIHNpZ25pbmcgb25seS5cIik7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgcmVzdWx0MiArPSBuZXcgb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkc2Vzc2lvbmtleSgpLlxuICAgICAgd3JpdGVfcHViX2tleV9wYWNrZXQoXG4gICAgICAgIHBrZXkuZ2V0S2V5SWQoKSxcbiAgICAgICAgcGtleS5NUElzLFxuICAgICAgICBwa2V5LnB1YmxpY0tleUFsZ29yaXRobSxcbiAgICAgICAgb3BlbnBncC5jb25maWcuY29uZmlnLmVuY3J5cHRpb25fY2lwaGVyLFxuICAgICAgICBzZXNzaW9ua2V5KTtcbiAgICB9XG4gICAgaWYgKG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5pbnRlZ3JpdHlfcHJvdGVjdCkge1xuICAgICAgcmVzdWx0MiArPSBuZXcgb3BlbnBncF9wYWNrZXRfZW5jcnlwdGVkaW50ZWdyaXR5cHJvdGVjdGVkZGF0YSgpLndyaXRlX3BhY2tldChvcGVucGdwLmNvbmZpZy5jb25maWcuZW5jcnlwdGlvbl9jaXBoZXIsXG4gICAgICAgIHNlc3Npb25rZXksIHJlc3VsdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdDIgKz0gbmV3IG9wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGEoKS53cml0ZV9wYWNrZXQob3BlbnBncC5jb25maWcuY29uZmlnLmVuY3J5cHRpb25fY2lwaGVyLCBzZXNzaW9ua2V5LFxuICAgICAgICByZXN1bHQpO1xuICAgIH1cbiAgICByZXR1cm4gYXJtb3IuZW5jb2RlKDMsIHJlc3VsdDIsIG51bGwsIG51bGwpO1xuICB9XG4gIC8qKlxuICAgKiBjcmVhdGVzIGEgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhbiBlbmNyeXB0ZWQgbWVzc2FnZS5cbiAgICogVGhlIG1lc3NhZ2Ugd2lsbCBiZSBlbmNyeXB0ZWQgd2l0aCB0aGUgcHVibGljIGtleXMgc3BlY2lmaWVkIFxuICAgKiBAcGFyYW0ge09iamVjdFtdfSBwdWJsaWNrZXlzIEFuIGFycmF5IG9mIHtvYmo6IFtvcGVucGdwX21zZ19wdWJsaWNrZXldfVxuICAgKiAtcHVibGljIGtleXMgdG8gYmUgdXNlZCB0byBlbmNyeXB0IHRoZSBtZXNzYWdlIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZXRleHQgbWVzc2FnZSB0ZXh0IHRvIGVuY3J5cHRcbiAgICogQHJldHVybiB7U3RyaW5nfSBhIGJpbmFyeSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG1lc3NhZ2VcbiAgICogd2hpY2ggY2FuIGJlIE9wZW5QR1AgYXJtb3JlZFxuICAgKi9cbiAgZnVuY3Rpb24gd3JpdGVfZW5jcnlwdGVkX21lc3NhZ2UocHVibGlja2V5cywgbWVzc2FnZXRleHQpIHtcbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICB2YXIgbGl0ZXJhbCA9IG5ldyBvcGVucGdwX3BhY2tldF9saXRlcmFsZGF0YSgpLndyaXRlX3BhY2tldChtZXNzYWdldGV4dC5yZXBsYWNlKC9cXHJcXG4vZywgXCJcXG5cIikucmVwbGFjZSgvXFxuL2csXG4gICAgICBcIlxcclxcblwiKSk7XG4gICAgdXRpbC5wcmludF9kZWJ1Z19oZXhzdHJfZHVtcChcImxpdGVyYWxfcGFja2V0OiB8XCIgKyBsaXRlcmFsICsgXCJ8XFxuXCIsIGxpdGVyYWwpO1xuICAgIHJlc3VsdCA9IGxpdGVyYWw7XG5cbiAgICAvLyBzaWduYXR1cmVzIGRvbmUuLiBub3cgZW5jcnlwdGlvblxuICAgIHZhciBzZXNzaW9ua2V5ID0gb3BlbnBncF9jcnlwdG9fZ2VuZXJhdGVTZXNzaW9uS2V5KG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlcik7XG4gICAgdmFyIHJlc3VsdDIgPSBcIlwiO1xuXG4gICAgLy8gY3JlYXRpbmcgc2Vzc2lvbiBrZXlzIGZvciBlYWNoIHJlY2lwaWVudFxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHVibGlja2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHBrZXkgPSBwdWJsaWNrZXlzW2ldLmdldEVuY3J5cHRpb25LZXkoKTtcbiAgICAgIGlmIChwa2V5ID09PSBudWxsKSB7XG4gICAgICAgIHV0aWwucHJpbnRfZXJyb3IoXCJubyBlbmNyeXB0aW9uIGtleSBmb3VuZCEgS2V5IGlzIGZvciBzaWduaW5nIG9ubHkuXCIpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJlc3VsdDIgKz0gbmV3IG9wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZHNlc3Npb25rZXkoKS5cbiAgICAgIHdyaXRlX3B1Yl9rZXlfcGFja2V0KFxuICAgICAgICBwa2V5LmdldEtleUlkKCksXG4gICAgICAgIHBrZXkuTVBJcyxcbiAgICAgICAgcGtleS5wdWJsaWNLZXlBbGdvcml0aG0sXG4gICAgICAgIG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlcixcbiAgICAgICAgc2Vzc2lvbmtleSk7XG4gICAgfVxuICAgIGlmIChvcGVucGdwLmNvbmZpZy5jb25maWcuaW50ZWdyaXR5X3Byb3RlY3QpIHtcbiAgICAgIHJlc3VsdDIgKz0gbmV3IG9wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGludGVncml0eXByb3RlY3RlZGRhdGEoKS53cml0ZV9wYWNrZXQob3BlbnBncC5jb25maWcuY29uZmlnLmVuY3J5cHRpb25fY2lwaGVyLFxuICAgICAgICBzZXNzaW9ua2V5LCByZXN1bHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQyICs9IG5ldyBvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhKCkud3JpdGVfcGFja2V0KG9wZW5wZ3AuY29uZmlnLmNvbmZpZy5lbmNyeXB0aW9uX2NpcGhlciwgc2Vzc2lvbmtleSxcbiAgICAgICAgcmVzdWx0KTtcbiAgICB9XG4gICAgcmV0dXJuIGFybW9yLmVuY29kZSgzLCByZXN1bHQyLCBudWxsLCBudWxsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBjcmVhdGVzIGEgYmluYXJ5IHN0cmluZyByZXByZXNlbnRhdGlvbiBhIHNpZ25lZCBtZXNzYWdlLlxuICAgKiBUaGUgbWVzc2FnZSB3aWxsIGJlIHNpZ25lZCB3aXRoIHRoZSBzcGVjaWZpZWQgcHJpdmF0ZSBrZXkuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwcml2YXRla2V5IHtvYmo6IFtvcGVucGdwX21zZ19wcml2YXRla2V5XX1cbiAgICogLSB0aGUgcHJpdmF0ZSBrZXkgdG8gYmUgdXNlZCB0byBzaWduIHRoZSBtZXNzYWdlIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZXRleHQgbWVzc2FnZSB0ZXh0IHRvIHNpZ25cbiAgICogQHJldHVybiB7T2JqZWN0fSB7T2JqZWN0OiB0ZXh0IFtTdHJpbmddfSwgb3BlbnBncDoge1N0cmluZ30gYSBiaW5hcnlcbiAgICogIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWVzc2FnZSB3aGljaCBjYW4gYmUgT3BlblBHUFxuICAgKiAgIGFybW9yZWQob3BlbnBncCkgYW5kIGEgdGV4dCByZXByZXNlbnRhdGlvbiBvZiB0aGUgbWVzc2FnZSAodGV4dCkuIFxuICAgKiBUaGlzIGNhbiBiZSBkaXJlY3RseSB1c2VkIHRvIE9wZW5QR1AgYXJtb3IgdGhlIG1lc3NhZ2VcbiAgICovXG4gIGZ1bmN0aW9uIHdyaXRlX3NpZ25lZF9tZXNzYWdlKHByaXZhdGVrZXksIG1lc3NhZ2V0ZXh0KSB7XG4gICAgdmFyIHNpZyA9IG5ldyBvcGVucGdwX3BhY2tldF9zaWduYXR1cmUoKS53cml0ZV9tZXNzYWdlX3NpZ25hdHVyZSgxLCBtZXNzYWdldGV4dC5yZXBsYWNlKC9cXHJcXG4vZywgXCJcXG5cIikucmVwbGFjZSgvXFxuLyxcbiAgICAgIFwiXFxyXFxuXCIpLCBwcml2YXRla2V5KTtcbiAgICB2YXIgcmVzdWx0ID0ge1xuICAgICAgdGV4dDogbWVzc2FnZXRleHQucmVwbGFjZSgvXFxyXFxuL2csIFwiXFxuXCIpLnJlcGxhY2UoL1xcbi8sIFwiXFxyXFxuXCIpLFxuICAgICAgb3BlbnBncDogc2lnLm9wZW5wZ3AsXG4gICAgICBoYXNoOiBzaWcuaGFzaFxuICAgIH07XG4gICAgcmV0dXJuIGFybW9yLmVuY29kZSgyLCByZXN1bHQsIG51bGwsIG51bGwpO1xuICB9XG5cbiAgLyoqXG4gICAqIGdlbmVyYXRlcyBhIG5ldyBrZXkgcGFpciBmb3Igb3BlbnBncC4gQmV0YSBzdGFnZS4gQ3VycmVudGx5IG9ubHkgXG4gICAqIHN1cHBvcnRzIFJTQSBrZXlzLCBhbmQgbm8gc3Via2V5cy5cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBrZXlUeXBlIHRvIGluZGljYXRlIHdoYXQgdHlwZSBvZiBrZXkgdG8gbWFrZS4gXG4gICAqIFJTQSBpcyAxLiBGb2xsb3dzIGFsZ29yaXRobXMgb3V0bGluZWQgaW4gT3BlblBHUC5cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBudW1CaXRzIG51bWJlciBvZiBiaXRzIGZvciB0aGUga2V5IGNyZWF0aW9uLiAoc2hvdWxkIFxuICAgKiBiZSAxMDI0KywgZ2VuZXJhbGx5KVxuICAgKiBAcGFyYW0ge1N0cmluZ30gdXNlcklkIGFzc3VtZXMgYWxyZWFkeSBpbiBmb3JtIG9mIFwiVXNlciBOYW1lIFxuICAgKiA8dXNlcm5hbWVAZW1haWwuY29tPlwiXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzcGhyYXNlIFRoZSBwYXNzcGhyYXNlIHVzZWQgdG8gZW5jcnlwdCB0aGUgcmVzdWx0aW5nIHByaXZhdGUga2V5XG4gICAqIEByZXR1cm4ge09iamVjdH0ge3ByaXZhdGVLZXk6IFtvcGVucGdwX21zZ19wcml2YXRla2V5XSwgXG4gICAqIHByaXZhdGVLZXlBcm1vcmVkOiBbc3RyaW5nXSwgcHVibGljS2V5QXJtb3JlZDogW3N0cmluZ119XG4gICAqL1xuICBmdW5jdGlvbiBnZW5lcmF0ZV9rZXlfcGFpcihrZXlUeXBlLCBudW1CaXRzLCB1c2VySWQsIHBhc3NwaHJhc2UpIHtcbiAgICB2YXIgdXNlcklkUGFja2V0ID0gbmV3IG9wZW5wZ3BfcGFja2V0X3VzZXJpZCgpO1xuICAgIHZhciB1c2VySWRTdHJpbmcgPSB1c2VySWRQYWNrZXQud3JpdGVfcGFja2V0KHVzZXJJZCk7XG5cbiAgICB2YXIga2V5UGFpciA9IG9wZW5wZ3BfY3J5cHRvX2dlbmVyYXRlS2V5UGFpcihrZXlUeXBlLCBudW1CaXRzLCBwYXNzcGhyYXNlLCBvcGVucGdwLmNvbmZpZy5jb25maWcucHJlZmVyX2hhc2hfYWxnb3JpdGhtLFxuICAgICAgMyk7XG4gICAgdmFyIHByaXZLZXlTdHJpbmcgPSBrZXlQYWlyLnByaXZhdGVLZXk7XG4gICAgdmFyIHByaXZLZXlQYWNrZXQgPSBuZXcgb3BlbnBncF9wYWNrZXRfa2V5bWF0ZXJpYWwoKS5yZWFkX3ByaXZfa2V5KHByaXZLZXlTdHJpbmcuc3RyaW5nLCAzLCBwcml2S2V5U3RyaW5nLnN0cmluZy5sZW5ndGgpO1xuICAgIGlmICghcHJpdktleVBhY2tldC5kZWNyeXB0U2VjcmV0TVBJcyhwYXNzcGhyYXNlKSlcbiAgICAgIHV0aWwucHJpbnRfZXJyb3IoJ0lzc3VlIGNyZWF0aW5nIGtleS4gVW5hYmxlIHRvIHJlYWQgcmVzdWx0aW5nIHByaXZhdGUga2V5Jyk7XG4gICAgdmFyIHByaXZLZXkgPSBuZXcgb3BlbnBncF9tc2dfcHJpdmF0ZWtleSgpO1xuICAgIHByaXZLZXkucHJpdmF0ZUtleVBhY2tldCA9IHByaXZLZXlQYWNrZXQ7XG4gICAgcHJpdktleS5nZXRQcmVmZXJyZWRTaWduYXR1cmVIYXNoQWxnb3JpdGhtID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gb3BlbnBncC5jb25maWcuY29uZmlnLnByZWZlcl9oYXNoX2FsZ29yaXRobVxuICAgIH07IC8vbmVlZCB0byBvdmVycmlkZSB0aGlzIHRvIHNvbHZlIGNhdGNoIDIyIHRvIGdlbmVyYXRlIHNpZ25hdHVyZS4gOCBpcyB2YWx1ZSBmb3IgU0hBMjU2XG5cbiAgICB2YXIgcHVibGljS2V5U3RyaW5nID0gcHJpdktleS5wcml2YXRlS2V5UGFja2V0LnB1YmxpY0tleS5kYXRhO1xuICAgIHZhciBoYXNoRGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHg5OSkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKCgocHVibGljS2V5U3RyaW5nLmxlbmd0aCkgPj4gOCkgJiAweEZGKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoKFxuICAgICAgcHVibGljS2V5U3RyaW5nLmxlbmd0aCkgJiAweEZGKSArIHB1YmxpY0tleVN0cmluZyArIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhCNCkgK1xuICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZSgodXNlcklkLmxlbmd0aCkgPj4gMjQpICsgU3RyaW5nLmZyb21DaGFyQ29kZSgoKHVzZXJJZC5sZW5ndGgpID4+IDE2KSAmIDB4RkYpICsgU3RyaW5nLmZyb21DaGFyQ29kZSgoKFxuICAgICAgdXNlcklkLmxlbmd0aCkgPj4gOCkgJiAweEZGKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoKHVzZXJJZC5sZW5ndGgpICYgMHhGRikgKyB1c2VySWQ7XG4gICAgdmFyIHNpZ25hdHVyZSA9IG5ldyBvcGVucGdwX3BhY2tldF9zaWduYXR1cmUoKTtcbiAgICBzaWduYXR1cmUgPSBzaWduYXR1cmUud3JpdGVfbWVzc2FnZV9zaWduYXR1cmUoMTYsIGhhc2hEYXRhLCBwcml2S2V5KTtcbiAgICB2YXIgcHVibGljQXJtb3JlZCA9IGFybW9yLmVuY29kZSg0LCBrZXlQYWlyLnB1YmxpY0tleS5zdHJpbmcgKyB1c2VySWRTdHJpbmcgKyBzaWduYXR1cmUub3BlbnBncCk7XG5cbiAgICB2YXIgcHJpdkFybW9yZWQgPSBhcm1vci5lbmNvZGUoNSwgcHJpdktleVN0cmluZy5zdHJpbmcgKyB1c2VySWRTdHJpbmcgKyBzaWduYXR1cmUub3BlbnBncCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcHJpdmF0ZUtleTogcHJpdktleSxcbiAgICAgIHByaXZhdGVLZXlBcm1vcmVkOiBwcml2QXJtb3JlZCxcbiAgICAgIHB1YmxpY0tleUFybW9yZWQ6IHB1YmxpY0FybW9yZWRcbiAgICB9O1xuICB9XG5cbiAgdGhpcy5nZW5lcmF0ZUtleVBhaXIgPSBnZW5lcmF0ZUtleVBhaXI7XG4gIHRoaXMud3JpdGVfc2lnbmVkX21lc3NhZ2UgPSB3cml0ZV9zaWduZWRfbWVzc2FnZTtcbiAgdGhpcy53cml0ZV9zaWduZWRfYW5kX2VuY3J5cHRlZF9tZXNzYWdlID0gd3JpdGVfc2lnbmVkX2FuZF9lbmNyeXB0ZWRfbWVzc2FnZTtcbiAgdGhpcy53cml0ZV9lbmNyeXB0ZWRfbWVzc2FnZSA9IHdyaXRlX2VuY3J5cHRlZF9tZXNzYWdlO1xuICB0aGlzLnJlYWRBcm1vcmVkUGFja2V0cyA9IHJlYWRBcm1vcmVkUGFja2V0cztcbiAgdGhpcy5yZWFkRGVhcm1vcmVkUGFja2V0cyA9IHJlYWREZWFybW9yZWRQYWNrZXRzO1xuICB0aGlzLmluaXQgPSBpbml0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBfb3BlbnBncCgpO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHBhY2tldCA9IHJlcXVpcmUoJy4vcGFja2V0Jyk7XG52YXIgZW51bXMgPSByZXF1aXJlKCcuL2VudW1zLmpzJyk7XG52YXIgYXJtb3IgPSByZXF1aXJlKCcuL2VuY29kaW5nL2FybW9yLmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIFRoZSBjbGFzcyB0aGF0IGRlYWxzIHdpdGggc3RvcmFnZSBvZiB0aGUga2V5cmluZy4gQ3VycmVudGx5IHRoZSBvbmx5IG9wdGlvbiBpcyB0byB1c2UgSFRNTDUgbG9jYWwgc3RvcmFnZS5cbiAqL1xudmFyIGtleXJpbmcgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5hcm1vcmVkUGFja2V0bGlzdHMgPSBbXTtcbiAgdGhpcy5wYXJzZWRQYWNrZXRsaXN0cyA9IFtdO1xuXG4gIC8qKlxuICAgKiBJbml0aWFsaXphdGlvbiByb3V0aW5lIGZvciB0aGUga2V5cmluZy4gVGhpcyBtZXRob2QgcmVhZHMgdGhlIFxuICAgKiBrZXlyaW5nIGZyb20gSFRNTDUgbG9jYWwgc3RvcmFnZSBhbmQgaW5pdGlhbGl6ZXMgdGhpcyBpbnN0YW5jZS5cbiAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IG9wZW5wZ3AuaW5pdCgpLlxuICAgKi9cbiAgZnVuY3Rpb24gaW5pdCgpIHtcbiAgICB2YXIgYXJtb3JlZFBhY2tldGxpc3RzID0gSlNPTi5wYXJzZSh3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJhcm1vcmVkUGFja2V0bGlzdHNcIikpO1xuICAgIGlmIChhcm1vcmVkUGFja2V0bGlzdHMgPT09IG51bGwgfHwgYXJtb3JlZFBhY2tldGxpc3RzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgYXJtb3JlZFBhY2tldGxpc3RzID0gW107XG4gICAgfVxuICAgIHRoaXMuYXJtb3JlZFBhY2tldGxpc3RzID0gYXJtb3JlZFBhY2tldGxpc3RzO1xuXG4gICAgdmFyIHBhY2tldGxpc3Q7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcm1vcmVkUGFja2V0bGlzdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgICAgIHBhY2tldGxpc3QucmVhZChhcm1vcmVkUGFja2V0bGlzdHNbaV0pO1xuICAgICAgdGhpcy5wYXJzZWRQYWNrZXRsaXN0cy5wdXNoKHBhY2tldGxpc3QpO1xuICAgIH1cbiAgfVxuICB0aGlzLmluaXQgPSBpbml0O1xuXG4gIC8qKlxuICAgKiBTYXZlcyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUga2V5cmluZyB0byBIVE1MNSBsb2NhbCBzdG9yYWdlLlxuICAgKiBUaGUgcHJpdmF0ZUtleXMgYXJyYXkgYW5kIHB1YmxpY0tleXMgYXJyYXkgZ2V0cyBTdHJpbmdpZmllZCB1c2luZyBKU09OXG4gICAqL1xuICBmdW5jdGlvbiBzdG9yZSgpIHtcbiAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0oXCJhcm1vcmVkUGFja2V0bGlzdHNcIiwgSlNPTi5zdHJpbmdpZnkodGhpcy5hcm1vcmVkUGFja2V0bGlzdHMpKTtcbiAgfVxuICB0aGlzLnN0b3JlID0gc3RvcmU7XG5cbiAgZnVuY3Rpb24gZW1haWxQYWNrZXRDaGVjayhwYWNrZXQsIGVtYWlsKSB7XG4gICAgdmFyIGVtYWlsTWF0Y2ggPSBmYWxzZTtcbiAgICB2YXIgcGFja2V0RW1haWw7XG4gICAgZW1haWwgPSBlbWFpbC50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChwYWNrZXQudGFnID09IGVudW1zLnBhY2tldC51c2VyaWQpIHtcbiAgICAgIHBhY2tldEVtYWlsID0gcGFja2V0LnVzZXJpZDtcbiAgICAgIC8vd2UgbmVlZCB0byBnZXQganVzdCB0aGUgZW1haWwgZnJvbSB0aGUgdXNlcmlkIHBhY2tldFxuICAgICAgcGFja2V0RW1haWwgPSBwYWNrZXRFbWFpbC5zcGxpdCgnPCcpWzFdLnNwbGl0KCc8JylbMF0udHJpbS50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKHBhY2tldEVtYWlsID09IGVtYWlsKSB7XG4gICAgICAgIGVtYWlsTWF0Y2ggPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZW1haWxNYXRjaDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlkUGFja2V0Q2hlY2socGFja2V0LCBpZCkge1xuICAgIGlmIChwYWNrZXQuZ2V0S2V5SWQgJiYgcGFja2V0LmdldEtleUlkKCkgPT0gaWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBmdW5jdGlvbiBoZWxwZXJDaGVja0lkZW50aXR5QW5kUGFja2V0TWF0Y2goaWRlbnRpdHlGdW5jdGlvbiwgaWRlbnRpdHlJbnB1dCwgcGFja2V0VHlwZSwgcGFja2V0bGlzdCkge1xuICAgIHZhciBwYWNrZXQ7XG4gICAgZm9yICh2YXIgbCA9IDA7IGwgPCBwYWNrZXRsaXN0Lmxlbmd0aDsgbCsrKSB7XG4gICAgICBwYWNrZXQgPSBwYWNrZXRsaXN0W2xdO1xuICAgICAgaWRlbnRpdHlNYXRjaCA9IGlkZW50aXR5RnVuY3Rpb24ocGFja2V0LCBpZGVudGl0eUlucHV0KTtcbiAgICAgIGlmICghcGFja2V0VHlwZSkge1xuICAgICAgICBwYWNrZXRNYXRjaCA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKHBhY2tldC50YWcgPT0gcGFja2V0VHlwZSkge1xuICAgICAgICBwYWNrZXRNYXRjaCA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAocGFja2V0TWF0Y2ggJiYgaWRlbnRpdHlNYXRjaCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gY2hlY2tGb3JJZGVudGl0eUFuZFBhY2tldE1hdGNoKGlkZW50aXR5RnVuY3Rpb24sIGlkZW50aXR5SW5wdXQsIHBhY2tldFR5cGUpIHtcbiAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgIHZhciBwYWNrZXRsaXN0O1xuICAgIHZhciBpZGVudGl0eU1hdGNoO1xuICAgIHZhciBwYWNrZXRNYXRjaDtcbiAgICBmb3IgKHZhciBwID0gMDsgcCA8IHRoaXMucGFyc2VkUGFja2V0bGlzdHMubGVuZ3RoOyBwKyspIHtcbiAgICAgIGlkZW50aXR5TWF0Y2ggPSBmYWxzZTtcbiAgICAgIHBhY2tldE1hdGNoID0gZmFsc2U7XG4gICAgICBwYWNrZXRsaXN0ID0gdGhpcy5wYXJzZWRQYWNrZXRsaXN0c1twXTtcbiAgICAgIGlmIChoZWxwZXJDaGVja0lkZW50aXR5QW5kUGFja2V0TWF0Y2goaWRlbnRpdHlGdW5jdGlvbiwgaWRlbnRpdHlJbnB1dCwgcGFja2V0VHlwZSwgcGFja2V0bGlzdCkpIHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKHBhY2tldGxpc3QpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuICB0aGlzLmNoZWNrRm9ySWRlbnRpdHlBbmRQYWNrZXRNYXRjaCA9IGNoZWNrRm9ySWRlbnRpdHlBbmRQYWNrZXRNYXRjaDtcblxuICAvKipcbiAgICogc2VhcmNoZXMgYWxsIHB1YmxpYyBrZXlzIGluIHRoZSBrZXlyaW5nIG1hdGNoaW5nIHRoZSBhZGRyZXNzIG9yIGFkZHJlc3MgcGFydCBvZiB0aGUgdXNlciBpZHNcbiAgICogQHBhcmFtIHtTdHJpbmd9IGVtYWlsX2FkZHJlc3NcbiAgICogQHJldHVybiB7b3BlbnBncF9tc2dfcHVibGlja2V5W119IFRoZSBwdWJsaWMga2V5cyBhc3NvY2lhdGVkIHdpdGggcHJvdmlkZWQgZW1haWwgYWRkcmVzcy5cbiAgICovXG4gIGZ1bmN0aW9uIGdldFB1YmxpY0tleUZvckFkZHJlc3MoZW1haWwpIHtcbiAgICByZXR1cm4gY2hlY2tGb3JJZGVudGl0eUFuZFBhY2tldE1hdGNoKGVtYWlsUGFja2V0Q2hlY2ssIGVtYWlsLCBlbnVtcy5wYWNrZXQucHVibGljX2tleSk7XG4gIH1cbiAgdGhpcy5nZXRQdWJsaWNLZXlGb3JBZGRyZXNzID0gZ2V0UHVibGljS2V5Rm9yQWRkcmVzcztcblxuICAvKipcbiAgICogU2VhcmNoZXMgdGhlIGtleXJpbmcgZm9yIGEgcHJpdmF0ZSBrZXkgY29udGFpbmluZyB0aGUgc3BlY2lmaWVkIGVtYWlsIGFkZHJlc3NcbiAgICogQHBhcmFtIHtTdHJpbmd9IGVtYWlsX2FkZHJlc3MgZW1haWwgYWRkcmVzcyB0byBzZWFyY2ggZm9yXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXlbXX0gcHJpdmF0ZSBrZXlzIGZvdW5kXG4gICAqL1xuICBmdW5jdGlvbiBnZXRQcml2YXRlS2V5Rm9yQWRkcmVzcyhlbWFpbF9hZGRyZXNzKSB7XG4gICAgcmV0dXJuIGNoZWNrRm9ySWRlbnRpdHlBbmRQYWNrZXRNYXRjaChlbWFpbFBhY2tldENoZWNrLCBlbWFpbCwgZW51bXMucGFja2V0LnNlY3JldF9rZXkpO1xuICB9XG4gIHRoaXMuZ2V0UHJpdmF0ZUtleUZvckFkZHJlc3MgPSBnZXRQcml2YXRlS2V5Rm9yQWRkcmVzcztcblxuICAvKipcbiAgICogU2VhcmNoZXMgdGhlIGtleXJpbmcgZm9yIHB1YmxpYyBrZXlzIGhhdmluZyB0aGUgc3BlY2lmaWVkIGtleSBpZFxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5SWQgcHJvdmlkZWQgYXMgc3RyaW5nIG9mIGhleCBudW1iZXIgKGxvd2VyY2FzZSlcbiAgICogQHJldHVybiB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleVtdfSBwdWJsaWMga2V5cyBmb3VuZFxuICAgKi9cbiAgZnVuY3Rpb24gZ2V0UGFja2V0bGlzdHNGb3JLZXlJZChrZXlJZCkge1xuICAgIHJldHVybiB0aGlzLmNoZWNrRm9ySWRlbnRpdHlBbmRQYWNrZXRNYXRjaChpZFBhY2tldENoZWNrLCBrZXlJZCk7XG4gIH1cbiAgdGhpcy5nZXRQYWNrZXRsaXN0c0ZvcktleUlkID0gZ2V0UGFja2V0bGlzdHNGb3JLZXlJZDtcblxuICAvKipcbiAgICogSW1wb3J0cyBhIHBhY2tldCBsaXN0IChwdWJsaWMgb3IgcHJpdmF0ZSBrZXkgYmxvY2spIGZyb20gYW4gYXNjaWkgYXJtb3JlZCBtZXNzYWdlIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gYXJtb3JlZCBtZXNzYWdlIHRvIHJlYWQgdGhlIHBhY2tldHMva2V5IGZyb21cbiAgICovXG4gIGZ1bmN0aW9uIGltcG9ydFBhY2tldGxpc3QoYXJtb3JlZCkge1xuICAgIHRoaXMuYXJtb3JlZFBhY2tldGxpc3RzLnB1c2goYXJtb3JlZCk7XG5cbiAgICB2YXIgZGVhcm1vcmVkID0gYXJtb3IuZGVjb2RlKGFybW9yZWQucmVwbGFjZSgvXFxyL2csICcnKSkub3BlbnBncDtcblxuICAgIHBhY2tldGxpc3QgPSBuZXcgcGFja2V0Lmxpc3QoKTtcbiAgICBwYWNrZXRsaXN0LnJlYWQoZGVhcm1vcmVkKTtcbiAgICB0aGlzLnBhcnNlZFBhY2tldGxpc3RzLnB1c2gocGFja2V0bGlzdCk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICB0aGlzLmltcG9ydFBhY2tldGxpc3QgPSBpbXBvcnRQYWNrZXRsaXN0O1xuXG4gIC8qKlxuICAgKiBUT0RPXG4gICAqIHJldHVybnMgdGhlIG9wZW5wZ3BfbXNnX3ByaXZhdGVrZXkgcmVwcmVzZW50YXRpb24gb2YgdGhlIHB1YmxpYyBrZXkgYXQgcHVibGljIGtleSByaW5nIGluZGV4ICBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIHB1YmxpYyBrZXkgd2l0aGluIHRoZSBwdWJsaWNLZXlzIGFycmF5XG4gICAqIEByZXR1cm4ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXl9IHRoZSBwdWJsaWMga2V5IG9iamVjdFxuICAgKi9cbiAgZnVuY3Rpb24gZXhwb3J0UHVibGljS2V5KGluZGV4KSB7XG4gICAgcmV0dXJuIHRoaXMucHVibGljS2V5W2luZGV4XTtcbiAgfVxuICB0aGlzLmV4cG9ydFB1YmxpY0tleSA9IGV4cG9ydFB1YmxpY0tleTtcblxuICAvKipcbiAgICogVE9ET1xuICAgKiBSZW1vdmVzIGEgcHVibGljIGtleSBmcm9tIHRoZSBwdWJsaWMga2V5IGtleXJpbmcgYXQgdGhlIHNwZWNpZmllZCBpbmRleCBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpbmRleCB0aGUgaW5kZXggb2YgdGhlIHB1YmxpYyBrZXkgd2l0aGluIHRoZSBwdWJsaWNLZXlzIGFycmF5XG4gICAqIEByZXR1cm4ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXl9IFRoZSBwdWJsaWMga2V5IG9iamVjdCB3aGljaCBoYXMgYmVlbiByZW1vdmVkXG4gICAqL1xuICBmdW5jdGlvbiByZW1vdmVQdWJsaWNLZXkoaW5kZXgpIHtcbiAgICB2YXIgcmVtb3ZlZCA9IHRoaXMucHVibGljS2V5cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHRoaXMuc3RvcmUoKTtcbiAgICByZXR1cm4gcmVtb3ZlZDtcbiAgfVxuICB0aGlzLnJlbW92ZVB1YmxpY0tleSA9IHJlbW92ZVB1YmxpY0tleTtcblxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcga2V5cmluZygpO1xuIiwidmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxuLy8gVGhpcyBpcyBwcmV0dHkgdWdseSwgYnV0IGJyb3dzZXJpZnkgbmVlZHMgdG8gaGF2ZSB0aGUgcmVxdWlyZXMgZXhwbGljaXRseSB3cml0dGVuLlxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGNvbXByZXNzZWQ6IHJlcXVpcmUoJy4vY29tcHJlc3NlZC5qcycpLFxuICBzeW1fZW5jcnlwdGVkX2ludGVncml0eV9wcm90ZWN0ZWQ6IHJlcXVpcmUoJy4vc3ltX2VuY3J5cHRlZF9pbnRlZ3JpdHlfcHJvdGVjdGVkLmpzJyksXG4gIHB1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5OiByZXF1aXJlKCcuL3B1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5LmpzJyksXG4gIHN5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXk6IHJlcXVpcmUoJy4vc3ltX2VuY3J5cHRlZF9zZXNzaW9uX2tleS5qcycpLFxuICBsaXRlcmFsOiByZXF1aXJlKCcuL2xpdGVyYWwuanMnKSxcbiAgcHVibGljX2tleTogcmVxdWlyZSgnLi9wdWJsaWNfa2V5LmpzJyksXG4gIHN5bW1ldHJpY2FsbHlfZW5jcnlwdGVkOiByZXF1aXJlKCcuL3N5bW1ldHJpY2FsbHlfZW5jcnlwdGVkLmpzJyksXG4gIG1hcmtlcjogcmVxdWlyZSgnLi9tYXJrZXIuanMnKSxcbiAgcHVibGljX3N1YmtleTogcmVxdWlyZSgnLi9wdWJsaWNfc3Via2V5LmpzJyksXG4gIHVzZXJfYXR0cmlidXRlOiByZXF1aXJlKCcuL3VzZXJfYXR0cmlidXRlLmpzJyksXG4gIG9uZV9wYXNzX3NpZ25hdHVyZTogcmVxdWlyZSgnLi9vbmVfcGFzc19zaWduYXR1cmUuanMnKSxcbiAgc2VjcmV0X2tleTogcmVxdWlyZSgnLi9zZWNyZXRfa2V5LmpzJyksXG4gIHVzZXJpZDogcmVxdWlyZSgnLi91c2VyaWQuanMnKSxcbiAgc2VjcmV0X3N1YmtleTogcmVxdWlyZSgnLi9zZWNyZXRfc3Via2V5LmpzJyksXG4gIHNpZ25hdHVyZTogcmVxdWlyZSgnLi9zaWduYXR1cmUuanMnKSxcbiAgdHJ1c3Q6IHJlcXVpcmUoJy4vdHJ1c3QuanMnKVxufVxuXG5mb3IgKHZhciBpIGluIGVudW1zLnBhY2tldCkge1xuICB2YXIgcGFja2V0Q2xhc3MgPSBtb2R1bGUuZXhwb3J0c1tpXTtcblxuICBpZiAocGFja2V0Q2xhc3MgIT0gdW5kZWZpbmVkKVxuICAgIHBhY2tldENsYXNzLnByb3RvdHlwZS50YWcgPSBlbnVtcy5wYWNrZXRbaV07XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBKWEcgPSByZXF1aXJlKCcuLi9jb21wcmVzc2lvbi9qeGcuanMnKSxcbiAgYmFzZTY0ID0gcmVxdWlyZSgnLi4vZW5jb2RpbmcvYmFzZTY0LmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBDb21wcmVzc2VkIERhdGEgUGFja2V0IChUYWcgOClcbiAqIFxuICogUkZDNDg4MCA1LjY6XG4gKiBUaGUgQ29tcHJlc3NlZCBEYXRhIHBhY2tldCBjb250YWlucyBjb21wcmVzc2VkIGRhdGEuICBUeXBpY2FsbHksIHRoaXNcbiAqIHBhY2tldCBpcyBmb3VuZCBhcyB0aGUgY29udGVudHMgb2YgYW4gZW5jcnlwdGVkIHBhY2tldCwgb3IgZm9sbG93aW5nXG4gKiBhIFNpZ25hdHVyZSBvciBPbmUtUGFzcyBTaWduYXR1cmUgcGFja2V0LCBhbmQgY29udGFpbnMgYSBsaXRlcmFsIGRhdGFcbiAqIHBhY2tldC5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfY29tcHJlc3NlZCgpIHtcbiAgLyoqIEB0eXBlIHtwYWNrZXRsaXN0fSAqL1xuICB0aGlzLnBhY2tldHM7XG4gIC8qKiBAdHlwZSB7Y29tcHJlc3Npb259ICovXG4gIHRoaXMuYWxnb3JpdGhtID0gJ3VuY29tcHJlc3NlZCc7XG5cbiAgdGhpcy5jb21wcmVzc2VkID0gbnVsbDtcblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciB0aGUgcGFja2V0LlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyA4IHBhY2tldFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJBTSB7aU5URUdFUn0gTEVOIGxFTkdUSCBPRiB0aGUgcGFja2V0IG9yIHRoZSByZW1haW5pbmcgbGVuZ3RoIG9mIFxuICAgKiBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9jb21wcmVzc2VkfSBPYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgLy8gT25lIG9jdGV0IHRoYXQgZ2l2ZXMgdGhlIGFsZ29yaXRobSB1c2VkIHRvIGNvbXByZXNzIHRoZSBwYWNrZXQuXG4gICAgdGhpcy5hbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLmNvbXByZXNzaW9uLCBieXRlcy5jaGFyQ29kZUF0KDApKTtcblxuICAgIC8vIENvbXByZXNzZWQgZGF0YSwgd2hpY2ggbWFrZXMgdXAgdGhlIHJlbWFpbmRlciBvZiB0aGUgcGFja2V0LlxuICAgIHRoaXMuY29tcHJlc3NlZCA9IGJ5dGVzLnN1YnN0cigxKTtcblxuICAgIHRoaXMuZGVjb21wcmVzcygpO1xuICB9XG5cblxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5jb21wcmVzc2VkID09IG51bGwpXG4gICAgICB0aGlzLmNvbXByZXNzKCk7XG5cbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5jb21wcmVzc2lvbiwgdGhpcy5hbGdvcml0aG0pKSArIHRoaXMuY29tcHJlc3NlZDtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIERlY29tcHJlc3Npb24gbWV0aG9kIGZvciBkZWNvbXByZXNzaW5nIHRoZSBjb21wcmVzc2VkIGRhdGFcbiAgICogcmVhZCBieSByZWFkX3BhY2tldFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBkZWNvbXByZXNzZWQgZGF0YVxuICAgKi9cbiAgdGhpcy5kZWNvbXByZXNzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGRlY29tcHJlc3NlZDtcblxuICAgIHN3aXRjaCAodGhpcy5hbGdvcml0aG0pIHtcbiAgICAgIGNhc2UgJ3VuY29tcHJlc3NlZCc6XG4gICAgICAgIGRlY29tcHJlc3NlZCA9IHRoaXMuY29tcHJlc3NlZDtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3ppcCc6XG4gICAgICAgIHZhciBjb21wRGF0YSA9IHRoaXMuY29tcHJlc3NlZDtcblxuICAgICAgICB2YXIgcmFkaXggPSBiYXNlNjQuZW5jb2RlKGNvbXBEYXRhKS5yZXBsYWNlKC9cXG4vZywgXCJcIik7XG4gICAgICAgIC8vIG5vIGhlYWRlciBpbiB0aGlzIGNhc2UsIGRpcmVjdGx5IGNhbGwgZGVmbGF0ZVxuICAgICAgICB2YXIganhnX29iaiA9IG5ldyBKWEcuVXRpbC5VbnppcChKWEcuVXRpbC5CYXNlNjQuZGVjb2RlQXNBcnJheShyYWRpeCkpO1xuXG4gICAgICAgIGRlY29tcHJlc3NlZCA9IHVuZXNjYXBlKGp4Z19vYmouZGVmbGF0ZSgpWzBdWzBdKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3psaWInOlxuICAgICAgICAvL1JGQyAxOTUwLiBCaXRzIDAtMyBDb21wcmVzc2lvbiBNZXRob2RcbiAgICAgICAgdmFyIGNvbXByZXNzaW9uTWV0aG9kID0gdGhpcy5jb21wcmVzc2VkLmNoYXJDb2RlQXQoMCkgJSAweDEwO1xuXG4gICAgICAgIC8vQml0cyA0LTcgUkZDIDE5NTAgYXJlIExaNzcgV2luZG93LiBHZW5lcmFsbHkgdGhpcyB2YWx1ZSBpcyA3ID09IDMyayB3aW5kb3cgc2l6ZS5cbiAgICAgICAgLy8gMm5kIEJ5dGUgaW4gUkZDIDE5NTAgaXMgZm9yIFwiRkxBR3NcIiBBbGxvd3MgZm9yIGEgRGljdGlvbmFyeSBcbiAgICAgICAgLy8gKGhvdyBpcyB0aGlzIGRlZmluZWQpLiBCYXNpYyBjaGVja3N1bSwgYW5kIGNvbXByZXNzaW9uIGxldmVsLlxuXG4gICAgICAgIGlmIChjb21wcmVzc2lvbk1ldGhvZCA9PSA4KSB7IC8vQ00gOCBpcyBmb3IgREVGTEFURSwgUkZDIDE5NTFcbiAgICAgICAgICAvLyByZW1vdmUgNCBieXRlcyBBRExFUjMyIGNoZWNrc3VtIGZyb20gdGhlIGVuZFxuICAgICAgICAgIHZhciBjb21wRGF0YSA9IHRoaXMuY29tcHJlc3NlZC5zdWJzdHJpbmcoMCwgdGhpcy5jb21wcmVzc2VkLmxlbmd0aCAtIDQpO1xuICAgICAgICAgIHZhciByYWRpeCA9IGJhc2U2NC5lbmNvZGUoY29tcERhdGEpLnJlcGxhY2UoL1xcbi9nLCBcIlwiKTtcbiAgICAgICAgICAvL1RPRE8gY2hlY2sgQURMRVIzMiBjaGVja3N1bVxuICAgICAgICAgIGRlY29tcHJlc3NlZCA9IEpYRy5kZWNvbXByZXNzKHJhZGl4KTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHV0aWwucHJpbnRfZXJyb3IoXCJDb21wcmVzc2lvbiBhbGdvcml0aG0gWkxJQiBvbmx5IHN1cHBvcnRzIFwiICtcbiAgICAgICAgICAgIFwiREVGTEFURSBjb21wcmVzc2lvbiBtZXRob2QuXCIpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdiemlwMic6XG4gICAgICAgIC8vIFRPRE86IG5lZWQgdG8gaW1wbGVtZW50IHRoaXNcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb21wcmVzc2lvbiBhbGdvcml0aG0gQlppcDIgW0JaMl0gaXMgbm90IGltcGxlbWVudGVkLicpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIHVua25vd24gOlwiICsgdGhpcy5hbG9ncml0aG0pO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLnBhY2tldHMucmVhZChkZWNvbXByZXNzZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXByZXNzIHRoZSBwYWNrZXQgZGF0YSAobWVtYmVyIGRlY29tcHJlc3NlZERhdGEpXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gdHlwZSBBbGdvcml0aG0gdG8gYmUgdXNlZCAvLyBTZWUgUkZDIDQ4ODAgOS4zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIERhdGEgdG8gYmUgY29tcHJlc3NlZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSBjb21wcmVzc2VkIGRhdGEgc3RvcmVkIGluIGF0dHJpYnV0ZSBjb21wcmVzc2VkRGF0YVxuICAgKi9cbiAgdGhpcy5jb21wcmVzcyA9IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5hbGdvcml0aG0pIHtcblxuICAgICAgY2FzZSAndW5jb21wcmVzc2VkJzpcbiAgICAgICAgLy8gLSBVbmNvbXByZXNzZWRcbiAgICAgICAgdGhpcy5jb21wcmVzc2VkID0gdGhpcy5wYWNrZXRzLndyaXRlKCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd6aXAnOlxuICAgICAgICAvLyAtIFpJUCBbUkZDMTk1MV1cbiAgICAgICAgdXRpbC5wcmludF9lcnJvcihcIkNvbXByZXNzaW9uIGFsZ29yaXRobSBaSVAgW1JGQzE5NTFdIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd6bGliJzpcbiAgICAgICAgLy8gLSBaTElCIFtSRkMxOTUwXVxuICAgICAgICAvLyBUT0RPOiBuZWVkIHRvIGltcGxlbWVudCB0aGlzXG4gICAgICAgIHV0aWwucHJpbnRfZXJyb3IoXCJDb21wcmVzc2lvbiBhbGdvcml0aG0gWkxJQiBbUkZDMTk1MF0gaXMgbm90IGltcGxlbWVudGVkLlwiKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2J6aXAyJzpcbiAgICAgICAgLy8gIC0gQlppcDIgW0JaMl1cbiAgICAgICAgLy8gVE9ETzogbmVlZCB0byBpbXBsZW1lbnQgdGhpc1xuICAgICAgICB1dGlsLnByaW50X2Vycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIEJaaXAyIFtCWjJdIGlzIG5vdCBpbXBsZW1lbnRlZC5cIik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB1dGlsLnByaW50X2Vycm9yKFwiQ29tcHJlc3Npb24gYWxnb3JpdGhtIHVua25vd24gOlwiICsgdGhpcy50eXBlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59O1xuIiwidmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGxpc3Q6IHJlcXVpcmUoJy4vcGFja2V0bGlzdC5qcycpLFxufTtcblxudmFyIHBhY2tldHMgPSByZXF1aXJlKCcuL2FsbF9wYWNrZXRzLmpzJyk7XG5cbmZvciAodmFyIGkgaW4gcGFja2V0cylcbiAgbW9kdWxlLmV4cG9ydHNbaV0gPSBwYWNrZXRzW2ldO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIExpdGVyYWwgRGF0YSBQYWNrZXQgKFRhZyAxMSlcbiAqIFxuICogUkZDNDg4MCA1Ljk6IEEgTGl0ZXJhbCBEYXRhIHBhY2tldCBjb250YWlucyB0aGUgYm9keSBvZiBhIG1lc3NhZ2U7IGRhdGEgdGhhdFxuICogaXMgbm90IHRvIGJlIGZ1cnRoZXIgaW50ZXJwcmV0ZWQuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X2xpdGVyYWwoKSB7XG4gIHRoaXMuZm9ybWF0ID0gJ3V0ZjgnO1xuICB0aGlzLmRhdGEgPSAnJztcbiAgdGhpcy5kYXRlID0gbmV3IERhdGUoKTtcblxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHBhY2tldCBkYXRhIHRvIGEgamF2YXNjcmlwdCBuYXRpdmUgc3RyaW5nIG9yIGEgc3F1ZW5jZSBvZiBcbiAgICogYnl0ZXMuIENvbnZlcnNpb24gdG8gYSBwcm9wZXIgdXRmOCBlbmNvZGluZyB0YWtlcyBwbGFjZSB3aGVuIHRoZSBcbiAgICogcGFja2V0IGlzIHdyaXR0ZW4uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgQW55IG5hdGl2ZSBqYXZhc2NyaXB0IHN0cmluZ1xuICAgKiBAcGFyYW0ge29wZW5wZ3BfcGFja2V0X2xpdGVyYWxkYXRhLmZvcm1hdH0gZm9ybWF0IFxuICAgKi9cbiAgdGhpcy5zZXQgPSBmdW5jdGlvbihzdHIsIGZvcm1hdCkge1xuICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0O1xuICAgIHRoaXMuZGF0YSA9IHN0cjtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHBhY2tldCBkYXRhIHRvIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHRoZSBwcm92aWRlZCBzdHJpbmdcbiAgICogb2YgYnl0ZXMgdG9nZXRoZXIgd2l0aCB0aGUgYXBwcm9wcmlhdGUgY29udmVyc2lvbiBmb3JtYXQuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBieXRlcyBUaGUgc3RyaW5nIG9mIGJ5dGVzXG4gICAqIEBwYXJhbSB7b3BlbnBncF9wYWNrZXRfbGl0ZXJhbGRhdGEuZm9ybWF0fSBmb3JtYXRcbiAgICovXG4gIHRoaXMuc2V0Qnl0ZXMgPSBmdW5jdGlvbihieXRlcywgZm9ybWF0KSB7XG4gICAgdGhpcy5mb3JtYXQgPSBmb3JtYXQ7XG5cbiAgICBpZiAoZm9ybWF0ID09ICd1dGY4JylcbiAgICAgIGJ5dGVzID0gdXRpbC5kZWNvZGVfdXRmOChieXRlcyk7XG5cbiAgICB0aGlzLmRhdGEgPSBieXRlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGJ5dGUgc2VxdWVuY2UgcmVwcmVzZW50aW5nIHRoZSBsaXRlcmFsIHBhY2tldCBkYXRhXG4gICAqIEByZXR1cm5zIHtTdHJpbmd9IEEgc2VxdWVuY2Ugb2YgYnl0ZXNcbiAgICovXG4gIHRoaXMuZ2V0Qnl0ZXMgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5mb3JtYXQgPT0gJ3V0ZjgnKVxuICAgICAgcmV0dXJuIHV0aWwuZW5jb2RlX3V0ZjgodGhpcy5kYXRhKTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gdGhpcy5kYXRhO1xuICB9XG5cblxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgKHRhZyAxMSkuXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBhIHRhZyAxMSBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvblxuICAgKiAgICAgICAgICAgIFBvc2l0aW9uIHRvIHN0YXJ0IHJlYWRpbmcgZnJvbSB0aGUgaW5wdXQgc3RyaW5nXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuXG4gICAqICAgICAgICAgICAgTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2ZcbiAgICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBvYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgLy8gLSBBIG9uZS1vY3RldCBmaWVsZCB0aGF0IGRlc2NyaWJlcyBob3cgdGhlIGRhdGEgaXMgZm9ybWF0dGVkLlxuXG4gICAgdmFyIGZvcm1hdCA9IGVudW1zLnJlYWQoZW51bXMubGl0ZXJhbCwgYnl0ZXNbMF0uY2hhckNvZGVBdCgpKTtcblxuICAgIHZhciBmaWxlbmFtZV9sZW4gPSBieXRlcy5jaGFyQ29kZUF0KDEpO1xuICAgIHRoaXMuZmlsZW5hbWUgPSB1dGlsLmRlY29kZV91dGY4KGJ5dGVzLnN1YnN0cigyLCBmaWxlbmFtZV9sZW4pKTtcblxuICAgIHRoaXMuZGF0ZSA9IHV0aWwucmVhZERhdGUoYnl0ZXMuc3Vic3RyKDIgKyBmaWxlbmFtZV9sZW4sIDQpKTtcblxuICAgIHZhciBkYXRhID0gYnl0ZXMuc3Vic3RyaW5nKDYgKyBmaWxlbmFtZV9sZW4pO1xuXG4gICAgdGhpcy5zZXRCeXRlcyhkYXRhLCBmb3JtYXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHBhY2tldFxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgVGhlIGRhdGEgdG8gYmUgaW5zZXJ0ZWQgYXMgYm9keVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IHN0cmluZy1yZXByZXNlbnRhdGlvbiBvZiB0aGUgcGFja2V0XG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGZpbGVuYW1lID0gdXRpbC5lbmNvZGVfdXRmOChcIm1zZy50eHRcIik7XG5cbiAgICB2YXIgZGF0YSA9IHRoaXMuZ2V0Qnl0ZXMoKTtcblxuICAgIHZhciByZXN1bHQgPSAnJztcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5saXRlcmFsLCB0aGlzLmZvcm1hdCkpO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGZpbGVuYW1lLmxlbmd0aCk7XG4gICAgcmVzdWx0ICs9IGZpbGVuYW1lO1xuICAgIHJlc3VsdCArPSB1dGlsLndyaXRlRGF0ZSh0aGlzLmRhdGUpO1xuICAgIHJlc3VsdCArPSBkYXRhO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIEltcGxlbWVudGF0aW9uIG9mIHRoZSBzdHJhbmdlIFwiTWFya2VyIHBhY2tldFwiIChUYWcgMTApXG4gKiBcbiAqIFJGQzQ4ODAgNS44OiBBbiBleHBlcmltZW50YWwgdmVyc2lvbiBvZiBQR1AgdXNlZCB0aGlzIHBhY2tldCBhcyB0aGUgTGl0ZXJhbFxuICogcGFja2V0LCBidXQgbm8gcmVsZWFzZWQgdmVyc2lvbiBvZiBQR1AgZ2VuZXJhdGVkIExpdGVyYWwgcGFja2V0cyB3aXRoIHRoaXNcbiAqIHRhZy4gV2l0aCBQR1AgNS54LCB0aGlzIHBhY2tldCBoYXMgYmVlbiByZWFzc2lnbmVkIGFuZCBpcyByZXNlcnZlZCBmb3IgdXNlIGFzXG4gKiB0aGUgTWFya2VyIHBhY2tldC5cbiAqIFxuICogU3VjaCBhIHBhY2tldCBNVVNUIGJlIGlnbm9yZWQgd2hlbiByZWNlaXZlZC5cbiAqL1xuZnVuY3Rpb24gcGFja2V0X21hcmtlcigpIHtcbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgbGl0ZXJhbCBkYXRhIHBhY2tldCAodGFnIDEwKS5cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDEwIHBhY2tldFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvc2l0aW9uXG4gICAqICAgICAgICAgICAgUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5cbiAgICogICAgICAgICAgICBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZlxuICAgKiAgICAgICAgICAgIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IE9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICBpZiAoYnl0ZXNbMF0uY2hhckNvZGVBdCgpID09IDB4NTAgJiYgLy8gUFxuICAgIGJ5dGVzWzFdLmNoYXJDb2RlQXQoKSA9PSAweDQ3ICYmIC8vIEdcbiAgICBieXRlc1syXS5jaGFyQ29kZUF0KCkgPT0gMHg1MCkgLy8gUFxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgLy8gbWFya2VyIHBhY2tldCBkb2VzIG5vdCBjb250YWluIFwiUEdQXCJcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBwYWNrZXRfbWFya2VyO1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIE9uZS1QYXNzIFNpZ25hdHVyZSBQYWNrZXRzIChUYWcgNClcbiAqIFxuICogUkZDNDg4MCA1LjQ6XG4gKiBUaGUgT25lLVBhc3MgU2lnbmF0dXJlIHBhY2tldCBwcmVjZWRlcyB0aGUgc2lnbmVkIGRhdGEgYW5kIGNvbnRhaW5zXG4gKiBlbm91Z2ggaW5mb3JtYXRpb24gdG8gYWxsb3cgdGhlIHJlY2VpdmVyIHRvIGJlZ2luIGNhbGN1bGF0aW5nIGFueVxuICogaGFzaGVzIG5lZWRlZCB0byB2ZXJpZnkgdGhlIHNpZ25hdHVyZS4gIEl0IGFsbG93cyB0aGUgU2lnbmF0dXJlXG4gKiBwYWNrZXQgdG8gYmUgcGxhY2VkIGF0IHRoZSBlbmQgb2YgdGhlIG1lc3NhZ2UsIHNvIHRoYXQgdGhlIHNpZ25lclxuICogY2FuIGNvbXB1dGUgdGhlIGVudGlyZSBzaWduZWQgbWVzc2FnZSBpbiBvbmUgcGFzcy5cbiAqL1xuXG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICB0eXBlX2tleWlkID0gcmVxdWlyZSgnLi4vdHlwZS9rZXlpZC5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9vbmVfcGFzc19zaWduYXR1cmUoKSB7XG4gIHRoaXMudmVyc2lvbiA9IG51bGw7IC8vIEEgb25lLW9jdGV0IHZlcnNpb24gbnVtYmVyLiAgVGhlIGN1cnJlbnQgdmVyc2lvbiBpcyAzLlxuICB0aGlzLnR5cGUgPSBudWxsOyAvLyBBIG9uZS1vY3RldCBzaWduYXR1cmUgdHlwZS4gIFNpZ25hdHVyZSB0eXBlcyBhcmUgZGVzY3JpYmVkIGluIFJGQzQ4ODAgU2VjdGlvbiA1LjIuMS5cbiAgdGhpcy5oYXNoQWxnb3JpdGhtID0gbnVsbDsgLy8gQSBvbmUtb2N0ZXQgbnVtYmVyIGRlc2NyaWJpbmcgdGhlIGhhc2ggYWxnb3JpdGhtIHVzZWQuIChTZWUgUkZDNDg4MCA5LjQpXG4gIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gbnVsbDsgLy8gQSBvbmUtb2N0ZXQgbnVtYmVyIGRlc2NyaWJpbmcgdGhlIHB1YmxpYy1rZXkgYWxnb3JpdGhtIHVzZWQuIChTZWUgUkZDNDg4MCA5LjEpXG4gIHRoaXMuc2lnbmluZ0tleUlkID0gbnVsbDsgLy8gQW4gZWlnaHQtb2N0ZXQgbnVtYmVyIGhvbGRpbmcgdGhlIEtleSBJRCBvZiB0aGUgc2lnbmluZyBrZXkuXG4gIHRoaXMuZmxhZ3MgPSBudWxsOyAvLyAgQSBvbmUtb2N0ZXQgbnVtYmVyIGhvbGRpbmcgYSBmbGFnIHNob3dpbmcgd2hldGhlciB0aGUgc2lnbmF0dXJlIGlzIG5lc3RlZC4gIEEgemVybyB2YWx1ZSBpbmRpY2F0ZXMgdGhhdCB0aGUgbmV4dCBwYWNrZXQgaXMgYW5vdGhlciBPbmUtUGFzcyBTaWduYXR1cmUgcGFja2V0IHRoYXQgZGVzY3JpYmVzIGFub3RoZXIgc2lnbmF0dXJlIHRvIGJlIGFwcGxpZWQgdG8gdGhlIHNhbWUgbWVzc2FnZSBkYXRhLlxuXG4gIC8qKlxuICAgKiBwYXJzaW5nIGZ1bmN0aW9uIGZvciBhIG9uZS1wYXNzIHNpZ25hdHVyZSBwYWNrZXQgKHRhZyA0KS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGJ5dGVzIHBheWxvYWQgb2YgYSB0YWcgNCBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGJ5dGVzIHN0cmluZ1xuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBsZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBieXRlcyBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBvYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIG15cG9zID0gMDtcbiAgICAvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gIFRoZSBjdXJyZW50IHZlcnNpb24gaXMgMy5cbiAgICB0aGlzLnZlcnNpb24gPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuXG4gICAgLy8gQSBvbmUtb2N0ZXQgc2lnbmF0dXJlIHR5cGUuICBTaWduYXR1cmUgdHlwZXMgYXJlIGRlc2NyaWJlZCBpblxuICAgIC8vICAgU2VjdGlvbiA1LjIuMS5cbiAgICB0aGlzLnR5cGUgPSBlbnVtcy5yZWFkKGVudW1zLnNpZ25hdHVyZSwgYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKSk7XG5cbiAgICAvLyBBIG9uZS1vY3RldCBudW1iZXIgZGVzY3JpYmluZyB0aGUgaGFzaCBhbGdvcml0aG0gdXNlZC5cbiAgICB0aGlzLmhhc2hBbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLmhhc2gsIGJ5dGVzLmNoYXJDb2RlQXQobXlwb3MrKykpO1xuXG4gICAgLy8gQSBvbmUtb2N0ZXQgbnVtYmVyIGRlc2NyaWJpbmcgdGhlIHB1YmxpYy1rZXkgYWxnb3JpdGhtIHVzZWQuXG4gICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSwgYnl0ZXMuY2hhckNvZGVBdChteXBvcysrKSk7XG5cbiAgICAvLyBBbiBlaWdodC1vY3RldCBudW1iZXIgaG9sZGluZyB0aGUgS2V5IElEIG9mIHRoZSBzaWduaW5nIGtleS5cbiAgICB0aGlzLnNpZ25pbmdLZXlJZCA9IG5ldyB0eXBlX2tleWlkKCk7XG4gICAgdGhpcy5zaWduaW5nS2V5SWQucmVhZChieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICBteXBvcyArPSA4O1xuXG4gICAgLy8gQSBvbmUtb2N0ZXQgbnVtYmVyIGhvbGRpbmcgYSBmbGFnIHNob3dpbmcgd2hldGhlciB0aGUgc2lnbmF0dXJlXG4gICAgLy8gICBpcyBuZXN0ZWQuICBBIHplcm8gdmFsdWUgaW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcGFja2V0IGlzXG4gICAgLy8gICBhbm90aGVyIE9uZS1QYXNzIFNpZ25hdHVyZSBwYWNrZXQgdGhhdCBkZXNjcmliZXMgYW5vdGhlclxuICAgIC8vICAgc2lnbmF0dXJlIHRvIGJlIGFwcGxpZWQgdG8gdGhlIHNhbWUgbWVzc2FnZSBkYXRhLlxuICAgIHRoaXMuZmxhZ3MgPSBieXRlcy5jaGFyQ29kZUF0KG15cG9zKyspO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIGNyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgYSBvbmUtcGFzcyBzaWduYXR1cmUgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gdHlwZSBTaWduYXR1cmUgdHlwZXMgYXMgZGVzY3JpYmVkIGluIFJGQzQ4ODAgU2VjdGlvbiA1LjIuMS5cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBoYXNoYWxnb3JpdGhtIHRoZSBoYXNoIGFsZ29yaXRobSB1c2VkIHdpdGhpbiB0aGUgc2lnbmF0dXJlXG4gICAqIEBwYXJhbSB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleX0gcHJpdmF0ZWtleSB0aGUgcHJpdmF0ZSBrZXkgdXNlZCB0byBnZW5lcmF0ZSB0aGUgc2lnbmF0dXJlXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIGxlbmd0aCBvZiBkYXRhIHRvIGJlIHNpZ25lZFxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IG5lc3RlZCBib29sZWFuIHNob3dpbmcgd2hldGhlciB0aGUgc2lnbmF0dXJlIGlzIG5lc3RlZC4gXG4gICAqICBcInRydWVcIiBpbmRpY2F0ZXMgdGhhdCB0aGUgbmV4dCBwYWNrZXQgaXMgYW5vdGhlciBPbmUtUGFzcyBTaWduYXR1cmUgcGFja2V0XG4gICAqICAgdGhhdCBkZXNjcmliZXMgYW5vdGhlciBzaWduYXR1cmUgdG8gYmUgYXBwbGllZCB0byB0aGUgc2FtZSBtZXNzYWdlIGRhdGEuIFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgb25lLXBhc3Mgc2lnbmF0dXJlIHBhY2tldFxuICAgKi9cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKHR5cGUsIGhhc2hhbGdvcml0aG0sIHByaXZhdGVrZXksIGxlbmd0aCwgbmVzdGVkKSB7XG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG5cbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgzKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5zaWduYXR1cmUsIHR5cGUpKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG0pKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHByaXZhdGVrZXkuYWxnb3JpdGhtKSk7XG4gICAgcmVzdWx0ICs9IHByaXZhdGVrZXkuZ2V0S2V5SWQoKTtcbiAgICBpZiAobmVzdGVkKVxuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMCk7XG4gICAgZWxzZVxuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMSk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcmVhZFNpbXBsZUxlbmd0aDogZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgbGVuID0gMCxcbiAgICAgIG9mZnNldCxcbiAgICAgIHR5cGUgPSBieXRlc1swXS5jaGFyQ29kZUF0KCk7XG5cblxuICAgIGlmICh0eXBlIDwgMTkyKSB7XG4gICAgICBsZW4gPSBieXRlc1swXS5jaGFyQ29kZUF0KCk7XG4gICAgICBvZmZzZXQgPSAxO1xuICAgIH0gZWxzZSBpZiAodHlwZSA8IDI1NSkge1xuICAgICAgbGVuID0gKChieXRlc1swXS5jaGFyQ29kZUF0KCkgLSAxOTIpIDw8IDgpICsgKGJ5dGVzWzFdLmNoYXJDb2RlQXQoKSkgKyAxOTI7XG4gICAgICBvZmZzZXQgPSAyO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PSAyNTUpIHtcbiAgICAgIGxlbiA9IHV0aWwucmVhZE51bWJlcihieXRlcy5zdWJzdHIoMSwgNCkpO1xuICAgICAgb2Zmc2V0ID0gNTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgbGVuOiBsZW4sXG4gICAgICBvZmZzZXQ6IG9mZnNldFxuICAgIH07XG4gIH0sXG5cbiAgLyoqXG4gICAqIEVuY29kZXMgYSBnaXZlbiBpbnRlZ2VyIG9mIGxlbmd0aCB0byB0aGUgb3BlbnBncCBsZW5ndGggc3BlY2lmaWVyIHRvIGFcbiAgICogc3RyaW5nXG4gICAqIFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbmd0aCBUaGUgbGVuZ3RoIHRvIGVuY29kZVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyB3aXRoIG9wZW5wZ3AgbGVuZ3RoIHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB3cml0ZVNpbXBsZUxlbmd0aDogZnVuY3Rpb24obGVuZ3RoKSB7XG4gICAgdmFyIHJlc3VsdCA9IFwiXCI7XG4gICAgaWYgKGxlbmd0aCA8IDE5Mikge1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuZ3RoKTtcbiAgICB9IGVsc2UgaWYgKGxlbmd0aCA+IDE5MSAmJiBsZW5ndGggPCA4Mzg0KSB7XG4gICAgICAvKlxuICAgICAgICogbGV0IGEgPSAodG90YWwgZGF0YSBwYWNrZXQgbGVuZ3RoKSAtIDE5MiBsZXQgYmMgPSB0d28gb2N0ZXRcbiAgICAgICAqIHJlcHJlc2VudGF0aW9uIG9mIGEgbGV0IGQgPSBiICsgMTkyXG4gICAgICAgKi9cbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKCgobGVuZ3RoIC0gMTkyKSA+PiA4KSArIDE5Mik7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgobGVuZ3RoIC0gMTkyKSAmIDB4RkYpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgyNTUpO1xuICAgICAgcmVzdWx0ICs9IHV0aWwud3JpdGVOdW1iZXIobGVuZ3RoLCA0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSxcblxuICAvKipcbiAgICogV3JpdGVzIGEgcGFja2V0IGhlYWRlciB2ZXJzaW9uIDQgd2l0aCB0aGUgZ2l2ZW4gdGFnX3R5cGUgYW5kIGxlbmd0aCB0byBhXG4gICAqIHN0cmluZ1xuICAgKiBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSB0YWdfdHlwZSBUYWcgdHlwZVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbmd0aCBMZW5ndGggb2YgdGhlIHBheWxvYWRcbiAgICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgb2YgdGhlIGhlYWRlclxuICAgKi9cbiAgd3JpdGVIZWFkZXI6IGZ1bmN0aW9uKHRhZ190eXBlLCBsZW5ndGgpIHtcbiAgICAvKiB3ZSdyZSBvbmx5IGdlbmVyYXRpbmcgdjQgcGFja2V0IGhlYWRlcnMgaGVyZSAqL1xuICAgIHZhciByZXN1bHQgPSBcIlwiO1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4QzAgfCB0YWdfdHlwZSk7XG4gICAgcmVzdWx0ICs9IHRoaXMud3JpdGVTaW1wbGVMZW5ndGgobGVuZ3RoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LFxuXG4gIC8qKlxuICAgKiBXcml0ZXMgYSBwYWNrZXQgaGVhZGVyIFZlcnNpb24gMyB3aXRoIHRoZSBnaXZlbiB0YWdfdHlwZSBhbmQgbGVuZ3RoIHRvIGFcbiAgICogc3RyaW5nXG4gICAqIFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHRhZ190eXBlIFRhZyB0eXBlXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gbGVuZ3RoIExlbmd0aCBvZiB0aGUgcGF5bG9hZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyBvZiB0aGUgaGVhZGVyXG4gICAqL1xuICB3cml0ZU9sZEhlYWRlcjogZnVuY3Rpb24odGFnX3R5cGUsIGxlbmd0aCkge1xuICAgIHZhciByZXN1bHQgPSBcIlwiO1xuICAgIGlmIChsZW5ndGggPCAyNTYpIHtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4ODAgfCAodGFnX3R5cGUgPDwgMikpO1xuICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuZ3RoKTtcbiAgICB9IGVsc2UgaWYgKGxlbmd0aCA8IDY1NTM2KSB7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDgwIHwgKHRhZ190eXBlIDw8IDIpIHwgMSk7XG4gICAgICByZXN1bHQgKz0gdXRpbC53cml0ZU51bWJlcihsZW5ndGgsIDIpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweDgwIHwgKHRhZ190eXBlIDw8IDIpIHwgMik7XG4gICAgICByZXN1bHQgKz0gdXRpbC53cml0ZU51bWJlcihsZW5ndGgsIDQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9LFxuXG4gIC8qKlxuICAgKiBHZW5lcmljIHN0YXRpYyBQYWNrZXQgUGFyc2VyIGZ1bmN0aW9uXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgSW5wdXQgc3RyZWFtIGFzIHN0cmluZ1xuICAgKiBAcGFyYW0ge2ludGVnZXJ9IHBvc2l0aW9uIFBvc2l0aW9uIHRvIHN0YXJ0IHBhcnNpbmdcbiAgICogQHBhcmFtIHtpbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBpbnB1dCBmcm9tIHBvc2l0aW9uIG9uXG4gICAqIEByZXR1cm4ge09iamVjdH0gUmV0dXJucyBhIHBhcnNlZCBvcGVucGdwX3BhY2tldFxuICAgKi9cbiAgcmVhZDogZnVuY3Rpb24oaW5wdXQsIHBvc2l0aW9uLCBsZW4pIHtcbiAgICAvLyBzb21lIHNhbml0eSBjaGVja3NcbiAgICBpZiAoaW5wdXQgPT0gbnVsbCB8fCBpbnB1dC5sZW5ndGggPD0gcG9zaXRpb24gfHwgaW5wdXQuc3Vic3RyaW5nKHBvc2l0aW9uKS5sZW5ndGggPCAyIHx8IChpbnB1dFtwb3NpdGlvbl0uY2hhckNvZGVBdCgpICZcbiAgICAgIDB4ODApID09IDApIHtcbiAgICAgIHV0aWxcbiAgICAgICAgLnByaW50X2Vycm9yKFwiRXJyb3IgZHVyaW5nIHBhcnNpbmcuIFRoaXMgbWVzc2FnZSAvIGtleSBpcyBwcm9iYWJseSBub3QgY29udGFpbmluZyBhIHZhbGlkIE9wZW5QR1AgZm9ybWF0LlwiKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB2YXIgbXlwb3MgPSBwb3NpdGlvbjtcbiAgICB2YXIgdGFnID0gLTE7XG4gICAgdmFyIGZvcm1hdCA9IC0xO1xuICAgIHZhciBwYWNrZXRfbGVuZ3RoO1xuXG4gICAgZm9ybWF0ID0gMDsgLy8gMCA9IG9sZCBmb3JtYXQ7IDEgPSBuZXcgZm9ybWF0XG4gICAgaWYgKChpbnB1dFtteXBvc10uY2hhckNvZGVBdCgpICYgMHg0MCkgIT0gMCkge1xuICAgICAgZm9ybWF0ID0gMTtcbiAgICB9XG5cbiAgICB2YXIgcGFja2V0X2xlbmd0aF90eXBlO1xuICAgIGlmIChmb3JtYXQpIHtcbiAgICAgIC8vIG5ldyBmb3JtYXQgaGVhZGVyXG4gICAgICB0YWcgPSBpbnB1dFtteXBvc10uY2hhckNvZGVBdCgpICYgMHgzRjsgLy8gYml0IDUtMFxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBvbGQgZm9ybWF0IGhlYWRlclxuICAgICAgdGFnID0gKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgJiAweDNGKSA+PiAyOyAvLyBiaXQgNS0yXG4gICAgICBwYWNrZXRfbGVuZ3RoX3R5cGUgPSBpbnB1dFtteXBvc10uY2hhckNvZGVBdCgpICYgMHgwMzsgLy8gYml0IDEtMFxuICAgIH1cblxuICAgIC8vIGhlYWRlciBvY3RldCBwYXJzaW5nIGRvbmVcbiAgICBteXBvcysrO1xuXG4gICAgLy8gcGFyc2VkIGxlbmd0aCBmcm9tIGxlbmd0aCBmaWVsZFxuICAgIHZhciBib2R5ZGF0YSA9IG51bGw7XG5cbiAgICAvLyB1c2VkIGZvciBwYXJ0aWFsIGJvZHkgbGVuZ3Roc1xuICAgIHZhciByZWFsX3BhY2tldF9sZW5ndGggPSAtMTtcbiAgICBpZiAoIWZvcm1hdCkge1xuICAgICAgLy8gNC4yLjEuIE9sZCBGb3JtYXQgUGFja2V0IExlbmd0aHNcbiAgICAgIHN3aXRjaCAocGFja2V0X2xlbmd0aF90eXBlKSB7XG4gICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAvLyBUaGUgcGFja2V0IGhhcyBhIG9uZS1vY3RldCBsZW5ndGguIFRoZSBoZWFkZXIgaXMgMiBvY3RldHNcbiAgICAgICAgICAvLyBsb25nLlxuICAgICAgICAgIHBhY2tldF9sZW5ndGggPSBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAvLyBUaGUgcGFja2V0IGhhcyBhIHR3by1vY3RldCBsZW5ndGguIFRoZSBoZWFkZXIgaXMgMyBvY3RldHNcbiAgICAgICAgICAvLyBsb25nLlxuICAgICAgICAgIHBhY2tldF9sZW5ndGggPSAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8IDgpIHwgaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgLy8gVGhlIHBhY2tldCBoYXMgYSBmb3VyLW9jdGV0IGxlbmd0aC4gVGhlIGhlYWRlciBpcyA1XG4gICAgICAgICAgLy8gb2N0ZXRzIGxvbmcuXG4gICAgICAgICAgcGFja2V0X2xlbmd0aCA9IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgMjQpIHwgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCAxNikgfCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8XG4gICAgICAgICAgICA4KSB8IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvLyAzIC0gVGhlIHBhY2tldCBpcyBvZiBpbmRldGVybWluYXRlIGxlbmd0aC4gVGhlIGhlYWRlciBpcyAxXG4gICAgICAgICAgLy8gb2N0ZXQgbG9uZywgYW5kIHRoZSBpbXBsZW1lbnRhdGlvbiBtdXN0IGRldGVybWluZSBob3cgbG9uZ1xuICAgICAgICAgIC8vIHRoZSBwYWNrZXQgaXMuIElmIHRoZSBwYWNrZXQgaXMgaW4gYSBmaWxlLCB0aGlzIG1lYW5zIHRoYXRcbiAgICAgICAgICAvLyB0aGUgcGFja2V0IGV4dGVuZHMgdW50aWwgdGhlIGVuZCBvZiB0aGUgZmlsZS4gSW4gZ2VuZXJhbCwgXG4gICAgICAgICAgLy8gYW4gaW1wbGVtZW50YXRpb24gU0hPVUxEIE5PVCB1c2UgaW5kZXRlcm1pbmF0ZS1sZW5ndGggXG4gICAgICAgICAgLy8gcGFja2V0cyBleGNlcHQgd2hlcmUgdGhlIGVuZCBvZiB0aGUgZGF0YSB3aWxsIGJlIGNsZWFyIFxuICAgICAgICAgIC8vIGZyb20gdGhlIGNvbnRleHQsIGFuZCBldmVuIHRoZW4gaXQgaXMgYmV0dGVyIHRvIHVzZSBhIFxuICAgICAgICAgIC8vIGRlZmluaXRlIGxlbmd0aCwgb3IgYSBuZXcgZm9ybWF0IGhlYWRlci4gVGhlIG5ldyBmb3JtYXQgXG4gICAgICAgICAgLy8gaGVhZGVycyBkZXNjcmliZWQgYmVsb3cgaGF2ZSBhIG1lY2hhbmlzbSBmb3IgcHJlY2lzZWx5XG4gICAgICAgICAgLy8gZW5jb2RpbmcgZGF0YSBvZiBpbmRldGVybWluYXRlIGxlbmd0aC5cbiAgICAgICAgICBwYWNrZXRfbGVuZ3RoID0gbGVuO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIC8vIDQuMi4yLiBOZXcgRm9ybWF0IFBhY2tldCBMZW5ndGhzXG4gICAge1xuXG4gICAgICAvLyA0LjIuMi4xLiBPbmUtT2N0ZXQgTGVuZ3Roc1xuICAgICAgaWYgKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPCAxOTIpIHtcbiAgICAgICAgcGFja2V0X2xlbmd0aCA9IGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKTtcbiAgICAgICAgdXRpbC5wcmludF9kZWJ1ZyhcIjEgYnl0ZSBsZW5ndGg6XCIgKyBwYWNrZXRfbGVuZ3RoKTtcbiAgICAgICAgLy8gNC4yLjIuMi4gVHdvLU9jdGV0IExlbmd0aHNcbiAgICAgIH0gZWxzZSBpZiAoaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSA+PSAxOTIgJiYgaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSA8IDIyNCkge1xuICAgICAgICBwYWNrZXRfbGVuZ3RoID0gKChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgLSAxOTIpIDw8IDgpICsgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSkgKyAxOTI7XG4gICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCIyIGJ5dGUgbGVuZ3RoOlwiICsgcGFja2V0X2xlbmd0aCk7XG4gICAgICAgIC8vIDQuMi4yLjQuIFBhcnRpYWwgQm9keSBMZW5ndGhzXG4gICAgICB9IGVsc2UgaWYgKGlucHV0W215cG9zXS5jaGFyQ29kZUF0KCkgPiAyMjMgJiYgaW5wdXRbbXlwb3NdLmNoYXJDb2RlQXQoKSA8IDI1NSkge1xuICAgICAgICBwYWNrZXRfbGVuZ3RoID0gMSA8PCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpICYgMHgxRik7XG4gICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCI0IGJ5dGUgbGVuZ3RoOlwiICsgcGFja2V0X2xlbmd0aCk7XG4gICAgICAgIC8vIEVFRUssIHdlJ3JlIHJlYWRpbmcgdGhlIGZ1bGwgZGF0YSBoZXJlLi4uXG4gICAgICAgIHZhciBteXBvczIgPSBteXBvcyArIHBhY2tldF9sZW5ndGg7XG4gICAgICAgIGJvZHlkYXRhID0gaW5wdXQuc3Vic3RyaW5nKG15cG9zLCBteXBvcyArIHBhY2tldF9sZW5ndGgpO1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgIGlmIChpbnB1dFtteXBvczJdLmNoYXJDb2RlQXQoKSA8IDE5Mikge1xuICAgICAgICAgICAgdmFyIHRtcGxlbiA9IGlucHV0W215cG9zMisrXS5jaGFyQ29kZUF0KCk7XG4gICAgICAgICAgICBwYWNrZXRfbGVuZ3RoICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJvZHlkYXRhICs9IGlucHV0LnN1YnN0cmluZyhteXBvczIsIG15cG9zMiArIHRtcGxlbik7XG4gICAgICAgICAgICBteXBvczIgKz0gdG1wbGVuO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfSBlbHNlIGlmIChpbnB1dFtteXBvczJdLmNoYXJDb2RlQXQoKSA+PSAxOTIgJiYgaW5wdXRbbXlwb3MyXS5jaGFyQ29kZUF0KCkgPCAyMjQpIHtcbiAgICAgICAgICAgIHZhciB0bXBsZW4gPSAoKGlucHV0W215cG9zMisrXS5jaGFyQ29kZUF0KCkgLSAxOTIpIDw8IDgpICsgKGlucHV0W215cG9zMisrXS5jaGFyQ29kZUF0KCkpICsgMTkyO1xuICAgICAgICAgICAgcGFja2V0X2xlbmd0aCArPSB0bXBsZW47XG4gICAgICAgICAgICBib2R5ZGF0YSArPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MyLCBteXBvczIgKyB0bXBsZW4pO1xuICAgICAgICAgICAgbXlwb3MyICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaW5wdXRbbXlwb3MyXS5jaGFyQ29kZUF0KCkgPiAyMjMgJiYgaW5wdXRbbXlwb3MyXS5jaGFyQ29kZUF0KCkgPCAyNTUpIHtcbiAgICAgICAgICAgIHZhciB0bXBsZW4gPSAxIDw8IChpbnB1dFtteXBvczIrK10uY2hhckNvZGVBdCgpICYgMHgxRik7XG4gICAgICAgICAgICBwYWNrZXRfbGVuZ3RoICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJvZHlkYXRhICs9IGlucHV0LnN1YnN0cmluZyhteXBvczIsIG15cG9zMiArIHRtcGxlbik7XG4gICAgICAgICAgICBteXBvczIgKz0gdG1wbGVuO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBteXBvczIrKztcbiAgICAgICAgICAgIHZhciB0bXBsZW4gPSAoaW5wdXRbbXlwb3MyKytdLmNoYXJDb2RlQXQoKSA8PCAyNCkgfCAoaW5wdXRbbXlwb3MyKytdLmNoYXJDb2RlQXQoKSA8PCAxNikgfCAoaW5wdXRbbXlwb3MyKytdXG4gICAgICAgICAgICAgIC5jaGFyQ29kZUF0KCkgPDwgOCkgfCBpbnB1dFtteXBvczIrK10uY2hhckNvZGVBdCgpO1xuICAgICAgICAgICAgYm9keWRhdGEgKz0gaW5wdXQuc3Vic3RyaW5nKG15cG9zMiwgbXlwb3MyICsgdG1wbGVuKTtcbiAgICAgICAgICAgIHBhY2tldF9sZW5ndGggKz0gdG1wbGVuO1xuICAgICAgICAgICAgbXlwb3MyICs9IHRtcGxlbjtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZWFsX3BhY2tldF9sZW5ndGggPSBteXBvczI7XG4gICAgICAgIC8vIDQuMi4yLjMuIEZpdmUtT2N0ZXQgTGVuZ3Roc1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbXlwb3MrKztcbiAgICAgICAgcGFja2V0X2xlbmd0aCA9IChpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCkgPDwgMjQpIHwgKGlucHV0W215cG9zKytdLmNoYXJDb2RlQXQoKSA8PCAxNikgfCAoaW5wdXRbbXlwb3MrK10uY2hhckNvZGVBdCgpIDw8XG4gICAgICAgICAgOCkgfCBpbnB1dFtteXBvcysrXS5jaGFyQ29kZUF0KCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gaWYgdGhlcmUgd2FzJ250IGEgcGFydGlhbCBib2R5IGxlbmd0aDogdXNlIHRoZSBzcGVjaWZpZWRcbiAgICAvLyBwYWNrZXRfbGVuZ3RoXG4gICAgaWYgKHJlYWxfcGFja2V0X2xlbmd0aCA9PSAtMSkge1xuICAgICAgcmVhbF9wYWNrZXRfbGVuZ3RoID0gcGFja2V0X2xlbmd0aDtcbiAgICB9XG5cbiAgICBpZiAoYm9keWRhdGEgPT0gbnVsbCkge1xuICAgICAgYm9keWRhdGEgPSBpbnB1dC5zdWJzdHJpbmcobXlwb3MsIG15cG9zICsgcmVhbF9wYWNrZXRfbGVuZ3RoKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdGFnOiB0YWcsXG4gICAgICBwYWNrZXQ6IGJvZHlkYXRhLFxuICAgICAgb2Zmc2V0OiBteXBvcyArIHJlYWxfcGFja2V0X2xlbmd0aFxuICAgIH07XG4gIH1cbn1cbiIsInZhciBwYWNrZXRQYXJzZXIgPSByZXF1aXJlKCcuL3BhY2tldC5qcycpLFxuICBwYWNrZXRzID0gcmVxdWlyZSgnLi9hbGxfcGFja2V0cy5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIGxpc3Qgb2Ygb3BlbnBncCBwYWNrZXRzLlxuICogVGFrZSBjYXJlIHdoZW4gaXRlcmF0aW5nIG92ZXIgaXQgLSB0aGUgcGFja2V0cyB0aGVtc2VsdmVzXG4gKiBhcmUgc3RvcmVkIGFzIG51bWVyaWNhbCBpbmRpY2VzLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldGxpc3QoKSB7XG4gIC8qKiBUaGUgbnVtYmVyIG9mIHBhY2tldHMgY29udGFpbmVkIHdpdGhpbiB0aGUgbGlzdC5cbiAgICogQHJlYWRvbmx5XG4gICAqIEB0eXBlIHtJbnRlZ2VyfSAqL1xuICB0aGlzLmxlbmd0aCA9IDA7XG5cblxuXG4gIC8qKlxuICAgKiBSZWFkcyBhIHN0cmVhbSBvZiBiaW5hcnkgZGF0YSBhbmQgaW50ZXJwcmVudHMgaXQgYXMgYSBsaXN0IG9mIHBhY2tldHMuXG4gICAqIEBwYXJhbSB7b3BlbnBncF9ieXRlYXJyYXl9IEFuIGFycmF5IG9mIGJ5dGVzLlxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgaSA9IDA7XG5cbiAgICB3aGlsZSAoaSA8IGJ5dGVzLmxlbmd0aCkge1xuICAgICAgdmFyIHBhcnNlZCA9IHBhY2tldFBhcnNlci5yZWFkKGJ5dGVzLCBpLCBieXRlcy5sZW5ndGggLSBpKTtcbiAgICAgIGkgPSBwYXJzZWQub2Zmc2V0O1xuXG4gICAgICB2YXIgdGFnID0gZW51bXMucmVhZChlbnVtcy5wYWNrZXQsIHBhcnNlZC50YWcpO1xuICAgICAgdmFyIHBhY2tldCA9IG5ldyBwYWNrZXRzW3RhZ10oKTtcblxuICAgICAgdGhpcy5wdXNoKHBhY2tldCk7XG5cbiAgICAgIHBhY2tldC5yZWFkKHBhcnNlZC5wYWNrZXQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgYmluYXJ5IHJlcHJlc2VudGF0aW9uIG9mIG9wZW5wZ3Agb2JqZWN0cyBjb250YWluZWQgd2l0aGluIHRoZVxuICAgKiBjbGFzcyBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge29wZW5wZ3BfYnl0ZWFycmF5fSBBbiBhcnJheSBvZiBieXRlcyBjb250YWluaW5nIHZhbGlkIG9wZW5wZ3AgcGFja2V0cy5cbiAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYnl0ZXMgPSAnJztcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHBhY2tldGJ5dGVzID0gdGhpc1tpXS53cml0ZSgpO1xuICAgICAgYnl0ZXMgKz0gcGFja2V0UGFyc2VyLndyaXRlSGVhZGVyKHRoaXNbaV0udGFnLCBwYWNrZXRieXRlcy5sZW5ndGgpO1xuICAgICAgYnl0ZXMgKz0gcGFja2V0Ynl0ZXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ5dGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBwYWNrZXQgdG8gdGhlIGxpc3QuIFRoaXMgaXMgdGhlIG9ubHkgc3VwcG9ydGVkIG1ldGhvZCBvZiBkb2luZyBzbztcbiAgICogd3JpdGluZyB0byBwYWNrZXRsaXN0W2ldIGRpcmVjdGx5IHdpbGwgcmVzdWx0IGluIGFuIGVycm9yLlxuICAgKi9cbiAgdGhpcy5wdXNoID0gZnVuY3Rpb24ocGFja2V0KSB7XG4gICAgcGFja2V0LnBhY2tldHMgPSBuZXcgcGFja2V0bGlzdCgpO1xuXG4gICAgdGhpc1t0aGlzLmxlbmd0aF0gPSBwYWNrZXQ7XG4gICAgdGhpcy5sZW5ndGgrKztcbiAgfVxuXG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgS2V5IE1hdGVyaWFsIFBhY2tldCAoVGFnIDUsNiw3LDE0KVxuICogICBcbiAqIFJGQzQ0ODAgNS41OlxuICogQSBrZXkgbWF0ZXJpYWwgcGFja2V0IGNvbnRhaW5zIGFsbCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgYSBwdWJsaWMgb3JcbiAqIHByaXZhdGUga2V5LiAgVGhlcmUgYXJlIGZvdXIgdmFyaWFudHMgb2YgdGhpcyBwYWNrZXQgdHlwZSwgYW5kIHR3b1xuICogbWFqb3IgdmVyc2lvbnMuICBDb25zZXF1ZW50bHksIHRoaXMgc2VjdGlvbiBpcyBjb21wbGV4LlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF9wdWJsaWNfa2V5KCkge1xuICAvKiogS2V5IGNyZWF0aW9uIGRhdGUuXG4gICAqIEB0eXBlIHtEYXRlfSAqL1xuICB0aGlzLmNyZWF0ZWQgPSBuZXcgRGF0ZSgpO1xuICAvKiogQSBsaXN0IG9mIG11bHRpcHJlY2lzaW9uIGludGVnZXJzXG4gICAqIEB0eXBlIHtvcGVucGdwX3R5cGVfbXBpfSAqL1xuICB0aGlzLm1waSA9IFtdO1xuICAvKiogUHVibGljIGtleSBhbGdvcml0aG1cbiAgICogQHR5cGUge29wZW5wZ3AucHVibGlja2V5fSAqL1xuICB0aGlzLmFsZ29yaXRobSA9ICdyc2Ffc2lnbic7XG5cblxuICAvKipcbiAgICogSW50ZXJuYWwgUGFyc2VyIGZvciBwdWJsaWMga2V5cyBhcyBzcGVjaWZpZWQgaW4gUkZDIDQ4ODAgc2VjdGlvbiBcbiAgICogNS41LjIgUHVibGljLUtleSBQYWNrZXQgRm9ybWF0c1xuICAgKiBjYWxsZWQgYnkgcmVhZF90YWcmbHQ7bnVtJmd0O1xuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgSW5wdXQgc3RyaW5nIHRvIHJlYWQgdGhlIHBhY2tldCBmcm9tXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gU3RhcnQgcG9zaXRpb24gZm9yIHRoZSBwYXJzZXJcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dFxuICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoaXMgb2JqZWN0IHdpdGggYXR0cmlidXRlcyBzZXQgYnkgdGhlIHBhcnNlclxuICAgKi9cbiAgdGhpcy5yZWFkUHVibGljS2V5ID0gdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlciAoMyBvciA0KS5cbiAgICB2YXIgdmVyc2lvbiA9IGJ5dGVzWzBdLmNoYXJDb2RlQXQoKTtcblxuICAgIGlmICh2ZXJzaW9uID09IDQpIHtcbiAgICAgIC8vIC0gQSBmb3VyLW9jdGV0IG51bWJlciBkZW5vdGluZyB0aGUgdGltZSB0aGF0IHRoZSBrZXkgd2FzIGNyZWF0ZWQuXG4gICAgICB0aGlzLmNyZWF0ZWQgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cigxLCA0KSk7XG5cbiAgICAgIC8vIC0gQSBvbmUtb2N0ZXQgbnVtYmVyIGRlbm90aW5nIHRoZSBwdWJsaWMta2V5IGFsZ29yaXRobSBvZiB0aGlzIGtleS5cbiAgICAgIHRoaXMuYWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5wdWJsaWNLZXksIGJ5dGVzWzVdLmNoYXJDb2RlQXQoKSk7XG5cbiAgICAgIHZhciBtcGljb3VudCA9IGNyeXB0by5nZXRQdWJsaWNNcGlDb3VudCh0aGlzLmFsZ29yaXRobSk7XG4gICAgICB0aGlzLm1waSA9IFtdO1xuXG4gICAgICB2YXIgYm1waSA9IGJ5dGVzLnN1YnN0cig2KTtcbiAgICAgIHZhciBwID0gMDtcblxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtcGljb3VudCAmJiBwIDwgYm1waS5sZW5ndGg7IGkrKykge1xuXG4gICAgICAgIHRoaXMubXBpW2ldID0gbmV3IHR5cGVfbXBpKCk7XG5cbiAgICAgICAgcCArPSB0aGlzLm1waVtpXS5yZWFkKGJtcGkuc3Vic3RyKHApKVxuXG4gICAgICAgIGlmIChwID4gYm1waS5sZW5ndGgpXG4gICAgICAgICAgdXRpbC5wcmludF9lcnJvcihcIm9wZW5wZ3AucGFja2V0LmtleW1hdGVyaWFsLmpzXFxuXCIgKyAnZXJyb3IgcmVhZGluZyBNUEkgQDonICsgcCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwICsgNjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWZXJzaW9uICcgKyB2ZXJzaW9uICsgJyBvZiB0aGUga2V5IHBhY2tldCBpcyB1bnN1cHBvcnRlZC4nKTtcbiAgICB9XG4gIH1cblxuICAvKlxuICAgKiBTYW1lIGFzIHdyaXRlX3ByaXZhdGVfa2V5LCBidXQgaGFzIGxlc3MgaW5mb3JtYXRpb24gYmVjYXVzZSBvZiBcbiAgICogcHVibGljIGtleS5cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBrZXlUeXBlIEZvbGxvd3MgdGhlIE9wZW5QR1AgYWxnb3JpdGhtIHN0YW5kYXJkLCBcbiAgICogSUUgMSBjb3JyZXNwb25kcyB0byBSU0EuXG4gICAqIEBwYXJhbSB7UlNBLmtleU9iamVjdH0ga2V5XG4gICAqIEBwYXJhbSB0aW1lUGFja2V0XG4gICAqIEByZXR1cm4ge09iamVjdH0ge2JvZHk6IFtzdHJpbmddT3BlblBHUCBwYWNrZXQgYm9keSBjb250ZW50cywgXG4gICAqIGhlYWRlcjogW3N0cmluZ10gT3BlblBHUCBwYWNrZXQgaGVhZGVyLCBzdHJpbmc6IFtzdHJpbmddIGhlYWRlcitib2R5fVxuICAgKi9cbiAgdGhpcy53cml0ZVB1YmxpY0tleSA9IHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICAvLyBWZXJzaW9uXG4gICAgdmFyIHJlc3VsdCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoNCk7XG4gICAgcmVzdWx0ICs9IHV0aWwud3JpdGVEYXRlKHRoaXMuY3JlYXRlZCk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMucHVibGljS2V5LCB0aGlzLmFsZ29yaXRobSkpO1xuXG4gICAgdmFyIG1waWNvdW50ID0gY3J5cHRvLmdldFB1YmxpY01waUNvdW50KHRoaXMuYWxnb3JpdGhtKTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXBpY291bnQ7IGkrKykge1xuICAgICAgcmVzdWx0ICs9IHRoaXMubXBpW2ldLndyaXRlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIFdyaXRlIGFuIG9sZCB2ZXJzaW9uIHBhY2tldCAtIGl0J3MgdXNlZCBieSBzb21lIG9mIHRoZSBpbnRlcm5hbCByb3V0aW5lcy5cbiAgdGhpcy53cml0ZU9sZCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBieXRlcyA9IHRoaXMud3JpdGVQdWJsaWNLZXkoKTtcblxuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4OTkpICtcbiAgICAgIHV0aWwud3JpdGVOdW1iZXIoYnl0ZXMubGVuZ3RoLCAyKSArXG4gICAgICBieXRlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIHRoZSBrZXkgaWQgb2YgdGhlIGtleSBcbiAgICogQHJldHVybiB7U3RyaW5nfSBBIDggYnl0ZSBrZXkgaWRcbiAgICovXG4gIHRoaXMuZ2V0S2V5SWQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRGaW5nZXJwcmludCgpLnN1YnN0cigxMiwgOCk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgZmluZ2VycHJpbnQgb2YgdGhlIGtleVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEEgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGZpbmdlcnByaW50XG4gICAqL1xuICB0aGlzLmdldEZpbmdlcnByaW50ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHRvSGFzaCA9IHRoaXMud3JpdGVPbGQoKTtcbiAgICByZXR1cm4gY3J5cHRvLmhhc2guc2hhMSh0b0hhc2gsIHRvSGFzaC5sZW5ndGgpO1xuICB9XG5cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciB0eXBlX2tleWlkID0gcmVxdWlyZSgnLi4vdHlwZS9rZXlpZC5qcycpLFxuICB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICB0eXBlX21waSA9IHJlcXVpcmUoJy4uL3R5cGUvbXBpLmpzJyksXG4gIGVudW1zID0gcmVxdWlyZSgnLi4vZW51bXMuanMnKSxcbiAgY3J5cHRvID0gcmVxdWlyZSgnLi4vY3J5cHRvJyk7XG5cblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgUGFja2V0cyAoVGFnIDEpXG4gKiBcbiAqIFJGQzQ4ODAgNS4xOiBBIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldCBob2xkcyB0aGUgc2Vzc2lvbiBrZXlcbiAqIHVzZWQgdG8gZW5jcnlwdCBhIG1lc3NhZ2UuIFplcm8gb3IgbW9yZSBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleVxuICogcGFja2V0cyBhbmQvb3IgU3ltbWV0cmljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgcGFja2V0cyBtYXkgcHJlY2VkZSBhXG4gKiBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCwgd2hpY2ggaG9sZHMgYW4gZW5jcnlwdGVkIG1lc3NhZ2UuIFRoZVxuICogbWVzc2FnZSBpcyBlbmNyeXB0ZWQgd2l0aCB0aGUgc2Vzc2lvbiBrZXksIGFuZCB0aGUgc2Vzc2lvbiBrZXkgaXMgaXRzZWxmXG4gKiBlbmNyeXB0ZWQgYW5kIHN0b3JlZCBpbiB0aGUgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldChzKS4gVGhlXG4gKiBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCBpcyBwcmVjZWRlZCBieSBvbmUgUHVibGljLUtleSBFbmNyeXB0ZWRcbiAqIFNlc3Npb24gS2V5IHBhY2tldCBmb3IgZWFjaCBPcGVuUEdQIGtleSB0byB3aGljaCB0aGUgbWVzc2FnZSBpcyBlbmNyeXB0ZWQuXG4gKiBUaGUgcmVjaXBpZW50IG9mIHRoZSBtZXNzYWdlIGZpbmRzIGEgc2Vzc2lvbiBrZXkgdGhhdCBpcyBlbmNyeXB0ZWQgdG8gdGhlaXJcbiAqIHB1YmxpYyBrZXksIGRlY3J5cHRzIHRoZSBzZXNzaW9uIGtleSwgYW5kIHRoZW4gdXNlcyB0aGUgc2Vzc2lvbiBrZXkgdG9cbiAqIGRlY3J5cHQgdGhlIG1lc3NhZ2UuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3B1YmxpY19rZXlfZW5jcnlwdGVkX3Nlc3Npb25fa2V5KCkge1xuICB0aGlzLnZlcnNpb24gPSAzO1xuXG4gIHRoaXMucHVibGljS2V5SWQgPSBuZXcgdHlwZV9rZXlpZCgpO1xuICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9ICdyc2FfZW5jcnlwdCc7XG5cbiAgdGhpcy5zZXNzaW9uS2V5ID0gbnVsbDtcbiAgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtID0gJ2FlczI1Nic7XG5cbiAgLyoqIEB0eXBlIHtvcGVucGdwX3R5cGVfbXBpW119ICovXG4gIHRoaXMuZW5jcnlwdGVkID0gW107XG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgcHVibGlja2V5IGVuY3J5cHRlZCBzZXNzaW9uIGtleSBwYWNrZXQgKHRhZyAxKS5cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDEgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2ZcbiAgICogICAgICAgICAgICBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBPYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG5cbiAgICB0aGlzLnZlcnNpb24gPSBieXRlc1swXS5jaGFyQ29kZUF0KCk7XG4gICAgdGhpcy5wdWJsaWNLZXlJZC5yZWFkKGJ5dGVzLnN1YnN0cigxKSk7XG4gICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLnB1YmxpY0tleSwgYnl0ZXNbOV0uY2hhckNvZGVBdCgpKTtcblxuICAgIHZhciBpID0gMTA7XG5cbiAgICB2YXIgaW50ZWdlckNvdW50ID0gKGZ1bmN0aW9uKGFsZ28pIHtcbiAgICAgIHN3aXRjaCAoYWxnbykge1xuICAgICAgICBjYXNlICdyc2FfZW5jcnlwdCc6XG4gICAgICAgIGNhc2UgJ3JzYV9lbmNyeXB0X3NpZ24nOlxuICAgICAgICAgIHJldHVybiAxO1xuXG4gICAgICAgIGNhc2UgJ2VsZ2FtYWwnOlxuICAgICAgICAgIHJldHVybiAyO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBhbGdvcml0aG0uXCIpO1xuICAgICAgfVxuICAgIH0pKHRoaXMucHVibGljS2V5QWxnb3JpdGhtKTtcblxuICAgIHRoaXMuZW5jcnlwdGVkID0gW107XG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGludGVnZXJDb3VudDsgaisrKSB7XG4gICAgICB2YXIgbXBpID0gbmV3IHR5cGVfbXBpKCk7XG4gICAgICBpICs9IG1waS5yZWFkKGJ5dGVzLnN1YnN0cihpKSk7XG4gICAgICB0aGlzLmVuY3J5cHRlZC5wdXNoKG1waSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhIHRhZyAxIHBhY2tldFxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IHB1YmxpY0tleUlkXG4gICAqICAgICAgICAgICAgIFRoZSBwdWJsaWMga2V5IGlkIGNvcnJlc3BvbmRpbmcgdG8gcHVibGljTVBJcyBrZXkgYXMgc3RyaW5nXG4gICAqIEBwYXJhbSB7b3BlbnBncF90eXBlX21waVtdfSBwdWJsaWNNUElzXG4gICAqICAgICAgICAgICAgTXVsdGlwcmVjaXNpb24gaW50ZWdlciBvYmplY3RzIGRlc2NyaWJpbmcgdGhlIHB1YmxpYyBrZXlcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwdWJhbGdvXG4gICAqICAgICAgICAgICAgVGhlIGNvcnJlc3BvbmRpbmcgcHVibGljIGtleSBhbGdvcml0aG0gLy8gU2VlIFJGQzQ4ODAgOS4xXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gc3ltbWFsZ29cbiAgICogICAgICAgICAgICBUaGUgc3ltbWV0cmljIGNpcGhlciBhbGdvcml0aG0gdXNlZCB0byBlbmNyeXB0IHRoZSBkYXRhIFxuICAgKiAgICAgICAgICAgIHdpdGhpbiBhbiBlbmNyeXB0ZWRkYXRhcGFja2V0IG9yIGVuY3J5cHRlZGludGVncml0eS1cbiAgICogICAgICAgICAgICBwcm90ZWN0ZWRkYXRhcGFja2V0IFxuICAgKiAgICAgICAgICAgIGZvbGxvd2luZyB0aGlzIHBhY2tldCAvL1NlZSBSRkM0ODgwIDkuMlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc2Vzc2lvbmtleVxuICAgKiAgICAgICAgICAgIEEgc3RyaW5nIG9mIHJhbmRvbWJ5dGVzIHJlcHJlc2VudGluZyB0aGUgc2Vzc2lvbiBrZXlcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG5cbiAgICB2YXIgcmVzdWx0ID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnZlcnNpb24pO1xuICAgIHJlc3VsdCArPSB0aGlzLnB1YmxpY0tleUlkLndyaXRlKCk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICBlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMucHVibGljS2V5QWxnb3JpdGhtKSk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZW5jcnlwdGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHQgKz0gdGhpcy5lbmNyeXB0ZWRbaV0ud3JpdGUoKVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICB0aGlzLmVuY3J5cHQgPSBmdW5jdGlvbihrZXkpIHtcbiAgICB2YXIgZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICBlbnVtcy53cml0ZShlbnVtcy5zeW1tZXRyaWMsIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSkpO1xuXG4gICAgZGF0YSArPSB0aGlzLnNlc3Npb25LZXk7XG4gICAgdmFyIGNoZWNrc3VtID0gdXRpbC5jYWxjX2NoZWNrc3VtKHRoaXMuc2Vzc2lvbktleSk7XG4gICAgZGF0YSArPSB1dGlsLndyaXRlTnVtYmVyKGNoZWNrc3VtLCAyKTtcblxuICAgIHZhciBtcGkgPSBuZXcgdHlwZV9tcGkoKTtcbiAgICBtcGkuZnJvbUJ5dGVzKGNyeXB0by5wa2NzMS5lbWUuZW5jb2RlKFxuICAgICAgZGF0YSxcbiAgICAgIGtleS5tcGlbMF0uYnl0ZUxlbmd0aCgpKSk7XG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5wdWJsaWNLZXlFbmNyeXB0KFxuICAgICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0sXG4gICAgICBrZXkubXBpLFxuICAgICAgbXBpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNyeXB0cyB0aGUgc2Vzc2lvbiBrZXkgKG9ubHkgZm9yIHB1YmxpYyBrZXkgZW5jcnlwdGVkIHNlc3Npb24ga2V5XG4gICAqIHBhY2tldHMgKHRhZyAxKVxuICAgKiBcbiAgICogQHBhcmFtIHtvcGVucGdwX21zZ19tZXNzYWdlfSBtc2dcbiAgICogICAgICAgICAgICBUaGUgbWVzc2FnZSBvYmplY3QgKHdpdGggbWVtYmVyIGVuY3J5cHRlZERhdGFcbiAgICogQHBhcmFtIHtvcGVucGdwX21zZ19wcml2YXRla2V5fSBrZXlcbiAgICogICAgICAgICAgICBQcml2YXRlIGtleSB3aXRoIHNlY01QSXMgdW5sb2NrZWRcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgdW5lbmNyeXB0ZWQgc2Vzc2lvbiBrZXlcbiAgICovXG4gIHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciByZXN1bHQgPSBjcnlwdG8ucHVibGljS2V5RGVjcnlwdChcbiAgICAgIHRoaXMucHVibGljS2V5QWxnb3JpdGhtLFxuICAgICAga2V5Lm1waSxcbiAgICAgIHRoaXMuZW5jcnlwdGVkKS50b0J5dGVzKCk7XG5cbiAgICB2YXIgY2hlY2tzdW0gPSB1dGlsLnJlYWROdW1iZXIocmVzdWx0LnN1YnN0cihyZXN1bHQubGVuZ3RoIC0gMikpO1xuXG4gICAgdmFyIGRlY29kZWQgPSBjcnlwdG8ucGtjczEuZW1lLmRlY29kZShcbiAgICAgIHJlc3VsdCxcbiAgICAgIGtleS5tcGlbMF0uYnl0ZUxlbmd0aCgpKTtcblxuICAgIHZhciBrZXkgPSBkZWNvZGVkLnN1YnN0cmluZygxLCBkZWNvZGVkLmxlbmd0aCAtIDIpO1xuXG4gICAgaWYgKGNoZWNrc3VtICE9IHV0aWwuY2FsY19jaGVja3N1bShrZXkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NoZWNrc3VtIG1pc21hdGNoJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2Vzc2lvbktleSA9IGtleTtcbiAgICAgIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9XG4gICAgICAgIGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBkZWNvZGVkLmNoYXJDb2RlQXQoMCkpO1xuICAgIH1cbiAgfVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBwdWJsaWNfa2V5ID0gcmVxdWlyZSgnLi9wdWJsaWNfa2V5LmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcHVibGljX3N1YmtleSgpIHtcbiAgcHVibGljX2tleS5jYWxsKHRoaXMpO1xufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHB1YmxpY0tleSA9IHJlcXVpcmUoJy4vcHVibGljX2tleS5qcycpLFxuICBlbnVtcyA9IHJlcXVpcmUoJy4uL2VudW1zLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyksXG4gIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpLFxuICB0eXBlX21waSA9IHJlcXVpcmUoJy4uL3R5cGUvbXBpLmpzJyksXG4gIHR5cGVfczJrID0gcmVxdWlyZSgnLi4vdHlwZS9zMmsuanMnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIEtleSBNYXRlcmlhbCBQYWNrZXQgKFRhZyA1LDYsNywxNClcbiAqICAgXG4gKiBSRkM0NDgwIDUuNTpcbiAqIEEga2V5IG1hdGVyaWFsIHBhY2tldCBjb250YWlucyBhbGwgdGhlIGluZm9ybWF0aW9uIGFib3V0IGEgcHVibGljIG9yXG4gKiBwcml2YXRlIGtleS4gIFRoZXJlIGFyZSBmb3VyIHZhcmlhbnRzIG9mIHRoaXMgcGFja2V0IHR5cGUsIGFuZCB0d29cbiAqIG1ham9yIHZlcnNpb25zLiAgQ29uc2VxdWVudGx5LCB0aGlzIHNlY3Rpb24gaXMgY29tcGxleC5cbiAqL1xuZnVuY3Rpb24gcGFja2V0X3NlY3JldF9rZXkoKSB7XG4gIHB1YmxpY0tleS5jYWxsKHRoaXMpO1xuXG4gIHRoaXMuZW5jcnlwdGVkID0gbnVsbDtcblxuXG4gIGZ1bmN0aW9uIGdldF9oYXNoX2xlbihoYXNoKSB7XG4gICAgaWYgKGhhc2ggPT0gJ3NoYTEnKVxuICAgICAgcmV0dXJuIDIwO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiAyO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0X2hhc2hfZm4oaGFzaCkge1xuICAgIGlmIChoYXNoID09ICdzaGExJylcbiAgICAgIHJldHVybiBjcnlwdG8uaGFzaC5zaGExO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiBmdW5jdGlvbihjKSB7XG4gICAgICAgIHJldHVybiB1dGlsLndyaXRlTnVtYmVyKHV0aWwuY2FsY19jaGVja3N1bShjKSwgMik7XG4gICAgfTtcbiAgfVxuXG4gIC8vIEhlbHBlciBmdW5jdGlvblxuXG4gIGZ1bmN0aW9uIHBhcnNlX2NsZWFydGV4dF9tcGkoaGFzaF9hbGdvcml0aG0sIGNsZWFydGV4dCwgYWxnb3JpdGhtKSB7XG4gICAgdmFyIGhhc2hsZW4gPSBnZXRfaGFzaF9sZW4oaGFzaF9hbGdvcml0aG0pLFxuICAgICAgaGFzaGZuID0gZ2V0X2hhc2hfZm4oaGFzaF9hbGdvcml0aG0pO1xuXG4gICAgdmFyIGhhc2h0ZXh0ID0gY2xlYXJ0ZXh0LnN1YnN0cihjbGVhcnRleHQubGVuZ3RoIC0gaGFzaGxlbik7XG4gICAgY2xlYXJ0ZXh0ID0gY2xlYXJ0ZXh0LnN1YnN0cigwLCBjbGVhcnRleHQubGVuZ3RoIC0gaGFzaGxlbik7XG5cbiAgICB2YXIgaGFzaCA9IGhhc2hmbihjbGVhcnRleHQpO1xuXG4gICAgaWYgKGhhc2ggIT0gaGFzaHRleHQpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJIYXNoIG1pc21hdGNoLlwiKTtcblxuICAgIHZhciBtcGlzID0gY3J5cHRvLmdldFByaXZhdGVNcGlDb3VudChhbGdvcml0aG0pO1xuXG4gICAgdmFyIGogPSAwO1xuICAgIHZhciBtcGkgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbXBpcyAmJiBqIDwgY2xlYXJ0ZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBtcGlbaV0gPSBuZXcgdHlwZV9tcGkoKTtcbiAgICAgIGogKz0gbXBpW2ldLnJlYWQoY2xlYXJ0ZXh0LnN1YnN0cihqKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1waTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdyaXRlX2NsZWFydGV4dF9tcGkoaGFzaF9hbGdvcml0aG0sIGFsZ29yaXRobSwgbXBpKSB7XG4gICAgdmFyIGJ5dGVzID0gJyc7XG4gICAgdmFyIGRpc2NhcmQgPSBjcnlwdG8uZ2V0UHVibGljTXBpQ291bnQoYWxnb3JpdGhtKTtcblxuICAgIGZvciAodmFyIGkgPSBkaXNjYXJkOyBpIDwgbXBpLmxlbmd0aDsgaSsrKSB7XG4gICAgICBieXRlcyArPSBtcGlbaV0ud3JpdGUoKTtcbiAgICB9XG5cblxuICAgIGJ5dGVzICs9IGdldF9oYXNoX2ZuKGhhc2hfYWxnb3JpdGhtKShieXRlcyk7XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuXG4gIC8vIDUuNS4zLiAgU2VjcmV0LUtleSBQYWNrZXQgRm9ybWF0c1xuXG4gIC8qKlxuICAgKiBJbnRlcm5hbCBwYXJzZXIgZm9yIHByaXZhdGUga2V5cyBhcyBzcGVjaWZpZWQgaW4gUkZDIDQ4ODAgc2VjdGlvbiA1LjUuM1xuICAgKiBAcGFyYW0ge1N0cmluZ30gYnl0ZXMgSW5wdXQgc3RyaW5nIHRvIHJlYWQgdGhlIHBhY2tldCBmcm9tXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gU3RhcnQgcG9zaXRpb24gZm9yIHRoZSBwYXJzZXJcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgcmVtYWluaW5nIGxlbmd0aCBvZiBieXRlc1xuICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoaXMgb2JqZWN0IHdpdGggYXR0cmlidXRlcyBzZXQgYnkgdGhlIHBhcnNlclxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAvLyAtIEEgUHVibGljLUtleSBvciBQdWJsaWMtU3Via2V5IHBhY2tldCwgYXMgZGVzY3JpYmVkIGFib3ZlLlxuICAgIHZhciBsZW4gPSB0aGlzLnJlYWRQdWJsaWNLZXkoYnl0ZXMpO1xuXG4gICAgYnl0ZXMgPSBieXRlcy5zdWJzdHIobGVuKTtcblxuXG4gICAgLy8gLSBPbmUgb2N0ZXQgaW5kaWNhdGluZyBzdHJpbmctdG8ta2V5IHVzYWdlIGNvbnZlbnRpb25zLiAgWmVyb1xuICAgIC8vICAgaW5kaWNhdGVzIHRoYXQgdGhlIHNlY3JldC1rZXkgZGF0YSBpcyBub3QgZW5jcnlwdGVkLiAgMjU1IG9yIDI1NFxuICAgIC8vICAgaW5kaWNhdGVzIHRoYXQgYSBzdHJpbmctdG8ta2V5IHNwZWNpZmllciBpcyBiZWluZyBnaXZlbi4gIEFueVxuICAgIC8vICAgb3RoZXIgdmFsdWUgaXMgYSBzeW1tZXRyaWMta2V5IGVuY3J5cHRpb24gYWxnb3JpdGhtIGlkZW50aWZpZXIuXG4gICAgdmFyIGlzRW5jcnlwdGVkID0gYnl0ZXNbMF0uY2hhckNvZGVBdCgpO1xuXG4gICAgaWYgKGlzRW5jcnlwdGVkKSB7XG4gICAgICB0aGlzLmVuY3J5cHRlZCA9IGJ5dGVzO1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIC8vIC0gUGxhaW4gb3IgZW5jcnlwdGVkIG11bHRpcHJlY2lzaW9uIGludGVnZXJzIGNvbXByaXNpbmcgdGhlIHNlY3JldFxuICAgICAgLy8gICBrZXkgZGF0YS4gIFRoZXNlIGFsZ29yaXRobS1zcGVjaWZpYyBmaWVsZHMgYXJlIGFzIGRlc2NyaWJlZFxuICAgICAgLy8gICBiZWxvdy5cblxuICAgICAgdGhpcy5tcGkgPSB0aGlzLm1waS5jb25jYXQocGFyc2VfY2xlYXJ0ZXh0X21waSgnbW9kJywgYnl0ZXMuc3Vic3RyKDEpLFxuICAgICAgICB0aGlzLmFsZ29yaXRobSkpO1xuICAgIH1cblxuICB9O1xuXG4gIC8qXG4gICAgICogQ3JlYXRlcyBhbiBPcGVuUEdQIGtleSBwYWNrZXQgZm9yIHRoZSBnaXZlbiBrZXkuIG11Y2ggXG5cdCAqIFRPRE8gaW4gcmVnYXJkcyB0byBzMmssIHN1YmtleXMuXG4gICAgICogQHBhcmFtIHtJbnRlZ2VyfSBrZXlUeXBlIEZvbGxvd3MgdGhlIE9wZW5QR1AgYWxnb3JpdGhtIHN0YW5kYXJkLCBcblx0ICogSUUgMSBjb3JyZXNwb25kcyB0byBSU0EuXG4gICAgICogQHBhcmFtIHtSU0Eua2V5T2JqZWN0fSBrZXlcbiAgICAgKiBAcGFyYW0gcGFzc3BocmFzZVxuICAgICAqIEBwYXJhbSBzMmtIYXNoXG4gICAgICogQHBhcmFtIHN5bW1ldHJpY0VuY3J5cHRpb25BbGdvcml0aG1cbiAgICAgKiBAcGFyYW0gdGltZVBhY2tldFxuICAgICAqIEByZXR1cm4ge09iamVjdH0ge2JvZHk6IFtzdHJpbmddT3BlblBHUCBwYWNrZXQgYm9keSBjb250ZW50cywgXG5cdFx0aGVhZGVyOiBbc3RyaW5nXSBPcGVuUEdQIHBhY2tldCBoZWFkZXIsIHN0cmluZzogW3N0cmluZ10gaGVhZGVyK2JvZHl9XG4gICAgICovXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYnl0ZXMgPSB0aGlzLndyaXRlUHVibGljS2V5KCk7XG5cbiAgICBpZiAoIXRoaXMuZW5jcnlwdGVkKSB7XG4gICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDApO1xuXG4gICAgICBieXRlcyArPSB3cml0ZV9jbGVhcnRleHRfbXBpKCdtb2QnLCB0aGlzLmFsZ29yaXRobSwgdGhpcy5tcGkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBieXRlcyArPSB0aGlzLmVuY3J5cHRlZDtcbiAgICB9XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH07XG5cblxuXG5cbiAgLyoqIEVuY3J5cHQgdGhlIHBheWxvYWQuIEJ5IGRlZmF1bHQsIHdlIHVzZSBhZXMyNTYgYW5kIGl0ZXJhdGVkLCBzYWx0ZWQgc3RyaW5nXG4gICAqIHRvIGtleSBzcGVjaWZpZXJcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhc3NwaHJhc2VcbiAgICovXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UpIHtcblxuICAgIHZhciBzMmsgPSBuZXcgdHlwZV9zMmsoKSxcbiAgICAgIHN5bW1ldHJpYyA9ICdhZXMyNTYnLFxuICAgICAgY2xlYXJ0ZXh0ID0gd3JpdGVfY2xlYXJ0ZXh0X21waSgnc2hhMScsIHRoaXMuYWxnb3JpdGhtLCB0aGlzLm1waSksXG4gICAgICBrZXkgPSBwcm9kdWNlRW5jcnlwdGlvbktleShzMmssIHBhc3NwaHJhc2UsIHN5bW1ldHJpYyksXG4gICAgICBibG9ja0xlbiA9IGNyeXB0by5jaXBoZXJbc3ltbWV0cmljXS5ibG9ja1NpemUsXG4gICAgICBpdiA9IGNyeXB0by5yYW5kb20uZ2V0UmFuZG9tQnl0ZXMoYmxvY2tMZW4pO1xuXG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9ICcnO1xuICAgIHRoaXMuZW5jcnlwdGVkICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMjU0KTtcbiAgICB0aGlzLmVuY3J5cHRlZCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGVudW1zLndyaXRlKGVudW1zLnN5bW1ldHJpYywgc3ltbWV0cmljKSk7XG4gICAgdGhpcy5lbmNyeXB0ZWQgKz0gczJrLndyaXRlKCk7XG4gICAgdGhpcy5lbmNyeXB0ZWQgKz0gaXY7XG5cbiAgICB0aGlzLmVuY3J5cHRlZCArPSBjcnlwdG8uY2ZiLm5vcm1hbEVuY3J5cHQoc3ltbWV0cmljLCBrZXksIGNsZWFydGV4dCwgaXYpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHByb2R1Y2VFbmNyeXB0aW9uS2V5KHMyaywgcGFzc3BocmFzZSwgYWxnb3JpdGhtKSB7XG4gICAgcmV0dXJuIHMyay5wcm9kdWNlX2tleShwYXNzcGhyYXNlLFxuICAgICAgY3J5cHRvLmNpcGhlclthbGdvcml0aG1dLmtleVNpemUpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBwcml2YXRlIGtleSBNUElzIHdoaWNoIGFyZSBuZWVkZWQgdG8gdXNlIHRoZSBrZXkuXG4gICAqIG9wZW5wZ3BfcGFja2V0X2tleW1hdGVyaWFsLmhhc1VuZW5jcnlwdGVkU2VjcmV0S2V5RGF0YSBzaG91bGQgYmUgXG4gICAqIGZhbHNlIG90aGVyd2lzZVxuICAgKiBhIGNhbGwgdG8gdGhpcyBmdW5jdGlvbiBpcyBub3QgbmVlZGVkXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyX3Bhc3NwaHJhc2UgVGhlIHBhc3NwaHJhc2UgZm9yIHRoaXMgcHJpdmF0ZSBrZXkgXG4gICAqIGFzIHN0cmluZ1xuICAgKiBAcmV0dXJuIHtCb29sZWFufSBUcnVlIGlmIHRoZSBwYXNzcGhyYXNlIHdhcyBjb3JyZWN0OyBmYWxzZSBpZiBub3RcbiAgICovXG4gIHRoaXMuZGVjcnlwdCA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UpIHtcbiAgICBpZiAoIXRoaXMuZW5jcnlwdGVkKVxuICAgICAgcmV0dXJuO1xuXG4gICAgdmFyIGkgPSAwLFxuICAgICAgc3ltbWV0cmljLFxuICAgICAga2V5O1xuXG4gICAgdmFyIHMya191c2FnZSA9IHRoaXMuZW5jcnlwdGVkW2krK10uY2hhckNvZGVBdCgpO1xuXG4gICAgLy8gLSBbT3B0aW9uYWxdIElmIHN0cmluZy10by1rZXkgdXNhZ2Ugb2N0ZXQgd2FzIDI1NSBvciAyNTQsIGEgb25lLVxuICAgIC8vICAgb2N0ZXQgc3ltbWV0cmljIGVuY3J5cHRpb24gYWxnb3JpdGhtLlxuICAgIGlmIChzMmtfdXNhZ2UgPT0gMjU1IHx8IHMya191c2FnZSA9PSAyNTQpIHtcbiAgICAgIHN5bW1ldHJpYyA9IHRoaXMuZW5jcnlwdGVkW2krK10uY2hhckNvZGVBdCgpO1xuICAgICAgc3ltbWV0cmljID0gZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsIHN5bW1ldHJpYyk7XG5cbiAgICAgIC8vIC0gW09wdGlvbmFsXSBJZiBzdHJpbmctdG8ta2V5IHVzYWdlIG9jdGV0IHdhcyAyNTUgb3IgMjU0LCBhXG4gICAgICAvLyAgIHN0cmluZy10by1rZXkgc3BlY2lmaWVyLiAgVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nLXRvLWtleVxuICAgICAgLy8gICBzcGVjaWZpZXIgaXMgaW1wbGllZCBieSBpdHMgdHlwZSwgYXMgZGVzY3JpYmVkIGFib3ZlLlxuICAgICAgdmFyIHMyayA9IG5ldyB0eXBlX3MyaygpO1xuICAgICAgaSArPSBzMmsucmVhZCh0aGlzLmVuY3J5cHRlZC5zdWJzdHIoaSkpO1xuXG4gICAgICBrZXkgPSBwcm9kdWNlRW5jcnlwdGlvbktleShzMmssIHBhc3NwaHJhc2UsIHN5bW1ldHJpYyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN5bW1ldHJpYyA9IHMya191c2FnZTtcbiAgICAgIHN5bW1ldHJpYyA9IGVudW1zLnJlYWQoZW51bXMuc3ltbWV0cmljLCBzeW1tZXRyaWMpO1xuICAgICAga2V5ID0gY3J5cHRvLmhhc2gubWQ1KHBhc3NwaHJhc2UpO1xuICAgIH1cblxuXG4gICAgLy8gLSBbT3B0aW9uYWxdIElmIHNlY3JldCBkYXRhIGlzIGVuY3J5cHRlZCAoc3RyaW5nLXRvLWtleSB1c2FnZSBvY3RldFxuICAgIC8vICAgbm90IHplcm8pLCBhbiBJbml0aWFsIFZlY3RvciAoSVYpIG9mIHRoZSBzYW1lIGxlbmd0aCBhcyB0aGVcbiAgICAvLyAgIGNpcGhlcidzIGJsb2NrIHNpemUuXG4gICAgdmFyIGl2ID0gdGhpcy5lbmNyeXB0ZWQuc3Vic3RyKGksXG4gICAgICBjcnlwdG8uY2lwaGVyW3N5bW1ldHJpY10uYmxvY2tTaXplKTtcblxuICAgIGkgKz0gaXYubGVuZ3RoO1xuXG4gICAgdmFyIGNsZWFydGV4dCxcbiAgICAgIGNpcGhlcnRleHQgPSB0aGlzLmVuY3J5cHRlZC5zdWJzdHIoaSk7XG5cbiAgICBjbGVhcnRleHQgPSBjcnlwdG8uY2ZiLm5vcm1hbERlY3J5cHQoc3ltbWV0cmljLCBrZXksIGNpcGhlcnRleHQsIGl2KTtcblxuICAgIHZhciBoYXNoID0gczJrX3VzYWdlID09IDI1NCA/XG4gICAgICAnc2hhMScgOlxuICAgICAgJ21vZCc7XG5cblxuICAgIHRoaXMubXBpID0gdGhpcy5tcGkuY29uY2F0KHBhcnNlX2NsZWFydGV4dF9tcGkoaGFzaCwgY2xlYXJ0ZXh0LFxuICAgICAgdGhpcy5hbGdvcml0aG0pKTtcbiAgfTtcblxuICB0aGlzLmdlbmVyYXRlID0gZnVuY3Rpb24oYml0cywgcGFzc3BocmFzZSkge1xuICAgIHRoaXMubXBpID0gY3J5cHRvLmdlbmVyYXRlTXBpKHRoaXMuYWxnb3JpdGhtLCBiaXRzKTtcbiAgfTtcblxufVxuXG5wYWNrZXRfc2VjcmV0X2tleS5wcm90b3R5cGUgPSBuZXcgcHVibGljS2V5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHBhY2tldF9zZWNyZXRfa2V5O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHNlY3JldF9rZXkgPSByZXF1aXJlKCcuL3NlY3JldF9rZXkuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzZWNyZXRfc3Via2V5KCkge1xuICBzZWNyZXRfa2V5LmNhbGwodGhpcyk7XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKSxcbiAgcGFja2V0ID0gcmVxdWlyZSgnLi9wYWNrZXQuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKSxcbiAgdHlwZV9tcGkgPSByZXF1aXJlKCcuLi90eXBlL21waS5qcycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2lnbmF0dXJlIFBhY2tldCAoVGFnIDIpXG4gKiBcbiAqIFJGQzQ0ODAgNS4yOlxuICogQSBTaWduYXR1cmUgcGFja2V0IGRlc2NyaWJlcyBhIGJpbmRpbmcgYmV0d2VlbiBzb21lIHB1YmxpYyBrZXkgYW5kXG4gKiBzb21lIGRhdGEuICBUaGUgbW9zdCBjb21tb24gc2lnbmF0dXJlcyBhcmUgYSBzaWduYXR1cmUgb2YgYSBmaWxlIG9yIGFcbiAqIGJsb2NrIG9mIHRleHQsIGFuZCBhIHNpZ25hdHVyZSB0aGF0IGlzIGEgY2VydGlmaWNhdGlvbiBvZiBhIFVzZXIgSUQuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3NpZ25hdHVyZSgpIHtcblxuICB0aGlzLnNpZ25hdHVyZVR5cGUgPSBudWxsO1xuICB0aGlzLmhhc2hBbGdvcml0aG0gPSBudWxsO1xuICB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSA9IG51bGw7XG5cbiAgdGhpcy5zaWduYXR1cmVEYXRhID0gbnVsbDtcbiAgdGhpcy5zaWduZWRIYXNoVmFsdWUgPSBudWxsO1xuICB0aGlzLm1waSA9IG51bGw7XG5cbiAgdGhpcy5jcmVhdGVkID0gbnVsbDtcbiAgdGhpcy5zaWduYXR1cmVFeHBpcmF0aW9uVGltZSA9IG51bGw7XG4gIHRoaXMuc2lnbmF0dXJlTmV2ZXJFeHBpcmVzID0gbnVsbDtcbiAgdGhpcy5leHBvcnRhYmxlID0gbnVsbDtcbiAgdGhpcy50cnVzdExldmVsID0gbnVsbDtcbiAgdGhpcy50cnVzdEFtb3VudCA9IG51bGw7XG4gIHRoaXMucmVndWxhckV4cHJlc3Npb24gPSBudWxsO1xuICB0aGlzLnJldm9jYWJsZSA9IG51bGw7XG4gIHRoaXMua2V5RXhwaXJhdGlvblRpbWUgPSBudWxsO1xuICB0aGlzLmtleU5ldmVyRXhwaXJlcyA9IG51bGw7XG4gIHRoaXMucHJlZmVycmVkU3ltbWV0cmljQWxnb3JpdGhtcyA9IG51bGw7XG4gIHRoaXMucmV2b2NhdGlvbktleUNsYXNzID0gbnVsbDtcbiAgdGhpcy5yZXZvY2F0aW9uS2V5QWxnb3JpdGhtID0gbnVsbDtcbiAgdGhpcy5yZXZvY2F0aW9uS2V5RmluZ2VycHJpbnQgPSBudWxsO1xuICB0aGlzLmlzc3VlcktleUlkID0gbnVsbDtcbiAgdGhpcy5ub3RhdGlvbiA9IHt9O1xuICB0aGlzLnByZWZlcnJlZEhhc2hBbGdvcml0aG1zID0gbnVsbDtcbiAgdGhpcy5wcmVmZXJyZWRDb21wcmVzc2lvbkFsZ29yaXRobXMgPSBudWxsO1xuICB0aGlzLmtleVNlcnZlclByZWZlcmVuY2VzID0gbnVsbDtcbiAgdGhpcy5wcmVmZXJyZWRLZXlTZXJ2ZXIgPSBudWxsO1xuICB0aGlzLmlzUHJpbWFyeVVzZXJJRCA9IG51bGw7XG4gIHRoaXMucG9saWN5VVJJID0gbnVsbDtcbiAgdGhpcy5rZXlGbGFncyA9IG51bGw7XG4gIHRoaXMuc2lnbmVyc1VzZXJJZCA9IG51bGw7XG4gIHRoaXMucmVhc29uRm9yUmV2b2NhdGlvbkZsYWcgPSBudWxsO1xuICB0aGlzLnJlYXNvbkZvclJldm9jYXRpb25TdHJpbmcgPSBudWxsO1xuICB0aGlzLnNpZ25hdHVyZVRhcmdldFB1YmxpY0tleUFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaCA9IG51bGw7XG4gIHRoaXMuZW1iZWRkZWRTaWduYXR1cmUgPSBudWxsO1xuXG4gIHRoaXMudmVyaWZpZWQgPSBmYWxzZTtcblxuXG4gIC8qKlxuICAgKiBwYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHNpZ25hdHVyZSBwYWNrZXQgKHRhZyAyKS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGJ5dGVzIHBheWxvYWQgb2YgYSB0YWcgMiBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGJ5dGVzIHN0cmluZ1xuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBsZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBieXRlcyBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBvYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIGkgPSAwO1xuXG4gICAgdmFyIHZlcnNpb24gPSBieXRlc1tpKytdLmNoYXJDb2RlQXQoKTtcbiAgICAvLyBzd2l0Y2ggb24gdmVyc2lvbiAoMyBhbmQgNClcbiAgICBzd2l0Y2ggKHZlcnNpb24pIHtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgLy8gT25lLW9jdGV0IGxlbmd0aCBvZiBmb2xsb3dpbmcgaGFzaGVkIG1hdGVyaWFsLiBNVVNUIGJlIDUuXG4gICAgICAgIGlmIChieXRlc1tpKytdLmNoYXJDb2RlQXQoKSAhPSA1KVxuICAgICAgICAgIHV0aWwucHJpbnRfZGVidWcoXCJvcGVucGdwLnBhY2tldC5zaWduYXR1cmUuanNcXG5cIiArXG4gICAgICAgICAgICAnaW52YWxpZCBPbmUtb2N0ZXQgbGVuZ3RoIG9mIGZvbGxvd2luZyBoYXNoZWQgbWF0ZXJpYWwuJyArXG4gICAgICAgICAgICAnTVVTVCBiZSA1LiBAOicgKyAoaSAtIDEpKTtcblxuICAgICAgICB2YXIgc2lncG9zID0gaTtcbiAgICAgICAgLy8gT25lLW9jdGV0IHNpZ25hdHVyZSB0eXBlLlxuICAgICAgICB0aGlzLnNpZ25hdHVyZVR5cGUgPSBieXRlc1tpKytdLmNoYXJDb2RlQXQoKTtcblxuICAgICAgICAvLyBGb3VyLW9jdGV0IGNyZWF0aW9uIHRpbWUuXG4gICAgICAgIHRoaXMuY3JlYXRlZCA9IHV0aWwucmVhZERhdGUoYnl0ZXMuc3Vic3RyKGksIDQpKTtcbiAgICAgICAgaSArPSA0O1xuXG4gICAgICAgIC8vIHN0b3JpbmcgZGF0YSBhcHBlbmRlZCB0byBkYXRhIHdoaWNoIGdldHMgdmVyaWZpZWRcbiAgICAgICAgdGhpcy5zaWduYXR1cmVEYXRhID0gYnl0ZXMuc3Vic3RyaW5nKHBvc2l0aW9uLCBpKTtcblxuICAgICAgICAvLyBFaWdodC1vY3RldCBLZXkgSUQgb2Ygc2lnbmVyLlxuICAgICAgICB0aGlzLmlzc3VlcktleUlkID0gYnl0ZXMuc3Vic3RyaW5nKGksIGkgKyA4KTtcbiAgICAgICAgaSArPSA4O1xuXG4gICAgICAgIC8vIE9uZS1vY3RldCBwdWJsaWMta2V5IGFsZ29yaXRobS5cbiAgICAgICAgdGhpcy5wdWJsaWNLZXlBbGdvcml0aG0gPSBieXRlc1tpKytdLmNoYXJDb2RlQXQoKTtcblxuICAgICAgICAvLyBPbmUtb2N0ZXQgaGFzaCBhbGdvcml0aG0uXG4gICAgICAgIHRoaXMuaGFzaEFsZ29yaXRobSA9IGJ5dGVzW2krK10uY2hhckNvZGVBdCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNDpcbiAgICAgICAgdGhpcy5zaWduYXR1cmVUeXBlID0gYnl0ZXNbaSsrXS5jaGFyQ29kZUF0KCk7XG4gICAgICAgIHRoaXMucHVibGljS2V5QWxnb3JpdGhtID0gYnl0ZXNbaSsrXS5jaGFyQ29kZUF0KCk7XG4gICAgICAgIHRoaXMuaGFzaEFsZ29yaXRobSA9IGJ5dGVzW2krK10uY2hhckNvZGVBdCgpO1xuXG5cbiAgICAgICAgZnVuY3Rpb24gc3VicGFja2V0cyhieXRlcywgc2lnbmVkKSB7XG4gICAgICAgICAgLy8gVHdvLW9jdGV0IHNjYWxhciBvY3RldCBjb3VudCBmb3IgZm9sbG93aW5nIGhhc2hlZCBzdWJwYWNrZXRcbiAgICAgICAgICAvLyBkYXRhLlxuICAgICAgICAgIHZhciBzdWJwYWNrZXRfbGVuZ3RoID0gdXRpbC5yZWFkTnVtYmVyKFxuICAgICAgICAgICAgYnl0ZXMuc3Vic3RyKDAsIDIpKTtcblxuICAgICAgICAgIHZhciBpID0gMjtcblxuICAgICAgICAgIC8vIEhhc2hlZCBzdWJwYWNrZXQgZGF0YSBzZXQgKHplcm8gb3IgbW9yZSBzdWJwYWNrZXRzKVxuICAgICAgICAgIHZhciBzdWJwYWNrZWRfcmVhZCA9IDA7XG4gICAgICAgICAgd2hpbGUgKGkgPCAyICsgc3VicGFja2V0X2xlbmd0aCkge1xuXG4gICAgICAgICAgICB2YXIgbGVuID0gcGFja2V0LnJlYWRTaW1wbGVMZW5ndGgoYnl0ZXMuc3Vic3RyKGkpKTtcbiAgICAgICAgICAgIGkgKz0gbGVuLm9mZnNldDtcblxuICAgICAgICAgICAgLy8gU2luY2UgaXQgaXMgdHJpdmlhbCB0byBhZGQgZGF0YSB0byB0aGUgdW5oYXNoZWQgcG9ydGlvbiBvZiBcbiAgICAgICAgICAgIC8vIHRoZSBwYWNrZXQgd2Ugc2ltcGx5IGlnbm9yZSBhbGwgdW5hdXRoZW50aWNhdGVkIGRhdGEuXG4gICAgICAgICAgICBpZiAoc2lnbmVkKVxuICAgICAgICAgICAgICB0aGlzLnJlYWRfc3ViX3BhY2tldChieXRlcy5zdWJzdHIoaSwgbGVuLmxlbikpO1xuXG4gICAgICAgICAgICBpICs9IGxlbi5sZW47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cblxuICAgICAgICBpICs9IHN1YnBhY2tldHMuY2FsbCh0aGlzLCBieXRlcy5zdWJzdHIoaSksIHRydWUpO1xuXG4gICAgICAgIC8vIEEgVjQgc2lnbmF0dXJlIGhhc2hlcyB0aGUgcGFja2V0IGJvZHlcbiAgICAgICAgLy8gc3RhcnRpbmcgZnJvbSBpdHMgZmlyc3QgZmllbGQsIHRoZSB2ZXJzaW9uIG51bWJlciwgdGhyb3VnaCB0aGUgZW5kXG4gICAgICAgIC8vIG9mIHRoZSBoYXNoZWQgc3VicGFja2V0IGRhdGEuICBUaHVzLCB0aGUgZmllbGRzIGhhc2hlZCBhcmUgdGhlXG4gICAgICAgIC8vIHNpZ25hdHVyZSB2ZXJzaW9uLCB0aGUgc2lnbmF0dXJlIHR5cGUsIHRoZSBwdWJsaWMta2V5IGFsZ29yaXRobSwgdGhlXG4gICAgICAgIC8vIGhhc2ggYWxnb3JpdGhtLCB0aGUgaGFzaGVkIHN1YnBhY2tldCBsZW5ndGgsIGFuZCB0aGUgaGFzaGVkXG4gICAgICAgIC8vIHN1YnBhY2tldCBib2R5LlxuICAgICAgICB0aGlzLnNpZ25hdHVyZURhdGEgPSBieXRlcy5zdWJzdHIoMCwgaSk7XG5cbiAgICAgICAgaSArPSBzdWJwYWNrZXRzLmNhbGwodGhpcywgYnl0ZXMuc3Vic3RyKGkpLCBmYWxzZSk7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZlcnNpb24gJyArIHZlcnNpb24gKyAnIG9mIHRoZSBzaWduYXR1cmUgaXMgdW5zdXBwb3J0ZWQuJyk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIFR3by1vY3RldCBmaWVsZCBob2xkaW5nIGxlZnQgMTYgYml0cyBvZiBzaWduZWQgaGFzaCB2YWx1ZS5cbiAgICB0aGlzLnNpZ25lZEhhc2hWYWx1ZSA9IGJ5dGVzLnN1YnN0cihpLCAyKTtcbiAgICBpICs9IDI7XG5cbiAgICB0aGlzLnNpZ25hdHVyZSA9IGJ5dGVzLnN1YnN0cihpKTtcbiAgfVxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5zaWduYXR1cmVEYXRhICtcbiAgICAgIHV0aWwud3JpdGVOdW1iZXIoMCwgMikgKyAvLyBOdW1iZXIgb2YgdW5zaWduZWQgc3VicGFja2V0cy5cbiAgICB0aGlzLnNpZ25lZEhhc2hWYWx1ZSArXG4gICAgICB0aGlzLnNpZ25hdHVyZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaWducyBwcm92aWRlZCBkYXRhLiBUaGlzIG5lZWRzIHRvIGJlIGRvbmUgcHJpb3IgdG8gc2VyaWFsaXphdGlvbi5cbiAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEgQ29udGFpbnMgcGFja2V0cyB0byBiZSBzaWduZWQuXG4gICAqIEBwYXJhbSB7b3BlbnBncF9tc2dfcHJpdmF0ZWtleX0gcHJpdmF0ZWtleSBwcml2YXRlIGtleSB1c2VkIHRvIHNpZ24gdGhlIG1lc3NhZ2UuIFxuICAgKi9cbiAgdGhpcy5zaWduID0gZnVuY3Rpb24oa2V5LCBkYXRhKSB7XG4gICAgdmFyIHNpZ25hdHVyZVR5cGUgPSBlbnVtcy53cml0ZShlbnVtcy5zaWduYXR1cmUsIHRoaXMuc2lnbmF0dXJlVHlwZSksXG4gICAgICBwdWJsaWNLZXlBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5wdWJsaWNLZXksIHRoaXMucHVibGljS2V5QWxnb3JpdGhtKSxcbiAgICAgIGhhc2hBbGdvcml0aG0gPSBlbnVtcy53cml0ZShlbnVtcy5oYXNoLCB0aGlzLmhhc2hBbGdvcml0aG0pO1xuXG4gICAgdmFyIHJlc3VsdCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoNCk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoc2lnbmF0dXJlVHlwZSk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocHVibGljS2V5QWxnb3JpdGhtKTtcbiAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShoYXNoQWxnb3JpdGhtKTtcblxuXG4gICAgLy8gQWRkIHN1YnBhY2tldHMgaGVyZVxuICAgIHJlc3VsdCArPSB1dGlsLndyaXRlTnVtYmVyKDAsIDIpO1xuXG5cbiAgICB0aGlzLnNpZ25hdHVyZURhdGEgPSByZXN1bHQ7XG5cbiAgICB2YXIgdHJhaWxlciA9IHRoaXMuY2FsY3VsYXRlVHJhaWxlcigpO1xuXG4gICAgdmFyIHRvSGFzaCA9IHRoaXMudG9TaWduKHNpZ25hdHVyZVR5cGUsIGRhdGEpICtcbiAgICAgIHRoaXMuc2lnbmF0dXJlRGF0YSArIHRyYWlsZXI7XG5cbiAgICB2YXIgaGFzaCA9IGNyeXB0by5oYXNoLmRpZ2VzdChoYXNoQWxnb3JpdGhtLCB0b0hhc2gpO1xuXG4gICAgdGhpcy5zaWduZWRIYXNoVmFsdWUgPSBoYXNoLnN1YnN0cigwLCAyKTtcblxuXG4gICAgdGhpcy5zaWduYXR1cmUgPSBjcnlwdG8uc2lnbmF0dXJlLnNpZ24oaGFzaEFsZ29yaXRobSxcbiAgICAgIHB1YmxpY0tleUFsZ29yaXRobSwga2V5Lm1waSwgdG9IYXNoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBjcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGEgc3ViIHNpZ25hdHVyZSBwYWNrZXQgKFNlZSBSRkMgNDg4MCA1LjIuMy4xKVxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHR5cGUgc3VicGFja2V0IHNpZ25hdHVyZSB0eXBlLiBTaWduYXR1cmUgdHlwZXMgYXMgZGVzY3JpYmVkIFxuICAgKiBpbiBSRkM0ODgwIFNlY3Rpb24gNS4yLjMuMlxuICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBkYXRhIHRvIGJlIGluY2x1ZGVkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gYSBzdHJpbmctcmVwcmVzZW50YXRpb24gb2YgYSBzdWIgc2lnbmF0dXJlIHBhY2tldCAoU2VlIFJGQyA0ODgwIDUuMi4zLjEpXG4gICAqL1xuICBmdW5jdGlvbiB3cml0ZV9zdWJfcGFja2V0KHR5cGUsIGRhdGEpIHtcbiAgICB2YXIgcmVzdWx0ID0gXCJcIjtcbiAgICByZXN1bHQgKz0gcGFja2V0LndyaXRlU2ltcGxlTGVuZ3RoKGRhdGEubGVuZ3RoICsgMSk7XG4gICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodHlwZSk7XG4gICAgcmVzdWx0ICs9IGRhdGE7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIFY0IHNpZ25hdHVyZSBzdWIgcGFja2V0c1xuXG4gIHRoaXMucmVhZF9zdWJfcGFja2V0ID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgbXlwb3MgPSAwO1xuXG4gICAgZnVuY3Rpb24gcmVhZF9hcnJheShwcm9wLCBieXRlcykge1xuICAgICAgdGhpc1twcm9wXSA9IFtdO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXNbcHJvcF0ucHVzaChieXRlc1tpXS5jaGFyQ29kZUF0KCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRoZSBsZWZ0d29zdCBiaXQgZGVub3RlcyBhIFwiY3JpdGljYWxcIiBwYWNrZXQsIGJ1dCB3ZSBpZ25vcmUgaXQuXG4gICAgdmFyIHR5cGUgPSBieXRlc1tteXBvcysrXS5jaGFyQ29kZUF0KCkgJiAweDdGO1xuXG4gICAgLy8gc3VicGFja2V0IHR5cGVcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgLy8gU2lnbmF0dXJlIENyZWF0aW9uIFRpbWVcbiAgICAgICAgdGhpcy5jcmVhdGVkID0gdXRpbC5yZWFkRGF0ZShieXRlcy5zdWJzdHIobXlwb3MpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIC8vIFNpZ25hdHVyZSBFeHBpcmF0aW9uIFRpbWVcbiAgICAgICAgdmFyIHRpbWUgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuXG4gICAgICAgIHRoaXMuc2lnbmF0dXJlTmV2ZXJFeHBpcmVzID0gdGltZS5nZXRUaW1lKCkgPT0gMDtcbiAgICAgICAgdGhpcy5zaWduYXR1cmVFeHBpcmF0aW9uVGltZSA9IHRpbWU7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIC8vIEV4cG9ydGFibGUgQ2VydGlmaWNhdGlvblxuICAgICAgICB0aGlzLmV4cG9ydGFibGUgPSBieXRlc1tteXBvcysrXS5jaGFyQ29kZUF0KCkgPT0gMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDU6XG4gICAgICAgIC8vIFRydXN0IFNpZ25hdHVyZVxuICAgICAgICB0aGlzLnRydXN0TGV2ZWwgPSBieXRlc1tteXBvcysrXS5jaGFyQ29kZUF0KCk7XG4gICAgICAgIHRoaXMudHJ1c3RBbW91bnQgPSBieXRlc1tteXBvcysrXS5jaGFyQ29kZUF0KCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA2OlxuICAgICAgICAvLyBSZWd1bGFyIEV4cHJlc3Npb25cbiAgICAgICAgdGhpcy5yZWd1bGFyRXhwcmVzc2lvbiA9IGJ5dGVzLnN1YnN0cihteXBvcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA3OlxuICAgICAgICAvLyBSZXZvY2FibGVcbiAgICAgICAgdGhpcy5yZXZvY2FibGUgPSBieXRlc1tteXBvcysrXS5jaGFyQ29kZUF0KCkgPT0gMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDk6XG4gICAgICAgIC8vIEtleSBFeHBpcmF0aW9uIFRpbWVcbiAgICAgICAgdmFyIHRpbWUgPSB1dGlsLnJlYWREYXRlKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuXG4gICAgICAgIHRoaXMua2V5RXhwaXJhdGlvblRpbWUgPSB0aW1lO1xuICAgICAgICB0aGlzLmtleU5ldmVyRXhwaXJlcyA9IHRpbWUuZ2V0VGltZSgpID09IDA7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDExOlxuICAgICAgICAvLyBQcmVmZXJyZWQgU3ltbWV0cmljIEFsZ29yaXRobXNcbiAgICAgICAgdGhpcy5wcmVmZXJyZWRTeW1tZXRyaWNBbGdvcml0aG1zID0gW107XG5cbiAgICAgICAgd2hpbGUgKG15cG9zICE9IGJ5dGVzLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMucHJlZmVycmVkU3ltbWV0cmljQWxnb3JpdGhtcy5wdXNoKGJ5dGVzW215cG9zKytdLmNoYXJDb2RlQXQoKSk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTI6XG4gICAgICAgIC8vIFJldm9jYXRpb24gS2V5XG4gICAgICAgIC8vICgxIG9jdGV0IG9mIGNsYXNzLCAxIG9jdGV0IG9mIHB1YmxpYy1rZXkgYWxnb3JpdGhtIElELCAyMFxuICAgICAgICAvLyBvY3RldHMgb2ZcbiAgICAgICAgLy8gZmluZ2VycHJpbnQpXG4gICAgICAgIHRoaXMucmV2b2NhdGlvbktleUNsYXNzID0gYnl0ZXNbbXlwb3MrK10uY2hhckNvZGVBdCgpO1xuICAgICAgICB0aGlzLnJldm9jYXRpb25LZXlBbGdvcml0aG0gPSBieXRlc1tteXBvcysrXS5jaGFyQ29kZUF0KCk7XG4gICAgICAgIHRoaXMucmV2b2NhdGlvbktleUZpbmdlcnByaW50ID0gYnl0ZXMuc3Vic3RyKG15cG9zLCAyMCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIDE2OlxuICAgICAgICAvLyBJc3N1ZXJcbiAgICAgICAgdGhpcy5pc3N1ZXJLZXlJZCA9IGJ5dGVzLnN1YnN0cihteXBvcywgOCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIDIwOlxuICAgICAgICAvLyBOb3RhdGlvbiBEYXRhXG4gICAgICAgIC8vIFdlIGRvbid0IGtub3cgaG93IHRvIGhhbmRsZSBhbnl0aGluZyBidXQgYSB0ZXh0IGZsYWdnZWQgZGF0YS5cbiAgICAgICAgaWYgKGJ5dGVzW215cG9zXS5jaGFyQ29kZUF0KCkgPT0gMHg4MCkge1xuXG4gICAgICAgICAgLy8gV2UgZXh0cmFjdCBrZXkvdmFsdWUgdHVwbGUgZnJvbSB0aGUgYnl0ZSBzdHJlYW0uXG4gICAgICAgICAgbXlwb3MgKz0gNDtcbiAgICAgICAgICB2YXIgbSA9IHV0aWwud3JpdGVOdW1iZXIoYnl0ZXMuc3Vic3RyKG15cG9zLCAyKSk7XG4gICAgICAgICAgbXlwb3MgKz0gMlxuICAgICAgICAgIHZhciBuID0gdXRpbC53cml0ZU51bWJlcihieXRlcy5zdWJzdHIobXlwb3MsIDIpKTtcbiAgICAgICAgICBteXBvcyArPSAyXG5cbiAgICAgICAgICB2YXIgbmFtZSA9IGJ5dGVzLnN1YnN0cihteXBvcywgbSksXG4gICAgICAgICAgICB2YWx1ZSA9IGJ5dGVzLnN1YnN0cihteXBvcyArIG0sIG4pO1xuXG4gICAgICAgICAgdGhpcy5ub3RhdGlvbltuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9IGVsc2UgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgbm90YXRpb24gZmxhZy5cIik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyMTpcbiAgICAgICAgLy8gUHJlZmVycmVkIEhhc2ggQWxnb3JpdGhtc1xuICAgICAgICByZWFkX2FycmF5LmNhbGwodGhpcywgJ3ByZWZlcnJlZEhhc2hBbGdvcml0aG1zJywgYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyMjpcbiAgICAgICAgLy8gUHJlZmVycmVkIENvbXByZXNzaW9uIEFsZ29yaXRobXNcbiAgICAgICAgcmVhZF9hcnJheS5jYWxsKHRoaXMsICdwcmVmZXJyZWRDb21wcmVzc2lvbkFsZ29yaXRobXMgJywgYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyMzpcbiAgICAgICAgLy8gS2V5IFNlcnZlciBQcmVmZXJlbmNlc1xuICAgICAgICByZWFkX2FycmF5LmNhbGwodGhpcywgJ2tleVNlcnZlclByZWZlcmVuY2VzcycsIGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjQ6XG4gICAgICAgIC8vIFByZWZlcnJlZCBLZXkgU2VydmVyXG4gICAgICAgIHRoaXMucHJlZmVycmVkS2V5U2VydmVyID0gYnl0ZXMuc3Vic3RyKG15cG9zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI1OlxuICAgICAgICAvLyBQcmltYXJ5IFVzZXIgSURcbiAgICAgICAgdGhpcy5pc1ByaW1hcnlVc2VySUQgPSBieXRlc1tteXBvcysrXSAhPSAwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjY6XG4gICAgICAgIC8vIFBvbGljeSBVUklcbiAgICAgICAgdGhpcy5wb2xpY3lVUkkgPSBieXRlcy5zdWJzdHIobXlwb3MpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjc6XG4gICAgICAgIC8vIEtleSBGbGFnc1xuICAgICAgICByZWFkX2FycmF5LmNhbGwodGhpcywgJ2tleUZsYWdzJywgYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyODpcbiAgICAgICAgLy8gU2lnbmVyJ3MgVXNlciBJRFxuICAgICAgICB0aGlzLnNpZ25lcnNVc2VySWQgKz0gYnl0ZXMuc3Vic3RyKG15cG9zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI5OlxuICAgICAgICAvLyBSZWFzb24gZm9yIFJldm9jYXRpb25cbiAgICAgICAgdGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uRmxhZyA9IGJ5dGVzW215cG9zKytdLmNoYXJDb2RlQXQoKTtcbiAgICAgICAgdGhpcy5yZWFzb25Gb3JSZXZvY2F0aW9uU3RyaW5nID0gYnl0ZXMuc3Vic3RyKG15cG9zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDMwOlxuICAgICAgICAvLyBGZWF0dXJlc1xuICAgICAgICByZWFkX2FycmF5LmNhbGwodGhpcywgJ2ZlYXR1cmVzJywgYnl0ZXMuc3Vic3RyKG15cG9zKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzMTpcbiAgICAgICAgLy8gU2lnbmF0dXJlIFRhcmdldFxuICAgICAgICAvLyAoMSBvY3RldCBwdWJsaWMta2V5IGFsZ29yaXRobSwgMSBvY3RldCBoYXNoIGFsZ29yaXRobSwgTiBvY3RldHMgaGFzaClcbiAgICAgICAgdGhpcy5zaWduYXR1cmVUYXJnZXRQdWJsaWNLZXlBbGdvcml0aG0gPSBieXRlc1tteXBvcysrXS5jaGFyQ29kZUF0KCk7XG4gICAgICAgIHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSA9IGJ5dGVzW215cG9zKytdLmNoYXJDb2RlQXQoKTtcblxuICAgICAgICB2YXIgbGVuID0gY3J5cHRvLmdldEhhc2hCeXRlTGVuZ3RoKHRoaXMuc2lnbmF0dXJlVGFyZ2V0SGFzaEFsZ29yaXRobSk7XG5cbiAgICAgICAgdGhpcy5zaWduYXR1cmVUYXJnZXRIYXNoID0gYnl0ZXMuc3Vic3RyKG15cG9zLCBsZW4pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzI6XG4gICAgICAgIC8vIEVtYmVkZGVkIFNpZ25hdHVyZVxuICAgICAgICB0aGlzLmVtYmVkZGVkU2lnbmF0dXJlID0gbmV3IHBhY2tldF9zaWduYXR1cmUoKTtcbiAgICAgICAgdGhpcy5lbWJlZGRlZFNpZ25hdHVyZS5yZWFkKGJ5dGVzLnN1YnN0cihteXBvcykpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHV0aWwucHJpbnRfZXJyb3IoXCJvcGVucGdwLnBhY2tldC5zaWduYXR1cmUuanNcXG5cIiArXG4gICAgICAgICAgJ3Vua25vd24gc2lnbmF0dXJlIHN1YnBhY2tldCB0eXBlICcgKyB0eXBlICsgXCIgQDpcIiArIG15cG9zICtcbiAgICAgICAgICBcIiBzdWJwbGVuOlwiICsgc3VicGxlbiArIFwiIGxlbjpcIiArIGxlbik7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfTtcblxuICAvLyBQcm9kdWNlcyBkYXRhIHRvIHByb2R1Y2Ugc2lnbmF0dXJlIG9uXG4gIHRoaXMudG9TaWduID0gZnVuY3Rpb24odHlwZSwgZGF0YSkge1xuICAgIHZhciB0ID0gZW51bXMuc2lnbmF0dXJlO1xuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIHQuYmluYXJ5OlxuICAgICAgICByZXR1cm4gZGF0YS5nZXRCeXRlcygpO1xuXG4gICAgICBjYXNlIHQudGV4dDpcbiAgICAgICAgcmV0dXJuIHRoaXMudG9TaWduKHQuYmluYXJ5LCBkYXRhKVxuICAgICAgICAgIC5yZXBsYWNlKC9cXHJcXG4vZywgJ1xcbicpXG4gICAgICAgICAgLnJlcGxhY2UoL1xcbi9nLCAnXFxyXFxuJyk7XG5cbiAgICAgIGNhc2UgdC5zdGFuZGFsb25lOlxuICAgICAgICByZXR1cm4gJyc7XG5cbiAgICAgIGNhc2UgdC5jZXJ0X2dlbmVyaWM6XG4gICAgICBjYXNlIHQuY2VydF9wZXJzb25hOlxuICAgICAgY2FzZSB0LmNlcnRfY2FzdWFsOlxuICAgICAgY2FzZSB0LmNlcnRfcG9zaXRpdmU6XG4gICAgICBjYXNlIHQuY2VydF9yZXZvY2F0aW9uOlxuICAgICAgICB7XG4gICAgICAgICAgdmFyIHBhY2tldCwgdGFnO1xuXG4gICAgICAgICAgaWYgKGRhdGEudXNlcmlkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRhZyA9IDB4QjQ7XG4gICAgICAgICAgICBwYWNrZXQgPSBkYXRhLnVzZXJpZDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGRhdGEudXNlcmF0dHJpYnV0ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0YWcgPSAweEQxO1xuICAgICAgICAgICAgcGFja2V0ID0gZGF0YS51c2VyYXR0cmlidXRlO1xuICAgICAgICAgIH0gZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ0VpdGhlciBhIHVzZXJpZCBvciB1c2VyYXR0cmlidXRlIHBhY2tldCBuZWVkcyB0byBiZSAnICtcbiAgICAgICAgICAgICAgJ3N1cHBsaWVkIGZvciBjZXJ0aWZpY2F0aW9uLicpO1xuXG4gICAgICAgICAgdmFyIGJ5dGVzID0gcGFja2V0LndyaXRlKCk7XG5cbiAgICAgICAgICByZXR1cm4gdGhpcy50b1NpZ24odC5rZXksIGRhdGEpICtcbiAgICAgICAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUodGFnKSArXG4gICAgICAgICAgICB1dGlsLndyaXRlTnVtYmVyKGJ5dGVzLmxlbmd0aCwgNCkgK1xuICAgICAgICAgICAgYnl0ZXM7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgdC5zdWJrZXlfYmluZGluZzpcbiAgICAgIGNhc2UgdC5rZXlfYmluZGluZzpcbiAgICAgICAge1xuICAgICAgICAgIHJldHVybiB0aGlzLnRvU2lnbih0LmtleSwgZGF0YSkgKyB0aGlzLnRvU2lnbih0LmtleSwge1xuICAgICAgICAgICAga2V5OiBkYXRhLmJpbmRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgY2FzZSB0LmtleTpcbiAgICAgICAge1xuICAgICAgICAgIGlmIChkYXRhLmtleSA9PSB1bmRlZmluZWQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0tleSBwYWNrZXQgaXMgcmVxdWlyZWQgZm9yIHRoaXMgc2lndGF0dXJlLicpO1xuXG4gICAgICAgICAgcmV0dXJuIGRhdGEua2V5LndyaXRlT2xkKCk7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgdC5rZXlfcmV2b2NhdGlvbjpcbiAgICAgIGNhc2UgdC5zdWJrZXlfcmV2b2NhdGlvbjpcbiAgICAgICAgcmV0dXJuIHRoaXMudG9TaWduKHQua2V5LCBkYXRhKTtcbiAgICAgIGNhc2UgdC50aW1lc3RhbXA6XG4gICAgICAgIHJldHVybiAnJztcbiAgICAgIGNhc2UgdC50aHJpZF9wYXJ0eTpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gc2lnbmF0dXJlIHR5cGUuJylcbiAgICB9XG4gIH1cblxuXG4gIHRoaXMuY2FsY3VsYXRlVHJhaWxlciA9IGZ1bmN0aW9uKCkge1xuICAgIC8vIGNhbGN1bGF0aW5nIHRoZSB0cmFpbGVyXG4gICAgdmFyIHRyYWlsZXIgPSAnJztcbiAgICB0cmFpbGVyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoNCk7IC8vIFZlcnNpb25cbiAgICB0cmFpbGVyICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMHhGRik7XG4gICAgdHJhaWxlciArPSB1dGlsLndyaXRlTnVtYmVyKHRoaXMuc2lnbmF0dXJlRGF0YS5sZW5ndGgsIDQpO1xuICAgIHJldHVybiB0cmFpbGVyXG4gIH1cblxuXG4gIC8qKlxuICAgKiB2ZXJpZnlzIHRoZSBzaWduYXR1cmUgcGFja2V0LiBOb3RlOiBub3Qgc2lnbmF0dXJlIHR5cGVzIGFyZSBpbXBsZW1lbnRlZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSBkYXRhIHdoaWNoIG9uIHRoZSBzaWduYXR1cmUgYXBwbGllc1xuICAgKiBAcGFyYW0ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXl9IGtleSB0aGUgcHVibGljIGtleSB0byB2ZXJpZnkgdGhlIHNpZ25hdHVyZVxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIG1lc3NhZ2UgaXMgdmVyaWZpZWQsIGVsc2UgZmFsc2UuXG4gICAqL1xuICB0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uKGtleSwgZGF0YSkge1xuICAgIHZhciBzaWduYXR1cmVUeXBlID0gZW51bXMud3JpdGUoZW51bXMuc2lnbmF0dXJlLCB0aGlzLnNpZ25hdHVyZVR5cGUpLFxuICAgICAgcHVibGljS2V5QWxnb3JpdGhtID0gZW51bXMud3JpdGUoZW51bXMucHVibGljS2V5LCB0aGlzLnB1YmxpY0tleUFsZ29yaXRobSksXG4gICAgICBoYXNoQWxnb3JpdGhtID0gZW51bXMud3JpdGUoZW51bXMuaGFzaCwgdGhpcy5oYXNoQWxnb3JpdGhtKTtcblxuICAgIHZhciBieXRlcyA9IHRoaXMudG9TaWduKHNpZ25hdHVyZVR5cGUsIGRhdGEpLFxuICAgICAgdHJhaWxlciA9IHRoaXMuY2FsY3VsYXRlVHJhaWxlcigpO1xuXG5cbiAgICB2YXIgbXBpY291bnQgPSAwO1xuICAgIC8vIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIFJTQSBzaWduYXR1cmVzOlxuICAgIC8vIFx0ICAgIC0gbXVsdGlwcmVjaXNpb24gbnVtYmVyIChNUEkpIG9mIFJTQSBzaWduYXR1cmUgdmFsdWUgbSoqZCBtb2Qgbi5cbiAgICBpZiAocHVibGljS2V5QWxnb3JpdGhtID4gMCAmJiBwdWJsaWNLZXlBbGdvcml0aG0gPCA0KVxuICAgICAgbXBpY291bnQgPSAxO1xuICAgIC8vICAgIEFsZ29yaXRobS1TcGVjaWZpYyBGaWVsZHMgZm9yIERTQSBzaWduYXR1cmVzOlxuICAgIC8vICAgICAgLSBNUEkgb2YgRFNBIHZhbHVlIHIuXG4gICAgLy8gICAgICAtIE1QSSBvZiBEU0EgdmFsdWUgcy5cbiAgICBlbHNlIGlmIChwdWJsaWNLZXlBbGdvcml0aG0gPT0gMTcpXG4gICAgICBtcGljb3VudCA9IDI7XG5cbiAgICB2YXIgbXBpID0gW10sXG4gICAgICBpID0gMDtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1waWNvdW50OyBqKyspIHtcbiAgICAgIG1waVtqXSA9IG5ldyB0eXBlX21waSgpO1xuICAgICAgaSArPSBtcGlbal0ucmVhZCh0aGlzLnNpZ25hdHVyZS5zdWJzdHIoaSkpO1xuICAgIH1cblxuICAgIHRoaXMudmVyaWZpZWQgPSBjcnlwdG8uc2lnbmF0dXJlLnZlcmlmeShwdWJsaWNLZXlBbGdvcml0aG0sXG4gICAgICBoYXNoQWxnb3JpdGhtLCBtcGksIGtleS5tcGksXG4gICAgICBieXRlcyArIHRoaXMuc2lnbmF0dXJlRGF0YSArIHRyYWlsZXIpO1xuXG4gICAgcmV0dXJuIHRoaXMudmVyaWZpZWQ7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIFN5bS4gRW5jcnlwdGVkIEludGVncml0eSBQcm90ZWN0ZWQgRGF0YSBcbiAqIFBhY2tldCAoVGFnIDE4KVxuICogXG4gKiBSRkM0ODgwIDUuMTM6IFRoZSBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBJbnRlZ3JpdHkgUHJvdGVjdGVkIERhdGEgcGFja2V0IGlzXG4gKiBhIHZhcmlhbnQgb2YgdGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgcGFja2V0LiBJdCBpcyBhIG5ldyBmZWF0dXJlXG4gKiBjcmVhdGVkIGZvciBPcGVuUEdQIHRoYXQgYWRkcmVzc2VzIHRoZSBwcm9ibGVtIG9mIGRldGVjdGluZyBhIG1vZGlmaWNhdGlvbiB0b1xuICogZW5jcnlwdGVkIGRhdGEuIEl0IGlzIHVzZWQgaW4gY29tYmluYXRpb24gd2l0aCBhIE1vZGlmaWNhdGlvbiBEZXRlY3Rpb24gQ29kZVxuICogcGFja2V0LlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3N5bV9lbmNyeXB0ZWRfaW50ZWdyaXR5X3Byb3RlY3RlZCgpIHtcbiAgLyoqIFRoZSBlbmNyeXB0ZWQgcGF5bG9hZC4gKi9cbiAgdGhpcy5lbmNyeXB0ZWQgPSBudWxsOyAvLyBzdHJpbmdcbiAgLyoqIEB0eXBlIHtCb29sZWFufVxuICAgKiBJZiBhZnRlciBkZWNyeXB0aW5nIHRoZSBwYWNrZXQgdGhpcyBpcyBzZXQgdG8gdHJ1ZSxcbiAgICogYSBtb2RpZmljYXRpb24gaGFzIGJlZW4gZGV0ZWN0ZWQgYW5kIHRodXMgdGhlIGNvbnRlbnRzXG4gICAqIHNob3VsZCBiZSBkaXNjYXJkZWQuXG4gICAqL1xuICB0aGlzLm1vZGlmaWNhdGlvbiA9IGZhbHNlO1xuICB0aGlzLnBhY2tldHM7XG5cblxuICB0aGlzLnJlYWQgPSBmdW5jdGlvbihieXRlcykge1xuICAgIC8vIC0gQSBvbmUtb2N0ZXQgdmVyc2lvbiBudW1iZXIuIFRoZSBvbmx5IGN1cnJlbnRseSBkZWZpbmVkIHZhbHVlIGlzXG4gICAgLy8gMS5cbiAgICB2YXIgdmVyc2lvbiA9IGJ5dGVzWzBdLmNoYXJDb2RlQXQoKTtcblxuICAgIGlmICh2ZXJzaW9uICE9IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBwYWNrZXQgdmVyc2lvbi4nKTtcbiAgICB9XG5cbiAgICAvLyAtIEVuY3J5cHRlZCBkYXRhLCB0aGUgb3V0cHV0IG9mIHRoZSBzZWxlY3RlZCBzeW1tZXRyaWMta2V5IGNpcGhlclxuICAgIC8vICAgb3BlcmF0aW5nIGluIENpcGhlciBGZWVkYmFjayBtb2RlIHdpdGggc2hpZnQgYW1vdW50IGVxdWFsIHRvIHRoZVxuICAgIC8vICAgYmxvY2sgc2l6ZSBvZiB0aGUgY2lwaGVyIChDRkItbiB3aGVyZSBuIGlzIHRoZSBibG9jayBzaXplKS5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGJ5dGVzLnN1YnN0cigxKTtcbiAgfVxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcblxuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDEpIC8vIFZlcnNpb25cbiAgICArIHRoaXMuZW5jcnlwdGVkO1xuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24oc2Vzc2lvbktleUFsZ29yaXRobSwga2V5KSB7XG4gICAgdmFyIGJ5dGVzID0gdGhpcy5wYWNrZXRzLndyaXRlKClcblxuICAgIHZhciBwcmVmaXhyYW5kb20gPSBjcnlwdG8uZ2V0UHJlZml4UmFuZG9tKHNlc3Npb25LZXlBbGdvcml0aG0pO1xuICAgIHZhciBwcmVmaXggPSBwcmVmaXhyYW5kb20gKyBwcmVmaXhyYW5kb20uY2hhckF0KHByZWZpeHJhbmRvbS5sZW5ndGggLSAyKSArIHByZWZpeHJhbmRvbS5jaGFyQXQocHJlZml4cmFuZG9tLmxlbmd0aCAtXG4gICAgICAxKVxuXG4gICAgdmFyIHRvaGFzaCA9IGJ5dGVzO1xuXG5cbiAgICAvLyBNb2RpZmljYXRpb24gZGV0ZWN0aW9uIGNvZGUgcGFja2V0LlxuICAgIHRvaGFzaCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RDMpO1xuICAgIHRvaGFzaCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MTQpO1xuXG5cbiAgICB0b2hhc2ggKz0gY3J5cHRvLmhhc2guc2hhMShwcmVmaXggKyB0b2hhc2gpO1xuXG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5jZmIuZW5jcnlwdChwcmVmaXhyYW5kb20sXG4gICAgICBzZXNzaW9uS2V5QWxnb3JpdGhtLCB0b2hhc2gsIGtleSwgZmFsc2UpLnN1YnN0cmluZygwLFxuICAgICAgcHJlZml4Lmxlbmd0aCArIHRvaGFzaC5sZW5ndGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBlbmNyeXB0ZWQgZGF0YSBjb250YWluZWQgaW4gdGhpcyBvYmplY3QgcmVhZF9wYWNrZXQgbXVzdFxuICAgKiBoYXZlIGJlZW4gY2FsbGVkIGJlZm9yZVxuICAgKiBcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBzZXNzaW9uS2V5QWxnb3JpdGhtXG4gICAqICAgICAgICAgICAgVGhlIHNlbGVjdGVkIHN5bW1ldHJpYyBlbmNyeXB0aW9uIGFsZ29yaXRobSB0byBiZSB1c2VkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgVGhlIGtleSBvZiBjaXBoZXIgYmxvY2tzaXplIGxlbmd0aCB0byBiZSB1c2VkXG4gICAqIEByZXR1cm4ge1N0cmluZ30gVGhlIGRlY3J5cHRlZCBkYXRhIG9mIHRoaXMgcGFja2V0XG4gICAqL1xuICB0aGlzLmRlY3J5cHQgPSBmdW5jdGlvbihzZXNzaW9uS2V5QWxnb3JpdGhtLCBrZXkpIHtcbiAgICB2YXIgZGVjcnlwdGVkID0gY3J5cHRvLmNmYi5kZWNyeXB0KFxuICAgICAgc2Vzc2lvbktleUFsZ29yaXRobSwga2V5LCB0aGlzLmVuY3J5cHRlZCwgZmFsc2UpO1xuXG5cbiAgICAvLyB0aGVyZSBtdXN0IGJlIGEgbW9kaWZpY2F0aW9uIGRldGVjdGlvbiBjb2RlIHBhY2tldCBhcyB0aGVcbiAgICAvLyBsYXN0IHBhY2tldCBhbmQgZXZlcnl0aGluZyBnZXRzIGhhc2hlZCBleGNlcHQgdGhlIGhhc2ggaXRzZWxmXG4gICAgdGhpcy5oYXNoID0gY3J5cHRvLmhhc2guc2hhMShcbiAgICAgIGNyeXB0by5jZmIubWRjKHNlc3Npb25LZXlBbGdvcml0aG0sIGtleSwgdGhpcy5lbmNyeXB0ZWQpICsgZGVjcnlwdGVkLnN1YnN0cmluZygwLCBkZWNyeXB0ZWQubGVuZ3RoIC0gMjApKTtcblxuXG4gICAgdmFyIG1kYyA9IGRlY3J5cHRlZC5zdWJzdHIoZGVjcnlwdGVkLmxlbmd0aCAtIDIwLCAyMCk7XG5cbiAgICBpZiAodGhpcy5oYXNoICE9IG1kYykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNb2RpZmljYXRpb24gZGV0ZWN0ZWQuJyk7XG4gICAgfSBlbHNlXG4gICAgICB0aGlzLnBhY2tldHMucmVhZChkZWNyeXB0ZWQuc3Vic3RyKDAsIGRlY3J5cHRlZC5sZW5ndGggLSAyMikpO1xuICB9XG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIHR5cGVfczJrID0gcmVxdWlyZSgnLi4vdHlwZS9zMmsuanMnKSxcbiAgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgUHVibGljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgUGFja2V0cyAoVGFnIDEpXG4gKiBcbiAqIFJGQzQ4ODAgNS4xOiBBIFB1YmxpYy1LZXkgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldCBob2xkcyB0aGUgc2Vzc2lvbiBrZXlcbiAqIHVzZWQgdG8gZW5jcnlwdCBhIG1lc3NhZ2UuIFplcm8gb3IgbW9yZSBQdWJsaWMtS2V5IEVuY3J5cHRlZCBTZXNzaW9uIEtleVxuICogcGFja2V0cyBhbmQvb3IgU3ltbWV0cmljLUtleSBFbmNyeXB0ZWQgU2Vzc2lvbiBLZXkgcGFja2V0cyBtYXkgcHJlY2VkZSBhXG4gKiBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCwgd2hpY2ggaG9sZHMgYW4gZW5jcnlwdGVkIG1lc3NhZ2UuIFRoZVxuICogbWVzc2FnZSBpcyBlbmNyeXB0ZWQgd2l0aCB0aGUgc2Vzc2lvbiBrZXksIGFuZCB0aGUgc2Vzc2lvbiBrZXkgaXMgaXRzZWxmXG4gKiBlbmNyeXB0ZWQgYW5kIHN0b3JlZCBpbiB0aGUgRW5jcnlwdGVkIFNlc3Npb24gS2V5IHBhY2tldChzKS4gVGhlXG4gKiBTeW1tZXRyaWNhbGx5IEVuY3J5cHRlZCBEYXRhIFBhY2tldCBpcyBwcmVjZWRlZCBieSBvbmUgUHVibGljLUtleSBFbmNyeXB0ZWRcbiAqIFNlc3Npb24gS2V5IHBhY2tldCBmb3IgZWFjaCBPcGVuUEdQIGtleSB0byB3aGljaCB0aGUgbWVzc2FnZSBpcyBlbmNyeXB0ZWQuXG4gKiBUaGUgcmVjaXBpZW50IG9mIHRoZSBtZXNzYWdlIGZpbmRzIGEgc2Vzc2lvbiBrZXkgdGhhdCBpcyBlbmNyeXB0ZWQgdG8gdGhlaXJcbiAqIHB1YmxpYyBrZXksIGRlY3J5cHRzIHRoZSBzZXNzaW9uIGtleSwgYW5kIHRoZW4gdXNlcyB0aGUgc2Vzc2lvbiBrZXkgdG9cbiAqIGRlY3J5cHQgdGhlIG1lc3NhZ2UuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFja2V0X3N5bV9lbmNyeXB0ZWRfc2Vzc2lvbl9rZXkoKSB7XG4gIHRoaXMudGFnID0gMztcbiAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSA9IG51bGw7XG4gIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9ICdhZXMyNTYnO1xuICB0aGlzLmVuY3J5cHRlZCA9IG51bGw7XG4gIHRoaXMuczJrID0gbmV3IHR5cGVfczJrKCk7XG5cbiAgLyoqXG4gICAqIFBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgc3ltbWV0cmljIGVuY3J5cHRlZCBzZXNzaW9uIGtleSBwYWNrZXQgKHRhZyAzKS5cbiAgICogXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dCBQYXlsb2FkIG9mIGEgdGFnIDEgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW5cbiAgICogICAgICAgICAgICBMZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZlxuICAgKiAgICAgICAgICAgIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IE9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICAvLyBBIG9uZS1vY3RldCB2ZXJzaW9uIG51bWJlci4gVGhlIG9ubHkgY3VycmVudGx5IGRlZmluZWQgdmVyc2lvbiBpcyA0LlxuICAgIHRoaXMudmVyc2lvbiA9IGJ5dGVzWzBdLmNoYXJDb2RlQXQoKTtcblxuICAgIC8vIEEgb25lLW9jdGV0IG51bWJlciBkZXNjcmliaW5nIHRoZSBzeW1tZXRyaWMgYWxnb3JpdGhtIHVzZWQuXG4gICAgdmFyIGFsZ28gPSBlbnVtcy5yZWFkKGVudW1zLnN5bW1ldHJpYywgYnl0ZXNbMV0uY2hhckNvZGVBdCgpKTtcblxuICAgIC8vIEEgc3RyaW5nLXRvLWtleSAoUzJLKSBzcGVjaWZpZXIsIGxlbmd0aCBhcyBkZWZpbmVkIGFib3ZlLlxuICAgIHZhciBzMmtsZW5ndGggPSB0aGlzLnMyay5yZWFkKGJ5dGVzLnN1YnN0cigyKSk7XG5cbiAgICAvLyBPcHRpb25hbGx5LCB0aGUgZW5jcnlwdGVkIHNlc3Npb24ga2V5IGl0c2VsZiwgd2hpY2ggaXMgZGVjcnlwdGVkXG4gICAgLy8gd2l0aCB0aGUgc3RyaW5nLXRvLWtleSBvYmplY3QuXG4gICAgdmFyIGRvbmUgPSBzMmtsZW5ndGggKyAyO1xuXG4gICAgaWYgKGRvbmUgPCBieXRlcy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuZW5jcnlwdGVkID0gYnl0ZXMuc3Vic3RyKGRvbmUpO1xuICAgICAgdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSA9IGFsZ29cbiAgICB9IGVsc2VcbiAgICAgIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA9IGFsZ287XG4gIH1cblxuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFsZ28gPSB0aGlzLmVuY3J5cHRlZCA9PSBudWxsID9cbiAgICAgIHRoaXMuc2Vzc2lvbktleUFsZ29yaXRobSA6XG4gICAgICB0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtO1xuXG4gICAgdmFyIGJ5dGVzID0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLnZlcnNpb24pICtcbiAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMuc3ltbWV0cmljLCBhbGdvKSkgK1xuICAgICAgdGhpcy5zMmsud3JpdGUoKTtcblxuICAgIGlmICh0aGlzLmVuY3J5cHRlZCAhPSBudWxsKVxuICAgICAgYnl0ZXMgKz0gdGhpcy5lbmNyeXB0ZWQ7XG4gICAgcmV0dXJuIGJ5dGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIERlY3J5cHRzIHRoZSBzZXNzaW9uIGtleSAob25seSBmb3IgcHVibGljIGtleSBlbmNyeXB0ZWQgc2Vzc2lvbiBrZXlcbiAgICogcGFja2V0cyAodGFnIDEpXG4gICAqIFxuICAgKiBAcGFyYW0ge29wZW5wZ3BfbXNnX21lc3NhZ2V9IG1zZ1xuICAgKiAgICAgICAgICAgIFRoZSBtZXNzYWdlIG9iamVjdCAod2l0aCBtZW1iZXIgZW5jcnlwdGVkRGF0YVxuICAgKiBAcGFyYW0ge29wZW5wZ3BfbXNnX3ByaXZhdGVrZXl9IGtleVxuICAgKiAgICAgICAgICAgIFByaXZhdGUga2V5IHdpdGggc2VjTVBJcyB1bmxvY2tlZFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFRoZSB1bmVuY3J5cHRlZCBzZXNzaW9uIGtleVxuICAgKi9cbiAgdGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24ocGFzc3BocmFzZSkge1xuICAgIHZhciBhbGdvID0gdGhpcy5zZXNzaW9uS2V5RW5jcnlwdGlvbkFsZ29yaXRobSAhPSBudWxsID9cbiAgICAgIHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0gOlxuICAgICAgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtO1xuXG5cbiAgICB2YXIgbGVuZ3RoID0gY3J5cHRvLmNpcGhlclthbGdvXS5rZXlTaXplO1xuICAgIHZhciBrZXkgPSB0aGlzLnMyay5wcm9kdWNlX2tleShwYXNzcGhyYXNlLCBsZW5ndGgpO1xuXG4gICAgaWYgKHRoaXMuZW5jcnlwdGVkID09IG51bGwpIHtcbiAgICAgIHRoaXMuc2Vzc2lvbktleSA9IGtleTtcblxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZGVjcnlwdGVkID0gY3J5cHRvLmNmYi5kZWNyeXB0KFxuICAgICAgICB0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtLCBrZXksIHRoaXMuZW5jcnlwdGVkLCB0cnVlKTtcblxuICAgICAgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtID0gZW51bXMucmVhZChlbnVtcy5zeW1tZXRyaWMsXG4gICAgICAgIGRlY3J5cHRlZFswXS5rZXlDb2RlQXQoKSk7XG5cbiAgICAgIHRoaXMuc2Vzc2lvbktleSA9IGRlY3J5cHRlZC5zdWJzdHIoMSk7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5lbmNyeXB0ID0gZnVuY3Rpb24ocGFzc3BocmFzZSkge1xuICAgIHZhciBsZW5ndGggPSBjcnlwdG8uZ2V0S2V5TGVuZ3RoKHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0pO1xuICAgIHZhciBrZXkgPSB0aGlzLnMyay5wcm9kdWNlX2tleShwYXNzcGhyYXNlLCBsZW5ndGgpO1xuXG4gICAgdmFyIHByaXZhdGVfa2V5ID0gU3RyaW5nLmZyb21DaGFyQ29kZShcbiAgICAgIGVudW1zLndyaXRlKGVudW1zLnN5bW1ldHJpYywgdGhpcy5zZXNzaW9uS2V5QWxnb3JpdGhtKSkgK1xuXG4gICAgY3J5cHRvLmdldFJhbmRvbUJ5dGVzKFxuICAgICAgY3J5cHRvLmdldEtleUxlbmd0aCh0aGlzLnNlc3Npb25LZXlBbGdvcml0aG0pKTtcblxuICAgIHRoaXMuZW5jcnlwdGVkID0gY3J5cHRvLmNmYi5lbmNyeXB0KFxuICAgICAgY3J5cHRvLmdldFByZWZpeFJhbmRvbSh0aGlzLnNlc3Npb25LZXlFbmNyeXB0aW9uQWxnb3JpdGhtKSxcbiAgICAgIHRoaXMuc2Vzc2lvbktleUVuY3J5cHRpb25BbGdvcml0aG0sIGtleSwgcHJpdmF0ZV9rZXksIHRydWUpO1xuICB9XG59O1xuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxudmFyIGNyeXB0byA9IHJlcXVpcmUoJy4uL2NyeXB0bycpO1xuXG4vKipcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBQYWNrZXQgKFRhZyA5KVxuICogXG4gKiBSRkM0ODgwIDUuNzogVGhlIFN5bW1ldHJpY2FsbHkgRW5jcnlwdGVkIERhdGEgcGFja2V0IGNvbnRhaW5zIGRhdGEgZW5jcnlwdGVkXG4gKiB3aXRoIGEgc3ltbWV0cmljLWtleSBhbGdvcml0aG0uIFdoZW4gaXQgaGFzIGJlZW4gZGVjcnlwdGVkLCBpdCBjb250YWlucyBvdGhlclxuICogcGFja2V0cyAodXN1YWxseSBhIGxpdGVyYWwgZGF0YSBwYWNrZXQgb3IgY29tcHJlc3NlZCBkYXRhIHBhY2tldCwgYnV0IGluXG4gKiB0aGVvcnkgb3RoZXIgU3ltbWV0cmljYWxseSBFbmNyeXB0ZWQgRGF0YSBwYWNrZXRzIG9yIHNlcXVlbmNlcyBvZiBwYWNrZXRzXG4gKiB0aGF0IGZvcm0gd2hvbGUgT3BlblBHUCBtZXNzYWdlcykuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYWNrZXRfc3ltbWV0cmljYWxseV9lbmNyeXB0ZWQoKSB7XG4gIHRoaXMuZW5jcnlwdGVkID0gbnVsbDtcbiAgLyoqIERlY3J5cHRlZCBwYWNrZXRzIGNvbnRhaW5lZCB3aXRoaW4uIFxuICAgKiBAdHlwZSB7b3BlbnBncF9wYWNrZXRsaXN0fSAqL1xuICB0aGlzLnBhY2tldHM7XG5cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB0aGlzLmVuY3J5cHRlZCA9IGJ5dGVzO1xuICB9XG5cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmVuY3J5cHRlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTeW1tZXRyaWNhbGx5IGRlY3J5cHQgdGhlIHBhY2tldCBkYXRhXG4gICAqIFxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IHNlc3Npb25LZXlBbGdvcml0aG1cbiAgICogICAgICAgICAgICAgU3ltbWV0cmljIGtleSBhbGdvcml0aG0gdG8gdXNlIC8vIFNlZSBSRkM0ODgwIDkuMlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gICAqICAgICAgICAgICAgIEtleSBhcyBzdHJpbmcgd2l0aCB0aGUgY29ycmVzcG9uZGluZyBsZW5ndGggdG8gdGhlXG4gICAqICAgICAgICAgICAgYWxnb3JpdGhtXG4gICAqIEByZXR1cm4gVGhlIGRlY3J5cHRlZCBkYXRhO1xuICAgKi9cbiAgdGhpcy5kZWNyeXB0ID0gZnVuY3Rpb24oc2Vzc2lvbktleUFsZ29yaXRobSwga2V5KSB7XG4gICAgdmFyIGRlY3J5cHRlZCA9IGNyeXB0by5jZmIuZGVjcnlwdChcbiAgICAgIHNlc3Npb25LZXlBbGdvcml0aG0sIGtleSwgdGhpcy5lbmNyeXB0ZWQsIHRydWUpO1xuXG4gICAgdGhpcy5wYWNrZXRzLnJlYWQoZGVjcnlwdGVkKTtcbiAgfVxuXG4gIHRoaXMuZW5jcnlwdCA9IGZ1bmN0aW9uKGFsZ28sIGtleSkge1xuICAgIHZhciBkYXRhID0gdGhpcy5wYWNrZXRzLndyaXRlKCk7XG5cbiAgICB0aGlzLmVuY3J5cHRlZCA9IGNyeXB0by5jZmIuZW5jcnlwdChcbiAgICAgIGNyeXB0by5nZXRQcmVmaXhSYW5kb20oYWxnbyksIGFsZ28sIGRhdGEsIGtleSwgdHJ1ZSk7XG4gIH1cbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF90cnVzdCgpIHtcblxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8qKiBcbiAqIEBjbGFzc1xuICogQGNsYXNzZGVzYyBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgVXNlciBBdHRyaWJ1dGUgUGFja2V0IChUYWcgMTcpXG4gKiAgVGhlIFVzZXIgQXR0cmlidXRlIHBhY2tldCBpcyBhIHZhcmlhdGlvbiBvZiB0aGUgVXNlciBJRCBwYWNrZXQuICBJdFxuICogIGlzIGNhcGFibGUgb2Ygc3RvcmluZyBtb3JlIHR5cGVzIG9mIGRhdGEgdGhhbiB0aGUgVXNlciBJRCBwYWNrZXQsXG4gKiAgd2hpY2ggaXMgbGltaXRlZCB0byB0ZXh0LiAgTGlrZSB0aGUgVXNlciBJRCBwYWNrZXQsIGEgVXNlciBBdHRyaWJ1dGVcbiAqICBwYWNrZXQgbWF5IGJlIGNlcnRpZmllZCBieSB0aGUga2V5IG93bmVyIChcInNlbGYtc2lnbmVkXCIpIG9yIGFueSBvdGhlclxuICogIGtleSBvd25lciB3aG8gY2FyZXMgdG8gY2VydGlmeSBpdC4gIEV4Y2VwdCBhcyBub3RlZCwgYSBVc2VyIEF0dHJpYnV0ZVxuICogIHBhY2tldCBtYXkgYmUgdXNlZCBhbnl3aGVyZSB0aGF0IGEgVXNlciBJRCBwYWNrZXQgbWF5IGJlIHVzZWQuXG4gKlxuICogIFdoaWxlIFVzZXIgQXR0cmlidXRlIHBhY2tldHMgYXJlIG5vdCBhIHJlcXVpcmVkIHBhcnQgb2YgdGhlIE9wZW5QR1BcbiAqICBzdGFuZGFyZCwgaW1wbGVtZW50YXRpb25zIFNIT1VMRCBwcm92aWRlIGF0IGxlYXN0IGVub3VnaFxuICogIGNvbXBhdGliaWxpdHkgdG8gcHJvcGVybHkgaGFuZGxlIGEgY2VydGlmaWNhdGlvbiBzaWduYXR1cmUgb24gdGhlXG4gKiAgVXNlciBBdHRyaWJ1dGUgcGFja2V0LiAgQSBzaW1wbGUgd2F5IHRvIGRvIHRoaXMgaXMgYnkgdHJlYXRpbmcgdGhlXG4gKiAgVXNlciBBdHRyaWJ1dGUgcGFja2V0IGFzIGEgVXNlciBJRCBwYWNrZXQgd2l0aCBvcGFxdWUgY29udGVudHMsIGJ1dFxuICogIGFuIGltcGxlbWVudGF0aW9uIG1heSB1c2UgYW55IG1ldGhvZCBkZXNpcmVkLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF91c2VyX2F0dHJpYnV0ZSgpIHtcbiAgdGhpcy50YWcgPSAxNztcbiAgdGhpcy5hdHRyaWJ1dGVzID0gW107XG5cbiAgLyoqXG4gICAqIHBhcnNpbmcgZnVuY3Rpb24gZm9yIGEgdXNlciBhdHRyaWJ1dGUgcGFja2V0ICh0YWcgMTcpLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgcGF5bG9hZCBvZiBhIHRhZyAxNyBwYWNrZXRcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBwb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IHN0cmluZ1xuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGxlbiBsZW5ndGggb2YgdGhlIHBhY2tldCBvciB0aGUgcmVtYWluaW5nIGxlbmd0aCBvZiBpbnB1dCBhdCBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtvcGVucGdwX3BhY2tldF9lbmNyeXB0ZWRkYXRhfSBvYmplY3QgcmVwcmVzZW50YXRpb25cbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIGkgPSAwO1xuICAgIHdoaWxlIChpIDwgYnl0ZXMubGVuZ3RoKSB7XG4gICAgICB2YXIgbGVuID0gb3BlbnBncF9wYWNrZXQucmVhZF9zaW1wbGVfbGVuZ3RoKGJ5dGVzKTtcblxuICAgICAgaSArPSBsZW4ub2Zmc2V0O1xuICAgICAgdGhpcy5hdHRyaWJ1dGVzLnB1c2goYnl0ZXMuc3Vic3RyKGksIGxlbi5sZW4pKTtcbiAgICAgIGkgKz0gbGVuLmxlbjtcbiAgICB9XG4gIH1cbn07XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJy4uL3V0aWwnKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIFVzZXIgSUQgUGFja2V0IChUYWcgMTMpXG4gKiBBIFVzZXIgSUQgcGFja2V0IGNvbnNpc3RzIG9mIFVURi04IHRleHQgdGhhdCBpcyBpbnRlbmRlZCB0byByZXByZXNlbnRcbiAqIHRoZSBuYW1lIGFuZCBlbWFpbCBhZGRyZXNzIG9mIHRoZSBrZXkgaG9sZGVyLiAgQnkgY29udmVudGlvbiwgaXRcbiAqIGluY2x1ZGVzIGFuIFJGQyAyODIyIFtSRkMyODIyXSBtYWlsIG5hbWUtYWRkciwgYnV0IHRoZXJlIGFyZSBub1xuICogcmVzdHJpY3Rpb25zIG9uIGl0cyBjb250ZW50LiAgVGhlIHBhY2tldCBsZW5ndGggaW4gdGhlIGhlYWRlclxuICogc3BlY2lmaWVzIHRoZSBsZW5ndGggb2YgdGhlIFVzZXIgSUQuIFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhY2tldF91c2VyaWQoKSB7XG4gIC8qKiBAdHlwZSB7U3RyaW5nfSBBIHN0cmluZyBjb250YWluaW5nIHRoZSB1c2VyIGlkLiBVc3VhbGx5IGluIHRoZSBmb3JtXG4gICAqIEpvaG4gRG9lIDxqb2huQGV4YW1wbGUuY29tPiBcbiAgICovXG4gIHRoaXMudXNlcmlkID0gJyc7XG5cblxuICAvKipcbiAgICogUGFyc2luZyBmdW5jdGlvbiBmb3IgYSB1c2VyIGlkIHBhY2tldCAodGFnIDEzKS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IHBheWxvYWQgb2YgYSB0YWcgMTMgcGFja2V0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gcG9zaXRpb24gcG9zaXRpb24gdG8gc3RhcnQgcmVhZGluZyBmcm9tIHRoZSBpbnB1dCBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gbGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2YgaW5wdXQgXG4gICAqIGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfcGFja2V0X2VuY3J5cHRlZGRhdGF9IG9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB0aGlzLnVzZXJpZCA9IHV0aWwuZGVjb2RlX3V0ZjgoYnl0ZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHVzZXIgaWQgcGFja2V0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB1c2VyX2lkIHRoZSB1c2VyIGlkIGFzIHN0cmluZyAoXCJKb2huIERvZSA8am9obi5kb2VAbWFpbC51c1wiKVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB1dGlsLmVuY29kZV91dGY4KHRoaXMudXNlcmlkKTtcbiAgfVxufVxuIiwiLy8gR1BHNEJyb3dzZXJzIC0gQW4gT3BlblBHUCBpbXBsZW1lbnRhdGlvbiBpbiBqYXZhc2NyaXB0XG4vLyBDb3B5cmlnaHQgKEMpIDIwMTEgUmVjdXJpdHkgTGFicyBHbWJIXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3Jcbi8vIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlclxuLy8gdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4vLyBcbi8vIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2Zcbi8vIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VXG4vLyBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuLy8gXG4vLyBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlXG4vLyBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BICAwMjExMC0xMzAxICBVU0FcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdHlwZSBrZXkgaWQgKFJGQzQ4ODAgMy4zKVxuICogIEEgS2V5IElEIGlzIGFuIGVpZ2h0LW9jdGV0IHNjYWxhciB0aGF0IGlkZW50aWZpZXMgYSBrZXkuXG4gICBJbXBsZW1lbnRhdGlvbnMgU0hPVUxEIE5PVCBhc3N1bWUgdGhhdCBLZXkgSURzIGFyZSB1bmlxdWUuICBUaGVcbiAgIHNlY3Rpb24gXCJFbmhhbmNlZCBLZXkgRm9ybWF0c1wiIGJlbG93IGRlc2NyaWJlcyBob3cgS2V5IElEcyBhcmVcbiAgIGZvcm1lZC5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBrZXlpZCgpIHtcbiAgdmFyIGJ5dGVzID0gJyc7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspXG4gICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgLyoqXG4gICAqIFBhcnNpbmcgbWV0aG9kIGZvciBhIGtleSBpZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgSW5wdXQgdG8gcmVhZCB0aGUga2V5IGlkIGZyb20gXG4gICAqIEBwYXJhbSB7aW50ZWdlcn0gcG9zaXRpb24gUG9zaXRpb24gd2hlcmUgdG8gc3RhcnQgcmVhZGluZyB0aGUga2V5IFxuICAgKiBpZCBmcm9tIGlucHV0XG4gICAqIEByZXR1cm4ge29wZW5wZ3BfdHlwZV9rZXlpZH0gVGhpcyBvYmplY3RcbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdGhpcy5ieXRlcyA9IGJ5dGVzLnN1YnN0cigwLCA4KTtcbiAgfVxuXG4gIHRoaXMud3JpdGUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5ieXRlcztcbiAgfVxufTtcbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbi8vIEhpbnQ6IFdlIGhvbGQgb3VyIE1QSXMgYXMgYW4gYXJyYXkgb2Ygb2N0ZXRzIGluIGJpZyBlbmRpYW4gZm9ybWF0IHByZWNlZWRpbmcgYSB0d29cbi8vIG9jdGV0IHNjYWxhcjogTVBJOiBbYSxiLGMsZCxlLGZdXG4vLyAtIE1QSSBzaXplOiAoYSA8PCA4KSB8IGIgXG4vLyAtIE1QSSA9IGMgfCBkIDw8IDggfCBlIDw8ICgoTVBJLmxlbmd0aCAtMikqOCkgfCBmICgoTVBJLmxlbmd0aCAtMikqOClcblxudmFyIEJpZ0ludGVnZXIgPSByZXF1aXJlKCcuLi9jcnlwdG8vcHVibGljX2tleS9qc2JuLmpzJyksXG4gIHV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY2xhc3NkZXNjSW1wbGVtZW50YXRpb24gb2YgdHlwZSBNUEkgKFJGQzQ4ODAgMy4yKVxuICogTXVsdGlwcmVjaXNpb24gaW50ZWdlcnMgKGFsc28gY2FsbGVkIE1QSXMpIGFyZSB1bnNpZ25lZCBpbnRlZ2VycyB1c2VkXG4gKiB0byBob2xkIGxhcmdlIGludGVnZXJzIHN1Y2ggYXMgdGhlIG9uZXMgdXNlZCBpbiBjcnlwdG9ncmFwaGljXG4gKiBjYWxjdWxhdGlvbnMuXG4gKiBBbiBNUEkgY29uc2lzdHMgb2YgdHdvIHBpZWNlczogYSB0d28tb2N0ZXQgc2NhbGFyIHRoYXQgaXMgdGhlIGxlbmd0aFxuICogb2YgdGhlIE1QSSBpbiBiaXRzIGZvbGxvd2VkIGJ5IGEgc3RyaW5nIG9mIG9jdGV0cyB0aGF0IGNvbnRhaW4gdGhlXG4gKiBhY3R1YWwgaW50ZWdlci5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtcGkoKSB7XG4gIC8qKiBBbiBpbXBsZW1lbnRhdGlvbiBkZXBlbmRlbnQgaW50ZWdlciAqL1xuICB0aGlzLmRhdGEgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIG1waSAoUkZDIDQ4ODAgMy4yKS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFBheWxvYWQgb2YgbXBpIGRhdGFcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3NpdGlvbiBQb3NpdGlvbiB0byBzdGFydCByZWFkaW5nIGZyb20gdGhlIGlucHV0IFxuICAgKiBzdHJpbmdcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBsZW4gTGVuZ3RoIG9mIHRoZSBwYWNrZXQgb3IgdGhlIHJlbWFpbmluZyBsZW5ndGggb2YgXG4gICAqIGlucHV0IGF0IHBvc2l0aW9uXG4gICAqIEByZXR1cm4ge29wZW5wZ3BfdHlwZV9tcGl9IE9iamVjdCByZXByZXNlbnRhdGlvblxuICAgKi9cbiAgdGhpcy5yZWFkID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgYml0cyA9IChieXRlc1swXS5jaGFyQ29kZUF0KCkgPDwgOCkgfCBieXRlc1sxXS5jaGFyQ29kZUF0KCk7XG5cbiAgICAvLyBBZGRpdGlvbmFsIHJ1bGVzOlxuICAgIC8vXG4gICAgLy8gICAgVGhlIHNpemUgb2YgYW4gTVBJIGlzICgoTVBJLmxlbmd0aCArIDcpIC8gOCkgKyAyIG9jdGV0cy5cbiAgICAvL1xuICAgIC8vICAgIFRoZSBsZW5ndGggZmllbGQgb2YgYW4gTVBJIGRlc2NyaWJlcyB0aGUgbGVuZ3RoIHN0YXJ0aW5nIGZyb20gaXRzXG4gICAgLy9cdCAgbW9zdCBzaWduaWZpY2FudCBub24temVybyBiaXQuICBUaHVzLCB0aGUgTVBJIFswMCAwMiAwMV0gaXMgbm90XG4gICAgLy8gICAgZm9ybWVkIGNvcnJlY3RseS4gIEl0IHNob3VsZCBiZSBbMDAgMDEgMDFdLlxuXG4gICAgLy8gVE9ETzogVmVyaWZpY2F0aW9uIG9mIHRoaXMgc2l6ZSBtZXRob2QhIFRoaXMgc2l6ZSBjYWxjdWxhdGlvbiBhc1xuICAgIC8vIFx0XHQgc3BlY2lmaWVkIGFib3ZlIGlzIG5vdCBhcHBsaWNhYmxlIGluIEphdmFTY3JpcHRcbiAgICB2YXIgYnl0ZWxlbiA9IE1hdGguY2VpbChiaXRzIC8gOCk7XG5cbiAgICB2YXIgcmF3ID0gYnl0ZXMuc3Vic3RyKDIsIGJ5dGVsZW4pO1xuICAgIHRoaXMuZnJvbUJ5dGVzKHJhdyk7XG5cbiAgICByZXR1cm4gMiArIGJ5dGVsZW47XG4gIH1cblxuICB0aGlzLmZyb21CeXRlcyA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdGhpcy5kYXRhID0gbmV3IEJpZ0ludGVnZXIodXRpbC5oZXhzdHJkdW1wKGJ5dGVzKSwgMTYpO1xuICB9XG5cbiAgdGhpcy50b0J5dGVzID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMud3JpdGUoKS5zdWJzdHIoMik7XG4gIH1cblxuICB0aGlzLmJ5dGVMZW5ndGggPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy50b0J5dGVzKCkubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHRoZSBtcGkgb2JqZWN0IHRvIGEgc3RyaW5nIGFzIHNwZWNpZmllZCBpbiBSRkM0ODgwIDMuMlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IG1waSBCeXRlIHJlcHJlc2VudGF0aW9uXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YS50b01QSSgpO1xuICB9XG5cbiAgdGhpcy50b0JpZ0ludGVnZXIgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhLmNsb25lKCk7XG4gIH1cblxuICB0aGlzLmZyb21CaWdJbnRlZ2VyID0gZnVuY3Rpb24oYm4pIHtcbiAgICB0aGlzLmRhdGEgPSBibi5jbG9uZSgpO1xuICB9XG59XG4iLCIvLyBHUEc0QnJvd3NlcnMgLSBBbiBPcGVuUEdQIGltcGxlbWVudGF0aW9uIGluIGphdmFzY3JpcHRcbi8vIENvcHlyaWdodCAoQykgMjAxMSBSZWN1cml0eSBMYWJzIEdtYkhcbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vclxuLy8gbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyXG4vLyB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbi8vIFxuLy8gVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4vLyBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlVcbi8vIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4vLyBcbi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWNcbi8vIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmVcbi8vIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQVxuXG52YXIgZW51bXMgPSByZXF1aXJlKCcuLi9lbnVtcy5qcycpLFxuICB1dGlsID0gcmVxdWlyZSgnLi4vdXRpbCcpLFxuICBjcnlwdG8gPSByZXF1aXJlKCcuLi9jcnlwdG8nKTtcblxuLyoqXG4gKiBAY2xhc3NcbiAqIEBjbGFzc2Rlc2MgSW1wbGVtZW50YXRpb24gb2YgdGhlIFN0cmluZy10by1rZXkgc3BlY2lmaWVyIChSRkM0ODgwIDMuNylcbiAqIFN0cmluZy10by1rZXkgKFMySykgc3BlY2lmaWVycyBhcmUgdXNlZCB0byBjb252ZXJ0IHBhc3NwaHJhc2Ugc3RyaW5nc1xuICAgaW50byBzeW1tZXRyaWMta2V5IGVuY3J5cHRpb24vZGVjcnlwdGlvbiBrZXlzLiAgVGhleSBhcmUgdXNlZCBpbiB0d29cbiAgIHBsYWNlcywgY3VycmVudGx5OiB0byBlbmNyeXB0IHRoZSBzZWNyZXQgcGFydCBvZiBwcml2YXRlIGtleXMgaW4gdGhlXG4gICBwcml2YXRlIGtleXJpbmcsIGFuZCB0byBjb252ZXJ0IHBhc3NwaHJhc2VzIHRvIGVuY3J5cHRpb24ga2V5cyBmb3JcbiAgIHN5bW1ldHJpY2FsbHkgZW5jcnlwdGVkIG1lc3NhZ2VzLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHMyaygpIHtcbiAgLyoqIEB0eXBlIHtvcGVucGdwLmhhc2h9ICovXG4gIHRoaXMuYWxnb3JpdGhtID0gJ3NoYTI1Nic7XG4gIC8qKiBAdHlwZSB7b3BlbnBncF90eXBlX3Myay50eXBlfSAqL1xuICB0aGlzLnR5cGUgPSAnaXRlcmF0ZWQnO1xuICB0aGlzLmMgPSA5NjtcbiAgLyoqIEB0eXBlIHtvcGVucGdwX2J5dGVhcnJheX0gXG4gICAqIEVpZ2h0IGJ5dGVzIG9mIHNhbHQuICovXG4gIHRoaXMuc2FsdCA9IGNyeXB0by5yYW5kb20uZ2V0UmFuZG9tQnl0ZXMoOCk7XG5cblxuICAvLyBFeHBvbmVuIGJpYXMsIGRlZmluZWQgaW4gUkZDNDg4MFxuICB2YXIgZXhwYmlhcyA9IDY7XG5cbiAgdGhpcy5nZXRfY291bnQgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gKDE2ICsgKHRoaXMuYyAmIDE1KSkgPDwgKCh0aGlzLmMgPj4gNCkgKyBleHBiaWFzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzaW5nIGZ1bmN0aW9uIGZvciBhIHN0cmluZy10by1rZXkgc3BlY2lmaWVyIChSRkMgNDg4MCAzLjcpLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgUGF5bG9hZCBvZiBzdHJpbmctdG8ta2V5IHNwZWNpZmllclxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBBY3R1YWwgbGVuZ3RoIG9mIHRoZSBvYmplY3RcbiAgICovXG4gIHRoaXMucmVhZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgdmFyIGkgPSAwO1xuICAgIHRoaXMudHlwZSA9IGVudW1zLnJlYWQoZW51bXMuczJrLCBieXRlc1tpKytdLmNoYXJDb2RlQXQoKSk7XG4gICAgdGhpcy5hbGdvcml0aG0gPSBlbnVtcy5yZWFkKGVudW1zLmhhc2gsIGJ5dGVzW2krK10uY2hhckNvZGVBdCgpKTtcblxuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICBjYXNlICdzaW1wbGUnOlxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnc2FsdGVkJzpcbiAgICAgICAgdGhpcy5zYWx0ID0gYnl0ZXMuc3Vic3RyKGksIDgpO1xuICAgICAgICBpICs9IDg7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdpdGVyYXRlZCc6XG4gICAgICAgIHRoaXMuc2FsdCA9IGJ5dGVzLnN1YnN0cihpLCA4KTtcbiAgICAgICAgaSArPSA4O1xuXG4gICAgICAgIC8vIE9jdGV0IDEwOiBjb3VudCwgYSBvbmUtb2N0ZXQsIGNvZGVkIHZhbHVlXG4gICAgICAgIHRoaXMuYyA9IGJ5dGVzW2krK10uY2hhckNvZGVBdCgpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnZ251JzpcbiAgICAgICAgaWYgKGJ5dGVzLnN1YnN0cihpLCAzKSA9PSBcIkdOVVwiKSB7XG4gICAgICAgICAgaSArPSAzOyAvLyBHTlVcbiAgICAgICAgICB2YXIgZ251RXh0VHlwZSA9IDEwMDAgKyBieXRlc1tpKytdLmNoYXJDb2RlQXQoKTtcbiAgICAgICAgICBpZiAoZ251RXh0VHlwZSA9PSAxMDAxKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBnbnVFeHRUeXBlO1xuICAgICAgICAgICAgLy8gR251UEcgZXh0ZW5zaW9uIG1vZGUgMTAwMSAtLSBkb24ndCB3cml0ZSBzZWNyZXQga2V5IGF0IGFsbFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIHMyayBnbnUgcHJvdGVjdGlvbiBtb2RlLlwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBzMmsgdHlwZS5cIik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gczJrIHR5cGUuXCIpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICByZXR1cm4gaTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIHdyaXRlcyBhbiBzMmsgaGFzaCBiYXNlZCBvbiB0aGUgaW5wdXRzLlxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFByb2R1Y2VkIGtleSBvZiBoYXNoQWxnb3JpdGhtIGhhc2ggbGVuZ3RoXG4gICAqL1xuICB0aGlzLndyaXRlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJ5dGVzID0gU3RyaW5nLmZyb21DaGFyQ29kZShlbnVtcy53cml0ZShlbnVtcy5zMmssIHRoaXMudHlwZSkpO1xuICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoZW51bXMud3JpdGUoZW51bXMuaGFzaCwgdGhpcy5hbGdvcml0aG0pKTtcblxuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICBjYXNlICdzaW1wbGUnOlxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3NhbHRlZCc6XG4gICAgICAgIGJ5dGVzICs9IHRoaXMuc2FsdDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpdGVyYXRlZCc6XG4gICAgICAgIGJ5dGVzICs9IHRoaXMuc2FsdDtcbiAgICAgICAgYnl0ZXMgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmMpO1xuICAgICAgICBicmVhaztcbiAgICB9O1xuXG4gICAgcmV0dXJuIGJ5dGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2R1Y2VzIGEga2V5IHVzaW5nIHRoZSBzcGVjaWZpZWQgcGFzc3BocmFzZSBhbmQgdGhlIGRlZmluZWQgXG4gICAqIGhhc2hBbGdvcml0aG0gXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzcGhyYXNlIFBhc3NwaHJhc2UgY29udGFpbmluZyB1c2VyIGlucHV0XG4gICAqIEByZXR1cm4ge1N0cmluZ30gUHJvZHVjZWQga2V5IHdpdGggYSBsZW5ndGggY29ycmVzcG9uZGluZyB0byBcbiAgICogaGFzaEFsZ29yaXRobSBoYXNoIGxlbmd0aFxuICAgKi9cbiAgdGhpcy5wcm9kdWNlX2tleSA9IGZ1bmN0aW9uKHBhc3NwaHJhc2UsIG51bUJ5dGVzKSB7XG4gICAgcGFzc3BocmFzZSA9IHV0aWwuZW5jb2RlX3V0ZjgocGFzc3BocmFzZSk7XG5cbiAgICBmdW5jdGlvbiByb3VuZChwcmVmaXgsIHMyaykge1xuICAgICAgdmFyIGFsZ29yaXRobSA9IGVudW1zLndyaXRlKGVudW1zLmhhc2gsIHMyay5hbGdvcml0aG0pO1xuXG4gICAgICBzd2l0Y2ggKHMyay50eXBlKSB7XG4gICAgICAgIGNhc2UgJ3NpbXBsZSc6XG4gICAgICAgICAgcmV0dXJuIGNyeXB0by5oYXNoLmRpZ2VzdChhbGdvcml0aG0sIHByZWZpeCArIHBhc3NwaHJhc2UpO1xuXG4gICAgICAgIGNhc2UgJ3NhbHRlZCc6XG4gICAgICAgICAgcmV0dXJuIGNyeXB0by5oYXNoLmRpZ2VzdChhbGdvcml0aG0sXG4gICAgICAgICAgICBwcmVmaXggKyBzMmsuc2FsdCArIHBhc3NwaHJhc2UpO1xuXG4gICAgICAgIGNhc2UgJ2l0ZXJhdGVkJzpcbiAgICAgICAgICB2YXIgaXNwID0gW10sXG4gICAgICAgICAgICBjb3VudCA9IHMyay5nZXRfY291bnQoKTtcbiAgICAgICAgICBkYXRhID0gczJrLnNhbHQgKyBwYXNzcGhyYXNlO1xuXG4gICAgICAgICAgd2hpbGUgKGlzcC5sZW5ndGggKiBkYXRhLmxlbmd0aCA8IGNvdW50KVxuICAgICAgICAgICAgaXNwLnB1c2goZGF0YSk7XG5cbiAgICAgICAgICBpc3AgPSBpc3Auam9pbignJyk7XG5cbiAgICAgICAgICBpZiAoaXNwLmxlbmd0aCA+IGNvdW50KVxuICAgICAgICAgICAgaXNwID0gaXNwLnN1YnN0cigwLCBjb3VudCk7XG5cbiAgICAgICAgICByZXR1cm4gY3J5cHRvLmhhc2guZGlnZXN0KGFsZ29yaXRobSwgcHJlZml4ICsgaXNwKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHJlc3VsdCA9ICcnLFxuICAgICAgcHJlZml4ID0gJyc7XG5cbiAgICB3aGlsZSAocmVzdWx0Lmxlbmd0aCA8PSBudW1CeXRlcykge1xuICAgICAgcmVzdWx0ICs9IHJvdW5kKHByZWZpeCwgdGhpcyk7XG4gICAgICBwcmVmaXggKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0LnN1YnN0cigwLCBudW1CeXRlcyk7XG4gIH1cbn1cbiIsIi8vIEdQRzRCcm93c2VycyAtIEFuIE9wZW5QR1AgaW1wbGVtZW50YXRpb24gaW4gamF2YXNjcmlwdFxuLy8gQ29weXJpZ2h0IChDKSAyMDExIFJlY3VyaXR5IExhYnMgR21iSFxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yXG4vLyBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljXG4vLyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXJcbi8vIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuLy8gXG4vLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbi8vIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4vLyBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVVxuLy8gTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbi8vIFxuLy8gWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpY1xuLy8gTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZVxuLy8gRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAgMDIxMTAtMTMwMSAgVVNBXG5cbnZhciBVdGlsID0gZnVuY3Rpb24oKSB7XG5cbiAgdGhpcy5yZWFkTnVtYmVyID0gZnVuY3Rpb24oYnl0ZXMpIHtcbiAgICB2YXIgbiA9IDA7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBuIDw8PSA4O1xuICAgICAgbiArPSBieXRlc1tpXS5jaGFyQ29kZUF0KCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG47XG4gIH07XG5cbiAgdGhpcy53cml0ZU51bWJlciA9IGZ1bmN0aW9uKG4sIGJ5dGVzKSB7XG4gICAgdmFyIGIgPSAnJztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzOyBpKyspIHtcbiAgICAgIGIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgobiA+PiAoOCAqIChieXRlcyAtIGkgLSAxKSkpICYgMHhGRik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGI7XG4gIH07XG5cblxuXG4gIHRoaXMucmVhZERhdGUgPSBmdW5jdGlvbihieXRlcykge1xuICAgIHZhciBuID0gdGhpcy5yZWFkTnVtYmVyKGJ5dGVzKTtcbiAgICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gICAgZC5zZXRUaW1lKG4gKiAxMDAwKTtcbiAgICByZXR1cm4gZDtcbiAgfTtcblxuICB0aGlzLndyaXRlRGF0ZSA9IGZ1bmN0aW9uKHRpbWUpIHtcbiAgICB2YXIgbnVtZXJpYyA9IE1hdGgucm91bmQodGltZS5nZXRUaW1lKCkgLyAxMDAwKTtcblxuICAgIHJldHVybiB0aGlzLndyaXRlTnVtYmVyKG51bWVyaWMsIDQpO1xuICB9O1xuXG4gIHRoaXMuZW1haWxSZWdFeCA9XG4gICAgL1thLXowLTkhIyQlJicqKy89P15fYHt8fX4tXSsoPzpcXC5bYS16MC05ISMkJSYnKisvPT9eX2B7fH1+LV0rKSpAKD86W2EtejAtOV0oPzpbYS16MC05LV0qW2EtejAtOV0pP1xcLikrW2EtejAtOV0oPzpbYS16MC05LV0qW2EtejAtOV0pPy87XG5cbiAgdGhpcy5kZWJ1ZyA9IGZhbHNlO1xuXG4gIHRoaXMuaGV4ZHVtcCA9IGZ1bmN0aW9uKHN0cikge1xuICAgIHZhciByID0gW107XG4gICAgdmFyIGUgPSBzdHIubGVuZ3RoO1xuICAgIHZhciBjID0gMDtcbiAgICB2YXIgaDtcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKGMgPCBlKSB7XG4gICAgICBoID0gc3RyLmNoYXJDb2RlQXQoYysrKS50b1N0cmluZygxNik7XG4gICAgICB3aGlsZSAoaC5sZW5ndGggPCAyKSBoID0gXCIwXCIgKyBoO1xuICAgICAgci5wdXNoKFwiIFwiICsgaCk7XG4gICAgICBpKys7XG4gICAgICBpZiAoaSAlIDMyID09IDApXG4gICAgICAgIHIucHVzaChcIlxcbiAgICAgICAgICAgXCIpO1xuICAgIH1cbiAgICByZXR1cm4gci5qb2luKCcnKTtcbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGhleHN0cmluZyBmcm9tIGEgYmluYXJ5XG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7U3RyaW5nfSBTdHJpbmcgY29udGFpbmluZyB0aGUgaGV4YWRlY2ltYWwgdmFsdWVzXG4gICAqL1xuICB0aGlzLmhleHN0cmR1bXAgPSBmdW5jdGlvbihzdHIpIHtcbiAgICBpZiAoc3RyID09IG51bGwpXG4gICAgICByZXR1cm4gXCJcIjtcbiAgICB2YXIgciA9IFtdO1xuICAgIHZhciBlID0gc3RyLmxlbmd0aDtcbiAgICB2YXIgYyA9IDA7XG4gICAgdmFyIGg7XG4gICAgd2hpbGUgKGMgPCBlKSB7XG4gICAgICBoID0gc3RyW2MrK10uY2hhckNvZGVBdCgpLnRvU3RyaW5nKDE2KTtcbiAgICAgIHdoaWxlIChoLmxlbmd0aCA8IDIpIGggPSBcIjBcIiArIGg7XG4gICAgICByLnB1c2goXCJcIiArIGgpO1xuICAgIH1cbiAgICByZXR1cm4gci5qb2luKCcnKTtcbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGJpbmFyeSBzdHJpbmcgZnJvbSBhIGhleCBlbmNvZGVkIHN0cmluZ1xuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIEhleCBzdHJpbmcgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyBjb250YWluaW5nIHRoZSBiaW5hcnkgdmFsdWVzXG4gICAqL1xuICB0aGlzLmhleDJiaW4gPSBmdW5jdGlvbihoZXgpIHtcbiAgICB2YXIgc3RyID0gJyc7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZXgubGVuZ3RoOyBpICs9IDIpXG4gICAgICBzdHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChoZXguc3Vic3RyKGksIDIpLCAxNikpO1xuICAgIHJldHVybiBzdHI7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0aW5nIGEgaGV4IHN0cmluZyBmcm9tIGFuIGJpbmFyeSBhcnJheSBvZiBpbnRlZ2VycyAoMC4uMjU1KVxuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIEFycmF5IG9mIGJ5dGVzIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7U3RyaW5nfSBIZXhhZGVjaW1hbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgYXJyYXlcbiAgICovXG4gIHRoaXMuaGV4aWR1bXAgPSBmdW5jdGlvbihzdHIpIHtcbiAgICB2YXIgciA9IFtdO1xuICAgIHZhciBlID0gc3RyLmxlbmd0aDtcbiAgICB2YXIgYyA9IDA7XG4gICAgdmFyIGg7XG4gICAgd2hpbGUgKGMgPCBlKSB7XG4gICAgICBoID0gc3RyW2MrK10udG9TdHJpbmcoMTYpO1xuICAgICAgd2hpbGUgKGgubGVuZ3RoIDwgMikgaCA9IFwiMFwiICsgaDtcbiAgICAgIHIucHVzaChcIlwiICsgaCk7XG4gICAgfVxuICAgIHJldHVybiByLmpvaW4oJycpO1xuICB9O1xuXG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmcgdG8gYSBzdHJpbmcgb2YgdXRmOCBieXRlc1xuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFRoZSBzdHJpbmcgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEEgdmFsaWQgc3F1ZW5jZSBvZiB1dGY4IGJ5dGVzXG4gICAqL1xuICB0aGlzLmVuY29kZV91dGY4ID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgcmV0dXJuIHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChzdHIpKTtcbiAgfTtcblxuICAvKipcbiAgICogQ29udmVydCBhIHN0cmluZyBvZiB1dGY4IGJ5dGVzIHRvIGEgbmF0aXZlIGphdmFzY3JpcHQgc3RyaW5nXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB1dGY4IEEgdmFsaWQgc3F1ZW5jZSBvZiB1dGY4IGJ5dGVzXG4gICAqIEByZXR1cm4ge1N0cmluZ30gQSBuYXRpdmUgamF2YXNjcmlwdCBzdHJpbmdcbiAgICovXG4gIHRoaXMuZGVjb2RlX3V0ZjggPSBmdW5jdGlvbih1dGY4KSB7XG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUodXRmOCkpO1xuICB9O1xuXG4gIHZhciBzdHIyYmluID0gZnVuY3Rpb24oc3RyLCByZXN1bHQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgcmVzdWx0W2ldID0gc3RyLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICB2YXIgYmluMnN0ciA9IGZ1bmN0aW9uKGJpbikge1xuICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmluLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHQucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJpbltpXSkpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQuam9pbignJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYSBzdHJpbmcgdG8gYW4gYXJyYXkgb2YgaW50ZWdlcnMoMC4yNTUpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7SW50ZWdlcltdfSBBbiBhcnJheSBvZiAoYmluYXJ5KSBpbnRlZ2Vyc1xuICAgKi9cbiAgdGhpcy5zdHIyYmluID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgcmV0dXJuIHN0cjJiaW4oc3RyLCBuZXcgQXJyYXkoc3RyLmxlbmd0aCkpO1xuICB9O1xuXG5cbiAgLyoqXG4gICAqIENvbnZlcnQgYW4gYXJyYXkgb2YgaW50ZWdlcnMoMC4yNTUpIHRvIGEgc3RyaW5nIFxuICAgKiBAcGFyYW0ge0ludGVnZXJbXX0gYmluIEFuIGFycmF5IG9mIChiaW5hcnkpIGludGVnZXJzIHRvIGNvbnZlcnRcbiAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBhcnJheVxuICAgKi9cbiAgdGhpcy5iaW4yc3RyID0gYmluMnN0cjtcblxuICAvKipcbiAgICogQ29udmVydCBhIHN0cmluZyB0byBhIFVpbnQ4QXJyYXlcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBTdHJpbmcgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtVaW50OEFycmF5fSBUaGUgYXJyYXkgb2YgKGJpbmFyeSkgaW50ZWdlcnNcbiAgICovXG4gIHRoaXMuc3RyMlVpbnQ4QXJyYXkgPSBmdW5jdGlvbihzdHIpIHtcbiAgICByZXR1cm4gc3RyMmJpbihzdHIsIG5ldyBVaW50OEFycmF5KG5ldyBBcnJheUJ1ZmZlcihzdHIubGVuZ3RoKSkpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgVWludDhBcnJheSB0byBhIHN0cmluZy4gVGhpcyBjdXJyZW50bHkgZnVuY3Rpb25zIFxuICAgKiB0aGUgc2FtZSBhcyBiaW4yc3RyLiBcbiAgICogQHBhcmFtIHtVaW50OEFycmF5fSBiaW4gQW4gYXJyYXkgb2YgKGJpbmFyeSkgaW50ZWdlcnMgdG8gY29udmVydFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgYXJyYXlcbiAgICovXG4gIHRoaXMuVWludDhBcnJheTJzdHIgPSBiaW4yc3RyO1xuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIGEgMTZiaXQgc3VtIG9mIGEgc3RyaW5nIGJ5IGFkZGluZyBlYWNoIGNoYXJhY3RlciBcbiAgICogY29kZXMgbW9kdWx1cyA2NTUzNVxuICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dCBTdHJpbmcgdG8gY3JlYXRlIGEgc3VtIG9mXG4gICAqIEByZXR1cm4ge0ludGVnZXJ9IEFuIGludGVnZXIgY29udGFpbmluZyB0aGUgc3VtIG9mIGFsbCBjaGFyYWN0ZXIgXG4gICAqIGNvZGVzICUgNjU1MzVcbiAgICovXG4gIHRoaXMuY2FsY19jaGVja3N1bSA9IGZ1bmN0aW9uKHRleHQpIHtcbiAgICB2YXIgY2hlY2tzdW0gPSB7XG4gICAgICBzOiAwLFxuICAgICAgYWRkOiBmdW5jdGlvbihzYWRkKSB7XG4gICAgICAgIHRoaXMucyA9ICh0aGlzLnMgKyBzYWRkKSAlIDY1NTM2O1xuICAgICAgfVxuICAgIH07XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjaGVja3N1bS5hZGQodGV4dC5jaGFyQ29kZUF0KGkpKTtcbiAgICB9XG4gICAgcmV0dXJuIGNoZWNrc3VtLnM7XG4gIH07XG5cbiAgLyoqXG4gICAqIEhlbHBlciBmdW5jdGlvbiB0byBwcmludCBhIGRlYnVnIG1lc3NhZ2UuIERlYnVnIFxuICAgKiBtZXNzYWdlcyBhcmUgb25seSBwcmludGVkIGlmXG4gICAqIG9wZW5wZ3AuY29uZmlnLmRlYnVnIGlzIHNldCB0byB0cnVlLiBUaGUgY2FsbGluZ1xuICAgKiBKYXZhc2NyaXB0IGNvbnRleHQgTVVTVCBkZWZpbmVcbiAgICogYSBcInNob3dNZXNzYWdlcyh0ZXh0KVwiIGZ1bmN0aW9uLiBMaW5lIGZlZWRzICgnXFxuJylcbiAgICogYXJlIGF1dG9tYXRpY2FsbHkgY29udmVydGVkIHRvIEhUTUwgbGluZSBmZWVkcyAnPGJyLz4nXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBkZWJ1ZyBtZXNzYWdlXG4gICAqIEByZXR1cm4ge1N0cmluZ30gQW4gSFRNTCB0dCBlbnRpdHkgY29udGFpbmluZyBhIHBhcmFncmFwaCB3aXRoIGEgXG4gICAqIHN0eWxlIGF0dHJpYnV0ZSB3aGVyZSB0aGUgZGVidWcgbWVzc2FnZSBpcyBIVE1MZW5jb2RlZCBpbi4gXG4gICAqL1xuICB0aGlzLnByaW50X2RlYnVnID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgaWYgKHRoaXMuZGVidWcpIHtcbiAgICAgIGNvbnNvbGUubG9nKHN0cik7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gcHJpbnQgYSBkZWJ1ZyBtZXNzYWdlLiBEZWJ1ZyBcbiAgICogbWVzc2FnZXMgYXJlIG9ubHkgcHJpbnRlZCBpZlxuICAgKiBvcGVucGdwLmNvbmZpZy5kZWJ1ZyBpcyBzZXQgdG8gdHJ1ZS4gVGhlIGNhbGxpbmdcbiAgICogSmF2YXNjcmlwdCBjb250ZXh0IE1VU1QgZGVmaW5lXG4gICAqIGEgXCJzaG93TWVzc2FnZXModGV4dClcIiBmdW5jdGlvbi4gTGluZSBmZWVkcyAoJ1xcbicpXG4gICAqIGFyZSBhdXRvbWF0aWNhbGx5IGNvbnZlcnRlZCB0byBIVE1MIGxpbmUgZmVlZHMgJzxici8+J1xuICAgKiBEaWZmZXJlbnQgdGhhbiBwcmludF9kZWJ1ZyBiZWNhdXNlIHdpbGwgY2FsbCBoZXhzdHJkdW1wIGlmZiBuZWNlc3NhcnkuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBkZWJ1ZyBtZXNzYWdlXG4gICAqIEByZXR1cm4ge1N0cmluZ30gQW4gSFRNTCB0dCBlbnRpdHkgY29udGFpbmluZyBhIHBhcmFncmFwaCB3aXRoIGEgXG4gICAqIHN0eWxlIGF0dHJpYnV0ZSB3aGVyZSB0aGUgZGVidWcgbWVzc2FnZSBpcyBIVE1MZW5jb2RlZCBpbi4gXG4gICAqL1xuICB0aGlzLnByaW50X2RlYnVnX2hleHN0cl9kdW1wID0gZnVuY3Rpb24oc3RyLCBzdHJUb0hleCkge1xuICAgIGlmICh0aGlzLmRlYnVnKSB7XG4gICAgICBzdHIgPSBzdHIgKyB0aGlzLmhleHN0cmR1bXAoc3RyVG9IZXgpO1xuICAgICAgY29uc29sZS5sb2coc3RyKTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEhlbHBlciBmdW5jdGlvbiB0byBwcmludCBhbiBlcnJvciBtZXNzYWdlLiBcbiAgICogVGhlIGNhbGxpbmcgSmF2YXNjcmlwdCBjb250ZXh0IE1VU1QgZGVmaW5lXG4gICAqIGEgXCJzaG93TWVzc2FnZXModGV4dClcIiBmdW5jdGlvbi4gTGluZSBmZWVkcyAoJ1xcbicpXG4gICAqIGFyZSBhdXRvbWF0aWNhbGx5IGNvbnZlcnRlZCB0byBIVE1MIGxpbmUgZmVlZHMgJzxici8+J1xuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyBvZiB0aGUgZXJyb3IgbWVzc2FnZVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IEEgSFRNTCBwYXJhZ3JhcGggZW50aXR5IHdpdGggYSBzdHlsZSBhdHRyaWJ1dGUgXG4gICAqIGNvbnRhaW5pbmcgdGhlIEhUTUwgZW5jb2RlZCBlcnJvciBtZXNzYWdlXG4gICAqL1xuICB0aGlzLnByaW50X2Vycm9yID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgaWYgKHRoaXMuZGVidWcpXG4gICAgICB0aHJvdyBzdHI7XG4gICAgY29uc29sZS5sb2coc3RyKTtcbiAgfTtcblxuICAvKipcbiAgICogSGVscGVyIGZ1bmN0aW9uIHRvIHByaW50IGFuIGluZm8gbWVzc2FnZS4gXG4gICAqIFRoZSBjYWxsaW5nIEphdmFzY3JpcHQgY29udGV4dCBNVVNUIGRlZmluZVxuICAgKiBhIFwic2hvd01lc3NhZ2VzKHRleHQpXCIgZnVuY3Rpb24uIExpbmUgZmVlZHMgKCdcXG4nKVxuICAgKiBhcmUgYXV0b21hdGljYWxseSBjb252ZXJ0ZWQgdG8gSFRNTCBsaW5lIGZlZWRzICc8YnIvPicuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIG9mIHRoZSBpbmZvIG1lc3NhZ2VcbiAgICogQHJldHVybiB7U3RyaW5nfSBBIEhUTUwgcGFyYWdyYXBoIGVudGl0eSB3aXRoIGEgc3R5bGUgYXR0cmlidXRlIFxuICAgKiBjb250YWluaW5nIHRoZSBIVE1MIGVuY29kZWQgaW5mbyBtZXNzYWdlXG4gICAqL1xuICB0aGlzLnByaW50X2luZm8gPSBmdW5jdGlvbihzdHIpIHtcbiAgICBpZiAodGhpcy5kZWJ1ZylcbiAgICAgIGNvbnNvbGUubG9nKHN0cik7XG4gIH07XG5cbiAgdGhpcy5wcmludF93YXJuaW5nID0gZnVuY3Rpb24oc3RyKSB7XG4gICAgY29uc29sZS5sb2coc3RyKTtcbiAgfTtcblxuICB0aGlzLmdldExlZnROQml0cyA9IGZ1bmN0aW9uKHN0cmluZywgYml0Y291bnQpIHtcbiAgICB2YXIgcmVzdCA9IGJpdGNvdW50ICUgODtcbiAgICBpZiAocmVzdCA9PSAwKVxuICAgICAgcmV0dXJuIHN0cmluZy5zdWJzdHJpbmcoMCwgYml0Y291bnQgLyA4KTtcbiAgICB2YXIgYnl0ZXMgPSAoYml0Y291bnQgLSByZXN0KSAvIDggKyAxO1xuICAgIHZhciByZXN1bHQgPSBzdHJpbmcuc3Vic3RyaW5nKDAsIGJ5dGVzKTtcbiAgICByZXR1cm4gdGhpcy5zaGlmdFJpZ2h0KHJlc3VsdCwgOCAtIHJlc3QpOyAvLyArU3RyaW5nLmZyb21DaGFyQ29kZShzdHJpbmcuY2hhckNvZGVBdChieXRlcyAtMSkgPDwgKDgtcmVzdCkgJiAweEZGKTtcbiAgfTtcblxuICAvKipcbiAgICogU2hpZnRpbmcgYSBzdHJpbmcgdG8gbiBiaXRzIHJpZ2h0XG4gICAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZSBUaGUgc3RyaW5nIHRvIHNoaWZ0XG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gYml0Y291bnQgQW1vdW50IG9mIGJpdHMgdG8gc2hpZnQgKE1VU1QgYmUgc21hbGxlciBcbiAgICogdGhhbiA5KVxuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFJlc3VsdGluZyBzdHJpbmcuIFxuICAgKi9cbiAgdGhpcy5zaGlmdFJpZ2h0ID0gZnVuY3Rpb24odmFsdWUsIGJpdGNvdW50KSB7XG4gICAgdmFyIHRlbXAgPSB1dGlsLnN0cjJiaW4odmFsdWUpO1xuICAgIGlmIChiaXRjb3VudCAlIDggIT0gMCkge1xuICAgICAgZm9yICh2YXIgaSA9IHRlbXAubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgdGVtcFtpXSA+Pj0gYml0Y291bnQgJSA4O1xuICAgICAgICBpZiAoaSA+IDApXG4gICAgICAgICAgdGVtcFtpXSB8PSAodGVtcFtpIC0gMV0gPDwgKDggLSAoYml0Y291bnQgJSA4KSkpICYgMHhGRjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gdXRpbC5iaW4yc3RyKHRlbXApO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGFsZ29yaXRobSB0eXBlIGFzIHN0cmluZ1xuICAgKiBAcmV0dXJuIHtTdHJpbmd9IFN0cmluZyByZXByZXNlbnRpbmcgdGhlIG1lc3NhZ2UgdHlwZVxuICAgKi9cbiAgdGhpcy5nZXRfaGFzaEFsZ29yaXRobVN0cmluZyA9IGZ1bmN0aW9uKGFsZ28pIHtcbiAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIFwiTUQ1XCI7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiBcIlNIQTFcIjtcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmV0dXJuIFwiUklQRU1EMTYwXCI7XG4gICAgICBjYXNlIDg6XG4gICAgICAgIHJldHVybiBcIlNIQTI1NlwiO1xuICAgICAgY2FzZSA5OlxuICAgICAgICByZXR1cm4gXCJTSEEzODRcIjtcbiAgICAgIGNhc2UgMTA6XG4gICAgICAgIHJldHVybiBcIlNIQTUxMlwiO1xuICAgICAgY2FzZSAxMTpcbiAgICAgICAgcmV0dXJuIFwiU0hBMjI0XCI7XG4gICAgfVxuICAgIHJldHVybiBcInVua25vd25cIjtcbiAgfTtcblxufTtcblxuLyoqXG4gKiBhbiBpbnN0YW5jZSB0aGF0IHNob3VsZCBiZSB1c2VkLiBcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBuZXcgVXRpbCgpO1xuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi8uLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJBRVMgUmlqbmRhZWwgY2lwaGVyIHRlc3Qgd2l0aCB0ZXN0IHZlY3RvcnMgZnJvbSBlY2JfdGJsLnR4dFwiLCBmdW5jdGlvbigpIHtcbiAgdmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8uLi8nKTtcbiAgdmFyIHV0aWwgPSBvcGVucGdwLnV0aWw7XG5cbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheSgpO1xuXG4gIGZ1bmN0aW9uIHRlc3RfYWVzKGlucHV0LCBrZXksIG91dHB1dCkge1xuICAgIHZhciBhZXMgPSBuZXcgb3BlbnBncC5jaXBoZXIuYWVzMTI4KHV0aWwuYmluMnN0cihrZXkpKTtcblxuICAgIHZhciByZXN1bHQgPSB1dGlsLmJpbjJzdHIoYWVzLmVuY3J5cHQoaW5wdXQpKTtcblxuICAgIHJldHVybiB1dGlsLmhleHN0cmR1bXAocmVzdWx0KSA9PSB1dGlsLmhleHN0cmR1bXAodXRpbC5iaW4yc3RyKG91dHB1dCkpO1xuICB9O1xuXG4gIHZhciB0ZXN0dmVjdG9yczEyOCA9IFtbWzB4MDAsMHgwMSwweDAyLDB4MDMsMHgwNSwweDA2LDB4MDcsMHgwOCwweDBBLDB4MEIsMHgwQywweDBELDB4MEYsMHgxMCwweDExLDB4MTJdLFsweDUwLDB4NjgsMHgxMiwweEE0LDB4NUYsMHgwOCwweEM4LDB4ODksMHhCOSwweDdGLDB4NTksMHg4MCwweDAzLDB4OEIsMHg4MywweDU5XSxbMHhEOCwweEY1LDB4MzIsMHg1MywweDgyLDB4ODksMHhFRiwweDdELDB4MDYsMHhCNSwweDA2LDB4QTQsMHhGRCwweDVCLDB4RTksMHhDOV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDE0LDB4MTUsMHgxNiwweDE3LDB4MTksMHgxQSwweDFCLDB4MUMsMHgxRSwweDFGLDB4MjAsMHgyMSwweDIzLDB4MjQsMHgyNSwweDI2XSxbMHg1QywweDZELDB4NzEsMHhDQSwweDMwLDB4REUsMHg4QiwweDhCLDB4MDAsMHg1NCwweDk5LDB4ODQsMHhEMiwweEVDLDB4N0QsMHg0Ql0sWzB4NTksMHhBQiwweDMwLDB4RjQsMHhENCwweEVFLDB4NkUsMHg0RiwweEY5LDB4OTAsMHg3RSwweEY2LDB4NUIsMHgxRiwweEI2LDB4OENdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHgyOCwweDI5LDB4MkEsMHgyQiwweDJELDB4MkUsMHgyRiwweDMwLDB4MzIsMHgzMywweDM0LDB4MzUsMHgzNywweDM4LDB4MzksMHgzQV0sWzB4NTMsMHhGMywweEY0LDB4QzYsMHg0RiwweDg2LDB4MTYsMHhFNCwweEU3LDB4QzUsMHg2MSwweDk5LDB4RjQsMHg4RiwweDIxLDB4RjZdLFsweEJGLDB4MUUsMHhEMiwweEZDLDB4QjIsMHhBRiwweDNGLDB4RDQsMHgxNCwweDQzLDB4QjUsMHg2RCwweDg1LDB4MDIsMHg1QywweEIxXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4M0MsMHgzRCwweDNFLDB4M0YsMHg0MSwweDQyLDB4NDMsMHg0NCwweDQ2LDB4NDcsMHg0OCwweDQ5LDB4NEIsMHg0QywweDRELDB4NEVdLFsweEExLDB4RUIsMHg2NSwweEEzLDB4NDgsMHg3MSwweDY1LDB4RkIsMHgwRiwweDFDLDB4MjcsMHhGRiwweDk5LDB4NTksMHhGNywweDAzXSxbMHg3MywweDE2LDB4NjMsMHgyRCwweDVDLDB4MzIsMHgyMywweDNFLDB4REMsMHhCMCwweDc4LDB4MDUsMHg2MCwweEVBLDB4RTgsMHhCMl1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDUwLDB4NTEsMHg1MiwweDUzLDB4NTUsMHg1NiwweDU3LDB4NTgsMHg1QSwweDVCLDB4NUMsMHg1RCwweDVGLDB4NjAsMHg2MSwweDYyXSxbMHgzNSwweDUzLDB4RUMsMHhGMCwweEIxLDB4NzMsMHg5NSwweDU4LDB4QjAsMHg4RSwweDM1LDB4MEEsMHg5OCwweEEzLDB4OUIsMHhGQV0sWzB4NDAsMHg4QywweDA3LDB4M0UsMHgzRSwweDI1LDB4MzgsMHgwNywweDJCLDB4NzIsMHg2MiwweDVFLDB4NjgsMHhCOCwweDM2LDB4NEJdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHg2NCwweDY1LDB4NjYsMHg2NywweDY5LDB4NkEsMHg2QiwweDZDLDB4NkUsMHg2RiwweDcwLDB4NzEsMHg3MywweDc0LDB4NzUsMHg3Nl0sWzB4NjcsMHg0MiwweDk5LDB4NjksMHg0OSwweDBCLDB4OTcsMHgxMSwweEFFLDB4MkIsMHgwMSwweERDLDB4NDksMHg3QSwweEZELDB4RThdLFsweEUxLDB4RjksMHg0RCwweEZBLDB4NzcsMHg2NSwweDk3LDB4QkUsMHhBQywweEEyLDB4NjIsMHhGMiwweEY2LDB4MzYsMHg2RiwweEVBXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4NzgsMHg3OSwweDdBLDB4N0IsMHg3RCwweDdFLDB4N0YsMHg4MCwweDgyLDB4ODMsMHg4NCwweDg1LDB4ODcsMHg4OCwweDg5LDB4OEFdLFsweDkzLDB4MzgsMHg1QywweDFGLDB4MkEsMHhFQywweDhCLDB4RUQsMHgxOSwweDJGLDB4NUEsMHg4RSwweDE2LDB4MUQsMHhENSwweDA4XSxbMHhGMiwweDlFLDB4OTgsMHg2QywweDZBLDB4MUMsMHgyNywweEQ3LDB4QjIsMHg5RiwweEZELDB4N0UsMHhFOSwweDJCLDB4NzUsMHhGMV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDhDLDB4OEQsMHg4RSwweDhGLDB4OTEsMHg5MiwweDkzLDB4OTQsMHg5NiwweDk3LDB4OTgsMHg5OSwweDlCLDB4OUMsMHg5RCwweDlFXSxbMHhCNSwweEJGLDB4OTQsMHg2QiwweEUxLDB4OUIsMHhFQiwweDhELDB4QjMsMHg5OCwweDNCLDB4NUYsMHg0QywweDZFLDB4OEQsMHhEQl0sWzB4MTMsMHgxQywweDg4LDB4NkEsMHg1NywweEY4LDB4QzIsMHhFNywweDEzLDB4QUIsMHhBNiwweDk1LDB4NUUsMHgyQiwweDU1LDB4QjVdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHhBMCwweEExLDB4QTIsMHhBMywweEE1LDB4QTYsMHhBNywweEE4LDB4QUEsMHhBQiwweEFDLDB4QUQsMHhBRiwweEIwLDB4QjEsMHhCMl0sWzB4NDEsMHgzMiwweDFFLDB4RTEsMHgwRSwweDIxLDB4QkQsMHg5MCwweDcyLDB4MjcsMHhDNCwweDQ1LDB4MEYsMHhGNCwweDIzLDB4MjRdLFsweEQyLDB4QUIsMHg3NiwweDYyLDB4REYsMHg5QiwweDhDLDB4NzQsMHgwMiwweDEwLDB4RTUsMHhFRSwweEI2LDB4MUMsMHgxOSwweDlEXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4QjQsMHhCNSwweEI2LDB4QjcsMHhCOSwweEJBLDB4QkIsMHhCQywweEJFLDB4QkYsMHhDMCwweEMxLDB4QzMsMHhDNCwweEM1LDB4QzZdLFsweDAwLDB4QTgsMHgyRiwweDU5LDB4QzksMHgxQywweDg0LDB4ODYsMHhEMSwweDJDLDB4MEEsMHg4MCwweDEyLDB4NEYsMHg2MCwweDg5XSxbMHgxNCwweEMxLDB4MDUsMHg1NCwweEIyLDB4ODUsMHg5QywweDQ4LDB4NEMsMHhBQiwweDU4LDB4NjksMHhCQiwweEU3LDB4QzQsMHg3MF1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweEM4LDB4QzksMHhDQSwweENCLDB4Q0QsMHhDRSwweENGLDB4RDAsMHhEMiwweEQzLDB4RDQsMHhENSwweEQ3LDB4RDgsMHhEOSwweERBXSxbMHg3QywweEUwLDB4RkQsMHgwNywweDY3LDB4NTQsMHg2OSwweDFCLDB4NEIsMHhCRCwweDlGLDB4QUYsMHg4QSwweDEzLDB4NzIsMHhGRV0sWzB4REIsMHg0RCwweDQ5LDB4OEYsMHgwQSwweDQ5LDB4Q0YsMHg1NSwweDQ0LDB4NUQsMHg1MCwweDJDLDB4MUYsMHg5QSwweEIzLDB4QjVdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHhEQywweERELDB4REUsMHhERiwweEUxLDB4RTIsMHhFMywweEU0LDB4RTYsMHhFNywweEU4LDB4RTksMHhFQiwweEVDLDB4RUQsMHhFRV0sWzB4MjMsMHg2MCwweDVBLDB4ODIsMHg0MywweEQwLDB4NzcsMHg2NCwweDU0LDB4MUIsMHhDNSwweEFELDB4MzUsMHg1QiwweDMxLDB4MjldLFsweDZELDB4OTYsMHhGRSwweEY3LDB4RDYsMHg2NSwweDkwLDB4QTcsMHg3QSwweDc3LDB4QkIsMHgyMCwweDU2LDB4NjYsMHg3RiwweDdGXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4RjAsMHhGMSwweEYyLDB4RjMsMHhGNSwweEY2LDB4RjcsMHhGOCwweEZBLDB4RkIsMHhGQywweEZELDB4RkUsMHgwMSwweDAwLDB4MDJdLFsweDEyLDB4QTgsMHhDRiwweEEyLDB4M0UsMHhBNywweDY0LDB4RkQsMHg4NywweDYyLDB4MzIsMHhCNCwweEU4LDB4NDIsMHhCQywweDQ0XSxbMHgzMSwweDZGLDB4QjYsMHg4RSwweERCLDB4QTcsMHgzNiwweEM1LDB4M0UsMHg3OCwweDQ3LDB4N0IsMHhGOSwweDEzLDB4NzIsMHg1Q11dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDA0LDB4MDUsMHgwNiwweDA3LDB4MDksMHgwQSwweDBCLDB4MEMsMHgwRSwweDBGLDB4MTAsMHgxMSwweDEzLDB4MTQsMHgxNSwweDE2XSxbMHhCQywweEFGLDB4MzIsMHg0MSwweDVFLDB4ODMsMHgwOCwweEIzLDB4NzIsMHgzRSwweDVGLDB4REQsMHg4NSwweDNDLDB4Q0MsMHg4MF0sWzB4NjksMHgzNiwweEYyLDB4QjksMHgzQSwweEY4LDB4MzksMHg3RiwweEQzLDB4QTcsMHg3MSwweEZDLDB4MDEsMHgxQywweDhDLDB4MzddXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHgyQywweDJELDB4MkUsMHgyRiwweDMxLDB4MzIsMHgzMywweDM0LDB4MzYsMHgzNywweDM4LDB4MzksMHgzQiwweDNDLDB4M0QsMHgzRV0sWzB4ODksMHhBRiwweEFFLDB4NjgsMHg1RCwweDgwLDB4MUEsMHhENywweDQ3LDB4QUMsMHhFOSwweDFGLDB4QzQsMHg5QSwweERELDB4RTBdLFsweEYzLDB4RjksMHgyRiwweDdBLDB4OUMsMHg1OSwweDE3LDB4OUMsMHgxRiwweENDLDB4MkMsMHgyQiwweEEwLDB4QjAsMHg4MiwweENEXV1dO1xuICBcbiAgdmFyIHRlc3R2ZWN0b3JzMTkyID0gW1tbMHgwMCwweDAxLDB4MDIsMHgwMywweDA1LDB4MDYsMHgwNywweDA4LDB4MEEsMHgwQiwweDBDLDB4MEQsMHgwRiwweDEwLDB4MTEsMHgxMiwweDE0LDB4MTUsMHgxNiwweDE3LDB4MTksMHgxQSwweDFCLDB4MUNdLFsweDJELDB4MzMsMHhFRSwweEYyLDB4QzAsMHg0MywweDBBLDB4OEEsMHg5RSwweEJGLDB4NDUsMHhFOCwweDA5LDB4QzQsMHgwQiwweEI2XSxbMHhERiwweEY0LDB4OTQsMHg1RSwweDAzLDB4MzYsMHhERiwweDRDLDB4MUMsMHg1NiwweEJDLDB4NzAsMHgwRSwweEZGLDB4ODMsMHg3Rl1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDFFLDB4MUYsMHgyMCwweDIxLDB4MjMsMHgyNCwweDI1LDB4MjYsMHgyOCwweDI5LDB4MkEsMHgyQiwweDJELDB4MkUsMHgyRiwweDMwLDB4MzIsMHgzMywweDM0LDB4MzUsMHgzNywweDM4LDB4MzksMHgzQV0sWzB4NkEsMHhBMywweDc1LDB4RDEsMHhGQSwweDE1LDB4NUEsMHg2MSwweEZCLDB4NzIsMHgzNSwweDNFLDB4MEEsMHg1QSwweDg3LDB4NTZdLFsweEI2LDB4RkQsMHhERSwweEY0LDB4NzUsMHgyNywweDY1LDB4RTMsMHg0NywweEQ1LDB4RDIsMHhEQywweDE5LDB4NkQsMHgxMiwweDUyXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4M0MsMHgzRCwweDNFLDB4M0YsMHg0MSwweDQyLDB4NDMsMHg0NCwweDQ2LDB4NDcsMHg0OCwweDQ5LDB4NEIsMHg0QywweDRELDB4NEUsMHg1MCwweDUxLDB4NTIsMHg1MywweDU1LDB4NTYsMHg1NywweDU4XSxbMHhCQywweDM3LDB4MzYsMHg1MSwweDhCLDB4OTQsMHg5MCwweERDLDB4QjgsMHhFRCwweDYwLDB4RUIsMHgyNiwweDc1LDB4OEUsMHhENF0sWzB4RDIsMHgzNiwweDg0LDB4RTMsMHhEOSwweDYzLDB4QjMsMHhBRiwweENGLDB4MUEsMHgxMSwweDRBLDB4Q0EsMHg5MCwweENCLDB4RDZdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHg1QSwweDVCLDB4NUMsMHg1RCwweDVGLDB4NjAsMHg2MSwweDYyLDB4NjQsMHg2NSwweDY2LDB4NjcsMHg2OSwweDZBLDB4NkIsMHg2QywweDZFLDB4NkYsMHg3MCwweDcxLDB4NzMsMHg3NCwweDc1LDB4NzZdLFsweEFBLDB4MjEsMHg0NCwweDAyLDB4QjQsMHg2QywweEZGLDB4QjksMHhGNywweDYxLDB4RUMsMHgxMSwweDI2LDB4M0EsMHgzMSwweDFFXSxbMHgzQSwweDdBLDB4QzAsMHgyNywweDc1LDB4M0UsMHgyQSwweDE4LDB4QzIsMHhDRSwweEFCLDB4OUUsMHgxNywweEMxLDB4MUYsMHhEMF1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDc4LDB4NzksMHg3QSwweDdCLDB4N0QsMHg3RSwweDdGLDB4ODAsMHg4MiwweDgzLDB4ODQsMHg4NSwweDg3LDB4ODgsMHg4OSwweDhBLDB4OEMsMHg4RCwweDhFLDB4OEYsMHg5MSwweDkyLDB4OTMsMHg5NF0sWzB4MDIsMHhBRSwweEE4LDB4NkUsMHg1NywweDJFLDB4RUEsMHhCNiwweDZCLDB4MkMsMHgzQSwweEY1LDB4RTksMHhBNCwweDZGLDB4RDZdLFsweDhGLDB4NjcsMHg4NiwweEJELDB4MDAsMHg3NSwweDI4LDB4QkEsMHgyNiwweDYwLDB4M0MsMHgxNiwweDAxLDB4Q0QsMHhEMCwweEQ4XV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4OTYsMHg5NywweDk4LDB4OTksMHg5QiwweDlDLDB4OUQsMHg5RSwweEEwLDB4QTEsMHhBMiwweEEzLDB4QTUsMHhBNiwweEE3LDB4QTgsMHhBQSwweEFCLDB4QUMsMHhBRCwweEFGLDB4QjAsMHhCMSwweEIyXSxbMHhFMiwweEFFLDB4RjYsMHhBQywweEMzLDB4M0IsMHg5NiwweDVDLDB4NEYsMHhBMSwweEY5LDB4MUMsMHg3NSwweEZGLDB4NkYsMHgzNl0sWzB4RDEsMHg3RCwweDA3LDB4M0IsMHgwMSwweEU3LDB4MTUsMHgwMiwweEUyLDB4OEIsMHg0NywweEFCLDB4NTUsMHgxMSwweDY4LDB4QjNdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHhCNCwweEI1LDB4QjYsMHhCNywweEI5LDB4QkEsMHhCQiwweEJDLDB4QkUsMHhCRiwweEMwLDB4QzEsMHhDMywweEM0LDB4QzUsMHhDNiwweEM4LDB4QzksMHhDQSwweENCLDB4Q0QsMHhDRSwweENGLDB4RDBdLFsweDA2LDB4NTksMHhERiwweDQ2LDB4NDIsMHg3MSwweDYyLDB4QjksMHg0MywweDQ4LDB4NjUsMHhERCwweDk0LDB4OTksMHhGOSwweDFEXSxbMHhBNCwweDY5LDB4REEsMHg1MSwweDcxLDB4MTksMHhGQSwweEI5LDB4NTgsMHg3NiwweEY0LDB4MUQsMHgwNiwweEQ0LDB4MEYsMHhGQV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweEQyLDB4RDMsMHhENCwweEQ1LDB4RDcsMHhEOCwweEQ5LDB4REEsMHhEQywweERELDB4REUsMHhERiwweEUxLDB4RTIsMHhFMywweEU0LDB4RTYsMHhFNywweEU4LDB4RTksMHhFQiwweEVDLDB4RUQsMHhFRV0sWzB4NDksMHhBNCwweDQyLDB4MzksMHhDNywweDQ4LDB4RkUsMHhCNCwweDU2LDB4RjUsMHg5QywweDI3LDB4NkEsMHg1NiwweDU4LDB4REZdLFsweDYwLDB4OTEsMHhBQSwweDNCLDB4NjksMHg1QywweDExLDB4RjUsMHhDMCwweEI2LDB4QUQsMHgyNiwweEQzLDB4RDgsMHg2MiwweEZGXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4RjAsMHhGMSwweEYyLDB4RjMsMHhGNSwweEY2LDB4RjcsMHhGOCwweEZBLDB4RkIsMHhGQywweEZELDB4RkUsMHgwMSwweDAwLDB4MDIsMHgwNCwweDA1LDB4MDYsMHgwNywweDA5LDB4MEEsMHgwQiwweDBDXSxbMHg2NiwweDIwLDB4OEYsMHg2RSwweDlELDB4MDQsMHg1MiwweDVCLDB4REUsMHhEQiwweDI3LDB4MzMsMHhCNiwweEE2LDB4QkUsMHgzN10sWzB4NzAsMHhGOSwweEU2LDB4N0YsMHg5RiwweDhELDB4RjEsMHgyOSwweDQxLDB4MzEsMHg2NiwweDJELDB4QzYsMHhFNiwweDkzLDB4NjRdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHgwRSwweDBGLDB4MTAsMHgxMSwweDEzLDB4MTQsMHgxNSwweDE2LDB4MTgsMHgxOSwweDFBLDB4MUIsMHgxRCwweDFFLDB4MUYsMHgyMCwweDIyLDB4MjMsMHgyNCwweDI1LDB4MjcsMHgyOCwweDI5LDB4MkFdLFsweDMzLDB4OTMsMHhGOCwweERGLDB4QzcsMHgyOSwweEM5LDB4N0YsMHg1NCwweDgwLDB4QjksMHg1MCwweEJDLDB4OTYsMHg2NiwweEIwXSxbMHhEMSwweDU0LDB4REMsMHhBRiwweEFELDB4OEIsMHgyMCwweDdGLDB4QTUsMHhDQiwweEM5LDB4NUUsMHg5OSwweDk2LDB4QjUsMHg1OV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDJDLDB4MkQsMHgyRSwweDJGLDB4MzEsMHgzMiwweDMzLDB4MzQsMHgzNiwweDM3LDB4MzgsMHgzOSwweDNCLDB4M0MsMHgzRCwweDNFLDB4NDAsMHg0MSwweDQyLDB4NDMsMHg0NSwweDQ2LDB4NDcsMHg0OF0sWzB4NjAsMHg2OCwweDM0LDB4QzgsMHhDRSwweDA2LDB4M0YsMHgzMiwweDM0LDB4Q0YsMHgxMSwweDQ1LDB4MzIsMHg1RCwweEJELDB4NzFdLFsweDQ5LDB4MzQsMHhENSwweDQxLDB4RTgsMHhCNCwweDZGLDB4QTMsMHgzOSwweEM4LDB4MDUsMHhBNywweEFFLDB4QjksMHhFNSwweERBXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4NEEsMHg0QiwweDRDLDB4NEQsMHg0RiwweDUwLDB4NTEsMHg1MiwweDU0LDB4NTUsMHg1NiwweDU3LDB4NTksMHg1QSwweDVCLDB4NUMsMHg1RSwweDVGLDB4NjAsMHg2MSwweDYzLDB4NjQsMHg2NSwweDY2XSxbMHhGRSwweEMxLDB4QzAsMHg0RiwweDUyLDB4OUIsMHhCRCwweDE3LDB4RDgsMHhDRSwweENGLDB4Q0MsMHg0NywweDE4LDB4QjEsMHg3Rl0sWzB4NjIsMHg1NiwweDRDLDB4NzMsMHg4RiwweDNFLDB4RkUsMHgxOCwweDZFLDB4MUEsMHgxMiwweDdBLDB4MEMsMHg0RCwweDNDLDB4NjFdXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFtbMHg2OCwweDY5LDB4NkEsMHg2QiwweDZELDB4NkUsMHg2RiwweDcwLDB4NzIsMHg3MywweDc0LDB4NzUsMHg3NywweDc4LDB4NzksMHg3QSwweDdDLDB4N0QsMHg3RSwweDdGLDB4ODEsMHg4MiwweDgzLDB4ODRdLFsweDMyLDB4REYsMHg5OSwweEI0LDB4MzEsMHhFRCwweDVELDB4QzUsMHhBQywweEY4LDB4Q0EsMHhGNiwweERDLDB4NkMsMHhFNCwweDc1XSxbMHgwNywweDgwLDB4NUEsMHhBMCwweDQzLDB4OTgsMHg2RSwweEIyLDB4MzYsMHg5MywweEUyLDB4M0IsMHhFRiwweDhGLDB4MzQsMHgzOF1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgW1sweDg2LDB4ODcsMHg4OCwweDg5LDB4OEIsMHg4QywweDhELDB4OEUsMHg5MCwweDkxLDB4OTIsMHg5MywweDk1LDB4OTYsMHg5NywweDk4LDB4OUEsMHg5QiwweDlDLDB4OUQsMHg5RiwweEEwLDB4QTEsMHhBMl0sWzB4N0YsMHhEQywweDJCLDB4NzQsMHg2RiwweDNGLDB4NjYsMHg1MiwweDk2LDB4OTQsMHgzQiwweDgzLDB4NzEsMHgwRCwweDFGLDB4ODJdLFsweERGLDB4MEIsMHg0OSwweDMxLDB4MDMsMHg4QiwweEFELDB4RTgsMHg0OCwweERFLDB4RTMsMHhCNCwweEI4LDB4NUEsMHhBNCwweDRCXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICBbWzB4QTQsMHhBNSwweEE2LDB4QTcsMHhBOSwweEFBLDB4QUIsMHhBQywweEFFLDB4QUYsMHhCMCwweEIxLDB4QjMsMHhCNCwweEI1LDB4QjYsMHhCOCwweEI5LDB4QkEsMHhCQiwweEJELDB4QkUsMHhCRiwweEMwXSxbMHg4RiwweEJBLDB4MTUsMHgxMCwweEEzLDB4QzUsMHhCOCwweDdFLDB4MkUsMHhBQSwweDNGLDB4N0EsMHg5MSwweDQ1LDB4NUMsMHhBMl0sWzB4NTksMHgyRCwweDVGLDB4REUsMHhENywweDY1LDB4ODIsMHhFNCwweDE0LDB4M0MsMHg2NSwweDA5LDB4OTMsMHgwOSwweDQ3LDB4N0NdXV07XG4gIFxuICB2YXIgdGVzdHZlY3RvcnMyNTYgPSBbW1sweDAwLDB4MDEsMHgwMiwweDAzLDB4MDUsMHgwNiwweDA3LDB4MDgsMHgwQSwweDBCLDB4MEMsMHgwRCwweDBGLDB4MTAsMHgxMSwweDEyLDB4MTQsMHgxNSwweDE2LDB4MTcsMHgxOSwweDFBLDB4MUIsMHgxQywweDFFLDB4MUYsMHgyMCwweDIxLDB4MjMsMHgyNCwweDI1LDB4MjZdLFsweDgzLDB4NEUsMHhBRCwweEZDLDB4Q0EsMHhDNywweEUxLDB4QjMsMHgwNiwweDY0LDB4QjEsMHhBQiwweEE0LDB4NDgsMHgxNSwweEFCXSxbMHgxOSwweDQ2LDB4REEsMHhCRiwweDZBLDB4MDMsMHhBMiwweEEyLDB4QzMsMHhEMCwweEIwLDB4NTAsMHg4MCwweEFFLDB4RDYsMHhGQ11dLFxuICAgICAgICAgICAgICBbWzB4MjgsMHgyOSwweDJBLDB4MkIsMHgyRCwweDJFLDB4MkYsMHgzMCwweDMyLDB4MzMsMHgzNCwweDM1LDB4MzcsMHgzOCwweDM5LDB4M0EsMHgzQywweDNELDB4M0UsMHgzRiwweDQxLDB4NDIsMHg0MywweDQ0LDB4NDYsMHg0NywweDQ4LDB4NDksMHg0QiwweDRDLDB4NEQsMHg0RV0sWzB4RDksMHhEQywweDRELDB4QkEsMHgzMCwweDIxLDB4QjAsMHg1RCwweDY3LDB4QzAsMHg1MSwweDhGLDB4NzIsMHhCNiwweDJCLDB4RjFdLFsweDVFLDB4RDMsMHgwMSwweEQ3LDB4NDcsMHhEMywweENDLDB4NzEsMHg1NCwweDQ1LDB4RUIsMHhERSwweEM2LDB4MkYsMHgyRiwweEI0XV0sXG4gICAgICAgICAgICAgIFtbMHg1MCwweDUxLDB4NTIsMHg1MywweDU1LDB4NTYsMHg1NywweDU4LDB4NUEsMHg1QiwweDVDLDB4NUQsMHg1RiwweDYwLDB4NjEsMHg2MiwweDY0LDB4NjUsMHg2NiwweDY3LDB4NjksMHg2QSwweDZCLDB4NkMsMHg2RSwweDZGLDB4NzAsMHg3MSwweDczLDB4NzQsMHg3NSwweDc2XSxbMHhBMiwweDkxLDB4RDgsMHg2MywweDAxLDB4QTQsMHhBNywweDM5LDB4RjcsMHgzOSwweDIxLDB4NzMsMHhBQSwweDNDLDB4NjAsMHg0Q10sWzB4NjUsMHg4NSwweEM4LDB4RjQsMHgzRCwweDEzLDB4QTYsMHhCRSwweEFCLDB4NjQsMHgxOSwweEZDLDB4NTksMHgzNSwweEI5LDB4RDBdXSxcbiAgICAgICAgICAgICAgW1sweDc4LDB4NzksMHg3QSwweDdCLDB4N0QsMHg3RSwweDdGLDB4ODAsMHg4MiwweDgzLDB4ODQsMHg4NSwweDg3LDB4ODgsMHg4OSwweDhBLDB4OEMsMHg4RCwweDhFLDB4OEYsMHg5MSwweDkyLDB4OTMsMHg5NCwweDk2LDB4OTcsMHg5OCwweDk5LDB4OUIsMHg5QywweDlELDB4OUVdLFsweDQyLDB4NjQsMHhCMiwweDY5LDB4NjQsMHg5OCwweERFLDB4NEQsMHhGNywweDk3LDB4ODgsMHhBOSwweEY4LDB4M0UsMHg5MywweDkwXSxbMHgyQSwweDVCLDB4NTYsMHhBNSwweDk2LDB4NjgsMHgwRiwweENDLDB4MEUsMHgwNSwweEY1LDB4RTAsMHhGMSwweDUxLDB4RUMsMHhBRV1dLFxuICAgICAgICAgICAgICBbWzB4QTAsMHhBMSwweEEyLDB4QTMsMHhBNSwweEE2LDB4QTcsMHhBOCwweEFBLDB4QUIsMHhBQywweEFELDB4QUYsMHhCMCwweEIxLDB4QjIsMHhCNCwweEI1LDB4QjYsMHhCNywweEI5LDB4QkEsMHhCQiwweEJDLDB4QkUsMHhCRiwweEMwLDB4QzEsMHhDMywweEM0LDB4QzUsMHhDNl0sWzB4RUUsMHg5OSwweDMyLDB4QjMsMHg3MiwweDE4LDB4MDQsMHhENSwweEE4LDB4M0UsMHhGNSwweDk0LDB4OTIsMHg0NSwweEI2LDB4RjZdLFsweEY1LDB4RDYsMHhGRiwweDQxLDB4NEYsMHhEMiwweEM2LDB4MTgsMHgxNCwweDk0LDB4RDIsMHgwQywweDM3LDB4RjIsMHhCOCwweEM0XV0sXG4gICAgICAgICAgICAgIFtbMHhDOCwweEM5LDB4Q0EsMHhDQiwweENELDB4Q0UsMHhDRiwweEQwLDB4RDIsMHhEMywweEQ0LDB4RDUsMHhENywweEQ4LDB4RDksMHhEQSwweERDLDB4REQsMHhERSwweERGLDB4RTEsMHhFMiwweEUzLDB4RTQsMHhFNiwweEU3LDB4RTgsMHhFOSwweEVCLDB4RUMsMHhFRCwweEVFXSxbMHhFNiwweDI0LDB4OEYsMHg1NSwweEM1LDB4RkQsMHhDQiwweENBLDB4OUMsMHhCQiwweEIwLDB4MUMsMHg4OCwweEEyLDB4RUEsMHg3N10sWzB4ODUsMHgzOSwweDlDLDB4MDEsMHhGNSwweDlGLDB4RkYsMHhCNSwweDIwLDB4NEYsMHgxOSwweEY4LDB4NDgsMHgyRiwweDAwLDB4QjhdXSxcbiAgICAgICAgICAgICAgW1sweEYwLDB4RjEsMHhGMiwweEYzLDB4RjUsMHhGNiwweEY3LDB4RjgsMHhGQSwweEZCLDB4RkMsMHhGRCwweEZFLDB4MDEsMHgwMCwweDAyLDB4MDQsMHgwNSwweDA2LDB4MDcsMHgwOSwweDBBLDB4MEIsMHgwQywweDBFLDB4MEYsMHgxMCwweDExLDB4MTMsMHgxNCwweDE1LDB4MTZdLFsweEI4LDB4MzUsMHg4RSwweDQxLDB4QjksMHhERiwweEY2LDB4NUYsMHhENCwweDYxLDB4RDUsMHg1QSwweDk5LDB4MjYsMHg2MiwweDQ3XSxbMHg5MiwweDA5LDB4N0IsMHg0QywweDg4LDB4QTAsMHg0MSwweERELDB4RjksMHg4MSwweDQ0LDB4QkMsMHg4RCwweDIyLDB4RTgsMHhFN11dLFxuICAgICAgICAgICAgICBbWzB4MTgsMHgxOSwweDFBLDB4MUIsMHgxRCwweDFFLDB4MUYsMHgyMCwweDIyLDB4MjMsMHgyNCwweDI1LDB4MjcsMHgyOCwweDI5LDB4MkEsMHgyQywweDJELDB4MkUsMHgyRiwweDMxLDB4MzIsMHgzMywweDM0LDB4MzYsMHgzNywweDM4LDB4MzksMHgzQiwweDNDLDB4M0QsMHgzRV0sWzB4RjAsMHhFMiwweEQ3LDB4MjIsMHg2MCwweEFGLDB4NTgsMHhFMiwweDFFLDB4MDEsMHg1QSwweEIzLDB4QTQsMHhDMCwweEQ5LDB4MDZdLFsweDg5LDB4QkQsMHg1QiwweDczLDB4QjMsMHg1NiwweEFCLDB4NDEsMHgyQSwweEVGLDB4OUYsMHg3NiwweENFLDB4QTIsMHhENiwweDVDXV0sXG4gICAgICAgICAgICAgIFtbMHg0MCwweDQxLDB4NDIsMHg0MywweDQ1LDB4NDYsMHg0NywweDQ4LDB4NEEsMHg0QiwweDRDLDB4NEQsMHg0RiwweDUwLDB4NTEsMHg1MiwweDU0LDB4NTUsMHg1NiwweDU3LDB4NTksMHg1QSwweDVCLDB4NUMsMHg1RSwweDVGLDB4NjAsMHg2MSwweDYzLDB4NjQsMHg2NSwweDY2XSxbMHg0NywweDVCLDB4OEIsMHg4MiwweDNDLDB4RTgsMHg4OSwweDNELDB4QjMsMHhDNCwweDRBLDB4OUYsMHgyQSwweDM3LDB4OUYsMHhGN10sWzB4MjUsMHgzNiwweDk2LDB4OTAsMHg5MywweEM1LDB4NUYsMHhGOSwweDQ1LDB4NDYsMHg5MiwweEYyLDB4RkEsMHhDMiwweEY1LDB4MzBdXSxcbiAgICAgICAgICAgICAgW1sweDY4LDB4NjksMHg2QSwweDZCLDB4NkQsMHg2RSwweDZGLDB4NzAsMHg3MiwweDczLDB4NzQsMHg3NSwweDc3LDB4NzgsMHg3OSwweDdBLDB4N0MsMHg3RCwweDdFLDB4N0YsMHg4MSwweDgyLDB4ODMsMHg4NCwweDg2LDB4ODcsMHg4OCwweDg5LDB4OEIsMHg4QywweDhELDB4OEVdLFsweDY4LDB4OEYsMHg1MiwweDgxLDB4OTQsMHg1OCwweDEyLDB4ODYsMHgyRiwweDVGLDB4MzAsMHg3NiwweENGLDB4ODAsMHg0MSwweDJGXSxbMHgwNywweEZDLDB4NzYsMHhBOCwweDcyLDB4ODQsMHgzRiwweDNGLDB4NkUsMHgwMCwweDgxLDB4RUUsMHg5MywweDk2LDB4RDYsMHgzN11dLFxuICAgICAgICAgICAgICBbWzB4OTAsMHg5MSwweDkyLDB4OTMsMHg5NSwweDk2LDB4OTcsMHg5OCwweDlBLDB4OUIsMHg5QywweDlELDB4OUYsMHhBMCwweEExLDB4QTIsMHhBNCwweEE1LDB4QTYsMHhBNywweEE5LDB4QUEsMHhBQiwweEFDLDB4QUUsMHhBRiwweEIwLDB4QjEsMHhCMywweEI0LDB4QjUsMHhCNl0sWzB4MDgsMHhEMSwweEQyLDB4QkMsMHg3NSwweDBBLDB4RjUsMHg1MywweDM2LDB4NUQsMHgzNSwweEU3LDB4NUEsMHhGQSwweENFLDB4QUFdLFsweEUzLDB4OEIsMHhBOCwweEVDLDB4MkEsMHhBNywweDQxLDB4MzUsMHg4RCwweENDLDB4OTMsMHhFOCwweEYxLDB4NDEsMHhDNCwweDkxXV0sXG4gICAgICAgICAgICAgIFtbMHhCOCwweEI5LDB4QkEsMHhCQiwweEJELDB4QkUsMHhCRiwweEMwLDB4QzIsMHhDMywweEM0LDB4QzUsMHhDNywweEM4LDB4QzksMHhDQSwweENDLDB4Q0QsMHhDRSwweENGLDB4RDEsMHhEMiwweEQzLDB4RDQsMHhENiwweEQ3LDB4RDgsMHhEOSwweERCLDB4REMsMHhERCwweERFXSxbMHg4NywweDA3LDB4MTIsMHgxRiwweDQ3LDB4Q0MsMHgzRSwweEZDLDB4RUMsMHhBNSwweEY5LDB4QTgsMHg0NywweDQ5LDB4NTAsMHhBMV0sWzB4RDAsMHgyOCwweEVFLDB4MjMsMHhFNCwweEE4LDB4OTAsMHg3NSwweEQwLDB4QjAsMHgzRSwweDg2LDB4OEQsMHg3RCwweDNBLDB4NDJdXSxcbiAgICAgICAgICAgICAgW1sweEUwLDB4RTEsMHhFMiwweEUzLDB4RTUsMHhFNiwweEU3LDB4RTgsMHhFQSwweEVCLDB4RUMsMHhFRCwweEVGLDB4RjAsMHhGMSwweEYyLDB4RjQsMHhGNSwweEY2LDB4RjcsMHhGOSwweEZBLDB4RkIsMHhGQywweEZFLDB4RkUsMHgwMSwweDAxLDB4MDMsMHgwNCwweDA1LDB4MDZdLFsweEU1LDB4MUEsMHhBMCwweEIxLDB4MzUsMHhEQiwweEE1LDB4NjYsMHg5MywweDlDLDB4M0IsMHg2MywweDU5LDB4QTksMHg4MCwweEM1XSxbMHg4QywweEQ5LDB4NDIsMHgzRCwweEZDLDB4NDUsMHg5RSwweDU0LDB4NzEsMHg1NSwweEM1LDB4RDEsMHhENSwweDIyLDB4RTUsMHg0MF1dLFxuICAgICAgICAgICAgICBbWzB4MDgsMHgwOSwweDBBLDB4MEIsMHgwRCwweDBFLDB4MEYsMHgxMCwweDEyLDB4MTMsMHgxNCwweDE1LDB4MTcsMHgxOCwweDE5LDB4MUEsMHgxQywweDFELDB4MUUsMHgxRiwweDIxLDB4MjIsMHgyMywweDI0LDB4MjYsMHgyNywweDI4LDB4MjksMHgyQiwweDJDLDB4MkQsMHgyRV0sWzB4MDYsMHg5QSwweDAwLDB4N0YsMHhDNywweDZBLDB4NDUsMHg5RiwweDk4LDB4QkEsMHhGOSwweDE3LDB4RkUsMHhERiwweDk1LDB4MjFdLFsweDA4LDB4MEUsMHg5NSwweDE3LDB4RUIsMHgxNiwweDc3LDB4NzEsMHg5QSwweENGLDB4NzIsMHg4MCwweDg2LDB4MDQsMHgwQSwweEUzXV0sXG4gICAgICAgICAgICAgIFtbMHgzMCwweDMxLDB4MzIsMHgzMywweDM1LDB4MzYsMHgzNywweDM4LDB4M0EsMHgzQiwweDNDLDB4M0QsMHgzRiwweDQwLDB4NDEsMHg0MiwweDQ0LDB4NDUsMHg0NiwweDQ3LDB4NDksMHg0QSwweDRCLDB4NEMsMHg0RSwweDRGLDB4NTAsMHg1MSwweDUzLDB4NTQsMHg1NSwweDU2XSxbMHg3MiwweDYxLDB4NjUsMHhDMSwweDcyLDB4M0YsMHhCQywweEY2LDB4QzAsMHgyNiwweEQ3LDB4RDAsMHgwQiwweDA5LDB4MTAsMHgyN10sWzB4N0MsMHgxNywweDAwLDB4MjEsMHgxQSwweDM5LDB4OTEsMHhGQywweDBFLDB4Q0QsMHhFRCwweDBBLDB4QjMsMHhFNSwweDc2LDB4QjBdXV07XG5cbiAgdmFyIHJlcyA9IHRydWU7XG4gIHZhciBqID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXN0dmVjdG9yczEyOC5sZW5ndGg7IGkrKykge1xuICAgIHZhciByZXMyID0gdGVzdF9hZXModGVzdHZlY3RvcnMxMjhbaV1bMV0sdGVzdHZlY3RvcnMxMjhbaV1bMF0sdGVzdHZlY3RvcnMxMjhbaV1bMl0pO1xuICAgIHJlcyAmPSByZXMyO1xuICAgIGlmICghcmVzMikge1xuICAgICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyAxMjggYml0IGtleSB2ZWN0b3Igd2l0aCBibG9jayBcIitcbiAgICAgICAgdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczEyOFtpXVsxXSkrXG4gICAgICAgIFwiIGFuZCBrZXkgXCIrdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczEyOFtpXVswXSkrXG4gICAgICAgIFwiIHNob3VsZCBiZSBcIit1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzMTI4W2ldWzJdKSxcbiAgICAgICAgZmFsc2UpO1xuICAgICAgaisrO1xuICAgIH1cbiAgfVxuICBpZiAocmVzKSB7XG4gICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiMTI4IGJpdCBrZXkgdGVzdCB2ZWN0b3JzIGNvbXBsZXRlZC5cIix0cnVlKVxuICAgIGorKztcbiAgfVxuICBcbiAgcmVzID0gdHJ1ZTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXN0dmVjdG9yczE5Mi5sZW5ndGg7IGkrKykge1xuICAgIHZhciByZXMyID0gdGVzdF9hZXModGVzdHZlY3RvcnMxOTJbaV1bMV0sdGVzdHZlY3RvcnMxOTJbaV1bMF0sdGVzdHZlY3RvcnMxOTJbaV1bMl0pO1xuICAgIHJlcyAmPSByZXMyO1xuICAgIGlmICghcmVzMikge1xuICAgICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyAxOTIgYml0IGtleSB2ZWN0b3Igd2l0aCBibG9jayBcIitcbiAgICAgICAgdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczE5MltpXVsxXSkrXG4gICAgICAgIFwiIGFuZCBrZXkgXCIrdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczE5MltpXVswXSkrXG4gICAgICAgIFwiIHNob3VsZCBiZSBcIit1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzMTkyW2ldWzJdKSxcbiAgICAgICAgZmFsc2UpO1xuICAgICAgaisrO1xuICAgIH1cbiAgfVxuICBpZiAocmVzKSB7XG4gICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiMTkyIGJpdCBrZXkgdGVzdCB2ZWN0b3JzIGNvbXBsZXRlZC5cIix0cnVlKVxuICAgIGorKztcbiAgfVxuXG4gIHJlcyA9IHRydWU7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGVzdHZlY3RvcnMyNTYubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcmVzMiA9IHRlc3RfYWVzKHRlc3R2ZWN0b3JzMjU2W2ldWzFdLHRlc3R2ZWN0b3JzMjU2W2ldWzBdLHRlc3R2ZWN0b3JzMjU2W2ldWzJdKTtcbiAgICByZXMgJj0gcmVzMjtcbiAgICBpZiAoIXJlczIpIHtcbiAgICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3RpbmcgMjU2IGJpdCBrZXkgdmVjdG9yIHdpdGggYmxvY2sgXCIrXG4gICAgICAgIHV0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnMyNTZbaV1bMV0pK1xuICAgICAgICBcIiBhbmQga2V5IFwiK3V0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnMyNTZbaV1bMF0pK1xuICAgICAgICBcIiBzaG91bGQgYmUgXCIrdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yczI1NltpXVsyXSksXG4gICAgICAgIGZhbHNlKTtcbiAgICAgIGorKztcbiAgICB9XG4gIH1cbiAgaWYgKHJlcykge1xuICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIjI1NiBiaXQga2V5IHRlc3QgdmVjdG9ycyBjb21wbGV0ZWQuXCIsIHRydWUpXG4gICAgaisrO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn0pO1xuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi8uLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJCbG93ZmlzaCBjaXBoZXIgdGVzdCB3aXRoIHRlc3QgdmVjdG9ycyBmcm9tIGh0dHA6Ly93d3cuc2NobmVpZXIuY29tL2NvZGUvdmVjdG9ycy50eHRcIiwgZnVuY3Rpb24oKSB7XG4gIHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vLi4vJyksXG4gICAgdXRpbCA9IG9wZW5wZ3AudXRpbCxcbiAgICBCRmVuY3J5cHQgPSBvcGVucGdwLmNpcGhlci5ibG93ZmlzaDtcblxuICB2YXIgcmVzdWx0ID0gW107XG4gIGZ1bmN0aW9uIHRlc3RfYmYoaW5wdXQsIGtleSwgb3V0cHV0KSB7XG4gICAgdmFyIGJsb3dmaXNoID0gbmV3IG9wZW5wZ3AuY2lwaGVyLmJsb3dmaXNoKHV0aWwuYmluMnN0cihrZXkpKTtcbiAgICB2YXIgcmVzdWx0ID0gdXRpbC5iaW4yc3RyKGJsb3dmaXNoLmVuY3J5cHQoaW5wdXQpKTtcblxuICAgIHJldHVybiAodXRpbC5oZXhzdHJkdW1wKHJlc3VsdCkgPT0gdXRpbC5oZXhzdHJkdW1wKHV0aWwuYmluMnN0cihvdXRwdXQpKSk7XG4gIH1cbiAgdmFyIHRlc3R2ZWN0b3JzID0gW1tbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg0RSwweEY5LDB4OTcsMHg0NSwweDYxLDB4OTgsMHhERCwweDc4XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRl0sWzB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRl0sWzB4NTEsMHg4NiwweDZGLDB4RDUsMHhCOCwweDVFLDB4Q0IsMHg4QV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDMwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDEwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDFdLFsweDdELDB4ODUsMHg2RiwweDlBLDB4NjEsMHgzMCwweDYzLDB4RjJdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExXSxbMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExXSxbMHgyNCwweDY2LDB4REQsMHg4NywweDhCLDB4OTYsMHgzQywweDlEXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDEsMHgyMywweDQ1LDB4NjcsMHg4OSwweEFCLDB4Q0QsMHhFRl0sWzB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMV0sWzB4NjEsMHhGOSwweEMzLDB4ODAsMHgyMiwweDgxLDB4QjAsMHg5Nl1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDExLDB4MTEsMHgxMSwweDExLDB4MTEsMHgxMSwweDExLDB4MTFdLFsweDAxLDB4MjMsMHg0NSwweDY3LDB4ODksMHhBQiwweENELDB4RUZdLFsweDdELDB4MEMsMHhDNiwweDMwLDB4QUYsMHhEQSwweDFFLDB4QzddXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg0RSwweEY5LDB4OTcsMHg0NSwweDYxLDB4OTgsMHhERCwweDc4XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4RkUsMHhEQywweEJBLDB4OTgsMHg3NiwweDU0LDB4MzIsMHgxMF0sWzB4MDEsMHgyMywweDQ1LDB4NjcsMHg4OSwweEFCLDB4Q0QsMHhFRl0sWzB4MEEsMHhDRSwweEFCLDB4MEYsMHhDNiwweEEwLDB4QTIsMHg4RF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDdDLDB4QTEsMHgxMCwweDQ1LDB4NEEsMHgxQSwweDZFLDB4NTddLFsweDAxLDB4QTEsMHhENiwweEQwLDB4MzksMHg3NywweDY3LDB4NDJdLFsweDU5LDB4QzYsMHg4MiwweDQ1LDB4RUIsMHgwNSwweDI4LDB4MkJdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMSwweDMxLDB4RDksMHg2MSwweDlELDB4QzEsMHgzNywweDZFXSxbMHg1QywweEQ1LDB4NEMsMHhBOCwweDNELDB4RUYsMHg1NywweERBXSxbMHhCMSwweEI4LDB4Q0MsMHgwQiwweDI1LDB4MEYsMHgwOSwweEEwXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDcsMHhBMSwweDEzLDB4M0UsMHg0QSwweDBCLDB4MjYsMHg4Nl0sWzB4MDIsMHg0OCwweEQ0LDB4MzgsMHgwNiwweEY2LDB4NzEsMHg3Ml0sWzB4MTcsMHgzMCwweEU1LDB4NzcsMHg4QiwweEVBLDB4MUQsMHhBNF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDM4LDB4NDksMHg2NywweDRDLDB4MjYsMHgwMiwweDMxLDB4OUVdLFsweDUxLDB4NDUsMHg0QiwweDU4LDB4MkQsMHhERiwweDQ0LDB4MEFdLFsweEEyLDB4NUUsMHg3OCwweDU2LDB4Q0YsMHgyNiwweDUxLDB4RUJdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwNCwweEI5LDB4MTUsMHhCQSwweDQzLDB4RkUsMHhCNSwweEI2XSxbMHg0MiwweEZELDB4NDQsMHgzMCwweDU5LDB4NTcsMHg3RiwweEEyXSxbMHgzNSwweDM4LDB4ODIsMHhCMSwweDA5LDB4Q0UsMHg4RiwweDFBXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDEsMHgxMywweEI5LDB4NzAsMHhGRCwweDM0LDB4RjIsMHhDRV0sWzB4MDUsMHg5QiwweDVFLDB4MDgsMHg1MSwweENGLDB4MTQsMHgzQV0sWzB4NDgsMHhGNCwweEQwLDB4ODgsMHg0QywweDM3LDB4OTksMHgxOF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAxLDB4NzAsMHhGMSwweDc1LDB4NDYsMHg4RiwweEI1LDB4RTZdLFsweDA3LDB4NTYsMHhEOCwweEUwLDB4NzcsMHg0NywweDYxLDB4RDJdLFsweDQzLDB4MjEsMHg5MywweEI3LDB4ODksMHg1MSwweEZDLDB4OThdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHg0MywweDI5LDB4N0YsMHhBRCwweDM4LDB4RTMsMHg3MywweEZFXSxbMHg3NiwweDI1LDB4MTQsMHhCOCwweDI5LDB4QkYsMHg0OCwweDZBXSxbMHgxMywweEYwLDB4NDEsMHg1NCwweEQ2LDB4OUQsMHgxQSwweEU1XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDcsMHhBNywweDEzLDB4NzAsMHg0NSwweERBLDB4MkEsMHgxNl0sWzB4M0IsMHhERCwweDExLDB4OTAsMHg0OSwweDM3LDB4MjgsMHgwMl0sWzB4MkUsMHhFRCwweERBLDB4OTMsMHhGRiwweEQzLDB4OUMsMHg3OV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDA0LDB4NjgsMHg5MSwweDA0LDB4QzIsMHhGRCwweDNCLDB4MkZdLFsweDI2LDB4OTUsMHg1RiwweDY4LDB4MzUsMHhBRiwweDYwLDB4OUFdLFsweEQ4LDB4ODcsMHhFMCwweDM5LDB4M0MsMHgyRCwweEE2LDB4RTNdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgzNywweEQwLDB4NkIsMHhCNSwweDE2LDB4Q0IsMHg3NSwweDQ2XSxbMHgxNiwweDRELDB4NUUsMHg0MCwweDRGLDB4MjcsMHg1MiwweDMyXSxbMHg1RiwweDk5LDB4RDAsMHg0RiwweDVCLDB4MTYsMHgzOSwweDY5XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MUYsMHgwOCwweDI2LDB4MEQsMHgxQSwweEMyLDB4NDYsMHg1RV0sWzB4NkIsMHgwNSwweDZFLDB4MTgsMHg3NSwweDlGLDB4NUMsMHhDQV0sWzB4NEEsMHgwNSwweDdBLDB4M0IsMHgyNCwweEQzLDB4OTcsMHg3Ql1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDU4LDB4NDAsMHgyMywweDY0LDB4MUEsMHhCQSwweDYxLDB4NzZdLFsweDAwLDB4NEIsMHhENiwweEVGLDB4MDksMHgxNywweDYwLDB4NjJdLFsweDQ1LDB4MjAsMHgzMSwweEMxLDB4RTQsMHhGQSwweERBLDB4OEVdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMiwweDU4LDB4MTYsMHgxNiwweDQ2LDB4MjksMHhCMCwweDA3XSxbMHg0OCwweDBELDB4MzksMHgwMCwweDZFLDB4RTcsMHg2MiwweEYyXSxbMHg3NSwweDU1LDB4QUUsMHgzOSwweEY1LDB4OUIsMHg4NywweEJEXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4NDksMHg3OSwweDNFLDB4QkMsMHg3OSwweEIzLDB4MjUsMHg4Rl0sWzB4NDMsMHg3NSwweDQwLDB4QzgsMHg2OSwweDhGLDB4M0MsMHhGQV0sWzB4NTMsMHhDNSwweDVGLDB4OUMsMHhCNCwweDlGLDB4QzAsMHgxOV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDRGLDB4QjAsMHg1RSwweDE1LDB4MTUsMHhBQiwweDczLDB4QTddLFsweDA3LDB4MkQsMHg0MywweEEwLDB4NzcsMHgwNywweDUyLDB4OTJdLFsweDdBLDB4OEUsMHg3QiwweEZBLDB4OTMsMHg3RSwweDg5LDB4QTNdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHg0OSwweEU5LDB4NUQsMHg2RCwweDRDLDB4QTIsMHgyOSwweEJGXSxbMHgwMiwweEZFLDB4NTUsMHg3NywweDgxLDB4MTcsMHhGMSwweDJBXSxbMHhDRiwweDlDLDB4NUQsMHg3QSwweDQ5LDB4ODYsMHhBRCwweEI1XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDEsMHg4MywweDEwLDB4REMsMHg0MCwweDlCLDB4MjYsMHhENl0sWzB4MUQsMHg5RCwweDVDLDB4NTAsMHgxOCwweEY3LDB4MjgsMHhDMl0sWzB4RDEsMHhBQiwweEIyLDB4OTAsMHg2NSwweDhCLDB4QzcsMHg3OF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDFDLDB4NTgsMHg3RiwweDFDLDB4MTMsMHg5MiwweDRGLDB4RUZdLFsweDMwLDB4NTUsMHgzMiwweDI4LDB4NkQsMHg2RiwweDI5LDB4NUFdLFsweDU1LDB4Q0IsMHgzNywweDc0LDB4RDEsMHgzRSwweEYyLDB4MDFdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMSwweDAxLDB4MDEsMHgwMSwweDAxLDB4MDEsMHgwMSwweDAxXSxbMHgwMSwweDIzLDB4NDUsMHg2NywweDg5LDB4QUIsMHhDRCwweEVGXSxbMHhGQSwweDM0LDB4RUMsMHg0OCwweDQ3LDB4QjIsMHg2OCwweEIyXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MUYsMHgxRiwweDFGLDB4MUYsMHgwRSwweDBFLDB4MEUsMHgwRV0sWzB4MDEsMHgyMywweDQ1LDB4NjcsMHg4OSwweEFCLDB4Q0QsMHhFRl0sWzB4QTcsMHg5MCwweDc5LDB4NTEsMHgwOCwweEVBLDB4M0MsMHhBRV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweEUwLDB4RkUsMHhFMCwweEZFLDB4RjEsMHhGRSwweEYxLDB4RkVdLFsweDAxLDB4MjMsMHg0NSwweDY3LDB4ODksMHhBQiwweENELDB4RUZdLFsweEMzLDB4OUUsMHgwNywweDJELDB4OUYsMHhBQywweDYzLDB4MURdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGXSxbMHgwMSwweDQ5LDB4MzMsMHhFMCwweENELDB4QUYsMHhGNiwweEU0XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRl0sWzB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RjIsMHgxRSwweDlBLDB4NzcsMHhCNywweDFDLDB4NDksMHhCQ11dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAxLDB4MjMsMHg0NSwweDY3LDB4ODksMHhBQiwweENELDB4RUZdLFsweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDI0LDB4NTksMHg0NiwweDg4LDB4NTcsMHg1NCwweDM2LDB4OUFdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHhGRSwweERDLDB4QkEsMHg5OCwweDc2LDB4NTQsMHgzMiwweDEwXSxbMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGLDB4RkYsMHhGRiwweEZGXSxbMHg2QiwweDVDLDB4NUEsMHg5QywweDVELDB4OUUsMHgwQSwweDVBXV1dO1xuXG4gIHZhciByZXMgPSB0cnVlO1xuICB2YXIgaiA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGVzdHZlY3RvcnMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcmVzMiA9IHRlc3RfYmYodGVzdHZlY3RvcnNbaV1bMV0sdGVzdHZlY3RvcnNbaV1bMF0sdGVzdHZlY3RvcnNbaV1bMl0pO1xuICAgIHJlcyAmPSByZXMyO1xuICAgIGlmICghcmVzMikge1xuICAgICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyB2ZWN0b3IgXCIraStcIiB3aXRoIGJsb2NrIFwiK1xuICAgICAgICB1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzW2ldWzBdKStcbiAgICAgICAgXCIgYW5kIGtleSBcIit1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzW2ldWzFdKStcbiAgICAgICAgXCIgc2hvdWxkIGJlIFwiK3V0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnNbaV1bMl0pLCBmYWxzZSk7XG4gICAgICBqKys7XG4gICAgfVxuICB9XG4gIGlmIChyZXMpIHtcbiAgICByZXN1bHRbal0gPSBuZXcgdW5pdC5yZXN1bHQoXCIzNCB0ZXN0IHZlY3RvcnMgY29tcGxldGVkIFwiLCB0cnVlKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uLy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIkNBU1QtMTI4IGNpcGhlciB0ZXN0IHdpdGggdGVzdCB2ZWN0b3JzIGZyb20gUkZDMjE0NFwiLCBmdW5jdGlvbigpIHtcblx0dmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8uLi8nKSxcblx0XHR1dGlsID0gb3BlbnBncC51dGlsO1xuXG5cdHZhciByZXN1bHQgPSBbXTtcblx0ZnVuY3Rpb24gdGVzdF9jYXN0KGlucHV0LCBrZXksIG91dHB1dCkge1xuXHRcdHZhciBjYXN0NSA9IG5ldyBvcGVucGdwLmNpcGhlci5jYXN0NSh1dGlsLmJpbjJzdHIoa2V5KSk7XG5cdFx0dmFyIHJlc3VsdCA9IHV0aWwuYmluMnN0cihjYXN0NS5lbmNyeXB0KGlucHV0KSk7XG5cblx0XHRyZXR1cm4gdXRpbC5oZXhzdHJkdW1wKHJlc3VsdCkgPT0gdXRpbC5oZXhzdHJkdW1wKHV0aWwuYmluMnN0cihvdXRwdXQpKTtcblx0fVxuXHRcblx0dmFyIHRlc3R2ZWN0b3JzID0gW1tbMHgwMSwweDIzLDB4NDUsMHg2NywweDEyLDB4MzQsMHg1NiwweDc4LDB4MjMsMHg0NSwweDY3LDB4ODksMHgzNCwweDU2LDB4NzgsMHg5QV0sWzB4MDEsMHgyMywweDQ1LDB4NjcsMHg4OSwweEFCLDB4Q0QsMHhFRl0sWzB4MjMsMHg4QiwweDRGLDB4RTUsMHg4NCwweDdFLDB4NDQsMHhCMl1dXTtcblxuXHRmb3IgKHZhciBpID0gMDsgaSA8IHRlc3R2ZWN0b3JzLmxlbmd0aDsgaSsrKSB7XG5cdFx0cmVzdWx0W2ldID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyB2ZWN0b3Igd2l0aCBibG9jayBcIitcblx0XHRcdFx0dXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yc1tpXVswXSkrXG5cdFx0XHRcdFwiIGFuZCBrZXkgXCIrdXRpbC5oZXhpZHVtcCh0ZXN0dmVjdG9yc1tpXVsxXSkrXG5cdFx0XHRcdFwiIHNob3VsZCBiZSBcIit1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzW2ldWzJdKSxcblx0XHRcdHRlc3RfY2FzdCh0ZXN0dmVjdG9yc1tpXVsxXSx0ZXN0dmVjdG9yc1tpXVswXSx0ZXN0dmVjdG9yc1tpXVsyXSkpO1xuXHR9XG5cdHJldHVybiByZXN1bHQ7XG59KTtcbiIsInZhciB1bml0ID0gcmVxdWlyZSgnLi4vLi4vdW5pdC5qcycpO1xuXG51bml0LnJlZ2lzdGVyKFwiVHJpcGxlREVTIChFREUpIGNpcGhlciB0ZXN0IHdpdGggdGVzdCB2ZWN0b3JzIGZyb20gaHR0cDovL2NzcmMubmlzdC5nb3YvcHVibGljYXRpb25zL25pc3RwdWJzLzgwMC0yMC84MDAtMjAucGRmXCIsIGZ1bmN0aW9uKCkge1xuICB2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLy4uLycpLFxuICAgIHV0aWwgPSBvcGVucGdwLnV0aWw7XG5cbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIga2V5ID0gdXRpbC5iaW4yc3RyKFsxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMV0pO1xuICB2YXIgdGVzdHZlY3RvcnMgPSBbW1sweDgwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDk1LDB4RjgsMHhBNSwweEU1LDB4REQsMHgzMSwweEQ5LDB4MDBdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHg0MCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhERCwweDdGLDB4MTIsMHgxQywweEE1LDB4MDEsMHg1NiwweDE5XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MjAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4MkUsMHg4NiwweDUzLDB4MTAsMHg0RiwweDM4LDB4MzQsMHhFQV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDEwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDRCLDB4RDMsMHg4OCwweEZGLDB4NkMsMHhEOCwweDFELDB4NEZdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwOCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHgyMCwweEI5LDB4RTcsMHg2NywweEIyLDB4RkIsMHgxNCwweDU2XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDQsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4NTUsMHg1NywweDkzLDB4ODAsMHhENywweDcxLDB4MzgsMHhFRl1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAyLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDZDLDB4QzUsMHhERSwweEZBLDB4QUYsMHgwNCwweDUxLDB4MkZdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMSwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHgwRCwweDlGLDB4MjcsMHg5QiwweEE1LDB4RDgsMHg3MiwweDYwXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHg4MCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RDksMHgwMywweDFCLDB4MDIsMHg3MSwweEJELDB4NUEsMHgwQV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAwLDB4NDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDQyLDB4NDIsMHg1MCwweEIzLDB4N0MsMHgzRCwweEQ5LDB4NTFdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDIwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhCOCwweDA2LDB4MUIsMHg3RSwweENELDB4OUEsMHgyMSwweEU1XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgxMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RjEsMHg1RCwweDBGLDB4MjgsMHg2QiwweDY1LDB4QkQsMHgyOF1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAwLDB4MDgsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweEFELDB4RDAsMHhDQywweDhELDB4NkUsMHg1RCwweEVCLDB4QTFdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDA0LDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhFNiwweEQ1LDB4RjgsMHgyNywweDUyLDB4QUQsMHg2MywweEQxXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMiwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RUMsMHhCRiwweEUzLDB4QkQsMHgzRiwweDU5LDB4MUEsMHg1RV1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAwLDB4MDEsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweEYzLDB4NTYsMHg4MywweDQzLDB4NzksMHhEMSwweDY1LDB4Q0RdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4ODAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHgyQiwweDlGLDB4OTgsMHgyRiwweDIwLDB4MDMsMHg3RiwweEE5XV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDQwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4ODgsMHg5RCwweEUwLDB4NjgsMHhBMSwweDZGLDB4MEIsMHhFNl1dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAwLDB4MDAsMHgyMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweEUxLDB4OUUsMHgyNywweDVELDB4ODQsMHg2QSwweDEyLDB4OThdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MTAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHgzMiwweDlBLDB4OEUsMHhENSwweDIzLDB4RDcsMHgxQSwweEVDXV0sXG4gICAgICAgICAgICAgICAgICAgICBbWzB4MDAsMHgwMCwweDA4LDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMF0sWzB4RTcsMHhGQywweEUyLDB4MjUsMHg1NywweEQyLDB4M0MsMHg5N11dLFxuICAgICAgICAgICAgICAgICAgICAgW1sweDAwLDB4MDAsMHgwNCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDBdLFsweDEyLDB4QTksMHhGNSwweDgxLDB4N0YsMHhGMiwweEQ2LDB4NURdXSxcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDIsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhBNCwweDg0LDB4QzMsMHhBRCwweDM4LDB4REMsMHg5QywweDE5XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDEsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhGQiwweEUwLDB4MEEsMHg4QSwweDFFLDB4RjgsMHhBRCwweDcyXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHg4MCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg3NSwweDBELDB4MDcsMHg5NCwweDA3LDB4NTIsMHgxMywweDYzXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHg0MCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg2NCwweEZFLDB4RUQsMHg5QywweDcyLDB4NEMsMHgyRiwweEFGXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgyMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhGMCwweDJCLDB4MjYsMHgzQiwweDMyLDB4OEUsMHgyQiwweDYwXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgxMCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHg5RCwweDY0LDB4NTUsMHg1QSwweDlBLDB4MTAsMHhCOCwweDUyXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwOCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhEMSwweDA2LDB4RkYsMHgwQiwweEVELDB4NTIsMHg1NSwweEQ3XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwNCwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhFMSwweDY1LDB4MkMsMHg2QiwweDEzLDB4OEMsMHg2NCwweEE1XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMiwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhFNCwweDI4LDB4NTgsMHgxMSwweDg2LDB4RUMsMHg4RiwweDQ2XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMSwweDAwLDB4MDAsMHgwMCwweDAwXSxbMHhBRSwweEI1LDB4RjUsMHhFRCwweEUyLDB4MkQsMHgxQSwweDM2XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDgwLDB4MDAsMHgwMCwweDAwXSxbMHhFOSwweDQzLDB4RDcsMHg1NiwweDhBLDB4RUMsMHgwQywweDVDXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDQwLDB4MDAsMHgwMCwweDAwXSxbMHhERiwweDk4LDB4QzgsMHgyNywweDZGLDB4NTQsMHhCMCwweDRCXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDIwLDB4MDAsMHgwMCwweDAwXSxbMHhCMSwweDYwLDB4RTQsMHg2OCwweDBGLDB4NkMsMHg2OSwweDZGXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDEwLDB4MDAsMHgwMCwweDAwXSxbMHhGQSwweDA3LDB4NTIsMHhCMCwweDdELDB4OUMsMHg0QSwweEI4XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDA4LDB4MDAsMHgwMCwweDAwXSxbMHhDQSwweDNBLDB4MkIsMHgwMywweDZELDB4QkMsMHg4NSwweDAyXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDA0LDB4MDAsMHgwMCwweDAwXSxbMHg1RSwweDA5LDB4MDUsMHg1MSwweDdCLDB4QjUsMHg5QiwweENGXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAyLDB4MDAsMHgwMCwweDAwXSxbMHg4MSwweDRFLDB4RUIsMHgzQiwweDkxLDB4RDksMHgwNywweDI2XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAxLDB4MDAsMHgwMCwweDAwXSxbMHg0RCwweDQ5LDB4REIsMHgxNSwweDMyLDB4OTEsMHg5QywweDlGXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4ODAsMHgwMCwweDAwXSxbMHgyNSwweEVCLDB4NUYsMHhDMywweEY4LDB4Q0YsMHgwNiwweDIxXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4NDAsMHgwMCwweDAwXSxbMHhBQiwweDZBLDB4MjAsMHhDMCwweDYyLDB4MEQsMHgxQywweDZGXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MjAsMHgwMCwweDAwXSxbMHg3OSwweEU5LDB4MEQsMHhCQywweDk4LDB4RjksMHgyQywweENBXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MTAsMHgwMCwweDAwXSxbMHg4NiwweDZFLDB4Q0UsMHhERCwweDgwLDB4NzIsMHhCQiwweDBFXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDgsMHgwMCwweDAwXSxbMHg4QiwweDU0LDB4NTMsMHg2RiwweDJGLDB4M0UsMHg2NCwweEE4XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDQsMHgwMCwweDAwXSxbMHhFQSwweDUxLDB4RDMsMHg5NywweDU1LDB4OTUsMHhCOCwweDZCXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDIsMHgwMCwweDAwXSxbMHhDQSwweEZGLDB4QzYsMHhBQywweDQ1LDB4NDIsMHhERSwweDMxXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDEsMHgwMCwweDAwXSxbMHg4RCwweEQ0LDB4NUEsMHgyRCwweERGLDB4OTAsMHg3OSwweDZDXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHg4MCwweDAwXSxbMHgxMCwweDI5LDB4RDUsMHg1RSwweDg4LDB4MEUsMHhDMiwweEQwXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHg0MCwweDAwXSxbMHg1RCwweDg2LDB4Q0IsMHgyMywweDYzLDB4OUQsMHhCRSwweEE5XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgyMCwweDAwXSxbMHgxRCwweDFDLDB4QTgsMHg1MywweEFFLDB4N0MsMHgwQywweDVGXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgxMCwweDAwXSxbMHhDRSwweDMzLDB4MjMsMHgyOSwweDI0LDB4OEYsMHgzMiwweDI4XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwOCwweDAwXSxbMHg4NCwweDA1LDB4RDEsMHhBQiwweEUyLDB4NEYsMHhCOSwweDQyXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwNCwweDAwXSxbMHhFNiwweDQzLDB4RDcsMHg4MCwweDkwLDB4Q0EsMHg0MiwweDA3XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMiwweDAwXSxbMHg0OCwweDIyLDB4MUIsMHg5OSwweDM3LDB4NzQsMHg4QSwweDIzXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMSwweDAwXSxbMHhERCwweDdDLDB4MEIsMHhCRCwweDYxLDB4RkEsMHhGRCwweDU0XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDgwXSxbMHgyRiwweEJDLDB4MjksMHgxQSwweDU3LDB4MEQsMHhCNSwweEM0XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDQwXSxbMHhFMCwweDdDLDB4MzAsMHhENywweEU0LDB4RTIsMHg2RSwweDEyXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDIwXSxbMHgwOSwweDUzLDB4RTIsMHgyNSwweDhFLDB4OEUsMHg5MCwweEExXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDEwXSxbMHg1QiwweDcxLDB4MUIsMHhDNCwweENFLDB4RUIsMHhGMiwweEVFXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDA4XSxbMHhDQywweDA4LDB4M0YsMHgxRSwweDZELDB4OUUsMHg4NSwweEY2XV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDA0XSxbMHhEMiwweEZELDB4ODgsMHg2NywweEQ1LDB4MEQsMHgyRCwweEZFXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAyXSxbMHgwNiwweEU3LDB4RUEsMHgyMiwweENFLDB4OTIsMHg3MCwweDhGXV0sXHJcbiAgICAgICAgICAgICAgICAgICAgIFtbMHgwMCwweDAwLDB4MDAsMHgwMCwweDAwLDB4MDAsMHgwMCwweDAxXSxbMHgxNiwweDZCLDB4NDAsMHhCNCwweDRBLDB4QkEsMHg0QiwweEQ2XV1dO1xyXG5cbiAgdmFyIHJlcyA9IHRydWU7XG4gIHZhciBqID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXN0dmVjdG9ycy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkZXMgPSBuZXcgb3BlbnBncC5jaXBoZXIuZGVzKGtleSk7XG5cbiAgICB2YXIgZW5jciA9IHV0aWwuYmluMnN0cihkZXMuZW5jcnlwdCh0ZXN0dmVjdG9yc1tpXVswXSwga2V5KSk7XG4gICAgdmFyIHJlczIgPSBlbmNyID09IHV0aWwuYmluMnN0cih0ZXN0dmVjdG9yc1tpXVsxXSk7XG5cbiAgICByZXMgJj0gcmVzMjtcblxuICAgIGlmICghcmVzMikge1xuICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIlRlc3RpbmcgdmVjdG9yIHdpdGggYmxvY2sgXCIgK1xuICAgICAgICB1dGlsLmhleGlkdW1wKHRlc3R2ZWN0b3JzW2ldWzBdKSArXG4gICAgICAgIFwiIGFuZCBrZXkgXCIgKyB1dGlsLmhleHN0cmR1bXAoa2V5KSArXG4gICAgICAgIFwiIHNob3VsZCBiZSBcIiArIHV0aWwuaGV4aWR1bXAodGVzdHZlY3RvcnNbaV1bMV0pICsgXCIgIT0gXCIgK1xuICAgICAgICB1dGlsLmhleGlkdW1wKGVuY3IpLFxuICAgICAgZmFsc2UpO1xuICAgIGorKztcbiAgICB9XG4gIH1cbiAgaWYgKHJlcykge1xuICAgIHJlc3VsdFtqXSA9IG5ldyB1bml0LnJlc3VsdChcIkFsbCAzREVTIEVERSB0ZXN0IHZlY3RvcnMgY29tcGxldGVkXCIsIHRydWUpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59KTtcblxuXG51bml0LnJlZ2lzdGVyKFwiREVTIGVuY3J5cHQvZGVjcnlwdCBwYWRkaW5nIHRlc3RzXCIsIGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vLi4vJyksXG4gICAgICB1dGlsID0gb3BlbnBncC51dGlsO1xuXG4gICAgdmFyIHJlc3VsdCA9IFtdO1xyXG4gICAgdmFyIGtleSA9IHV0aWwuYmluMnN0cihbMHgwMSwgMHgyMywgMHg0NSwgMHg2NywgMHg4OSwgMHhBQiwgMHhDRCwgMHhFRl0pO1xyXG4gICAgdmFyIHRlc3R2ZWN0b3JzID0gbmV3IEFycmF5KCk7XHJcbiAgICB0ZXN0dmVjdG9yc1swXSA9IFtbWzB4MDFdLCBbMHgyNCwgMHhDNywgMHg0QSwgMHg5QSwgMHg3OSwgMHg3NSwgMHg0QiwgMHhDN11dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwMiwgMHgwM10sIFsweEE3LCAweDdBLCAweDlBLCAweDU5LCAweDhBLCAweDg2LCAweDg1LCAweEM1XV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDAzLCAweDA0LCAweDA1XSwgWzB4MDEsIDB4Q0YsIDB4RUIsIDB4NkEsIDB4NzQsIDB4NjAsIDB4RjUsIDB4MDJdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDQsIDB4MDUsIDB4MDYsIDB4MDddLCBbMHhBOCwgMHhGMCwgMHgzRCwgMHg1OSwgMHhCQSwgMHg2QiwgMHgwRSwgMHg3Nl1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNSwgMHgwNiwgMHgwNywgMHgwOCwgMHgwOV0sIFsweDg2LCAweDQwLCAweDMzLCAweDYxLCAweDNGLCAweDU1LCAweDczLCAweDQ5XV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA2LCAweDA3LCAweDA4LCAweDA5LCAweDBBLCAweDBCXSwgWzB4MTMsIDB4MjEsIDB4M0UsIDB4MEUsIDB4Q0UsIDB4MkMsIDB4OTQsIDB4MDFdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDcsIDB4MDgsIDB4MDksIDB4MEEsIDB4MEIsIDB4MEMsIDB4MERdLCBbMHgzMCwgMHg0OSwgMHg5NywgMHhDMSwgMHhEQSwgMHhENSwgMHg1OSwgMHhBNV1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwOCwgMHgwOSwgMHgwQSwgMHgwQiwgMHgwQywgMHgwRCwgMHgwRSwgMHgwRl0sIFsweDgzLCAweDI1LCAweDc5LCAweDA2LCAweDU0LCAweEE0LCAweDQ0LCAweEQ5XV1dO1xyXG4gICAgdGVzdHZlY3RvcnNbMV0gPSBbW1sweDAxXSwgWzB4RjIsIDB4QUIsIDB4MUMsIDB4OUUsIDB4NzAsIDB4N0QsIDB4Q0MsIDB4OTJdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDIsIDB4MDNdLCBbMHg2QiwgMHg0QywgMHg2NywgMHgyNCwgMHg5RiwgMHhCNywgMHg0RCwgMHhBQ11dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwMywgMHgwNCwgMHgwNV0sIFsweDY4LCAweDk1LCAweEFCLCAweEE4LCAweEVBLCAweDUzLCAweDEzLCAweDIzXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA0LCAweDA1LCAweDA2LCAweDA3XSwgWzB4QzgsIDB4REUsIDB4NjAsIDB4OEYsIDB4RjYsIDB4MDksIDB4OTAsIDB4QjVdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDUsIDB4MDYsIDB4MDcsIDB4MDgsIDB4MDldLCBbMHgxOSwgMHgxMywgMHg1MCwgMHgyMCwgMHg3MCwgMHg0MCwgMHgyRSwgMHgwOV1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNiwgMHgwNywgMHgwOCwgMHgwOSwgMHgwQSwgMHgwQl0sIFsweEE4LCAweDIzLCAweDQwLCAweEM2LCAweDE3LCAweEE2LCAweDMxLCAweDRBXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA3LCAweDA4LCAweDA5LCAweDBBLCAweDBCLCAweDBDLCAweDBEXSwgWzB4MzYsIDB4NjIsIDB4RjIsIDB4OTksIDB4NjgsIDB4RDQsIDB4QkYsIDB4N0NdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDgsIDB4MDksIDB4MEEsIDB4MEIsIDB4MEMsIDB4MEQsIDB4MEUsIDB4MEZdLCBbMHg4MywgMHgyNSwgMHg3OSwgMHgwNiwgMHg1NCwgMHhBNCwgMHg0NCwgMHhEOSwgMHgwOCwgMHg2RiwgMHg5QSwgMHgxRCwgMHg3NCwgMHhDOSwgMHg0RCwgMHg0RV1dXTtcclxuICAgIHRlc3R2ZWN0b3JzWzJdID0gW1tbMHgwMV0sIFsweDgzLCAweDY4LCAweEU0LCAweDlDLCAweDg0LCAweENDLCAweENCLCAweEYwXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDAyLCAweDAzXSwgWzB4QkIsIDB4QTgsIDB4MEIsIDB4NjYsIDB4MUIsIDB4NjIsIDB4QzQsIDB4QzhdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDMsIDB4MDQsIDB4MDVdLCBbMHg5QSwgMHhENywgMHg1QSwgMHgyNCwgMHhGRCwgMHgzRiwgMHhCRiwgMHgyMl1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNCwgMHgwNSwgMHgwNiwgMHgwN10sIFsweDE0LCAweDRFLCAweDY4LCAweDZELCAweDJFLCAweEMxLCAweEI3LCAweDUyXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA1LCAweDA2LCAweDA3LCAweDA4LCAweDA5XSwgWzB4MTIsIDB4MEEsIDB4NTEsIDB4MDgsIDB4RjksIDB4QTMsIDB4MDMsIDB4NzRdXSxcclxuXHQgICAgICAgICAgICAgICAgICBbWzB4MDYsIDB4MDcsIDB4MDgsIDB4MDksIDB4MEEsIDB4MEJdLCBbMHhCMiwgMHgwNywgMHhEMSwgMHgwNSwgMHhGNiwgMHg2NywgMHhBRiwgMHhCQV1dLFxyXG5cdCAgICAgICAgICAgICAgICAgIFtbMHgwNywgMHgwOCwgMHgwOSwgMHgwQSwgMHgwQiwgMHgwQywgMHgwRF0sIFsweENBLCAweDU5LCAweDYxLCAweDNBLCAweDgzLCAweDIzLCAweDI2LCAweEREXV0sXHJcblx0ICAgICAgICAgICAgICAgICAgW1sweDA4LCAweDA5LCAweDBBLCAweDBCLCAweDBDLCAweDBELCAweDBFLCAweDBGXSwgWzB4ODMsIDB4MjUsIDB4NzksIDB4MDYsIDB4NTQsIDB4QTQsIDB4NDQsIDB4RDldXV07XHJcblxyXG4gICAgdmFyIGRlcyA9IG5ldyBvcGVucGdwLmNpcGhlci5vcmlnaW5hbERlcyhrZXkpO1xyXG5cclxuICAgIHZhciByZXMgPSB0cnVlO1xyXG4gICAgdmFyIGogPSAwO1xyXG5cclxuICAgIGZvciAodmFyIHBhZGRpbmcgPSAwOyBwYWRkaW5nIDwgMzsgcGFkZGluZysrKSB7XHJcbiAgICAgICAgdmFyIHRoaXNWZWN0b3JTZXQgPSB0ZXN0dmVjdG9yc1twYWRkaW5nXTtcclxuXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzVmVjdG9yU2V0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBlbmNyeXB0ZWQgPSBkZXMuZW5jcnlwdCh0aGlzVmVjdG9yU2V0W2ldWzBdLCBwYWRkaW5nKTtcclxuICAgICAgICAgICAgdmFyIGRlY3J5cHRlZCA9IGRlcy5kZWNyeXB0KGVuY3J5cHRlZCwgcGFkZGluZyk7XHJcblxyXG4gICAgICAgICAgICB2YXIgcmVzMiA9ICh1dGlsLmJpbjJzdHIoZW5jcnlwdGVkKSA9PSB1dGlsLmJpbjJzdHIodGhpc1ZlY3RvclNldFtpXVsxXSkpO1xyXG4gICAgICAgICAgICB2YXIgcmVzMyA9ICh1dGlsLmJpbjJzdHIoZGVjcnlwdGVkKSA9PSB1dGlsLmJpbjJzdHIodGhpc1ZlY3RvclNldFtpXVswXSkpO1xyXG4gICAgICAgICAgICByZXMgJj0gcmVzMjtcclxuICAgICAgICAgICAgcmVzICY9IHJlczM7XHJcbiAgICAgICAgICAgIGlmICghcmVzMiB8fCAhcmVzMykge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFxyXG4gICAgICAgICAgICAgICAgICAgIFwiVGVzdGluZyB2ZWN0b3Igd2l0aCBibG9jayBbXCIgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB1dGlsLmhleGlkdW1wKHRoaXNWZWN0b3JTZXRbaV1bMF0pICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXCJdIGFuZCBrZXkgW1wiICsgdXRpbC5oZXhzdHJkdW1wKGtleSkgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBcIl0gYW5kIHBhZGRpbmcgW1wiICsgcGFkZGluZyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiXSBzaG91bGQgYmUgXCIgKyB1dGlsLmhleGlkdW1wKHRoaXNWZWN0b3JTZXRbaV1bMV0pICsgXCIgLSBBY3R1YWxseSBbRU5DOlwiICsgdXRpbC5oZXhpZHVtcChlbmNyeXB0ZWQpICsgXCIsIERFQzpcIiArIHV0aWwuaGV4aWR1bXAoZGVjcnlwdGVkKSArIFwiXVwiLFxyXG4gICAgICAgICAgICAgICAgICAgIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgIGorKztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChyZXMpIHtcclxuICAgICAgICByZXN1bHRbal0gPSBuZXcgdW5pdC5yZXN1bHQoXCJBbGwgREVTIHRlc3QgdmVjdG9ycyBjb21wbGV0ZWRcIiwgdHJ1ZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59KTtcclxuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi8uLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJUd29maXNoIHRlc3Qgd2l0aCB0ZXN0IHZlY3RvcnMgZnJvbSBodHRwOi8vd3d3LnNjaG5laWVyLmNvbS9jb2RlL2VjYl9pdmFsLnR4dFwiLCBmdW5jdGlvbigpIHtcbiAgdmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8uLi8nKSxcbiAgICB1dGlsID0gb3BlbnBncC51dGlsO1xuXG4gIGZ1bmN0aW9uIFRGZW5jcnlwdChibG9jaywga2V5KSB7XG4gICAgdmFyIHRmID0gbmV3IG9wZW5wZ3AuY2lwaGVyLnR3b2Zpc2goa2V5KTtcblxuICAgIHJldHVybiB0Zi5lbmNyeXB0KGJsb2NrKTtcbiAgfVxuXG5cbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIgc3RhcnQgPSBbMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwXTtcbiAgdmFyIHN0YXJ0X3Nob3J0ID0gWzAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDBdO1xuICB2YXIgdGVzdHZlY3RvcnMgPSBbWzB4NTcsMHhGRiwweDczLDB4OUQsMHg0RCwweEM5LDB4MkMsMHgxQiwweEQ3LDB4RkMsMHgwMSwweDcwLDB4MEMsMHhDOCwweDIxLDB4NkZdLFxuICAgICAgICAgICAgWzB4RDQsMHgzQiwweEI3LDB4NTUsMHg2RSwweEEzLDB4MkUsMHg0NiwweEYyLDB4QTIsMHg4MiwweEI3LDB4RDQsMHg1QiwweDRFLDB4MERdLFxuICAgICAgICAgICAgWzB4OTAsMHhBRiwweEU5LDB4MUIsMHhCMiwweDg4LDB4NTQsMHg0RiwweDJDLDB4MzIsMHhEQywweDIzLDB4OUIsMHgyNiwweDM1LDB4RTZdLFxuICAgICAgICAgICAgWzB4NkMsMHhCNCwweDU2LDB4MUMsMHg0MCwweEJGLDB4MEEsMHg5NywweDA1LDB4OTMsMHgxQywweEI2LDB4RDQsMHgwOCwweEU3LDB4RkFdLFxuICAgICAgICAgICAgWzB4MzAsMHg1OSwweEQ2LDB4RDYsMHgxNywweDUzLDB4QjksMHg1OCwweEQ5LDB4MkYsMHg0NywweDgxLDB4QzgsMHg2NCwweDBFLDB4NThdLFxuICAgICAgICAgICAgWzB4RTYsMHg5NCwweDY1LDB4NzcsMHgwNSwweDA1LDB4RDcsMHhGOCwweDBFLDB4RjYsMHg4QywweEEzLDB4OEEsMHhCMywweEEzLDB4RDZdLFxuICAgICAgICAgICAgWzB4NUEsMHhCNiwweDdBLDB4NUYsMHg4NSwweDM5LDB4QTQsMHhBNSwweEZELDB4OUYsMHgwMywweDczLDB4QkEsMHg0NiwweDM0LDB4NjZdLFxuICAgICAgICAgICAgWzB4REMsMHgwOSwweDZCLDB4Q0QsMHg5OSwweEZDLDB4NzIsMHhGNywweDk5LDB4MzYsMHhENCwweEM3LDB4NDgsMHhFNywweDVBLDB4RjddLFxuICAgICAgICAgICAgWzB4QzUsMHhBMywweEU3LDB4Q0UsMHhFMCwweEYxLDB4QjcsMHgyNiwweDA1LDB4MjgsMHhBNiwweDhGLDB4QjQsMHhFQSwweDA1LDB4RjJdLFxuICAgICAgICAgICAgWzB4NDMsMHhENSwweENFLDB4QzMsMHgyNywweEIyLDB4NEEsMHhCOSwweDBBLDB4RDMsMHg0QSwweDc5LDB4RDAsMHg0NiwweDkxLDB4NTFdXTtcbiAgdGVzdHZlY3RvcnNbNDddID0gIFsweDQzLDB4MTAsMHg1OCwweEY0LDB4REIsMHhDNywweEY3LDB4MzQsMHhEQSwweDRGLDB4MDIsMHhGMCwweDRDLDB4QzQsMHhGNCwweDU5XTtcbiAgdGVzdHZlY3RvcnNbNDhdID0gIFsweDM3LDB4RkUsMHgyNiwweEZGLDB4MUMsMHhGNiwweDYxLDB4NzUsMHhGNSwweERELDB4RjQsMHhDMywweDNCLDB4OTcsMHhBMiwweDA1XTtcbiAgdmFyIHJlcyA9IHRydWU7XG4gIHZhciBqID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OTsgaSsrKSB7XG4gICAgdmFyIHJlczIgPSBmYWxzZTtcbiAgICB2YXIgYmxrLCBrZXksIGN0O1xuICAgIGlmIChpID09PSAwKSB7XG4gICAgICBibGsgPSBzdGFydF9zaG9ydDtcbiAgICAgIGtleSA9IHV0aWwuYmluMnN0cihzdGFydCk7XG4gICAgICBjdCA9IHRlc3R2ZWN0b3JzWzBdO1xuICAgICAgcmVzMiA9ICh1dGlsLmJpbjJzdHIoVEZlbmNyeXB0KGJsayxrZXkpKSA9PSB1dGlsLmJpbjJzdHIoY3QpKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IDEpIHtcbiAgICAgIGJsayA9IHRlc3R2ZWN0b3JzWzBdO1xuICAgICAga2V5ID0gdXRpbC5iaW4yc3RyKHN0YXJ0KTtcbiAgICAgIGN0ID0gdGVzdHZlY3RvcnNbMV07XG4gICAgICByZXMyID0gKHV0aWwuYmluMnN0cihURmVuY3J5cHQoYmxrLGtleSkpID09IHV0aWwuYmluMnN0cihjdCkpO1xuICAgIH0gZWxzZSBpZiAoaSA9PT0gMikge1xuICAgICAgYmxrID0gdGVzdHZlY3RvcnNbaS0xXTtcbiAgICAgIGtleSA9IHV0aWwuYmluMnN0cih0ZXN0dmVjdG9yc1tpLTJdLmNvbmNhdChzdGFydF9zaG9ydCkpO1xuICAgICAgY3QgPSB0ZXN0dmVjdG9yc1tpXTtcbiAgICAgIHJlczIgPSAodXRpbC5iaW4yc3RyKFRGZW5jcnlwdChibGssa2V5KSkgPT0gdXRpbC5iaW4yc3RyKGN0KSk7XG4gICAgfSBlbHNlIGlmIChpIDwgMTAgfHwgaSA+IDQ2KSB7XG4gICAgICBibGsgPSB0ZXN0dmVjdG9yc1tpLTFdO1xuICAgICAga2V5ID0gdXRpbC5iaW4yc3RyKHRlc3R2ZWN0b3JzW2ktMl0uY29uY2F0KHRlc3R2ZWN0b3JzW2ktM10pKTtcbiAgICAgIGN0ID0gdGVzdHZlY3RvcnNbaV07XG4gICAgICByZXMyID0gKHV0aWwuYmluMnN0cihURmVuY3J5cHQoYmxrLGtleSkpID09IHV0aWwuYmluMnN0cihjdCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0ZXN0dmVjdG9yc1tpXSA9IFRGZW5jcnlwdCh0ZXN0dmVjdG9yc1tpLTFdLHV0aWwuYmluMnN0cih0ZXN0dmVjdG9yc1tpLTJdLmNvbmNhdCh0ZXN0dmVjdG9yc1tpLTNdKSkpO1xuICAgICAgcmVzMiA9IHRydWU7XG4gICAgfVxuICAgIHJlcyAmPSByZXMyO1xuICAgIGlmICghcmVzMikge1xuICAgICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyB2ZWN0b3Igd2l0aCBibG9jayBcIit1dGlsLmhleGlkdW1wKGJsaykrXCIgd2l0aCBrZXkgXCIrIHV0aWwuaGV4c3RyZHVtcChrZXkpICtcIiBzaG91bGQgYmUgXCIrdXRpbC5oZXhpZHVtcChjdCkrXCIgYnV0IGlzIFwiK3V0aWwuaGV4aWR1bXAoVEZlbmNyeXB0KGJsayxrZXkpKSwgZmFsc2UpO1xuICAgICAgaisrO1xuICAgIH1cbiAgfVxuICBpZiAocmVzKSB7XG4gICAgcmVzdWx0W2pdID0gbmV3IHVuaXQucmVzdWx0KFwiNDkgdGVzdCB2ZWN0b3JzIGNvbXBsZXRlZFwiLCB0cnVlKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uLy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIk1ENSB0ZXN0IHdpdGggdGVzdCB2ZWN0b3JzIGZyb20gUkZDIDEzMjFcIiwgZnVuY3Rpb24oKSB7XG5cdHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vLi4vJyksXG5cdFx0dXRpbCA9IG9wZW5wZ3AudXRpbCxcblx0XHRNRDUgPSBvcGVucGdwLmhhc2gubWQ1O1xuXG5cdHZhciByZXN1bHQgPSBuZXcgQXJyYXkoKTtcblx0cmVzdWx0WzBdID0gbmV3IHVuaXQucmVzdWx0KFwiTUQ1IChcXFwiXFxcIikgPSBkNDFkOGNkOThmMDBiMjA0ZTk4MDA5OThlY2Y4NDI3ZVwiLFxuXHRcdFx0dXRpbC5oZXhzdHJkdW1wKE1ENShcIlwiKSkgPT0gXCJkNDFkOGNkOThmMDBiMjA0ZTk4MDA5OThlY2Y4NDI3ZVwiKTtcblx0cmVzdWx0WzFdID0gbmV3IHVuaXQucmVzdWx0KFwiTUQ1IChcXFwiYVxcXCIpID0gMGNjMTc1YjljMGYxYjZhODMxYzM5OWUyNjk3NzI2NjFcIixcblx0XHRcdHV0aWwuaGV4c3RyZHVtcChNRDUgKFwiYWJjXCIpKSA9PSBcIjkwMDE1MDk4M2NkMjRmYjBkNjk2M2Y3ZDI4ZTE3ZjcyXCIpO1xuXHRyZXN1bHRbMl0gPSBuZXcgdW5pdC5yZXN1bHQoXCJNRDUgKFxcXCJtZXNzYWdlIGRpZ2VzdFxcXCIpID0gZjk2YjY5N2Q3Y2I3OTM4ZDUyNWEyZjMxYWFmMTYxZDBcIixcblx0XHRcdHV0aWwuaGV4c3RyZHVtcChNRDUgKFwibWVzc2FnZSBkaWdlc3RcIikpID09IFwiZjk2YjY5N2Q3Y2I3OTM4ZDUyNWEyZjMxYWFmMTYxZDBcIik7XG5cdHJlc3VsdFszXSA9IG5ldyB1bml0LnJlc3VsdChcIk1ENSAoXFxcImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6XFxcIikgPSBjM2ZjZDNkNzYxOTJlNDAwN2RmYjQ5NmNjYTY3ZTEzYlwiLFxuXHRcdFx0dXRpbC5oZXhzdHJkdW1wKE1ENSAoXCJhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elwiKSkgPT0gXCJjM2ZjZDNkNzYxOTJlNDAwN2RmYjQ5NmNjYTY3ZTEzYlwiKTtcblx0cmVzdWx0WzRdID0gbmV3IHVuaXQucmVzdWx0KFwiTUQ1IChcXFwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODlcXFwiKSA9IGQxNzRhYjk4ZDI3N2Q5ZjVhNTYxMWMyYzlmNDE5ZDlmXCIsXG5cdFx0XHR1dGlsLmhleHN0cmR1bXAoTUQ1IChcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5XCIpKSA9PSBcImQxNzRhYjk4ZDI3N2Q5ZjVhNTYxMWMyYzlmNDE5ZDlmXCIpO1xuXHRyZXN1bHRbNV0gPSBuZXcgdW5pdC5yZXN1bHQoXCJNRDUgKFxcXCIxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MFxcXCIpID0gNTdlZGY0YTIyYmUzYzk1NWFjNDlkYTJlMjEwN2I2N2FcIixcblx0XHRcdHV0aWwuaGV4c3RyZHVtcChNRDUgKFwiMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTBcIikpID09IFwiNTdlZGY0YTIyYmUzYzk1NWFjNDlkYTJlMjEwN2I2N2FcIik7XG5cdHJldHVybiByZXN1bHQ7XG59KTtcbiIsInZhciB1bml0ID0gcmVxdWlyZSgnLi4vLi4vdW5pdC5qcycpO1xuXG51bml0LnJlZ2lzdGVyKFwiUklQRS1NRCAxNjAgYml0cyB0ZXN0IHdpdGggdGVzdCB2ZWN0b3JzIGZyb20gaHR0cDovL2hvbWVzLmVzYXQua3VsZXV2ZW4uYmUvfmJvc3NlbGFlL3JpcGVtZDE2MC5odG1sXCIsIGZ1bmN0aW9uKCkge1xuXG5cdHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vLi4vJyksXG5cdFx0dXRpbCA9IG9wZW5wZ3AudXRpbCxcblx0XHRSTURzdHJpbmcgPSBvcGVucGdwLmhhc2gucmlwZW1kO1xuXG5cdHZhciByZXN1bHQgPSBuZXcgQXJyYXkoKTtcblx0cmVzdWx0WzBdID0gbmV3IHVuaXQucmVzdWx0KFwiUk1Ec3RyaW5nIChcXFwiXFxcIikgPSA5YzExODVhNWM1ZTlmYzU0NjEyODA4OTc3ZWU4ZjU0OGIyMjU4ZDMxXCIsXG5cdFx0XHR1dGlsLmhleHN0cmR1bXAoUk1Ec3RyaW5nKFwiXCIpKSA9PSBcIjljMTE4NWE1YzVlOWZjNTQ2MTI4MDg5NzdlZThmNTQ4YjIyNThkMzFcIik7XG5cdHJlc3VsdFsxXSA9IG5ldyB1bml0LnJlc3VsdChcIlJNRHN0cmluZyAoXFxcImFcXFwiKSA9IDBiZGM5ZDJkMjU2YjNlZTlkYWFlMzQ3YmU2ZjRkYzgzNWE0NjdmZmVcIixcblx0XHRcdHV0aWwuaGV4c3RyZHVtcChSTURzdHJpbmcoXCJhXCIpKSA9PSBcIjBiZGM5ZDJkMjU2YjNlZTlkYWFlMzQ3YmU2ZjRkYzgzNWE0NjdmZmVcIik7XG5cdHJlc3VsdFsyXSA9IG5ldyB1bml0LnJlc3VsdChcIlJNRHN0cmluZyAoXFxcImFiY1xcXCIpID0gOGViMjA4ZjdlMDVkOTg3YTliMDQ0YThlOThjNmIwODdmMTVhMGJmY1wiLFxuXHRcdFx0dXRpbC5oZXhzdHJkdW1wKFJNRHN0cmluZyhcImFiY1wiKSkgPT0gXCI4ZWIyMDhmN2UwNWQ5ODdhOWIwNDRhOGU5OGM2YjA4N2YxNWEwYmZjXCIpO1xuXHRyZXN1bHRbM10gPSBuZXcgdW5pdC5yZXN1bHQoXCJSTURzdHJpbmcgKFxcXCJtZXNzYWdlIGRpZ2VzdFxcXCIpID0gNWQwNjg5ZWY0OWQyZmFlNTcyYjg4MWIxMjNhODVmZmEyMTU5NWYzNlwiLFxuXHRcdFx0dXRpbC5oZXhzdHJkdW1wKFJNRHN0cmluZyhcIm1lc3NhZ2UgZGlnZXN0XCIpKSA9PSBcIjVkMDY4OWVmNDlkMmZhZTU3MmI4ODFiMTIzYTg1ZmZhMjE1OTVmMzZcIik7XG5cdHJldHVybiByZXN1bHQ7XG59KTtcbiIsInZhciB1bml0ID0gcmVxdWlyZSgnLi4vLi4vdW5pdC5qcycpO1xuXG5cbnVuaXQucmVnaXN0ZXIoXCJTSEEqIHRlc3Qgd2l0aCB0ZXN0IHZlY3RvcnMgZnJvbSBOSVNUIEZJUFMgMTgwLTJcIiwgZnVuY3Rpb24oKSB7XG5cdHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vLi4vJyksXG5cdFx0dXRpbCA9IG9wZW5wZ3AudXRpbCxcblx0XHRoYXNoID0gb3BlbnBncC5oYXNoO1xuXG5cdHZhciByZXN1bHQgPSBuZXcgQXJyYXkoKTtcblx0XG5cdHJlc3VsdFswXSA9IG5ldyB1bml0LnJlc3VsdChcIlNIQTEgLSBhOTk5M2UzNjQ3MDY4MTZhYmEzZTI1NzE3ODUwYzI2YzljZDBkODlkID0gaGFzaC5zaGExKFxcXCJhYmNcXFwiKSBcIixcblx0XHRcdFwiYTk5OTNlMzY0NzA2ODE2YWJhM2UyNTcxNzg1MGMyNmM5Y2QwZDg5ZFwiID09IHV0aWwuaGV4c3RyZHVtcChoYXNoLnNoYTEoXCJhYmNcIikpKTtcblx0cmVzdWx0WzFdID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBMSAtIDg0OTgzZTQ0MWMzYmQyNmViYWFlNGFhMWY5NTEyOWU1ZTU0NjcwZjEgPSBoYXNoLnNoYTEoXFxcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXFxcIikgXCIsXG5cdFx0XHRcIjg0OTgzZTQ0MWMzYmQyNmViYWFlNGFhMWY5NTEyOWU1ZTU0NjcwZjFcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGExKFwiYWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHFcIikpKTtcblx0cmVzdWx0WzJdID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBMjI0IC0gMjMwOTdkMjIzNDA1ZDgyMjg2NDJhNDc3YmRhMjU1YjMyYWFkYmNlNGJkYTBiM2Y3ZTM2YzlkYTcgPSBoYXNoLnNoYTIyNChcXFwiYWJjXFxcIikgXCIsXG5cdFx0XHRcIjIzMDk3ZDIyMzQwNWQ4MjI4NjQyYTQ3N2JkYTI1NWIzMmFhZGJjZTRiZGEwYjNmN2UzNmM5ZGE3XCIgPT0gdXRpbC5oZXhzdHJkdW1wKGhhc2guc2hhMjI0KFwiYWJjXCIpKSk7XG5cdHJlc3VsdFszXSA9IG5ldyB1bml0LnJlc3VsdChcIlNIQTIyNCAtIDc1Mzg4YjE2NTEyNzc2Y2M1ZGJhNWRhMWZkODkwMTUwYjBjNjQ1NWNiNGY1OGIxOTUyNTIyNTI1ID0gaGFzaC5zaGEyMjQoXFxcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXFxcIikgXCIsXG5cdFx0XHRcIjc1Mzg4YjE2NTEyNzc2Y2M1ZGJhNWRhMWZkODkwMTUwYjBjNjQ1NWNiNGY1OGIxOTUyNTIyNTI1XCIgPT0gdXRpbC5oZXhzdHJkdW1wKGhhc2guc2hhMjI0KFwiYWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHFcIikpKTtcblx0cmVzdWx0WzRdID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBMjU2IC0gYmE3ODE2YmY4ZjAxY2ZlYTQxNDE0MGRlNWRhZTIyMjNiMDAzNjFhMzk2MTc3YTljYjQxMGZmNjFmMjAwMTVhZCA9IGhhc2guc2hhMjU2KFxcXCJhYmNcXFwiKSBcIixcblx0XHRcdFwiYmE3ODE2YmY4ZjAxY2ZlYTQxNDE0MGRlNWRhZTIyMjNiMDAzNjFhMzk2MTc3YTljYjQxMGZmNjFmMjAwMTVhZFwiID09IHV0aWwuaGV4c3RyZHVtcChoYXNoLnNoYTI1NihcImFiY1wiKSkpO1xuXHRyZXN1bHRbNV0gPSBuZXcgdW5pdC5yZXN1bHQoXCJTSEEyNTYgLSAyNDhkNmE2MWQyMDYzOGI4ZTVjMDI2OTMwYzNlNjAzOWEzM2NlNDU5NjRmZjIxNjdmNmVjZWRkNDE5ZGIwNmMxID0gaGFzaC5zaGEyNTYoXFxcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXFxcIikgXCIsXG5cdFx0XHRcIjI0OGQ2YTYxZDIwNjM4YjhlNWMwMjY5MzBjM2U2MDM5YTMzY2U0NTk2NGZmMjE2N2Y2ZWNlZGQ0MTlkYjA2YzFcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGEyNTYoXCJhYmNkYmNkZWNkZWZkZWZnZWZnaGZnaGlnaGlqaGlqa2lqa2xqa2xta2xtbmxtbm9tbm9wbm9wcVwiKSkpO1xuXHRyZXN1bHRbNl0gPSBuZXcgdW5pdC5yZXN1bHQoXCJTSEEzODQgLSBjYjAwNzUzZjQ1YTM1ZThiYjVhMDNkNjk5YWM2NTAwNzI3MmMzMmFiMGVkZWQxNjMxYThiNjA1YTQzZmY1YmVkODA4NjA3MmJhMWU3Y2MyMzU4YmFlY2ExMzRjODI1YTcgPSBoYXNoLnNoYTM4NChcXFwiYWJjXFxcIikgXCIsXG5cdFx0XHRcImNiMDA3NTNmNDVhMzVlOGJiNWEwM2Q2OTlhYzY1MDA3MjcyYzMyYWIwZWRlZDE2MzFhOGI2MDVhNDNmZjViZWQ4MDg2MDcyYmExZTdjYzIzNThiYWVjYTEzNGM4MjVhN1wiID09IHV0aWwuaGV4c3RyZHVtcChoYXNoLnNoYTM4NChcImFiY1wiKSkpO1xuXHRyZXN1bHRbN10gPSBuZXcgdW5pdC5yZXN1bHQoXCJTSEEzODQgLSAzMzkxZmRkZGZjOGRjNzM5MzcwN2E2NWIxYjQ3MDkzOTdjZjhiMWQxNjJhZjA1YWJmZThmNDUwZGU1ZjM2YmM2YjA0NTVhODUyMGJjNGU2ZjVmZTk1YjFmZTNjODQ1MmIgPSBzdHIzODQoXFxcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXFxcIikgXCIsXG5cdFx0XHRcIjMzOTFmZGRkZmM4ZGM3MzkzNzA3YTY1YjFiNDcwOTM5N2NmOGIxZDE2MmFmMDVhYmZlOGY0NTBkZTVmMzZiYzZiMDQ1NWE4NTIwYmM0ZTZmNWZlOTViMWZlM2M4NDUyYlwiID09IHV0aWwuaGV4c3RyZHVtcChoYXNoLnNoYTM4NChcImFiY2RiY2RlY2RlZmRlZmdlZmdoZmdoaWdoaWpoaWpraWprbGprbG1rbG1ubG1ub21ub3Bub3BxXCIpKSk7XHRcdFx0XHRcdFxuXHRyZXN1bHRbOF0gPSBuZXcgdW5pdC5yZXN1bHQoXCJTSEE1MTIgLSBkZGFmMzVhMTkzNjE3YWJhY2M0MTczNDlhZTIwNDEzMTEyZTZmYTRlODlhOTdlYTIwYTllZWVlNjRiNTVkMzlhMjE5Mjk5MmEyNzRmYzFhODM2YmEzYzIzYTNmZWViYmQ0NTRkNDQyMzY0M2NlODBlMmE5YWM5NGZhNTRjYTQ5ZiA9IGhhc2guc2hhNTEyKFxcXCJhYmNcXFwiKSBcIixcblx0XHRcdFwiZGRhZjM1YTE5MzYxN2FiYWNjNDE3MzQ5YWUyMDQxMzExMmU2ZmE0ZTg5YTk3ZWEyMGE5ZWVlZTY0YjU1ZDM5YTIxOTI5OTJhMjc0ZmMxYTgzNmJhM2MyM2EzZmVlYmJkNDU0ZDQ0MjM2NDNjZTgwZTJhOWFjOTRmYTU0Y2E0OWZcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGE1MTIoXCJhYmNcIikpKTtcblx0cmVzdWx0WzldID0gbmV3IHVuaXQucmVzdWx0KFwiU0hBNTEyIC0gMjA0YThmYzZkZGE4MmYwYTBjZWQ3YmViOGUwOGE0MTY1N2MxNmVmNDY4YjIyOGE4Mjc5YmUzMzFhNzAzYzMzNTk2ZmQxNWMxM2IxYjA3ZjlhYTFkM2JlYTU3Nzg5Y2EwMzFhZDg1YzdhNzFkZDcwMzU0ZWM2MzEyMzhjYTM0NDUgPSBoYXNoLnNoYTUxMihcXFwiYWJjZGJjZGVjZGVmZGVmZ2VmZ2hmZ2hpZ2hpamhpamtpamtsamtsbWtsbW5sbW5vbW5vcG5vcHFcXFwiKSBcIixcblx0XHRcdFwiMjA0YThmYzZkZGE4MmYwYTBjZWQ3YmViOGUwOGE0MTY1N2MxNmVmNDY4YjIyOGE4Mjc5YmUzMzFhNzAzYzMzNTk2ZmQxNWMxM2IxYjA3ZjlhYTFkM2JlYTU3Nzg5Y2EwMzFhZDg1YzdhNzFkZDcwMzU0ZWM2MzEyMzhjYTM0NDVcIiA9PSB1dGlsLmhleHN0cmR1bXAoaGFzaC5zaGE1MTIoXCJhYmNkYmNkZWNkZWZkZWZnZWZnaGZnaGlnaGlqaGlqa2lqa2xqa2xta2xtbmxtbm9tbm9wbm9wcVwiKSkpO1x0XHRcdFx0XHRcblx0cmV0dXJuIHJlc3VsdDtcbn0pO1xuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJGdW5jdGlvbmFsIHRlc3Rpbmcgb2Ygb3BlbnBncC5jcnlwdG8uKiBtZXRob2RzXCIsIGZ1bmN0aW9uKCkge1xuXHR2YXIgb3BlbnBncCA9IHJlcXVpcmUoJy4uLy4uLycpO1xuICB2YXIgdXRpbCA9IG9wZW5wZ3AudXRpbDtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIgUlNBcHViTVBJc3RycyA9IFtcbiAgICAgICAgICAgICAgdXRpbC5iaW4yc3RyKFsweDA4LDB4MDAsMHhhYywweDE1LDB4YjMsMHhkNiwweGQyLDB4MGYsMHhmMCwweDdhLDB4ZGQsMHgyMSwweGI3LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4YmYsMHg2MSwweGZhLDB4Y2EsMHg5MywweDg2LDB4YzgsMHg1NSwweDVhLDB4NGIsMHhhNiwweGE0LDB4MWEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg2MCwweGEyLDB4M2EsMHgzNywweDA2LDB4MDgsMHhkOCwweDE1LDB4OGUsMHg4NSwweDQ1LDB4YWEsMHhiNyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDFkLDB4N2IsMHgwYiwweDczLDB4OTQsMHg1NSwweDBjLDB4NWMsMHhlYywweGMwLDB4MjIsMHg0YiwweGExLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NjQsMHgyMCwweDdkLDB4NGQsMHhhOCwweDk2LDB4MWEsMHg2NCwweDM4LDB4OTMsMHhjZCwweGVjLDB4NzMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg1ZCwweGY5LDB4ODksMHg4OCwweDI0LDB4M2QsMHg0OCwweGZmLDB4M2IsMHg4NywweDYyLDB4ZDAsMHg4NCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGVhLDB4ZmYsMHgzOSwweGI1LDB4MjcsMHg3MCwweGVhLDB4NGEsMHhiMiwweDJlLDB4OWQsMHhmMSwweDdjLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjMsMHhlYywweGY0LDB4NWUsMHhlYSwweDYxLDB4M2QsMHhlNSwweGQ4LDB4MGQsMHhmOSwweDU5LDB4NmQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgyOCwweDAwLDB4ZWIsMHhjYiwweGM5LDB4NTUsMHgwMCwweDcyLDB4MzAsMHgxZiwweDY1LDB4OWQsMHhkNixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE3LDB4NTgsMHg1ZiwweGE2LDB4NGEsMHhhMCwweGRkLDB4ZTEsMHg3NiwweGYyLDB4ZWYsMHgyMSwweDlmLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODQsMHhmYywweGFhLDB4NWIsMHg1MiwweDZlLDB4YzEsMHhhMiwweGI5LDB4YmQsMHhiOSwweGY0LDB4OWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0OSwweDkyLDB4ZjIsMHhhZiwweDU3LDB4ODYsMHhmMiwweGVmLDB4NzAsMHhiZiwweDUxLDB4NDAsMHhmZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGJmLDB4NTYsMHg1MSwweGU4LDB4MmMsMHhhMiwweDRmLDB4ZjgsMHhhNCwweGQ3LDB4MzYsMHgxOCwweDg1LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4Y2UsMHgwOSwweDBkLDB4YmMsMHg4ZCwweDY1LDB4NWUsMHg4YSwweDFkLDB4OTgsMHhiMCwweDRkLDB4OWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhjMSwweGNmLDB4ODIsMHhlMSwweGI3LDB4NDMsMHg1ZCwweDVhLDB4NzIsMHhjZCwweDU1LDB4ZDIsMHhmZixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGIxLDB4YjQsMHg3OCwweGJmLDB4YTEsMHg3ZCwweGFjLDB4ZDksMHgxYiwweGM0LDB4ZmEsMHgzOSwweDM0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OTIsMHgwOSwweGY5LDB4MDgsMHgyYSwweDZiLDB4OWQsMHgxNCwweDU2LDB4MTIsMHg0YywweGU5LDB4YTYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgyOSwweGMxLDB4ZjMsMHhhOSwweDBiLDB4ZmMsMHgzMSwweDc1LDB4NTgsMHg3NCwweDJhLDB4ODgsMHhhZixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGVlLDB4YzksMHhhNCwweGNkLDB4MTUsMHhkYywweDFiLDB4OGQsMHg2NCwweGMxLDB4MzYsMHgxNywweGM0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OGQsMHg1ZSwweDk5LDB4N2EsMHg1YiwweDlmLDB4MzksMHhkMCwweDAwLDB4NmUsMHhmOV0pLFxuICAgICAgICAgICAgICB1dGlsLmJpbjJzdHIoWzB4MDAsMHgxMSwweDAxLDB4MDAsMHgwMV0pXTtcbiAgdmFyIFJTQXNlY01QSXN0cnMgPSBbXG4gICAgICAgICAgICAgIHV0aWwuYmluMnN0cihbMHgwNywweGZlLDB4MjMsMHhmZiwweGNlLDB4NDUsMHg2YywweDYwLDB4NjUsMHg0MCwweDZlLDB4YWUsMHgzNSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDEwLDB4NTYsMHg2MCwweGVlLDB4YWIsMHhmYSwweDEwLDB4NDIsMHhiYSwweGM3LDB4MDQsMHhhZiwweDYzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4Y2QsMHgzZiwweDYyLDB4Y2EsMHg0YiwweGZhLDB4ZTEsMHhhOSwweDcwLDB4Y2QsMHgzNCwweDhiLDB4YzgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwZSwweGU0LDB4YzQsMHhiYSwweDgzLDB4MTcsMHg1ZiwweGE0LDB4YjgsMHhlYSwweDYwLDB4YzIsMHg0ZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDlhLDB4ZjIsMHhhOSwweDAzLDB4ZWIsMHhmNiwweGFhLDB4YzIsMHhiOCwweDhiLDB4NDMsMHgxMiwweGU5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZjcsMHg4OCwweGQyLDB4NWEsMHhhNiwweGFhLDB4MjMsMHg3MSwweDMxLDB4NzQsMHhkYiwweDE5LDB4MjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNSwweDQxLDB4MWIsMHg0MywweDY4LDB4NjIsMHhkOCwweGMwLDB4OTMsMHg5MSwweGU4LDB4ZmMsMHhiMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGE5LDB4OWEsMHg1MiwweDZjLDB4ZTAsMHhiZiwweDQzLDB4MDEsMHhhOCwweDM3LDB4MTQsMHgyOCwweGJmLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MGIsMHgxNSwweDU2LDB4M2UsMHhhNSwweDc5LDB4YTAsMHhjNCwweDQyLDB4ODgsMHhlZSwweGViLDB4MWIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhmNCwweDdhLDB4NGEsMHg1OCwweDMxLDB4NTgsMHg4MSwweGQyLDB4M2UsMHhkZSwweDA3LDB4NjQsMHg5MixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGYwLDB4NjAsMHhkMywweDlhLDB4MjksMHhjYSwweGM2LDB4NjcsMHg3NSwweDA3LDB4Y2EsMHg5MiwweDM5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NTYsMHhmNiwweDExLDB4ODQsMHhiYSwweDZkLDB4NGIsMHhlNiwweDZmLDB4NjYsMHhjMiwweDE3LDB4ZWIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0NiwweDY5LDB4MWMsMHhiYiwweGRmLDB4YzAsMHgzOCwweDAwLDB4ZDYsMHgwMSwweGU2LDB4NzAsMHg5ZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDRiLDB4OWIsMHg3MCwweGVkLDB4NWMsMHhiOCwweGNmLDB4ZTgsMHg2OCwweDcxLDB4YmUsMHgyNCwweDZkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4YjEsMHhhMywweDEzLDB4Y2MsMHhmMSwweGJjLDB4NjcsMHhkYywweGUwLDB4NjksMHgwOSwweDgyLDB4M2MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgzYiwweDBmLDB4MTQsMHg5OCwweDQ4LDB4MzAsMHhiMiwweDcwLDB4YzYsMHg5ZSwweGZhLDB4NDYsMHg4ZixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGYxLDB4YzAsMHg2NSwweDhlLDB4YzYsMHhhZSwweGRjLDB4NDcsMHg5MSwweDEzLDB4MWUsMHhkNiwweDRhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZjIsMHhhZCwweGRhLDB4YzIsMHhjNywweDM5LDB4NzgsMHg5OSwweGRlLDB4NTcsMHgxNCwweDQ1LDB4N2YsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgzMiwweDM4LDB4YTMsMHg0NCwweDBmLDB4ZTcsMHgzOSwweDRjLDB4NmYsMHgwZiwweDMyLDB4N2UsMHhmMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDVjLDB4ODQsMHg5NywweGRkLDB4YTAsMHgwYywweDg3LDB4NjYsMHg3ZCwweDc1LDB4NzldKSxcbiAgICAgICAgICAgICAgdXRpbC5iaW4yc3RyKFsweDA0LDB4MDAsMHhjMiwweGJjLDB4NzEsMHhmNywweDQxLDB4NGEsMHgwOSwweDY2LDB4NzAsMHgwMiwweDY4LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OGIsMHhlYiwweGUyLDB4MzQsMHhkMSwweDEyLDB4ODMsMHg5MywweDc1LDB4ZTksMHg3MSwweDMyLDB4ZTIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhlZCwweDE4LDB4NmYsMHg4ZSwweDNhLDB4ZmYsMHgyMiwweDcwLDB4MjgsMHgwMSwweGJmLDB4NGEsMHgzOSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDQxLDB4YmIsMHgzYywweDRhLDB4YmMsMHhiOCwweDEzLDB4ZmMsMHgxNCwweGY2LDB4NzEsMHhhMSwweDQ0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MWMsMHgwMiwweGExLDB4NzMsMHg4MSwweGNjLDB4YTAsMHgzNSwweDAyLDB4M2UsMHg5NywweGI1LDB4YzQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg5NCwweDMzLDB4ZjEsMHhkMSwweGRmLDB4MTQsMHgzZiwweGZiLDB4OGYsMHhiOSwweDc1LDB4NzAsMHhkYyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDc0LDB4M2YsMHgwNywweDM1LDB4OGYsMHg1MywweGFhLDB4YjIsMHhkNiwweDg4LDB4NTEsMHg3MSwweDRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDEsMHgyNCwweGVjLDB4N2QsMHhjYSwweGY2LDB4YTIsMHhiMywweGJiLDB4YWQsMHgyZSwweDYwLDB4ZmIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxYywweGVlLDB4NDksMHhkMCwweDRlLDB4NWMsMHhlMywweDFmLDB4ODgsMHg0OCwweGU0LDB4NjgsMHgxNCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDNkLDB4NzEsMHhiYSwweGQ3LDB4NGQsMHgzNSwweDEwLDB4ODYsMHgzNywweDYyLDB4ZTAsMHhhNSwweDBiXSksXG4gICAgICAgICAgICAgIHV0aWwuYmluMnN0cihbMHgwNCwweDAwLDB4ZTIsMHgzOCwweGY5LDB4YzgsMHgzYywweGQxLDB4Y2YsMHg2MiwweDkzLDB4YzMsMHg3NyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDc2LDB4OTcsMHg0NCwweGU4LDB4YzgsMHhjYSwweDkzLDB4OWEsMHhlZiwweGYwLDB4NjMsMHg3NiwweDI1LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4M2IsMHgxYywweDQ2LDB4ZmYsMHg5MCwweDEzLDB4OTEsMHgxNSwweDk3LDB4N2UsMHg4OCwweDk1LDB4ZDQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg3ZiwweDJmLDB4NTIsMHg2ZSwweDBkLDB4NTUsMHg1NSwweDJlLDB4ZjEsMHg1OCwweDVjLDB4N2UsMHg1NixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGQ0LDB4NDgsMHhhYSwweGRiLDB4OGMsMHg0NCwweDRkLDB4ODQsMHg2OSwweDMzLDB4ODcsMHgwNywweGIyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4N2UsMHhmNSwweGEwLDB4NjAsMHhmYiwweDczLDB4NTksMHg0NiwweDI5LDB4Y2IsMHgxZSwweDNmLDB4N2MsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgyZiwweGE2LDB4NTMsMHhlMywweDhjLDB4ZWYsMHhkNSwweGViLDB4YmIsMHhjOCwweDlhLDB4OGUsMHg2NixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDRhLDB4NDcsMHgyZiwweGUxLDB4YmEsMHg1ZSwweDMyLDB4ZDQsMHg1MiwweDA0LDB4ODgsMHg5ZCwweDYzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4M2UsMHhiYSwweDcxLDB4MmQsMHhmNywweDYxLDB4ZDUsMHhmYywweDI2LDB4YmYsMHhkOCwweDYwLDB4OTIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg3YiwweDk0LDB4ZjgsMHg2ZiwweDNkLDB4OTcsMHgwYiwweDBjLDB4NTIsMHg4YywweGIzLDB4YjYsMHg4Yl0pLFxuICAgICAgICAgICAgICB1dGlsLmJpbjJzdHIoWzB4MDQsMHgwMCwweGI3LDB4YzUsMHg0ZCwweDZlLDB4MmYsMHhkZCwweGVmLDB4ZWMsMHgwNywweDcwLDB4YTIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg3YywweDFjLDB4OWQsMHg4ZSwweDY2LDB4NjAsMHg3YywweDYxLDB4MWUsMHg0NSwweGU5LDB4ZGMsMHg4MixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDJmLDB4YzUsMHg3ZSwweDFhLDB4YzYsMHhkMCwweDkyLDB4YzUsMHgyMiwweDliLDB4OWEsMHhmYiwweDczLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4OTUsMHg5OSwweGYyLDB4N2MsMHhkYiwweDJhLDB4OTMsMHg3YiwweDVhLDB4MjksMHg3MywweDI0LDB4MTYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MSwweDQ5LDB4YjUsMHhmMiwweDVmLDB4YmUsMHhlNywweDY0LDB4NGQsMHhkYSwweDUyLDB4OWUsMHhjMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDQxLDB4NDAsMHg1ZSwweDAzLDB4OTIsMHg4ZCwweDM5LDB4OTUsMHgxZiwweDY4LDB4OWYsMHgwMCwweDJlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MGMsMHg2ZiwweGNmLDB4ZDksMHg2ZCwweDY4LDB4ZjcsMHgwMCwweDRmLDB4MGUsMHhjOCwweDBiLDB4ZmEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg1MSwweGUwLDB4MjIsMHhmMCwweGZmLDB4YTcsMHg0MiwweGQ0LDB4ZGUsMHgwYiwweDQ3LDB4OGYsMHgyYixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAweGY1LDB4NGQsMHgwNCwweDMyLDB4OTEsMHg4OSwweDRiLDB4MGUsMHgwNSwweDhkLDB4NzAsMHhmOSwweGJiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ZTcsMHhkNiwweDc2LDB4ZWEsMHgwZSwweDFhLDB4OTAsMHgzMCwweGY1LDB4OTgsMHgwMSwweGM1LDB4NzNdKV07XG4gIFxuICB2YXIgRFNBcHViTVBJc3RycyA9IFtcbiAgICAgICAgICB1dGlsLmJpbjJzdHIoWzB4MDgsMHgwMCwweGE4LDB4ODUsMHg1YywweDI4LDB4MDUsMHg5NCwweDAzLDB4YmUsMHgwNywweDZjLDB4MTMsMHgzZSwweDY1LFxuICAgICAgICAgICAgICAgICAgICAgICAgMHhmYiwweGI1LDB4ZTEsMHg5OSwweDdjLDB4ZmEsMHg4NCwweGUzLDB4YWMsMHg0NywweGE1LDB4YzQsMHg0NiwweGQ4LDB4NWYsXG4gICAgICAgICAgICAgICAgICAgICAgICAweDQ0LDB4ZTksMHhjMSwweDZiLDB4NjksMHhmNywweDEwLDB4NzYsMHg0OSwweGE3LDB4MjUsMHg4NSwweGY0LDB4MWIsMHhlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4YzYsMHg2MCwweGM0LDB4NWIsMHhhYSwweGQ0LDB4ODcsMHhkNiwweDhmLDB4OTIsMHg1NiwweDdkLDB4NTUsMHgzZiwweDQ1LFxuICAgICAgICAgICAgICAgICAgICAgICAgMHhhZSwweDEyLDB4NzMsMHhkYSwweDI5LDB4OGMsMHhiYSwweDMyLDB4Y2MsMHhkNywweGE0LDB4ZDAsMHgyNCwweGIwLDB4N2MsXG4gICAgICAgICAgICAgICAgICAgICAgICAweGQ4LDB4MGMsMHgzYSwweDkxLDB4NmYsMHg5OCwweDQwLDB4OWMsMHg5YSwweGE4LDB4Y2MsMHgyOCwweDI3LDB4OTUsMHgwYixcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4ZTEsMHg1YiwweGI5LDB4M2IsMHgxYywweDFjLDB4ZDIsMHhlYywweGFiLDB4MDcsMHgyNSwweDhkLDB4N2EsMHgyYSwweDJiLFxuICAgICAgICAgICAgICAgICAgICAgICAgMHgxNiwweDE0LDB4ZTgsMHhkYSwweDcxLDB4ZDIsMHhhYiwweGJhLDB4ODUsMHgxNCwweDBkLDB4YzUsMHhlMCwweDg4LDB4ZWIsXG4gICAgICAgICAgICAgICAgICAgICAgICAweGE1LDB4ZTIsMHhkNSwweDQ4LDB4M2QsMHg3NCwweDBjLDB4NDEsMHhlYiwweGZkLDB4YjYsMHg0ZSwweGY5LDB4MmMsMHg4MixcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4MTcsMHhkZCwweDY0LDB4MWUsMHgxOSwweDM5LDB4YTMsMHg3ZiwweGY5LDB4MDAsMHhjZCwweDliLDB4ZGEsMHgyZSwweGJkLFxuICAgICAgICAgICAgICAgICAgICAgICAgMHg3MSwweDEyLDB4ZGYsMHgwZCwweDdjLDB4MGEsMHg2YiwweDJkLDB4MjEsMHgzYiwweDljLDB4NjYsMHg5MywweDRhLDB4MWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAweDkwLDB4NzksMHhkMywweDVhLDB4NWIsMHhlNSwweGI5LDB4OTQsMHgxYiwweGU2LDB4NDcsMHg5OSwweDA2LDB4OTgsMHhkOCxcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4MmEsMHhlNSwweGUyLDB4YTYsMHg5NSwweDZhLDB4MDcsMHhjOCwweGFjLDB4N2MsMHhlOSwweGZjLDB4YTIsMHg2YSwweDE2LFxuICAgICAgICAgICAgICAgICAgICAgICAgMHgyYywweDk0LDB4OTgsMHhiZCwweDkxLDB4MGEsMHg3YywweDdjLDB4MmMsMHhiOSwweDdlLDB4YTIsMHg1MSwweDhiLDB4NDUsXG4gICAgICAgICAgICAgICAgICAgICAgICAweDFkLDB4NDYsMHgzNCwweGE4LDB4NTIsMHgyYiwweGRkLDB4ZDksMHhhOCwweGJjLDB4NDYsMHg3OCwweDY2LDB4ZTEsMHg3MixcbiAgICAgICAgICAgICAgICAgICAgICAgIDB4MTEsMHhmMSwweGNiLDB4MWEsMHhiNiwweDRlLDB4MDUsMHg1NCwweGY3LDB4ZTksMHhiZSwweDRjLDB4MjUsMHg1OSwweDA4LFxuICAgICAgICAgICAgICAgICAgICAgICAgMHg5ZiwweGY4LDB4ZWEsMHgyNSwweDk3LDB4MzMsMHhkNiwweGM5LDB4MGYsMHg1OSwweDBlLDB4ZmQsMHg5ZiwweGRjLDB4ZTIsXG4gICAgICAgICAgICAgICAgICAgICAgICAweGMwLDB4Y2YsMHgyZl0pLFxuICAgICAgdXRpbC5iaW4yc3RyKFsweDAxLDB4MDAsMHhlMSwweDcyLDB4MmMsMHhkMCwweGJiLDB4MWEsMHg0ZiwweGI2LDB4YjYsMHg5NSwweDc3LDB4NzEsMHgyZSxcbiAgICAgICAgICAgICAgICAgICAgMHgwMSwweDQ4LDB4M2UsMHgzNSwweDU0LDB4NjQsMHgyYiwweGVkLDB4NDAsMHg1ZiwweDY1LDB4MGMsMHg1NywweDI4LDB4NWYsXG4gICAgICAgICAgICAgICAgICAgIDB4ZmQsMHhmZCwweGZmLDB4ZDddKSxcbiAgICAgIHV0aWwuYmluMnN0cihbMHgwNywweGZmLDB4NWQsMHg5ZiwweGM0LDB4YjUsMHg2MywweDI1LDB4OWQsMHg3MiwweDg4LDB4ZTUsMHg1MywweDQ2LDB4OTgsXG4gICAgICAgICAgICAgICAgICAgIDB4ZTMsMHhlOSwweDYyLDB4Y2IsMHgwYywweGExLDB4YjcsMHg3NSwweDlmLDB4MTgsMHg0MSwweDk0LDB4MzIsMHgyOCwweDI5LFxuICAgICAgICAgICAgICAgICAgICAweDZkLDB4NjksMHhlMCwweDNmLDB4N2QsMHg3YiwweDJiLDB4MDYsMHg1YSwweDMzLDB4NWMsMHhkNCwweDM2LDB4MzEsMHgwOSxcbiAgICAgICAgICAgICAgICAgICAgMHg1NCwweDg1LDB4OWQsMHhiOCwweDIwLDB4ZmUsMHhkYSwweGZjLDB4Y2QsMHgxZiwweGIxLDB4MmMsMHgxNSwweDA4LDB4OWQsXG4gICAgICAgICAgICAgICAgICAgIDB4MzIsMHg1MywweDJmLDB4YzEsMHg0MiwweDIyLDB4NjksMHhmZiwweDY3LDB4MmUsMHgzOSwweDk3LDB4NTAsMHg2NiwweDM5LFxuICAgICAgICAgICAgICAgICAgICAweGRhLDB4Y2YsMHhmZCwweDY0LDB4NmYsMHg5MSwweDA1LDB4NjQsMHgzNywweGM1LDB4MDcsMHgyNCwweGFhLDB4NDAsMHhhMCxcbiAgICAgICAgICAgICAgICAgICAgMHg3NSwweDgyLDB4MWQsMHg5NywweDk2LDB4MTIsMHhmMSwweGJkLDB4OWUsMHgwOSwweDI2LDB4M2MsMHg5NywweDVkLDB4NTcsXG4gICAgICAgICAgICAgICAgICAgIDB4YjgsMHg1YywweDdkLDB4ODksMHgwMywweDgyLDB4Y2QsMHg0MCwweGU1LDB4MDMsMHhlNiwweDRhLDB4ZmIsMHhiYywweGQyLFxuICAgICAgICAgICAgICAgICAgICAweGVmLDB4N2EsMHg4OSwweDAyLDB4MDgsMHhjOCwweDUyLDB4ZmEsMHg5NywweDc0LDB4NjYsMHgzMiwweGFlLDB4YTYsMHg1MixcbiAgICAgICAgICAgICAgICAgICAgMHg0YiwweGVmLDB4NWYsMHhjZSwweDkxLDB4MjMsMHgzZiwweGFiLDB4OWQsMHg2MiwweDIxLDB4ZWYsMHg0OCwweDZkLDB4MDcsXG4gICAgICAgICAgICAgICAgICAgIDB4NWEsMHhiYSwweGRmLDB4MDAsMHg5MSwweDU0LDB4ZWEsMHg1YywweGZhLDB4NGIsMHgxNiwweDI4LDB4MWEsMHhjZSwweDQ4LFxuICAgICAgICAgICAgICAgICAgICAweGI3LDB4NWMsMHg1MCwweGE1LDB4NTksMHhhNCwweGI0LDB4YWYsMHgxZiwweGViLDB4OGQsMHg1OCwweDNmLDB4MGEsMHhhNSxcbiAgICAgICAgICAgICAgICAgICAgMHg5NywweDJiLDB4NTEsMHg1NiwweGU4LDB4ODgsMHhmNiwweDA3LDB4YmMsMHhkZiwweGZhLDB4MmIsMHg3YiwweDg4LDB4ZTAsXG4gICAgICAgICAgICAgICAgICAgIDB4NDYsMHhjOCwweDdhLDB4M2UsMHhkOCwweDgwLDB4ZGIsMHg0ZCwweDg3LDB4NjEsMHg0ZiwweDY0LDB4Y2QsMHhlYiwweGU4LFxuICAgICAgICAgICAgICAgICAgICAweDBkLDB4ODYsMHgxNiwweGNjLDB4ZGQsMHg2YywweDc2LDB4NjYsMHhjMSwweDczLDB4YjcsMHgwOCwweDk4LDB4ODksMHgyZixcbiAgICAgICAgICAgICAgICAgICAgMHg2NywweDY5LDB4ZDEsMHhmYywweDk3LDB4NGQsMHhhMiwweGNlLDB4YWQsMHhiYiwweDZmLDB4YWIsMHhhNSwweGQ2LDB4MTgsXG4gICAgICAgICAgICAgICAgICAgIDB4YjMsMHgxYSwweDk2LDB4MDIsMHhiYywweDMxLDB4NDIsMHhhMiwweGFkLDB4NzcsMHhlOCwweGUyLDB4NGMsMHg5OSwweGY5LFxuICAgICAgICAgICAgICAgICAgICAweGRkLDB4YmUsMHhjZF0pLFxuICAgICAgdXRpbC5iaW4yc3RyKFsweDA3LDB4ZmYsMHg1ZCwweGZlLDB4OWMsMHg5OCwweGVmLDB4M2EsMHhhNiwweDQ5LDB4ZjAsMHgxMCwweDY3LDB4NzksMHgyYSxcbiAgICAgICAgICAgICAgICAgICAgMHg5ZCwweDc5LDB4NDMsMHgwNiwweGE0LDB4YTgsMHg2YiwweDFhLDB4NmQsMHgxZiwweDc3LDB4NmUsMHgwMCwweDMxLDB4YjksXG4gICAgICAgICAgICAgICAgICAgIDB4ZWQsMHhjOSwweDY2LDB4ZmYsMHhmMSwweDIxLDB4MzIsMHhmYSwweDYyLDB4NDMsMHhjZCwweDk3LDB4ZDMsMHgzZCwweGFmLFxuICAgICAgICAgICAgICAgICAgICAweGI0LDB4MjksMHgyOSwweDI2LDB4NGUsMHgxYywweGEwLDB4YWQsMHgxYywweDA3LDB4MjgsMHgzZiwweGU1LDB4NDMsMHgxMCxcbiAgICAgICAgICAgICAgICAgICAgMHhiYSwweGI0LDB4MDgsMHhlMCwweGRjLDB4YTIsMHhjMywweDViLDB4MWYsMHhiZCwweDk0LDB4YzcsMHg0MywweGU1LDB4ZjIsXG4gICAgICAgICAgICAgICAgICAgIDB4MTcsMHgzMCwweDU0LDB4N2YsMHgxNCwweGJlLDB4ZjQsMHhiZCwweDkxLDB4M2IsMHhlNCwweDM2LDB4YTQsMHg1MCwweDViLFxuICAgICAgICAgICAgICAgICAgICAweDM3LDB4ODksMHg1ZSwweGNjLDB4YzcsMHg3NCwweDU0LDB4MzIsMHgyMCwweDA5LDB4NjMsMHg5OCwweGI3LDB4ZDksMHhhZixcbiAgICAgICAgICAgICAgICAgICAgMHg3ZiwweGIwLDB4NmMsMHgyNywweDQzLDB4ZmUsMHg1MiwweGU2LDB4MWEsMHg4OCwweDU5LDB4MjUsMHhmYywweGViLDB4NDMsXG4gICAgICAgICAgICAgICAgICAgIDB4NTAsMHhjNywweDY1LDB4NDMsMHhjMSwweDg2LDB4NzMsMHg1OCwweDUzLDB4M2EsMHhjZiwweDdhLDB4YTMsMHgxZCwweDU2LFxuICAgICAgICAgICAgICAgICAgICAweGM4LDB4NGEsMHg4MCwweDcwLDB4YjcsMHhiZiwweGYyLDB4YTMsMHhlYywweGU4LDB4NzcsMHgwNSwweDMzLDB4MDksMHg5ZCxcbiAgICAgICAgICAgICAgICAgICAgMHhhYSwweGNhLDB4YTAsMHhlMSwweDY0LDB4NjQsMHg2ZiwweDc2LDB4OTksMHg0MSwweDc1LDB4NzgsMHg5MCwweGY2LDB4ZTcsXG4gICAgICAgICAgICAgICAgICAgIDB4MjMsMHhlNiwweGVjLDB4NTAsMHhlNSwweDk5LDB4YTgsMHgzZSwweDFhLDB4NGIsMHhjOSwweDg4LDB4NTgsMHg2NiwweGFlLFxuICAgICAgICAgICAgICAgICAgICAweDFhLDB4NTMsMHg1ZSwweGU0LDB4YjcsMHg4NiwweGNmLDB4YTYsMHhlNSwweGFkLDB4YjQsMHg4MCwweGEwLDB4ZjEsMHgwZCxcbiAgICAgICAgICAgICAgICAgICAgMHg5NiwweGI4LDB4NDEsMHhkMCwweDA3LDB4OWEsMHgyMSwweDhkLDB4NTAsMHg3ZiwweDRmLDB4NzMsMHgxMywweGEyLDB4ZTIsXG4gICAgICAgICAgICAgICAgICAgIDB4MDIsMHgwNywweGMzLDB4YTMsMHgwZiwweDA5LDB4MTgsMHg3ZiwweGY3LDB4NmIsMHg5MCwweDcwLDB4YzAsMHhmOSwweDBjLFxuICAgICAgICAgICAgICAgICAgICAweDY3LDB4OGQsMHg5ZCwweDE0LDB4YjYsMHg5ZCwweDMyLDB4ODIsMHhkMCwweGI1LDB4YzYsMHg1NywweGYwLDB4OTEsMHhkOSxcbiAgICAgICAgICAgICAgICAgICAgMHhjMywweDI2LDB4YWUsMHg5ZiwweGE5LDB4NjcsMHg0OSwweDk2LDB4NWMsMHgwNywweDNlLDB4NDcsMHg1YywweGVkLDB4NjAsXG4gICAgICAgICAgICAgICAgICAgIDB4MDcsMHhhYywweDZhXSldO1xuICB2YXIgRFNBc2VjTVBJc3RycyA9IFt1dGlsLmJpbjJzdHIoWzB4MDEsMHgwMCwweDliLDB4NTgsMHhhOCwweGY0LDB4MDQsMHhiMSwweGQ1LDB4MTQsMHgwOSwweGUxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhlMSwweGExLDB4OGEsMHgwYiwweGEzLDB4YzMsMHhhMywweDY2LDB4YWEsMHgyNywweDk5LDB4NTAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAweDFjLDB4NGQsMHhiYSwweDI0LDB4ZWUsMHhkZiwweGRmLDB4YjgsMHg4ZSwweDhlXSldO1xuICAgICAgICAgICAgXG4gIHZhciBFbGdhbWFscHViTVBJc3RycyA9IFxuICAgICAgICAgIFt1dGlsLmJpbjJzdHIoWzB4MDgsMHgwMCwweGVhLDB4Y2MsMHhiZSwweGUyLDB4ZTQsMHg1YSwweDUxLDB4MTgsMHg5MywweGExLDB4MTIsMHgyZixcbiAgICAgICAgICAgICAgICAgICAgIDB4MDAsMHg5OSwweDQyLDB4ZDgsMHg1YywweDFjLDB4MmYsMHhiNiwweDNjLDB4ZDksMHg5NCwweDYxLDB4YjQsMHg1NSxcbiAgICAgICAgICAgICAgICAgICAgIDB4OGQsMHg0ZSwweDczLDB4ZTYsMHg2OSwweGJjLDB4MWQsMHgzMywweGUzLDB4MmQsMHg5MSwweDIzLDB4NjksMHg5NSxcbiAgICAgICAgICAgICAgICAgICAgIDB4OTgsMHhkNywweDE4LDB4NWEsMHhhZiwweGE3LDB4OTMsMHhjNiwweDA1LDB4OTMsMHgzYSwweGM3LDB4ZWEsMHhkMCxcbiAgICAgICAgICAgICAgICAgICAgIDB4YjEsMHhhOSwweGM3LDB4YWIsMHg0MSwweDg5LDB4YzgsMHgzOCwweDk5LDB4ZGMsMHgxYSwweDU3LDB4MzUsMHgxYSxcbiAgICAgICAgICAgICAgICAgICAgIDB4MjcsMHg2MiwweDQwLDB4NzEsMHg5ZiwweDM2LDB4MWMsMHg2ZCwweDE4LDB4MWMsMHg5MywweGY3LDB4YmEsMHgzNSxcbiAgICAgICAgICAgICAgICAgICAgIDB4MDYsMHhlZCwweDMwLDB4YjgsMHhkOSwweDhhLDB4N2MsMHgwMywweGFmLDB4YmEsMHg0MCwweDFmLDB4NjIsMHhmMSxcbiAgICAgICAgICAgICAgICAgICAgIDB4NmQsMHg4NywweDJjLDB4YTYsMHgyZSwweDQ2LDB4YjAsMHhhYSwweGJjLDB4YmMsMHg5MywweGZhLDB4OWIsMHg0NyxcbiAgICAgICAgICAgICAgICAgICAgIDB4M2YsMHg3MCwweDFmLDB4MmEsMHhjMiwweDY2LDB4OWMsMHg3YywweDY5LDB4ZTAsMHgyYiwweDA1LDB4ZWUsMHhiNyxcbiAgICAgICAgICAgICAgICAgICAgIDB4YTcsMHg3ZiwweGYzLDB4MjEsMHg0OCwweDg1LDB4YzIsMHg5NSwweDVmLDB4NmYsMHgxZSwweGIzLDB4OWIsMHg5NyxcbiAgICAgICAgICAgICAgICAgICAgIDB4ZjgsMHgxNCwweGMzLDB4ZmYsMHg0ZCwweDk3LDB4MjUsMHgyOSwweDk0LDB4NDEsMHg0YiwweDkwLDB4ZDgsMHhiYSxcbiAgICAgICAgICAgICAgICAgICAgIDB4NzEsMHg0NSwweDRiLDB4MWUsMHgyZiwweGNhLDB4ODIsMHg1ZiwweDU2LDB4NzcsMHhlOSwweGQzLDB4ODgsMHg1ZCxcbiAgICAgICAgICAgICAgICAgICAgIDB4OGIsMHhlYywweDkyLDB4OGIsMHg4YSwweDIzLDB4ODgsMHgwNSwweGY4LDB4MmMsMHhhOCwweGYxLDB4NzAsMHg3NixcbiAgICAgICAgICAgICAgICAgICAgIDB4ZTcsMHhiZiwweDc1LDB4YTgsMHgzMSwweDE0LDB4OGUsMHg3NiwweGM4LDB4MDEsMHhhNiwweDI1LDB4MjcsMHg0OSxcbiAgICAgICAgICAgICAgICAgICAgIDB4YWYsMHhkYywweGY0LDB4ZjYsMHhmNCwweGNlLDB4OTAsMHg4NCwweDE1LDB4MmIsMHg0ZCwweGIzLDB4Y2MsMHg3NyxcbiAgICAgICAgICAgICAgICAgICAgIDB4ZGIsMHg2NSwweDcxLDB4NzUsMHhkMywweDAwLDB4MWQsMHgyMiwweGM1LDB4NDIsMHgyZiwweDUxLDB4ZmEsMHg3YixcbiAgICAgICAgICAgICAgICAgICAgIDB4ZWIsMHg2ZSwweDAzLDB4ZDksMHg0MSwweGRkLDB4MmQsMHgxYSwweGRkLDB4MDcsMHg3NCwweDhiLDB4YjcsMHhhMixcbiAgICAgICAgICAgICAgICAgICAgIDB4ZmEsMHhiMiwweDU5LDB4MGUsMHgwZSwweDk0LDB4N2MsMHgwMCwweGFkLDB4OTUsMHgyMywweDQyLDB4OTEsMHgxOCxcbiAgICAgICAgICAgICAgICAgICAgIDB4NGMsMHg5NywweGYxLDB4MjcsMHg2MiwweDc3XSksXG4gICAgICAgdXRpbC5iaW4yc3RyKFsweDAwLDB4MDMsMHgwNV0pLFxuICAgICAgIHV0aWwuYmluMnN0cihbMHgwNywweGZmLDB4NTcsMHgxOSwweDc2LDB4ZmMsMHgwOSwweDZhLDB4N2EsMHhmNywweGJhLDB4YjIsMHg0MiwweGJmLFxuICAgICAgICAgICAgICAgICAgICAgMHhjZCwweDJiLDB4YzEsMHgxYSwweDc5LDB4MjUsMHg4YywweGFkLDB4ZjQsMHgzYSwweDBhLDB4N2EsMHg5YiwweDRjLFxuICAgICAgICAgICAgICAgICAgICAgMHg0NiwweDNjLDB4ZTAsMHg0ZiwweGNjLDB4NmUsMHhlNSwweDdhLDB4MzMsMHgzYSwweDRlLDB4ODAsMHhjYiwweGQzLFxuICAgICAgICAgICAgICAgICAgICAgMHg2MiwweGQ3LDB4OGYsMHhlMiwweGM4LDB4YjAsMHhkMCwweGNiLDB4NDksMHhjOSwweDllLDB4MmQsMHg5NywweDE2LFxuICAgICAgICAgICAgICAgICAgICAgMHgzYSwweDdkLDB4YjEsMHhlMSwweGQzLDB4ZDksMHhkNywweDNmLDB4MjAsMHg2MCwweGUzLDB4M2UsMHg3NywweGVhLFxuICAgICAgICAgICAgICAgICAgICAgMHgwYywweGU0LDB4N2IsMHhmMCwweDM5LDB4MWEsMHgwZCwweGQ5LDB4OGYsMHg3MywweGQyLDB4NTEsMHhiOCwweDBjLFxuICAgICAgICAgICAgICAgICAgICAgMHgwZSwweDE1LDB4MWUsMHhhZCwweDdjLDB4ZDgsMHg5ZCwweDc0LDB4NmUsMHhhMiwweDE3LDB4NmIsMHg1OCwweDE0LFxuICAgICAgICAgICAgICAgICAgICAgMHgyYiwweGI3LDB4YWQsMHg4YSwweGQ3LDB4NjYsMHhjMCwweGRmLDB4ZWEsMHgyZCwweGZjLDB4YzQsMHg2ZSwweDY4LFxuICAgICAgICAgICAgICAgICAgICAgMHhiNiwweDRjLDB4OWEsMHgxNiwweGE0LDB4M2QsMHhjMiwweDI2LDB4MGMsMHhiNywweGQ0LDB4MTMsMHg3YiwweDIyLFxuICAgICAgICAgICAgICAgICAgICAgMHhmZCwweDg0LDB4ZDcsMHgwZiwweGRjLDB4NDIsMHg3NSwweDA1LDB4ODUsMHgyOSwweDAwLDB4MzEsMHgxZCwweGVjLFxuICAgICAgICAgICAgICAgICAgICAgMHg0ZSwweDIyLDB4OGIsMHhmNiwweDM3LDB4ODMsMHg0NSwweGU1LDB4YjMsMHgzMSwweDYxLDB4MmMsMHgwMiwweGExLFxuICAgICAgICAgICAgICAgICAgICAgMHhjNiwweDlkLDB4ZWEsMHhiYSwweDNkLDB4OGEsMHhhYiwweDBmLDB4NjEsMHg1ZSwweDE0LDB4NjQsMHg2OSwweDFlLFxuICAgICAgICAgICAgICAgICAgICAgMHhhMCwweDE1LDB4NDgsMHg4NiwweGU1LDB4MTEsMHgwNiwweGU4LDB4ZGUsMHgzNCwweGM3LDB4YTcsMHgzZCwweDM1LFxuICAgICAgICAgICAgICAgICAgICAgMHhkMSwweDc2LDB4YzIsMHhiZSwweDAxLDB4ODIsMHg2MSwweDhkLDB4ZTcsMHg3ZSwweDI4LDB4MWQsMHg0ZSwweDhjLFxuICAgICAgICAgICAgICAgICAgICAgMHhiOSwweGU4LDB4N2UsMHhhNCwweDVmLDB4YTYsMHgzYSwweDllLDB4NWQsMHhhYywweGYzLDB4NjAsMHgyMiwweDE0LFxuICAgICAgICAgICAgICAgICAgICAgMHhkNSwweGQ1LDB4YmUsMHgxZiwweGYwLDB4MTksMHhlNiwweDgxLDB4ZmQsMHg1ZCwweGUxLDB4ZjgsMHg3NiwweDVmLFxuICAgICAgICAgICAgICAgICAgICAgMHhlMywweGRhLDB4YmEsMHgxOSwweGYzLDB4Y2IsMHgxMCwweGEwLDB4NmIsMHhkMCwweDJkLDB4YmUsMHg0MCwweDQyLFxuICAgICAgICAgICAgICAgICAgICAgMHg3YiwweDliLDB4MTUsMHhhNCwweDJkLDB4ZWMsMHhjZiwweDA5LDB4ZDYsMHhlMywweDkyLDB4YzMsMHg4ZCwweDY1LFxuICAgICAgICAgICAgICAgICAgICAgMHg2YiwweDYwLDB4OTcsMHhkYSwweDZiLDB4Y2FdKV07XG5cbiAgdmFyIEVsZ2FtYWxzZWNNUElzdHJzID0gW1xuICAgICAgICAgICAgIHV0aWwuYmluMnN0cihbMHgwMSwweDUyLDB4MDIsMHg4MCwweDg3LDB4ZjYsMHhlNCwweDQ5LDB4ZDcsMHgyZSwweDNlLDB4ZmUsMHg2MCwweGI5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhhMywweDJhLDB4ZjAsMHg2NywweDU4LDB4ZTksMHhmNiwweDQ3LDB4ODMsMHhkZSwweDdlLDB4ZmIsMHhiYiwweGJkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhkZiwweDQ4LDB4MTIsMHgxYiwweDA2LDB4N2QsMHgxMywweGJjLDB4M2IsMHg0OSwweGY5LDB4ODYsMHhkNCwweDUzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhlZCwweDJkLDB4NjhdKV07XG5cbiAgdmFyIFJTQXB1Yk1QSXMgPSBbXTtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHtcbiAgICBSU0FwdWJNUElzW2ldID0gbmV3IG9wZW5wZ3AubXBpKCk7XG4gICAgUlNBcHViTVBJc1tpXS5yZWFkKFJTQXB1Yk1QSXN0cnNbaV0pO1xuICB9XG5cbiAgdmFyIFJTQXNlY01QSXMgPSBbXTtcbiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIFJTQXNlY01QSXNbaV0gPSBuZXcgb3BlbnBncC5tcGkoKTtcbiAgICBSU0FzZWNNUElzW2ldLnJlYWQoUlNBc2VjTVBJc3Ryc1tpXSk7XG4gIH1cbiAgICBcbiAgdmFyIERTQXNlY01QSXMgPSBbXTtcbiAgZm9yIChpID0gMDsgaSA8IDE7IGkrKykge1xuICAgIERTQXNlY01QSXNbaV0gPSBuZXcgb3BlbnBncC5tcGkoKTtcbiAgICBEU0FzZWNNUElzW2ldLnJlYWQoRFNBc2VjTVBJc3Ryc1tpXSk7XG4gIH1cbiAgICBcbiAgdmFyIERTQXB1Yk1QSXMgPSBbXTtcbiAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIERTQXB1Yk1QSXNbaV0gPSBuZXcgb3BlbnBncC5tcGkoKTtcbiAgICBEU0FwdWJNUElzW2ldLnJlYWQoRFNBcHViTVBJc3Ryc1tpXSk7XG4gIH1cbiAgdmFyIEVsZ2FtYWxzZWNNUElzID0gW107XG4gIGZvciAoaSA9IDA7IGkgPCAxOyBpKyspIHtcbiAgICBFbGdhbWFsc2VjTVBJc1tpXSA9IG5ldyBvcGVucGdwLm1waSgpO1xuICAgIEVsZ2FtYWxzZWNNUElzW2ldLnJlYWQoRWxnYW1hbHNlY01QSXN0cnNbaV0pO1xuICB9XG4gICAgXG4gIHZhciBFbGdhbWFscHViTVBJcyA9IFtdO1xuICBmb3IgKGkgPSAwOyBpIDwgMzsgaSsrKSB7XG4gICAgRWxnYW1hbHB1Yk1QSXNbaV0gPSBuZXcgb3BlbnBncC5tcGkoKTtcbiAgICBFbGdhbWFscHViTVBJc1tpXS5yZWFkKEVsZ2FtYWxwdWJNUElzdHJzW2ldKTtcbiAgfVxuXG4gIC8vT3JpZ2luYWxseSB3ZSBwYXNzZWQgcHVibGljIGFuZCBzZWNyZXQgTVBJIHNlcGFyYXRlbHksIG5vdyB0aGV5IGFyZSBqb2luZWQuIElzIHRoaXMgd2hhdCB3ZSB3YW50IHRvIGRvIGxvbmcgdGVybT9cbiAgLy8gUlNBXG4gIHZhciBSU0FzaWduZWREYXRhID0gb3BlbnBncC5zaWduYXR1cmUuc2lnbigyLCAxLCBSU0FwdWJNUElzLmNvbmNhdChSU0FzZWNNUElzKSwgXCJmb29iYXJcIik7XG4gIHZhciBSU0FzaWduZWREYXRhTVBJID0gbmV3IG9wZW5wZ3AubXBpKCk7XG4gIFJTQXNpZ25lZERhdGFNUEkucmVhZChSU0FzaWduZWREYXRhKTtcbiAgcmVzdWx0WzBdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBSU0EgU2lnbiBhbmQgVmVyaWZ5XCIsXG4gICAgICBvcGVucGdwLnNpZ25hdHVyZS52ZXJpZnkoMSwgMiwgW1JTQXNpZ25lZERhdGFNUEldLCBSU0FwdWJNUElzLCBcImZvb2JhclwiKSk7XG5cbiAgLy8gRFNBIFxuICB2YXIgRFNBc2lnbmVkRGF0YSA9IG9wZW5wZ3Auc2lnbmF0dXJlLnNpZ24oMiwgMTcsIERTQXB1Yk1QSXMuY29uY2F0KERTQXNlY01QSXMpLCBcImZvb2JhclwiKTtcbiAgXG4gIHZhciBEU0Ftc2dNUElzID0gW107XG4gICAgRFNBbXNnTVBJc1swXSA9IG5ldyBvcGVucGdwLm1waSgpO1xuICAgIERTQW1zZ01QSXNbMV0gPSBuZXcgb3BlbnBncC5tcGkoKTtcbiAgICBEU0Ftc2dNUElzWzBdLnJlYWQoRFNBc2lnbmVkRGF0YS5zdWJzdHJpbmcoMCwzNCkpO1xuICAgIERTQW1zZ01QSXNbMV0ucmVhZChEU0FzaWduZWREYXRhLnN1YnN0cmluZygzNCw2OCkpO1xuICByZXN1bHRbMV0gPSBuZXcgdW5pdC5yZXN1bHQoXCJUZXN0aW5nIERTQSBTaWduIGFuZCBWZXJpZnlcIixcbiAgICAgIG9wZW5wZ3Auc2lnbmF0dXJlLnZlcmlmeSgxNywgMiwgRFNBbXNnTVBJcywgRFNBcHViTVBJcywgXCJmb29iYXJcIikpO1xuICBcbiAgdmFyIHN5bW1BbGdvID0gXCJhZXMyNTZcIjsgLy8gQUVTMjU2XG4gIHZhciBzeW1tS2V5ID0gb3BlbnBncC5nZW5lcmF0ZVNlc3Npb25LZXkoc3ltbUFsZ28pO1xuICB2YXIgc3ltbWVuY0RhdGFPQ0ZCID0gb3BlbnBncC5jZmIuZW5jcnlwdChvcGVucGdwLmdldFByZWZpeFJhbmRvbShzeW1tQWxnbyksIHN5bW1BbGdvLCBcImZvb2JhcmZvb2JhcjEyMzQ1Njc4OTBcIiwgc3ltbUtleSwgdHJ1ZSk7XG4gIHZhciBzeW1tZW5jRGF0YUNGQiAgPSBvcGVucGdwLmNmYi5lbmNyeXB0KG9wZW5wZ3AuZ2V0UHJlZml4UmFuZG9tKHN5bW1BbGdvKSwgc3ltbUFsZ28sIFwiZm9vYmFyZm9vYmFyMTIzNDU2Nzg5MFwiLCBzeW1tS2V5LCBmYWxzZSk7XG4gIFxuICByZXN1bHRbMl0gPSBuZXcgdW5pdC5yZXN1bHQoXCJUZXN0aW5nIHN5bW1ldHJpYyBlbmNyeXB0IGFuZCBkZWNyeXB0IHdpdGggT3BlblBHUCBDRkIgcmVzeW5jXCIsXG4gICAgICBvcGVucGdwLmNmYi5kZWNyeXB0KHN5bW1BbGdvLHN5bW1LZXksc3ltbWVuY0RhdGFPQ0ZCLHRydWUpID09IFwiZm9vYmFyZm9vYmFyMTIzNDU2Nzg5MFwiKTtcbiAgcmVzdWx0WzNdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBzeW1tZXRyaWMgZW5jcnlwdCBhbmQgZGVjcnlwdCB3aXRob3V0IE9wZW5QR1AgQ0ZCIHJlc3luYyAodXNlZCBpbiBtb2RpZmljYXRpb24gZGV0ZWN0aW9uIGNvZGUgXFxcIk1EQ1xcXCIgcGFja2V0cylcIixcbiAgICAgIG9wZW5wZ3AuY2ZiLmRlY3J5cHQoc3ltbUFsZ28sc3ltbUtleSxzeW1tZW5jRGF0YUNGQixmYWxzZSkgPT0gXCJmb29iYXJmb29iYXIxMjM0NTY3ODkwXCIpO1xuICBcbiAgdmFyIFJTQVVuZW5jcnlwdGVkRGF0YSA9IG5ldyBvcGVucGdwLm1waSgpO1xuICBSU0FVbmVuY3J5cHRlZERhdGEuZnJvbUJ5dGVzKG9wZW5wZ3AucGtjczEuZW1lLmVuY29kZShzeW1tS2V5LCBSU0FwdWJNUElzWzBdLmJ5dGVMZW5ndGgoKSkpO1xuICB2YXIgUlNBRW5jcnlwdGVkRGF0YSA9IG9wZW5wZ3AucHVibGljS2V5RW5jcnlwdChcInJzYV9lbmNyeXB0X3NpZ25cIiwgUlNBcHViTVBJcywgUlNBVW5lbmNyeXB0ZWREYXRhKTtcblxuICByZXN1bHRbNF0gPSBuZXcgdW5pdC5yZXN1bHQoXCJUZXN0aW5nIGFzeW1tZXRyaWMgZW5jcnlwdCBhbmQgZGVjcnlwdCB1c2luZyBSU0Egd2l0aCBlbWVfcGtjczEgcGFkZGluZ1wiLFxuICAgICAgb3BlbnBncC5wa2NzMS5lbWUuZGVjb2RlKG9wZW5wZ3AucHVibGljS2V5RGVjcnlwdChcInJzYV9lbmNyeXB0X3NpZ25cIiwgUlNBcHViTVBJcy5jb25jYXQoUlNBc2VjTVBJcyksIFJTQUVuY3J5cHRlZERhdGEpLndyaXRlKCkuc3Vic3RyaW5nKDIpLCBSU0FwdWJNUElzWzBdLmJ5dGVMZW5ndGgoKSkgPT0gc3ltbUtleSk7XG5cbiAgdmFyIEVsZ2FtYWxVbmVuY3J5cHRlZERhdGEgPSBuZXcgb3BlbnBncC5tcGkoKTtcbiAgRWxnYW1hbFVuZW5jcnlwdGVkRGF0YS5mcm9tQnl0ZXMob3BlbnBncC5wa2NzMS5lbWUuZW5jb2RlKHN5bW1LZXksIEVsZ2FtYWxwdWJNUElzWzBdLmJ5dGVMZW5ndGgoKSkpO1xuICB2YXIgRWxnYW1hbEVuY3J5cHRlZERhdGEgPSBvcGVucGdwLnB1YmxpY0tleUVuY3J5cHQoXCJlbGdhbWFsXCIsIEVsZ2FtYWxwdWJNUElzLCBFbGdhbWFsVW5lbmNyeXB0ZWREYXRhKTtcblxuICByZXN1bHRbNV0gPSBuZXcgdW5pdC5yZXN1bHQoXCJUZXN0aW5nIGFzeW1tZXRyaWMgZW5jcnlwdCBhbmQgZGVjcnlwdCB1c2luZyBFbGdhbWFsIHdpdGggZW1lX3BrY3MxIHBhZGRpbmdcIixcbiAgICAgIG9wZW5wZ3AucGtjczEuZW1lLmRlY29kZShvcGVucGdwLnB1YmxpY0tleURlY3J5cHQoXCJlbGdhbWFsXCIsIEVsZ2FtYWxwdWJNUElzLmNvbmNhdChFbGdhbWFsc2VjTVBJcyksIEVsZ2FtYWxFbmNyeXB0ZWREYXRhKS53cml0ZSgpLnN1YnN0cmluZygyKSwgRWxnYW1hbHB1Yk1QSXNbMF0uYnl0ZUxlbmd0aCgpKSA9PSBzeW1tS2V5KTtcblxuICByZXR1cm4gcmVzdWx0O1xufSk7XG4iLCJ2YXIgdW5pdCA9IHJlcXVpcmUoJy4uL3VuaXQuanMnKTtcblxudW5pdC5yZWdpc3RlcihcIlRlc3Rpbmcgb2YgYmluYXJ5IHNpZ25hdHVyZSBjaGVja2luZ1wiLCBmdW5jdGlvbigpIHtcbiAgdmFyIG9wZW5wZ3AgPSByZXF1aXJlKCcuLi8uLi8nKTtcbiAgdmFyIGtleXJpbmcgPSByZXF1aXJlKCcuLi8uLi9zcmMvb3BlbnBncC5rZXlyaW5nLmpzJyk7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIHByaXZfa2V5ID0gb3BlbnBncC5yZWFkQXJtb3JlZFBhY2tldHMoW1xuICAgICAgICAnLS0tLS1CRUdJTiBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLScsXG4gICAgICAgICdWZXJzaW9uOiBHbnVQRyB2MS40LjExIChHTlUvTGludXgpJyxcbiAgICAgICAgJycsXG4gICAgICAgICdsUUhoQkZFUm5yTVJCQURtTTBoSWZrSTN5b3NqZ2JXbzl2MExucjNDQ0UrOEtzTXN6Z1ZTK2hCdTBYZkdyYUttJyxcbiAgICAgICAgJ2l2Y0EyYWFKaW1IcVZZT1A3Z0Vud0ZBeEhCQnBlVEpjdTV3ekNGeUp3RVlxVmVTM25uYUloQlBwbFNGMTREdWYnLFxuICAgICAgICAnaTZiQjlSVjdLeFZBZzZhdW5tTTJ0QXV0cUMrYTB5MnJEYWY3amtKb1o5Z1dKZTJ6SSt2cmFENmZpd0NneHZIbycsXG4gICAgICAgICczSWdVTEI5UnFJcXBMb01nWGZjakMrY0QvMWplSmxLUm0rbjcxcnlZd1QvRUNLc3NwRno3UzM2ejZxM1h5UzhRJyxcbiAgICAgICAgJ1FmcnNVejJwMWZiRmljdkp3SU9KOEIyMEovTjIvbml0NFAwZ0JVVFV4djNRRWE3WENNLzU2L3hyR2t5QnpzY1cnLFxuICAgICAgICAnQXpCb3kvQUs5SzdHTjZ6MTNSb3p1QVM2MEYxeE83TVFjNllpMlZVM2VBU0RRRUtpeUwvVWJmL3MvcmtaK3NHaicsXG4gICAgICAgICd5Sml6QkFDdHdDYlF6QSt6OVhCWk5VYXQ1TlBnY1p6NVFlaDFud0Y5TnhucjZweUJ2N3RrckxoLzNneFJHSHFHJyxcbiAgICAgICAgJzA2M2RNYlVrOHBtVWNKekJVeVJzTmlJUERvRVVzTGpZNXptWlptcC93YUFocFJFc25LMjlXTENicUxkcFVvcnMnLFxuICAgICAgICAnYzFKSkJzT2JrQTFJTThUWlk4WVVtdnNNRXZCTENDYW51S3BjbFpaWHFlUkFlT0hKMHY0REF3SzhXZnVUZTVCKycsXG4gICAgICAgICdNMkJPT2VaYk44QnBmaUExbC8vZk1NSExSUzNVdmJMQnY0UDErNFN5dmh5WVRSN003NlEweFBjMDNNRk9XSEwrJyxcbiAgICAgICAgJ1M5VnVtYlFXVkdWemRESWdQSFJsYzNReVFIUmxjM1F1WTI5dFBvaGlCQk1SQWdBaUJRSlJFWjZ6QWhzREJnc0onLFxuICAgICAgICAnQ0FjREFnWVZDQUlKQ2dzRUZnSURBUUllQVFJWGdBQUtDUkFSSjVRRHl4YWUrTVhOQUtDeldTRFIzdE1yVHJEYicsXG4gICAgICAgICdUQXJpNzNOMVhiM2oxQUNmU2w5eStTQWFoMnE3R3ZtaVIxKzYrL2VrcUpHZEFWZ0VVUkdlc3hBRUFObHBNWmpXJyxcbiAgICAgICAgJzMzak14bEtIRGR5UkZYdEtPcThScmVYaHEwMHBsb3JIYmd6OXpGRVdtNFZGNTMrRS9LR25tSEd5WTVDeThUS3knLFxuICAgICAgICAnWmphdWVaWjlYdUcwaHVaZzVJZjY4aXJGZk5adHhkQTI2anY4Ly9QZFowVWorWDZKM1JWYTJwZU1MRERzd1RZTCcsXG4gICAgICAgICdPTDFaTzFmeGR0REQ0MGZkQWlJWjFReWp3RUcwQVB0ejQxRWZBQU1GQkFDNS9kdGdCQlB0SGU4VWpEQmFVZTRuJyxcbiAgICAgICAgJ056SHVVQkJwNlhFK0g3ZXFITkZDdVpBSjd5cUpMR1ZITklhUVI0MTljTnkwOC9PTy8rWVVRN3JnNzhMeGpGaXYnLFxuICAgICAgICAnQ0g3SXpoZlUrNnl2RUxTYmdSTWljWTZFbkFQMkdUK2IxK010Rk5hM2xCR3RCSGNKbGE1MmMyclRBSHRoWVpXaycsXG4gICAgICAgICdmVDVSNURuSnVRMmNKSEJNUzlIV3lQNERBd0s4V2Z1VGU1QitNMkM3YS9ZSlNVdjZTZXhkR0NhaWFUY0FtNmcvJyxcbiAgICAgICAgJ1B2QTZody9GTHpJRVA2N1FjUVNTVG1oZnRRSXduZGR0NFM0TXlKSkgzVTRmSmFGZllRMXpDbmlZSm9oSkJCZ1InLFxuICAgICAgICAnQWdBSkJRSlJFWjZ6QWhzTUFBb0pFQkVubEFQTEZwNzRRYk1BbjNWNDg1N3h3bk85Lyt2eklWbkw5M1czazAvOCcsXG4gICAgICAgICdBS0M4b21ZUFBvbU4xRS9VSkZmWGRMRElNaTVMb0E9PScsXG4gICAgICAgICc9TFNyVycsXG4gICAgICAgICctLS0tLUVORCBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLSdcbiAgICAgIF0uam9pbihcIlxcblwiKSk7XG4gIHZhciBwdWJfa2V5ID0gb3BlbnBncC5yZWFkQXJtb3JlZFBhY2tldHMoXG4gICAgICBbICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0nLFxuICAgICAgICAnVmVyc2lvbjogR251UEcgdjEuNC4xMSAoR05VL0xpbnV4KScsXG4gICAgICAgICcnLFxuICAgICAgICAnbVFHaUJGRVJsdzRSQkFENkJtY2YydzFkdFVtdENMa2R4ZXFaTEFyazN2WW9RQWpkaWJ4QTNnWFZ5dXI3ZnNXYicsXG4gICAgICAgICdybzBqVmJCSHFPQ3RDNmpEeEUybDUyTlA5K3RUbFdlVk1hcXFOdlVFNDdMU2FQcTJER0k4V3gxUmo2YkYzbVRzJyxcbiAgICAgICAgJ29iWUV3aEdiR2gvTWhKbk1FOUFIT0RhcnZrOEFaYnpvMCtrMUV3ckJXRjZkVFVCUGZxTzdyR1UyZXdDZzgwV1YnLFxuICAgICAgICAneDVwdDNldmo4clJLM2pROFNNS1ROUnNELzFQaFRkeGRaVGRYQVJBRnpjVzFWYWFydVdXMFJyMStYSEtLd0RDeicsXG4gICAgICAgICdpN0hFNzZTTzlxam5RZlpDWkc3NUNkUXhJMGg4R0ZlTjN6c0RxbWhvYjJpU3oyYUoxa3J0ak0raVoxRkJGZDU3JyxcbiAgICAgICAgJ09xQ1Y2d21rNUlUMFJCTjEyWnpNUzE5WXZ6Ti9PTlhIcm1UWmxLRXhkOU1oOVJLTGVWTncrYmY2SnNLUUV6Y1knLFxuICAgICAgICAnSnpGa0JBQ1g5WCtoRFljaE8vMmhpVHd4NGlPTzlGaHN1aDdlSVd1bUIzZ3QrYVVwbTFqclNiYXMvUUxUeW1taycsXG4gICAgICAgICd1WnVRVlhJNE50bmx2emxOZ1d2NEw1czVSVTVXcU5HRzdXU2FLTmRjcnZKWlJDMmRnYlVKdDA0SjVDS3JXcDZSJyxcbiAgICAgICAgJ2FJWWFsLzgxVXQxNzc4bFUwMVBFdDU2M1RjUW5VQmxualU1T1IyNUtoZlNlTjVDWlk3UVVWR1Z6ZENBOGRHVnonLFxuICAgICAgICAnZEVCMFpYTjBMbU52YlQ2SVlnUVRFUUlBSWdVQ1VSR1hEZ0liQXdZTENRZ0hBd0lHRlFnQ0NRb0xCQllDQXdFQycsXG4gICAgICAgICdIZ0VDRjRBQUNna1Fpa0RsWksvVXZMU3NwZ0NmY05hT3BUZzFXMnVjUjFKd0JiQkd2YUVSZnVNQW5SZ3QzL3JzJyxcbiAgICAgICAgJ0VwbHFFYWtNY2tDdGlrRW5weFllJyxcbiAgICAgICAgJz1iMkxuJyxcbiAgICAgICAgJy0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0nXG4gICAgICBdLmpvaW4oXCJcXG5cIikpO1xuICB2YXIgbXNnID0gb3BlbnBncC5yZWFkQXJtb3JlZFBhY2tldHMoW1xuICAgICAgICAnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tJyxcbiAgICAgICAgJ1ZlcnNpb246IEdudVBHIHYxLjQuMTEgKEdOVS9MaW51eCknLFxuICAgICAgICAnJyxcbiAgICAgICAgJ2hRRU9BMU40T0NTU2pFQ0JFQVAvZGlESkNRbjRlODgxOTNQZ3FoYmZBa29oazlSUTB2ME1QblhwSmJDUlRIS08nLFxuICAgICAgICAnOHI5bnhpQXIvVFF2NFpPaW5nWGRBcDJKWkVvRTlwWHhaM3IxVVdldzA0Y3p4bWdKOEZQMXp0WllXVkZBV0ZWaScsXG4gICAgICAgICdUajkzMFRCRDdMMWZZL01ENGZLNnhqRUc3ejVHVDhrNHRuNG1MbS9QcFdNYmFySWdsZk1vcFR5MU0vcHkyY0lEJyxcbiAgICAgICAgJy8yU2o3SWtoM1VGaUcrem00c1ZpWWM1cm9OYk15OGl4ZW9LaXh4aTk5TXg4SU5hMmN4TmZxYmFiamJsRnljMFonLFxuICAgICAgICAnQndtYkljK1ppWTJtZVJOSTV5L3RrMGdSRDdoVDg0SVhHR2w2L21IMDBic1gva2tXZEtHZVR2ejhzNUc4UkRIYScsXG4gICAgICAgICdaYTRIZ0xiWEl0a1gvUWFydlJTOWt2a0QwMXVqSGZqKzFadmdtT0J0dE5mUDBwOEJRTElJQ3F2ZzFlWUQ5YVBCJyxcbiAgICAgICAgJytHdE9aMkYzK2s1VnlCTDV5SW4vczY1U0JqTk84RnFzM2FMMHgrcDdzMWNmVXp4OEo4YThuV3BxcS9xSVFJcWcnLFxuICAgICAgICAnWkpINk1aUkt1UXdzY3dINk5XZ3NTVndjblZDQVhuWU9wYkh4RlErajdSYkYvK3VpdXFVK0RGSC9SZDVwaWs4YicsXG4gICAgICAgICcwRHFucDB5ZmVmcmtqUTBudXZ1YmdCNlJ2ODltSHBudnVKZkZKUklucGc0bHJId0x2UndkcE4ySERvekZIY0tLJyxcbiAgICAgICAgJ2FPVT0nLFxuICAgICAgICAnPTRpR3QnLFxuICAgICAgICAnLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLSdcbiAgICAgIF0uam9pbihcIlxcblwiKSk7XG4gIC8vVE9ETyBuZWVkIGJvdGg/XG4gIHByaXZfa2V5WzBdLmRlY3J5cHQoXCJhYmNkXCIpO1xuICBwcml2X2tleVszXS5kZWNyeXB0KFwiYWJjZFwiKTtcbiAgbXNnWzBdLmRlY3J5cHQocHJpdl9rZXlbM10pO1xuICBtc2dbMV0uZGVjcnlwdChtc2dbMF0uc2Vzc2lvbktleUFsZ29yaXRobSwgbXNnWzBdLnNlc3Npb25LZXkpO1xuICBtc2dbMV0ucGFja2V0c1syXS52ZXJpZnkocHViX2tleVswXSwgbXNnWzFdLnBhY2tldHNbMV0pO1xuICByZXN1bHRbMF0gPSBuZXcgdW5pdC5yZXN1bHQoXCJUZXN0aW5nIHNpZ25hdHVyZSBjaGVja2luZyBvbiBDQVNUNS1lbmNpcGhlcmVkIG1lc3NhZ2VcIixcbiAgICAgICAgICBtc2dbMV0ucGFja2V0c1syXS52ZXJpZmllZCA9PT0gdHJ1ZSk7XG5cbiAgLy8gZXhlcmNpc2VzIHRoZSBHbnVQRyBzMmsgdHlwZSAxMDAxIGV4dGVuc2lvbjpcbiAgLy8gdGhlIHNlY3JldHMgb24gdGhlIHByaW1hcnkga2V5IGhhdmUgYmVlbiBzdHJpcHBlZC5cbiAgdmFyIHByaXZfa2V5X2dudXBnX2V4dCA9IG9wZW5wZ3AucmVhZEFybW9yZWRQYWNrZXRzKFtcbiAgICAgICAgJy0tLS0tQkVHSU4gUEdQIFBSSVZBVEUgS0VZIEJMT0NLLS0tLS0nLFxuICAgICAgICAnVmVyc2lvbjogR251UEcgdjEuNC4xMSAoR05VL0xpbnV4KScsXG4gICAgICAgICcnLFxuICAgICAgICAnbFFHcUJGRVJuck1SQkFEbU0waElma0kzeW9zamdiV285djBMbnIzQ0NFKzhLc01zemdWUytoQnUwWGZHcmFLbScsXG4gICAgICAgICdpdmNBMmFhSmltSHFWWU9QN2dFbndGQXhIQkJwZVRKY3U1d3pDRnlKd0VZcVZlUzNubmFJaEJQcGxTRjE0RHVmJyxcbiAgICAgICAgJ2k2YkI5UlY3S3hWQWc2YXVubU0ydEF1dHFDK2EweTJyRGFmN2prSm9aOWdXSmUyekkrdnJhRDZmaXdDZ3h2SG8nLFxuICAgICAgICAnM0lnVUxCOVJxSXFwTG9NZ1hmY2pDK2NELzFqZUpsS1JtK243MXJ5WXdUL0VDS3NzcEZ6N1MzNno2cTNYeVM4UScsXG4gICAgICAgICdRZnJzVXoycDFmYkZpY3ZKd0lPSjhCMjBKL04yL25pdDRQMGdCVVRVeHYzUUVhN1hDTS81Ni94ckdreUJ6c2NXJyxcbiAgICAgICAgJ0F6Qm95L0FLOUs3R042ejEzUm96dUFTNjBGMXhPN01RYzZZaTJWVTNlQVNEUUVLaXlML1ViZi9zL3JrWitzR2onLFxuICAgICAgICAneUppekJBQ3R3Q2JRekErejlYQlpOVWF0NU5QZ2NaejVRZWgxbndGOU54bnI2cHlCdjd0a3JMaC8zZ3hSR0hxRycsXG4gICAgICAgICcwNjNkTWJVazhwbVVjSnpCVXlSc05pSVBEb0VVc0xqWTV6bVpabXAvd2FBaHBSRXNuSzI5V0xDYnFMZHBVb3JzJyxcbiAgICAgICAgJ2MxSkpCc09ia0ExSU04VFpZOFlVbXZzTUV2QkxDQ2FudUtwY2xaWlhxZVJBZU9ISjB2NERaUUpIVGxVQnRCWlUnLFxuICAgICAgICAnWlhOME1pQThkR1Z6ZERKQWRHVnpkQzVqYjIwK2lHSUVFeEVDQUNJRkFsRVJuck1DR3dNR0N3a0lCd01DQmhVSScsXG4gICAgICAgICdBZ2tLQ3dRV0FnTUJBaDRCQWhlQUFBb0pFQkVubEFQTEZwNzR4YzBBb0xOWklOSGUweXRPc050TUN1THZjM1ZkJyxcbiAgICAgICAgJ3ZlUFVBSjlLWDNMNUlCcUhhcnNhK2FKSFg3cjc5NlNva1owQldBUlJFWjZ6RUFRQTJXa3htTmJmZU16R1VvY04nLFxuICAgICAgICAnM0pFVmUwbzZyeEd0NWVHclRTbVdpc2R1RFAzTVVSYWJoVVhuZjRUOG9hZVljYkpqa0xMeE1ySm1OcTU1bG4xZScsXG4gICAgICAgICc0YlNHNW1Ea2gvcnlLc1Y4MW0zRjBEYnFPL3ovODkxblJTUDVmb25kRlZyYWw0d3NNT3pCTmdzNHZWazdWL0YyJyxcbiAgICAgICAgJzBNUGpSOTBDSWhuVkRLUEFRYlFBKzNQalVSOEFBd1VFQUxuOTIyQUVFKzBkN3hTTU1GcFI3aWMzTWU1UUVHbnAnLFxuICAgICAgICAnY1Q0ZnQ2b2MwVUs1a0Fudktva3NaVWMwaHBCSGpYMXczTFR6ODQ3LzVoUkR1dUR2d3ZHTVdLOElmc2pPRjlUNycsXG4gICAgICAgICdySzhRdEp1QkV5Snhqb1NjQS9ZWlA1dlg0eTBVMXJlVUVhMEVkd21Wcm5aemF0TUFlMkZobGFSOVBsSGtPY201JyxcbiAgICAgICAgJ0Rad2tjRXhMMGRiSS9nTURBcnhaKzVON2tINHpZTHRyOWdsSlMvcEo3RjBZSnFKcE53Q2JxRDgrOERxSEQ4VXYnLFxuICAgICAgICAnTWdRL3J0QnhCSkpPYUYrMUFqQ2QxMjNoTGd6SWtrZmRUaDhsb1Y5aERYTUtlSmdtaUVrRUdCRUNBQWtGQWxFUicsXG4gICAgICAgICduck1DR3d3QUNna1FFU2VVQThzV252aEJzd0NmZFhqem52SENjNzMvNi9NaFdjdjNkYmVUVC93QW9MeWlaZzgrJyxcbiAgICAgICAgJ2lZM1VUOVFrVjlkMHNNZ3lMa3VnJyxcbiAgICAgICAgJz1HUXNZJyxcbiAgICAgICAgJy0tLS0tRU5EIFBHUCBQUklWQVRFIEtFWSBCTE9DSy0tLS0tJyxcbiAgICAgIF0uam9pbihcIlxcblwiKSk7XG4gIHByaXZfa2V5X2dudXBnX2V4dFszXS5kZWNyeXB0KFwiYWJjZFwiKTtcbiAgbXNnWzBdLmRlY3J5cHQocHJpdl9rZXlfZ251cGdfZXh0WzNdKTtcbiAgbXNnWzFdLmRlY3J5cHQobXNnWzBdLnNlc3Npb25LZXlBbGdvcml0aG0sIG1zZ1swXS5zZXNzaW9uS2V5KTtcbiAgbXNnWzFdLnBhY2tldHNbMl0udmVyaWZ5KHB1Yl9rZXlbMF0sIG1zZ1sxXS5wYWNrZXRzWzFdKTtcbiAgcmVzdWx0WzFdID0gbmV3IHVuaXQucmVzdWx0KFwiVGVzdGluZyBHbnVQRyBzdHJpcHBlZC1rZXkgZXh0ZW5zaW9uc1wiLFxuICAgICAgICAgIG1zZ1sxXS5wYWNrZXRzWzJdLnZlcmlmaWVkID09PSB0cnVlKTtcblxuICAvLyBFeGVyY2lzZXMgdGhlIGFiaWxpdHkgb2Ygb3BlbnBncF9rZXlyaW5nLmdldFB1YmxpY0tleXNGb3JLZXlJZCB0byByZXR1cm4gc3Via2V5c1xuICBrZXlyaW5nLmluaXQoKTtcbiAga2V5cmluZy5pbXBvcnRQYWNrZXRsaXN0KFtcbiAgICAgICAgJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLScsXG4gICAgICAgICdWZXJzaW9uOiBHbnVQRyB2MS40LjExIChHTlUvTGludXgpJyxcbiAgICAgICAgJycsXG4gICAgICAgICdtUUdpQkZFUnZJNFJCQUQwTS9IR2dsQ3RWTlhQRjcyZWhUOHJpQVhybDByU2VjNFJKQzYxQmgrVUFPaHhuNStVJyxcbiAgICAgICAgJ2ZEZ29zNXAxU3BJelltbitNODdKb1NTVkxBamZha0ZrMGdIZ1I5STNidTdTSXdxM0Jpa2sxVnczZ08reURTTzYnLFxuICAgICAgICAnVEtwTFVGR1lEaUJTU0UxTUdkeEJhZFdMRTFobFJmNUIyeDYyZ25HbWpTcFNWYmx5MzNQRmtvRG1yd0NnOXJBcCcsXG4gICAgICAgICdSbW5jbkY5R2hXak9MRmtFb1F3OVl4OEVBT3N4dnE4SWc1WjFnaytaS2ZEWmVmdHBIUmUzRmRyUnRibmh4dllZJyxcbiAgICAgICAgJzd6K3c5dXoxRXBvWlV3RFI1RzRYM2hUd0pRN2xYbUlPc2tnLytlUk1MRUFxRVk3Yi83dFc2UmFVSjJkNkVoc2knLFxuICAgICAgICAnZE9TODlmSXhFbHdqQU9uVk9NNVMyNGYwRkRRVFR0bzdRQk9veGNOVGZrRUpDSFhTbHBvT1VtR0FQODVmWGgzbCcsXG4gICAgICAgICd5UFRHQkFDSmZLYzc2VW4zVVdDMXNXSVJEeFlpeWgzWnBaeU5Fc2tvVjZFU1c4akVJMVJuTW52NVRyZkdKSDVLJyxcbiAgICAgICAgJ0U4aldYN1RUbm9GeVBKdEJUamx1Y0F0a1FhUzRCYjdkZzFMTGphMTd6QXFLTkdPSksyYjlmYjJaK2xuVGpQaVknLFxuICAgICAgICAnaTdEUEgxWEhuZmFFZXhqbGgvVTdtWWE1UnJ3SXBoUnhOaThnQ3V4djg3NFpNbWhFbjdRV1ZHVnpkRE1nUEhSbCcsXG4gICAgICAgICdjM1F6UUhSbGMzUXVZMjl0UG9oaUJCTVJBZ0FpQlFKUkVieU9BaHNEQmdzSkNBY0RBZ1lWQ0FJSkNnc0VGZ0lEJyxcbiAgICAgICAgJ0FRSWVBUUlYZ0FBS0NSQzB1OE8wTW9hMkpZeHlBSjlPaTJVbGNVVDBWSk5nd2p5bC9WRjlYY2pmOWdDZUpQdnknLFxuICAgICAgICAnZy9mcDRFQVU4TUpJYU4yeU1JOHBMRlM1QWFJRVVSRzhuaEVFQUtWZ2VORHVZRFB1Zkx1SjBHckpWL0NiWEVqaicsXG4gICAgICAgICdhRVBBMGlUVXFWMG5UQ1BkQWZRL25tRTNnaDVVbE5Nci96U0hKK2M0RlFoWWRMcnpSR0RPU3pWK21mUEhIM3QrJyxcbiAgICAgICAgJ1lWeCt3YXQwQll3QUJwSEF0c0l1TElWbzJSUXFZWllIODV0YXR3QmttNzFISFQzam1sRUF2cjZORkgzOCt2M3MnLFxuICAgICAgICAnM3c0V2wwL3NkSHlhZWlTWEFLQ3hKNFgxZU9kTjdMMXJyYkpvelEvZ0RDRnVWUVAvZGNWNktzc3M4QXc0NDNqRycsXG4gICAgICAgICdBWUJMSFdoNm80R2hBWTYvaDFraWpGMHhEK3VjK3RObVRRblFpMXRFT29UZUlaTVhuU1J3dGs4WEV1SmtrYkFQJyxcbiAgICAgICAgJyt1eXZNZ3lWM3dyazl6a2FUQWluN25yakFFUnhlekZPZEJFT3RuQjFDb3ZKeHRNbitSUnhhTUVHcEM0R25FVHknLFxuICAgICAgICAnTjUrNkZrTHVMY05YaUNRUDc1YWp6T0FOMWFJRC9qdU5qVU5wQmJOcGZxQlY3ajFLK0tuMG45SFlUeVFsOWdoeScsXG4gICAgICAgICcwMjYrLzRjOGFnMkhWK2JnM0JEN2MyVlRWdTl4Qk9ESHNmdTBxOFFsL1FCOVc4dG1ZdWdVNkRlWE1IYWVXUFVIJyxcbiAgICAgICAgJ3BoOThndU05a0YyeUhJaVJCdkFkNWk3d09qd24rSS9JcjZuQlIyeXhKM3AzMUNEVW5VbGJqVFBZZzdtdFF2SFcnLFxuICAgICAgICAnRVkyQ3A0U1dpSkVFR0JFQ0FBa0ZBbEVSdko0Q0d3SUFVZ2tRdEx2RHRES0d0aVZISUFRWkVRSUFCZ1VDVVJHOCcsXG4gICAgICAgICduZ0FLQ1JBTWlNZVIyOTZZMlNqeUFKOVYzd1JKSjJTemF6cWFsNGtoV0dmTHU1UjYvd0NmUVFJUkQyNHlWZHo4JyxcbiAgICAgICAgJzJhKzJlQ3J3eUFMVDJHQWloQUNmUzBuV00zYTBndElUcW5ncEpzUndzK0VwK2VJQW4xNXFEMml0dXR4TmI4TkknLFxuICAgICAgICAnYlIyZ0JCNVFtVkozJyxcbiAgICAgICAgJz1wR0E2JyxcbiAgICAgICAgJy0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS0nXG4gICAgICAgIF0uam9pbihcIlxcblwiKSk7XG5cbiAgdmFyIG1zZzIgPSBvcGVucGdwLnJlYWRBcm1vcmVkUGFja2V0cyhbXG4gICAgICAgICctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS0nLFxuICAgICAgICAnVmVyc2lvbjogR251UEcgdjEuNC4xMSAoR05VL0xpbnV4KScsXG4gICAgICAgICcnLFxuICAgICAgICAna0EwREFBSVJESWpIa2R2ZW1Oa0JyQjFpQjJadmJ5NTBlSFJSRWJ6M1ZFVlRWQ0JFUVZSQklERXlNelExTm9oRycsXG4gICAgICAgICdCQUFSQWdBR0JRSlJFYnozQUFvSkVBeUl4NUhiM3BqWjJUY0FuMzJMcERFdUhlOVFyU1JseXZTdVJFS05PRnd6JyxcbiAgICAgICAgJ0FKOXpoNHpzSzRHSVB1RXU4MVlQTm1Ic2p1N0RZZz09JyxcbiAgICAgICAgJz1XYVN4JyxcbiAgICAgICAgJy0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS0nXG4gICAgICAgIF0uam9pbihcIlxcblwiKSk7XG4gIHZhciBwYWNrZXRsaXN0cyA9IGtleXJpbmcuZ2V0UGFja2V0bGlzdHNGb3JLZXlJZChtc2cyWzBdLnNpZ25pbmdLZXlJZC53cml0ZSgpKTtcbiAgdmFyIHB1YktleSA9IHBhY2tldGxpc3RzWzBdO1xuICBtc2cyWzJdLnZlcmlmeShwdWJLZXlbM10sIG1zZzJbMV0pO1xuICByZXN1bHRbMl0gPSBuZXcgdW5pdC5yZXN1bHQoXCJUZXN0aW5nIGtleXJpbmcgcHVibGljIHN1YmtleSBzdXBwb3J0XCIsXG4gICAgICAgICAgcGFja2V0bGlzdHMgIT09IG51bGwgJiYgXG4gICAgICAgICAgcGFja2V0bGlzdHMubGVuZ3RoID09IDEgJiYgXG4gICAgICAgICAgbXNnMlsyXS52ZXJpZmllZCk7XG4gIHJldHVybiByZXN1bHQ7XG59KTtcblxuIiwidmFyIHVuaXQgPSByZXF1aXJlKCcuLi91bml0LmpzJyk7XG5cbnVuaXQucmVnaXN0ZXIoXCJFbmNyeXB0aW9uL2RlY3J5cHRpb25cIiwgZnVuY3Rpb24oKSB7XG4gIHZhciBvcGVucGdwID0gcmVxdWlyZSgnLi4vLi4vJyk7XG4gIHZhciBrZXlyaW5nID0gcmVxdWlyZSgnLi4vLi4vc3JjL29wZW5wZ3Aua2V5cmluZy5qcycpO1xuICB2YXIgcmVzdWx0ID0gW107XG5cdHZhciBrZXkgPSBvcGVucGdwLmdlbmVyYXRlS2V5UGFpcihvcGVucGdwLmVudW1zLnB1YmxpY0tleS5yc2FfZW5jcnlwdF9zaWduLCA1MTIsIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1Rlc3QgTWNUZXN0aW5ndG9uIDx0ZXN0QGV4YW1wbGUuY29tPicsICdoZWxsbyB3b3JsZCcpO1xuXG5cdHZhciBpbmZvID0gJ1xcbnBhc3NwaHJhc2U6ICcgKyBwYXNzcGhyYXNlICsgJ1xcbidcblx0XHRcdCsgJ3VzZXJpZDogJyArIHVzZXJpZCArICdcXG4nXG5cdFx0XHQrICdtZXNzYWdlOiAnICsgbWVzc2FnZTtcblxuXHRpZighcHJpdl9rZXkuZGVjcnlwdFNlY3JldE1QSXMocGFzc3BocmFzZSkpIHtcblx0XHRyZXR1cm4gbmV3IHRlc3RfcmVzdWx0KCdHZW5lcmF0aW5nIGEgZGVjcnlwdGFibGUgcHJpdmF0ZSBrZXkgZmFpbGVkJ1xuXHRcdFx0KyBpbmZvLFxuXHRcdFx0ZmFsc2UpO1xuXHR9XG5cblx0dmFyIGVuY3J5cHRlZCA9IG9wZW5wZ3Aud3JpdGVfc2lnbmVkX2FuZF9lbmNyeXB0ZWRfbWVzc2FnZShwcml2X2tleSxcblx0XHRwdWJfa2V5LCBtZXNzYWdlKTtcblxuXHRvcGVucGdwLmtleXJpbmcuaW1wb3J0UHVibGljS2V5KGtleS5wdWJsaWNLZXlBcm1vcmVkKVxuXG5cblx0dmFyIG1zZyA9IG9wZW5wZ3AucmVhZF9tZXNzYWdlKGVuY3J5cHRlZCk7XG5cdHZhciBrZXltYXQgPSBudWxsO1xuXHR2YXIgc2Vzc2tleSA9IG51bGw7XG5cblx0Ly8gRmluZCB0aGUgcHJpdmF0ZSAoc3ViKWtleSBmb3IgdGhlIHNlc3Npb24ga2V5IG9mIHRoZSBtZXNzYWdlXG5cdGZvciAodmFyIGkgPSAwOyBpPCBtc2dbMF0uc2Vzc2lvbktleXMubGVuZ3RoOyBpKyspIHtcblx0XHRpZiAocHJpdl9rZXkucHJpdmF0ZUtleVBhY2tldC5wdWJsaWNLZXkuZ2V0S2V5SWQoKSA9PSBtc2dbMF0uc2Vzc2lvbktleXNbaV0ua2V5SWQuYnl0ZXMpIHtcblx0XHRcdGtleW1hdCA9IHsga2V5OiBwcml2X2tleSwga2V5bWF0ZXJpYWw6IHByaXZfa2V5LnByaXZhdGVLZXlQYWNrZXR9O1xuXHRcdFx0c2Vzc2tleSA9IG1zZ1swXS5zZXNzaW9uS2V5c1tpXTtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0XHRmb3IgKHZhciBqID0gMDsgaiA8IHByaXZfa2V5LnN1YktleXMubGVuZ3RoOyBqKyspIHtcblx0XHRcdGlmIChwcml2X2tleS5zdWJLZXlzW2pdLnB1YmxpY0tleS5nZXRLZXlJZCgpID09IG1zZ1swXS5zZXNzaW9uS2V5c1tpXS5rZXlJZC5ieXRlcykge1xuXHRcdFx0XHRrZXltYXQgPSB7IGtleTogcHJpdl9rZXksIGtleW1hdGVyaWFsOiBwcml2X2tleS5zdWJLZXlzW2pdfTtcblx0XHRcdFx0c2Vzc2tleSA9IG1zZ1swXS5zZXNzaW9uS2V5c1tpXTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0dmFyIGRlY3J5cHRlZCA9ICcnO1xuXHRpZiAoa2V5bWF0ICE9PSBudWxsKSB7XG5cdFx0aWYgKCFrZXltYXQua2V5bWF0ZXJpYWwuZGVjcnlwdFNlY3JldE1QSXMocGFzc3BocmFzZSkpIHtcblx0XHRcdHJldHVybiBuZXcgdGVzdF9yZXN1bHQoXCJQYXNzd29yZCBmb3Igc2VjcmVjdCBrZXkgd2FzIGluY29ycmVjdCFcIiwgXG5cdFx0XHRcdCsgaW5mbywgZmFsc2UpO1xuXHRcdH1cblxuXHRcdGRlY3J5cHRlZCA9IG1zZ1swXS5kZWNyeXB0KGtleW1hdCwgc2Vzc2tleSk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIG5ldyB0ZXN0X3Jlc3VsdChcIk5vIHByaXZhdGUga2V5IGZvdW5kIVwiICsgaW5mbywgZmFsc2UpO1xuXHR9XG5cdFx0XG5cdHJlc3VsdC5wdXNoKG5ldyB0ZXN0X3Jlc3VsdChtZXNzYWdlICsgJyA9PSAnICsgZGVjcnlwdGVkICsgaW5mbywgbWVzc2FnZSA9PSBkZWNyeXB0ZWQpKTtcblxuICAvL3Jlc3VsdC5wdXNoKHRlc3QoJ3Bhc3N3b3JkJywgJ1Rlc3QgTWNUZXN0aW5ndG9uIDx0ZXN0QGV4YW1wbGUuY29tPicsICdoZWxsbyB3b3JsZCcpKTtcbiAgLy9yZXN1bHQucHVzaCh0ZXN0KCfil4/il4/il4/il48nLCAn4pmU4pmU4pmU4pmUIDx0ZXN0QGV4YW1wbGUuY29tPicsICfFgsOkw7PEhycpKTtcblxuICByZXR1cm4gcmVzdWx0O1xufSk7XG5cbiIsIm1vZHVsZS5leHBvcnRzPXJlcXVpcmUoJzJaWkNjbScpOyIsInZhciBwcm9jZXNzPXJlcXVpcmUoXCJfX2Jyb3dzZXJpZnlfcHJvY2Vzc1wiKTtcbm1vZHVsZS5leHBvcnRzID0ge1xuXHR0ZXN0czogW10sXG5cdHJlZ2lzdGVyOiBmdW5jdGlvbihzdHJfdGl0bGUsIGZ1bmNfcnVudGVzdCkge1xuXHRcdHRoaXMudGVzdHMucHVzaCh7IHRpdGxlOiBzdHJfdGl0bGUsIHJ1bjogZnVuY19ydW50ZXN0IH0pO1xuXHR9LFxuXHRcblx0cnVuOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgdGVzdCA9IHRoaXMudGVzdHMuc2hpZnQoKTtcblxuXHRcdHZhciByZXN1bHQgPSB7XG5cdFx0XHR0aXRsZTogdGVzdC50aXRsZVxuXHRcdH07XG5cblxuXHRcdHJlc3VsdC50ZXN0cyA9IHRlc3QucnVuKCk7XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9LFxuXG5cdHJ1bl9hbGw6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBwYXNzZWQgPSB0cnVlO1xuXG5cdFx0d2hpbGUodGhpcy50ZXN0cy5sZW5ndGggPiAwKSB7XG5cdFx0XHR2YXIgcmVzdWx0ID0gdGhpcy5ydW4oKTtcblxuXHRcdFx0Y29uc29sZS5sb2coJ1Rlc3Q6ICcgKyByZXN1bHQudGl0bGUpO1xuXG5cdFx0XHRmb3IodmFyIGkgaW4gcmVzdWx0LnRlc3RzKSB7XG5cblx0XHRcdFx0dmFyIHJlcyA9IHJlc3VsdC50ZXN0c1tpXS5yZXN1bHQgP1xuXHRcdFx0XHRcdCdTVUNDRVNTJyA6ICdGQUlMRUQnO1xuXG5cdFx0XHRcdGNvbnNvbGUubG9nKHJlc3VsdC50ZXN0c1tpXS5kZXNjcmlwdGlvbiArICcgJyArIHJlcyk7XG5cblx0XHRcdFx0cGFzc2VkID0gcGFzc2VkICYmIHJlc3VsdC50ZXN0c1tpXS5yZXN1bHQ7XG5cdFx0XHR9XHRcdFx0XHRcblx0XHR9XG5cblx0XHRpZighcGFzc2VkKSBwcm9jZXNzLmV4aXQoMSk7XG5cdH0sXG5cdFx0XG5cdHJlc3VsdDogZnVuY3Rpb24oc3RyX2Rlc2NyaXB0aW9uLCBib29sZWFuX3Jlc3VsdCkge1xuXHRcdHRoaXMuZGVzY3JpcHRpb24gPSBzdHJfZGVzY3JpcHRpb247XG5cdFx0dGhpcy5yZXN1bHQgPSBib29sZWFuX3Jlc3VsdDtcblx0fVxufVxuXG4iLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcblxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG5wcm9jZXNzLm5leHRUaWNrID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY2FuU2V0SW1tZWRpYXRlID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCdcbiAgICAmJiB3aW5kb3cuc2V0SW1tZWRpYXRlO1xuICAgIHZhciBjYW5Qb3N0ID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCdcbiAgICAmJiB3aW5kb3cucG9zdE1lc3NhZ2UgJiYgd2luZG93LmFkZEV2ZW50TGlzdGVuZXJcbiAgICA7XG5cbiAgICBpZiAoY2FuU2V0SW1tZWRpYXRlKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoZikgeyByZXR1cm4gd2luZG93LnNldEltbWVkaWF0ZShmKSB9O1xuICAgIH1cblxuICAgIGlmIChjYW5Qb3N0KSB7XG4gICAgICAgIHZhciBxdWV1ZSA9IFtdO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgaWYgKGV2LnNvdXJjZSA9PT0gd2luZG93ICYmIGV2LmRhdGEgPT09ICdwcm9jZXNzLXRpY2snKSB7XG4gICAgICAgICAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZuID0gcXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBuZXh0VGljayhmbikge1xuICAgICAgICAgICAgcXVldWUucHVzaChmbik7XG4gICAgICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ3Byb2Nlc3MtdGljaycsICcqJyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG59KSgpO1xuXG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59XG5cbi8vIFRPRE8oc2h0eWxtYW4pXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbiJdfQ== ; \ No newline at end of file