UNPKG

bitgo

Version:
212 lines • 40 kB
"use strict"; // // Account consolidation tests // Object.defineProperty(exports, "__esModule", { value: true }); const sinon = require("sinon"); require('should-sinon'); require("../lib/asserts"); const nock = require("nock"); const sdk_core_1 = require("@bitgo/sdk-core"); const sdk_test_1 = require("@bitgo/sdk-test"); const bitgo_1 = require("../../../src/bitgo"); const algoFixtures = require('../../../../sdk-coin-algo/test/fixtures/algo'); nock.disableNetConnect(); describe('Account Consolidations:', function () { let bitgo; let wallet; let basecoin; let bgUrl; let fixtures; for (const coinName of ['talgo', 'txtz']) { describe(coinName + ' Account Consolidations: ', function () { before(function () { bitgo = sdk_test_1.TestBitGo.decorate(bitgo_1.BitGo, { env: 'test' }); bitgo.initializeTestVars(); basecoin = bitgo.coin(coinName); const walletData = { id: '5e4168f4403d0c5c1c3bdd15486e757f', coin: coinName, }; wallet = new sdk_core_1.Wallet(bitgo, basecoin, walletData); bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri; if (coinName === 'talgo') { fixtures = algoFixtures.prebuild(); } }); describe('Building', function () { it('should not allow a non-account consolidation coin build', async function () { const unsupportedCoin = bitgo.coin('tbtc'); const invalidWallet = new sdk_core_1.Wallet(bitgo, unsupportedCoin, {}); await invalidWallet.buildAccountConsolidations().should.be.rejectedWith({ message: `${unsupportedCoin.getFullName()} does not allow account consolidations.`, }); }); it('should build with no params', async function () { const scope = nock(bgUrl) .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`) .query({}) .reply(200, fixtures.buildAccountConsolidation); const accountConsolidationBuild = await wallet.buildAccountConsolidations(); accountConsolidationBuild.length.should.equal(2); scope.isDone().should.be.True(); }); it('should throw if the result is an empty array', async function () { const scope = nock(bgUrl) .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`) .query({}) .reply(200, []); await wallet .buildAccountConsolidations() .should.be.rejectedWith('No receive addresses with balance found to consolidate.'); scope.isDone().should.be.True(); }); }); describe('Sending', function () { afterEach(function () { sinon.restore(); }); it('should use params.apiVersion if specified', async function () { const scope = nock(bgUrl) .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`, { apiVersion: 'lite' }) .reply(200, fixtures.buildAccountConsolidation); const sendAccountConsolidationStub = sinon .stub(wallet, 'sendAccountConsolidation') .resolves(fixtures.signedAccountConsolidationBuilds); sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').resolves([]); wallet.tssUtils = { supportedTxRequestVersions: () => ['lite', 'full'], }; const params = { apiVersion: 'lite' }; await wallet.sendAccountConsolidations(params); sinon.assert.calledWith(sendAccountConsolidationStub, sinon.match({ apiVersion: 'lite' })); scope.isDone().should.be.True(); }); it('should use apiVersion full for the transaction if it is supported and no apiVersion is passed', async function () { const scope = nock(bgUrl) .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`, { apiVersion: 'full' }) .reply(200, fixtures.buildAccountConsolidation); const sendAccountConsolidationStub = sinon .stub(wallet, 'sendAccountConsolidation') .resolves(fixtures.signedAccountConsolidationBuilds); sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').resolves([]); wallet.tssUtils = { supportedTxRequestVersions: () => ['lite', 'full'], }; const params = {}; await wallet.sendAccountConsolidations(params); sinon.assert.calledWith(sendAccountConsolidationStub, sinon.match({ apiVersion: 'full' })); scope.isDone().should.be.True(); }); it('should utilize codec for custodial consolidation', async function () { const custodialWallet = new sdk_core_1.Wallet(bitgo, basecoin, { id: '5f4168f4403d0c5c1c3bdd15486e757f', coin: coinName, type: 'custodial', }); const initiateTxPath = `/api/v2/${custodialWallet.coin()}/wallet/${custodialWallet.id()}/tx/initiate`; let req; nock(bgUrl) .post(initiateTxPath, (body) => { req = body; return true; }) .reply(200); const params = { prebuildTx: fixtures.buildAccountConsolidation[0] }; const paramsWithJunk = { ...params, junk: 'junk', otp: '000000' }; const paramsAfterCodec = { type: 'consolidate', otp: '000000' }; sinon.stub(wallet, 'prebuildAndSignTransaction').resolves(fixtures.signedAccountConsolidationBuilds[0]); await custodialWallet.sendAccountConsolidation(paramsWithJunk); req.should.deepEqual(paramsAfterCodec); }); it('should not allow a non-account consolidation coin send', async function () { const unsupportedCoin = bitgo.coin('tbtc'); const invalidWallet = new sdk_core_1.Wallet(bitgo, unsupportedCoin, {}); await invalidWallet.sendAccountConsolidation({}).should.be.rejectedWith({ message: `${unsupportedCoin.getFullName()} does not allow account consolidations.`, }); }); it('should not allow a non-account consolidation coin send multiples', async function () { const unsupportedCoin = bitgo.coin('tbtc'); const invalidWallet = new sdk_core_1.Wallet(bitgo, unsupportedCoin, {}); await invalidWallet.sendAccountConsolidations({}).should.be.rejectedWith({ message: `${unsupportedCoin.getFullName()} does not allow account consolidations.`, }); }); it('should not allow a bad pre-build to be passed', async function () { await wallet .sendAccountConsolidation({ prebuildTx: 'some string' }) .should.be.rejectedWith({ message: 'Invalid build of account consolidation.' }); await wallet .sendAccountConsolidation({ prebuildTx: undefined }) .should.be.rejectedWith({ message: 'Invalid build of account consolidation.' }); }); it('should require a consolidation id to be passed', async function () { await wallet .sendAccountConsolidation({ prebuildTx: {} }) .should.be.rejectedWith({ message: 'Failed to find consolidation id on consolidation transaction.' }); }); it('should submit a consolidation transaction', async function () { const params = { prebuildTx: fixtures.buildAccountConsolidation[0] }; sinon.stub(wallet, 'prebuildAndSignTransaction').resolves(fixtures.signedAccountConsolidationBuilds[0]); const scope = nock(bgUrl) .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, fixtures.signedAccountConsolidationBuild) .reply(200); await wallet.sendAccountConsolidation(params); scope.isDone().should.be.True(); }); it('should submit a consolidation account send (build + send) with two successes', async function () { const scopeBuild = nock(bgUrl) .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`) .query({}) .reply(200, fixtures.buildAccountConsolidation); sinon .stub(wallet, 'prebuildAndSignTransaction') .onCall(0) .resolves(fixtures.signedAccountConsolidationBuilds[0]) .onCall(1) .resolves(fixtures.signedAccountConsolidationBuilds[1]); sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').resolves([]); const scopeFirstSigned = nock(bgUrl) .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, fixtures.signedAccountConsolidationBuilds[0]) .reply(200); const scopeTwoSigned = nock(bgUrl) .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, fixtures.signedAccountConsolidationBuilds[1]) .reply(200); const consolidations = await wallet.sendAccountConsolidations(); consolidations.success.length.should.equal(2); consolidations.failure.length.should.equal(0); scopeFirstSigned.isDone().should.be.True(); scopeTwoSigned.isDone().should.be.True(); scopeBuild.isDone().should.be.True(); }); it('should submit a consolidation account send (build + send) with one success, one failure', async function () { const scopeBuild = nock(bgUrl) .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/consolidateAccount/build`) .query({}) .reply(200, fixtures.buildAccountConsolidation); sinon .stub(wallet, 'prebuildAndSignTransaction') .onCall(0) .resolves(fixtures.signedAccountConsolidationBuilds[0]) .onCall(1) .resolves(fixtures.signedAccountConsolidationBuilds[1]); sinon.stub(wallet, 'getKeychainsAndValidatePassphrase').resolves([]); const scopeWithSuccess = nock(bgUrl) .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, fixtures.signedAccountConsolidationBuilds[0]) .reply(200); const scopeWithError = nock(bgUrl) .post(`/api/v2/${wallet.coin()}/wallet/${wallet.id()}/tx/send`, fixtures.signedAccountConsolidationBuilds[1]) .reply(500); const consolidations = await wallet.sendAccountConsolidations(); consolidations.success.length.should.equal(1); consolidations.failure.length.should.equal(1); scopeWithSuccess.isDone().should.be.True(); scopeWithError.isDone().should.be.True(); scopeBuild.isDone().should.be.True(); }); }); }); } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3VudENvbnNvbGlkYXRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC92Mi91bml0L2FjY291bnRDb25zb2xpZGF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsRUFBRTtBQUNGLDhCQUE4QjtBQUM5QixFQUFFOztBQUVGLCtCQUErQjtBQUMvQixPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7QUFFeEIsMEJBQXdCO0FBQ3hCLDZCQUE4QjtBQUU5Qiw4Q0FBaUQ7QUFFakQsOENBQTRDO0FBQzVDLDhDQUEyQztBQUMzQyxNQUFNLFlBQVksR0FBRyxPQUFPLENBQUMsOENBQThDLENBQUMsQ0FBQztBQUU3RSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztBQUV6QixRQUFRLENBQUMseUJBQXlCLEVBQUU7SUFDbEMsSUFBSSxLQUFLLENBQUM7SUFDVixJQUFJLE1BQU0sQ0FBQztJQUNYLElBQUksUUFBUSxDQUFDO0lBQ2IsSUFBSSxLQUFLLENBQUM7SUFDVixJQUFJLFFBQVEsQ0FBQztJQUViLEtBQUssTUFBTSxRQUFRLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUN6QyxRQUFRLENBQUMsUUFBUSxHQUFHLDJCQUEyQixFQUFFO1lBQy9DLE1BQU0sQ0FBQztnQkFDTCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsYUFBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7Z0JBQ25ELEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO2dCQUMzQixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFFaEMsTUFBTSxVQUFVLEdBQUc7b0JBQ2pCLEVBQUUsRUFBRSxrQ0FBa0M7b0JBQ3RDLElBQUksRUFBRSxRQUFRO2lCQUNmLENBQUM7Z0JBRUYsTUFBTSxHQUFHLElBQUksaUJBQU0sQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUNqRCxLQUFLLEdBQUcsaUJBQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDO2dCQUNoRCxJQUFJLFFBQVEsS0FBSyxPQUFPLEVBQUUsQ0FBQztvQkFDekIsUUFBUSxHQUFHLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDckMsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1lBRUgsUUFBUSxDQUFDLFVBQVUsRUFBRTtnQkFDbkIsRUFBRSxDQUFDLHlEQUF5RCxFQUFFLEtBQUs7b0JBQ2pFLE1BQU0sZUFBZSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQzNDLE1BQU0sYUFBYSxHQUFHLElBQUksaUJBQU0sQ0FBQyxLQUFLLEVBQUUsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUM3RCxNQUFNLGFBQWEsQ0FBQywwQkFBMEIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDO3dCQUN0RSxPQUFPLEVBQUUsR0FBRyxlQUFlLENBQUMsV0FBVyxFQUFFLHlDQUF5QztxQkFDbkYsQ0FBQyxDQUFDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO2dCQUVILEVBQUUsQ0FBQyw2QkFBNkIsRUFBRSxLQUFLO29CQUNyQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3lCQUN0QixJQUFJLENBQUMsV0FBVyxNQUFNLENBQUMsSUFBSSxFQUFFLFdBQVcsTUFBTSxDQUFDLEVBQUUsRUFBRSwyQkFBMkIsQ0FBQzt5QkFDL0UsS0FBSyxDQUFDLEVBQUUsQ0FBQzt5QkFDVCxLQUFLLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO29CQUVsRCxNQUFNLHlCQUF5QixHQUFHLE1BQU0sTUFBTSxDQUFDLDBCQUEwQixFQUFFLENBQUM7b0JBRTVFLHlCQUF5QixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUVqRCxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDbEMsQ0FBQyxDQUFDLENBQUM7Z0JBRUgsRUFBRSxDQUFDLDhDQUE4QyxFQUFFLEtBQUs7b0JBQ3RELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7eUJBQ3RCLElBQUksQ0FBQyxXQUFXLE1BQU0sQ0FBQyxJQUFJLEVBQUUsV0FBVyxNQUFNLENBQUMsRUFBRSxFQUFFLDJCQUEyQixDQUFDO3lCQUMvRSxLQUFLLENBQUMsRUFBRSxDQUFDO3lCQUNULEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7b0JBRWxCLE1BQU0sTUFBTTt5QkFDVCwwQkFBMEIsRUFBRTt5QkFDNUIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMseURBQXlELENBQUMsQ0FBQztvQkFFckYsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2xDLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7WUFFSCxRQUFRLENBQUMsU0FBUyxFQUFFO2dCQUNsQixTQUFTLENBQUM7b0JBQ1IsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNsQixDQUFDLENBQUMsQ0FBQztnQkFFSCxFQUFFLENBQUMsMkNBQTJDLEVBQUUsS0FBSztvQkFDbkQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQzt5QkFDdEIsSUFBSSxDQUFDLFdBQVcsTUFBTSxDQUFDLElBQUksRUFBRSxXQUFXLE1BQU0sQ0FBQyxFQUFFLEVBQUUsMkJBQTJCLEVBQUUsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLENBQUM7eUJBQ3ZHLEtBQUssQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLHlCQUF5QixDQUFDLENBQUM7b0JBQ2xELE1BQU0sNEJBQTRCLEdBQUcsS0FBSzt5QkFDdkMsSUFBSSxDQUFDLE1BQU0sRUFBRSwwQkFBMEIsQ0FBQzt5QkFDeEMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO29CQUN2RCxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxtQ0FBbUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFFckUsTUFBTSxDQUFDLFFBQVEsR0FBRzt3QkFDaEIsMEJBQTBCLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDO3FCQUNuRCxDQUFDO29CQUVGLE1BQU0sTUFBTSxHQUFHLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxDQUFDO29CQUN0QyxNQUFNLE1BQU0sQ0FBQyx5QkFBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDL0MsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBRTNGLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNsQyxDQUFDLENBQUMsQ0FBQztnQkFFSCxFQUFFLENBQUMsK0ZBQStGLEVBQUUsS0FBSztvQkFDdkcsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQzt5QkFDdEIsSUFBSSxDQUFDLFdBQVcsTUFBTSxDQUFDLElBQUksRUFBRSxXQUFXLE1BQU0sQ0FBQyxFQUFFLEVBQUUsMkJBQTJCLEVBQUUsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLENBQUM7eUJBQ3ZHLEtBQUssQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLHlCQUF5QixDQUFDLENBQUM7b0JBQ2xELE1BQU0sNEJBQTRCLEdBQUcsS0FBSzt5QkFDdkMsSUFBSSxDQUFDLE1BQU0sRUFBRSwwQkFBMEIsQ0FBQzt5QkFDeEMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO29CQUN2RCxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxtQ0FBbUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFFckUsTUFBTSxDQUFDLFFBQVEsR0FBRzt3QkFDaEIsMEJBQTBCLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDO3FCQUNuRCxDQUFDO29CQUVGLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQztvQkFDbEIsTUFBTSxNQUFNLENBQUMseUJBQXlCLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQy9DLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLDRCQUE0QixFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUUzRixLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDbEMsQ0FBQyxDQUFDLENBQUM7Z0JBRUgsRUFBRSxDQUFDLGtEQUFrRCxFQUFFLEtBQUs7b0JBQzFELE1BQU0sZUFBZSxHQUFHLElBQUksaUJBQU0sQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFO3dCQUNsRCxFQUFFLEVBQUUsa0NBQWtDO3dCQUN0QyxJQUFJLEVBQUUsUUFBUTt3QkFDZCxJQUFJLEVBQUUsV0FBVztxQkFDbEIsQ0FBQyxDQUFDO29CQUVILE1BQU0sY0FBYyxHQUFHLFdBQVcsZUFBZSxDQUFDLElBQUksRUFBRSxXQUFXLGVBQWUsQ0FBQyxFQUFFLEVBQUUsY0FBYyxDQUFDO29CQUN0RyxJQUFJLEdBQUcsQ0FBQztvQkFDUixJQUFJLENBQUMsS0FBSyxDQUFDO3lCQUNSLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRTt3QkFDN0IsR0FBRyxHQUFHLElBQUksQ0FBQzt3QkFDWCxPQUFPLElBQUksQ0FBQztvQkFDZCxDQUFDLENBQUM7eUJBQ0QsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUVkLE1BQU0sTUFBTSxHQUFHLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUNyRSxNQUFNLGNBQWMsR0FBRyxFQUFFLEdBQUcsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxDQUFDO29CQUNsRSxNQUFNLGdCQUFnQixHQUFHLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLENBQUM7b0JBRWhFLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLDRCQUE0QixDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUN4RyxNQUFNLGVBQWUsQ0FBQyx3QkFBd0IsQ0FBQyxjQUFjLENBQUMsQ0FBQztvQkFFL0QsR0FBRyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDekMsQ0FBQyxDQUFDLENBQUM7Z0JBRUgsRUFBRSxDQUFDLHdEQUF3RCxFQUFFLEtBQUs7b0JBQ2hFLE1BQU0sZUFBZSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQzNDLE1BQU0sYUFBYSxHQUFHLElBQUksaUJBQU0sQ0FBQyxLQUFLLEVBQUUsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUM3RCxNQUFNLGFBQWEsQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQzt3QkFDdEUsT0FBTyxFQUFFLEdBQUcsZUFBZSxDQUFDLFdBQVcsRUFBRSx5Q0FBeUM7cUJBQ25GLENBQUMsQ0FBQztnQkFDTCxDQUFDLENBQUMsQ0FBQztnQkFFSCxFQUFFLENBQUMsa0VBQWtFLEVBQUUsS0FBSztvQkFDMUUsTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDM0MsTUFBTSxhQUFhLEdBQUcsSUFBSSxpQkFBTSxDQUFDLEtBQUssRUFBRSxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7b0JBQzdELE1BQU0sYUFBYSxDQUFDLHlCQUF5QixDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDO3dCQUN2RSxPQUFPLEVBQUUsR0FBRyxlQUFlLENBQUMsV0FBVyxFQUFFLHlDQUF5QztxQkFDbkYsQ0FBQyxDQUFDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO2dCQUVILEVBQUUsQ0FBQywrQ0FBK0MsRUFBRSxLQUFLO29CQUN2RCxNQUFNLE1BQU07eUJBQ1Qsd0JBQXdCLENBQUMsRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLENBQUM7eUJBQ3ZELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLEVBQUUsT0FBTyxFQUFFLHlDQUF5QyxFQUFFLENBQUMsQ0FBQztvQkFDbEYsTUFBTSxNQUFNO3lCQUNULHdCQUF3QixDQUFDLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxDQUFDO3lCQUNuRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxFQUFFLE9BQU8sRUFBRSx5Q0FBeUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3BGLENBQUMsQ0FBQyxDQUFDO2dCQUVILEVBQUUsQ0FBQyxnREFBZ0QsRUFBRSxLQUFLO29CQUN4RCxNQUFNLE1BQU07eUJBQ1Qsd0JBQXdCLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQUM7eUJBQzVDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLEVBQUUsT0FBTyxFQUFFLCtEQUErRCxFQUFFLENBQUMsQ0FBQztnQkFDMUcsQ0FBQyxDQUFDLENBQUM7Z0JBRUgsRUFBRSxDQUFDLDJDQUEyQyxFQUFFLEtBQUs7b0JBQ25ELE1BQU0sTUFBTSxHQUFHLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUVyRSxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSw0QkFBNEIsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsZ0NBQWdDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFFeEcsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQzt5QkFDdEIsSUFBSSxDQUFDLFdBQVcsTUFBTSxDQUFDLElBQUksRUFBRSxXQUFXLE1BQU0sQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLFFBQVEsQ0FBQywrQkFBK0IsQ0FBQzt5QkFDeEcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUVkLE1BQU0sTUFBTSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUU5QyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDbEMsQ0FBQyxDQUFDLENBQUM7Z0JBRUgsRUFBRSxDQUFDLDhFQUE4RSxFQUFFLEtBQUs7b0JBQ3RGLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7eUJBQzNCLElBQUksQ0FBQyxXQUFXLE1BQU0sQ0FBQyxJQUFJLEVBQUUsV0FBVyxNQUFNLENBQUMsRUFBRSxFQUFFLDJCQUEyQixDQUFDO3lCQUMvRSxLQUFLLENBQUMsRUFBRSxDQUFDO3lCQUNULEtBQUssQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLHlCQUF5QixDQUFDLENBQUM7b0JBRWxELEtBQUs7eUJBQ0YsSUFBSSxDQUFDLE1BQU0sRUFBRSw0QkFBNEIsQ0FBQzt5QkFDMUMsTUFBTSxDQUFDLENBQUMsQ0FBQzt5QkFDVCxRQUFRLENBQUMsUUFBUSxDQUFDLGdDQUFnQyxDQUFDLENBQUMsQ0FBQyxDQUFDO3lCQUN0RCxNQUFNLENBQUMsQ0FBQyxDQUFDO3lCQUNULFFBQVEsQ0FBQyxRQUFRLENBQUMsZ0NBQWdDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFFMUQsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsbUNBQW1DLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBRXJFLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQzt5QkFDakMsSUFBSSxDQUNILFdBQVcsTUFBTSxDQUFDLElBQUksRUFBRSxXQUFXLE1BQU0sQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUN4RCxRQUFRLENBQUMsZ0NBQWdDLENBQUMsQ0FBQyxDQUFDLENBQzdDO3lCQUNBLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFFZCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3lCQUMvQixJQUFJLENBQ0gsV0FBVyxNQUFNLENBQUMsSUFBSSxFQUFFLFdBQVcsTUFBTSxDQUFDLEVBQUUsRUFBRSxVQUFVLEVBQ3hELFFBQVEsQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDLENBQUMsQ0FDN0M7eUJBQ0EsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUVkLE1BQU0sY0FBYyxHQUFHLE1BQU0sTUFBTSxDQUFDLHlCQUF5QixFQUFFLENBQUM7b0JBRWhFLGNBQWMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQzlDLGNBQWMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBRTlDLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQzNDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO29CQUN6QyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDdkMsQ0FBQyxDQUFDLENBQUM7Z0JBRUgsRUFBRSxDQUFDLHlGQUF5RixFQUFFLEtBQUs7b0JBQ2pHLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7eUJBQzNCLElBQUksQ0FBQyxXQUFXLE1BQU0sQ0FBQyxJQUFJLEVBQUUsV0FBVyxNQUFNLENBQUMsRUFBRSxFQUFFLDJCQUEyQixDQUFDO3lCQUMvRSxLQUFLLENBQUMsRUFBRSxDQUFDO3lCQUNULEtBQUssQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLHlCQUF5QixDQUFDLENBQUM7b0JBRWxELEtBQUs7eUJBQ0YsSUFBSSxDQUFDLE1BQU0sRUFBRSw0QkFBNEIsQ0FBQzt5QkFDMUMsTUFBTSxDQUFDLENBQUMsQ0FBQzt5QkFDVCxRQUFRLENBQUMsUUFBUSxDQUFDLGdDQUFnQyxDQUFDLENBQUMsQ0FBQyxDQUFDO3lCQUN0RCxNQUFNLENBQUMsQ0FBQyxDQUFDO3lCQUNULFFBQVEsQ0FBQyxRQUFRLENBQUMsZ0NBQWdDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFFMUQsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsbUNBQW1DLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBRXJFLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQzt5QkFDakMsSUFBSSxDQUNILFdBQVcsTUFBTSxDQUFDLElBQUksRUFBRSxXQUFXLE1BQU0sQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUN4RCxRQUFRLENBQUMsZ0NBQWdDLENBQUMsQ0FBQyxDQUFDLENBQzdDO3lCQUNBLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFFZCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3lCQUMvQixJQUFJLENBQ0gsV0FBVyxNQUFNLENBQUMsSUFBSSxFQUFFLFdBQVcsTUFBTSxDQUFDLEVBQUUsRUFBRSxVQUFVLEVBQ3hELFFBQVEsQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDLENBQUMsQ0FDN0M7eUJBQ0EsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUVkLE1BQU0sY0FBYyxHQUFHLE1BQU0sTUFBTSxDQUFDLHlCQUF5QixFQUFFLENBQUM7b0JBRWhFLGNBQWMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQzlDLGNBQWMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBRTlDLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQzNDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO29CQUN6QyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDdkMsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztBQUNILENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy9cbi8vIEFjY291bnQgY29uc29saWRhdGlvbiB0ZXN0c1xuLy9cblxuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xucmVxdWlyZSgnc2hvdWxkLXNpbm9uJyk7XG5cbmltcG9ydCAnLi4vbGliL2Fzc2VydHMnO1xuaW1wb3J0IG5vY2sgPSByZXF1aXJlKCdub2NrJyk7XG5cbmltcG9ydCB7IGNvbW1vbiwgV2FsbGV0IH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcblxuaW1wb3J0IHsgVGVzdEJpdEdvIH0gZnJvbSAnQGJpdGdvL3Nkay10ZXN0JztcbmltcG9ydCB7IEJpdEdvIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2JpdGdvJztcbmNvbnN0IGFsZ29GaXh0dXJlcyA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL3Nkay1jb2luLWFsZ28vdGVzdC9maXh0dXJlcy9hbGdvJyk7XG5cbm5vY2suZGlzYWJsZU5ldENvbm5lY3QoKTtcblxuZGVzY3JpYmUoJ0FjY291bnQgQ29uc29saWRhdGlvbnM6JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z287XG4gIGxldCB3YWxsZXQ7XG4gIGxldCBiYXNlY29pbjtcbiAgbGV0IGJnVXJsO1xuICBsZXQgZml4dHVyZXM7XG5cbiAgZm9yIChjb25zdCBjb2luTmFtZSBvZiBbJ3RhbGdvJywgJ3R4dHonXSkge1xuICAgIGRlc2NyaWJlKGNvaW5OYW1lICsgJyBBY2NvdW50IENvbnNvbGlkYXRpb25zOiAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICAgICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbihjb2luTmFtZSk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgICBpZDogJzVlNDE2OGY0NDAzZDBjNWMxYzNiZGQxNTQ4NmU3NTdmJyxcbiAgICAgICAgICBjb2luOiBjb2luTmFtZSxcbiAgICAgICAgfTtcblxuICAgICAgICB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCBiYXNlY29pbiwgd2FsbGV0RGF0YSk7XG4gICAgICAgIGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgICBpZiAoY29pbk5hbWUgPT09ICd0YWxnbycpIHtcbiAgICAgICAgICBmaXh0dXJlcyA9IGFsZ29GaXh0dXJlcy5wcmVidWlsZCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ0J1aWxkaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpdCgnc2hvdWxkIG5vdCBhbGxvdyBhIG5vbi1hY2NvdW50IGNvbnNvbGlkYXRpb24gY29pbiBidWlsZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB1bnN1cHBvcnRlZENvaW4gPSBiaXRnby5jb2luKCd0YnRjJyk7XG4gICAgICAgICAgY29uc3QgaW52YWxpZFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIHVuc3VwcG9ydGVkQ29pbiwge30pO1xuICAgICAgICAgIGF3YWl0IGludmFsaWRXYWxsZXQuYnVpbGRBY2NvdW50Q29uc29saWRhdGlvbnMoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6IGAke3Vuc3VwcG9ydGVkQ29pbi5nZXRGdWxsTmFtZSgpfSBkb2VzIG5vdCBhbGxvdyBhY2NvdW50IGNvbnNvbGlkYXRpb25zLmAsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgYnVpbGQgd2l0aCBubyBwYXJhbXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vY29uc29saWRhdGVBY2NvdW50L2J1aWxkYClcbiAgICAgICAgICAgIC5xdWVyeSh7fSlcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIGZpeHR1cmVzLmJ1aWxkQWNjb3VudENvbnNvbGlkYXRpb24pO1xuXG4gICAgICAgICAgY29uc3QgYWNjb3VudENvbnNvbGlkYXRpb25CdWlsZCA9IGF3YWl0IHdhbGxldC5idWlsZEFjY291bnRDb25zb2xpZGF0aW9ucygpO1xuXG4gICAgICAgICAgYWNjb3VudENvbnNvbGlkYXRpb25CdWlsZC5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuXG4gICAgICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiB0aGUgcmVzdWx0IGlzIGFuIGVtcHR5IGFycmF5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHNjb3BlID0gbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L2NvbnNvbGlkYXRlQWNjb3VudC9idWlsZGApXG4gICAgICAgICAgICAucXVlcnkoe30pXG4gICAgICAgICAgICAucmVwbHkoMjAwLCBbXSk7XG5cbiAgICAgICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgICAgIC5idWlsZEFjY291bnRDb25zb2xpZGF0aW9ucygpXG4gICAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnTm8gcmVjZWl2ZSBhZGRyZXNzZXMgd2l0aCBiYWxhbmNlIGZvdW5kIHRvIGNvbnNvbGlkYXRlLicpO1xuXG4gICAgICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ1NlbmRpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgc2lub24ucmVzdG9yZSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHVzZSBwYXJhbXMuYXBpVmVyc2lvbiBpZiBzcGVjaWZpZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vY29uc29saWRhdGVBY2NvdW50L2J1aWxkYCwgeyBhcGlWZXJzaW9uOiAnbGl0ZScgfSlcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIGZpeHR1cmVzLmJ1aWxkQWNjb3VudENvbnNvbGlkYXRpb24pO1xuICAgICAgICAgIGNvbnN0IHNlbmRBY2NvdW50Q29uc29saWRhdGlvblN0dWIgPSBzaW5vblxuICAgICAgICAgICAgLnN0dWIod2FsbGV0LCAnc2VuZEFjY291bnRDb25zb2xpZGF0aW9uJylcbiAgICAgICAgICAgIC5yZXNvbHZlcyhmaXh0dXJlcy5zaWduZWRBY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkcyk7XG4gICAgICAgICAgc2lub24uc3R1Yih3YWxsZXQsICdnZXRLZXljaGFpbnNBbmRWYWxpZGF0ZVBhc3NwaHJhc2UnKS5yZXNvbHZlcyhbXSk7XG5cbiAgICAgICAgICB3YWxsZXQudHNzVXRpbHMgPSB7XG4gICAgICAgICAgICBzdXBwb3J0ZWRUeFJlcXVlc3RWZXJzaW9uczogKCkgPT4gWydsaXRlJywgJ2Z1bGwnXSxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0geyBhcGlWZXJzaW9uOiAnbGl0ZScgfTtcbiAgICAgICAgICBhd2FpdCB3YWxsZXQuc2VuZEFjY291bnRDb25zb2xpZGF0aW9ucyhwYXJhbXMpO1xuICAgICAgICAgIHNpbm9uLmFzc2VydC5jYWxsZWRXaXRoKHNlbmRBY2NvdW50Q29uc29saWRhdGlvblN0dWIsIHNpbm9uLm1hdGNoKHsgYXBpVmVyc2lvbjogJ2xpdGUnIH0pKTtcblxuICAgICAgICAgIHNjb3BlLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgdXNlIGFwaVZlcnNpb24gZnVsbCBmb3IgdGhlIHRyYW5zYWN0aW9uIGlmIGl0IGlzIHN1cHBvcnRlZCBhbmQgbm8gYXBpVmVyc2lvbiBpcyBwYXNzZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsKVxuICAgICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vY29uc29saWRhdGVBY2NvdW50L2J1aWxkYCwgeyBhcGlWZXJzaW9uOiAnZnVsbCcgfSlcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIGZpeHR1cmVzLmJ1aWxkQWNjb3VudENvbnNvbGlkYXRpb24pO1xuICAgICAgICAgIGNvbnN0IHNlbmRBY2NvdW50Q29uc29saWRhdGlvblN0dWIgPSBzaW5vblxuICAgICAgICAgICAgLnN0dWIod2FsbGV0LCAnc2VuZEFjY291bnRDb25zb2xpZGF0aW9uJylcbiAgICAgICAgICAgIC5yZXNvbHZlcyhmaXh0dXJlcy5zaWduZWRBY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkcyk7XG4gICAgICAgICAgc2lub24uc3R1Yih3YWxsZXQsICdnZXRLZXljaGFpbnNBbmRWYWxpZGF0ZVBhc3NwaHJhc2UnKS5yZXNvbHZlcyhbXSk7XG5cbiAgICAgICAgICB3YWxsZXQudHNzVXRpbHMgPSB7XG4gICAgICAgICAgICBzdXBwb3J0ZWRUeFJlcXVlc3RWZXJzaW9uczogKCkgPT4gWydsaXRlJywgJ2Z1bGwnXSxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgY29uc3QgcGFyYW1zID0ge307XG4gICAgICAgICAgYXdhaXQgd2FsbGV0LnNlbmRBY2NvdW50Q29uc29saWRhdGlvbnMocGFyYW1zKTtcbiAgICAgICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkV2l0aChzZW5kQWNjb3VudENvbnNvbGlkYXRpb25TdHViLCBzaW5vbi5tYXRjaCh7IGFwaVZlcnNpb246ICdmdWxsJyB9KSk7XG5cbiAgICAgICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHV0aWxpemUgY29kZWMgZm9yIGN1c3RvZGlhbCBjb25zb2xpZGF0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IGN1c3RvZGlhbFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIGJhc2Vjb2luLCB7XG4gICAgICAgICAgICBpZDogJzVmNDE2OGY0NDAzZDBjNWMxYzNiZGQxNTQ4NmU3NTdmJyxcbiAgICAgICAgICAgIGNvaW46IGNvaW5OYW1lLFxuICAgICAgICAgICAgdHlwZTogJ2N1c3RvZGlhbCcsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBpbml0aWF0ZVR4UGF0aCA9IGAvYXBpL3YyLyR7Y3VzdG9kaWFsV2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7Y3VzdG9kaWFsV2FsbGV0LmlkKCl9L3R4L2luaXRpYXRlYDtcbiAgICAgICAgICBsZXQgcmVxO1xuICAgICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucG9zdChpbml0aWF0ZVR4UGF0aCwgKGJvZHkpID0+IHtcbiAgICAgICAgICAgICAgcmVxID0gYm9keTtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7IHByZWJ1aWxkVHg6IGZpeHR1cmVzLmJ1aWxkQWNjb3VudENvbnNvbGlkYXRpb25bMF0gfTtcbiAgICAgICAgICBjb25zdCBwYXJhbXNXaXRoSnVuayA9IHsgLi4ucGFyYW1zLCBqdW5rOiAnanVuaycsIG90cDogJzAwMDAwMCcgfTtcbiAgICAgICAgICBjb25zdCBwYXJhbXNBZnRlckNvZGVjID0geyB0eXBlOiAnY29uc29saWRhdGUnLCBvdHA6ICcwMDAwMDAnIH07XG5cbiAgICAgICAgICBzaW5vbi5zdHViKHdhbGxldCwgJ3ByZWJ1aWxkQW5kU2lnblRyYW5zYWN0aW9uJykucmVzb2x2ZXMoZml4dHVyZXMuc2lnbmVkQWNjb3VudENvbnNvbGlkYXRpb25CdWlsZHNbMF0pO1xuICAgICAgICAgIGF3YWl0IGN1c3RvZGlhbFdhbGxldC5zZW5kQWNjb3VudENvbnNvbGlkYXRpb24ocGFyYW1zV2l0aEp1bmspO1xuXG4gICAgICAgICAgcmVxLnNob3VsZC5kZWVwRXF1YWwocGFyYW1zQWZ0ZXJDb2RlYyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgbm90IGFsbG93IGEgbm9uLWFjY291bnQgY29uc29saWRhdGlvbiBjb2luIHNlbmQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3QgdW5zdXBwb3J0ZWRDb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgICAgICAgIGNvbnN0IGludmFsaWRXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB1bnN1cHBvcnRlZENvaW4sIHt9KTtcbiAgICAgICAgICBhd2FpdCBpbnZhbGlkV2FsbGV0LnNlbmRBY2NvdW50Q29uc29saWRhdGlvbih7fSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCh7XG4gICAgICAgICAgICBtZXNzYWdlOiBgJHt1bnN1cHBvcnRlZENvaW4uZ2V0RnVsbE5hbWUoKX0gZG9lcyBub3QgYWxsb3cgYWNjb3VudCBjb25zb2xpZGF0aW9ucy5gLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIG5vdCBhbGxvdyBhIG5vbi1hY2NvdW50IGNvbnNvbGlkYXRpb24gY29pbiBzZW5kIG11bHRpcGxlcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCB1bnN1cHBvcnRlZENvaW4gPSBiaXRnby5jb2luKCd0YnRjJyk7XG4gICAgICAgICAgY29uc3QgaW52YWxpZFdhbGxldCA9IG5ldyBXYWxsZXQoYml0Z28sIHVuc3VwcG9ydGVkQ29pbiwge30pO1xuICAgICAgICAgIGF3YWl0IGludmFsaWRXYWxsZXQuc2VuZEFjY291bnRDb25zb2xpZGF0aW9ucyh7fSkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCh7XG4gICAgICAgICAgICBtZXNzYWdlOiBgJHt1bnN1cHBvcnRlZENvaW4uZ2V0RnVsbE5hbWUoKX0gZG9lcyBub3QgYWxsb3cgYWNjb3VudCBjb25zb2xpZGF0aW9ucy5gLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIG5vdCBhbGxvdyBhIGJhZCBwcmUtYnVpbGQgdG8gYmUgcGFzc2VkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgICAgLnNlbmRBY2NvdW50Q29uc29saWRhdGlvbih7IHByZWJ1aWxkVHg6ICdzb21lIHN0cmluZycgfSlcbiAgICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKHsgbWVzc2FnZTogJ0ludmFsaWQgYnVpbGQgb2YgYWNjb3VudCBjb25zb2xpZGF0aW9uLicgfSk7XG4gICAgICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgICAgICAuc2VuZEFjY291bnRDb25zb2xpZGF0aW9uKHsgcHJlYnVpbGRUeDogdW5kZWZpbmVkIH0pXG4gICAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCh7IG1lc3NhZ2U6ICdJbnZhbGlkIGJ1aWxkIG9mIGFjY291bnQgY29uc29saWRhdGlvbi4nIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdCgnc2hvdWxkIHJlcXVpcmUgYSBjb25zb2xpZGF0aW9uIGlkIHRvIGJlIHBhc3NlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgICAgIC5zZW5kQWNjb3VudENvbnNvbGlkYXRpb24oeyBwcmVidWlsZFR4OiB7fSB9KVxuICAgICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoeyBtZXNzYWdlOiAnRmFpbGVkIHRvIGZpbmQgY29uc29saWRhdGlvbiBpZCBvbiBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uLicgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgc3VibWl0IGEgY29uc29saWRhdGlvbiB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBwYXJhbXMgPSB7IHByZWJ1aWxkVHg6IGZpeHR1cmVzLmJ1aWxkQWNjb3VudENvbnNvbGlkYXRpb25bMF0gfTtcblxuICAgICAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAncHJlYnVpbGRBbmRTaWduVHJhbnNhY3Rpb24nKS5yZXNvbHZlcyhmaXh0dXJlcy5zaWduZWRBY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkc1swXSk7XG5cbiAgICAgICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9zZW5kYCwgZml4dHVyZXMuc2lnbmVkQWNjb3VudENvbnNvbGlkYXRpb25CdWlsZClcbiAgICAgICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAgICAgYXdhaXQgd2FsbGV0LnNlbmRBY2NvdW50Q29uc29saWRhdGlvbihwYXJhbXMpO1xuXG4gICAgICAgICAgc2NvcGUuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBzdWJtaXQgYSBjb25zb2xpZGF0aW9uIGFjY291bnQgc2VuZCAoYnVpbGQgKyBzZW5kKSB3aXRoIHR3byBzdWNjZXNzZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2NvcGVCdWlsZCA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS9jb25zb2xpZGF0ZUFjY291bnQvYnVpbGRgKVxuICAgICAgICAgICAgLnF1ZXJ5KHt9KVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgZml4dHVyZXMuYnVpbGRBY2NvdW50Q29uc29saWRhdGlvbik7XG5cbiAgICAgICAgICBzaW5vblxuICAgICAgICAgICAgLnN0dWIod2FsbGV0LCAncHJlYnVpbGRBbmRTaWduVHJhbnNhY3Rpb24nKVxuICAgICAgICAgICAgLm9uQ2FsbCgwKVxuICAgICAgICAgICAgLnJlc29sdmVzKGZpeHR1cmVzLnNpZ25lZEFjY291bnRDb25zb2xpZGF0aW9uQnVpbGRzWzBdKVxuICAgICAgICAgICAgLm9uQ2FsbCgxKVxuICAgICAgICAgICAgLnJlc29sdmVzKGZpeHR1cmVzLnNpZ25lZEFjY291bnRDb25zb2xpZGF0aW9uQnVpbGRzWzFdKTtcblxuICAgICAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnZ2V0S2V5Y2hhaW5zQW5kVmFsaWRhdGVQYXNzcGhyYXNlJykucmVzb2x2ZXMoW10pO1xuXG4gICAgICAgICAgY29uc3Qgc2NvcGVGaXJzdFNpZ25lZCA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgICAucG9zdChcbiAgICAgICAgICAgICAgYC9hcGkvdjIvJHt3YWxsZXQuY29pbigpfS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvc2VuZGAsXG4gICAgICAgICAgICAgIGZpeHR1cmVzLnNpZ25lZEFjY291bnRDb25zb2xpZGF0aW9uQnVpbGRzWzBdXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgICAgIGNvbnN0IHNjb3BlVHdvU2lnbmVkID0gbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5wb3N0KFxuICAgICAgICAgICAgICBgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9zZW5kYCxcbiAgICAgICAgICAgICAgZml4dHVyZXMuc2lnbmVkQWNjb3VudENvbnNvbGlkYXRpb25CdWlsZHNbMV1cbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAgICAgY29uc3QgY29uc29saWRhdGlvbnMgPSBhd2FpdCB3YWxsZXQuc2VuZEFjY291bnRDb25zb2xpZGF0aW9ucygpO1xuXG4gICAgICAgICAgY29uc29saWRhdGlvbnMuc3VjY2Vzcy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgICAgIGNvbnNvbGlkYXRpb25zLmZhaWx1cmUubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcblxuICAgICAgICAgIHNjb3BlRmlyc3RTaWduZWQuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICAgICAgICBzY29wZVR3b1NpZ25lZC5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgICAgIHNjb3BlQnVpbGQuaXNEb25lKCkuc2hvdWxkLmJlLlRydWUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBzdWJtaXQgYSBjb25zb2xpZGF0aW9uIGFjY291bnQgc2VuZCAoYnVpbGQgKyBzZW5kKSB3aXRoIG9uZSBzdWNjZXNzLCBvbmUgZmFpbHVyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBzY29wZUJ1aWxkID0gbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L2NvbnNvbGlkYXRlQWNjb3VudC9idWlsZGApXG4gICAgICAgICAgICAucXVlcnkoe30pXG4gICAgICAgICAgICAucmVwbHkoMjAwLCBmaXh0dXJlcy5idWlsZEFjY291bnRDb25zb2xpZGF0aW9uKTtcblxuICAgICAgICAgIHNpbm9uXG4gICAgICAgICAgICAuc3R1Yih3YWxsZXQsICdwcmVidWlsZEFuZFNpZ25UcmFuc2FjdGlvbicpXG4gICAgICAgICAgICAub25DYWxsKDApXG4gICAgICAgICAgICAucmVzb2x2ZXMoZml4dHVyZXMuc2lnbmVkQWNjb3VudENvbnNvbGlkYXRpb25CdWlsZHNbMF0pXG4gICAgICAgICAgICAub25DYWxsKDEpXG4gICAgICAgICAgICAucmVzb2x2ZXMoZml4dHVyZXMuc2lnbmVkQWNjb3VudENvbnNvbGlkYXRpb25CdWlsZHNbMV0pO1xuXG4gICAgICAgICAgc2lub24uc3R1Yih3YWxsZXQsICdnZXRLZXljaGFpbnNBbmRWYWxpZGF0ZVBhc3NwaHJhc2UnKS5yZXNvbHZlcyhbXSk7XG5cbiAgICAgICAgICBjb25zdCBzY29wZVdpdGhTdWNjZXNzID0gbm9jayhiZ1VybClcbiAgICAgICAgICAgIC5wb3N0KFxuICAgICAgICAgICAgICBgL2FwaS92Mi8ke3dhbGxldC5jb2luKCl9L3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC9zZW5kYCxcbiAgICAgICAgICAgICAgZml4dHVyZXMuc2lnbmVkQWNjb3VudENvbnNvbGlkYXRpb25CdWlsZHNbMF1cbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAgICAgY29uc3Qgc2NvcGVXaXRoRXJyb3IgPSBub2NrKGJnVXJsKVxuICAgICAgICAgICAgLnBvc3QoXG4gICAgICAgICAgICAgIGAvYXBpL3YyLyR7d2FsbGV0LmNvaW4oKX0vd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4L3NlbmRgLFxuICAgICAgICAgICAgICBmaXh0dXJlcy5zaWduZWRBY2NvdW50Q29uc29saWRhdGlvbkJ1aWxkc1sxXVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnJlcGx5KDUwMCk7XG5cbiAgICAgICAgICBjb25zdCBjb25zb2xpZGF0aW9ucyA9IGF3YWl0IHdhbGxldC5zZW5kQWNjb3VudENvbnNvbGlkYXRpb25zKCk7XG5cbiAgICAgICAgICBjb25zb2xpZGF0aW9ucy5zdWNjZXNzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgICAgY29uc29saWRhdGlvbnMuZmFpbHVyZS5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICAgICAgc2NvcGVXaXRoU3VjY2Vzcy5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgICAgIHNjb3BlV2l0aEVycm9yLmlzRG9uZSgpLnNob3VsZC5iZS5UcnVlKCk7XG4gICAgICAgICAgc2NvcGVCdWlsZC5pc0RvbmUoKS5zaG91bGQuYmUuVHJ1ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59KTtcbiJdfQ==