UNPKG

@magic-xpa/utils

Version:

magic utils package

290 lines • 35.3 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { ApplicationException, ISO_8859_1_Encoding } from "@magic-xpa/mscorelib"; import { StrUtil } from "./StrUtil"; import { Misc } from "./Misc"; export class Base64 { /** * @param {?} strOrData * @param {?=} encodingOrIsUseEnvCharset * @param {?=} encoding * @return {?} */ static encode(strOrData, encodingOrIsUseEnvCharset, encoding) { if (arguments.length === 2) return Base64.encode_0(strOrData, encodingOrIsUseEnvCharset); else if (arguments.length === 3) return Base64.encode_1(strOrData, encodingOrIsUseEnvCharset, encoding); else return Base64.encode_2(strOrData); } /// <summary> This method encodes the given string using the base64-encoding /// specified in RFC-2045 (Section 6.8). It's used for example in the /// "Basic" authorization scheme. /// </summary> /// <param name="str">the string </param> /// <param name="encoding"> Environment.Encoding </param> /// <returns> the base64-encoded str </returns> /** * @param {?} str * @param {?} encoding * @return {?} */ static encode_0(str, encoding) { return Base64.encode(str, false, encoding); } /// <summary> Encodes string using the base64-encoding. /// If isUseEnvCharset is true, use the specific charset when converting /// string to byte array. (DBCS support) /// </summary> /// <param name="str">the string </param> /// <param name="isUseEnvCharset"> </param> /// <param name="encoding"> Environment.Encoding </param> /// <returns> the base64-encoded str </returns> /** * @param {?} str * @param {?} isUseEnvCharset * @param {?} encoding * @return {?} */ static encode_1(str, isUseEnvCharset, encoding) { /** @type {?} */ let result; if (str === null) { result = null; } else { if (str === "") { result = str; } else { try { /** @type {?} */ let instance = ISO_8859_1_Encoding.ISO_8859_1; /** @type {?} */ let encoding2 = isUseEnvCharset ? encoding : instance; /** @type {?} */ let ba = Base64.encode(encoding2.GetBytes(str)); result = instance.GetString(ba, 0, ba.length); } catch (ex) { throw new ApplicationException(ex.Message); } } } return result; } /// <summary> This method encodes the given byte[] using the base64-encoding /// specified in RFC-2045 (Section 6.8). /// </summary> /// <param name="data">the data </param> /// <returns> the base64-encoded data </returns> /** * @param {?} data * @return {?} */ static encode_2(data) { if (data === null) return null; /** @type {?} */ let dest = new Uint8Array(Math.floor((data.length + 2) / 3) * 4); /** @type {?} */ let sidx = 0; /** @type {?} */ let didx = 0; // 3-byte to 4-byte conversion + 0-63 to ASCII printable conversion while (sidx < data.length - 2) { dest[didx++] = Base64._base64EncMap[Misc.URShift((/** @type {?} */ (data[sidx])), 2) & 63]; dest[didx++] = Base64._base64EncMap[(Misc.URShift((/** @type {?} */ (data[sidx + 1])), 4) & 15) | ((/** @type {?} */ (data[sidx])) << 4 & 63)]; dest[didx++] = Base64._base64EncMap[(Misc.URShift((/** @type {?} */ (data[sidx + 2])), 6) & 3) | ((/** @type {?} */ (data[sidx + 1])) << 2 & 63)]; dest[didx++] = Base64._base64EncMap[(/** @type {?} */ ((data[sidx + 2] & 63)))]; sidx = sidx + 3; } if (sidx < data.length) { dest[didx++] = Base64._base64EncMap[Misc.URShift((/** @type {?} */ (data[sidx])), 2) & 63]; if (sidx < data.length - 1) { dest[didx++] = Base64._base64EncMap[(Misc.URShift((/** @type {?} */ (data[sidx + 1])), 4) & 15) | ((/** @type {?} */ (data[sidx])) << 4 & 63)]; dest[didx++] = Base64._base64EncMap[(/** @type {?} */ (data[sidx + 1])) << 2 & 63]; } else { dest[didx++] = Base64._base64EncMap[(/** @type {?} */ (data[sidx])) << 4 & 63]; } } // add padding while (didx < dest.length) { dest[didx] = 61; didx = didx + 1; } return dest; } /** * @param {?} strOrData * @param {?=} encoding * @return {?} */ static decode(strOrData, encoding) { if (arguments.length === 1 && (strOrData === null || strOrData.constructor === String)) return Base64.decode_0(strOrData); else if (arguments.length === 2) return Base64.decode_1(strOrData, encoding); else return Base64.decode_2(strOrData); } /// <summary> This method decodes the given string using the base64-encoding /// specified in RFC-2045 (Section 6.8). /// </summary> /// <param name="str">the base64-encoded string. </param> /// <returns> the decoded str.</returns> /** * @param {?} str * @return {?} */ static decode_0(str) { return Base64.decode(str, null); } /// <summary> This method decodes the given string using the base64-encoding /// specified in RFC-2045 (Section 6.8). /// </summary> /// <param name="str">the base64-encoded string. </param> /// <param name="encoding">Environment.Encoding or null.</param> /// <returns> the decoded str.</returns> /** * @param {?} str * @param {?} encoding * @return {?} */ static decode_1(str, encoding) { /** @type {?} */ let result; if (str === null) { result = null; } else { if (str === "") { result = str; } else { try { /** @type {?} */ let instance = ISO_8859_1_Encoding.ISO_8859_1; /** @type {?} */ let array = Base64.decode(instance.GetBytes(str)); /** @type {?} */ let encoding2 = (encoding !== null) ? encoding : instance; result = encoding2.GetString(array, 0, array.length); } catch (ex) { throw new ApplicationException(ex.Message); } } } return result; } /// <summary> This method decodes the given byte[] using the base64-encoding /// specified in RFC-2045 (Section 6.8). /// </summary> /// <param name="data">the base64-encoded data.</param> /// <returns> the decoded <var>data</va /** * @param {?} data * @return {?} */ static decode_2(data) { if (data === null) return null; /** @type {?} */ let tail = data.length; while (data[tail - 1] === '='.charCodeAt(0)) { tail = tail - 1; } /** @type {?} */ let dest = new Uint8Array(tail - Math.floor(data.length / 4)); // ASCII printable to 0-63 conversion for (let idx = 0; idx < data.length; idx = idx + 1) { data[idx] = Base64._base64DecMap[data[idx]]; } // 4-byte to 3-byte conversion /** @type {?} */ let sidx = 0; /** @type {?} */ let didx; for (didx = 0; didx < dest.length - 2; didx = didx + 3) { dest[didx] = (((data[sidx] << 2) & 255) | (Misc.URShift(data[sidx + 1], 4) & 3)); dest[didx + 1] = (((data[sidx + 1] << 4) & 255) | (Misc.URShift(data[sidx + 2], 2) & 15)); dest[didx + 2] = (((data[sidx + 2] << 6) & 255) | (data[sidx + 3] & 63)); sidx = sidx + 4; } if (didx < dest.length) dest[didx] = (((data[sidx] << 2) & 255) | (Misc.URShift(data[sidx + 1], 4) & 3)); if ((didx = didx + 1) < dest.length) dest[didx] = (((data[sidx + 1] << 4) & 255) | (Misc.URShift(data[sidx + 2], 2) & 15)); return dest; } /// <summary> decoded and return an hex representation of the data</summary> /** * @param {?} str * @return {?} */ static decodeToHex(str) { if (str === null) return null; if (str === "") return str; return StrUtil.stringToHexaDump(Base64.decode(str), 2); } /// <summary> decodes a string to byte array</summary> /** * @param {?} str * @return {?} */ static decodeToByte(str) { if (str === null) return null; // QCR 740918 if we have and empty expression it is sent from the server as empty string // and changed locally to a string with one blank either way they are not valid base64 encoded // string and should not be decoded. if (str === "" || str === " ") return new Uint8Array(0); try { /** @type {?} */ let instance = ISO_8859_1_Encoding.ISO_8859_1; return Base64.decode(instance.GetBytes(str)); } catch (ex) { throw new ApplicationException(ex.Message); } } /** * @return {?} */ static initializeEncMap() { return new Uint8Array([ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47 ]); } /** * @return {?} */ static initializeDecMap() { /** @type {?} */ let decMap = new Uint8Array(128); for (let i = 0; i < Base64._base64EncMap.length; i = i + 1) { decMap[Base64._base64EncMap[i]] = i; } return decMap; } } Base64._base64EncMap = Base64.initializeEncMap(); Base64._base64DecMap = Base64.initializeDecMap(); if (false) { /** @type {?} */ Base64._base64EncMap; /** @type {?} */ Base64._base64DecMap; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQmFzZTY0LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG1hZ2ljLXhwYS91dGlscy8iLCJzb3VyY2VzIjpbInNyYy9CYXNlNjQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBc0Isb0JBQW9CLEVBQUUsbUJBQW1CLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUNwRyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFFNUIsTUFBTTs7Ozs7OztJQVFKLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBYyxFQUFFLHlCQUErQixFQUFFLFFBQW1CO1FBQ2hGLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDO1lBQ3pCLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDO1FBRS9ELElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQztZQUM5QixNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUseUJBQXlCLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFekUsSUFBSTtZQUNGLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7Ozs7Ozs7Ozs7Ozs7SUFTTyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQVcsRUFBRSxRQUFrQjtRQUNyRCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzdDLENBQUM7Ozs7Ozs7Ozs7Ozs7OztJQVVPLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBVyxFQUFFLGVBQXdCLEVBQUUsUUFBa0I7O1lBQzNFLE1BQWM7UUFDbEIsRUFBRSxDQUFDLENBQUMsR0FBRyxLQUFLLElB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QUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDM0YsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7U0FDbkIsQ0FBQyxDQUFDO0lBRUwsQ0FBQzs7OztJQUVPLE1BQU0sQ0FBQyxnQkFBZ0I7O1lBQ3pCLE1BQU0sR0FBZSxJQUFJLFVBQVUsQ0FBQyxHQUFHLENBQUM7UUFFNUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQVcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ25FLE1BQU0sQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFFRCxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ2hCLENBQUM7O0FBcFBjLG9CQUFhLEdBQWUsTUFBTSxDQUFDLGdCQUFnQixFQUFFLENBQUM7QUFDdEQsb0JBQWEsR0FBZSxNQUFNLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzs7O0lBRHJFLHFCQUFxRTs7SUFDckUscUJBQXFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtFbmNvZGluZywgRXhjZXB0aW9uLCBBcHBsaWNhdGlvbkV4Y2VwdGlvbiwgSVNPXzg4NTlfMV9FbmNvZGluZ30gZnJvbSBcIkBtYWdpYy14cGEvbXNjb3JlbGliXCI7XHJcbmltcG9ydCB7U3RyVXRpbH0gZnJvbSBcIi4vU3RyVXRpbFwiO1xyXG5pbXBvcnQge01pc2N9IGZyb20gXCIuL01pc2NcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBCYXNlNjR7XHJcbiAgcHJpdmF0ZSBzdGF0aWMgX2Jhc2U2NEVuY01hcDogVWludDhBcnJheSA9IEJhc2U2NC5pbml0aWFsaXplRW5jTWFwKCk7XHJcbiAgcHJpdmF0ZSBzdGF0aWMgX2Jhc2U2NERlY01hcDogVWludDhBcnJheSA9IEJhc2U2NC5pbml0aWFsaXplRGVjTWFwKCk7XHJcblxyXG5cclxuICBzdGF0aWMgZW5jb2RlKHN0cjogc3RyaW5nLCBlbmNvZGluZzogRW5jb2RpbmcpOiBzdHJpbmc7XHJcbiAgc3RhdGljIGVuY29kZShzdHI6IHN0cmluZywgaXNVc2VFbnZDaGFyc2V0OiBib29sZWFuLCBlbmNvZGluZzogRW5jb2RpbmcpOiBzdHJpbmc7XHJcbiAgc3RhdGljIGVuY29kZShkYXRhOiBVaW50OEFycmF5KTogVWludDhBcnJheTtcclxuICBzdGF0aWMgZW5jb2RlKHN0ck9yRGF0YTogYW55LCBlbmNvZGluZ09ySXNVc2VFbnZDaGFyc2V0PzogYW55LCBlbmNvZGluZz86IEVuY29kaW5nKTogYW55IHtcclxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyKVxyXG4gICAgICByZXR1cm4gQmFzZTY0LmVuY29kZV8wKHN0ck9yRGF0YSwgZW5jb2RpbmdPcklzVXNlRW52Q2hhcnNldCk7XHJcblxyXG4gICAgZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMylcclxuICAgICAgcmV0dXJuIEJhc2U2NC5lbmNvZGVfMShzdHJPckRhdGEsIGVuY29kaW5nT3JJc1VzZUVudkNoYXJzZXQsIGVuY29kaW5nKTtcclxuXHJcbiAgICBlbHNlXHJcbiAgICAgIHJldHVybiBCYXNlNjQuZW5jb2RlXzIoc3RyT3JEYXRhKTtcclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT4gVGhpcyBtZXRob2QgZW5jb2RlcyB0aGUgZ2l2ZW4gc3RyaW5nIHVzaW5nIHRoZSBiYXNlNjQtZW5jb2RpbmdcclxuICAvLy8gc3BlY2lmaWVkIGluIFJGQy0yMDQ1IChTZWN0aW9uIDYuOCkuIEl0J3MgdXNlZCBmb3IgZXhhbXBsZSBpbiB0aGVcclxuICAvLy8gXCJCYXNpY1wiIGF1dGhvcml6YXRpb24gc2NoZW1lLlxyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwic3RyXCI+dGhlIHN0cmluZyA8L3BhcmFtPlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cImVuY29kaW5nXCI+IEVudmlyb25tZW50LkVuY29kaW5nIDwvcGFyYW0+XHJcbiAgLy8vIDxyZXR1cm5zPiB0aGUgYmFzZTY0LWVuY29kZWQgc3RyIDwvcmV0dXJucz5cclxuICBwcml2YXRlIHN0YXRpYyBlbmNvZGVfMChzdHI6IHN0cmluZywgZW5jb2Rpbmc6IEVuY29kaW5nKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBCYXNlNjQuZW5jb2RlKHN0ciwgZmFsc2UsIGVuY29kaW5nKTtcclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT4gRW5jb2RlcyBzdHJpbmcgdXNpbmcgdGhlIGJhc2U2NC1lbmNvZGluZy5cclxuICAvLy8gSWYgaXNVc2VFbnZDaGFyc2V0IGlzIHRydWUsIHVzZSB0aGUgc3BlY2lmaWMgY2hhcnNldCB3aGVuIGNvbnZlcnRpbmdcclxuICAvLy8gc3RyaW5nIHRvIGJ5dGUgYXJyYXkuIChEQkNTIHN1cHBvcnQpXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJzdHJcIj50aGUgc3RyaW5nIDwvcGFyYW0+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwiaXNVc2VFbnZDaGFyc2V0XCI+IDwvcGFyYW0+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwiZW5jb2RpbmdcIj4gRW52aXJvbm1lbnQuRW5jb2RpbmcgPC9wYXJhbT5cclxuICAvLy8gPHJldHVybnM+IHRoZSBiYXNlNjQtZW5jb2RlZCBzdHIgPC9yZXR1cm5zPlxyXG4gIHByaXZhdGUgc3RhdGljIGVuY29kZV8xKHN0cjogc3RyaW5nLCBpc1VzZUVudkNoYXJzZXQ6IGJvb2xlYW4sIGVuY29kaW5nOiBFbmNvZGluZyk6IHN0cmluZyB7XHJcbiAgICBsZXQgcmVzdWx0OiBzdHJpbmc7XHJcbiAgICBpZiAoc3RyID09PSBudWxsKSB7XHJcbiAgICAgIHJlc3VsdCA9IG51bGw7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgaWYgKHN0ciA9PT0gXCJcIikge1xyXG4gICAgICAgIHJlc3VsdCA9IHN0cjtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgbGV0IGluc3RhbmNlOiBFbmNvZGluZyA9IElTT184ODU5XzFfRW5jb2RpbmcuSVNPXzg4NTlfMTtcclxuICAgICAgICAgIGxldCBlbmNvZGluZzI6IEVuY29kaW5nID0gaXNVc2VFbnZDaGFyc2V0ID8gZW5jb2RpbmcgOiBpbnN0YW5jZTtcclxuICAgICAgICAgIGxldCBiYTogVWludDhBcnJheSA9IEJhc2U2NC5lbmNvZGUoZW5jb2RpbmcyLkdldEJ5dGVzKHN0cikpO1xyXG4gICAgICAgICAgcmVzdWx0ID0gaW5zdGFuY2UuR2V0U3RyaW5nKGJhLCAwLCBiYS5sZW5ndGgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXgpIHtcclxuICAgICAgICAgIHRocm93IG5ldyBBcHBsaWNhdGlvbkV4Y2VwdGlvbihleC5NZXNzYWdlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+IFRoaXMgbWV0aG9kIGVuY29kZXMgdGhlIGdpdmVuIGJ5dGVbXSB1c2luZyB0aGUgYmFzZTY0LWVuY29kaW5nXHJcbiAgLy8vIHNwZWNpZmllZCBpbiBSRkMtMjA0NSAoU2VjdGlvbiA2LjgpLlxyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwiZGF0YVwiPnRoZSBkYXRhIDwvcGFyYW0+XHJcbiAgLy8vIDxyZXR1cm5zPiB0aGUgYmFzZTY0LWVuY29kZWQgZGF0YSA8L3JldHVybnM+XHJcbiAgcHJpdmF0ZSBzdGF0aWMgZW5jb2RlXzIoZGF0YTogVWludDhBcnJheSk6IFVpbnQ4QXJyYXkge1xyXG5cclxuICAgIGlmIChkYXRhID09PSBudWxsKVxyXG4gICAgICByZXR1cm4gbnVsbDtcclxuXHJcbiAgICBsZXQgZGVzdDogVWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KE1hdGguZmxvb3IoKGRhdGEubGVuZ3RoICsgMikgLyAzKSAqIDQpO1xyXG4gICAgbGV0IHNpZHg6IG51bWJlciA9IDA7XHJcbiAgICBsZXQgZGlkeDogbnVtYmVyID0gMDtcclxuXHJcbiAgICAvLyAzLWJ5dGUgdG8gNC1ieXRlIGNvbnZlcnNpb24gKyAwLTYzIHRvIEFTQ0lJIHByaW50YWJsZSBjb252ZXJzaW9uXHJcbiAgICB3aGlsZSAoc2lkeCA8IGRhdGEubGVuZ3RoIC0gMikge1xyXG4gICAgICBkZXN0W2RpZHgrK10gPSBCYXNlNjQuX2Jhc2U2NEVuY01hcFtNaXNjLlVSU2hpZnQoPG51bWJlcj5kYXRhW3NpZHhdLCAyKSAmIDYzXTtcclxuICAgICAgZGVzdFtkaWR4KytdID0gQmFzZTY0Ll9iYXNlNjRFbmNNYXBbKE1pc2MuVVJTaGlmdCg8bnVtYmVyPmRhdGFbc2lkeCArIDFdLCA0KSAmIDE1KSB8ICg8bnVtYmVyPmRhdGFbc2lkeF0gPDwgNCAmIDYzKV07XHJcbiAgICAgIGRlc3RbZGlkeCsrXSA9IEJhc2U2NC5fYmFzZTY0RW5jTWFwWyhNaXNjLlVSU2hpZnQoPG51bWJlcj5kYXRhW3NpZHggKyAyXSwgNikgJiAzKSB8ICg8bnVtYmVyPmRhdGFbc2lkeCArIDFdIDw8IDIgJiA2MyldO1xyXG4gICAgICBkZXN0W2RpZHgrK10gPSBCYXNlNjQuX2Jhc2U2NEVuY01hcFs8bnVtYmVyPihkYXRhW3NpZHggKyAyXSAmIDYzKV07XHJcbiAgICAgIHNpZHggPSBzaWR4ICsgMztcclxuICAgIH1cclxuXHJcbiAgICBpZiAoc2lkeCA8IGRhdGEubGVuZ3RoKSB7XHJcbiAgICAgIGRlc3RbZGlkeCsrXSA9IEJhc2U2NC5fYmFzZTY0RW5jTWFwW01pc2MuVVJTaGlmdCg8bnVtYmVyPmRhdGFbc2lkeF0sIDIpICYgNjNdO1xyXG4gICAgICBpZiAoc2lkeCA8IGRhdGEubGVuZ3RoIC0gMSkge1xyXG4gICAgICAgIGRlc3RbZGlkeCsrXSA9IEJhc2U2NC5fYmFzZTY0RW5jTWFwWyhNaXNjLlVSU2hpZnQoPG51bWJlcj5kYXRhW3NpZHggKyAxXSwgNCkgJiAxNSkgfCAoPG51bWJlcj5kYXRhW3NpZHhdIDw8IDQgJiA2MyldO1xyXG4gICAgICAgIGRlc3RbZGlkeCsrXSA9IEJhc2U2NC5fYmFzZTY0RW5jTWFwWzxudW1iZXI+ZGF0YVtzaWR4ICsgMV0gPDwgMiAmIDYzXTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIHtcclxuICAgICAgICBkZXN0W2RpZHgrK10gPSBCYXNlNjQuX2Jhc2U2NEVuY01hcFs8bnVtYmVyPmRhdGFbc2lkeF0gPDwgNCAmIDYzXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIGFkZCBwYWRkaW5nXHJcbiAgICB3aGlsZSAoZGlkeCA8IGRlc3QubGVuZ3RoKSB7XHJcbiAgICAgIGRlc3RbZGlkeF0gPSA2MTtcclxuICAgICAgZGlkeCA9IGRpZHggKyAxO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBkZXN0O1xyXG4gIH1cclxuXHJcbiAgc3RhdGljIGRlY29kZShzdHI6IHN0cmluZyk6IHN0cmluZztcclxuICBzdGF0aWMgZGVjb2RlKHN0cjogc3RyaW5nLCBlbmNvZGluZzogRW5jb2RpbmcpOiBzdHJpbmc7XHJcbiAgc3RhdGljIGRlY29kZShkYXRhOiBVaW50OEFycmF5KTogVWludDhBcnJheTtcclxuICBzdGF0aWMgZGVjb2RlKHN0ck9yRGF0YTogYW55LCBlbmNvZGluZz86IEVuY29kaW5nKTogYW55IHtcclxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxICYmIChzdHJPckRhdGEgPT09IG51bGwgfHwgc3RyT3JEYXRhLmNvbnN0cnVjdG9yID09PSBTdHJpbmcpKVxyXG4gICAgICByZXR1cm4gQmFzZTY0LmRlY29kZV8wKHN0ck9yRGF0YSk7XHJcblxyXG4gICAgZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMilcclxuICAgICAgcmV0dXJuIEJhc2U2NC5kZWNvZGVfMShzdHJPckRhdGEsIGVuY29kaW5nKTtcclxuXHJcbiAgICBlbHNlXHJcbiAgICAgIHJldHVybiBCYXNlNjQuZGVjb2RlXzIoc3RyT3JEYXRhKTtcclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT4gVGhpcyBtZXRob2QgZGVjb2RlcyB0aGUgZ2l2ZW4gc3RyaW5nIHVzaW5nIHRoZSBiYXNlNjQtZW5jb2RpbmdcclxuICAvLy8gc3BlY2lmaWVkIGluIFJGQy0yMDQ1IChTZWN0aW9uIDYuOCkuXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJzdHJcIj50aGUgYmFzZTY0LWVuY29kZWQgc3RyaW5nLiA8L3BhcmFtPlxyXG4gIC8vLyA8cmV0dXJucz4gdGhlIGRlY29kZWQgc3RyLjwvcmV0dXJucz5cclxuICBwcml2YXRlIHN0YXRpYyBkZWNvZGVfMChzdHI6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gQmFzZTY0LmRlY29kZShzdHIsIG51bGwpO1xyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PiBUaGlzIG1ldGhvZCBkZWNvZGVzIHRoZSBnaXZlbiBzdHJpbmcgdXNpbmcgdGhlIGJhc2U2NC1lbmNvZGluZ1xyXG4gIC8vLyBzcGVjaWZpZWQgaW4gUkZDLTIwNDUgKFNlY3Rpb24gNi44KS5cclxuICAvLy8gPC9zdW1tYXJ5PlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cInN0clwiPnRoZSBiYXNlNjQtZW5jb2RlZCBzdHJpbmcuIDwvcGFyYW0+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwiZW5jb2RpbmdcIj5FbnZpcm9ubWVudC5FbmNvZGluZyBvciBudWxsLjwvcGFyYW0+XHJcbiAgLy8vIDxyZXR1cm5zPiB0aGUgZGVjb2RlZCBzdHIuPC9yZXR1cm5zPlxyXG4gIHByaXZhdGUgc3RhdGljIGRlY29kZV8xKHN0cjogc3RyaW5nLCBlbmNvZGluZzogRW5jb2RpbmcpOiBzdHJpbmcge1xyXG5cclxuICAgIGxldCByZXN1bHQ6IHN0cmluZztcclxuICAgIGlmIChzdHIgPT09IG51bGwpIHtcclxuICAgICAgcmVzdWx0ID0gbnVsbDtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICBpZiAoc3RyID09PSBcIlwiKSB7XHJcbiAgICAgICAgcmVzdWx0ID0gc3RyO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2Uge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBsZXQgaW5zdGFuY2U6IElTT184ODU5XzFfRW5jb2RpbmcgPSBJU09fODg1OV8xX0VuY29kaW5nLklTT184ODU5XzE7XHJcbiAgICAgICAgICBsZXQgYXJyYXk6IFVpbnQ4QXJyYXkgPSBCYXNlNjQuZGVjb2RlKGluc3RhbmNlLkdldEJ5dGVzKHN0cikpO1xyXG4gICAgICAgICAgbGV0IGVuY29kaW5nMjogRW5jb2RpbmcgPSAoZW5jb2RpbmcgIT09IG51bGwpID8gZW5jb2RpbmcgOiBpbnN0YW5jZTtcclxuICAgICAgICAgIHJlc3VsdCA9IGVuY29kaW5nMi5HZXRTdHJpbmcoYXJyYXksIDAsIGFycmF5Lmxlbmd0aCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChleCkge1xyXG4gICAgICAgICAgdGhyb3cgbmV3IEFwcGxpY2F0aW9uRXhjZXB0aW9uKGV4Lk1lc3NhZ2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT4gVGhpcyBtZXRob2QgZGVjb2RlcyB0aGUgZ2l2ZW4gYnl0ZVtdIHVzaW5nIHRoZSBiYXNlNjQtZW5jb2RpbmdcclxuICAvLy8gc3BlY2lmaWVkIGluIFJGQy0yMDQ1IChTZWN0aW9uIDYuOCkuXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJkYXRhXCI+dGhlIGJhc2U2NC1lbmNvZGVkIGRhdGEuPC9wYXJhbT5cclxuICAvLy8gPHJldHVybnM+IHRoZSBkZWNvZGVkIDx2YXI+ZGF0YTwvdmFcclxuICBwcml2YXRlIHN0YXRpYyBkZWNvZGVfMihkYXRhOiBVaW50OEFycmF5KTogVWludDhBcnJheSB7XHJcbiAgICBpZiAoZGF0YSA9PT0gbnVsbClcclxuICAgICAgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgbGV0IHRhaWw6IG51bWJlciA9IGRhdGEubGVuZ3RoO1xyXG4gICAgd2hpbGUgKGRhdGFbdGFpbCAtIDFdID09PSAnPScuY2hhckNvZGVBdCgwKSkge1xyXG4gICAgICB0YWlsID0gdGFpbCAtIDE7XHJcbiAgICB9XHJcbiAgICBsZXQgZGVzdDogVWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KHRhaWwgLSBNYXRoLmZsb29yKGRhdGEubGVuZ3RoIC8gNCkpO1xyXG5cclxuICAgIC8vIEFTQ0lJIHByaW50YWJsZSB0byAwLTYzIGNvbnZlcnNpb25cclxuICAgIGZvciAobGV0IGlkeDogbnVtYmVyID0gMDsgaWR4IDwgZGF0YS5sZW5ndGg7IGlkeCA9IGlkeCArIDEpIHtcclxuICAgICAgZGF0YVtpZHhdID0gQmFzZTY0Ll9iYXNlNjREZWNNYXBbZGF0YVtpZHhdXTtcclxuICAgIH1cclxuXHJcbiAgICAvLyA0LWJ5dGUgdG8gMy1ieXRlIGNvbnZlcnNpb25cclxuICAgIGxldCBzaWR4OiBudW1iZXIgPSAwO1xyXG4gICAgbGV0IGRpZHg6IG51bWJlcjtcclxuICAgIGZvciAoZGlkeCA9IDA7IGRpZHggPCBkZXN0Lmxlbmd0aCAtIDI7IGRpZHggPSBkaWR4ICsgMykge1xyXG4gICAgICBkZXN0W2RpZHhdID0gKCgoZGF0YVtzaWR4XSA8PCAyKSAmIDI1NSkgfCAoTWlzYy5VUlNoaWZ0KGRhdGFbc2lkeCArIDFdLCA0KSAmIDMpKTtcclxuICAgICAgZGVzdFtkaWR4ICsgMV0gPSAoKChkYXRhW3NpZHggKyAxXSA8PCA0KSAmIDI1NSkgfCAoTWlzYy5VUlNoaWZ0KGRhdGFbc2lkeCArIDJdLCAyKSAmIDE1KSk7XHJcbiAgICAgIGRlc3RbZGlkeCArIDJdID0gKCgoZGF0YVtzaWR4ICsgMl0gPDwgNikgJiAyNTUpIHwgKGRhdGFbc2lkeCArIDNdICYgNjMpKTtcclxuICAgICAgc2lkeCA9IHNpZHggKyA0O1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChkaWR4IDwgZGVzdC5sZW5ndGgpXHJcbiAgICAgIGRlc3RbZGlkeF0gPSAoKChkYXRhW3NpZHhdIDw8IDIpICYgMjU1KSB8IChNaXNjLlVSU2hpZnQoZGF0YVtzaWR4ICsgMV0sIDQpICYgMykpO1xyXG4gICAgaWYgKChkaWR4ID0gZGlkeCArIDEpIDwgZGVzdC5sZW5ndGgpXHJcbiAgICAgIGRlc3RbZGlkeF0gPSAoKChkYXRhW3NpZHggKyAxXSA8PCA0KSAmIDI1NSkgfCAoTWlzYy5VUlNoaWZ0KGRhdGFbc2lkeCArIDJdLCAyKSAmIDE1KSk7XHJcblxyXG4gICAgcmV0dXJuIGRlc3Q7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+IGRlY29kZWQgYW5kIHJldHVybiBhbiBoZXggcmVwcmVzZW50YXRpb24gb2YgdGhlIGRhdGE8L3N1bW1hcnk+XHJcbiAgc3RhdGljIGRlY29kZVRvSGV4KHN0cjogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGlmIChzdHIgPT09IG51bGwpXHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgaWYgKHN0ciA9PT0gXCJcIilcclxuICAgICAgcmV0dXJuIHN0cjtcclxuXHJcbiAgICByZXR1cm4gU3RyVXRpbC5zdHJpbmdUb0hleGFEdW1wKEJhc2U2NC5kZWNvZGUoc3RyKSwgMik7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+IGRlY29kZXMgYSBzdHJpbmcgdG8gYnl0ZSBhcnJheTwvc3VtbWFyeT5cclxuICBzdGF0aWMgZGVjb2RlVG9CeXRlKHN0cjogc3RyaW5nKTogVWludDhBcnJheSB7XHJcbiAgICBpZiAoc3RyID09PSBudWxsKVxyXG4gICAgICByZXR1cm4gbnVsbDtcclxuXHJcbiAgICAvLyBRQ1IgNzQwOTE4IGlmIHdlIGhhdmUgYW5kIGVtcHR5IGV4cHJlc3Npb24gaXQgaXMgc2VudCBmcm9tIHRoZSBzZXJ2ZXIgYXMgZW1wdHkgc3RyaW5nXHJcbiAgICAvLyBhbmQgY2hhbmdlZCBsb2NhbGx5IHRvIGEgc3RyaW5nIHdpdGggb25lIGJsYW5rIGVpdGhlciB3YXkgdGhleSBhcmUgbm90IHZhbGlkIGJhc2U2NCBlbmNvZGVkXHJcbiAgICAvLyBzdHJpbmcgYW5kIHNob3VsZCBub3QgYmUgZGVjb2RlZC5cclxuICAgIGlmIChzdHIgPT09IFwiXCIgfHwgc3RyID09PSBcIiBcIilcclxuICAgICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KDApO1xyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIGxldCBpbnN0YW5jZTogRW5jb2RpbmcgPSBJU09fODg1OV8xX0VuY29kaW5nLklTT184ODU5XzE7XHJcbiAgICAgIHJldHVybiBCYXNlNjQuZGVjb2RlKGluc3RhbmNlLkdldEJ5dGVzKHN0cikpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGV4KSB7XHJcbiAgICAgIHRocm93IG5ldyBBcHBsaWNhdGlvbkV4Y2VwdGlvbihleC5NZXNzYWdlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgc3RhdGljIGluaXRpYWxpemVFbmNNYXAoKSB7XHJcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoW1xyXG4gICAgICA2NSwgNjYsIDY3LCA2OCwgNjksIDcwLCA3MSwgNzIsIDczLCA3NCwgNzUsIDc2LCA3NywgNzgsIDc5LCA4MCwgODEsIDgyLCA4MyxcclxuICAgICAgODQsIDg1LCA4NiwgODcsIDg4LCA4OSwgOTAsIDk3LCA5OCwgOTksIDEwMCwgMTAxLCAxMDIsIDEwMywgMTA0LCAxMDUsIDEwNiwgMTA3LCAxMDgsIDEwOSxcclxuICAgICAgMTEwLCAxMTEsIDExMiwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMTE5LCAxMjAsIDEyMSwgMTIyLCA0OCwgNDksIDUwLCA1MSwgNTIsIDUzLCA1NCxcclxuICAgICAgNTUsIDU2LCA1NywgNDMsIDQ3XHJcbiAgICBdKTtcclxuXHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN0YXRpYyBpbml0aWFsaXplRGVjTWFwKCkge1xyXG4gICAgbGV0IGRlY01hcDogVWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KDEyOCk7XHJcblxyXG4gICAgZm9yIChsZXQgaTogbnVtYmVyID0gMDsgaSA8IEJhc2U2NC5fYmFzZTY0RW5jTWFwLmxlbmd0aDsgaSA9IGkgKyAxKSB7XHJcbiAgICAgIGRlY01hcFtCYXNlNjQuX2Jhc2U2NEVuY01hcFtpXV0gPSBpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBkZWNNYXA7XHJcbiAgfVxyXG59XHJcbiJdfQ==