bitgo
Version:
BitGo JavaScript SDK
574 lines • 107 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sdk_core_1 = require("@bitgo/sdk-core");
const openpgp = require("openpgp");
const should = require("should");
const _ = require("lodash");
const sdk_test_1 = require("@bitgo/sdk-test");
const bitgo_1 = require("../../../../src/bitgo");
const helpers_1 = require("./helpers");
const sinon = require("sinon");
const nock = require("nock");
describe('test tss helper functions', function () {
let mpc;
let userKeyShare;
let backupKeyShare;
let bitgoKeyShare;
let userKey;
let backupKey;
let bitgoKey;
let userGpgKeypair;
let backupGpgKeypair;
let bitgoGpgKeypair;
let commonKeychain;
before(async function () {
const hdTree = await sdk_core_1.Ed25519BIP32.initialize();
mpc = await sdk_core_1.Eddsa.initialize(hdTree);
userKeyShare = mpc.keyShare(1, 2, 3);
backupKeyShare = mpc.keyShare(2, 2, 3);
bitgoKeyShare = mpc.keyShare(3, 2, 3);
userKey = mpc.keyCombine(userKeyShare.uShare, [backupKeyShare.yShares[1], bitgoKeyShare.yShares[1]]);
backupKey = mpc.keyCombine(backupKeyShare.uShare, [userKeyShare.yShares[2], bitgoKeyShare.yShares[2]]);
bitgoKey = mpc.keyCombine(bitgoKeyShare.uShare, [backupKeyShare.yShares[3], userKeyShare.yShares[3]]);
(userKey.pShare.y + userKey.pShare.chaincode).should.equal(backupKey.pShare.y + backupKey.pShare.chaincode);
(userKey.pShare.y + userKey.pShare.chaincode).should.equal(bitgoKey.pShare.y + bitgoKey.pShare.chaincode);
commonKeychain = userKey.pShare.y + userKey.pShare.chaincode;
userGpgKeypair = await openpgp.generateKey({
userIDs: [
{
name: 'user',
email: 'user@bitgo.com',
},
],
});
backupGpgKeypair = await openpgp.generateKey({
userIDs: [
{
name: 'backup',
email: 'backup@bitgo.com',
},
],
});
bitgoGpgKeypair = await openpgp.generateKey({
userIDs: [
{
name: 'bitgo',
email: 'bitgo@bitgo.com',
},
],
});
});
after(function () {
nock.cleanAll();
});
describe('encryptYShare', function () {
it('should encrypt y share', async function () {
for (let i = 2; i <= 3; i++) {
const encryptedYShare = await (0, sdk_core_1.encryptYShare)({
keyShare: userKeyShare,
recipientIndex: i,
senderGpgPrivateArmor: userGpgKeypair.privateKey,
recipientGpgPublicArmor: bitgoGpgKeypair.publicKey,
});
const decryptedMessage = await (0, sdk_core_1.readSignedMessage)(encryptedYShare.encryptedPrivateShare, userGpgKeypair.publicKey, bitgoGpgKeypair.privateKey);
decryptedMessage.should.equal(userKeyShare.yShares[i].u + userKeyShare.yShares[i].chaincode);
encryptedYShare.i.should.equal(i);
encryptedYShare.j.should.equal(1);
encryptedYShare.publicShare.should.equal(userKeyShare.uShare.y + userKeyShare.yShares[3].v + userKeyShare.uShare.chaincode);
}
});
it('should error for invalid recipient index', async function () {
await (0, sdk_core_1.encryptYShare)({
keyShare: userKeyShare,
recipientIndex: 1,
senderGpgPrivateArmor: userGpgKeypair.privateKey,
recipientGpgPublicArmor: bitgoGpgKeypair.publicKey,
}).should.be.rejectedWith('Invalid recipient');
await (0, sdk_core_1.encryptYShare)({
keyShare: backupKeyShare,
recipientIndex: 2,
senderGpgPrivateArmor: userGpgKeypair.privateKey,
recipientGpgPublicArmor: bitgoGpgKeypair.publicKey,
}).should.be.rejectedWith('Invalid recipient');
await (0, sdk_core_1.encryptYShare)({
keyShare: bitgoKeyShare,
recipientIndex: 3,
senderGpgPrivateArmor: userGpgKeypair.privateKey,
recipientGpgPublicArmor: bitgoGpgKeypair.publicKey,
}).should.be.rejectedWith('Invalid recipient');
});
});
describe('createCombinedKey', function () {
it('should create combined user key', async function () {
const bitgoToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: bitgoKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: bitgoGpgKeypair.privateKey,
});
const backupToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: backupKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: backupGpgKeypair.privateKey,
});
const combinedUserKey = await (0, sdk_core_1.createCombinedKey)({
keyShare: userKeyShare,
commonKeychain,
encryptedYShares: [
{
yShare: bitgoToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
},
{
yShare: backupToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: backupGpgKeypair.publicKey,
},
],
});
combinedUserKey.commonKeychain.should.equal(commonKeychain);
combinedUserKey.signingMaterial.uShare.should.deepEqual(userKeyShare.uShare);
combinedUserKey.signingMaterial.backupYShare.should.deepEqual(backupKeyShare.yShares[1]);
combinedUserKey.signingMaterial.bitgoYShare.should.deepEqual(bitgoKeyShare.yShares[1]);
should.not.exist(combinedUserKey.signingMaterial.userYShare);
});
it('should create combined backup key', async function () {
const bitgoToBackupShare = await (0, sdk_core_1.encryptYShare)({
keyShare: bitgoKeyShare,
recipientIndex: 2,
recipientGpgPublicArmor: backupGpgKeypair.publicKey,
senderGpgPrivateArmor: bitgoGpgKeypair.privateKey,
});
const userToBackupShare = await (0, sdk_core_1.encryptYShare)({
keyShare: userKeyShare,
recipientIndex: 2,
recipientGpgPublicArmor: backupGpgKeypair.publicKey,
senderGpgPrivateArmor: userGpgKeypair.privateKey,
});
const combinedBackupKey = await (0, sdk_core_1.createCombinedKey)({
keyShare: backupKeyShare,
commonKeychain,
encryptedYShares: [
{
yShare: bitgoToBackupShare,
recipientPrivateArmor: backupGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
},
{
yShare: userToBackupShare,
recipientPrivateArmor: backupGpgKeypair.privateKey,
senderPublicArmor: userGpgKeypair.publicKey,
},
],
});
combinedBackupKey.commonKeychain.should.equal(commonKeychain);
combinedBackupKey.signingMaterial.uShare.should.deepEqual(backupKeyShare.uShare);
combinedBackupKey.signingMaterial.userYShare.should.deepEqual(userKeyShare.yShares[2]);
combinedBackupKey.signingMaterial.bitgoYShare.should.deepEqual(bitgoKeyShare.yShares[2]);
should.not.exist(combinedBackupKey.signingMaterial.backupYShare);
});
it('should fail if common keychains do not match', async function () {
const bitgoToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: bitgoKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: bitgoGpgKeypair.privateKey,
});
const backupToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: backupKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: backupGpgKeypair.privateKey,
});
await (0, sdk_core_1.createCombinedKey)({
keyShare: userKeyShare,
commonKeychain: 'nottherightkeychain',
encryptedYShares: [
{
yShare: bitgoToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
},
{
yShare: backupToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: backupGpgKeypair.publicKey,
},
],
}).should.be.rejectedWith('Common keychains do not match');
});
it('should fail if gpg keys are mismatched', async function () {
const bitgoToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: bitgoKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: bitgoGpgKeypair.privateKey,
});
const backupToUserShare = await (0, sdk_core_1.encryptYShare)({
keyShare: backupKeyShare,
recipientIndex: 1,
recipientGpgPublicArmor: userGpgKeypair.publicKey,
senderGpgPrivateArmor: backupGpgKeypair.privateKey,
});
await (0, sdk_core_1.createCombinedKey)({
keyShare: userKeyShare,
commonKeychain: 'nottherightkeychain',
encryptedYShares: [
{
yShare: bitgoToUserShare,
recipientPrivateArmor: backupGpgKeypair.privateKey,
senderPublicArmor: bitgoGpgKeypair.publicKey,
},
{
yShare: backupToUserShare,
recipientPrivateArmor: userGpgKeypair.privateKey,
senderPublicArmor: backupGpgKeypair.publicKey,
},
],
}).should.be.rejectedWith('Error decrypting message: Session key decryption failed.');
});
});
describe('Eddsa tss signing helper function', async function () {
const bitgo = sdk_test_1.TestBitGo.decorate(bitgo_1.BitGo, { env: 'mock' });
bitgo.initializeTestVars();
let wallet;
const path = 'm/0';
const validUserSigningMaterial = {
uShare: {
i: 1,
t: 2,
n: 3,
y: '093c8603ad86c41d5ee25a814b88185b435dd3a9ceccf9c9fd691a465ac4a8b0',
seed: 'ca40c789813250c334ddd2ba19050f6ed20b5a08853ceca492358f2711ad4b15',
chaincode: '596d5404a7eb918ee78247b952d06539619884091fdd9e0ff5a665f349e32fca',
},
commonChaincode: '596d5404a7eb918ee78247b952d06539619884091fdd9e0ff5a665f349e32fca',
bitgoYShare: {
i: 1,
j: 3,
y: '59d8000ba5e85fa402f39382960e7d5ede82b1b6e22b146a18b7df238c3a3225',
v: '01ea3f425b1adf8aec6cfe4fc8f9b94755c34657965f32397655dcd784f1b517',
u: '9ce3204a8c9757738967f3f81b463d87267bf6f2c0e5eaf2843167537b872b0b',
chaincode: 'd21dbd8eae5d4789292ecea2efa53e0165b2439d57f5158eb4dd57dc26b59236',
},
backupYShare: {
i: 1,
j: 2,
y: 'e0ae75077715686a121acb41b29a55bde426971154f40a41fc317f7f774a9424',
v: 'f76ef629dfc15ab5e4531e532b5d67f2176637ca752b195876b7e3172459c969',
u: 'fe6b89fb6acfcd7392c35c084f58bde0846b888c4df57e466caf0a3271b06a05',
chaincode: '1c34e5dfbbd4a870f4479caaa5e6a46e3438f976ad5aefd4905b8fe8bca1101e',
},
};
const validUserSignShare = {
xShare: {
i: 1,
y: '4d9343988e68191aac945a6963031dddde3490f9020d0571a6e6c6e15cca0296',
u: '1e159d6a0ae3a8dccc74615113e7c3e25d3080e5e0ffeb0ae04dd6a967268102',
r: 'c8f64cc48926216c3f60e1d8ff1e24eba060d7c1ff020d0fc1d735d4564efd03',
R: '9be2208ee28cd4b2577a9a66f6aab1ed8b08a300969eeb9b203a52aa54d2c23c',
},
rShares: {
3: {
i: 3,
j: 1,
u: 'd675f9099fbef03aa9fcdca4009286f435e56369c374d0042f03cc60b49e690a',
v: '3c090e88ed42da0dd0bade35c8d6b88bc050284536b98e5b27d33ff45da9755b',
r: '7f16224dbf5b02adb6c21380fcb2a8ee00323daae62cac3575a4d328fd23a905',
R: '9be2208ee28cd4b2577a9a66f6aab1ed8b08a300969eeb9b203a52aa54d2c23c',
commitment: '445c8cb1dee0166b6bdd5ad1d0a53fbfe86c4d3a470f184745530a863eedff28',
},
},
};
const validUserToBitgoGShare = {
i: 1,
y: '4d9343988e68191aac945a6963031dddde3490f9020d0571a6e6c6e15cca0296',
gamma: 'ce87a00d17e52b91bc5bb6e275983b84fc1998b2b37f7166c671a019c33d3905',
R: 'aa6e5bad24ad4131b8793dcb95c72e03c5426456ab0b52fc99d61d7103c2f01b',
};
const validBitgoToUserSignShare = {
xShare: {
i: 3,
y: '4d9343988e68191aac945a6963031dddde3490f9020d0571a6e6c6e15cca0296',
u: '1315dbe18069825b4a27188b813eae7ff2917a614499ed553e70d65d4fa4820b',
r: 'd0539375e6566f2fe540cba48c5e56bd1cdf68cfe1f0d527d2b730fe4e879809',
R: 'c883fe2ae9b8da1764cc36a526cfa1a21f81d604320b209867f8de9223f1de32',
},
rShares: {
1: {
i: 1,
j: 3,
u: '9ce3204a8c9757738967f3f81b463d87267bf6f2c0e5eaf2843167537b872b0b',
v: '01ea3f425b1adf8aec6cfe4fc8f9b94755c34657965f32397655dcd784f1b517',
r: '0375e8c5a5691a73c21df00d49d423e3f83fe08d7b5d5af33c5c6aa9cae59d0a',
R: 'c883fe2ae9b8da1764cc36a526cfa1a21f81d604320b209867f8de9223f1de32',
commitment: '62b21f98bf885841ad469145192d4df0697b3f42c581e3e926394eae0b101ecb',
},
},
};
const txRequest = {
txRequestId: 'randomId',
unsignedTxs: [{ signableHex: 'MPC on a Friday night', serializedTxHex: 'MPC on a Friday night' }],
signatureShares: [
{
from: 'bitgo',
to: 'user',
share: validBitgoToUserSignShare.rShares[1].r + validBitgoToUserSignShare.rShares[1].R,
},
],
};
const signablePayload = Buffer.from(txRequest.unsignedTxs[0].signableHex);
const bitgoToUserCommitment = {
from: sdk_core_1.SignatureShareType.BITGO,
to: sdk_core_1.SignatureShareType.USER,
share: validBitgoToUserSignShare.rShares[1].commitment,
type: sdk_core_1.CommitmentType.COMMITMENT,
};
let MPC;
before('initializes', async function () {
const hdTree = await sdk_core_1.Ed25519BIP32.initialize();
MPC = await sdk_core_1.Eddsa.initialize(hdTree);
const baseCoin = bitgo.coin('tsol');
const walletData = {
id: '5b34252f1bf349930e34020a00000000',
coin: 'tsol',
keys: [
'5b3424f91bf349930e34017500000000',
'5b3424f91bf349930e34017600000000',
'5b3424f91bf349930e34017700000000',
],
coinSpecific: {},
};
wallet = new sdk_core_1.Wallet(bitgo, baseCoin, walletData);
});
describe('createUserSignShare:', async function () {
it('should succeed to create User SignShare', async function () {
const signingKey = MPC.keyDerive(validUserSigningMaterial.uShare, [validUserSigningMaterial.bitgoYShare, validUserSigningMaterial.backupYShare], path);
const userSignShare = await (0, sdk_core_1.createUserSignShare)(signablePayload, signingKey.pShare);
userSignShare.should.have.properties(['xShare', 'rShares']);
const { xShare, rShares } = userSignShare;
xShare.should.have.property('i').and.be.a.Number();
xShare.should.have.property('y').and.be.a.String();
xShare.should.have.property('u').and.be.a.String();
xShare.should.have.property('r').and.be.a.String();
xShare.should.have.property('R').and.be.a.String();
rShares.should.have.property('3').and.be.an.Object();
rShares[3].should.have.property('i').and.be.a.Number();
rShares[3].should.have.property('j').and.be.a.Number();
rShares[3].should.have.property('r').and.be.a.String();
rShares[3].should.have.property('R').and.be.a.String();
});
it('should fail if the Pshare doesnt belong to the User', async function () {
const invalidUserSigningMaterial = JSON.parse('{"uShare":{"i":2,"t":2,"n":3,"y":"e2b844934b56f278b4a8a3665d43d14de80732241622ec7a8bd6cffc0f74452a","seed":"5259ee23a364429919f969247323eee2f4af5786457b4af67d423f8944d3a691","chaincode":"7460de17d732969c3bc9bddbac1055aff168fad5668917b8ed3fd9628fc6e4f8"},"bitgoYShare":{"i":2,"j":3,"y":"141fd5cbb901d46b8c2c783f3d4ee968ae91c38f71aba05146b3ba8bd4309596","u":"581cfacb3de956cc434a35a3ac927f7d0a4daaef48a95c162cadb7878ef2270b","chaincode":"67d33063052606f341cae40877709de725abda41f2df7f4765e3f58ce5030e1a"},"backupYShare":{"i":2,"j":1,"y":"9e69e3e92978896e872d71ff7a9e63a963ab0f59583d4fcbe79f82cde9ea6bf9","u":"52a539f79df448a2f5108a5e410377cbd1574b7c3d9864bb310ebf7beb13460d","chaincode":"bda980c34aa06916f25c4c7934ea09a928bff7730a100902f4d53bb9236771a7"}}');
const signingKey = MPC.keyDerive(invalidUserSigningMaterial.uShare, [invalidUserSigningMaterial.bitgoYShare, invalidUserSigningMaterial.backupYShare], path);
await (0, sdk_core_1.createUserSignShare)(signablePayload, signingKey.pShare).should.be.rejectedWith('Invalid PShare, PShare doesnt belong to the User');
});
});
describe('sendSignatureShare:', async function () {
it('should succeed to send Signature Share', async function () {
const signatureShare = { from: 'user', to: 'bitgo', share: '128bytestring' };
await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare,
signerShare: 'signerShare',
});
const response = await (0, sdk_core_1.sendSignatureShare)(bitgo, wallet.id(), txRequest.txRequestId, signatureShare, sdk_core_1.RequestType.tx, 'signerShare');
response.should.deepEqual(signatureShare);
});
it('should fail to send Signature Share', async function () {
const invalidSignatureShare = { from: 'bitgo', to: 'user', share: '128bytestring' };
const nock = await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare: invalidSignatureShare,
signerShare: 'signerShare',
}, 400);
await (0, sdk_core_1.sendSignatureShare)(bitgo, wallet.id(), txRequest.txRequestId, invalidSignatureShare, sdk_core_1.RequestType.tx, 'signerShare').should.be.rejectedWith('some error');
nock.isDone().should.equal(true);
});
});
describe('offerUserToBitgoRShare:', async function () {
it('should succeed to send Signature Share', async function () {
const signatureShare = {
from: 'user',
to: 'bitgo',
share: validUserSignShare.rShares[3].r + validUserSignShare.rShares[3].R,
};
const nock = await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare,
signerShare: 'signerShare',
});
await (0, sdk_core_1.offerUserToBitgoRShare)(bitgo, wallet.id(), txRequest.txRequestId, validUserSignShare, 'signerShare').should.be.fulfilled();
nock.isDone().should.equal(true);
});
it('should fail if no rShare is found', async function () {
const invalidUserSignShare = _.cloneDeep(validUserSignShare);
delete invalidUserSignShare.rShares[3];
await (0, sdk_core_1.offerUserToBitgoRShare)(bitgo, wallet.id(), txRequest.txRequestId, invalidUserSignShare, 'signerShare').should.be.rejectedWith('userToBitgo RShare not found');
});
it('should fail if the rShare found is invalid', async function () {
const invalidUserSignShare = _.cloneDeep(validUserSignShare);
invalidUserSignShare.rShares[3].i = 1;
await (0, sdk_core_1.offerUserToBitgoRShare)(bitgo, wallet.id(), txRequest.txRequestId, invalidUserSignShare, 'signerShare').should.be.rejectedWith('Invalid RShare, is not from User to Bitgo');
const invalidUserSignShare2 = _.cloneDeep(validUserSignShare);
invalidUserSignShare2.rShares[3].j = 3;
await (0, sdk_core_1.offerUserToBitgoRShare)(bitgo, wallet.id(), txRequest.txRequestId, invalidUserSignShare2, 'signerShare').should.be.rejectedWith('Invalid RShare, is not from User to Bitgo');
});
it('should call setRequestTracer', async function () {
const signatureShare = {
from: 'user',
to: 'bitgo',
share: validUserSignShare.rShares[3].r + validUserSignShare.rShares[3].R,
};
const nock = await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare,
signerShare: 'signerShare',
});
const reqId = new sdk_core_1.RequestTracer();
const setRequestTracerSpy = sinon.spy(bitgo, 'setRequestTracer');
setRequestTracerSpy.withArgs(reqId);
await (0, sdk_core_1.offerUserToBitgoRShare)(bitgo, wallet.id(), txRequest.txRequestId, validUserSignShare, 'signerShare', undefined, reqId).should.be.fulfilled();
nock.isDone().should.equal(true);
sinon.assert.calledOnce(setRequestTracerSpy);
setRequestTracerSpy.restore();
});
});
describe('getBitgoToUserRShare:', async function () {
it('should succeed to get the Bitgo to User RShare', async function () {
const response = { txRequests: [txRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
const bitgoToUserRShare = await (0, sdk_core_1.getBitgoToUserRShare)(bitgo, wallet.id(), txRequest.txRequestId);
bitgoToUserRShare.should.deepEqual(txRequest.signatureShares[0]);
nock.isDone().should.equal(true);
});
it('should fail if there is no bitgo to user RShare', async function () {
const invalidTxRequest = _.cloneDeep(txRequest);
invalidTxRequest.signatureShares[0].to = 'bitgo';
invalidTxRequest.signatureShares[0].from = 'user';
const response = { txRequests: [invalidTxRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
await (0, sdk_core_1.getBitgoToUserRShare)(bitgo, wallet.id(), txRequest.txRequestId).should.be.rejectedWith('Bitgo to User RShare not found for id: ' + txRequest.txRequestId);
nock.isDone().should.equal(true);
});
it('should fail if there is no signaturesShares', async function () {
const invalidTxRequest = _.cloneDeep(txRequest);
invalidTxRequest.signatureShares = [];
const response = { txRequests: [invalidTxRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
await (0, sdk_core_1.getBitgoToUserRShare)(bitgo, wallet.id(), txRequest.txRequestId).should.be.rejectedWith('No signatures shares found for id: ' + txRequest.txRequestId);
nock.isDone().should.equal(true);
});
it('should call setRequestTracer', async function () {
const response = { txRequests: [txRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
const reqId = new sdk_core_1.RequestTracer();
const setRequestTracerSpy = sinon.spy(bitgo, 'setRequestTracer');
setRequestTracerSpy.withArgs(reqId);
const bitgoToUserRShare = await (0, sdk_core_1.getBitgoToUserRShare)(bitgo, wallet.id(), txRequest.txRequestId, reqId);
bitgoToUserRShare.should.deepEqual(txRequest.signatureShares[0]);
nock.isDone().should.equal(true);
sinon.assert.calledOnce(setRequestTracerSpy);
setRequestTracerSpy.restore();
});
});
describe('sendUserToBitgoGShare:', async function () {
it('should succeed to send User to Bitgo GShare', async function () {
const signatureShare = {
from: 'user',
to: 'bitgo',
share: validUserToBitgoGShare.R + validUserToBitgoGShare.gamma,
};
const nock = await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare,
});
await (0, sdk_core_1.sendUserToBitgoGShare)(bitgo, wallet.id(), txRequest.txRequestId, validUserToBitgoGShare).should.be.fulfilled();
nock.isDone().should.equal(true);
});
it('should fail when the GShare is not from the User', async function () {
const invalidUserToBitgoGShare = _.cloneDeep(validUserToBitgoGShare);
invalidUserToBitgoGShare.i = 3;
await (0, sdk_core_1.sendUserToBitgoGShare)(bitgo, wallet.id(), txRequest.txRequestId, invalidUserToBitgoGShare).should.be.rejectedWith('Invalid GShare, doesnt belong to the User');
});
it('should call setRequestTracer', async function () {
const signatureShare = {
from: 'user',
to: 'bitgo',
share: validUserToBitgoGShare.R + validUserToBitgoGShare.gamma,
};
const nock = await (0, helpers_1.nockSendSignatureShare)({
walletId: wallet.id(),
txRequestId: txRequest.txRequestId,
signatureShare,
});
const reqId = new sdk_core_1.RequestTracer();
const setRequestTracerSpy = sinon.spy(bitgo, 'setRequestTracer');
setRequestTracerSpy.withArgs(reqId);
await (0, sdk_core_1.sendUserToBitgoGShare)(bitgo, wallet.id(), txRequest.txRequestId, validUserToBitgoGShare, undefined, reqId).should.be.fulfilled();
nock.isDone().should.equal(true);
sinon.assert.calledOnce(setRequestTracerSpy);
setRequestTracerSpy.restore();
});
});
describe('getTxRequest:', async function () {
it('should succeed to get txRequest by id', async function () {
const response = { txRequests: [txRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
const txReq = await (0, sdk_core_1.getTxRequest)(bitgo, wallet.id(), txRequest.txRequestId);
txReq.should.deepEqual(txRequest);
nock.isDone().should.equal(true);
});
it('should fail if there are no txRequests', async function () {
const response = { txRequests: [] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
await (0, sdk_core_1.getTxRequest)(bitgo, wallet.id(), txRequest.txRequestId).should.be.rejectedWith('Unable to find TxRequest with id randomId');
nock.isDone().should.equal(true);
});
it('should call setRequestTracer', async function () {
const response = { txRequests: [txRequest] };
const nock = await (0, helpers_1.nockGetTxRequest)({ walletId: wallet.id(), txRequestId: txRequest.txRequestId, response });
const reqId = new sdk_core_1.RequestTracer();
const setRequestTracerSpy = sinon.spy(bitgo, 'setRequestTracer');
setRequestTracerSpy.withArgs(reqId);
const txReq = await (0, sdk_core_1.getTxRequest)(bitgo, wallet.id(), txRequest.txRequestId, reqId);
txReq.should.deepEqual(txRequest);
nock.isDone().should.equal(true);
sinon.assert.calledOnce(setRequestTracerSpy);
setRequestTracerSpy.restore();
});
});
describe('createUserToBitGoGShare:', async function () {
it('should succeed to create a UserToBitGo GShare', async function () {
const userToBitgoGShare = await (0, sdk_core_1.createUserToBitGoGShare)(validUserSignShare, txRequest.signatureShares[0], validUserSigningMaterial.backupYShare, validUserSigningMaterial.bitgoYShare, signablePayload, bitgoToUserCommitment);
userToBitgoGShare.should.deepEqual(validUserToBitgoGShare);
});
it('should fail when XShare doesnt belong to the user', async function () {
const invalidUserSignShare = _.cloneDeep(validUserSignShare);
invalidUserSignShare.xShare.i = 3;
await (0, sdk_core_1.createUserToBitGoGShare)(invalidUserSignShare, txRequest.signatureShares[0], validUserSigningMaterial.backupYShare, validUserSigningMaterial.bitgoYShare, signablePayload, bitgoToUserCommitment).should.be.rejectedWith('Invalid XShare, doesnt belong to the User');
});
it('should fail when commitment is invalid', async function () {
const invalidBitgoToUserCommitment = _.cloneDeep(bitgoToUserCommitment);
invalidBitgoToUserCommitment.share = 'deadbeef';
await (0, sdk_core_1.createUserToBitGoGShare)(validUserSignShare, txRequest.signatureShares[0], validUserSigningMaterial.backupYShare, validUserSigningMaterial.bitgoYShare, signablePayload, invalidBitgoToUserCommitment).should.be.rejectedWith('Could not verify other player share');
});
it('should fail when RShare doesnt belong to Bitgo', async function () {
const invalidBitgoRShare = _.cloneDeep(txRequest.signatureShares[0]);
invalidBitgoRShare.from = 'user';
await (0, sdk_core_1.createUserToBitGoGShare)(validUserSignShare, invalidBitgoRShare, validUserSigningMaterial.backupYShare, validUserSigningMaterial.bitgoYShare, signablePayload, bitgoToUserCommitment).should.be.rejectedWith('Invalid RShare, is not from Bitgo to User');
const invalidBitgoRShare2 = _.cloneDeep(txRequest.signatureShares[0]);
invalidBitgoRShare2.to = 'bitgo';
await (0, sdk_core_1.createUserToBitGoGShare)(validUserSignShare, invalidBitgoRShare2, validUserSigningMaterial.backupYShare, validUserSigningMaterial.bitgoYShare, signablePayload, bitgoToUserCommitment).should.be.rejectedWith('Invalid RShare, is not from Bitgo to User');
});
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRkc2EuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi90ZXN0L3YyL3VuaXQvdHNzL2VkZHNhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsOENBc0J5QjtBQUN6QixtQ0FBbUM7QUFDbkMsaUNBQWtDO0FBQ2xDLDRCQUE0QjtBQUM1Qiw4Q0FBNEM7QUFDNUMsaURBQThDO0FBQzlDLHVDQUFxRTtBQUNyRSwrQkFBK0I7QUFDL0IsNkJBQThCO0FBRTlCLFFBQVEsQ0FBQywyQkFBMkIsRUFBRTtJQUNwQyxJQUFJLEdBQVUsQ0FBQztJQUVmLElBQUksWUFBc0IsQ0FBQztJQUMzQixJQUFJLGNBQXdCLENBQUM7SUFDN0IsSUFBSSxhQUF1QixDQUFDO0lBRTVCLElBQUksT0FBTyxDQUFDO0lBQ1osSUFBSSxTQUFTLENBQUM7SUFDZCxJQUFJLFFBQVEsQ0FBQztJQUViLElBQUksY0FBeUQsQ0FBQztJQUM5RCxJQUFJLGdCQUEyRCxDQUFDO0lBQ2hFLElBQUksZUFBMEQsQ0FBQztJQUUvRCxJQUFJLGNBQXNCLENBQUM7SUFFM0IsTUFBTSxDQUFDLEtBQUs7UUFDVixNQUFNLE1BQU0sR0FBRyxNQUFNLHVCQUFZLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDL0MsR0FBRyxHQUFHLE1BQU0sZ0JBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFckMsWUFBWSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyQyxjQUFjLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLGFBQWEsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFdEMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckcsU0FBUyxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkcsUUFBUSxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFdEcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM1RyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFHLGNBQWMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztRQUU3RCxjQUFjLEdBQUcsTUFBTSxPQUFPLENBQUMsV0FBVyxDQUFDO1lBQ3pDLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxJQUFJLEVBQUUsTUFBTTtvQkFDWixLQUFLLEVBQUUsZ0JBQWdCO2lCQUN4QjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsZ0JBQWdCLEdBQUcsTUFBTSxPQUFPLENBQUMsV0FBVyxDQUFDO1lBQzNDLE9BQU8sRUFBRTtnQkFDUDtvQkFDRSxJQUFJLEVBQUUsUUFBUTtvQkFDZCxLQUFLLEVBQUUsa0JBQWtCO2lCQUMxQjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsZUFBZSxHQUFHLE1BQU0sT0FBTyxDQUFDLFdBQVcsQ0FBQztZQUMxQyxPQUFPLEVBQUU7Z0JBQ1A7b0JBQ0UsSUFBSSxFQUFFLE9BQU87b0JBQ2IsS0FBSyxFQUFFLGlCQUFpQjtpQkFDekI7YUFDRjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsS0FBSyxDQUFDO1FBQ0osSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2xCLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGVBQWUsRUFBRTtRQUN4QixFQUFFLENBQUMsd0JBQXdCLEVBQUUsS0FBSztZQUNoQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQzVCLE1BQU0sZUFBZSxHQUFHLE1BQU0sSUFBQSx3QkFBYSxFQUFDO29CQUMxQyxRQUFRLEVBQUUsWUFBWTtvQkFDdEIsY0FBYyxFQUFFLENBQUM7b0JBQ2pCLHFCQUFxQixFQUFFLGNBQWMsQ0FBQyxVQUFVO29CQUNoRCx1QkFBdUIsRUFBRSxlQUFlLENBQUMsU0FBUztpQkFDbkQsQ0FBQyxDQUFDO2dCQUVILE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxJQUFBLDRCQUFpQixFQUM5QyxlQUFlLENBQUMscUJBQXFCLEVBQ3JDLGNBQWMsQ0FBQyxTQUFTLEVBQ3hCLGVBQWUsQ0FBQyxVQUFVLENBQzNCLENBQUM7Z0JBQ0YsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUU3RixlQUFlLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xDLGVBQWUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbEMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUN0QyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FDbEYsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywwQ0FBMEMsRUFBRSxLQUFLO1lBQ2xELE1BQU0sSUFBQSx3QkFBYSxFQUFDO2dCQUNsQixRQUFRLEVBQUUsWUFBWTtnQkFDdEIsY0FBYyxFQUFFLENBQUM7Z0JBQ2pCLHFCQUFxQixFQUFFLGNBQWMsQ0FBQyxVQUFVO2dCQUNoRCx1QkFBdUIsRUFBRSxlQUFlLENBQUMsU0FBUzthQUNuRCxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsbUJBQW1CLENBQUMsQ0FBQztZQUMvQyxNQUFNLElBQUEsd0JBQWEsRUFBQztnQkFDbEIsUUFBUSxFQUFFLGNBQWM7Z0JBQ3hCLGNBQWMsRUFBRSxDQUFDO2dCQUNqQixxQkFBcUIsRUFBRSxjQUFjLENBQUMsVUFBVTtnQkFDaEQsdUJBQXVCLEVBQUUsZUFBZSxDQUFDLFNBQVM7YUFDbkQsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLG1CQUFtQixDQUFDLENBQUM7WUFDL0MsTUFBTSxJQUFBLHdCQUFhLEVBQUM7Z0JBQ2xCLFFBQVEsRUFBRSxhQUFhO2dCQUN2QixjQUFjLEVBQUUsQ0FBQztnQkFDakIscUJBQXFCLEVBQUUsY0FBYyxDQUFDLFVBQVU7Z0JBQ2hELHVCQUF1QixFQUFFLGVBQWUsQ0FBQyxTQUFTO2FBQ25ELENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ2pELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsbUJBQW1CLEVBQUU7UUFDNUIsRUFBRSxDQUFDLGlDQUFpQyxFQUFFLEtBQUs7WUFDekMsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLElBQUEsd0JBQWEsRUFBQztnQkFDM0MsUUFBUSxFQUFFLGFBQWE7Z0JBQ3ZCLGNBQWMsRUFBRSxDQUFDO2dCQUNqQix1QkFBdUIsRUFBRSxjQUFjLENBQUMsU0FBUztnQkFDakQscUJBQXFCLEVBQUUsZUFBZSxDQUFDLFVBQVU7YUFDbEQsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLElBQUEsd0JBQWEsRUFBQztnQkFDNUMsUUFBUSxFQUFFLGNBQWM7Z0JBQ3hCLGNBQWMsRUFBRSxDQUFDO2dCQUNqQix1QkFBdUIsRUFBRSxjQUFjLENBQUMsU0FBUztnQkFDakQscUJBQXFCLEVBQUUsZ0JBQWdCLENBQUMsVUFBVTthQUNuRCxDQUFDLENBQUM7WUFFSCxNQUFNLGVBQWUsR0FBRyxNQUFNLElBQUEsNEJBQWlCLEVBQUM7Z0JBQzlDLFFBQVEsRUFBRSxZQUFZO2dCQUN0QixjQUFjO2dCQUNkLGdCQUFnQixFQUFFO29CQUNoQjt3QkFDRSxNQUFNLEVBQUUsZ0JBQWdCO3dCQUN4QixxQkFBcUIsRUFBRSxjQUFjLENBQUMsVUFBVTt3QkFDaEQsaUJBQWlCLEVBQUUsZUFBZSxDQUFDLFNBQVM7cUJBQzdDO29CQUNEO3dCQUNFLE1BQU0sRUFBRSxpQkFBaUI7d0JBQ3pCLHFCQUFxQixFQUFFLGNBQWMsQ0FBQyxVQUFVO3dCQUNoRCxpQkFBaUIsRUFBRSxnQkFBZ0IsQ0FBQyxTQUFTO3FCQUM5QztpQkFDRjthQUNGLENBQUMsQ0FBQztZQUVILGVBQWUsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUM1RCxlQUFlLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM3RSxlQUFlLENBQUMsZUFBZSxDQUFDLFlBQWEsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMxRixlQUFlLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2RixNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQy9ELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1DQUFtQyxFQUFFLEtBQUs7WUFDM0MsTUFBTSxrQkFBa0IsR0FBRyxNQUFNLElBQUEsd0JBQWEsRUFBQztnQkFDN0MsUUFBUSxFQUFFLGFBQWE7Z0JBQ3ZCLGNBQWMsRUFBRSxDQUFDO2dCQUNqQix1QkFBdUIsRUFBRSxnQkFBZ0IsQ0FBQyxTQUFTO2dCQUNuRCxxQkFBcUIsRUFBRSxlQUFlLENBQUMsVUFBVTthQUNsRCxDQUFDLENBQUM7WUFDSCxNQUFNLGlCQUFpQixHQUFHLE1BQU0sSUFBQSx3QkFBYSxFQUFDO2dCQUM1QyxRQUFRLEVBQUUsWUFBWTtnQkFDdEIsY0FBYyxFQUFFLENBQUM7Z0JBQ2pCLHVCQUF1QixFQUFFLGdCQUFnQixDQUFDLFNBQVM7Z0JBQ25ELHFCQUFxQixFQUFFLGNBQWMsQ0FBQyxVQUFVO2FBQ2pELENBQUMsQ0FBQztZQUVILE1BQU0saUJBQWlCLEdBQUcsTUFBTSxJQUFBLDRCQUFpQixFQUFDO2dCQUNoRCxRQUFRLEVBQUUsY0FBYztnQkFDeEIsY0FBYztnQkFDZCxnQkFBZ0IsRUFBRTtvQkFDaEI7d0JBQ0UsTUFBTSxFQUFFLGtCQUFrQjt3QkFDMUIscUJBQXFCLEVBQUUsZ0JBQWdCLENBQUMsVUFBVTt3QkFDbEQsaUJBQWlCLEVBQUUsZUFBZSxDQUFDLFNBQVM7cUJBQzdDO29CQUNEO3dCQUNFLE1BQU0sRUFBRSxpQkFBaUI7d0JBQ3pCLHFCQUFxQixFQUFFLGdCQUFnQixDQUFDLFVBQVU7d0JBQ2xELGlCQUFpQixFQUFFLGNBQWMsQ0FBQyxTQUFTO3FCQUM1QztpQkFDRjthQUNGLENBQUMsQ0FBQztZQUVILGlCQUFpQixDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQzlELGlCQUFpQixDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDakYsaUJBQWlCLENBQUMsZUFBZSxDQUFDLFVBQVcsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4RixpQkFBaUIsQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pGLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNuRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRSxLQUFLO1lBQ3RELE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxJQUFBLHdCQUFhLEVBQUM7Z0JBQzNDLFFBQVEsRUFBRSxhQUFhO2dCQUN2QixjQUFjLEVBQUUsQ0FBQztnQkFDakIsdUJBQXVCLEVBQUUsY0FBYyxDQUFDLFNBQVM7Z0JBQ2pELHFCQUFxQixFQUFFLGVBQWUsQ0FBQyxVQUFVO2FBQ2xELENBQUMsQ0FBQztZQUNILE1BQU0saUJBQWlCLEdBQUcsTUFBTSxJQUFBLHdCQUFhLEVBQUM7Z0JBQzVDLFFBQVEsRUFBRSxjQUFjO2dCQUN4QixjQUFjLEVBQUUsQ0FBQztnQkFDakIsdUJBQXVCLEVBQUUsY0FBYyxDQUFDLFNBQVM7Z0JBQ2pELHFCQUFxQixFQUFFLGdCQUFnQixDQUFDLFVBQVU7YUFDbkQsQ0FBQyxDQUFDO1lBRUgsTUFBTSxJQUFBLDRCQUFpQixFQUFDO2dCQUN0QixRQUFRLEVBQUUsWUFBWTtnQkFDdEIsY0FBYyxFQUFFLHFCQUFxQjtnQkFDckMsZ0JBQWdCLEVBQUU7b0JBQ2hCO3dCQUNFLE1BQU0sRUFBRSxnQkFBZ0I7d0JBQ3hCLHFCQUFxQixFQUFFLGNBQWMsQ0FBQyxVQUFVO3dCQUNoRCxpQkFBaUIsRUFBRSxlQUFlLENBQUMsU0FBUztxQkFDN0M7b0JBQ0Q7d0JBQ0UsTUFBTSxFQUFFLGlCQUFpQjt3QkFDekIscUJBQXFCLEVBQUUsY0FBYyxDQUFDLFVBQVU7d0JBQ2hELGlCQUFpQixFQUFFLGdCQUFnQixDQUFDLFNBQVM7cUJBQzlDO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFDN0QsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0NBQXdDLEVBQUUsS0FBSztZQUNoRCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sSUFBQSx3QkFBYSxFQUFDO2dCQUMzQyxRQUFRLEVBQUUsYUFBYTtnQkFDdkIsY0FBYyxFQUFFLENBQUM7Z0JBQ2pCLHVCQUF1QixFQUFFLGNBQWMsQ0FBQyxTQUFTO2dCQUNqRCxxQkFBcUIsRUFBRSxlQUFlLENBQUMsVUFBVTthQUNsRCxDQUFDLENBQUM7WUFDSCxNQUFNLGlCQUFpQixHQUFHLE1BQU0sSUFBQSx3QkFBYSxFQUFDO2dCQUM1QyxRQUFRLEVBQUUsY0FBYztnQkFDeEIsY0FBYyxFQUFFLENBQUM7Z0JBQ2pCLHVCQUF1QixFQUFFLGNBQWMsQ0FBQyxTQUFTO2dCQUNqRCxxQkFBcUIsRUFBRSxnQkFBZ0IsQ0FBQyxVQUFVO2FBQ25ELENBQUMsQ0FBQztZQUVILE1BQU0sSUFBQSw0QkFBaUIsRUFBQztnQkFDdEIsUUFBUSxFQUFFLFlBQVk7Z0JBQ3RCLGNBQWMsRUFBRSxxQkFBcUI7Z0JBQ3JDLGdCQUFnQixFQUFFO29CQUNoQjt3QkFDRSxNQUFNLEVBQUUsZ0JBQWdCO3dCQUN4QixxQkFBcUIsRUFBRSxnQkFBZ0IsQ0FBQyxVQUFVO3dCQUNsRCxpQkFBaUIsRUFBRSxlQUFlLENBQUMsU0FBUztxQkFDN0M7b0JBQ0Q7d0JBQ0UsTUFBTSxFQUFFLGlCQUFpQjt3QkFDekIscUJBQXFCLEVBQUUsY0FBYyxDQUFDLFVBQVU7d0JBQ2hELGlCQUFpQixFQUFFLGdCQUFnQixDQUFDLFNBQVM7cUJBQzlDO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLDBEQUEwRCxDQUFDLENBQUM7UUFDeEYsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxtQ0FBbUMsRUFBRSxLQUFLO1FBQ2pELE1BQU0sS0FBSyxHQUFHLG9CQUFTLENBQUMsUUFBUSxDQUFDLGFBQUssRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBRTNCLElBQUksTUFBYyxDQUFDO1FBQ25CLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQztRQUNuQixNQUFNLHdCQUF3QixHQUFHO1lBQy9CLE1BQU0sRUFBRTtnQkFDTixDQUFDLEVBQUUsQ0FBQztnQkFDSixDQUFDLEVBQUUsQ0FBQztnQkFDSixDQUFDLEVBQUUsQ0FBQztnQkFDSixDQUFDLEVBQUUsa0VBQWtFO2dCQUNyRSxJQUFJLEVBQUUsa0VBQWtFO2dCQUN4RSxTQUFTLEVBQUUsa0VBQWtFO2FBQzlFO1lBQ0QsZUFBZSxFQUFFLGtFQUFrRTtZQUNuRixXQUFXLEVBQUU7Z0JBQ1gsQ0FBQyxFQUFFLENBQUM7Z0JBQ0osQ0FBQyxFQUFFLENBQUM7Z0JBQ0osQ0FBQyxFQUFFLGtFQUFrRTtnQkFDckUsQ0FBQyxFQUFFLGtFQUFrRTtnQkFDckUsQ0FBQyxFQUFFLGtFQUFrRTtnQkFDckUsU0FBUyxFQUFFLGtFQUFrRTthQUM5RTtZQUNELFlBQVksRUFBRTtnQkFDWixDQUFDLEVBQUUsQ0FBQztnQkFDSixDQUFDLEVBQUUsQ0FBQztnQkFDSixDQUFDLEVBQUUsa0VBQWtFO2dCQUNyRSxDQUFDLEVBQUUsa0VBQWtFO2dCQUNyRSxDQUFDLEVBQUUsa0VBQWtFO2dCQUNyRSxTQUFTLEVBQUUsa0VBQWtFO2FBQzlFO1NBQ0YsQ0FBQztRQUNGLE1BQU0sa0JBQWtCLEdBQWM7WUFDcEMsTUFBTSxFQUFFO2dCQUNOLENBQUMsRUFBRSxDQUFDO2dCQUNKLENBQUMsRUFBRSxrRUFBa0U7Z0JBQ3JFLENBQUMsRUFBRSxrRUFBa0U7Z0JBQ3JFLENBQUMsRUFBRSxrRUFBa0U7Z0JBQ3JFLENBQUMsRUFBRSxrRUFBa0U7YUFDdEU7WUFDRCxPQUFPLEVBQUU7Z0JBQ1AsQ0FBQyxFQUFFO29CQUNELENBQUMsRUFBRSxDQUFDO29CQUNKLENBQUMsRUFBRSxDQUFDO29CQUNKLENBQUMsRUFBRSxrRUFBa0U7b0JBQ3JFLENBQUMsRUFBRSxrRUFBa0U7b0JBQ3JFLENBQUMsRUFBRSxrRUFBa0U7b0JBQ3JFLENBQUMsRUFBRSxrRUFBa0U7b0JBQ3JFLFVBQVUsRUFBRSxrRUFBa0U7aUJBQy9FO2FBQ0Y7U0FDRixDQUFDO1FBRUYsTUFBTSxzQkFBc0IsR0FBRztZQUM3QixDQUFDLEVBQUUsQ0FBQztZQUNKLENBQUMsRUFBRSxrRUFBa0U7WUFDckUsS0FBSyxFQUFFLGtFQUFrRTtZQUN6RSxDQUFDLEVBQUUsa0VBQWtFO1NBQ3RFLENBQUM7UUFDRixNQUFNLHlCQUF5QixHQUFjO1lBQzNDLE1BQU0sRUFBRTtnQkFDTixDQUFDLEVBQUUsQ0FBQztnQkFDSixDQUFDLEVBQUUsa0VBQWtFO2dCQUNyRSxDQUFDLEVBQUUsa0VBQWtFO2dCQUNyRSxDQUFDLEVBQUUsa0VBQWtFO2dCQUNyRSxDQUFDLEVBQUUsa0VBQWtFO2FBQ3RFO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLENBQUMsRUFBRTtvQkFDRCxDQUFDLEVBQUUsQ0FBQztvQkFDSixDQUFDLEVBQUUsQ0FBQztvQkFDSixDQUFDLEVBQUUsa0VBQWtFO29CQUNyRSxDQUFDLEVBQUUsa0VBQWtFO29CQUNyRSxDQUFDLEVBQUUsa0VBQWtFO29CQUNyRSxDQUFDLEVBQUUsa0VBQWtFO29CQUNyRSxVQUFVLEVBQUUsa0VBQWtFO2lCQUMvRTthQUNGO1NBQ0YsQ0FBQztRQUVGLE1BQU0sU0FBUyxHQUFHO1lBQ2hCLFdBQVcsRUFBRSxVQUFVO1lBQ3ZCLFdBQVcsRUFBRSxDQUFDLEVBQUUsV0FBVyxFQUFFLHVCQUF1QixFQUFFLGVBQWUsRUFBRSx1QkFBdUIsRUFBRSxDQUFDO1lBQ2pHLGVBQWUsRUFBRTtnQkFDZjtvQkFDRSxJQUFJLEVBQUUsT0FBTztvQkFDYixFQUFFLEVBQUUsTUFBTTtvQkFDVixLQUFLLEVBQUUseUJBQXlCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyx5QkFBeUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDdkY7YUFDRjtTQUNGLENBQUM7UUFDRixNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDMUUsTUFBTSxxQkFBcUIsR0FBMEI7WUFDbkQsSUFBSSxFQUFFLDZCQUFrQixDQUFDLEtBQUs7WUFDOUIsRUFBRSxFQUFFLDZCQUFrQixDQUFDLElBQUk7WUFDM0IsS0FBSyxFQUFFLHlCQUF5QixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFXO1lBQ3ZELElBQUksRUFBRSx5QkFBYyxDQUFDLFVBQVU7U0FDaEMsQ0FBQztRQUVGLElBQUksR0FBVSxDQUFDO1FBRWYsTUFBTSxDQUFDLGFBQWEsRUFBRSxLQUFLO1lBQ3pCLE1BQU0sTUFBTSxHQUFHLE1BQU0sdUJBQVksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUMvQyxHQUFHLEdBQUcsTUFBTSxnQkFBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUVyQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BDLE1BQU0sVUFBVSxHQUFHO2dCQUNqQixFQUFFLEVBQUUsa0NBQWtDO2dCQUN0QyxJQUFJLEVBQUUsTUFBTTtnQkFDWixJQUFJLEVBQUU7b0JBQ0osa0NBQWtDO29CQUNsQyxrQ0FBa0M7b0JBQ2xDLGtDQUFrQztpQkFDbkM7Z0JBQ0QsWUFBWSxFQUFFLEVBQUU7YUFDakIsQ0FBQztZQUNGLE1BQU0sR0FBRyxJQUFJLGlCQUFNLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNuRCxDQUFDLENBQUMsQ0FBQztRQUVILFFBQVEsQ0FBQyxzQkFBc0IsRUFBRSxLQUFLO1lBQ3BDLEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxLQUFLO2dCQUNqRCxNQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsU0FBUyxDQUM5Qix3QkFBd0IsQ0FBQyxNQUFNLEVBQy9CLENBQUMsd0JBQXdCLENBQUMsV0FBVyxFQUFFLHdCQUF3QixDQUFDLFlBQVksQ0FBQyxFQUM3RSxJQUFJLENBQ0wsQ0FBQztnQkFDRixNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUEsOEJBQW1CLEVBQUMsZUFBZSxFQUFFLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDcEYsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQzVELE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsYUFBYSxDQUFDO2dCQUMxQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ25ELE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDbkQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNuRCxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ25ELE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDbkQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNyRCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ3ZELE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDdkQsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN2RCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENB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QyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgZW5jcnlwdFlTaGFyZSxcbiAgY3JlYXRlQ29tYmluZWRLZXksXG4gIGNyZWF0ZVVzZXJTaWduU2hhcmUsXG4gIHNlbmRTaWduYXR1cmVTaGFyZSxcbiAgZ2V0Qml0Z29Ub1VzZXJSU2hhcmUsXG4gIGdldFR4UmVxdWVzdCxcbiAgb2ZmZXJVc2VyVG9CaXRnb1JTaGFyZSxcbiAgY3JlYXRlVXNlclRvQml0R29HU2hhcmUsXG4gIHNlbmRVc2VyVG9CaXRnb0dTaGFyZSxcbiAgcmVhZFNpZ25lZE1lc3NhZ2UsXG4gIFJlcXVlc3RUeXBlLFxuICBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgV2FsbGV0LFxuICBLZXlTaGFyZSxcbiAgRWQyNTUxOUJJUDMyLFxuICBFZGRzYSxcbiAgU2lnblNoYXJlLFxuICBDb21taXRtZW50U2hhcmVSZWNvcmQsXG4gIENvbW1pdG1lbnRUeXBlLFxuICBTaWduYXR1cmVTaGFyZVR5cGUsXG4gIFJlcXVlc3RUcmFjZXIsXG59IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgKiBhcyBvcGVucGdwIGZyb20gJ29wZW5wZ3AnO1xuaW1wb3J0IHNob3VsZCA9IHJlcXVpcmUoJ3Nob3VsZCcpO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgVGVzdEJpdEdvIH0gZnJvbSAnQGJpdGdvL3Nkay10ZXN0JztcbmltcG9ydCB7IEJpdEdvIH0gZnJvbSAnLi4vLi4vLi4vLi4vc3JjL2JpdGdvJztcbmltcG9ydCB7IG5vY2tHZXRUeFJlcXVlc3QsIG5vY2tTZW5kU2lnbmF0dXJlU2hhcmUgfSBmcm9tICcuL2hlbHBlcnMnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IG5vY2sgPSByZXF1aXJlKCdub2NrJyk7XG5cbmRlc2NyaWJlKCd0ZXN0IHRzcyBoZWxwZXIgZnVuY3Rpb25zJywgZnVuY3Rpb24gKCkge1xuICBsZXQgbXBjOiBFZGRzYTtcblxuICBsZXQgdXNlcktleVNoYXJlOiBLZXlTaGFyZTtcbiAgbGV0IGJhY2t1cEtleVNoYXJlOiBLZXlTaGFyZTtcbiAgbGV0IGJpdGdvS2V5U2hhcmU6IEtleVNoYXJlO1xuXG4gIGxldCB1c2VyS2V5O1xuICBsZXQgYmFja3VwS2V5O1xuICBsZXQgYml0Z29LZXk7XG5cbiAgbGV0IHVzZXJHcGdLZXlwYWlyOiB7IHB1YmxpY0tleTogc3RyaW5nOyBwcml2YXRlS2V5OiBzdHJpbmcgfTtcbiAgbGV0IGJhY2t1cEdwZ0tleXBhaXI6IHsgcHVibGljS2V5OiBzdHJpbmc7IHByaXZhdGVLZXk6IHN0cmluZyB9O1xuICBsZXQgYml0Z29HcGdLZXlwYWlyOiB7IHB1YmxpY0tleTogc3RyaW5nOyBwcml2YXRlS2V5OiBzdHJpbmcgfTtcblxuICBsZXQgY29tbW9uS2V5Y2hhaW46IHN0cmluZztcblxuICBiZWZvcmUoYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGhkVHJlZSA9IGF3YWl0IEVkMjU1MTlCSVAzMi5pbml0aWFsaXplKCk7XG4gICAgbXBjID0gYXdhaXQgRWRkc2EuaW5pdGlhbGl6ZShoZFRyZWUpO1xuXG4gICAgdXNlcktleVNoYXJlID0gbXBjLmtleVNoYXJlKDEsIDIsIDMpO1xuICAgIGJhY2t1cEtleVNoYXJlID0gbXBjLmtleVNoYXJlKDIsIDIsIDMpO1xuICAgIGJpdGdvS2V5U2hhcmUgPSBtcGMua2V5U2hhcmUoMywgMiwgMyk7XG5cbiAgICB1c2VyS2V5ID0gbXBjLmtleUNvbWJpbmUodXNlcktleVNoYXJlLnVTaGFyZSwgW2JhY2t1cEtleVNoYXJlLnlTaGFyZXNbMV0sIGJpdGdvS2V5U2hhcmUueVNoYXJlc1sxXV0pO1xuICAgIGJhY2t1cEtleSA9IG1wYy5rZXlDb21iaW5lKGJhY2t1cEtleVNoYXJlLnVTaGFyZSwgW3VzZXJLZXlTaGFyZS55U2hhcmVzWzJdLCBiaXRnb0tleVNoYXJlLnlTaGFyZXNbMl1dKTtcbiAgICBiaXRnb0tleSA9IG1wYy5rZXlDb21iaW5lKGJpdGdvS2V5U2hhcmUudVNoYXJlLCBbYmFja3VwS2V5U2hhcmUueVNoYXJlc1szXSwgdXNlcktleVNoYXJlLnlTaGFyZXNbM11dKTtcblxuICAgICh1c2VyS2V5LnBTaGFyZS55ICsgdXNlcktleS5wU2hhcmUuY2hhaW5jb2RlKS5zaG91bGQuZXF1YWwoYmFja3VwS2V5LnBTaGFyZS55ICsgYmFja3VwS2V5LnBTaGFyZS5jaGFpbmNvZGUpO1xuICAgICh1c2VyS2V5LnBTaGFyZS55ICsgdXNlcktleS5wU2hhcmUuY2hhaW5jb2RlKS5zaG91bGQuZXF1YWwoYml0Z29LZXkucFNoYXJlLnkgKyBiaXRnb0tleS5wU2hhcmUuY2hhaW5jb2RlKTtcbiAgICBjb21tb25LZXljaGFpbiA9IHVzZXJLZXkucFNoYXJlLnkgKyB1c2VyS2V5LnBTaGFyZS5jaGFpbmNvZGU7XG5cbiAgICB1c2VyR3BnS2V5cGFpciA9IGF3YWl0IG9wZW5wZ3AuZ2VuZXJhdGVLZXkoe1xuICAgICAgdXNlcklEczogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogJ3VzZXInLFxuICAgICAgICAgIGVtYWlsOiAndXNlckBiaXRnby5jb20nLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgICBiYWNrdXBHcGdLZXlwYWlyID0gYXdhaXQgb3BlbnBncC5nZW5lcmF0ZUtleSh7XG4gICAgICB1c2VySURzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiAnYmFja3VwJyxcbiAgICAgICAgICBlbWFpbDogJ2JhY2t1cEBiaXRnby5jb20nLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgICBiaXRnb0dwZ0tleXBhaXIgPSBhd2FpdCBvcGVucGdwLmdlbmVyYXRlS2V5KHtcbiAgICAgIHVzZXJJRHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6ICdiaXRnbycsXG4gICAgICAgICAgZW1haWw6ICdiaXRnb0BiaXRnby5jb20nLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2VuY3J5cHRZU2hhcmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBlbmNyeXB0IHkgc2hhcmUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBmb3IgKGxldCBpID0gMjsgaSA8PSAzOyBpKyspIHtcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkWVNoYXJlID0gYXdhaXQgZW5jcnlwdFlTaGFyZSh7XG4gICAgICAgICAga2V5U2hhcmU6IHVzZXJLZXlTaGFyZSxcbiAgICAgICAgICByZWNpcGllbnRJbmRleDogaSxcbiAgICAgICAgICBzZW5kZXJHcGdQcml2YXRlQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IGJpdGdvR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGRlY3J5cHRlZE1lc3NhZ2UgPSBhd2FpdCByZWFkU2lnbmVkTWVzc2FnZShcbiAgICAgICAgICBlbmNyeXB0ZWRZU2hhcmUuZW5jcnlwdGVkUHJpdmF0ZVNoYXJlLFxuICAgICAgICAgIHVzZXJHcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICBiaXRnb0dwZ0tleXBhaXIucHJpdmF0ZUtleVxuICAgICAgICApO1xuICAgICAgICBkZWNyeXB0ZWRNZXNzYWdlLnNob3VsZC5lcXVhbCh1c2VyS2V5U2hhcmUueVNoYXJlc1tpXS51ICsgdXNlcktleVNoYXJlLnlTaGFyZXNbaV0uY2hhaW5jb2RlKTtcblxuICAgICAgICBlbmNyeXB0ZWRZU2hhcmUuaS5zaG91bGQuZXF1YWwoaSk7XG4gICAgICAgIGVuY3J5cHRlZFlTaGFyZS5qLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgZW5jcnlwdGVkWVNoYXJlLnB1YmxpY1NoYXJlLnNob3VsZC5lcXVhbChcbiAgICAgICAgICB1c2VyS2V5U2hhcmUudVNoYXJlLnkgKyB1c2VyS2V5U2hhcmUueVNoYXJlc1szXS52ICsgdXNlcktleVNoYXJlLnVTaGFyZS5jaGFpbmNvZGVcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXJyb3IgZm9yIGludmFsaWQgcmVjaXBpZW50IGluZGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgZW5jcnlwdFlTaGFyZSh7XG4gICAgICAgIGtleVNoYXJlOiB1c2VyS2V5U2hhcmUsXG4gICAgICAgIHJlY2lwaWVudEluZGV4OiAxLFxuICAgICAgICBzZW5kZXJHcGdQcml2YXRlQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICAgIHJlY2lwaWVudEdwZ1B1YmxpY0FybW9yOiBiaXRnb0dwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnSW52YWxpZCByZWNpcGllbnQnKTtcbiAgICAgIGF3YWl0IGVuY3J5cHRZU2hhcmUoe1xuICAgICAgICBrZXlTaGFyZTogYmFja3VwS2V5U2hhcmUsXG4gICAgICAgIHJlY2lwaWVudEluZGV4OiAyLFxuICAgICAgICBzZW5kZXJHcGdQcml2YXRlQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICAgIHJlY2lwaWVudEdwZ1B1YmxpY0FybW9yOiBiaXRnb0dwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnSW52YWxpZCByZWNpcGllbnQnKTtcbiAgICAgIGF3YWl0IGVuY3J5cHRZU2hhcmUoe1xuICAgICAgICBrZXlTaGFyZTogYml0Z29LZXlTaGFyZSxcbiAgICAgICAgcmVjaXBpZW50SW5kZXg6IDMsXG4gICAgICAgIHNlbmRlckdwZ1ByaXZhdGVBcm1vcjogdXNlckdwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IGJpdGdvR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHJlY2lwaWVudCcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY3JlYXRlQ29tYmluZWRLZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgY29tYmluZWQgdXNlciBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnb1RvVXNlclNoYXJlID0gYXdhaXQgZW5jcnlwdFlTaGFyZSh7XG4gICAgICAgIGtleVNoYXJlOiBiaXRnb0tleVNoYXJlLFxuICAgICAgICByZWNpcGllbnRJbmRleDogMSxcbiAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgc2VuZGVyR3BnUHJpdmF0ZUFybW9yOiBiaXRnb0dwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgYmFja3VwVG9Vc2VyU2hhcmUgPSBhd2FpdCBlbmNyeXB0WVNoYXJlKHtcbiAgICAgICAga2V5U2hhcmU6IGJhY2t1cEtleVNoYXJlLFxuICAgICAgICByZWNpcGllbnRJbmRleDogMSxcbiAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgc2VuZGVyR3BnUHJpdmF0ZUFybW9yOiBiYWNrdXBHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgY29tYmluZWRVc2VyS2V5ID0gYXdhaXQgY3JlYXRlQ29tYmluZWRLZXkoe1xuICAgICAgICBrZXlTaGFyZTogdXNlcktleVNoYXJlLFxuICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgZW5jcnlwdGVkWVNoYXJlczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHlTaGFyZTogYml0Z29Ub1VzZXJTaGFyZSxcbiAgICAgICAgICAgIHJlY2lwaWVudFByaXZhdGVBcm1vcjogdXNlckdwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgICAgICAgIHNlbmRlclB1YmxpY0FybW9yOiBiaXRnb0dwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgeVNoYXJlOiBiYWNrdXBUb1VzZXJTaGFyZSxcbiAgICAgICAgICAgIHJlY2lwaWVudFByaXZhdGVBcm1vcjogdXNlckdwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgICAgICAgIHNlbmRlclB1YmxpY0FybW9yOiBiYWNrdXBHcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbWJpbmVkVXNlcktleS5jb21tb25LZXljaGFpbi5zaG91bGQuZXF1YWwoY29tbW9uS2V5Y2hhaW4pO1xuICAgICAgY29tYmluZWRVc2VyS2V5LnNpZ25pbmdNYXRlcmlhbC51U2hhcmUuc2hvdWxkLmRlZXBFcXVhbCh1c2VyS2V5U2hhcmUudVNoYXJlKTtcbiAgICAgIGNvbWJpbmVkVXNlcktleS5zaWduaW5nTWF0ZXJpYWwuYmFja3VwWVNoYXJlIS5zaG91bGQuZGVlcEVxdWFsKGJhY2t1cEtleVNoYXJlLnlTaGFyZXNbMV0pO1xuICAgICAgY29tYmluZWRVc2VyS2V5LnNpZ25pbmdNYXRlcmlhbC5iaXRnb1lTaGFyZS5zaG91bGQuZGVlcEVxdWFsKGJpdGdvS2V5U2hhcmUueVNoYXJlc1sxXSk7XG4gICAgICBzaG91bGQubm90LmV4aXN0KGNvbWJpbmVkVXNlcktleS5zaWduaW5nTWF0ZXJpYWwudXNlcllTaGFyZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBjb21iaW5lZCBiYWNrdXAga2V5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z29Ub0JhY2t1cFNoYXJlID0gYXdhaXQgZW5jcnlwdFlTaGFyZSh7XG4gICAgICAgIGtleVNoYXJlOiBiaXRnb0tleVNoYXJlLFxuICAgICAgICByZWNpcGllbnRJbmRleDogMixcbiAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IGJhY2t1cEdwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICBzZW5kZXJHcGdQcml2YXRlQXJtb3I6IGJpdGdvR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgfSk7XG4gICAgICBjb25zdCB1c2VyVG9CYWNrdXBTaGFyZSA9IGF3YWl0IGVuY3J5cHRZU2hhcmUoe1xuICAgICAgICBrZXlTaGFyZTogdXNlcktleVNoYXJlLFxuICAgICAgICByZWNpcGllbnRJbmRleDogMixcbiAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IGJhY2t1cEdwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICBzZW5kZXJHcGdQcml2YXRlQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgY29tYmluZWRCYWNrdXBLZXkgPSBhd2FpdCBjcmVhdGVDb21iaW5lZEtleSh7XG4gICAgICAgIGtleVNoYXJlOiBiYWNrdXBLZXlTaGFyZSxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgIGVuY3J5cHRlZFlTaGFyZXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB5U2hhcmU6IGJpdGdvVG9CYWNrdXBTaGFyZSxcbiAgICAgICAgICAgIHJlY2lwaWVudFByaXZhdGVBcm1vcjogYmFja3VwR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgICAgICAgc2VuZGVyUHVibGljQXJtb3I6IGJpdGdvR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB5U2hhcmU6IHVzZXJUb0JhY2t1cFNoYXJlLFxuICAgICAgICAgICAgcmVjaXBpZW50UHJpdmF0ZUFybW9yOiBiYWNrdXBHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICAgICAgICBzZW5kZXJQdWJsaWNBcm1vcjogdXNlckdwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgY29tYmluZWRCYWNrdXBLZXkuY29tbW9uS2V5Y2hhaW4uc2hvdWxkLmVxdWFsKGNvbW1vbktleWNoYWluKTtcbiAgICAgIGNvbWJpbmVkQmFja3VwS2V5LnNpZ25pbmdNYXRlcmlhbC51U2hhcmUuc2hvdWxkLmRlZXBFcXVhbChiYWNrdXBLZXlTaGFyZS51U2hhcmUpO1xuICAgICAgY29tYmluZWRCYWNrdXBLZXkuc2lnbmluZ01hdGVyaWFsLnVzZXJZU2hhcmUhLnNob3VsZC5kZWVwRXF1YWwodXNlcktleVNoYXJlLnlTaGFyZXNbMl0pO1xuICAgICAgY29tYmluZWRCYWNrdXBLZXkuc2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLnNob3VsZC5kZWVwRXF1YWwoYml0Z29LZXlTaGFyZS55U2hhcmVzWzJdKTtcbiAgICAgIHNob3VsZC5ub3QuZXhpc3QoY29tYmluZWRCYWNrdXBLZXkuc2lnbmluZ01hdGVyaWFsLmJhY2t1cFlTaGFyZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgaWYgY29tbW9uIGtleWNoYWlucyBkbyBub3QgbWF0Y2gnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnb1RvVXNlclNoYXJlID0gYXdhaXQgZW5jcnlwdFlTaGFyZSh7XG4gICAgICAgIGtleVNoYXJlOiBiaXRnb0tleVNoYXJlLFxuICAgICAgICByZWNpcGllbnRJbmRleDogMSxcbiAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgc2VuZGVyR3BnUHJpdmF0ZUFybW9yOiBiaXRnb0dwZ0tleXBhaXIucHJpdmF0ZUtleSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgYmFja3VwVG9Vc2VyU2hhcmUgPSBhd2FpdCBlbmNyeXB0WVNoYXJlKHtcbiAgICAgICAga2V5U2hhcmU6IGJhY2t1cEtleVNoYXJlLFxuICAgICAgICByZWNpcGllbnRJbmRleDogMSxcbiAgICAgICAgcmVjaXBpZW50R3BnUHVibGljQXJtb3I6IHVzZXJHcGdLZXlwYWlyLnB1YmxpY0tleSxcbiAgICAgICAgc2VuZGVyR3BnUHJpdmF0ZUFybW9yOiBiYWNrdXBHcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgY3JlYXRlQ29tYmluZWRLZXkoe1xuICAgICAgICBrZXlTaGFyZTogdXNlcktleVNoYXJlLFxuICAgICAgICBjb21tb25LZXljaGFpbjogJ25vdHRoZXJpZ2h0a2V5Y2hhaW4nLFxuICAgICAgICBlbmNyeXB0ZWRZU2hhcmVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgeVNoYXJlOiBiaXRnb1RvVXNlclNoYXJlLFxuICAgICAgICAgICAgcmVjaXBpZW50UHJpdmF0ZUFybW9yOiB1c2VyR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgICAgICAgc2VuZGVyUHVibGljQXJtb3I6IGJpdGdvR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB5U2hhcmU6IGJhY2t1cFRvVXNlclNoYXJlLFxuICAgICAgICAgICAgcmVjaXBpZW50UHJpdmF0ZUFybW9yOiB1c2VyR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgICAgICAgc2VuZGVyUHVibGljQXJtb3I6IGJhY2t1cEdwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdDb21tb24ga2V5Y2hhaW5zIGRvIG5vdCBtYXRjaCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGlmIGdwZyBrZXlzIGFyZSBtaXNtYXRjaGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z29Ub1VzZXJTaGFyZSA9IGF3YWl0IGVuY3J5cHRZU2hhcmUoe1xuICAgICAgICBrZXlTaGFyZTogYml0Z29LZXlTaGFyZSxcbiAgICAgICAgcmVjaXBpZW50SW5kZXg6IDEsXG4gICAgICAgIHJlY2lwaWVudEdwZ1B1YmxpY0FybW9yOiB1c2VyR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgIHNlbmRlckdwZ1ByaXZhdGVBcm1vcjogYml0Z29HcGdLZXlwYWlyLnByaXZhdGVLZXksXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGJhY2t1cFRvVXNlclNoYXJlID0gYXdhaXQgZW5jcnlwdFlTaGFyZSh7XG4gICAgICAgIGtleVNoYXJlOiBiYWNrdXBLZXlTaGFyZSxcbiAgICAgICAgcmVjaXBpZW50SW5kZXg6IDEsXG4gICAgICAgIHJlY2lwaWVudEdwZ1B1YmxpY0FybW9yOiB1c2VyR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgIHNlbmRlckdwZ1ByaXZhdGVBcm1vcjogYmFja3VwR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGNyZWF0ZUNvbWJpbmVkS2V5KHtcbiAgICAgICAga2V5U2hhcmU6IHVzZXJLZXlTaGFyZSxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW46ICdub3R0aGVyaWdodGtleWNoYWluJyxcbiAgICAgICAgZW5jcnlwdGVkWVNoYXJlczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHlTaGFyZTogYml0Z29Ub1VzZXJTaGFyZSxcbiAgICAgICAgICAgIHJlY2lwaWVudFByaXZhdGVBcm1vcjogYmFja3VwR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgICAgICAgc2VuZGVyUHVibGljQXJtb3I6IGJpdGdvR3BnS2V5cGFpci5wdWJsaWNLZXksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB5U2hhcmU6IGJhY2t1cFRvVXNlclNoYXJlLFxuICAgICAgICAgICAgcmVjaXBpZW50UHJpdmF0ZUFybW9yOiB1c2VyR3BnS2V5cGFpci5wcml2YXRlS2V5LFxuICAgICAgICAgICAgc2VuZGVyUHVibGljQXJtb3I6IGJhY2t1cEdwZ0tleXBhaXIucHVibGljS2V5LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFcnJvciBkZWNyeXB0aW5nIG1lc3NhZ2U6IFNlc3Npb24ga2V5IGRlY3J5cHRpb24gZmFpbGVkLicpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRWRkc2EgdHNzIHNpZ25pbmcgaGVscGVyIGZ1bmN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuXG4gICAgbGV0IHdhbGxldDogV2FsbGV0O1xuICAgIGNvbnN0IHBhdGggPSAnbS8wJztcbiAgICBjb25zdCB2YWxpZFVzZXJTaWduaW5nTWF0ZXJpYWwgPSB7XG4gICAgICB1U2hhcmU6IHtcbiAgICAgICAgaTogMSxcbiAgICAgICAgdDogMixcbiAgICAgICAgbjogMyxcbiAgICAgICAgeTogJzA5M2M4NjAzYWQ4NmM0MWQ1ZWUyNWE4MTRiODgxODViNDM1ZGQzYTljZWNjZjljOWZkNjkxYTQ2NWFjNGE4YjAnLFxuICAgICAgICBzZWVkOiAnY2E0MGM3ODk4MTMyNTBjMzM0ZGRkMmJhMTkwNTBmNmVkMjBiNWEwODg1M2NlY2E0OTIzNThmMjcxMWFkNGIxNScsXG4gICAgICAgIGNoYWluY29kZTogJzU5NmQ1NDA0YTdlYjkxOGVlNzgyNDdiOTUyZDA2NTM5NjE5ODg0MDkxZmRkOWUwZmY1YTY2NWYzNDllMzJmY2EnLFxuICAgICAgfSxcbiAgICAgIGNvbW1vbkNoYWluY29kZTogJzU5NmQ1NDA0YTdlYjkxOGVlNzgyNDdiOTUyZDA2NTM5NjE5ODg0MDkxZmRkOWUwZmY1YTY2NWYzNDllMzJmY2EnLFxuICAgICAgYml0Z29ZU2hhcmU6IHtcbiAgICAgICAgaTogMSxcbiAgICAgICAgajogMyxcbiAgICAgICAgeTogJzU5ZDgwMDBiYTVlODVmYTQwMmYzOTM4Mjk2MGU3ZDVlZGU4MmIxYjZlMjJiMTQ2YTE4YjdkZjIzOGMzYTMyMjUnLFxuICAgICAgICB2OiAnMDFlYTNmNDI1YjFhZGY4YWVjNmNmZTRmYzhmOWI5NDc1NWMzNDY1Nzk2NWYzMjM5NzY1NWRjZDc4NGYxYjUxNycsXG4gICAgICAgIHU6ICc5Y2UzMjA0YThjOTc1NzczODk2N2YzZjgxYjQ2M2Q4NzI2N2JmNmYyYzBlNWVhZjI4NDMxNjc1MzdiODcyYjBiJyxcbiAgICAgICAgY2hhaW5jb2RlOiAnZDIxZGJkOGVhZTVkNDc4OTI5MmVjZWEyZWZhNTNlMDE2NWIyNDM5ZDU3ZjUxNThlYjRkZDU3ZGMyNmI1OTIzNicsXG4gICAgICB9LFxuICAgICAgYmFja3VwWVNoYXJlOiB7XG4gICAgICAgIGk6IDEsXG4gICAgICAgIGo6IDIsXG4gICAgICAgIHk6ICdlMGFlNzUwNzc3MTU2ODZhMTIxYWNiNDFiMjlhNTViZGU0MjY5NzExNTRmNDBhNDFmYzMxN2Y3Zjc3NGE5NDI0JyxcbiAgICAgICAgdjogJ2Y3NmVmNjI5ZGZjMTVhYjVlNDUzMWU1MzJiNWQ2N2YyMTc2NjM3Y2E3NTJiMTk1ODc2YjdlMzE3MjQ1OWM5NjknLFxuICAgICAgICB1OiAnZmU2Yjg5ZmI2YWNmY2Q3MzkyYzM1YzA4NGY1OGJkZTA4NDZiODg4YzRkZjU3ZTQ2NmNhZjBhMzI3MWIwNmEwNScsXG4gICAgICAgIGNoYWluY29kZTogJzFjMzRlNWRmYmJkNGE4NzBmNDQ3OWNhYWE1ZTZhNDZlMzQzOGY5NzZhZDVhZWZkNDkwNWI4ZmU4YmNhMTEwMWUnLFxuICAgICAgfSxcbiAgICB9O1xuICAgIGNvbnN0IHZhbGlkVXNlclNpZ25TaGFyZTogU2lnblNoYXJlID0ge1xuICAgICAgeFNoYXJlOiB7XG4gICAgICAgIGk6IDEsXG4gICAgICAgIHk6ICc0ZDkzNDM5ODhlNjgxOTFhYWM5NDVhNjk2MzAzMWRkZGRlMzQ5MGY5MDIwZDA1NzFhNmU2YzZlMTVjY2EwMjk2JyxcbiAgICAgICAgdTogJzFlMTU5ZDZhMGFlM2E4ZGNjYzc0NjE1MTEzZTdjM2UyNWQzMDgwZTVlMGZmZWIwYWUwNGRkNmE5NjcyNjgxMDInLFxuICAgICAgICByOiAnYzhmNjRjYzQ4OTI2MjE2YzNmNjBlMWQ4ZmYxZTI0ZWJhMDYwZDdjMWZmMDIwZDBmYzFkNzM1ZDQ1NjRlZmQwMycsXG4gICAgICAgIFI6ICc5YmUyMjA4ZWUyOGNkNGIyNTc3YTlhNjZmNmFhYjFlZDhiMDhhMzAwOTY5ZWViOWIyMDNhNTJhYTU0ZDJjMjNjJyxcbiAgICAgIH0sXG4gICAgICByU2hhcmVzOiB7XG4gICAgICAgIDM6IHtcbiAgICAgICAgICBpOiAzLFxuICAgICAgICAgIGo6IDEsXG4gICAgICAgICAgdTogJ2Q2NzVmOTA5OWZiZWYwM2FhOWZjZGNhNDAwOTI4NmY0MzVlNTYzNjljMzc0ZDAwNDJmMDNjYzYwYjQ5ZTY5MGEnLFxuICAgICAgICAgIHY6ICczYzA5MGU4OGVkNDJkYTBkZDBiYWRlMzVjOGQ2Yjg4YmMwNTAyODQ1MzZiOThlNWIyN2QzM2ZmNDVkYTk3NTViJyxcbiAgICAgICAgICByOiAnN2YxNjIyNGRiZjViMDJhZGI2YzIxMzgwZmNiMmE4ZWUwMDMyM2RhYWU2MmNhYzM1NzVhNGQzMjhmZDIzYTkwNScsXG4gICAgICAgICAgUjogJzliZTIyMDhlZTI4Y2Q0YjI1NzdhOWE2NmY2YWFiMWVkOGIwOGEzMDA5NjllZWI5YjIwM2E1MmFhNTRkMmMyM2MnLFxuICAgICAgICAgIGNvbW1pdG1lbnQ6ICc0NDVjOGNiMWRlZTAxNjZiNmJkZDVhZDFkMGE1M2ZiZmU4NmM0ZDNhNDcwZjE4NDc0NTUzMGE4NjNlZWRmZjI4JyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIGNvbnN0IHZhbGlkVXNlclRvQml0Z29HU2hhcmUgPSB7XG4gICAgICBpOiAxLFxuICAgICAgeTogJzRkOTM0Mzk4OGU2ODE5MWFhYzk0NWE2OTYzMDMxZGRkZGUzNDkwZjkwMjBkMDU3MWE2ZTZjNmUxNWNjYTAyOTYnLFxuICAgICAgZ2FtbWE6ICdjZTg3YTAwZDE3ZTUyYjkxYmM1YmI2ZTI3NTk4M2I4NGZjMTk5OGIyYjM3ZjcxNjZjNjcxYTAxOWMzM2QzOTA1JyxcbiAgICAgIFI6ICdhYTZlNWJhZDI0YWQ0MTMxYjg3OTNkY2I5NWM3MmUwM2M1NDI2NDU2YWIwYjUyZmM5OWQ2MWQ3MTAzYzJmMDFiJyxcbiAgICB9O1xuICAgIGNvbnN0IHZhbGlkQml0Z29Ub1VzZXJTaWduU2hhcmU6IFNpZ25TaGFyZSA9IHtcbiAgICAgIHhTaGFyZToge1xuICAgICAgICBpOiAzLFxuICAgICAgICB5OiAnNGQ5MzQzOTg4ZTY4MTkxYWFjOTQ1YTY5NjMwMzFkZGRkZTM0OTBmOTAyMGQwNTcxYTZlNmM2ZTE1Y2NhMDI5NicsXG4gICAgICAgIHU6ICcxMzE1ZGJlMTgwNjk4MjViNGEyNzE4OGI4MTNlYWU3ZmYyOTE3YTYxNDQ5OWVkNTUzZTcwZDY1ZDRmYTQ4MjBiJyxcbiAgICAgICAgcjogJ2QwNTM5Mzc1ZTY1NjZmMmZlNTQwY2JhNDhjNWU1NmJkMWNkZjY4Y2ZlMWYwZDUyN2QyYjczMGZlNGU4Nzk4MDknLFxuICAgICAgICBSOiAnYzg4M2ZlMmFlOWI4ZGExNzY0Y2MzNmE1MjZjZmExYTIxZjgxZDYwNDMyMGIyMDk4NjdmOGRlOTIyM2YxZGUzMicsXG4gICAgICB9LFxuICAgICAgclNoYXJlczoge1xuICAgICAgICAxOiB7XG4gICAgICAgICAgaTogMSxcbiAgICAgICAgICBqOiAzLFxuICAgICAgICAgIHU6ICc5Y2UzMjA0YThjOTc1NzczODk2N2YzZjgxYjQ2M2Q4NzI2N2JmNmYyYzBlNWVhZjI4NDMxNjc1MzdiODcyYjBiJyxcbiAgICAgICAgICB2OiAnMDFlYTNmNDI1YjFhZGY4YWVjNmNmZTRmYzhmOWI5NDc1NWMzNDY1Nzk2NWYzMjM5NzY1NWRjZDc4NGYxYjUxNycsXG4gICAgICAgICAgcjogJzAzNzVlOGM1YTU2OTFhNzNjMjFkZjAwZDQ5ZDQyM2UzZjgzZmUwOGQ3YjVkNWFmMzNjNWM2YWE5Y2FlNTlkMGEnLFxuICAgICAgICAgIFI6ICdjODgzZmUyYWU5YjhkYTE3NjRjYzM2YTUyNmNmYTFhMjFmODFkNjA0MzIwYjIwOTg2N2Y4ZGU5MjIzZjFkZTMyJyxcbiAgICAgICAgICBjb21taXRtZW50OiAnNjJiMjFmOThiZjg4NTg0MWFkNDY5MTQ1MTkyZDRkZjA2OTdiM2Y0MmM1ODFlM2U5MjYzOTRlYWUwYjEwMWVjYicsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBjb25zdCB0eFJlcXVlc3QgPSB7XG4gICAgICB0eFJlcXVlc3RJZDogJ3JhbmRvbUlkJyxcbiAgICAgIHVuc2lnbmVkVHhzOiBbeyBzaWduYWJsZUhleDogJ01QQyBvbiBhIEZyaWRheSBuaWdodCcsIHNlcmlhbGl6ZWRUeEhleDogJ01QQyBvbiBhIEZyaWRheSBuaWdodCcgfV0sXG4gICAgICBzaWduYXR1cmVTaGFyZXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGZyb206ICdiaXRnbycsXG4gICAgICAgICAgdG86ICd1c2VyJyxcbiAgICAgICAgICBzaGFyZTogdmFsaWRCaXRnb1RvVXNlclNpZ25TaGFyZS5yU2hhcmVzWzFdLnIgKyB2YWxpZEJpdGdvVG9Vc2VyU2lnblNoYXJlLnJTaGFyZXNbMV0uUixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcbiAgICBjb25zdCBzaWduYWJsZVBheWxvYWQgPSBCdWZmZXIuZnJvbSh0eFJlcXVlc3QudW5zaWduZWRUeHNbMF0uc2lnbmFibGVIZXgpO1xuICAgIGNvbnN0IGJpdGdvVG9Vc2VyQ29tbWl0bWVudDogQ29tbWl0bWVudFNoYXJlUmVjb3JkID0ge1xuICAgICAgZnJvbTogU2lnbmF0dXJlU2hhcmVUeXBlLkJJVEdPLFxuICAgICAgdG86IFNpZ25hdHVyZVNoYXJlVHlwZS5VU0VSLFxuICAgICAgc2hhcmU6IHZhbGlkQml0Z29Ub1VzZXJTaWduU2hhcmUuclNoYXJlc1sxXS5jb21taXRtZW50ISxcbiAgICAgIHR5cGU6IENvbW1pdG1lbnRUeXBlLkNPTU1JVE1FTlQsXG4gICAgfTtcblxuICAgIGxldCBNUEM6IEVkZHNhO1xuXG4gICAgYmVmb3JlKCdpbml0aWFsaXplcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGhkVHJlZSA9IGF3YWl0IEVkMjU1MTlCSVAzMi5pbml0aWFsaXplKCk7XG4gICAgICBNUEMgPSBhd2FpdCBFZGRzYS5pbml0aWFsaXplKGhkVHJlZSk7XG5cbiAgICAgIGNvbnN0IGJhc2VDb2luID0gYml0Z28uY29pbigndHNvbCcpO1xuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgICBdLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgfTtcbiAgICAgIHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2VDb2luLCB3YWxsZXREYXRhKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdjcmVhdGVVc2VyU2lnblNoYXJlOicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byBjcmVhdGUgVXNlciBTaWduU2hhcmUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNpZ25pbmdLZXkgPSBNUEMua2V5RGVyaXZlKFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC51U2hhcmUsXG4gICAgICAgICAgW3ZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC5iaXRnb1lTaGFyZSwgdmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLmJhY2t1cFlTaGFyZV0sXG4gICAgICAgICAgcGF0aFxuICAgICAgICApO1xuICAgICAgICBjb25zdCB1c2VyU2lnblNoYXJlID0gYXdhaXQgY3JlYXRlVXNlclNpZ25TaGFyZShzaWduYWJsZVBheWxvYWQsIHNpZ25pbmdLZXkucFNoYXJlKTtcbiAgICAgICAgdXNlclNpZ25TaGFyZS5zaG91bGQuaGF2ZS5wcm9wZXJ0aWVzKFsneFNoYXJlJywgJ3JTaGFyZXMnXSk7XG4gICAgICAgIGNvbnN0IHsgeFNoYXJlLCByU2hhcmVzIH0gPSB1c2VyU2lnblNoYXJlO1xuICAgICAgICB4U2hhcmUuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2knKS5hbmQuYmUuYS5OdW1iZXIoKTtcbiAgICAgICAgeFNoYXJlLnNob3VsZC5oYXZlLnByb3BlcnR5KCd5JykuYW5kLmJlLmEuU3RyaW5nKCk7XG4gICAgICAgIHhTaGFyZS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndScpLmFuZC5iZS5hLlN0cmluZygpO1xuICAgICAgICB4U2hhcmUuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3InKS5hbmQuYmUuYS5TdHJpbmcoKTtcbiAgICAgICAgeFNoYXJlLnNob3VsZC5oYXZlLnByb3BlcnR5KCdSJykuYW5kLmJlLmEuU3RyaW5nKCk7XG4gICAgICAgIHJTaGFyZXMuc2hvdWxkLmhhdmUucHJvcGVydHkoJzMnKS5hbmQuYmUuYW4uT2JqZWN0KCk7XG4gICAgICAgIHJTaGFyZXNbM10uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2knKS5hbmQuYmUuYS5OdW1iZXIoKTtcbiAgICAgICAgclNoYXJlc1szXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaicpLmFuZC5iZS5hLk51bWJlcigpO1xuICAgICAgICByU2hhcmVzWzNdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyJykuYW5kLmJlLmEuU3RyaW5nKCk7XG4gICAgICAgIHJTaGFyZXNbM10uc2hvdWxkLmhhdmUucHJvcGVydHkoJ1InKS5hbmQuYmUuYS5TdHJpbmcoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgaWYgdGhlIFBzaGFyZSBkb2VzbnQgYmVsb25nIHRvIHRoZSBVc2VyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbnZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbCA9IEpTT04ucGFyc2UoXG4gICAgICAgICAgJ3tcInVTaGFyZVwiOntcImlcIjoyLFwidFwiOjIsXCJuXCI6MyxcInlcIjpcImUyYjg0NDkzNGI1NmYyNzhiNGE4YTM2NjVkNDNkMTRkZTgwNzMyMjQxNjIyZWM3YThiZDZjZmZjMGY3NDQ1MmFcIixcInNlZWRcIjpcIjUyNTllZTIzYTM2NDQyOTkxOWY5NjkyNDczMjNlZWUyZjRhZjU3ODY0NTdiNGFmNjdkNDIzZjg5NDRkM2E2OTFcIixcImNoYWluY29kZVwiOlwiNzQ2MGRlMTdkNzMyOTY5YzNiYzliZGRiYWMxMDU1YWZmMTY4ZmFkNTY2ODkxN2I4ZWQzZmQ5NjI4ZmM2ZTRmOFwifSxcImJpdGdvWVNoYXJlXCI6e1wiaVwiOjIsXCJqXCI6MyxcInlcIjpcIjE0MWZkNWNiYjkwMWQ0NmI4YzJjNzgzZjNkNGVlOTY4YWU5MWMzOGY3MWFiYTA1MTQ2YjNiYThiZDQzMDk1OTZcIixcInVcIjpcIjU4MWNmYWNiM2RlOTU2Y2M0MzRhMzVhM2FjOTI3ZjdkMGE0ZGFhZWY0OGE5NWMxNjJjYWRiNzg3OGVmMjI3MGJcIixcImNoYWluY29kZVwiOlwiNjdkMzMwNjMwNTI2MDZmMzQxY2FlNDA4Nzc3MDlkZTcyNWFiZGE0MWYyZGY3ZjQ3NjVlM2Y1OGNlNTAzMGUxYVwifSxcImJhY2t1cFlTaGFyZVwiOntcImlcIjoyLFwialwiOjEsXCJ5XCI6XCI5ZTY5ZTNlOTI5Nzg4OTZlODcyZDcxZmY3YTllNjNhOTYzYWIwZjU5NTgzZDRmY2JlNzlmODJjZGU5ZWE2YmY5XCIsXCJ1XCI6XCI1MmE1MzlmNzlkZjQ0OGEyZjUxMDhhNWU0MTAzNzdjYmQxNTc0YjdjM2Q5ODY0YmIzMTBlYmY3YmViMTM0NjBkXCIsXCJjaGFpbmNvZGVcIjpcImJkYTk4MGMzNGFhMDY5MTZmMjVjNGM3OTM0ZWEwOWE5MjhiZmY3NzMwYTEwMDkwMmY0ZDUzYmI5MjM2NzcxYTdcIn19J1xuICAgICAgICApO1xuICAgICAgICBjb25zdCBzaWduaW5nS2V5ID0gTVBDLmtleURlcml2ZShcbiAgICAgICAgICBpbnZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC51U2hhcmUsXG4gICAgICAgICAgW2ludmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLCBpbnZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC5iYWNrdXBZU2hhcmVdLFxuICAgICAgICAgIHBhdGhcbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgY3JlYXRlVXNlclNpZ25TaGFyZShzaWduYWJsZVBheWxvYWQsIHNpZ25pbmdLZXkucFNoYXJlKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdJbnZhbGlkIFBTaGFyZSwgUFNoYXJlIGRvZXNudCBiZWxvbmcgdG8gdGhlIFVzZXInXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzZW5kU2lnbmF0dXJlU2hhcmU6JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHNlbmQgU2lnbmF0dXJlIFNoYXJlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaWduYXR1cmVTaGFyZSA9IHsgZnJvbTogJ3VzZXInLCB0bzogJ2JpdGdvJywgc2hhcmU6ICcxMjhieXRlc3RyaW5nJyB9IGFzIFNpZ25hdHVyZVNoYXJlUmVjb3JkO1xuICAgICAgICBhd2FpdCBub2NrU2VuZFNpZ25hdHVyZVNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0LmlkKCksXG4gICAgICAgICAgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICBzaWduYXR1cmVTaGFyZSxcbiAgICAgICAgICBzaWduZXJTaGFyZTogJ3NpZ25lclNoYXJlJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgc2VuZFNpZ25hdHVyZVNoYXJlKFxuICAgICAgICAgIGJpdGdvLFxuICAgICAgICAgIHdhbGxldC5pZCgpLFxuICAgICAgICAgIHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICBzaWduYXR1cmVTaGFyZSxcbiAgICAgICAgICBSZXF1ZXN0VHlwZS50eCxcbiAgICAgICAgICAnc2lnbmVyU2hhcmUnXG4gICAgICAgICk7XG4gICAgICAgIHJlc3BvbnNlLnNob3VsZC5kZWVwRXF1YWwoc2lnbmF0dXJlU2hhcmUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCB0byBzZW5kIFNpZ25hdHVyZSBTaGFyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaW52YWxpZFNpZ25hdHVyZVNoYXJlID0geyBmcm9tOiAnYml0Z28nLCB0bzogJ3VzZXInLCBzaGFyZTogJzEyOGJ5dGVzdHJpbmcnIH0gYXMgU2lnbmF0dXJlU2hhcmVSZWNvcmQ7XG4gICAgICAgIGNvbnN0IG5vY2sgPSBhd2FpdCBub2NrU2VuZFNpZ25hdHVyZVNoYXJlKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHdhbGxldElkOiB3YWxsZXQuaWQoKSxcbiAgICAgICAgICAgIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgICBzaWduYXR1cmVTaGFyZTogaW52YWxpZFNpZ25hdHVyZVNoYXJlLFxuICAgICAgICAgICAgc2lnbmVyU2hhcmU6ICdzaWduZXJTaGFyZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICA0MDBcbiAgICAgICAgKTtcbiAgICAgICAgYXdhaXQgc2VuZFNpZ25hdHVyZVNoYXJlKFxuICAgICAgICAgIGJpdGdvLFxuICAgICAgICAgIHdhbGxldC5pZCgpLFxuICAgICAgICAgIHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICBpbnZhbGlkU2lnbmF0dXJlU2hhcmUsXG4gICAgICAgICAgUmVxdWVzdFR5cGUudHgsXG4gICAgICAgICAgJ3NpZ25lclNoYXJlJ1xuICAgICAgICApLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3NvbWUgZXJyb3InKTtcbiAgICAgICAgbm9jay5pc0RvbmUoKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdvZmZlclVzZXJUb0JpdGdvUlNoYXJlOicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byBzZW5kIFNpZ25hdHVyZSBTaGFyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlU2hhcmUgPSB7XG4gICAgICAgICAgZnJvbTogJ3VzZXInLFxuICAgICAgICAgIHRvOiAnYml0Z28nLFxuICAgICAgICAgIHNoYXJlOiB2YWxpZFVzZXJTaWduU2hhcmUuclNoYXJlc1szXS5yICsgdmFsaWRVc2VyU2lnblNoYXJlLnJTaGFyZXNbM10uUixcbiAgICAgICAgfSBhcyBTaWduYXR1cmVTaGFyZVJlY29yZDtcbiAgICAgICAgY29uc3Qgbm9jayA9IGF3YWl0IG5vY2tTZW5kU2lnbmF0dXJlU2hhcmUoe1xuICAgICAgICAgIHdhbGxldElkOiB3YWxsZXQuaWQoKSxcbiAgICAgICAgICB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICAgIHNpZ25hdHVyZVNoYXJlLFxuICAgICAgICAgIHNpZ25lclNoYXJlOiAnc2lnbmVyU2hhcmUnLFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgb2ZmZXJVc2VyVG9CaXRnb1JTaGFyZShcbiAgICAgICAgICBiaXRnbyxcbiAgICAgICAgICB3YWxsZXQuaWQoKSxcbiAgICAgICAgICB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgdmFsaWRVc2VyU2lnblNoYXJlLFxuICAgICAgICAgICdzaWduZXJTaGFyZSdcbiAgICAgICAgKS5zaG91bGQuYmUuZnVsZmlsbGVkKCk7XG4gICAgICAgIG5vY2suaXNEb25lKCkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCBpZiBubyByU2hhcmUgaXMgZm91bmQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGludmFsaWRVc2VyU2lnblNoYXJlID0gXy5jbG9uZURlZXAodmFsaWRVc2VyU2lnblNoYXJlKSBhcyBhbnk7XG4gICAgICAgIGRlbGV0ZSBpbnZhbGlkVXNlclNpZ25TaGFyZS5yU2hhcmVzWzNdO1xuICAgICAgICBhd2FpdCBvZmZlclVzZXJUb0JpdGdvUlNoYXJlKFxuICAgICAgICAgIGJpdGdvLFxuICAgICAgICAgIHdhbGxldC5pZCgpLFxuICAgICAgICAgIHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICBpbnZhbGlkVXNlclNpZ25TaGFyZSxcbiAgICAgICAgICAnc2lnbmVyU2hhcmUnXG4gICAgICAgICkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndXNlclRvQml0Z28gUlNoYXJlIG5vdCBmb3VuZCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCBpZiB0aGUgclNoYXJlIGZvdW5kIGlzIGludmFsaWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGludmFsaWRVc2VyU2lnblNoYXJlID0gXy5jbG9uZURlZXAodmFsaWRVc2VyU2lnblNoYXJlKSBhcyBhbnk7XG4gICAgICAgIGludmFsaWRVc2VyU2lnblNoYXJlLnJTaGFyZXNbM10uaSA9IDE7XG4gICAgICAgIGF3YWl0IG9mZmVyVXNlclRvQml0Z29SU2hhcmUoXG4gICAgICAgICAgYml0Z28sXG4gICAgICAgICAgd2FsbGV0LmlkKCksXG4gICAgICAgICAgdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICAgIGludmFsaWRVc2VyU2lnblNoYXJlLFxuICAgICAgICAgICdzaWduZXJTaGFyZSdcbiAgICAgICAgKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIFJTaGFyZSwgaXMgbm90IGZyb20gVXNlciB0byBCaXRnbycpO1xuXG4gICAgICAgIGNvbnN0IGludmFsaWRVc2VyU2lnblNoYXJlMiA9IF8uY2xvbmVEZWVwKHZhbGlkVXNlclNpZ25TaGFyZSkgYXMgYW55O1xuICAgICAgICBpbnZhbGlkVXNlclNpZ25TaGFyZTIuclNoYXJlc1szXS5qID0gMztcbiAgICAgICAgYXdhaXQgb2ZmZXJVc2VyVG9CaXRnb1JTaGFyZShcbiAgICAgICAgICBiaXRnbyxcbiAgICAgICAgICB3YWxsZXQuaWQoKSxcbiAgICAgICAgICB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgaW52YWxpZFVzZXJTaWduU2hhcmUyLFxuICAgICAgICAgICdzaWduZXJTaGFyZSdcbiAgICAgICAgKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIFJTaGFyZSwgaXMgbm90IGZyb20gVXNlciB0byBCaXRnbycpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgY2FsbCBzZXRSZXF1ZXN0VHJhY2VyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaWduYXR1cmVTaGFyZSA9IHtcbiAgICAgICAgICBmcm9tOiAndXNlcicsXG4gICAgICAgICAgdG86ICdiaXRnbycsXG4gICAgICAgICAgc2hhcmU6IHZhbGlkVXNlclNpZ25TaGFyZS5yU2hhcmVzWzNdLnIgKyB2YWxpZFVzZXJTaWduU2hhcmUuclNoYXJlc1szXS5SLFxuICAgICAgICB9IGFzIFNpZ25hdHVyZVNoYXJlUmVjb3JkO1xuICAgICAgICBjb25zdCBub2NrID0gYXdhaXQgbm9ja1NlbmRTaWduYXR1cmVTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLFxuICAgICAgICAgIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgc2lnbmF0dXJlU2hhcmUsXG4gICAgICAgICAgc2lnbmVyU2hhcmU6ICdzaWduZXJTaGFyZScsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG4gICAgICAgIGNvbnN0IHNldFJlcXVlc3RUcmFjZXJTcHkgPSBzaW5vbi5zcHkoYml0Z28sICdzZXRSZXF1ZXN0VHJhY2VyJyk7XG4gICAgICAgIHNldFJlcXVlc3RUcmFjZXJTcHkud2l0aEFyZ3MocmVxSWQpO1xuICAgICAgICBhd2FpdCBvZmZlclVzZXJUb0JpdGdvUlNoYXJlKFxuICAgICAgICAgIGJpdGdvLFxuICAgICAgICAgIHdhbGxldC5pZCgpLFxuICAgICAgICAgIHR4UmVxdWVzdC50eFJlcXVlc3RJZCxcbiAgICAgICAgICB2YWxpZFVzZXJTaWduU2hhcmUsXG4gICAgICAgICAgJ3NpZ25lclNoYXJlJyxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgcmVxSWRcbiAgICAgICAgKS5zaG91bGQuYmUuZnVsZmlsbGVkKCk7XG4gICAgICAgIG5vY2suaXNEb25lKCkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShzZXRSZXF1ZXN0VHJhY2VyU3B5KTtcbiAgICAgICAgc2V0UmVxdWVzdFRyYWNlclNweS5yZXN0b3JlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdnZXRCaXRnb1RvVXNlclJTaGFyZTonLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gZ2V0IHRoZSBCaXRnbyB0byBVc2VyIFJTaGFyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB7IHR4UmVxdWVzdHM6IFt0eFJlcXVlc3RdIH07XG4gICAgICAgIGNvbnN0IG5vY2sgPSBhd2FpdCBub2NrR2V0VHhSZXF1ZXN0KHsgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLCB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLCByZXNwb25zZSB9KTtcbiAgICAgICAgY29uc3QgYml0Z29Ub1VzZXJSU2hhcmUgPSBhd2FpdCBnZXRCaXRnb1RvVXNlclJTaGFyZShiaXRnbywgd2FsbGV0LmlkKCksIHR4UmVxdWVzdC50eFJlcXVlc3RJZCk7XG4gICAgICAgIGJpdGdvVG9Vc2VyUlNoYXJlLnNob3VsZC5kZWVwRXF1YWwodHhSZXF1ZXN0LnNpZ25hdHVyZVNoYXJlc1swXSk7XG4gICAgICAgIG5vY2suaXNEb25lKCkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCBpZiB0aGVyZSBpcyBubyBiaXRnbyB0byB1c2VyIFJTaGFyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaW52YWxpZFR4UmVxdWVzdCA9IF8uY2xvbmVEZWVwKHR4UmVxdWVzdCk7XG4gICAgICAgIGludmFsaWRUeFJlcXVlc3Quc2lnbmF0dXJlU2hhcmVzWzBdLnRvID0gJ2JpdGdvJztcbiAgICAgICAgaW52YWxpZFR4UmVxdWVzdC5zaWduYXR1cmVTaGFyZXNbMF0uZnJvbSA9ICd1c2VyJztcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB7IHR4UmVxdWVzdHM6IFtpbnZhbGlkVHhSZXF1ZXN0XSB9O1xuICAgICAgICBjb25zdCBub2NrID0gYXdhaXQgbm9ja0dldFR4UmVxdWVzdCh7IHdhbGxldElkOiB3YWxsZXQuaWQoKSwgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCwgcmVzcG9uc2UgfSk7XG4gICAgICAgIGF3YWl0IGdldEJpdGdvVG9Vc2VyUlNoYXJlKGJpdGdvLCB3YWxsZXQuaWQoKSwgdHhSZXF1ZXN0LnR4UmVxdWVzdElkKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdCaXRnbyB0byBVc2VyIFJTaGFyZSBub3QgZm91bmQgZm9yIGlkOiAnICsgdHhSZXF1ZXN0LnR4UmVxdWVzdElkXG4gICAgICAgICk7XG4gICAgICAgIG5vY2suaXNEb25lKCkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCBpZiB0aGVyZSBpcyBubyBzaWduYXR1cmVzU2hhcmVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbnZhbGlkVHhSZXF1ZXN0ID0gXy5jbG9uZURlZXAodHhSZXF1ZXN0KTtcbiAgICAgICAgaW52YWxpZFR4UmVxdWVzdC5zaWduYXR1cmVTaGFyZXMgPSBbXTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB7IHR4UmVxdWVzdHM6IFtpbnZhbGlkVHhSZXF1ZXN0XSB9O1xuICAgICAgICBjb25zdCBub2NrID0gYXdhaXQgbm9ja0dldFR4UmVxdWVzdCh7IHdhbGxldElkOiB3YWxsZXQuaWQoKSwgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCwgcmVzcG9uc2UgfSk7XG4gICAgICAgIGF3YWl0IGdldEJpdGdvVG9Vc2VyUlNoYXJlKGJpdGdvLCB3YWxsZXQuaWQoKSwgdHhSZXF1ZXN0LnR4UmVxdWVzdElkKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdObyBzaWduYXR1cmVzIHNoYXJlcyBmb3VuZCBmb3IgaWQ6ICcgKyB0eFJlcXVlc3QudHhSZXF1ZXN0SWRcbiAgICAgICAgKTtcbiAgICAgICAgbm9jay5pc0RvbmUoKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBjYWxsIHNldFJlcXVlc3RUcmFjZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0geyB0eFJlcXVlc3RzOiBbdHhSZXF1ZXN0XSB9O1xuICAgICAgICBjb25zdCBub2NrID0gYXdhaXQgbm9ja0dldFR4UmVxdWVzdCh7IHdhbGxldElkOiB3YWxsZXQuaWQoKSwgdHhSZXF1ZXN0SWQ6IHR4UmVxdWVzdC50eFJlcXVlc3RJZCwgcmVzcG9uc2UgfSk7XG4gICAgICAgIGNvbnN0IHJlcUlkID0gbmV3IFJlcXVlc3RUcmFjZXIoKTtcbiAgICAgICAgY29uc3Qgc2V0UmVxdWVzdFRyYWNlclNweSA9IHNpbm9uLnNweShiaXRnbywgJ3NldFJlcXVlc3RUcmFjZXInKTtcbiAgICAgICAgc2V0UmVxdWVzdFRyYWNlclNweS53aXRoQXJncyhyZXFJZCk7XG4gICAgICAgIGNvbnN0IGJpdGdvVG9Vc2VyUlNoYXJlID0gYXdhaXQgZ2V0Qml0Z29Ub1VzZXJSU2hhcmUoYml0Z28sIHdhbGxldC5pZCgpLCB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsIHJlcUlkKTtcbiAgICAgICAgYml0Z29Ub1VzZXJSU2hhcmUuc2hvdWxkLmRlZXBFcXVhbCh0eFJlcXVlc3Quc2lnbmF0dXJlU2hhcmVzWzBdKTtcbiAgICAgICAgbm9jay5pc0RvbmUoKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKHNldFJlcXVlc3RUcmFjZXJTcHkpO1xuICAgICAgICBzZXRSZXF1ZXN0VHJhY2VyU3B5LnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3NlbmRVc2VyVG9CaXRnb0dTaGFyZTonLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gc2VuZCBVc2VyIHRvIEJpdGdvIEdTaGFyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlU2hhcmUgPSB7XG4gICAgICAgICAgZnJvbTogJ3VzZXInLFxuICAgICAgICAgIHRvOiAnYml0Z28nLFxuICAgICAgICAgIHNoYXJlOiB2YWxpZFVzZXJUb0JpdGdvR1NoYXJlLlIgKyB2YWxpZFVzZXJUb0JpdGdvR1NoYXJlLmdhbW1hLFxuICAgICAgICB9IGFzIFNpZ25hdHVyZVNoYXJlUmVjb3JkO1xuICAgICAgICBjb25zdCBub2NrID0gYXdhaXQgbm9ja1NlbmRTaWduYXR1cmVTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLFxuICAgICAgICAgIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgc2lnbmF0dXJlU2hhcmUsXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBzZW5kVXNlclRvQml0Z29HU2hhcmUoXG4gICAgICAgICAgYml0Z28sXG4gICAgICAgICAgd2FsbGV0LmlkKCksXG4gICAgICAgICAgdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICAgIHZhbGlkVXNlclRvQml0Z29HU2hhcmVcbiAgICAgICAgKS5zaG91bGQuYmUuZnVsZmlsbGVkKCk7XG4gICAgICAgIG5vY2suaXNEb25lKCkuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCB3aGVuIHRoZSBHU2hhcmUgaXMgbm90IGZyb20gdGhlIFVzZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGludmFsaWRVc2VyVG9CaXRnb0dTaGFyZSA9IF8uY2xvbmVEZWVwKHZhbGlkVXNlclRvQml0Z29HU2hhcmUpO1xuICAgICAgICBpbnZhbGlkVXNlclRvQml0Z29HU2hhcmUuaSA9IDM7XG4gICAgICAgIGF3YWl0IHNlbmRVc2VyVG9CaXRnb0dTaGFyZShcbiAgICAgICAgICBiaXRnbyxcbiAgICAgICAgICB3YWxsZXQuaWQoKSxcbiAgICAgICAgICB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgaW52YWxpZFVzZXJUb0JpdGdvR1NoYXJlXG4gICAgICAgICkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnSW52YWxpZCBHU2hhcmUsIGRvZXNudCBiZWxvbmcgdG8gdGhlIFVzZXInKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNhbGwgc2V0UmVxdWVzdFRyYWNlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlU2hhcmUgPSB7XG4gICAgICAgICAgZnJvbTogJ3VzZXInLFxuICAgICAgICAgIHRvOiAnYml0Z28nLFxuICAgICAgICAgIHNoYXJlOiB2YWxpZFVzZXJUb0JpdGdvR1NoYXJlLlIgKyB2YWxpZFVzZXJUb0JpdGdvR1NoYXJlLmdhbW1hLFxuICAgICAgICB9IGFzIFNpZ25hdHVyZVNoYXJlUmVjb3JkO1xuICAgICAgICBjb25zdCBub2NrID0gYXdhaXQgbm9ja1NlbmRTaWduYXR1cmVTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLFxuICAgICAgICAgIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsXG4gICAgICAgICAgc2lnbmF0dXJlU2hhcmUsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByZXFJZCA9IG5ldyBSZXF1ZXN0VHJhY2VyKCk7XG4gICAgICAgIGNvbnN0IHNldFJlcXVlc3RUcmFjZXJTcHkgPSBzaW5vbi5zcHkoYml0Z28sICdzZXRSZXF1ZXN0VHJhY2VyJyk7XG4gICAgICAgIHNldFJlcXVlc3RUcmFjZXJTcHkud2l0aEFyZ3MocmVxSWQpO1xuICAgICAgICBhd2FpdCBzZW5kVXNlclRvQml0Z29HU2hhcmUoXG4gICAgICAgICAgYml0Z28sXG4gICAgICAgICAgd2FsbGV0LmlkKCksXG4gICAgICAgICAgdHhSZXF1ZXN0LnR4UmVxdWVzdElkLFxuICAgICAgICAgIHZhbGlkVXNlclRvQml0Z29HU2hhcmUsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHJlcUlkXG4gICAgICAgICkuc2hvdWxkLmJlLmZ1bGZpbGxlZCgpO1xuICAgICAgICBub2NrLmlzRG9uZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2Uoc2V0UmVxdWVzdFRyYWNlclNweSk7XG4gICAgICAgIHNldFJlcXVlc3RUcmFjZXJTcHkucmVzdG9yZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnZ2V0VHhSZXF1ZXN0OicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byBnZXQgdHhSZXF1ZXN0IGJ5IGlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IHsgdHhSZXF1ZXN0czogW3R4UmVxdWVzdF0gfTtcbiAgICAgICAgY29uc3Qgbm9jayA9IGF3YWl0IG5vY2tHZXRUeFJlcXVlc3QoeyB3YWxsZXRJZDogd2FsbGV0LmlkKCksIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsIHJlc3BvbnNlIH0pO1xuICAgICAgICBjb25zdCB0eFJlcSA9IGF3YWl0IGdldFR4UmVxdWVzdChiaXRnbywgd2FsbGV0LmlkKCksIHR4UmVxdWVzdC50eFJlcXVlc3RJZCk7XG4gICAgICAgIHR4UmVxLnNob3VsZC5kZWVwRXF1YWwodHhSZXF1ZXN0KTtcbiAgICAgICAgbm9jay5pc0RvbmUoKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIGlmIHRoZXJlIGFyZSBubyB0eFJlcXVlc3RzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IHsgdHhSZXF1ZXN0czogW10gfTtcbiAgICAgICAgY29uc3Qgbm9jayA9IGF3YWl0IG5vY2tHZXRUeFJlcXVlc3QoeyB3YWxsZXRJZDogd2FsbGV0LmlkKCksIHR4UmVxdWVzdElkOiB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsIHJlc3BvbnNlIH0pO1xuICAgICAgICBhd2FpdCBnZXRUeFJlcXVlc3QoYml0Z28sIHdhbGxldC5pZCgpLCB0eFJlcXVlc3QudHhSZXF1ZXN0SWQpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ1VuYWJsZSB0byBmaW5kIFR4UmVxdWVzdCB3aXRoIGlkIHJhbmRvbUlkJ1xuICAgICAgICApO1xuICAgICAgICBub2NrLmlzRG9uZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGNhbGwgc2V0UmVxdWVzdFRyYWNlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB7IHR4UmVxdWVzdHM6IFt0eFJlcXVlc3RdIH07XG4gICAgICAgIGNvbnN0IG5vY2sgPSBhd2FpdCBub2NrR2V0VHhSZXF1ZXN0KHsgd2FsbGV0SWQ6IHdhbGxldC5pZCgpLCB0eFJlcXVlc3RJZDogdHhSZXF1ZXN0LnR4UmVxdWVzdElkLCByZXNwb25zZSB9KTtcbiAgICAgICAgY29uc3QgcmVxSWQgPSBuZXcgUmVxdWVzdFRyYWNlcigpO1xuICAgICAgICBjb25zdCBzZXRSZXF1ZXN0VHJhY2VyU3B5ID0gc2lub24uc3B5KGJpdGdvLCAnc2V0UmVxdWVzdFRyYWNlcicpO1xuICAgICAgICBzZXRSZXF1ZXN0VHJhY2VyU3B5LndpdGhBcmdzKHJlcUlkKTtcbiAgICAgICAgY29uc3QgdHhSZXEgPSBhd2FpdCBnZXRUeFJlcXVlc3QoYml0Z28sIHdhbGxldC5pZCgpLCB0eFJlcXVlc3QudHhSZXF1ZXN0SWQsIHJlcUlkKTtcbiAgICAgICAgdHhSZXEuc2hvdWxkLmRlZXBFcXVhbCh0eFJlcXVlc3QpO1xuICAgICAgICBub2NrLmlzRG9uZSgpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2Uoc2V0UmVxdWVzdFRyYWNlclNweSk7XG4gICAgICAgIHNldFJlcXVlc3RUcmFjZXJTcHkucmVzdG9yZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnY3JlYXRlVXNlclRvQml0R29HU2hhcmU6JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIGNyZWF0ZSBhIFVzZXJUb0JpdEdvIEdTaGFyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdXNlclRvQml0Z29HU2hhcmUgPSBhd2FpdCBjcmVhdGVVc2VyVG9CaXRHb0dTaGFyZShcbiAgICAgICAgICB2YWxpZFVzZXJTaWduU2hhcmUsXG4gICAgICAgICAgdHhSZXF1ZXN0LnNpZ25hdHVyZVNoYXJlc1swXSBhcyBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgICAgICAgICB2YWxpZFVzZXJTaWduaW5nTWF0ZXJpYWwuYmFja3VwWVNoYXJlLFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC5iaXRnb1lTaGFyZSxcbiAgICAgICAgICBzaWduYWJsZVBheWxvYWQsXG4gICAgICAgICAgYml0Z29Ub1VzZXJDb21taXRtZW50XG4gICAgICAgICk7XG4gICAgICAgIHVzZXJUb0JpdGdvR1NoYXJlLnNob3VsZC5kZWVwRXF1YWwodmFsaWRVc2VyVG9CaXRnb0dTaGFyZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIHdoZW4gWFNoYXJlIGRvZXNudCBiZWxvbmcgdG8gdGhlIHVzZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGludmFsaWRVc2VyU2lnblNoYXJlID0gXy5jbG9uZURlZXAodmFsaWRVc2VyU2lnblNoYXJlKTtcbiAgICAgICAgaW52YWxpZFVzZXJTaWduU2hhcmUueFNoYXJlLmkgPSAzO1xuICAgICAgICBhd2FpdCBjcmVhdGVVc2VyVG9CaXRHb0dTaGFyZShcbiAgICAgICAgICBpbnZhbGlkVXNlclNpZ25TaGFyZSxcbiAgICAgICAgICB0eFJlcXVlc3Quc2lnbmF0dXJlU2hhcmVzWzBdIGFzIFNpZ25hdHVyZVNoYXJlUmVjb3JkLFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC5iYWNrdXBZU2hhcmUsXG4gICAgICAgICAgdmFsaWRVc2VyU2lnbmluZ01hdGVyaWFsLmJpdGdvWVNoYXJlLFxuICAgICAgICAgIHNpZ25hYmxlUGF5bG9hZCxcbiAgICAgICAgICBiaXRnb1RvVXNlckNvbW1pdG1lbnRcbiAgICAgICAgKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIFhTaGFyZSwgZG9lc250IGJlbG9uZyB0byB0aGUgVXNlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCB3aGVuIGNvbW1pdG1lbnQgaXMgaW52YWxpZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaW52YWxpZEJpdGdvVG9Vc2VyQ29tbWl0bWVudCA9IF8uY2xvbmVEZWVwKGJpdGdvVG9Vc2VyQ29tbWl0bWVudCk7XG4gICAgICAgIGludmFsaWRCaXRnb1RvVXNlckNvbW1pdG1lbnQuc2hhcmUgPSAnZGVhZGJlZWYnO1xuICAgICAgICBhd2FpdCBjcmVhdGVVc2VyVG9CaXRHb0dTaGFyZShcbiAgICAgICAgICB2YWxpZFVzZXJTaWduU2hhcmUsXG4gICAgICAgICAgdHhSZXF1ZXN0LnNpZ25hdHVyZVNoYXJlc1swXSBhcyBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgICAgICAgICB2YWxpZFVzZXJTaWduaW5nTWF0ZXJpYWwuYmFja3VwWVNoYXJlLFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC5iaXRnb1lTaGFyZSxcbiAgICAgICAgICBzaWduYWJsZVBheWxvYWQsXG4gICAgICAgICAgaW52YWxpZEJpdGdvVG9Vc2VyQ29tbWl0bWVudFxuICAgICAgICApLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0NvdWxkIG5vdCB2ZXJpZnkgb3RoZXIgcGxheWVyIHNoYXJlJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBmYWlsIHdoZW4gUlNoYXJlIGRvZXNudCBiZWxvbmcgdG8gQml0Z28nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGludmFsaWRCaXRnb1JTaGFyZSA9IF8uY2xvbmVEZWVwKHR4UmVxdWVzdC5zaWduYXR1cmVTaGFyZXNbMF0pO1xuICAgICAgICBpbnZhbGlkQml0Z29SU2hhcmUuZnJvbSA9ICd1c2VyJztcbiAgICAgICAgYXdhaXQgY3JlYXRlVXNlclRvQml0R29HU2hhcmUoXG4gICAgICAgICAgdmFsaWRVc2VyU2lnblNoYXJlLFxuICAgICAgICAgIGludmFsaWRCaXRnb1JTaGFyZSBhcyBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgICAgICAgICB2YWxpZFVzZXJTaWduaW5nTWF0ZXJpYWwuYmFja3VwWVNoYXJlLFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC5iaXRnb1lTaGFyZSxcbiAgICAgICAgICBzaWduYWJsZVBheWxvYWQsXG4gICAgICAgICAgYml0Z29Ub1VzZXJDb21taXRtZW50XG4gICAgICAgICkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnSW52YWxpZCBSU2hhcmUsIGlzIG5vdCBmcm9tIEJpdGdvIHRvIFVzZXInKTtcblxuICAgICAgICBjb25zdCBpbnZhbGlkQml0Z29SU2hhcmUyID0gXy5jbG9uZURlZXAodHhSZXF1ZXN0LnNpZ25hdHVyZVNoYXJlc1swXSk7XG4gICAgICAgIGludmFsaWRCaXRnb1JTaGFyZTIudG8gPSAnYml0Z28nO1xuICAgICAgICBhd2FpdCBjcmVhdGVVc2VyVG9CaXRHb0dTaGFyZShcbiAgICAgICAgICB2YWxpZFVzZXJTaWduU2hhcmUsXG4gICAgICAgICAgaW52YWxpZEJpdGdvUlNoYXJlMiBhcyBTaWduYXR1cmVTaGFyZVJlY29yZCxcbiAgICAgICAgICB2YWxpZFVzZXJTaWduaW5nTWF0ZXJpYWwuYmFja3VwWVNoYXJlLFxuICAgICAgICAgIHZhbGlkVXNlclNpZ25pbmdNYXRlcmlhbC5iaXRnb1lTaGFyZSxcbiAgICAgICAgICBzaWduYWJsZVBheWxvYWQsXG4gICAgICAgICAgYml0Z29Ub1VzZXJDb21taXRtZW50XG4gICAgICAgICkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnSW52YWxpZCBSU2hhcmUsIGlzIG5vdCBmcm9tIEJpdGdvIHRvIFVzZXInKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19