@bitgo-beta/sdk-coin-ethlike 1.0.1-beta.97 → 1.0.1-beta.970

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.
@@ -0,0 +1,716 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const assert_1 = __importDefault(require("assert"));
40
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
41
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
42
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
43
+ const secp256k1_1 = require("@bitgo-beta/secp256k1");
44
+ const nock_1 = __importDefault(require("nock"));
45
+ const src_1 = require("../../src");
46
+ const getBuilder_1 = require("../getBuilder");
47
+ const resources_1 = require("../resources");
48
+ const mockData = __importStar(require("../fixtures/ethlikeCoin"));
49
+ nock_1.default.enableNetConnect();
50
+ const coins = [
51
+ {
52
+ name: 'hteth',
53
+ common: (0, resources_1.getCommon)('hteth'),
54
+ },
55
+ {
56
+ name: 'tarbeth',
57
+ common: (0, resources_1.getCommon)('tarbeth'),
58
+ },
59
+ ];
60
+ describe('EthLike coin tests', function () {
61
+ let bitgo;
62
+ let basecoin;
63
+ coins.forEach((coin) => {
64
+ describe(coin.name, function () {
65
+ before(function () {
66
+ const env = 'test';
67
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env });
68
+ bitgo.safeRegister(coin.name, src_1.TethLikeCoin.createInstance);
69
+ bitgo.initializeTestVars();
70
+ basecoin = bitgo.coin(coin.name);
71
+ });
72
+ after(function () {
73
+ nock_1.default.cleanAll();
74
+ });
75
+ it('should instantiate a coin', function () {
76
+ basecoin.should.be.an.instanceof(src_1.TethLikeCoin);
77
+ });
78
+ it('should reject for missing encryptedPrv for hot wallet', async function () {
79
+ const recoveryId = '0x1234567890abcdef';
80
+ (0, nock_1.default)(bitgo.microservicesUrl(`/api/recovery/v1/crosschain`)).get(`/${recoveryId}/buildtx`).reply(200, {
81
+ txHex: mockData.ccr[coin.name].txHex,
82
+ });
83
+ const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
84
+ const params = {
85
+ recoveryId,
86
+ walletPassphrase,
87
+ common: coin.common,
88
+ };
89
+ await basecoin
90
+ .sendCrossChainRecoveryTransaction({ ...params, walletType: 'hot' })
91
+ .should.be.rejectedWith('missing encryptedPrv');
92
+ });
93
+ it('should send cross chain recovery transaction for hot wallet', async function () {
94
+ const recoveryId = '0x1234567890abcdef';
95
+ (0, nock_1.default)(bitgo.microservicesUrl(`/api/recovery/v1/crosschain`)).get(`/${recoveryId}/buildtx`).reply(200, {
96
+ txHex: mockData.ccr[coin.name].txHex,
97
+ });
98
+ (0, nock_1.default)(bitgo.microservicesUrl(`/api/recovery/v1/crosschain`)).post(`/${recoveryId}/sign`).reply(200, {
99
+ coin: coin.name,
100
+ txid: mockData.ccr[coin.name].txid,
101
+ });
102
+ const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
103
+ const params = {
104
+ recoveryId,
105
+ walletPassphrase,
106
+ encryptedPrv: mockData.encryptedUserKey,
107
+ common: coin.common,
108
+ };
109
+ const result = await basecoin.sendCrossChainRecoveryTransaction({ ...params, walletType: 'hot' });
110
+ result.coin.should.equal(coin.name);
111
+ result.txid.should.equal(mockData.ccr[coin.name].txid);
112
+ });
113
+ it('should build txn for cross chain recovery for cold wallet', async function () {
114
+ const recoveryId = '0x1234567890abcdef';
115
+ (0, nock_1.default)(bitgo.microservicesUrl(`/api/recovery/v1/crosschain`)).get(`/${recoveryId}/buildtx`).reply(200, {
116
+ txHex: mockData.ccr[coin.name].txHex,
117
+ });
118
+ const params = {
119
+ recoveryId,
120
+ common: coin.common,
121
+ };
122
+ const result = await basecoin.sendCrossChainRecoveryTransaction({ ...params, walletType: 'cold' });
123
+ (0, assert_1.default)(result.txHex);
124
+ result.txHex.should.equal(mockData.ccr[coin.name].txHex);
125
+ });
126
+ it('should build cross chain recovery transaction and extract recipients', async function () {
127
+ const recoveryId = '0x1234567890abcdef';
128
+ const mockResponse = {
129
+ coin: coin.name,
130
+ txHex: mockData.ccr[coin.name].txHex,
131
+ txid: mockData.ccr[coin.name].txid,
132
+ walletVersion: 1,
133
+ };
134
+ (0, nock_1.default)(bitgo.microservicesUrl(`/api/recovery/v1/crosschain`))
135
+ .get(`/${recoveryId}/buildtx`)
136
+ .reply(200, mockResponse);
137
+ const result = await basecoin.buildCrossChainRecoveryTransaction(recoveryId);
138
+ result.should.have.property('coin');
139
+ result.coin.should.equal(coin.name);
140
+ result.should.have.property('txHex');
141
+ result.txHex.should.equal(mockData.ccr[coin.name].txHex);
142
+ result.should.have.property('txid');
143
+ result.txid.should.equal(mockData.ccr[coin.name].txid);
144
+ result.should.have.property('walletVersion');
145
+ result.should.have.property('recipients');
146
+ result.recipients.should.be.an.Array();
147
+ const recipient = result.recipients[0];
148
+ recipient.should.have.property('address');
149
+ recipient.should.have.property('amount');
150
+ recipient.address.should.be.a.String();
151
+ recipient.amount.should.be.a.String();
152
+ });
153
+ it('should generate signature data for custodial hot wallet and sign using hsm signature', async function () {
154
+ const baseAddress = '0x702cf81e03aa310ec9481d814e3d04a20b04b505';
155
+ const destinationAddress = '0xb9f62c71d5f6949cfb211a67fb13ccf079cc760b';
156
+ const tokenContractAddress = '0xe4ab69c077896252fafbd49efd26b5d171a32410';
157
+ const txBuilder = (0, getBuilder_1.getBuilder)(coin.name, coin.common);
158
+ txBuilder.contract(baseAddress);
159
+ txBuilder.contractCounter(0);
160
+ txBuilder.fee({
161
+ fee: '100000',
162
+ gasLimit: '21000',
163
+ });
164
+ const transferBuilder = txBuilder.transfer();
165
+ transferBuilder
166
+ .coin(coin.name)
167
+ .amount('100000000')
168
+ .contractSequenceId(100)
169
+ .expirationTime(1744049633)
170
+ .to(destinationAddress)
171
+ .tokenContractAddress(tokenContractAddress);
172
+ const signatureData = transferBuilder.getSignatureData();
173
+ assert_1.default.strictEqual(signatureData.toString('hex'), mockData.custodialHot[coin.name].signatureData);
174
+ // Set HSM Signature
175
+ transferBuilder.setSignature(mockData.custodialHot[coin.name].signature);
176
+ const tx = await txBuilder.build();
177
+ const txHex = tx.toBroadcastFormat();
178
+ assert_1.default.strictEqual(txHex, mockData.custodialHot[coin.name].signedTxHex);
179
+ });
180
+ });
181
+ });
182
+ });
183
+ describe('EthLikeCoin', function () {
184
+ let bitgo;
185
+ const coinName = 'tbaseeth';
186
+ let basecoin;
187
+ before(function () {
188
+ const bitgoKeyXprv = 'xprv9s21ZrQH143K3tpWBHWe31sLoXNRQ9AvRYJgitkKxQ4ATFQMwvr7hHNqYRUnS7PsjzB7aK1VxqHLuNQjj1sckJ2Jwo2qxmsvejwECSpFMfC';
189
+ const bitgoKey = secp256k1_1.bip32.fromBase58(bitgoKeyXprv);
190
+ if (!bitgoKey.privateKey) {
191
+ throw new Error('no privateKey');
192
+ }
193
+ const bitgoXpub = bitgoKey.neutered().toBase58();
194
+ const env = 'test';
195
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env });
196
+ sdk_core_1.common.Environments[env].hsmXpub = bitgoXpub;
197
+ bitgo.safeRegister('baseeth', src_1.EthLikeCoin.createInstance);
198
+ bitgo.safeRegister('tbaseeth', src_1.TethLikeCoin.createInstance);
199
+ bitgo.initializeTestVars();
200
+ basecoin = bitgo.coin('tbaseeth');
201
+ });
202
+ after(function () {
203
+ nock_1.default.cleanAll();
204
+ });
205
+ it('should instantiate a coin', function () {
206
+ let coin = bitgo.coin('tbaseeth');
207
+ coin.should.be.an.instanceof(src_1.TethLikeCoin);
208
+ coin = bitgo.coin('baseeth');
209
+ coin.should.be.an.instanceof(src_1.EthLikeCoin);
210
+ });
211
+ it('should build unsigned transaction', async function () {
212
+ const expireTime = Math.floor(new Date().getTime() / 1000);
213
+ const txBuilder = (0, getBuilder_1.getBuilder)(coinName, resources_1.baseChainCommon);
214
+ txBuilder.type(sdk_core_1.TransactionType.Send);
215
+ txBuilder.fee({
216
+ fee: '1000000000',
217
+ gasLimit: '100000',
218
+ });
219
+ txBuilder.counter(1);
220
+ txBuilder.contract('0x2c2b9c9a4a25e24b174f26114e8926a9f2128fe4');
221
+ const transferBuilder = txBuilder.transfer();
222
+ transferBuilder
223
+ .coin(coinName)
224
+ .expirationTime(expireTime)
225
+ .amount('1000000000000000000')
226
+ .to('0x2c2b9c9a4a25e24b174f26114e8926a9f2128fe4')
227
+ .contractSequenceId(1);
228
+ const tx = await txBuilder.build();
229
+ const txJson = tx.toJson();
230
+ txJson.gasLimit.should.equal('100000');
231
+ txJson.gasPrice.should.equal('1000000000');
232
+ txJson.chainId.should.equal('0x14a34');
233
+ });
234
+ it('should sign a transaction', async function () {
235
+ const account_1 = {
236
+ address: '0x8Ce59c2d1702844F8EdED451AA103961bC37B4e8',
237
+ owner_1: '4ee089aceabf3ddbf748db79b1066c33b7d3ea1ab3eb7e325121bba2bff2f5ca',
238
+ owner_2: '5c7e4efff7304d4dfff6d5f1591844ec6f2adfa6a47e9fece6a3c1a4d755f1e3',
239
+ owner_3: '4421ab25dd91e1a3180d03d57c323a7886dcc313d3b3a4b4256a5791572bf597',
240
+ };
241
+ const expireTime = Math.floor(new Date().getTime() / 1000);
242
+ const txBuilder = (0, getBuilder_1.getBuilder)(coinName, resources_1.baseChainCommon);
243
+ txBuilder.type(sdk_core_1.TransactionType.Send);
244
+ txBuilder.fee({
245
+ fee: '1000000000',
246
+ gasLimit: '100000',
247
+ });
248
+ txBuilder.counter(1);
249
+ txBuilder.contract(account_1.address);
250
+ const transferBuilder = txBuilder.transfer();
251
+ transferBuilder
252
+ .coin(coinName)
253
+ .expirationTime(expireTime)
254
+ .amount('1000000000000000000')
255
+ .to('0x2c2b9c9a4a25e24b174f26114e8926a9f2128fe4')
256
+ .contractSequenceId(1);
257
+ const unsignedTx = await txBuilder.build();
258
+ const unsignedTxHex = unsignedTx.toBroadcastFormat();
259
+ const halfSignedTx = (await basecoin.signTransaction({
260
+ txPrebuild: {
261
+ txHex: unsignedTxHex,
262
+ },
263
+ prv: account_1.owner_1,
264
+ common: resources_1.baseChainCommon,
265
+ }));
266
+ transferBuilder.key(account_1.owner_1);
267
+ const halfSignedTxBuilder = await txBuilder.build();
268
+ const halfSignedTxHexBuilder = halfSignedTxBuilder.toBroadcastFormat();
269
+ halfSignedTxHexBuilder.should.equal(halfSignedTx.halfSigned.txHex);
270
+ // Sign with the second key
271
+ const fullSignedTxn = (await basecoin.signTransaction({
272
+ txPrebuild: {
273
+ halfSigned: {
274
+ txHex: halfSignedTxHexBuilder,
275
+ expireTime: expireTime,
276
+ contractSequenceId: 1,
277
+ signature: '',
278
+ },
279
+ },
280
+ prv: account_1.owner_2,
281
+ common: resources_1.baseChainCommon,
282
+ isLastSignature: true,
283
+ }));
284
+ (0, assert_1.default)(fullSignedTxn.txHex);
285
+ });
286
+ describe('explainTransaction', function () {
287
+ const txHex = mockData.ccr[coinName].txHex;
288
+ const feeInfo = {
289
+ fee: '1000000000',
290
+ gasLimit: '100000',
291
+ };
292
+ it('should explain transaction when common is provided', async function () {
293
+ const explanation = await basecoin.explainTransaction({
294
+ txHex,
295
+ feeInfo,
296
+ common: resources_1.baseChainCommon,
297
+ });
298
+ explanation.should.have.property('id');
299
+ explanation.should.have.property('outputs');
300
+ explanation.should.have.property('outputAmount');
301
+ explanation.should.have.property('changeOutputs');
302
+ explanation.should.have.property('changeAmount');
303
+ explanation.should.have.property('fee');
304
+ explanation.fee.should.equal(feeInfo);
305
+ explanation.outputs.should.be.an.Array();
306
+ });
307
+ it('should fail to explain transaction when common is not provided', async function () {
308
+ await basecoin
309
+ .explainTransaction({
310
+ txHex,
311
+ feeInfo,
312
+ })
313
+ .should.be.rejectedWith('Common must be provided for EthLikeTransactionBuilder');
314
+ });
315
+ });
316
+ describe('Recovery', function () {
317
+ const baseUrl = 'https://api-sepolia.basescan.org/';
318
+ const userXpub = 'xpub661MyMwAqRbcEeTc8789MK5PUGEYiPG4F4V17n2Rd2LoTATA1XoCnJT5FAYAShQxSxtFjpo5NHmcWwTp2LiWGBMwpUcAA3HywhxivgYfq7q';
319
+ const backupXpub = 'xpub661MyMwAqRbcFZX15xpZf4ERCGHiVSJm8r5C4yh1yXV2GrdZCUPYo4WQr6tN9oUywKXsgSHo7Risf9r22GH5joVD2hEEEhqnSCvK8qy11wW';
320
+ it('should generate an unsigned sweep transaction', async function () {
321
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
322
+ const backupKeyAddress = '0x4f2c4830cc37f2785c646f89ded8a919219fa0e9';
323
+ (0, nock_1.default)(baseUrl)
324
+ .get('/api')
325
+ .twice()
326
+ .query(mockData.getTxListRequest(backupKeyAddress))
327
+ .reply(200, mockData.getTxListResponse);
328
+ (0, nock_1.default)(baseUrl)
329
+ .get('/api')
330
+ .query(mockData.getBalanceRequest(walletContractAddress))
331
+ .reply(200, mockData.getBalanceResponse);
332
+ (0, nock_1.default)(baseUrl)
333
+ .get('/api')
334
+ .query(mockData.getBalanceRequest(backupKeyAddress))
335
+ .reply(200, mockData.getBalanceResponse);
336
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
337
+ const baseCoin = bitgo.coin('tbaseeth');
338
+ const transaction = (await baseCoin.recover({
339
+ userKey: userXpub,
340
+ backupKey: backupXpub,
341
+ walletContractAddress: walletContractAddress,
342
+ recoveryDestination: sdk_test_1.TestBitGo.V2.TEST_ERC20_TOKEN_RECIPIENT,
343
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
344
+ gasLimit: 500000,
345
+ common: resources_1.baseChainCommon,
346
+ }));
347
+ (0, assert_1.default)(transaction.txHex);
348
+ (0, assert_1.default)(transaction.contractSequenceId);
349
+ assert_1.default.strictEqual(transaction.gasLimit, '500000');
350
+ });
351
+ });
352
+ describe('Evm Based Cross Chain Recovery transaction:', function () {
353
+ const baseUrl = 'https://api-sepolia.basescan.org/';
354
+ const userXpub = 'xpub661MyMwAqRbcEeTc8789MK5PUGEYiPG4F4V17n2Rd2LoTATA1XoCnJT5FAYAShQxSxtFjpo5NHmcWwTp2LiWGBMwpUcAA3HywhxivgYfq7q';
355
+ it('should generate an unsigned recovery txn for cold wallet', async function () {
356
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
357
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
358
+ const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
359
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
360
+ const basecoin = bitgo.coin('tbaseeth');
361
+ (0, nock_1.default)(baseUrl)
362
+ .get('/api')
363
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
364
+ .reply(200, mockData.getTxListResponse);
365
+ (0, nock_1.default)(baseUrl)
366
+ .get('/api')
367
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
368
+ .reply(200, mockData.getBalanceResponse);
369
+ (0, nock_1.default)(baseUrl)
370
+ .get('/api')
371
+ .query(mockData.getBalanceRequest(walletContractAddress))
372
+ .reply(200, mockData.getBalanceResponse);
373
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
374
+ const transaction = (await basecoin.recover({
375
+ userKey: userXpub,
376
+ backupKey: '',
377
+ walletContractAddress: walletContractAddress,
378
+ bitgoFeeAddress: bitgoFeeAddress,
379
+ recoveryDestination: destinationAddress,
380
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
381
+ gasLimit: 500000,
382
+ bitgoDestinationAddress: bitgoDestinationAddress,
383
+ common: resources_1.baseChainCommon,
384
+ }));
385
+ (0, assert_1.default)(transaction);
386
+ transaction.should.have.property('txHex');
387
+ transaction.should.have.property('userKey');
388
+ transaction.should.have.property('coin');
389
+ transaction.should.have.property('contractSequenceId');
390
+ transaction.should.have.property('expireTime');
391
+ transaction.should.have.property('gasLimit');
392
+ transaction.gasLimit.should.equal('500000');
393
+ transaction.should.have.property('isEvmBasedCrossChainRecovery');
394
+ transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
395
+ transaction.should.have.property('walletContractAddress');
396
+ transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
397
+ transaction.should.have.property('recipients');
398
+ const recipient = transaction.recipients[0];
399
+ recipient.should.have.property('address');
400
+ recipient.address.should.equal(destinationAddress);
401
+ recipient.should.have.property('amount');
402
+ recipient.amount.should.equal('9999999999999999928');
403
+ });
404
+ it('should generate an unsigned recovery txn for custody wallet', async function () {
405
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
406
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
407
+ const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
408
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
409
+ const basecoin = bitgo.coin('tbaseeth');
410
+ (0, nock_1.default)(baseUrl)
411
+ .get('/api')
412
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
413
+ .reply(200, mockData.getTxListResponse);
414
+ (0, nock_1.default)(baseUrl)
415
+ .get('/api')
416
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
417
+ .reply(200, mockData.getBalanceResponse);
418
+ (0, nock_1.default)(baseUrl)
419
+ .get('/api')
420
+ .query(mockData.getBalanceRequest(walletContractAddress))
421
+ .reply(200, mockData.getBalanceResponse);
422
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
423
+ const transaction = (await basecoin.recover({
424
+ userKey: '',
425
+ backupKey: '',
426
+ walletContractAddress: walletContractAddress,
427
+ bitgoFeeAddress: bitgoFeeAddress,
428
+ recoveryDestination: destinationAddress,
429
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
430
+ gasLimit: 500000,
431
+ bitgoDestinationAddress: bitgoDestinationAddress,
432
+ common: resources_1.baseChainCommon,
433
+ }));
434
+ (0, assert_1.default)(transaction);
435
+ transaction.should.have.property('txHex');
436
+ transaction.should.have.property('coin');
437
+ transaction.should.have.property('contractSequenceId');
438
+ transaction.should.have.property('expireTime');
439
+ transaction.should.have.property('gasLimit');
440
+ transaction.gasLimit.should.equal('500000');
441
+ transaction.should.have.property('isEvmBasedCrossChainRecovery');
442
+ transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
443
+ transaction.should.have.property('walletContractAddress');
444
+ transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
445
+ transaction.should.have.property('recipients');
446
+ const recipient = transaction.recipients[0];
447
+ recipient.should.have.property('address');
448
+ recipient.address.should.equal(destinationAddress);
449
+ recipient.should.have.property('amount');
450
+ recipient.amount.should.equal('9999999999999999928');
451
+ });
452
+ it('should generate an unsigned recovery txn for hot wallet', async function () {
453
+ const userKey = '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
454
+ ':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
455
+ '53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
456
+ 'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n';
457
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
458
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
459
+ const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
460
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
461
+ const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
462
+ const basecoin = bitgo.coin('tbaseeth');
463
+ (0, nock_1.default)(baseUrl)
464
+ .get('/api')
465
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
466
+ .reply(200, mockData.getTxListResponse);
467
+ (0, nock_1.default)(baseUrl)
468
+ .get('/api')
469
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
470
+ .reply(200, mockData.getBalanceResponse);
471
+ (0, nock_1.default)(baseUrl)
472
+ .get('/api')
473
+ .query(mockData.getBalanceRequest(walletContractAddress))
474
+ .reply(200, mockData.getBalanceResponse);
475
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
476
+ const transaction = (await basecoin.recover({
477
+ userKey: userKey,
478
+ backupKey: '',
479
+ walletPassphrase: walletPassphrase,
480
+ walletContractAddress: walletContractAddress,
481
+ bitgoFeeAddress: bitgoFeeAddress,
482
+ recoveryDestination: destinationAddress,
483
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
484
+ gasLimit: 500000,
485
+ bitgoDestinationAddress: bitgoDestinationAddress,
486
+ common: resources_1.baseChainCommon,
487
+ }));
488
+ (0, assert_1.default)(transaction);
489
+ transaction.should.have.property('txHex');
490
+ transaction.should.have.property('coin');
491
+ transaction.should.have.property('contractSequenceId');
492
+ transaction.should.have.property('expireTime');
493
+ transaction.should.have.property('gasLimit');
494
+ transaction.gasLimit.should.equal('500000');
495
+ transaction.should.have.property('isEvmBasedCrossChainRecovery');
496
+ transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
497
+ transaction.should.have.property('walletContractAddress');
498
+ transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
499
+ transaction.should.have.property('recipients');
500
+ const recipient = transaction.recipients[0];
501
+ recipient.should.have.property('address');
502
+ recipient.address.should.equal(destinationAddress);
503
+ recipient.should.have.property('amount');
504
+ recipient.amount.should.equal('9999999999999999928');
505
+ transaction.should.have.property('feesUsed');
506
+ transaction.feesUsed?.gasLimit.should.equal('500000');
507
+ transaction.should.have.property('halfSigned');
508
+ transaction.halfSigned?.should.have.property('txHex');
509
+ transaction.halfSigned?.should.have.property('recipients');
510
+ });
511
+ it('should generate an unsigned recovery txn of a token for cold wallet ', async function () {
512
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
513
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
514
+ const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
515
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
516
+ const tokenContractAddress = '0x326c977e6efc84e512bb9c30f76e30c160ed06fb';
517
+ const basecoin = bitgo.coin('tbaseeth');
518
+ (0, nock_1.default)(baseUrl)
519
+ .get('/api')
520
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
521
+ .reply(200, mockData.getTxListResponse);
522
+ (0, nock_1.default)(baseUrl)
523
+ .get('/api')
524
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
525
+ .reply(200, mockData.getBalanceResponse);
526
+ (0, nock_1.default)(baseUrl)
527
+ .get('/api')
528
+ .query(mockData.getTokenBalanceRequest(tokenContractAddress, walletContractAddress))
529
+ .reply(200, mockData.getBalanceResponse);
530
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
531
+ const transaction = (await basecoin.recover({
532
+ userKey: userXpub,
533
+ backupKey: '',
534
+ walletContractAddress: walletContractAddress,
535
+ bitgoFeeAddress: bitgoFeeAddress,
536
+ recoveryDestination: destinationAddress,
537
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
538
+ gasLimit: 500000,
539
+ bitgoDestinationAddress: bitgoDestinationAddress,
540
+ tokenContractAddress: tokenContractAddress,
541
+ common: resources_1.baseChainCommon,
542
+ }));
543
+ (0, assert_1.default)(transaction);
544
+ transaction.should.have.property('txHex');
545
+ transaction.should.have.property('userKey');
546
+ transaction.should.have.property('coin');
547
+ transaction.coin.should.equal('tbaseeth');
548
+ transaction.should.have.property('contractSequenceId');
549
+ transaction.should.have.property('expireTime');
550
+ transaction.should.have.property('gasLimit');
551
+ transaction.gasLimit.should.equal('500000');
552
+ transaction.should.have.property('isEvmBasedCrossChainRecovery');
553
+ transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
554
+ transaction.should.have.property('walletContractAddress');
555
+ transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
556
+ transaction.should.have.property('recipients');
557
+ const recipient = transaction.recipients[0];
558
+ recipient.should.have.property('address');
559
+ recipient.address.should.equal(destinationAddress);
560
+ recipient.should.have.property('amount');
561
+ recipient.amount.should.equal('9999999999999999928');
562
+ });
563
+ it('should generate an unsigned recovery txn of a token for custody wallet', async function () {
564
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
565
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
566
+ const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
567
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
568
+ const tokenContractAddress = '0x326c977e6efc84e512bb9c30f76e30c160ed06fb'; // unsupported token contract address
569
+ const basecoin = bitgo.coin('tbaseeth');
570
+ (0, nock_1.default)(baseUrl)
571
+ .get('/api')
572
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
573
+ .reply(200, mockData.getTxListResponse);
574
+ (0, nock_1.default)(baseUrl)
575
+ .get('/api')
576
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
577
+ .reply(200, mockData.getBalanceResponse);
578
+ (0, nock_1.default)(baseUrl)
579
+ .get('/api')
580
+ .query(mockData.getTokenBalanceRequest(tokenContractAddress, walletContractAddress))
581
+ .reply(200, mockData.getBalanceResponse);
582
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
583
+ const transaction = (await basecoin.recover({
584
+ userKey: '',
585
+ backupKey: '',
586
+ walletContractAddress: walletContractAddress,
587
+ bitgoFeeAddress: bitgoFeeAddress,
588
+ recoveryDestination: destinationAddress,
589
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
590
+ gasLimit: 500000,
591
+ bitgoDestinationAddress: bitgoDestinationAddress,
592
+ tokenContractAddress: tokenContractAddress,
593
+ common: resources_1.baseChainCommon,
594
+ }));
595
+ (0, assert_1.default)(transaction);
596
+ transaction.should.have.property('txHex');
597
+ transaction.should.have.property('coin');
598
+ transaction.coin.should.equal('tbaseeth');
599
+ transaction.should.have.property('contractSequenceId');
600
+ transaction.should.have.property('expireTime');
601
+ transaction.should.have.property('gasLimit');
602
+ transaction.gasLimit.should.equal('500000');
603
+ transaction.should.have.property('isEvmBasedCrossChainRecovery');
604
+ transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
605
+ transaction.should.have.property('walletContractAddress');
606
+ transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
607
+ transaction.should.have.property('recipients');
608
+ const recipient = transaction.recipients[0];
609
+ recipient.should.have.property('address');
610
+ recipient.address.should.equal(destinationAddress);
611
+ recipient.should.have.property('amount');
612
+ recipient.amount.should.equal('9999999999999999928');
613
+ });
614
+ it('should generate an unsigned recovery txn of a token for hot wallet', async function () {
615
+ const userKey = '{"iv":"VFZ3jvXhxo1Z+Yaf2MtZnA==","v":1,"iter":10000,"ks":256,"ts":64,"mode"\n' +
616
+ ':"ccm","adata":"","cipher":"aes","salt":"p+fkHuLa/8k=","ct":"hYG7pvljLIgCjZ\n' +
617
+ '53PBlCde5KZRmlUKKHLtDMk+HJfuU46hW+x+C9WsIAO4gFPnTCvFVmQ8x7czCtcNFub5AO2otOG\n' +
618
+ 'OsX4GE2gXOEmCl1TpWwwNhm7yMUjGJUpgW6ZZgXSXdDitSKi4V/hk78SGSzjFOBSPYRa6I="}\n';
619
+ const walletContractAddress = sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS;
620
+ const bitgoFeeAddress = '0x33a42faea3c6e87021347e51700b48aaf49aa1e7';
621
+ const destinationAddress = '0xd5adde17fed8baed3f32b84af05b8f2816f7b560';
622
+ const bitgoDestinationAddress = '0xE5986CE4490Deb67d2950562Ceb930Ddf9be7a14';
623
+ const walletPassphrase = sdk_test_1.TestBitGo.V2.TEST_RECOVERY_PASSCODE;
624
+ const tokenContractAddress = '0x326c977e6efc84e512bb9c30f76e30c160ed06fb'; // unsupported contract token address
625
+ const basecoin = bitgo.coin('tbaseeth');
626
+ (0, nock_1.default)(baseUrl)
627
+ .get('/api')
628
+ .query(mockData.getTxListRequest(bitgoFeeAddress))
629
+ .reply(200, mockData.getTxListResponse);
630
+ (0, nock_1.default)(baseUrl)
631
+ .get('/api')
632
+ .query(mockData.getBalanceRequest(bitgoFeeAddress))
633
+ .reply(200, mockData.getBalanceResponse);
634
+ (0, nock_1.default)(baseUrl)
635
+ .get('/api')
636
+ .query(mockData.getTokenBalanceRequest(tokenContractAddress, walletContractAddress))
637
+ .reply(200, mockData.getBalanceResponse);
638
+ (0, nock_1.default)(baseUrl).get('/api').query(mockData.getContractCallRequest).reply(200, mockData.getContractCallResponse);
639
+ const transaction = (await basecoin.recover({
640
+ userKey: userKey,
641
+ backupKey: '',
642
+ walletPassphrase: walletPassphrase,
643
+ walletContractAddress: walletContractAddress,
644
+ bitgoFeeAddress: bitgoFeeAddress,
645
+ recoveryDestination: destinationAddress,
646
+ eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
647
+ gasLimit: 500000,
648
+ bitgoDestinationAddress: bitgoDestinationAddress,
649
+ tokenContractAddress: tokenContractAddress,
650
+ common: resources_1.baseChainCommon,
651
+ }));
652
+ (0, assert_1.default)(transaction);
653
+ transaction.should.have.property('txHex');
654
+ transaction.should.have.property('coin');
655
+ transaction.coin.should.equal('tbaseeth');
656
+ transaction.should.have.property('contractSequenceId');
657
+ transaction.should.have.property('expireTime');
658
+ transaction.should.have.property('gasLimit');
659
+ transaction.gasLimit.should.equal('500000');
660
+ transaction.should.have.property('isEvmBasedCrossChainRecovery');
661
+ transaction.isEvmBasedCrossChainRecovery?.should.equal(true);
662
+ transaction.should.have.property('walletContractAddress');
663
+ transaction.walletContractAddress.should.equal(sdk_test_1.TestBitGo.V2.TEST_ETH_WALLET_FIRST_ADDRESS);
664
+ transaction.should.have.property('recipients');
665
+ const recipient = transaction.recipients[0];
666
+ recipient.should.have.property('address');
667
+ recipient.address.should.equal(destinationAddress);
668
+ recipient.should.have.property('amount');
669
+ recipient.amount.should.equal('9999999999999999928');
670
+ transaction.should.have.property('feesUsed');
671
+ transaction.feesUsed?.gasLimit.should.equal('500000');
672
+ transaction.should.have.property('halfSigned');
673
+ transaction.halfSigned?.should.have.property('txHex');
674
+ transaction.halfSigned?.should.have.property('recipients');
675
+ });
676
+ });
677
+ describe('Common parameter handling', function () {
678
+ it('should handle plain object common parameter for BASE chain', function () {
679
+ const baseCoin = bitgo.coin('baseeth');
680
+ const plainCommon = { chain: 8453, hardfork: 'london' };
681
+ const txBuilder = baseCoin.getTransactionBuilder(plainCommon);
682
+ txBuilder.should.be.an.instanceof(src_1.EthLikeTransactionBuilder);
683
+ });
684
+ it('should handle plain object common parameter with chainId property', function () {
685
+ const baseCoin = bitgo.coin('baseeth');
686
+ const plainCommon = { chainId: 8453, hardfork: 'london' };
687
+ const txBuilder = baseCoin.getTransactionBuilder(plainCommon);
688
+ txBuilder.should.be.an.instanceof(src_1.EthLikeTransactionBuilder);
689
+ });
690
+ it('should handle EthereumCommon instance', function () {
691
+ const baseCoin = bitgo.coin('baseeth');
692
+ const txBuilder = baseCoin.getTransactionBuilder(resources_1.baseChainCommon);
693
+ txBuilder.should.be.an.instanceof(src_1.EthLikeTransactionBuilder);
694
+ });
695
+ it('should require common parameter and throw error when undefined', function () {
696
+ const baseCoin = bitgo.coin('baseeth');
697
+ (() => {
698
+ baseCoin.getTransactionBuilder(undefined);
699
+ }).should.throw('Common must be provided for EthLikeTransactionBuilder');
700
+ });
701
+ it('should convert plain object common to EthereumCommon with working gteHardfork method', function () {
702
+ const baseCoin = bitgo.coin('baseeth');
703
+ const plainCommon = { chain: 8453, hardfork: 'london' };
704
+ const txBuilder = baseCoin.getTransactionBuilder(plainCommon);
705
+ txBuilder.should.be.an.instanceof(src_1.EthLikeTransactionBuilder);
706
+ const common = txBuilder._common;
707
+ common.should.not.be.undefined;
708
+ common.should.have.property('gteHardfork');
709
+ (typeof common.gteHardfork).should.equal('function');
710
+ const result = common.gteHardfork('homestead');
711
+ (typeof result).should.equal('boolean');
712
+ result.should.equal(true);
713
+ });
714
+ });
715
+ });
716
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXRobGlrZUNvaW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvZXRobGlrZUNvaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsaURBQStDO0FBQy9DLG1EQUE4RztBQUU5RyxtREFBK0Q7QUFDL0QscURBQThDO0FBQzlDLGdEQUF3QjtBQUV4QixtQ0FBaUY7QUFDakYsOENBQTJDO0FBQzNDLDRDQUEwRDtBQUMxRCxrRUFBb0Q7QUFFcEQsY0FBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7QUFFeEIsTUFBTSxLQUFLLEdBQUc7SUFDWjtRQUNFLElBQUksRUFBRSxPQUFPO1FBQ2IsTUFBTSxFQUFFLElBQUEscUJBQVMsRUFBQyxPQUFPLENBQUM7S0FDM0I7SUFDRDtRQUNFLElBQUksRUFBRSxTQUFTO1FBQ2YsTUFBTSxFQUFFLElBQUEscUJBQVMsRUFBQyxTQUFTLENBQUM7S0FDN0I7Q0FDRixDQUFDO0FBRUYsUUFBUSxDQUFDLG9CQUFvQixFQUFFO0lBQzdCLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLFFBQXNCLENBQUM7SUFDM0IsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1FBQ3JCLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ2xCLE1BQU0sQ0FBQztnQkFDTCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUM7Z0JBQ25CLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztnQkFDOUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGtCQUFZLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQzNELEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO2dCQUMzQixRQUFRLEdBQUcsS0FB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LCtCQUF5QixDQUFDLENBQUM7WUFFN0QsTUFBTSxNQUFNLEdBQUksU0FBaUIsQ0FBQyxPQUFPLENBQUM7WUFDMUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQztZQUUvQixNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDM0MsQ0FBQyxPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRXJELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDL0MsQ0FBQyxPQUFPLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgQml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstYXBpJztcbmltcG9ydCB7IGNvbW1vbiwgRnVsbHlTaWduZWRUcmFuc2FjdGlvbiwgSGFsZlNpZ25lZFRyYW5zYWN0aW9uLCBUcmFuc2FjdGlvblR5cGUgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBPZmZsaW5lVmF1bHRUeEluZm8sIFRyYW5zZmVyQnVpbGRlciB9IGZyb20gJ0BiaXRnby1iZXRhL2Fic3RyYWN0LWV0aCc7XG5pbXBvcnQgeyBUZXN0Qml0R28sIFRlc3RCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay10ZXN0JztcbmltcG9ydCB7IGJpcDMyIH0gZnJvbSAnQGJpdGdvLWJldGEvc2VjcDI1NmsxJztcbmltcG9ydCBub2NrIGZyb20gJ25vY2snO1xuXG5pbXBvcnQgeyBFdGhMaWtlQ29pbiwgVGV0aExpa2VDb2luLCBFdGhMaWtlVHJhbnNhY3Rpb25CdWlsZGVyIH0gZnJvbSAnLi4vLi4vc3JjJztcbmltcG9ydCB7IGdldEJ1aWxkZXIgfSBmcm9tICcuLi9nZXRCdWlsZGVyJztcbmltcG9ydCB7IGJhc2VDaGFpbkNvbW1vbiwgZ2V0Q29tbW9uIH0gZnJvbSAnLi4vcmVzb3VyY2VzJztcbmltcG9ydCAqIGFzIG1vY2tEYXRhIGZyb20gJy4uL2ZpeHR1cmVzL2V0aGxpa2VDb2luJztcblxubm9jay5lbmFibGVOZXRDb25uZWN0KCk7XG5cbmNvbnN0IGNvaW5zID0gW1xuICB7XG4gICAgbmFtZTogJ2h0ZXRoJyxcbiAgICBjb21tb246IGdldENvbW1vbignaHRldGgnKSxcbiAgfSxcbiAge1xuICAgIG5hbWU6ICd0YXJiZXRoJyxcbiAgICBjb21tb246IGdldENvbW1vbigndGFyYmV0aCcpLFxuICB9LFxuXTtcblxuZGVzY3JpYmUoJ0V0aExpa2UgY29pbiB0ZXN0cycsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gIGxldCBiYXNlY29pbjogVGV0aExpa2VDb2luO1xuICBjb2lucy5mb3JFYWNoKChjb2luKSA9PiB7XG4gICAgZGVzY3JpYmUoY29pbi5uYW1lLCBmdW5jdGlvbiAoKSB7XG4gICAgICBiZWZvcmUoZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBlbnYgPSAndGVzdCc7XG4gICAgICAgIGJpdGdvID0gVGVzdEJpdEdvLmRlY29yYXRlKEJpdEdvQVBJLCB7IGVudiB9KTtcbiAgICAgICAgYml0Z28uc2FmZVJlZ2lzdGVyKGNvaW4ubmFtZSwgVGV0aExpa2VDb2luLmNyZWF0ZUluc3RhbmNlKTtcbiAgICAgICAgYml0Z28uaW5pdGlhbGl6ZVRlc3RWYXJzKCk7XG4gICAgICAgIGJhc2Vjb2luID0gYml0Z28uY29pbihjb2luLm5hbWUpIGFzIFRldGhMaWtlQ29pbjtcbiAgICAgIH0pO1xuXG4gICAgICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGluc3RhbnRpYXRlIGEgY29pbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYmFzZWNvaW4uc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoVGV0aExpa2VDb2luKTtcbiAgICAgIH0pO1xuICAgICAgaXQoJ3Nob3VsZCByZWplY3QgZm9yIG1pc3NpbmcgZW5jcnlwdGVkUHJ2IGZvciBob3Qgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZWNvdmVyeUlkID0gJzB4MTIzNDU2Nzg5MGFiY2RlZic7XG4gICAgICAgIG5vY2soYml0Z28ubWljcm9zZXJ2aWNlc1VybChgL2FwaS9yZWNvdmVyeS92MS9jcm9zc2NoYWluYCkpLmdldChgLyR7cmVjb3ZlcnlJZH0vYnVpbGR0eGApLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHR4SGV4OiBtb2NrRGF0YS5jY3JbY29pbi5uYW1lXS50eEhleCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSBhcyBzdHJpbmc7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICByZWNvdmVyeUlkLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgY29tbW9uOiBjb2luLmNvbW1vbixcbiAgICAgICAgfTtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgICAuc2VuZENyb3NzQ2hhaW5SZWNvdmVyeVRyYW5zYWN0aW9uKHsgLi4ucGFyYW1zLCB3YWxsZXRUeXBlOiAnaG90JyB9KVxuICAgICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIGVuY3J5cHRlZFBydicpO1xuICAgICAgfSk7XG4gICAgICBpdCgnc2hvdWxkIHNlbmQgY3Jvc3MgY2hhaW4gcmVjb3ZlcnkgdHJhbnNhY3Rpb24gZm9yIGhvdCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IHJlY292ZXJ5SWQgPSAnMHgxMjM0NTY3ODkwYWJjZGVmJztcbiAgICAgICAgbm9jayhiaXRnby5taWNyb3NlcnZpY2VzVXJsKGAvYXBpL3JlY292ZXJ5L3YxL2Nyb3NzY2hhaW5gKSkuZ2V0KGAvJHtyZWNvdmVyeUlkfS9idWlsZHR4YCkucmVwbHkoMjAwLCB7XG4gICAgICAgICAgdHhIZXg6IG1vY2tEYXRhLmNjcltjb2luLm5hbWVdLnR4SGV4LFxuICAgICAgICB9KTtcbiAgICAgICAgbm9jayhiaXRnby5taWNyb3NlcnZpY2VzVXJsKGAvYXBpL3JlY292ZXJ5L3YxL2Nyb3NzY2hhaW5gKSkucG9zdChgLyR7cmVjb3ZlcnlJZH0vc2lnbmApLnJlcGx5KDIwMCwge1xuICAgICAgICAgIGNvaW46IGNvaW4ubmFtZSxcbiAgICAgICAgICB0eGlkOiBtb2NrRGF0YS5jY3JbY29pbi5uYW1lXS50eGlkLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9IFRlc3RCaXRHby5WMi5URVNUX1JFQ09WRVJZX1BBU1NDT0RFIGFzIHN0cmluZztcbiAgICAgICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgICAgIHJlY292ZXJ5SWQsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBlbmNyeXB0ZWRQcnY6IG1vY2tEYXRhLmVuY3J5cHRlZFVzZXJLZXksXG4gICAgICAgICAgY29tbW9uOiBjb2luLmNvbW1vbixcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4uc2VuZENyb3NzQ2hhaW5SZWNvdmVyeVRyYW5zYWN0aW9uKHsgLi4ucGFyYW1zLCB3YWxsZXRUeXBlOiAnaG90JyB9KTtcbiAgICAgICAgcmVzdWx0LmNvaW4uc2hvdWxkLmVxdWFsKGNvaW4ubmFtZSk7XG4gICAgICAgIHJlc3VsdC50eGlkLnNob3VsZC5lcXVhbChtb2NrRGF0YS5jY3JbY29pbi5uYW1lXS50eGlkKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGJ1aWxkIHR4biBmb3IgY3Jvc3MgY2hhaW4gcmVjb3ZlcnkgZm9yIGNvbGQgd2FsbGV0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZWNvdmVyeUlkID0gJzB4MTIzNDU2Nzg5MGFiY2RlZic7XG4gICAgICAgIG5vY2soYml0Z28ubWljcm9zZXJ2aWNlc1VybChgL2FwaS9yZWNvdmVyeS92MS9jcm9zc2NoYWluYCkpLmdldChgLyR7cmVjb3ZlcnlJZH0vYnVpbGR0eGApLnJlcGx5KDIwMCwge1xuICAgICAgICAgIHR4SGV4OiBtb2NrRGF0YS5jY3JbY29pbi5uYW1lXS50eEhleCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICByZWNvdmVyeUlkLFxuICAgICAgICAgIGNvbW1vbjogY29pbi5jb21tb24sXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJhc2Vjb2luLnNlbmRDcm9zc0NoYWluUmVjb3ZlcnlUcmFuc2FjdGlvbih7IC4uLnBhcmFtcywgd2FsbGV0VHlwZTogJ2NvbGQnIH0pO1xuICAgICAgICBhc3NlcnQocmVzdWx0LnR4SGV4KTtcbiAgICAgICAgcmVzdWx0LnR4SGV4LnNob3VsZC5lcXVhbChtb2NrRGF0YS5jY3JbY29pbi5uYW1lXS50eEhleCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBjcm9zcyBjaGFpbiByZWNvdmVyeSB0cmFuc2FjdGlvbiBhbmQgZXh0cmFjdCByZWNpcGllbnRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZWNvdmVyeUlkID0gJzB4MTIzNDU2Nzg5MGFiY2RlZic7XG4gICAgICAgIGNvbnN0IG1vY2tSZXNwb25zZSA9IHtcbiAgICAgICAgICBjb2luOiBjb2luLm5hbWUsXG4gICAgICAgICAgdHhIZXg6IG1vY2tEYXRhLmNjcltjb2luLm5hbWVdLnR4SGV4LFxuICAgICAgICAgIHR4aWQ6IG1vY2tEYXRhLmNjcltjb2luLm5hbWVdLnR4aWQsXG4gICAgICAgICAgd2FsbGV0VmVyc2lvbjogMSxcbiAgICAgICAgfTtcblxuICAgICAgICBub2NrKGJpdGdvLm1pY3Jvc2VydmljZXNVcmwoYC9hcGkvcmVjb3ZlcnkvdjEvY3Jvc3NjaGFpbmApKVxuICAgICAgICAgIC5nZXQoYC8ke3JlY292ZXJ5SWR9L2J1aWxkdHhgKVxuICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYmFzZWNvaW4uYnVpbGRDcm9zc0NoYWluUmVjb3ZlcnlUcmFuc2FjdGlvbihyZWNvdmVyeUlkKTtcblxuICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgICAgcmVzdWx0LmNvaW4uc2hvdWxkLmVxdWFsKGNvaW4ubmFtZSk7XG4gICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgICAgcmVzdWx0LnR4SGV4LnNob3VsZC5lcXVhbChtb2NrRGF0YS5jY3JbY29pbi5uYW1lXS50eEhleCk7XG4gICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhpZCcpO1xuICAgICAgICByZXN1bHQudHhpZC5zaG91bGQuZXF1YWwobW9ja0RhdGEuY2NyW2NvaW4ubmFtZV0udHhpZCk7XG4gICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0VmVyc2lvbicpO1xuICAgICAgICByZXN1bHQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICAgICAgcmVzdWx0LnJlY2lwaWVudHMuc2hvdWxkLmJlLmFuLkFycmF5KCk7XG4gICAgICAgIGNvbnN0IHJlY2lwaWVudCA9IHJlc3VsdC5yZWNpcGllbnRzWzBdO1xuICAgICAgICByZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkZHJlc3MnKTtcbiAgICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhbW91bnQnKTtcbiAgICAgICAgcmVjaXBpZW50LmFkZHJlc3Muc2hvdWxkLmJlLmEuU3RyaW5nKCk7XG4gICAgICAgIHJlY2lwaWVudC5hbW91bnQuc2hvdWxkLmJlLmEuU3RyaW5nKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBzaWduYXR1cmUgZGF0YSBmb3IgY3VzdG9kaWFsIGhvdCB3YWxsZXQgYW5kIHNpZ24gdXNpbmcgaHNtIHNpZ25hdHVyZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgYmFzZUFkZHJlc3MgPSAnMHg3MDJjZjgxZTAzYWEzMTBlYzk0ODFkODE0ZTNkMDRhMjBiMDRiNTA1JztcbiAgICAgICAgY29uc3QgZGVzdGluYXRpb25BZGRyZXNzID0gJzB4YjlmNjJjNzFkNWY2OTQ5Y2ZiMjExYTY3ZmIxM2NjZjA3OWNjNzYwYic7XG4gICAgICAgIGNvbnN0IHRva2VuQ29udHJhY3RBZGRyZXNzID0gJzB4ZTRhYjY5YzA3Nzg5NjI1MmZhZmJkNDllZmQyNmI1ZDE3MWEzMjQxMCc7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGdldEJ1aWxkZXIoY29pbi5uYW1lLCBjb2luLmNvbW1vbikgYXMgRXRoTGlrZVRyYW5zYWN0aW9uQnVpbGRlcjtcblxuICAgICAgICB0eEJ1aWxkZXIuY29udHJhY3QoYmFzZUFkZHJlc3MpO1xuICAgICAgICB0eEJ1aWxkZXIuY29udHJhY3RDb3VudGVyKDApO1xuICAgICAgICB0eEJ1aWxkZXIuZmVlKHtcbiAgICAgICAgICBmZWU6ICcxMDAwMDAnLFxuICAgICAgICAgIGdhc0xpbWl0OiAnMjEwMDAnLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIgPSB0eEJ1aWxkZXIudHJhbnNmZXIoKSBhcyBUcmFuc2ZlckJ1aWxkZXI7XG4gICAgICAgIHRyYW5zZmVyQnVpbGRlclxuICAgICAgICAgIC5jb2luKGNvaW4ubmFtZSlcbiAgICAgICAgICAuYW1vdW50KCcxMDAwMDAwMDAnKVxuICAgICAgICAgIC5jb250cmFjdFNlcXVlbmNlSWQoMTAwKVxuICAgICAgICAgIC5leHBpcmF0aW9uVGltZSgxNzQ0MDQ5NjMzKVxuICAgICAgICAgIC50byhkZXN0aW5hdGlvbkFkZHJlc3MpXG4gICAgICAgICAgLnRva2VuQ29udHJhY3RBZGRyZXNzKHRva2VuQ29udHJhY3RBZGRyZXNzKTtcbiAgICAgICAgY29uc3Qgc2lnbmF0dXJlRGF0YSA9IHRyYW5zZmVyQnVpbGRlci5nZXRTaWduYXR1cmVEYXRhKCk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaWduYXR1cmVEYXRhLnRvU3RyaW5nKCdoZXgnKSwgbW9ja0RhdGEuY3VzdG9kaWFsSG90W2NvaW4ubmFtZV0uc2lnbmF0dXJlRGF0YSk7XG5cbiAgICAgICAgLy8gU2V0IEhTTSBTaWduYXR1cmVcbiAgICAgICAgdHJhbnNmZXJCdWlsZGVyLnNldFNpZ25hdHVyZShtb2NrRGF0YS5jdXN0b2RpYWxIb3RbY29pbi5uYW1lXS5zaWduYXR1cmUpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICBjb25zdCB0eEhleCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eEhleCwgbW9ja0RhdGEuY3VzdG9kaWFsSG90W2NvaW4ubmFtZV0uc2lnbmVkVHhIZXgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG5kZXNjcmliZSgnRXRoTGlrZUNvaW4nLCBmdW5jdGlvbiAoKSB7XG4gIGxldCBiaXRnbzogVGVzdEJpdEdvQVBJO1xuICBjb25zdCBjb2luTmFtZSA9ICd0YmFzZWV0aCc7XG4gIGxldCBiYXNlY29pbjogVGV0aExpa2VDb2luO1xuXG4gIGJlZm9yZShmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgYml0Z29LZXlYcHJ2ID1cbiAgICAgICd4cHJ2OXMyMVpyUUgxNDNLM3RwV0JIV2UzMXNMb1hOUlE5QXZSWUpnaXRrS3hRNEFURlFNd3ZyN2hITnFZUlVuUzdQc2p6QjdhSzFWeHFITHVOUWpqMXNja0oySndvMnF4bXN2ZWp3RUNTcEZNZkMnO1xuICAgIGNvbnN0IGJpdGdvS2V5ID0gYmlwMzIuZnJvbUJhc2U1OChiaXRnb0tleVhwcnYpO1xuICAgIGlmICghYml0Z29LZXkucHJpdmF0ZUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBwcml2YXRlS2V5Jyk7XG4gICAgfVxuICAgIGNvbnN0IGJpdGdvWHB1YiA9IGJpdGdvS2V5Lm5ldXRlcmVkKCkudG9CYXNlNTgoKTtcbiAgICBjb25zdCBlbnYgPSAndGVzdCc7XG4gICAgYml0Z28gPSBUZXN0Qml0R28uZGVjb3JhdGUoQml0R29BUEksIHsgZW52IH0pO1xuICAgIGNvbW1vbi5FbnZpcm9ubWVudHNbZW52XS5oc21YcHViID0gYml0Z29YcHViO1xuICAgIGJpdGdvLnNhZmVSZWdpc3RlcignYmFzZWV0aCcsIEV0aExpa2VDb2luLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3RiYXNlZXRoJywgVGV0aExpa2VDb2luLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBiYXNlY29pbiA9IGJpdGdvLmNvaW4oJ3RiYXNlZXRoJykgYXMgVGV0aExpa2VDb2luO1xuICB9KTtcblxuICBhZnRlcihmdW5jdGlvbiAoKSB7XG4gICAgbm9jay5jbGVhbkFsbCgpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGluc3RhbnRpYXRlIGEgY29pbicsIGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgY29pbiA9IGJpdGdvLmNvaW4oJ3RiYXNlZXRoJyk7XG4gICAgY29pbi5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihUZXRoTGlrZUNvaW4pO1xuICAgIGNvaW4gPSBiaXRnby5jb2luKCdiYXNlZXRoJyk7XG4gICAgY29pbi5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihFdGhMaWtlQ29pbik7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYnVpbGQgdW5zaWduZWQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgZXhwaXJlVGltZSA9IE1hdGguZmxvb3IobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTtcbiAgICBjb25zdCB0eEJ1aWxkZXIgPSBnZXRCdWlsZGVyKGNvaW5OYW1lLCBiYXNlQ2hhaW5Db21tb24pIGFzIEV0aExpa2VUcmFuc2FjdGlvbkJ1aWxkZXI7XG4gICAgdHhCdWlsZGVyLnR5cGUoVHJhbnNhY3Rpb25UeXBlLlNlbmQpO1xuICAgIHR4QnVpbGRlci5mZWUoe1xuICAgICAgZmVlOiAnMTAwMDAwMDAwMCcsXG4gICAgICBnYXNMaW1pdDogJzEwMDAwMCcsXG4gICAgfSk7XG4gICAgdHhCdWlsZGVyLmNvdW50ZXIoMSk7XG4gICAgdHhCdWlsZGVyLmNvbnRyYWN0KCcweDJjMmI5YzlhNGEyNWUyNGIxNzRmMjYxMTRlODkyNmE5ZjIxMjhmZTQnKTtcblxuICAgIGNvbnN0IHRyYW5zZmVyQnVpbGRlciA9IHR4QnVpbGRlci50cmFuc2ZlcigpO1xuICAgIHRyYW5zZmVyQnVpbGRlclxuICAgICAgLmNvaW4oY29pbk5hbWUpXG4gICAgICAuZXhwaXJhdGlvblRpbWUoZXhwaXJlVGltZSlcbiAgICAgIC5hbW91bnQoJzEwMDAwMDAwMDAwMDAwMDAwMDAnKVxuICAgICAgLnRvKCcweDJjMmI5YzlhNGEyNWUyNGIxNzRmMjYxMTRlODkyNmE5ZjIxMjhmZTQnKVxuICAgICAgLmNvbnRyYWN0U2VxdWVuY2VJZCgxKTtcblxuICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgdHhKc29uLmdhc0xpbWl0LnNob3VsZC5lcXVhbCgnMTAwMDAwJyk7XG4gICAgdHhKc29uLmdhc1ByaWNlLnNob3VsZC5lcXVhbCgnMTAwMDAwMDAwMCcpO1xuICAgIHR4SnNvbi5jaGFpbklkLnNob3VsZC5lcXVhbCgnMHgxNGEzNCcpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHNpZ24gYSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBhY2NvdW50XzEgPSB7XG4gICAgICBhZGRyZXNzOiAnMHg4Q2U1OWMyZDE3MDI4NDRGOEVkRUQ0NTFBQTEwMzk2MWJDMzdCNGU4JyxcbiAgICAgIG93bmVyXzE6ICc0ZWUwODlhY2VhYmYzZGRiZjc0OGRiNzliMTA2NmMzM2I3ZDNlYTFhYjNlYjdlMzI1MTIxYmJhMmJmZjJmNWNhJyxcbiAgICAgIG93bmVyXzI6ICc1YzdlNGVmZmY3MzA0ZDRkZmZmNmQ1ZjE1OTE4NDRlYzZmMmFkZmE2YTQ3ZTlmZWNlNmEzYzFhNGQ3NTVmMWUzJyxcbiAgICAgIG93bmVyXzM6ICc0NDIxYWIyNWRkOTFlMWEzMTgwZDAzZDU3YzMyM2E3ODg2ZGNjMzEzZDNiM2E0YjQyNTZhNTc5MTU3MmJmNTk3JyxcbiAgICB9O1xuICAgIGNvbnN0IGV4cGlyZVRpbWUgPSBNYXRoLmZsb29yKG5ldyBEYXRlKCkuZ2V0VGltZSgpIC8gMTAwMCk7XG4gICAgY29uc3QgdHhCdWlsZGVyID0gZ2V0QnVpbGRlcihjb2luTmFtZSwgYmFzZUNoYWluQ29tbW9uKSBhcyBFdGhMaWtlVHJhbnNhY3Rpb25CdWlsZGVyO1xuICAgIHR4QnVpbGRlci50eXBlKFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcbiAgICB0eEJ1aWxkZXIuZmVlKHtcbiAgICAgIGZlZTogJzEwMDAwMDAwMDAnLFxuICAgICAgZ2FzTGltaXQ6ICcxMDAwMDAnLFxuICAgIH0pO1xuICAgIHR4QnVpbGRlci5jb3VudGVyKDEpO1xuICAgIHR4QnVpbGRlci5jb250cmFjdChhY2NvdW50XzEuYWRkcmVzcyk7XG5cbiAgICBjb25zdCB0cmFuc2ZlckJ1aWxkZXIgPSB0eEJ1aWxkZXIudHJhbnNmZXIoKTtcbiAgICB0cmFuc2ZlckJ1aWxkZXJcbiAgICAgIC5jb2luKGNvaW5OYW1lKVxuICAgICAgLmV4cGlyYXRpb25UaW1lKGV4cGlyZVRpbWUpXG4gICAgICAuYW1vdW50KCcxMDAwMDAwMDAwMDAwMDAwMDAwJylcbiAgICAgIC50bygnMHgyYzJiOWM5YTRhMjVlMjRiMTc0ZjI2MTE0ZTg5MjZhOWYyMTI4ZmU0JylcbiAgICAgIC5jb250cmFjdFNlcXVlbmNlSWQoMSk7XG5cbiAgICBjb25zdCB1bnNpZ25lZFR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgY29uc3QgdW5zaWduZWRUeEhleCA9IHVuc2lnbmVkVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICBjb25zdCBoYWxmU2lnbmVkVHggPSAoYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgdHhIZXg6IHVuc2lnbmVkVHhIZXgsXG4gICAgICB9LFxuICAgICAgcHJ2OiBhY2NvdW50XzEub3duZXJfMSxcbiAgICAgIGNvbW1vbjogYmFzZUNoYWluQ29tbW9uLFxuICAgIH0pKSBhcyBIYWxmU2lnbmVkVHJhbnNhY3Rpb247XG4gICAgdHJhbnNmZXJCdWlsZGVyLmtleShhY2NvdW50XzEub3duZXJfMSk7XG4gICAgY29uc3QgaGFsZlNpZ25lZFR4QnVpbGRlciA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIGNvbnN0IGhhbGZTaWduZWRUeEhleEJ1aWxkZXIgPSBoYWxmU2lnbmVkVHhCdWlsZGVyLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgaGFsZlNpZ25lZFR4SGV4QnVpbGRlci5zaG91bGQuZXF1YWwoaGFsZlNpZ25lZFR4LmhhbGZTaWduZWQudHhIZXgpO1xuXG4gICAgLy8gU2lnbiB3aXRoIHRoZSBzZWNvbmQga2V5XG5cbiAgICBjb25zdCBmdWxsU2lnbmVkVHhuID0gKGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgIGhhbGZTaWduZWQ6IHtcbiAgICAgICAgICB0eEhleDogaGFsZlNpZ25lZFR4SGV4QnVpbGRlcixcbiAgICAgICAgICBleHBpcmVUaW1lOiBleHBpcmVUaW1lLFxuICAgICAgICAgIGNvbnRyYWN0U2VxdWVuY2VJZDogMSxcbiAgICAgICAgICBzaWduYXR1cmU6ICcnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHBydjogYWNjb3VudF8xLm93bmVyXzIsXG4gICAgICBjb21tb246IGJhc2VDaGFpbkNvbW1vbixcbiAgICAgIGlzTGFzdFNpZ25hdHVyZTogdHJ1ZSxcbiAgICB9KSkgYXMgRnVsbHlTaWduZWRUcmFuc2FjdGlvbjtcblxuICAgIGFzc2VydChmdWxsU2lnbmVkVHhuLnR4SGV4KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2V4cGxhaW5UcmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB0eEhleCA9IG1vY2tEYXRhLmNjcltjb2luTmFtZV0udHhIZXg7XG4gICAgY29uc3QgZmVlSW5mbyA9IHtcbiAgICAgIGZlZTogJzEwMDAwMDAwMDAnLFxuICAgICAgZ2FzTGltaXQ6ICcxMDAwMDAnLFxuICAgIH07XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gdHJhbnNhY3Rpb24gd2hlbiBjb21tb24gaXMgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYW5hdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4LFxuICAgICAgICBmZWVJbmZvLFxuICAgICAgICBjb21tb246IGJhc2VDaGFpbkNvbW1vbixcbiAgICAgIH0pO1xuXG4gICAgICBleHBsYW5hdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaWQnKTtcbiAgICAgIGV4cGxhbmF0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdvdXRwdXRzJyk7XG4gICAgICBleHBsYW5hdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnb3V0cHV0QW1vdW50Jyk7XG4gICAgICBleHBsYW5hdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY2hhbmdlT3V0cHV0cycpO1xuICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NoYW5nZUFtb3VudCcpO1xuICAgICAgZXhwbGFuYXRpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZScpO1xuICAgICAgZXhwbGFuYXRpb24uZmVlLnNob3VsZC5lcXVhbChmZWVJbmZvKTtcbiAgICAgIGV4cGxhbmF0aW9uLm91dHB1dHMuc2hvdWxkLmJlLmFuLkFycmF5KCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gZXhwbGFpbiB0cmFuc2FjdGlvbiB3aGVuIGNvbW1vbiBpcyBub3QgcHJvdmlkZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAuZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eEhleCxcbiAgICAgICAgICBmZWVJbmZvLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnQ29tbW9uIG11c3QgYmUgcHJvdmlkZWQgZm9yIEV0aExpa2VUcmFuc2FjdGlvbkJ1aWxkZXInKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXJ5JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGJhc2VVcmwgPSAnaHR0cHM6Ly9hcGktc2Vwb2xpYS5iYXNlc2Nhbi5vcmcvJztcbiAgICBjb25zdCB1c2VyWHB1YiA9XG4gICAgICAneHB1YjY2MU15TXdBcVJiY0VlVGM4Nzg5TUs1UFVHRVlpUEc0RjRWMTduMlJkMkxvVEFUQTFYb0NuSlQ1RkFZQVNoUXhTeHRGanBvNU5IbWNXd1RwMkxpV0dCTXdwVWNBQTNIeXdoeGl2Z1lmcTdxJztcbiAgICBjb25zdCBiYWNrdXBYcHViID1cbiAgICAgICd4cHViNjYxTXlNd0FxUmJjRlpYMTV4cFpmNEVSQ0dIaVZTSm04cjVDNHloMXlYVjJHcmRaQ1VQWW80V1FyNnROOW9VeXdLWHNnU0hvN1Jpc2Y5cjIyR0g1am9WRDJoRUVFaHFuU0N2SzhxeTExd1cnO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiB1bnNpZ25lZCBzd2VlcCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldENvbnRyYWN0QWRkcmVzcyA9IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyBhcyBzdHJpbmc7XG4gICAgICBjb25zdCBiYWNrdXBLZXlBZGRyZXNzID0gJzB4NGYyYzQ4MzBjYzM3ZjI3ODVjNjQ2Zjg5ZGVkOGE5MTkyMTlmYTBlOSc7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAudHdpY2UoKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChiYWNrdXBLZXlBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0VHhMaXN0UmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KHdhbGxldENvbnRyYWN0QWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoYmFja3VwS2V5QWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG5cbiAgICAgIG5vY2soYmFzZVVybCkuZ2V0KCcvYXBpJykucXVlcnkobW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVxdWVzdCkucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXNwb25zZSk7XG5cbiAgICAgIGNvbnN0IGJhc2VDb2luID0gYml0Z28uY29pbigndGJhc2VldGgnKSBhcyBUZXRoTGlrZUNvaW47XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBiYXNlQ29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogdXNlclhwdWIsXG4gICAgICAgIGJhY2t1cEtleTogYmFja3VwWHB1YixcbiAgICAgICAgd2FsbGV0Q29udHJhY3RBZGRyZXNzOiB3YWxsZXRDb250cmFjdEFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IFRlc3RCaXRHby5WMi5URVNUX0VSQzIwX1RPS0VOX1JFQ0lQSUVOVCBhcyBzdHJpbmcsXG4gICAgICAgIGVpcDE1NTk6IHsgbWF4RmVlUGVyR2FzOiAyMDAwMDAwMDAwMCwgbWF4UHJpb3JpdHlGZWVQZXJHYXM6IDEwMDAwMDAwMDAwIH0sXG4gICAgICAgIGdhc0xpbWl0OiA1MDAwMDAsXG4gICAgICAgIGNvbW1vbjogYmFzZUNoYWluQ29tbW9uLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcbiAgICAgIGFzc2VydCh0cmFuc2FjdGlvbi50eEhleCk7XG4gICAgICBhc3NlcnQodHJhbnNhY3Rpb24uY29udHJhY3RTZXF1ZW5jZUlkKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cmFuc2FjdGlvbi5nYXNMaW1pdCwgJzUwMDAwMCcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRXZtIEJhc2VkIENyb3NzIENoYWluIFJlY292ZXJ5IHRyYW5zYWN0aW9uOicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBiYXNlVXJsID0gJ2h0dHBzOi8vYXBpLXNlcG9saWEuYmFzZXNjYW4ub3JnLyc7XG4gICAgY29uc3QgdXNlclhwdWIgPVxuICAgICAgJ3hwdWI2NjFNeU13QXFSYmNFZVRjODc4OU1LNVBVR0VZaVBHNEY0VjE3bjJSZDJMb1RBVEExWG9DbkpUNUZBWUFTaFF4U3h0RmpwbzVOSG1jV3dUcDJMaVdHQk13cFVjQUEzSHl3aHhpdmdZZnE3cSc7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIHJlY292ZXJ5IHR4biBmb3IgY29sZCB3YWxsZXQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRDb250cmFjdEFkZHJlc3MgPSBUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgYml0Z29GZWVBZGRyZXNzID0gJzB4MzNhNDJmYWVhM2M2ZTg3MDIxMzQ3ZTUxNzAwYjQ4YWFmNDlhYTFlNyc7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhkNWFkZGUxN2ZlZDhiYWVkM2YzMmI4NGFmMDViOGYyODE2ZjdiNTYwJztcbiAgICAgIGNvbnN0IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzID0gJzB4RTU5ODZDRTQ0OTBEZWI2N2QyOTUwNTYyQ2ViOTMwRGRmOWJlN2ExNCc7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJhc2VldGgnKSBhcyBUZXRoTGlrZUNvaW47XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdCh3YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHVzZXJYcHViLFxuICAgICAgICBiYWNrdXBLZXk6ICcnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBiaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBjb21tb246IGJhc2VDaGFpbkNvbW1vbixcbiAgICAgIH0pKSBhcyBPZmZsaW5lVmF1bHRUeEluZm87XG5cbiAgICAgIGFzc2VydCh0cmFuc2FjdGlvbik7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1c2VyS2V5Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29pbicpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvbnRyYWN0U2VxdWVuY2VJZCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2V4cGlyZVRpbWUnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdnYXNMaW1pdCcpO1xuICAgICAgdHJhbnNhY3Rpb24uZ2FzTGltaXQuc2hvdWxkLmVxdWFsKCc1MDAwMDAnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdpc0V2bUJhc2VkQ3Jvc3NDaGFpblJlY292ZXJ5Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5pc0V2bUJhc2VkQ3Jvc3NDaGFpblJlY292ZXJ5Py5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2FsbGV0Q29udHJhY3RBZGRyZXNzJyk7XG4gICAgICB0cmFuc2FjdGlvbi53YWxsZXRDb250cmFjdEFkZHJlc3Muc2hvdWxkLmVxdWFsKFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVjaXBpZW50cycpO1xuICAgICAgY29uc3QgcmVjaXBpZW50ID0gdHJhbnNhY3Rpb24ucmVjaXBpZW50c1swXTtcbiAgICAgIHJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYWRkcmVzcycpO1xuICAgICAgcmVjaXBpZW50LmFkZHJlc3Muc2hvdWxkLmVxdWFsKGRlc3RpbmF0aW9uQWRkcmVzcyk7XG4gICAgICByZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Ftb3VudCcpO1xuICAgICAgcmVjaXBpZW50LmFtb3VudC5zaG91bGQuZXF1YWwoJzk5OTk5OTk5OTk5OTk5OTk5MjgnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gdW5zaWduZWQgcmVjb3ZlcnkgdHhuIGZvciBjdXN0b2R5IHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldENvbnRyYWN0QWRkcmVzcyA9IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyBhcyBzdHJpbmc7XG4gICAgICBjb25zdCBiaXRnb0ZlZUFkZHJlc3MgPSAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JztcbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9ICcweGQ1YWRkZTE3ZmVkOGJhZWQzZjMyYjg0YWYwNWI4ZjI4MTZmN2I1NjAnO1xuICAgICAgY29uc3QgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhFNTk4NkNFNDQ5MERlYjY3ZDI5NTA1NjJDZWI5MzBEZGY5YmU3YTE0JztcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0YmFzZWV0aCcpIGFzIFRldGhMaWtlQ29pbjtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KGJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldEJhbGFuY2VSZXF1ZXN0KHdhbGxldENvbnRyYWN0QWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogJycsXG4gICAgICAgIGJhY2t1cEtleTogJycsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6IGJpdGdvRmVlQWRkcmVzcyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzczogYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIGNvbW1vbjogYmFzZUNoYWluQ29tbW9uLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcblxuICAgICAgYXNzZXJ0KHRyYW5zYWN0aW9uKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb250cmFjdFNlcXVlbmNlSWQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdleHBpcmVUaW1lJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZ2FzTGltaXQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmdhc0xpbWl0LnNob3VsZC5lcXVhbCgnNTAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeScpO1xuICAgICAgdHJhbnNhY3Rpb24uaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeT8uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvbnRyYWN0QWRkcmVzcycpO1xuICAgICAgdHJhbnNhY3Rpb24ud2FsbGV0Q29udHJhY3RBZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICAgIGNvbnN0IHJlY2lwaWVudCA9IHRyYW5zYWN0aW9uLnJlY2lwaWVudHNbMF07XG4gICAgICByZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkZHJlc3MnKTtcbiAgICAgIHJlY2lwaWVudC5hZGRyZXNzLnNob3VsZC5lcXVhbChkZXN0aW5hdGlvbkFkZHJlc3MpO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhbW91bnQnKTtcbiAgICAgIHJlY2lwaWVudC5hbW91bnQuc2hvdWxkLmVxdWFsKCc5OTk5OTk5OTk5OTk5OTk5OTI4Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIHJlY292ZXJ5IHR4biBmb3IgaG90IHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHVzZXJLZXkgPVxuICAgICAgICAne1wiaXZcIjpcIlZGWjNqdlhoeG8xWitZYWYyTXRabkE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCJcXG4nICtcbiAgICAgICAgJzpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcInArZmtIdUxhLzhrPVwiLFwiY3RcIjpcImhZRzdwdmxqTElnQ2paXFxuJyArXG4gICAgICAgICc1M1BCbENkZTVLWlJtbFVLS0hMdERNaytISmZ1VTQ2aFcreCtDOVdzSUFPNGdGUG5UQ3ZGVm1ROHg3Y3pDdGNORnViNUFPMm90T0dcXG4nICtcbiAgICAgICAgJ09zWDRHRTJnWE9FbUNsMVRwV3d3TmhtN3lNVWpHSlVwZ1c2WlpnWFNYZERpdFNLaTRWL2hrNzhTR1N6akZPQlNQWVJhNkk9XCJ9XFxuJztcbiAgICAgIGNvbnN0IHdhbGxldENvbnRyYWN0QWRkcmVzcyA9IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyBhcyBzdHJpbmc7XG4gICAgICBjb25zdCBiaXRnb0ZlZUFkZHJlc3MgPSAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JztcbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9ICcweGQ1YWRkZTE3ZmVkOGJhZWQzZjMyYjg0YWYwNWI4ZjI4MTZmN2I1NjAnO1xuICAgICAgY29uc3QgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhFNTk4NkNFNDQ5MERlYjY3ZDI5NTA1NjJDZWI5MzBEZGY5YmU3YTE0JztcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSBhcyBzdHJpbmc7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJhc2VldGgnKSBhcyBUZXRoTGlrZUNvaW47XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdCh3YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogJycsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6IGJpdGdvRmVlQWRkcmVzcyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzczogYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIGNvbW1vbjogYmFzZUNoYWluQ29tbW9uLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcblxuICAgICAgYXNzZXJ0KHRyYW5zYWN0aW9uKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb250cmFjdFNlcXVlbmNlSWQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdleHBpcmVUaW1lJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZ2FzTGltaXQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmdhc0xpbWl0LnNob3VsZC5lcXVhbCgnNTAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeScpO1xuICAgICAgdHJhbnNhY3Rpb24uaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeT8uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvbnRyYWN0QWRkcmVzcycpO1xuICAgICAgdHJhbnNhY3Rpb24ud2FsbGV0Q29udHJhY3RBZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICAgIGNvbnN0IHJlY2lwaWVudCA9IHRyYW5zYWN0aW9uLnJlY2lwaWVudHNbMF07XG4gICAgICByZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkZHJlc3MnKTtcbiAgICAgIHJlY2lwaWVudC5hZGRyZXNzLnNob3VsZC5lcXVhbChkZXN0aW5hdGlvbkFkZHJlc3MpO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhbW91bnQnKTtcbiAgICAgIHJlY2lwaWVudC5hbW91bnQuc2hvdWxkLmVxdWFsKCc5OTk5OTk5OTk5OTk5OTk5OTI4Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlc1VzZWQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmZlZXNVc2VkPy5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2hhbGZTaWduZWQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmhhbGZTaWduZWQ/LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgdHJhbnNhY3Rpb24uaGFsZlNpZ25lZD8uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYW4gdW5zaWduZWQgcmVjb3ZlcnkgdHhuIG9mIGEgdG9rZW4gZm9yIGNvbGQgd2FsbGV0ICcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldENvbnRyYWN0QWRkcmVzcyA9IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyBhcyBzdHJpbmc7XG4gICAgICBjb25zdCBiaXRnb0ZlZUFkZHJlc3MgPSAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JztcbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9ICcweGQ1YWRkZTE3ZmVkOGJhZWQzZjMyYjg0YWYwNWI4ZjI4MTZmN2I1NjAnO1xuICAgICAgY29uc3QgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhFNTk4NkNFNDQ5MERlYjY3ZDI5NTA1NjJDZWI5MzBEZGY5YmU3YTE0JztcbiAgICAgIGNvbnN0IHRva2VuQ29udHJhY3RBZGRyZXNzID0gJzB4MzI2Yzk3N2U2ZWZjODRlNTEyYmI5YzMwZjc2ZTMwYzE2MGVkMDZmYic7XG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJhc2VldGgnKSBhcyBUZXRoTGlrZUNvaW47XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUb2tlbkJhbGFuY2VSZXF1ZXN0KHRva2VuQ29udHJhY3RBZGRyZXNzLCB3YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHVzZXJYcHViLFxuICAgICAgICBiYWNrdXBLZXk6ICcnLFxuICAgICAgICB3YWxsZXRDb250cmFjdEFkZHJlc3M6IHdhbGxldENvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgYml0Z29GZWVBZGRyZXNzOiBiaXRnb0ZlZUFkZHJlc3MsXG4gICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgZWlwMTU1OTogeyBtYXhGZWVQZXJHYXM6IDIwMDAwMDAwMDAwLCBtYXhQcmlvcml0eUZlZVBlckdhczogMTAwMDAwMDAwMDAgfSxcbiAgICAgICAgZ2FzTGltaXQ6IDUwMDAwMCxcbiAgICAgICAgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3M6IGJpdGdvRGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICB0b2tlbkNvbnRyYWN0QWRkcmVzczogdG9rZW5Db250cmFjdEFkZHJlc3MsXG4gICAgICAgIGNvbW1vbjogYmFzZUNoYWluQ29tbW9uLFxuICAgICAgfSkpIGFzIE9mZmxpbmVWYXVsdFR4SW5mbztcblxuICAgICAgYXNzZXJ0KHRyYW5zYWN0aW9uKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eEhleCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3VzZXJLZXknKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb2luJyk7XG4gICAgICB0cmFuc2FjdGlvbi5jb2luLnNob3VsZC5lcXVhbCgndGJhc2VldGgnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb250cmFjdFNlcXVlbmNlSWQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdleHBpcmVUaW1lJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZ2FzTGltaXQnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmdhc0xpbWl0LnNob3VsZC5lcXVhbCgnNTAwMDAwJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeScpO1xuICAgICAgdHJhbnNhY3Rpb24uaXNFdm1CYXNlZENyb3NzQ2hhaW5SZWNvdmVyeT8uc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3dhbGxldENvbnRyYWN0QWRkcmVzcycpO1xuICAgICAgdHJhbnNhY3Rpb24ud2FsbGV0Q29udHJhY3RBZGRyZXNzLnNob3VsZC5lcXVhbChUZXN0Qml0R28uVjIuVEVTVF9FVEhfV0FMTEVUX0ZJUlNUX0FERFJFU1MpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3JlY2lwaWVudHMnKTtcbiAgICAgIGNvbnN0IHJlY2lwaWVudCA9IHRyYW5zYWN0aW9uLnJlY2lwaWVudHNbMF07XG4gICAgICByZWNpcGllbnQuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2FkZHJlc3MnKTtcbiAgICAgIHJlY2lwaWVudC5hZGRyZXNzLnNob3VsZC5lcXVhbChkZXN0aW5hdGlvbkFkZHJlc3MpO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhbW91bnQnKTtcbiAgICAgIHJlY2lwaWVudC5hbW91bnQuc2hvdWxkLmVxdWFsKCc5OTk5OTk5OTk5OTk5OTk5OTI4Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGFuIHVuc2lnbmVkIHJlY292ZXJ5IHR4biBvZiBhIHRva2VuIGZvciBjdXN0b2R5IHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldENvbnRyYWN0QWRkcmVzcyA9IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyBhcyBzdHJpbmc7XG4gICAgICBjb25zdCBiaXRnb0ZlZUFkZHJlc3MgPSAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JztcbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9ICcweGQ1YWRkZTE3ZmVkOGJhZWQzZjMyYjg0YWYwNWI4ZjI4MTZmN2I1NjAnO1xuICAgICAgY29uc3QgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhFNTk4NkNFNDQ5MERlYjY3ZDI5NTA1NjJDZWI5MzBEZGY5YmU3YTE0JztcbiAgICAgIGNvbnN0IHRva2VuQ29udHJhY3RBZGRyZXNzID0gJzB4MzI2Yzk3N2U2ZWZjODRlNTEyYmI5YzMwZjc2ZTMwYzE2MGVkMDZmYic7IC8vIHVuc3VwcG9ydGVkIHRva2VuIGNvbnRyYWN0IGFkZHJlc3NcblxuICAgICAgY29uc3QgYmFzZWNvaW4gPSBiaXRnby5jb2luKCd0YmFzZWV0aCcpIGFzIFRldGhMaWtlQ29pbjtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUeExpc3RSZXF1ZXN0KGJpdGdvRmVlQWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldFR4TGlzdFJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRCYWxhbmNlUmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpJylcbiAgICAgICAgLnF1ZXJ5KG1vY2tEYXRhLmdldFRva2VuQmFsYW5jZVJlcXVlc3QodG9rZW5Db250cmFjdEFkZHJlc3MsIHdhbGxldENvbnRyYWN0QWRkcmVzcykpXG4gICAgICAgIC5yZXBseSgyMDAsIG1vY2tEYXRhLmdldEJhbGFuY2VSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpLmdldCgnL2FwaScpLnF1ZXJ5KG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlcXVlc3QpLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0Q29udHJhY3RDYWxsUmVzcG9uc2UpO1xuXG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IChhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogJycsXG4gICAgICAgIGJhY2t1cEtleTogJycsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6IGJpdGdvRmVlQWRkcmVzcyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzczogYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiB0b2tlbkNvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgY29tbW9uOiBiYXNlQ2hhaW5Db21tb24sXG4gICAgICB9KSkgYXMgT2ZmbGluZVZhdWx0VHhJbmZvO1xuXG4gICAgICBhc3NlcnQodHJhbnNhY3Rpb24pO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4SGV4Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29pbicpO1xuICAgICAgdHJhbnNhY3Rpb24uY29pbi5zaG91bGQuZXF1YWwoJ3RiYXNlZXRoJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29udHJhY3RTZXF1ZW5jZUlkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZXhwaXJlVGltZScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3ZlcnknKTtcbiAgICAgIHRyYW5zYWN0aW9uLmlzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3Zlcnk/LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb250cmFjdEFkZHJlc3MnKTtcbiAgICAgIHRyYW5zYWN0aW9uLndhbGxldENvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnRzJyk7XG4gICAgICBjb25zdCByZWNpcGllbnQgPSB0cmFuc2FjdGlvbi5yZWNpcGllbnRzWzBdO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhZGRyZXNzJyk7XG4gICAgICByZWNpcGllbnQuYWRkcmVzcy5zaG91bGQuZXF1YWwoZGVzdGluYXRpb25BZGRyZXNzKTtcbiAgICAgIHJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYW1vdW50Jyk7XG4gICAgICByZWNpcGllbnQuYW1vdW50LnNob3VsZC5lcXVhbCgnOTk5OTk5OTk5OTk5OTk5OTkyOCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBhbiB1bnNpZ25lZCByZWNvdmVyeSB0eG4gb2YgYSB0b2tlbiBmb3IgaG90IHdhbGxldCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHVzZXJLZXkgPVxuICAgICAgICAne1wiaXZcIjpcIlZGWjNqdlhoeG8xWitZYWYyTXRabkE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjI1NixcInRzXCI6NjQsXCJtb2RlXCJcXG4nICtcbiAgICAgICAgJzpcImNjbVwiLFwiYWRhdGFcIjpcIlwiLFwiY2lwaGVyXCI6XCJhZXNcIixcInNhbHRcIjpcInArZmtIdUxhLzhrPVwiLFwiY3RcIjpcImhZRzdwdmxqTElnQ2paXFxuJyArXG4gICAgICAgICc1M1BCbENkZTVLWlJtbFVLS0hMdERNaytISmZ1VTQ2aFcreCtDOVdzSUFPNGdGUG5UQ3ZGVm1ROHg3Y3pDdGNORnViNUFPMm90T0dcXG4nICtcbiAgICAgICAgJ09zWDRHRTJnWE9FbUNsMVRwV3d3TmhtN3lNVWpHSlVwZ1c2WlpnWFNYZERpdFNLaTRWL2hrNzhTR1N6akZPQlNQWVJhNkk9XCJ9XFxuJztcbiAgICAgIGNvbnN0IHdhbGxldENvbnRyYWN0QWRkcmVzcyA9IFRlc3RCaXRHby5WMi5URVNUX0VUSF9XQUxMRVRfRklSU1RfQUREUkVTUyBhcyBzdHJpbmc7XG4gICAgICBjb25zdCBiaXRnb0ZlZUFkZHJlc3MgPSAnMHgzM2E0MmZhZWEzYzZlODcwMjEzNDdlNTE3MDBiNDhhYWY0OWFhMWU3JztcbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uQWRkcmVzcyA9ICcweGQ1YWRkZTE3ZmVkOGJhZWQzZjMyYjg0YWYwNWI4ZjI4MTZmN2I1NjAnO1xuICAgICAgY29uc3QgYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MgPSAnMHhFNTk4NkNFNDQ5MERlYjY3ZDI5NTA1NjJDZWI5MzBEZGY5YmU3YTE0JztcbiAgICAgIGNvbnN0IHdhbGxldFBhc3NwaHJhc2UgPSBUZXN0Qml0R28uVjIuVEVTVF9SRUNPVkVSWV9QQVNTQ09ERSBhcyBzdHJpbmc7XG4gICAgICBjb25zdCB0b2tlbkNvbnRyYWN0QWRkcmVzcyA9ICcweDMyNmM5NzdlNmVmYzg0ZTUxMmJiOWMzMGY3NmUzMGMxNjBlZDA2ZmInOyAvLyB1bnN1cHBvcnRlZCBjb250cmFjdCB0b2tlbiBhZGRyZXNzXG5cbiAgICAgIGNvbnN0IGJhc2Vjb2luID0gYml0Z28uY29pbigndGJhc2VldGgnKSBhcyBUZXRoTGlrZUNvaW47XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0VHhMaXN0UmVxdWVzdChiaXRnb0ZlZUFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRUeExpc3RSZXNwb25zZSk7XG4gICAgICBub2NrKGJhc2VVcmwpXG4gICAgICAgIC5nZXQoJy9hcGknKVxuICAgICAgICAucXVlcnkobW9ja0RhdGEuZ2V0QmFsYW5jZVJlcXVlc3QoYml0Z29GZWVBZGRyZXNzKSlcbiAgICAgICAgLnJlcGx5KDIwMCwgbW9ja0RhdGEuZ2V0QmFsYW5jZVJlc3BvbnNlKTtcbiAgICAgIG5vY2soYmFzZVVybClcbiAgICAgICAgLmdldCgnL2FwaScpXG4gICAgICAgIC5xdWVyeShtb2NrRGF0YS5nZXRUb2tlbkJhbGFuY2VSZXF1ZXN0KHRva2VuQ29udHJhY3RBZGRyZXNzLCB3YWxsZXRDb250cmFjdEFkZHJlc3MpKVxuICAgICAgICAucmVwbHkoMjAwLCBtb2NrRGF0YS5nZXRCYWxhbmNlUmVzcG9uc2UpO1xuICAgICAgbm9jayhiYXNlVXJsKS5nZXQoJy9hcGknKS5xdWVyeShtb2NrRGF0YS5nZXRDb250cmFjdENhbGxSZXF1ZXN0KS5yZXBseSgyMDAsIG1vY2tEYXRhLmdldENvbnRyYWN0Q2FsbFJlc3BvbnNlKTtcblxuICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSAoYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHVzZXJLZXksXG4gICAgICAgIGJhY2t1cEtleTogJycsXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgIHdhbGxldENvbnRyYWN0QWRkcmVzczogd2FsbGV0Q29udHJhY3RBZGRyZXNzLFxuICAgICAgICBiaXRnb0ZlZUFkZHJlc3M6IGJpdGdvRmVlQWRkcmVzcyxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBlaXAxNTU5OiB7IG1heEZlZVBlckdhczogMjAwMDAwMDAwMDAsIG1heFByaW9yaXR5RmVlUGVyR2FzOiAxMDAwMDAwMDAwMCB9LFxuICAgICAgICBnYXNMaW1pdDogNTAwMDAwLFxuICAgICAgICBiaXRnb0Rlc3RpbmF0aW9uQWRkcmVzczogYml0Z29EZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIHRva2VuQ29udHJhY3RBZGRyZXNzOiB0b2tlbkNvbnRyYWN0QWRkcmVzcyxcbiAgICAgICAgY29tbW9uOiBiYXNlQ2hhaW5Db21tb24sXG4gICAgICB9KSkgYXMgT2ZmbGluZVZhdWx0VHhJbmZvO1xuXG4gICAgICBhc3NlcnQodHJhbnNhY3Rpb24pO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4SGV4Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29pbicpO1xuICAgICAgdHJhbnNhY3Rpb24uY29pbi5zaG91bGQuZXF1YWwoJ3RiYXNlZXRoJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29udHJhY3RTZXF1ZW5jZUlkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZXhwaXJlVGltZScpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2dhc0xpbWl0Jyk7XG4gICAgICB0cmFuc2FjdGlvbi5nYXNMaW1pdC5zaG91bGQuZXF1YWwoJzUwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3ZlcnknKTtcbiAgICAgIHRyYW5zYWN0aW9uLmlzRXZtQmFzZWRDcm9zc0NoYWluUmVjb3Zlcnk/LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRDb250cmFjdEFkZHJlc3MnKTtcbiAgICAgIHRyYW5zYWN0aW9uLndhbGxldENvbnRyYWN0QWRkcmVzcy5zaG91bGQuZXF1YWwoVGVzdEJpdEdvLlYyLlRFU1RfRVRIX1dBTExFVF9GSVJTVF9BRERSRVNTKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnRzJyk7XG4gICAgICBjb25zdCByZWNpcGllbnQgPSB0cmFuc2FjdGlvbi5yZWNpcGllbnRzWzBdO1xuICAgICAgcmVjaXBpZW50LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhZGRyZXNzJyk7XG4gICAgICByZWNpcGllbnQuYWRkcmVzcy5zaG91bGQuZXF1YWwoZGVzdGluYXRpb25BZGRyZXNzKTtcbiAgICAgIHJlY2lwaWVudC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnYW1vdW50Jyk7XG4gICAgICByZWNpcGllbnQuYW1vdW50LnNob3VsZC5lcXVhbCgnOTk5OTk5OTk5OTk5OTk5OTkyOCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZXNVc2VkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5mZWVzVXNlZD8uZ2FzTGltaXQuc2hvdWxkLmVxdWFsKCc1MDAwMDAnKTtcbiAgICAgIHRyYW5zYWN0aW9uLnNob3VsZC5oYXZlLnByb3BlcnR5KCdoYWxmU2lnbmVkJyk7XG4gICAgICB0cmFuc2FjdGlvbi5oYWxmU2lnbmVkPy5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgIHRyYW5zYWN0aW9uLmhhbGZTaWduZWQ/LnNob3VsZC5oYXZlLnByb3BlcnR5KCdyZWNpcGllbnRzJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdDb21tb24gcGFyYW1ldGVyIGhhbmRsaW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgaGFuZGxlIHBsYWluIG9iamVjdCBjb21tb24gcGFyYW1ldGVyIGZvciBCQVNFIGNoYWluJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFzZUNvaW4gPSBiaXRnby5jb2luKCdiYXNlZXRoJykgYXMgRXRoTGlrZUNvaW47XG5cbiAgICAgIGNvbnN0IHBsYWluQ29tbW9uID0geyBjaGFpbjogODQ1MywgaGFyZGZvcms6ICdsb25kb24nIH07XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IChiYXNlQ29pbiBhcyBhbnkpLmdldFRyYW5zYWN0aW9uQnVpbGRlcihwbGFpbkNvbW1vbik7XG4gICAgICB0eEJ1aWxkZXIuc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoRXRoTGlrZVRyYW5zYWN0aW9uQnVpbGRlcik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBwbGFpbiBvYmplY3QgY29tbW9uIHBhcmFtZXRlciB3aXRoIGNoYWluSWQgcHJvcGVydHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYXNlQ29pbiA9IGJpdGdvLmNvaW4oJ2Jhc2VldGgnKSBhcyBFdGhMaWtlQ29pbjtcblxuICAgICAgY29uc3QgcGxhaW5Db21tb24gPSB7IGNoYWluSWQ6IDg0NTMsIGhhcmRmb3JrOiAnbG9uZG9uJyB9O1xuXG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSAoYmFzZUNvaW4gYXMgYW55KS5nZXRUcmFuc2FjdGlvbkJ1aWxkZXIocGxhaW5Db21tb24pO1xuICAgICAgdHhCdWlsZGVyLnNob3VsZC5iZS5hbi5pbnN0YW5jZW9mKEV0aExpa2VUcmFuc2FjdGlvbkJ1aWxkZXIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgRXRoZXJldW1Db21tb24gaW5zdGFuY2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYXNlQ29pbiA9IGJpdGdvLmNvaW4oJ2Jhc2VldGgnKSBhcyBFdGhMaWtlQ29pbjtcblxuICAgICAgY29uc3QgdHhCdWlsZGVyID0gKGJhc2VDb2luIGFzIGFueSkuZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKGJhc2VDaGFpbkNvbW1vbik7XG4gICAgICB0eEJ1aWxkZXIuc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoRXRoTGlrZVRyYW5zYWN0aW9uQnVpbGRlcik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlcXVpcmUgY29tbW9uIHBhcmFtZXRlciBhbmQgdGhyb3cgZXJyb3Igd2hlbiB1bmRlZmluZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBiYXNlQ29pbiA9IGJpdGdvLmNvaW4oJ2Jhc2VldGgnKSBhcyBFdGhMaWtlQ29pbjtcblxuICAgICAgKCgpID0+IHtcbiAgICAgICAgKGJhc2VDb2luIGFzIGFueSkuZ2V0VHJhbnNhY3Rpb25CdWlsZGVyKHVuZGVmaW5lZCk7XG4gICAgICB9KS5zaG91bGQudGhyb3coJ0NvbW1vbiBtdXN0IGJlIHByb3ZpZGVkIGZvciBFdGhMaWtlVHJhbnNhY3Rpb25CdWlsZGVyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvbnZlcnQgcGxhaW4gb2JqZWN0IGNvbW1vbiB0byBFdGhlcmV1bUNvbW1vbiB3aXRoIHdvcmtpbmcgZ3RlSGFyZGZvcmsgbWV0aG9kJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYmFzZUNvaW4gPSBiaXRnby5jb2luKCdiYXNlZXRoJykgYXMgRXRoTGlrZUNvaW47XG5cbiAgICAgIGNvbnN0IHBsYWluQ29tbW9uID0geyBjaGFpbjogODQ1MywgaGFyZGZvcms6ICdsb25kb24nIH07XG5cbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IChiYXNlQ29pbiBhcyBhbnkpLmdldFRyYW5zYWN0aW9uQnVpbGRlcihwbGFpbkNvbW1vbik7XG4gICAgICB0eEJ1aWxkZXIuc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoRXRoTGlrZVRyYW5zYWN0aW9uQnVpbGRlcik7XG5cbiAgICAgIGNvbnN0IGNvbW1vbiA9ICh0eEJ1aWxkZXIgYXMgYW55KS5fY29tbW9uO1xuICAgICAgY29tbW9uLnNob3VsZC5ub3QuYmUudW5kZWZpbmVkO1xuXG4gICAgICBjb21tb24uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2d0ZUhhcmRmb3JrJyk7XG4gICAgICAodHlwZW9mIGNvbW1vbi5ndGVIYXJkZm9yaykuc2hvdWxkLmVxdWFsKCdmdW5jdGlvbicpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBjb21tb24uZ3RlSGFyZGZvcmsoJ2hvbWVzdGVhZCcpO1xuICAgICAgKHR5cGVvZiByZXN1bHQpLnNob3VsZC5lcXVhbCgnYm9vbGVhbicpO1xuICAgICAgcmVzdWx0LnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==