UNPKG

@cute-dw/core

Version:

This TypeScript library is the main part of a more powerfull package designed for the fast WEB software development. The cornerstone of the library is the **DataStore** class, which might be useful when you need a full control of the data, but do not need

182 lines 26.9 kB
import { Strings } from "../../Strings"; import { Locale } from "../Locale"; import { NumberSpellerDictionary } from "./NumberSpellerDictionary"; /** * This utility class consists exclusively of the static methods that operate on numeric values with localization taking into account * @since 0.4.0 * @license MIT, (c) 2022 ALEXANDER STRELKOV, alv.strelkov@gmail.com */ export class NumberSpeller { /** * * @param amount * @param thousandGroup * @param words * @param options * @returns */ static _digitGroup(amount, thousandGroup, words, options) { let res = ""; let nBase = 1000000000000000.00, v = 0, srcAmount = amount; for (let nGrp = 1; nGrp <= 5; nGrp++) { v = Math.trunc(amount / nBase); if (v > 0) { amount -= Math.trunc(v * nBase); res += this._digitGroup(v, nGrp, words, options); if (amount > 0) { res += words.texts.delim1000 || ""; } res += " "; } nBase = Math.trunc(nBase / 1000); } // hundreds v = Math.trunc(amount / 100); if (v > 0) { amount -= Math.trunc(v * 100); if (words.hundreds.length == 1) { res += (words.ones[v] + " " + words.hundreds[0] + " "); } else { res += (words.hundreds[v - 1] + " "); } } // tens let fractions = ""; v = Math.trunc(amount / 10); if (v > 0) { amount -= Math.trunc(v * 10); if (v == 1 && amount > 0) { // 11-19 fractions += (words.teens[amount - 1] + " "); amount = 0; } else { fractions += words.tens[v - 1]; if (v > 1 && amount > 0 && words.texts.tenSplitter) { fractions += words.texts.tenSplitter; } else { fractions += " "; } } } // units let item; let more = ""; let pointWord = ""; let useExacts = true; let currOptions = undefined; if (thousandGroup !== undefined) { item = words.groups[thousandGroup].find(obj => obj.values === undefined || obj.values.indexOf(amount) >= 0); } else if (options.currency) { currOptions = words.currency[options.currency]; if (currOptions) { useExacts = currOptions.useExacts ?? true; if (options.isFraction) { item = currOptions.parts?.fraction.find(obj => obj.values === undefined || obj.values.indexOf(amount) >= 0); pointWord = Strings.trimAll(currOptions.point) || ""; pointWord = (pointWord != "" ? pointWord + " " : ""); } else { item = currOptions.parts?.integer.find(obj => obj.values === undefined || obj.values.indexOf(amount) >= 0); } } } if (item) { more = item.word; } if (amount > 0) { let word = words.ones[amount]; if (useExacts && words.exactWordsMapping && (options.isFraction || thousandGroup == 5)) { word = words.exactWordsMapping[amount] ?? word; } fractions += word; } else if (srcAmount == 0) { fractions += words.ones[0]; } return (res + pointWord + (options.isFraction && options.fractionAsNumber ? Strings.right("0" + String(srcAmount), 2) : fractions)).trimEnd() + " " + more; } /** * Converts an integer value in words * @param value A number to convert * @param options An object containing certain properties and their values * @returns String * @static */ static spellInteger(value, options) { const oLocale = options?.locale instanceof Locale ? options.locale : new Locale(options?.locale); const words = NumberSpellerDictionary.get(oLocale.baseName); if (!words) { return String(value); } if (!Number.isFinite(value)) { return String(value); } let signWord = ""; if (value < 0) { value = Math.abs(value); signWord = words.texts?.minus ?? "-"; } return signWord + this._digitGroup(Math.trunc(value), undefined, words, {}).trimEnd(); } /** * Converts amount of money in words * @param value Sum to convert * @param options Configuration object * @returns String * @throws Error if the _locale_ value is invalid in `options` * @static */ static spellCurrency(value, options) { const oLocale = options?.locale instanceof Locale ? options.locale : new Locale(options?.locale); const words = NumberSpellerDictionary.get(oLocale.baseName); if (!words) { throw new TypeError(`Unknown locale: ${oLocale.baseName}`); } let currency = options?.currency ?? ""; if (currency.trim() == "" && Object.keys(words.currency).length > 0) { currency = Object.keys(words.currency)[0]; } if (!words.currency[currency]) { throw new TypeError(`Unknown currency '${currency}' in locale '${oLocale.baseName}'`); } if (!Number.isFinite(value)) { throw new RangeError(`Invalid value: ${value}`); } let signWord = ""; if (value < 0) { value = Math.abs(value); signWord = (words.texts?.minus ?? "-") + " "; } const intPart = Math.trunc(value); const decPart = Math.round((value - intPart) * 100); let sVal = signWord + this._digitGroup(intPart, undefined, words, { currency, isFraction: false }); if (sVal != "") { sVal += " "; } return sVal + (decPart == 0 && words.currency[currency].only ? words.currency[currency].only : this._digitGroup(decPart, undefined, words, { currency, isFraction: true, fractionAsNumber: options?.fractionAsNumber ?? true })); } /** * Gets the result of the specified _unit_ formatting * @param value A value in units * @param unit Required value in unit formatting. Possible values are [core unit identifiers](https://tc39.es/proposal-unified-intl-numberformat/section6/locales-currencies-tz_proposed_out.html#sec-issanctionedsimpleunitidentifier) that was selected for use in ECMAScript. Pairs of simple units can be concatenated with "-per-" to make a compound unit. * @param options Configuration object * @returns String * @throws Error if the _locale_ value is invalid in `options` * @static */ static spellUnit(value, unit, options) { const oLocale = options?.locale instanceof Locale ? options.locale : new Locale(options?.locale); let output = (new Intl.NumberFormat(oLocale.baseName, { style: "unit", unit, unitDisplay: options?.unitDisplay ?? "long" })).format(value); if (!(options?.valueAsNumber ?? false) && Number.isInteger(value)) { output = NumberSpeller.spellInteger(value, { locale: options?.locale }) + " " + Strings.getLastToken(output, " ")[0]; } return output; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTnVtYmVyU3BlbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2N1dGUtY29yZS9zcmMvbGliL3V0aWwvaTE4bi90ZXh0L051bWJlclNwZWxsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ25DLE9BQU8sRUFBdUMsdUJBQXVCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN6Rzs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLGFBQWE7SUFDeEI7Ozs7Ozs7T0FPRztJQUNLLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBYyxFQUFFLGFBQWlDLEVBQUUsS0FBbUMsRUFBRSxPQUFnRjtRQUNqTSxJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFDYixJQUFJLEtBQUssR0FBRyxtQkFBbUIsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFNBQVMsR0FBRyxNQUFNLENBQUM7UUFFM0QsS0FBSyxJQUFJLElBQUksR0FBRyxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUNwQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUM7WUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUNULE1BQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQztnQkFDaEMsR0FBRyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ2pELElBQUksTUFBTSxHQUFHLENBQUMsRUFBRTtvQkFDZCxHQUFHLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUks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RUFBRSxNQUFNLFlBQVksTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDakcsSUFBSSxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsV0FBVyxJQUFJLE1BQU0sRUFBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekksSUFBSyxDQUFDLENBQUMsT0FBTyxFQUFFLGFBQWEsSUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFHO1lBQ2pFLE1BQU0sR0FBRyxhQUFhLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFDLENBQUMsR0FBRyxHQUFHLEdBQUUsT0FBTyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDbkg7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0NBRUYiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTdHJpbmdzIH0gZnJvbSBcIi4uLy4uL1N0cmluZ3NcIjtcbmltcG9ydCB7IExvY2FsZSB9IGZyb20gXCIuLi9Mb2NhbGVcIjtcbmltcG9ydCB7IEN1cnJlbmN5T3B0aW9ucywgRGlnaXRhbFdvcmRzQ29uZmlnLCBOdW1iZXJTcGVsbGVyRGljdGlvbmFyeSB9IGZyb20gXCIuL051bWJlclNwZWxsZXJEaWN0aW9uYXJ5XCI7XG4vKipcbiAqIFRoaXMgdXRpbGl0eSBjbGFzcyBjb25zaXN0cyBleGNsdXNpdmVseSBvZiB0aGUgc3RhdGljIG1ldGhvZHMgdGhhdCBvcGVyYXRlIG9uIG51bWVyaWMgdmFsdWVzIHdpdGggbG9jYWxpemF0aW9uIHRha2luZyBpbnRvIGFjY291bnRcbiAqIEBzaW5jZSAwLjQuMFxuICogQGxpY2Vuc2UgTUlULCAoYykgMjAyMiBBTEVYQU5ERVIgU1RSRUxLT1YsIGFsdi5zdHJlbGtvdkBnbWFpbC5jb21cbiAqL1xuZXhwb3J0IGNsYXNzIE51bWJlclNwZWxsZXIge1xuICAvKipcbiAgICpcbiAgICogQHBhcmFtIGFtb3VudFxuICAgKiBAcGFyYW0gdGhvdXNhbmRHcm91cFxuICAgKiBAcGFyYW0gd29yZHNcbiAgICogQHBhcmFtIG9wdGlvbnNcbiAgICogQHJldHVybnNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIF9kaWdpdEdyb3VwKGFtb3VudDogbnVtYmVyLCB0aG91c2FuZEdyb3VwOiBudW1iZXIgfCB1bmRlZmluZWQsIHdvcmRzOiBSZWFkb25seTxEaWdpdGFsV29yZHNDb25maWc+LCBvcHRpb25zOiB7IGN1cnJlbmN5Pzogc3RyaW5nLCBpc0ZyYWN0aW9uPzogYm9vbGVhbiwgZnJhY3Rpb25Bc051bWJlcj86IGJvb2xlYW4gfSk6IHN0cmluZyB7XG4gICAgbGV0IHJlcyA9IFwiXCI7XG4gICAgbGV0IG5CYXNlID0gMTAwMDAwMDAwMDAwMDAwMC4wMCwgdiA9IDAsIHNyY0Ftb3VudCA9IGFtb3VudDtcblxuICAgIGZvciAobGV0IG5HcnAgPSAxOyBuR3JwIDw9IDU7IG5HcnArKykge1xuICAgICAgdiA9IE1hdGgudHJ1bmMoYW1vdW50IC8gbkJhc2UpO1xuICAgICAgaWYgKHYgPiAwKSB7XG4gICAgICAgIGFtb3VudCAtPSBNYXRoLnRydW5jKHYgKiBuQmFzZSk7XG4gICAgICAgIHJlcyArPSB0aGlzLl9kaWdpdEdyb3VwKHYsIG5HcnAsIHdvcmRzLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKGFtb3VudCA+IDApIHtcbiAgICAgICAgICByZXMgKz0gd29yZHMudGV4dHMuZGVsaW0xMDAwIHx8IFwiXCI7XG4gICAgICAgIH1cbiAgICAgICAgcmVzICs9IFwiIFwiO1xuICAgICAgfVxuICAgICAgbkJhc2UgPSBNYXRoLnRydW5jKG5CYXNlIC8gMTAwMCk7XG4gICAgfVxuICAgIC8vIGh1bmRyZWRzXG4gICAgdiA9IE1hdGgudHJ1bmMoYW1vdW50IC8gMTAwKTtcbiAgICBpZiAodiA+IDApIHtcbiAgICAgIGFtb3VudCAtPSBNYXRoLnRydW5jKHYgKiAxMDApO1xuICAgICAgaWYgKHdvcmRzLmh1bmRyZWRzLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgIHJlcyArPSAod29yZHMub25lc1t2XSArIFwiIFwiICsgd29yZHMuaHVuZHJlZHNbMF0gKyBcIiBcIik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXMgKz0gKHdvcmRzLmh1bmRyZWRzW3YgLSAxXSArIFwiIFwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gdGVuc1xuICAgIGxldCBmcmFjdGlvbnMgPSBcIlwiO1xuICAgIHYgPSBNYXRoLnRydW5jKGFtb3VudCAvIDEwKTtcbiAgICBpZiAodiA+IDApIHtcbiAgICAgIGFtb3VudCAtPSBNYXRoLnRydW5jKHYgKiAxMCk7XG4gICAgICBpZiAodiA9PSAxICYmIGFtb3VudCA+IDApIHtcbiAgICAgICAgLy8gMTEtMTlcbiAgICAgICAgZnJhY3Rpb25zICs9ICh3b3Jkcy50ZWVuc1thbW91bnQgLSAxXSArIFwiIFwiKTtcbiAgICAgICAgYW1vdW50ID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZyYWN0aW9ucyArPSB3b3Jkcy50ZW5zW3YgLSAxXTtcbiAgICAgICAgaWYgKHYgPiAxICYmIGFtb3VudCA+IDAgJiYgd29yZHMudGV4dHMudGVuU3BsaXR0ZXIpIHtcbiAgICAgICAgICBmcmFjdGlvbnMgKz0gd29yZHMudGV4dHMudGVuU3BsaXR0ZXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZnJhY3Rpb25zICs9IFwiIFwiO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8vIHVuaXRzXG4gICAgbGV0IGl0ZW07XG4gICAgbGV0IG1vcmUgPSBcIlwiO1xuICAgIGxldCBwb2ludFdvcmQgPSBcIlwiO1xuICAgIGxldCB1c2VFeGFjdHMgPSB0cnVlO1xuICAgIGxldCBjdXJyT3B0aW9uczogQ3VycmVuY3lPcHRpb25zIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIGlmICh0aG91c2FuZEdyb3VwICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGl0ZW0gPSB3b3Jkcy5ncm91cHNbdGhvdXNhbmRHcm91cF0uZmluZChvYmogPT4gb2JqLnZhbHVlcyA9PT0gdW5kZWZpbmVkIHx8IG9iai52YWx1ZXMuaW5kZXhPZihhbW91bnQpID49IDApO1xuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5jdXJyZW5jeSkge1xuICAgICAgY3Vyck9wdGlvbnMgPSB3b3Jkcy5jdXJyZW5jeVtvcHRpb25zLmN1cnJlbmN5XTtcbiAgICAgIGlmIChjdXJyT3B0aW9ucykge1xuICAgICAgICB1c2VFeGFjdHMgPSBjdXJyT3B0aW9ucy51c2VFeGFjdHMgPz8gdHJ1ZTtcbiAgICAgICAgaWYgKG9wdGlvbnMuaXNGcmFjdGlvbikge1xuICAgICAgICAgIGl0ZW0gPSBjdXJyT3B0aW9ucy5wYXJ0cz8uZnJhY3Rpb24uZmluZChvYmogPT4gb2JqLnZhbHVlcyA9PT0gdW5kZWZpbmVkIHx8IG9iai52YWx1ZXMuaW5kZXhPZihhbW91bnQpID49IDApO1xuICAgICAgICAgIHBvaW50V29yZCA9IFN0cmluZ3MudHJpbUFsbChjdXJyT3B0aW9ucy5wb2ludCkgfHwgXCJcIjtcbiAgICAgICAgICBwb2ludFdvcmQgPSAocG9pbnRXb3JkICE9IFwiXCIgPyBwb2ludFdvcmQgKyBcIiBcIiA6IFwiXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZW0gPSBjdXJyT3B0aW9ucy5wYXJ0cz8uaW50ZWdlci5maW5kKG9iaiA9PiBvYmoudmFsdWVzID09PSB1bmRlZmluZWQgfHwgb2JqLnZhbHVlcy5pbmRleE9mKGFtb3VudCkgPj0gMCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGl0ZW0pIHtcbiAgICAgIG1vcmUgPSBpdGVtLndvcmQ7XG4gICAgfVxuXG4gICAgaWYgKGFtb3VudCA+IDApIHtcbiAgICAgIGxldCB3b3JkID0gd29yZHMub25lc1thbW91bnRdO1xuICAgICAgaWYgKHVzZUV4YWN0cyAmJiB3b3Jkcy5leGFjdFdvcmRzTWFwcGluZyAmJiAob3B0aW9ucy5pc0ZyYWN0aW9uIHx8IHRob3VzYW5kR3JvdXAgPT0gNSkpIHtcbiAgICAgICAgd29yZCA9IHdvcmRzLmV4YWN0V29yZHNNYXBwaW5nW2Ftb3VudF0gPz8gd29yZDtcbiAgICAgIH1cbiAgICAgIGZyYWN0aW9ucyArPSB3b3JkO1xuICAgIH0gZWxzZSBpZiAoc3JjQW1vdW50ID09IDApIHtcbiAgICAgIGZyYWN0aW9ucyArPSB3b3Jkcy5vbmVzWzBdO1xuICAgIH1cblxuICAgIHJldHVybiAocmVzICsgcG9pbnRXb3JkICsgKG9wdGlvbnMuaXNGcmFjdGlvbiAmJiBvcHRpb25zLmZyYWN0aW9uQXNOdW1iZXIgPyBTdHJpbmdzLnJpZ2h0KFwiMFwiICsgU3RyaW5nKHNyY0Ftb3VudCksIDIpIDogZnJhY3Rpb25zKSkudHJpbUVuZCgpICsgXCIgXCIgKyBtb3JlO1xuICB9XG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhbiBpbnRlZ2VyIHZhbHVlIGluIHdvcmRzXG4gICAqIEBwYXJhbSB2YWx1ZSBBIG51bWJlciB0byBjb252ZXJ0XG4gICAqIEBwYXJhbSBvcHRpb25zIEFuIG9iamVjdCBjb250YWluaW5nIGNlcnRhaW4gcHJvcGVydGllcyBhbmQgdGhlaXIgdmFsdWVzXG4gICAqIEByZXR1cm5zIFN0cmluZ1xuICAgKiBAc3RhdGljXG4gICAqL1xuICBzdGF0aWMgc3BlbGxJbnRlZ2VyKHZhbHVlOiBudW1iZXIsIG9wdGlvbnM/OiB7IGxvY2FsZT86IHN0cmluZyB8IExvY2FsZSB9KTogc3RyaW5nIHtcbiAgICBjb25zdCBvTG9jYWxlID0gb3B0aW9ucz8ubG9jYWxlIGluc3RhbmNlb2YgTG9jYWxlID8gb3B0aW9ucy5sb2NhbGUgOiBuZXcgTG9jYWxlKG9wdGlvbnM/LmxvY2FsZSk7XG5cbiAgICBjb25zdCB3b3JkcyA9IE51bWJlclNwZWxsZXJEaWN0aW9uYXJ5LmdldChvTG9jYWxlLmJhc2VOYW1lISk7XG4gICAgaWYgKCF3b3Jkcykge1xuICAgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gICAgfVxuICAgIGlmICghTnVtYmVyLmlzRmluaXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gICAgfVxuICAgIGxldCBzaWduV29yZCA9IFwiXCI7XG4gICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSk7XG4gICAgICBzaWduV29yZCA9IHdvcmRzLnRleHRzPy5taW51cyA/PyBcIi1cIjtcbiAgICB9XG5cbiAgICByZXR1cm4gc2lnbldvcmQgKyB0aGlzLl9kaWdpdEdyb3VwKE1hdGgudHJ1bmModmFsdWUpLCB1bmRlZmluZWQsIHdvcmRzLCB7fSkudHJpbUVuZCgpO1xuICB9XG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhbW91bnQgb2YgbW9uZXkgaW4gd29yZHNcbiAgICogQHBhcmFtIHZhbHVlICBTdW0gdG8gY29udmVydFxuICAgKiBAcGFyYW0gb3B0aW9ucyBDb25maWd1cmF0aW9uIG9iamVjdFxuICAgKiBAcmV0dXJucyBTdHJpbmdcbiAgICogQHRocm93cyBFcnJvciBpZiB0aGUgX2xvY2FsZV8gdmFsdWUgaXMgaW52YWxpZCBpbiBgb3B0aW9uc2BcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgc3RhdGljIHNwZWxsQ3VycmVuY3kodmFsdWU6IG51bWJlciwgb3B0aW9ucz86IHsgY3VycmVuY3k/OiBzdHJpbmcsIGxvY2FsZT86IHN0cmluZyB8IExvY2FsZSwgZnJhY3Rpb25Bc051bWJlcj86IGJvb2xlYW4gfSk6IHN0cmluZyB7XG4gICAgY29uc3Qgb0xvY2FsZSA9IG9wdGlvbnM/LmxvY2FsZSBpbnN0YW5jZW9mIExvY2FsZSA/IG9wdGlvbnMubG9jYWxlIDogbmV3IExvY2FsZShvcHRpb25zPy5sb2NhbGUpO1xuICAgIGNvbnN0IHdvcmRzID0gTnVtYmVyU3BlbGxlckRpY3Rpb25hcnkuZ2V0KG9Mb2NhbGUuYmFzZU5hbWUhKTtcblxuICAgIGlmICghd29yZHMpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFVua25vd24gbG9jYWxlOiAke29Mb2NhbGUuYmFzZU5hbWV9YCk7XG4gICAgfVxuXG4gICAgbGV0IGN1cnJlbmN5ID0gb3B0aW9ucz8uY3VycmVuY3kgPz8gXCJcIjtcbiAgICBpZiAoY3VycmVuY3kudHJpbSgpID09IFwiXCIgJiYgT2JqZWN0LmtleXMod29yZHMuY3VycmVuY3kpLmxlbmd0aCA+IDApIHtcbiAgICAgIGN1cnJlbmN5ID0gT2JqZWN0LmtleXMod29yZHMuY3VycmVuY3kpWzBdO1xuICAgIH1cblxuICAgIGlmICghd29yZHMuY3VycmVuY3lbY3VycmVuY3ldKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVbmtub3duIGN1cnJlbmN5ICcke2N1cnJlbmN5fScgaW4gbG9jYWxlICcke29Mb2NhbGUuYmFzZU5hbWV9J2ApO1xuICAgIH1cbiAgICBpZiAoIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBJbnZhbGlkIHZhbHVlOiAke3ZhbHVlfWApO1xuICAgIH1cblxuICAgIGxldCBzaWduV29yZCA9IFwiXCI7XG4gICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSk7XG4gICAgICBzaWduV29yZCA9ICh3b3Jkcy50ZXh0cz8ubWludXMgPz8gXCItXCIpICsgXCIgXCI7XG4gICAgfVxuXG4gICAgY29uc3QgaW50UGFydCA9IE1hdGgudHJ1bmModmFsdWUpO1xuICAgIGNvbnN0IGRlY1BhcnQgPSBNYXRoLnJvdW5kKCh2YWx1ZSAtIGludFBhcnQpICogMTAwKTtcblxuICAgIGxldCBzVmFsID0gc2lnbldvcmQgKyB0aGlzLl9kaWdpdEdyb3VwKGludFBhcnQsIHVuZGVmaW5lZCwgd29yZHMsIHsgY3VycmVuY3ksIGlzRnJhY3Rpb246IGZhbHNlIH0pO1xuICAgIGlmIChzVmFsICE9IFwiXCIpIHtcbiAgICAgIHNWYWwgKz0gXCIgXCI7XG4gICAgfVxuICAgIHJldHVybiBzVmFsICsgKGRlY1BhcnQgPT0gMCAmJiB3b3Jkcy5jdXJyZW5jeVtjdXJyZW5jeV0ub25seVxuICAgICAgICAgICAgICAgICAgICAgID8gd29yZHMuY3VycmVuY3lbY3VycmVuY3ldLm9ubHlcbiAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuX2RpZ2l0R3JvdXAoZGVjUGFydCwgdW5kZWZpbmVkLCB3b3JkcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgY3VycmVuY3ksIGlzRnJhY3Rpb246IHRydWUsIGZyYWN0aW9uQXNOdW1iZXI6IG9wdGlvbnM/LmZyYWN0aW9uQXNOdW1iZXIgPz8gdHJ1ZSB9XG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICApO1xuICB9XG4gIC8qKlxuICAgKiBHZXRzIHRoZSByZXN1bHQgb2YgdGhlIHNwZWNpZmllZCBfdW5pdF8gZm9ybWF0dGluZ1xuICAgKiBAcGFyYW0gdmFsdWUgQSB2YWx1ZSBpbiB1bml0c1xuICAgKiBAcGFyYW0gdW5pdCBSZXF1aXJlZCB2YWx1ZSBpbiB1bml0IGZvcm1hdHRpbmcuIFBvc3NpYmxlIHZhbHVlcyBhcmUgW2NvcmUgdW5pdCBpZGVudGlmaWVyc10oaHR0cHM6Ly90YzM5LmVzL3Byb3Bvc2FsLXVuaWZpZWQtaW50bC1udW1iZXJmb3JtYXQvc2VjdGlvbjYvbG9jYWxlcy1jdXJyZW5jaWVzLXR6X3Byb3Bvc2VkX291dC5odG1sI3NlYy1pc3NhbmN0aW9uZWRzaW1wbGV1bml0aWRlbnRpZmllcikgdGhhdCB3YXMgc2VsZWN0ZWQgZm9yIHVzZSBpbiBFQ01BU2NyaXB0LiBQYWlycyBvZiBzaW1wbGUgdW5pdHMgY2FuIGJlIGNvbmNhdGVuYXRlZCB3aXRoIFwiLXBlci1cIiB0byBtYWtlIGEgY29tcG91bmQgdW5pdC5cbiAgICogQHBhcmFtIG9wdGlvbnMgQ29uZmlndXJhdGlvbiBvYmplY3RcbiAgICogQHJldHVybnMgU3RyaW5nXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIF9sb2NhbGVfIHZhbHVlIGlzIGludmFsaWQgaW4gYG9wdGlvbnNgXG4gICAqIEBzdGF0aWNcbiAgICovXG4gIHN0YXRpYyBzcGVsbFVuaXQodmFsdWU6IG51bWJlciwgdW5pdDogc3RyaW5nLCBvcHRpb25zPzogeyBsb2NhbGU/OiBzdHJpbmcgfCBMb2NhbGUsIHVuaXREaXNwbGF5PzogXCJsb25nXCJ8XCJzaG9ydFwifFwibmFycm93XCIsIHZhbHVlQXNOdW1iZXI/OiBib29sZWFufSk6IHN0cmluZyB7XG4gICAgY29uc3Qgb0xvY2FsZSA9IG9wdGlvbnM/LmxvY2FsZSBpbnN0YW5jZW9mIExvY2FsZSA/IG9wdGlvbnMubG9jYWxlIDogbmV3IExvY2FsZShvcHRpb25zPy5sb2NhbGUpO1xuICAgIGxldCBvdXRwdXQgPSAobmV3IEludGwuTnVtYmVyRm9ybWF0KG9Mb2NhbGUuYmFzZU5hbWUsIHtzdHlsZTogXCJ1bml0XCIsIHVuaXQsIHVuaXREaXNwbGF5OiBvcHRpb25zPy51bml0RGlzcGxheSA/PyBcImxvbmdcIn0pKS5mb3JtYXQodmFsdWUpO1xuICAgIGlmICggIShvcHRpb25zPy52YWx1ZUFzTnVtYmVyPz9mYWxzZSkgJiYgTnVtYmVyLmlzSW50ZWdlcih2YWx1ZSkgKSB7XG4gICAgICBvdXRwdXQgPSBOdW1iZXJTcGVsbGVyLnNwZWxsSW50ZWdlcih2YWx1ZSwge2xvY2FsZTogb3B0aW9ucz8ubG9jYWxlfSkgKyBcIiBcIisgU3RyaW5ncy5nZXRMYXN0VG9rZW4ob3V0cHV0LCBcIiBcIilbMF07XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cblxufVxuIl19