UNPKG

@ngodings/ngx-rupiah

Version:

Angular directive mask for currency Rupiah/IDR support for NgModule or Reactive forms, pipe for currency Rupiah/IDR & pipe for terbilang in Rupiah/IDR

292 lines 48.7 kB
import { InputManager } from "./input.manager"; import { RupiahMaskInputMode } from "./rupiah-mask.config"; export class InputService { constructor(htmlInputElement, options) { this.htmlInputElement = htmlInputElement; this.options = options; this.SINGLE_DIGIT_REGEX = new RegExp(/^[0-9\u0660-\u0669\u06F0-\u06F9]$/); this.ONLY_NUMBERS_REGEX = new RegExp(/[^0-9\u0660-\u0669\u06F0-\u06F9]/g); this.PER_AR_NUMBER = new Map(); this.inputManager = new InputManager(htmlInputElement); this.initialize(); } initialize() { this.PER_AR_NUMBER.set("\u06F0", "0"); this.PER_AR_NUMBER.set("\u06F1", "1"); this.PER_AR_NUMBER.set("\u06F2", "2"); this.PER_AR_NUMBER.set("\u06F3", "3"); this.PER_AR_NUMBER.set("\u06F4", "4"); this.PER_AR_NUMBER.set("\u06F5", "5"); this.PER_AR_NUMBER.set("\u06F6", "6"); this.PER_AR_NUMBER.set("\u06F7", "7"); this.PER_AR_NUMBER.set("\u06F8", "8"); this.PER_AR_NUMBER.set("\u06F9", "9"); this.PER_AR_NUMBER.set("\u0660", "0"); this.PER_AR_NUMBER.set("\u0661", "1"); this.PER_AR_NUMBER.set("\u0662", "2"); this.PER_AR_NUMBER.set("\u0663", "3"); this.PER_AR_NUMBER.set("\u0664", "4"); this.PER_AR_NUMBER.set("\u0665", "5"); this.PER_AR_NUMBER.set("\u0666", "6"); this.PER_AR_NUMBER.set("\u0667", "7"); this.PER_AR_NUMBER.set("\u0668", "8"); this.PER_AR_NUMBER.set("\u0669", "9"); } addNumber(keyCode) { const { decimal, precision, inputMode } = this.options; let keyChar = String.fromCharCode(keyCode); const isDecimalChar = keyChar === this.options.decimal; if (!this.rawValue) { this.rawValue = this.applyMask(false, keyChar); let selectionStart = 0; if (inputMode === RupiahMaskInputMode.NATURAL && precision > 0) { selectionStart = this.rawValue.indexOf(decimal); if (isDecimalChar) { selectionStart++; } } this.updateFieldValue(selectionStart); } else { let selectionStart = this.inputSelection.selectionStart; let selectionEnd = this.inputSelection.selectionEnd; const rawValueStart = this.rawValue.substring(0, selectionStart); let rawValueEnd = this.rawValue.substring(selectionEnd, this.rawValue.length); // In natural mode, replace decimals instead of shifting them. const inDecimalPortion = rawValueStart.indexOf(decimal) !== -1; if (inputMode === RupiahMaskInputMode.NATURAL && inDecimalPortion && selectionStart === selectionEnd) { rawValueEnd = rawValueEnd.substring(1); } const newValue = rawValueStart + keyChar + rawValueEnd; let nextSelectionStart = selectionStart + 1; const isDecimalOrThousands = isDecimalChar || keyChar === this.options.thousands; if (isDecimalOrThousands && keyChar === rawValueEnd[0]) { // If the cursor is just before the decimal or thousands separator and the user types the // decimal or thousands separator, move the cursor past it. nextSelectionStart++; } else if (!this.SINGLE_DIGIT_REGEX.test(keyChar)) { // Ignore other non-numbers. return; } this.rawValue = newValue; this.updateFieldValue(nextSelectionStart); } } applyMask(isNumber, rawValue, disablePadAndTrim = false) { let { allowNegative, decimal, precision, prefix, suffix, thousands, min, max, inputMode } = this.options; rawValue = isNumber ? new Number(rawValue).toFixed(precision) : rawValue; let onlyNumbers = rawValue.replace(this.ONLY_NUMBERS_REGEX, ""); if (!onlyNumbers && rawValue !== decimal) { return ""; } if (inputMode === RupiahMaskInputMode.NATURAL && !isNumber && !disablePadAndTrim) { rawValue = this.padOrTrimPrecision(rawValue); onlyNumbers = rawValue.replace(this.ONLY_NUMBERS_REGEX, ""); } let integerPart = onlyNumbers.slice(0, onlyNumbers.length - precision) .replace(/^\u0660*/g, "") .replace(/^\u06F0*/g, "") .replace(/^0*/g, ""); if (integerPart == "") { integerPart = "0"; } let integerValue = parseInt(integerPart); integerPart = integerPart.replace(/\B(?=([0-9\u0660-\u0669\u06F0-\u06F9]{3})+(?![0-9\u0660-\u0669\u06F0-\u06F9]))/g, thousands); if (thousands && integerPart.startsWith(thousands)) { integerPart = integerPart.substring(1); } let newRawValue = integerPart; let decimalPart = onlyNumbers.slice(onlyNumbers.length - precision); let decimalValue = parseInt(decimalPart) || 0; let isNegative = rawValue.indexOf("-") > -1; // Ensure max is at least as large as min. max = (this.isNullOrUndefined(max) || this.isNullOrUndefined(min)) ? max : Math.max(max, min); // Ensure precision number works well with more than 2 digits // 23 / 100... 233 / 1000 and so on const divideBy = Number('1'.padEnd(precision + 1, '0')); // Restrict to the min and max values. let newValue = integerValue + (decimalValue / divideBy); newValue = isNegative ? -newValue : newValue; if (!this.isNullOrUndefined(max) && newValue > max) { return this.applyMask(true, max + ''); } else if (!this.isNullOrUndefined(min) && newValue < min) { return this.applyMask(true, min + ''); } if (precision > 0) { if (newRawValue == "0" && decimalPart.length < precision) { newRawValue += decimal + "0".repeat(precision - 1) + decimalPart; } else { newRawValue += decimal + decimalPart; } } // let isZero = newValue == 0; let operator = (isNegative && allowNegative /*&& !isZero */) ? "-" : ""; return operator + prefix + newRawValue + suffix; } padOrTrimPrecision(rawValue) { let { decimal, precision } = this.options; let decimalIndex = rawValue.lastIndexOf(decimal); if (decimalIndex === -1) { decimalIndex = rawValue.length; rawValue += decimal; } let decimalPortion = rawValue.substring(decimalIndex).replace(this.ONLY_NUMBERS_REGEX, ""); const actualPrecision = decimalPortion.length; if (actualPrecision < precision) { for (let i = actualPrecision; i < precision; i++) { decimalPortion += '0'; } } else if (actualPrecision > precision) { decimalPortion = decimalPortion.substring(0, decimalPortion.length + precision - actualPrecision); } return rawValue.substring(0, decimalIndex) + decimal + decimalPortion; } clearMask(rawValue) { if (this.isNullable() && rawValue === "") return 0; let value = (rawValue || "0").replace(this.options.prefix, "").replace(this.options.suffix, ""); if (this.options.thousands) { value = value.replace(new RegExp("\\" + this.options.thousands, "g"), ""); } if (this.options.decimal) { value = value.replace(this.options.decimal, "."); } this.PER_AR_NUMBER.forEach((val, key) => { const re = new RegExp(key, "g"); value = value.replace(re, val); }); return parseFloat(value); } changeToNegative() { if (this.options.allowNegative /*&& this.rawValue != ""*/ && this.rawValue.charAt(0) != "-" /*&& this.value != 0*/) { // Apply the mask to ensure the min and max values are enforced. this.rawValue = this.applyMask(false, "-" + (this.rawValue ? this.rawValue : '0')); } } changeToPositive() { // Apply the mask to ensure the min and max values are enforced. this.rawValue = this.applyMask(false, this.rawValue.replace("-", "")); } removeNumber(keyCode) { let { decimal, thousands, prefix, suffix, inputMode } = this.options; if (this.isNullable() && this.value == 0) { this.rawValue = ''; return; } let selectionEnd = this.inputSelection.selectionEnd; let selectionStart = this.inputSelection.selectionStart; const suffixStart = this.rawValue.length - suffix.length; selectionEnd = Math.min(suffixStart, Math.max(selectionEnd, prefix.length)); selectionStart = Math.min(suffixStart, Math.max(selectionStart, prefix.length)); // Check if selection was entirely in the prefix or suffix. if (selectionStart === selectionEnd && this.inputSelection.selectionStart !== this.inputSelection.selectionEnd) { this.updateFieldValue(selectionStart); return; } let decimalIndex = this.rawValue.indexOf(decimal); if (decimalIndex === -1) { decimalIndex = this.rawValue.length; } let shiftSelection = 0; let insertChars = ''; const isCursorInDecimals = decimalIndex < selectionEnd; const isCursorImmediatelyAfterDecimalPoint = decimalIndex + 1 === selectionEnd; if (selectionEnd === selectionStart) { if (keyCode == 8) { if (selectionStart <= prefix.length) { return; } selectionStart--; // If previous char isn't a number, go back one more. if (!this.rawValue.substr(selectionStart, 1).match(/\d/)) { selectionStart--; } // In natural mode, jump backwards when in decimal portion of number. if (inputMode === RupiahMaskInputMode.NATURAL && isCursorInDecimals) { shiftSelection = -1; // when removing a single whole number, replace it with 0 if (isCursorImmediatelyAfterDecimalPoint && this.value < 10 && this.value > -10) { insertChars += '0'; } } } else if (keyCode == 46 || keyCode == 63272) { if (selectionStart === suffixStart) { return; } selectionEnd++; // If next char isn't a number, go one more. if (!this.rawValue.substr(selectionStart, 1).match(/\d/)) { selectionStart++; selectionEnd++; } } } // In natural mode, replace decimals with 0s. if (inputMode === RupiahMaskInputMode.NATURAL && selectionStart > decimalIndex) { const replacedDecimalCount = selectionEnd - selectionStart; for (let i = 0; i < replacedDecimalCount; i++) { insertChars += '0'; } } let selectionFromEnd = this.rawValue.length - selectionEnd; this.rawValue = this.rawValue.substring(0, selectionStart) + insertChars + this.rawValue.substring(selectionEnd); // Remove leading thousand separator from raw value. const startChar = this.rawValue.substr(prefix.length, 1); if (startChar === thousands) { this.rawValue = this.rawValue.substring(0, prefix.length) + this.rawValue.substring(prefix.length + 1); selectionFromEnd = Math.min(selectionFromEnd, this.rawValue.length - prefix.length); } this.updateFieldValue(this.rawValue.length - selectionFromEnd + shiftSelection, true); } updateFieldValue(selectionStart, disablePadAndTrim = false) { let newRawValue = this.applyMask(false, this.rawValue || "", disablePadAndTrim); selectionStart = selectionStart == undefined ? this.rawValue.length : selectionStart; selectionStart = Math.max(this.options.prefix.length, Math.min(selectionStart, this.rawValue.length - this.options.suffix.length)); this.inputManager.updateValueAndCursor(newRawValue, this.rawValue.length, selectionStart); } updateOptions(options) { let value = this.value; this.options = options; this.value = value; } prefixLength() { return this.options.prefix.length; } suffixLength() { return this.options.suffix.length; } isNullable() { return this.options.nullable; } get canInputMoreNumbers() { return this.inputManager.canInputMoreNumbers; } get inputSelection() { return this.inputManager.inputSelection; } get rawValue() { return this.inputManager.rawValue; } set rawValue(value) { this.inputManager.rawValue = value; } get storedRawValue() { return this.inputManager.storedRawValue; } get value() { return this.clearMask(this.rawValue); } set value(value) { this.rawValue = this.applyMask(true, "" + value); } isNullOrUndefined(value) { return value === null || value === undefined; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL25neC1ydXBpYWgvc3JjL2xpYi9pbnB1dC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQW9CLG1CQUFtQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFN0UsTUFBTSxPQUFPLFlBQVk7SUFnQ3JCLFlBQW9CLGdCQUFxQixFQUFVLE9BQXlCO1FBQXhELHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBSztRQUFVLFlBQU8sR0FBUCxPQUFPLENBQWtCO1FBL0JwRSx1QkFBa0IsR0FBVyxJQUFJLE1BQU0sQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1FBQzdFLHVCQUFrQixHQUFXLElBQUksTUFBTSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7UUFFckYsa0JBQWEsR0FBd0IsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUE2QjNELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxZQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUE7SUFDckIsQ0FBQztJQTdCRCxVQUFVO1FBQ04sSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN0QyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN0QyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN0QyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBRXRDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN0QyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN0QyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN0QyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFB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QUFDLFlBQVksQ0FBQyxjQUFjLENBQUM7SUFDNUMsQ0FBQztJQUVELElBQUksUUFBUTtRQUNSLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUM7SUFDdEMsQ0FBQztJQUVELElBQUksUUFBUSxDQUFDLEtBQWE7UUFDdEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxJQUFJLGNBQWM7UUFDZCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDO0lBQzVDLENBQUM7SUFFRCxJQUFJLEtBQUs7UUFDTCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxJQUFJLEtBQUssQ0FBQyxLQUFhO1FBQ25CLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxHQUFHLEtBQUssQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFFTyxpQkFBaUIsQ0FBQyxLQUFVO1FBQ2hDLE9BQU8sS0FBSyxLQUFLLElBQUksSUFBSSxLQUFLLEtBQUssU0FBUyxDQUFDO0lBQ2pELENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElucHV0TWFuYWdlciB9IGZyb20gXCIuL2lucHV0Lm1hbmFnZXJcIjtcbmltcG9ydCB7IFJ1cGlhaE1hc2tDb25maWcsIFJ1cGlhaE1hc2tJbnB1dE1vZGUgfSBmcm9tIFwiLi9ydXBpYWgtbWFzay5jb25maWdcIjtcblxuZXhwb3J0IGNsYXNzIElucHV0U2VydmljZSB7XG4gICAgcHJpdmF0ZSBTSU5HTEVfRElHSVRfUkVHRVg6IFJlZ0V4cCA9IG5ldyBSZWdFeHAoL15bMC05XFx1MDY2MC1cXHUwNjY5XFx1MDZGMC1cXHUwNkY5XSQvKTtcbiAgICBwcml2YXRlIE9OTFlfTlVNQkVSU19SRUdFWDogUmVnRXhwID0gbmV3IFJlZ0V4cCgvW14wLTlcXHUwNjYwLVxcdTA2NjlcXHUwNkYwLVxcdTA2RjldL2cpO1xuXG4gICAgUEVSX0FSX05VTUJFUjogTWFwPHN0cmluZywgc3RyaW5nPiA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG5cbiAgICBpbml0aWFsaXplKCkge1xuICAgICAgICB0aGlzLlBFUl9BUl9OVU1CRVIuc2V0KFwiXFx1MDZGMFwiLCBcIjBcIik7XG4gICAgICAgIHRoaXMuUEVSX0FSX05VTUJFUi5zZXQoXCJcXHUwNkYxXCIsIFwiMVwiKTtcbiAgICAgICAgdGhpcy5QRVJfQVJfTlVNQkVSLnNldChcIlxcdTA2RjJcIiwgXCIyXCIpO1xuICAgICAgICB0aGlzLlBFUl9BUl9OVU1CRVIuc2V0KFwiXFx1MDZGM1wiLCBcIjNcIik7XG4gICAgICAgIHRoaXMuUEVSX0FSX05VTUJFUi5zZXQoXCJcXHUwNkY0XCIsIFwiNFwiKTtcbiAgICAgICAgdGhpcy5QRVJfQVJfTlVNQkVSLnNldChcIlxcdTA2RjVcIiwgXCI1XCIpO1xuICAgICAgICB0aGlzLlBFUl9BUl9OVU1CRVIuc2V0KFwiXFx1MDZGNlwiLCBcIjZcIik7XG4gICAgICAgIHRoaXMuUEVSX0FSX05VTUJFUi5zZXQoXCJcXHUwNkY3XCIsIFwiN1wiKTtcbiAgICAgICAgdGhpcy5QRVJfQVJfTlVNQkVSLnNldChcIlxcdTA2RjhcIiwgXCI4XCIpO1xuICAgICAgICB0aGlzLlBFUl9BUl9OVU1CRVIuc2V0KFwiXFx1MDZGOVwiLCBcIjlcIik7XG5cbiAgICAgICAgdGhpcy5QRVJfQVJfTlVNQkVSLnNldChcIlxcdTA2NjBcIiwgXCIwXCIpO1xuICAgICAgICB0aGlzLlBFUl9BUl9OVU1CRVIuc2V0KFwiXFx1MDY2MVwiLCBcIjFcIik7XG4gICAgICAgIHRoaXMuUEVSX0FSX05VTUJFUi5zZXQoXCJcXHUwNjYyXCIsIFwiMlwiKTtcbiAgICAgICAgdGhpcy5QRVJfQVJfTlVNQkVSLnNldChcIlxcdTA2NjNcIiwgXCIzXCIpO1xuICAgICAgICB0aGlzLlBFUl9BUl9OVU1CRVIuc2V0KFwiXFx1MDY2NFwiLCBcIjRcIik7XG4gICAgICAgIHRoaXMuUEVSX0FSX05VTUJFUi5zZXQoXCJcXHUwNjY1XCIsIFwiNVwiKTtcbiAgICAgICAgdGhpcy5QRVJfQVJfTlVNQkVSLnNldChcIlxcdTA2NjZcIiwgXCI2XCIpO1xuICAgICAgICB0aGlzLlBFUl9BUl9OVU1CRVIuc2V0KFwiXFx1MDY2N1wiLCBcIjdcIik7XG4gICAgICAgIHRoaXMuUEVSX0FSX05VTUJFUi5zZXQoXCJcXHUwNjY4XCIsIFwiOFwiKTtcbiAgICAgICAgdGhpcy5QRVJfQVJfTlVNQkVSLnNldChcIlxcdTA2NjlcIiwgXCI5XCIpO1xuICAgIH1cblxuICAgIGlucHV0TWFuYWdlcjogSW5wdXRNYW5hZ2VyO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBodG1sSW5wdXRFbGVtZW50OiBhbnksIHByaXZhdGUgb3B0aW9uczogUnVwaWFoTWFza0NvbmZpZykge1xuICAgICAgICB0aGlzLmlucHV0TWFuYWdlciA9IG5ldyBJbnB1dE1hbmFnZXIoaHRtbElucHV0RWxlbWVudCk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpXG4gICAgfVxuXG4gICAgYWRkTnVtYmVyKGtleUNvZGU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCB7IGRlY2ltYWwsIHByZWNpc2lvbiwgaW5wdXRNb2RlIH0gPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGxldCBrZXlDaGFyID0gU3RyaW5nLmZyb21DaGFyQ29kZShrZXlDb2RlKTtcbiAgICAgICAgY29uc3QgaXNEZWNpbWFsQ2hhciA9IGtleUNoYXIgPT09IHRoaXMub3B0aW9ucy5kZWNpbWFsO1xuXG4gICAgICAgIGlmICghdGhpcy5yYXdWYWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5yYXdWYWx1ZSA9IHRoaXMuYXBwbHlNYXNrKGZhbHNlLCBrZXlDaGFyKTtcbiAgICAgICAgICAgIGxldCBzZWxlY3Rpb25TdGFydDogbnVtYmVyID0gMDtcbiAgICAgICAgICAgIGlmIChpbnB1dE1vZGUgPT09IFJ1cGlhaE1hc2tJbnB1dE1vZGUuTkFUVVJBTCAmJiBwcmVjaXNpb24gPiAwKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uU3RhcnQgPSB0aGlzLnJhd1ZhbHVlLmluZGV4T2YoZGVjaW1hbCk7XG4gICAgICAgICAgICAgICAgaWYgKGlzRGVjaW1hbENoYXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uU3RhcnQrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUZpZWxkVmFsdWUoc2VsZWN0aW9uU3RhcnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IHNlbGVjdGlvblN0YXJ0ID0gdGhpcy5pbnB1dFNlbGVjdGlvbi5zZWxlY3Rpb25TdGFydDtcbiAgICAgICAgICAgIGxldCBzZWxlY3Rpb25FbmQgPSB0aGlzLmlucHV0U2VsZWN0aW9uLnNlbGVjdGlvbkVuZDtcbiAgICAgICAgICAgIGNvbnN0IHJhd1ZhbHVlU3RhcnQgPSB0aGlzLnJhd1ZhbHVlLnN1YnN0cmluZygwLCBzZWxlY3Rpb25TdGFydCk7XG4gICAgICAgICAgICBsZXQgcmF3VmFsdWVFbmQgPSB0aGlzLnJhd1ZhbHVlLnN1YnN0cmluZyhzZWxlY3Rpb25FbmQsIHRoaXMucmF3VmFsdWUubGVuZ3RoKTtcblxuICAgICAgICAgICAgLy8gSW4gbmF0dXJhbCBtb2RlLCByZXBsYWNlIGRlY2ltYWxzIGluc3RlYWQgb2Ygc2hpZnRpbmcgdGhlbS5cbiAgICAgICAgICAgIGNvbnN0IGluRGVjaW1hbFBvcnRpb24gPSByYXdWYWx1ZVN0YXJ0LmluZGV4T2YoZGVjaW1hbCkgIT09IC0xO1xuICAgICAgICAgICAgaWYgKGlucHV0TW9kZSA9PT0gUnVwaWFoTWFza0lucHV0TW9kZS5OQVRVUkFMICYmIGluRGVjaW1hbFBvcnRpb24gJiYgc2VsZWN0aW9uU3RhcnQgPT09IHNlbGVjdGlvbkVuZCkge1xuICAgICAgICAgICAgICAgIHJhd1ZhbHVlRW5kID0gcmF3VmFsdWVFbmQuc3Vic3RyaW5nKDEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBuZXdWYWx1ZSA9IHJhd1ZhbHVlU3RhcnQgKyBrZXlDaGFyICsgcmF3VmFsdWVFbmQ7XG4gICAgICAgICAgICBsZXQgbmV4dFNlbGVjdGlvblN0YXJ0ID0gc2VsZWN0aW9uU3RhcnQgKyAxO1xuICAgICAgICAgICAgY29uc3QgaXNEZWNpbWFsT3JUaG91c2FuZHMgPSBpc0RlY2ltYWxDaGFyIHx8IGtleUNoYXIgPT09IHRoaXMub3B0aW9ucy50aG91c2FuZHM7XG4gICAgICAgICAgICBpZiAoaXNEZWNpbWFsT3JUaG91c2FuZHMgJiYga2V5Q2hhciA9PT0gcmF3VmFsdWVFbmRbMF0pIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgY3Vyc29yIGlzIGp1c3QgYmVmb3JlIHRoZSBkZWNpbWFsIG9yIHRob3VzYW5kcyBzZXBhcmF0b3IgYW5kIHRoZSB1c2VyIHR5cGVzIHRoZVxuICAgICAgICAgICAgICAgIC8vIGRlY2ltYWwgb3IgdGhvdXNhbmRzIHNlcGFyYXRvciwgbW92ZSB0aGUgY3Vyc29yIHBhc3QgaXQuXG4gICAgICAgICAgICAgICAgbmV4dFNlbGVjdGlvblN0YXJ0Kys7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLlNJTkdMRV9ESUdJVF9SRUdFWC50ZXN0KGtleUNoYXIpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWdub3JlIG90aGVyIG5vbi1udW1iZXJzLlxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5yYXdWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVGaWVsZFZhbHVlKG5leHRTZWxlY3Rpb25TdGFydCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhcHBseU1hc2soaXNOdW1iZXI6IGJvb2xlYW4sIHJhd1ZhbHVlOiBzdHJpbmcsIGRpc2FibGVQYWRBbmRUcmltID0gZmFsc2UpOiBzdHJpbmcge1xuICAgICAgICBsZXQgeyBhbGxvd05lZ2F0aXZlLCBkZWNpbWFsLCBwcmVjaXNpb24sIHByZWZpeCwgc3VmZml4LCB0aG91c2FuZHMsIG1pbiwgbWF4LCBpbnB1dE1vZGUgfSA9IHRoaXMub3B0aW9ucztcblxuICAgICAgICByYXdWYWx1ZSA9IGlzTnVtYmVyID8gbmV3IE51bWJlcihyYXdWYWx1ZSkudG9GaXhlZChwcmVjaXNpb24pIDogcmF3VmFsdWU7XG4gICAgICAgIGxldCBvbmx5TnVtYmVycyA9IHJhd1ZhbHVlLnJlcGxhY2UodGhpcy5PTkxZX05VTUJFUlNfUkVHRVgsIFwiXCIpO1xuXG4gICAgICAgIGlmICghb25seU51bWJlcnMgJiYgcmF3VmFsdWUgIT09IGRlY2ltYWwpIHtcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlucHV0TW9kZSA9PT0gUnVwaWFoTWFza0lucHV0TW9kZS5OQVRVUkFMICYmICFpc051bWJlciAmJiAhZGlzYWJsZVBhZEFuZFRyaW0pIHtcbiAgICAgICAgICAgIHJhd1ZhbHVlID0gdGhpcy5wYWRPclRyaW1QcmVjaXNpb24ocmF3VmFsdWUpO1xuICAgICAgICAgICAgb25seU51bWJlcnMgPSByYXdWYWx1ZS5yZXBsYWNlKHRoaXMuT05MWV9OVU1CRVJTX1JFR0VYLCBcIlwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBpbnRlZ2VyUGFydCA9IG9ubHlOdW1iZXJzLnNsaWNlKDAsIG9ubHlOdW1iZXJzLmxlbmd0aCAtIHByZWNpc2lvbilcbiAgICAgICAgICAgIC5yZXBsYWNlKC9eXFx1MDY2MCovZywgXCJcIilcbiAgICAgICAgICAgIC5yZXBsYWNlKC9eXFx1MDZGMCovZywgXCJcIilcbiAgICAgICAgICAgIC5yZXBsYWNlKC9eMCovZywgXCJcIik7XG5cbiAgICAgICAgaWYgKGludGVnZXJQYXJ0ID09IFwiXCIpIHtcbiAgICAgICAgICAgIGludGVnZXJQYXJ0ID0gXCIwXCI7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGludGVnZXJWYWx1ZSA9IHBhcnNlSW50KGludGVnZXJQYXJ0KTtcblxuICAgICAgICBpbnRlZ2VyUGFydCA9IGludGVnZXJQYXJ0LnJlcGxhY2UoL1xcQig/PShbMC05XFx1MDY2MC1cXHUwNjY5XFx1MDZGMC1cXHUwNkY5XXszfSkrKD8hWzAtOVxcdTA2NjAtXFx1MDY2OVxcdTA2RjAtXFx1MDZGOV0pKS9nLCB0aG91c2FuZHMpO1xuICAgICAgICBpZiAodGhvdXNhbmRzICYmIGludGVnZXJQYXJ0LnN0YXJ0c1dpdGgodGhvdXNhbmRzKSkge1xuICAgICAgICAgICAgaW50ZWdlclBhcnQgPSBpbnRlZ2VyUGFydC5zdWJzdHJpbmcoMSk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbmV3UmF3VmFsdWUgPSBpbnRlZ2VyUGFydDtcbiAgICAgICAgbGV0IGRlY2ltYWxQYXJ0ID0gb25seU51bWJlcnMuc2xpY2Uob25seU51bWJlcnMubGVuZ3RoIC0gcHJlY2lzaW9uKTtcbiAgICAgICAgbGV0IGRlY2ltYWxWYWx1ZSA9IHBhcnNlSW50KGRlY2ltYWxQYXJ0KSB8fCAwO1xuXG4gICAgICAgIGxldCBpc05lZ2F0aXZlID0gcmF3VmFsdWUuaW5kZXhPZihcIi1cIikgPiAtMTtcblxuICAgICAgICAvLyBFbnN1cmUgbWF4IGlzIGF0IGxlYXN0IGFzIGxhcmdlIGFzIG1pbi5cbiAgICAgICAgbWF4ID0gKHRoaXMuaXNOdWxsT3JVbmRlZmluZWQobWF4KSB8fCB0aGlzLmlzTnVsbE9yVW5kZWZpbmVkKG1pbikpID8gbWF4IDogTWF0aC5tYXgobWF4ISwgbWluISk7XG5cbiAgICAgICAgLy8gRW5zdXJlIHByZWNpc2lvbiBudW1iZXIgd29ya3Mgd2VsbCB3aXRoIG1vcmUgdGhhbiAyIGRpZ2l0c1xuICAgICAgICAvLyAyMyAvIDEwMC4uLiAyMzMgLyAxMDAwIGFuZCBzbyBvblxuICAgICAgICBjb25zdCBkaXZpZGVCeSA9IE51bWJlcignMScucGFkRW5kKHByZWNpc2lvbiArIDEsICcwJykpO1xuXG4gICAgICAgIC8vIFJlc3RyaWN0IHRvIHRoZSBtaW4gYW5kIG1heCB2YWx1ZXMuXG4gICAgICAgIGxldCBuZXdWYWx1ZSA9IGludGVnZXJWYWx1ZSArIChkZWNpbWFsVmFsdWUgLyBkaXZpZGVCeSk7XG5cbiAgICAgICAgbmV3VmFsdWUgPSBpc05lZ2F0aXZlID8gLW5ld1ZhbHVlIDogbmV3VmFsdWU7XG4gICAgICAgIGlmICghdGhpcy5pc051bGxPclVuZGVmaW5lZChtYXgpICYmIG5ld1ZhbHVlID4gbWF4ISkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYXBwbHlNYXNrKHRydWUsIG1heCArICcnKTtcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5pc051bGxPclVuZGVmaW5lZChtaW4pICYmIG5ld1ZhbHVlIDwgbWluISkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYXBwbHlNYXNrKHRydWUsIG1pbiArICcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcmVjaXNpb24gPiAwKSB7XG4gICAgICAgICAgICBpZiAobmV3UmF3VmFsdWUgPT0gXCIwXCIgJiYgZGVjaW1hbFBhcnQubGVuZ3RoIDwgcHJlY2lzaW9uKSB7XG4gICAgICAgICAgICAgICAgbmV3UmF3VmFsdWUgKz0gZGVjaW1hbCArIFwiMFwiLnJlcGVhdChwcmVjaXNpb24gLSAxKSArIGRlY2ltYWxQYXJ0O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXdSYXdWYWx1ZSArPSBkZWNpbWFsICsgZGVjaW1hbFBhcnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBsZXQgaXNaZXJvID0gbmV3VmFsdWUgPT0gMDtcbiAgICAgICAgbGV0IG9wZXJhdG9yID0gKGlzTmVnYXRpdmUgJiYgYWxsb3dOZWdhdGl2ZSAvKiYmICFpc1plcm8gKi8pID8gXCItXCIgOiBcIlwiO1xuICAgICAgICByZXR1cm4gb3BlcmF0b3IgKyBwcmVmaXggKyBuZXdSYXdWYWx1ZSArIHN1ZmZpeDtcbiAgICB9XG5cbiAgICBwYWRPclRyaW1QcmVjaXNpb24ocmF3VmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIGxldCB7IGRlY2ltYWwsIHByZWNpc2lvbiB9ID0gdGhpcy5vcHRpb25zO1xuXG4gICAgICAgIGxldCBkZWNpbWFsSW5kZXggPSByYXdWYWx1ZS5sYXN0SW5kZXhPZihkZWNpbWFsKTtcbiAgICAgICAgaWYgKGRlY2ltYWxJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIGRlY2ltYWxJbmRleCA9IHJhd1ZhbHVlLmxlbmd0aDtcbiAgICAgICAgICAgIHJhd1ZhbHVlICs9IGRlY2ltYWw7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgZGVjaW1hbFBvcnRpb24gPSByYXdWYWx1ZS5zdWJzdHJpbmcoZGVjaW1hbEluZGV4KS5yZXBsYWNlKHRoaXMuT05MWV9OVU1CRVJTX1JFR0VYLCBcIlwiKTtcbiAgICAgICAgY29uc3QgYWN0dWFsUHJlY2lzaW9uID0gZGVjaW1hbFBvcnRpb24ubGVuZ3RoO1xuICAgICAgICBpZiAoYWN0dWFsUHJlY2lzaW9uIDwgcHJlY2lzaW9uKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gYWN0dWFsUHJlY2lzaW9uOyBpIDwgcHJlY2lzaW9uOyBpKyspIHtcbiAgICAgICAgICAgICAgICBkZWNpbWFsUG9ydGlvbiArPSAnMCc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoYWN0dWFsUHJlY2lzaW9uID4gcHJlY2lzaW9uKSB7XG4gICAgICAgICAgICBkZWNpbWFsUG9ydGlvbiA9IGRlY2ltYWxQb3J0aW9uLnN1YnN0cmluZygwLCBkZWNpbWFsUG9ydGlvbi5sZW5ndGggKyBwcmVjaXNpb24gLSBhY3R1YWxQcmVjaXNpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJhd1ZhbHVlLnN1YnN0cmluZygwLCBkZWNpbWFsSW5kZXgpICsgZGVjaW1hbCArIGRlY2ltYWxQb3J0aW9uO1xuICAgIH1cblxuICAgIGNsZWFyTWFzayhyYXdWYWx1ZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKHRoaXMuaXNOdWxsYWJsZSgpICYmIHJhd1ZhbHVlID09PSBcIlwiKVxuICAgICAgICAgICAgcmV0dXJuIDA7XG5cbiAgICAgICAgbGV0IHZhbHVlID0gKHJhd1ZhbHVlIHx8IFwiMFwiKS5yZXBsYWNlKHRoaXMub3B0aW9ucy5wcmVmaXgsIFwiXCIpLnJlcGxhY2UodGhpcy5vcHRpb25zLnN1ZmZpeCwgXCJcIik7XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy50aG91c2FuZHMpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZShuZXcgUmVnRXhwKFwiXFxcXFwiICsgdGhpcy5vcHRpb25zLnRob3VzYW5kcywgXCJnXCIpLCBcIlwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZGVjaW1hbCkge1xuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKHRoaXMub3B0aW9ucy5kZWNpbWFsLCBcIi5cIik7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLlBFUl9BUl9OVU1CRVIuZm9yRWFjaCgodmFsOiBzdHJpbmcsIGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZSA9IG5ldyBSZWdFeHAoa2V5LCBcImdcIik7XG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UocmUsIHZhbCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcGFyc2VGbG9hdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgY2hhbmdlVG9OZWdhdGl2ZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5hbGxvd05lZ2F0aXZlIC8qJiYgdGhpcy5yYXdWYWx1ZSAhPSBcIlwiKi8gJiYgdGhpcy5yYXdWYWx1ZS5jaGFyQXQoMCkgIT0gXCItXCIgLyomJiB0aGlzLnZhbHVlICE9IDAqLykge1xuICAgICAgICAgICAgLy8gQXBwbHkgdGhlIG1hc2sgdG8gZW5zdXJlIHRoZSBtaW4gYW5kIG1heCB2YWx1ZXMgYXJlIGVuZm9yY2VkLlxuICAgICAgICAgICAgdGhpcy5yYXdWYWx1ZSA9IHRoaXMuYXBwbHlNYXNrKGZhbHNlLCBcIi1cIiArICh0aGlzLnJhd1ZhbHVlID8gdGhpcy5yYXdWYWx1ZSA6ICcwJykpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2hhbmdlVG9Qb3NpdGl2ZSgpOiB2b2lkIHtcbiAgICAgICAgLy8gQXBwbHkgdGhlIG1hc2sgdG8gZW5zdXJlIHRoZSBtaW4gYW5kIG1heCB2YWx1ZXMgYXJlIGVuZm9yY2VkLlxuICAgICAgICB0aGlzLnJhd1ZhbHVlID0gdGhpcy5hcHBseU1hc2soZmFsc2UsIHRoaXMucmF3VmFsdWUucmVwbGFjZShcIi1cIiwgXCJcIikpO1xuICAgIH1cblxuICAgIHJlbW92ZU51bWJlcihrZXlDb2RlOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgbGV0IHsgZGVjaW1hbCwgdGhvdXNhbmRzLCBwcmVmaXgsIHN1ZmZpeCwgaW5wdXRNb2RlIH0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgICAgICAgaWYgKHRoaXMuaXNOdWxsYWJsZSgpICYmIHRoaXMudmFsdWUgPT0gMCkge1xuICAgICAgICAgICAgdGhpcy5yYXdWYWx1ZSA9ICcnO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHNlbGVjdGlvbkVuZCA9IHRoaXMuaW5wdXRTZWxlY3Rpb24uc2VsZWN0aW9uRW5kO1xuICAgICAgICBsZXQgc2VsZWN0aW9uU3RhcnQgPSB0aGlzLmlucHV0U2VsZWN0aW9uLnNlbGVjdGlvblN0YXJ0O1xuXG4gICAgICAgIGNvbnN0IHN1ZmZpeFN0YXJ0ID0gdGhpcy5yYXdWYWx1ZS5sZW5ndGggLSBzdWZmaXgubGVuZ3RoO1xuICAgICAgICBzZWxlY3Rpb25FbmQgPSBNYXRoLm1pbihzdWZmaXhTdGFydCwgTWF0aC5tYXgoc2VsZWN0aW9uRW5kLCBwcmVmaXgubGVuZ3RoKSk7XG4gICAgICAgIHNlbGVjdGlvblN0YXJ0ID0gTWF0aC5taW4oc3VmZml4U3RhcnQsIE1hdGgubWF4KHNlbGVjdGlvblN0YXJ0LCBwcmVmaXgubGVuZ3RoKSk7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgc2VsZWN0aW9uIHdhcyBlbnRpcmVseSBpbiB0aGUgcHJlZml4IG9yIHN1ZmZpeC5cbiAgICAgICAgaWYgKHNlbGVjdGlvblN0YXJ0ID09PSBzZWxlY3Rpb25FbmQgJiZcbiAgICAgICAgICAgIHRoaXMuaW5wdXRTZWxlY3Rpb24uc2VsZWN0aW9uU3RhcnQgIT09IHRoaXMuaW5wdXRTZWxlY3Rpb24uc2VsZWN0aW9uRW5kKSB7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUZpZWxkVmFsdWUoc2VsZWN0aW9uU3RhcnQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGRlY2ltYWxJbmRleCA9IHRoaXMucmF3VmFsdWUuaW5kZXhPZihkZWNpbWFsKTtcbiAgICAgICAgaWYgKGRlY2ltYWxJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgIGRlY2ltYWxJbmRleCA9IHRoaXMucmF3VmFsdWUubGVuZ3RoO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHNoaWZ0U2VsZWN0aW9uID0gMDtcbiAgICAgICAgbGV0IGluc2VydENoYXJzID0gJyc7XG5cbiAgICAgICAgY29uc3QgaXNDdXJzb3JJbkRlY2ltYWxzID0gZGVjaW1hbEluZGV4IDwgc2VsZWN0aW9uRW5kO1xuICAgICAgICBjb25zdCBpc0N1cnNvckltbWVkaWF0ZWx5QWZ0ZXJEZWNpbWFsUG9pbnQgPSBkZWNpbWFsSW5kZXggKyAxID09PSBzZWxlY3Rpb25FbmQ7XG5cbiAgICAgICAgaWYgKHNlbGVjdGlvbkVuZCA9PT0gc2VsZWN0aW9uU3RhcnQpIHtcbiAgICAgICAgICAgIGlmIChrZXlDb2RlID09IDgpIHtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uU3RhcnQgPD0gcHJlZml4Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNlbGVjdGlvblN0YXJ0LS07XG5cbiAgICAgICAgICAgICAgICAvLyBJZiBwcmV2aW91cyBjaGFyIGlzbid0IGEgbnVtYmVyLCBnbyBiYWNrIG9uZSBtb3JlLlxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5yYXdWYWx1ZS5zdWJzdHIoc2VsZWN0aW9uU3RhcnQsIDEpLm1hdGNoKC9cXGQvKSkge1xuICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb25TdGFydC0tO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEluIG5hdHVyYWwgbW9kZSwganVtcCBiYWNrd2FyZHMgd2hlbiBpbiBkZWNpbWFsIHBvcnRpb24gb2YgbnVtYmVyLlxuICAgICAgICAgICAgICAgIGlmIChpbnB1dE1vZGUgPT09IFJ1cGlhaE1hc2tJbnB1dE1vZGUuTkFUVVJBTCAmJiBpc0N1cnNvckluRGVjaW1hbHMpIHtcbiAgICAgICAgICAgICAgICAgICAgc2hpZnRTZWxlY3Rpb24gPSAtMTtcbiAgICAgICAgICAgICAgICAgICAgLy8gd2hlbiByZW1vdmluZyBhIHNpbmdsZSB3aG9sZSBudW1iZXIsIHJlcGxhY2UgaXQgd2l0aCAwXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0N1cnNvckltbWVkaWF0ZWx5QWZ0ZXJEZWNpbWFsUG9pbnQgJiYgdGhpcy52YWx1ZSA8IDEwICYmIHRoaXMudmFsdWUgPiAtMTApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluc2VydENoYXJzICs9ICcwJztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5Q29kZSA9PSA0NiB8fCBrZXlDb2RlID09IDYzMjcyKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvblN0YXJ0ID09PSBzdWZmaXhTdGFydCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbkVuZCsrO1xuXG4gICAgICAgICAgICAgICAgLy8gSWYgbmV4dCBjaGFyIGlzbid0IGEgbnVtYmVyLCBnbyBvbmUgbW9yZS5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMucmF3VmFsdWUuc3Vic3RyKHNlbGVjdGlvblN0YXJ0LCAxKS5tYXRjaCgvXFxkLykpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uU3RhcnQrKztcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uRW5kKys7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSW4gbmF0dXJhbCBtb2RlLCByZXBsYWNlIGRlY2ltYWxzIHdpdGggMHMuXG4gICAgICAgIGlmIChpbnB1dE1vZGUgPT09IFJ1cGlhaE1hc2tJbnB1dE1vZGUuTkFUVVJBTCAmJiBzZWxlY3Rpb25TdGFydCA+IGRlY2ltYWxJbmRleCkge1xuICAgICAgICAgICAgY29uc3QgcmVwbGFjZWREZWNpbWFsQ291bnQgPSBzZWxlY3Rpb25FbmQgLSBzZWxlY3Rpb25TdGFydDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVwbGFjZWREZWNpbWFsQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGluc2VydENoYXJzICs9ICcwJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzZWxlY3Rpb25Gcm9tRW5kID0gdGhpcy5yYXdWYWx1ZS5sZW5ndGggLSBzZWxlY3Rpb25FbmQ7XG4gICAgICAgIHRoaXMucmF3VmFsdWUgPSB0aGlzLnJhd1ZhbHVlLnN1YnN0cmluZygwLCBzZWxlY3Rpb25TdGFydCkgKyBpbnNlcnRDaGFycyArIHRoaXMucmF3VmFsdWUuc3Vic3RyaW5nKHNlbGVjdGlvbkVuZCk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGxlYWRpbmcgdGhvdXNhbmQgc2VwYXJhdG9yIGZyb20gcmF3IHZhbHVlLlxuICAgICAgICBjb25zdCBzdGFydENoYXIgPSB0aGlzLnJhd1ZhbHVlLnN1YnN0cihwcmVmaXgubGVuZ3RoLCAxKTtcbiAgICAgICAgaWYgKHN0YXJ0Q2hhciA9PT0gdGhvdXNhbmRzKSB7XG4gICAgICAgICAgICB0aGlzLnJhd1ZhbHVlID0gdGhpcy5yYXdWYWx1ZS5zdWJzdHJpbmcoMCwgcHJlZml4Lmxlbmd0aCkgKyB0aGlzLnJhd1ZhbHVlLnN1YnN0cmluZyhwcmVmaXgubGVuZ3RoICsgMSk7XG4gICAgICAgICAgICBzZWxlY3Rpb25Gcm9tRW5kID0gTWF0aC5taW4oc2VsZWN0aW9uRnJvbUVuZCwgdGhpcy5yYXdWYWx1ZS5sZW5ndGggLSBwcmVmaXgubGVuZ3RoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudXBkYXRlRmllbGRWYWx1ZSh0aGlzLnJhd1ZhbHVlLmxlbmd0aCAtIHNlbGVjdGlvbkZyb21FbmQgKyBzaGlmdFNlbGVjdGlvbiwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgdXBkYXRlRmllbGRWYWx1ZShzZWxlY3Rpb25TdGFydD86IG51bWJlciwgZGlzYWJsZVBhZEFuZFRyaW0gPSBmYWxzZSk6IHZvaWQge1xuICAgICAgICBsZXQgbmV3UmF3VmFsdWUgPSB0aGlzLmFwcGx5TWFzayhmYWxzZSwgdGhpcy5yYXdWYWx1ZSB8fCBcIlwiLCBkaXNhYmxlUGFkQW5kVHJpbSk7XG4gICAgICAgIHNlbGVjdGlvblN0YXJ0ID0gc2VsZWN0aW9uU3RhcnQgPT0gdW5kZWZpbmVkID8gdGhpcy5yYXdWYWx1ZS5sZW5ndGggOiBzZWxlY3Rpb25TdGFydDtcbiAgICAgICAgc2VsZWN0aW9uU3RhcnQgPSBNYXRoLm1heCh0aGlzLm9wdGlvbnMucHJlZml4Lmxlbmd0aCwgTWF0aC5taW4oc2VsZWN0aW9uU3RhcnQsIHRoaXMucmF3VmFsdWUubGVuZ3RoIC0gdGhpcy5vcHRpb25zLnN1ZmZpeC5sZW5ndGgpKTtcbiAgICAgICAgdGhpcy5pbnB1dE1hbmFnZXIudXBkYXRlVmFsdWVBbmRDdXJzb3IobmV3UmF3VmFsdWUsIHRoaXMucmF3VmFsdWUubGVuZ3RoLCBzZWxlY3Rpb25TdGFydCk7XG4gICAgfVxuXG4gICAgdXBkYXRlT3B0aW9ucyhvcHRpb25zOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgbGV0IHZhbHVlOiBudW1iZXIgPSB0aGlzLnZhbHVlO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgcHJlZml4TGVuZ3RoKCk6IGFueSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMucHJlZml4Lmxlbmd0aDtcbiAgICB9XG5cbiAgICBzdWZmaXhMZW5ndGgoKTogYW55IHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5zdWZmaXgubGVuZ3RoO1xuICAgIH1cblxuICAgIGlzTnVsbGFibGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMubnVsbGFibGU7XG4gICAgfVxuXG4gICAgZ2V0IGNhbklucHV0TW9yZU51bWJlcnMoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmlucHV0TWFuYWdlci5jYW5JbnB1dE1vcmVOdW1iZXJzO1xuICAgIH1cblxuICAgIGdldCBpbnB1dFNlbGVjdGlvbigpOiBhbnkge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnB1dE1hbmFnZXIuaW5wdXRTZWxlY3Rpb247XG4gICAgfVxuXG4gICAgZ2V0IHJhd1ZhbHVlKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmlucHV0TWFuYWdlci5yYXdWYWx1ZTtcbiAgICB9XG5cbiAgICBzZXQgcmF3VmFsdWUodmFsdWU6IHN0cmluZykge1xuICAgICAgICB0aGlzLmlucHV0TWFuYWdlci5yYXdWYWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIGdldCBzdG9yZWRSYXdWYWx1ZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnB1dE1hbmFnZXIuc3RvcmVkUmF3VmFsdWU7XG4gICAgfVxuXG4gICAgZ2V0IHZhbHVlKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLmNsZWFyTWFzayh0aGlzLnJhd1ZhbHVlKTtcbiAgICB9XG5cbiAgICBzZXQgdmFsdWUodmFsdWU6IG51bWJlcikge1xuICAgICAgICB0aGlzLnJhd1ZhbHVlID0gdGhpcy5hcHBseU1hc2sodHJ1ZSwgXCJcIiArIHZhbHVlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzTnVsbE9yVW5kZWZpbmVkKHZhbHVlOiBhbnkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQ7XG4gICAgfVxufSJdfQ==