PHP WebShell
Текущая директория: /opt/BitGoJS/modules/utxo-lib/dist/test/bitgo/psbt
Просмотр файла: SignVerifyPsbtAndTx.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const bitgo_1 = require("../../../src/bitgo");
const testutil_1 = require("../../../src/testutil");
const src_1 = require("../../../src");
const outputScripts_1 = require("../../../src/bitgo/outputScripts");
const rootWalletKeys = (0, testutil_1.getDefaultWalletKeys)();
const signs = ['unsigned', 'halfsigned', 'fullsigned'];
const neutratedRootWalletKeys = new bitgo_1.RootWalletKeys(rootWalletKeys.triple.map((bip32) => bip32.neutered()), rootWalletKeys.derivationPrefixes);
const psbtInputs = testutil_1.inputScriptTypes.map((scriptType) => ({ scriptType, value: BigInt(1000) }));
const psbtOutputs = testutil_1.outputScriptTypes.map((scriptType) => ({ scriptType, value: BigInt(900) }));
const txInputs = testutil_1.txnInputScriptTypes.map((scriptType) => ({ scriptType, value: BigInt(1000) }));
const txOutputs = testutil_1.txnOutputScriptTypes.map((scriptType) => ({ scriptType, value: BigInt(900) }));
function getSigValidArray(scriptType, sign) {
if (scriptType === 'p2shP2pk' || sign === 'unsigned') {
return [false, false, false];
}
if (sign === 'halfsigned') {
return [true, false, false];
}
return scriptType === 'p2trMusig2' ? [true, true, false] : [true, false, true];
}
function signCount(sign) {
return sign === 'unsigned' ? 0 : sign === 'halfsigned' ? 1 : 2;
}
function runPsbt(network, sign, inputs, outputs) {
const coin = (0, src_1.getNetworkName)(network);
const signatureCount = signCount(sign);
describe(`psbt build, sign and verify for ${coin} ${sign}`, function () {
it(`getSignatureValidationArray with globalXpub ${coin} ${sign}`, function () {
const psbt = (0, testutil_1.constructPsbt)(inputs, outputs, network, rootWalletKeys, sign);
(0, bitgo_1.addXpubsToPsbt)(psbt, neutratedRootWalletKeys);
psbt.data.inputs.forEach((input, inputIndex) => {
const isP2shP2pk = inputs[inputIndex].scriptType === 'p2shP2pk';
const expectedSigValid = getSigValidArray(inputs[inputIndex].scriptType, sign);
psbt.getSignatureValidationArray(inputIndex, { rootNodes: rootWalletKeys.triple }).forEach((sv, i) => {
if (isP2shP2pk && sign !== 'unsigned' && i === 0) {
assert.strictEqual(sv, true);
}
else {
assert.strictEqual(sv, expectedSigValid[i]);
}
});
});
});
it(`getSignatureValidationArray with rootNodes ${coin} ${sign}`, function () {
const psbt = (0, testutil_1.constructPsbt)(inputs, outputs, network, rootWalletKeys, sign);
(0, bitgo_1.addXpubsToPsbt)(psbt, neutratedRootWalletKeys);
psbt.data.inputs.forEach((input, inputIndex) => {
const isP2shP2pk = inputs[inputIndex].scriptType === 'p2shP2pk';
const expectedSigValid = getSigValidArray(inputs[inputIndex].scriptType, sign);
psbt.getSignatureValidationArray(inputIndex, { rootNodes: neutratedRootWalletKeys.triple }).forEach((sv, i) => {
if (isP2shP2pk && sign !== 'unsigned' && i === 0) {
assert.strictEqual(sv, true);
}
else {
assert.strictEqual(sv, expectedSigValid[i]);
}
});
});
});
it(`getSignatureValidationArrayPsbt ${coin} ${sign}`, function () {
const psbt = (0, testutil_1.constructPsbt)(inputs, outputs, network, rootWalletKeys, sign);
const sigValidations = (0, bitgo_1.getSignatureValidationArrayPsbt)(psbt, neutratedRootWalletKeys);
psbt.data.inputs.forEach((input, inputIndex) => {
const expectedSigValid = getSigValidArray(inputs[inputIndex].scriptType, sign);
const sigValid = sigValidations.find((sv) => sv[0] === inputIndex);
assert.ok(sigValid);
sigValid[1].forEach((sv, i) => assert.strictEqual(sv, expectedSigValid[i]));
});
});
it(`psbt signature counts ${coin} ${sign}`, function () {
const psbt = (0, testutil_1.constructPsbt)(inputs, outputs, network, rootWalletKeys, sign);
const counts = (0, bitgo_1.getStrictSignatureCounts)(psbt);
const countsFromInputs = (0, bitgo_1.getStrictSignatureCounts)(psbt.data.inputs);
assert.strictEqual(counts.length, psbt.data.inputs.length);
assert.strictEqual(countsFromInputs.length, psbt.data.inputs.length);
psbt.data.inputs.forEach((input, inputIndex) => {
const expectedCount = inputs[inputIndex].scriptType === 'p2shP2pk' && signatureCount > 0 ? 1 : signatureCount;
assert.strictEqual((0, bitgo_1.getPsbtInputSignatureCount)(input), expectedCount);
assert.strictEqual((0, bitgo_1.getStrictSignatureCount)(input), expectedCount);
assert.strictEqual(counts[inputIndex], expectedCount);
assert.strictEqual(countsFromInputs[inputIndex], expectedCount);
});
if (sign === 'fullsigned') {
const tx = psbt.finalizeAllInputs().extractTransaction();
const counts = (0, bitgo_1.getStrictSignatureCounts)(tx);
const countsFromIns = (0, bitgo_1.getStrictSignatureCounts)(tx.ins);
tx.ins.forEach((input, inputIndex) => {
const expectedCount = inputs[inputIndex].scriptType === 'p2shP2pk' ? 1 : signatureCount;
assert.strictEqual((0, bitgo_1.getStrictSignatureCount)(input), expectedCount);
assert.strictEqual(counts[inputIndex], expectedCount);
assert.strictEqual(countsFromIns[inputIndex], expectedCount);
});
}
});
});
}
function runTx(network, sign, inputs, outputs) {
const coin = (0, src_1.getNetworkName)(network);
const signatureCount = signCount(sign);
describe(`tx build, sign and verify for ${coin} ${sign}`, function () {
it(`tx signature counts ${coin} ${sign}`, function () {
const txb = (0, testutil_1.constructTxnBuilder)(inputs, outputs, network, rootWalletKeys, sign);
const tx = sign === 'fullsigned' ? txb.build() : txb.buildIncomplete();
const counts = (0, bitgo_1.getStrictSignatureCounts)(tx);
const countsFromIns = (0, bitgo_1.getStrictSignatureCounts)(tx.ins);
assert.strictEqual(counts.length, tx.ins.length);
assert.strictEqual(countsFromIns.length, tx.ins.length);
tx.ins.forEach((input, inputIndex) => {
const expectedCount = inputs[inputIndex].scriptType === 'p2shP2pk' && signatureCount > 0 ? 1 : signatureCount;
assert.strictEqual((0, bitgo_1.getStrictSignatureCount)(input), expectedCount);
assert.strictEqual(counts[inputIndex], expectedCount);
assert.strictEqual(countsFromIns[inputIndex], expectedCount);
});
});
});
}
signs.forEach((sign) => {
(0, src_1.getNetworkList)()
.filter((v) => (0, src_1.isMainnet)(v) && v !== src_1.networks.bitcoinsv)
.forEach((network) => {
const supportedPsbtInputs = psbtInputs.filter((input) => (0, outputScripts_1.isSupportedScriptType)(network, input.scriptType === 'taprootKeyPathSpend' ? 'p2trMusig2' : input.scriptType));
const supportedPsbtOutputs = psbtOutputs.filter((output) => (0, outputScripts_1.isSupportedScriptType)(network, output.scriptType));
runPsbt(network, sign, supportedPsbtInputs, supportedPsbtOutputs);
const supportedTxInputs = txInputs.filter((input) => (0, outputScripts_1.isSupportedScriptType)(network, input.scriptType));
const supportedTxOutputs = txOutputs.filter((output) => (0, outputScripts_1.isSupportedScriptType)(network, output.scriptType));
runTx(network, sign, supportedTxInputs, supportedTxOutputs);
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2lnblZlcmlmeVBzYnRBbmRUeC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvYml0Z28vcHNidC9TaWduVmVyaWZ5UHNidEFuZFR4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaUNBQWlDO0FBRWpDLDhDQVM0QjtBQUU1QixvREFhK0I7QUFDL0Isc0NBQTRGO0FBQzVGLG9FQUF5RTtBQUd6RSxNQUFNLGNBQWMsR0FBRyxJQUFBLCtCQUFvQixHQUFFLENBQUM7QUFDOUMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxVQUFVLEVBQUUsWUFBWSxFQUFFLFlBQVksQ0FBVSxDQUFDO0FBRWhFLE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxzQkFBYyxDQUNoRCxjQUFjLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUEyQixFQUNoRixjQUFjLENBQUMsa0JBQWtCLENBQ2xDLENBQUM7QUFFRixNQUFNLFVBQVUsR0FBRywyQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMvRixNQUFNLFdBQVcsR0FBRyw0QkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUVoRyxNQUFNLFFBQVEsR0FBRyw4QkFBbUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUNoRyxNQUFNLFNB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LG1CQUFtQixHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUN0RCxJQUFBLHFDQUFxQixFQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsVUFBVSxLQUFLLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FDN0csQ0FBQztRQUNGLE1BQU0sb0JBQW9CLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsSUFBQSxxQ0FBcUIsRUFBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDL0csT0FBTyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsbUJBQW1CLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztRQUVsRSxNQUFNLGlCQUFpQixHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLElBQUEscUNBQXFCLEVBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ3ZHLE1BQU0sa0JBQWtCLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsSUFBQSxxQ0FBcUIsRUFBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDM0csS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztJQUM5RCxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5cbmltcG9ydCB7XG4gIGFkZFhwdWJzVG9Qc2J0LFxuICBnZXRQc2J0SW5wdXRTaWduYXR1cmVDb3VudCxcbiAgZ2V0U2lnbmF0dXJlVmFsaWRhdGlvbkFycmF5UHNidCxcbiAgZ2V0U3RyaWN0U2lnbmF0dXJlQ291bnQsXG4gIGdldFN0cmljdFNpZ25hdHVyZUNvdW50cyxcbiAgUm9vdFdhbGxldEtleXMsXG4gIFRyaXBsZSxcbiAgVXR4b1RyYW5zYWN0aW9uLFxufSBmcm9tICcuLi8uLi8uLi9zcmMvYml0Z28nO1xuaW1wb3J0IHsgQklQMzJJbnRlcmZhY2UgfSBmcm9tICdiaXAzMic7XG5pbXBvcnQge1xuICBjb25zdHJ1Y3RQc2J0LFxuICBjb25zdHJ1Y3RUeG5CdWlsZGVyLFxuICBnZXREZWZhdWx0V2FsbGV0S2V5cyxcbiAgSW5wdXQsXG4gIElucHV0U2NyaXB0VHlwZSxcbiAgaW5wdXRTY3JpcHRUeXBlcyxcbiAgT3V0cHV0LFxuICBvdXRwdXRTY3JpcHRUeXBlcyxcbiAgVHhuSW5wdXQsXG4gIHR4bklucHV0U2NyaXB0VHlwZXMsXG4gIFR4bk91dHB1dCxcbiAgdHhuT3V0cHV0U2NyaXB0VHlwZXMsXG59IGZyb20gJy4uLy4uLy4uL3NyYy90ZXN0dXRpbCc7XG5pbXBvcnQgeyBnZXROZXR3b3JrTGlzdCwgZ2V0TmV0d29ya05hbWUsIGlzTWFpbm5ldCwgTmV0d29yaywgbmV0d29ya3MgfSBmcm9tICcuLi8uLi8uLi9zcmMnO1xuaW1wb3J0IHsgaXNTdXBwb3J0ZWRTY3JpcHRUeXBlIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2JpdGdvL291dHB1dFNjcmlwdHMnO1xuaW1wb3J0IHsgU2lnbmF0dXJlVGFyZ2V0VHlwZSB9IGZyb20gJy4vUHNidCc7XG5cbmNvbnN0IHJvb3RXYWxsZXRLZXlzID0gZ2V0RGVmYXVsdFdhbGxldEtleXMoKTtcbmNvbnN0IHNpZ25zID0gWyd1bnNpZ25lZCcsICdoYWxmc2lnbmVkJywgJ2Z1bGxzaWduZWQnXSBhcyBjb25zdDtcblxuY29uc3QgbmV1dHJhdGVkUm9vdFdhbGxldEtleXMgPSBuZXcgUm9vdFdhbGxldEtleXMoXG4gIHJvb3RXYWxsZXRLZXlzLnRyaXBsZS5tYXAoKGJpcDMyKSA9PiBiaXAzMi5uZXV0ZXJlZCgpKSBhcyBUcmlwbGU8QklQMzJJbnRlcmZhY2U+LFxuICByb290V2FsbGV0S2V5cy5kZXJpdmF0aW9uUHJlZml4ZXNcbik7XG5cbmNvbnN0IHBzYnRJbnB1dHMgPSBpbnB1dFNjcmlwdFR5cGVzLm1hcCgoc2NyaXB0VHlwZSkgPT4gKHsgc2NyaXB0VHlwZSwgdmFsdWU6IEJpZ0ludCgxMDAwKSB9KSk7XG5jb25zdCBwc2J0T3V0cHV0cyA9IG91dHB1dFNjcmlwdFR5cGVzLm1hcCgoc2NyaXB0VHlwZSkgPT4gKHsgc2NyaXB0VHlwZSwgdmFsdWU6IEJpZ0ludCg5MDApIH0pKTtcblxuY29uc3QgdHhJbnB1dHMgPSB0eG5JbnB1dFNjcmlwdFR5cGVzLm1hcCgoc2NyaXB0VHlwZSkgPT4gKHsgc2NyaXB0VHlwZSwgdmFsdWU6IEJpZ0ludCgxMDAwKSB9KSk7XG5jb25zdCB0eE91dHB1dHMgPSB0eG5PdXRwdXRTY3JpcHRUeXBlcy5tYXAoKHNjcmlwdFR5cGUpID0+ICh7IHNjcmlwdFR5cGUsIHZhbHVlOiBCaWdJbnQoOTAwKSB9KSk7XG5cbmZ1bmN0aW9uIGdldFNpZ1ZhbGlkQXJyYXkoc2NyaXB0VHlwZTogSW5wdXRTY3JpcHRUeXBlLCBzaWduOiBTaWduYXR1cmVUYXJnZXRUeXBlKTogVHJpcGxlPGJvb2xlYW4+IHtcbiAgaWYgKHNjcmlwdFR5cGUgPT09ICdwMnNoUDJwaycgfHwgc2lnbiA9PT0gJ3Vuc2lnbmVkJykge1xuICAgIHJldHVybiBbZmFsc2UsIGZhbHNlLCBmYWxzZV07XG4gIH1cbiAgaWYgKHNpZ24gPT09ICdoYWxmc2lnbmVkJykge1xuICAgIHJldHVybiBbdHJ1ZSwgZmFsc2UsIGZhbHNlXTtcbiAgfVxuICByZXR1cm4gc2NyaXB0VHlwZSA9PT0gJ3AydHJNdXNpZzInID8gW3RydWUsIHRydWUsIGZhbHNlXSA6IFt0cnVlLCBmYWxzZSwgdHJ1ZV07XG59XG5cbmZ1bmN0aW9uIHNpZ25Db3VudChzaWduOiBTaWduYXR1cmVUYXJnZXRUeXBlKSB7XG4gIHJldHVybiBzaWduID09PSAndW5zaWduZWQnID8gMCA6IHNpZ24gPT09ICdoYWxmc2lnbmVkJyA/IDEgOiAyO1xufVxuXG5mdW5jdGlvbiBydW5Qc2J0KG5ldHdvcms6IE5ldHdvcmssIHNpZ246IFNpZ25hdHVyZVRhcmdldFR5cGUsIGlucHV0czogSW5wdXRbXSwgb3V0cHV0czogT3V0cHV0W10pIHtcbiAgY29uc3QgY29pbiA9IGdldE5ldHdvcmtOYW1lKG5ldHdvcmspO1xuICBjb25zdCBzaWduYXR1cmVDb3VudCA9IHNpZ25Db3VudChzaWduKTtcblxuICBkZXNjcmliZShgcHNidCBidWlsZCwgc2lnbiBhbmQgdmVyaWZ5IGZvciAke2NvaW59ICR7c2lnbn1gLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoYGdldFNpZ25hdHVyZVZhbGlkYXRpb25BcnJheSB3aXRoIGdsb2JhbFhwdWIgJHtjb2lufSAke3NpZ259YCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQoaW5wdXRzLCBvdXRwdXRzLCBuZXR3b3JrLCByb290V2FsbGV0S2V5cywgc2lnbik7XG4gICAgICBhZGRYcHVic1RvUHNidChwc2J0LCBuZXV0cmF0ZWRSb290V2FsbGV0S2V5cyk7XG4gICAgICBwc2J0LmRhdGEuaW5wdXRzLmZvckVhY2goKGlucHV0LCBpbnB1dEluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGlzUDJzaFAycGsgPSBpbnB1dHNbaW5wdXRJbmRleF0uc2NyaXB0VHlwZSA9PT0gJ3Ayc2hQMnBrJztcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRTaWdWYWxpZCA9IGdldFNpZ1ZhbGlkQXJyYXkoaW5wdXRzW2lucHV0SW5kZXhdLnNjcmlwdFR5cGUsIHNpZ24pO1xuICAgICAgICBwc2J0LmdldFNpZ25hdHVyZVZhbGlkYXRpb25BcnJheShpbnB1dEluZGV4LCB7IHJvb3ROb2Rlczogcm9vdFdhbGxldEtleXMudHJpcGxlIH0pLmZvckVhY2goKHN2LCBpKSA9PiB7XG4gICAgICAgICAgaWYgKGlzUDJzaFAycGsgJiYgc2lnbiAhPT0gJ3Vuc2lnbmVkJyAmJiBpID09PSAwKSB7XG4gICAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc3YsIHRydWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc3YsIGV4cGVjdGVkU2lnVmFsaWRbaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KGBnZXRTaWduYXR1cmVWYWxpZGF0aW9uQXJyYXkgd2l0aCByb290Tm9kZXMgJHtjb2lufSAke3NpZ259YCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQoaW5wdXRzLCBvdXRwdXRzLCBuZXR3b3JrLCByb290V2FsbGV0S2V5cywgc2lnbik7XG4gICAgICBhZGRYcHVic1RvUHNidChwc2J0LCBuZXV0cmF0ZWRSb290V2FsbGV0S2V5cyk7XG4gICAgICBwc2J0LmRhdGEuaW5wdXRzLmZvckVhY2goKGlucHV0LCBpbnB1dEluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGlzUDJzaFAycGsgPSBpbnB1dHNbaW5wdXRJbmRleF0uc2NyaXB0VHlwZSA9PT0gJ3Ayc2hQMnBrJztcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRTaWdWYWxpZCA9IGdldFNpZ1ZhbGlkQXJyYXkoaW5wdXRzW2lucHV0SW5kZXhdLnNjcmlwdFR5cGUsIHNpZ24pO1xuICAgICAgICBwc2J0LmdldFNpZ25hdHVyZVZhbGlkYXRpb25BcnJheShpbnB1dEluZGV4LCB7IHJvb3ROb2RlczogbmV1dHJhdGVkUm9vdFdhbGxldEtleXMudHJpcGxlIH0pLmZvckVhY2goKHN2LCBpKSA9PiB7XG4gICAgICAgICAgaWYgKGlzUDJzaFAycGsgJiYgc2lnbiAhPT0gJ3Vuc2lnbmVkJyAmJiBpID09PSAwKSB7XG4gICAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc3YsIHRydWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc3YsIGV4cGVjdGVkU2lnVmFsaWRbaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KGBnZXRTaWduYXR1cmVWYWxpZGF0aW9uQXJyYXlQc2J0ICAke2NvaW59ICR7c2lnbn1gLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwc2J0ID0gY29uc3RydWN0UHNidChpbnB1dHMsIG91dHB1dHMsIG5ldHdvcmssIHJvb3RXYWxsZXRLZXlzLCBzaWduKTtcbiAgICAgIGNvbnN0IHNpZ1ZhbGlkYXRpb25zID0gZ2V0U2lnbmF0dXJlVmFsaWRhdGlvbkFycmF5UHNidChwc2J0LCBuZXV0cmF0ZWRSb290V2FsbGV0S2V5cyk7XG4gICAgICBwc2J0LmRhdGEuaW5wdXRzLmZvckVhY2goKGlucHV0LCBpbnB1dEluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkU2lnVmFsaWQgPSBnZXRTaWdWYWxpZEFycmF5KGlucHV0c1tpbnB1dEluZGV4XS5zY3JpcHRUeXBlLCBzaWduKTtcbiAgICAgICAgY29uc3Qgc2lnVmFsaWQgPSBzaWdWYWxpZGF0aW9ucy5maW5kKChzdikgPT4gc3ZbMF0gPT09IGlucHV0SW5kZXgpO1xuICAgICAgICBhc3NlcnQub2soc2lnVmFsaWQpO1xuICAgICAgICBzaWdWYWxpZFsxXS5mb3JFYWNoKChzdiwgaSkgPT4gYXNzZXJ0LnN0cmljdEVxdWFsKHN2LCBleHBlY3RlZFNpZ1ZhbGlkW2ldKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KGBwc2J0IHNpZ25hdHVyZSBjb3VudHMgJHtjb2lufSAke3NpZ259YCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHNidCA9IGNvbnN0cnVjdFBzYnQoaW5wdXRzLCBvdXRwdXRzLCBuZXR3b3JrLCByb290V2FsbGV0S2V5cywgc2lnbik7XG4gICAgICBjb25zdCBjb3VudHMgPSBnZXRTdHJpY3RTaWduYXR1cmVDb3VudHMocHNidCk7XG4gICAgICBjb25zdCBjb3VudHNGcm9tSW5wdXRzID0gZ2V0U3RyaWN0U2lnbmF0dXJlQ291bnRzKHBzYnQuZGF0YS5pbnB1dHMpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoY291bnRzLmxlbmd0aCwgcHNidC5kYXRhLmlucHV0cy5sZW5ndGgpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNvdW50c0Zyb21JbnB1dHMubGVuZ3RoLCBwc2J0LmRhdGEuaW5wdXRzLmxlbmd0aCk7XG4gICAgICBwc2J0LmRhdGEuaW5wdXRzLmZvckVhY2goKGlucHV0LCBpbnB1dEluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkQ291bnQgPSBpbnB1dHNbaW5wdXRJbmRleF0uc2NyaXB0VHlwZSA9PT0gJ3Ayc2hQMnBrJyAmJiBzaWduYXR1cmVDb3VudCA+IDAgPyAxIDogc2lnbmF0dXJlQ291bnQ7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChnZXRQc2J0SW5wdXRTaWduYXR1cmVDb3VudChpbnB1dCksIGV4cGVjdGVkQ291bnQpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZ2V0U3RyaWN0U2lnbmF0dXJlQ291bnQoaW5wdXQpLCBleHBlY3RlZENvdW50KTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNvdW50c1tpbnB1dEluZGV4XSwgZXhwZWN0ZWRDb3VudCk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChjb3VudHNGcm9tSW5wdXRzW2lucHV0SW5kZXhdLCBleHBlY3RlZENvdW50KTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoc2lnbiA9PT0gJ2Z1bGxzaWduZWQnKSB7XG4gICAgICAgIGNvbnN0IHR4ID0gcHNidC5maW5hbGl6ZUFsbElucHV0cygpLmV4dHJhY3RUcmFuc2FjdGlvbigpIGFzIFV0eG9UcmFuc2FjdGlvbjxiaWdpbnQ+O1xuICAgICAgICBjb25zdCBjb3VudHMgPSBnZXRTdHJpY3RTaWduYXR1cmVDb3VudHModHgpO1xuICAgICAgICBjb25zdCBjb3VudHNGcm9tSW5zID0gZ2V0U3RyaWN0U2lnbmF0dXJlQ291bnRzKHR4Lmlucyk7XG5cbiAgICAgICAgdHguaW5zLmZvckVhY2goKGlucHV0LCBpbnB1dEluZGV4KSA9PiB7XG4gICAgICAgICAgY29uc3QgZXhwZWN0ZWRDb3VudCA9IGlucHV0c1tpbnB1dEluZGV4XS5zY3JpcHRUeXBlID09PSAncDJzaFAycGsnID8gMSA6IHNpZ25hdHVyZUNvdW50O1xuICAgICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChnZXRTdHJpY3RTaWduYXR1cmVDb3VudChpbnB1dCksIGV4cGVjdGVkQ291bnQpO1xuICAgICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChjb3VudHNbaW5wdXRJbmRleF0sIGV4cGVjdGVkQ291bnQpO1xuICAgICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChjb3VudHNGcm9tSW5zW2lucHV0SW5kZXhdLCBleHBlY3RlZENvdW50KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBydW5UeDxUTnVtYmVyIGV4dGVuZHMgbnVtYmVyIHwgYmlnaW50PihcbiAgbmV0d29yazogTmV0d29yayxcbiAgc2lnbjogU2lnbmF0dXJlVGFyZ2V0VHlwZSxcbiAgaW5wdXRzOiBUeG5JbnB1dDxUTnVtYmVyPltdLFxuICBvdXRwdXRzOiBUeG5PdXRwdXQ8VE51bWJlcj5bXVxuKSB7XG4gIGNvbnN0IGNvaW4gPSBnZXROZXR3b3JrTmFtZShuZXR3b3JrKTtcbiAgY29uc3Qgc2lnbmF0dXJlQ291bnQgPSBzaWduQ291bnQoc2lnbik7XG4gIGRlc2NyaWJlKGB0eCBidWlsZCwgc2lnbiBhbmQgdmVyaWZ5IGZvciAke2NvaW59ICR7c2lnbn1gLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoYHR4IHNpZ25hdHVyZSBjb3VudHMgJHtjb2lufSAke3NpZ259YCwgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhiID0gY29uc3RydWN0VHhuQnVpbGRlcihpbnB1dHMsIG91dHB1dHMsIG5ldHdvcmssIHJvb3RXYWxsZXRLZXlzLCBzaWduKTtcbiAgICAgIGNvbnN0IHR4ID0gc2lnbiA9PT0gJ2Z1bGxzaWduZWQnID8gdHhiLmJ1aWxkKCkgOiB0eGIuYnVpbGRJbmNvbXBsZXRlKCk7XG5cbiAgICAgIGNvbnN0IGNvdW50cyA9IGdldFN0cmljdFNpZ25hdHVyZUNvdW50cyh0eCk7XG4gICAgICBjb25zdCBjb3VudHNGcm9tSW5zID0gZ2V0U3RyaWN0U2lnbmF0dXJlQ291bnRzKHR4Lmlucyk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChjb3VudHMubGVuZ3RoLCB0eC5pbnMubGVuZ3RoKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChjb3VudHNGcm9tSW5zLmxlbmd0aCwgdHguaW5zLmxlbmd0aCk7XG4gICAgICB0eC5pbnMuZm9yRWFjaCgoaW5wdXQsIGlucHV0SW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRDb3VudCA9IGlucHV0c1tpbnB1dEluZGV4XS5zY3JpcHRUeXBlID09PSAncDJzaFAycGsnICYmIHNpZ25hdHVyZUNvdW50ID4gMCA/IDEgOiBzaWduYXR1cmVDb3VudDtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGdldFN0cmljdFNpZ25hdHVyZUNvdW50KGlucHV0KSwgZXhwZWN0ZWRDb3VudCk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChjb3VudHNbaW5wdXRJbmRleF0sIGV4cGVjdGVkQ291bnQpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoY291bnRzRnJvbUluc1tpbnB1dEluZGV4XSwgZXhwZWN0ZWRDb3VudCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbnNpZ25zLmZvckVhY2goKHNpZ24pID0+IHtcbiAgZ2V0TmV0d29ya0xpc3QoKVxuICAgIC5maWx0ZXIoKHYpID0+IGlzTWFpbm5ldCh2KSAmJiB2ICE9PSBuZXR3b3Jrcy5iaXRjb2luc3YpXG4gICAgLmZvckVhY2goKG5ldHdvcmspID0+IHtcbiAgICAgIGNvbnN0IHN1cHBvcnRlZFBzYnRJbnB1dHMgPSBwc2J0SW5wdXRzLmZpbHRlcigoaW5wdXQpID0+XG4gICAgICAgIGlzU3VwcG9ydGVkU2NyaXB0VHlwZShuZXR3b3JrLCBpbnB1dC5zY3JpcHRUeXBlID09PSAndGFwcm9vdEtleVBhdGhTcGVuZCcgPyAncDJ0ck11c2lnMicgOiBpbnB1dC5zY3JpcHRUeXBlKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IHN1cHBvcnRlZFBzYnRPdXRwdXRzID0gcHNidE91dHB1dHMuZmlsdGVyKChvdXRwdXQpID0+IGlzU3VwcG9ydGVkU2NyaXB0VHlwZShuZXR3b3JrLCBvdXRwdXQuc2NyaXB0VHlwZSkpO1xuICAgICAgcnVuUHNidChuZXR3b3JrLCBzaWduLCBzdXBwb3J0ZWRQc2J0SW5wdXRzLCBzdXBwb3J0ZWRQc2J0T3V0cHV0cyk7XG5cbiAgICAgIGNvbnN0IHN1cHBvcnRlZFR4SW5wdXRzID0gdHhJbnB1dHMuZmlsdGVyKChpbnB1dCkgPT4gaXNTdXBwb3J0ZWRTY3JpcHRUeXBlKG5ldHdvcmssIGlucHV0LnNjcmlwdFR5cGUpKTtcbiAgICAgIGNvbnN0IHN1cHBvcnRlZFR4T3V0cHV0cyA9IHR4T3V0cHV0cy5maWx0ZXIoKG91dHB1dCkgPT4gaXNTdXBwb3J0ZWRTY3JpcHRUeXBlKG5ldHdvcmssIG91dHB1dC5zY3JpcHRUeXBlKSk7XG4gICAgICBydW5UeChuZXR3b3JrLCBzaWduLCBzdXBwb3J0ZWRUeElucHV0cywgc3VwcG9ydGVkVHhPdXRwdXRzKTtcbiAgICB9KTtcbn0pO1xuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!