bitgo
Version:
BitGo JavaScript SDK
1,147 lines • 222 kB
JavaScript
"use strict";
//
// Test for Keychains
//
Object.defineProperty(exports, "__esModule", { value: true });
const statics_1 = require("@bitgo/statics");
const assert = require("assert");
const _ = require("lodash");
const nock = require("nock");
const should = require("should");
const sinon = require("sinon");
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_test_1 = require("@bitgo/sdk-test");
const bitgo_1 = require("../../../src/bitgo");
describe('V2 Keychains', function () {
let bitgo;
let basecoin;
let keychains;
let bgUrl;
before(function () {
bitgo = sdk_test_1.TestBitGo.decorate(bitgo_1.BitGo, { env: 'mock' });
bitgo.initializeTestVars();
bitgo.setValidate(false);
basecoin = bitgo.coin('tltc');
keychains = basecoin.keychains();
bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
});
describe('Add Keychain', function () {
it('should add a keychain', async function () {
const scope = nock(bgUrl)
.post('/api/v2/tltc/key', function (body) {
body.pub.should.equal('pub');
body.derivedFromParentWithSeed.should.equal('derivedFromParentWithSeed');
return true;
})
.reply(200, {});
await keychains.add({ pub: 'pub', derivedFromParentWithSeed: 'derivedFromParentWithSeed' });
scope.done();
});
it('should add a safe child keychain with derivedFromParentWithPath', async function () {
const scope = nock(bgUrl)
.post('/api/v2/tltc/key', function (body) {
body.pub.should.equal('pub');
body.parent.should.equal('parent-key-id');
body.safeId.should.equal('safe-id');
body.derivedFromParentWithPath.should.equal("m/7'");
should.equal(body.path, undefined);
should.equal(body.derivedFromParentWithSeed, undefined);
return true;
})
.reply(200, { id: 'child-key-id', derivedFromParentWithPath: "m/7'", path: '/0/0' });
const result = await keychains.add({
pub: 'pub',
parent: 'parent-key-id',
safeId: 'safe-id',
derivedFromParentWithPath: "m/7'",
});
result.derivedFromParentWithPath.should.equal("m/7'");
scope.done();
});
});
/**
* This section's intention is to provide some key generation sanity checking. generateKeyPair is a general surface
* for key generation but the keys are treated the same by BitGo down the line. Any SECP256K1 based coins key-pairs can
* be re-used so need to be the same.
**/
describe('Key generation enforcement for SECP256K1', function () {
// iterate over non-fiat crypto secp coins
const coinFamilyValues = Object.keys(statics_1.CoinFamily).map((n) => n.toLowerCase());
const cryptoSecpCoins = statics_1.coins.filter((n) => n.primaryKeyCurve === statics_1.KeyCurve.Secp256k1 &&
n.kind === statics_1.CoinKind.CRYPTO &&
n.asset !== statics_1.UnderlyingAsset.USD &&
n.asset !== statics_1.UnderlyingAsset.AVAXP &&
n.asset !== statics_1.UnderlyingAsset.APECHAIN &&
n.asset !== statics_1.UnderlyingAsset.DOGE &&
n.asset !== statics_1.UnderlyingAsset.ETHW &&
n.asset !== statics_1.UnderlyingAsset.KAVACOSMOS &&
n.asset !== statics_1.UnderlyingAsset.COREUM &&
n.asset !== statics_1.UnderlyingAsset.BERA &&
n.asset !== statics_1.UnderlyingAsset.ISLM &&
n.asset !== statics_1.UnderlyingAsset.ARBETH && // TODO(WIN-692): remove this once coin-specific module for arbeth is added
n.asset !== statics_1.UnderlyingAsset.OPETH && // TODO(WIN-692): remove this once coin-specific module for opeth is added
n.asset !== statics_1.UnderlyingAsset.ZKETH && // TODO(WIN-1427): remove this once coin-specific module for zketh is added
n.asset !== statics_1.UnderlyingAsset.OAS && // TODO(WIN-3696): remove this once coin-specific module for oas is added
n.asset !== statics_1.UnderlyingAsset.COREDAO && // TODO(WIN-3696): remove this once coin-specific module for coredao is added
n.asset !== statics_1.UnderlyingAsset.FLR && // TODO(WIN-4215): remove this once coin-specific module for FLR is added
n.asset !== statics_1.UnderlyingAsset.SGB && // TODO(WIN-4216): remove this once coin-specific module for SGB is added
n.asset !== statics_1.UnderlyingAsset.WEMIX && // TODO(WIN-4177): remove this once coin-specific module for WEMIX is added
n.asset !== statics_1.UnderlyingAsset.XDC && // TODO(WIN-4173): remove this once coin-specific module for XDC is added
n.asset !== statics_1.UnderlyingAsset.RUNE &&
n.asset !== statics_1.UnderlyingAsset.BABY &&
n.asset !== statics_1.UnderlyingAsset.ICP &&
n.asset !== statics_1.UnderlyingAsset.MANTRA &&
n.asset !== statics_1.UnderlyingAsset.MON &&
n.asset !== statics_1.UnderlyingAsset.OG &&
n.asset !== statics_1.UnderlyingAsset.WORLD &&
n.asset !== statics_1.UnderlyingAsset.PHRS &&
n.asset !== statics_1.UnderlyingAsset.CTC &&
n.asset !== statics_1.UnderlyingAsset.HYPEEVM &&
n.asset !== statics_1.UnderlyingAsset.XPL &&
n.asset !== statics_1.UnderlyingAsset.SONEIUM &&
n.asset !== statics_1.UnderlyingAsset.VET &&
n.asset !== statics_1.UnderlyingAsset.CRONOS &&
n.asset !== statics_1.UnderlyingAsset.FETCHAI &&
n.asset !== statics_1.UnderlyingAsset.INITIA &&
n.asset !== statics_1.UnderlyingAsset.ASI &&
n.asset !== statics_1.UnderlyingAsset.SONIC &&
n.asset !== statics_1.UnderlyingAsset.SEIEVM &&
n.asset !== statics_1.UnderlyingAsset.KAIA &&
n.asset !== statics_1.UnderlyingAsset.IRYS &&
n.asset !== statics_1.UnderlyingAsset.LINEAETH &&
n.asset !== statics_1.UnderlyingAsset.IP && // Data Network
n.asset !== statics_1.UnderlyingAsset.BASEETH &&
n.asset !== statics_1.UnderlyingAsset.SOMI &&
n.asset !== statics_1.UnderlyingAsset.FLRP &&
n.asset !== statics_1.UnderlyingAsset.FLUENTETH &&
n.asset !== statics_1.UnderlyingAsset.MANTLE &&
n.asset !== statics_1.UnderlyingAsset.H &&
n.asset !== statics_1.UnderlyingAsset.HOODETH &&
n.asset !== statics_1.UnderlyingAsset.HPPETH &&
n.asset !== statics_1.UnderlyingAsset.JOVAYETH &&
n.asset !== statics_1.UnderlyingAsset.OKBXLAYER &&
n.asset !== statics_1.UnderlyingAsset.UNIETH &&
n.asset !== statics_1.UnderlyingAsset.MORPH &&
n.asset !== statics_1.UnderlyingAsset.MORPHETH &&
n.asset !== statics_1.UnderlyingAsset.DOGEOS &&
n.asset !== statics_1.UnderlyingAsset.MEGAETH &&
n.asset !== statics_1.UnderlyingAsset.ARCUSDC &&
n.asset !== statics_1.UnderlyingAsset.ZKSYNCERA &&
n.asset !== statics_1.UnderlyingAsset.HYPERLIQUID &&
n.asset !== statics_1.UnderlyingAsset.BOBAETH &&
coinFamilyValues.includes(n.name));
const expectedXpub = 'xpub661MyMwAqRbcGpZf8mxNWhSPdWaLGvQzzage6vq2oQFzq8toVzmkjygYZ3HcZw6eCzAfn9ZdyGjKoKkcpKwackdgznVbiunpq7rkxDu7quS';
const expectedXprv = 'xprv9s21ZrQH143K4LVC2kRN9ZVf5UjqsTh9dMm3JYRRF4j1xLZexTTWCBN4hmdZUHeT3vCJPL181ErVaY489ArBKSWaB7Du7vyVS6XC43WtK7A';
const seed = Buffer.from('this is some random seed we will use', 'utf-8');
cryptoSecpCoins.forEach((coin) => {
it(`should create the same ${coin.name} key with the same seed`, function () {
const currentCoin = bitgo.coin(coin.name);
const keyPair = currentCoin.generateKeyPair(seed);
should.exist(keyPair.pub);
should.exist(keyPair.prv);
keyPair.pub.should.equal(expectedXpub);
keyPair.prv.should.equal(expectedXprv);
});
});
});
describe('Update Password', function () {
const oldPassword = 'oldPassword';
const newPassword = 'newPassword';
const otherPassword = 'otherPassword';
describe('should fail', function () {
let sandbox;
beforeEach(function () {
sandbox = sinon.createSandbox();
});
afterEach(function () {
sandbox.restore();
});
it('to update the password', async function () {
await keychains
.updatePassword({ newPassword: '5678' })
.should.be.rejectedWith('Missing parameter: oldPassword');
await keychains
.updatePassword({ oldPassword: 1234, newPassword: '5678' })
.should.be.rejectedWith('Expecting parameter string: oldPassword but found number');
await keychains
.updatePassword({ oldPassword: '1234' })
.should.be.rejectedWith('Missing parameter: newPassword');
await keychains
.updatePassword({ oldPassword: '1234', newPassword: 5678 })
.should.be.rejectedWith('Expecting parameter string: newPassword but found number');
});
it('to update the password for a single keychain', async function () {
(() => keychains.updateSingleKeychainPassword({ newPassword: '5678' })).should.throw('expected old password to be a string');
(() => keychains.updateSingleKeychainPassword({ oldPassword: 1234, newPassword: '5678' })).should.throw('expected old password to be a string');
(() => keychains.updateSingleKeychainPassword({ oldPassword: '1234' })).should.throw('expected new password to be a string');
(() => keychains.updateSingleKeychainPassword({ oldPassword: '1234', newPassword: 5678 })).should.throw();
(() => keychains.updateSingleKeychainPassword({ oldPassword: '1234', newPassword: '5678' })).should.throw('expected keychain to be an object with an encryptedPrv property');
(() => keychains.updateSingleKeychainPassword({
oldPassword: '1234',
newPassword: '5678',
keychain: {},
})).should.throw('expected keychain to be an object with an encryptedPrv property');
(() => keychains.updateSingleKeychainPassword({
oldPassword: '1234',
newPassword: '5678',
keychain: { encryptedPrv: 123 },
})).should.throw('expected keychain to be an object with an encryptedPrv property');
const keychain = { encryptedPrv: await bitgo.encrypt({ input: 'xprv1', password: otherPassword }) };
(() => keychains.updateSingleKeychainPassword({ oldPassword, newPassword, keychain })).should.throw('password used to decrypt keychain private key is incorrect');
});
it('to update the password for a single keychain (async)', async function () {
await keychains
.updateSingleKeychainPassword({ newPassword: '5678' })
.should.be.rejectedWith('expected old password to be a string');
await keychains
.updateSingleKeychainPassword({ oldPassword: 1234, newPassword: '5678' })
.should.be.rejectedWith('expected old password to be a string');
await keychains
.updateSingleKeychainPassword({ oldPassword: '1234' })
.should.be.rejectedWith('expected new password to be a string');
await keychains
.updateSingleKeychainPassword({ oldPassword: '1234', newPassword: 5678 })
.should.be.rejectedWith('expected new password to be a string');
await keychains
.updateSingleKeychainPassword({ oldPassword: '1234', newPassword: '5678' })
.should.be.rejectedWith('expected keychain to be an object with an encryptedPrv property');
await keychains
.updateSingleKeychainPassword({ oldPassword: '1234', newPassword: '5678', keychain: {} })
.should.be.rejectedWith('expected keychain to be an object with an encryptedPrv property');
await keychains
.updateSingleKeychainPassword({
oldPassword: '1234',
newPassword: '5678',
keychain: { encryptedPrv: 123 },
})
.should.be.rejectedWith('expected keychain to be an object with an encryptedPrv property');
// wrong password — decrypt fails
const keychain = { encryptedPrv: await bitgo.encrypt({ input: 'xprv1', password: otherPassword }) };
await keychains
.updateSingleKeychainPassword({ oldPassword, newPassword, keychain })
.should.be.rejectedWith('failed to update keychain password: incorrect password');
// invalid JSON in encryptedPrv
await keychains
.updateSingleKeychainPassword({ oldPassword, newPassword, keychain: { encryptedPrv: 'not-valid-json' } })
.should.be.rejectedWith('failed to update keychain password: decrypt: ciphertext is not valid JSON');
// unknown envelope version
const unknownVersionEnvelope = JSON.stringify({ v: 99, ct: 'abc' });
await keychains
.updateSingleKeychainPassword({
oldPassword,
newPassword,
keychain: { encryptedPrv: unknownVersionEnvelope },
})
.should.be.rejectedWith('failed to update keychain password: decrypt: unknown envelope version 99');
});
it('on any other error', async function () {
const encXprv1 = await bitgo.encrypt({ input: 'xprv1', password: oldPassword });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
keys: [
{
pub: 'xpub1',
encryptedPrv: encXprv1,
},
],
});
sandbox.stub(keychains, 'updateSingleKeychainPassword').throws('error', 'some random error');
await keychains.updatePassword({ oldPassword, newPassword }).should.be.rejectedWith('some random error');
});
});
describe('successful password update', function () {
const validateKeys = async function (keys, newPassword, expectedLength) {
assert.ok(Object.keys(keys).length === expectedLength, 'should have the expected number of keys');
for (const [key, value] of Object.entries(keys)) {
assert.ok(key.includes('xpub') || key.includes('randomid'), 'key should be xpub or randomid');
const decryptedPrv = await bitgo.decrypt({ input: value, password: newPassword });
decryptedPrv.should.startWith('xprv');
}
};
it('receive only one page when listing keychains', async function () {
const encXprv1 = await bitgo.encrypt({ input: 'xprv1', password: oldPassword });
const encXprv2 = await bitgo.encrypt({ input: 'xprv2', password: otherPassword });
const encXprv3 = await bitgo.encrypt({ input: 'xprv3', password: oldPassword });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
keys: [
{
pub: 'xpub1',
encryptedPrv: encXprv1,
},
{
pub: 'xpub2',
encryptedPrv: encXprv2,
},
{
id: 'randomid1',
type: 'tss',
encryptedPrv: encXprv3,
},
],
});
const keys = await keychains.updatePassword({ oldPassword: oldPassword, newPassword: newPassword });
await validateKeys(keys, newPassword, 2);
});
it('receive multiple pages when listing keychains', async function () {
const prevId = 'prevId';
const encXprv1 = await bitgo.encrypt({ input: 'xprv1', password: oldPassword });
const encXprv2 = await bitgo.encrypt({ input: 'xprv2', password: otherPassword });
const encXprv3a = await bitgo.encrypt({ input: 'xprv3', password: oldPassword });
const encXprv3b = await bitgo.encrypt({ input: 'xprv3', password: oldPassword });
const encXprv4 = await bitgo.encrypt({ input: 'xprv4', password: otherPassword });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
nextBatchPrevId: prevId,
keys: [
{
pub: 'xpub1',
encryptedPrv: encXprv1,
},
{
pub: 'xpub2',
encryptedPrv: encXprv2,
},
{
id: 'randomid1',
type: 'tss',
encryptedPrv: encXprv3a,
},
],
});
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(function queryNextPageMatch(queryObject) {
return queryObject.prevId === prevId;
})
.reply(200, {
keys: [
{
pub: 'xpub3',
encryptedPrv: encXprv3b,
},
{
pub: 'xpub4',
encryptedPrv: encXprv4,
},
],
});
const keys = await keychains.updatePassword({ oldPassword: oldPassword, newPassword: newPassword });
await validateKeys(keys, newPassword, 3);
});
it('single keychain password update', async () => {
const prv = 'xprvtest';
const keychain = {
xpub: 'xpub123',
encryptedPrv: await bitgo.encrypt({ input: prv, password: oldPassword }),
};
const newKeychain = await keychains.updateSingleKeychainPassword({ keychain, oldPassword, newPassword });
const decryptedPrv = await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: newPassword });
decryptedPrv.should.equal(prv);
});
it('single keychain password update emits a v2 (Argon2id) envelope for a v2 input', async () => {
const prv = 'xprvtest-v2';
const encryptedPrv = await bitgo.encrypt({ input: prv, password: oldPassword, encryptionVersion: 2 });
const envelope = JSON.parse(encryptedPrv);
envelope.v.should.equal(2, 'pre-condition: keychain must be v2-encrypted');
const keychain = { xpub: 'xpub123', encryptedPrv };
const newKeychain = await keychains.updateSingleKeychainPassword({ keychain, oldPassword, newPassword });
const newEnvelope = JSON.parse(newKeychain.encryptedPrv);
newEnvelope.v.should.equal(2, 're-encrypted keychain must still be v2');
const decryptedPrv = await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: newPassword });
decryptedPrv.should.equal(prv, 'new password must decrypt to original prv');
await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: oldPassword }).should.be.rejected();
});
it('single keychain password update preserves a v1 (SJCL) envelope by default', async () => {
const prv = 'xprvtest-v1';
const encryptedPrv = await bitgo.encrypt({ input: prv, password: oldPassword, encryptionVersion: 1 });
JSON.parse(encryptedPrv).should.not.have.property('v', 2, 'pre-condition: input must not be v2');
const keychain = { xpub: 'xpub123', encryptedPrv };
const newKeychain = await keychains.updateSingleKeychainPassword({ keychain, oldPassword, newPassword });
JSON.parse(newKeychain.encryptedPrv).should.not.have.property('v', 2, 'v1 keychain must stay v1 by default');
const decryptedPrv = await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: newPassword });
decryptedPrv.should.equal(prv, 'new password must decrypt to original prv');
await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: oldPassword }).should.be.rejected();
});
it('single keychain password update upgrades a v1 envelope to v2 when encryptionVersion: 2 is passed', async () => {
const prv = 'xprvtest-v1-opt-in';
const encryptedPrv = await bitgo.encrypt({ input: prv, password: oldPassword, encryptionVersion: 1 });
const keychain = { xpub: 'xpub123', encryptedPrv };
const newKeychain = await keychains.updateSingleKeychainPassword({
keychain,
oldPassword,
newPassword,
encryptionVersion: 2,
});
JSON.parse(newKeychain.encryptedPrv).v.should.equal(2, 'v2 opt-in must emit a v2 envelope');
const decryptedPrv = await bitgo.decrypt({ input: newKeychain.encryptedPrv, password: newPassword });
decryptedPrv.should.equal(prv, 'new password must decrypt to original prv');
});
it("updatePassword preserves each keychain's existing envelope version by default", async function () {
const v1Prv = 'xprv-v1';
const v2Prv = 'xprv-v2';
const encV1 = await bitgo.encrypt({ input: v1Prv, password: oldPassword, encryptionVersion: 1 });
const encV2 = await bitgo.encrypt({ input: v2Prv, password: oldPassword, encryptionVersion: 2 });
const encOther = await bitgo.encrypt({ input: 'xprv-other', password: 'different-password' });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
keys: [
{
pub: 'xpub-v1',
encryptedPrv: encV1,
},
{
pub: 'xpub-v2',
encryptedPrv: encV2,
},
{
pub: 'xpub-other',
encryptedPrv: encOther,
},
],
});
const updatedKeys = await keychains.updatePassword({ oldPassword, newPassword });
assert.strictEqual(Object.keys(updatedKeys).length, 2, 'only the two matching keychains should be updated');
const updatedV1 = updatedKeys['xpub-v1'];
const updatedV2 = updatedKeys['xpub-v2'];
assert.ok(updatedV1, 'v1 keychain must be in the result');
assert.ok(updatedV2, 'v2 keychain must be in the result');
JSON.parse(updatedV1).should.not.have.property('v', 2, 'v1 keychain must stay v1 by default');
const decryptedV1 = await bitgo.decrypt({ input: updatedV1, password: newPassword });
decryptedV1.should.equal(v1Prv);
JSON.parse(updatedV2).v.should.equal(2, 'v2 keychain must remain v2 after password change');
const decryptedV2 = await bitgo.decrypt({ input: updatedV2, password: newPassword });
decryptedV2.should.equal(v2Prv);
});
it('should return the updated keys with ids', async function () {
const encXprv1 = await bitgo.encrypt({ input: 'xprv1', password: oldPassword });
const encXprv2 = await bitgo.encrypt({ input: 'xprv2', password: otherPassword });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
keys: [
{
id: 'randomid1',
type: 'tss',
encryptedPrv: encXprv1,
},
{
id: 'randomid2',
type: 'tss',
encryptedPrv: encXprv2,
},
],
});
const keys = await keychains.updatePassword({ oldPassword: oldPassword, newPassword: newPassword });
await validateKeys(keys, newPassword, 1);
});
it('should update multi-user-ofc keys', async function () {
const encXprv1 = await bitgo.encrypt({ input: 'xprv1', password: oldPassword });
const encXprv2 = await bitgo.encrypt({ input: 'xprv2', password: otherPassword });
nock(bgUrl)
.get('/api/v2/tltc/key')
.query(true)
.reply(200, {
keys: [
{
id: 'randomid1',
encryptedPrv: encXprv1,
coinSpecific: {
ofc: {
features: ['multi-user-key'],
},
},
},
{
id: 'randomid2',
encryptedPrv: encXprv2,
coinSpecific: {
ofc: {
features: ['multi-user-key'],
},
},
},
],
});
const keys = await keychains.updatePassword({ oldPassword: oldPassword, newPassword: newPassword });
await validateKeys(keys, newPassword, 1);
});
});
describe('Create TSS Keychains', function () {
const stubbedKeychainsTriplet = {
userKeychain: {
id: '1',
pub: 'userPub',
},
backupKeychain: {
id: '2',
pub: 'userPub',
},
bitgoKeychain: {
id: '3',
pub: 'userPub',
},
};
let sandbox;
beforeEach(function () {
sandbox = sinon.createSandbox();
});
afterEach(function () {
sandbox.restore();
});
['tsol', 'tdot', 'tnear'].forEach((coin) => {
it('should create EDDSA TSS Keychains', async function () {
sandbox.stub(sdk_core_1.EDDSAUtils.default.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
const keychains = await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise',
originalPasscodeEncryptionCode: 'originalPasscodeEncryptionCode',
});
keychains.should.deepEqual(stubbedKeychainsTriplet);
});
});
['tbsc'].forEach((coin) => {
it('should create ECDSA TSS Keychains', async function () {
nock(bgUrl).get('/api/v2/tss/settings').query(true).reply(200, {
coinSettings: {},
});
sandbox.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
const keychains = await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise',
originalPasscodeEncryptionCode: 'originalPasscodeEncryptionCode',
});
keychains.should.deepEqual(stubbedKeychainsTriplet);
});
});
['tsol'].forEach((coin) => {
it('should forward the enterprise param on the GET /tss/settings call', async function () {
// Exact query match (not .query(true)) — this only passes if `enterprise` is actually
// forwarded on the request, proving WCI-1358's fix rather than just tolerating it.
const tssSettingsNock = nock(bgUrl)
.get('/api/v2/tss/settings')
.query({ enterprise: 'enterprise-123' })
.reply(200, { coinSettings: {} });
sandbox.stub(sdk_core_1.EDDSAUtils.default.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise-123',
originalPasscodeEncryptionCode: 'originalPasscodeEncryptionCode',
});
tssSettingsNock.isDone().should.be.true();
});
});
['tsol'].forEach((coin) => {
it('should send no enterprise query param on GET /tss/settings when enterprise is not supplied', async function () {
const tssSettingsNock = nock(bgUrl).get('/api/v2/tss/settings').reply(200, { coinSettings: {} });
sandbox.stub(sdk_core_1.EDDSAUtils.default.prototype, 'createKeychains').resolves(stubbedKeychainsTriplet);
await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
originalPasscodeEncryptionCode: 'originalPasscodeEncryptionCode',
});
tssSettingsNock.isDone().should.be.true();
});
});
['tsol'].forEach((coin) => {
it('should pass webauthnInfo to createKeychains for EDDSA TSS', async function () {
const webauthnInfo = {
otpDeviceId: 'device-1',
prfSalt: 'salt-1',
passphrase: 'prf-derived-passphrase',
};
const createKeychains = sandbox
.stub(sdk_core_1.EDDSAUtils.default.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise',
webauthnInfo,
});
createKeychains.calledOnce.should.be.true();
createKeychains.firstCall.args[0].should.have.property('webauthnInfo', webauthnInfo);
});
});
['tbsc'].forEach((coin) => {
it('should reject safe root creation when the resolved ceremony is legacy MPCv1', async function () {
nock(bgUrl).get('/api/v2/tss/settings').query(true).reply(200, {
coinSettings: {},
});
const createKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
await bitgo
.coin(coin)
.keychains()
.createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise',
safeId: 'safeId',
})
.should.be.rejectedWith(/legacy MPCv1 ceremony/);
createKeychains.called.should.be.false();
});
});
['tbsc'].forEach((coin) => {
it('should pass webauthnInfo to createKeychains for ECDSA TSS', async function () {
nock(bgUrl).get('/api/v2/tss/settings').query(true).reply(200, {
coinSettings: {},
});
const webauthnInfo = {
otpDeviceId: 'device-1',
prfSalt: 'salt-1',
passphrase: 'prf-derived-passphrase',
};
const createKeychains = sandbox
.stub(sdk_core_1.ECDSAUtils.EcdsaUtils.prototype, 'createKeychains')
.resolves(stubbedKeychainsTriplet);
await bitgo.coin(coin).keychains().createMpc({
multisigType: 'tss',
passphrase: 'password',
enterprise: 'enterprise',
webauthnInfo,
});
createKeychains.calledOnce.should.be.true();
createKeychains.firstCall.args[0].should.have.property('webauthnInfo', webauthnInfo);
});
});
});
describe('Recreate Keychains from MPCV1 to MPCV2', async function () {
const coin = 'hteth';
const walletId = 'walletId';
const otp = '000000';
const sandbox = sinon.createSandbox();
const decryptResult = JSON.stringify({ key: 'decrypted' });
beforeEach(function () {
nock(bgUrl)
.get('/api/v2/tss/settings')
.query(true)
.reply(200, {
coinSettings: {
eth: {
walletCreationSettings: {
multiSigTypeVersion: 'MPCv2',
},
},
},
});
sandbox.stub(bitgo, 'decrypt').resolves(decryptResult);
});
afterEach(function () {
sandbox.restore();
nock.cleanAll();
});
it('should fail if empty strings are provided', async function () {
const params = {
coin,
walletId,
otp,
passphrase: 'password',
enterprise: 'enterprise',
encryptedMaterial: {
encryptedUserKey: 'encrypted',
encryptedBackupKey: 'encrypted',
encryptedWalletPassphrase: 'passphrase',
},
};
await keychains.recreateMpc({ ...params, coin: '' }).should.be.rejectedWith('missing required param coin');
await keychains
.recreateMpc({ ...params, walletId: '' })
.should.be.rejectedWith('missing required param walletId');
await keychains.recreateMpc({ ...params, otp: '' }).should.be.rejectedWith('missing required param otp');
await keychains
.recreateMpc({ ...params, passphrase: '' })
.should.be.rejectedWith('missing required param passphrase');
await keychains
.recreateMpc({
...params,
encryptedMaterial: {
...params.encryptedMaterial,
encryptedWalletPassphrase: '',
},
})
.should.be.rejectedWith('missing required param encryptedWalletPassphrase');
await keychains
.recreateMpc({
...params,
encryptedMaterial: {
...params.encryptedMaterial,
encryptedUserKey: '',
},
})
.should.be.rejectedWith('missing required param encryptedUserKey');
await keychains
.recreateMpc({
...params,
encryptedMaterial: {
...params.encryptedMaterial,
encryptedBackupKey: '',
},
})
.should.be.rejectedWith('missing required param encryptedBackupKey');
});
it('should fail if otp unlock fails', async function () {
nock(bgUrl).post('/api/v1/user/unlock').replyWithError('otp error');
const params = {
coin,
walletId,
otp,
passphrase: 'password',
encryptedMaterial: {
encryptedUserKey: 'encryptedUserKey',
encryptedBackupKey: 'encryptedBackupKey',
encryptedWalletPassphrase: 'encryptedWalletPassphrase',
},
};
await keychains.recreateMpc(params).should.be.rejectedWith('otp error');
});
it('should fail if passcode recovery api call fails', async function () {
nock(bgUrl).post('/api/v1/user/unlock').reply(200, { otp });
nock(bgUrl)
.post(`/api/v2/${coin}/wallet/${walletId}/passcoderecovery`)
.replyWithError('passcode recovery error');
const params = {
coin,
walletId,
otp,
passphrase: 'password',
encryptedMaterial: {
encryptedUserKey: 'encryptedUserKey',
encryptedBackupKey: 'encryptedBackupKey',
encryptedWalletPassphrase: 'encryptedWalletPassphrase',
},
};
await keychains.recreateMpc(params).should.be.rejectedWith('passcode recovery error');
});
it('should fail if passcode recovery api call returns invalid recovery info', async function () {
nock(bgUrl).post('/api/v1/user/unlock').reply(200, { otp });
nock(bgUrl).post(`/api/v2/${coin}/wallet/${walletId}/passcoderecovery`).reply(200, { recoveryInfo: {} });
const params = {
coin,
walletId,
otp,
passphrase: 'password',
encryptedMaterial: {
encryptedUserKey: 'encryptedUserKey',
encryptedBackupKey: 'encryptedBackupKey',
encryptedWalletPassphrase: 'encryptedWalletPassphrase',
},
};
await keychains.recreateMpc(params).should.be.rejectedWith('failed to get recovery info');
});
it('should call createMpc with the correct parameters', async function () {
nock(bgUrl).post('/api/v1/user/unlock').reply(200, { otp });
nock(bgUrl)
.post(`/api/v2/${coin}/wallet/${walletId}/passcoderecovery`)
.reply(200, { recoveryInfo: { passcodeEncryptionCode: '123' } });
const params = {
coin,
walletId: 'walletId',
otp,
passphrase: 'password',
enterprise: 'enterprise',
originalPasscodeEncryptionCode: 'originalPasscodeEncryptionCode',
encryptedMaterial: {
encryptedUserKey: 'encryptedUserKey',
encryptedBackupKey: 'encryptedBackupKey',
encryptedWalletPassphrase: 'encryptedWalletPassphrase',
},
};
const createMpcStub = sinon.stub(keychains, 'createMpc').resolves();
await keychains.recreateMpc(params);
assert.ok(createMpcStub.calledOnceWith({
...params,
multisigType: 'tss',
retrofit: {
decryptedUserKey: decryptResult,
decryptedBackupKey: decryptResult,
walletId: params.walletId,
},
}));
});
});
after(function afterUpdatePassword() {
nock.pendingMocks().should.be.empty();
});
});
describe('Create BitGo Key from OVC JSON', function () {
const bitGoKeyResult = {
id: '6421eb755fea9e0006c2c040072f74bb',
commonKeychain: '123',
walletHSMGPGPublicKeySigs: '123',
verifiedVssProof: true,
keyShares: [
{
from: 'bitgo',
to: 'user',
publicShare: 'ccc',
privateShare: 'ccc private',
paillierPublicKey: 'ccc paillier',
vssProof: 'ccc vss proof',
},
{
from: 'bitgo',
to: 'backup',
publicShare: 'fff',
privateShare: 'fff private',
paillierPublicKey: 'fff paillier',
vssProof: 'fff vss proof',
},
],
};
const ovcOutputJson = {
tssVersion: '0.0.1',
walletType: 'tss',
coin: 'sol',
state: 1,
ovc: {
1: {
gpgPubKey: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7o\n=vjgl\n-----END PGP PUBLIC KEY BLOCK-----\n',
ovcToBitgoShare: {
publicShare: '07bfbb052a1f4b106b315bd5a9d6a71604653289f861320d9801881e952f8550753c89511a360e3b599d9f239a8d36a4956437ed0b152180e22cb94fb08fdc81',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEd/wQ/AhwIRsSf/6iHwmHKvEYAwfaLtTQotS6BwZm\naX00T7LumGIrNZzBgcggBKMl+8Omom8mX5sP8FUE451iZjBmXlkpHlpAqskS\nEi5SfjlsT31utoLaBLA7NjNSmyYHIiyfh6YnwfV5U72k6hhfpuDSsQGy8Yxp\nM2dVlN4uoO31zgQPf+fgJkZvAPwvjYLBL4O8hs21HGf0VvG99brk4xlFVRhw\nQnuPpM51GOs4vUtbLNSYnAuhU4ReXwwDV9Xu0MXAjfQMk2E3wQLGQ+82uv2B\n1hPD9nDHTtAdWrXd6ZjXFrG4Mf2MQBxySFvVSnFi6yStjfZeiKcD5Vg38PjG\nWg1O5N3/paq98HfH0Q4qNKGZljwo3oEQZzlYm2kVnI0PULoMYg==\n=ovAx\n-----END PGP MESSAGE-----\n',
vssProof: 'be8198c2cef94cb381aa8aa9277a0a46ba5a54b0ac9930034b4af66b1b805234',
i: 3,
j: 1,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7ozjMEZBsq\n9RYJKwYBBAHaRw8BAQdAS1534LdCC60ASpEgnEBC8pWPSOWWBLXyWaBhEOW2\n/ijCeAQYEwgACQUCZBsq9QIbIAAhCRDlHgu0Kxi/thYhBIzerz1BUcHlbQyh\nWeUeC7QrGL+2FUYA/AgMU4V7C7I/5HwK73mctaGXNdfVr/muRMNOGW/CAxVL\nAP9KaBr95o32oEN5eo7tWFByoOCCk9JMjs36Cq7o+sR31A==\n=eZ3B\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
},
2: {
gpgPubKey: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh2w==\n=Ettu\n-----END PGP PUBLIC KEY BLOCK-----\n',
ovcToBitgoShare: {
publicShare: 'ecf95e9ba6f02c0bc4c2ab254565d21a1562059c8a1ab70d286fa04ae2c511e0491410b6d6fa8ab22e691bed7938a7adaabfa8d9d59aab9cc2c078cd37dde01b',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEe1nYNv9DnHl8HX8jNs3reGs5nPT2bNzGMCFL0N3P\nKLwGd8DBkDJIMpoClaAS/HTUTPTRzj4U1GShV79I+bbfTDBV6uhyfZ7a88dV\nRDTXl6rchFl/fmwLoXnqH+BDPEXytpAvKwDrAg55T/H7aop5QbfSsQErEv7X\nTpTLHHHflEEQL62p1Rnnq2kKvwJK7TY1g5RtPgYXH6GEs33DLulPeUs8UkKq\nTPLf2+1KCLYyzMwmSi8KEC8HJb0vAkXZAlZ1+DoZ2PfiIJcVnz7a3omjiP77\nhmC8phTcJ718UxIB09f8uic0/fM7FNu0JHFgRDA69zzeFYnZc2XNQg5hs/dZ\nZ8AitP4rnaAfprsq4rAEE/c3Trm9tzQHZPCqr/2s4LluyUMVJw==\n=IJZH\n-----END PGP MESSAGE-----\n',
vssProof: '309d2fef2272ad31375954b99a862742f22d8023eef9855b8ae26ea84e08bf5e',
i: 3,
j: 2,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh284z\nBGQbKzQWCSsGAQQB2kcPAQEHQIVTmlt8a/fjJCY9UyP8J51eTPX9PMRF3/Hr\nBYwtfOZYwngEGBMIAAkFAmQbKzQCGyAAIQkQtgJORtkpO2UWIQS06UpBTnt2\no26qLnq2Ak5G2Sk7ZcthAQD4ek3aqUDEbhfRHolm4jFhIPIbb9hUJwuBR0R4\n+gvaeAEAk8uk5cEACeqmpdEF52oGx7jmGCoX73AIILYVcf9iMkI=\n=92Hf\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
ovcToOvcShare: {
publicShare: 'ecf95e9ba6f02c0bc4c2ab254565d21a1562059c8a1ab70d286fa04ae2c511e0491410b6d6fa8ab22e691bed7938a7adaabfa8d9d59aab9cc2c078cd37dde01b',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4D+F3vI962zVMSAgMENy2X9xDIOm1gwOfMdL/1vZjeMW/ile/f2dRIP2GV\nv4w60K92+mHI9yooU1VT77jZrVOcNK41DFNCF/fuoUU+VzBON0I1hHyXm2QJ\nwL+nNdvAXwRv7nSFD3ABUmRYdG71AFIWjW2L+1C2hxpsNlmdxffSsQHHT9uP\nBNpFYgQN77OUxcgrweSVrPyer1rCQ8o+QnoK2/hIx9PlJZkcl3uwF6TpBtjs\nqvRxThomoHyo0hJHG0vmI42Gq5u0tcSeU902efpCDaeJhPVOiqISoJ96wn0r\nFB3lYLSflOpCLAE7nsZJRoXA6akU7xMCMNA++d4tv6p98FQ+MZ6e9x6kiSw1\nM+VWj+PvN1dtQ8fNYwpJf7KBfD1w6ISMFDmewkDE7iBOXF6FLw==\n=+3Yc\n-----END PGP MESSAGE-----\n',
vssProof: '309d2fef2272ad31375954b99a862742f22d8023eef9855b8ae26ea84e08bf5e',
i: 1,
j: 2,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh284z\nBGQbKzQWCSsGAQQB2kcPAQEHQNVGg0vPsfK1yJjFuDYB8Tj7CQRHKGAVEDcj\nh/QIqr0KwngEGBMIAAkFAmQbKzQCGyAAIQkQtgJORtkpO2UWIQS06UpBTnt2\no26qLnq2Ak5G2Sk7ZS9oAQCe2zJD5ItW2GEgAitnY+NrLBjbXI6+LY29GjRa\nf6yFTQD/cP0E1DleqXMjgfR+ewt6quVFMZebhr3tBr/H0Zv/9EA=\n=8ai+\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
},
},
};
const expectedBitGoOutput = {
wallet: {
...ovcOutputJson,
state: 2,
platform: {
commonKeychain: bitGoKeyResult.commonKeychain,
walletGpgPubKeySigs: bitGoKeyResult.walletHSMGPGPublicKeySigs,
ovc: {
1: {
bitgoToOvcShare: {
i: 1,
j: 3,
publicShare: bitGoKeyResult.keyShares[0].publicShare,
privateShare: bitGoKeyResult.keyShares[0].privateShare,
paillierPublicKey: bitGoKeyResult.keyShares[0].paillierPublicKey,
vssProof: bitGoKeyResult.keyShares[0].vssProof,
},
},
2: {
bitgoToOvcShare: {
i: 2,
j: 3,
publicShare: bitGoKeyResult.keyShares[1].publicShare,
privateShare: bitGoKeyResult.keyShares[1].privateShare,
paillierPublicKey: bitGoKeyResult.keyShares[1].paillierPublicKey,
vssProof: bitGoKeyResult.keyShares[1].vssProof,
},
},
},
},
},
};
it('Parses the OVC JSON file properly and creates the next input for OVC', async function () {
nock(bgUrl)
.post('/api/v2/tsol/key', _.matches({ source: 'bitgo', keyType: 'tss' }))
.reply(200, bitGoKeyResult);
const platformOutput = await bitgo.coin('tsol').keychains().createTssBitGoKeyFromOvcShares(ovcOutputJson);
should.equal(platformOutput.bitGoKeyId, bitGoKeyResult.id);
should.deepEqual(platformOutput.bitGoOutputJsonForOvc, expectedBitGoOutput);
});
it('Passes the enterprise with correct value to bitgo if provided by caller', async function () {
const bitgoNock = nock(bgUrl)
.post('/api/v2/tsol/key', _.matches({ source: 'bitgo', keyType: 'tss' }))
.reply(200, (uri, body) => {
body.should.have.property('enterprise');
body.enterprise.should.equal('enterpriseId');
return bitGoKeyResult;
});
const platformOutput = await bitgo
.coin('tsol')
.keychains()
.createTssBitGoKeyFromOvcShares(ovcOutputJson, 'enterpriseId');
should.equal(platformOutput.bitGoKeyId, bitGoKeyResult.id);
should.deepEqual(platformOutput.bitGoOutputJsonForOvc, expectedBitGoOutput);
bitgoNock.isDone();
});
it('Should fail if the state is not 1', async function () {
const ovcOutputJson = {
tssVersion: '0.0.1',
walletType: 'tss',
coin: 'sol',
state: 0,
ovc: {
1: {
gpgPubKey: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7o\n=vjgl\n-----END PGP PUBLIC KEY BLOCK-----\n',
ovcToBitgoShare: {
publicShare: '07bfbb052a1f4b106b315bd5a9d6a71604653289f861320d9801881e952f8550753c89511a360e3b599d9f239a8d36a4956437ed0b152180e22cb94fb08fdc81',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEd/wQ/AhwIRsSf/6iHwmHKvEYAwfaLtTQotS6BwZm\naX00T7LumGIrNZzBgcggBKMl+8Omom8mX5sP8FUE451iZjBmXlkpHlpAqskS\nEi5SfjlsT31utoLaBLA7NjNSmyYHIiyfh6YnwfV5U72k6hhfpuDSsQGy8Yxp\nM2dVlN4uoO31zgQPf+fgJkZvAPwvjYLBL4O8hs21HGf0VvG99brk4xlFVRhw\nQnuPpM51GOs4vUtbLNSYnAuhU4ReXwwDV9Xu0MXAjfQMk2E3wQLGQ+82uv2B\n1hPD9nDHTtAdWrXd6ZjXFrG4Mf2MQBxySFvVSnFi6yStjfZeiKcD5Vg38PjG\nWg1O5N3/paq98HfH0Q4qNKGZljwo3oEQZzlYm2kVnI0PULoMYg==\n=ovAx\n-----END PGP MESSAGE-----\n',
vssProof: 'be8198c2cef94cb381aa8aa9277a0a46ba5a54b0ac9930034b4af66b1b805234',
i: 3,
j: 1,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7ozjMEZBsq\n9RYJKwYBBAHaRw8BAQdAS1534LdCC60ASpEgnEBC8pWPSOWWBLXyWaBhEOW2\n/ijCeAQYEwgACQUCZBsq9QIbIAAhCRDlHgu0Kxi/thYhBIzerz1BUcHlbQyh\nWeUeC7QrGL+2FUYA/AgMU4V7C7I/5HwK73mctaGXNdfVr/muRMNOGW/CAxVL\nAP9KaBr95o32oEN5eo7tWFByoOCCk9JMjs36Cq7o+sR31A==\n=eZ3B\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
},
2: {
gpgPubKey: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh2w==\n=Ettu\n-----END PGP PUBLIC KEY BLOCK-----\n',
ovcToBitgoShare: {
publicShare: 'ecf95e9ba6f02c0bc4c2ab254565d21a1562059c8a1ab70d286fa04ae2c511e0491410b6d6fa8ab22e691bed7938a7adaabfa8d9d59aab9cc2c078cd37dde01b',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEe1nYNv9DnHl8HX8jNs3reGs5nPT2bNzGMCFL0N3P\nKLwGd8DBkDJIMpoClaAS/HTUTPTRzj4U1GShV79I+bbfTDBV6uhyfZ7a88dV\nRDTXl6rchFl/fmwLoXnqH+BDPEXytpAvKwDrAg55T/H7aop5QbfSsQErEv7X\nTpTLHHHflEEQL62p1Rnnq2kKvwJK7TY1g5RtPgYXH6GEs33DLulPeUs8UkKq\nTPLf2+1KCLYyzMwmSi8KEC8HJb0vAkXZAlZ1+DoZ2PfiIJcVnz7a3omjiP77\nhmC8phTcJ718UxIB09f8uic0/fM7FNu0JHFgRDA69zzeFYnZc2XNQg5hs/dZ\nZ8AitP4rnaAfprsq4rAEE/c3Trm9tzQHZPCqr/2s4LluyUMVJw==\n=IJZH\n-----END PGP MESSAGE-----\n',
vssProof: '309d2fef2272ad31375954b99a862742f22d8023eef9855b8ae26ea84e08bf5e',
i: 3,
j: 2,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh284z\nBGQbKzQWCSsGAQQB2kcPAQEHQIVTmlt8a/fjJCY9UyP8J51eTPX9PMRF3/Hr\nBYwtfOZYwngEGBMIAAkFAmQbKzQCGyAAIQkQtgJORtkpO2UWIQS06UpBTnt2\no26qLnq2Ak5G2Sk7ZcthAQD4ek3aqUDEbhfRHolm4jFhIPIbb9hUJwuBR0R4\n+gvaeAEAk8uk5cEACeqmpdEF52oGx7jmGCoX73AIILYVcf9iMkI=\n=92Hf\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
ovcToOvcShare: {
publicShare: 'ecf95e9ba6f02c0bc4c2ab254565d21a1562059c8a1ab70d286fa04ae2c511e0491410b6d6fa8ab22e691bed7938a7adaabfa8d9d59aab9cc2c078cd37dde01b',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4D+F3vI962zVMSAgMENy2X9xDIOm1gwOfMdL/1vZjeMW/ile/f2dRIP2GV\nv4w60K92+mHI9yooU1VT77jZrVOcNK41DFNCF/fuoUU+VzBON0I1hHyXm2QJ\nwL+nNdvAXwRv7nSFD3ABUmRYdG71AFIWjW2L+1C2hxpsNlmdxffSsQHHT9uP\nBNpFYgQN77OUxcgrweSVrPyer1rCQ8o+QnoK2/hIx9PlJZkcl3uwF6TpBtjs\nqvRxThomoHyo0hJHG0vmI42Gq5u0tcSeU902efpCDaeJhPVOiqISoJ96wn0r\nFB3lYLSflOpCLAE7nsZJRoXA6akU7xMCMNA++d4tv6p98FQ+MZ6e9x6kiSw1\nM+VWj+PvN1dtQ8fNYwpJf7KBfD1w6ISMFDmewkDE7iBOXF6FLw==\n=+3Yc\n-----END PGP MESSAGE-----\n',
vssProof: '309d2fef2272ad31375954b99a862742f22d8023eef9855b8ae26ea84e08bf5e',
i: 1,
j: 2,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsrNBMFK4EEAAoCAwT2xXv/mG/daPdKGD/fHIUEE2ZtcK+njtCZtMEr\nkIubmUwe3Dj8+hQxt3SKaTxQbuD+WaLSj986QYUr4Zw4T+W3zWpvdmMtMi1i\nYWNrdXAtNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4IDxvdmMtMi1iYWNrdXAt\nNTQ3YmJkZjMwOGMxZTYxY2Q5ZGI4NmU4QDU0N2JiZGYzMDhjMWU2MWNkOWRi\nODZlOC5jb20+wowEEBMIAB0FAmQbKzQECwkHCAMVCAoEFgACAQIZAQIbAwIe\nAQAhCRC2Ak5G2Sk7ZRYhBLTpSkFOe3ajbqouerYCTkbZKTtlxtYBALLIBnAa\n4AS77XvXmmznNCWO/HNuDPD2ugRqVhqU4SxmAQDma14APuMNSVyi17xomZjW\n0nimtaMIBjc0A4MXE6G4Xc5TBGQbKzQSBSuBBAAKAgMEUHoQDY98y8CAVouu\ny4y3Q2QnBpnUBK/0PELV7VANXd9lY7CShyogJScgPliUm97Au9FC17vqZa1B\n5bBMJAdXVwMBCAfCeAQYEwgACQUCZBsrNAIbDAAhCRC2Ak5G2Sk7ZRYhBLTp\nSkFOe3ajbqouerYCTkbZKTtlR5wA/3zOFTSeXXRRemXl3hY10spxabE4O2J8\nZD2VRfjbDpZjAQDWg1W+jPbM2Htikd1N01V+zweNDhJEH65r0Qr8BlXh284z\nBGQbKzQWCSsGAQQB2kcPAQEHQNVGg0vPsfK1yJjFuDYB8Tj7CQRHKGAVEDcj\nh/QIqr0KwngEGBMIAAkFAmQbKzQCGyAAIQkQtgJORtkpO2UWIQS06UpBTnt2\no26qLnq2Ak5G2Sk7ZS9oAQCe2zJD5ItW2GEgAitnY+NrLBjbXI6+LY29GjRa\nf6yFTQD/cP0E1DleqXMjgfR+ewt6quVFMZebhr3tBr/H0Zv/9EA=\n=8ai+\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
},
},
};
await bitgo
.coin('tsol')
.keychains()
.createTssBitGoKeyFromOvcShares(ovcOutputJson)
.should.be.rejectedWith('State expected to be "1". Please complete the first two OVC operations');
});
it('Fails to decode if the OVC json is missing fields', async function () {
const ovcOutputJson = {
tssVersion: '0.0.1',
state: 1,
coin: 'tsol',
ovc: {
1: {
gpgPubKey: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7o\n=vjgl\n-----END PGP PUBLIC KEY BLOCK-----\n',
ovcToBitgoShare: {
publicShare: '07bfbb052a1f4b106b315bd5a9d6a71604653289f861320d9801881e952f8550753c89511a360e3b599d9f239a8d36a4956437ed0b152180e22cb94fb08fdc81',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEd/wQ/AhwIRsSf/6iHwmHKvEYAwfaLtTQotS6BwZm\naX00T7LumGIrNZzBgcggBKMl+8Omom8mX5sP8FUE451iZjBmXlkpHlpAqskS\nEi5SfjlsT31utoLaBLA7NjNSmyYHIiyfh6YnwfV5U72k6hhfpuDSsQGy8Yxp\nM2dVlN4uoO31zgQPf+fgJkZvAPwvjYLBL4O8hs21HGf0VvG99brk4xlFVRhw\nQnuPpM51GOs4vUtbLNSYnAuhU4ReXwwDV9Xu0MXAjfQMk2E3wQLGQ+82uv2B\n1hPD9nDHTtAdWrXd6ZjXFrG4Mf2MQBxySFvVSnFi6yStjfZeiKcD5Vg38PjG\nWg1O5N3/paq98HfH0Q4qNKGZljwo3oEQZzlYm2kVnI0PULoMYg==\n=ovAx\n-----END PGP MESSAGE-----\n',
vssProof: 'be8198c2cef94cb381aa8aa9277a0a46ba5a54b0ac9930034b4af66b1b805234',
i: 3,
j: 1,
uSig: '-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxk8EZBsq9RMFK4EEAAoCAwRgDpgm1bptRT5yLOMadcGAHuvkxISL8/3xPy/D\nYA+1NgBqIFK/3OOXxp73Tv86bt1dgH7OD1ACO0mVXAoX5EaVzWZvdmMtMS11\nc2VyLWRmMjQwOWY0NWNhMTZmNTU3OGNkMzAxMyA8b3ZjLTEtdXNlci1kZjI0\nMDlmNDVjYTE2ZjU1NzhjZDMwMTNAZGYyNDA5ZjQ1Y2ExNmY1NTc4Y2QzMDEz\nLmNvbT7CjAQQEwgAHQUCZBsq9QQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJ\nEOUeC7QrGL+2FiEEjN6vPUFRweVtDKFZ5R4LtCsYv7Z7oAEAvNKaJrTIs3ky\nbxjkUicsuxOyA2oWGarJH6TGlWF6WD8A/3EIeZzPKSLaW+3enpbCPiU8RVDp\nC6yo6NMAqKp4XlyQzlMEZBsq9RIFK4EEAAoCAwQWlWPNMpk3afEzfgG0xFg4\nCEjY7fGO35n47nZ4qxjEXz2XN4I23xFMiwZbXbptDXlqm7W9ZAHKi892h+Yt\nU4B6AwEIB8J4BBgTCAAJBQJkGyr1AhsMACEJEOUeC7QrGL+2FiEEjN6vPUFR\nweVtDKFZ5R4LtCsYv7YqZwD8DLRuneB0HEzBCyrE4YL+UHaofoHQX1+nRh0j\n82qaDzAA/i3U1SoEIi32YMrorNG50vb4vaEPbbYmfglb+JQ1Yx7ozjMEZBsq\n9RYJKwYBBAHaRw8BAQdAS1534LdCC60ASpEgnEBC8pWPSOWWBLXyWaBhEOW2\n/ijCeAQYEwgACQUCZBsq9QIbIAAhCRDlHgu0Kxi/thYhBIzerz1BUcHlbQyh\nWeUeC7QrGL+2FUYA/AgMU4V7C7I/5HwK73mctaGXNdfVr/muRMNOGW/CAxVL\nAP9KaBr95o32oEN5eo7tWFByoOCCk9JMjs36Cq7o+sR31A==\n=eZ3B\n-----END PGP PUBLIC KEY BLOCK-----\n',
},
},
},
};
await bitgo.coin('tsol').keychains().createTssBitGoKeyFromOvcShares(ovcOutputJson).should.be.rejected();
});
it('OvcShare codec decodes correctly', async function () {
const test = {
publicShare: '07bfbb052a1f4b106b315bd5a9d6a71604653289f861320d9801881e952f8550753c89511a360e3b599d9f239a8d36a4956437ed0b152180e22cb94fb08fdc81',
privateShare: '-----BEGIN PGP MESSAGE-----\n\nwX4DUQ8XhGVGcTISAgMEd/wQ/AhwIRsSf/6iHwmHKvEYAwfaLtTQotS6BwZm\naX00T7LumGIrNZzBgcggBKMl+8Omom8mX5sP8FUE451iZjBmXlkpHlpAqskS\nEi5SfjlsT31utoLaBLA7NjNSmyYHIiyfh6YnwfV5U72k6hhfpuDSsQGy8Yxp\nM2dVlN4uoO31zgQPf+fgJkZvAPwvjYLBL4O8hs21HGf0VvG99brk4xlFVRhw\nQnuPpM51GOs4vUtbLNSYnAuhU4ReXwwDV9Xu0MXAjfQMk2E3wQLGQ+82uv2B\n1hPD9nDHTtAdWrXd6ZjXFrG4Mf2MQBxySFvVSnFi6yStjfZeiKcD5Vg38PjG\nWg1O5N3/paq98HfH0Q4qNKGZljwo3oEQZzlYm2kVnI0PULoMYg==\n=ovAx\n-----END PGP MESSAGE-----\n',
vssProof: 'be8198c2cef94cb381aa8aa9277a0a46ba5a54b0ac9930034b4af66b1b805234',
i: 3,
j: 1,
};
const decodedRes = (0, sdk_core_1.decodeOrElse)(sdk_core_1.OvcShare.name, sdk_core_1.OvcShare, test, (errors) => {
throw new Error(`error(s) parsing parsing json: ${errors}`);
});
assert.ok(decodedRes);
});
});
it('should generate backup without encryptedPrv when passphrase not provided', async () => {
const scope = nock(bgUrl)
.post('/api/v2/tltc/key', (body) => {
return body.encryptedPrv === undefined && body.prv === undefined;
})
.reply(200);
const backup = await keychains.createBackup({});
scope.isDone().should.be.true();
backup.should.not.have.property('encryptedPrv');
backup.should.have.property('prv');
});
it('should generate backup and call endpoint with encryptedPrv when passphrase is provided', async () => {
const scope = nock(bgUrl)
.post('/api/v2/tltc/key', (body) => {
return body.encryptedPrv !== undefined && body.prv === undefined;
})
.reply(200);
const backup = await keychains.createBackup({ passphrase: 't3stSicretly!' });
scope.isDone().should.be.true();
backup.should.have.property('encryptedPrv');
const decryptedPrv = await bitgo.decrypt({ input: backup.encryptedPrv, password: 't3stSicretly!' });
decryptedPrv.should.startWith('xprv');
});
describe('Rotate OFC multi-user-key keychains', function () {
let ofcBaseCoin;
let ofcKeychains;
const mockOfcKeychain = {
id: 'ofcKeychainId',
pub: 'ofcKeychainPub',
encryptedPrv: 'ofcEncryptedPrv',
source: 'user',
coinSpecific: {
ofc: {
features: ['multi-user-key'],
},
},
type: 'tss',
};
let nonOfcBaseCoin;
let nonOfcKeychains;
const mockNonOfcKeychain = {
id: 'nonOfcKeychainId',
pub: 'nonOfcKeychainPub',
source: 'user',
type: 'tss',
};
const mockNewKeypair = {
pub: 'newPub',
prv: 'newPrv',
};
let sandbox;
let updateKeychainStub;
let createKeypairStub;
let encryptionStub;
beforeEach(function () {
ofcBaseCoin = bitgo.coin('ofc');
ofcKeychains = ofcBaseCoin.keychains();
nonOfcBaseCoin = bitgo.coin('hteth');
nonOfcKeychains = nonOfcBaseCoin.keychains();
sandbox = sinon.createSandbox();
updateKeychainStub = sandbox.stub().returns({ result: sandbox.stub().resolves() });
sandbox.stub(bitgo_1.BitGo.prototype, 'put').returns({ send: updateKeychainStub });
createKeypairStub = sandbox.stub(ofcKeychains, 'create').returns(mockNewKeypair);
encryptionStub = sandbox.stub(bitgo_1.BitGo.prototype, 'encrypt').resolves('newEncryptedPrv');
});
afterEach(function () {
sandbox.restore();
});
it('should rotate ofc multi-user-key properly', async function () {
nock(bgUrl).get(`/api/v2/ofc/key/${mockOfcKeychain.id}`).query(true).reply(200, mockOfcKeychain);
await ofcKeychains.rotateKeychain({ id: mockOfcKeychain.id, password: '1234' });
sinon.assert.called(createKeypairStub);
sinon.assert.calledWith(encryptionStub, { input: mockNewKeypair.prv, password: '1234', encryptionVersion: 2 });
sinon.assert.calledWith(updateKeychainStub, {
pub: mockNewKeypair.pub,
encryptedPrv: 'newEncryptedPrv',
reqId: undefined,
});
});
it('should allow user to supply pub and encryptedPrv directly', async function () {
nock(bgUrl).get(`/api/v2/ofc/key/${mockOfcKeychain.id}`).query(true).reply(200, mockOfcKeychain);
await ofcKeychains.rotateKeychain({ id: mockOfcKeychain.id, pub: 'pub', encryptedPrv: 'encryptedPrv' });
sinon.assert.notCalled(createKeypairStub);
sinon.assert.notCalled(encryptionStub);
sinon.assert.calledWith(updateKeychainStub, {
pub: 'pub',
encryptedPrv: 'encryptedPrv',
reqId: undefined,
});
});
it('should throw when trying to rotate non-ofc keychain', async function () {
nock(bgUrl).get(`/api/v2/hteth/key/${mockNonOfcKeychain.id}`).query(true).reply(200, mockNonOfcKeychain);
await assert.rejects(async () => await nonOfcKeychains.rotateKeychain({ id: mockNonOfcKeychain.id, password: '1234' }), (err) => err.message === 'rotateKeychain is only permitted for ofc multi-user-key wallet');
});
});
describe('getEncryptionVersion', function () {
it('returns 1 when the v field is absent', function () {
const envelope = JSON.stringify({ ct: 'cipher', iv: 'iv', s: 'salt' });
keychains.getEncryptionVersion(envelope).should.equal(1);
});
it('returns 1 when v is explicitly 1', function () {
keychains.getEncryptionVersion(JSON.stringify({ v: 1, ct: 'abc' })).should.equal(1);
});
it('returns 2 when v is 2', function () {
keychains.getEncryptionVersion(JSON.stringify({ v: 2, ct: 'abc' })).should.equal(2);
});
it('throws on an unrecognized version number', function () {
assert.throws(() => keychains.getEncryptionVersion(JSON.stringify({ v: 3, ct: 'abc' })), /Unrecognized encryption version: 3/);
});
it('throws when the input is not valid JSON', function () {
assert.throws(() => keychains.getEncryptionVersion('not-json'), /Failed to parse ciphertext envelope/);
});
it('throws when the input is an empty string', function () {
assert.throws(() => keychains.getEncryptionVersion(''), /Failed to parse ciphertext envelope/);
});
it('handles a real SJCL v1 envelope', function () {
const sjcl = JSON.stringify({
iv: 'aaaa',
v: 1,
iter: 10000,
ks: 256,
ts: 64,
mode: 'ccm',
adata: '',
cipher: 'aes',
salt: 'ssss',
ct: 'cccc',
});
keychains.getEncryptionVersion(sjcl).should.equal(1);
});
it('handles a real Argon2id v2 envelope', function () {
const argon2 = JSON.stringify({
v: 2,
ct: 'cccc',
iv: 'iiii',
tag: 'tttt',
salt: 'ssss',
m: 65536,
t: 3,
p: 4,
});
keychains.getEncryptionVersion(argon2).should.equal(2);
});
});
describe('reencryptAsV2', function () {
it('decrypts a v1 envelope with the passphrase and re-encrypts as v2', async function () {
const prv = 'thePrivateKey';
const encryptedV1 = await bitgo.encrypt({ input: prv, password: 'myPass', encryptionVersion: 1 });
JSON.parse(encryptedV1).v.should.equal(1);
const result = await keychains.reencryptAsV2(encryptedV1, 'myPass');
JSON.parse(result).v.should.equal(2);
(await bitgo.decrypt({ input: result, password: 'myPass' })).should.equal(prv);
});
it('accepts a v2 envelope and re-encrypts it as v2 (idempotent)', async function () {
const prv = 'xprv-v2';
const encryptedV2 = await bitgo.encrypt({ input: prv, password: 'pass', encryptionVersion: 2 });
JSON.parse(encryptedV2).v.should.equal(2);
const result = await keychains.reencryptAsV2(encryptedV2, 'pass');
JSON.parse(result).v.should.equal(2);
(await bitgo.decrypt({ input: result, password: 'pass' })).should.equal(prv);
});
it('surfaces decrypt errors directly (no fallback logic in the primitive)', async function () {
const encrypted = await bitgo.encrypt({ input: 'prv', password: 'realPass', encryptionVersion: 1 });
await keychains.reencryptAsV2(encrypted, 'wrongPass').should.be.rejected();
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5Y2hhaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC92Mi91bml0L2tleWNoYWlucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsRUFBRTtBQUNGLHFCQUFxQjtBQUNyQixFQUFFOztBQUVGLDRDQUF3RjtBQUN4RixpQ0FBaUM7QUFDakMsNEJBQTRCO0FBQzVCLDZCQUE4QjtBQUM5QixpQ0FBa0M7QUFDbEMsK0JBQStCO0FBRS9CLDhDQUE4RztBQUM5Ryw4Q0FBNEM7QUFDNUMsOENBQTJDO0FBRzNDLFFBQVEsQ0FBQyxjQUFjLEVBQUU7SUFDdkIsSUFBSSxLQUFLLENBQUM7SUFDVixJQUFJLFFBQVEsQ0FBQztJQUNiLElBQUksU0FBUyxDQUFDO0lBQ2QsSUFBSSxLQUFLLENBQUM7SUFFVixNQUFNLENBQUM7UUFDTCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsYUFBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDbkQsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0IsS0FBSyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QixTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBRWpDLEtBQUssR0FBRyxpQkFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsY0FBYyxFQUFFO1FBQ3ZCLEVBQUUsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLO1lBQy9CLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ3RCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxVQUFVLElBQUk7Z0JBQ3RDLElBQUksQ0FBQyxH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QkFBZSxDQUFDLFVBQVU7WUFDdEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU07WUFDbEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU0sSUFBSSwyRUFBMkU7WUFDakgsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEtBQUssSUFBSSwwRUFBMEU7WUFDL0csQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEtBQUssSUFBSSwyRUFBMkU7WUFDaEgsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUcsSUFBSSx5RUFBeUU7WUFDNUcsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE9BQU8sSUFBSSw2RUFBNkU7WUFDcEgsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUcsSUFBSSx5RUFBeUU7WUFDNUcsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUcsSUFBSSx5RUFBeUU7WUFDNUcsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEtBQUssSUFBSSwyRUFBMkU7WUFDaEgsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUcsSUFBSSx5RUFBeUU7WUFDNUcsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU07WUFDbEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEVBQUU7WUFDOUIsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEtBQUs7WUFDakMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE9BQU87WUFDbkMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE9BQU87WUFDbkMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU07WUFDbEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE9BQU87WUFDbkMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU07WUFDbEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEdBQUc7WUFDL0IsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEtBQUs7WUFDakMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLE1BQU07WUFDbEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLElBQUk7WUFDaEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLFFBQVE7WUFDcEMsQ0FBQyxDQUFDLEtBQUssS0FBSyx5QkFBZSxDQUFDLEVBQUUsSUFBSSxlQUFlO1lBQ2pELENBQUMsQ0FBQyxLQUFLLEtBQUsseUJBQWUsQ0FBQyxPQUFPO1lBQ25DLENBQUMsQ0FBQyxLQUFLLEtBQUsseUJBQWUsQ0FBQyxJQUFJO1lBQ2hDLENBQUMsQ0FBQyxLQUFLLEtBQUsseUJBQWUsQ0FBQyxJQUFJO1lBQ2hDLENBQUMsQ0FBQyxLQUFLLEtBQUsseUJBQWUsQ0FBQyxTQUFTO1lBQ3JDLENBQUMsQ0FBQyxLQUFLLEtBQUsseUJB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QyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0UsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUVBQXVFLEVBQUUsS0FBSztZQUMvRSxNQUFNLFNBQVMsR0FBRyxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNwRyxNQUFNLFNBQVMsQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDN0UsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy9cbi8vIFRlc3QgZm9yIEtleWNoYWluc1xuLy9cblxuaW1wb3J0IHsgQ29pbkZhbWlseSwgQ29pbktpbmQsIGNvaW5zLCBLZXlDdXJ2ZSwgVW5kZXJseWluZ0Fzc2V0IH0gZnJvbSAnQGJpdGdvL3N0YXRpY3MnO1xuaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbm9jayA9IHJlcXVpcmUoJ25vY2snKTtcbmltcG9ydCBzaG91bGQgPSByZXF1aXJlKCdzaG91bGQnKTtcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcblxuaW1wb3J0IHsgY29tbW9uLCBkZWNvZGVPckVsc2UsIEVDRFNBVXRpbHMsIEVERFNBVXRpbHMsIEtleWNoYWluLCBLZXljaGFpbnMsIE92Y1NoYXJlIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IFRlc3RCaXRHbyB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHbyB9IGZyb20gJy4uLy4uLy4uL3NyYy9iaXRnbyc7XG5pbXBvcnQgeyBTaW5vblN0dWIgfSBmcm9tICdzaW5vbic7XG5cbmRlc2NyaWJlKCdWMiBLZXljaGFpbnMnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbztcbiAgbGV0IGJhc2Vjb2luO1xuICBsZXQga2V5Y2hhaW5zO1xuICBsZXQgYmdVcmw7XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBiaXRnby5zZXRWYWxpZGF0ZShmYWxzZSk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0bHRjJyk7XG4gICAga2V5Y2hhaW5zID0gYmFzZWNvaW4ua2V5Y2hhaW5zKCk7XG5cbiAgICBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FkZCBLZXljaGFpbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGFkZCBhIGtleWNoYWluJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90bHRjL2tleScsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS5wdWIuc2hvdWxkLmVxdWFsKCdwdWInKTtcbiAgICAgICAgICBib2R5LmRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQuc2hvdWxkLmVxdWFsKCdkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkJyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IGtleWNoYWlucy5hZGQoeyBwdWI6ICdwdWInLCBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiAnZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZCcgfSk7XG4gICAgICBzY29wZS5kb25lKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFkZCBhIHNhZmUgY2hpbGQga2V5Y2hhaW4gd2l0aCBkZXJpdmVkRnJvbVBhcmVudFdpdGhQYXRoJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90bHRjL2tleScsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS5wdWIuc2hvdWxkLmVxdWFsKCdwdWInKTtcbiAgICAgICAgICBib2R5LnBhcmVudC5zaG91bGQuZXF1YWwoJ3BhcmVudC1rZXktaWQnKTtcbiAgICAgICAgICBib2R5LnNhZmVJZC5zaG91bGQuZXF1YWwoJ3NhZmUtaWQnKTtcbiAgICAgICAgICBib2R5LmRlcml2ZWRGcm9tUGFyZW50V2l0aFBhdGguc2hvdWxkLmVxdWFsKFwibS83J1wiKTtcbiAgICAgICAgICBzaG91bGQuZXF1YWwoYm9keS5wYXRoLCB1bmRlZmluZWQpO1xuICAgICAgICAgIHNob3VsZC5lcXVhbChib2R5LmRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQsIHVuZGVmaW5lZCk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHsgaWQ6ICdjaGlsZC1rZXktaWQnLCBkZXJpdmVkRnJvbVBhcmVudFdpdGhQYXRoOiBcIm0vNydcIiwgcGF0aDogJy8wLzAnIH0pO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQga2V5Y2hhaW5zLmFkZCh7XG4gICAgICAgIHB1YjogJ3B1YicsXG4gICAgICAgIHBhcmVudDogJ3BhcmVudC1rZXktaWQnLFxuICAgICAgICBzYWZlSWQ6ICdzYWZlLWlkJyxcbiAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoUGF0aDogXCJtLzcnXCIsXG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5kZXJpdmVkRnJvbVBhcmVudFdpdGhQYXRoLnNob3VsZC5lcXVhbChcIm0vNydcIik7XG4gICAgICBzY29wZS5kb25lKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBUaGlzIHNlY3Rpb24ncyBpbnRlbnRpb24gaXMgdG8gcHJvdmlkZSBzb21lIGtleSBnZW5lcmF0aW9uIHNhbml0eSBjaGVja2luZy4gZ2VuZXJhdGVLZXlQYWlyIGlzIGEgZ2VuZXJhbCBzdXJmYWNlXG4gICAqIGZvciBrZXkgZ2VuZXJhdGlvbiBidXQgdGhlIGtleXMgYXJlIHRyZWF0ZWQgdGhlIHNhbWUgYnkgQml0R28gZG93biB0aGUgbGluZS4gQW55IFNFQ1AyNTZLMSBiYXNlZCBjb2lucyBrZXktcGFpcnMgY2FuXG4gICAqIGJlIHJlLXVzZWQgc28gbmVlZCB0byBiZSB0aGUgc2FtZS5cbiAgICoqL1xuICBkZXNjcmliZSgnS2V5IGdlbmVyYXRpb24gZW5mb3JjZW1lbnQgZm9yIFNFQ1AyNTZLMScsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBpdGVyYXRlIG92ZXIgbm9uLWZpYXQgY3J5cHRvIHNlY3AgY29pbnNcbiAgICBjb25zdCBjb2luRmFtaWx5VmFsdWVzID0gT2JqZWN0LmtleXMoQ29pbkZhbWlseSkubWFwKChuKSA9PiBuLnRvTG93ZXJDYXNlKCkpO1xuICAgIGNvbnN0IGNyeXB0b1NlY3BDb2lucyA9IGNvaW5zLmZpbHRlcihcbiAgICAgIChuKSA9PlxuICAgICAgICBuLnByaW1hcnlLZXlDdXJ2ZSA9PT0gS2V5Q3VydmUuU2VjcDI1NmsxICYmXG4gICAgICAgIG4ua2luZCA9PT0gQ29pbktpbmQuQ1JZUFRPICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5VU0QgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkFWQVhQICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5BUEVDSEFJTiAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuRE9HRSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuRVRIVyAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuS0FWQUNPU01PUyAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuQ09SRVVNICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5CRVJBICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5JU0xNICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5BUkJFVEggJiYgLy8gVE9ETyhXSU4tNjkyKTogcmVtb3ZlIHRoaXMgb25jZSBjb2luLXNwZWNpZmljIG1vZHVsZSBmb3IgYXJiZXRoIGlzIGFkZGVkXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5PUEVUSCAmJiAvLyBUT0RPKFdJTi02OTIpOiByZW1vdmUgdGhpcyBvbmNlIGNvaW4tc3BlY2lmaWMgbW9kdWxlIGZvciBvcGV0aCBpcyBhZGRlZFxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuWktFVEggJiYgLy8gVE9ETyhXSU4tMTQyNyk6IHJlbW92ZSB0aGlzIG9uY2UgY29pbi1zcGVjaWZpYyBtb2R1bGUgZm9yIHprZXRoIGlzIGFkZGVkXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5PQVMgJiYgLy8gVE9ETyhXSU4tMzY5Nik6IHJlbW92ZSB0aGlzIG9uY2UgY29pbi1zcGVjaWZpYyBtb2R1bGUgZm9yIG9hcyBpcyBhZGRlZFxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuQ09SRURBTyAmJiAvLyBUT0RPKFdJTi0zNjk2KTogcmVtb3ZlIHRoaXMgb25jZSBjb2luLXNwZWNpZmljIG1vZHVsZSBmb3IgY29yZWRhbyBpcyBhZGRlZFxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuRkxSICYmIC8vIFRPRE8oV0lOLTQyMTUpOiByZW1vdmUgdGhpcyBvbmNlIGNvaW4tc3BlY2lmaWMgbW9kdWxlIGZvciBGTFIgaXMgYWRkZWRcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlNHQiAmJiAvLyBUT0RPKFdJTi00MjE2KTogcmVtb3ZlIHRoaXMgb25jZSBjb2luLXNwZWNpZmljIG1vZHVsZSBmb3IgU0dCIGlzIGFkZGVkXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5XRU1JWCAmJiAvLyBUT0RPKFdJTi00MTc3KTogcmVtb3ZlIHRoaXMgb25jZSBjb2luLXNwZWNpZmljIG1vZHVsZSBmb3IgV0VNSVggaXMgYWRkZWRcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlhEQyAmJiAvLyBUT0RPKFdJTi00MTczKTogcmVtb3ZlIHRoaXMgb25jZSBjb2luLXNwZWNpZmljIG1vZHVsZSBmb3IgWERDIGlzIGFkZGVkXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5SVU5FICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5CQUJZICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5JQ1AgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0Lk1BTlRSQSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuTU9OICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5PRyAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuV09STEQgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlBIUlMgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkNUQyAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSFlQRUVWTSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuWFBMICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5TT05FSVVNICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5WRVQgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkNST05PUyAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuRkVUQ0hBSSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSU5JVElBICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5BU0kgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlNPTklDICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5TRUlFVk0gJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LktBSUEgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LklSWVMgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkxJTkVBRVRIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5JUCAmJiAvLyBEYXRhIE5ldHdvcmtcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkJBU0VFVEggJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlNPTUkgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkZMUlAgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkZMVUVOVEVUSCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuTUFOVExFICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5IICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5IT09ERVRIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5IUFBFVEggJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkpPVkFZRVRIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5PS0JYTEFZRVIgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlVOSUVUSCAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuTU9SUEggJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0Lk1PUlBIRVRIICYmXG4gICAgICAgIG4uYXNzZXQgIT09IFVuZGVybHlpbmdBc3NldC5ET0dFT1MgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0Lk1FR0FFVEggJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkFSQ1VTREMgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LlpLU1lOQ0VSQSAmJlxuICAgICAgICBuLmFzc2V0ICE9PSBVbmRlcmx5aW5nQXNzZXQuSFlQRVJMSVFVSUQgJiZcbiAgICAgICAgbi5hc3NldCAhPT0gVW5kZXJseWluZ0Fzc2V0LkJPQkFFVEggJiZcbiAgICAgICAgY29pbkZhbWlseVZhbHVlcy5pbmNsdWRlcyhuLm5hbWUpXG4gICAgKTtcblxuICAgIGNvbnN0IGV4cGVjdGVkWHB1YiA9XG4gICAgICAneHB1YjY2MU15TXdBcVJiY0dwWmY4bXhOV2hTUGRXYUxHdlF6emFnZTZ2cTJvUUZ6cTh0b1Z6bWtqeWdZWjNIY1p3NmVDekFmbjlaZHlHaktvS2tjcEt3YWNrZGd6blZiaXVucHE3cmt4RHU3cXVTJztcbiAgICBjb25zdCBleHBlY3RlZFhwcnYgPVxuICAgICAgJ3hwcnY5czIxWnJRSDE0M0s0TFZDMmtSTjlaVmY1VWpxc1RoOWRNbTNKWVJSRjRqMXhMWmV4VFRXQ0JONGhtZFpVSGVUM3ZDSlBMMTgxRXJWYVk0ODlBckJLU1dhQjdEdTd2eVZTNlhDNDNXdEs3QSc7XG5cbiAgICBjb25zdCBzZWVkID0gQnVmZmVyLmZyb20oJ3RoaXMgaXMgc29tZSByYW5kb20gc2VlZCB3ZSB3aWxsIHVzZScsICd1dGYtOCcpO1xuXG4gICAgY3J5cHRvU2VjcENvaW5zLmZvckVhY2goKGNvaW4pID0+IHtcbiAgICAgIGl0KGBzaG91bGQgY3JlYXRlIHRoZSBzYW1lICR7Y29pbi5uYW1lfSBrZXkgd2l0aCB0aGUgc2FtZSBzZWVkYCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBjdXJyZW50Q29pbiA9IGJpdGdvLmNvaW4oY29pbi5uYW1lKTtcbiAgICAgICAgY29uc3Qga2V5UGFpciA9IGN1cnJlbnRDb2luLmdlbmVyYXRlS2V5UGFpcihzZWVkKTtcblxuICAgICAgICBzaG91bGQuZXhpc3Qoa2V5UGFpci5wdWIpO1xuICAgICAgICBzaG91bGQuZXhpc3Qoa2V5UGFpci5wcnYpO1xuXG4gICAgICAgIGtleVBhaXIucHViLnNob3VsZC5lcXVhbChleHBlY3RlZFhwdWIpO1xuICAgICAgICBrZXlQYWlyLnBydi5zaG91bGQuZXF1YWwoZXhwZWN0ZWRYcHJ2KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVXBkYXRlIFBhc3N3b3JkJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IG9sZFBhc3N3b3JkID0gJ29sZFBhc3N3b3JkJztcbiAgICBjb25zdCBuZXdQYXNzd29yZCA9ICduZXdQYXNzd29yZCc7XG4gICAgY29uc3Qgb3RoZXJQYXNzd29yZCA9ICdvdGhlclBhc3N3b3JkJztcblxuICAgIGRlc2NyaWJlKCdzaG91bGQgZmFpbCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBzYW5kYm94O1xuICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3RvIHVwZGF0ZSB0aGUgcGFzc3dvcmQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVQYXNzd29yZCh7IG5ld1Bhc3N3b3JkOiAnNTY3OCcgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnTWlzc2luZyBwYXJhbWV0ZXI6IG9sZFBhc3N3b3JkJyk7XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zXG4gICAgICAgICAgLnVwZGF0ZVBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6IDEyMzQsIG5ld1Bhc3N3b3JkOiAnNTY3OCcgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnRXhwZWN0aW5nIHBhcmFtZXRlciBzdHJpbmc6IG9sZFBhc3N3b3JkIGJ1dCBmb3VuZCBudW1iZXInKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAudXBkYXRlUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogJzEyMzQnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3NpbmcgcGFyYW1ldGVyOiBuZXdQYXNzd29yZCcpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVQYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnMTIzNCcsIG5ld1Bhc3N3b3JkOiA1Njc4IH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0V4cGVjdGluZyBwYXJhbWV0ZXIgc3RyaW5nOiBuZXdQYXNzd29yZCBidXQgZm91bmQgbnVtYmVyJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3RvIHVwZGF0ZSB0aGUgcGFzc3dvcmQgZm9yIGEgc2luZ2xlIGtleWNoYWluJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAoKCkgPT4ga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBuZXdQYXNzd29yZDogJzU2NzgnIH0pKS5zaG91bGQudGhyb3coXG4gICAgICAgICAgJ2V4cGVjdGVkIG9sZCBwYXNzd29yZCB0byBiZSBhIHN0cmluZydcbiAgICAgICAgKTtcblxuICAgICAgICAoKCkgPT4ga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogMTIzNCwgbmV3UGFzc3dvcmQ6ICc1Njc4JyB9KSkuc2hvdWxkLnRocm93KFxuICAgICAgICAgICdleHBlY3RlZCBvbGQgcGFzc3dvcmQgdG8gYmUgYSBzdHJpbmcnXG4gICAgICAgICk7XG5cbiAgICAgICAgKCgpID0+IGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICcxMjM0JyB9KSkuc2hvdWxkLnRocm93KFxuICAgICAgICAgICdleHBlY3RlZCBuZXcgcGFzc3dvcmQgdG8gYmUgYSBzdHJpbmcnXG4gICAgICAgICk7XG5cbiAgICAgICAgKCgpID0+IGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICcxMjM0JywgbmV3UGFzc3dvcmQ6IDU2NzggfSkpLnNob3VsZC50aHJvdygpO1xuXG4gICAgICAgICgoKSA9PiBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkOiAnMTIzNCcsIG5ld1Bhc3N3b3JkOiAnNTY3OCcgfSkpLnNob3VsZC50aHJvdyhcbiAgICAgICAgICAnZXhwZWN0ZWQga2V5Y2hhaW4gdG8gYmUgYW4gb2JqZWN0IHdpdGggYW4gZW5jcnlwdGVkUHJ2IHByb3BlcnR5J1xuICAgICAgICApO1xuXG4gICAgICAgICgoKSA9PlxuICAgICAgICAgIGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHtcbiAgICAgICAgICAgIG9sZFBhc3N3b3JkOiAnMTIzNCcsXG4gICAgICAgICAgICBuZXdQYXNzd29yZDogJzU2NzgnLFxuICAgICAgICAgICAga2V5Y2hhaW46IHt9LFxuICAgICAgICAgIH0pKS5zaG91bGQudGhyb3coJ2V4cGVjdGVkIGtleWNoYWluIHRvIGJlIGFuIG9iamVjdCB3aXRoIGFuIGVuY3J5cHRlZFBydiBwcm9wZXJ0eScpO1xuXG4gICAgICAgICgoKSA9PlxuICAgICAgICAgIGtleWNoYWlucy51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHtcbiAgICAgICAgICAgIG9sZFBhc3N3b3JkOiAnMTIzNCcsXG4gICAgICAgICAgICBuZXdQYXNzd29yZDogJzU2NzgnLFxuICAgICAgICAgICAga2V5Y2hhaW46IHsgZW5jcnlwdGVkUHJ2OiAxMjMgfSxcbiAgICAgICAgICB9KSkuc2hvdWxkLnRocm93KCdleHBlY3RlZCBrZXljaGFpbiB0byBiZSBhbiBvYmplY3Qgd2l0aCBhbiBlbmNyeXB0ZWRQcnYgcHJvcGVydHknKTtcblxuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHsgZW5jcnlwdGVkUHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MScsIHBhc3N3b3JkOiBvdGhlclBhc3N3b3JkIH0pIH07XG4gICAgICAgICgoKSA9PiBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IG9sZFBhc3N3b3JkLCBuZXdQYXNzd29yZCwga2V5Y2hhaW4gfSkpLnNob3VsZC50aHJvdyhcbiAgICAgICAgICAncGFzc3dvcmQgdXNlZCB0byBkZWNyeXB0IGtleWNoYWluIHByaXZhdGUga2V5IGlzIGluY29ycmVjdCdcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgndG8gdXBkYXRlIHRoZSBwYXNzd29yZCBmb3IgYSBzaW5nbGUga2V5Y2hhaW4gKGFzeW5jKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zXG4gICAgICAgICAgLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBuZXdQYXNzd29yZDogJzU2NzgnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2V4cGVjdGVkIG9sZCBwYXNzd29yZCB0byBiZSBhIHN0cmluZycpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6IDEyMzQsIG5ld1Bhc3N3b3JkOiAnNTY3OCcgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZXhwZWN0ZWQgb2xkIHBhc3N3b3JkIHRvIGJlIGEgc3RyaW5nJyk7XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zXG4gICAgICAgICAgLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogJzEyMzQnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2V4cGVjdGVkIG5ldyBwYXNzd29yZCB0byBiZSBhIHN0cmluZycpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICcxMjM0JywgbmV3UGFzc3dvcmQ6IDU2NzggfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnZXhwZWN0ZWQgbmV3IHBhc3N3b3JkIHRvIGJlIGEgc3RyaW5nJyk7XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zXG4gICAgICAgICAgLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBvbGRQYXNzd29yZDogJzEyMzQnLCBuZXdQYXNzd29yZDogJzU2NzgnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2V4cGVjdGVkIGtleWNoYWluIHRvIGJlIGFuIG9iamVjdCB3aXRoIGFuIGVuY3J5cHRlZFBydiBwcm9wZXJ0eScpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6ICcxMjM0JywgbmV3UGFzc3dvcmQ6ICc1Njc4Jywga2V5Y2hhaW46IHt9IH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2V4cGVjdGVkIGtleWNoYWluIHRvIGJlIGFuIG9iamVjdCB3aXRoIGFuIGVuY3J5cHRlZFBydiBwcm9wZXJ0eScpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHtcbiAgICAgICAgICAgIG9sZFBhc3N3b3JkOiAnMTIzNCcsXG4gICAgICAgICAgICBuZXdQYXNzd29yZDogJzU2NzgnLFxuICAgICAgICAgICAga2V5Y2hhaW46IHsgZW5jcnlwdGVkUHJ2OiAxMjMgfSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdleHBlY3RlZCBrZXljaGFpbiB0byBiZSBhbiBvYmplY3Qgd2l0aCBhbiBlbmNyeXB0ZWRQcnYgcHJvcGVydHknKTtcblxuICAgICAgICAvLyB3cm9uZyBwYXNzd29yZCDigJQgZGVjcnlwdCBmYWlsc1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHsgZW5jcnlwdGVkUHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MScsIHBhc3N3b3JkOiBvdGhlclBhc3N3b3JkIH0pIH07XG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkLCBrZXljaGFpbiB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdmYWlsZWQgdG8gdXBkYXRlIGtleWNoYWluIHBhc3N3b3JkOiBpbmNvcnJlY3QgcGFzc3dvcmQnKTtcblxuICAgICAgICAvLyBpbnZhbGlkIEpTT04gaW4gZW5jcnlwdGVkUHJ2XG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHsgb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkLCBrZXljaGFpbjogeyBlbmNyeXB0ZWRQcnY6ICdub3QtdmFsaWQtanNvbicgfSB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdmYWlsZWQgdG8gdXBkYXRlIGtleWNoYWluIHBhc3N3b3JkOiBkZWNyeXB0OiBjaXBoZXJ0ZXh0IGlzIG5vdCB2YWxpZCBKU09OJyk7XG5cbiAgICAgICAgLy8gdW5rbm93biBlbnZlbG9wZSB2ZXJzaW9uXG4gICAgICAgIGNvbnN0IHVua25vd25WZXJzaW9uRW52ZWxvcGUgPSBKU09OLnN0cmluZ2lmeSh7IHY6IDk5LCBjdDogJ2FiYycgfSk7XG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC51cGRhdGVTaW5nbGVLZXljaGFpblBhc3N3b3JkKHtcbiAgICAgICAgICAgIG9sZFBhc3N3b3JkLFxuICAgICAgICAgICAgbmV3UGFzc3dvcmQsXG4gICAgICAgICAgICBrZXljaGFpbjogeyBlbmNyeXB0ZWRQcnY6IHVua25vd25WZXJzaW9uRW52ZWxvcGUgfSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdmYWlsZWQgdG8gdXBkYXRlIGtleWNoYWluIHBhc3N3b3JkOiBkZWNyeXB0OiB1bmtub3duIGVudmVsb3BlIHZlcnNpb24gOTknKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnb24gYW55IG90aGVyIGVycm9yJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBlbmNYcHJ2MSA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYxJywgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvdGx0Yy9rZXknKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHB1YjogJ3hwdWIxJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1hwcnYxLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBzYW5kYm94LnN0dWIoa2V5Y2hhaW5zLCAndXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCcpLnRocm93cygnZXJyb3InLCAnc29tZSByYW5kb20gZXJyb3InKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnMudXBkYXRlUGFzc3dvcmQoeyBvbGRQYXNzd29yZCwgbmV3UGFzc3dvcmQgfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnc29tZSByYW5kb20gZXJyb3InKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3N1Y2Nlc3NmdWwgcGFzc3dvcmQgdXBkYXRlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdmFsaWRhdGVLZXlzID0gYXN5bmMgZnVuY3Rpb24gKGtleXMsIG5ld1Bhc3N3b3JkLCBleHBlY3RlZExlbmd0aCkge1xuICAgICAgICBhc3NlcnQub2soT2JqZWN0LmtleXMoa2V5cykubGVuZ3RoID09PSBleHBlY3RlZExlbmd0aCwgJ3Nob3VsZCBoYXZlIHRoZSBleHBlY3RlZCBudW1iZXIgb2Yga2V5cycpO1xuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhrZXlzKSkge1xuICAgICAgICAgIGFzc2VydC5vayhrZXkuaW5jbHVkZXMoJ3hwdWInKSB8fCBrZXkuaW5jbHVkZXMoJ3JhbmRvbWlkJyksICdrZXkgc2hvdWxkIGJlIHhwdWIgb3IgcmFuZG9taWQnKTtcbiAgICAgICAgICBjb25zdCBkZWNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHZhbHVlIGFzIHN0cmluZywgcGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICAgIGRlY3J5cHRlZFBydi5zaG91bGQuc3RhcnRXaXRoKCd4cHJ2Jyk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGl0KCdyZWNlaXZlIG9ubHkgb25lIHBhZ2Ugd2hlbiBsaXN0aW5nIGtleWNoYWlucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZW5jWHBydjEgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MScsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jWHBydjIgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MicsIHBhc3N3b3JkOiBvdGhlclBhc3N3b3JkIH0pO1xuICAgICAgICBjb25zdCBlbmNYcHJ2MyA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYzJywgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvdGx0Yy9rZXknKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHB1YjogJ3hwdWIxJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1hwcnYxLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHViOiAneHB1YjInLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogJ3JhbmRvbWlkMScsXG4gICAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5cyA9IGF3YWl0IGtleWNoYWlucy51cGRhdGVQYXNzd29yZCh7IG9sZFBhc3N3b3JkOiBvbGRQYXNzd29yZCwgbmV3UGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBhd2FpdCB2YWxpZGF0ZUtleXMoa2V5cywgbmV3UGFzc3dvcmQsIDIpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdyZWNlaXZlIG11bHRpcGxlIHBhZ2VzIHdoZW4gbGlzdGluZyBrZXljaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHByZXZJZCA9ICdwcmV2SWQnO1xuICAgICAgICBjb25zdCBlbmNYcHJ2MSA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYxJywgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkIH0pO1xuICAgICAgICBjb25zdCBlbmNYcHJ2MiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYyJywgcGFzc3dvcmQ6IG90aGVyUGFzc3dvcmQgfSk7XG4gICAgICAgIGNvbnN0IGVuY1hwcnYzYSA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYzJywgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkIH0pO1xuICAgICAgICBjb25zdCBlbmNYcHJ2M2IgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MycsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jWHBydjQgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2NCcsIHBhc3N3b3JkOiBvdGhlclBhc3N3b3JkIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvdGx0Yy9rZXknKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIG5leHRCYXRjaFByZXZJZDogcHJldklkLFxuICAgICAgICAgICAga2V5czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHViOiAneHB1YjEnLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jWHBydjEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwdWI6ICd4cHViMicsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlkOiAncmFuZG9taWQxJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1hwcnYzYSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkoZnVuY3Rpb24gcXVlcnlOZXh0UGFnZU1hdGNoKHF1ZXJ5T2JqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gcXVlcnlPYmplY3QucHJldklkID09PSBwcmV2SWQ7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwdWI6ICd4cHViMycsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2M2IsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwdWI6ICd4cHViNCcsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2NCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qga2V5cyA9IGF3YWl0IGtleWNoYWlucy51cGRhdGVQYXNzd29yZCh7IG9sZFBhc3N3b3JkOiBvbGRQYXNzd29yZCwgbmV3UGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBhd2FpdCB2YWxpZGF0ZUtleXMoa2V5cywgbmV3UGFzc3dvcmQsIDMpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaW5nbGUga2V5Y2hhaW4gcGFzc3dvcmQgdXBkYXRlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBwcnYgPSAneHBydnRlc3QnO1xuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHtcbiAgICAgICAgICB4cHViOiAneHB1YjEyMycsXG4gICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHBydiwgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkIH0pLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IG5ld0tleWNoYWluID0gYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBrZXljaGFpbiwgb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkIH0pO1xuXG4gICAgICAgIGNvbnN0IGRlY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogbmV3S2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LCBwYXNzd29yZDogbmV3UGFzc3dvcmQgfSk7XG4gICAgICAgIGRlY3J5cHRlZFBydi5zaG91bGQuZXF1YWwocHJ2KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2luZ2xlIGtleWNoYWluIHBhc3N3b3JkIHVwZGF0ZSBlbWl0cyBhIHYyIChBcmdvbjJpZCkgZW52ZWxvcGUgZm9yIGEgdjIgaW5wdXQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBydiA9ICd4cHJ2dGVzdC12Mic7XG4gICAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogcHJ2LCBwYXNzd29yZDogb2xkUGFzc3dvcmQsIGVuY3J5cHRpb25WZXJzaW9uOiAyIH0pO1xuICAgICAgICBjb25zdCBlbnZlbG9wZSA9IEpTT04ucGFyc2UoZW5jcnlwdGVkUHJ2KTtcbiAgICAgICAgZW52ZWxvcGUudi5zaG91bGQuZXF1YWwoMiwgJ3ByZS1jb25kaXRpb246IGtleWNoYWluIG11c3QgYmUgdjItZW5jcnlwdGVkJyk7XG5cbiAgICAgICAgY29uc3Qga2V5Y2hhaW4gPSB7IHhwdWI6ICd4cHViMTIzJywgZW5jcnlwdGVkUHJ2IH07XG4gICAgICAgIGNvbnN0IG5ld0tleWNoYWluID0gYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVNpbmdsZUtleWNoYWluUGFzc3dvcmQoeyBrZXljaGFpbiwgb2xkUGFzc3dvcmQsIG5ld1Bhc3N3b3JkIH0pO1xuXG4gICAgICAgIGNvbnN0IG5ld0VudmVsb3BlID0gSlNPTi5wYXJzZShuZXdLZXljaGFpbi5lbmNyeXB0ZWRQcnYpO1xuICAgICAgICBuZXdFbnZlbG9wZS52LnNob3VsZC5lcXVhbCgyLCAncmUtZW5jcnlwdGVkIGtleWNoYWluIG11c3Qgc3RpbGwgYmUgdjInKTtcblxuICAgICAgICBjb25zdCBkZWNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IG5ld0tleWNoYWluLmVuY3J5cHRlZFBydiwgcGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBkZWNyeXB0ZWRQcnYuc2hvdWxkLmVxdWFsKHBydiwgJ25ldyBwYXNzd29yZCBtdXN0IGRlY3J5cHQgdG8gb3JpZ2luYWwgcHJ2Jyk7XG5cbiAgICAgICAgYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiBuZXdLZXljaGFpbi5lbmNyeXB0ZWRQcnYsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KS5zaG91bGQuYmUucmVqZWN0ZWQoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2luZ2xlIGtleWNoYWluIHBhc3N3b3JkIHVwZGF0ZSBwcmVzZXJ2ZXMgYSB2MSAoU0pDTCkgZW52ZWxvcGUgYnkgZGVmYXVsdCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcHJ2ID0gJ3hwcnZ0ZXN0LXYxJztcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCwgZW5jcnlwdGlvblZlcnNpb246IDEgfSk7XG4gICAgICAgIEpTT04ucGFyc2UoZW5jcnlwdGVkUHJ2KS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ3YnLCAyLCAncHJlLWNvbmRpdGlvbjogaW5wdXQgbXVzdCBub3QgYmUgdjInKTtcblxuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHsgeHB1YjogJ3hwdWIxMjMnLCBlbmNyeXB0ZWRQcnYgfTtcbiAgICAgICAgY29uc3QgbmV3S2V5Y2hhaW4gPSBhd2FpdCBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7IGtleWNoYWluLCBvbGRQYXNzd29yZCwgbmV3UGFzc3dvcmQgfSk7XG5cbiAgICAgICAgSlNPTi5wYXJzZShuZXdLZXljaGFpbi5lbmNyeXB0ZWRQcnYpLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgndicsIDIsICd2MSBrZXljaGFpbiBtdXN0IHN0YXkgdjEgYnkgZGVmYXVsdCcpO1xuXG4gICAgICAgIGNvbnN0IGRlY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogbmV3S2V5Y2hhaW4uZW5jcnlwdGVkUHJ2LCBwYXNzd29yZDogbmV3UGFzc3dvcmQgfSk7XG4gICAgICAgIGRlY3J5cHRlZFBydi5zaG91bGQuZXF1YWwocHJ2LCAnbmV3IHBhc3N3b3JkIG11c3QgZGVjcnlwdCB0byBvcmlnaW5hbCBwcnYnKTtcblxuICAgICAgICBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IG5ld0tleWNoYWluLmVuY3J5cHRlZFBydiwgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkIH0pLnNob3VsZC5iZS5yZWplY3RlZCgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaW5nbGUga2V5Y2hhaW4gcGFzc3dvcmQgdXBkYXRlIHVwZ3JhZGVzIGEgdjEgZW52ZWxvcGUgdG8gdjIgd2hlbiBlbmNyeXB0aW9uVmVyc2lvbjogMiBpcyBwYXNzZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBydiA9ICd4cHJ2dGVzdC12MS1vcHQtaW4nO1xuICAgICAgICBjb25zdCBlbmNyeXB0ZWRQcnYgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHBydiwgcGFzc3dvcmQ6IG9sZFBhc3N3b3JkLCBlbmNyeXB0aW9uVmVyc2lvbjogMSB9KTtcblxuICAgICAgICBjb25zdCBrZXljaGFpbiA9IHsgeHB1YjogJ3hwdWIxMjMnLCBlbmNyeXB0ZWRQcnYgfTtcbiAgICAgICAgY29uc3QgbmV3S2V5Y2hhaW4gPSBhd2FpdCBrZXljaGFpbnMudXBkYXRlU2luZ2xlS2V5Y2hhaW5QYXNzd29yZCh7XG4gICAgICAgICAga2V5Y2hhaW4sXG4gICAgICAgICAgb2xkUGFzc3dvcmQsXG4gICAgICAgICAgbmV3UGFzc3dvcmQsXG4gICAgICAgICAgZW5jcnlwdGlvblZlcnNpb246IDIsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIEpTT04ucGFyc2UobmV3S2V5Y2hhaW4uZW5jcnlwdGVkUHJ2KS52LnNob3VsZC5lcXVhbCgyLCAndjIgb3B0LWluIG11c3QgZW1pdCBhIHYyIGVudmVsb3BlJyk7XG5cbiAgICAgICAgY29uc3QgZGVjcnlwdGVkUHJ2ID0gYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiBuZXdLZXljaGFpbi5lbmNyeXB0ZWRQcnYsIHBhc3N3b3JkOiBuZXdQYXNzd29yZCB9KTtcbiAgICAgICAgZGVjcnlwdGVkUHJ2LnNob3VsZC5lcXVhbChwcnYsICduZXcgcGFzc3dvcmQgbXVzdCBkZWNyeXB0IHRvIG9yaWdpbmFsIHBydicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KFwidXBkYXRlUGFzc3dvcmQgcHJlc2VydmVzIGVhY2gga2V5Y2hhaW4ncyBleGlzdGluZyBlbnZlbG9wZSB2ZXJzaW9uIGJ5IGRlZmF1bHRcIiwgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCB2MVBydiA9ICd4cHJ2LXYxJztcbiAgICAgICAgY29uc3QgdjJQcnYgPSAneHBydi12Mic7XG5cbiAgICAgICAgY29uc3QgZW5jVjEgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHYxUHJ2LCBwYXNzd29yZDogb2xkUGFzc3dvcmQsIGVuY3J5cHRpb25WZXJzaW9uOiAxIH0pO1xuICAgICAgICBjb25zdCBlbmNWMiA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogdjJQcnYsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCwgZW5jcnlwdGlvblZlcnNpb246IDIgfSk7XG4gICAgICAgIGNvbnN0IGVuY090aGVyID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydi1vdGhlcicsIHBhc3N3b3JkOiAnZGlmZmVyZW50LXBhc3N3b3JkJyB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvdGx0Yy9rZXknKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHB1YjogJ3hwdWItdjEnLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jVjEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBwdWI6ICd4cHViLXYyJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1YyLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcHViOiAneHB1Yi1vdGhlcicsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNPdGhlcixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdXBkYXRlZEtleXMgPSBhd2FpdCBrZXljaGFpbnMudXBkYXRlUGFzc3dvcmQoeyBvbGRQYXNzd29yZCwgbmV3UGFzc3dvcmQgfSk7XG5cbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKE9iamVjdC5rZXlzKHVwZGF0ZWRLZXlzKS5sZW5ndGgsIDIsICdvbmx5IHRoZSB0d28gbWF0Y2hpbmcga2V5Y2hhaW5zIHNob3VsZCBiZSB1cGRhdGVkJyk7XG5cbiAgICAgICAgY29uc3QgdXBkYXRlZFYxID0gdXBkYXRlZEtleXNbJ3hwdWItdjEnXTtcbiAgICAgICAgY29uc3QgdXBkYXRlZFYyID0gdXBkYXRlZEtleXNbJ3hwdWItdjInXTtcbiAgICAgICAgYXNzZXJ0Lm9rKHVwZGF0ZWRWMSwgJ3YxIGtleWNoYWluIG11c3QgYmUgaW4gdGhlIHJlc3VsdCcpO1xuICAgICAgICBhc3NlcnQub2sodXBkYXRlZFYyLCAndjIga2V5Y2hhaW4gbXVzdCBiZSBpbiB0aGUgcmVzdWx0Jyk7XG5cbiAgICAgICAgSlNPTi5wYXJzZSh1cGRhdGVkVjEpLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgndicsIDIsICd2MSBrZXljaGFpbiBtdXN0IHN0YXkgdjEgYnkgZGVmYXVsdCcpO1xuICAgICAgICBjb25zdCBkZWNyeXB0ZWRWMSA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogdXBkYXRlZFYxLCBwYXNzd29yZDogbmV3UGFzc3dvcmQgfSk7XG4gICAgICAgIGRlY3J5cHRlZFYxLnNob3VsZC5lcXVhbCh2MVBydik7XG5cbiAgICAgICAgSlNPTi5wYXJzZSh1cGRhdGVkVjIpLnYuc2hvdWxkLmVxdWFsKDIsICd2MiBrZXljaGFpbiBtdXN0IHJlbWFpbiB2MiBhZnRlciBwYXNzd29yZCBjaGFuZ2UnKTtcbiAgICAgICAgY29uc3QgZGVjcnlwdGVkVjIgPSBhd2FpdCBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHVwZGF0ZWRWMiwgcGFzc3dvcmQ6IG5ld1Bhc3N3b3JkIH0pO1xuICAgICAgICBkZWNyeXB0ZWRWMi5zaG91bGQuZXF1YWwodjJQcnYpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSB1cGRhdGVkIGtleXMgd2l0aCBpZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGVuY1hwcnYxID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogb2xkUGFzc3dvcmQgfSk7XG4gICAgICAgIGNvbnN0IGVuY1hwcnYyID0gYXdhaXQgYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjInLCBwYXNzd29yZDogb3RoZXJQYXNzd29yZCB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3RsdGMva2V5JylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXlzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogJ3JhbmRvbWlkMScsXG4gICAgICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlkOiAncmFuZG9taWQyJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1hwcnYyLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBrZXlzID0gYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6IG9sZFBhc3N3b3JkLCBuZXdQYXNzd29yZDogbmV3UGFzc3dvcmQgfSk7XG4gICAgICAgIGF3YWl0IHZhbGlkYXRlS2V5cyhrZXlzLCBuZXdQYXNzd29yZCwgMSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB1cGRhdGUgbXVsdGktdXNlci1vZmMga2V5cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgZW5jWHBydjEgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MScsIHBhc3N3b3JkOiBvbGRQYXNzd29yZCB9KTtcbiAgICAgICAgY29uc3QgZW5jWHBydjIgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6ICd4cHJ2MicsIHBhc3N3b3JkOiBvdGhlclBhc3N3b3JkIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvdGx0Yy9rZXknKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGtleXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlkOiAncmFuZG9taWQxJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGVuY1hwcnYxLFxuICAgICAgICAgICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgICAgICAgICAgb2ZjOiB7XG4gICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzOiBbJ211bHRpLXVzZXIta2V5J10sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpZDogJ3JhbmRvbWlkMicsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBlbmNYcHJ2MixcbiAgICAgICAgICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICAgICAgICAgIG9mYzoge1xuICAgICAgICAgICAgICAgICAgICBmZWF0dXJlczogWydtdWx0aS11c2VyLWtleSddLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBrZXlzID0gYXdhaXQga2V5Y2hhaW5zLnVwZGF0ZVBhc3N3b3JkKHsgb2xkUGFzc3dvcmQ6IG9sZFBhc3N3b3JkLCBuZXdQYXNzd29yZDogbmV3UGFzc3dvcmQgfSk7XG4gICAgICAgIGF3YWl0IHZhbGlkYXRlS2V5cyhrZXlzLCBuZXdQYXNzd29yZCwgMSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdDcmVhdGUgVFNTIEtleWNoYWlucycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgIHB1YjogJ3VzZXJQdWInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzMnLFxuICAgICAgICAgIHB1YjogJ3VzZXJQdWInLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgbGV0IHNhbmRib3g7XG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICAgIH0pO1xuXG4gICAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBzYW5kYm94LnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBbJ3Rzb2wnLCAndGRvdCcsICd0bmVhciddLmZvckVhY2goKGNvaW4pID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCBjcmVhdGUgRUREU0EgVFNTIEtleWNoYWlucycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBzYW5kYm94LnN0dWIoRUREU0FVdGlscy5kZWZhdWx0LnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBhd2FpdCBiaXRnby5jb2luKGNvaW4pLmtleWNoYWlucygpLmNyZWF0ZU1wYyh7XG4gICAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICAgIG9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAga2V5Y2hhaW5zLnNob3VsZC5kZWVwRXF1YWwoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBbJ3Ric2MnXS5mb3JFYWNoKChjb2luKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgY3JlYXRlIEVDRFNBIFRTUyBLZXljaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgbm9jayhiZ1VybCkuZ2V0KCcvYXBpL3YyL3Rzcy9zZXR0aW5ncycpLnF1ZXJ5KHRydWUpLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgY29pblNldHRpbmdzOiB7fSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzYW5kYm94LnN0dWIoRUNEU0FVdGlscy5FY2RzYVV0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgICBjb25zdCBrZXljaGFpbnMgPSBhd2FpdCBiaXRnby5jb2luKGNvaW4pLmtleWNoYWlucygpLmNyZWF0ZU1wYyh7XG4gICAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICAgIG9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAga2V5Y2hhaW5zLnNob3VsZC5kZWVwRXF1YWwoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBbJ3Rzb2wnXS5mb3JFYWNoKChjb2luKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgZm9yd2FyZCB0aGUgZW50ZXJwcmlzZSBwYXJhbSBvbiB0aGUgR0VUIC90c3Mvc2V0dGluZ3MgY2FsbCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAvLyBFeGFjdCBxdWVyeSBtYXRjaCAobm90IC5xdWVyeSh0cnVlKSkg4oCUIHRoaXMgb25seSBwYXNzZXMgaWYgYGVudGVycHJpc2VgIGlzIGFjdHVhbGx5XG4gICAgICAgICAgLy8gZm9yd2FyZGVkIG9uIHRoZSByZXF1ZXN0LCBwcm92aW5nIFdDSS0xMzU4J3MgZml4IHJhdGhlciB0aGFuIGp1c3QgdG9sZXJhdGluZyBpdC5cbiAgICAgICAgICBjb25zdCB0c3NTZXR0aW5nc05vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgICAgLmdldCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKVxuICAgICAgICAgICAgLnF1ZXJ5KHsgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UtMTIzJyB9KVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgeyBjb2luU2V0dGluZ3M6IHt9IH0pO1xuICAgICAgICAgIHNhbmRib3guc3R1YihFRERTQVV0aWxzLmRlZmF1bHQucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJykucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuICAgICAgICAgIGF3YWl0IGJpdGdvLmNvaW4oY29pbikua2V5Y2hhaW5zKCkuY3JlYXRlTXBjKHtcbiAgICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgICAgICBwYXNzcGhyYXNlOiAncGFzc3dvcmQnLFxuICAgICAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UtMTIzJyxcbiAgICAgICAgICAgIG9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdHNzU2V0dGluZ3NOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIFsndHNvbCddLmZvckVhY2goKGNvaW4pID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCBzZW5kIG5vIGVudGVycHJpc2UgcXVlcnkgcGFyYW0gb24gR0VUIC90c3Mvc2V0dGluZ3Mgd2hlbiBlbnRlcnByaXNlIGlzIG5vdCBzdXBwbGllZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB0c3NTZXR0aW5nc05vY2sgPSBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjIvdHNzL3NldHRpbmdzJykucmVwbHkoMjAwLCB7IGNvaW5TZXR0aW5nczoge30gfSk7XG4gICAgICAgICAgc2FuZGJveC5zdHViKEVERFNBVXRpbHMuZGVmYXVsdC5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKS5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG4gICAgICAgICAgYXdhaXQgYml0Z28uY29pbihjb2luKS5rZXljaGFpbnMoKS5jcmVhdGVNcGMoe1xuICAgICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRzc1NldHRpbmdzTm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBbJ3Rzb2wnXS5mb3JFYWNoKChjb2luKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgcGFzcyB3ZWJhdXRobkluZm8gdG8gY3JlYXRlS2V5Y2hhaW5zIGZvciBFRERTQSBUU1MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgd2ViYXV0aG5JbmZvID0ge1xuICAgICAgICAgICAgb3RwRGV2aWNlSWQ6ICdkZXZpY2UtMScsXG4gICAgICAgICAgICBwcmZTYWx0OiAnc2FsdC0xJyxcbiAgICAgICAgICAgIHBhc3NwaHJhc2U6ICdwcmYtZGVyaXZlZC1wYXNzcGhyYXNlJyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNvbnN0IGNyZWF0ZUtleWNoYWlucyA9IHNhbmRib3hcbiAgICAgICAgICAgIC5zdHViKEVERFNBVXRpbHMuZGVmYXVsdC5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAgICAgLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcbiAgICAgICAgICBhd2FpdCBiaXRnby5jb2luKGNvaW4pLmtleWNoYWlucygpLmNyZWF0ZU1wYyh7XG4gICAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICAgIHdlYmF1dGhuSW5mbyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBjcmVhdGVLZXljaGFpbnMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAgIGNyZWF0ZUtleWNoYWlucy5maXJzdENhbGwuYXJnc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2ViYXV0aG5JbmZvJywgd2ViYXV0aG5JbmZvKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgWyd0YnNjJ10uZm9yRWFjaCgoY29pbikgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIHJlamVjdCBzYWZlIHJvb3QgY3JlYXRpb24gd2hlbiB0aGUgcmVzb2x2ZWQgY2VyZW1vbnkgaXMgbGVnYWN5IE1QQ3YxJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIG5vY2soYmdVcmwpLmdldCgnL2FwaS92Mi90c3Mvc2V0dGluZ3MnKS5xdWVyeSh0cnVlKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGNvaW5TZXR0aW5nczoge30sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgY29uc3QgY3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAgICAgLnN0dWIoRUNEU0FVdGlscy5FY2RzYVV0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpXG4gICAgICAgICAgICAucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuICAgICAgICAgIGF3YWl0IGJpdGdvXG4gICAgICAgICAgICAuY29pbihjb2luKVxuICAgICAgICAgICAgLmtleWNoYWlucygpXG4gICAgICAgICAgICAuY3JlYXRlTXBjKHtcbiAgICAgICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICAgICAgICBzYWZlSWQ6ICdzYWZlSWQnLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9sZWdhY3kgTVBDdjEgY2VyZW1vbnkvKTtcbiAgICAgICAgICBjcmVhdGVLZXljaGFpbnMuY2FsbGVkLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBbJ3Ric2MnXS5mb3JFYWNoKChjb2luKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgcGFzcyB3ZWJhdXRobkluZm8gdG8gY3JlYXRlS2V5Y2hhaW5zIGZvciBFQ0RTQSBUU1MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgbm9jayhiZ1VybCkuZ2V0KCcvYXBpL3YyL3Rzcy9zZXR0aW5ncycpLnF1ZXJ5KHRydWUpLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgY29pblNldHRpbmdzOiB7fSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBjb25zdCB3ZWJhdXRobkluZm8gPSB7XG4gICAgICAgICAgICBvdHBEZXZpY2VJZDogJ2RldmljZS0xJyxcbiAgICAgICAgICAgIHByZlNhbHQ6ICdzYWx0LTEnLFxuICAgICAgICAgICAgcGFzc3BocmFzZTogJ3ByZi1kZXJpdmVkLXBhc3NwaHJhc2UnLFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgY3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAgICAgLnN0dWIoRUNEU0FVdGlscy5FY2RzYVV0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpXG4gICAgICAgICAgICAucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuICAgICAgICAgIGF3YWl0IGJpdGdvLmNvaW4oY29pbikua2V5Y2hhaW5zKCkuY3JlYXRlTXBjKHtcbiAgICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgICAgICBwYXNzcGhyYXNlOiAncGFzc3dvcmQnLFxuICAgICAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICAgICAgd2ViYXV0aG5JbmZvLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGNyZWF0ZUtleWNoYWlucy5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgICAgY3JlYXRlS2V5Y2hhaW5zLmZpcnN0Q2FsbC5hcmdzWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3ZWJhdXRobkluZm8nLCB3ZWJhdXRobkluZm8pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ1JlY3JlYXRlIEtleWNoYWlucyBmcm9tIE1QQ1YxIHRvIE1QQ1YyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29pbiA9ICdodGV0aCc7XG4gICAgICBjb25zdCB3YWxsZXRJZCA9ICd3YWxsZXRJZCc7XG4gICAgICBjb25zdCBvdHAgPSAnMDAwMDAwJztcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgICAgIGNvbnN0IGRlY3J5cHRSZXN1bHQgPSBKU09OLnN0cmluZ2lmeSh7IGtleTogJ2RlY3J5cHRlZCcgfSk7XG5cbiAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoJy9hcGkvdjIvdHNzL3NldHRpbmdzJylcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBjb2luU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgZXRoOiB7XG4gICAgICAgICAgICAgICAgd2FsbGV0Q3JlYXRpb25TZXR0aW5nczoge1xuICAgICAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBzYW5kYm94LnN0dWIoYml0Z28sICdkZWNyeXB0JykucmVzb2x2ZXMoZGVjcnlwdFJlc3VsdCk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgaWYgZW1wdHkgc3RyaW5ncyBhcmUgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtczogUGFyYW1ldGVyczxLZXljaGFpbnNbJ3JlY3JlYXRlTXBjJ10+WzBdID0ge1xuICAgICAgICAgIGNvaW4sXG4gICAgICAgICAgd2FsbGV0SWQsXG4gICAgICAgICAgb3RwLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzd29yZCcsXG4gICAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICAgIGVuY3J5cHRlZE1hdGVyaWFsOiB7XG4gICAgICAgICAgICBlbmNyeXB0ZWRVc2VyS2V5OiAnZW5jcnlwdGVkJyxcbiAgICAgICAgICAgIGVuY3J5cHRlZEJhY2t1cEtleTogJ2VuY3J5cHRlZCcsXG4gICAgICAgICAgICBlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlOiAncGFzc3BocmFzZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnMucmVjcmVhdGVNcGMoeyAuLi5wYXJhbXMsIGNvaW46ICcnIH0pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW0gY29pbicpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC5yZWNyZWF0ZU1wYyh7IC4uLnBhcmFtcywgd2FsbGV0SWQ6ICcnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW0gd2FsbGV0SWQnKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnMucmVjcmVhdGVNcGMoeyAuLi5wYXJhbXMsIG90cDogJycgfSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnbWlzc2luZyByZXF1aXJlZCBwYXJhbSBvdHAnKTtcblxuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAucmVjcmVhdGVNcGMoeyAuLi5wYXJhbXMsIHBhc3NwaHJhc2U6ICcnIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW0gcGFzc3BocmFzZScpO1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWluc1xuICAgICAgICAgIC5yZWNyZWF0ZU1wYyh7XG4gICAgICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgICAgICBlbmNyeXB0ZWRNYXRlcmlhbDoge1xuICAgICAgICAgICAgICAuLi5wYXJhbXMuZW5jcnlwdGVkTWF0ZXJpYWwsXG4gICAgICAgICAgICAgIGVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2U6ICcnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIGVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UnKTtcbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zXG4gICAgICAgICAgLnJlY3JlYXRlTXBjKHtcbiAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgIGVuY3J5cHRlZE1hdGVyaWFsOiB7XG4gICAgICAgICAgICAgIC4uLnBhcmFtcy5lbmNyeXB0ZWRNYXRlcmlhbCxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkVXNlcktleTogJycsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ21pc3NpbmcgcmVxdWlyZWQgcGFyYW0gZW5jcnlwdGVkVXNlcktleScpO1xuICAgICAgICBhd2FpdCBrZXljaGFpbnNcbiAgICAgICAgICAucmVjcmVhdGVNcGMoe1xuICAgICAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICAgICAgZW5jcnlwdGVkTWF0ZXJpYWw6IHtcbiAgICAgICAgICAgICAgLi4ucGFyYW1zLmVuY3J5cHRlZE1hdGVyaWFsLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRCYWNrdXBLZXk6ICcnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHBhcmFtIGVuY3J5cHRlZEJhY2t1cEtleScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCBpZiBvdHAgdW5sb2NrIGZhaWxzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL3VzZXIvdW5sb2NrJykucmVwbHlXaXRoRXJyb3IoJ290cCBlcnJvcicpO1xuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgY29pbixcbiAgICAgICAgICB3YWxsZXRJZCxcbiAgICAgICAgICBvdHAsXG4gICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICBlbmNyeXB0ZWRNYXRlcmlhbDoge1xuICAgICAgICAgICAgZW5jcnlwdGVkVXNlcktleTogJ2VuY3J5cHRlZFVzZXJLZXknLFxuICAgICAgICAgICAgZW5jcnlwdGVkQmFja3VwS2V5OiAnZW5jcnlwdGVkQmFja3VwS2V5JyxcbiAgICAgICAgICAgIGVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2U6ICdlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWlucy5yZWNyZWF0ZU1wYyhwYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ290cCBlcnJvcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgZmFpbCBpZiBwYXNzY29kZSByZWNvdmVyeSBhcGkgY2FsbCBmYWlscycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS91c2VyL3VubG9jaycpLnJlcGx5KDIwMCwgeyBvdHAgfSk7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvJHt3YWxsZXRJZH0vcGFzc2NvZGVyZWNvdmVyeWApXG4gICAgICAgICAgLnJlcGx5V2l0aEVycm9yKCdwYXNzY29kZSByZWNvdmVyeSBlcnJvcicpO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBjb2luLFxuICAgICAgICAgIHdhbGxldElkLFxuICAgICAgICAgIG90cCxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAncGFzc3dvcmQnLFxuICAgICAgICAgIGVuY3J5cHRlZE1hdGVyaWFsOiB7XG4gICAgICAgICAgICBlbmNyeXB0ZWRVc2VyS2V5OiAnZW5jcnlwdGVkVXNlcktleScsXG4gICAgICAgICAgICBlbmNyeXB0ZWRCYWNrdXBLZXk6ICdlbmNyeXB0ZWRCYWNrdXBLZXknLFxuICAgICAgICAgICAgZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZTogJ2VuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgYXdhaXQga2V5Y2hhaW5zLnJlY3JlYXRlTXBjKHBhcmFtcykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgncGFzc2NvZGUgcmVjb3ZlcnkgZXJyb3InKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGZhaWwgaWYgcGFzc2NvZGUgcmVjb3ZlcnkgYXBpIGNhbGwgcmV0dXJucyBpbnZhbGlkIHJlY292ZXJ5IGluZm8nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjEvdXNlci91bmxvY2snKS5yZXBseSgyMDAsIHsgb3RwIH0pO1xuICAgICAgICBub2NrKGJnVXJsKS5wb3N0KGAvYXBpL3YyLyR7Y29pbn0vd2FsbGV0LyR7d2FsbGV0SWR9L3Bhc3Njb2RlcmVjb3ZlcnlgKS5yZXBseSgyMDAsIHsgcmVjb3ZlcnlJbmZvOiB7fSB9KTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgY29pbixcbiAgICAgICAgICB3YWxsZXRJZCxcbiAgICAgICAgICBvdHAsXG4gICAgICAgICAgcGFzc3BocmFzZTogJ3Bhc3N3b3JkJyxcbiAgICAgICAgICBlbmNyeXB0ZWRNYXRlcmlhbDoge1xuICAgICAgICAgICAgZW5jcnlwdGVkVXNlcktleTogJ2VuY3J5cHRlZFVzZXJLZXknLFxuICAgICAgICAgICAgZW5jcnlwdGVkQmFja3VwS2V5OiAnZW5jcnlwdGVkQmFja3VwS2V5JyxcbiAgICAgICAgICAgIGVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2U6ICdlbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlJyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGF3YWl0IGtleWNoYWlucy5yZWNyZWF0ZU1wYyhwYXJhbXMpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ZhaWxlZCB0byBnZXQgcmVjb3ZlcnkgaW5mbycpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgY2FsbCBjcmVhdGVNcGMgd2l0aCB0aGUgY29ycmVjdCBwYXJhbWV0ZXJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL3VzZXIvdW5sb2NrJykucmVwbHkoMjAwLCB7IG90cCB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke2NvaW59L3dhbGxldC8ke3dhbGxldElkfS9wYXNzY29kZXJlY292ZXJ5YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IHJlY292ZXJ5SW5mbzogeyBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnMTIzJyB9IH0pO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBjb2luLFxuICAgICAgICAgIHdhbGxldElkOiAnd2FsbGV0SWQnLFxuICAgICAgICAgIG90cCxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAncGFzc3dvcmQnLFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICAgIGVuY3J5cHRlZE1hdGVyaWFsOiB7XG4gICAgICAgICAgICBlbmNyeXB0ZWRVc2VyS2V5OiAnZW5jcnlwdGVkVXNlcktleScsXG4gICAgICAgICAgICBlbmNyeXB0ZWRCYWNrdXBLZXk6ICdlbmNyeXB0ZWRCYWNrdXBLZXknLFxuICAgICAgICAgICAgZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZTogJ2VuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNyZWF0ZU1wY1N0dWIgPSBzaW5vbi5zdHViKGtleWNoYWlucywgJ2NyZWF0ZU1wYycpLnJlc29sdmVzKCk7XG4gICAgICAgIGF3YWl0IGtleWNoYWlucy5yZWNyZWF0ZU1wYyhwYXJhbXMpO1xuXG4gICAgICAgIGFzc2VydC5vayhcbiAgICAgICAgICBjcmVhdGVNcGNTdHViLmNhbGxlZE9uY2VXaXRoKHtcbiAgICAgICAgICAgIC4uLnBhcmFtcyxcbiAgICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgICAgICByZXRyb2ZpdDoge1xuICAgICAgICAgICAgICBkZWNyeXB0ZWRVc2VyS2V5OiBkZWNyeXB0UmVzdWx0LFxuICAgICAgICAgICAgICBkZWNyeXB0ZWRCYWNrdXBLZXk6IGRlY3J5cHRSZXN1bHQsXG4gICAgICAgICAgICAgIHdhbGxldElkOiBwYXJhbXMud2FsbGV0SWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyKGZ1bmN0aW9uIGFmdGVyVXBkYXRlUGFzc3dvcmQoKSB7XG4gICAgICBub2NrLnBlbmRpbmdNb2NrcygpLnNob3VsZC5iZS5lbXB0eSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQ3JlYXRlIEJpdEdvIEtleSBmcm9tIE9WQyBKU09OJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJpdEdvS2V5UmVzdWx0ID0ge1xuICAgICAgaWQ6ICc2NDIxZWI3NTVmZWE5ZTAwMDZjMmMwNDAwNzJmNzRiYicsXG4gICAgICBjb21tb25LZXljaGFpbjogJzEyMycsXG4gICAgICB3YWxsZXRIU01HUEdQdWJsaWNLZXlTaWdzOiAnMTIzJyxcbiAgICAgIHZlcmlmaWVkVnNzUHJvb2Y6IHRydWUsXG4gICAgICBrZXlTaGFyZXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGZyb206ICdiaXRnbycsXG4gICAgICAgICAgdG86ICd1c2VyJyxcbiAgICAgICAgICBwdWJsaWNTaGFyZTogJ2NjYycsXG4gICAgICAgICAgcHJpdmF0ZVNoYXJlOiAnY2NjIHByaXZhdGUnLFxuICAgICAgICAgIHBhaWxsaWVyUHVibGljS2V5OiAnY2NjIHBhaWxsaWVyJyxcbiAgICAgICAgICB2c3NQcm9vZjogJ2NjYyB2c3MgcHJvb2YnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgZnJvbTogJ2JpdGdvJyxcbiAgICAgICAgICB0bzogJ2JhY2t1cCcsXG4gICAgICAgICAgcHVibGljU2hhcmU6ICdmZmYnLFxuICAgICAgICAgIHByaXZhdGVTaGFyZTogJ2ZmZiBwcml2YXRlJyxcbiAgICAgICAgICBwYWlsbGllclB1YmxpY0tleTogJ2ZmZiBwYWlsbGllcicsXG4gICAgICAgICAgdnNzUHJvb2Y6ICdmZmYgdnNzIHByb29mJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIGNvbnN0IG92Y091dHB1dEpzb24gPSB7XG4gICAgICB0c3NWZXJzaW9uOiAnMC4wLjEnLFxuICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICBjb2luOiAnc29sJyxcbiAgICAgIHN0YXRlOiAxLFxuICAgICAgb3ZjOiB7XG4gICAgICAgIDE6IHtcbiAgICAgICAgICBncGdQdWJLZXk6XG4gICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuXFxueGs4RVpCc3E5Uk1GSzRFRUFBb0NBd1JnRHBnbTFicHRSVDV5TE9NYWRjR0FIdXZreElTTDgvM3hQeS9EXFxuWUErMU5nQnFJRksvM09PWHhwNzNUdjg2YnQxZGdIN09EMUFDTzBtVlhBb1g1RWFWeldadmRtTXRNUzExXFxuYzJWeUxXUm1NalF3T1dZME5XTmhNVFptTlRVM09HTmtNekF4TXlBOGIzWmpMVEV0ZFhObGNpMWtaakkwXFxuTURsbU5EVmpZVEUyWmpVMU56aGpaRE13TVROQVpHWXlOREE1WmpRMVkyRXhObVkxTlRjNFkyUXpNREV6XFxuTG1OdmJUN0NqQVFRRXdnQUhRVUNaQnNxOVFRTENRY0lBeFVJQ2dRV0FBSUJBaGtCQWhzREFoNEJBQ0VKXFxuRU9VZUM3UXJHTCsyRmlFRWpONnZQVUZSd2VWdERLRlo1UjRMdENzWXY3WjdvQUVBdk5LYUpyVElzM2t5XFxuYnhqa1VpY3N1eE95QTJvV0dhckpINlRHbFdGNldEOEEvM0VJZVp6UEtTTGFXKzNlbnBiQ1BpVThSVkRwXFxuQzZ5bzZOTUFxS3A0WGx5UXpsTUVaQnNxOVJJRks0RUVBQW9DQXdRV2xXUE5NcGszYWZFemZnRzB4Rmc0XFxuQ0VqWTdmR08zNW40N25aNHF4akVYejJYTjRJMjN4Rk1pd1piWGJwdERYbHFtN1c5WkFIS2k4OTJoK1l0XFxuVTRCNkF3RUlCOEo0QkJnVENBQUpCUUprR3lyMUFoc01BQ0VKRU9VZUM3UXJHTCsyRmlFRWpONnZQVUZSXFxud2VWdERLRlo1UjRMdENzWXY3WXFad0Q4RExSdW5lQjBIRXpCQ3lyRTRZTCtVSGFvZm9IUVgxK25SaDBqXFxuODJxYUR6QUEvaTNVMVNvRUlpMzJZTXJvck5HNTB2YjR2YUVQYmJZbWZnbGIrSlExWXg3b1xcbj12amdsXFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgb3ZjVG9CaXRnb1NoYXJlOiB7XG4gICAgICAgICAgICBwdWJsaWNTaGFyZTpcbiAgICAgICAgICAgICAgJzA3YmZiYjA1MmExZjRiMTA2YjMxNWJkNWE5ZDZhNzE2MDQ2NTMyODlmODYxMzIwZDk4MDE4ODFlOTUyZjg1NTA3NTNjODk1MTFhMzYwZTNiNTk5ZDlmMjM5YThkMzZhNDk1NjQzN2VkMGIxNTIxODBlMjJjYjk0ZmIwOGZkYzgxJyxcbiAgICAgICAgICAgIHByaXZhdGVTaGFyZTpcbiAgICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcblxcbndYNERVUThYaEdWR2NUSVNBZ01FZC93US9BaHdJUnNTZi82aUh3bUhLdkVZQXdmYUx0VFFvdFM2QndabVxcbmFYMDBUN0x1bUdJck5aekJnY2dnQktNbCs4T21vbThtWDVzUDhGVUU0NTFpWmpCbVhsa3BIbHBBcXNrU1xcbkVpNVNmamxzVDMxdXRvTGFCTEE3TmpOU215WUhJaXlmaDZZbndmVjVVNzJrNmhoZnB1RFNzUUd5OFl4cFxcbk0yZFZsTjR1b08zMXpnUVBmK2ZnSmtadkFQd3ZqWUxCTDRPOGhzMjFIR2YwVnZHOTlicms0eGxGVlJod1xcblFudVBwTTUxR09zNHZVdGJMTlNZbkF1aFU0UmVYd3dEVjlYdTBNWEFqZlFNazJFM3dRTEdRKzgydXYyQlxcbjFoUEQ5bkRIVHRBZFdyWGQ2WmpYRnJHNE1mMk1RQnh5U0Z2VlNuRmk2eVN0amZaZWlLY0Q1VmczOFBqR1xcbldnMU81TjMvcGFxOThIZkgwUTRxTktHWmxqd28zb0VRWnpsWW0ya1ZuSTBQVUxvTVlnPT1cXG49b3ZBeFxcbi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS1cXG4nLFxuICAgICAgICAgICAgdnNzUHJvb2Y6ICdiZTgxOThjMmNlZjk0Y2IzODFhYThhYTkyNzdhMGE0NmJhNWE1NGIwYWM5OTMwMDM0YjRhZjY2YjFiODA1MjM0JyxcbiAgICAgICAgICAgIGk6IDMsXG4gICAgICAgICAgICBqOiAxLFxuICAgICAgICAgICAgdVNpZzogJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNxOVJNRks0RUVBQW9DQXdSZ0RwZ20xYnB0UlQ1eUxPTWFkY0dBSHV2a3hJU0w4LzN4UHkvRFxcbllBKzFOZ0JxSUZLLzNPT1h4cDczVHY4NmJ0MWRnSDdPRDFBQ08wbVZYQW9YNUVhVnpXWnZkbU10TVMxMVxcbmMyVnlMV1JtTWpRd09XWTBOV05oTVRabU5UVTNPR05rTXpBeE15QThiM1pqTFRFdGRYTmxjaTFrWmpJMFxcbk1EbG1ORFZqWVRFMlpqVTFOemhqWkRNd01UTkFaR1l5TkRBNVpqUTFZMkV4Tm1ZMU5UYzRZMlF6TURFelxcbkxtTnZiVDdDakFRUUV3Z0FIUVVDWkJzcTlRUUxDUWNJQXhVSUNnUVdBQUlCQWhrQkFoc0RBaDRCQUNFSlxcbkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUndlVnRES0ZaNVI0THRDc1l2N1o3b0FFQXZOS2FKclRJczNreVxcbmJ4amtVaWNzdXhPeUEyb1dHYXJKSDZUR2xXRjZXRDhBLzNFSWVaelBLU0xhVyszZW5wYkNQaVU4UlZEcFxcbkM2eW82Tk1BcUtwNFhseVF6bE1FWkJzcTlSSUZLNEVFQUFvQ0F3UVdsV1BOTXBrM2FmRXpmZ0cweEZnNFxcbkNFalk3ZkdPMzVuNDduWjRxeGpFWHoyWE40STIzeEZNaXdaYlhicHREWGxxbTdXOVpBSEtpODkyaCtZdFxcblU0QjZBd0VJQjhKNEJCZ1RDQUFKQlFKa0d5cjFBaHNNQUNFSkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUlxcbndlVnRES0ZaNVI0THRDc1l2N1lxWndEOERMUnVuZUIwSEV6QkN5ckU0WUwrVUhhb2ZvSFFYMStuUmgwalxcbjgycWFEekFBL2kzVTFTb0VJaTMyWU1yb3JORzUwdmI0dmFFUGJiWW1mZ2xiK0pRMVl4N296ak1FWkJzcVxcbjlSWUpLd1lCQkFIYVJ3OEJBUWRBUzE1MzRMZENDNjBBU3BFZ25FQkM4cFdQU09XV0JMWHlXYUJoRU9XMlxcbi9pakNlQVFZRXdnQUNRVUNaQnNxOVFJYklBQWhDUkRsSGd1MEt4aS90aFloQkl6ZXJ6MUJVY0hsYlF5aFxcbldlVWVDN1FyR0wrMkZVWUEvQWdNVTRWN0M3SS81SHdLNzNtY3RhR1hOZGZWci9tdVJNTk9HVy9DQXhWTFxcbkFQOUthQnI5NW8zMm9FTjVlbzd0V0ZCeW9PQ0NrOUpNanMzNkNxN28rc1IzMUE9PVxcbj1lWjNCXFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgMjoge1xuICAgICAgICAgIGdwZ1B1YktleTpcbiAgICAgICAgICAgICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG5cXG54azhFWkJzck5CTUZLNEVFQUFvQ0F3VDJ4WHYvbUcvZGFQZEtHRC9mSElVRUUyWnRjSytuanRDWnRNRXJcXG5rSXVibVV3ZTNEajgraFF4dDNTS2FUeFFidUQrV2FMU2o5ODZRWVVyNFp3NFQrVzN6V3B2ZG1NdE1pMWlcXG5ZV05yZFhBdE5UUTNZbUprWmpNd09HTXhaVFl4WTJRNVpHSTRObVU0SUR4dmRtTXRNaTFpWVdOcmRYQXRcXG5OVFEzWW1Ka1pqTXdPR014WlRZeFkyUTVaR0k0Tm1VNFFEVTBOMkppWkdZek1EaGpNV1UyTVdOa09XUmlcXG5PRFpsT0M1amIyMCt3b3dFRUJNSUFCMEZBbVFiS3pRRUN3a0hDQU1WQ0FvRUZnQUNBUUlaQVFJYkF3SWVcXG5BUUFoQ1JDMkFrNUcyU2s3WlJZaEJMVHBTa0ZPZTNhamJxb3VlcllDVGtiWktUdGx4dFlCQUxMSUJuQWFcXG40QVM3N1h2WG1tem5OQ1dPL0hOdURQRDJ1Z1JxVmhxVTRTeG1BUURtYTE0QVB1TU5TVnlpMTd4b21aaldcXG4wbmltdGFNSUJqYzBBNE1YRTZHNFhjNVRCR1FiS3pRU0JTdUJCQUFLQWdNRVVIb1FEWTk4eThDQVZvdXVcXG55NHkzUTJRbkJwblVCSy8wUEVMVjdWQU5YZDlsWTdDU2h5b2dKU2NnUGxpVW05N0F1OUZDMTd2cVphMUJcXG41YkJNSkFkWFZ3TUJDQWZDZUFRWUV3Z0FDUVVDWkJzck5BSWJEQUFoQ1JDMkFrNUcyU2s3WlJZaEJMVHBcXG5Ta0ZPZTNhamJxb3VlcllDVGtiWktUdGxSNXdBLzN6T0ZUU2VYWFJSZW1YbDNoWTEwc3B4YWJFNE8ySjhcXG5aRDJWUmZqYkRwWmpBUURXZzFXK2pQYk0ySHRpa2QxTjAxVit6d2VORGhKRUg2NXIwUXI4QmxYaDJ3PT1cXG49RXR0dVxcbi0tLS0tRU5EIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG4nLFxuICAgICAgICAgIG92Y1RvQml0Z29TaGFyZToge1xuICAgICAgICAgICAgcHVibGljU2hhcmU6XG4gICAgICAgICAgICAgICdlY2Y5NWU5YmE2ZjAyYzBiYzRjMmFiMjU0NTY1ZDIxYTE1NjIwNTljOGExYWI3MGQyODZmYTA0YWUyYzUxMWUwNDkxNDEwYjZkNmZhOGFiMjJlNjkxYmVkNzkzOGE3YWRhYWJmYThkOWQ1OWFhYjljYzJjMDc4Y2QzN2RkZTAxYicsXG4gICAgICAgICAgICBwcml2YXRlU2hhcmU6XG4gICAgICAgICAgICAgICctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS1cXG5cXG53WDREVVE4WGhHVkdjVElTQWdNRWUxbllOdjlEbkhsOEhYOGpOczNyZUdzNW5QVDJiTnpHTUNGTDBOM1BcXG5LTHdHZDhEQmtESklNcG9DbGFBUy9IVFVUUFRSemo0VTFHU2hWNzlJK2JiZlREQlY2dWh5Zlo3YTg4ZFZcXG5SRFRYbDZyY2hGbC9mbXdMb1hucUgrQkRQRVh5dHBBdkt3RHJBZzU1VC9IN2FvcDVRYmZTc1FFckV2N1hcXG5UcFRMSEhIZmxFRVFMNjJwMVJubnEya0t2d0pLN1RZMWc1UnRQZ1lYSDZHRXMzM0RMdWxQZVVzOFVrS3FcXG5UUExmMisxS0NMWXl6TXdtU2k4S0VDOEhKYjB2QWtYWkFsWjErRG9aMlBmaUlKY1ZuejdhM29tamlQNzdcXG5obUM4cGhUY0o3MThVeElCMDlmOHVpYzAvZk03Rk51MEpIRmdSREE2OXp6ZUZZblpjMlhOUWc1aHMvZFpcXG5aOEFpdFA0cm5hQWZwcnNxNHJBRUUvYzNUcm05dHpRSFpQQ3FyLzJzNExsdXlVTVZKdz09XFxuPUlKWkhcXG4tLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxuJyxcbiAgICAgICAgICAgIHZzc1Byb29mOiAnMzA5ZDJmZWYyMjcyYWQzMTM3NTk1NGI5OWE4NjI3NDJmMjJkODAyM2VlZjk4NTViOGFlMjZlYTg0ZTA4YmY1ZScsXG4gICAgICAgICAgICBpOiAzLFxuICAgICAgICAgICAgajogMixcbiAgICAgICAgICAgIHVTaWc6ICctLS0tLUJFR0lOIFBHUCBQVUJMSUMgS0VZIEJMT0NLLS0tLS1cXG5cXG54azhFWkJzck5CTUZLNEVFQUFvQ0F3VDJ4WHYvbUcvZGFQZEtHRC9mSElVRUUyWnRjSytuanRDWnRNRXJcXG5rSXVibVV3ZTNEajgraFF4dDNTS2FUeFFidUQrV2FMU2o5ODZRWVVyNFp3NFQrVzN6V3B2ZG1NdE1pMWlcXG5ZV05yZFhBdE5UUTNZbUprWmpNd09HTXhaVFl4WTJRNVpHSTRObVU0SUR4dmRtTXRNaTFpWVdOcmRYQXRcXG5OVFEzWW1Ka1pqTXdPR014WlRZeFkyUTVaR0k0Tm1VNFFEVTBOMkppWkdZek1EaGpNV1UyTVdOa09XUmlcXG5PRFpsT0M1amIyMCt3b3dFRUJNSUFCMEZBbVFiS3pRRUN3a0hDQU1WQ0FvRUZnQUNBUUlaQVFJYkF3SWVcXG5BUUFoQ1JDMkFrNUcyU2s3WlJZaEJMVHBTa0ZPZTNhamJxb3VlcllDVGtiWktUdGx4dFlCQUxMSUJuQWFcXG40QVM3N1h2WG1tem5OQ1dPL0hOdURQRDJ1Z1JxVmhxVTRTeG1BUURtYTE0QVB1TU5TVnlpMTd4b21aaldcXG4wbmltdGFNSUJqYzBBNE1YRTZHNFhjNVRCR1FiS3pRU0JTdUJCQUFLQWdNRVVIb1FEWTk4eThDQVZvdXVcXG55NHkzUTJRbkJwblVCSy8wUEVMVjdWQU5YZDlsWTdDU2h5b2dKU2NnUGxpVW05N0F1OUZDMTd2cVphMUJcXG41YkJNSkFkWFZ3TUJDQWZDZUFRWUV3Z0FDUVVDWkJzck5BSWJEQUFoQ1JDMkFrNUcyU2s3WlJZaEJMVHBcXG5Ta0ZPZTNhamJxb3VlcllDVGtiWktUdGxSNXdBLzN6T0ZUU2VYWFJSZW1YbDNoWTEwc3B4YWJFNE8ySjhcXG5aRDJWUmZqYkRwWmpBUURXZzFXK2pQYk0ySHRpa2QxTjAxVit6d2VORGhKRUg2NXIwUXI4QmxYaDI4NHpcXG5CR1FiS3pRV0NTc0dBUVFCMmtjUEFRRUhRSVZUbWx0OGEvZmpKQ1k5VXlQOEo1MWVUUFg5UE1SRjMvSHJcXG5CWXd0Zk9aWXduZ0VHQk1JQUFrRkFtUWJLelFDR3lBQUlRa1F0Z0pPUnRrcE8yVVdJUVMwNlVwQlRudDJcXG5vMjZxTG5xMkFrNUcyU2s3WmN0aEFRRDRlazNhcVVERWJoZlJIb2xtNGpGaElQSWJiOWhVSnd1QlIwUjRcXG4rZ3ZhZUFFQWs4dWs1Y0VBQ2VxbXBkRUY1Mm9HeDdqbUdDb1g3M0FJSUxZVmNmOWlNa0k9XFxuPTkySGZcXG4tLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG92Y1RvT3ZjU2hhcmU6IHtcbiAgICAgICAgICAgIHB1YmxpY1NoYXJlOlxuICAgICAgICAgICAgICAnZWNmOTVlOWJhNmYwMmMwYmM0YzJhYjI1NDU2NWQyMWExNTYyMDU5YzhhMWFiNzBkMjg2ZmEwNGFlMmM1MTFlMDQ5MTQxMGI2ZDZmYThhYjIyZTY5MWJlZDc5MzhhN2FkYWFiZmE4ZDlkNTlhYWI5Y2MyYzA3OGNkMzdkZGUwMWInLFxuICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOlxuICAgICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tXFxuXFxud1g0RCtGM3ZJOTYyelZNU0FnTUVOeTJYOXhESU9tMWd3T2ZNZEwvMXZaamVNVy9pbGUvZjJkUklQMkdWXFxudjR3NjBLOTIrbUhJOXlvb1UxVlQ3N2paclZPY05LNDFERk5DRi9mdW9VVStWekJPTjBJMWhIeVhtMlFKXFxud0wrbk5kdkFYd1J2N25TRkQzQUJVbVJZZEc3MUFGSVdqVzJMKzFDMmh4cHNObG1keGZmU3NRSEhUOXVQXFxuQk5wRllnUU43N09VeGNncndlU1ZyUHllcjFyQ1E4bytRbm9LMi9oSXg5UGxKWmtjbDN1d0Y2VHBCdGpzXFxucXZSeFRob21vSHlvMGhKSEcwdm1JNDJHcTV1MHRjU2VVOTAyZWZwQ0RhZUpoUFZPaXFJU29KOTZ3bjByXFxuRkIzbFlMU2ZsT3BDTEFFN25zWkpSb1hBNmFrVTd4TUNNTkErK2Q0dHY2cDk4RlErTVo2ZTl4NmtpU3cxXFxuTStWV2orUHZOMWR0UThmTll3cEpmN0tCZkQxdzZJU01GRG1ld2tERTdpQk9YRjZGTHc9PVxcbj0rM1ljXFxuLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLVxcbicsXG4gICAgICAgICAgICB2c3NQcm9vZjogJzMwOWQyZmVmMjI3MmFkMzEzNzU5NTRiOTlhODYyNzQyZjIyZDgwMjNlZWY5ODU1YjhhZTI2ZWE4NGUwOGJmNWUnLFxuICAgICAgICAgICAgaTogMSxcbiAgICAgICAgICAgIGo6IDIsXG4gICAgICAgICAgICB1U2lnOiAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuXFxueGs4RVpCc3JOQk1GSzRFRUFBb0NBd1QyeFh2L21HL2RhUGRLR0QvZkhJVUVFMlp0Y0srbmp0Q1p0TUVyXFxua0l1Ym1Vd2UzRGo4K2hReHQzU0thVHhRYnVEK1dhTFNqOTg2UVlVcjRadzRUK1czeldwdmRtTXRNaTFpXFxuWVdOcmRYQXROVFEzWW1Ka1pqTXdPR014WlRZeFkyUTVaR0k0Tm1VNElEeHZkbU10TWkxaVlXTnJkWEF0XFxuTlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRRRFUwTjJKaVpHWXpNRGhqTVdVMk1XTmtPV1JpXFxuT0RabE9DNWpiMjArd293RUVCTUlBQjBGQW1RYkt6UUVDd2tIQ0FNVkNBb0VGZ0FDQVFJWkFRSWJBd0llXFxuQVFBaENSQzJBazVHMlNrN1pSWWhCTFRwU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRseHRZQkFMTElCbkFhXFxuNEFTNzdYdlhtbXpuTkNXTy9ITnVEUEQydWdScVZocVU0U3htQVFEbWExNEFQdU1OU1Z5aTE3eG9tWmpXXFxuMG5pbXRhTUlCamMwQTRNWEU2RzRYYzVUQkdRYkt6UVNCU3VCQkFBS0FnTUVVSG9RRFk5OHk4Q0FWb3V1XFxueTR5M1EyUW5CcG5VQksvMFBFTFY3VkFOWGQ5bFk3Q1NoeW9nSlNjZ1BsaVVtOTdBdTlGQzE3dnFaYTFCXFxuNWJCTUpBZFhWd01CQ0FmQ2VBUVlFd2dBQ1FVQ1pCc3JOQUliREFBaENSQzJBazVHMlNrN1pSWWhCTFRwXFxuU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRsUjV3QS8zek9GVFNlWFhSUmVtWGwzaFkxMHNweGFiRTRPMko4XFxuWkQyVlJmamJEcFpqQVFEV2cxVytqUGJNMkh0aWtkMU4wMVYrendlTkRoSkVINjVyMFFyOEJsWGgyODR6XFxuQkdRYkt6UVdDU3NHQVFRQjJrY1BBUUVIUU5WR2cwdlBzZksxeUpqRnVEWUI4VGo3Q1FSSEtHQVZFRGNqXFxuaC9RSXFyMEt3bmdFR0JNSUFBa0ZBbVFiS3pRQ0d5QUFJUWtRdGdKT1J0a3BPMlVXSVFTMDZVcEJUbnQyXFxubzI2cUxucTJBazVHMlNrN1pTOW9BUUNlMnpKRDVJdFcyR0VnQWl0blkrTnJMQmpiWEk2K0xZMjlHalJhXFxuZjZ5RlRRRC9jUDBFMURsZXFYTWpnZlIrZXd0NnF1VkZNWmViaHIzdEJyL0gwWnYvOUVBPVxcbj04YWkrXFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCBleHBlY3RlZEJpdEdvT3V0cHV0ID0ge1xuICAgICAgd2FsbGV0OiB7XG4gICAgICAgIC4uLm92Y091dHB1dEpzb24sXG4gICAgICAgIHN0YXRlOiAyLFxuICAgICAgICBwbGF0Zm9ybToge1xuICAgICAgICAgIGNvbW1vbktleWNoYWluOiBiaXRHb0tleVJlc3VsdC5jb21tb25LZXljaGFpbixcbiAgICAgICAgICB3YWxsZXRHcGdQdWJLZXlTaWdzOiBiaXRHb0tleVJlc3VsdC53YWxsZXRIU01HUEdQdWJsaWNLZXlTaWdzLFxuICAgICAgICAgIG92Yzoge1xuICAgICAgICAgICAgMToge1xuICAgICAgICAgICAgICBiaXRnb1RvT3ZjU2hhcmU6IHtcbiAgICAgICAgICAgICAgICBpOiAxLFxuICAgICAgICAgICAgICAgIGo6IDMsXG4gICAgICAgICAgICAgICAgcHVibGljU2hhcmU6IGJpdEdvS2V5UmVzdWx0LmtleVNoYXJlc1swXS5wdWJsaWNTaGFyZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlU2hhcmU6IGJpdEdvS2V5UmVzdWx0LmtleVNoYXJlc1swXS5wcml2YXRlU2hhcmUsXG4gICAgICAgICAgICAgICAgcGFpbGxpZXJQdWJsaWNLZXk6IGJpdEdvS2V5UmVzdWx0LmtleVNoYXJlc1swXS5wYWlsbGllclB1YmxpY0tleSxcbiAgICAgICAgICAgICAgICB2c3NQcm9vZjogYml0R29LZXlSZXN1bHQua2V5U2hhcmVzWzBdLnZzc1Byb29mLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIDI6IHtcbiAgICAgICAgICAgICAgYml0Z29Ub092Y1NoYXJlOiB7XG4gICAgICAgICAgICAgICAgaTogMixcbiAgICAgICAgICAgICAgICBqOiAzLFxuICAgICAgICAgICAgICAgIHB1YmxpY1NoYXJlOiBiaXRHb0tleVJlc3VsdC5rZXlTaGFyZXNbMV0ucHVibGljU2hhcmUsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOiBiaXRHb0tleVJlc3VsdC5rZXlTaGFyZXNbMV0ucHJpdmF0ZVNoYXJlLFxuICAgICAgICAgICAgICAgIHBhaWxsaWVyUHVibGljS2V5OiBiaXRHb0tleVJlc3VsdC5rZXlTaGFyZXNbMV0ucGFpbGxpZXJQdWJsaWNLZXksXG4gICAgICAgICAgICAgICAgdnNzUHJvb2Y6IGJpdEdvS2V5UmVzdWx0LmtleVNoYXJlc1sxXS52c3NQcm9vZixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBpdCgnUGFyc2VzIHRoZSBPVkMgSlNPTiBmaWxlIHByb3Blcmx5IGFuZCBjcmVhdGVzIHRoZSBuZXh0IGlucHV0IGZvciBPVkMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90c29sL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJywga2V5VHlwZTogJ3RzcycgfSkpXG4gICAgICAgIC5yZXBseSgyMDAsIGJpdEdvS2V5UmVzdWx0KTtcbiAgICAgIGNvbnN0IHBsYXRmb3JtT3V0cHV0ID0gYXdhaXQgYml0Z28uY29pbigndHNvbCcpLmtleWNoYWlucygpLmNyZWF0ZVRzc0JpdEdvS2V5RnJvbU92Y1NoYXJlcyhvdmNPdXRwdXRKc29uKTtcbiAgICAgIHNob3VsZC5lcXVhbChwbGF0Zm9ybU91dHB1dC5iaXRHb0tleUlkLCBiaXRHb0tleVJlc3VsdC5pZCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHBsYXRmb3JtT3V0cHV0LmJpdEdvT3V0cHV0SnNvbkZvck92YywgZXhwZWN0ZWRCaXRHb091dHB1dCk7XG4gICAgfSk7XG5cbiAgICBpdCgnUGFzc2VzIHRoZSBlbnRlcnByaXNlIHdpdGggY29ycmVjdCB2YWx1ZSB0byBiaXRnbyBpZiBwcm92aWRlZCBieSBjYWxsZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnb05vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90c29sL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJywga2V5VHlwZTogJ3RzcycgfSkpXG4gICAgICAgIC5yZXBseSgyMDAsICh1cmksIGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VudGVycHJpc2UnKTtcbiAgICAgICAgICBib2R5LmVudGVycHJpc2Uuc2hvdWxkLmVxdWFsKCdlbnRlcnByaXNlSWQnKTtcbiAgICAgICAgICByZXR1cm4gYml0R29LZXlSZXN1bHQ7XG4gICAgICAgIH0pO1xuICAgICAgY29uc3QgcGxhdGZvcm1PdXRwdXQgPSBhd2FpdCBiaXRnb1xuICAgICAgICAuY29pbigndHNvbCcpXG4gICAgICAgIC5rZXljaGFpbnMoKVxuICAgICAgICAuY3JlYXRlVHNzQml0R29LZXlGcm9tT3ZjU2hhcmVzKG92Y091dHB1dEpzb24sICdlbnRlcnByaXNlSWQnKTtcbiAgICAgIHNob3VsZC5lcXVhbChwbGF0Zm9ybU91dHB1dC5iaXRHb0tleUlkLCBiaXRHb0tleVJlc3VsdC5pZCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHBsYXRmb3JtT3V0cHV0LmJpdEdvT3V0cHV0SnNvbkZvck92YywgZXhwZWN0ZWRCaXRHb091dHB1dCk7XG4gICAgICBiaXRnb05vY2suaXNEb25lKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnU2hvdWxkIGZhaWwgaWYgdGhlIHN0YXRlIGlzIG5vdCAxJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgb3ZjT3V0cHV0SnNvbiA9IHtcbiAgICAgICAgdHNzVmVyc2lvbjogJzAuMC4xJyxcbiAgICAgICAgd2FsbGV0VHlwZTogJ3RzcycsXG4gICAgICAgIGNvaW46ICdzb2wnLFxuICAgICAgICBzdGF0ZTogMCxcbiAgICAgICAgb3ZjOiB7XG4gICAgICAgICAgMToge1xuICAgICAgICAgICAgZ3BnUHViS2V5OlxuICAgICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuXFxueGs4RVpCc3E5Uk1GSzRFRUFBb0NBd1JnRHBnbTFicHRSVDV5TE9NYWRjR0FIdXZreElTTDgvM3hQeS9EXFxuWUErMU5nQnFJRksvM09PWHhwNzNUdjg2YnQxZGdIN09EMUFDTzBtVlhBb1g1RWFWeldadmRtTXRNUzExXFxuYzJWeUxXUm1NalF3T1dZME5XTmhNVFptTlRVM09HTmtNekF4TXlBOGIzWmpMVEV0ZFhObGNpMWtaakkwXFxuTURsbU5EVmpZVEUyWmpVMU56aGpaRE13TVROQVpHWXlOREE1WmpRMVkyRXhObVkxTlRjNFkyUXpNREV6XFxuTG1OdmJUN0NqQVFRRXdnQUhRVUNaQnNxOVFRTENRY0lBeFVJQ2dRV0FBSUJBaGtCQWhzREFoNEJBQ0VKXFxuRU9VZUM3UXJHTCsyRmlFRWpONnZQVUZSd2VWdERLRlo1UjRMdENzWXY3WjdvQUVBdk5LYUpyVElzM2t5XFxuYnhqa1VpY3N1eE95QTJvV0dhckpINlRHbFdGNldEOEEvM0VJZVp6UEtTTGFXKzNlbnBiQ1BpVThSVkRwXFxuQzZ5bzZOTUFxS3A0WGx5UXpsTUVaQnNxOVJJRks0RUVBQW9DQXdRV2xXUE5NcGszYWZFemZnRzB4Rmc0XFxuQ0VqWTdmR08zNW40N25aNHF4akVYejJYTjRJMjN4Rk1pd1piWGJwdERYbHFtN1c5WkFIS2k4OTJoK1l0XFxuVTRCNkF3RUlCOEo0QkJnVENBQUpCUUprR3lyMUFoc01BQ0VKRU9VZUM3UXJHTCsyRmlFRWpONnZQVUZSXFxud2VWdERLRlo1UjRMdENzWXY3WXFad0Q4RExSdW5lQjBIRXpCQ3lyRTRZTCtVSGFvZm9IUVgxK25SaDBqXFxuODJxYUR6QUEvaTNVMVNvRUlpMzJZTXJvck5HNTB2YjR2YUVQYmJZbWZnbGIrSlExWXg3b1xcbj12amdsXFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgICBvdmNUb0JpdGdvU2hhcmU6IHtcbiAgICAgICAgICAgICAgcHVibGljU2hhcmU6XG4gICAgICAgICAgICAgICAgJzA3YmZiYjA1MmExZjRiMTA2YjMxNWJkNWE5ZDZhNzE2MDQ2NTMyODlmODYxMzIwZDk4MDE4ODFlOTUyZjg1NTA3NTNjODk1MTFhMzYwZTNiNTk5ZDlmMjM5YThkMzZhNDk1NjQzN2VkMGIxNTIxODBlMjJjYjk0ZmIwOGZkYzgxJyxcbiAgICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOlxuICAgICAgICAgICAgICAgICctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS1cXG5cXG53WDREVVE4WGhHVkdjVElTQWdNRWQvd1EvQWh3SVJzU2YvNmlId21IS3ZFWUF3ZmFMdFRRb3RTNkJ3Wm1cXG5hWDAwVDdMdW1HSXJOWnpCZ2NnZ0JLTWwrOE9tb204bVg1c1A4RlVFNDUxaVpqQm1YbGtwSGxwQXFza1NcXG5FaTVTZmpsc1QzMXV0b0xhQkxBN05qTlNteVlISWl5Zmg2WW53ZlY1VTcyazZoaGZwdURTc1FHeThZeHBcXG5NMmRWbE40dW9PMzF6Z1FQZitmZ0prWnZBUHd2allMQkw0TzhoczIxSEdmMFZ2Rzk5YnJrNHhsRlZSaHdcXG5RbnVQcE01MUdPczR2VXRiTE5TWW5BdWhVNFJlWHd3RFY5WHUwTVhBamZRTWsyRTN3UUxHUSs4MnV2MkJcXG4xaFBEOW5ESFR0QWRXclhkNlpqWEZyRzRNZjJNUUJ4eVNGdlZTbkZpNnlTdGpmWmVpS2NENVZnMzhQakdcXG5XZzFPNU4zL3BhcTk4SGZIMFE0cU5LR1psandvM29FUVp6bFltMmtWbkkwUFVMb01ZZz09XFxuPW92QXhcXG4tLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxuJyxcbiAgICAgICAgICAgICAgdnNzUHJvb2Y6ICdiZTgxOThjMmNlZjk0Y2IzODFhYThhYTkyNzdhMGE0NmJhNWE1NGIwYWM5OTMwMDM0YjRhZjY2YjFiODA1MjM0JyxcbiAgICAgICAgICAgICAgaTogMyxcbiAgICAgICAgICAgICAgajogMSxcbiAgICAgICAgICAgICAgdVNpZzogJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNxOVJNRks0RUVBQW9DQXdSZ0RwZ20xYnB0UlQ1eUxPTWFkY0dBSHV2a3hJU0w4LzN4UHkvRFxcbllBKzFOZ0JxSUZLLzNPT1h4cDczVHY4NmJ0MWRnSDdPRDFBQ08wbVZYQW9YNUVhVnpXWnZkbU10TVMxMVxcbmMyVnlMV1JtTWpRd09XWTBOV05oTVRabU5UVTNPR05rTXpBeE15QThiM1pqTFRFdGRYTmxjaTFrWmpJMFxcbk1EbG1ORFZqWVRFMlpqVTFOemhqWkRNd01UTkFaR1l5TkRBNVpqUTFZMkV4Tm1ZMU5UYzRZMlF6TURFelxcbkxtTnZiVDdDakFRUUV3Z0FIUVVDWkJzcTlRUUxDUWNJQXhVSUNnUVdBQUlCQWhrQkFoc0RBaDRCQUNFSlxcbkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUndlVnRES0ZaNVI0THRDc1l2N1o3b0FFQXZOS2FKclRJczNreVxcbmJ4amtVaWNzdXhPeUEyb1dHYXJKSDZUR2xXRjZXRDhBLzNFSWVaelBLU0xhVyszZW5wYkNQaVU4UlZEcFxcbkM2eW82Tk1BcUtwNFhseVF6bE1FWkJzcTlSSUZLNEVFQUFvQ0F3UVdsV1BOTXBrM2FmRXpmZ0cweEZnNFxcbkNFalk3ZkdPMzVuNDduWjRxeGpFWHoyWE40STIzeEZNaXdaYlhicHREWGxxbTdXOVpBSEtpODkyaCtZdFxcblU0QjZBd0VJQjhKNEJCZ1RDQUFKQlFKa0d5cjFBaHNNQUNFSkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUlxcbndlVnRES0ZaNVI0THRDc1l2N1lxWndEOERMUnVuZUIwSEV6QkN5ckU0WUwrVUhhb2ZvSFFYMStuUmgwalxcbjgycWFEekFBL2kzVTFTb0VJaTMyWU1yb3JORzUwdmI0dmFFUGJiWW1mZ2xiK0pRMVl4N296ak1FWkJzcVxcbjlSWUpLd1lCQkFIYVJ3OEJBUWRBUzE1MzRMZENDNjBBU3BFZ25FQkM4cFdQU09XV0JMWHlXYUJoRU9XMlxcbi9pakNlQVFZRXdnQUNRVUNaQnNxOVFJYklBQWhDUkRsSGd1MEt4aS90aFloQkl6ZXJ6MUJVY0hsYlF5aFxcbldlVWVDN1FyR0wrMkZVWUEvQWdNVTRWN0M3SS81SHdLNzNtY3RhR1hOZGZWci9tdVJNTk9HVy9DQXhWTFxcbkFQOUthQnI5NW8zMm9FTjVlbzd0V0ZCeW9PQ0NrOUpNanMzNkNxN28rc1IzMUE9PVxcbj1lWjNCXFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgMjoge1xuICAgICAgICAgICAgZ3BnUHViS2V5OlxuICAgICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuXFxueGs4RVpCc3JOQk1GSzRFRUFBb0NBd1QyeFh2L21HL2RhUGRLR0QvZkhJVUVFMlp0Y0srbmp0Q1p0TUVyXFxua0l1Ym1Vd2UzRGo4K2hReHQzU0thVHhRYnVEK1dhTFNqOTg2UVlVcjRadzRUK1czeldwdmRtTXRNaTFpXFxuWVdOcmRYQXROVFEzWW1Ka1pqTXdPR014WlRZeFkyUTVaR0k0Tm1VNElEeHZkbU10TWkxaVlXTnJkWEF0XFxuTlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRRRFUwTjJKaVpHWXpNRGhqTVdVMk1XTmtPV1JpXFxuT0RabE9DNWpiMjArd293RUVCTUlBQjBGQW1RYkt6UUVDd2tIQ0FNVkNBb0VGZ0FDQVFJWkFRSWJBd0llXFxuQVFBaENSQzJBazVHMlNrN1pSWWhCTFRwU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRseHRZQkFMTElCbkFhXFxuNEFTNzdYdlhtbXpuTkNXTy9ITnVEUEQydWdScVZocVU0U3htQVFEbWExNEFQdU1OU1Z5aTE3eG9tWmpXXFxuMG5pbXRhTUlCamMwQTRNWEU2RzRYYzVUQkdRYkt6UVNCU3VCQkFBS0FnTUVVSG9RRFk5OHk4Q0FWb3V1XFxueTR5M1EyUW5CcG5VQksvMFBFTFY3VkFOWGQ5bFk3Q1NoeW9nSlNjZ1BsaVVtOTdBdTlGQzE3dnFaYTFCXFxuNWJCTUpBZFhWd01CQ0FmQ2VBUVlFd2dBQ1FVQ1pCc3JOQUliREFBaENSQzJBazVHMlNrN1pSWWhCTFRwXFxuU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRsUjV3QS8zek9GVFNlWFhSUmVtWGwzaFkxMHNweGFiRTRPMko4XFxuWkQyVlJmamJEcFpqQVFEV2cxVytqUGJNMkh0aWtkMU4wMVYrendlTkRoSkVINjVyMFFyOEJsWGgydz09XFxuPUV0dHVcXG4tLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuJyxcbiAgICAgICAgICAgIG92Y1RvQml0Z29TaGFyZToge1xuICAgICAgICAgICAgICBwdWJsaWNTaGFyZTpcbiAgICAgICAgICAgICAgICAnZWNmOTVlOWJhNmYwMmMwYmM0YzJhYjI1NDU2NWQyMWExNTYyMDU5YzhhMWFiNzBkMjg2ZmEwNGFlMmM1MTFlMDQ5MTQxMGI2ZDZmYThhYjIyZTY5MWJlZDc5MzhhN2FkYWFiZmE4ZDlkNTlhYWI5Y2MyYzA3OGNkMzdkZGUwMWInLFxuICAgICAgICAgICAgICBwcml2YXRlU2hhcmU6XG4gICAgICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcblxcbndYNERVUThYaEdWR2NUSVNBZ01FZTFuWU52OURuSGw4SFg4ak5zM3JlR3M1blBUMmJOekdNQ0ZMME4zUFxcbktMd0dkOERCa0RKSU1wb0NsYUFTL0hUVVRQVFJ6ajRVMUdTaFY3OUkrYmJmVERCVjZ1aHlmWjdhODhkVlxcblJEVFhsNnJjaEZsL2Ztd0xvWG5xSCtCRFBFWHl0cEF2S3dEckFnNTVUL0g3YW9wNVFiZlNzUUVyRXY3WFxcblRwVExISEhmbEVFUUw2MnAxUm5ucTJrS3Z3Sks3VFkxZzVSdFBnWVhINkdFczMzREx1bFBlVXM4VWtLcVxcblRQTGYyKzFLQ0xZeXpNd21TaThLRUM4SEpiMHZBa1haQWxaMStEb1oyUGZpSUpjVm56N2Ezb21qaVA3N1xcbmhtQzhwaFRjSjcxOFV4SUIwOWY4dWljMC9mTTdGTnUwSkhGZ1JEQTY5enplRlluWmMyWE5RZzVocy9kWlxcblo4QWl0UDRybmFBZnByc3E0ckFFRS9jM1RybTl0elFIWlBDcXIvMnM0TGx1eVVNVkp3PT1cXG49SUpaSFxcbi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS1cXG4nLFxuICAgICAgICAgICAgICB2c3NQcm9vZjogJzMwOWQyZmVmMjI3MmFkMzEzNzU5NTRiOTlhODYyNzQyZjIyZDgwMjNlZWY5ODU1YjhhZTI2ZWE4NGUwOGJmNWUnLFxuICAgICAgICAgICAgICBpOiAzLFxuICAgICAgICAgICAgICBqOiAyLFxuICAgICAgICAgICAgICB1U2lnOiAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuXFxueGs4RVpCc3JOQk1GSzRFRUFBb0NBd1QyeFh2L21HL2RhUGRLR0QvZkhJVUVFMlp0Y0srbmp0Q1p0TUVyXFxua0l1Ym1Vd2UzRGo4K2hReHQzU0thVHhRYnVEK1dhTFNqOTg2UVlVcjRadzRUK1czeldwdmRtTXRNaTFpXFxuWVdOcmRYQXROVFEzWW1Ka1pqTXdPR014WlRZeFkyUTVaR0k0Tm1VNElEeHZkbU10TWkxaVlXTnJkWEF0XFxuTlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRRRFUwTjJKaVpHWXpNRGhqTVdVMk1XTmtPV1JpXFxuT0RabE9DNWpiMjArd293RUVCTUlBQjBGQW1RYkt6UUVDd2tIQ0FNVkNBb0VGZ0FDQVFJWkFRSWJBd0llXFxuQVFBaENSQzJBazVHMlNrN1pSWWhCTFRwU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRseHRZQkFMTElCbkFhXFxuNEFTNzdYdlhtbXpuTkNXTy9ITnVEUEQydWdScVZocVU0U3htQVFEbWExNEFQdU1OU1Z5aTE3eG9tWmpXXFxuMG5pbXRhTUlCamMwQTRNWEU2RzRYYzVUQkdRYkt6UVNCU3VCQkFBS0FnTUVVSG9RRFk5OHk4Q0FWb3V1XFxueTR5M1EyUW5CcG5VQksvMFBFTFY3VkFOWGQ5bFk3Q1NoeW9nSlNjZ1BsaVVtOTdBdTlGQzE3dnFaYTFCXFxuNWJCTUpBZFhWd01CQ0FmQ2VBUVlFd2dBQ1FVQ1pCc3JOQUliREFBaENSQzJBazVHMlNrN1pSWWhCTFRwXFxuU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRsUjV3QS8zek9GVFNlWFhSUmVtWGwzaFkxMHNweGFiRTRPMko4XFxuWkQyVlJmamJEcFpqQVFEV2cxVytqUGJNMkh0aWtkMU4wMVYrendlTkRoSkVINjVyMFFyOEJsWGgyODR6XFxuQkdRYkt6UVdDU3NHQVFRQjJrY1BBUUVIUUlWVG1sdDhhL2ZqSkNZOVV5UDhKNTFlVFBYOVBNUkYzL0hyXFxuQll3dGZPWll3bmdFR0JNSUFBa0ZBbVFiS3pRQ0d5QUFJUWtRdGdKT1J0a3BPMlVXSVFTMDZVcEJUbnQyXFxubzI2cUxucTJBazVHMlNrN1pjdGhBUUQ0ZWszYXFVREViaGZSSG9sbTRqRmhJUEliYjloVUp3dUJSMFI0XFxuK2d2YWVBRUFrOHVrNWNFQUNlcW1wZEVGNTJvR3g3am1HQ29YNzNBSUlMWVZjZjlpTWtJPVxcbj05MkhmXFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3ZjVG9PdmNTaGFyZToge1xuICAgICAgICAgICAgICBwdWJsaWNTaGFyZTpcbiAgICAgICAgICAgICAgICAnZWNmOTVlOWJhNmYwMmMwYmM0YzJhYjI1NDU2NWQyMWExNTYyMDU5YzhhMWFiNzBkMjg2ZmEwNGFlMmM1MTFlMDQ5MTQxMGI2ZDZmYThhYjIyZTY5MWJlZDc5MzhhN2FkYWFiZmE4ZDlkNTlhYWI5Y2MyYzA3OGNkMzdkZGUwMWInLFxuICAgICAgICAgICAgICBwcml2YXRlU2hhcmU6XG4gICAgICAgICAgICAgICAgJy0tLS0tQkVHSU4gUEdQIE1FU1NBR0UtLS0tLVxcblxcbndYNEQrRjN2STk2MnpWTVNBZ01FTnkyWDl4RElPbTFnd09mTWRMLzF2WmplTVcvaWxlL2YyZFJJUDJHVlxcbnY0dzYwSzkyK21ISTl5b29VMVZUNzdqWnJWT2NOSzQxREZOQ0YvZnVvVVUrVnpCT04wSTFoSHlYbTJRSlxcbndMK25OZHZBWHdSdjduU0ZEM0FCVW1SWWRHNzFBRklXalcyTCsxQzJoeHBzTmxtZHhmZlNzUUhIVDl1UFxcbkJOcEZZZ1FONzdPVXhjZ3J3ZVNWclB5ZXIxckNROG8rUW5vSzIvaEl4OVBsSlprY2wzdXdGNlRwQnRqc1xcbnF2UnhUaG9tb0h5bzBoSkhHMHZtSTQyR3E1dTB0Y1NlVTkwMmVmcENEYWVKaFBWT2lxSVNvSjk2d24wclxcbkZCM2xZTFNmbE9wQ0xBRTduc1pKUm9YQTZha1U3eE1DTU5BKytkNHR2NnA5OEZRK01aNmU5eDZraVN3MVxcbk0rVldqK1B2TjFkdFE4Zk5Zd3BKZjdLQmZEMXc2SVNNRkRtZXdrREU3aUJPWEY2Rkx3PT1cXG49KzNZY1xcbi0tLS0tRU5EIFBHUCBNRVNTQUdFLS0tLS1cXG4nLFxuICAgICAgICAgICAgICB2c3NQcm9vZjogJzMwOWQyZmVmMjI3MmFkMzEzNzU5NTRiOTlhODYyNzQyZjIyZDgwMjNlZWY5ODU1YjhhZTI2ZWE4NGUwOGJmNWUnLFxuICAgICAgICAgICAgICBpOiAxLFxuICAgICAgICAgICAgICBqOiAyLFxuICAgICAgICAgICAgICB1U2lnOiAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuXFxueGs4RVpCc3JOQk1GSzRFRUFBb0NBd1QyeFh2L21HL2RhUGRLR0QvZkhJVUVFMlp0Y0srbmp0Q1p0TUVyXFxua0l1Ym1Vd2UzRGo4K2hReHQzU0thVHhRYnVEK1dhTFNqOTg2UVlVcjRadzRUK1czeldwdmRtTXRNaTFpXFxuWVdOcmRYQXROVFEzWW1Ka1pqTXdPR014WlRZeFkyUTVaR0k0Tm1VNElEeHZkbU10TWkxaVlXTnJkWEF0XFxuTlRRM1ltSmtaak13T0dNeFpUWXhZMlE1WkdJNE5tVTRRRFUwTjJKaVpHWXpNRGhqTVdVMk1XTmtPV1JpXFxuT0RabE9DNWpiMjArd293RUVCTUlBQjBGQW1RYkt6UUVDd2tIQ0FNVkNBb0VGZ0FDQVFJWkFRSWJBd0llXFxuQVFBaENSQzJBazVHMlNrN1pSWWhCTFRwU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRseHRZQkFMTElCbkFhXFxuNEFTNzdYdlhtbXpuTkNXTy9ITnVEUEQydWdScVZocVU0U3htQVFEbWExNEFQdU1OU1Z5aTE3eG9tWmpXXFxuMG5pbXRhTUlCamMwQTRNWEU2RzRYYzVUQkdRYkt6UVNCU3VCQkFBS0FnTUVVSG9RRFk5OHk4Q0FWb3V1XFxueTR5M1EyUW5CcG5VQksvMFBFTFY3VkFOWGQ5bFk3Q1NoeW9nSlNjZ1BsaVVtOTdBdTlGQzE3dnFaYTFCXFxuNWJCTUpBZFhWd01CQ0FmQ2VBUVlFd2dBQ1FVQ1pCc3JOQUliREFBaENSQzJBazVHMlNrN1pSWWhCTFRwXFxuU2tGT2UzYWpicW91ZXJZQ1RrYlpLVHRsUjV3QS8zek9GVFNlWFhSUmVtWGwzaFkxMHNweGFiRTRPMko4XFxuWkQyVlJmamJEcFpqQVFEV2cxVytqUGJNMkh0aWtkMU4wMVYrendlTkRoSkVINjVyMFFyOEJsWGgyODR6XFxuQkdRYkt6UVdDU3NHQVFRQjJrY1BBUUVIUU5WR2cwdlBzZksxeUpqRnVEWUI4VGo3Q1FSSEtHQVZFRGNqXFxuaC9RSXFyMEt3bmdFR0JNSUFBa0ZBbVFiS3pRQ0d5QUFJUWtRdGdKT1J0a3BPMlVXSVFTMDZVcEJUbnQyXFxubzI2cUxucTJBazVHMlNrN1pTOW9BUUNlMnpKRDVJdFcyR0VnQWl0blkrTnJMQmpiWEk2K0xZMjlHalJhXFxuZjZ5RlRRRC9jUDBFMURsZXFYTWpnZlIrZXd0NnF1VkZNWmViaHIzdEJyL0gwWnYvOUVBPVxcbj04YWkrXFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCBiaXRnb1xuICAgICAgICAuY29pbigndHNvbCcpXG4gICAgICAgIC5rZXljaGFpbnMoKVxuICAgICAgICAuY3JlYXRlVHNzQml0R29LZXlGcm9tT3ZjU2hhcmVzKG92Y091dHB1dEpzb24pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdTdGF0ZSBleHBlY3RlZCB0byBiZSBcIjFcIi4gUGxlYXNlIGNvbXBsZXRlIHRoZSBmaXJzdCB0d28gT1ZDIG9wZXJhdGlvbnMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdGYWlscyB0byBkZWNvZGUgaWYgdGhlIE9WQyBqc29uIGlzIG1pc3NpbmcgZmllbGRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgb3ZjT3V0cHV0SnNvbiA9IHtcbiAgICAgICAgdHNzVmVyc2lvbjogJzAuMC4xJyxcbiAgICAgICAgc3RhdGU6IDEsXG4gICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgb3ZjOiB7XG4gICAgICAgICAgMToge1xuICAgICAgICAgICAgZ3BnUHViS2V5OlxuICAgICAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tXFxuXFxueGs4RVpCc3E5Uk1GSzRFRUFBb0NBd1JnRHBnbTFicHRSVDV5TE9NYWRjR0FIdXZreElTTDgvM3hQeS9EXFxuWUErMU5nQnFJRksvM09PWHhwNzNUdjg2YnQxZGdIN09EMUFDTzBtVlhBb1g1RWFWeldadmRtTXRNUzExXFxuYzJWeUxXUm1NalF3T1dZME5XTmhNVFptTlRVM09HTmtNekF4TXlBOGIzWmpMVEV0ZFhObGNpMWtaakkwXFxuTURsbU5EVmpZVEUyWmpVMU56aGpaRE13TVROQVpHWXlOREE1WmpRMVkyRXhObVkxTlRjNFkyUXpNREV6XFxuTG1OdmJUN0NqQVFRRXdnQUhRVUNaQnNxOVFRTENRY0lBeFVJQ2dRV0FBSUJBaGtCQWhzREFoNEJBQ0VKXFxuRU9VZUM3UXJHTCsyRmlFRWpONnZQVUZSd2VWdERLRlo1UjRMdENzWXY3WjdvQUVBdk5LYUpyVElzM2t5XFxuYnhqa1VpY3N1eE95QTJvV0dhckpINlRHbFdGNldEOEEvM0VJZVp6UEtTTGFXKzNlbnBiQ1BpVThSVkRwXFxuQzZ5bzZOTUFxS3A0WGx5UXpsTUVaQnNxOVJJRks0RUVBQW9DQXdRV2xXUE5NcGszYWZFemZnRzB4Rmc0XFxuQ0VqWTdmR08zNW40N25aNHF4akVYejJYTjRJMjN4Rk1pd1piWGJwdERYbHFtN1c5WkFIS2k4OTJoK1l0XFxuVTRCNkF3RUlCOEo0QkJnVENBQUpCUUprR3lyMUFoc01BQ0VKRU9VZUM3UXJHTCsyRmlFRWpONnZQVUZSXFxud2VWdERLRlo1UjRMdENzWXY3WXFad0Q4RExSdW5lQjBIRXpCQ3lyRTRZTCtVSGFvZm9IUVgxK25SaDBqXFxuODJxYUR6QUEvaTNVMVNvRUlpMzJZTXJvck5HNTB2YjR2YUVQYmJZbWZnbGIrSlExWXg3b1xcbj12amdsXFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgICBvdmNUb0JpdGdvU2hhcmU6IHtcbiAgICAgICAgICAgICAgcHVibGljU2hhcmU6XG4gICAgICAgICAgICAgICAgJzA3YmZiYjA1MmExZjRiMTA2YjMxNWJkNWE5ZDZhNzE2MDQ2NTMyODlmODYxMzIwZDk4MDE4ODFlOTUyZjg1NTA3NTNjODk1MTFhMzYwZTNiNTk5ZDlmMjM5YThkMzZhNDk1NjQzN2VkMGIxNTIxODBlMjJjYjk0ZmIwOGZkYzgxJyxcbiAgICAgICAgICAgICAgcHJpdmF0ZVNoYXJlOlxuICAgICAgICAgICAgICAgICctLS0tLUJFR0lOIFBHUCBNRVNTQUdFLS0tLS1cXG5cXG53WDREVVE4WGhHVkdjVElTQWdNRWQvd1EvQWh3SVJzU2YvNmlId21IS3ZFWUF3ZmFMdFRRb3RTNkJ3Wm1cXG5hWDAwVDdMdW1HSXJOWnpCZ2NnZ0JLTWwrOE9tb204bVg1c1A4RlVFNDUxaVpqQm1YbGtwSGxwQXFza1NcXG5FaTVTZmpsc1QzMXV0b0xhQkxBN05qTlNteVlISWl5Zmg2WW53ZlY1VTcyazZoaGZwdURTc1FHeThZeHBcXG5NMmRWbE40dW9PMzF6Z1FQZitmZ0prWnZBUHd2allMQkw0TzhoczIxSEdmMFZ2Rzk5YnJrNHhsRlZSaHdcXG5RbnVQcE01MUdPczR2VXRiTE5TWW5BdWhVNFJlWHd3RFY5WHUwTVhBamZRTWsyRTN3UUxHUSs4MnV2MkJcXG4xaFBEOW5ESFR0QWRXclhkNlpqWEZyRzRNZjJNUUJ4eVNGdlZTbkZpNnlTdGpmWmVpS2NENVZnMzhQakdcXG5XZzFPNU4zL3BhcTk4SGZIMFE0cU5LR1psandvM29FUVp6bFltMmtWbkkwUFVMb01ZZz09XFxuPW92QXhcXG4tLS0tLUVORCBQR1AgTUVTU0FHRS0tLS0tXFxuJyxcbiAgICAgICAgICAgICAgdnNzUHJvb2Y6ICdiZTgxOThjMmNlZjk0Y2IzODFhYThhYTkyNzdhMGE0NmJhNWE1NGIwYWM5OTMwMDM0YjRhZjY2YjFiODA1MjM0JyxcbiAgICAgICAgICAgICAgaTogMyxcbiAgICAgICAgICAgICAgajogMSxcbiAgICAgICAgICAgICAgdVNpZzogJy0tLS0tQkVHSU4gUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcblxcbnhrOEVaQnNxOVJNRks0RUVBQW9DQXdSZ0RwZ20xYnB0UlQ1eUxPTWFkY0dBSHV2a3hJU0w4LzN4UHkvRFxcbllBKzFOZ0JxSUZLLzNPT1h4cDczVHY4NmJ0MWRnSDdPRDFBQ08wbVZYQW9YNUVhVnpXWnZkbU10TVMxMVxcbmMyVnlMV1JtTWpRd09XWTBOV05oTVRabU5UVTNPR05rTXpBeE15QThiM1pqTFRFdGRYTmxjaTFrWmpJMFxcbk1EbG1ORFZqWVRFMlpqVTFOemhqWkRNd01UTkFaR1l5TkRBNVpqUTFZMkV4Tm1ZMU5UYzRZMlF6TURFelxcbkxtTnZiVDdDakFRUUV3Z0FIUVVDWkJzcTlRUUxDUWNJQXhVSUNnUVdBQUlCQWhrQkFoc0RBaDRCQUNFSlxcbkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUndlVnRES0ZaNVI0THRDc1l2N1o3b0FFQXZOS2FKclRJczNreVxcbmJ4amtVaWNzdXhPeUEyb1dHYXJKSDZUR2xXRjZXRDhBLzNFSWVaelBLU0xhVyszZW5wYkNQaVU4UlZEcFxcbkM2eW82Tk1BcUtwNFhseVF6bE1FWkJzcTlSSUZLNEVFQUFvQ0F3UVdsV1BOTXBrM2FmRXpmZ0cweEZnNFxcbkNFalk3ZkdPMzVuNDduWjRxeGpFWHoyWE40STIzeEZNaXdaYlhicHREWGxxbTdXOVpBSEtpODkyaCtZdFxcblU0QjZBd0VJQjhKNEJCZ1RDQUFKQlFKa0d5cjFBaHNNQUNFSkVPVWVDN1FyR0wrMkZpRUVqTjZ2UFVGUlxcbndlVnRES0ZaNVI0THRDc1l2N1lxWndEOERMUnVuZUIwSEV6QkN5ckU0WUwrVUhhb2ZvSFFYMStuUmgwalxcbjgycWFEekFBL2kzVTFTb0VJaTMyWU1yb3JORzUwdmI0dmFFUGJiWW1mZ2xiK0pRMVl4N296ak1FWkJzcVxcbjlSWUpLd1lCQkFIYVJ3OEJBUWRBUzE1MzRMZENDNjBBU3BFZ25FQkM4cFdQU09XV0JMWHlXYUJoRU9XMlxcbi9pakNlQVFZRXdnQUNRVUNaQnNxOVFJYklBQWhDUkRsSGd1MEt4aS90aFloQkl6ZXJ6MUJVY0hsYlF5aFxcbldlVWVDN1FyR0wrMkZVWUEvQWdNVTRWN0M3SS81SHdLNzNtY3RhR1hOZGZWci9tdVJNTk9HVy9DQXhWTFxcbkFQOUthQnI5NW8zMm9FTjVlbzd0V0ZCeW9PQ0NrOUpNanMzNkNxN28rc1IzMUE9PVxcbj1lWjNCXFxuLS0tLS1FTkQgUEdQIFBVQkxJQyBLRVkgQkxPQ0stLS0tLVxcbicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgYXdhaXQgYml0Z28uY29pbigndHNvbCcpLmtleWNoYWlucygpLmNyZWF0ZVRzc0JpdEdvS2V5RnJvbU92Y1NoYXJlcyhvdmNPdXRwdXRKc29uKS5zaG91bGQuYmUucmVqZWN0ZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KCdPdmNTaGFyZSBjb2RlYyBkZWNvZGVzIGNvcnJlY3RseScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRlc3QgPSB7XG4gICAgICAgIHB1YmxpY1NoYXJlOlxuICAgICAgICAgICcwN2JmYmIwNTJhMWY0YjEwNmIzMTViZDVhOWQ2YTcxNjA0NjUzMjg5Zjg2MTMyMGQ5ODAxODgxZTk1MmY4NTUwNzUzYzg5NTExYTM2MGUzYjU5OWQ5ZjIzOWE4ZDM2YTQ5NTY0MzdlZDBiMTUyMTgwZTIyY2I5NGZiMDhmZGM4MScsXG4gICAgICAgIHByaXZhdGVTaGFyZTpcbiAgICAgICAgICAnLS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tXFxuXFxud1g0RFVROFhoR1ZHY1RJU0FnTUVkL3dRL0Fod0lSc1NmLzZpSHdtSEt2RVlBd2ZhTHRUUW90UzZCd1ptXFxuYVgwMFQ3THVtR0lyTlp6QmdjZ2dCS01sKzhPbW9tOG1YNXNQOEZVRTQ1MWlaakJtWGxrcEhscEFxc2tTXFxuRWk1U2ZqbHNUMzF1dG9MYUJMQTdOak5TbXlZSElpeWZoNllud2ZWNVU3Mms2aGhmcHVEU3NRR3k4WXhwXFxuTTJkVmxONHVvTzMxemdRUGYrZmdKa1p2QVB3dmpZTEJMNE84aHMyMUhHZjBWdkc5OWJyazR4bEZWUmh3XFxuUW51UHBNNTFHT3M0dlV0YkxOU1luQXVoVTRSZVh3d0RWOVh1ME1YQWpmUU1rMkUzd1FMR1ErODJ1djJCXFxuMWhQRDluREhUdEFkV3JYZDZaalhGckc0TWYyTVFCeHlTRnZWU25GaTZ5U3RqZlplaUtjRDVWZzM4UGpHXFxuV2cxTzVOMy9wYXE5OEhmSDBRNHFOS0dabGp3bzNvRVFaemxZbTJrVm5JMFBVTG9NWWc9PVxcbj1vdkF4XFxuLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLVxcbicsXG4gICAgICAgIHZzc1Byb29mOiAnYmU4MTk4YzJjZWY5NGNiMzgxYWE4YWE5Mjc3YTBhNDZiYTVhNTRiMGFjOTkzMDAzNGI0YWY2NmIxYjgwNTIzNCcsXG4gICAgICAgIGk6IDMsXG4gICAgICAgIGo6IDEsXG4gICAgICB9O1xuICAgICAgY29uc3QgZGVjb2RlZFJlcyA9IGRlY29kZU9yRWxzZShPdmNTaGFyZS5uYW1lLCBPdmNTaGFyZSwgdGVzdCwgKGVycm9ycykgPT4ge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGVycm9yKHMpIHBhcnNpbmcgcGFyc2luZyBqc29uOiAke2Vycm9yc31gKTtcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0Lm9rKGRlY29kZWRSZXMpO1xuICAgIH0pO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGdlbmVyYXRlIGJhY2t1cCB3aXRob3V0IGVuY3J5cHRlZFBydiB3aGVuIHBhc3NwaHJhc2Ugbm90IHByb3ZpZGVkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHNjb3BlID0gbm9jayhiZ1VybClcbiAgICAgIC5wb3N0KCcvYXBpL3YyL3RsdGMva2V5JywgKGJvZHkpID0+IHtcbiAgICAgICAgcmV0dXJuIGJvZHkuZW5jcnlwdGVkUHJ2ID09PSB1bmRlZmluZWQgJiYgYm9keS5wcnYgPT09IHVuZGVmaW5lZDtcbiAgICAgIH0pXG4gICAgICAucmVwbHkoMjAwKTtcblxuICAgIGNvbnN0IGJhY2t1cCA9IGF3YWl0IGtleWNoYWlucy5jcmVhdGVCYWNrdXAoe30pO1xuICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgYmFja3VwLnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnZW5jcnlwdGVkUHJ2Jyk7XG4gICAgYmFja3VwLnNob3VsZC5oYXZlLnByb3BlcnR5KCdwcnYnKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBiYWNrdXAgYW5kIGNhbGwgZW5kcG9pbnQgd2l0aCBlbmNyeXB0ZWRQcnYgd2hlbiBwYXNzcGhyYXNlIGlzIHByb3ZpZGVkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHNjb3BlID0gbm9jayhiZ1VybClcbiAgICAgIC5wb3N0KCcvYXBpL3YyL3RsdGMva2V5JywgKGJvZHkpID0+IHtcbiAgICAgICAgcmV0dXJuIGJvZHkuZW5jcnlwdGVkUHJ2ICE9PSB1bmRlZmluZWQgJiYgYm9keS5wcnYgPT09IHVuZGVmaW5lZDtcbiAgICAgIH0pXG4gICAgICAucmVwbHkoMjAwKTtcblxuICAgIGNvbnN0IGJhY2t1cCA9IGF3YWl0IGtleWNoYWlucy5jcmVhdGVCYWNrdXAoeyBwYXNzcGhyYXNlOiAndDNzdFNpY3JldGx5IScgfSk7XG4gICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICBiYWNrdXAuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2VuY3J5cHRlZFBydicpO1xuICAgIGNvbnN0IGRlY3J5cHRlZFBydiA9IGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogYmFja3VwLmVuY3J5cHRlZFBydiwgcGFzc3dvcmQ6ICd0M3N0U2ljcmV0bHkhJyB9KTtcbiAgICBkZWNyeXB0ZWRQcnYuc2hvdWxkLnN0YXJ0V2l0aCgneHBydicpO1xuICB9KTtcblxuICBkZXNjcmliZSgnUm90YXRlIE9GQyBtdWx0aS11c2VyLWtleSBrZXljaGFpbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IG9mY0Jhc2VDb2luO1xuICAgIGxldCBvZmNLZXljaGFpbnM7XG4gICAgY29uc3QgbW9ja09mY0tleWNoYWluOiBLZXljaGFpbiA9IHtcbiAgICAgIGlkOiAnb2ZjS2V5Y2hhaW5JZCcsXG4gICAgICBwdWI6ICdvZmNLZXljaGFpblB1YicsXG4gICAgICBlbmNyeXB0ZWRQcnY6ICdvZmNFbmNyeXB0ZWRQcnYnLFxuICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgb2ZjOiB7XG4gICAgICAgICAgZmVhdHVyZXM6IFsnbXVsdGktdXNlci1rZXknXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB0eXBlOiAndHNzJyxcbiAgICB9O1xuICAgIGxldCBub25PZmNCYXNlQ29pbjtcbiAgICBsZXQgbm9uT2ZjS2V5Y2hhaW5zO1xuICAgIGNvbnN0IG1vY2tOb25PZmNLZXljaGFpbjogS2V5Y2hhaW4gPSB7XG4gICAgICBpZDogJ25vbk9mY0tleWNoYWluSWQnLFxuICAgICAgcHViOiAnbm9uT2ZjS2V5Y2hhaW5QdWInLFxuICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICB0eXBlOiAndHNzJyxcbiAgICB9O1xuXG4gICAgY29uc3QgbW9ja05ld0tleXBhaXIgPSB7XG4gICAgICBwdWI6ICduZXdQdWInLFxuICAgICAgcHJ2OiAnbmV3UHJ2JyxcbiAgICB9O1xuXG4gICAgbGV0IHNhbmRib3g7XG4gICAgbGV0IHVwZGF0ZUtleWNoYWluU3R1YjogU2lub25TdHViO1xuICAgIGxldCBjcmVhdGVLZXlwYWlyU3R1YjogU2lub25TdHViO1xuICAgIGxldCBlbmNyeXB0aW9uU3R1YjogU2lub25TdHViO1xuXG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBvZmNCYXNlQ29pbiA9IGJpdGdvLmNvaW4oJ29mYycpO1xuICAgICAgb2ZjS2V5Y2hhaW5zID0gb2ZjQmFzZUNvaW4ua2V5Y2hhaW5zKCk7XG5cbiAgICAgIG5vbk9mY0Jhc2VDb2luID0gYml0Z28uY29pbignaHRldGgnKTtcbiAgICAgIG5vbk9mY0tleWNoYWlucyA9IG5vbk9mY0Jhc2VDb2luLmtleWNoYWlucygpO1xuXG4gICAgICBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgdXBkYXRlS2V5Y2hhaW5TdHViID0gc2FuZGJveC5zdHViKCkucmV0dXJucyh7IHJlc3VsdDogc2FuZGJveC5zdHViKCkucmVzb2x2ZXMoKSB9KTtcbiAgICAgIHNhbmRib3guc3R1YihCaXRHby5wcm90b3R5cGUsICdwdXQnKS5yZXR1cm5zKHsgc2VuZDogdXBkYXRlS2V5Y2hhaW5TdHViIH0pO1xuICAgICAgY3JlYXRlS2V5cGFpclN0dWIgPSBzYW5kYm94LnN0dWIob2ZjS2V5Y2hhaW5zLCAnY3JlYXRlJykucmV0dXJucyhtb2NrTmV3S2V5cGFpcik7XG4gICAgICBlbmNyeXB0aW9uU3R1YiA9IHNhbmRib3guc3R1YihCaXRHby5wcm90b3R5cGUsICdlbmNyeXB0JykucmVzb2x2ZXMoJ25ld0VuY3J5cHRlZFBydicpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNhbmRib3gucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByb3RhdGUgb2ZjIG11bHRpLXVzZXIta2V5IHByb3Blcmx5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL29mYy9rZXkvJHttb2NrT2ZjS2V5Y2hhaW4uaWR9YCkucXVlcnkodHJ1ZSkucmVwbHkoMjAwLCBtb2NrT2ZjS2V5Y2hhaW4pO1xuXG4gICAgICBhd2FpdCBvZmNLZXljaGFpbnMucm90YXRlS2V5Y2hhaW4oeyBpZDogbW9ja09mY0tleWNoYWluLmlkLCBwYXNzd29yZDogJzEyMzQnIH0pO1xuICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZChjcmVhdGVLZXlwYWlyU3R1Yik7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkV2l0aChlbmNyeXB0aW9uU3R1YiwgeyBpbnB1dDogbW9ja05ld0tleXBhaXIucHJ2LCBwYXNzd29yZDogJzEyMzQnLCBlbmNyeXB0aW9uVmVyc2lvbjogMiB9KTtcbiAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRXaXRoKHVwZGF0ZUtleWNoYWluU3R1Yiwge1xuICAgICAgICBwdWI6IG1vY2tOZXdLZXlwYWlyLnB1YixcbiAgICAgICAgZW5jcnlwdGVkUHJ2OiAnbmV3RW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgcmVxSWQ6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhbGxvdyB1c2VyIHRvIHN1cHBseSBwdWIgYW5kIGVuY3J5cHRlZFBydiBkaXJlY3RseScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9vZmMva2V5LyR7bW9ja09mY0tleWNoYWluLmlkfWApLnF1ZXJ5KHRydWUpLnJlcGx5KDIwMCwgbW9ja09mY0tleWNoYWluKTtcblxuICAgICAgYXdhaXQgb2ZjS2V5Y2hhaW5zLnJvdGF0ZUtleWNoYWluKHsgaWQ6IG1vY2tPZmNLZXljaGFpbi5pZCwgcHViOiAncHViJywgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2JyB9KTtcbiAgICAgIHNpbm9uLmFzc2VydC5ub3RDYWxsZWQoY3JlYXRlS2V5cGFpclN0dWIpO1xuICAgICAgc2lub24uYXNzZXJ0Lm5vdENhbGxlZChlbmNyeXB0aW9uU3R1Yik7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkV2l0aCh1cGRhdGVLZXljaGFpblN0dWIsIHtcbiAgICAgICAgcHViOiAncHViJyxcbiAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgcmVxSWQ6IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyB3aGVuIHRyeWluZyB0byByb3RhdGUgbm9uLW9mYyBrZXljaGFpbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi9odGV0aC9rZXkvJHttb2NrTm9uT2ZjS2V5Y2hhaW4uaWR9YCkucXVlcnkodHJ1ZSkucmVwbHkoMjAwLCBtb2NrTm9uT2ZjS2V5Y2hhaW4pO1xuXG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgYXN5bmMgKCkgPT4gYXdhaXQgbm9uT2ZjS2V5Y2hhaW5zLnJvdGF0ZUtleWNoYWluKHsgaWQ6IG1vY2tOb25PZmNLZXljaGFpbi5pZCwgcGFzc3dvcmQ6ICcxMjM0JyB9KSxcbiAgICAgICAgKGVycjogRXJyb3IpID0+IGVyci5tZXNzYWdlID09PSAncm90YXRlS2V5Y2hhaW4gaXMgb25seSBwZXJtaXR0ZWQgZm9yIG9mYyBtdWx0aS11c2VyLWtleSB3YWxsZXQnXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0RW5jcnlwdGlvblZlcnNpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3JldHVybnMgMSB3aGVuIHRoZSB2IGZpZWxkIGlzIGFic2VudCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVudmVsb3BlID0gSlNPTi5zdHJpbmdpZnkoeyBjdDogJ2NpcGhlcicsIGl2OiAnaXYnLCBzOiAnc2FsdCcgfSk7XG4gICAgICBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oZW52ZWxvcGUpLnNob3VsZC5lcXVhbCgxKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZXR1cm5zIDEgd2hlbiB2IGlzIGV4cGxpY2l0bHkgMScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGtleWNoYWlucy5nZXRFbmNyeXB0aW9uVmVyc2lvbihKU09OLnN0cmluZ2lmeSh7IHY6IDEsIGN0OiAnYWJjJyB9KSkuc2hvdWxkLmVxdWFsKDEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3JldHVybnMgMiB3aGVuIHYgaXMgMicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGtleWNoYWlucy5nZXRFbmNyeXB0aW9uVmVyc2lvbihKU09OLnN0cmluZ2lmeSh7IHY6IDIsIGN0OiAnYWJjJyB9KSkuc2hvdWxkLmVxdWFsKDIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyBvbiBhbiB1bnJlY29nbml6ZWQgdmVyc2lvbiBudW1iZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oSlNPTi5zdHJpbmdpZnkoeyB2OiAzLCBjdDogJ2FiYycgfSkpLFxuICAgICAgICAvVW5yZWNvZ25pemVkIGVuY3J5cHRpb24gdmVyc2lvbjogMy9cbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgndGhyb3dzIHdoZW4gdGhlIGlucHV0IGlzIG5vdCB2YWxpZCBKU09OJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oJ25vdC1qc29uJyksIC9GYWlsZWQgdG8gcGFyc2UgY2lwaGVydGV4dCBlbnZlbG9wZS8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Rocm93cyB3aGVuIHRoZSBpbnB1dCBpcyBhbiBlbXB0eSBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IGtleWNoYWlucy5nZXRFbmNyeXB0aW9uVmVyc2lvbignJyksIC9GYWlsZWQgdG8gcGFyc2UgY2lwaGVydGV4dCBlbnZlbG9wZS8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2hhbmRsZXMgYSByZWFsIFNKQ0wgdjEgZW52ZWxvcGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzamNsID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBpdjogJ2FhYWEnLFxuICAgICAgICB2OiAxLFxuICAgICAgICBpdGVyOiAxMDAwMCxcbiAgICAgICAga3M6IDI1NixcbiAgICAgICAgdHM6IDY0LFxuICAgICAgICBtb2RlOiAnY2NtJyxcbiAgICAgICAgYWRhdGE6ICcnLFxuICAgICAgICBjaXBoZXI6ICdhZXMnLFxuICAgICAgICBzYWx0OiAnc3NzcycsXG4gICAgICAgIGN0OiAnY2NjYycsXG4gICAgICB9KTtcbiAgICAgIGtleWNoYWlucy5nZXRFbmNyeXB0aW9uVmVyc2lvbihzamNsKS5zaG91bGQuZXF1YWwoMSk7XG4gICAgfSk7XG5cbiAgICBpdCgnaGFuZGxlcyBhIHJlYWwgQXJnb24yaWQgdjIgZW52ZWxvcGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhcmdvbjIgPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIHY6IDIsXG4gICAgICAgIGN0OiAnY2NjYycsXG4gICAgICAgIGl2OiAnaWlpaScsXG4gICAgICAgIHRhZzogJ3R0dHQnLFxuICAgICAgICBzYWx0OiAnc3NzcycsXG4gICAgICAgIG06IDY1NTM2LFxuICAgICAgICB0OiAzLFxuICAgICAgICBwOiA0LFxuICAgICAgfSk7XG4gICAgICBrZXljaGFpbnMuZ2V0RW5jcnlwdGlvblZlcnNpb24oYXJnb24yKS5zaG91bGQuZXF1YWwoMik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdyZWVuY3J5cHRBc1YyJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdkZWNyeXB0cyBhIHYxIGVudmVsb3BlIHdpdGggdGhlIHBhc3NwaHJhc2UgYW5kIHJlLWVuY3J5cHRzIGFzIHYyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHJ2ID0gJ3RoZVByaXZhdGVLZXknO1xuICAgICAgY29uc3QgZW5jcnlwdGVkVjEgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHBydiwgcGFzc3dvcmQ6ICdteVBhc3MnLCBlbmNyeXB0aW9uVmVyc2lvbjogMSB9KTtcbiAgICAgIEpTT04ucGFyc2UoZW5jcnlwdGVkVjEpLnYuc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBrZXljaGFpbnMucmVlbmNyeXB0QXNWMihlbmNyeXB0ZWRWMSwgJ215UGFzcycpO1xuICAgICAgSlNPTi5wYXJzZShyZXN1bHQpLnYuc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgKGF3YWl0IGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzdWx0LCBwYXNzd29yZDogJ215UGFzcycgfSkpLnNob3VsZC5lcXVhbChwcnYpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FjY2VwdHMgYSB2MiBlbnZlbG9wZSBhbmQgcmUtZW5jcnlwdHMgaXQgYXMgdjIgKGlkZW1wb3RlbnQpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHJ2ID0gJ3hwcnYtdjInO1xuICAgICAgY29uc3QgZW5jcnlwdGVkVjIgPSBhd2FpdCBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHBydiwgcGFzc3dvcmQ6ICdwYXNzJywgZW5jcnlwdGlvblZlcnNpb246IDIgfSk7XG4gICAgICBKU09OLnBhcnNlKGVuY3J5cHRlZFYyKS52LnNob3VsZC5lcXVhbCgyKTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQga2V5Y2hhaW5zLnJlZW5jcnlwdEFzVjIoZW5jcnlwdGVkVjIsICdwYXNzJyk7XG4gICAgICBKU09OLnBhcnNlKHJlc3VsdCkudi5zaG91bGQuZXF1YWwoMik7XG4gICAgICAoYXdhaXQgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXN1bHQsIHBhc3N3b3JkOiAncGFzcycgfSkpLnNob3VsZC5lcXVhbChwcnYpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3N1cmZhY2VzIGRlY3J5cHQgZXJyb3JzIGRpcmVjdGx5IChubyBmYWxsYmFjayBsb2dpYyBpbiB0aGUgcHJpbWl0aXZlKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVuY3J5cHRlZCA9IGF3YWl0IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3BydicsIHBhc3N3b3JkOiAncmVhbFBhc3MnLCBlbmNyeXB0aW9uVmVyc2lvbjogMSB9KTtcbiAgICAgIGF3YWl0IGtleWNoYWlucy5yZWVuY3J5cHRBc1YyKGVuY3J5cHRlZCwgJ3dyb25nUGFzcycpLnNob3VsZC5iZS5yZWplY3RlZCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19