UNPKG

angular-oauth2-oidc

Version:

Support for OAuth 2 and OpenId Connect (OIDC) in Angular. Already prepared for the upcoming OAuth 2.1.

417 lines 54.5 kB
// Credits: https://github.com/dchest/fast-sha256-js/tree/master/src // We add this lib directly b/c the published version of fast-sha256-js // is commonjs and hence leads to a warning about tree-shakability emitted // by the Angular CLI // SHA-256 (+ HMAC and PBKDF2) for JavaScript. // // Written in 2014-2016 by Dmitry Chestnykh. // Public domain, no warranty. // // Functions (accept and return Uint8Arrays): // // sha256(message) -> hash // sha256.hmac(key, message) -> mac // sha256.pbkdf2(password, salt, rounds, dkLen) -> dk // // Classes: // // new sha256.Hash() // new sha256.HMAC(key) // export const digestLength = 32; export const blockSize = 64; // SHA-256 constants const K = new Uint32Array([ 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, ]); function hashBlocks(w, v, p, pos, len) { let a, b, c, d, e, f, g, h, u, i, j, t1, t2; while (len >= 64) { a = v[0]; b = v[1]; c = v[2]; d = v[3]; e = v[4]; f = v[5]; g = v[6]; h = v[7]; for (i = 0; i < 16; i++) { j = pos + i * 4; w[i] = ((p[j] & 0xff) << 24) | ((p[j + 1] & 0xff) << 16) | ((p[j + 2] & 0xff) << 8) | (p[j + 3] & 0xff); } for (i = 16; i < 64; i++) { u = w[i - 2]; t1 = ((u >>> 17) | (u << (32 - 17))) ^ ((u >>> 19) | (u << (32 - 19))) ^ (u >>> 10); u = w[i - 15]; t2 = ((u >>> 7) | (u << (32 - 7))) ^ ((u >>> 18) | (u << (32 - 18))) ^ (u >>> 3); w[i] = ((t1 + w[i - 7]) | 0) + ((t2 + w[i - 16]) | 0); } for (i = 0; i < 64; i++) { t1 = ((((((e >>> 6) | (e << (32 - 6))) ^ ((e >>> 11) | (e << (32 - 11))) ^ ((e >>> 25) | (e << (32 - 25)))) + ((e & f) ^ (~e & g))) | 0) + ((h + ((K[i] + w[i]) | 0)) | 0)) | 0; t2 = ((((a >>> 2) | (a << (32 - 2))) ^ ((a >>> 13) | (a << (32 - 13))) ^ ((a >>> 22) | (a << (32 - 22)))) + ((a & b) ^ (a & c) ^ (b & c))) | 0; h = g; g = f; f = e; e = (d + t1) | 0; d = c; c = b; b = a; a = (t1 + t2) | 0; } v[0] += a; v[1] += b; v[2] += c; v[3] += d; v[4] += e; v[5] += f; v[6] += g; v[7] += h; pos += 64; len -= 64; } return pos; } // Hash implements SHA256 hash algorithm. export class Hash { constructor() { this.digestLength = digestLength; this.blockSize = blockSize; // Note: Int32Array is used instead of Uint32Array for performance reasons. this.state = new Int32Array(8); // hash state this.temp = new Int32Array(64); // temporary state this.buffer = new Uint8Array(128); // buffer for data to hash this.bufferLength = 0; // number of bytes in buffer this.bytesHashed = 0; // number of total bytes hashed this.finished = false; // indicates whether the hash was finalized this.reset(); } // Resets hash state making it possible // to re-use this instance to hash other data. reset() { this.state[0] = 0x6a09e667; this.state[1] = 0xbb67ae85; this.state[2] = 0x3c6ef372; this.state[3] = 0xa54ff53a; this.state[4] = 0x510e527f; this.state[5] = 0x9b05688c; this.state[6] = 0x1f83d9ab; this.state[7] = 0x5be0cd19; this.bufferLength = 0; this.bytesHashed = 0; this.finished = false; return this; } // Cleans internal buffers and re-initializes hash state. clean() { for (let i = 0; i < this.buffer.length; i++) { this.buffer[i] = 0; } for (let i = 0; i < this.temp.length; i++) { this.temp[i] = 0; } this.reset(); } // Updates hash state with the given data. // // Optionally, length of the data can be specified to hash // fewer bytes than data.length. // // Throws error when trying to update already finalized hash: // instance must be reset to use it again. update(data, dataLength = data.length) { if (this.finished) { throw new Error("SHA256: can't update because hash was finished."); } let dataPos = 0; this.bytesHashed += dataLength; if (this.bufferLength > 0) { while (this.bufferLength < 64 && dataLength > 0) { this.buffer[this.bufferLength++] = data[dataPos++]; dataLength--; } if (this.bufferLength === 64) { hashBlocks(this.temp, this.state, this.buffer, 0, 64); this.bufferLength = 0; } } if (dataLength >= 64) { dataPos = hashBlocks(this.temp, this.state, data, dataPos, dataLength); dataLength %= 64; } while (dataLength > 0) { this.buffer[this.bufferLength++] = data[dataPos++]; dataLength--; } return this; } // Finalizes hash state and puts hash into out. // // If hash was already finalized, puts the same value. finish(out) { if (!this.finished) { const bytesHashed = this.bytesHashed; const left = this.bufferLength; const bitLenHi = (bytesHashed / 0x20000000) | 0; const bitLenLo = bytesHashed << 3; const padLength = bytesHashed % 64 < 56 ? 64 : 128; this.buffer[left] = 0x80; for (let i = left + 1; i < padLength - 8; i++) { this.buffer[i] = 0; } this.buffer[padLength - 8] = (bitLenHi >>> 24) & 0xff; this.buffer[padLength - 7] = (bitLenHi >>> 16) & 0xff; this.buffer[padLength - 6] = (bitLenHi >>> 8) & 0xff; this.buffer[padLength - 5] = (bitLenHi >>> 0) & 0xff; this.buffer[padLength - 4] = (bitLenLo >>> 24) & 0xff; this.buffer[padLength - 3] = (bitLenLo >>> 16) & 0xff; this.buffer[padLength - 2] = (bitLenLo >>> 8) & 0xff; this.buffer[padLength - 1] = (bitLenLo >>> 0) & 0xff; hashBlocks(this.temp, this.state, this.buffer, 0, padLength); this.finished = true; } for (let i = 0; i < 8; i++) { out[i * 4 + 0] = (this.state[i] >>> 24) & 0xff; out[i * 4 + 1] = (this.state[i] >>> 16) & 0xff; out[i * 4 + 2] = (this.state[i] >>> 8) & 0xff; out[i * 4 + 3] = (this.state[i] >>> 0) & 0xff; } return this; } // Returns the final hash digest. digest() { const out = new Uint8Array(this.digestLength); this.finish(out); return out; } // Internal function for use in HMAC for optimization. _saveState(out) { for (let i = 0; i < this.state.length; i++) { out[i] = this.state[i]; } } // Internal function for use in HMAC for optimization. _restoreState(from, bytesHashed) { for (let i = 0; i < this.state.length; i++) { this.state[i] = from[i]; } this.bytesHashed = bytesHashed; this.finished = false; this.bufferLength = 0; } } // HMAC implements HMAC-SHA256 message authentication algorithm. export class HMAC { constructor(key) { this.inner = new Hash(); this.outer = new Hash(); this.blockSize = this.inner.blockSize; this.digestLength = this.inner.digestLength; const pad = new Uint8Array(this.blockSize); if (key.length > this.blockSize) { new Hash().update(key).finish(pad).clean(); } else { for (let i = 0; i < key.length; i++) { pad[i] = key[i]; } } for (let i = 0; i < pad.length; i++) { pad[i] ^= 0x36; } this.inner.update(pad); for (let i = 0; i < pad.length; i++) { pad[i] ^= 0x36 ^ 0x5c; } this.outer.update(pad); this.istate = new Uint32Array(8); this.ostate = new Uint32Array(8); this.inner._saveState(this.istate); this.outer._saveState(this.ostate); for (let i = 0; i < pad.length; i++) { pad[i] = 0; } } // Returns HMAC state to the state initialized with key // to make it possible to run HMAC over the other data with the same // key without creating a new instance. reset() { this.inner._restoreState(this.istate, this.inner.blockSize); this.outer._restoreState(this.ostate, this.outer.blockSize); return this; } // Cleans HMAC state. clean() { for (let i = 0; i < this.istate.length; i++) { this.ostate[i] = this.istate[i] = 0; } this.inner.clean(); this.outer.clean(); } // Updates state with provided data. update(data) { this.inner.update(data); return this; } // Finalizes HMAC and puts the result in out. finish(out) { if (this.outer.finished) { this.outer.finish(out); } else { this.inner.finish(out); this.outer.update(out, this.digestLength).finish(out); } return this; } // Returns message authentication code. digest() { const out = new Uint8Array(this.digestLength); this.finish(out); return out; } } // Returns SHA256 hash of data. export function hash(data) { const h = new Hash().update(data); const digest = h.digest(); h.clean(); return digest; } // Function hash is both available as module.hash and as default export. export default hash; // Returns HMAC-SHA256 of data under the key. export function hmac(key, data) { const h = new HMAC(key).update(data); const digest = h.digest(); h.clean(); return digest; } // Fills hkdf buffer like this: // T(1) = HMAC-Hash(PRK, T(0) | info | 0x01) function fillBuffer(buffer, hmac, info, counter) { // Counter is a byte value: check if it overflowed. const num = counter[0]; if (num === 0) { throw new Error('hkdf: cannot expand more'); } // Prepare HMAC instance for new data with old key. hmac.reset(); // Hash in previous output if it was generated // (i.e. counter is greater than 1). if (num > 1) { hmac.update(buffer); } // Hash in info if it exists. if (info) { hmac.update(info); } // Hash in the counter. hmac.update(counter); // Output result to buffer and clean HMAC instance. hmac.finish(buffer); // Increment counter inside typed array, this works properly. counter[0]++; } const hkdfSalt = new Uint8Array(digestLength); // Filled with zeroes. export function hkdf(key, salt = hkdfSalt, info, length = 32) { const counter = new Uint8Array([1]); // HKDF-Extract uses salt as HMAC key, and key as data. const okm = hmac(salt, key); // Initialize HMAC for expanding with extracted key. // Ensure no collisions with `hmac` function. const hmac_ = new HMAC(okm); // Allocate buffer. const buffer = new Uint8Array(hmac_.digestLength); let bufpos = buffer.length; const out = new Uint8Array(length); for (let i = 0; i < length; i++) { if (bufpos === buffer.length) { fillBuffer(buffer, hmac_, info, counter); bufpos = 0; } out[i] = buffer[bufpos++]; } hmac_.clean(); buffer.fill(0); counter.fill(0); return out; } // Derives a key from password and salt using PBKDF2-HMAC-SHA256 // with the given number of iterations. // // The number of bytes returned is equal to dkLen. // // (For better security, avoid dkLen greater than hash length - 32 bytes). export function pbkdf2(password, salt, iterations, dkLen) { const prf = new HMAC(password); const len = prf.digestLength; const ctr = new Uint8Array(4); const t = new Uint8Array(len); const u = new Uint8Array(len); const dk = new Uint8Array(dkLen); for (let i = 0; i * len < dkLen; i++) { const c = i + 1; ctr[0] = (c >>> 24) & 0xff; ctr[1] = (c >>> 16) & 0xff; ctr[2] = (c >>> 8) & 0xff; ctr[3] = (c >>> 0) & 0xff; prf.reset(); prf.update(salt); prf.update(ctr); prf.finish(u); for (let j = 0; j < len; j++) { t[j] = u[j]; } for (let j = 2; j <= iterations; j++) { prf.reset(); prf.update(u).finish(u); for (let k = 0; k < len; k++) { t[k] ^= u[k]; } } for (let j = 0; j < len && i * len + j < dkLen; j++) { dk[i * len + j] = t[j]; } } for (let i = 0; i < len; i++) { t[i] = u[i] = 0; } for (let i = 0; i < 4; i++) { ctr[i] = 0; } prf.clean(); return dk; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFzdC1zaGEyNTZqcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2xpYi9zcmMvdG9rZW4tdmFsaWRhdGlvbi9mYXN0LXNoYTI1NmpzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG9FQUFvRTtBQUNwRSx1RUFBdUU7QUFDdkUsMEVBQTBFO0FBQzFFLHFCQUFxQjtBQUVyQiw4Q0FBOEM7QUFDOUMsRUFBRTtBQUNGLDRDQUE0QztBQUM1Qyw4QkFBOEI7QUFDOUIsRUFBRTtBQUNGLDZDQUE2QztBQUM3QyxFQUFFO0FBQ0YsNEJBQTRCO0FBQzVCLHFDQUFxQztBQUNyQyx1REFBdUQ7QUFDdkQsRUFBRTtBQUNGLFlBQVk7QUFDWixFQUFFO0FBQ0Ysc0JBQXNCO0FBQ3RCLHlCQUF5QjtBQUN6QixFQUFFO0FBQ0YsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQztBQUMvQixNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFDO0FBRTVCLG9CQUFvQjtBQUNwQixNQUFNLENBQUMsR0FBRyxJQUFJLFdBQVcsQ0FBQztJQUN4QixVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVU7SUFDdEUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVO0lBQ3RFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVTtJQUN0RSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVU7SUFDdEUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVO0lBQ3RFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsVUFBVTtJQUN0RSxVQUFV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RSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztvQkFDL0IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFFWixDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDdkQ7UUFFRCxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN2QixFQUFFO2dCQUNBLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUMvQixDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQy9CLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNoQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDckIsQ0FBQyxDQUFDO29CQUNGLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO29CQUNsQyxDQUFDLENB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SUFBSSxDQUFDO1lBQ3RELElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsUUFBUSxLQUFLLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQztZQUN0RCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDckQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBRXJELFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFFN0QsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7U0FDdEI7UUFFRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzFCLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDL0MsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQztZQUMvQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQzlDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMs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LE9BQU8sRUFBRSxDQUFDO0FBQ1osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENyZWRpdHM6IGh0dHBzOi8vZ2l0aHViLmNvbS9kY2hlc3QvZmFzdC1zaGEyNTYtanMvdHJlZS9tYXN0ZXIvc3JjXG4vLyBXZSBhZGQgdGhpcyBsaWIgZGlyZWN0bHkgYi9jIHRoZSBwdWJsaXNoZWQgdmVyc2lvbiBvZiBmYXN0LXNoYTI1Ni1qc1xuLy8gaXMgY29tbW9uanMgYW5kIGhlbmNlIGxlYWRzIHRvIGEgd2FybmluZyBhYm91dCB0cmVlLXNoYWthYmlsaXR5IGVtaXR0ZWRcbi8vIGJ5IHRoZSBBbmd1bGFyIENMSVxuXG4vLyBTSEEtMjU2ICgrIEhNQUMgYW5kIFBCS0RGMikgZm9yIEphdmFTY3JpcHQuXG4vL1xuLy8gV3JpdHRlbiBpbiAyMDE0LTIwMTYgYnkgRG1pdHJ5IENoZXN0bnlraC5cbi8vIFB1YmxpYyBkb21haW4sIG5vIHdhcnJhbnR5LlxuLy9cbi8vIEZ1bmN0aW9ucyAoYWNjZXB0IGFuZCByZXR1cm4gVWludDhBcnJheXMpOlxuLy9cbi8vICAgc2hhMjU2KG1lc3NhZ2UpIC0+IGhhc2hcbi8vICAgc2hhMjU2LmhtYWMoa2V5LCBtZXNzYWdlKSAtPiBtYWNcbi8vICAgc2hhMjU2LnBia2RmMihwYXNzd29yZCwgc2FsdCwgcm91bmRzLCBka0xlbikgLT4gZGtcbi8vXG4vLyAgQ2xhc3Nlczpcbi8vXG4vLyAgIG5ldyBzaGEyNTYuSGFzaCgpXG4vLyAgIG5ldyBzaGEyNTYuSE1BQyhrZXkpXG4vL1xuZXhwb3J0IGNvbnN0IGRpZ2VzdExlbmd0aCA9IDMyO1xuZXhwb3J0IGNvbnN0IGJsb2NrU2l6ZSA9IDY0O1xuXG4vLyBTSEEtMjU2IGNvbnN0YW50c1xuY29uc3QgSyA9IG5ldyBVaW50MzJBcnJheShbXG4gIDB4NDI4YTJmOTgsIDB4NzEzNzQ0OTEsIDB4YjVjMGZiY2YsIDB4ZTliNWRiYTUsIDB4Mzk1NmMyNWIsIDB4NTlmMTExZjEsXG4gIDB4OTIzZjgyYTQsIDB4YWIxYzVlZDUsIDB4ZDgwN2FhOTgsIDB4MTI4MzViMDEsIDB4MjQzMTg1YmUsIDB4NTUwYzdkYzMsXG4gIDB4NzJiZTVkNzQsIDB4ODBkZWIxZmUsIDB4OWJkYzA2YTcsIDB4YzE5YmYxNzQsIDB4ZTQ5YjY5YzEsIDB4ZWZiZTQ3ODYsXG4gIDB4MGZjMTlkYzYsIDB4MjQwY2ExY2MsIDB4MmRlOTJjNmYsIDB4NGE3NDg0YWEsIDB4NWNiMGE5ZGMsIDB4NzZmOTg4ZGEsXG4gIDB4OTgzZTUxNTIsIDB4YTgzMWM2NmQsIDB4YjAwMzI3YzgsIDB4YmY1OTdmYzcsIDB4YzZlMDBiZjMsIDB4ZDVhNzkxNDcsXG4gIDB4MDZjYTYzNTEsIDB4MTQyOTI5NjcsIDB4MjdiNzBhODUsIDB4MmUxYjIxMzgsIDB4NGQyYzZkZmMsIDB4NTMzODBkMTMsXG4gIDB4NjUwYTczNTQsIDB4NzY2YTBhYmIsIDB4ODFjMmM5MmUsIDB4OTI3MjJjODUsIDB4YTJiZmU4YTEsIDB4YTgxYTY2NGIsXG4gIDB4YzI0YjhiNzAsIDB4Yzc2YzUxYTMsIDB4ZDE5MmU4MTksIDB4ZDY5OTA2MjQsIDB4ZjQwZTM1ODUsIDB4MTA2YWEwNzAsXG4gIDB4MTlhNGMxMTYsIDB4MWUzNzZjMDgsIDB4Mjc0ODc3NGMsIDB4MzRiMGJjYjUsIDB4MzkxYzBjYjMsIDB4NGVkOGFhNGEsXG4gIDB4NWI5Y2NhNGYsIDB4NjgyZTZmZjMsIDB4NzQ4ZjgyZWUsIDB4NzhhNTYzNmYsIDB4ODRjODc4MTQsIDB4OGNjNzAyMDgsXG4gIDB4OTBiZWZmZmEsIDB4YTQ1MDZjZWIsIDB4YmVmOWEzZjcsIDB4YzY3MTc4ZjIsXG5dKTtcblxuZnVuY3Rpb24gaGFzaEJsb2NrcyhcbiAgdzogSW50MzJBcnJheSxcbiAgdjogSW50MzJBcnJheSxcbiAgcDogVWludDhBcnJheSxcbiAgcG9zOiBudW1iZXIsXG4gIGxlbjogbnVtYmVyXG4pOiBudW1iZXIge1xuICBsZXQgYTogbnVtYmVyLFxuICAgIGI6IG51bWJlcixcbiAgICBjOiBudW1iZXIsXG4gICAgZDogbnVtYmVyLFxuICAgIGU6IG51bWJlcixcbiAgICBmOiBudW1iZXIsXG4gICAgZzogbnVtYmVyLFxuICAgIGg6IG51bWJlcixcbiAgICB1OiBudW1iZXIsXG4gICAgaTogbnVtYmVyLFxuICAgIGo6IG51bWJlcixcbiAgICB0MTogbnVtYmVyLFxuICAgIHQyOiBudW1iZXI7XG4gIHdoaWxlIChsZW4gPj0gNjQpIHtcbiAgICBhID0gdlswXTtcbiAgICBiID0gdlsxXTtcbiAgICBjID0gdlsyXTtcbiAgICBkID0gdlszXTtcbiAgICBlID0gdls0XTtcbiAgICBmID0gdls1XTtcbiAgICBnID0gdls2XTtcbiAgICBoID0gdls3XTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCAxNjsgaSsrKSB7XG4gICAgICBqID0gcG9zICsgaSAqIDQ7XG4gICAgICB3W2ldID1cbiAgICAgICAgKChwW2pdICYgMHhmZikgPDwgMjQpIHxcbiAgICAgICAgKChwW2ogKyAxXSAmIDB4ZmYpIDw8IDE2KSB8XG4gICAgICAgICgocFtqICsgMl0gJiAweGZmKSA8PCA4KSB8XG4gICAgICAgIChwW2ogKyAzXSAmIDB4ZmYpO1xuICAgIH1cblxuICAgIGZvciAoaSA9IDE2OyBpIDwgNjQ7IGkrKykge1xuICAgICAgdSA9IHdbaSAtIDJdO1xuICAgICAgdDEgPVxuICAgICAgICAoKHUgPj4+IDE3KSB8ICh1IDw8ICgzMiAtIDE3KSkpIF5cbiAgICAgICAgKCh1ID4+PiAxOSkgfCAodSA8PCAoMzIgLSAxOSkpKSBeXG4gICAgICAgICh1ID4+PiAxMCk7XG5cbiAgICAgIHUgPSB3W2kgLSAxNV07XG4gICAgICB0MiA9XG4gICAgICAgICgodSA+Pj4gNykgfCAodSA8PCAoMzIgLSA3KSkpIF5cbiAgICAgICAgKCh1ID4+PiAxOCkgfCAodSA8PCAoMzIgLSAxOCkpKSBeXG4gICAgICAgICh1ID4+PiAzKTtcblxuICAgICAgd1tpXSA9ICgodDEgKyB3W2kgLSA3XSkgfCAwKSArICgodDIgKyB3W2kgLSAxNl0pIHwgMCk7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IDY0OyBpKyspIHtcbiAgICAgIHQxID1cbiAgICAgICAgKCgoKCgoZSA+Pj4gNikgfCAoZSA8PCAoMzIgLSA2KSkpIF5cbiAgICAgICAgICAoKGUgPj4+IDExKSB8IChlIDw8ICgzMiAtIDExKSkpIF5cbiAgICAgICAgICAoKGUgPj4+IDI1KSB8IChlIDw8ICgzMiAtIDI1KSkpKSArXG4gICAgICAgICAgKChlICYgZikgXiAofmUgJiBnKSkpIHxcbiAgICAgICAgICAwKSArXG4gICAgICAgICAgKChoICsgKChLW2ldICsgd1tpXSkgfCAwKSkgfCAwKSkgfFxuICAgICAgICAwO1xuXG4gICAgICB0MiA9XG4gICAgICAgICgoKChhID4+PiAyKSB8IChhIDw8ICgzMiAtIDIpKSkgXlxuICAgICAgICAgICgoYSA+Pj4gMTMpIHwgKGEgPDwgKDMyIC0gMTMpKSkgXlxuICAgICAgICAgICgoYSA+Pj4gMjIpIHwgKGEgPDwgKDMyIC0gMjIpKSkpICtcbiAgICAgICAgICAoKGEgJiBiKSBeIChhICYgYykgXiAoYiAmIGMpKSkgfFxuICAgICAgICAwO1xuXG4gICAgICBoID0gZztcbiAgICAgIGcgPSBmO1xuICAgICAgZiA9IGU7XG4gICAgICBlID0gKGQgKyB0MSkgfCAwO1xuICAgICAgZCA9IGM7XG4gICAgICBjID0gYjtcbiAgICAgIGIgPSBhO1xuICAgICAgYSA9ICh0MSArIHQyKSB8IDA7XG4gICAgfVxuXG4gICAgdlswXSArPSBhO1xuICAgIHZbMV0gKz0gYjtcbiAgICB2WzJdICs9IGM7XG4gICAgdlszXSArPSBkO1xuICAgIHZbNF0gKz0gZTtcbiAgICB2WzVdICs9IGY7XG4gICAgdls2XSArPSBnO1xuICAgIHZbN10gKz0gaDtcblxuICAgIHBvcyArPSA2NDtcbiAgICBsZW4gLT0gNjQ7XG4gIH1cbiAgcmV0dXJuIHBvcztcbn1cblxuLy8gSGFzaCBpbXBsZW1lbnRzIFNIQTI1NiBoYXNoIGFsZ29yaXRobS5cbmV4cG9ydCBjbGFzcyBIYXNoIHtcbiAgZGlnZXN0TGVuZ3RoOiBudW1iZXIgPSBkaWdlc3RMZW5ndGg7XG4gIGJsb2NrU2l6ZTogbnVtYmVyID0gYmxvY2tTaXplO1xuXG4gIC8vIE5vdGU6IEludDMyQXJyYXkgaXMgdXNlZCBpbnN0ZWFkIG9mIFVpbnQzMkFycmF5IGZvciBwZXJmb3JtYW5jZSByZWFzb25zLlxuICBwcml2YXRlIHN0YXRlOiBJbnQzMkFycmF5ID0gbmV3IEludDMyQXJyYXkoOCk7IC8vIGhhc2ggc3RhdGVcbiAgcHJpdmF0ZSB0ZW1wOiBJbnQzMkFycmF5ID0gbmV3IEludDMyQXJyYXkoNjQpOyAvLyB0ZW1wb3Jhcnkgc3RhdGVcbiAgcHJpdmF0ZSBidWZmZXI6IFVpbnQ4QXJyYXkgPSBuZXcgVWludDhBcnJheSgxMjgpOyAvLyBidWZmZXIgZm9yIGRhdGEgdG8gaGFzaFxuICBwcml2YXRlIGJ1ZmZlckxlbmd0aCA9IDA7IC8vIG51bWJlciBvZiBieXRlcyBpbiBidWZmZXJcbiAgcHJpdmF0ZSBieXRlc0hhc2hlZCA9IDA7IC8vIG51bWJlciBvZiB0b3RhbCBieXRlcyBoYXNoZWRcblxuICBmaW5pc2hlZCA9IGZhbHNlOyAvLyBpbmRpY2F0ZXMgd2hldGhlciB0aGUgaGFzaCB3YXMgZmluYWxpemVkXG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5yZXNldCgpO1xuICB9XG5cbiAgLy8gUmVzZXRzIGhhc2ggc3RhdGUgbWFraW5nIGl0IHBvc3NpYmxlXG4gIC8vIHRvIHJlLXVzZSB0aGlzIGluc3RhbmNlIHRvIGhhc2ggb3RoZXIgZGF0YS5cbiAgcmVzZXQoKTogdGhpcyB7XG4gICAgdGhpcy5zdGF0ZVswXSA9IDB4NmEwOWU2Njc7XG4gICAgdGhpcy5zdGF0ZVsxXSA9IDB4YmI2N2FlODU7XG4gICAgdGhpcy5zdGF0ZVsyXSA9IDB4M2M2ZWYzNzI7XG4gICAgdGhpcy5zdGF0ZVszXSA9IDB4YTU0ZmY1M2E7XG4gICAgdGhpcy5zdGF0ZVs0XSA9IDB4NTEwZTUyN2Y7XG4gICAgdGhpcy5zdGF0ZVs1XSA9IDB4OWIwNTY4OGM7XG4gICAgdGhpcy5zdGF0ZVs2XSA9IDB4MWY4M2Q5YWI7XG4gICAgdGhpcy5zdGF0ZVs3XSA9IDB4NWJlMGNkMTk7XG4gICAgdGhpcy5idWZmZXJMZW5ndGggPSAwO1xuICAgIHRoaXMuYnl0ZXNIYXNoZWQgPSAwO1xuICAgIHRoaXMuZmluaXNoZWQgPSBmYWxzZTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIENsZWFucyBpbnRlcm5hbCBidWZmZXJzIGFuZCByZS1pbml0aWFsaXplcyBoYXNoIHN0YXRlLlxuICBjbGVhbigpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYnVmZmVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLmJ1ZmZlcltpXSA9IDA7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50ZW1wLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLnRlbXBbaV0gPSAwO1xuICAgIH1cbiAgICB0aGlzLnJlc2V0KCk7XG4gIH1cblxuICAvLyBVcGRhdGVzIGhhc2ggc3RhdGUgd2l0aCB0aGUgZ2l2ZW4gZGF0YS5cbiAgLy9cbiAgLy8gT3B0aW9uYWxseSwgbGVuZ3RoIG9mIHRoZSBkYXRhIGNhbiBiZSBzcGVjaWZpZWQgdG8gaGFzaFxuICAvLyBmZXdlciBieXRlcyB0aGFuIGRhdGEubGVuZ3RoLlxuICAvL1xuICAvLyBUaHJvd3MgZXJyb3Igd2hlbiB0cnlpbmcgdG8gdXBkYXRlIGFscmVhZHkgZmluYWxpemVkIGhhc2g6XG4gIC8vIGluc3RhbmNlIG11c3QgYmUgcmVzZXQgdG8gdXNlIGl0IGFnYWluLlxuICB1cGRhdGUoZGF0YTogVWludDhBcnJheSwgZGF0YUxlbmd0aDogbnVtYmVyID0gZGF0YS5sZW5ndGgpOiB0aGlzIHtcbiAgICBpZiAodGhpcy5maW5pc2hlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU0hBMjU2OiBjYW4ndCB1cGRhdGUgYmVjYXVzZSBoYXNoIHdhcyBmaW5pc2hlZC5cIik7XG4gICAgfVxuICAgIGxldCBkYXRhUG9zID0gMDtcbiAgICB0aGlzLmJ5dGVzSGFzaGVkICs9IGRhdGFMZW5ndGg7XG4gICAgaWYgKHRoaXMuYnVmZmVyTGVuZ3RoID4gMCkge1xuICAgICAgd2hpbGUgKHRoaXMuYnVmZmVyTGVuZ3RoIDwgNjQgJiYgZGF0YUxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5idWZmZXJbdGhpcy5idWZmZXJMZW5ndGgrK10gPSBkYXRhW2RhdGFQb3MrK107XG4gICAgICAgIGRhdGFMZW5ndGgtLTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmJ1ZmZlckxlbmd0aCA9PT0gNjQpIHtcbiAgICAgICAgaGFzaEJsb2Nrcyh0aGlzLnRlbXAsIHRoaXMuc3RhdGUsIHRoaXMuYnVmZmVyLCAwLCA2NCk7XG4gICAgICAgIHRoaXMuYnVmZmVyTGVuZ3RoID0gMDtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGRhdGFMZW5ndGggPj0gNjQpIHtcbiAgICAgIGRhdGFQb3MgPSBoYXNoQmxvY2tzKHRoaXMudGVtcCwgdGhpcy5zdGF0ZSwgZGF0YSwgZGF0YVBvcywgZGF0YUxlbmd0aCk7XG4gICAgICBkYXRhTGVuZ3RoICU9IDY0O1xuICAgIH1cbiAgICB3aGlsZSAoZGF0YUxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYnVmZmVyW3RoaXMuYnVmZmVyTGVuZ3RoKytdID0gZGF0YVtkYXRhUG9zKytdO1xuICAgICAgZGF0YUxlbmd0aC0tO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIEZpbmFsaXplcyBoYXNoIHN0YXRlIGFuZCBwdXRzIGhhc2ggaW50byBvdXQuXG4gIC8vXG4gIC8vIElmIGhhc2ggd2FzIGFscmVhZHkgZmluYWxpemVkLCBwdXRzIHRoZSBzYW1lIHZhbHVlLlxuICBmaW5pc2gob3V0OiBVaW50OEFycmF5KTogdGhpcyB7XG4gICAgaWYgKCF0aGlzLmZpbmlzaGVkKSB7XG4gICAgICBjb25zdCBieXRlc0hhc2hlZCA9IHRoaXMuYnl0ZXNIYXNoZWQ7XG4gICAgICBjb25zdCBsZWZ0ID0gdGhpcy5idWZmZXJMZW5ndGg7XG4gICAgICBjb25zdCBiaXRMZW5IaSA9IChieXRlc0hhc2hlZCAvIDB4MjAwMDAwMDApIHwgMDtcbiAgICAgIGNvbnN0IGJpdExlbkxvID0gYnl0ZXNIYXNoZWQgPDwgMztcbiAgICAgIGNvbnN0IHBhZExlbmd0aCA9IGJ5dGVzSGFzaGVkICUgNjQgPCA1NiA/IDY0IDogMTI4O1xuXG4gICAgICB0aGlzLmJ1ZmZlcltsZWZ0XSA9IDB4ODA7XG4gICAgICBmb3IgKGxldCBpID0gbGVmdCArIDE7IGkgPCBwYWRMZW5ndGggLSA4OyBpKyspIHtcbiAgICAgICAgdGhpcy5idWZmZXJbaV0gPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5idWZmZXJbcGFkTGVuZ3RoIC0gOF0gPSAoYml0TGVuSGkgPj4+IDI0KSAmIDB4ZmY7XG4gICAgICB0aGlzLmJ1ZmZlcltwYWRMZW5ndGggLSA3XSA9IChiaXRMZW5IaSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIHRoaXMuYnVmZmVyW3BhZExlbmd0aCAtIDZdID0gKGJpdExlbkhpID4+PiA4KSAmIDB4ZmY7XG4gICAgICB0aGlzLmJ1ZmZlcltwYWRMZW5ndGggLSA1XSA9IChiaXRMZW5IaSA+Pj4gMCkgJiAweGZmO1xuICAgICAgdGhpcy5idWZmZXJbcGFkTGVuZ3RoIC0gNF0gPSAoYml0TGVuTG8gPj4+IDI0KSAmIDB4ZmY7XG4gICAgICB0aGlzLmJ1ZmZlcltwYWRMZW5ndGggLSAzXSA9IChiaXRMZW5MbyA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIHRoaXMuYnVmZmVyW3BhZExlbmd0aCAtIDJdID0gKGJpdExlbkxvID4+PiA4KSAmIDB4ZmY7XG4gICAgICB0aGlzLmJ1ZmZlcltwYWRMZW5ndGggLSAxXSA9IChiaXRMZW5MbyA+Pj4gMCkgJiAweGZmO1xuXG4gICAgICBoYXNoQmxvY2tzKHRoaXMudGVtcCwgdGhpcy5zdGF0ZSwgdGhpcy5idWZmZXIsIDAsIHBhZExlbmd0aCk7XG5cbiAgICAgIHRoaXMuZmluaXNoZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgODsgaSsrKSB7XG4gICAgICBvdXRbaSAqIDQgKyAwXSA9ICh0aGlzLnN0YXRlW2ldID4+PiAyNCkgJiAweGZmO1xuICAgICAgb3V0W2kgKiA0ICsgMV0gPSAodGhpcy5zdGF0ZVtpXSA+Pj4gMTYpICYgMHhmZjtcbiAgICAgIG91dFtpICogNCArIDJdID0gKHRoaXMuc3RhdGVbaV0gPj4+IDgpICYgMHhmZjtcbiAgICAgIG91dFtpICogNCArIDNdID0gKHRoaXMuc3RhdGVbaV0gPj4+IDApICYgMHhmZjtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIFJldHVybnMgdGhlIGZpbmFsIGhhc2ggZGlnZXN0LlxuICBkaWdlc3QoKTogVWludDhBcnJheSB7XG4gICAgY29uc3Qgb3V0ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5kaWdlc3RMZW5ndGgpO1xuICAgIHRoaXMuZmluaXNoKG91dCk7XG4gICAgcmV0dXJuIG91dDtcbiAgfVxuXG4gIC8vIEludGVybmFsIGZ1bmN0aW9uIGZvciB1c2UgaW4gSE1BQyBmb3Igb3B0aW1pemF0aW9uLlxuICBfc2F2ZVN0YXRlKG91dDogVWludDMyQXJyYXkpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuc3RhdGUubGVuZ3RoOyBpKyspIHtcbiAgICAgIG91dFtpXSA9IHRoaXMuc3RhdGVbaV07XG4gICAgfVxuICB9XG5cbiAgLy8gSW50ZXJuYWwgZnVuY3Rpb24gZm9yIHVzZSBpbiBITUFDIGZvciBvcHRpbWl6YXRpb24uXG4gIF9yZXN0b3JlU3RhdGUoZnJvbTogVWludDMyQXJyYXksIGJ5dGVzSGFzaGVkOiBudW1iZXIpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuc3RhdGUubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuc3RhdGVbaV0gPSBmcm9tW2ldO1xuICAgIH1cbiAgICB0aGlzLmJ5dGVzSGFzaGVkID0gYnl0ZXNIYXNoZWQ7XG4gICAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuICAgIHRoaXMuYnVmZmVyTGVuZ3RoID0gMDtcbiAgfVxufVxuXG4vLyBITUFDIGltcGxlbWVudHMgSE1BQy1TSEEyNTYgbWVzc2FnZSBhdXRoZW50aWNhdGlvbiBhbGdvcml0aG0uXG5leHBvcnQgY2xhc3MgSE1BQyB7XG4gIHByaXZhdGUgaW5uZXI6IEhhc2ggPSBuZXcgSGFzaCgpO1xuICBwcml2YXRlIG91dGVyOiBIYXNoID0gbmV3IEhhc2goKTtcblxuICBibG9ja1NpemU6IG51bWJlciA9IHRoaXMuaW5uZXIuYmxvY2tTaXplO1xuICBkaWdlc3RMZW5ndGg6IG51bWJlciA9IHRoaXMuaW5uZXIuZGlnZXN0TGVuZ3RoO1xuXG4gIC8vIENvcGllcyBvZiBoYXNoIHN0YXRlcyBhZnRlciBrZXlpbmcuXG4gIC8vIE5lZWQgZm9yIHF1aWNrIHJlc2V0IHdpdGhvdXQgaGFzaGluZyB0aGV5IGtleSBhZ2Fpbi5cbiAgcHJpdmF0ZSBpc3RhdGU6IFVpbnQzMkFycmF5O1xuICBwcml2YXRlIG9zdGF0ZTogVWludDMyQXJyYXk7XG5cbiAgY29uc3RydWN0b3Ioa2V5OiBVaW50OEFycmF5KSB7XG4gICAgY29uc3QgcGFkID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5ibG9ja1NpemUpO1xuICAgIGlmIChrZXkubGVuZ3RoID4gdGhpcy5ibG9ja1NpemUpIHtcbiAgICAgIG5ldyBIYXNoKCkudXBkYXRlKGtleSkuZmluaXNoKHBhZCkuY2xlYW4oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcGFkW2ldID0ga2V5W2ldO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhZC5sZW5ndGg7IGkrKykge1xuICAgICAgcGFkW2ldIF49IDB4MzY7XG4gICAgfVxuICAgIHRoaXMuaW5uZXIudXBkYXRlKHBhZCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhZC5sZW5ndGg7IGkrKykge1xuICAgICAgcGFkW2ldIF49IDB4MzYgXiAweDVjO1xuICAgIH1cbiAgICB0aGlzLm91dGVyLnVwZGF0ZShwYWQpO1xuXG4gICAgdGhpcy5pc3RhdGUgPSBuZXcgVWludDMyQXJyYXkoOCk7XG4gICAgdGhpcy5vc3RhdGUgPSBuZXcgVWludDMyQXJyYXkoOCk7XG5cbiAgICB0aGlzLmlubmVyLl9zYXZlU3RhdGUodGhpcy5pc3RhdGUpO1xuICAgIHRoaXMub3V0ZXIuX3NhdmVTdGF0ZSh0aGlzLm9zdGF0ZSk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhZC5sZW5ndGg7IGkrKykge1xuICAgICAgcGFkW2ldID0gMDtcbiAgICB9XG4gIH1cblxuICAvLyBSZXR1cm5zIEhNQUMgc3RhdGUgdG8gdGhlIHN0YXRlIGluaXRpYWxpemVkIHdpdGgga2V5XG4gIC8vIHRvIG1ha2UgaXQgcG9zc2libGUgdG8gcnVuIEhNQUMgb3ZlciB0aGUgb3RoZXIgZGF0YSB3aXRoIHRoZSBzYW1lXG4gIC8vIGtleSB3aXRob3V0IGNyZWF0aW5nIGEgbmV3IGluc3RhbmNlLlxuICByZXNldCgpOiB0aGlzIHtcbiAgICB0aGlzLmlubmVyLl9yZXN0b3JlU3RhdGUodGhpcy5pc3RhdGUsIHRoaXMuaW5uZXIuYmxvY2tTaXplKTtcbiAgICB0aGlzLm91dGVyLl9yZXN0b3JlU3RhdGUodGhpcy5vc3RhdGUsIHRoaXMub3V0ZXIuYmxvY2tTaXplKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIENsZWFucyBITUFDIHN0YXRlLlxuICBjbGVhbigpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuaXN0YXRlLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLm9zdGF0ZVtpXSA9IHRoaXMuaXN0YXRlW2ldID0gMDtcbiAgICB9XG4gICAgdGhpcy5pbm5lci5jbGVhbigpO1xuICAgIHRoaXMub3V0ZXIuY2xlYW4oKTtcbiAgfVxuXG4gIC8vIFVwZGF0ZXMgc3RhdGUgd2l0aCBwcm92aWRlZCBkYXRhLlxuICB1cGRhdGUoZGF0YTogVWludDhBcnJheSk6IHRoaXMge1xuICAgIHRoaXMuaW5uZXIudXBkYXRlKGRhdGEpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gRmluYWxpemVzIEhNQUMgYW5kIHB1dHMgdGhlIHJlc3VsdCBpbiBvdXQuXG4gIGZpbmlzaChvdXQ6IFVpbnQ4QXJyYXkpOiB0aGlzIHtcbiAgICBpZiAodGhpcy5vdXRlci5maW5pc2hlZCkge1xuICAgICAgdGhpcy5vdXRlci5maW5pc2gob3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pbm5lci5maW5pc2gob3V0KTtcbiAgICAgIHRoaXMub3V0ZXIudXBkYXRlKG91dCwgdGhpcy5kaWdlc3RMZW5ndGgpLmZpbmlzaChvdXQpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIFJldHVybnMgbWVzc2FnZSBhdXRoZW50aWNhdGlvbiBjb2RlLlxuICBkaWdlc3QoKTogVWludDhBcnJheSB7XG4gICAgY29uc3Qgb3V0ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5kaWdlc3RMZW5ndGgpO1xuICAgIHRoaXMuZmluaXNoKG91dCk7XG4gICAgcmV0dXJuIG91dDtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIFNIQTI1NiBoYXNoIG9mIGRhdGEuXG5leHBvcnQgZnVuY3Rpb24gaGFzaChkYXRhOiBVaW50OEFycmF5KTogVWludDhBcnJheSB7XG4gIGNvbnN0IGggPSBuZXcgSGFzaCgpLnVwZGF0ZShkYXRhKTtcbiAgY29uc3QgZGlnZXN0ID0gaC5kaWdlc3QoKTtcbiAgaC5jbGVhbigpO1xuICByZXR1cm4gZGlnZXN0O1xufVxuXG4vLyBGdW5jdGlvbiBoYXNoIGlzIGJvdGggYXZhaWxhYmxlIGFzIG1vZH