PHP WebShell

Текущая директория: /opt/BitGoJS/modules/bitgo/dist/test/v2/unit

Просмотр файла: wallets.js

"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 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();
        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(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(bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
        });
    });
    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`)
                .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(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(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 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 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`).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(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(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(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(bitgo.decrypt({ input: response.encryptedWalletPassphrase, password: params.passcodeEncryptionCode }), params.passphrase);
        });
    });
    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/tbtc/walletshare/${shareId}`)
                    .reply(200, {
                    keychainOverrideRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                });
                // Validate accept share case
                await wallets
                    .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/tbtc/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/tbtc/walletshare/${shareId}`)
                    .reply(200, {
                    keychainOverrideRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                });
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/tbtc/walletshare/${shareId}`, (body) => {
                    if (body.walletShareId !== shareId || body.state !== 'accepted' || body.keyId !== keychainId) {
                        return false;
                    }
                    return true;
                })
                    .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 wallets.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/tbtc/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/tbtc/walletshare/${shareId}`)
                    .reply(200, {
                    keychainOverrideRequired: true,
                    permissions: ['admin', 'spend', 'view'],
                });
                const acceptShareNock = nock(bgUrl)
                    .post(`/api/v2/tbtc/walletshare/${shareId}`, (body) => {
                    if (body.walletShareId !== shareId || body.state !== 'accepted' || body.keyId !== keychainId) {
                        return false;
                    }
                    return true;
                })
                    .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 wallets.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/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) => {
                    if (body.walletShareId !== shareId || body.state !== 'accepted' || body.keyId !== keychainId) {
                        return false;
                    }
                    return true;
                })
                    .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) => 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 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.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) => {
                    if (body.walletShareId !== shareId || body.state !== 'accepted' || body.keyId !== keychainId) {
                        return false;
                    }
                    return true;
                })
                    .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);
            });
        });
        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('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('Missing parameter: userLoginPassword');
            });
            it('should throw assertion error for empty walletShareIds', async () => {
                await wallets
                    .bulkAcceptShare({ walletShareIds: [], userLoginPassword: 'dummy@123' })
                    .should.rejectedWith('no walletShareIds 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
                    .bulkAcceptShare({
                    walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd1'],
                    userLoginPassword: 'dummy@123',
                })
                    .should.rejectedWith('invalid wallet shares provided');
            });
            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('invalid wallet shares provided');
            });
            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: bitgo.encrypt({ input: fromUserPrv.toString(), password: walletPassphrase }),
                };
                const userPrv = (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 = 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: bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                const prvKey = bitgo.decrypt({
                    password: walletPassphrase,
                    input: bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                sinon.stub(bitgo, 'decrypt').returns(prvKey);
                sinon.stub(moduleBitgo, 'getSharedSecret').resolves('fakeSharedSecret');
                const share = await wallets.bulkAcceptShare({
                    walletShareIds: ['66a229dbdccdcfb95b44fc2745a60bd4'],
                    userLoginPassword: walletPassphrase,
                });
                assert.deepEqual(share, {
                    acceptedWalletShares: [
                        {
                            walletShareId: '66a229dbdccdcfb95b44fc2745a60bd4',
                        },
                    ],
                });
            });
        });
        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 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: 'tsol',
                            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(wallets.baseCoin.keychains(), 'createUserKeychain').resolves(userKeychain);
                // Mock decrypt and signMessage
                sinon.stub(bitgo, 'decrypt').returns('decryptedPrivateKey');
                sinon.stub(wallets.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 wallets.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 = 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: bitgo.encrypt({ input: myEcdhKeychain.xprv, password: walletPassphrase }),
                });
                // Setup decrypt and encrypt stubs
                const decryptStub = sinon.stub(bitgo, 'decrypt');
                decryptStub.onFirstCall().returns(myEcdhKeychain.xprv); // For sharing keychain
                decryptStub.onSecondCall().returns(originalPrivKey); // For wallet keychain
                const encryptStub = sinon.stub(bitgo, 'encrypt').returns('newEncryptedPrv');
                // 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);
                // Param should be for share1 with accept status and encryptedPrv
                updateParams.should.containDeep([
                    {
                        walletShareId: 'share1',
                        status: 'accept',
                        encryptedPrv: 'newEncryptedPrv',
                    },
                ]);
                // Verify encrypt was called with correct parameters
                encryptStub.calledOnce.should.be.true();
                encryptStub.firstCall.args[0].should.have.property('password', 'newPassphrase');
                encryptStub.firstCall.args[0].should.have.property('input', 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');
            });
        });
    });
    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(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, 'shareOptions cannot be empty');
            }
        });
        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: 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: 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: 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: 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(error instanceof sdk_core_1.IncorrectPasswordError);
                assert.equal(error.message, 'Password shared is incorrect for this wallet');
            }
        });
    });
    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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Rlc3QvdjIvdW5pdC93YWxsZXRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsRUFBRTtBQUNGLG9CQUFvQjtBQUNwQixFQUFFO0FBQ0YsaUNBQWlDO0FBQ2pDLDZCQUE2QjtBQUM3QiwrQkFBK0I7QUFDL0IsaUNBQWlDO0FBQ2pDLDRCQUE0QjtBQUM1QiwyQ0FBMkM7QUFDM0MsOENBQTRDO0FBQzVDLDhDQWtCeUI7QUFDekIsc0NBQXFDO0FBQ3JDLGlDQUFrQztBQUVsQywrQ0FBK0M7QUFFL0MsUUFBUSxDQUFDLGFBQWEsRUFBRTtJQUN0QixNQUFNLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxXQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUN6RCxJQUFJLE9BQU8sQ0FBQztJQUNaLElBQUksS0FBSyxDQUFDO0lBRVYsTUFBTSxDQUFDO1FBQ0wsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLDBCQUEwQixDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakgsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFFM0IsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwQyxPQUFPLEdBQUcsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzdCLEtBQUssR0FBRyxpQkFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxLQUFLLENBQUM7UUFDSixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdDLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGFBQWEsRUFBRTtRQUN0QixFQUFFLENBQUMsNkJBQTZCLEVBQUUsS0FBSztZQUNyQyxvQ0FBb0M7WUFDcEMsTUFBTSxPQUFPO2lCQUNWLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUM7aUJBQ3ZGLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHFEQUFxRCxDQUFDLENBQUM7WUFFakYsdUJBQXVCO1lBQ3ZCLE1BQU0sT0FBTztpQkFDVixHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO2lCQUNoRixNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxtREFBbUQsQ0FBQyxDQUFDO1lBRS9FLGdDQUFnQztZQUNoQyxNQUFNLE9BQU87aUJBQ1YsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQztpQkFDckYsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsOERBQThELENBQUMsQ0FBQztZQUUxRix1QkFBdUI7WUFDdkIsTUFBTSxPQUFPO2lCQUNWLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7aUJBQ3ZGLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLGlEQUFpRCxDQUFDLENBQUM7WUFFN0UsNEJBQTRCO1lBQzVCLE1BQU0sT0FBTztpQkFDVixHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLEdBQUcsRUFBRSxDQUFDO2lCQUMzRixNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxzREFBc0QsQ0FBQyxDQUFDO1FBQ3BGLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1DQUFtQyxFQUFFLEtBQUs7WUFDM0MsSUFBSSxDQUFDLEtBQUssQ0FBQztpQkFDUixJQUFJLENBQUMseUJBQXlCLEVBQUUsVUFBVSxJQUFJO2dCQUM3QyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDbEMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2QixJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZCLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQyxDQUFDO2lCQUNELEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbEIsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzNHLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDJDQUEyQyxFQUFFLEtBQUs7WUFDbkQsTUFBTSxRQUFRLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsV0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDNUQsUUFBUSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDOUIsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNuRCxNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUM7WUFDL0IsSUFBSSxDQUFDLEtBQUssQ0FBQztpQkFDUixJQUFJLENBQUMseUJBQXlCLEVBQUUsVUFBVSxJQUFJO2dCQUM3QyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN2QixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ25DLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQyxDQUFDO2lCQUNELEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbEIsTUFBTSxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBUyxDQUFDLENBQUM7UUFDM0csQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsbUNBQW1DLEVBQUUsS0FBSztZQUMzQyxJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNSLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxVQUFVLElBQUk7Z0JBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDbkMsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNsQixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDckYsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUNBQXVDLEVBQUUsS0FBSztZQUMvQyxNQUFNLFFBQVEsR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxXQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUM1RCxRQUFRLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUM5QixNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ25ELElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ1IsSUFBSSxDQUFDLHlCQUF5QixFQUFFLFVBQVUsSUFBSTtnQkFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUNwQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ25DLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQyxDQUFDO2lCQUNELEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbEIsTUFBTSxVQUFVLENBQUMsR0FBRyxDQUFDO2dCQUNuQixLQUFLLEVBQUUsT0FBTztnQkFDZCxVQUFVLEVBQUUsWUFBWTtnQkFDeEIsSUFBSSxFQUFFLFdBQVc7Z0JBQ2pCLFFBQVEsRUFBRSxXQUFXO2FBQ2YsQ0FBQyxDQUFDO1FBQ1osQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMseUNBQXlDLEVBQUUsS0FBSztZQUNqRCxNQUFNLFFBQVEsR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxXQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUM1RCxRQUFRLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUM5QixNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ25ELElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ1IsSUFBSSxDQUFDLHlCQUF5QixFQUFFLFVBQVUsSUFBSTtnQkFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUNwQyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ25DLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQyxDQUFDO2lCQUNELEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbEIsTUFBTSxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBUyxDQUFDLENBQUM7UUFDakgsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUNBQXVDLEVBQUUsS0FBSztZQUMvQyxJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNSLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxVQUFVLElBQUk7Z0JBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDOUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNsQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQy9CLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDL0IsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNsQixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUM7Z0JBQ2hCLEtBQUssRUFBRSxPQUFPO2dCQUNkLFVBQVUsRUFBRSxZQUFZO2dCQUN4QixJQUFJLEVBQUUsS0FBSztnQkFDWCxJQUFJLEVBQUUsRUFBRTtnQkFDUixDQUFDLEVBQUUsQ0FBQztnQkFDSixDQUFDLEVBQUUsQ0FBQztnQkFDSixPQUFPLEVBQUUsU0FBUzthQUNuQixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGtCQUFrQixFQUFFO1FBQzNCLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN0QyxFQUFFLENBQUMsNEJBQTRCLEVBQUUsS0FBSztZQUNwQyxJQUFJLE1BQU0sR0FBRyxFQUFFLENBQUM7WUFDaEIsTUFBTSxPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLDBCQUEwQixDQUFDLENBQUM7WUFFeEYsTUFBTSxHQUFHO2dCQUNQLEtBQUssRUFBRSxLQUFLO2dCQUNaLFVBQVUsRUFBRSxRQUFRO2dCQUNwQixrQkFBa0IsRUFBRSxVQUFVO2FBQy9CLENBQUM7WUFFRixNQUFNLE9BQU87aUJBQ1YsY0FBYyxDQUFDLE1BQU0sQ0FBQztpQkFDdEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsb0VBQW9FLENBQUMsQ0FBQztZQUVoRyxNQUFNLEdBQUc7Z0JBQ1AsS0FBSyxFQUFFLEtBQUs7Z0JBQ1osc0JBQXNCLEVBQUUsR0FBRzthQUM1QixDQUFDO1lBQ0YsTUFBTSxPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHlDQUF5QyxDQUFDLENBQUM7WUFFdkcsTUFBTSxHQUFHO2dCQUNQLEtBQUssRUFBRSxLQUFLO2dCQUNaLFVBQVUsRUFBRSxJQUFJO2FBQ2pCLENBQUM7WUFDRixNQUFNLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsK0NBQStDLENBQUMsQ0FBQztZQUU3RyxNQUFNLEdBQUc7Z0JBQ1AsS0FBSyxFQUFFLEtBQUs7Z0JBQ1osK0JBQStCLEVBQUUsUUFBUTthQUMxQyxDQUFDO1lBRUYsTUFBTSxPQUFPO2lCQUNWLGNBQWMsQ0FBQyxNQUFNLENBQUM7aUJBQ3RCLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHFFQUFxRSxDQUFDLENBQUM7WUFFakcsTUFBTSxHQUFHO2dCQUNQLEtBQUssRUFBRSxLQUFLO2dCQUNaLFFBQVEsRUFBRSxRQUFRO2FBQ25CLENBQUM7WUFFRixNQUFNLE9BQU87aUJBQ1YsY0FBYyxDQUFDLE1BQU0sQ0FBQztpQkFDdEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsa0VBQWtFLENBQUMsQ0FBQztZQUU5RixNQUFNLEdBQUc7Z0JBQ1AsS0FBSyxFQUFFLEtBQUs7Z0JBQ1osUUFBUSxFQUFFLElBQUk7YUFDZixDQUFDO1lBRUYsTUFBTSxPQUFPO2lCQUNWLGNBQWMsQ0FBQyxNQUFNLENBQUM7aUJBQ3RCLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLGtFQUFrRSxDQUFDLENBQUM7WUFFOUYsTUFBTSxHQUFHO2dCQUNQLEtBQUssRUFBRSxLQUFLO2dCQUNaLFFBQVEsRUFBRSxHQUFHO2dCQUNiLE9BQU8sRUFBRTtvQkFDUCxZQUFZLEVBQUUsSUFBSTtvQkFDbEIsb0JBQW9CLEVBQUUsR0FBRztpQkFDMUI7YUFDRixDQUFDO1lBRUYsTUFBTSxPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLDhDQUE4QyxDQUFDLENBQUM7WUFFNUcsTUFBTSxHQUFHO2dCQUNQLEtBQUssRUFBRSxLQUFLO2dCQUNaLE9BQU8sRUFBRTtvQkFDUCxZQUFZLEVBQUUsT0FBTztvQkFDckIsb0JBQW9CLEVBQUUsS0FBSztpQkFDNUI7YUFDRixDQUFDO1lBRUYsTUFBTSxPQUFPO2lCQUNWLGNBQWMsQ0FBQyxNQUFNLENBQUM7aUJBQ3RCLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLGdFQUFnRSxDQUFDLENBQUM7WUFFNUYsTUFBTSxHQUFHO2dCQUNQLEtBQUssRUFBRSxLQUFLO2dCQUNaLE9BQU8sRUFBRTtvQkFDUCxZQUFZLEVBQUUsSUFBSTtvQkFDbEIsb0JBQW9CLEVBQUUsTUFBTTtpQkFDN0I7YUFDRixDQUFDO1lBRUYsTUFBTSxPQUFPO2lCQUNWLGNBQWMsQ0FBQyxNQUFNLENBQUM7aUJBQ3RCLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHFFQUFxRSxDQUFDLENBQUM7WUFFakcsTUFBTSxHQUFHO2dCQUNQLEtBQUssRUFBRSxLQUFLO2dCQUNaLGVBQWUsRUFBRSxRQUFRO2FBQzFCLENBQUM7WUFFRixNQUFNLE9BQU87aUJBQ1YsY0FBYyxDQUFDLE1BQU0sQ0FBQztpQkFDdEIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMscURBQXFELENBQUMsQ0FBQztZQUVqRixNQUFNLEdBQUc7Z0JBQ1AsS0FBSyxFQUFFLEtBQUs7Z0JBQ1osV0FBVyxFQUFFO29CQUNYLFNBQVMsRUFBRTt3QkFDVCxVQUFVLEVBQUU7NEJBQ1YsSUFBSSxFQUFFLFFBQVE7eUJBQ2Y7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDO1lBRUYsTUFBTSxPQUFPO2lCQUNWLGNBQWMsQ0FBQyxNQUFNLENBQUM7aUJBQ3RCLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUNyQiwwRkFBMEYsQ0FDM0YsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG9FQUFvRSxFQUFFLEtBQUs7WUFDNUUsTUFBTSxNQUFNLEdBQUc7Z0JBQ2IsS0FBSyxFQUFFLFdBQVc7Z0JBQ2xCLGVBQWUsRUFBRSxJQUFJO2dCQUNyQixrQkFBa0IsRUFBRSxNQUFNO2dCQUMxQixVQUFVLEVBQUUsU0FBUztnQkFDckIsT0FBTyxFQUFFLFNBQVM7YUFDbkIsQ0FBQztZQUVGLFlBQVk7WUFDWixJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNSLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7aUJBQ3hELEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUVkLFdBQVc7WUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNSLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDMUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWQsYUFBYTtZQUNiLElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ1IsSUFBSSxDQUNILGtCQUFrQixFQUNsQixDQUFDLENBQUMsT0FBTyxDQUFDO2dCQUNSLE1BQU0sRUFBRSxRQUFRO2dCQUNoQixRQUFRLEVBQUUsTUFBTSxDQUFDLGtCQUFrQjtnQkFDbkMsZUFBZSxFQUFFLElBQUk7YUFDdEIsQ0FBQyxDQUNIO2lCQUNBLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUVkLFNBQVM7WUFDVCxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRXZELE1BQU0sT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvRkFBb0YsRUFBRSxLQUFLO1lBQzVGLE1BQU0sTUFBTSxHQUFHO2dCQUNiLEtBQUssRUFBRSxXQUFXO2dCQUNsQixrQkFBa0IsRUFBRSxNQUFNO2dCQUMxQixVQUFVLEVBQUUsU0FBUztnQkFDckIsT0FBTyxFQUFFLFNBQVM7Z0JBQ2xCLFdBQVcsRUFBRSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFO2FBQzFFLENBQUM7WUFFRixZQUFZO1lBQ1osSUFBSSxDQUFDLEtBQUssQ0FBQztpQkFDUixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO2lCQUN4RCxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFZCxXQUFXO1lBQ1gsSUFBSSxDQUFDLEtBQUssQ0FBQztpQkFDUixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7aUJBQzFFLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUVkLGFBQWE7WUFDYixJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNSLElBQUksQ0FDSCxrQkFBa0IsRUFDbEIsQ0FBQyxDQUFDLE9BQU8sQ0FBQztnQkFDUixNQUFNLEVBQUUsUUFBUTtnQkFDaEIsUUFBUSxFQUFFLE1BQU0sQ0FBQyxrQkFBa0I7Z0JBQ25DLFdBQVcsRUFBRSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFO2FBQzFFLENBQUMsQ0FDSDtpQkFDQSxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFZCxTQUFTO1lBQ1QsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUV2RCxNQUFNLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMscURBQXFELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDbkUsTUFBTSxNQUFNLEdBQUc7Z0JBQ2IsS0FBSyxFQUFFLGdCQUFnQjtnQkFDdkIsVUFBVSxFQUFFLFNBQVM7Z0JBQ3JCLE9BQU8sRUFDTCxpSEFBaUg7Z0JBQ25ILGtCQUFrQixFQUFFLEtBQUs7YUFDMUIsQ0FBQztZQUVGLFlBQVk7WUFDWixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUM3QixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO2lCQUN4RCxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFZCxXQUFXO1lBQ1gsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztpQkFDNUIsSUFBSSxDQUNILGtCQUFrQixFQUNsQixDQUFDLENBQUMsT0FBTyxDQUFDO2dCQUNSLHlCQUF5QixFQUFFLE1BQU0sQ0FBQyxrQkFBa0I7YUFDckQsQ0FBQyxDQUNIO2lCQUNBLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUVkLGFBQWE7WUFDYixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUM5QixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO2lCQUN6RCxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFZCxTQUFTO1lBQ1QsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUUxRSxNQUFNLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDckMsS0FBSyxNQUFNLEtBQUssSUFBSSxDQUFDLFlBQVksRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUM7Z0JBQzNFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNmLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvRkFBb0YsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNsRyxNQUFNLE1BQU0sR0FBMEI7Z0JBQ3BDLEtBQUssRUFBRSxhQUFhO2dCQUNwQixVQUFVLEVBQUUsY0FBYztnQkFDMUIsSUFBSSxFQUFFLFdBQVc7YUFDbEIsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQzNCLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxVQUFVLElBQUk7Z0JBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDcEMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN6QixNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3pCLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDNUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUNyQyxPQUFPLElBQUksQ0FBQztZQUNkLENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUV4RixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbkYsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLFdBQVcsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUVwRixNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFdEQsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7WUFFckMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMseUJBQXlCLEtBQUssU0FBUyxDQUFDLENBQUM7WUFDNUQsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0NBQW9DLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDbEQsTUFBTSxNQUFNLEdBQTBCO2dCQUNwQyxLQUFLLEVBQUUsYUFBYTtnQkFDcEIsVUFBVSxFQUFFLG1CQUFtQjtnQkFDL0IsVUFBVSxFQUFFLFlBQVk7Z0JBQ3hCLHNCQUFzQixFQUFFLGdDQUFnQzthQUN6RCxDQUFDO1lBRUYsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztpQkFDM0IsSUFBSSxDQUFDLHlCQUF5QixFQUFFLFVBQVUsSUFBSTtnQkFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM5QixPQUFPLElBQUksQ0FBQztZQUNkLENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFZCxJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNSLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7aUJBQ3hELEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDL0QsSUFBSSxDQUFDLEtBQUssQ0FBQztpQkFDUixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO2lCQUN6RCxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7WUFFcEMsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRXRELFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBRXJDLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLHlCQUF5QixDQUFDLENBQUM7WUFDOUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0IsTUFBTSxDQUFDLEtBQUssQ0FDVixLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyx5QkFBeUIsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLHNCQUFzQixFQUFFLENBQUMsRUFDckcsTUFBTSxDQUFDLFVBQVUsQ0FDbEIsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGtFQUFrRSxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ2hGLE1BQU0sTUFBTSxHQUEwQjtnQkFDcEMsS0FBSyxFQUFFLGFBQWE7Z0JBQ3BCLFVBQVUsRUFBRSxtQkFBbUI7Z0JBQy9CLFVBQVUsRUFBRSxZQUFZO2dCQUN4QixzQkFBc0IsRUFBRSxnQ0FBZ0M7YUFDekQsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQzNCLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxVQUFVLElBQUk7Z0JBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDOUIsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWQsSUFBSSxDQUFDLEtBQUssQ0FBQztpQkFDUixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO2lCQUN4RCxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7WUFDbkMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQy9ELElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ1IsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztpQkFDekQsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBRXBDLE1BQU0saUJBQWlCLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUNqRSxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEQsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDckMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUMzQyxNQUFNLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxFQUFFLHdCQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDeEYsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMseUJBQXlCLENBQUMsQ0FBQztZQUM5QyxNQUFNLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMzQixNQUFNLENBQUMsS0FBSyxDQUNWLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDLHlCQUF5QixFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxFQUNyRyxNQUFNLENBQUMsVUFBVSxDQUNsQixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxzQkFBc0IsRUFBRTtRQUMvQixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUV0QyxVQUFVLENBQUM7WUFDVCxJQUFJLENBQUMsdUJBQXVCLENBQUM7aUJBQzFCLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQztpQkFDM0IsS0FBSyxDQUFDLENBQUMsQ0FBQztpQkFDUixLQUFLLENBQUMsR0FBRyxFQUFFO2dCQUNWLFlBQVksRUFBRTtvQkFDWixHQUFHLEVBQUU7d0JBQ0gsc0JBQXNCLEVBQUUsRUFBRTtxQkFDM0I7b0JBQ0QsR0FBRyxFQUFFO3dCQUNILHNCQUFzQixFQUFFLEVBQUU7cUJBQzNCO29CQUNELE9BQU8sRUFBRTt3QkFDUCxzQkFBc0IsRUFBRSxFQUFFO3FCQUMzQjtpQkFDRjthQUNGLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBQSxpQkFBUyxFQUFDO1lBQ1IsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ2hCLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLEtBQUs7WUFDeEMsTUFBTSx1QkFBdUIsR0FBcUI7Z0JBQ2hELFlBQVksRUFBRTtvQkFDWixFQUFFLEVBQUUsR0FBRztvQkFDUCxHQUFHLEVBQUUsU0FBUztvQkFDZCxJQUFJLEVBQUUsYUFBYTtvQkFDbkIsTUFBTSxFQUFFLE1BQU07aUJBQ2Y7Z0JBQ0QsY0FBYyxFQUFFO29CQUNkLEVBQUUsRUFBRSxHQUFHO29CQUNQLEdBQUcsRUFBRSxTQUFTO29CQUNkLElBQUksRUFBRSxhQUFhO29CQUNuQixNQUFNLEVBQUUsUUFBUTtpQkFDakI7Z0JBQ0QsYUFBYSxFQUFFO29CQUNiLEVBQUUsRUFBRSxHQUFHO29CQUNQLEdBQUcsRUFBRSxTQUFTO29CQUNkLElBQUksRUFBRSxhQUFhO29CQUNuQixNQUFNLEVBQUUsT0FBTztpQkFDaEI7YUFDRixDQUFDO1lBQ0YsT0FBTyxDQUFDLElBQUksQ0FBQyxtQkFBUSxDQUFDLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1lBRXRGLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUU1RixNQUFNLE9BQU8sR0FBRyxJQUFJLGtCQUFPLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRXpDLE1BQU0sTUFBTSxHQUFHO2dCQUNiLEtBQUssRUFBRSxZQUFZO2dCQUNuQixVQUFVLEVBQUUsY0FBYztnQkFDMUIsWUFBWSxFQUFFLEtBQVk7Z0JBQzFCLFVBQVUsRUFBRSxZQUFZO2dCQUN4QixzQkFBc0IsRUFBRSxnQ0FBZ0M7YUFDekQsQ0FBQztZQUVGLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUV0RCxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUVyQyxNQUFNLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1lBQzlDLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzNCLE1BQU0sQ0FBQyxLQUFLLENBQ1YsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMseUJBQXlCLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLEVBQ3JHLE1BQU0sQ0FBQyxVQUFVLENBQ2xCLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw4REFBOEQsRUFBRSxLQUFLO1lBQ3RFLE1BQU0sdUJBQXVCLEdBQXFCO2dCQUNoRCxZQUFZLEVBQUU7b0JBQ1osRUFBRSxFQUFFLEdBQUc7b0JBQ1AsR0FBRyxFQUFFLFNBQVM7b0JBQ2QsSUFBSSxFQUFFLGFBQWE7b0JBQ25CLE1BQU0sRUFBRSxNQUFNO2lCQUNmO2dCQUNELGNBQWMsRUFBRTtvQkFDZCxFQUFFLEVBQUUsR0FBRztvQkFDUCxHQUFHLEVBQUUsU0FBUztvQkFDZCxJQUFJLEVBQUUsYUFBYTtvQkFDbkIsTUFBTSxFQUFFLFFBQVE7aUJBQ2pCO2dCQUNELGFBQWEsRUFBRTtvQkFDYixFQUFFLEVBQUUsR0FBRztvQkFDUCxHQUFHLEVBQUUsU0FBUztvQkFDZCxJQUFJLEVBQUUsYUFBYTtvQkFDbkIsTUFBTSxFQUFFLE9BQU87aUJBQ2hCO2FBQ0YsQ0FBQztZQUNGLE9BQU8sQ0FBQyxJQUFJLENBQUMsbUJBQVEsQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxRQUFRLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUV0RixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUM7aUJBQzdDLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxVQUFVLElBQUk7Z0JBQzdDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx3QkFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNsRCxPQUFPLElBQUksQ0FBQztZQUNkLENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFZCxNQUFNLE9BQU8sR0FBRyxJQUFJLGtCQUFPLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRXpDLE1BQU0sTUFBTSxHQUFHO2dCQUNiLEtBQUssRUFBRSxZQUFZO2dCQUNuQixVQUFVLEVBQUUsY0FBYztnQkFDMUIsVUFBVSxFQUFFLFlBQVk7Z0JBQ3hCLHNCQUFzQixFQUFFLGdDQUFnQzthQUN6RCxDQUFDO1lBRUYsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2pFLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0RCxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNyQyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQzNDLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxZQUFZLEVBQUUsd0JBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNwRixNQUFNLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1lBQzlDLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzNCLE1BQU0sQ0FBQyxLQUFLLENBQ1YsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMseUJBQXlCLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLEVBQ3JHLE1BQU0sQ0FBQyxVQUFVLENBQ2xCLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5RUFBeUUsRUFBRSxLQUFLO1lBQ2pGLE1BQU0sdUJBQXVCLEdBQXFCO2dCQUNoRCxZQUFZLEVBQUU7b0JBQ1osRUFBRSxFQUFFLEdBQUc7b0JBQ1AsR0FBRyxFQUFFLFNBQVM7b0JBQ2QsSUFBSSxFQUFFLGFBQWE7b0JBQ25CLE1BQU0sRUFBRSxNQUFNO2lCQUNmO2dCQUNELGNBQWMsRUFBRTtvQkFDZCxFQUFFLEVBQUUsR0FBRztvQkFDUCxHQUFHLEVBQUUsU0FBUztvQkFDZCxJQUFJLEVBQUUsYUFBYTtvQkFDbkIsTUFBTSxFQUFFLFFBQVE7aUJBQ2pCO2dCQUNELGFBQWEsRUFBRTtvQkFDYixFQUFFLEVBQUUsR0FBRztvQkFDUCxHQUFHLEVBQUUsU0FBUztvQkFDZCxJQUFJLEVBQUUsYUFBYTtvQkFDbkIsTUFBTSxFQUFFLE9BQU87aUJBQ2hCO2FBQ0YsQ0FBQztZQUNGLE9BQU8sQ0FBQyxJQUFJLENBQUMsbUJBQVEsQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxRQUFRLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUV0RixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFNUYsTUFBTSxPQUFPLEdBQUcsSUFBSSxrQkFBTyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztZQUV6QyxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxjQUFjLENBQUM7Z0JBQzVDLEtBQUssRUFBRSxZQUFZO2dCQUNuQixVQUFVLEVBQUUsY0FBYztnQkFDMUIsWUFBWSxFQUFFLEtBQUs7Z0JBQ25CLFVBQVUsRUFBRSxZQUFZO2FBQ3pCLENBQUMsQ0FBQztZQUVILFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBRXJDLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzNCLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLHlCQUF5QixLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBQzlELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNEQUFzRCxFQUFFLEtBQUs7WUFDOUQsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNoQyxNQUFNLE1BQU0sR0FBRztnQkFDYixLQUFLLEVBQUUsZ0JBQWdCO2dCQUN2QixVQUFVLEVBQUUsU0FBUztnQkFDckIsT0FBTyxFQUNMLGlIQUFpSDtnQkFDbkgsa0JBQWtCLEVBQUUsS0FBSzthQUMxQixDQUFDO1lBQ0YsTUFBTSxPQUFPLEdBQUcsSUFBSSxrQkFBTyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztZQUV6QyxJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNSLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7aUJBQ3hELEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUVkLElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ1IsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSx5QkFBeUIsRUFBRSxNQUFNLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDO2lCQUM3RixLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDZCxJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNSLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7aUJBQ3pELEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUVkLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFdkQsbUdBQW1HO1lBQ25HLE1BQU0sT0FBTyxDQUFDLGNBQWMsQ0FBQyxFQUFFLEdBQUcsTUFBTSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBRWpFLE1BQU0sV0FBVyxHQUFHLElBQUksa0JBQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFFN0MsTUFBTSxXQUFXO2lCQUNkLGNBQWMsQ0FBQztnQkFDZCxLQUFLLEVBQUUsaUJBQWlCO2dCQUN4QixVQUFVLEVBQUUsWUFBWTtnQkFDeEIsT0FBTyxFQUFFLFVBQVU7Z0JBQ25CLFlBQVksRUFBRSxLQUFLO2FBQ3BCLENBQUM7aUJBQ0QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsdUNBQXVDLENBQUMsQ0FBQztZQUVuRSxNQUFNLFdBQVc7aUJBQ2QsY0FBYyxDQUFDO2dCQUNkLEtBQUssRUFBRSxpQkFBaUI7Z0JBQ3hCLE9BQU8sRUFBRSxVQUFVO2dCQUNuQixZQUFZLEVBQUUsS0FBSztnQkFDbkIsVUFBVSxFQUFFLGNBQWM7YUFDM0IsQ0FBQztpQkFDRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1FBQzNFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBDQUEwQyxFQUFFLEtBQUs7WUFDbEQsTUFBTSxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBRTdCLE1BQU0sWUFBWSxHQUEwQjtnQkFDMUMsS0FBSyxFQUFFLFlBQVk7Z0JBQ25CLFlBQVksRUFBRSxLQUFLO2dCQUNuQixVQUFVLEVBQUUsWUFBWTtnQkFDeEIsSUFBSSxFQUFFLFdBQVc7YUFDbEIsQ0FBQztZQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztpQkFDN0MsSUFBSSxDQUFDLHlCQUF5QixDQUFDO2lCQUMvQixLQUFLLENBQUMsQ0FBQyxDQUFDO2lCQUNSLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxHQUFHLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBRXpDLE1BQU0sT0FBTyxHQUFHLElBQUksa0JBQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFFekMsTUFBTSxHQUFHLEdBQUcsTUFBTSxPQUFPLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3ZELElBQUksQ0FBQyxJQUFBLGdDQUFxQixFQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2hDLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztZQUN2RCxDQUFDO1lBQ0QsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNwRCxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ25ELEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3JFLEdBQUcsQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDbEUsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMxQyxHQUFHLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVDLEdBQUcsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFM0MsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdkMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0NBQW9DLEVBQUUsS0FBSztZQUM1QyxNQUFNLGNBQWMsR0FBRyxZQUFZLENBQUM7WUFDcEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxHQUFxQjtnQkFDN0IsWUFBWSxFQUFFO29CQUNaLEVBQUUsRUFBRSxHQUFHO29CQUNQLGNBQWM7b0JBQ2QsSUFBSSxFQUFFLEtBQUs7b0JBQ1gseUJBQXlCLEVBQUUsSUFBSTtvQkFDL0IsTUFBTSxFQUFFLE1BQU07aUJBQ2Y7Z0JBQ0QsY0FBYyxFQUFFO29CQUNkLEVBQUUsRUFBRSxHQUFHO29CQUNQLGNBQWM7b0JBQ2QsSUFBSSxFQUFFLEtBQUs7b0JBQ1gseUJBQXlCLEVBQUUsSUFBSTtvQkFDL0IsTUFBTSxFQUFFLFFBQVE7aUJBQ2pCO2dCQUNELGFBQWEsRUFBRTtvQkFDYixFQUFFLEVBQUUsR0FBRztvQkFDUCxjQUFjO29CQUNkLElBQUksRUFBRSxLQUFLO29CQUNYLE1BQU0sRUFBRSxPQUFPO2lCQUNoQjthQUNGLENBQUM7WUFFRixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUM1RyxNQUFNLG1CQUFtQixHQUFHO2dCQUMxQixNQUFNLEVBQUUsTUFBTTtnQkFDZCxPQUFPLEVBQUUsS0FBSztnQkFDZCxjQUFjO2dCQUNkLHlCQUF5QixFQUFFLElBQUk7YUFDaEMsQ0FBQztZQUNGLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztpQkFDOUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLG1CQUFtQixDQUFDO2lCQUM3QyxLQUFLLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNqQyxNQUFNLHFCQUFxQixHQUFHO2dCQUM1QixNQUFNLEVBQUUsUUFBUTtnQkFDaEIsT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsY0FBYztnQkFDZCx5QkFBeUIsRUFBRSxJQUFJO2FBQ2hDLENBQUM7WUFDRixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUM7aUJBQ2hELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxxQkFBcUIsQ0FBQztpQkFDL0MsS0FBSyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7WUFFbkMsTUFBTSxZQUFZLEdBQTBCO2dCQUMxQyxLQUFLLEVBQUUsWUFBWTtnQkFDbkIsWUFBWSxFQUFFLEtBQUs7Z0JBQ25CLFVBQVUsRUFBRSxZQUFZO2dCQUN4QixJQUFJLEVBQUUsTUFBTTtnQkFDWixVQUFVLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFO2dCQUNqQyxjQUFjO2dCQUNkLGtCQUFrQixFQUFFLElBQUk7YUFDekIsQ0FBQztZQUVGLE1BQU0sa0JBQWtCLEdBQUc7Z0JBQ3pCLEtBQUssRUFBRSxZQUFZLENBQUMsS0FBSztnQkFDekIsQ0FBQyxFQUFFLENBQUM7Z0JBQ0osQ0FBQyxFQUFFLENBQUM7Z0JBQ0osSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7Z0JBQzNFLElBQUksRUFBRSxZQUFZLENBQUMsSUFBSTtnQkFDdkIsWUFBWSxFQUFFLFlBQVksQ0FBQyxZQUFZO2dCQUN2QyxVQUFVLEVBQUUsWUFBWSxDQUFDLFVBQVU7Z0JBQ25DLGFBQWEsRUFBRSxTQUFTO2FBQ3pCLENBQUM7WUFFRixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUM7aUJBQzdDLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxrQkFBa0IsQ0FBQztpQkFDbkQsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLEdBQUcsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLHFCQUFxQixFQUFFLENBQUMsQ0FBQztZQUU5RSxNQUFNLE9BQU8sR0FBRyxJQUFJLGtCQUFPLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRXpDLE1BQU0sR0FBRyxHQUFHLE1BQU0sT0FBTyxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUN2RCxJQUFJLENBQUMsSUFBQSxnQ0FBcUIsRUFBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNoQyxNQUFNLElBQUksS0FBSyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7WUFDdkQsQ0FBQztZQUNELEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1lBQ3JELEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuRCxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNyRSxHQUFHLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ2xFLEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDckQsR0FBRyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUN6RCxHQUFHLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBRXZELFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3ZDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3RDLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3hDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3ZDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGdGQUFnRixFQUFFLEtBQUs7WUFDeEYsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDO1lBQ3BDLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQztZQUNwQixNQUFNLElBQUksR0FBcUI7Z0JBQzdCLFlBQVksRUFBRTtvQkFDWixFQUFFLEVBQUUsR0FBRztvQkFDUCxjQUFjO29CQUNkLElBQUksRUFBRSxLQUFLO29CQUNYLHlCQUF5QixFQUFFLElBQUk7b0JBQy9CLE1BQU0sRUFBRSxNQUFNO2lCQUNmO2dCQUNELGNBQWMsRUFBRTtvQkFDZCxFQUFFLEVBQUUsR0FBRztvQkFDUCxjQUFjO29CQUNkLElBQUksRUFBRSxLQUFLO29CQUNYLHlCQUF5QixFQUFFLElBQUk7b0JBQy9CLE1BQU0sRUFBRSxRQUFRO2lCQUNqQjtnQkFDRCxhQUFhLEVBQUU7b0JBQ2IsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsY0FBYztvQkFDZCxJQUFJLEVBQUUsS0FBSztvQkFDWCxNQUFNLEVBQUUsT0FBTztpQkFDaEI7YUFDRixDQUFDO1lBRUYsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFFM0csTUFBTSxZQUFZLEdBQTBCO2dCQUMxQyxLQUFLLEVBQUUsWUFBWTtnQkFDbkIsWUFBWSxFQUFFLEtBQUs7Z0JBQ25CLFVBQVUsRUFBRSxZQUFZO2dCQUN4QixJQUFJLEVBQUUsTUFBTTtnQkFDWixVQUFVLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFO2dCQUNoQyxjQUFjO2dCQUNkLGtCQUFrQixFQUFFLElBQUk7YUFDekIsQ0FBQztZQUVGLE1BQU0sT0FBTyxHQUFHLElBQUksa0JBQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFFekMsTUFBTSxPQUFPO2lCQUNWLGNBQWMsQ0FBQyxZQUFZLENBQUM7aUJBQzVCLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLGlEQUFpRCxDQUFDLENBQUM7WUFFN0UsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDekMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyw0QkFBNEIsRUFBRSxLQUFLO1FBQzFDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUV0QyxVQUFVLENBQUM7WUFDVCxNQUFNLFdBQVcsR0FBZ0I7Z0JBQy9CLFlBQVksRUFBRTtvQkFDWixHQUFHLEVBQUU7d0JBQ0gsc0JBQXNCLEVBQUU7NEJBQ3RCLG1CQUFtQixFQUFFLE9BQU87NEJBQzVCLHVCQUF1QixFQUFFLE9BQU87NEJBQ2hDLDRCQUE0QixFQUFFLE9BQU87eUJBQ3RDO3FCQUNGO29CQUNELEdBQUcsRUFBRTt3QkFDSCxzQkFBc0IsRUFBRTs0QkFDdEIsbUJBQW1CLEVBQUUsT0FBTzs0QkFDNUIsdUJBQXVCLEVBQUUsT0FBTzs0QkFDaEMsNEJBQTRCLEVBQUUsT0FBTzt5QkFDdEM7cUJBQ0Y7b0JBQ0QsT0FBTyxFQUFFO3dCQUNQLHNCQUFzQixFQUFFOzRCQUN0QixtQkFBbUIsRUFBRSxPQUFPOzRCQUM1Qix1QkFBdUIsRUFBRSxPQUFPOzRCQUNoQyw0QkFBNEIsRUFBRSxPQUFPO3lCQUN0QztxQkFDRjtvQkFDRCxJQUFJLEVBQUU7d0JBQ0osc0JBQXNCLEVBQUU7NEJBQ3RCLG1CQUFtQixFQUFFLE9BQU87NEJBQzVCLHVCQUF1QixFQUFFLE9BQU87NEJBQ2hDLDRCQUE0QixFQUFFLE9BQU87eUJBQ3RDO3FCQUNGO29CQUNELEdBQUcsRUFBRTt3QkFDSCxzQkFBc0IsRUFBRTs0QkFDdEIsbUJBQW1CLEVBQUUsT0FBTzs0QkFDNUIsdUJBQXVCLEVBQUUsT0FBTzs0QkFDaEMsNEJBQTRCLEVBQUUsT0FBTzt5QkFDdEM7cUJBQ0Y7b0JBQ0QsSUFBSSxFQUFFO3dCQUNKLHNCQUFzQixFQUFFOzRCQUN0QixtQkFBbUIsRUFBRSxPQUFPOzRCQUM1Qix1QkFBdUIsRUFBRSxPQUFPOzRCQUNoQyw0QkFBNEIsRUFBRSxPQUFPO3lCQUN0QztxQkFDRjtvQkFDRCxNQUFNLEVBQUU7d0JBQ04sc0JBQXNCLEVBQUU7NEJBQ3RCLG1CQUFtQixFQUFFLE9BQU87NEJBQzVCLHVCQUF1QixFQUFFLE9BQU87NEJBQ2hDLDRCQUE0QixFQUFFLE9BQU87eUJBQ3RDO3FCQUNGO29CQUNELEtBQUssRUFBRTt3QkFDTCxzQkFBc0IsRUFBRTs0QkFDdEIsbUJBQW1CLEVBQUUsT0FBTzs0QkFDNUIsdUJBQXVCLEVBQUUsT0FBTzs0QkFDaEMsNEJBQTRCLEVBQUUsT0FBTzt5QkFDdEM7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDO1lBQ0YsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDN0YsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFBLGlCQUFTLEVBQUM7WUFDUixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDaEIsT0FBTyxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQUM7UUFFSCxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUM1RixFQUFFLENBQUMsdUJBQXVCLElBQUksdUJBQXVCLEVBQUUsS0FBSztnQkFDMUQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDbEMsTUFBTSx1QkFBdUIsR0FBcUI7b0JBQ2hELFlBQVksRUFBRTt3QkFDWixFQUFFLEVBQUUsR0FBRzt3QkFDUCxjQUFjLEVBQUUsU0FBUzt3QkFDekIsSUFBSSxFQUFFLEtBQUs7d0JBQ1gsTUFBTSxFQUFFLE1BQU07cUJBQ2Y7b0JBQ0QsY0FBYyxFQUFFO3dCQUNkLEVBQUUsRUFBRSxHQUFHO3dCQUNQLGNBQWMsRUFBRSxTQUFTO3dCQUN6QixJQUFJLEVBQUUsS0FBSzt3QkFDWCxNQUFNLEVBQUUsUUFBUTtxQkFDakI7b0JBQ0QsYUFBYSxFQUFFO3dCQUNiLEVBQUUsRUFBRSxHQUFHO3dCQUNQLGNBQWMsRUFBRSxTQUFTO3dCQUN6QixJQUFJLEVBQUUsS0FBSzt3QkFDWCxNQUFNLEVBQUUsT0FBTztxQkFDaEI7aUJBQ0YsQ0FBQztnQkFDRixNQUFNLG1CQUFtQixHQUFHLE9BQU87cUJBQ2hDLElBQUksQ0FBQyxxQkFBVSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLENBQUM7cUJBQzdELFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO2dCQUVyQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLGFBQWEsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFFL0YsTUFBTSxPQUFPLEdBQUcsSUFBSSxrQkFBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFFN0MsTUFBTSxNQUFNLEdBQUc7b0JBQ2IsS0FBSyxFQUFFLFlBQVk7b0JBQ25CLFVBQVUsRUFBRSxjQUFjO29CQUMxQixZQUFZLEVBQUUsS0FBYztvQkFDNUIsVUFBVSxFQUFFLFlBQVk7b0JBQ3hCLHNCQUFzQixFQUFFLGdDQUFnQztvQkFDeEQsYUFBYSxFQUFFLENBQUM7aUJBQ2pCLENBQUM7Z0JBRUYsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUV0RCxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDckMsbUJBQW1CLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBRWhELE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLHlCQUF5QixDQUFDLENBQUM7Z0JBQzlDLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUMzQixNQUFNLENBQUMsS0FBSyxDQUNWLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFDLHlCQUF5QixFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxFQUNyRyxNQUFNLENBQUMsVUFBVSxDQUNsQixDQUFDO1lBQ0osQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsdUJBQXVCLElBQUkscURBQXFELEVBQUUsS0FBSztnQkFDeEYsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDbEMsTUFBTSx1QkFBdUIsR0FBcUI7b0JBQ2hELFlBQVksRUFBRTt3QkFDWixFQUFFLEVBQUUsR0FBRzt3QkFDUCxjQUFjLEVBQUUsU0FBUzt3QkFDekIsSUFBSSxFQUFFLEtBQUs7d0JBQ1gsTUFBTSxFQUFFLE1BQU07cUJBQ2Y7b0JBQ0QsY0FBYyxFQUFFO3dCQUNkLEVBQUUsRUFBRSxHQUFHO3dCQUNQLGNBQWMsRUFBRSxTQUFTO3dCQUN6QixJQUFJLEVBQUUsS0FBSzt3QkFDWCxNQUFNLEVBQUUsUUFBUTtxQkFDakI7b0JBQ0QsYUFBYSxFQUFFO3dCQUNiLEVBQUUsRUFBRSxHQUFHO3dCQUNQLGNBQWMsRUFBRSxTQUFTO3dCQUN6QixJQUFJLEVBQUUsS0FBSzt3QkFDWCxNQUFNLEVBQUUsT0FBTztxQkFDaEI7aUJBQ0YsQ0FBQztnQkFDRixNQUFNLG1CQUFtQixHQUFHLE9BQU87cUJBQ2hDLElBQUksQ0FBQyxxQkFBVSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLENBQUM7cUJBQzdELFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO2dCQUVyQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUM7cUJBQzdDLElBQUksQ0FBQyxXQUFXLElBQUksYUFBYSxFQUFFLFVBQVUsSUFBSTtvQkFDaEQsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHdCQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ2xELE9BQU8sSUFBSSxDQUFDO2dCQUNkLENBQUMsQ0FBQztxQkFDRCxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBRWQsTUFBTSxPQUFPLEdBQUcsSUFBSSxrQkFBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFFN0MsTUFBTSxNQUFNLEdBQUc7b0JBQ2IsS0FBSyxFQUFFLFlBQVk7b0JBQ25CLFVBQVUsRUFBRSxjQUFjO29CQUMxQixVQUFVLEVBQUUsWUFBWTtvQkFDeEIsc0JBQXNCLEVBQUUsZ0NBQWdDO29CQUN4RCxhQUFhLEVBQUUsQ0FBQztpQkFDakIsQ0FBQztnQkFFRixNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBRXRELFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNyQyxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFFaEQsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMseUJBQXlCLENBQUMsQ0FBQztnQkFDOUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzNCLE1BQU0sQ0FBQyxLQUFLLENBQ1YsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMseUJBQXlCLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLEVBQ3JHLE1BQU0sQ0FBQyxVQUFVLENBQ2xCLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyx1QkFBdUIsSUFBSSx3QkFBd0IsRUFBRSxLQUFLO2dCQUMzRCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNsQyxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUM7Z0JBQzVCLE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQztnQkFFL0IsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDO3FCQUMvQyxHQUFHLENBQUMsV0FBVyxJQUFJLFFBQVEsVUFBVSxFQUFFLENBQUM7cUJBQ3hDLEtBQUssQ0FBQyxDQUFDLENBQUM7cUJBQ1IsS0FBSyxDQUFDLEdBQUcsRUFBRTtvQkFDVixFQUFFLEVBQUUsUUFBUTtvQkFDWixHQUFHLEVBQUUsVUFBVTtvQkFDZixJQUFJLEVBQUUsS0FBSztvQkFDWCxNQUFNLEVBQUUsT0FBTztvQkFDZixjQUFjO2lCQUNmLENBQUMsQ0FBQztnQkFFTCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUM7cUJBQzlDLElBQUksQ0FBQyxXQUFXLElBQUksTUFBTSxFQUFFO29CQUMzQixNQUFNLEVBQUUsTUFBTTtvQkFDZCxPQUFPLEVBQUUsS0FBSztvQkFDZCxjQUFjO29CQUNkLHlCQUF5QixFQUFFLElBQUk7b0JBQy9CLE9BQU8sRUFBRSxJQUFJO2lCQUNkLENBQUM7cUJBQ0QsS0FBSyxDQUFDLENBQUMsQ0FBQztxQkFDUixLQUFLLENBQUMsR0FBRyxFQUFFO29CQUNWLEVBQUUsRUFBRSxZQUFZO29CQUNoQixHQUFHLEVBQUUsU0FBUztvQkFDZCxJQUFJLEVBQUUsS0FBSztvQkFDWCxNQUFNLEVBQUUsTUFBTTtpQkFDZixDQUFDLENBQUM7Z0JBRUwsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDO3FCQUNoRCxJQUFJLENBQUMsV0FBVyxJQUFJLE1BQU0sRUFBRTtvQkFDM0IsTUFBTSxFQUFFLFFBQVE7b0JBQ2hCLE9BQU8sRUFBRSxLQUFLO29CQUNkLGNBQWM7b0JBQ2QseUJBQXlCLEVBQUUsSUFBSTtvQkFDL0IsT0FBTyxFQUFFLElBQUk7aUJBQ2QsQ0FBQztxQkFDRCxLQUFLLENBQUMsQ0FBQyxDQUFDO3FCQUNSLEtBQUssQ0FBQyxHQUFHLEVBQUU7b0JBQ1YsRUFBRSxFQUFFLGNBQWM7b0JBQ2xCLEdBQUcsRUFBRSxXQUFXO29CQUNoQixJQUFJLEVBQUUsS0FBSztvQkFDWCxNQUFNLEVBQUUsUUFBUTtpQkFDakIsQ0FBQyxDQUFDO2dCQUVMLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztxQkFDN0MsSUFBSSxDQUFDLFdBQVcsSUFBSSxhQUFhLEVBQUU7b0JBQ2xDLEtBQUssRUFBRSxZQUFZO29CQUNuQixDQUFDLEVBQUUsQ0FBQztvQkFDSixDQUFDLEVBQUUsQ0FBQztvQkFDSixJQUFJLEVBQUUsQ0FBQyxZQUFZLEVBQUUsY0FBYyxFQUFFLFFBQVEsQ0FBQztvQkFDOUMsSUFBSSxFQUFFLE1BQU07b0JBQ1osWUFBWSxFQUFFLEtBQUs7b0JBQ25CLFVBQVUsRUFBRSxZQUFZO29CQUN4QixhQUFhLEVBQUUsQ0FBQztpQkFDakIsQ0FBQztxQkFDRCxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBRWQsTUFBTSxPQUFPLEdBQUcsSUFBSSxrQkFBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFFN0MsTUFBTSxNQUFNLEdBQTBCO29CQUNwQyxLQUFLLEVBQUUsWUFBWTtvQkFDbkIsWUFBWSxFQUFFLEtBQWM7b0JBQzVCLFVBQVUsRUFBRSxZQUFZO29CQUN4QixzQkFBc0IsRUFBRSxnQ0FBZ0M7b0JBQ3hELGFBQWEsRUFBRSxDQUFDO29CQUNoQixJQUFJLEVBQUUsTUFBTTtvQkFDWixVQUFVLEVBQUUsUUFBUTtvQkFDcEIsY0FBYyxFQUFFLE9BQU87b0JBQ3ZCLGtCQUFrQixFQUFFLElBQUk7aUJBQ3pCLENBQUM7Z0JBRUYsTUFBTSxRQUFRLEdBQUcsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQXdCLENBQUM7Z0JBRS9FLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN2QyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDdEMsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3hDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUVyQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDOUIsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQ3BDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUN0QyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDckMsUUFBUSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7Z0JBQzFELFFBQVEsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQ3BELFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQ3hELFFBQVEsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDbkQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsdUJBQXVCLElBQUksMkJBQTJCLEVBQUUsS0FBSztnQkFDOUQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDbEMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxTQUFTLEVBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUVsRCxNQUFNLE1BQU0sR0FBMEI7b0JBQ3BDLEtBQUssRUFBRSxZQUFZO29CQUNuQixVQUFVLEVBQUUsY0FBYztvQkFDMUIsWUFBWSxFQUFFLEtBQWM7b0JBQzVCLFVBQVUsRUFBRSxZQUFZO29CQUN4QixzQkFBc0IsRUFBRSxnQ0FBZ0M7b0JBQ3hELGFBQWEsRUFBRSxDQUFDO29CQUNoQixJQUFJLEVBQUUsV0FBVztpQkFDbEIsQ0FBQztnQkFFRixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUM7cUJBQzdDLElBQUksQ0FBQyxXQUFXLElBQUksYUFBYSxDQUFDO3FCQUNsQyxLQUFLLENBQUMsQ0FBQyxDQUFDO3FCQUNSLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxHQUFHLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUVuQyxNQUFNLE9BQU8sR0FBRyxJQUFJLGtCQUFPLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUU3QyxNQUFNLFFBQVEsR0FBRyxDQUFDLE1BQU0sT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBd0IsQ0FBQztnQkFFL0UsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3JDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDcEMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQ3RDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUNyQyxRQUFRLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztnQkFDMUQsUUFBUSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDL0MsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDakQsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsRCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlFQUFpRSxFQUFFLEtBQUs7WUFDekUsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyQyxNQUFNLHVCQUF1QixHQUFxQjtnQkFDaEQsWUFBWSxFQUFFO29CQUNaLEVBQUUsRUFBRSxHQUFHO29CQUNQLGNBQWMsRUFBRSxTQUFTO29CQUN6QixJQUFJLEVBQUUsS0FBSztvQkFDWCxNQUFNLEVBQUUsTUFBTTtpQkFDZjtnQkFDRCxjQUFjLEVBQUU7b0JBQ2QsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsY0FBYyxFQUFFLFNBQVM7b0JBQ3pCLElBQUksRUFBRSxLQUFLO29CQUNYLE1BQU0sRUFBRSxRQUFRO2lCQUNqQjtnQkFDRCxhQUFhLEVBQUU7b0JBQ2IsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsY0FBYyxFQUFFLFNBQVM7b0JBQ3pCLElBQUksRUFBRSxLQUFLO29CQUNYLE1BQU0sRUFBRSxPQUFPO2lCQUNoQjthQUNGLENBQUM7WUFDRixNQUFNLG1CQUFtQixHQUFHLE9BQU87aUJBQ2hDLElBQUksQ0FBQyxxQkFBVSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLENBQUM7aUJBQzdELFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1lBRXJDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztpQkFDN0MsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUU7Z0JBQ3pDLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbkMsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWQsTUFBTSxPQUFPLEdBQUcsSUFBSSxrQkFBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztZQUU3QyxNQUFNLE1BQU0sR0FBRztnQkFDYixLQUFLLEVBQUUsWUFBWTtnQkFDbkIsVUFBVSxFQUFFLGNBQWM7Z0JBQzFCLFlBQVksRUFBRSxLQUFjO2dCQUM1QixVQUFVLEVBQUUsWUFBWTtnQkFDeEIsc0JBQXNCLEVBQUUsZ0NBQWdDO2dCQUN4RCxhQUFhLEVBQUUsQ0FBQzthQUNqQixDQUFDO1lBRUYsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRXRELFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3JDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBRWhELE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLHlCQUF5QixDQUFDLENBQUM7WUFDOUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0IsTUFBTSxDQUFDLEtBQUssQ0FDVixLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyx5QkFBeUIsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLHNCQUFzQixFQUFFLENBQUMsRUFDckcsTUFBTSxDQUFDLFVBQVUsQ0FDbEIsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHVGQUF1RixFQUFFLEtBQUs7WUFDL0YsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyQyxNQUFNLHVCQUF1QixHQUFxQjtnQkFDaEQsWUFBWSxFQUFFO29CQUNaLEVBQUUsRUFBRSxHQUFHO29CQUNQLGNBQWMsRUFBRSxTQUFTO29CQUN6QixJQUFJLEVBQUUsS0FBSztvQkFDWCxNQUFNLEVBQUUsTUFBTTtpQkFDZjtnQkFDRCxjQUFjLEVBQUU7b0JBQ2QsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsY0FBYyxFQUFFLFNBQVM7b0JBQ3pCLElBQUksRUFBRSxLQUFLO29CQUNYLE1BQU0sRUFBRSxRQUFRO2lCQUNqQjtnQkFDRCxhQUFhLEVBQUU7b0JBQ2IsRUFBRSxFQUFFLEdBQUc7b0JBQ1AsY0FBYyxFQUFFLFNBQVM7b0JBQ3pCLElBQUksRUFBRSxLQUFLO29CQUNYLE1BQU0sRUFBRSxPQUFPO2lCQUNoQjthQUNGLENBQUM7WUFDRixNQUFNLG1CQUFtQixHQUFHLE9BQU87aUJBQ2hDLElBQUksQ0FBQyxxQkFBVSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLENBQUM7aUJBQzdELFFBQVEsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1lBRXJDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztpQkFDN0MsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUU7Z0JBQ3pDLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbkMsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRWQsTUFBTSxPQUFPLEdBQUcsSUFBSSxrQkFBTyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztZQUU3QyxNQUFNLE1BQU0sR0FBRztnQkFDYixLQUFLLEVBQUUsWUFBWTtnQkFDbkIsVUFBVSxFQUFFLGNBQWM7Z0JBQzFCLFlBQVksRUFBRSxLQUFjO2dCQUM1QixVQUFVLEVBQUUsWUFBWTtnQkFDeEIsc0JBQXNCLEVBQUUsZ0NBQWdDO2dCQUN4RCxhQUFhLEVBQUUsQ0FBQzthQUNqQixDQUFDO1lBRUYsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRXRELFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3JDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBRWhELE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLHlCQUF5QixDQUFDLENBQUM7WUFDOUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0IsTUFBTSxDQUFDLEtBQUssQ0FDVixLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyx5QkFBeUIsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLHNCQUFzQixFQUFFLENBQUMsRUFDckcsTUFBTSxDQUFDLFVBQVUsQ0FDbEIsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRTtRQUN2QixRQUFRLENBQUMseURBQXlELEVBQUUsR0FBRyxFQUFFO1lBQ3ZFLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUV0QyxJQUFBLGlCQUFTLEVBQUM7Z0JBQ1IsT0FBTyxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDN0IsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsK0RBQStELEVBQUUsS0FBSztnQkFDdkUsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDO2dCQUU5QixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3FCQUNoQyxHQUFHLENBQUMsNEJBQTRCLE9BQU8sRUFBRSxDQUFDO3FCQUMxQyxLQUFLLENBQUMsR0FBRyxFQUFFO29CQUNWLHdCQUF3QixFQUFFLElBQUk7b0JBQzlCLFdBQVcsRUFBRSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDO2lCQUN4QyxDQUFDLENBQUM7Z0JBRUwsNkJBQTZCO2dCQUM3QixNQUFNLE9BQU87cUJBQ1YsV0FBVyxDQUFDLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxDQUFDO3FCQUN2QyxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQywyREFBMkQsQ0FBQyxDQUFDO2dCQUN2RixlQUFlLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDekIsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsK0VBQStFLEVBQUUsS0FBSztnQkFDdkYsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDO2dCQUM5QixNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUM7Z0JBQ2pDLE1BQU0sWUFBWSxHQUFHLGFBQWEsQ0FBQztnQkFDbkMsb0JBQW9CO2dCQUNwQixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3FCQUM3QixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7cUJBQzFFLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsV0FBVyxFQUFFLEVBQUU7b0JBQy9CLE9BQU8sRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxXQUFXLENBQUMsY0FBYyxDQUFDLEVBQUUsR0FBRyxFQUFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNoRyxDQUFDLENBQUMsQ0FBQztnQkFFTCxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7cUJBQ3BDLEdBQUcsQ0FBQyw0QkFBNEIsT0FBTyxFQUFFLENBQUM7cUJBQzFDLEtBQUssQ0FBQyxHQUFHLEVBQUU7b0JBQ1Ysd0JBQXdCLEVBQUUsSUFBSTtvQkFDOUIsV0FBVyxFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUM7aUJBQ3hDLENBQUMsQ0FBQztnQkFFTCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3FCQUNoQyxJQUFJLENBQUMsNEJBQTRCLE9BQU8sRUFBRSxFQUFFLENBQUMsSUFBUyxFQUFFLEVBQUU7b0JBQ3pELElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxPQUFPLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxVQUFVLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxVQUFVLEVBQUUsQ0FBQzt3QkFDN0YsT0FBTyxLQUFLLENBQUM7b0JBQ2YsQ0FBQztvQkFDRCxPQUFPLElBQUksQ0FBQztnQkFDZCxDQUFDLENBQUM7cUJBQ0QsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO2dCQUVsQyxrQ0FBa0M7Z0JBQ2xDLE1BQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUJBQU0sQ0FBQyxTQUFTLEVBQUUsYUFBYSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFFcEcsTUFBTSxHQUFHLEdBQUcsTUFBTSxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ2pDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDcEIsbUJBQW1CLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQzNCLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDdkIsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzlDLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLDJFQUEyRSxFQUFFLEtBQUs7Z0JBQ25GLE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQztnQkFDOUIsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDO2dCQUNqQyxNQUFNLFlBQVksR0FBRyxhQUFhLENBQUM7Z0JBRW5DLG9CQUFvQjtnQkFDcEIsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztxQkFDN0IsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO3FCQUMxRSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLFdBQVcsRUFBRSxFQUFFO29CQUMvQixPQUFPLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsV0FBVyxDQUFDLGNBQWMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxXQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDaEcsQ0FBQyxDQUFDLENBQUM7Z0JBRUwsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3FCQUNwQyxHQUFHLENBQUMsNEJBQTRCLE9BQU8sRUFBRSxDQUFDO3FCQUMxQyxLQUFLLENBQUMsR0FBRyxFQUFFO29CQUNWLHdCQUF3QixFQUFFLElBQUk7b0JBQzlCLFdBQVcsRUFBRSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDO2lCQUN4QyxDQUFDLENBQUM7Z0JBRUwsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztxQkFDaEMsSUFBSSxDQUFDLDRCQUE0QixPQUFPLEVBQUUsRUFBRSxDQUFDLElBQVMsRUFBRSxFQUFFO29CQUN6RCxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssVUFBVSxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssVUFBVSxFQUFFLENBQUM7d0JBQzdGLE9BQU8sS0FBSyxDQUFDO29CQUNmLENBQUM7b0JBQ0QsT0FBTyxJQUFJLENBQUM7Z0JBQ2QsQ0FBQyxDQUFDO3FCQUNELEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO2dCQUV4RCxrQ0FBa0M7Z0JBQ2xDLE1BQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUJBQU0sQ0FBQyxTQUFTLEVBQUUsYUFBYSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFFcEcsTUFBTSxHQUFHLEdBQUcsTUFBTSxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ2hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxjQUFjLENBQUMsQ0FBQztnQkFDeEMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNwQixtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDM0IsZUFBZSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN2QixNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDOUMsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMscUdBQXFHLEVBQUUsS0FBSztnQkFDN0csTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDO2dCQUM5QixNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUM7Z0JBQ2pDLE1BQU0sY0FBYyxHQUFHO29CQUNyQixPQUFPLEVBQUU7d0JBQ1AsV0FBVyxFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQzt3QkFDOUIsSUFBSSxFQUFFLGFBQWE7cUJBQ3BCO29CQUNELEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUU7b0JBQy9CLEVBQUUsRUFBRSxhQUFhO29CQUNqQixJQUFJLEVBQUUsS0FBSztpQkFDWixDQUFDO2dCQUNGLE1BQU0sY0FBYyxHQUFHO29CQUNyQixPQUFPLEVBQUU7d0JBQ1AsV0FBVyxFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQzt3QkFDOUIsSUFBSSxFQUFFLGFBQWE7cUJBQ3BCO29CQUNELEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUU7b0JBQy9CLEVBQUUsRUFBRSxhQUFhO29CQUNqQixJQUFJLEVBQUUsS0FBSztpQkFDWixDQUFDO2dCQUNGLE1BQU0sU0FBUyxHQUFHO29CQUNoQixPQUFPLEVBQUU7d0JBQ1AsV0FBVyxFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUM7d0JBQ3ZDLElBQUksRUFBRSxhQUFhO3FCQUNwQjtvQkFDRCxLQUFLLEVBQUUsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFO29CQUMvQixFQUFFLEVBQUUsYUFBYTtvQkFDakIsSUFBSSxFQUFFLEtBQUs7aUJBQ1osQ0FBQztnQkFDRixNQUFNLFVBQVUsR0FBRztvQkFDakIsT0FBTyxFQUFFO3dCQUNQLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQzt3QkFDckIsSUFBSSxFQUFFLGFBQWE7cUJBQ3BCO29CQUNELEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUU7b0JBQy9CLEVBQUUsRUFBRSxhQUFhO29CQUNqQixJQUFJLEVBQUUsS0FBSztpQkFDWixDQUFDO2dCQUNGLE1BQU0sWUFBWSxHQUFHLGFBQWEsQ0FBQztnQkFDbkMsTUFBTSxRQUFRLEdBQUcsYUFBYSxDQUFDO2dCQUMvQixNQUFNLFlBQVksR0FBRyxhQUFhLENBQUM7Z0JBRW5DLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7cUJBQ2hDLEdBQUcsQ0FBQyw0QkFBNEIsT0FBTyxFQUFFLENBQUM7cUJBQzFDLEtBQUssQ0FBQyxHQUFHLEVBQUU7b0JBQ1Ysd0JBQXdCLEVBQUUsSUFBSTtvQkFDOUIsV0FBVyxFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUM7b0JBQ3ZDLE1BQU0sRUFBRSxRQUFRO2lCQUNqQixDQUFDLENBQUM7Z0JBRUwsb0JBQW9CO2dCQUNwQixNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7cUJBQ25DLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztxQkFDMUUsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxXQUFXLEVBQUUsRUFBRTtvQkFDL0IsT0FBTyxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFdBQVcsQ0FBQyxjQUFjLENBQUMsRUFBRSxHQUFHLEVBQUUsV0FBVyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ2hHLENBQUMsQ0FBQyxDQUFDO2dCQUVMLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7cUJBQ2hDLElBQUksQ0FBQyw0QkFBNEIsT0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFTLEVBQUUsRUFBRTtvQkFDekQsSUFBSSxJQUFJLENBQUMsYUFBYSxLQUFLLE9BQU8sSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLFVBQVUsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLFVBQVUsRUFBRSxDQUFDO3dCQUM3RixPQUFPLEtBQUssQ0FBQztvQkFDZixDQUFDO29CQUNELE9BQU8sSUFBSSxDQUFDO2dCQUNkLENBQUMsQ0FBQztxQkFDRCxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztnQkFFcEQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztxQkFDL0IsR0FBRyxDQUFDLHVCQUF1QixRQUFRLEVBQUUsQ0FBQztxQkFDdEMsS0FBSyxDQUFDLEdBQUcsRUFBRTtvQkFDVixLQUFLLEVBQUUsQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsT0FBTyxDQUFDO29CQUM5RixVQUFVLEVBQUUsWUFBWTtvQkFDeEIsSUFBSSxFQUFFLGNBQWMsQ0FBQyxJQUFJO29CQUN6QixFQUFFLEVBQUUsUUFBUTtvQkFDWixJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7aUJBQ1gsQ0FBQyxDQUFDO2dCQUVMLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztxQkFDbkMsR0FBRyxDQUFDLHNCQUFzQixZQUFZLE9BQU8sQ0FBQztxQkFDOUMsS0FBSyxDQUFDLEdBQUcsRUFBRTtvQkFDVixVQUFVLEVBQUU7d0JBQ1YsRUFBRSxFQUFFLEVBQUUsY0FBYyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsY0FBYyxDQUFDLEtBQUssRUFBRTt3QkFDdEQsRUFBRSxFQUFFLEVBQUUsY0FBYyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsY0FBYyxDQUFDLEtBQUssRUFBRTt3QkFDdEQsRUFBRSxFQUFFLEVBQUUsU0FBUyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUssRUFBRTt3QkFDNUMsRUFBRSxFQUFFLEVBQUUsVUFBVSxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUssRUFBRTtxQkFDL0M7b0JBQ0QsYUFBYSxFQUFFLEVBQUU7aUJBQ2xCLENBQUMsQ0FBQztnQkFFTCxNQUFNLGVBQWUsR0FBRyxPQUFPO3FCQUM1QixJQUFJLENBQUMsaUJBQU0sQ0FBQyxTQUFTLEVBQUUsYUFBYSxDQUFDO3FCQUNyQyxPQUFPLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFN0YsTUFBTSxjQUFjLEdBQUc7b0JBQ3JCLFFBQVEsRUFBRSxRQUFRO29CQUNsQixJQUFJLEVBQUUsY0FBYyxDQUFDLEVBQUU7b0JBQ3ZCLFdBQVcsRUFBRSxjQUFjLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO29CQUN6RCxnQkFBZ0IsRUFBRSxZQUFZO29CQUM5QixLQUFLLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxLQUFLO29CQUNqQyxPQUFPLEVBQUUsSUFBSTtvQkFDYixZQUFZLEVBQUUsS0FBSztpQkFDcEIsQ0FBQztnQkFFRixNQUFNLGNBQWMsR0FBRztvQkFDckIsUUFBUSxFQUFFLFFBQVE7b0JBQ2xCLElBQUksRUFBRSxjQUFjLENBQUMsRUFBRTtvQkFDdkIsV0FBVyxFQUFFLGNBQWMsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7b0JBQ3pELGdCQUFnQixFQUFFLFlBQVk7b0JBQzlCLEtBQUssRUFBRSxjQUFjLENBQUMsS0FBSyxDQUFDLEtBQUs7b0JBQ2pDLE9BQU8sRUFBRSxJQUFJO29CQUNiLFlBQVksRUFBRSxLQUFLO2lCQUNwQixDQUFDO2dCQUVGLE1BQU0sR0FBRyxHQUFHLE1BQU0sT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztnQkFDaEYsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNoQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUM7Z0JBQ3BDLGtCQUFrQixDQUFDLElBQUksRUFBRSxDQUFDO2dCQUMxQixlQUFlLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3ZCLGNBQWMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDdEIsZUFBZSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN2QixrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDMUIsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUMvQyxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQy9ELE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsRSxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQywwRkFBMEYsRUFBRSxLQUFLO2dCQUNsRyxNQUFNLE9BQU8sR0FBRyxhQUFhLENBQUM7Z0JBQzlCLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQztnQkFDakMsTUFBTSxjQUFjLEdBQUc7b0JBQ3JCLE9BQU8sRUFBRTt3QkFDUCxXQUFXLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDO3dCQUM5QixJQUFJLEVBQUUsYUFBYTtxQkFDcEI7b0JBQ0QsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRTtvQkFDL0IsRUFBRSxFQUFFLGFBQWE7b0JBQ2pCLElBQUksRUFBRSxLQUFLO2lCQUNaLENBQUM7Z0JBQ0YsTUFBTSxjQUFjLEdBQUc7b0JBQ3JCLE9BQU8sRUFBRTt3QkFDUCxXQUFXLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDO3dCQUM5QixJQUFJLEVBQUUsYUFBYTtxQkFDcEI7b0JBQ0QsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRTtvQkFDL0IsRUFBRSxFQUFFLGFBQWE7b0JBQ2pCLElBQUksRUFBRSxLQUFLO2lCQUNaLENBQUM7Z0JBQ0YsTUFBTSxTQUFTLEdBQUc7b0JBQ2hCLE9BQU8sRUFBRTt3QkFDUCxXQUFXLEVBQUUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQzt3QkFDdkMsSUFBSSxFQUFFLGFBQWE7cUJBQ3BCO29CQUNELEtBQUssRUFBRSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUU7b0JBQy9CLEVBQUUsRUFBRSxhQUFhO29CQUNqQixJQUFJLEVBQUUsS0FBSztpQkFDWixDQUFDO2dCQUNGLE1BQU0sVUFBVSxHQUFHO29CQUNqQixPQUFPLEVBQUU7d0JBQ1AsV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDO3dCQUNyQixJQUFJLEVBQUUsYUFBYTtxQkFDcEI7b0JBQ0QsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRTtvQkFDL0IsRUFBRSxFQUFFLGFBQWE7b0JBQ2pCLElBQUksRUFBRSxLQUFLO2lCQUNaLENBQUM7Z0JBQ0YsTUFBTSxZQUFZLEdBQUcsYUFBYSxDQUFDO2dCQUNuQyxNQUFNLFFBQVEsR0FBRyxhQUFhLENBQUM7Z0JBQy9CLE1BQU0sWUFBWSxHQUFHLGFBQWEsQ0FBQztnQkFFbkMsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztxQkFDaEMsR0FBRyxDQUFDLDRCQUE0QixPQUFPLEVBQUUsQ0FBQztxQkFDMUMsS0FBSyxDQUFDLEdBQUcsRUFBRTtvQkFDVix3QkFBd0IsRUFBRSxJQUFJO29CQUM5QixXQUFXLEVBQUUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQztvQkFDdkMsTUFBTSxFQUFFLFFBQVE7aUJBQ2pCLENBQUMsQ0FBQztnQkFFTCxvQkFBb0I7Z0JBQ3BCLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztxQkFDbkMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO3FCQUMxRSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLFdBQVcsRUFBRSxFQUFFO29CQUMvQixPQUFPLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsV0FBVyxDQUFDLGNBQWMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxXQUFXLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDaEcsQ0FBQyxDQUFDLENBQUM7Z0JBRUwsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztxQkFDaEMsSUFBSSxDQUFDLDRCQUE0QixPQUFPLEVBQUUsRUFBRSxDQUFDLElBQVMsRUFBRSxFQUFFO29CQUN6RCxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssT0FBTyxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssVUFBVSxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssVUFBVSxFQUFFLENBQUM7d0JBQzdGLE9BQU8sS0FBSyxDQUFDO29CQUNmLENBQUM7b0JBQ0QsT0FBTyxJQUFJLENBQUM7Z0JBQ2QsQ0FBQyxDQUFDO3FCQUNELEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDO2dCQUVwRCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3FCQUMvQixHQUFHLENBQUMsdUJBQXVCLFFBQVEsRUFBRSxDQUFDO3FCQUN0QyxLQUFLLENBQUMsR0FBRyxFQUFFO29CQUNWLEtBQUssRUFBRSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsY0FBYyxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUM7b0JBQzlGLFVBQVUsRUFBRSxZQUFZO29CQUN4QixJQUFJLEVBQUUsY0FBYyxDQUFDLElBQUk7b0JBQ3pCLEVBQUUsRUFBRSxRQUFRO29CQUNaLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztpQkFDWCxDQUFDLENBQUM7Z0JBRUwsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3FCQUNuQyxHQUFHLENBQUMsc0JBQXNCLFlBQVksT0FBTyxDQUFDO3FCQUM5QyxLQUFLLENBQUMsR0FBRyxFQUFFO29CQUNWLFVBQVUsRUFBRTt3QkFDVixFQUFFLEVBQUUsRUFBRSxjQUFjLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxjQUFjLENBQUMsS0FBSyxFQUFFO3dCQUN0RCxFQUFFLEVBQUUsRUFBRSxjQUFjLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxjQUFjLENBQUMsS0FBSyxFQUFFO3dCQUN0RCxFQUFFLEVBQUUsRUFBRSxTQUFTLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFO3dCQUM1QyxFQUFFLEVBQUUsRUFBRSxVQUFVLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSyxFQUFFO3FCQUMvQztvQkFDRCxhQUFhLEVBQUUsRUFBRTtpQkFDbEIsQ0FBQyxDQUFDO2dCQUVMLE1BQU0sZUFBZSxHQUFHLE9BQU87cUJBQzVCLElBQUksQ0FBQyxpQkFBTSxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQUM7cUJBQ3JDLE9BQU8sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBRWxFLE1BQU0sY0FBYyxHQUFHO29CQUNyQixRQUFRLEVBQUUsUUFBUTtvQkFDbEIsSUFBSSxFQUFFLGNBQWMsQ0FBQyxFQUFFO29CQUN2QixXQUFXLEVBQUUsY0FBYyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztvQkFDekQsZ0JBQWdCLEVBQUUsWUFBWTtvQkFDOUIsS0FBSyxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsS0FBSztvQkFDakMsT0FBTyxFQUFFLElBQUk7b0JBQ2IsWUFBWSxFQUFFLEtBQUs7aUJBQ3BCLENBQUM7Z0JBRUYsTUFBTSxjQUFjLEdBQUc7b0JBQ3JCLFFBQVEsRUFBRSxRQUFRO29CQUNsQixJQUFJLEVBQUUsY0FBYyxDQUFDLEVBQUU7b0JBQ3ZCLFdBQVcsRUFBRSxjQUFjLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO29CQUN6RCxnQkFBZ0IsRUFBRSxZQUFZO29CQUM5QixLQUFLLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxLQUFLO29CQUNqQyxPQUFPLEVBQUUsSUFBSTtvQkFDYixZQUFZLEVBQUUsS0FBSztpQkFDcEIsQ0FBQztnQkFFRixNQUFNLEdBQUcsR0FBRyxNQUFNLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7Z0JBQ2hGLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDaEMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUNwQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDMUIsZUFBZSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN2QixjQUFjLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3RCLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDdkIsa0JBQWtCLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQzFCLE1BQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDaEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLGNBQWMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUMvRCxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDakUsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxpQ0FBaUMsRUFBRSxLQUFLO1lBQ3pDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUV4QixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLDRCQUE0QixPQUFPLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdEUsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztpQkFDaEMsSUFBSSxDQUFDLDRCQUE0QixPQUFPLEVBQUUsRUFBRSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxDQUFDO2lCQUMxRixLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRWxCLE1BQU0sT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBQ3RELGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztRQUVILFFBQVEsQ0FBQyxpQkFBaUIsRUFBRTtZQUMxQixJQUFBLGlCQUFTLEVBQUM7Z0JBQ1IsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUNoQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNsQixDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyw2REFBNkQsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDM0UsTUFBTSxPQUFPO3FCQUNWLGVBQWUsQ0FBQyxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsRUFBRSxFQUFFLENBQUM7cUJBQzlELE1BQU0sQ0FBQyxZQUFZLENBQUMsc0NBQXNDLENBQUMsQ0FBQztZQUNqRSxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyx1REFBdUQsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDckUsTUFBTSxPQUFPO3FCQUNWLGVBQWUsQ0FBQyxFQUFFLGNBQWMsRUFBRSxFQUFFLEVBQUUsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLENBQUM7cUJBQ3ZFLE1BQU0sQ0FBQyxZQUFZLENBQUMsOEJBQThCLENBQUMsQ0FBQztZQUN6RCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQywrQ0FBK0MsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDN0QsS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBTyxDQUFDLFNBQVMsRUFBRSxjQUFjLENBQUMsQ0FBQyxRQUFRLENBQUM7b0JBQ3JELFFBQVEsRUFBRTt3QkFDUjs0QkFDRSxFQUFFLEVBQUUsa0NBQWtDOzRCQUN0QyxJQUFJLEVBQUUsTUFBTTs0QkFDWixXQUFXLEVBQUUsU0FBUzs0QkFDdEIsUUFBUSxFQUFFLGVBQWU7NEJBQ3pCLE1BQU0sRUFBRSxhQUFhOzRCQUNyQixNQUFNLEVBQUUsZUFBZTs0QkFDdkIsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDOzRCQUN0QixLQUFLLEVBQUUsUUFBUTt5QkFDaEI7cUJBQ0Y7b0JBQ0QsUUFBUSxFQUFFLEVBQUU7aUJBQ2IsQ0FBQyxDQUFDO2dCQUNILE1BQU0sT0FBTztxQkFDVixlQUFlLENBQUM7b0JBQ2YsY0FBYyxFQUFFLENBQUMsa0NBQWtDLENBQUM7b0JBQ3BELGlCQUFpQixFQUFFLFdBQVc7aUJBQy9CLENBQUM7cUJBQ0QsTUFBTSxDQUFDLFlBQVksQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1lBQzNELENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLDREQUE0RCxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUMxRSxLQUFLLENBQUMsSUFBSSxDQUFDLGtCQUFPLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDckQsUUFBUSxFQUFFO3dCQUNSOzRCQUNFLEVBQUUsRUFBRSxrQ0FBa0M7NEJBQ3RDLElBQUksRUFBRSxNQUFNOzRCQUNaLFdBQVcsRUFBRSxTQUFTOzRCQUN0QixRQUFRLEVBQUUsZUFBZTs0QkFDekIsTUFBTSxFQUFFLGFBQWE7NEJBQ3JCLE1BQU0sRUFBRSxlQUFlOzRCQUN2QixXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUM7NEJBQ3RCLEtBQUssRUFBRSxRQUFRO3lCQUNoQjtxQkFDRjtvQkFDRCxRQUFRLEVBQUUsRUFBRTtpQkFDYixDQUFDLENBQUM7Z0JBRUgsTUFBTSxPQUFPO3FCQUNWLGVBQWUsQ0FBQztvQkFDZixjQUFjLEVBQUUsQ0FBQyxrQ0FBa0MsQ0FBQztvQkFDcEQsaUJBQWlCLEVBQUUsV0FBVztpQkFDL0IsQ0FBQztxQkFDRCxNQUFNLENBQUMsWUFBWSxDQUFDLGdDQUFnQyxDQUFDLENBQUM7WUFDM0QsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsZ0RBQWdELEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQzlELEtBQUssQ0FBQyxJQUFJLENBQUMsa0JBQU8sQ0FBQyxTQUFTLEVBQUUsY0FBYyxDQUFDLENBQUMsUUFBUSxDQUFDO29CQUNyRCxRQUFRLEVBQUU7d0JBQ1I7NEJBQ0UsRUFBRSxFQUFFLGtDQUFrQzs0QkFDdEMsSUFBSSxFQUFFLE1BQU07NEJBQ1osV0FBVyxFQUFFLFNBQVM7NEJBQ3RCLFFBQVEsRUFBRSxlQUFlOzRCQUN6QixNQUFNLEVBQUUsYUFBYTs0QkFDckIsTUFBTSxFQUFFLGVBQWU7NEJBQ3ZCLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQzs0QkFDdEIsS0FBSyxFQUFFLFFBQVE7NEJBQ2YsUUFBUSxFQUFFO2dDQUNSLEdBQUcsRUFBRSxLQUFLO2dDQUNWLFFBQVEsRUFBRSxVQUFVO2dDQUNwQixVQUFVLEVBQUUsWUFBWTtnQ0FDeEIsWUFBWSxFQUFFLGNBQWM7Z0NBQzVCLElBQUksRUFBRSxNQUFNOzZCQUNiO3lCQUNGO3FCQUNGO29CQUNELFFBQVEsRUFBRSxFQUFFO2lCQUNiLENBQUMsQ0FBQztnQkFDSCxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDNUMsR0FBRyxFQUFFLGFBQWE7aUJBQ25CLENBQUMsQ0FBQztnQkFFSCxNQUFNLE9BQU87cUJBQ1YsZUFBZSxDQUFDO29CQUNmLGNBQWMsRUFBRSxDQUFDLGtDQUFrQyxDQUFDO29CQUNwRCxpQkFBaUIsRUFBRSxXQUFXO2lCQUMvQixDQUFDO3FCQUNELE1BQU0sQ0FBQyxZQUFZLENBQUMsaURBQWlELENBQUMsQ0FBQztZQUM1RSxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxrQ0FBa0MsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDaEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNsQyxNQUFNLGdCQUFnQixHQUFHLFdBQVcsQ0FBQztnQkFDckMsTUFBTSxZQUFZLEdBQWlDO29CQUNqRCxZQUFZLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsUUFBUSxFQUFFLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLENBQUM7aUJBQzNGLENBQUM7Z0JBQ0YsTUFBTSxPQUFPLEdBQUcsSUFBQSxvQ0FBeUIsRUFBQyxLQUFLLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixDQUFDLENBQUM7Z0JBQ2pGLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDYixNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7Z0JBQ3JELENBQUM7Z0JBRUQsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQywwQ0FBMEMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUMxRyxNQUFNLElBQUksR0FBRyxjQUFjLENBQUM7Z0JBQzVCLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFFckUsTUFBTSxLQUFLLEdBQUcsSUFBQSx3QkFBYSxHQUFFLENBQUM7Z0JBQzlCLE1BQU0sTUFBTSxHQUFHLElBQUEsMEJBQWUsRUFBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2xGLE1BQU0sZUFBZSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUM1RSxJQUFJLENBQUMsS0FBSyxDQUFDO3FCQUNSLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQztxQkFDM0IsS0FBSyxDQUFDLEdBQUcsRUFBRTtvQkFDVixRQUFRLEVBQUU7d0JBQ1I7NEJBQ0UsRUFBRSxFQUFFLGtDQUFrQzs0QkFDdEMsY0FBYyxFQUFFLElBQUk7NEJBQ3BCLFFBQVEsRUFBRTtnQ0FDUixJQUFJLEVBQUUsSUFBSTtnQ0FDVixVQUFVLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO2dDQUMzQyxZQUFZLEVBQUUsZUFBZTtnQ0FDN0IsUUFBUSxFQUFFLE1BQU07Z0NBQ2hCLEdBQUcsRUFBRSxNQUFNOzZCQUNaO3lCQUNGO3FCQUNGO2lCQUNGLENBQUMsQ0FBQztnQkFDTCxJQUFJLENBQUMsS0FBSyxDQUFDO3FCQUNSLEdBQUcsQ0FBQyw2QkFBNkIsQ0FBQztxQkFDbEMsS0FBSyxDQUFDLEdBQUcsRUFBRTtvQkFDVixvQkFBb0IsRUFBRTt3QkFDcEI7NEJBQ0UsYUFBYSxFQUFFLGtDQUFrQzt5QkFDbEQ7cUJBQ0Y7aUJBQ0YsQ0FBQyxDQUFDO2dCQUVMLE1BQU0sY0FBYyxHQUFHLE1BQU0sS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN4RCxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDNUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLEVBQUUsY0FBYyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQztpQkFDekYsQ0FBQyxDQUFDO2dCQUVILE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7b0JBQzNCLFFBQVEsRUFBRSxnQkFBZ0I7b0JBQzFCLEtBQUssRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxFQUFFLGNBQWMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLENBQUM7aUJBQ2pGLENBQUMsQ0FBQztnQkFDSCxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzdDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLGlCQUFpQixDQUFDLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQUM7Z0JBRXhFLE1BQU0sS0FBSyxHQUFHLE1BQU0sT0FBTyxDQUFDLGVBQWUsQ0FBQztvQkFDMUMsY0FBYyxFQUFFLENBQUMsa0NBQWtDLENBQUM7b0JBQ3BELGlCQUFpQixFQUFFLGdCQUFnQjtpQkFDcEMsQ0FBQyxDQUFDO2dCQUNILE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFO29CQUN0QixvQkFBb0IsRUFBRTt3QkFDcEI7NEJBQ0UsYUFBYSxFQUFFLGtDQUFrQzt5QkFDbEQ7cUJBQ0Y7aUJBQ0YsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILFFBQVEsQ0FBQyx1QkFBdUIsRUFBRTtZQUNoQyxJQUFBLGlCQUFTLEVBQUM7Z0JBQ1IsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUNoQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNsQixDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyw0REFBNEQsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDMUUsTUFBTSxPQUFPLENBQUMscUJBQXFCLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsMkJBQTJCLENBQUMsQ0FBQztZQUM5RixDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyw4REFBOEQsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDNUUsTUFBTSxPQUFPO3FCQUNWLHFCQUFxQixDQUFDLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxDQUFDO3FCQUNqRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1lBQ2xGLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLGtFQUFrRSxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUNoRixNQUFNLE9BQU87cUJBQ1YscUJBQXFCLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUM7cUJBQ3pELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLGdDQUFnQyxDQUFDLENBQUM7WUFDOUQsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsMkRBQTJELEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQ3pFLE1BQU0sT0FBTztxQkFDVixxQkFBcUIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQztxQkFDN0QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMseUJBQXlCLENBQUMsQ0FBQztZQUN2RCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQywyREFBMkQsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDekUsTUFBTSxPQUFPO3FCQUNWLHFCQUFxQixDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQyxFQUFFLENBQUM7cUJBQ2hGLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHVFQUF1RSxDQUFDLENBQUM7WUFDckcsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsNERBQTRELEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQzFFLE1BQU0sT0FBTztxQkFDVixxQkFBcUIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDO3FCQUM3RSxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyx5REFBeUQsQ0FBQyxDQUFDO1lBQ3ZGLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLGdFQUFnRSxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUM5RSxNQUFNLE9BQU87cUJBQ1YscUJBQXFCLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsaUJBQWlCLEVBQUUsR0FBRyxFQUFFLENBQUM7cUJBQ3ZHLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLGdFQUFnRSxDQUFDLENBQUM7WUFDOUYsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsa0VBQWtFLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQ2hGLE1BQU0sT0FBTztxQkFDVixxQkFBcUIsQ0FBQztvQkFDckIsTUFBTSxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQztvQkFDcEQsaUJBQWlCLEVBQUUsVUFBVTtvQkFDN0IsbUJBQW1CLEVBQUUsR0FBRztpQkFDekIsQ0FBQztxQkFDRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxrRUFBa0UsQ0FBQyxDQUFDO1lBQ2hHLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHFEQUFxRCxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUNuRSxNQUFNLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHNCQUFzQixDQUFDLENBQUM7WUFDckcsQ0FBQyxDQUFDLENBQUM7WUFFSCxFQUFFLENBQUMsK0NBQStDLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQzdELEtBQUssQ0FBQyxJQUFJLENBQUMsa0JBQU8sQ0FBQyxTQUFTLEVBQUUsY0FBYyxDQUFDLENBQUMsUUFBUSxDQUFDO29CQUNyRCxRQUFRLEVBQUU7d0JBQ1I7NEJBQ0UsRUFBRSxFQUFFLGtDQUFrQzs0QkFDdEMsSUFBSSxFQUFFLE1BQU07NEJBQ1osV0FBVyxFQUFFLFNBQVM7NEJBQ3RCLFFBQVEsRUFBRSxlQUFlOzRCQUN6QixNQUFNLEVBQUUsYUFBYTs0QkFDckIsTUFBTSxFQUFFLGVBQWU7NEJBQ3ZCLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQzs0QkFDdEIsS0FBSyxFQUFFLFFBQVE7eUJBQ2hCO3FCQUNGO29CQUNELFFBQVEsRUFBRSxFQUFFO2lCQUNiLENBQUMsQ0FBQztnQkFDSCxNQUFNLE9BQU87cUJBQ1YscUJBQXFCLENBQUM7b0JBQ3JCLE1BQU0sRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLGtDQUFrQyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQztvQkFDakYsaUJBQWlCLEVBQUUsV0FBVztpQkFDL0IsQ0FBQztxQkFDRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxpRUFBaUUsQ0FBQyxDQUFDO1lBQy9GLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLDBGQUEwRixFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUN4RyxLQUFLLENBQUMsSUFBSSxDQUFDLGtCQUFPLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDckQsUUFBUSxFQUFFO3dCQUNSOzRCQUNFLEVBQUUsRUFBRSxrQ0FBa0M7NEJBQ3RDLElBQUksRUFBRSxNQUFNOzRCQUNaLFdBQVcsRUFBRSxTQUFTOzRCQUN0QixRQUFRLEVBQUUsZUFBZTs0QkFDekIsTUFBTSxFQUFFLGFBQWE7NEJBQ3JCLE1BQU0sRUFBRSxlQUFlOzRCQUN2QixXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUM7NEJBQ3RCLEtBQUssRUFBRSxRQUFROzRCQUNmLFFBQVEsRUFBRTtnQ0FDUixHQUFHLEVBQUUsS0FBSztnQ0FDVixRQUFRLEVBQUUsVUFBVTtnQ0FDcEIsVUFBVSxFQUFFLFlBQVk7Z0NBQ3hCLFlBQVksRUFBRSxjQUFjO2dDQUM1QixJQUFJLEVBQUUsTUFBTTs2QkFDYjt5QkFDRjtxQkFDRjtvQkFDRCxRQUFRLEVBQUUsRUFBRTtpQkFDYixDQUFDLENBQUM7Z0JBQ0gsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxRQUFRLENBQUM7b0JBQzVDLEdBQUcsRUFBRSxhQUFhO2lCQUNuQixDQUFDLENBQUM7Z0JBRUgsTUFBTSxPQUFPO3FCQUNWLHFCQUFxQixDQUFDO29CQUNyQixNQUFNLEVBQUUsQ0FBQyxFQUFFLGFBQWEsRUFBRSxrQ0FBa0MsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUM7b0JBQ2pGLGlCQUFpQixFQUFFLFdBQVc7aUJBQy9CLENBQUM7cUJBQ0QsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsaURBQWlELENBQUMsQ0FBQztZQUMvRSxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyx3RUFBd0UsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDdEYsTUFBTSxnQkFBZ0IsR0FBRyxXQUFXLENBQUM7Z0JBRXJDLHlDQUF5QztnQkFDekMsS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBTyxDQUFDLFNBQVMsRUFBRSxjQUFjLENBQUMsQ0FBQyxRQUFRLENBQUM7b0JBQ3JELFFBQVEsRUFBRTt3QkFDUjs0QkFDRSxFQUFFLEVBQUUsUUFBUTs0QkFDWixJQUFJLEVBQUUsTUFBTTs0QkFDWixXQUFXLEVBQUUsU0FBUzs0QkFDdEIsUUFBUSxFQUFFLGVBQWU7NEJBQ3pCLE1BQU0sRUFBRSxhQUFhOzRCQUNyQixNQUFNLEVBQUUsU0FBUzs0QkFDakIsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDOzRCQUN0QixLQUFLLEVBQUUsUUFBUTt5QkFDaEI7d0JBQ0Q7NEJBQ0UsRUFBRSxFQUFFLFFBQVE7NEJBQ1osSUFBSSxFQUFFLE1BQU07NEJBQ1osV0FBVyxFQUFFLFVBQVU7NEJBQ3ZCLFFBQVEsRUFBRSxlQUFlOzRCQUN6QixNQUFNLEVBQUUsYUFBYTs0QkFDckIsTUFBTSxFQUFFLFNBQVM7NEJBQ2pCLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQzs0QkFDdEIsS0FBSyxFQUFFLFFBQVE7eUJBQ2hCO3FCQUNGO29CQUNELFFBQVEsRUFBRSxFQUFFO2lCQUNiLENBQUMsQ0FBQztnQkFFSCxvQ0FBb0M7Z0JBQ3BDLE1BQU0sY0FBYyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsa0JBQU8sQ0FBQyxTQUFTLEVBQUUsOEJBQThCLENBQUMsQ0FBQyxRQUFRLENBQUM7b0JBQzVGLG9CQUFvQixFQUFFLENBQUMsUUFBUSxDQUFDO29CQUNoQyxvQkFBb0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkFDaEMsdUJBQXVCLEVBQUUsRUFBRTtpQkFDNUIsQ0FBQyxDQUFDO2dCQUVILE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLHFCQUFxQixDQUFDO29CQUNqRCxNQUFNLEVBQUU7d0JBQ04sRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7d0JBQzdDLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO3FCQUM5QztvQkFDRCxpQkFBaUIsRUFBRSxnQkFBZ0I7aUJBQ3BDLENBQUMsQ0FBQztnQkFFSCxvQkFBb0I7Z0JBQ3BCLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFO29CQUN2QixvQkFBb0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkFDaEMsb0JBQW9CLEVBQUUsQ0FBQyxRQUFRLENBQUM7b0JBQ2hDLHVCQUF1QixFQUFFLEVBQUU7aUJBQzVCLENBQUMsQ0FBQztnQkFFSCx5RUFBeUU7Z0JBQ3pFLGNBQWMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDM0MsTUFBTSxZQUFZLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RELFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFckMsdURBQXVEO2dCQUN2RCxZQUFZLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQztvQkFDOUI7d0JBQ0UsYUFBYSxFQUFFLFFBQVE7d0JBQ3ZCLE1BQU0sRUFBRSxRQUFRO3FCQUNqQjtpQkFDRixDQUFDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztZQUVILEVBQUUsQ0FBQyxnRUFBZ0UsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDOUUsTUFBTSxnQkFBZ0IsR0FBRyxXQUFXLENBQUM7Z0JBRXJDLG9FQUFvRTtnQkFDcEUsS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBTyxDQUFDLFNBQVMsRUFBRSxjQUFjLENBQUMsQ0FBQyxRQUFRLENBQUM7b0JBQ3JELFFBQVEsRUFBRTt3QkFDUjs0QkFDRSxFQUFFLEVBQUUsUUFBUTs0QkFDWixJQUFJLEVBQUUsTUFBTTs0QkFDWixXQUFXLEVBQUUsU0FBUzs0QkFDdEIsUUFBUSxFQUFFLGVBQWU7NEJBQ3pCLE1BQU0sRUFBRSxhQUFhOzRCQUNyQixNQUFNLEVBQUUsU0FBUzs0QkFDakIsV0FBVyxFQUFFLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQzs0QkFDL0IsS0FBSyxFQUFFLFFBQVE7NEJBQ2Ysd0JBQXdCLEVBQUUsSUFBSTt5QkFDL0I7cUJBQ0Y7b0JBQ0QsUUFBUSxFQUFFLEVBQUU7aUJBQ2IsQ0FBQyxDQUFDO2dCQUVILHdEQUF3RDtnQkFDeEQsTUFBTSxZQUFZLEdBQUc7b0JBQ25CLEVBQUUsRUFBRSxNQUFNO29CQUNWLEdBQUcsRUFBRSxRQUFRO29CQUNiLFlBQVksRUFBRSxxQkFBcUI7aUJBQ3BDLENBQUM7Z0JBQ0YsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUV0RiwrQkFBK0I7Z0JBQy9CLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO2dCQUM1RCxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztnQkFFL0UsdUJBQXVCO2dCQUN2QixLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDNUMsYUFBYSxFQUFFLGVBQWU7aUJBQy9CLENBQUMsQ0FBQztnQkFFSCxvQ0FBb0M7Z0JBQ3BDLE1BQU0sY0FBYyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsa0JBQU8sQ0FBQyxTQUFTLEVBQUUsOEJBQThCLENBQUMsQ0FBQyxRQUFRLENBQUM7b0JBQzVGLG9CQUFvQixFQUFFLENBQUMsUUFBUSxDQUFDO29CQUNoQyxvQkFBb0IsRUFBRSxFQUFFO29CQUN4Qix1QkFBdUIsRUFBRSxFQUFFO2lCQUM1QixDQUFDLENBQUM7Z0JBRUgsaUNBQWlDO2dCQUNqQyxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLGtCQUFPLENBQUMsU0FBUyxFQUFFLDJCQUEyQixDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBRTFGLE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLHFCQUFxQixDQUFDO29CQUNqRCxNQUFNLEVBQUUsQ0FBQyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxDQUFDO29CQUN2RCxpQkFBaUIsRUFBRSxnQkFBZ0I7aUJBQ3BDLENBQUMsQ0FBQztnQkFFSCxvQkFBb0I7Z0JBQ3BCLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFO29CQUN2QixvQkFBb0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkFDaEMsb0JBQW9CLEVBQUUsRUFBRTtvQkFDeEIsdUJBQXVCLEVBQUUsRUFBRTtpQkFDNUIsQ0FBQyxDQUFDO2dCQUVILGlEQUFpRDtnQkFDakQsY0FBYyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUUzQyxzRUFBc0U7Z0JBQ3RFLFdBQVcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDeEMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDdEQsV0FBVyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQy9ELENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLGtEQUFrRCxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUNoRSxNQUFNLGdCQUFnQixHQUFHLFdBQVcsQ0FBQztnQkFFckMsdURBQXVEO2dCQUN2RCxLQUFLLENBQUMsSUFBSSxDQUFDLGtCQUFPLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDckQsUUFBUSxFQUFFO3dCQUNSOzRCQUNFLEVBQUUsRUFBRSxRQUFROzRCQUNaLElBQUksRUFBRSxNQUFNOzRCQUNaLFdBQVcsRUFBRSxTQUFTOzRCQUN0QixRQUFRLEVBQUUsZUFBZTs0QkFDekIsTUFBTSxFQUFFLGFBQWE7NEJBQ3JCLE1BQU0sRUFBRSxTQUFTOzRCQUNqQixXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUM7NEJBQ3JCLEtBQUssRUFBRSxRQUFRO3lCQUNoQjtxQkFDRjtvQkFDRCxRQUFRLEVBQUUsRUFBRTtpQkFDYixDQUFDLENBQUM7Z0JBRUgsb0NBQW9DO2dCQUNwQyxNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLGtCQUFPLENBQUMsU0FBUyxFQUFFLDhCQUE4QixDQUFDLENBQUMsUUFBUSxDQUFDO29CQUM1RixvQkFBb0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkFDaEMsb0JBQW9CLEVBQUUsRUFBRTtvQkFDeEIsdUJBQXVCLEVBQUUsRUFBRTtpQkFDNUIsQ0FBQyxDQUFDO2dCQUVILE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLHFCQUFxQixDQUFDO29CQUNqRCxNQUFNLEVBQUUsQ0FBQyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxDQUFDO29CQUN2RCxpQkFBaUIsRUFBRSxnQkFBZ0I7aUJBQ3BDLENBQUMsQ0FBQztnQkFFSCxvQkFBb0I7Z0JBQ3BCLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFO29CQUN2QixvQkFBb0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkFDaEMsb0JBQW9CLEVBQUUsRUFBRTtvQkFDeEIsdUJBQXVCLEVBQUUsRUFBRTtpQkFDNUIsQ0FBQyxDQUFDO2dCQUVILHlFQUF5RTtnQkFDekUsY0FBYyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUMzQyxNQUFNLFlBQVksR0FBRyxjQUFjLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEQsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUVyQyx5RUFBeUU7Z0JBQ3pFLFlBQVksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDO29CQUM5Qjt3QkFDRSxhQUFhLEVBQUUsUUFBUTt3QkFDdkIsTUFBTSxFQUFFLFFBQVE7cUJBQ2pCO2lCQUNGLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHlEQUF5RCxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUN2RSxNQUFNLGdCQUFnQixHQUFHLFdBQVcsQ0FBQztnQkFDckMsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDO2dCQUU1Qix3QkFBd0I7Z0JBQ3hCLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsMENBQTBDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDNUcsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQywwQ0FBMEMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUUxRyxNQUFNLFVBQVUsR0FBRyxZQUFZLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDMUQsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUV2RSwrQkFBK0I7Z0JBQy9CLE1BQU0sZUFBZSxHQUFHLG9CQUFvQixDQUFDO2dCQUM3QyxNQUFNLFlBQVksR0FBRyxJQUFBLDBCQUFlLEVBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUVqRyxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO29CQUNqQyxRQUFRLEVBQUUsWUFBWTtvQkFDdEIsS0FBSyxFQUFFLGVBQWU7aUJBQ3ZCLENBQUMsQ0FBQztnQkFFSCxvREFBb0Q7Z0JBQ3BELEtBQUssQ0FBQyxJQUFJLENBQUMsa0JBQU8sQ0FBQyxTQUFTLEVBQUUsY0FBYyxDQUFDLENBQUMsUUFBUSxDQUFDO29CQUNyRCxRQUFRLEVBQUU7d0JBQ1I7NEJBQ0UsRUFBRSxFQUFFLFFBQVE7NEJBQ1osSUFBSSxFQUFFLE1BQU07NEJBQ1osV0FBVyxFQUFFLFNBQVM7NEJBQ3RCLFFBQVEsRUFBRSxlQUFlOzRCQUN6QixNQUFNLEVBQUUsYUFBYTs0QkFDckIsTUFBTSxFQUFFLFNBQVM7NEJBQ2pCLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQzs0QkFDdEIsS0FBSyxFQUFFLFFBQVE7NEJBQ2YsUUFBUSxFQUFFO2dDQUNSLEdBQUcsRUFBRSxRQUFRO2dDQUNiLFFBQVEsRUFBRSxRQUFRO2dDQUNsQixVQUFVLEVBQUUsVUFBVTtnQ0FDdEIsWUFBWSxFQUFFLFlBQVk7Z0NBQzFCLElBQUksRUFBRSxJQUFJOzZCQUNYO3lCQUNGO3FCQUNGO29CQUNELFFBQVEsRUFBRSxFQUFFO2lCQUNiLENBQUMsQ0FBQztnQkFFSCx1QkFBdUI7Z0JBQ3ZCLE1BQU0sY0FBYyxHQUFHLE1BQU0sS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN4RCxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDNUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLEVBQUUsY0FBYyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQztpQkFDekYsQ0FBQyxDQUFDO2dCQUVILGtDQUFrQztnQkFDbEMsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQ2pELFdBQVcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsdUJBQXVCO2dCQUMvRSxXQUFXLENBQUMsWUFBWSxFQUFFLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsc0JBQXNCO2dCQUUzRSxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQztnQkFFNUUsdUJBQXVCO2dCQUN2QixLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7Z0JBRTlFLG9DQUFvQztnQkFDcEMsTUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBTyxDQUFDLFNBQVMsRUFBRSw4QkFBOEIsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDNUYsb0JBQW9CLEVBQUUsQ0FBQyxRQUFRLENBQUM7b0JBQ2hDLG9CQUFvQixFQUFFLEVBQUU7b0JBQ3hCLHVCQUF1QixFQUFFLEVBQUU7aUJBQzVCLENBQUMsQ0FBQztnQkFFSCxNQUFNLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQztvQkFDakQsTUFBTSxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQztvQkFDdkQsaUJBQWlCLEVBQUUsZ0JBQWdCO29CQUNuQyxtQkFBbUIsRUFBRSxlQUFlO2lCQUNyQyxDQUFDLENBQUM7Z0JBRUgsb0JBQW9CO2dCQUNwQixNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRTtvQkFDdkIsb0JBQW9CLEVBQUUsQ0FBQyxRQUFRLENBQUM7b0JBQ2hDLG9CQUFvQixFQUFFLEVBQUU7b0JBQ3hCLHVCQUF1QixFQUFFLEVBQUU7aUJBQzVCLENBQUMsQ0FBQztnQkFFSCx5RUFBeUU7Z0JBQ3pFLGNBQWMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDM0MsTUFBTSxZQUFZLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RELFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFckMsaUVBQWlFO2dCQUNqRSxZQUFZLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQztvQkFDOUI7d0JBQ0UsYUFBYSxFQUFFLFFBQVE7d0JBQ3ZCLE1BQU0sRUFBRSxRQUFRO3dCQUNoQixZQUFZLEVBQUUsaUJBQWlCO3FCQUNoQztpQkFDRixDQUFDLENBQUM7Z0JBRUgsb0RBQW9EO2dCQUNwRCxXQUFXLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3hDLFdBQVcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxlQUFlLENBQUMsQ0FBQztnQkFDaEYsV0FBVyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBQy9FLENBQUMsQ0FBQyxDQUFDO1lBRUgsRUFBRSxDQUFDLHlFQUF5RSxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUN2RixNQUFNLGdCQUFnQixHQUFHLFdBQVcsQ0FBQztnQkFFckMseUNBQXlDO2dCQUN6QyxLQUFLLENBQUMsSUFBSSxDQUFDLGtCQUFPLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDckQsUUFBUSxFQUFFO3dCQUNSOzRCQUNFLEVBQUUsRUFBRSxRQUFROzRCQUNaLElBQUksRUFBRSxNQUFNOzRCQUNaLFdBQVcsRUFBRSxTQUFTOzRCQUN0QixRQUFRLEVBQUUsZUFBZTs0QkFDekIsTUFBTSxFQUFFLGFBQWE7NEJBQ3JCLE1BQU0sRUFBRSxTQUFTOzRCQUNqQixXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUM7NEJBQ3RCLEtBQUssRUFBRSxRQUFRO3lCQUNoQjt3QkFDRDs0QkFDRSxFQUFFLEVBQUUsUUFBUTs0QkFDWixJQUFJLEVBQUUsTUFBTTs0QkFDWixXQUFXLEVBQUUsVUFBVTs0QkFDdkIsUUFBUSxFQUFFLGVBQWU7NEJBQ3pCLE1BQU0sRUFBRSxhQUFhOzRCQUNyQixNQUFNLEVBQUUsU0FBUzs0QkFDakIsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDOzRCQUN0QixLQUFLLEVBQUUsUUFBUTt5QkFDaEI7d0JBQ0Q7NEJBQ0UsRUFBRSxFQUFFLFFBQVE7NEJBQ1osSUFBSSxFQUFFLE1BQU07NEJBQ1osV0FBVyxFQUFFLFVBQVU7NEJBQ3ZCLFFBQVEsRUFBRSxlQUFlOzRCQUN6QixNQUFNLEVBQUUsYUFBYTs0QkFDckIsTUFBTSxFQUFFLFNBQVM7NEJBQ2pCLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQzs0QkFDdEIsS0FBSyxFQUFFLFFBQVE7eUJBQ2hCO3FCQUNGO29CQUNELFFBQVEsRUFBRSxFQUFFO2lCQUNiLENBQUMsQ0FBQztnQkFFSCx1REFBdUQ7Z0JBQ3ZELG1FQUFtRTtnQkFDbkUsTUFBTSxzQkFBc0IsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLGtCQUFPLENBQUMsU0FBZ0IsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO2dCQUMxRixzQkFBc0I7cUJBQ25CLFFBQVEsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7cUJBQ3RGLFFBQVEsQ0FBQyxDQUFDLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUM3RCxzQkFBc0I7cUJBQ25CLFFBQVEsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7cUJBQ3RGLE9BQU8sQ0FBQyxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xELHNCQUFzQjtxQkFDbkIsUUFBUSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQztxQkFDdEYsUUFBUSxDQUFDLENBQUMsRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBRTdELHlEQUF5RDtnQkFDekQsTUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBTyxDQUFDLFNBQVMsRUFBRSw4QkFBOEIsQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDNUYsb0JBQW9CLEVBQUUsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDO29CQUMxQyxvQkFBb0IsRUFBRSxFQUFFO29CQUN4Qix1QkFBdUIsRUFBRSxFQUFFLEVBQUUsdUNBQXVDO2lCQUNyRSxDQUFDLENBQUM7Z0JBRUgsTUFBTSxNQUFNLEdBQUcsTUFBTSxPQUFPLENBQUMscUJBQXFCLENBQUM7b0JBQ2pELE1BQU0sRUFBRTt3QkFDTixFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTt3QkFDN0MsRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7d0JBQzdDLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO3FCQUM5QztvQkFDRCxpQkFBaUIsRUFBRSxnQkFBZ0I7aUJBQ3BDLENBQUMsQ0FBQztnQkFFSCxnRkFBZ0Y7Z0JBQ2hGLGNBQWMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDM0MsTUFBTSxZQUFZLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RELFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDckMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNyRCxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQzlDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDckQsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUU5QyxtREFBbUQ7Z0JBQ25ELE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO2dCQUN2RCxNQUFNLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3BELE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdkQsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDbEYsTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSwwQkFBMEIsQ0FBQyxDQUFDO1lBQy9GLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQywyQkFBMkIsRUFBRSxHQUFHLEVBQUU7UUFDekMsTUFBTSxVQUFVLEdBQUc7WUFDakIsRUFBRSxFQUFFLGtDQUFrQztZQUN0QyxJQUFJLEVBQUUsTUFBTTtZQUNaLElBQUksRUFBRTtnQkFDSixrQ0FBa0M7Z0JBQ2xDLGtDQUFrQztnQkFDbEMsa0NBQWtDO2FBQ25DO1lBQ0QsWUFBWSxFQUFFLEVBQUU7WUFDaEIsWUFBWSxFQUFFLFNBQVM7WUFDdkIsSUFBSSxFQUFFLEtBQUs7U0FDWixDQUFDO1FBQ0YsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxNQUFNLE1BQU0sR0FBRyxJQUFJLGlCQUFNLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNuRCxNQUFNLENBQUM7WUFDTCxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNqSCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztRQUNILFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDeEIsQ0FBQyxDQUFDLENBQUM7UUFDSCxLQUFLLENBQUM7WUFDSixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDaEIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBQSxpQkFBUyxFQUFDO1lBQ1IsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2xCLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGdEQUFnRCxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzlELElBQUksQ0FBQztnQkFDSCxNQUFNLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDckMsTUFBTSxDQUFDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1lBQzNDLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSw4QkFBOEIsQ0FBQyxDQUFDO1lBQ3BFLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0REFBNEQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMxRSxNQUFNLE1BQU0sR0FBRztnQkFDYjtvQkFDRSxJQUFJLEVBQUUsc0JBQXNCO29CQUM1QixXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUM7b0JBQ3RCLFFBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRTtpQkFDdEY7YUFDRixDQUFDO1lBRUYsSUFBSSxDQUFDO2dCQUNILE1BQU0sTUFBTSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN6QyxNQUFNLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUM7WUFDM0MsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2Ysa0RBQWtEO2dCQUNsRCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsOEJBQThCLENBQUMsQ0FBQztZQUNwRSxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMscUVBQXFFLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDbkYsTUFBTSxNQUFNLEdBQUc7Z0JBQ2IsWUFBWSxFQUFFO29CQUNaO3dCQUNFLElBQUksRUFBRSxzQkFBc0I7d0JBQzVCLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQzt3QkFDdEIsUUFBUSxFQUFFOzRCQUNSLEdBQUcsRUFBRSxRQUFROzRCQUNiLFlBQVksRUFBRSxjQUFjOzRCQUM1QixVQUFVLEVBQUUsWUFBWTs0QkFDeEIsUUFBUSxFQUFFLFVBQVU7NEJBQ3BCLElBQUksRUFBRSxPQUFPO3lCQUNkO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQztZQUNGLE1BQU0sWUFBWSxHQUFHO2dCQUNuQjtvQkFDRSxJQUFJLEVBQUUsc0JBQXNCO29CQUM1QixXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUM7b0JBQ3RCLFFBQVEsRUFBRTt3QkFDUixHQUFHLEVBQUUsUUFBUTt3QkFDYixZQUFZLEVBQUUsY0FBYzt3QkFDNUIsVUFBVSxFQUFFLFlBQVk7d0JBQ3hCLFFBQVEsRUFBRSxVQUFVO3dCQUNwQixJQUFJLEVBQUUsT0FBTztxQkFDZDtpQkFDRjthQUNGLENBQUM7WUFDRixJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNSLElBQUksQ0FBQyxrQkFBa0IsVUFBVSxDQUFDLEVBQUUsZUFBZSxFQUFFLE1BQU0sQ0FBQztpQkFDNUQsS0FBSyxDQUFDLEdBQUcsRUFBRTtnQkFDVixNQUFNLEVBQUU7b0JBQ047d0JBQ0UsRUFBRSxFQUFFLFFBQVE7d0JBQ1osSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO3dCQUNyQixNQUFNLEVBQUUsVUFBVSxDQUFDLEVBQUU7d0JBQ3JCLFFBQVEsRUFBRSxZQUFZO3dCQUN0QixNQUFNLEVBQUUsVUFBVTt3QkFDbEIsV0FBVyxFQUFFLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQzt3QkFDOUIsUUFBUSxFQUFFOzRCQUNSLEdBQUcsRUFBRSxVQUFVOzRCQUNmLFlBQVksRUFBRSxtQkFBbUI7NEJBQ2pDLFVBQVUsRUFBRSxpQkFBaUI7NEJBQzdCLFFBQVEsRUFBRSxlQUFlOzRCQUN6QixJQUFJLEVBQUUsV0FBVzt5QkFDbEI7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDLENBQUM7WUFDTCxNQUFNLE1BQU0sR0FBRyxNQUFNLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM5RCxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSwyQkFBMkIsQ0FBQyxDQUFDO1lBQy9FLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1lBQ3BGLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLEVBQUUsRUFBRSw0QkFBNEIsQ0FBQyxDQUFDO1lBQ3pGLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2xDLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRSwrQkFBK0IsQ0FBQyxDQUFDO1lBQy9GLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksRUFBRSx1Q0FBdUMsQ0FBQyxDQUFDO1lBQ2pILE1BQU0sQ0FBQyxXQUFXLENBQ2hCLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFDOUMsSUFBSSxFQUNKLHdDQUF3QyxDQUN6QyxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyw2QkFBNkIsRUFBRSxHQUFHLEVBQUU7UUFDM0MsTUFBTSxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsV0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFFekQsTUFBTSxVQUFVLEdBQUc7WUFDakIsRUFBRSxFQUFFLGtDQUFrQztZQUN0QyxJQUFJLEVBQUUsTUFBTTtZQUNaLElBQUksRUFBRTtnQkFDSixrQ0FBa0M7Z0JBQ2xDLGtDQUFrQztnQkFDbEMsa0NBQWtDO2FBQ25DO1lBQ0QsWUFBWSxFQUFFLEVBQUU7WUFDaEIsWUFBWSxFQUFFLFNBQVM7WUFDdkIsSUFBSSxFQUFFLEtBQUs7U0FDWixDQUFDO1FBQ0YsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxNQUFNLE1BQU0sR0FBRyxJQUFJLGlCQUFNLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNuRCxNQUFNLENBQUM7WUFDTCxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNqSCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztRQUVILEtBQUssQ0FBQztZQUNKLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFBLGlCQUFTLEVBQUM7WUFDUixLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDbEIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0RBQXdELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDdEUsSUFBSSxDQUFDO2dCQUNILE1BQU0sTUFBTSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUN0RixNQUFNLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUM7WUFDM0MsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLDhCQUE4QixDQUFDLENBQUM7WUFDcEUsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHFFQUFxRSxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ25GLE1BQU0sTUFBTSxHQUFHLGtCQUFrQixDQUFDO1lBQ2xDLE1BQU0sV0FBVyxHQUFHLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ3RDLE1BQU0sSUFBSSxHQUFHLGNBQWMsQ0FBQztZQUM1QixNQUFNLGdCQUFnQixHQUFHLFdBQVcsQ0FBQztZQUNyQyxNQUFNLEdBQUcsR0FBRyw2Q0FBNkMsQ0FBQztZQUMxRCxJQUFJLENBQUMsS0FBSyxDQUFDO2lCQUNSLEdBQUcsQ0FBQyxvQkFBb0IsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7aUJBQzdDLEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsRUFBRSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RCLEdBQUc7Z0JBQ0gsTUFBTSxFQUFFLE1BQU07Z0JBQ2QsWUFBWSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDO2dCQUMzRSxZQUFZLEVBQUUsRUFBRTthQUNqQixDQUFDLENBQUM7WUFDTCxNQUFNLE1BQU0sR0FBMkI7Z0JBQ3JDLGdCQUFnQjtnQkFDaEIsZUFBZSxFQUFFO29CQUNmO3dCQUNFLE1BQU0sRUFBRSxNQUFNO3dCQUNkLFdBQVcsRUFBRSxXQUFXO3dCQUN4QixNQUFNLEVBQUUsb0VBQW9FO3dCQUM1RSxJQUFJLEVBQUUsSUFBSTtxQkFDWDtpQkFDRjthQUNGLENBQUM7WUFFRixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDdEMsTUFBTSxZQUFZLEdBQWlDO2dCQUNqRCxZQUFZLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLENBQUM7YUFDekUsQ0FBQztZQUVGLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLDBCQUEwQixDQUFDLENBQUMsUUFBUSxDQUFDO2dCQUN0RCxZQUFZLEVBQUUsWUFBWSxDQUFDLFlBQVk7Z0JBQ3ZDLEdBQUc7YUFDd0IsQ0FBQyxDQUFDO1lBRS9CLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLGlCQUFpQixDQUFDLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFFeEUsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUscUJBQXFCLENBQUMsQ0FBQyxRQUFRLENBQUM7Z0JBQ2pELE1BQU0sRUFBRTtvQkFDTjt3QkFDRSxFQUFFLEVBQUUsTUFBTTt3QkFDVixJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUk7d0JBQ3JCLE1BQU0sRUFBRSxVQUFVLENBQUMsRUFBRTt3QkFDckIsUUFBUSxFQUFFLE1BQU07d0JBQ2hCLE1BQU0sRUFBRSxNQUFNO3dCQUNkLFdBQVcsRUFBRSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUM7d0JBQzlCLFFBQVEsRUFBRTs0QkFDUixHQUFHLEVBQUUsVUFBVTs0QkFDZixZQUFZLEVBQUUsbUJBQW1COzRCQUNqQyxVQUFVLEVBQUUsaUJBQWlCOzRCQUM3QixRQUFRLEVBQUUsZUFBZTs0QkFDekIsSUFBSSxFQUFFLFdBQVc7eUJBQ2xCO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsTUFBTSxNQUFNLEdBQUcsTUFBTSxNQUFNLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFMUQsTUFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQUU7Z0JBQzdCLE1BQU0sRUFBRTtvQkFDTjt3QkFDRSxFQUFFLEVBQUUsTUFBTTt3QkFDVixJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUk7d0JBQ3JCLE1BQU0sRUFBRSxVQUFVLENBQUMsRUFBRTt3QkFDckIsUUFBUSxFQUFFLE1BQU07d0JBQ2hCLE1BQU0sRUFBRSxNQUFNO3dCQUNkLFdBQVcsRUFBRSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUM7d0JBQzlCLFFBQVEsRUFBRTs0QkFDUixHQUFHLEVBQUUsVUFBVTs0QkFDZixZQUFZLEVBQUUsbUJBQW1COzRCQUNqQyxVQUFVLEVBQUUsaUJBQWlCOzRCQUM3QixRQUFRLEVBQUUsZUFBZTs0QkFDekIsSUFBSSxFQUFFLFdBQVc7eUJBQ2xCO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0ZBQWtGLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDaEcsTUFBTSxNQUFNLEdBQUcsa0JBQWtCLENBQUM7WUFDbEMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDdEMsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDO1lBQzVCLE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxDQUFDO1lBQ3JDLE1BQU0sR0FBRyxHQUFHLDZDQUE2QyxDQUFDO1lBQzFELElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ1IsR0FBRyxDQUFDLG9CQUFvQixNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztpQkFDN0MsS0FBSyxDQUFDLEdBQUcsRUFBRTtnQkFDVixFQUFFLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDdEIsR0FBRztnQkFDSCxNQUFNLEVBQUUsTUFBTTtnQkFDZCxZQUFZLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLENBQUM7Z0JBQzNFLFlBQVksRUFBRSxFQUFFO2FBQ2pCLENBQUMsQ0FBQztZQUNMLE1BQU0sTUFBTSxHQUEyQjtnQkFDckMsZ0JBQWdCLEVBQUUsZ0JBQWdCO2dCQUNsQyxlQUFlLEVBQUU7b0JBQ2Y7d0JBQ0UsTUFBTSxFQUFFLE1BQU07d0JBQ2QsV0FBVyxFQUFFLFdBQVc7d0JBQ3hCLE1BQU0sRUFBRSxvRUFBb0U7d0JBQzVFLElBQUksRUFBRSxJQUFJO3FCQUNYO2lCQUNGO2FBQ0YsQ0FBQztZQUVGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUN0QyxNQUFNLFlBQVksR0FBaUM7Z0JBQ2pELFlBQVksRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQzthQUN6RSxDQUFDO1lBRUYsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsMEJBQTBCLENBQUMsQ0FBQyxRQUFRLENBQUM7Z0JBQ3RELFlBQVksRUFBRSxZQUFZLENBQUMsWUFBWTtnQkFDdkMsR0FBRzthQUN3QixDQUFDLENBQUM7WUFFL0IsSUFBSSxDQUFDO2dCQUNILE1BQU0sTUFBTSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUMzQyxNQUFNLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUM7WUFDM0MsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsTUFBTSxDQUFDLEtBQUssWUFBWSxpQ0FBc0IsQ0FBQyxDQUFDO2dCQUNoRCxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsOENBQThDLENBQUMsQ0FBQztZQUM5RSxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxlQUFlLEVBQUU7UUFDeEIsRUFBRSxDQUFDLG9EQUFvRCxFQUFFLEtBQUs7WUFDNUQsTUFBTSxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsV0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDekQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwQyxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDbkMsTUFBTSxLQUFLLEdBQUcsaUJBQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDO1lBRXRELElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ1IsR0FBRyxDQUFDLHFCQUFxQixDQUFDO2lCQUMxQixLQUFLLENBQUMsRUFBRSxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsQ0FBQztpQkFDbkMsS0FBSyxDQUFDLEdBQUcsRUFBRTtnQkFDVixPQUFPLEVBQUU7b0JBQ1AsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUU7b0JBQ3pDLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFO2lCQUMxQzthQUNGLENBQUMsQ0FBQztZQUVMLE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLGtCQUFrQixFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDaEUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNyQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7WUFDckQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGdEQUFnRCxFQUFFLEtBQUs7WUFDeEQsTUFBTSxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsV0FBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDekQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwQyxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDbkMsTUFBTSxLQUFLLEdBQUcsaUJBQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDO1lBRXRELElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ1IsR0FBRyxDQUFDLHFCQUFxQixDQUFDO2lCQUMxQixLQUFLLENBQUMsRUFBRSxDQUFDO2lCQUNULEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFO29CQUNQLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsRUFBRTtvQkFDbEYsRUFBRSxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxFQUFFO2lCQUNuRjthQUNGLENBQUMsQ0FBQztZQUVMLE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3BDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7WUFDakQsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7UUFDbkQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy9cbi8vIFRlc3RzIGZvciBXYWxsZXRzXG4vL1xuaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgKiBhcyBub2NrIGZyb20gJ25vY2snO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0ICogYXMgc2hvdWxkIGZyb20gJ3Nob3VsZCc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgKiBhcyB1dHhvTGliIGZyb20gJ0BiaXRnby91dHhvLWxpYic7XG5pbXBvcnQgeyBUZXN0Qml0R28gfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHtcbiAgY29tbW9uLFxuICBUc3NVdGlscyxcbiAgV2FsbGV0cyxcbiAgRUNEU0FVdGlscyxcbiAgS2V5Y2hhaW5zVHJpcGxldCxcbiAgR2VuZXJhdGVXYWxsZXRPcHRpb25zLFxuICBXYWxsZXQsXG4gIGlzV2FsbGV0V2l0aEtleWNoYWlucyxcbiAgT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSxcbiAgZGVjcnlwdEtleWNoYWluUHJpdmF0ZUtleSxcbiAgbWFrZVJhbmRvbUtleSxcbiAgZ2V0U2hhcmVkU2VjcmV0LFxuICBCdWxrV2FsbGV0U2hhcmVPcHRpb25zLFxuICBLZXljaGFpbldpdGhFbmNyeXB0ZWRQcnYsXG4gIFdhbGxldFdpdGhLZXljaGFpbnMsXG4gIG11bHRpc2lnVHlwZXMsXG4gIEluY29ycmVjdFBhc3N3b3JkRXJyb3IsXG59IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBCaXRHbyB9IGZyb20gJy4uLy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBhZnRlckVhY2ggfSBmcm9tICdtb2NoYSc7XG5pbXBvcnQgeyBUc3NTZXR0aW5ncyB9IGZyb20gJ0BiaXRnby9wdWJsaWMtdHlwZXMnO1xuaW1wb3J0ICogYXMgbW9kdWxlQml0Z28gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcblxuZGVzY3JpYmUoJ1YyIFdhbGxldHM6JywgZnVuY3Rpb24gKCkge1xuICBjb25zdCBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgbGV0IHdhbGxldHM7XG4gIGxldCBiZ1VybDtcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBlcnNpc3QoKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnJlcGx5KDIwMCwgeyB0dGw6IDM2MDAsIGNvbnN0YW50czoge30gfSk7XG5cbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcblxuICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgIHdhbGxldHMgPSBiYXNlY29pbi53YWxsZXRzKCk7XG4gICAgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS51cmk7XG4gIH0pO1xuXG4gIGFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgbm9jay5wZW5kaW5nTW9ja3MoKS5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWRkIFdhbGxldDonLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Rocm93cyBvbiBpbnZhbGlkIGFyZ3VtZW50cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGlzQ3VzdG9kaWFsIGZsYWcgaXMgbm90IGEgYm9vbGVhblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywga2V5czogW10sIG06IDIsIG46IDMsIGlzQ3VzdG9kaWFsOiAxIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGFyZ3VtZW50IGZvciBpc0N1c3RvZGlhbCAtIGJvb2xlYW4gZXhwZWN0ZWQnKTtcblxuICAgICAgLy8gdHlwZSBpcyBub3QgYSBzdHJpbmdcbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmFkZCh7IGxhYmVsOiAnbGFiZWwnLCBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsIGtleXM6IFtdLCBtOiAyLCBuOiAzLCB0eXBlOiAxIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFeHBlY3RpbmcgcGFyYW1ldGVyIHN0cmluZzogdHlwZSBidXQgZm91bmQgbnVtYmVyJyk7XG5cbiAgICAgIC8vIEFkZHJlc3MgaXMgYW4gaW52YWxpZCBhZGRyZXNzXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5hZGQoeyBsYWJlbDogJ2xhYmVsJywgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLCBrZXlzOiBbXSwgbTogMiwgbjogMywgYWRkcmVzczogJyQnIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGFyZ3VtZW50IGZvciBhZGRyZXNzIC0gdmFsaWQgYWRkcmVzcyBzdHJpbmcgZXhwZWN0ZWQnKTtcblxuICAgICAgLy8gZ2FzUHJpY2UgaXMgYSBudW1iZXJcbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmFkZCh7IGxhYmVsOiAnbGFiZWwnLCBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsIGtleXM6IFtdLCBtOiAyLCBuOiAzLCBnYXNQcmljZTogJzE3JyB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBhcmd1bWVudCBmb3IgZ2FzUHJpY2UgLSBudW1iZXIgZXhwZWN0ZWQnKTtcblxuICAgICAgLy8gd2FsbGV0VmVyc2lvbiBpcyBhIG51bWJlclxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywga2V5czogW10sIG06IDIsIG46IDMsIHdhbGxldFZlcnNpb246ICcxJyB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBhcmd1bWVudCBmb3Igd2FsbGV0VmVyc2lvbiAtIG51bWJlciBleHBlY3RlZCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NyZWF0ZXMgYSBwYWlyZWQgY3VzdG9kaWFsIHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS5pc0N1c3RvZGlhbC5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgICBib2R5Lm0uc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgICAgIGJvZHkubi5zaG91bGQuZXF1YWwoMyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IHdhbGxldHMuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywga2V5czogW10sIG06IDIsIG46IDMsIGlzQ3VzdG9kaWFsOiB0cnVlIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NyZWF0ZXMgYW4gZW9zIHdhbGxldCB3aXRoIGN1c3RvbSBhZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZW9zQml0R28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgICBlb3NCaXRHby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICAgIGNvbnN0IGVvc1dhbGxldHMgPSBlb3NCaXRHby5jb2luKCd0ZW9zJykud2FsbGV0cygpO1xuICAgICAgY29uc3QgYWRkcmVzcyA9ICd0ZXN0ZW9zYWRkcmUnO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGVvcy93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdrZXlzJyk7XG4gICAgICAgICAgYm9keS5tLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgICAgICBib2R5Lm4uc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgICAgIGJvZHkuYWRkcmVzcy5zaG91bGQuZXF1YWwoYWRkcmVzcyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IGVvc1dhbGxldHMuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywga2V5czogW10sIG06IDIsIG46IDMsIGFkZHJlc3MgfSBhcyBhbnkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NyZWF0ZXMgYSBzaW5nbGUgY3VzdG9kaWFsIHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS50eXBlLnNob3VsZC5lcXVhbCgnY3VzdG9kaWFsJyk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnbScpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCduJyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGF3YWl0IHdhbGxldHMuYWRkKHsgbGFiZWw6ICdsYWJlbCcsIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJywgdHlwZTogJ2N1c3RvZGlhbCcgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlcyBhIHdhbGxldCB3aXRoIGN1c3RvbSBnYXNQcmljZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV0aEJpdEdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuICAgICAgZXRoQml0R28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgICBjb25zdCBldGhXYWxsZXRzID0gZXRoQml0R28uY29pbigndGV0aCcpLndhbGxldHMoKTtcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RldGgvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS50eXBlLnNob3VsZC5lcXVhbCgnY3VzdG9kaWFsJyk7XG4gICAgICAgICAgYm9keS5nYXNQcmljZS5zaG91bGQuZXF1YWwoMjAwMDAwMDAwMDApO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdrZXlzJyk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ20nKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnbicpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG4gICAgICBhd2FpdCBldGhXYWxsZXRzLmFkZCh7XG4gICAgICAgIGxhYmVsOiAnbGFiZWwnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHR5cGU6ICdjdXN0b2RpYWwnLFxuICAgICAgICBnYXNQcmljZTogMjAwMDAwMDAwMDAsXG4gICAgICB9IGFzIGFueSk7XG4gICAgfSk7XG5cbiAgICBpdCgnY3JlYXRlcyBhIG5ldyB3YWxsZXQgd2l0aCB3YWxsZXRWZXJzaW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXRoQml0R28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgICBldGhCaXRHby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICAgIGNvbnN0IGV0aFdhbGxldHMgPSBldGhCaXRHby5jb2luKCd0ZXRoJykud2FsbGV0cygpO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGV0aC93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnR5cGUuc2hvdWxkLmVxdWFsKCdjdXN0b2RpYWwnKTtcbiAgICAgICAgICBib2R5LndhbGxldFZlcnNpb24uc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLm5vdC5oYXZlLnByb3BlcnR5KCdrZXlzJyk7XG4gICAgICAgICAgYm9keS5zaG91bGQubm90LmhhdmUucHJvcGVydHkoJ20nKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5ub3QuaGF2ZS5wcm9wZXJ0eSgnbicpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwLCB7fSk7XG4gICAgICBhd2FpdCBldGhXYWxsZXRzLmFkZCh7IGxhYmVsOiAnbGFiZWwnLCBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsIHR5cGU6ICdjdXN0b2RpYWwnLCB3YWxsZXRWZXJzaW9uOiAxIH0gYXMgYW55KTtcbiAgICB9KTtcblxuICAgIGl0KCdjcmVhdGVzIGEgbmV3IGhvdCB3YWxsZXQgd2l0aCB1c2VyS2V5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnR5cGUuc2hvdWxkLmVxdWFsKCdob3QnKTtcbiAgICAgICAgICBib2R5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdrZXlzJyk7XG4gICAgICAgICAgYm9keS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnbScpO1xuICAgICAgICAgIGJvZHkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ24nKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuICAgICAgYXdhaXQgd2FsbGV0cy5hZGQoe1xuICAgICAgICBsYWJlbDogJ2xhYmVsJyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICB0eXBlOiAnaG90JyxcbiAgICAgICAga2V5czogW10sXG4gICAgICAgIG06IDIsXG4gICAgICAgIG46IDMsXG4gICAgICAgIHVzZXJLZXk6ICd0ZXN0MTIzJyxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnR2VuZXJhdGUgd2FsbGV0OicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBzYW5kYm94ID0gc2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgcGFyYW1ldGVycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGxldCBwYXJhbXMgPSB7fTtcbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdNaXNzaW5nIHBhcmFtZXRlcjogbGFiZWwnKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGJhY2t1cFhwdWI6ICdiYWNrdXAnLFxuICAgICAgICBiYWNrdXBYcHViUHJvdmlkZXI6ICdwcm92aWRlcicsXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdDYW5ub3QgcHJvdmlkZSBtb3JlIHRoYW4gb25lIGJhY2t1cFhwdWIgb3IgYmFja3VwWHB1YlByb3ZpZGVyIGZsYWcnKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6IDEyMyxcbiAgICAgIH07XG4gICAgICBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgncGFzc2NvZGVFbmNyeXB0aW9uQ29kZSBtdXN0IGJlIGEgc3RyaW5nJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBlbnRlcnByaXNlOiAxMjM0LFxuICAgICAgfTtcbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGVudGVycHJpc2UgYXJndW1lbnQsIGV4cGVjdGluZyBzdHJpbmcnKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGRpc2FibGVUcmFuc2FjdGlvbk5vdGlmaWNhdGlvbnM6ICdzdHJpbmcnLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBkaXNhYmxlVHJhbnNhY3Rpb25Ob3RpZmljYXRpb25zIGFyZ3VtZW50LCBleHBlY3RpbmcgYm9vbGVhbicpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZ2FzUHJpY2U6ICdzdHJpbmcnLFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBnYXMgcHJpY2UgYXJndW1lbnQsIGV4cGVjdGluZyBudW1iZXIgb3IgbnVtYmVyIGFzIHN0cmluZycpO1xuXG4gICAgICBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnYWJjJyxcbiAgICAgICAgZ2FzUHJpY2U6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGdhcyBwcmljZSBhcmd1bWVudCwgZXhwZWN0aW5nIG51bWJlciBvciBudW1iZXIgYXMgc3RyaW5nJyk7XG5cbiAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdhYmMnLFxuICAgICAgICBnYXNQcmljZTogMTIzLFxuICAgICAgICBlaXAxNTU5OiB7XG4gICAgICAgICAgbWF4RmVlUGVyR2FzOiAxMjM0LFxuICAgICAgICAgIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMjMsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnY2FuIG5vdCB1c2UgYm90aCBlaXAxNTU5IGFuZCBnYXNQcmljZSB2YWx1ZXMnKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6ICdxMTIzNCcsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6ICcxMjMnLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnaW52YWxpZCBtYXggZmVlIGFyZ3VtZW50LCBleHBlY3RpbmcgbnVtYmVyIG9yIG51bWJlciBhcyBzdHJpbmcnKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6IDEyMzQsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6ICcxMjNhJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgLmdlbmVyYXRlV2FsbGV0KHBhcmFtcylcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2ludmFsaWQgcHJpb3JpdHkgZmVlIGFyZ3VtZW50LCBleHBlY3RpbmcgbnVtYmVyIG9yIG51bWJlciBhcyBzdHJpbmcnKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGRpc2FibGVLUlNFbWFpbDogJ3N0cmluZycsXG4gICAgICB9O1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldChwYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIGRpc2FibGVLUlNFbWFpbCBhcmd1bWVudCwgZXhwZWN0aW5nIGJvb2xlYW4nKTtcblxuICAgICAgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ2FiYycsXG4gICAgICAgIGtyc1NwZWNpZmljOiB7XG4gICAgICAgICAgbWFsaWNpb3VzOiB7XG4gICAgICAgICAgICBqYXZhc2NyaXB0OiB7XG4gICAgICAgICAgICAgIGNvZGU6ICdiYWQuanMnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aChcbiAgICAgICAgICAna3JzU3BlY2lmaWMgb2JqZWN0IGNvbnRhaW5zIGlsbGVnYWwgdmFsdWVzLiB2YWx1ZXMgbXVzdCBiZSBzdHJpbmdzLCBib29sZWFucywgb3IgbnVtYmVycydcbiAgICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IGRpc2FibGUga3JzIGVtYWlscyB3aGVuIGNyZWF0aW5nIGJhY2t1cCBrZXljaGFpbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnbXlfd2FsbGV0JyxcbiAgICAgICAgZGlzYWJsZUtSU0VtYWlsOiB0cnVlLFxuICAgICAgICBiYWNrdXBYcHViUHJvdmlkZXI6ICd0ZXN0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3Rlc3QxMjMnLFxuICAgICAgICB1c2VyS2V5OiAneHB1YjEyMycsXG4gICAgICB9O1xuXG4gICAgICAvLyBiaXRnbyBrZXlcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgc291cmNlOiAnYml0Z28nIH0pKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgLy8gdXNlciBrZXlcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5jb25mb3Jtcyh7IHB1YjogKHApID0+IHAuc3RhcnRzV2l0aCgneHB1YicpIH0pKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgLy8gYmFja3VwIGtleVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoXG4gICAgICAgICAgJy9hcGkvdjIvdGJ0Yy9rZXknLFxuICAgICAgICAgIF8ubWF0Y2hlcyh7XG4gICAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICAgICAgcHJvdmlkZXI6IHBhcmFtcy5iYWNrdXBYcHViUHJvdmlkZXIsXG4gICAgICAgICAgICBkaXNhYmxlS1JTRW1haWw6IHRydWUsXG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgLy8gd2FsbGV0XG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcpLnJlcGx5KDIwMCk7XG5cbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IHBhc3MgdGhyb3VnaCB0aGUga3JzU3BlY2lmaWMgcGFyYW0gd2hlbiBjcmVhdGluZyBiYWNrdXAga2V5Y2hhaW5zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICBsYWJlbDogJ215X3dhbGxldCcsXG4gICAgICAgIGJhY2t1cFhwdWJQcm92aWRlcjogJ3Rlc3QnLFxuICAgICAgICBwYXNzcGhyYXNlOiAndGVzdDEyMycsXG4gICAgICAgIHVzZXJLZXk6ICd4cHViMTIzJyxcbiAgICAgICAga3JzU3BlY2lmaWM6IHsgY292ZXJhZ2U6ICdpbnN1cmFuY2UnLCBleHBlbnNpdmU6IHRydWUsIGhvd0V4cGVuc2l2ZTogMjUgfSxcbiAgICAgIH07XG5cbiAgICAgIC8vIGJpdGdvIGtleVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyB1c2VyIGtleVxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLmNvbmZvcm1zKHsgcHViOiAocCkgPT4gcC5zdGFydHNXaXRoKCd4cHViJykgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyBiYWNrdXAga2V5XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdChcbiAgICAgICAgICAnL2FwaS92Mi90YnRjL2tleScsXG4gICAgICAgICAgXy5tYXRjaGVzKHtcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgICBwcm92aWRlcjogcGFyYW1zLmJhY2t1cFhwdWJQcm92aWRlcixcbiAgICAgICAgICAgIGtyc1NwZWNpZmljOiB7IGNvdmVyYWdlOiAnaW5zdXJhbmNlJywgZXhwZW5zaXZlOiB0cnVlLCBob3dFeHBlbnNpdmU6IDI1IH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgLy8gd2FsbGV0XG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcpLnJlcGx5KDIwMCk7XG5cbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2VuZCB0aGUgY29sZCBkZXJpdmF0aW9uIHNlZWQgZm9yIGEgdXNlciBrZXknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAnbXktY29sZC13YWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAndGVzdDEyMycsXG4gICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNGdFhnUzVzWUpBQnFxRzlZTG1DNFExUmRhcDlnU0U4TnF0d3liR2hlUFkyZ1oyOUVTRmpxSm9DdTFSdXBqZThZdEdxc2VmRDI2NVRNZzd1c1VERmRwNlcxRUdNY2V0OCcsXG4gICAgICAgIGNvbGREZXJpdmF0aW9uU2VlZDogJzEyMycsXG4gICAgICB9O1xuXG4gICAgICAvLyBiaXRnbyBrZXlcbiAgICAgIGNvbnN0IGJpdGdvS2V5Tm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgc291cmNlOiAnYml0Z28nIH0pKVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgLy8gdXNlciBrZXlcbiAgICAgIGNvbnN0IHVzZXJLZXlOb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoXG4gICAgICAgICAgJy9hcGkvdjIvdGJ0Yy9rZXknLFxuICAgICAgICAgIF8ubWF0Y2hlcyh7XG4gICAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBwYXJhbXMuY29sZERlcml2YXRpb25TZWVkLFxuICAgICAgICAgIH0pXG4gICAgICAgIClcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIGJhY2t1cCBrZXlcbiAgICAgIGNvbnN0IGJhY2t1cEtleU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JhY2t1cCcgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAvLyB3YWxsZXRcbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcpLnJlcGx5KDIwMCk7XG5cbiAgICAgIGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcbiAgICAgIGZvciAoY29uc3Qgc2NvcGUgb2YgW2JpdGdvS2V5Tm9jaywgdXNlcktleU5vY2ssIGJhY2t1cEtleU5vY2ssIHdhbGxldE5vY2tdKSB7XG4gICAgICAgIHNjb3BlLmRvbmUoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgY3VzdG9kaWFsIG9uY2hhaW4gd2FsbGV0IHdpdGhvdXQgcGFzc2luZyBtLCBuLCBrZXlzLCBrZXlTaWduYXR1cmVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAndGVzdCB3YWxsZXQnLFxuICAgICAgICBlbnRlcnByaXNlOiAnbXllbnRlcnByaXNlJyxcbiAgICAgICAgdHlwZTogJ2N1c3RvZGlhbCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnR5cGUuc2hvdWxkLmVxdWFsKCdjdXN0b2RpYWwnKTtcbiAgICAgICAgICBzaG91bGQubm90LmV4aXN0KGJvZHkubSk7XG4gICAgICAgICAgc2hvdWxkLm5vdC5leGlzdChib2R5Lm4pO1xuICAgICAgICAgIHNob3VsZC5ub3QuZXhpc3QoYm9keS5rZXlzKTtcbiAgICAgICAgICBzaG91bGQubm90LmV4aXN0KGJvZHkua2V5U2lnbmF0dXJlcyk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHsgaWQ6ICcxMjMnLCBiYXNlQ29pbjogYml0Z28uY29pbigndGJ0YycpLCBrZXlzOiBbJzEyMycsICc0NTYnLCAnNzg5J10gfSk7XG5cbiAgICAgIG5vY2soYmdVcmwpLmdldCgnL2FwaS92Mi90YnRjL2tleS8xMjMnKS5yZXBseSgyMDAsIHsgcHViOiAnYml0Z29QdWInLCBpZDogJzc4OScgfSk7XG4gICAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjIvdGJ0Yy9rZXkvNDU2JywgXy5tYXRjaGVzKHt9KSkucmVwbHkoMjAwKTtcbiAgICAgIG5vY2soYmdVcmwpLmdldCgnL2FwaS92Mi90YnRjL2tleS83ODknKS5yZXBseSgyMDAsIHsgcHViOiAnYmFja3VwUHViJywgaWQ6ICc3ODknIH0pO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKTtcblxuICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSA9PT0gdW5kZWZpbmVkKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBob3Qgb25jaGFpbiB3YWxsZXQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXM6IEdlbmVyYXRlV2FsbGV0T3B0aW9ucyA9IHtcbiAgICAgICAgbGFiZWw6ICd0ZXN0IHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICdtdWx0aXNpZyBwYXNzd29yZCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy93YWxsZXQvYWRkJywgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICBib2R5LnR5cGUuc2hvdWxkLmVxdWFsKCdob3QnKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgc291cmNlOiAnYml0Z28nIH0pKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHB1YjogJ2JpdGdvUHViJyB9KTtcbiAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoe30pKS5yZXBseSgyMDApO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiYWNrdXAnIH0pKVxuICAgICAgICAucmVwbHkoMjAwLCB7IHB1YjogJ2JhY2t1cFB1YicgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UsIHBhc3N3b3JkOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSB9KSxcbiAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGhvdCBvbmNoYWluIHdhbGxldCB3aXRob3V0IHBhc3NpbmcgbXVsdGlzaWcgdHlwZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ3Rlc3Qgd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ211bHRpc2lnIHBhc3N3b3JkJyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHdhbGxldE5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL3dhbGxldC9hZGQnLCBmdW5jdGlvbiAoYm9keSkge1xuICAgICAgICAgIGJvZHkudHlwZS5zaG91bGQuZXF1YWwoJ2hvdCcpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KVxuICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLm1hdGNoZXMoeyBzb3VyY2U6ICdiaXRnbycgfSkpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgcHViOiAnYml0Z29QdWInIH0pO1xuICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7fSkpLnJlcGx5KDIwMCk7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JhY2t1cCcgfSkpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgcHViOiAnYmFja3VwUHViJyB9KTtcblxuICAgICAgY29uc3QgZ2VuZXJhdGVXYWxsZXRTcHkgPSBzYW5kYm94LnNweSh3YWxsZXRzLCAnZ2VuZXJhdGVXYWxsZXQnKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuICAgICAgd2FsbGV0Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgc2lub24uYXNzZXJ0LmNhbGxlZE9uY2UoZ2VuZXJhdGVXYWxsZXRTcHkpO1xuICAgICAgYXNzZXJ0LmVxdWFsKGdlbmVyYXRlV2FsbGV0U3B5LmZpcnN0Q2FsbD8uYXJnc1swXT8ubXVsdGlzaWdUeXBlLCBtdWx0aXNpZ1R5cGVzLm9uY2hhaW4pO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgIGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlIH0pLFxuICAgICAgICBwYXJhbXMucGFzc3BocmFzZVxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIFRTUyB3YWxsZXQ6JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHRzb2wgPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgY29uc3Qgc2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLmdldChgL2FwaS92Mi90c3Mvc2V0dGluZ3NgKVxuICAgICAgICAudGltZXMoMilcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGNvaW5TZXR0aW5nczoge1xuICAgICAgICAgICAgZXRoOiB7XG4gICAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJzYzoge1xuICAgICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwb2x5Z29uOiB7XG4gICAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICBzYW5kYm94LnZlcmlmeUFuZFJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbmV3IFRTUyB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBzYW5kYm94LnN0dWIoVHNzVXRpbHMucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJykucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucG9zdCgnL2FwaS92Mi90c29sL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGFueSxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UsIHBhc3N3b3JkOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSB9KSxcbiAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBUU1Mgd2FsbGV0IHdpdGhvdXQgcGFzc2luZyBtdWx0aXNpZyB0eXBlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc3R1YmJlZEtleWNoYWluc1RyaXBsZXQ6IEtleWNoYWluc1RyaXBsZXQgPSB7XG4gICAgICAgIHVzZXJLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgfSxcbiAgICAgICAgYmFja3VwS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgIHB1YjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICdpbmRlcGVuZGVudCcsXG4gICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgfSxcbiAgICAgICAgYml0Z29LZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgc2FuZGJveC5zdHViKFRzc1V0aWxzLnByb3RvdHlwZSwgJ2NyZWF0ZUtleWNoYWlucycpLnJlc29sdmVzKHN0dWJiZWRLZXljaGFpbnNUcmlwbGV0KTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3Rzb2wvd2FsbGV0L2FkZCcsIGZ1bmN0aW9uIChib2R5KSB7XG4gICAgICAgICAgYm9keS5tdWx0aXNpZ1R5cGUuc2hvdWxkLmVxdWFsKG11bHRpc2lnVHlwZXMudHNzKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdHNvbCk7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBnZW5lcmF0ZVdhbGxldFNweSA9IHNhbmRib3guc3B5KHdhbGxldHMsICdnZW5lcmF0ZVdhbGxldCcpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG4gICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkT25jZShnZW5lcmF0ZVdhbGxldFNweSk7XG4gICAgICBhc3NlcnQuZXF1YWwoZ2VuZXJhdGVXYWxsZXRTcHkuZmlyc3RDYWxsPy5hcmdzWzBdPy5tdWx0aXNpZ1R5cGUsIG11bHRpc2lnVHlwZXMudHNzKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlKTtcbiAgICAgIGFzc2VydC5vayhyZXNwb25zZS53YWxsZXQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICBiaXRnby5kZWNyeXB0KHsgaW5wdXQ6IHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UsIHBhc3N3b3JkOiBwYXJhbXMucGFzc2NvZGVFbmNyeXB0aW9uQ29kZSB9KSxcbiAgICAgICAgcGFyYW1zLnBhc3NwaHJhc2VcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIG5ldyBUU1Mgd2FsbGV0IHdpdGhvdXQgcHJvdmlkaW5nIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgdHlwZTogJ2luZGVwZW5kZW50JyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBwdWI6ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAnaW5kZXBlbmRlbnQnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBzYW5kYm94LnN0dWIoVHNzVXRpbHMucHJvdG90eXBlLCAnY3JlYXRlS2V5Y2hhaW5zJykucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucG9zdCgnL2FwaS92Mi90c29sL3dhbGxldC9hZGQnKS5yZXBseSgyMDApO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQoe1xuICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICBwYXNzcGhyYXNlOiAndHNzIHBhc3N3b3JkJyxcbiAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgZW50ZXJwcmlzZTogJ2VudGVycHJpc2UnLFxuICAgICAgfSk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLndhbGxldCk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSA9PT0gdW5kZWZpbmVkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBjcmVhdGUgVFNTIHdhbGxldCB3aXRoIGludmFsaWQgaW5wdXRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGJ0YyA9IGJpdGdvLmNvaW4oJ3RidGMnKTtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgbGFiZWw6ICdteS1jb2xkLXdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0ZXN0MTIzJyxcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0Z0WGdTNXNZSkFCcXFHOVlMbUM0UTFSZGFwOWdTRThOcXR3eWJHaGVQWTJnWjI5RVNGanFKb0N1MVJ1cGplOFl0R3FzZWZEMjY1VE1nN3VzVURGZHA2VzFFR01jZXQ4JyxcbiAgICAgICAgY29sZERlcml2YXRpb25TZWVkOiAnMTIzJyxcbiAgICAgIH07XG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRidGMpO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JpdGdvJyB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KCcvYXBpL3YyL3RidGMva2V5JywgXy5tYXRjaGVzKHsgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogcGFyYW1zLmNvbGREZXJpdmF0aW9uU2VlZCB9KSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90YnRjL2tleScsIF8ubWF0Y2hlcyh7IHNvdXJjZTogJ2JhY2t1cCcgfSkpXG4gICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YyL3RidGMvd2FsbGV0L2FkZCcpLnJlcGx5KDIwMCk7XG5cbiAgICAgIC8vIGNyZWF0ZSBhIG5vbiB0c3Mgd2FsbGV0IGZvciBjb2luIHRoYXQgZG9lc24ndCBzdXBwb3J0IHRzcyBldmVuIHRob3VnaCBtdWx0aXNpZ1R5cGUgaXMgc2V0IHRvIHRzc1xuICAgICAgYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldCh7IC4uLnBhcmFtcywgbXVsdGlzaWdUeXBlOiAndHNzJyB9KTtcblxuICAgICAgY29uc3QgdHNvbFdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdHNvbCk7XG5cbiAgICAgIGF3YWl0IHRzb2xXYWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgICAgbGFiZWw6ICd0c3MgY29sZCB3YWxsZXQnLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICdwYXNzcGhyYXNlJyxcbiAgICAgICAgICB1c2VyS2V5OiAndXNlciBrZXknLFxuICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdlbnRlcnByaXNlIGlzIHJlcXVpcmVkIGZvciBUU1Mgd2FsbGV0Jyk7XG5cbiAgICAgIGF3YWl0IHRzb2xXYWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh7XG4gICAgICAgICAgbGFiZWw6ICd0c3MgY29sZCB3YWxsZXQnLFxuICAgICAgICAgIHVzZXJLZXk6ICd1c2VyIGtleScsXG4gICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyxcbiAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZUlkJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ2Nhbm5vdCBnZW5lcmF0ZSBUU1Mga2V5cyB3aXRob3V0IHBhc3NwaHJhc2UnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbmV3IFRTUyBjdXN0b2RpYWwgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5cyA9IFsnMScsICcyJywgJzMnXTtcblxuICAgICAgY29uc3Qgd2FsbGV0UGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgdHlwZTogJ2N1c3RvZGlhbCcsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC93YWxsZXQvYWRkJylcbiAgICAgICAgLnRpbWVzKDEpXG4gICAgICAgIC5yZXBseSgyMDAsIHsgLi4ud2FsbGV0UGFyYW1zLCBrZXlzIH0pO1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHdhbGxldFBhcmFtcyk7XG4gICAgICBpZiAoIWlzV2FsbGV0V2l0aEtleWNoYWlucyhyZXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignd2FsbGV0IG1pc3NpbmcgcmVxdWlyZWQga2V5Y2hhaW5zJyk7XG4gICAgICB9XG4gICAgICByZXMud2FsbGV0LmxhYmVsKCkuc2hvdWxkLmVxdWFsKHdhbGxldFBhcmFtcy5sYWJlbCk7XG4gICAgICBzaG91bGQuZXF1YWwocmVzLndhbGxldC50eXBlKCksIHdhbGxldFBhcmFtcy50eXBlKTtcbiAgICAgIHJlcy53YWxsZXQudG9KU09OKCkuZW50ZXJwcmlzZS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLmVudGVycHJpc2UpO1xuICAgICAgcmVzLndhbGxldC5tdWx0aXNpZ1R5cGUoKS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLm11bHRpc2lnVHlwZSk7XG4gICAgICByZXMudXNlcktleWNoYWluLmlkLnNob3VsZC5lcXVhbChrZXlzWzBdKTtcbiAgICAgIHJlcy5iYWNrdXBLZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1sxXSk7XG4gICAgICByZXMuYml0Z29LZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1syXSk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgbmV3IFRTUyBTTUMgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29tbW9uS2V5Y2hhaW4gPSAnbG9uZ3N0cmluZyc7XG4gICAgICBjb25zdCBzZWVkID0gJ3NlZWQnO1xuICAgICAgY29uc3Qga2V5czogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBzZWVkLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogc2VlZCxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBiaXRnb0tleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKS5nZXQoJy9hcGkvdjIvdHNvbC9rZXkvMycpLnJlcGx5KDIwMCwga2V5cy5iaXRnb0tleWNoYWluKTtcbiAgICAgIGNvbnN0IHVzZXJLZXlFeHBlY3RlZEJvZHkgPSB7XG4gICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICBrZXlUeXBlOiAndHNzJyxcbiAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHNlZWQsXG4gICAgICB9O1xuICAgICAgY29uc3QgdXNlcktleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90c29sL2tleScsIHVzZXJLZXlFeHBlY3RlZEJvZHkpXG4gICAgICAgIC5yZXBseSgyMDAsIGtleXMudXNlcktleWNoYWluKTtcbiAgICAgIGNvbnN0IGJhY2t1cEtleUV4cGVjdGVkQm9keSA9IHtcbiAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAga2V5VHlwZTogJ3RzcycsXG4gICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBzZWVkLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGJhY2t1cEtleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAucG9zdCgnL2FwaS92Mi90c29sL2tleScsIGJhY2t1cEtleUV4cGVjdGVkQm9keSlcbiAgICAgICAgLnJlcGx5KDIwMCwga2V5cy5iYWNrdXBLZXljaGFpbik7XG5cbiAgICAgIGNvbnN0IHdhbGxldFBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgICAgYml0Z29LZXlJZDoga2V5cy5iaXRnb0tleWNoYWluLmlkLFxuICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgY29sZERlcml2YXRpb25TZWVkOiBzZWVkLFxuICAgICAgfTtcblxuICAgICAgY29uc3Qgd2FsbGV0Tm9ja0V4cGVjdGVkID0ge1xuICAgICAgICBsYWJlbDogd2FsbGV0UGFyYW1zLmxhYmVsLFxuICAgICAgICBtOiAyLFxuICAgICAgICBuOiAzLFxuICAgICAgICBrZXlzOiBba2V5cy51c2VyS2V5Y2hhaW4uaWQsIGtleXMuYmFja3VwS2V5Y2hhaW4uaWQsIGtleXMuYml0Z29LZXljaGFpbi5pZF0sXG4gICAgICAgIHR5cGU6IHdhbGxldFBhcmFtcy50eXBlLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6IHdhbGxldFBhcmFtcy5tdWx0aXNpZ1R5cGUsXG4gICAgICAgIGVudGVycHJpc2U6IHdhbGxldFBhcmFtcy5lbnRlcnByaXNlLFxuICAgICAgICB3YWxsZXRWZXJzaW9uOiB1bmRlZmluZWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdHNvbC93YWxsZXQvYWRkJywgd2FsbGV0Tm9ja0V4cGVjdGVkKVxuICAgICAgICAucmVwbHkoMjAwLCB7IC4uLndhbGxldE5vY2tFeHBlY3RlZCwgcmVzcG9uc2VUeXBlOiAnV2FsbGV0V2l0aEtleWNoYWlucycgfSk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdHNvbCk7XG5cbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQod2FsbGV0UGFyYW1zKTtcbiAgICAgIGlmICghaXNXYWxsZXRXaXRoS2V5Y2hhaW5zKHJlcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd3YWxsZXQgbWlzc2luZyByZXF1aXJlZCBrZXljaGFpbnMnKTtcbiAgICAgIH1cbiAgICAgIHJlcy5yZXNwb25zZVR5cGUuc2hvdWxkLmVxdWFsKCdXYWxsZXRXaXRoS2V5Y2hhaW5zJyk7XG4gICAgICByZXMud2FsbGV0LmxhYmVsKCkuc2hvdWxkLmVxdWFsKHdhbGxldFBhcmFtcy5sYWJlbCk7XG4gICAgICBzaG91bGQuZXF1YWwocmVzLndhbGxldC50eXBlKCksIHdhbGxldFBhcmFtcy50eXBlKTtcbiAgICAgIHJlcy53YWxsZXQudG9KU09OKCkuZW50ZXJwcmlzZS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLmVudGVycHJpc2UpO1xuICAgICAgcmVzLndhbGxldC5tdWx0aXNpZ1R5cGUoKS5zaG91bGQuZXF1YWwod2FsbGV0UGFyYW1zLm11bHRpc2lnVHlwZSk7XG4gICAgICByZXMudXNlcktleWNoYWluLnNob3VsZC5kZWVwRXF1YWwoa2V5cy51c2VyS2V5Y2hhaW4pO1xuICAgICAgcmVzLmJhY2t1cEtleWNoYWluLnNob3VsZC5kZWVwRXF1YWwoa2V5cy5iYWNrdXBLZXljaGFpbik7XG4gICAgICByZXMuYml0Z29LZXljaGFpbi5zaG91bGQuZGVlcEVxdWFsKGtleXMuYml0Z29LZXljaGFpbik7XG5cbiAgICAgIGJpdGdvS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgdXNlcktleU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIGJhY2t1cEtleU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgZm9yIFRTUyBTTUMgd2FsbGV0IGlmIHRoZSBiaXRnb0tleUlkIGlzIG5vdCBhIGJpdGdvIGtleSAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9ICdsb25nc3RyaW5nJztcbiAgICAgIGNvbnN0IHNlZWQgPSAnc2VlZCc7XG4gICAgICBjb25zdCBrZXlzOiBLZXljaGFpbnNUcmlwbGV0ID0ge1xuICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzEnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIGRlcml2ZWRGcm9tUGFyZW50V2l0aFNlZWQ6IHNlZWQsXG4gICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgIH0sXG4gICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcyJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiBzZWVkLFxuICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgIH0sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICBpZDogJzMnLFxuICAgICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGJpdGdvS2V5Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLmdldCgnL2FwaS92Mi90c29sL2tleS8xJykucmVwbHkoMjAwLCBrZXlzLnVzZXJLZXljaGFpbik7XG5cbiAgICAgIGNvbnN0IHdhbGxldFBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgICAgYml0Z29LZXlJZDoga2V5cy51c2VyS2V5Y2hhaW4uaWQsXG4gICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICBjb2xkRGVyaXZhdGlvblNlZWQ6IHNlZWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRzb2wpO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgIC5nZW5lcmF0ZVdhbGxldCh3YWxsZXRQYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdUaGUgcHJvdmlkZWQgYml0Z29LZXlJZCBpcyBub3QgYSBCaXRHbyBrZXljaGFpbicpO1xuXG4gICAgICBiaXRnb0tleU5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIFRTUyBNUEN2MiB3YWxsZXQ6JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRzc1NldHRpbmdzOiBUc3NTZXR0aW5ncyA9IHtcbiAgICAgICAgY29pblNldHRpbmdzOiB7XG4gICAgICAgICAgZXRoOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJzYzoge1xuICAgICAgICAgICAgd2FsbGV0Q3JlYXRpb25TZXR0aW5nczoge1xuICAgICAgICAgICAgICBtdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjb2xkTXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY3VzdG9kaWFsTXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwb2x5Z29uOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGF0b206IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY29sZE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGN1c3RvZGlhbE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGlhOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJlcmE6IHtcbiAgICAgICAgICAgIHdhbGxldENyZWF0aW9uU2V0dGluZ3M6IHtcbiAgICAgICAgICAgICAgbXVsdGlTaWdUeXBlVmVyc2lvbjogJ01QQ3YyJyxcbiAgICAgICAgICAgICAgY29sZE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGN1c3RvZGlhbE11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYXJiZXRoOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9wZXRoOiB7XG4gICAgICAgICAgICB3YWxsZXRDcmVhdGlvblNldHRpbmdzOiB7XG4gICAgICAgICAgICAgIG11bHRpU2lnVHlwZVZlcnNpb246ICdNUEN2MicsXG4gICAgICAgICAgICAgIGNvbGRNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgICBjdXN0b2RpYWxNdWx0aVNpZ1R5cGVWZXJzaW9uOiAnTVBDdjInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLmdldChgL2FwaS92Mi90c3Mvc2V0dGluZ3NgKS50aW1lcygyKS5yZXBseSgyMDAsIHRzc1NldHRpbmdzKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICBzYW5kYm94LnZlcmlmeUFuZFJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIFsnaHRldGgnLCAndGJzYycsICd0cG9seWdvbicsICd0dGlhJywgJ3RhdG9tJywgJ3RiZXJhJywgJ3RhcmJldGgnLCAndG9wZXRoJ10uZm9yRWFjaCgoY29pbikgPT4ge1xuICAgICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgJHtjb2lufSBUU1MgTVBDdjIgaG90IHdhbGxldGAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc3R1YkNyZWF0ZUtleWNoYWlucyA9IHNhbmRib3hcbiAgICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvYWRkYCkucmVwbHkoMjAwKTtcblxuICAgICAgICBjb25zdCB3YWxsZXRzID0gbmV3IFdhbGxldHMoYml0Z28sIHRlc3RDb2luKTtcblxuICAgICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgICBwYXNzcGhyYXNlOiAndHNzIHBhc3N3b3JkJyxcbiAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgc3R1YkNyZWF0ZUtleWNoYWlucy5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlIH0pLFxuICAgICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgJHtjb2lufSBUU1MgTVBDdjIgaG90IHdhbGxldCB3aXRob3V0IHBhc3NpbmcgbXVsdGlzaWcgdHlwZWAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgICB1c2VyS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMScsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJhY2t1cEtleWNoYWluOiB7XG4gICAgICAgICAgICBpZDogJzInLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJpdGdvS2V5Y2hhaW46IHtcbiAgICAgICAgICAgIGlkOiAnMycsXG4gICAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgICAgdHlwZTogJ3RzcycsXG4gICAgICAgICAgICBzb3VyY2U6ICdiaXRnbycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgc3R1YkNyZWF0ZUtleWNoYWlucyA9IHNhbmRib3hcbiAgICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAgIC5yZXNvbHZlcyhzdHViYmVkS2V5Y2hhaW5zVHJpcGxldCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvYWRkYCwgZnVuY3Rpb24gKGJvZHkpIHtcbiAgICAgICAgICAgIGJvZHkubXVsdGlzaWdUeXBlLnNob3VsZC5lcXVhbChtdWx0aXNpZ1R5cGVzLnRzcyk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBsYWJlbDogJ3RzcyB3YWxsZXQnLFxuICAgICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpO1xuXG4gICAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgc3R1YkNyZWF0ZUtleWNoYWlucy5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG5cbiAgICAgICAgYXNzZXJ0Lm9rKHJlc3BvbnNlLmVuY3J5cHRlZFdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIGJpdGdvLmRlY3J5cHQoeyBpbnB1dDogcmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSwgcGFzc3dvcmQ6IHBhcmFtcy5wYXNzY29kZUVuY3J5cHRpb25Db2RlIH0pLFxuICAgICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgJHtjb2lufSBUU1MgTVBDdjIgY29sZCB3YWxsZXRgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHRlc3RDb2luID0gYml0Z28uY29pbihjb2luKTtcbiAgICAgICAgY29uc3QgYml0Z29LZXlJZCA9ICdrZXkxMjMnO1xuICAgICAgICBjb25zdCBjb21tb25LZXljaGFpbiA9ICcweGFiYyc7XG5cbiAgICAgICAgY29uc3QgYml0Z29LZXlOb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyLyR7Y29pbn0va2V5LyR7Yml0Z29LZXlJZH1gKVxuICAgICAgICAgIC50aW1lcygxKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGlkOiAna2V5MTIzJyxcbiAgICAgICAgICAgIHB1YjogJ2JpdGdvUHViJyxcbiAgICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgc291cmNlOiAnYml0Z28nLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdXNlcktleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7Y29pbn0va2V5YCwge1xuICAgICAgICAgICAgc291cmNlOiAndXNlcicsXG4gICAgICAgICAgICBrZXlUeXBlOiAndHNzJyxcbiAgICAgICAgICAgIGNvbW1vbktleWNoYWluLFxuICAgICAgICAgICAgZGVyaXZlZEZyb21QYXJlbnRXaXRoU2VlZDogJzM3JyxcbiAgICAgICAgICAgIGlzTVBDdjI6IHRydWUsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAudGltZXMoMSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBpZDogJ3VzZXJLZXkxMjMnLFxuICAgICAgICAgICAgcHViOiAndXNlclB1YicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGJhY2t1cEtleU5vY2sgPSBub2NrKCdodHRwczovL2JpdGdvLmZha2V1cmwnKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyLyR7Y29pbn0va2V5YCwge1xuICAgICAgICAgICAgc291cmNlOiAnYmFja3VwJyxcbiAgICAgICAgICAgIGtleVR5cGU6ICd0c3MnLFxuICAgICAgICAgICAgY29tbW9uS2V5Y2hhaW4sXG4gICAgICAgICAgICBkZXJpdmVkRnJvbVBhcmVudFdpdGhTZWVkOiAnMzcnLFxuICAgICAgICAgICAgaXNNUEN2MjogdHJ1ZSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aW1lcygxKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGlkOiAnYmFja3VwS2V5MTIzJyxcbiAgICAgICAgICAgIHB1YjogJ2JhY2t1cFB1YicsXG4gICAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICAgIHNvdXJjZTogJ2JhY2t1cCcsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0Tm9jayA9IG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvJHtjb2lufS93YWxsZXQvYWRkYCwge1xuICAgICAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgICAgIG06IDIsXG4gICAgICAgICAgICBuOiAzLFxuICAgICAgICAgICAga2V5czogWyd1c2VyS2V5MTIzJywgJ2JhY2t1cEtleTEyMycsICdrZXkxMjMnXSxcbiAgICAgICAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgICAgICAgIG11bHRpc2lnVHlwZTogJ3RzcycsXG4gICAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgY29uc3Qgd2FsbGV0cyA9IG5ldyBXYWxsZXRzKGJpdGdvLCB0ZXN0Q29pbik7XG5cbiAgICAgICAgY29uc3QgcGFyYW1zOiBHZW5lcmF0ZVdhbGxldE9wdGlvbnMgPSB7XG4gICAgICAgICAgbGFiZWw6ICd0c3Mgd2FsbGV0JyxcbiAgICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICAgIGVudGVycHJpc2U6ICdlbnRlcnByaXNlJyxcbiAgICAgICAgICBwYXNzY29kZUVuY3J5cHRpb25Db2RlOiAnb3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlJyxcbiAgICAgICAgICB3YWxsZXRWZXJzaW9uOiA1LFxuICAgICAgICAgIHR5cGU6ICdjb2xkJyxcbiAgICAgICAgICBiaXRnb0tleUlkOiAna2V5MTIzJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJzB4YWJjJyxcbiAgICAgICAgICBjb2xkRGVyaXZhdGlvblNlZWQ6ICczNycsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSAoYXdhaXQgd2FsbGV0cy5nZW5lcmF0ZVdhbGxldChwYXJhbXMpKSBhcyBXYWxsZXRXaXRoS2V5Y2hhaW5zO1xuXG4gICAgICAgIGJpdGdvS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICB1c2VyS2V5Tm9jay5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICBiYWNrdXBLZXlOb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgICBzaG91bGQuZXhpc3QocmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLnVzZXJLZXljaGFpbik7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXNwb25zZS5iYWNrdXBLZXljaGFpbik7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXNwb25zZS5iaXRnb0tleWNoYWluKTtcbiAgICAgICAgcmVzcG9uc2UucmVzcG9uc2VUeXBlLnNob3VsZC5lcXVhbCgnV2FsbGV0V2l0aEtleWNoYWlucycpO1xuICAgICAgICByZXNwb25zZS51c2VyS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKCd1c2VyS2V5MTIzJyk7XG4gICAgICAgIHJlc3BvbnNlLmJhY2t1cEtleWNoYWluLmlkLnNob3VsZC5lcXVhbCgnYmFja3VwS2V5MTIzJyk7XG4gICAgICAgIHJlc3BvbnNlLmJpdGdvS2V5Y2hhaW4uaWQuc2hvdWxkLmVxdWFsKCdrZXkxMjMnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdChgc2hvdWxkIGNyZWF0ZSBhIG5ldyAke2NvaW59IFRTUyBNUEN2MiBjdXN0b2R5IHdhbGxldGAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdGVzdENvaW4gPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgICBjb25zdCBrZXlzID0gWyd1c2VyS2V5JywgJ2JhY2t1cEtleScsICdiaXRnb0tleSddO1xuXG4gICAgICAgIGNvbnN0IHBhcmFtczogR2VuZXJhdGVXYWxsZXRPcHRpb25zID0ge1xuICAgICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgICAgcGFzc3BocmFzZTogJ3RzcyBwYXNzd29yZCcsXG4gICAgICAgICAgbXVsdGlzaWdUeXBlOiAndHNzJyBhcyBjb25zdCxcbiAgICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgICAgcGFzc2NvZGVFbmNyeXB0aW9uQ29kZTogJ29yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZScsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogNSxcbiAgICAgICAgICB0eXBlOiAnY3VzdG9kaWFsJyxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgICAucG9zdChgL2FwaS92Mi8ke2NvaW59L3dhbGxldC9hZGRgKVxuICAgICAgICAgIC50aW1lcygxKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHsgLi4ucGFyYW1zLCBrZXlzIH0pO1xuXG4gICAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gKGF3YWl0IHdhbGxldHMuZ2VuZXJhdGVXYWxsZXQocGFyYW1zKSkgYXMgV2FsbGV0V2l0aEtleWNoYWlucztcblxuICAgICAgICB3YWxsZXROb2NrLmlzRG9uZSgpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXNwb25zZS53YWxsZXQpO1xuICAgICAgICBzaG91bGQuZXhpc3QocmVzcG9uc2UudXNlcktleWNoYWluKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLmJhY2t1cEtleWNoYWluKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3BvbnNlLmJpdGdvS2V5Y2hhaW4pO1xuICAgICAgICByZXNwb25zZS5yZXNwb25zZVR5cGUuc2hvdWxkLmVxdWFsKCdXYWxsZXRXaXRoS2V5Y2hhaW5zJyk7XG4gICAgICAgIHJlc3BvbnNlLnVzZXJLZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1swXSk7XG4gICAgICAgIHJlc3BvbnNlLmJhY2t1cEtleWNoYWluLmlkLnNob3VsZC5lcXVhbChrZXlzWzFdKTtcbiAgICAgICAgcmVzcG9uc2UuYml0Z29LZXljaGFpbi5pZC5zaG91bGQuZXF1YWwoa2V5c1syXSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KGBzaG91bGQgY3JlYXRlIGEgbmV3IGh0ZXRoIFRTUyBNUEN2MiB3YWxsZXQgd2l0aCB3YWxsZXRWZXJzaW9uIDZgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdHViQ3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0L2FkZGAsIChib2R5KSA9PiB7XG4gICAgICAgICAgYm9keS53YWxsZXRWZXJzaW9uLnNob3VsZC5lcXVhbCg2KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICB3YWxsZXRWZXJzaW9uOiA2LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHN0dWJDcmVhdGVLZXljaGFpbnMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoYHNob3VsZCBjcmVhdGUgYSBuZXcgTVBDdjIgd2FsbGV0IHdpdGggdmVyc2lvbiA1IGlmIHdhbGxldFZlcnNpb24gcGFzc2VkIGlzIG5vdCA1IG9yIDZgLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0ZXN0Q29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBjb25zdCBzdHViYmVkS2V5Y2hhaW5zVHJpcGxldDogS2V5Y2hhaW5zVHJpcGxldCA9IHtcbiAgICAgICAgdXNlcktleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICcxJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrdXBLZXljaGFpbjoge1xuICAgICAgICAgIGlkOiAnMicsXG4gICAgICAgICAgY29tbW9uS2V5Y2hhaW46ICd1c2VyUHViJyxcbiAgICAgICAgICB0eXBlOiAndHNzJyxcbiAgICAgICAgICBzb3VyY2U6ICdiYWNrdXAnLFxuICAgICAgICB9LFxuICAgICAgICBiaXRnb0tleWNoYWluOiB7XG4gICAgICAgICAgaWQ6ICczJyxcbiAgICAgICAgICBjb21tb25LZXljaGFpbjogJ3VzZXJQdWInLFxuICAgICAgICAgIHR5cGU6ICd0c3MnLFxuICAgICAgICAgIHNvdXJjZTogJ2JpdGdvJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBzdHViQ3JlYXRlS2V5Y2hhaW5zID0gc2FuZGJveFxuICAgICAgICAuc3R1YihFQ0RTQVV0aWxzLkVjZHNhTVBDdjJVdGlscy5wcm90b3R5cGUsICdjcmVhdGVLZXljaGFpbnMnKVxuICAgICAgICAucmVzb2x2ZXMoc3R1YmJlZEtleWNoYWluc1RyaXBsZXQpO1xuXG4gICAgICBjb25zdCB3YWxsZXROb2NrID0gbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJylcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvaHRldGgvd2FsbGV0L2FkZGAsIChib2R5KSA9PiB7XG4gICAgICAgICAgYm9keS53YWxsZXRWZXJzaW9uLnNob3VsZC5lcXVhbCg1KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgIGNvbnN0IHdhbGxldHMgPSBuZXcgV2FsbGV0cyhiaXRnbywgdGVzdENvaW4pO1xuXG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIGxhYmVsOiAndHNzIHdhbGxldCcsXG4gICAgICAgIHBhc3NwaHJhc2U6ICd0c3MgcGFzc3dvcmQnLFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnIGFzIGNvbnN0LFxuICAgICAgICBlbnRlcnByaXNlOiAnZW50ZXJwcmlzZScsXG4gICAgICAgIHBhc3Njb2RlRW5jcnlwdGlvbkNvZGU6ICdvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGUnLFxuICAgICAgICB3YWxsZXRWZXJzaW9uOiAzLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB3YWxsZXRzLmdlbmVyYXRlV2FsbGV0KHBhcmFtcyk7XG5cbiAgICAgIHdhbGxldE5vY2suaXNEb25lKCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHN0dWJDcmVhdGVLZXljaGFpbnMuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICBhc3NlcnQub2socmVzcG9uc2UuZW5jcnlwdGVkV2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICBhc3NlcnQub2socmVzcG9uc2Uud2FsbGV0KTtcbiAgICAgIGFzc2VydC5lcXVhbChcbiAgICAgICAgYml0Z28uZGVjcnlwdCh7IGlucHV0OiByZXNwb25zZS5lbmNyeXB0ZWRXYWxsZXRQYXNzcGhyYXNlLCBwYXNzd29yZDogcGFyYW1zLnBhc3Njb2RlRW5jcnlwdGlvbkNvZGUgfSksXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2hhcmluZycsICgpID0+IHtcbiAgICBkZXNjcmliZSgnV2FsbGV0IHNoYXJlIHdoZXJlIGtleWNoYWluT3ZlcnJpZGVSZXF1aXJlZCBpcyBzZXQgdHJ1ZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNhbmRib3gudmVyaWZ5QW5kUmVzdG9yZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd3aGVuIHBhc3N3b3JkIG5vdCBwcm92aXZlZCB3ZSBzaG91bGQgcmVjZWl2ZSB2YWxpZGF0aW9uIGVycm9yJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfY2FzZV8xJztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgYWNjZXB0IHNoYXJlIGNhc2VcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5hY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWQ6IHNoYXJlSWQgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgndXNlclBhc3N3b3JkIHBhcmFtIG11c3QgYmUgcHJvdmlkZWQgdG8gZGVjcnlwdCBzaGFyZWQga2V5Jyk7XG4gICAgICAgIHdhbGxldFNoYXJlTm9jay5kb25lKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3doZW4gd2UgYWNjZXB0IHNoYXJlIGFuZCBmYWlsZWQgdG8gbWFrZSBjaGFuZ2VzLCByZXNoYXJlIHNob3VsZCBub3QgYmUgY2FsbGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBzaGFyZUlkID0gJ3Rlc3RfY2FzZV8yJztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5JZCA9ICd0ZXN0X2Nhc2VfMic7XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X2Nhc2VfMic7XG4gICAgICAgIC8vIGNyZWF0ZSBhIHVzZXIga2V5XG4gICAgICAgIGNvbnN0IGtleUNoYWluTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLmNvbmZvcm1zKHsgcHViOiAocCkgPT4gcC5zdGFydHNXaXRoKCd4cHViJykgfSkpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgKHVyaSwgcmVxdWVzdEJvZHkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7IGlkOiBrZXljaGFpbklkLCBlbmNyeXB0ZWRQcnY6IHJlcXVlc3RCb2R5WydlbmNyeXB0ZWRQcnYnXSwgcHViOiByZXF1ZXN0Qm9keVsncHViJ10gfTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZUluZm9Ob2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKGJvZHkud2FsbGV0U2hhcmVJZCAhPT0gc2hhcmVJZCB8fCBib2R5LnN0YXRlICE9PSAnYWNjZXB0ZWQnIHx8IGJvZHkua2V5SWQgIT09IGtleWNoYWluSWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IGZhbHNlIH0pO1xuXG4gICAgICAgIC8vIFN0dWIgd2FsbGV0IHNoYXJlIHdhbGxldCBtZXRob2RcbiAgICAgICAgY29uc3Qgd2FsbGV0U2hhcmVTdHViID0gc2FuZGJveC5zdHViKFdhbGxldC5wcm90b3R5cGUsICdzaGFyZVdhbGxldCcpLm9uQ2FsbCgwKS5yZXNvbHZlcygnc3VjY2VzcycpO1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHdhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgZmFsc2UpO1xuICAgICAgICBrZXlDaGFpbk5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRTaGFyZUluZm9Ob2NrLmRvbmUoKTtcbiAgICAgICAgYWNjZXB0U2hhcmVOb2NrLmRvbmUoKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWQsIGZhbHNlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnd2hlbiB3ZSBhY2NlcHQgc2hhcmUgYnV0IHN0YXRlIGlzIG5vdCB2YWxpZCwgcmVzaGFyZSBzaG91bGQgbm90IGJlIGNhbGxlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3Qgc2hhcmVJZCA9ICd0ZXN0X2Nhc2VfMyc7XG4gICAgICAgIGNvbnN0IGtleWNoYWluSWQgPSAndGVzdF9jYXNlXzMnO1xuICAgICAgICBjb25zdCB1c2VyUGFzc3dvcmQgPSAndGVzdF9jYXNlXzMnO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBhIHVzZXIga2V5XG4gICAgICAgIGNvbnN0IGtleUNoYWluTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLmNvbmZvcm1zKHsgcHViOiAocCkgPT4gcC5zdGFydHNXaXRoKCd4cHViJykgfSkpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgKHVyaSwgcmVxdWVzdEJvZHkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7IGlkOiBrZXljaGFpbklkLCBlbmNyeXB0ZWRQcnY6IHJlcXVlc3RCb2R5WydlbmNyeXB0ZWRQcnYnXSwgcHViOiByZXF1ZXN0Qm9keVsncHViJ10gfTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZUluZm9Ob2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAga2V5Y2hhaW5PdmVycmlkZVJlcXVpcmVkOiB0cnVlLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YCwgKGJvZHk6IGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKGJvZHkud2FsbGV0U2hhcmVJZCAhPT0gc2hhcmVJZCB8fCBib2R5LnN0YXRlICE9PSAnYWNjZXB0ZWQnIHx8IGJvZHkua2V5SWQgIT09IGtleWNoYWluSWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7IGNoYW5nZWQ6IHRydWUsIHN0YXRlOiAnbm90X2FjY2VwdGVkJyB9KTtcblxuICAgICAgICAvLyBTdHViIHdhbGxldCBzaGFyZSB3YWxsZXQgbWV0aG9kXG4gICAgICAgIGNvbnN0IHdhbGxldFNoYXJlU3R1YiA9IHNhbmRib3guc3R1YihXYWxsZXQucHJvdG90eXBlLCAnc2hhcmVXYWxsZXQnKS5vbkNhbGwoMCkucmVzb2x2ZXMoJ3N1Y2Nlc3MnKTtcblxuICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB3YWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgdXNlclBhc3N3b3JkIH0pO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLmNoYW5nZWQsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzLnN0YXRlLCAnbm90X2FjY2VwdGVkJyk7XG4gICAgICAgIGtleUNoYWluTm9jay5kb25lKCk7XG4gICAgICAgIHdhbGxldFNoYXJlSW5mb05vY2suZG9uZSgpO1xuICAgICAgICBhY2NlcHRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICBzaG91bGQuZXF1YWwod2FsbGV0U2hhcmVTdHViLmNhbGxlZCwgZmFsc2UpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCd3aGVuIHdlIGdldCBhIGNvcnJlY3QgcmVzcG9zbmUgZnJvbSBhY2NlcHQgc2hhcmUgbWV0aG9kLCBidXQgZmFpbGVkIHRvIHJlc2hhcmUgd2FsbGV0IHdpdGggc3BlbmRlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9jYXNlXzYnO1xuICAgICAgICBjb25zdCBrZXljaGFpbklkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3Qgc3BlbmRlclVzZXJPbmUgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV82JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzYnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfNicsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHNwZW5kZXJVc2VyVHdvID0ge1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHVzZXI6ICd0ZXN0X2Nhc2VfOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlbWFpbDogeyBlbWFpbDogJ3Rlc3RfY2FzZV85JyB9LFxuICAgICAgICAgIGlkOiAndGVzdF9jYXNlXzknLFxuICAgICAgICAgIGNvaW46ICdvZmMnLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBhZG1pblVzZXIgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV83JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzcnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfNycsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHZpZXdlclVzZXIgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV84JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzgnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfOCcsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X2Nhc2VfNic7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3QgZW50ZXJwcmlzZUlkID0gJ3Rlc3RfY2FzZV82JztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldElkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBhIHVzZXIga2V5XG4gICAgICAgIGNvbnN0IGtleUNoYWluQ3JlYXRlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLmNvbmZvcm1zKHsgcHViOiAocCkgPT4gcC5zdGFydHNXaXRoKCd4cHViJykgfSkpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgKHVyaSwgcmVxdWVzdEJvZHkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7IGlkOiBrZXljaGFpbklkLCBlbmNyeXB0ZWRQcnY6IHJlcXVlc3RCb2R5WydlbmNyeXB0ZWRQcnYnXSwgcHViOiByZXF1ZXN0Qm9keVsncHViJ10gfTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICAgIGlmIChib2R5LndhbGxldFNoYXJlSWQgIT09IHNoYXJlSWQgfHwgYm9keS5zdGF0ZSAhPT0gJ2FjY2VwdGVkJyB8fCBib2R5LmtleUlkICE9PSBrZXljaGFpbklkKSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRJbmZvTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi90YnRjL3dhbGxldC8ke3dhbGxldElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlcnM6IFtzcGVuZGVyVXNlck9uZS5wYXlsb2FkLCBzcGVuZGVyVXNlclR3by5wYXlsb2FkLCBhZG1pblVzZXIucGF5bG9hZCwgdmlld2VyVXNlci5wYXlsb2FkXSxcbiAgICAgICAgICAgIGVudGVycHJpc2U6IGVudGVycHJpc2VJZCxcbiAgICAgICAgICAgIGNvaW46IHNwZW5kZXJVc2VyT25lLmNvaW4sXG4gICAgICAgICAgICBpZDogd2FsbGV0SWQsXG4gICAgICAgICAgICBrZXlzOiBbe31dLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGVudGVycHJpc2VVc2VyTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS9lbnRlcnByaXNlLyR7ZW50ZXJwcmlzZUlkfS91c2VyYClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBhZG1pblVzZXJzOiBbXG4gICAgICAgICAgICAgIHsgaWQ6IHNwZW5kZXJVc2VyT25lLmlkLCBlbWFpbDogc3BlbmRlclVzZXJPbmUuZW1haWwgfSxcbiAgICAgICAgICAgICAgeyBpZDogc3BlbmRlclVzZXJUd28uaWQsIGVtYWlsOiBzcGVuZGVyVXNlclR3by5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiBhZG1pblVzZXIuaWQsIGVtYWlsOiBhZG1pblVzZXIuZW1haWwgfSxcbiAgICAgICAgICAgICAgeyBpZDogdmlld2VyVXNlci5pZCwgZW1haWw6IHZpZXdlclVzZXIuZW1haWwgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBub25BZG1pblVzZXJzOiBbXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZVN0dWIgPSBzYW5kYm94XG4gICAgICAgICAgLnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ3NoYXJlV2FsbGV0JylcbiAgICAgICAgICAucmV0dXJucyhuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIHJlamVjdCkgPT4gcmVqZWN0KG5ldyBFcnJvcignRmFpbGVkIHRvIHJlc2hhcmUgd2FsbGV0JykpKSk7XG5cbiAgICAgICAgY29uc3Qgc2hhcmVQYXJhbXNPbmUgPSB7XG4gICAgICAgICAgd2FsbGV0SWQ6IHdhbGxldElkLFxuICAgICAgICAgIHVzZXI6IHNwZW5kZXJVc2VyT25lLmlkLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBzcGVuZGVyVXNlck9uZS5wYXlsb2FkLnBlcm1pc3Npb25zLmpvaW4oJywnKSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB1c2VyUGFzc3dvcmQsXG4gICAgICAgICAgZW1haWw6IHNwZW5kZXJVc2VyT25lLmVtYWlsLmVtYWlsLFxuICAgICAgICAgIHJlc2hhcmU6IHRydWUsXG4gICAgICAgICAgc2tpcEtleWNoYWluOiBmYWxzZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBzaGFyZVBhcmFtc1R3byA9IHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0SWQsXG4gICAgICAgICAgdXNlcjogc3BlbmRlclVzZXJUd28uaWQsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IHNwZW5kZXJVc2VyVHdvLnBheWxvYWQucGVybWlzc2lvbnMuam9pbignLCcpLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHVzZXJQYXNzd29yZCxcbiAgICAgICAgICBlbWFpbDogc3BlbmRlclVzZXJUd28uZW1haWwuZW1haWwsXG4gICAgICAgICAgcmVzaGFyZTogdHJ1ZSxcbiAgICAgICAgICBza2lwS2V5Y2hhaW46IGZhbHNlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHdhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuc3RhdGUsICdhY2NlcHRlZCcpO1xuICAgICAgICBrZXlDaGFpbkNyZWF0ZU5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRJbmZvTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGVudGVycHJpc2VVc2VyTm9jay5kb25lKCk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh3YWxsZXRTaGFyZVN0dWIuY2FsbGVkT25jZSwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh3YWxsZXRTaGFyZVN0dWIuY2FsbGVkV2l0aChzaGFyZVBhcmFtc09uZSksIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwod2FsbGV0U2hhcmVTdHViLmNhbGxlZFdpdGgoc2hhcmVQYXJhbXNUd28pLCBmYWxzZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3doZW4gd2UgZ2V0IGEgY29ycmVjdCByZXNwb3NuZSBmcm9tIGFjY2VwdCBzaGFyZSBtZXRob2QgYW5kIHJlc2hhcmUgd2FsbGV0IHdpdGggc3BlbmRlcnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHNoYXJlSWQgPSAndGVzdF9jYXNlXzYnO1xuICAgICAgICBjb25zdCBrZXljaGFpbklkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3Qgc3BlbmRlclVzZXJPbmUgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV82JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzYnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfNicsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHNwZW5kZXJVc2VyVHdvID0ge1xuICAgICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJywgJ3ZpZXcnXSxcbiAgICAgICAgICAgIHVzZXI6ICd0ZXN0X2Nhc2VfOScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlbWFpbDogeyBlbWFpbDogJ3Rlc3RfY2FzZV85JyB9LFxuICAgICAgICAgIGlkOiAndGVzdF9jYXNlXzknLFxuICAgICAgICAgIGNvaW46ICdvZmMnLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBhZG1pblVzZXIgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnLCAndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV83JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzcnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfNycsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHZpZXdlclVzZXIgPSB7XG4gICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldyddLFxuICAgICAgICAgICAgdXNlcjogJ3Rlc3RfY2FzZV84JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGVtYWlsOiB7IGVtYWlsOiAndGVzdF9jYXNlXzgnIH0sXG4gICAgICAgICAgaWQ6ICd0ZXN0X2Nhc2VfOCcsXG4gICAgICAgICAgY29pbjogJ29mYycsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHVzZXJQYXNzd29yZCA9ICd0ZXN0X2Nhc2VfNic7XG4gICAgICAgIGNvbnN0IHdhbGxldElkID0gJ3Rlc3RfY2FzZV82JztcbiAgICAgICAgY29uc3QgZW50ZXJwcmlzZUlkID0gJ3Rlc3RfY2FzZV82JztcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy93YWxsZXRzaGFyZS8ke3NoYXJlSWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydhZG1pbicsICdzcGVuZCcsICd2aWV3J10sXG4gICAgICAgICAgICB3YWxsZXQ6IHdhbGxldElkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBhIHVzZXIga2V5XG4gICAgICAgIGNvbnN0IGtleUNoYWluQ3JlYXRlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGJ0Yy9rZXknLCBfLmNvbmZvcm1zKHsgcHViOiAocCkgPT4gcC5zdGFydHNXaXRoKCd4cHViJykgfSkpXG4gICAgICAgICAgLnJlcGx5KDIwMCwgKHVyaSwgcmVxdWVzdEJvZHkpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB7IGlkOiBrZXljaGFpbklkLCBlbmNyeXB0ZWRQcnY6IHJlcXVlc3RCb2R5WydlbmNyeXB0ZWRQcnYnXSwgcHViOiByZXF1ZXN0Qm9keVsncHViJ10gfTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBhY2NlcHRTaGFyZU5vY2sgPSBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIChib2R5OiBhbnkpID0+IHtcbiAgICAgICAgICAgIGlmIChib2R5LndhbGxldFNoYXJlSWQgIT09IHNoYXJlSWQgfHwgYm9keS5zdGF0ZSAhPT0gJ2FjY2VwdGVkJyB8fCBib2R5LmtleUlkICE9PSBrZXljaGFpbklkKSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnJlcGx5KDIwMCwgeyBjaGFuZ2VkOiB0cnVlLCBzdGF0ZTogJ2FjY2VwdGVkJyB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRJbmZvTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92Mi90YnRjL3dhbGxldC8ke3dhbGxldElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdXNlcnM6IFtzcGVuZGVyVXNlck9uZS5wYXlsb2FkLCBzcGVuZGVyVXNlclR3by5wYXlsb2FkLCBhZG1pblVzZXIucGF5bG9hZCwgdmlld2VyVXNlci5wYXlsb2FkXSxcbiAgICAgICAgICAgIGVudGVycHJpc2U6IGVudGVycHJpc2VJZCxcbiAgICAgICAgICAgIGNvaW46IHNwZW5kZXJVc2VyT25lLmNvaW4sXG4gICAgICAgICAgICBpZDogd2FsbGV0SWQsXG4gICAgICAgICAgICBrZXlzOiBbe31dLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGVudGVycHJpc2VVc2VyTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS9lbnRlcnByaXNlLyR7ZW50ZXJwcmlzZUlkfS91c2VyYClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBhZG1pblVzZXJzOiBbXG4gICAgICAgICAgICAgIHsgaWQ6IHNwZW5kZXJVc2VyT25lLmlkLCBlbWFpbDogc3BlbmRlclVzZXJPbmUuZW1haWwgfSxcbiAgICAgICAgICAgICAgeyBpZDogc3BlbmRlclVzZXJUd28uaWQsIGVtYWlsOiBzcGVuZGVyVXNlclR3by5lbWFpbCB9LFxuICAgICAgICAgICAgICB7IGlkOiBhZG1pblVzZXIuaWQsIGVtYWlsOiBhZG1pblVzZXIuZW1haWwgfSxcbiAgICAgICAgICAgICAgeyBpZDogdmlld2VyVXNlci5pZCwgZW1haWw6IHZpZXdlclVzZXIuZW1haWwgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBub25BZG1pblVzZXJzOiBbXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB3YWxsZXRTaGFyZVN0dWIgPSBzYW5kYm94XG4gICAgICAgICAgLnN0dWIoV2FsbGV0LnByb3RvdHlwZSwgJ3NoYXJlV2FsbGV0JylcbiAgICAgICAgICAucmV0dXJucyhuZXcgUHJvbWlzZSgocmVzb2x2ZSwgX3JlamVjdCkgPT4gcmVzb2x2ZSgnc3VjY2VzcycpKSk7XG5cbiAgICAgICAgY29uc3Qgc2hhcmVQYXJhbXNPbmUgPSB7XG4gICAgICAgICAgd2FsbGV0SWQ6IHdhbGxldElkLFxuICAgICAgICAgIHVzZXI6IHNwZW5kZXJVc2VyT25lLmlkLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBzcGVuZGVyVXNlck9uZS5wYXlsb2FkLnBlcm1pc3Npb25zLmpvaW4oJywnKSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB1c2VyUGFzc3dvcmQsXG4gICAgICAgICAgZW1haWw6IHNwZW5kZXJVc2VyT25lLmVtYWlsLmVtYWlsLFxuICAgICAgICAgIHJlc2hhcmU6IHRydWUsXG4gICAgICAgICAgc2tpcEtleWNoYWluOiBmYWxzZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBzaGFyZVBhcmFtc1R3byA9IHtcbiAgICAgICAgICB3YWxsZXRJZDogd2FsbGV0SWQsXG4gICAgICAgICAgdXNlcjogc3BlbmRlclVzZXJUd28uaWQsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IHNwZW5kZXJVc2VyVHdvLnBheWxvYWQucGVybWlzc2lvbnMuam9pbignLCcpLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHVzZXJQYXNzd29yZCxcbiAgICAgICAgICBlbWFpbDogc3BlbmRlclVzZXJUd28uZW1haWwuZW1haWwsXG4gICAgICAgICAgcmVzaGFyZTogdHJ1ZSxcbiAgICAgICAgICBza2lwS2V5Y2hhaW46IGZhbHNlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHdhbGxldHMuYWNjZXB0U2hhcmUoeyB3YWxsZXRTaGFyZUlkOiBzaGFyZUlkLCB1c2VyUGFzc3dvcmQgfSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuY2hhbmdlZCwgdHJ1ZSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXMuc3RhdGUsICdhY2NlcHRlZCcpO1xuICAgICAgICBrZXlDaGFpbkNyZWF0ZU5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRTaGFyZU5vY2suZG9uZSgpO1xuICAgICAgICB3YWxsZXRJbmZvTm9jay5kb25lKCk7XG4gICAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgICAgIGVudGVycHJpc2VVc2VyTm9jay5kb25lKCk7XG4gICAgICAgIHNob3VsZC5lcXVhbCh3YWxsZXRTaGFyZVN0dWIuY2FsbGVkVHdpY2UsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwod2FsbGV0U2hhcmVTdHViLmNhbGxlZFdpdGgoc2hhcmVQYXJhbXNPbmUpLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHdhbGxldFNoYXJlU3R1Yi5jYWxsZWRXaXRoKHNoYXJlUGFyYW1zVHdvKSwgdHJ1ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2hhcmUgYSB3YWxsZXQgdG8gdmlld2VyJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2hhcmVJZCA9ICcxMjMxMSc7XG5cbiAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi90YnRjL3dhbGxldHNoYXJlLyR7c2hhcmVJZH1gKS5yZXBseSgyMDAsIHt9KTtcbiAgICAgIGNvbnN0IGFjY2VwdFNoYXJlTm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5wb3N0KGAvYXBpL3YyL3RidGMvd2FsbGV0c2hhcmUvJHtzaGFyZUlkfWAsIHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCwgc3RhdGU6ICdhY2NlcHRlZCcgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge30pO1xuXG4gICAgICBhd2FpdCB3YWxsZXRzLmFjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZDogc2hhcmVJZCB9KTtcbiAgICAgIGFjY2VwdFNoYXJlTm9jay5kb25lKCk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnYnVsa0FjY2VwdFNoYXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgICBub2NrLnBlbmRpbmdNb2NrcygpLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHZhbGlkYXRpb24gZXJyb3IgZm9yIHVzZXJQYXNzd29yZCBlbXB0eSBzdHJpbmcnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa0FjY2VwdFNoYXJlKHsgd2FsbGV0U2hhcmVJZHM6IFtdLCB1c2VyTG9naW5QYXNzd29yZDogJycgfSlcbiAgICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnTWlzc2luZyBwYXJhbWV0ZXI6IHVzZXJMb2dpblBhc3N3b3JkJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBhc3NlcnRpb24gZXJyb3IgZm9yIGVtcHR5IHdhbGxldFNoYXJlSWRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtBY2NlcHRTaGFyZSh7IHdhbGxldFNoYXJlSWRzOiBbXSwgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnIH0pXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ25vIHdhbGxldFNoYXJlSWRzIGFyZSBwYXNzZWQnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBubyB2YWxpZCB3YWxsZXQgc2hhcmVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnZHVtbXlXYWxsZXRJZCcsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkczogWyc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkMSddLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ2ludmFsaWQgd2FsbGV0IHNoYXJlcyBwcm92aWRlZCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIG5vIHZhbGlkIHdhbGxldFNoYXJlcyB3aXRoIGtleWNoYWluJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnZHVtbXlXYWxsZXRJZCcsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBvdXRnb2luZzogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa0FjY2VwdFNoYXJlKHtcbiAgICAgICAgICAgIHdhbGxldFNoYXJlSWRzOiBbJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0J10sXG4gICAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogJ2R1bW15QDEyMycsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnaW52YWxpZCB3YWxsZXQgc2hhcmVzIHByb3ZpZGVkJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgZWNkaCBrZXljaGFpbiB1bmRlZmluZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICdkdW1teVdhbGxldElkJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgIHB1YjogJ3B1YicsXG4gICAgICAgICAgICAgICAgdG9QdWJLZXk6ICd0b1B1YktleScsXG4gICAgICAgICAgICAgICAgZnJvbVB1YktleTogJ2Zyb21QdWJLZXknLFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFBydicsXG4gICAgICAgICAgICAgICAgcGF0aDogJ3BhdGgnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgcHJ2OiAncHJpdmF0ZSBrZXknLFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkczogWyc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCddLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdkdW1teUAxMjMnLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoJ2VuY3J5cHRlZFhwcnYgd2FzIG5vdCBmb3VuZCBvbiBzaGFyaW5nIGtleWNoYWluJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBzdWNjZXNzZnVsbHkgYWNjZXB0IHNoYXJlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBmcm9tVXNlclBydiA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3Qga2V5Y2hhaW5UZXN0OiBPcHRpb25hbEtleWNoYWluRW5jcnlwdGVkS2V5ID0ge1xuICAgICAgICAgIGVuY3J5cHRlZFBydjogYml0Z28uZW5jcnlwdCh7IGlucHV0OiBmcm9tVXNlclBydi50b1N0cmluZygpLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdXNlclBydiA9IGRlY3J5cHRLZXljaGFpblByaXZhdGVLZXkoYml0Z28sIGtleWNoYWluVGVzdCwgd2FsbGV0UGFzc3BocmFzZSk7XG4gICAgICAgIGlmICghdXNlclBydikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRlY3J5cHQgdXNlciBrZXljaGFpbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdG9LZXljaGFpbiA9IHV0eG9MaWIuYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmZyb20oJ2RlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDInLCAnaGV4JykpO1xuICAgICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICAgIGNvbnN0IHB1YmtleSA9IHRvS2V5Y2hhaW4uZGVyaXZlUGF0aChwYXRoKS5wdWJsaWNLZXkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICAgIGNvbnN0IGVja2V5ID0gbWFrZVJhbmRvbUtleSgpO1xuICAgICAgICBjb25zdCBzZWNyZXQgPSBnZXRTaGFyZWRTZWNyZXQoZWNrZXksIEJ1ZmZlci5mcm9tKHB1YmtleSwgJ2hleCcpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IG5ld0VuY3J5cHRlZFBydiA9IGJpdGdvLmVuY3J5cHQoeyBwYXNzd29yZDogc2VjcmV0LCBpbnB1dDogdXNlclBydiB9KTtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KCcvYXBpL3YyL3dhbGxldHNoYXJlcycpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLFxuICAgICAgICAgICAgICAgIGlzVU1TSW5pdGlhdGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgICAgICAgZnJvbVB1YktleTogZWNrZXkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKSxcbiAgICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogbmV3RW5jcnlwdGVkUHJ2LFxuICAgICAgICAgICAgICAgICAgdG9QdWJLZXk6IHB1YmtleSxcbiAgICAgICAgICAgICAgICAgIHB1YjogcHVia2V5LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wdXQoJy9hcGkvdjIvd2FsbGV0c2hhcmVzL2FjY2VwdCcpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHdhbGxldFNoYXJlSWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IG15RWNkaEtleWNoYWluID0gYXdhaXQgYml0Z28ua2V5Y2hhaW5zKCkuY3JlYXRlKCk7XG4gICAgICAgIHNpbm9uLnN0dWIoYml0Z28sICdnZXRFQ0RIS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgICAgZW5jcnlwdGVkWHBydjogYml0Z28uZW5jcnlwdCh7IGlucHV0OiBteUVjZGhLZXljaGFpbi54cHJ2LCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcHJ2S2V5ID0gYml0Z28uZGVjcnlwdCh7XG4gICAgICAgICAgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgaW5wdXQ6IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpLnJldHVybnMocHJ2S2V5KTtcbiAgICAgICAgc2lub24uc3R1Yihtb2R1bGVCaXRnbywgJ2dldFNoYXJlZFNlY3JldCcpLnJlc29sdmVzKCdmYWtlU2hhcmVkU2VjcmV0Jyk7XG5cbiAgICAgICAgY29uc3Qgc2hhcmUgPSBhd2FpdCB3YWxsZXRzLmJ1bGtBY2NlcHRTaGFyZSh7XG4gICAgICAgICAgd2FsbGV0U2hhcmVJZHM6IFsnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnXSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwoc2hhcmUsIHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB3YWxsZXRTaGFyZUlkOiAnNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBtaXNzaW5nIHNoYXJlcyBwYXJhbWV0ZXInLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHt9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdNaXNzaW5nIHBhcmFtZXRlcjogc2hhcmVzJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBub24tYXJyYXkgc2hhcmVzIHBhcmFtZXRlcicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0c1xuICAgICAgICAgIC5idWxrVXBkYXRlV2FsbGV0U2hhcmUoeyBzaGFyZXM6ICdub3QtYW4tYXJyYXknIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0V4cGVjdGluZyBwYXJhbWV0ZXIgYXJyYXk6IHNoYXJlcyBidXQgZm91bmQgc3RyaW5nJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyB2YWxpZGF0aW9uIGVycm9yIGZvciBtaXNzaW5nIHdhbGxldFNoYXJlSWQgaW4gc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbeyBzdGF0dXM6ICdhY2NlcHQnIH1dIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ01pc3Npbmcgd2FsbGV0U2hhcmVJZCBpbiBzaGFyZScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3IgbWlzc2luZyBzdGF0dXMgaW4gc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnMTIzJyB9XSB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdNaXNzaW5nIHN0YXR1cyBpbiBzaGFyZScpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3IgaW52YWxpZCBzdGF0dXMgaW4gc2hhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnMTIzJywgc3RhdHVzOiAnaW52YWxpZCcgfV0gfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnSW52YWxpZCBzdGF0dXMgaW4gc2hhcmU6IGludmFsaWQuIE11c3QgYmUgZWl0aGVyIFwiYWNjZXB0XCIgb3IgXCJyZWplY3RcIicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3Igbm9uLXN0cmluZyB3YWxsZXRTaGFyZUlkJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7IHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogMTIzLCBzdGF0dXM6ICdhY2NlcHQnIH1dIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0V4cGVjdGluZyB3YWxsZXRTaGFyZUlkIHRvIGJlIGEgc3RyaW5nIGJ1dCBmb3VuZCBudW1iZXInKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IHZhbGlkYXRpb24gZXJyb3IgZm9yIG5vbi1zdHJpbmcgdXNlckxvZ2luUGFzc3dvcmQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnMTIzJywgc3RhdHVzOiAnYWNjZXB0JyB9XSwgdXNlckxvZ2luUGFzc3dvcmQ6IDEyMyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFeHBlY3RpbmcgcGFyYW1ldGVyIHN0cmluZzogdXNlckxvZ2luUGFzc3dvcmQgYnV0IGZvdW5kIG51bWJlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgdmFsaWRhdGlvbiBlcnJvciBmb3Igbm9uLXN0cmluZyBuZXdXYWxsZXRQYXNzcGhyYXNlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB3YWxsZXRzXG4gICAgICAgICAgLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgICBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICcxMjMnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6ICdwYXNzd29yZCcsXG4gICAgICAgICAgICBuZXdXYWxsZXRQYXNzcGhyYXNlOiAxMjMsXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnRXhwZWN0aW5nIHBhcmFtZXRlciBzdHJpbmc6IG5ld1dhbGxldFBhc3NwaHJhc2UgYnV0IGZvdW5kIG51bWJlcicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgYXNzZXJ0aW9uIGVycm9yIGZvciBlbXB0eSBzaGFyZXMgYXJyYXknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHsgc2hhcmVzOiBbXSB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdubyBzaGFyZXMgYXJlIHBhc3NlZCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIG5vIHZhbGlkIHdhbGxldCBzaGFyZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICc2NmEyMjlkYmRjY2RjZmI5NWI0NGZjMjc0NWE2MGJkNCcsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICdkdW1teVdhbGxldElkJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQxJywgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiAnZHVtbXlAMTIzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdpbnZhbGlkIHdhbGxldCBzaGFyZSBwcm92aWRlZDogNjZhMjI5ZGJkY2NkY2ZiOTViNDRmYzI3NDVhNjBiZDEnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBlY2RoIGtleWNoYWluIHVuZGVmaW5lZCB3aGVuIGFjY2VwdGluZyBzaGFyZSByZXF1aXJpbmcgZGVjcnlwdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0JyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ2R1bW15V2FsbGV0SWQnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgICAgcHViOiAncHViJyxcbiAgICAgICAgICAgICAgICB0b1B1YktleTogJ3RvUHViS2V5JyxcbiAgICAgICAgICAgICAgICBmcm9tUHViS2V5OiAnZnJvbVB1YktleScsXG4gICAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgICAgICAgICBwYXRoOiAncGF0aCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2dldEVDREhLZXljaGFpbicpLnJlc29sdmVzKHtcbiAgICAgICAgICBwcnY6ICdwcml2YXRlIGtleScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldHNcbiAgICAgICAgICAuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJzY2YTIyOWRiZGNjZGNmYjk1YjQ0ZmMyNzQ1YTYwYmQ0Jywgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiAnZHVtbXlAMTIzJyxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdlbmNyeXB0ZWRYcHJ2IHdhcyBub3QgZm91bmQgb24gc2hhcmluZyBrZXljaGFpbicpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc3VjY2Vzc2Z1bGx5IHVwZGF0ZSBzaGFyZXMgd2l0aCBib3RoIGFjY2VwdCBhbmQgcmVqZWN0IHN0YXR1c2VzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIHR3byBzaGFyZXNcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMScsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICdzaGFyZTInLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZzInLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDInLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3RcbiAgICAgICAgY29uc3QgYnVsa1VwZGF0ZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogWydzaGFyZTInXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFtcbiAgICAgICAgICAgIHsgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsIHN0YXR1czogJ2FjY2VwdCcgfSxcbiAgICAgICAgICAgIHsgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMicsIHN0YXR1czogJ3JlamVjdCcgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgdGhlIHJlc3VsdFxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHJlc3VsdCwge1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMiddLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3Qgd2FzIGNhbGxlZCB3aXRoIGNvcnJlY3QgcGFyYW1ldGVyc1xuICAgICAgICBidWxrVXBkYXRlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGNvbnN0IHVwZGF0ZVBhcmFtcyA9IGJ1bGtVcGRhdGVTdHViLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgICB1cGRhdGVQYXJhbXMuc2hvdWxkLmhhdmUubGVuZ3RoT2YoMik7XG5cbiAgICAgICAgLy8gU2Vjb25kIHBhcmFtIHNob3VsZCBiZSBmb3Igc2hhcmUyIHdpdGggcmVqZWN0IHN0YXR1c1xuICAgICAgICB1cGRhdGVQYXJhbXMuc2hvdWxkLmNvbnRhaW5EZWVwKFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkOiAnc2hhcmUyJyxcbiAgICAgICAgICAgIHN0YXR1czogJ3JlamVjdCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgc3BlY2lhbCBvdmVycmlkZSBjYXNlcyBhbmQgcmVzaGFyZSB3aXRoIHNwZW5kZXJzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG5cbiAgICAgICAgLy8gTW9jayBsaXN0U2hhcmVzVjIgdG8gcmV0dXJuIGEgc2hhcmUgd2l0aCBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWRcbiAgICAgICAgc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2xpc3RTaGFyZXNWMicpLnJlc29sdmVzKHtcbiAgICAgICAgICBpbmNvbWluZzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMScsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQxJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnYWRtaW4nLCAnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgICBrZXljaGFpbk92ZXJyaWRlUmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXR1cCBmb3IgdGhlIGJhc2VDb2luLmtleWNoYWlucygpLmNyZWF0ZVVzZXJLZXljaGFpblxuICAgICAgICBjb25zdCB1c2VyS2V5Y2hhaW4gPSB7XG4gICAgICAgICAgaWQ6ICdrZXkxJyxcbiAgICAgICAgICBwdWI6ICdwdWJLZXknLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogJ2VuY3J5cHRlZFByaXZhdGVLZXknLFxuICAgICAgICB9O1xuICAgICAgICBzaW5vbi5zdHViKHdhbGxldHMuYmFzZUNvaW4ua2V5Y2hhaW5zKCksICdjcmVhdGVVc2VyS2V5Y2hhaW4nKS5yZXNvbHZlcyh1c2VyS2V5Y2hhaW4pO1xuXG4gICAgICAgIC8vIE1vY2sgZGVjcnlwdCBhbmQgc2lnbk1lc3NhZ2VcbiAgICAgICAgc2lub24uc3R1YihiaXRnbywgJ2RlY3J5cHQnKS5yZXR1cm5zKCdkZWNyeXB0ZWRQcml2YXRlS2V5Jyk7XG4gICAgICAgIHNpbm9uLnN0dWIod2FsbGV0cy5iYXNlQ29pbiwgJ3NpZ25NZXNzYWdlJykucmVzb2x2ZXMoQnVmZmVyLmZyb20oJ3NpZ25hdHVyZScpKTtcblxuICAgICAgICAvLyBNb2NrIGdldEVDREhLZXljaGFpblxuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGVuY3J5cHRlZFhwcnY6ICdlbmNyeXB0ZWRYcHJ2JyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayBidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0XG4gICAgICAgIGNvbnN0IGJ1bGtVcGRhdGVTdHViID0gc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QnKS5yZXNvbHZlcyh7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayByZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzXG4gICAgICAgIGNvbnN0IHJlc2hhcmVTdHViID0gc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ3Jlc2hhcmVXYWxsZXRXaXRoU3BlbmRlcnMnKS5yZXNvbHZlcygpO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFt7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTEnLCBzdGF0dXM6ICdhY2NlcHQnIH1dLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgdGhlIHJlc3VsdFxuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHJlc3VsdCwge1xuICAgICAgICAgIGFjY2VwdGVkV2FsbGV0U2hhcmVzOiBbJ3NoYXJlMSddLFxuICAgICAgICAgIHJlamVjdGVkV2FsbGV0U2hhcmVzOiBbXSxcbiAgICAgICAgICB3YWxsZXRTaGFyZVVwZGF0ZUVycm9yczogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSBidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0IHdhcyBjYWxsZWRcbiAgICAgICAgYnVsa1VwZGF0ZVN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICAgIC8vIFZlcmlmeSByZXNoYXJlV2FsbGV0V2l0aFNwZW5kZXJzIHdhcyBjYWxsZWQgd2l0aCBjb3JyZWN0IHBhcmFtZXRlcnNcbiAgICAgICAgcmVzaGFyZVN0dWIuY2FsbGVkT25jZS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgICAgICByZXNoYXJlU3R1Yi5maXJzdENhbGwuYXJnc1swXS5zaG91bGQuZXF1YWwoJ3dhbGxldDEnKTtcbiAgICAgICAgcmVzaGFyZVN0dWIuZmlyc3RDYWxsLmFyZ3NbMV0uc2hvdWxkLmVxdWFsKHdhbGxldFBhc3NwaHJhc2UpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHNoYXJlcyB3aXRoIG5vIGtleWNoYWluIHRvIGRlY3J5cHQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gYSBzaGFyZSB3aXRoIG5vIGtleWNoYWluXG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICdzaGFyZTEnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MScsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayBidWxrVXBkYXRlV2FsbGV0U2hhcmVSZXF1ZXN0XG4gICAgICAgIGNvbnN0IGJ1bGtVcGRhdGVTdHViID0gc2lub24uc3R1YihXYWxsZXRzLnByb3RvdHlwZSwgJ2J1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QnKS5yZXNvbHZlcyh7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0cy5idWxrVXBkYXRlV2FsbGV0U2hhcmUoe1xuICAgICAgICAgIHNoYXJlczogW3sgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsIHN0YXR1czogJ2FjY2VwdCcgfV0sXG4gICAgICAgICAgdXNlckxvZ2luUGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGUgcmVzdWx0XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzdWx0LCB7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3Qgd2FzIGNhbGxlZCB3aXRoIGNvcnJlY3QgcGFyYW1ldGVyc1xuICAgICAgICBidWxrVXBkYXRlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGNvbnN0IHVwZGF0ZVBhcmFtcyA9IGJ1bGtVcGRhdGVTdHViLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgICB1cGRhdGVQYXJhbXMuc2hvdWxkLmhhdmUubGVuZ3RoT2YoMSk7XG5cbiAgICAgICAgLy8gUGFyYW0gc2hvdWxkIGJlIGZvciBzaGFyZTEgd2l0aCBhY2NlcHQgc3RhdHVzIGFuZCBubyBhZGRpdGlvbmFsIGZpZWxkc1xuICAgICAgICB1cGRhdGVQYXJhbXMuc2hvdWxkLmNvbnRhaW5EZWVwKFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB3YWxsZXRTaGFyZUlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgIHN0YXR1czogJ2FjY2VwdCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgc2hhcmVzIHdpdGgga2V5Y2hhaW4gcmVxdWlyaW5nIGRlY3J5cHRpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgICAgY29uc3QgcGF0aCA9ICdtLzk5OTk5OS8xLzEnO1xuXG4gICAgICAgIC8vIENyZWF0ZSB0ZXN0IGtleWNoYWluc1xuICAgICAgICBjb25zdCBmcm9tS2V5Y2hhaW4gPSB1dHhvTGliLmJpcDMyLmZyb21TZWVkKEJ1ZmZlci5mcm9tKCdkZWFkYmVlZjAxZGVhZGJlZWYwMWRlYWRiZWVmMDFkZWFkYmVlZjAxJywgJ2hleCcpKTtcbiAgICAgICAgY29uc3QgdG9LZXljaGFpbiA9IHV0eG9MaWIuYmlwMzIuZnJvbVNlZWQoQnVmZmVyLmZyb20oJ2RlYWRiZWVmMDJkZWFkYmVlZjAyZGVhZGJlZWYwMmRlYWRiZWVmMDInLCAnaGV4JykpO1xuXG4gICAgICAgIGNvbnN0IGZyb21QdWJLZXkgPSBmcm9tS2V5Y2hhaW4ucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgICAgY29uc3QgdG9QdWJLZXkgPSB0b0tleWNoYWluLmRlcml2ZVBhdGgocGF0aCkucHVibGljS2V5LnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgICAvLyBDcmVhdGUgZW5jcnlwdGVkIHByaXZhdGUga2V5XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsUHJpdktleSA9ICdvcmlnaW5hbFByaXZhdGVLZXknO1xuICAgICAgICBjb25zdCBzaGFyZWRTZWNyZXQgPSBnZXRTaGFyZWRTZWNyZXQoZnJvbUtleWNoYWluLCBCdWZmZXIuZnJvbSh0b1B1YktleSwgJ2hleCcpKS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUHJ2ID0gYml0Z28uZW5jcnlwdCh7XG4gICAgICAgICAgcGFzc3dvcmQ6IHNoYXJlZFNlY3JldCxcbiAgICAgICAgICBpbnB1dDogb3JpZ2luYWxQcml2S2V5LFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gYSBzaGFyZSB3aXRoIGtleWNoYWluXG4gICAgICAgIHNpbm9uLnN0dWIoV2FsbGV0cy5wcm90b3R5cGUsICdsaXN0U2hhcmVzVjInKS5yZXNvbHZlcyh7XG4gICAgICAgICAgaW5jb21pbmc6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaWQ6ICdzaGFyZTEnLFxuICAgICAgICAgICAgICBjb2luOiAndHNvbCcsXG4gICAgICAgICAgICAgIHdhbGxldExhYmVsOiAndGVzdGluZycsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MScsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgICBwdWI6IHRvUHViS2V5LFxuICAgICAgICAgICAgICAgIHRvUHViS2V5OiB0b1B1YktleSxcbiAgICAgICAgICAgICAgICBmcm9tUHViS2V5OiBmcm9tUHViS2V5LFxuICAgICAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZW5jcnlwdGVkUHJ2LFxuICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgb3V0Z29pbmc6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIGdldEVDREhLZXljaGFpblxuICAgICAgICBjb25zdCBteUVjZGhLZXljaGFpbiA9IGF3YWl0IGJpdGdvLmtleWNoYWlucygpLmNyZWF0ZSgpO1xuICAgICAgICBzaW5vbi5zdHViKGJpdGdvLCAnZ2V0RUNESEtleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogbXlFY2RoS2V5Y2hhaW4ueHBydiwgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldHVwIGRlY3J5cHQgYW5kIGVuY3J5cHQgc3R1YnNcbiAgICAgICAgY29uc3QgZGVjcnlwdFN0dWIgPSBzaW5vbi5zdHViKGJpdGdvLCAnZGVjcnlwdCcpO1xuICAgICAgICBkZWNyeXB0U3R1Yi5vbkZpcnN0Q2FsbCgpLnJldHVybnMobXlFY2RoS2V5Y2hhaW4ueHBydik7IC8vIEZvciBzaGFyaW5nIGtleWNoYWluXG4gICAgICAgIGRlY3J5cHRTdHViLm9uU2Vjb25kQ2FsbCgpLnJldHVybnMob3JpZ2luYWxQcml2S2V5KTsgLy8gRm9yIHdhbGxldCBrZXljaGFpblxuXG4gICAgICAgIGNvbnN0IGVuY3J5cHRTdHViID0gc2lub24uc3R1YihiaXRnbywgJ2VuY3J5cHQnKS5yZXR1cm5zKCduZXdFbmNyeXB0ZWRQcnYnKTtcblxuICAgICAgICAvLyBNb2NrIGdldFNoYXJlZFNlY3JldFxuICAgICAgICBzaW5vbi5zdHViKG1vZHVsZUJpdGdvLCAnZ2V0U2hhcmVkU2VjcmV0JykucmV0dXJucyhCdWZmZXIuZnJvbShzaGFyZWRTZWNyZXQpKTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3RcbiAgICAgICAgY29uc3QgYnVsa1VwZGF0ZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnXSxcbiAgICAgICAgICByZWplY3RlZFdhbGxldFNoYXJlczogW10sXG4gICAgICAgICAgd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXRzLmJ1bGtVcGRhdGVXYWxsZXRTaGFyZSh7XG4gICAgICAgICAgc2hhcmVzOiBbeyB3YWxsZXRTaGFyZUlkOiAnc2hhcmUxJywgc3RhdHVzOiAnYWNjZXB0JyB9XSxcbiAgICAgICAgICB1c2VyTG9naW5QYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBuZXdXYWxsZXRQYXNzcGhyYXNlOiAnbmV3UGFzc3BocmFzZScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGUgcmVzdWx0XG4gICAgICAgIGFzc2VydC5kZWVwRXF1YWwocmVzdWx0LCB7XG4gICAgICAgICAgYWNjZXB0ZWRXYWxsZXRTaGFyZXM6IFsnc2hhcmUxJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVmVyaWZ5IGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3Qgd2FzIGNhbGxlZCB3aXRoIGNvcnJlY3QgcGFyYW1ldGVyc1xuICAgICAgICBidWxrVXBkYXRlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGNvbnN0IHVwZGF0ZVBhcmFtcyA9IGJ1bGtVcGRhdGVTdHViLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgICB1cGRhdGVQYXJhbXMuc2hvdWxkLmhhdmUubGVuZ3RoT2YoMSk7XG5cbiAgICAgICAgLy8gUGFyYW0gc2hvdWxkIGJlIGZvciBzaGFyZTEgd2l0aCBhY2NlcHQgc3RhdHVzIGFuZCBlbmNyeXB0ZWRQcnZcbiAgICAgICAgdXBkYXRlUGFyYW1zLnNob3VsZC5jb250YWluRGVlcChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsXG4gICAgICAgICAgICBzdGF0dXM6ICdhY2NlcHQnLFxuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnbmV3RW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcblxuICAgICAgICAvLyBWZXJpZnkgZW5jcnlwdCB3YXMgY2FsbGVkIHdpdGggY29ycmVjdCBwYXJhbWV0ZXJzXG4gICAgICAgIGVuY3J5cHRTdHViLmNhbGxlZE9uY2Uuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgZW5jcnlwdFN0dWIuZmlyc3RDYWxsLmFyZ3NbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Bhc3N3b3JkJywgJ25ld1Bhc3NwaHJhc2UnKTtcbiAgICAgICAgZW5jcnlwdFN0dWIuZmlyc3RDYWxsLmFyZ3NbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lucHV0Jywgb3JpZ2luYWxQcml2S2V5KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSByZWplY3RlZCBwcm9taXNlcyBhbmQgYWRkIHRoZW0gdG8gd2FsbGV0U2hhcmVVcGRhdGVFcnJvcnMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcblxuICAgICAgICAvLyBNb2NrIGxpc3RTaGFyZXNWMiB0byByZXR1cm4gdHdvIHNoYXJlc1xuICAgICAgICBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnbGlzdFNoYXJlc1YyJykucmVzb2x2ZXMoe1xuICAgICAgICAgIGluY29taW5nOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUxJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmcnLFxuICAgICAgICAgICAgICBmcm9tVXNlcjogJ2R1bW15RnJvbVVzZXInLFxuICAgICAgICAgICAgICB0b1VzZXI6ICdkdW1teVRvVXNlcicsXG4gICAgICAgICAgICAgIHdhbGxldDogJ3dhbGxldDEnLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAgICBzdGF0ZTogJ2FjdGl2ZScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBpZDogJ3NoYXJlMicsXG4gICAgICAgICAgICAgIGNvaW46ICd0c29sJyxcbiAgICAgICAgICAgICAgd2FsbGV0TGFiZWw6ICd0ZXN0aW5nMicsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZHVtbXlGcm9tVXNlcicsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ2R1bW15VG9Vc2VyJyxcbiAgICAgICAgICAgICAgd2FsbGV0OiAnd2FsbGV0MicsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAgICAgIHN0YXRlOiAnYWN0aXZlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAnc2hhcmUzJyxcbiAgICAgICAgICAgICAgY29pbjogJ3Rzb2wnLFxuICAgICAgICAgICAgICB3YWxsZXRMYWJlbDogJ3Rlc3RpbmczJyxcbiAgICAgICAgICAgICAgZnJvbVVzZXI6ICdkdW1teUZyb21Vc2VyJyxcbiAgICAgICAgICAgICAgdG9Vc2VyOiAnZHVtbXlUb1VzZXInLFxuICAgICAgICAgICAgICB3YWxsZXQ6ICd3YWxsZXQzJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICAgICAgc3RhdGU6ICdhY3RpdmUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIG91dGdvaW5nOiBbXSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU3R1YiBwcm9jZXNzQWNjZXB0U2hhcmUgdG8gdGhyb3cgYW4gZXJyb3IgZm9yIHNoYXJlMlxuICAgICAgICAvLyBVc2luZyAnYXMgYW55JyB0byBieXBhc3MgVHlwZVNjcmlwdCdzIHByaXZhdGUgbWV0aG9kIHJlc3RyaWN0aW9uXG4gICAgICAgIGNvbnN0IHByb2Nlc3NBY2NlcHRTaGFyZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlIGFzIGFueSwgJ3Byb2Nlc3NBY2NlcHRTaGFyZScpO1xuICAgICAgICBwcm9jZXNzQWNjZXB0U2hhcmVTdHViXG4gICAgICAgICAgLndpdGhBcmdzKCdzaGFyZTEnLCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnkpXG4gICAgICAgICAgLnJlc29sdmVzKFt7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTEnLCBzdGF0dXM6ICdhY2NlcHQnIH1dKTtcbiAgICAgICAgcHJvY2Vzc0FjY2VwdFNoYXJlU3R1YlxuICAgICAgICAgIC53aXRoQXJncygnc2hhcmUyJywgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55KVxuICAgICAgICAgIC5yZWplY3RzKG5ldyBFcnJvcignRmFpbGVkIHRvIHByb2Nlc3Mgc2hhcmUyJykpO1xuICAgICAgICBwcm9jZXNzQWNjZXB0U2hhcmVTdHViXG4gICAgICAgICAgLndpdGhBcmdzKCdzaGFyZTMnLCBzaW5vbi5tYXRjaC5hbnksIHNpbm9uLm1hdGNoLmFueSwgc2lub24ubWF0Y2guYW55LCBzaW5vbi5tYXRjaC5hbnkpXG4gICAgICAgICAgLnJlc29sdmVzKFt7IHdhbGxldFNoYXJlSWQ6ICdzaGFyZTMnLCBzdGF0dXM6ICdhY2NlcHQnIH1dKTtcblxuICAgICAgICAvLyBNb2NrIGJ1bGtVcGRhdGVXYWxsZXRTaGFyZVJlcXVlc3QgdG8gcmV0dXJuIGEgcmVzcG9uc2VcbiAgICAgICAgY29uc3QgYnVsa1VwZGF0ZVN0dWIgPSBzaW5vbi5zdHViKFdhbGxldHMucHJvdG90eXBlLCAnYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCcpLnJlc29sdmVzKHtcbiAgICAgICAgICBhY2NlcHRlZFdhbGxldFNoYXJlczogWydzaGFyZTEnLCAnc2hhcmUzJ10sXG4gICAgICAgICAgcmVqZWN0ZWRXYWxsZXRTaGFyZXM6IFtdLFxuICAgICAgICAgIHdhbGxldFNoYXJlVXBkYXRlRXJyb3JzOiBbXSwgLy8gRW1wdHkgYXJyYXkgdGhhdCBzaG91bGQgYmUgcG9wdWxhdGVkXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHdhbGxldHMuYnVsa1VwZGF0ZVdhbGxldFNoYXJlKHtcbiAgICAgICAgICBzaGFyZXM6IFtcbiAgICAgICAgICAgIHsgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMScsIHN0YXR1czogJ2FjY2VwdCcgfSxcbiAgICAgICAgICAgIHsgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMicsIHN0YXR1czogJ2FjY2VwdCcgfSxcbiAgICAgICAgICAgIHsgd2FsbGV0U2hhcmVJZDogJ3NoYXJlMycsIHN0YXR1czogJ2FjY2VwdCcgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHVzZXJMb2dpblBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBWZXJpZnkgYnVsa1VwZGF0ZVdhbGxldFNoYXJlUmVxdWVzdCB3YXMgY2FsbGVkIHdpdGggb25seSB0aGUgc3VjY2Vzc2Z1bCBzaGFyZVxuICAgICAgICBidWxrVXBkYXRlU3R1Yi5jYWxsZWRPbmNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgIGNvbnN0IHVwZGF0ZVBhcmFtcyA9IGJ1bGtVcGRhdGVTdHViLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgICB1cGRhdGVQYXJhbXMuc2hvdWxkLmhhdmUubGVuZ3RoT2YoMik7XG4gICAgICAgIHVwZGF0ZVBhcmFtc1swXS53YWxsZXRTaGFyZUlkLnNob3VsZC5lcXVhbCgnc2hhcmUxJyk7XG4gICAgICAgIHVwZGF0ZVBhcmFtc1swXS5zdGF0dXMuc2hvdWxkLmVxdWFsKCdhY2NlcHQnKTtcbiAgICAgICAgdXBkYXRlUGFyYW1zWzFdLndhbGxldFNoYXJlSWQuc2hvdWxkLmVxdWFsKCdzaGFyZTMnKTtcbiAgICAgICAgdXBkYXRlUGFyYW1zWzFdLnN0YXR1cy5zaG91bGQuZXF1YWwoJ2FjY2VwdCcpO1xuXG4gICAgICAgIC8vIFZlcmlmeSB0aGUgcmVzdWx0IGNvbnRhaW5zIHRoZSBlcnJvciBpbmZvcm1hdGlvblxuICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFNoYXJlVXBkYXRlRXJyb3JzJyk7XG4gICAgICAgIHJlc3VsdC53YWxsZXRTaGFyZVVwZGF0ZUVycm9ycy5zaG91bGQuYmUuYW4uQXJyYXkoKTtcbiAgICAgICAgcmVzdWx0LndhbGxldFNoYXJlVXBkYXRlRXJyb3JzLnNob3VsZC5oYXZlLmxlbmd0aE9mKDEpO1xuICAgICAgICByZXN1bHQud2FsbGV0U2hhcmVVcGRhdGVFcnJvcnNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldFNoYXJlSWQnLCAnc2hhcmUyJyk7XG4gICAgICAgIHJlc3VsdC53YWxsZXRTaGFyZVVwZGF0ZUVycm9yc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVhc29uJywgJ0ZhaWxlZCB0byBwcm9jZXNzIHNoYXJlMicpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjcmVhdGVCdWxrS2V5U2hhcmVzIHRlc3RzJywgKCkgPT4ge1xuICAgIGNvbnN0IHdhbGxldERhdGEgPSB7XG4gICAgICBpZDogJzViMzQyNTJmMWJmMzQ5OTMwZTM0MDIwYTAwMDAwMDAwJyxcbiAgICAgIGNvaW46ICd0YnRjJyxcbiAgICAgIGtleXM6IFtcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NzAwMDAwMDAwJyxcbiAgICAgIF0sXG4gICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgbXVsdGlzaWdUeXBlOiAnb25jaGFpbicsXG4gICAgICB0eXBlOiAnaG90JyxcbiAgICB9O1xuICAgIGNvbnN0IHRzb2wgPSBiaXRnby5jb2luKCd0c29sJyk7XG4gICAgY29uc3Qgd2FsbGV0ID0gbmV3IFdhbGxldChiaXRnbywgdHNvbCwgd2FsbGV0RGF0YSk7XG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2soJ2h0dHBzOi8vYml0Z28uZmFrZXVybCcpLnBlcnNpc3QoKS5nZXQoJy9hcGkvdjEvY2xpZW50L2NvbnN0YW50cycpLnJlcGx5KDIwMCwgeyB0dGw6IDM2MDAsIGNvbnN0YW50czoge30gfSk7XG4gICAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICB9KTtcbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgIHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICB9KTtcbiAgICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgICBub2NrLnBlbmRpbmdNb2NrcygpLmxlbmd0aC5zaG91bGQuZXF1YWwoMCk7XG4gICAgfSk7XG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgaWYgc2hhcmVPcHRpb25zIGlzIGVtcHR5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtLZXlTaGFyZXMoW10pO1xuICAgICAgICBhc3NlcnQuZmFpbCgnRXhwZWN0ZWQgZXJyb3Igbm90IHRocm93bicpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVycm9yLm1lc3NhZ2UsICdzaGFyZU9wdGlvbnMgY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNraXAgc2hhcmVvcHRpb24gaWYga2V5Y2hhaW4gcGFyYW1ldGVycyBhcmUgbWlzc2luZycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIHVzZXI6ICd0ZXN0dXNlckBleGFtcGxlLmNvbScsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IFsnc3BlbmQnXSxcbiAgICAgICAgICBrZXljaGFpbjogeyBwdWI6ICdwdWJrZXknLCBlbmNyeXB0ZWRQcnY6ICcnLCBmcm9tUHViS2V5OiAnJywgdG9QdWJLZXk6ICcnLCBwYXRoOiAnJyB9LFxuICAgICAgICB9LFxuICAgICAgXTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtLZXlTaGFyZXMocGFyYW1zKTtcbiAgICAgICAgYXNzZXJ0LmZhaWwoJ0V4cGVjdGVkIGVycm9yIG5vdCB0aHJvd24nKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIFNoYXJlb3B0aW9ucyB3aXRoIGludmFsaWQga2V5Y2hhaW5zIGFyZSBza2lwcGVkXG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChlcnJvci5tZXNzYWdlLCAnc2hhcmVPcHRpb25zIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZW5kIHRoZSBjb3JyZWN0IGRhdGEgdG8gQml0R28gQVBJIGlmIHNoYXJlT3B0aW9ucyBhcmUgdmFsaWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICAgIHNoYXJlT3B0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVzZXI6ICd0ZXN0dXNlckBleGFtcGxlLmNvbScsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogWydzcGVuZCddLFxuICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgcHViOiAncHVia2V5JyxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZW5jcnlwdGVkUHJ2JyxcbiAgICAgICAgICAgICAgZnJvbVB1YktleTogJ2Zyb21QdWJLZXknLFxuICAgICAgICAgICAgICB0b1B1YktleTogJ3RvUHViS2V5JyxcbiAgICAgICAgICAgICAgcGF0aDogJ20vMC8wJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBjb25zdCBwYXJhbXNUb1NlbmQgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB1c2VyOiAndGVzdHVzZXJAZXhhbXBsZS5jb20nLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3NwZW5kJ10sXG4gICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgIHB1YjogJ3B1YmtleScsXG4gICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdlbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgZnJvbVB1YktleTogJ2Zyb21QdWJLZXknLFxuICAgICAgICAgICAgdG9QdWJLZXk6ICd0b1B1YktleScsXG4gICAgICAgICAgICBwYXRoOiAnbS8wLzAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoYC9hcGkvdjIvd2FsbGV0LyR7d2FsbGV0RGF0YS5pZH0vd2FsbGV0c2hhcmVzYCwgcGFyYW1zKVxuICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgc2hhcmVzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGlkOiAndXNlcklkJyxcbiAgICAgICAgICAgICAgY29pbjogd2FsbGV0RGF0YS5jb2luLFxuICAgICAgICAgICAgICB3YWxsZXQ6IHdhbGxldERhdGEuaWQsXG4gICAgICAgICAgICAgIGZyb21Vc2VyOiAnZnJvbVVzZXJJZCcsXG4gICAgICAgICAgICAgIHRvVXNlcjogJ3RvVXNlcklkJyxcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldycsICdzcGVuZCddLFxuICAgICAgICAgICAgICBrZXljaGFpbjoge1xuICAgICAgICAgICAgICAgIHB1YjogJ2R1bW15UHViJyxcbiAgICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdkdW1teUVuY3J5cHRlZFBydicsXG4gICAgICAgICAgICAgICAgZnJvbVB1YktleTogJ2R1bW15RnJvbVB1YktleScsXG4gICAgICAgICAgICAgICAgdG9QdWJLZXk6ICdkdW1teVRvUHViS2V5JyxcbiAgICAgICAgICAgICAgICBwYXRoOiAnZHVtbXlQYXRoJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXQuY3JlYXRlQnVsa0tleVNoYXJlcyhwYXJhbXNUb1NlbmQpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5zaGFyZXNbMF0uaWQsICd1c2VySWQnLCAnVGhlIHNoYXJlIElEIHNob3VsZCBtYXRjaCcpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5zaGFyZXNbMF0uY29pbiwgd2FsbGV0RGF0YS5jb2luLCAnVGhlIGNvaW4gc2hvdWxkIG1hdGNoJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LnNoYXJlc1swXS53YWxsZXQsIHdhbGxldERhdGEuaWQsICdUaGUgd2FsbGV0IElEIHNob3VsZCBtYXRjaCcpO1xuICAgICAgYXNzZXJ0KHJlc3VsdC5zaGFyZXNbMF0ua2V5Y2hhaW4pO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdC5zaGFyZXNbMF0ua2V5Y2hhaW4ucHViLCAnZHVtbXlQdWInLCAnVGhlIGtleWNoYWluIHB1YiBzaG91bGQgbWF0Y2gnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQuc2hhcmVzWzBdLnBlcm1pc3Npb25zLmluY2x1ZGVzKCd2aWV3JyksIHRydWUsICdUaGUgcGVybWlzc2lvbnMgc2hvdWxkIGluY2x1ZGUgXCJ2aWV3XCInKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChcbiAgICAgICAgcmVzdWx0LnNoYXJlc1swXS5wZXJtaXNzaW9ucy5pbmNsdWRlcygnc3BlbmQnKSxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICAgJ1RoZSBwZXJtaXNzaW9ucyBzaG91bGQgaW5jbHVkZSBcInNwZW5kXCInXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY3JlYXRlQnVsa1dhbGxldFNoYXJlIHRlc3RzJywgKCkgPT4ge1xuICAgIGNvbnN0IGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ21vY2snIH0pO1xuXG4gICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgIGlkOiAnNWIzNDI1MmYxYmYzNDk5MzBlMzQwMjBhMDAwMDAwMDAnLFxuICAgICAgY29pbjogJ3RidGMnLFxuICAgICAga2V5czogW1xuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc1MDAwMDAwMDAnLFxuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc2MDAwMDAwMDAnLFxuICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgXSxcbiAgICAgIGNvaW5TcGVjaWZpYzoge30sXG4gICAgICBtdWx0aXNpZ1R5cGU6ICdvbmNoYWluJyxcbiAgICAgIHR5cGU6ICdob3QnLFxuICAgIH07XG4gICAgY29uc3QgdHNvbCA9IGJpdGdvLmNvaW4oJ3Rzb2wnKTtcbiAgICBjb25zdCB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB0c29sLCB3YWxsZXREYXRhKTtcbiAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgbm9jaygnaHR0cHM6Ly9iaXRnby5mYWtldXJsJykucGVyc2lzdCgpLmdldCgnL2FwaS92MS9jbGllbnQvY29uc3RhbnRzJykucmVwbHkoMjAwLCB7IHR0bDogMzYwMCwgY29uc3RhbnRzOiB7fSB9KTtcbiAgICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5sZW5ndGguc2hvdWxkLmVxdWFsKDApO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3IgaWYgbm8gc2hhcmUgb3B0aW9ucyBhcmUgcHJvdmlkZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQnVsa1dhbGxldFNoYXJlKHsgd2FsbGV0UGFzc3BocmFzZTogJ1Rlc3QnLCBrZXlTaGFyZU9wdGlvbnM6IFtdIH0pO1xuICAgICAgICBhc3NlcnQuZmFpbCgnRXhwZWN0ZWQgZXJyb3Igbm90IHRocm93bicpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGVycm9yLm1lc3NhZ2UsICdzaGFyZU9wdGlvbnMgY2Fubm90IGJlIGVtcHR5Jyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBwcm9jZXNzIHNoYXJlIG9wdGlvbnMgYW5kIGNhbGwgY3JlYXRlQnVsa0tleVNoYXJlcycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJJZCA9ICd1c2VyQGV4YW1wbGUuY29tJztcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gWyd2aWV3JywgJ3NwZW5kJ107XG4gICAgICBjb25zdCBwYXRoID0gJ20vOTk5OTk5LzEvMSc7XG4gICAgICBjb25zdCB3YWxsZXRQYXNzcGhyYXNlID0gJ2JpdGdvMTIzNCc7XG4gICAgICBjb25zdCBwdWIgPSAnWm8xZ2d6VFVLTVk1YlluRHZUNW10VmVaeHpmMkZhTFRiS2ttdkdVaFVRayc7XG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KGAvYXBpL3YyL3RidGMva2V5LyR7d2FsbGV0LmtleUlkcygpWzBdfWApXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBpZDogd2FsbGV0LmtleUlkcygpWzBdLFxuICAgICAgICAgIHB1YixcbiAgICAgICAgICBzb3VyY2U6ICd1c2VyJyxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogJ3hwcnYxJywgcGFzc3dvcmQ6IHdhbGxldFBhc3NwaHJhc2UgfSksXG4gICAgICAgICAgY29pblNwZWNpZmljOiB7fSxcbiAgICAgICAgfSk7XG4gICAgICBjb25zdCBwYXJhbXM6IEJ1bGtXYWxsZXRTaGFyZU9wdGlvbnMgPSB7XG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIGtleVNoYXJlT3B0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVzZXJJZDogdXNlcklkLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgcHViS2V5OiAnMDI3MDVhNmQzM2EyNDU5ZmViNTM3ZTdhYmUzNmFhYWQ4YzExNTMyY2RiZmZhM2EyZTRlNTg4Njg0NjdkNTFmNTMyJyxcbiAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBydjEgPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKCk7XG4gICAgICBjb25zdCBrZXljaGFpblRlc3Q6IE9wdGlvbmFsS2V5Y2hhaW5FbmNyeXB0ZWRLZXkgPSB7XG4gICAgICAgIGVuY3J5cHRlZFBydjogYml0Z28uZW5jcnlwdCh7IGlucHV0OiBwcnYxLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgIH07XG5cbiAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnZ2V0RW5jcnlwdGVkVXNlcktleWNoYWluJykucmVzb2x2ZXMoe1xuICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleWNoYWluVGVzdC5lbmNyeXB0ZWRQcnYsXG4gICAgICAgIHB1YixcbiAgICAgIH0gYXMgS2V5Y2hhaW5XaXRoRW5jcnlwdGVkUHJ2KTtcblxuICAgICAgc2lub24uc3R1Yihtb2R1bGVCaXRnbywgJ2dldFNoYXJlZFNlY3JldCcpLnJlc29sdmVzKCdmYWtlU2hhcmVkU2VjcmV0Jyk7XG5cbiAgICAgIHNpbm9uLnN0dWIod2FsbGV0LCAnY3JlYXRlQnVsa0tleVNoYXJlcycpLnJlc29sdmVzKHtcbiAgICAgICAgc2hhcmVzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6IHVzZXJJZCxcbiAgICAgICAgICAgIGNvaW46IHdhbGxldERhdGEuY29pbixcbiAgICAgICAgICAgIHdhbGxldDogd2FsbGV0RGF0YS5pZCxcbiAgICAgICAgICAgIGZyb21Vc2VyOiB1c2VySWQsXG4gICAgICAgICAgICB0b1VzZXI6IHVzZXJJZCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBbJ3ZpZXcnLCAnc3BlbmQnXSxcbiAgICAgICAgICAgIGtleWNoYWluOiB7XG4gICAgICAgICAgICAgIHB1YjogJ2R1bW15UHViJyxcbiAgICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiAnZHVtbXlFbmNyeXB0ZWRQcnYnLFxuICAgICAgICAgICAgICBmcm9tUHViS2V5OiAnZHVtbXlGcm9tUHViS2V5JyxcbiAgICAgICAgICAgICAgdG9QdWJLZXk6ICdkdW1teVRvUHViS2V5JyxcbiAgICAgICAgICAgICAgcGF0aDogJ2R1bW15UGF0aCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgd2FsbGV0LmNyZWF0ZUJ1bGtXYWxsZXRTaGFyZShwYXJhbXMpO1xuXG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHJlc3VsdCwge1xuICAgICAgICBzaGFyZXM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogdXNlcklkLFxuICAgICAgICAgICAgY29pbjogd2FsbGV0RGF0YS5jb2luLFxuICAgICAgICAgICAgd2FsbGV0OiB3YWxsZXREYXRhLmlkLFxuICAgICAgICAgICAgZnJvbVVzZXI6IHVzZXJJZCxcbiAgICAgICAgICAgIHRvVXNlcjogdXNlcklkLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IFsndmlldycsICdzcGVuZCddLFxuICAgICAgICAgICAga2V5Y2hhaW46IHtcbiAgICAgICAgICAgICAgcHViOiAnZHVtbXlQdWInLFxuICAgICAgICAgICAgICBlbmNyeXB0ZWRQcnY6ICdkdW1teUVuY3J5cHRlZFBydicsXG4gICAgICAgICAgICAgIGZyb21QdWJLZXk6ICdkdW1teUZyb21QdWJLZXknLFxuICAgICAgICAgICAgICB0b1B1YktleTogJ2R1bW15VG9QdWJLZXknLFxuICAgICAgICAgICAgICBwYXRoOiAnZHVtbXlQYXRoJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpbiBwcm9jZXNzaW5nIHNoYXJlIG9wdGlvbnMgd2hlbiB3YWxsZXQgcGFzc3dvcmQgaXMgaW5jb3JyZWN0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdXNlcklkID0gJ3VzZXJAZXhhbXBsZS5jb20nO1xuICAgICAgY29uc3QgcGVybWlzc2lvbnMgPSBbJ3ZpZXcnLCAnc3BlbmQnXTtcbiAgICAgIGNvbnN0IHBhdGggPSAnbS85OTk5OTkvMS8xJztcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSAnYml0Z28xMjM0JztcbiAgICAgIGNvbnN0IHB1YiA9ICdabzFnZ3pUVUtNWTViWW5EdlQ1bXRWZVp4emYyRmFMVGJLa212R1VoVVFrJztcbiAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvdGJ0Yy9rZXkvJHt3YWxsZXQua2V5SWRzKClbMF19YClcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGlkOiB3YWxsZXQua2V5SWRzKClbMF0sXG4gICAgICAgICAgcHViLFxuICAgICAgICAgIHNvdXJjZTogJ3VzZXInLFxuICAgICAgICAgIGVuY3J5cHRlZFBydjogYml0Z28uZW5jcnlwdCh7IGlucHV0OiAneHBydjEnLCBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSB9KSxcbiAgICAgICAgICBjb2luU3BlY2lmaWM6IHt9LFxuICAgICAgICB9KTtcbiAgICAgIGNvbnN0IHBhcmFtczogQnVsa1dhbGxldFNoYXJlT3B0aW9ucyA9IHtcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ3dyb25nIHBhc3N3b3JkJyxcbiAgICAgICAga2V5U2hhcmVPcHRpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXNlcklkOiB1c2VySWQsXG4gICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnMsXG4gICAgICAgICAgICBwdWJLZXk6ICcwMjcwNWE2ZDMzYTI0NTlmZWI1MzdlN2FiZTM2YWFhZDhjMTE1MzJjZGJmZmEzYTJlNGU1ODg2ODQ2N2Q1MWY1MzInLFxuICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcHJ2MSA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoKTtcbiAgICAgIGNvbnN0IGtleWNoYWluVGVzdDogT3B0aW9uYWxLZXljaGFpbkVuY3J5cHRlZEtleSA9IHtcbiAgICAgICAgZW5jcnlwdGVkUHJ2OiBiaXRnby5lbmNyeXB0KHsgaW5wdXQ6IHBydjEsIHBhc3N3b3JkOiB3YWxsZXRQYXNzcGhyYXNlIH0pLFxuICAgICAgfTtcblxuICAgICAgc2lub24uc3R1Yih3YWxsZXQsICdnZXRFbmNyeXB0ZWRVc2VyS2V5Y2hhaW4nKS5yZXNvbHZlcyh7XG4gICAgICAgIGVuY3J5cHRlZFBydjoga2V5Y2hhaW5UZXN0LmVuY3J5cHRlZFBydixcbiAgICAgICAgcHViLFxuICAgICAgfSBhcyBLZXljaGFpbldpdGhFbmNyeXB0ZWRQcnYpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB3YWxsZXQuY3JlYXRlQnVsa1dhbGxldFNoYXJlKHBhcmFtcyk7XG4gICAgICAgIGFzc2VydC5mYWlsKCdFeHBlY3RlZCBlcnJvciBub3QgdGhyb3duJyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBhc3NlcnQoZXJyb3IgaW5zdGFuY2VvZiBJbmNvcnJlY3RQYXNzd29yZEVycm9yKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKGVycm9yLm1lc3NhZ2UsICdQYXNzd29yZCBzaGFyZWQgaXMgaW5jb3JyZWN0IGZvciB0aGlzIHdhbGxldCcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnTGlzdCBXYWxsZXRzOicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGxpc3Qgd2FsbGV0cyB3aXRoIHNraXBSZWNlaXZlQWRkcmVzcyA9IHRydWUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJ0YycpO1xuICAgICAgY29uc3Qgd2FsbGV0cyA9IGJhc2Vjb2luLndhbGxldHMoKTtcbiAgICAgIGNvbnN0IGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyL3RidGMvd2FsbGV0JylcbiAgICAgICAgLnF1ZXJ5KHsgc2tpcFJlY2VpdmVBZGRyZXNzOiB0cnVlIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICB3YWxsZXRzOiBbXG4gICAgICAgICAgICB7IGlkOiAnd2FsbGV0MScsIGxhYmVsOiAnVGVzdCBXYWxsZXQgMScgfSxcbiAgICAgICAgICAgIHsgaWQ6ICd3YWxsZXQyJywgbGFiZWw6ICdUZXN0IFdhbGxldCAyJyB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXRzLmxpc3QoeyBza2lwUmVjZWl2ZUFkZHJlc3M6IHRydWUgfSk7XG4gICAgICByZXN1bHQud2FsbGV0cy5zaG91bGQuaGF2ZS5sZW5ndGgoMik7XG4gICAgICBzaG91bGQubm90LmV4aXN0KHJlc3VsdC53YWxsZXRzWzBdLnJlY2VpdmVBZGRyZXNzKCkpO1xuICAgICAgc2hvdWxkLm5vdC5leGlzdChyZXN1bHQud2FsbGV0c1sxXS5yZWNlaXZlQWRkcmVzcygpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbGlzdCB3YWxsZXRzIHdpdGhvdXQgc2tpcFJlY2VpdmVBZGRyZXNzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R28sIHsgZW52OiAnbW9jaycgfSk7XG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RidGMnKTtcbiAgICAgIGNvbnN0IHdhbGxldHMgPSBiYXNlY29pbi53YWxsZXRzKCk7XG4gICAgICBjb25zdCBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbYml0Z28uZ2V0RW52KCldLnVyaTtcblxuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLmdldCgnL2FwaS92Mi90YnRjL3dhbGxldCcpXG4gICAgICAgIC5xdWVyeSh7fSlcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHdhbGxldHM6IFtcbiAgICAgICAgICAgIHsgaWQ6ICd3YWxsZXQxJywgbGFiZWw6ICdUZXN0IFdhbGxldCAxJywgcmVjZWl2ZUFkZHJlc3M6IHsgYWRkcmVzczogJ2FkZHJlc3MxJyB9IH0sXG4gICAgICAgICAgICB7IGlkOiAnd2FsbGV0MicsIGxhYmVsOiAnVGVzdCBXYWxsZXQgMicsIHJlY2VpdmVBZGRyZXNzOiB7IGFkZHJlc3M6ICdhZGRyZXNzMicgfSB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3YWxsZXRzLmxpc3QoKTtcbiAgICAgIHJlc3VsdC53YWxsZXRzLnNob3VsZC5oYXZlLmxlbmd0aCgyKTtcbiAgICAgIHNob3VsZC5leGlzdChyZXN1bHQud2FsbGV0c1swXS5yZWNlaXZlQWRkcmVzcygpKTtcbiAgICAgIHNob3VsZC5leGlzdChyZXN1bHQud2FsbGV0c1sxXS5yZWNlaXZlQWRkcmVzcygpKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==

Выполнить команду


Для локальной разработки. Не используйте в интернете!