@bitgo-beta/sdk-coin-atom 3.1.2-beta.185 → 3.1.2-beta.1850

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 (87) hide show
  1. package/dist/src/atom.d.ts +7 -115
  2. package/dist/src/atom.d.ts.map +1 -1
  3. package/dist/src/atom.js +12 -491
  4. package/dist/src/index.js +6 -2
  5. package/dist/src/lib/constants.d.ts +0 -6
  6. package/dist/src/lib/constants.d.ts.map +1 -1
  7. package/dist/src/lib/constants.js +10 -12
  8. package/dist/src/lib/index.d.ts +3 -8
  9. package/dist/src/lib/index.d.ts.map +1 -1
  10. package/dist/src/lib/index.js +33 -24
  11. package/dist/src/lib/keyPair.d.ts +3 -12
  12. package/dist/src/lib/keyPair.d.ts.map +1 -1
  13. package/dist/src/lib/keyPair.js +7 -44
  14. package/dist/src/lib/transactionBuilderFactory.d.ts +8 -11
  15. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  16. package/dist/src/lib/transactionBuilderFactory.js +21 -11
  17. package/dist/src/lib/utils.d.ts +5 -174
  18. package/dist/src/lib/utils.d.ts.map +1 -1
  19. package/dist/src/lib/utils.js +32 -532
  20. package/dist/src/tatom.d.ts +0 -8
  21. package/dist/src/tatom.d.ts.map +1 -1
  22. package/dist/src/tatom.js +1 -13
  23. package/dist/test/integration/index.d.ts +2 -0
  24. package/dist/test/integration/index.d.ts.map +1 -0
  25. package/dist/test/integration/index.js +54 -0
  26. package/dist/test/resources/atom.d.ts +291 -0
  27. package/dist/test/resources/atom.d.ts.map +1 -0
  28. package/dist/test/resources/atom.js +471 -0
  29. package/dist/test/unit/atom.d.ts +2 -0
  30. package/dist/test/unit/atom.d.ts.map +1 -0
  31. package/dist/test/unit/atom.js +552 -0
  32. package/dist/test/unit/getBuilderFactory.d.ts +3 -0
  33. package/dist/test/unit/getBuilderFactory.d.ts.map +1 -0
  34. package/dist/test/unit/getBuilderFactory.js +10 -0
  35. package/dist/test/unit/keyPair.d.ts +2 -0
  36. package/dist/test/unit/keyPair.d.ts.map +1 -0
  37. package/dist/test/unit/keyPair.js +93 -0
  38. package/dist/test/unit/transaction.d.ts +2 -0
  39. package/dist/test/unit/transaction.d.ts.map +1 -0
  40. package/dist/test/unit/transaction.js +220 -0
  41. package/dist/test/unit/transactionBuilder/StakingActivateBuilder.d.ts +2 -0
  42. package/dist/test/unit/transactionBuilder/StakingActivateBuilder.d.ts.map +1 -0
  43. package/dist/test/unit/transactionBuilder/StakingActivateBuilder.js +171 -0
  44. package/dist/test/unit/transactionBuilder/StakingDeactivateBuilder.d.ts +2 -0
  45. package/dist/test/unit/transactionBuilder/StakingDeactivateBuilder.d.ts.map +1 -0
  46. package/dist/test/unit/transactionBuilder/StakingDeactivateBuilder.js +140 -0
  47. package/dist/test/unit/transactionBuilder/StakingRedelegateBuilder.d.ts +2 -0
  48. package/dist/test/unit/transactionBuilder/StakingRedelegateBuilder.d.ts.map +1 -0
  49. package/dist/test/unit/transactionBuilder/StakingRedelegateBuilder.js +93 -0
  50. package/dist/test/unit/transactionBuilder/StakingWithdrawRewardsBuilder.d.ts +2 -0
  51. package/dist/test/unit/transactionBuilder/StakingWithdrawRewardsBuilder.d.ts.map +1 -0
  52. package/dist/test/unit/transactionBuilder/StakingWithdrawRewardsBuilder.js +141 -0
  53. package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts +2 -0
  54. package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts.map +1 -0
  55. package/dist/test/unit/transactionBuilder/transactionBuilder.js +100 -0
  56. package/dist/test/unit/transactionBuilder/transferBuilder.d.ts +2 -0
  57. package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
  58. package/dist/test/unit/transactionBuilder/transferBuilder.js +241 -0
  59. package/dist/test/unit/utils.d.ts +2 -0
  60. package/dist/test/unit/utils.d.ts.map +1 -0
  61. package/dist/test/unit/utils.js +85 -0
  62. package/dist/tsconfig.tsbuildinfo +1 -0
  63. package/package.json +15 -17
  64. package/.eslintignore +0 -5
  65. package/.mocharc.yml +0 -8
  66. package/CHANGELOG.md +0 -287
  67. package/dist/src/lib/StakingActivateBuilder.d.ts +0 -11
  68. package/dist/src/lib/StakingActivateBuilder.d.ts.map +0 -1
  69. package/dist/src/lib/StakingActivateBuilder.js +0 -31
  70. package/dist/src/lib/StakingDeactivateBuilder.d.ts +0 -11
  71. package/dist/src/lib/StakingDeactivateBuilder.d.ts.map +0 -1
  72. package/dist/src/lib/StakingDeactivateBuilder.js +0 -31
  73. package/dist/src/lib/StakingWithdrawRewardsBuilder.d.ts +0 -11
  74. package/dist/src/lib/StakingWithdrawRewardsBuilder.d.ts.map +0 -1
  75. package/dist/src/lib/StakingWithdrawRewardsBuilder.js +0 -31
  76. package/dist/src/lib/iface.d.ts +0 -46
  77. package/dist/src/lib/iface.d.ts.map +0 -1
  78. package/dist/src/lib/iface.js +0 -3
  79. package/dist/src/lib/transaction.d.ts +0 -58
  80. package/dist/src/lib/transaction.d.ts.map +0 -1
  81. package/dist/src/lib/transaction.js +0 -279
  82. package/dist/src/lib/transactionBuilder.d.ts +0 -78
  83. package/dist/src/lib/transactionBuilder.d.ts.map +0 -1
  84. package/dist/src/lib/transactionBuilder.js +0 -179
  85. package/dist/src/lib/transferBuilder.d.ts +0 -11
  86. package/dist/src/lib/transferBuilder.d.ts.map +0 -1
  87. package/dist/src/lib/transferBuilder.js +0 -31
@@ -0,0 +1,552 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const abstract_cosmos_1 = require("@bitgo-beta/abstract-cosmos");
7
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
8
+ const sdk_lib_mpc_1 = require("@bitgo-beta/sdk-lib-mpc");
9
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
10
+ const statics_1 = require("@bitgo-beta/statics");
11
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
12
+ const sinon_1 = __importDefault(require("sinon"));
13
+ const src_1 = require("../../src");
14
+ const constants_1 = require("../../src/lib/constants");
15
+ const utils_1 = __importDefault(require("../../src/lib/utils"));
16
+ const atom_1 = require("../resources/atom");
17
+ const should = require("should");
18
+ describe('ATOM', function () {
19
+ let bitgo;
20
+ let basecoin;
21
+ before(function () {
22
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
23
+ bitgo.safeRegister('atom', src_1.Atom.createInstance);
24
+ bitgo.safeRegister('tatom', src_1.Tatom.createInstance);
25
+ bitgo.initializeTestVars();
26
+ basecoin = bitgo.coin('tatom');
27
+ });
28
+ it('should retun the right info', function () {
29
+ const atom = bitgo.coin('atom');
30
+ const tatom = bitgo.coin('tatom');
31
+ atom.getChain().should.equal('atom');
32
+ atom.getFamily().should.equal('atom');
33
+ atom.getFullName().should.equal('Cosmos Hub ATOM');
34
+ atom.getBaseFactor().should.equal(1e6);
35
+ tatom.getChain().should.equal('tatom');
36
+ tatom.getFamily().should.equal('atom');
37
+ tatom.getFullName().should.equal('Testnet Cosmos Hub ATOM');
38
+ tatom.getBaseFactor().should.equal(1e6);
39
+ });
40
+ describe('Address Validation', () => {
41
+ it('should get address details without memoId', function () {
42
+ const addressDetails = basecoin.getAddressDetails(atom_1.address.noMemoIdAddress);
43
+ addressDetails.address.should.equal(atom_1.address.noMemoIdAddress);
44
+ should.not.exist(addressDetails.memoId);
45
+ });
46
+ it('should get address details with memoId', function () {
47
+ const addressDetails = basecoin.getAddressDetails(atom_1.address.validMemoIdAddress);
48
+ addressDetails.address.should.equal(atom_1.address.validMemoIdAddress.split('?')[0]);
49
+ addressDetails.memoId.should.equal('2');
50
+ });
51
+ it('should throw on multiple memo id address', () => {
52
+ (() => {
53
+ basecoin.getAddressDetails(atom_1.address.multipleMemoIdAddress);
54
+ }).should.throw();
55
+ });
56
+ it('should validate wallet receive address', async function () {
57
+ const receiveAddress = {
58
+ address: 'cosmos1r7k3xmlljsfdk6y9r8ssfnt4ks5ka0nwmm0z70?memoId=7',
59
+ coinSpecific: {
60
+ rootAddress: 'cosmos1r7k3xmlljsfdk6y9r8ssfnt4ks5ka0nwmm0z70',
61
+ memoID: '7',
62
+ },
63
+ };
64
+ const isValid = await basecoin.isWalletAddress(receiveAddress);
65
+ isValid.should.equal(true);
66
+ });
67
+ it('should validate account addresses correctly', () => {
68
+ should.equal(utils_1.default.isValidAddress(atom_1.address.address1), true);
69
+ should.equal(utils_1.default.isValidAddress(atom_1.address.address2), true);
70
+ should.equal(utils_1.default.isValidAddress(atom_1.address.address3), false);
71
+ should.equal(utils_1.default.isValidAddress(atom_1.address.address4), false);
72
+ should.equal(utils_1.default.isValidAddress('dfjk35y'), false);
73
+ should.equal(utils_1.default.isValidAddress(undefined), false);
74
+ should.equal(utils_1.default.isValidAddress(''), false);
75
+ should.equal(utils_1.default.isValidAddress(atom_1.address.validMemoIdAddress), true);
76
+ should.equal(utils_1.default.isValidAddress(atom_1.address.multipleMemoIdAddress), false);
77
+ });
78
+ it('should validate validator addresses correctly', () => {
79
+ should.equal(utils_1.default.isValidValidatorAddress(atom_1.address.validatorAddress1), true);
80
+ should.equal(utils_1.default.isValidValidatorAddress(atom_1.address.validatorAddress2), true);
81
+ should.equal(utils_1.default.isValidValidatorAddress(atom_1.address.validatorAddress3), false);
82
+ should.equal(utils_1.default.isValidValidatorAddress(atom_1.address.validatorAddress4), false);
83
+ should.equal(utils_1.default.isValidValidatorAddress('dfjk35y'), false);
84
+ should.equal(utils_1.default.isValidValidatorAddress(undefined), false);
85
+ should.equal(utils_1.default.isValidValidatorAddress(''), false);
86
+ });
87
+ });
88
+ describe('Verify transaction: ', () => {
89
+ it('should succeed to verify transaction', async function () {
90
+ const txPrebuild = {
91
+ txHex: atom_1.TEST_SEND_TX.signedTxBase64,
92
+ txInfo: {},
93
+ };
94
+ const txParams = {
95
+ recipients: [
96
+ {
97
+ address: atom_1.TEST_SEND_TX.recipient,
98
+ amount: atom_1.TEST_SEND_TX.sendAmount,
99
+ },
100
+ ],
101
+ };
102
+ const verification = {};
103
+ const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, verification });
104
+ isTransactionVerified.should.equal(true);
105
+ });
106
+ it('should succeed to verify sendMany transaction', async function () {
107
+ const txPrebuild = {
108
+ txHex: atom_1.TEST_SEND_MANY_TX.signedTxBase64,
109
+ txInfo: {},
110
+ };
111
+ const txParams = {
112
+ recipients: [
113
+ {
114
+ address: 'cosmos16ghn9c6f5yua09zqw7y794mvc30h4y4md7ckuk',
115
+ amount: '500',
116
+ },
117
+ {
118
+ address: 'cosmos1ytez06yx0u3yjzjjjm02xyx3mh25akenzql3n8',
119
+ amount: '500',
120
+ },
121
+ ],
122
+ };
123
+ const verification = {};
124
+ const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, verification });
125
+ isTransactionVerified.should.equal(true);
126
+ });
127
+ it('should succeed to verify delegate transaction', async function () {
128
+ const txPrebuild = {
129
+ txHex: atom_1.TEST_DELEGATE_TX.signedTxBase64,
130
+ txInfo: {},
131
+ };
132
+ const txParams = {
133
+ recipients: [
134
+ {
135
+ address: atom_1.TEST_DELEGATE_TX.validator,
136
+ amount: atom_1.TEST_DELEGATE_TX.sendAmount,
137
+ },
138
+ ],
139
+ };
140
+ const verification = {};
141
+ const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, verification });
142
+ isTransactionVerified.should.equal(true);
143
+ });
144
+ it('should succeed to verify undelegate transaction', async function () {
145
+ const txPrebuild = {
146
+ txHex: atom_1.TEST_UNDELEGATE_TX.signedTxBase64,
147
+ txInfo: {},
148
+ };
149
+ const txParams = {
150
+ recipients: [
151
+ {
152
+ address: atom_1.TEST_UNDELEGATE_TX.validator,
153
+ amount: atom_1.TEST_UNDELEGATE_TX.sendAmount,
154
+ },
155
+ ],
156
+ };
157
+ const verification = {};
158
+ const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, verification });
159
+ isTransactionVerified.should.equal(true);
160
+ });
161
+ it('should succeed to verify withdraw rewards transaction', async function () {
162
+ const txPrebuild = {
163
+ txHex: atom_1.TEST_WITHDRAW_REWARDS_TX.signedTxBase64,
164
+ txInfo: {},
165
+ };
166
+ const txParams = {
167
+ recipients: [
168
+ {
169
+ address: atom_1.TEST_WITHDRAW_REWARDS_TX.validator,
170
+ amount: 'UNAVAILABLE',
171
+ },
172
+ ],
173
+ };
174
+ const verification = {};
175
+ const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, verification });
176
+ isTransactionVerified.should.equal(true);
177
+ });
178
+ it('should fail to verify transaction with invalid param', async function () {
179
+ const txPrebuild = {};
180
+ const txParams = { recipients: undefined };
181
+ await basecoin
182
+ .verifyTransaction({
183
+ txParams,
184
+ txPrebuild,
185
+ })
186
+ .should.rejectedWith('missing required tx prebuild property txHex');
187
+ });
188
+ });
189
+ describe('Explain Transaction: ', () => {
190
+ it('should explain a transfer transaction', async function () {
191
+ const explainedTransaction = await basecoin.explainTransaction({
192
+ txHex: atom_1.TEST_SEND_TX.signedTxBase64,
193
+ });
194
+ explainedTransaction.should.deepEqual({
195
+ displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'type'],
196
+ id: atom_1.TEST_SEND_TX.hash,
197
+ outputs: [
198
+ {
199
+ address: atom_1.TEST_SEND_TX.recipient,
200
+ amount: atom_1.TEST_SEND_TX.sendAmount,
201
+ },
202
+ ],
203
+ outputAmount: atom_1.TEST_SEND_TX.sendAmount,
204
+ changeOutputs: [],
205
+ changeAmount: '0',
206
+ fee: { fee: atom_1.TEST_SEND_TX.gasBudget.amount[0].amount },
207
+ type: 0,
208
+ });
209
+ });
210
+ it('should explain sendMany transfer transaction', async function () {
211
+ const explainedTransaction = await basecoin.explainTransaction({
212
+ txHex: atom_1.TEST_SEND_MANY_TX.signedTxBase64,
213
+ });
214
+ explainedTransaction.should.deepEqual({
215
+ displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'type'],
216
+ id: atom_1.TEST_SEND_MANY_TX.hash,
217
+ outputs: [
218
+ {
219
+ address: 'cosmos16ghn9c6f5yua09zqw7y794mvc30h4y4md7ckuk',
220
+ amount: '500',
221
+ },
222
+ {
223
+ address: 'cosmos1ytez06yx0u3yjzjjjm02xyx3mh25akenzql3n8',
224
+ amount: '500',
225
+ },
226
+ ],
227
+ outputAmount: '1000',
228
+ changeOutputs: [],
229
+ changeAmount: '0',
230
+ fee: { fee: atom_1.TEST_SEND_MANY_TX.gasBudget.amount[0].amount },
231
+ type: 0,
232
+ });
233
+ });
234
+ it('should explain a delegate transaction', async function () {
235
+ const explainedTransaction = await basecoin.explainTransaction({
236
+ txHex: atom_1.TEST_DELEGATE_TX.signedTxBase64,
237
+ });
238
+ explainedTransaction.should.deepEqual({
239
+ displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'type'],
240
+ id: atom_1.TEST_DELEGATE_TX.hash,
241
+ outputs: [
242
+ {
243
+ address: atom_1.TEST_DELEGATE_TX.validator,
244
+ amount: atom_1.TEST_DELEGATE_TX.sendAmount,
245
+ },
246
+ ],
247
+ outputAmount: atom_1.TEST_DELEGATE_TX.sendAmount,
248
+ changeOutputs: [],
249
+ changeAmount: '0',
250
+ fee: { fee: atom_1.TEST_DELEGATE_TX.gasBudget.amount[0].amount },
251
+ type: 13,
252
+ });
253
+ });
254
+ it('should explain a undelegate transaction', async function () {
255
+ const explainedTransaction = await basecoin.explainTransaction({
256
+ txHex: atom_1.TEST_UNDELEGATE_TX.signedTxBase64,
257
+ });
258
+ explainedTransaction.should.deepEqual({
259
+ displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'type'],
260
+ id: atom_1.TEST_UNDELEGATE_TX.hash,
261
+ outputs: [
262
+ {
263
+ address: atom_1.TEST_UNDELEGATE_TX.validator,
264
+ amount: atom_1.TEST_UNDELEGATE_TX.sendAmount,
265
+ },
266
+ ],
267
+ outputAmount: atom_1.TEST_UNDELEGATE_TX.sendAmount,
268
+ changeOutputs: [],
269
+ changeAmount: '0',
270
+ fee: { fee: atom_1.TEST_UNDELEGATE_TX.gasBudget.amount[0].amount },
271
+ type: 17,
272
+ });
273
+ });
274
+ it('should explain a withdraw transaction', async function () {
275
+ const explainedTransaction = await basecoin.explainTransaction({
276
+ txHex: atom_1.TEST_WITHDRAW_REWARDS_TX.signedTxBase64,
277
+ });
278
+ explainedTransaction.should.deepEqual({
279
+ displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'type'],
280
+ id: atom_1.TEST_WITHDRAW_REWARDS_TX.hash,
281
+ outputs: [
282
+ {
283
+ address: atom_1.TEST_WITHDRAW_REWARDS_TX.validator,
284
+ amount: 'UNAVAILABLE',
285
+ },
286
+ ],
287
+ outputAmount: undefined,
288
+ changeOutputs: [],
289
+ changeAmount: '0',
290
+ fee: { fee: atom_1.TEST_WITHDRAW_REWARDS_TX.gasBudget.amount[0].amount },
291
+ type: 15,
292
+ });
293
+ });
294
+ it('should explain a transfer transaction with memo', async function () {
295
+ const explainedTransaction = await basecoin.explainTransaction({
296
+ txHex: atom_1.TEST_TX_WITH_MEMO.signedTxBase64,
297
+ });
298
+ explainedTransaction.should.deepEqual({
299
+ displayOrder: ['id', 'outputs', 'outputAmount', 'changeOutputs', 'changeAmount', 'fee', 'type'],
300
+ id: atom_1.TEST_TX_WITH_MEMO.hash,
301
+ outputs: [
302
+ {
303
+ address: atom_1.TEST_TX_WITH_MEMO.to,
304
+ amount: atom_1.TEST_TX_WITH_MEMO.sendAmount,
305
+ memo: atom_1.TEST_TX_WITH_MEMO.memo,
306
+ },
307
+ ],
308
+ outputAmount: atom_1.TEST_TX_WITH_MEMO.sendAmount,
309
+ changeOutputs: [],
310
+ changeAmount: '0',
311
+ fee: { fee: atom_1.TEST_TX_WITH_MEMO.gasBudget.amount[0].amount },
312
+ type: 0,
313
+ });
314
+ });
315
+ it('should fail to explain transaction with missing params', async function () {
316
+ try {
317
+ await basecoin.explainTransaction({});
318
+ }
319
+ catch (error) {
320
+ should.equal(error.message, 'missing required txHex parameter');
321
+ }
322
+ });
323
+ it('should fail to explain transaction with invalid params', async function () {
324
+ try {
325
+ await basecoin.explainTransaction({ txHex: 'randomString' });
326
+ }
327
+ catch (error) {
328
+ should.equal(error.message.startsWith('Invalid transaction:'), true);
329
+ }
330
+ });
331
+ });
332
+ describe('Parse Transactions: ', () => {
333
+ const transferInputsResponse = {
334
+ address: atom_1.TEST_SEND_TX.recipient,
335
+ amount: new bignumber_js_1.default(atom_1.TEST_SEND_TX.sendAmount).plus(atom_1.TEST_SEND_TX.gasBudget.amount[0].amount).toFixed(),
336
+ };
337
+ const transferOutputsResponse = {
338
+ address: atom_1.TEST_SEND_TX.recipient,
339
+ amount: atom_1.TEST_SEND_TX.sendAmount,
340
+ };
341
+ it('should parse a transfer transaction', async function () {
342
+ const parsedTransaction = await basecoin.parseTransaction({ txHex: atom_1.TEST_SEND_TX.signedTxBase64 });
343
+ parsedTransaction.should.deepEqual({
344
+ inputs: [transferInputsResponse],
345
+ outputs: [transferOutputsResponse],
346
+ });
347
+ });
348
+ it('should fail to parse a transfer transaction when explainTransaction response is undefined', async function () {
349
+ const stub = sinon_1.default.stub(src_1.Atom.prototype, 'explainTransaction');
350
+ stub.resolves(undefined);
351
+ await basecoin
352
+ .parseTransaction({ txHex: atom_1.TEST_SEND_TX.signedTxBase64 })
353
+ .should.be.rejectedWith('Invalid transaction');
354
+ stub.restore();
355
+ });
356
+ });
357
+ describe('Recover transactions: success path', () => {
358
+ const sandBox = sinon_1.default.createSandbox();
359
+ const destinationAddress = atom_1.wrwUser.destinationAddress;
360
+ const coin = statics_1.coins.get('tatom');
361
+ const testBalance = [
362
+ {
363
+ denom: 'uatom',
364
+ amount: '150000',
365
+ },
366
+ ];
367
+ const testAccountNumber = '725163';
368
+ const testSequenceNumber = '8';
369
+ const testBalanceDkls = [
370
+ {
371
+ denom: 'uatom',
372
+ amount: '150000',
373
+ },
374
+ ];
375
+ const testAccountNumberDkls = '755440';
376
+ const testSequenceNumberDkls = '2';
377
+ const testChainId = 'theta-testnet-001';
378
+ beforeEach(() => {
379
+ const accountBalance = sandBox.stub(src_1.Atom.prototype, 'getAccountBalance');
380
+ accountBalance.withArgs(atom_1.wrwUser.senderAddress).resolves(testBalance);
381
+ accountBalance.withArgs(atom_1.wrwUserDkls.senderAddress).resolves(testBalanceDkls);
382
+ const accountDetails = sandBox.stub(src_1.Atom.prototype, 'getAccountDetails');
383
+ accountDetails.withArgs(atom_1.wrwUser.senderAddress).resolves([testAccountNumber, testSequenceNumber]);
384
+ accountDetails.withArgs(atom_1.wrwUserDkls.senderAddress).resolves([testAccountNumberDkls, testSequenceNumberDkls]);
385
+ const chainId = sandBox.stub(src_1.Atom.prototype, 'getChainId');
386
+ chainId.withArgs().resolves(testChainId);
387
+ const deserializedEntChallenge = sdk_lib_mpc_1.EcdsaTypes.deserializeNtildeWithProofs(sdk_test_1.mockSerializedChallengeWithProofs);
388
+ sinon_1.default.stub(sdk_lib_mpc_1.EcdsaRangeProof, 'generateNtilde').resolves(deserializedEntChallenge);
389
+ });
390
+ afterEach(function () {
391
+ sandBox.restore();
392
+ sinon_1.default.restore();
393
+ });
394
+ it('should recover funds for non-bitgo recoveries', async function () {
395
+ const res = await basecoin.recover({
396
+ userKey: atom_1.wrwUser.userKey,
397
+ backupKey: atom_1.wrwUser.backupKey,
398
+ bitgoKey: atom_1.wrwUser.bitgoKey,
399
+ walletPassphrase: atom_1.wrwUser.walletPassphrase,
400
+ recoveryDestination: destinationAddress,
401
+ });
402
+ res.should.not.be.empty();
403
+ res.should.hasOwnProperty('serializedTx');
404
+ sandBox.assert.calledOnce(basecoin.getAccountBalance);
405
+ sandBox.assert.calledOnce(basecoin.getAccountDetails);
406
+ sandBox.assert.calledOnce(basecoin.getChainId);
407
+ const atomTxn = new abstract_cosmos_1.CosmosTransaction(coin, utils_1.default);
408
+ atomTxn.enrichTransactionDetailsFromRawTransaction(res.serializedTx);
409
+ const atomTxnJson = atomTxn.toJson();
410
+ const sendMessage = atomTxnJson.sendMessages[0].value;
411
+ const balance = new bignumber_js_1.default(testBalance[0].amount);
412
+ const gasAmount = new bignumber_js_1.default(constants_1.GAS_AMOUNT);
413
+ const actualBalance = balance.minus(gasAmount);
414
+ should.equal(sendMessage.amount[0].amount, actualBalance.toFixed());
415
+ should.equal(sendMessage.amount[0].denom, testBalance[0].denom);
416
+ });
417
+ it('should recover funds for non-bitgo recoveries - DKLS type', async function () {
418
+ const res = await basecoin.recover({
419
+ userKey: atom_1.wrwUserDkls.userKey,
420
+ backupKey: atom_1.wrwUserDkls.backupKey,
421
+ bitgoKey: atom_1.wrwUserDkls.bitgoKey,
422
+ walletPassphrase: atom_1.wrwUserDkls.walletPassphrase,
423
+ recoveryDestination: atom_1.wrwUserDkls.destinationAddress,
424
+ });
425
+ res.should.not.be.empty();
426
+ res.should.hasOwnProperty('serializedTx');
427
+ sandBox.assert.calledOnce(basecoin.getAccountBalance);
428
+ sandBox.assert.calledOnce(basecoin.getAccountDetails);
429
+ sandBox.assert.calledOnce(basecoin.getChainId);
430
+ const atomTxn = new abstract_cosmos_1.CosmosTransaction(coin, utils_1.default);
431
+ atomTxn.enrichTransactionDetailsFromRawTransaction(res.serializedTx);
432
+ const atomTxnJson = atomTxn.toJson();
433
+ const sendMessage = atomTxnJson.sendMessages[0].value;
434
+ const balance = new bignumber_js_1.default(testBalanceDkls[0].amount);
435
+ const gasAmount = new bignumber_js_1.default(constants_1.GAS_AMOUNT);
436
+ const actualBalance = balance.minus(gasAmount);
437
+ should.equal(sendMessage.amount[0].amount, actualBalance.toFixed());
438
+ });
439
+ it('should recover funds for Unsigned Sweep Transaction', async function () {
440
+ const res = await basecoin.recover({
441
+ userKey: atom_1.wrwUser.userKey,
442
+ backupKey: atom_1.wrwUser.backupKey,
443
+ bitgoKey: atom_1.wrwUser.bitgoKey,
444
+ walletPassphrase: atom_1.wrwUser.walletPassphrase,
445
+ recoveryDestination: destinationAddress,
446
+ });
447
+ res.should.not.be.empty();
448
+ res.should.hasOwnProperty('serializedTx');
449
+ sandBox.assert.calledOnce(basecoin.getAccountBalance);
450
+ sandBox.assert.calledOnce(basecoin.getAccountDetails);
451
+ sandBox.assert.calledOnce(basecoin.getChainId);
452
+ const unsignedSweepTxnDeserialize = new abstract_cosmos_1.CosmosTransaction(coin, utils_1.default);
453
+ unsignedSweepTxnDeserialize.enrichTransactionDetailsFromRawTransaction(res.serializedTx);
454
+ const unsignedSweepTxnJson = unsignedSweepTxnDeserialize.toJson();
455
+ const sendMessage = unsignedSweepTxnJson.sendMessages[0].value;
456
+ const balance = new bignumber_js_1.default(testBalance[0].amount);
457
+ const gasAmount = new bignumber_js_1.default(constants_1.GAS_AMOUNT);
458
+ const actualBalance = balance.minus(gasAmount);
459
+ should.equal(sendMessage.amount[0].amount, actualBalance.toFixed());
460
+ });
461
+ it('should redelegate funds to new validator', async function () {
462
+ const res = await basecoin.redelegate({
463
+ userKey: atom_1.wrwUser.userKey,
464
+ backupKey: atom_1.wrwUser.backupKey,
465
+ bitgoKey: atom_1.wrwUser.bitgoKey,
466
+ walletPassphrase: atom_1.wrwUser.walletPassphrase,
467
+ amountToRedelegate: '10000000000000000',
468
+ validatorSrcAddress: 'cosmosvaloper1409te27da74uahh6hn0040x7l272hjs2padjuz',
469
+ validatorDstAddress: 'cosmosvaloper183aycgtstp67r6s4vd7ts2npp2ckk4xah7rxj6',
470
+ });
471
+ res.should.not.be.empty();
472
+ res.should.hasOwnProperty('serializedTx');
473
+ sandBox.assert.calledOnce(basecoin.getChainId);
474
+ const txn = new abstract_cosmos_1.CosmosTransaction(coin, utils_1.default);
475
+ txn.enrichTransactionDetailsFromRawTransaction(res.serializedTx);
476
+ const txnJson = txn.toJson();
477
+ const redelegateMessage = txnJson.sendMessages[0].value;
478
+ should.equal(redelegateMessage.validatorSrcAddress, 'cosmosvaloper1409te27da74uahh6hn0040x7l272hjs2padjuz');
479
+ should.equal(redelegateMessage.validatorDstAddress, 'cosmosvaloper183aycgtstp67r6s4vd7ts2npp2ckk4xah7rxj6');
480
+ should.equal(redelegateMessage.amount.amount, '10000000000000000');
481
+ });
482
+ });
483
+ describe('Recover transactions: failure path', () => {
484
+ const sandBox = sinon_1.default.createSandbox();
485
+ const destinationAddress = atom_1.wrwUser.destinationAddress;
486
+ const testZeroBalance = [
487
+ {
488
+ denom: 'uatom',
489
+ amount: '0',
490
+ },
491
+ ];
492
+ const testAccountNumber = '1234';
493
+ const testSequenceNumber = '0';
494
+ const testChainId = 'test-chain';
495
+ beforeEach(() => {
496
+ const accountBalance = sandBox.stub(src_1.Atom.prototype, 'getAccountBalance');
497
+ accountBalance.withArgs(atom_1.wrwUser.senderAddress).resolves(testZeroBalance);
498
+ const accountNumber = sandBox.stub(src_1.Atom.prototype, 'getAccountDetails');
499
+ accountNumber.withArgs(atom_1.wrwUser.senderAddress).resolves([testAccountNumber, testSequenceNumber]);
500
+ const chainId = sandBox.stub(src_1.Atom.prototype, 'getChainId');
501
+ chainId.withArgs().resolves(testChainId);
502
+ const deserializedEntChallenge = sdk_lib_mpc_1.EcdsaTypes.deserializeNtildeWithProofs(sdk_test_1.mockSerializedChallengeWithProofs);
503
+ sinon_1.default.stub(sdk_lib_mpc_1.EcdsaRangeProof, 'generateNtilde').resolves(deserializedEntChallenge);
504
+ });
505
+ afterEach(function () {
506
+ sandBox.restore();
507
+ sinon_1.default.restore();
508
+ });
509
+ it('should throw error if backupkey is not present', async function () {
510
+ await basecoin
511
+ .recover({
512
+ userKey: atom_1.wrwUser.userKey,
513
+ bitgoKey: atom_1.wrwUser.bitgoKey,
514
+ walletPassphrase: atom_1.wrwUser.walletPassphrase,
515
+ recoveryDestination: destinationAddress,
516
+ })
517
+ .should.rejectedWith('missing backupKey');
518
+ });
519
+ it('should throw error if userkey is not present', async function () {
520
+ await basecoin
521
+ .recover({
522
+ backupKey: atom_1.wrwUser.backupKey,
523
+ bitgoKey: atom_1.wrwUser.bitgoKey,
524
+ walletPassphrase: atom_1.wrwUser.walletPassphrase,
525
+ recoveryDestination: destinationAddress,
526
+ })
527
+ .should.rejectedWith('missing userKey');
528
+ });
529
+ it('should throw error if wallet passphrase is not present', async function () {
530
+ await basecoin
531
+ .recover({
532
+ userKey: atom_1.wrwUser.userKey,
533
+ backupKey: atom_1.wrwUser.backupKey,
534
+ bitgoKey: atom_1.wrwUser.bitgoKey,
535
+ recoveryDestination: destinationAddress,
536
+ })
537
+ .should.rejectedWith('missing wallet passphrase');
538
+ });
539
+ it('should throw error if there is no balance', async function () {
540
+ await basecoin
541
+ .recover({
542
+ userKey: atom_1.wrwUser.userKey,
543
+ backupKey: atom_1.wrwUser.backupKey,
544
+ bitgoKey: atom_1.wrwUser.bitgoKey,
545
+ walletPassphrase: atom_1.wrwUser.walletPassphrase,
546
+ recoveryDestination: destinationAddress,
547
+ })
548
+ .should.rejectedWith('Did not have enough funds to recover');
549
+ });
550
+ });
551
+ });
552
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRvbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC9hdG9tLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsaUVBQWdHO0FBQ2hHLGlEQUErQztBQUMvQyx5REFBc0U7QUFDdEUsbURBQWtHO0FBQ2xHLGlEQUE0QztBQUM1QyxnRUFBcUM7QUFDckMsa0RBQTBCO0FBQzFCLG1DQUF3QztBQUN4Qyx1REFBcUQ7QUFDckQsZ0VBQXdDO0FBQ3hDLDRDQVUyQjtBQUMzQixpQ0FBa0M7QUFFbEMsUUFBUSxDQUFDLE1BQU0sRUFBRTtJQUNmLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLFFBQVEsQ0FBQztJQUNiLE1BQU0sQ0FBQztRQUNMLEtBQUssR0FBRyxvQkFBUyxDQUFDLFFBQVEsQ0FBQyxrQkFBUSxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEQsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsVUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2hELEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLFdBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNsRCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMzQixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw2QkFBNkIsRUFBRTtRQUNoQyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hDLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFbEMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLE1B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QU8sQ0FBQztnQkFDUCxTQUFTLEVBQUUsY0FBTyxDQUFDLFNBQVM7Z0JBQzVCLFFBQVEsRUFBRSxjQUFPLENBQUMsUUFBUTtnQkFDMUIsZ0JBQWdCLEVBQUUsY0FBTyxDQUFDLGdCQUFnQjtnQkFDMUMsbUJBQW1CLEVBQUUsa0JBQWtCO2FBQ3hDLENBQUM7aUJBQ0QsTUFBTSxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQzVDLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHdEQUF3RCxFQUFFLEtBQUs7WUFDaEUsTUFBTSxRQUFRO2lCQUNYLE9BQU8sQ0FBQztnQkFDUCxPQUFPLEVBQUUsY0FBTyxDQUFDLE9BQU87Z0JBQ3hCLFNBQVMsRUFBRSxjQUFPLENBQUMsU0FBUztnQkFDNUIsUUFBUSxFQUFFLGNBQU8sQ0FBQyxRQUFRO2dCQUMxQixtQkFBbUIsRUFBRSxrQkFBa0I7YUFDeEMsQ0FBQztpQkFDRCxNQUFNLENBQUMsWUFBWSxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDdEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMkNBQTJDLEVBQUUsS0FBSztZQUNuRCxNQUFNLFFBQVE7aUJBQ1gsT0FBTyxDQUFDO2dCQUNQLE9BQU8sRUFBRSxjQUFPLENBQUMsT0FBTztnQkFDeEIsU0FBUyxFQUFFLGNBQU8sQ0FBQyxTQUFTO2dCQUM1QixRQUFRLEVBQUUsY0FBTyxDQUFDLFFBQVE7Z0JBQzFCLGdCQUFnQixFQUFFLGNBQU8sQ0FBQyxnQkFBZ0I7Z0JBQzFDLG1CQUFtQixFQUFFLGtCQUFrQjthQUN4QyxDQUFDO2lCQUNELE1BQU0sQ0FBQyxZQUFZLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUNqRSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb3Ntb3NUcmFuc2FjdGlvbiwgUmVkZWxlZ2F0ZU1lc3NhZ2UsIFNlbmRNZXNzYWdlIH0gZnJvbSAnQGJpdGdvLWJldGEvYWJzdHJhY3QtY29zbW9zJztcbmltcG9ydCB7IEJpdEdvQVBJIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWFwaSc7XG5pbXBvcnQgeyBFY2RzYVJhbmdlUHJvb2YsIEVjZHNhVHlwZXMgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstbGliLW1wYyc7XG5pbXBvcnQgeyBUZXN0Qml0R28sIFRlc3RCaXRHb0FQSSwgbW9ja1NlcmlhbGl6ZWRDaGFsbGVuZ2VXaXRoUHJvb2ZzIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLXRlc3QnO1xuaW1wb3J0IHsgY29pbnMgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCBCaWdOdW1iZXIgZnJvbSAnYmlnbnVtYmVyLmpzJztcbmltcG9ydCBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgeyBBdG9tLCBUYXRvbSB9IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBHQVNfQU1PVU5UIH0gZnJvbSAnLi4vLi4vc3JjL2xpYi9jb25zdGFudHMnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuaW1wb3J0IHtcbiAgVEVTVF9ERUxFR0FURV9UWCxcbiAgVEVTVF9TRU5EX01BTllfVFgsXG4gIFRFU1RfU0VORF9UWCxcbiAgVEVTVF9UWF9XSVRIX01FTU8sXG4gIFRFU1RfVU5ERUxFR0FURV9UWCxcbiAgVEVTVF9XSVRIRFJBV19SRVdBUkRTX1RYLFxuICBhZGRyZXNzLFxuICB3cndVc2VyLFxuICB3cndVc2VyRGtscyxcbn0gZnJvbSAnLi4vcmVzb3VyY2VzL2F0b20nO1xuaW1wb3J0IHNob3VsZCA9IHJlcXVpcmUoJ3Nob3VsZCcpO1xuXG5kZXNjcmliZSgnQVRPTScsIGZ1bmN0aW9uICgpIHtcbiAgbGV0IGJpdGdvOiBUZXN0Qml0R29BUEk7XG4gIGxldCBiYXNlY29pbjtcbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ2F0b20nLCBBdG9tLmNyZWF0ZUluc3RhbmNlKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3RhdG9tJywgVGF0b20uY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndGF0b20nKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCByZXR1biB0aGUgcmlnaHQgaW5mbycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBhdG9tID0gYml0Z28uY29pbignYXRvbScpO1xuICAgIGNvbnN0IHRhdG9tID0gYml0Z28uY29pbigndGF0b20nKTtcblxuICAgIGF0b20uZ2V0Q2hhaW4oKS5zaG91bGQuZXF1YWwoJ2F0b20nKTtcbiAgICBhdG9tLmdldEZhbWlseSgpLnNob3VsZC5lcXVhbCgnYXRvbScpO1xuICAgIGF0b20uZ2V0RnVsbE5hbWUoKS5zaG91bGQuZXF1YWwoJ0Nvc21vcyBIdWIgQVRPTScpO1xuICAgIGF0b20uZ2V0QmFzZUZhY3RvcigpLnNob3VsZC5lcXVhbCgxZTYpO1xuXG4gICAgdGF0b20uZ2V0Q2hhaW4oKS5zaG91bGQuZXF1YWwoJ3RhdG9tJyk7XG4gICAgdGF0b20uZ2V0RmFtaWx5KCkuc2hvdWxkLmVxdWFsKCdhdG9tJyk7XG4gICAgdGF0b20uZ2V0RnVsbE5hbWUoKS5zaG91bGQuZXF1YWwoJ1Rlc3RuZXQgQ29zbW9zIEh1YiBBVE9NJyk7XG4gICAgdGF0b20uZ2V0QmFzZUZhY3RvcigpLnNob3VsZC5lcXVhbCgxZTYpO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWRkcmVzcyBWYWxpZGF0aW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2V0IGFkZHJlc3MgZGV0YWlscyB3aXRob3V0IG1lbW9JZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3NEZXRhaWxzID0gYmFzZWNvaW4uZ2V0QWRkcmVzc0RldGFpbHMoYWRkcmVzcy5ub01lbW9JZEFkZHJlc3MpO1xuICAgICAgYWRkcmVzc0RldGFpbHMuYWRkcmVzcy5zaG91bGQuZXF1YWwoYWRkcmVzcy5ub01lbW9JZEFkZHJlc3MpO1xuICAgICAgc2hvdWxkLm5vdC5leGlzdChhZGRyZXNzRGV0YWlscy5tZW1vSWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgYWRkcmVzcyBkZXRhaWxzIHdpdGggbWVtb0lkJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzc0RldGFpbHMgPSBiYXNlY29pbi5nZXRBZGRyZXNzRGV0YWlscyhhZGRyZXNzLnZhbGlkTWVtb0lkQWRkcmVzcyk7XG4gICAgICBhZGRyZXNzRGV0YWlscy5hZGRyZXNzLnNob3VsZC5lcXVhbChhZGRyZXNzLnZhbGlkTWVtb0lkQWRkcmVzcy5zcGxpdCgnPycpWzBdKTtcbiAgICAgIGFkZHJlc3NEZXRhaWxzLm1lbW9JZC5zaG91bGQuZXF1YWwoJzInKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgb24gbXVsdGlwbGUgbWVtbyBpZCBhZGRyZXNzJywgKCkgPT4ge1xuICAgICAgKCgpID0+IHtcbiAgICAgICAgYmFzZWNvaW4uZ2V0QWRkcmVzc0RldGFpbHMoYWRkcmVzcy5tdWx0aXBsZU1lbW9JZEFkZHJlc3MpO1xuICAgICAgfSkuc2hvdWxkLnRocm93KCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIHdhbGxldCByZWNlaXZlIGFkZHJlc3MnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZWNlaXZlQWRkcmVzcyA9IHtcbiAgICAgICAgYWRkcmVzczogJ2Nvc21vczFyN2szeG1sbGpzZmRrNnk5cjhzc2ZudDRrczVrYTBud21tMHo3MD9tZW1vSWQ9NycsXG4gICAgICAgIGNvaW5TcGVjaWZpYzoge1xuICAgICAgICAgIHJvb3RBZGRyZXNzOiAnY29zbW9zMXI3azN4bWxsanNmZGs2eTlyOHNzZm50NGtzNWthMG53bW0wejcwJyxcbiAgICAgICAgICBtZW1vSUQ6ICc3JyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBjb25zdCBpc1ZhbGlkID0gYXdhaXQgYmFzZWNvaW4uaXNXYWxsZXRBZGRyZXNzKHJlY2VpdmVBZGRyZXNzKTtcbiAgICAgIGlzVmFsaWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBhY2NvdW50IGFkZHJlc3NlcyBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcy5hZGRyZXNzMSksIHRydWUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MuYWRkcmVzczIpLCB0cnVlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzLmFkZHJlc3MzKSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MuYWRkcmVzczQpLCBmYWxzZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoJ2RmamszNXknKSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIHN0cmluZyksIGZhbHNlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcygnJyksIGZhbHNlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzLnZhbGlkTWVtb0lkQWRkcmVzcyksIHRydWUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MubXVsdGlwbGVNZW1vSWRBZGRyZXNzKSwgZmFsc2UpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgdmFsaWRhdG9yIGFkZHJlc3NlcyBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFZhbGlkYXRvckFkZHJlc3MoYWRkcmVzcy52YWxpZGF0b3JBZGRyZXNzMSksIHRydWUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRWYWxpZGF0b3JBZGRyZXNzKGFkZHJlc3MudmFsaWRhdG9yQWRkcmVzczIpLCB0cnVlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkVmFsaWRhdG9yQWRkcmVzcyhhZGRyZXNzLnZhbGlkYXRvckFkZHJlc3MzKSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRWYWxpZGF0b3JBZGRyZXNzKGFkZHJlc3MudmFsaWRhdG9yQWRkcmVzczQpLCBmYWxzZSk7XG4gICAgICBzaG91bGQuZXF1YWwodXRpbHMuaXNWYWxpZFZhbGlkYXRvckFkZHJlc3MoJ2RmamszNXknKSwgZmFsc2UpO1xuICAgICAgc2hvdWxkLmVxdWFsKHV0aWxzLmlzVmFsaWRWYWxpZGF0b3JBZGRyZXNzKHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIHN0cmluZyksIGZhbHNlKTtcbiAgICAgIHNob3VsZC5lcXVhbCh1dGlscy5pc1ZhbGlkVmFsaWRhdG9yQWRkcmVzcygnJyksIGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1ZlcmlmeSB0cmFuc2FjdGlvbjogJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge1xuICAgICAgICB0eEhleDogVEVTVF9TRU5EX1RYLnNpZ25lZFR4QmFzZTY0LFxuICAgICAgICB0eEluZm86IHt9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogVEVTVF9TRU5EX1RYLnJlY2lwaWVudCxcbiAgICAgICAgICAgIGFtb3VudDogVEVTVF9TRU5EX1RYLnNlbmRBbW91bnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgICBjb25zdCB2ZXJpZmljYXRpb24gPSB7fTtcbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHZlcmlmaWNhdGlvbiB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN1Y2NlZWQgdG8gdmVyaWZ5IHNlbmRNYW55IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6IFRFU1RfU0VORF9NQU5ZX1RYLnNpZ25lZFR4QmFzZTY0LFxuICAgICAgICB0eEluZm86IHt9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ2Nvc21vczE2Z2huOWM2ZjV5dWEwOXpxdzd5Nzk0bXZjMzBoNHk0bWQ3Y2t1aycsXG4gICAgICAgICAgICBhbW91bnQ6ICc1MDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJ2Nvc21vczF5dGV6MDZ5eDB1M3lqempqam0wMnh5eDNtaDI1YWtlbnpxbDNuOCcsXG4gICAgICAgICAgICBhbW91bnQ6ICc1MDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB2ZXJpZmljYXRpb24gfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSBkZWxlZ2F0ZSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiBURVNUX0RFTEVHQVRFX1RYLnNpZ25lZFR4QmFzZTY0LFxuICAgICAgICB0eEluZm86IHt9LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0ge1xuICAgICAgICByZWNpcGllbnRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogVEVTVF9ERUxFR0FURV9UWC52YWxpZGF0b3IsXG4gICAgICAgICAgICBhbW91bnQ6IFRFU1RfREVMRUdBVEVfVFguc2VuZEFtb3VudCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgdmVyaWZpY2F0aW9uIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgdW5kZWxlZ2F0ZSB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiBURVNUX1VOREVMRUdBVEVfVFguc2lnbmVkVHhCYXNlNjQsXG4gICAgICAgIHR4SW5mbzoge30sXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiBURVNUX1VOREVMRUdBVEVfVFgudmFsaWRhdG9yLFxuICAgICAgICAgICAgYW1vdW50OiBURVNUX1VOREVMRUdBVEVfVFguc2VuZEFtb3VudCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuICAgICAgY29uc3QgaXNUcmFuc2FjdGlvblZlcmlmaWVkID0gYXdhaXQgYmFzZWNvaW4udmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgdmVyaWZpY2F0aW9uIH0pO1xuICAgICAgaXNUcmFuc2FjdGlvblZlcmlmaWVkLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgd2l0aGRyYXcgcmV3YXJkcyB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgICAgIHR4SGV4OiBURVNUX1dJVEhEUkFXX1JFV0FSRFNfVFguc2lnbmVkVHhCYXNlNjQsXG4gICAgICAgIHR4SW5mbzoge30sXG4gICAgICB9O1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSB7XG4gICAgICAgIHJlY2lwaWVudHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiBURVNUX1dJVEhEUkFXX1JFV0FSRFNfVFgudmFsaWRhdG9yLFxuICAgICAgICAgICAgYW1vdW50OiAnVU5BVkFJTEFCTEUnLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB2ZXJpZmljYXRpb24gfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIHZlcmlmeSB0cmFuc2FjdGlvbiB3aXRoIGludmFsaWQgcGFyYW0nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge307XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHsgcmVjaXBpZW50czogdW5kZWZpbmVkIH07XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHR4UGFyYW1zLFxuICAgICAgICAgIHR4UHJlYnVpbGQsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHJlcXVpcmVkIHR4IHByZWJ1aWxkIHByb3BlcnR5IHR4SGV4Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFeHBsYWluIFRyYW5zYWN0aW9uOiAnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBURVNUX1NFTkRfVFguc2lnbmVkVHhCYXNlNjQsXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFsnaWQnLCAnb3V0cHV0cycsICdvdXRwdXRBbW91bnQnLCAnY2hhbmdlT3V0cHV0cycsICdjaGFuZ2VBbW91bnQnLCAnZmVlJywgJ3R5cGUnXSxcbiAgICAgICAgaWQ6IFRFU1RfU0VORF9UWC5oYXNoLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogVEVTVF9TRU5EX1RYLnJlY2lwaWVudCxcbiAgICAgICAgICAgIGFtb3VudDogVEVTVF9TRU5EX1RYLnNlbmRBbW91bnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0QW1vdW50OiBURVNUX1NFTkRfVFguc2VuZEFtb3VudCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBmZWU6IHsgZmVlOiBURVNUX1NFTkRfVFguZ2FzQnVkZ2V0LmFtb3VudFswXS5hbW91bnQgfSxcbiAgICAgICAgdHlwZTogMCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIHNlbmRNYW55IHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogVEVTVF9TRU5EX01BTllfVFguc2lnbmVkVHhCYXNlNjQsXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFsnaWQnLCAnb3V0cHV0cycsICdvdXRwdXRBbW91bnQnLCAnY2hhbmdlT3V0cHV0cycsICdjaGFuZ2VBbW91bnQnLCAnZmVlJywgJ3R5cGUnXSxcbiAgICAgICAgaWQ6IFRFU1RfU0VORF9NQU5ZX1RYLmhhc2gsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnY29zbW9zMTZnaG45YzZmNXl1YTA5enF3N3k3OTRtdmMzMGg0eTRtZDdja3VrJyxcbiAgICAgICAgICAgIGFtb3VudDogJzUwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiAnY29zbW9zMXl0ZXowNnl4MHUzeWp6ampqbTAyeHl4M21oMjVha2VuenFsM244JyxcbiAgICAgICAgICAgIGFtb3VudDogJzUwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0QW1vdW50OiAnMTAwMCcsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgZmVlOiB7IGZlZTogVEVTVF9TRU5EX01BTllfVFguZ2FzQnVkZ2V0LmFtb3VudFswXS5hbW91bnQgfSxcbiAgICAgICAgdHlwZTogMCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgZGVsZWdhdGUgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBURVNUX0RFTEVHQVRFX1RYLnNpZ25lZFR4QmFzZTY0LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbJ2lkJywgJ291dHB1dHMnLCAnb3V0cHV0QW1vdW50JywgJ2NoYW5nZU91dHB1dHMnLCAnY2hhbmdlQW1vdW50JywgJ2ZlZScsICd0eXBlJ10sXG4gICAgICAgIGlkOiBURVNUX0RFTEVHQVRFX1RYLmhhc2gsXG4gICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBhZGRyZXNzOiBURVNUX0RFTEVHQVRFX1RYLnZhbGlkYXRvcixcbiAgICAgICAgICAgIGFtb3VudDogVEVTVF9ERUxFR0FURV9UWC5zZW5kQW1vdW50LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG91dHB1dEFtb3VudDogVEVTVF9ERUxFR0FURV9UWC5zZW5kQW1vdW50LFxuICAgICAgICBjaGFuZ2VPdXRwdXRzOiBbXSxcbiAgICAgICAgY2hhbmdlQW1vdW50OiAnMCcsXG4gICAgICAgIGZlZTogeyBmZWU6IFRFU1RfREVMRUdBVEVfVFguZ2FzQnVkZ2V0LmFtb3VudFswXS5hbW91bnQgfSxcbiAgICAgICAgdHlwZTogMTMsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHVuZGVsZWdhdGUgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBURVNUX1VOREVMRUdBVEVfVFguc2lnbmVkVHhCYXNlNjQsXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwoe1xuICAgICAgICBkaXNwbGF5T3JkZXI6IFsnaWQnLCAnb3V0cHV0cycsICdvdXRwdXRBbW91bnQnLCAnY2hhbmdlT3V0cHV0cycsICdjaGFuZ2VBbW91bnQnLCAnZmVlJywgJ3R5cGUnXSxcbiAgICAgICAgaWQ6IFRFU1RfVU5ERUxFR0FURV9UWC5oYXNoLFxuICAgICAgICBvdXRwdXRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogVEVTVF9VTkRFTEVHQVRFX1RYLnZhbGlkYXRvcixcbiAgICAgICAgICAgIGFtb3VudDogVEVTVF9VTkRFTEVHQVRFX1RYLnNlbmRBbW91bnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0QW1vdW50OiBURVNUX1VOREVMRUdBVEVfVFguc2VuZEFtb3VudCxcbiAgICAgICAgY2hhbmdlT3V0cHV0czogW10sXG4gICAgICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgICAgICBmZWU6IHsgZmVlOiBURVNUX1VOREVMRUdBVEVfVFguZ2FzQnVkZ2V0LmFtb3VudFswXS5hbW91bnQgfSxcbiAgICAgICAgdHlwZTogMTcsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHdpdGhkcmF3IHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogVEVTVF9XSVRIRFJBV19SRVdBUkRTX1RYLnNpZ25lZFR4QmFzZTY0LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluZWRUcmFuc2FjdGlvbi5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgZGlzcGxheU9yZGVyOiBbJ2lkJywgJ291dHB1dHMnLCAnb3V0cHV0QW1vdW50JywgJ2NoYW5nZU91dHB1dHMnLCAnY2hhbmdlQW1vdW50JywgJ2ZlZScsICd0eXBlJ10sXG4gICAgICAgIGlkOiBURVNUX1dJVEhEUkFXX1JFV0FSRFNfVFguaGFzaCxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IFRFU1RfV0lUSERSQVdfUkVXQVJEU19UWC52YWxpZGF0b3IsXG4gICAgICAgICAgICBhbW91bnQ6ICdVTkFWQUlMQUJMRScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgb3V0cHV0QW1vdW50OiB1bmRlZmluZWQsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgZmVlOiB7IGZlZTogVEVTVF9XSVRIRFJBV19SRVdBUkRTX1RYLmdhc0J1ZGdldC5hbW91bnRbMF0uYW1vdW50IH0sXG4gICAgICAgIHR5cGU6IDE1LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSB0cmFuc2ZlciB0cmFuc2FjdGlvbiB3aXRoIG1lbW8nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBURVNUX1RYX1dJVEhfTUVNTy5zaWduZWRUeEJhc2U2NCxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbmVkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGRpc3BsYXlPcmRlcjogWydpZCcsICdvdXRwdXRzJywgJ291dHB1dEFtb3VudCcsICdjaGFuZ2VPdXRwdXRzJywgJ2NoYW5nZUFtb3VudCcsICdmZWUnLCAndHlwZSddLFxuICAgICAgICBpZDogVEVTVF9UWF9XSVRIX01FTU8uaGFzaCxcbiAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6IFRFU1RfVFhfV0lUSF9NRU1PLnRvLFxuICAgICAgICAgICAgYW1vdW50OiBURVNUX1RYX1dJVEhfTUVNTy5zZW5kQW1vdW50LFxuICAgICAgICAgICAgbWVtbzogVEVTVF9UWF9XSVRIX01FTU8ubWVtbyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBvdXRwdXRBbW91bnQ6IFRFU1RfVFhfV0lUSF9NRU1PLnNlbmRBbW91bnQsXG4gICAgICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgICAgICBjaGFuZ2VBbW91bnQ6ICcwJyxcbiAgICAgICAgZmVlOiB7IGZlZTogVEVTVF9UWF9XSVRIX01FTU8uZ2FzQnVkZ2V0LmFtb3VudFswXS5hbW91bnQgfSxcbiAgICAgICAgdHlwZTogMCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHRvIGV4cGxhaW4gdHJhbnNhY3Rpb24gd2l0aCBtaXNzaW5nIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7fSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBzaG91bGQuZXF1YWwoZXJyb3IubWVzc2FnZSwgJ21pc3NpbmcgcmVxdWlyZWQgdHhIZXggcGFyYW1ldGVyJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gZXhwbGFpbiB0cmFuc2FjdGlvbiB3aXRoIGludmFsaWQgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHsgdHhIZXg6ICdyYW5kb21TdHJpbmcnIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgc2hvdWxkLmVxdWFsKGVycm9yLm1lc3NhZ2Uuc3RhcnRzV2l0aCgnSW52YWxpZCB0cmFuc2FjdGlvbjonKSwgdHJ1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdQYXJzZSBUcmFuc2FjdGlvbnM6ICcsICgpID0+IHtcbiAgICBjb25zdCB0cmFuc2ZlcklucHV0c1Jlc3BvbnNlID0ge1xuICAgICAgYWRkcmVzczogVEVTVF9TRU5EX1RYLnJlY2lwaWVudCxcbiAgICAgIGFtb3VudDogbmV3IEJpZ051bWJlcihURVNUX1NFTkRfVFguc2VuZEFtb3VudCkucGx1cyhURVNUX1NFTkRfVFguZ2FzQnVkZ2V0LmFtb3VudFswXS5hbW91bnQpLnRvRml4ZWQoKSxcbiAgICB9O1xuXG4gICAgY29uc3QgdHJhbnNmZXJPdXRwdXRzUmVzcG9uc2UgPSB7XG4gICAgICBhZGRyZXNzOiBURVNUX1NFTkRfVFgucmVjaXBpZW50LFxuICAgICAgYW1vdW50OiBURVNUX1NFTkRfVFguc2VuZEFtb3VudCxcbiAgICB9O1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBhIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyc2VkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5wYXJzZVRyYW5zYWN0aW9uKHsgdHhIZXg6IFRFU1RfU0VORF9UWC5zaWduZWRUeEJhc2U2NCB9KTtcblxuICAgICAgcGFyc2VkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgIGlucHV0czogW3RyYW5zZmVySW5wdXRzUmVzcG9uc2VdLFxuICAgICAgICBvdXRwdXRzOiBbdHJhbnNmZXJPdXRwdXRzUmVzcG9uc2VdLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gcGFyc2UgYSB0cmFuc2ZlciB0cmFuc2FjdGlvbiB3aGVuIGV4cGxhaW5UcmFuc2FjdGlvbiByZXNwb25zZSBpcyB1bmRlZmluZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdHViID0gc2lub24uc3R1YihBdG9tLnByb3RvdHlwZSwgJ2V4cGxhaW5UcmFuc2FjdGlvbicpO1xuICAgICAgc3R1Yi5yZXNvbHZlcyh1bmRlZmluZWQpO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnBhcnNlVHJhbnNhY3Rpb24oeyB0eEhleDogVEVTVF9TRU5EX1RYLnNpZ25lZFR4QmFzZTY0IH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHRyYW5zYWN0aW9uJyk7XG4gICAgICBzdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXIgdHJhbnNhY3Rpb25zOiBzdWNjZXNzIHBhdGgnLCAoKSA9PiB7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSB3cndVc2VyLmRlc3RpbmF0aW9uQWRkcmVzcztcbiAgICBjb25zdCBjb2luID0gY29pbnMuZ2V0KCd0YXRvbScpO1xuICAgIGNvbnN0IHRlc3RCYWxhbmNlID0gW1xuICAgICAge1xuICAgICAgICBkZW5vbTogJ3VhdG9tJyxcbiAgICAgICAgYW1vdW50OiAnMTUwMDAwJyxcbiAgICAgIH0sXG4gICAgXTtcbiAgICBjb25zdCB0ZXN0QWNjb3VudE51bWJlciA9ICc3MjUxNjMnO1xuICAgIGNvbnN0IHRlc3RTZXF1ZW5jZU51bWJlciA9ICc4JztcblxuICAgIGNvbnN0IHRlc3RCYWxhbmNlRGtscyA9IFtcbiAgICAgIHtcbiAgICAgICAgZGVub206ICd1YXRvbScsXG4gICAgICAgIGFtb3VudDogJzE1MDAwMCcsXG4gICAgICB9LFxuICAgIF07XG4gICAgY29uc3QgdGVzdEFjY291bnROdW1iZXJEa2xzID0gJzc1NTQ0MCc7XG4gICAgY29uc3QgdGVzdFNlcXVlbmNlTnVtYmVyRGtscyA9ICcyJztcblxuICAgIGNvbnN0IHRlc3RDaGFpbklkID0gJ3RoZXRhLXRlc3RuZXQtMDAxJztcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgY29uc3QgYWNjb3VudEJhbGFuY2UgPSBzYW5kQm94LnN0dWIoQXRvbS5wcm90b3R5cGUsICdnZXRBY2NvdW50QmFsYW5jZScgYXMga2V5b2YgQXRvbSk7XG4gICAgICBhY2NvdW50QmFsYW5jZS53aXRoQXJncyh3cndVc2VyLnNlbmRlckFkZHJlc3MpLnJlc29sdmVzKHRlc3RCYWxhbmNlKTtcbiAgICAgIGFjY291bnRCYWxhbmNlLndpdGhBcmdzKHdyd1VzZXJEa2xzLnNlbmRlckFkZHJlc3MpLnJlc29sdmVzKHRlc3RCYWxhbmNlRGtscyk7XG5cbiAgICAgIGNvbnN0IGFjY291bnREZXRhaWxzID0gc2FuZEJveC5zdHViKEF0b20ucHJvdG90eXBlLCAnZ2V0QWNjb3VudERldGFpbHMnIGFzIGtleW9mIEF0b20pO1xuICAgICAgYWNjb3VudERldGFpbHMud2l0aEFyZ3Mod3J3VXNlci5zZW5kZXJBZGRyZXNzKS5yZXNvbHZlcyhbdGVzdEFjY291bnROdW1iZXIsIHRlc3RTZXF1ZW5jZU51bWJlcl0pO1xuICAgICAgYWNjb3VudERldGFpbHMud2l0aEFyZ3Mod3J3VXNlckRrbHMuc2VuZGVyQWRkcmVzcykucmVzb2x2ZXMoW3Rlc3RBY2NvdW50TnVtYmVyRGtscywgdGVzdFNlcXVlbmNlTnVtYmVyRGtsc10pO1xuXG4gICAgICBjb25zdCBjaGFpbklkID0gc2FuZEJveC5zdHViKEF0b20ucHJvdG90eXBlLCAnZ2V0Q2hhaW5JZCcgYXMga2V5b2YgQXRvbSk7XG4gICAgICBjaGFpbklkLndpdGhBcmdzKCkucmVzb2x2ZXModGVzdENoYWluSWQpO1xuXG4gICAgICBjb25zdCBkZXNlcmlhbGl6ZWRFbnRDaGFsbGVuZ2UgPSBFY2RzYVR5cGVzLmRlc2VyaWFsaXplTnRpbGRlV2l0aFByb29mcyhtb2NrU2VyaWFsaXplZENoYWxsZW5nZVdpdGhQcm9vZnMpO1xuICAgICAgc2lub24uc3R1YihFY2RzYVJhbmdlUHJvb2YsICdnZW5lcmF0ZU50aWxkZScpLnJlc29sdmVzKGRlc2VyaWFsaXplZEVudENoYWxsZW5nZSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZEJveC5yZXN0b3JlKCk7XG4gICAgICBzaW5vbi5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgZnVuZHMgZm9yIG5vbi1iaXRnbyByZWNvdmVyaWVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHdyd1VzZXIudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB3cndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IHdyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHdyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGJhc2Vjb2luLmdldEFjY291bnRCYWxhbmNlKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZE9uY2UoYmFzZWNvaW4uZ2V0QWNjb3VudERldGFpbHMpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkT25jZShiYXNlY29pbi5nZXRDaGFpbklkKTtcblxuICAgICAgY29uc3QgYXRvbVR4biA9IG5ldyBDb3Ntb3NUcmFuc2FjdGlvbihjb2luLCB1dGlscyk7XG4gICAgICBhdG9tVHhuLmVucmljaFRyYW5zYWN0aW9uRGV0YWlsc0Zyb21SYXdUcmFuc2FjdGlvbihyZXMuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IGF0b21UeG5Kc29uID0gYXRvbVR4bi50b0pzb24oKTtcbiAgICAgIGNvbnN0IHNlbmRNZXNzYWdlID0gYXRvbVR4bkpzb24uc2VuZE1lc3NhZ2VzWzBdLnZhbHVlIGFzIFNlbmRNZXNzYWdlO1xuICAgICAgY29uc3QgYmFsYW5jZSA9IG5ldyBCaWdOdW1iZXIodGVzdEJhbGFuY2VbMF0uYW1vdW50KTtcbiAgICAgIGNvbnN0IGdhc0Ftb3VudCA9IG5ldyBCaWdOdW1iZXIoR0FTX0FNT1VOVCk7XG4gICAgICBjb25zdCBhY3R1YWxCYWxhbmNlID0gYmFsYW5jZS5taW51cyhnYXNBbW91bnQpO1xuICAgICAgc2hvdWxkLmVxdWFsKHNlbmRNZXNzYWdlLmFtb3VudFswXS5hbW91bnQsIGFjdHVhbEJhbGFuY2UudG9GaXhlZCgpKTtcbiAgICAgIHNob3VsZC5lcXVhbChzZW5kTWVzc2FnZS5hbW91bnRbMF0uZGVub20sIHRlc3RCYWxhbmNlWzBdLmRlbm9tKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBmdW5kcyBmb3Igbm9uLWJpdGdvIHJlY292ZXJpZXMgLSBES0xTIHR5cGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogd3J3VXNlckRrbHMudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB3cndVc2VyRGtscy5iYWNrdXBLZXksXG4gICAgICAgIGJpdGdvS2V5OiB3cndVc2VyRGtscy5iaXRnb0tleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogd3J3VXNlckRrbHMud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogd3J3VXNlckRrbHMuZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGJhc2Vjb2luLmdldEFjY291bnRCYWxhbmNlKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZE9uY2UoYmFzZWNvaW4uZ2V0QWNjb3VudERldGFpbHMpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkT25jZShiYXNlY29pbi5nZXRDaGFpbklkKTtcblxuICAgICAgY29uc3QgYXRvbVR4biA9IG5ldyBDb3Ntb3NUcmFuc2FjdGlvbihjb2luLCB1dGlscyk7XG4gICAgICBhdG9tVHhuLmVucmljaFRyYW5zYWN0aW9uRGV0YWlsc0Zyb21SYXdUcmFuc2FjdGlvbihyZXMuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IGF0b21UeG5Kc29uID0gYXRvbVR4bi50b0pzb24oKTtcbiAgICAgIGNvbnN0IHNlbmRNZXNzYWdlID0gYXRvbVR4bkpzb24uc2VuZE1lc3NhZ2VzWzBdLnZhbHVlIGFzIFNlbmRNZXNzYWdlO1xuICAgICAgY29uc3QgYmFsYW5jZSA9IG5ldyBCaWdOdW1iZXIodGVzdEJhbGFuY2VEa2xzWzBdLmFtb3VudCk7XG4gICAgICBjb25zdCBnYXNBbW91bnQgPSBuZXcgQmlnTnVtYmVyKEdBU19BTU9VTlQpO1xuICAgICAgY29uc3QgYWN0dWFsQmFsYW5jZSA9IGJhbGFuY2UubWludXMoZ2FzQW1vdW50KTtcbiAgICAgIHNob3VsZC5lcXVhbChzZW5kTWVzc2FnZS5hbW91bnRbMF0uYW1vdW50LCBhY3R1YWxCYWxhbmNlLnRvRml4ZWQoKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgZnVuZHMgZm9yIFVuc2lnbmVkIFN3ZWVwIFRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHdyd1VzZXIudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB3cndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IHdyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHdyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGJhc2Vjb2luLmdldEFjY291bnRCYWxhbmNlKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZE9uY2UoYmFzZWNvaW4uZ2V0QWNjb3VudERldGFpbHMpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkT25jZShiYXNlY29pbi5nZXRDaGFpbklkKTtcblxuICAgICAgY29uc3QgdW5zaWduZWRTd2VlcFR4bkRlc2VyaWFsaXplID0gbmV3IENvc21vc1RyYW5zYWN0aW9uKGNvaW4sIHV0aWxzKTtcbiAgICAgIHVuc2lnbmVkU3dlZXBUeG5EZXNlcmlhbGl6ZS5lbnJpY2hUcmFuc2FjdGlvbkRldGFpbHNGcm9tUmF3VHJhbnNhY3Rpb24ocmVzLnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCB1bnNpZ25lZFN3ZWVwVHhuSnNvbiA9IHVuc2lnbmVkU3dlZXBUeG5EZXNlcmlhbGl6ZS50b0pzb24oKTtcbiAgICAgIGNvbnN0IHNlbmRNZXNzYWdlID0gdW5zaWduZWRTd2VlcFR4bkpzb24uc2VuZE1lc3NhZ2VzWzBdLnZhbHVlIGFzIFNlbmRNZXNzYWdlO1xuICAgICAgY29uc3QgYmFsYW5jZSA9IG5ldyBCaWdOdW1iZXIodGVzdEJhbGFuY2VbMF0uYW1vdW50KTtcbiAgICAgIGNvbnN0IGdhc0Ftb3VudCA9IG5ldyBCaWdOdW1iZXIoR0FTX0FNT1VOVCk7XG4gICAgICBjb25zdCBhY3R1YWxCYWxhbmNlID0gYmFsYW5jZS5taW51cyhnYXNBbW91bnQpO1xuICAgICAgc2hvdWxkLmVxdWFsKHNlbmRNZXNzYWdlLmFtb3VudFswXS5hbW91bnQsIGFjdHVhbEJhbGFuY2UudG9GaXhlZCgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVkZWxlZ2F0ZSBmdW5kcyB0byBuZXcgdmFsaWRhdG9yJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYmFzZWNvaW4ucmVkZWxlZ2F0ZSh7XG4gICAgICAgIHVzZXJLZXk6IHdyd1VzZXIudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB3cndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IHdyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHdyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgYW1vdW50VG9SZWRlbGVnYXRlOiAnMTAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICB2YWxpZGF0b3JTcmNBZGRyZXNzOiAnY29zbW9zdmFsb3BlcjE0MDl0ZTI3ZGE3NHVhaGg2aG4wMDQweDdsMjcyaGpzMnBhZGp1eicsXG4gICAgICAgIHZhbGlkYXRvckRzdEFkZHJlc3M6ICdjb3Ntb3N2YWxvcGVyMTgzYXljZ3RzdHA2N3I2czR2ZDd0czJucHAyY2trNHhhaDdyeGo2JyxcbiAgICAgIH0pO1xuXG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnNob3VsZC5oYXNPd25Qcm9wZXJ0eSgnc2VyaWFsaXplZFR4Jyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGJhc2Vjb2luLmdldENoYWluSWQpO1xuXG4gICAgICBjb25zdCB0eG4gPSBuZXcgQ29zbW9zVHJhbnNhY3Rpb24oY29pbiwgdXRpbHMpO1xuICAgICAgdHhuLmVucmljaFRyYW5zYWN0aW9uRGV0YWlsc0Zyb21SYXdUcmFuc2FjdGlvbihyZXMuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IHR4bkpzb24gPSB0eG4udG9Kc29uKCk7XG4gICAgICBjb25zdCByZWRlbGVnYXRlTWVzc2FnZSA9IHR4bkpzb24uc2VuZE1lc3NhZ2VzWzBdLnZhbHVlIGFzIFJlZGVsZWdhdGVNZXNzYWdlO1xuICAgICAgc2hvdWxkLmVxdWFsKHJlZGVsZWdhdGVNZXNzYWdlLnZhbGlkYXRvclNyY0FkZHJlc3MsICdjb3Ntb3N2YWxvcGVyMTQwOXRlMjdkYTc0dWFoaDZobjAwNDB4N2wyNzJoanMycGFkanV6Jyk7XG4gICAgICBzaG91bGQuZXF1YWwocmVkZWxlZ2F0ZU1lc3NhZ2UudmFsaWRhdG9yRHN0QWRkcmVzcywgJ2Nvc21vc3ZhbG9wZXIxODNheWNndHN0cDY3cjZzNHZkN3RzMm5wcDJja2s0eGFoN3J4ajYnKTtcbiAgICAgIHNob3VsZC5lcXVhbChyZWRlbGVnYXRlTWVzc2FnZS5hbW91bnQuYW1vdW50LCAnMTAwMDAwMDAwMDAwMDAwMDAnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXIgdHJhbnNhY3Rpb25zOiBmYWlsdXJlIHBhdGgnLCAoKSA9PiB7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcbiAgICBjb25zdCBkZXN0aW5hdGlvbkFkZHJlc3MgPSB3cndVc2VyLmRlc3RpbmF0aW9uQWRkcmVzcztcbiAgICBjb25zdCB0ZXN0WmVyb0JhbGFuY2UgPSBbXG4gICAgICB7XG4gICAgICAgIGRlbm9tOiAndWF0b20nLFxuICAgICAgICBhbW91bnQ6ICcwJyxcbiAgICAgIH0sXG4gICAgXTtcbiAgICBjb25zdCB0ZXN0QWNjb3VudE51bWJlciA9ICcxMjM0JztcbiAgICBjb25zdCB0ZXN0U2VxdWVuY2VOdW1iZXIgPSAnMCc7XG4gICAgY29uc3QgdGVzdENoYWluSWQgPSAndGVzdC1jaGFpbic7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgIGNvbnN0IGFjY291bnRCYWxhbmNlID0gc2FuZEJveC5zdHViKEF0b20ucHJvdG90eXBlLCAnZ2V0QWNjb3VudEJhbGFuY2UnIGFzIGtleW9mIEF0b20pO1xuICAgICAgYWNjb3VudEJhbGFuY2Uud2l0aEFyZ3Mod3J3VXNlci5zZW5kZXJBZGRyZXNzKS5yZXNvbHZlcyh0ZXN0WmVyb0JhbGFuY2UpO1xuXG4gICAgICBjb25zdCBhY2NvdW50TnVtYmVyID0gc2FuZEJveC5zdHViKEF0b20ucHJvdG90eXBlLCAnZ2V0QWNjb3VudERldGFpbHMnIGFzIGtleW9mIEF0b20pO1xuICAgICAgYWNjb3VudE51bWJlci53aXRoQXJncyh3cndVc2VyLnNlbmRlckFkZHJlc3MpLnJlc29sdmVzKFt0ZXN0QWNjb3VudE51bWJlciwgdGVzdFNlcXVlbmNlTnVtYmVyXSk7XG5cbiAgICAgIGNvbnN0IGNoYWluSWQgPSBzYW5kQm94LnN0dWIoQXRvbS5wcm90b3R5cGUsICdnZXRDaGFpbklkJyBhcyBrZXlvZiBBdG9tKTtcbiAgICAgIGNoYWluSWQud2l0aEFyZ3MoKS5yZXNvbHZlcyh0ZXN0Q2hhaW5JZCk7XG5cbiAgICAgIGNvbnN0IGRlc2VyaWFsaXplZEVudENoYWxsZW5nZSA9IEVjZHNhVHlwZXMuZGVzZXJpYWxpemVOdGlsZGVXaXRoUHJvb2ZzKG1vY2tTZXJpYWxpemVkQ2hhbGxlbmdlV2l0aFByb29mcyk7XG4gICAgICBzaW5vbi5zdHViKEVjZHNhUmFuZ2VQcm9vZiwgJ2dlbmVyYXRlTnRpbGRlJykucmVzb2x2ZXMoZGVzZXJpYWxpemVkRW50Q2hhbGxlbmdlKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICAgIHNpbm9uLnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgYmFja3Vwa2V5IGlzIG5vdCBwcmVzZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHdyd1VzZXIudXNlcktleSxcbiAgICAgICAgICBiaXRnb0tleTogd3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiB3cndVc2VyLndhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnbWlzc2luZyBiYWNrdXBLZXknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdXNlcmtleSBpcyBub3QgcHJlc2VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5yZWNvdmVyKHtcbiAgICAgICAgICBiYWNrdXBLZXk6IHdyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiB3cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHdyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIHVzZXJLZXknKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgd2FsbGV0IHBhc3NwaHJhc2UgaXMgbm90IHByZXNlbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTogd3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogd3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHdyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnbWlzc2luZyB3YWxsZXQgcGFzc3BocmFzZScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGVyZSBpcyBubyBiYWxhbmNlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHdyd1VzZXIudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IHdyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiB3cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHdyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdEaWQgbm90IGhhdmUgZW5vdWdoIGZ1bmRzIHRvIHJlY292ZXInKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==