UNPKG

@angular/compiler

Version:

Angular - the compiler library

324 lines • 42.2 kB
/** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { newArray, utf8Encode } from '../util'; import { BigIntExponentiation } from './big_integer'; /** * Return the message id or compute it using the XLIFF1 digest. */ export function digest(message) { return message.id || computeDigest(message); } /** * Compute the message id using the XLIFF1 digest. */ export function computeDigest(message) { return sha1(serializeNodes(message.nodes).join('') + `[${message.meaning}]`); } /** * Return the message id or compute it using the XLIFF2/XMB/$localize digest. */ export function decimalDigest(message) { return message.id || computeDecimalDigest(message); } /** * Compute the message id using the XLIFF2/XMB/$localize digest. */ export function computeDecimalDigest(message) { const visitor = new _SerializerIgnoreIcuExpVisitor(); const parts = message.nodes.map(a => a.visit(visitor, null)); return computeMsgId(parts.join(''), message.meaning); } /** * Serialize the i18n ast to something xml-like in order to generate an UID. * * The visitor is also used in the i18n parser tests * * @internal */ class _SerializerVisitor { visitText(text, context) { return text.value; } visitContainer(container, context) { return `[${container.children.map(child => child.visit(this)).join(', ')}]`; } visitIcu(icu, context) { const strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`); return `{${icu.expression}, ${icu.type}, ${strCases.join(', ')}}`; } visitTagPlaceholder(ph, context) { return ph.isVoid ? `<ph tag name="${ph.startName}"/>` : `<ph tag name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`; } visitPlaceholder(ph, context) { return ph.value ? `<ph name="${ph.name}">${ph.value}</ph>` : `<ph name="${ph.name}"/>`; } visitIcuPlaceholder(ph, context) { return `<ph icu name="${ph.name}">${ph.value.visit(this)}</ph>`; } } const serializerVisitor = new _SerializerVisitor(); export function serializeNodes(nodes) { return nodes.map(a => a.visit(serializerVisitor, null)); } /** * Serialize the i18n ast to something xml-like in order to generate an UID. * * Ignore the ICU expressions so that message IDs stays identical if only the expression changes. * * @internal */ class _SerializerIgnoreIcuExpVisitor extends _SerializerVisitor { visitIcu(icu, context) { let strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`); // Do not take the expression into account return `{${icu.type}, ${strCases.join(', ')}}`; } } /** * Compute the SHA1 of the given string * * see http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf * * WARNING: this function has not been designed not tested with security in mind. * DO NOT USE IT IN A SECURITY SENSITIVE CONTEXT. */ export function sha1(str) { const utf8 = utf8Encode(str); const words32 = bytesToWords32(utf8, Endian.Big); const len = utf8.length * 8; const w = newArray(80); let a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476, e = 0xc3d2e1f0; words32[len >> 5] |= 0x80 << (24 - len % 32); words32[((len + 64 >> 9) << 4) + 15] = len; for (let i = 0; i < words32.length; i += 16) { const h0 = a, h1 = b, h2 = c, h3 = d, h4 = e; for (let j = 0; j < 80; j++) { if (j < 16) { w[j] = words32[i + j]; } else { w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); } const fkVal = fk(j, b, c, d); const f = fkVal[0]; const k = fkVal[1]; const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32); e = d; d = c; c = rol32(b, 30); b = a; a = temp; } a = add32(a, h0); b = add32(b, h1); c = add32(c, h2); d = add32(d, h3); e = add32(e, h4); } return bytesToHexString(words32ToByteString([a, b, c, d, e])); } function fk(index, b, c, d) { if (index < 20) { return [(b & c) | (~b & d), 0x5a827999]; } if (index < 40) { return [b ^ c ^ d, 0x6ed9eba1]; } if (index < 60) { return [(b & c) | (b & d) | (c & d), 0x8f1bbcdc]; } return [b ^ c ^ d, 0xca62c1d6]; } /** * Compute the fingerprint of the given string * * The output is 64 bit number encoded as a decimal string * * based on: * https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/GoogleJsMessageIdGenerator.java */ export function fingerprint(str) { const utf8 = utf8Encode(str); let hi = hash32(utf8, 0); let lo = hash32(utf8, 102072); if (hi == 0 && (lo == 0 || lo == 1)) { hi = hi ^ 0x130f9bef; lo = lo ^ -0x6b5f56d8; } return [hi, lo]; } export function computeMsgId(msg, meaning = '') { let msgFingerprint = fingerprint(msg); if (meaning) { const meaningFingerprint = fingerprint(meaning); msgFingerprint = add64(rol64(msgFingerprint, 1), meaningFingerprint); } const hi = msgFingerprint[0]; const lo = msgFingerprint[1]; return wordsToDecimalString(hi & 0x7fffffff, lo); } function hash32(bytes, c) { let a = 0x9e3779b9, b = 0x9e3779b9; let i; const len = bytes.length; for (i = 0; i + 12 <= len; i += 12) { a = add32(a, wordAt(bytes, i, Endian.Little)); b = add32(b, wordAt(bytes, i + 4, Endian.Little)); c = add32(c, wordAt(bytes, i + 8, Endian.Little)); const res = mix(a, b, c); a = res[0], b = res[1], c = res[2]; } a = add32(a, wordAt(bytes, i, Endian.Little)); b = add32(b, wordAt(bytes, i + 4, Endian.Little)); // the first byte of c is reserved for the length c = add32(c, len); c = add32(c, wordAt(bytes, i + 8, Endian.Little) << 8); return mix(a, b, c)[2]; } // clang-format off function mix(a, b, c) { a = sub32(a, b); a = sub32(a, c); a ^= c >>> 13; b = sub32(b, c); b = sub32(b, a); b ^= a << 8; c = sub32(c, a); c = sub32(c, b); c ^= b >>> 13; a = sub32(a, b); a = sub32(a, c); a ^= c >>> 12; b = sub32(b, c); b = sub32(b, a); b ^= a << 16; c = sub32(c, a); c = sub32(c, b); c ^= b >>> 5; a = sub32(a, b); a = sub32(a, c); a ^= c >>> 3; b = sub32(b, c); b = sub32(b, a); b ^= a << 10; c = sub32(c, a); c = sub32(c, b); c ^= b >>> 15; return [a, b, c]; } // clang-format on // Utils var Endian; (function (Endian) { Endian[Endian["Little"] = 0] = "Little"; Endian[Endian["Big"] = 1] = "Big"; })(Endian || (Endian = {})); function add32(a, b) { return add32to64(a, b)[1]; } function add32to64(a, b) { const low = (a & 0xffff) + (b & 0xffff); const high = (a >>> 16) + (b >>> 16) + (low >>> 16); return [high >>> 16, (high << 16) | (low & 0xffff)]; } function add64(a, b) { const ah = a[0], al = a[1]; const bh = b[0], bl = b[1]; const result = add32to64(al, bl); const carry = result[0]; const l = result[1]; const h = add32(add32(ah, bh), carry); return [h, l]; } function sub32(a, b) { const low = (a & 0xffff) - (b & 0xffff); const high = (a >> 16) - (b >> 16) + (low >> 16); return (high << 16) | (low & 0xffff); } // Rotate a 32b number left `count` position function rol32(a, count) { return (a << count) | (a >>> (32 - count)); } // Rotate a 64b number left `count` position function rol64(num, count) { const hi = num[0], lo = num[1]; const h = (hi << count) | (lo >>> (32 - count)); const l = (lo << count) | (hi >>> (32 - count)); return [h, l]; } function bytesToWords32(bytes, endian) { const size = (bytes.length + 3) >>> 2; const words32 = []; for (let i = 0; i < size; i++) { words32[i] = wordAt(bytes, i * 4, endian); } return words32; } function byteAt(bytes, index) { return index >= bytes.length ? 0 : bytes[index]; } function wordAt(bytes, index, endian) { let word = 0; if (endian === Endian.Big) { for (let i = 0; i < 4; i++) { word += byteAt(bytes, index + i) << (24 - 8 * i); } } else { for (let i = 0; i < 4; i++) { word += byteAt(bytes, index + i) << 8 * i; } } return word; } function words32ToByteString(words32) { return words32.reduce((bytes, word) => bytes.concat(word32ToByteString(word)), []); } function word32ToByteString(word) { let bytes = []; for (let i = 0; i < 4; i++) { bytes.push((word >>> 8 * (3 - i)) & 0xff); } return bytes; } function bytesToHexString(bytes) { let hex = ''; for (let i = 0; i < bytes.length; i++) { const b = byteAt(bytes, i); hex += (b >>> 4).toString(16) + (b & 0x0f).toString(16); } return hex.toLowerCase(); } /** * Create a shared exponentiation pool for base-256 computations. This shared pool provides memoized * power-of-256 results with memoized power-of-two computations for efficient multiplication. * * For our purposes, this can be safely stored as a global without memory concerns. The reason is * that we encode two words, so only need the 0th (for the low word) and 4th (for the high word) * exponent. */ const base256 = new BigIntExponentiation(256); /** * Represents two 32-bit words as a single decimal number. This requires a big integer storage * model as JS numbers are not accurate enough to represent the 64-bit number. * * Based on http://www.danvk.org/hex2dec.html */ function wordsToDecimalString(hi, lo) { // Encode the four bytes in lo in the lower digits of the decimal number. // Note: the multiplication results in lo itself but represented by a big integer using its // decimal digits. const decimal = base256.toThePowerOf(0).multiplyBy(lo); // Encode the four bytes in hi above the four lo bytes. lo is a maximum of (2^8)^4, which is why // this multiplication factor is applied. base256.toThePowerOf(4).multiplyByAndAddTo(hi, decimal); return decimal.toString(); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlnZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL2kxOG4vZGlnZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBTyxRQUFRLEVBQUUsVUFBVSxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBQ25ELE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUluRDs7R0FFRztBQUNILE1BQU0sVUFBVSxNQUFNLENBQUMsT0FBcUI7SUFDMUMsT0FBTyxPQUFPLENBQUMsRUFBRSxJQUFJLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM5QyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUFDLE9BQXFCO0lBQ2pELE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksT0FBTyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7QUFDL0UsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxPQUFxQjtJQUNqRCxPQUFPLE9BQU8sQ0FBQyxFQUFFLElBQUksb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDckQsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUFDLE9BQXFCO0lBQ3hELE1BQU0sT0FBTyxHQUFHLElBQUksOEJBQThCLEVBQUUsQ0FBQztJQUNyRCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDN0QsT0FBTyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMs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LENBQUM7Q0FDRjtBQUVEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsSUFBSSxDQUFDLEdBQVc7SUFDOUIsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzdCLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2pELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBRTVCLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN2QixJQUFJLENBQUMsR0FBRyxVQUFVLEVBQUUsQ0FBQyxHQUFHLFVBQVUsRUFBRSxDQUFDLEdBQUcsVUFBVSxFQUFFLENBQUMsR0FBRyxVQUFVLEVBQUUsQ0FBQyxHQUFHLFVBQVUsQ0FBQztJQUVuRixPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDN0MsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztJQUUzQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFO1FBQzNDLE1BQU0sRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBRTdDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDM0IsSUFBSSxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUNWLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxP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LENBQUM7SUFDcEQsT0FBTyxDQUFDLElBQUksS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUN0RCxDQUFDO0FBRUQsU0FBUyxLQUFLLENBQUMsQ0FBbUIsRUFBRSxDQUFtQjtJQUNyRCxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzQixNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMzQixNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2pDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4QixNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEIsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDdEMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNoQixDQUFDO0FBRUQsU0FBUyxLQUFLLENBQUMsQ0FBUyxFQUFFLENBQVM7SUFDakMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUM7SUFDeEMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLENBQUM7SUFDakQsT0FBTyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsQ0FBQztBQUN2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O0FBQzVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtCeXRlLCBuZXdBcnJheSwgdXRmOEVuY29kZX0gZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQge0JpZ0ludEV4cG9uZW50aWF0aW9ufSBmcm9tICcuL2JpZ19pbnRlZ2VyJztcblxuaW1wb3J0ICogYXMgaTE4biBmcm9tICcuL2kxOG5fYXN0JztcblxuLyoqXG4gKiBSZXR1cm4gdGhlIG1lc3NhZ2UgaWQgb3IgY29tcHV0ZSBpdCB1c2luZyB0aGUgWExJRkYxIGRpZ2VzdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpZ2VzdChtZXNzYWdlOiBpMThuLk1lc3NhZ2UpOiBzdHJpbmcge1xuICByZXR1cm4gbWVzc2FnZS5pZCB8fCBjb21wdXRlRGlnZXN0KG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIENvbXB1dGUgdGhlIG1lc3NhZ2UgaWQgdXNpbmcgdGhlIFhMSUZGMSBkaWdlc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlRGlnZXN0KG1lc3NhZ2U6IGkxOG4uTWVzc2FnZSk6IHN0cmluZyB7XG4gIHJldHVybiBzaGExKHNlcmlhbGl6ZU5vZGVzKG1lc3NhZ2Uubm9kZXMpLmpvaW4oJycpICsgYFske21lc3NhZ2UubWVhbmluZ31dYCk7XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBtZXNzYWdlIGlkIG9yIGNvbXB1dGUgaXQgdXNpbmcgdGhlIFhMSUZGMi9YTUIvJGxvY2FsaXplIGRpZ2VzdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY2ltYWxEaWdlc3QobWVzc2FnZTogaTE4bi5NZXNzYWdlKTogc3RyaW5nIHtcbiAgcmV0dXJuIG1lc3NhZ2UuaWQgfHwgY29tcHV0ZURlY2ltYWxEaWdlc3QobWVzc2FnZSk7XG59XG5cbi8qKlxuICogQ29tcHV0ZSB0aGUgbWVzc2FnZSBpZCB1c2luZyB0aGUgWExJRkYyL1hNQi8kbG9jYWxpemUgZGlnZXN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZURlY2ltYWxEaWdlc3QobWVzc2FnZTogaTE4bi5NZXNzYWdlKTogc3RyaW5nIHtcbiAgY29uc3QgdmlzaXRvciA9IG5ldyBfU2VyaWFsaXplcklnbm9yZUljdUV4cFZpc2l0b3IoKTtcbiAgY29uc3QgcGFydHMgPSBtZXNzYWdlLm5vZGVzLm1hcChhID0+IGEudmlzaXQodmlzaXRvciwgbnVsbCkpO1xuICByZXR1cm4gY29tcHV0ZU1zZ0lkKHBhcnRzLmpvaW4oJycpLCBtZXNzYWdlLm1lYW5pbmcpO1xufVxuXG4vKipcbiAqIFNlcmlhbGl6ZSB0aGUgaTE4biBhc3QgdG8gc29tZXRoaW5nIHhtbC1saWtlIGluIG9yZGVyIHRvIGdlbmVyYXRlIGFuIFVJRC5cbiAqXG4gKiBUaGUgdmlzaXRvciBpcyBhbHNvIHVzZWQgaW4gdGhlIGkxOG4gcGFyc2VyIHRlc3RzXG4gKlxuICogQGludGVybmFsXG4gKi9cbmNsYXNzIF9TZXJpYWxpemVyVmlzaXRvciBpbXBsZW1lbnRzIGkxOG4uVmlzaXRvciB7XG4gIHZpc2l0VGV4dCh0ZXh0OiBpMThuLlRleHQsIGNvbnRleHQ6IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIHRleHQudmFsdWU7XG4gIH1cblxuICB2aXNpdENvbnRhaW5lcihjb250YWluZXI6IGkxOG4uQ29udGFpbmVyLCBjb250ZXh0OiBhbnkpOiBhbnkge1xuICAgIHJldHVybiBgWyR7Y29udGFpbmVyLmNoaWxkcmVuLm1hcChjaGlsZCA9PiBjaGlsZC52aXNpdCh0aGlzKSkuam9pbignLCAnKX1dYDtcbiAgfVxuXG4gIHZpc2l0SWN1KGljdTogaTE4bi5JY3UsIGNvbnRleHQ6IGFueSk6IGFueSB7XG4gICAgY29uc3Qgc3RyQ2FzZXMgPVxuICAgICAgICBPYmplY3Qua2V5cyhpY3UuY2FzZXMpLm1hcCgoazogc3RyaW5nKSA9PiBgJHtrfSB7JHtpY3UuY2FzZXNba10udmlzaXQodGhpcyl9fWApO1xuICAgIHJldHVybiBgeyR7aWN1LmV4cHJlc3Npb259LCAke2ljdS50eXBlfSwgJHtzdHJDYXNlcy5qb2luKCcsICcpfX1gO1xuICB9XG5cbiAgdmlzaXRUYWdQbGFjZWhvbGRlcihwaDogaTE4bi5UYWdQbGFjZWhvbGRlciwgY29udGV4dDogYW55KTogYW55IHtcbiAgICByZXR1cm4gcGguaXNWb2lkID9cbiAgICAgICAgYDxwaCB0YWcgbmFtZT1cIiR7cGguc3RhcnROYW1lfVwiLz5gIDpcbiAgICAgICAgYDxwaCB0YWcgbmFtZT1cIiR7cGguc3RhcnROYW1lfVwiPiR7XG4gICAgICAgICAgICBwaC5jaGlsZHJlbi5tYXAoY2hpbGQgPT4gY2hpbGQudmlzaXQodGhpcykpLmpvaW4oJywgJyl9PC9waCBuYW1lPVwiJHtwaC5jbG9zZU5hbWV9XCI+YDtcbiAgfVxuXG4gIHZpc2l0UGxhY2Vob2xkZXIocGg6IGkxOG4uUGxhY2Vob2xkZXIsIGNvbnRleHQ6IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIHBoLnZhbHVlID8gYDxwaCBuYW1lPVwiJHtwaC5uYW1lfVwiPiR7cGgudmFsdWV9PC9waD5gIDogYDxwaCBuYW1lPVwiJHtwaC5uYW1lfVwiLz5gO1xuICB9XG5cbiAgdmlzaXRJY3VQbGFjZWhvbGRlcihwaDogaTE4bi5JY3VQbGFjZWhvbGRlciwgY29udGV4dD86IGFueSk6IGFueSB7XG4gICAgcmV0dXJuIGA8cGggaWN1IG5hbWU9XCIke3BoLm5hbWV9XCI+JHtwaC52YWx1ZS52aXNpdCh0aGlzKX08L3BoPmA7XG4gIH1cbn1cblxuY29uc3Qgc2VyaWFsaXplclZpc2l0b3IgPSBuZXcgX1NlcmlhbGl6ZXJWaXNpdG9yKCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVOb2Rlcyhub2RlczogaTE4bi5Ob2RlW10pOiBzdHJpbmdbXSB7XG4gIHJldHVybiBub2Rlcy5tYXAoYSA9PiBhLnZpc2l0KHNlcmlhbGl6ZXJWaXNpdG9yLCBudWxsKSk7XG59XG5cbi8qKlxuICogU2VyaWFsaXplIHRoZSBpMThuIGFzdCB0byBzb21ldGhpbmcgeG1sLWxpa2UgaW4gb3JkZXIgdG8gZ2VuZXJhdGUgYW4gVUlELlxuICpcbiAqIElnbm9yZSB0aGUgSUNVIGV4cHJlc3Npb25zIHNvIHRoYXQgbWVzc2FnZSBJRHMgc3RheXMgaWRlbnRpY2FsIGlmIG9ubHkgdGhlIGV4cHJlc3Npb24gY2hhbmdlcy5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuY2xhc3MgX1NlcmlhbGl6ZXJJZ25vcmVJY3VFeHBWaXNpdG9yIGV4dGVuZHMgX1NlcmlhbGl6ZXJWaXNpdG9yIHtcbiAgdmlzaXRJY3UoaWN1OiBpMThuLkljdSwgY29udGV4dDogYW55KTogYW55IHtcbiAgICBsZXQgc3RyQ2FzZXMgPSBPYmplY3Qua2V5cyhpY3UuY2FzZXMpLm1hcCgoazogc3RyaW5nKSA9PiBgJHtrfSB7JHtpY3UuY2FzZXNba10udmlzaXQodGhpcyl9fWApO1xuICAgIC8vIERvIG5vdCB0YWtlIHRoZSBleHByZXNzaW9uIGludG8gYWNjb3VudFxuICAgIHJldHVybiBgeyR7aWN1LnR5cGV9LCAke3N0ckNhc2VzLmpvaW4oJywgJyl9fWA7XG4gIH1cbn1cblxuLyoqXG4gKiBDb21wdXRlIHRoZSBTSEExIG9mIHRoZSBnaXZlbiBzdHJpbmdcbiAqXG4gKiBzZWUgaHR0cDovL2NzcmMubmlzdC5nb3YvcHVibGljYXRpb25zL2ZpcHMvZmlwczE4MC00L2ZpcHMtMTgwLTQucGRmXG4gKlxuICogV0FSTklORzogdGhpcyBmdW5jdGlvbiBoYXMgbm90IGJlZW4gZGVzaWduZWQgbm90IHRlc3RlZCB3aXRoIHNlY3VyaXR5IGluIG1pbmQuXG4gKiAgICAgICAgICBETyBOT1QgVVNFIElUIElOIEEgU0VDVVJJVFkgU0VOU0lUSVZFIENPTlRFWFQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaGExKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgdXRmOCA9IHV0ZjhFbmNvZGUoc3RyKTtcbiAgY29uc3Qgd29yZHMzMiA9IGJ5dGVzVG9Xb3JkczMyKHV0ZjgsIEVuZGlhbi5CaWcpO1xuICBjb25zdCBsZW4gPSB1dGY4Lmxlbmd0aCAqIDg7XG5cbiAgY29uc3QgdyA9IG5ld0FycmF5KDgwKTtcbiAgbGV0IGEgPSAweDY3NDUyMzAxLCBiID0gMHhlZmNkYWI4OSwgYyA9IDB4OThiYWRjZmUsIGQgPSAweDEwMzI1NDc2LCBlID0gMHhjM2QyZTFmMDtcblxuICB3b3JkczMyW2xlbiA+PiA1XSB8PSAweDgwIDw8ICgyNCAtIGxlbiAlIDMyKTtcbiAgd29yZHMzMlsoKGxlbiArIDY0ID4+IDkpIDw8IDQpICsgMTVdID0gbGVuO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgd29yZHMzMi5sZW5ndGg7IGkgKz0gMTYpIHtcbiAgICBjb25zdCBoMCA9IGEsIGgxID0gYiwgaDIgPSBjLCBoMyA9IGQsIGg0ID0gZTtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgODA7IGorKykge1xuICAgICAgaWYgKGogPCAxNikge1xuICAgICAgICB3W2pdID0gd29yZHMzMltpICsgal07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3W2pdID0gcm9sMzIod1tqIC0gM10gXiB3W2ogLSA4XSBeIHdbaiAtIDE0XSBeIHdbaiAtIDE2XSwgMSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZrVmFsID0gZmsoaiwgYiwgYywgZCk7XG4gICAgICBjb25zdCBmID0gZmtWYWxbMF07XG4gICAgICBjb25zdCBrID0gZmtWYWxbMV07XG4gICAgICBjb25zdCB0ZW1wID0gW3JvbDMyKGEsIDUpLCBmLCBlLCBrLCB3W2pdXS5yZWR1Y2UoYWRkMzIpO1xuICAgICAgZSA9IGQ7XG4gICAgICBkID0gYztcbiAgICAgIGMgPSByb2wzMihiLCAzMCk7XG4gICAgICBiID0gYTtcbiAgICAgIGEgPSB0ZW1wO1xuICAgIH1cbiAgICBhID0gYWRkMzIoYSwgaDApO1xuICAgIGIgPSBhZGQzMihiLCBoMSk7XG4gICAgYyA9IGFkZDMyKGMsIGgyKTtcbiAgICBkID0gYWRkMzIoZCwgaDMpO1xuICAgIGUgPSBhZGQzMihlLCBoNCk7XG4gIH1cblxuICByZXR1cm4gYnl0ZXNUb0hleFN0cmluZyh3b3JkczMyVG9CeXRlU3RyaW5nKFthLCBiLCBjLCBkLCBlXSkpO1xufVxuXG5mdW5jdGlvbiBmayhpbmRleDogbnVtYmVyLCBiOiBudW1iZXIsIGM6IG51bWJlciwgZDogbnVtYmVyKTogW251bWJlciwgbnVtYmVyXSB7XG4gIGlmIChpbmRleCA8IDIwKSB7XG4gICAgcmV0dXJuIFsoYiAmIGMpIHwgKH5iICYgZCksIDB4NWE4Mjc5OTldO1xuICB9XG5cbiAgaWYgKGluZGV4IDwgNDApIHtcbiAgICByZXR1cm4gW2IgXiBjIF4gZCwgMHg2ZWQ5ZWJhMV07XG4gIH1cblxuICBpZiAoaW5kZXggPCA2MCkge1xuICAgIHJldHVybiBbKGIgJiBjKSB8IChiICYgZCkgfCAoYyAmIGQpLCAweDhmMWJiY2RjXTtcbiAgfVxuXG4gIHJldHVybiBbYiBeIGMgXiBkLCAweGNhNjJjMWQ2XTtcbn1cblxuLyoqXG4gKiBDb21wdXRlIHRoZSBmaW5nZXJwcmludCBvZiB0aGUgZ2l2ZW4gc3RyaW5nXG4gKlxuICogVGhlIG91dHB1dCBpcyA2NCBiaXQgbnVtYmVyIGVuY29kZWQgYXMgYSBkZWNpbWFsIHN0cmluZ1xuICpcbiAqIGJhc2VkIG9uOlxuICogaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9jbG9zdXJlLWNvbXBpbGVyL2Jsb2IvbWFzdGVyL3NyYy9jb20vZ29vZ2xlL2phdmFzY3JpcHQvanNjb21wL0dvb2dsZUpzTWVzc2FnZUlkR2VuZXJhdG9yLmphdmFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmdlcnByaW50KHN0cjogc3RyaW5nKTogW251bWJlciwgbnVtYmVyXSB7XG4gIGNvbnN0IHV0ZjggPSB1dGY4RW5jb2RlKHN0cik7XG5cbiAgbGV0IGhpID0gaGFzaDMyKHV0ZjgsIDApO1xuICBsZXQgbG8gPSBoYXNoMzIodXRmOCwgMTAyMDcyKTtcblxuICBpZiAoaGkgPT0gMCAmJiAobG8gPT0gMCB8fCBsbyA9PSAxKSkge1xuICAgIGhpID0gaGkgXiAweDEzMGY5YmVmO1xuICAgIGxvID0gbG8gXiAtMHg2YjVmNTZkODtcbiAgfVxuXG4gIHJldHVybiBbaGksIGxvXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVNc2dJZChtc2c6IHN0cmluZywgbWVhbmluZzogc3RyaW5nID0gJycpOiBzdHJpbmcge1xuICBsZXQgbXNnRmluZ2VycHJpbnQgPSBmaW5nZXJwcmludChtc2cpO1xuXG4gIGlmIChtZWFuaW5nKSB7XG4gICAgY29uc3QgbWVhbmluZ0ZpbmdlcnByaW50ID0gZmluZ2VycHJpbnQobWVhbmluZyk7XG4gICAgbXNnRmluZ2VycHJpbnQgPSBhZGQ2NChyb2w2NChtc2dGaW5nZXJwcmludCwgMSksIG1lYW5pbmdGaW5nZXJwcmludCk7XG4gIH1cblxuICBjb25zdCBoaSA9IG1zZ0ZpbmdlcnByaW50WzBdO1xuICBjb25zdCBsbyA9IG1zZ0ZpbmdlcnByaW50WzFdO1xuXG4gIHJldHVybiB3b3Jkc1RvRGVjaW1hbFN0cmluZyhoaSAmIDB4N2ZmZmZmZmYsIGxvKTtcbn1cblxuZnVuY3Rpb24gaGFzaDMyKGJ5dGVzOiBCeXRlW10sIGM6IG51bWJlcik6IG51bWJlciB7XG4gIGxldCBhID0gMHg5ZTM3NzliOSwgYiA9IDB4OWUzNzc5Yjk7XG4gIGxldCBpOiBudW1iZXI7XG5cbiAgY29uc3QgbGVuID0gYnl0ZXMubGVuZ3RoO1xuXG4gIGZvciAoaSA9IDA7IGkgKyAxMiA8PSBsZW47IGkgKz0gMTIpIHtcbiAgICBhID0gYWRkMzIoYSwgd29yZEF0KGJ5dGVzLCBpLCBFbmRpYW4uTGl0dGxlKSk7XG4gICAgYiA9IGFkZDMyKGIsIHdvcmRBdChieXRlcywgaSArIDQsIEVuZGlhbi5MaXR0bGUpKTtcbiAgICBjID0gYWRkMzIoYywgd29yZEF0KGJ5dGVzLCBpICsgOCwgRW5kaWFuLkxpdHRsZSkpO1xuICAgIGNvbnN0IHJlcyA9IG1peChhLCBiLCBjKTtcbiAgICBhID0gcmVzWzBdLCBiID0gcmVzWzFdLCBjID0gcmVzWzJdO1xuICB9XG5cbiAgYSA9IGFkZDMyKGEsIHdvcmRBdChieXRlcywgaSwgRW5kaWFuLkxpdHRsZSkpO1xuICBiID0gYWRkMzIoYiwgd29yZEF0KGJ5dGVzLCBpICsgNCwgRW5kaWFuLkxpdHRsZSkpO1xuICAvLyB0aGUgZmlyc3QgYnl0ZSBvZiBjIGlzIHJlc2VydmVkIGZvciB0aGUgbGVuZ3RoXG4gIGMgPSBhZGQzMihjLCBsZW4pO1xuICBjID0gYWRkMzIoYywgd29yZEF0KGJ5dGVzLCBpICsgOCwgRW5kaWFuLkxpdHRsZSkgPDwgOCk7XG5cbiAgcmV0dXJuIG1peChhLCBiLCBjKVsyXTtcbn1cblxuLy8gY2xhbmctZm9ybWF0IG9mZlxuZnVuY3Rpb24gbWl4KGE6IG51bWJlciwgYjogbnVtYmVyLCBjOiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0ge1xuICBhID0gc3ViMzIoYSwgYik7IGEgPSBzdWIzMihhLCBjKTsgYSBePSBjID4+PiAxMztcbiAgYiA9IHN1YjMyKGIsIGMpOyBiID0gc3ViMzIoYiwgYSk7IGIgXj0gYSA8PCA4O1xuICBjID0gc3ViMzIoYywgYSk7IGMgPSBzdWIzMihjLCBiKTsgYyBePSBiID4+PiAxMztcbiAgYSA9IHN1YjMyKGEsIGIpOyBhID0gc3ViMzIoYSwgYyk7IGEgXj0gYyA+Pj4gMTI7XG4gIGIgPSBzdWIzMihiLCBjKTsgYiA9IHN1YjMyKGIsIGEpOyBiIF49IGEgPDwgMTY7XG4gIGMgPSBzdWIzMihjLCBhKTsgYyA9IHN1YjMyKGMsIGIpOyBjIF49IGIgPj4+IDU7XG4gIGEgPSBzdWIzMihhLCBiKTsgYSA9IHN1YjMyKGEsIGMpOyBhIF49IGMgPj4+IDM7XG4gIGIgPSBzdWIzMihiLCBjKTsgYiA9IHN1YjMyKGIsIGEpOyBiIF49IGEgPDwgMTA7XG4gIGMgPSBzdWIzMihjLCBhKTsgYyA9IHN1YjMyKGMsIGIpOyBjIF49IGIgPj4+IDE1O1xuICByZXR1cm4gW2EsIGIsIGNdO1xufVxuLy8gY2xhbmctZm9ybWF0IG9uXG5cbi8vIFV0aWxzXG5cbmVudW0gRW5kaWFuIHtcbiAgTGl0dGxlLFxuICBCaWcsXG59XG5cbmZ1bmN0aW9uIGFkZDMyKGE6IG51bWJlciwgYjogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIGFkZDMydG82NChhLCBiKVsxXTtcbn1cblxuZnVuY3Rpb24gYWRkMzJ0bzY0KGE6IG51bWJlciwgYjogbnVtYmVyKTogW251bWJlciwgbnVtYmVyXSB7XG4gIGNvbnN0IGxvdyA9IChhICYgMHhmZmZmKSArIChiICYgMHhmZmZmKTtcbiAgY29uc3QgaGlnaCA9IChhID4+PiAxNikgKyAoYiA+Pj4gMTYpICsgKGxvdyA+Pj4gMTYpO1xuICByZXR1cm4gW2hpZ2ggPj4+IDE2LCAoaGlnaCA8PCAxNikgfCAobG93ICYgMHhmZmZmKV07XG59XG5cbmZ1bmN0aW9uIGFkZDY0KGE6IFtudW1iZXIsIG51bWJlcl0sIGI6IFtudW1iZXIsIG51bWJlcl0pOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgY29uc3QgYWggPSBhWzBdLCBhbCA9IGFbMV07XG4gIGNvbnN0IGJoID0gYlswXSwgYmwgPSBiWzFdO1xuICBjb25zdCByZXN1bHQgPSBhZGQzMnRvNjQoYWwsIGJsKTtcbiAgY29uc3QgY2FycnkgPSByZXN1bHRbMF07XG4gIGNvbnN0IGwgPSByZXN1bHRbMV07XG4gIGNvbnN0IGggPSBhZGQzMihhZGQzMihhaCwgYmgpLCBjYXJyeSk7XG4gIHJldHVybiBbaCwgbF07XG59XG5cbmZ1bmN0aW9uIHN1YjMyKGE6IG51bWJlciwgYjogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgbG93ID0gKGEgJiAweGZmZmYpIC0gKGIgJiAweGZmZmYpO1xuICBjb25zdCBoaWdoID0gKGEgPj4gMTYpIC0gKGIgPj4gMTYpICsgKGxvdyA+PiAxNik7XG4gIHJldHVybiAoaGlnaCA8PCAxNikgfCAobG93ICYgMHhmZmZmKTtcbn1cblxuLy8gUm90YXRlIGEgMzJiIG51bWJlciBsZWZ0IGBjb3VudGAgcG9zaXRpb25cbmZ1bmN0aW9uIHJvbDMyKGE6IG51bWJlciwgY291bnQ6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiAoYSA8PCBjb3VudCkgfCAoYSA+Pj4gKDMyIC0gY291bnQpKTtcbn1cblxuLy8gUm90YXRlIGEgNjRiIG51bWJlciBsZWZ0IGBjb3VudGAgcG9zaXRpb25cbmZ1bmN0aW9uIHJvbDY0KG51bTogW251bWJlciwgbnVtYmVyXSwgY291bnQ6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl0ge1xuICBjb25zdCBoaSA9IG51bVswXSwgbG8gPSBudW1bMV07XG4gIGNvbnN0IGggPSAoaGkgPDwgY291bnQpIHwgKGxvID4+PiAoMzIgLSBjb3VudCkpO1xuICBjb25zdCBsID0gKGxvIDw8IGNvdW50KSB8IChoaSA+Pj4gKDMyIC0gY291bnQpKTtcbiAgcmV0dXJuIFtoLCBsXTtcbn1cblxuZnVuY3Rpb24gYnl0ZXNUb1dvcmRzMzIoYnl0ZXM6IEJ5dGVbXSwgZW5kaWFuOiBFbmRpYW4pOiBudW1iZXJbXSB7XG4gIGNvbnN0IHNpemUgPSAoYnl0ZXMubGVuZ3RoICsgMykgPj4+IDI7XG4gIGNvbnN0IHdvcmRzMzIgPSBbXTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemU7IGkrKykge1xuICAgIHdvcmRzMzJbaV0gPSB3b3JkQXQoYnl0ZXMsIGkgKiA0LCBlbmRpYW4pO1xuICB9XG5cbiAgcmV0dXJuIHdvcmRzMzI7XG59XG5cbmZ1bmN0aW9uIGJ5dGVBdChieXRlczogQnl0ZVtdLCBpbmRleDogbnVtYmVyKTogQnl0ZSB7XG4gIHJldHVybiBpbmRleCA+PSBieXRlcy5sZW5ndGggPyAwIDogYnl0ZXNbaW5kZXhdO1xufVxuXG5mdW5jdGlvbiB3b3JkQXQoYnl0ZXM6IEJ5dGVbXSwgaW5kZXg6IG51bWJlciwgZW5kaWFuOiBFbmRpYW4pOiBudW1iZXIge1xuICBsZXQgd29yZCA9IDA7XG4gIGlmIChlbmRpYW4gPT09IEVuZGlhbi5CaWcpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgd29yZCArPSBieXRlQXQoYnl0ZXMsIGluZGV4ICsgaSkgPDwgKDI0IC0gOCAqIGkpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgICAgd29yZCArPSBieXRlQXQoYnl0ZXMsIGluZGV4ICsgaSkgPDwgOCAqIGk7XG4gICAgfVxuICB9XG4gIHJldHVybiB3b3JkO1xufVxuXG5mdW5jdGlvbiB3b3JkczMyVG9CeXRlU3RyaW5nKHdvcmRzMzI6IG51bWJlcltdKTogQnl0ZVtdIHtcbiAgcmV0dXJuIHdvcmRzMzIucmVkdWNlKChieXRlcywgd29yZCkgPT4gYnl0ZXMuY29uY2F0KHdvcmQzMlRvQnl0ZVN0cmluZyh3b3JkKSksIFtdIGFzIEJ5dGVbXSk7XG59XG5cbmZ1bmN0aW9uIHdvcmQzMlRvQnl0ZVN0cmluZyh3b3JkOiBudW1iZXIpOiBCeXRlW10ge1xuICBsZXQgYnl0ZXM6IEJ5dGVbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIGJ5dGVzLnB1c2goKHdvcmQgPj4+IDggKiAoMyAtIGkpKSAmIDB4ZmYpO1xuICB9XG4gIHJldHVybiBieXRlcztcbn1cblxuZnVuY3Rpb24gYnl0ZXNUb0hleFN0cmluZyhieXRlczogQnl0ZVtdKTogc3RyaW5nIHtcbiAgbGV0IGhleDogc3RyaW5nID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBiID0gYnl0ZUF0KGJ5dGVzLCBpKTtcbiAgICBoZXggKz0gKGIgPj4+IDQpLnRvU3RyaW5nKDE2KSArIChiICYgMHgwZikudG9TdHJpbmcoMTYpO1xuICB9XG4gIHJldHVybiBoZXgudG9Mb3dlckNhc2UoKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBzaGFyZWQgZXhwb25lbnRpYXRpb24gcG9vbCBmb3IgYmFzZS0yNTYgY29tcHV0YXRpb25zLiBUaGlzIHNoYXJlZCBwb29sIHByb3ZpZGVzIG1lbW9pemVkXG4gKiBwb3dlci1vZi0yNTYgcmVzdWx0cyB3aXRoIG1lbW9pemVkIHBvd2VyLW9mLXR3byBjb21wdXRhdGlvbnMgZm9yIGVmZmljaWVudCBtdWx0aXBsaWNhdGlvbi5cbiAqXG4gKiBGb3Igb3VyIHB1cnBvc2VzLCB0aGlzIGNhbiBiZSBzYWZlbHkgc3RvcmVkIGFzIGEgZ2xvYmFsIHdpdGhvdXQgbWVtb3J5IGNvbmNlcm5zLiBUaGUgcmVhc29uIGlzXG4gKiB0aGF0IHdlIGVuY29kZSB0d28gd29yZHMsIHNvIG9ubHkgbmVlZCB0aGUgMHRoIChmb3IgdGhlIGxvdyB3b3JkKSBhbmQgNHRoIChmb3IgdGhlIGhpZ2ggd29yZClcbiAqIGV4cG9uZW50LlxuICovXG5jb25zdCBiYXNlMjU2ID0gbmV3IEJpZ0ludEV4cG9uZW50aWF0aW9uKDI1Nik7XG5cbi8qKlxuICogUmVwcmVzZW50cyB0d28gMzItYml0IHdvcmRzIGFzIGEgc2luZ2xlIGRlY2ltYWwgbnVtYmVyLiBUaGlzIHJlcXVpcmVzIGEgYmlnIGludGVnZXIgc3RvcmFnZVxuICogbW9kZWwgYXMgSlMgbnVtYmVycyBhcmUgbm90IGFjY3VyYXRlIGVub3VnaCB0byByZXByZXNlbnQgdGhlIDY0LWJpdCBudW1iZXIuXG4gKlxuICogQmFzZWQgb24gaHR0cDovL3d3dy5kYW52ay5vcmcvaGV4MmRlYy5odG1sXG4gKi9cbmZ1bmN0aW9uIHdvcmRzVG9EZWNpbWFsU3RyaW5nKGhpOiBudW1iZXIsIGxvOiBudW1iZXIpOiBzdHJpbmcge1xuICAvLyBFbmNvZGUgdGhlIGZvdXIgYnl0ZXMgaW4gbG8gaW4gdGhlIGxvd2VyIGRpZ2l0cyBvZiB0aGUgZGVjaW1hbCBudW1iZXIuXG4gIC8vIE5vdGU6IHRoZSBtdWx0aXBsaWNhdGlvbiByZXN1bHRzIGluIGxvIGl0c2VsZiBidXQgcmVwcmVzZW50ZWQgYnkgYSBiaWcgaW50ZWdlciB1c2luZyBpdHNcbiAgLy8gZGVjaW1hbCBkaWdpdHMuXG4gIGNvbnN0IGRlY2ltYWwgPSBiYXNlMjU2LnRvVGhlUG93ZXJPZigwKS5tdWx0aXBseUJ5KGxvKTtcblxuICAvLyBFbmNvZGUgdGhlIGZvdXIgYnl0ZXMgaW4gaGkgYWJvdmUgdGhlIGZvdXIgbG8gYnl0ZXMuIGxvIGlzIGEgbWF4aW11bSBvZiAoMl44KV40LCB3aGljaCBpcyB3aHlcbiAgLy8gdGhpcyBtdWx0aXBsaWNhdGlvbiBmYWN0b3IgaXMgYXBwbGllZC5cbiAgYmFzZTI1Ni50b1RoZVBvd2VyT2YoNCkubXVsdGlwbHlCeUFuZEFkZFRvKGhpLCBkZWNpbWFsKTtcblxuICByZXR1cm4gZGVjaW1hbC50b1N0cmluZygpO1xufVxuIl19