UNPKG

bitgo

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