PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-sol/dist/test/unit/transactionBuilder
Просмотр файла: transactionBuilder.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 should_1 = __importDefault(require("should"));
const bs58 = __importStar(require("bs58"));
const getBuilderFactory_1 = require("../getBuilderFactory");
const src_1 = require("../../../src");
const sdk_core_1 = require("@bitgo/sdk-core");
const testData = __importStar(require("../../resources/sol"));
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
describe('Sol Transaction Builder', async () => {
let builders;
const factory = (0, getBuilderFactory_1.getBuilderFactory)('tsol');
const authAccount = new src_1.KeyPair(testData.authAccount).getKeys();
const nonceAccount = new src_1.KeyPair(testData.nonceAccount).getKeys();
const validBlockhash = 'GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi';
beforeEach(function (done) {
builders = [
factory.getWalletInitializationBuilder(),
factory.getTransferBuilder(),
factory.getStakingActivateBuilder(),
factory.getStakingWithdrawBuilder(),
];
done();
});
it('start and build an empty a transfer tx with fee', async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.sender(authAccount.pub);
txBuilder.nonce(validBlockhash);
txBuilder.fee({ amount: 5000 });
const tx = await txBuilder.build();
should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
const txJson = tx.toJson();
txJson.lamportsPerSignature?.should.equal(5000);
});
it('should fail to build if missing sender', async () => {
for (const txBuilder of builders) {
txBuilder.nonce(validBlockhash);
await txBuilder.build().should.rejectedWith('Invalid transaction: missing sender');
}
});
it('should fail to build if missing nonce', async () => {
for (const txBuilder of builders) {
txBuilder.sender(authAccount.pub);
await txBuilder.build().should.rejectedWith('Invalid transaction: missing nonce blockhash');
}
});
it('build a wallet init from rawTx', async () => {
const txBuilder = factory.from(testData.WALLET_INIT_SIGNED_TX);
const builtTx = await txBuilder.build();
should_1.default.equal(builtTx.type, sdk_core_1.TransactionType.WalletInitialization);
should_1.default.equal(builtTx.id, '7TkU8wLgXDeLFbVydtg6mqMsp9GatsetitSngysgjxFhofKSUcLPBoKPHciLeGEfJFMsqezpZmGRSFQTBy7ZDsg');
builtTx.inputs.length.should.equal(1);
builtTx.inputs[0].should.deepEqual({
address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
value: testData.tokenTransfers.amount.toString(),
coin: 'tsol',
});
builtTx.outputs.length.should.equal(0);
const jsonTx = builtTx.toJson();
jsonTx.id.should.equal('7TkU8wLgXDeLFbVydtg6mqMsp9GatsetitSngysgjxFhofKSUcLPBoKPHciLeGEfJFMsqezpZmGRSFQTBy7ZDsg');
jsonTx.feePayer.should.equal('5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe');
jsonTx.nonce.should.equal('GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi');
jsonTx.numSignatures.should.equal(2);
jsonTx.instructionsData.should.deepEqual([
{
type: 'CreateNonceAccount',
params: {
fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
nonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
authAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
amount: '300000',
},
},
]);
builtTx.toBroadcastFormat().should.equal(testData.WALLET_INIT_SIGNED_TX);
});
it('build a staking activate from rawTx', async () => {
const txBuilder = factory.from(testData.STAKING_ACTIVATE_SIGNED_TX);
const builtTx = await txBuilder.build();
should_1.default.equal(builtTx.type, sdk_core_1.TransactionType.StakingActivate);
should_1.default.equal(builtTx.id, 'DCsSiGuKiWgtFRF2ZCh5x6xukApffYDs5Y9CyvYBEebMVnXH5TydKpT76srTSr1AhvDZqsnS5EVhvkS8Rzh91hH');
builtTx.inputs.length.should.equal(1);
builtTx.inputs[0].should.deepEqual({
address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
value: testData.tokenTransfers.amount.toString(),
coin: 'tsol',
});
builtTx.outputs.length.should.equal(1);
const jsonTx = builtTx.toJson();
jsonTx.id.should.equal('DCsSiGuKiWgtFRF2ZCh5x6xukApffYDs5Y9CyvYBEebMVnXH5TydKpT76srTSr1AhvDZqsnS5EVhvkS8Rzh91hH');
jsonTx.feePayer.should.equal('5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe');
jsonTx.nonce.should.equal('GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi');
jsonTx.numSignatures.should.equal(2);
jsonTx.instructionsData.should.deepEqual([
{
type: 'Activate',
params: {
fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
stakingAddress: '7dRuGFbU2y2kijP6o1LYNzVyz4yf13MooqoionCzv5Za',
amount: '300000',
validator: 'CyjoLt3kjqB57K7ewCBHmnHq3UgEj3ak6A7m6EsBsuhA',
isMarinade: false,
},
},
]);
builtTx.toBroadcastFormat().should.equal(testData.STAKING_ACTIVATE_SIGNED_TX);
});
it('build a send from rawTx', async () => {
const txBuilder = factory.from(testData.TRANSFER_SIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE);
const builtTx = await txBuilder.build();
should_1.default.equal(builtTx.type, sdk_core_1.TransactionType.Send);
should_1.default.equal(builtTx.id, '2XFxGfXddKWnqGaMAsfNL8HgXqDvjBL2Ae28KWrRvg9bQBmCrpHYVDacuZFeAUyYwjXG6ey2jTARX5VQCnj7SF4L');
builtTx.inputs.length.should.equal(1);
builtTx.inputs[0].should.deepEqual({
address: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
value: testData.tokenTransfers.amount.toString(),
coin: 'tsol',
});
builtTx.outputs.length.should.equal(1);
builtTx.outputs[0].should.deepEqual({
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
value: testData.tokenTransfers.amount.toString(),
coin: 'tsol',
});
const jsonTx = builtTx.toJson();
jsonTx.id.should.equal('2XFxGfXddKWnqGaMAsfNL8HgXqDvjBL2Ae28KWrRvg9bQBmCrpHYVDacuZFeAUyYwjXG6ey2jTARX5VQCnj7SF4L');
jsonTx.feePayer.should.equal('5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe');
jsonTx.nonce.should.equal('GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi');
jsonTx.numSignatures.should.equal(1);
jsonTx.durableNonce.should.deepEqual({
walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
authWalletAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
});
jsonTx.instructionsData.should.deepEqual([
{
type: 'Transfer',
params: {
fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
toAddress: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
amount: '300000',
},
},
{
type: 'Memo',
params: { memo: 'test memo' },
},
]);
builtTx.toBroadcastFormat().should.equal(testData.TRANSFER_SIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE);
});
it('build a send from raw token transaction', async () => {
const txBuilder = factory.from(testData.TOKEN_TRANSFER_SIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE);
const prioFeeMicroLamports = '10000000';
// We don't have to manually set the priority fee here as the raw txn already has the priority fee instruction;
// therefore once initBuilder is called (it's called within fromImplementation), it will set the txBuilder's priorityFee field
// which will then be used in txBuilder.build() by tokenTransferBuilder to add the set compute fee instruction
const builtTx = await txBuilder.build();
should_1.default.equal(builtTx.type, sdk_core_1.TransactionType.Send);
should_1.default.equal(builtTx.id, '2ticU4ZkEqdTHULr6LobTgWBhim6E7wSscDhM4gzyuGUmQyUwLYhoqaifuvwmNzzEf1T5aefVcgMQkSHdJ5nsrfZ');
builtTx.inputs.length.should.equal(1);
builtTx.inputs[0].should.deepEqual({
address: testData.associatedTokenAccounts.accounts[0].pub,
value: testData.tokenTransfers.amount.toString(),
coin: 'tsol:usdc',
});
builtTx.outputs.length.should.equal(1);
builtTx.outputs[0].should.deepEqual({
address: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
value: testData.tokenTransfers.amount.toString(),
coin: 'tsol:usdc',
});
const jsonTx = builtTx.toJson();
jsonTx.id.should.equal('2ticU4ZkEqdTHULr6LobTgWBhim6E7wSscDhM4gzyuGUmQyUwLYhoqaifuvwmNzzEf1T5aefVcgMQkSHdJ5nsrfZ');
jsonTx.feePayer.should.equal(testData.associatedTokenAccounts.accounts[0].pub);
jsonTx.nonce.should.equal('GHtXQBsoZHVnNFa9YevAzFr17DJjgHXk3ycTKD5xD3Zi');
jsonTx.numSignatures.should.equal(1);
jsonTx.durableNonce.should.deepEqual({
walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
authWalletAddress: testData.associatedTokenAccounts.accounts[0].pub,
});
const priorityFeeBigInt = BigInt(prioFeeMicroLamports);
jsonTx.instructionsData.should.deepEqual([
{
params: {
fee: priorityFeeBigInt,
},
type: 'SetPriorityFee',
},
{
type: 'TokenTransfer',
params: {
fromAddress: testData.associatedTokenAccounts.accounts[0].pub,
toAddress: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
amount: testData.tokenTransfers.amount.toString(),
tokenName: testData.tokenTransfers.nameUSDC.toString(),
sourceAddress: 'B5rJjuVi7En63iK6o3ijKdJwAoTe2gwCYmJsVdHQ2aKV',
},
},
{
type: 'Memo',
params: { memo: 'test memo' },
},
]);
builtTx.toBroadcastFormat().should.equal(testData.TOKEN_TRANSFER_SIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE);
});
describe('Nonce tests', async () => {
it('should throw for invalid nonce', () => {
const blockHash = 'randomstring';
for (const txBuilder of builders) {
(0, should_1.default)(() => txBuilder.nonce(blockHash)).throw('Invalid or missing blockHash, got: ' + blockHash);
}
});
it('should throw for invalid params using durable nonce', () => {
const invalidPubKey = 'randomstring';
for (const txBuilder of builders) {
(0, should_1.default)(() => txBuilder.nonce(validBlockhash, {
walletNonceAddress: invalidPubKey,
authWalletAddress: authAccount.pub,
})).throw('Invalid or missing walletNonceAddress, got: ' + invalidPubKey);
(0, should_1.default)(() => txBuilder.nonce(validBlockhash, {
walletNonceAddress: nonceAccount.pub,
authWalletAddress: invalidPubKey,
})).throw('Invalid or missing authWalletAddress, got: ' + invalidPubKey);
(0, should_1.default)(() => txBuilder.nonce(validBlockhash, {
walletNonceAddress: nonceAccount.pub,
authWalletAddress: nonceAccount.pub,
})).throw('Invalid params: walletNonceAddress cannot be equal to authWalletAddress');
}
});
it('should succeed for valid nonce', () => {
for (const txBuilder of builders) {
should_1.default.doesNotThrow(() => txBuilder.nonce(validBlockhash));
}
});
it('should succeed for valid durable nonce', () => {
for (const txBuilder of builders) {
should_1.default.doesNotThrow(() => txBuilder.nonce(validBlockhash, { walletNonceAddress: nonceAccount.pub, authWalletAddress: authAccount.pub }));
}
});
});
describe('sender tests', async () => {
it('should throw for invalid sender', () => {
const invalidPublicKey = 'randomstring';
for (const txBuilder of builders) {
(0, should_1.default)(() => txBuilder.sender(invalidPublicKey)).throw('Invalid or missing sender, got: ' + invalidPublicKey);
}
});
it('should succeed for valid sender', () => {
for (const txBuilder of builders) {
should_1.default.doesNotThrow(() => txBuilder.sender(authAccount.pub));
}
});
});
it('validateAddress', () => {
const validAddress = { address: authAccount.pub };
const invalidAddress = { address: testData.pubKeys.invalidPubKeys[0] };
for (const builder of builders) {
should_1.default.doesNotThrow(() => builder.validateAddress(validAddress));
(0, should_1.default)(() => builder.validateAddress(invalidAddress)).throwError('Invalid address ' + testData.pubKeys.invalidPubKeys[0]);
}
});
it('validateKey', () => {
const validKey = { key: testData.authAccount.prv };
const invalidKey = { key: testData.authAccount.pub };
for (const builder of builders) {
should_1.default.doesNotThrow(() => builder.validateKey(validKey));
(0, should_1.default)(() => builder.validateKey(invalidKey)).throwError('Invalid key');
}
});
it('validateRawTransaction', () => {
const validRawTx = testData.RAW_TX_SIGNED;
const invalidRawTx = 'AAAAAAAAAAAAAAAAAAA';
for (const builder of builders) {
should_1.default.doesNotThrow(() => builder.validateRawTransaction(validRawTx));
(0, should_1.default)(() => builder.validateRawTransaction(invalidRawTx)).throwError('Invalid raw transaction');
}
});
it('validateValue', () => {
const validValue = new bignumber_js_1.default('100000');
const invalidValue = new bignumber_js_1.default('-100000');
for (const builder of builders) {
should_1.default.doesNotThrow(() => builder.validateValue(validValue));
(0, should_1.default)(() => builder.validateValue(invalidValue)).throwError('Value cannot be less than zero');
}
});
it('validateMemo', () => {
const validMemo = 'test memo';
const invalidMemo = 'ooawindaonmawñdamwdoianwdonalskdnaiouwbdoinowadn90awndoawndaowdnaioiuwbdioauwndaoudnbawodnba9owudbnaowdnaasdijhaksdkjasdkjhaskdjhkasdasdasdasdasd';
for (const builder of builders) {
builder._instructionsData.push({
type: 'Transfer',
params: {
fromAddress: '5hr5fisPi6DXNuuRpm5XUbzpiEnmdyxXuBDTwzwZj5Pe',
toAddress: 'CP5Dpaa42RtJmMuKqCQsLwma5Yh3knuvKsYDFX85F41S',
amount: '300000',
},
});
builder.validateMemo(validMemo);
(0, should_1.default)(() => builder.validateMemo(invalidMemo)).throwError('Memo is too long');
(0, should_1.default)((memo) => builder.validateMemo(memo)).throwError('Invalid memo, got: undefined');
}
});
describe('add signature', () => {
let MPC;
it('should add signature to transaction', async () => {
const transferBuilder = factory
.getTransferBuilder()
.sender(authAccount.pub)
.nonce(validBlockhash)
.fee({ amount: 5000 })
.send({ address: nonceAccount.pub, amount: '1000' });
transferBuilder.sign({ key: authAccount.prv });
const signedTransaction = await transferBuilder.build();
// signature is base58 encoded
const signature = signedTransaction.signature[0];
// verify rebuilt transaction contains signature
const rawTransaction = signedTransaction.toBroadcastFormat();
const rebuiltSignedTransaction = await factory.from(rawTransaction).build();
rebuiltSignedTransaction.signature.should.deepEqual(signedTransaction.signature);
const transferBuilder2 = factory
.getTransferBuilder()
.sender(authAccount.pub)
.nonce(validBlockhash)
.fee({ amount: 5000 })
.send({ address: nonceAccount.pub, amount: '1000' });
transferBuilder2.addSignature({ pub: authAccount.pub }, Buffer.from(bs58.decode(signature)));
const signedTransaction2 = await transferBuilder2.build();
// verify signatures are correct
signedTransaction.signature.should.deepEqual(signedTransaction2.signature);
// verify rebuilt transaction contains signature
const rawTransaction2 = signedTransaction2.toBroadcastFormat();
const rebuiltTransaction2 = await factory.from(rawTransaction2).build();
rebuiltTransaction2.signature.should.deepEqual(signedTransaction2.signature);
});
before('initialize mpc module', async () => {
const hdTree = await sdk_lib_mpc_1.Ed25519Bip32HdTree.initialize();
MPC = await sdk_core_1.Eddsa.initialize(hdTree);
});
it('should add TSS signature', async () => {
const A = MPC.keyShare(1, 2, 3);
const B = MPC.keyShare(2, 2, 3);
const C = MPC.keyShare(3, 2, 3);
const A_combine = MPC.keyCombine(A.uShare, [B.yShares[1], C.yShares[1]]);
const B_combine = MPC.keyCombine(B.uShare, [A.yShares[2], C.yShares[2]]);
const C_combine = MPC.keyCombine(C.uShare, [A.yShares[3], B.yShares[3]]);
const commonPub = A_combine.pShare.y;
const solPublicKey = new src_1.KeyPair({ pub: commonPub });
const sender = solPublicKey.getAddress();
let transferBuilder = factory
.getTransferBuilder()
.sender(sender)
.nonce(validBlockhash)
.fee({ amount: 5000 })
.send({ address: nonceAccount.pub, amount: '1000' });
const unsignedTransaction = await transferBuilder.build();
const signablePayload = unsignedTransaction.signablePayload;
// signing with A and B
let A_sign_share = MPC.signShare(signablePayload, A_combine.pShare, [A_combine.jShares[2]]);
let B_sign_share = MPC.signShare(signablePayload, B_combine.pShare, [B_combine.jShares[1]]);
let A_sign = MPC.sign(signablePayload, A_sign_share.xShare, [B_sign_share.rShares[1]], [C.yShares[1]]);
let B_sign = MPC.sign(signablePayload, B_sign_share.xShare, [A_sign_share.rShares[2]], [C.yShares[2]]);
let signature = MPC.signCombine([A_sign, B_sign]);
let rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
transferBuilder = factory
.getTransferBuilder()
.sender(sender)
.nonce(validBlockhash)
.fee({ amount: 5000 })
.send({ address: nonceAccount.pub, amount: '1000' });
transferBuilder.addSignature({ pub: sender }, rawSignature);
let signedTransaction = await transferBuilder.build();
signedTransaction.signature.length.should.equal(1);
signedTransaction.signature[0].should.equal(bs58.encode(rawSignature));
signedTransaction.id.should.equal(bs58.encode(rawSignature));
// signing with A and C
A_sign_share = MPC.signShare(signablePayload, A_combine.pShare, [A_combine.jShares[3]]);
let C_sign_share = MPC.signShare(signablePayload, C_combine.pShare, [C_combine.jShares[1]]);
A_sign = MPC.sign(signablePayload, A_sign_share.xShare, [C_sign_share.rShares[1]], [B.yShares[1]]);
let C_sign = MPC.sign(signablePayload, C_sign_share.xShare, [A_sign_share.rShares[3]], [B.yShares[3]]);
signature = MPC.signCombine([A_sign, C_sign]);
rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
transferBuilder = factory
.getTransferBuilder()
.sender(sender)
.nonce(validBlockhash)
.fee({ amount: 5000 })
.send({ address: nonceAccount.pub, amount: '1000' });
transferBuilder.addSignature({ pub: sender }, rawSignature);
signedTransaction = await transferBuilder.build();
signedTransaction.signature.length.should.equal(1);
signedTransaction.signature[0].should.equal(bs58.encode(rawSignature));
signedTransaction.id.should.equal(bs58.encode(rawSignature));
// signing with B and C
B_sign_share = MPC.signShare(signablePayload, B_combine.pShare, [B_combine.jShares[3]]);
C_sign_share = MPC.signShare(signablePayload, C_combine.pShare, [C_combine.jShares[2]]);
B_sign = MPC.sign(signablePayload, B_sign_share.xShare, [C_sign_share.rShares[2]], [A.yShares[2]]);
C_sign = MPC.sign(signablePayload, C_sign_share.xShare, [B_sign_share.rShares[3]], [A.yShares[3]]);
signature = MPC.signCombine([B_sign, C_sign]);
rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
transferBuilder = factory
.getTransferBuilder()
.sender(sender)
.nonce(validBlockhash)
.fee({ amount: 5000 })
.send({ address: nonceAccount.pub, amount: '1000' });
transferBuilder.addSignature({ pub: sender }, rawSignature);
signedTransaction = await transferBuilder.build();
signedTransaction.signature.length.should.equal(1);
signedTransaction.signature[0].should.equal(bs58.encode(rawSignature));
signedTransaction.id.should.equal(bs58.encode(rawSignature));
const rawTransaction = signedTransaction.toBroadcastFormat();
const rebuiltTransaction = await factory.from(rawTransaction).build();
rebuiltTransaction.id.should.equal(signedTransaction.id);
rebuiltTransaction.signature.should.deepEqual(signedTransaction.signature);
});
it('should add TSS HD signature', async () => {
const A = MPC.keyShare(1, 2, 3);
const B = MPC.keyShare(2, 2, 3);
const C = MPC.keyShare(3, 2, 3);
const A_combine = MPC.keyCombine(A.uShare, [B.yShares[1], C.yShares[1]]);
const B_combine = MPC.keyCombine(B.uShare, [A.yShares[2], C.yShares[2]]);
for (let index = 0; index < 10; index++) {
const path = `m/${index}`;
const A_subkey = MPC.keyDerive(A.uShare, [B.yShares[1], C.yShares[1]], path);
const B_subkey = MPC.keyCombine(B.uShare, [A_subkey.yShares[2], C.yShares[2]]);
const solPublicKey = new src_1.KeyPair({ pub: A_subkey.pShare.y });
const sender = solPublicKey.getAddress();
const transferBuilder = factory
.getTransferBuilder()
.sender(sender)
.nonce(validBlockhash)
.fee({ amount: 5000 })
.send({ address: nonceAccount.pub, amount: '1000' });
const unsignedTransaction = await transferBuilder.build();
const signablePayload = unsignedTransaction.signablePayload;
const A_sign_share = MPC.signShare(signablePayload, A_subkey.pShare, [A_combine.jShares[2]]);
const B_sign_share = MPC.signShare(signablePayload, B_subkey.pShare, [B_combine.jShares[1]]);
const A_sign = MPC.sign(signablePayload, A_sign_share.xShare, [B_sign_share.rShares[1]], [C.yShares[1]]);
const B_sign = MPC.sign(signablePayload, B_sign_share.xShare, [A_sign_share.rShares[2]], [C.yShares[2]]);
const signature = MPC.signCombine([A_sign, B_sign]);
const rawSignature = Buffer.concat([Buffer.from(signature.R, 'hex'), Buffer.from(signature.sigma, 'hex')]);
transferBuilder.addSignature({ pub: sender }, rawSignature);
const signedTransaction = await transferBuilder.build();
signedTransaction.signature.length.should.equal(1);
signedTransaction.signature[0].should.equal(bs58.encode(rawSignature));
signedTransaction.id.should.equal(bs58.encode(rawSignature));
const rawTransaction = signedTransaction.toBroadcastFormat();
const rebuiltTransaction = await factory.from(rawTransaction).build();
rebuiltTransaction.id.should.equal(signedTransaction.id);
rebuiltTransaction.signature.should.deepEqual(signedTransaction.signature);
}
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb25CdWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3RyYW5zYWN0aW9uQnVpbGRlci90cmFuc2FjdGlvbkJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsMkNBQTZCO0FBRTdCLDREQUF5RDtBQUN6RCxzQ0FBNkQ7QUFDN0QsOENBQXlEO0FBQ3pELDhEQUFnRDtBQUNoRCxnRUFBcUM7QUFDckMsb0RBQXdEO0FBRXhELFFBQVEsQ0FBQyx5QkFBeUIsRUFBRSxLQUFLLElBQUksRUFBRTtJQUM3QyxJQUFJLFFBQVEsQ0FBQztJQUNiLE1BQU0sT0FBTyxHQUFHLElBQUEscUNBQWlCLEVBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxhQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2hFLE1BQU0sWUFBWSxHQUFHLElBQUksYUFBTyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNsRSxNQUFNLGNBQWMsR0FBRyw4Q0FBOEMsQ0FBQztJQUV0RSxVQUFVLENBQUMsVUFBVSxJQUFJO1FBQ3ZCLFFBQVEsR0FBRztZQUNULE9BQU8sQ0FBQyw4QkFBOEIsRUFBRTtZQUN4QyxPQUFPLENBQUMsa0JBQWtCLEVBQUU7WUFDNUIsT0FBTyxDQUFDLHlCQUF5QixFQUFFO1lBQ25DLE9BQU8sQ0FBQyx5QkFBeUIsRUFBRTtTQUNwQyxDQUFDO1FBQ0YsSUFBSSxFQUFFLENBQUM7SUFDVCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxpREFBaUQsRUFBRSxLQUFLLElBQUksRUFBRTtRQUMvRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMv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U0FBUyxDQUFDLENBQUM7WUFDN0UsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBzaG91bGQgZnJvbSAnc2hvdWxkJztcbmltcG9ydCAqIGFzIGJzNTggZnJvbSAnYnM1OCc7XG5cbmltcG9ydCB7IGdldEJ1aWxkZXJGYWN0b3J5IH0gZnJvbSAnLi4vZ2V0QnVpbGRlckZhY3RvcnknO1xuaW1wb3J0IHsgS2V5UGFpciwgVG9rZW5UcmFuc2ZlckJ1aWxkZXIgfSBmcm9tICcuLi8uLi8uLi9zcmMnO1xuaW1wb3J0IHsgRWRkc2EsIFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgKiBhcyB0ZXN0RGF0YSBmcm9tICcuLi8uLi9yZXNvdXJjZXMvc29sJztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCB7IEVkMjU1MTlCaXAzMkhkVHJlZSB9IGZyb20gJ0BiaXRnby9zZGstbGliLW1wYyc7XG5cbmRlc2NyaWJlKCdTb2wgVHJhbnNhY3Rpb24gQnVpbGRlcicsIGFzeW5jICgpID0+IHtcbiAgbGV0IGJ1aWxkZXJzO1xuICBjb25zdCBmYWN0b3J5ID0gZ2V0QnVpbGRlckZhY3RvcnkoJ3Rzb2wnKTtcbiAgY29uc3QgYXV0aEFjY291bnQgPSBuZXcgS2V5UGFpcih0ZXN0RGF0YS5hdXRoQWNjb3VudCkuZ2V0S2V5cygpO1xuICBjb25zdCBub25jZUFjY291bnQgPSBuZXcgS2V5UGFpcih0ZXN0RGF0YS5ub25jZUFjY291bnQpLmdldEtleXMoKTtcbiAgY29uc3QgdmFsaWRCbG9ja2hhc2ggPSAnR0h0WFFCc29aSFZuTkZhOVlldkF6RnIxN0RKamdIWGszeWNUS0Q1eEQzWmknO1xuXG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKGRvbmUpIHtcbiAgICBidWlsZGVycyA9IFtcbiAgICAgIGZhY3RvcnkuZ2V0V2FsbGV0SW5pdGlhbGl6YXRpb25CdWlsZGVyKCksXG4gICAgICBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpLFxuICAgICAgZmFjdG9yeS5nZXRTdGFraW5nQWN0aXZhdGVCdWlsZGVyKCksXG4gICAgICBmYWN0b3J5LmdldFN0YWtpbmdXaXRoZHJhd0J1aWxkZXIoKSxcbiAgICBdO1xuICAgIGRvbmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3N0YXJ0IGFuZCBidWlsZCBhbiBlbXB0eSBhIHRyYW5zZmVyIHR4IHdpdGggZmVlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgdHhCdWlsZGVyLnNlbmRlcihhdXRoQWNjb3VudC5wdWIpO1xuICAgIHR4QnVpbGRlci5ub25jZSh2YWxpZEJsb2NraGFzaCk7XG4gICAgdHhCdWlsZGVyLmZlZSh7IGFtb3VudDogNTAwMCB9KTtcbiAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIHNob3VsZC5lcXVhbCh0eC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG5cbiAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICB0eEpzb24ubGFtcG9ydHNQZXJTaWduYXR1cmU/LnNob3VsZC5lcXVhbCg1MDAwKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBmYWlsIHRvIGJ1aWxkIGlmIG1pc3Npbmcgc2VuZGVyJywgYXN5bmMgKCkgPT4ge1xuICAgIGZvciAoY29uc3QgdHhCdWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICB0eEJ1aWxkZXIubm9uY2UodmFsaWRCbG9ja2hhc2gpO1xuICAgICAgYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCkuc2hvdWxkLnJlamVjdGVkV2l0aCgnSW52YWxpZCB0cmFuc2FjdGlvbjogbWlzc2luZyBzZW5kZXInKTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgZmFpbCB0byBidWlsZCBpZiBtaXNzaW5nIG5vbmNlJywgYXN5bmMgKCkgPT4ge1xuICAgIGZvciAoY29uc3QgdHhCdWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICB0eEJ1aWxkZXIuc2VuZGVyKGF1dGhBY2NvdW50LnB1Yik7XG4gICAgICBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKS5zaG91bGQucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHRyYW5zYWN0aW9uOiBtaXNzaW5nIG5vbmNlIGJsb2NraGFzaCcpO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ2J1aWxkIGEgd2FsbGV0IGluaXQgZnJvbSByYXdUeCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odGVzdERhdGEuV0FMTEVUX0lOSVRfU0lHTkVEX1RYKTtcbiAgICBjb25zdCBidWlsdFR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgc2hvdWxkLmVxdWFsKGJ1aWx0VHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLldhbGxldEluaXRpYWxpemF0aW9uKTtcbiAgICBzaG91bGQuZXF1YWwoYnVpbHRUeC5pZCwgJzdUa1U4d0xnWERlTEZiVnlkdGc2bXFNc3A5R2F0c2V0aXRTbmd5c2dqeEZob2ZLU1VjTFBCb0tQSGNpTGVHRWZKRk1zcWV6cFptR1JTRlFUQnk3WkRzZycpO1xuICAgIGJ1aWx0VHguaW5wdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgYnVpbHRUeC5pbnB1dHNbMF0uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICBhZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgdmFsdWU6IHRlc3REYXRhLnRva2VuVHJhbnNmZXJzLmFtb3VudC50b1N0cmluZygpLFxuICAgICAgY29pbjogJ3Rzb2wnLFxuICAgIH0pO1xuICAgIGJ1aWx0VHgub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIGNvbnN0IGpzb25UeCA9IGJ1aWx0VHgudG9Kc29uKCk7XG4gICAganNvblR4LmlkLnNob3VsZC5lcXVhbCgnN1RrVTh3TGdYRGVMRmJWeWR0ZzZtcU1zcDlHYXRzZXRpdFNuZ3lzZ2p4RmhvZktTVWNMUEJvS1BIY2lMZUdFZkpGTXNxZXpwWm1HUlNGUVRCeTdaRHNnJyk7XG4gICAganNvblR4LmZlZVBheWVyLnNob3VsZC5lcXVhbCgnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnKTtcbiAgICBqc29uVHgubm9uY2Uuc2hvdWxkLmVxdWFsKCdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScpO1xuICAgIGpzb25UeC5udW1TaWduYXR1cmVzLnNob3VsZC5lcXVhbCgyKTtcbiAgICBqc29uVHguaW5zdHJ1Y3Rpb25zRGF0YS5zaG91bGQuZGVlcEVxdWFsKFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ0NyZWF0ZU5vbmNlQWNjb3VudCcsXG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgIGZyb21BZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgICAgIG5vbmNlQWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgICAgICBhdXRoQWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICBhbW91bnQ6ICczMDAwMDAnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdKTtcbiAgICBidWlsdFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkuc2hvdWxkLmVxdWFsKHRlc3REYXRhLldBTExFVF9JTklUX1NJR05FRF9UWCk7XG4gIH0pO1xuXG4gIGl0KCdidWlsZCBhIHN0YWtpbmcgYWN0aXZhdGUgZnJvbSByYXdUeCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20odGVzdERhdGEuU1RBS0lOR19BQ1RJVkFURV9TSUdORURfVFgpO1xuICAgIGNvbnN0IGJ1aWx0VHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBzaG91bGQuZXF1YWwoYnVpbHRUeC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ0FjdGl2YXRlKTtcbiAgICBzaG91bGQuZXF1YWwoYnVpbHRUeC5pZCwgJ0RDc1NpR3VLaVdndEZSRjJaQ2g1eDZ4dWtBcGZmWURzNVk5Q3l2WUJFZWJNVm5YSDVUeWRLcFQ3NnNyVFNyMUFodkRacXNuUzVFVmh2a1M4UnpoOTFoSCcpO1xuICAgIGJ1aWx0VHguaW5wdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgYnVpbHRUeC5pbnB1dHNbMF0uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICBhZGRyZXNzOiAnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnLFxuICAgICAgdmFsdWU6IHRlc3REYXRhLnRva2VuVHJhbnNmZXJzLmFtb3VudC50b1N0cmluZygpLFxuICAgICAgY29pbjogJ3Rzb2wnLFxuICAgIH0pO1xuICAgIGJ1aWx0VHgub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgIGNvbnN0IGpzb25UeCA9IGJ1aWx0VHgudG9Kc29uKCk7XG4gICAganNvblR4LmlkLnNob3VsZC5lcXVhbCgnRENzU2lHdUtpV2d0RlJGMlpDaDV4Nnh1a0FwZmZZRHM1WTlDeXZZQkVlYk1WblhINVR5ZEtwVDc2c3JUU3IxQWh2RFpxc25TNUVWaHZrUzhSemg5MWhIJyk7XG4gICAganNvblR4LmZlZVBheWVyLnNob3VsZC5lcXVhbCgnNWhyNWZpc1BpNkRYTnV1UnBtNVhVYnpwaUVubWR5eFh1QkRUd3p3Wmo1UGUnKTtcbiAgICBqc29uVHgubm9uY2Uuc2hvdWxkLmVxdWFsKCdHSHRYUUJzb1pIVm5ORmE5WWV2QXpGcjE3REpqZ0hYazN5Y1RLRDV4RDNaaScpO1xuICAgIGpzb25UeC5udW1TaWduYXR1cmVzLnNob3VsZC5lcXVhbCgyKTtcbiAgICBqc29uVHguaW5zdHJ1Y3Rpb25zRGF0YS5zaG91bGQuZGVlcEVxdWFsKFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ0FjdGl2YXRlJyxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgZnJvbUFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgc3Rha2luZ0FkZHJlc3M6ICc3ZFJ1R0ZiVTJ5MmtpalA2bzFMWU56Vnl6NHlmMTNNb29xb2lvbkN6djVaYScsXG4gICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgICB2YWxpZGF0b3I6ICdDeWpvTHQza2pxQjU3Szdld0NCSG1uSHEzVWdFajNhazZBN202RXNCc3VoQScsXG4gICAgICAgICAgaXNNYXJpbmFkZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIF0pO1xuICAgIGJ1aWx0VHgudG9Ccm9hZGNhc3RGb3JtYXQoKS5zaG91bGQuZXF1YWwodGVzdERhdGEuU1RBS0lOR19BQ1RJVkFURV9TSUdORURfVFgpO1xuICB9KTtcblxuICBpdCgnYnVpbGQgYSBzZW5kIGZyb20gcmF3VHgnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHRlc3REYXRhLlRSQU5TRkVSX1NJR05FRF9UWF9XSVRIX01FTU9fQU5EX0RVUkFCTEVfTk9OQ0UpO1xuICAgIGNvbnN0IGJ1aWx0VHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBzaG91bGQuZXF1YWwoYnVpbHRUeC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgc2hvdWxkLmVxdWFsKFxuICAgICAgYnVpbHRUeC5pZCxcbiAgICAgICcyWEZ4R2ZYZGRLV25xR2FNQXNmTkw4SGdYcUR2akJMMkFlMjhLV3JSdmc5YlFCbUNycEhZVkRhY3VaRmVBVXlZd2pYRzZleTJqVEFSWDVWUUNuajdTRjRMJ1xuICAgICk7XG4gICAgYnVpbHRUeC5pbnB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICBidWlsdFR4LmlucHV0c1swXS5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgIGFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICB2YWx1ZTogdGVzdERhdGEudG9rZW5UcmFuc2ZlcnMuYW1vdW50LnRvU3RyaW5nKCksXG4gICAgICBjb2luOiAndHNvbCcsXG4gICAgfSk7XG4gICAgYnVpbHRUeC5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgYnVpbHRUeC5vdXRwdXRzWzBdLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgYWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgIHZhbHVlOiB0ZXN0RGF0YS50b2tlblRyYW5zZmVycy5hbW91bnQudG9TdHJpbmcoKSxcbiAgICAgIGNvaW46ICd0c29sJyxcbiAgICB9KTtcbiAgICBjb25zdCBqc29uVHggPSBidWlsdFR4LnRvSnNvbigpO1xuICAgIGpzb25UeC5pZC5zaG91bGQuZXF1YWwoJzJYRnhHZlhkZEtXbnFHYU1Bc2ZOTDhIZ1hxRHZqQkwyQWUyOEtXclJ2ZzliUUJtQ3JwSFlWRGFjdVpGZUFVeVl3alhHNmV5MmpUQVJYNVZRQ25qN1NGNEwnKTtcbiAgICBqc29uVHguZmVlUGF5ZXIuc2hvdWxkLmVxdWFsKCc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScpO1xuICAgIGpzb25UeC5ub25jZS5zaG91bGQuZXF1YWwoJ0dIdFhRQnNvWkhWbk5GYTlZZXZBekZyMTdESmpnSFhrM3ljVEtENXhEM1ppJyk7XG4gICAganNvblR4Lm51bVNpZ25hdHVyZXMuc2hvdWxkLmVxdWFsKDEpO1xuICAgIGpzb25UeC5kdXJhYmxlTm9uY2Uuc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICB3YWxsZXROb25jZUFkZHJlc3M6ICc4WTdSTTZKZmNYNEFTU05Ca3Jrcm1TYlJ1NDMxWVZpOVkzb0xGbnpDMmRDaCcsXG4gICAgICBhdXRoV2FsbGV0QWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICB9KTtcbiAgICBqc29uVHguaW5zdHJ1Y3Rpb25zRGF0YS5zaG91bGQuZGVlcEVxdWFsKFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ1RyYW5zZmVyJyxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgZnJvbUFkZHJlc3M6ICc1aHI1ZmlzUGk2RFhOdXVScG01WFVienBpRW5tZHl4WHVCRFR3endaajVQZScsXG4gICAgICAgICAgdG9BZGRyZXNzOiAnQ1A1RHBhYTQyUnRKbU11S3FDUXNMd21hNVloM2tudXZLc1lERlg4NUY0MVMnLFxuICAgICAgICAgIGFtb3VudDogJzMwMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0eXBlOiAnTWVtbycsXG4gICAgICAgIHBhcmFtczogeyBtZW1vOiAndGVzdCBtZW1vJyB9LFxuICAgICAgfSxcbiAgICBdKTtcbiAgICBidWlsdFR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkuc2hvdWxkLmVxdWFsKHRlc3REYXRhLlRSQU5TRkVSX1NJR05FRF9UWF9XSVRIX01FTU9fQU5EX0RVUkFCTEVfTk9OQ0UpO1xuICB9KTtcblxuICBpdCgnYnVpbGQgYSBzZW5kIGZyb20gcmF3IHRva2VuIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZnJvbShcbiAgICAgIHRlc3REYXRhLlRPS0VOX1RSQU5TRkVSX1NJR05FRF9UWF9XSVRIX01FTU9fQU5EX0RVUkFCTEVfTk9OQ0VcbiAgICApIGFzIFRva2VuVHJhbnNmZXJCdWlsZGVyO1xuICAgIGNvbnN0IHByaW9GZWVNaWNyb0xhbXBvcnRzID0gJzEwMDAwMDAwJztcbiAgICAvLyBXZSBkb24ndCBoYXZlIHRvIG1hbnVhbGx5IHNldCB0aGUgcHJpb3JpdHkgZmVlIGhlcmUgYXMgdGhlIHJhdyB0eG4gYWxyZWFkeSBoYXMgdGhlIHByaW9yaXR5IGZlZSBpbnN0cnVjdGlvbjtcbiAgICAvLyB0aGVyZWZvcmUgb25jZSBpbml0QnVpbGRlciBpcyBjYWxsZWQgKGl0J3MgY2FsbGVkIHdpdGhpbiBmcm9tSW1wbGVtZW50YXRpb24pLCBpdCB3aWxsIHNldCB0aGUgdHhCdWlsZGVyJ3MgcHJpb3JpdHlGZWUgZmllbGRcbiAgICAvLyB3aGljaCB3aWxsIHRoZW4gYmUgdXNlZCBpbiB0eEJ1aWxkZXIuYnVpbGQoKSBieSB0b2tlblRyYW5zZmVyQnVpbGRlciB0byBhZGQgdGhlIHNldCBjb21wdXRlIGZlZSBpbnN0cnVjdGlvblxuICAgIGNvbnN0IGJ1aWx0VHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICBzaG91bGQuZXF1YWwoYnVpbHRUeC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgc2hvdWxkLmVxdWFsKFxuICAgICAgYnVpbHRUeC5pZCxcbiAgICAgICcydGljVTRaa0VxZFRIVUxyNkxvYlRnV0JoaW02RTd3U3NjRGhNNGd6eXVHVW1ReVV3TFlob3FhaWZ1dndtTnp6RWYxVDVhZWZWY2dNUWtTSGRKNW5zcmZaJ1xuICAgICk7XG4gICAgYnVpbHRUeC5pbnB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICBidWlsdFR4LmlucHV0c1swXS5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgIGFkZHJlc3M6IHRlc3REYXRhLmFzc29jaWF0ZWRUb2tlbkFjY291bnRzLmFjY291bnRzWzBdLnB1YixcbiAgICAgIHZhbHVlOiB0ZXN0RGF0YS50b2tlblRyYW5zZmVycy5hbW91bnQudG9TdHJpbmcoKSxcbiAgICAgIGNvaW46ICd0c29sOnVzZGMnLFxuICAgIH0pO1xuICAgIGJ1aWx0VHgub3V0cHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgIGJ1aWx0VHgub3V0cHV0c1swXS5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgIGFkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICB2YWx1ZTogdGVzdERhdGEudG9rZW5UcmFuc2ZlcnMuYW1vdW50LnRvU3RyaW5nKCksXG4gICAgICBjb2luOiAndHNvbDp1c2RjJyxcbiAgICB9KTtcbiAgICBjb25zdCBqc29uVHggPSBidWlsdFR4LnRvSnNvbigpO1xuICAgIGpzb25UeC5pZC5zaG91bGQuZXF1YWwoJzJ0aWNVNFprRXFkVEhVTHI2TG9iVGdXQmhpbTZFN3dTc2NEaE00Z3p5dUdVbVF5VXdMWWhvcWFpZnV2d21OenpFZjFUNWFlZlZjZ01Ra1NIZEo1bnNyZlonKTtcbiAgICBqc29uVHguZmVlUGF5ZXIuc2hvdWxkLmVxdWFsKHRlc3REYXRhLmFzc29jaWF0ZWRUb2tlbkFjY291bnRzLmFjY291bnRzWzBdLnB1Yik7XG4gICAganNvblR4Lm5vbmNlLnNob3VsZC5lcXVhbCgnR0h0WFFCc29aSFZuTkZhOVlldkF6RnIxN0RKamdIWGszeWNUS0Q1eEQzWmknKTtcbiAgICBqc29uVHgubnVtU2lnbmF0dXJlcy5zaG91bGQuZXF1YWwoMSk7XG4gICAganNvblR4LmR1cmFibGVOb25jZS5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgIHdhbGxldE5vbmNlQWRkcmVzczogJzhZN1JNNkpmY1g0QVNTTkJrcmtybVNiUnU0MzFZVmk5WTNvTEZuekMyZENoJyxcbiAgICAgIGF1dGhXYWxsZXRBZGRyZXNzOiB0ZXN0RGF0YS5hc3NvY2lhdGVkVG9rZW5BY2NvdW50cy5hY2NvdW50c1swXS5wdWIsXG4gICAgfSk7XG4gICAgY29uc3QgcHJpb3JpdHlGZWVCaWdJbnQgPSBCaWdJbnQocHJpb0ZlZU1pY3JvTGFtcG9ydHMpO1xuICAgIGpzb25UeC5pbnN0cnVjdGlvbnNEYXRhLnNob3VsZC5kZWVwRXF1YWwoW1xuICAgICAge1xuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBmZWU6IHByaW9yaXR5RmVlQmlnSW50LFxuICAgICAgICB9LFxuICAgICAgICB0eXBlOiAnU2V0UHJpb3JpdHlGZWUnLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ1Rva2VuVHJhbnNmZXInLFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBmcm9tQWRkcmVzczogdGVzdERhdGEuYXNzb2NpYXRlZFRva2VuQWNjb3VudHMuYWNjb3VudHNbMF0ucHViLFxuICAgICAgICAgIHRvQWRkcmVzczogJ0NQNURwYWE0MlJ0Sm1NdUtxQ1FzTHdtYTVZaDNrbnV2S3NZREZYODVGNDFTJyxcbiAgICAgICAgICBhbW91bnQ6IHRlc3REYXRhLnRva2VuVHJhbnNmZXJzLmFtb3VudC50b1N0cmluZygpLFxuICAgICAgICAgIHRva2VuTmFtZTogdGVzdERhdGEudG9rZW5UcmFuc2ZlcnMubmFtZVVTREMudG9TdHJpbmcoKSxcbiAgICAgICAgICBzb3VyY2VBZGRyZXNzOiAnQjVySmp1Vmk3RW42M2lLNm8zaWpLZEp3QW9UZTJnd0NZbUpzVmRIUTJhS1YnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ01lbW8nLFxuICAgICAgICBwYXJhbXM6IHsgbWVtbzogJ3Rlc3QgbWVtbycgfSxcbiAgICAgIH0sXG4gICAgXSk7XG4gICAgYnVpbHRUeC50b0Jyb2FkY2FzdEZvcm1hdCgpLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5UT0tFTl9UUkFOU0ZFUl9TSUdORURfVFhfV0lUSF9NRU1PX0FORF9EVVJBQkxFX05PTkNFKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ05vbmNlIHRlc3RzJywgYXN5bmMgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgdGhyb3cgZm9yIGludmFsaWQgbm9uY2UnLCAoKSA9PiB7XG4gICAgICBjb25zdCBibG9ja0hhc2ggPSAncmFuZG9tc3RyaW5nJztcbiAgICAgIGZvciAoY29uc3QgdHhCdWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICAgIHNob3VsZCgoKSA9PiB0eEJ1aWxkZXIubm9uY2UoYmxvY2tIYXNoKSkudGhyb3coJ0ludmFsaWQgb3IgbWlzc2luZyBibG9ja0hhc2gsIGdvdDogJyArIGJsb2NrSGFzaCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGZvciBpbnZhbGlkIHBhcmFtcyB1c2luZyBkdXJhYmxlIG5vbmNlJywgKCkgPT4ge1xuICAgICAgY29uc3QgaW52YWxpZFB1YktleSA9ICdyYW5kb21zdHJpbmcnO1xuICAgICAgZm9yIChjb25zdCB0eEJ1aWxkZXIgb2YgYnVpbGRlcnMpIHtcbiAgICAgICAgc2hvdWxkKCgpID0+XG4gICAgICAgICAgdHhCdWlsZGVyLm5vbmNlKHZhbGlkQmxvY2toYXNoLCB7XG4gICAgICAgICAgICB3YWxsZXROb25jZUFkZHJlc3M6IGludmFsaWRQdWJLZXksXG4gICAgICAgICAgICBhdXRoV2FsbGV0QWRkcmVzczogYXV0aEFjY291bnQucHViLFxuICAgICAgICAgIH0pXG4gICAgICAgICkudGhyb3coJ0ludmFsaWQgb3IgbWlzc2luZyB3YWxsZXROb25jZUFkZHJlc3MsIGdvdDogJyArIGludmFsaWRQdWJLZXkpO1xuXG4gICAgICAgIHNob3VsZCgoKSA9PlxuICAgICAgICAgIHR4QnVpbGRlci5ub25jZSh2YWxpZEJsb2NraGFzaCwge1xuICAgICAgICAgICAgd2FsbGV0Tm9uY2VBZGRyZXNzOiBub25jZUFjY291bnQucHViLFxuICAgICAgICAgICAgYXV0aFdhbGxldEFkZHJlc3M6IGludmFsaWRQdWJLZXksXG4gICAgICAgICAgfSlcbiAgICAgICAgKS50aHJvdygnSW52YWxpZCBvciBtaXNzaW5nIGF1dGhXYWxsZXRBZGRyZXNzLCBnb3Q6ICcgKyBpbnZhbGlkUHViS2V5KTtcblxuICAgICAgICBzaG91bGQoKCkgPT5cbiAgICAgICAgICB0eEJ1aWxkZXIubm9uY2UodmFsaWRCbG9ja2hhc2gsIHtcbiAgICAgICAgICAgIHdhbGxldE5vbmNlQWRkcmVzczogbm9uY2VBY2NvdW50LnB1YixcbiAgICAgICAgICAgIGF1dGhXYWxsZXRBZGRyZXNzOiBub25jZUFjY291bnQucHViLFxuICAgICAgICAgIH0pXG4gICAgICAgICkudGhyb3coJ0ludmFsaWQgcGFyYW1zOiB3YWxsZXROb25jZUFkZHJlc3MgY2Fubm90IGJlIGVxdWFsIHRvIGF1dGhXYWxsZXRBZGRyZXNzJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgZm9yIHZhbGlkIG5vbmNlJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCB0eEJ1aWxkZXIgb2YgYnVpbGRlcnMpIHtcbiAgICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB0eEJ1aWxkZXIubm9uY2UodmFsaWRCbG9ja2hhc2gpKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VjY2VlZCBmb3IgdmFsaWQgZHVyYWJsZSBub25jZScsICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgdHhCdWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT5cbiAgICAgICAgICB0eEJ1aWxkZXIubm9uY2UodmFsaWRCbG9ja2hhc2gsIHsgd2FsbGV0Tm9uY2VBZGRyZXNzOiBub25jZUFjY291bnQucHViLCBhdXRoV2FsbGV0QWRkcmVzczogYXV0aEFjY291bnQucHViIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdzZW5kZXIgdGVzdHMnLCBhc3luYyAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgaW52YWxpZCBzZW5kZXInLCAoKSA9PiB7XG4gICAgICBjb25zdCBpbnZhbGlkUHVibGljS2V5ID0gJ3JhbmRvbXN0cmluZyc7XG4gICAgICBmb3IgKGNvbnN0IHR4QnVpbGRlciBvZiBidWlsZGVycykge1xuICAgICAgICBzaG91bGQoKCkgPT4gdHhCdWlsZGVyLnNlbmRlcihpbnZhbGlkUHVibGljS2V5KSkudGhyb3coJ0ludmFsaWQgb3IgbWlzc2luZyBzZW5kZXIsIGdvdDogJyArIGludmFsaWRQdWJsaWNLZXkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgc3VjY2VlZCBmb3IgdmFsaWQgc2VuZGVyJywgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCB0eEJ1aWxkZXIgb2YgYnVpbGRlcnMpIHtcbiAgICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiB0eEJ1aWxkZXIuc2VuZGVyKGF1dGhBY2NvdW50LnB1YikpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBpdCgndmFsaWRhdGVBZGRyZXNzJywgKCkgPT4ge1xuICAgIGNvbnN0IHZhbGlkQWRkcmVzcyA9IHsgYWRkcmVzczogYXV0aEFjY291bnQucHViIH07XG4gICAgY29uc3QgaW52YWxpZEFkZHJlc3MgPSB7IGFkZHJlc3M6IHRlc3REYXRhLnB1YktleXMuaW52YWxpZFB1YktleXNbMF0gfTtcbiAgICBmb3IgKGNvbnN0IGJ1aWxkZXIgb2YgYnVpbGRlcnMpIHtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gYnVpbGRlci52YWxpZGF0ZUFkZHJlc3ModmFsaWRBZGRyZXNzKSk7XG4gICAgICBzaG91bGQoKCkgPT4gYnVpbGRlci52YWxpZGF0ZUFkZHJlc3MoaW52YWxpZEFkZHJlc3MpKS50aHJvd0Vycm9yKFxuICAgICAgICAnSW52YWxpZCBhZGRyZXNzICcgKyB0ZXN0RGF0YS5wdWJLZXlzLmludmFsaWRQdWJLZXlzWzBdXG4gICAgICApO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3ZhbGlkYXRlS2V5JywgKCkgPT4ge1xuICAgIGNvbnN0IHZhbGlkS2V5ID0geyBrZXk6IHRlc3REYXRhLmF1dGhBY2NvdW50LnBydiB9O1xuICAgIGNvbnN0IGludmFsaWRLZXkgPSB7IGtleTogdGVzdERhdGEuYXV0aEFjY291bnQucHViIH07XG4gICAgZm9yIChjb25zdCBidWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICBzaG91bGQuZG9lc05vdFRocm93KCgpID0+IGJ1aWxkZXIudmFsaWRhdGVLZXkodmFsaWRLZXkpKTtcbiAgICAgIHNob3VsZCgoKSA9PiBidWlsZGVyLnZhbGlkYXRlS2V5KGludmFsaWRLZXkpKS50aHJvd0Vycm9yKCdJbnZhbGlkIGtleScpO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3ZhbGlkYXRlUmF3VHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gICAgY29uc3QgdmFsaWRSYXdUeCA9IHRlc3REYXRhLlJBV19UWF9TSUdORUQ7XG4gICAgY29uc3QgaW52YWxpZFJhd1R4ID0gJ0FBQUFBQUFBQUFBQUFBQUFBQUEnO1xuICAgIGZvciAoY29uc3QgYnVpbGRlciBvZiBidWlsZGVycykge1xuICAgICAgc2hvdWxkLmRvZXNOb3RUaHJvdygoKSA9PiBidWlsZGVyLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24odmFsaWRSYXdUeCkpO1xuICAgICAgc2hvdWxkKCgpID0+IGJ1aWxkZXIudmFsaWRhdGVSYXdUcmFuc2FjdGlvbihpbnZhbGlkUmF3VHgpKS50aHJvd0Vycm9yKCdJbnZhbGlkIHJhdyB0cmFuc2FjdGlvbicpO1xuICAgIH1cbiAgfSk7XG5cbiAgaXQoJ3ZhbGlkYXRlVmFsdWUnLCAoKSA9PiB7XG4gICAgY29uc3QgdmFsaWRWYWx1ZSA9IG5ldyBCaWdOdW1iZXIoJzEwMDAwMCcpO1xuICAgIGNvbnN0IGludmFsaWRWYWx1ZSA9IG5ldyBCaWdOdW1iZXIoJy0xMDAwMDAnKTtcbiAgICBmb3IgKGNvbnN0IGJ1aWxkZXIgb2YgYnVpbGRlcnMpIHtcbiAgICAgIHNob3VsZC5kb2VzTm90VGhyb3coKCkgPT4gYnVpbGRlci52YWxpZGF0ZVZhbHVlKHZhbGlkVmFsdWUpKTtcbiAgICAgIHNob3VsZCgoKSA9PiBidWlsZGVyLnZhbGlkYXRlVmFsdWUoaW52YWxpZFZhbHVlKSkudGhyb3dFcnJvcignVmFsdWUgY2Fubm90IGJlIGxlc3MgdGhhbiB6ZXJvJyk7XG4gICAgfVxuICB9KTtcblxuICBpdCgndmFsaWRhdGVNZW1vJywgKCkgPT4ge1xuICAgIGNvbnN0IHZhbGlkTWVtbyA9ICd0ZXN0IG1lbW8nO1xuICAgIGNvbnN0IGludmFsaWRNZW1vID1cbiAgICAgICdvb2F3aW5kYW9ubWF3w7FkYW13ZG9pYW53ZG9uYWxza2RuYWlvdXdiZG9pbm93YWRuOTBhd25kb2F3bmRhb3dkbmFpb2l1d2JkaW9hdXduZGFvdWRuYmF3b2RuYmE5b3d1ZGJuYW93ZG5hYXNkaWpoYWtzZGtqYXNka2poYXNrZGpoa2FzZGFzZGFzZGFzZGFzZCc7XG4gICAgZm9yIChjb25zdCBidWlsZGVyIG9mIGJ1aWxkZXJzKSB7XG4gICAgICBidWlsZGVyLl9pbnN0cnVjdGlvbnNEYXRhLnB1c2goe1xuICAgICAgICB0eXBlOiAnVHJhbnNmZXInLFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBmcm9tQWRkcmVzczogJzVocjVmaXNQaTZEWE51dVJwbTVYVWJ6cGlFbm1keXhYdUJEVHd6d1pqNVBlJyxcbiAgICAgICAgICB0b0FkZHJlc3M6ICdDUDVEcGFhNDJSdEptTXVLcUNRc0x3bWE1WWgza251dktzWURGWDg1RjQxUycsXG4gICAgICAgICAgYW1vdW50OiAnMzAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgYnVpbGRlci52YWxpZGF0ZU1lbW8odmFsaWRNZW1vKTtcbiAgICAgIHNob3VsZCgoKSA9PiBidWlsZGVyLnZhbGlkYXRlTWVtbyhpbnZhbGlkTWVtbykpLnRocm93RXJyb3IoJ01lbW8gaXMgdG9vIGxvbmcnKTtcbiAgICAgIHNob3VsZCgobWVtbzogc3RyaW5nKSA9PiBidWlsZGVyLnZhbGlkYXRlTWVtbyhtZW1vKSkudGhyb3dFcnJvcignSW52YWxpZCBtZW1vLCBnb3Q6IHVuZGVmaW5lZCcpO1xuICAgIH1cbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2FkZCBzaWduYXR1cmUnLCAoKSA9PiB7XG4gICAgbGV0IE1QQzogRWRkc2E7XG5cbiAgICBpdCgnc2hvdWxkIGFkZCBzaWduYXR1cmUgdG8gdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIgPSBmYWN0b3J5XG4gICAgICAgIC5nZXRUcmFuc2ZlckJ1aWxkZXIoKVxuICAgICAgICAuc2VuZGVyKGF1dGhBY2NvdW50LnB1YilcbiAgICAgICAgLm5vbmNlKHZhbGlkQmxvY2toYXNoKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5zZW5kKHsgYWRkcmVzczogbm9uY2VBY2NvdW50LnB1YiwgYW1vdW50OiAnMTAwMCcgfSk7XG4gICAgICB0cmFuc2ZlckJ1aWxkZXIuc2lnbih7IGtleTogYXV0aEFjY291bnQucHJ2IH0pO1xuXG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHRyYW5zZmVyQnVpbGRlci5idWlsZCgpO1xuICAgICAgLy8gc2lnbmF0dXJlIGlzIGJhc2U1OCBlbmNvZGVkXG4gICAgICBjb25zdCBzaWduYXR1cmUgPSBzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmVbMF07XG5cbiAgICAgIC8vIHZlcmlmeSByZWJ1aWx0IHRyYW5zYWN0aW9uIGNvbnRhaW5zIHNpZ25hdHVyZVxuICAgICAgY29uc3QgcmF3VHJhbnNhY3Rpb24gPSBzaWduZWRUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IHJlYnVpbHRTaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGZhY3RvcnkuZnJvbShyYXdUcmFuc2FjdGlvbikuYnVpbGQoKTtcbiAgICAgIHJlYnVpbHRTaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmUuc2hvdWxkLmRlZXBFcXVhbChzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmUpO1xuXG4gICAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIyID0gZmFjdG9yeVxuICAgICAgICAuZ2V0VHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgLnNlbmRlcihhdXRoQWNjb3VudC5wdWIpXG4gICAgICAgIC5ub25jZSh2YWxpZEJsb2NraGFzaClcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuc2VuZCh7IGFkZHJlc3M6IG5vbmNlQWNjb3VudC5wdWIsIGFtb3VudDogJzEwMDAnIH0pO1xuICAgICAgdHJhbnNmZXJCdWlsZGVyMi5hZGRTaWduYXR1cmUoeyBwdWI6IGF1dGhBY2NvdW50LnB1YiB9LCBCdWZmZXIuZnJvbShiczU4LmRlY29kZShzaWduYXR1cmUpKSk7XG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbjIgPSBhd2FpdCB0cmFuc2ZlckJ1aWxkZXIyLmJ1aWxkKCk7XG5cbiAgICAgIC8vIHZlcmlmeSBzaWduYXR1cmVzIGFyZSBjb3JyZWN0XG4gICAgICBzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmUuc2hvdWxkLmRlZXBFcXVhbChzaWduZWRUcmFuc2FjdGlvbjIuc2lnbmF0dXJlKTtcblxuICAgICAgLy8gdmVyaWZ5IHJlYnVpbHQgdHJhbnNhY3Rpb24gY29udGFpbnMgc2lnbmF0dXJlXG4gICAgICBjb25zdCByYXdUcmFuc2FjdGlvbjIgPSBzaWduZWRUcmFuc2FjdGlvbjIudG9Ccm9hZGNhc3RGb3JtYXQoKSBhcyBzdHJpbmc7XG4gICAgICBjb25zdCByZWJ1aWx0VHJhbnNhY3Rpb24yID0gYXdhaXQgZmFjdG9yeS5mcm9tKHJhd1RyYW5zYWN0aW9uMikuYnVpbGQoKTtcbiAgICAgIHJlYnVpbHRUcmFuc2FjdGlvbjIuc2lnbmF0dXJlLnNob3VsZC5kZWVwRXF1YWwoc2lnbmVkVHJhbnNhY3Rpb24yLnNpZ25hdHVyZSk7XG4gICAgfSk7XG5cbiAgICBiZWZvcmUoJ2luaXRpYWxpemUgbXBjIG1vZHVsZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGhkVHJlZSA9IGF3YWl0IEVkMjU1MTlCaXAzMkhkVHJlZS5pbml0aWFsaXplKCk7XG4gICAgICBNUEMgPSBhd2FpdCBFZGRzYS5pbml0aWFsaXplKGhkVHJlZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFkZCBUU1Mgc2lnbmF0dXJlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgQSA9IE1QQy5rZXlTaGFyZSgxLCAyLCAzKTtcbiAgICAgIGNvbnN0IEIgPSBNUEMua2V5U2hhcmUoMiwgMiwgMyk7XG4gICAgICBjb25zdCBDID0gTVBDLmtleVNoYXJlKDMsIDIsIDMpO1xuXG4gICAgICBjb25zdCBBX2NvbWJpbmUgPSBNUEMua2V5Q29tYmluZShBLnVTaGFyZSwgW0IueVNoYXJlc1sxXSwgQy55U2hhcmVzWzFdXSk7XG4gICAgICBjb25zdCBCX2NvbWJpbmUgPSBNUEMua2V5Q29tYmluZShCLnVTaGFyZSwgW0EueVNoYXJlc1syXSwgQy55U2hhcmVzWzJdXSk7XG4gICAgICBjb25zdCBDX2NvbWJpbmUgPSBNUEMua2V5Q29tYmluZShDLnVTaGFyZSwgW0EueVNoYXJlc1szXSwgQi55U2hhcmVzWzNdXSk7XG5cbiAgICAgIGNvbnN0IGNvbW1vblB1YiA9IEFfY29tYmluZS5wU2hhcmUueTtcbiAgICAgIGNvbnN0IHNvbFB1YmxpY0tleSA9IG5ldyBLZXlQYWlyKHsgcHViOiBjb21tb25QdWIgfSk7XG4gICAgICBjb25zdCBzZW5kZXIgPSBzb2xQdWJsaWNLZXkuZ2V0QWRkcmVzcygpO1xuXG4gICAgICBsZXQgdHJhbnNmZXJCdWlsZGVyID0gZmFjdG9yeVxuICAgICAgICAuZ2V0VHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgLnNlbmRlcihzZW5kZXIpXG4gICAgICAgIC5ub25jZSh2YWxpZEJsb2NraGFzaClcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuc2VuZCh7IGFkZHJlc3M6IG5vbmNlQWNjb3VudC5wdWIsIGFtb3VudDogJzEwMDAnIH0pO1xuICAgICAgY29uc3QgdW5zaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IHRyYW5zZmVyQnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3Qgc2lnbmFibGVQYXlsb2FkID0gdW5zaWduZWRUcmFuc2FjdGlvbi5zaWduYWJsZVBheWxvYWQ7XG5cbiAgICAgIC8vIHNpZ25pbmcgd2l0aCBBIGFuZCBCXG4gICAgICBsZXQgQV9zaWduX3NoYXJlID0gTVBDLnNpZ25TaGFyZShzaWduYWJsZVBheWxvYWQsIEFfY29tYmluZS5wU2hhcmUsIFtBX2NvbWJpbmUualNoYXJlc1syXV0pO1xuICAgICAgbGV0IEJfc2lnbl9zaGFyZSA9IE1QQy5zaWduU2hhcmUoc2lnbmFibGVQYXlsb2FkLCBCX2NvbWJpbmUucFNoYXJlLCBbQl9jb21iaW5lLmpTaGFyZXNbMV1dKTtcbiAgICAgIGxldCBBX3NpZ24gPSBNUEMuc2lnbihzaWduYWJsZVBheWxvYWQsIEFfc2lnbl9zaGFyZS54U2hhcmUsIFtCX3NpZ25fc2hhcmUuclNoYXJlc1sxXV0sIFtDLnlTaGFyZXNbMV1dKTtcbiAgICAgIGxldCBCX3NpZ24gPSBNUEMuc2lnbihzaWduYWJsZVBheWxvYWQsIEJfc2lnbl9zaGFyZS54U2hhcmUsIFtBX3NpZ25fc2hhcmUuclNoYXJlc1syXV0sIFtDLnlTaGFyZXNbMl1dKTtcbiAgICAgIGxldCBzaWduYXR1cmUgPSBNUEMuc2lnbkNvbWJpbmUoW0Ffc2lnbiwgQl9zaWduXSk7XG4gICAgICBsZXQgcmF3U2lnbmF0dXJlID0gQnVmZmVyLmNvbmNhdChbQnVmZmVyLmZyb20oc2lnbmF0dXJlLlIsICdoZXgnKSwgQnVmZmVyLmZyb20oc2lnbmF0dXJlLnNpZ21hLCAnaGV4JyldKTtcblxuICAgICAgdHJhbnNmZXJCdWlsZGVyID0gZmFjdG9yeVxuICAgICAgICAuZ2V0VHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgLnNlbmRlcihzZW5kZXIpXG4gICAgICAgIC5ub25jZSh2YWxpZEJsb2NraGFzaClcbiAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAuc2VuZCh7IGFkZHJlc3M6IG5vbmNlQWNjb3VudC5wdWIsIGFtb3VudDogJzEwMDAnIH0pO1xuICAgICAgdHJhbnNmZXJCdWlsZGVyLmFkZFNpZ25hdHVyZSh7IHB1Yjogc2VuZGVyIH0sIHJhd1NpZ25hdHVyZSk7XG4gICAgICBsZXQgc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCB0cmFuc2ZlckJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hdHVyZS5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgc2lnbmVkVHJhbnNhY3Rpb24uc2lnbmF0dXJlWzBdLnNob3VsZC5lcXVhbChiczU4LmVuY29kZShyYXdTaWduYXR1cmUpKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLmlkLnNob3VsZC5lcXVhbChiczU4LmVuY29kZShyYXdTaWduYXR1cmUpKTtcblxuICAgICAgLy8gc2lnbmluZyB3aXRoIEEgYW5kIENcbiAgICAgIEFfc2lnbl9zaGFyZSA9IE1QQy5zaWduU2hhcmUoc2lnbmFibGVQYXlsb2FkLCBBX2NvbWJpbmUucFNoYXJlLCBbQV9jb21iaW5lLmpTaGFyZXNbM11dKTtcbiAgICAgIGxldCBDX3NpZ25fc2hhcmUgPSBNUEMuc2lnblNoYXJlKHNpZ25hYmxlUGF5bG9hZCwgQ19jb21iaW5lLnBTaGFyZSwgW0NfY29tYmluZS5qU2hhcmVzWzFdXSk7XG4gICAgICBBX3NpZ24gPSBNUEMuc2lnbihzaWduYWJsZVBheWxvYWQsIEFfc2lnbl9zaGFyZS54U2hhcmUsIFtDX3NpZ25fc2hhcmUuclNoYXJlc1sxXV0sIFtCLnlTaGFyZXNbMV1dKTtcbiAgICAgIGxldCBDX3NpZ24gPSBNUEMuc2lnbihzaWduYWJsZVBheWxvYWQsIENfc2lnbl9zaGFyZS54U2hhcmUsIFtBX3NpZ25fc2hhcmUuclNoYXJlc1szXV0sIFtCLnlTaGFyZXNbM11dKTtcbiAgICAgIHNpZ25hdHVyZSA9IE1QQy5zaWduQ29tYmluZShbQV9zaWduLCBDX3NpZ25dKTtcbiAgICAgIHJhd1NpZ25hdHVyZSA9IEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKHNpZ25hdHVyZS5SLCAnaGV4JyksIEJ1ZmZlci5mcm9tKHNpZ25hdHVyZS5zaWdtYSwgJ2hleCcpXSk7XG5cbiAgICAgIHRyYW5zZmVyQnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgLmdldFRyYW5zZmVyQnVpbGRlcigpXG4gICAgICAgIC5zZW5kZXIoc2VuZGVyKVxuICAgICAgICAubm9uY2UodmFsaWRCbG9ja2hhc2gpXG4gICAgICAgIC5mZWUoeyBhbW91bnQ6IDUwMDAgfSlcbiAgICAgICAgLnNlbmQoeyBhZGRyZXNzOiBub25jZUFjY291bnQucHViLCBhbW91bnQ6ICcxMDAwJyB9KTtcbiAgICAgIHRyYW5zZmVyQnVpbGRlci5hZGRTaWduYXR1cmUoeyBwdWI6IHNlbmRlciB9LCByYXdTaWduYXR1cmUpO1xuICAgICAgc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCB0cmFuc2ZlckJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hdHVyZS5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgc2lnbmVkVHJhbnNhY3Rpb24uc2lnbmF0dXJlWzBdLnNob3VsZC5lcXVhbChiczU4LmVuY29kZShyYXdTaWduYXR1cmUpKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLmlkLnNob3VsZC5lcXVhbChiczU4LmVuY29kZShyYXdTaWduYXR1cmUpKTtcblxuICAgICAgLy8gc2lnbmluZyB3aXRoIEIgYW5kIENcbiAgICAgIEJfc2lnbl9zaGFyZSA9IE1QQy5zaWduU2hhcmUoc2lnbmFibGVQYXlsb2FkLCBCX2NvbWJpbmUucFNoYXJlLCBbQl9jb21iaW5lLmpTaGFyZXNbM11dKTtcbiAgICAgIENfc2lnbl9zaGFyZSA9IE1QQy5zaWduU2hhcmUoc2lnbmFibGVQYXlsb2FkLCBDX2NvbWJpbmUucFNoYXJlLCBbQ19jb21iaW5lLmpTaGFyZXNbMl1dKTtcbiAgICAgIEJfc2lnbiA9IE1QQy5zaWduKHNpZ25hYmxlUGF5bG9hZCwgQl9zaWduX3NoYXJlLnhTaGFyZSwgW0Nfc2lnbl9zaGFyZS5yU2hhcmVzWzJdXSwgW0EueVNoYXJlc1syXV0pO1xuICAgICAgQ19zaWduID0gTVBDLnNpZ24oc2lnbmFibGVQYXlsb2FkLCBDX3NpZ25fc2hhcmUueFNoYXJlLCBbQl9zaWduX3NoYXJlLnJTaGFyZXNbM11dLCBbQS55U2hhcmVzWzNdXSk7XG4gICAgICBzaWduYXR1cmUgPSBNUEMuc2lnbkNvbWJpbmUoW0Jfc2lnbiwgQ19zaWduXSk7XG4gICAgICByYXdTaWduYXR1cmUgPSBCdWZmZXIuY29uY2F0KFtCdWZmZXIuZnJvbShzaWduYXR1cmUuUiwgJ2hleCcpLCBCdWZmZXIuZnJvbShzaWduYXR1cmUuc2lnbWEsICdoZXgnKV0pO1xuXG4gICAgICB0cmFuc2ZlckJ1aWxkZXIgPSBmYWN0b3J5XG4gICAgICAgIC5nZXRUcmFuc2ZlckJ1aWxkZXIoKVxuICAgICAgICAuc2VuZGVyKHNlbmRlcilcbiAgICAgICAgLm5vbmNlKHZhbGlkQmxvY2toYXNoKVxuICAgICAgICAuZmVlKHsgYW1vdW50OiA1MDAwIH0pXG4gICAgICAgIC5zZW5kKHsgYWRkcmVzczogbm9uY2VBY2NvdW50LnB1YiwgYW1vdW50OiAnMTAwMCcgfSk7XG4gICAgICB0cmFuc2ZlckJ1aWxkZXIuYWRkU2lnbmF0dXJlKHsgcHViOiBzZW5kZXIgfSwgcmF3U2lnbmF0dXJlKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgdHJhbnNmZXJCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmUubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hdHVyZVswXS5zaG91bGQuZXF1YWwoYnM1OC5lbmNvZGUocmF3U2lnbmF0dXJlKSk7XG4gICAgICBzaWduZWRUcmFuc2FjdGlvbi5pZC5zaG91bGQuZXF1YWwoYnM1OC5lbmNvZGUocmF3U2lnbmF0dXJlKSk7XG5cbiAgICAgIGNvbnN0IHJhd1RyYW5zYWN0aW9uID0gc2lnbmVkVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKSBhcyBzdHJpbmc7XG4gICAgICBjb25zdCByZWJ1aWx0VHJhbnNhY3Rpb24gPSBhd2FpdCBmYWN0b3J5LmZyb20ocmF3VHJhbnNhY3Rpb24pLmJ1aWxkKCk7XG4gICAgICByZWJ1aWx0VHJhbnNhY3Rpb24uaWQuc2hvdWxkLmVxdWFsKHNpZ25lZFRyYW5zYWN0aW9uLmlkKTtcbiAgICAgIHJlYnVpbHRUcmFuc2FjdGlvbi5zaWduYXR1cmUuc2hvdWxkLmRlZXBFcXVhbChzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhZGQgVFNTIEhEIHNpZ25hdHVyZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IEEgPSBNUEMua2V5U2hhcmUoMSwgMiwgMyk7XG4gICAgICBjb25zdCBCID0gTVBDLmtleVNoYXJlKDIsIDIsIDMpO1xuICAgICAgY29uc3QgQyA9IE1QQy5rZXlTaGFyZSgzLCAyLCAzKTtcblxuICAgICAgY29uc3QgQV9jb21iaW5lID0gTVBDLmtleUNvbWJpbmUoQS51U2hhcmUsIFtCLnlTaGFyZXNbMV0sIEMueVNoYXJlc1sxXV0pO1xuICAgICAgY29uc3QgQl9jb21iaW5lID0gTVBDLmtleUNvbWJpbmUoQi51U2hhcmUsIFtBLnlTaGFyZXNbMl0sIEMueVNoYXJlc1syXV0pO1xuXG4gICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgMTA7IGluZGV4KyspIHtcbiAgICAgICAgY29uc3QgcGF0aCA9IGBtLyR7aW5kZXh9YDtcblxuICAgICAgICBjb25zdCBBX3N1YmtleSA9IE1QQy5rZXlEZXJpdmUoQS51U2hhcmUsIFtCLnlTaGFyZXNbMV0sIEMueVNoYXJlc1sxXV0sIHBhdGgpO1xuICAgICAgICBjb25zdCBCX3N1YmtleSA9IE1QQy5rZXlDb21iaW5lKEIudVNoYXJlLCBbQV9zdWJrZXkueVNoYXJlc1syXSwgQy55U2hhcmVzWzJdXSk7XG5cbiAgICAgICAgY29uc3Qgc29sUHVibGljS2V5ID0gbmV3IEtleVBhaXIoeyBwdWI6IEFfc3Via2V5LnBTaGFyZS55IH0pO1xuICAgICAgICBjb25zdCBzZW5kZXIgPSBzb2xQdWJsaWNLZXkuZ2V0QWRkcmVzcygpO1xuXG4gICAgICAgIGNvbnN0IHRyYW5zZmVyQnVpbGRlciA9IGZhY3RvcnlcbiAgICAgICAgICAuZ2V0VHJhbnNmZXJCdWlsZGVyKClcbiAgICAgICAgICAuc2VuZGVyKHNlbmRlcilcbiAgICAgICAgICAubm9uY2UodmFsaWRCbG9ja2hhc2gpXG4gICAgICAgICAgLmZlZSh7IGFtb3VudDogNTAwMCB9KVxuICAgICAgICAgIC5zZW5kKHsgYWRkcmVzczogbm9uY2VBY2NvdW50LnB1YiwgYW1vdW50OiAnMTAwMCcgfSk7XG4gICAgICAgIGNvbnN0IHVuc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCB0cmFuc2ZlckJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgY29uc3Qgc2lnbmFibGVQYXlsb2FkID0gdW5zaWduZWRUcmFuc2FjdGlvbi5zaWduYWJsZVBheWxvYWQ7XG5cbiAgICAgICAgY29uc3QgQV9zaWduX3NoYXJlID0gTVBDLnNpZ25TaGFyZShzaWduYWJsZVBheWxvYWQsIEFfc3Via2V5LnBTaGFyZSwgW0FfY29tYmluZS5qU2hhcmVzWzJdXSk7XG4gICAgICAgIGNvbnN0IEJfc2lnbl9zaGFyZSA9IE1QQy5zaWduU2hhcmUoc2lnbmFibGVQYXlsb2FkLCBCX3N1YmtleS5wU2hhcmUsIFtCX2NvbWJpbmUualNoYXJlc1sxXV0pO1xuICAgICAgICBjb25zdCBBX3NpZ24gPSBNUEMuc2lnbihzaWduYWJsZVBheWxvYWQsIEFfc2lnbl9zaGFyZS54U2hhcmUsIFtCX3NpZ25fc2hhcmUuclNoYXJlc1sxXV0sIFtDLnlTaGFyZXNbMV1dKTtcbiAgICAgICAgY29uc3QgQl9zaWduID0gTVBDLnNpZ24oc2lnbmFibGVQYXlsb2FkLCBCX3NpZ25fc2hhcmUueFNoYXJlLCBbQV9zaWduX3NoYXJlLnJTaGFyZXNbMl1dLCBbQy55U2hhcmVzWzJdXSk7XG5cbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlID0gTVBDLnNpZ25Db21iaW5lKFtBX3NpZ24sIEJfc2lnbl0pO1xuICAgICAgICBjb25zdCByYXdTaWduYXR1cmUgPSBCdWZmZXIuY29uY2F0KFtCdWZmZXIuZnJvbShzaWduYXR1cmUuUiwgJ2hleCcpLCBCdWZmZXIuZnJvbShzaWduYXR1cmUuc2lnbWEsICdoZXgnKV0pO1xuXG4gICAgICAgIHRyYW5zZmVyQnVpbGRlci5hZGRTaWduYXR1cmUoeyBwdWI6IHNlbmRlciB9LCByYXdTaWduYXR1cmUpO1xuXG4gICAgICAgIGNvbnN0IHNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgdHJhbnNmZXJCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIHNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hdHVyZS5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICBzaWduZWRUcmFuc2FjdGlvbi5zaWduYXR1cmVbMF0uc2hvdWxkLmVxdWFsKGJzNTguZW5jb2RlKHJhd1NpZ25hdHVyZSkpO1xuICAgICAgICBzaWduZWRUcmFuc2FjdGlvbi5pZC5zaG91bGQuZXF1YWwoYnM1OC5lbmNvZGUocmF3U2lnbmF0dXJlKSk7XG5cbiAgICAgICAgY29uc3QgcmF3VHJhbnNhY3Rpb24gPSBzaWduZWRUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpIGFzIHN0cmluZztcbiAgICAgICAgY29uc3QgcmVidWlsdFRyYW5zYWN0aW9uID0gYXdhaXQgZmFjdG9yeS5mcm9tKHJhd1RyYW5zYWN0aW9uKS5idWlsZCgpO1xuICAgICAgICByZWJ1aWx0VHJhbnNhY3Rpb24uaWQuc2hvdWxkLmVxdWFsKHNpZ25lZFRyYW5zYWN0aW9uLmlkKTtcbiAgICAgICAgcmVidWlsdFRyYW5zYWN0aW9uLnNpZ25hdHVyZS5zaG91bGQuZGVlcEVxdWFsKHNpZ25lZFRyYW5zYWN0aW9uLnNpZ25hdHVyZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!