PHP WebShell
Текущая директория: /opt/BitGoJS/modules/bitgo/dist/test/v2/unit/internal/tssUtils/ecdsaMPCv2
Просмотр файла: createKeychains.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const nock = require("nock");
const openpgp = require("openpgp");
const crypto = require("crypto");
const sdk_test_1 = require("@bitgo/sdk-test");
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
const public_types_1 = require("@bitgo/public-types");
const src_1 = require("../../../../../../src");
const v1Fixtures = require("./fixtures/mpcv1KeyShares");
describe('TSS Ecdsa MPCv2 Utils:', async function () {
const coinName = 'hteth';
const walletId = '5b34252f1bf349930e34020a00000000';
const enterpriseId = '6449153a6f6bc20006d66771cdbe15d3';
let storedUserCommitment2;
let storedBackupCommitment2;
let storedBitgoCommitment2;
let bgUrl;
let tssUtils;
let wallet;
let bitgo;
let baseCoin;
let bitGoGgpKey;
let constants;
let bitgoGpgPrvKey;
let userGpgPubKey;
let backupGpgPubKey;
let bitgoGpgPubKey;
beforeEach(async function () {
nock.cleanAll();
await nockGetBitgoPublicKeyBasedOnFeatureFlags(coinName, enterpriseId, bitGoGgpKey);
nock(bgUrl).get('/api/v1/client/constants').times(16).reply(200, { ttl: 3600, constants });
});
before(async function () {
bitGoGgpKey = await openpgp.generateKey({
userIDs: [
{
name: 'bitgo',
email: 'bitgo@test.com',
},
],
curve: 'secp256k1',
});
constants = {
mpc: {
bitgoPublicKey: bitGoGgpKey.publicKey,
bitgoMPCv2PublicKey: bitGoGgpKey.publicKey,
},
};
bitgoGpgPubKey = {
partyId: 2,
gpgKey: bitGoGgpKey.publicKey,
};
bitgoGpgPrvKey = {
partyId: 2,
gpgKey: bitGoGgpKey.privateKey,
};
bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
bitgo.initializeTestVars();
baseCoin = bitgo.coin(coinName);
bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
const walletData = {
id: walletId,
enterprise: enterpriseId,
coin: coinName,
coinSpecific: {},
multisigType: 'tss',
};
wallet = new sdk_core_1.Wallet(bitgo, baseCoin, walletData);
tssUtils = new sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils(bitgo, baseCoin, wallet);
});
after(function () {
nock.cleanAll();
});
describe('Retrofit MPCv1 to MPCv2 keys', async function () {
it('should generate TSS MPCv2 keys from MPCv1 keys and sign a message', async function () {
const retrofitData = tssUtils.getMpcV2RetrofitDataFromMpcV1Keys({
mpcv1UserKeyShare: JSON.stringify(v1Fixtures.mockUserSigningMaterial),
mpcv1BackupKeyShare: JSON.stringify(v1Fixtures.mockBackupSigningMaterial),
});
const bitgoRetrofitData = {
xiList: retrofitData.mpcv2UserKeyShare.xiList,
xShare: v1Fixtures.mockBitGoShareSigningMaterial.xShare,
};
const [user, backup, bitgo] = await sdk_lib_mpc_1.DklsUtils.generateDKGKeyShares(retrofitData.mpcv2UserKeyShare, retrofitData.mpcv2BackupKeyShare, bitgoRetrofitData);
assert.ok(bitgo.getKeyShare());
const messageToSign = crypto.createHash('sha256').update(Buffer.from('ffff', 'hex')).digest();
const derivationPath = 'm/999/988/0/0';
const signature = await sdk_lib_mpc_1.DklsUtils.executeTillRound(5, new sdk_lib_mpc_1.DklsDsg.Dsg(user.getKeyShare(), 0, derivationPath, messageToSign), new sdk_lib_mpc_1.DklsDsg.Dsg(backup.getKeyShare(), 1, derivationPath, messageToSign));
const convertedSignature = sdk_lib_mpc_1.DklsUtils.verifyAndConvertDklsSignature(Buffer.from('ffff', 'hex'), signature, v1Fixtures.mockBitGoShareSigningMaterial.xShare.y + v1Fixtures.mockBitGoShareSigningMaterial.xShare.chaincode, derivationPath);
assert.ok(convertedSignature);
convertedSignature.split(':').length.should.equal(4);
});
});
describe('TSS key chains', async function () {
it('should generate TSS MPCv2 keys', async function () {
const bitgoSession = new sdk_lib_mpc_1.DklsDkg.Dkg(3, 2, 2);
const round1Nock = await nockKeyGenRound1(bitgoSession, 1);
const round2Nock = await nockKeyGenRound2(bitgoSession, 1);
const round3Nock = await nockKeyGenRound3(bitgoSession, 1);
const addKeyNock = await nockAddKeyChain(coinName, 3);
const params = {
passphrase: 'test',
enterprise: enterpriseId,
originalPasscodeEncryptionCode: '123456',
};
const { userKeychain, backupKeychain, bitgoKeychain } = await tssUtils.createKeychains(params);
assert.ok(round1Nock.isDone());
assert.ok(round2Nock.isDone());
assert.ok(round3Nock.isDone());
assert.ok(addKeyNock.isDone());
assert.ok(userKeychain);
assert.equal(userKeychain.source, 'user');
assert.ok(userKeychain.commonKeychain);
assert.ok(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.validateCommonKeychainPublicKey(userKeychain.commonKeychain));
assert.ok(userKeychain.encryptedPrv);
assert.ok(bitgo.decrypt({ input: userKeychain.encryptedPrv, password: params.passphrase }));
assert.ok(backupKeychain);
assert.equal(backupKeychain.source, 'backup');
assert.ok(backupKeychain.commonKeychain);
assert.ok(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.validateCommonKeychainPublicKey(backupKeychain.commonKeychain));
assert.ok(backupKeychain.encryptedPrv);
assert.ok(bitgo.decrypt({ input: backupKeychain.encryptedPrv, password: params.passphrase }));
assert.ok(bitgoKeychain);
assert.equal(bitgoKeychain.source, 'bitgo');
});
it('should generate TSS MPCv2 keys for retrofit', async function () {
const xiList = [
Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(1), 32)),
Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(2), 32)),
Array.from((0, sdk_lib_mpc_1.bigIntToBufferBE)(BigInt(3), 32)),
];
const bitgoRetrofitData = {
xiList,
xShare: v1Fixtures.mockBitGoShareSigningMaterial.xShare,
};
const bitgoSession = new sdk_lib_mpc_1.DklsDkg.Dkg(3, 2, sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BITGO, undefined, bitgoRetrofitData);
const round1Nock = await nockKeyGenRound1(bitgoSession, 1);
const round2Nock = await nockKeyGenRound2(bitgoSession, 1);
const round3Nock = await nockKeyGenRound3(bitgoSession, 1);
const addKeyNock = await nockAddKeyChain(coinName, 3);
const params = {
passphrase: 'test',
enterprise: enterpriseId,
originalPasscodeEncryptionCode: '123456',
retrofit: {
decryptedUserKey: JSON.stringify(v1Fixtures.mockUserSigningMaterial),
decryptedBackupKey: JSON.stringify(v1Fixtures.mockBackupSigningMaterial),
walletId: '123',
},
};
const { userKeychain, backupKeychain, bitgoKeychain } = await tssUtils.createKeychains(params);
assert.ok(round1Nock.isDone());
assert.ok(round2Nock.isDone());
assert.ok(round3Nock.isDone());
assert.ok(addKeyNock.isDone());
assert.ok(userKeychain);
assert.equal(userKeychain.source, 'user');
assert.ok(userKeychain.commonKeychain);
assert.ok(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.validateCommonKeychainPublicKey(userKeychain.commonKeychain));
assert.ok(userKeychain.encryptedPrv);
assert.ok(bitgo.decrypt({ input: userKeychain.encryptedPrv, password: params.passphrase }));
assert.ok(backupKeychain);
assert.equal(backupKeychain.source, 'backup');
assert.ok(backupKeychain.commonKeychain);
assert.ok(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.validateCommonKeychainPublicKey(backupKeychain.commonKeychain));
assert.ok(backupKeychain.encryptedPrv);
assert.ok(bitgo.decrypt({ input: backupKeychain.encryptedPrv, password: params.passphrase }));
assert.ok(bitgoKeychain);
assert.equal(bitgoKeychain.source, 'bitgo');
});
it('should create TSS key chains', async function () {
const nockPromises = [
nockKeychain({
coin: coinName,
keyChain: { id: '1', pub: '1', type: 'tss', reducedEncryptedPrv: '' },
source: 'user',
}),
nockKeychain({
coin: coinName,
keyChain: { id: '2', pub: '2', type: 'tss', reducedEncryptedPrv: '' },
source: 'backup',
}),
nockKeychain({
coin: coinName,
keyChain: { id: '3', pub: '3', type: 'tss', reducedEncryptedPrv: '' },
source: 'bitgo',
}),
];
const [nockedUserKeychain, nockedBackupKeychain, nockedBitGoKeychain] = await Promise.all(nockPromises);
const bitgoKeychainPromise = tssUtils.createParticipantKeychain(sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BITGO, 'test');
const usersKeychainPromise = tssUtils.createParticipantKeychain(sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.USER, 'test', Buffer.from('test'), Buffer.from('test'), 'passphrase', 'test');
const backupKeychainPromise = tssUtils.createParticipantKeychain(sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BACKUP, 'test', Buffer.from('test'), Buffer.from('test'), 'passphrase', 'test');
const [userKeychain, backupKeychain, bitgoKeychain] = await Promise.all([
usersKeychainPromise,
backupKeychainPromise,
bitgoKeychainPromise,
]);
({ ...userKeychain, reducedEncryptedPrv: '' }).should.deepEqual(nockedUserKeychain);
({ ...backupKeychain, reducedEncryptedPrv: '' }).should.deepEqual(nockedBackupKeychain);
({ ...bitgoKeychain, reducedEncryptedPrv: '' }).should.deepEqual(nockedBitGoKeychain);
});
it('should create TSS MPCv2 key chains with OVCs', async function () {
const MPCv2SMCUtils = new sdk_core_1.ECDSAUtils.MPCv2SMCUtils(bitgo, baseCoin);
const bitgoSession = new sdk_lib_mpc_1.DklsDkg.Dkg(3, 2, 2);
const round1Nock = await nockKeyGenRound1(bitgoSession, 1);
const round2Nock = await nockKeyGenRound2(bitgoSession, 1);
const round3Nock = await nockKeyGenRound3(bitgoSession, 1);
const addKeyNock = await nockAddKeyChain(coinName, 3);
// OVC 1 - User GPG key
const userGgpKey = await openpgp.generateKey({
userIDs: [
{
name: 'user',
email: 'user@test.com',
},
],
curve: 'secp256k1',
});
const userGpgPrvKey = {
partyId: 0,
gpgKey: userGgpKey.privateKey,
};
// Round 1 User
const userSession = new sdk_lib_mpc_1.DklsDkg.Dkg(3, 2, 0);
let OVC1ToOVC2Round1Payload;
{
const userBroadcastMsg1Unsigned = await userSession.initDkg();
const userMsgs1Signed = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages({ broadcastMessages: [sdk_lib_mpc_1.DklsTypes.serializeBroadcastMessage(userBroadcastMsg1Unsigned)], p2pMessages: [] }, [], [userGpgPrvKey]);
const userMsg1 = userMsgs1Signed.broadcastMessages.find((m) => m.from === 0);
assert(userMsg1, 'userMsg1 not found');
OVC1ToOVC2Round1Payload = {
tssVersion: '0.0.1',
walletType: public_types_1.WalletTypeEnum.tss,
coin: 'eth',
state: public_types_1.KeyCreationMPCv2StateEnum.WaitingForOVC2Round1Data,
ovc: {
[public_types_1.OVCIndexEnum.ONE]: {
gpgPubKey: userGgpKey.publicKey,
ovcMsg1: userMsg1,
},
},
};
}
// OVC 2 - Backup GPG key
const backupGgpKey = await openpgp.generateKey({
userIDs: [
{
name: 'backup',
email: 'backup@test.com',
},
],
curve: 'secp256k1',
});
const backupGpgPrvKey = {
partyId: 1,
gpgKey: backupGgpKey.privateKey,
};
// Round 1 Backup
const backupSession = new sdk_lib_mpc_1.DklsDkg.Dkg(3, 2, 1);
let OVC2ToBitgoRound1Payload;
{
assert(OVC1ToOVC2Round1Payload.state === 0, 'OVC1ToOVC2Round1Payload.state should be 0');
const backupBroadcastMsg1Unsigned = await backupSession.initDkg();
const backupMsgs1Signed = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages({ broadcastMessages: [sdk_lib_mpc_1.DklsTypes.serializeBroadcastMessage(backupBroadcastMsg1Unsigned)], p2pMessages: [] }, [], [backupGpgPrvKey]);
const backupMsg1 = backupMsgs1Signed.broadcastMessages.find((m) => m.from === 1);
assert(backupMsg1, 'backupMsg1 not found');
OVC2ToBitgoRound1Payload = {
...OVC1ToOVC2Round1Payload,
state: public_types_1.KeyCreationMPCv2StateEnum.WaitingForBitgoRound1Data,
ovc: {
...OVC1ToOVC2Round1Payload.ovc,
[public_types_1.OVCIndexEnum.TWO]: {
gpgPubKey: backupGgpKey.publicKey,
ovcMsg1: backupMsg1,
},
},
};
}
// Round 1 BitGo
const bitgoToOVC1Round1Payload = await MPCv2SMCUtils.keyGenRound1('testId', OVC2ToBitgoRound1Payload);
// Round 2 User
let OVC1ToOVC2Round2Payload;
{
assert(bitgoToOVC1Round1Payload.state === 2, 'bitgoToOVC1Round1Payload.state should be 2');
const toUserRound1BroadcastMessages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [],
broadcastMessages: [
bitgoToOVC1Round1Payload.ovc[public_types_1.OVCIndexEnum.TWO].ovcMsg1,
bitgoToOVC1Round1Payload.platform.bitgoMsg1,
],
}, [bitgoGpgPubKey, { partyId: 1, gpgKey: bitgoToOVC1Round1Payload.ovc[public_types_1.OVCIndexEnum.TWO].gpgPubKey }], [userGpgPrvKey]);
const userRound2P2PMessages = userSession.handleIncomingMessages({
p2pMessages: [],
broadcastMessages: toUserRound1BroadcastMessages.broadcastMessages.map(sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage),
});
const userRound2Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(sdk_lib_mpc_1.DklsTypes.serializeMessages(userRound2P2PMessages), [{ partyId: 1, gpgKey: bitgoToOVC1Round1Payload.ovc[public_types_1.OVCIndexEnum.TWO].gpgPubKey }, bitgoGpgPubKey], [userGpgPrvKey]);
const userToBackupMsg2 = userRound2Messages.p2pMessages.find((m) => m.from === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.USER && m.to === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BACKUP);
assert(userToBackupMsg2, 'userToBackupMsg2 not found');
const userToBitgoMsg2 = userRound2Messages.p2pMessages.find((m) => m.from === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.USER && m.to === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BITGO);
assert(userToBitgoMsg2, 'userToBitgoMsg2 not found');
OVC1ToOVC2Round2Payload = {
...bitgoToOVC1Round1Payload,
state: public_types_1.KeyCreationMPCv2StateEnum.WaitingForOVC2Round2Data,
ovc: {
...bitgoToOVC1Round1Payload.ovc,
[public_types_1.OVCIndexEnum.ONE]: Object.assign(bitgoToOVC1Round1Payload.ovc[public_types_1.OVCIndexEnum.ONE], {
ovcToBitgoMsg2: userToBitgoMsg2,
ovcToOvcMsg2: userToBackupMsg2,
}),
},
};
}
// Round 2 Backup
let OVC2ToBitgoRound2Payload;
{
assert(OVC1ToOVC2Round2Payload.state === 3, 'bitgoToOVC1Round1Payload.state should be 3');
const toBackupRound1BroadcastMessages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [],
broadcastMessages: [
bitgoToOVC1Round1Payload.ovc[public_types_1.OVCIndexEnum.ONE].ovcMsg1,
bitgoToOVC1Round1Payload.platform.bitgoMsg1,
],
}, [bitgoGpgPubKey, { partyId: 0, gpgKey: OVC1ToOVC2Round2Payload.ovc[public_types_1.OVCIndexEnum.ONE].gpgPubKey }], [backupGpgPrvKey]);
const backupRound2P2PMessages = backupSession.handleIncomingMessages({
p2pMessages: [],
broadcastMessages: toBackupRound1BroadcastMessages.broadcastMessages.map(sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage),
});
const backupRound2Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(sdk_lib_mpc_1.DklsTypes.serializeMessages(backupRound2P2PMessages), [{ partyId: 0, gpgKey: bitgoToOVC1Round1Payload.ovc[public_types_1.OVCIndexEnum.ONE].gpgPubKey }, bitgoGpgPubKey], [backupGpgPrvKey]);
const backupToUserMsg2 = backupRound2Messages.p2pMessages.find((m) => m.from === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BACKUP && m.to === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.USER);
assert(backupToUserMsg2, 'backupToUserMsg2 not found');
const backupToBitgoMsg2 = backupRound2Messages.p2pMessages.find((m) => m.from === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BACKUP && m.to === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BITGO);
assert(backupToBitgoMsg2, 'backupToBitgoMsg2 not found');
OVC2ToBitgoRound2Payload = {
...OVC1ToOVC2Round2Payload,
state: public_types_1.KeyCreationMPCv2StateEnum.WaitingForBitgoRound2Data,
ovc: {
...OVC1ToOVC2Round2Payload.ovc,
[public_types_1.OVCIndexEnum.TWO]: Object.assign(OVC1ToOVC2Round2Payload.ovc[public_types_1.OVCIndexEnum.TWO], {
ovcToBitgoMsg2: backupToBitgoMsg2,
ovcToOvcMsg2: backupToUserMsg2,
}),
},
};
}
// Round 2 BitGo
// call bitgo round 2
const bitgoToOVC1Round2Payload = await MPCv2SMCUtils.keyGenRound2('testId', OVC2ToBitgoRound2Payload);
// Round 3A User
let OVC1ToOVC2Round3Payload;
{
assert(bitgoToOVC1Round2Payload.state === 5, 'bitgoToOVC1Round2Payload.state should be 5');
const toUserRound2P2PMessages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [
bitgoToOVC1Round2Payload.ovc[public_types_1.OVCIndexEnum.TWO].ovcToOvcMsg2,
bitgoToOVC1Round2Payload.platform.ovc[public_types_1.OVCIndexEnum.ONE].bitgoToOvcMsg2,
],
broadcastMessages: [],
}, [bitgoGpgPubKey, { partyId: 1, gpgKey: bitgoToOVC1Round2Payload.ovc[public_types_1.OVCIndexEnum.TWO].gpgPubKey }], [userGpgPrvKey]);
const userRound3AP2PMessages = userSession.handleIncomingMessages({
p2pMessages: toUserRound2P2PMessages.p2pMessages.map(sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage),
broadcastMessages: [],
}).p2pMessages;
const userRound3AMessages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(sdk_lib_mpc_1.DklsTypes.serializeMessages({
p2pMessages: userRound3AP2PMessages,
broadcastMessages: [],
}), [{ partyId: 1, gpgKey: bitgoToOVC1Round2Payload.ovc[public_types_1.OVCIndexEnum.TWO].gpgPubKey }, bitgoGpgPubKey], [userGpgPrvKey]);
const userToBitgoMsg3 = userRound3AMessages.p2pMessages.find((m) => m.from === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.USER && m.to === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BITGO);
assert(userToBitgoMsg3, 'userToBitgoMsg3 not found');
const userToBackupMsg3 = userRound3AMessages.p2pMessages.find((m) => m.from === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.USER && m.to === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BACKUP);
assert(userToBackupMsg3, 'userToBackupMsg3 not found');
OVC1ToOVC2Round3Payload = {
...bitgoToOVC1Round2Payload,
state: public_types_1.KeyCreationMPCv2StateEnum.WaitingForOVC2Round3Data,
ovc: {
...bitgoToOVC1Round2Payload.ovc,
[public_types_1.OVCIndexEnum.ONE]: Object.assign(bitgoToOVC1Round2Payload.ovc[public_types_1.OVCIndexEnum.ONE], {
ovcToBitgoMsg3: userToBitgoMsg3,
ovcToOvcMsg3: userToBackupMsg3,
}),
},
};
}
// Round 3 Backup
let OVC2ToOVC1Round3Payload;
{
assert(OVC1ToOVC2Round3Payload.state === 6, 'OVC1ToOVC2Round3Payload.state should be 6');
const toBackupRound3P2PMessages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [
OVC1ToOVC2Round3Payload.ovc[public_types_1.OVCIndexEnum.ONE].ovcToOvcMsg2,
OVC1ToOVC2Round3Payload.platform.ovc[public_types_1.OVCIndexEnum.TWO].bitgoToOvcMsg2,
],
broadcastMessages: [],
}, [bitgoGpgPubKey, { partyId: 0, gpgKey: OVC1ToOVC2Round3Payload.ovc[public_types_1.OVCIndexEnum.ONE].gpgPubKey }], [backupGpgPrvKey]);
const backupRound3P2PMessages = backupSession.handleIncomingMessages({
p2pMessages: toBackupRound3P2PMessages.p2pMessages.map(sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage),
broadcastMessages: [],
});
const backupRound3Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(sdk_lib_mpc_1.DklsTypes.serializeMessages(backupRound3P2PMessages), [{ partyId: 0, gpgKey: OVC1ToOVC2Round3Payload.ovc[public_types_1.OVCIndexEnum.ONE].gpgPubKey }, bitgoGpgPubKey], [backupGpgPrvKey]);
const backupToBitgoMsg3 = backupRound3Messages.p2pMessages.find((m) => m.from === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BACKUP && m.to === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BITGO);
assert(backupToBitgoMsg3, 'backupToBitgoMsg3 not found');
const backupToUserMsg3 = backupRound3Messages.p2pMessages.find((m) => m.from === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BACKUP && m.to === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.USER);
assert(backupToUserMsg3, 'backupToUserMsg3 not found');
const toBackupRound3Messages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [
{
...OVC1ToOVC2Round3Payload.ovc[public_types_1.OVCIndexEnum.ONE].ovcToOvcMsg3,
commitment: OVC1ToOVC2Round3Payload.ovc[public_types_1.OVCIndexEnum.ONE].ovcToOvcMsg2.commitment,
},
{
...OVC1ToOVC2Round3Payload.platform.ovc[public_types_1.OVCIndexEnum.TWO].bitgoToOvcMsg3,
commitment: OVC1ToOVC2Round3Payload.platform.bitgoCommitment2,
},
],
broadcastMessages: [],
}, [bitgoGpgPubKey, { partyId: 0, gpgKey: OVC1ToOVC2Round3Payload.ovc[public_types_1.OVCIndexEnum.ONE].gpgPubKey }], [backupGpgPrvKey]);
const backupRound4Messages = backupSession.handleIncomingMessages({
p2pMessages: toBackupRound3Messages.p2pMessages.map(sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage),
broadcastMessages: [],
}).broadcastMessages;
const backupRound4BroadcastMessages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(sdk_lib_mpc_1.DklsTypes.serializeMessages({
p2pMessages: [],
broadcastMessages: backupRound4Messages,
}), [], [backupGpgPrvKey]);
const backupMsg4 = backupRound4BroadcastMessages.broadcastMessages.find((m) => m.from === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.BACKUP);
assert(backupMsg4, 'backupMsg4 not found');
OVC2ToOVC1Round3Payload = {
...OVC1ToOVC2Round3Payload,
state: public_types_1.KeyCreationMPCv2StateEnum.WaitingForOVC1Round3bData,
ovc: {
...OVC1ToOVC2Round3Payload.ovc,
[public_types_1.OVCIndexEnum.TWO]: Object.assign(OVC1ToOVC2Round3Payload.ovc[public_types_1.OVCIndexEnum.TWO], {
ovcToOvcMsg3: backupToUserMsg3,
ovcToBitgoMsg3: backupToBitgoMsg3,
ovcMsg4: backupMsg4,
}),
},
};
}
// Round 3B User
let OVC1ToBitgoRound3BPayload;
{
assert(OVC2ToOVC1Round3Payload.state === 7, 'OVC2ToOVC1Round3Payload.state should be 7');
const toUserRound4Messages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [
{
...OVC2ToOVC1Round3Payload.ovc[public_types_1.OVCIndexEnum.TWO].ovcToOvcMsg3,
commitment: OVC2ToOVC1Round3Payload.ovc[public_types_1.OVCIndexEnum.TWO].ovcToOvcMsg2.commitment,
},
{
...OVC2ToOVC1Round3Payload.platform.ovc[public_types_1.OVCIndexEnum.ONE].bitgoToOvcMsg3,
commitment: OVC2ToOVC1Round3Payload.platform.bitgoCommitment2,
},
],
broadcastMessages: [],
}, [bitgoGpgPubKey, { partyId: 1, gpgKey: OVC2ToOVC1Round3Payload.ovc[public_types_1.OVCIndexEnum.TWO].gpgPubKey }], [userGpgPrvKey]);
const userRound4BroadcastMessages = userSession.handleIncomingMessages({
p2pMessages: toUserRound4Messages.p2pMessages.map(sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage),
broadcastMessages: [],
}).broadcastMessages;
assert(userRound4BroadcastMessages.length === 1, 'userRound4BroadcastMessages length should be 1');
const userRound4Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(sdk_lib_mpc_1.DklsTypes.serializeMessages({
p2pMessages: [],
broadcastMessages: userRound4BroadcastMessages,
}), [], [userGpgPrvKey]);
const userMsg4 = userRound4Messages.broadcastMessages.find((m) => m.from === sdk_core_1.ECDSAUtils.MPCv2PartiesEnum.USER);
assert(userMsg4, 'userMsg4 not found');
OVC1ToBitgoRound3BPayload = {
...OVC2ToOVC1Round3Payload,
state: public_types_1.KeyCreationMPCv2StateEnum.WaitingForBitgoRound3Data,
ovc: {
...OVC2ToOVC1Round3Payload.ovc,
[public_types_1.OVCIndexEnum.ONE]: Object.assign(OVC2ToOVC1Round3Payload.ovc[public_types_1.OVCIndexEnum.ONE], {
ovcMsg4: userMsg4,
}),
},
};
}
// Round 3 BitGo
// creates bitgo keychain
const bitgoToOVC1Round3Payload = await MPCv2SMCUtils.keyGenRound3('testId', OVC1ToBitgoRound3BPayload);
// Round 4 User
let userCommonKeychain;
let OVC1ToOVC2Round4Payload;
{
assert(bitgoToOVC1Round3Payload.state === 9, 'bitgoToOVC1Round3Payload.state should be 9');
assert(bitgoToOVC1Round3Payload.bitGoKeyId, 'bitgoToOVC1Round3Payload.bitGoKeyId not found');
const toUserBitgoRound3Msg = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [],
broadcastMessages: [
bitgoToOVC1Round3Payload.ovc[public_types_1.OVCIndexEnum.TWO].ovcMsg4,
bitgoToOVC1Round3Payload.platform.bitgoMsg4,
],
}, [bitgoGpgPubKey, { partyId: 1, gpgKey: bitgoToOVC1Round3Payload.ovc[public_types_1.OVCIndexEnum.TWO].gpgPubKey }], [userGpgPrvKey]);
userSession.handleIncomingMessages({
p2pMessages: [],
broadcastMessages: toUserBitgoRound3Msg.broadcastMessages.map(sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage),
});
const userPrivateMaterial = userSession.getKeyShare();
userCommonKeychain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(userPrivateMaterial);
assert.equal(bitgoToOVC1Round3Payload.platform.commonKeychain, userCommonKeychain, 'User and Bitgo Common keychains do not match');
const userPrv = userPrivateMaterial.toString('base64');
assert(userPrv, 'userPrv not found');
OVC1ToOVC2Round4Payload = {
bitgoKeyId: bitgoToOVC1Round3Payload.bitGoKeyId,
...bitgoToOVC1Round3Payload,
state: public_types_1.KeyCreationMPCv2StateEnum.WaitingForOVC2GenerateKey,
};
}
// Round 4 Backup
let backupCommonKeychain;
{
assert(OVC1ToOVC2Round4Payload.state === 10, 'OVC1ToOVC2Round4Payload.state should be 10');
assert(OVC1ToOVC2Round4Payload.bitgoKeyId, 'OVC1ToOVC2Round4Payload.bitGoKeyId not found');
const toBackupBitgoRound3Msg = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [],
broadcastMessages: [
OVC1ToOVC2Round4Payload.ovc[public_types_1.OVCIndexEnum.ONE].ovcMsg4,
OVC1ToOVC2Round4Payload.platform.bitgoMsg4,
],
}, [bitgoGpgPubKey, { partyId: 0, gpgKey: OVC1ToOVC2Round4Payload.ovc[public_types_1.OVCIndexEnum.ONE].gpgPubKey }], [backupGpgPrvKey]);
backupSession.handleIncomingMessages({
p2pMessages: [],
broadcastMessages: toBackupBitgoRound3Msg.broadcastMessages.map(sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage),
});
const backupPrivateMaterial = backupSession.getKeyShare();
backupCommonKeychain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(backupPrivateMaterial);
assert.equal(OVC1ToOVC2Round4Payload.platform.commonKeychain, backupCommonKeychain, 'Backup and Bitgo Common keychains do not match');
const backupPrv = backupPrivateMaterial.toString('base64');
assert(backupPrv, 'backupPrv not found');
}
// Round 4 BitGo
// creates user and backup keychain
const keychains = await MPCv2SMCUtils.uploadClientKeys(bitgoToOVC1Round3Payload.bitGoKeyId, userCommonKeychain, backupCommonKeychain);
assert.deepEqual(keychains.userKeychain, {
commonKeychain: userCommonKeychain,
type: 'tss',
source: 'user',
id: 'user',
});
assert.deepEqual(keychains.backupKeychain, {
commonKeychain: backupCommonKeychain,
type: 'tss',
source: 'backup',
id: 'backup',
});
assert.ok(round1Nock.isDone());
assert.ok(round2Nock.isDone());
assert.ok(round3Nock.isDone());
assert.ok(addKeyNock.isDone());
});
it('should throw for MPCv2 SMC utils if the state is invalid', async function () {
const MPCv2SMCUtils = new sdk_core_1.ECDSAUtils.MPCv2SMCUtils(bitgo, baseCoin);
const invalidPayload = {
state: public_types_1.KeyCreationMPCv2StateEnum.WaitingForOVC1Round2Data,
};
await assert.rejects(async () => await MPCv2SMCUtils.keyGenRound1('testId', invalidPayload), {
message: `Invalid state for round 1, expected: ${public_types_1.KeyCreationMPCv2StateEnum.WaitingForBitgoRound1Data}, got: ${public_types_1.KeyCreationMPCv2StateEnum.WaitingForOVC1Round2Data}`,
});
await assert.rejects(async () => await MPCv2SMCUtils.keyGenRound2('testId', invalidPayload), {
message: `Invalid state for round 2, expected: ${public_types_1.KeyCreationMPCv2StateEnum.WaitingForBitgoRound2Data}, got: ${public_types_1.KeyCreationMPCv2StateEnum.WaitingForOVC1Round2Data}`,
});
await assert.rejects(async () => await MPCv2SMCUtils.keyGenRound3('testId', invalidPayload), {
message: `Invalid state for round 3, expected: ${public_types_1.KeyCreationMPCv2StateEnum.WaitingForBitgoRound3Data}, got: ${public_types_1.KeyCreationMPCv2StateEnum.WaitingForOVC1Round2Data}`,
});
});
});
async function nockKeychain(params, times = 1) {
nock(bgUrl)
.post(`/api/v2/${params.coin}/key`, (body) => {
return body.keyType === 'tss' && body.source === params.source;
})
.times(times)
.reply(200, params.keyChain);
return params.keyChain;
}
async function nockGetBitgoPublicKeyBasedOnFeatureFlags(coin, enterpriseId, bitgoGpgKeyPair) {
const bitgoGPGPublicKeyResponse = {
name: 'irrelevant',
publicKey: bitgoGpgKeyPair.publicKey,
mpcv2PublicKey: bitgoGpgKeyPair.publicKey,
enterpriseId,
};
nock(bgUrl).get(`/api/v2/${coin}/tss/pubkey`).query({ enterpriseId }).reply(200, bitgoGPGPublicKeyResponse);
return bitgoGPGPublicKeyResponse;
}
async function nockKeyGenRound1(bitgoSession, times = 1) {
return nock(bgUrl)
.post(`/api/v2/mpc/generatekey`, (body) => body.round === 'MPCv2-R1')
.times(times)
.reply(200, async (uri, { payload }) => {
const { userGpgPublicKey, backupGpgPublicKey, userMsg1, backupMsg1 } = payload;
userGpgPubKey = {
partyId: 0,
gpgKey: userGpgPublicKey,
};
backupGpgPubKey = {
partyId: 1,
gpgKey: backupGpgPublicKey,
};
const bitgoBroadcastMsg1Unsigned = await bitgoSession.initDkg();
const bitgoMsgs1Signed = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages({ broadcastMessages: [sdk_lib_mpc_1.DklsTypes.serializeBroadcastMessage(bitgoBroadcastMsg1Unsigned)], p2pMessages: [] }, [], [bitgoGpgPrvKey]);
const bitgoMsg1 = bitgoMsgs1Signed.broadcastMessages.find((m) => m.from === 2);
assert(bitgoMsg1, 'bitgoMsg1 not found');
const round1IncomingMsgs = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [],
broadcastMessages: [
{ from: 0, payload: userMsg1 },
{ from: 1, payload: backupMsg1 },
],
}, [userGpgPubKey, backupGpgPubKey], [bitgoGpgPrvKey]);
const round2Messages = sdk_lib_mpc_1.DklsTypes.serializeMessages(bitgoSession.handleIncomingMessages(sdk_lib_mpc_1.DklsTypes.deserializeMessages(round1IncomingMsgs)));
const round2SignedMessages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(round2Messages, [userGpgPubKey, backupGpgPubKey], [bitgoGpgPrvKey]);
const bitgoToUserMsg2 = round2SignedMessages.p2pMessages.find((m) => m.to === 0);
const bitgoToBackupMsg2 = round2SignedMessages.p2pMessages.find((m) => m.to === 1);
assert(bitgoToUserMsg2, 'bitgoToUserMsg2 not found');
assert(bitgoToBackupMsg2, 'bitgoToBackupMsg2 not found');
assert(bitgoToUserMsg2.commitment, 'bitgoToUserMsg2.commitment not found');
storedBitgoCommitment2 = bitgoToUserMsg2?.commitment;
return {
sessionId: 'testid',
bitgoMsg1: { from: 2, ...bitgoMsg1.payload },
bitgoToBackupMsg2: {
from: 2,
to: 1,
encryptedMessage: bitgoToBackupMsg2.payload.encryptedMessage,
signature: bitgoToBackupMsg2.payload.signature,
},
bitgoToUserMsg2: {
from: 2,
to: 0,
encryptedMessage: bitgoToUserMsg2.payload.encryptedMessage,
signature: bitgoToUserMsg2.payload.signature,
},
walletGpgPubKeySigs: 'something',
};
});
}
async function nockKeyGenRound2(bitgoSession, times = 1) {
return nock(bgUrl)
.post(`/api/v2/mpc/generatekey`, (body) => body.round === 'MPCv2-R2')
.times(times)
.reply(200, async (uri, { payload }) => {
const { sessionId, userMsg2, backupMsg2, userCommitment2, backupCommitment2 } = payload;
storedUserCommitment2 = userCommitment2;
storedBackupCommitment2 = backupCommitment2;
const round2IncomingMsgs = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [
{
from: userMsg2.from,
to: userMsg2.to,
payload: { signature: userMsg2.signature, encryptedMessage: userMsg2.encryptedMessage },
},
{
from: backupMsg2.from,
to: backupMsg2.to,
payload: { signature: backupMsg2.signature, encryptedMessage: backupMsg2.encryptedMessage },
},
],
broadcastMessages: [],
}, [userGpgPubKey, backupGpgPubKey], [bitgoGpgPrvKey]);
const round3Messages = sdk_lib_mpc_1.DklsTypes.serializeMessages(bitgoSession.handleIncomingMessages(sdk_lib_mpc_1.DklsTypes.deserializeMessages(round2IncomingMsgs)));
const round3SignedMessages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(round3Messages, [userGpgPubKey, backupGpgPubKey], [bitgoGpgPrvKey]);
const bitgoToUserMsg3 = round3SignedMessages.p2pMessages.find((m) => m.to === 0);
const bitgoToBackupMsg3 = round3SignedMessages.p2pMessages.find((m) => m.to === 1);
assert(bitgoToUserMsg3, 'bitgoToUserMsg3 not found');
assert(bitgoToBackupMsg3, 'bitgoToBackupMsg3 not found');
return {
sessionId,
bitgoCommitment2: storedBitgoCommitment2,
bitgoToUserMsg3: {
from: 2,
to: 0,
encryptedMessage: bitgoToUserMsg3.payload.encryptedMessage,
signature: bitgoToUserMsg3.payload.signature,
},
bitgoToBackupMsg3: {
from: 2,
to: 1,
encryptedMessage: bitgoToBackupMsg3.payload.encryptedMessage,
signature: bitgoToBackupMsg3.payload.signature,
},
};
});
}
async function nockKeyGenRound3(bitgoSession, times = 1) {
return nock(bgUrl)
.post(`/api/v2/mpc/generatekey`, (body) => body.round === 'MPCv2-R3')
.times(times)
.reply(200, async (uri, { payload }) => {
const { sessionId, userMsg3, userMsg4, backupMsg3, backupMsg4 } = payload;
const round3IncomingMsgs = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [
{
from: userMsg3.from,
to: userMsg3.to,
payload: { signature: userMsg3.signature, encryptedMessage: userMsg3.encryptedMessage },
commitment: storedUserCommitment2,
},
{
from: backupMsg3.from,
to: backupMsg3.to,
payload: { signature: backupMsg3.signature, encryptedMessage: backupMsg3.encryptedMessage },
commitment: storedBackupCommitment2,
},
],
broadcastMessages: [],
}, [userGpgPubKey, backupGpgPubKey], [bitgoGpgPrvKey]);
const round4Messages = sdk_lib_mpc_1.DklsTypes.serializeMessages(bitgoSession.handleIncomingMessages(sdk_lib_mpc_1.DklsTypes.deserializeMessages(round3IncomingMsgs)));
const round4SignedMessages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(round4Messages, [], [bitgoGpgPrvKey]);
const bitgoMsg4 = round4SignedMessages.broadcastMessages.find((m) => m.from === 2);
assert(bitgoMsg4, 'bitgoMsg4 not found');
const round4IncomingMsgs = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({
p2pMessages: [],
broadcastMessages: [
{
from: userMsg4.from,
payload: { signature: userMsg4.signature, message: userMsg4.message },
},
{
from: backupMsg4.from,
payload: { signature: backupMsg4.signature, message: backupMsg4.message },
},
],
}, [userGpgPubKey, backupGpgPubKey], []);
bitgoSession.handleIncomingMessages(sdk_lib_mpc_1.DklsTypes.deserializeMessages(round4IncomingMsgs));
const keyShare = bitgoSession.getKeyShare();
const commonKeychain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(keyShare);
return {
sessionId,
commonKeychain: commonKeychain,
bitgoMsg4: { from: 2, ...bitgoMsg4.payload },
};
});
}
async function nockAddKeyChain(coin, times = 1) {
return nock('https://bitgo.fakeurl')
.post(`/api/v2/${coin}/key`, (body) => body.keyType === 'tss' && body.isMPCv2)
.times(times)
.reply(200, async (uri, requestBody) => {
const key = {
id: requestBody.source,
source: requestBody.source,
type: requestBody.keyType,
commonKeychain: requestBody.commonKeychain,
encryptedPrv: requestBody.encryptedPrv,
};
// nock gets
nock('https://bitgo.fakeurl').get(`/api/v2/${coin}/key/${requestBody.source}`).reply(200, key);
return key;
});
}
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlS2V5Y2hhaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vdGVzdC92Mi91bml0L2ludGVybmFsL3Rzc1V0aWxzL2VjZHNhTVBDdjIvY3JlYXRlS2V5Y2hhaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaUNBQWlDO0FBQ2pDLDZCQUE2QjtBQUM3QixtQ0FBbUM7QUFDbkMsaUNBQWlDO0FBRWpDLDhDQUF3RDtBQUN4RCw4Q0FBcUc7QUFDckcsb0RBQXlHO0FBQ3pHLHNEQWlCNkI7QUFFN0IsK0NBQWlFO0FBQ2pFLHdEQUF3RDtBQUV4RCxRQUFRLENBQUMsd0JBQXdCLEVBQUUsS0FBSztJQUN0QyxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUM7SUFDekIsTUFBTSxRQUFRLEdBQUcsa0NBQWtDLENBQUM7SUFDcEQsTUFBTSxZQUFZLEdBQUcsa0NBQWtDLENBQUM7SUFDeEQsSUFBSSxxQkFBNkIsQ0FBQztJQUNsQyxJQUFJLHVCQUErQixDQUFDO0lBQ3BDLElBQUksc0JBQThCLENBQUM7SUFFbkMsSUFBSSxLQUFhLENBQUM7SUFDbEIsSUFBSSxRQUFvQyxDQUFDO0lBQ3pDLElBQUksTUFBYyxDQUFDO0lBQ25CLElBQUksS0FBeUIsQ0FBQztJQUM5QixJQUFJLFFBQWtCLENBQUM7SUFDdkIsSUFBSSxXQUVILENBQUM7SUFDRixJQUFJLFNBQTJFLENBQUM7SUFDaEYsSUFBSSxjQUFtRCxDQUFDO0lBQ3hELElBQUksYUFBa0QsQ0FBQztJQUN2RCxJQUFJLGVBQW9ELENBQUM7SUFDekQsSUFBSSxjQUFtRCxDQUFDO0lBRXhELFVBQVUsQ0FBQyxLQUFLO1FBQ2QsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2hCLE1BQU0sd0NBQXdDLENBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxXQUFXLENBQUMsQ0FBQztRQUNwRixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLDBCQUEw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LEVBQUUsY0FBZ0M7Z0JBQ2hELFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUMsT0FBTyxFQUFFO2FBQzdDLENBQUM7UUFDSixDQUFDLENBQ0YsQ0FBQztJQUNOLENBQUM7SUFFRCxLQUFLLFVBQVUsZUFBZSxDQUFDLElBQVksRUFBRSxLQUFLLEdBQUcsQ0FBQztRQUNwRCxPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FBQzthQUNqQyxJQUFJLENBQUMsV0FBVyxJQUFJLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQzthQUM3RSxLQUFLLENBQUMsS0FBSyxDQUFDO2FBQ1osS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLFdBQStCLEVBQUUsRUFBRTtZQUN6RCxNQUFNLEdBQUcsR0FBRztnQkFDVixFQUFFLEVBQUUsV0FBVyxDQUFDLE1BQU07Z0JBQ3RCLE1BQU0sRUFBRSxXQUFXLENBQUMsTUFBTTtnQkFDMUIsSUFBSSxFQUFFLFdBQVcsQ0FBQyxPQUFPO2dCQUN6QixjQUFjLEVBQUUsV0FBVyxDQUFDLGNBQWM7Z0JBQzFDLFlBQVksRUFBRSxXQUFXLENBQUMsWUFBWTthQUN2QyxDQUFDO1lBQ0YsWUFBWTtZQUNaLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxXQUFXLElBQUksUUFBUSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQy9GLE9BQU8sR0FBRyxDQUFDO1FBQ2IsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0FBQ0gsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAqIGFzIG5vY2sgZnJvbSAnbm9jayc7XG5pbXBvcnQgKiBhcyBvcGVucGdwIGZyb20gJ29wZW5wZ3AnO1xuaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5cbmltcG9ydCB7IFRlc3RhYmxlQkcsIFRlc3RCaXRHbyB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQgeyBBZGRLZXljaGFpbk9wdGlvbnMsIEJhc2VDb2luLCBjb21tb24sIEVDRFNBVXRpbHMsIEtleWNoYWluLCBXYWxsZXQgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgYmlnSW50VG9CdWZmZXJCRSwgRGtsc0NvbW1zLCBEa2xzRGtnLCBEa2xzRHNnLCBEa2xzVHlwZXMsIERrbHNVdGlscyB9IGZyb20gJ0BiaXRnby9zZGstbGliLW1wYyc7XG5pbXBvcnQge1xuICBLZXlDcmVhdGlvbk1QQ3YyU3RhdGVFbnVtLFxuICBNUEN2MktleUdlblJvdW5kMVJlcXVlc3QsXG4gIE1QQ3YyS2V5R2VuUm91bmQxUmVzcG9uc2UsXG4gIE1QQ3YyS2V5R2VuUm91bmQyUmVxdWVzdCxcbiAgTVBDdjJLZXlHZW5Sb3VuZDJSZXNwb25zZSxcbiAgTVBDdjJLZXlHZW5Sb3VuZDNSZXF1ZXN0LFxuICBNUEN2MktleUdlblJvdW5kM1Jlc3BvbnNlLFxuICBPVkMxVG9CaXRnb1JvdW5kM1BheWxvYWQsXG4gIE9WQzFUb09WQzJSb3VuZDFQYXlsb2FkLFxuICBPVkMxVG9PVkMyUm91bmQyUGF5bG9hZCxcbiAgT1ZDMVRvT1ZDMlJvdW5kM1BheWxvYWQsXG4gIE9WQzJUb0JpdGdvUm91bmQxUGF5bG9hZCxcbiAgT1ZDMlRvQml0Z29Sb3VuZDJQYXlsb2FkLFxuICBPVkMyVG9PVkMxUm91bmQzUGF5bG9hZCxcbiAgT1ZDSW5kZXhFbnVtLFxuICBXYWxsZXRUeXBlRW51bSxcbn0gZnJvbSAnQGJpdGdvL3B1YmxpYy10eXBlcyc7XG5pbXBvcnQgeyBOb25FbXB0eVN0cmluZyB9IGZyb20gJ2lvLXRzLXR5cGVzJztcbmltcG9ydCB7IEJpdEdvLCBCaXRnb0dQR1B1YmxpY0tleSB9IGZyb20gJy4uLy4uLy4uLy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgKiBhcyB2MUZpeHR1cmVzIGZyb20gJy4vZml4dHVyZXMvbXBjdjFLZXlTaGFyZXMnO1xuXG5kZXNjcmliZSgnVFNTIEVjZHNhIE1QQ3YyIFV0aWxzOicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgY29pbk5hbWUgPSAnaHRldGgnO1xuICBjb25zdCB3YWxsZXRJZCA9ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCc7XG4gIGNvbnN0IGVudGVycHJpc2VJZCA9ICc2NDQ5MTUzYTZmNmJjMjAwMDZkNjY3NzFjZGJlMTVkMyc7XG4gIGxldCBzdG9yZWRVc2VyQ29tbWl0bWVudDI6IHN0cmluZztcbiAgbGV0IHN0b3JlZEJhY2t1cENvbW1pdG1lbnQyOiBzdHJpbmc7XG4gIGxldCBzdG9yZWRCaXRnb0NvbW1pdG1lbnQyOiBzdHJpbmc7XG5cbiAgbGV0IGJnVXJsOiBzdHJpbmc7XG4gIGxldCB0c3NVdGlsczogRUNEU0FVdGlscy5FY2RzYU1QQ3YyVXRpbHM7XG4gIGxldCB3YWxsZXQ6IFdhbGxldDtcbiAgbGV0IGJpdGdvOiBUZXN0YWJsZUJHICYgQml0R287XG4gIGxldCBiYXNlQ29pbjogQmFzZUNvaW47XG4gIGxldCBiaXRHb0dncEtleTogb3BlbnBncC5TZXJpYWxpemVkS2V5UGFpcjxzdHJpbmc+ICYge1xuICAgIHJldm9jYXRpb25DZXJ0aWZpY2F0ZTogc3RyaW5nO1xuICB9O1xuICBsZXQgY29uc3RhbnRzOiB7IG1wYzogeyBiaXRnb1B1YmxpY0tleTogc3RyaW5nOyBiaXRnb01QQ3YyUHVibGljS2V5OiBzdHJpbmcgfSB9O1xuICBsZXQgYml0Z29HcGdQcnZLZXk6IHsgcGFydHlJZDogbnVtYmVyOyBncGdLZXk6IHN0cmluZyB9O1xuICBsZXQgdXNlckdwZ1B1YktleTogeyBwYXJ0eUlkOiBudW1iZXI7IGdwZ0tleTogc3RyaW5nIH07XG4gIGxldCBiYWNrdXBHcGdQdWJLZXk6IHsgcGFydHlJZDogbnVtYmVyOyBncGdLZXk6IHN0cmluZyB9O1xuICBsZXQgYml0Z29HcGdQdWJLZXk6IHsgcGFydHlJZDogbnVtYmVyOyBncGdLZXk6IHN0cmluZyB9O1xuXG4gIGJlZm9yZUVhY2goYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICBhd2FpdCBub2NrR2V0Qml0Z29QdWJsaWNLZXlCYXNlZE9uRmVhdHVyZUZsYWdzKGNvaW5OYW1lLCBlbnRlcnByaXNlSWQsIGJpdEdvR2dwS2V5KTtcbiAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnRpbWVzKDE2KS5yZXBseSgyMDAsIHsgdHRsOiAzNjAwLCBjb25zdGFudHMgfSk7XG4gIH0pO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgYml0R29HZ3BLZXkgPSBhd2FpdCBvcGVucGdwLmdlbmVyYXRlS2V5KHtcbiAgICAgIHVzZXJJRHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6ICdiaXRnbycsXG4gICAgICAgICAgZW1haWw6ICdiaXRnb0B0ZXN0LmNvbScsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgY3VydmU6ICdzZWNwMjU2azEnLFxuICAgIH0pO1xuICAgIGNvbnN0YW50cyA9IHtcbiAgICAgIG1wYzoge1xuICAgICAgICBiaXRnb1B1YmxpY0tleTogYml0R29HZ3BLZXkucHVibGljS2V5LFxuICAgICAgICBiaXRnb01QQ3YyUHVibGljS2V5OiBiaXRHb0dncEtleS5wdWJsaWNLZXksXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBiaXRnb0dwZ1B1YktleSA9IHtcbiAgICAgIHBhcnR5SWQ6IDIsXG4gICAgICBncGdLZXk6IGJpdEdvR2dwS2V5LnB1YmxpY0tleSxcbiAgICB9O1xuXG4gICAgYml0Z29HcGdQcnZLZXkgPSB7XG4gICAgICBwYXJ0eUlkOiAyLFxuICAgICAgZ3BnS2V5OiBiaXRHb0dncEtleS5wcml2YXRlS2V5LFxuICAgIH07XG5cbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcblxuICAgIGJhc2VDb2luID0gYml0Z28uY29pbihjb2luTmFtZSk7XG5cbiAgICBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcblxuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogd2FsbGV0SWQsXG4gICAgICBlbnRlcnByaXNlOiBlbnRlcnByaXNlSWQsXG4gICAgICBjb2luOiBjb2luTmFtZSxcbiAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgIH07XG4gICAgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgYmFzZUNvaW4sIHdhbGxldERhdGEpO1xuICAgIHRzc1V0aWxzID0gbmV3IEVDRFNBVXRpbHMuRWNkc2FNUEN2MlV0aWxzKGJpdGdvLCBiYXNlQ29pbiwgd2FsbGV0KTtcbiAgfSk7XG5cbiAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JldHJvZml0IE1QQ3YxIHRvIE1QQ3YyIGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBUU1MgTVBDdjIga2V5cyBmcm9tIE1QQ3YxIGtleXMgYW5kIHNpZ24gYSBtZXNzYWdlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmV0cm9maXREYXRhID0gdHNzVXRpbHMuZ2V0TXBjVjJSZXRyb2ZpdERhdGFGcm9tTXBjVjFLZXlzKHtcbiAgICAgICAgbXBjdjFVc2VyS2V5U2hhcmU6IEpTT04uc3RyaW5naWZ5KHYxRml4dHVyZXMubW9ja1VzZXJTaWduaW5nTWF0ZXJpYWwpLFxuICAgICAgICBtcGN2MUJhY2t1cEtleVNoYXJlOiBKU09OLnN0cmluZ2lmeSh2MUZpeHR1cmVzLm1vY2tCYWNrdXBTaWduaW5nTWF0ZXJpYWwpLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBiaXRnb1JldHJvZml0RGF0YTogRGtsc1R5cGVzLlJldHJvZml0RGF0YSA9IHtcbiAgICAgICAgeGlMaXN0OiByZXRyb2ZpdERhdGEubXBjdjJVc2VyS2V5U2hhcmUueGlMaXN0LFxuICAgICAgICB4U2hhcmU6IHYxRml4dHVyZXMubW9ja0JpdEdvU2hhcmVTaWduaW5nTWF0ZXJpYWwueFNoYXJlLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IFt1c2VyLCBiYWNrdXAsIGJpdGdvXSA9IGF3YWl0IERrbHNVdGlscy5nZW5lcmF0ZURLR0tleVNoYXJlcyhcbiAgICAgICAgcmV0cm9maXREYXRhLm1wY3YyVXNlcktleVNoYXJlLFxuICAgICAgICByZXRyb2ZpdERhdGEubXBjdjJCYWNrdXBLZXlTaGFyZSxcbiAgICAgICAgYml0Z29SZXRyb2ZpdERhdGFcbiAgICAgICk7XG4gICAgICBhc3NlcnQub2soYml0Z28uZ2V0S2V5U2hhcmUoKSk7XG4gICAgICBjb25zdCBtZXNzYWdlVG9TaWduID0gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShCdWZmZXIuZnJvbSgnZmZmZicsICdoZXgnKSkuZGlnZXN0KCk7XG4gICAgICBjb25zdCBkZXJpdmF0aW9uUGF0aCA9ICdtLzk5OS85ODgvMC8wJztcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IGF3YWl0IERrbHNVdGlscy5leGVjdXRlVGlsbFJvdW5kKFxuICAgICAgICA1LFxuICAgICAgICBuZXcgRGtsc0RzZy5Ec2codXNlci5nZXRLZXlTaGFyZSgpLCAwLCBkZXJpdmF0aW9uUGF0aCwgbWVzc2FnZVRvU2lnbiksXG4gICAgICAgIG5ldyBEa2xzRHNnLkRzZyhiYWNrdXAuZ2V0S2V5U2hhcmUoKSwgMSwgZGVyaXZhdGlvblBhdGgsIG1lc3NhZ2VUb1NpZ24pXG4gICAgICApO1xuICAgICAgY29uc3QgY29udmVydGVkU2lnbmF0dXJlID0gRGtsc1V0aWxzLnZlcmlmeUFuZENvbnZlcnREa2xzU2lnbmF0dXJlKFxuICAgICAgICBCdWZmZXIuZnJvbSgnZmZmZicsICdoZXgnKSxcbiAgICAgICAgc2lnbmF0dXJlIGFzIERrbHNUeXBlcy5EZXNlcmlhbGl6ZWREa2xzU2lnbmF0dXJlLFxuICAgICAgICB2MUZpeHR1cmVzLm1vY2tCaXRHb1NoYXJlU2lnbmluZ01hdGVyaWFsLnhTaGFyZS55ICsgdjFGaXh0dXJlcy5tb2NrQml0R29TaGFyZVNpZ25pbmdNYXRlcmlhbC54U2hhcmUuY2hhaW5jb2RlLFxuICAgICAgICBkZXJpdmF0aW9uUGF0aFxuICAgICAgKTtcbiAgICAgIGFzc2VydC5vayhjb252ZXJ0ZWRTaWduYXR1cmUpO1xuICAgICAgY29udmVydGVkU2lnbmF0dXJlLnNwbGl0KCc6JykubGVuZ3RoLnNob3VsZC5lcXVhbCg0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RTUyBrZXkgY2hhaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgVFNTIE1QQ3YyIGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnb1Nlc3Npb24gPSBuZXcgRGtsc0RrZy5Ea2coMywgMiwgMik7XG5cbiAgICAgIGNvbnN0IHJvdW5kMU5vY2sgPSBhd2FpdCBub2NrS2V5R2VuUm91bmQxKGJpdGdvU2Vzc2lvbiwgMSk7XG4gICAgICBjb25zdCByb3VuZDJOb2NrID0gYXdhaXQgbm9ja0tleUdlblJvdW5kMihiaXRnb1Nlc3Npb24sIDEpO1xuICAgICAgY29uc3Qgcm91bmQzTm9jayA9IGF3YWl0IG5vY2tLZXlHZW5Sb3VuZDMoYml0Z29TZXNzaW9uLCAxKTtcbiAgICAgIGNvbnN0IGFkZEtleU5vY2sgPSBhd2FpdCBub2NrQWRkS2V5Q2hhaW4oY29pbk5hbWUsIDMpO1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBwYXNzcGhyYXNlOiAndGVzdCcsXG4gICAgICAgIGVudGVycHJpc2U6IGVudGVycHJpc2VJZCxcbiAgICAgICAgb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnMTIzNDU2JyxcbiAgICAgIH07XG4gICAgICBjb25zdCB7IHVzZXJLZXljaGFpbiwgYmFja3VwS2V5Y2hhaW4sIGJpdGdvS2V5Y2hhaW4gfSA9IGF3YWl0IHRzc1V0aWxzLmNyZWF0ZUtleWNoYWlucyhwYXJhbXMpO1xuICAgICAgYXNzZXJ0Lm9rKHJvdW5kMU5vY2suaXNEb25lKCkpO1xuICAgICAgYXNzZXJ0Lm9rKHJvdW5kMk5vY2suaXNEb25lKCkpO1xuICAgICAgYXNzZXJ0Lm9rKHJvdW5kM05vY2suaXNEb25lKCkpO1xuICAgICAgYXNzZXJ0Lm9rKGFkZEtleU5vY2suaXNEb25lKCkpO1xuXG4gICAgICBhc3NlcnQub2sodXNlcktleWNoYWluKTtcbiAgICAgIGFzc2VydC5lcXVhbCh1c2VyS2V5Y2hhaW4uc291cmNlLCAndXNlcicpO1xuICAgICAgYXNzZXJ0Lm9rKHVzZXJLZXljaGFpbi5jb21tb25LZXljaGFpbik7XG4gICAgICBhc3NlcnQub2soRUNEU0FVdGlscy5FY2RzYU1QQ3YyVXRpbHMudmFsaWRhdGVDb21tb25LZXljaGFpblB1YmxpY0tleSh1c2VyS2V5Y2hhaW4uY29tbW9uS2V5Y2hhaW4pKTtcbiAgICAgIGFzc2VydC5vayh1c2VyS2V5Y2hhaW4uZW5jcnlwdGVkUHJ2KTtcbiAgICAgIGFzc2VydC5vayhiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHVzZXJLZXljaGFpbi5lbmNyeXB0ZWRQcnYsIHBhc3N3b3JkOiBwYXJhbXMucGFzc3BocmFzZSB9KSk7XG5cbiAgICAgIGFzc2VydC5vayhiYWNrdXBLZXljaGFpbik7XG4gICAgICBhc3NlcnQuZXF1YWwoYmFja3VwS2V5Y2hhaW4uc291cmNlLCAnYmFja3VwJyk7XG4gICAgICBhc3NlcnQub2soYmFja3VwS2V5Y2hhaW4uY29tbW9uS2V5Y2hhaW4pO1xuICAgICAgYXNzZXJ0Lm9rKEVDRFNBVXRpbHMuRWNkc2FNUEN2MlV0aWxzLnZhbGlkYXRlQ29tbW9uS2V5Y2hhaW5QdWJsaWNLZXkoYmFja3VwS2V5Y2hhaW4uY29tbW9uS2V5Y2hhaW4pKTtcbiAgICAgIGFzc2VydC5vayhiYWNrdXBLZXljaGFpbi5lbmNyeXB0ZWRQcnYpO1xuICAgICAgYXNzZXJ0Lm9rKGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogYmFja3VwS2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LCBwYXNzd29yZDogcGFyYW1zLnBhc3NwaHJhc2UgfSkpO1xuXG4gICAgICBhc3NlcnQub2soYml0Z29LZXljaGFpbik7XG4gICAgICBhc3NlcnQuZXF1YWwoYml0Z29LZXljaGFpbi5zb3VyY2UsICdiaXRnbycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBUU1MgTVBDdjIga2V5cyBmb3IgcmV0cm9maXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB4aUxpc3QgPSBbXG4gICAgICAgIEFycmF5LmZyb20oYmlnSW50VG9CdWZmZXJCRShCaWdJbnQoMSksIDMyKSksXG4gICAgICAgIEFycmF5LmZyb20oYmlnSW50VG9CdWZmZXJCRShCaWdJbnQoMiksIDMyKSksXG4gICAgICAgIEFycmF5LmZyb20oYmlnSW50VG9CdWZmZXJCRShCaWdJbnQoMyksIDMyKSksXG4gICAgICBdO1xuICAgICAgY29uc3QgYml0Z29SZXRyb2ZpdERhdGE6IERrbHNUeXBlcy5SZXRyb2ZpdERhdGEgPSB7XG4gICAgICAgIHhpTGlzdCxcbiAgICAgICAgeFNoYXJlOiB2MUZpeHR1cmVzLm1vY2tCaXRHb1NoYXJlU2lnbmluZ01hdGVyaWFsLnhTaGFyZSxcbiAgICAgIH07XG4gICAgICBjb25zdCBiaXRnb1Nlc3Npb24gPSBuZXcgRGtsc0RrZy5Ea2coMywgMiwgRUNEU0FVdGlscy5NUEN2MlBhcnRpZXNFbnVtLkJJVEdPLCB1bmRlZmluZWQsIGJpdGdvUmV0cm9maXREYXRhKTtcblxuICAgICAgY29uc3Qgcm91bmQxTm9jayA9IGF3YWl0IG5vY2tLZXlHZW5Sb3VuZDEoYml0Z29TZXNzaW9uLCAxKTtcbiAgICAgIGNvbnN0IHJvdW5kMk5vY2sgPSBhd2FpdCBub2NrS2V5R2VuUm91bmQyKGJpdGdvU2Vzc2lvbiwgMSk7XG4gICAgICBjb25zdCByb3VuZDNOb2NrID0gYXdhaXQgbm9ja0tleUdlblJvdW5kMyhiaXRnb1Nlc3Npb24sIDEpO1xuICAgICAgY29uc3QgYWRkS2V5Tm9jayA9IGF3YWl0IG5vY2tBZGRLZXlDaGFpbihjb2luTmFtZSwgMyk7XG4gICAgICBjb25zdCBwYXJhbXM6IFBhcmFtZXRlcnM8dHlwZW9mIHRzc1V0aWxzLmNyZWF0ZUtleWNoYWlucz5bMF0gPSB7XG4gICAgICAgIHBhc3NwaHJhc2U6ICd0ZXN0JyxcbiAgICAgICAgZW50ZXJwcmlzZTogZW50ZXJwcmlzZUlkLFxuICAgICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICcxMjM0NTYnLFxuICAgICAgICByZXRyb2ZpdDoge1xuICAgICAgICAgIGRlY3J5cHRlZFVzZXJLZXk6IEpTT04uc3RyaW5naWZ5KHYxRml4dHVyZXMubW9ja1VzZXJTaWduaW5nTWF0ZXJpYWwpLFxuICAgICAgICAgIGRlY3J5cHRlZEJhY2t1cEtleTogSlNPTi5zdHJpbmdpZnkodjFGaXh0dXJlcy5tb2NrQmFja3VwU2lnbmluZ01hdGVyaWFsKSxcbiAgICAgICAgICB3YWxsZXRJZDogJzEyMycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgY29uc3QgeyB1c2VyS2V5Y2hhaW4sIGJhY2t1cEtleWNoYWluLCBiaXRnb0tleWNoYWluIH0gPSBhd2FpdCB0c3NVdGlscy5jcmVhdGVLZXljaGFpbnMocGFyYW1zKTtcbiAgICAgIGFzc2VydC5vayhyb3VuZDFOb2NrLmlzRG9uZSgpKTtcbiAgICAgIGFzc2VydC5vayhyb3VuZDJOb2NrLmlzRG9uZSgpKTtcbiAgICAgIGFzc2VydC5vayhyb3VuZDNOb2NrLmlzRG9uZSgpKTtcbiAgICAgIGFzc2VydC5vayhhZGRLZXlOb2NrLmlzRG9uZSgpKTtcblxuICAgICAgYXNzZXJ0Lm9rKHVzZXJLZXljaGFpbik7XG4gICAgICBhc3NlcnQuZXF1YWwodXNlcktleWNoYWluLnNvdXJjZSwgJ3VzZXInKTtcbiAgICAgIGFzc2VydC5vayh1c2VyS2V5Y2hhaW4uY29tbW9uS2V5Y2hhaW4pO1xuICAgICAgYXNzZXJ0Lm9rKEVDRFNBVXRpbHMuRWNkc2FNUEN2MlV0aWxzLnZhbGlkYXRlQ29tbW9uS2V5Y2hhaW5QdWJsaWNLZXkodXNlcktleWNoYWluLmNvbW1vbktleWNoYWluKSk7XG4gICAgICBhc3NlcnQub2sodXNlcktleWNoYWluLmVuY3J5cHRlZFBydik7XG4gICAgICBhc3NlcnQub2soYml0Z28uZGVjcnlwdCh7IGlucHV0OiB1c2VyS2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LCBwYXNzd29yZDogcGFyYW1zLnBhc3NwaHJhc2UgfSkpO1xuXG4gICAgICBhc3NlcnQub2soYmFja3VwS2V5Y2hhaW4pO1xuICAgICAgYXNzZXJ0LmVxdWFsKGJhY2t1cEtleWNoYWluLnNvdXJjZSwgJ2JhY2t1cCcpO1xuICAgICAgYXNzZXJ0Lm9rKGJhY2t1cEtleWNoYWluLmNvbW1vbktleWNoYWluKTtcbiAgICAgIGFzc2VydC5vayhFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy52YWxpZGF0ZUNvbW1vbktleWNoYWluUHVibGljS2V5KGJhY2t1cEtleWNoYWluLmNvbW1vbktleWNoYWluKSk7XG4gICAgICBhc3NlcnQub2soYmFja3VwS2V5Y2hhaW4uZW5jcnlwdGVkUHJ2KTtcbiAgICAgIGFzc2VydC5vayhiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IGJhY2t1cEtleWNoYWluLmVuY3J5cHRlZFBydiwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzcGhyYXNlIH0pKTtcblxuICAgICAgYXNzZXJ0Lm9rKGJpdGdvS2V5Y2hhaW4pO1xuICAgICAgYXNzZXJ0LmVxdWFsKGJpdGdvS2V5Y2hhaW4uc291cmNlLCAnYml0Z28nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIFRTUyBrZXkgY2hhaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgbm9ja1Byb21pc2VzID0gW1xuICAgICAgICBub2NrS2V5Y2hhaW4oe1xuICAgICAgICAgIGNvaW46IGNvaW5OYW1lLFxuICAgICAgICAgIGtleUNoYWluOiB7IGlkOiAnMScsIHB1YjogJzEnLCB0eXBlOiAndHNzJywgcmVkdWNlZEVuY3J5cHRlZFBydjogJycgfSxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgfSksXG4gICAgICAgIG5vY2tLZXljaGFpbih7XG4gICAgICAgICAgY29pbjogY29pbk5hbWUsXG4gICAgICAgICAga2V5Q2hhaW46IHsgaWQ6ICcyJywgcHViOiAnMicsIHR5cGU6ICd0c3MnLCByZWR1Y2VkRW5jcnlwdGVkUHJ2OiAnJyB9LFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIH0pLFxuICAgICAgICBub2NrS2V5Y2hhaW4oe1xuICAgICAgICAgIGNvaW46IGNvaW5OYW1lLFxuICAgICAgICAgIGtleUNoYWluOiB7IGlkOiAnMycsIHB1YjogJzMnLCB0eXBlOiAndHNzJywgcmVkdWNlZEVuY3J5cHRlZFBydjogJycgfSxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIH0pLFxuICAgICAgXTtcbiAgICAgIGNvbnN0IFtub2NrZWRVc2VyS2V5Y2hhaW4sIG5vY2tlZEJhY2t1cEtleWNoYWluLCBub2NrZWRCaXRHb0tleWNoYWluXSA9IGF3YWl0IFByb21pc2UuYWxsKG5vY2tQcm9taXNlcyk7XG5cbiAgICAgIGNvbnN0IGJpdGdvS2V5Y2hhaW5Qcm9taXNlID0gdHNzVXRpbHMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0uQklUR08sICd0ZXN0Jyk7XG4gICAgICBjb25zdCB1c2Vyc0tleWNoYWluUHJvbWlzZSA9IHRzc1V0aWxzLmNyZWF0ZVBhcnRpY2lwYW50S2V5Y2hhaW4oXG4gICAgICAgIEVDRFNBVXRpbHMuTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgICAgICAndGVzdCcsXG4gICAgICAgIEJ1ZmZlci5mcm9tKCd0ZXN0JyksXG4gICAgICAgIEJ1ZmZlci5mcm9tKCd0ZXN0JyksXG4gICAgICAgICdwYXNzcGhyYXNlJyxcbiAgICAgICAgJ3Rlc3QnXG4gICAgICApO1xuICAgICAgY29uc3QgYmFja3VwS2V5Y2hhaW5Qcm9taXNlID0gdHNzVXRpbHMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgICAgRUNEU0FVdGlscy5NUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCxcbiAgICAgICAgJ3Rlc3QnLFxuICAgICAgICBCdWZmZXIuZnJvbSgndGVzdCcpLFxuICAgICAgICBCdWZmZXIuZnJvbSgndGVzdCcpLFxuICAgICAgICAncGFzc3BocmFzZScsXG4gICAgICAgICd0ZXN0J1xuICAgICAgKTtcblxuICAgICAgY29uc3QgW3VzZXJLZXljaGFpbiwgYmFja3VwS2V5Y2hhaW4sIGJpdGdvS2V5Y2hhaW5dID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICB1c2Vyc0tleWNoYWluUHJvbWlzZSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW5Qcm9taXNlLFxuICAgICAgICBiaXRnb0tleWNoYWluUHJvbWlzZSxcbiAgICAgIF0pO1xuXG4gICAgICAoeyAuLi51c2VyS2V5Y2hhaW4sIHJlZHVjZWRFbmNyeXB0ZWRQcnY6ICcnIH0pLnNob3VsZC5kZWVwRXF1YWwobm9ja2VkVXNlcktleWNoYWluKTtcbiAgICAgICh7IC4uLmJhY2t1cEtleWNoYWluLCByZWR1Y2VkRW5jcnlwdGVkUHJ2OiAnJyB9KS5zaG91bGQuZGVlcEVxdWFsKG5vY2tlZEJhY2t1cEtleWNoYWluKTtcbiAgICAgICh7IC4uLmJpdGdvS2V5Y2hhaW4sIHJlZHVjZWRFbmNyeXB0ZWRQcnY6ICcnIH0pLnNob3VsZC5kZWVwRXF1YWwobm9ja2VkQml0R29LZXljaGFpbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBUU1MgTVBDdjIga2V5IGNoYWlucyB3aXRoIE9WQ3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBNUEN2MlNNQ1V0aWxzID0gbmV3IEVDRFNBVXRpbHMuTVBDdjJTTUNVdGlscyhiaXRnbywgYmFzZUNvaW4pO1xuICAgICAgY29uc3QgYml0Z29TZXNzaW9uID0gbmV3IERrbHNEa2cuRGtnKDMsIDIsIDIpO1xuXG4gICAgICBjb25zdCByb3VuZDFOb2NrID0gYXdhaXQgbm9ja0tleUdlblJvdW5kMShiaXRnb1Nlc3Npb24sIDEpO1xuICAgICAgY29uc3Qgcm91bmQyTm9jayA9IGF3YWl0IG5vY2tLZXlHZW5Sb3VuZDIoYml0Z29TZXNzaW9uLCAxKTtcbiAgICAgIGNvbnN0IHJvdW5kM05vY2sgPSBhd2FpdCBub2NrS2V5R2VuUm91bmQzKGJpdGdvU2Vzc2lvbiwgMSk7XG4gICAgICBjb25zdCBhZGRLZXlOb2NrID0gYXdhaXQgbm9ja0FkZEtleUNoYWluKGNvaW5OYW1lLCAzKTtcblxuICAgICAgLy8gT1ZDIDEgLSBVc2VyIEdQRyBrZXlcbiAgICAgIGNvbnN0IHVzZXJHZ3BLZXkgPSBhd2FpdCBvcGVucGdwLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgdXNlcklEczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICd1c2VyJyxcbiAgICAgICAgICAgIGVtYWlsOiAndXNlckB0ZXN0LmNvbScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgY3VydmU6ICdzZWNwMjU2azEnLFxuICAgICAgfSk7XG4gICAgICBjb25zdCB1c2VyR3BnUHJ2S2V5ID0ge1xuICAgICAgICBwYXJ0eUlkOiAwLFxuICAgICAgICBncGdLZXk6IHVzZXJHZ3BLZXkucHJpdmF0ZUtleSxcbiAgICAgIH07XG5cbiAgICAgIC8vIFJvdW5kIDEgVXNlclxuICAgICAgY29uc3QgdXNlclNlc3Npb24gPSBuZXcgRGtsc0RrZy5Ea2coMywgMiwgMCk7XG4gICAgICBsZXQgT1ZDMVRvT1ZDMlJvdW5kMVBheWxvYWQ6IE9WQzFUb09WQzJSb3VuZDFQYXlsb2FkO1xuICAgICAge1xuICAgICAgICBjb25zdCB1c2VyQnJvYWRjYXN0TXNnMVVuc2lnbmVkID0gYXdhaXQgdXNlclNlc3Npb24uaW5pdERrZygpO1xuICAgICAgICBjb25zdCB1c2VyTXNnczFTaWduZWQgPSBhd2FpdCBEa2xzQ29tbXMuZW5jcnlwdEFuZEF1dGhPdXRnb2luZ01lc3NhZ2VzKFxuICAgICAgICAgIHsgYnJvYWRjYXN0TWVzc2FnZXM6IFtEa2xzVHlwZXMuc2VyaWFsaXplQnJvYWRjYXN0TWVzc2FnZSh1c2VyQnJvYWRjYXN0TXNnMVVuc2lnbmVkKV0sIHAycE1lc3NhZ2VzOiBbXSB9LFxuICAgICAgICAgIFtdLFxuICAgICAgICAgIFt1c2VyR3BnUHJ2S2V5XVxuICAgICAgICApO1xuICAgICAgICBjb25zdCB1c2VyTXNnMSA9IHVzZXJNc2dzMVNpZ25lZC5icm9hZGNhc3RNZXNzYWdlcy5maW5kKChtKSA9PiBtLmZyb20gPT09IDApO1xuICAgICAgICBhc3NlcnQodXNlck1zZzEsICd1c2VyTXNnMSBub3QgZm91bmQnKTtcblxuICAgICAgICBPVkMxVG9PVkMyUm91bmQxUGF5bG9hZCA9IHtcbiAgICAgICAgICB0c3NWZXJzaW9uOiAnMC4wLjEnIGFzIE5vbkVtcHR5U3RyaW5nLFxuICAgICAgICAgIHdhbGxldFR5cGU6IFdhbGxldFR5cGVFbnVtLnRzcyxcbiAgICAgICAgICBjb2luOiAnZXRoJyBhcyBOb25FbXB0eVN0cmluZyxcbiAgICAgICAgICBzdGF0ZTogS2V5Q3JlYXRpb25NUEN2MlN0YXRlRW51bS5XYWl0aW5nRm9yT1ZDMlJvdW5kMURhdGEsXG4gICAgICAgICAgb3ZjOiB7XG4gICAgICAgICAgICBbT1ZDSW5kZXhFbnVtLk9ORV06IHtcbiAgICAgICAgICAgICAgZ3BnUHViS2V5OiB1c2VyR2dwS2V5LnB1YmxpY0tleSBhcyBOb25FbXB0eVN0cmluZyxcbiAgICAgICAgICAgICAgb3ZjTXNnMTogdXNlck1zZzEgYXMgYW55LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBPVkMgMiAtIEJhY2t1cCBHUEcga2V5XG4gICAgICBjb25zdCBiYWNrdXBHZ3BLZXkgPSBhd2FpdCBvcGVucGdwLmdlbmVyYXRlS2V5KHtcbiAgICAgICAgdXNlcklEczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdiYWNrdXAnLFxuICAgICAgICAgICAgZW1haWw6ICdiYWNrdXBAdGVzdC5jb20nLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGN1cnZlOiAnc2VjcDI1NmsxJyxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBiYWNrdXBHcGdQcnZLZXkgPSB7XG4gICAgICAgIHBhcnR5SWQ6IDEsXG4gICAgICAgIGdwZ0tleTogYmFja3VwR2dwS2V5LnByaXZhdGVLZXksXG4gICAgICB9O1xuICAgICAgLy8gUm91bmQgMSBCYWNrdXBcbiAgICAgIGNvbnN0IGJhY2t1cFNlc3Npb24gPSBuZXcgRGtsc0RrZy5Ea2coMywgMiwgMSk7XG4gICAgICBsZXQgT1ZDMlRvQml0Z29Sb3VuZDFQYXlsb2FkOiBPVkMyVG9CaXRnb1JvdW5kMVBheWxvYWQ7XG4gICAgICB7XG4gICAgICAgIGFzc2VydChPVkMxVG9PVkMyUm91bmQxUGF5bG9hZC5zdGF0ZSA9PT0gMCwgJ09WQzFUb09WQzJSb3VuZDFQYXlsb2FkLnN0YXRlIHNob3VsZCBiZSAwJyk7XG4gICAgICAgIGNvbnN0IGJhY2t1cEJyb2FkY2FzdE1zZzFVbnNpZ25lZCA9IGF3YWl0IGJhY2t1cFNlc3Npb24uaW5pdERrZygpO1xuICAgICAgICBjb25zdCBiYWNrdXBNc2dzMVNpZ25lZCA9IGF3YWl0IERrbHNDb21tcy5lbmNyeXB0QW5kQXV0aE91dGdvaW5nTWVzc2FnZXMoXG4gICAgICAgICAgeyBicm9hZGNhc3RNZXNzYWdlczogW0RrbHNUeXBlcy5zZXJpYWxpemVCcm9hZGNhc3RNZXNzYWdlKGJhY2t1cEJyb2FkY2FzdE1zZzFVbnNpZ25lZCldLCBwMnBNZXNzYWdlczogW10gfSxcbiAgICAgICAgICBbXSxcbiAgICAgICAgICBbYmFja3VwR3BnUHJ2S2V5XVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBiYWNrdXBNc2cxID0gYmFja3VwTXNnczFTaWduZWQuYnJvYWRjYXN0TWVzc2FnZXMuZmluZCgobSkgPT4gbS5mcm9tID09PSAxKTtcbiAgICAgICAgYXNzZXJ0KGJhY2t1cE1zZzEsICdiYWNrdXBNc2cxIG5vdCBmb3VuZCcpO1xuXG4gICAgICAgIE9WQzJUb0JpdGdvUm91bmQxUGF5bG9hZCA9IHtcbiAgICAgICAgICAuLi5PVkMxVG9PVkMyUm91bmQxUGF5bG9hZCxcbiAgICAgICAgICBzdGF0ZTogS2V5Q3JlYXRpb25NUEN2MlN0YXRlRW51bS5XYWl0aW5nRm9yQml0Z29Sb3VuZDFEYXRhLFxuICAgICAgICAgIG92Yzoge1xuICAgICAgICAgICAgLi4uT1ZDMVRvT1ZDMlJvdW5kMVBheWxvYWQub3ZjLFxuICAgICAgICAgICAgW09WQ0luZGV4RW51bS5UV09dOiB7XG4gICAgICAgICAgICAgIGdwZ1B1YktleTogYmFja3VwR2dwS2V5LnB1YmxpY0tleSBhcyBOb25FbXB0eVN0cmluZyxcbiAgICAgICAgICAgICAgb3ZjTXNnMTogYmFja3VwTXNnMSBhcyBhbnksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIC8vIFJvdW5kIDEgQml0R29cbiAgICAgIGNvbnN0IGJpdGdvVG9PVkMxUm91bmQxUGF5bG9hZCA9IGF3YWl0IE1QQ3YyU01DVXRpbHMua2V5R2VuUm91bmQxKCd0ZXN0SWQnLCBPVkMyVG9CaXRnb1JvdW5kMVBheWxvYWQpO1xuXG4gICAgICAvLyBSb3VuZCAyIFVzZXJcbiAgICAgIGxldCBPVkMxVG9PVkMyUm91bmQyUGF5bG9hZDogT1ZDMVRvT1ZDMlJvdW5kMlBheWxvYWQ7XG4gICAgICB7XG4gICAgICAgIGFzc2VydChiaXRnb1RvT1ZDMVJvdW5kMVBheWxvYWQuc3RhdGUgPT09IDIsICdiaXRnb1RvT1ZDMVJvdW5kMVBheWxvYWQuc3RhdGUgc2hvdWxkIGJlIDInKTtcbiAgICAgICAgY29uc3QgdG9Vc2VyUm91bmQxQnJvYWRjYXN0TWVzc2FnZXMgPSBhd2FpdCBEa2xzQ29tbXMuZGVjcnlwdEFuZFZlcmlmeUluY29taW5nTWVzc2FnZXMoXG4gICAgICAgICAge1xuICAgICAgICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgICAgICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtcbiAgICAgICAgICAgICAgYml0Z29Ub09WQzFSb3VuZDFQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uVFdPXS5vdmNNc2cxLFxuICAgICAgICAgICAgICBiaXRnb1RvT1ZDMVJvdW5kMVBheWxvYWQucGxhdGZvcm0uYml0Z29Nc2cxLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIFtiaXRnb0dwZ1B1YktleSwgeyBwYXJ0eUlkOiAxLCBncGdLZXk6IGJpdGdvVG9PVkMxUm91bmQxUGF5bG9hZC5vdmNbT1ZDSW5kZXhFbnVtLlRXT10uZ3BnUHViS2V5IH1dLFxuICAgICAgICAgIFt1c2VyR3BnUHJ2S2V5XVxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHVzZXJSb3VuZDJQMlBNZXNzYWdlcyA9IHVzZXJTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICAgICAgICBicm9hZGNhc3RNZXNzYWdlczogdG9Vc2VyUm91bmQxQnJvYWRjYXN0TWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXMubWFwKERrbHNUeXBlcy5kZXNlcmlhbGl6ZUJyb2FkY2FzdE1lc3NhZ2UpLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgdXNlclJvdW5kMk1lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmVuY3J5cHRBbmRBdXRoT3V0Z29pbmdNZXNzYWdlcyhcbiAgICAgICAgICBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXModXNlclJvdW5kMlAyUE1lc3NhZ2VzKSxcbiAgICAgICAgICBbeyBwYXJ0eUlkOiAxLCBncGdLZXk6IGJpdGdvVG9PVkMxUm91bmQxUGF5bG9hZC5vdmNbT1ZDSW5kZXhFbnVtLlRXT10uZ3BnUHViS2V5IH0sIGJpdGdvR3BnUHViS2V5XSxcbiAgICAgICAgICBbdXNlckdwZ1BydktleV1cbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgdXNlclRvQmFja3VwTXNnMiA9IHVzZXJSb3VuZDJNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgICAgIChtKSA9PiBtLmZyb20gPT09IEVDRFNBVXRpbHMuTVBDdjJQYXJ0aWVzRW51bS5VU0VSICYmIG0udG8gPT09IEVDRFNBVXRpbHMuTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVBcbiAgICAgICAgKTtcbiAgICAgICAgYXNzZXJ0KHVzZXJUb0JhY2t1cE1zZzIsICd1c2VyVG9CYWNrdXBNc2cyIG5vdCBmb3VuZCcpO1xuICAgICAgICBjb25zdCB1c2VyVG9CaXRnb01zZzIgPSB1c2VyUm91bmQyTWVzc2FnZXMucDJwTWVzc2FnZXMuZmluZChcbiAgICAgICAgICAobSkgPT4gbS5mcm9tID09PSBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0uVVNFUiAmJiBtLnRvID09PSBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0uQklUR09cbiAgICAgICAgKTtcbiAgICAgICAgYXNzZXJ0KHVzZXJUb0JpdGdvTXNnMiwgJ3VzZXJUb0JpdGdvTXNnMiBub3QgZm91bmQnKTtcblxuICAgICAgICBPVkMxVG9PVkMyUm91bmQyUGF5bG9hZCA9IHtcbiAgICAgICAgICAuLi5iaXRnb1RvT1ZDMVJvdW5kMVBheWxvYWQsXG4gICAgICAgICAgc3RhdGU6IEtleUNyZWF0aW9uTVBDdjJTdGF0ZUVudW0uV2FpdGluZ0Zvck9WQzJSb3VuZDJEYXRhLFxuICAgICAgICAgIG92Yzoge1xuICAgICAgICAgICAgLi4uYml0Z29Ub09WQzFSb3VuZDFQYXlsb2FkLm92YyxcbiAgICAgICAgICAgIFtPVkNJbmRleEVudW0uT05FXTogT2JqZWN0LmFzc2lnbihiaXRnb1RvT1ZDMVJvdW5kMVBheWxvYWQub3ZjW09WQ0luZGV4RW51bS5PTkVdLCB7XG4gICAgICAgICAgICAgIG92Y1RvQml0Z29Nc2cyOiB1c2VyVG9CaXRnb01zZzIsXG4gICAgICAgICAgICAgIG92Y1RvT3ZjTXNnMjogdXNlclRvQmFja3VwTXNnMixcbiAgICAgICAgICAgIH0pIGFzIGFueSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBSb3VuZCAyIEJhY2t1cFxuICAgICAgbGV0IE9WQzJUb0JpdGdvUm91bmQyUGF5bG9hZDogT1ZDMlRvQml0Z29Sb3VuZDJQYXlsb2FkO1xuXG4gICAgICB7XG4gICAgICAgIGFzc2VydChPVkMxVG9PVkMyUm91bmQyUGF5bG9hZC5zdGF0ZSA9PT0gMywgJ2JpdGdvVG9PVkMxUm91bmQxUGF5bG9hZC5zdGF0ZSBzaG91bGQgYmUgMycpO1xuICAgICAgICBjb25zdCB0b0JhY2t1cFJvdW5kMUJyb2FkY2FzdE1lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmRlY3J5cHRBbmRWZXJpZnlJbmNvbWluZ01lc3NhZ2VzKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICAgICAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXG4gICAgICAgICAgICAgIGJpdGdvVG9PVkMxUm91bmQxUGF5bG9hZC5vdmNbT1ZDSW5kZXhFbnVtLk9ORV0ub3ZjTXNnMSxcbiAgICAgICAgICAgICAgYml0Z29Ub09WQzFSb3VuZDFQYXlsb2FkLnBsYXRmb3JtLmJpdGdvTXNnMSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBbYml0Z29HcGdQdWJLZXksIHsgcGFydHlJZDogMCwgZ3BnS2V5OiBPVkMxVG9PVkMyUm91bmQyUGF5bG9hZC5vdmNbT1ZDSW5kZXhFbnVtLk9ORV0uZ3BnUHViS2V5IH1dLFxuICAgICAgICAgIFtiYWNrdXBHcGdQcnZLZXldXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgYmFja3VwUm91bmQyUDJQTWVzc2FnZXMgPSBiYWNrdXBTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICAgICAgICBicm9hZGNhc3RNZXNzYWdlczogdG9CYWNrdXBSb3VuZDFCcm9hZGNhc3RNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcy5tYXAoXG4gICAgICAgICAgICBEa2xzVHlwZXMuZGVzZXJpYWxpemVCcm9hZGNhc3RNZXNzYWdlXG4gICAgICAgICAgKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGJhY2t1cFJvdW5kMk1lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmVuY3J5cHRBbmRBdXRoT3V0Z29pbmdNZXNzYWdlcyhcbiAgICAgICAgICBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXMoYmFja3VwUm91bmQyUDJQTWVzc2FnZXMpLFxuICAgICAgICAgIFt7IHBhcnR5SWQ6IDAsIGdwZ0tleTogYml0Z29Ub09WQzFSb3VuZDFQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uT05FXS5ncGdQdWJLZXkgfSwgYml0Z29HcGdQdWJLZXldLFxuICAgICAgICAgIFtiYWNrdXBHcGdQcnZLZXldXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGJhY2t1cFRvVXNlck1zZzIgPSBiYWNrdXBSb3VuZDJNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgICAgIChtKSA9PiBtLmZyb20gPT09IEVDRFNBVXRpbHMuTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAgJiYgbS50byA9PT0gRUNEU0FVdGlscy5NUEN2MlBhcnRpZXNFbnVtLlVTRVJcbiAgICAgICAgKTtcbiAgICAgICAgYXNzZXJ0KGJhY2t1cFRvVXNlck1zZzIsICdiYWNrdXBUb1VzZXJNc2cyIG5vdCBmb3VuZCcpO1xuICAgICAgICBjb25zdCBiYWNrdXBUb0JpdGdvTXNnMiA9IGJhY2t1cFJvdW5kMk1lc3NhZ2VzLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAgICAgKG0pID0+IG0uZnJvbSA9PT0gRUNEU0FVdGlscy5NUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCAmJiBtLnRvID09PSBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0uQklUR09cbiAgICAgICAgKTtcbiAgICAgICAgYXNzZXJ0KGJhY2t1cFRvQml0Z29Nc2cyLCAnYmFja3VwVG9CaXRnb01zZzIgbm90IGZvdW5kJyk7XG5cbiAgICAgICAgT1ZDMlRvQml0Z29Sb3VuZDJQYXlsb2FkID0ge1xuICAgICAgICAgIC4uLk9WQzFUb09WQzJSb3VuZDJQYXlsb2FkLFxuICAgICAgICAgIHN0YXRlOiBLZXlDcmVhdGlvbk1QQ3YyU3RhdGVFbnVtLldhaXRpbmdGb3JCaXRnb1JvdW5kMkRhdGEsXG4gICAgICAgICAgb3ZjOiB7XG4gICAgICAgICAgICAuLi5PVkMxVG9PVkMyUm91bmQyUGF5bG9hZC5vdmMsXG4gICAgICAgICAgICBbT1ZDSW5kZXhFbnVtLlRXT106IE9iamVjdC5hc3NpZ24oT1ZDMVRvT1ZDMlJvdW5kMlBheWxvYWQub3ZjW09WQ0luZGV4RW51bS5UV09dLCB7XG4gICAgICAgICAgICAgIG92Y1RvQml0Z29Nc2cyOiBiYWNrdXBUb0JpdGdvTXNnMixcbiAgICAgICAgICAgICAgb3ZjVG9PdmNNc2cyOiBiYWNrdXBUb1VzZXJNc2cyLFxuICAgICAgICAgICAgfSkgYXMgYW55LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIC8vIFJvdW5kIDIgQml0R29cbiAgICAgIC8vIGNhbGwgYml0Z28gcm91bmQgMlxuICAgICAgY29uc3QgYml0Z29Ub09WQzFSb3VuZDJQYXlsb2FkID0gYXdhaXQgTVBDdjJTTUNVdGlscy5rZXlHZW5Sb3VuZDIoJ3Rlc3RJZCcsIE9WQzJUb0JpdGdvUm91bmQyUGF5bG9hZCk7XG5cbiAgICAgIC8vIFJvdW5kIDNBIFVzZXJcbiAgICAgIGxldCBPVkMxVG9PVkMyUm91bmQzUGF5bG9hZDogT1ZDMVRvT1ZDMlJvdW5kM1BheWxvYWQ7XG4gICAgICB7XG4gICAgICAgIGFzc2VydChiaXRnb1RvT1ZDMVJvdW5kMlBheWxvYWQuc3RhdGUgPT09IDUsICdiaXRnb1RvT1ZDMVJvdW5kMlBheWxvYWQuc3RhdGUgc2hvdWxkIGJlIDUnKTtcbiAgICAgICAgY29uc3QgdG9Vc2VyUm91bmQyUDJQTWVzc2FnZXMgPSBhd2FpdCBEa2xzQ29tbXMuZGVjcnlwdEFuZFZlcmlmeUluY29taW5nTWVzc2FnZXMoXG4gICAgICAgICAge1xuICAgICAgICAgICAgcDJwTWVzc2FnZXM6IFtcbiAgICAgICAgICAgICAgYml0Z29Ub09WQzFSb3VuZDJQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uVFdPXS5vdmNUb092Y01zZzIsXG4gICAgICAgICAgICAgIGJpdGdvVG9PVkMxUm91bmQyUGF5bG9hZC5wbGF0Zm9ybS5vdmNbT1ZDSW5kZXhFbnVtLk9ORV0uYml0Z29Ub092Y01zZzIsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgW2JpdGdvR3BnUHViS2V5LCB7IHBhcnR5SWQ6IDEsIGdwZ0tleTogYml0Z29Ub09WQzFSb3VuZDJQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uVFdPXS5ncGdQdWJLZXkgfV0sXG4gICAgICAgICAgW3VzZXJHcGdQcnZLZXldXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHVzZXJSb3VuZDNBUDJQTWVzc2FnZXMgPSB1c2VyU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgICAgICBwMnBNZXNzYWdlczogdG9Vc2VyUm91bmQyUDJQTWVzc2FnZXMucDJwTWVzc2FnZXMubWFwKERrbHNUeXBlcy5kZXNlcmlhbGl6ZVAyUE1lc3NhZ2UpLFxuICAgICAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICAgICAgfSkucDJwTWVzc2FnZXM7XG5cbiAgICAgICAgY29uc3QgdXNlclJvdW5kM0FNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5lbmNyeXB0QW5kQXV0aE91dGdvaW5nTWVzc2FnZXMoXG4gICAgICAgICAgRGtsc1R5cGVzLnNlcmlhbGl6ZU1lc3NhZ2VzKHtcbiAgICAgICAgICAgIHAycE1lc3NhZ2VzOiB1c2VyUm91bmQzQVAyUE1lc3NhZ2VzLFxuICAgICAgICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIFt7IHBhcnR5SWQ6IDEsIGdwZ0tleTogYml0Z29Ub09WQzFSb3VuZDJQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uVFdPXS5ncGdQdWJLZXkgfSwgYml0Z29HcGdQdWJLZXldLFxuICAgICAgICAgIFt1c2VyR3BnUHJ2S2V5XVxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHVzZXJUb0JpdGdvTXNnMyA9IHVzZXJSb3VuZDNBTWVzc2FnZXMucDJwTWVzc2FnZXMuZmluZChcbiAgICAgICAgICAobSkgPT4gbS5mcm9tID09PSBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0uVVNFUiAmJiBtLnRvID09PSBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0uQklUR09cbiAgICAgICAgKTtcbiAgICAgICAgYXNzZXJ0KHVzZXJUb0JpdGdvTXNnMywgJ3VzZXJUb0JpdGdvTXNnMyBub3QgZm91bmQnKTtcbiAgICAgICAgY29uc3QgdXNlclRvQmFja3VwTXNnMyA9IHVzZXJSb3VuZDNBTWVzc2FnZXMucDJwTWVzc2FnZXMuZmluZChcbiAgICAgICAgICAobSkgPT4gbS5mcm9tID09PSBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0uVVNFUiAmJiBtLnRvID09PSBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0uQkFDS1VQXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydCh1c2VyVG9CYWNrdXBNc2czLCAndXNlclRvQmFja3VwTXNnMyBub3QgZm91bmQnKTtcblxuICAgICAgICBPVkMxVG9PVkMyUm91bmQzUGF5bG9hZCA9IHtcbiAgICAgICAgICAuLi5iaXRnb1RvT1ZDMVJvdW5kMlBheWxvYWQsXG4gICAgICAgICAgc3RhdGU6IEtleUNyZWF0aW9uTVBDdjJTdGF0ZUVudW0uV2FpdGluZ0Zvck9WQzJSb3VuZDNEYXRhLFxuICAgICAgICAgIG92Yzoge1xuICAgICAgICAgICAgLi4uYml0Z29Ub09WQzFSb3VuZDJQYXlsb2FkLm92YyxcbiAgICAgICAgICAgIFtPVkNJbmRleEVudW0uT05FXTogT2JqZWN0LmFzc2lnbihiaXRnb1RvT1ZDMVJvdW5kMlBheWxvYWQub3ZjW09WQ0luZGV4RW51bS5PTkVdLCB7XG4gICAgICAgICAgICAgIG92Y1RvQml0Z29Nc2czOiB1c2VyVG9CaXRnb01zZzMsXG4gICAgICAgICAgICAgIG92Y1RvT3ZjTXNnMzogdXNlclRvQmFja3VwTXNnMyxcbiAgICAgICAgICAgIH0pIGFzIGFueSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBSb3VuZCAzIEJhY2t1cFxuICAgICAgbGV0IE9WQzJUb09WQzFSb3VuZDNQYXlsb2FkOiBPVkMyVG9PVkMxUm91bmQzUGF5bG9hZDtcbiAgICAgIHtcbiAgICAgICAgYXNzZXJ0KE9WQzFUb09WQzJSb3VuZDNQYXlsb2FkLnN0YXRlID09PSA2LCAnT1ZDMVRvT1ZDMlJvdW5kM1BheWxvYWQuc3RhdGUgc2hvdWxkIGJlIDYnKTtcbiAgICAgICAgY29uc3QgdG9CYWNrdXBSb3VuZDNQMlBNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBwMnBNZXNzYWdlczogW1xuICAgICAgICAgICAgICBPVkMxVG9PVkMyUm91bmQzUGF5bG9hZC5vdmNbT1ZDSW5kZXhFbnVtLk9ORV0ub3ZjVG9PdmNNc2cyLFxuICAgICAgICAgICAgICBPVkMxVG9PVkMyUm91bmQzUGF5bG9hZC5wbGF0Zm9ybS5vdmNbT1ZDSW5kZXhFbnVtLlRXT10uYml0Z29Ub092Y01zZzIsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgW2JpdGdvR3BnUHViS2V5LCB7IHBhcnR5SWQ6IDAsIGdwZ0tleTogT1ZDMVRvT1ZDMlJvdW5kM1BheWxvYWQub3ZjW09WQ0luZGV4RW51bS5PTkVdLmdwZ1B1YktleSB9XSxcbiAgICAgICAgICBbYmFja3VwR3BnUHJ2S2V5XVxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGJhY2t1cFJvdW5kM1AyUE1lc3NhZ2VzID0gYmFja3VwU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgICAgICBwMnBNZXNzYWdlczogdG9CYWNrdXBSb3VuZDNQMlBNZXNzYWdlcy5wMnBNZXNzYWdlcy5tYXAoRGtsc1R5cGVzLmRlc2VyaWFsaXplUDJQTWVzc2FnZSksXG4gICAgICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBiYWNrdXBSb3VuZDNNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5lbmNyeXB0QW5kQXV0aE91dGdvaW5nTWVzc2FnZXMoXG4gICAgICAgICAgRGtsc1R5cGVzLnNlcmlhbGl6ZU1lc3NhZ2VzKGJhY2t1cFJvdW5kM1AyUE1lc3NhZ2VzKSxcbiAgICAgICAgICBbeyBwYXJ0eUlkOiAwLCBncGdLZXk6IE9WQzFUb09WQzJSb3VuZDNQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uT05FXS5ncGdQdWJLZXkgfSwgYml0Z29HcGdQdWJLZXldLFxuICAgICAgICAgIFtiYWNrdXBHcGdQcnZLZXldXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgYmFja3VwVG9CaXRnb01zZzMgPSBiYWNrdXBSb3VuZDNNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgICAgIChtKSA9PiBtLmZyb20gPT09IEVDRFNBVXRpbHMuTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAgJiYgbS50byA9PT0gRUNEU0FVdGlscy5NUEN2MlBhcnRpZXNFbnVtLkJJVEdPXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydChiYWNrdXBUb0JpdGdvTXNnMywgJ2JhY2t1cFRvQml0Z29Nc2czIG5vdCBmb3VuZCcpO1xuICAgICAgICBjb25zdCBiYWNrdXBUb1VzZXJNc2czID0gYmFja3VwUm91bmQzTWVzc2FnZXMucDJwTWVzc2FnZXMuZmluZChcbiAgICAgICAgICAobSkgPT4gbS5mcm9tID09PSBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0uQkFDS1VQICYmIG0udG8gPT09IEVDRFNBVXRpbHMuTVBDdjJQYXJ0aWVzRW51bS5VU0VSXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydChiYWNrdXBUb1VzZXJNc2czLCAnYmFja3VwVG9Vc2VyTXNnMyBub3QgZm91bmQnKTtcblxuICAgICAgICBjb25zdCB0b0JhY2t1cFJvdW5kM01lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmRlY3J5cHRBbmRWZXJpZnlJbmNvbWluZ01lc3NhZ2VzKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHAycE1lc3NhZ2VzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi5PVkMxVG9PVkMyUm91bmQzUGF5bG9hZC5vdmNbT1ZDSW5kZXhFbnVtLk9ORV0ub3ZjVG9PdmNNc2czLFxuICAgICAgICAgICAgICAgIGNvbW1pdG1lbnQ6IE9WQzFUb09WQzJSb3VuZDNQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uT05FXS5vdmNUb092Y01zZzIuY29tbWl0bWVudCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC4uLk9WQzFUb09WQzJSb3VuZDNQYXlsb2FkLnBsYXRmb3JtLm92Y1tPVkNJbmRleEVudW0uVFdPXS5iaXRnb1RvT3ZjTXNnMyxcbiAgICAgICAgICAgICAgICBjb21taXRtZW50OiBPVkMxVG9PVkMyUm91bmQzUGF5bG9hZC5wbGF0Zm9ybS5iaXRnb0NvbW1pdG1lbnQyLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIFtiaXRnb0dwZ1B1YktleSwgeyBwYXJ0eUlkOiAwLCBncGdLZXk6IE9WQzFUb09WQzJSb3VuZDNQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uT05FXS5ncGdQdWJLZXkgfV0sXG4gICAgICAgICAgW2JhY2t1cEdwZ1BydktleV1cbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBiYWNrdXBSb3VuZDRNZXNzYWdlcyA9IGJhY2t1cFNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICAgICAgcDJwTWVzc2FnZXM6IHRvQmFja3VwUm91bmQzTWVzc2FnZXMucDJwTWVzc2FnZXMubWFwKERrbHNUeXBlcy5kZXNlcmlhbGl6ZVAyUE1lc3NhZ2UpLFxuICAgICAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICAgICAgfSkuYnJvYWRjYXN0TWVzc2FnZXM7XG5cbiAgICAgICAgY29uc3QgYmFja3VwUm91bmQ0QnJvYWRjYXN0TWVzc2FnZXMgPSBhd2FpdCBEa2xzQ29tbXMuZW5jcnlwdEFuZEF1dGhPdXRnb2luZ01lc3NhZ2VzKFxuICAgICAgICAgIERrbHNUeXBlcy5zZXJpYWxpemVNZXNzYWdlcyh7XG4gICAgICAgICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICAgICAgICBicm9hZGNhc3RNZXNzYWdlczogYmFja3VwUm91bmQ0TWVzc2FnZXMsXG4gICAgICAgICAgfSksXG4gICAgICAgICAgW10sXG4gICAgICAgICAgW2JhY2t1cEdwZ1BydktleV1cbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBiYWNrdXBNc2c0ID0gYmFja3VwUm91bmQ0QnJvYWRjYXN0TWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXMuZmluZChcbiAgICAgICAgICAobSkgPT4gbS5mcm9tID09PSBFQ0RTQVV0aWxzLk1QQ3YyUGFydGllc0VudW0uQkFDS1VQXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydChiYWNrdXBNc2c0LCAnYmFja3VwTXNnNCBub3QgZm91bmQnKTtcblxuICAgICAgICBPVkMyVG9PVkMxUm91bmQzUGF5bG9hZCA9IHtcbiAgICAgICAgICAuLi5PVkMxVG9PVkMyUm91bmQzUGF5bG9hZCxcbiAgICAgICAgICBzdGF0ZTogS2V5Q3JlYXRpb25NUEN2MlN0YXRlRW51bS5XYWl0aW5nRm9yT1ZDMVJvdW5kM2JEYXRhLFxuICAgICAgICAgIG92Yzoge1xuICAgICAgICAgICAgLi4uT1ZDMVRvT1ZDMlJvdW5kM1BheWxvYWQub3ZjLFxuICAgICAgICAgICAgW09WQ0luZGV4RW51bS5UV09dOiBPYmplY3QuYXNzaWduKE9WQzFUb09WQzJSb3VuZDNQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uVFdPXSwge1xuICAgICAgICAgICAgICBvdmNUb092Y01zZzM6IGJhY2t1cFRvVXNlck1zZzMsXG4gICAgICAgICAgICAgIG92Y1RvQml0Z29Nc2czOiBiYWNrdXBUb0JpdGdvTXNnMyxcbiAgICAgICAgICAgICAgb3ZjTXNnNDogYmFja3VwTXNnNCxcbiAgICAgICAgICAgIH0pIGFzIGFueSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBSb3VuZCAzQiBVc2VyXG4gICAgICBsZXQgT1ZDMVRvQml0Z29Sb3VuZDNCUGF5bG9hZDogT1ZDMVRvQml0Z29Sb3VuZDNQYXlsb2FkO1xuICAgICAge1xuICAgICAgICBhc3NlcnQoT1ZDMlRvT1ZDMVJvdW5kM1BheWxvYWQuc3RhdGUgPT09IDcsICdPVkMyVG9PVkMxUm91bmQzUGF5bG9hZC5zdGF0ZSBzaG91bGQgYmUgNycpO1xuICAgICAgICBjb25zdCB0b1VzZXJSb3VuZDRNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBwMnBNZXNzYWdlczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgLi4uT1ZDMlRvT1ZDMVJvdW5kM1BheWxvYWQub3ZjW09WQ0luZGV4RW51bS5UV09dLm92Y1RvT3ZjTXNnMyxcbiAgICAgICAgICAgICAgICBjb21taXRtZW50OiBPVkMyVG9PVkMxUm91bmQzUGF5bG9hZC5vdmNbT1ZDSW5kZXhFbnVtLlRXT10ub3ZjVG9PdmNNc2cyLmNvbW1pdG1lbnQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi5PVkMyVG9PVkMxUm91bmQzUGF5bG9hZC5wbGF0Zm9ybS5vdmNbT1ZDSW5kZXhFbnVtLk9ORV0uYml0Z29Ub092Y01zZzMsXG4gICAgICAgICAgICAgICAgY29tbWl0bWVudDogT1ZDMlRvT1ZDMVJvdW5kM1BheWxvYWQucGxhdGZvcm0uYml0Z29Db21taXRtZW50MixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBbYml0Z29HcGdQdWJLZXksIHsgcGFydHlJZDogMSwgZ3BnS2V5OiBPVkMyVG9PVkMxUm91bmQzUGF5bG9hZC5vdmNbT1ZDSW5kZXhFbnVtLlRXT10uZ3BnUHViS2V5IH1dLFxuICAgICAgICAgIFt1c2VyR3BnUHJ2S2V5XVxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHVzZXJSb3VuZDRCcm9hZGNhc3RNZXNzYWdlcyA9IHVzZXJTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgICAgIHAycE1lc3NhZ2VzOiB0b1VzZXJSb3VuZDRNZXNzYWdlcy5wMnBNZXNzYWdlcy5tYXAoRGtsc1R5cGVzLmRlc2VyaWFsaXplUDJQTWVzc2FnZSksXG4gICAgICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgICAgICB9KS5icm9hZGNhc3RNZXNzYWdlcztcbiAgICAgICAgYXNzZXJ0KHVzZXJSb3VuZDRCcm9hZGNhc3RNZXNzYWdlcy5sZW5ndGggPT09IDEsICd1c2VyUm91bmQ0QnJvYWRjYXN0TWVzc2FnZXMgbGVuZ3RoIHNob3VsZCBiZSAxJyk7XG5cbiAgICAgICAgY29uc3QgdXNlclJvdW5kNE1lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmVuY3J5cHRBbmRBdXRoT3V0Z29pbmdNZXNzYWdlcyhcbiAgICAgICAgICBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXMoe1xuICAgICAgICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgICAgICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IHVzZXJSb3VuZDRCcm9hZGNhc3RNZXNzYWdlcyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBbXSxcbiAgICAgICAgICBbdXNlckdwZ1BydktleV1cbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCB1c2VyTXNnNCA9IHVzZXJSb3VuZDRNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcy5maW5kKChtKSA9PiBtLmZyb20gPT09IEVDRFNBVXRpbHMuTVBDdjJQYXJ0aWVzRW51bS5VU0VSKTtcbiAgICAgICAgYXNzZXJ0KHVzZXJNc2c0LCAndXNlck1zZzQgbm90IGZvdW5kJyk7XG5cbiAgICAgICAgT1ZDMVRvQml0Z29Sb3VuZDNCUGF5bG9hZCA9IHtcbiAgICAgICAgICAuLi5PVkMyVG9PVkMxUm91bmQzUGF5bG9hZCxcbiAgICAgICAgICBzdGF0ZTogS2V5Q3JlYXRpb25NUEN2MlN0YXRlRW51bS5XYWl0aW5nRm9yQml0Z29Sb3VuZDNEYXRhLFxuICAgICAgICAgIG92Yzoge1xuICAgICAgICAgICAgLi4uT1ZDMlRvT1ZDMVJvdW5kM1BheWxvYWQub3ZjLFxuICAgICAgICAgICAgW09WQ0luZGV4RW51bS5PTkVdOiBPYmplY3QuYXNzaWduKE9WQzJUb09WQzFSb3VuZDNQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uT05FXSwge1xuICAgICAgICAgICAgICBvdmNNc2c0OiB1c2VyTXNnNCxcbiAgICAgICAgICAgIH0pIGFzIGFueSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBSb3VuZCAzIEJpdEdvXG4gICAgICAvLyBjcmVhdGVzIGJpdGdvIGtleWNoYWluXG4gICAgICBjb25zdCBiaXRnb1RvT1ZDMVJvdW5kM1BheWxvYWQgPSBhd2FpdCBNUEN2MlNNQ1V0aWxzLmtleUdlblJvdW5kMygndGVzdElkJywgT1ZDMVRvQml0Z29Sb3VuZDNCUGF5bG9hZCk7XG5cbiAgICAgIC8vIFJvdW5kIDQgVXNlclxuICAgICAgbGV0IHVzZXJDb21tb25LZXljaGFpbjogc3RyaW5nO1xuICAgICAgbGV0IE9WQzFUb09WQzJSb3VuZDRQYXlsb2FkO1xuICAgICAge1xuICAgICAgICBhc3NlcnQoYml0Z29Ub09WQzFSb3VuZDNQYXlsb2FkLnN0YXRlID09PSA5LCAnYml0Z29Ub09WQzFSb3VuZDNQYXlsb2FkLnN0YXRlIHNob3VsZCBiZSA5Jyk7XG4gICAgICAgIGFzc2VydChiaXRnb1RvT1ZDMVJvdW5kM1BheWxvYWQuYml0R29LZXlJZCwgJ2JpdGdvVG9PVkMxUm91bmQzUGF5bG9hZC5iaXRHb0tleUlkIG5vdCBmb3VuZCcpO1xuICAgICAgICBjb25zdCB0b1VzZXJCaXRnb1JvdW5kM01zZyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICAgICAgICBicm9hZGNhc3RNZXNzYWdlczogW1xuICAgICAgICAgICAgICBiaXRnb1RvT1ZDMVJvdW5kM1BheWxvYWQub3ZjW09WQ0luZGV4RW51bS5UV09dLm92Y01zZzQsXG4gICAgICAgICAgICAgIGJpdGdvVG9PVkMxUm91bmQzUGF5bG9hZC5wbGF0Zm9ybS5iaXRnb01zZzQsXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgW2JpdGdvR3BnUHViS2V5LCB7IHBhcnR5SWQ6IDEsIGdwZ0tleTogYml0Z29Ub09WQzFSb3VuZDNQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uVFdPXS5ncGdQdWJLZXkgfV0sXG4gICAgICAgICAgW3VzZXJHcGdQcnZLZXldXG4gICAgICAgICk7XG5cbiAgICAgICAgdXNlclNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgICAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiB0b1VzZXJCaXRnb1JvdW5kM01zZy5icm9hZGNhc3RNZXNzYWdlcy5tYXAoRGtsc1R5cGVzLmRlc2VyaWFsaXplQnJvYWRjYXN0TWVzc2FnZSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHVzZXJQcml2YXRlTWF0ZXJpYWwgPSB1c2VyU2Vzc2lvbi5nZXRLZXlTaGFyZSgpO1xuICAgICAgICB1c2VyQ29tbW9uS2V5Y2hhaW4gPSBEa2xzVHlwZXMuZ2V0Q29tbW9uS2V5Y2hhaW4odXNlclByaXZhdGVNYXRlcmlhbCk7XG4gICAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgICBiaXRnb1RvT1ZDMVJvdW5kM1BheWxvYWQucGxhdGZvcm0uY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdXNlckNvbW1vbktleWNoYWluLFxuICAgICAgICAgICdVc2VyIGFuZCBCaXRnbyBDb21tb24ga2V5Y2hhaW5zIGRvIG5vdCBtYXRjaCdcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgdXNlclBydiA9IHVzZXJQcml2YXRlTWF0ZXJpYWwudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgICAgICBhc3NlcnQodXNlclBydiwgJ3VzZXJQcnYgbm90IGZvdW5kJyk7XG5cbiAgICAgICAgT1ZDMVRvT1ZDMlJvdW5kNFBheWxvYWQgPSB7XG4gICAgICAgICAgYml0Z29LZXlJZDogYml0Z29Ub09WQzFSb3VuZDNQYXlsb2FkLmJpdEdvS2V5SWQsXG4gICAgICAgICAgLi4uYml0Z29Ub09WQzFSb3VuZDNQYXlsb2FkLFxuICAgICAgICAgIHN0YXRlOiBLZXlDcmVhdGlvbk1QQ3YyU3RhdGVFbnVtLldhaXRpbmdGb3JPVkMyR2VuZXJhdGVLZXksXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIC8vIFJvdW5kIDQgQmFja3VwXG4gICAgICBsZXQgYmFja3VwQ29tbW9uS2V5Y2hhaW46IHN0cmluZztcbiAgICAgIHtcbiAgICAgICAgYXNzZXJ0KE9WQzFUb09WQzJSb3VuZDRQYXlsb2FkLnN0YXRlID09PSAxMCwgJ09WQzFUb09WQzJSb3VuZDRQYXlsb2FkLnN0YXRlIHNob3VsZCBiZSAxMCcpO1xuICAgICAgICBhc3NlcnQoT1ZDMVRvT1ZDMlJvdW5kNFBheWxvYWQuYml0Z29LZXlJZCwgJ09WQzFUb09WQzJSb3VuZDRQYXlsb2FkLmJpdEdvS2V5SWQgbm90IGZvdW5kJyk7XG5cbiAgICAgICAgY29uc3QgdG9CYWNrdXBCaXRnb1JvdW5kM01zZyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICAgICAgICBicm9hZGNhc3RNZXNzYWdlczogW1xuICAgICAgICAgICAgICBPVkMxVG9PVkMyUm91bmQ0UGF5bG9hZC5vdmNbT1ZDSW5kZXhFbnVtLk9ORV0ub3ZjTXNnNCxcbiAgICAgICAgICAgICAgT1ZDMVRvT1ZDMlJvdW5kNFBheWxvYWQucGxhdGZvcm0uYml0Z29Nc2c0LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIFtiaXRnb0dwZ1B1YktleSwgeyBwYXJ0eUlkOiAwLCBncGdLZXk6IE9WQzFUb09WQzJSb3VuZDRQYXlsb2FkLm92Y1tPVkNJbmRleEVudW0uT05FXS5ncGdQdWJLZXkgfV0sXG4gICAgICAgICAgW2JhY2t1cEdwZ1BydktleV1cbiAgICAgICAgKTtcblxuICAgICAgICBiYWNrdXBTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICAgICAgICBicm9hZGNhc3RNZXNzYWdlczogdG9CYWNrdXBCaXRnb1JvdW5kM01zZy5icm9hZGNhc3RNZXNzYWdlcy5tYXAoRGtsc1R5cGVzLmRlc2VyaWFsaXplQnJvYWRjYXN0TWVzc2FnZSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGJhY2t1cFByaXZhdGVNYXRlcmlhbCA9IGJhY2t1cFNlc3Npb24uZ2V0S2V5U2hhcmUoKTtcbiAgICAgICAgYmFja3VwQ29tbW9uS2V5Y2hhaW4gPSBEa2xzVHlwZXMuZ2V0Q29tbW9uS2V5Y2hhaW4oYmFja3VwUHJpdmF0ZU1hdGVyaWFsKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIE9WQzFUb09WQzJSb3VuZDRQYXlsb2FkLnBsYXRmb3JtLmNvbW1vbktleWNoYWluLFxuICAgICAgICAgIGJhY2t1cENvbW1vbktleWNoYWluLFxuICAgICAgICAgICdCYWNrdXAgYW5kIEJpdGdvIENvbW1vbiBrZXljaGFpbnMgZG8gbm90IG1hdGNoJ1xuICAgICAgICApO1xuICAgICAgICBjb25zdCBiYWNrdXBQcnYgPSBiYWNrdXBQcml2YXRlTWF0ZXJpYWwudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgICAgICBhc3NlcnQoYmFja3VwUHJ2LCAnYmFja3VwUHJ2IG5vdCBmb3VuZCcpO1xuICAgICAgfVxuXG4gICAgICAvLyBSb3VuZCA0IEJpdEdvXG4gICAgICAvLyBjcmVhdGVzIHVzZXIgYW5kIGJhY2t1cCBrZXljaGFpblxuICAgICAgY29uc3Qga2V5Y2hhaW5zID0gYXdhaXQgTVBDdjJTTUNVdGlscy51cGxvYWRDbGllbnRLZXlzKFxuICAgICAgICBiaXRnb1RvT1ZDMVJvdW5kM1BheWxvYWQuYml0R29LZXlJZCxcbiAgICAgICAgdXNlckNvbW1vbktleWNoYWluLFxuICAgICAgICBiYWNrdXBDb21tb25LZXljaGFpblxuICAgICAgKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoa2V5Y2hhaW5zLnVzZXJLZXljaGFpbiwge1xuICAgICAgICBjb21tb25LZXljaGFpbjogdXNlckNvbW1vbktleWNoYWluLFxuICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIGlkOiAndXNlcicsXG4gICAgICB9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwoa2V5Y2hhaW5zLmJhY2t1cEtleWNoYWluLCB7XG4gICAgICAgIGNvbW1vbktleWNoYWluOiBiYWNrdXBDb21tb25LZXljaGFpbixcbiAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIGlkOiAnYmFja3VwJyxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0Lm9rKHJvdW5kMU5vY2suaXNEb25lKCkpO1xuICAgICAgYXNzZXJ0Lm9rKHJvdW5kMk5vY2suaXNEb25lKCkpO1xuICAgICAgYXNzZXJ0Lm9rKHJvdW5kM05vY2suaXNEb25lKCkpO1xuICAgICAgYXNzZXJ0Lm9rKGFkZEtleU5vY2suaXNEb25lKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgTVBDdjIgU01DIHV0aWxzIGlmIHRoZSBzdGF0ZSBpcyBpbnZhbGlkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgTVBDdjJTTUNVdGlscyA9IG5ldyBFQ0RTQVV0aWxzLk1QQ3YyU01DVXRpbHMoYml0Z28sIGJhc2VDb2luKTtcbiAgICAgIGNvbnN0IGludmFsaWRQYXlsb2FkID0ge1xuICAgICAgICBzdGF0ZTogS2V5Q3JlYXRpb25NUEN2MlN0YXRlRW51bS5XYWl0aW5nRm9yT1ZDMVJvdW5kMkRhdGEsXG4gICAgICB9IGFzIGFueTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoYXN5bmMgKCkgPT4gYXdhaXQgTVBDdjJTTUNVdGlscy5rZXlHZW5Sb3VuZDEoJ3Rlc3RJZCcsIGludmFsaWRQYXlsb2FkKSwge1xuICAgICAgICBtZXNzYWdlOiBgSW52YWxpZCBzdGF0ZSBmb3Igcm91bmQgMSwgZXhwZWN0ZWQ6ICR7S2V5Q3JlYXRpb25NUEN2MlN0YXRlRW51bS5XYWl0aW5nRm9yQml0Z29Sb3VuZDFEYXRhfSwgZ290OiAke0tleUNyZWF0aW9uTVBDdjJTdGF0ZUVudW0uV2FpdGluZ0Zvck9WQzFSb3VuZDJEYXRhfWAsXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IGF3YWl0IE1QQ3YyU01DVXRpbHMua2V5R2VuUm91bmQyKCd0ZXN0SWQnLCBpbnZhbGlkUGF5bG9hZCksIHtcbiAgICAgICAgbWVzc2FnZTogYEludmFsaWQgc3RhdGUgZm9yIHJvdW5kIDIsIGV4cGVjdGVkOiAke0tleUNyZWF0aW9uTVBDdjJTdGF0ZUVudW0uV2FpdGluZ0ZvckJpdGdvUm91bmQyRGF0YX0sIGdvdDogJHtLZXlDcmVhdGlvbk1QQ3YyU3RhdGVFbnVtLldhaXRpbmdGb3JPVkMxUm91bmQyRGF0YX1gLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiBhd2FpdCBNUEN2MlNNQ1V0aWxzLmtleUdlblJvdW5kMygndGVzdElkJywgaW52YWxpZFBheWxvYWQpLCB7XG4gICAgICAgIG1lc3NhZ2U6IGBJbnZhbGlkIHN0YXRlIGZvciByb3VuZCAzLCBleHBlY3RlZDogJHtLZXlDcmVhdGlvbk1QQ3YyU3RhdGVFbnVtLldhaXRpbmdGb3JCaXRnb1JvdW5kM0RhdGF9LCBnb3Q6ICR7S2V5Q3JlYXRpb25NUEN2MlN0YXRlRW51bS5XYWl0aW5nRm9yT1ZDMVJvdW5kMkRhdGF9YCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBhc3luYyBmdW5jdGlvbiBub2NrS2V5Y2hhaW4oXG4gICAgcGFyYW1zOiB7XG4gICAgICBjb2luOiBzdHJpbmc7XG4gICAgICBrZXlDaGFpbjogS2V5Y2hhaW47XG4gICAgICBzb3VyY2U6ICd1c2VyJyB8ICdiYWNrdXAnIHwgJ2JpdGdvJztcbiAgICB9LFxuICAgIHRpbWVzID0gMVxuICApOiBQcm9taXNlPEtleWNoYWluPiB7XG4gICAgbm9jayhiZ1VybClcbiAgICAgIC5wb3N0KGAvYXBpL3YyLyR7cGFyYW1zLmNvaW59L2tleWAsIChib2R5KSA9PiB7XG4gICAgICAgIHJldHVybiBib2R5LmtleVR5cGUgPT09ICd0c3MnICYmIGJvZHkuc291cmNlID09PSBwYXJhbXMuc291cmNlO1xuICAgICAgfSlcbiAgICAgIC50aW1lcyh0aW1lcylcbiAgICAgIC5yZXBseSgyMDAsIHBhcmFtcy5rZXlDaGFpbik7XG5cbiAgICByZXR1cm4gcGFyYW1zLmtleUNoYWluO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gbm9ja0dldEJpdGdvUHVibGljS2V5QmFzZWRPbkZlYXR1cmVGbGFncyhcbiAgICBjb2luOiBzdHJpbmcsXG4gICAgZW50ZXJwcmlzZUlkOiBzdHJpbmcsXG4gICAgYml0Z29HcGdLZXlQYWlyOiBvcGVucGdwLlNlcmlhbGl6ZWRLZXlQYWlyPHN0cmluZz5cbiAgKTogUHJvbWlzZTxCaXRnb0dQR1B1YmxpY0tleT4ge1xuICAgIGNvbnN0IGJpdGdvR1BHUHVibGljS2V5UmVzcG9uc2U6IEJpdGdvR1BHUHVibGljS2V5ID0ge1xuICAgICAgbmFtZTogJ2lycmVsZXZhbnQnLFxuICAgICAgcHVibGljS2V5OiBiaXRnb0dwZ0tleVBhaXIucHVibGljS2V5LFxuICAgICAgbXBjdjJQdWJsaWNLZXk6IGJpdGdvR3BnS2V5UGFpci5wdWJsaWNLZXksXG4gICAgICBlbnRlcnByaXNlSWQsXG4gICAgfTtcbiAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvJHtjb2lufS90c3MvcHVia2V5YCkucXVlcnkoeyBlbnRlcnByaXNlSWQgfSkucmVwbHkoMjAwLCBiaXRnb0dQR1B1YmxpY0tleVJlc3BvbnNlKTtcblxuICAgIHJldHVybiBiaXRnb0dQR1B1YmxpY0tleVJlc3BvbnNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gbm9ja0tleUdlblJvdW5kMShiaXRnb1Nlc3Npb246IERrbHNEa2cuRGtnLCB0aW1lcyA9IDEpIHtcbiAgICByZXR1cm4gbm9jayhiZ1VybClcbiAgICAgIC5wb3N0KGAvYXBpL3YyL21wYy9nZW5lcmF0ZWtleWAsIChib2R5KSA9PiBib2R5LnJvdW5kID09PSAnTVBDdjItUjEnKVxuICAgICAgLnRpbWVzKHRpbWVzKVxuICAgICAgLnJlcGx5KFxuICAgICAgICAyMDAsXG4gICAgICAgIGFzeW5jICh1cmksIHsgcGF5bG9hZCB9OiB7IHBheWxvYWQ6IE1QQ3YyS2V5R2VuUm91bmQxUmVxdWVzdCB9KTogUHJvbWlzZTxNUEN2MktleUdlblJvdW5kMVJlc3BvbnNlPiA9PiB7XG4gICAgICAgICAgY29uc3QgeyB1c2VyR3BnUHVibGljS2V5LCBiYWNrdXBHcGdQdWJsaWNLZXksIHVzZXJNc2cxLCBiYWNrdXBNc2cxIH0gPSBwYXlsb2FkO1xuICAgICAgICAgIHVzZXJHcGdQdWJLZXkgPSB7XG4gICAgICAgICAgICBwYXJ0eUlkOiAwLFxuICAgICAgICAgICAgZ3BnS2V5OiB1c2VyR3BnUHVibGljS2V5LFxuICAgICAgICAgIH07XG4gICAgICAgICAgYmFja3VwR3BnUHViS2V5ID0ge1xuICAgICAgICAgICAgcGFydHlJZDogMSxcbiAgICAgICAgICAgIGdwZ0tleTogYmFja3VwR3BnUHVibGljS2V5LFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBjb25zdCBiaXRnb0Jyb2FkY2FzdE1zZzFVbnNpZ25lZCA9IGF3YWl0IGJpdGdvU2Vzc2lvbi5pbml0RGtnKCk7XG4gICAgICAgICAgY29uc3QgYml0Z29Nc2dzMVNpZ25lZCA9IGF3YWl0IERrbHNDb21tcy5lbmNyeXB0QW5kQXV0aE91dGdvaW5nTWVzc2FnZXMoXG4gICAgICAgICAgICB7IGJyb2FkY2FzdE1lc3NhZ2VzOiBbRGtsc1R5cGVzLnNlcmlhbGl6ZUJyb2FkY2FzdE1lc3NhZ2UoYml0Z29Ccm9hZGNhc3RNc2cxVW5zaWduZWQpXSwgcDJwTWVzc2FnZXM6IFtdIH0sXG4gICAgICAgICAgICBbXSxcbiAgICAgICAgICAgIFtiaXRnb0dwZ1BydktleV1cbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IGJpdGdvTXNnMSA9IGJpdGdvTXNnczFTaWduZWQuYnJvYWRjYXN0TWVzc2FnZXMuZmluZCgobSkgPT4gbS5mcm9tID09PSAyKTtcbiAgICAgICAgICBhc3NlcnQoYml0Z29Nc2cxLCAnYml0Z29Nc2cxIG5vdCBmb3VuZCcpO1xuXG4gICAgICAgICAgY29uc3Qgcm91bmQxSW5jb21pbmdNc2dzID0gYXdhaXQgRGtsc0NvbW1zLmRlY3J5cHRBbmRWZXJpZnlJbmNvbWluZ01lc3NhZ2VzKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICAgICAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXG4gICAgICAgICAgICAgICAgeyBmcm9tOiAwLCBwYXlsb2FkOiB1c2VyTXNnMSB9LFxuICAgICAgICAgICAgICAgIHsgZnJvbTogMSwgcGF5bG9hZDogYmFja3VwTXNnMSB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFt1c2VyR3BnUHViS2V5LCBiYWNrdXBHcGdQdWJLZXldLFxuICAgICAgICAgICAgW2JpdGdvR3BnUHJ2S2V5XVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCByb3VuZDJNZXNzYWdlcyA9IERrbHNUeXBlcy5zZXJpYWxpemVNZXNzYWdlcyhcbiAgICAgICAgICAgIGJpdGdvU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKERrbHNUeXBlcy5kZXNlcmlhbGl6ZU1lc3NhZ2VzKHJvdW5kMUluY29taW5nTXNncykpXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHJvdW5kMlNpZ25lZE1lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmVuY3J5cHRBbmRBdXRoT3V0Z29pbmdNZXNzYWdlcyhcbiAgICAgICAgICAgIHJvdW5kMk1lc3NhZ2VzLFxuICAgICAgICAgICAgW3VzZXJHcGdQdWJLZXksIGJhY2t1cEdwZ1B1YktleV0sXG4gICAgICAgICAgICBbYml0Z29HcGdQcnZLZXldXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IGJpdGdvVG9Vc2VyTXNnMiA9IHJvdW5kMlNpZ25lZE1lc3NhZ2VzLnAycE1lc3NhZ2VzLmZpbmQoKG0pID0+IG0udG8gPT09IDApO1xuICAgICAgICAgIGNvbnN0IGJpdGdvVG9CYWNrdXBNc2cyID0gcm91bmQyU2lnbmVkTWVzc2FnZXMucDJwTWVzc2FnZXMuZmluZCgobSkgPT4gbS50byA9PT0gMSk7XG4gICAgICAgICAgYXNzZXJ0KGJpdGdvVG9Vc2VyTXNnMiwgJ2JpdGdvVG9Vc2VyTXNnMiBub3QgZm91bmQnKTtcbiAgICAgICAgICBhc3NlcnQoYml0Z29Ub0JhY2t1cE1zZzIsICdiaXRnb1RvQmFja3VwTXNnMiBub3QgZm91bmQnKTtcbiAgICAgICAgICBhc3NlcnQoYml0Z29Ub1VzZXJNc2cyLmNvbW1pdG1lbnQsICdiaXRnb1RvVXNlck1zZzIuY29tbWl0bWVudCBub3QgZm91bmQnKTtcblxuICAgICAgICAgIHN0b3JlZEJpdGdvQ29tbWl0bWVudDIgPSBiaXRnb1RvVXNlck1zZzI/LmNvbW1pdG1lbnQ7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNlc3Npb25JZDogJ3Rlc3RpZCcgYXMgTm9uRW1wdHlTdHJpbmcsXG4gICAgICAgICAgICBiaXRnb01zZzE6IHsgZnJvbTogMiwgLi4uYml0Z29Nc2cxLnBheWxvYWQgfSxcbiAgICAgICAgICAgIGJpdGdvVG9CYWNrdXBNc2cyOiB7XG4gICAgICAgICAgICAgIGZyb206IDIsXG4gICAgICAgICAgICAgIHRvOiAxLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRNZXNzYWdlOiBiaXRnb1RvQmFja3VwTXNnMi5wYXlsb2FkLmVuY3J5cHRlZE1lc3NhZ2UsXG4gICAgICAgICAgICAgIHNpZ25hdHVyZTogYml0Z29Ub0JhY2t1cE1zZzIucGF5bG9hZC5zaWduYXR1cmUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYml0Z29Ub1VzZXJNc2cyOiB7XG4gICAgICAgICAgICAgIGZyb206IDIsXG4gICAgICAgICAgICAgIHRvOiAwLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRNZXNzYWdlOiBiaXRnb1RvVXNlck1zZzIucGF5bG9hZC5lbmNyeXB0ZWRNZXNzYWdlLFxuICAgICAgICAgICAgICBzaWduYXR1cmU6IGJpdGdvVG9Vc2VyTXNnMi5wYXlsb2FkLnNpZ25hdHVyZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB3YWxsZXRHcGdQdWJLZXlTaWdzOiAnc29tZXRoaW5nJyBhcyBOb25FbXB0eVN0cmluZyxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICApO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gbm9ja0tleUdlblJvdW5kMihiaXRnb1Nlc3Npb246IERrbHNEa2cuRGtnLCB0aW1lcyA9IDEpIHtcbiAgICByZXR1cm4gbm9jayhiZ1VybClcbiAgICAgIC5wb3N0KGAvYXBpL3YyL21wYy9nZW5lcmF0ZWtleWAsIChib2R5KSA9PiBib2R5LnJvdW5kID09PSAnTVBDdjItUjInKVxuICAgICAgLnRpbWVzKHRpbWVzKVxuICAgICAgLnJlcGx5KFxuICAgICAgICAyMDAsXG4gICAgICAgIGFzeW5jICh1cmksIHsgcGF5bG9hZCB9OiB7IHBheWxvYWQ6IE1QQ3YyS2V5R2VuUm91bmQyUmVxdWVzdCB9KTogUHJvbWlzZTxNUEN2MktleUdlblJvdW5kMlJlc3BvbnNlPiA9PiB7XG4gICAgICAgICAgY29uc3QgeyBzZXNzaW9uSWQsIHVzZXJNc2cyLCBiYWNrdXBNc2cyLCB1c2VyQ29tbWl0bWVudDIsIGJhY2t1cENvbW1pdG1lbnQyIH0gPSBwYXlsb2FkO1xuICAgICAgICAgIHN0b3JlZFVzZXJDb21taXRtZW50MiA9IHVzZXJDb21taXRtZW50MjtcbiAgICAgICAgICBzdG9yZWRCYWNrdXBDb21taXRtZW50MiA9IGJhY2t1cENvbW1pdG1lbnQyO1xuICAgICAgICAgIGNvbnN0IHJvdW5kMkluY29taW5nTXNncyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcDJwTWVzc2FnZXM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBmcm9tOiB1c2VyTXNnMi5mcm9tLFxuICAgICAgICAgICAgICAgICAgdG86IHVzZXJNc2cyLnRvLFxuICAgICAgICAgICAgICAgICAgcGF5bG9hZDogeyBzaWduYXR1cmU6IHVzZXJNc2cyLnNpZ25hdHVyZSwgZW5jcnlwdGVkTWVzc2FnZTogdXNlck1zZzIuZW5jcnlwdGVkTWVzc2FnZSB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZnJvbTogYmFja3VwTXNnMi5mcm9tLFxuICAgICAgICAgICAgICAgICAgdG86IGJhY2t1cE1zZzIudG8sXG4gICAgICAgICAgICAgICAgICBwYXlsb2FkOiB7IHNpZ25hdHVyZTogYmFja3VwTXNnMi5zaWduYXR1cmUsIGVuY3J5cHRlZE1lc3NhZ2U6IGJhY2t1cE1zZzIuZW5jcnlwdGVkTWVzc2FnZSB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBbdXNlckdwZ1B1YktleSwgYmFja3VwR3BnUHViS2V5XSxcbiAgICAgICAgICAgIFtiaXRnb0dwZ1BydktleV1cbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3Qgcm91bmQzTWVzc2FnZXMgPSBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXMoXG4gICAgICAgICAgICBiaXRnb1Nlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhEa2xzVHlwZXMuZGVzZXJpYWxpemVNZXNzYWdlcyhyb3VuZDJJbmNvbWluZ01zZ3MpKVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCByb3VuZDNTaWduZWRNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5lbmNyeXB0QW5kQXV0aE91dGdvaW5nTWVzc2FnZXMoXG4gICAgICAgICAgICByb3VuZDNNZXNzYWdlcyxcbiAgICAgICAgICAgIFt1c2VyR3BnUHViS2V5LCBiYWNrdXBHcGdQdWJLZXldLFxuICAgICAgICAgICAgW2JpdGdvR3BnUHJ2S2V5XVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCBiaXRnb1RvVXNlck1zZzMgPSByb3VuZDNTaWduZWRNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKChtKSA9PiBtLnRvID09PSAwKTtcbiAgICAgICAgICBjb25zdCBiaXRnb1RvQmFja3VwTXNnMyA9IHJvdW5kM1NpZ25lZE1lc3NhZ2VzLnAycE1lc3NhZ2VzLmZpbmQoKG0pID0+IG0udG8gPT09IDEpO1xuICAgICAgICAgIGFzc2VydChiaXRnb1RvVXNlck1zZzMsICdiaXRnb1RvVXNlck1zZzMgbm90IGZvdW5kJyk7XG4gICAgICAgICAgYXNzZXJ0KGJpdGdvVG9CYWNrdXBNc2czLCAnYml0Z29Ub0JhY2t1cE1zZzMgbm90IGZvdW5kJyk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2Vzc2lvbklkLFxuICAgICAgICAgICAgYml0Z29Db21taXRtZW50Mjogc3RvcmVkQml0Z29Db21taXRtZW50MiBhcyBOb25FbXB0eVN0cmluZyxcbiAgICAgICAgICAgIGJpdGdvVG9Vc2VyTXNnMzoge1xuICAgICAgICAgICAgICBmcm9tOiAyLFxuICAgICAgICAgICAgICB0bzogMCxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkTWVzc2FnZTogYml0Z29Ub1VzZXJNc2czLnBheWxvYWQuZW5jcnlwdGVkTWVzc2FnZSxcbiAgICAgICAgICAgICAgc2lnbmF0dXJlOiBiaXRnb1RvVXNlck1zZzMucGF5bG9hZC5zaWduYXR1cmUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYml0Z29Ub0JhY2t1cE1zZzM6IHtcbiAgICAgICAgICAgICAgZnJvbTogMixcbiAgICAgICAgICAgICAgdG86IDEsXG4gICAgICAgICAgICAgIGVuY3J5cHRlZE1lc3NhZ2U6IGJpdGdvVG9CYWNrdXBNc2czLnBheWxvYWQuZW5jcnlwdGVkTWVzc2FnZSxcbiAgICAgICAgICAgICAgc2lnbmF0dXJlOiBiaXRnb1RvQmFja3VwTXNnMy5wYXlsb2FkLnNpZ25hdHVyZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIG5vY2tLZXlHZW5Sb3VuZDMoYml0Z29TZXNzaW9uOiBEa2xzRGtnLkRrZywgdGltZXMgPSAxKSB7XG4gICAgcmV0dXJuIG5vY2soYmdVcmwpXG4gICAgICAucG9zdChgL2FwaS92Mi9tcGMvZ2VuZXJhdGVrZXlgLCAoYm9keSkgPT4gYm9keS5yb3VuZCA9PT0gJ01QQ3YyLVIzJylcbiAgICAgIC50aW1lcyh0aW1lcylcbiAgICAgIC5yZXBseShcbiAgICAgICAgMjAwLFxuICAgICAgICBhc3luYyAodXJpLCB7IHBheWxvYWQgfTogeyBwYXlsb2FkOiBNUEN2MktleUdlblJvdW5kM1JlcXVlc3QgfSk6IFByb21pc2U8TVBDdjJLZXlHZW5Sb3VuZDNSZXNwb25zZT4gPT4ge1xuICAgICAgICAgIGNvbnN0IHsgc2Vzc2lvbklkLCB1c2VyTXNnMywgdXNlck1zZzQsIGJhY2t1cE1zZzMsIGJhY2t1cE1zZzQgfSA9IHBheWxvYWQ7XG5cbiAgICAgICAgICBjb25zdCByb3VuZDNJbmNvbWluZ01zZ3MgPSBhd2FpdCBEa2xzQ29tbXMuZGVjcnlwdEFuZFZlcmlmeUluY29taW5nTWVzc2FnZXMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHAycE1lc3NhZ2VzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZnJvbTogdXNlck1zZzMuZnJvbSxcbiAgICAgICAgICAgICAgICAgIHRvOiB1c2VyTXNnMy50byxcbiAgICAgICAgICAgICAgICAgIHBheWxvYWQ6IHsgc2lnbmF0dXJlOiB1c2VyTXNnMy5zaWduYXR1cmUsIGVuY3J5cHRlZE1lc3NhZ2U6IHVzZXJNc2czLmVuY3J5cHRlZE1lc3NhZ2UgfSxcbiAgICAgICAgICAgICAgICAgIGNvbW1pdG1lbnQ6IHN0b3JlZFVzZXJDb21taXRtZW50MixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGZyb206IGJhY2t1cE1zZzMuZnJvbSxcbiAgICAgICAgICAgICAgICAgIHRvOiBiYWNrdXBNc2czLnRvLFxuICAgICAgICAgICAgICAgICAgcGF5bG9hZDogeyBzaWduYXR1cmU6IGJhY2t1cE1zZzMuc2lnbmF0dXJlLCBlbmNyeXB0ZWRNZXNzYWdlOiBiYWNrdXBNc2czLmVuY3J5cHRlZE1lc3NhZ2UgfSxcbiAgICAgICAgICAgICAgICAgIGNvbW1pdG1lbnQ6IHN0b3JlZEJhY2t1cENvbW1pdG1lbnQyLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBbdXNlckdwZ1B1YktleSwgYmFja3VwR3BnUHViS2V5XSxcbiAgICAgICAgICAgIFtiaXRnb0dwZ1BydktleV1cbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3Qgcm91bmQ0TWVzc2FnZXMgPSBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXMoXG4gICAgICAgICAgICBiaXRnb1Nlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhEa2xzVHlwZXMuZGVzZXJpYWxpemVNZXNzYWdlcyhyb3VuZDNJbmNvbWluZ01zZ3MpKVxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3Qgcm91bmQ0U2lnbmVkTWVzc2FnZXMgPSBhd2FpdCBEa2xzQ29tbXMuZW5jcnlwdEFuZEF1dGhPdXRnb2luZ01lc3NhZ2VzKFxuICAgICAgICAgICAgcm91bmQ0TWVzc2FnZXMsXG4gICAgICAgICAgICBbXSxcbiAgICAgICAgICAgIFtiaXRnb0dwZ1BydktleV1cbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IGJpdGdvTXNnNCA9IHJvdW5kNFNpZ25lZE1lc3NhZ2VzLmJyb2FkY2FzdE1lc3NhZ2VzLmZpbmQoKG0pID0+IG0uZnJvbSA9PT0gMik7XG4gICAgICAgICAgYXNzZXJ0KGJpdGdvTXNnNCwgJ2JpdGdvTXNnNCBub3QgZm91bmQnKTtcblxuICAgICAgICAgIGNvbnN0IHJvdW5kNEluY29taW5nTXNncyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgICAgICAgICAgICBicm9hZGNhc3RNZXNzYWdlczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGZyb206IHVzZXJNc2c0LmZyb20sXG4gICAgICAgICAgICAgICAgICBwYXlsb2FkOiB7IHNpZ25hdHVyZTogdXNlck1zZzQuc2lnbmF0dXJlLCBtZXNzYWdlOiB1c2VyTXNnNC5tZXNzYWdlIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBmcm9tOiBiYWNrdXBNc2c0LmZyb20sXG5cbiAgICAgICAgICAgICAgICAgIHBheWxvYWQ6IHsgc2lnbmF0dXJlOiBiYWNrdXBNc2c0LnNpZ25hdHVyZSwgbWVzc2FnZTogYmFja3VwTXNnNC5tZXNzYWdlIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBbdXNlckdwZ1B1YktleSwgYmFja3VwR3BnUHViS2V5XSxcbiAgICAgICAgICAgIFtdXG4gICAgICAgICAgKTtcbiAgICAgICAgICBiaXRnb1Nlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhEa2xzVHlwZXMuZGVzZXJpYWxpemVNZXNzYWdlcyhyb3VuZDRJbmNvbWluZ01zZ3MpKTtcbiAgICAgICAgICBjb25zdCBrZXlTaGFyZSA9IGJpdGdvU2Vzc2lvbi5nZXRLZXlTaGFyZSgpO1xuICAgICAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID0gRGtsc1R5cGVzLmdldENvbW1vbktleWNoYWluKGtleVNoYXJlKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZXNzaW9uSWQsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogY29tbW9uS2V5Y2hhaW4gYXMgTm9uRW1wdHlTdHJpbmcsXG4gICAgICAgICAgICBiaXRnb01zZzQ6IHsgZnJvbTogMiwgLi4uYml0Z29Nc2c0LnBheWxvYWQgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICApO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gbm9ja0FkZEtleUNoYWluKGNvaW46IHN0cmluZywgdGltZXMgPSAxKSB7XG4gICAgcmV0dXJuIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAucG9zdChgL2FwaS92Mi8ke2NvaW59L2tleWAsIChib2R5KSA9PiBib2R5LmtleVR5cGUgPT09ICd0c3MnICYmIGJvZHkuaXNNUEN2MilcbiAgICAgIC50aW1lcyh0aW1lcylcbiAgICAgIC5yZXBseSgyMDAsIGFzeW5jICh1cmksIHJlcXVlc3RCb2R5OiBBZGRLZXljaGFpbk9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3Qga2V5ID0ge1xuICAgICAgICAgIGlkOiByZXF1ZXN0Qm9keS5zb3VyY2UsXG4gICAgICAgICAgc291cmNlOiByZXF1ZXN0Qm9keS5zb3VyY2UsXG4gICAgICAgICAgdHlwZTogcmVxdWVzdEJvZHkua2V5VHlwZSxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogcmVxdWVzdEJvZHkuY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiByZXF1ZXN0Qm9keS5lbmNyeXB0ZWRQcnYsXG4gICAgICAgIH07XG4gICAgICAgIC8vIG5vY2sgZ2V0c1xuICAgICAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKS5nZXQoYC9hcGkvdjIvJHtjb2lufS9rZXkvJHtyZXF1ZXN0Qm9keS5zb3VyY2V9YCkucmVwbHkoMjAwLCBrZXkpO1xuICAgICAgICByZXR1cm4ga2V5O1xuICAgICAgfSk7XG4gIH1cbn0pO1xuIl19Выполнить команду
Для локальной разработки. Не используйте в интернете!