@bitgo/sdk-api 1.69.2 → 1.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/package.json +7 -4
  2. package/dist/src/bitgoAPI.d.ts +8 -2
  3. package/dist/src/bitgoAPI.d.ts.map +1 -1
  4. package/dist/src/bitgoAPI.js +40 -19
  5. package/dist/src/types.d.ts +5 -0
  6. package/dist/src/types.d.ts.map +1 -1
  7. package/dist/src/types.js +1 -1
  8. package/dist/test/unit/api.d.ts +2 -0
  9. package/dist/test/unit/api.d.ts.map +1 -0
  10. package/dist/test/unit/api.js +158 -0
  11. package/dist/test/unit/bitgoAPI.d.ts +2 -0
  12. package/dist/test/unit/bitgoAPI.d.ts.map +1 -0
  13. package/dist/test/unit/bitgoAPI.js +393 -0
  14. package/dist/test/unit/encrypt.d.ts +2 -0
  15. package/dist/test/unit/encrypt.d.ts.map +1 -0
  16. package/dist/test/unit/encrypt.js +62 -0
  17. package/dist/test/unit/utils.d.ts +2 -0
  18. package/dist/test/unit/utils.d.ts.map +1 -0
  19. package/dist/test/unit/utils.js +65 -0
  20. package/dist/test/unit/v1/fixtures/accelerate-tx.d.ts +4 -0
  21. package/dist/test/unit/v1/fixtures/accelerate-tx.d.ts.map +1 -0
  22. package/dist/test/unit/v1/fixtures/accelerate-tx.js +53 -0
  23. package/dist/test/unit/v1/fixtures/index.d.ts +3 -0
  24. package/dist/test/unit/v1/fixtures/index.d.ts.map +1 -0
  25. package/dist/test/unit/v1/fixtures/index.js +24 -0
  26. package/dist/test/unit/v1/signPsbt.d.ts +2 -0
  27. package/dist/test/unit/v1/signPsbt.d.ts.map +1 -0
  28. package/dist/test/unit/v1/signPsbt.js +53 -0
  29. package/dist/test/unit/v1/wallet.d.ts +2 -0
  30. package/dist/test/unit/v1/wallet.d.ts.map +1 -0
  31. package/dist/test/unit/v1/wallet.js +1371 -0
  32. package/dist/tsconfig.tsbuildinfo +1 -0
  33. package/package.json +7 -4
  34. package/.eslintignore +0 -5
  35. package/CHANGELOG.md +0 -1321
@@ -0,0 +1,1371 @@
1
+ "use strict";
2
+ //
3
+ // Tests for Wallet
4
+ //
5
+ // Copyright 2014, BitGo, Inc. All Rights Reserved.
6
+ //
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ var __importDefault = (this && this.__importDefault) || function (mod) {
41
+ return (mod && mod.__esModule) ? mod : { "default": mod };
42
+ };
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ const fixtures_1 = require("./fixtures");
45
+ const Wallet = require('../../../src/v1/wallet');
46
+ const bitgoAPI_1 = require("../../../src/bitgoAPI");
47
+ const _ = __importStar(require("lodash"));
48
+ const sdk_core_1 = require("@bitgo/sdk-core");
49
+ const utxolib = __importStar(require("@bitgo/utxo-lib"));
50
+ const should = __importStar(require("should"));
51
+ const nock_1 = __importDefault(require("nock"));
52
+ const sinon = __importStar(require("sinon"));
53
+ const accelerate_tx_1 = require("./fixtures/accelerate-tx");
54
+ nock_1.default.disableNetConnect();
55
+ const TestBitGo = {
56
+ TEST_WALLET1_PASSCODE: 'iVWeATjqLS1jJShrPpETti0b',
57
+ };
58
+ describe('Wallet Prototype Methods', function () {
59
+ const fixtures = (0, accelerate_tx_1.getFixtures)();
60
+ let bitgo = new bitgoAPI_1.BitGoAPI({ env: 'test', clientConstants: { constants: {} } });
61
+ // bitgo.initializeTestVars();
62
+ const userKeypair = {
63
+ xprv: 'xprv9s21ZrQH143K2fJ91S4BRsupcYrE6mmY96fcX5HkhoTrrwmwjd16Cn87cWinJjByrfpojjx7ezsJLx7TAKLT8m8hM5Kax9YcoxnBeJZ3t2k',
64
+ xpub: 'xpub661MyMwAqRbcF9Nc7TbBo1rZAagiWEVPWKbDKThNG8zqjk76HAKLkaSbTn6dK2dQPfuD7xjicxCZVWvj67fP5nQ9W7QURmoMVAX8m6jZsGp',
65
+ rawPub: '02c103ac74481874b5ef0f385d12725e4f14aedc9e00bc814ce96f47f62ce7adf2',
66
+ rawPrv: '936c5af3f8af81f75cdad1b08f29e7d9c01e598e2db2d7be18b9e5a8646e87c6',
67
+ path: 'm',
68
+ walletSubPath: '/0/0',
69
+ };
70
+ const backupKeypair = {
71
+ xprv: 'xprv9s21ZrQH143K47sEkLkykgYmq1xF5ZWrPYhUZcmBpPFMQojvGUmEcr5jFXYGfr8CpFdpTvhQ7L9NN2rLtsBFjSix3BAjwJcBj6U3D5hxTPc',
72
+ xpub: 'xpub661MyMwAqRbcGbwhrNHz7pVWP3njV2Ehkmd5N1AoNinLHc54p25VAeQD6q2oTS3uuDMDnfnXnthbS9ufC8JVYpNnWU5Rn3pYaNuLCNywkw1',
73
+ rawPub: '03bbcb73997977068d9e36666bbd5cd37579acae8e2bd5ce9d0a6e5c150a423bc3',
74
+ rawPrv: '77a15f14796f4001d1092ae84f766bd869e9bee6bffae6547def5045b96fa943',
75
+ path: 'm',
76
+ walletSubPath: '/0/0',
77
+ };
78
+ const bitgoKey = {
79
+ xpub: 'xpub661MyMwAqRbcGQcVFiwcrtc7c3vopsX96jsJUYPcFMREcRTqAqsqbv2ZRyCJAPLm5NMHCy85E3ZwpT4EAUw9WGU7vMhG6z83hDeKXBWn6Lf',
80
+ path: 'm',
81
+ walletSubPath: '/0/0',
82
+ };
83
+ const fakeWallet = new Wallet(bitgo, {
84
+ id: '2NCoSfHH6Ls4CdTS5QahgC9k7x9RfXeSwY4',
85
+ private: { keychains: [userKeypair, backupKeypair, bitgoKey] },
86
+ });
87
+ describe('Generate Address', function () {
88
+ before(() => nock_1.default.pendingMocks().should.be.empty());
89
+ it('generate first address', function () {
90
+ const idAddress = fakeWallet.generateAddress({ path: '/0/0', segwit: false });
91
+ idAddress.address.should.equal(fakeWallet.id());
92
+ idAddress.chain.should.equal(0);
93
+ idAddress.index.should.equal(0);
94
+ idAddress.chainPath.should.equal('/0/0');
95
+ idAddress.path.should.equal('/0/0');
96
+ idAddress.outputScript.should.equal('a914d682476e9bd54454a885f9dff1e604e99cef43dc87');
97
+ idAddress.redeemScript.should.equal('522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae');
98
+ idAddress.wallet.should.equal(fakeWallet.id());
99
+ });
100
+ it('generate second address', function () {
101
+ const p2shAddress = fakeWallet.generateAddress({ path: '/0/1', segwit: false });
102
+ p2shAddress.address.should.equal('2N5y5RLVqdZi7qp5PmzMdPR6YvQzUqBQFWK');
103
+ p2shAddress.chain.should.equal(0);
104
+ p2shAddress.index.should.equal(1);
105
+ p2shAddress.chainPath.should.equal('/0/1');
106
+ p2shAddress.path.should.equal('/0/1');
107
+ p2shAddress.outputScript.should.equal('a9148b8bd3da68ef0f2465523146bd2de33c86b9c87187');
108
+ p2shAddress.redeemScript.should.equal('522102709edb6a2198d364c485a76b981d12065eabde8aa2d85bd7e7a035f7ecb3579b2102a724efed499c05fdb4da1e139700951fae00c006b3283888bdfd1b46979292242102b32abe44d61986ff57b835e3bd16293d93f303d0d8fb0454e2c9cceda5c4929853ae');
109
+ p2shAddress.wallet.should.equal(fakeWallet.id());
110
+ });
111
+ it('generate change address', function () {
112
+ const p2shAddress = fakeWallet.generateAddress({ path: '/1/0', segwit: false });
113
+ p2shAddress.address.should.equal('2NFj9JrpZc5MyYnCouyREtzNY4eoyKWDfgP');
114
+ p2shAddress.chain.should.equal(1);
115
+ p2shAddress.index.should.equal(0);
116
+ p2shAddress.chainPath.should.equal('/1/0');
117
+ p2shAddress.path.should.equal('/1/0');
118
+ p2shAddress.outputScript.should.equal('a914f69a81fad75ea65ad166da76515291679a4f1ad887');
119
+ p2shAddress.redeemScript.should.equal('5221020b4c4f891a5520f5a0b6818d8d53919552a0d4d806b5fa05c97708079d83737e2102c5cc49bf0331eb0b0890a7e7d87f7e9e0dea515438280dc76834c21d198efe08210370e52cf741ebf4513749d028839d696891eb789ba7a58592cfbc857cdc0a9de753ae');
120
+ p2shAddress.wallet.should.equal(fakeWallet.id());
121
+ });
122
+ it('generate segwit address', function () {
123
+ const segwitAddress = fakeWallet.generateAddress({ path: '/10/0', segwit: true });
124
+ segwitAddress.address.should.equal('2N5EVegRPWnmed2PpqDggZPw7DcNDguRYv8');
125
+ segwitAddress.chain.should.equal(10);
126
+ segwitAddress.index.should.equal(0);
127
+ segwitAddress.chainPath.should.equal('/10/0');
128
+ segwitAddress.path.should.equal('/10/0');
129
+ segwitAddress.outputScript.should.equal('a914837e2adcb6f6386fea3c5d40316b282ccf39121d87');
130
+ segwitAddress.redeemScript.should.equal('0020a62afee1d211c5adb9739f81ed4e36330e6cda651c7bdd314e32ccc465ec2203');
131
+ segwitAddress.witnessScript.should.equal('5221027b30505777a4ed8947b069fcb0116e287995d97278d84da4db6c613270649d3d21034c30e51f1e614cad667815c91d041404c18225d0b2f79e2c0bcb63fd2604316b2103b65ddfc06159b691693390761e75a0b8cc7a65b6ff305d094f3ad972f17953fe53ae');
132
+ segwitAddress.wallet.should.equal(fakeWallet.id());
133
+ });
134
+ });
135
+ describe('Create Transaction', function () {
136
+ let bgUrl, bgUrlTest;
137
+ let fakeProdWallet;
138
+ before(function () {
139
+ nock_1.default.pendingMocks().should.be.empty();
140
+ const prodBitgo = new bitgoAPI_1.BitGoAPI({ env: 'prod', clientConstants: { constants: {} } });
141
+ // prodBitgo.initializeTestVars();
142
+ bgUrl = sdk_core_1.common.Environments[prodBitgo.getEnv()].uri;
143
+ fakeProdWallet = new Wallet(prodBitgo, {
144
+ id: '2NCoSfHH6Ls4CdTS5QahgC9k7x9RfXeSwY4',
145
+ private: { keychains: [userKeypair, backupKeypair, bitgoKey] },
146
+ });
147
+ bgUrlTest = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
148
+ });
149
+ it('extra unspent fetch params', async function () {
150
+ const billingAddress = '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy';
151
+ const customUnspentsFetchParams = { test: 123 };
152
+ const sendAmount = 1e5;
153
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: billingAddress });
154
+ const scope = (0, nock_1.default)(bgUrl)
155
+ .get(`/api/v1/wallet/${fakeProdWallet.id()}/unspents`)
156
+ .query(_.merge(customUnspentsFetchParams, {
157
+ segwit: true,
158
+ target: sendAmount,
159
+ minSize: 0,
160
+ }))
161
+ .reply(200, { unspents: [] });
162
+ await fakeProdWallet
163
+ .createTransaction({
164
+ unspentsFetchParams: customUnspentsFetchParams,
165
+ recipients: { [billingAddress]: sendAmount },
166
+ feeRate: 10000,
167
+ bitgoFee: {
168
+ amount: 0,
169
+ address: '',
170
+ },
171
+ })
172
+ .should.be.rejectedWith('0 unspents available for transaction creation');
173
+ scope.isDone().should.be.true();
174
+ });
175
+ it('default p2sh', async function () {
176
+ const p2shAddress = fakeProdWallet.generateAddress({ path: '/0/13', segwit: false });
177
+ const unspent = {
178
+ addresses: ['2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X'],
179
+ value: '0.00504422',
180
+ value_int: 504422,
181
+ txid: 'b816ded89c3d8d5021b01097f4a3129a6a68a5cb7c886e97945f4205cba5de44',
182
+ n: 1,
183
+ script_pub_key: {
184
+ asm: 'OP_HASH160 d039cb3344294a5a384a5508a006444c420cbc11 OP_EQUAL',
185
+ hex: 'a914d039cb3344294a5a384a5508a006444c420cbc1187',
186
+ },
187
+ req_sigs: 1,
188
+ type: 'scripthash',
189
+ confirmations: 9,
190
+ id: 61330229,
191
+ };
192
+ _.extend(unspent, p2shAddress);
193
+ unspent.value = unspent.value_int;
194
+ unspent.tx_hash = unspent.txid;
195
+ unspent.tx_output_n = unspent.n;
196
+ unspent.script = unspent.outputScript;
197
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
198
+ const transaction = (await fakeProdWallet.createTransaction({
199
+ changeAddress: p2shAddress.address,
200
+ unspents: [unspent],
201
+ recipients: {},
202
+ noSplitChange: true,
203
+ forceChangeAtEnd: true,
204
+ feeRate: 10000,
205
+ bitgoFee: {
206
+ amount: 0,
207
+ address: '',
208
+ },
209
+ opReturns: { 'BitGo p2sh test': 1000 },
210
+ }));
211
+ transaction.transactionHex.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b80100000000ffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
212
+ // add first signature
213
+ transaction.keychain = userKeypair;
214
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
215
+ signature1.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000b600473044022021fa73d5fe61ac8942cd70ff4507c574677ce747de5bc46c3dd2e38ec2448fce022047906d2c0154337ab96041e8fb58c243b9bce5f8818fa991643c1260a1859ad80100004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
216
+ // add second signature
217
+ transaction.transactionHex = signature1.tx;
218
+ transaction.keychain = backupKeypair;
219
+ transaction.fullLocalSigning = true;
220
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
221
+ // This transaction has actually worked: https://testnet.smartbit.com.au/tx/a8ccb928169032d6e1f37bf81dfd9ab6d90362a4f84e577397fa690aa711550c
222
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
223
+ // changed, changing the output amounts and thus the tx hex.
224
+ signature2.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000fdfd0000473044022021fa73d5fe61ac8942cd70ff4507c574677ce747de5bc46c3dd2e38ec2448fce022047906d2c0154337ab96041e8fb58c243b9bce5f8818fa991643c1260a1859ad80147304402202ae01f01b5ae0c3fa7d67ac73db81932cb5aca10db16a99063fef45e3f1398cd022055001ba7e163cb350910fc7321ecd7eb6359b321d4c04887484d9c7284b78c4701004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
225
+ });
226
+ it('BCH p2sh', async function () {
227
+ const p2shAddress = fakeProdWallet.generateAddress({ path: '/0/13', segwit: false });
228
+ const unspent = {
229
+ addresses: ['2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X'],
230
+ value: '0.00504422',
231
+ value_int: 504422,
232
+ txid: 'b816ded89c3d8d5021b01097f4a3129a6a68a5cb7c886e97945f4205cba5de44',
233
+ n: 1,
234
+ script_pub_key: {
235
+ asm: 'OP_HASH160 d039cb3344294a5a384a5508a006444c420cbc11 OP_EQUAL',
236
+ hex: 'a914d039cb3344294a5a384a5508a006444c420cbc1187',
237
+ },
238
+ req_sigs: 1,
239
+ type: 'scripthash',
240
+ confirmations: 9,
241
+ id: 61330229,
242
+ };
243
+ _.extend(unspent, p2shAddress);
244
+ unspent.value = unspent.value_int;
245
+ unspent.tx_hash = unspent.txid;
246
+ unspent.tx_output_n = unspent.n;
247
+ unspent.script = unspent.outputScript;
248
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
249
+ const transaction = (await fakeProdWallet.createTransaction({
250
+ changeAddress: p2shAddress.address,
251
+ unspents: [unspent],
252
+ recipients: {},
253
+ noSplitChange: true,
254
+ forceChangeAtEnd: true,
255
+ feeRate: 10000,
256
+ bitgoFee: {
257
+ amount: 0,
258
+ address: '',
259
+ },
260
+ opReturns: { 'BitGo p2sh test': 1000 },
261
+ }));
262
+ transaction.transactionHex.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b80100000000ffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
263
+ // add first signature
264
+ transaction.keychain = userKeypair;
265
+ transaction.forceBCH = true;
266
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
267
+ signature1.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000b60047304402206221a97f081d87e02e3b14988a64861811a6a8de4f11f74f5aaea45981cf612e022077a08a5bd7d781e79838afbb126af2e48802fefad660afdbd8805f5e598ed5884100004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
268
+ // add second signature
269
+ transaction.transactionHex = signature1.tx;
270
+ transaction.keychain = backupKeypair;
271
+ transaction.fullLocalSigning = true;
272
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
273
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/a8ccb928169032d6e1f37bf81dfd9ab6d90362a4f84e577397fa690aa711550c
274
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
275
+ // changed, changing the output amounts and thus the tx hex.
276
+ signature2.tx.should.equal('010000000144dea5cb05425f94976e887ccba5686a9a12a3f49710b021508d3d9cd8de16b801000000fdfe000047304402206221a97f081d87e02e3b14988a64861811a6a8de4f11f74f5aaea45981cf612e022077a08a5bd7d781e79838afbb126af2e48802fefad660afdbd8805f5e598ed5884148304502210082bc546293858459f3895db24c85ccf37505c56f8faf4bb8f78cf40135bc2f2b02203dc1c78d7c7ceaf6b924eca3c39b95e8a227b069a07047581273136b47ca7ac441004c695221031cd227e40ad61b4e137109cb2845eb6f5a584ed5c67d9d3135cdaa5045a842ea2103a2e7b54c7b2da0992555353b8e26c6acff4248f4351f08787bf3e2efc94b658321025c2a6cde33c2d73ccf12eecf64c54f08f722c2f073824498950695e9883b141253aeffffffff02e803000000000000116a0f426974476f2070327368207465737422a107000000000017a914d039cb3344294a5a384a5508a006444c420cbc118700000000');
277
+ });
278
+ it('default segwit', async function () {
279
+ const segwitAddress = fakeProdWallet.generateAddress({ path: '/10/13', segwit: true });
280
+ const unspent = {
281
+ addresses: ['2MxKkH8yB3S9YWmTQRbvmborYQyQnH5petP'],
282
+ value: '0.18750000',
283
+ value_int: 18750000,
284
+ txid: '7d282878a85daee5d46e043827daed57596d75d1aa6e04fd0c09a36f9130881f',
285
+ n: 0,
286
+ script_pub_key: {
287
+ asm: 'OP_HASH160 37b393fce627a0ec634eb543dda1e608e2d1c78a OP_EQUAL',
288
+ hex: 'a91437b393fce627a0ec634eb543dda1e608e2d1c78a87',
289
+ },
290
+ req_sigs: 1,
291
+ type: 'scripthash',
292
+ confirmations: 0,
293
+ id: 61331617,
294
+ };
295
+ _.extend(unspent, segwitAddress);
296
+ unspent.value = unspent.value_int;
297
+ unspent.tx_hash = unspent.txid;
298
+ unspent.tx_output_n = unspent.n;
299
+ unspent.script = unspent.outputScript;
300
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
301
+ const transaction = (await fakeProdWallet.createTransaction({
302
+ changeAddress: segwitAddress.address,
303
+ unspents: [unspent],
304
+ recipients: {},
305
+ noSplitChange: true,
306
+ forceChangeAtEnd: true,
307
+ feeRate: 10000,
308
+ bitgoFee: {
309
+ amount: 0,
310
+ address: '',
311
+ },
312
+ opReturns: { 'BitGo segwit test': 1000 },
313
+ }));
314
+ transaction.transactionHex.should.equal('01000000011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000000ffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a8700000000');
315
+ // add first signature
316
+ transaction.keychain = userKeypair;
317
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
318
+ signature1.tx.should.equal('010000000001011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000023220020440e858228b753544b4c57e300296b55717f811053883f9be9b6a712eacd931cffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a870500483045022100bf3a8914a1bfe92661f27ca37c0d6b5c0b3c7353614c955646929f2e7eb89ffe02202d556b0ffab37c104bae67406ca16f8859cfa37c6a40f2013d89afcecd5594f3010000695221032c505fc8a1e4b56811b27366a371e61c9faf565dd2fabaff7a70eac19c32157c210251160b583bd5dc0f0d48096505131c4347ab65b4f21ed57d76c38157499c003d2102679712d62a2560917cc43fd2cc3a1b9b61f528c88bc64905bae6ee079e60609f53ae00000000');
319
+ // add second signature
320
+ transaction.transactionHex = signature1.tx;
321
+ transaction.keychain = backupKeypair;
322
+ transaction.fullLocalSigning = true;
323
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
324
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/d67266f1de905baaee750011fa4b3d88a8e3a1758d5173a659c67709488dde07
325
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
326
+ // changed, changing the output amounts and thus the tx hex.
327
+ signature2.tx.should.equal('010000000001011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000023220020440e858228b753544b4c57e300296b55717f811053883f9be9b6a712eacd931cffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a870500483045022100bf3a8914a1bfe92661f27ca37c0d6b5c0b3c7353614c955646929f2e7eb89ffe02202d556b0ffab37c104bae67406ca16f8859cfa37c6a40f2013d89afcecd5594f30147304402205cf8d2f2be6ce083d35654bdc3fa85d7e71b227d457e9245bb603b21e7b5165102203ea686226db8320e08c26bfb304048b3a9473d0e05797d3658dacb2f09a2b51c0100695221032c505fc8a1e4b56811b27366a371e61c9faf565dd2fabaff7a70eac19c32157c210251160b583bd5dc0f0d48096505131c4347ab65b4f21ed57d76c38157499c003d2102679712d62a2560917cc43fd2cc3a1b9b61f528c88bc64905bae6ee079e60609f53ae00000000');
328
+ });
329
+ it('creates an unsigned tx made of uncompressed public keys of v1 safe wallet', async function () {
330
+ const { address, redeemScript, scriptPubKey } = await (0, fixtures_1.getFixture)(`${__dirname}/fixtures/sign-transaction.json`);
331
+ const testBitgo = new bitgoAPI_1.BitGoAPI({ env: 'test', clientConstants: { constants: {} } });
332
+ const fakeTestV1SafeWallet = new Wallet(testBitgo, {
333
+ id: address,
334
+ private: { safe: { redeemScript } },
335
+ });
336
+ const unspentsToSpend = [
337
+ {
338
+ value: 100000,
339
+ redeemScript,
340
+ script: scriptPubKey,
341
+ tx_hash: 'a55d11dc8b701bd19601fbfe711a1e465fc8f128ec4474e78e1fd087e808e5fe',
342
+ tx_output_n: 0,
343
+ confirmations: 1,
344
+ },
345
+ {
346
+ value: 100000,
347
+ redeemScript,
348
+ script: scriptPubKey,
349
+ tx_hash: '48fb879cec879356045a331937023aed859f5dc5db955a1dc8a5ccf29f49d108',
350
+ tx_output_n: 0,
351
+ confirmations: 1,
352
+ },
353
+ ];
354
+ const recipients = {
355
+ '2MyGxrhLC4kRfuVjLqCVYFtC7DchhgMCiNz': 191340, // purposely set to simulate a sweep transaction
356
+ };
357
+ const scope = (0, nock_1.default)(bgUrlTest)
358
+ .post('/api/v1/billing/address')
359
+ .reply(200, { address: '2N3L9cu9WN2Df7Xvb1Y8owokuDVj5Hdyv4i' });
360
+ const result = await fakeTestV1SafeWallet.createTransaction({
361
+ recipients,
362
+ unspents: unspentsToSpend,
363
+ feeRate: 10000, // 10 sat/byte
364
+ bitgoFee: {
365
+ amount: 0,
366
+ address: '',
367
+ },
368
+ });
369
+ scope.isDone().should.be.true();
370
+ result.estimatedSize.should.equal(866);
371
+ result.fee.should.equal(8660);
372
+ // This should equal to 1 because this is a sweep transaction but due to hardcoded addition of
373
+ // 1 change output in transactionBuilder, it is 2.
374
+ // Because of this the estimated size of the transactions is more than what it actually is in the hex.
375
+ result.txInfo.nOutputs.should.equal(2);
376
+ });
377
+ it('signs an unsigned tx made of uncompressed public keys of v1 safe wallet & verifies signatures', async function () {
378
+ const { address, redeemScript, scriptPubKey, userKeyWIF: userSigningKey, bitgoKeyWIF: bitgoSigningKey, unsignedTxHex, halfSignedTxHex, fullSignedTxHex, } = await (0, fixtures_1.getFixture)(`${__dirname}/fixtures/sign-transaction.json`);
379
+ const testBitgo = new bitgoAPI_1.BitGoAPI({ env: 'test', clientConstants: { constants: {} } });
380
+ const fakeTestV1SafeWallet = new Wallet(testBitgo, {
381
+ id: address,
382
+ private: { safe: { redeemScript } },
383
+ });
384
+ const unspentsToSpend = [
385
+ { value: 100000, redeemScript, script: scriptPubKey },
386
+ { value: 100000, redeemScript, script: scriptPubKey },
387
+ ];
388
+ const halfSignedTx = await fakeTestV1SafeWallet.signTransaction({
389
+ transactionHex: unsignedTxHex,
390
+ signingKey: userSigningKey,
391
+ unspents: unspentsToSpend,
392
+ validate: true,
393
+ });
394
+ halfSignedTx.tx.should.equal(halfSignedTxHex);
395
+ const fullSignedTx = await fakeTestV1SafeWallet.signTransaction({
396
+ transactionHex: halfSignedTxHex,
397
+ signingKey: bitgoSigningKey,
398
+ unspents: unspentsToSpend,
399
+ validate: true,
400
+ fullLocalSigning: true,
401
+ });
402
+ // Upon calling txb.build() instead after getting 2 valid signatures, we get a valid full signed tx that was broadcast
403
+ // and confirmed on testnet here: https://mempool.space/testnet/tx/bde09f1bd5e6661c28d90e4c96291853e21ba15ab42f3e4a30719decb73e791b
404
+ // It's present in the fullSignedTxHexBuildComplete property of the fixture.
405
+ fullSignedTx.tx.should.equal(fullSignedTxHex);
406
+ });
407
+ it('BCH segwit should fail', async function () {
408
+ const segwitAddress = fakeProdWallet.generateAddress({ path: '/10/13', segwit: true });
409
+ const unspent = {
410
+ addresses: ['2MxKkH8yB3S9YWmTQRbvmborYQyQnH5petP'],
411
+ value: '0.18750000',
412
+ value_int: 18750000,
413
+ txid: '7d282878a85daee5d46e043827daed57596d75d1aa6e04fd0c09a36f9130881f',
414
+ n: 0,
415
+ script_pub_key: {
416
+ asm: 'OP_HASH160 37b393fce627a0ec634eb543dda1e608e2d1c78a OP_EQUAL',
417
+ hex: 'a91437b393fce627a0ec634eb543dda1e608e2d1c78a87',
418
+ },
419
+ req_sigs: 1,
420
+ type: 'scripthash',
421
+ confirmations: 0,
422
+ id: 61331617,
423
+ };
424
+ _.extend(unspent, segwitAddress);
425
+ unspent.value = unspent.value_int;
426
+ unspent.tx_hash = unspent.txid;
427
+ unspent.tx_output_n = unspent.n;
428
+ unspent.script = unspent.outputScript;
429
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, { address: '2MswQjkvN6oWYdE7L2brJ5cAAMjPmG59oco' });
430
+ const transaction = (await fakeProdWallet.createTransaction({
431
+ changeAddress: segwitAddress.address,
432
+ unspents: [unspent],
433
+ recipients: {},
434
+ noSplitChange: true,
435
+ forceChangeAtEnd: true,
436
+ feeRate: 10000,
437
+ bitgoFee: {
438
+ amount: 0,
439
+ address: '',
440
+ },
441
+ opReturns: { 'BitGo segwit test': 1000 },
442
+ }));
443
+ transaction.transactionHex.should.equal('01000000011f8830916fa3090cfd046eaad1756d5957edda2738046ed4e5ae5da87828287d0000000000ffffffff02e803000000000000136a11426974476f2073656777697420746573740e0f1e010000000017a91437b393fce627a0ec634eb543dda1e608e2d1c78a8700000000');
444
+ // add first signature
445
+ transaction.keychain = userKeypair;
446
+ transaction.forceBCH = true;
447
+ (() => fakeProdWallet.signTransaction(transaction)).should.throw('BCH does not support segwit inputs');
448
+ });
449
+ it('mixed p2sh & segwit', async function () {
450
+ const p2shAddress = fakeWallet.generateAddress({ path: '/0/14', segwit: false });
451
+ const segwitAddress = fakeWallet.generateAddress({ path: '/10/14', segwit: true });
452
+ const p2shUnspent = {
453
+ addresses: ['2N533fqgyPYKVD892nBRaYmFHbbTykhYSEw'],
454
+ value: '2.99996610',
455
+ value_int: 299996610,
456
+ txid: 'f654ce0a5be3f12df7fecf4ee777b6d86b5aa8c710ef6946ec121206b4f8757c',
457
+ n: 1,
458
+ script_pub_key: {
459
+ asm: 'OP_HASH160 8153e7a35508088b6cf599226792c7de2dbff252 OP_EQUAL',
460
+ hex: 'a9148153e7a35508088b6cf599226792c7de2dbff25287',
461
+ },
462
+ req_sigs: 1,
463
+ type: 'scripthash',
464
+ confirmations: 0,
465
+ id: 61331263,
466
+ };
467
+ const segwitUnspent = {
468
+ addresses: ['2NBtpXcDruf3zRutmF4AbCMFNQHXsGNP6kT'],
469
+ value: '1.50000000',
470
+ value_int: 150000000,
471
+ txid: 'a4409c3f042fae67b890ac3df40ef0db03539c67331fd7e9260511893b4f9f24',
472
+ n: 0,
473
+ script_pub_key: {
474
+ asm: 'OP_HASH160 cc8e7cbf481389d3183a590acfa6aa66eb97c8e1 OP_EQUAL',
475
+ hex: 'a914cc8e7cbf481389d3183a590acfa6aa66eb97c8e187',
476
+ },
477
+ req_sigs: 1,
478
+ type: 'scripthash',
479
+ confirmations: 0,
480
+ id: 61330882,
481
+ };
482
+ const addresses = [p2shAddress, segwitAddress];
483
+ const unspents = [p2shUnspent, segwitUnspent].map((unspent, index) => {
484
+ const address = addresses[index];
485
+ _.extend(unspent, address);
486
+ unspent.value = unspent.value_int;
487
+ unspent.tx_hash = unspent.txid;
488
+ unspent.tx_output_n = unspent.n;
489
+ unspent.script = unspent.outputScript;
490
+ return unspent;
491
+ });
492
+ const transaction = (await fakeWallet.createTransaction({
493
+ changeAddress: p2shAddress.address,
494
+ unspents: unspents,
495
+ recipients: {},
496
+ noSplitChange: true,
497
+ forceChangeAtEnd: true,
498
+ feeRate: 10000,
499
+ opReturns: { 'BitGo mixed p2sh & segwit test': 400000000 },
500
+ bitgoFee: {
501
+ amount: 81760,
502
+ address: '2ND7jQR5itjGTbh3DKgbpZWSY9ungDrwcwb',
503
+ },
504
+ }));
505
+ transaction.transactionHex.should.equal('01000000027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f60100000000ffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a40000000000ffffffff030084d71700000000206a1e426974476f206d6978656420703273682026207365677769742074657374b08ff9020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700000000');
506
+ // add first signature
507
+ transaction.keychain = userKeypair;
508
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
509
+ signature1.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000b700483045022100ffc45d93cbaf4c1c850e21f277c5b311d3e3957f1338955cb165d72a768a054c022052020593b36781eea00a9f8dcbeb76608f920c7a933a9088318ab2f70c11e1d90100004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff030084d71700000000206a1e426974476f206d6978656420703273682026207365677769742074657374b08ff9020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700050047304402205898bee711467c09a5e22e1dcb1a11fce1a0d6ea129d911f813f87c7d45e067b02202f69fb118bbf0b072ed26d72cf8073e7acd66c205419a4a00f86a7ba0f6e3dd6010000695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
510
+ // add second signature
511
+ transaction.transactionHex = signature1.tx;
512
+ transaction.keychain = backupKeypair;
513
+ transaction.fullLocalSigning = true;
514
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
515
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/e2f696bcba91a376c36bb525df8c367938f6e2fd6344c90587bf12802091124c
516
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
517
+ // changed, changing the output amounts and thus the tx hex.
518
+ signature2.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000fdff0000483045022100ffc45d93cbaf4c1c850e21f277c5b311d3e3957f1338955cb165d72a768a054c022052020593b36781eea00a9f8dcbeb76608f920c7a933a9088318ab2f70c11e1d9014830450221008254d100401a3a831ed019e1662dbd90b96c6c4072b81ce640d152bc29295c10022013f86c5af5716234999a7bd6e94fc8f428f7697cc3138b3649d0ec4dd8681bc701004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff030084d71700000000206a1e426974476f206d6978656420703273682026207365677769742074657374b08ff9020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700050047304402205898bee711467c09a5e22e1dcb1a11fce1a0d6ea129d911f813f87c7d45e067b02202f69fb118bbf0b072ed26d72cf8073e7acd66c205419a4a00f86a7ba0f6e3dd60147304402207713d671b45989688e2665c2b11ab7e5ea8d57eb14f9da233c095dabe441308d022069521b5aeb071b07a70a7197a0c2bbc40a23ae63a04160cf3627250c4ba4c40f0100695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
519
+ });
520
+ it('should send to bech32 recipient', async function () {
521
+ const p2shAddress = fakeWallet.generateAddress({ path: '/0/14', segwit: false });
522
+ const segwitAddress = fakeWallet.generateAddress({ path: '/10/14', segwit: true });
523
+ const p2shUnspent = {
524
+ addresses: ['2N533fqgyPYKVD892nBRaYmFHbbTykhYSEw'],
525
+ value: '2.99996610',
526
+ value_int: 299996610,
527
+ txid: 'f654ce0a5be3f12df7fecf4ee777b6d86b5aa8c710ef6946ec121206b4f8757c',
528
+ n: 1,
529
+ script_pub_key: {
530
+ asm: 'OP_HASH160 8153e7a35508088b6cf599226792c7de2dbff252 OP_EQUAL',
531
+ hex: 'a9148153e7a35508088b6cf599226792c7de2dbff25287',
532
+ },
533
+ req_sigs: 1,
534
+ type: 'scripthash',
535
+ confirmations: 0,
536
+ id: 61331263,
537
+ };
538
+ const segwitUnspent = {
539
+ addresses: ['2NBtpXcDruf3zRutmF4AbCMFNQHXsGNP6kT'],
540
+ value: '1.50000000',
541
+ value_int: 150000000,
542
+ txid: 'a4409c3f042fae67b890ac3df40ef0db03539c67331fd7e9260511893b4f9f24',
543
+ n: 0,
544
+ script_pub_key: {
545
+ asm: 'OP_HASH160 cc8e7cbf481389d3183a590acfa6aa66eb97c8e1 OP_EQUAL',
546
+ hex: 'a914cc8e7cbf481389d3183a590acfa6aa66eb97c8e187',
547
+ },
548
+ req_sigs: 1,
549
+ type: 'scripthash',
550
+ confirmations: 0,
551
+ id: 61330882,
552
+ };
553
+ const addresses = [p2shAddress, segwitAddress];
554
+ const unspents = [p2shUnspent, segwitUnspent].map((unspent, index) => {
555
+ const address = addresses[index];
556
+ _.extend(unspent, address);
557
+ unspent.value = unspent.value_int;
558
+ unspent.tx_hash = unspent.txid;
559
+ unspent.tx_output_n = unspent.n;
560
+ unspent.script = unspent.outputScript;
561
+ return unspent;
562
+ });
563
+ const transaction = (await fakeWallet.createTransaction({
564
+ changeAddress: p2shAddress.address,
565
+ unspents: unspents,
566
+ recipients: { tb1qguzyk4w6kaqtpsczs5aj0w8r7598jq36egm8e98wqph3rwmex68seslgsg: 300000 },
567
+ noSplitChange: true,
568
+ forceChangeAtEnd: true,
569
+ feeRate: 10000,
570
+ opReturns: { 'BitGo mixed p2sh & segwit test': 400000000 },
571
+ bitgoFee: {
572
+ amount: 81760,
573
+ address: '2ND7jQR5itjGTbh3DKgbpZWSY9ungDrwcwb',
574
+ },
575
+ }));
576
+ transaction.transactionHex.should.equal('01000000027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f60100000000ffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a40000000000ffffffff04e09304000000000022002047044b55dab740b0c302853b27b8e3f50a79023aca367c94ee006f11bb79368f0084d71700000000206a1e426974476f206d69786564207032736820262073656777697420746573747cfaf4020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba98700000000');
577
+ // add first signature
578
+ transaction.keychain = userKeypair;
579
+ const signature1 = (await fakeProdWallet.signTransaction(transaction));
580
+ signature1.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000b7004830450221008809377634e667d6e19f38a138a55b2b6370312af76a5ca3b776df61fc719617022021d90347b9085ab71a76c8400f984e322c15451ecc673dd37de30887436d37b40100004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff04e09304000000000022002047044b55dab740b0c302853b27b8e3f50a79023aca367c94ee006f11bb79368f0084d71700000000206a1e426974476f206d69786564207032736820262073656777697420746573747cfaf4020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba9870005004830450221008b95ac83e44c727b79ffbf4571171925d06f883a05c122b3b33c055f0bffa70102207b5ee3412ea8a5cec4a5c386f1b464ab68d531c6c697077bc462c05eb44a2832010000695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
581
+ // add second signature
582
+ transaction.transactionHex = signature1.tx;
583
+ transaction.keychain = backupKeypair;
584
+ transaction.fullLocalSigning = true;
585
+ const signature2 = (await fakeProdWallet.signTransaction(transaction));
586
+ console.log('signature1 ' + JSON.stringify(signature2));
587
+ // this transaction has actually worked: https://testnet.smartbit.com.au/tx/e2f696bcba91a376c36bb525df8c367938f6e2fd6344c90587bf12802091124c
588
+ // Note that the tx hex below no longer corresponds to the above transaction because our fee estimation has
589
+ // changed, changing the output amounts and thus the tx hex.
590
+ signature2.tx.should.equal('010000000001027c75f8b4061212ec4669ef10c7a85a6bd8b677e74ecffef72df1e35b0ace54f601000000fdfe00004830450221008809377634e667d6e19f38a138a55b2b6370312af76a5ca3b776df61fc719617022021d90347b9085ab71a76c8400f984e322c15451ecc673dd37de30887436d37b40147304402205a58e602042b8e8a5da509d19ce31050147dd0ffcfbe2bb337c23d4c88f4cc41022075bfa455d1f74e30fbd9c786cd4811a1defe54310f235b4193ce4ffa0e8309a101004c69522103da95b28a13aa2d4bb490d70628e2e5d912461d375fef381aadd89dc1256220752103121287a510c5f32e8ba72d2479e90eb52ba44a467173df339feb0ff215f100e32102977cdfbee76066ae739db72d55371ad49dc6712fb8f2f3f69bb1a4c2422b0b1a53aeffffffff249f4f3b89110526e9d71f33679c5303dbf00ef43dac90b867ae2f043f9c40a400000000232200208b91aa03eb0f7f31e3917088084168ba5282a915e7cde0a5a934b7ea02eb057bffffffff04e09304000000000022002047044b55dab740b0c302853b27b8e3f50a79023aca367c94ee006f11bb79368f0084d71700000000206a1e426974476f206d69786564207032736820262073656777697420746573747cfaf4020000000017a9148153e7a35508088b6cf599226792c7de2dbff25287603f01000000000017a914d9f7be47975c036f94228b0bfd70701912758ba9870005004830450221008b95ac83e44c727b79ffbf4571171925d06f883a05c122b3b33c055f0bffa70102207b5ee3412ea8a5cec4a5c386f1b464ab68d531c6c697077bc462c05eb44a283201473044022053690234582a6911a28cae9f534c980b7d7918749a7413c1c59327debf16ff0b022056175f5c27a363416b2ce4791aefc3d55545cacbd0527202e869e1127fc2f24d0100695221030780186c0be5df0d2d62cf54cc2f3d2c09911e377aa95b5fe875fa352aed0a592103f3237edd2d87010e8fe9f43f34e8c63de6384283de909795d62af4ddb4d579542102ad03de5504ef947e4e6ee2fa6b15d150d553c21275f49f2ce2359d9fdedb9ade53ae00000000');
591
+ });
592
+ });
593
+ describe('Send Many', function () {
594
+ it('responds with proper fee and fee rate', async function () {
595
+ const params = {
596
+ recipients: [
597
+ {
598
+ address: '2MutpXVYs8Lyk74pVDn3eAG7xnK4Wc2kjTQ',
599
+ amount: 300000,
600
+ },
601
+ ],
602
+ };
603
+ const unspents = [
604
+ {
605
+ value: 8170,
606
+ },
607
+ {
608
+ value: 800000,
609
+ },
610
+ ];
611
+ const createAndSignResponse = {
612
+ bitgoFee: 0,
613
+ travelInfos: [],
614
+ unspents,
615
+ tx: 'halfsignedhex',
616
+ };
617
+ sinon.stub(fakeWallet, 'createAndSignTransaction').returns(Promise.resolve(createAndSignResponse));
618
+ const getSendTxResponse = () => ({
619
+ status: 'accepted',
620
+ tx: '0100000000010228b5c3e2789d4770fc397ec79fa7255f86235297c5a04def678b481b8b09e81b0100000023220020b3bbe067960be39501f365b8999d53f2a8285d8d9836f61fad020e6a4a9e26fdffffffff1510e90411a86c49f2a52546a32a03febde2bc604741f0e85dc47adec33f515900000000fdfd0000483045022100a44bbf97b155c57703862be69d2b20c4b2ab9e94f402595880bf74402ccc87e202200a4aaf98f939b65c98ca08eb96074c222ecb1fc37e359b1d67a05f1c56dedfc001473044022003f3989a14284f132bbb550118c20256d4ea737704123a29955acc1d03ea6eb7022017223da7edcf73076d89875aa33360aa6a12141807f683c6c1b9a5a0d3ff6019014c695221025789857cc8be110ff4cbf354b52dd0e7e9326c6bfe0aee6c30c1ee69660c3dc02102f58f1b1516d05814ae688ca701856695e27050e3e16d3a2351284d7af84498882102385c7bcec3f38c13e87b558aebf2f20a8928e7ecbe11e7c3a47792bc8e33fe8853aeffffffff02e09304000000000017a9141d0c791cec3af1f37808d42f04593095d6fdea268705bc07000000000017a914d8c720f646c7c56c5467248e47c72dc0b2d30bbc87040047304402201eaa1359fffd3bdec5b48268bd2f15193a299c22b1970356f390883473324651022074186232f02245af9c0977031448c2c99e7b7e2b05b2ba4b32c3227d8ca1494e01483045022100bd61b37051c28533ea0b00dda75b1c4f1dee1b683bb7351b2d8dd720f6dfbe1102203acc4cf9d2dd44b294aa25812e99e7d8eb3730e4ff6f889d3cdcd525195750b8016952210219d093c18c27cb547737b4a49dddac9c3412b10e9f880eb30053c3eba81928542103747118892cac1b4da11526fc4ebeebe168dae0907cefb1a1812541cd46b07602210339f73b6750f8f91efd484b5aa2974321a6cc2776d5bd78b9cfb5fe18e3b2d66253ae005a9e1600',
621
+ hash: 'f8df43c2c650b3bb11277aee4531db99a715fa3b9dfd3d45a8d171342c1bf780',
622
+ instant: false,
623
+ });
624
+ const expectedResult = Object.assign({
625
+ fee: 1285,
626
+ feeRate: 2519.607843137255,
627
+ }, getSendTxResponse());
628
+ sinon.stub(fakeWallet, 'sendTransaction').resolves(getSendTxResponse());
629
+ const result = (await fakeWallet.sendMany(params));
630
+ result.tx.should.equal(expectedResult.tx);
631
+ result.fee.should.equal(expectedResult.fee);
632
+ result.feeRate.should.equal(expectedResult.feeRate);
633
+ });
634
+ });
635
+ describe('Accelerate Transaction (server mocked)', function accelerateTxMockedDescribe() {
636
+ let wallet;
637
+ let bgUrl;
638
+ let explorerUrl;
639
+ let minChangeSize;
640
+ let parentTxId = '6a74b74df4991d93c32d751336c85b5f2d1ee544a2dfbae2e5f4beb4f914e5e0';
641
+ const outputIdx = 0;
642
+ const outputAddress = '2NCoSfHH6Ls4CdTS5QahgC9k7x9RfXeSwY4';
643
+ const unrelatedTxId = '08f5e0b4acb5ab8245229dfe161ce4ca0da1ec983e7a34b09e72f56979a467df';
644
+ const walletId = '2NCoSfHH6Ls4CdTS5QahgC9k7x9RfXeSwY4';
645
+ /**
646
+ * Helper function to get the parent transaction ID from a transaction input
647
+ *
648
+ * This function converts `hash` (which is a Buffer object) to a usable txid string.
649
+ * The issue is that the bytes are stored in reverse order in the buffer, so
650
+ * the simple approach of just comparing the hex strings doesn't work.
651
+ * Instead, the Buffer is copied to a new Buffer object, the new Buffer
652
+ * object is reversed in-place, and then the new Buffer is converted to a
653
+ * hex string. After this, the result is a hex string which is the parent txid
654
+ *
655
+ * @param hash a bitcoinjs-lib transaction object's input hash
656
+ */
657
+ function inputParentTxId({ hash }) {
658
+ return Buffer.from(hash).reverse().toString('hex');
659
+ }
660
+ before(function accelerateTxMockedBefore() {
661
+ nock_1.default.pendingMocks().should.be.empty();
662
+ bitgo = new bitgoAPI_1.BitGoAPI({ env: 'mock', clientConstants: { constants: {} } });
663
+ // bitgo.initializeTestVars();
664
+ bitgo.setValidate(false);
665
+ wallet = new Wallet(bitgo, { id: walletId, private: { keychains: [userKeypair, backupKeypair, bitgoKey] } });
666
+ wallet.bitgo = bitgo;
667
+ bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
668
+ explorerUrl = sdk_core_1.common.Environments[bitgo.getEnv()].btcExplorerBaseUrl;
669
+ // try to get the min change size from the server, otherwise default to 0.1 BTC
670
+ // TODO: minChangeSize is not currently a constant defined on the client and should be added
671
+ minChangeSize = 1e7;
672
+ });
673
+ after(function accelerateTxMockedAfter() {
674
+ // make sure all nocks are cleared or consumed after the tests are complete
675
+ nock_1.default.pendingMocks().should.be.empty();
676
+ });
677
+ it('arguments', async () => {
678
+ await wallet.accelerateTransaction({ feeRate: 123 }).should.be.rejectedWith(/^Missing parameter: transactionID$/);
679
+ await wallet
680
+ .accelerateTransaction({ transactionID: 123, feeRate: 123 })
681
+ .should.be.rejectedWith(/^Expecting parameter string: transactionID but found number$/);
682
+ await wallet
683
+ .accelerateTransaction({ transactionID: '123' })
684
+ .should.be.rejectedWith(/^Missing parameter: feeRate$/);
685
+ const feeRatesParams = ['123', 0, -10, -Infinity, Infinity, NaN];
686
+ for (const feeRate of feeRatesParams) {
687
+ await wallet
688
+ .accelerateTransaction({ transactionID: '123', feeRate })
689
+ .should.be.rejectedWith(/^Expecting positive finite number for parameter: feeRate$/);
690
+ }
691
+ });
692
+ describe('bad input', function badInputDescribe() {
693
+ after(() => {
694
+ // make sure all nocks are cleared or consumed after the tests are complete
695
+ nock_1.default.pendingMocks().should.be.empty();
696
+ });
697
+ it('non existent transaction ID', async () => {
698
+ (0, nock_1.default)(bgUrl)
699
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
700
+ .reply(404, 'transaction not found on this wallet');
701
+ await wallet
702
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 123 })
703
+ .should.be.rejectedWith(/^404\ntransaction not found on this wallet$/);
704
+ });
705
+ it('confirmed transaction', async () => {
706
+ (0, nock_1.default)(bgUrl).get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`).reply(200, {
707
+ confirmations: 6,
708
+ });
709
+ await wallet
710
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
711
+ .should.be.rejectedWith(/^Transaction [0-9a-f]+ is already confirmed and cannot be accelerated$/);
712
+ });
713
+ it('no outputs to wallet', async () => {
714
+ (0, nock_1.default)(bgUrl)
715
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
716
+ .reply(200, {
717
+ outputs: [
718
+ {
719
+ account: outputAddress,
720
+ value: 1890000,
721
+ vout: 0,
722
+ chain: 0,
723
+ },
724
+ ],
725
+ confirmations: 0,
726
+ });
727
+ await wallet
728
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
729
+ .should.be.rejectedWith(/^Transaction [0-9a-f]+ contains no outputs to this wallet, and thus cannot be accelerated$/);
730
+ });
731
+ /*
732
+ * This test covers the case where a failure occurs during the process of
733
+ * converting an output from the parent transaction into an unspent which
734
+ * can be used to chain the child tx to the parent.
735
+ *
736
+ * This should never happen, but it is possible (for example, in the case
737
+ * of an attempted double spend of the output from the parent, or a race
738
+ * between finding the parent output, and retrieving the corresponding unspent).
739
+ */
740
+ it('cannot find correct unspent to use', async () => {
741
+ (0, nock_1.default)(bgUrl)
742
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
743
+ .reply(200, {
744
+ outputs: [
745
+ {
746
+ account: outputAddress,
747
+ value: 50 * 1e4,
748
+ vout: outputIdx,
749
+ isMine: true,
750
+ chain: 0,
751
+ },
752
+ ],
753
+ confirmations: 0,
754
+ hex: parentTxId,
755
+ fee: 10,
756
+ });
757
+ (0, nock_1.default)(bgUrl).get(`/api/v1/wallet/${wallet.id()}/unspents`).query(true).reply(200, {
758
+ count: 0,
759
+ unspents: [],
760
+ });
761
+ await wallet
762
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
763
+ .should.be.rejectedWith(/^Could not find unspent output from parent tx to use as child input$/);
764
+ });
765
+ it('Detects when an incorrect tx hex is returned by the external service', async () => {
766
+ (0, nock_1.default)(bgUrl)
767
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
768
+ .reply(200, {
769
+ outputs: [
770
+ {
771
+ account: outputAddress,
772
+ value: 10,
773
+ vout: outputIdx,
774
+ isMine: true,
775
+ chain: 0,
776
+ },
777
+ ],
778
+ confirmations: 0,
779
+ hex: fixtures[parentTxId],
780
+ fee: 10,
781
+ });
782
+ (0, nock_1.default)(bgUrl)
783
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
784
+ .query(true)
785
+ .reply(200, {
786
+ count: 1,
787
+ unspents: [
788
+ {
789
+ tx_hash: parentTxId,
790
+ tx_output_n: outputIdx,
791
+ },
792
+ ],
793
+ });
794
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[unrelatedTxId]);
795
+ await wallet
796
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
797
+ .should.be.rejectedWith(/^Decoded transaction id is [0-9a-f]+, which does not match given txid [0-9a-f]+$/);
798
+ });
799
+ it('cannot cover child fee with one parent output and one wallet unspent', async () => {
800
+ (0, nock_1.default)(bgUrl)
801
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
802
+ .reply(200, {
803
+ outputs: [
804
+ {
805
+ account: outputAddress,
806
+ value: 10,
807
+ vout: outputIdx,
808
+ isMine: true,
809
+ chain: 0,
810
+ },
811
+ ],
812
+ confirmations: 0,
813
+ hex: fixtures[parentTxId],
814
+ fee: 10,
815
+ });
816
+ (0, nock_1.default)(bgUrl)
817
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
818
+ .query(true)
819
+ .reply(200, {
820
+ count: 1,
821
+ unspents: [
822
+ {
823
+ tx_hash: parentTxId,
824
+ tx_output_n: outputIdx,
825
+ },
826
+ ],
827
+ });
828
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
829
+ (0, nock_1.default)(bgUrl).get(`/api/v1/wallet/${wallet.id()}/unspents`).query(true).reply(200, {
830
+ count: 0,
831
+ unspents: [],
832
+ });
833
+ await wallet
834
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
835
+ .should.be.rejectedWith(/^Insufficient confirmed unspents available to cover the child fee$/);
836
+ });
837
+ it('cannot lower fee rate', async () => {
838
+ (0, nock_1.default)(bgUrl)
839
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
840
+ .reply(200, {
841
+ outputs: [
842
+ {
843
+ account: outputAddress,
844
+ value: 10,
845
+ vout: outputIdx,
846
+ isMine: true,
847
+ chain: 11,
848
+ },
849
+ ],
850
+ confirmations: 0,
851
+ hex: fixtures[parentTxId],
852
+ fee: 10000, // large fee, and thus fee rate, for parent
853
+ });
854
+ (0, nock_1.default)(bgUrl)
855
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
856
+ .query(true)
857
+ .reply(200, {
858
+ count: 1,
859
+ unspents: [
860
+ {
861
+ tx_hash: parentTxId,
862
+ tx_output_n: outputIdx,
863
+ },
864
+ ],
865
+ });
866
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
867
+ await wallet
868
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2000 })
869
+ .should.be.rejectedWith(/^Cannot lower fee rate! \(Parent tx fee rate is \d+\.?\d* sat\/kB, and requested fee rate was \d+\.?\d* sat\/kB\)$/);
870
+ });
871
+ it('cannot break maximum fee limit for combined transaction', async () => {
872
+ (0, nock_1.default)(bgUrl)
873
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
874
+ .reply(200, {
875
+ outputs: [
876
+ {
877
+ account: outputAddress,
878
+ value: 3e7,
879
+ vout: outputIdx,
880
+ isMine: true,
881
+ chain: 11,
882
+ },
883
+ ],
884
+ confirmations: 0,
885
+ hex: fixtures[parentTxId],
886
+ fee: 1000,
887
+ });
888
+ (0, nock_1.default)(bgUrl)
889
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
890
+ .query(true)
891
+ .reply(200, {
892
+ count: 1,
893
+ unspents: [
894
+ {
895
+ tx_hash: parentTxId,
896
+ tx_output_n: outputIdx,
897
+ },
898
+ ],
899
+ });
900
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
901
+ await wallet
902
+ .accelerateTransaction({ transactionID: parentTxId, feeRate: 2e6 })
903
+ .should.be.rejectedWith(/^Transaction cannot be accelerated\. Combined fee rate of \d+\.?\d* sat\/kB exceeds maximum fee rate of \d+\.?\d* sat\/kB$/);
904
+ });
905
+ });
906
+ describe('successful tx acceleration', function successfulTxDescribe() {
907
+ const feeRate = 20000;
908
+ beforeEach(() => {
909
+ (0, nock_1.default)(bgUrl).post(`/api/v1/wallet/${wallet.id()}/address/1`).reply(200, {
910
+ address: '2NCYjG8Q56yr8tx9jazNoYnGKxjgB2MQSfY',
911
+ });
912
+ (0, nock_1.default)(bgUrl).post('/api/v1/billing/address').reply(200, {
913
+ address: '2NFbvo2HK4eXZm1aqDcSDGGqD64FPt7T6d8',
914
+ });
915
+ (0, nock_1.default)(bgUrl).get('/api/v1/tx/fee').query(true).reply(200, {
916
+ feePerKb: 0,
917
+ });
918
+ (0, nock_1.default)(bgUrl)
919
+ .post(`/api/v1/keychain/${userKeypair.xpub}`, {})
920
+ .reply(200, {
921
+ encryptedXprv: bitgo.encrypt({ input: userKeypair.xprv, password: TestBitGo.TEST_WALLET1_PASSCODE }),
922
+ path: userKeypair.path + userKeypair.walletSubPath,
923
+ });
924
+ });
925
+ it('accelerates a stuck tx without additional unspents', async () => {
926
+ parentTxId = '75cfc5a7b214c4b73c92c7b02608cde70b226767a9576f84c04407e43fd385bd';
927
+ (0, nock_1.default)(bgUrl)
928
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
929
+ .reply(200, {
930
+ fee: 434,
931
+ outputs: [
932
+ {
933
+ vout: 0,
934
+ value: 10348500,
935
+ isMine: true,
936
+ chain: 1,
937
+ },
938
+ {
939
+ vout: 1,
940
+ value: 10000,
941
+ isMine: true,
942
+ chain: 11,
943
+ },
944
+ ],
945
+ });
946
+ (0, nock_1.default)(bgUrl)
947
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
948
+ .query(true)
949
+ .reply(200, {
950
+ unspents: [
951
+ {
952
+ tx_hash: parentTxId,
953
+ tx_output_n: 0,
954
+ value: 10348500,
955
+ redeemScript: '0020f7b58d455351b7b8ddd7c8986d98244f6a95f0746720091537323b967800f744',
956
+ chainPath: '/11/160',
957
+ witnessScript: '5221027f0b45bb4155ea532e3b4312fe0be80166f297d1e0753d2d4a9118c073ad6514210310aa9d68c98831625f329b7826b6c3e3b53e16736b1994b8902442bdcd6653d121026e0ca414f2488b0ab572b99e0ae5442911ab4e0821b2709d885175a527fd552b53ae',
958
+ },
959
+ ],
960
+ });
961
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
962
+ (0, nock_1.default)(bgUrl)
963
+ .post('/api/v1/tx/send', (body) => {
964
+ return !body.ignoreMaxFeeRate;
965
+ })
966
+ .reply(200, function (_, body) {
967
+ return {
968
+ transaction: body.tx,
969
+ };
970
+ });
971
+ const childTx = await wallet.accelerateTransaction({
972
+ transactionID: parentTxId,
973
+ feeRate,
974
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
975
+ });
976
+ should.exist(childTx);
977
+ childTx.should.have.property('status', 'accepted');
978
+ childTx.should.have.property('tx');
979
+ // assert the following:
980
+ // 0) The child tx has exactly one input
981
+ // 1) The parent tx output is an input
982
+ // 2) The child tx has exactly one output
983
+ // 3) The child tx output meets the minimum change threshold
984
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
985
+ decodedChild.ins.length.should.equal(1);
986
+ decodedChild.outs.length.should.equal(1);
987
+ const childInput = decodedChild.ins[0];
988
+ childInput.should.have.property('index', 0);
989
+ childInput.should.have.property('hash');
990
+ const inputTxId = inputParentTxId(childInput);
991
+ inputTxId.should.equal(parentTxId);
992
+ const childOutput = decodedChild.outs[0];
993
+ childOutput.should.have.property('value');
994
+ childOutput.value.should.be.above(minChangeSize);
995
+ });
996
+ it('accelerates a stuck tx with one additional segwit unspent', async () => {
997
+ parentTxId = '8815f202c8654b6c8b295749545c711878cd845a14cb1ea982394d0c14945c33';
998
+ const additionalUnspentTxId = '07d6ee57b024ce2b6108f67847454a0a79a4fcfb98ab255553a2993a1a170b87';
999
+ (0, nock_1.default)(bgUrl)
1000
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1001
+ .reply(200, {
1002
+ fee: 1336,
1003
+ outputs: [
1004
+ {
1005
+ vout: 0,
1006
+ value: 10000,
1007
+ isMine: true,
1008
+ chain: 11,
1009
+ },
1010
+ {
1011
+ vout: 1,
1012
+ value: 8664,
1013
+ isMine: true,
1014
+ chain: 1,
1015
+ },
1016
+ ],
1017
+ confirmations: 0,
1018
+ });
1019
+ (0, nock_1.default)(bgUrl)
1020
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1021
+ .query(true)
1022
+ .reply(200, {
1023
+ unspents: [
1024
+ {
1025
+ tx_hash: parentTxId,
1026
+ tx_output_n: 0,
1027
+ value: 10000,
1028
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1029
+ chainPath: '/0/0',
1030
+ },
1031
+ ],
1032
+ });
1033
+ (0, nock_1.default)(bgUrl)
1034
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1035
+ .query(true)
1036
+ .reply(200, {
1037
+ unspents: [
1038
+ {
1039
+ tx_hash: additionalUnspentTxId,
1040
+ tx_output_n: 0,
1041
+ value: 19935526,
1042
+ redeemScript: '0020d34ef6dd34ef2a4fbea67c541c1c796749a60afe4a97fee8ec7ded188bd749da',
1043
+ chainPath: '/11/155',
1044
+ witnessScript: '522102219d2aa8417633f0bce3911374a1604c1b64161f83a3c2ee409c27c42355f08e2102c9734920dc4da06c289fe69171dfcd75e3b9b4f190d0cbc3d5d0ff3f5fdeeaae2103ccd68d7fa8dc0d02dd45dad165557a48582eda4435fae7377b3c31e08ad065c953ae',
1045
+ },
1046
+ ],
1047
+ });
1048
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1049
+ (0, nock_1.default)(bgUrl)
1050
+ .post('/api/v1/tx/send', (body) => {
1051
+ return !body.ignoreMaxFeeRate;
1052
+ })
1053
+ .reply(200, function (_, body) {
1054
+ return {
1055
+ transaction: body.tx,
1056
+ };
1057
+ });
1058
+ const childTx = await wallet.accelerateTransaction({
1059
+ transactionID: parentTxId,
1060
+ feeRate,
1061
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1062
+ });
1063
+ should.exist(childTx);
1064
+ childTx.should.have.property('status', 'accepted');
1065
+ childTx.should.have.property('tx');
1066
+ // assert the following:
1067
+ // 0) The child tx has exactly two inputs
1068
+ // 1) The parent tx output is an input
1069
+ // 2) The additional unspent output is an input
1070
+ // 3) The child tx has exactly one output
1071
+ // 4) The child tx output meets the minimum change threshold
1072
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
1073
+ decodedChild.ins.length.should.equal(2);
1074
+ decodedChild.outs.length.should.equal(1);
1075
+ let inputFromParent = undefined;
1076
+ let additionalInput = undefined;
1077
+ _.forEach(decodedChild.ins, (input) => {
1078
+ input.should.have.property('hash');
1079
+ input.should.have.property('index');
1080
+ const inputTxId = inputParentTxId(input);
1081
+ if (inputTxId === parentTxId) {
1082
+ inputFromParent = input;
1083
+ }
1084
+ else {
1085
+ additionalInput = input;
1086
+ }
1087
+ });
1088
+ should.exist(inputFromParent);
1089
+ const inputFromParentHash = inputParentTxId(inputFromParent);
1090
+ inputFromParentHash.should.equal(parentTxId);
1091
+ inputFromParent.index.should.equal(0);
1092
+ should.exist(additionalInput);
1093
+ const additionalInputHash = inputParentTxId(additionalInput);
1094
+ additionalInputHash.should.equal(additionalUnspentTxId);
1095
+ additionalInput.index.should.equal(0);
1096
+ const childOutput = decodedChild.outs[0];
1097
+ childOutput.should.have.property('value');
1098
+ childOutput.value.should.be.above(minChangeSize);
1099
+ });
1100
+ it('accelerates a stuck tx with one additional P2SH unspent', async () => {
1101
+ parentTxId = '8815f202c8654b6c8b295749545c711878cd845a14cb1ea982394d0c14945c33';
1102
+ const additionalUnspentTxId = 'e190310f2f3f71aa8846f1161cbce1533c24a857dd24e4501b131feb400aad58';
1103
+ (0, nock_1.default)(bgUrl)
1104
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1105
+ .reply(200, {
1106
+ fee: 1336,
1107
+ outputs: [
1108
+ {
1109
+ vout: 0,
1110
+ value: 10000,
1111
+ isMine: true,
1112
+ chain: 11,
1113
+ },
1114
+ {
1115
+ vout: 1,
1116
+ value: 8664,
1117
+ isMine: true,
1118
+ chain: 1,
1119
+ },
1120
+ ],
1121
+ confirmations: 0,
1122
+ });
1123
+ (0, nock_1.default)(bgUrl)
1124
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1125
+ .query(true)
1126
+ .reply(200, {
1127
+ unspents: [
1128
+ {
1129
+ tx_hash: parentTxId,
1130
+ tx_output_n: 0,
1131
+ value: 10000,
1132
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1133
+ chainPath: '/0/0',
1134
+ },
1135
+ ],
1136
+ });
1137
+ (0, nock_1.default)(bgUrl)
1138
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1139
+ .query(true)
1140
+ .reply(200, {
1141
+ unspents: [
1142
+ {
1143
+ tx_hash: additionalUnspentTxId,
1144
+ tx_output_n: 1,
1145
+ value: 20000000,
1146
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1147
+ chainPath: '/0/0',
1148
+ },
1149
+ ],
1150
+ });
1151
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1152
+ (0, nock_1.default)(bgUrl)
1153
+ .post('/api/v1/tx/send', (body) => {
1154
+ return !body.ignoreMaxFeeRate;
1155
+ })
1156
+ .reply(200, function (_, body) {
1157
+ return {
1158
+ transaction: body.tx,
1159
+ };
1160
+ });
1161
+ const childTx = await wallet.accelerateTransaction({
1162
+ transactionID: parentTxId,
1163
+ feeRate,
1164
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1165
+ });
1166
+ should.exist(childTx);
1167
+ childTx.should.have.property('status', 'accepted');
1168
+ childTx.should.have.property('tx');
1169
+ // assert the following:
1170
+ // 0) The child tx has exactly two inputs
1171
+ // 1) The parent tx output is an input
1172
+ // 2) The additional unspent output is an input
1173
+ // 3) The child tx has exactly one output
1174
+ // 4) The child tx output meets the minimum change threshold
1175
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
1176
+ decodedChild.ins.length.should.equal(2);
1177
+ decodedChild.outs.length.should.equal(1);
1178
+ let inputFromParent = undefined;
1179
+ let additionalInput = undefined;
1180
+ _.forEach(decodedChild.ins, (input) => {
1181
+ input.should.have.property('hash');
1182
+ input.should.have.property('index');
1183
+ const inputHash = inputParentTxId(input);
1184
+ if (inputHash === parentTxId) {
1185
+ inputFromParent = input;
1186
+ }
1187
+ else {
1188
+ additionalInput = input;
1189
+ }
1190
+ });
1191
+ should.exist(inputFromParent);
1192
+ const inputFromParentHash = inputParentTxId(inputFromParent);
1193
+ inputFromParentHash.should.equal(parentTxId);
1194
+ inputFromParent.index.should.equal(0);
1195
+ should.exist(additionalInput);
1196
+ const additionalInputHash = inputParentTxId(additionalInput);
1197
+ additionalInputHash.should.equal(additionalUnspentTxId);
1198
+ additionalInput.index.should.equal(1);
1199
+ const childOutput = decodedChild.outs[0];
1200
+ childOutput.should.have.property('value');
1201
+ childOutput.value.should.be.above(minChangeSize);
1202
+ });
1203
+ it('accelerates a stuck tx with two additional unspents (segwit and P2SH)', async () => {
1204
+ parentTxId = '8815f202c8654b6c8b295749545c711878cd845a14cb1ea982394d0c14945c33';
1205
+ (0, nock_1.default)(bgUrl)
1206
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1207
+ .reply(200, {
1208
+ fee: 1336,
1209
+ outputs: [
1210
+ {
1211
+ vout: 0,
1212
+ value: 10000,
1213
+ isMine: true,
1214
+ chain: 11,
1215
+ },
1216
+ {
1217
+ vout: 1,
1218
+ value: 8664,
1219
+ isMine: true,
1220
+ chain: 1,
1221
+ },
1222
+ ],
1223
+ confirmations: 0,
1224
+ });
1225
+ (0, nock_1.default)(bgUrl)
1226
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1227
+ .query(true)
1228
+ .reply(200, {
1229
+ unspents: [
1230
+ {
1231
+ tx_hash: parentTxId,
1232
+ tx_output_n: 0,
1233
+ value: 10000,
1234
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1235
+ chainPath: '/0/0',
1236
+ },
1237
+ ],
1238
+ });
1239
+ (0, nock_1.default)(bgUrl)
1240
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1241
+ .query(true)
1242
+ .reply(200, {
1243
+ unspents: [
1244
+ {
1245
+ tx_hash: 'e190310f2f3f71aa8846f1161cbce1533c24a857dd24e4501b131feb400aad58',
1246
+ tx_output_n: 1,
1247
+ value: 800000,
1248
+ redeemScript: '522102cd3c8e6006a4627705021d1d016d097c2944d98100a47bf2da67a5fe15aeeb342102ee1fa9e812e779356aa3c31ebf317d0cffebab92864cfe38bab223e0820f98bc21026ba05752baa6eafd5c5659da62b7f0ac51fd2886b65c241d0afef1c4fdfa1cbc53ae',
1249
+ chainPath: '/0/0',
1250
+ },
1251
+ {
1252
+ tx_hash: '07d6ee57b024ce2b6108f67847454a0a79a4fcfb98ab255553a2993a1a170b87',
1253
+ tx_output_n: 0,
1254
+ value: 20006284,
1255
+ redeemScript: '0020d34ef6dd34ef2a4fbea67c541c1c796749a60afe4a97fee8ec7ded188bd749da',
1256
+ chainPath: '/11/155',
1257
+ witnessScript: '522102219d2aa8417633f0bce3911374a1604c1b64161f83a3c2ee409c27c42355f08e2102c9734920dc4da06c289fe69171dfcd75e3b9b4f190d0cbc3d5d0ff3f5fdeeaae2103ccd68d7fa8dc0d02dd45dad165557a48582eda4435fae7377b3c31e08ad065c953ae',
1258
+ },
1259
+ ],
1260
+ });
1261
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1262
+ (0, nock_1.default)(bgUrl)
1263
+ .post('/api/v1/tx/send', (body) => {
1264
+ return !body.ignoreMaxFeeRate;
1265
+ })
1266
+ .reply(200, function (_, body) {
1267
+ return {
1268
+ transaction: body.tx,
1269
+ };
1270
+ });
1271
+ const childTx = await wallet.accelerateTransaction({
1272
+ transactionID: parentTxId,
1273
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1274
+ feeRate,
1275
+ });
1276
+ should.exist(childTx);
1277
+ childTx.should.have.property('status', 'accepted');
1278
+ childTx.should.have.property('tx');
1279
+ // assert the following:
1280
+ // 0) The child tx has exactly three inputs
1281
+ // 1) The parent tx output is an input
1282
+ // 2) The child tx has exactly one output
1283
+ // 3) The child tx output meets the minimum change threshold
1284
+ const decodedChild = utxolib.bitgo.createTransactionFromHex(childTx.tx, utxolib.networks.bitcoin);
1285
+ decodedChild.ins.length.should.equal(3);
1286
+ decodedChild.outs.length.should.equal(1);
1287
+ let inputFromParent = undefined;
1288
+ const additionalInputs = [];
1289
+ _.forEach(decodedChild.ins, (input) => {
1290
+ input.should.have.property('hash');
1291
+ input.should.have.property('index');
1292
+ const inputHash = inputParentTxId(input);
1293
+ if (inputHash === parentTxId) {
1294
+ inputFromParent = input;
1295
+ }
1296
+ else {
1297
+ additionalInputs.push(input);
1298
+ }
1299
+ });
1300
+ should.exist(inputFromParent);
1301
+ const inputFromParentHash = inputParentTxId(inputFromParent);
1302
+ inputFromParentHash.should.equal(parentTxId);
1303
+ inputFromParent.index.should.equal(0);
1304
+ additionalInputs.length.should.equal(2);
1305
+ const childOutput = decodedChild.outs[0];
1306
+ childOutput.should.have.property('value');
1307
+ childOutput.value.should.be.above(minChangeSize);
1308
+ });
1309
+ it('correctly uses the ignoreMaxFeeRate parameter only when necessary', async () => {
1310
+ parentTxId = '75cfc5a7b214c4b73c92c7b02608cde70b226767a9576f84c04407e43fd385bd';
1311
+ (0, nock_1.default)(bgUrl)
1312
+ .get(`/api/v1/wallet/${wallet.id()}/tx/${parentTxId}`)
1313
+ .reply(200, {
1314
+ fee: 434,
1315
+ outputs: [
1316
+ {
1317
+ vout: 0,
1318
+ value: 10348500,
1319
+ isMine: true,
1320
+ chain: 0,
1321
+ },
1322
+ {
1323
+ vout: 1,
1324
+ value: 10000,
1325
+ isMine: true,
1326
+ chain: 11,
1327
+ },
1328
+ ],
1329
+ });
1330
+ (0, nock_1.default)(bgUrl)
1331
+ .get(`/api/v1/wallet/${wallet.id()}/unspents`)
1332
+ .query(true)
1333
+ .reply(200, {
1334
+ unspents: [
1335
+ {
1336
+ tx_hash: parentTxId,
1337
+ tx_output_n: 0,
1338
+ value: 10348500,
1339
+ redeemScript: '0020f7b58d455351b7b8ddd7c8986d98244f6a95f0746720091537323b967800f744',
1340
+ chainPath: '/11/160',
1341
+ witnessScript: '5221027f0b45bb4155ea532e3b4312fe0be80166f297d1e0753d2d4a9118c073ad6514210310aa9d68c98831625f329b7826b6c3e3b53e16736b1994b8902442bdcd6653d121026e0ca414f2488b0ab572b99e0ae5442911ab4e0821b2709d885175a527fd552b53ae',
1342
+ },
1343
+ ],
1344
+ });
1345
+ (0, nock_1.default)(explorerUrl).get(`/tx/${parentTxId}/hex`).reply(200, fixtures[parentTxId]);
1346
+ (0, nock_1.default)(bgUrl)
1347
+ .post('/api/v1/tx/send', (body) => {
1348
+ // ignore max fee rate must be set for this test
1349
+ return body.ignoreMaxFeeRate;
1350
+ })
1351
+ .reply(200);
1352
+ // monkey patch the bitgo getConstants() function
1353
+ const oldGetConstants = bitgo.__proto__.getConstants;
1354
+ bitgo.__proto__.getConstants = () => ({
1355
+ // child fee rate in this test is 31378 sat/kb
1356
+ // so set the max fee rate just below that limit,
1357
+ // but above the combined fee rate of 20000
1358
+ maxFeeRate: 30000,
1359
+ });
1360
+ await wallet.accelerateTransaction({
1361
+ transactionID: parentTxId,
1362
+ feeRate,
1363
+ walletPassphrase: TestBitGo.TEST_WALLET1_PASSCODE,
1364
+ });
1365
+ nock_1.default.pendingMocks().should.be.empty();
1366
+ bitgo.__proto__.getConstants = oldGetConstants;
1367
+ });
1368
+ });
1369
+ });
1370
+ });
1371
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FsbGV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVzdC91bml0L3YxL3dhbGxldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsRUFBRTtBQUNGLG1CQUFtQjtBQUNuQixFQUFFO0FBQ0Ysb0RBQW9EO0FBQ3BELEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUYseUNBQXdDO0FBRXhDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBQ2pELG9EQUFpRDtBQUNqRCwwQ0FBNEI7QUFDNUIsOENBQXlDO0FBQ3pDLHlEQUEyQztBQUMzQywrQ0FBaUM7QUFDakMsZ0RBQXdCO0FBQ3hCLDZDQUErQjtBQUUvQiw0REFBdUQ7QUFFdkQsY0FBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7QUFFekIsTUFBTSxTQUFTLEdBQUc7SUFDaEIscUJBQXFCLEVBQUUsMEJBQTBCO0NBQ2xELENBQUM7QUFDRixRQUFRLENBQUMsMEJBQTBCLEVBQUU7SUFDbkMsTUFBTSxRQUFRLEdBQUcsSUFBQSwyQkFBVyxHQUFFLENBQUM7SUFFL0IsSUFBSSxLQUFLLEdBQUcsSUFBSSxtQkFBUSxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzlFLDhCQUE4QjtJQUU5QixNQUFNLFdBQVcsR0FBRztRQUNsQixJQUFJLEVBQUUsaUhBQWlIO1FBQ3ZILElBQUksRUFBRSxpSEFBaUg7UUFDdkgsTUFBTSxFQUFFLG9FQUFvRTtRQUM1RSxNQUFNLEVBQUUsa0VBQWtFO1FBQzFFLElBQUksRUFBRSxHQUFHO1FBQ1QsYUFBYSxFQUFFLE1BQU07S0FDdEIsQ0FBQztJQUNGLE1BQU0sYUFBYSxHQUFHO1FBQ3BCLElBQUksRUFBRSxpSEFBaUg7UUFDdkgsSUFBSSxFQUFFLGlIQUFpSDtRQUN2SCxN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Q2pELDJDQUEyQztvQkFDM0MsVUFBVSxFQUFFLEtBQUs7aUJBQ2xCLENBQUMsQ0FBQztnQkFFSCxNQUFNLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQztvQkFDakMsYUFBYSxFQUFFLFVBQVU7b0JBQ3pCLE9BQU87b0JBQ1AsZ0JBQWdCLEVBQUUsU0FBUyxDQUFDLHFCQUFxQjtpQkFDbEQsQ0FBQyxDQUFDO2dCQUNILGNBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUVyQyxLQUFhLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxlQUFlLENBQUM7WUFDMUQsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvL1xuLy8gVGVzdHMgZm9yIFdhbGxldFxuLy9cbi8vIENvcHlyaWdodCAyMDE0LCBCaXRHbywgSW5jLiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vXG5cbmltcG9ydCB7IGdldEZpeHR1cmUgfSBmcm9tICcuL2ZpeHR1cmVzJztcblxuY29uc3QgV2FsbGV0ID0gcmVxdWlyZSgnLi4vLi4vLi4vc3JjL3YxL3dhbGxldCcpO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICcuLi8uLi8uLi9zcmMvYml0Z29BUEknO1xuaW1wb3J0ICogYXMgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgY29tbW9uIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCAqIGFzIHV0eG9saWIgZnJvbSAnQGJpdGdvL3V0eG8tbGliJztcbmltcG9ydCAqIGFzIHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IG5vY2sgZnJvbSAnbm9jayc7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5cbmltcG9ydCB7IGdldEZpeHR1cmVzIH0gZnJvbSAnLi9maXh0dXJlcy9hY2NlbGVyYXRlLXR4Jztcblxubm9jay5kaXNhYmxlTmV0Q29ubmVjdCgpO1xuXG5jb25zdCBUZXN0Qml0R28gPSB7XG4gIFRFU1RfV0FMTEVUMV9QQVNTQ09ERTogJ2lWV2VBVGpxTFMxakpTaHJQcEVUdGkwYicsXG59O1xuZGVzY3JpYmUoJ1dhbGxldCBQcm90b3R5cGUgTWV0aG9kcycsIGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgZml4dHVyZXMgPSBnZXRGaXh0dXJlcygpO1xuXG4gIGxldCBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ3Rlc3QnLCBjbGllbnRDb25zdGFudHM6IHsgY29uc3RhbnRzOiB7fSB9IH0pO1xuICAvLyBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcblxuICBjb25zdCB1c2VyS2V5cGFpciA9IHtcbiAgICB4cHJ2OiAneHBydjlzMjFaclFIMTQzSzJmSjkxUzRCUnN1cGNZckU2bW1ZOTZmY1g1SGtob1Rycndtd2pkMTZDbjg3Y1dpbkpqQnlyZnBvamp4N2V6c0pMeDdUQUtMVDhtOGhNNUtheDlZY294bkJlSlozdDJrJyxcbiAgICB4cHViOiAneHB1YjY2MU15TXdBcVJiY0Y5TmM3VGJCbzFyWkFhZ2lXRVZQV0tiREtUaE5HOHpxams3NkhBS0xrYVNiVG42ZEsyZFFQZnVEN3hqaWN4Q1pWV3ZqNjdmUDVuUTlXN1FVUm1vTVZBWDhtNmpac0dwJyxcbiAgICByYXdQdWI6ICcwMmMxMDNhYzc0NDgxODc0YjVlZjBmMzg1ZDEyNzI1ZTRmMTRhZWRjOWUwMGJjODE0Y2U5NmY0N2Y2MmNlN2FkZjInLFxuICAgIHJhd1BydjogJzkzNmM1YWYzZjhhZjgxZjc1Y2RhZDFiMDhmMjllN2Q5YzAxZTU5OGUyZGIyZDdiZTE4YjllNWE4NjQ2ZTg3YzYnLFxuICAgIHBhdGg6ICdtJyxcbiAgICB3YWxsZXRTdWJQYXRoOiAnLzAvMCcsXG4gIH07XG4gIGNvbnN0IGJhY2t1cEtleXBhaXIgPSB7XG4gICAgeHBydjogJ3hwcnY5czIxWnJRSDE0M0s0N3NFa0xreWtnWW1xMXhGNVpXclBZaFVaY21CcFBGTVFvanZHVW1FY3I1akZYWUdmcjhDcEZkcFR2aFE3TDlOTjJyTHRzQkZqU2l4M0JBandKY0JqNlUzRDVoeFRQYycsXG4gICAgeHB1YjogJ3hwdWI2NjFNeU13QXFSYmNHYndock5IejdwVldQM25qVjJFaGttZDVOMUFvTmluTEhjNTRwMjVWQWVRRDZxMm9UUzN1dURNRG5mblhudGhiUzl1ZkM4SlZZcE5uV1U1Um4zcFlhTnVMQ055d2t3MScsXG4gICAgcmF3UHViOiAnMDNiYmNiNzM5OTc5NzcwNjhkOWUzNjY2NmJiZDVjZDM3NTc5YWNhZThlMmJkNWNlOWQwYTZlNWMxNTBhNDIzYmMzJyxcbiAgICByYXdQcnY6ICc3N2ExNWYxNDc5NmY0MDAxZDEwOTJhZTg0Zjc2NmJkODY5ZTliZWU2YmZmYWU2NTQ3ZGVmNTA0NWI5NmZhOTQzJyxcbiAgICBwYXRoOiAnbScsXG4gICAgd2FsbGV0U3ViUGF0aDogJy8wLzAnLFxuICB9O1xuICBjb25zdCBiaXRnb0tleSA9IHtcbiAgICB4cHViOiAneHB1YjY2MU15TXdBcVJiY0dRY1ZGaXdjcnRjN2Mzdm9wc1g5NmpzSlVZUGNGTVJFY1JUcUFxc3FidjJaUnlDSkFQTG01Tk1IQ3k4NUUzWndwVDRFQVV3OVdHVTd2TWhHNno4M2hEZUtYQlduNkxmJyxcbiAgICBwYXRoOiAnbScsXG4gICAgd2FsbGV0U3ViUGF0aDogJy8wLzAnLFxuICB9O1xuXG4gIGNvbnN0IGZha2VXYWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB7XG4gICAgaWQ6ICcyTkNvU2ZISDZMczRDZFRTNVFhaGdDOWs3eDlSZlhlU3dZNCcsXG4gICAgcHJpdmF0ZTogeyBrZXljaGFpbnM6IFt1c2VyS2V5cGFpciwgYmFja3VwS2V5cGFpciwgYml0Z29LZXldIH0sXG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZW5lcmF0ZSBBZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgIGJlZm9yZSgoKSA9PiBub2NrLnBlbmRpbmdNb2NrcygpLnNob3VsZC5iZS5lbXB0eSgpKTtcblxuICAgIGl0KCdnZW5lcmF0ZSBmaXJzdCBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaWRBZGRyZXNzID0gZmFrZVdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzAvMCcsIHNlZ3dpdDogZmFsc2UgfSk7XG4gICAgICBpZEFkZHJlc3MuYWRkcmVzcy5zaG91bGQuZXF1YWwoZmFrZVdhbGxldC5pZCgpKTtcbiAgICAgIGlkQWRkcmVzcy5jaGFpbi5zaG91bGQuZXF1YWwoMCk7XG4gICAgICBpZEFkZHJlc3MuaW5kZXguc2hvdWxkLmVxdWFsKDApO1xuICAgICAgaWRBZGRyZXNzLmNoYWluUGF0aC5zaG91bGQuZXF1YWwoJy8wLzAnKTtcbiAgICAgIGlkQWRkcmVzcy5wYXRoLnNob3VsZC5lcXVhbCgnLzAvMCcpO1xuICAgICAgaWRBZGRyZXNzLm91dHB1dFNjcmlwdC5zaG91bGQuZXF1YWwoJ2E5MTRkNjgyNDc2ZTliZDU0NDU0YTg4NWY5ZGZmMWU2MDRlOTljZWY0M2RjODcnKTtcbiAgICAgIGlkQWRkcmVzcy5yZWRlZW1TY3JpcHQuc2hvdWxkLmVxdWFsKFxuICAgICAgICAnNTIyMTAyY2QzYzhlNjAwNmE0NjI3NzA1MDIxZDFkMDE2ZDA5N2MyOTQ0ZDk4MTAwYTQ3YmYyZGE2N2E1ZmUxNWFlZWIzNDIxMDJlZTFmYTllODEyZTc3OTM1NmFhM2MzMWViZjMxN2QwY2ZmZWJhYjkyODY0Y2ZlMzhiYWIyMjNlMDgyMGY5OGJjMjEwMjZiYTA1NzUyYmFhNmVhZmQ1YzU2NTlkYTYyYjdmMGFjNTFmZDI4ODZiNjVjMjQxZDBhZmVmMWM0ZmRmYTFjYmM1M2FlJ1xuICAgICAgKTtcbiAgICAgIGlkQWRkcmVzcy53YWxsZXQuc2hvdWxkLmVxdWFsKGZha2VXYWxsZXQuaWQoKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZ2VuZXJhdGUgc2Vjb25kIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwMnNoQWRkcmVzcyA9IGZha2VXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8wLzEnLCBzZWd3aXQ6IGZhbHNlIH0pO1xuICAgICAgcDJzaEFkZHJlc3MuYWRkcmVzcy5zaG91bGQuZXF1YWwoJzJONXk1UkxWcWRaaTdxcDVQbXpNZFBSNll2UXpVcUJRRldLJyk7XG4gICAgICBwMnNoQWRkcmVzcy5jaGFpbi5zaG91bGQuZXF1YWwoMCk7XG4gICAgICBwMnNoQWRkcmVzcy5pbmRleC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICBwMnNoQWRkcmVzcy5jaGFpblBhdGguc2hvdWxkLmVxdWFsKCcvMC8xJyk7XG4gICAgICBwMnNoQWRkcmVzcy5wYXRoLnNob3VsZC5lcXVhbCgnLzAvMScpO1xuICAgICAgcDJzaEFkZHJlc3Mub3V0cHV0U2NyaXB0LnNob3VsZC5lcXVhbCgnYTkxNDhiOGJkM2RhNjhlZjBmMjQ2NTUyMzE0NmJkMmRlMzNjODZiOWM4NzE4NycpO1xuICAgICAgcDJzaEFkZHJlc3MucmVkZWVtU2NyaXB0LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzUyMjEwMjcwOWVkYjZhMjE5OGQzNjRjNDg1YTc2Yjk4MWQxMjA2NWVhYmRlOGFhMmQ4NWJkN2U3YTAzNWY3ZWNiMzU3OWIyMTAyYTcyNGVmZWQ0OTljMDVmZGI0ZGExZTEzOTcwMDk1MWZhZTAwYzAwNmIzMjgzODg4YmRmZDFiNDY5NzkyOTIyNDIxMDJiMzJhYmU0NGQ2MTk4NmZmNTdiODM1ZTNiZDE2MjkzZDkzZjMwM2QwZDhmYjA0NTRlMmM5Y2NlZGE1YzQ5Mjk4NTNhZSdcbiAgICAgICk7XG4gICAgICBwMnNoQWRkcmVzcy53YWxsZXQuc2hvdWxkLmVxdWFsKGZha2VXYWxsZXQuaWQoKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZ2VuZXJhdGUgY2hhbmdlIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwMnNoQWRkcmVzcyA9IGZha2VXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8xLzAnLCBzZWd3aXQ6IGZhbHNlIH0pO1xuICAgICAgcDJzaEFkZHJlc3MuYWRkcmVzcy5zaG91bGQuZXF1YWwoJzJORmo5SnJwWmM1TXlZbkNvdXlSRXR6Tlk0ZW95S1dEZmdQJyk7XG4gICAgICBwMnNoQWRkcmVzcy5jaGFpbi5zaG91bGQuZXF1YWwoMSk7XG4gICAgICBwMnNoQWRkcmVzcy5pbmRleC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICBwMnNoQWRkcmVzcy5jaGFpblBhdGguc2hvdWxkLmVxdWFsKCcvMS8wJyk7XG4gICAgICBwMnNoQWRkcmVzcy5wYXRoLnNob3VsZC5lcXVhbCgnLzEvMCcpO1xuICAgICAgcDJzaEFkZHJlc3Mub3V0cHV0U2NyaXB0LnNob3VsZC5lcXVhbCgnYTkxNGY2OWE4MWZhZDc1ZWE2NWFkMTY2ZGE3NjUxNTI5MTY3OWE0ZjFhZDg4NycpO1xuICAgICAgcDJzaEFkZHJlc3MucmVkZWVtU2NyaXB0LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzUyMjEwMjBiNGM0Zjg5MWE1NTIwZjVhMGI2ODE4ZDhkNTM5MTk1NTJhMGQ0ZDgwNmI1ZmEwNWM5NzcwODA3OWQ4MzczN2UyMTAyYzVjYzQ5YmYwMzMxZWIwYjA4OTBhN2U3ZDg3ZjdlOWUwZGVhNTE1NDM4MjgwZGM3NjgzNGMyMWQxOThlZmUwODIxMDM3MGU1MmNmNzQxZWJmNDUxMzc0OWQwMjg4MzlkNjk2ODkxZWI3ODliYTdhNTg1OTJjZmJjODU3Y2RjMGE5ZGU3NTNhZSdcbiAgICAgICk7XG4gICAgICBwMnNoQWRkcmVzcy53YWxsZXQuc2hvdWxkLmVxdWFsKGZha2VXYWxsZXQuaWQoKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnZ2VuZXJhdGUgc2Vnd2l0IGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZWd3aXRBZGRyZXNzID0gZmFrZVdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzEwLzAnLCBzZWd3aXQ6IHRydWUgfSk7XG4gICAgICBzZWd3aXRBZGRyZXNzLmFkZHJlc3Muc2hvdWxkLmVxdWFsKCcyTjVFVmVnUlBXbm1lZDJQcHFEZ2daUHc3RGNORGd1Ull2OCcpO1xuICAgICAgc2Vnd2l0QWRkcmVzcy5jaGFpbi5zaG91bGQuZXF1YWwoMTApO1xuICAgICAgc2Vnd2l0QWRkcmVzcy5pbmRleC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICBzZWd3aXRBZGRyZXNzLmNoYWluUGF0aC5zaG91bGQuZXF1YWwoJy8xMC8wJyk7XG4gICAgICBzZWd3aXRBZGRyZXNzLnBhdGguc2hvdWxkLmVxdWFsKCcvMTAvMCcpO1xuICAgICAgc2Vnd2l0QWRkcmVzcy5vdXRwdXRTY3JpcHQuc2hvdWxkLmVxdWFsKCdhOTE0ODM3ZTJhZGNiNmY2Mzg2ZmVhM2M1ZDQwMzE2YjI4MmNjZjM5MTIxZDg3Jyk7XG4gICAgICBzZWd3aXRBZGRyZXNzLnJlZGVlbVNjcmlwdC5zaG91bGQuZXF1YWwoJzAwMjBhNjJhZmVlMWQyMTFjNWFkYjk3MzlmODFlZDRlMzYzMzBlNmNkYTY1MWM3YmRkMzE0ZTMyY2NjNDY1ZWMyMjAzJyk7XG4gICAgICBzZWd3aXRBZGRyZXNzLndpdG5lc3NTY3JpcHQuc2hvdWxkLmVxdWFsKFxuICAgICAgICAnNTIyMTAyN2IzMDUwNTc3N2E0ZWQ4OTQ3YjA2OWZjYjAxMTZlMjg3OTk1ZDk3Mjc4ZDg0ZGE0ZGI2YzYxMzI3MDY0OWQzZDIxMDM0YzMwZTUxZjFlNjE0Y2FkNjY3ODE1YzkxZDA0MTQwNGMxODIyNWQwYjJmNzllMmMwYmNiNjNmZDI2MDQzMTZiMjEwM2I2NWRkZmMwNjE1OWI2OTE2OTMzOTA3NjFlNzVhMGI4Y2M3YTY1YjZmZjMwNWQwOTRmM2FkOTcyZjE3OTUzZmU1M2FlJ1xuICAgICAgKTtcbiAgICAgIHNlZ3dpdEFkZHJlc3Mud2FsbGV0LnNob3VsZC5lcXVhbChmYWtlV2FsbGV0LmlkKCkpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQ3JlYXRlIFRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBiZ1VybCwgYmdVcmxUZXN0O1xuICAgIGxldCBmYWtlUHJvZFdhbGxldDtcblxuICAgIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgICBub2NrLnBlbmRpbmdNb2NrcygpLnNob3VsZC5iZS5lbXB0eSgpO1xuICAgICAgY29uc3QgcHJvZEJpdGdvID0gbmV3IEJpdEdvQVBJKHsgZW52OiAncHJvZCcsIGNsaWVudENvbnN0YW50czogeyBjb25zdGFudHM6IHt9IH0gfSk7XG4gICAgICAvLyBwcm9kQml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgICBiZ1VybCA9IGNvbW1vbi5FbnZpcm9ubWVudHNbcHJvZEJpdGdvLmdldEVudigpXS51cmk7XG4gICAgICBmYWtlUHJvZFdhbGxldCA9IG5ldyBXYWxsZXQocHJvZEJpdGdvLCB7XG4gICAgICAgIGlkOiAnMk5Db1NmSEg2THM0Q2RUUzVRYWhnQzlrN3g5UmZYZVN3WTQnLFxuICAgICAgICBwcml2YXRlOiB7IGtleWNoYWluczogW3VzZXJLZXlwYWlyLCBiYWNrdXBLZXlwYWlyLCBiaXRnb0tleV0gfSxcbiAgICAgIH0pO1xuICAgICAgYmdVcmxUZXN0ID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2V4dHJhIHVuc3BlbnQgZmV0Y2ggcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmlsbGluZ0FkZHJlc3MgPSAnM0o5OHQxV3BFWjczQ05tUXZpZWNybnlpV3JucVJoV05MeSc7XG4gICAgICBjb25zdCBjdXN0b21VbnNwZW50c0ZldGNoUGFyYW1zID0geyB0ZXN0OiAxMjMgfTtcbiAgICAgIGNvbnN0IHNlbmRBbW91bnQgPSAxZTU7XG5cbiAgICAgIG5vY2soYmdVcmwpLnBvc3QoJy9hcGkvdjEvYmlsbGluZy9hZGRyZXNzJykucmVwbHkoMjAwLCB7IGFkZHJlc3M6IGJpbGxpbmdBZGRyZXNzIH0pO1xuXG4gICAgICBjb25zdCBzY29wZSA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7ZmFrZVByb2RXYWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAucXVlcnkoXG4gICAgICAgICAgXy5tZXJnZShjdXN0b21VbnNwZW50c0ZldGNoUGFyYW1zLCB7XG4gICAgICAgICAgICBzZWd3aXQ6IHRydWUsXG4gICAgICAgICAgICB0YXJnZXQ6IHNlbmRBbW91bnQsXG4gICAgICAgICAgICBtaW5TaXplOiAwLFxuICAgICAgICAgIH0pXG4gICAgICAgIClcbiAgICAgICAgLnJlcGx5KDIwMCwgeyB1bnNwZW50czogW10gfSk7XG5cbiAgICAgIGF3YWl0IGZha2VQcm9kV2FsbGV0XG4gICAgICAgIC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdW5zcGVudHNGZXRjaFBhcmFtczogY3VzdG9tVW5zcGVudHNGZXRjaFBhcmFtcyxcbiAgICAgICAgICByZWNpcGllbnRzOiB7IFtiaWxsaW5nQWRkcmVzc106IHNlbmRBbW91bnQgfSxcbiAgICAgICAgICBmZWVSYXRlOiAxMDAwMCxcbiAgICAgICAgICBiaXRnb0ZlZToge1xuICAgICAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICAgICAgYWRkcmVzczogJycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJzAgdW5zcGVudHMgYXZhaWxhYmxlIGZvciB0cmFuc2FjdGlvbiBjcmVhdGlvbicpO1xuXG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2RlZmF1bHQgcDJzaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHAyc2hBZGRyZXNzID0gZmFrZVByb2RXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8wLzEzJywgc2Vnd2l0OiBmYWxzZSB9KTtcbiAgICAgIGNvbnN0IHVuc3BlbnQ6IGFueSA9IHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJzJOQ0VEbW1LTk5ucUt2bld3N3BFM1JMenVGZTVhSEhWeTFYJ10sXG4gICAgICAgIHZhbHVlOiAnMC4wMDUwNDQyMicsXG4gICAgICAgIHZhbHVlX2ludDogNTA0NDIyLFxuICAgICAgICB0eGlkOiAnYjgxNmRlZDg5YzNkOGQ1MDIxYjAxMDk3ZjRhMzEyOWE2YTY4YTVjYjdjODg2ZTk3OTQ1ZjQyMDVjYmE1ZGU0NCcsXG4gICAgICAgIG46IDEsXG4gICAgICAgIHNjcmlwdF9wdWJfa2V5OiB7XG4gICAgICAgICAgYXNtOiAnT1BfSEFTSDE2MCBkMDM5Y2IzMzQ0Mjk0YTVhMzg0YTU1MDhhMDA2NDQ0YzQyMGNiYzExIE9QX0VRVUFMJyxcbiAgICAgICAgICBoZXg6ICdhOTE0ZDAzOWNiMzM0NDI5NGE1YTM4NGE1NTA4YTAwNjQ0NGM0MjBjYmMxMTg3JyxcbiAgICAgICAgfSxcbiAgICAgICAgcmVxX3NpZ3M6IDEsXG4gICAgICAgIHR5cGU6ICdzY3JpcHRoYXNoJyxcbiAgICAgICAgY29uZmlybWF0aW9uczogOSxcbiAgICAgICAgaWQ6IDYxMzMwMjI5LFxuICAgICAgfTtcbiAgICAgIF8uZXh0ZW5kKHVuc3BlbnQsIHAyc2hBZGRyZXNzKTtcbiAgICAgIHVuc3BlbnQudmFsdWUgPSB1bnNwZW50LnZhbHVlX2ludDtcbiAgICAgIHVuc3BlbnQudHhfaGFzaCA9IHVuc3BlbnQudHhpZDtcbiAgICAgIHVuc3BlbnQudHhfb3V0cHV0X24gPSB1bnNwZW50Lm47XG4gICAgICB1bnNwZW50LnNjcmlwdCA9IHVuc3BlbnQub3V0cHV0U2NyaXB0O1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL2JpbGxpbmcvYWRkcmVzcycpLnJlcGx5KDIwMCwgeyBhZGRyZXNzOiAnMk1zd1Fqa3ZONm9XWWRFN0wyYnJKNWNBQU1qUG1HNTlvY28nIH0pO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHAyc2hBZGRyZXNzLmFkZHJlc3MsXG4gICAgICAgIHVuc3BlbnRzOiBbdW5zcGVudF0sXG4gICAgICAgIHJlY2lwaWVudHM6IHt9LFxuICAgICAgICBub1NwbGl0Q2hhbmdlOiB0cnVlLFxuICAgICAgICBmb3JjZUNoYW5nZUF0RW5kOiB0cnVlLFxuICAgICAgICBmZWVSYXRlOiAxMDAwMCxcbiAgICAgICAgYml0Z29GZWU6IHtcbiAgICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgICAgYWRkcmVzczogJycsXG4gICAgICAgIH0sXG4gICAgICAgIG9wUmV0dXJuczogeyAnQml0R28gcDJzaCB0ZXN0JzogMTAwMCB9LFxuICAgICAgfSkpIGFzIGFueTtcbiAgICAgIHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDE0NGRlYTVjYjA1NDI1Zjk0OTc2ZTg4N2NjYmE1Njg2YTlhMTJhM2Y0OTcxMGIwMjE1MDhkM2Q5Y2Q4ZGUxNmI4MDEwMDAwMDAwMGZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTE2YTBmNDI2OTc0NDc2ZjIwNzAzMjczNjgyMDc0NjU3Mzc0MjJhMTA3MDAwMDAwMDAwMDE3YTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NzAwMDAwMDAwJ1xuICAgICAgKTtcblxuICAgICAgLy8gYWRkIGZpcnN0IHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSB1c2VyS2V5cGFpcjtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZTEgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSkgYXMgYW55O1xuICAgICAgc2lnbmF0dXJlMS50eC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAxNDRkZWE1Y2IwNTQyNWY5NDk3NmU4ODdjY2JhNTY4NmE5YTEyYTNmNDk3MTBiMDIxNTA4ZDNkOWNkOGRlMTZiODAxMDAwMDAwYjYwMDQ3MzA0NDAyMjAyMWZhNzNkNWZlNjFhYzg5NDJjZDcwZmY0NTA3YzU3NDY3N2NlNzQ3ZGU1YmM0NmMzZGQyZTM4ZWMyNDQ4ZmNlMDIyMDQ3OTA2ZDJjMDE1NDMzN2FiOTYwNDFlOGZiNThjMjQzYjliY2U1Zjg4MThmYTk5MTY0M2MxMjYwYTE4NTlhZDgwMTAwMDA0YzY5NTIyMTAzMWNkMjI3ZTQwYWQ2MWI0ZTEzNzEwOWNiMjg0NWViNmY1YTU4NGVkNWM2N2Q5ZDMxMzVjZGFhNTA0NWE4NDJlYTIxMDNhMmU3YjU0YzdiMmRhMDk5MjU1NTM1M2I4ZTI2YzZhY2ZmNDI0OGY0MzUxZjA4Nzg3YmYzZTJlZmM5NGI2NTgzMjEwMjVjMmE2Y2RlMzNjMmQ3M2NjZjEyZWVjZjY0YzU0ZjA4ZjcyMmMyZjA3MzgyNDQ5ODk1MDY5NWU5ODgzYjE0MTI1M2FlZmZmZmZmZmYwMmU4MDMwMDAwMDAwMDAwMDAxMTZhMGY0MjY5NzQ0NzZmMjA3MDMyNzM2ODIwNzQ2NTczNzQyMmExMDcwMDAwMDAwMDAwMTdhOTE0ZDAzOWNiMzM0NDI5NGE1YTM4NGE1NTA4YTAwNjQ0NGM0MjBjYmMxMTg3MDAwMDAwMDAnXG4gICAgICApO1xuXG4gICAgICAvLyBhZGQgc2Vjb25kIHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24udHJhbnNhY3Rpb25IZXggPSBzaWduYXR1cmUxLnR4O1xuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSBiYWNrdXBLZXlwYWlyO1xuICAgICAgdHJhbnNhY3Rpb24uZnVsbExvY2FsU2lnbmluZyA9IHRydWU7XG4gICAgICBjb25zdCBzaWduYXR1cmUyID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIC8vIFRoaXMgdHJhbnNhY3Rpb24gaGFzIGFjdHVhbGx5IHdvcmtlZDogaHR0cHM6Ly90ZXN0bmV0LnNtYXJ0Yml0LmNvbS5hdS90eC9hOGNjYjkyODE2OTAzMmQ2ZTFmMzdiZjgxZGZkOWFiNmQ5MDM2MmE0Zjg0ZTU3NzM5N2ZhNjkwYWE3MTE1NTBjXG4gICAgICAvLyBOb3RlIHRoYXQgdGhlIHR4IGhleCBiZWxvdyBubyBsb25nZXIgY29ycmVzcG9uZHMgdG8gdGhlIGFib3ZlIHRyYW5zYWN0aW9uIGJlY2F1c2Ugb3VyIGZlZSBlc3RpbWF0aW9uIGhhc1xuICAgICAgLy8gY2hhbmdlZCwgY2hhbmdpbmcgdGhlIG91dHB1dCBhbW91bnRzIGFuZCB0aHVzIHRoZSB0eCBoZXguXG4gICAgICBzaWduYXR1cmUyLnR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDE0NGRlYTVjYjA1NDI1Zjk0OTc2ZTg4N2NjYmE1Njg2YTlhMTJhM2Y0OTcxMGIwMjE1MDhkM2Q5Y2Q4ZGUxNmI4MDEwMDAwMDBmZGZkMDAwMDQ3MzA0NDAyMjAyMWZhNzNkNWZlNjFhYzg5NDJjZDcwZmY0NTA3YzU3NDY3N2NlNzQ3ZGU1YmM0NmMzZGQyZTM4ZWMyNDQ4ZmNlMDIyMDQ3OTA2ZDJjMDE1NDMzN2FiOTYwNDFlOGZiNThjMjQzYjliY2U1Zjg4MThmYTk5MTY0M2MxMjYwYTE4NTlhZDgwMTQ3MzA0NDAyMjAyYWUwMWYwMWI1YWUwYzNmYTdkNjdhYzczZGI4MTkzMmNiNWFjYTEwZGIxNmE5OTA2M2ZlZjQ1ZTNmMTM5OGNkMDIyMDU1MDAxYmE3ZTE2M2NiMzUwOTEwZmM3MzIxZWNkN2ViNjM1OWIzMjFkNGMwNDg4NzQ4NGQ5YzcyODRiNzhjNDcwMTAwNGM2OTUyMjEwMzFjZDIyN2U0MGFkNjFiNGUxMzcxMDljYjI4NDVlYjZmNWE1ODRlZDVjNjdkOWQzMTM1Y2RhYTUwNDVhODQyZWEyMTAzYTJlN2I1NGM3YjJkYTA5OTI1NTUzNTNiOGUyNmM2YWNmZjQyNDhmNDM1MWYwODc4N2JmM2UyZWZjOTRiNjU4MzIxMDI1YzJhNmNkZTMzYzJkNzNjY2YxMmVlY2Y2NGM1NGYwOGY3MjJjMmYwNzM4MjQ0OTg5NTA2OTVlOTg4M2IxNDEyNTNhZWZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTE2YTBmNDI2OTc0NDc2ZjIwNzAzMjczNjgyMDc0NjU3Mzc0MjJhMTA3MDAwMDAwMDAwMDE3YTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NzAwMDAwMDAwJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdCQ0ggcDJzaCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHAyc2hBZGRyZXNzID0gZmFrZVByb2RXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8wLzEzJywgc2Vnd2l0OiBmYWxzZSB9KTtcbiAgICAgIGNvbnN0IHVuc3BlbnQ6IGFueSA9IHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJzJOQ0VEbW1LTk5ucUt2bld3N3BFM1JMenVGZTVhSEhWeTFYJ10sXG4gICAgICAgIHZhbHVlOiAnMC4wMDUwNDQyMicsXG4gICAgICAgIHZhbHVlX2ludDogNTA0NDIyLFxuICAgICAgICB0eGlkOiAnYjgxNmRlZDg5YzNkOGQ1MDIxYjAxMDk3ZjRhMzEyOWE2YTY4YTVjYjdjODg2ZTk3OTQ1ZjQyMDVjYmE1ZGU0NCcsXG4gICAgICAgIG46IDEsXG4gICAgICAgIHNjcmlwdF9wdWJfa2V5OiB7XG4gICAgICAgICAgYXNtOiAnT1BfSEFTSDE2MCBkMDM5Y2IzMzQ0Mjk0YTVhMzg0YTU1MDhhMDA2NDQ0YzQyMGNiYzExIE9QX0VRVUFMJyxcbiAgICAgICAgICBoZXg6ICdhOTE0ZDAzOWNiMzM0NDI5NGE1YTM4NGE1NTA4YTAwNjQ0NGM0MjBjYmMxMTg3JyxcbiAgICAgICAgfSxcbiAgICAgICAgcmVxX3NpZ3M6IDEsXG4gICAgICAgIHR5cGU6ICdzY3JpcHRoYXNoJyxcbiAgICAgICAgY29uZmlybWF0aW9uczogOSxcbiAgICAgICAgaWQ6IDYxMzMwMjI5LFxuICAgICAgfTtcbiAgICAgIF8uZXh0ZW5kKHVuc3BlbnQsIHAyc2hBZGRyZXNzKTtcbiAgICAgIHVuc3BlbnQudmFsdWUgPSB1bnNwZW50LnZhbHVlX2ludDtcbiAgICAgIHVuc3BlbnQudHhfaGFzaCA9IHVuc3BlbnQudHhpZDtcbiAgICAgIHVuc3BlbnQudHhfb3V0cHV0X24gPSB1bnNwZW50Lm47XG4gICAgICB1bnNwZW50LnNjcmlwdCA9IHVuc3BlbnQub3V0cHV0U2NyaXB0O1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL2JpbGxpbmcvYWRkcmVzcycpLnJlcGx5KDIwMCwgeyBhZGRyZXNzOiAnMk1zd1Fqa3ZONm9XWWRFN0wyYnJKNWNBQU1qUG1HNTlvY28nIH0pO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHAyc2hBZGRyZXNzLmFkZHJlc3MsXG4gICAgICAgIHVuc3BlbnRzOiBbdW5zcGVudF0sXG4gICAgICAgIHJlY2lwaWVudHM6IHt9LFxuICAgICAgICBub1NwbGl0Q2hhbmdlOiB0cnVlLFxuICAgICAgICBmb3JjZUNoYW5nZUF0RW5kOiB0cnVlLFxuICAgICAgICBmZWVSYXRlOiAxMDAwMCxcbiAgICAgICAgYml0Z29GZWU6IHtcbiAgICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgICAgYWRkcmVzczogJycsXG4gICAgICAgIH0sXG4gICAgICAgIG9wUmV0dXJuczogeyAnQml0R28gcDJzaCB0ZXN0JzogMTAwMCB9LFxuICAgICAgfSkpIGFzIGFueTtcbiAgICAgIHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDE0NGRlYTVjYjA1NDI1Zjk0OTc2ZTg4N2NjYmE1Njg2YTlhMTJhM2Y0OTcxMGIwMjE1MDhkM2Q5Y2Q4ZGUxNmI4MDEwMDAwMDAwMGZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTE2YTBmNDI2OTc0NDc2ZjIwNzAzMjczNjgyMDc0NjU3Mzc0MjJhMTA3MDAwMDAwMDAwMDE3YTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NzAwMDAwMDAwJ1xuICAgICAgKTtcblxuICAgICAgLy8gYWRkIGZpcnN0IHNpZ25hdHVyZVxuICAgICAgdHJhbnNhY3Rpb24ua2V5Y2hhaW4gPSB1c2VyS2V5cGFpcjtcbiAgICAgIHRyYW5zYWN0aW9uLmZvcmNlQkNIID0gdHJ1ZTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZTEgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSkgYXMgYW55O1xuICAgICAgc2lnbmF0dXJlMS50eC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAxNDRkZWE1Y2IwNTQyNWY5NDk3NmU4ODdjY2JhNTY4NmE5YTEyYTNmNDk3MTBiMDIxNTA4ZDNkOWNkOGRlMTZiODAxMDAwMDAwYjYwMDQ3MzA0NDAyMjA2MjIxYTk3ZjA4MWQ4N2UwMmUzYjE0OTg4YTY0ODYxODExYTZhOGRlNGYxMWY3NGY1YWFlYTQ1OTgxY2Y2MTJlMDIyMDc3YTA4YTViZDdkNzgxZTc5ODM4YWZiYjEyNmFmMmU0ODgwMmZlZmFkNjYwYWZkYmQ4ODA1ZjVlNTk4ZWQ1ODg0MTAwMDA0YzY5NTIyMTAzMWNkMjI3ZTQwYWQ2MWI0ZTEzNzEwOWNiMjg0NWViNmY1YTU4NGVkNWM2N2Q5ZDMxMzVjZGFhNTA0NWE4NDJlYTIxMDNhMmU3YjU0YzdiMmRhMDk5MjU1NTM1M2I4ZTI2YzZhY2ZmNDI0OGY0MzUxZjA4Nzg3YmYzZTJlZmM5NGI2NTgzMjEwMjVjMmE2Y2RlMzNjMmQ3M2NjZjEyZWVjZjY0YzU0ZjA4ZjcyMmMyZjA3MzgyNDQ5ODk1MDY5NWU5ODgzYjE0MTI1M2FlZmZmZmZmZmYwMmU4MDMwMDAwMDAwMDAwMDAxMTZhMGY0MjY5NzQ0NzZmMjA3MDMyNzM2ODIwNzQ2NTczNzQyMmExMDcwMDAwMDAwMDAwMTdhOTE0ZDAzOWNiMzM0NDI5NGE1YTM4NGE1NTA4YTAwNjQ0NGM0MjBjYmMxMTg3MDAwMDAwMDAnXG4gICAgICApO1xuICAgICAgLy8gYWRkIHNlY29uZCBzaWduYXR1cmVcbiAgICAgIHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4ID0gc2lnbmF0dXJlMS50eDtcbiAgICAgIHRyYW5zYWN0aW9uLmtleWNoYWluID0gYmFja3VwS2V5cGFpcjtcbiAgICAgIHRyYW5zYWN0aW9uLmZ1bGxMb2NhbFNpZ25pbmcgPSB0cnVlO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlMiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5zaWduVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKSBhcyBhbnk7XG4gICAgICAvLyB0aGlzIHRyYW5zYWN0aW9uIGhhcyBhY3R1YWxseSB3b3JrZWQ6IGh0dHBzOi8vdGVzdG5ldC5zbWFydGJpdC5jb20uYXUvdHgvYThjY2I5MjgxNjkwMzJkNmUxZjM3YmY4MWRmZDlhYjZkOTAzNjJhNGY4NGU1NzczOTdmYTY5MGFhNzExNTUwY1xuICAgICAgLy8gTm90ZSB0aGF0IHRoZSB0eCBoZXggYmVsb3cgbm8gbG9uZ2VyIGNvcnJlc3BvbmRzIHRvIHRoZSBhYm92ZSB0cmFuc2FjdGlvbiBiZWNhdXNlIG91ciBmZWUgZXN0aW1hdGlvbiBoYXNcbiAgICAgIC8vIGNoYW5nZWQsIGNoYW5naW5nIHRoZSBvdXRwdXQgYW1vdW50cyBhbmQgdGh1cyB0aGUgdHggaGV4LlxuICAgICAgc2lnbmF0dXJlMi50eC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAxNDRkZWE1Y2IwNTQyNWY5NDk3NmU4ODdjY2JhNTY4NmE5YTEyYTNmNDk3MTBiMDIxNTA4ZDNkOWNkOGRlMTZiODAxMDAwMDAwZmRmZTAwMDA0NzMwNDQwMjIwNjIyMWE5N2YwODFkODdlMDJlM2IxNDk4OGE2NDg2MTgxMWE2YThkZTRmMTFmNzRmNWFhZWE0NTk4MWNmNjEyZTAyMjA3N2EwOGE1YmQ3ZDc4MWU3OTgzOGFmYmIxMjZhZjJlNDg4MDJmZWZhZDY2MGFmZGJkODgwNWY1ZTU5OGVkNTg4NDE0ODMwNDUwMjIxMDA4MmJjNTQ2MjkzODU4NDU5ZjM4OTVkYjI0Yzg1Y2NmMzc1MDVjNTZmOGZhZjRiYjhmNzhjZjQwMTM1YmMyZjJiMDIyMDNkYzFjNzhkN2M3Y2VhZjZiOTI0ZWNhM2MzOWI5NWU4YTIyN2IwNjlhMDcwNDc1ODEyNzMxMzZiNDdjYTdhYzQ0MTAwNGM2OTUyMjEwMzFjZDIyN2U0MGFkNjFiNGUxMzcxMDljYjI4NDVlYjZmNWE1ODRlZDVjNjdkOWQzMTM1Y2RhYTUwNDVhODQyZWEyMTAzYTJlN2I1NGM3YjJkYTA5OTI1NTUzNTNiOGUyNmM2YWNmZjQyNDhmNDM1MWYwODc4N2JmM2UyZWZjOTRiNjU4MzIxMDI1YzJhNmNkZTMzYzJkNzNjY2YxMmVlY2Y2NGM1NGYwOGY3MjJjMmYwNzM4MjQ0OTg5NTA2OTVlOTg4M2IxNDEyNTNhZWZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTE2YTBmNDI2OTc0NDc2ZjIwNzAzMjczNjgyMDc0NjU3Mzc0MjJhMTA3MDAwMDAwMDAwMDE3YTkxNGQwMzljYjMzNDQyOTRhNWEzODRhNTUwOGEwMDY0NDRjNDIwY2JjMTE4NzAwMDAwMDAwJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdkZWZhdWx0IHNlZ3dpdCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlZ3dpdEFkZHJlc3MgPSBmYWtlUHJvZFdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzEwLzEzJywgc2Vnd2l0OiB0cnVlIH0pO1xuICAgICAgY29uc3QgdW5zcGVudDogYW55ID0ge1xuICAgICAgICBhZGRyZXNzZXM6IFsnMk14S2tIOHlCM1M5WVdtVFFSYnZtYm9yWVF5UW5INXBldFAnXSxcbiAgICAgICAgdmFsdWU6ICcwLjE4NzUwMDAwJyxcbiAgICAgICAgdmFsdWVfaW50OiAxODc1MDAwMCxcbiAgICAgICAgdHhpZDogJzdkMjgyODc4YTg1ZGFlZTVkNDZlMDQzODI3ZGFlZDU3NTk2ZDc1ZDFhYTZlMDRmZDBjMDlhMzZmOTEzMDg4MWYnLFxuICAgICAgICBuOiAwLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgMzdiMzkzZmNlNjI3YTBlYzYzNGViNTQzZGRhMWU2MDhlMmQxYzc4YSBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGE4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgIGlkOiA2MTMzMTYxNyxcbiAgICAgIH07XG4gICAgICBfLmV4dGVuZCh1bnNwZW50LCBzZWd3aXRBZGRyZXNzKTtcbiAgICAgIHVuc3BlbnQudmFsdWUgPSB1bnNwZW50LnZhbHVlX2ludDtcbiAgICAgIHVuc3BlbnQudHhfaGFzaCA9IHVuc3BlbnQudHhpZDtcbiAgICAgIHVuc3BlbnQudHhfb3V0cHV0X24gPSB1bnNwZW50Lm47XG4gICAgICB1bnNwZW50LnNjcmlwdCA9IHVuc3BlbnQub3V0cHV0U2NyaXB0O1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL2JpbGxpbmcvYWRkcmVzcycpLnJlcGx5KDIwMCwgeyBhZGRyZXNzOiAnMk1zd1Fqa3ZONm9XWWRFN0wyYnJKNWNBQU1qUG1HNTlvY28nIH0pO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHNlZ3dpdEFkZHJlc3MuYWRkcmVzcyxcbiAgICAgICAgdW5zcGVudHM6IFt1bnNwZW50XSxcbiAgICAgICAgcmVjaXBpZW50czoge30sXG4gICAgICAgIG5vU3BsaXRDaGFuZ2U6IHRydWUsXG4gICAgICAgIGZvcmNlQ2hhbmdlQXRFbmQ6IHRydWUsXG4gICAgICAgIGZlZVJhdGU6IDEwMDAwLFxuICAgICAgICBiaXRnb0ZlZToge1xuICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgICBhZGRyZXNzOiAnJyxcbiAgICAgICAgfSxcbiAgICAgICAgb3BSZXR1cm5zOiB7ICdCaXRHbyBzZWd3aXQgdGVzdCc6IDEwMDAgfSxcbiAgICAgIH0pKSBhcyBhbnk7XG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAxMWY4ODMwOTE2ZmEzMDkwY2ZkMDQ2ZWFhZDE3NTZkNTk1N2VkZGEyNzM4MDQ2ZWQ0ZTVhZTVkYTg3ODI4Mjg3ZDAwMDAwMDAwMDBmZmZmZmZmZjAyZTgwMzAwMDAwMDAwMDAwMDEzNmExMTQyNjk3NDQ3NmYyMDczNjU2Nzc3Njk3NDIwNzQ2NTczNzQwZTBmMWUwMTAwMDAwMDAwMTdhOTE0MzdiMzkzZmNlNjI3YTBlYzYzNGViNTQzZGRhMWU2MDhlMmQxYzc4YTg3MDAwMDAwMDAnXG4gICAgICApO1xuXG4gICAgICAvLyBhZGQgZmlyc3Qgc2lnbmF0dXJlXG4gICAgICB0cmFuc2FjdGlvbi5rZXljaGFpbiA9IHVzZXJLZXlwYWlyO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlMSA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5zaWduVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKSBhcyBhbnk7XG4gICAgICBzaWduYXR1cmUxLnR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDAwMTAxMWY4ODMwOTE2ZmEzMDkwY2ZkMDQ2ZWFhZDE3NTZkNTk1N2VkZGEyNzM4MDQ2ZWQ0ZTVhZTVkYTg3ODI4Mjg3ZDAwMDAwMDAwMjMyMjAwMjA0NDBlODU4MjI4Yjc1MzU0NGI0YzU3ZTMwMDI5NmI1NTcxN2Y4MTEwNTM4ODNmOWJlOWI2YTcxMmVhY2Q5MzFjZmZmZmZmZmYwMmU4MDMwMDAwMDAwMDAwMDAxMzZhMTE0MjY5NzQ0NzZmMjA3MzY1Njc3NzY5NzQyMDc0NjU3Mzc0MGUwZjFlMDEwMDAwMDAwMDE3YTkxNDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGE4NzA1MDA0ODMwNDUwMjIxMDBiZjNhODkxNGExYmZlOTI2NjFmMjdjYTM3YzBkNmI1YzBiM2M3MzUzNjE0Yzk1NTY0NjkyOWYyZTdlYjg5ZmZlMDIyMDJkNTU2YjBmZmFiMzdjMTA0YmFlNjc0MDZjYTE2Zjg4NTljZmEzN2M2YTQwZjIwMTNkODlhZmNlY2Q1NTk0ZjMwMTAwMDA2OTUyMjEwMzJjNTA1ZmM4YTFlNGI1NjgxMWIyNzM2NmEzNzFlNjFjOWZhZjU2NWRkMmZhYmFmZjdhNzBlYWMxOWMzMjE1N2MyMTAyNTExNjBiNTgzYmQ1ZGMwZjBkNDgwOTY1MDUxMzFjNDM0N2FiNjViNGYyMWVkNTdkNzZjMzgxNTc0OTljMDAzZDIxMDI2Nzk3MTJkNjJhMjU2MDkxN2NjNDNmZDJjYzNhMWI5YjYxZjUyOGM4OGJjNjQ5MDViYWU2ZWUwNzllNjA2MDlmNTNhZTAwMDAwMDAwJ1xuICAgICAgKTtcblxuICAgICAgLy8gYWRkIHNlY29uZCBzaWduYXR1cmVcbiAgICAgIHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4ID0gc2lnbmF0dXJlMS50eDtcbiAgICAgIHRyYW5zYWN0aW9uLmtleWNoYWluID0gYmFja3VwS2V5cGFpcjtcbiAgICAgIHRyYW5zYWN0aW9uLmZ1bGxMb2NhbFNpZ25pbmcgPSB0cnVlO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlMiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5zaWduVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKSBhcyBhbnk7XG4gICAgICAvLyB0aGlzIHRyYW5zYWN0aW9uIGhhcyBhY3R1YWxseSB3b3JrZWQ6IGh0dHBzOi8vdGVzdG5ldC5zbWFydGJpdC5jb20uYXUvdHgvZDY3MjY2ZjFkZTkwNWJhYWVlNzUwMDExZmE0YjNkODhhOGUzYTE3NThkNTE3M2E2NTljNjc3MDk0ODhkZGUwN1xuICAgICAgLy8gTm90ZSB0aGF0IHRoZSB0eCBoZXggYmVsb3cgbm8gbG9uZ2VyIGNvcnJlc3BvbmRzIHRvIHRoZSBhYm92ZSB0cmFuc2FjdGlvbiBiZWNhdXNlIG91ciBmZWUgZXN0aW1hdGlvbiBoYXNcbiAgICAgIC8vIGNoYW5nZWQsIGNoYW5naW5nIHRoZSBvdXRwdXQgYW1vdW50cyBhbmQgdGh1cyB0aGUgdHggaGV4LlxuICAgICAgc2lnbmF0dXJlMi50eC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAwMDEwMTFmODgzMDkxNmZhMzA5MGNmZDA0NmVhYWQxNzU2ZDU5NTdlZGRhMjczODA0NmVkNGU1YWU1ZGE4NzgyODI4N2QwMDAwMDAwMDIzMjIwMDIwNDQwZTg1ODIyOGI3NTM1NDRiNGM1N2UzMDAyOTZiNTU3MTdmODExMDUzODgzZjliZTliNmE3MTJlYWNkOTMxY2ZmZmZmZmZmMDJlODAzMDAwMDAwMDAwMDAwMTM2YTExNDI2OTc0NDc2ZjIwNzM2NTY3Nzc2OTc0MjA3NDY1NzM3NDBlMGYxZTAxMDAwMDAwMDAxN2E5MTQzN2IzOTNmY2U2MjdhMGVjNjM0ZWI1NDNkZGExZTYwOGUyZDFjNzhhODcwNTAwNDgzMDQ1MDIyMTAwYmYzYTg5MTRhMWJmZTkyNjYxZjI3Y2EzN2MwZDZiNWMwYjNjNzM1MzYxNGM5NTU2NDY5MjlmMmU3ZWI4OWZmZTAyMjAyZDU1NmIwZmZhYjM3YzEwNGJhZTY3NDA2Y2ExNmY4ODU5Y2ZhMzdjNmE0MGYyMDEzZDg5YWZjZWNkNTU5NGYzMDE0NzMwNDQwMjIwNWNmOGQyZjJiZTZjZTA4M2QzNTY1NGJkYzNmYTg1ZDdlNzFiMjI3ZDQ1N2U5MjQ1YmI2MDNiMjFlN2I1MTY1MTAyMjAzZWE2ODYyMjZkYjgzMjBlMDhjMjZiZmIzMDQwNDhiM2E5NDczZDBlMDU3OTdkMzY1OGRhY2IyZjA5YTJiNTFjMDEwMDY5NTIyMTAzMmM1MDVmYzhhMWU0YjU2ODExYjI3MzY2YTM3MWU2MWM5ZmFmNTY1ZGQyZmFiYWZmN2E3MGVhYzE5YzMyMTU3YzIxMDI1MTE2MGI1ODNiZDVkYzBmMGQ0ODA5NjUwNTEzMWM0MzQ3YWI2NWI0ZjIxZWQ1N2Q3NmMzODE1NzQ5OWMwMDNkMjEwMjY3OTcxMmQ2MmEyNTYwOTE3Y2M0M2ZkMmNjM2ExYjliNjFmNTI4Yzg4YmM2NDkwNWJhZTZlZTA3OWU2MDYwOWY1M2FlMDAwMDAwMDAnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ2NyZWF0ZXMgYW4gdW5zaWduZWQgdHggbWFkZSBvZiB1bmNvbXByZXNzZWQgcHVibGljIGtleXMgb2YgdjEgc2FmZSB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7IGFkZHJlc3MsIHJlZGVlbVNjcmlwdCwgc2NyaXB0UHViS2V5IH0gPSBhd2FpdCBnZXRGaXh0dXJlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PihcbiAgICAgICAgYCR7X19kaXJuYW1lfS9maXh0dXJlcy9zaWduLXRyYW5zYWN0aW9uLmpzb25gXG4gICAgICApO1xuICAgICAgY29uc3QgdGVzdEJpdGdvID0gbmV3IEJpdEdvQVBJKHsgZW52OiAndGVzdCcsIGNsaWVudENvbnN0YW50czogeyBjb25zdGFudHM6IHt9IH0gfSk7XG4gICAgICBjb25zdCBmYWtlVGVzdFYxU2FmZVdhbGxldCA9IG5ldyBXYWxsZXQodGVzdEJpdGdvLCB7XG4gICAgICAgIGlkOiBhZGRyZXNzLFxuICAgICAgICBwcml2YXRlOiB7IHNhZmU6IHsgcmVkZWVtU2NyaXB0IH0gfSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgdW5zcGVudHNUb1NwZW5kID0gW1xuICAgICAgICB7XG4gICAgICAgICAgdmFsdWU6IDEwMDAwMCxcbiAgICAgICAgICByZWRlZW1TY3JpcHQsXG4gICAgICAgICAgc2NyaXB0OiBzY3JpcHRQdWJLZXksXG4gICAgICAgICAgdHhfaGFzaDogJ2E1NWQxMWRjOGI3MDFiZDE5NjAxZmJmZTcxMWExZTQ2NWZjOGYxMjhlYzQ0NzRlNzhlMWZkMDg3ZTgwOGU1ZmUnLFxuICAgICAgICAgIHR4X291dHB1dF9uOiAwLFxuICAgICAgICAgIGNvbmZpcm1hdGlvbnM6IDEsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogMTAwMDAwLFxuICAgICAgICAgIHJlZGVlbVNjcmlwdCxcbiAgICAgICAgICBzY3JpcHQ6IHNjcmlwdFB1YktleSxcbiAgICAgICAgICB0eF9oYXNoOiAnNDhmYjg3OWNlYzg3OTM1NjA0NWEzMzE5MzcwMjNhZWQ4NTlmNWRjNWRiOTU1YTFkYzhhNWNjZjI5ZjQ5ZDEwOCcsXG4gICAgICAgICAgdHhfb3V0cHV0X246IDAsXG4gICAgICAgICAgY29uZmlybWF0aW9uczogMSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCByZWNpcGllbnRzID0ge1xuICAgICAgICAnMk15R3hyaExDNGtSZnVWakxxQ1ZZRnRDN0RjaGhnTUNpTnonOiAxOTEzNDAsIC8vIHB1cnBvc2VseSBzZXQgdG8gc2ltdWxhdGUgYSBzd2VlcCB0cmFuc2FjdGlvblxuICAgICAgfTtcblxuICAgICAgY29uc3Qgc2NvcGUgPSBub2NrKGJnVXJsVGVzdClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjEvYmlsbGluZy9hZGRyZXNzJylcbiAgICAgICAgLnJlcGx5KDIwMCwgeyBhZGRyZXNzOiAnMk4zTDljdTlXTjJEZjdYdmIxWThvd29rdURWajVIZHl2NGknIH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmYWtlVGVzdFYxU2FmZVdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIHJlY2lwaWVudHMsXG4gICAgICAgIHVuc3BlbnRzOiB1bnNwZW50c1RvU3BlbmQsXG4gICAgICAgIGZlZVJhdGU6IDEwMDAwLCAvLyAxMCBzYXQvYnl0ZVxuICAgICAgICBiaXRnb0ZlZToge1xuICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgICBhZGRyZXNzOiAnJyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBzY29wZS5pc0RvbmUoKS5zaG91bGQuYmUudHJ1ZSgpO1xuXG4gICAgICByZXN1bHQuZXN0aW1hdGVkU2l6ZS5zaG91bGQuZXF1YWwoODY2KTtcbiAgICAgIHJlc3VsdC5mZWUuc2hvdWxkLmVxdWFsKDg2NjApO1xuICAgICAgLy8gVGhpcyBzaG91bGQgZXF1YWwgdG8gMSBiZWNhdXNlIHRoaXMgaXMgYSBzd2VlcCB0cmFuc2FjdGlvbiBidXQgZHVlIHRvIGhhcmRjb2RlZCBhZGRpdGlvbiBvZlxuICAgICAgLy8gMSBjaGFuZ2Ugb3V0cHV0IGluIHRyYW5zYWN0aW9uQnVpbGRlciwgaXQgaXMgMi5cbiAgICAgIC8vIEJlY2F1c2Ugb2YgdGhpcyB0aGUgZXN0aW1hdGVkIHNpemUgb2YgdGhlIHRyYW5zYWN0aW9ucyBpcyBtb3JlIHRoYW4gd2hhdCBpdCBhY3R1YWxseSBpcyBpbiB0aGUgaGV4LlxuICAgICAgcmVzdWx0LnR4SW5mby5uT3V0cHV0cy5zaG91bGQuZXF1YWwoMik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2lnbnMgYW4gdW5zaWduZWQgdHggbWFkZSBvZiB1bmNvbXByZXNzZWQgcHVibGljIGtleXMgb2YgdjEgc2FmZSB3YWxsZXQgJiB2ZXJpZmllcyBzaWduYXR1cmVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qge1xuICAgICAgICBhZGRyZXNzLFxuICAgICAgICByZWRlZW1TY3JpcHQsXG4gICAgICAgIHNjcmlwdFB1YktleSxcbiAgICAgICAgdXNlcktleVdJRjogdXNlclNpZ25pbmdLZXksXG4gICAgICAgIGJpdGdvS2V5V0lGOiBiaXRnb1NpZ25pbmdLZXksXG4gICAgICAgIHVuc2lnbmVkVHhIZXgsXG4gICAgICAgIGhhbGZTaWduZWRUeEhleCxcbiAgICAgICAgZnVsbFNpZ25lZFR4SGV4LFxuICAgICAgfSA9IGF3YWl0IGdldEZpeHR1cmU8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KGAke19fZGlybmFtZX0vZml4dHVyZXMvc2lnbi10cmFuc2FjdGlvbi5qc29uYCk7XG4gICAgICBjb25zdCB0ZXN0Qml0Z28gPSBuZXcgQml0R29BUEkoeyBlbnY6ICd0ZXN0JywgY2xpZW50Q29uc3RhbnRzOiB7IGNvbnN0YW50czoge30gfSB9KTtcbiAgICAgIGNvbnN0IGZha2VUZXN0VjFTYWZlV2FsbGV0ID0gbmV3IFdhbGxldCh0ZXN0Qml0Z28sIHtcbiAgICAgICAgaWQ6IGFkZHJlc3MsXG4gICAgICAgIHByaXZhdGU6IHsgc2FmZTogeyByZWRlZW1TY3JpcHQgfSB9LFxuICAgICAgfSk7XG4gICAgICBjb25zdCB1bnNwZW50c1RvU3BlbmQgPSBbXG4gICAgICAgIHsgdmFsdWU6IDEwMDAwMCwgcmVkZWVtU2NyaXB0LCBzY3JpcHQ6IHNjcmlwdFB1YktleSB9LFxuICAgICAgICB7IHZhbHVlOiAxMDAwMDAsIHJlZGVlbVNjcmlwdCwgc2NyaXB0OiBzY3JpcHRQdWJLZXkgfSxcbiAgICAgIF07XG4gICAgICBjb25zdCBoYWxmU2lnbmVkVHggPSBhd2FpdCBmYWtlVGVzdFYxU2FmZVdhbGxldC5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0cmFuc2FjdGlvbkhleDogdW5zaWduZWRUeEhleCxcbiAgICAgICAgc2lnbmluZ0tleTogdXNlclNpZ25pbmdLZXksXG4gICAgICAgIHVuc3BlbnRzOiB1bnNwZW50c1RvU3BlbmQsXG4gICAgICAgIHZhbGlkYXRlOiB0cnVlLFxuICAgICAgfSk7XG4gICAgICBoYWxmU2lnbmVkVHgudHguc2hvdWxkLmVxdWFsKGhhbGZTaWduZWRUeEhleCk7XG5cbiAgICAgIGNvbnN0IGZ1bGxTaWduZWRUeCA9IGF3YWl0IGZha2VUZXN0VjFTYWZlV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHRyYW5zYWN0aW9uSGV4OiBoYWxmU2lnbmVkVHhIZXgsXG4gICAgICAgIHNpZ25pbmdLZXk6IGJpdGdvU2lnbmluZ0tleSxcbiAgICAgICAgdW5zcGVudHM6IHVuc3BlbnRzVG9TcGVuZCxcbiAgICAgICAgdmFsaWRhdGU6IHRydWUsXG4gICAgICAgIGZ1bGxMb2NhbFNpZ25pbmc6IHRydWUsXG4gICAgICB9KTtcbiAgICAgIC8vIFVwb24gY2FsbGluZyB0eGIuYnVpbGQoKSBpbnN0ZWFkIGFmdGVyIGdldHRpbmcgMiB2YWxpZCBzaWduYXR1cmVzLCB3ZSBnZXQgYSB2YWxpZCBmdWxsIHNpZ25lZCB0eCB0aGF0IHdhcyBicm9hZGNhc3RcbiAgICAgIC8vIGFuZCBjb25maXJtZWQgb24gdGVzdG5ldCBoZXJlOiBodHRwczovL21lbXBvb2wuc3BhY2UvdGVzdG5ldC90eC9iZGUwOWYxYmQ1ZTY2NjFjMjhkOTBlNGM5NjI5MTg1M2UyMWJhMTVhYjQyZjNlNGEzMDcxOWRlY2I3M2U3OTFiXG4gICAgICAvLyBJdCdzIHByZXNlbnQgaW4gdGhlIGZ1bGxTaWduZWRUeEhleEJ1aWxkQ29tcGxldGUgcHJvcGVydHkgb2YgdGhlIGZpeHR1cmUuXG4gICAgICBmdWxsU2lnbmVkVHgudHguc2hvdWxkLmVxdWFsKGZ1bGxTaWduZWRUeEhleCk7XG4gICAgfSk7XG5cbiAgICBpdCgnQkNIIHNlZ3dpdCBzaG91bGQgZmFpbCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlZ3dpdEFkZHJlc3MgPSBmYWtlUHJvZFdhbGxldC5nZW5lcmF0ZUFkZHJlc3MoeyBwYXRoOiAnLzEwLzEzJywgc2Vnd2l0OiB0cnVlIH0pO1xuICAgICAgY29uc3QgdW5zcGVudDogYW55ID0ge1xuICAgICAgICBhZGRyZXNzZXM6IFsnMk14S2tIOHlCM1M5WVdtVFFSYnZtYm9yWVF5UW5INXBldFAnXSxcbiAgICAgICAgdmFsdWU6ICcwLjE4NzUwMDAwJyxcbiAgICAgICAgdmFsdWVfaW50OiAxODc1MDAwMCxcbiAgICAgICAgdHhpZDogJzdkMjgyODc4YTg1ZGFlZTVkNDZlMDQzODI3ZGFlZDU3NTk2ZDc1ZDFhYTZlMDRmZDBjMDlhMzZmOTEzMDg4MWYnLFxuICAgICAgICBuOiAwLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgMzdiMzkzZmNlNjI3YTBlYzYzNGViNTQzZGRhMWU2MDhlMmQxYzc4YSBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNDM3YjM5M2ZjZTYyN2EwZWM2MzRlYjU0M2RkYTFlNjA4ZTJkMWM3OGE4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgIGlkOiA2MTMzMTYxNyxcbiAgICAgIH07XG4gICAgICBfLmV4dGVuZCh1bnNwZW50LCBzZWd3aXRBZGRyZXNzKTtcbiAgICAgIHVuc3BlbnQudmFsdWUgPSB1bnNwZW50LnZhbHVlX2ludDtcbiAgICAgIHVuc3BlbnQudHhfaGFzaCA9IHVuc3BlbnQudHhpZDtcbiAgICAgIHVuc3BlbnQudHhfb3V0cHV0X24gPSB1bnNwZW50Lm47XG4gICAgICB1bnNwZW50LnNjcmlwdCA9IHVuc3BlbnQub3V0cHV0U2NyaXB0O1xuXG4gICAgICBub2NrKGJnVXJsKS5wb3N0KCcvYXBpL3YxL2JpbGxpbmcvYWRkcmVzcycpLnJlcGx5KDIwMCwgeyBhZGRyZXNzOiAnMk1zd1Fqa3ZONm9XWWRFN0wyYnJKNWNBQU1qUG1HNTlvY28nIH0pO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5jcmVhdGVUcmFuc2FjdGlvbih7XG4gICAgICAgIGNoYW5nZUFkZHJlc3M6IHNlZ3dpdEFkZHJlc3MuYWRkcmVzcyxcbiAgICAgICAgdW5zcGVudHM6IFt1bnNwZW50XSxcbiAgICAgICAgcmVjaXBpZW50czoge30sXG4gICAgICAgIG5vU3BsaXRDaGFuZ2U6IHRydWUsXG4gICAgICAgIGZvcmNlQ2hhbmdlQXRFbmQ6IHRydWUsXG4gICAgICAgIGZlZVJhdGU6IDEwMDAwLFxuICAgICAgICBiaXRnb0ZlZToge1xuICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgICBhZGRyZXNzOiAnJyxcbiAgICAgICAgfSxcbiAgICAgICAgb3BSZXR1cm5zOiB7ICdCaXRHbyBzZWd3aXQgdGVzdCc6IDEwMDAgfSxcbiAgICAgIH0pKSBhcyBhbnk7XG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleC5zaG91bGQuZXF1YWwoXG4gICAgICAgICcwMTAwMDAwMDAxMWY4ODMwOTE2ZmEzMDkwY2ZkMDQ2ZWFhZDE3NTZkNTk1N2VkZGEyNzM4MDQ2ZWQ0ZTVhZTVkYTg3ODI4Mjg3ZDAwMDAwMDAwMDBmZmZmZmZmZjAyZTgwMzAwMDAwMDAwMDAwMDEzNmExMTQyNjk3NDQ3NmYyMDczNjU2Nzc3Njk3NDIwNzQ2NTczNzQwZTBmMWUwMTAwMDAwMDAwMTdhOTE0MzdiMzkzZmNlNjI3YTBlYzYzNGViNTQzZGRhMWU2MDhlMmQxYzc4YTg3MDAwMDAwMDAnXG4gICAgICApO1xuXG4gICAgICAvLyBhZGQgZmlyc3Qgc2lnbmF0dXJlXG4gICAgICB0cmFuc2FjdGlvbi5rZXljaGFpbiA9IHVzZXJLZXlwYWlyO1xuICAgICAgdHJhbnNhY3Rpb24uZm9yY2VCQ0ggPSB0cnVlO1xuICAgICAgKCgpID0+IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpLnNob3VsZC50aHJvdygnQkNIIGRvZXMgbm90IHN1cHBvcnQgc2Vnd2l0IGlucHV0cycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ21peGVkIHAyc2ggJiBzZWd3aXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwMnNoQWRkcmVzcyA9IGZha2VXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8wLzE0Jywgc2Vnd2l0OiBmYWxzZSB9KTtcbiAgICAgIGNvbnN0IHNlZ3dpdEFkZHJlc3MgPSBmYWtlV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMTAvMTQnLCBzZWd3aXQ6IHRydWUgfSk7XG4gICAgICBjb25zdCBwMnNoVW5zcGVudCA9IHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJzJONTMzZnFneVBZS1ZEODkybkJSYVltRkhiYlR5a2hZU0V3J10sXG4gICAgICAgIHZhbHVlOiAnMi45OTk5NjYxMCcsXG4gICAgICAgIHZhbHVlX2ludDogMjk5OTk2NjEwLFxuICAgICAgICB0eGlkOiAnZjY1NGNlMGE1YmUzZjEyZGY3ZmVjZjRlZTc3N2I2ZDg2YjVhYThjNzEwZWY2OTQ2ZWMxMjEyMDZiNGY4NzU3YycsXG4gICAgICAgIG46IDEsXG4gICAgICAgIHNjcmlwdF9wdWJfa2V5OiB7XG4gICAgICAgICAgYXNtOiAnT1BfSEFTSDE2MCA4MTUzZTdhMzU1MDgwODhiNmNmNTk5MjI2NzkyYzdkZTJkYmZmMjUyIE9QX0VRVUFMJyxcbiAgICAgICAgICBoZXg6ICdhOTE0ODE1M2U3YTM1NTA4MDg4YjZjZjU5OTIyNjc5MmM3ZGUyZGJmZjI1Mjg3JyxcbiAgICAgICAgfSxcbiAgICAgICAgcmVxX3NpZ3M6IDEsXG4gICAgICAgIHR5cGU6ICdzY3JpcHRoYXNoJyxcbiAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgaWQ6IDYxMzMxMjYzLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHNlZ3dpdFVuc3BlbnQgPSB7XG4gICAgICAgIGFkZHJlc3NlczogWycyTkJ0cFhjRHJ1ZjN6UnV0bUY0QWJDTUZOUUhYc0dOUDZrVCddLFxuICAgICAgICB2YWx1ZTogJzEuNTAwMDAwMDAnLFxuICAgICAgICB2YWx1ZV9pbnQ6IDE1MDAwMDAwMCxcbiAgICAgICAgdHhpZDogJ2E0NDA5YzNmMDQyZmFlNjdiODkwYWMzZGY0MGVmMGRiMDM1MzljNjczMzFmZDdlOTI2MDUxMTg5M2I0ZjlmMjQnLFxuICAgICAgICBuOiAwLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgY2M4ZTdjYmY0ODEzODlkMzE4M2E1OTBhY2ZhNmFhNjZlYjk3YzhlMSBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNGNjOGU3Y2JmNDgxMzg5ZDMxODNhNTkwYWNmYTZhYTY2ZWI5N2M4ZTE4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgIGlkOiA2MTMzMDg4MixcbiAgICAgIH07XG4gICAgICBjb25zdCBhZGRyZXNzZXMgPSBbcDJzaEFkZHJlc3MsIHNlZ3dpdEFkZHJlc3NdO1xuICAgICAgY29uc3QgdW5zcGVudHMgPSBbcDJzaFVuc3BlbnQsIHNlZ3dpdFVuc3BlbnRdLm1hcCgodW5zcGVudDogYW55LCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBhZGRyZXNzID0gYWRkcmVzc2VzW2luZGV4XTtcbiAgICAgICAgXy5leHRlbmQodW5zcGVudCwgYWRkcmVzcyk7XG4gICAgICAgIHVuc3BlbnQudmFsdWUgPSB1bnNwZW50LnZhbHVlX2ludDtcbiAgICAgICAgdW5zcGVudC50eF9oYXNoID0gdW5zcGVudC50eGlkO1xuICAgICAgICB1bnNwZW50LnR4X291dHB1dF9uID0gdW5zcGVudC5uO1xuICAgICAgICB1bnNwZW50LnNjcmlwdCA9IHVuc3BlbnQub3V0cHV0U2NyaXB0O1xuICAgICAgICByZXR1cm4gdW5zcGVudDtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBmYWtlV2FsbGV0LmNyZWF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgY2hhbmdlQWRkcmVzczogcDJzaEFkZHJlc3MuYWRkcmVzcyxcbiAgICAgICAgdW5zcGVudHM6IHVuc3BlbnRzLFxuICAgICAgICByZWNpcGllbnRzOiB7fSxcbiAgICAgICAgbm9TcGxpdENoYW5nZTogdHJ1ZSxcbiAgICAgICAgZm9yY2VDaGFuZ2VBdEVuZDogdHJ1ZSxcbiAgICAgICAgZmVlUmF0ZTogMTAwMDAsXG4gICAgICAgIG9wUmV0dXJuczogeyAnQml0R28gbWl4ZWQgcDJzaCAmIHNlZ3dpdCB0ZXN0JzogNDAwMDAwMDAwIH0sXG4gICAgICAgIGJpdGdvRmVlOiB7XG4gICAgICAgICAgYW1vdW50OiA4MTc2MCxcbiAgICAgICAgICBhZGRyZXNzOiAnMk5EN2pRUjVpdGpHVGJoM0RLZ2JwWldTWTl1bmdEcndjd2InLFxuICAgICAgICB9LFxuICAgICAgfSkpIGFzIGFueTtcbiAgICAgIHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDI3Yzc1ZjhiNDA2MTIxMmVjNDY2OWVmMTBjN2E4NWE2YmQ4YjY3N2U3NGVjZmZlZjcyZGYxZTM1YjBhY2U1NGY2MDEwMDAwMDAwMGZmZmZmZmZmMjQ5ZjRmM2I4OTExMDUyNmU5ZDcxZjMzNjc5YzUzMDNkYmYwMGVmNDNkYWM5MGI4NjdhZTJmMDQzZjljNDBhNDAwMDAwMDAwMDBmZmZmZmZmZjAzMDA4NGQ3MTcwMDAwMDAwMDIwNmExZTQyNjk3NDQ3NmYyMDZkNjk3ODY1NjQyMDcwMzI3MzY4MjAyNjIwNzM2NTY3Nzc2OTc0MjA3NDY1NzM3NGIwOGZmOTAyMDAwMDAwMDAxN2E5MTQ4MTUzZTdhMzU1MDgwODhiNmNmNTk5MjI2NzkyYzdkZTJkYmZmMjUyODc2MDNmMDEwMDAwMDAwMDAwMTdhOTE0ZDlmN2JlNDc5NzVjMDM2Zjk0MjI4YjBiZmQ3MDcwMTkxMjc1OGJhOTg3MDAwMDAwMDAnXG4gICAgICApO1xuXG4gICAgICAvLyBhZGQgZmlyc3Qgc2lnbmF0dXJlXG4gICAgICB0cmFuc2FjdGlvbi5rZXljaGFpbiA9IHVzZXJLZXlwYWlyO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlMSA9IChhd2FpdCBmYWtlUHJvZFdhbGxldC5zaWduVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24pKSBhcyBhbnk7XG4gICAgICBzaWduYXR1cmUxLnR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDAwMTAyN2M3NWY4YjQwNjEyMTJlYzQ2NjllZjEwYzdhODVhNmJkOGI2NzdlNzRlY2ZmZWY3MmRmMWUzNWIwYWNlNTRmNjAxMDAwMDAwYjcwMDQ4MzA0NTAyMjEwMGZmYzQ1ZDkzY2JhZjRjMWM4NTBlMjFmMjc3YzViMzExZDNlMzk1N2YxMzM4OTU1Y2IxNjVkNzJhNzY4YTA1NGMwMjIwNTIwMjA1OTNiMzY3ODFlZWEwMGE5ZjhkY2JlYjc2NjA4ZjkyMGM3YTkzM2E5MDg4MzE4YWIyZjcwYzExZTFkOTAxMDAwMDRjNjk1MjIxMDNkYTk1YjI4YTEzYWEyZDRiYjQ5MGQ3MDYyOGUyZTVkOTEyNDYxZDM3NWZlZjM4MWFhZGQ4OWRjMTI1NjIyMDc1MjEwMzEyMTI4N2E1MTBjNWYzMmU4YmE3MmQyNDc5ZTkwZWI1MmJhNDRhNDY3MTczZGYzMzlmZWIwZmYyMTVmMTAwZTMyMTAyOTc3Y2RmYmVlNzYwNjZhZTczOWRiNzJkNTUzNzFhZDQ5ZGM2NzEyZmI4ZjJmM2Y2OWJiMWE0YzI0MjJiMGIxYTUzYWVmZmZmZmZmZjI0OWY0ZjNiODkxMTA1MjZlOWQ3MWYzMzY3OWM1MzAzZGJmMDBlZjQzZGFjOTBiODY3YWUyZjA0M2Y5YzQwYTQwMDAwMDAwMDIzMjIwMDIwOGI5MWFhMDNlYjBmN2YzMWUzOTE3MDg4MDg0MTY4YmE1MjgyYTkxNWU3Y2RlMGE1YTkzNGI3ZWEwMmViMDU3YmZmZmZmZmZmMDMwMDg0ZDcxNzAwMDAwMDAwMjA2YTFlNDI2OTc0NDc2ZjIwNmQ2OTc4NjU2NDIwNzAzMjczNjgyMDI2MjA3MzY1Njc3NzY5NzQyMDc0NjU3Mzc0YjA4ZmY5MDIwMDAwMDAwMDE3YTkxNDgxNTNlN2EzNTUwODA4OGI2Y2Y1OTkyMjY3OTJjN2RlMmRiZmYyNTI4NzYwM2YwMTAwMDAwMDAwMDAxN2E5MTRkOWY3YmU0Nzk3NWMwMzZmOTQyMjhiMGJmZDcwNzAxOTEyNzU4YmE5ODcwMDA1MDA0NzMwNDQwMjIwNTg5OGJlZTcxMTQ2N2MwOWE1ZTIyZTFkY2IxYTExZmNlMWEwZDZlYTEyOWQ5MTFmODEzZjg3YzdkNDVlMDY3YjAyMjAyZjY5ZmIxMThiYmYwYjA3MmVkMjZkNzJjZjgwNzNlN2FjZDY2YzIwNTQxOWE0YTAwZjg2YTdiYTBmNmUzZGQ2MDEwMDAwNjk1MjIxMDMwNzgwMTg2YzBiZTVkZjBkMmQ2MmNmNTRjYzJmM2QyYzA5OTExZTM3N2FhOTViNWZlODc1ZmEzNTJhZWQwYTU5MjEwM2YzMjM3ZWRkMmQ4NzAxMGU4ZmU5ZjQzZjM0ZThjNjNkZTYzODQyODNkZTkwOTc5NWQ2MmFmNGRkYjRkNTc5NTQyMTAyYWQwM2RlNTUwNGVmOTQ3ZTRlNmVlMmZhNmIxNWQxNTBkNTUzYzIxMjc1ZjQ5ZjJjZTIzNTlkOWZkZWRiOWFkZTUzYWUwMDAwMDAwMCdcbiAgICAgICk7XG5cbiAgICAgIC8vIGFkZCBzZWNvbmQgc2lnbmF0dXJlXG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleCA9IHNpZ25hdHVyZTEudHg7XG4gICAgICB0cmFuc2FjdGlvbi5rZXljaGFpbiA9IGJhY2t1cEtleXBhaXI7XG4gICAgICB0cmFuc2FjdGlvbi5mdWxsTG9jYWxTaWduaW5nID0gdHJ1ZTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZTIgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSkgYXMgYW55O1xuICAgICAgLy8gdGhpcyB0cmFuc2FjdGlvbiBoYXMgYWN0dWFsbHkgd29ya2VkOiBodHRwczovL3Rlc3RuZXQuc21hcnRiaXQuY29tLmF1L3R4L2UyZjY5NmJjYmE5MWEzNzZjMzZiYjUyNWRmOGMzNjc5MzhmNmUyZmQ2MzQ0YzkwNTg3YmYxMjgwMjA5MTEyNGNcbiAgICAgIC8vIE5vdGUgdGhhdCB0aGUgdHggaGV4IGJlbG93IG5vIGxvbmdlciBjb3JyZXNwb25kcyB0byB0aGUgYWJvdmUgdHJhbnNhY3Rpb24gYmVjYXVzZSBvdXIgZmVlIGVzdGltYXRpb24gaGFzXG4gICAgICAvLyBjaGFuZ2VkLCBjaGFuZ2luZyB0aGUgb3V0cHV0IGFtb3VudHMgYW5kIHRodXMgdGhlIHR4IGhleC5cbiAgICAgIHNpZ25hdHVyZTIudHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMDAxMDI3Yzc1ZjhiNDA2MTIxMmVjNDY2OWVmMTBjN2E4NWE2YmQ4YjY3N2U3NGVjZmZlZjcyZGYxZTM1YjBhY2U1NGY2MDEwMDAwMDBmZGZmMDAwMDQ4MzA0NTAyMjEwMGZmYzQ1ZDkzY2JhZjRjMWM4NTBlMjFmMjc3YzViMzExZDNlMzk1N2YxMzM4OTU1Y2IxNjVkNzJhNzY4YTA1NGMwMjIwNTIwMjA1OTNiMzY3ODFlZWEwMGE5ZjhkY2JlYjc2NjA4ZjkyMGM3YTkzM2E5MDg4MzE4YWIyZjcwYzExZTFkOTAxNDgzMDQ1MDIyMTAwODI1NGQxMDA0MDFhM2E4MzFlZDAxOWUxNjYyZGJkOTBiOTZjNmM0MDcyYjgxY2U2NDBkMTUyYmMyOTI5NWMxMDAyMjAxM2Y4NmM1YWY1NzE2MjM0OTk5YTdiZDZlOTRmYzhmNDI4Zjc2OTdjYzMxMzhiMzY0OWQwZWM0ZGQ4NjgxYmM3MDEwMDRjNjk1MjIxMDNkYTk1YjI4YTEzYWEyZDRiYjQ5MGQ3MDYyOGUyZTVkOTEyNDYxZDM3NWZlZjM4MWFhZGQ4OWRjMTI1NjIyMDc1MjEwMzEyMTI4N2E1MTBjNWYzMmU4YmE3MmQyNDc5ZTkwZWI1MmJhNDRhNDY3MTczZGYzMzlmZWIwZmYyMTVmMTAwZTMyMTAyOTc3Y2RmYmVlNzYwNjZhZTczOWRiNzJkNTUzNzFhZDQ5ZGM2NzEyZmI4ZjJmM2Y2OWJiMWE0YzI0MjJiMGIxYTUzYWVmZmZmZmZmZjI0OWY0ZjNiODkxMTA1MjZlOWQ3MWYzMzY3OWM1MzAzZGJmMDBlZjQzZGFjOTBiODY3YWUyZjA0M2Y5YzQwYTQwMDAwMDAwMDIzMjIwMDIwOGI5MWFhMDNlYjBmN2YzMWUzOTE3MDg4MDg0MTY4YmE1MjgyYTkxNWU3Y2RlMGE1YTkzNGI3ZWEwMmViMDU3YmZmZmZmZmZmMDMwMDg0ZDcxNzAwMDAwMDAwMjA2YTFlNDI2OTc0NDc2ZjIwNmQ2OTc4NjU2NDIwNzAzMjczNjgyMDI2MjA3MzY1Njc3NzY5NzQyMDc0NjU3Mzc0YjA4ZmY5MDIwMDAwMDAwMDE3YTkxNDgxNTNlN2EzNTUwODA4OGI2Y2Y1OTkyMjY3OTJjN2RlMmRiZmYyNTI4NzYwM2YwMTAwMDAwMDAwMDAxN2E5MTRkOWY3YmU0Nzk3NWMwMzZmOTQyMjhiMGJmZDcwNzAxOTEyNzU4YmE5ODcwMDA1MDA0NzMwNDQwMjIwNTg5OGJlZTcxMTQ2N2MwOWE1ZTIyZTFkY2IxYTExZmNlMWEwZDZlYTEyOWQ5MTFmODEzZjg3YzdkNDVlMDY3YjAyMjAyZjY5ZmIxMThiYmYwYjA3MmVkMjZkNzJjZjgwNzNlN2FjZDY2YzIwNTQxOWE0YTAwZjg2YTdiYTBmNmUzZGQ2MDE0NzMwNDQwMjIwNzcxM2Q2NzFiNDU5ODk2ODhlMjY2NWMyYjExYWI3ZTVlYThkNTdlYjE0ZjlkYTIzM2MwOTVkYWJlNDQxMzA4ZDAyMjA2OTUyMWI1YWViMDcxYjA3YTcwYTcxOTdhMGMyYmJjNDBhMjNhZTYzYTA0MTYwY2YzNjI3MjUwYzRiYTRjNDBmMDEwMDY5NTIyMTAzMDc4MDE4NmMwYmU1ZGYwZDJkNjJjZjU0Y2MyZjNkMmMwOTkxMWUzNzdhYTk1YjVmZTg3NWZhMzUyYWVkMGE1OTIxMDNmMzIzN2VkZDJkODcwMTBlOGZlOWY0M2YzNGU4YzYzZGU2Mzg0MjgzZGU5MDk3OTVkNjJhZjRkZGI0ZDU3OTU0MjEwMmFkMDNkZTU1MDRlZjk0N2U0ZTZlZTJmYTZiMTVkMTUwZDU1M2MyMTI3NWY0OWYyY2UyMzU5ZDlmZGVkYjlhZGU1M2FlMDAwMDAwMDAnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZW5kIHRvIGJlY2gzMiByZWNpcGllbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwMnNoQWRkcmVzcyA9IGZha2VXYWxsZXQuZ2VuZXJhdGVBZGRyZXNzKHsgcGF0aDogJy8wLzE0Jywgc2Vnd2l0OiBmYWxzZSB9KTtcbiAgICAgIGNvbnN0IHNlZ3dpdEFkZHJlc3MgPSBmYWtlV2FsbGV0LmdlbmVyYXRlQWRkcmVzcyh7IHBhdGg6ICcvMTAvMTQnLCBzZWd3aXQ6IHRydWUgfSk7XG4gICAgICBjb25zdCBwMnNoVW5zcGVudCA9IHtcbiAgICAgICAgYWRkcmVzc2VzOiBbJzJONTMzZnFneVBZS1ZEODkybkJSYVltRkhiYlR5a2hZU0V3J10sXG4gICAgICAgIHZhbHVlOiAnMi45OTk5NjYxMCcsXG4gICAgICAgIHZhbHVlX2ludDogMjk5OTk2NjEwLFxuICAgICAgICB0eGlkOiAnZjY1NGNlMGE1YmUzZjEyZGY3ZmVjZjRlZTc3N2I2ZDg2YjVhYThjNzEwZWY2OTQ2ZWMxMjEyMDZiNGY4NzU3YycsXG4gICAgICAgIG46IDEsXG4gICAgICAgIHNjcmlwdF9wdWJfa2V5OiB7XG4gICAgICAgICAgYXNtOiAnT1BfSEFTSDE2MCA4MTUzZTdhMzU1MDgwODhiNmNmNTk5MjI2NzkyYzdkZTJkYmZmMjUyIE9QX0VRVUFMJyxcbiAgICAgICAgICBoZXg6ICdhOTE0ODE1M2U3YTM1NTA4MDg4YjZjZjU5OTIyNjc5MmM3ZGUyZGJmZjI1Mjg3JyxcbiAgICAgICAgfSxcbiAgICAgICAgcmVxX3NpZ3M6IDEsXG4gICAgICAgIHR5cGU6ICdzY3JpcHRoYXNoJyxcbiAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgaWQ6IDYxMzMxMjYzLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHNlZ3dpdFVuc3BlbnQgPSB7XG4gICAgICAgIGFkZHJlc3NlczogWycyTkJ0cFhjRHJ1ZjN6UnV0bUY0QWJDTUZOUUhYc0dOUDZrVCddLFxuICAgICAgICB2YWx1ZTogJzEuNTAwMDAwMDAnLFxuICAgICAgICB2YWx1ZV9pbnQ6IDE1MDAwMDAwMCxcbiAgICAgICAgdHhpZDogJ2E0NDA5YzNmMDQyZmFlNjdiODkwYWMzZGY0MGVmMGRiMDM1MzljNjczMzFmZDdlOTI2MDUxMTg5M2I0ZjlmMjQnLFxuICAgICAgICBuOiAwLFxuICAgICAgICBzY3JpcHRfcHViX2tleToge1xuICAgICAgICAgIGFzbTogJ09QX0hBU0gxNjAgY2M4ZTdjYmY0ODEzODlkMzE4M2E1OTBhY2ZhNmFhNjZlYjk3YzhlMSBPUF9FUVVBTCcsXG4gICAgICAgICAgaGV4OiAnYTkxNGNjOGU3Y2JmNDgxMzg5ZDMxODNhNTkwYWNmYTZhYTY2ZWI5N2M4ZTE4NycsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcV9zaWdzOiAxLFxuICAgICAgICB0eXBlOiAnc2NyaXB0aGFzaCcsXG4gICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgIGlkOiA2MTMzMDg4MixcbiAgICAgIH07XG4gICAgICBjb25zdCBhZGRyZXNzZXMgPSBbcDJzaEFkZHJlc3MsIHNlZ3dpdEFkZHJlc3NdO1xuICAgICAgY29uc3QgdW5zcGVudHMgPSBbcDJzaFVuc3BlbnQsIHNlZ3dpdFVuc3BlbnRdLm1hcCgodW5zcGVudDogYW55LCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBhZGRyZXNzID0gYWRkcmVzc2VzW2luZGV4XTtcbiAgICAgICAgXy5leHRlbmQodW5zcGVudCwgYWRkcmVzcyk7XG4gICAgICAgIHVuc3BlbnQudmFsdWUgPSB1bnNwZW50LnZhbHVlX2ludDtcbiAgICAgICAgdW5zcGVudC50eF9oYXNoID0gdW5zcGVudC50eGlkO1xuICAgICAgICB1bnNwZW50LnR4X291dHB1dF9uID0gdW5zcGVudC5uO1xuICAgICAgICB1bnNwZW50LnNjcmlwdCA9IHVuc3BlbnQub3V0cHV0U2NyaXB0O1xuICAgICAgICByZXR1cm4gdW5zcGVudDtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBmYWtlV2FsbGV0LmNyZWF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgY2hhbmdlQWRkcmVzczogcDJzaEFkZHJlc3MuYWRkcmVzcyxcbiAgICAgICAgdW5zcGVudHM6IHVuc3BlbnRzLFxuICAgICAgICByZWNpcGllbnRzOiB7IHRiMXFndXp5azR3NmthcXRwc2N6czVhajB3OHI3NTk4anEzNmVnbThlOTh3cXBoM3J3bWV4NjhzZXNsZ3NnOiAzMDAwMDAgfSxcbiAgICAgICAgbm9TcGxpdENoYW5nZTogdHJ1ZSxcbiAgICAgICAgZm9yY2VDaGFuZ2VBdEVuZDogdHJ1ZSxcbiAgICAgICAgZmVlUmF0ZTogMTAwMDAsXG4gICAgICAgIG9wUmV0dXJuczogeyAnQml0R28gbWl4ZWQgcDJzaCAmIHNlZ3dpdCB0ZXN0JzogNDAwMDAwMDAwIH0sXG4gICAgICAgIGJpdGdvRmVlOiB7XG4gICAgICAgICAgYW1vdW50OiA4MTc2MCxcbiAgICAgICAgICBhZGRyZXNzOiAnMk5EN2pRUjVpdGpHVGJoM0RLZ2JwWldTWTl1bmdEcndjd2InLFxuICAgICAgICB9LFxuICAgICAgfSkpIGFzIGFueTtcbiAgICAgIHRyYW5zYWN0aW9uLnRyYW5zYWN0aW9uSGV4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDI3Yzc1ZjhiNDA2MTIxMmVjNDY2OWVmMTBjN2E4NWE2YmQ4YjY3N2U3NGVjZmZlZjcyZGYxZTM1YjBhY2U1NGY2MDEwMDAwMDAwMGZmZmZmZmZmMjQ5ZjRmM2I4OTExMDUyNmU5ZDcxZjMzNjc5YzUzMDNkYmYwMGVmNDNkYWM5MGI4NjdhZTJmMDQzZjljNDBhNDAwMDAwMDAwMDBmZmZmZmZmZjA0ZTA5MzA0MDAwMDAwMDAwMDIyMDAyMDQ3MDQ0YjU1ZGFiNzQwYjBjMzAyODUzYjI3YjhlM2Y1MGE3OTAyM2FjYTM2N2M5NGVlMDA2ZjExYmI3OTM2OGYwMDg0ZDcxNzAwMDAwMDAwMjA2YTFlNDI2OTc0NDc2ZjIwNmQ2OTc4NjU2NDIwNzAzMjczNjgyMDI2MjA3MzY1Njc3NzY5NzQyMDc0NjU3Mzc0N2NmYWY0MDIwMDAwMDAwMDE3YTkxNDgxNTNlN2EzNTUwODA4OGI2Y2Y1OTkyMjY3OTJjN2RlMmRiZmYyNTI4NzYwM2YwMTAwMDAwMDAwMDAxN2E5MTRkOWY3YmU0Nzk3NWMwMzZmOTQyMjhiMGJmZDcwNzAxOTEyNzU4YmE5ODcwMDAwMDAwMCdcbiAgICAgICk7XG5cbiAgICAgIC8vIGFkZCBmaXJzdCBzaWduYXR1cmVcbiAgICAgIHRyYW5zYWN0aW9uLmtleWNoYWluID0gdXNlcktleXBhaXI7XG4gICAgICBjb25zdCBzaWduYXR1cmUxID0gKGF3YWl0IGZha2VQcm9kV2FsbGV0LnNpZ25UcmFuc2FjdGlvbih0cmFuc2FjdGlvbikpIGFzIGFueTtcbiAgICAgIHNpZ25hdHVyZTEudHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnMDEwMDAwMDAwMDAxMDI3Yzc1ZjhiNDA2MTIxMmVjNDY2OWVmMTBjN2E4NWE2YmQ4YjY3N2U3NGVjZmZlZjcyZGYxZTM1YjBhY2U1NGY2MDEwMDAwMDBiNzAwNDgzMDQ1MDIyMTAwODgwOTM3NzYzNGU2NjdkNmUxOWYzOGExMzhhNTViMmI2MzcwMzEyYWY3NmE1Y2EzYjc3NmRmNjFmYzcxOTYxNzAyMjAyMWQ5MDM0N2I5MDg1YWI3MWE3NmM4NDAwZjk4NGUzMjJjMTU0NTFlY2M2NzNkZDM3ZGUzMDg4NzQzNmQzN2I0MDEwMDAwNGM2OTUyMjEwM2RhOTViMjhhMTNhYTJkNGJiNDkwZDcwNjI4ZTJlNWQ5MTI0NjFkMzc1ZmVmMzgxYWFkZDg5ZGMxMjU2MjIwNzUyMTAzMTIxMjg3YTUxMGM1ZjMyZThiYTcyZDI0NzllOTBlYjUyYmE0NGE0NjcxNzNkZjMzOWZlYjBmZjIxNWYxMDBlMzIxMDI5NzdjZGZiZWU3NjA2NmFlNzM5ZGI3MmQ1NTM3MWFkNDlkYzY3MTJmYjhmMmYzZjY5YmIxYTRjMjQyMmIwYjFhNTNhZWZmZmZmZmZmMjQ5ZjRmM2I4OTExMDUyNmU5ZDcxZjMzNjc5YzUzMDNkYmYwMGVmNDNkYWM5MGI4NjdhZTJmMDQzZjljNDBhNDAwMDAwMDAwMjMyMjAwMjA4YjkxYWEwM2ViMGY3ZjMxZTM5MTcwODgwODQxNjhiYTUyODJhOTE1ZTdjZGUwYTVhOTM0YjdlYTAyZWIwNTdiZmZmZmZmZmYwNGUwOTMwNDAwMDAwMDAwMDAyMjAwMjA0NzA0NGI1NWRhYjc0MGIwYzMwMjg1M2IyN2I4ZTNmNTBhNzkwMjNhY2EzNjdjOTRlZTAwNmYxMWJiNzkzNjhmMDA4NGQ3MTcwMDAwMDAwMDIwNmExZTQyNjk3NDQ3NmYyMDZkNjk3ODY1NjQyMDcwMzI3MzY4MjAyNjIwNzM2NTY3Nzc2OTc0MjA3NDY1NzM3NDdjZmFmNDAyMDAwMDAwMDAxN2E5MTQ4MTUzZTdhMzU1MDgwODhiNmNmNTk5MjI2NzkyYzdkZTJkYmZmMjUyODc2MDNmMDEwMDAwMDAwMDAwMTdhOTE0ZDlmN2JlNDc5NzVjMDM2Zjk0MjI4YjBiZmQ3MDcwMTkxMjc1OGJhOTg3MDAwNTAwNDgzMDQ1MDIyMTAwOGI5NWFjODNlNDRjNzI3Yjc5ZmZiZjQ1NzExNzE5MjVkMDZmODgzYTA1YzEyMmIzYjMzYzA1NWYwYmZmYTcwMTAyMjA3YjVlZTM0MTJlYThhNWNlYzRhNWMzODZmMWI0NjRhYjY4ZDUzMWM2YzY5NzA3N2JjNDYyYzA1ZWI0NGEyODMyMDEwMDAwNjk1MjIxMDMwNzgwMTg2YzBiZTVkZjBkMmQ2MmNmNTRjYzJmM2QyYzA5OTExZTM3N2FhOTViNWZlODc1ZmEzNTJhZWQwYTU5MjEwM2YzMjM3ZWRkMmQ4NzAxMGU4ZmU5ZjQzZjM0ZThjNjNkZTYzODQyODNkZTkwOTc5NWQ2MmFmNGRkYjRkNTc5NTQyMTAyYWQwM2RlNTUwNGVmOTQ3ZTRlNmVlMmZhNmIxNWQxNTBkNTUzYzIxMjc1ZjQ5ZjJjZTIzNTlkOWZkZWRiOWFkZTUzYWUwMDAwMDAwMCdcbiAgICAgICk7XG5cbiAgICAgIC8vIGFkZCBzZWNvbmQgc2lnbmF0dXJlXG4gICAgICB0cmFuc2FjdGlvbi50cmFuc2FjdGlvbkhleCA9IHNpZ25hdHVyZTEudHg7XG4gICAgICB0cmFuc2FjdGlvbi5rZXljaGFpbiA9IGJhY2t1cEtleXBhaXI7XG4gICAgICB0cmFuc2FjdGlvbi5mdWxsTG9jYWxTaWduaW5nID0gdHJ1ZTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZTIgPSAoYXdhaXQgZmFrZVByb2RXYWxsZXQuc2lnblRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSkgYXMgYW55O1xuICAgICAgY29uc29sZS5sb2coJ3NpZ25hdHVyZTEgJyArIEpTT04uc3RyaW5naWZ5KHNpZ25hdHVyZTIpKTtcbiAgICAgIC8vIHRoaXMgdHJhbnNhY3Rpb24gaGFzIGFjdHVhbGx5IHdvcmtlZDogaHR0cHM6Ly90ZXN0bmV0LnNtYXJ0Yml0LmNvbS5hdS90eC9lMmY2OTZiY2JhOTFhMzc2YzM2YmI1MjVkZjhjMzY3OTM4ZjZlMmZkNjM0NGM5MDU4N2JmMTI4MDIwOTExMjRjXG4gICAgICAvLyBOb3RlIHRoYXQgdGhlIHR4IGhleCBiZWxvdyBubyBsb25nZXIgY29ycmVzcG9uZHMgdG8gdGhlIGFib3ZlIHRyYW5zYWN0aW9uIGJlY2F1c2Ugb3VyIGZlZSBlc3RpbWF0aW9uIGhhc1xuICAgICAgLy8gY2hhbmdlZCwgY2hhbmdpbmcgdGhlIG91dHB1dCBhbW91bnRzIGFuZCB0aHVzIHRoZSB0eCBoZXguXG4gICAgICBzaWduYXR1cmUyLnR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzAxMDAwMDAwMDAwMTAyN2M3NWY4YjQwNjEyMTJlYzQ2NjllZjEwYzdhODVhNmJkOGI2NzdlNzRlY2ZmZWY3MmRmMWUzNWIwYWNlNTRmNjAxMDAwMDAwZmRmZTAwMDA0ODMwNDUwMjIxMDA4ODA5Mzc3NjM0ZTY2N2Q2ZTE5ZjM4YTEzOGE1NWIyYjYzNzAzMTJhZjc2YTVjYTNiNzc2ZGY2MWZjNzE5NjE3MDIyMDIxZDkwMzQ3YjkwODVhYjcxYTc2Yzg0MDBmOTg0ZTMyMmMxNTQ1MWVjYzY3M2RkMzdkZTMwODg3NDM2ZDM3YjQwMTQ3MzA0NDAyMjA1YTU4ZTYwMjA0MmI4ZThhNWRhNTA5ZDE5Y2UzMTA1MDE0N2RkMGZmY2ZiZTJiYjMzN2MyM2Q0Yzg4ZjRjYzQxMDIyMDc1YmZhNDU1ZDFmNzRlMzBmYmQ5Yzc4NmNkNDgxMWExZGVmZTU0MzEwZjIzNWI0MTkzY2U0ZmZhMGU4MzA5YTEwMTAwNGM2OTUyMjEwM2RhOTViMjhhMTNhYTJkNGJiNDkwZDcwNjI4ZTJlNWQ5MTI0NjFkMzc1ZmVmMzgxYWFkZDg5ZGMxMjU2MjIwNzUyMTAzMTIxMjg3YTUxMGM1ZjMyZThiYTcyZDI0NzllOTBlYjUyYmE0NGE0NjcxNzNkZjMzOWZlYjBmZjIxNWYxMDBlMzIxMDI5NzdjZGZiZWU3NjA2NmFlNzM5ZGI3MmQ1NTM3MWFkNDlkYzY3MTJmYjhmMmYzZjY5YmIxYTRjMjQyMmIwYjFhNTNhZWZmZmZmZmZmMjQ5ZjRmM2I4OTExMDUyNmU5ZDcxZjMzNjc5YzUzMDNkYmYwMGVmNDNkYWM5MGI4NjdhZTJmMDQzZjljNDBhNDAwMDAwMDAwMjMyMjAwMjA4YjkxYWEwM2ViMGY3ZjMxZTM5MTcwODgwODQxNjhiYTUyODJhOTE1ZTdjZGUwYTVhOTM0YjdlYTAyZWIwNTdiZmZmZmZmZmYwNGUwOTMwNDAwMDAwMDAwMDAyMjAwMjA0NzA0NGI1NWRhYjc0MGIwYzMwMjg1M2IyN2I4ZTNmNTBhNzkwMjNhY2EzNjdjOTRlZTAwNmYxMWJiNzkzNjhmMDA4NGQ3MTcwMDAwMDAwMDIwNmExZTQyNjk3NDQ3NmYyMDZkNjk3ODY1NjQyMDcwMzI3MzY4MjAyNjIwNzM2NTY3Nzc2OTc0MjA3NDY1NzM3NDdjZmFmNDAyMDAwMDAwMDAxN2E5MTQ4MTUzZTdhMzU1MDgwODhiNmNmNTk5MjI2NzkyYzdkZTJkYmZmMjUyODc2MDNmMDEwMDAwMDAwMDAwMTdhOTE0ZDlmN2JlNDc5NzVjMDM2Zjk0MjI4YjBiZmQ3MDcwMTkxMjc1OGJhOTg3MDAwNTAwNDgzMDQ1MDIyMTAwOGI5NWFjODNlNDRjNzI3Yjc5ZmZiZjQ1NzExNzE5MjVkMDZmODgzYTA1YzEyMmIzYjMzYzA1NWYwYmZmYTcwMTAyMjA3YjVlZTM0MTJlYThhNWNlYzRhNWMzODZmMWI0NjRhYjY4ZDUzMWM2YzY5NzA3N2JjNDYyYzA1ZWI0NGEyODMyMDE0NzMwNDQwMjIwNTM2OTAyMzQ1ODJhNjkxMWEyOGNhZTlmNTM0Yzk4MGI3ZDc5MTg3NDlhNzQxM2MxYzU5MzI3ZGViZjE2ZmYwYjAyMjA1NjE3NWY1YzI3YTM2MzQxNmIyY2U0NzkxYWVmYzNkNTU1NDVjYWNiZDA1MjcyMDJlODY5ZTExMjdmYzJmMjRkMDEwMDY5NTIyMTAzMDc4MDE4NmMwYmU1ZGYwZDJkNjJjZjU0Y2MyZjNkMmMwOTkxMWUzNzdhYTk1YjVmZTg3NWZhMzUyYWVkMGE1OTIxMDNmMzIzN2VkZDJkODcwMTBlOGZlOWY0M2YzNGU4YzYzZGU2Mzg0MjgzZGU5MDk3OTVkNjJhZjRkZGI0ZDU3OTU0MjEwMmFkMDNkZTU1MDRlZjk0N2U0ZTZlZTJmYTZiMTVkMTUwZDU1M2MyMTI3NWY0OWYyY2UyMzU5ZDlmZGVkYjlhZGU1M2FlMDAwMDAwMDAnXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2VuZCBNYW55JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdyZXNwb25kcyB3aXRoIHByb3BlciBmZWUgYW5kIGZlZSByYXRlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzJNdXRwWFZZczhMeWs3NHBWRG4zZUFHN3huSzRXYzJralRRJyxcbiAgICAgICAgICAgIGFtb3VudDogMzAwMDAwLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgY29uc3QgdW5zcGVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICB2YWx1ZTogODE3MCxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHZhbHVlOiA4MDAwMDAsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgY29uc3QgY3JlYXRlQW5kU2lnblJlc3BvbnNlID0ge1xuICAgICAgICBiaXRnb0ZlZTogMCxcbiAgICAgICAgdHJhdmVsSW5mb3M6IFtdLFxuICAgICAgICB1bnNwZW50cyxcbiAgICAgICAgdHg6ICdoYWxmc2lnbmVkaGV4JyxcbiAgICAgIH07XG4gICAgICBzaW5vbi5zdHViKGZha2VXYWxsZXQsICdjcmVhdGVBbmRTaWduVHJhbnNhY3Rpb24nKS5yZXR1cm5zKFByb21pc2UucmVzb2x2ZShjcmVhdGVBbmRTaWduUmVzcG9uc2UpKTtcbiAgICAgIGNvbnN0IGdldFNlbmRUeFJlc3BvbnNlID0gKCkgPT4gKHtcbiAgICAgICAgc3RhdHVzOiAnYWNjZXB0ZWQnLFxuICAgICAgICB0eDogJzAxMDAwMDAwMDAwMTAyMjhiNWMzZTI3ODlkNDc3MGZjMzk3ZWM3OWZhNzI1NWY4NjIzNTI5N2M1YTA0ZGVmNjc4YjQ4MWI4YjA5ZTgxYjAxMDAwMDAwMjMyMjAwMjBiM2JiZTA2Nzk2MGJlMzk1MDFmMzY1Yjg5OTlkNTNmMmE4Mjg1ZDhkOTgzNmY2MWZhZDAyMGU2YTRhOWUyNmZkZmZmZmZmZmYxNTEwZTkwNDExYTg2YzQ5ZjJhNTI1NDZhMzJhMDNmZWJkZTJiYzYwNDc0MWYwZTg1ZGM0N2FkZWMzM2Y1MTU5MDAwMDAwMDBmZGZkMDAwMDQ4MzA0NTAyMjEwMGE0NGJiZjk3YjE1NWM1NzcwMzg2MmJlNjlkMmIyMGM0YjJhYjllOTRmNDAyNTk1ODgwYmY3NDQwMmNjYzg3ZTIwMjIwMGE0YWFmOThmOTM5YjY1Yzk4Y2EwOGViOTYwNzRjMjIyZWNiMWZjMzdlMzU5YjFkNjdhMDVmMWM1NmRlZGZjMDAxNDczMDQ0MDIyMDAzZjM5ODlhMTQyODRmMTMyYmJiNTUwMTE4YzIwMjU2ZDRlYTczNzcwNDEyM2EyOTk1NWFjYzFkMDNlYTZlYjcwMjIwMTcyMjNkYTdlZGNmNzMwNzZkODk4NzVhYTMzMzYwYWE2YTEyMTQxODA3ZjY4M2M2YzFiOWE1YTBkM2ZmNjAxOTAxNGM2OTUyMjEwMjU3ODk4NTdjYzhiZTExMGZmNGNiZjM1NGI1MmRkMGU3ZTkzMjZjNmJmZTBhZWU2YzMwYzFlZTY5NjYwYzNkYzAyMTAyZjU4ZjFiMTUxNmQwNTgxNGFlNjg4Y2E3MDE4NTY2OTVlMjcwNTBlM2UxNmQzYTIzNTEyODRkN2FmODQ0OTg4ODIxMDIzODVjN2JjZWMzZjM4YzEzZTg3YjU1OGFlYmYyZjIwYTg5MjhlN2VjYmUxMWU3YzNhNDc3OTJiYzhlMzNmZTg4NTNhZWZmZmZmZmZmMDJlMDkzMDQwMDAwMDAwMDAwMTdhOTE0MWQwYzc5MWNlYzNhZjFmMzc4MDhkNDJmMDQ1OTMwOTVkNmZkZWEyNjg3MDViYzA3MDAwMDAwMDAwMDE3YTkxNGQ4YzcyMGY2NDZjN2M1NmM1NDY3MjQ4ZTQ3YzcyZGMwYjJkMzBiYmM4NzA0MDA0NzMwNDQwMjIwMWVhYTEzNTlmZmZkM2JkZWM1YjQ4MjY4YmQyZjE1MTkzYTI5OWMyMmIxOTcwMzU2ZjM5MDg4MzQ3MzMyNDY1MTAyMjA3NDE4NjIzMmYwMjI0NWFmOWMwOTc3MDMxNDQ4YzJjOTllN2I3ZTJiMDViMmJhNGIzMmMzMjI3ZDhjYTE0OTRlMDE0ODMwNDUwMjIxMDBiZDYxYjM3MDUxYzI4NTMzZWEwYjAwZGRhNzViMWM0ZjFkZWUxYjY4M2JiNzM1MWIyZDhkZDcyMGY2ZGZiZTExMDIyMDNhY2M0Y2Y5ZDJkZDQ0YjI5NGFhMjU4MTJlOTllN2Q4ZWIzNzMwZTRmZjZmODg5ZDNjZGNkNTI1MTk1NzUwYjgwMTY5NTIyMTAyMTlkMDkzYzE4YzI3Y2I1NDc3MzdiNGE0OWRkZGFjOWMzNDEyYjEwZTlmODgwZWIzMDA1M2MzZWJhODE5Mjg1NDIxMDM3NDcxMTg4OTJjYWMxYjRkYTExNTI2ZmM0ZWJlZWJlMTY4ZGFlMDkwN2NlZmIxYTE4MTI1NDFjZDQ2YjA3NjAyMjEwMzM5ZjczYjY3NTBmOGY5MWVmZDQ4NGI1YWEyOTc0MzIxYTZjYzI3NzZkNWJkNzhiOWNmYjVmZTE4ZTNiMmQ2NjI1M2FlMDA1YTllMTYwMCcsXG4gICAgICAgIGhhc2g6ICdmOGRmNDNjMmM2NTBiM2JiMTEyNzdhZWU0NTMxZGI5OWE3MTVmYTNiOWRmZDNkNDVhOGQxNzEzNDJjMWJmNzgwJyxcbiAgICAgICAgaW5zdGFudDogZmFsc2UsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkUmVzdWx0ID0gT2JqZWN0LmFzc2lnbihcbiAgICAgICAge1xuICAgICAgICAgIGZlZTogMTI4NSxcbiAgICAgICAgICBmZWVSYXRlOiAyNTE5LjYwNzg0MzEzNzI1NSxcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0U2VuZFR4UmVzcG9uc2UoKVxuICAgICAgKTtcbiAgICAgIHNpbm9uLnN0dWIoZmFrZVdhbGxldCwgJ3NlbmRUcmFuc2FjdGlvbicpLnJlc29sdmVzKGdldFNlbmRUeFJlc3BvbnNlKCkpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gKGF3YWl0IGZha2VXYWxsZXQuc2VuZE1hbnkocGFyYW1zKSkgYXMgYW55O1xuICAgICAgcmVzdWx0LnR4LnNob3VsZC5lcXVhbChleHBlY3RlZFJlc3VsdC50eCk7XG4gICAgICByZXN1bHQuZmVlLnNob3VsZC5lcXVhbChleHBlY3RlZFJlc3VsdC5mZWUpO1xuICAgICAgcmVzdWx0LmZlZVJhdGUuc2hvdWxkLmVxdWFsKGV4cGVjdGVkUmVzdWx0LmZlZVJhdGUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWNjZWxlcmF0ZSBUcmFuc2FjdGlvbiAoc2VydmVyIG1vY2tlZCknLCBmdW5jdGlvbiBhY2NlbGVyYXRlVHhNb2NrZWREZXNjcmliZSgpIHtcbiAgICBsZXQgd2FsbGV0O1xuICAgIGxldCBiZ1VybDtcbiAgICBsZXQgZXhwbG9yZXJVcmw7XG4gICAgbGV0IG1pbkNoYW5nZVNpemU7XG5cbiAgICBsZXQgcGFyZW50VHhJZCA9ICc2YTc0Yjc0ZGY0OTkxZDkzYzMyZDc1MTMzNmM4NWI1ZjJkMWVlNTQ0YTJkZmJhZTJlNWY0YmViNGY5MTRlNWUwJztcbiAgICBjb25zdCBvdXRwdXRJZHggPSAwO1xuICAgIGNvbnN0IG91dHB1dEFkZHJlc3MgPSAnMk5Db1NmSEg2THM0Q2RUUzVRYWhnQzlrN3g5UmZYZVN3WTQnO1xuICAgIGNvbnN0IHVucmVsYXRlZFR4SWQgPSAnMDhmNWUwYjRhY2I1YWI4MjQ1MjI5ZGZlMTYxY2U0Y2EwZGExZWM5ODNlN2EzNGIwOWU3MmY1Njk3OWE0NjdkZic7XG4gICAgY29uc3Qgd2FsbGV0SWQgPSAnMk5Db1NmSEg2THM0Q2RUUzVRYWhnQzlrN3g5UmZYZVN3WTQnO1xuXG4gICAgLyoqXG4gICAgICogSGVscGVyIGZ1bmN0aW9uIHRvIGdldCB0aGUgcGFyZW50IHRyYW5zYWN0aW9uIElEIGZyb20gYSB0cmFuc2FjdGlvbiBpbnB1dFxuICAgICAqXG4gICAgICogVGhpcyBmdW5jdGlvbiBjb252ZXJ0cyBgaGFzaGAgKHdoaWNoIGlzIGEgQnVmZmVyIG9iamVjdCkgdG8gYSB1c2FibGUgdHhpZCBzdHJpbmcuXG4gICAgICogVGhlIGlzc3VlIGlzIHRoYXQgdGhlIGJ5dGVzIGFyZSBzdG9yZWQgaW4gcmV2ZXJzZSBvcmRlciBpbiB0aGUgYnVmZmVyLCBzb1xuICAgICAqIHRoZSBzaW1wbGUgYXBwcm9hY2ggb2YganVzdCBjb21wYXJpbmcgdGhlIGhleCBzdHJpbmdzIGRvZXNuJ3Qgd29yay5cbiAgICAgKiBJbnN0ZWFkLCB0aGUgQnVmZmVyIGlzIGNvcGllZCB0byBhIG5ldyBCdWZmZXIgb2JqZWN0LCB0aGUgbmV3IEJ1ZmZlclxuICAgICAqIG9iamVjdCBpcyByZXZlcnNlZCBpbi1wbGFjZSwgYW5kIHRoZW4gdGhlIG5ldyBCdWZmZXIgaXMgY29udmVydGVkIHRvIGFcbiAgICAgKiBoZXggc3RyaW5nLiBBZnRlciB0aGlzLCB0aGUgcmVzdWx0IGlzIGEgaGV4IHN0cmluZyB3aGljaCBpcyB0aGUgcGFyZW50IHR4aWRcbiAgICAgKlxuICAgICAqIEBwYXJhbSBoYXNoIGEgYml0Y29pbmpzLWxpYiB0cmFuc2FjdGlvbiBvYmplY3QncyBpbnB1dCBoYXNoXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW5wdXRQYXJlbnRUeElkKHsgaGFzaCB9KTogc3RyaW5nIHtcbiAgICAgIHJldHVybiAoQnVmZmVyLmZyb20oaGFzaCkucmV2ZXJzZSgpIGFzIEJ1ZmZlcikudG9TdHJpbmcoJ2hleCcpO1xuICAgIH1cblxuICAgIGJlZm9yZShmdW5jdGlvbiBhY2NlbGVyYXRlVHhNb2NrZWRCZWZvcmUoKSB7XG4gICAgICBub2NrLnBlbmRpbmdNb2NrcygpLnNob3VsZC5iZS5lbXB0eSgpO1xuXG4gICAgICBiaXRnbyA9IG5ldyBCaXRHb0FQSSh7IGVudjogJ21vY2snLCBjbGllbnRDb25zdGFudHM6IHsgY29uc3RhbnRzOiB7fSB9IH0pO1xuICAgICAgLy8gYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgICBiaXRnby5zZXRWYWxpZGF0ZShmYWxzZSk7XG4gICAgICB3YWxsZXQgPSBuZXcgV2FsbGV0KGJpdGdvLCB7IGlkOiB3YWxsZXRJZCwgcHJpdmF0ZTogeyBrZXljaGFpbnM6IFt1c2VyS2V5cGFpciwgYmFja3VwS2V5cGFpciwgYml0Z29LZXldIH0gfSk7XG4gICAgICAod2FsbGV0IGFzIGFueSkuYml0Z28gPSBiaXRnbztcbiAgICAgIGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuICAgICAgZXhwbG9yZXJVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzW2JpdGdvLmdldEVudigpXS5idGNFeHBsb3JlckJhc2VVcmw7XG5cbiAgICAgIC8vIHRyeSB0byBnZXQgdGhlIG1pbiBjaGFuZ2Ugc2l6ZSBmcm9tIHRoZSBzZXJ2ZXIsIG90aGVyd2lzZSBkZWZhdWx0IHRvIDAuMSBCVENcbiAgICAgIC8vIFRPRE86IG1pbkNoYW5nZVNpemUgaXMgbm90IGN1cnJlbnRseSBhIGNvbnN0YW50IGRlZmluZWQgb24gdGhlIGNsaWVudCBhbmQgc2hvdWxkIGJlIGFkZGVkXG4gICAgICBtaW5DaGFuZ2VTaXplID0gMWU3O1xuICAgIH0pO1xuXG4gICAgYWZ0ZXIoZnVuY3Rpb24gYWNjZWxlcmF0ZVR4TW9ja2VkQWZ0ZXIoKSB7XG4gICAgICAvLyBtYWtlIHN1cmUgYWxsIG5vY2tzIGFyZSBjbGVhcmVkIG9yIGNvbnN1bWVkIGFmdGVyIHRoZSB0ZXN0cyBhcmUgY29tcGxldGVcbiAgICAgIG5vY2sucGVuZGluZ01vY2tzKCkuc2hvdWxkLmJlLmVtcHR5KCk7XG4gICAgfSk7XG5cbiAgICBpdCgnYXJndW1lbnRzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgd2FsbGV0LmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IGZlZVJhdGU6IDEyMyB9KS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9eTWlzc2luZyBwYXJhbWV0ZXI6IHRyYW5zYWN0aW9uSUQkLyk7XG5cbiAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgdHJhbnNhY3Rpb25JRDogMTIzLCBmZWVSYXRlOiAxMjMgfSlcbiAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL15FeHBlY3RpbmcgcGFyYW1ldGVyIHN0cmluZzogdHJhbnNhY3Rpb25JRCBidXQgZm91bmQgbnVtYmVyJC8pO1xuXG4gICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHRyYW5zYWN0aW9uSUQ6ICcxMjMnIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9eTWlzc2luZyBwYXJhbWV0ZXI6IGZlZVJhdGUkLyk7XG5cbiAgICAgIGNvbnN0IGZlZVJhdGVzUGFyYW1zID0gWycxMjMnLCAwLCAtMTAsIC1JbmZpbml0eSwgSW5maW5pdHksIE5hTl07XG4gICAgICBmb3IgKGNvbnN0IGZlZVJhdGUgb2YgZmVlUmF0ZXNQYXJhbXMpIHtcbiAgICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHRyYW5zYWN0aW9uSUQ6ICcxMjMnLCBmZWVSYXRlIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL15FeHBlY3RpbmcgcG9zaXRpdmUgZmluaXRlIG51bWJlciBmb3IgcGFyYW1ldGVyOiBmZWVSYXRlJC8pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2JhZCBpbnB1dCcsIGZ1bmN0aW9uIGJhZElucHV0RGVzY3JpYmUoKSB7XG4gICAgICBhZnRlcigoKSA9PiB7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSBhbGwgbm9ja3MgYXJlIGNsZWFyZWQgb3IgY29uc3VtZWQgYWZ0ZXIgdGhlIHRlc3RzIGFyZSBjb21wbGV0ZVxuICAgICAgICBub2NrLnBlbmRpbmdNb2NrcygpLnNob3VsZC5iZS5lbXB0eSgpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdub24gZXhpc3RlbnQgdHJhbnNhY3Rpb24gSUQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDQwNCwgJ3RyYW5zYWN0aW9uIG5vdCBmb3VuZCBvbiB0aGlzIHdhbGxldCcpO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLCBmZWVSYXRlOiAxMjMgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvXjQwNFxcbnRyYW5zYWN0aW9uIG5vdCBmb3VuZCBvbiB0aGlzIHdhbGxldCQvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnY29uZmlybWVkIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICBjb25maXJtYXRpb25zOiA2LFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgdHJhbnNhY3Rpb25JRDogcGFyZW50VHhJZCwgZmVlUmF0ZTogMjAwMCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9eVHJhbnNhY3Rpb24gWzAtOWEtZl0rIGlzIGFscmVhZHkgY29uZmlybWVkIGFuZCBjYW5ub3QgYmUgYWNjZWxlcmF0ZWQkLyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ25vIG91dHB1dHMgdG8gd2FsbGV0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjY291bnQ6IG91dHB1dEFkZHJlc3MsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDE4OTAwMDAsXG4gICAgICAgICAgICAgICAgdm91dDogMCxcbiAgICAgICAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLCBmZWVSYXRlOiAyMDAwIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgICAvXlRyYW5zYWN0aW9uIFswLTlhLWZdKyBjb250YWlucyBubyBvdXRwdXRzIHRvIHRoaXMgd2FsbGV0LCBhbmQgdGh1cyBjYW5ub3QgYmUgYWNjZWxlcmF0ZWQkL1xuICAgICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgLypcbiAgICAgICAqIFRoaXMgdGVzdCBjb3ZlcnMgdGhlIGNhc2Ugd2hlcmUgYSBmYWlsdXJlIG9jY3VycyBkdXJpbmcgdGhlIHByb2Nlc3Mgb2ZcbiAgICAgICAqIGNvbnZlcnRpbmcgYW4gb3V0cHV0IGZyb20gdGhlIHBhcmVudCB0cmFuc2FjdGlvbiBpbnRvIGFuIHVuc3BlbnQgd2hpY2hcbiAgICAgICAqIGNhbiBiZSB1c2VkIHRvIGNoYWluIHRoZSBjaGlsZCB0eCB0byB0aGUgcGFyZW50LlxuICAgICAgICpcbiAgICAgICAqIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiwgYnV0IGl0IGlzIHBvc3NpYmxlIChmb3IgZXhhbXBsZSwgaW4gdGhlIGNhc2VcbiAgICAgICAqIG9mIGFuIGF0dGVtcHRlZCBkb3VibGUgc3BlbmQgb2YgdGhlIG91dHB1dCBmcm9tIHRoZSBwYXJlbnQsIG9yIGEgcmFjZVxuICAgICAgICogYmV0d2VlbiBmaW5kaW5nIHRoZSBwYXJlbnQgb3V0cHV0LCBhbmQgcmV0cmlldmluZyB0aGUgY29ycmVzcG9uZGluZyB1bnNwZW50KS5cbiAgICAgICAqL1xuICAgICAgaXQoJ2Nhbm5vdCBmaW5kIGNvcnJlY3QgdW5zcGVudCB0byB1c2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWNjb3VudDogb3V0cHV0QWRkcmVzcyxcbiAgICAgICAgICAgICAgICB2YWx1ZTogNTAgKiAxZTQsXG4gICAgICAgICAgICAgICAgdm91dDogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgICAgaGV4OiBwYXJlbnRUeElkLFxuICAgICAgICAgICAgZmVlOiAxMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYCkucXVlcnkodHJ1ZSkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgY291bnQ6IDAsXG4gICAgICAgICAgdW5zcGVudHM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCB3YWxsZXRcbiAgICAgICAgICAuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHsgdHJhbnNhY3Rpb25JRDogcGFyZW50VHhJZCwgZmVlUmF0ZTogMjAwMCB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKC9eQ291bGQgbm90IGZpbmQgdW5zcGVudCBvdXRwdXQgZnJvbSBwYXJlbnQgdHggdG8gdXNlIGFzIGNoaWxkIGlucHV0JC8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdEZXRlY3RzIHdoZW4gYW4gaW5jb3JyZWN0IHR4IGhleCBpcyByZXR1cm5lZCBieSB0aGUgZXh0ZXJuYWwgc2VydmljZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC8ke3BhcmVudFR4SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBhY2NvdW50OiBvdXRwdXRBZGRyZXNzLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMCxcbiAgICAgICAgICAgICAgICB2b3V0OiBvdXRwdXRJZHgsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNvbmZpcm1hdGlvbnM6IDAsXG4gICAgICAgICAgICBoZXg6IGZpeHR1cmVzW3BhcmVudFR4SWRdLFxuICAgICAgICAgICAgZmVlOiAxMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBjb3VudDogMSxcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBwYXJlbnRUeElkLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiBvdXRwdXRJZHgsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soZXhwbG9yZXJVcmwpLmdldChgL3R4LyR7cGFyZW50VHhJZH0vaGV4YCkucmVwbHkoMjAwLCBmaXh0dXJlc1t1bnJlbGF0ZWRUeElkXSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsIGZlZVJhdGU6IDIwMDAgfSlcbiAgICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgvXkRlY29kZWQgdHJhbnNhY3Rpb24gaWQgaXMgWzAtOWEtZl0rLCB3aGljaCBkb2VzIG5vdCBtYXRjaCBnaXZlbiB0eGlkIFswLTlhLWZdKyQvKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnY2Fubm90IGNvdmVyIGNoaWxkIGZlZSB3aXRoIG9uZSBwYXJlbnQgb3V0cHV0IGFuZCBvbmUgd2FsbGV0IHVuc3BlbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWNjb3VudDogb3V0cHV0QWRkcmVzcyxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAsXG4gICAgICAgICAgICAgICAgdm91dDogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgICAgaGV4OiBmaXh0dXJlc1twYXJlbnRUeElkXSxcbiAgICAgICAgICAgIGZlZTogMTAsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgY291bnQ6IDEsXG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGV4cGxvcmVyVXJsKS5nZXQoYC90eC8ke3BhcmVudFR4SWR9L2hleGApLnJlcGx5KDIwMCwgZml4dHVyZXNbcGFyZW50VHhJZF0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKS5xdWVyeSh0cnVlKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICBjb3VudDogMCxcbiAgICAgICAgICB1bnNwZW50czogW10sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLCBmZWVSYXRlOiAyMDAwIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoL15JbnN1ZmZpY2llbnQgY29uZmlybWVkIHVuc3BlbnRzIGF2YWlsYWJsZSB0byBjb3ZlciB0aGUgY2hpbGQgZmVlJC8pO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdjYW5ub3QgbG93ZXIgZmVlIHJhdGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgYWNjb3VudDogb3V0cHV0QWRkcmVzcyxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAsXG4gICAgICAgICAgICAgICAgdm91dDogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMTEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgICAgIGhleDogZml4dHVyZXNbcGFyZW50VHhJZF0sXG4gICAgICAgICAgICBmZWU6IDEwMDAwLCAvLyBsYXJnZSBmZWUsIGFuZCB0aHVzIGZlZSByYXRlLCBmb3IgcGFyZW50XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgY291bnQ6IDEsXG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogb3V0cHV0SWR4LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGV4cGxvcmVyVXJsKS5nZXQoYC90eC8ke3BhcmVudFR4SWR9L2hleGApLnJlcGx5KDIwMCwgZml4dHVyZXNbcGFyZW50VHhJZF0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldFxuICAgICAgICAgIC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLCBmZWVSYXRlOiAyMDAwIH0pXG4gICAgICAgICAgLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgICAvXkNhbm5vdCBsb3dlciBmZWUgcmF0ZSEgXFwoUGFyZW50IHR4IGZlZSByYXRlIGlzIFxcZCtcXC4/XFxkKiBzYXRcXC9rQiwgYW5kIHJlcXVlc3RlZCBmZWUgcmF0ZSB3YXMgXFxkK1xcLj9cXGQqIHNhdFxcL2tCXFwpJC9cbiAgICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdjYW5ub3QgYnJlYWsgbWF4aW11bSBmZWUgbGltaXQgZm9yIGNvbWJpbmVkIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGFjY291bnQ6IG91dHB1dEFkZHJlc3MsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDNlNyxcbiAgICAgICAgICAgICAgICB2b3V0OiBvdXRwdXRJZHgsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAxMSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgICAgaGV4OiBmaXh0dXJlc1twYXJlbnRUeElkXSxcbiAgICAgICAgICAgIGZlZTogMTAwMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBjb3VudDogMSxcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBwYXJlbnRUeElkLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiBvdXRwdXRJZHgsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soZXhwbG9yZXJVcmwpLmdldChgL3R4LyR7cGFyZW50VHhJZH0vaGV4YCkucmVwbHkoMjAwLCBmaXh0dXJlc1twYXJlbnRUeElkXSk7XG5cbiAgICAgICAgYXdhaXQgd2FsbGV0XG4gICAgICAgICAgLmFjY2VsZXJhdGVUcmFuc2FjdGlvbih7IHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsIGZlZVJhdGU6IDJlNiB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICAgL15UcmFuc2FjdGlvbiBjYW5ub3QgYmUgYWNjZWxlcmF0ZWRcXC4gQ29tYmluZWQgZmVlIHJhdGUgb2YgXFxkK1xcLj9cXGQqIHNhdFxcL2tCIGV4Y2VlZHMgbWF4aW11bSBmZWUgcmF0ZSBvZiBcXGQrXFwuP1xcZCogc2F0XFwva0IkL1xuICAgICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzdWNjZXNzZnVsIHR4IGFjY2VsZXJhdGlvbicsIGZ1bmN0aW9uIHN1Y2Nlc3NmdWxUeERlc2NyaWJlKCkge1xuICAgICAgY29uc3QgZmVlUmF0ZSA9IDIwMDAwO1xuXG4gICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgbm9jayhiZ1VybCkucG9zdChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vYWRkcmVzcy8xYCkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgYWRkcmVzczogJzJOQ1lqRzhRNTZ5cjh0eDlqYXpOb1luR0t4amdCMk1RU2ZZJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybCkucG9zdCgnL2FwaS92MS9iaWxsaW5nL2FkZHJlc3MnKS5yZXBseSgyMDAsIHtcbiAgICAgICAgICBhZGRyZXNzOiAnMk5GYnZvMkhLNGVYWm0xYXFEY1NER0dxRDY0RlB0N1Q2ZDgnLFxuICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoJy9hcGkvdjEvdHgvZmVlJykucXVlcnkodHJ1ZSkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgZmVlUGVyS2I6IDAsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoYC9hcGkvdjEva2V5Y2hhaW4vJHt1c2VyS2V5cGFpci54cHVifWAsIHt9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFhwcnY6IGJpdGdvLmVuY3J5cHQoeyBpbnB1dDogdXNlcktleXBhaXIueHBydiwgcGFzc3dvcmQ6IFRlc3RCaXRHby5URVNUX1dBTExFVDFfUEFTU0NPREUgfSksXG4gICAgICAgICAgICBwYXRoOiB1c2VyS2V5cGFpci5wYXRoICsgdXNlcktleXBhaXIud2FsbGV0U3ViUGF0aCxcbiAgICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnYWNjZWxlcmF0ZXMgYSBzdHVjayB0eCB3aXRob3V0IGFkZGl0aW9uYWwgdW5zcGVudHMnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHBhcmVudFR4SWQgPSAnNzVjZmM1YTdiMjE0YzRiNzNjOTJjN2IwMjYwOGNkZTcwYjIyNjc2N2E5NTc2Zjg0YzA0NDA3ZTQzZmQzODViZCc7XG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdHgvJHtwYXJlbnRUeElkfWApXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgZmVlOiA0MzQsXG4gICAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDM0ODUwMCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAxLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDExLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAzNDg1MDAsXG4gICAgICAgICAgICAgICAgcmVkZWVtU2NyaXB0OiAnMDAyMGY3YjU4ZDQ1NTM1MWI3YjhkZGQ3Yzg5ODZkOTgyNDRmNmE5NWYwNzQ2NzIwMDkxNTM3MzIzYjk2NzgwMGY3NDQnLFxuICAgICAgICAgICAgICAgIGNoYWluUGF0aDogJy8xMS8xNjAnLFxuICAgICAgICAgICAgICAgIHdpdG5lc3NTY3JpcHQ6XG4gICAgICAgICAgICAgICAgICAnNTIyMTAyN2YwYjQ1YmI0MTU1ZWE1MzJlM2I0MzEyZmUwYmU4MDE2NmYyOTdkMWUwNzUzZDJkNGE5MTE4YzA3M2FkNjUxNDIxMDMxMGFhOWQ2OGM5ODgzMTYyNWYzMjliNzgyNmI2YzNlM2I1M2UxNjczNmIxOTk0Yjg5MDI0NDJiZGNkNjY1M2QxMjEwMjZlMGNhNDE0ZjI0ODhiMGFiNTcyYjk5ZTBhZTU0NDI5MTFhYjRlMDgyMWIyNzA5ZDg4NTE3NWE1MjdmZDU1MmI1M2FlJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhleHBsb3JlclVybCkuZ2V0KGAvdHgvJHtwYXJlbnRUeElkfS9oZXhgKS5yZXBseSgyMDAsIGZpeHR1cmVzW3BhcmVudFR4SWRdKTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YxL3R4L3NlbmQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICFib2R5Lmlnbm9yZU1heEZlZVJhdGU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBmdW5jdGlvbiAoXywgYm9keSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgdHJhbnNhY3Rpb246IChib2R5IGFzIGFueSkudHgsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkVHggPSBhd2FpdCB3YWxsZXQuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLFxuICAgICAgICAgIGZlZVJhdGUsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfV0FMTEVUMV9QQVNTQ09ERSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGNoaWxkVHgpO1xuICAgICAgICBjaGlsZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzdGF0dXMnLCAnYWNjZXB0ZWQnKTtcbiAgICAgICAgY2hpbGRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgICAvLyBhc3NlcnQgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgLy8gMCkgVGhlIGNoaWxkIHR4IGhhcyBleGFjdGx5IG9uZSBpbnB1dFxuICAgICAgICAvLyAxKSBUaGUgcGFyZW50IHR4IG91dHB1dCBpcyBhbiBpbnB1dFxuICAgICAgICAvLyAyKSBUaGUgY2hpbGQgdHggaGFzIGV4YWN0bHkgb25lIG91dHB1dFxuICAgICAgICAvLyAzKSBUaGUgY2hpbGQgdHggb3V0cHV0IG1lZXRzIHRoZSBtaW5pbXVtIGNoYW5nZSB0aHJlc2hvbGRcbiAgICAgICAgY29uc3QgZGVjb2RlZENoaWxkID0gdXR4b2xpYi5iaXRnby5jcmVhdGVUcmFuc2FjdGlvbkZyb21IZXgoY2hpbGRUeC50eCwgdXR4b2xpYi5uZXR3b3Jrcy5iaXRjb2luKTtcbiAgICAgICAgZGVjb2RlZENoaWxkLmlucy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICBkZWNvZGVkQ2hpbGQub3V0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkSW5wdXQgPSBkZWNvZGVkQ2hpbGQuaW5zWzBdO1xuICAgICAgICBjaGlsZElucHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpbmRleCcsIDApO1xuICAgICAgICBjaGlsZElucHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdoYXNoJyk7XG5cbiAgICAgICAgY29uc3QgaW5wdXRUeElkID0gaW5wdXRQYXJlbnRUeElkKGNoaWxkSW5wdXQpO1xuICAgICAgICBpbnB1dFR4SWQuc2hvdWxkLmVxdWFsKHBhcmVudFR4SWQpO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkT3V0cHV0ID0gZGVjb2RlZENoaWxkLm91dHNbMF07XG4gICAgICAgIGNoaWxkT3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd2YWx1ZScpO1xuICAgICAgICBjaGlsZE91dHB1dC52YWx1ZS5zaG91bGQuYmUuYWJvdmUobWluQ2hhbmdlU2l6ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2FjY2VsZXJhdGVzIGEgc3R1Y2sgdHggd2l0aCBvbmUgYWRkaXRpb25hbCBzZWd3aXQgdW5zcGVudCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcGFyZW50VHhJZCA9ICc4ODE1ZjIwMmM4NjU0YjZjOGIyOTU3NDk1NDVjNzExODc4Y2Q4NDVhMTRjYjFlYTk4MjM5NGQwYzE0OTQ1YzMzJztcbiAgICAgICAgY29uc3QgYWRkaXRpb25hbFVuc3BlbnRUeElkID0gJzA3ZDZlZTU3YjAyNGNlMmI2MTA4ZjY3ODQ3NDU0YTBhNzlhNGZjZmI5OGFiMjU1NTUzYTI5OTNhMWExNzBiODcnO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGZlZTogMTMzNixcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZvdXQ6IDAsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwMDAwLFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMTEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAxLFxuICAgICAgICAgICAgICAgIHZhbHVlOiA4NjY0LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBwYXJlbnRUeElkLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgICByZWRlZW1TY3JpcHQ6XG4gICAgICAgICAgICAgICAgICAnNTIyMTAyY2QzYzhlNjAwNmE0NjI3NzA1MDIxZDFkMDE2ZDA5N2MyOTQ0ZDk4MTAwYTQ3YmYyZGE2N2E1ZmUxNWFlZWIzNDIxMDJlZTFmYTllODEyZTc3OTM1NmFhM2MzMWViZjMxN2QwY2ZmZWJhYjkyODY0Y2ZlMzhiYWIyMjNlMDgyMGY5OGJjMjEwMjZiYTA1NzUyYmFhNmVhZmQ1YzU2NTlkYTYyYjdmMGFjNTFmZDI4ODZiNjVjMjQxZDBhZmVmMWM0ZmRmYTFjYmM1M2FlJyxcbiAgICAgICAgICAgICAgICBjaGFpblBhdGg6ICcvMC8wJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdW5zcGVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR4X2hhc2g6IGFkZGl0aW9uYWxVbnNwZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTk5MzU1MjYsXG4gICAgICAgICAgICAgICAgcmVkZWVtU2NyaXB0OiAnMDAyMGQzNGVmNmRkMzRlZjJhNGZiZWE2N2M1NDFjMWM3OTY3NDlhNjBhZmU0YTk3ZmVlOGVjN2RlZDE4OGJkNzQ5ZGEnLFxuICAgICAgICAgICAgICAgIGNoYWluUGF0aDogJy8xMS8xNTUnLFxuICAgICAgICAgICAgICAgIHdpdG5lc3NTY3JpcHQ6XG4gICAgICAgICAgICAgICAgICAnNTIyMTAyMjE5ZDJhYTg0MTc2MzNmMGJjZTM5MTEzNzRhMTYwNGMxYjY0MTYxZjgzYTNjMmVlNDA5YzI3YzQyMzU1ZjA4ZTIxMDJjOTczNDkyMGRjNGRhMDZjMjg5ZmU2OTE3MWRmY2Q3NWUzYjliNGYxOTBkMGNiYzNkNWQwZmYzZjVmZGVlYWFlMjEwM2NjZDY4ZDdmYThkYzBkMDJkZDQ1ZGFkMTY1NTU3YTQ4NTgyZWRhNDQzNWZhZTczNzdiM2MzMWUwOGFkMDY1Yzk1M2FlJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhleHBsb3JlclVybCkuZ2V0KGAvdHgvJHtwYXJlbnRUeElkfS9oZXhgKS5yZXBseSgyMDAsIGZpeHR1cmVzW3BhcmVudFR4SWRdKTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5wb3N0KCcvYXBpL3YxL3R4L3NlbmQnLCAoYm9keSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICFib2R5Lmlnbm9yZU1heEZlZVJhdGU7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAucmVwbHkoMjAwLCBmdW5jdGlvbiAoXywgYm9keSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgdHJhbnNhY3Rpb246IChib2R5IGFzIGFueSkudHgsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkVHggPSBhd2FpdCB3YWxsZXQuYWNjZWxlcmF0ZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0cmFuc2FjdGlvbklEOiBwYXJlbnRUeElkLFxuICAgICAgICAgIGZlZVJhdGUsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfV0FMTEVUMV9QQVNTQ09ERSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGNoaWxkVHgpO1xuICAgICAgICBjaGlsZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCdzdGF0dXMnLCAnYWNjZXB0ZWQnKTtcbiAgICAgICAgY2hpbGRUeC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHgnKTtcblxuICAgICAgICAvLyBhc3NlcnQgdGhlIGZvbGxvd2luZzpcbiAgICAgICAgLy8gMCkgVGhlIGNoaWxkIHR4IGhhcyBleGFjdGx5IHR3byBpbnB1dHNcbiAgICAgICAgLy8gMSkgVGhlIHBhcmVudCB0eCBvdXRwdXQgaXMgYW4gaW5wdXRcbiAgICAgICAgLy8gMikgVGhlIGFkZGl0aW9uYWwgdW5zcGVudCBvdXRwdXQgaXMgYW4gaW5wdXRcbiAgICAgICAgLy8gMykgVGhlIGNoaWxkIHR4IGhhcyBleGFjdGx5IG9uZSBvdXRwdXRcbiAgICAgICAgLy8gNCkgVGhlIGNoaWxkIHR4IG91dHB1dCBtZWV0cyB0aGUgbWluaW11bSBjaGFuZ2UgdGhyZXNob2xkXG4gICAgICAgIGNvbnN0IGRlY29kZWRDaGlsZCA9IHV0eG9saWIuYml0Z28uY3JlYXRlVHJhbnNhY3Rpb25Gcm9tSGV4KGNoaWxkVHgudHgsIHV0eG9saWIubmV0d29ya3MuYml0Y29pbik7XG4gICAgICAgIGRlY29kZWRDaGlsZC5pbnMubGVuZ3RoLnNob3VsZC5lcXVhbCgyKTtcbiAgICAgICAgZGVjb2RlZENoaWxkLm91dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgICBsZXQgaW5wdXRGcm9tUGFyZW50OiBhbnkgPSB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBhZGRpdGlvbmFsSW5wdXQ6IGFueSA9IHVuZGVmaW5lZDtcblxuICAgICAgICBfLmZvckVhY2goZGVjb2RlZENoaWxkLmlucywgKGlucHV0KSA9PiB7XG4gICAgICAgICAgaW5wdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2hhc2gnKTtcbiAgICAgICAgICBpbnB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaW5kZXgnKTtcblxuICAgICAgICAgIGNvbnN0IGlucHV0VHhJZCA9IGlucHV0UGFyZW50VHhJZChpbnB1dCk7XG5cbiAgICAgICAgICBpZiAoaW5wdXRUeElkID09PSBwYXJlbnRUeElkKSB7XG4gICAgICAgICAgICBpbnB1dEZyb21QYXJlbnQgPSBpbnB1dDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWRkaXRpb25hbElucHV0ID0gaW5wdXQ7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXhpc3QoaW5wdXRGcm9tUGFyZW50KTtcbiAgICAgICAgY29uc3QgaW5wdXRGcm9tUGFyZW50SGFzaCA9IGlucHV0UGFyZW50VHhJZChpbnB1dEZyb21QYXJlbnQpO1xuICAgICAgICBpbnB1dEZyb21QYXJlbnRIYXNoLnNob3VsZC5lcXVhbChwYXJlbnRUeElkKTtcbiAgICAgICAgaW5wdXRGcm9tUGFyZW50LmluZGV4LnNob3VsZC5lcXVhbCgwKTtcblxuICAgICAgICBzaG91bGQuZXhpc3QoYWRkaXRpb25hbElucHV0KTtcbiAgICAgICAgY29uc3QgYWRkaXRpb25hbElucHV0SGFzaCA9IGlucHV0UGFyZW50VHhJZChhZGRpdGlvbmFsSW5wdXQpO1xuICAgICAgICBhZGRpdGlvbmFsSW5wdXRIYXNoLnNob3VsZC5lcXVhbChhZGRpdGlvbmFsVW5zcGVudFR4SWQpO1xuICAgICAgICBhZGRpdGlvbmFsSW5wdXQuaW5kZXguc2hvdWxkLmVxdWFsKDApO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkT3V0cHV0ID0gZGVjb2RlZENoaWxkLm91dHNbMF07XG4gICAgICAgIGNoaWxkT3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd2YWx1ZScpO1xuICAgICAgICBjaGlsZE91dHB1dC52YWx1ZS5zaG91bGQuYmUuYWJvdmUobWluQ2hhbmdlU2l6ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2FjY2VsZXJhdGVzIGEgc3R1Y2sgdHggd2l0aCBvbmUgYWRkaXRpb25hbCBQMlNIIHVuc3BlbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHBhcmVudFR4SWQgPSAnODgxNWYyMDJjODY1NGI2YzhiMjk1NzQ5NTQ1YzcxMTg3OGNkODQ1YTE0Y2IxZWE5ODIzOTRkMGMxNDk0NWMzMyc7XG4gICAgICAgIGNvbnN0IGFkZGl0aW9uYWxVbnNwZW50VHhJZCA9ICdlMTkwMzEwZjJmM2Y3MWFhODg0NmYxMTYxY2JjZTE1MzNjMjRhODU3ZGQyNGU0NTAxYjEzMWZlYjQwMGFhZDU4JztcbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS90eC8ke3BhcmVudFR4SWR9YClcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICBmZWU6IDEzMzYsXG4gICAgICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDExLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdm91dDogMSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogODY2NCxcbiAgICAgICAgICAgICAgICBpc01pbmU6IHRydWUsXG4gICAgICAgICAgICAgICAgY2hhaW46IDEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY29uZmlybWF0aW9uczogMCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3Vuc3BlbnRzYClcbiAgICAgICAgICAucXVlcnkodHJ1ZSlcbiAgICAgICAgICAucmVwbHkoMjAwLCB7XG4gICAgICAgICAgICB1bnNwZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogcGFyZW50VHhJZCxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgICAgcmVkZWVtU2NyaXB0OlxuICAgICAgICAgICAgICAgICAgJzUyMjEwMmNkM2M4ZTYwMDZhNDYyNzcwNTAyMWQxZDAxNmQwOTdjMjk0NGQ5ODEwMGE0N2JmMmRhNjdhNWZlMTVhZWViMzQyMTAyZWUxZmE5ZTgxMmU3NzkzNTZhYTNjMzFlYmYzMTdkMGNmZmViYWI5Mjg2NGNmZTM4YmFiMjIzZTA4MjBmOThiYzIxMDI2YmEwNTc1MmJhYTZlYWZkNWM1NjU5ZGE2MmI3ZjBhYzUxZmQyODg2YjY1YzI0MWQwYWZlZjFjNGZkZmExY2JjNTNhZScsXG4gICAgICAgICAgICAgICAgY2hhaW5QYXRoOiAnLzAvMCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBhZGRpdGlvbmFsVW5zcGVudFR4SWQsXG4gICAgICAgICAgICAgICAgdHhfb3V0cHV0X246IDEsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDIwMDAwMDAwLFxuICAgICAgICAgICAgICAgIHJlZGVlbVNjcmlwdDpcbiAgICAgICAgICAgICAgICAgICc1MjIxMDJjZDNjOGU2MDA2YTQ2Mjc3MDUwMjFkMWQwMTZkMDk3YzI5NDRkOTgxMDBhNDdiZjJkYTY3YTVmZTE1YWVlYjM0MjEwMmVlMWZhOWU4MTJlNzc5MzU2YWEzYzMxZWJmMzE3ZDBjZmZlYmFiOTI4NjRjZmUzOGJhYjIyM2UwODIwZjk4YmMyMTAyNmJhMDU3NTJiYWE2ZWFmZDVjNTY1OWRhNjJiN2YwYWM1MWZkMjg4NmI2NWMyNDFkMGFmZWYxYzRmZGZhMWNiYzUzYWUnLFxuICAgICAgICAgICAgICAgIGNoYWluUGF0aDogJy8wLzAnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGV4cGxvcmVyVXJsKS5nZXQoYC90eC8ke3BhcmVudFR4SWR9L2hleGApLnJlcGx5KDIwMCwgZml4dHVyZXNbcGFyZW50VHhJZF0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjEvdHgvc2VuZCcsIChib2R5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gIWJvZHkuaWdub3JlTWF4RmVlUmF0ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIGZ1bmN0aW9uIChfLCBib2R5KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICB0cmFuc2FjdGlvbjogKGJvZHkgYXMgYW55KS50eCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY2hpbGRUeCA9IGF3YWl0IHdhbGxldC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsXG4gICAgICAgICAgZmVlUmF0ZSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQxX1BBU1NDT0RFLFxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXhpc3QoY2hpbGRUeCk7XG4gICAgICAgIGNoaWxkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3N0YXR1cycsICdhY2NlcHRlZCcpO1xuICAgICAgICBjaGlsZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuXG4gICAgICAgIC8vIGFzc2VydCB0aGUgZm9sbG93aW5nOlxuICAgICAgICAvLyAwKSBUaGUgY2hpbGQgdHggaGFzIGV4YWN0bHkgdHdvIGlucHV0c1xuICAgICAgICAvLyAxKSBUaGUgcGFyZW50IHR4IG91dHB1dCBpcyBhbiBpbnB1dFxuICAgICAgICAvLyAyKSBUaGUgYWRkaXRpb25hbCB1bnNwZW50IG91dHB1dCBpcyBhbiBpbnB1dFxuICAgICAgICAvLyAzKSBUaGUgY2hpbGQgdHggaGFzIGV4YWN0bHkgb25lIG91dHB1dFxuICAgICAgICAvLyA0KSBUaGUgY2hpbGQgdHggb3V0cHV0IG1lZXRzIHRoZSBtaW5pbXVtIGNoYW5nZSB0aHJlc2hvbGRcbiAgICAgICAgY29uc3QgZGVjb2RlZENoaWxkID0gdXR4b2xpYi5iaXRnby5jcmVhdGVUcmFuc2FjdGlvbkZyb21IZXgoY2hpbGRUeC50eCwgdXR4b2xpYi5uZXR3b3Jrcy5iaXRjb2luKTtcbiAgICAgICAgZGVjb2RlZENoaWxkLmlucy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgICBkZWNvZGVkQ2hpbGQub3V0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICAgIGxldCBpbnB1dEZyb21QYXJlbnQ6IGFueSA9IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGFkZGl0aW9uYWxJbnB1dDogYW55ID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIF8uZm9yRWFjaChkZWNvZGVkQ2hpbGQuaW5zLCAoaW5wdXQpID0+IHtcbiAgICAgICAgICBpbnB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaGFzaCcpO1xuICAgICAgICAgIGlucHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpbmRleCcpO1xuXG4gICAgICAgICAgY29uc3QgaW5wdXRIYXNoID0gaW5wdXRQYXJlbnRUeElkKGlucHV0KTtcblxuICAgICAgICAgIGlmIChpbnB1dEhhc2ggPT09IHBhcmVudFR4SWQpIHtcbiAgICAgICAgICAgIGlucHV0RnJvbVBhcmVudCA9IGlucHV0O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhZGRpdGlvbmFsSW5wdXQgPSBpbnB1dDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChpbnB1dEZyb21QYXJlbnQpO1xuICAgICAgICBjb25zdCBpbnB1dEZyb21QYXJlbnRIYXNoID0gaW5wdXRQYXJlbnRUeElkKGlucHV0RnJvbVBhcmVudCk7XG4gICAgICAgIGlucHV0RnJvbVBhcmVudEhhc2guc2hvdWxkLmVxdWFsKHBhcmVudFR4SWQpO1xuICAgICAgICBpbnB1dEZyb21QYXJlbnQuaW5kZXguc2hvdWxkLmVxdWFsKDApO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChhZGRpdGlvbmFsSW5wdXQpO1xuICAgICAgICBjb25zdCBhZGRpdGlvbmFsSW5wdXRIYXNoID0gaW5wdXRQYXJlbnRUeElkKGFkZGl0aW9uYWxJbnB1dCk7XG4gICAgICAgIGFkZGl0aW9uYWxJbnB1dEhhc2guc2hvdWxkLmVxdWFsKGFkZGl0aW9uYWxVbnNwZW50VHhJZCk7XG4gICAgICAgIGFkZGl0aW9uYWxJbnB1dC5pbmRleC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgY29uc3QgY2hpbGRPdXRwdXQgPSBkZWNvZGVkQ2hpbGQub3V0c1swXTtcbiAgICAgICAgY2hpbGRPdXRwdXQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3ZhbHVlJyk7XG4gICAgICAgIGNoaWxkT3V0cHV0LnZhbHVlLnNob3VsZC5iZS5hYm92ZShtaW5DaGFuZ2VTaXplKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnYWNjZWxlcmF0ZXMgYSBzdHVjayB0eCB3aXRoIHR3byBhZGRpdGlvbmFsIHVuc3BlbnRzIChzZWd3aXQgYW5kIFAyU0gpJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBwYXJlbnRUeElkID0gJzg4MTVmMjAyYzg2NTRiNmM4YjI5NTc0OTU0NWM3MTE4NzhjZDg0NWExNGNiMWVhOTgyMzk0ZDBjMTQ5NDVjMzMnO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGZlZTogMTMzNixcbiAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZvdXQ6IDAsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwMDAwLFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMTEsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB2b3V0OiAxLFxuICAgICAgICAgICAgICAgIHZhbHVlOiA4NjY0LFxuICAgICAgICAgICAgICAgIGlzTWluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjaGFpbjogMSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjb25maXJtYXRpb25zOiAwLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLmdldChgL2FwaS92MS93YWxsZXQvJHt3YWxsZXQuaWQoKX0vdW5zcGVudHNgKVxuICAgICAgICAgIC5xdWVyeSh0cnVlKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIHVuc3BlbnRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eF9oYXNoOiBwYXJlbnRUeElkLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgICByZWRlZW1TY3JpcHQ6XG4gICAgICAgICAgICAgICAgICAnNTIyMTAyY2QzYzhlNjAwNmE0NjI3NzA1MDIxZDFkMDE2ZDA5N2MyOTQ0ZDk4MTAwYTQ3YmYyZGE2N2E1ZmUxNWFlZWIzNDIxMDJlZTFmYTllODEyZTc3OTM1NmFhM2MzMWViZjMxN2QwY2ZmZWJhYjkyODY0Y2ZlMzhiYWIyMjNlMDgyMGY5OGJjMjEwMjZiYTA1NzUyYmFhNmVhZmQ1YzU2NTlkYTYyYjdmMGFjNTFmZDI4ODZiNjVjMjQxZDBhZmVmMWM0ZmRmYTFjYmM1M2FlJyxcbiAgICAgICAgICAgICAgICBjaGFpblBhdGg6ICcvMC8wJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdW5zcGVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR4X2hhc2g6ICdlMTkwMzEwZjJmM2Y3MWFhODg0NmYxMTYxY2JjZTE1MzNjMjRhODU3ZGQyNGU0NTAxYjEzMWZlYjQwMGFhZDU4JyxcbiAgICAgICAgICAgICAgICB0eF9vdXRwdXRfbjogMSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogODAwMDAwLFxuICAgICAgICAgICAgICAgIHJlZGVlbVNjcmlwdDpcbiAgICAgICAgICAgICAgICAgICc1MjIxMDJjZDNjOGU2MDA2YTQ2Mjc3MDUwMjFkMWQwMTZkMDk3YzI5NDRkOTgxMDBhNDdiZjJkYTY3YTVmZTE1YWVlYjM0MjEwMmVlMWZhOWU4MTJlNzc5MzU2YWEzYzMxZWJmMzE3ZDBjZmZlYmFiOTI4NjRjZmUzOGJhYjIyM2UwODIwZjk4YmMyMTAyNmJhMDU3NTJiYWE2ZWFmZDVjNTY1OWRhNjJiN2YwYWM1MWZkMjg4NmI2NWMyNDFkMGFmZWYxYzRmZGZhMWNiYzUzYWUnLFxuICAgICAgICAgICAgICAgIGNoYWluUGF0aDogJy8wLzAnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHhfaGFzaDogJzA3ZDZlZTU3YjAyNGNlMmI2MTA4ZjY3ODQ3NDU0YTBhNzlhNGZjZmI5OGFiMjU1NTUzYTI5OTNhMWExNzBiODcnLFxuICAgICAgICAgICAgICAgIHR4X291dHB1dF9uOiAwLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAyMDAwNjI4NCxcbiAgICAgICAgICAgICAgICByZWRlZW1TY3JpcHQ6ICcwMDIwZDM0ZWY2ZGQzNGVmMmE0ZmJlYTY3YzU0MWMxYzc5Njc0OWE2MGFmZTRhOTdmZWU4ZWM3ZGVkMTg4YmQ3NDlkYScsXG4gICAgICAgICAgICAgICAgY2hhaW5QYXRoOiAnLzExLzE1NScsXG4gICAgICAgICAgICAgICAgd2l0bmVzc1NjcmlwdDpcbiAgICAgICAgICAgICAgICAgICc1MjIxMDIyMTlkMmFhODQxNzYzM2YwYmNlMzkxMTM3NGExNjA0YzFiNjQxNjFmODNhM2MyZWU0MDljMjdjNDIzNTVmMDhlMjEwMmM5NzM0OTIwZGM0ZGEwNmMyODlmZTY5MTcxZGZjZDc1ZTNiOWI0ZjE5MGQwY2JjM2Q1ZDBmZjNmNWZkZWVhYWUyMTAzY2NkNjhkN2ZhOGRjMGQwMmRkNDVkYWQxNjU1NTdhNDg1ODJlZGE0NDM1ZmFlNzM3N2IzYzMxZTA4YWQwNjVjOTUzYWUnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICBub2NrKGV4cGxvcmVyVXJsKS5nZXQoYC90eC8ke3BhcmVudFR4SWR9L2hleGApLnJlcGx5KDIwMCwgZml4dHVyZXNbcGFyZW50VHhJZF0pO1xuXG4gICAgICAgIG5vY2soYmdVcmwpXG4gICAgICAgICAgLnBvc3QoJy9hcGkvdjEvdHgvc2VuZCcsIChib2R5KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gIWJvZHkuaWdub3JlTWF4RmVlUmF0ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIGZ1bmN0aW9uIChfLCBib2R5KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICB0cmFuc2FjdGlvbjogKGJvZHkgYXMgYW55KS50eCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgY2hpbGRUeCA9IGF3YWl0IHdhbGxldC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogVGVzdEJpdEdvLlRFU1RfV0FMTEVUMV9QQVNTQ09ERSxcbiAgICAgICAgICBmZWVSYXRlLFxuICAgICAgICB9KTtcblxuICAgICAgICBzaG91bGQuZXhpc3QoY2hpbGRUeCk7XG4gICAgICAgIGNoaWxkVHguc2hvdWxkLmhhdmUucHJvcGVydHkoJ3N0YXR1cycsICdhY2NlcHRlZCcpO1xuICAgICAgICBjaGlsZFR4LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuXG4gICAgICAgIC8vIGFzc2VydCB0aGUgZm9sbG93aW5nOlxuICAgICAgICAvLyAwKSBUaGUgY2hpbGQgdHggaGFzIGV4YWN0bHkgdGhyZWUgaW5wdXRzXG4gICAgICAgIC8vIDEpIFRoZSBwYXJlbnQgdHggb3V0cHV0IGlzIGFuIGlucHV0XG4gICAgICAgIC8vIDIpIFRoZSBjaGlsZCB0eCBoYXMgZXhhY3RseSBvbmUgb3V0cHV0XG4gICAgICAgIC8vIDMpIFRoZSBjaGlsZCB0eCBvdXRwdXQgbWVldHMgdGhlIG1pbmltdW0gY2hhbmdlIHRocmVzaG9sZFxuICAgICAgICBjb25zdCBkZWNvZGVkQ2hpbGQgPSB1dHhvbGliLmJpdGdvLmNyZWF0ZVRyYW5zYWN0aW9uRnJvbUhleChjaGlsZFR4LnR4LCB1dHhvbGliLm5ldHdvcmtzLmJpdGNvaW4pO1xuICAgICAgICBkZWNvZGVkQ2hpbGQuaW5zLmxlbmd0aC5zaG91bGQuZXF1YWwoMyk7XG4gICAgICAgIGRlY29kZWRDaGlsZC5vdXRzLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgbGV0IGlucHV0RnJvbVBhcmVudDogYW55ID0gdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBhZGRpdGlvbmFsSW5wdXRzOiBhbnlbXSA9IFtdO1xuXG4gICAgICAgIF8uZm9yRWFjaChkZWNvZGVkQ2hpbGQuaW5zLCAoaW5wdXQpID0+IHtcbiAgICAgICAgICBpbnB1dC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaGFzaCcpO1xuICAgICAgICAgIGlucHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCdpbmRleCcpO1xuXG4gICAgICAgICAgY29uc3QgaW5wdXRIYXNoID0gaW5wdXRQYXJlbnRUeElkKGlucHV0KTtcblxuICAgICAgICAgIGlmIChpbnB1dEhhc2ggPT09IHBhcmVudFR4SWQpIHtcbiAgICAgICAgICAgIGlucHV0RnJvbVBhcmVudCA9IGlucHV0O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhZGRpdGlvbmFsSW5wdXRzLnB1c2goaW5wdXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KGlucHV0RnJvbVBhcmVudCk7XG4gICAgICAgIGNvbnN0IGlucHV0RnJvbVBhcmVudEhhc2ggPSBpbnB1dFBhcmVudFR4SWQoaW5wdXRGcm9tUGFyZW50KTtcbiAgICAgICAgaW5wdXRGcm9tUGFyZW50SGFzaC5zaG91bGQuZXF1YWwocGFyZW50VHhJZCk7XG4gICAgICAgIGlucHV0RnJvbVBhcmVudC5pbmRleC5zaG91bGQuZXF1YWwoMCk7XG5cbiAgICAgICAgYWRkaXRpb25hbElucHV0cy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuXG4gICAgICAgIGNvbnN0IGNoaWxkT3V0cHV0ID0gZGVjb2RlZENoaWxkLm91dHNbMF07XG4gICAgICAgIGNoaWxkT3V0cHV0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd2YWx1ZScpO1xuICAgICAgICBjaGlsZE91dHB1dC52YWx1ZS5zaG91bGQuYmUuYWJvdmUobWluQ2hhbmdlU2l6ZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ2NvcnJlY3RseSB1c2VzIHRoZSBpZ25vcmVNYXhGZWVSYXRlIHBhcmFtZXRlciBvbmx5IHdoZW4gbmVjZXNzYXJ5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBwYXJlbnRUeElkID0gJzc1Y2ZjNWE3YjIxNGM0YjczYzkyYzdiMDI2MDhjZGU3MGIyMjY3NjdhOTU3NmY4NGMwNDQwN2U0M2ZkMzg1YmQnO1xuICAgICAgICBub2NrKGJnVXJsKVxuICAgICAgICAgIC5nZXQoYC9hcGkvdjEvd2FsbGV0LyR7d2FsbGV0LmlkKCl9L3R4LyR7cGFyZW50VHhJZH1gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIGZlZTogNDM0LFxuICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdm91dDogMCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAzNDg1MDAsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAwLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdm91dDogMSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAsXG4gICAgICAgICAgICAgICAgaXNNaW5lOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNoYWluOiAxMSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YxL3dhbGxldC8ke3dhbGxldC5pZCgpfS91bnNwZW50c2ApXG4gICAgICAgICAgLnF1ZXJ5KHRydWUpXG4gICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgdW5zcGVudHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR4X2hhc2g6IHBhcmVudFR4SWQsXG4gICAgICAgICAgICAgICAgdHhfb3V0cHV0X246IDAsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDEwMzQ4NTAwLFxuICAgICAgICAgICAgICAgIHJlZGVlbVNjcmlwdDogJzAwMjBmN2I1OGQ0NTUzNTFiN2I4ZGRkN2M4OTg2ZDk4MjQ0ZjZhOTVmMDc0NjcyMDA5MTUzNzMyM2I5Njc4MDBmNzQ0JyxcbiAgICAgICAgICAgICAgICBjaGFpblBhdGg6ICcvMTEvMTYwJyxcbiAgICAgICAgICAgICAgICB3aXRuZXNzU2NyaXB0OlxuICAgICAgICAgICAgICAgICAgJzUyMjEwMjdmMGI0NWJiNDE1NWVhNTMyZTNiNDMxMmZlMGJlODAxNjZmMjk3ZDFlMDc1M2QyZDRhOTExOGMwNzNhZDY1MTQyMTAzMTBhYTlkNjhjOTg4MzE2MjVmMzI5Yjc4MjZiNmMzZTNiNTNlMTY3MzZiMTk5NGI4OTAyNDQyYmRjZDY2NTNkMTIxMDI2ZTBjYTQxNGYyNDg4YjBhYjU3MmI5OWUwYWU1NDQyOTExYWI0ZTA4MjFiMjcwOWQ4ODUxNzVhNTI3ZmQ1NTJiNTNhZScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIG5vY2soZXhwbG9yZXJVcmwpLmdldChgL3R4LyR7cGFyZW50VHhJZH0vaGV4YCkucmVwbHkoMjAwLCBmaXh0dXJlc1twYXJlbnRUeElkXSk7XG5cbiAgICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgICAucG9zdCgnL2FwaS92MS90eC9zZW5kJywgKGJvZHkpID0+IHtcbiAgICAgICAgICAgIC8vIGlnbm9yZSBtYXggZmVlIHJhdGUgbXVzdCBiZSBzZXQgZm9yIHRoaXMgdGVzdFxuICAgICAgICAgICAgcmV0dXJuIGJvZHkuaWdub3JlTWF4RmVlUmF0ZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAgIC8vIG1vbmtleSBwYXRjaCB0aGUgYml0Z28gZ2V0Q29uc3RhbnRzKCkgZnVuY3Rpb25cbiAgICAgICAgY29uc3Qgb2xkR2V0Q29uc3RhbnRzID0gKGJpdGdvIGFzIGFueSkuX19wcm90b19fLmdldENvbnN0YW50cztcbiAgICAgICAgKGJpdGdvIGFzIGFueSkuX19wcm90b19fLmdldENvbnN0YW50cyA9ICgpID0+ICh7XG4gICAgICAgICAgLy8gY2hpbGQgZmVlIHJhdGUgaW4gdGhpcyB0ZXN0IGlzIDMxMzc4IHNhdC9rYlxuICAgICAgICAgIC8vIHNvIHNldCB0aGUgbWF4IGZlZSByYXRlIGp1c3QgYmVsb3cgdGhhdCBsaW1pdCxcbiAgICAgICAgICAvLyBidXQgYWJvdmUgdGhlIGNvbWJpbmVkIGZlZSByYXRlIG9mIDIwMDAwXG4gICAgICAgICAgbWF4RmVlUmF0ZTogMzAwMDAsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGF3YWl0IHdhbGxldC5hY2NlbGVyYXRlVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHRyYW5zYWN0aW9uSUQ6IHBhcmVudFR4SWQsXG4gICAgICAgICAgZmVlUmF0ZSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQxX1BBU1NDT0RFLFxuICAgICAgICB9KTtcbiAgICAgICAgbm9jay5wZW5kaW5nTW9ja3MoKS5zaG91bGQuYmUuZW1wdHkoKTtcblxuICAgICAgICAoYml0Z28gYXMgYW55KS5fX3Byb3RvX18uZ2V0Q29uc3RhbnRzID0gb2xkR2V0Q29uc3RhbnRzO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=