bitgo
Version:
BitGo JavaScript SDK
4,373 lines • 705 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//
// Tests for Wallets
//
const assert = require("assert");
const nock = require("nock");
const sinon = require("sinon");
const should = require("should");
const _ = require("lodash");
const utxoLib = require("@bitgo/utxo-lib");
const sdk_test_1 = require("@bitgo/sdk-test");
const sdk_core_1 = require("@bitgo/sdk-core");
const src_1 = require("../../../src");
const mocha_1 = require("mocha");
const moduleBitgo = require("@bitgo/sdk-core");
describe('V2 Wallets:', function () {
const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
let wallets;
let ofcWallets;
let bgUrl;
before(function () {
nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
bitgo.initializeTestVars();
const basecoin = bitgo.coin('tbtc');
wallets = basecoin.wallets();
ofcWallets = bitgo.coin('ofc').wallets();
bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
});
after(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
});
describe('Add Wallet:', function () {
it('throws on invalid arguments', async function () {
// isCustodial flag is not a boolean
await wallets
.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, isCustodial: 1 })
.should.be.rejectedWith('invalid argument for isCustodial - boolean expected');
// type is not a string
await wallets
.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, type: 1 })
.should.be.rejectedWith('Expecting parameter string: type but found number');
// Address is an invalid address
await wallets
.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, address: '$' })
.should.be.rejectedWith('invalid argument for address - valid address string expected');
// gasPrice is a number
await wallets
.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, gasPrice: '17' })
.should.be.rejectedWith('invalid argument for gasPrice - number expected');
// walletVersion is a number
await wallets
.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, walletVersion: '1' })
.should.be.rejectedWith('invalid argument for walletVersion - number expected');
});
it('creates a paired custodial wallet', async function () {
nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.isCustodial.should.be.true();
body.should.have.property('keys');
body.m.should.equal(2);
body.n.should.equal(3);
return true;
})
.reply(200, {});
await wallets.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, isCustodial: true });
});
it('creates an eos wallet with custom address', async function () {
const eosBitGo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
eosBitGo.initializeTestVars();
const eosWallets = eosBitGo.coin('teos').wallets();
const address = 'testeosaddre';
nock(bgUrl)
.post('/api/v2/teos/wallet/add', function (body) {
body.should.have.property('keys');
body.m.should.equal(2);
body.n.should.equal(3);
body.address.should.equal(address);
return true;
})
.reply(200, {});
await eosWallets.add({ label: 'label', enterprise: 'enterprise', keys: [], m: 2, n: 3, address });
});
it('creates a single custodial wallet', async function () {
nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.type.should.equal('custodial');
body.should.not.have.property('keys');
body.should.not.have.property('m');
body.should.not.have.property('n');
return true;
})
.reply(200, {});
await wallets.add({ label: 'label', enterprise: 'enterprise', type: 'custodial' });
});
it('creates a wallet with custom gasPrice', async function () {
const ethBitGo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
ethBitGo.initializeTestVars();
const ethWallets = ethBitGo.coin('teth').wallets();
nock(bgUrl)
.post('/api/v2/teth/wallet/add', function (body) {
body.type.should.equal('custodial');
body.gasPrice.should.equal(20000000000);
body.should.not.have.property('keys');
body.should.not.have.property('m');
body.should.not.have.property('n');
return true;
})
.reply(200, {});
await ethWallets.add({
label: 'label',
enterprise: 'enterprise',
type: 'custodial',
gasPrice: 20000000000,
});
});
it('creates a new wallet with walletVersion', async function () {
const ethBitGo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
ethBitGo.initializeTestVars();
const ethWallets = ethBitGo.coin('teth').wallets();
nock(bgUrl)
.post('/api/v2/teth/wallet/add', function (body) {
body.type.should.equal('custodial');
body.walletVersion.should.equal(1);
body.should.not.have.property('keys');
body.should.not.have.property('m');
body.should.not.have.property('n');
return true;
})
.reply(200, {});
await ethWallets.add({ label: 'label', enterprise: 'enterprise', type: 'custodial', walletVersion: 1 });
});
it('creates a new hot wallet with userKey', async function () {
nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.type.should.equal('hot');
body.should.have.property('keys');
body.should.have.property('m');
body.should.have.property('n');
return true;
})
.reply(200, {});
await wallets.add({
label: 'label',
enterprise: 'enterprise',
type: 'hot',
keys: [],
m: 2,
n: 3,
userKey: 'test123',
});
});
});
describe('Generate wallet:', function () {
const sandbox = sinon.createSandbox();
it('should validate parameters', async function () {
let params = {};
await wallets.generateWallet(params).should.be.rejectedWith('Missing parameter: label');
params = {
label: 'abc',
backupXpub: 'backup',
backupXpubProvider: 'provider',
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('Cannot provide more than one backupXpub or backupXpubProvider flag');
params = {
label: 'abc',
passcodeEncryptionCode: 123,
};
await wallets.generateWallet(params).should.be.rejectedWith('passcodeEncryptionCode must be a string');
params = {
label: 'abc',
enterprise: 1234,
};
await wallets.generateWallet(params).should.be.rejectedWith('invalid enterprise argument, expecting string');
params = {
label: 'abc',
disableTransactionNotifications: 'string',
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid disableTransactionNotifications argument, expecting boolean');
params = {
label: 'abc',
gasPrice: 'string',
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid gas price argument, expecting number or number as string');
params = {
label: 'abc',
gasPrice: true,
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid gas price argument, expecting number or number as string');
params = {
label: 'abc',
gasPrice: 123,
eip1559: {
maxFeePerGas: 1234,
maxPriorityFeePerGas: 123,
},
};
await wallets.generateWallet(params).should.be.rejectedWith('can not use both eip1559 and gasPrice values');
params = {
label: 'abc',
eip1559: {
maxFeePerGas: 'q1234',
maxPriorityFeePerGas: '123',
},
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid max fee argument, expecting number or number as string');
params = {
label: 'abc',
eip1559: {
maxFeePerGas: 1234,
maxPriorityFeePerGas: '123a',
},
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid priority fee argument, expecting number or number as string');
params = {
label: 'abc',
disableKRSEmail: 'string',
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('invalid disableKRSEmail argument, expecting boolean');
params = {
label: 'abc',
krsSpecific: {
malicious: {
javascript: {
code: 'bad.js',
},
},
},
};
await wallets
.generateWallet(params)
.should.be.rejectedWith('krsSpecific object contains illegal values. values must be strings, booleans, or numbers');
});
it('should correctly disable krs emails when creating backup keychains', async function () {
const params = {
label: 'my_wallet',
disableKRSEmail: true,
backupXpubProvider: 'test',
passphrase: 'test123',
userKey: 'xpub123',
};
// bitgo key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200);
// user key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200);
// backup key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({
source: 'backup',
provider: params.backupXpubProvider,
disableKRSEmail: true,
}))
.reply(200);
// wallet
nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
await wallets.generateWallet(params);
});
it('should correctly pass through the krsSpecific param when creating backup keychains', async function () {
const params = {
label: 'my_wallet',
backupXpubProvider: 'test',
passphrase: 'test123',
userKey: 'xpub123',
krsSpecific: { coverage: 'insurance', expensive: true, howExpensive: 25 },
};
// bitgo key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200);
// user key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200);
// backup key
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({
source: 'backup',
provider: params.backupXpubProvider,
krsSpecific: { coverage: 'insurance', expensive: true, howExpensive: 25 },
}))
.reply(200);
// wallet
nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
await wallets.generateWallet(params);
});
it('should send the cold derivation seed for a user key', async () => {
const params = {
label: 'my-cold-wallet',
passphrase: 'test123',
userKey: 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8',
coldDerivationSeed: '123',
};
// bitgo key
const bitgoKeyNock = nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200);
// user key
const userKeyNock = nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({
derivedFromParentWithSeed: params.coldDerivationSeed,
}))
.reply(200);
// backup key
const backupKeyNock = nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
.reply(200);
// wallet
const walletNock = nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
await wallets.generateWallet(params);
for (const scope of [bitgoKeyNock, userKeyNock, backupKeyNock, walletNock]) {
scope.done();
}
});
it('should generate custodial onchain wallet without passing m, n, keys, keySignatures', async () => {
const params = {
label: 'test wallet',
enterprise: 'myenterprise',
type: 'custodial',
};
const walletNock = nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.type.should.equal('custodial');
should.not.exist(body.m);
should.not.exist(body.n);
should.not.exist(body.keys);
should.not.exist(body.keySignatures);
return true;
})
.reply(200, { id: '123', baseCoin: bitgo.coin('tbtc'), keys: ['123', '456', '789'] });
nock(bgUrl).get('/api/v2/tbtc/key/123').reply(200, { pub: 'bitgoPub', id: '789' });
nock(bgUrl).get('/api/v2/tbtc/key/456', _.matches({})).reply(200);
nock(bgUrl).get('/api/v2/tbtc/key/789').reply(200, { pub: 'backupPub', id: '789' });
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
assert.ok(response.encryptedWalletPassphrase === undefined);
assert.ok(response.wallet);
});
it('should generate hot onchain wallet', async () => {
const params = {
label: 'test wallet',
passphrase: 'multisig password',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const walletNock = nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.type.should.equal('hot');
return true;
})
.reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200, { pub: 'bitgoPub' });
nock(bgUrl).post('/api/v2/tbtc/key', _.matches({})).reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
.reply(200, { pub: 'backupPub' });
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it('should generate hot onchain wallet without passing multisig type', async () => {
const params = {
label: 'test wallet',
passphrase: 'multisig password',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const walletNock = nock(bgUrl)
.post('/api/v2/tbtc/wallet/add', function (body) {
body.type.should.equal('hot');
return true;
})
.reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200, { pub: 'bitgoPub' });
nock(bgUrl).post('/api/v2/tbtc/key', _.matches({})).reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
.reply(200, { pub: 'backupPub' });
const generateWalletSpy = sandbox.spy(wallets, 'generateWallet');
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
sinon.assert.calledOnce(generateWalletSpy);
assert.equal(generateWalletSpy.firstCall?.args[0]?.multisigType, sdk_core_1.multisigTypes.onchain);
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it('should generate Go Account wallet', async () => {
const params = {
label: 'Go Account Wallet',
passphrase: 'go_account_password',
enterprise: 'enterprise-id',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
type: 'trading',
};
const keychainId = 'user_keychain_id';
// Mock keychain creation and upload
nock(bgUrl)
.post('/api/v2/ofc/key', function (body) {
body.should.have.property('encryptedPrv');
body.should.have.property('originalPasscodeEncryptionCode');
body.keyType.should.equal('independent');
body.source.should.equal('user');
return true;
})
.reply(200, { id: keychainId, pub: 'userPub', encryptedPrv: 'encryptedPrivateKey' });
// Mock wallet creation
const walletNock = nock(bgUrl)
.post('/api/v2/ofc/wallet/add', function (body) {
body.type.should.equal('trading');
body.m.should.equal(1);
body.n.should.equal(1);
body.keys.should.have.length(1);
body.keys[0].should.equal(keychainId);
return true;
})
.reply(200, { id: 'wallet123', keys: [keychainId] });
const response = await ofcWallets.generateWallet(params);
walletNock.isDone().should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.ok('userKeychain' in response);
});
});
describe('Generate TSS wallet:', function () {
const tsol = bitgo.coin('tsol');
const sandbox = sinon.createSandbox();
beforeEach(function () {
nock('https://bitgo.fakeurl')
.get(`/api/v2/tss/settings`)
.query(true)
.times(2)
.reply(200, {
coinSettings: {
eth: {
walletCreationSettings: {},
},
bsc: {
walletCreationSettings: {},
},
polygon: {
walletCreationSettings: {},
},
},
});
});
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
sandbox.verifyAndRestore();
});
it('should create a new TSS wallet', async function () {
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
pub: 'userPub',
type: 'independent',
source: 'user',
},
backupKeychain: {
id: '2',
pub: 'userPub',
type: 'independent',
source: 'backup',
},
bitgoKeychain: {
id: '3',
pub: 'userPub',
type: 'independent',
source: 'bitgo',
},
};
sandbox.stub(sdk_core_1.TssUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it('should create a new TSS wallet without passing multisig type', async function () {
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
pub: 'userPub',
type: 'independent',
source: 'user',
},
backupKeychain: {
id: '2',
pub: 'userPub',
type: 'independent',
source: 'backup',
},
bitgoKeychain: {
id: '3',
pub: 'userPub',
type: 'independent',
source: 'bitgo',
},
};
sandbox.stub(sdk_core_1.TssUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tsol/wallet/add', function (body) {
body.multisigType.should.equal(sdk_core_1.multisigTypes.tss);
return true;
})
.reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const generateWalletSpy = sandbox.spy(wallets, 'generateWallet');
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
sinon.assert.calledOnce(generateWalletSpy);
assert.equal(generateWalletSpy.firstCall?.args[0]?.multisigType, sdk_core_1.multisigTypes.tss);
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it('should create a new TSS wallet without providing passcodeEncryptionCode', async function () {
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
pub: 'userPub',
type: 'independent',
source: 'user',
},
backupKeychain: {
id: '2',
pub: 'userPub',
type: 'independent',
source: 'backup',
},
bitgoKeychain: {
id: '3',
pub: 'userPub',
type: 'independent',
source: 'bitgo',
},
};
sandbox.stub(sdk_core_1.TssUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
const response = await wallets.generateWallet({
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
});
walletNock.isDone().should.be.true();
assert.ok(response.wallet);
assert.ok(response.encryptedWalletPassphrase === undefined);
});
it('should fail to create TSS wallet with invalid inputs', async function () {
const tbtc = bitgo.coin('tbtc');
const params = {
label: 'my-cold-wallet',
passphrase: 'test123',
userKey: 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8',
coldDerivationSeed: '123',
};
const wallets = new sdk_core_1.Wallets(bitgo, tbtc);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'bitgo' }))
.reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ derivedFromParentWithSeed: params.coldDerivationSeed }))
.reply(200);
nock(bgUrl)
.post('/api/v2/tbtc/key', _.matches({ source: 'backup' }))
.reply(200);
nock(bgUrl).post('/api/v2/tbtc/wallet/add').reply(200);
// create a non tss wallet for coin that doesn't support tss even though multisigType is set to tss
await wallets.generateWallet({ ...params, multisigType: 'tss' });
const tsolWallets = new sdk_core_1.Wallets(bitgo, tsol);
await tsolWallets
.generateWallet({
label: 'tss cold wallet',
passphrase: 'passphrase',
userKey: 'user key',
multisigType: 'tss',
})
.should.be.rejectedWith('enterprise is required for TSS wallet');
await tsolWallets
.generateWallet({
label: 'tss cold wallet',
userKey: 'user key',
multisigType: 'tss',
enterprise: 'enterpriseId',
})
.should.be.rejectedWith('cannot generate TSS keys without passphrase');
});
it('should create a new TSS custodial wallet', async function () {
const keys = ['1', '2', '3'];
const walletParams = {
label: 'tss wallet',
multisigType: 'tss',
enterprise: 'enterprise',
type: 'custodial',
};
const walletNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tsol/wallet/add')
.times(1)
.reply(200, { ...walletParams, keys });
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
const res = await wallets.generateWallet(walletParams);
if (!(0, sdk_core_1.isWalletWithKeychains)(res)) {
throw new Error('wallet missing required keychains');
}
res.wallet.label().should.equal(walletParams.label);
should.equal(res.wallet.type(), walletParams.type);
res.wallet.toJSON().enterprise.should.equal(walletParams.enterprise);
res.wallet.multisigType().should.equal(walletParams.multisigType);
res.userKeychain.id.should.equal(keys[0]);
res.backupKeychain.id.should.equal(keys[1]);
res.bitgoKeychain.id.should.equal(keys[2]);
walletNock.isDone().should.be.true();
});
it('should create a new FLRP TSS custodial wallet without requiring a passphrase', async function () {
const keys = ['1', '2', '3'];
const tflrp = bitgo.coin('tflrp');
const walletParams = {
label: 'flrp custodial wallet',
enterprise: 'enterprise',
type: 'custodial',
// No multisigType specified — should default to 'tss' for FLRP
// No passphrase — custodial wallets must not require one
};
// FLRP is ECDSA, so generateCustodialMpcWallet fetches TSS settings
nock('https://bitgo.fakeurl')
.get('/api/v2/tss/settings')
.query(true)
.reply(200, { coinSettings: { flrp: { walletCreationSettings: {} } } });
const walletNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tflrp/wallet/add')
.times(1)
.reply(200, { ...walletParams, multisigType: 'tss', keys });
const flrpWallets = new sdk_core_1.Wallets(bitgo, tflrp);
const res = await flrpWallets.generateWallet(walletParams);
if (!(0, sdk_core_1.isWalletWithKeychains)(res)) {
throw new Error('wallet missing required keychains');
}
res.wallet.label().should.equal(walletParams.label);
should.equal(res.wallet.type(), walletParams.type);
res.wallet.multisigType().should.equal('tss');
res.userKeychain.id.should.equal(keys[0]);
res.backupKeychain.id.should.equal(keys[1]);
res.bitgoKeychain.id.should.equal(keys[2]);
walletNock.isDone().should.be.true();
});
it('should create a new TSS SMC wallet', async function () {
const commonKeychain = 'longstring';
const seed = 'seed';
const keys = {
userKeychain: {
id: '1',
commonKeychain,
type: 'tss',
derivedFromParentWithSeed: seed,
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain,
type: 'tss',
derivedFromParentWithSeed: seed,
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain,
type: 'tss',
source: 'bitgo',
},
};
const bitgoKeyNock = nock('https://bitgo.fakeurl').get('/api/v2/tsol/key/3').reply(200, keys.bitgoKeychain);
const userKeyExpectedBody = {
source: 'user',
keyType: 'tss',
commonKeychain,
derivedFromParentWithSeed: seed,
};
const userKeyNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tsol/key', userKeyExpectedBody)
.reply(200, keys.userKeychain);
const backupKeyExpectedBody = {
source: 'backup',
keyType: 'tss',
commonKeychain,
derivedFromParentWithSeed: seed,
};
const backupKeyNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tsol/key', backupKeyExpectedBody)
.reply(200, keys.backupKeychain);
const walletParams = {
label: 'tss wallet',
multisigType: 'tss',
enterprise: 'enterprise',
type: 'cold',
bitgoKeyId: keys.bitgoKeychain.id,
commonKeychain,
coldDerivationSeed: seed,
};
const walletNockExpected = {
label: walletParams.label,
m: 2,
n: 3,
keys: [keys.userKeychain.id, keys.backupKeychain.id, keys.bitgoKeychain.id],
type: walletParams.type,
multisigType: walletParams.multisigType,
enterprise: walletParams.enterprise,
walletVersion: undefined,
};
const walletNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tsol/wallet/add', walletNockExpected)
.reply(200, { ...walletNockExpected, responseType: 'WalletWithKeychains' });
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
const res = await wallets.generateWallet(walletParams);
if (!(0, sdk_core_1.isWalletWithKeychains)(res)) {
throw new Error('wallet missing required keychains');
}
res.responseType.should.equal('WalletWithKeychains');
res.wallet.label().should.equal(walletParams.label);
should.equal(res.wallet.type(), walletParams.type);
res.wallet.toJSON().enterprise.should.equal(walletParams.enterprise);
res.wallet.multisigType().should.equal(walletParams.multisigType);
res.userKeychain.should.deepEqual(keys.userKeychain);
res.backupKeychain.should.deepEqual(keys.backupKeychain);
res.bitgoKeychain.should.deepEqual(keys.bitgoKeychain);
bitgoKeyNock.isDone().should.be.true();
userKeyNock.isDone().should.be.true();
backupKeyNock.isDone().should.be.true();
walletNock.isDone().should.be.true();
});
it('should throw an error for TSS SMC wallet if the bitgoKeyId is not a bitgo key ', async function () {
const commonKeychain = 'longstring';
const seed = 'seed';
const keys = {
userKeychain: {
id: '1',
commonKeychain,
type: 'tss',
derivedFromParentWithSeed: seed,
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain,
type: 'tss',
derivedFromParentWithSeed: seed,
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain,
type: 'tss',
source: 'bitgo',
},
};
const bitgoKeyNock = nock('https://bitgo.fakeurl').get('/api/v2/tsol/key/1').reply(200, keys.userKeychain);
const walletParams = {
label: 'tss wallet',
multisigType: 'tss',
enterprise: 'enterprise',
type: 'cold',
bitgoKeyId: keys.userKeychain.id,
commonKeychain,
coldDerivationSeed: seed,
};
const wallets = new sdk_core_1.Wallets(bitgo, tsol);
await wallets
.generateWallet(walletParams)
.should.be.rejectedWith('The provided bitgoKeyId is not a BitGo keychain');
bitgoKeyNock.isDone().should.be.true();
});
});
describe('Generate shielded wallet:', function () {
const tzec = bitgo.coin('tzec');
it('should create a new shielded custodial wallet', async function () {
const keys = ['1', '2', '3'];
const walletParams = {
label: 'shielded wallet',
isShielded: true,
enterprise: 'enterprise',
type: 'custodial',
};
const walletNock = nock('https://bitgo.fakeurl')
.post('/api/v2/tzec/wallet/add', (body) => {
body.multisigType.should.equal(sdk_core_1.multisigTypes.tss);
body.coinSpecific.should.deepEqual({ isShielded: true });
return true;
})
.times(1)
.reply(200, { ...walletParams, multisigType: sdk_core_1.multisigTypes.tss, keys });
const shieldedWallets = new sdk_core_1.Wallets(bitgo, tzec);
const res = await shieldedWallets.generateWallet(walletParams);
if (!(0, sdk_core_1.isWalletWithKeychains)(res)) {
throw new Error('wallet missing required keychains');
}
res.wallet.label().should.equal(walletParams.label);
should.equal(res.wallet.type(), walletParams.type);
res.wallet.toJSON().enterprise.should.equal(walletParams.enterprise);
res.wallet.multisigType().should.equal(sdk_core_1.multisigTypes.tss);
res.userKeychain.type.should.equal('tss');
res.backupKeychain.type.should.equal('tss');
res.bitgoKeychain.type.should.equal('tss');
walletNock.isDone().should.be.true();
});
it('should reject a non-custodial shielded wallet', async function () {
const walletParams = {
label: 'shielded wallet',
isShielded: true,
enterprise: 'enterprise',
type: 'hot',
};
const shieldedWallets = new sdk_core_1.Wallets(bitgo, tzec);
await shieldedWallets
.generateWallet(walletParams)
.should.be.rejectedWith('shielded wallets can only be created as custodial wallets');
});
it('should reject a shielded wallet without an enterprise', async function () {
const walletParams = {
label: 'shielded wallet',
isShielded: true,
type: 'custodial',
};
const shieldedWallets = new sdk_core_1.Wallets(bitgo, tzec);
await shieldedWallets.generateWallet(walletParams).should.be.rejectedWith('enterprise is required');
});
});
describe('Generate TSS MPCv2 wallet:', async function () {
const sandbox = sinon.createSandbox();
beforeEach(function () {
const tssSettings = {
coinSettings: {
eth: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
bsc: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
polygon: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
atom: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
tia: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
bera: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
arbeth: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
opeth: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
coldMultiSigTypeVersion: 'MPCv2',
custodialMultiSigTypeVersion: 'MPCv2',
},
},
},
};
nock('https://bitgo.fakeurl').get(`/api/v2/tss/settings`).query(true).times(2).reply(200, tssSettings);
});
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
sandbox.verifyAndRestore();
});
['hteth', 'tbsc', 'tpolygon', 'ttia', 'tatom', 'tbera', 'tarbeth', 'topeth'].forEach((coin) => {
it(`should create a new ${coin} TSS MPCv2 hot wallet`, async function () {
const testCoin = bitgo.coin(coin);
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubCreateKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl').post(`/api/v2/${coin}/wallet/add`).reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 3,
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubCreateKeychains.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it(`should create a new ${coin} TSS MPCv2 hot wallet without passing multisig type`, async function () {
const testCoin = bitgo.coin(coin);
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubCreateKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/${coin}/wallet/add`, function (body) {
body.multisigType.should.equal(sdk_core_1.multisigTypes.tss);
return true;
})
.reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 3,
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubCreateKeychains.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it(`should create a new ${coin} TSS MPCv2 cold wallet`, async function () {
const testCoin = bitgo.coin(coin);
const bitgoKeyId = 'key123';
const commonKeychain = '0xabc';
const bitgoKeyNock = nock('https://bitgo.fakeurl')
.get(`/api/v2/${coin}/key/${bitgoKeyId}`)
.times(1)
.reply(200, {
id: 'key123',
pub: 'bitgoPub',
type: 'tss',
source: 'bitgo',
commonKeychain,
});
const userKeyNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/${coin}/key`, {
source: 'user',
keyType: 'tss',
commonKeychain,
derivedFromParentWithSeed: '37',
isMPCv2: true,
})
.times(1)
.reply(200, {
id: 'userKey123',
pub: 'userPub',
type: 'tss',
source: 'user',
});
const backupKeyNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/${coin}/key`, {
source: 'backup',
keyType: 'tss',
commonKeychain,
derivedFromParentWithSeed: '37',
isMPCv2: true,
})
.times(1)
.reply(200, {
id: 'backupKey123',
pub: 'backupPub',
type: 'tss',
source: 'backup',
});
const walletNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/${coin}/wallet/add`, {
label: 'tss wallet',
m: 2,
n: 3,
keys: ['userKey123', 'backupKey123', 'key123'],
type: 'cold',
multisigType: 'tss',
enterprise: 'enterprise',
walletVersion: 5,
})
.reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss wallet',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 5,
type: 'cold',
bitgoKeyId: 'key123',
commonKeychain: '0xabc',
coldDerivationSeed: '37',
};
const response = (await wallets.generateWallet(params));
bitgoKeyNock.isDone().should.be.true();
userKeyNock.isDone().should.be.true();
backupKeyNock.isDone().should.be.true();
walletNock.isDone().should.be.true();
should.exist(response.wallet);
should.exist(response.userKeychain);
should.exist(response.backupKeychain);
should.exist(response.bitgoKeychain);
response.responseType.should.equal('WalletWithKeychains');
response.userKeychain.id.should.equal('userKey123');
response.backupKeychain.id.should.equal('backupKey123');
response.bitgoKeychain.id.should.equal('key123');
});
it(`should create a new ${coin} TSS MPCv2 custody wallet`, async function () {
const testCoin = bitgo.coin(coin);
const keys = ['userKey', 'backupKey', 'bitgoKey'];
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 5,
type: 'custodial',
};
const walletNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/${coin}/wallet/add`)
.times(1)
.reply(200, { ...params, keys });
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const response = (await wallets.generateWallet(params));
walletNock.isDone().should.be.true();
should.exist(response.wallet);
should.exist(response.userKeychain);
should.exist(response.backupKeychain);
should.exist(response.bitgoKeychain);
response.responseType.should.equal('WalletWithKeychains');
response.userKeychain.id.should.equal(keys[0]);
response.backupKeychain.id.should.equal(keys[1]);
response.bitgoKeychain.id.should.equal(keys[2]);
});
});
it(`should create a new hteth TSS MPCv2 wallet with walletVersion 6`, async function () {
const testCoin = bitgo.coin('hteth');
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubCreateKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/hteth/wallet/add`, (body) => {
body.walletVersion.should.equal(6);
return true;
})
.reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 6,
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubCreateKeychains.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it(`should create a new MPCv2 wallet with version 5 if walletVersion passed is not 5 or 6`, async function () {
const testCoin = bitgo.coin('hteth');
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubCreateKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaMPCv2Utils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl')
.post(`/api/v2/hteth/wallet/add`, (body) => {
body.walletVersion.should.equal(5);
return true;
})
.reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
walletVersion: 3,
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubCreateKeychains.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
});
describe('Generate TSS EdDSA MPCv2 wallet:', async function () {
const sandbox = sinon.createSandbox();
beforeEach(function () {
const tssSettings = {
coinSettings: {
sol: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
},
},
},
};
nock('https://bitgo.fakeurl').get(`/api/v2/tss/settings`).query(true).times(2).reply(200, tssSettings);
});
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
sandbox.verifyAndRestore();
});
it('should create a new tsol TSS EdDSA MPCv2 hot wallet', async function () {
const testCoin = bitgo.coin('tsol');
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubCreateKeychains = sandbox
.stub(sdk_core_1.EDDSAUtils.EddsaMPCv2Utils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss eddsa mpcv2 wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubCreateKeychains.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
assert.equal(await bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
});
it('should fall back to EddsaUtils when tss/settings does not return MPCv2 for tsol', async function () {
nock.cleanAll();
nock('https://bitgo.fakeurl')
.get('/api/v2/tss/settings')
.query(true)
.reply(200, { coinSettings: { sol: { walletCreationSettings: {} } } });
const testCoin = bitgo.coin('tsol');
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
commonKeychain: 'userPub',
type: 'tss',
source: 'user',
},
backupKeychain: {
id: '2',
commonKeychain: 'userPub',
type: 'tss',
source: 'backup',
},
bitgoKeychain: {
id: '3',
commonKeychain: 'userPub',
type: 'tss',
source: 'bitgo',
},
};
const stubEddsaUtils = sandbox
.stub(sdk_core_1.EDDSAUtils.default.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
const walletNock = nock('https://bitgo.fakeurl').post('/api/v2/tsol/wallet/add').reply(200);
const wallets = new sdk_core_1.Wallets(bitgo, testCoin);
const params = {
label: 'tss eddsa wallet',
passphrase: 'tss password',
multisigType: 'tss',
enterprise: 'enterprise',
passcodeEncryptionCode: 'originalPasscodeEncryptionCode',
};
const response = await wallets.generateWallet(params);
walletNock.isDone().should.be.true();
stubEddsaUtils.calledOnce.should.be.true();
assert.ok(response.encryptedWalletPassphrase);
assert.ok(response.wallet);
});
});
describe('Sharing', () => {
describe('Wallet share where keychainOverrideRequired is set true', () => {
const sandbox = sinon.createSandbox();
(0, mocha_1.afterEach)(function () {
sandbox.verifyAndRestore();
});
it('when password not provived we should receive validation error', async function () {
const shareId = 'test_case_1';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
keychainOverrideRequired: true,
permissions: ['admin', 'spend', 'view'],
});
// Validate accept share case
await ofcWallets
.acceptShare({ walletShareId: shareId })
.should.be.rejectedWith('userPassword param must be provided to decrypt shared key');
walletShareNock.done();
});
it('when we accept share and failed to make changes, reshare should not be called', async function () {
const shareId = 'test_case_2';
const keychainId = 'test_case_2';
const userPassword = 'test_case_2';
// create a user key
const keyChainNock = nock(bgUrl)
.post('/api/v2/ofc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200, (uri, requestBody) => {
return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
});
const walletShareInfoNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
keychainOverrideRequired: true,
permissions: ['admin', 'spend', 'view'],
});
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
// Check required fields are present (signature and payload are dynamic)
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.keyId === keychainId &&
typeof body.signature === 'string' &&
typeof body.payload === 'string');
})
.reply(200, { changed: false });
// Stub wallet share wallet method
const walletShareStub = sandbox.stub(sdk_core_1.Wallet.prototype, 'shareWallet').onCall(0).resolves('success');
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, false);
keyChainNock.done();
walletShareInfoNock.done();
acceptShareNock.done();
should.equal(walletShareStub.called, false);
});
it('when we accept share but state is not valid, reshare should not be called', async function () {
const shareId = 'test_case_3';
const keychainId = 'test_case_3';
const userPassword = 'test_case_3';
// create a user key
const keyChainNock = nock(bgUrl)
.post('/api/v2/ofc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200, (uri, requestBody) => {
return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
});
const walletShareInfoNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
keychainOverrideRequired: true,
permissions: ['admin', 'spend', 'view'],
});
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
// Check required fields are present (signature and payload are dynamic)
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.keyId === keychainId &&
typeof body.signature === 'string' &&
typeof body.payload === 'string');
})
.reply(200, { changed: true, state: 'not_accepted' });
// Stub wallet share wallet method
const walletShareStub = sandbox.stub(sdk_core_1.Wallet.prototype, 'shareWallet').onCall(0).resolves('success');
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'not_accepted');
keyChainNock.done();
walletShareInfoNock.done();
acceptShareNock.done();
should.equal(walletShareStub.called, false);
});
it('when we get a correct resposne from accept share method, but failed to reshare wallet with spenders', async function () {
const shareId = 'test_case_6';
const keychainId = 'test_case_6';
const spenderUserOne = {
payload: {
permissions: ['spend', 'view'],
user: 'test_case_6',
},
email: { email: 'test_case_6' },
id: 'test_case_6',
coin: 'ofc',
};
const spenderUserTwo = {
payload: {
permissions: ['spend', 'view'],
user: 'test_case_9',
},
email: { email: 'test_case_9' },
id: 'test_case_9',
coin: 'ofc',
};
const adminUser = {
payload: {
permissions: ['admin', 'spend', 'view'],
user: 'test_case_7',
},
email: { email: 'test_case_7' },
id: 'test_case_7',
coin: 'ofc',
};
const viewerUser = {
payload: {
permissions: ['view'],
user: 'test_case_8',
},
email: { email: 'test_case_8' },
id: 'test_case_8',
coin: 'ofc',
};
const userPassword = 'test_case_6';
const walletId = 'test_case_6';
const enterpriseId = 'test_case_6';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
keychainOverrideRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
// create a user key
const keyChainCreateNock = nock(bgUrl)
.post('/api/v2/ofc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200, (uri, requestBody) => {
return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
});
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
// Check required fields are present (signature and payload are dynamic)
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.keyId === keychainId &&
typeof body.signature === 'string' &&
typeof body.payload === 'string');
})
.reply(200, { changed: true, state: 'accepted' });
const walletInfoNock = nock(bgUrl)
.get(`/api/v2/ofc/wallet/${walletId}`)
.reply(200, {
users: [spenderUserOne.payload, spenderUserTwo.payload, adminUser.payload, viewerUser.payload],
enterprise: enterpriseId,
coin: spenderUserOne.coin,
id: walletId,
keys: [{}],
});
const enterpriseUserNock = nock(bgUrl)
.get(`/api/v1/enterprise/${enterpriseId}/user`)
.reply(200, {
adminUsers: [
{ id: spenderUserOne.id, email: spenderUserOne.email },
{ id: spenderUserTwo.id, email: spenderUserTwo.email },
{ id: adminUser.id, email: adminUser.email },
{ id: viewerUser.id, email: viewerUser.email },
],
nonAdminUsers: [],
});
const walletShareStub = sandbox
.stub(sdk_core_1.Wallet.prototype, 'shareWallet')
.returns(new Promise((_resolve, reject) => reject(new Error('Failed to reshare wallet'))));
const shareParamsOne = {
walletId: walletId,
user: spenderUserOne.id,
permissions: spenderUserOne.payload.permissions.join(','),
walletPassphrase: userPassword,
email: spenderUserOne.email.email,
reshare: true,
skipKeychain: false,
};
const shareParamsTwo = {
walletId: walletId,
user: spenderUserTwo.id,
permissions: spenderUserTwo.payload.permissions.join(','),
walletPassphrase: userPassword,
email: spenderUserTwo.email.email,
reshare: true,
skipKeychain: false,
};
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
keyChainCreateNock.done();
walletShareNock.done();
walletInfoNock.done();
acceptShareNock.done();
enterpriseUserNock.done();
should.equal(walletShareStub.calledOnce, true);
should.equal(walletShareStub.calledWith(shareParamsOne), true);
should.equal(walletShareStub.calledWith(shareParamsTwo), false);
});
it('when we get a correct resposne from accept share method and reshare wallet with spenders', async function () {
const shareId = 'test_case_6';
const keychainId = 'test_case_6';
const spenderUserOne = {
payload: {
permissions: ['spend', 'view'],
user: 'test_case_6',
},
email: { email: 'test_case_6' },
id: 'test_case_6',
coin: 'ofc',
};
const spenderUserTwo = {
payload: {
permissions: ['spend', 'view'],
user: 'test_case_9',
},
email: { email: 'test_case_9' },
id: 'test_case_9',
coin: 'ofc',
};
const adminUser = {
payload: {
permissions: ['admin', 'spend', 'view'],
user: 'test_case_7',
},
email: { email: 'test_case_7' },
id: 'test_case_7',
coin: 'ofc',
};
const viewerUser = {
payload: {
permissions: ['view'],
user: 'test_case_8',
},
email: { email: 'test_case_8' },
id: 'test_case_8',
coin: 'ofc',
};
const userPassword = 'test_case_6';
const walletId = 'test_case_6';
const enterpriseId = 'test_case_6';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/tbtc/walletshare/${shareId}`)
.reply(200, {
keychainOverrideRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
// create a user key
const keyChainCreateNock = nock(bgUrl)
.post('/api/v2/tbtc/key', _.conforms({ pub: (p) => p.startsWith('xpub') }))
.reply(200, (uri, requestBody) => {
return { id: keychainId, encryptedPrv: requestBody['encryptedPrv'], pub: requestBody['pub'] };
});
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/tbtc/walletshare/${shareId}`, (body) => {
// Check required fields are present (signature and payload are dynamic)
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.keyId === keychainId &&
typeof body.signature === 'string' &&
typeof body.payload === 'string');
})
.reply(200, { changed: true, state: 'accepted' });
const walletInfoNock = nock(bgUrl)
.get(`/api/v2/tbtc/wallet/${walletId}`)
.reply(200, {
users: [spenderUserOne.payload, spenderUserTwo.payload, adminUser.payload, viewerUser.payload],
enterprise: enterpriseId,
coin: spenderUserOne.coin,
id: walletId,
keys: [{}],
});
const enterpriseUserNock = nock(bgUrl)
.get(`/api/v1/enterprise/${enterpriseId}/user`)
.reply(200, {
adminUsers: [
{ id: spenderUserOne.id, email: spenderUserOne.email },
{ id: spenderUserTwo.id, email: spenderUserTwo.email },
{ id: adminUser.id, email: adminUser.email },
{ id: viewerUser.id, email: viewerUser.email },
],
nonAdminUsers: [],
});
const walletShareStub = sandbox
.stub(sdk_core_1.Wallet.prototype, 'shareWallet')
.returns(new Promise((resolve, _reject) => resolve('success')));
const shareParamsOne = {
walletId: walletId,
user: spenderUserOne.id,
permissions: spenderUserOne.payload.permissions.join(','),
walletPassphrase: userPassword,
email: spenderUserOne.email.email,
reshare: true,
skipKeychain: false,
};
const shareParamsTwo = {
walletId: walletId,
user: spenderUserTwo.id,
permissions: spenderUserTwo.payload.permissions.join(','),
walletPassphrase: userPassword,
email: spenderUserTwo.email.email,
reshare: true,
skipKeychain: false,
};
const res = await wallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
keyChainCreateNock.done();
walletShareNock.done();
walletInfoNock.done();
acceptShareNock.done();
enterpriseUserNock.done();
should.equal(walletShareStub.calledTwice, true);
should.equal(walletShareStub.calledWith(shareParamsOne), true);
should.equal(walletShareStub.calledWith(shareParamsTwo), true);
});
});
describe('Wallet share where userMultiKeyRotationRequired is set true', () => {
const sandbox = sinon.createSandbox();
(0, mocha_1.afterEach)(function () {
sandbox.verifyAndRestore();
});
it('should throw error when password not provided', async function () {
const shareId = 'test_multi_key_1';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
});
await ofcWallets
.acceptShare({ walletShareId: shareId })
.should.be.rejectedWith('userPassword param must be provided to generate user keychain');
walletShareNock.done();
});
it('should successfully accept share with userMultiKeyRotationRequired and send pub and encryptedPrv', async function () {
const shareId = 'test_multi_key_2';
const userPassword = 'test_password_123';
const walletId = 'test_wallet_123';
// Mock wallet share response
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
// Mock keychain creation - baseCoin.keychains().create() returns { prv, pub }
// We need to create a proper keychain object with prv property
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv, // OFC uses secp256k1 keys, so prv format
pub: testKeychain.pub,
};
// Stub keychains().create() and encrypt() BEFORE calculating encryptedPrv
const keychainsInstance = ofcWallets.baseCoin.keychains();
const keychainsStub = sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
// Mock the updateShare API call
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
// Verify that pub and encryptedPrv are included
if (body.walletShareId !== shareId || body.state !== 'accepted' || !body.pub || !body.encryptedPrv) {
return false;
}
// Verify pub is a valid format (secp256k1 public key for OFC)
if (!ofcWallets.baseCoin.isValidPub(body.pub)) {
return false;
}
return true;
})
.reply(200, { changed: true, state: 'accepted' });
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
// Verify keychain creation was called
should.equal(keychainsStub.calledOnce, true);
// Verify encrypt was called with the correct parameters
should.equal(encryptStub.calledWith({ input: keychain.prv, password: userPassword }), true);
walletShareNock.done();
acceptShareNock.done();
});
it('should NOT trigger reshare when userMultiKeyRotationRequired is true', async function () {
const shareId = 'test_multi_key_3';
const userPassword = 'test_password_123';
const walletId = 'test_wallet_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, { changed: true, state: 'accepted' });
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
// Stub reshareWalletWithSpenders to verify it's NOT called
const reshareStub = sandbox.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders');
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
// Verify reshare was NOT called (unlike keychainOverrideRequired case)
should.equal(reshareStub.called, false);
walletShareNock.done();
acceptShareNock.done();
});
it('should handle bulk accept share with userMultiKeyRotationRequired', async function () {
const shareId = 'test_multi_key_bulk_1';
const userPassword = 'test_password_123';
// Mock listSharesV2 to return a share with userMultiKeyRotationRequired
// Note: userMultiKeyRotationRequired shares don't have a keychain, so they won't be filtered
// by the bulkAcceptShare filter, but processAcceptShare will handle them
sandbox.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: shareId,
coin: 'ofc',
walletLabel: 'test wallet',
fromUser: 'fromUser',
toUser: 'toUser',
wallet: 'wallet123',
permissions: ['admin', 'spend', 'view'],
state: 'active',
userMultiKeyRotationRequired: true,
// No keychain - this is the key difference for multi-key-user-key shares
},
],
outgoing: [],
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Set up stubs first
const keychainsInstance = ofcWallets.baseCoin.keychains();
const keychainsStub = sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
// Mock bulk update API - this is called via bulkUpdateWalletShare
nock(bgUrl)
.put('/api/v2/walletshares/update', (body) => {
if (!body.shares || body.shares.length !== 1) {
return false;
}
const share = body.shares[0];
return (share.walletShareId === shareId &&
share.status === 'accept' &&
share.pub === keychain.pub &&
share.encryptedPrv === encryptedPrv);
})
.reply(200, {
acceptedWalletShares: [{ walletShareId: shareId }],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Note: bulkAcceptShare filters for shares WITH keychains, but userMultiKeyRotationRequired
// shares don't have keychains, so they go through a different path
// We need to stub the processAcceptShare path or use bulkUpdateWalletShare directly
// For this test, we'll use bulkUpdateWalletShare which calls processAcceptShare internally
const result = await ofcWallets.bulkUpdateWalletShare({
shares: [{ walletShareId: shareId, status: 'accept' }],
userLoginPassword: userPassword,
});
should.equal(result.acceptedWalletShares.length, 1);
should.deepEqual(result.acceptedWalletShares[0], { walletShareId: 'test_multi_key_bulk_1' });
should.equal(keychainsStub.calledOnce, true);
should.equal(encryptStub.calledWith({ input: keychain.prv, password: userPassword }), true);
});
it('should handle bulk accept share with userMultiKeyRotationRequired and newWalletPassphrase', async function () {
const shareId = 'test_multi_key_bulk_2';
const userPassword = 'test_password_123';
const newWalletPassphrase = 'new_wallet_passphrase_456';
// Mock listSharesV2 to return a share with userMultiKeyRotationRequired
sandbox.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: shareId,
coin: 'ofc',
walletLabel: 'test wallet',
fromUser: 'fromUser',
toUser: 'toUser',
wallet: 'wallet123',
permissions: ['admin', 'spend', 'view'],
state: 'active',
userMultiKeyRotationRequired: true,
// No keychain - this is the key difference for multi-key-user-key shares
},
],
outgoing: [],
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Set up stubs first
const keychainsInstance = ofcWallets.baseCoin.keychains();
const keychainsStub = sandbox.stub(keychainsInstance, 'create').returns(keychain);
// Should encrypt with newWalletPassphrase if provided (as per implementation)
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: newWalletPassphrase });
const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
// Mock bulk update API - this is called via bulkUpdateWalletShare
nock(bgUrl)
.put('/api/v2/walletshares/update', (body) => {
if (!body.shares || body.shares.length !== 1) {
return false;
}
const share = body.shares[0];
return (share.walletShareId === shareId &&
share.status === 'accept' &&
share.pub === keychain.pub &&
share.encryptedPrv === encryptedPrv);
})
.reply(200, {
acceptedWalletShares: [{ walletShareId: shareId }],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
const result = await ofcWallets.bulkUpdateWalletShare({
shares: [{ walletShareId: shareId, status: 'accept' }],
userLoginPassword: userPassword,
newWalletPassphrase: newWalletPassphrase,
});
should.equal(result.acceptedWalletShares.length, 1);
should.deepEqual(result.acceptedWalletShares[0], { walletShareId: shareId });
should.equal(keychainsStub.calledOnce, true);
// Verify encrypt was called with newWalletPassphrase (not userPassword)
should.equal(encryptStub.calledWith({ input: keychain.prv, password: newWalletPassphrase }), true);
});
it('should throw error when neither userLoginPassword nor newWalletPassphrase provided for bulk accept', async function () {
const shareId = 'test_multi_key_bulk_3';
// Mock listSharesV2 to return a share with userMultiKeyRotationRequired
sandbox.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: shareId,
coin: 'ofc',
walletLabel: 'test wallet',
fromUser: 'fromUser',
toUser: 'toUser',
wallet: 'wallet123',
permissions: ['admin', 'spend', 'view'],
state: 'active',
userMultiKeyRotationRequired: true,
},
],
outgoing: [],
});
// Mock user settings API call (required by bulkUpdateWalletShare)
nock(bgUrl).get('/api/v1/user/settings').reply(200, {});
// Mock bulkUpdateWalletShareRequest - when there are errors, it's called with empty array
nock(bgUrl)
.put('/api/v2/walletshares/update', (body) => {
return body.shares && body.shares.length === 0;
})
.reply(200, {
acceptedWalletShares: [],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// bulkUpdateWalletShare uses Promise.allSettled, so errors are caught and returned in walletShareUpdateErrors
// We need to check the result for errors instead of expecting a rejection
const result = await ofcWallets.bulkUpdateWalletShare({
shares: [{ walletShareId: shareId, status: 'accept' }],
});
// Verify that the error was captured in walletShareUpdateErrors
should.equal(result.walletShareUpdateErrors.length, 1);
should.equal(result.walletShareUpdateErrors[0].walletShareId, shareId);
should(result.walletShareUpdateErrors[0].reason).containEql('userLoginPassword param must be provided to generate user keychain');
});
it('should work with newWalletPassphrase parameter', async function () {
const shareId = 'test_multi_key_4';
const userPassword = 'test_password_123';
const newWalletPassphrase = 'new_wallet_passphrase_456';
const walletId = 'test_wallet_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Stub create() and encrypt() BEFORE calculating encryptedPrv to ensure consistency
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
// Should encrypt with newWalletPassphrase if provided (as per implementation)
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: newWalletPassphrase });
const encryptStub = sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.pub === keychain.pub &&
body.encryptedPrv === encryptedPrv);
})
.reply(200, { changed: true, state: 'accepted' });
const res = await ofcWallets.acceptShare({
walletShareId: shareId,
userPassword,
newWalletPassphrase,
});
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
// Verify encrypt was called with newWalletPassphrase
should.equal(encryptStub.calledWith({ input: keychain.prv, password: newWalletPassphrase }), true);
walletShareNock.done();
acceptShareNock.done();
});
it('should prioritize userMultiKeyRotationRequired over keychainOverrideRequired', async function () {
const shareId = 'test_multi_key_5';
const userPassword = 'test_password_123';
const walletId = 'test_wallet_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
keychainOverrideRequired: true, // Both set, but userMultiKeyRotationRequired should take precedence
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Set up stubs first
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
// Should use the multi-key-user-key flow (no signature/payload/keyId)
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
// Verify it's using multi-key-user-key flow (has pub and encryptedPrv, but no signature/payload/keyId)
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.pub === keychain.pub &&
body.encryptedPrv === encryptedPrv &&
!body.signature &&
!body.payload &&
!body.keyId);
})
.reply(200, { changed: true, state: 'accepted' });
const reshareStub = sandbox.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders');
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
// Verify reshare was NOT called (multi-key-user-key flow)
should.equal(reshareStub.called, false);
walletShareNock.done();
acceptShareNock.done();
});
it('should handle keychain creation failure', async function () {
const shareId = 'test_multi_key_6';
const userPassword = 'test_password_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
});
const keychainError = new Error('Failed to create keychain');
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').throws(keychainError);
await ofcWallets
.acceptShare({ walletShareId: shareId, userPassword })
.should.be.rejectedWith('Failed to create keychain');
walletShareNock.done();
});
it('should handle encryption failure', async function () {
const shareId = 'test_multi_key_7';
const userPassword = 'test_password_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptionError = new Error('Encryption failed');
sandbox.stub(bitgo, 'encrypt').throws(encryptionError);
await ofcWallets
.acceptShare({ walletShareId: shareId, userPassword })
.should.be.rejectedWith('Encryption failed');
walletShareNock.done();
});
it('should work with view-only permissions', async function () {
const shareId = 'test_multi_key_8';
const userPassword = 'test_password_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['view'], // View-only permissions
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Set up stubs first
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
return (body.walletShareId === shareId &&
body.state === 'accepted' &&
body.pub === keychain.pub &&
body.encryptedPrv === encryptedPrv);
})
.reply(200, { changed: true, state: 'accepted' });
const res = await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
walletShareNock.done();
acceptShareNock.done();
});
it('should verify exact values sent in API request', async function () {
const shareId = 'test_multi_key_9';
const userPassword = 'test_password_123';
const walletId = 'test_wallet_123';
const walletShareNock = nock(bgUrl)
.get(`/api/v2/ofc/walletshare/${shareId}`)
.reply(200, {
userMultiKeyRotationRequired: true,
permissions: ['admin', 'spend', 'view'],
wallet: walletId,
});
const testKeychain = bitgo.coin('ofc').keychains().create();
const keychain = {
prv: testKeychain.prv,
pub: testKeychain.pub,
};
// Set up stubs first
const keychainsInstance = ofcWallets.baseCoin.keychains();
sandbox.stub(keychainsInstance, 'create').returns(keychain);
const encryptedPrv = await bitgo.encrypt({ input: keychain.prv, password: userPassword });
sandbox.stub(bitgo, 'encrypt').resolves(encryptedPrv);
let capturedBody;
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/ofc/walletshare/${shareId}`, (body) => {
capturedBody = body;
return true;
})
.reply(200, { changed: true, state: 'accepted' });
await ofcWallets.acceptShare({ walletShareId: shareId, userPassword });
// Verify exact values
should.equal(capturedBody.walletShareId, shareId);
should.equal(capturedBody.state, 'accepted');
should.equal(capturedBody.pub, keychain.pub);
should.equal(capturedBody.encryptedPrv, encryptedPrv);
should.not.exist(capturedBody.signature);
should.not.exist(capturedBody.payload);
should.not.exist(capturedBody.keyId);
walletShareNock.done();
acceptShareNock.done();
});
});
it('should share a wallet to viewer', async function () {
const shareId = '12311';
nock(bgUrl).get(`/api/v2/tbtc/walletshare/${shareId}`).reply(200, {});
const acceptShareNock = nock(bgUrl)
.post(`/api/v2/tbtc/walletshare/${shareId}`, { walletShareId: shareId, state: 'accepted' })
.reply(200, {});
await wallets.acceptShare({ walletShareId: shareId });
acceptShareNock.done();
});
describe('v2 envelope support in acceptShare', () => {
const sandbox = sinon.createSandbox();
(0, mocha_1.afterEach)(() => sandbox.verifyAndRestore());
it('should accept share when ECDH sharing keychain encryptedXprv is v2-encrypted', async function () {
const shareId = 'v2-ecdh-xprv-1';
const userPassword = 'test_password';
// Simulate a v2 envelope for the ECDH root key
const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aabbcc', ct: 'ddeeff', adata: '00' });
const fakeXprv = 'xprvSomeBase58Value';
const fakeSecret = 'fakeEcdhSharedSecret';
const decryptedWalletPrv = 'walletPrivKeyPlaintext';
const eckey = (0, sdk_core_1.makeRandomKey)();
const v2EncryptedPrv = await bitgo.encrypt({ password: fakeSecret, input: decryptedWalletPrv });
nock(bgUrl)
.get(`/api/v2/tbtc/walletshare/${shareId}`)
.reply(200, {
keychain: {
path: 'm/0/0/1',
fromPubKey: eckey.publicKey.toString('hex'),
toPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: v2EncryptedPrv,
pub: eckey.publicKey.toString('hex'),
},
});
nock(bgUrl).post(`/api/v2/tbtc/walletshare/${shareId}`).reply(200, { changed: true, state: 'accepted' });
sandbox.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
const decryptAsyncStub = sandbox.stub(bitgo, 'decrypt');
// First call decrypts the ECDH keychain (v2), second decrypts the shared wallet prv
decryptAsyncStub.onFirstCall().resolves(fakeXprv);
decryptAsyncStub.onSecondCall().resolves(decryptedWalletPrv);
sandbox.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(fakeSecret));
const res = await wallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
// Must have called decrypt (not the sync decrypt) for both the ECDH key and the wallet prv
assert.equal(decryptAsyncStub.callCount, 2);
});
it('should accept share when wallet keychain encryptedPrv is v2-encrypted', async function () {
const shareId = 'v2-wallet-prv-1';
const userPassword = 'test_password';
const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aabbcc', ct: 'ddeeff', adata: '00' });
const fakeXprv = 'xprvAnotherKey';
const fakeSecret = 'ecdhSharedSecret2';
const decryptedWalletPrv = 'walletPrivKey2';
const v2EncryptedPrv = JSON.stringify({ v: 2, iv: '112233', ct: '445566', adata: '77' });
const eckey = (0, sdk_core_1.makeRandomKey)();
nock(bgUrl)
.get(`/api/v2/tbtc/walletshare/${shareId}`)
.reply(200, {
keychain: {
path: 'm/0/0/2',
fromPubKey: eckey.publicKey.toString('hex'),
toPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: v2EncryptedPrv,
pub: eckey.publicKey.toString('hex'),
},
});
nock(bgUrl).post(`/api/v2/tbtc/walletshare/${shareId}`).reply(200, { changed: true, state: 'accepted' });
sandbox.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
const decryptAsyncStub = sandbox.stub(bitgo, 'decrypt');
decryptAsyncStub.onFirstCall().resolves(fakeXprv);
decryptAsyncStub.onSecondCall().resolves(decryptedWalletPrv);
sandbox.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(fakeSecret));
const res = await wallets.acceptShare({ walletShareId: shareId, userPassword });
should.equal(res.changed, true);
should.equal(res.state, 'accepted');
});
});
describe('bulkAcceptShare', function () {
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
sinon.restore();
});
it('should throw validation error for userPassword empty string', async () => {
await wallets
.bulkAcceptShare({ walletShareIds: [], userLoginPassword: '' })
.should.rejectedWith('Please provide a valid user login password');
});
it('should throw validation error for sending walletPassphrase empty string', async () => {
await wallets
.bulkAcceptShare({ walletShareIds: [], userLoginPassword: 'password', newWalletPassphrase: 123 })
.should.rejectedWith('Please provide a valid wallet passphrase');
});
it('should throw assertion error for empty walletShareIds', async () => {
await wallets
.bulkAcceptShare({ walletShareIds: [], userLoginPassword: 'dummy@123' })
.should.rejectedWith('Please provide at least one wallet share to accept');
});
it('should throw error for no valid wallet shares', async () => {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'dummyWalletId',
permissions: ['spend'],
state: 'active',
},
],
outgoing: [],
});
await wallets
.bulkAcceptShare({
walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd1'],
userLoginPassword: 'dummy@123',
})
.should.rejectedWith('No valid wallet shares found to accept');
});
it('should throw error for no valid walletShares with keychain', async () => {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'dummyWalletId',
permissions: ['spend'],
state: 'active',
},
],
outgoing: [],
});
await wallets
.bulkAcceptShare({
walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd4'],
userLoginPassword: 'dummy@123',
})
.should.rejectedWith('No valid wallet shares found to accept');
});
it('should throw error for ecdh keychain undefined', async () => {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'dummyWalletId',
permissions: ['spend'],
state: 'active',
keychain: {
pub: 'pub',
toPubKey: 'toPubKey',
fromPubKey: 'fromPubKey',
encryptedPrv: 'encryptedPrv',
path: 'path',
},
},
],
outgoing: [],
});
sinon.stub(bitgo, 'getECDHKeychain').resolves({
prv: 'private key',
});
await wallets
.bulkAcceptShare({
walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd4'],
userLoginPassword: 'dummy@123',
})
.should.rejectedWith('encryptedXprv was not found on sharing keychain');
});
it('should successfully accept share', async () => {
const fromUserPrv = Math.random();
const walletPassphrase = 'bitgo1234';
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
nock(bgUrl)
.get('/api/v2/walletshares')
.reply(200, {
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
isUMSInitiated: true,
keychain: {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
},
],
});
nock(bgUrl)
.put('/api/v2/walletshares/accept')
.reply(200, {
acceptedWalletShares: [
{
walletShareId: '66a229dbdccdcfb95b44fc2745a60bd4',
},
],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
const share = await wallets.bulkAcceptShare({
walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd4'],
userLoginPassword: walletPassphrase,
});
assert.deepEqual(share, {
acceptedWalletShares: [
{
walletShareId: '66a229dbdccdcfb95b44fc2745a60bd4',
},
],
});
});
it('should accept share when ECDH sharing keychain is v2-encrypted', async () => {
const walletPassphrase = 'bitgo1234';
const shareId = '66a229dbdccdcfb95b44fc2745a60bd4';
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const decryptedPrv = 'someWalletPrivateKey';
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: decryptedPrv });
// Simulate v2-encrypted ECDH keychain xprv (envelope with v:2 marker)
const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aaa', ct: 'bbb', adata: 'ccc' });
const myEcdhXprv = 'xprvSomeBase58Key';
nock(bgUrl)
.get('/api/v2/walletshares')
.reply(200, {
incoming: [
{
id: shareId,
isUMSInitiated: true,
keychain: {
path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
},
],
});
nock(bgUrl)
.put('/api/v2/walletshares/accept')
.reply(200, { acceptedWalletShares: [{ walletShareId: shareId }] });
sinon.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
// decrypt resolves with the xprv regardless of whether the envelope is v1 or v2
sinon.stub(bitgo, 'decrypt').resolves(myEcdhXprv);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
const share = await wallets.bulkAcceptShare({
walletShareIds: [shareId],
userLoginPassword: walletPassphrase,
});
assert.deepEqual(share, { acceptedWalletShares: [{ walletShareId: shareId }] });
});
it('should accept share when wallet keychain encryptedPrv is v2-encrypted', async () => {
const walletPassphrase = 'bitgo1234';
const shareId = 'v2-prv-share-1';
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
// Simulate v2-encrypted encryptedPrv in the wallet share keychain
const v2EncryptedPrv = JSON.stringify({ v: 2, iv: 'xxx', ct: 'yyy', adata: 'zzz' });
const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aaa', ct: 'bbb', adata: 'ccc' });
const myEcdhXprv = 'xprvSomeBase58Key';
const decryptedWalletPrv = 'decryptedWalletPrivKey';
nock(bgUrl)
.get('/api/v2/walletshares')
.reply(200, {
incoming: [
{
id: shareId,
isUMSInitiated: true,
keychain: {
path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: v2EncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
},
],
});
nock(bgUrl)
.put('/api/v2/walletshares/accept')
.reply(200, { acceptedWalletShares: [{ walletShareId: shareId }] });
sinon.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
// First call: decrypt ECDH keychain xprv; second call: decrypt v2 wallet share prv
const decryptAsyncStub = sinon.stub(bitgo, 'decrypt');
decryptAsyncStub.onFirstCall().resolves(myEcdhXprv);
decryptAsyncStub.onSecondCall().resolves(decryptedWalletPrv);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
const share = await wallets.bulkAcceptShare({
walletShareIds: [shareId],
userLoginPassword: walletPassphrase,
});
assert.deepEqual(share, { acceptedWalletShares: [{ walletShareId: shareId }] });
// Both decrypt calls must use decrypt (not the sync decrypt)
assert.equal(decryptAsyncStub.callCount, 2);
});
it('should include webauthnInfo in request when provided (ECDH branch)', async () => {
const fromUserPrv = Math.random();
const walletPassphrase = 'bitgo1234';
const webauthnPassphrase = 'prf-derived-secret';
const shareId = '66a229dbdccdcfb95b44fc2745a60bd4';
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
let capturedBody;
nock(bgUrl)
.get('/api/v2/walletshares')
.reply(200, {
incoming: [
{
id: shareId,
isUMSInitiated: true,
keychain: {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
},
],
});
nock(bgUrl)
.put('/api/v2/walletshares/accept', (body) => {
capturedBody = body;
return true;
})
.reply(200, {
acceptedWalletShares: [{ walletShareId: shareId }],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
await wallets.bulkAcceptShare({
walletShareIds: [shareId],
userLoginPassword: walletPassphrase,
webauthnInfo: {
otpDeviceId: 'device-001',
prfSalt: 'salt-abc',
passphrase: webauthnPassphrase,
},
});
const sentEntries = capturedBody.keysForWalletShares;
sentEntries.should.have.length(1);
sentEntries[0].should.have.property('encryptedPrv');
sentEntries[0].should.have.property('webauthnInfo');
sentEntries[0].webauthnInfo.should.have.property('otpDeviceId', 'device-001');
sentEntries[0].webauthnInfo.should.have.property('prfSalt', 'salt-abc');
sentEntries[0].webauthnInfo.should.have.property('encryptedPrv');
sentEntries[0].webauthnInfo.should.not.have.property('passphrase');
});
it('should NOT include webauthnInfo when not provided (backward compat)', async () => {
const fromUserPrv = Math.random();
const walletPassphrase = 'bitgo1234';
const shareId = '66a229dbdccdcfb95b44fc2745a60bd4';
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
let capturedBody;
nock(bgUrl)
.get('/api/v2/walletshares')
.reply(200, {
incoming: [
{
id: shareId,
isUMSInitiated: true,
keychain: {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
},
],
});
nock(bgUrl)
.put('/api/v2/walletshares/accept', (body) => {
capturedBody = body;
return true;
})
.reply(200, {
acceptedWalletShares: [{ walletShareId: shareId }],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
await wallets.bulkAcceptShare({
walletShareIds: [shareId],
userLoginPassword: walletPassphrase,
});
const sentEntries = capturedBody.keysForWalletShares;
sentEntries.should.have.length(1);
sentEntries[0].should.have.property('encryptedPrv');
sentEntries[0].should.not.have.property('webauthnInfo');
});
it('should handle 413 payload too large error with smart retry', async () => {
const walletPassphrase = 'bitgo1234';
const fromUserPrv = Math.random();
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
// Pad the private key with additional data to make it larger before encrypting
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
const keychain = {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
};
const shareIds = Array.from({ length: 20 }, (_, i) => `share${i + 1}`);
// Mock listSharesV2 to return 25 shares
const shares = shareIds.map((id, index) => ({
id,
coin: 'tsol',
walletLabel: `testing${index}`,
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: `wallet${index}`,
permissions: ['spend'],
state: 'active',
keychain: keychain,
}));
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: shares,
outgoing: [],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(bitgo, 'encrypt').resolves(userPrv + 'X'.repeat(100000));
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
// Mock bulkAcceptShareRequestWithRetry to track batch sizes
const batchSizes = [];
nock(bgUrl)
.persist() // This ensures the interceptor remains active for multiple requests
.put('/api/v2/walletshares/accept')
.reply(function (_, requestBody, cb) {
const params = requestBody['keysForWalletShares'];
batchSizes.push(params.length);
if (Buffer.byteLength(JSON.stringify(requestBody), 'utf8') > 950000) {
// Simulate 413 error
return cb(null, [413, { error: 'Request Entity Too Large' }]);
}
// Return success for smaller batches
return cb(null, [
200,
{
acceptedWalletShares: params.map((param) => ({
walletShareId: param.walletShareId,
})),
},
]);
});
const result = await wallets.bulkAcceptShare({
walletShareIds: shareIds,
userLoginPassword: walletPassphrase,
});
// Should have tried with 20 (initial batch size for 25 items), then retried with smaller batches
batchSizes.length.should.be.greaterThan(1);
batchSizes.should.deepEqual([9, 9, 2]); // Initial batch size// Retry batches should be smaller
result.should.have.property('acceptedWalletShares');
result.acceptedWalletShares.should.be.an.Array();
result.acceptedWalletShares.length.should.equal(20);
result.acceptedWalletShares.forEach((share) => {
share.should.have.property('walletShareId');
share.walletShareId.should.match(/^share\d+$/);
});
});
it('should retry with progressively smaller batch sizes on 413 errors', async () => {
const walletPassphrase = 'bitgo1234';
const fromUserPrv = Math.random();
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
const keychain = {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
};
const shareIds = Array.from({ length: 20 }, (_, i) => `share${i + 1}`);
// Mock listSharesV2
const shares = shareIds.map((id, index) => ({
id,
coin: 'tsol',
walletLabel: `testing${index}`,
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: `wallet${index}`,
permissions: ['spend'],
state: 'active',
keychain: keychain,
}));
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: shares,
outgoing: [],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(bitgo, 'encrypt').resolves(userPrv + 'X'.repeat(100000));
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
// Track the sequence of batch sizes attempted
const batchSizeAttempts = [];
nock(bgUrl)
.persist() // This ensures the interceptor remains active for multiple requests
.put('/api/v2/walletshares/accept')
.reply(function (_, requestBody, cb) {
const params = requestBody['keysForWalletShares'];
batchSizeAttempts.push(params.length);
// Simulate 413 for batches > 5, success for batches <= 5
if (Buffer.byteLength(JSON.stringify(requestBody), 'utf8') > 600000) {
// Simulate 413 error
return cb(null, [413, { error: 'Request Entity Too Large' }]);
}
// Return success for smaller batches
return cb(null, [
200,
{
acceptedWalletShares: params.map((param) => ({
walletShareId: param.walletShareId || 'test',
})),
},
]);
});
const result = await wallets.bulkAcceptShare({
walletShareIds: shareIds,
userLoginPassword: walletPassphrase,
});
// Should see progressive batch size reduction: 20 -> 10 -> 5 (success)
batchSizeAttempts.should.containDeep([9, 4, 4, 4, 4, 4]);
result.should.have.property('acceptedWalletShares');
result.acceptedWalletShares.should.be.an.Array();
result.acceptedWalletShares.length.should.equal(20);
result.acceptedWalletShares.forEach((share) => {
share.should.have.property('walletShareId');
share.walletShareId.should.match(/^share\d+$/);
});
});
it('should throw error when batch size cannot be reduced further', async () => {
const walletPassphrase = 'bitgo1234';
const fromUserPrv = Math.random();
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
};
const userPrv = await (0, sdk_core_1.decryptKeychainPrivateKey)(bitgo, keychainTest, walletPassphrase);
if (!userPrv) {
throw new Error('Unable to decrypt user keychain');
}
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const newEncryptedPrv = await bitgo.encrypt({ password: secret, input: userPrv });
const keychain = {
path: path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: newEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
};
const shareIds = ['share1'];
// Mock listSharesV2
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['spend'],
state: 'active',
keychain: keychain,
},
],
outgoing: [],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
const prvKey = await bitgo.decrypt({
password: walletPassphrase,
input: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
sinon.stub(bitgo, 'decrypt').resolves(prvKey);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
// Always throw 413 error, even for batch size 1
nock(bgUrl)
.persist()
.put('/api/v2/walletshares/accept')
.reply(function (_, _requestBody, cb) {
// Always respond with 413 error
return cb(null, [413, { error: 'Request Entity Too Large' }]);
});
await wallets
.bulkAcceptShare({
walletShareIds: shareIds,
userLoginPassword: walletPassphrase,
})
.should.be.rejectedWith('Request Entity Too Large');
});
describe('EncryptionSession (HKDF)', function () {
async function stubForShares(shareCount, decryptedWalletPrv, walletPassphrase) {
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const senderEncryptedPrv = await bitgo.encrypt({ password: secret, input: decryptedWalletPrv });
const shareIds = Array.from({ length: shareCount }, (_, i) => `hkdf-share-${i}`);
const shares = shareIds.map((id, index) => ({
id,
coin: 'tsol',
walletLabel: `w${index}`,
fromUser: 'from',
toUser: 'to',
wallet: `w${index}`,
enterprise: `ent-${index}`,
permissions: ['spend'],
state: 'active',
keychain: {
path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: senderEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
}));
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({ incoming: shares, outgoing: [] });
const ecdh = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: ecdh.xprv, password: walletPassphrase }),
});
const decryptStub = sinon.stub(bitgo, 'decrypt');
decryptStub.onFirstCall().resolves(ecdh.xprv);
decryptStub.resolves(decryptedWalletPrv);
sinon.stub(moduleBitgo, 'getSharedSecret').resolves(secret);
return { shareIds };
}
it('opens one session per passphrase and destroys them after the loop', async function () {
const walletPassphrase = 'strong-outer-passphrase';
const decryptedWalletPrv = 'plaintext-wallet-prv';
const { shareIds } = await stubForShares(3, decryptedWalletPrv, walletPassphrase);
const realSession = await bitgo.createEncryptionSession(walletPassphrase);
const destroySpy = sinon.spy(realSession, 'destroy');
const sessionStub = sinon.stub(bitgo, 'createEncryptionSession').resolves(realSession);
nock(bgUrl)
.put('/api/v2/walletshares/accept')
.reply(200, {
acceptedWalletShares: shareIds.map((id) => ({ walletShareId: id })),
});
await wallets.bulkAcceptShare({ walletShareIds: shareIds, userLoginPassword: walletPassphrase });
sessionStub.callCount.should.equal(1);
sessionStub.firstCall.args[0].should.equal(walletPassphrase);
destroySpy.called.should.equal(true);
});
it('produces standalone-decryptable v2 envelopes with unique per-envelope hkdfSalts', async function () {
const walletPassphrase = 'session-passphrase-42';
const decryptedWalletPrv = 'secret-wallet-material';
const { shareIds } = await stubForShares(4, decryptedWalletPrv, walletPassphrase);
let captured;
nock(bgUrl)
.put('/api/v2/walletshares/accept', (body) => {
captured = body;
return true;
})
.reply(200, {
acceptedWalletShares: shareIds.map((id) => ({ walletShareId: id })),
});
await wallets.bulkAcceptShare({ walletShareIds: shareIds, userLoginPassword: walletPassphrase });
const entries = captured.keysForWalletShares;
entries.should.have.length(4);
const envelopes = entries.map((e) => JSON.parse(e.encryptedPrv));
for (const env of envelopes) {
env.should.have.property('v', 2);
env.should.have.property('hkdfSalt');
env.should.have.property('salt');
}
// Same session ⇒ same Argon2 salt across envelopes
const argonSalts = new Set(envelopes.map((e) => e.salt));
argonSalts.size.should.equal(1);
// Unique HKDF salt per envelope ⇒ independent AES keys
const hkdfSalts = new Set(envelopes.map((e) => e.hkdfSalt));
hkdfSalts.size.should.equal(4);
// Cross-wallet isolation: every envelope decrypts back under the same passphrase
for (const env of envelopes) {
const roundTrip = await bitgo.decrypt({ password: walletPassphrase, input: JSON.stringify(env) });
roundTrip.should.equal(decryptedWalletPrv);
}
});
it('opens a second, independent session for webauthnInfo.passphrase and binds adata per share', async function () {
const walletPassphrase = 'outer-pw';
const webauthnPassphrase = 'webauthn-prf-pw';
const decryptedWalletPrv = 'wallet-prv-webauthn-case';
const { shareIds } = await stubForShares(2, decryptedWalletPrv, walletPassphrase);
const sessionSpy = sinon.spy(bitgo, 'createEncryptionSession');
let captured;
nock(bgUrl)
.put('/api/v2/walletshares/accept', (body) => {
captured = body;
return true;
})
.reply(200, { acceptedWalletShares: shareIds.map((id) => ({ walletShareId: id })) });
await wallets.bulkAcceptShare({
walletShareIds: shareIds,
userLoginPassword: walletPassphrase,
webauthnInfo: { otpDeviceId: 'dev', prfSalt: 'salt', passphrase: webauthnPassphrase },
});
sessionSpy.callCount.should.equal(2);
const passwords = sessionSpy.getCalls().map((c) => c.args[0]);
passwords.should.containEql(walletPassphrase);
passwords.should.containEql(webauthnPassphrase);
const entries = captured.keysForWalletShares;
for (let i = 0; i < entries.length; i++) {
const webEnv = JSON.parse(entries[i].webauthnInfo.encryptedPrv);
webEnv.should.have.property('adata', `ent-${i}`);
const rt = await bitgo.decrypt({ password: webauthnPassphrase, input: JSON.stringify(webEnv) });
rt.should.equal(decryptedWalletPrv);
}
});
it('destroys the session even when the accept API call fails', async function () {
const walletPassphrase = 'pw-error';
const decryptedWalletPrv = 'x';
const { shareIds } = await stubForShares(2, decryptedWalletPrv, walletPassphrase);
const realSession = await bitgo.createEncryptionSession(walletPassphrase);
const destroySpy = sinon.spy(realSession, 'destroy');
sinon.stub(bitgo, 'createEncryptionSession').resolves(realSession);
nock(bgUrl).put('/api/v2/walletshares/accept').reply(500, { error: 'boom' });
await wallets
.bulkAcceptShare({ walletShareIds: shareIds, userLoginPassword: walletPassphrase })
.should.be.rejected();
destroySpy.called.should.equal(true);
});
it('threads encryptionVersion=1 into the factory so v1 envelopes are produced', async function () {
const walletPassphrase = 'v1-caller';
const decryptedWalletPrv = 'legacy';
const { shareIds } = await stubForShares(2, decryptedWalletPrv, walletPassphrase);
const sessionSpy = sinon.spy(bitgo, 'createEncryptionSession');
let captured;
nock(bgUrl)
.put('/api/v2/walletshares/accept', (body) => {
captured = body;
return true;
})
.reply(200, { acceptedWalletShares: shareIds.map((id) => ({ walletShareId: id })) });
await wallets.bulkAcceptShare({
walletShareIds: shareIds,
userLoginPassword: walletPassphrase,
encryptionVersion: 1,
});
// Factory is still called uniformly, but with encryptionVersion=1
sessionSpy.callCount.should.equal(1);
sessionSpy.firstCall.args[1].should.equal(1);
const entries = captured.keysForWalletShares;
const envelopes = entries.map((e) => JSON.parse(e.encryptedPrv));
for (const env of envelopes) {
env.should.not.have.property('hkdfSalt');
env.should.have.property('iter'); // v1 SJCL
}
});
});
});
describe('bulkUpdateWalletShare', function () {
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
sinon.restore();
});
it('should throw validation error for missing shares parameter', async () => {
await wallets.bulkUpdateWalletShare({}).should.be.rejectedWith('Missing parameter: shares');
});
it('should throw validation error for non-array shares parameter', async () => {
await wallets
.bulkUpdateWalletShare({ shares: 'not-an-array' })
.should.be.rejectedWith('Expecting parameter array: shares but found string');
});
it('should throw validation error for missing walletShareId in share', async () => {
await wallets
.bulkUpdateWalletShare({ shares: [{ status: 'accept' }] })
.should.be.rejectedWith('Missing walletShareId in share');
});
it('should throw validation error for missing status in share', async () => {
await wallets
.bulkUpdateWalletShare({ shares: [{ walletShareId: '123' }] })
.should.be.rejectedWith('Missing status in share');
});
it('should throw validation error for invalid status in share', async () => {
await wallets
.bulkUpdateWalletShare({ shares: [{ walletShareId: '123', status: 'invalid' }] })
.should.be.rejectedWith('Invalid status in share: invalid. Must be either "accept" or "reject"');
});
it('should throw validation error for non-string walletShareId', async () => {
await wallets
.bulkUpdateWalletShare({ shares: [{ walletShareId: 123, status: 'accept' }] })
.should.be.rejectedWith('Expecting walletShareId to be a string but found number');
});
it('should throw validation error for non-string userLoginPassword', async () => {
await wallets
.bulkUpdateWalletShare({ shares: [{ walletShareId: '123', status: 'accept' }], userLoginPassword: 123 })
.should.be.rejectedWith('Expecting parameter string: userLoginPassword but found number');
});
it('should throw validation error for non-string newWalletPassphrase', async () => {
await wallets
.bulkUpdateWalletShare({
shares: [{ walletShareId: '123', status: 'accept' }],
userLoginPassword: 'password',
newWalletPassphrase: 123,
})
.should.be.rejectedWith('Expecting parameter string: newWalletPassphrase but found number');
});
it('should throw assertion error for empty shares array', async () => {
await wallets.bulkUpdateWalletShare({ shares: [] }).should.be.rejectedWith('no shares are passed');
});
it('should throw error for no valid wallet shares', async () => {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'dummyWalletId',
permissions: ['spend'],
state: 'active',
},
],
outgoing: [],
});
await wallets
.bulkUpdateWalletShare({
shares: [{ walletShareId: '66a229dbdccdcfb95b44fc2745a60bd1', status: 'accept' }],
userLoginPassword: 'dummy@123',
})
.should.be.rejectedWith('invalid wallet share provided: 66a229dbdccdcfb95b44fc2745a60bd1');
});
it('should throw error for ecdh keychain undefined when accepting share requiring decryption', async () => {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: '66a229dbdccdcfb95b44fc2745a60bd4',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'dummyWalletId',
permissions: ['spend'],
state: 'active',
keychain: {
pub: 'pub',
toPubKey: 'toPubKey',
fromPubKey: 'fromPubKey',
encryptedPrv: 'encryptedPrv',
path: 'path',
},
},
],
outgoing: [],
});
sinon.stub(bitgo, 'getECDHKeychain').resolves({
prv: 'private key',
});
await wallets
.bulkUpdateWalletShare({
shares: [{ walletShareId: '66a229dbdccdcfb95b44fc2745a60bd4', status: 'accept' }],
userLoginPassword: 'dummy@123',
})
.should.be.rejectedWith('encryptedXprv was not found on sharing keychain');
});
it('should successfully update shares with both accept and reject statuses', async () => {
const walletPassphrase = 'bitgo1234';
// Mock listSharesV2 to return two shares
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['spend'],
state: 'active',
},
{
id: 'share2',
coin: 'tsol',
walletLabel: 'testing2',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet2',
permissions: ['spend'],
state: 'active',
},
],
outgoing: [],
});
// Mock bulkUpdateWalletShareRequest
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: ['share2'],
walletShareUpdateErrors: [],
});
const result = await wallets.bulkUpdateWalletShare({
shares: [
{ walletShareId: 'share1', status: 'accept' },
{ walletShareId: 'share2', status: 'reject' },
],
userLoginPassword: walletPassphrase,
});
// Verify the result
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: ['share2'],
walletShareUpdateErrors: [],
});
// Verify bulkUpdateWalletShareRequest was called with correct parameters
bulkUpdateStub.calledOnce.should.be.true();
const updateParams = bulkUpdateStub.firstCall.args[0];
updateParams.should.have.lengthOf(2);
// Second param should be for share2 with reject status
updateParams.should.containDeep([
{
walletShareId: 'share2',
status: 'reject',
},
]);
});
it('should handle keychainOverrideRequired with newWalletPassphrase in bulk operations', async () => {
const userLoginPassword = 'bitgo1234';
const newWalletPassphrase = 'new_wallet_passphrase_456';
// Mock listSharesV2 to return a share with keychainOverrideRequired
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['admin', 'spend'],
state: 'active',
keychainOverrideRequired: true,
},
],
outgoing: [],
});
// Mock user settings API call (required by bulkUpdateWalletShare)
nock(bgUrl).get('/api/v1/user/settings').reply(200, {});
// Mock getECDHKeychain (required by bulkUpdateWalletShare when userLoginPassword is provided)
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: 'encryptedXprv',
});
// Setup for the baseCoin.keychains().createUserKeychain
const userKeychain = {
id: 'key1',
pub: 'pubKey',
encryptedPrv: 'encryptedPrivateKey',
};
const createUserKeychainStub = sinon
.stub(wallets.baseCoin.keychains(), 'createUserKeychain')
.resolves(userKeychain);
// Mock decrypt and signMessage
sinon.stub(bitgo, 'decrypt').resolves('decryptedPrivateKey');
sinon.stub(wallets.baseCoin, 'signMessage').resolves(Buffer.from('signature'));
// Mock bulkUpdateWalletShareRequest
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Mock reshareWalletWithSpenders (called for keychainOverrideRequired cases)
const reshareStub = sinon.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders').resolves();
const result = await wallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'share1', status: 'accept' }],
userLoginPassword: userLoginPassword,
newWalletPassphrase: newWalletPassphrase,
});
// Verify createUserKeychain was called with newWalletPassphrase (not userLoginPassword)
createUserKeychainStub.calledOnce.should.be.true();
createUserKeychainStub.calledWith(newWalletPassphrase).should.be.true();
// Verify the result
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
bulkUpdateStub.calledOnce.should.be.true();
// Verify reshare was called for keychainOverrideRequired case
reshareStub.calledOnce.should.be.true();
});
it('should handle special override cases and reshare with spenders', async () => {
const walletPassphrase = 'bitgo1234';
// Mock listSharesV2 to return a share with keychainOverrideRequired
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'ofc',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['admin', 'spend'],
state: 'active',
keychainOverrideRequired: true,
},
],
outgoing: [],
});
// Setup for the baseCoin.keychains().createUserKeychain
const userKeychain = {
id: 'key1',
pub: 'pubKey',
encryptedPrv: 'encryptedPrivateKey',
};
sinon.stub(ofcWallets.baseCoin.keychains(), 'createUserKeychain').resolves(userKeychain);
// Mock decrypt and signMessage
sinon.stub(bitgo, 'decrypt').resolves('decryptedPrivateKey');
sinon.stub(ofcWallets.baseCoin, 'signMessage').resolves(Buffer.from('signature'));
// Mock getECDHKeychain
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: 'encryptedXprv',
});
// Mock bulkUpdateWalletShareRequest
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Mock reshareWalletWithSpenders
const reshareStub = sinon.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders').resolves();
const result = await ofcWallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'share1', status: 'accept' }],
userLoginPassword: walletPassphrase,
});
// Verify the result
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Verify bulkUpdateWalletShareRequest was called
bulkUpdateStub.calledOnce.should.be.true();
// Verify reshareWalletWithSpenders was called with correct parameters
reshareStub.calledOnce.should.be.true();
reshareStub.firstCall.args[0].should.equal('wallet1');
reshareStub.firstCall.args[1].should.equal(walletPassphrase);
});
it('should handle shares with no keychain to decrypt', async () => {
const walletPassphrase = 'bitgo1234';
// Mock listSharesV2 to return a share with no keychain
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['view'],
state: 'active',
},
],
outgoing: [],
});
// Mock bulkUpdateWalletShareRequest
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
const result = await wallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'share1', status: 'accept' }],
userLoginPassword: walletPassphrase,
});
// Verify the result
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Verify bulkUpdateWalletShareRequest was called with correct parameters
bulkUpdateStub.calledOnce.should.be.true();
const updateParams = bulkUpdateStub.firstCall.args[0];
updateParams.should.have.lengthOf(1);
// Param should be for share1 with accept status and no additional fields
updateParams.should.containDeep([
{
walletShareId: 'share1',
status: 'accept',
},
]);
});
it('should handle shares with keychain requiring decryption', async () => {
const walletPassphrase = 'bitgo1234';
const path = 'm/999999/1/1';
// Create test keychains
const fromKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef01deadbeef01deadbeef01deadbeef01', 'hex'));
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const fromPubKey = fromKeychain.publicKey.toString('hex');
const toPubKey = toKeychain.derivePath(path).publicKey.toString('hex');
// Create encrypted private key
const originalPrivKey = 'originalPrivateKey';
const sharedSecret = (0, sdk_core_1.getSharedSecret)(fromKeychain, Buffer.from(toPubKey, 'hex')).toString('hex');
const encryptedPrv = await bitgo.encrypt({
password: sharedSecret,
input: originalPrivKey,
});
// Mock listSharesV2 to return a share with keychain
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['spend'],
state: 'active',
keychain: {
pub: toPubKey,
toPubKey: toPubKey,
fromPubKey: fromPubKey,
encryptedPrv: encryptedPrv,
path: path,
},
},
],
outgoing: [],
});
// Mock getECDHKeychain
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
});
// Setup decrypt stubs
const decryptStub = sinon.stub(bitgo, 'decrypt');
decryptStub.onFirstCall().resolves(myEcdhKeychain.xprv); // For sharing keychain
decryptStub.onSecondCall().resolves(originalPrivKey); // For wallet keychain
// Mock getSharedSecret
sinon.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(sharedSecret));
// Mock bulkUpdateWalletShareRequest
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
const result = await wallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'share1', status: 'accept' }],
userLoginPassword: walletPassphrase,
newWalletPassphrase: 'newPassphrase',
});
// Verify the result
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Verify bulkUpdateWalletShareRequest was called with correct parameters
bulkUpdateStub.calledOnce.should.be.true();
const updateParams = bulkUpdateStub.firstCall.args[0];
updateParams.should.have.lengthOf(1);
updateParams[0].should.have.property('walletShareId', 'share1');
updateParams[0].should.have.property('status', 'accept');
// encryptedPrv is now emitted by the session; verify it's a real v2 envelope that
// decrypts back to the original prv under newPassphrase.
const envelope = JSON.parse(updateParams[0].encryptedPrv);
envelope.should.have.property('v', 2);
envelope.should.have.property('hkdfSalt');
// Session encrypt bypasses bitgo.decrypt's stub -- restore then decrypt the envelope
decryptStub.restore();
const rt = await bitgo.decrypt({ password: 'newPassphrase', input: updateParams[0].encryptedPrv });
rt.should.equal(originalPrivKey);
});
it('should handle rejected promises and add them to walletShareUpdateErrors', async () => {
const walletPassphrase = 'bitgo1234';
// Mock listSharesV2 to return two shares
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['spend'],
state: 'active',
},
{
id: 'share2',
coin: 'tsol',
walletLabel: 'testing2',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet2',
permissions: ['spend'],
state: 'active',
},
{
id: 'share3',
coin: 'tsol',
walletLabel: 'testing3',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet3',
permissions: ['spend'],
state: 'active',
},
],
outgoing: [],
});
// Stub processAcceptShare to throw an error for share2
// Using 'as any' to bypass TypeScript's private method restriction
const processAcceptShareStub = sinon.stub(sdk_core_1.Wallets.prototype, 'processAcceptShare');
processAcceptShareStub
.withArgs('share1', sinon.match.any, sinon.match.any, sinon.match.any, sinon.match.any)
.resolves([{ walletShareId: 'share1', status: 'accept' }]);
processAcceptShareStub
.withArgs('share2', sinon.match.any, sinon.match.any, sinon.match.any, sinon.match.any)
.rejects(new Error('Failed to process share2'));
processAcceptShareStub
.withArgs('share3', sinon.match.any, sinon.match.any, sinon.match.any, sinon.match.any)
.resolves([{ walletShareId: 'share3', status: 'accept' }]);
// Mock bulkUpdateWalletShareRequest to return a response
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1', 'share3'],
rejectedWalletShares: [],
walletShareUpdateErrors: [], // Empty array that should be populated
});
const result = await wallets.bulkUpdateWalletShare({
shares: [
{ walletShareId: 'share1', status: 'accept' },
{ walletShareId: 'share2', status: 'accept' },
{ walletShareId: 'share3', status: 'accept' },
],
userLoginPassword: walletPassphrase,
});
// Verify bulkUpdateWalletShareRequest was called with only the successful share
bulkUpdateStub.calledOnce.should.be.true();
const updateParams = bulkUpdateStub.firstCall.args[0];
updateParams.should.have.lengthOf(2);
updateParams[0].walletShareId.should.equal('share1');
updateParams[0].status.should.equal('accept');
updateParams[1].walletShareId.should.equal('share3');
updateParams[1].status.should.equal('accept');
// Verify the result contains the error information
result.should.have.property('walletShareUpdateErrors');
result.walletShareUpdateErrors.should.be.an.Array();
result.walletShareUpdateErrors.should.have.lengthOf(1);
result.walletShareUpdateErrors[0].should.have.property('walletShareId', 'share2');
result.walletShareUpdateErrors[0].should.have.property('reason', 'Failed to process share2');
});
it('should accept share with v2-encrypted ECDH keychain and wallet prv', async () => {
const walletPassphrase = 'bitgo1234';
const path = 'm/999999/1/1';
const fromKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef01deadbeef01deadbeef01deadbeef01', 'hex'));
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef02deadbeef02deadbeef02deadbeef02', 'hex'));
const toPubKey = toKeychain.derivePath(path).publicKey.toString('hex');
const fromPubKey = fromKeychain.publicKey.toString('hex');
const originalPrivKey = 'originalPrivateKey';
const sharedSecret = (0, sdk_core_1.getSharedSecret)(fromKeychain, Buffer.from(toPubKey, 'hex')).toString('hex');
const encryptedPrv = await bitgo.encrypt({ password: sharedSecret, input: originalPrivKey });
// Both the ECDH keychain and share prv are v2-encrypted in this scenario
const v2EncryptedXprv = JSON.stringify({ v: 2, iv: 'aabbcc', ct: 'ddeeff', adata: '00' });
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'share1',
coin: 'tsol',
walletLabel: 'testing',
fromUser: 'dummyFromUser',
toUser: 'dummyToUser',
wallet: 'wallet1',
permissions: ['spend'],
state: 'active',
keychain: { pub: toPubKey, toPubKey, fromPubKey, encryptedPrv, path },
},
],
outgoing: [],
});
const myEcdhKeychain = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: v2EncryptedXprv });
// decrypt handles v2 transparently; stub to return expected values
const decryptAsyncStub = sinon.stub(bitgo, 'decrypt');
decryptAsyncStub.onFirstCall().resolves(myEcdhKeychain.xprv); // ECDH keychain
decryptAsyncStub.onSecondCall().resolves(originalPrivKey); // wallet share prv
sinon.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(sharedSecret));
const bulkUpdateStub = sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
const result = await wallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'share1', status: 'accept' }],
userLoginPassword: walletPassphrase,
newWalletPassphrase: 'newPassphrase',
});
assert.deepEqual(result, {
acceptedWalletShares: ['share1'],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Both decrypt calls must have gone through decrypt
assert.equal(decryptAsyncStub.callCount, 2);
bulkUpdateStub.calledOnce.should.be.true();
// Encryption now goes through the session; assert a real v2 envelope round-trips
const updateParams = bulkUpdateStub.firstCall.args[0];
const envelope = JSON.parse(updateParams[0].encryptedPrv);
envelope.should.have.property('v', 2);
envelope.should.have.property('hkdfSalt');
decryptAsyncStub.restore();
const rt = await bitgo.decrypt({ password: 'newPassphrase', input: updateParams[0].encryptedPrv });
rt.should.equal(originalPrivKey);
});
describe('EncryptionSession (HKDF)', function () {
// Build a set of accept-status shares with realistic ECDH-encrypted keychains so
// bulkUpdateWalletShare walks the standard re-encrypt path for every share.
async function stubForAcceptShares(shareCount, decryptedWalletPrv, walletPassphrase) {
const toKeychain = utxoLib.bip32.fromSeed(Buffer.from('deadbeef03deadbeef03deadbeef03deadbeef03', 'hex'));
const path = 'm/999999/1/1';
const pubkey = toKeychain.derivePath(path).publicKey.toString('hex');
const eckey = (0, sdk_core_1.makeRandomKey)();
const secret = (0, sdk_core_1.getSharedSecret)(eckey, Buffer.from(pubkey, 'hex')).toString('hex');
const senderEncryptedPrv = await bitgo.encrypt({ password: secret, input: decryptedWalletPrv });
const shareIds = Array.from({ length: shareCount }, (_, i) => `bulk-update-share-${i}`);
const shares = shareIds.map((id, index) => ({
id,
coin: 'tsol',
walletLabel: `w${index}`,
fromUser: 'from',
toUser: 'to',
wallet: `w${index}`,
permissions: ['spend'],
state: 'active',
keychain: {
path,
fromPubKey: eckey.publicKey.toString('hex'),
encryptedPrv: senderEncryptedPrv,
toPubKey: pubkey,
pub: pubkey,
},
}));
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({ incoming: shares, outgoing: [] });
const ecdh = await bitgo.keychains().create();
sinon.stub(bitgo, 'getECDHKeychain').resolves({
encryptedXprv: await bitgo.encrypt({ input: ecdh.xprv, password: walletPassphrase }),
});
const decryptStub = sinon.stub(bitgo, 'decrypt');
decryptStub.onFirstCall().resolves(ecdh.xprv);
decryptStub.resolves(decryptedWalletPrv);
sinon.stub(moduleBitgo, 'getSharedSecret').returns(Buffer.from(secret));
return { shareIds };
}
it('opens one session over the outer passphrase and destroys it after the loop', async function () {
const walletPassphrase = 'update-passphrase';
const { shareIds } = await stubForAcceptShares(3, 'plaintext-prv', walletPassphrase);
const realSession = await bitgo.createEncryptionSession(walletPassphrase);
const destroySpy = sinon.spy(realSession, 'destroy');
const sessionStub = sinon.stub(bitgo, 'createEncryptionSession').resolves(realSession);
sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: shareIds,
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
await wallets.bulkUpdateWalletShare({
shares: shareIds.map((id) => ({ walletShareId: id, status: 'accept' })),
userLoginPassword: walletPassphrase,
});
sessionStub.callCount.should.equal(1);
sessionStub.firstCall.args[0].should.equal(walletPassphrase);
destroySpy.called.should.equal(true);
});
it('threads the session into processAcceptShare so envelopes carry the same argon2 salt', async function () {
const walletPassphrase = 'shared-argon2-salt-test';
const { shareIds } = await stubForAcceptShares(4, 'plaintext-prv', walletPassphrase);
let capturedShares = [];
sinon
.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest')
.callsFake(async (shares) => {
capturedShares = shares;
return { acceptedWalletShares: shareIds, rejectedWalletShares: [], walletShareUpdateErrors: [] };
});
await wallets.bulkUpdateWalletShare({
shares: shareIds.map((id) => ({ walletShareId: id, status: 'accept' })),
userLoginPassword: walletPassphrase,
});
capturedShares.should.have.length(4);
const envelopes = capturedShares.map((s) => JSON.parse(s.encryptedPrv));
for (const env of envelopes) {
env.should.have.property('v', 2);
env.should.have.property('hkdfSalt');
}
const argonSalts = new Set(envelopes.map((e) => e.salt));
argonSalts.size.should.equal(1); // one session -> one argon2 salt
const hkdfSalts = new Set(envelopes.map((e) => e.hkdfSalt));
hkdfSalts.size.should.equal(4); // per-envelope key isolation
// Cross-envelope round-trip: each envelope decrypts under the same passphrase
for (const env of envelopes) {
const rt = await bitgo.decrypt({ password: walletPassphrase, input: JSON.stringify(env) });
rt.should.equal('plaintext-prv');
}
});
it('bounds concurrent processAcceptShare calls at BULK_SHARE_BATCH_SIZE (16)', async function () {
const walletPassphrase = 'batch-cap-pw';
const { shareIds } = await stubForAcceptShares(20, 'plaintext-prv', walletPassphrase);
sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: shareIds,
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
// Track concurrent in-flight processAcceptShare invocations. The batching in
// bulkUpdateWalletShare should cap this at BULK_SHARE_BATCH_SIZE (16).
let inFlight = 0;
let maxInFlight = 0;
sinon.stub(sdk_core_1.Wallets.prototype, 'processAcceptShare').callsFake(async (...args) => {
const walletShareId = args[0];
inFlight++;
maxInFlight = Math.max(maxInFlight, inFlight);
await new Promise((r) => setTimeout(r, 5));
inFlight--;
return [{ walletShareId, status: 'accept' }];
});
await wallets.bulkUpdateWalletShare({
shares: shareIds.map((id) => ({ walletShareId: id, status: 'accept' })),
userLoginPassword: walletPassphrase,
});
maxInFlight.should.be.lessThanOrEqual(16);
});
it('does not open a session when the bulk contains only rejects', async function () {
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: 'reject-1',
coin: 'tsol',
walletLabel: 'x',
fromUser: 'a',
toUser: 'b',
wallet: 'w',
permissions: ['view'],
state: 'active',
},
],
outgoing: [],
});
const sessionStub = sinon.stub(bitgo, 'createEncryptionSession');
sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: [],
rejectedWalletShares: ['reject-1'],
walletShareUpdateErrors: [],
});
await wallets.bulkUpdateWalletShare({
shares: [{ walletShareId: 'reject-1', status: 'reject' }],
userLoginPassword: 'irrelevant',
});
sessionStub.callCount.should.equal(0);
});
it('threads the session through createUserKeychain in the special override path', async function () {
const walletPassphrase = 'override-pw';
const shareId = 'override-share-1';
const walletId = 'override-wallet';
sinon.stub(sdk_core_1.Wallets.prototype, 'listSharesV2').resolves({
incoming: [
{
id: shareId,
coin: 'ofc',
walletLabel: 'x',
fromUser: 'a',
toUser: 'b',
wallet: walletId,
permissions: ['admin', 'spend', 'view'],
state: 'active',
keychainOverrideRequired: true,
},
],
outgoing: [],
});
const testKeychain = bitgo.coin('ofc').keychains().create();
// Short-circuit createUserKeychain so the test doesn't hit the /key API dance; the
// point of this test is verifying the session argument threading, nothing more.
const createUserKeychainStub = sinon.stub(ofcWallets.baseCoin.keychains(), 'createUserKeychain').resolves({
id: 'new-keychain-id',
pub: testKeychain.pub,
encryptedPrv: 'stubbed-encrypted-prv',
type: 'independent',
});
// specialOverrideCase pulls the sharing keychain up front, so stub it.
sinon.stub(bitgo, 'getECDHKeychain').resolves({ encryptedXprv: 'stubbed-encrypted-xprv' });
sinon.stub(ofcWallets.baseCoin, 'signMessage').resolves(Buffer.from('signature-bytes'));
sinon.stub(bitgo, 'decrypt').resolves(testKeychain.prv);
sinon.stub(sdk_core_1.Wallets.prototype, 'bulkUpdateWalletShareRequest').resolves({
acceptedWalletShares: [shareId],
rejectedWalletShares: [],
walletShareUpdateErrors: [],
});
sinon.stub(sdk_core_1.Wallets.prototype, 'reshareWalletWithSpenders').resolves();
await ofcWallets.bulkUpdateWalletShare({
shares: [{ walletShareId: shareId, status: 'accept' }],
userLoginPassword: walletPassphrase,
});
createUserKeychainStub.calledOnce.should.equal(true);
// 3rd positional arg is the session
const sessionArg = createUserKeychainStub.firstCall.args[2];
should.exist(sessionArg);
(typeof sessionArg.encrypt).should.equal('function');
(typeof sessionArg.destroy).should.equal('function');
});
});
});
describe('reshareWalletWithSpenders', function () {
(0, mocha_1.afterEach)(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
sinon.restore();
});
// Build a mock wallet with N spender users on the same enterprise.
function stubForReshare(spenderCount, walletId, enterprise) {
const users = Array.from({ length: spenderCount }, (_, i) => ({
user: `spender-${i}`,
permissions: ['view', 'spend'],
}));
const walletObj = {
id: walletId,
coin: 'tsol',
enterprise,
users,
keys: ['userKeyId', 'backupKeyId', 'bitgoKeyId'],
};
// wallets.get(walletId) -> Wallet wrapping walletObj
sinon.stub(sdk_core_1.Wallets.prototype, 'get').resolves(new sdk_core_1.Wallet(bitgo, bitgo.coin('tsol'), walletObj));
nock(bgUrl)
.get(`/api/v1/enterprise/${enterprise}/user`)
.reply(200, {
adminUsers: [],
nonAdminUsers: users.map((u, i) => ({ id: u.user, email: { email: `spender-${i}@example.com` } })),
});
return { walletObj, users };
}
it('decrypts the wallet keychain once and threads it into every shareWallet call', async function () {
const walletId = 'reshare-wallet-1';
const enterprise = 'ent-1';
const userPassword = 'shared-passphrase';
const decryptedKeychain = { prv: 'plaintext-prv', pub: 'wallet-pub' };
const { users } = stubForReshare(3, walletId, enterprise);
// getDecryptedKeychainForSharing is what runs Argon2id on the wallet's encryptedPrv.
// Assert it fires exactly once regardless of spender count.
const decryptStub = sinon.stub(sdk_core_1.Wallet.prototype, 'getDecryptedKeychainForSharing').resolves(decryptedKeychain);
const shareWalletStub = sinon.stub(sdk_core_1.Wallet.prototype, 'shareWallet').resolves({ shared: true });
await wallets.reshareWalletWithSpenders(walletId, userPassword);
decryptStub.callCount.should.equal(1);
decryptStub.firstCall.args[0].should.equal(userPassword);
// shareWallet called once per spender, each with decryptedKeychain threaded in
shareWalletStub.callCount.should.equal(users.length);
for (let i = 0; i < users.length; i++) {
const call = shareWalletStub.getCall(i);
const shareArg = call.args[0];
shareArg.should.have.property('decryptedKeychain').eql(decryptedKeychain);
shareArg.should.have.property('walletPassphrase', userPassword);
}
});
it('runs shareWallet calls sequentially so per-recipient Argon2id is bounded', async function () {
const walletId = 'reshare-wallet-seq';
const enterprise = 'ent-2';
stubForReshare(5, walletId, enterprise);
sinon.stub(sdk_core_1.Wallet.prototype, 'getDecryptedKeychainForSharing').resolves({ prv: 'p', pub: 'q' });
// Track concurrent in-flight shareWallet calls. Sequential -> max concurrent is 1.
let inFlight = 0;
let maxInFlight = 0;
sinon.stub(sdk_core_1.Wallet.prototype, 'shareWallet').callsFake(async () => {
inFlight++;
maxInFlight = Math.max(maxInFlight, inFlight);
await new Promise((r) => setTimeout(r, 5));
inFlight--;
return { shared: true };
});
await wallets.reshareWalletWithSpenders(walletId, 'pw');
maxInFlight.should.equal(1);
});
it('returns early when the wallet has no spender users', async function () {
const walletId = 'reshare-empty';
const enterprise = 'ent-empty';
sinon.stub(sdk_core_1.Wallets.prototype, 'get').resolves(new sdk_core_1.Wallet(bitgo, bitgo.coin('tsol'), {
id: walletId,
coin: 'tsol',
enterprise,
users: [{ user: 'admin-only', permissions: ['admin', 'view', 'spend'] }],
keys: ['userKeyId', 'backupKeyId', 'bitgoKeyId'],
}));
nock(bgUrl)
.get(`/api/v1/enterprise/${enterprise}/user`)
.reply(200, {
adminUsers: [{ id: 'admin-only', email: { email: 'admin@example.com' } }],
nonAdminUsers: [],
});
const decryptStub = sinon.stub(sdk_core_1.Wallet.prototype, 'getDecryptedKeychainForSharing');
const shareWalletStub = sinon.stub(sdk_core_1.Wallet.prototype, 'shareWallet');
await wallets.reshareWalletWithSpenders(walletId, 'pw');
// No decrypt burned, no shares attempted
decryptStub.called.should.equal(false);
shareWalletStub.called.should.equal(false);
});
it('proceeds with per-recipient shareWallet even when the wallet is cold (no decryptedKeychain)', async function () {
const walletId = 'reshare-cold';
const enterprise = 'ent-cold';
stubForReshare(2, walletId, enterprise);
// Simulate cold wallet: getDecryptedKeychainForSharing throws MissingEncryptedKeychainError
// (which we catch inside reshareWalletWithSpenders and fall through).
sinon.stub(sdk_core_1.Wallet.prototype, 'getDecryptedKeychainForSharing').rejects(new sdk_core_1.MissingEncryptedKeychainError());
const shareWalletStub = sinon.stub(sdk_core_1.Wallet.prototype, 'shareWallet').resolves({ shared: true });
await wallets.reshareWalletWithSpenders(walletId, 'pw');
// Still fires per recipient; each call gets undefined decryptedKeychain and shareWallet
// can fall back to its own decrypt path (or a no-op for cold wallets internally).
shareWalletStub.callCount.should.equal(2);
for (let i = 0; i < 2; i++) {
const shareArg = shareWalletStub.getCall(i).args[0];
assert.strictEqual(shareArg.decryptedKeychain, undefined);
}
});
});
});
describe('createBulkKeyShares tests', () => {
const walletData = {
id: '5b34252f1bf349930e34020a00000000',
coin: 'tbtc',
keys: [
'5b3424f91bf349930e34017500000000',
'5b3424f91bf349930e34017600000000',
'5b3424f91bf349930e34017700000000',
],
coinSpecific: {},
multisigType: 'onchain',
type: 'hot',
};
const tsol = bitgo.coin('tsol');
const wallet = new sdk_core_1.Wallet(bitgo, tsol, walletData);
before(function () {
nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
bitgo.initializeTestVars();
});
beforeEach(() => {
sinon.createSandbox();
});
after(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
});
(0, mocha_1.afterEach)(function () {
sinon.restore();
});
it('should throw an error if shareOptions is empty', async () => {
try {
await wallet.createBulkKeyShares([]);
assert.fail('Expected error not thrown');
}
catch (error) {
assert.strictEqual(error.message, 'shareOptions cannot be empty');
}
});
it('should skip shareoption if keychain parameters are missing', async () => {
const params = [
{
user: 'testuser@example.com',
permissions: ['spend'],
keychain: { pub: 'pubkey', encryptedPrv: '', fromPubKey: '', toPubKey: '', path: '' },
},
];
try {
await wallet.createBulkKeyShares(params);
assert.fail('Expected error not thrown');
}
catch (error) {
// Shareoptions with invalid keychains are skipped
assert.strictEqual(error.message, 'shareOptions cannot be empty');
}
});
it('should send the correct data to BitGo API if shareOptions are valid', async () => {
const params = {
shareOptions: [
{
user: 'testuser@example.com',
permissions: ['spend'],
keychain: {
pub: 'pubkey',
encryptedPrv: 'encryptedPrv',
fromPubKey: 'fromPubKey',
toPubKey: 'toPubKey',
path: 'm/0/0',
},
},
],
};
const paramsToSend = [
{
user: 'testuser@example.com',
permissions: ['spend'],
keychain: {
pub: 'pubkey',
encryptedPrv: 'encryptedPrv',
fromPubKey: 'fromPubKey',
toPubKey: 'toPubKey',
path: 'm/0/0',
},
},
];
nock(bgUrl)
.post(`/api/v2/wallet/${walletData.id}/walletshares`, params)
.reply(200, {
shares: [
{
id: 'userId',
coin: walletData.coin,
wallet: walletData.id,
fromUser: 'fromUserId',
toUser: 'toUserId',
permissions: ['view', 'spend'],
keychain: {
pub: 'dummyPub',
encryptedPrv: 'dummyEncryptedPrv',
fromPubKey: 'dummyFromPubKey',
toPubKey: 'dummyToPubKey',
path: 'dummyPath',
},
},
],
});
const result = await wallet.createBulkKeyShares(paramsToSend);
assert.strictEqual(result.shares[0].id, 'userId', 'The share ID should match');
assert.strictEqual(result.shares[0].coin, walletData.coin, 'The coin should match');
assert.strictEqual(result.shares[0].wallet, walletData.id, 'The wallet ID should match');
assert.ok(result.shares[0].keychain);
assert.strictEqual(result.shares[0].keychain.pub, 'dummyPub', 'The keychain pub should match');
assert.strictEqual(result.shares[0].permissions.includes('view'), true, 'The permissions should include "view"');
assert.strictEqual(result.shares[0].permissions.includes('spend'), true, 'The permissions should include "spend"');
});
});
describe('createBulkWalletShare tests', () => {
const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
const walletData = {
id: '5b34252f1bf349930e34020a00000000',
coin: 'tbtc',
keys: [
'5b3424f91bf349930e34017500000000',
'5b3424f91bf349930e34017600000000',
'5b3424f91bf349930e34017700000000',
],
coinSpecific: {},
multisigType: 'onchain',
type: 'hot',
};
const tsol = bitgo.coin('tsol');
const wallet = new sdk_core_1.Wallet(bitgo, tsol, walletData);
before(function () {
nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
bitgo.initializeTestVars();
});
after(function () {
nock.cleanAll();
nock.pendingMocks().length.should.equal(0);
});
(0, mocha_1.afterEach)(function () {
sinon.restore();
});
it('should throw an error if no share options are provided', async () => {
try {
await wallet.createBulkWalletShare({ walletPassphrase: 'Test', keyShareOptions: [] });
assert.fail('Expected error not thrown');
}
catch (error) {
assert.strictEqual(error.message, 'No share options provided');
}
});
it('should throw NeedsUserSignup error if pubkey is missing', async () => {
const userId = 'user@example.com';
const permissions = ['view', 'spend'];
try {
await wallet.createBulkWalletShare({
walletPassphrase: 'Test',
keyShareOptions: [
{
userId: userId,
permissions: permissions,
path: 'm/999999/1/1',
},
],
});
assert.fail('Expected error not thrown');
}
catch (error) {
assert.ok(error instanceof sdk_core_1.NeedUserSignupError);
assert.strictEqual(error.name, 'NeedUserSignupError');
assert.strictEqual(error.message, userId);
}
});
it('should throw error if path is missing', async () => {
const userId = 'user@example.com';
const permissions = ['view', 'spend'];
try {
await wallet.createBulkWalletShare({
walletPassphrase: 'Test',
keyShareOptions: [
{
userId: userId,
permissions: permissions,
pubKey: 'm/999999/1/1',
},
],
});
assert.fail('Expected error not thrown');
}
catch (error) {
assert.strictEqual(error.name, 'Error');
assert.strictEqual(error.message, 'Missing parameter: path');
}
});
it('should throw NeedsUserSignup error if pubkey is empty string', async () => {
const userId = 'user@example.com';
const permissions = ['view', 'spend'];
try {
await wallet.createBulkWalletShare({
walletPassphrase: 'Test',
keyShareOptions: [
{
userId: userId,
pubKey: '',
permissions: permissions,
path: 'm/999999/1/1',
},
],
});
assert.fail('Expected error not thrown');
}
catch (error) {
assert.ok(error instanceof sdk_core_1.NeedUserSignupError);
assert.strictEqual(error.name, 'NeedUserSignupError');
assert.strictEqual(error.message, userId);
}
});
it('should correctly process share options and call createBulkKeyShares', async () => {
const userId = 'user@example.com';
const permissions = ['view', 'spend'];
const path = 'm/999999/1/1';
const walletPassphrase = 'bitgo1234';
const pub = 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk';
nock(bgUrl)
.get(`/api/v2/tbtc/key/${wallet.keyIds()[0]}`)
.reply(200, {
id: wallet.keyIds()[0],
pub,
source: 'user',
encryptedPrv: await bitgo.encrypt({ input: 'xprv1', password: walletPassphrase }),
coinSpecific: {},
});
const params = {
walletPassphrase,
keyShareOptions: [
{
userId: userId,
permissions: permissions,
pubKey: '02705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f532',
path: path,
},
],
};
const prv1 = Math.random().toString();
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: prv1, password: walletPassphrase }),
};
sinon.stub(wallet, 'getEncryptedUserKeychain').resolves({
encryptedPrv: keychainTest.encryptedPrv,
pub,
});
sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
sinon.stub(wallet, 'createBulkKeyShares').resolves({
shares: [
{
id: userId,
coin: walletData.coin,
wallet: walletData.id,
fromUser: userId,
toUser: userId,
permissions: ['view', 'spend'],
keychain: {
pub: 'dummyPub',
encryptedPrv: 'dummyEncryptedPrv',
fromPubKey: 'dummyFromPubKey',
toPubKey: 'dummyToPubKey',
path: 'dummyPath',
},
},
],
});
const result = await wallet.createBulkWalletShare(params);
assert.deepStrictEqual(result, {
shares: [
{
id: userId,
coin: walletData.coin,
wallet: walletData.id,
fromUser: userId,
toUser: userId,
permissions: ['view', 'spend'],
keychain: {
pub: 'dummyPub',
encryptedPrv: 'dummyEncryptedPrv',
fromPubKey: 'dummyFromPubKey',
toPubKey: 'dummyToPubKey',
path: 'dummyPath',
},
},
],
});
});
it('should throw error in processing share options when wallet password is incorrect', async () => {
const userId = 'user@example.com';
const permissions = ['view', 'spend'];
const path = 'm/999999/1/1';
const walletPassphrase = 'bitgo1234';
const pub = 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk';
nock(bgUrl)
.get(`/api/v2/tbtc/key/${wallet.keyIds()[0]}`)
.reply(200, {
id: wallet.keyIds()[0],
pub,
source: 'user',
encryptedPrv: await bitgo.encrypt({ input: 'xprv1', password: walletPassphrase }),
coinSpecific: {},
});
const params = {
walletPassphrase: 'wrong password',
keyShareOptions: [
{
userId: userId,
permissions: permissions,
pubKey: '02705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f532',
path: path,
},
],
};
const prv1 = Math.random().toString();
const keychainTest = {
encryptedPrv: await bitgo.encrypt({ input: prv1, password: walletPassphrase }),
};
sinon.stub(wallet, 'getEncryptedUserKeychain').resolves({
encryptedPrv: keychainTest.encryptedPrv,
pub,
});
try {
await wallet.createBulkWalletShare(params);
assert.fail('Expected error not thrown');
}
catch (error) {
assert.ok(error instanceof sdk_core_1.IncorrectPasswordError);
assert.equal(error.message, 'Password shared is incorrect for this wallet');
}
});
it('should fetch keychain only ONCE when sharing with multiple users', async () => {
const walletPassphrase = 'bitgo1234';
const pub = 'Zo1ggzTUKMY5bYnDvT5mtVeZxzf2FaLTbKkmvGUhUQk';
const prv1 = 'xprv1';
// Create multiple users to share with
const users = [
{
userId: 'user1@example.com',
permissions: ['view', 'spend'],
pubKey: '02705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f532',
path: 'm/999999/1/1',
},
{
userId: 'user2@example.com',
permissions: ['view', 'spend'],
pubKey: '03705a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f533',
path: 'm/999999/1/2',
},
{
userId: 'user3@example.com',
permissions: ['view', 'spend'],
pubKey: '02815a6d33a2459feb537e7abe36aaad8c11532cdbffa3a2e4e58868467d51f534',
path: 'm/999999/1/3',
},
];
const params = {
walletPassphrase,
keyShareOptions: users,
};
const getDecryptedKeychainStub = sinon.stub(wallet, 'getDecryptedKeychainForSharing').resolves({
prv: prv1,
pub,
});
const encryptPrvForUserStub = sinon
.stub(wallet, 'encryptPrvForUser')
.callsFake(async (prv, pubKey, userPubKey, path) => {
return {
pub: pubKey,
encryptedPrv: 'dummyEncryptedPrv',
fromPubKey: 'dummyFromPubKey',
toPubKey: userPubKey,
path: path,
};
});
sinon.stub(wallet, 'createBulkKeyShares').resolves({
shares: users.map((user) => ({
id: user.userId,
coin: walletData.coin,
wallet: walletData.id,
fromUser: 'fromUser',
toUser: user.userId,
permissions: user.permissions,
keychain: {
pub: 'dummyPub',
encryptedPrv: 'dummyEncryptedPrv',
fromPubKey: 'dummyFromPubKey',
toPubKey: user.pubKey,
path: user.path,
},
})),
});
await wallet.createBulkWalletShare(params);
// Verify keychain is fetched only ONCE, not once per user
assert.strictEqual(getDecryptedKeychainStub.callCount, 1, 'getDecryptedKeychainForSharing should be called exactly once, not once per user');
// Verify encryption happens for EACH user (once per user)
assert.strictEqual(encryptPrvForUserStub.callCount, users.length, `encryptPrvForUser should be called once per user (${users.length} times)`);
// Verify each call had the correct user's pubKey and path
users.forEach((user, index) => {
const call = encryptPrvForUserStub.getCall(index);
assert.strictEqual(call.args[0], prv1, 'Should use the same decrypted private key for all users');
assert.strictEqual(call.args[1], pub, 'Should use the same public key for all users');
assert.strictEqual(call.args[2], user.pubKey, `Should use user${index + 1}'s public key`);
assert.strictEqual(call.args[3], user.path, `Should use user${index + 1}'s path`);
});
});
});
describe('downloadKeycard', () => {
const localBitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
const walletData = {
id: '5b34252f1bf349930e34020a00000002',
coin: 'tbtc',
keys: [
'5b3424f91bf349930e34017500000000',
'5b3424f91bf349930e34017600000000',
'5b3424f91bf349930e34017700000000',
],
coinSpecific: {},
multisigType: 'onchain',
type: 'hot',
};
const tbtc = localBitgo.coin('tbtc');
const wallet = new sdk_core_1.Wallet(localBitgo, tbtc, walletData);
it('should throw when called in Node.js (no browser window)', async () => {
// In Node.js, accessing `window` throws ReferenceError; the method rejects.
await wallet.downloadKeycard().should.be.rejected();
});
it('downloadKeycard (sync) should throw when called in Node.js (no browser window)', () => {
should.throws(() => wallet.downloadKeycard());
});
});
describe('encryptPrvForUser', () => {
const localBitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
const walletData = {
id: '5b34252f1bf349930e34020a00000001',
coin: 'tbtc',
keys: [
'5b3424f91bf349930e34017500000000',
'5b3424f91bf349930e34017600000000',
'5b3424f91bf349930e34017700000000',
],
coinSpecific: {},
multisigType: 'onchain',
type: 'hot',
};
const tbtc = localBitgo.coin('tbtc');
const wallet = new sdk_core_1.Wallet(localBitgo, tbtc, walletData);
before(function () {
nock('https://bitgo.fakeurl').persist().get('/api/v1/client/constants').reply(200, { ttl: 3600, constants: {} });
localBitgo.initializeTestVars();
});
(0, mocha_1.afterEach)(function () {
sinon.restore();
});
it('should encrypt prv for user and return the correct output shape', async () => {
const decryptedPrv = 'xprv9s21ZrQH143K2fJ91S4BRsupcYrE6mmY96fcX5HkhoTrrwmwjd16Cn87cWinJjByrfpojjx7ezsJLx7TAKLT8m8hM5Kax9YcoxnBeJZ3t2k';
const pub = 'xpub661MyMwAqRbcF9Nc7TbBo1rZAagiWEVPWKbDKThNG8zqjk76HAKLkaSbTn6dK2dQPfuD7xjicxCZVWvj67fP5nQ9W7QURmoMVAX8m6jZsGp';
// A valid 33-byte compressed EC point on secp256k1
const userPubkey = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798';
const path = 'm/999999/0/1';
sinon.stub(localBitgo, 'encrypt').resolves('encryptedPrvForUser');
const result = await wallet.encryptPrvForUser(decryptedPrv, pub, userPubkey, path);
result.should.have.property('pub', pub);
result.should.have.property('encryptedPrv', 'encryptedPrvForUser');
result.should.have.property('fromPubKey').which.is.a.String();
result.should.have.property('toPubKey', userPubkey);
result.should.have.property('path', path);
});
});
describe('List Wallets:', function () {
it('should list wallets with skipReceiveAddress = true', async function () {
const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
const basecoin = bitgo.coin('tbtc');
const wallets = basecoin.wallets();
const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
nock(bgUrl)
.get('/api/v2/tbtc/wallet')
.query({ skipReceiveAddress: true })
.reply(200, {
wallets: [
{ id: 'wallet1', label: 'Test Wallet 1' },
{ id: 'wallet2', label: 'Test Wallet 2' },
],
});
const result = await wallets.list({ skipReceiveAddress: true });
result.wallets.should.have.length(2);
should.not.exist(result.wallets[0].receiveAddress());
should.not.exist(result.wallets[1].receiveAddress());
});
it('should list wallets without skipReceiveAddress', async function () {
const bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'mock' });
const basecoin = bitgo.coin('tbtc');
const wallets = basecoin.wallets();
const bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
nock(bgUrl)
.get('/api/v2/tbtc/wallet')
.query({})
.reply(200, {
wallets: [
{ id: 'wallet1', label: 'Test Wallet 1', receiveAddress: { address: 'address1' } },
{ id: 'wallet2', label: 'Test Wallet 2', receiveAddress: { address: 'address2' } },
],
});
const result = await wallets.list();
result.wallets.should.have.length(2);
should.exist(result.wallets[0].receiveAddress());
should.exist(result.wallets[1].receiveAddress());
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdjIvdW5pdC93YWxsZXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsRUFBRTtBQUNGLG9CQUFvQjtBQUNwQixFQUFFO0FBQ0YsaUNBQWlDO0FBQ2pDLDZCQUE4QjtBQUM5QiwrQkFBK0I7QUFDL0IsaUNBQWtDO0FBQ2xDLDRCQUE0QjtBQUM1QiwyQ0FBMkM7QUFDM0MsOENBQTRDO0FBQzVDLDhDQXVCeUI7QUFDekIsc0NBQXFDO0FBQ3JDLGlDQUFrQztBQUVsQywrQ0FBK0M7QUFFL0MsUUFBUSxDQUFDLGFBQWEsRUFBRTtJQUN0QixNQUFNLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxXQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUN6RCxJQUFJLE9BQU8sQ0FBQztJQUNaLElBQUksVUFBVSxDQUFDO0lBQ2YsSUFBSSxLQUFLLENBQUM7SUFFVixNQUFNLENBQUM7UUFDTCxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqSCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUUzQixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDN0IsVUFBVSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDekMsS0FBSyxHQUFHLGlCQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFD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QztZQUNwQyxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDbkMsTUFBTSxLQUFLLEdBQUcsaUJBQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDO1lBRXRELElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ1IsR0FBRyxDQUFDLHFCQUFxQixDQUFDO2lCQUMxQixLQUFLLENBQUMsRUFBRSxDQUFDO2lCQUNULEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFO29CQUNQLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsRUFBRTtvQkFDbEYsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxFQUFFO2lCQUNuRjthQUNGLENBQUMsQ0FBQztZQUVMLE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3BDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7WUFDakQsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7UUFDbkQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy9cbi8vIFRlc3RzIGZvciBXYWxsZXRzXG4vL1xuaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgbm9jayA9IHJlcXVpcmUoJ25vY2snKTtcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCBzaG91bGQgPSByZXF1aXJlKCdzaG91bGQnKTtcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCAqIGFzIHV0eG9MaWIgZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCB7IFRlc3RCaXRHbyB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQge1xuICBjb21tb24sXG4gIFRzc1V0aWxzLFxuICBXYWxsZXRzLFxuICBFQ0RTQVV0aWxzLFxuICBFRERTQVV0aWxzLFxuICBLZXljaGFpbnNUcmlwbGV0LFxuICBHZW5lcmF0ZVdhbGxldE9wdGlvbnMsXG4gIFdhbGxldCxcbiAgaXNXYWxsZXRXaXRoS2V5Y2hhaW5zLFxuICBPcHRpb25hbEtleWNoYWluRW5jcnlwdGVkS2V5LFxuICBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5LFxuICBtYWtlUmFuZG9tS2V5LFxuICBnZXRTaGFyZWRTZWNyZXQsXG4gIEJ1bGtVcGRhdGVXYWxsZXRTaGFyZU9wdGlvbnNSZXF1ZXN0LFxuICBCdWxrV2FsbGV0U2hhcmVPcHRpb25zLFxuICBBY2NlcHRTaGFyZU9wdGlvbnNSZXF1ZXN0LFxuICBLZXljaGFpbldpdGhFbmNyeXB0ZWRQcnYsXG4gIFdhbGxldFdpdGhLZXljaGFpbnMsXG4gIG11bHRpc2lnVHlwZXMsXG4gIEluY29ycmVjdFBhc3N3b3JkRXJyb3IsXG4gIE1pc3NpbmdFbmNyeXB0ZWRLZXljaGFpbkVycm9yLFxuICBOZWVkVXNlclNpZ251cEVycm9yLFxufSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgQml0R28gfSBmcm9tICcuLi8uLi8uLi9zcmMnO1xuaW1wb3J0IHsgYWZ0ZXJFYWNoIH0gZnJvbSAnbW9jaGEnO1xuaW1wb3J0IHsgVHNzU2V0dGluZ3MgfSBmcm9tICdAYml0Z28vcHVibGljLXR5cGVzJztcbmltcG9ydCAqIGFzIG1vZHVsZUJpdGdvIGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5cbmRlc2NyaWJlKCdWMiBXYWxsZXRzOicsIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gIGxldCB3YWxsZXRzO1xuICBsZXQgb2ZjV2FsbGV0cztcbiAgbGV0IGJnVXJsO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucGVyc2lzdCgpLmdldCgnL2FwaS92MS9jbGllbnQvY29uc3RhbnRzJykucmVwbHkoMjAwLCB7IHR0bDogMzYwMCwgY29uc3RhbnRzOiB7fSB9KTtcblxuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuXG4gICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0YnRjJyk7XG4gICAgd2FsbGV0cyA9IGJhc2Vjb2luLndhbGxldHMoKTtcbiAgICBvZmNXYWxsZXRzID0gYml0Z28uY29pbignb2ZjJykud2FsbGV0cygpO1xuICAgIGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICB9KTtcblxuICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIG5vY2sucGVuZGluZ01vY2tzKCkubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FkZCBXYWxsZXQ6JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCd0aHJvd3Mgb24gaW52YWxpZCBhcmd1bWVudHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBpc0N1c3RvZGlhbCBmbGFnIGlzIG5vdCBhIGJvb2xlYW5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmFkZCh7IGxhYmVsOiAnbGFiZWwnLCBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsIGtleXM6IFtdLCBtOiAyLCBuOiAzLCBpc0N1c3RvZGlhbDogMSB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBhcmd1bWVudCBmb3IgaXNDdXN0b2RpYWwgLSBib29sZWFuIGV4cGVjdGVkJyk7XG5cbiAgICAgIC8vIHR5cGUgaXMgbm90IGEgc3RyaW5nXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCBrZXlzOiBbXSwgbTogMiwgbjogMywgdHlwZTogMSB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnRXhwZWN0aW5nIHBhcmFtZXRlciBzdHJpbmc6IHR5cGUgYnV0IGZvdW5kIG51bWJlcicpO1xuXG4gICAgICAvLyBBZGRyZXNzIGlzIGFuIGludmFsaWQgYWRkcmVzc1xuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywga2V5czogW10sIG06IDIsIG46IDMsIGFkZHJlc3M6ICckJyB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBhcmd1bWVudCBmb3IgYWRkcmVzcyAtIHZhbGlkIGFkZHJlc3Mgc3RyaW5nIGV4cGVjdGVkJyk7XG5cbiAgICAgIC8vIGdhc1ByaWNlIGlzIGEgbnVtYmVyXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCBrZXlzOiBbXSwgbTogMiwgbjogMywgZ2FzUHJpY2U6ICcxNycgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgYXJndW1lbnQgZm9yIGdhc1ByaWNlIC0gbnVtYmVyIGV4cGVjdGVkJyk7XG5cbiAgICAgIC8vIHdhbGxldFZlcnNpb24gaXMgYSBudW1iZXJcbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmFkZCh7IGxhYmVsOiAnbGFiZWwnLCBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsIGtleXM6IFtdLCBtOiAyLCBuOiAzLCB3YWxsZXRWZXJzaW9uOiAnMScgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgYXJndW1lbnQgZm9yIHdhbGxldFZlcnNpb24gLSBudW1iZXIgZXhwZWN0ZWQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGVzIGEgcGFpcmVkIGN1c3RvZGlhbCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkuaXNDdXN0b2RpYWwuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdrZXlzJyk7XG4gICAgICAgICAgYm9keS5tLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgICAgICBib2R5Lm4uc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG4gICAgICBhd2FpdCB3YWxsZXRzLmFkZCh7IGxhYmVsOiAnbGFiZWwnLCBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsIGtleXM6IFtdLCBtOiAyLCBuOiAzLCBpc0N1c3RvZGlhbDogdHJ1ZSB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGVzIGFuIGVvcyB3YWxsZXQgd2l0aCBjdXN0b20gYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVvc0JpdEdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgICAgZW9zQml0R28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgICBjb25zdCBlb3NXYWxsZXRzID0gZW9zQml0R28uY29pbigndGVvcycpLndhbGxldHMoKTtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSAndGVzdGVvc2FkZHJlJztcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3Rlb3Mvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgna2V5cycpO1xuICAgICAgICAgIGJvZHkubS5zaG91bGQuZXF1YWwoMik7XG4gICAgICAgICAgYm9keS5uLnNob3VsZC5lcXVhbCgzKTtcbiAgICAgICAgICBib2R5LmFkZHJlc3Muc2hvdWxkLmVxdWFsKGFkZHJlc3MpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG4gICAgICBhd2FpdCBlb3NXYWxsZXRzLmFkZCh7IGxhYmVsOiAnbGFiZWwnLCBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsIGtleXM6IFtdLCBtOiAyLCBuOiAzLCBhZGRyZXNzIH0gYXMgYW55KTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGVzIGEgc2luZ2xlIGN1c3RvZGlhbCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkudHlwZS5zaG91bGQuZXF1YWwoJ2N1c3RvZGlhbCcpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdrZXlzJyk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ20nKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnbicpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG4gICAgICBhd2FpdCB3YWxsZXRzLmFkZCh7IGxhYmVsOiAnbGFiZWwnLCBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsIHR5cGU6ICdjdXN0b2RpYWwnIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NyZWF0ZXMgYSB3YWxsZXQgd2l0aCBjdXN0b20gZ2FzUHJpY2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBldGhCaXRHbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICAgIGV0aEJpdEdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgICAgY29uc3QgZXRoV2FsbGV0cyA9IGV0aEJpdEdvLmNvaW4oJ3RldGgnKS53YWxsZXRzKCk7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90ZXRoL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkudHlwZS5zaG91bGQuZXF1YWwoJ2N1c3RvZGlhbCcpO1xuICAgICAgICAgIGJvZHkuZ2FzUHJpY2Uuc2hvdWxkLmVxdWFsKDIwMDAwMDAwMDAwKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgna2V5cycpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdtJyk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ24nKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuICAgICAgYXdhaXQgZXRoV2FsbGV0cy5hZGQoe1xuICAgICAgICBsYWJlbDogJ2xhYmVsJyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICAgICAgZ2FzUHJpY2U6IDIwMDAwMDAwMDAwLFxuICAgICAgfSBhcyBhbnkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NyZWF0ZXMgYSBuZXcgd2FsbGV0IHdpdGggd2FsbGV0VmVyc2lvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV0aEJpdEdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgICAgZXRoQml0R28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgICBjb25zdCBldGhXYWxsZXRzID0gZXRoQml0R28uY29pbigndGV0aCcpLndhbGxldHMoKTtcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RldGgvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS50eXBlLnNob3VsZC5lcXVhbCgnY3VzdG9kaWFsJyk7XG4gICAgICAgICAgYm9keS53YWxsZXRWZXJzaW9uLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgna2V5cycpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdtJyk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ24nKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuICAgICAgYXdhaXQgZXRoV2FsbGV0cy5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCB0eXBlOiAnY3VzdG9kaWFsJywgd2FsbGV0VmVyc2lvbjogMSB9IGFzIGFueSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlcyBhIG5ldyBob3Qgd2FsbGV0IHdpdGggdXNlcktleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS50eXBlLnNob3VsZC5lcXVhbCgnaG90Jyk7XG4gICAgICAgICAgYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgna2V5cycpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ20nKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCduJyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IHdhbGxldHMuYWRkKHtcbiAgICAgICAgbGFiZWw6ICdsYWJlbCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgdHlwZTogJ2hvdCcsXG4gICAgICAgIGtleXM6IFtdLFxuICAgICAgICBtOiAyLFxuICAgICAgICBuOiAzLFxuICAgICAgICB1c2VyS2V5OiAndGVzdDEyMycsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIHdhbGxldDonLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIHBhcmFtZXRlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBsZXQgcGFyYW1zID0ge307XG4gICAgICBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnTWlzc2luZyBwYXJhbWV0ZXI6IGxhYmVsJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBiYWNrdXBYcHViOiAnYmFja3VwJyxcbiAgICAgICAgYmFja3VwWHB1YlByb3ZpZGVyOiAncHJvdmlkZXInLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnQ2Fubm90IHByb3ZpZGUgbW9yZSB0aGFuIG9uZSBiYWNrdXBYcHViIG9yIGJhY2t1cFhwdWJQcm92aWRlciBmbGFnJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAxMjMsXG4gICAgICB9O1xuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3Bhc3Njb2RlRW5jcnlwdGlvbkNvZGUgbXVzdCBiZSBhIHN0cmluZycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZW50ZXJwcmlzZTogMTIzNCxcbiAgICAgIH07XG4gICAgICBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBlbnRlcnByaXNlIGFyZ3VtZW50LCBleHBlY3Rpbmcgc3RyaW5nJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBkaXNhYmxlVHJhbnNhY3Rpb25Ob3RpZmljYXRpb25zOiAnc3RyaW5nJyxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgZGlzYWJsZVRyYW5zYWN0aW9uTm90aWZpY2F0aW9ucyBhcmd1bWVudCwgZXhwZWN0aW5nIGJvb2xlYW4nKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGdhc1ByaWNlOiAnc3RyaW5nJyxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgZ2FzIHByaWNlIGFyZ3VtZW50LCBleHBlY3RpbmcgbnVtYmVyIG9yIG51bWJlciBhcyBzdHJpbmcnKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGdhc1ByaWNlOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBnYXMgcHJpY2UgYXJndW1lbnQsIGV4cGVjdGluZyBudW1iZXIgb3IgbnVtYmVyIGFzIHN0cmluZycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZ2FzUHJpY2U6IDEyMyxcbiAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgIG1heEZlZVBlckdhczogMTIzNCxcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogMTIzLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2NhbiBub3QgdXNlIGJvdGggZWlwMTU1OSBhbmQgZ2FzUHJpY2UgdmFsdWVzJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBlaXAxNTU5OiB7XG4gICAgICAgICAgbWF4RmVlUGVyR2FzOiAncTEyMzQnLFxuICAgICAgICAgIG1heFByaW9yaXR5RmVlUGVyR2FzOiAnMTIzJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgbWF4IGZlZSBhcmd1bWVudCwgZXhwZWN0aW5nIG51bWJlciBvciBudW1iZXIgYXMgc3RyaW5nJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBlaXAxNTU5OiB7XG4gICAgICAgICAgbWF4RmVlUGVyR2FzOiAxMjM0LFxuICAgICAgICAgIG1heFByaW9yaXR5RmVlUGVyR2FzOiAnMTIzYScsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIHByaW9yaXR5IGZlZSBhcmd1bWVudCwgZXhwZWN0aW5nIG51bWJlciBvciBudW1iZXIgYXMgc3RyaW5nJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBkaXNhYmxlS1JTRW1haWw6ICdzdHJpbmcnLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBkaXNhYmxlS1JTRW1haWwgYXJndW1lbnQsIGV4cGVjdGluZyBib29sZWFuJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBrcnNTcGVjaWZpYzoge1xuICAgICAgICAgIG1hbGljaW91czoge1xuICAgICAgICAgICAgamF2YXNjcmlwdDoge1xuICAgICAgICAgICAgICBjb2RlOiAnYmFkLmpzJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ2tyc1NwZWNpZmljIG9iamVjdCBjb250YWlucyBpbGxlZ2FsIHZhbHVlcy4gdmFsdWVzIG11c3QgYmUgc3RyaW5ncywgYm9vbGVhbnMsIG9yIG51bWJlcnMnXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBkaXNhYmxlIGtycyBlbWFpbHMgd2hlbiBjcmVhdGluZyBiYWNrdXAga2V5Y2hhaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ215X3dhbGxldCcsXG4gICAgICAgIGRpc2FibGVLUlNFbWFpbDogdHJ1ZSxcbiAgICAgICAgYmFja3VwWHB1YlByb3ZpZGVyOiAndGVzdCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0ZXN0MTIzJyxcbiAgICAgICAgdXNlcktleTogJ3hwdWIxMjMnLFxuICAgICAgfTtcblxuICAgICAgLy8gYml0Z28ga2V5XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIHVzZXIga2V5XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8uY29uZm9ybXMoeyBwdWI6IChwKSA9PiBwLnN0YXJ0c1dpdGgoJ3hwdWInKSB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIGJhY2t1cCBrZXlcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KFxuICAgICAgICAgICcvYXBpL3YyL3RidGMva2V5JyxcbiAgICAgICAgICBfLm1hdGNoZXMoe1xuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgIHByb3ZpZGVyOiBwYXJhbXMuYmFja3VwWHB1YlByb3ZpZGVyLFxuICAgICAgICAgICAgZGlzYWJsZUtSU0VtYWlsOiB0cnVlLFxuICAgICAgICAgIH0pXG4gICAgICAgIClcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIHdhbGxldFxuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBwYXNzIHRocm91Z2ggdGhlIGtyc1NwZWNpZmljIHBhcmFtIHdoZW4gY3JlYXRpbmcgYmFja3VwIGtleWNoYWlucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdteV93YWxsZXQnLFxuICAgICAgICBiYWNrdXBYcHViUHJvdmlkZXI6ICd0ZXN0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3Rlc3QxMjMnLFxuICAgICAgICB1c2VyS2V5OiAneHB1YjEyMycsXG4gICAgICAgIGtyc1NwZWNpZmljOiB7IGNvdmVyYWdlOiAnaW5zdXJhbmNlJywgZXhwZW5zaXZlOiB0cnVlLCBob3dFeHBlbnNpdmU6IDI1IH0sXG4gICAgICB9O1xuXG4gICAgICAvLyBiaXRnbyBrZXlcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgc291cmNlOiAnYml0Z28nIH0pKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgLy8gdXNlciBrZXlcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5jb25mb3Jtcyh7IHB1YjogKHApID0+IHAuc3RhcnRzV2l0aCgneHB1YicpIH0pKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgLy8gYmFja3VwIGtleVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoXG4gICAgICAgICAgJy9hcGkvdjIvdGJ0Yy9rZXknLFxuICAgICAgICAgIF8ubWF0Y2hlcyh7XG4gICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgcHJvdmlkZXI6IHBhcmFtcy5iYWNrdXBYcHViUHJvdmlkZXIsXG4gICAgICAgICAgICBrcnNTcGVjaWZpYzogeyBjb3ZlcmFnZTogJ2luc3VyYW5jZScsIGV4cGVuc2l2ZTogdHJ1ZSwgaG93RXhwZW5zaXZlOiAyNSB9LFxuICAgICAgICAgIH0pXG4gICAgICAgIClcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIHdhbGxldFxuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNlbmQgdGhlIGNvbGQgZGVyaXZhdGlvbiBzZWVkIGZvciBhIHVzZXIga2V5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ215LWNvbGQtd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3Rlc3QxMjMnLFxuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjRnRYZ1M1c1lKQUJxcUc5WUxtQzRRMVJkYXA5Z1NFOE5xdHd5YkdoZVBZMmdaMjlFU0ZqcUpvQ3UxUnVwamU4WXRHcXNlZkQyNjVUTWc3dXNVREZkcDZXMUVHTWNldDgnLFxuICAgICAgICBjb2xkRGVyaXZhdGlvblNlZWQ6ICcxMjMnLFxuICAgICAgfTtcblxuICAgICAgLy8gYml0Z28ga2V5XG4gICAgICBjb25zdCBiaXRnb0tleU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIHVzZXIga2V5XG4gICAgICBjb25zdCB1c2VyS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KFxuICAgICAgICAgICcvYXBpL3YyL3RidGMva2V5JyxcbiAgICAgICAgICBfLm1hdGNoZXMoe1xuICAgICAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogcGFyYW1zLmNvbGREZXJpdmF0aW9uU2VlZCxcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyBiYWNrdXAga2V5XG4gICAgICBjb25zdCBiYWNrdXBLZXlOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiYWNrdXAnIH0pKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgLy8gd2FsbGV0XG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jayhiZ1VybCkucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG4gICAgICBmb3IgKGNvbnN0IHNjb3BlIG9mIFtiaXRnb0tleU5vY2ssIHVzZXJLZXlOb2NrLCBiYWNrdXBLZXlOb2NrLCB3YWxsZXROb2NrXSkge1xuICAgICAgICBzY29wZS5kb25lKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGN1c3RvZGlhbCBvbmNoYWluIHdhbGxldCB3aXRob3V0IHBhc3NpbmcgbSwgbiwga2V5cywga2V5U2lnbmF0dXJlcycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ3Rlc3Qgd2FsbGV0JyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ215ZW50ZXJwcmlzZScsXG4gICAgICAgIHR5cGU6ICdjdXN0b2RpYWwnLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS50eXBlLnNob3VsZC5lcXVhbCgnY3VzdG9kaWFsJyk7XG4gICAgICAgICAgc2hvdWxkLm5vdC5leGlzdChib2R5Lm0pO1xuICAgICAgICAgIHNob3VsZC5ub3QuZXhpc3QoYm9keS5uKTtcbiAgICAgICAgICBzaG91bGQubm90LmV4aXN0KGJvZHkua2V5cyk7XG4gICAgICAgICAgc2hvdWxkLm5vdC5leGlzdChib2R5LmtleVNpZ25hdHVyZXMpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7IGlkOiAnMTIzJywgYmFzZUNvaW46IGJpdGdvLmNvaW4oJ3RidGMnKSwga2V5czogWycxMjMnLCAnNDU2JywgJzc4OSddIH0pO1xuXG4gICAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjIvdGJ0Yy9rZXkvMTIzJykucmVwbHkoMjAwLCB7IHB1YjogJ2JpdGdvUHViJywgaWQ6ICc3ODknIH0pO1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KCcvYXBpL3YyL3RidGMva2V5LzQ1NicsIF8ubWF0Y2hlcyh7fSkpLnJlcGx5KDIwMCk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjIvdGJ0Yy9rZXkvNzg5JykucmVwbHkoMjAwLCB7IHB1YjogJ2JhY2t1cFB1YicsIGlkOiAnNzg5JyB9KTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UgPT09IHVuZGVmaW5lZCk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgaG90IG9uY2hhaW4gd2FsbGV0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAndGVzdCB3YWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAnbXVsdGlzaWcgcGFzc3dvcmQnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS50eXBlLnNob3VsZC5lcXVhbCgnaG90Jyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBwdWI6ICdiaXRnb1B1YicgfSk7XG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHt9KSkucmVwbHkoMjAwKTtcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgc291cmNlOiAnYmFja3VwJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBwdWI6ICdiYWNrdXBQdWInIH0pO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcblxuICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBob3Qgb25jaGFpbiB3YWxsZXQgd2l0aG91dCBwYXNzaW5nIG11bHRpc2lnIHR5cGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXM6IEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHtcbiAgICAgICAgbGFiZWw6ICd0ZXN0IHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICdtdWx0aXNpZyBwYXNzd29yZCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnR5cGUuc2hvdWxkLmVxdWFsKCdob3QnKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgc291cmNlOiAnYml0Z28nIH0pKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHB1YjogJ2JpdGdvUHViJyB9KTtcbiAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoe30pKS5yZXBseSgyMDApO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiYWNrdXAnIH0pKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHB1YjogJ2JhY2t1cFB1YicgfSk7XG5cbiAgICAgIGNvbnN0IGdlbmVyYXRlV2FsbGV0U3B5ID0gc2FuZGJveC5zcHkod2FsbGV0cywgJ2dlbmVyYXRlV2FsbGV0Jyk7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRPbmNlKGdlbmVyYXRlV2FsbGV0U3B5KTtcbiAgICAgIGFzc2VydC5lcXVhbChnZW5lcmF0ZVdhbGxldFNweS5maXJzdENhbGw/LmFyZ3NbMF0/Lm11bHRpc2lnVHlwZSwgbXVsdGlzaWdUeXBlcy5vbmNoYWluKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UsIHBhc3N3b3JkOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSB9KSxcbiAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIEdvIEFjY291bnQgd2FsbGV0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAnR28gQWNjb3VudCBXYWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAnZ29fYWNjb3VudF9wYXNzd29yZCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlLWlkJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICAgIHR5cGU6ICd0cmFkaW5nJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGtleWNoYWluSWQgPSAndXNlcl9rZXljaGFpbl9pZCc7XG5cbiAgICAgIC8vIE1vY2sga2V5Y2hhaW4gY3JlYXRpb24gYW5kIHVwbG9hZFxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvb2ZjL2tleScsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZW5jcnlwdGVkUHJ2Jyk7XG4gICAgICAgICAgYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyk7XG4gICAgICAgICAgYm9keS5rZXlUeXBlLnNob3VsZC5lcXVhbCgnaW5kZXBlbmRlbnQnKTtcbiAgICAgICAgICBib2R5LnNvdXJjZS5zaG91bGQuZXF1YWwoJ3VzZXInKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBpZDoga2V5Y2hhaW5JZCwgcHViOiAndXNlclB1YicsIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFByaXZhdGVLZXknIH0pO1xuXG4gICAgICAvLyBNb2NrIHdhbGxldCBjcmVhdGlvblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL29mYy93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnR5cGUuc2hvdWxkLmVxdWFsKCd0cmFkaW5nJyk7XG4gICAgICAgICAgYm9keS5tLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgICBib2R5Lm4uc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICAgIGJvZHkua2V5cy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICAgICAgYm9keS5rZXlzWzBdLnNob3VsZC5lcXVhbChrZXljaGFpbklkKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBpZDogJ3dhbGxldDEyMycsIGtleXM6IFtrZXljaGFpbklkXSB9KTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBvZmNXYWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgICBhc3NlcnQub2soJ3VzZXJLZXljaGFpbicgaW4gcmVzcG9uc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnR2VuZXJhdGUgVFNTIHdhbGxldDonLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgdHNvbCA9IGJpdGdvLmNvaW4oJ3Rzb2wnKTtcbiAgICBjb25zdCBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyL3Rzcy9zZXR0aW5nc2ApXG4gICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAudGltZXMoMilcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGNvaW5TZXR0aW5nczoge1xuICAgICAgICAgICAgZXRoOiB7XG4gICAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJzYzoge1xuICAgICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwb2x5Z29uOiB7XG4gICAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICBzYW5kYm94LnZlcmlmeUFuZFJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbmV3IFRTUyB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBzYW5kYm94LnN0dWIoVHNzVXRpbHMucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJykucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucG9zdCgnL2FwaS92Mi90c29sL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGFueSxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UsIHBhc3N3b3JkOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSB9KSxcbiAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBUU1Mgd2FsbGV0IHdpdGhvdXQgcGFzc2luZyBtdWx0aXNpZyB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc3R1YmJlZEtleWNoYWluc1RyaXBsZXQ6IEtleWNoYWluc1RyaXBsZXQgPSB7XG4gICAgICAgIHVzZXJLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgfSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgIHB1YjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgfSxcbiAgICAgICAgYml0Z29LZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgc2FuZGJveC5zdHViKFRzc1V0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3Rzb2wvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS5tdWx0aXNpZ1R5cGUuc2hvdWxkLmVxdWFsKG11bHRpc2lnVHlwZXMudHNzKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdHNvbCk7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBnZW5lcmF0ZVdhbGxldFNweSA9IHNhbmRib3guc3B5KHdhbGxldHMsICdnZW5lcmF0ZVdhbGxldCcpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShnZW5lcmF0ZVdhbGxldFNweSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZ2VuZXJhdGVXYWxsZXRTcHkuZmlyc3RDYWxsPy5hcmdzWzBdPy5tdWx0aXNpZ1R5cGUsIG11bHRpc2lnVHlwZXMudHNzKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UsIHBhc3N3b3JkOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSB9KSxcbiAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBUU1Mgd2FsbGV0IHdpdGhvdXQgcHJvdmlkaW5nIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBzYW5kYm94LnN0dWIoVHNzVXRpbHMucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJykucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucG9zdCgnL2FwaS92Mi90c29sL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAndHNzIHBhc3N3b3JkJyxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgfSk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSA9PT0gdW5kZWZpbmVkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBjcmVhdGUgVFNTIHdhbGxldCB3aXRoIGludmFsaWQgaW5wdXRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGJ0YyA9IGJpdGdvLmNvaW4oJ3RidGMnKTtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdteS1jb2xkLXdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0ZXN0MTIzJyxcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0Z0WGdTNXNZSkFCcXFHOVlMbUM0UTFSZGFwOWdTRThOcXR3eWJHaGVQWTJnWjI5RVNGanFKb0N1MVJ1cGplOFl0R3FzZWZEMjY1VE1nN3VzVURGZHA2VzFFR01jZXQ4JyxcbiAgICAgICAgY29sZERlcml2YXRpb25TZWVkOiAnMTIzJyxcbiAgICAgIH07XG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRidGMpO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogcGFyYW1zLmNvbGREZXJpdmF0aW9uU2VlZCB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JhY2t1cCcgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcpLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIGNyZWF0ZSBhIG5vbiB0c3Mgd2FsbGV0IGZvciBjb2luIHRoYXQgZG9lc24ndCBzdXBwb3J0IHRzcyBldmVuIHRob3VnaCBtdWx0aXNpZ1R5cGUgaXMgc2V0IHRvIHRzc1xuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldCh7IC4uLnBhcmFtcywgbXVsdGlzaWdUeXBlOiAndHNzJyB9KTtcblxuICAgICAgY29uc3QgdHNvbFdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdHNvbCk7XG5cbiAgICAgIGF3YWl0IHRzb2xXYWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgICAgbGFiZWw6ICd0c3MgY29sZCB3YWxsZXQnLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzcGhyYXNlJyxcbiAgICAgICAgICB1c2VyS2V5OiAndXNlciBrZXknLFxuICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdlbnRlcnByaXNlIGlzIHJlcXVpcmVkIGZvciBUU1Mgd2FsbGV0Jyk7XG5cbiAgICAgIGF3YWl0IHRzb2xXYWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgICAgbGFiZWw6ICd0c3MgY29sZCB3YWxsZXQnLFxuICAgICAgICAgIHVzZXJLZXk6ICd1c2VyIGtleScsXG4gICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZUlkJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2Nhbm5vdCBnZW5lcmF0ZSBUU1Mga2V5cyB3aXRob3V0IHBhc3NwaHJhc2UnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbmV3IFRTUyBjdXN0b2RpYWwgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5cyA9IFsnMScsICcyJywgJzMnXTtcblxuICAgICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgdHlwZTogJ2N1c3RvZGlhbCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC93YWxsZXQvYWRkJylcbiAgICAgICAgLnRpbWVzKDEpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgLi4ud2FsbGV0UGFyYW1zLCBrZXlzIH0pO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHdhbGxldFBhcmFtcyk7XG4gICAgICBpZiAoIWlzV2FsbGV0V2l0aEtleWNoYWlucyhyZXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignd2FsbGV0IG1pc3NpbmcgcmVxdWlyZWQga2V5Y2hhaW5zJyk7XG4gICAgICB9XG4gICAgICByZXMud2FsbGV0LmxhYmVsKCkuc2hvdWxkLmVxdWFsKHdhbGxldFBhcmFtcy5sYWJlbCk7XG4gICAgICBzaG91bGQuZXF1YWwocmVzLndhbGxldC50eXBlKCksIHdhbGxldFBhcmFtcy50eXBlKTtcbiAgICAgIHJlcy53YWxsZXQudG9KU09OKCkuZW50ZXJwcmlzZS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLmVudGVycHJpc2UpO1xuICAgICAgcmVzLndhbGxldC5tdWx0aXNpZ1R5cGUoKS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLm11bHRpc2lnVHlwZSk7XG4gICAgICByZXMudXNlcktleWNoYWluLmlkLnNob3VsZC5lcXVhbChrZXlzWzBdKTtcbiAgICAgIHJlcy5iYWNrdXBLZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1sxXSk7XG4gICAgICByZXMuYml0Z29LZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1syXSk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbmV3IEZMUlAgVFNTIGN1c3RvZGlhbCB3YWxsZXQgd2l0aG91dCByZXF1aXJpbmcgYSBwYXNzcGhyYXNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5cyA9IFsnMScsICcyJywgJzMnXTtcbiAgICAgIGNvbnN0IHRmbHJwID0gYml0Z28uY29pbigndGZscnAnKTtcblxuICAgICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAnZmxycCBjdXN0b2RpYWwgd2FsbGV0JyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICAgICAgLy8gTm8gbXVsdGlzaWdUeXBlIHNwZWNpZmllZCDigJQgc2hvdWxkIGRlZmF1bHQgdG8gJ3RzcycgZm9yIEZMUlBcbiAgICAgICAgLy8gTm8gcGFzc3BocmFzZSDigJQgY3VzdG9kaWFsIHdhbGxldHMgbXVzdCBub3QgcmVxdWlyZSBvbmVcbiAgICAgIH07XG5cbiAgICAgIC8vIEZMUlAgaXMgRUNEU0EsIHNvIGdlbmVyYXRlQ3VzdG9kaWFsTXBjV2FsbGV0IGZldGNoZXMgVFNTIHNldHRpbmdzXG4gICAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyL3Rzcy9zZXR0aW5ncycpXG4gICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAucmVwbHkoMjAwLCB7IGNvaW5TZXR0aW5nczogeyBmbHJwOiB7IHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHt9IH0gfSB9KTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RmbHJwL3dhbGxldC9hZGQnKVxuICAgICAgICAudGltZXMoMSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyAuLi53YWxsZXRQYXJhbXMsIG11bHRpc2lnVHlwZTogJ3RzcycsIGtleXMgfSk7XG5cbiAgICAgIGNvbnN0IGZscnBXYWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRmbHJwKTtcblxuICAgICAgY29uc3QgcmVzID0gYXdhaXQgZmxycFdhbGxldHMuZ2VuZXJhdGVXYWxsZXQod2FsbGV0UGFyYW1zKTtcbiAgICAgIGlmICghaXNXYWxsZXRXaXRoS2V5Y2hhaW5zKHJlcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd3YWxsZXQgbWlzc2luZyByZXF1aXJlZCBrZXljaGFpbnMnKTtcbiAgICAgIH1cbiAgICAgIHJlcy53YWxsZXQubGFiZWwoKS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLmxhYmVsKTtcbiAgICAgIHNob3VsZC5lcXVhbChyZXMud2FsbGV0LnR5cGUoKSwgd2FsbGV0UGFyYW1zLnR5cGUpO1xuICAgICAgcmVzLndhbGxldC5tdWx0aXNpZ1R5cGUoKS5zaG91bGQuZXF1YWwoJ3RzcycpO1xuICAgICAgcmVzLnVzZXJLZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1swXSk7XG4gICAgICByZXMuYmFja3VwS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKGtleXNbMV0pO1xuICAgICAgcmVzLmJpdGdvS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKGtleXNbMl0pO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBUU1MgU01DIHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvbW1vbktleWNoYWluID0gJ2xvbmdzdHJpbmcnO1xuICAgICAgY29uc3Qgc2VlZCA9ICdzZWVkJztcbiAgICAgIGNvbnN0IGtleXM6IEtleWNoYWluc1RyaXBsZXQgPSB7XG4gICAgICAgIHVzZXJLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogc2VlZCxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgfSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHNlZWQsXG4gICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgfSxcbiAgICAgICAgYml0Z29LZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgYml0Z29LZXlOb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykuZ2V0KCcvYXBpL3YyL3Rzb2wva2V5LzMnKS5yZXBseSgyMDAsIGtleXMuYml0Z29LZXljaGFpbik7XG4gICAgICBjb25zdCB1c2VyS2V5RXhwZWN0ZWRCb2R5ID0ge1xuICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAga2V5VHlwZTogJ3RzcycsXG4gICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBzZWVkLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHVzZXJLZXlOb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC9rZXknLCB1c2VyS2V5RXhwZWN0ZWRCb2R5KVxuICAgICAgICAucmVwbHkoMjAwLCBrZXlzLnVzZXJLZXljaGFpbik7XG4gICAgICBjb25zdCBiYWNrdXBLZXlFeHBlY3RlZEJvZHkgPSB7XG4gICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIGtleVR5cGU6ICd0c3MnLFxuICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogc2VlZCxcbiAgICAgIH07XG4gICAgICBjb25zdCBiYWNrdXBLZXlOb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC9rZXknLCBiYWNrdXBLZXlFeHBlY3RlZEJvZHkpXG4gICAgICAgIC5yZXBseSgyMDAsIGtleXMuYmFja3VwS2V5Y2hhaW4pO1xuXG4gICAgICBjb25zdCB3YWxsZXRQYXJhbXM6IEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHtcbiAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICB0eXBlOiAnY29sZCcsXG4gICAgICAgIGJpdGdvS2V5SWQ6IGtleXMuYml0Z29LZXljaGFpbi5pZCxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgIGNvbGREZXJpdmF0aW9uU2VlZDogc2VlZCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2tFeHBlY3RlZCA9IHtcbiAgICAgICAgbGFiZWw6IHdhbGxldFBhcmFtcy5sYWJlbCxcbiAgICAgICAgbTogMixcbiAgICAgICAgbjogMyxcbiAgICAgICAga2V5czogW2tleXMudXNlcktleWNoYWluLmlkLCBrZXlzLmJhY2t1cEtleWNoYWluLmlkLCBrZXlzLmJpdGdvS2V5Y2hhaW4uaWRdLFxuICAgICAgICB0eXBlOiB3YWxsZXRQYXJhbXMudHlwZSxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiB3YWxsZXRQYXJhbXMubXVsdGlzaWdUeXBlLFxuICAgICAgICBlbnRlcnByaXNlOiB3YWxsZXRQYXJhbXMuZW50ZXJwcmlzZSxcbiAgICAgICAgd2FsbGV0VmVyc2lvbjogdW5kZWZpbmVkLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3Rzb2wvd2FsbGV0L2FkZCcsIHdhbGxldE5vY2tFeHBlY3RlZClcbiAgICAgICAgLnJlcGx5KDIwMCwgeyAuLi53YWxsZXROb2NrRXhwZWN0ZWQsIHJlc3BvbnNlVHlwZTogJ1dhbGxldFdpdGhLZXljaGFpbnMnIH0pO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHdhbGxldFBhcmFtcyk7XG4gICAgICBpZiAoIWlzV2FsbGV0V2l0aEtleWNoYWlucyhyZXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignd2FsbGV0IG1pc3NpbmcgcmVxdWlyZWQga2V5Y2hhaW5zJyk7XG4gICAgICB9XG4gICAgICByZXMucmVzcG9uc2VUeXBlLnNob3VsZC5lcXVhbCgnV2FsbGV0V2l0aEtleWNoYWlucycpO1xuICAgICAgcmVzLndhbGxldC5sYWJlbCgpLnNob3VsZC5lcXVhbCh3YWxsZXRQYXJhbXMubGFiZWwpO1xuICAgICAgc2hvdWxkLmVxdWFsKHJlcy53YWxsZXQudHlwZSgpLCB3YWxsZXRQYXJhbXMudHlwZSk7XG4gICAgICByZXMud2FsbGV0LnRvSlNPTigpLmVudGVycHJpc2Uuc2hvdWxkLmVxdWFsKHdhbGxldFBhcmFtcy5lbnRlcnByaXNlKTtcbiAgICAgIHJlcy53YWxsZXQubXVsdGlzaWdUeXBlKCkuc2hvdWxkLmVxdWFsKHdhbGxldFBhcmFtcy5tdWx0aXNpZ1R5cGUpO1xuICAgICAgcmVzLnVzZXJLZXljaGFpbi5zaG91bGQuZGVlcEVxdWFsKGtleXMudXNlcktleWNoYWluKTtcbiAgICAgIHJlcy5iYWNrdXBLZXljaGFpbi5zaG91bGQuZGVlcEVxdWFsKGtleXMuYmFja3VwS2V5Y2hhaW4pO1xuICAgICAgcmVzLmJpdGdvS2V5Y2hhaW4uc2hvdWxkLmRlZXBFcXVhbChrZXlzLmJpdGdvS2V5Y2hhaW4pO1xuXG4gICAgICBiaXRnb0tleU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHVzZXJLZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBiYWNrdXBLZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGZvciBUU1MgU01DIHdhbGxldCBpZiB0aGUgYml0Z29LZXlJZCBpcyBub3QgYSBiaXRnbyBrZXkgJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPSAnbG9uZ3N0cmluZyc7XG4gICAgICBjb25zdCBzZWVkID0gJ3NlZWQnO1xuICAgICAgY29uc3Qga2V5czogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBzZWVkLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogc2VlZCxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBiaXRnb0tleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKS5nZXQoJy9hcGkvdjIvdHNvbC9rZXkvMScpLnJlcGx5KDIwMCwga2V5cy51c2VyS2V5Y2hhaW4pO1xuXG4gICAgICBjb25zdCB3YWxsZXRQYXJhbXM6IEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHtcbiAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICB0eXBlOiAnY29sZCcsXG4gICAgICAgIGJpdGdvS2V5SWQ6IGtleXMudXNlcktleWNoYWluLmlkLFxuICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgY29sZERlcml2YXRpb25TZWVkOiBzZWVkLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0c29sKTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQod2FsbGV0UGFyYW1zKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnVGhlIHByb3ZpZGVkIGJpdGdvS2V5SWQgaXMgbm90IGEgQml0R28ga2V5Y2hhaW4nKTtcblxuICAgICAgYml0Z29LZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZW5lcmF0ZSBzaGllbGRlZCB3YWxsZXQ6JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHR6ZWMgPSBiaXRnby5jb2luKCd0emVjJyk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBzaGllbGRlZCBjdXN0b2RpYWwgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5cyA9IFsnMScsICcyJywgJzMnXTtcblxuICAgICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAnc2hpZWxkZWQgd2FsbGV0JyxcbiAgICAgICAgaXNTaGllbGRlZDogdHJ1ZSxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90emVjL3dhbGxldC9hZGQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgIGJvZHkubXVsdGlzaWdUeXBlLnNob3VsZC5lcXVhbChtdWx0aXNpZ1R5cGVzLnRzcyk7XG4gICAgICAgICAgYm9keS5jb2luU3BlY2lmaWMuc2hvdWxkLmRlZXBFcXVhbCh7IGlzU2hpZWxkZWQ6IHRydWUgfSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC50aW1lcygxKVxuICAgICAgICAucmVwbHkoMjAwLCB7IC4uLndhbGxldFBhcmFtcywgbXVsdGlzaWdUeXBlOiBtdWx0aXNpZ1R5cGVzLnRzcywga2V5cyB9KTtcblxuICAgICAgY29uc3Qgc2hpZWxkZWRXYWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHR6ZWMpO1xuXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBzaGllbGRlZFdhbGxldHMuZ2VuZXJhdGVXYWxsZXQod2FsbGV0UGFyYW1zKTtcbiAgICAgIGlmICghaXNXYWxsZXRXaXRoS2V5Y2hhaW5zKHJlcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd3YWxsZXQgbWlzc2luZyByZXF1aXJlZCBrZXljaGFpbnMnKTtcbiAgICAgIH1cbiAgICAgIHJlcy53YWxsZXQubGFiZWwoKS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLmxhYmVsKTtcbiAgICAgIHNob3VsZC5lcXVhbChyZXMud2FsbGV0LnR5cGUoKSwgd2FsbGV0UGFyYW1zLnR5cGUpO1xuICAgICAgcmVzLndhbGxldC50b0pTT04oKS5lbnRlcnByaXNlLnNob3VsZC5lcXVhbCh3YWxsZXRQYXJhbXMuZW50ZXJwcmlzZSk7XG4gICAgICByZXMud2FsbGV0Lm11bHRpc2lnVHlwZSgpLnNob3VsZC5lcXVhbChtdWx0aXNpZ1R5cGVzLnRzcyk7XG4gICAgICByZXMudXNlcktleWNoYWluLnR5cGUuc2hvdWxkLmVxdWFsKCd0c3MnKTtcbiAgICAgIHJlcy5iYWNrdXBLZXljaGFpbi50eXBlLnNob3VsZC5lcXVhbCgndHNzJyk7XG4gICAgICByZXMuYml0Z29LZXljaGFpbi50eXBlLnNob3VsZC5lcXVhbCgndHNzJyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGEgbm9uLWN1c3RvZGlhbCBzaGllbGRlZCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRQYXJhbXM6IEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHtcbiAgICAgICAgbGFiZWw6ICdzaGllbGRlZCB3YWxsZXQnLFxuICAgICAgICBpc1NoaWVsZGVkOiB0cnVlLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHR5cGU6ICdob3QnLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2hpZWxkZWRXYWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHR6ZWMpO1xuXG4gICAgICBhd2FpdCBzaGllbGRlZFdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHdhbGxldFBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3NoaWVsZGVkIHdhbGxldHMgY2FuIG9ubHkgYmUgY3JlYXRlZCBhcyBjdXN0b2RpYWwgd2FsbGV0cycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgYSBzaGllbGRlZCB3YWxsZXQgd2l0aG91dCBhbiBlbnRlcnByaXNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAnc2hpZWxkZWQgd2FsbGV0JyxcbiAgICAgICAgaXNTaGllbGRlZDogdHJ1ZSxcbiAgICAgICAgdHlwZTogJ2N1c3RvZGlhbCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBzaGllbGRlZFdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdHplYyk7XG5cbiAgICAgIGF3YWl0IHNoaWVsZGVkV2FsbGV0cy5nZW5lcmF0ZVdhbGxldCh3YWxsZXRQYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2VudGVycHJpc2UgaXMgcmVxdWlyZWQnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIFRTUyBNUEN2MiB3YWxsZXQ6JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRzc1NldHRpbmdzOiBUc3NTZXR0aW5ncyA9IHtcbiAgICAgICAgY29pblNldHRpbmdzOiB7XG4gICAgICAgICAgZXRoOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJzYzoge1xuICAgICAgICAgICAgd2FsbGV0Q3JlYXRpb25TZXR0aW5nczoge1xuICAgICAgICAgICAgICBtdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjb2xkTXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY3VzdG9kaWFsTXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwb2x5Z29uOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGF0b206IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY29sZE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGN1c3RvZGlhbE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGlhOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJlcmE6IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY29sZE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGN1c3RvZGlhbE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYXJiZXRoOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9wZXRoOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLmdldChgL2FwaS92Mi90c3Mvc2V0dGluZ3NgKS5xdWVyeSh0cnVlKS50aW1lcygyKS5yZXBseSgyMDAsIHRzc1NldHRpbmdzKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICBzYW5kYm94LnZlcmlmeUFuZFJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIFsnaHRldGgnLCAndGJzYycsICd0cG9seWdvbicsICd0dGlhJywgJ3RhdG9tJywgJ3RiZXJhJywgJ3RhcmJldGgnLCAndG9wZXRoJ10uZm9yRWFjaCgoY29pbikgPT4ge1xuICAgICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgJHtjb2lufSBUU1MgTVBDdjIgaG90IHdhbGxldGAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc3R1YkNyZWF0ZUtleWNoYWlucyA9IHNhbmRib3hcbiAgICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvYWRkYCkucmVwbHkoMjAwKTtcblxuICAgICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRlc3RDb2luKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAndHNzIHBhc3N3b3JkJyxcbiAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgc3R1YkNyZWF0ZUtleWNoYWlucy5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlIH0pLFxuICAgICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgJHtjb2lufSBUU1MgTVBDdjIgaG90IHdhbGxldCB3aXRob3V0IHBhc3NpbmcgbXVsdGlzaWcgdHlwZWAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc3R1YkNyZWF0ZUtleWNoYWlucyA9IHNhbmRib3hcbiAgICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvYWRkYCwgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICAgIGJvZHkubXVsdGlzaWdUeXBlLnNob3VsZC5lcXVhbChtdWx0aXNpZ1R5cGVzLnRzcyk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgc3R1YkNyZWF0ZUtleWNoYWlucy5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlIH0pLFxuICAgICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgJHtjb2lufSBUU1MgTVBDdjIgY29sZCB3YWxsZXRgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHRlc3RDb2luID0gYml0Z28uY29pbihjb2luKTtcbiAgICAgICAgY29uc3QgYml0Z29LZXlJZCA9ICdrZXkxMjMnO1xuICAgICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9ICcweGFiYyc7XG5cbiAgICAgICAgY29uc3QgYml0Z29LZXlOb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyLyR7Y29pbn0va2V5LyR7Yml0Z29LZXlJZH1gKVxuICAgICAgICAgIC50aW1lcygxKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGlkOiAna2V5MTIzJyxcbiAgICAgICAgICAgIHB1YjogJ2JpdGdvUHViJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdXNlcktleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7Y29pbn0va2V5YCwge1xuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICBrZXlUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogJzM3JyxcbiAgICAgICAgICAgIGlzTVBDdjI6IHRydWUsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAudGltZXMoMSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBpZDogJ3VzZXJLZXkxMjMnLFxuICAgICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGJhY2t1cEtleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7Y29pbn0va2V5YCwge1xuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgIGtleVR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiAnMzcnLFxuICAgICAgICAgICAgaXNNUEN2MjogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aW1lcygxKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGlkOiAnYmFja3VwS2V5MTIzJyxcbiAgICAgICAgICAgIHB1YjogJ2JhY2t1cFB1YicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvYWRkYCwge1xuICAgICAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgICAgIG06IDIsXG4gICAgICAgICAgICBuOiAzLFxuICAgICAgICAgICAga2V5czogWyd1c2VyS2V5MTIzJywgJ2JhY2t1cEtleTEyMycsICdrZXkxMjMnXSxcbiAgICAgICAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0ZXN0Q29pbik7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgICAgICBiaXRnb0tleUlkOiAna2V5MTIzJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJzB4YWJjJyxcbiAgICAgICAgICBjb2xkRGVyaXZhdGlvblNlZWQ6ICczNycsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSAoYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpKSBhcyBXYWxsZXRXaXRoS2V5Y2hhaW5zO1xuXG4gICAgICAgIGJpdGdvS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICB1c2VyS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBiYWNrdXBLZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgICBzaG91bGQuZXhpc3QocmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLnVzZXJLZXljaGFpbik7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXNwb25zZS5iYWNrdXBLZXljaGFpbik7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXNwb25zZS5iaXRnb0tleWNoYWluKTtcbiAgICAgICAgcmVzcG9uc2UucmVzcG9uc2VUeXBlLnNob3VsZC5lcXVhbCgnV2FsbGV0V2l0aEtleWNoYWlucycpO1xuICAgICAgICByZXNwb25zZS51c2VyS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKCd1c2VyS2V5MTIzJyk7XG4gICAgICAgIHJlc3BvbnNlLmJhY2t1cEtleWNoYWluLmlkLnNob3VsZC5lcXVhbCgnYmFja3VwS2V5MTIzJyk7XG4gICAgICAgIHJlc3BvbnNlLmJpdGdvS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKCdrZXkxMjMnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgc2hvdWxkIGNyZWF0ZSBhIG5ldyAke2NvaW59IFRTUyBNUEN2MiBjdXN0b2R5IHdhbGxldGAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgICBjb25zdCBrZXlzID0gWyd1c2VyS2V5JywgJ2JhY2t1cEtleScsICdiaXRnb0tleSddO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyBhcyBjb25zdCxcbiAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogNSxcbiAgICAgICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke2NvaW59L3dhbGxldC9hZGRgKVxuICAgICAgICAgIC50aW1lcygxKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgLi4ucGFyYW1zLCBrZXlzIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gKGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKSkgYXMgV2FsbGV0V2l0aEtleWNoYWlucztcblxuICAgICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXNwb25zZS53YWxsZXQpO1xuICAgICAgICBzaG91bGQuZXhpc3QocmVzcG9uc2UudXNlcktleWNoYWluKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLmJhY2t1cEtleWNoYWluKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLmJpdGdvS2V5Y2hhaW4pO1xuICAgICAgICByZXNwb25zZS5yZXNwb25zZVR5cGUuc2hvdWxkLmVxdWFsKCdXYWxsZXRXaXRoS2V5Y2hhaW5zJyk7XG4gICAgICAgIHJlc3BvbnNlLnVzZXJLZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1swXSk7XG4gICAgICAgIHJlc3BvbnNlLmJhY2t1cEtleWNoYWluLmlkLnNob3VsZC5lcXVhbChrZXlzWzFdKTtcbiAgICAgICAgcmVzcG9uc2UuYml0Z29LZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1syXSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KGBzaG91bGQgY3JlYXRlIGEgbmV3IGh0ZXRoIFRTUyBNUEN2MiB3YWxsZXQgd2l0aCB3YWxsZXRWZXJzaW9uIDZgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdHViQ3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0L2FkZGAsIChib2R5KSA9PiB7XG4gICAgICAgICAgYm9keS53YWxsZXRWZXJzaW9uLnNob3VsZC5lcXVhbCg2KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHN0dWJDcmVhdGVLZXljaGFpbnMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgTVBDdjIgd2FsbGV0IHdpdGggdmVyc2lvbiA1IGlmIHdhbGxldFZlcnNpb24gcGFzc2VkIGlzIG5vdCA1IG9yIDZgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdHViQ3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0L2FkZGAsIChib2R5KSA9PiB7XG4gICAgICAgICAgYm9keS53YWxsZXRWZXJzaW9uLnNob3VsZC5lcXVhbCg1KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHN0dWJDcmVhdGVLZXljaGFpbnMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnR2VuZXJhdGUgVFNTIEVkRFNBIE1QQ3YyIHdhbGxldDonLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHNzU2V0dGluZ3M6IFRzc1NldHRpbmdzID0ge1xuICAgICAgICBjb2luU2V0dGluZ3M6IHtcbiAgICAgICAgICBzb2w6IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKS5nZXQoYC9hcGkvdjIvdHNzL3NldHRpbmdzYCkucXVlcnkodHJ1ZSkudGltZXMoMikucmVwbHkoMjAwLCB0c3NTZXR0aW5ncyk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgc2FuZGJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyB0c29sIFRTUyBFZERTQSBNUEN2MiBob3Qgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdHViQ3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAuc3R1YihFRERTQVV0aWxzLkVkZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucG9zdCgnL2FwaS92Mi90c29sL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRlc3RDb2luKTtcblxuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ3RzcyBlZGRzYSBtcGN2MiB3YWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAndHNzIHBhc3N3b3JkJyxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyBhcyBjb25zdCxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBzdHViQ3JlYXRlS2V5Y2hhaW5zLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgIGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlIH0pLFxuICAgICAgICBwYXJhbXMucGFzc3BocmFzZVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFsbCBiYWNrIHRvIEVkZHNhVXRpbHMgd2hlbiB0c3Mvc2V0dGluZ3MgZG9lcyBub3QgcmV0dXJuIE1QQ3YyIGZvciB0c29sJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLmdldCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKVxuICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBjb2luU2V0dGluZ3M6IHsgc29sOiB7IHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHt9IH0gfSB9KTtcblxuICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdHViRWRkc2FVdGlscyA9IHNhbmRib3hcbiAgICAgICAgLnN0dWIoRUREU0FVdGlscy5kZWZhdWx0LnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpXG4gICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKS5wb3N0KCcvYXBpL3YyL3Rzb2wvd2FsbGV0L2FkZCcpLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIGVkZHNhIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHN0dWJFZGRzYVV0aWxzLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdTaGFyaW5nJywgKCkgPT4ge1xuICAgIGRlc2NyaWJlKCdXYWxsZXQgc2hhcmUgd2hlcmUga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkIGlzIHNldCB0cnVlJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZGJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3doZW4gcGFzc3dvcmQgbm90IHByb3ZpdmVkIHdlIHNob3VsZCByZWNlaXZlIHZhbGlkYXRpb24gZXJyb3InLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9jYXNlXzEnO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIGFjY2VwdCBzaGFyZSBjYXNlXG4gICAgICAgIGF3YWl0IG9mY1dhbGxldHNcbiAgICAgICAgICAuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3VzZXJQYXNzd29yZCBwYXJhbSBtdXN0IGJlIHByb3ZpZGVkIHRvIGRlY3J5cHQgc2hhcmVkIGtleScpO1xuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd3aGVuIHdlIGFjY2VwdCBzaGFyZSBhbmQgZmFpbGVkIHRvIG1ha2UgY2hhbmdlcywgcmVzaGFyZSBzaG91bGQgbm90IGJlIGNhbGxlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X2Nhc2VfMic7XG4gICAgICAgIGNvbnN0IGtleWNoYWluSWQgPSAndGVzdF9jYXNlXzInO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9jYXNlXzInO1xuICAgICAgICAvLyBjcmVhdGUgYSB1c2VyIGtleVxuICAgICAgICBjb25zdCBrZXlDaGFpbk5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YyL29mYy9rZXknLCBfLmNvbmZvcm1zKHsgcHViOiAocCkgPT4gcC5zdGFydHNXaXRoKCd4cHViJykgfSkpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgKHVyaSwgcmVxdWVzdEJvZHkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7IGlkOiBrZXljaGFpbklkLCBlbmNyeXB0ZWRQcnY6IHJlcXVlc3RCb2R5WydlbmNyeXB0ZWRQcnYnXSwgcHViOiByZXF1ZXN0Qm9keVsncHViJ10gfTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZUluZm9Ob2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgYWNjZXB0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICAgIC8vIENoZWNrIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudCAoc2lnbmF0dXJlIGFuZCBwYXlsb2FkIGFyZSBkeW5hbWljKVxuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgYm9keS53YWxsZXRTaGFyZUlkID09PSBzaGFyZUlkICYmXG4gICAgICAgICAgICAgIGJvZHkuc3RhdGUgPT09ICdhY2NlcHRlZCcgJiZcbiAgICAgICAgICAgICAgYm9keS5rZXlJZCA9PT0ga2V5Y2hhaW5JZCAmJlxuICAgICAgICAgICAgICB0eXBlb2YgYm9keS5zaWduYXR1cmUgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBib2R5LnBheWxvYWQgPT09ICdzdHJpbmcnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiBmYWxzZSB9KTtcblxuICAgICAgICAvLyBTdHViIHdhbGxldCBzaGFyZSB3YWxsZXQgbWV0aG9kXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlU3R1YiA9IHNhbmRib3guc3R1YihXYWxsZXQucHJvdG90eXBlLCAnc2hhcmVXYWxsZXQnKS5vbkNhbGwoMCkucmVzb2x2ZXMoJ3N1Y2Nlc3MnKTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBvZmNXYWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLmNoYW5nZWQsIGZhbHNlKTtcbiAgICAgICAga2V5Q2hhaW5Ob2NrLmRvbmUoKTtcbiAgICAgICAgd2FsbGV0U2hhcmVJbmZvTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh3YWxsZXRTaGFyZVN0dWIuY2FsbGVkLCBmYWxzZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3doZW4gd2UgYWNjZXB0IHNoYXJlIGJ1dCBzdGF0ZSBpcyBub3QgdmFsaWQsIHJlc2hhcmUgc2hvdWxkIG5vdCBiZSBjYWxsZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9jYXNlXzMnO1xuICAgICAgICBjb25zdCBrZXljaGFpbklkID0gJ3Rlc3RfY2FzZV8zJztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfY2FzZV8zJztcblxuICAgICAgICAvLyBjcmVhdGUgYSB1c2VyIGtleVxuICAgICAgICBjb25zdCBrZXlDaGFpbk5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YyL29mYy9rZXknLCBfLmNvbmZvcm1zKHsgcHViOiAocCkgPT4gcC5zdGFydHNXaXRoKCd4cHViJykgfSkpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgKHVyaSwgcmVxdWVzdEJvZHkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7IGlkOiBrZXljaGFpbklkLCBlbmNyeXB0ZWRQcnY6IHJlcXVlc3RCb2R5WydlbmNyeXB0ZWRQcnYnXSwgcHViOiByZXF1ZXN0Qm9keVsncHViJ10gfTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZUluZm9Ob2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgYWNjZXB0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICAgIC8vIENoZWNrIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudCAoc2lnbmF0dXJlIGFuZCBwYXlsb2FkIGFyZSBkeW5hbWljKVxuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgYm9keS53YWxsZXRTaGFyZUlkID09PSBzaGFyZUlkICYmXG4gICAgICAgICAgICAgIGJvZHkuc3RhdGUgPT09ICdhY2NlcHRlZCcgJiZcbiAgICAgICAgICAgICAgYm9keS5rZXlJZCA9PT0ga2V5Y2hhaW5JZCAmJlxuICAgICAgICAgICAgICB0eXBlb2YgYm9keS5zaWduYXR1cmUgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBib2R5LnBheWxvYWQgPT09ICdzdHJpbmcnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ25vdF9hY2NlcHRlZCcgfSk7XG5cbiAgICAgICAgLy8gU3R1YiB3YWxsZXQgc2hhcmUgd2FsbGV0IG1ldGhvZFxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZVN0dWIgPSBzYW5kYm94LnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ3NoYXJlV2FsbGV0Jykub25DYWxsKDApLnJlc29sdmVzKCdzdWNjZXNzJyk7XG5cbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgb2ZjV2FsbGV0cy5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ25vdF9hY2NlcHRlZCcpO1xuICAgICAgICBrZXlDaGFpbk5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRTaGFyZUluZm9Ob2NrLmRvbmUoKTtcbiAgICAgICAgYWNjZXB0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWQsIGZhbHNlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnd2hlbiB3ZSBnZXQgYSBjb3JyZWN0IHJlc3Bvc25lIGZyb20gYWNjZXB0IHNoYXJlIG1ldGhvZCwgYnV0IGZhaWxlZCB0byByZXNoYXJlIHdhbGxldCB3aXRoIHNwZW5kZXJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5JZCA9ICd0ZXN0X2Nhc2VfNic7XG4gICAgICAgIGNvbnN0IHNwZW5kZXJVc2VyT25lID0ge1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHVzZXI6ICd0ZXN0X2Nhc2VfNicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlbWFpbDogeyBlbWFpbDogJ3Rlc3RfY2FzZV82JyB9LFxuICAgICAgICAgIGlkOiAndGVzdF9jYXNlXzYnLFxuICAgICAgICAgIGNvaW46ICdvZmMnLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzcGVuZGVyVXNlclR3byA9IHtcbiAgICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB1c2VyOiAndGVzdF9jYXNlXzknLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZW1haWw6IHsgZW1haWw6ICd0ZXN0X2Nhc2VfOScgfSxcbiAgICAgICAgICBpZDogJ3Rlc3RfY2FzZV85JyxcbiAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgYWRtaW5Vc2VyID0ge1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHVzZXI6ICd0ZXN0X2Nhc2VfNycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlbWFpbDogeyBlbWFpbDogJ3Rlc3RfY2FzZV83JyB9LFxuICAgICAgICAgIGlkOiAndGVzdF9jYXNlXzcnLFxuICAgICAgICAgIGNvaW46ICdvZmMnLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB2aWV3ZXJVc2VyID0ge1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnXSxcbiAgICAgICAgICAgIHVzZXI6ICd0ZXN0X2Nhc2VfOCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlbWFpbDogeyBlbWFpbDogJ3Rlc3RfY2FzZV84JyB9LFxuICAgICAgICAgIGlkOiAndGVzdF9jYXNlXzgnLFxuICAgICAgICAgIGNvaW46ICdvZmMnLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9jYXNlXzYnO1xuICAgICAgICBjb25zdCB3YWxsZXRJZCA9ICd0ZXN0X2Nhc2VfNic7XG4gICAgICAgIGNvbnN0IGVudGVycHJpc2VJZCA9ICd0ZXN0X2Nhc2VfNic7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldElkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBhIHVzZXIga2V5XG4gICAgICAgIGNvbnN0IGtleUNoYWluQ3JlYXRlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvb2ZjL2tleScsIF8uY29uZm9ybXMoeyBwdWI6IChwKSA9PiBwLnN0YXJ0c1dpdGgoJ3hwdWInKSB9KSlcbiAgICAgICAgICAucmVwbHkoMjAwLCAodXJpLCByZXF1ZXN0Qm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHsgaWQ6IGtleWNoYWluSWQsIGVuY3J5cHRlZFBydjogcmVxdWVzdEJvZHlbJ2VuY3J5cHRlZFBydiddLCBwdWI6IHJlcXVlc3RCb2R5WydwdWInXSB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICAvLyBDaGVjayByZXF1aXJlZCBmaWVsZHMgYXJlIHByZXNlbnQgKHNpZ25hdHVyZSBhbmQgcGF5bG9hZCBhcmUgZHluYW1pYylcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgIGJvZHkud2FsbGV0U2hhcmVJZCA9PT0gc2hhcmVJZCAmJlxuICAgICAgICAgICAgICBib2R5LnN0YXRlID09PSAnYWNjZXB0ZWQnICYmXG4gICAgICAgICAgICAgIGJvZHkua2V5SWQgPT09IGtleWNoYWluSWQgJiZcbiAgICAgICAgICAgICAgdHlwZW9mIGJvZHkuc2lnbmF0dXJlID09PSAnc3RyaW5nJyAmJlxuICAgICAgICAgICAgICB0eXBlb2YgYm9keS5wYXlsb2FkID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgY2hhbmdlZDogdHJ1ZSwgc3RhdGU6ICdhY2NlcHRlZCcgfSk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0SW5mb05vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldC8ke3dhbGxldElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlcnM6IFtzcGVuZGVyVXNlck9uZS5wYXlsb2FkLCBzcGVuZGVyVXNlclR3by5wYXlsb2FkLCBhZG1pblVzZXIucGF5bG9hZCwgdmlld2VyVXNlci5wYXlsb2FkXSxcbiAgICAgICAgICAgIGVudGVycHJpc2U6IGVudGVycHJpc2VJZCxcbiAgICAgICAgICAgIGNvaW46IHNwZW5kZXJVc2VyT25lLmNvaW4sXG4gICAgICAgICAgICBpZDogd2FsbGV0SWQsXG4gICAgICAgICAgICBrZXlzOiBbe31dLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGVudGVycHJpc2VVc2VyTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS9lbnRlcnByaXNlLyR7ZW50ZXJwcmlzZUlkfS91c2VyYClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBhZG1pblVzZXJzOiBbXG4gICAgICAgICAgICAgIHsgaWQ6IHNwZW5kZXJVc2VyT25lLmlkLCBlbWFpbDogc3BlbmRlclVzZXJPbmUuZW1haWwgfSxcbiAgICAgICAgICAgICAgeyBpZDogc3BlbmRlclVzZXJUd28uaWQsIGVtYWlsOiBzcGVuZGVyVXNlclR3by5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiBhZG1pblVzZXIuaWQsIGVtYWlsOiBhZG1pblVzZXIuZW1haWwgfSxcbiAgICAgICAgICAgICAgeyBpZDogdmlld2VyVXNlci5pZCwgZW1haWw6IHZpZXdlclVzZXIuZW1haWwgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBub25BZG1pblVzZXJzOiBbXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZVN0dWIgPSBzYW5kYm94XG4gICAgICAgICAgLnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ3NoYXJlV2FsbGV0JylcbiAgICAgICAgICAucmV0dXJucyhuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIHJlamVjdCkgPT4gcmVqZWN0KG5ldyBFcnJvcignRmFpbGVkIHRvIHJlc2hhcmUgd2FsbGV0JykpKSk7XG5cbiAgICAgICAgY29uc3Qgc2hhcmVQYXJhbXNPbmUgPSB7XG4gICAgICAgICAgd2FsbGV0SWQ6IHdhbGxldElkLFxuICAgICAgICAgIHVzZXI6IHNwZW5kZXJVc2VyT25lLmlkLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBzcGVuZGVyVXNlck9uZS5wYXlsb2FkLnBlcm1pc3Npb25zLmpvaW4oJywnKSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB1c2VyUGFzc3dvcmQsXG4gICAgICAgICAgZW1haWw6IHNwZW5kZXJVc2VyT25lLmVtYWlsLmVtYWlsLFxuICAgICAgICAgIHJlc2hhcmU6IHRydWUsXG4gICAgICAgICAgc2tpcEtleWNoYWluOiBmYWxzZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBzaGFyZVBhcmFtc1R3byA9IHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0SWQsXG4gICAgICAgICAgdXNlcjogc3BlbmRlclVzZXJUd28uaWQsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IHNwZW5kZXJVc2VyVHdvLnBheWxvYWQucGVybWlzc2lvbnMuam9pbignLCcpLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHVzZXJQYXNzd29yZCxcbiAgICAgICAgICBlbWFpbDogc3BlbmRlclVzZXJUd28uZW1haWwuZW1haWwsXG4gICAgICAgICAgcmVzaGFyZTogdHJ1ZSxcbiAgICAgICAgICBza2lwS2V5Y2hhaW46IGZhbHNlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuc3RhdGUsICdhY2NlcHRlZCcpO1xuICAgICAgICBrZXlDaGFpbkNyZWF0ZU5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRJbmZvTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGVudGVycHJpc2VVc2VyTm9jay5kb25lKCk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh3YWxsZXRTaGFyZVN0dWIuY2FsbGVkT25jZSwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh3YWxsZXRTaGFyZVN0dWIuY2FsbGVkV2l0aChzaGFyZVBhcmFtc09uZSksIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwod2FsbGV0U2hhcmVTdHViLmNhbGxlZFdpdGgoc2hhcmVQYXJhbXNUd28pLCBmYWxzZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3doZW4gd2UgZ2V0IGEgY29ycmVjdCByZXNwb3NuZSBmcm9tIGFjY2VwdCBzaGFyZSBtZXRob2QgYW5kIHJlc2hhcmUgd2FsbGV0IHdpdGggc3BlbmRlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9jYXNlXzYnO1xuICAgICAgICBjb25zdCBrZXljaGFpbklkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3Qgc3BlbmRlclVzZXJPbmUgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV82JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzYnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfNicsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHNwZW5kZXJVc2VyVHdvID0ge1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHVzZXI6ICd0ZXN0X2Nhc2VfOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlbWFpbDogeyBlbWFpbDogJ3Rlc3RfY2FzZV85JyB9LFxuICAgICAgICAgIGlkOiAndGVzdF9jYXNlXzknLFxuICAgICAgICAgIGNvaW46ICdvZmMnLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBhZG1pblVzZXIgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV83JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzcnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfNycsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHZpZXdlclVzZXIgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV84JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzgnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfOCcsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X2Nhc2VfNic7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3QgZW50ZXJwcmlzZUlkID0gJ3Rlc3RfY2FzZV82JztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldElkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBhIHVzZXIga2V5XG4gICAgICAgIGNvbnN0IGtleUNoYWluQ3JlYXRlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLmNvbmZvcm1zKHsgcHViOiAocCkgPT4gcC5zdGFydHNXaXRoKCd4cHViJykgfSkpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgKHVyaSwgcmVxdWVzdEJvZHkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7IGlkOiBrZXljaGFpbklkLCBlbmNyeXB0ZWRQcnY6IHJlcXVlc3RCb2R5WydlbmNyeXB0ZWRQcnYnXSwgcHViOiByZXF1ZXN0Qm9keVsncHViJ10gfTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICAgIC8vIENoZWNrIHJlcXVpcmVkIGZpZWxkcyBhcmUgcHJlc2VudCAoc2lnbmF0dXJlIGFuZCBwYXlsb2FkIGFyZSBkeW5hbWljKVxuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgYm9keS53YWxsZXRTaGFyZUlkID09PSBzaGFyZUlkICYmXG4gICAgICAgICAgICAgIGJvZHkuc3RhdGUgPT09ICdhY2NlcHRlZCcgJiZcbiAgICAgICAgICAgICAgYm9keS5rZXlJZCA9PT0ga2V5Y2hhaW5JZCAmJlxuICAgICAgICAgICAgICB0eXBlb2YgYm9keS5zaWduYXR1cmUgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgICAgIHR5cGVvZiBib2R5LnBheWxvYWQgPT09ICdzdHJpbmcnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRJbmZvTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi90YnRjL3dhbGxldC8ke3dhbGxldElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlcnM6IFtzcGVuZGVyVXNlck9uZS5wYXlsb2FkLCBzcGVuZGVyVXNlclR3by5wYXlsb2FkLCBhZG1pblVzZXIucGF5bG9hZCwgdmlld2VyVXNlci5wYXlsb2FkXSxcbiAgICAgICAgICAgIGVudGVycHJpc2U6IGVudGVycHJpc2VJZCxcbiAgICAgICAgICAgIGNvaW46IHNwZW5kZXJVc2VyT25lLmNvaW4sXG4gICAgICAgICAgICBpZDogd2FsbGV0SWQsXG4gICAgICAgICAgICBrZXlzOiBbe31dLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGVudGVycHJpc2VVc2VyTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS9lbnRlcnByaXNlLyR7ZW50ZXJwcmlzZUlkfS91c2VyYClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBhZG1pblVzZXJzOiBbXG4gICAgICAgICAgICAgIHsgaWQ6IHNwZW5kZXJVc2VyT25lLmlkLCBlbWFpbDogc3BlbmRlclVzZXJPbmUuZW1haWwgfSxcbiAgICAgICAgICAgICAgeyBpZDogc3BlbmRlclVzZXJUd28uaWQsIGVtYWlsOiBzcGVuZGVyVXNlclR3by5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiBhZG1pblVzZXIuaWQsIGVtYWlsOiBhZG1pblVzZXIuZW1haWwgfSxcbiAgICAgICAgICAgICAgeyBpZDogdmlld2VyVXNlci5pZCwgZW1haWw6IHZpZXdlclVzZXIuZW1haWwgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBub25BZG1pblVzZXJzOiBbXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZVN0dWIgPSBzYW5kYm94XG4gICAgICAgICAgLnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ3NoYXJlV2FsbGV0JylcbiAgICAgICAgICAucmV0dXJucyhuZXcgUHJvbWlzZSgocmVzb2x2ZSwgX3JlamVjdCkgPT4gcmVzb2x2ZSgnc3VjY2VzcycpKSk7XG5cbiAgICAgICAgY29uc3Qgc2hhcmVQYXJhbXNPbmUgPSB7XG4gICAgICAgICAgd2FsbGV0SWQ6IHdhbGxldElkLFxuICAgICAgICAgIHVzZXI6IHNwZW5kZXJVc2VyT25lLmlkLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBzcGVuZGVyVXNlck9uZS5wYXlsb2FkLnBlcm1pc3Npb25zLmpvaW4oJywnKSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB1c2VyUGFzc3dvcmQsXG4gICAgICAgICAgZW1haWw6IHNwZW5kZXJVc2VyT25lLmVtYWlsLmVtYWlsLFxuICAgICAgICAgIHJlc2hhcmU6IHRydWUsXG4gICAgICAgICAgc2tpcEtleWNoYWluOiBmYWxzZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBzaGFyZVBhcmFtc1R3byA9IHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0SWQsXG4gICAgICAgICAgdXNlcjogc3BlbmRlclVzZXJUd28uaWQsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IHNwZW5kZXJVc2VyVHdvLnBheWxvYWQucGVybWlzc2lvbnMuam9pbignLCcpLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHVzZXJQYXNzd29yZCxcbiAgICAgICAgICBlbWFpbDogc3BlbmRlclVzZXJUd28uZW1haWwuZW1haWwsXG4gICAgICAgICAgcmVzaGFyZTogdHJ1ZSxcbiAgICAgICAgICBza2lwS2V5Y2hhaW46IGZhbHNlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHdhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuc3RhdGUsICdhY2NlcHRlZCcpO1xuICAgICAgICBrZXlDaGFpbkNyZWF0ZU5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRJbmZvTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGVudGVycHJpc2VVc2VyTm9jay5kb25lKCk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh3YWxsZXRTaGFyZVN0dWIuY2FsbGVkVHdpY2UsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwod2FsbGV0U2hhcmVTdHViLmNhbGxlZFdpdGgoc2hhcmVQYXJhbXNPbmUpLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWRXaXRoKHNoYXJlUGFyYW1zVHdvKSwgdHJ1ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdXYWxsZXQgc2hhcmUgd2hlcmUgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZCBpcyBzZXQgdHJ1ZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNhbmRib3gudmVyaWZ5QW5kUmVzdG9yZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiBwYXNzd29yZCBub3QgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9tdWx0aV9rZXlfMSc7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IG9mY1dhbGxldHNcbiAgICAgICAgICAuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ3VzZXJQYXNzd29yZCBwYXJhbSBtdXN0IGJlIHByb3ZpZGVkIHRvIGdlbmVyYXRlIHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgICAgd2FsbGV0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHN1Y2Nlc3NmdWxseSBhY2NlcHQgc2hhcmUgd2l0aCB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkIGFuZCBzZW5kIHB1YiBhbmQgZW5jcnlwdGVkUHJ2JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfbXVsdGlfa2V5XzInO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZF8xMjMnO1xuICAgICAgICBjb25zdCB3YWxsZXRJZCA9ICd0ZXN0X3dhbGxldF8xMjMnO1xuXG4gICAgICAgIC8vIE1vY2sgd2FsbGV0IHNoYXJlIHJlc3BvbnNlXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0SWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayBrZXljaGFpbiBjcmVhdGlvbiAtIGJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZSgpIHJldHVybnMgeyBwcnYsIHB1YiB9XG4gICAgICAgIC8vIFdlIG5lZWQgdG8gY3JlYXRlIGEgcHJvcGVyIGtleWNoYWluIG9iamVjdCB3aXRoIHBydiBwcm9wZXJ0eVxuICAgICAgICBjb25zdCB0ZXN0S2V5Y2hhaW4gPSBiaXRnby5jb2luKCdvZmMnKS5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7XG4gICAgICAgICAgcHJ2OiB0ZXN0S2V5Y2hhaW4ucHJ2LCAvLyBPRkMgdXNlcyBzZWNwMjU2azEga2V5cywgc28gcHJ2IGZvcm1hdFxuICAgICAgICAgIHB1YjogdGVzdEtleWNoYWluLnB1YixcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTdHViIGtleWNoYWlucygpLmNyZWF0ZSgpIGFuZCBlbmNyeXB0KCkgQkVGT1JFIGNhbGN1bGF0aW5nIGVuY3J5cHRlZFBydlxuICAgICAgICBjb25zdCBrZXljaGFpbnNJbnN0YW5jZSA9IG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluc1N0dWIgPSBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zSW5zdGFuY2UsICdjcmVhdGUnKS5yZXR1cm5zKGtleWNoYWluKTtcblxuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IGtleWNoYWluLnBydiwgcGFzc3dvcmQ6IHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jcnlwdFN0dWIgPSBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXMoZW5jcnlwdGVkUHJ2KTtcblxuICAgICAgICAvLyBNb2NrIHRoZSB1cGRhdGVTaGFyZSBBUEkgY2FsbFxuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgLy8gVmVyaWZ5IHRoYXQgcHViIGFuZCBlbmNyeXB0ZWRQcnYgYXJlIGluY2x1ZGVkXG4gICAgICAgICAgICBpZiAoYm9keS53YWxsZXRTaGFyZUlkICE9PSBzaGFyZUlkIHx8IGJvZHkuc3RhdGUgIT09ICdhY2NlcHRlZCcgfHwgIWJvZHkucHViIHx8ICFib2R5LmVuY3J5cHRlZFBydikge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBWZXJpZnkgcHViIGlzIGEgdmFsaWQgZm9ybWF0IChzZWNwMjU2azEgcHVibGljIGtleSBmb3IgT0ZDKVxuICAgICAgICAgICAgaWYgKCFvZmNXYWxsZXRzLmJhc2VDb2luLmlzVmFsaWRQdWIoYm9keS5wdWIpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBvZmNXYWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLmNoYW5nZWQsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLnN0YXRlLCAnYWNjZXB0ZWQnKTtcblxuICAgICAgICAvLyBWZXJpZnkga2V5Y2hhaW4gY3JlYXRpb24gd2FzIGNhbGxlZFxuICAgICAgICBzaG91bGQuZXF1YWwoa2V5Y2hhaW5zU3R1Yi5jYWxsZWRPbmNlLCB0cnVlKTtcbiAgICAgICAgLy8gVmVyaWZ5IGVuY3J5cHQgd2FzIGNhbGxlZCB3aXRoIHRoZSBjb3JyZWN0IHBhcmFtZXRlcnNcbiAgICAgICAgc2hvdWxkLmVxdWFsKGVuY3J5cHRTdHViLmNhbGxlZFdpdGgoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogdXNlclBhc3N3b3JkIH0pLCB0cnVlKTtcblxuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICBhY2NlcHRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgTk9UIHRyaWdnZXIgcmVzaGFyZSB3aGVuIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQgaXMgdHJ1ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV8zJztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmRfMTIzJztcbiAgICAgICAgY29uc3Qgd2FsbGV0SWQgPSAndGVzdF93YWxsZXRfMTIzJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldElkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlc3RLZXljaGFpbiA9IGJpdGdvLmNvaW4oJ29mYycpLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwcnY6IHRlc3RLZXljaGFpbi5wcnYsXG4gICAgICAgICAgcHViOiB0ZXN0S2V5Y2hhaW4ucHViLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IGtleWNoYWluLnBydiwgcGFzc3dvcmQ6IHVzZXJQYXNzd29yZCB9KTtcblxuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuXG4gICAgICAgIGNvbnN0IGtleWNoYWluc0luc3RhbmNlID0gb2ZjV2FsbGV0cy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICAgICAgc2FuZGJveC5zdHViKGtleWNoYWluc0luc3RhbmNlLCAnY3JlYXRlJykucmV0dXJucyhrZXljaGFpbik7XG4gICAgICAgIHNhbmRib3guc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcyhlbmNyeXB0ZWRQcnYpO1xuXG4gICAgICAgIC8vIFN0dWIgcmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycyB0byB2ZXJpZnkgaXQncyBOT1QgY2FsbGVkXG4gICAgICAgIGNvbnN0IHJlc2hhcmVTdHViID0gc2FuZGJveC5zdHViKFdhbGxldHMucHJvdG90eXBlLCAncmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycycpO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IG9mY1dhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuc3RhdGUsICdhY2NlcHRlZCcpO1xuXG4gICAgICAgIC8vIFZlcmlmeSByZXNoYXJlIHdhcyBOT1QgY2FsbGVkICh1bmxpa2Uga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkIGNhc2UpXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXNoYXJlU3R1Yi5jYWxsZWQsIGZhbHNlKTtcblxuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICBhY2NlcHRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGJ1bGsgYWNjZXB0IHNoYXJlIHdpdGggdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV9idWxrXzEnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZF8xMjMnO1xuXG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyIHRvIHJldHVybiBhIHNoYXJlIHdpdGggdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZFxuICAgICAgICAvLyBOb3RlOiB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkIHNoYXJlcyBkb24ndCBoYXZlIGEga2V5Y2hhaW4sIHNvIHRoZXkgd29uJ3QgYmUgZmlsdGVyZWRcbiAgICAgICAgLy8gYnkgdGhlIGJ1bGtBY2NlcHRTaGFyZSBmaWx0ZXIsIGJ1dCBwcm9jZXNzQWNjZXB0U2hhcmUgd2lsbCBoYW5kbGUgdGhlbVxuICAgICAgICBzYW5kYm94LnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6IHNoYXJlSWQsXG4gICAgICAgICAgICAgIGNvaW46ICdvZmMnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3Qgd2FsbGV0JyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdmcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ3RvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEyMycsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgICAvLyBObyBrZXljaGFpbiAtIHRoaXMgaXMgdGhlIGtleSBkaWZmZXJlbmNlIGZvciBtdWx0aS1rZXktdXNlci1rZXkgc2hhcmVzXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0ZXN0S2V5Y2hhaW4gPSBiaXRnby5jb2luKCdvZmMnKS5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7XG4gICAgICAgICAgcHJ2OiB0ZXN0S2V5Y2hhaW4ucHJ2LFxuICAgICAgICAgIHB1YjogdGVzdEtleWNoYWluLnB1YixcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTZXQgdXAgc3R1YnMgZmlyc3RcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zSW5zdGFuY2UgPSBvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgICAgICBjb25zdCBrZXljaGFpbnNTdHViID0gc2FuZGJveC5zdHViKGtleWNoYWluc0luc3RhbmNlLCAnY3JlYXRlJykucmV0dXJucyhrZXljaGFpbik7XG5cbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBrZXljaGFpbi5wcnYsIHBhc3N3b3JkOiB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIGNvbnN0IGVuY3J5cHRTdHViID0gc2FuZGJveC5zdHViKGJpdGdvLCAnZW5jcnlwdCcpLnJlc29sdmVzKGVuY3J5cHRlZFBydik7XG5cbiAgICAgICAgLy8gTW9jayBidWxrIHVwZGF0ZSBBUEkgLSB0aGlzIGlzIGNhbGxlZCB2aWEgYnVsa1VwZGF0ZVdhbGxldFNoYXJlXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvdXBkYXRlJywgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKCFib2R5LnNoYXJlcyB8fCBib2R5LnNoYXJlcy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc2hhcmUgPSBib2R5LnNoYXJlc1swXTtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgIHNoYXJlLndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgc2hhcmUuc3RhdHVzID09PSAnYWNjZXB0JyAmJlxuICAgICAgICAgICAgICBzaGFyZS5wdWIgPT09IGtleWNoYWluLnB1YiAmJlxuICAgICAgICAgICAgICBzaGFyZS5lbmNyeXB0ZWRQcnYgPT09IGVuY3J5cHRlZFBydlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkIH1dLFxuICAgICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE5vdGU6IGJ1bGtBY2NlcHRTaGFyZSBmaWx0ZXJzIGZvciBzaGFyZXMgV0lUSCBrZXljaGFpbnMsIGJ1dCB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkXG4gICAgICAgIC8vIHNoYXJlcyBkb24ndCBoYXZlIGtleWNoYWlucywgc28gdGhleSBnbyB0aHJvdWdoIGEgZGlmZmVyZW50IHBhdGhcbiAgICAgICAgLy8gV2UgbmVlZCB0byBzdHViIHRoZSBwcm9jZXNzQWNjZXB0U2hhcmUgcGF0aCBvciB1c2UgYnVsa1VwZGF0ZVdhbGxldFNoYXJlIGRpcmVjdGx5XG4gICAgICAgIC8vIEZvciB0aGlzIHRlc3QsIHdlJ2xsIHVzZSBidWxrVXBkYXRlV2FsbGV0U2hhcmUgd2hpY2ggY2FsbHMgcHJvY2Vzc0FjY2VwdFNoYXJlIGludGVybmFsbHlcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb2ZjV2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogdXNlclBhc3N3b3JkLFxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0LmFjY2VwdGVkV2FsbGV0U2hhcmVzLmxlbmd0aCwgMSk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwocmVzdWx0LmFjY2VwdGVkV2FsbGV0U2hhcmVzWzBdLCB7IHdhbGxldFNoYXJlSWQ6ICd0ZXN0X211bHRpX2tleV9idWxrXzEnIH0pO1xuICAgICAgICBzaG91bGQuZXF1YWwoa2V5Y2hhaW5zU3R1Yi5jYWxsZWRPbmNlLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGVuY3J5cHRTdHViLmNhbGxlZFdpdGgoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogdXNlclBhc3N3b3JkIH0pLCB0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBidWxrIGFjY2VwdCBzaGFyZSB3aXRoIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQgYW5kIG5ld1dhbGxldFBhc3NwaHJhc2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9tdWx0aV9rZXlfYnVsa18yJztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmRfMTIzJztcbiAgICAgICAgY29uc3QgbmV3V2FsbGV0UGFzc3BocmFzZSA9ICduZXdfd2FsbGV0X3Bhc3NwaHJhc2VfNDU2JztcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gYSBzaGFyZSB3aXRoIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWRcbiAgICAgICAgc2FuZGJveC5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiBzaGFyZUlkLFxuICAgICAgICAgICAgICBjb2luOiAnb2ZjJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0IHdhbGxldCcsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICd0b1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxMjMnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgLy8gTm8ga2V5Y2hhaW4gLSB0aGlzIGlzIHRoZSBrZXkgZGlmZmVyZW5jZSBmb3IgbXVsdGkta2V5LXVzZXIta2V5IHNoYXJlc1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdEtleWNoYWluID0gYml0Z28uY29pbignb2ZjJykua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBydjogdGVzdEtleWNoYWluLnBydixcbiAgICAgICAgICBwdWI6IHRlc3RLZXljaGFpbi5wdWIsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU2V0IHVwIHN0dWJzIGZpcnN0XG4gICAgICAgIGNvbnN0IGtleWNoYWluc0luc3RhbmNlID0gb2ZjV2FsbGV0cy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zU3R1YiA9IHNhbmRib3guc3R1YihrZXljaGFpbnNJbnN0YW5jZSwgJ2NyZWF0ZScpLnJldHVybnMoa2V5Y2hhaW4pO1xuXG4gICAgICAgIC8vIFNob3VsZCBlbmNyeXB0IHdpdGggbmV3V2FsbGV0UGFzc3BocmFzZSBpZiBwcm92aWRlZCAoYXMgcGVyIGltcGxlbWVudGF0aW9uKVxuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IGtleWNoYWluLnBydiwgcGFzc3dvcmQ6IG5ld1dhbGxldFBhc3NwaHJhc2UgfSk7XG4gICAgICAgIGNvbnN0IGVuY3J5cHRTdHViID0gc2FuZGJveC5zdHViKGJpdGdvLCAnZW5jcnlwdCcpLnJlc29sdmVzKGVuY3J5cHRlZFBydik7XG5cbiAgICAgICAgLy8gTW9jayBidWxrIHVwZGF0ZSBBUEkgLSB0aGlzIGlzIGNhbGxlZCB2aWEgYnVsa1VwZGF0ZVdhbGxldFNoYXJlXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvdXBkYXRlJywgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKCFib2R5LnNoYXJlcyB8fCBib2R5LnNoYXJlcy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc2hhcmUgPSBib2R5LnNoYXJlc1swXTtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgIHNoYXJlLndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgc2hhcmUuc3RhdHVzID09PSAnYWNjZXB0JyAmJlxuICAgICAgICAgICAgICBzaGFyZS5wdWIgPT09IGtleWNoYWluLnB1YiAmJlxuICAgICAgICAgICAgICBzaGFyZS5lbmNyeXB0ZWRQcnYgPT09IGVuY3J5cHRlZFBydlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkIH1dLFxuICAgICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG9mY1dhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHN0YXR1czogJ2FjY2VwdCcgfV0sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHVzZXJQYXNzd29yZCxcbiAgICAgICAgICBuZXdXYWxsZXRQYXNzcGhyYXNlOiBuZXdXYWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0LmFjY2VwdGVkV2FsbGV0U2hhcmVzLmxlbmd0aCwgMSk7XG4gICAgICAgIHNob3VsZC5kZWVwRXF1YWwocmVzdWx0LmFjY2VwdGVkV2FsbGV0U2hhcmVzWzBdLCB7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChrZXljaGFpbnNTdHViLmNhbGxlZE9uY2UsIHRydWUpO1xuICAgICAgICAvLyBWZXJpZnkgZW5jcnlwdCB3YXMgY2FsbGVkIHdpdGggbmV3V2FsbGV0UGFzc3BocmFzZSAobm90IHVzZXJQYXNzd29yZClcbiAgICAgICAgc2hvdWxkLmVxdWFsKGVuY3J5cHRTdHViLmNhbGxlZFdpdGgoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogbmV3V2FsbGV0UGFzc3BocmFzZSB9KSwgdHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIG5laXRoZXIgdXNlckxvZ2luUGFzc3dvcmQgbm9yIG5ld1dhbGxldFBhc3NwaHJhc2UgcHJvdmlkZWQgZm9yIGJ1bGsgYWNjZXB0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfbXVsdGlfa2V5X2J1bGtfMyc7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIGEgc2hhcmUgd2l0aCB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkXG4gICAgICAgIHNhbmRib3guc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogc2hhcmVJZCxcbiAgICAgICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdCB3YWxsZXQnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2Zyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAndG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MTIzJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIHVzZXIgc2V0dGluZ3MgQVBJIGNhbGwgKHJlcXVpcmVkIGJ5IGJ1bGtVcGRhdGVXYWxsZXRTaGFyZSlcbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KCcvYXBpL3YxL3VzZXIvc2V0dGluZ3MnKS5yZXBseSgyMDAsIHt9KTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QgLSB3aGVuIHRoZXJlIGFyZSBlcnJvcnMsIGl0J3MgY2FsbGVkIHdpdGggZW1wdHkgYXJyYXlcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy91cGRhdGUnLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gYm9keS5zaGFyZXMgJiYgYm9keS5zaGFyZXMubGVuZ3RoID09PSAwO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZSB1c2VzIFByb21pc2UuYWxsU2V0dGxlZCwgc28gZXJyb3JzIGFyZSBjYXVnaHQgYW5kIHJldHVybmVkIGluIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzXG4gICAgICAgIC8vIFdlIG5lZWQgdG8gY2hlY2sgdGhlIHJlc3VsdCBmb3IgZXJyb3JzIGluc3RlYWQgb2YgZXhwZWN0aW5nIGEgcmVqZWN0aW9uXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG9mY1dhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHN0YXR1czogJ2FjY2VwdCcgfV0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGF0IHRoZSBlcnJvciB3YXMgY2FwdHVyZWQgaW4gd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnNcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc3VsdC53YWxsZXRTaGFyZVVwZGF0ZUVycm9ycy5sZW5ndGgsIDEpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0LndhbGxldFNoYXJlVXBkYXRlRXJyb3JzWzBdLndhbGxldFNoYXJlSWQsIHNoYXJlSWQpO1xuICAgICAgICBzaG91bGQocmVzdWx0LndhbGxldFNoYXJlVXBkYXRlRXJyb3JzWzBdLnJlYXNvbikuY29udGFpbkVxbChcbiAgICAgICAgICAndXNlckxvZ2luUGFzc3dvcmQgcGFyYW0gbXVzdCBiZSBwcm92aWRlZCB0byBnZW5lcmF0ZSB1c2VyIGtleWNoYWluJ1xuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgd29yayB3aXRoIG5ld1dhbGxldFBhc3NwaHJhc2UgcGFyYW1ldGVyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfbXVsdGlfa2V5XzQnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZF8xMjMnO1xuICAgICAgICBjb25zdCBuZXdXYWxsZXRQYXNzcGhyYXNlID0gJ25ld193YWxsZXRfcGFzc3BocmFzZV80NTYnO1xuICAgICAgICBjb25zdCB3YWxsZXRJZCA9ICd0ZXN0X3dhbGxldF8xMjMnO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi9vZmMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0SWQsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdGVzdEtleWNoYWluID0gYml0Z28uY29pbignb2ZjJykua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBydjogdGVzdEtleWNoYWluLnBydixcbiAgICAgICAgICBwdWI6IHRlc3RLZXljaGFpbi5wdWIsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gU3R1YiBjcmVhdGUoKSBhbmQgZW5jcnlwdCgpIEJFRk9SRSBjYWxjdWxhdGluZyBlbmNyeXB0ZWRQcnYgdG8gZW5zdXJlIGNvbnNpc3RlbmN5XG4gICAgICAgIGNvbnN0IGtleWNoYWluc0luc3RhbmNlID0gb2ZjV2FsbGV0cy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICAgICAgc2FuZGJveC5zdHViKGtleWNoYWluc0luc3RhbmNlLCAnY3JlYXRlJykucmV0dXJucyhrZXljaGFpbik7XG5cbiAgICAgICAgLy8gU2hvdWxkIGVuY3J5cHQgd2l0aCBuZXdXYWxsZXRQYXNzcGhyYXNlIGlmIHByb3ZpZGVkIChhcyBwZXIgaW1wbGVtZW50YXRpb24pXG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogbmV3V2FsbGV0UGFzc3BocmFzZSB9KTtcbiAgICAgICAgY29uc3QgZW5jcnlwdFN0dWIgPSBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXMoZW5jcnlwdGVkUHJ2KTtcblxuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgYm9keS53YWxsZXRTaGFyZUlkID09PSBzaGFyZUlkICYmXG4gICAgICAgICAgICAgIGJvZHkuc3RhdGUgPT09ICdhY2NlcHRlZCcgJiZcbiAgICAgICAgICAgICAgYm9keS5wdWIgPT09IGtleWNoYWluLnB1YiAmJlxuICAgICAgICAgICAgICBib2R5LmVuY3J5cHRlZFBydiA9PT0gZW5jcnlwdGVkUHJ2XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBvZmNXYWxsZXRzLmFjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLFxuICAgICAgICAgIHVzZXJQYXNzd29yZCxcbiAgICAgICAgICBuZXdXYWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXF1YWwocmVzLmNoYW5nZWQsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLnN0YXRlLCAnYWNjZXB0ZWQnKTtcbiAgICAgICAgLy8gVmVyaWZ5IGVuY3J5cHQgd2FzIGNhbGxlZCB3aXRoIG5ld1dhbGxldFBhc3NwaHJhc2VcbiAgICAgICAgc2hvdWxkLmVxdWFsKGVuY3J5cHRTdHViLmNhbGxlZFdpdGgoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogbmV3V2FsbGV0UGFzc3BocmFzZSB9KSwgdHJ1ZSk7XG5cbiAgICAgICAgd2FsbGV0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgICAgYWNjZXB0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHByaW9yaXRpemUgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZCBvdmVyIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV81JztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmRfMTIzJztcbiAgICAgICAgY29uc3Qgd2FsbGV0SWQgPSAndGVzdF93YWxsZXRfMTIzJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsIC8vIEJvdGggc2V0LCBidXQgdXNlck11bHRpS2V5Um90YXRpb25SZXF1aXJlZCBzaG91bGQgdGFrZSBwcmVjZWRlbmNlXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldElkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlc3RLZXljaGFpbiA9IGJpdGdvLmNvaW4oJ29mYycpLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwcnY6IHRlc3RLZXljaGFpbi5wcnYsXG4gICAgICAgICAgcHViOiB0ZXN0S2V5Y2hhaW4ucHViLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFNldCB1cCBzdHVicyBmaXJzdFxuICAgICAgICBjb25zdCBrZXljaGFpbnNJbnN0YW5jZSA9IG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG4gICAgICAgIHNhbmRib3guc3R1YihrZXljaGFpbnNJbnN0YW5jZSwgJ2NyZWF0ZScpLnJldHVybnMoa2V5Y2hhaW4pO1xuXG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXMoZW5jcnlwdGVkUHJ2KTtcblxuICAgICAgICAvLyBTaG91bGQgdXNlIHRoZSBtdWx0aS1rZXktdXNlci1rZXkgZmxvdyAobm8gc2lnbmF0dXJlL3BheWxvYWQva2V5SWQpXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gLCAoYm9keTogYW55KSA9PiB7XG4gICAgICAgICAgICAvLyBWZXJpZnkgaXQncyB1c2luZyBtdWx0aS1rZXktdXNlci1rZXkgZmxvdyAoaGFzIHB1YiBhbmQgZW5jcnlwdGVkUHJ2LCBidXQgbm8gc2lnbmF0dXJlL3BheWxvYWQva2V5SWQpXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICBib2R5LndhbGxldFNoYXJlSWQgPT09IHNoYXJlSWQgJiZcbiAgICAgICAgICAgICAgYm9keS5zdGF0ZSA9PT0gJ2FjY2VwdGVkJyAmJlxuICAgICAgICAgICAgICBib2R5LnB1YiA9PT0ga2V5Y2hhaW4ucHViICYmXG4gICAgICAgICAgICAgIGJvZHkuZW5jcnlwdGVkUHJ2ID09PSBlbmNyeXB0ZWRQcnYgJiZcbiAgICAgICAgICAgICAgIWJvZHkuc2lnbmF0dXJlICYmXG4gICAgICAgICAgICAgICFib2R5LnBheWxvYWQgJiZcbiAgICAgICAgICAgICAgIWJvZHkua2V5SWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pO1xuICAgICAgICBjb25zdCByZXNoYXJlU3R1YiA9IHNhbmRib3guc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ3Jlc2hhcmVXYWxsZXRXaXRoU3BlbmRlcnMnKTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBvZmNXYWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuc3RhdGUsICdhY2NlcHRlZCcpO1xuICAgICAgICAvLyBWZXJpZnkgcmVzaGFyZSB3YXMgTk9UIGNhbGxlZCAobXVsdGkta2V5LXVzZXIta2V5IGZsb3cpXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXNoYXJlU3R1Yi5jYWxsZWQsIGZhbHNlKTtcblxuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICBhY2NlcHRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGtleWNoYWluIGNyZWF0aW9uIGZhaWx1cmUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9tdWx0aV9rZXlfNic7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkXzEyMyc7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGtleWNoYWluRXJyb3IgPSBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBjcmVhdGUga2V5Y2hhaW4nKTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zSW5zdGFuY2UgPSBvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgICAgICBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zSW5zdGFuY2UsICdjcmVhdGUnKS50aHJvd3Moa2V5Y2hhaW5FcnJvcik7XG5cbiAgICAgICAgYXdhaXQgb2ZjV2FsbGV0c1xuICAgICAgICAgIC5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdGYWlsZWQgdG8gY3JlYXRlIGtleWNoYWluJyk7XG5cbiAgICAgICAgd2FsbGV0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBlbmNyeXB0aW9uIGZhaWx1cmUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9tdWx0aV9rZXlfNyc7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkXzEyMyc7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlc3RLZXljaGFpbiA9IGJpdGdvLmNvaW4oJ29mYycpLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwcnY6IHRlc3RLZXljaGFpbi5wcnYsXG4gICAgICAgICAgcHViOiB0ZXN0S2V5Y2hhaW4ucHViLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGtleWNoYWluc0luc3RhbmNlID0gb2ZjV2FsbGV0cy5iYXNlQ29pbi5rZXljaGFpbnMoKTtcbiAgICAgICAgc2FuZGJveC5zdHViKGtleWNoYWluc0luc3RhbmNlLCAnY3JlYXRlJykucmV0dXJucyhrZXljaGFpbik7XG4gICAgICAgIGNvbnN0IGVuY3J5cHRpb25FcnJvciA9IG5ldyBFcnJvcignRW5jcnlwdGlvbiBmYWlsZWQnKTtcbiAgICAgICAgc2FuZGJveC5zdHViKGJpdGdvLCAnZW5jcnlwdCcpLnRocm93cyhlbmNyeXB0aW9uRXJyb3IpO1xuXG4gICAgICAgIGF3YWl0IG9mY1dhbGxldHNcbiAgICAgICAgICAuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnRW5jcnlwdGlvbiBmYWlsZWQnKTtcblxuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgd29yayB3aXRoIHZpZXctb25seSBwZXJtaXNzaW9ucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X211bHRpX2tleV84JztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3Rlc3RfcGFzc3dvcmRfMTIzJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvb2ZjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVzZXJNdWx0aUtleVJvdGF0aW9uUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3J10sIC8vIFZpZXctb25seSBwZXJtaXNzaW9uc1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHRlc3RLZXljaGFpbiA9IGJpdGdvLmNvaW4oJ29mYycpLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwcnY6IHRlc3RLZXljaGFpbi5wcnYsXG4gICAgICAgICAgcHViOiB0ZXN0S2V5Y2hhaW4ucHViLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFNldCB1cCBzdHVicyBmaXJzdFxuICAgICAgICBjb25zdCBrZXljaGFpbnNJbnN0YW5jZSA9IG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG4gICAgICAgIHNhbmRib3guc3R1YihrZXljaGFpbnNJbnN0YW5jZSwgJ2NyZWF0ZScpLnJldHVybnMoa2V5Y2hhaW4pO1xuXG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDoga2V5Y2hhaW4ucHJ2LCBwYXNzd29yZDogdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzYW5kYm94LnN0dWIoYml0Z28sICdlbmNyeXB0JykucmVzb2x2ZXMoZW5jcnlwdGVkUHJ2KTtcblxuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgYm9keS53YWxsZXRTaGFyZUlkID09PSBzaGFyZUlkICYmXG4gICAgICAgICAgICAgIGJvZHkuc3RhdGUgPT09ICdhY2NlcHRlZCcgJiZcbiAgICAgICAgICAgICAgYm9keS5wdWIgPT09IGtleWNoYWluLnB1YiAmJlxuICAgICAgICAgICAgICBib2R5LmVuY3J5cHRlZFBydiA9PT0gZW5jcnlwdGVkUHJ2XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBvZmNXYWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuc3RhdGUsICdhY2NlcHRlZCcpO1xuXG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB2ZXJpZnkgZXhhY3QgdmFsdWVzIHNlbnQgaW4gQVBJIHJlcXVlc3QnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9tdWx0aV9rZXlfOSc7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkXzEyMyc7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Rlc3Rfd2FsbGV0XzEyMyc7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1c2VyTXVsdGlLZXlSb3RhdGlvblJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXRJZCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0ZXN0S2V5Y2hhaW4gPSBiaXRnby5jb2luKCdvZmMnKS5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7XG4gICAgICAgICAgcHJ2OiB0ZXN0S2V5Y2hhaW4ucHJ2LFxuICAgICAgICAgIHB1YjogdGVzdEtleWNoYWluLnB1YixcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTZXQgdXAgc3R1YnMgZmlyc3RcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5zSW5zdGFuY2UgPSBvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpO1xuICAgICAgICBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zSW5zdGFuY2UsICdjcmVhdGUnKS5yZXR1cm5zKGtleWNoYWluKTtcblxuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IGtleWNoYWluLnBydiwgcGFzc3dvcmQ6IHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgc2FuZGJveC5zdHViKGJpdGdvLCAnZW5jcnlwdCcpLnJlc29sdmVzKGVuY3J5cHRlZFBydik7XG5cbiAgICAgICAgbGV0IGNhcHR1cmVkQm9keTogYW55O1xuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL29mYy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgY2FwdHVyZWRCb2R5ID0gYm9keTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBhd2FpdCBvZmNXYWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSBleGFjdCB2YWx1ZXNcbiAgICAgICAgc2hvdWxkLmVxdWFsKGNhcHR1cmVkQm9keS53YWxsZXRTaGFyZUlkLCBzaGFyZUlkKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGNhcHR1cmVkQm9keS5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG4gICAgICAgIHNob3VsZC5lcXVhbChjYXB0dXJlZEJvZHkucHViLCBrZXljaGFpbi5wdWIpO1xuICAgICAgICBzaG91bGQuZXF1YWwoY2FwdHVyZWRCb2R5LmVuY3J5cHRlZFBydiwgZW5jcnlwdGVkUHJ2KTtcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChjYXB0dXJlZEJvZHkuc2lnbmF0dXJlKTtcbiAgICAgICAgc2hvdWxkLm5vdC5leGlzdChjYXB0dXJlZEJvZHkucGF5bG9hZCk7XG4gICAgICAgIHNob3VsZC5ub3QuZXhpc3QoY2FwdHVyZWRCb2R5LmtleUlkKTtcblxuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICBhY2NlcHRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNoYXJlIGEgd2FsbGV0IHRvIHZpZXdlcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNoYXJlSWQgPSAnMTIzMTEnO1xuXG4gICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCkucmVwbHkoMjAwLCB7fSk7XG4gICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChgL2FwaS92Mi90YnRjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gLCB7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHN0YXRlOiAnYWNjZXB0ZWQnIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcblxuICAgICAgYXdhaXQgd2FsbGV0cy5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfSk7XG4gICAgICBhY2NlcHRTaGFyZU5vY2suZG9uZSgpO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3YyIGVudmVsb3BlIHN1cHBvcnQgaW4gYWNjZXB0U2hhcmUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgYWZ0ZXJFYWNoKCgpID0+IHNhbmRib3gudmVyaWZ5QW5kUmVzdG9yZSgpKTtcblxuICAgICAgaXQoJ3Nob3VsZCBhY2NlcHQgc2hhcmUgd2hlbiBFQ0RIIHNoYXJpbmcga2V5Y2hhaW4gZW5jcnlwdGVkWHBydiBpcyB2Mi1lbmNyeXB0ZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndjItZWNkaC14cHJ2LTEnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9wYXNzd29yZCc7XG5cbiAgICAgICAgLy8gU2ltdWxhdGUgYSB2MiBlbnZlbG9wZSBmb3IgdGhlIEVDREggcm9vdCBrZXlcbiAgICAgICAgY29uc3QgdjJFbmNyeXB0ZWRYcHJ2ID0gSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBpdjogJ2FhYmJjYycsIGN0OiAnZGRlZWZmJywgYWRhdGE6ICcwMCcgfSk7XG4gICAgICAgIGNvbnN0IGZha2VYcHJ2ID0gJ3hwcnZTb21lQmFzZTU4VmFsdWUnO1xuICAgICAgICBjb25zdCBmYWtlU2VjcmV0ID0gJ2Zha2VFY2RoU2hhcmVkU2VjcmV0JztcbiAgICAgICAgY29uc3QgZGVjcnlwdGVkV2FsbGV0UHJ2ID0gJ3dhbGxldFByaXZLZXlQbGFpbnRleHQnO1xuXG4gICAgICAgIGNvbnN0IGVja2V5ID0gbWFrZVJhbmRvbUtleSgpO1xuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogZmFrZVNlY3JldCwgaW5wdXQ6IGRlY3J5cHRlZFdhbGxldFBydiB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICBwYXRoOiAnbS8wLzAvMScsXG4gICAgICAgICAgICAgIGZyb21QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICAgIHRvUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IHYyRW5jcnlwdGVkUHJ2LFxuICAgICAgICAgICAgICBwdWI6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICBub2NrKGJnVXJsKS5wb3N0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBzYW5kYm94LnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7IGVuY3J5cHRlZFhwcnY6IHYyRW5jcnlwdGVkWHBydiB9KTtcbiAgICAgICAgY29uc3QgZGVjcnlwdEFzeW5jU3R1YiA9IHNhbmRib3guc3R1YihiaXRnbywgJ2RlY3J5cHQnKTtcbiAgICAgICAgLy8gRmlyc3QgY2FsbCBkZWNyeXB0cyB0aGUgRUNESCBrZXljaGFpbiAodjIpLCBzZWNvbmQgZGVjcnlwdHMgdGhlIHNoYXJlZCB3YWxsZXQgcHJ2XG4gICAgICAgIGRlY3J5cHRBc3luY1N0dWIub25GaXJzdENhbGwoKS5yZXNvbHZlcyhmYWtlWHBydik7XG4gICAgICAgIGRlY3J5cHRBc3luY1N0dWIub25TZWNvbmRDYWxsKCkucmVzb2x2ZXMoZGVjcnlwdGVkV2FsbGV0UHJ2KTtcbiAgICAgICAgc2FuZGJveC5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmV0dXJucyhCdWZmZXIuZnJvbShmYWtlU2VjcmV0KSk7XG5cbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgd2FsbGV0cy5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG4gICAgICAgIC8vIE11c3QgaGF2ZSBjYWxsZWQgZGVjcnlwdCAobm90IHRoZSBzeW5jIGRlY3J5cHQpIGZvciBib3RoIHRoZSBFQ0RIIGtleSBhbmQgdGhlIHdhbGxldCBwcnZcbiAgICAgICAgYXNzZXJ0LmVxdWFsKGRlY3J5cHRBc3luY1N0dWIuY2FsbENvdW50LCAyKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGFjY2VwdCBzaGFyZSB3aGVuIHdhbGxldCBrZXljaGFpbiBlbmNyeXB0ZWRQcnYgaXMgdjItZW5jcnlwdGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3YyLXdhbGxldC1wcnYtMSc7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X3Bhc3N3b3JkJztcblxuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFhwcnYgPSBKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGl2OiAnYWFiYmNjJywgY3Q6ICdkZGVlZmYnLCBhZGF0YTogJzAwJyB9KTtcbiAgICAgICAgY29uc3QgZmFrZVhwcnYgPSAneHBydkFub3RoZXJLZXknO1xuICAgICAgICBjb25zdCBmYWtlU2VjcmV0ID0gJ2VjZGhTaGFyZWRTZWNyZXQyJztcbiAgICAgICAgY29uc3QgZGVjcnlwdGVkV2FsbGV0UHJ2ID0gJ3dhbGxldFByaXZLZXkyJztcbiAgICAgICAgY29uc3QgdjJFbmNyeXB0ZWRQcnYgPSBKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGl2OiAnMTEyMjMzJywgY3Q6ICc0NDU1NjYnLCBhZGF0YTogJzc3JyB9KTtcbiAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgcGF0aDogJ20vMC8wLzInLFxuICAgICAgICAgICAgICBmcm9tUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgICB0b1B1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiB2MkVuY3J5cHRlZFBydixcbiAgICAgICAgICAgICAgcHViOiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgbm9jayhiZ1VybCkucG9zdChgL2FwaS92Mi90YnRjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKS5yZXBseSgyMDAsIHsgY2hhbmdlZDogdHJ1ZSwgc3RhdGU6ICdhY2NlcHRlZCcgfSk7XG5cbiAgICAgICAgc2FuZGJveC5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoeyBlbmNyeXB0ZWRYcHJ2OiB2MkVuY3J5cHRlZFhwcnYgfSk7XG4gICAgICAgIGNvbnN0IGRlY3J5cHRBc3luY1N0dWIgPSBzYW5kYm94LnN0dWIoYml0Z28sICdkZWNyeXB0Jyk7XG4gICAgICAgIGRlY3J5cHRBc3luY1N0dWIub25GaXJzdENhbGwoKS5yZXNvbHZlcyhmYWtlWHBydik7XG4gICAgICAgIGRlY3J5cHRBc3luY1N0dWIub25TZWNvbmRDYWxsKCkucmVzb2x2ZXMoZGVjcnlwdGVkV2FsbGV0UHJ2KTtcbiAgICAgICAgc2FuZGJveC5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmV0dXJucyhCdWZmZXIuZnJvbShmYWtlU2VjcmV0KSk7XG5cbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgd2FsbGV0cy5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHVzZXJQYXNzd29yZCB9KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5jaGFuZ2VkLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlcy5zdGF0ZSwgJ2FjY2VwdGVkJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdidWxrQWNjZXB0U2hhcmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICAgIG5vY2sucGVuZGluZ01vY2tzKCkubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgICAgc2lub24ucmVzdG9yZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3IgdXNlclBhc3N3b3JkIGVtcHR5IHN0cmluZycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrQWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkczogW10sIHVzZXJMb2dpblBhc3N3b3JkOiAnJyB9KVxuICAgICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdQbGVhc2UgcHJvdmlkZSBhIHZhbGlkIHVzZXIgbG9naW4gcGFzc3dvcmQnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHZhbGlkYXRpb24gZXJyb3IgZm9yIHNlbmRpbmcgd2FsbGV0UGFzc3BocmFzZSBlbXB0eSBzdHJpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa0FjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZHM6IFtdLCB1c2VyTG9naW5QYXNzd29yZDogJ3Bhc3N3b3JkJywgbmV3V2FsbGV0UGFzc3BocmFzZTogMTIzIH0pXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ1BsZWFzZSBwcm92aWRlIGEgdmFsaWQgd2FsbGV0IHBhc3NwaHJhc2UnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGFzc2VydGlvbiBlcnJvciBmb3IgZW1wdHkgd2FsbGV0U2hhcmVJZHMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa0FjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZHM6IFtdLCB1c2VyTG9naW5QYXNzd29yZDogJ2R1bW15QDEyMycgfSlcbiAgICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnUGxlYXNlIHByb3ZpZGUgYXQgbGVhc3Qgb25lIHdhbGxldCBzaGFyZSB0byBhY2NlcHQnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBubyB2YWxpZCB3YWxsZXQgc2hhcmVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnZHVtbXlXYWxsZXRJZCcsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkczogWyc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkMSddLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ05vIHZhbGlkIHdhbGxldCBzaGFyZXMgZm91bmQgdG8gYWNjZXB0Jyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3Igbm8gdmFsaWQgd2FsbGV0U2hhcmVzIHdpdGgga2V5Y2hhaW4nLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICdkdW1teVdhbGxldElkJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrQWNjZXB0U2hhcmUoe1xuICAgICAgICAgICAgd2FsbGV0U2hhcmVJZHM6IFsnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnXSxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiAnZHVtbXlAMTIzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdObyB2YWxpZCB3YWxsZXQgc2hhcmVzIGZvdW5kIHRvIGFjY2VwdCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGVjZGgga2V5Y2hhaW4gdW5kZWZpbmVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnZHVtbXlXYWxsZXRJZCcsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgICBwdWI6ICdwdWInLFxuICAgICAgICAgICAgICAgIHRvUHViS2V5OiAndG9QdWJLZXknLFxuICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6ICdmcm9tUHViS2V5JyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgICAgIHBhdGg6ICdwYXRoJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIHBydjogJ3ByaXZhdGUga2V5JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrQWNjZXB0U2hhcmUoe1xuICAgICAgICAgICAgd2FsbGV0U2hhcmVJZHM6IFsnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnXSxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiAnZHVtbXlAMTIzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdlbmNyeXB0ZWRYcHJ2IHdhcyBub3QgZm91bmQgb24gc2hhcmluZyBrZXljaGFpbicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3VjY2Vzc2Z1bGx5IGFjY2VwdCBzaGFyZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgZnJvbVVzZXJQcnYgPSBNYXRoLnJhbmRvbSgpO1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZnJvbVVzZXJQcnYudG9TdHJpbmcoKSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQcnYgPSBhd2FpdCBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5KGJpdGdvLCBrZXljaGFpblRlc3QsIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZWNyeXB0IHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcbiAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICBjb25zdCBuZXdFbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHNlY3JldCwgaW5wdXQ6IHVzZXJQcnYgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaS92Mi93YWxsZXRzaGFyZXMnKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JyxcbiAgICAgICAgICAgICAgICBpc1VNU0luaXRpYXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IG5ld0VuY3J5cHRlZFBydixcbiAgICAgICAgICAgICAgICAgIHRvUHViS2V5OiBwdWJrZXksXG4gICAgICAgICAgICAgICAgICBwdWI6IHB1YmtleSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB3YWxsZXRTaGFyZUlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBteUVjZGhLZXljaGFpbiA9IGF3YWl0IGJpdGdvLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHBydktleSA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoe1xuICAgICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGlucHV0OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcyhwcnZLZXkpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICBjb25zdCBzaGFyZSA9IGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogWyc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCddLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChzaGFyZSwge1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHdhbGxldFNoYXJlSWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgYWNjZXB0IHNoYXJlIHdoZW4gRUNESCBzaGFyaW5nIGtleWNoYWluIGlzIHYyLWVuY3J5cHRlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JztcblxuICAgICAgICBjb25zdCB0b0tleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMicsICdoZXgnKSk7XG4gICAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcbiAgICAgICAgY29uc3QgcHVia2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IGVja2V5ID0gbWFrZVJhbmRvbUtleSgpO1xuICAgICAgICBjb25zdCBzZWNyZXQgPSBnZXRTaGFyZWRTZWNyZXQoZWNrZXksIEJ1ZmZlci5mcm9tKHB1YmtleSwgJ2hleCcpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IGRlY3J5cHRlZFBydiA9ICdzb21lV2FsbGV0UHJpdmF0ZUtleSc7XG4gICAgICAgIGNvbnN0IG5ld0VuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogc2VjcmV0LCBpbnB1dDogZGVjcnlwdGVkUHJ2IH0pO1xuXG4gICAgICAgIC8vIFNpbXVsYXRlIHYyLWVuY3J5cHRlZCBFQ0RIIGtleWNoYWluIHhwcnYgKGVudmVsb3BlIHdpdGggdjoyIG1hcmtlcilcbiAgICAgICAgY29uc3QgdjJFbmNyeXB0ZWRYcHJ2ID0gSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBpdjogJ2FhYScsIGN0OiAnYmJiJywgYWRhdGE6ICdjY2MnIH0pO1xuICAgICAgICBjb25zdCBteUVjZGhYcHJ2ID0gJ3hwcnZTb21lQmFzZTU4S2V5JztcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzJylcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6IHNoYXJlSWQsXG4gICAgICAgICAgICAgICAgaXNVTVNJbml0aWF0ZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICAgICAgICBmcm9tUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBuZXdFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICAgICAgICB0b1B1YktleTogcHVia2V5LFxuICAgICAgICAgICAgICAgICAgcHViOiBwdWJrZXksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JylcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkIH1dIH0pO1xuXG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7IGVuY3J5cHRlZFhwcnY6IHYyRW5jcnlwdGVkWHBydiB9KTtcbiAgICAgICAgLy8gZGVjcnlwdCByZXNvbHZlcyB3aXRoIHRoZSB4cHJ2IHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgZW52ZWxvcGUgaXMgdjEgb3IgdjJcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcyhteUVjZGhYcHJ2KTtcbiAgICAgICAgc2lub24uc3R1Yihtb2R1bGVCaXRnbywgJ2dldFNoYXJlZFNlY3JldCcpLnJlc29sdmVzKCdmYWtlU2hhcmVkU2VjcmV0Jyk7XG5cbiAgICAgICAgY29uc3Qgc2hhcmUgPSBhd2FpdCB3YWxsZXRzLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0U2hhcmVJZHM6IFtzaGFyZUlkXSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoc2hhcmUsIHsgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfV0gfSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBhY2NlcHQgc2hhcmUgd2hlbiB3YWxsZXQga2V5Y2hhaW4gZW5jcnlwdGVkUHJ2IGlzIHYyLWVuY3J5cHRlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3YyLXBydi1zaGFyZS0xJztcblxuICAgICAgICBjb25zdCB0b0tleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMicsICdoZXgnKSk7XG4gICAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcbiAgICAgICAgY29uc3QgcHVia2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IGVja2V5ID0gbWFrZVJhbmRvbUtleSgpO1xuXG4gICAgICAgIC8vIFNpbXVsYXRlIHYyLWVuY3J5cHRlZCBlbmNyeXB0ZWRQcnYgaW4gdGhlIHdhbGxldCBzaGFyZSBrZXljaGFpblxuICAgICAgICBjb25zdCB2MkVuY3J5cHRlZFBydiA9IEpTT04uc3RyaW5naWZ5KHsgdjogMiwgaXY6ICd4eHgnLCBjdDogJ3l5eScsIGFkYXRhOiAnenp6JyB9KTtcbiAgICAgICAgY29uc3QgdjJFbmNyeXB0ZWRYcHJ2ID0gSlNPTi5zdHJpbmdpZnkoeyB2OiAyLCBpdjogJ2FhYScsIGN0OiAnYmJiJywgYWRhdGE6ICdjY2MnIH0pO1xuICAgICAgICBjb25zdCBteUVjZGhYcHJ2ID0gJ3hwcnZTb21lQmFzZTU4S2V5JztcbiAgICAgICAgY29uc3QgZGVjcnlwdGVkV2FsbGV0UHJ2ID0gJ2RlY3J5cHRlZFdhbGxldFByaXZLZXknO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldCgnL2FwaS92Mi93YWxsZXRzaGFyZXMnKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogc2hhcmVJZCxcbiAgICAgICAgICAgICAgICBpc1VNU0luaXRpYXRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IHYyRW5jcnlwdGVkUHJ2LFxuICAgICAgICAgICAgICAgICAgdG9QdWJLZXk6IHB1YmtleSxcbiAgICAgICAgICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wdXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzL2FjY2VwdCcpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBhY2NlcHRlZFdhbGxldFNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCB9XSB9KTtcblxuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoeyBlbmNyeXB0ZWRYcHJ2OiB2MkVuY3J5cHRlZFhwcnYgfSk7XG4gICAgICAgIC8vIEZpcnN0IGNhbGw6IGRlY3J5cHQgRUNESCBrZXljaGFpbiB4cHJ2OyBzZWNvbmQgY2FsbDogZGVjcnlwdCB2MiB3YWxsZXQgc2hhcmUgcHJ2XG4gICAgICAgIGNvbnN0IGRlY3J5cHRBc3luY1N0dWIgPSBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpO1xuICAgICAgICBkZWNyeXB0QXN5bmNTdHViLm9uRmlyc3RDYWxsKCkucmVzb2x2ZXMobXlFY2RoWHBydik7XG4gICAgICAgIGRlY3J5cHRBc3luY1N0dWIub25TZWNvbmRDYWxsKCkucmVzb2x2ZXMoZGVjcnlwdGVkV2FsbGV0UHJ2KTtcbiAgICAgICAgc2lub24uc3R1Yihtb2R1bGVCaXRnbywgJ2dldFNoYXJlZFNlY3JldCcpLnJlc29sdmVzKCdmYWtlU2hhcmVkU2VjcmV0Jyk7XG5cbiAgICAgICAgY29uc3Qgc2hhcmUgPSBhd2FpdCB3YWxsZXRzLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0U2hhcmVJZHM6IFtzaGFyZUlkXSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoc2hhcmUsIHsgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfV0gfSk7XG4gICAgICAgIC8vIEJvdGggZGVjcnlwdCBjYWxscyBtdXN0IHVzZSBkZWNyeXB0IChub3QgdGhlIHN5bmMgZGVjcnlwdClcbiAgICAgICAgYXNzZXJ0LmVxdWFsKGRlY3J5cHRBc3luY1N0dWIuY2FsbENvdW50LCAyKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGluY2x1ZGUgd2ViYXV0aG5JbmZvIGluIHJlcXVlc3Qgd2hlbiBwcm92aWRlZCAoRUNESCBicmFuY2gpJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBmcm9tVXNlclBydiA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3Qgd2ViYXV0aG5QYXNzcGhyYXNlID0gJ3ByZi1kZXJpdmVkLXNlY3JldCc7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnO1xuICAgICAgICBjb25zdCBrZXljaGFpblRlc3Q6IE9wdGlvbmFsS2V5Y2hhaW5FbmNyeXB0ZWRLZXkgPSB7XG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IGZyb21Vc2VyUHJ2LnRvU3RyaW5nKCksIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB1c2VyUHJ2ID0gYXdhaXQgZGVjcnlwdEtleWNoYWluUHJpdmF0ZUtleShiaXRnbywga2V5Y2hhaW5UZXN0LCB3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgICAgaWYgKCF1c2VyUHJ2KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZGVjcnlwdCB1c2VyIGtleWNoYWluJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0b0tleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMicsICdoZXgnKSk7XG4gICAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcbiAgICAgICAgY29uc3QgcHVia2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG4gICAgICAgIGNvbnN0IHNlY3JldCA9IGdldFNoYXJlZFNlY3JldChlY2tleSwgQnVmZmVyLmZyb20ocHVia2V5LCAnaGV4JykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgbmV3RW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IHBhc3N3b3JkOiBzZWNyZXQsIGlucHV0OiB1c2VyUHJ2IH0pO1xuXG4gICAgICAgIGxldCBjYXB0dXJlZEJvZHk6IGFueTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3dhbGxldHNoYXJlcycpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlkOiBzaGFyZUlkLFxuICAgICAgICAgICAgICAgIGlzVU1TSW5pdGlhdGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogbmV3RW5jcnlwdGVkUHJ2LFxuICAgICAgICAgICAgICAgICAgdG9QdWJLZXk6IHB1YmtleSxcbiAgICAgICAgICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wdXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzL2FjY2VwdCcsIChib2R5KSA9PiB7XG4gICAgICAgICAgICBjYXB0dXJlZEJvZHkgPSBib2R5O1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCB9XSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBteUVjZGhLZXljaGFpbiA9IGF3YWl0IGJpdGdvLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHBydktleSA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoe1xuICAgICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGlucHV0OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcyhwcnZLZXkpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRzLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0U2hhcmVJZHM6IFtzaGFyZUlkXSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICB3ZWJhdXRobkluZm86IHtcbiAgICAgICAgICAgIG90cERldmljZUlkOiAnZGV2aWNlLTAwMScsXG4gICAgICAgICAgICBwcmZTYWx0OiAnc2FsdC1hYmMnLFxuICAgICAgICAgICAgcGFzc3BocmFzZTogd2ViYXV0aG5QYXNzcGhyYXNlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHNlbnRFbnRyaWVzID0gY2FwdHVyZWRCb2R5LmtleXNGb3JXYWxsZXRTaGFyZXM7XG4gICAgICAgIHNlbnRFbnRyaWVzLnNob3VsZC5oYXZlLmxlbmd0aCgxKTtcbiAgICAgICAgc2VudEVudHJpZXNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicpO1xuICAgICAgICBzZW50RW50cmllc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2ViYXV0aG5JbmZvJyk7XG4gICAgICAgIHNlbnRFbnRyaWVzWzBdLndlYmF1dGhuSW5mby5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnb3RwRGV2aWNlSWQnLCAnZGV2aWNlLTAwMScpO1xuICAgICAgICBzZW50RW50cmllc1swXS53ZWJhdXRobkluZm8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3ByZlNhbHQnLCAnc2FsdC1hYmMnKTtcbiAgICAgICAgc2VudEVudHJpZXNbMF0ud2ViYXV0aG5JbmZvLnNob3VsZC5oYXZlLnByb3BlcnR5KCdlbmNyeXB0ZWRQcnYnKTtcbiAgICAgICAgc2VudEVudHJpZXNbMF0ud2ViYXV0aG5JbmZvLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgncGFzc3BocmFzZScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgTk9UIGluY2x1ZGUgd2ViYXV0aG5JbmZvIHdoZW4gbm90IHByb3ZpZGVkIChiYWNrd2FyZCBjb21wYXQpJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBmcm9tVXNlclBydiA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCc7XG4gICAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZnJvbVVzZXJQcnYudG9TdHJpbmcoKSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQcnYgPSBhd2FpdCBkZWNyeXB0S2V5Y2hhaW5Qcml2YXRlS2V5KGJpdGdvLCBrZXljaGFpblRlc3QsIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBpZiAoIXVzZXJQcnYpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBkZWNyeXB0IHVzZXIga2V5Y2hhaW4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICBjb25zdCBwdWJrZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBlY2tleSA9IG1ha2VSYW5kb21LZXkoKTtcbiAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICBjb25zdCBuZXdFbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHNlY3JldCwgaW5wdXQ6IHVzZXJQcnYgfSk7XG5cbiAgICAgICAgbGV0IGNhcHR1cmVkQm9keTogYW55O1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzJylcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6IHNoYXJlSWQsXG4gICAgICAgICAgICAgICAgaXNVTVNJbml0aWF0ZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgICBmcm9tUHViS2V5OiBlY2tleS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBuZXdFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICAgICAgICB0b1B1YktleTogcHVia2V5LFxuICAgICAgICAgICAgICAgICAgcHViOiBwdWJrZXksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JywgKGJvZHkpID0+IHtcbiAgICAgICAgICAgIGNhcHR1cmVkQm9keSA9IGJvZHk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkIH1dLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IG15RWNkaEtleWNoYWluID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgZW5jcnlwdGVkWHBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBteUVjZGhLZXljaGFpbi54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHBydktleSA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoe1xuICAgICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGlucHV0OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcyhwcnZLZXkpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRzLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0U2hhcmVJZHM6IFtzaGFyZUlkXSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc2VudEVudHJpZXMgPSBjYXB0dXJlZEJvZHkua2V5c0ZvcldhbGxldFNoYXJlcztcbiAgICAgICAgc2VudEVudHJpZXMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgICBzZW50RW50cmllc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZW5jcnlwdGVkUHJ2Jyk7XG4gICAgICAgIHNlbnRFbnRyaWVzWzBdLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnd2ViYXV0aG5JbmZvJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgNDEzIHBheWxvYWQgdG9vIGxhcmdlIGVycm9yIHdpdGggc21hcnQgcmV0cnknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3QgZnJvbVVzZXJQcnYgPSBNYXRoLnJhbmRvbSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpblRlc3Q6IE9wdGlvbmFsS2V5Y2hhaW5FbmNyeXB0ZWRLZXkgPSB7XG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IGZyb21Vc2VyUHJ2LnRvU3RyaW5nKCksIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB1c2VyUHJ2ID0gYXdhaXQgZGVjcnlwdEtleWNoYWluUHJpdmF0ZUtleShiaXRnbywga2V5Y2hhaW5UZXN0LCB3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgICAgaWYgKCF1c2VyUHJ2KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZGVjcnlwdCB1c2VyIGtleWNoYWluJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0b0tleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMicsICdoZXgnKSk7XG4gICAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcbiAgICAgICAgY29uc3QgcHVia2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG4gICAgICAgIGNvbnN0IHNlY3JldCA9IGdldFNoYXJlZFNlY3JldChlY2tleSwgQnVmZmVyLmZyb20ocHVia2V5LCAnaGV4JykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgLy8gUGFkIHRoZSBwcml2YXRlIGtleSB3aXRoIGFkZGl0aW9uYWwgZGF0YSB0byBtYWtlIGl0IGxhcmdlciBiZWZvcmUgZW5jcnlwdGluZ1xuICAgICAgICBjb25zdCBuZXdFbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHNlY3JldCwgaW5wdXQ6IHVzZXJQcnYgfSk7XG4gICAgICAgIGNvbnN0IGtleWNoYWluID0ge1xuICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IG5ld0VuY3J5cHRlZFBydixcbiAgICAgICAgICB0b1B1YktleTogcHVia2V5LFxuICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzaGFyZUlkcyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IDIwIH0sIChfLCBpKSA9PiBgc2hhcmUke2kgKyAxfWApO1xuXG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyIHRvIHJldHVybiAyNSBzaGFyZXNcbiAgICAgICAgY29uc3Qgc2hhcmVzID0gc2hhcmVJZHMubWFwKChpZCwgaW5kZXgpID0+ICh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgIHdhbGxldExhYmVsOiBgdGVzdGluZyR7aW5kZXh9YCxcbiAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICB3YWxsZXQ6IGB3YWxsZXQke2luZGV4fWAsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScgYXMgY29uc3QsXG4gICAgICAgICAga2V5Y2hhaW46IGtleWNoYWluLFxuICAgICAgICB9KSk7XG5cbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogc2hhcmVzLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgbXlFY2RoS2V5Y2hhaW4gPSBhd2FpdCBiaXRnby5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBlbmNyeXB0ZWRYcHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBwcnZLZXkgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHtcbiAgICAgICAgICBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBpbnB1dDogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBteUVjZGhLZXljaGFpbi54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfSk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdkZWNyeXB0JykucmVzb2x2ZXMocHJ2S2V5KTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcyh1c2VyUHJ2ICsgJ1gnLnJlcGVhdCgxMDAwMDApKTtcbiAgICAgICAgc2lub24uc3R1Yihtb2R1bGVCaXRnbywgJ2dldFNoYXJlZFNlY3JldCcpLnJlc29sdmVzKCdmYWtlU2hhcmVkU2VjcmV0Jyk7XG5cbiAgICAgICAgLy8gTW9jayBidWxrQWNjZXB0U2hhcmVSZXF1ZXN0V2l0aFJldHJ5IHRvIHRyYWNrIGJhdGNoIHNpemVzXG4gICAgICAgIGNvbnN0IGJhdGNoU2l6ZXM6IG51bWJlcltdID0gW107XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucGVyc2lzdCgpIC8vIFRoaXMgZW5zdXJlcyB0aGUgaW50ZXJjZXB0b3IgcmVtYWlucyBhY3RpdmUgZm9yIG11bHRpcGxlIHJlcXVlc3RzXG4gICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JylcbiAgICAgICAgICAucmVwbHkoZnVuY3Rpb24gKF8sIHJlcXVlc3RCb2R5LCBjYikge1xuICAgICAgICAgICAgY29uc3QgcGFyYW1zID0gcmVxdWVzdEJvZHlbJ2tleXNGb3JXYWxsZXRTaGFyZXMnXSBhcyBBY2NlcHRTaGFyZU9wdGlvbnNSZXF1ZXN0W107XG4gICAgICAgICAgICBiYXRjaFNpemVzLnB1c2gocGFyYW1zLmxlbmd0aCk7XG4gICAgICAgICAgICBpZiAoQnVmZmVyLmJ5dGVMZW5ndGgoSlNPTi5zdHJpbmdpZnkocmVxdWVzdEJvZHkpLCAndXRmOCcpID4gOTUwMDAwKSB7XG4gICAgICAgICAgICAgIC8vIFNpbXVsYXRlIDQxMyBlcnJvclxuICAgICAgICAgICAgICByZXR1cm4gY2IobnVsbCwgWzQxMywgeyBlcnJvcjogJ1JlcXVlc3QgRW50aXR5IFRvbyBMYXJnZScgfV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gUmV0dXJuIHN1Y2Nlc3MgZm9yIHNtYWxsZXIgYmF0Y2hlc1xuICAgICAgICAgICAgcmV0dXJuIGNiKG51bGwsIFtcbiAgICAgICAgICAgICAgMjAwLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IHBhcmFtcy5tYXAoKHBhcmFtKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgd2FsbGV0U2hhcmVJZDogcGFyYW0ud2FsbGV0U2hhcmVJZCxcbiAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXRzLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0U2hhcmVJZHM6IHNoYXJlSWRzLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTaG91bGQgaGF2ZSB0cmllZCB3aXRoIDIwIChpbml0aWFsIGJhdGNoIHNpemUgZm9yIDI1IGl0ZW1zKSwgdGhlbiByZXRyaWVkIHdpdGggc21hbGxlciBiYXRjaGVzXG4gICAgICAgIGJhdGNoU2l6ZXMubGVuZ3RoLnNob3VsZC5iZS5ncmVhdGVyVGhhbigxKTtcbiAgICAgICAgYmF0Y2hTaXplcy5zaG91bGQuZGVlcEVxdWFsKFs5LCA5LCAyXSk7IC8vIEluaXRpYWwgYmF0Y2ggc2l6ZS8vIFJldHJ5IGJhdGNoZXMgc2hvdWxkIGJlIHNtYWxsZXJcblxuICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FjY2VwdGVkV2FsbGV0U2hhcmVzJyk7XG4gICAgICAgIHJlc3VsdC5hY2NlcHRlZFdhbGxldFNoYXJlcy5zaG91bGQuYmUuYW4uQXJyYXkoKTtcbiAgICAgICAgcmVzdWx0LmFjY2VwdGVkV2FsbGV0U2hhcmVzLmxlbmd0aC5zaG91bGQuZXF1YWwoMjApO1xuICAgICAgICByZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXMuZm9yRWFjaCgoc2hhcmUpID0+IHtcbiAgICAgICAgICBzaGFyZS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0U2hhcmVJZCcpO1xuICAgICAgICAgIHNoYXJlLndhbGxldFNoYXJlSWQuc2hvdWxkLm1hdGNoKC9ec2hhcmVcXGQrJC8pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHJldHJ5IHdpdGggcHJvZ3Jlc3NpdmVseSBzbWFsbGVyIGJhdGNoIHNpemVzIG9uIDQxMyBlcnJvcnMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3QgZnJvbVVzZXJQcnYgPSBNYXRoLnJhbmRvbSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpblRlc3Q6IE9wdGlvbmFsS2V5Y2hhaW5FbmNyeXB0ZWRLZXkgPSB7XG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IGZyb21Vc2VyUHJ2LnRvU3RyaW5nKCksIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB1c2VyUHJ2ID0gYXdhaXQgZGVjcnlwdEtleWNoYWluUHJpdmF0ZUtleShiaXRnbywga2V5Y2hhaW5UZXN0LCB3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgICAgaWYgKCF1c2VyUHJ2KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZGVjcnlwdCB1c2VyIGtleWNoYWluJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0b0tleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMicsICdoZXgnKSk7XG4gICAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcbiAgICAgICAgY29uc3QgcHVia2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG4gICAgICAgIGNvbnN0IHNlY3JldCA9IGdldFNoYXJlZFNlY3JldChlY2tleSwgQnVmZmVyLmZyb20ocHVia2V5LCAnaGV4JykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgbmV3RW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IHBhc3N3b3JkOiBzZWNyZXQsIGlucHV0OiB1c2VyUHJ2IH0pO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgIGZyb21QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBuZXdFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgdG9QdWJLZXk6IHB1YmtleSxcbiAgICAgICAgICBwdWI6IHB1YmtleSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc2hhcmVJZHMgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiAyMCB9LCAoXywgaSkgPT4gYHNoYXJlJHtpICsgMX1gKTtcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMlxuICAgICAgICBjb25zdCBzaGFyZXMgPSBzaGFyZUlkcy5tYXAoKGlkLCBpbmRleCkgPT4gKHtcbiAgICAgICAgICBpZCxcbiAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgd2FsbGV0TGFiZWw6IGB0ZXN0aW5nJHtpbmRleH1gLFxuICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgIHdhbGxldDogYHdhbGxldCR7aW5kZXh9YCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyBhcyBjb25zdCxcbiAgICAgICAgICBrZXljaGFpbjoga2V5Y2hhaW4sXG4gICAgICAgIH0pKTtcblxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBzaGFyZXMsXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBteUVjZGhLZXljaGFpbiA9IGF3YWl0IGJpdGdvLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHBydktleSA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoe1xuICAgICAgICAgIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGlucHV0OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXNvbHZlcyhwcnZLZXkpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZW5jcnlwdCcpLnJlc29sdmVzKHVzZXJQcnYgKyAnWCcucmVwZWF0KDEwMDAwMCkpO1xuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoJ2Zha2VTaGFyZWRTZWNyZXQnKTtcblxuICAgICAgICAvLyBUcmFjayB0aGUgc2VxdWVuY2Ugb2YgYmF0Y2ggc2l6ZXMgYXR0ZW1wdGVkXG4gICAgICAgIGNvbnN0IGJhdGNoU2l6ZUF0dGVtcHRzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBlcnNpc3QoKSAvLyBUaGlzIGVuc3VyZXMgdGhlIGludGVyY2VwdG9yIHJlbWFpbnMgYWN0aXZlIGZvciBtdWx0aXBsZSByZXF1ZXN0c1xuICAgICAgICAgIC5wdXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzL2FjY2VwdCcpXG4gICAgICAgICAgLnJlcGx5KGZ1bmN0aW9uIChfLCByZXF1ZXN0Qm9keTogYW55LCBjYikge1xuICAgICAgICAgICAgY29uc3QgcGFyYW1zID0gcmVxdWVzdEJvZHlbJ2tleXNGb3JXYWxsZXRTaGFyZXMnXSBhcyBBY2NlcHRTaGFyZU9wdGlvbnNSZXF1ZXN0W107XG4gICAgICAgICAgICBiYXRjaFNpemVBdHRlbXB0cy5wdXNoKHBhcmFtcy5sZW5ndGgpO1xuXG4gICAgICAgICAgICAvLyBTaW11bGF0ZSA0MTMgZm9yIGJhdGNoZXMgPiA1LCBzdWNjZXNzIGZvciBiYXRjaGVzIDw9IDVcbiAgICAgICAgICAgIGlmIChCdWZmZXIuYnl0ZUxlbmd0aChKU09OLnN0cmluZ2lmeShyZXF1ZXN0Qm9keSksICd1dGY4JykgPiA2MDAwMDApIHtcbiAgICAgICAgICAgICAgLy8gU2ltdWxhdGUgNDEzIGVycm9yXG4gICAgICAgICAgICAgIHJldHVybiBjYihudWxsLCBbNDEzLCB7IGVycm9yOiAnUmVxdWVzdCBFbnRpdHkgVG9vIExhcmdlJyB9XSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJldHVybiBzdWNjZXNzIGZvciBzbWFsbGVyIGJhdGNoZXNcbiAgICAgICAgICAgIHJldHVybiBjYihudWxsLCBbXG4gICAgICAgICAgICAgIDIwMCxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBwYXJhbXMubWFwKChwYXJhbSkgPT4gKHtcbiAgICAgICAgICAgICAgICAgIHdhbGxldFNoYXJlSWQ6IHBhcmFtLndhbGxldFNoYXJlSWQgfHwgJ3Rlc3QnLFxuICAgICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRTaGFyZUlkczogc2hhcmVJZHMsXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNob3VsZCBzZWUgcHJvZ3Jlc3NpdmUgYmF0Y2ggc2l6ZSByZWR1Y3Rpb246IDIwIC0+IDEwIC0+IDUgKHN1Y2Nlc3MpXG4gICAgICAgIGJhdGNoU2l6ZUF0dGVtcHRzLnNob3VsZC5jb250YWluRGVlcChbOSwgNCwgNCwgNCwgNCwgNF0pO1xuXG4gICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYWNjZXB0ZWRXYWxsZXRTaGFyZXMnKTtcbiAgICAgICAgcmVzdWx0LmFjY2VwdGVkV2FsbGV0U2hhcmVzLnNob3VsZC5iZS5hbi5BcnJheSgpO1xuICAgICAgICByZXN1bHQuYWNjZXB0ZWRXYWxsZXRTaGFyZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgyMCk7XG4gICAgICAgIHJlc3VsdC5hY2NlcHRlZFdhbGxldFNoYXJlcy5mb3JFYWNoKChzaGFyZSkgPT4ge1xuICAgICAgICAgIHNoYXJlLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRTaGFyZUlkJyk7XG4gICAgICAgICAgc2hhcmUud2FsbGV0U2hhcmVJZC5zaG91bGQubWF0Y2goL15zaGFyZVxcZCskLyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiBiYXRjaCBzaXplIGNhbm5vdCBiZSByZWR1Y2VkIGZ1cnRoZXInLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3QgZnJvbVVzZXJQcnYgPSBNYXRoLnJhbmRvbSgpO1xuICAgICAgICBjb25zdCBrZXljaGFpblRlc3Q6IE9wdGlvbmFsS2V5Y2hhaW5FbmNyeXB0ZWRLZXkgPSB7XG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IGZyb21Vc2VyUHJ2LnRvU3RyaW5nKCksIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB1c2VyUHJ2ID0gYXdhaXQgZGVjcnlwdEtleWNoYWluUHJpdmF0ZUtleShiaXRnbywga2V5Y2hhaW5UZXN0LCB3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgICAgaWYgKCF1c2VyUHJ2KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmFibGUgdG8gZGVjcnlwdCB1c2VyIGtleWNoYWluJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0b0tleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMicsICdoZXgnKSk7XG4gICAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcbiAgICAgICAgY29uc3QgcHVia2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG4gICAgICAgIGNvbnN0IHNlY3JldCA9IGdldFNoYXJlZFNlY3JldChlY2tleSwgQnVmZmVyLmZyb20ocHVia2V5LCAnaGV4JykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgbmV3RW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IHBhc3N3b3JkOiBzZWNyZXQsIGlucHV0OiB1c2VyUHJ2IH0pO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgIGZyb21QdWJLZXk6IGVja2V5LnB1YmxpY0tleS50b1N0cmluZygnaGV4JyksXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBuZXdFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgdG9QdWJLZXk6IHB1YmtleSxcbiAgICAgICAgICBwdWI6IHB1YmtleSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc2hhcmVJZHMgPSBbJ3NoYXJlMSddO1xuXG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyXG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICdzaGFyZTEnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MScsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAga2V5Y2hhaW46IGtleWNoYWluLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgbXlFY2RoS2V5Y2hhaW4gPSBhd2FpdCBiaXRnby5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBlbmNyeXB0ZWRYcHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IG15RWNkaEtleWNoYWluLnhwcnYsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBwcnZLZXkgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHtcbiAgICAgICAgICBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBpbnB1dDogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBteUVjZGhLZXljaGFpbi54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfSk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdkZWNyeXB0JykucmVzb2x2ZXMocHJ2S2V5KTtcbiAgICAgICAgc2lub24uc3R1Yihtb2R1bGVCaXRnbywgJ2dldFNoYXJlZFNlY3JldCcpLnJlc29sdmVzKCdmYWtlU2hhcmVkU2VjcmV0Jyk7XG5cbiAgICAgICAgLy8gQWx3YXlzIHRocm93IDQxMyBlcnJvciwgZXZlbiBmb3IgYmF0Y2ggc2l6ZSAxXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBlcnNpc3QoKVxuICAgICAgICAgIC5wdXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzL2FjY2VwdCcpXG4gICAgICAgICAgLnJlcGx5KGZ1bmN0aW9uIChfLCBfcmVxdWVzdEJvZHksIGNiKSB7XG4gICAgICAgICAgICAvLyBBbHdheXMgcmVzcG9uZCB3aXRoIDQxMyBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNiKG51bGwsIFs0MTMsIHsgZXJyb3I6ICdSZXF1ZXN0IEVudGl0eSBUb28gTGFyZ2UnIH1dKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkczogc2hhcmVJZHMsXG4gICAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdSZXF1ZXN0IEVudGl0eSBUb28gTGFyZ2UnKTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnRW5jcnlwdGlvblNlc3Npb24gKEhLREYpJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBhc3luYyBmdW5jdGlvbiBzdHViRm9yU2hhcmVzKHNoYXJlQ291bnQ6IG51bWJlciwgZGVjcnlwdGVkV2FsbGV0UHJ2OiBzdHJpbmcsIHdhbGxldFBhc3NwaHJhc2U6IHN0cmluZykge1xuICAgICAgICAgIGNvbnN0IHRvS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyJywgJ2hleCcpKTtcbiAgICAgICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICAgICAgY29uc3QgcHVia2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgICAgY29uc3QgZWNrZXkgPSBtYWtlUmFuZG9tS2V5KCk7XG4gICAgICAgICAgY29uc3Qgc2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGVja2V5LCBCdWZmZXIuZnJvbShwdWJrZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICAgIGNvbnN0IHNlbmRlckVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogc2VjcmV0LCBpbnB1dDogZGVjcnlwdGVkV2FsbGV0UHJ2IH0pO1xuXG4gICAgICAgICAgY29uc3Qgc2hhcmVJZHMgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiBzaGFyZUNvdW50IH0sIChfLCBpKSA9PiBgaGtkZi1zaGFyZS0ke2l9YCk7XG4gICAgICAgICAgY29uc3Qgc2hhcmVzID0gc2hhcmVJZHMubWFwKChpZCwgaW5kZXgpID0+ICh7XG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgIHdhbGxldExhYmVsOiBgdyR7aW5kZXh9YCxcbiAgICAgICAgICAgIGZyb21Vc2VyOiAnZnJvbScsXG4gICAgICAgICAgICB0b1VzZXI6ICd0bycsXG4gICAgICAgICAgICB3YWxsZXQ6IGB3JHtpbmRleH1gLFxuICAgICAgICAgICAgZW50ZXJwcmlzZTogYGVudC0ke2luZGV4fWAsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnIGFzIGNvbnN0LFxuICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBzZW5kZXJFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICAgIHRvUHViS2V5OiBwdWJrZXksXG4gICAgICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoeyBpbmNvbWluZzogc2hhcmVzLCBvdXRnb2luZzogW10gfSk7XG5cbiAgICAgICAgICBjb25zdCBlY2RoID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZWNkaC54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGRlY3J5cHRTdHViID0gc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKTtcbiAgICAgICAgICBkZWNyeXB0U3R1Yi5vbkZpcnN0Q2FsbCgpLnJlc29sdmVzKGVjZGgueHBydik7XG4gICAgICAgICAgZGVjcnlwdFN0dWIucmVzb2x2ZXMoZGVjcnlwdGVkV2FsbGV0UHJ2KTtcbiAgICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmVzb2x2ZXMoc2VjcmV0KTtcblxuICAgICAgICAgIHJldHVybiB7IHNoYXJlSWRzIH07XG4gICAgICAgIH1cblxuICAgICAgICBpdCgnb3BlbnMgb25lIHNlc3Npb24gcGVyIHBhc3NwaHJhc2UgYW5kIGRlc3Ryb3lzIHRoZW0gYWZ0ZXIgdGhlIGxvb3AnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdzdHJvbmctb3V0ZXItcGFzc3BocmFzZSc7XG4gICAgICAgICAgY29uc3QgZGVjcnlwdGVkV2FsbGV0UHJ2ID0gJ3BsYWludGV4dC13YWxsZXQtcHJ2JztcbiAgICAgICAgICBjb25zdCB7IHNoYXJlSWRzIH0gPSBhd2FpdCBzdHViRm9yU2hhcmVzKDMsIGRlY3J5cHRlZFdhbGxldFBydiwgd2FsbGV0UGFzc3BocmFzZSk7XG5cbiAgICAgICAgICBjb25zdCByZWFsU2Vzc2lvbiA9IGF3YWl0IGJpdGdvLmNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uKHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICAgIGNvbnN0IGRlc3Ryb3lTcHkgPSBzaW5vbi5zcHkocmVhbFNlc3Npb24sICdkZXN0cm95Jyk7XG4gICAgICAgICAgY29uc3Qgc2Vzc2lvblN0dWIgPSBzaW5vbi5zdHViKGJpdGdvLCAnY3JlYXRlRW5jcnlwdGlvblNlc3Npb24nKS5yZXNvbHZlcyhyZWFsU2Vzc2lvbik7XG5cbiAgICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JylcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IHNoYXJlSWRzLm1hcCgoaWQpID0+ICh7IHdhbGxldFNoYXJlSWQ6IGlkIH0pKSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgYXdhaXQgd2FsbGV0cy5idWxrQWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkczogc2hhcmVJZHMsIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pO1xuXG4gICAgICAgICAgc2Vzc2lvblN0dWIuY2FsbENvdW50LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgICBzZXNzaW9uU3R1Yi5maXJzdENhbGwuYXJnc1swXS5zaG91bGQuZXF1YWwod2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICAgICAgZGVzdHJveVNweS5jYWxsZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgncHJvZHVjZXMgc3RhbmRhbG9uZS1kZWNyeXB0YWJsZSB2MiBlbnZlbG9wZXMgd2l0aCB1bmlxdWUgcGVyLWVudmVsb3BlIGhrZGZTYWx0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3Nlc3Npb24tcGFzc3BocmFzZS00Mic7XG4gICAgICAgICAgY29uc3QgZGVjcnlwdGVkV2FsbGV0UHJ2ID0gJ3NlY3JldC13YWxsZXQtbWF0ZXJpYWwnO1xuICAgICAgICAgIGNvbnN0IHsgc2hhcmVJZHMgfSA9IGF3YWl0IHN0dWJGb3JTaGFyZXMoNCwgZGVjcnlwdGVkV2FsbGV0UHJ2LCB3YWxsZXRQYXNzcGhyYXNlKTtcblxuICAgICAgICAgIGxldCBjYXB0dXJlZDogeyBrZXlzRm9yV2FsbGV0U2hhcmVzOiBBY2NlcHRTaGFyZU9wdGlvbnNSZXF1ZXN0W10gfSB8IHVuZGVmaW5lZDtcbiAgICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgICAgLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JywgKGJvZHkpID0+IHtcbiAgICAgICAgICAgICAgY2FwdHVyZWQgPSBib2R5O1xuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBzaGFyZUlkcy5tYXAoKGlkKSA9PiAoeyB3YWxsZXRTaGFyZUlkOiBpZCB9KSksXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZHM6IHNoYXJlSWRzLCB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KTtcblxuICAgICAgICAgIGNvbnN0IGVudHJpZXMgPSBjYXB0dXJlZCEua2V5c0ZvcldhbGxldFNoYXJlcztcbiAgICAgICAgICBlbnRyaWVzLnNob3VsZC5oYXZlLmxlbmd0aCg0KTtcbiAgICAgICAgICBjb25zdCBlbnZlbG9wZXMgPSBlbnRyaWVzLm1hcCgoZSkgPT4gSlNPTi5wYXJzZShlLmVuY3J5cHRlZFBydiBhcyBzdHJpbmcpKTtcblxuICAgICAgICAgIGZvciAoY29uc3QgZW52IG9mIGVudmVsb3Blcykge1xuICAgICAgICAgICAgZW52LnNob3VsZC5oYXZlLnByb3BlcnR5KCd2JywgMik7XG4gICAgICAgICAgICBlbnYuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2hrZGZTYWx0Jyk7XG4gICAgICAgICAgICBlbnYuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NhbHQnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gU2FtZSBzZXNzaW9uIOKHkiBzYW1lIEFyZ29uMiBzYWx0IGFjcm9zcyBlbnZlbG9wZXNcbiAgICAgICAgICBjb25zdCBhcmdvblNhbHRzID0gbmV3IFNldChlbnZlbG9wZXMubWFwKChlKSA9PiBlLnNhbHQpKTtcbiAgICAgICAgICBhcmdvblNhbHRzLnNpemUuc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICAgIC8vIFVuaXF1ZSBIS0RGIHNhbHQgcGVyIGVudmVsb3BlIOKHkiBpbmRlcGVuZGVudCBBRVMga2V5c1xuICAgICAgICAgIGNvbnN0IGhrZGZTYWx0cyA9IG5ldyBTZXQoZW52ZWxvcGVzLm1hcCgoZSkgPT4gZS5oa2RmU2FsdCkpO1xuICAgICAgICAgIGhrZGZTYWx0cy5zaXplLnNob3VsZC5lcXVhbCg0KTtcbiAgICAgICAgICAvLyBDcm9zcy13YWxsZXQgaXNvbGF0aW9uOiBldmVyeSBlbnZlbG9wZSBkZWNyeXB0cyBiYWNrIHVuZGVyIHRoZSBzYW1lIHBhc3NwaHJhc2VcbiAgICAgICAgICBmb3IgKGNvbnN0IGVudiBvZiBlbnZlbG9wZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHJvdW5kVHJpcCA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSwgaW5wdXQ6IEpTT04uc3RyaW5naWZ5KGVudikgfSk7XG4gICAgICAgICAgICByb3VuZFRyaXAuc2hvdWxkLmVxdWFsKGRlY3J5cHRlZFdhbGxldFBydik7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnb3BlbnMgYSBzZWNvbmQsIGluZGVwZW5kZW50IHNlc3Npb24gZm9yIHdlYmF1dGhuSW5mby5wYXNzcGhyYXNlIGFuZCBiaW5kcyBhZGF0YSBwZXIgc2hhcmUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdvdXRlci1wdyc7XG4gICAgICAgICAgY29uc3Qgd2ViYXV0aG5QYXNzcGhyYXNlID0gJ3dlYmF1dGhuLXByZi1wdyc7XG4gICAgICAgICAgY29uc3QgZGVjcnlwdGVkV2FsbGV0UHJ2ID0gJ3dhbGxldC1wcnYtd2ViYXV0aG4tY2FzZSc7XG4gICAgICAgICAgY29uc3QgeyBzaGFyZUlkcyB9ID0gYXdhaXQgc3R1YkZvclNoYXJlcygyLCBkZWNyeXB0ZWRXYWxsZXRQcnYsIHdhbGxldFBhc3NwaHJhc2UpO1xuXG4gICAgICAgICAgY29uc3Qgc2Vzc2lvblNweSA9IHNpbm9uLnNweShiaXRnbywgJ2NyZWF0ZUVuY3J5cHRpb25TZXNzaW9uJyk7XG4gICAgICAgICAgbGV0IGNhcHR1cmVkOiB7IGtleXNGb3JXYWxsZXRTaGFyZXM6IEFjY2VwdFNoYXJlT3B0aW9uc1JlcXVlc3RbXSB9IHwgdW5kZWZpbmVkO1xuICAgICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgICBjYXB0dXJlZCA9IGJvZHk7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIHsgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IHNoYXJlSWRzLm1hcCgoaWQpID0+ICh7IHdhbGxldFNoYXJlSWQ6IGlkIH0pKSB9KTtcblxuICAgICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWRzOiBzaGFyZUlkcyxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgd2ViYXV0aG5JbmZvOiB7IG90cERldmljZUlkOiAnZGV2JywgcHJmU2FsdDogJ3NhbHQnLCBwYXNzcGhyYXNlOiB3ZWJhdXRoblBhc3NwaHJhc2UgfSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHNlc3Npb25TcHkuY2FsbENvdW50LnNob3VsZC5lcXVhbCgyKTtcbiAgICAgICAgICBjb25zdCBwYXNzd29yZHMgPSBzZXNzaW9uU3B5LmdldENhbGxzKCkubWFwKChjKSA9PiBjLmFyZ3NbMF0pO1xuICAgICAgICAgIHBhc3N3b3Jkcy5zaG91bGQuY29udGFpbkVxbCh3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgICAgICBwYXNzd29yZHMuc2hvdWxkLmNvbnRhaW5FcWwod2ViYXV0aG5QYXNzcGhyYXNlKTtcblxuICAgICAgICAgIGNvbnN0IGVudHJpZXMgPSBjYXB0dXJlZCEua2V5c0ZvcldhbGxldFNoYXJlcztcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVudHJpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHdlYkVudiA9IEpTT04ucGFyc2UoZW50cmllc1tpXS53ZWJhdXRobkluZm8hLmVuY3J5cHRlZFBydiBhcyBzdHJpbmcpO1xuICAgICAgICAgICAgd2ViRW52LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhZGF0YScsIGBlbnQtJHtpfWApO1xuICAgICAgICAgICAgY29uc3QgcnQgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgcGFzc3dvcmQ6IHdlYmF1dGhuUGFzc3BocmFzZSwgaW5wdXQ6IEpTT04uc3RyaW5naWZ5KHdlYkVudikgfSk7XG4gICAgICAgICAgICBydC5zaG91bGQuZXF1YWwoZGVjcnlwdGVkV2FsbGV0UHJ2KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdkZXN0cm95cyB0aGUgc2Vzc2lvbiBldmVuIHdoZW4gdGhlIGFjY2VwdCBBUEkgY2FsbCBmYWlscycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3B3LWVycm9yJztcbiAgICAgICAgICBjb25zdCBkZWNyeXB0ZWRXYWxsZXRQcnYgPSAneCc7XG4gICAgICAgICAgY29uc3QgeyBzaGFyZUlkcyB9ID0gYXdhaXQgc3R1YkZvclNoYXJlcygyLCBkZWNyeXB0ZWRXYWxsZXRQcnYsIHdhbGxldFBhc3NwaHJhc2UpO1xuXG4gICAgICAgICAgY29uc3QgcmVhbFNlc3Npb24gPSBhd2FpdCBiaXRnby5jcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbih3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgICAgICBjb25zdCBkZXN0cm95U3B5ID0gc2lub24uc3B5KHJlYWxTZXNzaW9uLCAnZGVzdHJveScpO1xuICAgICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbicpLnJlc29sdmVzKHJlYWxTZXNzaW9uKTtcblxuICAgICAgICAgIG5vY2soYmdVcmwpLnB1dCgnL2FwaS92Mi93YWxsZXRzaGFyZXMvYWNjZXB0JykucmVwbHkoNTAwLCB7IGVycm9yOiAnYm9vbScgfSk7XG5cbiAgICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgICAuYnVsa0FjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZHM6IHNoYXJlSWRzLCB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KVxuICAgICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZCgpO1xuXG4gICAgICAgICAgZGVzdHJveVNweS5jYWxsZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgndGhyZWFkcyBlbmNyeXB0aW9uVmVyc2lvbj0xIGludG8gdGhlIGZhY3Rvcnkgc28gdjEgZW52ZWxvcGVzIGFyZSBwcm9kdWNlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ3YxLWNhbGxlcic7XG4gICAgICAgICAgY29uc3QgZGVjcnlwdGVkV2FsbGV0UHJ2ID0gJ2xlZ2FjeSc7XG4gICAgICAgICAgY29uc3QgeyBzaGFyZUlkcyB9ID0gYXdhaXQgc3R1YkZvclNoYXJlcygyLCBkZWNyeXB0ZWRXYWxsZXRQcnYsIHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICAgIGNvbnN0IHNlc3Npb25TcHkgPSBzaW5vbi5zcHkoYml0Z28sICdjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbicpO1xuXG4gICAgICAgICAgbGV0IGNhcHR1cmVkOiB7IGtleXNGb3JXYWxsZXRTaGFyZXM6IEFjY2VwdFNoYXJlT3B0aW9uc1JlcXVlc3RbXSB9IHwgdW5kZWZpbmVkO1xuICAgICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucHV0KCcvYXBpL3YyL3dhbGxldHNoYXJlcy9hY2NlcHQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgICBjYXB0dXJlZCA9IGJvZHk7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIHsgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IHNoYXJlSWRzLm1hcCgoaWQpID0+ICh7IHdhbGxldFNoYXJlSWQ6IGlkIH0pKSB9KTtcblxuICAgICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWRzOiBzaGFyZUlkcyxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgZW5jcnlwdGlvblZlcnNpb246IDEsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyBGYWN0b3J5IGlzIHN0aWxsIGNhbGxlZCB1bmlmb3JtbHksIGJ1dCB3aXRoIGVuY3J5cHRpb25WZXJzaW9uPTFcbiAgICAgICAgICBzZXNzaW9uU3B5LmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgICAgc2Vzc2lvblNweS5maXJzdENhbGwuYXJnc1sxXSEuc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICAgICAgY29uc3QgZW50cmllcyA9IGNhcHR1cmVkIS5rZXlzRm9yV2FsbGV0U2hhcmVzO1xuICAgICAgICAgIGNvbnN0IGVudmVsb3BlcyA9IGVudHJpZXMubWFwKChlKSA9PiBKU09OLnBhcnNlKGUuZW5jcnlwdGVkUHJ2IGFzIHN0cmluZykpO1xuICAgICAgICAgIGZvciAoY29uc3QgZW52IG9mIGVudmVsb3Blcykge1xuICAgICAgICAgICAgZW52LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnaGtkZlNhbHQnKTtcbiAgICAgICAgICAgIGVudi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaXRlcicpOyAvLyB2MSBTSkNMXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBtaXNzaW5nIHNoYXJlcyBwYXJhbWV0ZXInLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHt9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdNaXNzaW5nIHBhcmFtZXRlcjogc2hhcmVzJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBub24tYXJyYXkgc2hhcmVzIHBhcmFtZXRlcicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6ICdub3QtYW4tYXJyYXknIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0V4cGVjdGluZyBwYXJhbWV0ZXIgYXJyYXk6IHNoYXJlcyBidXQgZm91bmQgc3RyaW5nJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBtaXNzaW5nIHdhbGxldFNoYXJlSWQgaW4gc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbeyBzdGF0dXM6ICdhY2NlcHQnIH1dIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3Npbmcgd2FsbGV0U2hhcmVJZCBpbiBzaGFyZScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3IgbWlzc2luZyBzdGF0dXMgaW4gc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnMTIzJyB9XSB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdNaXNzaW5nIHN0YXR1cyBpbiBzaGFyZScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3IgaW52YWxpZCBzdGF0dXMgaW4gc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnMTIzJywgc3RhdHVzOiAnaW52YWxpZCcgfV0gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnSW52YWxpZCBzdGF0dXMgaW4gc2hhcmU6IGludmFsaWQuIE11c3QgYmUgZWl0aGVyIFwiYWNjZXB0XCIgb3IgXCJyZWplY3RcIicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3Igbm9uLXN0cmluZyB3YWxsZXRTaGFyZUlkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7IHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogMTIzLCBzdGF0dXM6ICdhY2NlcHQnIH1dIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0V4cGVjdGluZyB3YWxsZXRTaGFyZUlkIHRvIGJlIGEgc3RyaW5nIGJ1dCBmb3VuZCBudW1iZXInKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHZhbGlkYXRpb24gZXJyb3IgZm9yIG5vbi1zdHJpbmcgdXNlckxvZ2luUGFzc3dvcmQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnMTIzJywgc3RhdHVzOiAnYWNjZXB0JyB9XSwgdXNlckxvZ2luUGFzc3dvcmQ6IDEyMyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFeHBlY3RpbmcgcGFyYW1ldGVyIHN0cmluZzogdXNlckxvZ2luUGFzc3dvcmQgYnV0IGZvdW5kIG51bWJlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3Igbm9uLXN0cmluZyBuZXdXYWxsZXRQYXNzcGhyYXNlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgICBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICcxMjMnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdwYXNzd29yZCcsXG4gICAgICAgICAgICBuZXdXYWxsZXRQYXNzcGhyYXNlOiAxMjMsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnRXhwZWN0aW5nIHBhcmFtZXRlciBzdHJpbmc6IG5ld1dhbGxldFBhc3NwaHJhc2UgYnV0IGZvdW5kIG51bWJlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgYXNzZXJ0aW9uIGVycm9yIGZvciBlbXB0eSBzaGFyZXMgYXJyYXknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbXSB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdubyBzaGFyZXMgYXJlIHBhc3NlZCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIG5vIHZhbGlkIHdhbGxldCBzaGFyZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICdkdW1teVdhbGxldElkJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQxJywgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiAnZHVtbXlAMTIzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIHdhbGxldCBzaGFyZSBwcm92aWRlZDogNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDEnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBlY2RoIGtleWNoYWluIHVuZGVmaW5lZCB3aGVuIGFjY2VwdGluZyBzaGFyZSByZXF1aXJpbmcgZGVjcnlwdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ2R1bW15V2FsbGV0SWQnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgICAgcHViOiAncHViJyxcbiAgICAgICAgICAgICAgICB0b1B1YktleTogJ3RvUHViS2V5JyxcbiAgICAgICAgICAgICAgICBmcm9tUHViS2V5OiAnZnJvbVB1YktleScsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgICAgICAgICBwYXRoOiAncGF0aCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBwcnY6ICdwcml2YXRlIGtleScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0Jywgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiAnZHVtbXlAMTIzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdlbmNyeXB0ZWRYcHJ2IHdhcyBub3QgZm91bmQgb24gc2hhcmluZyBrZXljaGFpbicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3VjY2Vzc2Z1bGx5IHVwZGF0ZSBzaGFyZXMgd2l0aCBib3RoIGFjY2VwdCBhbmQgcmVqZWN0IHN0YXR1c2VzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIHR3byBzaGFyZXNcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMScsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICdzaGFyZTInLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZzInLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDInLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3RcbiAgICAgICAgY29uc3QgYnVsa1VwZGF0ZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogWydzaGFyZTInXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFtcbiAgICAgICAgICAgIHsgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsIHN0YXR1czogJ2FjY2VwdCcgfSxcbiAgICAgICAgICAgIHsgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMicsIHN0YXR1czogJ3JlamVjdCcgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgdGhlIHJlc3VsdFxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHJlc3VsdCwge1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMiddLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3Qgd2FzIGNhbGxlZCB3aXRoIGNvcnJlY3QgcGFyYW1ldGVyc1xuICAgICAgICBidWxrVXBkYXRlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGNvbnN0IHVwZGF0ZVBhcmFtcyA9IGJ1bGtVcGRhdGVTdHViLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgICB1cGRhdGVQYXJhbXMuc2hvdWxkLmhhdmUubGVuZ3RoT2YoMik7XG5cbiAgICAgICAgLy8gU2Vjb25kIHBhcmFtIHNob3VsZCBiZSBmb3Igc2hhcmUyIHdpdGggcmVqZWN0IHN0YXR1c1xuICAgICAgICB1cGRhdGVQYXJhbXMuc2hvdWxkLmNvbnRhaW5EZWVwKFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkOiAnc2hhcmUyJyxcbiAgICAgICAgICAgIHN0YXR1czogJ3JlamVjdCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkIHdpdGggbmV3V2FsbGV0UGFzc3BocmFzZSBpbiBidWxrIG9wZXJhdGlvbnMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHVzZXJMb2dpblBhc3N3b3JkID0gJ2JpdGdvMTIzNCc7XG4gICAgICAgIGNvbnN0IG5ld1dhbGxldFBhc3NwaHJhc2UgPSAnbmV3X3dhbGxldF9wYXNzcGhyYXNlXzQ1Nic7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIGEgc2hhcmUgd2l0aCBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWRcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMScsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIHVzZXIgc2V0dGluZ3MgQVBJIGNhbGwgKHJlcXVpcmVkIGJ5IGJ1bGtVcGRhdGVXYWxsZXRTaGFyZSlcbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KCcvYXBpL3YxL3VzZXIvc2V0dGluZ3MnKS5yZXBseSgyMDAsIHt9KTtcblxuICAgICAgICAvLyBNb2NrIGdldEVDREhLZXljaGFpbiAocmVxdWlyZWQgYnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlIHdoZW4gdXNlckxvZ2luUGFzc3dvcmQgaXMgcHJvdmlkZWQpXG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgZW5jcnlwdGVkWHBydjogJ2VuY3J5cHRlZFhwcnYnLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXR1cCBmb3IgdGhlIGJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZVVzZXJLZXljaGFpblxuICAgICAgICBjb25zdCB1c2VyS2V5Y2hhaW4gPSB7XG4gICAgICAgICAgaWQ6ICdrZXkxJyxcbiAgICAgICAgICBwdWI6ICdwdWJLZXknLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFByaXZhdGVLZXknLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjcmVhdGVVc2VyS2V5Y2hhaW5TdHViID0gc2lub25cbiAgICAgICAgICAuc3R1Yih3YWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpLCAnY3JlYXRlVXNlcktleWNoYWluJylcbiAgICAgICAgICAucmVzb2x2ZXModXNlcktleWNoYWluKTtcblxuICAgICAgICAvLyBNb2NrIGRlY3J5cHQgYW5kIHNpZ25NZXNzYWdlXG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdkZWNyeXB0JykucmVzb2x2ZXMoJ2RlY3J5cHRlZFByaXZhdGVLZXknKTtcbiAgICAgICAgc2lub24uc3R1Yih3YWxsZXRzLmJhc2VDb2luLCAnc2lnbk1lc3NhZ2UnKS5yZXNvbHZlcyhCdWZmZXIuZnJvbSgnc2lnbmF0dXJlJykpO1xuXG4gICAgICAgIC8vIE1vY2sgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdFxuICAgICAgICBjb25zdCBidWxrVXBkYXRlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgcmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycyAoY2FsbGVkIGZvciBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQgY2FzZXMpXG4gICAgICAgIGNvbnN0IHJlc2hhcmVTdHViID0gc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ3Jlc2hhcmVXYWxsZXRXaXRoU3BlbmRlcnMnKS5yZXNvbHZlcygpO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTEnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB1c2VyTG9naW5QYXNzd29yZCxcbiAgICAgICAgICBuZXdXYWxsZXRQYXNzcGhyYXNlOiBuZXdXYWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgY3JlYXRlVXNlcktleWNoYWluIHdhcyBjYWxsZWQgd2l0aCBuZXdXYWxsZXRQYXNzcGhyYXNlIChub3QgdXNlckxvZ2luUGFzc3dvcmQpXG4gICAgICAgIGNyZWF0ZVVzZXJLZXljaGFpblN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBjcmVhdGVVc2VyS2V5Y2hhaW5TdHViLmNhbGxlZFdpdGgobmV3V2FsbGV0UGFzc3BocmFzZSkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgICAvLyBWZXJpZnkgdGhlIHJlc3VsdFxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHJlc3VsdCwge1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGJ1bGtVcGRhdGVTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgLy8gVmVyaWZ5IHJlc2hhcmUgd2FzIGNhbGxlZCBmb3Iga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkIGNhc2VcbiAgICAgICAgcmVzaGFyZVN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHNwZWNpYWwgb3ZlcnJpZGUgY2FzZXMgYW5kIHJlc2hhcmUgd2l0aCBzcGVuZGVycycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gYSBzaGFyZSB3aXRoIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZFxuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MScsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0dXAgZm9yIHRoZSBiYXNlQ29pbi5rZXljaGFpbnMoKS5jcmVhdGVVc2VyS2V5Y2hhaW5cbiAgICAgICAgY29uc3QgdXNlcktleWNoYWluID0ge1xuICAgICAgICAgIGlkOiAna2V5MScsXG4gICAgICAgICAgcHViOiAncHViS2V5JyxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWRQcml2YXRlS2V5JyxcbiAgICAgICAgfTtcbiAgICAgICAgc2lub24uc3R1YihvZmNXYWxsZXRzLmJhc2VDb2luLmtleWNoYWlucygpLCAnY3JlYXRlVXNlcktleWNoYWluJykucmVzb2x2ZXModXNlcktleWNoYWluKTtcblxuICAgICAgICAvLyBNb2NrIGRlY3J5cHQgYW5kIHNpZ25NZXNzYWdlXG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdkZWNyeXB0JykucmVzb2x2ZXMoJ2RlY3J5cHRlZFByaXZhdGVLZXknKTtcbiAgICAgICAgc2lub24uc3R1YihvZmNXYWxsZXRzLmJhc2VDb2luLCAnc2lnbk1lc3NhZ2UnKS5yZXNvbHZlcyhCdWZmZXIuZnJvbSgnc2lnbmF0dXJlJykpO1xuXG4gICAgICAgIC8vIE1vY2sgZ2V0RUNESEtleWNoYWluXG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgZW5jcnlwdGVkWHBydjogJ2VuY3J5cHRlZFhwcnYnLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3RcbiAgICAgICAgY29uc3QgYnVsa1VwZGF0ZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIHJlc2hhcmVXYWxsZXRXaXRoU3BlbmRlcnNcbiAgICAgICAgY29uc3QgcmVzaGFyZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAncmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycycpLnJlc29sdmVzKCk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb2ZjV2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsIHN0YXR1czogJ2FjY2VwdCcgfV0sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGUgcmVzdWx0XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzdWx0LCB7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3Qgd2FzIGNhbGxlZFxuICAgICAgICBidWxrVXBkYXRlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IHJlc2hhcmVXYWxsZXRXaXRoU3BlbmRlcnMgd2FzIGNhbGxlZCB3aXRoIGNvcnJlY3QgcGFyYW1ldGVyc1xuICAgICAgICByZXNoYXJlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIHJlc2hhcmVTdHViLmZpcnN0Q2FsbC5hcmdzWzBdLnNob3VsZC5lcXVhbCgnd2FsbGV0MScpO1xuICAgICAgICByZXNoYXJlU3R1Yi5maXJzdENhbGwuYXJnc1sxXS5zaG91bGQuZXF1YWwod2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgc2hhcmVzIHdpdGggbm8ga2V5Y2hhaW4gdG8gZGVjcnlwdCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuXG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyIHRvIHJldHVybiBhIHNoYXJlIHdpdGggbm8ga2V5Y2hhaW5cbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMScsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldyddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3RcbiAgICAgICAgY29uc3QgYnVsa1VwZGF0ZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUxJywgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IHRoZSByZXN1bHRcbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChyZXN1bHQsIHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCB3YXMgY2FsbGVkIHdpdGggY29ycmVjdCBwYXJhbWV0ZXJzXG4gICAgICAgIGJ1bGtVcGRhdGVTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgY29uc3QgdXBkYXRlUGFyYW1zID0gYnVsa1VwZGF0ZVN0dWIuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICAgIHVwZGF0ZVBhcmFtcy5zaG91bGQuaGF2ZS5sZW5ndGhPZigxKTtcblxuICAgICAgICAvLyBQYXJhbSBzaG91bGQgYmUgZm9yIHNoYXJlMSB3aXRoIGFjY2VwdCBzdGF0dXMgYW5kIG5vIGFkZGl0aW9uYWwgZmllbGRzXG4gICAgICAgIHVwZGF0ZVBhcmFtcy5zaG91bGQuY29udGFpbkRlZXAoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWQ6ICdzaGFyZTEnLFxuICAgICAgICAgICAgc3RhdHVzOiAnYWNjZXB0JyxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBzaGFyZXMgd2l0aCBrZXljaGFpbiByZXF1aXJpbmcgZGVjcnlwdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG5cbiAgICAgICAgLy8gQ3JlYXRlIHRlc3Qga2V5Y2hhaW5zXG4gICAgICAgIGNvbnN0IGZyb21LZXljaGFpbiA9IHV0eG9MaWIuYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmZyb20oJ2RlYWRiZWVmMDFkZWFkYmVlZjAxZGVhZGJlZWYwMWRlYWRiZWVmMDEnLCAnaGV4JykpO1xuICAgICAgICBjb25zdCB0b0tleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMicsICdoZXgnKSk7XG5cbiAgICAgICAgY29uc3QgZnJvbVB1YktleSA9IGZyb21LZXljaGFpbi5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICBjb25zdCB0b1B1YktleSA9IHRvS2V5Y2hhaW4uZGVyaXZlUGF0aChwYXRoKS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBlbmNyeXB0ZWQgcHJpdmF0ZSBrZXlcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxQcml2S2V5ID0gJ29yaWdpbmFsUHJpdmF0ZUtleSc7XG4gICAgICAgIGNvbnN0IHNoYXJlZFNlY3JldCA9IGdldFNoYXJlZFNlY3JldChmcm9tS2V5Y2hhaW4sIEJ1ZmZlci5mcm9tKHRvUHViS2V5LCAnaGV4JykpLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHtcbiAgICAgICAgICBwYXNzd29yZDogc2hhcmVkU2VjcmV0LFxuICAgICAgICAgIGlucHV0OiBvcmlnaW5hbFByaXZLZXksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgbGlzdFNoYXJlc1YyIHRvIHJldHVybiBhIHNoYXJlIHdpdGgga2V5Y2hhaW5cbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMScsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgIHB1YjogdG9QdWJLZXksXG4gICAgICAgICAgICAgICAgdG9QdWJLZXk6IHRvUHViS2V5LFxuICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6IGZyb21QdWJLZXksXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1vY2sgZ2V0RUNESEtleWNoYWluXG4gICAgICAgIGNvbnN0IG15RWNkaEtleWNoYWluID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgZW5jcnlwdGVkWHBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBteUVjZGhLZXljaGFpbi54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0dXAgZGVjcnlwdCBzdHVic1xuICAgICAgICBjb25zdCBkZWNyeXB0U3R1YiA9IHNpbm9uLnN0dWIoYml0Z28sICdkZWNyeXB0Jyk7XG4gICAgICAgIGRlY3J5cHRTdHViLm9uRmlyc3RDYWxsKCkucmVzb2x2ZXMobXlFY2RoS2V5Y2hhaW4ueHBydik7IC8vIEZvciBzaGFyaW5nIGtleWNoYWluXG4gICAgICAgIGRlY3J5cHRTdHViLm9uU2Vjb25kQ2FsbCgpLnJlc29sdmVzKG9yaWdpbmFsUHJpdktleSk7IC8vIEZvciB3YWxsZXQga2V5Y2hhaW5cblxuICAgICAgICAvLyBNb2NrIGdldFNoYXJlZFNlY3JldFxuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmV0dXJucyhCdWZmZXIuZnJvbShzaGFyZWRTZWNyZXQpKTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3RcbiAgICAgICAgY29uc3QgYnVsa1VwZGF0ZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUxJywgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBuZXdXYWxsZXRQYXNzcGhyYXNlOiAnbmV3UGFzc3BocmFzZScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGUgcmVzdWx0XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzdWx0LCB7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3Qgd2FzIGNhbGxlZCB3aXRoIGNvcnJlY3QgcGFyYW1ldGVyc1xuICAgICAgICBidWxrVXBkYXRlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGNvbnN0IHVwZGF0ZVBhcmFtcyA9IGJ1bGtVcGRhdGVTdHViLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgICB1cGRhdGVQYXJhbXMuc2hvdWxkLmhhdmUubGVuZ3RoT2YoMSk7XG4gICAgICAgIHVwZGF0ZVBhcmFtc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0U2hhcmVJZCcsICdzaGFyZTEnKTtcbiAgICAgICAgdXBkYXRlUGFyYW1zWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCdzdGF0dXMnLCAnYWNjZXB0Jyk7XG4gICAgICAgIC8vIGVuY3J5cHRlZFBydiBpcyBub3cgZW1pdHRlZCBieSB0aGUgc2Vzc2lvbjsgdmVyaWZ5IGl0J3MgYSByZWFsIHYyIGVudmVsb3BlIHRoYXRcbiAgICAgICAgLy8gZGVjcnlwdHMgYmFjayB0byB0aGUgb3JpZ2luYWwgcHJ2IHVuZGVyIG5ld1Bhc3NwaHJhc2UuXG4gICAgICAgIGNvbnN0IGVudmVsb3BlID0gSlNPTi5wYXJzZSh1cGRhdGVQYXJhbXNbMF0uZW5jcnlwdGVkUHJ2IGFzIHN0cmluZyk7XG4gICAgICAgIGVudmVsb3BlLnNob3VsZC5oYXZlLnByb3BlcnR5KCd2JywgMik7XG4gICAgICAgIGVudmVsb3BlLnNob3VsZC5oYXZlLnByb3BlcnR5KCdoa2RmU2FsdCcpO1xuICAgICAgICAvLyBTZXNzaW9uIGVuY3J5cHQgYnlwYXNzZXMgYml0Z28uZGVjcnlwdCdzIHN0dWIgLS0gcmVzdG9yZSB0aGVuIGRlY3J5cHQgdGhlIGVudmVsb3BlXG4gICAgICAgIGRlY3J5cHRTdHViLnJlc3RvcmUoKTtcbiAgICAgICAgY29uc3QgcnQgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgcGFzc3dvcmQ6ICduZXdQYXNzcGhyYXNlJywgaW5wdXQ6IHVwZGF0ZVBhcmFtc1swXS5lbmNyeXB0ZWRQcnYgYXMgc3RyaW5nIH0pO1xuICAgICAgICBydC5zaG91bGQuZXF1YWwob3JpZ2luYWxQcml2S2V5KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSByZWplY3RlZCBwcm9taXNlcyBhbmQgYWRkIHRoZW0gdG8gd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gdHdvIHNoYXJlc1xuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMicsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nMicsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MicsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUzJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmczJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQzJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3R1YiBwcm9jZXNzQWNjZXB0U2hhcmUgdG8gdGhyb3cgYW4gZXJyb3IgZm9yIHNoYXJlMlxuICAgICAgICAvLyBVc2luZyAnYXMgYW55JyB0byBieXBhc3MgVHlwZVNjcmlwdCdzIHByaXZhdGUgbWV0aG9kIHJlc3RyaWN0aW9uXG4gICAgICAgIGNvbnN0IHByb2Nlc3NBY2NlcHRTaGFyZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlIGFzIGFueSwgJ3Byb2Nlc3NBY2NlcHRTaGFyZScpO1xuICAgICAgICBwcm9jZXNzQWNjZXB0U2hhcmVTdHViXG4gICAgICAgICAgLndpdGhBcmdzKCdzaGFyZTEnLCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnkpXG4gICAgICAgICAgLnJlc29sdmVzKFt7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTEnLCBzdGF0dXM6ICdhY2NlcHQnIH1dKTtcbiAgICAgICAgcHJvY2Vzc0FjY2VwdFNoYXJlU3R1YlxuICAgICAgICAgIC53aXRoQXJncygnc2hhcmUyJywgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55KVxuICAgICAgICAgIC5yZWplY3RzKG5ldyBFcnJvcignRmFpbGVkIHRvIHByb2Nlc3Mgc2hhcmUyJykpO1xuICAgICAgICBwcm9jZXNzQWNjZXB0U2hhcmVTdHViXG4gICAgICAgICAgLndpdGhBcmdzKCdzaGFyZTMnLCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnkpXG4gICAgICAgICAgLnJlc29sdmVzKFt7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTMnLCBzdGF0dXM6ICdhY2NlcHQnIH1dKTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QgdG8gcmV0dXJuIGEgcmVzcG9uc2VcbiAgICAgICAgY29uc3QgYnVsa1VwZGF0ZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnLCAnc2hhcmUzJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSwgLy8gRW1wdHkgYXJyYXkgdGhhdCBzaG91bGQgYmUgcG9wdWxhdGVkXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFtcbiAgICAgICAgICAgIHsgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsIHN0YXR1czogJ2FjY2VwdCcgfSxcbiAgICAgICAgICAgIHsgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMicsIHN0YXR1czogJ2FjY2VwdCcgfSxcbiAgICAgICAgICAgIHsgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMycsIHN0YXR1czogJ2FjY2VwdCcgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCB3YXMgY2FsbGVkIHdpdGggb25seSB0aGUgc3VjY2Vzc2Z1bCBzaGFyZVxuICAgICAgICBidWxrVXBkYXRlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGNvbnN0IHVwZGF0ZVBhcmFtcyA9IGJ1bGtVcGRhdGVTdHViLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgICB1cGRhdGVQYXJhbXMuc2hvdWxkLmhhdmUubGVuZ3RoT2YoMik7XG4gICAgICAgIHVwZGF0ZVBhcmFtc1swXS53YWxsZXRTaGFyZUlkLnNob3VsZC5lcXVhbCgnc2hhcmUxJyk7XG4gICAgICAgIHVwZGF0ZVBhcmFtc1swXS5zdGF0dXMuc2hvdWxkLmVxdWFsKCdhY2NlcHQnKTtcbiAgICAgICAgdXBkYXRlUGFyYW1zWzFdLndhbGxldFNoYXJlSWQuc2hvdWxkLmVxdWFsKCdzaGFyZTMnKTtcbiAgICAgICAgdXBkYXRlUGFyYW1zWzFdLnN0YXR1cy5zaG91bGQuZXF1YWwoJ2FjY2VwdCcpO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGUgcmVzdWx0IGNvbnRhaW5zIHRoZSBlcnJvciBpbmZvcm1hdGlvblxuICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFNoYXJlVXBkYXRlRXJyb3JzJyk7XG4gICAgICAgIHJlc3VsdC53YWxsZXRTaGFyZVVwZGF0ZUVycm9ycy5zaG91bGQuYmUuYW4uQXJyYXkoKTtcbiAgICAgICAgcmVzdWx0LndhbGxldFNoYXJlVXBkYXRlRXJyb3JzLnNob3VsZC5oYXZlLmxlbmd0aE9mKDEpO1xuICAgICAgICByZXN1bHQud2FsbGV0U2hhcmVVcGRhdGVFcnJvcnNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFNoYXJlSWQnLCAnc2hhcmUyJyk7XG4gICAgICAgIHJlc3VsdC53YWxsZXRTaGFyZVVwZGF0ZUVycm9yc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVhc29uJywgJ0ZhaWxlZCB0byBwcm9jZXNzIHNoYXJlMicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgYWNjZXB0IHNoYXJlIHdpdGggdjItZW5jcnlwdGVkIEVDREgga2V5Y2hhaW4gYW5kIHdhbGxldCBwcnYnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuXG4gICAgICAgIGNvbnN0IGZyb21LZXljaGFpbiA9IHV0eG9MaWIuYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmZyb20oJ2RlYWRiZWVmMDFkZWFkYmVlZjAxZGVhZGJlZWYwMWRlYWRiZWVmMDEnLCAnaGV4JykpO1xuICAgICAgICBjb25zdCB0b0tleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwMmRlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMicsICdoZXgnKSk7XG4gICAgICAgIGNvbnN0IHRvUHViS2V5ID0gdG9LZXljaGFpbi5kZXJpdmVQYXRoKHBhdGgpLnB1YmxpY0tleS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IGZyb21QdWJLZXkgPSBmcm9tS2V5Y2hhaW4ucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICBjb25zdCBvcmlnaW5hbFByaXZLZXkgPSAnb3JpZ2luYWxQcml2YXRlS2V5JztcbiAgICAgICAgY29uc3Qgc2hhcmVkU2VjcmV0ID0gZ2V0U2hhcmVkU2VjcmV0KGZyb21LZXljaGFpbiwgQnVmZmVyLmZyb20odG9QdWJLZXksICdoZXgnKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHNoYXJlZFNlY3JldCwgaW5wdXQ6IG9yaWdpbmFsUHJpdktleSB9KTtcblxuICAgICAgICAvLyBCb3RoIHRoZSBFQ0RIIGtleWNoYWluIGFuZCBzaGFyZSBwcnYgYXJlIHYyLWVuY3J5cHRlZCBpbiB0aGlzIHNjZW5hcmlvXG4gICAgICAgIGNvbnN0IHYyRW5jcnlwdGVkWHBydiA9IEpTT04uc3RyaW5naWZ5KHsgdjogMiwgaXY6ICdhYWJiY2MnLCBjdDogJ2RkZWVmZicsIGFkYXRhOiAnMDAnIH0pO1xuXG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICdzaGFyZTEnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MScsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAga2V5Y2hhaW46IHsgcHViOiB0b1B1YktleSwgdG9QdWJLZXksIGZyb21QdWJLZXksIGVuY3J5cHRlZFBydiwgcGF0aCB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgbXlFY2RoS2V5Y2hhaW4gPSBhd2FpdCBiaXRnby5rZXljaGFpbnMoKS5jcmVhdGUoKTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHsgZW5jcnlwdGVkWHBydjogdjJFbmNyeXB0ZWRYcHJ2IH0pO1xuXG4gICAgICAgIC8vIGRlY3J5cHQgaGFuZGxlcyB2MiB0cmFuc3BhcmVudGx5OyBzdHViIHRvIHJldHVybiBleHBlY3RlZCB2YWx1ZXNcbiAgICAgICAgY29uc3QgZGVjcnlwdEFzeW5jU3R1YiA9IHNpbm9uLnN0dWIoYml0Z28sICdkZWNyeXB0Jyk7XG4gICAgICAgIGRlY3J5cHRBc3luY1N0dWIub25GaXJzdENhbGwoKS5yZXNvbHZlcyhteUVjZGhLZXljaGFpbi54cHJ2KTsgLy8gRUNESCBrZXljaGFpblxuICAgICAgICBkZWNyeXB0QXN5bmNTdHViLm9uU2Vjb25kQ2FsbCgpLnJlc29sdmVzKG9yaWdpbmFsUHJpdktleSk7IC8vIHdhbGxldCBzaGFyZSBwcnZcblxuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmV0dXJucyhCdWZmZXIuZnJvbShzaGFyZWRTZWNyZXQpKTtcblxuICAgICAgICBjb25zdCBidWxrVXBkYXRlU3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTEnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIG5ld1dhbGxldFBhc3NwaHJhc2U6ICduZXdQYXNzcGhyYXNlJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXNzZXJ0LmRlZXBFcXVhbChyZXN1bHQsIHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBCb3RoIGRlY3J5cHQgY2FsbHMgbXVzdCBoYXZlIGdvbmUgdGhyb3VnaCBkZWNyeXB0XG4gICAgICAgIGFzc2VydC5lcXVhbChkZWNyeXB0QXN5bmNTdHViLmNhbGxDb3VudCwgMik7XG4gICAgICAgIGJ1bGtVcGRhdGVTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgLy8gRW5jcnlwdGlvbiBub3cgZ29lcyB0aHJvdWdoIHRoZSBzZXNzaW9uOyBhc3NlcnQgYSByZWFsIHYyIGVudmVsb3BlIHJvdW5kLXRyaXBzXG4gICAgICAgIGNvbnN0IHVwZGF0ZVBhcmFtcyA9IGJ1bGtVcGRhdGVTdHViLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgICBjb25zdCBlbnZlbG9wZSA9IEpTT04ucGFyc2UodXBkYXRlUGFyYW1zWzBdLmVuY3J5cHRlZFBydiBhcyBzdHJpbmcpO1xuICAgICAgICBlbnZlbG9wZS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndicsIDIpO1xuICAgICAgICBlbnZlbG9wZS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaGtkZlNhbHQnKTtcbiAgICAgICAgZGVjcnlwdEFzeW5jU3R1Yi5yZXN0b3JlKCk7XG4gICAgICAgIGNvbnN0IHJ0ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7IHBhc3N3b3JkOiAnbmV3UGFzc3BocmFzZScsIGlucHV0OiB1cGRhdGVQYXJhbXNbMF0uZW5jcnlwdGVkUHJ2IGFzIHN0cmluZyB9KTtcbiAgICAgICAgcnQuc2hvdWxkLmVxdWFsKG9yaWdpbmFsUHJpdktleSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ0VuY3J5cHRpb25TZXNzaW9uIChIS0RGKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gQnVpbGQgYSBzZXQgb2YgYWNjZXB0LXN0YXR1cyBzaGFyZXMgd2l0aCByZWFsaXN0aWMgRUNESC1lbmNyeXB0ZWQga2V5Y2hhaW5zIHNvXG4gICAgICAgIC8vIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZSB3YWxrcyB0aGUgc3RhbmRhcmQgcmUtZW5jcnlwdCBwYXRoIGZvciBldmVyeSBzaGFyZS5cbiAgICAgICAgYXN5bmMgZnVuY3Rpb24gc3R1YkZvckFjY2VwdFNoYXJlcyhzaGFyZUNvdW50OiBudW1iZXIsIGRlY3J5cHRlZFdhbGxldFBydjogc3RyaW5nLCB3YWxsZXRQYXNzcGhyYXNlOiBzdHJpbmcpIHtcbiAgICAgICAgICBjb25zdCB0b0tleWNoYWluID0gdXR4b0xpYi5iaXAzMi5mcm9tU2VlZChCdWZmZXIuZnJvbSgnZGVhZGJlZWYwM2RlYWRiZWVmMDNkZWFkYmVlZjAzZGVhZGJlZWYwMycsICdoZXgnKSk7XG4gICAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgICAgIGNvbnN0IHB1YmtleSA9IHRvS2V5Y2hhaW4uZGVyaXZlUGF0aChwYXRoKS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgICAgIGNvbnN0IGVja2V5ID0gbWFrZVJhbmRvbUtleSgpO1xuICAgICAgICAgIGNvbnN0IHNlY3JldCA9IGdldFNoYXJlZFNlY3JldChlY2tleSwgQnVmZmVyLmZyb20ocHVia2V5LCAnaGV4JykpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgICBjb25zdCBzZW5kZXJFbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgcGFzc3dvcmQ6IHNlY3JldCwgaW5wdXQ6IGRlY3J5cHRlZFdhbGxldFBydiB9KTtcblxuICAgICAgICAgIGNvbnN0IHNoYXJlSWRzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogc2hhcmVDb3VudCB9LCAoXywgaSkgPT4gYGJ1bGstdXBkYXRlLXNoYXJlLSR7aX1gKTtcbiAgICAgICAgICBjb25zdCBzaGFyZXMgPSBzaGFyZUlkcy5tYXAoKGlkLCBpbmRleCkgPT4gKHtcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgd2FsbGV0TGFiZWw6IGB3JHtpbmRleH1gLFxuICAgICAgICAgICAgZnJvbVVzZXI6ICdmcm9tJyxcbiAgICAgICAgICAgIHRvVXNlcjogJ3RvJyxcbiAgICAgICAgICAgIHdhbGxldDogYHcke2luZGV4fWAsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnIGFzIGNvbnN0LFxuICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBzZW5kZXJFbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICAgIHRvUHViS2V5OiBwdWJrZXksXG4gICAgICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoeyBpbmNvbWluZzogc2hhcmVzLCBvdXRnb2luZzogW10gfSk7XG5cbiAgICAgICAgICBjb25zdCBlY2RoID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogZWNkaC54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IGRlY3J5cHRTdHViID0gc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKTtcbiAgICAgICAgICBkZWNyeXB0U3R1Yi5vbkZpcnN0Q2FsbCgpLnJlc29sdmVzKGVjZGgueHBydik7XG4gICAgICAgICAgZGVjcnlwdFN0dWIucmVzb2x2ZXMoZGVjcnlwdGVkV2FsbGV0UHJ2KTtcbiAgICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmV0dXJucyhCdWZmZXIuZnJvbShzZWNyZXQpKTtcblxuICAgICAgICAgIHJldHVybiB7IHNoYXJlSWRzIH07XG4gICAgICAgIH1cblxuICAgICAgICBpdCgnb3BlbnMgb25lIHNlc3Npb24gb3ZlciB0aGUgb3V0ZXIgcGFzc3BocmFzZSBhbmQgZGVzdHJveXMgaXQgYWZ0ZXIgdGhlIGxvb3AnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICd1cGRhdGUtcGFzc3BocmFzZSc7XG4gICAgICAgICAgY29uc3QgeyBzaGFyZUlkcyB9ID0gYXdhaXQgc3R1YkZvckFjY2VwdFNoYXJlcygzLCAncGxhaW50ZXh0LXBydicsIHdhbGxldFBhc3NwaHJhc2UpO1xuXG4gICAgICAgICAgY29uc3QgcmVhbFNlc3Npb24gPSBhd2FpdCBiaXRnby5jcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbih3YWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgICAgICBjb25zdCBkZXN0cm95U3B5ID0gc2lub24uc3B5KHJlYWxTZXNzaW9uLCAnZGVzdHJveScpO1xuICAgICAgICAgIGNvbnN0IHNlc3Npb25TdHViID0gc2lub24uc3R1YihiaXRnbywgJ2NyZWF0ZUVuY3J5cHRpb25TZXNzaW9uJykucmVzb2x2ZXMocmVhbFNlc3Npb24pO1xuXG4gICAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QnKS5yZXNvbHZlcyh7XG4gICAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogc2hhcmVJZHMsXG4gICAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBhd2FpdCB3YWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgICBzaGFyZXM6IHNoYXJlSWRzLm1hcCgoaWQpID0+ICh7IHdhbGxldFNoYXJlSWQ6IGlkLCBzdGF0dXM6ICdhY2NlcHQnIGFzIGNvbnN0IH0pKSxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgc2Vzc2lvblN0dWIuY2FsbENvdW50LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgICBzZXNzaW9uU3R1Yi5maXJzdENhbGwuYXJnc1swXS5zaG91bGQuZXF1YWwod2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICAgICAgZGVzdHJveVNweS5jYWxsZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgndGhyZWFkcyB0aGUgc2Vzc2lvbiBpbnRvIHByb2Nlc3NBY2NlcHRTaGFyZSBzbyBlbnZlbG9wZXMgY2FycnkgdGhlIHNhbWUgYXJnb24yIHNhbHQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdzaGFyZWQtYXJnb24yLXNhbHQtdGVzdCc7XG4gICAgICAgICAgY29uc3QgeyBzaGFyZUlkcyB9ID0gYXdhaXQgc3R1YkZvckFjY2VwdFNoYXJlcyg0LCAncGxhaW50ZXh0LXBydicsIHdhbGxldFBhc3NwaHJhc2UpO1xuXG4gICAgICAgICAgbGV0IGNhcHR1cmVkU2hhcmVzOiBCdWxrVXBkYXRlV2FsbGV0U2hhcmVPcHRpb25zUmVxdWVzdFtdID0gW107XG4gICAgICAgICAgc2lub25cbiAgICAgICAgICAgIC5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpXG4gICAgICAgICAgICAuY2FsbHNGYWtlKGFzeW5jIChzaGFyZXM6IEJ1bGtVcGRhdGVXYWxsZXRTaGFyZU9wdGlvbnNSZXF1ZXN0W10pID0+IHtcbiAgICAgICAgICAgICAgY2FwdHVyZWRTaGFyZXMgPSBzaGFyZXM7XG4gICAgICAgICAgICAgIHJldHVybiB7IGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBzaGFyZUlkcywgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLCB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10gfTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgICAgc2hhcmVzOiBzaGFyZUlkcy5tYXAoKGlkKSA9PiAoeyB3YWxsZXRTaGFyZUlkOiBpZCwgc3RhdHVzOiAnYWNjZXB0JyBhcyBjb25zdCB9KSksXG4gICAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNhcHR1cmVkU2hhcmVzLnNob3VsZC5oYXZlLmxlbmd0aCg0KTtcbiAgICAgICAgICBjb25zdCBlbnZlbG9wZXMgPSBjYXB0dXJlZFNoYXJlcy5tYXAoKHMpID0+IEpTT04ucGFyc2Uocy5lbmNyeXB0ZWRQcnYgYXMgc3RyaW5nKSk7XG4gICAgICAgICAgZm9yIChjb25zdCBlbnYgb2YgZW52ZWxvcGVzKSB7XG4gICAgICAgICAgICBlbnYuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3YnLCAyKTtcbiAgICAgICAgICAgIGVudi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaGtkZlNhbHQnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgYXJnb25TYWx0cyA9IG5ldyBTZXQoZW52ZWxvcGVzLm1hcCgoZSkgPT4gZS5zYWx0KSk7XG4gICAgICAgICAgYXJnb25TYWx0cy5zaXplLnNob3VsZC5lcXVhbCgxKTsgLy8gb25lIHNlc3Npb24gLT4gb25lIGFyZ29uMiBzYWx0XG4gICAgICAgICAgY29uc3QgaGtkZlNhbHRzID0gbmV3IFNldChlbnZlbG9wZXMubWFwKChlKSA9PiBlLmhrZGZTYWx0KSk7XG4gICAgICAgICAgaGtkZlNhbHRzLnNpemUuc2hvdWxkLmVxdWFsKDQpOyAvLyBwZXItZW52ZWxvcGUga2V5IGlzb2xhdGlvblxuICAgICAgICAgIC8vIENyb3NzLWVudmVsb3BlIHJvdW5kLXRyaXA6IGVhY2ggZW52ZWxvcGUgZGVjcnlwdHMgdW5kZXIgdGhlIHNhbWUgcGFzc3BocmFzZVxuICAgICAgICAgIGZvciAoY29uc3QgZW52IG9mIGVudmVsb3Blcykge1xuICAgICAgICAgICAgY29uc3QgcnQgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsIGlucHV0OiBKU09OLnN0cmluZ2lmeShlbnYpIH0pO1xuICAgICAgICAgICAgcnQuc2hvdWxkLmVxdWFsKCdwbGFpbnRleHQtcHJ2Jyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnYm91bmRzIGNvbmN1cnJlbnQgcHJvY2Vzc0FjY2VwdFNoYXJlIGNhbGxzIGF0IEJVTEtfU0hBUkVfQkFUQ0hfU0laRSAoMTYpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYmF0Y2gtY2FwLXB3JztcbiAgICAgICAgICBjb25zdCB7IHNoYXJlSWRzIH0gPSBhd2FpdCBzdHViRm9yQWNjZXB0U2hhcmVzKDIwLCAncGxhaW50ZXh0LXBydicsIHdhbGxldFBhc3NwaHJhc2UpO1xuXG4gICAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QnKS5yZXNvbHZlcyh7XG4gICAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogc2hhcmVJZHMsXG4gICAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyBUcmFjayBjb25jdXJyZW50IGluLWZsaWdodCBwcm9jZXNzQWNjZXB0U2hhcmUgaW52b2NhdGlvbnMuIFRoZSBiYXRjaGluZyBpblxuICAgICAgICAgIC8vIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZSBzaG91bGQgY2FwIHRoaXMgYXQgQlVMS19TSEFSRV9CQVRDSF9TSVpFICgxNikuXG4gICAgICAgICAgbGV0IGluRmxpZ2h0ID0gMDtcbiAgICAgICAgICBsZXQgbWF4SW5GbGlnaHQgPSAwO1xuICAgICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUgYXMgYW55LCAncHJvY2Vzc0FjY2VwdFNoYXJlJykuY2FsbHNGYWtlKGFzeW5jICguLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHdhbGxldFNoYXJlSWQgPSBhcmdzWzBdIGFzIHN0cmluZztcbiAgICAgICAgICAgIGluRmxpZ2h0Kys7XG4gICAgICAgICAgICBtYXhJbkZsaWdodCA9IE1hdGgubWF4KG1heEluRmxpZ2h0LCBpbkZsaWdodCk7XG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCA1KSk7XG4gICAgICAgICAgICBpbkZsaWdodC0tO1xuICAgICAgICAgICAgcmV0dXJuIFt7IHdhbGxldFNoYXJlSWQsIHN0YXR1czogJ2FjY2VwdCcgYXMgY29uc3QgfV07XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBhd2FpdCB3YWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgICBzaGFyZXM6IHNoYXJlSWRzLm1hcCgoaWQpID0+ICh7IHdhbGxldFNoYXJlSWQ6IGlkLCBzdGF0dXM6ICdhY2NlcHQnIGFzIGNvbnN0IH0pKSxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgbWF4SW5GbGlnaHQuc2hvdWxkLmJlLmxlc3NUaGFuT3JFcXVhbCgxNik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdkb2VzIG5vdCBvcGVuIGEgc2Vzc2lvbiB3aGVuIHRoZSBidWxrIGNvbnRhaW5zIG9ubHkgcmVqZWN0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlkOiAncmVqZWN0LTEnLFxuICAgICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3gnLFxuICAgICAgICAgICAgICAgIGZyb21Vc2VyOiAnYScsXG4gICAgICAgICAgICAgICAgdG9Vc2VyOiAnYicsXG4gICAgICAgICAgICAgICAgd2FsbGV0OiAndycsXG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldyddLFxuICAgICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBzZXNzaW9uU3R1YiA9IHNpbm9uLnN0dWIoYml0Z28sICdjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbicpO1xuICAgICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFsncmVqZWN0LTEnXSxcbiAgICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJ3JlamVjdC0xJywgc3RhdHVzOiAncmVqZWN0JyB9XSxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiAnaXJyZWxldmFudCcsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBzZXNzaW9uU3R1Yi5jYWxsQ291bnQuc2hvdWxkLmVxdWFsKDApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgndGhyZWFkcyB0aGUgc2Vzc2lvbiB0aHJvdWdoIGNyZWF0ZVVzZXJLZXljaGFpbiBpbiB0aGUgc3BlY2lhbCBvdmVycmlkZSBwYXRoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnb3ZlcnJpZGUtcHcnO1xuICAgICAgICAgIGNvbnN0IHNoYXJlSWQgPSAnb3ZlcnJpZGUtc2hhcmUtMSc7XG4gICAgICAgICAgY29uc3Qgd2FsbGV0SWQgPSAnb3ZlcnJpZGUtd2FsbGV0JztcblxuICAgICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgaWQ6IHNoYXJlSWQsXG4gICAgICAgICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd4JyxcbiAgICAgICAgICAgICAgICBmcm9tVXNlcjogJ2EnLFxuICAgICAgICAgICAgICAgIHRvVXNlcjogJ2InLFxuICAgICAgICAgICAgICAgIHdhbGxldDogd2FsbGV0SWQsXG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgdGVzdEtleWNoYWluID0gYml0Z28uY29pbignb2ZjJykua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgICAgLy8gU2hvcnQtY2lyY3VpdCBjcmVhdGVVc2VyS2V5Y2hhaW4gc28gdGhlIHRlc3QgZG9lc24ndCBoaXQgdGhlIC9rZXkgQVBJIGRhbmNlOyB0aGVcbiAgICAgICAgICAvLyBwb2ludCBvZiB0aGlzIHRlc3QgaXMgdmVyaWZ5aW5nIHRoZSBzZXNzaW9uIGFyZ3VtZW50IHRocmVhZGluZywgbm90aGluZyBtb3JlLlxuICAgICAgICAgIGNvbnN0IGNyZWF0ZVVzZXJLZXljaGFpblN0dWIgPSBzaW5vbi5zdHViKG9mY1dhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCksICdjcmVhdGVVc2VyS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgICBpZDogJ25ldy1rZXljaGFpbi1pZCcsXG4gICAgICAgICAgICBwdWI6IHRlc3RLZXljaGFpbi5wdWIsXG4gICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdzdHViYmVkLWVuY3J5cHRlZC1wcnYnLFxuICAgICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIHNwZWNpYWxPdmVycmlkZUNhc2UgcHVsbHMgdGhlIHNoYXJpbmcga2V5Y2hhaW4gdXAgZnJvbnQsIHNvIHN0dWIgaXQuXG4gICAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHsgZW5jcnlwdGVkWHBydjogJ3N0dWJiZWQtZW5jcnlwdGVkLXhwcnYnIH0pO1xuICAgICAgICAgIHNpbm9uLnN0dWIob2ZjV2FsbGV0cy5iYXNlQ29pbiwgJ3NpZ25NZXNzYWdlJykucmVzb2x2ZXMoQnVmZmVyLmZyb20oJ3NpZ25hdHVyZS1ieXRlcycpKTtcbiAgICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJlc29sdmVzKHRlc3RLZXljaGFpbi5wcnYpO1xuICAgICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0JykucmVzb2x2ZXMoe1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFtzaGFyZUlkXSxcbiAgICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAncmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycycpLnJlc29sdmVzKCk7XG5cbiAgICAgICAgICBhd2FpdCBvZmNXYWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgICBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQsIHN0YXR1czogJ2FjY2VwdCcgfV0sXG4gICAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNyZWF0ZVVzZXJLZXljaGFpblN0dWIuY2FsbGVkT25jZS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICAgICAgLy8gM3JkIHBvc2l0aW9uYWwgYXJnIGlzIHRoZSBzZXNzaW9uXG4gICAgICAgICAgY29uc3Qgc2Vzc2lvbkFyZyA9IGNyZWF0ZVVzZXJLZXljaGFpblN0dWIuZmlyc3RDYWxsLmFyZ3NbMl07XG4gICAgICAgICAgc2hvdWxkLmV4aXN0KHNlc3Npb25BcmcpO1xuICAgICAgICAgICh0eXBlb2Ygc2Vzc2lvbkFyZyEuZW5jcnlwdCkuc2hvdWxkLmVxdWFsKCdmdW5jdGlvbicpO1xuICAgICAgICAgICh0eXBlb2Ygc2Vzc2lvbkFyZyEuZGVzdHJveSkuc2hvdWxkLmVxdWFsKCdmdW5jdGlvbicpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3Jlc2hhcmVXYWxsZXRXaXRoU3BlbmRlcnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICAgIG5vY2sucGVuZGluZ01vY2tzKCkubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgICAgc2lub24ucmVzdG9yZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIEJ1aWxkIGEgbW9jayB3YWxsZXQgd2l0aCBOIHNwZW5kZXIgdXNlcnMgb24gdGhlIHNhbWUgZW50ZXJwcmlzZS5cbiAgICAgIGZ1bmN0aW9uIHN0dWJGb3JSZXNoYXJlKHNwZW5kZXJDb3VudDogbnVtYmVyLCB3YWxsZXRJZDogc3RyaW5nLCBlbnRlcnByaXNlOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgdXNlcnMgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiBzcGVuZGVyQ291bnQgfSwgKF8sIGkpID0+ICh7XG4gICAgICAgICAgdXNlcjogYHNwZW5kZXItJHtpfWAsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldycsICdzcGVuZCddLFxuICAgICAgICB9KSk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0T2JqID0ge1xuICAgICAgICAgIGlkOiB3YWxsZXRJZCxcbiAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgZW50ZXJwcmlzZSxcbiAgICAgICAgICB1c2VycyxcbiAgICAgICAgICBrZXlzOiBbJ3VzZXJLZXlJZCcsICdiYWNrdXBLZXlJZCcsICdiaXRnb0tleUlkJ10sXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gd2FsbGV0cy5nZXQod2FsbGV0SWQpIC0+IFdhbGxldCB3cmFwcGluZyB3YWxsZXRPYmpcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2dldCcpLnJlc29sdmVzKG5ldyBXYWxsZXQoYml0Z28sIGJpdGdvLmNvaW4oJ3Rzb2wnKSwgd2FsbGV0T2JqKSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL2VudGVycHJpc2UvJHtlbnRlcnByaXNlfS91c2VyYClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBhZG1pblVzZXJzOiBbXSxcbiAgICAgICAgICAgIG5vbkFkbWluVXNlcnM6IHVzZXJzLm1hcCgodSwgaSkgPT4gKHsgaWQ6IHUudXNlciwgZW1haWw6IHsgZW1haWw6IGBzcGVuZGVyLSR7aX1AZXhhbXBsZS5jb21gIH0gfSkpLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7IHdhbGxldE9iaiwgdXNlcnMgfTtcbiAgICAgIH1cblxuICAgICAgaXQoJ2RlY3J5cHRzIHRoZSB3YWxsZXQga2V5Y2hhaW4gb25jZSBhbmQgdGhyZWFkcyBpdCBpbnRvIGV2ZXJ5IHNoYXJlV2FsbGV0IGNhbGwnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Jlc2hhcmUtd2FsbGV0LTEnO1xuICAgICAgICBjb25zdCBlbnRlcnByaXNlID0gJ2VudC0xJztcbiAgICAgICAgY29uc3QgdXNlclBhc3N3b3JkID0gJ3NoYXJlZC1wYXNzcGhyYXNlJztcbiAgICAgICAgY29uc3QgZGVjcnlwdGVkS2V5Y2hhaW4gPSB7IHBydjogJ3BsYWludGV4dC1wcnYnLCBwdWI6ICd3YWxsZXQtcHViJyB9O1xuXG4gICAgICAgIGNvbnN0IHsgdXNlcnMgfSA9IHN0dWJGb3JSZXNoYXJlKDMsIHdhbGxldElkLCBlbnRlcnByaXNlKTtcblxuICAgICAgICAvLyBnZXREZWNyeXB0ZWRLZXljaGFpbkZvclNoYXJpbmcgaXMgd2hhdCBydW5zIEFyZ29uMmlkIG9uIHRoZSB3YWxsZXQncyBlbmNyeXB0ZWRQcnYuXG4gICAgICAgIC8vIEFzc2VydCBpdCBmaXJlcyBleGFjdGx5IG9uY2UgcmVnYXJkbGVzcyBvZiBzcGVuZGVyIGNvdW50LlxuICAgICAgICBjb25zdCBkZWNyeXB0U3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ2dldERlY3J5cHRlZEtleWNoYWluRm9yU2hhcmluZycpLnJlc29sdmVzKGRlY3J5cHRlZEtleWNoYWluKTtcblxuICAgICAgICBjb25zdCBzaGFyZVdhbGxldFN0dWIgPSBzaW5vbi5zdHViKFdhbGxldC5wcm90b3R5cGUsICdzaGFyZVdhbGxldCcpLnJlc29sdmVzKHsgc2hhcmVkOiB0cnVlIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHMucmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycyh3YWxsZXRJZCwgdXNlclBhc3N3b3JkKTtcblxuICAgICAgICBkZWNyeXB0U3R1Yi5jYWxsQ291bnQuc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICBkZWNyeXB0U3R1Yi5maXJzdENhbGwuYXJnc1swXSEuc2hvdWxkLmVxdWFsKHVzZXJQYXNzd29yZCk7XG5cbiAgICAgICAgLy8gc2hhcmVXYWxsZXQgY2FsbGVkIG9uY2UgcGVyIHNwZW5kZXIsIGVhY2ggd2l0aCBkZWNyeXB0ZWRLZXljaGFpbiB0aHJlYWRlZCBpblxuICAgICAgICBzaGFyZVdhbGxldFN0dWIuY2FsbENvdW50LnNob3VsZC5lcXVhbCh1c2Vycy5sZW5ndGgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHVzZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgY2FsbCA9IHNoYXJlV2FsbGV0U3R1Yi5nZXRDYWxsKGkpO1xuICAgICAgICAgIGNvbnN0IHNoYXJlQXJnID0gY2FsbC5hcmdzWzBdITtcbiAgICAgICAgICBzaGFyZUFyZy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZGVjcnlwdGVkS2V5Y2hhaW4nKS5lcWwoZGVjcnlwdGVkS2V5Y2hhaW4pO1xuICAgICAgICAgIHNoYXJlQXJnLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRQYXNzcGhyYXNlJywgdXNlclBhc3N3b3JkKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGl0KCdydW5zIHNoYXJlV2FsbGV0IGNhbGxzIHNlcXVlbnRpYWxseSBzbyBwZXItcmVjaXBpZW50IEFyZ29uMmlkIGlzIGJvdW5kZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Jlc2hhcmUtd2FsbGV0LXNlcSc7XG4gICAgICAgIGNvbnN0IGVudGVycHJpc2UgPSAnZW50LTInO1xuICAgICAgICBzdHViRm9yUmVzaGFyZSg1LCB3YWxsZXRJZCwgZW50ZXJwcmlzZSk7XG5cbiAgICAgICAgc2lub24uc3R1YihXYWxsZXQucHJvdG90eXBlLCAnZ2V0RGVjcnlwdGVkS2V5Y2hhaW5Gb3JTaGFyaW5nJykucmVzb2x2ZXMoeyBwcnY6ICdwJywgcHViOiAncScgfSk7XG5cbiAgICAgICAgLy8gVHJhY2sgY29uY3VycmVudCBpbi1mbGlnaHQgc2hhcmVXYWxsZXQgY2FsbHMuIFNlcXVlbnRpYWwgLT4gbWF4IGNvbmN1cnJlbnQgaXMgMS5cbiAgICAgICAgbGV0IGluRmxpZ2h0ID0gMDtcbiAgICAgICAgbGV0IG1heEluRmxpZ2h0ID0gMDtcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXQucHJvdG90eXBlLCAnc2hhcmVXYWxsZXQnKS5jYWxsc0Zha2UoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGluRmxpZ2h0Kys7XG4gICAgICAgICAgbWF4SW5GbGlnaHQgPSBNYXRoLm1heChtYXhJbkZsaWdodCwgaW5GbGlnaHQpO1xuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIDUpKTtcbiAgICAgICAgICBpbkZsaWdodC0tO1xuICAgICAgICAgIHJldHVybiB7IHNoYXJlZDogdHJ1ZSB9O1xuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRzLnJlc2hhcmVXYWxsZXRXaXRoU3BlbmRlcnMod2FsbGV0SWQsICdwdycpO1xuXG4gICAgICAgIG1heEluRmxpZ2h0LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgncmV0dXJucyBlYXJseSB3aGVuIHRoZSB3YWxsZXQgaGFzIG5vIHNwZW5kZXIgdXNlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Jlc2hhcmUtZW1wdHknO1xuICAgICAgICBjb25zdCBlbnRlcnByaXNlID0gJ2VudC1lbXB0eSc7XG5cbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2dldCcpLnJlc29sdmVzKFxuICAgICAgICAgIG5ldyBXYWxsZXQoYml0Z28sIGJpdGdvLmNvaW4oJ3Rzb2wnKSwge1xuICAgICAgICAgICAgaWQ6IHdhbGxldElkLFxuICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgZW50ZXJwcmlzZSxcbiAgICAgICAgICAgIHVzZXJzOiBbeyB1c2VyOiAnYWRtaW4tb25seScsIHBlcm1pc3Npb25zOiBbJ2FkbWluJywgJ3ZpZXcnLCAnc3BlbmQnXSB9XSxcbiAgICAgICAgICAgIGtleXM6IFsndXNlcktleUlkJywgJ2JhY2t1cEtleUlkJywgJ2JpdGdvS2V5SWQnXSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvZW50ZXJwcmlzZS8ke2VudGVycHJpc2V9L3VzZXJgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGFkbWluVXNlcnM6IFt7IGlkOiAnYWRtaW4tb25seScsIGVtYWlsOiB7IGVtYWlsOiAnYWRtaW5AZXhhbXBsZS5jb20nIH0gfV0sXG4gICAgICAgICAgICBub25BZG1pblVzZXJzOiBbXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBkZWNyeXB0U3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ2dldERlY3J5cHRlZEtleWNoYWluRm9yU2hhcmluZycpO1xuICAgICAgICBjb25zdCBzaGFyZVdhbGxldFN0dWIgPSBzaW5vbi5zdHViKFdhbGxldC5wcm90b3R5cGUsICdzaGFyZVdhbGxldCcpO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHMucmVzaGFyZVdhbGxldFdpdGhTcGVuZGVycyh3YWxsZXRJZCwgJ3B3Jyk7XG5cbiAgICAgICAgLy8gTm8gZGVjcnlwdCBidXJuZWQsIG5vIHNoYXJlcyBhdHRlbXB0ZWRcbiAgICAgICAgZGVjcnlwdFN0dWIuY2FsbGVkLnNob3VsZC5lcXVhbChmYWxzZSk7XG4gICAgICAgIHNoYXJlV2FsbGV0U3R1Yi5jYWxsZWQuc2hvdWxkLmVxdWFsKGZhbHNlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgncHJvY2VlZHMgd2l0aCBwZXItcmVjaXBpZW50IHNoYXJlV2FsbGV0IGV2ZW4gd2hlbiB0aGUgd2FsbGV0IGlzIGNvbGQgKG5vIGRlY3J5cHRlZEtleWNoYWluKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgd2FsbGV0SWQgPSAncmVzaGFyZS1jb2xkJztcbiAgICAgICAgY29uc3QgZW50ZXJwcmlzZSA9ICdlbnQtY29sZCc7XG4gICAgICAgIHN0dWJGb3JSZXNoYXJlKDIsIHdhbGxldElkLCBlbnRlcnByaXNlKTtcblxuICAgICAgICAvLyBTaW11bGF0ZSBjb2xkIHdhbGxldDogZ2V0RGVjcnlwdGVkS2V5Y2hhaW5Gb3JTaGFyaW5nIHRocm93cyBNaXNzaW5nRW5jcnlwdGVkS2V5Y2hhaW5FcnJvclxuICAgICAgICAvLyAod2hpY2ggd2UgY2F0Y2ggaW5zaWRlIHJlc2hhcmVXYWxsZXRXaXRoU3BlbmRlcnMgYW5kIGZhbGwgdGhyb3VnaCkuXG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ2dldERlY3J5cHRlZEtleWNoYWluRm9yU2hhcmluZycpLnJlamVjdHMobmV3IE1pc3NpbmdFbmNyeXB0ZWRLZXljaGFpbkVycm9yKCkpO1xuXG4gICAgICAgIGNvbnN0IHNoYXJlV2FsbGV0U3R1YiA9IHNpbm9uLnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ3NoYXJlV2FsbGV0JykucmVzb2x2ZXMoeyBzaGFyZWQ6IHRydWUgfSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0cy5yZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzKHdhbGxldElkLCAncHcnKTtcblxuICAgICAgICAvLyBTdGlsbCBmaXJlcyBwZXIgcmVjaXBpZW50OyBlYWNoIGNhbGwgZ2V0cyB1bmRlZmluZWQgZGVjcnlwdGVkS2V5Y2hhaW4gYW5kIHNoYXJlV2FsbGV0XG4gICAgICAgIC8vIGNhbiBmYWxsIGJhY2sgdG8gaXRzIG93biBkZWNyeXB0IHBhdGggKG9yIGEgbm8tb3AgZm9yIGNvbGQgd2FsbGV0cyBpbnRlcm5hbGx5KS5cbiAgICAgICAgc2hhcmVXYWxsZXRTdHViLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMjsgaSsrKSB7XG4gICAgICAgICAgY29uc3Qgc2hhcmVBcmcgPSBzaGFyZVdhbGxldFN0dWIuZ2V0Q2FsbChpKS5hcmdzWzBdITtcbiAgICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2hhcmVBcmcuZGVjcnlwdGVkS2V5Y2hhaW4sIHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY3JlYXRlQnVsa0tleVNoYXJlcyB0ZXN0cycsICgpID0+IHtcbiAgICBjb25zdCB3YWxsZXREYXRhID0ge1xuICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICBjb2luOiAndGJ0YycsXG4gICAgICBrZXlzOiBbXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzYwMDAwMDAwMCcsXG4gICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzcwMDAwMDAwMCcsXG4gICAgICBdLFxuICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgIG11bHRpc2lnVHlwZTogJ29uY2hhaW4nLFxuICAgICAgdHlwZTogJ2hvdCcsXG4gICAgfTtcbiAgICBjb25zdCB0c29sID0gYml0Z28uY29pbigndHNvbCcpO1xuICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIHRzb2wsIHdhbGxldERhdGEpO1xuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKS5wZXJzaXN0KCkuZ2V0KCcvYXBpL3YxL2NsaWVudC9jb25zdGFudHMnKS5yZXBseSgyMDAsIHsgdHRsOiAzNjAwLCBjb25zdGFudHM6IHt9IH0pO1xuICAgICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgfSk7XG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgfSk7XG4gICAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIH0pO1xuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGlmIHNoYXJlT3B0aW9ucyBpcyBlbXB0eScsIGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVCdWxrS2V5U2hhcmVzKFtdKTtcbiAgICAgICAgYXNzZXJ0LmZhaWwoJ0V4cGVjdGVkIGVycm9yIG5vdCB0aHJvd24nKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5tZXNzYWdlLCAnc2hhcmVPcHRpb25zIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBza2lwIHNoYXJlb3B0aW9uIGlmIGtleWNoYWluIHBhcmFtZXRlcnMgYXJlIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB1c2VyOiAndGVzdHVzZXJAZXhhbXBsZS5jb20nLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAga2V5Y2hhaW46IHsgcHViOiAncHVia2V5JywgZW5jcnlwdGVkUHJ2OiAnJywgZnJvbVB1YktleTogJycsIHRvUHViS2V5OiAnJywgcGF0aDogJycgfSxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVCdWxrS2V5U2hhcmVzKHBhcmFtcyk7XG4gICAgICAgIGFzc2VydC5mYWlsKCdFeHBlY3RlZCBlcnJvciBub3QgdGhyb3duJyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBTaGFyZW9wdGlvbnMgd2l0aCBpbnZhbGlkIGtleWNoYWlucyBhcmUgc2tpcHBlZFxuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXJyb3IubWVzc2FnZSwgJ3NoYXJlT3B0aW9ucyBjYW5ub3QgYmUgZW1wdHknKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2VuZCB0aGUgY29ycmVjdCBkYXRhIHRvIEJpdEdvIEFQSSBpZiBzaGFyZU9wdGlvbnMgYXJlIHZhbGlkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBzaGFyZU9wdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1c2VyOiAndGVzdHVzZXJAZXhhbXBsZS5jb20nLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgIHB1YjogJ3B1YmtleScsXG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFBydicsXG4gICAgICAgICAgICAgIGZyb21QdWJLZXk6ICdmcm9tUHViS2V5JyxcbiAgICAgICAgICAgICAgdG9QdWJLZXk6ICd0b1B1YktleScsXG4gICAgICAgICAgICAgIHBhdGg6ICdtLzAvMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgY29uc3QgcGFyYW1zVG9TZW5kID0gW1xuICAgICAgICB7XG4gICAgICAgICAgdXNlcjogJ3Rlc3R1c2VyQGV4YW1wbGUuY29tJyxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICBwdWI6ICdwdWJrZXknLFxuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgICAgIGZyb21QdWJLZXk6ICdmcm9tUHViS2V5JyxcbiAgICAgICAgICAgIHRvUHViS2V5OiAndG9QdWJLZXknLFxuICAgICAgICAgICAgcGF0aDogJ20vMC8wJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3dhbGxldC8ke3dhbGxldERhdGEuaWR9L3dhbGxldHNoYXJlc2AsIHBhcmFtcylcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHNoYXJlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3VzZXJJZCcsXG4gICAgICAgICAgICAgIGNvaW46IHdhbGxldERhdGEuY29pbixcbiAgICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXREYXRhLmlkLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2Zyb21Vc2VySWQnLFxuICAgICAgICAgICAgICB0b1VzZXI6ICd0b1VzZXJJZCcsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnLCAnc3BlbmQnXSxcbiAgICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgICBwdWI6ICdkdW1teVB1YicsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZHVtbXlFbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgICAgIGZyb21QdWJLZXk6ICdkdW1teUZyb21QdWJLZXknLFxuICAgICAgICAgICAgICAgIHRvUHViS2V5OiAnZHVtbXlUb1B1YktleScsXG4gICAgICAgICAgICAgICAgcGF0aDogJ2R1bW15UGF0aCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtLZXlTaGFyZXMocGFyYW1zVG9TZW5kKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc2hhcmVzWzBdLmlkLCAndXNlcklkJywgJ1RoZSBzaGFyZSBJRCBzaG91bGQgbWF0Y2gnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc2hhcmVzWzBdLmNvaW4sIHdhbGxldERhdGEuY29pbiwgJ1RoZSBjb2luIHNob3VsZCBtYXRjaCcpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5zaGFyZXNbMF0ud2FsbGV0LCB3YWxsZXREYXRhLmlkLCAnVGhlIHdhbGxldCBJRCBzaG91bGQgbWF0Y2gnKTtcbiAgICAgIGFzc2VydC5vayhyZXN1bHQuc2hhcmVzWzBdLmtleWNoYWluKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc2hhcmVzWzBdLmtleWNoYWluLnB1YiwgJ2R1bW15UHViJywgJ1RoZSBrZXljaGFpbiBwdWIgc2hvdWxkIG1hdGNoJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LnNoYXJlc1swXS5wZXJtaXNzaW9ucy5pbmNsdWRlcygndmlldycpLCB0cnVlLCAnVGhlIHBlcm1pc3Npb25zIHNob3VsZCBpbmNsdWRlIFwidmlld1wiJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoXG4gICAgICAgIHJlc3VsdC5zaGFyZXNbMF0ucGVybWlzc2lvbnMuaW5jbHVkZXMoJ3NwZW5kJyksXG4gICAgICAgIHRydWUsXG4gICAgICAgICdUaGUgcGVybWlzc2lvbnMgc2hvdWxkIGluY2x1ZGUgXCJzcGVuZFwiJ1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NyZWF0ZUJ1bGtXYWxsZXRTaGFyZSB0ZXN0cycsICgpID0+IHtcbiAgICBjb25zdCBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcblxuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgIGNvaW46ICd0YnRjJyxcbiAgICAgIGtleXM6IFtcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NzAwMDAwMDAwJyxcbiAgICAgIF0sXG4gICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgbXVsdGlzaWdUeXBlOiAnb25jaGFpbicsXG4gICAgICB0eXBlOiAnaG90JyxcbiAgICB9O1xuICAgIGNvbnN0IHRzb2wgPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdHNvbCwgd2FsbGV0RGF0YSk7XG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBlcnNpc3QoKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnJlcGx5KDIwMCwgeyB0dGw6IDM2MDAsIGNvbnN0YW50czoge30gfSk7XG4gICAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICB9KTtcblxuICAgIGFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgIG5vY2sucGVuZGluZ01vY2tzKCkubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGlmIG5vIHNoYXJlIG9wdGlvbnMgYXJlIHByb3ZpZGVkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtXYWxsZXRTaGFyZSh7IHdhbGxldFBhc3NwaHJhc2U6ICdUZXN0Jywga2V5U2hhcmVPcHRpb25zOiBbXSB9KTtcbiAgICAgICAgYXNzZXJ0LmZhaWwoJ0V4cGVjdGVkIGVycm9yIG5vdCB0aHJvd24nKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5tZXNzYWdlLCAnTm8gc2hhcmUgb3B0aW9ucyBwcm92aWRlZCcpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBOZWVkc1VzZXJTaWdudXAgZXJyb3IgaWYgcHVia2V5IGlzIG1pc3NpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB1c2VySWQgPSAndXNlckBleGFtcGxlLmNvbSc7XG4gICAgICBjb25zdCBwZXJtaXNzaW9ucyA9IFsndmlldycsICdzcGVuZCddO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ1Rlc3QnLFxuICAgICAgICAgIGtleVNoYXJlT3B0aW9uczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB1c2VySWQ6IHVzZXJJZCxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgICBwYXRoOiAnbS85OTk5OTkvMS8xJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSBhcyBCdWxrV2FsbGV0U2hhcmVPcHRpb25zKTtcbiAgICAgICAgYXNzZXJ0LmZhaWwoJ0V4cGVjdGVkIGVycm9yIG5vdCB0aHJvd24nKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGFzc2VydC5vayhlcnJvciBpbnN0YW5jZW9mIE5lZWRVc2VyU2lnbnVwRXJyb3IpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXJyb3IubmFtZSwgJ05lZWRVc2VyU2lnbnVwRXJyb3InKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVycm9yLm1lc3NhZ2UsIHVzZXJJZCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGlmIHBhdGggaXMgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJJZCA9ICd1c2VyQGV4YW1wbGUuY29tJztcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gWyd2aWV3JywgJ3NwZW5kJ107XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQnVsa1dhbGxldFNoYXJlKHtcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAnVGVzdCcsXG4gICAgICAgICAga2V5U2hhcmVPcHRpb25zOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHVzZXJJZDogdXNlcklkLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnMsXG4gICAgICAgICAgICAgIHB1YktleTogJ20vOTk5OTk5LzEvMScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0gYXMgQnVsa1dhbGxldFNoYXJlT3B0aW9ucyk7XG4gICAgICAgIGFzc2VydC5mYWlsKCdFeHBlY3RlZCBlcnJvciBub3QgdGhyb3duJyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXJyb3IubmFtZSwgJ0Vycm9yJyk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5tZXNzYWdlLCAnTWlzc2luZyBwYXJhbWV0ZXI6IHBhdGgnKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgTmVlZHNVc2VyU2lnbnVwIGVycm9yIGlmIHB1YmtleSBpcyBlbXB0eSBzdHJpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB1c2VySWQgPSAndXNlckBleGFtcGxlLmNvbSc7XG4gICAgICBjb25zdCBwZXJtaXNzaW9ucyA9IFsndmlldycsICdzcGVuZCddO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ1Rlc3QnLFxuICAgICAgICAgIGtleVNoYXJlT3B0aW9uczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB1c2VySWQ6IHVzZXJJZCxcbiAgICAgICAgICAgICAgcHViS2V5OiAnJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgICBwYXRoOiAnbS85OTk5OTkvMS8xJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5mYWlsKCdFeHBlY3RlZCBlcnJvciBub3QgdGhyb3duJyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBhc3NlcnQub2soZXJyb3IgaW5zdGFuY2VvZiBOZWVkVXNlclNpZ251cEVycm9yKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVycm9yLm5hbWUsICdOZWVkVXNlclNpZ251cEVycm9yJyk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5tZXNzYWdlLCB1c2VySWQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb3JyZWN0bHkgcHJvY2VzcyBzaGFyZSBvcHRpb25zIGFuZCBjYWxsIGNyZWF0ZUJ1bGtLZXlTaGFyZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB1c2VySWQgPSAndXNlckBleGFtcGxlLmNvbSc7XG4gICAgICBjb25zdCBwZXJtaXNzaW9ucyA9IFsndmlldycsICdzcGVuZCddO1xuICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgY29uc3QgcHViID0gJ1pvMWdnelRVS01ZNWJZbkR2VDVtdFZlWnh6ZjJGYUxUYktrbXZHVWhVUWsnO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLmdldChgL2FwaS92Mi90YnRjL2tleS8ke3dhbGxldC5rZXlJZHMoKVswXX1gKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgaWQ6IHdhbGxldC5rZXlJZHMoKVswXSxcbiAgICAgICAgICBwdWIsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MScsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICAgIH0pO1xuICAgICAgY29uc3QgcGFyYW1zOiBCdWxrV2FsbGV0U2hhcmVPcHRpb25zID0ge1xuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBrZXlTaGFyZU9wdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB1c2VySWQ6IHVzZXJJZCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIHB1YktleTogJzAyNzA1YTZkMzNhMjQ1OWZlYjUzN2U3YWJlMzZhYWFkOGMxMTUzMmNkYmZmYTNhMmU0ZTU4ODY4NDY3ZDUxZjUzMicsXG4gICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwcnYxID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygpO1xuICAgICAgY29uc3Qga2V5Y2hhaW5UZXN0OiBPcHRpb25hbEtleWNoYWluRW5jcnlwdGVkS2V5ID0ge1xuICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogcHJ2MSwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICB9O1xuXG4gICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ2dldEVuY3J5cHRlZFVzZXJLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgZW5jcnlwdGVkUHJ2OiBrZXljaGFpblRlc3QuZW5jcnlwdGVkUHJ2LFxuICAgICAgICBwdWIsXG4gICAgICB9IGFzIEtleWNoYWluV2l0aEVuY3J5cHRlZFBydik7XG5cbiAgICAgIHNpbm9uLnN0dWIobW9kdWxlQml0Z28sICdnZXRTaGFyZWRTZWNyZXQnKS5yZXNvbHZlcygnZmFrZVNoYXJlZFNlY3JldCcpO1xuXG4gICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ2NyZWF0ZUJ1bGtLZXlTaGFyZXMnKS5yZXNvbHZlcyh7XG4gICAgICAgIHNoYXJlczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGlkOiB1c2VySWQsXG4gICAgICAgICAgICBjb2luOiB3YWxsZXREYXRhLmNvaW4sXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldERhdGEuaWQsXG4gICAgICAgICAgICBmcm9tVXNlcjogdXNlcklkLFxuICAgICAgICAgICAgdG9Vc2VyOiB1c2VySWQsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3JywgJ3NwZW5kJ10sXG4gICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICBwdWI6ICdkdW1teVB1YicsXG4gICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2R1bW15RW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgICAgICAgZnJvbVB1YktleTogJ2R1bW15RnJvbVB1YktleScsXG4gICAgICAgICAgICAgIHRvUHViS2V5OiAnZHVtbXlUb1B1YktleScsXG4gICAgICAgICAgICAgIHBhdGg6ICdkdW1teVBhdGgnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldC5jcmVhdGVCdWxrV2FsbGV0U2hhcmUocGFyYW1zKTtcblxuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChyZXN1bHQsIHtcbiAgICAgICAgc2hhcmVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6IHVzZXJJZCxcbiAgICAgICAgICAgIGNvaW46IHdhbGxldERhdGEuY29pbixcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0RGF0YS5pZCxcbiAgICAgICAgICAgIGZyb21Vc2VyOiB1c2VySWQsXG4gICAgICAgICAgICB0b1VzZXI6IHVzZXJJZCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnLCAnc3BlbmQnXSxcbiAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgIHB1YjogJ2R1bW15UHViJyxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZHVtbXlFbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgICBmcm9tUHViS2V5OiAnZHVtbXlGcm9tUHViS2V5JyxcbiAgICAgICAgICAgICAgdG9QdWJLZXk6ICdkdW1teVRvUHViS2V5JyxcbiAgICAgICAgICAgICAgcGF0aDogJ2R1bW15UGF0aCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaW4gcHJvY2Vzc2luZyBzaGFyZSBvcHRpb25zIHdoZW4gd2FsbGV0IHBhc3N3b3JkIGlzIGluY29ycmVjdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJJZCA9ICd1c2VyQGV4YW1wbGUuY29tJztcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gWyd2aWV3JywgJ3NwZW5kJ107XG4gICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICBjb25zdCBwdWIgPSAnWm8xZ2d6VFVLTVk1YlluRHZUNW10VmVaeHpmMkZhTFRiS2ttdkdVaFVRayc7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyL3RidGMva2V5LyR7d2FsbGV0LmtleUlkcygpWzBdfWApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogd2FsbGV0LmtleUlkcygpWzBdLFxuICAgICAgICAgIHB1YixcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYxJywgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBwYXJhbXM6IEJ1bGtXYWxsZXRTaGFyZU9wdGlvbnMgPSB7XG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICd3cm9uZyBwYXNzd29yZCcsXG4gICAgICAgIGtleVNoYXJlT3B0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVzZXJJZDogdXNlcklkLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgcHViS2V5OiAnMDI3MDVhNmQzM2EyNDU5ZmViNTM3ZTdhYmUzNmFhYWQ4YzExNTMyY2RiZmZhM2EyZTRlNTg4Njg0NjdkNTFmNTMyJyxcbiAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBydjEgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKCk7XG4gICAgICBjb25zdCBrZXljaGFpblRlc3Q6IE9wdGlvbmFsS2V5Y2hhaW5FbmNyeXB0ZWRLZXkgPSB7XG4gICAgICAgIGVuY3J5cHRlZFBydjogYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYxLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgIH07XG5cbiAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnZ2V0RW5jcnlwdGVkVXNlcktleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleWNoYWluVGVzdC5lbmNyeXB0ZWRQcnYsXG4gICAgICAgIHB1YixcbiAgICAgIH0gYXMgS2V5Y2hhaW5XaXRoRW5jcnlwdGVkUHJ2KTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtXYWxsZXRTaGFyZShwYXJhbXMpO1xuICAgICAgICBhc3NlcnQuZmFpbCgnRXhwZWN0ZWQgZXJyb3Igbm90IHRocm93bicpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYXNzZXJ0Lm9rKGVycm9yIGluc3RhbmNlb2YgSW5jb3JyZWN0UGFzc3dvcmRFcnJvcik7XG4gICAgICAgIGFzc2VydC5lcXVhbChlcnJvci5tZXNzYWdlLCAnUGFzc3dvcmQgc2hhcmVkIGlzIGluY29ycmVjdCBmb3IgdGhpcyB3YWxsZXQnKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmV0Y2gga2V5Y2hhaW4gb25seSBPTkNFIHdoZW4gc2hhcmluZyB3aXRoIG11bHRpcGxlIHVzZXJzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdiaXRnbzEyMzQnO1xuICAgICAgY29uc3QgcHViID0gJ1pvMWdnelRVS01ZNWJZbkR2VDVtdFZlWnh6ZjJGYUxUYktrbXZHVWhVUWsnO1xuICAgICAgY29uc3QgcHJ2MSA9ICd4cHJ2MSc7XG5cbiAgICAgIC8vIENyZWF0ZSBtdWx0aXBsZSB1c2VycyB0byBzaGFyZSB3aXRoXG4gICAgICBjb25zdCB1c2VycyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIHVzZXJJZDogJ3VzZXIxQGV4YW1wbGUuY29tJyxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3JywgJ3NwZW5kJ10sXG4gICAgICAgICAgcHViS2V5OiAnMDI3MDVhNmQzM2EyNDU5ZmViNTM3ZTdhYmUzNmFhYWQ4YzExNTMyY2RiZmZhM2EyZTRlNTg4Njg0NjdkNTFmNTMyJyxcbiAgICAgICAgICBwYXRoOiAnbS85OTk5OTkvMS8xJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHVzZXJJZDogJ3VzZXIyQGV4YW1wbGUuY29tJyxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3JywgJ3NwZW5kJ10sXG4gICAgICAgICAgcHViS2V5OiAnMDM3MDVhNmQzM2EyNDU5ZmViNTM3ZTdhYmUzNmFhYWQ4YzExNTMyY2RiZmZhM2EyZTRlNTg4Njg0NjdkNTFmNTMzJyxcbiAgICAgICAgICBwYXRoOiAnbS85OTk5OTkvMS8yJyxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHVzZXJJZDogJ3VzZXIzQGV4YW1wbGUuY29tJyxcbiAgICAgICAgICBwZXJtaXNzaW9uczogWyd2aWV3JywgJ3NwZW5kJ10sXG4gICAgICAgICAgcHViS2V5OiAnMDI4MTVhNmQzM2EyNDU5ZmViNTM3ZTdhYmUzNmFhYWQ4YzExNTMyY2RiZmZhM2EyZTRlNTg4Njg0NjdkNTFmNTM0JyxcbiAgICAgICAgICBwYXRoOiAnbS85OTk5OTkvMS8zJyxcbiAgICAgICAgfSxcbiAgICAgIF07XG5cbiAgICAgIGNvbnN0IHBhcmFtczogQnVsa1dhbGxldFNoYXJlT3B0aW9ucyA9IHtcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAga2V5U2hhcmVPcHRpb25zOiB1c2VycyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGdldERlY3J5cHRlZEtleWNoYWluU3R1YiA9IHNpbm9uLnN0dWIod2FsbGV0LCAnZ2V0RGVjcnlwdGVkS2V5Y2hhaW5Gb3JTaGFyaW5nJykucmVzb2x2ZXMoe1xuICAgICAgICBwcnY6IHBydjEsXG4gICAgICAgIHB1YixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBlbmNyeXB0UHJ2Rm9yVXNlclN0dWIgPSBzaW5vblxuICAgICAgICAuc3R1Yih3YWxsZXQsICdlbmNyeXB0UHJ2Rm9yVXNlcicpXG4gICAgICAgIC5jYWxsc0Zha2UoYXN5bmMgKHBydiwgcHViS2V5LCB1c2VyUHViS2V5LCBwYXRoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHB1YjogcHViS2V5LFxuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZHVtbXlFbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgZnJvbVB1YktleTogJ2R1bW15RnJvbVB1YktleScsXG4gICAgICAgICAgICB0b1B1YktleTogdXNlclB1YktleSxcbiAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnY3JlYXRlQnVsa0tleVNoYXJlcycpLnJlc29sdmVzKHtcbiAgICAgICAgc2hhcmVzOiB1c2Vycy5tYXAoKHVzZXIpID0+ICh7XG4gICAgICAgICAgaWQ6IHVzZXIudXNlcklkLFxuICAgICAgICAgIGNvaW46IHdhbGxldERhdGEuY29pbixcbiAgICAgICAgICB3YWxsZXQ6IHdhbGxldERhdGEuaWQsXG4gICAgICAgICAgZnJvbVVzZXI6ICdmcm9tVXNlcicsXG4gICAgICAgICAgdG9Vc2VyOiB1c2VyLnVzZXJJZCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogdXNlci5wZXJtaXNzaW9ucyxcbiAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgcHViOiAnZHVtbXlQdWInLFxuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZHVtbXlFbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgZnJvbVB1YktleTogJ2R1bW15RnJvbVB1YktleScsXG4gICAgICAgICAgICB0b1B1YktleTogdXNlci5wdWJLZXksXG4gICAgICAgICAgICBwYXRoOiB1c2VyLnBhdGgsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSkpLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHdhbGxldC5jcmVhdGVCdWxrV2FsbGV0U2hhcmUocGFyYW1zKTtcblxuICAgICAgLy8gVmVyaWZ5IGtleWNoYWluIGlzIGZldGNoZWQgb25seSBPTkNFLCBub3Qgb25jZSBwZXIgdXNlclxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKFxuICAgICAgICBnZXREZWNyeXB0ZWRLZXljaGFpblN0dWIuY2FsbENvdW50LFxuICAgICAgICAxLFxuICAgICAgICAnZ2V0RGVjcnlwdGVkS2V5Y2hhaW5Gb3JTaGFyaW5nIHNob3VsZCBiZSBjYWxsZWQgZXhhY3RseSBvbmNlLCBub3Qgb25jZSBwZXIgdXNlcidcbiAgICAgICk7XG5cbiAgICAgIC8vIFZlcmlmeSBlbmNyeXB0aW9uIGhhcHBlbnMgZm9yIEVBQ0ggdXNlciAob25jZSBwZXIgdXNlcilcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgZW5jcnlwdFBydkZvclVzZXJTdHViLmNhbGxDb3VudCxcbiAgICAgICAgdXNlcnMubGVuZ3RoLFxuICAgICAgICBgZW5jcnlwdFBydkZvclVzZXIgc2hvdWxkIGJlIGNhbGxlZCBvbmNlIHBlciB1c2VyICgke3VzZXJzLmxlbmd0aH0gdGltZXMpYFxuICAgICAgKTtcblxuICAgICAgLy8gVmVyaWZ5IGVhY2ggY2FsbCBoYWQgdGhlIGNvcnJlY3QgdXNlcidzIHB1YktleSBhbmQgcGF0aFxuICAgICAgdXNlcnMuZm9yRWFjaCgodXNlciwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgY2FsbCA9IGVuY3J5cHRQcnZGb3JVc2VyU3R1Yi5nZXRDYWxsKGluZGV4KTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNhbGwuYXJnc1swXSwgcHJ2MSwgJ1Nob3VsZCB1c2UgdGhlIHNhbWUgZGVjcnlwdGVkIHByaXZhdGUga2V5IGZvciBhbGwgdXNlcnMnKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNhbGwuYXJnc1sxXSwgcHViLCAnU2hvdWxkIHVzZSB0aGUgc2FtZSBwdWJsaWMga2V5IGZvciBhbGwgdXNlcnMnKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGNhbGwuYXJnc1syXSwgdXNlci5wdWJLZXksIGBTaG91bGQgdXNlIHVzZXIke2luZGV4ICsgMX0ncyBwdWJsaWMga2V5YCk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChjYWxsLmFyZ3NbM10sIHVzZXIucGF0aCwgYFNob3VsZCB1c2UgdXNlciR7aW5kZXggKyAxfSdzIHBhdGhgKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZG93bmxvYWRLZXljYXJkJywgKCkgPT4ge1xuICAgIGNvbnN0IGxvY2FsQml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgIGlkOiAnNWIzNDI1MmYxYmYzNDk5MzBlMzQwMjBhMDAwMDAwMDInLFxuICAgICAgY29pbjogJ3RidGMnLFxuICAgICAga2V5czogW1xuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1MDAwMDAwMDAnLFxuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgXSxcbiAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICBtdWx0aXNpZ1R5cGU6ICdvbmNoYWluJyxcbiAgICAgIHR5cGU6ICdob3QnLFxuICAgIH07XG4gICAgY29uc3QgdGJ0YyA9IGxvY2FsQml0Z28uY29pbigndGJ0YycpO1xuICAgIGNvbnN0IHdhbGxldCA9IG5ldyBXYWxsZXQobG9jYWxCaXRnbywgdGJ0Yywgd2FsbGV0RGF0YSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IHdoZW4gY2FsbGVkIGluIE5vZGUuanMgKG5vIGJyb3dzZXIgd2luZG93KScsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIEluIE5vZGUuanMsIGFjY2Vzc2luZyBgd2luZG93YCB0aHJvd3MgUmVmZXJlbmNlRXJyb3I7IHRoZSBtZXRob2QgcmVqZWN0cy5cbiAgICAgIGF3YWl0IHdhbGxldC5kb3dubG9hZEtleWNhcmQoKS5zaG91bGQuYmUucmVqZWN0ZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KCdkb3dubG9hZEtleWNhcmQgKHN5bmMpIHNob3VsZCB0aHJvdyB3aGVuIGNhbGxlZCBpbiBOb2RlLmpzIChubyBicm93c2VyIHdpbmRvdyknLCAoKSA9PiB7XG4gICAgICBzaG91bGQudGhyb3dzKCgpID0+IHdhbGxldC5kb3dubG9hZEtleWNhcmQoKSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdlbmNyeXB0UHJ2Rm9yVXNlcicsICgpID0+IHtcbiAgICBjb25zdCBsb2NhbEJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAxJyxcbiAgICAgIGNvaW46ICd0YnRjJyxcbiAgICAgIGtleXM6IFtcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NzAwMDAwMDAwJyxcbiAgICAgIF0sXG4gICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgbXVsdGlzaWdUeXBlOiAnb25jaGFpbicsXG4gICAgICB0eXBlOiAnaG90JyxcbiAgICB9O1xuICAgIGNvbnN0IHRidGMgPSBsb2NhbEJpdGdvLmNvaW4oJ3RidGMnKTtcbiAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGxvY2FsQml0Z28sIHRidGMsIHdhbGxldERhdGEpO1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBlcnNpc3QoKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnJlcGx5KDIwMCwgeyB0dGw6IDM2MDAsIGNvbnN0YW50czoge30gfSk7XG4gICAgICBsb2NhbEJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZW5jcnlwdCBwcnYgZm9yIHVzZXIgYW5kIHJldHVybiB0aGUgY29ycmVjdCBvdXRwdXQgc2hhcGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBkZWNyeXB0ZWRQcnYgPVxuICAgICAgICAneHBydjlzMjFaclFIMTQzSzJmSjkxUzRCUnN1cGNZckU2bW1ZOTZmY1g1SGtob1Rycndtd2pkMTZDbjg3Y1dpbkpqQnlyZnBvamp4N2V6c0pMeDdUQUtMVDhtOGhNNUtheDlZY294bkJlSlozdDJrJztcbiAgICAgIGNvbnN0IHB1YiA9XG4gICAgICAgICd4cHViNjYxTXlNd0FxUmJjRjlOYzdUYkJvMXJaQWFnaVdFVlBXS2JES1RoTkc4enFqazc2SEFLTGthU2JUbjZkSzJkUVBmdUQ3eGppY3hDWlZXdmo2N2ZQNW5ROVc3UVVSbW9NVkFYOG02alpzR3AnO1xuICAgICAgLy8gQSB2YWxpZCAzMy1ieXRlIGNvbXByZXNzZWQgRUMgcG9pbnQgb24gc2VjcDI1NmsxXG4gICAgICBjb25zdCB1c2VyUHVia2V5ID0gJzAyNzliZTY2N2VmOWRjYmJhYzU1YTA2Mjk1Y2U4NzBiMDcwMjliZmNkYjJkY2UyOGQ5NTlmMjgxNWIxNmY4MTc5OCc7XG4gICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzAvMSc7XG5cbiAgICAgIHNpbm9uLnN0dWIobG9jYWxCaXRnbywgJ2VuY3J5cHQnKS5yZXNvbHZlcygnZW5jcnlwdGVkUHJ2Rm9yVXNlcicpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXQuZW5jcnlwdFBydkZvclVzZXIoZGVjcnlwdGVkUHJ2LCBwdWIsIHVzZXJQdWJrZXksIHBhdGgpO1xuXG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3B1YicsIHB1Yik7XG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicsICdlbmNyeXB0ZWRQcnZGb3JVc2VyJyk7XG4gICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Zyb21QdWJLZXknKS53aGljaC5pcy5hLlN0cmluZygpO1xuICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0b1B1YktleScsIHVzZXJQdWJrZXkpO1xuICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdwYXRoJywgcGF0aCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdMaXN0IFdhbGxldHM6JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgbGlzdCB3YWxsZXRzIHdpdGggc2tpcFJlY2VpdmVBZGRyZXNzID0gdHJ1ZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0YnRjJyk7XG4gICAgICBjb25zdCB3YWxsZXRzID0gYmFzZWNvaW4ud2FsbGV0cygpO1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG5cbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoJy9hcGkvdjIvdGJ0Yy93YWxsZXQnKVxuICAgICAgICAucXVlcnkoeyBza2lwUmVjZWl2ZUFkZHJlc3M6IHRydWUgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHdhbGxldHM6IFtcbiAgICAgICAgICAgIHsgaWQ6ICd3YWxsZXQxJywgbGFiZWw6ICdUZXN0IFdhbGxldCAxJyB9LFxuICAgICAgICAgICAgeyBpZDogJ3dhbGxldDInLCBsYWJlbDogJ1Rlc3QgV2FsbGV0IDInIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMubGlzdCh7IHNraXBSZWNlaXZlQWRkcmVzczogdHJ1ZSB9KTtcbiAgICAgIHJlc3VsdC53YWxsZXRzLnNob3VsZC5oYXZlLmxlbmd0aCgyKTtcbiAgICAgIHNob3VsZC5ub3QuZXhpc3QocmVzdWx0LndhbGxldHNbMF0ucmVjZWl2ZUFkZHJlc3MoKSk7XG4gICAgICBzaG91bGQubm90LmV4aXN0KHJlc3VsdC53YWxsZXRzWzFdLnJlY2VpdmVBZGRyZXNzKCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBsaXN0IHdhbGxldHMgd2l0aG91dCBza2lwUmVjZWl2ZUFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgICAgY29uc3Qgd2FsbGV0cyA9IGJhc2Vjb2luLndhbGxldHMoKTtcbiAgICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyL3RidGMvd2FsbGV0JylcbiAgICAgICAgLnF1ZXJ5KHt9KVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgd2FsbGV0czogW1xuICAgICAgICAgICAgeyBpZDogJ3dhbGxldDEnLCBsYWJlbDogJ1Rlc3QgV2FsbGV0IDEnLCByZWNlaXZlQWRkcmVzczogeyBhZGRyZXNzOiAnYWRkcmVzczEnIH0gfSxcbiAgICAgICAgICAgIHsgaWQ6ICd3YWxsZXQyJywgbGFiZWw6ICdUZXN0IFdhbGxldCAyJywgcmVjZWl2ZUFkZHJlc3M6IHsgYWRkcmVzczogJ2FkZHJlc3MyJyB9IH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMubGlzdCgpO1xuICAgICAgcmVzdWx0LndhbGxldHMuc2hvdWxkLmhhdmUubGVuZ3RoKDIpO1xuICAgICAgc2hvdWxkLmV4aXN0KHJlc3VsdC53YWxsZXRzWzBdLnJlY2VpdmVBZGRyZXNzKCkpO1xuICAgICAgc2hvdWxkLmV4aXN0KHJlc3VsdC53YWxsZXRzWzFdLnJlY2VpdmVBZGRyZXNzKCkpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19