PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-cspr/dist/test/unit/lib
Просмотр файла: transaction.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = __importDefault(require("assert"));
const should_1 = __importDefault(require("should"));
const statics_1 = require("@bitgo/statics");
const casper_js_sdk_1 = require("casper-js-sdk");
const transaction_1 = require("../../../src/lib/transaction");
const testData = __importStar(require("../../fixtures/resources"));
const lib_1 = require("../../../src/lib");
const constants_1 = require("../../../src/lib/constants");
const utils_1 = require("../../../src/lib/utils");
describe('Cspr Transaction', () => {
const coin = statics_1.coins.get('tcspr');
const factory = new lib_1.TransactionBuilderFactory(coin);
const owner1Address = new lib_1.KeyPair({ pub: testData.ACCOUNT_1.publicKey }).getAddress();
const owner2Address = new lib_1.KeyPair({ pub: testData.ACCOUNT_2.publicKey }).getAddress();
const owner3Address = new lib_1.KeyPair({ pub: testData.ACCOUNT_3.publicKey }).getAddress();
const sourceAddress = new lib_1.KeyPair({ pub: testData.ROOT_ACCOUNT.publicKey }).getAddress();
const getTransaction = () => {
return new transaction_1.Transaction(coin);
};
const getWalletInitTransaction = async () => {
const txBuilder = factory.getWalletInitializationBuilder();
txBuilder.fee(testData.FEE);
txBuilder.owner(owner1Address);
txBuilder.owner(owner2Address);
txBuilder.owner(owner3Address);
txBuilder.source({ address: sourceAddress });
txBuilder.sign({ key: testData.ROOT_ACCOUNT.privateKey });
return (await txBuilder.build());
};
const getWalletInitTransactionUsignExtendedKey = async () => {
const txBuilder = factory.getWalletInitializationBuilder();
txBuilder.fee(testData.FEE);
txBuilder.owner(owner1Address);
txBuilder.owner(owner2Address);
txBuilder.owner(owner3Address);
txBuilder.source({ address: sourceAddress });
txBuilder.sign({ key: testData.ROOT_ACCOUNT.xPrivateKey });
return (await txBuilder.build());
};
const getTransferTransaction = async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.fee({ gasLimit: testData.FEE.gasLimit, gasPrice: testData.FEE.gasPrice });
txBuilder.source({ address: sourceAddress });
txBuilder.to(owner2Address);
txBuilder.amount(testData.MIN_MOTES_AMOUNT);
txBuilder.transferId(255);
return (await txBuilder.build());
};
// Creates a deploy instance, required to test signing.
const getTransferDeploy = () => {
const gasPrice = testData.FEE.gasPrice ? parseInt(testData.FEE.gasPrice, 10) : undefined;
const sourcePublicKey = casper_js_sdk_1.CLPublicKey.fromHex(testData.SECP256K1_PREFIX + testData.ACCOUNT_1.publicKey);
const deployParams = new casper_js_sdk_1.DeployUtil.DeployParams(sourcePublicKey, constants_1.DEFAULT_CHAIN_NAMES.testnet, gasPrice);
const session = casper_js_sdk_1.DeployUtil.ExecutableDeployItem.newTransfer(1, sourcePublicKey, undefined, 123);
const payment = casper_js_sdk_1.DeployUtil.standardPayment(parseInt(testData.FEE.gasLimit, 10));
return casper_js_sdk_1.DeployUtil.makeDeploy(deployParams, session, payment);
};
it('should throw empty transaction', () => {
const tx = getTransaction();
assert_1.default.throws(() => {
tx.toJson();
});
assert_1.default.throws(() => {
tx.toBroadcastFormat();
});
});
describe('should sign if transaction is', () => {
it('valid', async () => {
const tx = getTransaction();
const transferDeploy = getTransferDeploy();
if (transferDeploy) {
tx.casperTx = transferDeploy;
}
const keypair = new lib_1.KeyPair({ prv: testData.ACCOUNT_1.privateKey });
should_1.default.doesNotThrow(() => tx.sign(keypair));
should_1.default.equal(tx.casperTx.approvals[0].signer, testData.SECP256K1_PREFIX + testData.ACCOUNT_1.publicKey);
should_1.default.equal((0, utils_1.isValidTransactionSignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, Buffer.from(tx.casperTx.header.account.value()).toString('hex')), true);
should_1.default.doesNotThrow(() => (0, utils_1.verifySignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, Buffer.from(tx.casperTx.header.account.value()).toString('hex')));
});
it('valid using extended key', async () => {
const tx = getTransaction();
const transferDeploy = getTransferDeploy();
if (transferDeploy) {
tx.casperTx = transferDeploy;
}
const keypair = new lib_1.KeyPair({ prv: testData.ACCOUNT_1.xPrivateKey });
should_1.default.doesNotThrow(() => tx.sign(keypair));
should_1.default.equal(tx.casperTx.approvals[0].signer, testData.SECP256K1_PREFIX + testData.ACCOUNT_1.publicKey);
should_1.default.equal((0, utils_1.isValidTransactionSignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, Buffer.from(tx.casperTx.header.account.value()).toString('hex')), true);
should_1.default.doesNotThrow(() => (0, utils_1.verifySignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, Buffer.from(tx.casperTx.header.account.value()).toString('hex')));
});
it('multiple valid', async () => {
const tx = getTransaction();
const transferDeploy = getTransferDeploy();
if (transferDeploy) {
tx.casperTx = transferDeploy;
}
const keypair = new lib_1.KeyPair({ prv: testData.ACCOUNT_1.privateKey });
const keypair2 = new lib_1.KeyPair({ prv: testData.ACCOUNT_2.privateKey });
should_1.default.doesNotThrow(() => tx.sign(keypair));
should_1.default.equal(tx.casperTx.approvals[0].signer, testData.SECP256K1_PREFIX + testData.ACCOUNT_1.publicKey);
should_1.default.equal((0, utils_1.isValidTransactionSignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey), true);
should_1.default.doesNotThrow(() => (0, utils_1.verifySignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey));
should_1.default.doesNotThrow(() => tx.sign(keypair2));
should_1.default.equal(tx.casperTx.approvals[0].signer, testData.SECP256K1_PREFIX + testData.ACCOUNT_1.publicKey);
should_1.default.equal(tx.casperTx.approvals[1].signer, testData.SECP256K1_PREFIX + testData.ACCOUNT_2.publicKey);
should_1.default.equal((0, utils_1.isValidTransactionSignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey), true);
should_1.default.equal((0, utils_1.isValidTransactionSignature)(tx.casperTx.approvals[1].signature, tx.casperTx.hash, testData.ACCOUNT_2.publicKey), true);
should_1.default.doesNotThrow(() => (0, utils_1.verifySignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey));
should_1.default.doesNotThrow(() => (0, utils_1.verifySignature)(tx.casperTx.approvals[1].signature, tx.casperTx.hash, testData.ACCOUNT_2.publicKey));
});
it('multiple valid using extended keys', async () => {
const tx = getTransaction();
const transferDeploy = getTransferDeploy();
if (transferDeploy) {
tx.casperTx = transferDeploy;
}
const keypair = new lib_1.KeyPair({ prv: testData.ACCOUNT_1.xPrivateKey });
const keypair2 = new lib_1.KeyPair({ prv: testData.ACCOUNT_2.xPrivateKey });
should_1.default.doesNotThrow(() => tx.sign(keypair));
should_1.default.equal(tx.casperTx.approvals[0].signer, testData.SECP256K1_PREFIX + testData.ACCOUNT_1.publicKey);
should_1.default.equal((0, utils_1.isValidTransactionSignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey), true);
should_1.default.doesNotThrow(() => (0, utils_1.verifySignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey));
should_1.default.doesNotThrow(() => tx.sign(keypair2));
should_1.default.equal(tx.casperTx.approvals[0].signer, testData.SECP256K1_PREFIX + testData.ACCOUNT_1.publicKey);
should_1.default.equal(tx.casperTx.approvals[1].signer, testData.SECP256K1_PREFIX + testData.ACCOUNT_2.publicKey);
should_1.default.equal((0, utils_1.isValidTransactionSignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey), true);
should_1.default.equal((0, utils_1.isValidTransactionSignature)(tx.casperTx.approvals[1].signature, tx.casperTx.hash, testData.ACCOUNT_2.publicKey), true);
should_1.default.doesNotThrow(() => (0, utils_1.verifySignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey));
should_1.default.doesNotThrow(() => (0, utils_1.verifySignature)(tx.casperTx.approvals[1].signature, tx.casperTx.hash, testData.ACCOUNT_2.publicKey));
});
it('multiple valid using one extended key', async () => {
const tx = getTransaction();
const transferDeploy = getTransferDeploy();
if (transferDeploy) {
tx.casperTx = transferDeploy;
}
const keypair = new lib_1.KeyPair({ prv: testData.ACCOUNT_1.xPrivateKey });
const keypair2 = new lib_1.KeyPair({ prv: testData.ACCOUNT_2.privateKey });
should_1.default.doesNotThrow(() => tx.sign(keypair));
should_1.default.equal(tx.casperTx.approvals[0].signer, testData.SECP256K1_PREFIX + testData.ACCOUNT_1.publicKey);
should_1.default.equal((0, utils_1.isValidTransactionSignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey), true);
should_1.default.doesNotThrow(() => (0, utils_1.verifySignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey));
should_1.default.doesNotThrow(() => tx.sign(keypair2));
should_1.default.equal(tx.casperTx.approvals[0].signer, testData.SECP256K1_PREFIX + testData.ACCOUNT_1.publicKey);
should_1.default.equal(tx.casperTx.approvals[1].signer, testData.SECP256K1_PREFIX + testData.ACCOUNT_2.publicKey);
should_1.default.equal((0, utils_1.isValidTransactionSignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey), true);
should_1.default.equal((0, utils_1.isValidTransactionSignature)(tx.casperTx.approvals[1].signature, tx.casperTx.hash, testData.ACCOUNT_2.publicKey), true);
should_1.default.doesNotThrow(() => (0, utils_1.verifySignature)(tx.casperTx.approvals[0].signature, tx.casperTx.hash, testData.ACCOUNT_1.publicKey));
should_1.default.doesNotThrow(() => (0, utils_1.verifySignature)(tx.casperTx.approvals[1].signature, tx.casperTx.hash, testData.ACCOUNT_2.publicKey));
});
});
describe('should reject sign if transaction signer is', () => {
it('invalid private key', function () {
const tx = getTransaction();
assert_1.default.throws(() => tx.sign(testData.INVALID_KEYPAIR_PRV));
});
it('public key', function () {
const tx = getTransaction();
const keypair = new lib_1.KeyPair({ pub: testData.ACCOUNT_1.publicKey });
assert_1.default.throws(() => tx.sign(keypair), (e) => e.message === testData.ERROR_MISSING_PRIVATE_KEY);
});
it('public extended key', function () {
const tx = getTransaction();
const keypair = new lib_1.KeyPair({ pub: testData.ACCOUNT_1.xPublicKey });
assert_1.default.throws(() => tx.sign(keypair), (e) => e.message === testData.ERROR_MISSING_PRIVATE_KEY);
});
});
describe('should return encoded tx', function () {
it('wallet initialization', async function () {
const walletInitTx = await getWalletInitTransaction();
const encodedTx = walletInitTx.toBroadcastFormat();
const walletInitJsonTx = JSON.parse(encodedTx);
const argName = 0;
const argValue = 1;
const owner0 = 0;
const owner1 = 1;
const owner2 = 2;
const ownersValues = new Map();
[owner0, owner1, owner2].forEach((index) => {
ownersValues.set(constants_1.OWNER_PREFIX + index, walletInitTx.casperTx.session.getArgByName(constants_1.OWNER_PREFIX + index).value());
});
const jsonOwnerArgs = walletInitJsonTx['deploy']['session']['ModuleBytes']['args'].filter((arg) => ownersValues.has(arg[argName]));
jsonOwnerArgs.length.should.equal(ownersValues.size);
jsonOwnerArgs.forEach((arg) => {
arg[argValue]['parsed'].should.be.equal(ownersValues.get(arg[argName]));
});
});
it('wallet initialization using extended key', async function () {
const walletInitTx = await getWalletInitTransactionUsignExtendedKey();
const encodedTx = walletInitTx.toBroadcastFormat();
const walletInitJsonTx = JSON.parse(encodedTx);
const argName = 0;
const argValue = 1;
const owner0 = 0;
const owner1 = 1;
const owner2 = 2;
const ownersValues = new Map();
[owner0, owner1, owner2].forEach((index) => {
ownersValues.set(constants_1.OWNER_PREFIX + index, walletInitTx.casperTx.session.getArgByName(constants_1.OWNER_PREFIX + index).value());
});
const jsonOwnerArgs = walletInitJsonTx['deploy']['session']['ModuleBytes']['args'].filter((arg) => ownersValues.has(arg[argName]));
jsonOwnerArgs.length.should.equal(ownersValues.size);
jsonOwnerArgs.forEach((arg) => {
arg[argValue]['parsed'].should.be.equal(ownersValues.get(arg[argName]));
});
});
it('transfer', async function () {
const transferTx = await getTransferTransaction();
const encodedTx = transferTx.toBroadcastFormat();
const transferJsonTx = JSON.parse(encodedTx);
const argName = 0;
const argValue = 1;
const transferValues = new Map();
transferValues.set('amount', (0, utils_1.getTransferAmount)(transferTx.casperTx.session));
transferValues.set('to_address', (0, utils_1.getTransferDestinationAddress)(transferTx.casperTx.session));
const transferId = (0, utils_1.getTransferId)(transferTx.casperTx.session);
if (transferId !== undefined) {
transferValues.set('id', transferId.toString());
}
const jsonOwnerArgs = transferJsonTx['deploy']['session']['Transfer']['args'].filter((arg) => transferValues.has(arg[argName]));
jsonOwnerArgs.length.should.equal(transferValues.size);
jsonOwnerArgs.forEach((arg) => {
arg[argValue]['parsed'].should.be.equal(transferValues.get(arg[argName]));
});
});
// TODO STLX-1174: get and decode encoded transaction
it('valid sign', function (done) {
done();
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3RyYW5zYWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsb0RBQTRCO0FBQzVCLG9EQUE0QjtBQUM1Qiw0Q0FBdUM7QUFDdkMsaURBQStFO0FBQy9FLDhEQUEyRDtBQUMzRCxtRUFBcUQ7QUFDckQsMENBQXNFO0FBQ3RFLDBEQUErRTtBQUMvRSxrREFNZ0M7QUFFaEMsUUFBUSxDQUFDLGtCQUFrQixFQUFFLEdBQUcsRUFBRTtJQUNoQyxNQUFNLElBQUksR0FBRyxlQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2hDLE1BQU0sT0FBTyxHQUFHLElBQUksK0JBQXlCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEQsTUFBTSxhQUFhLEdBQUcsSUFBSSxhQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3RGLE1BQU0sYUFBYSxHQUFHLElBQUksYUFBTyxDQUFDLEVBQUUsR0FBRyxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUN0RixNQUFNLGFBQWEsR0FBRyxJQUFJLGFBQU8sQ0FBQyxFQUFFLEdBQUcsRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDdEYsTUFBTSxhQUFhLEdBQUcsSUFBSSxhQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBRXpGLE1BQU0sY0FBYyxHQUFHLEdBQWdCLEVBQUU7UUFDdkMsT0FBTyxJ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Q0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ2xELENBQUM7WUFFRCxNQUFNLGFBQWEsR0FBRyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FDM0YsY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FDakMsQ0FBQztZQUNGLGFBQWEsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFdkQsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUM1QixHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVFLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxxREFBcUQ7UUFDckQsRUFBRSxDQUFDLFlBQVksRUFBRSxVQUFVLElBQUk7WUFDN0IsSUFBSSxFQUFFLENBQUM7UUFDVCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcbmltcG9ydCB7IENMU3RyaW5nLCBEZXBsb3lVdGlsLCBDTFB1YmxpY0tleSBhcyBQdWJsaWNLZXkgfSBmcm9tICdjYXNwZXItanMtc2RrJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2xpYi90cmFuc2FjdGlvbic7XG5pbXBvcnQgKiBhcyB0ZXN0RGF0YSBmcm9tICcuLi8uLi9maXh0dXJlcy9yZXNvdXJjZXMnO1xuaW1wb3J0IHsgS2V5UGFpciwgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB9IGZyb20gJy4uLy4uLy4uL3NyYy9saWInO1xuaW1wb3J0IHsgREVGQVVMVF9DSEFJTl9OQU1FUywgT1dORVJfUFJFRklYIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2xpYi9jb25zdGFudHMnO1xuaW1wb3J0IHtcbiAgZ2V0VHJhbnNmZXJBbW91bnQsXG4gIGdldFRyYW5zZmVyRGVzdGluYXRpb25BZGRyZXNzLFxuICBnZXRUcmFuc2ZlcklkLFxuICBpc1ZhbGlkVHJhbnNhY3Rpb25TaWduYXR1cmUsXG4gIHZlcmlmeVNpZ25hdHVyZSxcbn0gZnJvbSAnLi4vLi4vLi4vc3JjL2xpYi91dGlscyc7XG5cbmRlc2NyaWJlKCdDc3ByIFRyYW5zYWN0aW9uJywgKCkgPT4ge1xuICBjb25zdCBjb2luID0gY29pbnMuZ2V0KCd0Y3NwcicpO1xuICBjb25zdCBmYWN0b3J5ID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbik7XG4gIGNvbnN0IG93bmVyMUFkZHJlc3MgPSBuZXcgS2V5UGFpcih7IHB1YjogdGVzdERhdGEuQUNDT1VOVF8xLnB1YmxpY0tleSB9KS5nZXRBZGRyZXNzKCk7XG4gIGNvbnN0IG93bmVyMkFkZHJlc3MgPSBuZXcgS2V5UGFpcih7IHB1YjogdGVzdERhdGEuQUNDT1VOVF8yLnB1YmxpY0tleSB9KS5nZXRBZGRyZXNzKCk7XG4gIGNvbnN0IG93bmVyM0FkZHJlc3MgPSBuZXcgS2V5UGFpcih7IHB1YjogdGVzdERhdGEuQUNDT1VOVF8zLnB1YmxpY0tleSB9KS5nZXRBZGRyZXNzKCk7XG4gIGNvbnN0IHNvdXJjZUFkZHJlc3MgPSBuZXcgS2V5UGFpcih7IHB1YjogdGVzdERhdGEuUk9PVF9BQ0NPVU5ULnB1YmxpY0tleSB9KS5nZXRBZGRyZXNzKCk7XG5cbiAgY29uc3QgZ2V0VHJhbnNhY3Rpb24gPSAoKTogVHJhbnNhY3Rpb24gPT4ge1xuICAgIHJldHVybiBuZXcgVHJhbnNhY3Rpb24oY29pbik7XG4gIH07XG5cbiAgY29uc3QgZ2V0V2FsbGV0SW5pdFRyYW5zYWN0aW9uID0gYXN5bmMgKCk6IFByb21pc2U8VHJhbnNhY3Rpb24+ID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFdhbGxldEluaXRpYWxpemF0aW9uQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5mZWUodGVzdERhdGEuRkVFKTtcbiAgICB0eEJ1aWxkZXIub3duZXIob3duZXIxQWRkcmVzcyk7XG4gICAgdHhCdWlsZGVyLm93bmVyKG93bmVyMkFkZHJlc3MpO1xuICAgIHR4QnVpbGRlci5vd25lcihvd25lcjNBZGRyZXNzKTtcbiAgICB0eEJ1aWxkZXIuc291cmNlKHsgYWRkcmVzczogc291cmNlQWRkcmVzcyB9KTtcbiAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogdGVzdERhdGEuUk9PVF9BQ0NPVU5ULnByaXZhdGVLZXkgfSk7XG4gICAgcmV0dXJuIChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gIH07XG5cbiAgY29uc3QgZ2V0V2FsbGV0SW5pdFRyYW5zYWN0aW9uVXNpZ25FeHRlbmRlZEtleSA9IGFzeW5jICgpOiBQcm9taXNlPFRyYW5zYWN0aW9uPiA9PiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXIoKTtcbiAgICB0eEJ1aWxkZXIuZmVlKHRlc3REYXRhLkZFRSk7XG4gICAgdHhCdWlsZGVyLm93bmVyKG93bmVyMUFkZHJlc3MpO1xuICAgIHR4QnVpbGRlci5vd25lcihvd25lcjJBZGRyZXNzKTtcbiAgICB0eEJ1aWxkZXIub3duZXIob3duZXIzQWRkcmVzcyk7XG4gICAgdHhCdWlsZGVyLnNvdXJjZSh7IGFkZHJlc3M6IHNvdXJjZUFkZHJlc3MgfSk7XG4gICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IHRlc3REYXRhLlJPT1RfQUNDT1VOVC54UHJpdmF0ZUtleSB9KTtcbiAgICByZXR1cm4gKGF3YWl0IHR4QnVpbGRlci5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgfTtcblxuICBjb25zdCBnZXRUcmFuc2ZlclRyYW5zYWN0aW9uID0gYXN5bmMgKCk6IFByb21pc2U8VHJhbnNhY3Rpb24+ID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpO1xuICAgIHR4QnVpbGRlci5mZWUoeyBnYXNMaW1pdDogdGVzdERhdGEuRkVFLmdhc0xpbWl0LCBnYXNQcmljZTogdGVzdERhdGEuRkVFLmdhc1ByaWNlIH0pO1xuICAgIHR4QnVpbGRlci5zb3VyY2UoeyBhZGRyZXNzOiBzb3VyY2VBZGRyZXNzIH0pO1xuICAgIHR4QnVpbGRlci50byhvd25lcjJBZGRyZXNzKTtcbiAgICB0eEJ1aWxkZXIuYW1vdW50KHRlc3REYXRhLk1JTl9NT1RFU19BTU9VTlQpO1xuICAgIHR4QnVpbGRlci50cmFuc2ZlcklkKDI1NSk7XG4gICAgcmV0dXJuIChhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gIH07XG5cbiAgLy8gQ3JlYXRlcyBhIGRlcGxveSBpbnN0YW5jZSwgcmVxdWlyZWQgdG8gdGVzdCBzaWduaW5nLlxuICBjb25zdCBnZXRUcmFuc2ZlckRlcGxveSA9ICgpOiBEZXBsb3lVdGlsLkRlcGxveSB8IHVuZGVmaW5lZCA9PiB7XG4gICAgY29uc3QgZ2FzUHJpY2UgPSB0ZXN0RGF0YS5GRUUuZ2FzUHJpY2UgPyBwYXJzZUludCh0ZXN0RGF0YS5GRUUuZ2FzUHJpY2UsIDEwKSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBzb3VyY2VQdWJsaWNLZXkgPSBQdWJsaWNLZXkuZnJvbUhleCh0ZXN0RGF0YS5TRUNQMjU2SzFfUFJFRklYICsgdGVzdERhdGEuQUNDT1VOVF8xLnB1YmxpY0tleSk7XG4gICAgY29uc3QgZGVwbG95UGFyYW1zID0gbmV3IERlcGxveVV0aWwuRGVwbG95UGFyYW1zKHNvdXJjZVB1YmxpY0tleSwgREVGQVVMVF9DSEFJTl9OQU1FUy50ZXN0bmV0LCBnYXNQcmljZSk7XG5cbiAgICBjb25zdCBzZXNzaW9uID0gRGVwbG95VXRpbC5FeGVjdXRhYmxlRGVwbG95SXRlbS5uZXdUcmFuc2ZlcigxLCBzb3VyY2VQdWJsaWNLZXksIHVuZGVmaW5lZCwgMTIzKTtcblxuICAgIGNvbnN0IHBheW1lbnQgPSBEZXBsb3lVdGlsLnN0YW5kYXJkUGF5bWVudChwYXJzZUludCh0ZXN0RGF0YS5GRUUuZ2FzTGltaXQsIDEwKSk7XG5cbiAgICByZXR1cm4gRGVwbG95VXRpbC5tYWtlRGVwbG95KGRlcGxveVBhcmFtcywgc2Vzc2lvbiwgcGF5bWVudCk7XG4gIH07XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyBlbXB0eSB0cmFuc2FjdGlvbicsICgpID0+IHtcbiAgICBjb25zdCB0eCA9IGdldFRyYW5zYWN0aW9uKCk7XG4gICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICB0eC50b0pzb24oKTtcbiAgICB9KTtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHtcbiAgICAgIHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzaG91bGQgc2lnbiBpZiB0cmFuc2FjdGlvbiBpcycsICgpID0+IHtcbiAgICBpdCgndmFsaWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eCA9IGdldFRyYW5zYWN0aW9uKCk7XG4gICAgICBjb25zdCB0cmFuc2ZlckRlcGxveSA9IGdldFRyYW5zZmVyRGVwbG95KCk7XG4gICAgICBpZiAodHJhbnNmZXJEZXBsb3kpIHtcbiAgICAgICAgdHguY2FzcGVyVHggPSB0cmFuc2ZlckRlcGxveTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGtleXBhaXIgPSBuZXcgS2V5UGFpcih7IHBydjogdGVzdERhdGEuQUNDT1VOVF8xLnByaXZhdGVLZXkgfSk7XG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IHR4LnNpZ24oa2V5cGFpcikpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduZXIsIHRlc3REYXRhLlNFQ1AyNTZLMV9QUkVGSVggKyB0ZXN0RGF0YS5BQ0NPVU5UXzEucHVibGljS2V5KTtcbiAgICAgIHNob3VsZC5lcXVhbChcbiAgICAgICAgaXNWYWxpZFRyYW5zYWN0aW9uU2lnbmF0dXJlKFxuICAgICAgICAgIHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduYXR1cmUsXG4gICAgICAgICAgdHguY2FzcGVyVHguaGFzaCxcbiAgICAgICAgICBCdWZmZXIuZnJvbSh0eC5jYXNwZXJUeC5oZWFkZXIuYWNjb3VudC52YWx1ZSgpKS50b1N0cmluZygnaGV4JylcbiAgICAgICAgKSxcbiAgICAgICAgdHJ1ZVxuICAgICAgKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT5cbiAgICAgICAgdmVyaWZ5U2lnbmF0dXJlKFxuICAgICAgICAgIHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduYXR1cmUsXG4gICAgICAgICAgdHguY2FzcGVyVHguaGFzaCxcbiAgICAgICAgICBCdWZmZXIuZnJvbSh0eC5jYXNwZXJUeC5oZWFkZXIuYWNjb3VudC52YWx1ZSgpKS50b1N0cmluZygnaGV4JylcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCd2YWxpZCB1c2luZyBleHRlbmRlZCBrZXknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eCA9IGdldFRyYW5zYWN0aW9uKCk7XG4gICAgICBjb25zdCB0cmFuc2ZlckRlcGxveSA9IGdldFRyYW5zZmVyRGVwbG95KCk7XG4gICAgICBpZiAodHJhbnNmZXJEZXBsb3kpIHtcbiAgICAgICAgdHguY2FzcGVyVHggPSB0cmFuc2ZlckRlcGxveTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGtleXBhaXIgPSBuZXcgS2V5UGFpcih7IHBydjogdGVzdERhdGEuQUNDT1VOVF8xLnhQcml2YXRlS2V5IH0pO1xuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB0eC5zaWduKGtleXBhaXIpKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmVyLCB0ZXN0RGF0YS5TRUNQMjU2SzFfUFJFRklYICsgdGVzdERhdGEuQUNDT1VOVF8xLnB1YmxpY0tleSk7XG4gICAgICBzaG91bGQuZXF1YWwoXG4gICAgICAgIGlzVmFsaWRUcmFuc2FjdGlvblNpZ25hdHVyZShcbiAgICAgICAgICB0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmF0dXJlLFxuICAgICAgICAgIHR4LmNhc3BlclR4Lmhhc2gsXG4gICAgICAgICAgQnVmZmVyLmZyb20odHguY2FzcGVyVHguaGVhZGVyLmFjY291bnQudmFsdWUoKSkudG9TdHJpbmcoJ2hleCcpXG4gICAgICAgICksXG4gICAgICAgIHRydWVcbiAgICAgICk7XG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+XG4gICAgICAgIHZlcmlmeVNpZ25hdHVyZShcbiAgICAgICAgICB0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmF0dXJlLFxuICAgICAgICAgIHR4LmNhc3BlclR4Lmhhc2gsXG4gICAgICAgICAgQnVmZmVyLmZyb20odHguY2FzcGVyVHguaGVhZGVyLmFjY291bnQudmFsdWUoKSkudG9TdHJpbmcoJ2hleCcpXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnbXVsdGlwbGUgdmFsaWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eCA9IGdldFRyYW5zYWN0aW9uKCk7XG4gICAgICBjb25zdCB0cmFuc2ZlckRlcGxveSA9IGdldFRyYW5zZmVyRGVwbG95KCk7XG4gICAgICBpZiAodHJhbnNmZXJEZXBsb3kpIHtcbiAgICAgICAgdHguY2FzcGVyVHggPSB0cmFuc2ZlckRlcGxveTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGtleXBhaXIgPSBuZXcgS2V5UGFpcih7IHBydjogdGVzdERhdGEuQUNDT1VOVF8xLnByaXZhdGVLZXkgfSk7XG4gICAgICBjb25zdCBrZXlwYWlyMiA9IG5ldyBLZXlQYWlyKHsgcHJ2OiB0ZXN0RGF0YS5BQ0NPVU5UXzIucHJpdmF0ZUtleSB9KTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gdHguc2lnbihrZXlwYWlyKSk7XG4gICAgICBzaG91bGQuZXF1YWwodHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25lciwgdGVzdERhdGEuU0VDUDI1NksxX1BSRUZJWCArIHRlc3REYXRhLkFDQ09VTlRfMS5wdWJsaWNLZXkpO1xuICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICBpc1ZhbGlkVHJhbnNhY3Rpb25TaWduYXR1cmUodHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25hdHVyZSwgdHguY2FzcGVyVHguaGFzaCwgdGVzdERhdGEuQUNDT1VOVF8xLnB1YmxpY0tleSksXG4gICAgICAgIHRydWVcbiAgICAgICk7XG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+XG4gICAgICAgIHZlcmlmeVNpZ25hdHVyZSh0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmF0dXJlLCB0eC5jYXNwZXJUeC5oYXNoLCB0ZXN0RGF0YS5BQ0NPVU5UXzEucHVibGljS2V5KVxuICAgICAgKTtcblxuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB0eC5zaWduKGtleXBhaXIyKSk7XG4gICAgICBzaG91bGQuZXF1YWwodHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25lciwgdGVzdERhdGEuU0VDUDI1NksxX1BSRUZJWCArIHRlc3REYXRhLkFDQ09VTlRfMS5wdWJsaWNLZXkpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LmNhc3BlclR4LmFwcHJvdmFsc1sxXS5zaWduZXIsIHRlc3REYXRhLlNFQ1AyNTZLMV9QUkVGSVggKyB0ZXN0RGF0YS5BQ0NPVU5UXzIucHVibGljS2V5KTtcbiAgICAgIHNob3VsZC5lcXVhbChcbiAgICAgICAgaXNWYWxpZFRyYW5zYWN0aW9uU2lnbmF0dXJlKHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduYXR1cmUsIHR4LmNhc3BlclR4Lmhhc2gsIHRlc3REYXRhLkFDQ09VTlRfMS5wdWJsaWNLZXkpLFxuICAgICAgICB0cnVlXG4gICAgICApO1xuICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICBpc1ZhbGlkVHJhbnNhY3Rpb25TaWduYXR1cmUodHguY2FzcGVyVHguYXBwcm92YWxzWzFdLnNpZ25hdHVyZSwgdHguY2FzcGVyVHguaGFzaCwgdGVzdERhdGEuQUNDT1VOVF8yLnB1YmxpY0tleSksXG4gICAgICAgIHRydWVcbiAgICAgICk7XG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+XG4gICAgICAgIHZlcmlmeVNpZ25hdHVyZSh0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmF0dXJlLCB0eC5jYXNwZXJUeC5oYXNoLCB0ZXN0RGF0YS5BQ0NPVU5UXzEucHVibGljS2V5KVxuICAgICAgKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT5cbiAgICAgICAgdmVyaWZ5U2lnbmF0dXJlKHR4LmNhc3BlclR4LmFwcHJvdmFsc1sxXS5zaWduYXR1cmUsIHR4LmNhc3BlclR4Lmhhc2gsIHRlc3REYXRhLkFDQ09VTlRfMi5wdWJsaWNLZXkpXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ211bHRpcGxlIHZhbGlkIHVzaW5nIGV4dGVuZGVkIGtleXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eCA9IGdldFRyYW5zYWN0aW9uKCk7XG4gICAgICBjb25zdCB0cmFuc2ZlckRlcGxveSA9IGdldFRyYW5zZmVyRGVwbG95KCk7XG4gICAgICBpZiAodHJhbnNmZXJEZXBsb3kpIHtcbiAgICAgICAgdHguY2FzcGVyVHggPSB0cmFuc2ZlckRlcGxveTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGtleXBhaXIgPSBuZXcgS2V5UGFpcih7IHBydjogdGVzdERhdGEuQUNDT1VOVF8xLnhQcml2YXRlS2V5IH0pO1xuICAgICAgY29uc3Qga2V5cGFpcjIgPSBuZXcgS2V5UGFpcih7IHBydjogdGVzdERhdGEuQUNDT1VOVF8yLnhQcml2YXRlS2V5IH0pO1xuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB0eC5zaWduKGtleXBhaXIpKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmVyLCB0ZXN0RGF0YS5TRUNQMjU2SzFfUFJFRklYICsgdGVzdERhdGEuQUNDT1VOVF8xLnB1YmxpY0tleSk7XG4gICAgICBzaG91bGQuZXF1YWwoXG4gICAgICAgIGlzVmFsaWRUcmFuc2FjdGlvblNpZ25hdHVyZSh0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmF0dXJlLCB0eC5jYXNwZXJUeC5oYXNoLCB0ZXN0RGF0YS5BQ0NPVU5UXzEucHVibGljS2V5KSxcbiAgICAgICAgdHJ1ZVxuICAgICAgKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT5cbiAgICAgICAgdmVyaWZ5U2lnbmF0dXJlKHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduYXR1cmUsIHR4LmNhc3BlclR4Lmhhc2gsIHRlc3REYXRhLkFDQ09VTlRfMS5wdWJsaWNLZXkpXG4gICAgICApO1xuXG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IHR4LnNpZ24oa2V5cGFpcjIpKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmVyLCB0ZXN0RGF0YS5TRUNQMjU2SzFfUFJFRklYICsgdGVzdERhdGEuQUNDT1VOVF8xLnB1YmxpY0tleSk7XG4gICAgICBzaG91bGQuZXF1YWwodHguY2FzcGVyVHguYXBwcm92YWxzWzFdLnNpZ25lciwgdGVzdERhdGEuU0VDUDI1NksxX1BSRUZJWCArIHRlc3REYXRhLkFDQ09VTlRfMi5wdWJsaWNLZXkpO1xuICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICBpc1ZhbGlkVHJhbnNhY3Rpb25TaWduYXR1cmUodHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25hdHVyZSwgdHguY2FzcGVyVHguaGFzaCwgdGVzdERhdGEuQUNDT1VOVF8xLnB1YmxpY0tleSksXG4gICAgICAgIHRydWVcbiAgICAgICk7XG4gICAgICBzaG91bGQuZXF1YWwoXG4gICAgICAgIGlzVmFsaWRUcmFuc2FjdGlvblNpZ25hdHVyZSh0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMV0uc2lnbmF0dXJlLCB0eC5jYXNwZXJUeC5oYXNoLCB0ZXN0RGF0YS5BQ0NPVU5UXzIucHVibGljS2V5KSxcbiAgICAgICAgdHJ1ZVxuICAgICAgKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT5cbiAgICAgICAgdmVyaWZ5U2lnbmF0dXJlKHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduYXR1cmUsIHR4LmNhc3BlclR4Lmhhc2gsIHRlc3REYXRhLkFDQ09VTlRfMS5wdWJsaWNLZXkpXG4gICAgICApO1xuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PlxuICAgICAgICB2ZXJpZnlTaWduYXR1cmUodHguY2FzcGVyVHguYXBwcm92YWxzWzFdLnNpZ25hdHVyZSwgdHguY2FzcGVyVHguaGFzaCwgdGVzdERhdGEuQUNDT1VOVF8yLnB1YmxpY0tleSlcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnbXVsdGlwbGUgdmFsaWQgdXNpbmcgb25lIGV4dGVuZGVkIGtleScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHR4ID0gZ2V0VHJhbnNhY3Rpb24oKTtcbiAgICAgIGNvbnN0IHRyYW5zZmVyRGVwbG95ID0gZ2V0VHJhbnNmZXJEZXBsb3koKTtcbiAgICAgIGlmICh0cmFuc2ZlckRlcGxveSkge1xuICAgICAgICB0eC5jYXNwZXJUeCA9IHRyYW5zZmVyRGVwbG95O1xuICAgICAgfVxuICAgICAgY29uc3Qga2V5cGFpciA9IG5ldyBLZXlQYWlyKHsgcHJ2OiB0ZXN0RGF0YS5BQ0NPVU5UXzEueFByaXZhdGVLZXkgfSk7XG4gICAgICBjb25zdCBrZXlwYWlyMiA9IG5ldyBLZXlQYWlyKHsgcHJ2OiB0ZXN0RGF0YS5BQ0NPVU5UXzIucHJpdmF0ZUtleSB9KTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gdHguc2lnbihrZXlwYWlyKSk7XG4gICAgICBzaG91bGQuZXF1YWwodHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25lciwgdGVzdERhdGEuU0VDUDI1NksxX1BSRUZJWCArIHRlc3REYXRhLkFDQ09VTlRfMS5wdWJsaWNLZXkpO1xuICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICBpc1ZhbGlkVHJhbnNhY3Rpb25TaWduYXR1cmUodHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25hdHVyZSwgdHguY2FzcGVyVHguaGFzaCwgdGVzdERhdGEuQUNDT1VOVF8xLnB1YmxpY0tleSksXG4gICAgICAgIHRydWVcbiAgICAgICk7XG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+XG4gICAgICAgIHZlcmlmeVNpZ25hdHVyZSh0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmF0dXJlLCB0eC5jYXNwZXJUeC5oYXNoLCB0ZXN0RGF0YS5BQ0NPVU5UXzEucHVibGljS2V5KVxuICAgICAgKTtcblxuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB0eC5zaWduKGtleXBhaXIyKSk7XG4gICAgICBzaG91bGQuZXF1YWwodHguY2FzcGVyVHguYXBwcm92YWxzWzBdLnNpZ25lciwgdGVzdERhdGEuU0VDUDI1NksxX1BSRUZJWCArIHRlc3REYXRhLkFDQ09VTlRfMS5wdWJsaWNLZXkpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LmNhc3BlclR4LmFwcHJvdmFsc1sxXS5zaWduZXIsIHRlc3REYXRhLlNFQ1AyNTZLMV9QUkVGSVggKyB0ZXN0RGF0YS5BQ0NPVU5UXzIucHVibGljS2V5KTtcbiAgICAgIHNob3VsZC5lcXVhbChcbiAgICAgICAgaXNWYWxpZFRyYW5zYWN0aW9uU2lnbmF0dXJlKHR4LmNhc3BlclR4LmFwcHJvdmFsc1swXS5zaWduYXR1cmUsIHR4LmNhc3BlclR4Lmhhc2gsIHRlc3REYXRhLkFDQ09VTlRfMS5wdWJsaWNLZXkpLFxuICAgICAgICB0cnVlXG4gICAgICApO1xuICAgICAgc2hvdWxkLmVxdWFsKFxuICAgICAgICBpc1ZhbGlkVHJhbnNhY3Rpb25TaWduYXR1cmUodHguY2FzcGVyVHguYXBwcm92YWxzWzFdLnNpZ25hdHVyZSwgdHguY2FzcGVyVHguaGFzaCwgdGVzdERhdGEuQUNDT1VOVF8yLnB1YmxpY0tleSksXG4gICAgICAgIHRydWVcbiAgICAgICk7XG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+XG4gICAgICAgIHZlcmlmeVNpZ25hdHVyZSh0eC5jYXNwZXJUeC5hcHByb3ZhbHNbMF0uc2lnbmF0dXJlLCB0eC5jYXNwZXJUeC5oYXNoLCB0ZXN0RGF0YS5BQ0NPVU5UXzEucHVibGljS2V5KVxuICAgICAgKTtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT5cbiAgICAgICAgdmVyaWZ5U2lnbmF0dXJlKHR4LmNhc3BlclR4LmFwcHJvdmFsc1sxXS5zaWduYXR1cmUsIHR4LmNhc3BlclR4Lmhhc2gsIHRlc3REYXRhLkFDQ09VTlRfMi5wdWJsaWNLZXkpXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc2hvdWxkIHJlamVjdCBzaWduIGlmIHRyYW5zYWN0aW9uIHNpZ25lciBpcycsICgpID0+IHtcbiAgICBpdCgnaW52YWxpZCBwcml2YXRlIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gZ2V0VHJhbnNhY3Rpb24oKTtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdHguc2lnbih0ZXN0RGF0YS5JTlZBTElEX0tFWVBBSVJfUFJWKSk7XG4gICAgfSk7XG5cbiAgICBpdCgncHVibGljIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gZ2V0VHJhbnNhY3Rpb24oKTtcbiAgICAgIGNvbnN0IGtleXBhaXIgPSBuZXcgS2V5UGFpcih7IHB1YjogdGVzdERhdGEuQUNDT1VOVF8xLnB1YmxpY0tleSB9KTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHR4LnNpZ24oa2V5cGFpciksXG4gICAgICAgIChlOiBFcnJvcikgPT4gZS5tZXNzYWdlID09PSB0ZXN0RGF0YS5FUlJPUl9NSVNTSU5HX1BSSVZBVEVfS0VZXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3B1YmxpYyBleHRlbmRlZCBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IGdldFRyYW5zYWN0aW9uKCk7XG4gICAgICBjb25zdCBrZXlwYWlyID0gbmV3IEtleVBhaXIoeyBwdWI6IHRlc3REYXRhLkFDQ09VTlRfMS54UHVibGljS2V5IH0pO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gdHguc2lnbihrZXlwYWlyKSxcbiAgICAgICAgKGU6IEVycm9yKSA9PiBlLm1lc3NhZ2UgPT09IHRlc3REYXRhLkVSUk9SX01JU1NJTkdfUFJJVkFURV9LRVlcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzaG91bGQgcmV0dXJuIGVuY29kZWQgdHgnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3dhbGxldCBpbml0aWFsaXphdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldEluaXRUeCA9IGF3YWl0IGdldFdhbGxldEluaXRUcmFuc2FjdGlvbigpO1xuICAgICAgY29uc3QgZW5jb2RlZFR4ID0gd2FsbGV0SW5pdFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCB3YWxsZXRJbml0SnNvblR4ID0gSlNPTi5wYXJzZShlbmNvZGVkVHgpO1xuXG4gICAgICBjb25zdCBhcmdOYW1lID0gMDtcbiAgICAgIGNvbnN0IGFyZ1ZhbHVlID0gMTtcbiAgICAgIGNvbnN0IG93bmVyMCA9IDA7XG4gICAgICBjb25zdCBvd25lcjEgPSAxO1xuICAgICAgY29uc3Qgb3duZXIyID0gMjtcblxuICAgICAgY29uc3Qgb3duZXJzVmFsdWVzID0gbmV3IE1hcCgpO1xuXG4gICAgICBbb3duZXIwLCBvd25lcjEsIG93bmVyMl0uZm9yRWFjaCgoaW5kZXgpID0+IHtcbiAgICAgICAgb3duZXJzVmFsdWVzLnNldChcbiAgICAgICAgICBPV05FUl9QUkVGSVggKyBpbmRleCxcbiAgICAgICAgICAod2FsbGV0SW5pdFR4LmNhc3BlclR4LnNlc3Npb24uZ2V0QXJnQnlOYW1lKE9XTkVSX1BSRUZJWCArIGluZGV4KSBhcyBDTFN0cmluZykudmFsdWUoKVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGpzb25Pd25lckFyZ3MgPSB3YWxsZXRJbml0SnNvblR4WydkZXBsb3knXVsnc2Vzc2lvbiddWydNb2R1bGVCeXRlcyddWydhcmdzJ10uZmlsdGVyKChhcmcpID0+XG4gICAgICAgIG93bmVyc1ZhbHVlcy5oYXMoYXJnW2FyZ05hbWVdKVxuICAgICAgKTtcbiAgICAgIGpzb25Pd25lckFyZ3MubGVuZ3RoLnNob3VsZC5lcXVhbChvd25lcnNWYWx1ZXMuc2l6ZSk7XG5cbiAgICAgIGpzb25Pd25lckFyZ3MuZm9yRWFjaCgoYXJnKSA9PiB7XG4gICAgICAgIGFyZ1thcmdWYWx1ZV1bJ3BhcnNlZCddLnNob3VsZC5iZS5lcXVhbChvd25lcnNWYWx1ZXMuZ2V0KGFyZ1thcmdOYW1lXSkpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnd2FsbGV0IGluaXRpYWxpemF0aW9uIHVzaW5nIGV4dGVuZGVkIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldEluaXRUeCA9IGF3YWl0IGdldFdhbGxldEluaXRUcmFuc2FjdGlvblVzaWduRXh0ZW5kZWRLZXkoKTtcbiAgICAgIGNvbnN0IGVuY29kZWRUeCA9IHdhbGxldEluaXRUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuICAgICAgY29uc3Qgd2FsbGV0SW5pdEpzb25UeCA9IEpTT04ucGFyc2UoZW5jb2RlZFR4KTtcblxuICAgICAgY29uc3QgYXJnTmFtZSA9IDA7XG4gICAgICBjb25zdCBhcmdWYWx1ZSA9IDE7XG4gICAgICBjb25zdCBvd25lcjAgPSAwO1xuICAgICAgY29uc3Qgb3duZXIxID0gMTtcbiAgICAgIGNvbnN0IG93bmVyMiA9IDI7XG5cbiAgICAgIGNvbnN0IG93bmVyc1ZhbHVlcyA9IG5ldyBNYXAoKTtcblxuICAgICAgW293bmVyMCwgb3duZXIxLCBvd25lcjJdLmZvckVhY2goKGluZGV4KSA9PiB7XG4gICAgICAgIG93bmVyc1ZhbHVlcy5zZXQoXG4gICAgICAgICAgT1dORVJfUFJFRklYICsgaW5kZXgsXG4gICAgICAgICAgKHdhbGxldEluaXRUeC5jYXNwZXJUeC5zZXNzaW9uLmdldEFyZ0J5TmFtZShPV05FUl9QUkVGSVggKyBpbmRleCkgYXMgQ0xTdHJpbmcpLnZhbHVlKClcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBqc29uT3duZXJBcmdzID0gd2FsbGV0SW5pdEpzb25UeFsnZGVwbG95J11bJ3Nlc3Npb24nXVsnTW9kdWxlQnl0ZXMnXVsnYXJncyddLmZpbHRlcigoYXJnKSA9PlxuICAgICAgICBvd25lcnNWYWx1ZXMuaGFzKGFyZ1thcmdOYW1lXSlcbiAgICAgICk7XG4gICAgICBqc29uT3duZXJBcmdzLmxlbmd0aC5zaG91bGQuZXF1YWwob3duZXJzVmFsdWVzLnNpemUpO1xuXG4gICAgICBqc29uT3duZXJBcmdzLmZvckVhY2goKGFyZykgPT4ge1xuICAgICAgICBhcmdbYXJnVmFsdWVdWydwYXJzZWQnXS5zaG91bGQuYmUuZXF1YWwob3duZXJzVmFsdWVzLmdldChhcmdbYXJnTmFtZV0pKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3RyYW5zZmVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHJhbnNmZXJUeCA9IGF3YWl0IGdldFRyYW5zZmVyVHJhbnNhY3Rpb24oKTtcbiAgICAgIGNvbnN0IGVuY29kZWRUeCA9IHRyYW5zZmVyVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIGNvbnN0IHRyYW5zZmVySnNvblR4ID0gSlNPTi5wYXJzZShlbmNvZGVkVHgpO1xuXG4gICAgICBjb25zdCBhcmdOYW1lID0gMDtcbiAgICAgIGNvbnN0IGFyZ1ZhbHVlID0gMTtcblxuICAgICAgY29uc3QgdHJhbnNmZXJWYWx1ZXMgPSBuZXcgTWFwKCk7XG5cbiAgICAgIHRyYW5zZmVyVmFsdWVzLnNldCgnYW1vdW50JywgZ2V0VHJhbnNmZXJBbW91bnQodHJhbnNmZXJUeC5jYXNwZXJUeC5zZXNzaW9uKSk7XG4gICAgICB0cmFuc2ZlclZhbHVlcy5zZXQoJ3RvX2FkZHJlc3MnLCBnZXRUcmFuc2ZlckRlc3RpbmF0aW9uQWRkcmVzcyh0cmFuc2ZlclR4LmNhc3BlclR4LnNlc3Npb24pKTtcbiAgICAgIGNvbnN0IHRyYW5zZmVySWQgPSBnZXRUcmFuc2ZlcklkKHRyYW5zZmVyVHguY2FzcGVyVHguc2Vzc2lvbik7XG4gICAgICBpZiAodHJhbnNmZXJJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRyYW5zZmVyVmFsdWVzLnNldCgnaWQnLCB0cmFuc2ZlcklkLnRvU3RyaW5nKCkpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBqc29uT3duZXJBcmdzID0gdHJhbnNmZXJKc29uVHhbJ2RlcGxveSddWydzZXNzaW9uJ11bJ1RyYW5zZmVyJ11bJ2FyZ3MnXS5maWx0ZXIoKGFyZykgPT5cbiAgICAgICAgdHJhbnNmZXJWYWx1ZXMuaGFzKGFyZ1thcmdOYW1lXSlcbiAgICAgICk7XG4gICAgICBqc29uT3duZXJBcmdzLmxlbmd0aC5zaG91bGQuZXF1YWwodHJhbnNmZXJWYWx1ZXMuc2l6ZSk7XG5cbiAgICAgIGpzb25Pd25lckFyZ3MuZm9yRWFjaCgoYXJnKSA9PiB7XG4gICAgICAgIGFyZ1thcmdWYWx1ZV1bJ3BhcnNlZCddLnNob3VsZC5iZS5lcXVhbCh0cmFuc2ZlclZhbHVlcy5nZXQoYXJnW2FyZ05hbWVdKSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vIFRPRE8gU1RMWC0xMTc0OiBnZXQgYW5kIGRlY29kZSBlbmNvZGVkIHRyYW5zYWN0aW9uXG4gICAgaXQoJ3ZhbGlkIHNpZ24nLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgZG9uZSgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!