@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
JavaScript
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==