@bitgo-beta/sdk-coin-ada 2.3.14-beta.132 → 2.3.14-beta.1321

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 (113) hide show
  1. package/dist/src/ada.d.ts +11 -12
  2. package/dist/src/ada.d.ts.map +1 -1
  3. package/dist/src/ada.js +68 -25
  4. package/dist/src/adaToken.d.ts +3 -10
  5. package/dist/src/adaToken.d.ts.map +1 -1
  6. package/dist/src/adaToken.js +6 -3
  7. package/dist/src/index.js +6 -2
  8. package/dist/src/lib/index.d.ts +2 -0
  9. package/dist/src/lib/index.d.ts.map +1 -1
  10. package/dist/src/lib/index.js +29 -9
  11. package/dist/src/lib/keyPair.js +29 -16
  12. package/dist/src/lib/messages/cip8/cip8Message.d.ts +25 -0
  13. package/dist/src/lib/messages/cip8/cip8Message.d.ts.map +1 -0
  14. package/dist/src/lib/messages/cip8/cip8Message.js +140 -0
  15. package/dist/src/lib/messages/cip8/cip8MessageBuilder.d.ts +19 -0
  16. package/dist/src/lib/messages/cip8/cip8MessageBuilder.d.ts.map +1 -0
  17. package/dist/src/lib/messages/cip8/cip8MessageBuilder.js +27 -0
  18. package/dist/src/lib/messages/cip8/index.d.ts +3 -0
  19. package/dist/src/lib/messages/cip8/index.d.ts.map +1 -0
  20. package/dist/src/lib/messages/cip8/index.js +19 -0
  21. package/dist/src/lib/messages/cip8/utils.d.ts +24 -0
  22. package/dist/src/lib/messages/cip8/utils.d.ts.map +1 -0
  23. package/dist/src/lib/messages/cip8/utils.js +73 -0
  24. package/dist/src/lib/messages/index.d.ts +3 -0
  25. package/dist/src/lib/messages/index.d.ts.map +1 -0
  26. package/dist/src/lib/messages/index.js +19 -0
  27. package/dist/src/lib/messages/messageBuilderFactory.d.ts +7 -0
  28. package/dist/src/lib/messages/messageBuilderFactory.d.ts.map +1 -0
  29. package/dist/src/lib/messages/messageBuilderFactory.js +20 -0
  30. package/dist/src/lib/stakingActivateBuilder.d.ts +1 -1
  31. package/dist/src/lib/stakingActivateBuilder.d.ts.map +1 -1
  32. package/dist/src/lib/stakingActivateBuilder.js +30 -10
  33. package/dist/src/lib/stakingDeactivateBuilder.js +24 -10
  34. package/dist/src/lib/transaction.d.ts +13 -6
  35. package/dist/src/lib/transaction.d.ts.map +1 -1
  36. package/dist/src/lib/transaction.js +49 -16
  37. package/dist/src/lib/transactionBuilder.d.ts +82 -3
  38. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  39. package/dist/src/lib/transactionBuilder.js +411 -22
  40. package/dist/src/lib/transactionBuilderFactory.d.ts +2 -0
  41. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  42. package/dist/src/lib/transactionBuilderFactory.js +7 -1
  43. package/dist/src/lib/utils.d.ts +23 -0
  44. package/dist/src/lib/utils.d.ts.map +1 -1
  45. package/dist/src/lib/utils.js +153 -17
  46. package/dist/src/lib/voteDelegationBuilder.d.ts +24 -0
  47. package/dist/src/lib/voteDelegationBuilder.d.ts.map +1 -0
  48. package/dist/src/lib/voteDelegationBuilder.js +84 -0
  49. package/dist/test/resources/cip8Resources.d.ts +25 -0
  50. package/dist/test/resources/cip8Resources.d.ts.map +1 -0
  51. package/dist/test/resources/cip8Resources.js +76 -0
  52. package/dist/test/resources/index.d.ts +435 -0
  53. package/dist/test/resources/index.d.ts.map +1 -0
  54. package/dist/test/resources/index.js +635 -0
  55. package/dist/test/unit/StakingActivateBuilder.d.ts +2 -0
  56. package/dist/test/unit/StakingActivateBuilder.d.ts.map +1 -0
  57. package/dist/test/unit/StakingActivateBuilder.js +213 -0
  58. package/dist/test/unit/StakingDeactivateBuilder.d.ts +2 -0
  59. package/dist/test/unit/StakingDeactivateBuilder.d.ts.map +1 -0
  60. package/dist/test/unit/StakingDeactivateBuilder.js +158 -0
  61. package/dist/test/unit/ada.d.ts +5 -0
  62. package/dist/test/unit/ada.d.ts.map +1 -0
  63. package/dist/test/unit/ada.js +825 -0
  64. package/dist/test/unit/getBuilderFactory.d.ts +3 -0
  65. package/dist/test/unit/getBuilderFactory.d.ts.map +1 -0
  66. package/dist/test/unit/getBuilderFactory.js +10 -0
  67. package/dist/test/unit/index.d.ts +2 -0
  68. package/dist/test/unit/index.d.ts.map +1 -0
  69. package/dist/test/unit/index.js +32 -0
  70. package/dist/test/unit/keyPair.d.ts +2 -0
  71. package/dist/test/unit/keyPair.d.ts.map +1 -0
  72. package/dist/test/unit/keyPair.js +88 -0
  73. package/dist/test/unit/messages/cip8/cip8Message.d.ts +2 -0
  74. package/dist/test/unit/messages/cip8/cip8Message.d.ts.map +1 -0
  75. package/dist/test/unit/messages/cip8/cip8Message.js +131 -0
  76. package/dist/test/unit/messages/cip8/cip8MessageBuilder.d.ts +2 -0
  77. package/dist/test/unit/messages/cip8/cip8MessageBuilder.d.ts.map +1 -0
  78. package/dist/test/unit/messages/cip8/cip8MessageBuilder.js +132 -0
  79. package/dist/test/unit/messages/cip8/utils.d.ts +2 -0
  80. package/dist/test/unit/messages/cip8/utils.d.ts.map +1 -0
  81. package/dist/test/unit/messages/cip8/utils.js +127 -0
  82. package/dist/test/unit/messages/messageBuilderFactory.d.ts +2 -0
  83. package/dist/test/unit/messages/messageBuilderFactory.d.ts.map +1 -0
  84. package/dist/test/unit/messages/messageBuilderFactory.js +35 -0
  85. package/dist/test/unit/stakingClaimRewardsBuilder.d.ts +2 -0
  86. package/dist/test/unit/stakingClaimRewardsBuilder.d.ts.map +1 -0
  87. package/dist/test/unit/stakingClaimRewardsBuilder.js +70 -0
  88. package/dist/test/unit/stakingPledgeBuilder.d.ts +2 -0
  89. package/dist/test/unit/stakingPledgeBuilder.d.ts.map +1 -0
  90. package/dist/test/unit/stakingPledgeBuilder.js +141 -0
  91. package/dist/test/unit/stakingWithdrawBuilder.d.ts +2 -0
  92. package/dist/test/unit/stakingWithdrawBuilder.d.ts.map +1 -0
  93. package/dist/test/unit/stakingWithdrawBuilder.js +167 -0
  94. package/dist/test/unit/tokenWithdrawal.d.ts +2 -0
  95. package/dist/test/unit/tokenWithdrawal.d.ts.map +1 -0
  96. package/dist/test/unit/tokenWithdrawal.js +286 -0
  97. package/dist/test/unit/transaction.d.ts +2 -0
  98. package/dist/test/unit/transaction.d.ts.map +1 -0
  99. package/dist/test/unit/transaction.js +100 -0
  100. package/dist/test/unit/transactionBuilder.d.ts +2 -0
  101. package/dist/test/unit/transactionBuilder.d.ts.map +1 -0
  102. package/dist/test/unit/transactionBuilder.js +454 -0
  103. package/dist/test/unit/utils.d.ts +2 -0
  104. package/dist/test/unit/utils.d.ts.map +1 -0
  105. package/dist/test/unit/utils.js +138 -0
  106. package/dist/test/unit/voteDelegationBuilder.d.ts +2 -0
  107. package/dist/test/unit/voteDelegationBuilder.d.ts.map +1 -0
  108. package/dist/test/unit/voteDelegationBuilder.js +96 -0
  109. package/dist/tsconfig.tsbuildinfo +1 -0
  110. package/package.json +17 -12
  111. package/.eslintignore +0 -5
  112. package/.mocharc.yml +0 -8
  113. package/CHANGELOG.md +0 -322
@@ -0,0 +1,825 @@
1
+ "use strict";
2
+ /**
3
+ * @prettier
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ var __importDefault = (this && this.__importDefault) || function (mod) {
39
+ return (mod && mod.__esModule) ? mod : { "default": mod };
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ const should = require("should");
43
+ const crypto_1 = require("crypto");
44
+ const sinon = __importStar(require("sinon"));
45
+ const sdk_test_1 = require("@bitgo-beta/sdk-test");
46
+ const sdk_api_1 = require("@bitgo-beta/sdk-api");
47
+ const resources_1 = require("../resources");
48
+ const _ = __importStar(require("lodash"));
49
+ const src_1 = require("../../src");
50
+ const lib_1 = require("../../src/lib");
51
+ const enum_1 = require("../../../sdk-core/src/account-lib/baseCoin/enum");
52
+ const assert_1 = __importDefault(require("assert"));
53
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
54
+ const nock_1 = __importDefault(require("nock"));
55
+ describe('ADA', function () {
56
+ const coinName = 'ada';
57
+ const tcoinName = 't' + coinName;
58
+ let bitgo;
59
+ let basecoin;
60
+ let newTxPrebuild;
61
+ let newTxParams;
62
+ const txPrebuild = {
63
+ txHex: resources_1.rawTx.unsignedTx,
64
+ txInfo: {},
65
+ };
66
+ const txParams = {
67
+ recipients: [
68
+ {
69
+ address: resources_1.rawTx.outputAddress1.address,
70
+ amount: '5000000',
71
+ },
72
+ {
73
+ address: resources_1.rawTx.outputAddress2.address,
74
+ amount: '248329150',
75
+ },
76
+ ],
77
+ };
78
+ const transactionExplanation = {
79
+ displayOrder: ['id', 'outputAmount', 'changeAmount', 'outputs', 'changeOutputs', 'fee', 'type'],
80
+ id: 'f48f6ea0f75f3f942855cc0edf29e81e1e0724e75f5db8a1575b166fb202176c',
81
+ outputs: [
82
+ {
83
+ address: 'addr_test1qqnnvptrc3rec64q2n9jh572ncu5wvdtt8uvg4g3aj96s5dwu9nj70mlahzglm9939uevupsmj8dcdqv25d5n5r8vw8sn7prey',
84
+ amount: '7823121',
85
+ },
86
+ {
87
+ address: 'addr_test1vr8rakm66rcfv4fcxqykg5lf0yv7lsyk9mvapx369jpvtcgfcuk7f',
88
+ amount: '13041729',
89
+ },
90
+ ],
91
+ outputAmount: '20864850',
92
+ changeOutputs: [],
93
+ changeAmount: '0',
94
+ fee: { fee: '167173' },
95
+ type: 'Transfer',
96
+ certificates: [],
97
+ withdrawals: [],
98
+ pledgeDetails: undefined,
99
+ };
100
+ before(function () {
101
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
102
+ bitgo.initializeTestVars();
103
+ bitgo.safeRegister(coinName, src_1.Ada.createInstance);
104
+ bitgo.safeRegister(tcoinName, src_1.Tada.createInstance);
105
+ basecoin = bitgo.coin(tcoinName);
106
+ newTxPrebuild = () => {
107
+ return _.cloneDeep(txPrebuild);
108
+ };
109
+ newTxParams = () => {
110
+ return _.cloneDeep(txParams);
111
+ };
112
+ });
113
+ it('should instantiate the coin', function () {
114
+ let localBasecoin = bitgo.coin(tcoinName);
115
+ localBasecoin.should.be.an.instanceof(src_1.Tada);
116
+ localBasecoin.getChain().should.equal(tcoinName);
117
+ localBasecoin.getFullName().should.equal('Testnet Ada');
118
+ localBasecoin = bitgo.coin(coinName);
119
+ localBasecoin.should.be.an.instanceof(src_1.Ada);
120
+ localBasecoin.getChain().should.equal(coinName);
121
+ localBasecoin.getFullName().should.equal('Cardano ADA');
122
+ });
123
+ describe('Sign Message', () => {
124
+ it('should be performed', async () => {
125
+ const keyPair = new src_1.KeyPair();
126
+ const messageToSign = Buffer.from((0, crypto_1.randomBytes)(32)).toString('hex');
127
+ const signature = await basecoin.signMessage(keyPair.getKeys(), messageToSign);
128
+ keyPair.verifySignature(messageToSign, Uint8Array.from(signature)).should.equals(false);
129
+ });
130
+ it('should fail with missing private key', async () => {
131
+ const keyPair = new src_1.KeyPair({
132
+ pub: '7788327c695dca4b3e649a0db45bc3e703a2c67428fce360e61800cc4248f4f7',
133
+ }).getKeys();
134
+ const messageToSign = Buffer.from((0, crypto_1.randomBytes)(32)).toString('hex');
135
+ await basecoin.signMessage(keyPair, messageToSign).should.be.rejectedWith('Invalid key pair options');
136
+ });
137
+ });
138
+ describe('Sign transaction', () => {
139
+ it('should sign transaction', async function () {
140
+ const signed = await basecoin.signTransaction({
141
+ txPrebuild: {
142
+ txHex: resources_1.rawTx.unsignedTx2,
143
+ },
144
+ pubs: [resources_1.publicKeys.pubKey1],
145
+ prv: resources_1.privateKeys.prvKey4,
146
+ });
147
+ signed.txHex.should.equal(resources_1.rawTx.signedTx2);
148
+ });
149
+ it('should fail to sign transaction with an invalid key', async function () {
150
+ try {
151
+ await basecoin.signTransaction({
152
+ txPrebuild: {
153
+ txHex: resources_1.rawTx.unsignedTx2,
154
+ },
155
+ pubs: [resources_1.publicKeys.pubKey1],
156
+ prv: resources_1.privateKeys.prvKey2,
157
+ });
158
+ }
159
+ catch (e) {
160
+ should.equal(e.message, 'Private key cannot sign the transaction');
161
+ }
162
+ });
163
+ it('should fail to build transaction with missing params', async function () {
164
+ try {
165
+ await basecoin.signTransaction({
166
+ txPrebuild: {
167
+ txHex: resources_1.rawTx.unsignedTx,
168
+ key: resources_1.enterpriseAccounts.account1.publicKey,
169
+ },
170
+ prv: resources_1.enterpriseAccounts.account1.secretKey,
171
+ });
172
+ }
173
+ catch (e) {
174
+ should.notEqual(e, null);
175
+ }
176
+ });
177
+ });
178
+ describe('Generate wallet key pair: ', () => {
179
+ it('should generate key pair', () => {
180
+ const kp = basecoin.generateKeyPair();
181
+ basecoin.isValidPub(kp.pub).should.equal(true);
182
+ basecoin.isValidPrv(kp.prv).should.equal(true);
183
+ });
184
+ it('should generate key pair from seed', () => {
185
+ const seed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
186
+ const kp = basecoin.generateKeyPair(seed);
187
+ basecoin.isValidPub(kp.pub).should.equal(true);
188
+ basecoin.isValidPrv(kp.prv).should.equal(true);
189
+ });
190
+ });
191
+ describe('Verify transaction: ', () => {
192
+ it('should succeed to verify unsigned transaction in hex encoding', async () => {
193
+ const txParams = newTxParams();
194
+ const txPrebuild = newTxPrebuild();
195
+ const verification = {};
196
+ const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, verification });
197
+ isTransactionVerified.should.equal(true);
198
+ });
199
+ it('should succeed to verify signed transaction in hex encoding', async () => {
200
+ const txPrebuild = {
201
+ txHex: resources_1.rawTx.signedTx,
202
+ txInfo: {},
203
+ };
204
+ const txParams = newTxParams();
205
+ const verification = {};
206
+ const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, verification });
207
+ isTransactionVerified.should.equal(true);
208
+ });
209
+ it('should fail verify transactions when have different recipients', async () => {
210
+ const txPrebuild = newTxPrebuild();
211
+ const txParams = {
212
+ recipients: [
213
+ {
214
+ address: '9f7b0675db59d19b4bd9c8c72eaabba75a9863d02b30115b8b3c3ca5c20f0254',
215
+ amount: '1000000000000000000000000',
216
+ },
217
+ {
218
+ address: '9f7b0675db59d19b4bd9c8c72eaabba75a9863d02b30115b8b3c3ca5c20f0254',
219
+ amount: '2000000000000000000000000',
220
+ },
221
+ ],
222
+ };
223
+ const verification = {};
224
+ await basecoin
225
+ .verifyTransaction({ txParams, txPrebuild, verification })
226
+ .should.be.rejectedWith('cannot find recipient in expected output');
227
+ });
228
+ it('should verify when input `recipients` is absent', async function () {
229
+ const txParams = newTxParams();
230
+ txParams.recipients = undefined;
231
+ const txPrebuild = newTxPrebuild();
232
+ const validTransaction = await basecoin.verifyTransaction({ txParams, txPrebuild });
233
+ validTransaction.should.equal(true);
234
+ });
235
+ it('should fail verify when txHex is invalid', async function () {
236
+ const txParams = newTxParams();
237
+ txParams.recipients = undefined;
238
+ const txPrebuild = {};
239
+ await basecoin
240
+ .verifyTransaction({ txParams, txPrebuild })
241
+ .should.rejectedWith('missing required tx prebuild property txHex');
242
+ });
243
+ it('should succeed to verify transactions when recipients has extra data', async function () {
244
+ const txPrebuild = newTxPrebuild();
245
+ const txParams = newTxParams();
246
+ txParams.data = 'data';
247
+ const validTransaction = await basecoin.verifyTransaction({ txParams, txPrebuild });
248
+ validTransaction.should.equal(true);
249
+ });
250
+ it('should verify a valid consolidation transaction', async () => {
251
+ const consolidationTx = {
252
+ txRequestId: '1b5c79c5-ab7c-4f47-912b-de6a95fb0779',
253
+ walletId: '64fa31a94db65a0007c9691b',
254
+ txHex: '84a40081825820db46c7c76ea54fec2ca0a2f94b77a238931a8dce2387c99a12b08dd8aac21c4f000181825839004601fc016ac38580916d3520bc76b659298156008738d347aa93142f4601fc016ac38580916d3520bc76b659298156008738d347aa93142f1a3b984357021a000286a9031a060e37eea0f5f6',
255
+ feeInfo: {
256
+ fee: 165545,
257
+ feeString: '165545',
258
+ },
259
+ txInfo: {
260
+ minerFee: '165545',
261
+ spendAmount: '999834455',
262
+ spendAmounts: [
263
+ {
264
+ coinName: 'tada',
265
+ amountString: '999834455',
266
+ },
267
+ ],
268
+ payGoFee: '0',
269
+ outputs: [
270
+ {
271
+ address: 'addr_test1qprqrlqpdtpctqy3d56jp0rkkevjnq2kqzrn356842f3gt6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsjdmg2s',
272
+ value: 999834455,
273
+ wallet: '64fa31a94db65a0007c9691b',
274
+ wallets: ['64fa31a94db65a0007c9691b'],
275
+ enterprise: '62cc59b727443a0007089033',
276
+ enterprises: ['62cc59b727443a0007089033'],
277
+ valueString: '999834455',
278
+ coinName: 'tada',
279
+ walletType: 'hot',
280
+ walletTypes: ['hot'],
281
+ },
282
+ ],
283
+ inputs: [
284
+ {
285
+ value: 1000000000,
286
+ address: 'addr_test1qqlzxfl7tlgp999x4a7334pchycpkk72pykrsr3mryl3yj6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsvpgl8w',
287
+ valueString: '1000000000',
288
+ },
289
+ ],
290
+ type: '0',
291
+ },
292
+ consolidateId: '68b9fc18558006aab53785615fea7c28',
293
+ coin: 'tada',
294
+ };
295
+ const mockedWallet = {
296
+ coinSpecific: () => {
297
+ return {
298
+ rootAddress: 'addr_test1qprqrlqpdtpctqy3d56jp0rkkevjnq2kqzrn356842f3gt6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsjdmg2s',
299
+ };
300
+ },
301
+ };
302
+ try {
303
+ const isVerified = await basecoin.verifyTransaction({
304
+ txParams: {},
305
+ txPrebuild: consolidationTx,
306
+ wallet: mockedWallet,
307
+ verification: {
308
+ consolidationToBaseAddress: true,
309
+ },
310
+ });
311
+ isVerified.should.equal(true);
312
+ }
313
+ catch (e) {
314
+ assert_1.default.fail('Transaction should pass verification');
315
+ }
316
+ });
317
+ it('should fail to sign a spoofed consolidation transaction', async function () {
318
+ // Set up wallet data
319
+ const walletData = {
320
+ id: '5b34252f1bf349930e34020a00000000',
321
+ coin: 'tada',
322
+ keys: [
323
+ '5b3424f91bf349930e34017500000000',
324
+ '5b3424f91bf349930e34017600000000',
325
+ '5b3424f91bf349930e34017700000000',
326
+ ],
327
+ coinSpecific: {
328
+ rootAddress: 'addr_test1qprqrlqpdtpctqy3d56jp0rkkevjnq2kqzrn356842f3gt6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsjdmg2s',
329
+ },
330
+ multisigType: 'tss',
331
+ };
332
+ const fakePrv = (0, sdk_api_1.encrypt)('password', 'prv');
333
+ const walletObj = new sdk_core_1.Wallet(bitgo, basecoin, walletData);
334
+ const bgUrl = sdk_core_1.common.Environments['mock'].uri;
335
+ (0, nock_1.default)(bgUrl)
336
+ .get('/api/v2/tada/key/5b3424f91bf349930e34017500000000')
337
+ .reply(200, [
338
+ {
339
+ encryptedPrv: fakePrv,
340
+ },
341
+ ]);
342
+ // Mock the API response for buildAccountConsolidations
343
+ (0, nock_1.default)(bgUrl)
344
+ .post('/api/v2/tada/wallet/5b34252f1bf349930e34020a00000000/consolidateAccount/build')
345
+ .reply(200, [
346
+ {
347
+ txRequestId: '1b5c79c5-ab7c-4f47-912b-de6a95fb0779',
348
+ walletId: '64fa31a94db65a0007c9691b',
349
+ txHex: '84a40081825820db46c7c76ea54fec2ca0a2f94b77a238931a8dce2387c99a12b08dd8aac21c4f01018282581d6033c378cee41b2e15ac848f7f6f1d2f78155ab12d93b713de898d855f1a00989680825839004601fc016ac38580916d3520bc76b659298156008738d347aa93142f4601fc016ac38580916d3520bc76b659298156008738d347aa93142f1b0000000217acebe9021a00028db5031a060e3b41a0f5f6',
350
+ feeInfo: {
351
+ fee: 165545,
352
+ feeString: '165545',
353
+ },
354
+ txInfo: {
355
+ minerFee: '165545',
356
+ spendAmount: '999834455',
357
+ spendAmounts: [
358
+ {
359
+ coinName: 'tada',
360
+ amountString: '999834455',
361
+ },
362
+ ],
363
+ payGoFee: '0',
364
+ outputs: [
365
+ {
366
+ address: 'addr_test1qprqrlqpdtpctqy3d56jp0rkkevjnq2kqzrn356842f3gt6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsjdmg2s',
367
+ value: 999834455,
368
+ wallet: '64fa31a94db65a0007c9691b',
369
+ wallets: ['64fa31a94db65a0007c9691b'],
370
+ enterprise: '62cc59b727443a0007089033',
371
+ enterprises: ['62cc59b727443a0007089033'],
372
+ valueString: '999834455',
373
+ coinName: 'tada',
374
+ walletType: 'hot',
375
+ walletTypes: ['hot'],
376
+ },
377
+ ],
378
+ inputs: [
379
+ {
380
+ value: 1000000000,
381
+ address: 'addr_test1qqlzxfl7tlgp999x4a7334pchycpkk72pykrsr3mryl3yj6xq87qz6krskqfzmf4yz78ddje9xq4vqy88rf5025nzshsvpgl8w',
382
+ valueString: '1000000000',
383
+ },
384
+ ],
385
+ type: '0',
386
+ },
387
+ consolidateId: '68b9fc18558006aab53785615fea7c28',
388
+ coin: 'tada',
389
+ },
390
+ ]);
391
+ // Call the function to test
392
+ await assert_1.default.rejects(async () => {
393
+ await walletObj.sendAccountConsolidations({
394
+ walletPassphrase: 'password',
395
+ });
396
+ }, {
397
+ message: 'tx outputs does not match with expected address',
398
+ });
399
+ });
400
+ });
401
+ describe('Explain Transactions:', () => {
402
+ it('should explain an unsigned transfer transaction', async function () {
403
+ const explainedTransaction = await basecoin.explainTransaction({
404
+ txPrebuild: {
405
+ txHex: resources_1.rawTx.unsignedTx2,
406
+ },
407
+ });
408
+ console.log(explainedTransaction);
409
+ explainedTransaction.should.deepEqual(transactionExplanation);
410
+ });
411
+ it('should fail to explain transaction with missing params', async function () {
412
+ try {
413
+ await basecoin.explainTransaction({
414
+ txPrebuild: {},
415
+ });
416
+ }
417
+ catch (error) {
418
+ should.equal(error.message, 'Invalid transaction');
419
+ }
420
+ });
421
+ it('should fail to explain transaction with wrong params', async function () {
422
+ try {
423
+ await basecoin.explainTransaction({
424
+ txPrebuild: {
425
+ txHex: 'invalidTxHex',
426
+ },
427
+ });
428
+ }
429
+ catch (error) {
430
+ should.equal(error.message, 'Invalid transaction');
431
+ }
432
+ });
433
+ });
434
+ describe('Parse Raw Transactions', () => {
435
+ it('should parse staking pledge transaction', function () {
436
+ const tx = new lib_1.Transaction(basecoin);
437
+ tx.fromRawTransaction(resources_1.rawTx.unsignedNewPledgeTx);
438
+ should.equal(tx.type, enum_1.TransactionType.StakingPledge);
439
+ });
440
+ it('should parse staking activation tx', function () {
441
+ const tx = new lib_1.Transaction(basecoin);
442
+ tx.fromRawTransaction(resources_1.rawTx.unsignedStakingActiveTx);
443
+ should.equal(tx.type, enum_1.TransactionType.StakingActivate);
444
+ });
445
+ it('should parse staking deactivation tx', function () {
446
+ const tx = new lib_1.Transaction(basecoin);
447
+ tx.fromRawTransaction(resources_1.rawTx.unsignedStakingDeactiveTx);
448
+ should.equal(tx.type, enum_1.TransactionType.StakingDeactivate);
449
+ });
450
+ });
451
+ describe('Parse Transactions:', () => {
452
+ it('should parse an unsigned transfer transaction', async function () {
453
+ const parsedTransaction = await basecoin.parseTransaction({
454
+ txPrebuild: {
455
+ txHex: resources_1.rawTx.unsignedTx2,
456
+ },
457
+ });
458
+ parsedTransaction.should.deepEqual(transactionExplanation);
459
+ });
460
+ it('should parse a signed transfer transaction', async function () {
461
+ const parsedTransaction = await basecoin.parseTransaction({
462
+ txPrebuild: {
463
+ txHex: resources_1.rawTx.signedTx2,
464
+ },
465
+ });
466
+ parsedTransaction.should.deepEqual(transactionExplanation);
467
+ });
468
+ it('should fail parse a signed transfer transaction when explainTransaction response is undefined', async function () {
469
+ const stub = sinon.stub(src_1.Ada.prototype, 'explainTransaction');
470
+ stub.resolves(undefined);
471
+ await basecoin
472
+ .parseTransaction({
473
+ txPrebuild: {
474
+ txHex: resources_1.rawTx.signedTx,
475
+ },
476
+ })
477
+ .should.be.rejectedWith('Invalid transaction');
478
+ stub.restore();
479
+ });
480
+ });
481
+ describe('Recover Transactions:', () => {
482
+ const destAddr = resources_1.address.address2;
483
+ const sandBox = sinon.createSandbox();
484
+ beforeEach(function () {
485
+ const callBack = sandBox.stub(src_1.Ada.prototype, 'getDataFromNode');
486
+ callBack
487
+ .withArgs('address_info', {
488
+ _addresses: [resources_1.wrwUser.walletAddress0],
489
+ })
490
+ .resolves(resources_1.endpointResponses.addressInfoResponse.OneUTXO);
491
+ callBack.withArgs('tip').resolves(resources_1.endpointResponses.tipInfoResponse);
492
+ });
493
+ afterEach(function () {
494
+ sandBox.restore();
495
+ });
496
+ it('should take OVC output and generate a signed sweep transaction', async function () {
497
+ const params = resources_1.ovcResponse;
498
+ const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
499
+ recoveryTxn.transactions[0].serializedTx.should.equal('84a400818258204bd0f991c1532cffe31d4a10db492b43175ec326765b6b29ceee598df2b61f470001818258390087379ebc5533ebe621963c915c3cbc5f08537fcdca4af8f8ae08ed4c87379ebc5533ebe621963c915c3cbc5f08537fcdca4af8f8ae08ed4c1a05f359ff021a00028701031a024972e1a10081825820bbacb13431b99208e6e8cdbf710147feaf06a39d71565e60b411ce9e4fa3f137584001a4ab8236563f69ff309e5786e8f39c629ed57676c692159cb2e0494c9e663355384c13c749d04c17a80ba2a45cc127df480fc64a43199a772f11acd5b14a0ff5f6');
500
+ recoveryTxn.transactions[0].scanIndex.should.equal(0);
501
+ recoveryTxn.lastScanIndex.should.equal(0);
502
+ });
503
+ it('should take consolidation OVC output and generate multiple signed sweep transactions', async function () {
504
+ const params = resources_1.ovcResponse2;
505
+ const recoveryTxn = await basecoin.createBroadcastableSweepTransaction(params);
506
+ recoveryTxn.transactions[0].serializedTx.should.equal('84a400818258203e62e5ee8b12012c4b949f9777b72165239bb2146ae8b078b4d1c5ca8d3168e300018182583900baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd08004baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd080041a00960f7f021a00028701031a0250f7eaa10081825820500e0d725a5ba3a306da3503dfe57b8a14068a09b61b36ec068fcf8cf5c391de5840c836ce6d3262d5654706ea06721522d3b75f6d545245047a7be7463629d88b3f4264b995f591df52bdffcf09da1e6ab9e88de3714c6e2ec1961786cf1c586a07f5f6');
507
+ recoveryTxn.transactions[0].scanIndex.should.equal(1);
508
+ recoveryTxn.transactions[1].serializedTx.should.equal('84a4008182582029c10acf0e08f9523325c88243565af6b32274992189c1153903c410bed7c2c700018182583900baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd08004baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd080041a00960f7f021a00028701031a0250f7eaa1008182582062770b224bd314bc526fbd6a94e9082fb6458c425e6e09bad74004dd897e962358403842544f2ff28be054eb7c7997bc303b1e251eb13a41802c82318e592bb24eaa3197c450e797cc8559f0356cd5cdd1ab5eb80c5173e34e9e1d1737533a89520cf5f6');
509
+ recoveryTxn.transactions[1].scanIndex.should.equal(2);
510
+ recoveryTxn.transactions[2].serializedTx.should.equal('84a40081825820dd140f133d865e1bb5642e708fe685bf7601d71d0c99511e5d552da7f8bd10ff00018182583900baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd08004baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd080041a00960f7f021a00028701031a0250f7eaa1008182582053b4bb74aa38add458dafc8153f0aa8266acad59322b877ca9c23c5d3873779d5840e94ce7896957d094c6bafbf2ec10df5ebb0f1d2a27a7e31f2d45c531fb687edd6c4d33f8e9b99c7692b6fac6d8399bd8fd47641baae9bbb69f518d42ad11710af5f6');
511
+ recoveryTxn.transactions[2].scanIndex.should.equal(3);
512
+ recoveryTxn.transactions[3].serializedTx.should.equal('84a4008182582015a1d6db5d3f592aa1cda185b6359ca0e2921c3c51959f64222a6b7d95d3392300018182583900baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd08004baf55ebcf9ada1b8ecb1640880fba54d2817690f12b3a106afd080041a00960f7f021a00028701031a0250f7eaa10081825820600f86ca22d670f0a990ade4e882c05e654343263494735a31517de0819676735840fe199f8e247a4cfabfeb4f9cb574aa35739a0aa98860ee0a85d720c4ab4fecfac7b4504df310b3e4bea04711f60652d4a8cf5eb41817293b8d29977fe695f704f5f6');
513
+ recoveryTxn.transactions[3].scanIndex.should.equal(4);
514
+ recoveryTxn.lastScanIndex.should.equal(20);
515
+ });
516
+ it('should recover a txn for non-bitgo recoveries', async function () {
517
+ const res = await basecoin.recover({
518
+ userKey: resources_1.wrwUser.userKey,
519
+ backupKey: resources_1.wrwUser.backupKey,
520
+ bitgoKey: resources_1.wrwUser.bitgoKey,
521
+ walletPassphrase: resources_1.wrwUser.walletPassphrase,
522
+ recoveryDestination: destAddr,
523
+ });
524
+ res.should.not.be.empty();
525
+ res.should.hasOwnProperty('serializedTx');
526
+ sandBox.assert.calledTwice(basecoin.getDataFromNode);
527
+ const tx = new lib_1.Transaction(basecoin);
528
+ tx.fromRawTransaction(res.serializedTx);
529
+ const txJson = tx.toJson();
530
+ const fee = Number(tx.explainTransaction().fee.fee);
531
+ should.deepEqual(txJson.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_1.tx_hash);
532
+ should.deepEqual(txJson.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_1.tx_index);
533
+ should.deepEqual(txJson.outputs[0].address, destAddr);
534
+ should.deepEqual(Number(txJson.outputs[0].amount) + fee, resources_1.testnetUTXO.UTXO_1.value);
535
+ });
536
+ it('should recover a txn for unsigned sweep recoveries', async function () {
537
+ const res = await basecoin.recover({
538
+ bitgoKey: resources_1.wrwUser.bitgoKey,
539
+ recoveryDestination: destAddr,
540
+ });
541
+ res.should.not.be.empty();
542
+ res.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('serializedTx');
543
+ sandBox.assert.calledTwice(basecoin.getDataFromNode);
544
+ const tx = new lib_1.Transaction(basecoin);
545
+ tx.fromRawTransaction(res.txRequests[0].transactions[0].unsignedTx.serializedTx);
546
+ const txJson = tx.toJson();
547
+ const fee = Number(tx.explainTransaction().fee.fee);
548
+ should.deepEqual(txJson.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_1.tx_hash);
549
+ should.deepEqual(txJson.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_1.tx_index);
550
+ should.deepEqual(txJson.outputs[0].address, destAddr);
551
+ should.deepEqual(Number(txJson.outputs[0].amount) + fee, resources_1.testnetUTXO.UTXO_1.value);
552
+ });
553
+ });
554
+ describe('Recover Transactions Multiple UTXO:', () => {
555
+ const destAddr = resources_1.address.address2;
556
+ const sandBox = sinon.createSandbox();
557
+ beforeEach(function () {
558
+ const callBack = sandBox.stub(src_1.Ada.prototype, 'getDataFromNode');
559
+ callBack
560
+ .withArgs('address_info', {
561
+ _addresses: [resources_1.wrwUser.walletAddress0],
562
+ })
563
+ .resolves(resources_1.endpointResponses.addressInfoResponse.TwoUTXO);
564
+ callBack.withArgs('tip').resolves(resources_1.endpointResponses.tipInfoResponse);
565
+ });
566
+ afterEach(function () {
567
+ sandBox.restore();
568
+ });
569
+ it('should recover a txn for non-bitgo recoveries', async function () {
570
+ const res = await basecoin.recover({
571
+ userKey: resources_1.wrwUser.userKey,
572
+ backupKey: resources_1.wrwUser.backupKey,
573
+ bitgoKey: resources_1.wrwUser.bitgoKey,
574
+ walletPassphrase: resources_1.wrwUser.walletPassphrase,
575
+ recoveryDestination: destAddr,
576
+ });
577
+ res.should.not.be.empty();
578
+ res.should.hasOwnProperty('serializedTx');
579
+ sandBox.assert.calledTwice(basecoin.getDataFromNode);
580
+ const tx = new lib_1.Transaction(basecoin);
581
+ tx.fromRawTransaction(res.serializedTx);
582
+ const txJson = tx.toJson();
583
+ const fee = Number(tx.explainTransaction().fee.fee);
584
+ should.deepEqual(txJson.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_1.tx_hash);
585
+ should.deepEqual(txJson.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_1.tx_index);
586
+ should.deepEqual(txJson.inputs[1].transaction_id, resources_1.testnetUTXO.UTXO_2.tx_hash);
587
+ should.deepEqual(txJson.inputs[1].transaction_index, resources_1.testnetUTXO.UTXO_2.tx_index);
588
+ should.deepEqual(txJson.outputs[0].address, destAddr);
589
+ should.deepEqual(Number(txJson.outputs[0].amount) + fee, resources_1.testnetUTXO.UTXO_1.value + resources_1.testnetUTXO.UTXO_2.value);
590
+ });
591
+ it('should recover a txn for unsigned sweep recoveries', async function () {
592
+ const res = await basecoin.recover({
593
+ bitgoKey: resources_1.wrwUser.bitgoKey,
594
+ recoveryDestination: destAddr,
595
+ });
596
+ res.should.not.be.empty();
597
+ res.txRequests[0].transactions[0].unsignedTx.should.hasOwnProperty('serializedTx');
598
+ sandBox.assert.calledTwice(basecoin.getDataFromNode);
599
+ const tx = new lib_1.Transaction(basecoin);
600
+ tx.fromRawTransaction(res.txRequests[0].transactions[0].unsignedTx.serializedTx);
601
+ const txJson = tx.toJson();
602
+ const fee = Number(tx.explainTransaction().fee.fee);
603
+ should.deepEqual(txJson.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_1.tx_hash);
604
+ should.deepEqual(txJson.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_1.tx_index);
605
+ should.deepEqual(txJson.inputs[1].transaction_id, resources_1.testnetUTXO.UTXO_2.tx_hash);
606
+ should.deepEqual(txJson.inputs[1].transaction_index, resources_1.testnetUTXO.UTXO_2.tx_index);
607
+ should.deepEqual(txJson.outputs[0].address, destAddr);
608
+ should.deepEqual(Number(txJson.outputs[0].amount) + fee, resources_1.testnetUTXO.UTXO_1.value + resources_1.testnetUTXO.UTXO_2.value);
609
+ });
610
+ });
611
+ describe('Build Consolidation Recoveries:', () => {
612
+ const baseAddr = resources_1.consolidationWrwUser.walletAddress0;
613
+ const sandBox = sinon.createSandbox();
614
+ beforeEach(function () {
615
+ const callBack = sandBox.stub(src_1.Ada.prototype, 'getDataFromNode');
616
+ callBack
617
+ .withArgs('address_info', {
618
+ _addresses: [resources_1.consolidationWrwUser.walletAddress1],
619
+ })
620
+ .resolves(resources_1.endpointResponses.addressInfoResponse.ZeroUTXO);
621
+ callBack
622
+ .withArgs('address_info', {
623
+ _addresses: [resources_1.consolidationWrwUser.walletAddress2],
624
+ })
625
+ .resolves(resources_1.endpointResponses.addressInfoResponse.OneUTXO);
626
+ callBack
627
+ .withArgs('address_info', {
628
+ _addresses: [resources_1.consolidationWrwUser.walletAddress3],
629
+ })
630
+ .resolves(resources_1.endpointResponses.addressInfoResponse.OneUTXO2);
631
+ callBack.withArgs('tip').resolves(resources_1.endpointResponses.tipInfoResponse);
632
+ });
633
+ afterEach(function () {
634
+ sandBox.restore();
635
+ });
636
+ it('should build signed consolidation recoveries', async function () {
637
+ const res = await basecoin.recoverConsolidations({
638
+ userKey: resources_1.consolidationWrwUser.userKey,
639
+ backupKey: resources_1.consolidationWrwUser.backupKey,
640
+ bitgoKey: resources_1.consolidationWrwUser.bitgoKey,
641
+ walletPassphrase: resources_1.consolidationWrwUser.walletPassphrase,
642
+ startingScanIndex: 1,
643
+ endingScanIndex: 4,
644
+ });
645
+ res.should.not.be.empty();
646
+ res.transactions.length.should.equal(2);
647
+ res.lastScanIndex.should.equal(3);
648
+ const txn1 = res.transactions[0];
649
+ const tx1 = new lib_1.Transaction(basecoin);
650
+ tx1.fromRawTransaction(txn1.serializedTx);
651
+ const txJson1 = tx1.toJson();
652
+ const fee1 = Number(tx1.explainTransaction().fee.fee);
653
+ should.deepEqual(txJson1.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_1.tx_hash);
654
+ should.deepEqual(txJson1.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_1.tx_index);
655
+ should.deepEqual(txJson1.outputs[0].address, baseAddr);
656
+ should.deepEqual(Number(txJson1.outputs[0].amount) + fee1, resources_1.testnetUTXO.UTXO_1.value);
657
+ const txn2 = res.transactions[1];
658
+ const tx2 = new lib_1.Transaction(basecoin);
659
+ tx2.fromRawTransaction(txn2.serializedTx);
660
+ const txJson2 = tx2.toJson();
661
+ const fee2 = Number(tx2.explainTransaction().fee.fee);
662
+ should.deepEqual(txJson2.inputs[0].transaction_id, resources_1.testnetUTXO.UTXO_2.tx_hash);
663
+ should.deepEqual(txJson2.inputs[0].transaction_index, resources_1.testnetUTXO.UTXO_2.tx_index);
664
+ should.deepEqual(txJson2.outputs[0].address, baseAddr);
665
+ should.deepEqual(Number(txJson2.outputs[0].amount) + fee2, resources_1.testnetUTXO.UTXO_2.value);
666
+ });
667
+ it('should skip building consolidate transaction if balance is equal to zero', async function () {
668
+ await basecoin
669
+ .recoverConsolidations({
670
+ userKey: resources_1.consolidationWrwUser.userKey,
671
+ backupKey: resources_1.consolidationWrwUser.backupKey,
672
+ bitgoKey: resources_1.consolidationWrwUser.bitgoKey,
673
+ walletPassphrase: resources_1.consolidationWrwUser.walletPassphrase,
674
+ startingScanIndex: 1,
675
+ endingScanIndex: 2,
676
+ })
677
+ .should.rejectedWith('Did not find an address with funds to recover');
678
+ });
679
+ it('should throw if startingScanIndex is not ge to 1', async () => {
680
+ await basecoin
681
+ .recoverConsolidations({
682
+ userKey: resources_1.consolidationWrwUser.userKey,
683
+ backupKey: resources_1.consolidationWrwUser.backupKey,
684
+ bitgoKey: resources_1.consolidationWrwUser.bitgoKey,
685
+ startingScanIndex: -1,
686
+ })
687
+ .should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: -1, endingScanIndex: 19.');
688
+ });
689
+ it('should throw if scan factor is too high', async () => {
690
+ await basecoin
691
+ .recoverConsolidations({
692
+ userKey: resources_1.consolidationWrwUser.userKey,
693
+ backupKey: resources_1.consolidationWrwUser.backupKey,
694
+ bitgoKey: resources_1.consolidationWrwUser.bitgoKey,
695
+ startingScanIndex: 1,
696
+ endingScanIndex: 300,
697
+ })
698
+ .should.be.rejectedWith('Invalid starting or ending index to scan for addresses. startingScanIndex: 1, endingScanIndex: 300.');
699
+ });
700
+ });
701
+ describe('Recover Transactions Failure:', () => {
702
+ const destAddr = resources_1.address.address2;
703
+ const sandBox = sinon.createSandbox();
704
+ afterEach(function () {
705
+ sandBox.restore();
706
+ });
707
+ it('should fail to recover due to not finding an address with funds', async function () {
708
+ const callBack = sandBox.stub(src_1.Ada.prototype, 'getDataFromNode');
709
+ callBack
710
+ .withArgs('address_info', sinon.match.has('_addresses'))
711
+ .resolves(resources_1.endpointResponses.addressInfoResponse.ZeroUTXO);
712
+ callBack.withArgs('tip').resolves(resources_1.endpointResponses.tipInfoResponse);
713
+ await basecoin
714
+ .recover({
715
+ userKey: resources_1.wrwUser.userKey,
716
+ backupKey: resources_1.wrwUser.backupKey,
717
+ bitgoKey: resources_1.wrwUser.bitgoKey,
718
+ walletPassphrase: resources_1.wrwUser.walletPassphrase,
719
+ recoveryDestination: destAddr,
720
+ })
721
+ .should.rejectedWith('Did not find address with funds to recover');
722
+ sandBox.assert.calledOnce(basecoin.getDataFromNode);
723
+ });
724
+ it('should fail to recover due to not having more than 1 ADA in funds', async function () {
725
+ const callBack = sandBox.stub(src_1.Ada.prototype, 'getDataFromNode');
726
+ callBack
727
+ .withArgs('address_info', sinon.match.has('_addresses'))
728
+ .resolves(resources_1.endpointResponses.addressInfoResponse.OneSmallUTXO);
729
+ callBack.withArgs('tip').resolves(resources_1.endpointResponses.tipInfoResponse);
730
+ await basecoin
731
+ .recover({
732
+ userKey: resources_1.wrwUser.userKey,
733
+ backupKey: resources_1.wrwUser.backupKey,
734
+ bitgoKey: resources_1.wrwUser.bitgoKey,
735
+ walletPassphrase: resources_1.wrwUser.walletPassphrase,
736
+ recoveryDestination: destAddr,
737
+ })
738
+ .should.rejectedWith('Insufficient funds to recover, minimum required is 1 ADA plus fees, got 9834455 fees: 165545');
739
+ sandBox.assert.calledTwice(basecoin.getDataFromNode);
740
+ });
741
+ });
742
+ describe('Verify token consolidation transaction:', () => {
743
+ it('should fail to verify a spoofed token consolidation transaction with incorrect address', async () => {
744
+ const consolidationTx = {
745
+ txRequestId: '4fdd0cae-2563-43b1-b5cf-94865158ca10',
746
+ walletId: '63068ed4efa63a000877f02fd4b0fa6d',
747
+ txHex: '84a400818258204bd0f991c1532cffe31d4a10db492b43175ec326765b6b29ceee598df2b61f470001818258390087379ebc5533ebe621963c915c3cbc5f08537fcdca4af8f8ae08ed4c87379ebc5533ebe621963c915c3cbc5f08537fcdca4af8f8ae08ed4c1a05f359ff021a00028701031a024972e1a10081825820bbacb13431b99208e6e8cdbf710147feaf06a39d71565e60b411ce9e4fa3f137584001a4ab8236563f69ff309e5786e8f39c629ed57676c692159cb2e0494c9e663355384c13c749d04c17a80ba2a45cc127df480fc64a43199a772f11acd5b14a0ff5f6',
748
+ feeInfo: {
749
+ fee: 10000,
750
+ feeString: '10000',
751
+ },
752
+ txInfo: {
753
+ inputs: [
754
+ {
755
+ address: '8iLa26KSbdpBUzNK7uYq8FvyuyA5h4k4erDHsDcPbHus',
756
+ value: 2.0173228e10,
757
+ valueString: '20173228000',
758
+ },
759
+ {
760
+ address: '8P2kX7Tyh9eS3RKdaBhqbEtQGAX58DXzL7mhDQABGX2d',
761
+ value: 10000,
762
+ valueString: '10000',
763
+ },
764
+ ],
765
+ minerFee: '10000',
766
+ outputs: [
767
+ {
768
+ address: 'addr_test1vr8rakm66rcfv4fcxqykg5lf0yv7lsyk9mvapx369jpvtcgfcuk7f',
769
+ coinName: 'tada:usdt',
770
+ enterprise: {
771
+ $oid: '5553ba8ae7a5c77006719661',
772
+ },
773
+ enterprises: [
774
+ {
775
+ $oid: '5553ba8ae7a5c77006719661',
776
+ },
777
+ ],
778
+ value: 2.0173228e10,
779
+ valueString: '20173228000',
780
+ wallet: {
781
+ $oid: '62f4c3720d92c50008257eb5',
782
+ },
783
+ walletType: 'hot',
784
+ wallets: [
785
+ {
786
+ $oid: '62f4c3720d92c50008257eb5',
787
+ },
788
+ ],
789
+ },
790
+ ],
791
+ payGoFee: '0',
792
+ spendAmount: '20173228000',
793
+ spendAmounts: [
794
+ {
795
+ amountString: '20173228000',
796
+ coinName: 'tada:usdt',
797
+ },
798
+ ],
799
+ type: 'Send',
800
+ },
801
+ consolidateId: '6712d7fda6de4906d658c04aebbf8f9b',
802
+ coin: 'tada',
803
+ };
804
+ // Mock the wallet with a different address than the transaction's output
805
+ const mockedWallet = {
806
+ coinSpecific: () => {
807
+ return {
808
+ rootAddress: 'addr_test1qqnnvptrc3rec64q2n9jh572ncu5wvdtt8uvg4g3aj96s5dwu9nj70mlahzglm9939uevupsmj8dcdqv25d5n5r8vw8sn7prey',
809
+ };
810
+ },
811
+ };
812
+ await basecoin
813
+ .verifyTransaction({
814
+ txParams: {},
815
+ txPrebuild: consolidationTx,
816
+ wallet: mockedWallet,
817
+ verification: {
818
+ consolidationToBaseAddress: true,
819
+ },
820
+ })
821
+ .should.be.rejectedWith('tx outputs does not match with expected address');
822
+ });
823
+ });
824
+ });
825
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L2FkYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7O0dBRUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUgsaUNBQWtDO0FBQ2xDLG1DQUFxQztBQUNyQyw2Q0FBK0I7QUFDL0IsbURBQStEO0FBQy9ELGlEQUF3RDtBQUN4RCw0Q0FZc0I7QUFDdEIsMENBQTRCO0FBQzVCLG1DQUErQztBQUMvQyx1Q0FBNEM7QUFDNUMsMEVBQWtGO0FBQ2xGLG9EQUE0QjtBQUM1QixtREFBc0Q7QUFDdEQsZ0RBQXdCO0FBRXhCLFFBQVEsQ0FBQyxLQUFLLEVBQUU7SUFDZCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDdkIsTUFBTSxTQUFTLEdBQUcsR0FBRyxHQUFHLFFBQVEsQ0FBQztJQUNqQyxJQUFJLEtBQW1CLENBQUM7SUFDeEIsSUFBSSxRQUFRLENBQUM7SUFDYixJQUFJLGFBQWEsQ0FBQztJQUNsQixJQUFJLFdBQVcsQ0FBQztJQUVoQixNQUFNLFVBQVUsR0FBRztRQUNqQixLQUFLLEVBQUUsaUJBQUssQ0FBQyxVQUFVO1FBQ3ZCLE1BQU0sRUFBRSxFQUFFO0tBQ1gsQ0FBQztJQUVGLE1BQU0sUUFBUSxHQUFHO1FBQ2YsVUFBVSxFQUFFO1lBQ1Y7Z0JBQ0UsT0FBTyxFQUFFLGlCQUFLLENBQUMsY0FBYyxDQUFDLE9BQU87Z0JBQ3JDLE1BQU0sRUFBRSxTQUFTO2FBQ2xCO1lBQ0Q7Z0JBQ0UsT0FBTyxFQUFFLGlCQUFLLENBQUMsY0FBYyxDQUFDLE9BQU87Z0JBQ3JDLE1BQU0sRUFBRSxXQUFXO2FBQ3BCO1NBQ0Y7S0FDRixDQUFDO0lBRUYsTUFBTSxzQkFBc0IsR0FBRztRQUM3QixZQUFZLEVBQUUsQ0FBQyxJQUFJLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxNQUFNLENB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RUFDVCw4R0FBOEc7cUJBQ2pILENBQUM7Z0JBQ0osQ0FBQzthQUNGLENBQUM7WUFFRixNQUFNLFFBQVE7aUJBQ1gsaUJBQWlCLENBQUM7Z0JBQ2pCLFFBQVEsRUFBRSxFQUFFO2dCQUNaLFVBQVUsRUFBRSxlQUFlO2dCQUMzQixNQUFNLEVBQUUsWUFBWTtnQkFDcEIsWUFBWSxFQUFFO29CQUNaLDBCQUEwQixFQUFFLElBQUk7aUJBQ2pDO2FBQ0YsQ0FBQztpQkFDRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO1FBQy9FLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHByZXR0aWVyXG4gKi9cblxuaW1wb3J0IHNob3VsZCA9IHJlcXVpcmUoJ3Nob3VsZCcpO1xuaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0ICogYXMgc2lub24gZnJvbSAnc2lub24nO1xuaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHb0FQSSwgZW5jcnlwdCB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1hcGknO1xuaW1wb3J0IHtcbiAgYWRkcmVzcyxcbiAgY29uc29saWRhdGlvbldyd1VzZXIsXG4gIGVuZHBvaW50UmVzcG9uc2VzLFxuICBlbnRlcnByaXNlQWNjb3VudHMgYXMgYWNjb3VudHMsXG4gIG92Y1Jlc3BvbnNlLFxuICBvdmNSZXNwb25zZTIsXG4gIHByaXZhdGVLZXlzLFxuICBwdWJsaWNLZXlzLFxuICByYXdUeCxcbiAgdGVzdG5ldFVUWE8sXG4gIHdyd1VzZXIsXG59IGZyb20gJy4uL3Jlc291cmNlcyc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBBZGEsIEtleVBhaXIsIFRhZGEgfSBmcm9tICcuLi8uLi9zcmMnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb24gfSBmcm9tICcuLi8uLi9zcmMvbGliJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJy4uLy4uLy4uL3Nkay1jb3JlL3NyYy9hY2NvdW50LWxpYi9iYXNlQ29pbi9lbnVtJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IGNvbW1vbiwgV2FsbGV0IH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0IG5vY2sgZnJvbSAnbm9jayc7XG5cbmRlc2NyaWJlKCdBREEnLCBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IGNvaW5OYW1lID0gJ2FkYSc7XG4gIGNvbnN0IHRjb2luTmFtZSA9ICd0JyArIGNvaW5OYW1lO1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luO1xuICBsZXQgbmV3VHhQcmVidWlsZDtcbiAgbGV0IG5ld1R4UGFyYW1zO1xuXG4gIGNvbnN0IHR4UHJlYnVpbGQgPSB7XG4gICAgdHhIZXg6IHJhd1R4LnVuc2lnbmVkVHgsXG4gICAgdHhJbmZvOiB7fSxcbiAgfTtcblxuICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICByZWNpcGllbnRzOiBbXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6IHJhd1R4Lm91dHB1dEFkZHJlc3MxLmFkZHJlc3MsXG4gICAgICAgIGFtb3VudDogJzUwMDAwMDAnLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgYWRkcmVzczogcmF3VHgub3V0cHV0QWRkcmVzczIuYWRkcmVzcyxcbiAgICAgICAgYW1vdW50OiAnMjQ4MzI5MTUwJyxcbiAgICAgIH0sXG4gICAgXSxcbiAgfTtcblxuICBjb25zdCB0cmFuc2FjdGlvbkV4cGxhbmF0aW9uID0ge1xuICAgIGRpc3BsYXlPcmRlcjogWydpZCcsICdvdXRwdXRBbW91bnQnLCAnY2hhbmdlQW1vdW50JywgJ291dHB1dHMnLCAnY2hhbmdlT3V0cHV0cycsICdmZWUnLCAndHlwZSddLFxuICAgIGlkOiAnZjQ4ZjZlYTBmNzVmM2Y5NDI4NTVjYzBlZGYyOWU4MWUxZTA3MjRlNzVmNWRiOGExNTc1YjE2NmZiMjAyMTc2YycsXG4gICAgb3V0cHV0czogW1xuICAgICAge1xuICAgICAgICBhZGRyZXNzOlxuICAgICAgICAgICdhZGRyX3Rlc3QxcXFubnZwdHJjM3JlYzY0cTJuOWpoNTcybmN1NXd2ZHR0OHV2ZzRnM2FqOTZzNWR3dTluajcwbWxhaHpnbG05OTM5dWV2dXBzbWo4ZGNkcXYyNWQ1bjVyOHZ3OHNuN3ByZXknLFxuICAgICAgICBhbW91bnQ6ICc3ODIzMTIxJyxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGFkZHJlc3M6ICdhZGRyX3Rlc3QxdnI4cmFrbTY2cmNmdjRmY3hxeWtnNWxmMHl2N2xzeWs5bXZhcHgzNjlqcHZ0Y2dmY3VrN2YnLFxuICAgICAgICBhbW91bnQ6ICcxMzA0MTcyOScsXG4gICAgICB9LFxuICAgIF0sXG4gICAgb3V0cHV0QW1vdW50OiAnMjA4NjQ4NTAnLFxuICAgIGNoYW5nZU91dHB1dHM6IFtdLFxuICAgIGNoYW5nZUFtb3VudDogJzAnLFxuICAgIGZlZTogeyBmZWU6ICcxNjcxNzMnIH0sXG4gICAgdHlwZTogJ1RyYW5zZmVyJyxcbiAgICBjZXJ0aWZpY2F0ZXM6IFtdLFxuICAgIHdpdGhkcmF3YWxzOiBbXSxcbiAgICBwbGVkZ2VEZXRhaWxzOiB1bmRlZmluZWQsXG4gIH07XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoY29pbk5hbWUsIEFkYS5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYml0Z28uc2FmZVJlZ2lzdGVyKHRjb2luTmFtZSwgVGFkYS5jcmVhdGVJbnN0YW5jZSk7XG4gICAgYmFzZWNvaW4gPSBiaXRnby5jb2luKHRjb2luTmFtZSk7XG4gICAgbmV3VHhQcmVidWlsZCA9ICgpID0+IHtcbiAgICAgIHJldHVybiBfLmNsb25lRGVlcCh0eFByZWJ1aWxkKTtcbiAgICB9O1xuICAgIG5ld1R4UGFyYW1zID0gKCkgPT4ge1xuICAgICAgcmV0dXJuIF8uY2xvbmVEZWVwKHR4UGFyYW1zKTtcbiAgICB9O1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGluc3RhbnRpYXRlIHRoZSBjb2luJywgZnVuY3Rpb24gKCkge1xuICAgIGxldCBsb2NhbEJhc2Vjb2luID0gYml0Z28uY29pbih0Y29pbk5hbWUpO1xuICAgIGxvY2FsQmFzZWNvaW4uc2hvdWxkLmJlLmFuLmluc3RhbmNlb2YoVGFkYSk7XG4gICAgbG9jYWxCYXNlY29pbi5nZXRDaGFpbigpLnNob3VsZC5lcXVhbCh0Y29pbk5hbWUpO1xuICAgIGxvY2FsQmFzZWNvaW4uZ2V0RnVsbE5hbWUoKS5zaG91bGQuZXF1YWwoJ1Rlc3RuZXQgQWRhJyk7XG5cbiAgICBsb2NhbEJhc2Vjb2luID0gYml0Z28uY29pbihjb2luTmFtZSk7XG4gICAgbG9jYWxCYXNlY29pbi5zaG91bGQuYmUuYW4uaW5zdGFuY2VvZihBZGEpO1xuICAgIGxvY2FsQmFzZWNvaW4uZ2V0Q2hhaW4oKS5zaG91bGQuZXF1YWwoY29pbk5hbWUpO1xuICAgIGxvY2FsQmFzZWNvaW4uZ2V0RnVsbE5hbWUoKS5zaG91bGQuZXF1YWwoJ0NhcmRhbm8gQURBJyk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdTaWduIE1lc3NhZ2UnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBiZSBwZXJmb3JtZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBrZXlQYWlyID0gbmV3IEtleVBhaXIoKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VUb1NpZ24gPSBCdWZmZXIuZnJvbShyYW5kb21CeXRlcygzMikpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IGF3YWl0IGJhc2Vjb2luLnNpZ25NZXNzYWdlKGtleVBhaXIuZ2V0S2V5cygpLCBtZXNzYWdlVG9TaWduKTtcbiAgICAgIGtleVBhaXIudmVyaWZ5U2lnbmF0dXJlKG1lc3NhZ2VUb1NpZ24sIFVpbnQ4QXJyYXkuZnJvbShzaWduYXR1cmUpKS5zaG91bGQuZXF1YWxzKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB3aXRoIG1pc3NpbmcgcHJpdmF0ZSBrZXknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBrZXlQYWlyID0gbmV3IEtleVBhaXIoe1xuICAgICAgICBwdWI6ICc3Nzg4MzI3YzY5NWRjYTRiM2U2NDlhMGRiNDViYzNlNzAzYTJjNjc0MjhmY2UzNjBlNjE4MDBjYzQyNDhmNGY3JyxcbiAgICAgIH0pLmdldEtleXMoKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VUb1NpZ24gPSBCdWZmZXIuZnJvbShyYW5kb21CeXRlcygzMikpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGF3YWl0IGJhc2Vjb2luLnNpZ25NZXNzYWdlKGtleVBhaXIsIG1lc3NhZ2VUb1NpZ24pLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0ludmFsaWQga2V5IHBhaXIgb3B0aW9ucycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2lnbiB0cmFuc2FjdGlvbicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHNpZ24gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWduZWQgPSBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHJhd1R4LnVuc2lnbmVkVHgyLFxuICAgICAgICB9LFxuICAgICAgICBwdWJzOiBbcHVibGljS2V5cy5wdWJLZXkxXSxcbiAgICAgICAgcHJ2OiBwcml2YXRlS2V5cy5wcnZLZXk0LFxuICAgICAgfSk7XG4gICAgICBzaWduZWQudHhIZXguc2hvdWxkLmVxdWFsKHJhd1R4LnNpZ25lZFR4Mik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gc2lnbiB0cmFuc2FjdGlvbiB3aXRoIGFuIGludmFsaWQga2V5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgICB0eEhleDogcmF3VHgudW5zaWduZWRUeDIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwdWJzOiBbcHVibGljS2V5cy5wdWJLZXkxXSxcbiAgICAgICAgICBwcnY6IHByaXZhdGVLZXlzLnBydktleTIsXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBzaG91bGQuZXF1YWwoZS5tZXNzYWdlLCAnUHJpdmF0ZSBrZXkgY2Fubm90IHNpZ24gdGhlIHRyYW5zYWN0aW9uJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gYnVpbGQgdHJhbnNhY3Rpb24gd2l0aCBtaXNzaW5nIHBhcmFtcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgdHhIZXg6IHJhd1R4LnVuc2lnbmVkVHgsXG4gICAgICAgICAgICBrZXk6IGFjY291bnRzLmFjY291bnQxLnB1YmxpY0tleSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBydjogYWNjb3VudHMuYWNjb3VudDEuc2VjcmV0S2V5LFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgc2hvdWxkLm5vdEVxdWFsKGUsIG51bGwpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnR2VuZXJhdGUgd2FsbGV0IGtleSBwYWlyOiAnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBrZXkgcGFpcicsICgpID0+IHtcbiAgICAgIGNvbnN0IGtwID0gYmFzZWNvaW4uZ2VuZXJhdGVLZXlQYWlyKCk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHViKGtwLnB1Yikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFBydihrcC5wcnYpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUga2V5IHBhaXIgZnJvbSBzZWVkJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc2VlZCA9IEJ1ZmZlci5mcm9tKCc5ZDYxYjE5ZGVmZmQ1YTYwYmE4NDRhZjQ5MmVjMmNjNDQ0NDljNTY5N2IzMjY5MTk3MDNiYWMwMzFjYWU3ZjYwJywgJ2hleCcpO1xuICAgICAgY29uc3Qga3AgPSBiYXNlY29pbi5nZW5lcmF0ZUtleVBhaXIoc2VlZCk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHViKGtwLnB1Yikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFBydihrcC5wcnYpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1ZlcmlmeSB0cmFuc2FjdGlvbjogJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgc3VjY2VlZCB0byB2ZXJpZnkgdW5zaWduZWQgdHJhbnNhY3Rpb24gaW4gaGV4IGVuY29kaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBjb25zdCBpc1RyYW5zYWN0aW9uVmVyaWZpZWQgPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkLCB2ZXJpZmljYXRpb24gfSk7XG4gICAgICBpc1RyYW5zYWN0aW9uVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSBzaWduZWQgdHJhbnNhY3Rpb24gaW4gaGV4IGVuY29kaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IHtcbiAgICAgICAgdHhIZXg6IHJhd1R4LnNpZ25lZFR4LFxuICAgICAgICB0eEluZm86IHt9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgdHhQYXJhbXMgPSBuZXdUeFBhcmFtcygpO1xuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uID0ge307XG5cbiAgICAgIGNvbnN0IGlzVHJhbnNhY3Rpb25WZXJpZmllZCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHsgdHhQYXJhbXMsIHR4UHJlYnVpbGQsIHZlcmlmaWNhdGlvbiB9KTtcbiAgICAgIGlzVHJhbnNhY3Rpb25WZXJpZmllZC5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdmVyaWZ5IHRyYW5zYWN0aW9ucyB3aGVuIGhhdmUgZGlmZmVyZW50IHJlY2lwaWVudHMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0gbmV3VHhQcmVidWlsZCgpO1xuXG4gICAgICBjb25zdCB0eFBhcmFtcyA9IHtcbiAgICAgICAgcmVjaXBpZW50czogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGFkZHJlc3M6ICc5ZjdiMDY3NWRiNTlkMTliNGJkOWM4YzcyZWFhYmJhNzVhOTg2M2QwMmIzMDExNWI4YjNjM2NhNWMyMGYwMjU0JyxcbiAgICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWRkcmVzczogJzlmN2IwNjc1ZGI1OWQxOWI0YmQ5YzhjNzJlYWFiYmE3NWE5ODYzZDAyYjMwMTE1YjhiM2MzY2E1YzIwZjAyNTQnLFxuICAgICAgICAgICAgYW1vdW50OiAnMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWNhdGlvbiA9IHt9O1xuXG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCwgdmVyaWZpY2F0aW9uIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdjYW5ub3QgZmluZCByZWNpcGllbnQgaW4gZXhwZWN0ZWQgb3V0cHV0Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSB3aGVuIGlucHV0IGByZWNpcGllbnRzYCBpcyBhYnNlbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eFBhcmFtcyA9IG5ld1R4UGFyYW1zKCk7XG4gICAgICB0eFBhcmFtcy5yZWNpcGllbnRzID0gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkIH0pO1xuICAgICAgdmFsaWRUcmFuc2FjdGlvbi5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdmVyaWZ5IHdoZW4gdHhIZXggaXMgaW52YWxpZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIHR4UGFyYW1zLnJlY2lwaWVudHMgPSB1bmRlZmluZWQ7XG4gICAgICBjb25zdCB0eFByZWJ1aWxkID0ge307XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAudmVyaWZ5VHJhbnNhY3Rpb24oeyB0eFBhcmFtcywgdHhQcmVidWlsZCB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnbWlzc2luZyByZXF1aXJlZCB0eCBwcmVidWlsZCBwcm9wZXJ0eSB0eEhleCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzdWNjZWVkIHRvIHZlcmlmeSB0cmFuc2FjdGlvbnMgd2hlbiByZWNpcGllbnRzIGhhcyBleHRyYSBkYXRhJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHhQcmVidWlsZCA9IG5ld1R4UHJlYnVpbGQoKTtcbiAgICAgIGNvbnN0IHR4UGFyYW1zID0gbmV3VHhQYXJhbXMoKTtcbiAgICAgIHR4UGFyYW1zLmRhdGEgPSAnZGF0YSc7XG5cbiAgICAgIGNvbnN0IHZhbGlkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi52ZXJpZnlUcmFuc2FjdGlvbih7IHR4UGFyYW1zLCB0eFByZWJ1aWxkIH0pO1xuICAgICAgdmFsaWRUcmFuc2FjdGlvbi5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBhIHZhbGlkIGNvbnNvbGlkYXRpb24gdHJhbnNhY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjb25zb2xpZGF0aW9uVHggPSB7XG4gICAgICAgIHR4UmVxdWVzdElkOiAnMWI1Yzc5YzUtYWI3Yy00ZjQ3LTkxMmItZGU2YTk1ZmIwNzc5JyxcbiAgICAgICAgd2FsbGV0SWQ6ICc2NGZhMzFhOTRkYjY1YTAwMDdjOTY5MWInLFxuICAgICAgICB0eEhleDpcbiAgICAgICAgICAnODRhNDAwODE4MjU4MjBkYjQ2YzdjNzZlYTU0ZmVjMmNhMGEyZjk0Yjc3YTIzODkzMWE4ZGNlMjM4N2M5OWExMmIwOGRkOGFhYzIxYzRmMDAwMTgxODI1ODM5MDA0NjAxZmMwMTZhYzM4NTgwOTE2ZDM1MjBiYzc2YjY1OTI5ODE1NjAwODczOGQzNDdhYTkzMTQyZjQ2MDFmYzAxNmFjMzg1ODA5MTZkMzUyMGJjNzZiNjU5Mjk4MTU2MDA4NzM4ZDM0N2FhOTMxNDJmMWEzYjk4NDM1NzAyMWEwMDAyODZhOTAzMWEwNjBlMzdlZWEwZjVmNicsXG4gICAgICAgIGZlZUluZm86IHtcbiAgICAgICAgICBmZWU6IDE2NTU0NSxcbiAgICAgICAgICBmZWVTdHJpbmc6ICcxNjU1NDUnLFxuICAgICAgICB9LFxuICAgICAgICB0eEluZm86IHtcbiAgICAgICAgICBtaW5lckZlZTogJzE2NTU0NScsXG4gICAgICAgICAgc3BlbmRBbW91bnQ6ICc5OTk4MzQ0NTUnLFxuICAgICAgICAgIHNwZW5kQW1vdW50czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjb2luTmFtZTogJ3RhZGEnLFxuICAgICAgICAgICAgICBhbW91bnRTdHJpbmc6ICc5OTk4MzQ0NTUnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHBheUdvRmVlOiAnMCcsXG4gICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhZGRyZXNzOlxuICAgICAgICAgICAgICAgICdhZGRyX3Rlc3QxcXBycXJscXBkdHBjdHF5M2Q1NmpwMHJra2V2am5xMmtxenJuMzU2ODQyZjNndDZ4cTg3cXo2a3Jza3Fmem1mNHl6NzhkZGplOXhxNHZxeTg4cmY1MDI1bnpzaHNqZG1nMnMnLFxuICAgICAgICAgICAgICB2YWx1ZTogOTk5ODM0NDU1LFxuICAgICAgICAgICAgICB3YWxsZXQ6ICc2NGZhMzFhOTRkYjY1YTAwMDdjOTY5MWInLFxuICAgICAgICAgICAgICB3YWxsZXRzOiBbJzY0ZmEzMWE5NGRiNjVhMDAwN2M5NjkxYiddLFxuICAgICAgICAgICAgICBlbnRlcnByaXNlOiAnNjJjYzU5YjcyNzQ0M2EwMDA3MDg5MDMzJyxcbiAgICAgICAgICAgICAgZW50ZXJwcmlzZXM6IFsnNjJjYzU5YjcyNzQ0M2EwMDA3MDg5MDMzJ10sXG4gICAgICAgICAgICAgIHZhbHVlU3RyaW5nOiAnOTk5ODM0NDU1JyxcbiAgICAgICAgICAgICAgY29pbk5hbWU6ICd0YWRhJyxcbiAgICAgICAgICAgICAgd2FsbGV0VHlwZTogJ2hvdCcsXG4gICAgICAgICAgICAgIHdhbGxldFR5cGVzOiBbJ2hvdCddLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGlucHV0czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAwMDAwMCxcbiAgICAgICAgICAgICAgYWRkcmVzczpcbiAgICAgICAgICAgICAgICAnYWRkcl90ZXN0MXFxbHp4Zmw3dGxncDk5OXg0YTczMzRwY2h5Y3BrazcycHlrcnNyM21yeWwzeWo2eHE4N3F6Nmtyc2txZnptZjR5ejc4ZGRqZTl4cTR2cXk4OHJmNTAyNW56c2hzdnBnbDh3JyxcbiAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICcxMDAwMDAwMDAwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICB0eXBlOiAnMCcsXG4gICAgICAgIH0sXG4gICAgICAgIGNvbnNvbGlkYXRlSWQ6ICc2OGI5ZmMxODU1ODAwNmFhYjUzNzg1NjE1ZmVhN2MyOCcsXG4gICAgICAgIGNvaW46ICd0YWRhJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1vY2tlZFdhbGxldCA9IHtcbiAgICAgICAgY29pblNwZWNpZmljOiAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJvb3RBZGRyZXNzOlxuICAgICAgICAgICAgICAnYWRkcl90ZXN0MXFwcnFybHFwZHRwY3RxeTNkNTZqcDBya2tldmpucTJrcXpybjM1Njg0MmYzZ3Q2eHE4N3F6Nmtyc2txZnptZjR5ejc4ZGRqZTl4cTR2cXk4OHJmNTAyNW56c2hzamRtZzJzJyxcbiAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgaXNWZXJpZmllZCA9IGF3YWl0IGJhc2Vjb2luLnZlcmlmeVRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFBhcmFtczoge30sXG4gICAgICAgICAgdHhQcmVidWlsZDogY29uc29saWRhdGlvblR4LFxuICAgICAgICAgIHdhbGxldDogbW9ja2VkV2FsbGV0LFxuICAgICAgICAgIHZlcmlmaWNhdGlvbjoge1xuICAgICAgICAgICAgY29uc29saWRhdGlvblRvQmFzZUFkZHJlc3M6IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGlzVmVyaWZpZWQuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBhc3NlcnQuZmFpbCgnVHJhbnNhY3Rpb24gc2hvdWxkIHBhc3MgdmVyaWZpY2F0aW9uJyk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gc2lnbiBhIHNwb29mZWQgY29uc29saWRhdGlvbiB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFNldCB1cCB3YWxsZXQgZGF0YVxuICAgICAgY29uc3Qgd2FsbGV0RGF0YSA9IHtcbiAgICAgICAgaWQ6ICc1YjM0MjUyZjFiZjM0OTkzMGUzNDAyMGEwMDAwMDAwMCcsXG4gICAgICAgIGNvaW46ICd0YWRhJyxcbiAgICAgICAga2V5czogW1xuICAgICAgICAgICc1YjM0MjRmOTFiZjM0OTkzMGUzNDAxNzUwMDAwMDAwMCcsXG4gICAgICAgICAgJzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NjAwMDAwMDAwJyxcbiAgICAgICAgICAnNWIzNDI0ZjkxYmYzNDk5MzBlMzQwMTc3MDAwMDAwMDAnLFxuICAgICAgICBdLFxuICAgICAgICBjb2luU3BlY2lmaWM6IHtcbiAgICAgICAgICByb290QWRkcmVzczpcbiAgICAgICAgICAgICdhZGRyX3Rlc3QxcXBycXJscXBkdHBjdHF5M2Q1NmpwMHJra2V2am5xMmtxenJuMzU2ODQyZjNndDZ4cTg3cXo2a3Jza3Fmem1mNHl6NzhkZGplOXhxNHZxeTg4cmY1MDI1bnpzaHNqZG1nMnMnLFxuICAgICAgICB9LFxuICAgICAgICBtdWx0aXNpZ1R5cGU6ICd0c3MnLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGZha2VQcnYgPSBlbmNyeXB0KCdwYXNzd29yZCcsICdwcnYnKTtcblxuICAgICAgY29uc3Qgd2FsbGV0T2JqID0gbmV3IFdhbGxldChiaXRnbywgYmFzZWNvaW4sIHdhbGxldERhdGEpO1xuICAgICAgY29uc3QgYmdVcmwgPSBjb21tb24uRW52aXJvbm1lbnRzWydtb2NrJ10udXJpO1xuXG4gICAgICBub2NrKGJnVXJsKVxuICAgICAgICAuZ2V0KCcvYXBpL3YyL3RhZGEva2V5LzViMzQyNGY5MWJmMzQ5OTMwZTM0MDE3NTAwMDAwMDAwJylcbiAgICAgICAgLnJlcGx5KDIwMCwgW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGVuY3J5cHRlZFBydjogZmFrZVBydixcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcblxuICAgICAgLy8gTW9jayB0aGUgQVBJIHJlc3BvbnNlIGZvciBidWlsZEFjY291bnRDb25zb2xpZGF0aW9uc1xuICAgICAgbm9jayhiZ1VybClcbiAgICAgICAgLnBvc3QoJy9hcGkvdjIvdGFkYS93YWxsZXQvNWIzNDI1MmYxYmYzNDk5MzBlMzQwMjBhMDAwMDAwMDAvY29uc29saWRhdGVBY2NvdW50L2J1aWxkJylcbiAgICAgICAgLnJlcGx5KDIwMCwgW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR4UmVxdWVzdElkOiAnMWI1Yzc5YzUtYWI3Yy00ZjQ3LTkxMmItZGU2YTk1ZmIwNzc5JyxcbiAgICAgICAgICAgIHdhbGxldElkOiAnNjRmYTMxYTk0ZGI2NWEwMDA3Yzk2OTFiJyxcbiAgICAgICAgICAgIHR4SGV4OlxuICAgICAgICAgICAgICAnODRhNDAwODE4MjU4MjBkYjQ2YzdjNzZlYTU0ZmVjMmNhMGEyZjk0Yjc3YTIzODkzMWE4ZGNlMjM4N2M5OWExMmIwOGRkOGFhYzIxYzRmMDEwMTgyODI1ODFkNjAzM2MzNzhjZWU0MWIyZTE1YWM4NDhmN2Y2ZjFkMmY3ODE1NWFiMTJkOTNiNzEzZGU4OThkODU1ZjFhMDA5ODk2ODA4MjU4MzkwMDQ2MDFmYzAxNmFjMzg1ODA5MTZkMzUyMGJjNzZiNjU5Mjk4MTU2MDA4NzM4ZDM0N2FhOTMxNDJmNDYwMWZjMDE2YWMzODU4MDkxNmQzNTIwYmM3NmI2NTkyOTgxNTYwMDg3MzhkMzQ3YWE5MzE0MmYxYjAwMDAwMDAyMTdhY2ViZTkwMjFhMDAwMjhkYjUwMzFhMDYwZTNiNDFhMGY1ZjYnLFxuICAgICAgICAgICAgZmVlSW5mbzoge1xuICAgICAgICAgICAgICBmZWU6IDE2NTU0NSxcbiAgICAgICAgICAgICAgZmVlU3RyaW5nOiAnMTY1NTQ1JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0eEluZm86IHtcbiAgICAgICAgICAgICAgbWluZXJGZWU6ICcxNjU1NDUnLFxuICAgICAgICAgICAgICBzcGVuZEFtb3VudDogJzk5OTgzNDQ1NScsXG4gICAgICAgICAgICAgIHNwZW5kQW1vdW50czogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGNvaW5OYW1lOiAndGFkYScsXG4gICAgICAgICAgICAgICAgICBhbW91bnRTdHJpbmc6ICc5OTk4MzQ0NTUnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIHBheUdvRmVlOiAnMCcsXG4gICAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBhZGRyZXNzOlxuICAgICAgICAgICAgICAgICAgICAnYWRkcl90ZXN0MXFwcnFybHFwZHRwY3RxeTNkNTZqcDBya2tldmpucTJrcXpybjM1Njg0MmYzZ3Q2eHE4N3F6Nmtyc2txZnptZjR5ejc4ZGRqZTl4cTR2cXk4OHJmNTAyNW56c2hzamRtZzJzJyxcbiAgICAgICAgICAgICAgICAgIHZhbHVlOiA5OTk4MzQ0NTUsXG4gICAgICAgICAgICAgICAgICB3YWxsZXQ6ICc2NGZhMzFhOTRkYjY1YTAwMDdjOTY5MWInLFxuICAgICAgICAgICAgICAgICAgd2FsbGV0czogWyc2NGZhMzFhOTRkYjY1YTAwMDdjOTY5MWInXSxcbiAgICAgICAgICAgICAgICAgIGVudGVycHJpc2U6ICc2MmNjNTliNzI3NDQzYTAwMDcwODkwMzMnLFxuICAgICAgICAgICAgICAgICAgZW50ZXJwcmlzZXM6IFsnNjJjYzU5YjcyNzQ0M2EwMDA3MDg5MDMzJ10sXG4gICAgICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzk5OTgzNDQ1NScsXG4gICAgICAgICAgICAgICAgICBjb2luTmFtZTogJ3RhZGEnLFxuICAgICAgICAgICAgICAgICAgd2FsbGV0VHlwZTogJ2hvdCcsXG4gICAgICAgICAgICAgICAgICB3YWxsZXRUeXBlczogWydob3QnXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICB2YWx1ZTogMTAwMDAwMDAwMCxcbiAgICAgICAgICAgICAgICAgIGFkZHJlc3M6XG4gICAgICAgICAgICAgICAgICAgICdhZGRyX3Rlc3QxcXFsenhmbDd0bGdwOTk5eDRhNzMzNHBjaHljcGtrNzJweWtyc3IzbXJ5bDN5ajZ4cTg3cXo2a3Jza3Fmem1mNHl6NzhkZGplOXhxNHZxeTg4cmY1MDI1bnpzaHN2cGdsOHcnLFxuICAgICAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICcxMDAwMDAwMDAwJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB0eXBlOiAnMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29uc29saWRhdGVJZDogJzY4YjlmYzE4NTU4MDA2YWFiNTM3ODU2MTVmZWE3YzI4JyxcbiAgICAgICAgICAgIGNvaW46ICd0YWRhJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcblxuICAgICAgLy8gQ2FsbCB0aGUgZnVuY3Rpb24gdG8gdGVzdFxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCB3YWxsZXRPYmouc2VuZEFjY291bnRDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAncGFzc3dvcmQnLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbWVzc2FnZTogJ3R4IG91dHB1dHMgZG9lcyBub3QgbWF0Y2ggd2l0aCBleHBlY3RlZCBhZGRyZXNzJyxcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0V4cGxhaW4gVHJhbnNhY3Rpb25zOicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYW4gdW5zaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICB0eEhleDogcmF3VHgudW5zaWduZWRUeDIsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGNvbnNvbGUubG9nKGV4cGxhaW5lZFRyYW5zYWN0aW9uKTtcbiAgICAgIGV4cGxhaW5lZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwodHJhbnNhY3Rpb25FeHBsYW5hdGlvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gZXhwbGFpbiB0cmFuc2FjdGlvbiB3aXRoIG1pc3NpbmcgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7fSxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBzaG91bGQuZXF1YWwoZXJyb3IubWVzc2FnZSwgJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBleHBsYWluIHRyYW5zYWN0aW9uIHdpdGggd3JvbmcgcGFyYW1zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgICB0eEhleDogJ2ludmFsaWRUeEhleCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBzaG91bGQuZXF1YWwoZXJyb3IubWVzc2FnZSwgJ0ludmFsaWQgdHJhbnNhY3Rpb24nKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1BhcnNlIFJhdyBUcmFuc2FjdGlvbnMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBzdGFraW5nIHBsZWRnZSB0cmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gbmV3IFRyYW5zYWN0aW9uKGJhc2Vjb2luKTtcbiAgICAgIHR4LmZyb21SYXdUcmFuc2FjdGlvbihyYXdUeC51bnNpZ25lZE5ld1BsZWRnZVR4KTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU3Rha2luZ1BsZWRnZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIHN0YWtpbmcgYWN0aXZhdGlvbiB0eCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gbmV3IFRyYW5zYWN0aW9uKGJhc2Vjb2luKTtcbiAgICAgIHR4LmZyb21SYXdUcmFuc2FjdGlvbihyYXdUeC51bnNpZ25lZFN0YWtpbmdBY3RpdmVUeCk7XG4gICAgICBzaG91bGQuZXF1YWwodHgudHlwZSwgVHJhbnNhY3Rpb25UeXBlLlN0YWtpbmdBY3RpdmF0ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIHN0YWtpbmcgZGVhY3RpdmF0aW9uIHR4JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oYmFzZWNvaW4pO1xuICAgICAgdHguZnJvbVJhd1RyYW5zYWN0aW9uKHJhd1R4LnVuc2lnbmVkU3Rha2luZ0RlYWN0aXZlVHgpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TdGFraW5nRGVhY3RpdmF0ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdQYXJzZSBUcmFuc2FjdGlvbnM6JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcGFyc2UgYW4gdW5zaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJzZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJhc2Vjb2luLnBhcnNlVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IHJhd1R4LnVuc2lnbmVkVHgyLFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIHBhcnNlZFRyYW5zYWN0aW9uLnNob3VsZC5kZWVwRXF1YWwodHJhbnNhY3Rpb25FeHBsYW5hdGlvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIGEgc2lnbmVkIHRyYW5zZmVyIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcGFyc2VkVHJhbnNhY3Rpb24gPSBhd2FpdCBiYXNlY29pbi5wYXJzZVRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIHR4SGV4OiByYXdUeC5zaWduZWRUeDIsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgcGFyc2VkVHJhbnNhY3Rpb24uc2hvdWxkLmRlZXBFcXVhbCh0cmFuc2FjdGlvbkV4cGxhbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBwYXJzZSBhIHNpZ25lZCB0cmFuc2ZlciB0cmFuc2FjdGlvbiB3aGVuIGV4cGxhaW5UcmFuc2FjdGlvbiByZXNwb25zZSBpcyB1bmRlZmluZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzdHViID0gc2lub24uc3R1YihBZGEucHJvdG90eXBlLCAnZXhwbGFpblRyYW5zYWN0aW9uJyk7XG4gICAgICBzdHViLnJlc29sdmVzKHVuZGVmaW5lZCk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucGFyc2VUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgICAgdHhIZXg6IHJhd1R4LnNpZ25lZFR4LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdJbnZhbGlkIHRyYW5zYWN0aW9uJyk7XG4gICAgICBzdHViLnJlc3RvcmUoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXIgVHJhbnNhY3Rpb25zOicsICgpID0+IHtcbiAgICBjb25zdCBkZXN0QWRkciA9IGFkZHJlc3MuYWRkcmVzczI7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY2FsbEJhY2sgPSBzYW5kQm94LnN0dWIoQWRhLnByb3RvdHlwZSwgJ2dldERhdGFGcm9tTm9kZScgYXMga2V5b2YgQWRhKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncygnYWRkcmVzc19pbmZvJywge1xuICAgICAgICAgIF9hZGRyZXNzZXM6IFt3cndVc2VyLndhbGxldEFkZHJlc3MwXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLmFkZHJlc3NJbmZvUmVzcG9uc2UuT25lVVRYTyk7XG4gICAgICBjYWxsQmFjay53aXRoQXJncygndGlwJykucmVzb2x2ZXMoZW5kcG9pbnRSZXNwb25zZXMudGlwSW5mb1Jlc3BvbnNlKTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGFrZSBPVkMgb3V0cHV0IGFuZCBnZW5lcmF0ZSBhIHNpZ25lZCBzd2VlcCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IG92Y1Jlc3BvbnNlO1xuICAgICAgY29uc3QgcmVjb3ZlcnlUeG4gPSBhd2FpdCBiYXNlY29pbi5jcmVhdGVCcm9hZGNhc3RhYmxlU3dlZXBUcmFuc2FjdGlvbihwYXJhbXMpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICc4NGE0MDA4MTgyNTgyMDRiZDBmOTkxYzE1MzJjZmZlMzFkNGExMGRiNDkyYjQzMTc1ZWMzMjY3NjViNmIyOWNlZWU1OThkZjJiNjFmNDcwMDAxODE4MjU4MzkwMDg3Mzc5ZWJjNTUzM2ViZTYyMTk2M2M5MTVjM2NiYzVmMDg1MzdmY2RjYTRhZjhmOGFlMDhlZDRjODczNzllYmM1NTMzZWJlNjIxOTYzYzkxNWMzY2JjNWYwODUzN2ZjZGNhNGFmOGY4YWUwOGVkNGMxYTA1ZjM1OWZmMDIxYTAwMDI4NzAxMDMxYTAyNDk3MmUxYTEwMDgxODI1ODIwYmJhY2IxMzQzMWI5OTIwOGU2ZThjZGJmNzEwMTQ3ZmVhZjA2YTM5ZDcxNTY1ZTYwYjQxMWNlOWU0ZmEzZjEzNzU4NDAwMWE0YWI4MjM2NTYzZjY5ZmYzMDllNTc4NmU4ZjM5YzYyOWVkNTc2NzZjNjkyMTU5Y2IyZTA0OTRjOWU2NjMzNTUzODRjMTNjNzQ5ZDA0YzE3YTgwYmEyYTQ1Y2MxMjdkZjQ4MGZjNjRhNDMxOTlhNzcyZjExYWNkNWIxNGEwZmY1ZjYnXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzBdLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMCk7XG4gICAgICByZWNvdmVyeVR4bi5sYXN0U2NhbkluZGV4LnNob3VsZC5lcXVhbCgwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGFrZSBjb25zb2xpZGF0aW9uIE9WQyBvdXRwdXQgYW5kIGdlbmVyYXRlIG11bHRpcGxlIHNpZ25lZCBzd2VlcCB0cmFuc2FjdGlvbnMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBwYXJhbXMgPSBvdmNSZXNwb25zZTI7XG4gICAgICBjb25zdCByZWNvdmVyeVR4biA9IGF3YWl0IGJhc2Vjb2luLmNyZWF0ZUJyb2FkY2FzdGFibGVTd2VlcFRyYW5zYWN0aW9uKHBhcmFtcyk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2VyaWFsaXplZFR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzg0YTQwMDgxODI1ODIwM2U2MmU1ZWU4YjEyMDEyYzRiOTQ5Zjk3NzdiNzIxNjUyMzliYjIxNDZhZThiMDc4YjRkMWM1Y2E4ZDMxNjhlMzAwMDE4MTgyNTgzOTAwYmFmNTVlYmNmOWFkYTFiOGVjYjE2NDA4ODBmYmE1NGQyODE3NjkwZjEyYjNhMTA2YWZkMDgwMDRiYWY1NWViY2Y5YWRhMWI4ZWNiMTY0MDg4MGZiYTU0ZDI4MTc2OTBmMTJiM2ExMDZhZmQwODAwNDFhMDA5NjBmN2YwMjFhMDAwMjg3MDEwMzFhMDI1MGY3ZWFhMTAwODE4MjU4MjA1MDBlMGQ3MjVhNWJhM2EzMDZkYTM1MDNkZmU1N2I4YTE0MDY4YTA5YjYxYjM2ZWMwNjhmY2Y4Y2Y1YzM5MWRlNTg0MGM4MzZjZTZkMzI2MmQ1NjU0NzA2ZWEwNjcyMTUyMmQzYjc1ZjZkNTQ1MjQ1MDQ3YTdiZTc0NjM2MjlkODhiM2Y0MjY0Yjk5NWY1OTFkZjUyYmRmZmNmMDlkYTFlNmFiOWU4OGRlMzcxNGM2ZTJlYzE5NjE3ODZjZjFjNTg2YTA3ZjVmNidcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbMF0uc2NhbkluZGV4LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1sxXS5zZXJpYWxpemVkVHguc2hvdWxkLmVxdWFsKFxuICAgICAgICAnODRhNDAwODE4MjU4MjAyOWMxMGFjZjBlMDhmOTUyMzMyNWM4ODI0MzU2NWFmNmIzMjI3NDk5MjE4OWMxMTUzOTAzYzQxMGJlZDdjMmM3MDAwMTgxODI1ODM5MDBiYWY1NWViY2Y5YWRhMWI4ZWNiMTY0MDg4MGZiYTU0ZDI4MTc2OTBmMTJiM2ExMDZhZmQwODAwNGJhZjU1ZWJjZjlhZGExYjhlY2IxNjQwODgwZmJhNTRkMjgxNzY5MGYxMmIzYTEwNmFmZDA4MDA0MWEwMDk2MGY3ZjAyMWEwMDAyODcwMTAzMWEwMjUwZjdlYWExMDA4MTgyNTgyMDYyNzcwYjIyNGJkMzE0YmM1MjZmYmQ2YTk0ZTkwODJmYjY0NThjNDI1ZTZlMDliYWQ3NDAwNGRkODk3ZTk2MjM1ODQwMzg0MjU0NGYyZmYyOGJlMDU0ZWI3Yzc5OTdiYzMwM2IxZTI1MWViMTNhNDE4MDJjODIzMThlNTkyYmIyNGVhYTMxOTdjNDUwZTc5N2NjODU1OWYwMzU2Y2Q1Y2RkMWFiNWViODBjNTE3M2UzNGU5ZTFkMTczNzUzM2E4OTUyMGNmNWY2J1xuICAgICAgKTtcbiAgICAgIHJlY292ZXJ5VHhuLnRyYW5zYWN0aW9uc1sxXS5zY2FuSW5kZXguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzJdLnNlcmlhbGl6ZWRUeC5zaG91bGQuZXF1YWwoXG4gICAgICAgICc4NGE0MDA4MTgyNTgyMGRkMTQwZjEzM2Q4NjVlMWJiNTY0MmU3MDhmZTY4NWJmNzYwMWQ3MWQwYzk5NTExZTVkNTUyZGE3ZjhiZDEwZmYwMDAxODE4MjU4MzkwMGJhZjU1ZWJjZjlhZGExYjhlY2IxNjQwODgwZmJhNTRkMjgxNzY5MGYxMmIzYTEwNmFmZDA4MDA0YmFmNTVlYmNmOWFkYTFiOGVjYjE2NDA4ODBmYmE1NGQyODE3NjkwZjEyYjNhMTA2YWZkMDgwMDQxYTAwOTYwZjdmMDIxYTAwMDI4NzAxMDMxYTAyNTBmN2VhYTEwMDgxODI1ODIwNTNiNGJiNzRhYTM4YWRkNDU4ZGFmYzgxNTNmMGFhODI2NmFjYWQ1OTMyMmI4NzdjYTljMjNjNWQzODczNzc5ZDU4NDBlOTRjZTc4OTY5NTdkMDk0YzZiYWZiZjJlYzEwZGY1ZWJiMGYxZDJhMjdhN2UzMWYyZDQ1YzUzMWZiNjg3ZWRkNmM0ZDMzZjhlOWI5OWM3NjkyYjZmYWM2ZDgzOTliZDhmZDQ3NjQxYmFhZTliYmI2OWY1MThkNDJhZDExNzEwYWY1ZjYnXG4gICAgICApO1xuICAgICAgcmVjb3ZlcnlUeG4udHJhbnNhY3Rpb25zWzJdLnNjYW5JbmRleC5zaG91bGQuZXF1YWwoMyk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbM10uc2VyaWFsaXplZFR4LnNob3VsZC5lcXVhbChcbiAgICAgICAgJzg0YTQwMDgxODI1ODIwMTVhMWQ2ZGI1ZDNmNTkyYWExY2RhMTg1YjYzNTljYTBlMjkyMWMzYzUxOTU5ZjY0MjIyYTZiN2Q5NWQzMzkyMzAwMDE4MTgyNTgzOTAwYmFmNTVlYmNmOWFkYTFiOGVjYjE2NDA4ODBmYmE1NGQyODE3NjkwZjEyYjNhMTA2YWZkMDgwMDRiYWY1NWViY2Y5YWRhMWI4ZWNiMTY0MDg4MGZiYTU0ZDI4MTc2OTBmMTJiM2ExMDZhZmQwODAwNDFhMDA5NjBmN2YwMjFhMDAwMjg3MDEwMzFhMDI1MGY3ZWFhMTAwODE4MjU4MjA2MDBmODZjYTIyZDY3MGYwYTk5MGFkZTRlODgyYzA1ZTY1NDM0MzI2MzQ5NDczNWEzMTUxN2RlMDgxOTY3NjczNTg0MGZlMTk5ZjhlMjQ3YTRjZmFiZmViNGY5Y2I1NzRhYTM1NzM5YTBhYTk4ODYwZWUwYTg1ZDcyMGM0YWI0ZmVjZmFjN2I0NTA0ZGYzMTBiM2U0YmVhMDQ3MTFmNjA2NTJkNGE4Y2Y1ZWI0MTgxNzI5M2I4ZDI5OTc3ZmU2OTVmNzA0ZjVmNidcbiAgICAgICk7XG4gICAgICByZWNvdmVyeVR4bi50cmFuc2FjdGlvbnNbM10uc2NhbkluZGV4LnNob3VsZC5lcXVhbCg0KTtcbiAgICAgIHJlY292ZXJ5VHhuLmxhc3RTY2FuSW5kZXguc2hvdWxkLmVxdWFsKDIwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBhIHR4biBmb3Igbm9uLWJpdGdvIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgdXNlcktleTogd3J3VXNlci51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IHdyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICBiaXRnb0tleTogd3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogd3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0QWRkcixcbiAgICAgIH0pO1xuICAgICAgcmVzLnNob3VsZC5ub3QuYmUuZW1wdHkoKTtcbiAgICAgIHJlcy5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkVHdpY2UoYmFzZWNvaW4uZ2V0RGF0YUZyb21Ob2RlKTtcblxuICAgICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oYmFzZWNvaW4pO1xuICAgICAgdHguZnJvbVJhd1RyYW5zYWN0aW9uKHJlcy5zZXJpYWxpemVkVHgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICBjb25zdCBmZWUgPSBOdW1iZXIodHguZXhwbGFpblRyYW5zYWN0aW9uKCkuZmVlLmZlZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5pbnB1dHNbMF0udHJhbnNhY3Rpb25faWQsIHRlc3RuZXRVVFhPLlVUWE9fMS50eF9oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmlucHV0c1swXS50cmFuc2FjdGlvbl9pbmRleCwgdGVzdG5ldFVUWE8uVVRYT18xLnR4X2luZGV4KTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLm91dHB1dHNbMF0uYWRkcmVzcywgZGVzdEFkZHIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChOdW1iZXIodHhKc29uLm91dHB1dHNbMF0uYW1vdW50KSArIGZlZSwgdGVzdG5ldFVUWE8uVVRYT18xLnZhbHVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBhIHR4biBmb3IgdW5zaWduZWQgc3dlZXAgcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICBiaXRnb0tleTogd3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdEFkZHIsXG4gICAgICB9KTtcbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICByZXMudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkVHdpY2UoYmFzZWNvaW4uZ2V0RGF0YUZyb21Ob2RlKTtcblxuICAgICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oYmFzZWNvaW4pO1xuICAgICAgdHguZnJvbVJhd1RyYW5zYWN0aW9uKHJlcy50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIGNvbnN0IGZlZSA9IE51bWJlcih0eC5leHBsYWluVHJhbnNhY3Rpb24oKS5mZWUuZmVlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmlucHV0c1swXS50cmFuc2FjdGlvbl9pZCwgdGVzdG5ldFVUWE8uVVRYT18xLnR4X2hhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uaW5wdXRzWzBdLnRyYW5zYWN0aW9uX2luZGV4LCB0ZXN0bmV0VVRYTy5VVFhPXzEudHhfaW5kZXgpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24ub3V0cHV0c1swXS5hZGRyZXNzLCBkZXN0QWRkcik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKE51bWJlcih0eEpzb24ub3V0cHV0c1swXS5hbW91bnQpICsgZmVlLCB0ZXN0bmV0VVRYTy5VVFhPXzEudmFsdWUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVjb3ZlciBUcmFuc2FjdGlvbnMgTXVsdGlwbGUgVVRYTzonLCAoKSA9PiB7XG4gICAgY29uc3QgZGVzdEFkZHIgPSBhZGRyZXNzLmFkZHJlc3MyO1xuICAgIGNvbnN0IHNhbmRCb3ggPSBzaW5vbi5jcmVhdGVTYW5kYm94KCk7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNhbGxCYWNrID0gc2FuZEJveC5zdHViKEFkYS5wcm90b3R5cGUsICdnZXREYXRhRnJvbU5vZGUnIGFzIGtleW9mIEFkYSk7XG4gICAgICBjYWxsQmFja1xuICAgICAgICAud2l0aEFyZ3MoJ2FkZHJlc3NfaW5mbycsIHtcbiAgICAgICAgICBfYWRkcmVzc2VzOiBbd3J3VXNlci53YWxsZXRBZGRyZXNzMF0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyhlbmRwb2ludFJlc3BvbnNlcy5hZGRyZXNzSW5mb1Jlc3BvbnNlLlR3b1VUWE8pO1xuICAgICAgY2FsbEJhY2sud2l0aEFyZ3MoJ3RpcCcpLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLnRpcEluZm9SZXNwb25zZSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZEJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgYSB0eG4gZm9yIG5vbi1iaXRnbyByZWNvdmVyaWVzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgIHVzZXJLZXk6IHdyd1VzZXIudXNlcktleSxcbiAgICAgICAgYmFja3VwS2V5OiB3cndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IHdyd1VzZXIuYml0Z29LZXksXG4gICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHdyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdEFkZHIsXG4gICAgICB9KTtcbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICByZXMuc2hvdWxkLmhhc093blByb3BlcnR5KCdzZXJpYWxpemVkVHgnKTtcbiAgICAgIHNhbmRCb3guYXNzZXJ0LmNhbGxlZFR3aWNlKGJhc2Vjb2luLmdldERhdGFGcm9tTm9kZSk7XG5cbiAgICAgIGNvbnN0IHR4ID0gbmV3IFRyYW5zYWN0aW9uKGJhc2Vjb2luKTtcbiAgICAgIHR4LmZyb21SYXdUcmFuc2FjdGlvbihyZXMuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgY29uc3QgZmVlID0gTnVtYmVyKHR4LmV4cGxhaW5UcmFuc2FjdGlvbigpLmZlZS5mZWUpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uaW5wdXRzWzBdLnRyYW5zYWN0aW9uX2lkLCB0ZXN0bmV0VVRYTy5VVFhPXzEudHhfaGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5pbnB1dHNbMF0udHJhbnNhY3Rpb25faW5kZXgsIHRlc3RuZXRVVFhPLlVUWE9fMS50eF9pbmRleCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5pbnB1dHNbMV0udHJhbnNhY3Rpb25faWQsIHRlc3RuZXRVVFhPLlVUWE9fMi50eF9oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmlucHV0c1sxXS50cmFuc2FjdGlvbl9pbmRleCwgdGVzdG5ldFVUWE8uVVRYT18yLnR4X2luZGV4KTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLm91dHB1dHNbMF0uYWRkcmVzcywgZGVzdEFkZHIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChOdW1iZXIodHhKc29uLm91dHB1dHNbMF0uYW1vdW50KSArIGZlZSwgdGVzdG5ldFVUWE8uVVRYT18xLnZhbHVlICsgdGVzdG5ldFVUWE8uVVRYT18yLnZhbHVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBhIHR4biBmb3IgdW5zaWduZWQgc3dlZXAgcmVjb3ZlcmllcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICBiaXRnb0tleTogd3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogZGVzdEFkZHIsXG4gICAgICB9KTtcbiAgICAgIHJlcy5zaG91bGQubm90LmJlLmVtcHR5KCk7XG4gICAgICByZXMudHhSZXF1ZXN0c1swXS50cmFuc2FjdGlvbnNbMF0udW5zaWduZWRUeC5zaG91bGQuaGFzT3duUHJvcGVydHkoJ3NlcmlhbGl6ZWRUeCcpO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkVHdpY2UoYmFzZWNvaW4uZ2V0RGF0YUZyb21Ob2RlKTtcblxuICAgICAgY29uc3QgdHggPSBuZXcgVHJhbnNhY3Rpb24oYmFzZWNvaW4pO1xuICAgICAgdHguZnJvbVJhd1RyYW5zYWN0aW9uKHJlcy50eFJlcXVlc3RzWzBdLnRyYW5zYWN0aW9uc1swXS51bnNpZ25lZFR4LnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgIGNvbnN0IGZlZSA9IE51bWJlcih0eC5leHBsYWluVHJhbnNhY3Rpb24oKS5mZWUuZmVlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uLmlucHV0c1swXS50cmFuc2FjdGlvbl9pZCwgdGVzdG5ldFVUWE8uVVRYT18xLnR4X2hhc2gpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uaW5wdXRzWzBdLnRyYW5zYWN0aW9uX2luZGV4LCB0ZXN0bmV0VVRYTy5VVFhPXzEudHhfaW5kZXgpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24uaW5wdXRzWzFdLnRyYW5zYWN0aW9uX2lkLCB0ZXN0bmV0VVRYTy5VVFhPXzIudHhfaGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5pbnB1dHNbMV0udHJhbnNhY3Rpb25faW5kZXgsIHRlc3RuZXRVVFhPLlVUWE9fMi50eF9pbmRleCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbi5vdXRwdXRzWzBdLmFkZHJlc3MsIGRlc3RBZGRyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwoTnVtYmVyKHR4SnNvbi5vdXRwdXRzWzBdLmFtb3VudCkgKyBmZWUsIHRlc3RuZXRVVFhPLlVUWE9fMS52YWx1ZSArIHRlc3RuZXRVVFhPLlVUWE9fMi52YWx1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdCdWlsZCBDb25zb2xpZGF0aW9uIFJlY292ZXJpZXM6JywgKCkgPT4ge1xuICAgIGNvbnN0IGJhc2VBZGRyID0gY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0QWRkcmVzczA7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY2FsbEJhY2sgPSBzYW5kQm94LnN0dWIoQWRhLnByb3RvdHlwZSwgJ2dldERhdGFGcm9tTm9kZScgYXMga2V5b2YgQWRhKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncygnYWRkcmVzc19pbmZvJywge1xuICAgICAgICAgIF9hZGRyZXNzZXM6IFtjb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRBZGRyZXNzMV0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyhlbmRwb2ludFJlc3BvbnNlcy5hZGRyZXNzSW5mb1Jlc3BvbnNlLlplcm9VVFhPKTtcbiAgICAgIGNhbGxCYWNrXG4gICAgICAgIC53aXRoQXJncygnYWRkcmVzc19pbmZvJywge1xuICAgICAgICAgIF9hZGRyZXNzZXM6IFtjb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRBZGRyZXNzMl0sXG4gICAgICAgIH0pXG4gICAgICAgIC5yZXNvbHZlcyhlbmRwb2ludFJlc3BvbnNlcy5hZGRyZXNzSW5mb1Jlc3BvbnNlLk9uZVVUWE8pO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKCdhZGRyZXNzX2luZm8nLCB7XG4gICAgICAgICAgX2FkZHJlc3NlczogW2NvbnNvbGlkYXRpb25XcndVc2VyLndhbGxldEFkZHJlc3MzXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLmFkZHJlc3NJbmZvUmVzcG9uc2UuT25lVVRYTzIpO1xuICAgICAgY2FsbEJhY2sud2l0aEFyZ3MoJ3RpcCcpLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLnRpcEluZm9SZXNwb25zZSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgc2FuZEJveC5yZXN0b3JlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJ1aWxkIHNpZ25lZCBjb25zb2xpZGF0aW9uIHJlY292ZXJpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyQ29uc29saWRhdGlvbnMoe1xuICAgICAgICB1c2VyS2V5OiBjb25zb2xpZGF0aW9uV3J3VXNlci51c2VyS2V5LFxuICAgICAgICBiYWNrdXBLZXk6IGNvbnNvbGlkYXRpb25XcndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgYml0Z29LZXk6IGNvbnNvbGlkYXRpb25XcndVc2VyLmJpdGdvS2V5LFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiBjb25zb2xpZGF0aW9uV3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgZW5kaW5nU2NhbkluZGV4OiA0LFxuICAgICAgfSk7XG4gICAgICByZXMuc2hvdWxkLm5vdC5iZS5lbXB0eSgpO1xuICAgICAgcmVzLnRyYW5zYWN0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFsKDIpO1xuICAgICAgcmVzLmxhc3RTY2FuSW5kZXguc2hvdWxkLmVxdWFsKDMpO1xuICAgICAgY29uc3QgdHhuMSA9IHJlcy50cmFuc2FjdGlvbnNbMF07XG4gICAgICBjb25zdCB0eDEgPSBuZXcgVHJhbnNhY3Rpb24oYmFzZWNvaW4pO1xuICAgICAgdHgxLmZyb21SYXdUcmFuc2FjdGlvbih0eG4xLnNlcmlhbGl6ZWRUeCk7XG4gICAgICBjb25zdCB0eEpzb24xID0gdHgxLnRvSnNvbigpO1xuICAgICAgY29uc3QgZmVlMSA9IE51bWJlcih0eDEuZXhwbGFpblRyYW5zYWN0aW9uKCkuZmVlLmZlZSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuaW5wdXRzWzBdLnRyYW5zYWN0aW9uX2lkLCB0ZXN0bmV0VVRYTy5VVFhPXzEudHhfaGFzaCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjEuaW5wdXRzWzBdLnRyYW5zYWN0aW9uX2luZGV4LCB0ZXN0bmV0VVRYTy5VVFhPXzEudHhfaW5kZXgpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eEpzb24xLm91dHB1dHNbMF0uYWRkcmVzcywgYmFzZUFkZHIpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChOdW1iZXIodHhKc29uMS5vdXRwdXRzWzBdLmFtb3VudCkgKyBmZWUxLCB0ZXN0bmV0VVRYTy5VVFhPXzEudmFsdWUpO1xuXG4gICAgICBjb25zdCB0eG4yID0gcmVzLnRyYW5zYWN0aW9uc1sxXTtcbiAgICAgIGNvbnN0IHR4MiA9IG5ldyBUcmFuc2FjdGlvbihiYXNlY29pbik7XG4gICAgICB0eDIuZnJvbVJhd1RyYW5zYWN0aW9uKHR4bjIuc2VyaWFsaXplZFR4KTtcbiAgICAgIGNvbnN0IHR4SnNvbjIgPSB0eDIudG9Kc29uKCk7XG4gICAgICBjb25zdCBmZWUyID0gTnVtYmVyKHR4Mi5leHBsYWluVHJhbnNhY3Rpb24oKS5mZWUuZmVlKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5pbnB1dHNbMF0udHJhbnNhY3Rpb25faWQsIHRlc3RuZXRVVFhPLlVUWE9fMi50eF9oYXNoKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHhKc29uMi5pbnB1dHNbMF0udHJhbnNhY3Rpb25faW5kZXgsIHRlc3RuZXRVVFhPLlVUWE9fMi50eF9pbmRleCk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4SnNvbjIub3V0cHV0c1swXS5hZGRyZXNzLCBiYXNlQWRkcik7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKE51bWJlcih0eEpzb24yLm91dHB1dHNbMF0uYW1vdW50KSArIGZlZTIsIHRlc3RuZXRVVFhPLlVUWE9fMi52YWx1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNraXAgYnVpbGRpbmcgY29uc29saWRhdGUgdHJhbnNhY3Rpb24gaWYgYmFsYW5jZSBpcyBlcXVhbCB0byB6ZXJvJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgICAgdXNlcktleTogY29uc29saWRhdGlvbldyd1VzZXIudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IGNvbnNvbGlkYXRpb25XcndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogY29uc29saWRhdGlvbldyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogY29uc29saWRhdGlvbldyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogMSxcbiAgICAgICAgICBlbmRpbmdTY2FuSW5kZXg6IDIsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQucmVqZWN0ZWRXaXRoKCdEaWQgbm90IGZpbmQgYW4gYWRkcmVzcyB3aXRoIGZ1bmRzIHRvIHJlY292ZXInKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgc3RhcnRpbmdTY2FuSW5kZXggaXMgbm90IGdlIHRvIDEnLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3ZlckNvbnNvbGlkYXRpb25zKHtcbiAgICAgICAgICB1c2VyS2V5OiBjb25zb2xpZGF0aW9uV3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogY29uc29saWRhdGlvbldyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiBjb25zb2xpZGF0aW9uV3J3VXNlci5iaXRnb0tleSxcbiAgICAgICAgICBzdGFydGluZ1NjYW5JbmRleDogLTEsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdJbnZhbGlkIHN0YXJ0aW5nIG9yIGVuZGluZyBpbmRleCB0byBzY2FuIGZvciBhZGRyZXNzZXMuIHN0YXJ0aW5nU2NhbkluZGV4OiAtMSwgZW5kaW5nU2NhbkluZGV4OiAxOS4nXG4gICAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIHNjYW4gZmFjdG9yIGlzIHRvbyBoaWdoJywgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXJDb25zb2xpZGF0aW9ucyh7XG4gICAgICAgICAgdXNlcktleTogY29uc29saWRhdGlvbldyd1VzZXIudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IGNvbnNvbGlkYXRpb25XcndVc2VyLmJhY2t1cEtleSxcbiAgICAgICAgICBiaXRnb0tleTogY29uc29saWRhdGlvbldyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgc3RhcnRpbmdTY2FuSW5kZXg6IDEsXG4gICAgICAgICAgZW5kaW5nU2NhbkluZGV4OiAzMDAsXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKFxuICAgICAgICAgICdJbnZhbGlkIHN0YXJ0aW5nIG9yIGVuZGluZyBpbmRleCB0byBzY2FuIGZvciBhZGRyZXNzZXMuIHN0YXJ0aW5nU2NhbkluZGV4OiAxLCBlbmRpbmdTY2FuSW5kZXg6IDMwMC4nXG4gICAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZWNvdmVyIFRyYW5zYWN0aW9ucyBGYWlsdXJlOicsICgpID0+IHtcbiAgICBjb25zdCBkZXN0QWRkciA9IGFkZHJlc3MuYWRkcmVzczI7XG4gICAgY29uc3Qgc2FuZEJveCA9IHNpbm9uLmNyZWF0ZVNhbmRib3goKTtcblxuICAgIGFmdGVyRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBzYW5kQm94LnJlc3RvcmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byByZWNvdmVyIGR1ZSB0byBub3QgZmluZGluZyBhbiBhZGRyZXNzIHdpdGggZnVuZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjYWxsQmFjayA9IHNhbmRCb3guc3R1YihBZGEucHJvdG90eXBlLCAnZ2V0RGF0YUZyb21Ob2RlJyBhcyBrZXlvZiBBZGEpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKCdhZGRyZXNzX2luZm8nLCBzaW5vbi5tYXRjaC5oYXMoJ19hZGRyZXNzZXMnKSlcbiAgICAgICAgLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLmFkZHJlc3NJbmZvUmVzcG9uc2UuWmVyb1VUWE8pO1xuICAgICAgY2FsbEJhY2sud2l0aEFyZ3MoJ3RpcCcpLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLnRpcEluZm9SZXNwb25zZSk7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAucmVjb3Zlcih7XG4gICAgICAgICAgdXNlcktleTogd3J3VXNlci51c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleTogd3J3VXNlci5iYWNrdXBLZXksXG4gICAgICAgICAgYml0Z29LZXk6IHdyd1VzZXIuYml0Z29LZXksXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZTogd3J3VXNlci53YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGRlc3RBZGRyLFxuICAgICAgICB9KVxuICAgICAgICAuc2hvdWxkLnJlamVjdGVkV2l0aCgnRGlkIG5vdCBmaW5kIGFkZHJlc3Mgd2l0aCBmdW5kcyB0byByZWNvdmVyJyk7XG4gICAgICBzYW5kQm94LmFzc2VydC5jYWxsZWRPbmNlKGJhc2Vjb2luLmdldERhdGFGcm9tTm9kZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gcmVjb3ZlciBkdWUgdG8gbm90IGhhdmluZyBtb3JlIHRoYW4gMSBBREEgaW4gZnVuZHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjYWxsQmFjayA9IHNhbmRCb3guc3R1YihBZGEucHJvdG90eXBlLCAnZ2V0RGF0YUZyb21Ob2RlJyBhcyBrZXlvZiBBZGEpO1xuICAgICAgY2FsbEJhY2tcbiAgICAgICAgLndpdGhBcmdzKCdhZGRyZXNzX2luZm8nLCBzaW5vbi5tYXRjaC5oYXMoJ19hZGRyZXNzZXMnKSlcbiAgICAgICAgLnJlc29sdmVzKGVuZHBvaW50UmVzcG9uc2VzLmFkZHJlc3NJbmZvUmVzcG9uc2UuT25lU21hbGxVVFhPKTtcbiAgICAgIGNhbGxCYWNrLndpdGhBcmdzKCd0aXAnKS5yZXNvbHZlcyhlbmRwb2ludFJlc3BvbnNlcy50aXBJbmZvUmVzcG9uc2UpO1xuICAgICAgYXdhaXQgYmFzZWNvaW5cbiAgICAgICAgLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHdyd1VzZXIudXNlcktleSxcbiAgICAgICAgICBiYWNrdXBLZXk6IHdyd1VzZXIuYmFja3VwS2V5LFxuICAgICAgICAgIGJpdGdvS2V5OiB3cndVc2VyLmJpdGdvS2V5LFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6IHdyd1VzZXIud2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiBkZXN0QWRkcixcbiAgICAgICAgfSlcbiAgICAgICAgLnNob3VsZC5yZWplY3RlZFdpdGgoXG4gICAgICAgICAgJ0luc3VmZmljaWVudCBmdW5kcyB0byByZWNvdmVyLCBtaW5pbXVtIHJlcXVpcmVkIGlzIDEgQURBIHBsdXMgZmVlcywgZ290IDk4MzQ0NTUgZmVlczogMTY1NTQ1J1xuICAgICAgICApO1xuICAgICAgc2FuZEJveC5hc3NlcnQuY2FsbGVkVHdpY2UoYmFzZWNvaW4uZ2V0RGF0YUZyb21Ob2RlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1ZlcmlmeSB0b2tlbiBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uOicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGZhaWwgdG8gdmVyaWZ5IGEgc3Bvb2ZlZCB0b2tlbiBjb25zb2xpZGF0aW9uIHRyYW5zYWN0aW9uIHdpdGggaW5jb3JyZWN0IGFkZHJlc3MnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjb25zb2xpZGF0aW9uVHggPSB7XG4gICAgICAgIHR4UmVxdWVzdElkOiAnNGZkZDBjYWUtMjU2My00M2IxLWI1Y2YtOTQ4NjUxNThjYTEwJyxcbiAgICAgICAgd2FsbGV0SWQ6ICc2MzA2OGVkNGVmYTYzYTAwMDg3N2YwMmZkNGIwZmE2ZCcsXG4gICAgICAgIHR4SGV4OlxuICAgICAgICAgICc4NGE0MDA4MTgyNTgyMDRiZDBmOTkxYzE1MzJjZmZlMzFkNGExMGRiNDkyYjQzMTc1ZWMzMjY3NjViNmIyOWNlZWU1OThkZjJiNjFmNDcwMDAxODE4MjU4MzkwMDg3Mzc5ZWJjNTUzM2ViZTYyMTk2M2M5MTVjM2NiYzVmMDg1MzdmY2RjYTRhZjhmOGFlMDhlZDRjODczNzllYmM1NTMzZWJlNjIxOTYzYzkxNWMzY2JjNWYwODUzN2ZjZGNhNGFmOGY4YWUwOGVkNGMxYTA1ZjM1OWZmMDIxYTAwMDI4NzAxMDMxYTAyNDk3MmUxYTEwMDgxODI1ODIwYmJhY2IxMzQzMWI5OTIwOGU2ZThjZGJmNzEwMTQ3ZmVhZjA2YTM5ZDcxNTY1ZTYwYjQxMWNlOWU0ZmEzZjEzNzU4NDAwMWE0YWI4MjM2NTYzZjY5ZmYzMDllNTc4NmU4ZjM5YzYyOWVkNTc2NzZjNjkyMTU5Y2IyZTA0OTRjOWU2NjMzNTUzODRjMTNjNzQ5ZDA0YzE3YTgwYmEyYTQ1Y2MxMjdkZjQ4MGZjNjRhNDMxOTlhNzcyZjExYWNkNWIxNGEwZmY1ZjYnLFxuICAgICAgICBmZWVJbmZvOiB7XG4gICAgICAgICAgZmVlOiAxMDAwMCxcbiAgICAgICAgICBmZWVTdHJpbmc6ICcxMDAwMCcsXG4gICAgICAgIH0sXG4gICAgICAgIHR4SW5mbzoge1xuICAgICAgICAgIGlucHV0czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhZGRyZXNzOiAnOGlMYTI2S1NiZHBCVXpOSzd1WXE4RnZ5dXlBNWg0azRlckRIc0RjUGJIdXMnLFxuICAgICAgICAgICAgICB2YWx1ZTogMi4wMTczMjI4ZTEwLFxuICAgICAgICAgICAgICB2YWx1ZVN0cmluZzogJzIwMTczMjI4MDAwJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFkZHJlc3M6ICc4UDJrWDdUeWg5ZVMzUktkYUJocWJFdFFHQVg1OERYekw3bWhEUUFCR1gyZCcsXG4gICAgICAgICAgICAgIHZhbHVlOiAxMDAwMCxcbiAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICcxMDAwMCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgbWluZXJGZWU6ICcxMDAwMCcsXG4gICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhZGRyZXNzOiAnYWRkcl90ZXN0MXZyOHJha202NnJjZnY0ZmN4cXlrZzVsZjB5djdsc3lrOW12YXB4MzY5anB2dGNnZmN1azdmJyxcbiAgICAgICAgICAgICAgY29pbk5hbWU6ICd0YWRhOnVzZHQnLFxuICAgICAgICAgICAgICBlbnRlcnByaXNlOiB7XG4gICAgICAgICAgICAgICAgJG9pZDogJzU1NTNiYThhZTdhNWM3NzAwNjcxOTY2MScsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGVudGVycHJpc2VzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgJG9pZDogJzU1NTNiYThhZTdhNWM3NzAwNjcxOTY2MScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgdmFsdWU6IDIuMDE3MzIyOGUxMCxcbiAgICAgICAgICAgICAgdmFsdWVTdHJpbmc6ICcyMDE3MzIyODAwMCcsXG4gICAgICAgICAgICAgIHdhbGxldDoge1xuICAgICAgICAgICAgICAgICRvaWQ6ICc2MmY0YzM3MjBkOTJjNTAwMDgyNTdlYjUnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB3YWxsZXRUeXBlOiAnaG90JyxcbiAgICAgICAgICAgICAgd2FsbGV0czogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICRvaWQ6ICc2MmY0YzM3MjBkOTJjNTAwMDgyNTdlYjUnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgcGF5R29GZWU6ICcwJyxcbiAgICAgICAgICBzcGVuZEFtb3VudDogJzIwMTczMjI4MDAwJyxcbiAgICAgICAgICBzcGVuZEFtb3VudHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYW1vdW50U3RyaW5nOiAnMjAxNzMyMjgwMDAnLFxuICAgICAgICAgICAgICBjb2luTmFtZTogJ3RhZGE6dXNkdCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgdHlwZTogJ1NlbmQnLFxuICAgICAgICB9LFxuICAgICAgICBjb25zb2xpZGF0ZUlkOiAnNjcxMmQ3ZmRhNmRlNDkwNmQ2NThjMDRhZWJiZjhmOWInLFxuICAgICAgICBjb2luOiAndGFkYScsXG4gICAgICB9O1xuXG4gICAgICAvLyBNb2NrIHRoZSB3YWxsZXQgd2l0aCBhIGRpZmZlcmVudCBhZGRyZXNzIHRoYW4gdGhlIHRyYW5zYWN0aW9uJ3Mgb3V0cHV0XG4gICAgICBjb25zdCBtb2NrZWRXYWxsZXQgPSB7XG4gICAgICAgIGNvaW5TcGVjaWZpYzogKCkgPT4ge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByb290QWRkcmVzczpcbiAgICAgICAgICAgICAgJ2FkZHJfdGVzdDFxcW5udnB0cmMzcmVjNjRxMm45amg1NzJuY3U1d3ZkdHQ4dXZnNGczYWo5NnM1ZHd1OW5qNzBtbGFoemdsbTk5Mzl1ZXZ1cHNtajhkY2RxdjI1ZDVuNXI4dnc4c243cHJleScsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC52ZXJpZnlUcmFuc2FjdGlvbih7XG4gICAgICAgICAgdHhQYXJhbXM6IHt9LFxuICAgICAgICAgIHR4UHJlYnVpbGQ6IGNvbnNvbGlkYXRpb25UeCxcbiAgICAgICAgICB3YWxsZXQ6IG1vY2tlZFdhbGxldCxcbiAgICAgICAgICB2ZXJpZmljYXRpb246IHtcbiAgICAgICAgICAgIGNvbnNvbGlkYXRpb25Ub0Jhc2VBZGRyZXNzOiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCd0eCBvdXRwdXRzIGRvZXMgbm90IG1hdGNoIHdpdGggZXhwZWN0ZWQgYWRkcmVzcycpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19