UNPKG

@bitgo/utxo-bin

Version:

Command-line utility for BitGo UTXO transactions

141 lines 19.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAsPlaceholderDescription = getAsPlaceholderDescription; exports.getFixedScriptAddressPlaceholderDescription = getFixedScriptAddressPlaceholderDescription; exports.formatAddressTree = formatAddressTree; exports.formatAddressWithFormatString = formatAddressWithFormatString; exports.formatFixedScriptAddress = formatFixedScriptAddress; exports.getRange = getRange; exports.parseIndexRange = parseIndexRange; exports.generateFixedScriptAddress = generateFixedScriptAddress; exports.getDescriptorAddressPlaceholderDescription = getDescriptorAddressPlaceholderDescription; exports.formatDescriptorAddress = formatDescriptorAddress; exports.generateDescriptorAddress = generateDescriptorAddress; const assert = require("assert"); const utxolib = require("@bitgo/utxo-lib"); const wasm_miniscript_1 = require("@bitgo/wasm-miniscript"); const Parser_1 = require("./Parser"); const parseUnknown_1 = require("./parseUnknown"); const format_1 = require("./format"); const args_1 = require("./args"); function getDefaultChainCodes() { return utxolib.bitgo.chainCodes.filter( // these are rare and show an annoying warning in stderr (c) => utxolib.bitgo.scriptTypeForChain(c) !== 'p2tr' && utxolib.bitgo.scriptTypeForChain(c) !== 'p2trMusig2'); } const fixedScriptPlaceholders = { '%c': 'chain', '%i': 'index', '%p': 'userPath', '%t': 'type', '%p0': 'userPath', '%p1': 'backupPath', '%p2': 'bitgoPath', '%k0': 'userKey', '%k1': 'backupKey', '%k2': 'bitgoKey', '%s': 'scriptPubKey', '%r': 'redeemScript', '%w': 'witnessScript', '%a': 'address', }; function getAsPlaceholderDescription(v) { return Object.entries(v) .map(([placeholder, prop]) => `${placeholder} -> ${prop}`) .join('\n'); } function getFixedScriptAddressPlaceholderDescription() { return getAsPlaceholderDescription(fixedScriptPlaceholders); } function getAddressProperties(keys, chain, index, network) { const [userPath, backupPath, bitgoPath] = keys.triple.map((k) => keys.getDerivationPath(k, chain, index)); const scripts = utxolib.bitgo.getWalletOutputScripts(keys, chain, index); const [userKey, backupKey, bitgoKey] = keys.triple.map((k) => k.derivePath(userPath).publicKey.toString('hex')); const address = utxolib.address.fromOutputScript(scripts.scriptPubKey, network); return { chain, index, type: utxolib.bitgo.scriptTypeForChain(chain), userPath, backupPath, bitgoPath, userKey, backupKey, bitgoKey, scriptPubKey: scripts.scriptPubKey.toString('hex'), redeemScript: scripts.redeemScript?.toString('hex'), witnessScript: scripts.witnessScript?.toString('hex'), address, }; } function formatAddressTree(props) { const parser = new Parser_1.Parser(); return (0, format_1.formatTree)((0, parseUnknown_1.parseUnknown)(parser, 'address', props)); } function formatAddressWithFormatString(props, placeholders, format) { // replace all patterns with a % prefix from format string with the corresponding property // e.g. %p0 -> userPath, %k1 -> backupKey, etc. return format.replace(/%[a-z0-9]+/gi, (match) => { if (match in placeholders) { const prop = placeholders[match]; return String(props[prop]); } return match; }); } function formatFixedScriptAddress(props, format) { return formatAddressWithFormatString(props, fixedScriptPlaceholders, format); } function getRange(start, end) { return Array.from({ length: end - start + 1 }, (_, i) => start + i); } function parseIndexRange(ranges) { return ranges.flatMap((range) => { const [start, end] = range.split('-'); if (end) { return getRange(Number(start), Number(end)); } return [Number(start)]; }); } function* generateFixedScriptAddress(argv) { const rootXpubs = (0, args_1.getRootWalletKeys)(argv); const chains = argv.chain ?? getDefaultChainCodes(); for (const i of argv.index) { for (const chain of chains) { assert(utxolib.bitgo.isChainCode(chain)); // yield formatAddress(rootXpubs, chain, i, argv.network ?? utxolib.networks.bitcoin, argv.format); yield getAddressProperties(rootXpubs, chain, i, argv.network ?? utxolib.networks.bitcoin); } } } const descriptorAddressPlaceholders = { '%d': 'descriptor', '%i': 'index', '%e': 'explicitScript', '%s': 'scriptPubKey', '%a': 'address', }; function getDescriptorAddressPlaceholderDescription() { return getAsPlaceholderDescription(descriptorAddressPlaceholders); } function formatDescriptorAddress(props, format) { return formatAddressWithFormatString(props, descriptorAddressPlaceholders, format); } function* generateDescriptorAddress(argv) { const descriptor = wasm_miniscript_1.Descriptor.fromString(argv.descriptor, 'derivable'); for (const i of argv.index) { const derived = descriptor.atDerivationIndex(i); const explicitScript = Buffer.from(derived.encode()); const scriptPubKey = Buffer.from(derived.scriptPubkey()); const address = utxolib.address.fromOutputScript(scriptPubKey, argv.network); yield { descriptor: derived.toString(), index: i, address, explicitScript: explicitScript.toString('hex'), scriptPubKey: scriptPubKey.toString('hex'), }; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVBZGRyZXNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2dlbmVyYXRlQWRkcmVzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWtEQSxrRUFJQztBQUVELGtHQUVDO0FBNkJELDhDQUdDO0FBRUQsc0VBY0M7QUFFRCw0REFFQztBQUVELDRCQUVDO0FBRUQsMENBUUM7QUFFRCxnRUFpQkM7QUFrQkQsZ0dBRUM7QUFFRCwwREFFQztBQUVELDhEQW9CQztBQTdMRCxpQ0FBaUM7QUFFakMsMkNBQTJDO0FBQzNDLDREQUFvRDtBQUVwRCxxQ0FBa0M7QUFDbEMsaURBQThDO0FBQzlDLHFDQUFzQztBQUN0QyxpQ0FBdUQ7QUFFdkQsU0FBUyxvQkFBb0I7SUFDM0IsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNO0lBQ3BDLHdEQUF3RDtJQUN4RCxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxNQUFNLElBQUksT0FBTyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxZQUFZLENBQzlHLENBQUM7QUFDSixDQUFDO0FBa0JELE1BQU0sdUJBQXVCLEdBQUc7SUFDOUIsSUFBSSxFQUFFLE9BQU87SUFDYixJQUFJLEVBQUUsT0FBTztJQUNiLElBQUksRUFBRSxVQUFVO0lBQ2hCLElBQUksRUFBRSxNQUFNO0lBQ1osS0FBSyxFQUFFLFVBQVU7SUFDakIsS0FBSyxFQUFFLFlBQVk7SUFDbkIsS0FBSyxFQUFFLFdBQVc7SUFDbEIsS0FBSyxFQUFFLFNBQVM7SUFDaEIsS0FBSyxFQUFFLFdBQVc7SUFDbEIsS0FBSyxFQUFFLFVBQVU7SUFDakIsSUFBSSxFQUFFLGNBQWM7SUFDcEIsSUFBSSxFQUFFLGNBQWM7SUFDcEIsSUFBSSxFQUFFLGVBQWU7SUFDckIsSUFBSSxFQUFFLFNBQVM7Q0FDUCxD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RSxPQUFPLENBQUMsUUFBUSxFQUFFO1lBQzlCLEtBQUssRUFBRSxDQUFDO1lBQ1IsT0FBTztZQUNQLGNBQWMsRUFBRSxjQUFjLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUM5QyxZQUFZLEVBQUUsWUFBWSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7U0FDM0MsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCB7IERlc2NyaXB0b3IgfSBmcm9tICdAYml0Z28vd2FzbS1taW5pc2NyaXB0JztcblxuaW1wb3J0IHsgUGFyc2VyIH0gZnJvbSAnLi9QYXJzZXInO1xuaW1wb3J0IHsgcGFyc2VVbmtub3duIH0gZnJvbSAnLi9wYXJzZVVua25vd24nO1xuaW1wb3J0IHsgZm9ybWF0VHJlZSB9IGZyb20gJy4vZm9ybWF0JztcbmltcG9ydCB7IEtleU9wdGlvbnMsIGdldFJvb3RXYWxsZXRLZXlzIH0gZnJvbSAnLi9hcmdzJztcblxuZnVuY3Rpb24gZ2V0RGVmYXVsdENoYWluQ29kZXMoKTogbnVtYmVyW10ge1xuICByZXR1cm4gdXR4b2xpYi5iaXRnby5jaGFpbkNvZGVzLmZpbHRlcihcbiAgICAvLyB0aGVzZSBhcmUgcmFyZSBhbmQgc2hvdyBhbiBhbm5veWluZyB3YXJuaW5nIGluIHN0ZGVyclxuICAgIChjKSA9PiB1dHhvbGliLmJpdGdvLnNjcmlwdFR5cGVGb3JDaGFpbihjKSAhPT0gJ3AydHInICYmIHV0eG9saWIuYml0Z28uc2NyaXB0VHlwZUZvckNoYWluKGMpICE9PSAncDJ0ck11c2lnMidcbiAgKTtcbn1cblxudHlwZSBGaXhlZFNjcmlwdEFkZHJlc3NQcm9wZXJ0aWVzID0ge1xuICBjaGFpbjogdXR4b2xpYi5iaXRnby5DaGFpbkNvZGU7XG4gIGluZGV4OiBudW1iZXI7XG4gIHR5cGU6IHV0eG9saWIuYml0Z28ub3V0cHV0U2NyaXB0cy5TY3JpcHRUeXBlO1xuICB1c2VyUGF0aDogc3RyaW5nO1xuICBiYWNrdXBQYXRoOiBzdHJpbmc7XG4gIGJpdGdvUGF0aDogc3RyaW5nO1xuICB1c2VyS2V5OiBzdHJpbmc7XG4gIGJhY2t1cEtleTogc3RyaW5nO1xuICBiaXRnb0tleTogc3RyaW5nO1xuICByZWRlZW1TY3JpcHQ/OiBzdHJpbmc7XG4gIHdpdG5lc3NTY3JpcHQ/OiBzdHJpbmc7XG4gIHNjcmlwdFB1YktleTogc3RyaW5nO1xuICBhZGRyZXNzOiBzdHJpbmc7XG59O1xuXG5jb25zdCBmaXhlZFNjcmlwdFBsYWNlaG9sZGVycyA9IHtcbiAgJyVjJzogJ2NoYWluJyxcbiAgJyVpJzogJ2luZGV4JyxcbiAgJyVwJzogJ3VzZXJQYXRoJyxcbiAgJyV0JzogJ3R5cGUnLFxuICAnJXAwJzogJ3VzZXJQYXRoJyxcbiAgJyVwMSc6ICdiYWNrdXBQYXRoJyxcbiAgJyVwMic6ICdiaXRnb1BhdGgnLFxuICAnJWswJzogJ3VzZXJLZXknLFxuICAnJWsxJzogJ2JhY2t1cEtleScsXG4gICclazInOiAnYml0Z29LZXknLFxuICAnJXMnOiAnc2NyaXB0UHViS2V5JyxcbiAgJyVyJzogJ3JlZGVlbVNjcmlwdCcsXG4gICcldyc6ICd3aXRuZXNzU2NyaXB0JyxcbiAgJyVhJzogJ2FkZHJlc3MnLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFzUGxhY2Vob2xkZXJEZXNjcmlwdGlvbih2OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTogc3RyaW5nIHtcbiAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHYpXG4gICAgLm1hcCgoW3BsYWNlaG9sZGVyLCBwcm9wXSkgPT4gYCR7cGxhY2Vob2xkZXJ9IC0+ICR7cHJvcH1gKVxuICAgIC5qb2luKCdcXG4nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZpeGVkU2NyaXB0QWRkcmVzc1BsYWNlaG9sZGVyRGVzY3JpcHRpb24oKTogc3RyaW5nIHtcbiAgcmV0dXJuIGdldEFzUGxhY2Vob2xkZXJEZXNjcmlwdGlvbihmaXhlZFNjcmlwdFBsYWNlaG9sZGVycyk7XG59XG5cbmZ1bmN0aW9uIGdldEFkZHJlc3NQcm9wZXJ0aWVzKFxuICBrZXlzOiB1dHhvbGliLmJpdGdvLlJvb3RXYWxsZXRLZXlzLFxuICBjaGFpbjogdXR4b2xpYi5iaXRnby5DaGFpbkNvZGUsXG4gIGluZGV4OiBudW1iZXIsXG4gIG5ldHdvcms6IHV0eG9saWIuTmV0d29ya1xuKTogRml4ZWRTY3JpcHRBZGRyZXNzUHJvcGVydGllcyB7XG4gIGNvbnN0IFt1c2VyUGF0aCwgYmFja3VwUGF0aCwgYml0Z29QYXRoXSA9IGtleXMudHJpcGxlLm1hcCgoaykgPT4ga2V5cy5nZXREZXJpdmF0aW9uUGF0aChrLCBjaGFpbiwgaW5kZXgpKTtcbiAgY29uc3Qgc2NyaXB0cyA9IHV0eG9saWIuYml0Z28uZ2V0V2FsbGV0T3V0cHV0U2NyaXB0cyhrZXlzLCBjaGFpbiwgaW5kZXgpO1xuICBjb25zdCBbdXNlcktleSwgYmFja3VwS2V5LCBiaXRnb0tleV0gPSBrZXlzLnRyaXBsZS5tYXAoKGspID0+IGsuZGVyaXZlUGF0aCh1c2VyUGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSk7XG4gIGNvbnN0IGFkZHJlc3MgPSB1dHhvbGliLmFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChzY3JpcHRzLnNjcmlwdFB1YktleSwgbmV0d29yayk7XG4gIHJldHVybiB7XG4gICAgY2hhaW4sXG4gICAgaW5kZXgsXG4gICAgdHlwZTogdXR4b2xpYi5iaXRnby5zY3JpcHRUeXBlRm9yQ2hhaW4oY2hhaW4pLFxuICAgIHVzZXJQYXRoLFxuICAgIGJhY2t1cFBhdGgsXG4gICAgYml0Z29QYXRoLFxuICAgIHVzZXJLZXksXG4gICAgYmFja3VwS2V5LFxuICAgIGJpdGdvS2V5LFxuICAgIHNjcmlwdFB1YktleTogc2NyaXB0cy5zY3JpcHRQdWJLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgIHJlZGVlbVNjcmlwdDogc2NyaXB0cy5yZWRlZW1TY3JpcHQ/LnRvU3RyaW5nKCdoZXgnKSxcbiAgICB3aXRuZXNzU2NyaXB0OiBzY3JpcHRzLndpdG5lc3NTY3JpcHQ/LnRvU3RyaW5nKCdoZXgnKSxcbiAgICBhZGRyZXNzLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0QWRkcmVzc1RyZWUocHJvcHM6IEZpeGVkU2NyaXB0QWRkcmVzc1Byb3BlcnRpZXMgfCBEZXNjcmlwdG9yQWRkcmVzc1Byb3BlcnRpZXMpOiBzdHJpbmcge1xuICBjb25zdCBwYXJzZXIgPSBuZXcgUGFyc2VyKCk7XG4gIHJldHVybiBmb3JtYXRUcmVlKHBhcnNlVW5rbm93bihwYXJzZXIsICdhZGRyZXNzJywgcHJvcHMpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdEFkZHJlc3NXaXRoRm9ybWF0U3RyaW5nKFxuICBwcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIHBsYWNlaG9sZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgZm9ybWF0OiBzdHJpbmdcbik6IHN0cmluZyB7XG4gIC8vIHJlcGxhY2UgYWxsIHBhdHRlcm5zIHdpdGggYSAlIHByZWZpeCBmcm9tIGZvcm1hdCBzdHJpbmcgd2l0aCB0aGUgY29ycmVzcG9uZGluZyBwcm9wZXJ0eVxuICAvLyBlLmcuICVwMCAtPiB1c2VyUGF0aCwgJWsxIC0+IGJhY2t1cEtleSwgZXRjLlxuICByZXR1cm4gZm9ybWF0LnJlcGxhY2UoLyVbYS16MC05XSsvZ2ksIChtYXRjaCkgPT4ge1xuICAgIGlmIChtYXRjaCBpbiBwbGFjZWhvbGRlcnMpIHtcbiAgICAgIGNvbnN0IHByb3AgPSBwbGFjZWhvbGRlcnNbbWF0Y2hdO1xuICAgICAgcmV0dXJuIFN0cmluZyhwcm9wc1twcm9wXSk7XG4gICAgfVxuICAgIHJldHVybiBtYXRjaDtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRGaXhlZFNjcmlwdEFkZHJlc3MocHJvcHM6IEZpeGVkU2NyaXB0QWRkcmVzc1Byb3BlcnRpZXMsIGZvcm1hdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGZvcm1hdEFkZHJlc3NXaXRoRm9ybWF0U3RyaW5nKHByb3BzLCBmaXhlZFNjcmlwdFBsYWNlaG9sZGVycywgZm9ybWF0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJhbmdlKHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyKTogbnVtYmVyW10ge1xuICByZXR1cm4gQXJyYXkuZnJvbSh7IGxlbmd0aDogZW5kIC0gc3RhcnQgKyAxIH0sIChfLCBpKSA9PiBzdGFydCArIGkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VJbmRleFJhbmdlKHJhbmdlczogc3RyaW5nW10pOiBudW1iZXJbXSB7XG4gIHJldHVybiByYW5nZXMuZmxhdE1hcCgocmFuZ2UpID0+IHtcbiAgICBjb25zdCBbc3RhcnQsIGVuZF0gPSByYW5nZS5zcGxpdCgnLScpO1xuICAgIGlmIChlbmQpIHtcbiAgICAgIHJldHVybiBnZXRSYW5nZShOdW1iZXIoc3RhcnQpLCBOdW1iZXIoZW5kKSk7XG4gICAgfVxuICAgIHJldHVybiBbTnVtYmVyKHN0YXJ0KV07XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24qIGdlbmVyYXRlRml4ZWRTY3JpcHRBZGRyZXNzKFxuICBhcmd2OiBLZXlPcHRpb25zICYge1xuICAgIG5ldHdvcms/OiB1dHhvbGliLk5ldHdvcms7XG4gICAgY2hhaW4/OiBudW1iZXJbXTtcbiAgICBmb3JtYXQ6IHN0cmluZztcbiAgICBpbmRleDogbnVtYmVyW107XG4gIH1cbik6IEdlbmVyYXRvcjxGaXhlZFNjcmlwdEFkZHJlc3NQcm9wZXJ0aWVzPiB7XG4gIGNvbnN0IHJvb3RYcHVicyA9IGdldFJvb3RXYWxsZXRLZXlzKGFyZ3YpO1xuICBjb25zdCBjaGFpbnMgPSBhcmd2LmNoYWluID8/IGdldERlZmF1bHRDaGFpbkNvZGVzKCk7XG4gIGZvciAoY29uc3QgaSBvZiBhcmd2LmluZGV4KSB7XG4gICAgZm9yIChjb25zdCBjaGFpbiBvZiBjaGFpbnMpIHtcbiAgICAgIGFzc2VydCh1dHhvbGliLmJpdGdvLmlzQ2hhaW5Db2RlKGNoYWluKSk7XG4gICAgICAvLyB5aWVsZCBmb3JtYXRBZGRyZXNzKHJvb3RYcHVicywgY2hhaW4sIGksIGFyZ3YubmV0d29yayA/PyB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4sIGFyZ3YuZm9ybWF0KTtcbiAgICAgIHlpZWxkIGdldEFkZHJlc3NQcm9wZXJ0aWVzKHJvb3RYcHVicywgY2hhaW4sIGksIGFyZ3YubmV0d29yayA/PyB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4pO1xuICAgIH1cbiAgfVxufVxuXG50eXBlIERlc2NyaXB0b3JBZGRyZXNzUHJvcGVydGllcyA9IHtcbiAgZGVzY3JpcHRvcjogc3RyaW5nO1xuICBpbmRleDogbnVtYmVyO1xuICBleHBsaWNpdFNjcmlwdDogc3RyaW5nO1xuICBzY3JpcHRQdWJLZXk6IHN0cmluZztcbiAgYWRkcmVzczogc3RyaW5nO1xufTtcblxuY29uc3QgZGVzY3JpcHRvckFkZHJlc3NQbGFjZWhvbGRlcnMgPSB7XG4gICclZCc6ICdkZXNjcmlwdG9yJyxcbiAgJyVpJzogJ2luZGV4JyxcbiAgJyVlJzogJ2V4cGxpY2l0U2NyaXB0JyxcbiAgJyVzJzogJ3NjcmlwdFB1YktleScsXG4gICclYSc6ICdhZGRyZXNzJyxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREZXNjcmlwdG9yQWRkcmVzc1BsYWNlaG9sZGVyRGVzY3JpcHRpb24oKTogc3RyaW5nIHtcbiAgcmV0dXJuIGdldEFzUGxhY2Vob2xkZXJEZXNjcmlwdGlvbihkZXNjcmlwdG9yQWRkcmVzc1BsYWNlaG9sZGVycyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXREZXNjcmlwdG9yQWRkcmVzcyhwcm9wczogRGVzY3JpcHRvckFkZHJlc3NQcm9wZXJ0aWVzLCBmb3JtYXQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBmb3JtYXRBZGRyZXNzV2l0aEZvcm1hdFN0cmluZyhwcm9wcywgZGVzY3JpcHRvckFkZHJlc3NQbGFjZWhvbGRlcnMsIGZvcm1hdCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiogZ2VuZXJhdGVEZXNjcmlwdG9yQWRkcmVzcyhhcmd2OiB7XG4gIG5ldHdvcms6IHV0eG9saWIuTmV0d29yaztcbiAgZGVzY3JpcHRvcjogc3RyaW5nO1xuICBmb3JtYXQ6IHN0cmluZztcbiAgaW5kZXg6IG51bWJlcltdO1xufSk6IEdlbmVyYXRvcjxEZXNjcmlwdG9yQWRkcmVzc1Byb3BlcnRpZXM+IHtcbiAgY29uc3QgZGVzY3JpcHRvciA9IERlc2NyaXB0b3IuZnJvbVN0cmluZyhhcmd2LmRlc2NyaXB0b3IsICdkZXJpdmFibGUnKTtcbiAgZm9yIChjb25zdCBpIG9mIGFyZ3YuaW5kZXgpIHtcbiAgICBjb25zdCBkZXJpdmVkID0gZGVzY3JpcHRvci5hdERlcml2YXRpb25JbmRleChpKTtcbiAgICBjb25zdCBleHBsaWNpdFNjcmlwdCA9IEJ1ZmZlci5mcm9tKGRlcml2ZWQuZW5jb2RlKCkpO1xuICAgIGNvbnN0IHNjcmlwdFB1YktleSA9IEJ1ZmZlci5mcm9tKGRlcml2ZWQuc2NyaXB0UHVia2V5KCkpO1xuICAgIGNvbnN0IGFkZHJlc3MgPSB1dHhvbGliLmFkZHJlc3MuZnJvbU91dHB1dFNjcmlwdChzY3JpcHRQdWJLZXksIGFyZ3YubmV0d29yayk7XG4gICAgeWllbGQge1xuICAgICAgZGVzY3JpcHRvcjogZGVyaXZlZC50b1N0cmluZygpLFxuICAgICAgaW5kZXg6IGksXG4gICAgICBhZGRyZXNzLFxuICAgICAgZXhwbGljaXRTY3JpcHQ6IGV4cGxpY2l0U2NyaXB0LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgIHNjcmlwdFB1YktleTogc2NyaXB0UHViS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICB9O1xuICB9XG59XG4iXX0=