bitgo
Version:
BitGo JavaScript SDK
1,261 lines • 242 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const should = require("should");
const nock = require("nock");
const sdk_test_1 = require("@bitgo/sdk-test");
const src_1 = require("../../../src");
const sdk_core_1 = require("@bitgo/sdk-core");
const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
const tx_1 = require("@ethereumjs/tx");
const sinon = require("sinon");
const recoveryFixtures_1 = require("../fixtures/tss/recoveryFixtures");
const sdk_coin_xrp_1 = require("@bitgo/sdk-coin-xrp");
const recoveryNocks = require('../lib/recovery-nocks');
nock.disableNetConnect();
describe('Recovery:', function () {
let bitgo;
before(function () {
bitgo = sdk_test_1.TestBitGo.decorate(src_1.BitGo, { env: 'test' });
bitgo.initializeTestVars();
// pretend that Keyternal accepts recoveries for all coins
sdk_core_1.krsProviders.keyternal.supportedCoins = ['btc', 'eth', 'xrp', 'bch', 'bcha', 'ltc', 'zec', 'dash', 'xlm', 'bsv'];
sdk_core_1.krsProviders.keyternal.feeAddresses = {
tbtc: '2Mujz9eicmgpPcdScRJTywVK3EQNHDJG3yN',
tbch: '2Mujz9eicmgpPcdScRJTywVK3EQNHDJG3yN',
tbsv: '2Mujz9eicmgpPcdScRJTywVK3EQNHDJG3yN',
tbcha: '2Mujz9eicmgpPcdScRJTywVK3EQNHDJG3yN',
tltc: 'QffXMViM8DYgPRf1Hoczjw7BS5CVdSWaBL',
tzec: 't2ATLAhBP1uTuyiWs5DY5CPH1VuYkGUindt',
tdash: '8euHug4dbmPy3CLawwWdeTjGLqPYEGz3Kt',
};
});
after(function () {
nock.cleanAll();
});
describe('Recover Ripple', function () {
it('should generate XRP recovery tx', function () {
recoveryNocks.nockXrpRecovery();
const basecoin = bitgo.coin('txrp');
return basecoin
.recover({
userKey: '{"iv":"rU++mEtIHtbp3d4jg5EulA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ip1rb59uYnM=","ct":"ssmP9abPoVyXkW4Io0SUy+AAS8lr+wgIerTMw+lDYnkUh0sjlI4A6Fpve0q1riQ3Dy/J0bNu7dgoZkO4xs/X6dzwEwlmPhk3pEQ7Yd4CXa1zA01y0Geu900FLe4LdaS8jt6fixui2tTd4Vi3JYglF1/HmCjG1Ug="}',
backupKey: '{"iv":"uB/BTcn1rXmgYGfncXOowg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"I3WrumxkuMQ=","ct":"sgyDNAzNsBruTRm0d04oBTBf8lheHNKS+dRgl8FeMEhodKsiyjtRVHG0CHPf5rV3g5ixVnZ+iwsSCv3PKyyeoy7RGnT0AG9YYpi0me+OvP8331iO+n5quzstrGbV1j8uEh5IMW78S+YUZKSx6zbbdZ0xNu8D5WM="}',
rootAddress: 'raGZWRkRBUWdQJsKYEzwXJNbCZMTqX56aA',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_WALLET1_PASSCODE,
recoveryDestination: 'rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2?dt=12345',
})
.then(function (recovery) {
recovery.txHex.should.equal('120000228000000024000000042E00003039201B0015519161400000024E06C0C068400000000000001E7300811439CA010E0E0198150F8DDD5768CCD2B095701D8C8314201276ADC469C4F10D1369E0F5C5A7DEF37B2267F3E0107321026C91974146427889C801BD26CE31CE0E10307A69DFE4139DE45E5E35933A6B037446304402204AA3D2F344729B0BB9075C4AEA07EBB2EAF6D3F36309BCAEF10B2C9734AC943E022032D55EC19E27B2E90E3D9444FD26CC06FD47BB3E3D85B0FCC0CC4DE7038563FD8114ABB5B7C843F3AA8D8EFACC3C5A7D9B0484C17442E1E010732102F4E376133012F5404990C7E1DF83A9F943B30D55F0D856632C8E8378FCEB70D2744630440220568F1D49F5810458E7204A1D2D23B86B694505327E8410A215AB9C9324EA8A3102207A93211ACFB5E9C1441B701A7954B72A3054265BA3FD61965D709E4C4E9080F38114ACEF9F0A2FCEC44A9A213444A9E6C57E2D02856AE1F1');
recovery.id.should.equal('F2005B392E9454FF1E8217B816C87866A56770382B8FCAC0AAE2FA8D12A53B98');
recovery.outputAmount.should.equal('9899000000');
recovery.outputs.length.should.equal(1);
recovery.outputs[0].address.should.equal('rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2?dt=12345');
recovery.outputs[0].amount.should.equal('9899000000');
recovery.fee.fee.should.equal('30');
});
});
it('should generate XRP recovery tx with KRS', function () {
recoveryNocks.nockXrpRecovery();
const basecoin = bitgo.coin('txrp');
return basecoin
.recover({
userKey: '{"iv":"rU++mEtIHtbp3d4jg5EulA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ip1rb59uYnM=","ct":"ssmP9abPoVyXkW4Io0SUy+AAS8lr+wgIerTMw+lDYnkUh0sjlI4A6Fpve0q1riQ3Dy/J0bNu7dgoZkO4xs/X6dzwEwlmPhk3pEQ7Yd4CXa1zA01y0Geu900FLe4LdaS8jt6fixui2tTd4Vi3JYglF1/HmCjG1Ug="}',
backupKey: 'xpub661MyMwAqRbcFtWdmWHKZEh9pYiJrAGTu1NNSwxY2S63tU9nGcfCAbNUKQuFqXRTRk8KkuBabxo6YjeBri8Q7dkMsmths6MVxSd6MTaeCmd',
rootAddress: 'raGZWRkRBUWdQJsKYEzwXJNbCZMTqX56aA',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_WALLET1_PASSCODE,
krsProvider: 'keyternal',
recoveryDestination: 'rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2?dt=12345',
})
.then(function (recovery) {
recovery.txHex.should.equal('120000228000000024000000042E00003039201B0015519161400000024E06C0C068400000000000001E7300811439CA010E0E0198150F8DDD5768CCD2B095701D8C8314201276ADC469C4F10D1369E0F5C5A7DEF37B2267F3E010732102F4E376133012F5404990C7E1DF83A9F943B30D55F0D856632C8E8378FCEB70D2744630440220568F1D49F5810458E7204A1D2D23B86B694505327E8410A215AB9C9324EA8A3102207A93211ACFB5E9C1441B701A7954B72A3054265BA3FD61965D709E4C4E9080F38114ACEF9F0A2FCEC44A9A213444A9E6C57E2D02856AE1F1');
recovery.id.should.equal('6EA1728B0CC0C047E54AAF578D81822EDE1107908B979868299657E74A8E18C0');
recovery.outputAmount.should.equal('9899000000');
recovery.outputs.length.should.equal(1);
recovery.outputs[0].address.should.equal('rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2?dt=12345');
recovery.outputs[0].amount.should.equal('9899000000');
recovery.fee.fee.should.equal('30');
});
});
it('should generate an XRP unsigned sweep', function () {
recoveryNocks.nockXrpRecovery();
const basecoin = bitgo.coin('txrp');
return basecoin
.recover({
userKey: 'xpub661MyMwAqRbcF9Ya4zDHGzDtJz3NaaeEGbQ6rnqnNxL9RXDJNHcfzAyPUBXuKXjytvJNzQxqbjBwmPveiYX323Zp8Zx2RYQN9gGM7ntiXxr',
backupKey: 'xpub661MyMwAqRbcFtWdmWHKZEh9pYiJrAGTu1NNSwxY2S63tU9nGcfCAbNUKQuFqXRTRk8KkuBabxo6YjeBri8Q7dkMsmths6MVxSd6MTaeCmd',
rootAddress: 'raGZWRkRBUWdQJsKYEzwXJNbCZMTqX56aA',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_WALLET1_PASSCODE,
krsProvider: 'keyternal',
recoveryDestination: 'rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2?dt=12345',
})
.then(function (recovery) {
recovery.txHex.should.equal('120000228000000024000000042E00003039201B0015519161400000024E06C0C068400000000000001E811439CA010E0E0198150F8DDD5768CCD2B095701D8C8314201276ADC469C4F10D1369E0F5C5A7DEF37B2267');
const tx = sdk_coin_xrp_1.Utils.decodeTransaction(recovery.txHex);
tx.TransactionType.should.equal('Payment');
tx.Account.should.equal('raGZWRkRBUWdQJsKYEzwXJNbCZMTqX56aA');
tx.Destination.should.equal('rsv2kremJSSFbbaLqrf8fWxxN5QnsynNm2');
tx.DestinationTag.should.equal(12345);
tx.Amount.should.equal('9899000000');
tx.Flags.should.equal(2147483648);
tx.LastLedgerSequence.should.equal(1397137);
tx.Fee.should.equal('30');
tx.Sequence.should.equal(4);
});
});
});
describe('Recover Stellar', function () {
async function checkRecoveryTxExplanation(basecoin, tx, recoveryAmount, recoveryDestination) {
const explanation = await basecoin.explainTransaction({ txBase64: tx });
explanation.should.have.property('outputs');
explanation.outputs.should.containEql({
amount: recoveryAmount.toFixed(),
address: recoveryDestination,
coin: basecoin.getChain(),
});
explanation.should.have.property('changeOutputs', []);
explanation.should.have.property('changeAmount', '0');
explanation.should.have.property('fee', { fee: '100', feeRate: null, size: null });
explanation.should.have.property('operations', []);
}
it('should generate XLM recovery tx', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: `{"iv":"PiLveA+5AFPURwaU7iijBQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"KlJc8NSKHpw=","ct":"YcdNOFpzXgDnRqjlR3W9R+5eztysyhpCTuRBHsnPyPDst9nvL+GeSORbLY9xVThTdyV6llRgfUr5O7y4l9s9Fg=="}`,
backupKey: `{"iv":"TmiAIHr0vCX6g2BKkc6/7g==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"wOkMJEm5B6U=","ct":"HJPS56/FuMieiH6K2s5k5jFp8RPHQqZa9qi8hDkjOqNUFjD4XKq8Sy3BDhpwzozTBW6EmQGSF0kpc7eZ9CucKw=="}`,
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', recoveryAmount);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should recover to an unfunded XLM wallet', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: `{"iv":"PiLveA+5AFPURwaU7iijBQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"KlJc8NSKHpw=","ct":"YcdNOFpzXgDnRqjlR3W9R+5eztysyhpCTuRBHsnPyPDst9nvL+GeSORbLY9xVThTdyV6llRgfUr5O7y4l9s9Fg=="}`,
backupKey: `{"iv":"TmiAIHr0vCX6g2BKkc6/7g==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"wOkMJEm5B6U=","ct":"HJPS56/FuMieiH6K2s5k5jFp8RPHQqZa9qi8hDkjOqNUFjD4XKq8Sy3BDhpwzozTBW6EmQGSF0kpc7eZ9CucKw=="}`,
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GAGCQLUGMX76XC24JRCRJWOHXK23ONURH4433JOEPU6CH7Z44CCYUCEL',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', recoveryAmount);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate XLM recovery tx with unencrypted keys', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: `SAMF5XS7O5BL4OOTB625DELCVNW5JMHF2DDM7NSIVPNQQEKPKLBQFNJ3`,
backupKey: `SCXZ7UFVSIFIYJVPLWEAY22TZJOR4L2Z4HE6BMZGZHBBJ4UAABTFMK3V`,
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', recoveryAmount);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate XLM recovery tx with unencrypted root private keys', async function () {
recoveryNocks.nockXlmRecovery();
// userKey and backupKey are in prv + pub representation
// first 64 characters (32 bytes) are the private key, the rest is the public key
const recoveryParams = {
userKey: `185ede5f7742be39d30fb5d19162ab6dd4b0e5d0c6cfb648abdb08114f52c3025aae152ef1470686aba3fec40889a550d7b53910c739e25b5d4a2f27eb512eb7`,
backupKey: `af9fd0b5920a8c26af5d880c6b53ca5d1e2f59e1c9e0b326c9c214f2800066568200a5e4dd279da5f422324b8210e898dbf68fc29c1f9cf791c224187fad7dc3`,
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', recoveryAmount);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate XLM recovery tx with encrypted root keys', async function () {
recoveryNocks.nockXlmRecovery();
// userKey and backupKey are in encrypted prv + pub representation
const recoveryParams = {
userKey: `{"iv":"bUHw53Oa8tSrFRzidPi8ag==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"QHNZFlDnCW0=","ct":"AQSABvUmCMsD3rJQzyg29TnLPnDVCZFXZkg9hJ2ReYaXWWkSb8Bw0nn3LW/GIGi3ZbOgPivJ4LhCbO9A2pp4aVOhbsbqCNBWxpmHzneVS3FPrLebQixH1Rn0X+ft2I9XcNNEklEw5cH3pf9I1vqLmwEHpF8DWx0OgGnlh/Qq0r5ZaEt5tbTDPA=="}`,
backupKey: `{"iv":"19SQ3SlLzuTbEfU7s8lTHQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"jLM2oWyO8Wg=","ct":"iXUdNcqhsbykfyLKYrcEegSHooAJt82krdSWhQhs/cUAoA6tX4j+HfOutQhSPDtJkIpbz19ynoTo8VVpxp/Ga+ubQVlClbZPyhC8YkCRvJBvWKg41EEGlyduK7esVrnnv1c4Xk4a4BaXszOEdGw/1aQB9AOQMMVsv6z8Yhu55QqVz6zN49PmaQ=="}`,
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', recoveryAmount);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate XLM recovery tx with KRS', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: `{"iv":"PiLveA+5AFPURwaU7iijBQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"KlJc8NSKHpw=","ct":"YcdNOFpzXgDnRqjlR3W9R+5eztysyhpCTuRBHsnPyPDst9nvL+GeSORbLY9xVThTdyV6llRgfUr5O7y4l9s9Fg=="}`,
backupKey: 'GCBABJPE3UTZ3JPUEIZEXAQQ5CMNX5UPYKOB7HHXSHBCIGD7VV64H6KU',
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
krsProvider: 'keyternal',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', 74999500);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate XLM recovery tx with KRS using root keys', async function () {
recoveryNocks.nockXlmRecovery();
// userKey is in encrypted prv + pub representation
const recoveryParams = {
userKey: `{"iv":"bUHw53Oa8tSrFRzidPi8ag==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"QHNZFlDnCW0=","ct":"AQSABvUmCMsD3rJQzyg29TnLPnDVCZFXZkg9hJ2ReYaXWWkSb8Bw0nn3LW/GIGi3ZbOgPivJ4LhCbO9A2pp4aVOhbsbqCNBWxpmHzneVS3FPrLebQixH1Rn0X+ft2I9XcNNEklEw5cH3pf9I1vqLmwEHpF8DWx0OgGnlh/Qq0r5ZaEt5tbTDPA=="}`,
backupKey: '8200a5e4dd279da5f422324b8210e898dbf68fc29c1f9cf791c224187fad7dc3', // this is a pub root key, note it is 32 bytes
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
krsProvider: 'keyternal',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', 74999500);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate an XLM unsigned sweep', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: 'GBNK4FJO6FDQNBVLUP7MICEJUVINPNJZCDDTTYS3LVFC6J7LKEXLOBKM',
backupKey: 'GCBABJPE3UTZ3JPUEIZEXAQQ5CMNX5UPYKOB7HHXSHBCIGD7VV64H6KU',
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
krsProvider: 'keyternal',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', 74999500);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
it('should generate an XLM unsigned sweep using root keys', async function () {
recoveryNocks.nockXlmRecovery();
const recoveryParams = {
userKey: '5aae152ef1470686aba3fec40889a550d7b53910c739e25b5d4a2f27eb512eb7', // this is a pub key, note it is 32 bytes
backupKey: '8200a5e4dd279da5f422324b8210e898dbf68fc29c1f9cf791c224187fad7dc3', // this is a pub root key, note it is 32 bytes
rootAddress: 'GAUAGTL3NBZ7NP3UIMZCVJYM6O2NKUP6XRTK4E5VZDVIQX3CBYIVMDIB',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: 'GASW277S2ZOE7H7A5EQ5H5AKLP6UA6Z5AKOSWV6ARBEGTSIGMZMC7AIZ',
krsProvider: 'keyternal',
};
const recoveryAmount = 74999500;
const basecoin = bitgo.coin('txlm');
const recovery = await basecoin.recover(recoveryParams);
recovery.should.have.property('txBase64');
recovery.should.have.property('recoveryAmount', 74999500);
await checkRecoveryTxExplanation(basecoin, recovery.txBase64, recoveryAmount, recoveryParams.recoveryDestination);
});
});
describe('Recover TRON', function () {
let baseCoin;
before(function () {
baseCoin = bitgo.coin('ttrx');
});
afterEach(function () {
nock.cleanAll();
});
it('should generate recovery tx from encrypted user and backup keys', async function () {
recoveryNocks.nockTronRecovery();
const recoveryTx = await baseCoin.recover({
userKey: '{"iv":"eXwYIygDyRy1R1lw9EwEgQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"NNOxF+LR7aU=","ct":"qX/G+AiZJ35XwUmL9alYitRwvYgE/bS24DSAVV7tBaoTs40tsVB/kWx+hV/J5acKIA6Z/wSucxbKrQlJB69xJJl/OirYqmXRBirH+rag1aC1zj7ZVnbO+h+P5GHqHJltLc4UyDf+p22+NjoDLfR+fEPtG8c4v5o="}',
backupKey: '{"iv":"QaoXCEkibo4VMEyo3fSUUQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"iqqtrBtC5vY=","ct":"JHbHJ8U2Ala2cRFcoqTAftLYmDDSOTfhdVmZkmW/ORJeP60Vf5T1m661yWQT3ADKSsq2CSRV49OqSfH2lIOBU3EfXdFXkWQeTNX+bhzC6E2o/us3SnwlXhO659DQMPmLthvgCTX8xM+5UzgV/PYnqFpSuxl379s="}',
bitgoKey: 'xpub661MyMwAqRbcEx6zKTBrgZkWPBGvx8qguEd1NqEDp6yW3srBGhTUdFkcdcBjp5FQgXkDNiQBdj6Fsgka8D9VFYt32M2GsCTRuffnXMhq1ho',
walletPassphrase: 'test_wallet_passphrase',
recoveryDestination: 'TYPgx8NfDxB8pyiyTeiMkYzem1dNA6G12i',
});
should.exist(recoveryTx);
recoveryTx.coin.should.equal('ttrx');
recoveryTx.feeInfo.fee.should.equal('2100000');
recoveryTx.recoveryAmount.should.equal(899047400);
recoveryTx.txHex.should.equal('{"visible":false,"txID":"98b398e3027e601870a86b0785f1f1d301f087dbaafe44337507b5001bae0d49","raw_data":{"contract":[{"parameter":{"value":{"amount":10000000,"owner_address":"41e7e11df2c5704888c3cb63fb43a9498bd1812cb2","to_address":"41f5f414d447aafe70bb9b9d93912cbc4c54f0c014"},"type_url":"type.googleapis.com/protocol.TransferContract"},"type":"TransferContract"}],"ref_block_bytes":"a762","ref_block_hash":"18dfe946fbf7a0ac","expiration":1676746443000,"timestamp":1676659983799},"raw_data_hex":"0a02a762220818dfe946fbf7a0ac40f89181afe6305a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a1541e7e11df2c5704888c3cb63fb43a9498bd1812cb2121541f5f414d447aafe70bb9b9d93912cbc4c54f0c01418c8d19cad0370b78be485e630","signature":["79a110116657e75be81400ad4a9f738fd098695fc5fc6009176aa1c27924c4cdb2989fe2052b70c739b10cd3881c9872660b83998dc9316e6c8d11fb588d731d00","250d0bae2491596bd800d830aa9d4c6d25e1d01a4c860b856d6000a8ab8fa2082a1ae20168e0ab97c9ffd64824b483b9843db74e9553d5d9e68a3a64d414dd1201"]}');
recoveryTx.tx.signature[0].should.equal('79a110116657e75be81400ad4a9f738fd098695fc5fc6009176aa1c27924c4cdb2989fe2052b70c739b10cd3881c9872660b83998dc9316e6c8d11fb588d731d00');
recoveryTx.tx.signature[1].should.equal('250d0bae2491596bd800d830aa9d4c6d25e1d01a4c860b856d6000a8ab8fa2082a1ae20168e0ab97c9ffd64824b483b9843db74e9553d5d9e68a3a64d414dd1201');
recoveryTx.tx.txID.should.equal('98b398e3027e601870a86b0785f1f1d301f087dbaafe44337507b5001bae0d49');
recoveryTx.tx.raw_data_hex.should.equal('0a02a762220818dfe946fbf7a0ac40f89181afe6305a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a1541e7e11df2c5704888c3cb63fb43a9498bd1812cb2121541f5f414d447aafe70bb9b9d93912cbc4c54f0c01418c8d19cad0370b78be485e630');
});
it('should generate recovery tx from encrypted user and backup keys from a receive address', async function () {
nock.cleanAll();
recoveryNocks.nockTronReceiveRecovery();
const recoveryTx = await baseCoin.recover({
userKey: '{"iv":"eXwYIygDyRy1R1lw9EwEgQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"NNOxF+LR7aU=","ct":"qX/G+AiZJ35XwUmL9alYitRwvYgE/bS24DSAVV7tBaoTs40tsVB/kWx+hV/J5acKIA6Z/wSucxbKrQlJB69xJJl/OirYqmXRBirH+rag1aC1zj7ZVnbO+h+P5GHqHJltLc4UyDf+p22+NjoDLfR+fEPtG8c4v5o="}',
backupKey: '{"iv":"QaoXCEkibo4VMEyo3fSUUQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"iqqtrBtC5vY=","ct":"JHbHJ8U2Ala2cRFcoqTAftLYmDDSOTfhdVmZkmW/ORJeP60Vf5T1m661yWQT3ADKSsq2CSRV49OqSfH2lIOBU3EfXdFXkWQeTNX+bhzC6E2o/us3SnwlXhO659DQMPmLthvgCTX8xM+5UzgV/PYnqFpSuxl379s="}',
bitgoKey: 'xpub661MyMwAqRbcEx6zKTBrgZkWPBGvx8qguEd1NqEDp6yW3srBGhTUdFkcdcBjp5FQgXkDNiQBdj6Fsgka8D9VFYt32M2GsCTRuffnXMhq1ho',
walletPassphrase: 'test_wallet_passphrase',
recoveryDestination: 'TEbha9FhQMZ3FRtZgok8QBunPQU4pZvBxX',
});
should.exist(recoveryTx);
recoveryTx.coin.should.equal('ttrx');
recoveryTx.feeInfo.fee.should.equal('2100000');
recoveryTx.recoveryAmount.should.equal(197900000);
recoveryTx.addressInfo.address.should.equal('TNeGpwAurk7kjQLdcdWhFr8YP8E9Za8w1x');
recoveryTx.addressInfo.chain.should.equal(0);
recoveryTx.addressInfo.index.should.equal(1);
recoveryTx.txHex.should.equal('{"visible":false,"txID":"da67e32e9ea3bd022f3d93ed259771dda9b444d41d1e63e54c8254a6ebb6332f","raw_data":{"contract":[{"parameter":{"value":{"amount":199000000,"owner_address":"418b04ecdc3db7e8da7cd838492f66e424a051e2cd","to_address":"4132c753bf8d3de7358748a75fcf299f146dff6e4e"},"type_url":"type.googleapis.com/protocol.TransferContract"},"type":"TransferContract"}],"ref_block_bytes":"81e0","ref_block_hash":"5b1b20e9ebeaa4f8","expiration":1686038682000,"timestamp":1685952224483},"raw_data_hex":"0a0281e022085b1b20e9ebeaa4f84090b3f2fd88315a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a15418b04ecdc3db7e8da7cd838492f66e424a051e2cd12154132c753bf8d3de7358748a75fcf299f146dff6e4e18c0fff15e70e3b9d5d48831","signature":["94a31cdd64e93e375c3eebae5db4f66761cb49550f2cee9388b618e6836bc471ecf33e14122d62244737358e33a9d14a056ce8c7dc34dcfcb8ef2db15d40d83600"]}');
recoveryTx.tx.signature[0].should.equal('94a31cdd64e93e375c3eebae5db4f66761cb49550f2cee9388b618e6836bc471ecf33e14122d62244737358e33a9d14a056ce8c7dc34dcfcb8ef2db15d40d83600');
recoveryTx.tx.txID.should.equal('da67e32e9ea3bd022f3d93ed259771dda9b444d41d1e63e54c8254a6ebb6332f');
recoveryTx.tx.raw_data_hex.should.equal('0a0281e022085b1b20e9ebeaa4f84090b3f2fd88315a68080112640a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412330a15418b04ecdc3db7e8da7cd838492f66e424a051e2cd12154132c753bf8d3de7358748a75fcf299f146dff6e4e18c0fff15e70e3b9d5d48831');
});
it('should throw an error when there is no funds to flush', async function () {
recoveryNocks.nockTronReceiveRecoveryZeroFunds();
await baseCoin
.recover({
userKey: '{"iv":"eXwYIygDyRy1R1lw9EwEgQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"NNOxF+LR7aU=","ct":"qX/G+AiZJ35XwUmL9alYitRwvYgE/bS24DSAVV7tBaoTs40tsVB/kWx+hV/J5acKIA6Z/wSucxbKrQlJB69xJJl/OirYqmXRBirH+rag1aC1zj7ZVnbO+h+P5GHqHJltLc4UyDf+p22+NjoDLfR+fEPtG8c4v5o="}',
backupKey: '{"iv":"QaoXCEkibo4VMEyo3fSUUQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"iqqtrBtC5vY=","ct":"JHbHJ8U2Ala2cRFcoqTAftLYmDDSOTfhdVmZkmW/ORJeP60Vf5T1m661yWQT3ADKSsq2CSRV49OqSfH2lIOBU3EfXdFXkWQeTNX+bhzC6E2o/us3SnwlXhO659DQMPmLthvgCTX8xM+5UzgV/PYnqFpSuxl379s="}',
bitgoKey: 'xpub661MyMwAqRbcEx6zKTBrgZkWPBGvx8qguEd1NqEDp6yW3srBGhTUdFkcdcBjp5FQgXkDNiQBdj6Fsgka8D9VFYt32M2GsCTRuffnXMhq1ho',
walletPassphrase: 'test_wallet_passphrase',
recoveryDestination: 'TEbha9FhQMZ3FRtZgok8QBunPQU4pZvBxX',
})
.should.be.rejectedWith("Amount of funds to recover undefined is less than 2100000 and wouldn't be able to fund a send");
});
it('should generate recovery tx with unencrypted keys', async function () {
recoveryNocks.nockTronRecovery();
const recoveryTx = await baseCoin.recover({
userKey: 'xpub661MyMwAqRbcGKN3UxRqwKdVNRbJvqxiNaWBCfXcUJaEf56wqRsGR6R7tmWrpnjbdQLryb6hzx8RfXXsvRqBuB2idGg1NeD1yueWcsBoq7A',
backupKey: 'xpub661MyMwAqRbcF5b9fJAfJp6P9p2LmeZV7YbfgDkttGJrGdmLtsLxyHTQaoPE1pJr5EA7SBwMSzFmv2TvsDLtG42FeesyaVQazBX4YmD28bh',
bitgoKey: 'xpub661MyMwAqRbcEx6zKTBrgZkWPBGvx8qguEd1NqEDp6yW3srBGhTUdFkcdcBjp5FQgXkDNiQBdj6Fsgka8D9VFYt32M2GsCTRuffnXMhq1ho',
recoveryDestination: 'TYPgx8NfDxB8pyiyTeiMkYzem1dNA6G12i',
});
should.exist(recoveryTx);
recoveryTx.coin.should.equal('ttrx');
recoveryTx.feeInfo.fee.should.equal('2100000');
recoveryTx.recoveryAmount.should.equal(899047400);
recoveryTx.tx.txID.should.equal('98b398e3027e601870a86b0785f1f1d301f087dbaafe44337507b5001bae0d49');
recoveryTx.tx.raw_data_hex.should.equal('0a02a762220818dfe946fbf7a0ac40f89181afe6305a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a1541e7e11df2c5704888c3cb63fb43a9498bd1812cb2121541f5f414d447aafe70bb9b9d93912cbc4c54f0c01418c8d19cad0370b78be485e630');
});
it('should generate an unsigned sweep', async function () {
recoveryNocks.nockTronRecovery();
const recoveryTx = await baseCoin.recover({
userKey: '{"iv":"eXwYIygDyRy1R1lw9EwEgQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"NNOxF+LR7aU=","ct":"qX/G+AiZJ35XwUmL9alYitRwvYgE/bS24DSAVV7tBaoTs40tsVB/kWx+hV/J5acKIA6Z/wSucxbKrQlJB69xJJl/OirYqmXRBirH+rag1aC1zj7ZVnbO+h+P5GHqHJltLc4UyDf+p22+NjoDLfR+fEPtG8c4v5o="}',
backupKey: 'xpub661MyMwAqRbcF5b9fJAfJp6P9p2LmeZV7YbfgDkttGJrGdmLtsLxyHTQaoPE1pJr5EA7SBwMSzFmv2TvsDLtG42FeesyaVQazBX4YmD28bh',
bitgoKey: 'xpub661MyMwAqRbcEx6zKTBrgZkWPBGvx8qguEd1NqEDp6yW3srBGhTUdFkcdcBjp5FQgXkDNiQBdj6Fsgka8D9VFYt32M2GsCTRuffnXMhq1ho',
walletPassphrase: 'test_wallet_passphrase',
recoveryDestination: 'TYPgx8NfDxB8pyiyTeiMkYzem1dNA6G12i',
});
should.exist(recoveryTx);
recoveryTx.coin.should.equal('ttrx');
recoveryTx.feeInfo.fee.should.equal('2100000');
recoveryTx.recoveryAmount.should.equal(899047400);
recoveryTx.tx.txID.should.equal('98b398e3027e601870a86b0785f1f1d301f087dbaafe44337507b5001bae0d49');
recoveryTx.tx.raw_data_hex.should.equal('0a02a762220818dfe946fbf7a0ac40f89181afe6305a69080112650a2d747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e73666572436f6e747261637412340a1541e7e11df2c5704888c3cb63fb43a9498bd1812cb2121541f5f414d447aafe70bb9b9d93912cbc4c54f0c01418c8d19cad0370b78be485e630');
});
it('should generate a token recovery tx from encrypted user and backup keys', async function () {
recoveryNocks.nockTronTokenRecovery();
const recoveryTx = await baseCoin.recover({
userKey: '{"iv":"RyjTV4B09tQT576jAM2nLg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"nJdtmecHNME=","ct":"5rCeihO3pZmd+vMYStP0f0zLbJkHhdvax+6ZAr5R4VmvjJnQqWjKkz4iqV2F1dSZVzNTU97hHjZE5d3DpJhy7rFsFFIFVutjORSZv8Wnr0g99XOiEDbuDENE2BQyTkOzSYLLGIi71myuwgAjBuQMomk0+7gtfjY="}',
backupKey: '{"iv":"vnbzx3YnSRHRMUnEOTmHLw==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"2D32eMOgkZc=","ct":"yKP0jnRkv/XnMHP6mJMQGozvtkkiHJpYxD6o1n7FcN44oOJHoQAI0xrew7WyGTzOpzoA0E0BH00Abi9XINNnQ5LLgJRdIF0HbJxfkj1QvElckMH94DMxn14s9cYQgIkI676vhwFBhAAwvbN8458wqtXsl+0Lnrs="}',
bitgoKey: 'xpub661MyMwAqRbcGYq9RtWYzKuvqba2EHr9vAkDbPsNi1L9TmiHSRUXHqxe18P4DHXtDFtUy4Sb9bhpShHEWW9h3LwHM9bB2qoP2cwWTduV9nP',
walletPassphrase: 'test_wallet_passphrase',
tokenContractAddress: 'TG3XXyExBkPp9nzdajDZsozEu4BkaSJozs',
recoveryDestination: 'TYPgx8NfDxB8pyiyTeiMkYzem1dNA6G12i',
});
should.exist(recoveryTx);
recoveryTx.tx.signature[0].should.equal('3a67eee7ae067cd85cae86530be338af2cff4034a30f39656e2d8117ff7915ad256176afcfbe8177c4195ea887d79740420b12f9ea7c5698a6d2eeec260f34df01');
recoveryTx.tx.signature[1].should.equal('551d41e007b8b36b2ac50297fd53678f196067848731f4340f7ee0eb6d963c24b11dde96727f3cf4d051af586869daa51394db0853e6d4c80e41fee414a9c95201');
recoveryTx.tx.txID.should.equal('28117d9f0c3ac1fe22fa2cb10412537763fea8ad6b4b8d0504d8f25c6141f43c');
recoveryTx.tx.raw_data_hex.should.equal('0a02a71c2208d0ecb53aa03882a640d89cf3aee6305aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a15416a0a05e098c628f7f3ca63dbb5756e5c0c01852112154142a1e39aefa49290f2b3f9ed688d7cecf86cd6e02244a9059cbb000000000000000000000000f5f414d447aafe70bb9b9d93912cbc4c54f0c014000000000000000000000000000000000000000000000000000000012410110070a2a9d685e630900180c2d72f');
});
});
describe('Recover EOS', function () {
let baseCoin;
const expectedPackedTrx = '7122315d5e91d408e1b3000000000100a6823403ea3055000000572d3ccdcd0150f3ea2e4cf4bc8300000000a8ed32322150f3ea2e4cf4bc83e0f27c27cc0adf7f40420f000000000004454f53000000000000';
const expectedTxId = '99c6a4eedf5cff246314bdc0a053c12d75488df3aa09474bad4ceca88d8b2498';
before(function () {
baseCoin = bitgo.coin('teos');
});
beforeEach(function () {
recoveryNocks.nockEosRecovery();
});
it('should generate EOS recovery tx with correct expiration date', async function () {
const recoveryTx = await baseCoin.recover({
userKey: '{"iv":"jRBZi43c7t4tvx7SgP8h0g==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"TgZqHtZrmLU=","ct":"hRntzrbcH81dOzlyr49nbAIJdHWqEKKVJx0s55kNV+fqUjKKoEuWqVGF1dPfQkkTkcIjFTNvuHsiGicVGSRf5RI3Q0ZD6YtCqO2bWX6t7HgBio5yYMaPy+cNJHmp6jHBQFZ9cCjqwAam/V+1mRvpJpn2dSWPotw="}',
backupKey: '{"iv":"qE+D+C6KXaZKFXXTM/AF5w==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"a/YD7/8gJFw=","ct":"tc2c1PfSjDS9TshXEIKKlToDcdCeL45fpGUWEPIM2+6CrvIuaXZC6/Hx9bza7VIoEPhJWHmgvoeAouto4PUpnyKJUuz+T46RY09XJs2rcDvbfMKblRsh6lzUc8O7ubTzJRNgFOUqkZM6qGB22A0FtL8yNlFqc3c="}',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
rootAddress: 'kiyjcn1ixftp',
recoveryDestination: 'jzjkpn1bjnti',
});
recoveryTx.should.have.property('transaction');
recoveryTx.transaction.compression.should.equal('none');
recoveryTx.transaction.packed_trx.should.equal(expectedPackedTrx);
recoveryTx.transaction.signatures.length.should.equal(2);
recoveryTx.txid.should.equal(expectedTxId);
const deserializeTransactionParams = {
transaction: {
packed_trx: recoveryTx.transaction.packed_trx,
},
};
const deserializedTx = await baseCoin.deserializeTransaction(deserializeTransactionParams);
const mockedHeadBlockTime = '2019-07-18T17:52:49.000';
const hoursUntilExpiration = 8;
const hourDiff = (new Date(deserializedTx.expiration).getTime() - new Date(mockedHeadBlockTime).getTime()) / 36e5;
hourDiff.should.equal(hoursUntilExpiration);
});
it('should generate EOS recovery tx with unencrypted keys', async function () {
const recoveryTx = await baseCoin.recover({
userKey: 'xprv9s21ZrQH143K4NDgnKH8zTTLpJuCmv6dtykRJwapBH73bvcvTvCQAMmQLxRGqg5YbvXBN5VGD3y2cPGUGyrVcjWDJM573RVseHg4oL64AXx',
backupKey: 'xprv9s21ZrQH143K4Gh3snX8z5d24djEVwCwVwdHGEssUpKwHqKDtAz8gRPw7Fi12NC3ur94CsJ2KormunQQm3gNkXQiTy534NdfuQ4C2EpdmRp',
rootAddress: 'kiyjcn1ixftp',
recoveryDestination: 'jzjkpn1bjnti',
});
recoveryTx.should.have.property('transaction');
recoveryTx.transaction.compression.should.equal('none');
recoveryTx.transaction.packed_trx.should.equal(expectedPackedTrx);
recoveryTx.transaction.signatures.length.should.equal(2);
recoveryTx.txid.should.equal(expectedTxId);
});
it('should generate an EOS unsigned sweep', async function () {
const recoveryTx = await baseCoin.recover({
userKey: 'xpub661MyMwAqRbcGrJ9tLp9MbQ5NLjhBNpVGCg27KzRjce2Uix51TWeiA5tCDyBFHENmKSf6BiWg3tAjYgrhTz9bZGdXj7pfksXaEpVLQqzYEE',
backupKey: 'xpub661MyMwAqRbcGkmWyp49MDZkcfZiuPvnsAYt4dHV39rvAdeNRiJPEDiQxYTNrbFEHJVBJWBdxW7DgCqRUyVpYAbT3D6LGsZpynYpMFAgAZr',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
rootAddress: 'kiyjcn1ixftp',
recoveryDestination: 'jzjkpn1bjnti',
});
recoveryTx.should.have.property('transaction');
recoveryTx.transaction.compression.should.equal('none');
recoveryTx.transaction.packed_trx.should.equal(expectedPackedTrx);
recoveryTx.transaction.signatures.length.should.equal(0);
recoveryTx.txid.should.equal(expectedTxId);
});
});
describe('Recover ERC20', function () {
it('should successfully construct a recovery transaction for tokens stuck in a wallet', async function () {
const wallet = bitgo.nockEthWallet();
// There should be 24 Potatokens stuck in our test wallet (based on nock)
const tx = await wallet.recoverToken({
tokenContractAddress: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_ADDRESS,
recipient: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_PASSPHRASE,
});
should.exist(tx);
tx.should.have.property('halfSigned');
const txInfo = tx.halfSigned;
txInfo.should.have.property('contractSequenceId');
txInfo.contractSequenceId.should.equal(1101);
txInfo.should.have.property('expireTime');
txInfo.should.have.property('gasLimit');
txInfo.gasLimit.should.equal(500000);
txInfo.should.have.property('gasPrice');
txInfo.gasPrice.should.equal(20000000000);
txInfo.should.have.property('operationHash');
txInfo.should.have.property('signature');
txInfo.should.have.property('tokenContractAddress');
txInfo.tokenContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_ADDRESS);
txInfo.should.have.property('walletId');
txInfo.walletId.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_ID);
txInfo.should.have.property('recipient');
txInfo.recipient.should.have.property('address');
txInfo.recipient.address.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT);
txInfo.recipient.should.have.property('amount');
txInfo.recipient.amount.should.equal('2400');
});
it('should successfully generate an ERC20 unsigned sweep', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('tdai');
// There should be 1 TDAI token in our test wallet (based on nock)
const transaction = await basecoin.recover({
userKey: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
backupKey: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
walletContractAddress: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS,
tokenContractAddress: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_ADDRESS,
recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
});
should.exist(transaction);
transaction.should.have.property('tx');
transaction.should.have.property('contractSequenceId');
transaction.should.have.property('expireTime');
transaction.should.have.property('gasLimit');
transaction.gasLimit.should.equal('500000');
transaction.should.have.property('gasPrice');
transaction.gasPrice.should.equal('20000000000');
transaction.should.have.property('tokenContractAddress');
transaction.tokenContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_TDAI_TOKEN_ADDRESS);
transaction.should.have.property('walletContractAddress');
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
transaction.should.have.property('recipient');
transaction.recipient.should.have.property('address');
transaction.recipient.address.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT);
transaction.recipient.should.have.property('amount');
transaction.recipient.amount.should.equal('1000000000000000000');
});
it('should use user provided gas params when building recovery transaction', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('tdai');
// There should be 1 TDAI token in our test wallet (based on nock)
const transaction = await basecoin.recover({
userKey: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
backupKey: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
walletContractAddress: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS,
tokenContractAddress: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_ADDRESS,
recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
gasLimit: '400000',
eip1559: {
maxFeePerGas: '10000000000',
maxPriorityFeePerGas: '5000',
},
});
should.exist(transaction);
transaction.should.have.property('tx');
transaction.should.have.property('contractSequenceId');
transaction.should.have.property('expireTime');
transaction.should.have.property('gasLimit');
transaction.should.have.property('eip1559');
transaction.gasLimit.should.equal('400000');
transaction.should.have.property('gasPrice');
transaction.gasPrice.should.equal('10000000000');
transaction.should.have.property('tokenContractAddress');
transaction.tokenContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_TDAI_TOKEN_ADDRESS);
transaction.should.have.property('walletContractAddress');
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
transaction.should.have.property('recipient');
transaction.recipient.should.have.property('address');
transaction.recipient.address.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT);
transaction.recipient.should.have.property('amount');
transaction.recipient.amount.should.equal('1000000000000000000');
});
});
describe('API Key usage in recovery', function () {
let basecoin;
let sandbox;
before(function () {
basecoin = bitgo.coin('hteth');
sandbox = sinon.createSandbox();
});
afterEach(function () {
sandbox.restore();
nock.cleanAll();
});
it('Eth Recovery overrides env etherscan api key if provided ', async function () {
const customApiKey = 'custom-key'; // Custom API key for etherscan
const recoveryParams = {
userKey: 'xpub661MyMwAqRbcFjHW9Qv2wCGehMiQXYPuLKGdJRx9L9qvaGQfM7rCjvW1MQWZmi1arGK9PN6zPtkUvi8g3oNTkgR2dNg8HjGYW81jm68sCCy',
backupKey: 'xpub661MyMwAqRbcGTKcjByQ7nFJBiUBWQPKUEwsUZnw58RS5efcujUSxrQxjdRn1Rp5DGzRP8rkzqtHdUvJMH9Y2zvSV5JjsaBpFKWBwjTrMyC',
walletContractAddress: '0xff169682bfde5b811ba90a61aea39bedd78c2f75',
recoveryDestination: '0x33e6b4dd60a917d24170eb96d5eb25fa2277a92f',
isUnsignedSweep: true,
apiKey: customApiKey,
};
// Create spy on queryAddressBalance to verify apiKey usage
const queryAddressBalanceSpy = sandbox.spy(basecoin, 'queryAddressBalance');
const getAddressNonceSpy = sandbox.spy(basecoin, 'getAddressNonce');
const querySequenceIdSpy = sandbox.spy(basecoin, 'querySequenceId');
const recoveryBlockchainExplorerQuerySpy = sandbox.spy(basecoin, 'recoveryBlockchainExplorerQuery');
nock('https://api.etherscan.io')
.get('/api')
.query((actual) => {
return actual.module === 'account' && actual.action === 'txlist' && actual.apikey === customApiKey;
})
.reply(200, {
status: '1',
message: 'OK',
result: [
{
blockNumber: '1125356',
timeStamp: '1710252036',
hash: '0x01b0642c852592a772495b8b3b4fbd203c5b0142579801e1c223fe86700174c2',
nonce: '588543',
from: '0x6cc9397c3b38739dacbfaa68ead5f5d77ba5f455',
to: '0x56c879503c8e74dc1a9a140ab5a920b7cd9871e9',
value: '470779375000000000',
gas: '21000',
gasPrice: '6117622005',
},
],
});
// Mock backup key balance check
nock('https://api.etherscan.io')
.get('/api')
.query((actual) => {
return (actual.module === 'account' &&
actual.action === 'balance' &&
actual.apikey === customApiKey &&
actual.address === '0x56c879503c8e74dc1a9a140ab5a920b7cd9871e9');
})
.reply(200, {
status: '1',
message: 'OK',
result: '926211656736450471',
});
// Mock wallet contract balance check
nock('https://api.etherscan.io')
.get('/api')
.query((actual) => {
return (actual.module === 'account' &&
actual.action === 'balance' &&
actual.apikey === customApiKey &&
actual.address === '0xff169682bfde5b811ba90a61aea39bedd78c2f75');
})
.reply(200, {
status: '1',
message: 'OK',
result: '518749999999999000',
});
// Mock sequence ID query
nock('https://api.etherscan.io')
.get('/api')
.query((actual) => {
return (actual.module === 'proxy' &&
actual.action === 'eth_call' &&
actual.apikey === customApiKey &&
actual.data === 'a0b7967b');
})
.reply(200, {
jsonrpc: '2.0',
id: 1,
result: '0x0000000000000000000000000000000000000000000000000000000000000002',
});
// Additional nock for the v2 API endpoint with chainid parameter for txlist
nock('https://api.etherscan.io')
.get('/v2/api')
.query((actual) => {
return (actual.chainid === '560048' &&
actual.module === 'account' &&
actual.action === 'txlist' &&
actual.address === '0x56c879503c8e74dc1a9a140ab5a920b7cd9871e9' &&
actual.apikey === customApiKey);
})
.reply(200, {
status: '1',
message: 'OK',
result: [
{
blockNumber: '1125356',
timeStamp: '1710252036',
hash: '0x01b0642c852592a772495b8b3b4fbd203c5b0142579801e1c223fe86700174c2',
nonce: '588543',
blockHash: '0x172f67d8c9bc8ac181a83c8f9363e7365239f88b6fbdf851c1b354519be7287a',
transactionIndex: '3',
from: '0x6cc9397c3b38739dacbfaa68ead5f5d77ba5f455',
to: '0x56c879503c8e74dc1a9a140ab5a920b7cd9871e9',
value: '470779375000000000',
gas: '21000',
gasPrice: '6117622005',
isError: '0',
txreceipt_status: '1',
input: '0x',
contractAddress: '',
cumulativeGasUsed: '84000',
gasUsed: '21000',
confirmations: '3089935',
methodId: '0x',
functionName: '',
},
],
});
// Additional nock for the v2 API endpoint with chainid parameter for backup key balance
nock('https://api.etherscan.io')
.get('/v2/api')
.query((actual) => {
return (actual.chainid === '560048' &&
actual.module === 'account' &&
actual.action === 'balance' &&
actual.address === '0x56c879503c8e74dc1a9a140ab5a920b7cd9871e9' &&
actual.apikey === customApiKey);
})
.reply(200, {
status: '1',
message: 'OK',
result: '926211656736450471',
});
// Additional nock for the v2 API endpoint with chainid parameter for wallet contract balance
nock('https://api.etherscan.io')
.get('/v2/api')
.query((actual) => {
return (actual.chainid === '560048' &&
actual.module === 'account' &&
actual.action === 'balance' &&
actual.address === '0xff169682bfde5b811ba90a61aea39bedd78c2f75' &&
actual.apikey === customApiKey);
})
.reply(200, {
status: '1',
message: 'OK',
result: '518749999999999000',
});
// Additional nock for the v2 API endpoint with chainid parameter for sequence ID query
nock('https://api.etherscan.io')
.get('/v2/api')
.query((actual) => {
return (actual.chainid === '560048' &&
actual.module === 'proxy' &&
actual.action === 'eth_call' &&
actual.to === '0xff169682bfde5b811ba90a61aea39bedd78c2f75' &&
actual.data === 'a0b7967b' &&
actual.tag === 'latest' &&
actual.apikey === customApiKey);
})
.reply(200, {
jsonrpc: '2.0',
id: 1,
result: '0x0000000000000000000000000000000000000000000000000000000000000002',
});
nock('https://api.etherscan.io')
.get('/v2/api')
.query((actual) => {
return (actual.chainid === '560048' &&
actual.module === 'account' &&
actual.action === 'txlist' &&
actual.address === '0x56c879503c8e74dc1a9a140ab5a920b7cd9871e9' &&
actual.apikey === customApiKey);
})
.reply(200, {
status: '1',
message: 'OK',
result: [
{
blockNumber: '4214015',
timeStamp: '1753283724',
hash: '0xd0b3a93ddfe62f533a36cf02c5ca9428967aca31fcce3c80159b5a958b298420',
nonce: '22',
blockHash: '0x588293d0274643abd0a121cf054f29842eabd400d0251527585bb5797183a814',
transactionIndex: '2',
from: '0x56c879503c8e74dc1a9a140ab5a920b7cd9871e9',
to: '0xff169682bfde5b811ba90a61aea39bedd78c2f75',
value: '0',
gas: '196618',
gasPrice: '1380010',
isError: '0',
txreceipt_status: '1',
input: '0x39125215000000000000000000000000333eba73b8c96bd8ac2b19485ab8fc2b07973e6000000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000688a3702000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000412870d16f7a02b8ae8809559ad6c7b3c7742fe57e4c068ee0ea20d5c71f9ec2c561a582d91a231cf0137b12d65058d50638d779f86f958c748cb988d4b68244311c00000000000000000000000000000000000000000000000000000000000000',
contractAddress: '',
cumulativeGasUsed: '767545',
gasUsed: '124463',
confirmations: '2245',
methodId: '0x39125215',
functionName: 'sendMultiSig(address toAddress,uint256 value,bytes data,uint256 expireTime,uint256 sequenceId,bytes signature)',
},
],
});
try {
const recovery = await basecoin.recover(recoveryParams);
should.exist(recovery);
recovery.should.have.property('tx');
recovery.tx.should.match(/^f9012b.*808080$/); // Transaction hex format check
recovery.recipients[0].address.should.equal('0x33e6b4dd60a917d24170eb96d5eb25fa2277a92f');
recovery.recipients[0].amount.should.equal('518749999999999000');
recovery.contractSequenceId.should.equal(2);
}
catch (e) {
sinon.assert.fail(e);
}
// Verify API key is correctly passed to each blockchain explorer query
sinon.assert.called(recoveryBlockchainExplorerQuerySpy);
const explorerQueryCalls = recoveryBlockchainExplorerQuerySpy.getCalls();
// Check that all calls used the custom API key
explorerQueryCalls.forEach((call) => {
call.args[1].should.equal(customApiKey);
});
// Verify specific functions received the API key
if (queryAddressBalanceSpy.called) {
const queryAddressBalanceCall = queryAddressBalanceSpy.getCall(0);
queryAddressBalanceCall.args[1].should.equal(customApiKey);
}
if (getAddressNonceSpy.called) {
const getAddressNonceCall = getAddressNonceSpy.getCall(0);
getAddressNonceCall.args[1].should.equal(customApiKey);
}
if (querySequenceIdSpy.called) {
const querySequenceIdCall = querySequenceIdSpy.getCall(0);
querySequenceIdCall.args[1].should.equal(customApiKey);
}
});
});
describe('Recover Ethereum', function () {
beforeEach(() => {
nock.cleanAll();
});
let recoveryParams;
const nockTSSData = [
{
params: {
module: 'account',
action: 'txlist',
address: '0xe7406dc43d13f698fb41a345c7783d39a4c2d191',
},
response: {
status: '0',
message: 'No transactions found',
result: [],
},
},
{
params: {
module: 'account',
action: 'balance',
address: '0xe7406dc43d13f698fb41a345c7783d39a4c2d191',
},
response: {
status: '1',
message: 'OK',
result: '1000000000000000000',
},
},
];
const nockUnsignedSweepTSSData = [
{
params: {
module: 'account',
action: 'txlist',
address: '0xa91e1059953d7ef2adbbca4b688bfe22866fbcee',
},
response: {
status: '0',
message: 'No transactions found',
result: [],
},
},
{
params: {
module: 'account',
action: 'balance',
address: '0xa91e1059953d7ef2adbbca4b688bfe22866fbcee',
},
response: {
status: '1',
message: 'OK',
result: '1000000000000000000',
},
},
];
let recoverEthSandbox;
before(() => {
recoveryParams = {
userKey: '{"iv":"+TkmT3GJ5msVWQjBrt3lsw==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
':"ccm","adata":"","cipher":"aes","salt":"cCE20fGIobs=","ct":"NVIdYIh91J3aRI\n' +
'8GG0JE3DhXW3AUmz2G5RqMejdz1+t4/vovIP7lleegI7VYyWiiLvlM0OCFf3EVvV/RyXr8+2vsn\n' +
'Q0Vn8c2CV5FRZ80OjGYrW3A/6T/zpOz6E8CMvnD++iIpeO4r2eZJavejZxdzlxF0BRz7VI="}',
backupKey: '{"iv":"asB356ofC7nZtg4NBvQkiQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
':"ccm","adata":"","cipher":"aes","salt":"1hr2HhBbBIk=","ct":"8CZc6upt+XNOto\n' +
'KDD38TUg3ZUjzW+DraZlkcku2bNp0JS2s1g/iC6YTGUGtPoxDxumDlXwlWQx+5WPjZu79M8DCrI\n' +
't9aZaOvHkGH9aFtMbavFX419TcrwDmpUeQFN0hRkfrIHXyHNbTpGSVAjHvHMtzDMaw+ACg="}',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
walletContractAddress: '0x5df5a96b478bb1808140d87072143e60262e8670',
recoveryDestination: '0xac05da78464520aa7c9d4c19bd7a440b111b3054',
replayProtectionOptions: {
chain: 42,
hardfork: 'london',
},
};
recoverEthSandbox = sinon.createSandbox();
recoverEthSandbox
.stub(sdk_lib_mpc_1.EcdsaRangeProof, 'generateNtilde')
.resolves(sdk_lib_mpc_1.EcdsaTypes.deserializeNtildeWithProofs(sdk_test_1.mockSerializedChallengeWithProofs));
});
after(() => {
recoverEthSandbox.restore();
});
it('should throw on invalid gasLimit', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
await basecoin
.recover({
...recoveryParams,
gasLimit: -400000,
gasPrice: 25000000000,
})
.should.be.rejectedWith('Gas limit must be between 30000 and 20000000');
});
it('should throw if etherscan errs', async function () {
const nockUnsuccessfulEtherscanData = [
{
params: {
module: 'account',
action: 'txlist',
address: '0x74c2137d54b0fc9f907e13f14e0dd18485fee924',
},
response: {
status: '0',
message: 'No transactions found',
result: [],
},
},
{
params: {
module: 'account',
action: 'balance',
address: '0x74c2137d54b0fc9f907e13f14e0dd18485fee924',
},
response: {
status: '1',
message: 'NOTOK',
result: 'Rate limit exceeded',
},
},
];
recoveryNocks.nockEthLikeRecovery(bitgo, nockUnsuccessfulEtherscanData);
const basecoin = bitgo.coin('hteth');
await basecoin
.recover(recoveryParams)
.should.be.rejectedWith('Could not obtain address balance for 0x74c2137d54b0fc9f907e13f14e0dd18485fee924 from the explorer, got: Rate limit exceeded');
});
it('should throw if backup key address has insufficient balance', async function () {
const insufficientFeeData = [
{
params: {
module: 'account',
action: 'txlist',
address: '0x74c2137d54b0fc9f907e13f14e0dd18485fee924',
},
response: {
status: '0',
message: 'No transactions found',
result: [],
},
},
{
params: {
module: 'account',
action: 'balance',
address: '0x74c2137d54b0fc9f907e13f14e0dd18485fee924',
},
response: {
status: '1',
message: 'OK',
result: '1234',
},
},
];
recoveryNocks.nockEthLikeRecovery(bitgo, insufficientFeeData);
const basecoin = bitgo.coin('hteth');
await basecoin
.recover({
...recoveryParams,
gasLimit: 300000,
gasPrice: 1000000000,
})
.should.be.rejectedWith('Backup key address 0x74c2137d54b0fc9f907e13f14e0dd18485fee924 has balance 0.000001234 Gwei.' +
'This address must have a balance of at least 300000 Gwei to perform recoveries. Try sending some ETH to this address then retry.');
});
it('should throw on invalid gasPrice', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
await basecoin
.recover({
...recoveryParams,
gasLimit: 400000,
gasPrice: 2500000,
})
.should.be.rejectedWith('Gas price must be between 1000000000 and 2500000000000');
});
it('should successfully construct a tx with custom gas price and limit', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
const recovery = await basecoin.recover({
...recoveryParams,
gasLimit: 400000,
gasPrice: 1000000000,
});
// id and tx will always be different because of expireTime
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
});
it('should construct a recovery transaction without BitGo', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
const recovery = await basecoin.recover(recoveryParams);
// id and tx will always be different because of expireTime
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
});
it('should construct an eip1559 recovery transaction without BitGo', async function () {
const eip1559RecoveryParams = {
...recoveryParams,
eip1559: {
maxPriorityFeePerGas: 3,
maxFeePerGas: 20,
},
};
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
const recovery = await basecoin.recover(eip1559RecoveryParams);
// id and tx will always be different because of expireTime
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
});
it('should construct a recovery transaction without BitGo and with KRS', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
const recovery = await basecoin.recover({
...recoveryParams,
backupKey: 'xpub661MyMwAqRbcGsCNiG4BzbxLmXnJFo4K5gVSE2b9AxufAtpuTun1SYwg9Uykqqf4DrKrDZ6KqPm9ehthWbCma7pnaMrtXY11nY7MeFbEDPm',
krsProvider: 'keyternal',
});
// id and tx will always be different because of expireTime
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
});
it('should error when the backup key is unfunded (cannot pay gas)', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
await basecoin
.recover({
userKey: '{"iv":"VNvG6t3fHfxMcfvNuafYYA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
':"ccm","adata":"","cipher":"aes","salt":"mc9pCk3H43w=","ct":"Qe4Z1evaXcrOMC\n' +
'cQ/XMVVBO9M/99D1QQ6LxkG8z3fQtwwOVXM3/6doNrriprUqs+adpFC93KRcAaDroL1E6o17J2k\n' +
'mcpXRd2CuXRFORZmZ/6QBfjKfCJ3aq0kEkDVv37gZNVT3aNtGkNSQdCEWKQLwd1++r5AkA="}\n',
backupKey: '{"iv":"EjD7x0OJX9kNM/C3yEDvyQ==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
':"ccm","adata":"","cipher":"aes","salt":"Na9NvRRe3n8=","ct":"B/AtSLHolsdNLr\n' +
'4Dlij4kQ0E6NyUUs6wo6T2HtPDAPO0hyhPPbh1OAYqIS7VlL9xmJRFC2zPxwRJvzf6OWC/m48HX\n' +
'vgLoXYgahArhalzJVlRxcXUz4HOhozRWfv/eK3t5HJfm+25+WBOiW8YgSE7hVEYTbeBRD4="}',
walletContractAddress: '0x22ff743216b58aeb3efc46985406b50112e9e176',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
recoveryDestination: '0xac05da78464520aa7c9d4c19bd7a440b111b3054',
})
.should.be.rejectedWith('Backup key address 0xba6d9d82cf2920c544b834b72f4c6d11a3ef3de6 has balance 0 Gwei.This address must have a balance of at least 10000000 Gwei to perform recoveries. Try sending some ETH to this address then retry.');
});
it('should throw error when the etherscan rate limit is reached', async function () {
const basecoin = bitgo.coin('hteth');
recoveryNocks.nockEtherscanRateLimitError();
await basecoin.recover(recoveryParams).should.be.rejectedWith('Etherscan rate limit reached');
});
it('should generate an ETH unsigned sweep', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo);
const basecoin = bitgo.coin('hteth');
const transaction = await basecoin.recover({
userKey: 'xpub661MyMwAqRbcFXDcWD2vxuebcT1ZpTF4Vke6qmMW8yzddwNYpAPjvYEEL5jLfyYXW2fuxtAxY8TgjPUJLcf1C8qz9N6VgZxArKX4EwB8rH5',
backupKey: 'xpub661MyMwAqRbcGhSaXikpuTC9KU88Xx9LrjKSw1JKsvXNgabpTdgjy7LSovh9ZHhcqhAHQu7uthu7FguNGdcC4aXTKK5gqTcPe4WvLYRbCSG',
walletContractAddress: sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS,
recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
gasPrice: '20000000000',
gasLimit: '500000',
});
should.exist(transaction);
transaction.should.have.property('tx');
transaction.should.have.property('contractSequenceId');
transaction.should.have.property('expireTime');
transaction.should.have.property('gasLimit');
transaction.gasLimit.should.equal('500000');
transaction.should.have.property('gasPrice');
transaction.gasPrice.should.equal('20000000000');
transaction.should.have.property('walletContractAddress');
transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
transaction.should.have.property('recipient');
transaction.recipient.should.have.property('address');
transaction.recipient.address.should.equal(sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT);
transaction.recipient.should.have.property('amount');
transaction.recipient.amount.should.equal('9999999999999999928');
});
it('should construct a recovery tx with TSS', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo, nockTSSData);
const basecoin = bitgo.coin('hteth');
const baseAddress = recoveryFixtures_1.ethLikeGG18Keycard.senderAddress;
const nockTSSDataWithBaseAddress = nockTSSData.map((data) => {
return {
...data,
params: {
...data.params,
address: baseAddress,
},
};
});
recoveryNocks.nockEthLikeRecovery(bitgo, nockTSSDataWithBaseAddress);
recoveryParams = {
userKey: recoveryFixtures_1.ethLikeGG18Keycard.userKey,
backupKey: recoveryFixtures_1.ethLikeGG18Keycard.backupKey,
walletContractAddress: recoveryFixtures_1.ethLikeGG18Keycard.senderAddress,
recoveryDestination: recoveryFixtures_1.ethLikeGG18Keycard.destinationAddress,
walletPassphrase: recoveryFixtures_1.ethLikeGG18Keycard.walletPassphrase,
eip1559: {
maxPriorityFeePerGas: 3,
maxFeePerGas: 20,
},
isTss: true,
replayProtectionOptions: {
chain: 5,
hardfork: 'london',
},
};
const recovery = await basecoin.recover(recoveryParams);
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
// verify data after signing is correct
const finalTx = tx_1.TransactionFactory.fromSerializedData(Buffer.from(recovery.tx.substr(2), 'hex'));
const senderAddress = finalTx.getSenderAddress().toString();
baseAddress.should.equal(senderAddress);
recoveryParams.recoveryDestination.should.equal(finalTx.to?.toString());
Number(finalTx.value).should.equal(999999999990000000);
});
it('should construct a recovery tx with MPCv2 TSS', async function () {
for (const { coin, chain } of [
{ coin: 'hteth', chain: 560048 },
{ coin: 'tpolygon', chain: 80002 },
{ coin: 'tbsc', chain: 97 },
]) {
recoveryNocks.nockEthLikeRecovery(bitgo, nockTSSData);
const basecoin = bitgo.coin(coin);
const baseAddress = recoveryFixtures_1.ethLikeDKLSKeycard.senderAddress;
const nockTSSDataWithBaseAddress = nockTSSData.map((data) => {
return {
...data,
params: {
...data.params,
address: baseAddress,
},
};
});
recoveryNocks.nockEthLikeRecovery(bitgo, nockTSSDataWithBaseAddress);
recoveryParams = {
userKey: recoveryFixtures_1.ethLikeDKLSKeycard.userKey,
backupKey: recoveryFixtures_1.ethLikeDKLSKeycard.backupKey,
walletContractAddress: baseAddress,
recoveryDestination: recoveryFixtures_1.ethLikeDKLSKeycard.destinationAddress,
walletPassphrase: recoveryFixtures_1.ethLikeDKLSKeycard.walletPassphrase,
eip1559: {
maxPriorityFeePerGas: 3,
maxFeePerGas: 20000000000,
},
isTss: true,
replayProtectionOptions: {
chain: chain,
},
};
if (coin === 'tbsc') {
recoveryParams.eip1559 = undefined;
recoveryParams['gasPrice'] = 20000000000;
}
const recovery = await basecoin.recover(recoveryParams);
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
// verify data after signing is correct
const finalTx = tx_1.TransactionFactory.fromSerializedData(Buffer.from(recovery.tx.substr(2), 'hex'));
const senderAddress = finalTx.getSenderAddress().toString();
finalTx.common.chainIdBN().toNumber().should.equal(chain);
baseAddress.should.equal(senderAddress);
recoveryParams.recoveryDestination.should.equal(finalTx.to?.toString());
Number(finalTx.value).should.equal(990000000000000000);
}
});
it('should construct an unsigned sweep tx with TSS', async function () {
recoveryNocks.nockEthLikeRecovery(bitgo, nockUnsignedSweepTSSData);
const basecoin = bitgo.coin('hteth');
const userKey = '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
const backupKey = '0234eb39b22fed523ece7c78da29ba1f1de5b64a6e48013e0914de793bc1df0570e779de04758732734d97e54b782c8b336283811af6a2c57bd81438798e1c2446';
recoveryParams = {
userKey: userKey,
backupKey: backupKey,
walletContractAddress: '0xe7406dc43d13f698fb41a345c7783d39a4c2d191',
recoveryDestination: '0xac05da78464520aa7c9d4c19bd7a440b111b3054',
walletPassphrase: sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE,
isTss: true,
gasPrice: '20000000000',
gasLimit: '500000',
replayProtectionOptions: {
chain: 42,
hardfork: 'london',
},
};
const transaction = await basecoin.recover(recoveryParams);
should.exist(transaction);
const output = transaction;
output.should.have.property('txRequests');
output.txRequests.should.have.length(1);
output.txRequests[0].should.have.property('transactions');
output.txRequests[0].transactions.should.have.length(1);
output.txRequests[0].should.have.property('walletCoin');
output.txRequests[0].transactions[0].should.have.property('unsignedTx');
output.txRequests[0].transactions[0].unsignedTx.should.have.property('serializedTxHex');
output.txRequests[0].transactions[0].unsignedTx.should.have.property('signableHex');
output.txRequests[0].transactions[0].unsignedTx.should.have.property('derivationPath');
output.txRequests[0].transactions[0].unsignedTx.should.have.property('feeInfo');
output.txRequests[0].transactions[0].unsignedTx.should.have.property('parsedTx');
const parsedTx = output.txRequests[0].transactions[0].unsignedTx.parsedTx;
parsedTx.should.have.property('spendAmount');
output.txRequests[0].transactions[0].unsignedTx.parsedTx.should.have.property('outputs');
});
});
describe('RecoverVet', function () {
beforeEach(() => {
nock.cleanAll();
});
let recoveryParams;
it('should construct a recovery tx with MPCv2 TSS', async function () {
const basecoin = bitgo.coin('tvet');
const baseAddress = recoveryFixtures_1.ethLikeDKLSKeycard.senderAddress;
recoveryNocks.nockVetRecovery(bitgo, baseAddress);
recoveryParams = {
userKey: recoveryFixtures_1.ethLikeDKLSKeycard.userKey,
backupKey: recoveryFixtures_1.ethLikeDKLSKeycard.backupKey,
walletContractAddress: baseAddress,
recoveryDestination: recoveryFixtures_1.ethLikeDKLSKeycard.destinationAddress,
walletPassphrase: recoveryFixtures_1.ethLikeDKLSKeycard.walletPassphrase,
isTss: true,
};
const recovery = await basecoin.recover(recoveryParams);
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
});
it('should construct an unsigned sweep tx with TSS', async function () {
recoveryNocks.nockVetRecovery(bitgo, '0xad848d2c97a08b2cd5e7f28f76ecd45dd0f82e0e');
const basecoin = bitgo.coin('tvet');
const unsignedSweepRecoveryParams = {
bitgoKey: '03f54983c529802697d9a2320ded23eb7f15118fcba01156356c2264f04d32b4caa77fcf8cf3f73547078e984f28787c4c1e694586214b609e45b6de9cc32ad6e5',
recoveryDestination: recoveryFixtures_1.ethLikeDKLSKeycard.destinationAddress,
};
const recovery = await basecoin.recover(unsignedSweepRecoveryParams);
should.exist(recovery);
recovery.should.have.property('txHex');
recovery.should.have.property('coin');
recovery.coin.should.equal('tvet');
});
it('should construct a token(vtho) recovery tx with MPCv2 TSS', async function () {
const basecoin = bitgo.coin('tvet');
const baseAddress = recoveryFixtures_1.ethLikeDKLSKeycard.senderAddress;
recoveryNocks.nockVetTokenRecovery(bitgo, baseAddress);
recoveryParams = {
userKey: recoveryFixtures_1.ethLikeDKLSKeycard.userKey,
backupKey: recoveryFixtures_1.ethLikeDKLSKeycard.backupKey,
walletContractAddress: baseAddress,
recoveryDestination: recoveryFixtures_1.ethLikeDKLSKeycard.destinationAddress,
walletPassphrase: recoveryFixtures_1.ethLikeDKLSKeycard.walletPassphrase,
tokenContractAddress: '0x0000000000000000000000000000456E65726779',
};
const recovery = await basecoin.recover(recoveryParams);
should.exist(recovery);
recovery.should.have.property('id');
recovery.should.have.property('tx');
});
it('should construct an unsigned sweep token tx(vtho) with TSS', async function () {
recoveryNocks.nockVetTokenRecovery(bitgo, '0xad848d2c97a08b2cd5e7f28f76ecd45dd0f82e0e');
const basecoin = bitgo.coin('tvet');
const unsignedSweepRecoveryParams = {
bitgoKey: '03f54983c529802697d9a2320ded23eb7f15118fcba01156356c2264f04d32b4caa77fcf8cf3f73547078e984f28787c4c1e694586214b609e45b6de9cc32ad6e5',
recoveryDestination: recoveryFixtures_1.ethLikeDKLSKeycard.destinationAddress,
tokenContractAddress: '0x0000000000000000000000000000456E65726779',
};
const recovery = await basecoin.recover(unsignedSweepRecoveryParams);
should.exist(recovery);
recovery.should.have.property('txHex');
recovery.should.have.property('coin');
recovery.coin.should.equal('tvet');
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3ZlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3YyL3VuaXQvcmVjb3ZlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBa0M7QUFDbEMsNkJBQThCO0FBRTlCLDhDQUErRTtBQUMvRSxzQ0FBcUM7QUFDckMsOENBQStDO0FBQy9DLG9EQUFpRTtBQUNqRSx1Q0FBb0Q7QUFDcEQsK0JBQStCO0FBQy9CLHVFQUEwRjtBQUMxRixzREFBNEM7QUFHNUMsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLHVCQUF1QixDQUFDLENBQUM7QUFFdkQsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7QUFFekIsUUFBUSxDQUFDLFdBQVcsRUFBRTtJQUNwQixJQUFJLEtBQUssQ0FBQztJQUVWLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxXQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNuRCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUUzQiwwREFBMEQ7UUFDMUQsdUJBQVksQ0FBQyxTQUFTLENBQUMsY0FBYyxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDaEgsdUJBQVksQ0FBQyxTQUFTLENBQUMsWUFBb0IsR0FBRztZQUM3QyxJQUFJLEVBQUUscUNBQXFDO1lBQzNDLElBQUksRUFBRSxxQ0FBcUM7WUFDM0MsSUFBSSxFQUFFLHFDQUFxQztZQUMzQyxLQUFLLEVBQUUscUNBQXFDO1lBQzVDLElBQUksRUFBRSxvQ0FBb0M7WUFDMUMsSUFBSSxFQUFFLHFDQUFxQztZQUMzQyxLQUFLLEVBQUUsb0NBQW9DO1NBQzVDLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVILEtBQUssQ0FBQztRQUNKLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNsQixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN6QixFQUFFLENBQUMsaUNBQWlDLEVBQUU7WUFDcEMsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBRWhDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEMsT0FBTyxRQUFRO2lCQUNaLE9BQU8sQ0FBQztnQkFDUCxPQUFPLEVBQ0wsNFNBQTRTO2dCQUM5UyxTQUFTLEVBQ1AsNFNBQTRTO2dCQUM5UyxXQUFXLEVBQUUsb0NBQW9DO2dCQUNqRCxnQkFBZ0IsRUFBRSxvQkFBUyxDQUFDLEVBQUUsQ0FBQyxxQkFBcUI7Z0JBQ3BELG1CQUFtQixFQUFFLDZDQUE2QzthQUNuRSxDQUFDO2lCQUNELElBQUksQ0FBQyxVQUFVLFFBQVE7Z0JBQ3RCLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FDekIsc3NCQUFzc0IsQ0FDdnNCLENBQUM7Z0JBQ0YsUUFBUSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGtFQUFrRSxDQUFDLENBQUM7Z0JBQzdGLFFBQVEsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDakQsUUFBUSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDeEMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO2dCQUN4RixRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUN0RCxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3RDLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMENBQTBDLEVBQUU7WUFDN0MsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBRWhDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEMsT0FBTyxRQUFRO2lCQUNaLE9BQU8sQ0FBQztnQkFDUCxPQUFPLEVBQ0wsNFNBQTRTO2dCQUM5UyxTQUFTLEVBQ1AsaUhBQWlIO2dCQUNuSCxXQUFXLEVBQUUsb0NBQW9DO2dCQUNqRCxnQkFBZ0IsRUFBRSxvQkFBUyxDQUFDLEVBQUUsQ0FBQyxxQkFBcUI7Z0JBQ3BELFdBQVcsRUFBRSxXQUFXO2dCQUN4QixtQkFBbUIsRUFBRSw2Q0FBNkM7YUFDbkUsQ0FBQztpQkFDRCxJQUFJLENBQUMsVUFBVSxRQUFRO2dCQUN0QixRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ3pCLDhiQUE4YixDQUMvYixDQUFDO2dCQUNGLFFBQVEsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxrRUFBa0UsQ0FBQyxDQUFDO2dCQUM3RixRQUFRLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQ2pELFFBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztnQkFDeEYsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDdEQsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0QyxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHVDQUF1QyxFQUFFO1lBQzFDLGFBQWEsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUVoQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BDLE9BQU8sUUFBUTtpQkFDWixPQUFPLENBQUM7Z0JBQ1AsT0FBTyxFQUNMLGlIQUFpSDtnQkFDbkgsU0FBUyxFQUNQLGlIQUFpSDtnQkFDbkgsV0FBVyxFQUFFLG9DQUFvQztnQkFDakQsZ0JBQWdCLEVBQUUsb0JBQVMsQ0FBQyxFQUFFLENBQUMscUJBQXFCO2dCQUNwRCxXQUFXLEVBQUUsV0FBVztnQkFDeEIsbUJBQW1CLEVBQUUsNkNBQTZDO2FBQ25FLENBQUM7aUJBQ0QsSUFBSSxDQUFDLFVBQVUsUUFBUTtnQkFDdEIsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUN6Qiw4S0FBOEssQ0FDL0ssQ0FBQztnQkFDRixNQUFNLEVBQUUsR0FBUSxvQkFBSyxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDeEQsRUFBRSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUMzQyxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztnQkFDOUQsRUFBRSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7Z0JBQ2xFLEVBQUUsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDdEMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO2dCQUNyQyxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ2xDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUM1QyxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzFCLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QixDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsaUJBQWlCLEVBQUU7UUFDMUIsS0FBSyxVQUFVLDBCQUEwQixDQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsY0FBYyxFQUFFLG1CQUFtQjtZQUN6RixNQUFNLFdBQVcsR0FBRyxNQUFNLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3hFLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUM1QyxXQUFXLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7Z0JBQ3BDLE1BQU0sRUFBRSxjQUFjLENBQUMsT0FBTyxFQUFFO2dCQUNoQyxPQUFPLEVBQUUsbUJBQW1CO2dCQUM1QixJQUFJLEVBQUUsUUFBUSxDQUFDLFFBQVEsRUFBRTthQUMxQixDQUFDLENBQUM7WUFDSCxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3RELFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDdEQsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNuRixXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFFRCxFQUFFLENBQUMsaUNBQWlDLEVBQUUsS0FBSztZQUN6QyxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7WUFFaEMsTUFBTSxjQUFjLEdBQUc7Z0JBQ3JCLE9BQU8sRUFBRSxvT0FBb087Z0JBQzdPLFNBQVMsRUFBRSxvT0FBb087Z0JBQy9PLFdBQVcsRUFBRSwwREFBMEQ7Z0JBQ3ZFLGdCQUFnQixFQUFFLG9CQUFTLENBQUMsRUFBRSxDQUFDLHNCQUFzQjtnQkFDckQsbUJBQW1CLEVBQUUsMERBQTBEO2FBQ2hGLENBQUM7WUFDRixNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUM7WUFFaEMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwQyxNQUFNLFFBQVEsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7WUFFeEQsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxjQUFjLENBQUMsQ0FBQztZQUVoRSxNQUFNLDBCQUEwQixDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsUUFBUSxFQUFFLGNBQWMsRUFBRSxjQUFjLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUNwSCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywwQ0FBMEMsRUFBRSxLQUFLO1lBQ2xELGFBQWEsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUVoQyxNQUFNLGNBQWMsR0FBRztnQkFDckIsT0FBTyxFQUFFLG9PQUFvTztnQkFDN08sU0FBUyxFQUFFLG9PQUFvTztnQkFDL08sV0FBVyxFQUFFLDBEQUEwRDtnQkFDdkUsZ0JBQWdCLEVBQUUsb0JBQVMsQ0FBQyxFQUFFLENBQUMsc0JBQXNCO2dCQUNyRCxtQkFBbUIsRUFBRSwwREFBMEQ7YUFDaEYsQ0FBQztZQUNGLE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQztZQUVoQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BDLE1BQU0sUUFBUSxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUV4RCxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDMUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBRWhFLE1BQU0sMEJBQTBCLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRLEVBQUUsY0FBYyxFQUFFLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3BILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHVEQUF1RCxFQUFFLEtBQUs7WUFDL0QsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBRWhDLE1BQU0sY0FBYyxHQUFHO2dCQUNyQixPQUFPLEVBQUUsMERBQTBEO2dCQUNuRSxTQUFTLEVBQUUsMERBQTBEO2dCQUNyRSxXQUFXLEVBQUUsMERBQTBEO2dCQUN2RSxtQkFBbUIsRUFBRSwwREFBMEQ7YUFDaEYsQ0FBQztZQUNGLE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQztZQUVoQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BDLE1BQU0sUUFBUSxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUV4RCxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDMUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBRWhFLE1BQU0sMEJBQTBCLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRLEVBQUUsY0FBYyxFQUFFLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3BILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG9FQUFvRSxFQUFFLEtBQUs7WUFDNUUsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBRWhDLHdEQUF3RDtZQUN4RCxpRkFBaUY7WUFDakYsTUFBTSxjQUFjLEdBQUc7Z0JBQ3JCLE9BQU8sRUFBRSxrSUFBa0k7Z0JBQzNJLFNBQVMsRUFBRSxrSUFBa0k7Z0JBQzdJLFdBQVcsRUFBRSwwREFBMEQ7Z0JBQ3ZFLG1CQUFtQixFQUFFLDBEQUEwRDthQUNoRixDQUFDO1lBQ0YsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDO1lBRWhDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEMsTUFBTSxRQUFRLEdBQUcsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBRXhELFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUMxQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsY0FBYyxDQUFDLENBQUM7WUFFaEUsTUFBTSwwQkFBMEIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsRUFBRSxjQUFjLEVBQUUsY0FBYyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDcEgsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMERBQTBELEVBQUUsS0FBSztZQUNsRSxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7WUFFaEMsa0VBQWtFO1lBQ2xFLE1BQU0sY0FBYyxHQUFHO2dCQUNyQixPQUFPLEVBQUUsb1VBQW9VO2dCQUM3VSxTQUFTLEVBQUUsb1VBQW9VO2dCQUMvVSxXQUFXLEVBQUUsMERBQTBEO2dCQUN2RSxnQkFBZ0IsRUFBRSxvQkFBUyxDQUFDLEVBQUUsQ0FBQyxzQkFBc0I7Z0JBQ3JELG1CQUFtQixFQUFFLDBEQUEwRDthQUNoRixDQUFDO1lBRUYsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDO1lBRWhDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEMsTUFBTSxRQUFRLEdBQUcsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBRXhELFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUMxQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsY0FBYyxDQUFDLENBQUM7WUFFaEUsTUFBTSwwQkFBMEIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsRUFBRSxjQUFjLEVBQUUsY0FBYyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDcEgsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMENBQTBDLEVBQUUsS0FBSztZQUNsRCxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7WUFFaEMsTUFBTSxjQUFjLEdBQUc7Z0JBQ3JCLE9BQU8sRUFBRSxvT0FBb087Z0JBQzdPLFNBQVMsRUFBRSwwREFBMEQ7Z0JBQ3JFLFdBQVcsRUFBRSwwREFBMEQ7Z0JBQ3ZFLGdCQUFnQixFQUFFLG9CQUFTLENBQUMsRUFBRSxDQUFDLHNCQUFzQjtnQkFDckQsbUJBQW1CLEVBQUUsMERBQTBEO2dCQUMvRSxXQUFXLEVBQUUsV0FBVzthQUN6QixDQUFDO1lBQ0YsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDO1lBRWhDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEMsTUFBTSxRQUFRLEdBQUcsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBRXhELFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUMxQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFFMUQsTUFBTSwwQkFBMEIsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsRUFBRSxjQUFjLEVBQUUsY0FBYyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDcEgsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMERBQTBELEVBQUUsS0FBSztZQUNsRSxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7WUFFaEMsbURBQW1EO1lBQ25ELE1BQU0sY0FBYyxHQUFHO2dCQUNyQixPQUFPLEVBQUUsb1VBQW9VO2dCQUM3VSxTQUFTLEVBQUUsa0VBQWtFLEVBQUUsOENBQThDO2dCQUM3SCxXQUFXLEVBQUUsMERBQTBEO2dCQUN2RSxnQkFBZ0IsRUFBRSxvQkFBUyxDQUFDLEVBQUUsQ0FBQyxzQkFBc0I7Z0JBQ3JELG1CQUFtQixFQUFFLDBEQUEwRDtnQkFDL0UsV0FBVyxFQUFFLFdBQVc7YUFDekIsQ0FBQztZQUNGLE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQztZQUVoQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BDLE1BQU0sUUFBUSxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUV4RCxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDMUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBRTFELE1BQU0sMEJBQTBCLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRLEVBQUUsY0FBYyxFQUFFLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3BILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHVDQUF1QyxFQUFFLEtBQUs7WUFDL0MsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBRWhDLE1BQU0sY0FBYyxHQUFHO2dCQUNyQixPQUFPLEVBQUUsMERBQTBEO2dCQUNuRSxTQUFTLEVBQUUsMERBQTBEO2dCQUNyRSxXQUFXLEVBQUUsMERBQTBEO2dCQUN2RSxnQkFBZ0IsRUFBRSxvQkFBUyxDQUFDLEVBQUUsQ0FBQyxzQkFBc0I7Z0JBQ3JELG1CQUFtQixFQUFFLDBEQUEwRDtnQkFDL0UsV0FBVyxFQUFFLFdBQVc7YUFDekIsQ0FBQztZQUNGLE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQztZQUVoQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BDLE1BQU0sUUFBUSxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUV4RCxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDMUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBRTFELE1BQU0sMEJBQTBCLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRLEVBQUUsY0FBYyxFQUFFLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3BILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHVEQUF1RCxFQUFFLEtBQUs7WUFDL0QsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBRWhDLE1BQU0sY0FBYyxHQUFHO2dCQUNyQixPQUFPLEVBQUUsa0VBQWtFLEVBQUUseUNBQXlDO2dCQUN0SCxTQUFTLEVBQUUsa0VBQWtFLEVBQUUsOENBQThDO2dCQUM3SCxXQUFXLEVBQUUsMERBQTBEO2dCQUN2RSxnQkFBZ0IsRUFBRSxvQkFBUyxDQUFDLEVBQUUsQ0FBQyxzQkFBc0I7Z0JBQ3JELG1CQUFtQixFQUFFLDBEQUEwRDtnQkFDL0UsV0FBVyxFQUFFLFdBQVc7YUFDekIsQ0FBQztZQUNGLE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQztZQUVoQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BDLE1BQU0sUUFBUSxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUV4RCxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDMUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBRTFELE1BQU0sMEJBQTBCLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxRQUFRLEVBQUUsY0FBYyxFQUFFLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3BILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsY0FBYyxFQUFFO1FBQ3ZCLElBQUksUUFBUSxDQUFDO1FBRWIsTUFBTSxDQUFDO1lBQ0wsUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxTQUFTLENBQUM7WUFDUixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbEIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaUVBQWlFLEVBQUUsS0FBSztZQUN6RSxhQUFhLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNqQyxNQUFNLFVBQVUsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUM7Z0JBQ3hDLE9BQU8sRUFDTCw0U0FBNFM7Z0JBQzlTLFNBQVMsRUFDUCw0U0FBNFM7Z0JBQzlTLFFBQVEsRUFDTixpSEFBaUg7Z0JBQ25ILGdCQUFnQixFQUFFLHdCQUF3QjtnQkFDMUMsbUJBQW1CLEVBQUUsb0NBQW9DO2FBQzFELENBQUMsQ0FBQztZQUVILE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7WUFFekIsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3JDLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDL0MsVUFBVSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2xELFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FDM0IseWhDQUF5aEMsQ0FDMWhDLENBQUM7WUFDRixVQUFVLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNyQyxvSUFBb0ksQ0FDckksQ0FBQztZQUNGLFVBQVUsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ3JDLG9JQUFvSSxDQUNySSxDQUFDO1lBQ0YsVUFBVSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxrRUFBa0UsQ0FBQyxDQUFDO1lBQ3BHLFVBQVUsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ3JDLGdSQUFnUixDQUNqUixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0ZBQXdGLEVBQUUsS0FBSztZQUNoRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDaEIsYUFBYSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDeEMsTUFBTSxVQUFVLEdBQUcsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDO2dCQUN4QyxPQUFPLEVBQ0wsNFNBQTRTO2dCQUM5UyxTQUFTLEVBQ1AsNFNBQTRTO2dCQUM5UyxRQUFRLEVBQ04saUhBQWlIO2dCQUNuSCxnQkFBZ0IsRUFBRSx3QkFBd0I7Z0JBQzFDLG1CQUFtQixFQUFFLG9DQUFvQzthQUMxRCxDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRXpCLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyQyxVQUFVLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQy9DLFVBQVUsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNsRCxVQUFVLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7WUFDbEYsVUFBVSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM3QyxVQUFVLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdDLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FDM0IsbTVCQUFtNUIsQ0FDcDVCLENBQUM7WUFDRixVQUFVLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNyQyxvSUFBb0ksQ0FDckksQ0FBQztZQUNGLFVBQVUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0VBQWtFLENBQUMsQ0FBQztZQUNwRyxVQUFVLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNyQyw4UUFBOFEsQ0FDL1EsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHVEQUF1RCxFQUFFLEtBQUs7WUFDL0QsYUFBYSxDQUFDLGdDQUFnQyxFQUFFLENBQUM7WUFDakQsTUFBTSxRQUFRO2lCQUNYLE9BQU8sQ0FBQztnQkFDUCxPQUFPLEVBQ0wsNFNBQTRTO2dCQUM5UyxTQUFTLEVBQ1AsNFNBQTRTO2dCQUM5UyxRQUFRLEVBQ04saUhBQWlIO2dCQUNuSCxnQkFBZ0IsRUFBRSx3QkFBd0I7Z0JBQzFDLG1CQUFtQixFQUFFLG9DQUFvQzthQUMxRCxDQUFDO2lCQUNELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUNyQiwrRkFBK0YsQ0FDaEcsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1EQUFtRCxFQUFFLEtBQUs7WUFDM0QsYUFBYSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDakMsTUFBTSxVQUFVLEdBQUcsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDO2dCQUN4QyxPQUFPLEVBQ0wsaUhBQWlIO2dCQUNuSCxTQUFTLEVBQ1AsaUhBQWlIO2dCQUNuSCxRQUFRLEVBQ04saUhBQWlIO2dCQUNuSCxtQkFBbUIsRUFBRSxvQ0FBb0M7YUFDMUQsQ0FBQyxDQUFDO1lBRUgsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUV6QixVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDckMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMvQyxVQUFVLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbEQsVUFBVSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxrRUFBa0UsQ0FBQyxDQUFDO1lBQ3BHLFVBQVUsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQ3JDLGdSQUFnUixDQUNqUixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsbUNBQW1DLEVBQUUsS0FBSztZQUMzQyxhQUFhLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNqQyxNQUFNLFVBQVUsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUM7Z0JBQ3hDLE9BQU8sRUFDTCw0U0FBNFM7Z0JBQzlTLFNBQVMsRUFDUCxpSEFBaUg7Z0JBQ25ILFFBQVEsRUFDTixpSEFBaUg7Z0JBQ25ILGdCQUFnQixFQUFFLHdCQUF3QjtnQkFDMUMsbUJBQW1CLEVBQUUsb0NBQW9DO2FBQzFELENBQUMsQ0FBQztZQUVILE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7WUFFekIsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3JDLFVBQVUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDL0MsVUFBVSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2xELFVBQVUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0VBQWtFLENBQUMsQ0FBQztZQUNwRyxVQUFVLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNyQyxnUkFBZ1IsQ0FDalIsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHlFQUF5RSxFQUFFLEtBQUs7WUFDakYsYUFBYSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDdEMsTUFBTSxVQUFVLEdBQUcsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDO2dCQUN4QyxPQUFPLEVBQ0wsNFNBQTRTO2dCQUM5UyxTQUFTLEVBQ1AsNFNBQTRTO2dCQUM5UyxRQUFRLEVBQ04saUhBQWlIO2dCQUNuSCxnQkFBZ0IsRUFBRSx3QkFBd0I7Z0JBQzFDLG9CQUFvQixFQUFFLG9DQUFvQztnQkFDMUQsbUJBQW1CLEVBQUUsb0NBQW9DO2FBQzFELENBQUMsQ0FBQztZQUVILE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7WUFFekIsVUFBVSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FDckMsb0lBQW9JLENBQ3JJLENBQUM7WUFDRixVQUFVLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNyQyxvSUFBb0ksQ0FDckksQ0FBQztZQUNGLFVBQVUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0VBQWtFLENBQUMsQ0FBQztZQUNwRyxVQUFVLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUNyQyx3YUFBd2EsQ0FDemEsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsYUFBYSxFQUFFO1FBQ3RCLElBQUksUUFBUSxDQUFDO1FBQ2IsTUFBTSxpQkFBaUIsR0FDckIsd0tBQXdLLENBQUM7UUFDM0ssTUFBTSxZQUFZLEdBQUcsa0VBQWtFLENBQUM7UUFDeEYsTUFBTSxDQUFDO1lBQ0wsUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFDSCxVQUFVLENBQUM7WUFDVCxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDbEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsOERBQThELEVBQUUsS0FBSztZQUN0RSxNQUFNLFVBQVUsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUM7Z0JBQ3hDLE9BQU8sRUFDTCw0U0FBNFM7Z0JBQzlTLFNBQVMsRUFDUCw0U0FBNFM7Z0JBQzlTLGdCQUFnQixFQUFFLG9CQUFTLENBQUMsRUFBRSxDQUFDLHNCQUFzQjtnQkFDckQsV0FBVyxFQUFFLGNBQWM7Z0JBQzNCLG1CQUFtQixFQUFFLGNBQWM7YUFDcEMsQ0FBQyxDQUFDO1lBRUgsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQy9DLFVBQVUsQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEQsVUFBVSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ2xFLFVBQVUsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pELFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUUzQyxNQUFNLDRCQUE0QixHQUFHO2dCQUNuQyxXQUFXLEVBQUU7b0JBQ1gsVUFBVSxFQUFFLFVBQVUsQ0FBQyxXQUFXLENBQUMsVUFBVTtpQkFDOUM7YUFDRixDQUFDO1lBRUYsTUFBTSxjQUFjLEdBQUcsTUFBTSxRQUFRLENBQUMsc0JBQXNCLENBQUMsNEJBQTRCLENBQUMsQ0FBQztZQUMzRixNQUFNLG1CQUFtQixHQUFHLHlCQUF5QixDQUFDO1lBQ3RELE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLE1BQU0sUUFBUSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUM7WUFDbEgsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUM5QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx1REFBdUQsRUFBRSxLQUFLO1lBQy9ELE1BQU0sVUFBVSxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQztnQkFDeEMsT0FBTyxFQUNMLGlIQUFpSDtnQkFDbkgsU0FBUyxFQUNQLGlIQUFpSDtnQkFDbkgsV0FBVyxFQUFFLGNBQWM7Z0JBQzNCLG1CQUFtQixFQUFFLGNBQWM7YUFDcEMsQ0FBQyxDQUFDO1lBRUgsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQy9DLFVBQVUsQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEQsVUFBVSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ2xFLFVBQVUsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pELFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx1Q0FBdUMsRUFBRSxLQUFLO1lBQy9DLE1BQU0sVUFBVSxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQztnQkFDeEMsT0FBTyxFQUNMLGlIQUFpSDtnQkFDbkgsU0FBUyxFQUNQLGlIQUFpSDtnQkFDbkgsZ0JBQWdCLEVBQUUsb0JBQVMsQ0FBQyxFQUFFLENBQUMsc0JBQXNCO2dCQUNyRCxXQUFXLEVBQUUsY0FBYztnQkFDM0IsbUJBQW1CLEVBQUUsY0FBYzthQUNwQyxDQUFDLENBQUM7WUFFSCxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDL0MsVUFBVSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN4RCxVQUFVLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDbEUsVUFBVSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekQsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsZUFBZSxFQUFFO1FBQ3hCLEVBQUUsQ0FBQyxtRkFBbUYsRUFBRSxLQUFLO1lBQzNGLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUVyQyx5RUFBeUU7WUFDekUsTUFBTSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsWUFBWSxDQUFDO2dCQUNuQyxvQkFBb0IsRUFBRSxvQkFBUyxDQUFDLEVBQUUsQ0FBQyx3QkFBd0I7Z0JBQzNELFNBQVMsRUFBRSxvQkFBUyxDQUFDLEVBQUUsQ0FBQywwQkFBMEI7Z0JBQ2xELGdCQUFnQixFQUFFLG9CQUFTLENBQUMsRUFBRSxDQUFDLDBCQUEwQjthQUMxRCxDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2pCLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUV0QyxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDO1lBQzdCLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBQ2xELE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzdDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMxQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN4QyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDMUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzdDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUN6QyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsc0JBQXNCLENBQUMsQ0FBQztZQUNwRCxNQUFNLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBUyxDQUFDLEVBQUUsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQ2hGLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN4QyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQVMsQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsQ0FBQztZQUM5RCxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDekMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNqRCxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFTLENBQUMsRUFBRSxDQUFDLDBCQUEwQixDQUFDLENBQUM7WUFDL0UsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNoRCxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHNEQUFzRCxFQUFFLEtBQUs7WUFDOUQsYUFBYSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFcEMsa0VBQWtFO1lBQ2xFLE1BQU0sV0FBVyxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQztnQkFDekMsT0FBTyxFQUNMLGlIQUFpSDtnQkFDbkgsU0FBUyxFQUNQLGlIQUFpSDtnQkFDbkgscUJBQXFCLEVBQUUsb0JBQVMsQ0FBQyxFQUFFLENBQUMsNkJBQTZCO2dCQUNqRSxvQkFBb0IsRUFBRSxvQkFBUyxDQUFDLEVBQUUsQ0FBQyx3QkFBd0I7Z0JBQzNELG1CQUFtQixFQUFFLG9CQUFTLENBQUMsRUFBRSxDQUFDLDBCQUEwQjthQUM3RCxDQUFDLENBQUM7WUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzFCLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUV2QyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsQ0FBQztZQUN2RCxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDL0MsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzdDLFdBQVcsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM1QyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDN0MsV0FBVyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2pELFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBQ3pELFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFTLENBQUMsRUFBRSxDQUFDLHVCQUF1QixDQUFDLENBQUM7WUFDcEYsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFDLENBQUM7WUFDMUQsV0FBVyxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQVMsQ0FBQyxFQUFFLENBQUMsNkJBQTZCLENBQUMsQ0FBQztZQUMzRixXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDOUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN0RCxXQUFXLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFTLENBQUMsRUFBRSxDQUFDLDBCQUEwQixDQUFDLENBQUM7WUFDcEYsV0FBVyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNyRCxXQUFXLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDbkUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0VBQXdFLEVBQUUsS0FBSztZQUNoRixhQUFhLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUVwQyxrRUFBa0U7WUFDbEUsTUFBTSxXQUFXLEdBQUcsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDO2dCQUN6QyxPQUFPLEVBQ0wsaUhBQWlIO2dCQUNuSCxTQUFTLEVBQ1AsaUhBQWlIO2dCQUNuSCxxQkFBcUIsRUFBRSxvQkFBUyxDQUFDLEVBQUUsQ0FBQyw2QkFBNkI7Z0JBQ2pFLG9CQUFvQixFQUFFLG9CQUFTLENBQUMsRUFBRSxDQUFDLHdCQUF3QjtnQkFDM0QsbUJBQW1CLEVBQUUsb0JBQVMsQ0FBQyxFQUFFLENBQUMsMEJBQTBCO2dCQUM1RCxRQUFRLEVBQUUsUUFBUTtnQkFDbEIsT0FBTyxFQUFFO29CQUNQLFlBQVksRUFBRSxhQUFhO29CQUMzQixvQkFBb0IsRUFBRSxNQUFNO2lCQUM3QjthQUNGLENBQUMsQ0FBQztZQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDMUIsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRXZDLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1lBQ3ZELFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMvQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDN0MsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzVDLFdBQVcsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM1QyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDN0MsV0FBVyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2pELFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBQ3pELFdBQVcsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFTLENBQUMsRUFBRSxDQUFDLHVCQUF1QixDQUFDLENBQUM7WUFDcEYsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFDLENBQUM7WUFDMUQsV0FBVyxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQVMsQ0FBQyxFQUFFLENBQUMsNkJBQTZCLENBQUMsQ0FBQztZQUMzRixXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDOUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN0RCxXQUFXLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFTLENBQUMsRUFBRSxDQUFDLDBCQUEwQixDQUFDLENBQUM7WUFDcEYsV0FBVyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNyRCxXQUFXLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDbkUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQywyQkFBMkIsRUFBRTtRQUNwQyxJQUFJLFFBQVEsQ0FBQztRQUNiLElBQUksT0FBTyxDQUFDO1FBRVosTUFBTSxDQUFDO1lBQ0wsUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDL0IsT0FBTyxHQUFHLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FBQztRQUVILFNBQVMsQ0FBQztZQUNSLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbEIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMkRBQTJELEVBQUUsS0FBSztZQUNuRSxNQUFNLFlBQVksR0FBRyxZQUFZLENBQUMsQ0FBQywrQkFBK0I7WUFDbEUsTUFBTSxjQUFjLEdBQUc7Z0JBQ3JCLE9BQU8sRUFDTCxpSEFBaUg7Z0JBQ25ILFNBQVMsRUFDUCxpSEFBaUg7Z0JBQ25ILHFCQUFxQixFQUFFLDRDQUE0QztnQkFDbkUsbUJBQW1CLEVBQUUsNENBQTRDO2dCQUNqRSxlQUFlLEVBQUUsSUFBSTtnQkFDckIsTUFBTSxFQUFFLFlBQVk7YUFDckIsQ0FBQztZQUVGLDJEQUEyRDtZQUMzRCxNQUFNLHNCQUFzQixHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLHFCQUFxQixDQUFDLENBQUM7WUFDNUUsTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3BFLE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztZQUNwRSxNQUFNLGtDQUFrQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLGlDQUFpQyxDQUFDLENBQUM7WUFFcEcsSUFBSSxDQUFDLDBCQUEwQixDQUFDO2lCQUM3QixHQUFHLENBQUMsTUFBTSxDQUFDO2lCQUNYLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO2dCQUNoQixPQUFPLE1BQU0sQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssUUFBUSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssWUFBWSxDQUFDO1lBQ3JHLENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsR0FBRyxFQUFFO2dCQUNWLE1BQU0sRUFBRSxHQUFHO2dCQUNYLE9BQU8sRUFBRSxJQUFJO2dCQUNiLE1BQU0sRUFBRTtvQkFDTjt3QkFDRSxXQUFXLEVBQUUsU0FBUzt3QkFDdEIsU0FBUyxFQUFFLFlBQVk7d0JBQ3ZCLElBQUksRUFBRSxvRUFBb0U7d0JBQzFFLEtBQUssRUFBRSxRQUFRO3dCQUNmLElBQUksRUFBRSw0Q0FBNEM7d0JBQ2xELEVBQUUsRUFBRSw0Q0FBNEM7d0JBQ2hELEtBQUssRUFBRSxvQkFBb0I7d0JBQzNCLEdBQUcsRUFBRSxPQUFPO3dCQUNaLFFBQVEsRUFBRSxZQUFZO3FCQUN2QjtpQkFDRjthQUNGLENBQUMsQ0FBQztZQUVMLGdDQUFnQztZQUNoQyxJQUFJLENBQUMsMEJBQTBCLENBQUM7aUJBQzdCLEdBQUcsQ0FBQyxNQUFNLENBQUM7aUJBQ1gsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7Z0JBQ2hCLE9BQU8sQ0FDTCxNQUFNLENBQUMsTUFBTSxLQUFLLFNBQVM7b0JBQzNCLE1BQU0sQ0FBQyxNQUFNLEtBQUssU0FBUztvQkFDM0IsTUFBTSxDQUFDLE1BQU0sS0FBSyxZQUFZO29CQUM5QixNQUFNLENBQUMsT0FBTyxLQUFLLDRDQUE0QyxDQUNoRSxDQUFDO1lBQ0osQ0FBQyxDQUFDO2lCQUNELEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsTUFBTSxFQUFFLEdBQUc7Z0JBQ1gsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsTUFBTSxFQUFFLG9CQUFvQjthQUM3QixDQUFDLENBQUM7WUFFTCxxQ0FBcUM7WUFDckMsSUFBSSxDQUFDLDBCQUEwQixDQUFDO2lCQUM3QixHQUFHLENBQUMsTUFBTSxDQUFDO2lCQUNYLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO2dCQUNoQixPQUFPLENBQ0wsTUFBTSxDQUFDLE1BQU0sS0FBSyxTQUFTO29CQUMzQixNQUFNLENBQUMsTUFBTSxLQUFLLFNBQVM7b0JBQzNCLE1BQU0sQ0FBQyxNQUFNLEtBQUssWUFBWTtvQkFDOUIsTUFBTSxDQUFDLE9BQU8sS0FBSyw0Q0FBNEMsQ0FDaEUsQ0FBQztZQUNKLENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsR0FBRyxFQUFFO2dCQUNWLE1BQU0sRUFBRSxHQUFHO2dCQUNYLE9BQU8sRUFBRSxJQUFJO2dCQUNiLE1BQU0sRUFBRSxvQkFBb0I7YUFDN0IsQ0FBQyxDQUFDO1lBRUwseUJBQXlCO1lBQ3pCLElBQUksQ0FBQywwQkFBMEIsQ0FBQztpQkFDN0IsR0FBRyxDQUFDLE1BQU0sQ0FBQztpQkFDWCxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtnQkFDaEIsT0FBTyxDQUNMLE1BQU0sQ0FBQyxNQUFNLEtBQUssT0FBTztvQkFDekIsTUFBTSxDQUFDLE1BQU0sS0FBSyxVQUFVO29CQUM1QixNQUFNLENBQUMsTUFBTSxLQUFLLFlBQVk7b0JBQzlCLE1BQU0sQ0FBQyxJQUFJLEtBQUssVUFBVSxDQUMzQixDQUFDO1lBQ0osQ0FBQyxDQUFDO2lCQUNELEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsRUFBRSxFQUFFLENBQUM7Z0JBQ0wsTUFBTSxFQUFFLG9FQUFvRTthQUM3RSxDQUFDLENBQUM7WUFFTCw0RUFBNEU7WUFDNUUsSUFBSSxDQUFDLDBCQUEwQixDQUFDO2lCQUM3QixHQUFHLENBQUMsU0FBUyxDQUFDO2lCQUNkLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO2dCQUNoQixPQUFPLENBQ0wsTUFBTSxDQUFDLE9BQU8sS0FBSyxRQUFRO29CQUMzQixNQUFNLENBQUMsTUFBTSxLQUFLLFNBQVM7b0JBQzNCLE1BQU0sQ0FBQyxNQUFNLEtBQUssUUFBUTtvQkFDMUIsTUFBTSxDQUFDLE9BQU8sS0FBSyw0Q0FBNEM7b0JBQy9ELE1BQU0sQ0FBQyxNQUFNLEtBQUssWUFBWSxDQUMvQixDQUFDO1lBQ0osQ0FBQyxDQUFDO2lCQUNELEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsTUFBTSxFQUFFLEdBQUc7Z0JBQ1gsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsTUFBTSxFQUFFO29CQUNOO3dCQUNFLFdBQVcsRUFBRSxTQUFTO3dCQUN0QixTQUFTLEVBQUUsWUFBWTt3QkFDdkIsSUFBSSxFQUFFLG9FQUFvRTt3QkFDMUUsS0FBSyxFQUFFLFFBQVE7d0JBQ2YsU0FBUyxFQUFFLG9FQUFvRTt3QkFDL0UsZ0JBQWdCLEVBQUUsR0FBRzt3QkFDckIsSUFBSSxFQUFFLDRDQUE0Qzt3QkFDbEQsRUFBRSxFQUFFLDRDQUE0Qzt3QkFDaEQsS0FBSyxFQUFFLG9CQUFvQjt3QkFDM0IsR0FBRyxFQUFFLE9BQU87d0JBQ1osUUFBUSxFQUFFLFlBQVk7d0JBQ3RCLE9BQU8sRUFBRSxHQUFHO3dCQUNaLGdCQUFnQixFQUFFLEdBQUc7d0JBQ3JCLEtBQUssRUFBRSxJQUFJO3dCQUNYLGVBQWUsRUFBRSxFQUFFO3dCQUNuQixpQkFBaUIsRUFBRSxPQUFPO3dCQUMxQixPQUFPLEVBQUUsT0FBTzt3QkFDaEIsYUFBYSxFQUFFLFNBQVM7d0JBQ3hCLFFBQVEsRUFBRSxJQUFJO3dCQUNkLFlBQVksRUFBRSxFQUFFO3FCQUNqQjtpQkFDRjthQUNGLENBQUMsQ0FBQztZQUVMLHdGQUF3RjtZQUN4RixJQUFJLENBQUMsMEJBQTBCLENBQUM7aUJBQzdCLEdBQUcsQ0FBQyxTQUFTLENBQUM7aUJBQ2QsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7Z0JBQ2hCLE9BQU8sQ0FDTCxNQUFNLENBQUMsT0FBTyxLQUFLLFFBQVE7b0JBQzNCLE1BQU0sQ0FBQyxNQUFNLEtBQUssU0FBUztvQkFDM0IsTUFBTSxDQUFDLE1BQU0sS0FBSyxTQUFTO29CQUMzQixNQUFNLENBQUMsT0FBTyxLQUFLLDRDQUE0QztvQkFDL0QsTUFBTSxDQUFDLE1BQU0sS0FBSyxZQUFZLENBQy9CLENBQUM7WUFDSixDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLEdBQUcsRUFBRTtnQkFDVixNQUFNLEVBQUUsR0FBRztnQkFDWCxPQUFPLEVBQUUsSUFBSTtnQkFDYixNQUFNLEVBQUUsb0JBQW9CO2FBQzdCLENBQUMsQ0FBQztZQUVMLDZGQUE2RjtZQUM3RixJQUFJLENBQUMsMEJBQTBCLENBQUM7aUJBQzdCLEdBQUcsQ0FBQyxTQUFTLENBQUM7aUJBQ2QsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7Z0JBQ2hCLE9BQU8sQ0FDTCxNQUFNLENBQUMsT0FBTyxLQUFLLFFBQVE7b0JBQzNCLE1BQU0sQ0FBQyxNQUFNLEtBQUssU0FBUztvQkFDM0IsTUFBTSxDQUFDLE1BQU0sS0FBSyxTQUFTO29CQUMzQixNQUFNLENBQUMsT0FBTyxLQUFLLDRDQUE0QztvQkFDL0QsTUFBTSxDQUFDLE1BQU0sS0FBSyxZQUFZLENBQy9CLENBQUM7WUFDSixDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLEdBQUcsRUFBRTtnQkFDVixNQUFNLEVBQUUsR0FBRztnQkFDWCxPQUFPLEVBQUUsSUFBSTtnQkFDYixNQUFNLEVBQUUsb0JBQW9CO2FBQzdCLENBQUMsQ0FBQztZQUVMLHVGQUF1RjtZQUN2RixJQUFJLENBQUMsMEJBQTBCLENBQUM7aUJBQzdCLEdBQUcsQ0FBQyxTQUFTLENBQUM7aUJBQ2QsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7Z0JBQ2hCLE9BQU8sQ0FDTCxNQUFNLENBQUMsT0FBTyxLQUFLLFFBQVE7b0JBQzNCLE1BQU0sQ0FBQyxNQUFNLEtBQUssT0FBTztvQkFDekIsTUFBTSxDQUFDLE1BQU0sS0FBSyxVQUFVO29CQUM1QixNQUFNLENBQUMsRUFBRSxLQUFLLDRDQUE0QztvQkFDMUQsTUFBTSxDQUFDLElBQUksS0FBSyxVQUFVO29CQUMxQixNQUFNLENBQUMsR0FBRyxLQUFLLFFBQVE7b0JBQ3ZCLE1BQU0sQ0FBQyxNQUFNLEtBQUssWUFBWSxDQUMvQixDQUFDO1lBQ0osQ0FBQyxDQUFDO2lCQUNELEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsRUFBRSxFQUFFLENBQUM7Z0JBQ0wsTUFBTSxFQUFFLG9FQUFvRTthQUM3RSxDQUFDLENBQUM7WUFFTCxJQUFJLENBQUMsMEJBQTBCLENBQUM7aUJBQzdCLEdBQUcsQ0FBQyxTQUFTLENBQUM7aUJBQ2QsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7Z0JBQ2hCLE9BQU8sQ0FDTCxNQUFNLENBQUMsT0FBTyxLQUFLLFFBQVE7b0JBQzNCLE1BQU0sQ0FBQyxNQUFNLEtBQUssU0FBUztvQkFDM0IsTUFBTSxDQUFDLE1BQU0sS0FBSyxRQUFRO29CQUMxQixNQUFNLENBQUMsT0FBTyxLQUFLLDRDQUE0QztvQkFDL0QsTUFBTSxDQUFDLE1BQU0sS0FBSyxZQUFZLENBQy9CLENBQUM7WUFDSixDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLEdBQUcsRUFBRTtnQkFDVixNQUFNLEVBQUUsR0FBRztnQkFDWCxPQUFPLEVBQUUsSUFBSTtnQkFDYixNQUFNLEVBQUU7b0JBQ047d0JBQ0UsV0FBVyxFQUFFLFNBQVM7d0JBQ3RCLFNBQVMsRUFBRSxZQUFZO3dCQUN2QixJQUFJLEVBQUUsb0VBQW9FO3dCQUMxRSxLQUFLLEVBQUUsSUFBSTt3QkFDWCxTQUFTLEVBQUUsb0VBQW9FO3dCQUMvRSxnQkFBZ0IsRUFBRSxHQUFHO3dCQUNyQixJQUFJLEVBQUUsNENBQTRDO3dCQUNsRCxFQUFFLEVBQUUsNENBQTRDO3dCQUNoRCxLQUFLLEVBQUUsR0FBRzt3QkFDVixHQUFHLEVBQUUsUUFBUTt3QkFDYixRQUFRLEVBQUUsU0FBUzt3QkFDbkIsT0FBTyxFQUFFLEdBQUc7d0JBQ1osZ0JBQWdCLEVBQUUsR0FBRzt3QkFDckIsS0FBSyxFQUNILDRzQkFBNHNCO3dCQUM5c0IsZUFBZSxFQUFFLEVBQUU7d0JBQ25CLGlCQUFpQixFQUFFLFFBQVE7d0JBQzNCLE9BQU8sRUFBRSxRQUFRO3dCQUNqQixhQUFhLEVBQUUsTUFBTTt3QkFDckIsUUFBUSxFQUFFLFlBQVk7d0JBQ3RCLFlBQVksRUFDVixnSEFBZ0g7cUJBQ25IO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1lBRUwsSUFBSSxDQUFDO2dCQUNILE1BQU0sUUFBUSxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztnQkFDeEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDdkIsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNwQyxRQUFRLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLCtCQUErQjtnQkFDN0UsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO2dCQUMxRixRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUM7Z0JBQ2pFLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlDLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNYLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZCLENBQUM7WUFFRCx1RUFBdUU7WUFDdkUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsa0NBQWtDLENBQUMsQ0FBQztZQUN4RCxNQUFNLGtCQUFrQixHQUFHLGtDQUFrQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBRXpFLCtDQUErQztZQUMvQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDbEMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzFDLENBQUMsQ0FBQyxDQUFDO1lBRUgsaURBQWlEO1lBQ2pELElBQUksc0JBQXNCLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ2xDLE1BQU0sdUJBQXVCLEdBQUcsc0JBQXNCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNsRSx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM3RCxDQUFDO1lBRUQsSUFBSSxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDOUIsTUFBTSxtQkFBbUIsR0FBRyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzFELG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3pELENBQUM7WUFFRCxJQUFJLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUM5QixNQUFNLG1CQUFtQixHQUFHLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDMUQsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDekQsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsa0JBQWtCLEVBQUU7UUFDM0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNsQixDQUFDLENBQUMsQ0FBQztRQUNILElBQUksY0FBYyxDQUFDO1FBRW5CLE1BQU0sV0FBVyxHQUFVO1lBQ3pCO2dCQUNFLE1BQU0sRUFBRTtvQkFDTixNQUFNLEVBQUUsU0FBUztvQkFDakIsTUFBTSxFQUFFLFFBQVE7b0JBQ2hCLE9BQU8sRUFBRSw0Q0FBNEM7aUJBQ3REO2dCQUNELFFBQVEsRUFBRTtvQkFDUixNQUFNLEVBQUUsR0FBRztvQkFDWCxPQUFPLEVBQUUsdUJBQXVCO29CQUNoQyxNQUFNLEVBQUUsRUFBRTtpQkFDWDthQUNGO1lBQ0Q7Z0JBQ0UsTUFBTSxFQUFFO29CQUNOLE1BQU0sRUFBRSxTQUFTO29CQUNqQixNQUFNLEVBQUUsU0FBUztvQkFDakIsT0FBTyxFQUFFLDRDQUE0QztpQkFDdEQ7Z0JBQ0QsUUFBUSxFQUFFO29CQUNSLE1BQU0sRUFBRSxHQUFHO29CQUNYLE9BQU8sRUFBRSxJQUFJO29CQUNiLE1BQU0sRUFBRSxxQkFBcUI7aUJBQzlCO2FBQ0Y7U0FDRixDQUFDO1FBQ0YsTUFBTSx3QkFBd0IsR0FBVTtZQUN0QztnQkFDRSxNQUFNLEVBQUU7b0JBQ04sTUFBTSxFQUFFLFNBQVM7b0JBQ2pCLE1BQU0sRUFBRSxRQUFRO29CQUNoQixPQUFPLEVBQUUsNENBQTRDO2lCQUN0RDtnQkFDRCxRQUFRLEVBQUU7b0JBQ1IsTUFBTSxFQUFFLEdBQUc7b0JBQ1gsT0FBTyxFQUFFLHVCQUF1QjtvQkFDaEMsTUFBTSxFQUFFLEVBQUU7aUJBQ1g7YUFDRjtZQUNEO2dCQUNFLE1BQU0sRUFBRTtvQkFDTixNQUFNLEVBQUUsU0FBUztvQkFDakIsTUFBTSxFQUFFLFNBQVM7b0JBQ2pCLE9BQU8sRUFBRSw0Q0FBNEM7aUJBQ3REO2dCQUNELFFBQVEsRUFBRTtvQkFDUixNQUFNLEVBQUUsR0FBRztvQkFDWCxPQUFPLEVBQUUsSUFBSTtvQkFDYixNQUFNLEVBQUUscUJBQXFCO2lCQUM5QjthQUNGO1NBQ0YsQ0FBQztRQUNGLElBQUksaUJBQXFDLENBQUM7UUFFMUMsTUFBTSxDQUFDLEdBQUcsRUFBRTtZQUNWLGNBQWMsR0FBRztnQkFDZixPQUFPLEVBQ0wsK0VBQStFO29CQUMvRSwrRUFBK0U7b0JBQy9FLCtFQUErRTtvQkFDL0UsMkVBQTJFO2dCQUM3RSxTQUFTLEVBQ1AsK0VBQStFO29CQUMvRSwrRUFBK0U7b0JBQy9FLCtFQUErRTtvQkFDL0UsMkVBQTJFO2dCQUM3RSxnQkFBZ0IsRUFBRSxvQkFBUyxDQUFDLEVBQUUsQ0FBQyxzQkFBc0I7Z0JBQ3JELHFCQUFxQixFQUFFLDRDQUE0QztnQkFDbkUsbUJBQW1CLEVBQUUsNENBQTRDO2dCQUNqRSx1QkFBdUIsRUFBRTtvQkFDdkIsS0FBSyxFQUFFLEVBQUU7b0JBQ1QsUUFBUSxFQUFFLFFBQVE7aUJBQ25CO2FBQ0YsQ0FBQztZQUNGLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUMxQyxpQkFBaUI7aUJBQ2QsSUFBSSxDQUFDLDZCQUFlLEVBQUUsZ0JBQWdCLENBQUM7aUJBQ3ZDLFFBQVEsQ0FBQyx3QkFBVSxDQUFDLDJCQUEyQixDQUFDLDRDQUFpQyxDQUFDLENBQUMsQ0FBQztRQUN6RixDQUFDLENBQUMsQ0FBQztRQUVILEtBQUssQ0FBQyxHQUFHLEVBQUU7WUFDVCxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM5QixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxrQ0FBa0MsRUFBRSxLQUFLO1lBQzFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUV6QyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sUUFBUTtpQkFDWCxPQUFPLENBQUM7Z0JBQ1AsR0FBRyxjQUFjO2dCQUNqQixRQUFRLEVBQUUsQ0FBQyxNQUFNO2dCQUNqQixRQUFRLEVBQUUsV0FBVzthQUN0QixDQUFDO2lCQUNELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLDhDQUE4QyxDQUFDLENBQUM7UUFDNUUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0NBQWdDLEVBQUUsS0FBSztZQUN4QyxNQUFNLDZCQUE2QixHQUFVO2dCQUMzQztvQkFDRSxNQUFNLEVBQUU7d0JBQ04sTUFBTSxFQUFFLFNBQVM7d0JBQ2pCLE1BQU0sRUFBRSxRQUFRO3dCQUNoQixPQUFPLEVBQUUsNENBQTRDO3FCQUN0RDtvQkFDRCxRQUFRLEVBQUU7d0JBQ1IsTUFBTSxFQUFFLEdBQUc7d0JBQ1gsT0FBTyxFQUFFLHVCQUF1Qjt3QkFDaEMsTUFBTSxFQUFFLEVBQUU7cUJBQ1g7aUJBQ0Y7Z0JBQ0Q7b0JBQ0UsTUFBTSxFQUFFO3dCQUNOLE1BQU0sRUFBRSxTQUFTO3dCQUNqQixNQUFNLEVBQUUsU0FBUzt3QkFDakIsT0FBTyxFQUFFLDRDQUE0QztxQkFDdEQ7b0JBQ0QsUUFBUSxFQUFFO3dCQUNSLE1BQU0sRUFBRSxHQUFHO3dCQUNYLE9BQU8sRUFBRSxPQUFPO3dCQUNoQixNQUFNLEVBQUUscUJBQXFCO3FCQUM5QjtpQkFDRjthQUNGLENBQUM7WUFDRixhQUFhLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLDZCQUE2QixDQUFDLENBQUM7WUFFeEUsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyQyxNQUFNLFFBQVE7aUJBQ1gsT0FBTyxDQUFDLGNBQWMsQ0FBQztpQkFDdkIsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQ3JCLDZIQUE2SCxDQUM5SCxDQUFDO1FBQ04sQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsNkRBQTZELEVBQUUsS0FBSztZQUNyRSxNQUFNLG1CQUFtQixHQUFVO2dCQUNqQztvQkFDRSxNQUFNLEVBQUU7d0JBQ04sTUFBTSxFQUFFLFNBQVM7d0JBQ2pCLE1BQU0sRUFBRSxRQUFRO3dCQUNoQixPQUFPLEVBQUUsNENBQTRDO3FCQUN0RDtvQkFDRCxRQUFRLEVBQUU7d0JBQ1IsTUFBTSxFQUFFLEdBQUc7d0JBQ1gsT0FBTyxFQUFFLHVCQUF1Qjt3QkFDaEMsTUFBTSxFQUFFLEVBQUU7cUJBQ1g7aUJBQ0Y7Z0JBQ0Q7b0JBQ0UsTUFBTSxFQUFFO3dCQUNOLE1BQU0sRUFBRSxTQUFTO3dCQUNqQixNQUFNLEVBQUUsU0FBUzt3QkFDakIsT0FBTyxFQUFFLDRDQUE0QztxQkFDdEQ7b0JBQ0QsUUFBUSxFQUFFO3dCQUNSLE1BQU0sRUFBRSxHQUFHO3dCQUNYLE9BQU8sRUFBRSxJQUFJO3dCQUNiLE1BQU0sRUFBRSxNQUFNO3FCQUNmO2lCQUNGO2FBQ0YsQ0FBQztZQUNGLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztZQUU5RCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sUUFBUTtpQkFDWCxPQUFPLENBQUM7Z0JBQ1AsR0FBRyxjQUFjO2dCQUNqQixRQUFRLEVBQUUsTUFBTTtnQkFDaEIsUUFBUSxFQUFFLFVBQVU7YUFDckIsQ0FBQztpQkFDRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FDckIsNkZBQTZGO2dCQUMzRixrSUFBa0ksQ0FDckksQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGtDQUFrQyxFQUFFLEtBQUs7WUFDMUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDckMsTUFBTSxRQUFRO2lCQUNYLE9BQU8sQ0FBQztnQkFDUCxHQUFHLGNBQWM7Z0JBQ2pCLFFBQVEsRUFBRSxNQUFNO2dCQUNoQixRQUFRLEVBQUUsT0FBTzthQUNsQixDQUFDO2lCQUNELE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHdEQUF3RCxDQUFDLENBQUM7UUFDdEYsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsb0VBQW9FLEVBQUUsS0FBSztZQUM1RSxhQUFhLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyQyxNQUFNLFFBQVEsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUM7Z0JBQ3RDLEdBQUcsY0FBYztnQkFDakIsUUFBUSxFQUFFLE1BQU07Z0JBQ2hCLFFBQVEsRUFBRSxVQUFVO2FBQ3JCLENBQUMsQ0FBQztZQUNILDJEQUEyRDtZQUMzRCxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZCLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdURBQXVELEVBQUUsS0FBSztZQUMvRCxhQUFhLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyQyxNQUFNLFFBQVEsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDeEQsMkRBQTJEO1lBQzNELE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdkIsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3BDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxnRUFBZ0UsRUFBRSxLQUFLO1lBQ3hFLE1BQU0scUJBQXFCLEdBQUc7Z0JBQzVCLEdBQUcsY0FBYztnQkFDakIsT0FBTyxFQUFFO29CQUNQLG9CQUFvQixFQUFFLENBQUM7b0JBQ3ZCLFlBQVksRUFBRSxFQUFFO2lCQUNqQjthQUNGLENBQUM7WUFDRixhQUFhLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyQyxNQUFNLFFBQVEsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUMvRCwyREFBMkQ7WUFDM0QsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN2QixRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG9FQUFvRSxFQUFFLEtBQUs7WUFDNUUsYUFBYSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXpDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDckMsTUFBTSxRQUFRLEdBQUcsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDO2dCQUN0QyxHQUFHLGNBQWM7Z0JBQ2pCLFNBQVMsRUFDUCxpSEFBaUg7Z0JBQ25ILFdBQVcsRUFBRSxXQUFXO2FBQ3pCLENBQUMsQ0FBQztZQUVILDJEQUEyRDtZQUMzRCxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZCLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0RBQStELEVBQUUsS0FBSztZQUN2RSxhQUFhLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyQyxNQUFNLFFBQVE7aUJBQ1gsT0FBTyxDQUFDO2dCQUNQLE9BQU8sRUFDTCwrRUFBK0U7b0JBQy9FLCtFQUErRTtvQkFDL0UsK0VBQStFO29CQUMvRSw2RUFBNkU7Z0JBQy9FLFNBQVMsRUFDUCwrRUFBK0U7b0JBQy9FLCtFQUErRTtvQkFDL0UsK0VBQStFO29CQUMvRSwyRUFBMkU7Z0JBQzdFLHFCQUFxQixFQUFFLDRDQUE0QztnQkFDbkUsZ0JBQWdCLEVBQUUsb0JBQVMsQ0FBQyxFQUFFLENBQUMsc0JBQXNCO2dCQUNyRCxtQkFBbUIsRUFBRSw0Q0FBNEM7YUFDbEUsQ0FBQztpQkFDRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FDckIscU5BQXFOLENBQ3ROLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw2REFBNkQsRUFBRSxLQUFLO1lBQ3JFLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDckMsYUFBYSxDQUFDLDJCQUEyQixFQUFFLENBQUM7WUFDNUMsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFDaEcsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUNBQXVDLEVBQUUsS0FBSztZQUMvQyxhQUFhLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFekMsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUVyQyxNQUFNLFdBQVcsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUM7Z0JBQ3pDLE9BQU8sRUFDTCxpSEFBaUg7Z0JBQ25ILFNBQVMsRUFDUCxpSEFBaUg7Z0JBQ25ILHFCQUFxQixFQUFFLG9CQUFTLENBQUMsRUFBRSxDQUFDLDZCQUE2QjtnQkFDakUsbUJBQW1CLEVBQUUsb0JBQVMsQ0FBQyxFQUFFLENBQUMsMEJBQTBCO2dCQUM1RCxRQUFRLEVBQUUsYUFBYTtnQkFDdkIsUUFBUSxFQUFFLFFBQVE7YUFDbkIsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUMxQixXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLENBQUM7WUFDdkQsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQy9DLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUM3QyxXQUFXLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDNUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzdDLFdBQVcsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNqRCxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUMxRCxXQUFXLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBUyxDQUFDLEVBQUUsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1lBQzNGLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUM5QyxXQUFXLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3RELFdBQVcsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQVMsQ0FBQyxFQUFFLENBQUMsMEJBQTBCLENBQUMsQ0FBQztZQUNwRixXQUFXLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3JELFdBQVcsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUNuRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxLQUFLO1lBQ2pELGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDdEQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyQyxNQUFNLFdBQVcsR0FBRyxxQ0FBa0IsQ0FBQyxhQUFhLENBQUM7WUFFckQsTUFBTSwwQkFBMEIsR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7Z0JBQzFELE9BQU87b0JBQ0wsR0FBRyxJQUFJO29CQUNQLE1BQU0sRUFBRTt3QkFDTixHQUFHLElBQUksQ0FBQyxNQUFNO3dCQUNkLE9BQU8sRUFBRSxXQUFXO3FCQUNyQjtpQkFDRixDQUFDO1lBQ0osQ0FBQyxDQUFDLENBQUM7WUFFSCxhQUFhLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLDBCQUEwQixDQUFDLENBQUM7WUFDckUsY0FBYyxHQUFHO2dCQUNmLE9BQU8sRUFBRSxxQ0FBa0IsQ0FBQyxPQUFPO2dCQUNuQyxTQUFTLEVBQUUscUNBQWtCLENBQUMsU0FBUztnQkFDdkMscUJBQXFCLEVBQUUscUNBQWtCLENBQUMsYUFBYTtnQkFDdkQsbUJBQW1CLEVBQUUscUNBQWtCLENBQUMsa0JBQWtCO2dCQUMxRCxnQkFBZ0IsRUFBRSxxQ0FBa0IsQ0FBQyxnQkFBZ0I7Z0JBQ3JELE9BQU8sRUFBRTtvQkFDUCxvQkFBb0IsRUFBRSxDQUFDO29CQUN2QixZQUFZLEVBQUUsRUFBRTtpQkFDakI7Z0JBQ0QsS0FBSyxFQUFFLElBQUk7Z0JBQ1gsdUJBQXVCLEVBQUU7b0JBQ3ZCLEtBQUssRUFBRSxDQUFDO29CQUNSLFFBQVEsRUFBRSxRQUFRO2lCQUNuQjthQUNGLENBQUM7WUFFRixNQUFNLFFBQVEsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7WUFFeEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN2QixRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRXBDLHVDQUF1QztZQUN2QyxNQUFNLE9BQU8sR0FBRyx1QkFBa0IsQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFFakcsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7WUFFNUQsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDeEMsY0FBYyxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ3hFLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3pELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLCtDQUErQyxFQUFFLEtBQUs7WUFDdkQsS0FBSyxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJO2dCQUM1QixFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRTtnQkFDaEMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUU7Z0JBQ2xDLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFO2FBQzVCLEVBQUUsQ0FBQztnQkFDRixhQUFhLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDO2dCQUN0RCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNsQyxNQUFNLFdBQVcsR0FBRyxxQ0FBa0IsQ0FBQyxhQUFhLENBQUM7Z0JBQ3JELE1BQU0sMEJBQTBCLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO29CQUMxRCxPQUFPO3dCQUNMLEdBQUcsSUFBSTt3QkFDUCxNQUFNLEVBQUU7NEJBQ04sR0FBRyxJQUFJLENBQUMsTUFBTTs0QkFDZCxPQUFPLEVBQUUsV0FBVzt5QkFDckI7cUJBQ0YsQ0FBQztnQkFDSixDQUFDLENBQUMsQ0FBQztnQkFFSCxhQUFhLENBQUMsbUJBQW1CLENBQUMsS0FBSyxFQUFFLDBCQUEwQixDQUFDLENBQUM7Z0JBQ3JFLGNBQWMsR0FBRztvQkFDZixPQUFPLEVBQUUscUNBQWtCLENBQUMsT0FBTztvQkFDbkMsU0FBUyxFQUFFLHFDQUFrQixDQUFDLFNBQVM7b0JBQ3ZDLHFCQUFxQixFQUFFLFdBQVc7b0JBQ2xDLG1CQUFtQixFQUFFLHFDQUFrQixDQUFDLGtCQUFrQjtvQkFDMUQsZ0JBQWdCLEVBQUUscUNBQWtCLENBQUMsZ0JBQWdCO29CQUNyRCxPQUFPLEVBQUU7d0JBQ1Asb0JBQW9CLEVBQUUsQ0FBQzt3QkFDdkIsWUFBWSxFQUFFLFdBQVc7cUJBQzFCO29CQUNELEtBQUssRUFBRSxJQUFJO29CQUNYLHVCQUF1QixFQUFFO3dCQUN2QixLQUFLLEVBQUUsS0FBSztxQkFDYjtpQkFDRixDQUFDO2dCQUVGLElBQUksSUFBSSxLQUFLLE1BQU0sRUFBRSxDQUFDO29CQUNwQixjQUFjLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQztvQkFDbkMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxHQUFHLFdBQVcsQ0FBQztnQkFDM0MsQ0FBQztnQkFFRCxNQUFNLFFBQVEsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBRXhELE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3ZCLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDcEMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVwQyx1Q0FBdUM7Z0JBQ3ZDLE1BQU0sT0FBTyxHQUFHLHVCQUFrQixDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFFakcsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQzVELE9BQU8sQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDMUQsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQ3hDLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztnQkFDeEUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDekQsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGdEQUFnRCxFQUFFLEtBQUs7WUFDeEQsYUFBYSxDQUFDLG1CQUFtQixDQUFDLEtBQUssRUFBRSx3QkFBd0IsQ0FBQyxDQUFDO1lBRW5FLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFckMsTUFBTSxPQUFPLEdBQ1gsb0lBQW9JLENBQUM7WUFDdkksTUFBTSxTQUFTLEdBQ2Isb0lBQW9JLENBQUM7WUFFdkksY0FBYyxHQUFHO2dCQUNmLE9BQU8sRUFBRSxPQUFPO2dCQUNoQixTQUFTLEVBQUUsU0FBUztnQkFDcEIscUJBQXFCLEVBQUUsNENBQTRDO2dCQUNuRSxtQkFBbUIsRUFBRSw0Q0FBNEM7Z0JBQ2pFLGdCQUFnQixFQUFFLG9CQUFTLENBQUMsRUFBRSxDQUFDLHNCQUFzQjtnQkFDckQsS0FBSyxFQUFFLElBQUk7Z0JBQ1gsUUFBUSxFQUFFLGFBQWE7Z0JBQ3ZCLFFBQVEsRUFBRSxRQUFRO2dCQUNsQix1QkFBdUIsRUFBRTtvQkFDdkIsS0FBSyxFQUFFLEVBQUU7b0JBQ1QsUUFBUSxFQUFFLFFBQVE7aUJBQ25CO2FBQ0YsQ0FBQztZQUVGLE1BQU0sV0FBVyxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUMzRCxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQzFCLE1BQU0sTUFBTSxHQUFHLFdBQThDLENBQUM7WUFDOUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUMxRCxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4RCxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3hELE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3hFLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3hGLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNwRixNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUN2RixNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDaEYsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2pGLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFtQyxDQUFDO1lBQ3JHLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUM1QyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBK0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFlBQVksRUFBRTtRQUNyQixVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2xCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxjQUFjLENBQUM7UUFFbkIsRUFBRSxDQUFDLCtDQUErQyxFQUFFLEtBQUs7WUFDdkQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwQyxNQUFNLFdBQVcsR0FBRyxxQ0FBa0IsQ0FBQyxhQUFhLENBQUM7WUFDckQsYUFBYSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDbEQsY0FBYyxHQUFHO2dCQUNmLE9BQU8sRUFBRSxxQ0FBa0IsQ0FBQyxPQUFPO2dCQUNuQyxTQUFTLEVBQUUscUNBQWtCLENBQUMsU0FBUztnQkFDdkMscUJBQXFCLEVBQUUsV0FBVztnQkFDbEMsbUJBQW1CLEVBQUUscUNBQWtCLENBQUMsa0JBQWtCO2dCQUMxRCxnQkFBZ0IsRUFBRSxxQ0FBa0IsQ0FBQyxnQkFBZ0I7Z0JBQ3JELEtBQUssRUFBRSxJQUFJO2FBQ1osQ0FBQztZQUVGLE1BQU0sUUFBUSxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUV4RCxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZCLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNwQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0RBQWdELEVBQUUsS0FBSztZQUN4RCxhQUFhLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSw0Q0FBNEMsQ0FBQyxDQUFDO1lBQ25GLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFcEMsTUFBTSwyQkFBMkIsR0FBRztnQkFDbEMsUUFBUSxFQUNOLG9JQUFvSTtnQkFDdEksbUJBQW1CLEVBQUUscUNBQWtCLENBQUMsa0JBQWtCO2FBQzNELENBQUM7WUFFRixNQUFNLFFBQVEsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUMsMkJBQTJCLENBQUMsQ0FBQztZQUNyRSxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZCLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN2QyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDJEQUEyRCxFQUFFLEtBQUs7WUFDbkUsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwQyxNQUFNLFdBQVcsR0FBRyxxQ0FBa0IsQ0FBQyxhQUFhLENBQUM7WUFDckQsYUFBYSxDQUFDLG9CQUFvQixDQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsQ0FBQztZQUN2RCxjQUFjLEdBQUc7Z0JBQ2YsT0FBTyxFQUFFLHFDQUFrQixDQUFDLE9BQU87Z0JBQ25DLFNBQVMsRUFBRSxxQ0FBa0IsQ0FBQyxTQUFTO2dCQUN2QyxxQkFBcUIsRUFBRSxXQUFXO2dCQUNsQyxtQkFBbUIsRUFBRSxxQ0FBa0IsQ0FBQyxrQkFBa0I7Z0JBQzFELGdCQUFnQixFQUFFLHFDQUFrQixDQUFDLGdCQUFnQjtnQkFDckQsb0JBQW9CLEVBQUUsNENBQTRDO2FBQ25FLENBQUM7WUFFRixNQUFNLFFBQVEsR0FBRyxNQUFNLFFBQVEsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7WUFFeEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN2QixRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDREQUE0RCxFQUFFLEtBQUs7WUFDcEUsYUFBYSxDQUFDLG9CQUFvQixDQUFDLEtBQUssRUFBRSw0Q0FBNEMsQ0FBQyxDQUFDO1lBQ3hGLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFcEMsTUFBTSwyQkFBMkIsR0FBRztnQkFDbEMsUUFBUSxFQUNOLG9JQUFvSTtnQkFDdEksbUJBQW1CLEVBQUUscUNBQWtCLENBQUMsa0JBQWtCO2dCQUMxRCxvQkFBb0IsRUFBRSw0Q0FBNEM7YUFDbkUsQ0FBQztZQUVGLE1BQU0sUUFBUSxHQUFHLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1lBQ3JFLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdkIsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3ZDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QyxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHNob3VsZCA9IHJlcXVpcmUoJ3Nob3VsZCcpO1xuaW1wb3J0IG5vY2sgPSByZXF1aXJlKCdub2NrJyk7XG5cbmltcG9ydCB7IG1vY2tTZXJpYWxpemVkQ2hhbGxlbmdlV2l0aFByb29mcywgVGVzdEJpdEdvIH0gZnJvbSAnQGJpdGdvL3Nkay10ZXN0JztcbmltcG9ydCB7IEJpdEdvIH0gZnJvbSAnLi4vLi4vLi4vc3JjJztcbmltcG9ydCB7IGtyc1Byb3ZpZGVycyB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBFY2RzYVJhbmdlUHJvb2YsIEVjZHNhVHlwZXMgfSBmcm9tICdAYml0Z28vc2RrLWxpYi1tcGMnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25GYWN0b3J5IH0gZnJvbSAnQGV0aGVyZXVtanMvdHgnO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgZXRoTGlrZURLTFNLZXljYXJkLCBldGhMaWtlR0cxOEtleWNhcmQgfSBmcm9tICcuLi9maXh0dXJlcy90c3MvcmVjb3ZlcnlGaXh0dXJlcyc7XG5pbXBvcnQgeyBVdGlscyB9IGZyb20gJ0BiaXRnby9zZGstY29pbi14cnAnO1xuaW1wb3J0IHsgVW5zaWduZWRTd2VlcFR4TVBDdjIgfSBmcm9tICdAYml0Z28vc2RrLWNvaW4tZXRoJztcblxuY29uc3QgcmVjb3ZlcnlOb2NrcyA9IHJlcXVpcmUoJy4uL2xpYi9yZWNvdmVyeS1ub2NrcycpO1xuXG5ub2NrLmRpc2FibGVOZXRDb25uZWN0KCk7XG5cbmRlc2NyaWJlKCdSZWNvdmVyeTonLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbztcblxuICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvLCB7IGVudjogJ3Rlc3QnIH0pO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuXG4gICAgLy8gcHJldGVuZCB0aGF0IEtleXRlcm5hbCBhY2NlcHRzIHJlY292ZXJpZXMgZm9yIGFsbCBjb2luc1xuICAgIGtyc1Byb3ZpZGVycy5rZXl0ZXJuYWwuc3VwcG9ydGVkQ29pbnMgPSBbJ2J0YycsICdldGgnLCAneHJwJywgJ2JjaCcsICdiY2hhJywgJ2x0YycsICd6ZWMnLCAnZGFzaCcsICd4bG0nLCAnYnN2J107XG4gICAgKGtyc1Byb3ZpZGVycy5rZXl0ZXJuYWwuZmVlQWRkcmVzc2VzIGFzIGFueSkgPSB7XG4gICAgICB0YnRjOiAnMk11ano5ZWljbWdwUGNkU2NSSlR5d1ZLM0VRTkhESkczeU4nLFxuICAgICAgdGJjaDogJzJNdWp6OWVpY21ncFBjZFNjUkpUeXdWSzNFUU5IREpHM3lOJyxcbiAgICAgIHRic3Y6ICcyTXVqejllaWNtZ3BQY2RTY1JKVHl3VkszRVFOSERKRzN5TicsXG4gICAgICB0YmNoYTogJzJNdWp6OWVpY21ncFBjZFNjUkpUeXdWSzNFUU5IREpHM3lOJyxcbiAgICAgIHRsdGM6ICdRZmZYTVZpTThEWWdQUmYxSG9jemp3N0JTNUNWZFNXYUJMJyxcbiAgICAgIHR6ZWM6ICd0MkFUTEFoQlAxdVR1eWlXczVEWTVDUEgxVnVZa0dVaW5kdCcsXG4gICAgICB0ZGFzaDogJzhldUh1ZzRkYm1QeTNDTGF3d1dkZVRqR0xxUFlFR3ozS3QnLFxuICAgIH07XG4gIH0pO1xuXG4gIGFmdGVyKGZ1bmN0aW9uICgpIHtcbiAgICBub2NrLmNsZWFuQWxsKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIFJpcHBsZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIFhSUCByZWNvdmVyeSB0eCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1hycFJlY292ZXJ5KCk7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndHhycCcpO1xuICAgICAgcmV0dXJuIGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICAgJ3tcIml2XCI6XCJyVSsrbUV0SUh0YnAzZDRqZzVFdWxBPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiaXAxcmI1OXVZbk09XCIsXCJjdFwiOlwic3NtUDlhYlBvVnlYa1c0SW8wU1V5K0FBUzhscit3Z0llclRNdytsRFlua1VoMHNqbEk0QTZGcHZlMHExcmlRM0R5L0owYk51N2Rnb1prTzR4cy9YNmR6d0V3bG1QaGszcEVRN1lkNENYYTF6QTAxeTBHZXU5MDBGTGU0TGRhUzhqdDZmaXh1aTJ0VGQ0VmkzSllnbEYxL0htQ2pHMVVnPVwifScsXG4gICAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICAgJ3tcIml2XCI6XCJ1Qi9CVGNuMXJYbWdZR2ZuY1hPb3dnPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiSTNXcnVteGt1TVE9XCIsXCJjdFwiOlwic2d5RE5Bek5zQnJ1VFJtMGQwNG9CVEJmOGxoZUhOS1MrZFJnbDhGZU1FaG9kS3NpeWp0UlZIRzBDSFBmNXJWM2c1aXhWbloraXdzU0N2M1BLeXllb3k3UkduVDBBRzlZWXBpMG1lK092UDgzMzFpTytuNXF1enN0ckdiVjFqOHVFaDVJTVc3OFMrWVVaS1N4NnpiYmRaMHhOdThENVdNPVwifScsXG4gICAgICAgICAgcm9vdEFkZHJlc3M6ICdyYUdaV1JrUkJVV2RRSnNLWUV6d1hKTmJDWk1UcVg1NmFBJyxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9XQUxMRVQxX1BBU1NDT0RFLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdyc3Yya3JlbUpTU0ZiYmFMcXJmOGZXeHhONVFuc3luTm0yP2R0PTEyMzQ1JyxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlY292ZXJ5KSB7XG4gICAgICAgICAgcmVjb3ZlcnkudHhIZXguc2hvdWxkLmVxdWFsKFxuICAgICAgICAgICAgJzEyMDAwMDIyODAwMDAwMDAyNDAwMDAwMDA0MkUwMDAwMzAzOTIwMUIwMDE1NTE5MTYxNDAwMDAwMDI0RTA2QzBDMDY4NDAwMDAwMDAwMDAwMDAxRTczMDA4MTE0MzlDQTAxMEUwRTAxOTgxNTBGOERERDU3NjhDQ0QyQjA5NTcwMUQ4QzgzMTQyMDEyNzZBREM0NjlDNEYxMEQxMzY5RTBGNUM1QTdERUYzN0IyMjY3RjNFMDEwNzMyMTAyNkM5MTk3NDE0NjQyNzg4OUM4MDFCRDI2Q0UzMUNFMEUxMDMwN0E2OURGRTQxMzlERTQ1RTVFMzU5MzNBNkIwMzc0NDYzMDQ0MDIyMDRBQTNEMkYzNDQ3MjlCMEJCOTA3NUM0QUVBMDdFQkIyRUFGNkQzRjM2MzA5QkNBRUYxMEIyQzk3MzRBQzk0M0UwMjIwMzJENTVFQzE5RTI3QjJFOTBFM0Q5NDQ0RkQyNkNDMDZGRDQ3QkIzRTNEODVCMEZDQzBDQzRERTcwMzg1NjNGRDgxMTRBQkI1QjdDODQzRjNBQThEOEVGQUNDM0M1QTdEOUIwNDg0QzE3NDQyRTFFMDEwNzMyMTAyRjRFMzc2MTMzMDEyRjU0MDQ5OTBDN0UxREY4M0E5Rjk0M0IzMEQ1NUYwRDg1NjYzMkM4RTgzNzhGQ0VCNzBEMjc0NDYzMDQ0MDIyMDU2OEYxRDQ5RjU4MTA0NThFNzIwNEExRDJEMjNCODZCNjk0NTA1MzI3RTg0MTBBMjE1QUI5QzkzMjRFQThBMzEwMjIwN0E5MzIxMUFDRkI1RTlDMTQ0MUI3MDFBNzk1NEI3MkEzMDU0MjY1QkEzRkQ2MTk2NUQ3MDlFNEM0RTkwODBGMzgxMTRBQ0VGOUYwQTJGQ0VDNDRBOUEyMTM0NDRBOUU2QzU3RTJEMDI4NTZBRTFGMSdcbiAgICAgICAgICApO1xuICAgICAgICAgIHJlY292ZXJ5LmlkLnNob3VsZC5lcXVhbCgnRjIwMDVCMzkyRTk0NTRGRjFFODIxN0I4MTZDODc4NjZBNTY3NzAzODJCOEZDQUMwQUFFMkZBOEQxMkE1M0I5OCcpO1xuICAgICAgICAgIHJlY292ZXJ5Lm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoJzk4OTkwMDAwMDAnKTtcbiAgICAgICAgICByZWNvdmVyeS5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgICAgcmVjb3Zlcnkub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCgncnN2MmtyZW1KU1NGYmJhTHFyZjhmV3h4TjVRbnN5bk5tMj9kdD0xMjM0NScpO1xuICAgICAgICAgIHJlY292ZXJ5Lm91dHB1dHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbCgnOTg5OTAwMDAwMCcpO1xuICAgICAgICAgIHJlY292ZXJ5LmZlZS5mZWUuc2hvdWxkLmVxdWFsKCczMCcpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgWFJQIHJlY292ZXJ5IHR4IHdpdGggS1JTJywgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrWHJwUmVjb3ZlcnkoKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0eHJwJyk7XG4gICAgICByZXR1cm4gYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgICAne1wiaXZcIjpcInJVKyttRXRJSHRicDNkNGpnNUV1bEE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJpcDFyYjU5dVluTT1cIixcImN0XCI6XCJzc21QOWFiUG9WeVhrVzRJbzBTVXkrQUFTOGxyK3dnSWVyVE13K2xEWW5rVWgwc2psSTRBNkZwdmUwcTFyaVEzRHkvSjBiTnU3ZGdvWmtPNHhzL1g2ZHp3RXdsbVBoazNwRVE3WWQ0Q1hhMXpBMDF5MEdldTkwMEZMZTRMZGFTOGp0NmZpeHVpMnRUZDRWaTNKWWdsRjEvSG1DakcxVWc9XCJ9JyxcbiAgICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0Z0V2RtV0hLWkVoOXBZaUpyQUdUdTFOTlN3eFkyUzYzdFU5bkdjZkNBYk5VS1F1RnFYUlRSazhLa3VCYWJ4bzZZamVCcmk4UTdka01zbXRoczZNVnhTZDZNVGFlQ21kJyxcbiAgICAgICAgICByb290QWRkcmVzczogJ3JhR1pXUmtSQlVXZFFKc0tZRXp3WEpOYkNaTVRxWDU2YUEnLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1dBTExFVDFfUEFTU0NPREUsXG4gICAgICAgICAga3JzUHJvdmlkZXI6ICdrZXl0ZXJuYWwnLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdyc3Yya3JlbUpTU0ZiYmFMcXJmOGZXeHhONVFuc3luTm0yP2R0PTEyMzQ1JyxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlY292ZXJ5KSB7XG4gICAgICAgICAgcmVjb3ZlcnkudHhIZXguc2hvdWxkLmVxdWFsKFxuICAgICAgICAgICAgJzEyMDAwMDIyODAwMDAwMDAyNDAwMDAwMDA0MkUwMDAwMzAzOTIwMUIwMDE1NTE5MTYxNDAwMDAwMDI0RTA2QzBDMDY4NDAwMDAwMDAwMDAwMDAxRTczMDA4MTE0MzlDQTAxMEUwRTAxOTgxNTBGOERERDU3NjhDQ0QyQjA5NTcwMUQ4QzgzMTQyMDEyNzZBREM0NjlDNEYxMEQxMzY5RTBGNUM1QTdERUYzN0IyMjY3RjNFMDEwNzMyMTAyRjRFMzc2MTMzMDEyRjU0MDQ5OTBDN0UxREY4M0E5Rjk0M0IzMEQ1NUYwRDg1NjYzMkM4RTgzNzhGQ0VCNzBEMjc0NDYzMDQ0MDIyMDU2OEYxRDQ5RjU4MTA0NThFNzIwNEExRDJEMjNCODZCNjk0NTA1MzI3RTg0MTBBMjE1QUI5QzkzMjRFQThBMzEwMjIwN0E5MzIxMUFDRkI1RTlDMTQ0MUI3MDFBNzk1NEI3MkEzMDU0MjY1QkEzRkQ2MTk2NUQ3MDlFNEM0RTkwODBGMzgxMTRBQ0VGOUYwQTJGQ0VDNDRBOUEyMTM0NDRBOUU2QzU3RTJEMDI4NTZBRTFGMSdcbiAgICAgICAgICApO1xuICAgICAgICAgIHJlY292ZXJ5LmlkLnNob3VsZC5lcXVhbCgnNkVBMTcyOEIwQ0MwQzA0N0U1NEFBRjU3OEQ4MTgyMkVERTExMDc5MDhCOTc5ODY4Mjk5NjU3RTc0QThFMThDMCcpO1xuICAgICAgICAgIHJlY292ZXJ5Lm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoJzk4OTkwMDAwMDAnKTtcbiAgICAgICAgICByZWNvdmVyeS5vdXRwdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgICAgcmVjb3Zlcnkub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbCgncnN2MmtyZW1KU1NGYmJhTHFyZjhmV3h4TjVRbnN5bk5tMj9kdD0xMjM0NScpO1xuICAgICAgICAgIHJlY292ZXJ5Lm91dHB1dHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbCgnOTg5OTAwMDAwMCcpO1xuICAgICAgICAgIHJlY292ZXJ5LmZlZS5mZWUuc2hvdWxkLmVxdWFsKCczMCcpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gWFJQIHVuc2lnbmVkIHN3ZWVwJywgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrWHJwUmVjb3ZlcnkoKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0eHJwJyk7XG4gICAgICByZXR1cm4gYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0Y5WWE0ekRIR3pEdEp6M05hYWVFR2JRNnJucW5OeEw5UlhESk5IY2Z6QXlQVUJYdUtYanl0dkpOelF4cWJqQndtUHZlaVlYMzIzWnA4WngyUllRTjlnR003bnRpWHhyJyxcbiAgICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0Z0V2RtV0hLWkVoOXBZaUpyQUdUdTFOTlN3eFkyUzYzdFU5bkdjZkNBYk5VS1F1RnFYUlRSazhLa3VCYWJ4bzZZamVCcmk4UTdka01zbXRoczZNVnhTZDZNVGFlQ21kJyxcbiAgICAgICAgICByb290QWRkcmVzczogJ3JhR1pXUmtSQlVXZFFKc0tZRXp3WEpOYkNaTVRxWDU2YUEnLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1dBTExFVDFfUEFTU0NPREUsXG4gICAgICAgICAga3JzUHJvdmlkZXI6ICdrZXl0ZXJuYWwnLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdyc3Yya3JlbUpTU0ZiYmFMcXJmOGZXeHhONVFuc3luTm0yP2R0PTEyMzQ1JyxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlY292ZXJ5KSB7XG4gICAgICAgICAgcmVjb3ZlcnkudHhIZXguc2hvdWxkLmVxdWFsKFxuICAgICAgICAgICAgJzEyMDAwMDIyODAwMDAwMDAyNDAwMDAwMDA0MkUwMDAwMzAzOTIwMUIwMDE1NTE5MTYxNDAwMDAwMDI0RTA2QzBDMDY4NDAwMDAwMDAwMDAwMDAxRTgxMTQzOUNBMDEwRTBFMDE5ODE1MEY4RERENTc2OENDRDJCMDk1NzAxRDhDODMxNDIwMTI3NkFEQzQ2OUM0RjEwRDEzNjlFMEY1QzVBN0RFRjM3QjIyNjcnXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCB0eDogYW55ID0gVXRpbHMuZGVjb2RlVHJhbnNhY3Rpb24ocmVjb3ZlcnkudHhIZXgpO1xuICAgICAgICAgIHR4LlRyYW5zYWN0aW9uVHlwZS5zaG91bGQuZXF1YWwoJ1BheW1lbnQnKTtcbiAgICAgICAgICB0eC5BY2NvdW50LnNob3VsZC5lcXVhbCgncmFHWldSa1JCVVdkUUpzS1lFendYSk5iQ1pNVHFYNTZhQScpO1xuICAgICAgICAgIHR4LkRlc3RpbmF0aW9uLnNob3VsZC5lcXVhbCgncnN2MmtyZW1KU1NGYmJhTHFyZjhmV3h4TjVRbnN5bk5tMicpO1xuICAgICAgICAgIHR4LkRlc3RpbmF0aW9uVGFnLnNob3VsZC5lcXVhbCgxMjM0NSk7XG4gICAgICAgICAgdHguQW1vdW50LnNob3VsZC5lcXVhbCgnOTg5OTAwMDAwMCcpO1xuICAgICAgICAgIHR4LkZsYWdzLnNob3VsZC5lcXVhbCgyMTQ3NDgzNjQ4KTtcbiAgICAgICAgICB0eC5MYXN0TGVkZ2VyU2VxdWVuY2Uuc2hvdWxkLmVxdWFsKDEzOTcxMzcpO1xuICAgICAgICAgIHR4LkZlZS5zaG91bGQuZXF1YWwoJzMwJyk7XG4gICAgICAgICAgdHguU2VxdWVuY2Uuc2hvdWxkLmVxdWFsKDQpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXIgU3RlbGxhcicsIGZ1bmN0aW9uICgpIHtcbiAgICBhc3luYyBmdW5jdGlvbiBjaGVja1JlY292ZXJ5VHhFeHBsYW5hdGlvbihiYXNlY29pbiwgdHgsIHJlY292ZXJ5QW1vdW50LCByZWNvdmVyeURlc3RpbmF0aW9uKSB7XG4gICAgICBjb25zdCBleHBsYW5hdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7IHR4QmFzZTY0OiB0eCB9KTtcbiAgICAgIGV4cGxhbmF0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdvdXRwdXRzJyk7XG4gICAgICBleHBsYW5hdGlvbi5vdXRwdXRzLnNob3VsZC5jb250YWluRXFsKHtcbiAgICAgICAgYW1vdW50OiByZWNvdmVyeUFtb3VudC50b0ZpeGVkKCksXG4gICAgICAgIGFkZHJlc3M6IHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgIGNvaW46IGJhc2Vjb2luLmdldENoYWluKCksXG4gICAgICB9KTtcbiAgICAgIGV4cGxhbmF0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjaGFuZ2VPdXRwdXRzJywgW10pO1xuICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NoYW5nZUFtb3VudCcsICcwJyk7XG4gICAgICBleHBsYW5hdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlJywgeyBmZWU6ICcxMDAnLCBmZWVSYXRlOiBudWxsLCBzaXplOiBudWxsIH0pO1xuICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ29wZXJhdGlvbnMnLCBbXSk7XG4gICAgfVxuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBYTE0gcmVjb3ZlcnkgdHgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tYbG1SZWNvdmVyeSgpO1xuXG4gICAgICBjb25zdCByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgdXNlcktleTogYHtcIml2XCI6XCJQaUx2ZUErNUFGUFVSd2FVN2lpakJRPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiS2xKYzhOU0tIcHc9XCIsXCJjdFwiOlwiWWNkTk9GcHpYZ0RuUnFqbFIzVzlSKzVlenR5c3locENUdVJCSHNuUHlQRHN0OW52TCtHZVNPUmJMWTl4VlRoVGR5VjZsbFJnZlVyNU83eTRsOXM5Rmc9PVwifWAsXG4gICAgICAgIGJhY2t1cEtleTogYHtcIml2XCI6XCJUbWlBSUhyMHZDWDZnMkJLa2M2LzdnPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwid09rTUpFbTVCNlU9XCIsXCJjdFwiOlwiSEpQUzU2L0Z1TWllaUg2SzJzNWs1akZwOFJQSFFxWmE5cWk4aERrak9xTlVGakQ0WEtxOFN5M0JEaHB3em96VEJXNkVtUUdTRjBrcGM3ZVo5Q3VjS3c9PVwifWAsXG4gICAgICAgIHJvb3RBZGRyZXNzOiAnR0FVQUdUTDNOQlo3TlAzVUlNWkNWSllNNk8yTktVUDZYUlRLNEU1VlpEVklRWDNDQllJVk1ESUInLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ0dBU1cyNzdTMlpPRTdIN0E1RVE1SDVBS0xQNlVBNlo1QUtPU1dWNkFSQkVHVFNJR01aTUM3QUlaJyxcbiAgICAgIH07XG4gICAgICBjb25zdCByZWNvdmVyeUFtb3VudCA9IDc0OTk5NTAwO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R4bG0nKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEJhc2U2NCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY292ZXJ5QW1vdW50JywgcmVjb3ZlcnlBbW91bnQpO1xuXG4gICAgICBhd2FpdCBjaGVja1JlY292ZXJ5VHhFeHBsYW5hdGlvbihiYXNlY29pbiwgcmVjb3ZlcnkudHhCYXNlNjQsIHJlY292ZXJ5QW1vdW50LCByZWNvdmVyeVBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciB0byBhbiB1bmZ1bmRlZCBYTE0gd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrWGxtUmVjb3ZlcnkoKTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIHVzZXJLZXk6IGB7XCJpdlwiOlwiUGlMdmVBKzVBRlBVUndhVTdpaWpCUT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIktsSmM4TlNLSHB3PVwiLFwiY3RcIjpcIlljZE5PRnB6WGdEblJxamxSM1c5Uis1ZXp0eXN5aHBDVHVSQkhzblB5UERzdDludkwrR2VTT1JiTFk5eFZUaFRkeVY2bGxSZ2ZVcjVPN3k0bDlzOUZnPT1cIn1gLFxuICAgICAgICBiYWNrdXBLZXk6IGB7XCJpdlwiOlwiVG1pQUlIcjB2Q1g2ZzJCS2tjNi83Zz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIndPa01KRW01QjZVPVwiLFwiY3RcIjpcIkhKUFM1Ni9GdU1pZWlINksyczVrNWpGcDhSUEhRcVphOXFpOGhEa2pPcU5VRmpENFhLcThTeTNCRGhwd3pvelRCVzZFbVFHU0Ywa3BjN2VaOUN1Y0t3PT1cIn1gLFxuICAgICAgICByb290QWRkcmVzczogJ0dBVUFHVEwzTkJaN05QM1VJTVpDVkpZTTZPMk5LVVA2WFJUSzRFNVZaRFZJUVgzQ0JZSVZNRElCJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdHQUdDUUxVR01YNzZYQzI0SlJDUkpXT0hYSzIzT05VUkg0NDMzSk9FUFU2Q0g3WjQ0Q0NZVUNFTCcsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVjb3ZlcnlBbW91bnQgPSA3NDk5OTUwMDtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0eGxtJyk7XG4gICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpO1xuXG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhCYXNlNjQnKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNvdmVyeUFtb3VudCcsIHJlY292ZXJ5QW1vdW50KTtcblxuICAgICAgYXdhaXQgY2hlY2tSZWNvdmVyeVR4RXhwbGFuYXRpb24oYmFzZWNvaW4sIHJlY292ZXJ5LnR4QmFzZTY0LCByZWNvdmVyeUFtb3VudCwgcmVjb3ZlcnlQYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIFhMTSByZWNvdmVyeSB0eCB3aXRoIHVuZW5jcnlwdGVkIGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tYbG1SZWNvdmVyeSgpO1xuXG4gICAgICBjb25zdCByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgdXNlcktleTogYFNBTUY1WFM3TzVCTDRPT1RCNjI1REVMQ1ZOVzVKTUhGMkRETTdOU0lWUE5RUUVLUEtMQlFGTkozYCxcbiAgICAgICAgYmFja3VwS2V5OiBgU0NYWjdVRlZTSUZJWUpWUExXRUFZMjJUWkpPUjRMMlo0SEU2Qk1aR1pIQkJKNFVBQUJURk1LM1ZgLFxuICAgICAgICByb290QWRkcmVzczogJ0dBVUFHVEwzTkJaN05QM1VJTVpDVkpZTTZPMk5LVVA2WFJUSzRFNVZaRFZJUVgzQ0JZSVZNRElCJyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ0dBU1cyNzdTMlpPRTdIN0E1RVE1SDVBS0xQNlVBNlo1QUtPU1dWNkFSQkVHVFNJR01aTUM3QUlaJyxcbiAgICAgIH07XG4gICAgICBjb25zdCByZWNvdmVyeUFtb3VudCA9IDc0OTk5NTAwO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R4bG0nKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEJhc2U2NCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY292ZXJ5QW1vdW50JywgcmVjb3ZlcnlBbW91bnQpO1xuXG4gICAgICBhd2FpdCBjaGVja1JlY292ZXJ5VHhFeHBsYW5hdGlvbihiYXNlY29pbiwgcmVjb3ZlcnkudHhCYXNlNjQsIHJlY292ZXJ5QW1vdW50LCByZWNvdmVyeVBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgWExNIHJlY292ZXJ5IHR4IHdpdGggdW5lbmNyeXB0ZWQgcm9vdCBwcml2YXRlIGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tYbG1SZWNvdmVyeSgpO1xuXG4gICAgICAvLyB1c2VyS2V5IGFuZCBiYWNrdXBLZXkgYXJlIGluIHBydiArIHB1YiByZXByZXNlbnRhdGlvblxuICAgICAgLy8gZmlyc3QgNjQgY2hhcmFjdGVycyAoMzIgYnl0ZXMpIGFyZSB0aGUgcHJpdmF0ZSBrZXksIHRoZSByZXN0IGlzIHRoZSBwdWJsaWMga2V5XG4gICAgICBjb25zdCByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgdXNlcktleTogYDE4NWVkZTVmNzc0MmJlMzlkMzBmYjVkMTkxNjJhYjZkZDRiMGU1ZDBjNmNmYjY0OGFiZGIwODExNGY1MmMzMDI1YWFlMTUyZWYxNDcwNjg2YWJhM2ZlYzQwODg5YTU1MGQ3YjUzOTEwYzczOWUyNWI1ZDRhMmYyN2ViNTEyZWI3YCxcbiAgICAgICAgYmFja3VwS2V5OiBgYWY5ZmQwYjU5MjBhOGMyNmFmNWQ4ODBjNmI1M2NhNWQxZTJmNTllMWM5ZTBiMzI2YzljMjE0ZjI4MDAwNjY1NjgyMDBhNWU0ZGQyNzlkYTVmNDIyMzI0YjgyMTBlODk4ZGJmNjhmYzI5YzFmOWNmNzkxYzIyNDE4N2ZhZDdkYzNgLFxuICAgICAgICByb290QWRkcmVzczogJ0dBVUFHVEwzTkJaN05QM1VJTVpDVkpZTTZPMk5LVVA2WFJUSzRFNVZaRFZJUVgzQ0JZSVZNRElCJyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ0dBU1cyNzdTMlpPRTdIN0E1RVE1SDVBS0xQNlVBNlo1QUtPU1dWNkFSQkVHVFNJR01aTUM3QUlaJyxcbiAgICAgIH07XG4gICAgICBjb25zdCByZWNvdmVyeUFtb3VudCA9IDc0OTk5NTAwO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R4bG0nKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEJhc2U2NCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY292ZXJ5QW1vdW50JywgcmVjb3ZlcnlBbW91bnQpO1xuXG4gICAgICBhd2FpdCBjaGVja1JlY292ZXJ5VHhFeHBsYW5hdGlvbihiYXNlY29pbiwgcmVjb3ZlcnkudHhCYXNlNjQsIHJlY292ZXJ5QW1vdW50LCByZWNvdmVyeVBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgWExNIHJlY292ZXJ5IHR4IHdpdGggZW5jcnlwdGVkIHJvb3Qga2V5cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1hsbVJlY292ZXJ5KCk7XG5cbiAgICAgIC8vIHVzZXJLZXkgYW5kIGJhY2t1cEtleSBhcmUgaW4gZW5jcnlwdGVkIHBydiArIHB1YiByZXByZXNlbnRhdGlvblxuICAgICAgY29uc3QgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIHVzZXJLZXk6IGB7XCJpdlwiOlwiYlVIdzUzT2E4dFNyRlJ6aWRQaThhZz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIlFITlpGbERuQ1cwPVwiLFwiY3RcIjpcIkFRU0FCdlVtQ01zRDNySlF6eWcyOVRuTFBuRFZDWkZYWmtnOWhKMlJlWWFYV1drU2I4Qncwbm4zTFcvR0lHaTNaYk9nUGl2SjRMaENiTzlBMnBwNGFWT2hic2JxQ05CV3hwbUh6bmVWUzNGUHJMZWJRaXhIMVJuMFgrZnQySTlYY05ORWtsRXc1Y0gzcGY5STF2cUxtd0VIcEY4RFd4ME9nR25saC9RcTByNVphRXQ1dGJURFBBPT1cIn1gLFxuICAgICAgICBiYWNrdXBLZXk6IGB7XCJpdlwiOlwiMTlTUTNTbEx6dVRiRWZVN3M4bFRIUT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcImpMTTJvV3lPOFdnPVwiLFwiY3RcIjpcImlYVWROY3Foc2J5a2Z5TEtZcmNFZWdTSG9vQUp0ODJrcmRTV2hRaHMvY1VBb0E2dFg0aitIZk91dFFoU1BEdEprSXBiejE5eW5vVG84VlZweHAvR2ErdWJRVmxDbGJaUHloQzhZa0NSdkpCdldLZzQxRUVHbHlkdUs3ZXNWcm5udjFjNFhrNGE0QmFYc3pPRWRHdy8xYVFCOUFPUU1NVnN2Nno4WWh1NTVRcVZ6NnpONDlQbWFRPT1cIn1gLFxuICAgICAgICByb290QWRkcmVzczogJ0dBVUFHVEwzTkJaN05QM1VJTVpDVkpZTTZPMk5LVVA2WFJUSzRFNVZaRFZJUVgzQ0JZSVZNRElCJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdHQVNXMjc3UzJaT0U3SDdBNUVRNUg1QUtMUDZVQTZaNUFLT1NXVjZBUkJFR1RTSUdNWk1DN0FJWicsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZWNvdmVyeUFtb3VudCA9IDc0OTk5NTAwO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R4bG0nKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEJhc2U2NCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY292ZXJ5QW1vdW50JywgcmVjb3ZlcnlBbW91bnQpO1xuXG4gICAgICBhd2FpdCBjaGVja1JlY292ZXJ5VHhFeHBsYW5hdGlvbihiYXNlY29pbiwgcmVjb3ZlcnkudHhCYXNlNjQsIHJlY292ZXJ5QW1vdW50LCByZWNvdmVyeVBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgWExNIHJlY292ZXJ5IHR4IHdpdGggS1JTJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrWGxtUmVjb3ZlcnkoKTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIHVzZXJLZXk6IGB7XCJpdlwiOlwiUGlMdmVBKzVBRlBVUndhVTdpaWpCUT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIktsSmM4TlNLSHB3PVwiLFwiY3RcIjpcIlljZE5PRnB6WGdEblJxamxSM1c5Uis1ZXp0eXN5aHBDVHVSQkhzblB5UERzdDludkwrR2VTT1JiTFk5eFZUaFRkeVY2bGxSZ2ZVcjVPN3k0bDlzOUZnPT1cIn1gLFxuICAgICAgICBiYWNrdXBLZXk6ICdHQ0JBQkpQRTNVVFozSlBVRUlaRVhBUVE1Q01OWDVVUFlLT0I3SEhYU0hCQ0lHRDdWVjY0SDZLVScsXG4gICAgICAgIHJvb3RBZGRyZXNzOiAnR0FVQUdUTDNOQlo3TlAzVUlNWkNWSllNNk8yTktVUDZYUlRLNEU1VlpEVklRWDNDQllJVk1ESUInLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ0dBU1cyNzdTMlpPRTdIN0E1RVE1SDVBS0xQNlVBNlo1QUtPU1dWNkFSQkVHVFNJR01aTUM3QUlaJyxcbiAgICAgICAga3JzUHJvdmlkZXI6ICdrZXl0ZXJuYWwnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5QW1vdW50ID0gNzQ5OTk1MDA7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndHhsbScpO1xuICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKTtcblxuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4QmFzZTY0Jyk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjb3ZlcnlBbW91bnQnLCA3NDk5OTUwMCk7XG5cbiAgICAgIGF3YWl0IGNoZWNrUmVjb3ZlcnlUeEV4cGxhbmF0aW9uKGJhc2Vjb2luLCByZWNvdmVyeS50eEJhc2U2NCwgcmVjb3ZlcnlBbW91bnQsIHJlY292ZXJ5UGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBYTE0gcmVjb3ZlcnkgdHggd2l0aCBLUlMgdXNpbmcgcm9vdCBrZXlzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrWGxtUmVjb3ZlcnkoKTtcblxuICAgICAgLy8gdXNlcktleSBpcyBpbiBlbmNyeXB0ZWQgcHJ2ICsgcHViIHJlcHJlc2VudGF0aW9uXG4gICAgICBjb25zdCByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgdXNlcktleTogYHtcIml2XCI6XCJiVUh3NTNPYTh0U3JGUnppZFBpOGFnPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiUUhOWkZsRG5DVzA9XCIsXCJjdFwiOlwiQVFTQUJ2VW1DTXNEM3JKUXp5ZzI5VG5MUG5EVkNaRlhaa2c5aEoyUmVZYVhXV2tTYjhCdzBubjNMVy9HSUdpM1piT2dQaXZKNExoQ2JPOUEycHA0YVZPaGJzYnFDTkJXeHBtSHpuZVZTM0ZQckxlYlFpeEgxUm4wWCtmdDJJOVhjTk5Fa2xFdzVjSDNwZjlJMXZxTG13RUhwRjhEV3gwT2dHbmxoL1FxMHI1WmFFdDV0YlREUEE9PVwifWAsXG4gICAgICAgIGJhY2t1cEtleTogJzgyMDBhNWU0ZGQyNzlkYTVmNDIyMzI0YjgyMTBlODk4ZGJmNjhmYzI5YzFmOWNmNzkxYzIyNDE4N2ZhZDdkYzMnLCAvLyB0aGlzIGlzIGEgcHViIHJvb3Qga2V5LCBub3RlIGl0IGlzIDMyIGJ5dGVzXG4gICAgICAgIHJvb3RBZGRyZXNzOiAnR0FVQUdUTDNOQlo3TlAzVUlNWkNWSllNNk8yTktVUDZYUlRLNEU1VlpEVklRWDNDQllJVk1ESUInLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ0dBU1cyNzdTMlpPRTdIN0E1RVE1SDVBS0xQNlVBNlo1QUtPU1dWNkFSQkVHVFNJR01aTUM3QUlaJyxcbiAgICAgICAga3JzUHJvdmlkZXI6ICdrZXl0ZXJuYWwnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5QW1vdW50ID0gNzQ5OTk1MDA7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndHhsbScpO1xuICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKTtcblxuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4QmFzZTY0Jyk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjb3ZlcnlBbW91bnQnLCA3NDk5OTUwMCk7XG5cbiAgICAgIGF3YWl0IGNoZWNrUmVjb3ZlcnlUeEV4cGxhbmF0aW9uKGJhc2Vjb2luLCByZWNvdmVyeS50eEJhc2U2NCwgcmVjb3ZlcnlBbW91bnQsIHJlY292ZXJ5UGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiBYTE0gdW5zaWduZWQgc3dlZXAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tYbG1SZWNvdmVyeSgpO1xuXG4gICAgICBjb25zdCByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgdXNlcktleTogJ0dCTks0RkpPNkZEUU5CVkxVUDdNSUNFSlVWSU5QTkpaQ0REVFRZUzNMVkZDNko3TEtFWExPQktNJyxcbiAgICAgICAgYmFja3VwS2V5OiAnR0NCQUJKUEUzVVRaM0pQVUVJWkVYQVFRNUNNTlg1VVBZS09CN0hIWFNIQkNJR0Q3VlY2NEg2S1UnLFxuICAgICAgICByb290QWRkcmVzczogJ0dBVUFHVEwzTkJaN05QM1VJTVpDVkpZTTZPMk5LVVA2WFJUSzRFNVZaRFZJUVgzQ0JZSVZNRElCJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlYyLlRFU1RfUkVDT1ZFUllfUEFTU0NPREUsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdHQVNXMjc3UzJaT0U3SDdBNUVRNUg1QUtMUDZVQTZaNUFLT1NXVjZBUkJFR1RTSUdNWk1DN0FJWicsXG4gICAgICAgIGtyc1Byb3ZpZGVyOiAna2V5dGVybmFsJyxcbiAgICAgIH07XG4gICAgICBjb25zdCByZWNvdmVyeUFtb3VudCA9IDc0OTk5NTAwO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R4bG0nKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEJhc2U2NCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY292ZXJ5QW1vdW50JywgNzQ5OTk1MDApO1xuXG4gICAgICBhd2FpdCBjaGVja1JlY292ZXJ5VHhFeHBsYW5hdGlvbihiYXNlY29pbiwgcmVjb3ZlcnkudHhCYXNlNjQsIHJlY292ZXJ5QW1vdW50LCByZWNvdmVyeVBhcmFtcy5yZWNvdmVyeURlc3RpbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gWExNIHVuc2lnbmVkIHN3ZWVwIHVzaW5nIHJvb3Qga2V5cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1hsbVJlY292ZXJ5KCk7XG5cbiAgICAgIGNvbnN0IHJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgICB1c2VyS2V5OiAnNWFhZTE1MmVmMTQ3MDY4NmFiYTNmZWM0MDg4OWE1NTBkN2I1MzkxMGM3MzllMjViNWQ0YTJmMjdlYjUxMmViNycsIC8vIHRoaXMgaXMgYSBwdWIga2V5LCBub3RlIGl0IGlzIDMyIGJ5dGVzXG4gICAgICAgIGJhY2t1cEtleTogJzgyMDBhNWU0ZGQyNzlkYTVmNDIyMzI0YjgyMTBlODk4ZGJmNjhmYzI5YzFmOWNmNzkxYzIyNDE4N2ZhZDdkYzMnLCAvLyB0aGlzIGlzIGEgcHViIHJvb3Qga2V5LCBub3RlIGl0IGlzIDMyIGJ5dGVzXG4gICAgICAgIHJvb3RBZGRyZXNzOiAnR0FVQUdUTDNOQlo3TlAzVUlNWkNWSllNNk8yTktVUDZYUlRLNEU1VlpEVklRWDNDQllJVk1ESUInLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ0dBU1cyNzdTMlpPRTdIN0E1RVE1SDVBS0xQNlVBNlo1QUtPU1dWNkFSQkVHVFNJR01aTUM3QUlaJyxcbiAgICAgICAga3JzUHJvdmlkZXI6ICdrZXl0ZXJuYWwnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5QW1vdW50ID0gNzQ5OTk1MDA7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndHhsbScpO1xuICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKTtcblxuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4QmFzZTY0Jyk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjb3ZlcnlBbW91bnQnLCA3NDk5OTUwMCk7XG5cbiAgICAgIGF3YWl0IGNoZWNrUmVjb3ZlcnlUeEV4cGxhbmF0aW9uKGJhc2Vjb2luLCByZWNvdmVyeS50eEJhc2U2NCwgcmVjb3ZlcnlBbW91bnQsIHJlY292ZXJ5UGFyYW1zLnJlY292ZXJ5RGVzdGluYXRpb24pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVjb3ZlciBUUk9OJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBiYXNlQ29pbjtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICBiYXNlQ29pbiA9IGJpdGdvLmNvaW4oJ3R0cngnKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIHJlY292ZXJ5IHR4IGZyb20gZW5jcnlwdGVkIHVzZXIgYW5kIGJhY2t1cCBrZXlzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrVHJvblJlY292ZXJ5KCk7XG4gICAgICBjb25zdCByZWNvdmVyeVR4ID0gYXdhaXQgYmFzZUNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgJ3tcIml2XCI6XCJlWHdZSXlnRHlSeTFSMWx3OUV3RWdRPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiTk5PeEYrTFI3YVU9XCIsXCJjdFwiOlwicVgvRytBaVpKMzVYd1VtTDlhbFlpdFJ3dllnRS9iUzI0RFNBVlY3dEJhb1RzNDB0c1ZCL2tXeCtoVi9KNWFjS0lBNlovd1N1Y3hiS3JRbEpCNjl4SkpsL09pcllxbVhSQmlySCtyYWcxYUMxemo3WlZuYk8raCtQNUdIcUhKbHRMYzRVeURmK3AyMitOam9ETGZSK2ZFUHRHOGM0djVvPVwifScsXG4gICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAne1wiaXZcIjpcIlFhb1hDRWtpYm80Vk1FeW8zZlNVVVE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJpcXF0ckJ0QzV2WT1cIixcImN0XCI6XCJKSGJISjhVMkFsYTJjUkZjb3FUQWZ0TFltRERTT1RmaGRWbVprbVcvT1JKZVA2MFZmNVQxbTY2MXlXUVQzQURLU3NxMkNTUlY0OU9xU2ZIMmxJT0JVM0VmWGRGWGtXUWVUTlgrYmh6QzZFMm8vdXMzU253bFhoTzY1OURRTVBtTHRodmdDVFg4eE0rNVV6Z1YvUFlucUZwU3V4bDM3OXM9XCJ9JyxcbiAgICAgICAgYml0Z29LZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNFeDZ6S1RCcmdaa1dQQkd2eDhxZ3VFZDFOcUVEcDZ5VzNzckJHaFRVZEZrY2RjQmpwNUZRZ1hrRE5pUUJkajZGc2drYThEOVZGWXQzMk0yR3NDVFJ1ZmZuWE1ocTFobycsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICd0ZXN0X3dhbGxldF9wYXNzcGhyYXNlJyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ1RZUGd4OE5mRHhCOHB5aXlUZWlNa1l6ZW0xZE5BNkcxMmknLFxuICAgICAgfSk7XG5cbiAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeVR4KTtcblxuICAgICAgcmVjb3ZlcnlUeC5jb2luLnNob3VsZC5lcXVhbCgndHRyeCcpO1xuICAgICAgcmVjb3ZlcnlUeC5mZWVJbmZvLmZlZS5zaG91bGQuZXF1YWwoJzIxMDAwMDAnKTtcbiAgICAgIHJlY292ZXJ5VHgucmVjb3ZlcnlBbW91bnQuc2hvdWxkLmVxdWFsKDg5OTA0NzQwMCk7XG4gICAgICByZWNvdmVyeVR4LnR4SGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJ3tcInZpc2libGVcIjpmYWxzZSxcInR4SURcIjpcIjk4YjM5OGUzMDI3ZTYwMTg3MGE4NmIwNzg1ZjFmMWQzMDFmMDg3ZGJhYWZlNDQzMzc1MDdiNTAwMWJhZTBkNDlcIixcInJhd19kYXRhXCI6e1wiY29udHJhY3RcIjpbe1wicGFyYW1ldGVyXCI6e1widmFsdWVcIjp7XCJhbW91bnRcIjoxMDAwMDAwMCxcIm93bmVyX2FkZHJlc3NcIjpcIjQxZTdlMTFkZjJjNTcwNDg4OGMzY2I2M2ZiNDNhOTQ5OGJkMTgxMmNiMlwiLFwidG9fYWRkcmVzc1wiOlwiNDFmNWY0MTRkNDQ3YWFmZTcwYmI5YjlkOTM5MTJjYmM0YzU0ZjBjMDE0XCJ9LFwidHlwZV91cmxcIjpcInR5cGUuZ29vZ2xlYXBpcy5jb20vcHJvdG9jb2wuVHJhbnNmZXJDb250cmFjdFwifSxcInR5cGVcIjpcIlRyYW5zZmVyQ29udHJhY3RcIn1dLFwicmVmX2Jsb2NrX2J5dGVzXCI6XCJhNzYyXCIsXCJyZWZfYmxvY2tfaGFzaFwiOlwiMThkZmU5NDZmYmY3YTBhY1wiLFwiZXhwaXJhdGlvblwiOjE2NzY3NDY0NDMwMDAsXCJ0aW1lc3RhbXBcIjoxNjc2NjU5OTgzNzk5fSxcInJhd19kYXRhX2hleFwiOlwiMGEwMmE3NjIyMjA4MThkZmU5NDZmYmY3YTBhYzQwZjg5MTgxYWZlNjMwNWE2OTA4MDExMjY1MGEyZDc0Nzk3MDY1MmU2NzZmNmY2NzZjNjU2MTcwNjk3MzJlNjM2ZjZkMmY3MDcyNmY3NDZmNjM2ZjZjMmU1NDcyNjE2ZTczNjY2NTcyNDM2ZjZlNzQ3MjYxNjM3NDEyMzQwYTE1NDFlN2UxMWRmMmM1NzA0ODg4YzNjYjYzZmI0M2E5NDk4YmQxODEyY2IyMTIxNTQxZjVmNDE0ZDQ0N2FhZmU3MGJiOWI5ZDkzOTEyY2JjNGM1NGYwYzAxNDE4YzhkMTljYWQwMzcwYjc4YmU0ODVlNjMwXCIsXCJzaWduYXR1cmVcIjpbXCI3OWExMTAxMTY2NTdlNzViZTgxNDAwYWQ0YTlmNzM4ZmQwOTg2OTVmYzVmYzYwMDkxNzZhYTFjMjc5MjRjNGNkYjI5ODlmZTIwNTJiNzBjNzM5YjEwY2QzODgxYzk4NzI2NjBiODM5OThkYzkzMTZlNmM4ZDExZmI1ODhkNzMxZDAwXCIsXCIyNTBkMGJhZTI0OTE1OTZiZDgwMGQ4MzBhYTlkNGM2ZDI1ZTFkMDFhNGM4NjBiODU2ZDYwMDBhOGFiOGZhMjA4MmExYWUyMDE2OGUwYWI5N2M5ZmZkNjQ4MjRiNDgzYjk4NDNkYjc0ZTk1NTNkNWQ5ZTY4YTNhNjRkNDE0ZGQxMjAxXCJdfSdcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4LnR4LnNpZ25hdHVyZVswXS5zaG91bGQuZXF1YWwoXG4gICAgICAgICc3OWExMTAxMTY2NTdlNzViZTgxNDAwYWQ0YTlmNzM4ZmQwOTg2OTVmYzVmYzYwMDkxNzZhYTFjMjc5MjRjNGNkYjI5ODlmZTIwNTJiNzBjNzM5YjEwY2QzODgxYzk4NzI2NjBiODM5OThkYzkzMTZlNmM4ZDExZmI1ODhkNzMxZDAwJ1xuICAgICAgKTtcbiAgICAgIHJlY292ZXJ5VHgudHguc2lnbmF0dXJlWzFdLnNob3VsZC5lcXVhbChcbiAgICAgICAgJzI1MGQwYmFlMjQ5MTU5NmJkODAwZDgzMGFhOWQ0YzZkMjVlMWQwMWE0Yzg2MGI4NTZkNjAwMGE4YWI4ZmEyMDgyYTFhZTIwMTY4ZTBhYjk3YzlmZmQ2NDgyNGI0ODNiOTg0M2RiNzRlOTU1M2Q1ZDllNjhhM2E2NGQ0MTRkZDEyMDEnXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeC50eC50eElELnNob3VsZC5lcXVhbCgnOThiMzk4ZTMwMjdlNjAxODcwYTg2YjA3ODVmMWYxZDMwMWYwODdkYmFhZmU0NDMzNzUwN2I1MDAxYmFlMGQ0OScpO1xuICAgICAgcmVjb3ZlcnlUeC50eC5yYXdfZGF0YV9oZXguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMGEwMmE3NjIyMjA4MThkZmU5NDZmYmY3YTBhYzQwZjg5MTgxYWZlNjMwNWE2OTA4MDExMjY1MGEyZDc0Nzk3MDY1MmU2NzZmNmY2NzZjNjU2MTcwNjk3MzJlNjM2ZjZkMmY3MDcyNmY3NDZmNjM2ZjZjMmU1NDcyNjE2ZTczNjY2NTcyNDM2ZjZlNzQ3MjYxNjM3NDEyMzQwYTE1NDFlN2UxMWRmMmM1NzA0ODg4YzNjYjYzZmI0M2E5NDk4YmQxODEyY2IyMTIxNTQxZjVmNDE0ZDQ0N2FhZmU3MGJiOWI5ZDkzOTEyY2JjNGM1NGYwYzAxNDE4YzhkMTljYWQwMzcwYjc4YmU0ODVlNjMwJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgcmVjb3ZlcnkgdHggZnJvbSBlbmNyeXB0ZWQgdXNlciBhbmQgYmFja3VwIGtleXMgZnJvbSBhIHJlY2VpdmUgYWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1Ryb25SZWNlaXZlUmVjb3ZlcnkoKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5VHggPSBhd2FpdCBiYXNlQ29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAne1wiaXZcIjpcImVYd1lJeWdEeVJ5MVIxbHc5RXdFZ1E9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJOTk94RitMUjdhVT1cIixcImN0XCI6XCJxWC9HK0FpWkozNVh3VW1MOWFsWWl0Und2WWdFL2JTMjREU0FWVjd0QmFvVHM0MHRzVkIva1d4K2hWL0o1YWNLSUE2Wi93U3VjeGJLclFsSkI2OXhKSmwvT2lyWXFtWFJCaXJIK3JhZzFhQzF6ajdaVm5iTytoK1A1R0hxSEpsdExjNFV5RGYrcDIyK05qb0RMZlIrZkVQdEc4YzR2NW89XCJ9JyxcbiAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICd7XCJpdlwiOlwiUWFvWENFa2libzRWTUV5bzNmU1VVUT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcImlxcXRyQnRDNXZZPVwiLFwiY3RcIjpcIkpIYkhKOFUyQWxhMmNSRmNvcVRBZnRMWW1ERFNPVGZoZFZtWmttVy9PUkplUDYwVmY1VDFtNjYxeVdRVDNBREtTc3EyQ1NSVjQ5T3FTZkgybElPQlUzRWZYZEZYa1dRZVROWCtiaHpDNkUyby91czNTbndsWGhPNjU5RFFNUG1MdGh2Z0NUWDh4TSs1VXpnVi9QWW5xRnBTdXhsMzc5cz1cIn0nLFxuICAgICAgICBiaXRnb0tleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0V4NnpLVEJyZ1prV1BCR3Z4OHFndUVkMU5xRURwNnlXM3NyQkdoVFVkRmtjZGNCanA1RlFnWGtETmlRQmRqNkZzZ2thOEQ5VkZZdDMyTTJHc0NUUnVmZm5YTWhxMWhvJyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ3Rlc3Rfd2FsbGV0X3Bhc3NwaHJhc2UnLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnVEViaGE5RmhRTVozRlJ0WmdvazhRQnVuUFFVNHBadkJ4WCcsXG4gICAgICB9KTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHJlY292ZXJ5VHgpO1xuXG4gICAgICByZWNvdmVyeVR4LmNvaW4uc2hvdWxkLmVxdWFsKCd0dHJ4Jyk7XG4gICAgICByZWNvdmVyeVR4LmZlZUluZm8uZmVlLnNob3VsZC5lcXVhbCgnMjEwMDAwMCcpO1xuICAgICAgcmVjb3ZlcnlUeC5yZWNvdmVyeUFtb3VudC5zaG91bGQuZXF1YWwoMTk3OTAwMDAwKTtcbiAgICAgIHJlY292ZXJ5VHguYWRkcmVzc0luZm8uYWRkcmVzcy5zaG91bGQuZXF1YWwoJ1ROZUdwd0F1cms3a2pRTGRjZFdoRnI4WVA4RTlaYTh3MXgnKTtcbiAgICAgIHJlY292ZXJ5VHguYWRkcmVzc0luZm8uY2hhaW4uc2hvdWxkLmVxdWFsKDApO1xuICAgICAgcmVjb3ZlcnlUeC5hZGRyZXNzSW5mby5pbmRleC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICByZWNvdmVyeVR4LnR4SGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJ3tcInZpc2libGVcIjpmYWxzZSxcInR4SURcIjpcImRhNjdlMzJlOWVhM2JkMDIyZjNkOTNlZDI1OTc3MWRkYTliNDQ0ZDQxZDFlNjNlNTRjODI1NGE2ZWJiNjMzMmZcIixcInJhd19kYXRhXCI6e1wiY29udHJhY3RcIjpbe1wicGFyYW1ldGVyXCI6e1widmFsdWVcIjp7XCJhbW91bnRcIjoxOTkwMDAwMDAsXCJvd25lcl9hZGRyZXNzXCI6XCI0MThiMDRlY2RjM2RiN2U4ZGE3Y2Q4Mzg0OTJmNjZlNDI0YTA1MWUyY2RcIixcInRvX2FkZHJlc3NcIjpcIjQxMzJjNzUzYmY4ZDNkZTczNTg3NDhhNzVmY2YyOTlmMTQ2ZGZmNmU0ZVwifSxcInR5cGVfdXJsXCI6XCJ0eXBlLmdvb2dsZWFwaXMuY29tL3Byb3RvY29sLlRyYW5zZmVyQ29udHJhY3RcIn0sXCJ0eXBlXCI6XCJUcmFuc2ZlckNvbnRyYWN0XCJ9XSxcInJlZl9ibG9ja19ieXRlc1wiOlwiODFlMFwiLFwicmVmX2Jsb2NrX2hhc2hcIjpcIjViMWIyMGU5ZWJlYWE0ZjhcIixcImV4cGlyYXRpb25cIjoxNjg2MDM4NjgyMDAwLFwidGltZXN0YW1wXCI6MTY4NTk1MjIyNDQ4M30sXCJyYXdfZGF0YV9oZXhcIjpcIjBhMDI4MWUwMjIwODViMWIyMGU5ZWJlYWE0Zjg0MDkwYjNmMmZkODgzMTVhNjgwODAxMTI2NDBhMmQ3NDc5NzA2NTJlNjc2ZjZmNjc2YzY1NjE3MDY5NzMyZTYzNmY2ZDJmNzA3MjZmNzQ2ZjYzNmY2YzJlNTQ3MjYxNmU3MzY2NjU3MjQzNmY2ZTc0NzI2MTYzNzQxMjMzMGExNTQxOGIwNGVjZGMzZGI3ZThkYTdjZDgzODQ5MmY2NmU0MjRhMDUxZTJjZDEyMTU0MTMyYzc1M2JmOGQzZGU3MzU4NzQ4YTc1ZmNmMjk5ZjE0NmRmZjZlNGUxOGMwZmZmMTVlNzBlM2I5ZDVkNDg4MzFcIixcInNpZ25hdHVyZVwiOltcIjk0YTMxY2RkNjRlOTNlMzc1YzNlZWJhZTVkYjRmNjY3NjFjYjQ5NTUwZjJjZWU5Mzg4YjYxOGU2ODM2YmM0NzFlY2YzM2UxNDEyMmQ2MjI0NDczNzM1OGUzM2E5ZDE0YTA1NmNlOGM3ZGMzNGRjZmNiOGVmMmRiMTVkNDBkODM2MDBcIl19J1xuICAgICAgKTtcbiAgICAgIHJlY292ZXJ5VHgudHguc2lnbmF0dXJlWzBdLnNob3VsZC5lcXVhbChcbiAgICAgICAgJzk0YTMxY2RkNjRlOTNlMzc1YzNlZWJhZTVkYjRmNjY3NjFjYjQ5NTUwZjJjZWU5Mzg4YjYxOGU2ODM2YmM0NzFlY2YzM2UxNDEyMmQ2MjI0NDczNzM1OGUzM2E5ZDE0YTA1NmNlOGM3ZGMzNGRjZmNiOGVmMmRiMTVkNDBkODM2MDAnXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeC50eC50eElELnNob3VsZC5lcXVhbCgnZGE2N2UzMmU5ZWEzYmQwMjJmM2Q5M2VkMjU5NzcxZGRhOWI0NDRkNDFkMWU2M2U1NGM4MjU0YTZlYmI2MzMyZicpO1xuICAgICAgcmVjb3ZlcnlUeC50eC5yYXdfZGF0YV9oZXguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMGEwMjgxZTAyMjA4NWIxYjIwZTllYmVhYTRmODQwOTBiM2YyZmQ4ODMxNWE2ODA4MDExMjY0MGEyZDc0Nzk3MDY1MmU2NzZmNmY2NzZjNjU2MTcwNjk3MzJlNjM2ZjZkMmY3MDcyNmY3NDZmNjM2ZjZjMmU1NDcyNjE2ZTczNjY2NTcyNDM2ZjZlNzQ3MjYxNjM3NDEyMzMwYTE1NDE4YjA0ZWNkYzNkYjdlOGRhN2NkODM4NDkyZjY2ZTQyNGEwNTFlMmNkMTIxNTQxMzJjNzUzYmY4ZDNkZTczNTg3NDhhNzVmY2YyOTlmMTQ2ZGZmNmU0ZTE4YzBmZmYxNWU3MGUzYjlkNWQ0ODgzMSdcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIHdoZW4gdGhlcmUgaXMgbm8gZnVuZHMgdG8gZmx1c2gnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tUcm9uUmVjZWl2ZVJlY292ZXJ5WmVyb0Z1bmRzKCk7XG4gICAgICBhd2FpdCBiYXNlQ29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAgICd7XCJpdlwiOlwiZVh3WUl5Z0R5UnkxUjFsdzlFd0VnUT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIk5OT3hGK0xSN2FVPVwiLFwiY3RcIjpcInFYL0crQWlaSjM1WHdVbUw5YWxZaXRSd3ZZZ0UvYlMyNERTQVZWN3RCYW9UczQwdHNWQi9rV3graFYvSjVhY0tJQTZaL3dTdWN4YktyUWxKQjY5eEpKbC9PaXJZcW1YUkJpckgrcmFnMWFDMXpqN1pWbmJPK2grUDVHSHFISmx0TGM0VXlEZitwMjIrTmpvRExmUitmRVB0RzhjNHY1bz1cIn0nLFxuICAgICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAgICd7XCJpdlwiOlwiUWFvWENFa2libzRWTUV5bzNmU1VVUT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcImlxcXRyQnRDNXZZPVwiLFwiY3RcIjpcIkpIYkhKOFUyQWxhMmNSRmNvcVRBZnRMWW1ERFNPVGZoZFZtWmttVy9PUkplUDYwVmY1VDFtNjYxeVdRVDNBREtTc3EyQ1NSVjQ5T3FTZkgybElPQlUzRWZYZEZYa1dRZVROWCtiaHpDNkUyby91czNTbndsWGhPNjU5RFFNUG1MdGh2Z0NUWDh4TSs1VXpnVi9QWW5xRnBTdXhsMzc5cz1cIn0nLFxuICAgICAgICAgIGJpdGdvS2V5OlxuICAgICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNFeDZ6S1RCcmdaa1dQQkd2eDhxZ3VFZDFOcUVEcDZ5VzNzckJHaFRVZEZrY2RjQmpwNUZRZ1hrRE5pUUJkajZGc2drYThEOVZGWXQzMk0yR3NDVFJ1ZmZuWE1ocTFobycsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogJ3Rlc3Rfd2FsbGV0X3Bhc3NwaHJhc2UnLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdURWJoYTlGaFFNWjNGUnRaZ29rOFFCdW5QUVU0cFp2QnhYJyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgXCJBbW91bnQgb2YgZnVuZHMgdG8gcmVjb3ZlciB1bmRlZmluZWQgaXMgbGVzcyB0aGFuIDIxMDAwMDAgYW5kIHdvdWxkbid0IGJlIGFibGUgdG8gZnVuZCBhIHNlbmRcIlxuICAgICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSByZWNvdmVyeSB0eCB3aXRoIHVuZW5jcnlwdGVkIGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tUcm9uUmVjb3ZlcnkoKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5VHggPSBhd2FpdCBiYXNlQ29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0dLTjNVeFJxd0tkVk5SYkp2cXhpTmFXQkNmWGNVSmFFZjU2d3FSc0dSNlI3dG1XcnBuamJkUUxyeWI2aHp4OFJmWFhzdlJxQnVCMmlkR2cxTmVEMXl1ZVdjc0JvcTdBJyxcbiAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjRjViOWZKQWZKcDZQOXAyTG1lWlY3WWJmZ0RrdHRHSnJHZG1MdHNMeHlIVFFhb1BFMXBKcjVFQTdTQndNU3pGbXYyVHZzREx0RzQyRmVlc3lhVlFhekJYNFltRDI4YmgnLFxuICAgICAgICBiaXRnb0tleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0V4NnpLVEJyZ1prV1BCR3Z4OHFndUVkMU5xRURwNnlXM3NyQkdoVFVkRmtjZGNCanA1RlFnWGtETmlRQmRqNkZzZ2thOEQ5VkZZdDMyTTJHc0NUUnVmZm5YTWhxMWhvJyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ1RZUGd4OE5mRHhCOHB5aXlUZWlNa1l6ZW0xZE5BNkcxMmknLFxuICAgICAgfSk7XG5cbiAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeVR4KTtcblxuICAgICAgcmVjb3ZlcnlUeC5jb2luLnNob3VsZC5lcXVhbCgndHRyeCcpO1xuICAgICAgcmVjb3ZlcnlUeC5mZWVJbmZvLmZlZS5zaG91bGQuZXF1YWwoJzIxMDAwMDAnKTtcbiAgICAgIHJlY292ZXJ5VHgucmVjb3ZlcnlBbW91bnQuc2hvdWxkLmVxdWFsKDg5OTA0NzQwMCk7XG4gICAgICByZWNvdmVyeVR4LnR4LnR4SUQuc2hvdWxkLmVxdWFsKCc5OGIzOThlMzAyN2U2MDE4NzBhODZiMDc4NWYxZjFkMzAxZjA4N2RiYWFmZTQ0MzM3NTA3YjUwMDFiYWUwZDQ5Jyk7XG4gICAgICByZWNvdmVyeVR4LnR4LnJhd19kYXRhX2hleC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwYTAyYTc2MjIyMDgxOGRmZTk0NmZiZjdhMGFjNDBmODkxODFhZmU2MzA1YTY5MDgwMTEyNjUwYTJkNzQ3OTcwNjUyZTY3NmY2ZjY3NmM2NTYxNzA2OTczMmU2MzZmNmQyZjcwNzI2Zjc0NmY2MzZmNmMyZTU0NzI2MTZlNzM2NjY1NzI0MzZmNmU3NDcyNjE2Mzc0MTIzNDBhMTU0MWU3ZTExZGYyYzU3MDQ4ODhjM2NiNjNmYjQzYTk0OThiZDE4MTJjYjIxMjE1NDFmNWY0MTRkNDQ3YWFmZTcwYmI5YjlkOTM5MTJjYmM0YzU0ZjBjMDE0MThjOGQxOWNhZDAzNzBiNzhiZTQ4NWU2MzAnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiB1bnNpZ25lZCBzd2VlcCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1Ryb25SZWNvdmVyeSgpO1xuICAgICAgY29uc3QgcmVjb3ZlcnlUeCA9IGF3YWl0IGJhc2VDb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICd7XCJpdlwiOlwiZVh3WUl5Z0R5UnkxUjFsdzlFd0VnUT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIk5OT3hGK0xSN2FVPVwiLFwiY3RcIjpcInFYL0crQWlaSjM1WHdVbUw5YWxZaXRSd3ZZZ0UvYlMyNERTQVZWN3RCYW9UczQwdHNWQi9rV3graFYvSjVhY0tJQTZaL3dTdWN4YktyUWxKQjY5eEpKbC9PaXJZcW1YUkJpckgrcmFnMWFDMXpqN1pWbmJPK2grUDVHSHFISmx0TGM0VXlEZitwMjIrTmpvRExmUitmRVB0RzhjNHY1bz1cIn0nLFxuICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNGNWI5ZkpBZkpwNlA5cDJMbWVaVjdZYmZnRGt0dEdKckdkbUx0c0x4eUhUUWFvUEUxcEpyNUVBN1NCd01TekZtdjJUdnNETHRHNDJGZWVzeWFWUWF6Qlg0WW1EMjhiaCcsXG4gICAgICAgIGJpdGdvS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjRXg2ektUQnJnWmtXUEJHdng4cWd1RWQxTnFFRHA2eVczc3JCR2hUVWRGa2NkY0JqcDVGUWdYa0ROaVFCZGo2RnNna2E4RDlWRll0MzJNMkdzQ1RSdWZmblhNaHExaG8nLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAndGVzdF93YWxsZXRfcGFzc3BocmFzZScsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdUWVBneDhOZkR4QjhweWl5VGVpTWtZemVtMWROQTZHMTJpJyxcbiAgICAgIH0pO1xuXG4gICAgICBzaG91bGQuZXhpc3QocmVjb3ZlcnlUeCk7XG5cbiAgICAgIHJlY292ZXJ5VHguY29pbi5zaG91bGQuZXF1YWwoJ3R0cngnKTtcbiAgICAgIHJlY292ZXJ5VHguZmVlSW5mby5mZWUuc2hvdWxkLmVxdWFsKCcyMTAwMDAwJyk7XG4gICAgICByZWNvdmVyeVR4LnJlY292ZXJ5QW1vdW50LnNob3VsZC5lcXVhbCg4OTkwNDc0MDApO1xuICAgICAgcmVjb3ZlcnlUeC50eC50eElELnNob3VsZC5lcXVhbCgnOThiMzk4ZTMwMjdlNjAxODcwYTg2YjA3ODVmMWYxZDMwMWYwODdkYmFhZmU0NDMzNzUwN2I1MDAxYmFlMGQ0OScpO1xuICAgICAgcmVjb3ZlcnlUeC50eC5yYXdfZGF0YV9oZXguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMGEwMmE3NjIyMjA4MThkZmU5NDZmYmY3YTBhYzQwZjg5MTgxYWZlNjMwNWE2OTA4MDExMjY1MGEyZDc0Nzk3MDY1MmU2NzZmNmY2NzZjNjU2MTcwNjk3MzJlNjM2ZjZkMmY3MDcyNmY3NDZmNjM2ZjZjMmU1NDcyNjE2ZTczNjY2NTcyNDM2ZjZlNzQ3MjYxNjM3NDEyMzQwYTE1NDFlN2UxMWRmMmM1NzA0ODg4YzNjYjYzZmI0M2E5NDk4YmQxODEyY2IyMTIxNTQxZjVmNDE0ZDQ0N2FhZmU3MGJiOWI5ZDkzOTEyY2JjNGM1NGYwYzAxNDE4YzhkMTljYWQwMzcwYjc4YmU0ODVlNjMwJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYSB0b2tlbiByZWNvdmVyeSB0eCBmcm9tIGVuY3J5cHRlZCB1c2VyIGFuZCBiYWNrdXAga2V5cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja1Ryb25Ub2tlblJlY292ZXJ5KCk7XG4gICAgICBjb25zdCByZWNvdmVyeVR4ID0gYXdhaXQgYmFzZUNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgJ3tcIml2XCI6XCJSeWpUVjRCMDl0UVQ1NzZqQU0ybkxnPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwibkpkdG1lY0hOTUU9XCIsXCJjdFwiOlwiNXJDZWloTzNwWm1kK3ZNWVN0UDBmMHpMYkprSGhkdmF4KzZaQXI1UjRWbXZqSm5RcVdqS2t6NGlxVjJGMWRTWlZ6TlRVOTdoSGpaRTVkM0RwSmh5N3JGc0ZGSUZWdXRqT1JTWnY4V25yMGc5OVhPaUVEYnVERU5FMkJReVRrT3pTWUxMR0lpNzFteXV3Z0FqQnVRTW9tazArN2d0ZmpZPVwifScsXG4gICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAne1wiaXZcIjpcInZuYnp4M1luU1JIUk1VbkVPVG1ITHc9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCIyRDMyZU1PZ2taYz1cIixcImN0XCI6XCJ5S1Awam5Sa3YvWG5NSFA2bUpNUUdvenZ0a2tpSEpwWXhENm8xbjdGY040NG9PSkhvUUFJMHhyZXc3V3lHVHpPcHpvQTBFMEJIMDBBYmk5WElOTm5RNUxMZ0pSZElGMEhiSnhma2oxUXZFbGNrTUg5NERNeG4xNHM5Y1lRZ0lrSTY3NnZod0ZCaEFBd3ZiTjg0NTh3cXRYc2wrMExucnM9XCJ9JyxcbiAgICAgICAgYml0Z29LZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNHWXE5UnRXWXpLdXZxYmEyRUhyOXZBa0RiUHNOaTFMOVRtaUhTUlVYSHF4ZTE4UDRESFh0REZ0VXk0U2I5YmhwU2hIRVdXOWgzTHdITTliQjJxb1AyY3dXVGR1VjluUCcsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICd0ZXN0X3dhbGxldF9wYXNzcGhyYXNlJyxcbiAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6ICdURzNYWHlFeEJrUHA5bnpkYWpEWnNvekV1NEJrYVNKb3pzJyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJ1RZUGd4OE5mRHhCOHB5aXlUZWlNa1l6ZW0xZE5BNkcxMmknLFxuICAgICAgfSk7XG5cbiAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeVR4KTtcblxuICAgICAgcmVjb3ZlcnlUeC50eC5zaWduYXR1cmVbMF0uc2hvdWxkLmVxdWFsKFxuICAgICAgICAnM2E2N2VlZTdhZTA2N2NkODVjYWU4NjUzMGJlMzM4YWYyY2ZmNDAzNGEzMGYzOTY1NmUyZDgxMTdmZjc5MTVhZDI1NjE3NmFmY2ZiZTgxNzdjNDE5NWVhODg3ZDc5NzQwNDIwYjEyZjllYTdjNTY5OGE2ZDJlZWVjMjYwZjM0ZGYwMSdcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4LnR4LnNpZ25hdHVyZVsxXS5zaG91bGQuZXF1YWwoXG4gICAgICAgICc1NTFkNDFlMDA3YjhiMzZiMmFjNTAyOTdmZDUzNjc4ZjE5NjA2Nzg0ODczMWY0MzQwZjdlZTBlYjZkOTYzYzI0YjExZGRlOTY3MjdmM2NmNGQwNTFhZjU4Njg2OWRhYTUxMzk0ZGIwODUzZTZkNGM4MGU0MWZlZTQxNGE5Yzk1MjAxJ1xuICAgICAgKTtcbiAgICAgIHJlY292ZXJ5VHgudHgudHhJRC5zaG91bGQuZXF1YWwoJzI4MTE3ZDlmMGMzYWMxZmUyMmZhMmNiMTA0MTI1Mzc3NjNmZWE4YWQ2YjRiOGQwNTA0ZDhmMjVjNjE0MWY0M2MnKTtcbiAgICAgIHJlY292ZXJ5VHgudHgucmF3X2RhdGFfaGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzBhMDJhNzFjMjIwOGQwZWNiNTNhYTAzODgyYTY0MGQ4OWNmM2FlZTYzMDVhYWUwMTA4MWYxMmE5MDEwYTMxNzQ3OTcwNjUyZTY3NmY2ZjY3NmM2NTYxNzA2OTczMmU2MzZmNmQyZjcwNzI2Zjc0NmY2MzZmNmMyZTU0NzI2OTY3Njc2NTcyNTM2ZDYxNzI3NDQzNmY2ZTc0NzI2MTYzNzQxMjc0MGExNTQxNmEwYTA1ZTA5OGM2MjhmN2YzY2E2M2RiYjU3NTZlNWMwYzAxODUyMTEyMTU0MTQyYTFlMzlhZWZhNDkyOTBmMmIzZjllZDY4OGQ3Y2VjZjg2Y2Q2ZTAyMjQ0YTkwNTljYmIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBmNWY0MTRkNDQ3YWFmZTcwYmI5YjlkOTM5MTJjYmM0YzU0ZjBjMDE0MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEyNDEwMTEwMDcwYTJhOWQ2ODVlNjMwOTAwMTgwYzJkNzJmJ1xuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXIgRU9TJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBiYXNlQ29pbjtcbiAgICBjb25zdCBleHBlY3RlZFBhY2tlZFRyeCA9XG4gICAgICAnNzEyMjMxNWQ1ZTkxZDQwOGUxYjMwMDAwMDAwMDAxMDBhNjgyMzQwM2VhMzA1NTAwMDAwMDU3MmQzY2NkY2QwMTUwZjNlYTJlNGNmNGJjODMwMDAwMDAwMGE4ZWQzMjMyMjE1MGYzZWEyZTRjZjRiYzgzZTBmMjdjMjdjYzBhZGY3ZjQwNDIwZjAwMDAwMDAwMDAwNDQ1NGY1MzAwMDAwMDAwMDAwMCc7XG4gICAgY29uc3QgZXhwZWN0ZWRUeElkID0gJzk5YzZhNGVlZGY1Y2ZmMjQ2MzE0YmRjMGEwNTNjMTJkNzU0ODhkZjNhYTA5NDc0YmFkNGNlY2E4OGQ4YjI0OTgnO1xuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICBiYXNlQ29pbiA9IGJpdGdvLmNvaW4oJ3Rlb3MnKTtcbiAgICB9KTtcbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0Vvc1JlY292ZXJ5KCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIEVPUyByZWNvdmVyeSB0eCB3aXRoIGNvcnJlY3QgZXhwaXJhdGlvbiBkYXRlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVjb3ZlcnlUeCA9IGF3YWl0IGJhc2VDb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICd7XCJpdlwiOlwialJCWmk0M2M3dDR0dng3U2dQOGgwZz09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIjpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcIlRnWnFIdFpybUxVPVwiLFwiY3RcIjpcImhSbnR6cmJjSDgxZE96bHlyNDluYkFJSmRIV3FFS0tWSngwczU1a05WK2ZxVWpLS29FdVdxVkdGMWRQZlFra1RrY0lqRlROdnVIc2lHaWNWR1NSZjVSSTNRMFpENll0Q3FPMmJXWDZ0N0hnQmlvNXlZTWFQeStjTkpIbXA2akhCUUZaOWNDanF3QWFtL1YrMW1SdnBKcG4yZFNXUG90dz1cIn0nLFxuICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgJ3tcIml2XCI6XCJxRStEK0M2S1hhWktGWFhUTS9BRjV3PT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiYS9ZRDcvOGdKRnc9XCIsXCJjdFwiOlwidGMyYzFQZlNqRFM5VHNoWEVJS0tsVG9EY2RDZUw0NWZwR1VXRVBJTTIrNkNydkl1YVhaQzYvSHg5YnphN1ZJb0VQaEpXSG1ndm9lQW91dG80UFVwbnlLSlV1eitUNDZSWTA5WEpzMnJjRHZiZk1LYmxSc2g2bHpVYzhPN3ViVHpKUk5nRk9VcWtaTTZxR0IyMkEwRnRMOHlObEZxYzNjPVwifScsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFLFxuICAgICAgICByb290QWRkcmVzczogJ2tpeWpjbjFpeGZ0cCcsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdqemprcG4xYmpudGknLFxuICAgICAgfSk7XG5cbiAgICAgIHJlY292ZXJ5VHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9uJyk7XG4gICAgICByZWNvdmVyeVR4LnRyYW5zYWN0aW9uLmNvbXByZXNzaW9uLnNob3VsZC5lcXVhbCgnbm9uZScpO1xuICAgICAgcmVjb3ZlcnlUeC50cmFuc2FjdGlvbi5wYWNrZWRfdHJ4LnNob3VsZC5lcXVhbChleHBlY3RlZFBhY2tlZFRyeCk7XG4gICAgICByZWNvdmVyeVR4LnRyYW5zYWN0aW9uLnNpZ25hdHVyZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIHJlY292ZXJ5VHgudHhpZC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRUeElkKTtcblxuICAgICAgY29uc3QgZGVzZXJpYWxpemVUcmFuc2FjdGlvblBhcmFtcyA9IHtcbiAgICAgICAgdHJhbnNhY3Rpb246IHtcbiAgICAgICAgICBwYWNrZWRfdHJ4OiByZWNvdmVyeVR4LnRyYW5zYWN0aW9uLnBhY2tlZF90cngsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBkZXNlcmlhbGl6ZWRUeCA9IGF3YWl0IGJhc2VDb2luLmRlc2VyaWFsaXplVHJhbnNhY3Rpb24oZGVzZXJpYWxpemVUcmFuc2FjdGlvblBhcmFtcyk7XG4gICAgICBjb25zdCBtb2NrZWRIZWFkQmxvY2tUaW1lID0gJzIwMTktMDctMThUMTc6NTI6NDkuMDAwJztcbiAgICAgIGNvbnN0IGhvdXJzVW50aWxFeHBpcmF0aW9uID0gODtcbiAgICAgIGNvbnN0IGhvdXJEaWZmID0gKG5ldyBEYXRlKGRlc2VyaWFsaXplZFR4LmV4cGlyYXRpb24pLmdldFRpbWUoKSAtIG5ldyBEYXRlKG1vY2tlZEhlYWRCbG9ja1RpbWUpLmdldFRpbWUoKSkgLyAzNmU1O1xuICAgICAgaG91ckRpZmYuc2hvdWxkLmVxdWFsKGhvdXJzVW50aWxFeHBpcmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgRU9TIHJlY292ZXJ5IHR4IHdpdGggdW5lbmNyeXB0ZWQga2V5cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlY292ZXJ5VHggPSBhd2FpdCBiYXNlQ29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHBydjlzMjFaclFIMTQzSzRORGduS0g4elRUTHBKdUNtdjZkdHlrUkp3YXBCSDczYnZjdlR2Q1FBTW1RTHhSR3FnNVlidlhCTjVWR0QzeTJjUEdVR3lyVmNqV0RKTTU3M1JWc2VIZzRvTDY0QVh4JyxcbiAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICd4cHJ2OXMyMVpyUUgxNDNLNEdoM3NuWDh6NWQyNGRqRVZ3Q3dWd2RIR0Vzc1VwS3dIcUtEdEF6OGdSUHc3RmkxMk5DM3VyOTRDc0oyS29ybXVuUVFtM2dOa1hRaVR5NTM0TmRmdVE0QzJFcGRtUnAnLFxuICAgICAgICByb290QWRkcmVzczogJ2tpeWpjbjFpeGZ0cCcsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdqemprcG4xYmpudGknLFxuICAgICAgfSk7XG5cbiAgICAgIHJlY292ZXJ5VHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9uJyk7XG4gICAgICByZWNvdmVyeVR4LnRyYW5zYWN0aW9uLmNvbXByZXNzaW9uLnNob3VsZC5lcXVhbCgnbm9uZScpO1xuICAgICAgcmVjb3ZlcnlUeC50cmFuc2FjdGlvbi5wYWNrZWRfdHJ4LnNob3VsZC5lcXVhbChleHBlY3RlZFBhY2tlZFRyeCk7XG4gICAgICByZWNvdmVyeVR4LnRyYW5zYWN0aW9uLnNpZ25hdHVyZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIHJlY292ZXJ5VHgudHhpZC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRUeElkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gRU9TIHVuc2lnbmVkIHN3ZWVwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVjb3ZlcnlUeCA9IGF3YWl0IGJhc2VDb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjR3JKOXRMcDlNYlE1TkxqaEJOcFZHQ2cyN0t6UmpjZTJVaXg1MVRXZWlBNXRDRHlCRkhFTm1LU2Y2QmlXZzN0QWpZZ3JoVHo5YlpHZFhqN3Bma3NYYUVwVkxRcXpZRUUnLFxuICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNHa21XeXA0OU1EWmtjZlppdVB2bnNBWXQ0ZEhWMzlydkFkZU5SaUpQRURpUXhZVE5yYkZFSEpWQkpXQmR4VzdEZ0NxUlV5VnBZQWJUM0Q2TEdzWnB5bllwTUZBZ0FacicsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFLFxuICAgICAgICByb290QWRkcmVzczogJ2tpeWpjbjFpeGZ0cCcsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246ICdqemprcG4xYmpudGknLFxuICAgICAgfSk7XG5cbiAgICAgIHJlY292ZXJ5VHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3RyYW5zYWN0aW9uJyk7XG4gICAgICByZWNvdmVyeVR4LnRyYW5zYWN0aW9uLmNvbXByZXNzaW9uLnNob3VsZC5lcXVhbCgnbm9uZScpO1xuICAgICAgcmVjb3ZlcnlUeC50cmFuc2FjdGlvbi5wYWNrZWRfdHJ4LnNob3VsZC5lcXVhbChleHBlY3RlZFBhY2tlZFRyeCk7XG4gICAgICByZWNvdmVyeVR4LnRyYW5zYWN0aW9uLnNpZ25hdHVyZXMubGVuZ3RoLnNob3VsZC5lcXVhbCgwKTtcbiAgICAgIHJlY292ZXJ5VHgudHhpZC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRUeElkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXIgRVJDMjAnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBzdWNjZXNzZnVsbHkgY29uc3RydWN0IGEgcmVjb3ZlcnkgdHJhbnNhY3Rpb24gZm9yIHRva2VucyBzdHVjayBpbiBhIHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldCA9IGJpdGdvLm5vY2tFdGhXYWxsZXQoKTtcblxuICAgICAgLy8gVGhlcmUgc2hvdWxkIGJlIDI0IFBvdGF0b2tlbnMgc3R1Y2sgaW4gb3VyIHRlc3Qgd2FsbGV0IChiYXNlZCBvbiBub2NrKVxuICAgICAgY29uc3QgdHggPSBhd2FpdCB3YWxsZXQucmVjb3ZlclRva2VuKHtcbiAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6IFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX0FERFJFU1MsXG4gICAgICAgIHJlY2lwaWVudDogVGVzdEJpdEdvLlYyLlRFU1RfRVJDMjBfVE9LRU5fUkVDSVBJRU5ULFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX1BBU1NQSFJBU0UsXG4gICAgICB9KTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHR4KTtcbiAgICAgIHR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdoYWxmU2lnbmVkJyk7XG5cbiAgICAgIGNvbnN0IHR4SW5mbyA9IHR4LmhhbGZTaWduZWQ7XG4gICAgICB0eEluZm8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvbnRyYWN0U2VxdWVuY2VJZCcpO1xuICAgICAgdHhJbmZvLmNvbnRyYWN0U2VxdWVuY2VJZC5zaG91bGQuZXF1YWwoMTEwMSk7XG4gICAgICB0eEluZm8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2V4cGlyZVRpbWUnKTtcbiAgICAgIHR4SW5mby5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZ2FzTGltaXQnKTtcbiAgICAgIHR4SW5mby5nYXNMaW1pdC5zaG91bGQuZXF1YWwoNTAwMDAwKTtcbiAgICAgIHR4SW5mby5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZ2FzUHJpY2UnKTtcbiAgICAgIHR4SW5mby5nYXNQcmljZS5zaG91bGQuZXF1YWwoMjAwMDAwMDAwMDApO1xuICAgICAgdHhJbmZvLnNob3VsZC5oYXZlLnByb3BlcnR5KCdvcGVyYXRpb25IYXNoJyk7XG4gICAgICB0eEluZm8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NpZ25hdHVyZScpO1xuICAgICAgdHhJbmZvLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0b2tlbkNvbnRyYWN0QWRkcmVzcycpO1xuICAgICAgdHhJbmZvLnRva2VuQ29udHJhY3RBZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FUkMyMF9UT0tFTl9BRERSRVNTKTtcbiAgICAgIHR4SW5mby5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0SWQnKTtcbiAgICAgIHR4SW5mby53YWxsZXRJZC5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9JRCk7XG4gICAgICB0eEluZm8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudCcpO1xuICAgICAgdHhJbmZvLnJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYWRkcmVzcycpO1xuICAgICAgdHhJbmZvLnJlY2lwaWVudC5hZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FUkMyMF9UT0tFTl9SRUNJUElFTlQpO1xuICAgICAgdHhJbmZvLnJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYW1vdW50Jyk7XG4gICAgICB0eEluZm8ucmVjaXBpZW50LmFtb3VudC5zaG91bGQuZXF1YWwoJzI0MDAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VjY2Vzc2Z1bGx5IGdlbmVyYXRlIGFuIEVSQzIwIHVuc2lnbmVkIHN3ZWVwJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0ZGFpJyk7XG5cbiAgICAgIC8vIFRoZXJlIHNob3VsZCBiZSAxIFREQUkgdG9rZW4gaW4gb3VyIHRlc3Qgd2FsbGV0IChiYXNlZCBvbiBub2NrKVxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0ZYRGNXRDJ2eHVlYmNUMVpwVEY0VmtlNnFtTVc4eXpkZHdOWXBBUGp2WUVFTDVqTGZ5WVhXMmZ1eHRBeFk4VGdqUFVKTGNmMUM4cXo5TjZWZ1p4QXJLWDRFd0I4ckg1JyxcbiAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjR2hTYVhpa3B1VEM5S1U4OFh4OUxyaktTdzFKS3N2WE5nYWJwVGRnank3TFNvdmg5WkhoY3FoQUhRdTd1dGh1N0ZndU5HZGNDNGFYVEtLNWdxVGNQZTRXdkxZUmJDU0cnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyxcbiAgICAgICAgdG9rZW5Db250cmFjdEFkZHJlc3M6IFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX0FERFJFU1MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX1JFQ0lQSUVOVCxcbiAgICAgIH0pO1xuICAgICAgc2hvdWxkLmV4aXN0KHRyYW5zYWN0aW9uKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuXG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29udHJhY3RTZXF1ZW5jZUlkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZXhwaXJlVGltZScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc1ByaWNlJyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNQcmljZS5zaG91bGQuZXF1YWwoJzIwMDAwMDAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndG9rZW5Db250cmFjdEFkZHJlc3MnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnRva2VuQ29udHJhY3RBZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9UREFJX1RPS0VOX0FERFJFU1MpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvbnRyYWN0QWRkcmVzcycpO1xuICAgICAgdHJhbnNhY3Rpb24ud2FsbGV0Q29udHJhY3RBZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudCcpO1xuICAgICAgdHJhbnNhY3Rpb24ucmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi5yZWNpcGllbnQuYWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVJDMjBfVE9LRU5fUkVDSVBJRU5UKTtcbiAgICAgIHRyYW5zYWN0aW9uLnJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYW1vdW50Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5yZWNpcGllbnQuYW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAwMDAwMDAwMDAwMDAwMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgdXNlciBwcm92aWRlZCBnYXMgcGFyYW1zIHdoZW4gYnVpbGRpbmcgcmVjb3ZlcnkgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tFdGhMaWtlUmVjb3ZlcnkoYml0Z28pO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RkYWknKTtcblxuICAgICAgLy8gVGhlcmUgc2hvdWxkIGJlIDEgVERBSSB0b2tlbiBpbiBvdXIgdGVzdCB3YWxsZXQgKGJhc2VkIG9uIG5vY2spXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjRlhEY1dEMnZ4dWViY1QxWnBURjRWa2U2cW1NVzh5emRkd05ZcEFQanZZRUVMNWpMZnlZWFcyZnV4dEF4WThUZ2pQVUpMY2YxQzhxejlONlZnWnhBcktYNEV3QjhySDUnLFxuICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNHaFNhWGlrcHVUQzlLVTg4WHg5THJqS1N3MUpLc3ZYTmdhYnBUZGdqeTdMU292aDlaSGhjcWhBSFF1N3V0aHU3Rmd1TkdkY0M0YVhUS0s1Z3FUY1BlNFd2TFlSYkNTRycsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTLFxuICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogVGVzdEJpdEdvLlYyLlRFU1RfRVJDMjBfVE9LRU5fQUREUkVTUyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogVGVzdEJpdEdvLlYyLlRFU1RfRVJDMjBfVE9LRU5fUkVDSVBJRU5ULFxuICAgICAgICBnYXNMaW1pdDogJzQwMDAwMCcsXG4gICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6ICcxMDAwMDAwMDAwMCcsXG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6ICc1MDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgc2hvdWxkLmV4aXN0KHRyYW5zYWN0aW9uKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuXG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29udHJhY3RTZXF1ZW5jZUlkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZXhwaXJlVGltZScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZWlwMTU1OScpO1xuICAgICAgdHJhbnNhY3Rpb24uZ2FzTGltaXQuc2hvdWxkLmVxdWFsKCc0MDAwMDAnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdnYXNQcmljZScpO1xuICAgICAgdHJhbnNhY3Rpb24uZ2FzUHJpY2Uuc2hvdWxkLmVxdWFsKCcxMDAwMDAwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3Rva2VuQ29udHJhY3RBZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi50b2tlbkNvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfVERBSV9UT0tFTl9BRERSRVNTKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb250cmFjdEFkZHJlc3MnKTtcbiAgICAgIHRyYW5zYWN0aW9uLndhbGxldENvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYWRkcmVzcycpO1xuICAgICAgdHJhbnNhY3Rpb24ucmVjaXBpZW50LmFkZHJlc3Muc2hvdWxkLmVxdWFsKFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX1JFQ0lQSUVOVCk7XG4gICAgICB0cmFuc2FjdGlvbi5yZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Ftb3VudCcpO1xuICAgICAgdHJhbnNhY3Rpb24ucmVjaXBpZW50LmFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwMDAwMDAwMDAwMDAwMDAnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FQSSBLZXkgdXNhZ2UgaW4gcmVjb3ZlcnknLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGJhc2Vjb2luO1xuICAgIGxldCBzYW5kYm94O1xuXG4gICAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKTtcbiAgICAgIHNhbmRib3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZGJveC5yZXN0b3JlKCk7XG4gICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnRXRoIFJlY292ZXJ5IG92ZXJyaWRlcyBlbnYgZXRoZXJzY2FuIGFwaSBrZXkgaWYgcHJvdmlkZWQgJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY3VzdG9tQXBpS2V5ID0gJ2N1c3RvbS1rZXknOyAvLyBDdXN0b20gQVBJIGtleSBmb3IgZXRoZXJzY2FuXG4gICAgICBjb25zdCByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0ZqSFc5UXYyd0NHZWhNaVFYWVB1TEtHZEpSeDlMOXF2YUdRZk03ckNqdlcxTVFXWm1pMWFyR0s5UE42elB0a1V2aThnM29OVGtnUjJkTmc4SGpHWVc4MWptNjhzQ0N5JyxcbiAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICd4cHViNjYxTXlNd0FxUmJjR1RLY2pCeVE3bkZKQmlVQldRUEtVRXdzVVpudzU4UlM1ZWZjdWpVU3hyUXhqZFJuMVJwNURHelJQOHJrenF0SGRVdkpNSDlZMnp2U1Y1SmpzYUJwRktXQndqVHJNeUMnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6ICcweGZmMTY5NjgyYmZkZTViODExYmE5MGE2MWFlYTM5YmVkZDc4YzJmNzUnLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnMHgzM2U2YjRkZDYwYTkxN2QyNDE3MGViOTZkNWViMjVmYTIyNzdhOTJmJyxcbiAgICAgICAgaXNVbnNpZ25lZFN3ZWVwOiB0cnVlLFxuICAgICAgICBhcGlLZXk6IGN1c3RvbUFwaUtleSxcbiAgICAgIH07XG5cbiAgICAgIC8vIENyZWF0ZSBzcHkgb24gcXVlcnlBZGRyZXNzQmFsYW5jZSB0byB2ZXJpZnkgYXBpS2V5IHVzYWdlXG4gICAgICBjb25zdCBxdWVyeUFkZHJlc3NCYWxhbmNlU3B5ID0gc2FuZGJveC5zcHkoYmFzZWNvaW4sICdxdWVyeUFkZHJlc3NCYWxhbmNlJyk7XG4gICAgICBjb25zdCBnZXRBZGRyZXNzTm9uY2VTcHkgPSBzYW5kYm94LnNweShiYXNlY29pbiwgJ2dldEFkZHJlc3NOb25jZScpO1xuICAgICAgY29uc3QgcXVlcnlTZXF1ZW5jZUlkU3B5ID0gc2FuZGJveC5zcHkoYmFzZWNvaW4sICdxdWVyeVNlcXVlbmNlSWQnKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5QmxvY2tjaGFpbkV4cGxvcmVyUXVlcnlTcHkgPSBzYW5kYm94LnNweShiYXNlY29pbiwgJ3JlY292ZXJ5QmxvY2tjaGFpbkV4cGxvcmVyUXVlcnknKTtcblxuICAgICAgbm9jaygnaHR0cHM6Ly9hcGkuZXRoZXJzY2FuLmlvJylcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeSgoYWN0dWFsKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGFjdHVhbC5tb2R1bGUgPT09ICdhY2NvdW50JyAmJiBhY3R1YWwuYWN0aW9uID09PSAndHhsaXN0JyAmJiBhY3R1YWwuYXBpa2V5ID09PSBjdXN0b21BcGlLZXk7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBzdGF0dXM6ICcxJyxcbiAgICAgICAgICBtZXNzYWdlOiAnT0snLFxuICAgICAgICAgIHJlc3VsdDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBibG9ja051bWJlcjogJzExMjUzNTYnLFxuICAgICAgICAgICAgICB0aW1lU3RhbXA6ICcxNzEwMjUyMDM2JyxcbiAgICAgICAgICAgICAgaGFzaDogJzB4MDFiMDY0MmM4NTI1OTJhNzcyNDk1YjhiM2I0ZmJkMjAzYzViMDE0MjU3OTgwMWUxYzIyM2ZlODY3MDAxNzRjMicsXG4gICAgICAgICAgICAgIG5vbmNlOiAnNTg4NTQzJyxcbiAgICAgICAgICAgICAgZnJvbTogJzB4NmNjOTM5N2MzYjM4NzM5ZGFjYmZhYTY4ZWFkNWY1ZDc3YmE1ZjQ1NScsXG4gICAgICAgICAgICAgIHRvOiAnMHg1NmM4Nzk1MDNjOGU3NGRjMWE5YTE0MGFiNWE5MjBiN2NkOTg3MWU5JyxcbiAgICAgICAgICAgICAgdmFsdWU6ICc0NzA3NzkzNzUwMDAwMDAwMDAnLFxuICAgICAgICAgICAgICBnYXM6ICcyMTAwMCcsXG4gICAgICAgICAgICAgIGdhc1ByaWNlOiAnNjExNzYyMjAwNScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuXG4gICAgICAvLyBNb2NrIGJhY2t1cCBrZXkgYmFsYW5jZSBjaGVja1xuICAgICAgbm9jaygnaHR0cHM6Ly9hcGkuZXRoZXJzY2FuLmlvJylcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeSgoYWN0dWFsKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIGFjdHVhbC5tb2R1bGUgPT09ICdhY2NvdW50JyAmJlxuICAgICAgICAgICAgYWN0dWFsLmFjdGlvbiA9PT0gJ2JhbGFuY2UnICYmXG4gICAgICAgICAgICBhY3R1YWwuYXBpa2V5ID09PSBjdXN0b21BcGlLZXkgJiZcbiAgICAgICAgICAgIGFjdHVhbC5hZGRyZXNzID09PSAnMHg1NmM4Nzk1MDNjOGU3NGRjMWE5YTE0MGFiNWE5MjBiN2NkOTg3MWU5J1xuICAgICAgICAgICk7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBzdGF0dXM6ICcxJyxcbiAgICAgICAgICBtZXNzYWdlOiAnT0snLFxuICAgICAgICAgIHJlc3VsdDogJzkyNjIxMTY1NjczNjQ1MDQ3MScsXG4gICAgICAgIH0pO1xuXG4gICAgICAvLyBNb2NrIHdhbGxldCBjb250cmFjdCBiYWxhbmNlIGNoZWNrXG4gICAgICBub2NrKCdodHRwczovL2FwaS5ldGhlcnNjYW4uaW8nKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KChhY3R1YWwpID0+IHtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgYWN0dWFsLm1vZHVsZSA9PT0gJ2FjY291bnQnICYmXG4gICAgICAgICAgICBhY3R1YWwuYWN0aW9uID09PSAnYmFsYW5jZScgJiZcbiAgICAgICAgICAgIGFjdHVhbC5hcGlrZXkgPT09IGN1c3RvbUFwaUtleSAmJlxuICAgICAgICAgICAgYWN0dWFsLmFkZHJlc3MgPT09ICcweGZmMTY5NjgyYmZkZTViODExYmE5MGE2MWFlYTM5YmVkZDc4YzJmNzUnXG4gICAgICAgICAgKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHN0YXR1czogJzEnLFxuICAgICAgICAgIG1lc3NhZ2U6ICdPSycsXG4gICAgICAgICAgcmVzdWx0OiAnNTE4NzQ5OTk5OTk5OTk5MDAwJyxcbiAgICAgICAgfSk7XG5cbiAgICAgIC8vIE1vY2sgc2VxdWVuY2UgSUQgcXVlcnlcbiAgICAgIG5vY2soJ2h0dHBzOi8vYXBpLmV0aGVyc2Nhbi5pbycpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkoKGFjdHVhbCkgPT4ge1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBhY3R1YWwubW9kdWxlID09PSAncHJveHknICYmXG4gICAgICAgICAgICBhY3R1YWwuYWN0aW9uID09PSAnZXRoX2NhbGwnICYmXG4gICAgICAgICAgICBhY3R1YWwuYXBpa2V5ID09PSBjdXN0b21BcGlLZXkgJiZcbiAgICAgICAgICAgIGFjdHVhbC5kYXRhID09PSAnYTBiNzk2N2InXG4gICAgICAgICAgKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGlkOiAxLFxuICAgICAgICAgIHJlc3VsdDogJzB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMicsXG4gICAgICAgIH0pO1xuXG4gICAgICAvLyBBZGRpdGlvbmFsIG5vY2sgZm9yIHRoZSB2MiBBUEkgZW5kcG9pbnQgd2l0aCBjaGFpbmlkIHBhcmFtZXRlciBmb3IgdHhsaXN0XG4gICAgICBub2NrKCdodHRwczovL2FwaS5ldGhlcnNjYW4uaW8nKVxuICAgICAgICAuZ2V0KCcvdjIvYXBpJylcbiAgICAgICAgLnF1ZXJ5KChhY3R1YWwpID0+IHtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgYWN0dWFsLmNoYWluaWQgPT09ICc1NjAwNDgnICYmXG4gICAgICAgICAgICBhY3R1YWwubW9kdWxlID09PSAnYWNjb3VudCcgJiZcbiAgICAgICAgICAgIGFjdHVhbC5hY3Rpb24gPT09ICd0eGxpc3QnICYmXG4gICAgICAgICAgICBhY3R1YWwuYWRkcmVzcyA9PT0gJzB4NTZjODc5NTAzYzhlNzRkYzFhOWExNDBhYjVhOTIwYjdjZDk4NzFlOScgJiZcbiAgICAgICAgICAgIGFjdHVhbC5hcGlrZXkgPT09IGN1c3RvbUFwaUtleVxuICAgICAgICAgICk7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBzdGF0dXM6ICcxJyxcbiAgICAgICAgICBtZXNzYWdlOiAnT0snLFxuICAgICAgICAgIHJlc3VsdDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBibG9ja051bWJlcjogJzExMjUzNTYnLFxuICAgICAgICAgICAgICB0aW1lU3RhbXA6ICcxNzEwMjUyMDM2JyxcbiAgICAgICAgICAgICAgaGFzaDogJzB4MDFiMDY0MmM4NTI1OTJhNzcyNDk1YjhiM2I0ZmJkMjAzYzViMDE0MjU3OTgwMWUxYzIyM2ZlODY3MDAxNzRjMicsXG4gICAgICAgICAgICAgIG5vbmNlOiAnNTg4NTQzJyxcbiAgICAgICAgICAgICAgYmxvY2tIYXNoOiAnMHgxNzJmNjdkOGM5YmM4YWMxODFhODNjOGY5MzYzZTczNjUyMzlmODhiNmZiZGY4NTFjMWIzNTQ1MTliZTcyODdhJyxcbiAgICAgICAgICAgICAgdHJhbnNhY3Rpb25JbmRleDogJzMnLFxuICAgICAgICAgICAgICBmcm9tOiAnMHg2Y2M5Mzk3YzNiMzg3MzlkYWNiZmFhNjhlYWQ1ZjVkNzdiYTVmNDU1JyxcbiAgICAgICAgICAgICAgdG86ICcweDU2Yzg3OTUwM2M4ZTc0ZGMxYTlhMTQwYWI1YTkyMGI3Y2Q5ODcxZTknLFxuICAgICAgICAgICAgICB2YWx1ZTogJzQ3MDc3OTM3NTAwMDAwMDAwMCcsXG4gICAgICAgICAgICAgIGdhczogJzIxMDAwJyxcbiAgICAgICAgICAgICAgZ2FzUHJpY2U6ICc2MTE3NjIyMDA1JyxcbiAgICAgICAgICAgICAgaXNFcnJvcjogJzAnLFxuICAgICAgICAgICAgICB0eHJlY2VpcHRfc3RhdHVzOiAnMScsXG4gICAgICAgICAgICAgIGlucHV0OiAnMHgnLFxuICAgICAgICAgICAgICBjb250cmFjdEFkZHJlc3M6ICcnLFxuICAgICAgICAgICAgICBjdW11bGF0aXZlR2FzVXNlZDogJzg0MDAwJyxcbiAgICAgICAgICAgICAgZ2FzVXNlZDogJzIxMDAwJyxcbiAgICAgICAgICAgICAgY29uZmlybWF0aW9uczogJzMwODk5MzUnLFxuICAgICAgICAgICAgICBtZXRob2RJZDogJzB4JyxcbiAgICAgICAgICAgICAgZnVuY3Rpb25OYW1lOiAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG5cbiAgICAgIC8vIEFkZGl0aW9uYWwgbm9jayBmb3IgdGhlIHYyIEFQSSBlbmRwb2ludCB3aXRoIGNoYWluaWQgcGFyYW1ldGVyIGZvciBiYWNrdXAga2V5IGJhbGFuY2VcbiAgICAgIG5vY2soJ2h0dHBzOi8vYXBpLmV0aGVyc2Nhbi5pbycpXG4gICAgICAgIC5nZXQoJy92Mi9hcGknKVxuICAgICAgICAucXVlcnkoKGFjdHVhbCkgPT4ge1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBhY3R1YWwuY2hhaW5pZCA9PT0gJzU2MDA0OCcgJiZcbiAgICAgICAgICAgIGFjdHVhbC5tb2R1bGUgPT09ICdhY2NvdW50JyAmJlxuICAgICAgICAgICAgYWN0dWFsLmFjdGlvbiA9PT0gJ2JhbGFuY2UnICYmXG4gICAgICAgICAgICBhY3R1YWwuYWRkcmVzcyA9PT0gJzB4NTZjODc5NTAzYzhlNzRkYzFhOWExNDBhYjVhOTIwYjdjZDk4NzFlOScgJiZcbiAgICAgICAgICAgIGFjdHVhbC5hcGlrZXkgPT09IGN1c3RvbUFwaUtleVxuICAgICAgICAgICk7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBzdGF0dXM6ICcxJyxcbiAgICAgICAgICBtZXNzYWdlOiAnT0snLFxuICAgICAgICAgIHJlc3VsdDogJzkyNjIxMTY1NjczNjQ1MDQ3MScsXG4gICAgICAgIH0pO1xuXG4gICAgICAvLyBBZGRpdGlvbmFsIG5vY2sgZm9yIHRoZSB2MiBBUEkgZW5kcG9pbnQgd2l0aCBjaGFpbmlkIHBhcmFtZXRlciBmb3Igd2FsbGV0IGNvbnRyYWN0IGJhbGFuY2VcbiAgICAgIG5vY2soJ2h0dHBzOi8vYXBpLmV0aGVyc2Nhbi5pbycpXG4gICAgICAgIC5nZXQoJy92Mi9hcGknKVxuICAgICAgICAucXVlcnkoKGFjdHVhbCkgPT4ge1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBhY3R1YWwuY2hhaW5pZCA9PT0gJzU2MDA0OCcgJiZcbiAgICAgICAgICAgIGFjdHVhbC5tb2R1bGUgPT09ICdhY2NvdW50JyAmJlxuICAgICAgICAgICAgYWN0dWFsLmFjdGlvbiA9PT0gJ2JhbGFuY2UnICYmXG4gICAgICAgICAgICBhY3R1YWwuYWRkcmVzcyA9PT0gJzB4ZmYxNjk2ODJiZmRlNWI4MTFiYTkwYTYxYWVhMzliZWRkNzhjMmY3NScgJiZcbiAgICAgICAgICAgIGFjdHVhbC5hcGlrZXkgPT09IGN1c3RvbUFwaUtleVxuICAgICAgICAgICk7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBzdGF0dXM6ICcxJyxcbiAgICAgICAgICBtZXNzYWdlOiAnT0snLFxuICAgICAgICAgIHJlc3VsdDogJzUxODc0OTk5OTk5OTk5OTAwMCcsXG4gICAgICAgIH0pO1xuXG4gICAgICAvLyBBZGRpdGlvbmFsIG5vY2sgZm9yIHRoZSB2MiBBUEkgZW5kcG9pbnQgd2l0aCBjaGFpbmlkIHBhcmFtZXRlciBmb3Igc2VxdWVuY2UgSUQgcXVlcnlcbiAgICAgIG5vY2soJ2h0dHBzOi8vYXBpLmV0aGVyc2Nhbi5pbycpXG4gICAgICAgIC5nZXQoJy92Mi9hcGknKVxuICAgICAgICAucXVlcnkoKGFjdHVhbCkgPT4ge1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBhY3R1YWwuY2hhaW5pZCA9PT0gJzU2MDA0OCcgJiZcbiAgICAgICAgICAgIGFjdHVhbC5tb2R1bGUgPT09ICdwcm94eScgJiZcbiAgICAgICAgICAgIGFjdHVhbC5hY3Rpb24gPT09ICdldGhfY2FsbCcgJiZcbiAgICAgICAgICAgIGFjdHVhbC50byA9PT0gJzB4ZmYxNjk2ODJiZmRlNWI4MTFiYTkwYTYxYWVhMzliZWRkNzhjMmY3NScgJiZcbiAgICAgICAgICAgIGFjdHVhbC5kYXRhID09PSAnYTBiNzk2N2InICYmXG4gICAgICAgICAgICBhY3R1YWwudGFnID09PSAnbGF0ZXN0JyAmJlxuICAgICAgICAgICAgYWN0dWFsLmFwaWtleSA9PT0gY3VzdG9tQXBpS2V5XG4gICAgICAgICAgKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGpzb25ycGM6ICcyLjAnLFxuICAgICAgICAgIGlkOiAxLFxuICAgICAgICAgIHJlc3VsdDogJzB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMicsXG4gICAgICAgIH0pO1xuXG4gICAgICBub2NrKCdodHRwczovL2FwaS5ldGhlcnNjYW4uaW8nKVxuICAgICAgICAuZ2V0KCcvdjIvYXBpJylcbiAgICAgICAgLnF1ZXJ5KChhY3R1YWwpID0+IHtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgYWN0dWFsLmNoYWluaWQgPT09ICc1NjAwNDgnICYmXG4gICAgICAgICAgICBhY3R1YWwubW9kdWxlID09PSAnYWNjb3VudCcgJiZcbiAgICAgICAgICAgIGFjdHVhbC5hY3Rpb24gPT09ICd0eGxpc3QnICYmXG4gICAgICAgICAgICBhY3R1YWwuYWRkcmVzcyA9PT0gJzB4NTZjODc5NTAzYzhlNzRkYzFhOWExNDBhYjVhOTIwYjdjZDk4NzFlOScgJiZcbiAgICAgICAgICAgIGFjdHVhbC5hcGlrZXkgPT09IGN1c3RvbUFwaUtleVxuICAgICAgICAgICk7XG4gICAgICAgIH0pXG4gICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICBzdGF0dXM6ICcxJyxcbiAgICAgICAgICBtZXNzYWdlOiAnT0snLFxuICAgICAgICAgIHJlc3VsdDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBibG9ja051bWJlcjogJzQyMTQwMTUnLFxuICAgICAgICAgICAgICB0aW1lU3RhbXA6ICcxNzUzMjgzNzI0JyxcbiAgICAgICAgICAgICAgaGFzaDogJzB4ZDBiM2E5M2RkZmU2MmY1MzNhMzZjZjAyYzVjYTk0Mjg5NjdhY2EzMWZjY2UzYzgwMTU5YjVhOTU4YjI5ODQyMCcsXG4gICAgICAgICAgICAgIG5vbmNlOiAnMjInLFxuICAgICAgICAgICAgICBibG9ja0hhc2g6ICcweDU4ODI5M2QwMjc0NjQzYWJkMGExMjFjZjA1NGYyOTg0MmVhYmQ0MDBkMDI1MTUyNzU4NWJiNTc5NzE4M2E4MTQnLFxuICAgICAgICAgICAgICB0cmFuc2FjdGlvbkluZGV4OiAnMicsXG4gICAgICAgICAgICAgIGZyb206ICcweDU2Yzg3OTUwM2M4ZTc0ZGMxYTlhMTQwYWI1YTkyMGI3Y2Q5ODcxZTknLFxuICAgICAgICAgICAgICB0bzogJzB4ZmYxNjk2ODJiZmRlNWI4MTFiYTkwYTYxYWVhMzliZWRkNzhjMmY3NScsXG4gICAgICAgICAgICAgIHZhbHVlOiAnMCcsXG4gICAgICAgICAgICAgIGdhczogJzE5NjYxOCcsXG4gICAgICAgICAgICAgIGdhc1ByaWNlOiAnMTM4MDAxMCcsXG4gICAgICAgICAgICAgIGlzRXJyb3I6ICcwJyxcbiAgICAgICAgICAgICAgdHhyZWNlaXB0X3N0YXR1czogJzEnLFxuICAgICAgICAgICAgICBpbnB1dDpcbiAgICAgICAgICAgICAgICAnMHgzOTEyNTIxNTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDMzM2ViYTczYjhjOTZiZDhhYzJiMTk0ODVhYjhmYzJiMDc5NzNlNjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM2U4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBjMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNjg4YTM3MDIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBlMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDQxMjg3MGQxNmY3YTAyYjhhZTg4MDk1NTlhZDZjN2IzYzc3NDJmZTU3ZTRjMDY4ZWUwZWEyMGQ1YzcxZjllYzJjNTYxYTU4MmQ5MWEyMzFjZjAxMzdiMTJkNjUwNThkNTA2MzhkNzc5Zjg2Zjk1OGM3NDhjYjk4OGQ0YjY4MjQ0MzExYzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgICAgICAgY29udHJhY3RBZGRyZXNzOiAnJyxcbiAgICAgICAgICAgICAgY3VtdWxhdGl2ZUdhc1VzZWQ6ICc3Njc1NDUnLFxuICAgICAgICAgICAgICBnYXNVc2VkOiAnMTI0NDYzJyxcbiAgICAgICAgICAgICAgY29uZmlybWF0aW9uczogJzIyNDUnLFxuICAgICAgICAgICAgICBtZXRob2RJZDogJzB4MzkxMjUyMTUnLFxuICAgICAgICAgICAgICBmdW5jdGlvbk5hbWU6XG4gICAgICAgICAgICAgICAgJ3NlbmRNdWx0aVNpZyhhZGRyZXNzIHRvQWRkcmVzcyx1aW50MjU2IHZhbHVlLGJ5dGVzIGRhdGEsdWludDI1NiBleHBpcmVUaW1lLHVpbnQyNTYgc2VxdWVuY2VJZCxieXRlcyBzaWduYXR1cmUpJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG4gICAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeSk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgICAgICByZWNvdmVyeS50eC5zaG91bGQubWF0Y2goL15mOTAxMmIuKjgwODA4MCQvKTsgLy8gVHJhbnNhY3Rpb24gaGV4IGZvcm1hdCBjaGVja1xuICAgICAgICByZWNvdmVyeS5yZWNpcGllbnRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCcweDMzZTZiNGRkNjBhOTE3ZDI0MTcwZWI5NmQ1ZWIyNWZhMjI3N2E5MmYnKTtcbiAgICAgICAgcmVjb3ZlcnkucmVjaXBpZW50c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKCc1MTg3NDk5OTk5OTk5OTkwMDAnKTtcbiAgICAgICAgcmVjb3ZlcnkuY29udHJhY3RTZXF1ZW5jZUlkLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgc2lub24uYXNzZXJ0LmZhaWwoZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFZlcmlmeSBBUEkga2V5IGlzIGNvcnJlY3RseSBwYXNzZWQgdG8gZWFjaCBibG9ja2NoYWluIGV4cGxvcmVyIHF1ZXJ5XG4gICAgICBzaW5vbi5hc3NlcnQuY2FsbGVkKHJlY292ZXJ5QmxvY2tjaGFpbkV4cGxvcmVyUXVlcnlTcHkpO1xuICAgICAgY29uc3QgZXhwbG9yZXJRdWVyeUNhbGxzID0gcmVjb3ZlcnlCbG9ja2NoYWluRXhwbG9yZXJRdWVyeVNweS5nZXRDYWxscygpO1xuXG4gICAgICAvLyBDaGVjayB0aGF0IGFsbCBjYWxscyB1c2VkIHRoZSBjdXN0b20gQVBJIGtleVxuICAgICAgZXhwbG9yZXJRdWVyeUNhbGxzLmZvckVhY2goKGNhbGwpID0+IHtcbiAgICAgICAgY2FsbC5hcmdzWzFdLnNob3VsZC5lcXVhbChjdXN0b21BcGlLZXkpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIFZlcmlmeSBzcGVjaWZpYyBmdW5jdGlvbnMgcmVjZWl2ZWQgdGhlIEFQSSBrZXlcbiAgICAgIGlmIChxdWVyeUFkZHJlc3NCYWxhbmNlU3B5LmNhbGxlZCkge1xuICAgICAgICBjb25zdCBxdWVyeUFkZHJlc3NCYWxhbmNlQ2FsbCA9IHF1ZXJ5QWRkcmVzc0JhbGFuY2VTcHkuZ2V0Q2FsbCgwKTtcbiAgICAgICAgcXVlcnlBZGRyZXNzQmFsYW5jZUNhbGwuYXJnc1sxXS5zaG91bGQuZXF1YWwoY3VzdG9tQXBpS2V5KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGdldEFkZHJlc3NOb25jZVNweS5jYWxsZWQpIHtcbiAgICAgICAgY29uc3QgZ2V0QWRkcmVzc05vbmNlQ2FsbCA9IGdldEFkZHJlc3NOb25jZVNweS5nZXRDYWxsKDApO1xuICAgICAgICBnZXRBZGRyZXNzTm9uY2VDYWxsLmFyZ3NbMV0uc2hvdWxkLmVxdWFsKGN1c3RvbUFwaUtleSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChxdWVyeVNlcXVlbmNlSWRTcHkuY2FsbGVkKSB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5U2VxdWVuY2VJZENhbGwgPSBxdWVyeVNlcXVlbmNlSWRTcHkuZ2V0Q2FsbCgwKTtcbiAgICAgICAgcXVlcnlTZXF1ZW5jZUlkQ2FsbC5hcmdzWzFdLnNob3VsZC5lcXVhbChjdXN0b21BcGlLZXkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVjb3ZlciBFdGhlcmV1bScsIGZ1bmN0aW9uICgpIHtcbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICB9KTtcbiAgICBsZXQgcmVjb3ZlcnlQYXJhbXM7XG5cbiAgICBjb25zdCBub2NrVFNTRGF0YTogYW55W10gPSBbXG4gICAgICB7XG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgIG1vZHVsZTogJ2FjY291bnQnLFxuICAgICAgICAgIGFjdGlvbjogJ3R4bGlzdCcsXG4gICAgICAgICAgYWRkcmVzczogJzB4ZTc0MDZkYzQzZDEzZjY5OGZiNDFhMzQ1Yzc3ODNkMzlhNGMyZDE5MScsXG4gICAgICAgIH0sXG4gICAgICAgIHJlc3BvbnNlOiB7XG4gICAgICAgICAgc3RhdHVzOiAnMCcsXG4gICAgICAgICAgbWVzc2FnZTogJ05vIHRyYW5zYWN0aW9ucyBmb3VuZCcsXG4gICAgICAgICAgcmVzdWx0OiBbXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgIG1vZHVsZTogJ2FjY291bnQnLFxuICAgICAgICAgIGFjdGlvbjogJ2JhbGFuY2UnLFxuICAgICAgICAgIGFkZHJlc3M6ICcweGU3NDA2ZGM0M2QxM2Y2OThmYjQxYTM0NWM3NzgzZDM5YTRjMmQxOTEnLFxuICAgICAgICB9LFxuICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgIHN0YXR1czogJzEnLFxuICAgICAgICAgIG1lc3NhZ2U6ICdPSycsXG4gICAgICAgICAgcmVzdWx0OiAnMTAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIF07XG4gICAgY29uc3Qgbm9ja1Vuc2lnbmVkU3dlZXBUU1NEYXRhOiBhbnlbXSA9IFtcbiAgICAgIHtcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgbW9kdWxlOiAnYWNjb3VudCcsXG4gICAgICAgICAgYWN0aW9uOiAndHhsaXN0JyxcbiAgICAgICAgICBhZGRyZXNzOiAnMHhhOTFlMTA1OTk1M2Q3ZWYyYWRiYmNhNGI2ODhiZmUyMjg2NmZiY2VlJyxcbiAgICAgICAgfSxcbiAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICBzdGF0dXM6ICcwJyxcbiAgICAgICAgICBtZXNzYWdlOiAnTm8gdHJhbnNhY3Rpb25zIGZvdW5kJyxcbiAgICAgICAgICByZXN1bHQ6IFtdLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgbW9kdWxlOiAnYWNjb3VudCcsXG4gICAgICAgICAgYWN0aW9uOiAnYmFsYW5jZScsXG4gICAgICAgICAgYWRkcmVzczogJzB4YTkxZTEwNTk5NTNkN2VmMmFkYmJjYTRiNjg4YmZlMjI4NjZmYmNlZScsXG4gICAgICAgIH0sXG4gICAgICAgIHJlc3BvbnNlOiB7XG4gICAgICAgICAgc3RhdHVzOiAnMScsXG4gICAgICAgICAgbWVzc2FnZTogJ09LJyxcbiAgICAgICAgICByZXN1bHQ6ICcxMDAwMDAwMDAwMDAwMDAwMDAwJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgXTtcbiAgICBsZXQgcmVjb3ZlckV0aFNhbmRib3g6IHNpbm9uLlNpbm9uU2FuZGJveDtcblxuICAgIGJlZm9yZSgoKSA9PiB7XG4gICAgICByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgdXNlcktleTpcbiAgICAgICAgICAne1wiaXZcIjpcIitUa21UM0dKNW1zVldRakJydDNsc3c9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCJcXG4nICtcbiAgICAgICAgICAnOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiY0NFMjBmR0lvYnM9XCIsXCJjdFwiOlwiTlZJZFlJaDkxSjNhUklcXG4nICtcbiAgICAgICAgICAnOEdHMEpFM0RoWFczQVVtejJHNVJxTWVqZHoxK3Q0L3ZvdklQN2xsZWVnSTdWWXlXaWlMdmxNME9DRmYzRVZ2Vi9SeVhyOCsydnNuXFxuJyArXG4gICAgICAgICAgJ1EwVm44YzJDVjVGUlo4ME9qR1lyVzNBLzZUL3pwT3o2RThDTXZuRCsraUlwZU80cjJlWkphdmVqWnhkemx4RjBCUno3Vkk9XCJ9JyxcbiAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICd7XCJpdlwiOlwiYXNCMzU2b2ZDN25adGc0TkJ2UWtpUT09XCIsXCJ2XCI6MSxcIml0ZXJcIjoxMDAwMCxcImtzXCI6MjU2LFwidHNcIjo2NCxcIm1vZGVcIlxcbicgK1xuICAgICAgICAgICc6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCIxaHIySGhCYkJJaz1cIixcImN0XCI6XCI4Q1pjNnVwdCtYTk90b1xcbicgK1xuICAgICAgICAgICdLREQzOFRVZzNaVWp6VytEcmFabGtja3UyYk5wMEpTMnMxZy9pQzZZVEdVR3RQb3hEeHVtRGxYd2xXUXgrNVdQalp1NzlNOERDcklcXG4nICtcbiAgICAgICAgICAndDlhWmFPdkhrR0g5YUZ0TWJhdkZYNDE5VGNyd0RtcFVlUUZOMGhSa2ZySUhYeUhOYlRwR1NWQWpIdkhNdHpETWF3K0FDZz1cIn0nLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnMHg1ZGY1YTk2YjQ3OGJiMTgwODE0MGQ4NzA3MjE0M2U2MDI2MmU4NjcwJyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJzB4YWMwNWRhNzg0NjQ1MjBhYTdjOWQ0YzE5YmQ3YTQ0MGIxMTFiMzA1NCcsXG4gICAgICAgIHJlcGxheVByb3RlY3Rpb25PcHRpb25zOiB7XG4gICAgICAgICAgY2hhaW46IDQyLFxuICAgICAgICAgIGhhcmRmb3JrOiAnbG9uZG9uJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICByZWNvdmVyRXRoU2FuZGJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICAgIHJlY292ZXJFdGhTYW5kYm94XG4gICAgICAgIC5zdHViKEVjZHNhUmFuZ2VQcm9vZiwgJ2dlbmVyYXRlTnRpbGRlJylcbiAgICAgICAgLnJlc29sdmVzKEVjZHNhVHlwZXMuZGVzZXJpYWxpemVOdGlsZGVXaXRoUHJvb2ZzKG1vY2tTZXJpYWxpemVkQ2hhbGxlbmdlV2l0aFByb29mcykpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXIoKCkgPT4ge1xuICAgICAgcmVjb3ZlckV0aFNhbmRib3gucmVzdG9yZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBvbiBpbnZhbGlkIGdhc0xpbWl0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIC4uLnJlY292ZXJ5UGFyYW1zLFxuICAgICAgICAgIGdhc0xpbWl0OiAtNDAwMDAwLFxuICAgICAgICAgIGdhc1ByaWNlOiAyNTAwMDAwMDAwMCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0dhcyBsaW1pdCBtdXN0IGJlIGJldHdlZW4gMzAwMDAgYW5kIDIwMDAwMDAwJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIGV0aGVyc2NhbiBlcnJzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgbm9ja1Vuc3VjY2Vzc2Z1bEV0aGVyc2NhbkRhdGE6IGFueVtdID0gW1xuICAgICAgICB7XG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBtb2R1bGU6ICdhY2NvdW50JyxcbiAgICAgICAgICAgIGFjdGlvbjogJ3R4bGlzdCcsXG4gICAgICAgICAgICBhZGRyZXNzOiAnMHg3NGMyMTM3ZDU0YjBmYzlmOTA3ZTEzZjE0ZTBkZDE4NDg1ZmVlOTI0JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlc3BvbnNlOiB7XG4gICAgICAgICAgICBzdGF0dXM6ICcwJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6ICdObyB0cmFuc2FjdGlvbnMgZm91bmQnLFxuICAgICAgICAgICAgcmVzdWx0OiBbXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBtb2R1bGU6ICdhY2NvdW50JyxcbiAgICAgICAgICAgIGFjdGlvbjogJ2JhbGFuY2UnLFxuICAgICAgICAgICAgYWRkcmVzczogJzB4NzRjMjEzN2Q1NGIwZmM5ZjkwN2UxM2YxNGUwZGQxODQ4NWZlZTkyNCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgc3RhdHVzOiAnMScsXG4gICAgICAgICAgICBtZXNzYWdlOiAnTk9UT0snLFxuICAgICAgICAgICAgcmVzdWx0OiAnUmF0ZSBsaW1pdCBleGNlZWRlZCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tFdGhMaWtlUmVjb3ZlcnkoYml0Z28sIG5vY2tVbnN1Y2Nlc3NmdWxFdGhlcnNjYW5EYXRhKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdDb3VsZCBub3Qgb2J0YWluIGFkZHJlc3MgYmFsYW5jZSBmb3IgMHg3NGMyMTM3ZDU0YjBmYzlmOTA3ZTEzZjE0ZTBkZDE4NDg1ZmVlOTI0IGZyb20gdGhlIGV4cGxvcmVyLCBnb3Q6IFJhdGUgbGltaXQgZXhjZWVkZWQnXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIGJhY2t1cCBrZXkgYWRkcmVzcyBoYXMgaW5zdWZmaWNpZW50IGJhbGFuY2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnN1ZmZpY2llbnRGZWVEYXRhOiBhbnlbXSA9IFtcbiAgICAgICAge1xuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgbW9kdWxlOiAnYWNjb3VudCcsXG4gICAgICAgICAgICBhY3Rpb246ICd0eGxpc3QnLFxuICAgICAgICAgICAgYWRkcmVzczogJzB4NzRjMjEzN2Q1NGIwZmM5ZjkwN2UxM2YxNGUwZGQxODQ4NWZlZTkyNCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgc3RhdHVzOiAnMCcsXG4gICAgICAgICAgICBtZXNzYWdlOiAnTm8gdHJhbnNhY3Rpb25zIGZvdW5kJyxcbiAgICAgICAgICAgIHJlc3VsdDogW10sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgbW9kdWxlOiAnYWNjb3VudCcsXG4gICAgICAgICAgICBhY3Rpb246ICdiYWxhbmNlJyxcbiAgICAgICAgICAgIGFkZHJlc3M6ICcweDc0YzIxMzdkNTRiMGZjOWY5MDdlMTNmMTRlMGRkMTg0ODVmZWU5MjQnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIHN0YXR1czogJzEnLFxuICAgICAgICAgICAgbWVzc2FnZTogJ09LJyxcbiAgICAgICAgICAgIHJlc3VsdDogJzEyMzQnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvLCBpbnN1ZmZpY2llbnRGZWVEYXRhKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIC4uLnJlY292ZXJ5UGFyYW1zLFxuICAgICAgICAgIGdhc0xpbWl0OiAzMDAwMDAsXG4gICAgICAgICAgZ2FzUHJpY2U6IDEwMDAwMDAwMDAsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdCYWNrdXAga2V5IGFkZHJlc3MgMHg3NGMyMTM3ZDU0YjBmYzlmOTA3ZTEzZjE0ZTBkZDE4NDg1ZmVlOTI0IGhhcyBiYWxhbmNlIDAuMDAwMDAxMjM0IEd3ZWkuJyArXG4gICAgICAgICAgICAnVGhpcyBhZGRyZXNzIG11c3QgaGF2ZSBhIGJhbGFuY2Ugb2YgYXQgbGVhc3QgMzAwMDAwIEd3ZWkgdG8gcGVyZm9ybSByZWNvdmVyaWVzLiBUcnkgc2VuZGluZyBzb21lIEVUSCB0byB0aGlzIGFkZHJlc3MgdGhlbiByZXRyeS4nXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG9uIGludmFsaWQgZ2FzUHJpY2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tFdGhMaWtlUmVjb3ZlcnkoYml0Z28pO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgLi4ucmVjb3ZlcnlQYXJhbXMsXG4gICAgICAgICAgZ2FzTGltaXQ6IDQwMDAwMCxcbiAgICAgICAgICBnYXNQcmljZTogMjUwMDAwMCxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0dhcyBwcmljZSBtdXN0IGJlIGJldHdlZW4gMTAwMDAwMDAwMCBhbmQgMjUwMDAwMDAwMDAwMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdWNjZXNzZnVsbHkgY29uc3RydWN0IGEgdHggd2l0aCBjdXN0b20gZ2FzIHByaWNlIGFuZCBsaW1pdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aExpa2VSZWNvdmVyeShiaXRnbyk7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIC4uLnJlY292ZXJ5UGFyYW1zLFxuICAgICAgICBnYXNMaW1pdDogNDAwMDAwLFxuICAgICAgICBnYXNQcmljZTogMTAwMDAwMDAwMCxcbiAgICAgIH0pO1xuICAgICAgLy8gaWQgYW5kIHR4IHdpbGwgYWx3YXlzIGJlIGRpZmZlcmVudCBiZWNhdXNlIG9mIGV4cGlyZVRpbWVcbiAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeSk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaWQnKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb25zdHJ1Y3QgYSByZWNvdmVyeSB0cmFuc2FjdGlvbiB3aXRob3V0IEJpdEdvJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvKTtcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpO1xuICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKTtcbiAgICAgIC8vIGlkIGFuZCB0eCB3aWxsIGFsd2F5cyBiZSBkaWZmZXJlbnQgYmVjYXVzZSBvZiBleHBpcmVUaW1lXG4gICAgICBzaG91bGQuZXhpc3QocmVjb3ZlcnkpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lkJyk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29uc3RydWN0IGFuIGVpcDE1NTkgcmVjb3ZlcnkgdHJhbnNhY3Rpb24gd2l0aG91dCBCaXRHbycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVpcDE1NTlSZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgLi4ucmVjb3ZlcnlQYXJhbXMsXG4gICAgICAgIGVpcDE1NTk6IHtcbiAgICAgICAgICBtYXhQcmlvcml0eUZlZVBlckdhczogMyxcbiAgICAgICAgICBtYXhGZWVQZXJHYXM6IDIwLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aExpa2VSZWNvdmVyeShiaXRnbyk7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihlaXAxNTU5UmVjb3ZlcnlQYXJhbXMpO1xuICAgICAgLy8gaWQgYW5kIHR4IHdpbGwgYWx3YXlzIGJlIGRpZmZlcmVudCBiZWNhdXNlIG9mIGV4cGlyZVRpbWVcbiAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeSk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaWQnKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb25zdHJ1Y3QgYSByZWNvdmVyeSB0cmFuc2FjdGlvbiB3aXRob3V0IEJpdEdvIGFuZCB3aXRoIEtSUycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aExpa2VSZWNvdmVyeShiaXRnbyk7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKTtcbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIC4uLnJlY292ZXJ5UGFyYW1zLFxuICAgICAgICBiYWNrdXBLZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNHc0NOaUc0QnpieExtWG5KRm80SzVnVlNFMmI5QXh1ZkF0cHVUdW4xU1l3ZzlVeWtxcWY0RHJLckRaNktxUG05ZWh0aFdiQ21hN3BuYU1ydFhZMTFuWTdNZUZiRURQbScsXG4gICAgICAgIGtyc1Byb3ZpZGVyOiAna2V5dGVybmFsJyxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBpZCBhbmQgdHggd2lsbCBhbHdheXMgYmUgZGlmZmVyZW50IGJlY2F1c2Ugb2YgZXhwaXJlVGltZVxuICAgICAgc2hvdWxkLmV4aXN0KHJlY292ZXJ5KTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpZCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGVycm9yIHdoZW4gdGhlIGJhY2t1cCBrZXkgaXMgdW5mdW5kZWQgKGNhbm5vdCBwYXkgZ2FzKScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aExpa2VSZWNvdmVyeShiaXRnbyk7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbignaHRldGgnKTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OlxuICAgICAgICAgICAgJ3tcIml2XCI6XCJWTnZHNnQzZkhmeE1jZnZOdWFmWVlBPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiXFxuJyArXG4gICAgICAgICAgICAnOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwibWM5cENrM0g0M3c9XCIsXCJjdFwiOlwiUWU0WjFldmFYY3JPTUNcXG4nICtcbiAgICAgICAgICAgICdjUS9YTVZWQk85TS85OUQxUVE2THhrRzh6M2ZRdHd3T1ZYTTMvNmRvTnJyaXByVXFzK2FkcEZDOTNLUmNBYURyb0wxRTZvMTdKMmtcXG4nICtcbiAgICAgICAgICAgICdtY3BYUmQyQ3VYUkZPUlptWi82UUJmaktmQ0ozYXEwa0VrRFZ2MzdnWk5WVDNhTnRHa05TUWRDRVdLUUx3ZDErK3I1QWtBPVwifVxcbicsXG4gICAgICAgICAgYmFja3VwS2V5OlxuICAgICAgICAgICAgJ3tcIml2XCI6XCJFakQ3eDBPSlg5a05NL0MzeUVEdnlRPT1cIixcInZcIjoxLFwiaXRlclwiOjEwMDAwLFwia3NcIjoyNTYsXCJ0c1wiOjY0LFwibW9kZVwiXFxuJyArXG4gICAgICAgICAgICAnOlwiY2NtXCIsXCJhZGF0YVwiOlwiXCIsXCJjaXBoZXJcIjpcImFlc1wiLFwic2FsdFwiOlwiTmE5TnZSUmUzbjg9XCIsXCJjdFwiOlwiQi9BdFNMSG9sc2ROTHJcXG4nICtcbiAgICAgICAgICAgICc0RGxpajRrUTBFNk55VVVzNndvNlQySHRQREFQTzBoeWhQUGJoMU9BWXFJUzdWbEw5eG1KUkZDMnpQeHdSSnZ6ZjZPV0MvbTQ4SFhcXG4nICtcbiAgICAgICAgICAgICd2Z0xvWFlnYWhBcmhhbHpKVmxSeGNYVXo0SE9ob3pSV2Z2L2VLM3Q1SEpmbSsyNStXQk9pVzhZZ1NFN2hWRVlUYmVCUkQ0PVwifScsXG4gICAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnMHgyMmZmNzQzMjE2YjU4YWViM2VmYzQ2OTg1NDA2YjUwMTEyZTllMTc2JyxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiAnMHhhYzA1ZGE3ODQ2NDUyMGFhN2M5ZDRjMTliZDdhNDQwYjExMWIzMDU0JyxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0JhY2t1cCBrZXkgYWRkcmVzcyAweGJhNmQ5ZDgyY2YyOTIwYzU0NGI4MzRiNzJmNGM2ZDExYTNlZjNkZTYgaGFzIGJhbGFuY2UgMCBHd2VpLlRoaXMgYWRkcmVzcyBtdXN0IGhhdmUgYSBiYWxhbmNlIG9mIGF0IGxlYXN0IDEwMDAwMDAwIEd3ZWkgdG8gcGVyZm9ybSByZWNvdmVyaWVzLiBUcnkgc2VuZGluZyBzb21lIEVUSCB0byB0aGlzIGFkZHJlc3MgdGhlbiByZXRyeS4nXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIHdoZW4gdGhlIGV0aGVyc2NhbiByYXRlIGxpbWl0IGlzIHJlYWNoZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tFdGhlcnNjYW5SYXRlTGltaXRFcnJvcigpO1xuICAgICAgYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcykuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnRXRoZXJzY2FuIHJhdGUgbGltaXQgcmVhY2hlZCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiBFVEggdW5zaWduZWQgc3dlZXAnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tFdGhMaWtlUmVjb3ZlcnkoYml0Z28pO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG5cbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6XG4gICAgICAgICAgJ3hwdWI2NjFNeU13QXFSYmNGWERjV0Qydnh1ZWJjVDFacFRGNFZrZTZxbU1XOHl6ZGR3TllwQVBqdllFRUw1akxmeVlYVzJmdXh0QXhZOFRnalBVSkxjZjFDOHF6OU42VmdaeEFyS1g0RXdCOHJINScsXG4gICAgICAgIGJhY2t1cEtleTpcbiAgICAgICAgICAneHB1YjY2MU15TXdBcVJiY0doU2FYaWtwdVRDOUtVODhYeDlMcmpLU3cxSktzdlhOZ2FicFRkZ2p5N0xTb3ZoOVpIaGNxaEFIUXU3dXRodTdGZ3VOR2RjQzRhWFRLSzVncVRjUGU0V3ZMWVJiQ1NHJyxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX1JFQ0lQSUVOVCxcbiAgICAgICAgZ2FzUHJpY2U6ICcyMDAwMDAwMDAwMCcsXG4gICAgICAgIGdhc0xpbWl0OiAnNTAwMDAwJyxcbiAgICAgIH0pO1xuICAgICAgc2hvdWxkLmV4aXN0KHRyYW5zYWN0aW9uKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvbnRyYWN0U2VxdWVuY2VJZCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2V4cGlyZVRpbWUnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdnYXNMaW1pdCcpO1xuICAgICAgdHJhbnNhY3Rpb24uZ2FzTGltaXQuc2hvdWxkLmVxdWFsKCc1MDAwMDAnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdnYXNQcmljZScpO1xuICAgICAgdHJhbnNhY3Rpb24uZ2FzUHJpY2Uuc2hvdWxkLmVxdWFsKCcyMDAwMDAwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvbnRyYWN0QWRkcmVzcycpO1xuICAgICAgdHJhbnNhY3Rpb24ud2FsbGV0Q29udHJhY3RBZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudCcpO1xuICAgICAgdHJhbnNhY3Rpb24ucmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi5yZWNpcGllbnQuYWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVJDMjBfVE9LRU5fUkVDSVBJRU5UKTtcbiAgICAgIHRyYW5zYWN0aW9uLnJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYW1vdW50Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5yZWNpcGllbnQuYW1vdW50LnNob3VsZC5lcXVhbCgnOTk5OTk5OTk5OTk5OTk5OTkyOCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb25zdHJ1Y3QgYSByZWNvdmVyeSB0eCB3aXRoIFRTUycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aExpa2VSZWNvdmVyeShiaXRnbywgbm9ja1RTU0RhdGEpO1xuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCdodGV0aCcpO1xuICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSBldGhMaWtlR0cxOEtleWNhcmQuc2VuZGVyQWRkcmVzcztcblxuICAgICAgY29uc3Qgbm9ja1RTU0RhdGFXaXRoQmFzZUFkZHJlc3MgPSBub2NrVFNTRGF0YS5tYXAoKGRhdGEpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5kYXRhLFxuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgLi4uZGF0YS5wYXJhbXMsXG4gICAgICAgICAgICBhZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfSk7XG5cbiAgICAgIHJlY292ZXJ5Tm9ja3Mubm9ja0V0aExpa2VSZWNvdmVyeShiaXRnbywgbm9ja1RTU0RhdGFXaXRoQmFzZUFkZHJlc3MpO1xuICAgICAgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIHVzZXJLZXk6IGV0aExpa2VHRzE4S2V5Y2FyZC51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IGV0aExpa2VHRzE4S2V5Y2FyZC5iYWNrdXBLZXksXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogZXRoTGlrZUdHMThLZXljYXJkLnNlbmRlckFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGV0aExpa2VHRzE4S2V5Y2FyZC5kZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IGV0aExpa2VHRzE4S2V5Y2FyZC53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBlaXAxNTU5OiB7XG4gICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDMsXG4gICAgICAgICAgbWF4RmVlUGVyR2FzOiAyMCxcbiAgICAgICAgfSxcbiAgICAgICAgaXNUc3M6IHRydWUsXG4gICAgICAgIHJlcGxheVByb3RlY3Rpb25PcHRpb25zOiB7XG4gICAgICAgICAgY2hhaW46IDUsXG4gICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KHJlY292ZXJ5KTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpZCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4Jyk7XG5cbiAgICAgIC8vIHZlcmlmeSBkYXRhIGFmdGVyIHNpZ25pbmcgaXMgY29ycmVjdFxuICAgICAgY29uc3QgZmluYWxUeCA9IFRyYW5zYWN0aW9uRmFjdG9yeS5mcm9tU2VyaWFsaXplZERhdGEoQnVmZmVyLmZyb20ocmVjb3ZlcnkudHguc3Vic3RyKDIpLCAnaGV4JykpO1xuXG4gICAgICBjb25zdCBzZW5kZXJBZGRyZXNzID0gZmluYWxUeC5nZXRTZW5kZXJBZGRyZXNzKCkudG9TdHJpbmcoKTtcblxuICAgICAgYmFzZUFkZHJlc3Muc2hvdWxkLmVxdWFsKHNlbmRlckFkZHJlc3MpO1xuICAgICAgcmVjb3ZlcnlQYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbi5zaG91bGQuZXF1YWwoZmluYWxUeC50bz8udG9TdHJpbmcoKSk7XG4gICAgICBOdW1iZXIoZmluYWxUeC52YWx1ZSkuc2hvdWxkLmVxdWFsKDk5OTk5OTk5OTk5MDAwMDAwMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvbnN0cnVjdCBhIHJlY292ZXJ5IHR4IHdpdGggTVBDdjIgVFNTJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgZm9yIChjb25zdCB7IGNvaW4sIGNoYWluIH0gb2YgW1xuICAgICAgICB7IGNvaW46ICdodGV0aCcsIGNoYWluOiA1NjAwNDggfSxcbiAgICAgICAgeyBjb2luOiAndHBvbHlnb24nLCBjaGFpbjogODAwMDIgfSxcbiAgICAgICAgeyBjb2luOiAndGJzYycsIGNoYWluOiA5NyB9LFxuICAgICAgXSkge1xuICAgICAgICByZWNvdmVyeU5vY2tzLm5vY2tFdGhMaWtlUmVjb3ZlcnkoYml0Z28sIG5vY2tUU1NEYXRhKTtcbiAgICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKGNvaW4pO1xuICAgICAgICBjb25zdCBiYXNlQWRkcmVzcyA9IGV0aExpa2VES0xTS2V5Y2FyZC5zZW5kZXJBZGRyZXNzO1xuICAgICAgICBjb25zdCBub2NrVFNTRGF0YVdpdGhCYXNlQWRkcmVzcyA9IG5vY2tUU1NEYXRhLm1hcCgoZGF0YSkgPT4ge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5kYXRhLFxuICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgIC4uLmRhdGEucGFyYW1zLFxuICAgICAgICAgICAgICBhZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvLCBub2NrVFNTRGF0YVdpdGhCYXNlQWRkcmVzcyk7XG4gICAgICAgIHJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgICAgIHVzZXJLZXk6IGV0aExpa2VES0xTS2V5Y2FyZC51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogZXRoTGlrZURLTFNLZXljYXJkLmJhY2t1cEtleSxcbiAgICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IGJhc2VBZGRyZXNzLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGV0aExpa2VES0xTS2V5Y2FyZC5kZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogZXRoTGlrZURLTFNLZXljYXJkLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgZWlwMTU1OToge1xuICAgICAgICAgICAgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDMsXG4gICAgICAgICAgICBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaXNUc3M6IHRydWUsXG4gICAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICAgIGNoYWluOiBjaGFpbixcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChjb2luID09PSAndGJzYycpIHtcbiAgICAgICAgICByZWNvdmVyeVBhcmFtcy5laXAxNTU5ID0gdW5kZWZpbmVkO1xuICAgICAgICAgIHJlY292ZXJ5UGFyYW1zWydnYXNQcmljZSddID0gMjAwMDAwMDAwMDA7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIocmVjb3ZlcnlQYXJhbXMpO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeSk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpZCcpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgICAvLyB2ZXJpZnkgZGF0YSBhZnRlciBzaWduaW5nIGlzIGNvcnJlY3RcbiAgICAgICAgY29uc3QgZmluYWxUeCA9IFRyYW5zYWN0aW9uRmFjdG9yeS5mcm9tU2VyaWFsaXplZERhdGEoQnVmZmVyLmZyb20ocmVjb3ZlcnkudHguc3Vic3RyKDIpLCAnaGV4JykpO1xuXG4gICAgICAgIGNvbnN0IHNlbmRlckFkZHJlc3MgPSBmaW5hbFR4LmdldFNlbmRlckFkZHJlc3MoKS50b1N0cmluZygpO1xuICAgICAgICBmaW5hbFR4LmNvbW1vbi5jaGFpbklkQk4oKS50b051bWJlcigpLnNob3VsZC5lcXVhbChjaGFpbik7XG4gICAgICAgIGJhc2VBZGRyZXNzLnNob3VsZC5lcXVhbChzZW5kZXJBZGRyZXNzKTtcbiAgICAgICAgcmVjb3ZlcnlQYXJhbXMucmVjb3ZlcnlEZXN0aW5hdGlvbi5zaG91bGQuZXF1YWwoZmluYWxUeC50bz8udG9TdHJpbmcoKSk7XG4gICAgICAgIE51bWJlcihmaW5hbFR4LnZhbHVlKS5zaG91bGQuZXF1YWwoOTkwMDAwMDAwMDAwMDAwMDAwKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29uc3RydWN0IGFuIHVuc2lnbmVkIHN3ZWVwIHR4IHdpdGggVFNTJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgcmVjb3ZlcnlOb2Nrcy5ub2NrRXRoTGlrZVJlY292ZXJ5KGJpdGdvLCBub2NrVW5zaWduZWRTd2VlcFRTU0RhdGEpO1xuXG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ2h0ZXRoJyk7XG5cbiAgICAgIGNvbnN0IHVzZXJLZXkgPVxuICAgICAgICAnMDIzNGViMzliMjJmZWQ1MjNlY2U3Yzc4ZGEyOWJhMWYxZGU1YjY0YTZlNDgwMTNlMDkxNGRlNzkzYmMxZGYwNTcwZTc3OWRlMDQ3NTg3MzI3MzRkOTdlNTRiNzgyYzhiMzM2MjgzODExYWY2YTJjNTdiZDgxNDM4Nzk4ZTFjMjQ0Nic7XG4gICAgICBjb25zdCBiYWNrdXBLZXkgPVxuICAgICAgICAnMDIzNGViMzliMjJmZWQ1MjNlY2U3Yzc4ZGEyOWJhMWYxZGU1YjY0YTZlNDgwMTNlMDkxNGRlNzkzYmMxZGYwNTcwZTc3OWRlMDQ3NTg3MzI3MzRkOTdlNTRiNzgyYzhiMzM2MjgzODExYWY2YTJjNTdiZDgxNDM4Nzk4ZTFjMjQ0Nic7XG5cbiAgICAgIHJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgICB1c2VyS2V5OiB1c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IGJhY2t1cEtleSxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiAnMHhlNzQwNmRjNDNkMTNmNjk4ZmI0MWEzNDVjNzc4M2QzOWE0YzJkMTkxJyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogJzB4YWMwNWRhNzg0NjQ1MjBhYTdjOWQ0YzE5YmQ3YTQ0MGIxMTFiMzA1NCcsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFLFxuICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgICAgZ2FzUHJpY2U6ICcyMDAwMDAwMDAwMCcsXG4gICAgICAgIGdhc0xpbWl0OiAnNTAwMDAwJyxcbiAgICAgICAgcmVwbGF5UHJvdGVjdGlvbk9wdGlvbnM6IHtcbiAgICAgICAgICBjaGFpbjogNDIsXG4gICAgICAgICAgaGFyZGZvcms6ICdsb25kb24nLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHJlY292ZXJ5UGFyYW1zKTtcbiAgICAgIHNob3VsZC5leGlzdCh0cmFuc2FjdGlvbik7XG4gICAgICBjb25zdCBvdXRwdXQgPSB0cmFuc2FjdGlvbiBhcyB1bmtub3duIGFzIFVuc2lnbmVkU3dlZXBUeE1QQ3YyO1xuICAgICAgb3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eFJlcXVlc3RzJyk7XG4gICAgICBvdXRwdXQudHhSZXF1ZXN0cy5zaG91bGQuaGF2ZS5sZW5ndGgoMSk7XG4gICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHJhbnNhY3Rpb25zJyk7XG4gICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnMuc2hvdWxkLmhhdmUubGVuZ3RoKDEpO1xuICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvaW4nKTtcbiAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndW5zaWduZWRUeCcpO1xuICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NlcmlhbGl6ZWRUeEhleCcpO1xuICAgICAgb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3NpZ25hYmxlSGV4Jyk7XG4gICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZGVyaXZhdGlvblBhdGgnKTtcbiAgICAgIG91dHB1dC50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmZWVJbmZvJyk7XG4gICAgICBvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncGFyc2VkVHgnKTtcbiAgICAgIGNvbnN0IHBhcnNlZFR4ID0gb3V0cHV0LnR4UmVxdWVzdHNbMF0udHJhbnNhY3Rpb25zWzBdLnVuc2lnbmVkVHgucGFyc2VkVHggYXMgeyBzcGVuZEFtb3VudDogc3RyaW5nIH07XG4gICAgICBwYXJzZWRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnc3BlbmRBbW91bnQnKTtcbiAgICAgIChvdXRwdXQudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5wYXJzZWRUeCBhcyB7IG91dHB1dHM6IGFueVtdIH0pLnNob3VsZC5oYXZlLnByb3BlcnR5KCdvdXRwdXRzJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyVmV0JywgZnVuY3Rpb24gKCkge1xuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuICAgIGxldCByZWNvdmVyeVBhcmFtcztcblxuICAgIGl0KCdzaG91bGQgY29uc3RydWN0IGEgcmVjb3ZlcnkgdHggd2l0aCBNUEN2MiBUU1MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R2ZXQnKTtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gZXRoTGlrZURLTFNLZXljYXJkLnNlbmRlckFkZHJlc3M7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tWZXRSZWNvdmVyeShiaXRnbywgYmFzZUFkZHJlc3MpO1xuICAgICAgcmVjb3ZlcnlQYXJhbXMgPSB7XG4gICAgICAgIHVzZXJLZXk6IGV0aExpa2VES0xTS2V5Y2FyZC51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IGV0aExpa2VES0xTS2V5Y2FyZC5iYWNrdXBLZXksXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogYmFzZUFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGV0aExpa2VES0xTS2V5Y2FyZC5kZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IGV0aExpa2VES0xTS2V5Y2FyZC53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBpc1RzczogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeSk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaWQnKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb25zdHJ1Y3QgYW4gdW5zaWduZWQgc3dlZXAgdHggd2l0aCBUU1MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tWZXRSZWNvdmVyeShiaXRnbywgJzB4YWQ4NDhkMmM5N2EwOGIyY2Q1ZTdmMjhmNzZlY2Q0NWRkMGY4MmUwZScpO1xuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0dmV0Jyk7XG5cbiAgICAgIGNvbnN0IHVuc2lnbmVkU3dlZXBSZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgYml0Z29LZXk6XG4gICAgICAgICAgJzAzZjU0OTgzYzUyOTgwMjY5N2Q5YTIzMjBkZWQyM2ViN2YxNTExOGZjYmEwMTE1NjM1NmMyMjY0ZjA0ZDMyYjRjYWE3N2ZjZjhjZjNmNzM1NDcwNzhlOTg0ZjI4Nzg3YzRjMWU2OTQ1ODYyMTRiNjA5ZTQ1YjZkZTljYzMyYWQ2ZTUnLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBldGhMaWtlREtMU0tleWNhcmQuZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHVuc2lnbmVkU3dlZXBSZWNvdmVyeVBhcmFtcyk7XG4gICAgICBzaG91bGQuZXhpc3QocmVjb3ZlcnkpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4SGV4Jyk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29pbicpO1xuICAgICAgcmVjb3ZlcnkuY29pbi5zaG91bGQuZXF1YWwoJ3R2ZXQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29uc3RydWN0IGEgdG9rZW4odnRobykgcmVjb3ZlcnkgdHggd2l0aCBNUEN2MiBUU1MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R2ZXQnKTtcbiAgICAgIGNvbnN0IGJhc2VBZGRyZXNzID0gZXRoTGlrZURLTFNLZXljYXJkLnNlbmRlckFkZHJlc3M7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tWZXRUb2tlblJlY292ZXJ5KGJpdGdvLCBiYXNlQWRkcmVzcyk7XG4gICAgICByZWNvdmVyeVBhcmFtcyA9IHtcbiAgICAgICAgdXNlcktleTogZXRoTGlrZURLTFNLZXljYXJkLnVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogZXRoTGlrZURLTFNLZXljYXJkLmJhY2t1cEtleSxcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiBiYXNlQWRkcmVzcyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZXRoTGlrZURLTFNLZXljYXJkLmRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogZXRoTGlrZURLTFNLZXljYXJkLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiAnMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNDU2RTY1NzI2Nzc5JyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3ZlcihyZWNvdmVyeVBhcmFtcyk7XG5cbiAgICAgIHNob3VsZC5leGlzdChyZWNvdmVyeSk7XG4gICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaWQnKTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb25zdHJ1Y3QgYW4gdW5zaWduZWQgc3dlZXAgdG9rZW4gdHgodnRobykgd2l0aCBUU1MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICByZWNvdmVyeU5vY2tzLm5vY2tWZXRUb2tlblJlY292ZXJ5KGJpdGdvLCAnMHhhZDg0OGQyYzk3YTA4YjJjZDVlN2YyOGY3NmVjZDQ1ZGQwZjgyZTBlJyk7XG4gICAgICBjb25zdCBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3R2ZXQnKTtcblxuICAgICAgY29uc3QgdW5zaWduZWRTd2VlcFJlY292ZXJ5UGFyYW1zID0ge1xuICAgICAgICBiaXRnb0tleTpcbiAgICAgICAgICAnMDNmNTQ5ODNjNTI5ODAyNjk3ZDlhMjMyMGRlZDIzZWI3ZjE1MTE4ZmNiYTAxMTU2MzU2YzIyNjRmMDRkMzJiNGNhYTc3ZmNmOGNmM2Y3MzU0NzA3OGU5ODRmMjg3ODdjNGMxZTY5NDU4NjIxNGI2MDllNDViNmRlOWNjMzJhZDZlNScsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGV0aExpa2VES0xTS2V5Y2FyZC5kZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiAnMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNDU2RTY1NzI2Nzc5JyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlY292ZXJ5ID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih1bnNpZ25lZFN3ZWVwUmVjb3ZlcnlQYXJhbXMpO1xuICAgICAgc2hvdWxkLmV4aXN0KHJlY292ZXJ5KTtcbiAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgIHJlY292ZXJ5LmNvaW4uc2hvdWxkLmVxdWFsKCd0dmV0Jyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=