@bitgo/sdk-coin-algo 2.5.2 → 2.5.4

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 (54) hide show
  1. package/dist/test/fixtures/algo.d.ts +101 -0
  2. package/dist/test/fixtures/algo.d.ts.map +1 -0
  3. package/dist/test/fixtures/algo.js +239 -0
  4. package/dist/test/fixtures/resources.d.ts +114 -0
  5. package/dist/test/fixtures/resources.d.ts.map +1 -0
  6. package/dist/test/fixtures/resources.js +123 -0
  7. package/dist/test/integration/algo.integration.d.ts +2 -0
  8. package/dist/test/integration/algo.integration.d.ts.map +1 -0
  9. package/dist/test/integration/algo.integration.js +71 -0
  10. package/dist/test/unit/algo.d.ts +2 -0
  11. package/dist/test/unit/algo.d.ts.map +1 -0
  12. package/dist/test/unit/algo.js +1096 -0
  13. package/dist/test/unit/algoIsWalletAddress.d.ts +2 -0
  14. package/dist/test/unit/algoIsWalletAddress.d.ts.map +1 -0
  15. package/dist/test/unit/algoIsWalletAddress.js +118 -0
  16. package/dist/test/unit/algoToken.d.ts +2 -0
  17. package/dist/test/unit/algoToken.d.ts.map +1 -0
  18. package/dist/test/unit/algoToken.js +79 -0
  19. package/dist/test/unit/fixtures/algoBackupKey.d.ts +4 -0
  20. package/dist/test/unit/fixtures/algoBackupKey.d.ts.map +1 -0
  21. package/dist/test/unit/fixtures/algoBackupKey.js +10 -0
  22. package/dist/test/unit/lib/keyPair.d.ts +2 -0
  23. package/dist/test/unit/lib/keyPair.d.ts.map +1 -0
  24. package/dist/test/unit/lib/keyPair.js +110 -0
  25. package/dist/test/unit/lib/seedEncoding.d.ts +2 -0
  26. package/dist/test/unit/lib/seedEncoding.d.ts.map +1 -0
  27. package/dist/test/unit/lib/seedEncoding.js +59 -0
  28. package/dist/test/unit/lib/transaction.d.ts +2 -0
  29. package/dist/test/unit/lib/transaction.d.ts.map +1 -0
  30. package/dist/test/unit/lib/transaction.js +157 -0
  31. package/dist/test/unit/lib/transactionBuilder/assetTransferBuilder.d.ts +2 -0
  32. package/dist/test/unit/lib/transactionBuilder/assetTransferBuilder.d.ts.map +1 -0
  33. package/dist/test/unit/lib/transactionBuilder/assetTransferBuilder.js +300 -0
  34. package/dist/test/unit/lib/transactionBuilder/base.d.ts +2 -0
  35. package/dist/test/unit/lib/transactionBuilder/base.d.ts.map +1 -0
  36. package/dist/test/unit/lib/transactionBuilder/base.js +310 -0
  37. package/dist/test/unit/lib/transactionBuilder/keyRegistrationBuilder.d.ts +2 -0
  38. package/dist/test/unit/lib/transactionBuilder/keyRegistrationBuilder.d.ts.map +1 -0
  39. package/dist/test/unit/lib/transactionBuilder/keyRegistrationBuilder.js +473 -0
  40. package/dist/test/unit/lib/transactionBuilder/transactionBuilderFactory.d.ts +2 -0
  41. package/dist/test/unit/lib/transactionBuilder/transactionBuilderFactory.d.ts.map +1 -0
  42. package/dist/test/unit/lib/transactionBuilder/transactionBuilderFactory.js +138 -0
  43. package/dist/test/unit/lib/transactionBuilder/transferBuilder.d.ts +2 -0
  44. package/dist/test/unit/lib/transactionBuilder/transferBuilder.d.ts.map +1 -0
  45. package/dist/test/unit/lib/transactionBuilder/transferBuilder.js +290 -0
  46. package/dist/test/unit/lib/utils.d.ts +2 -0
  47. package/dist/test/unit/lib/utils.d.ts.map +1 -0
  48. package/dist/test/unit/lib/utils.js +307 -0
  49. package/dist/tsconfig.tsbuildinfo +1 -0
  50. package/package.json +10 -7
  51. package/.eslintignore +0 -5
  52. package/.mocharc.yml +0 -8
  53. package/CHANGELOG.md +0 -868
  54. package/types/index.d.ts +0 -60
@@ -0,0 +1,1096 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const src_1 = require("../../src");
40
+ const sdk_test_1 = require("@bitgo/sdk-test");
41
+ const sdk_api_1 = require("@bitgo/sdk-api");
42
+ const AlgoResources = __importStar(require("../fixtures/algo"));
43
+ const crypto_1 = require("crypto");
44
+ const statics_1 = require("@bitgo/statics");
45
+ const sinon_1 = __importDefault(require("sinon"));
46
+ const assert_1 = __importDefault(require("assert"));
47
+ const algo_1 = require("../../src/algo");
48
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
49
+ const lib_1 = require("../../src/lib");
50
+ const algoBackupKey_1 = require("./fixtures/algoBackupKey");
51
+ describe('ALGO:', function () {
52
+ let bitgo;
53
+ let basecoin;
54
+ const receiver = AlgoResources.accounts.account2;
55
+ before(function () {
56
+ bitgo = sdk_test_1.TestBitGo.decorate(sdk_api_1.BitGoAPI, { env: 'mock' });
57
+ bitgo.safeRegister('talgo', src_1.Talgo.createInstance);
58
+ bitgo.initializeTestVars();
59
+ basecoin = bitgo.coin('talgo');
60
+ });
61
+ describe('Should Fail: ', () => {
62
+ it('Does not have a txHex', async () => {
63
+ await basecoin
64
+ .explainTransaction({
65
+ params: {},
66
+ })
67
+ .should.be.rejectedWith('missing explain tx parameters');
68
+ });
69
+ it('Does not have a fee', async () => {
70
+ await basecoin
71
+ .explainTransaction({
72
+ params: {
73
+ txHex: 'Some Valid Hex',
74
+ },
75
+ })
76
+ .should.be.rejectedWith('missing explain tx parameters');
77
+ });
78
+ });
79
+ describe('Transfer Builder: ', () => {
80
+ const buildBaseTransferTransaction = ({ destination, amount = 10000, sender, memo = '' }) => {
81
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
82
+ const txBuilder = factory.getTransferBuilder();
83
+ const lease = new Uint8Array((0, crypto_1.randomBytes)(32));
84
+ const note = new Uint8Array(Buffer.from(memo, 'utf-8'));
85
+ txBuilder
86
+ .sender({ address: sender })
87
+ .to({ address: destination })
88
+ .amount(amount)
89
+ .isFlatFee(true)
90
+ .fee({
91
+ fee: '1000',
92
+ })
93
+ .firstRound(1)
94
+ .lastRound(100)
95
+ .lease(lease)
96
+ .note(note)
97
+ .testnet();
98
+ return txBuilder;
99
+ };
100
+ /**
101
+ * Build an unsigned account-lib single-signature send transaction
102
+ * @param sender The senders address
103
+ * @param destination The destination address of the transaction
104
+ * @param amount The amount to send to the recipient
105
+ * @param memo Optional note with the transaction
106
+ */
107
+ const buildUnsignedTransaction = async function ({ sender, destination, amount = 10000, memo = '' }) {
108
+ const txBuilder = buildBaseTransferTransaction({ sender, destination, amount, memo });
109
+ return await txBuilder.build();
110
+ };
111
+ /**
112
+ * Build a signed account-lib single-signature send transaction
113
+ * @param sender The senders address
114
+ * @param destination The destination address of the transaction
115
+ * @param amount The amount to send to the recipient
116
+ * @param memo Optional note with the transaction
117
+ */
118
+ const buildSignedTransaction = async function ({ sender, destination, amount = 10000, memo = '' }) {
119
+ const txBuilder = buildBaseTransferTransaction({ sender, destination, amount, memo });
120
+ txBuilder.numberOfSigners(1);
121
+ txBuilder.sign({ key: AlgoResources.accounts.account1.prvKey });
122
+ return await txBuilder.build();
123
+ };
124
+ /**
125
+ * Build a multi-signed account-lib single-signature send transaction
126
+ * @param senders The list of senders
127
+ * @param destination The destination address of the transaction
128
+ * @param amount The amount to send to the recipient
129
+ * @param memo Optional note with the transaction
130
+ */
131
+ const buildMultiSignedTransaction = async function ({ senders, destination, amount = 10000, memo = '' }) {
132
+ const txBuilder = buildBaseTransferTransaction({ sender: senders[0], destination, amount, memo });
133
+ txBuilder.numberOfSigners(2);
134
+ txBuilder.setSigners(senders);
135
+ txBuilder.sign({ key: AlgoResources.accounts.account1.prvKey });
136
+ txBuilder.sign({ key: AlgoResources.accounts.account3.prvKey });
137
+ return await txBuilder.build();
138
+ };
139
+ it('should explain an unsigned transfer transaction hex', async function () {
140
+ const explain = await basecoin.explainTransaction({
141
+ txHex: AlgoResources.explainRawTx.transfer.unsigned,
142
+ feeInfo: { fee: '1000' },
143
+ });
144
+ explain.outputAmount.should.equal('10000');
145
+ explain.outputs[0].amount.should.equal('10000');
146
+ explain.outputs[0].address.should.equal(receiver.address);
147
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
148
+ explain.fee.should.equal(1000);
149
+ explain.changeAmount.should.equal('0');
150
+ });
151
+ it('should explain a signed transfer transaction hex', async function () {
152
+ const explain = await basecoin.explainTransaction({
153
+ txHex: AlgoResources.explainRawTx.transfer.signed,
154
+ feeInfo: { fee: '1000' },
155
+ });
156
+ explain.outputAmount.should.equal('10000');
157
+ explain.outputs[0].amount.should.equal('10000');
158
+ explain.outputs[0].address.should.equal(receiver.address);
159
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
160
+ explain.fee.should.equal(1000);
161
+ explain.changeAmount.should.equal('0');
162
+ });
163
+ it('should explain a multiSig transfer transaction hex', async function () {
164
+ const explain = await basecoin.explainTransaction({
165
+ txHex: AlgoResources.explainRawTx.transfer.multiSigned,
166
+ feeInfo: { fee: '1000' },
167
+ });
168
+ explain.outputAmount.should.equal('10000');
169
+ explain.outputs[0].amount.should.equal('10000');
170
+ explain.outputs[0].address.should.equal(receiver.address);
171
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
172
+ explain.fee.should.equal(1000);
173
+ explain.changeAmount.should.equal('0');
174
+ });
175
+ it('should explain a half signed transfer transaction hex', async function () {
176
+ const explain = await basecoin.explainTransaction({
177
+ halfSigned: {
178
+ txHex: AlgoResources.explainRawTx.transfer.halfSigned,
179
+ },
180
+ feeInfo: { fee: '1000' },
181
+ });
182
+ explain.outputAmount.should.equal('10000');
183
+ explain.outputs[0].amount.should.equal('10000');
184
+ explain.outputs[0].address.should.equal(receiver.address);
185
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
186
+ explain.fee.should.equal(1000);
187
+ explain.changeAmount.should.equal('0');
188
+ });
189
+ it('should explain an unsigned transaction', async function () {
190
+ const sender = AlgoResources.accounts.account1.address;
191
+ const destination = AlgoResources.accounts.account2.address;
192
+ const amount = 10000;
193
+ const memo = AlgoResources.explainRawTx.transfer.note;
194
+ const unsignedTransaction = await buildUnsignedTransaction({
195
+ sender,
196
+ destination,
197
+ amount,
198
+ memo,
199
+ });
200
+ const unsignedHex = Buffer.from(unsignedTransaction.toBroadcastFormat()).toString('hex');
201
+ const explain = await basecoin.explainTransaction({
202
+ txHex: unsignedHex,
203
+ feeInfo: { fee: '1000' },
204
+ });
205
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
206
+ explain.outputs[0].amount.should.equal(amount.toString());
207
+ explain.outputs[0].address.should.equal(destination);
208
+ });
209
+ it('should explain a signed transaction', async function () {
210
+ const sender = AlgoResources.accounts.account1.address;
211
+ const destination = AlgoResources.accounts.account2.address;
212
+ const amount = 10000;
213
+ const memo = AlgoResources.explainRawTx.transfer.note;
214
+ const signedTransaction = await buildSignedTransaction({
215
+ sender,
216
+ destination,
217
+ amount,
218
+ memo,
219
+ });
220
+ const signedHex = Buffer.from(signedTransaction.toBroadcastFormat()).toString('hex');
221
+ const explain = await basecoin.explainTransaction({
222
+ txHex: signedHex,
223
+ feeInfo: { fee: '1000' },
224
+ });
225
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
226
+ explain.outputs[0].amount.should.equal(amount.toString());
227
+ explain.outputs[0].address.should.equal(destination);
228
+ });
229
+ it('should explain a multiSigned transaction', async function () {
230
+ const senders = [AlgoResources.accounts.account1.address, AlgoResources.accounts.account3.address];
231
+ const destination = AlgoResources.accounts.account2.address;
232
+ const amount = 10000;
233
+ const memo = AlgoResources.explainRawTx.transfer.note;
234
+ const signedTransaction = await buildMultiSignedTransaction({
235
+ senders,
236
+ destination,
237
+ amount,
238
+ memo,
239
+ });
240
+ const signedHex = Buffer.from(signedTransaction.toBroadcastFormat()).toString('hex');
241
+ const explain = await basecoin.explainTransaction({
242
+ txHex: signedHex,
243
+ feeInfo: { fee: '1000' },
244
+ });
245
+ Buffer.from(explain.outputs[0].memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
246
+ explain.outputs[0].amount.should.equal(amount.toString());
247
+ explain.outputs[0].address.should.equal(destination);
248
+ });
249
+ });
250
+ describe('Asset Transfer Builder: ', () => {
251
+ const buildBaseAssetTransferTransaction = ({ destination, amount = 1000, tokenId, sender }) => {
252
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
253
+ const txBuilder = factory.getAssetTransferBuilder();
254
+ const lease = new Uint8Array((0, crypto_1.randomBytes)(32));
255
+ txBuilder
256
+ .sender({ address: sender })
257
+ .isFlatFee(true)
258
+ .fee({
259
+ fee: '1000',
260
+ })
261
+ .tokenId(tokenId)
262
+ .firstRound(1)
263
+ .lastRound(100)
264
+ .lease(lease)
265
+ .to({ address: destination })
266
+ .amount(amount)
267
+ .testnet();
268
+ return txBuilder;
269
+ };
270
+ /**
271
+ * Build an unsigned account-lib single-signature asset transfer transaction
272
+ * @param sender The senders address
273
+ * @param destination The destination address of the transaction
274
+ * @param amount The amount to send to the recipient
275
+ * @param tokenId The assetIndex for the token
276
+ */
277
+ const buildUnsignedTransaction = async function ({ sender, destination, amount = 10000, tokenId }) {
278
+ const txBuilder = buildBaseAssetTransferTransaction({ sender, destination, amount, tokenId });
279
+ return await txBuilder.build();
280
+ };
281
+ /**
282
+ * Build a signed account-lib single-signature send transaction
283
+ * @param sender The senders address
284
+ * @param destination The destination address of the transaction
285
+ * @param amount The amount to send to the recipient
286
+ * @param tokenId The assetIndex for the token
287
+ */
288
+ const buildSignedTransaction = async function ({ sender, destination, amount = 10000, tokenId }) {
289
+ const txBuilder = buildBaseAssetTransferTransaction({ sender, destination, amount, tokenId });
290
+ txBuilder.numberOfSigners(1);
291
+ txBuilder.sign({ key: AlgoResources.accounts.account1.prvKey });
292
+ return await txBuilder.build();
293
+ };
294
+ it('should explain an unsigned asset transfer transaction hex', async function () {
295
+ const explain = await basecoin.explainTransaction({
296
+ txHex: AlgoResources.explainRawTx.assetTransfer.unsigned,
297
+ feeInfo: { fee: '1000' },
298
+ });
299
+ explain.outputAmount.should.equal('1000');
300
+ explain.outputs[0].amount.should.equal('1000');
301
+ explain.outputs[0].address.should.equal(receiver.address);
302
+ explain.fee.should.equal(1000);
303
+ explain.changeAmount.should.equal('0');
304
+ explain.tokenId.should.equal(1);
305
+ });
306
+ it('should explain a signed asset transfer transaction hex', async function () {
307
+ const explain = await basecoin.explainTransaction({
308
+ txHex: AlgoResources.explainRawTx.assetTransfer.signed,
309
+ feeInfo: { fee: '1000' },
310
+ });
311
+ explain.outputAmount.should.equal('10000000000000000000');
312
+ explain.outputs[0].amount.should.equal('10000000000000000000');
313
+ explain.outputs[0].address.should.equal(receiver.address);
314
+ explain.fee.should.equal(1000);
315
+ explain.changeAmount.should.equal('0');
316
+ explain.tokenId.should.equal(1);
317
+ });
318
+ it('should explain an unsigned transaction', async function () {
319
+ const sender = AlgoResources.accounts.account1.address;
320
+ const destination = AlgoResources.accounts.account2.address;
321
+ const amount = 10000;
322
+ const tokenId = 1;
323
+ const unsignedTransaction = await buildUnsignedTransaction({
324
+ sender,
325
+ destination,
326
+ amount,
327
+ tokenId,
328
+ });
329
+ const unsignedHex = Buffer.from(unsignedTransaction.toBroadcastFormat()).toString('hex');
330
+ const explain = await basecoin.explainTransaction({
331
+ txHex: unsignedHex,
332
+ feeInfo: { fee: '1000' },
333
+ });
334
+ explain.outputs[0].amount.should.equal(amount.toString());
335
+ explain.outputs[0].address.should.equal(destination);
336
+ explain.tokenId.should.equal(1);
337
+ });
338
+ it('should explain a signed transaction', async function () {
339
+ const sender = AlgoResources.accounts.account1.address;
340
+ const destination = AlgoResources.accounts.account2.address;
341
+ const amount = 10000;
342
+ const tokenId = 1;
343
+ const signedTransaction = await buildSignedTransaction({
344
+ sender,
345
+ destination,
346
+ amount,
347
+ tokenId,
348
+ });
349
+ const signedHex = Buffer.from(signedTransaction.toBroadcastFormat()).toString('hex');
350
+ const explain = await basecoin.explainTransaction({
351
+ txHex: signedHex,
352
+ feeInfo: { fee: '1000' },
353
+ });
354
+ explain.outputs[0].amount.should.equal(amount.toString());
355
+ explain.outputs[0].address.should.equal(destination);
356
+ explain.tokenId.should.equal(1);
357
+ });
358
+ });
359
+ describe('Wallet Init Builder: ', () => {
360
+ const buildBaseKeyRegTransaction = ({ sender, memo = '' }) => {
361
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
362
+ const txBuilder = factory.getWalletInitializationBuilder();
363
+ const lease = new Uint8Array((0, crypto_1.randomBytes)(32));
364
+ const note = new Uint8Array(Buffer.from(memo, 'utf-8'));
365
+ txBuilder
366
+ .sender({ address: sender.address })
367
+ .isFlatFee(true)
368
+ .fee({
369
+ fee: '1000',
370
+ })
371
+ .firstRound(1)
372
+ .lastRound(100)
373
+ .lease(lease)
374
+ .note(note)
375
+ .voteKey(sender.voteKey)
376
+ .selectionKey(sender.selectionKey)
377
+ .voteFirst(1)
378
+ .voteLast(100)
379
+ .voteKeyDilution(9)
380
+ .testnet();
381
+ return txBuilder;
382
+ };
383
+ /**
384
+ * Build an unsigned account-lib single-signature send transaction
385
+ * @param sender The senders address
386
+ * @param memo Optional note with the transaction
387
+ */
388
+ const buildUnsignedTransaction = async function ({ sender, memo = '' }) {
389
+ const txBuilder = buildBaseKeyRegTransaction({ sender, memo });
390
+ return await txBuilder.build();
391
+ };
392
+ /**
393
+ * Build a signed account-lib single-signature send transaction
394
+ * @param sender The senders address
395
+ * @param memo Optional note with the transaction
396
+ */
397
+ const buildSignedTransaction = async function ({ sender, memo = '' }) {
398
+ const txBuilder = buildBaseKeyRegTransaction({ sender, memo });
399
+ txBuilder.numberOfSigners(1);
400
+ txBuilder.sign({ key: AlgoResources.accounts.account1.prvKey });
401
+ return await txBuilder.build();
402
+ };
403
+ /**
404
+ * Build a multi-signed account-lib single-signature send transaction
405
+ * @param senders The list of senders
406
+ * @param memo Optional note with the transaction
407
+ */
408
+ const buildMultiSignedTransaction = async function ({ senders, memo = '' }) {
409
+ const txBuilder = buildBaseKeyRegTransaction({ sender: senders[0], memo });
410
+ txBuilder.numberOfSigners(2);
411
+ txBuilder.setSigners(senders.map(({ address }) => address));
412
+ txBuilder.sign({ key: AlgoResources.accounts.account1.prvKey });
413
+ txBuilder.sign({ key: AlgoResources.accounts.account3.prvKey });
414
+ return await txBuilder.build();
415
+ };
416
+ it('should explain an unsigned KeyReg transfer transaction hex', async function () {
417
+ const sender = AlgoResources.accounts.account1;
418
+ const explain = await basecoin.explainTransaction({
419
+ txHex: AlgoResources.explainRawTx.keyreg.unsigned,
420
+ feeInfo: { fee: '1000' },
421
+ });
422
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.keyreg.note);
423
+ explain.fee.should.equal(1000);
424
+ explain.changeAmount.should.equal('0');
425
+ explain.voteKey.should.equal(sender.voteKey);
426
+ explain.selectionKey.should.equal(sender.selectionKey);
427
+ explain.voteFirst.should.equal(1);
428
+ explain.voteLast.should.equal(100);
429
+ explain.voteKeyDilution.should.equal(9);
430
+ });
431
+ it('should explain a signed transfer transaction hex', async function () {
432
+ const sender = AlgoResources.accounts.account1;
433
+ const explain = await basecoin.explainTransaction({
434
+ txHex: AlgoResources.explainRawTx.keyreg.signed,
435
+ feeInfo: { fee: '1000' },
436
+ });
437
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.keyreg.note);
438
+ explain.fee.should.equal(1000);
439
+ explain.changeAmount.should.equal('0');
440
+ explain.voteKey.should.equal(sender.voteKey);
441
+ explain.selectionKey.should.equal(sender.selectionKey);
442
+ explain.voteFirst.should.equal(1);
443
+ explain.voteLast.should.equal(100);
444
+ explain.voteKeyDilution.should.equal(9);
445
+ });
446
+ it('should explain a multiSig transfer transaction hex', async function () {
447
+ const sender = AlgoResources.accounts.account1;
448
+ const explain = await basecoin.explainTransaction({
449
+ txHex: AlgoResources.explainRawTx.keyreg.multiSigned,
450
+ feeInfo: { fee: '1000' },
451
+ });
452
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.keyreg.note);
453
+ explain.fee.should.equal(1000);
454
+ explain.changeAmount.should.equal('0');
455
+ explain.voteKey.should.equal(sender.voteKey);
456
+ explain.selectionKey.should.equal(sender.selectionKey);
457
+ explain.voteFirst.should.equal(1);
458
+ explain.voteLast.should.equal(100);
459
+ explain.voteKeyDilution.should.equal(9);
460
+ });
461
+ it('should explain a half signed transfer transaction hex', async function () {
462
+ const sender = AlgoResources.accounts.account1;
463
+ const explain = await basecoin.explainTransaction({
464
+ halfSigned: {
465
+ txHex: AlgoResources.explainRawTx.keyreg.halfSigned,
466
+ },
467
+ feeInfo: { fee: '1000' },
468
+ });
469
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.keyreg.note);
470
+ explain.fee.should.equal(1000);
471
+ explain.changeAmount.should.equal('0');
472
+ explain.voteKey.should.equal(sender.voteKey);
473
+ explain.selectionKey.should.equal(sender.selectionKey);
474
+ explain.voteFirst.should.equal(1);
475
+ explain.voteLast.should.equal(100);
476
+ explain.voteKeyDilution.should.equal(9);
477
+ });
478
+ it('should explain an unsigned transaction', async function () {
479
+ const sender = AlgoResources.accounts.account1;
480
+ const memo = AlgoResources.explainRawTx.transfer.note;
481
+ const unsignedTransaction = await buildUnsignedTransaction({
482
+ sender,
483
+ memo,
484
+ });
485
+ const unsignedHex = Buffer.from(unsignedTransaction.toBroadcastFormat()).toString('hex');
486
+ const explain = await basecoin.explainTransaction({
487
+ txHex: unsignedHex,
488
+ feeInfo: { fee: '1000' },
489
+ });
490
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
491
+ explain.voteKey.should.equal(sender.voteKey);
492
+ explain.selectionKey.should.equal(sender.selectionKey);
493
+ explain.voteFirst.should.equal(1);
494
+ explain.voteLast.should.equal(100);
495
+ explain.voteKeyDilution.should.equal(9);
496
+ });
497
+ it('should explain a signed transaction', async function () {
498
+ const sender = AlgoResources.accounts.account1;
499
+ const memo = AlgoResources.explainRawTx.transfer.note;
500
+ const signedTransaction = await buildSignedTransaction({
501
+ sender,
502
+ memo,
503
+ });
504
+ const signedHex = Buffer.from(signedTransaction.toBroadcastFormat()).toString('hex');
505
+ const explain = await basecoin.explainTransaction({
506
+ txHex: signedHex,
507
+ feeInfo: { fee: '1000' },
508
+ });
509
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
510
+ explain.voteKey.should.equal(sender.voteKey);
511
+ explain.selectionKey.should.equal(sender.selectionKey);
512
+ explain.voteFirst.should.equal(1);
513
+ explain.voteLast.should.equal(100);
514
+ explain.voteKeyDilution.should.equal(9);
515
+ });
516
+ it('should explain a multiSigned transaction', async function () {
517
+ const senders = [AlgoResources.accounts.account1, AlgoResources.accounts.account3];
518
+ const memo = AlgoResources.explainRawTx.transfer.note;
519
+ const signedTransaction = await buildMultiSignedTransaction({
520
+ senders,
521
+ memo,
522
+ });
523
+ const signedHex = Buffer.from(signedTransaction.toBroadcastFormat()).toString('hex');
524
+ const explain = await basecoin.explainTransaction({
525
+ txHex: signedHex,
526
+ feeInfo: { fee: '1000' },
527
+ });
528
+ Buffer.from(explain.memo).toString().should.equal(AlgoResources.explainRawTx.transfer.note);
529
+ explain.voteKey.should.equal(AlgoResources.accounts.account1.voteKey);
530
+ explain.selectionKey.should.equal(AlgoResources.accounts.account1.selectionKey);
531
+ explain.voteFirst.should.equal(1);
532
+ explain.voteLast.should.equal(100);
533
+ explain.voteKeyDilution.should.equal(9);
534
+ });
535
+ });
536
+ describe('Sign transaction', () => {
537
+ it('should sign transaction', async function () {
538
+ const signed = await basecoin.signTransaction({
539
+ txPrebuild: {
540
+ txHex: AlgoResources.rawTx.transfer.unsigned,
541
+ keys: [AlgoResources.accounts.account1.pubKey.toString('hex')],
542
+ addressVersion: 1,
543
+ },
544
+ prv: AlgoResources.accounts.account1.prvKey,
545
+ });
546
+ signed.txHex.should.equal(AlgoResources.rawTx.transfer.signed);
547
+ });
548
+ it('should sign transaction with root key', async function () {
549
+ const keypair = basecoin.generateRootKeyPair(AlgoResources.accounts.account1.secretKey);
550
+ const signed = await basecoin.signTransaction({
551
+ txPrebuild: {
552
+ txHex: AlgoResources.rawTx.transfer.unsigned,
553
+ keys: [keypair.pub],
554
+ addressVersion: 1,
555
+ },
556
+ prv: keypair.prv,
557
+ });
558
+ signed.txHex.should.equal(AlgoResources.rawTx.transfer.signed);
559
+ });
560
+ it('should sign half signed transaction', async function () {
561
+ const signed = await basecoin.signTransaction({
562
+ txPrebuild: {
563
+ halfSigned: {
564
+ txHex: AlgoResources.rawTx.transfer.halfSigned,
565
+ },
566
+ keys: [
567
+ AlgoResources.accounts.account1.pubKey.toString('hex'),
568
+ AlgoResources.accounts.account3.pubKey.toString('hex'),
569
+ ],
570
+ addressVersion: 1,
571
+ },
572
+ prv: AlgoResources.accounts.account3.prvKey,
573
+ });
574
+ signed.txHex.should.equal(AlgoResources.rawTx.transfer.multisig);
575
+ });
576
+ it('should sign half signed transaction with root key', async function () {
577
+ const signed = await basecoin.signTransaction({
578
+ txPrebuild: {
579
+ halfSigned: {
580
+ txHex: AlgoResources.rootKeyData.unsignedTx,
581
+ },
582
+ keys: [
583
+ AlgoResources.rootKeyData.userKeyPair.pub,
584
+ AlgoResources.rootKeyData.backupPub,
585
+ AlgoResources.rootKeyData.bitgoPub,
586
+ ],
587
+ addressVersion: 1,
588
+ },
589
+ prv: AlgoResources.rootKeyData.userKeyPair.prv,
590
+ });
591
+ signed.txHex.should.deepEqual(AlgoResources.rootKeyData.halfSignedTx);
592
+ const factory = new lib_1.TransactionBuilderFactory(statics_1.coins.get('algo'));
593
+ const tx = await factory.from(signed.txHex).build();
594
+ const txJson = tx.toJson();
595
+ txJson.from.should.equal(AlgoResources.rootKeyData.senderAddress);
596
+ });
597
+ it('should verify sign params if the key array contains addresses', function () {
598
+ const keys = [
599
+ AlgoResources.accounts.account1.address,
600
+ AlgoResources.accounts.account2.address,
601
+ AlgoResources.accounts.account3.address,
602
+ ];
603
+ const verifiedParams = basecoin.verifySignTransactionParams({
604
+ txPrebuild: {
605
+ txHex: AlgoResources.rawTx.transfer.unsigned,
606
+ keys,
607
+ addressVersion: 1,
608
+ },
609
+ prv: AlgoResources.accounts.account2.secretKey.toString('hex'),
610
+ });
611
+ verifiedParams.should.have.properties([
612
+ 'txHex',
613
+ 'addressVersion',
614
+ 'signers',
615
+ 'prv',
616
+ 'isHalfSigned',
617
+ 'numberSigners',
618
+ ]);
619
+ const { txHex, signers, isHalfSigned } = verifiedParams;
620
+ txHex.should.be.equal(AlgoResources.rawTx.transfer.unsigned);
621
+ signers.should.be.deepEqual(keys);
622
+ isHalfSigned.should.be.equal(false);
623
+ });
624
+ it('should sign half signed transaction if the key array contains addresses', async function () {
625
+ const signed = await basecoin.signTransaction({
626
+ txPrebuild: {
627
+ halfSigned: {
628
+ txHex: AlgoResources.rawTx.transfer.halfSigned,
629
+ },
630
+ keys: [AlgoResources.accounts.account1.address, AlgoResources.accounts.account3.address],
631
+ addressVersion: 1,
632
+ },
633
+ prv: AlgoResources.accounts.account3.prvKey,
634
+ });
635
+ signed.txHex.should.equal(AlgoResources.rawTx.transfer.multisig);
636
+ });
637
+ });
638
+ describe('Sign message', () => {
639
+ it('should sign message', async function () {
640
+ const signed = await basecoin.signMessage({ prv: AlgoResources.accounts.account1.prvKey }, AlgoResources.message.unsigned);
641
+ signed.toString('hex').should.equal(AlgoResources.message.signed);
642
+ });
643
+ });
644
+ describe('Generate wallet key pair: ', () => {
645
+ it('should generate key pair', () => {
646
+ const kp = basecoin.generateKeyPair();
647
+ basecoin.isValidPub(kp.pub).should.equal(true);
648
+ basecoin.isValidPrv(kp.prv).should.equal(true);
649
+ });
650
+ it('should generate key pair from seed', () => {
651
+ const seed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
652
+ const kp = basecoin.generateKeyPair(seed);
653
+ basecoin.isValidPub(kp.pub).should.equal(true);
654
+ basecoin.isValidPrv(kp.prv).should.equal(true);
655
+ });
656
+ });
657
+ describe('Generate wallet Root key pair: ', () => {
658
+ it('should generate key pair', () => {
659
+ const kp = basecoin.generateRootKeyPair();
660
+ basecoin.isValidPub(kp.pub).should.equal(true);
661
+ basecoin.isValidPrv(kp.prv).should.equal(true);
662
+ });
663
+ it('should generate key pair from seed', () => {
664
+ const seed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
665
+ const kp = basecoin.generateRootKeyPair(seed);
666
+ basecoin.isValidPub(kp.pub).should.equal(true);
667
+ kp.pub.should.equal('d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a');
668
+ basecoin.isValidPrv(kp.prv).should.equal(true);
669
+ kp.prv.should.equal('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a');
670
+ });
671
+ });
672
+ describe('Enable, disable and transfer Token ', () => {
673
+ it('should explain an enable token transaction hex', async function () {
674
+ const explain = await basecoin.explainTransaction({
675
+ txHex: AlgoResources.explainRawTx.enableToken,
676
+ feeInfo: { fee: '1000' },
677
+ });
678
+ explain.operations.length.should.equals(1);
679
+ explain.operations[0].type.should.equals('enableToken');
680
+ explain.operations[0].coin.should.equals('talgo:USON-16026728');
681
+ });
682
+ it('should explain an disable token transaction hex', async function () {
683
+ const explain = await basecoin.explainTransaction({
684
+ txHex: AlgoResources.explainRawTx.disableToken,
685
+ feeInfo: { fee: '1000' },
686
+ });
687
+ explain.operations.length.should.equals(1);
688
+ explain.operations[0].type.should.equals('disableToken');
689
+ explain.operations[0].coin.should.equals('talgo:USON-16026728');
690
+ });
691
+ it('should explain an transfer token transaction hex', async function () {
692
+ const explain = await basecoin.explainTransaction({
693
+ txHex: AlgoResources.explainRawTx.assetTransfer.signed,
694
+ feeInfo: { fee: '1000' },
695
+ });
696
+ explain.operations.length.should.equals(1);
697
+ explain.operations[0].type.should.equals('transferToken');
698
+ explain.operations[0].coin.should.equals('AlgoToken unknown');
699
+ });
700
+ it('should explain an enable USDT token transaction hex', async function () {
701
+ const explain = await basecoin.explainTransaction({
702
+ txHex: AlgoResources.explainRawTx.enableTokenUSDT,
703
+ feeInfo: { fee: '1000' },
704
+ });
705
+ explain.operations.length.should.equals(1);
706
+ explain.operations[0].type.should.equals('enableToken');
707
+ explain.operations[0].coin.should.equals('talgo:USDt-180447');
708
+ });
709
+ it('should explain an enable USDC token transaction hex', async function () {
710
+ const explain = await basecoin.explainTransaction({
711
+ txHex: AlgoResources.explainRawTx.enableTokenUSDC,
712
+ feeInfo: { fee: '1000' },
713
+ });
714
+ explain.operations.length.should.equals(1);
715
+ explain.operations[0].type.should.equals('enableToken');
716
+ explain.operations[0].coin.should.equals('talgo:USDC-10458941');
717
+ });
718
+ it('should explain an disable USDC token transaction hex', async function () {
719
+ const explain = await basecoin.explainTransaction({
720
+ txHex: AlgoResources.explainRawTx.disableTokenUSDC,
721
+ feeInfo: { fee: '1000' },
722
+ });
723
+ explain.operations.length.should.equals(1);
724
+ explain.operations[0].type.should.equals('disableToken');
725
+ explain.operations[0].coin.should.equals('talgo:USDC-10458941');
726
+ });
727
+ it('should explain an transfer USDC token transaction hex', async function () {
728
+ const explain = await basecoin.explainTransaction({
729
+ txHex: AlgoResources.explainRawTx.USDCAssetTransfer.signed,
730
+ feeInfo: { fee: '1000' },
731
+ });
732
+ explain.operations.length.should.equals(1);
733
+ explain.operations[0].type.should.equals('transferToken');
734
+ explain.operations[0].coin.should.equals('talgo:USDC-10458941');
735
+ });
736
+ });
737
+ describe('deriveKeyWithSeed', function () {
738
+ it('should derive key with seed', function () {
739
+ (() => {
740
+ basecoin.deriveKeyWithSeed('test');
741
+ }).should.throw('method deriveKeyWithSeed not supported for eddsa curve');
742
+ });
743
+ });
744
+ describe('Recovery', function () {
745
+ const fee = 1000;
746
+ const userKey = '{"iv":"ZJg0a0+zT+684MUl44Lm4A==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"abQy0OL2468=","ct":"LNlSlTJED8jSwHCmUflzqFtRPL+PojzOgfd5mD2nmLVdAoyKCWHvAieKt7lJ7zg417CUi6Qj77/s3lbqmxVsfEsk"}';
747
+ const userPub = 'S4D7DDRAHWZIB2RCZICSRODFCNQXGANHGA7VCWBK5I37SQT6KVHXQNKMTE';
748
+ const backupKey = '{"iv":"mZY8XTvHxX8BPc1rdGQQww==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"abQy0OL2468=","ct":"UQXo0EaPXb6TIZDYYhKYS9d/fRMNT6ptpl9BgJw3AVooSbO4nppWnTRYlQO7hpON4XY85hYDu/7hy91IX1z1bDDq"}';
749
+ const backupPub = '6FVGZUZOHZSXTTBRLWZDXGYSWVVYNN4ZESIEMZEMIBJCUBHC5C77OIE5RQ';
750
+ const rootAddress = 'FWLNDL7UXCSOPOQXA5VU2DMANZAYCCMBY377HKTGGMZ4GEPEJBFARDOGBA';
751
+ const walletPassphrase = 'Testing@43210!';
752
+ const recoveryDestination = 'GB3YETD5TSTBAIYGYHVWU3O3I7XGOB44HOZA5MOEF5M23CLLZKRQLEVAOA';
753
+ const bitgoPub = 'FJSWLLPRBXEGMWZY5BXA6673YKIK7JOURVCQEOWXC5TQPCXCOK3VHOO2VQ';
754
+ const nativeBalance = 10000000; // 10 ALGO
755
+ const MIN_ACCOUNT_BALANCE = 100000; // 1 AGLO
756
+ const nodeParams = {
757
+ token: '2810c2d168e8417c5f111d38d68327b8cfe2d0ddc02986490c22f8ddf4128bcd',
758
+ baseServer: 'http://localhost/',
759
+ port: 8443,
760
+ };
761
+ describe('Non-BitGo', async function () {
762
+ const sandBox = sinon_1.default.createSandbox();
763
+ const expectedAmount = new bignumber_js_1.default(nativeBalance).minus(fee).minus(MIN_ACCOUNT_BALANCE).toString();
764
+ afterEach(function () {
765
+ sandBox.verifyAndRestore();
766
+ });
767
+ it('should build and sign the recovery tx', async function () {
768
+ const getBalanceStub = sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(nativeBalance);
769
+ const recovery = await basecoin.recover({
770
+ userKey,
771
+ backupKey,
772
+ rootAddress,
773
+ walletPassphrase,
774
+ fee,
775
+ bitgoKey: bitgoPub,
776
+ recoveryDestination: recoveryDestination,
777
+ firstRound: 5002596,
778
+ nodeParams,
779
+ });
780
+ recovery.should.not.be.undefined();
781
+ recovery.should.have.property('id');
782
+ recovery.should.have.property('tx');
783
+ recovery.should.have.property('fee');
784
+ recovery.should.have.property('coin', 'talgo');
785
+ recovery.should.have.property('firstRound');
786
+ recovery.should.have.property('lastRound');
787
+ getBalanceStub.callCount.should.equal(1);
788
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
789
+ const txBuilder = factory.from(recovery.tx);
790
+ const tx = await txBuilder.build();
791
+ const txBroadcastFormat = Buffer.from(tx.toBroadcastFormat()).toString('base64');
792
+ txBroadcastFormat.should.deepEqual(recovery.tx);
793
+ const txJson = tx.toJson();
794
+ txJson.amount.should.equal(expectedAmount);
795
+ txJson.to.should.equal(recoveryDestination);
796
+ txJson.from.should.equal(rootAddress);
797
+ txJson.fee.should.equal(fee);
798
+ });
799
+ it('should throw for invalid rootAddress', async function () {
800
+ const invalidRootAddress = 'randomstring';
801
+ await assert_1.default.rejects(async () => {
802
+ await basecoin.recover({
803
+ userKey,
804
+ backupKey,
805
+ rootAddress: invalidRootAddress,
806
+ walletPassphrase,
807
+ fee,
808
+ recoveryDestination: recoveryDestination,
809
+ firstRound: 5002596,
810
+ nodeParams,
811
+ });
812
+ }, { message: 'invalid rootAddress, got: ' + invalidRootAddress });
813
+ });
814
+ it('should throw for invalid recoveryDestination', async function () {
815
+ const invalidRecoveryDestination = 'randomstring';
816
+ await assert_1.default.rejects(async () => {
817
+ await basecoin.recover({
818
+ userKey,
819
+ backupKey,
820
+ rootAddress,
821
+ walletPassphrase,
822
+ fee,
823
+ recoveryDestination: invalidRecoveryDestination,
824
+ firstRound: 5002596,
825
+ nodeParams,
826
+ });
827
+ }, { message: 'invalid recoveryDestination, got: ' + invalidRecoveryDestination });
828
+ });
829
+ it('should throw if there is no enough balance to recover', async function () {
830
+ const getBalanceStub = sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(100500);
831
+ await assert_1.default.rejects(async () => {
832
+ await basecoin.recover({
833
+ userKey,
834
+ backupKey,
835
+ rootAddress,
836
+ fee,
837
+ walletPassphrase,
838
+ bitgoKey: bitgoPub,
839
+ recoveryDestination,
840
+ firstRound: 5003596,
841
+ nodeParams,
842
+ });
843
+ }, { message: 'Insufficient balance to recover, got balance: 100500 fee: 1000 min account balance: 100000' });
844
+ getBalanceStub.callCount.should.equal(1);
845
+ });
846
+ it('should throw if the walletPassphrase is undefined', async function () {
847
+ await assert_1.default.rejects(async () => {
848
+ await basecoin.recover({
849
+ userKey,
850
+ backupKey,
851
+ rootAddress,
852
+ fee,
853
+ recoveryDestination,
854
+ firstRound: 5003596,
855
+ nodeParams,
856
+ });
857
+ }, { message: 'walletPassphrase is required for non-bitgo recovery' });
858
+ });
859
+ it('should throw if the walletPassphrase is wrong', async function () {
860
+ await assert_1.default.rejects(async () => {
861
+ await basecoin.recover({
862
+ userKey,
863
+ backupKey,
864
+ rootAddress,
865
+ bitgoKey: bitgoPub,
866
+ walletPassphrase: 'wrongpassword',
867
+ fee,
868
+ recoveryDestination,
869
+ firstRound: 5003596,
870
+ nodeParams,
871
+ });
872
+ }, {
873
+ message: "unable to decrypt userKey or backupKey with the walletPassphrase provided, got error: password error - ccm: tag doesn't match",
874
+ });
875
+ });
876
+ it('should throw if bitgo key is not provided', async function () {
877
+ await assert_1.default.rejects(async () => {
878
+ await basecoin.recover({
879
+ userKey,
880
+ backupKey,
881
+ rootAddress,
882
+ walletPassphrase,
883
+ fee,
884
+ recoveryDestination,
885
+ firstRound: 5003596,
886
+ nodeParams,
887
+ });
888
+ }, {
889
+ message: 'bitgo public key from the keyCard is required for non-bitgo recovery',
890
+ });
891
+ });
892
+ it('should be able to pass a utf-8 encoded note', async function () {
893
+ const note = 'Non-BitGo Recovery Sweep Tx';
894
+ sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(nativeBalance);
895
+ const recovery = await basecoin.recover({
896
+ userKey,
897
+ backupKey,
898
+ rootAddress,
899
+ walletPassphrase,
900
+ fee,
901
+ bitgoKey: bitgoPub,
902
+ recoveryDestination: recoveryDestination,
903
+ firstRound: 5002596,
904
+ nodeParams,
905
+ note,
906
+ });
907
+ recovery.should.not.be.undefined();
908
+ recovery.note.should.be.equal(note);
909
+ });
910
+ });
911
+ describe('Unsigned Sweep', function () {
912
+ const sandBox = sinon_1.default.createSandbox();
913
+ const expectedAmount = new bignumber_js_1.default(nativeBalance).minus(fee).minus(MIN_ACCOUNT_BALANCE).toString();
914
+ let getBalanceStub;
915
+ beforeEach(function () {
916
+ getBalanceStub = sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(nativeBalance);
917
+ });
918
+ afterEach(function () {
919
+ sandBox.verifyAndRestore();
920
+ });
921
+ it('should build unsigned sweep tx', async function () {
922
+ const recovery = await basecoin.recover({
923
+ userKey: userPub,
924
+ backupKey: backupPub,
925
+ bitgoKey: bitgoPub,
926
+ rootAddress,
927
+ walletPassphrase,
928
+ fee,
929
+ recoveryDestination,
930
+ firstRound: 5003596,
931
+ nodeParams,
932
+ });
933
+ getBalanceStub.callCount.should.equal(1);
934
+ recovery.should.not.be.undefined();
935
+ recovery.should.have.property('txHex');
936
+ recovery.should.have.property('type');
937
+ recovery.should.have.property('amount');
938
+ recovery.should.have.property('feeInfo');
939
+ recovery.should.have.property('coin', 'talgo');
940
+ recovery.firstRound.should.not.be.undefined();
941
+ recovery.lastRound.should.not.be.undefined();
942
+ recovery.should.have.property('keys');
943
+ recovery.keys.should.deepEqual([userPub, backupPub, bitgoPub]);
944
+ recovery.addressVersion.should.equal(1);
945
+ getBalanceStub.callCount.should.equal(1);
946
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
947
+ const txBuilder = factory.from(recovery.txHex);
948
+ const tx = await txBuilder.build();
949
+ Buffer.from(tx.toBroadcastFormat()).toString('hex').should.deepEqual(recovery.txHex);
950
+ const txJson = tx.toJson();
951
+ txJson.amount.should.equal(expectedAmount);
952
+ txJson.to.should.equal(recoveryDestination);
953
+ txJson.from.should.equal(rootAddress);
954
+ txJson.fee.should.equal(fee);
955
+ });
956
+ });
957
+ describe('Recovery with root keys', function () {
958
+ const sandBox = sinon_1.default.createSandbox();
959
+ let userKp;
960
+ let backupKp;
961
+ let rootAddress;
962
+ let encryptedUserPrv;
963
+ let encryptedBackupPrv;
964
+ const expectedAmount = new bignumber_js_1.default(nativeBalance).minus(fee).minus(MIN_ACCOUNT_BALANCE).toString();
965
+ let getBalanceStub;
966
+ beforeEach(function () {
967
+ const userSeed = Buffer.from('9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
968
+ userKp = basecoin.generateRootKeyPair(userSeed);
969
+ encryptedUserPrv = bitgo.encrypt({
970
+ input: userKp.prv,
971
+ password: walletPassphrase,
972
+ });
973
+ (0, assert_1.default)(userKp.pub);
974
+ const backupSeed = Buffer.from('6d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60', 'hex');
975
+ backupKp = basecoin.generateRootKeyPair(backupSeed);
976
+ encryptedBackupPrv = bitgo.encrypt({
977
+ input: backupKp.prv,
978
+ password: walletPassphrase,
979
+ });
980
+ const bitgoPub = 'FJSWLLPRBXEGMWZY5BXA6673YKIK7JOURVCQEOWXC5TQPCXCOK3VHOO2VQ';
981
+ const userAddress = src_1.AlgoLib.algoUtils.privateKeyToAlgoAddress(userKp.prv);
982
+ const backupAddress = src_1.AlgoLib.algoUtils.privateKeyToAlgoAddress(backupKp.prv);
983
+ rootAddress = src_1.AlgoLib.algoUtils.multisigAddress(1, 2, [userAddress, backupAddress, bitgoPub]);
984
+ });
985
+ afterEach(function () {
986
+ sandBox.verifyAndRestore();
987
+ });
988
+ it('should build and sign non-bitgo recovery tx with root keys', async function () {
989
+ getBalanceStub = sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(nativeBalance);
990
+ const recovery = await basecoin.recover({
991
+ userKey: encryptedUserPrv,
992
+ backupKey: encryptedBackupPrv,
993
+ rootAddress,
994
+ walletPassphrase,
995
+ fee,
996
+ bitgoKey: bitgoPub,
997
+ recoveryDestination: recoveryDestination,
998
+ firstRound: 5002596,
999
+ nodeParams,
1000
+ });
1001
+ recovery.should.not.be.undefined();
1002
+ recovery.should.have.property('id');
1003
+ recovery.should.have.property('tx');
1004
+ recovery.should.have.property('fee');
1005
+ recovery.should.have.property('coin', 'talgo');
1006
+ recovery.should.have.property('firstRound');
1007
+ recovery.should.have.property('lastRound');
1008
+ getBalanceStub.callCount.should.equal(1);
1009
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
1010
+ const txBuilder = factory.from(recovery.tx);
1011
+ const tx = await txBuilder.build();
1012
+ const txBroadcastFormat = Buffer.from(tx.toBroadcastFormat()).toString('base64');
1013
+ txBroadcastFormat.should.deepEqual(recovery.tx);
1014
+ const txJson = tx.toJson();
1015
+ txJson.amount.should.equal(expectedAmount);
1016
+ txJson.to.should.equal(recoveryDestination);
1017
+ txJson.from.should.equal(rootAddress);
1018
+ txJson.fee.should.equal(fee);
1019
+ });
1020
+ it('should build unsigned sweep tx', async function () {
1021
+ getBalanceStub = sandBox.stub(algo_1.Algo.prototype, 'getAccountBalance').resolves(nativeBalance);
1022
+ const recovery = await basecoin.recover({
1023
+ userKey: userKp.pub,
1024
+ backupKey: backupKp.pub,
1025
+ bitgoKey: bitgoPub,
1026
+ rootAddress,
1027
+ walletPassphrase,
1028
+ fee,
1029
+ recoveryDestination,
1030
+ firstRound: 5003596,
1031
+ nodeParams,
1032
+ });
1033
+ getBalanceStub.callCount.should.equal(1);
1034
+ recovery.should.not.be.undefined();
1035
+ recovery.should.have.property('txHex');
1036
+ recovery.should.have.property('type');
1037
+ recovery.should.have.property('amount');
1038
+ recovery.should.have.property('feeInfo');
1039
+ recovery.should.have.property('coin', 'talgo');
1040
+ recovery.firstRound.should.not.be.undefined();
1041
+ recovery.lastRound.should.not.be.undefined();
1042
+ recovery.should.have.property('keys');
1043
+ recovery.keys.should.deepEqual([userKp.pub, backupKp.pub, bitgoPub]);
1044
+ recovery.addressVersion.should.equal(1);
1045
+ getBalanceStub.callCount.should.equal(1);
1046
+ const factory = new src_1.AlgoLib.TransactionBuilderFactory(statics_1.coins.get('algo'));
1047
+ const txBuilder = factory.from(recovery.txHex);
1048
+ const tx = await txBuilder.build();
1049
+ Buffer.from(tx.toBroadcastFormat()).toString('hex').should.deepEqual(recovery.txHex);
1050
+ const txJson = tx.toJson();
1051
+ txJson.amount.should.equal(expectedAmount);
1052
+ txJson.to.should.equal(recoveryDestination);
1053
+ txJson.from.should.equal(rootAddress);
1054
+ txJson.fee.should.equal(fee);
1055
+ });
1056
+ });
1057
+ });
1058
+ describe('AuditKey', () => {
1059
+ const { key } = algoBackupKey_1.algoBackupKey;
1060
+ const walletPassphrase = 'ZQ8MhxT84m4P';
1061
+ it('should return for valid inputs', () => {
1062
+ basecoin.assertIsValidKey({
1063
+ encryptedPrv: key,
1064
+ walletPassphrase,
1065
+ });
1066
+ });
1067
+ it('should throw error if the walletPassphrase is incorrect', () => {
1068
+ assert_1.default.throws(() => {
1069
+ basecoin.assertIsValidKey({
1070
+ encryptedPrv: key,
1071
+ walletPassphrase: 'foo',
1072
+ });
1073
+ }, { message: "failed to decrypt prv: ccm: tag doesn't match" });
1074
+ });
1075
+ it('should throw error if the key is altered', () => {
1076
+ const alteredKey = key.replace(/[0-9]/g, '0');
1077
+ assert_1.default.throws(() => {
1078
+ basecoin.assertIsValidKey({
1079
+ encryptedPrv: alteredKey,
1080
+ walletPassphrase,
1081
+ });
1082
+ }, { message: 'failed to decrypt prv: json decrypt: invalid parameters' });
1083
+ });
1084
+ it('should throw error if the key is not a valid key', () => {
1085
+ const invalidKey = '#@)$#($*@)#($*';
1086
+ const encryptedPrv = (0, sdk_api_1.encrypt)(walletPassphrase, invalidKey);
1087
+ assert_1.default.throws(() => {
1088
+ basecoin.assertIsValidKey({
1089
+ encryptedPrv,
1090
+ walletPassphrase,
1091
+ });
1092
+ }, { message: 'Invalid private key: Invalid base32 characters' });
1093
+ });
1094
+ });
1095
+ });
1096
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxnby5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC9hbGdvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsbUNBQTJDO0FBQzNDLDhDQUEwRDtBQUMxRCw0Q0FBbUQ7QUFDbkQsZ0VBQWtEO0FBQ2xELG1DQUFxQztBQUNyQyw0Q0FBdUM7QUFDdkMsa0RBQXlDO0FBQ3pDLG9EQUE0QjtBQUM1Qix5Q0FBc0M7QUFDdEMsZ0VBQXFDO0FBQ3JDLHVDQUEwRDtBQUUxRCw0REFBeUQ7QUFFekQsUUFBUSxDQUFDLE9BQU8sRUFBRTtJQUNoQixJQUFJLEtBQW1CLENBQUM7SUFDeEIsSUFBSSxRQUFRLENBQUM7SUFDYixNQUFNLFFBQVEsR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztJQUVqRCxNQUFNLENBQUM7UUFDTCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsa0JBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3RELEtBQUssQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLFdBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNsRCxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMzQixRQUFRLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqQyxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxlQUFlLEVBQUUsR0FBRyxFQUFFO1FBQzdCLEVBQUUsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLLElBQUksRUFBRTtZQUNyQyxNQUFNLFFBQVE7aUJBQ1gsa0JBQWtCLENBQUM7Z0JBQ2xCLE1BQU0sRUFBRSxFQUFFO2FBQ1gsQ0FBQztpQkFDRCxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO1FBQzdELENBQUMsQ0FBQyxD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LEVBQUU7Z0JBQ0gsUUFBUSxDQUFDLGdCQUFnQixDQUFDO29CQUN4QixZQUFZO29CQUNaLGdCQUFnQjtpQkFDakIsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxFQUNELEVBQUUsT0FBTyxFQUFFLGdEQUFnRCxFQUFFLENBQzlELENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBbGdvTGliLCBUYWxnbyB9IGZyb20gJy4uLy4uL3NyYyc7XG5pbXBvcnQgeyBUZXN0Qml0R28sIFRlc3RCaXRHb0FQSSB9IGZyb20gJ0BiaXRnby9zZGstdGVzdCc7XG5pbXBvcnQgeyBCaXRHb0FQSSwgZW5jcnlwdCB9IGZyb20gJ0BiaXRnby9zZGstYXBpJztcbmltcG9ydCAqIGFzIEFsZ29SZXNvdXJjZXMgZnJvbSAnLi4vZml4dHVyZXMvYWxnbyc7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcbmltcG9ydCBTaW5vbiwgeyBTaW5vblN0dWIgfSBmcm9tICdzaW5vbic7XG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgeyBBbGdvIH0gZnJvbSAnLi4vLi4vc3JjL2FsZ28nO1xuaW1wb3J0IEJpZ051bWJlciBmcm9tICdiaWdudW1iZXIuanMnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB9IGZyb20gJy4uLy4uL3NyYy9saWInO1xuaW1wb3J0IHsgS2V5UGFpciB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBhbGdvQmFja3VwS2V5IH0gZnJvbSAnLi9maXh0dXJlcy9hbGdvQmFja3VwS2V5JztcblxuZGVzY3JpYmUoJ0FMR086JywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJhc2Vjb2luO1xuICBjb25zdCByZWNlaXZlciA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDI7XG5cbiAgYmVmb3JlKGZ1bmN0aW9uICgpIHtcbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHb0FQSSwgeyBlbnY6ICdtb2NrJyB9KTtcbiAgICBiaXRnby5zYWZlUmVnaXN0ZXIoJ3RhbGdvJywgVGFsZ28uY3JlYXRlSW5zdGFuY2UpO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuICAgIGJhc2Vjb2luID0gYml0Z28uY29pbigndGFsZ28nKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1Nob3VsZCBGYWlsOiAnLCAoKSA9PiB7XG4gICAgaXQoJ0RvZXMgbm90IGhhdmUgYSB0eEhleCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IGJhc2Vjb2luXG4gICAgICAgIC5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICAgIHBhcmFtczoge30sXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIGV4cGxhaW4gdHggcGFyYW1ldGVycycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ0RvZXMgbm90IGhhdmUgYSBmZWUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBiYXNlY29pblxuICAgICAgICAuZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgIHR4SGV4OiAnU29tZSBWYWxpZCBIZXgnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdtaXNzaW5nIGV4cGxhaW4gdHggcGFyYW1ldGVycycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVHJhbnNmZXIgQnVpbGRlcjogJywgKCkgPT4ge1xuICAgIGNvbnN0IGJ1aWxkQmFzZVRyYW5zZmVyVHJhbnNhY3Rpb24gPSAoeyBkZXN0aW5hdGlvbiwgYW1vdW50ID0gMTAwMDAsIHNlbmRlciwgbWVtbyA9ICcnIH0pID0+IHtcbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgQWxnb0xpYi5UcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgnYWxnbycpKTtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICBjb25zdCBsZWFzZSA9IG5ldyBVaW50OEFycmF5KHJhbmRvbUJ5dGVzKDMyKSk7XG4gICAgICBjb25zdCBub3RlID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20obWVtbywgJ3V0Zi04JykpO1xuICAgICAgdHhCdWlsZGVyXG4gICAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiBzZW5kZXIgfSlcbiAgICAgICAgLnRvKHsgYWRkcmVzczogZGVzdGluYXRpb24gfSlcbiAgICAgICAgLmFtb3VudChhbW91bnQpXG4gICAgICAgIC5pc0ZsYXRGZWUodHJ1ZSlcbiAgICAgICAgLmZlZSh7XG4gICAgICAgICAgZmVlOiAnMTAwMCcsXG4gICAgICAgIH0pXG4gICAgICAgIC5maXJzdFJvdW5kKDEpXG4gICAgICAgIC5sYXN0Um91bmQoMTAwKVxuICAgICAgICAubGVhc2UobGVhc2UpXG4gICAgICAgIC5ub3RlKG5vdGUpXG4gICAgICAgIC50ZXN0bmV0KCk7XG4gICAgICByZXR1cm4gdHhCdWlsZGVyO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBCdWlsZCBhbiB1bnNpZ25lZCBhY2NvdW50LWxpYiBzaW5nbGUtc2lnbmF0dXJlIHNlbmQgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gc2VuZGVyIFRoZSBzZW5kZXJzIGFkZHJlc3NcbiAgICAgKiBAcGFyYW0gZGVzdGluYXRpb24gVGhlIGRlc3RpbmF0aW9uIGFkZHJlc3Mgb2YgdGhlIHRyYW5zYWN0aW9uXG4gICAgICogQHBhcmFtIGFtb3VudCBUaGUgYW1vdW50IHRvIHNlbmQgdG8gdGhlIHJlY2lwaWVudFxuICAgICAqIEBwYXJhbSBtZW1vIE9wdGlvbmFsIG5vdGUgd2l0aCB0aGUgdHJhbnNhY3Rpb25cbiAgICAgKi9cbiAgICBjb25zdCBidWlsZFVuc2lnbmVkVHJhbnNhY3Rpb24gPSBhc3luYyBmdW5jdGlvbiAoeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQgPSAxMDAwMCwgbWVtbyA9ICcnIH0pIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGJ1aWxkQmFzZVRyYW5zZmVyVHJhbnNhY3Rpb24oeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQsIG1lbW8gfSk7XG4gICAgICByZXR1cm4gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEJ1aWxkIGEgc2lnbmVkIGFjY291bnQtbGliIHNpbmdsZS1zaWduYXR1cmUgc2VuZCB0cmFuc2FjdGlvblxuICAgICAqIEBwYXJhbSBzZW5kZXIgVGhlIHNlbmRlcnMgYWRkcmVzc1xuICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbiBUaGUgZGVzdGluYXRpb24gYWRkcmVzcyBvZiB0aGUgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gYW1vdW50IFRoZSBhbW91bnQgdG8gc2VuZCB0byB0aGUgcmVjaXBpZW50XG4gICAgICogQHBhcmFtIG1lbW8gT3B0aW9uYWwgbm90ZSB3aXRoIHRoZSB0cmFuc2FjdGlvblxuICAgICAqL1xuICAgIGNvbnN0IGJ1aWxkU2lnbmVkVHJhbnNhY3Rpb24gPSBhc3luYyBmdW5jdGlvbiAoeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQgPSAxMDAwMCwgbWVtbyA9ICcnIH0pIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGJ1aWxkQmFzZVRyYW5zZmVyVHJhbnNhY3Rpb24oeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQsIG1lbW8gfSk7XG4gICAgICB0eEJ1aWxkZXIubnVtYmVyT2ZTaWduZXJzKDEpO1xuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDEucHJ2S2V5IH0pO1xuICAgICAgcmV0dXJuIGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBCdWlsZCBhIG11bHRpLXNpZ25lZCBhY2NvdW50LWxpYiBzaW5nbGUtc2lnbmF0dXJlIHNlbmQgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gc2VuZGVycyBUaGUgbGlzdCBvZiBzZW5kZXJzXG4gICAgICogQHBhcmFtIGRlc3RpbmF0aW9uIFRoZSBkZXN0aW5hdGlvbiBhZGRyZXNzIG9mIHRoZSB0cmFuc2FjdGlvblxuICAgICAqIEBwYXJhbSBhbW91bnQgVGhlIGFtb3VudCB0byBzZW5kIHRvIHRoZSByZWNpcGllbnRcbiAgICAgKiBAcGFyYW0gbWVtbyBPcHRpb25hbCBub3RlIHdpdGggdGhlIHRyYW5zYWN0aW9uXG4gICAgICovXG4gICAgY29uc3QgYnVpbGRNdWx0aVNpZ25lZFRyYW5zYWN0aW9uID0gYXN5bmMgZnVuY3Rpb24gKHsgc2VuZGVycywgZGVzdGluYXRpb24sIGFtb3VudCA9IDEwMDAwLCBtZW1vID0gJycgfSkge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gYnVpbGRCYXNlVHJhbnNmZXJUcmFuc2FjdGlvbih7IHNlbmRlcjogc2VuZGVyc1swXSwgZGVzdGluYXRpb24sIGFtb3VudCwgbWVtbyB9KTtcbiAgICAgIHR4QnVpbGRlci5udW1iZXJPZlNpZ25lcnMoMik7XG4gICAgICB0eEJ1aWxkZXIuc2V0U2lnbmVycyhzZW5kZXJzKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLnBydktleSB9KTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQzLnBydktleSB9KTtcbiAgICAgIHJldHVybiBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICB9O1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIHVuc2lnbmVkIHRyYW5zZmVyIHRyYW5zYWN0aW9uIGhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIudW5zaWduZWQsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbi5vdXRwdXRBbW91bnQuc2hvdWxkLmVxdWFsKCcxMDAwMCcpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwJyk7XG4gICAgICBleHBsYWluLm91dHB1dHNbMF0uYWRkcmVzcy5zaG91bGQuZXF1YWwocmVjZWl2ZXIuYWRkcmVzcyk7XG4gICAgICBCdWZmZXIuZnJvbShleHBsYWluLm91dHB1dHNbMF0ubWVtbykudG9TdHJpbmcoKS5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIubm90ZSk7XG4gICAgICBleHBsYWluLmZlZS5zaG91bGQuZXF1YWwoMTAwMCk7XG4gICAgICBleHBsYWluLmNoYW5nZUFtb3VudC5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHNpZ25lZCB0cmFuc2ZlciB0cmFuc2FjdGlvbiBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LnRyYW5zZmVyLnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwJyk7XG4gICAgICBleHBsYWluLm91dHB1dHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAnKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChyZWNlaXZlci5hZGRyZXNzKTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ub3V0cHV0c1swXS5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIGV4cGxhaW4uY2hhbmdlQW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgbXVsdGlTaWcgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5tdWx0aVNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwJyk7XG4gICAgICBleHBsYWluLm91dHB1dHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAnKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChyZWNlaXZlci5hZGRyZXNzKTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ub3V0cHV0c1swXS5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIGV4cGxhaW4uY2hhbmdlQW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgaGFsZiBzaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIGhhbGZTaWduZWQ6IHtcbiAgICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIuaGFsZlNpZ25lZCxcbiAgICAgICAgfSxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAwJyk7XG4gICAgICBleHBsYWluLm91dHB1dHNbMF0uYW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAnKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChyZWNlaXZlci5hZGRyZXNzKTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ub3V0cHV0c1swXS5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIGV4cGxhaW4uY2hhbmdlQW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIHVuc2lnbmVkIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzO1xuICAgICAgY29uc3QgZGVzdGluYXRpb24gPSBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQyLmFkZHJlc3M7XG4gICAgICBjb25zdCBhbW91bnQgPSAxMDAwMDtcbiAgICAgIGNvbnN0IG1lbW8gPSBBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlO1xuICAgICAgY29uc3QgdW5zaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJ1aWxkVW5zaWduZWRUcmFuc2FjdGlvbih7XG4gICAgICAgIHNlbmRlcixcbiAgICAgICAgZGVzdGluYXRpb24sXG4gICAgICAgIGFtb3VudCxcbiAgICAgICAgbWVtbyxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgdW5zaWduZWRIZXggPSBCdWZmZXIuZnJvbSh1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogdW5zaWduZWRIZXgsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgQnVmZmVyLmZyb20oZXhwbGFpbi5vdXRwdXRzWzBdLm1lbW8pLnRvU3RyaW5nKCkuc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LnRyYW5zZmVyLm5vdGUpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoYW1vdW50LnRvU3RyaW5nKCkpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKGRlc3RpbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHNpZ25lZCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlbmRlciA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcztcbiAgICAgIGNvbnN0IGRlc3RpbmF0aW9uID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50Mi5hZGRyZXNzO1xuICAgICAgY29uc3QgYW1vdW50ID0gMTAwMDA7XG4gICAgICBjb25zdCBtZW1vID0gQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIubm90ZTtcbiAgICAgIGNvbnN0IHNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgYnVpbGRTaWduZWRUcmFuc2FjdGlvbih7XG4gICAgICAgIHNlbmRlcixcbiAgICAgICAgZGVzdGluYXRpb24sXG4gICAgICAgIGFtb3VudCxcbiAgICAgICAgbWVtbyxcbiAgICAgIH0pO1xuICAgICAgY29uc3Qgc2lnbmVkSGV4ID0gQnVmZmVyLmZyb20oc2lnbmVkVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBzaWduZWRIZXgsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgQnVmZmVyLmZyb20oZXhwbGFpbi5vdXRwdXRzWzBdLm1lbW8pLnRvU3RyaW5nKCkuc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LnRyYW5zZmVyLm5vdGUpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoYW1vdW50LnRvU3RyaW5nKCkpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKGRlc3RpbmF0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIG11bHRpU2lnbmVkIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVycyA9IFtBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLmFkZHJlc3MsIEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDMuYWRkcmVzc107XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbiA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDIuYWRkcmVzcztcbiAgICAgIGNvbnN0IGFtb3VudCA9IDEwMDAwO1xuICAgICAgY29uc3QgbWVtbyA9IEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LnRyYW5zZmVyLm5vdGU7XG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJ1aWxkTXVsdGlTaWduZWRUcmFuc2FjdGlvbih7XG4gICAgICAgIHNlbmRlcnMsXG4gICAgICAgIGRlc3RpbmF0aW9uLFxuICAgICAgICBhbW91bnQsXG4gICAgICAgIG1lbW8sXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHNpZ25lZEhleCA9IEJ1ZmZlci5mcm9tKHNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogc2lnbmVkSGV4LFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ub3V0cHV0c1swXS5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKGFtb3VudC50b1N0cmluZygpKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChkZXN0aW5hdGlvbik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdBc3NldCBUcmFuc2ZlciBCdWlsZGVyOiAnLCAoKSA9PiB7XG4gICAgY29uc3QgYnVpbGRCYXNlQXNzZXRUcmFuc2ZlclRyYW5zYWN0aW9uID0gKHsgZGVzdGluYXRpb24sIGFtb3VudCA9IDEwMDAsIHRva2VuSWQsIHNlbmRlciB9KSA9PiB7XG4gICAgICBjb25zdCBmYWN0b3J5ID0gbmV3IEFsZ29MaWIuVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoJ2FsZ28nKSk7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmdldEFzc2V0VHJhbnNmZXJCdWlsZGVyKCk7XG4gICAgICBjb25zdCBsZWFzZSA9IG5ldyBVaW50OEFycmF5KHJhbmRvbUJ5dGVzKDMyKSk7XG4gICAgICB0eEJ1aWxkZXJcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IHNlbmRlciB9KVxuICAgICAgICAuaXNGbGF0RmVlKHRydWUpXG4gICAgICAgIC5mZWUoe1xuICAgICAgICAgIGZlZTogJzEwMDAnLFxuICAgICAgICB9KVxuICAgICAgICAudG9rZW5JZCh0b2tlbklkKVxuICAgICAgICAuZmlyc3RSb3VuZCgxKVxuICAgICAgICAubGFzdFJvdW5kKDEwMClcbiAgICAgICAgLmxlYXNlKGxlYXNlKVxuICAgICAgICAudG8oeyBhZGRyZXNzOiBkZXN0aW5hdGlvbiB9KVxuICAgICAgICAuYW1vdW50KGFtb3VudClcbiAgICAgICAgLnRlc3RuZXQoKTtcbiAgICAgIHJldHVybiB0eEJ1aWxkZXI7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEJ1aWxkIGFuIHVuc2lnbmVkIGFjY291bnQtbGliIHNpbmdsZS1zaWduYXR1cmUgYXNzZXQgdHJhbnNmZXIgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gc2VuZGVyIFRoZSBzZW5kZXJzIGFkZHJlc3NcbiAgICAgKiBAcGFyYW0gZGVzdGluYXRpb24gVGhlIGRlc3RpbmF0aW9uIGFkZHJlc3Mgb2YgdGhlIHRyYW5zYWN0aW9uXG4gICAgICogQHBhcmFtIGFtb3VudCBUaGUgYW1vdW50IHRvIHNlbmQgdG8gdGhlIHJlY2lwaWVudFxuICAgICAqIEBwYXJhbSB0b2tlbklkIFRoZSBhc3NldEluZGV4IGZvciB0aGUgdG9rZW5cbiAgICAgKi9cbiAgICBjb25zdCBidWlsZFVuc2lnbmVkVHJhbnNhY3Rpb24gPSBhc3luYyBmdW5jdGlvbiAoeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQgPSAxMDAwMCwgdG9rZW5JZCB9KSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBidWlsZEJhc2VBc3NldFRyYW5zZmVyVHJhbnNhY3Rpb24oeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQsIHRva2VuSWQgfSk7XG4gICAgICByZXR1cm4gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEJ1aWxkIGEgc2lnbmVkIGFjY291bnQtbGliIHNpbmdsZS1zaWduYXR1cmUgc2VuZCB0cmFuc2FjdGlvblxuICAgICAqIEBwYXJhbSBzZW5kZXIgVGhlIHNlbmRlcnMgYWRkcmVzc1xuICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbiBUaGUgZGVzdGluYXRpb24gYWRkcmVzcyBvZiB0aGUgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gYW1vdW50IFRoZSBhbW91bnQgdG8gc2VuZCB0byB0aGUgcmVjaXBpZW50XG4gICAgICogQHBhcmFtIHRva2VuSWQgVGhlIGFzc2V0SW5kZXggZm9yIHRoZSB0b2tlblxuICAgICAqL1xuICAgIGNvbnN0IGJ1aWxkU2lnbmVkVHJhbnNhY3Rpb24gPSBhc3luYyBmdW5jdGlvbiAoeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQgPSAxMDAwMCwgdG9rZW5JZCB9KSB7XG4gICAgICBjb25zdCB0eEJ1aWxkZXIgPSBidWlsZEJhc2VBc3NldFRyYW5zZmVyVHJhbnNhY3Rpb24oeyBzZW5kZXIsIGRlc3RpbmF0aW9uLCBhbW91bnQsIHRva2VuSWQgfSk7XG4gICAgICB0eEJ1aWxkZXIubnVtYmVyT2ZTaWduZXJzKDEpO1xuICAgICAgdHhCdWlsZGVyLnNpZ24oeyBrZXk6IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDEucHJ2S2V5IH0pO1xuICAgICAgcmV0dXJuIGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIH07XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYW4gdW5zaWduZWQgYXNzZXQgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC5hc3NldFRyYW5zZmVyLnVuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMCcpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoJzEwMDAnKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChyZWNlaXZlci5hZGRyZXNzKTtcbiAgICAgIGV4cGxhaW4uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIGV4cGxhaW4uY2hhbmdlQW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgZXhwbGFpbi50b2tlbklkLnNob3VsZC5lcXVhbCgxKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHNpZ25lZCBhc3NldCB0cmFuc2ZlciB0cmFuc2FjdGlvbiBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LmFzc2V0VHJhbnNmZXIuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0QW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAwMDAwMDAwMDAwMDAwMDAnKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKCcxMDAwMDAwMDAwMDAwMDAwMDAwMCcpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKHJlY2VpdmVyLmFkZHJlc3MpO1xuICAgICAgZXhwbGFpbi5mZWUuc2hvdWxkLmVxdWFsKDEwMDApO1xuICAgICAgZXhwbGFpbi5jaGFuZ2VBbW91bnQuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICBleHBsYWluLnRva2VuSWQuc2hvdWxkLmVxdWFsKDEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIHVuc2lnbmVkIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzO1xuICAgICAgY29uc3QgZGVzdGluYXRpb24gPSBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQyLmFkZHJlc3M7XG4gICAgICBjb25zdCBhbW91bnQgPSAxMDAwMDtcbiAgICAgIGNvbnN0IHRva2VuSWQgPSAxO1xuICAgICAgY29uc3QgdW5zaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJ1aWxkVW5zaWduZWRUcmFuc2FjdGlvbih7XG4gICAgICAgIHNlbmRlcixcbiAgICAgICAgZGVzdGluYXRpb24sXG4gICAgICAgIGFtb3VudCxcbiAgICAgICAgdG9rZW5JZCxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgdW5zaWduZWRIZXggPSBCdWZmZXIuZnJvbSh1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogdW5zaWduZWRIZXgsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFtb3VudC5zaG91bGQuZXF1YWwoYW1vdW50LnRvU3RyaW5nKCkpO1xuICAgICAgZXhwbGFpbi5vdXRwdXRzWzBdLmFkZHJlc3Muc2hvdWxkLmVxdWFsKGRlc3RpbmF0aW9uKTtcbiAgICAgIGV4cGxhaW4udG9rZW5JZC5zaG91bGQuZXF1YWwoMSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBzaWduZWQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZW5kZXIgPSBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLmFkZHJlc3M7XG4gICAgICBjb25zdCBkZXN0aW5hdGlvbiA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDIuYWRkcmVzcztcbiAgICAgIGNvbnN0IGFtb3VudCA9IDEwMDAwO1xuICAgICAgY29uc3QgdG9rZW5JZCA9IDE7XG4gICAgICBjb25zdCBzaWduZWRUcmFuc2FjdGlvbiA9IGF3YWl0IGJ1aWxkU2lnbmVkVHJhbnNhY3Rpb24oe1xuICAgICAgICBzZW5kZXIsXG4gICAgICAgIGRlc3RpbmF0aW9uLFxuICAgICAgICBhbW91bnQsXG4gICAgICAgIHRva2VuSWQsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHNpZ25lZEhleCA9IEJ1ZmZlci5mcm9tKHNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogc2lnbmVkSGV4LFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hbW91bnQuc2hvdWxkLmVxdWFsKGFtb3VudC50b1N0cmluZygpKTtcbiAgICAgIGV4cGxhaW4ub3V0cHV0c1swXS5hZGRyZXNzLnNob3VsZC5lcXVhbChkZXN0aW5hdGlvbik7XG4gICAgICBleHBsYWluLnRva2VuSWQuc2hvdWxkLmVxdWFsKDEpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnV2FsbGV0IEluaXQgQnVpbGRlcjogJywgKCkgPT4ge1xuICAgIGNvbnN0IGJ1aWxkQmFzZUtleVJlZ1RyYW5zYWN0aW9uID0gKHsgc2VuZGVyLCBtZW1vID0gJycgfSkgPT4ge1xuICAgICAgY29uc3QgZmFjdG9yeSA9IG5ldyBBbGdvTGliLlRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCdhbGdvJykpO1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5nZXRXYWxsZXRJbml0aWFsaXphdGlvbkJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IGxlYXNlID0gbmV3IFVpbnQ4QXJyYXkocmFuZG9tQnl0ZXMoMzIpKTtcbiAgICAgIGNvbnN0IG5vdGUgPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShtZW1vLCAndXRmLTgnKSk7XG4gICAgICB0eEJ1aWxkZXJcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IHNlbmRlci5hZGRyZXNzIH0pXG4gICAgICAgIC5pc0ZsYXRGZWUodHJ1ZSlcbiAgICAgICAgLmZlZSh7XG4gICAgICAgICAgZmVlOiAnMTAwMCcsXG4gICAgICAgIH0pXG4gICAgICAgIC5maXJzdFJvdW5kKDEpXG4gICAgICAgIC5sYXN0Um91bmQoMTAwKVxuICAgICAgICAubGVhc2UobGVhc2UpXG4gICAgICAgIC5ub3RlKG5vdGUpXG4gICAgICAgIC52b3RlS2V5KHNlbmRlci52b3RlS2V5KVxuICAgICAgICAuc2VsZWN0aW9uS2V5KHNlbmRlci5zZWxlY3Rpb25LZXkpXG4gICAgICAgIC52b3RlRmlyc3QoMSlcbiAgICAgICAgLnZvdGVMYXN0KDEwMClcbiAgICAgICAgLnZvdGVLZXlEaWx1dGlvbig5KVxuICAgICAgICAudGVzdG5ldCgpO1xuICAgICAgcmV0dXJuIHR4QnVpbGRlcjtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQnVpbGQgYW4gdW5zaWduZWQgYWNjb3VudC1saWIgc2luZ2xlLXNpZ25hdHVyZSBzZW5kIHRyYW5zYWN0aW9uXG4gICAgICogQHBhcmFtIHNlbmRlciBUaGUgc2VuZGVycyBhZGRyZXNzXG4gICAgICogQHBhcmFtIG1lbW8gT3B0aW9uYWwgbm90ZSB3aXRoIHRoZSB0cmFuc2FjdGlvblxuICAgICAqL1xuICAgIGNvbnN0IGJ1aWxkVW5zaWduZWRUcmFuc2FjdGlvbiA9IGFzeW5jIGZ1bmN0aW9uICh7IHNlbmRlciwgbWVtbyA9ICcnIH0pIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGJ1aWxkQmFzZUtleVJlZ1RyYW5zYWN0aW9uKHsgc2VuZGVyLCBtZW1vIH0pO1xuICAgICAgcmV0dXJuIGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBCdWlsZCBhIHNpZ25lZCBhY2NvdW50LWxpYiBzaW5nbGUtc2lnbmF0dXJlIHNlbmQgdHJhbnNhY3Rpb25cbiAgICAgKiBAcGFyYW0gc2VuZGVyIFRoZSBzZW5kZXJzIGFkZHJlc3NcbiAgICAgKiBAcGFyYW0gbWVtbyBPcHRpb25hbCBub3RlIHdpdGggdGhlIHRyYW5zYWN0aW9uXG4gICAgICovXG4gICAgY29uc3QgYnVpbGRTaWduZWRUcmFuc2FjdGlvbiA9IGFzeW5jIGZ1bmN0aW9uICh7IHNlbmRlciwgbWVtbyA9ICcnIH0pIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGJ1aWxkQmFzZUtleVJlZ1RyYW5zYWN0aW9uKHsgc2VuZGVyLCBtZW1vIH0pO1xuICAgICAgdHhCdWlsZGVyLm51bWJlck9mU2lnbmVycygxKTtcbiAgICAgIHR4QnVpbGRlci5zaWduKHsga2V5OiBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLnBydktleSB9KTtcbiAgICAgIHJldHVybiBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQnVpbGQgYSBtdWx0aS1zaWduZWQgYWNjb3VudC1saWIgc2luZ2xlLXNpZ25hdHVyZSBzZW5kIHRyYW5zYWN0aW9uXG4gICAgICogQHBhcmFtIHNlbmRlcnMgVGhlIGxpc3Qgb2Ygc2VuZGVyc1xuICAgICAqIEBwYXJhbSBtZW1vIE9wdGlvbmFsIG5vdGUgd2l0aCB0aGUgdHJhbnNhY3Rpb25cbiAgICAgKi9cbiAgICBjb25zdCBidWlsZE11bHRpU2lnbmVkVHJhbnNhY3Rpb24gPSBhc3luYyBmdW5jdGlvbiAoeyBzZW5kZXJzLCBtZW1vID0gJycgfSkge1xuICAgICAgY29uc3QgdHhCdWlsZGVyID0gYnVpbGRCYXNlS2V5UmVnVHJhbnNhY3Rpb24oeyBzZW5kZXI6IHNlbmRlcnNbMF0sIG1lbW8gfSk7XG4gICAgICB0eEJ1aWxkZXIubnVtYmVyT2ZTaWduZXJzKDIpO1xuICAgICAgdHhCdWlsZGVyLnNldFNpZ25lcnMoc2VuZGVycy5tYXAoKHsgYWRkcmVzcyB9KSA9PiBhZGRyZXNzKSk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5wcnZLZXkgfSk7XG4gICAgICB0eEJ1aWxkZXIuc2lnbih7IGtleTogQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50My5wcnZLZXkgfSk7XG4gICAgICByZXR1cm4gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgfTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB1bnNpZ25lZCBLZXlSZWcgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLnVuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ubWVtbykudG9TdHJpbmcoKS5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLm5vdGUpO1xuICAgICAgZXhwbGFpbi5mZWUuc2hvdWxkLmVxdWFsKDEwMDApO1xuICAgICAgZXhwbGFpbi5jaGFuZ2VBbW91bnQuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICBleHBsYWluLnZvdGVLZXkuc2hvdWxkLmVxdWFsKHNlbmRlci52b3RlS2V5KTtcbiAgICAgIGV4cGxhaW4uc2VsZWN0aW9uS2V5LnNob3VsZC5lcXVhbChzZW5kZXIuc2VsZWN0aW9uS2V5KTtcbiAgICAgIGV4cGxhaW4udm90ZUZpcnN0LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIGV4cGxhaW4udm90ZUxhc3Quc2hvdWxkLmVxdWFsKDEwMCk7XG4gICAgICBleHBsYWluLnZvdGVLZXlEaWx1dGlvbi5zaG91bGQuZXF1YWwoOSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBzaWduZWQgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLnNpZ25lZCxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBCdWZmZXIuZnJvbShleHBsYWluLm1lbW8pLnRvU3RyaW5nKCkuc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LmtleXJlZy5ub3RlKTtcbiAgICAgIGV4cGxhaW4uZmVlLnNob3VsZC5lcXVhbCgxMDAwKTtcbiAgICAgIGV4cGxhaW4uY2hhbmdlQW1vdW50LnNob3VsZC5lcXVhbCgnMCcpO1xuICAgICAgZXhwbGFpbi52b3RlS2V5LnNob3VsZC5lcXVhbChzZW5kZXIudm90ZUtleSk7XG4gICAgICBleHBsYWluLnNlbGVjdGlvbktleS5zaG91bGQuZXF1YWwoc2VuZGVyLnNlbGVjdGlvbktleSk7XG4gICAgICBleHBsYWluLnZvdGVGaXJzdC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICBleHBsYWluLnZvdGVMYXN0LnNob3VsZC5lcXVhbCgxMDApO1xuICAgICAgZXhwbGFpbi52b3RlS2V5RGlsdXRpb24uc2hvdWxkLmVxdWFsKDkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGEgbXVsdGlTaWcgdHJhbnNmZXIgdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVyID0gQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLm11bHRpU2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIEJ1ZmZlci5mcm9tKGV4cGxhaW4ubWVtbykudG9TdHJpbmcoKS5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLm5vdGUpO1xuICAgICAgZXhwbGFpbi5mZWUuc2hvdWxkLmVxdWFsKDEwMDApO1xuICAgICAgZXhwbGFpbi5jaGFuZ2VBbW91bnQuc2hvdWxkLmVxdWFsKCcwJyk7XG4gICAgICBleHBsYWluLnZvdGVLZXkuc2hvdWxkLmVxdWFsKHNlbmRlci52b3RlS2V5KTtcbiAgICAgIGV4cGxhaW4uc2VsZWN0aW9uS2V5LnNob3VsZC5lcXVhbChzZW5kZXIuc2VsZWN0aW9uS2V5KTtcbiAgICAgIGV4cGxhaW4udm90ZUZpcnN0LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIGV4cGxhaW4udm90ZUxhc3Quc2hvdWxkLmVxdWFsKDEwMCk7XG4gICAgICBleHBsYWluLnZvdGVLZXlEaWx1dGlvbi5zaG91bGQuZXF1YWwoOSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBoYWxmIHNpZ25lZCB0cmFuc2ZlciB0cmFuc2FjdGlvbiBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzZW5kZXIgPSBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxO1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIGhhbGZTaWduZWQ6IHtcbiAgICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgua2V5cmVnLmhhbGZTaWduZWQsXG4gICAgICAgIH0sXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgQnVmZmVyLmZyb20oZXhwbGFpbi5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC5rZXlyZWcubm90ZSk7XG4gICAgICBleHBsYWluLmZlZS5zaG91bGQuZXF1YWwoMTAwMCk7XG4gICAgICBleHBsYWluLmNoYW5nZUFtb3VudC5zaG91bGQuZXF1YWwoJzAnKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleS5zaG91bGQuZXF1YWwoc2VuZGVyLnZvdGVLZXkpO1xuICAgICAgZXhwbGFpbi5zZWxlY3Rpb25LZXkuc2hvdWxkLmVxdWFsKHNlbmRlci5zZWxlY3Rpb25LZXkpO1xuICAgICAgZXhwbGFpbi52b3RlRmlyc3Quc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgZXhwbGFpbi52b3RlTGFzdC5zaG91bGQuZXF1YWwoMTAwKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleURpbHV0aW9uLnNob3VsZC5lcXVhbCg5KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB1bnNpZ25lZCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlbmRlciA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDE7XG4gICAgICBjb25zdCBtZW1vID0gQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIubm90ZTtcbiAgICAgIGNvbnN0IHVuc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBidWlsZFVuc2lnbmVkVHJhbnNhY3Rpb24oe1xuICAgICAgICBzZW5kZXIsXG4gICAgICAgIG1lbW8sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdW5zaWduZWRIZXggPSBCdWZmZXIuZnJvbSh1bnNpZ25lZFRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogdW5zaWduZWRIZXgsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgQnVmZmVyLmZyb20oZXhwbGFpbi5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleS5zaG91bGQuZXF1YWwoc2VuZGVyLnZvdGVLZXkpO1xuICAgICAgZXhwbGFpbi5zZWxlY3Rpb25LZXkuc2hvdWxkLmVxdWFsKHNlbmRlci5zZWxlY3Rpb25LZXkpO1xuICAgICAgZXhwbGFpbi52b3RlRmlyc3Quc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgZXhwbGFpbi52b3RlTGFzdC5zaG91bGQuZXF1YWwoMTAwKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleURpbHV0aW9uLnNob3VsZC5lcXVhbCg5KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIHNpZ25lZCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNlbmRlciA9IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDE7XG4gICAgICBjb25zdCBtZW1vID0gQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHgudHJhbnNmZXIubm90ZTtcbiAgICAgIGNvbnN0IHNpZ25lZFRyYW5zYWN0aW9uID0gYXdhaXQgYnVpbGRTaWduZWRUcmFuc2FjdGlvbih7XG4gICAgICAgIHNlbmRlcixcbiAgICAgICAgbWVtbyxcbiAgICAgIH0pO1xuICAgICAgY29uc3Qgc2lnbmVkSGV4ID0gQnVmZmVyLmZyb20oc2lnbmVkVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKSkudG9TdHJpbmcoJ2hleCcpO1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBzaWduZWRIZXgsXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgQnVmZmVyLmZyb20oZXhwbGFpbi5tZW1vKS50b1N0cmluZygpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleS5zaG91bGQuZXF1YWwoc2VuZGVyLnZvdGVLZXkpO1xuICAgICAgZXhwbGFpbi5zZWxlY3Rpb25LZXkuc2hvdWxkLmVxdWFsKHNlbmRlci5zZWxlY3Rpb25LZXkpO1xuICAgICAgZXhwbGFpbi52b3RlRmlyc3Quc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgZXhwbGFpbi52b3RlTGFzdC5zaG91bGQuZXF1YWwoMTAwKTtcbiAgICAgIGV4cGxhaW4udm90ZUtleURpbHV0aW9uLnNob3VsZC5lcXVhbCg5KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhIG11bHRpU2lnbmVkIHRyYW5zYWN0aW9uJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2VuZGVycyA9IFtBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLCBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQzXTtcbiAgICAgIGNvbnN0IG1lbW8gPSBBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC50cmFuc2Zlci5ub3RlO1xuICAgICAgY29uc3Qgc2lnbmVkVHJhbnNhY3Rpb24gPSBhd2FpdCBidWlsZE11bHRpU2lnbmVkVHJhbnNhY3Rpb24oe1xuICAgICAgICBzZW5kZXJzLFxuICAgICAgICBtZW1vLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBzaWduZWRIZXggPSBCdWZmZXIuZnJvbShzaWduZWRUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpKS50b1N0cmluZygnaGV4Jyk7XG4gICAgICBjb25zdCBleHBsYWluID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IHNpZ25lZEhleCxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBCdWZmZXIuZnJvbShleHBsYWluLm1lbW8pLnRvU3RyaW5nKCkuc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LnRyYW5zZmVyLm5vdGUpO1xuICAgICAgZXhwbGFpbi52b3RlS2V5LnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLnZvdGVLZXkpO1xuICAgICAgZXhwbGFpbi5zZWxlY3Rpb25LZXkuc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDEuc2VsZWN0aW9uS2V5KTtcbiAgICAgIGV4cGxhaW4udm90ZUZpcnN0LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIGV4cGxhaW4udm90ZUxhc3Quc2hvdWxkLmVxdWFsKDEwMCk7XG4gICAgICBleHBsYWluLnZvdGVLZXlEaWx1dGlvbi5zaG91bGQuZXF1YWwoOSk7XG4gICAgfSk7XG4gIH0pO1xuICBkZXNjcmliZSgnU2lnbiB0cmFuc2FjdGlvbicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHNpZ24gdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWduZWQgPSBhd2FpdCBiYXNlY29pbi5zaWduVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eFByZWJ1aWxkOiB7XG4gICAgICAgICAgdHhIZXg6IEFsZ29SZXNvdXJjZXMucmF3VHgudHJhbnNmZXIudW5zaWduZWQsXG4gICAgICAgICAga2V5czogW0FsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDEucHViS2V5LnRvU3RyaW5nKCdoZXgnKV0sXG4gICAgICAgICAgYWRkcmVzc1ZlcnNpb246IDEsXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5wcnZLZXksXG4gICAgICB9KTtcbiAgICAgIHNpZ25lZC50eEhleC5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5yYXdUeC50cmFuc2Zlci5zaWduZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzaWduIHRyYW5zYWN0aW9uIHdpdGggcm9vdCBrZXknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBrZXlwYWlyID0gYmFzZWNvaW4uZ2VuZXJhdGVSb290S2V5UGFpcihBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLnNlY3JldEtleSk7XG5cbiAgICAgIGNvbnN0IHNpZ25lZCA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5yYXdUeC50cmFuc2Zlci51bnNpZ25lZCxcbiAgICAgICAgICBrZXlzOiBba2V5cGFpci5wdWJdLFxuICAgICAgICAgIGFkZHJlc3NWZXJzaW9uOiAxLFxuICAgICAgICB9LFxuICAgICAgICBwcnY6IGtleXBhaXIucHJ2LFxuICAgICAgfSk7XG4gICAgICBzaWduZWQudHhIZXguc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMucmF3VHgudHJhbnNmZXIuc2lnbmVkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2lnbiBoYWxmIHNpZ25lZCB0cmFuc2FjdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZ25lZCA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICBoYWxmU2lnbmVkOiB7XG4gICAgICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5yYXdUeC50cmFuc2Zlci5oYWxmU2lnbmVkLFxuICAgICAgICAgIH0sXG4gICAgICAgICAga2V5czogW1xuICAgICAgICAgICAgQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5wdWJLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgICAgQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50My5wdWJLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgYWRkcmVzc1ZlcnNpb246IDEsXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50My5wcnZLZXksXG4gICAgICB9KTtcbiAgICAgIHNpZ25lZC50eEhleC5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5yYXdUeC50cmFuc2Zlci5tdWx0aXNpZyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNpZ24gaGFsZiBzaWduZWQgdHJhbnNhY3Rpb24gd2l0aCByb290IGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZ25lZCA9IGF3YWl0IGJhc2Vjb2luLnNpZ25UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4UHJlYnVpbGQ6IHtcbiAgICAgICAgICBoYWxmU2lnbmVkOiB7XG4gICAgICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5yb290S2V5RGF0YS51bnNpZ25lZFR4LFxuICAgICAgICAgIH0sXG4gICAgICAgICAga2V5czogW1xuICAgICAgICAgICAgQWxnb1Jlc291cmNlcy5yb290S2V5RGF0YS51c2VyS2V5UGFpci5wdWIsXG4gICAgICAgICAgICBBbGdvUmVzb3VyY2VzLnJvb3RLZXlEYXRhLmJhY2t1cFB1YixcbiAgICAgICAgICAgIEFsZ29SZXNvdXJjZXMucm9vdEtleURhdGEuYml0Z29QdWIsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBhZGRyZXNzVmVyc2lvbjogMSxcbiAgICAgICAgfSxcbiAgICAgICAgcHJ2OiBBbGdvUmVzb3VyY2VzLnJvb3RLZXlEYXRhLnVzZXJLZXlQYWlyLnBydixcbiAgICAgIH0pO1xuXG4gICAgICBzaWduZWQudHhIZXguc2hvdWxkLmRlZXBFcXVhbChBbGdvUmVzb3VyY2VzLnJvb3RLZXlEYXRhLmhhbGZTaWduZWRUeCk7XG4gICAgICBjb25zdCBmYWN0b3J5ID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCdhbGdvJykpO1xuICAgICAgY29uc3QgdHggPSBhd2FpdCBmYWN0b3J5LmZyb20oc2lnbmVkLnR4SGV4KS5idWlsZCgpO1xuICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICB0eEpzb24uZnJvbS5zaG91bGQuZXF1YWwoQWxnb1Jlc291cmNlcy5yb290S2V5RGF0YS5zZW5kZXJBZGRyZXNzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IHNpZ24gcGFyYW1zIGlmIHRoZSBrZXkgYXJyYXkgY29udGFpbnMgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qga2V5cyA9IFtcbiAgICAgICAgQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzLFxuICAgICAgICBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQyLmFkZHJlc3MsXG4gICAgICAgIEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDMuYWRkcmVzcyxcbiAgICAgIF07XG5cbiAgICAgIGNvbnN0IHZlcmlmaWVkUGFyYW1zID0gYmFzZWNvaW4udmVyaWZ5U2lnblRyYW5zYWN0aW9uUGFyYW1zKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIHR4SGV4OiBBbGdvUmVzb3VyY2VzLnJhd1R4LnRyYW5zZmVyLnVuc2lnbmVkLFxuICAgICAgICAgIGtleXMsXG4gICAgICAgICAgYWRkcmVzc1ZlcnNpb246IDEsXG4gICAgICAgIH0sXG4gICAgICAgIHBydjogQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50Mi5zZWNyZXRLZXkudG9TdHJpbmcoJ2hleCcpLFxuICAgICAgfSk7XG4gICAgICB2ZXJpZmllZFBhcmFtcy5zaG91bGQuaGF2ZS5wcm9wZXJ0aWVzKFtcbiAgICAgICAgJ3R4SGV4JyxcbiAgICAgICAgJ2FkZHJlc3NWZXJzaW9uJyxcbiAgICAgICAgJ3NpZ25lcnMnLFxuICAgICAgICAncHJ2JyxcbiAgICAgICAgJ2lzSGFsZlNpZ25lZCcsXG4gICAgICAgICdudW1iZXJTaWduZXJzJyxcbiAgICAgIF0pO1xuICAgICAgY29uc3QgeyB0eEhleCwgc2lnbmVycywgaXNIYWxmU2lnbmVkIH0gPSB2ZXJpZmllZFBhcmFtcztcbiAgICAgIHR4SGV4LnNob3VsZC5iZS5lcXVhbChBbGdvUmVzb3VyY2VzLnJhd1R4LnRyYW5zZmVyLnVuc2lnbmVkKTtcbiAgICAgIHNpZ25lcnMuc2hvdWxkLmJlLmRlZXBFcXVhbChrZXlzKTtcbiAgICAgIGlzSGFsZlNpZ25lZC5zaG91bGQuYmUuZXF1YWwoZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzaWduIGhhbGYgc2lnbmVkIHRyYW5zYWN0aW9uIGlmIHRoZSBrZXkgYXJyYXkgY29udGFpbnMgYWRkcmVzc2VzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnbmVkID0gYXdhaXQgYmFzZWNvaW4uc2lnblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhQcmVidWlsZDoge1xuICAgICAgICAgIGhhbGZTaWduZWQ6IHtcbiAgICAgICAgICAgIHR4SGV4OiBBbGdvUmVzb3VyY2VzLnJhd1R4LnRyYW5zZmVyLmhhbGZTaWduZWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBrZXlzOiBbQWxnb1Jlc291cmNlcy5hY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzLCBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQzLmFkZHJlc3NdLFxuICAgICAgICAgIGFkZHJlc3NWZXJzaW9uOiAxLFxuICAgICAgICB9LFxuICAgICAgICBwcnY6IEFsZ29SZXNvdXJjZXMuYWNjb3VudHMuYWNjb3VudDMucHJ2S2V5LFxuICAgICAgfSk7XG4gICAgICBzaWduZWQudHhIZXguc2hvdWxkLmVxdWFsKEFsZ29SZXNvdXJjZXMucmF3VHgudHJhbnNmZXIubXVsdGlzaWcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2lnbiBtZXNzYWdlJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgc2lnbiBtZXNzYWdlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnbmVkID0gYXdhaXQgYmFzZWNvaW4uc2lnbk1lc3NhZ2UoXG4gICAgICAgIHsgcHJ2OiBBbGdvUmVzb3VyY2VzLmFjY291bnRzLmFjY291bnQxLnBydktleSB9LFxuICAgICAgICBBbGdvUmVzb3VyY2VzLm1lc3NhZ2UudW5zaWduZWRcbiAgICAgICk7XG4gICAgICBzaWduZWQudG9TdHJpbmcoJ2hleCcpLnNob3VsZC5lcXVhbChBbGdvUmVzb3VyY2VzLm1lc3NhZ2Uuc2lnbmVkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0dlbmVyYXRlIHdhbGxldCBrZXkgcGFpcjogJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUga2V5IHBhaXInLCAoKSA9PiB7XG4gICAgICBjb25zdCBrcCA9IGJhc2Vjb2luLmdlbmVyYXRlS2V5UGFpcigpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFB1YihrcC5wdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQcnYoa3AucHJ2KS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIGtleSBwYWlyIGZyb20gc2VlZCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHNlZWQgPSBCdWZmZXIuZnJvbSgnOWQ2MWIxOWRlZmZkNWE2MGJhODQ0YWY0OTJlYzJjYzQ0NDQ5YzU2OTdiMzI2OTE5NzAzYmFjMDMxY2FlN2Y2MCcsICdoZXgnKTtcbiAgICAgIGNvbnN0IGtwID0gYmFzZWNvaW4uZ2VuZXJhdGVLZXlQYWlyKHNlZWQpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFB1YihrcC5wdWIpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQcnYoa3AucHJ2KS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZW5lcmF0ZSB3YWxsZXQgUm9vdCBrZXkgcGFpcjogJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUga2V5IHBhaXInLCAoKSA9PiB7XG4gICAgICBjb25zdCBrcCA9IGJhc2Vjb2luLmdlbmVyYXRlUm9vdEtleVBhaXIoKTtcbiAgICAgIGJhc2Vjb2luLmlzVmFsaWRQdWIoa3AucHViKS5zaG91bGQuZXF1YWwodHJ1ZSk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHJ2KGtwLnBydikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSBrZXkgcGFpciBmcm9tIHNlZWQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzZWVkID0gQnVmZmVyLmZyb20oJzlkNjFiMTlkZWZmZDVhNjBiYTg0NGFmNDkyZWMyY2M0NDQ0OWM1Njk3YjMyNjkxOTcwM2JhYzAzMWNhZTdmNjAnLCAnaGV4Jyk7XG4gICAgICBjb25zdCBrcCA9IGJhc2Vjb2luLmdlbmVyYXRlUm9vdEtleVBhaXIoc2VlZCk7XG4gICAgICBiYXNlY29pbi5pc1ZhbGlkUHViKGtwLnB1Yikuc2hvdWxkLmVxdWFsKHRydWUpO1xuICAgICAga3AucHViLnNob3VsZC5lcXVhbCgnZDc1YTk4MDE4MmIxMGFiN2Q1NGJmZWQzYzk2NDA3M2EwZWUxNzJmM2RhYTYyMzI1YWYwMjFhNjhmNzA3NTExYScpO1xuICAgICAgYmFzZWNvaW4uaXNWYWxpZFBydihrcC5wcnYpLnNob3VsZC5lcXVhbCh0cnVlKTtcbiAgICAgIGtwLnBydi5zaG91bGQuZXF1YWwoXG4gICAgICAgICc5ZDYxYjE5ZGVmZmQ1YTYwYmE4NDRhZjQ5MmVjMmNjNDQ0NDljNTY5N2IzMjY5MTk3MDNiYWMwMzFjYWU3ZjYwZDc1YTk4MDE4MmIxMGFiN2Q1NGJmZWQzYzk2NDA3M2EwZWUxNzJmM2RhYTYyMzI1YWYwMjFhNjhmNzA3NTExYSdcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdFbmFibGUsIGRpc2FibGUgYW5kIHRyYW5zZmVyIFRva2VuICcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYW4gZW5hYmxlIHRva2VuIHRyYW5zYWN0aW9uIGhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHguZW5hYmxlVG9rZW4sXG4gICAgICAgIGZlZUluZm86IHsgZmVlOiAnMTAwMCcgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwbGFpbi5vcGVyYXRpb25zLmxlbmd0aC5zaG91bGQuZXF1YWxzKDEpO1xuICAgICAgZXhwbGFpbi5vcGVyYXRpb25zWzBdLnR5cGUuc2hvdWxkLmVxdWFscygnZW5hYmxlVG9rZW4nKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS5jb2luLnNob3VsZC5lcXVhbHMoJ3RhbGdvOlVTT04tMTYwMjY3MjgnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiBkaXNhYmxlIHRva2VuIHRyYW5zYWN0aW9uIGhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHguZGlzYWJsZVRva2VuLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS50eXBlLnNob3VsZC5lcXVhbHMoJ2Rpc2FibGVUb2tlbicpO1xuICAgICAgZXhwbGFpbi5vcGVyYXRpb25zWzBdLmNvaW4uc2hvdWxkLmVxdWFscygndGFsZ286VVNPTi0xNjAyNjcyOCcpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB0cmFuc2ZlciB0b2tlbiB0cmFuc2FjdGlvbiBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LmFzc2V0VHJhbnNmZXIuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS50eXBlLnNob3VsZC5lcXVhbHMoJ3RyYW5zZmVyVG9rZW4nKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS5jb2luLnNob3VsZC5lcXVhbHMoJ0FsZ29Ub2tlbiB1bmtub3duJyk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCBleHBsYWluIGFuIGVuYWJsZSBVU0RUIHRva2VuIHRyYW5zYWN0aW9uIGhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHguZW5hYmxlVG9rZW5VU0RULFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS50eXBlLnNob3VsZC5lcXVhbHMoJ2VuYWJsZVRva2VuJyk7XG4gICAgICBleHBsYWluLm9wZXJhdGlvbnNbMF0uY29pbi5zaG91bGQuZXF1YWxzKCd0YWxnbzpVU0R0LTE4MDQ0NycpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiBlbmFibGUgVVNEQyB0b2tlbiB0cmFuc2FjdGlvbiBoZXgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBleHBsYWluID0gYXdhaXQgYmFzZWNvaW4uZXhwbGFpblRyYW5zYWN0aW9uKHtcbiAgICAgICAgdHhIZXg6IEFsZ29SZXNvdXJjZXMuZXhwbGFpblJhd1R4LmVuYWJsZVRva2VuVVNEQyxcbiAgICAgICAgZmVlSW5mbzogeyBmZWU6ICcxMDAwJyB9LFxuICAgICAgfSk7XG4gICAgICBleHBsYWluLm9wZXJhdGlvbnMubGVuZ3RoLnNob3VsZC5lcXVhbHMoMSk7XG4gICAgICBleHBsYWluLm9wZXJhdGlvbnNbMF0udHlwZS5zaG91bGQuZXF1YWxzKCdlbmFibGVUb2tlbicpO1xuICAgICAgZXhwbGFpbi5vcGVyYXRpb25zWzBdLmNvaW4uc2hvdWxkLmVxdWFscygndGFsZ286VVNEQy0xMDQ1ODk0MScpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiBkaXNhYmxlIFVTREMgdG9rZW4gdHJhbnNhY3Rpb24gaGV4JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXhwbGFpbiA9IGF3YWl0IGJhc2Vjb2luLmV4cGxhaW5UcmFuc2FjdGlvbih7XG4gICAgICAgIHR4SGV4OiBBbGdvUmVzb3VyY2VzLmV4cGxhaW5SYXdUeC5kaXNhYmxlVG9rZW5VU0RDLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS50eXBlLnNob3VsZC5lcXVhbHMoJ2Rpc2FibGVUb2tlbicpO1xuICAgICAgZXhwbGFpbi5vcGVyYXRpb25zWzBdLmNvaW4uc2hvdWxkLmVxdWFscygndGFsZ286VVNEQy0xMDQ1ODk0MScpO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgZXhwbGFpbiBhbiB0cmFuc2ZlciBVU0RDIHRva2VuIHRyYW5zYWN0aW9uIGhleCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4cGxhaW4gPSBhd2FpdCBiYXNlY29pbi5leHBsYWluVHJhbnNhY3Rpb24oe1xuICAgICAgICB0eEhleDogQWxnb1Jlc291cmNlcy5leHBsYWluUmF3VHguVVNEQ0Fzc2V0VHJhbnNmZXIuc2lnbmVkLFxuICAgICAgICBmZWVJbmZvOiB7IGZlZTogJzEwMDAnIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9ucy5sZW5ndGguc2hvdWxkLmVxdWFscygxKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS50eXBlLnNob3VsZC5lcXVhbHMoJ3RyYW5zZmVyVG9rZW4nKTtcbiAgICAgIGV4cGxhaW4ub3BlcmF0aW9uc1swXS5jb2luLnNob3VsZC5lcXVhbHMoJ3RhbGdvOlVTREMtMTA0NTg5NDEnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2Rlcml2ZUtleVdpdGhTZWVkJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgZGVyaXZlIGtleSB3aXRoIHNlZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAoKCkgPT4ge1xuICAgICAgICBiYXNlY29pbi5kZXJpdmVLZXlXaXRoU2VlZCgndGVzdCcpO1xuICAgICAgfSkuc2hvdWxkLnRocm93KCdtZXRob2QgZGVyaXZlS2V5V2l0aFNlZWQgbm90IHN1cHBvcnRlZCBmb3IgZWRkc2EgY3VydmUnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlY292ZXJ5JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGZlZSA9IDEwMDA7XG4gICAgY29uc3QgdXNlcktleSA9XG4gICAgICAne1wiaXZcIjpcIlpKZzBhMCt6VCs2ODRNVWw0NExtNEE9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjEyOCxcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJhYlF5ME9MMjQ2OD1cIixcImN0XCI6XCJMTmxTbFRKRUQ4alN3SENtVWZsenFGdFJQTCtQb2p6T2dmZDVtRDJubUxWZEFveUtDV0h2QWllS3Q3bEo3emc0MTdDVWk2UWo3Ny9zM2xicW14VnNmRXNrXCJ9JztcbiAgICBjb25zdCB1c2VyUHViID0gJ1M0RDdERFJBSFdaSUIyUkNaSUNTUk9ERkNOUVhHQU5IR0E3VkNXQks1STM3U1FUNktWSFhRTktNVEUnO1xuICAgIGNvbnN0IGJhY2t1cEtleSA9XG4gICAgICAne1wiaXZcIjpcIm1aWThYVHZIeFg4QlBjMXJkR1FRd3c9PVwiLFwidlwiOjEsXCJpdGVyXCI6MTAwMDAsXCJrc1wiOjEyOCxcInRzXCI6NjQsXCJtb2RlXCI6XCJjY21cIixcImFkYXRhXCI6XCJcIixcImNpcGhlclwiOlwiYWVzXCIsXCJzYWx0XCI6XCJhYlF5ME9MMjQ2OD1cIixcImN0XCI6XCJVUVhvMEVhUFhiNlRJWkRZWWhLWVM5ZC9mUk1OVDZwdHBsOUJnSnczQVZvb1NiTzRucHBXblRSWWxRTzdocE9ONFhZODVoWUR1LzdoeTkxSVgxejFiRERxXCJ9JztcbiAgICBjb25zdCBiYWNrdXBQdWIgPSAnNkZWR1pVWk9IWlNYVFRCUkxXWkRYR1lTV1ZWWU5ONFpFU0lFTVpFTUlCSkNVQkhDNUM3N09JRTVSUSc7XG4gICAgY29uc3Qgcm9vdEFkZHJlc3MgPSAnRldMTkRMN1VYQ1NPUE9RWEE1VlUyRE1BTlpBWUNDTUJZMzc3SEtUR0dNWjRHRVBFSkJGQVJET0dCQSc7XG4gICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdUZXN0aW5nQDQzMjEwISc7XG4gICAgY29uc3QgcmVjb3ZlcnlEZXN0aW5hdGlvbiA9ICdHQjNZRVRENVRTVEJBSVlHWUhWV1UzTzNJN1hHT0I0NEhPWkE1TU9FRjVNMjNDTExaS1JRTEVWQU9BJztcbiAgICBjb25zdCBiaXRnb1B1YiA9ICdGSlNXTExQUkJYRUdNV1pZNUJYQTY2NzNZS0lLN0pPVVJWQ1FFT1dYQzVUUVBDWENPSzNWSE9PMlZRJztcbiAgICBjb25zdCBuYXRpdmVCYWxhbmNlID0gMTAwMDAwMDA7IC8vIDEwIEFMR09cbiAgICBjb25zdCBNSU5fQUNDT1VOVF9CQUxBTkNFID0gMTAwMDAwOyAvLyAxIEFHTE9cblxuICAgIGNvbnN0IG5vZGVQYXJhbXMgPSB7XG4gICAgICB0b2tlbjogJzI4MTBjMmQxNjhlODQxN2M1ZjExMWQzOGQ2ODMyN2I4Y2ZlMmQwZGRjMDI5ODY0OTBjMjJmOGRkZjQxMjhiY2QnLFxuICAgICAgYmFzZVNlcnZlcjogJ2h0dHA6Ly9sb2NhbGhvc3QvJyxcbiAgICAgIHBvcnQ6IDg0NDMsXG4gICAgfTtcblxuICAgIGRlc2NyaWJlKCdOb24tQml0R28nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzYW5kQm94ID0gU2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgY29uc3QgZXhwZWN0ZWRBbW91bnQgPSBuZXcgQmlnTnVtYmVyKG5hdGl2ZUJhbGFuY2UpLm1pbnVzKGZlZSkubWludXMoTUlOX0FDQ09VTlRfQkFMQU5DRSkudG9TdHJpbmcoKTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZEJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBhbmQgc2lnbiB0aGUgcmVjb3ZlcnkgdHgnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGdldEJhbGFuY2VTdHViID0gc2FuZEJveC5zdHViKEFsZ28ucHJvdG90eXBlLCAnZ2V0QWNjb3VudEJhbGFuY2UnKS5yZXNvbHZlcyhuYXRpdmVCYWxhbmNlKTtcblxuICAgICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXksXG4gICAgICAgICAgYmFja3VwS2V5LFxuICAgICAgICAgIHJvb3RBZGRyZXNzLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgZmVlLFxuICAgICAgICAgIGJpdGdvS2V5OiBiaXRnb1B1YixcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgIGZpcnN0Um91bmQ6IDUwMDI1OTYsXG4gICAgICAgICAgbm9kZVBhcmFtcyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lkJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb2luJywgJ3RhbGdvJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmaXJzdFJvdW5kJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdsYXN0Um91bmQnKTtcbiAgICAgICAgZ2V0QmFsYW5jZVN0dWIuY2FsbENvdW50LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgY29uc3QgZmFjdG9yeSA9IG5ldyBBbGdvTGliLlRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCdhbGdvJykpO1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20ocmVjb3ZlcnkudHgpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICBjb25zdCB0eEJyb2FkY2FzdEZvcm1hdCA9IEJ1ZmZlci5mcm9tKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICAgICAgdHhCcm9hZGNhc3RGb3JtYXQuc2hvdWxkLmRlZXBFcXVhbChyZWNvdmVyeS50eCk7XG4gICAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgICB0eEpzb24uYW1vdW50LnNob3VsZC5lcXVhbChleHBlY3RlZEFtb3VudCk7XG4gICAgICAgIHR4SnNvbi50by5zaG91bGQuZXF1YWwocmVjb3ZlcnlEZXN0aW5hdGlvbik7XG4gICAgICAgIHR4SnNvbi5mcm9tLnNob3VsZC5lcXVhbChyb290QWRkcmVzcyk7XG4gICAgICAgIHR4SnNvbi5mZWUuc2hvdWxkLmVxdWFsKGZlZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgaW52YWxpZCByb290QWRkcmVzcycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgaW52YWxpZFJvb3RBZGRyZXNzID0gJ3JhbmRvbXN0cmluZyc7XG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgICAgICB1c2VyS2V5LFxuICAgICAgICAgICAgICBiYWNrdXBLZXksXG4gICAgICAgICAgICAgIHJvb3RBZGRyZXNzOiBpbnZhbGlkUm9vdEFkZHJlc3MsXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIGZlZSxcbiAgICAgICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICAgICAgZmlyc3RSb3VuZDogNTAwMjU5NixcbiAgICAgICAgICAgICAgbm9kZVBhcmFtcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBtZXNzYWdlOiAnaW52YWxpZCByb290QWRkcmVzcywgZ290OiAnICsgaW52YWxpZFJvb3RBZGRyZXNzIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGZvciBpbnZhbGlkIHJlY292ZXJ5RGVzdGluYXRpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGludmFsaWRSZWNvdmVyeURlc3RpbmF0aW9uID0gJ3JhbmRvbXN0cmluZyc7XG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgICAgICB1c2VyS2V5LFxuICAgICAgICAgICAgICBiYWNrdXBLZXksXG4gICAgICAgICAgICAgIHJvb3RBZGRyZXNzLFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgICBmZWUsXG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb246IGludmFsaWRSZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgICAgICBmaXJzdFJvdW5kOiA1MDAyNTk2LFxuICAgICAgICAgICAgICBub2RlUGFyYW1zLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IG1lc3NhZ2U6ICdpbnZhbGlkIHJlY292ZXJ5RGVzdGluYXRpb24sIGdvdDogJyArIGludmFsaWRSZWNvdmVyeURlc3RpbmF0aW9uIH1cbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHRocm93IGlmIHRoZXJlIGlzIG5vIGVub3VnaCBiYWxhbmNlIHRvIHJlY292ZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IGdldEJhbGFuY2VTdHViID0gc2FuZEJveC5zdHViKEFsZ28ucHJvdG90eXBlLCAnZ2V0QWNjb3VudEJhbGFuY2UnKS5yZXNvbHZlcygxMDA1MDApO1xuICAgICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhcbiAgICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgICAgICAgdXNlcktleSxcbiAgICAgICAgICAgICAgYmFja3VwS2V5LFxuICAgICAgICAgICAgICByb290QWRkcmVzcyxcbiAgICAgICAgICAgICAgZmVlLFxuICAgICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgICAgICBiaXRnb0tleTogYml0Z29QdWIsXG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgICAgIGZpcnN0Um91bmQ6IDUwMDM1OTYsXG4gICAgICAgICAgICAgIG5vZGVQYXJhbXMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgbWVzc2FnZTogJ0luc3VmZmljaWVudCBiYWxhbmNlIHRvIHJlY292ZXIsIGdvdCBiYWxhbmNlOiAxMDA1MDAgZmVlOiAxMDAwIG1pbiBhY2NvdW50IGJhbGFuY2U6IDEwMDAwMCcgfVxuICAgICAgICApO1xuXG4gICAgICAgIGdldEJhbGFuY2VTdHViLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiB0aGUgd2FsbGV0UGFzc3BocmFzZSBpcyB1bmRlZmluZWQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgICAgICB1c2VyS2V5LFxuICAgICAgICAgICAgICBiYWNrdXBLZXksXG4gICAgICAgICAgICAgIHJvb3RBZGRyZXNzLFxuICAgICAgICAgICAgICBmZWUsXG4gICAgICAgICAgICAgIHJlY292ZXJ5RGVzdGluYXRpb24sXG4gICAgICAgICAgICAgIGZpcnN0Um91bmQ6IDUwMDM1OTYsXG4gICAgICAgICAgICAgIG5vZGVQYXJhbXMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgbWVzc2FnZTogJ3dhbGxldFBhc3NwaHJhc2UgaXMgcmVxdWlyZWQgZm9yIG5vbi1iaXRnbyByZWNvdmVyeScgfVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgdGhlIHdhbGxldFBhc3NwaHJhc2UgaXMgd3JvbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKFxuICAgICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgICAgICB1c2VyS2V5LFxuICAgICAgICAgICAgICBiYWNrdXBLZXksXG4gICAgICAgICAgICAgIHJvb3RBZGRyZXNzLFxuICAgICAgICAgICAgICBiaXRnb0tleTogYml0Z29QdWIsXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICd3cm9uZ3Bhc3N3b3JkJyxcbiAgICAgICAgICAgICAgZmVlLFxuICAgICAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgICAgICBmaXJzdFJvdW5kOiA1MDAzNTk2LFxuICAgICAgICAgICAgICBub2RlUGFyYW1zLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtZXNzYWdlOlxuICAgICAgICAgICAgICBcInVuYWJsZSB0byBkZWNyeXB0IHVzZXJLZXkgb3IgYmFja3VwS2V5IHdpdGggdGhlIHdhbGxldFBhc3NwaHJhc2UgcHJvdmlkZWQsIGdvdCBlcnJvcjogcGFzc3dvcmQgZXJyb3IgLSBjY206IHRhZyBkb2Vzbid0IG1hdGNoXCIsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgYml0Z28ga2V5IGlzIG5vdCBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgYmFzZWNvaW4ucmVjb3Zlcih7XG4gICAgICAgICAgICAgIHVzZXJLZXksXG4gICAgICAgICAgICAgIGJhY2t1cEtleSxcbiAgICAgICAgICAgICAgcm9vdEFkZHJlc3MsXG4gICAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgICAgIGZlZSxcbiAgICAgICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICAgICAgZmlyc3RSb3VuZDogNTAwMzU5NixcbiAgICAgICAgICAgICAgbm9kZVBhcmFtcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWVzc2FnZTogJ2JpdGdvIHB1YmxpYyBrZXkgZnJvbSB0aGUga2V5Q2FyZCBpcyByZXF1aXJlZCBmb3Igbm9uLWJpdGdvIHJlY292ZXJ5JyxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBiZSBhYmxlIHRvIHBhc3MgYSB1dGYtOCBlbmNvZGVkIG5vdGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbnN0IG5vdGUgPSAnTm9uLUJpdEdvIFJlY292ZXJ5IFN3ZWVwIFR4JztcbiAgICAgICAgc2FuZEJveC5zdHViKEFsZ28ucHJvdG90eXBlLCAnZ2V0QWNjb3VudEJhbGFuY2UnKS5yZXNvbHZlcyhuYXRpdmVCYWxhbmNlKTtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5LFxuICAgICAgICAgIGJhY2t1cEtleSxcbiAgICAgICAgICByb290QWRkcmVzcyxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGZlZSxcbiAgICAgICAgICBiaXRnb0tleTogYml0Z29QdWIsXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbjogcmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICBmaXJzdFJvdW5kOiA1MDAyNTk2LFxuICAgICAgICAgIG5vZGVQYXJhbXMsXG4gICAgICAgICAgbm90ZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgICAgcmVjb3Zlcnkubm90ZS5zaG91bGQuYmUuZXF1YWwobm90ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdVbnNpZ25lZCBTd2VlcCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNhbmRCb3ggPSBTaW5vbi5jcmVhdGVTYW5kYm94KCk7XG4gICAgICBjb25zdCBleHBlY3RlZEFtb3VudCA9IG5ldyBCaWdOdW1iZXIobmF0aXZlQmFsYW5jZSkubWludXMoZmVlKS5taW51cyhNSU5fQUNDT1VOVF9CQUxBTkNFKS50b1N0cmluZygpO1xuICAgICAgbGV0IGdldEJhbGFuY2VTdHViOiBTaW5vblN0dWI7XG5cbiAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBnZXRCYWxhbmNlU3R1YiA9IHNhbmRCb3guc3R1YihBbGdvLnByb3RvdHlwZSwgJ2dldEFjY291bnRCYWxhbmNlJykucmVzb2x2ZXMobmF0aXZlQmFsYW5jZSk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZEJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCB1bnNpZ25lZCBzd2VlcCB0eCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiB1c2VyUHViLFxuICAgICAgICAgIGJhY2t1cEtleTogYmFja3VwUHViLFxuICAgICAgICAgIGJpdGdvS2V5OiBiaXRnb1B1YixcbiAgICAgICAgICByb290QWRkcmVzcyxcbiAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIGZlZSxcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgIGZpcnN0Um91bmQ6IDUwMDM1OTYsXG4gICAgICAgICAgbm9kZVBhcmFtcyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZ2V0QmFsYW5jZVN0dWIuY2FsbENvdW50LnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgICByZWNvdmVyeS5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndHhIZXgnKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R5cGUnKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2Ftb3VudCcpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlSW5mbycpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnY29pbicsICd0YWxnbycpO1xuICAgICAgICByZWNvdmVyeS5maXJzdFJvdW5kLnNob3VsZC5ub3QuYmUudW5kZWZpbmVkKCk7XG4gICAgICAgIHJlY292ZXJ5Lmxhc3RSb3VuZC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgna2V5cycpO1xuICAgICAgICByZWNvdmVyeS5rZXlzLnNob3VsZC5kZWVwRXF1YWwoW3VzZXJQdWIsIGJhY2t1cFB1YiwgYml0Z29QdWJdKTtcbiAgICAgICAgcmVjb3ZlcnkuYWRkcmVzc1ZlcnNpb24uc2hvdWxkLmVxdWFsKDEpO1xuXG4gICAgICAgIGdldEJhbGFuY2VTdHViLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgQWxnb0xpYi5UcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW5zLmdldCgnYWxnbycpKTtcbiAgICAgICAgY29uc3QgdHhCdWlsZGVyID0gZmFjdG9yeS5mcm9tKHJlY292ZXJ5LnR4SGV4KTtcbiAgICAgICAgY29uc3QgdHggPSBhd2FpdCB0eEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgICAgQnVmZmVyLmZyb20odHgudG9Ccm9hZGNhc3RGb3JtYXQoKSkudG9TdHJpbmcoJ2hleCcpLnNob3VsZC5kZWVwRXF1YWwocmVjb3ZlcnkudHhIZXgpO1xuICAgICAgICBjb25zdCB0eEpzb24gPSB0eC50b0pzb24oKTtcbiAgICAgICAgdHhKc29uLmFtb3VudC5zaG91bGQuZXF1YWwoZXhwZWN0ZWRBbW91bnQpO1xuICAgICAgICB0eEpzb24udG8uc2hvdWxkLmVxdWFsKHJlY292ZXJ5RGVzdGluYXRpb24pO1xuICAgICAgICB0eEpzb24uZnJvbS5zaG91bGQuZXF1YWwocm9vdEFkZHJlc3MpO1xuICAgICAgICB0eEpzb24uZmVlLnNob3VsZC5lcXVhbChmZWUpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnUmVjb3Zlcnkgd2l0aCByb290IGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzYW5kQm94ID0gU2lub24uY3JlYXRlU2FuZGJveCgpO1xuICAgICAgbGV0IHVzZXJLcDogS2V5UGFpcjtcbiAgICAgIGxldCBiYWNrdXBLcDogS2V5UGFpcjtcbiAgICAgIGxldCByb290QWRkcmVzczogc3RyaW5nO1xuICAgICAgbGV0IGVuY3J5cHRlZFVzZXJQcnY6IHN0cmluZztcbiAgICAgIGxldCBlbmNyeXB0ZWRCYWNrdXBQcnY6IHN0cmluZztcblxuICAgICAgY29uc3QgZXhwZWN0ZWRBbW91bnQgPSBuZXcgQmlnTnVtYmVyKG5hdGl2ZUJhbGFuY2UpLm1pbnVzKGZlZSkubWludXMoTUlOX0FDQ09VTlRfQkFMQU5DRSkudG9TdHJpbmcoKTtcbiAgICAgIGxldCBnZXRCYWxhbmNlU3R1YjogU2lub25TdHViO1xuXG4gICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdXNlclNlZWQgPSBCdWZmZXIuZnJvbSgnOWQ2MWIxOWRlZmZkNWE2MGJhODQ0YWY0OTJlYzJjYzQ0NDQ5YzU2OTdiMzI2OTE5NzAzYmFjMDMxY2FlN2Y2MCcsICdoZXgnKTtcbiAgICAgICAgdXNlcktwID0gYmFzZWNvaW4uZ2VuZXJhdGVSb290S2V5UGFpcih1c2VyU2VlZCk7XG4gICAgICAgIGVuY3J5cHRlZFVzZXJQcnYgPSBiaXRnby5lbmNyeXB0KHtcbiAgICAgICAgICBpbnB1dDogdXNlcktwLnBydixcbiAgICAgICAgICBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydCh1c2VyS3AucHViKTtcblxuICAgICAgICBjb25zdCBiYWNrdXBTZWVkID0gQnVmZmVyLmZyb20oJzZkNjFiMTlkZWZmZDVhNjBiYTg0NGFmNDkyZWMyY2M0NDQ0OWM1Njk3YjMyNjkxOTcwM2JhYzAzMWNhZTdmNjAnLCAnaGV4Jyk7XG4gICAgICAgIGJhY2t1cEtwID0gYmFzZWNvaW4uZ2VuZXJhdGVSb290S2V5UGFpcihiYWNrdXBTZWVkKTtcbiAgICAgICAgZW5jcnlwdGVkQmFja3VwUHJ2ID0gYml0Z28uZW5jcnlwdCh7XG4gICAgICAgICAgaW5wdXQ6IGJhY2t1cEtwLnBydixcbiAgICAgICAgICBwYXNzd29yZDogd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGJpdGdvUHViID0gJ0ZKU1dMTFBSQlhFR01XWlk1QlhBNjY3M1lLSUs3Sk9VUlZDUUVPV1hDNVRRUENYQ09LM1ZIT08yVlEnO1xuICAgICAgICBjb25zdCB1c2VyQWRkcmVzcyA9IEFsZ29MaWIuYWxnb1V0aWxzLnByaXZhdGVLZXlUb0FsZ29BZGRyZXNzKHVzZXJLcC5wcnYpO1xuICAgICAgICBjb25zdCBiYWNrdXBBZGRyZXNzID0gQWxnb0xpYi5hbGdvVXRpbHMucHJpdmF0ZUtleVRvQWxnb0FkZHJlc3MoYmFja3VwS3AucHJ2KTtcblxuICAgICAgICByb290QWRkcmVzcyA9IEFsZ29MaWIuYWxnb1V0aWxzLm11bHRpc2lnQWRkcmVzcygxLCAyLCBbdXNlckFkZHJlc3MsIGJhY2t1cEFkZHJlc3MsIGJpdGdvUHViXSk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2FuZEJveC52ZXJpZnlBbmRSZXN0b3JlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCBhbmQgc2lnbiBub24tYml0Z28gcmVjb3ZlcnkgdHggd2l0aCByb290IGtleXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdldEJhbGFuY2VTdHViID0gc2FuZEJveC5zdHViKEFsZ28ucHJvdG90eXBlLCAnZ2V0QWNjb3VudEJhbGFuY2UnKS5yZXNvbHZlcyhuYXRpdmVCYWxhbmNlKTtcbiAgICAgICAgY29uc3QgcmVjb3ZlcnkgPSBhd2FpdCBiYXNlY29pbi5yZWNvdmVyKHtcbiAgICAgICAgICB1c2VyS2V5OiBlbmNyeXB0ZWRVc2VyUHJ2LFxuICAgICAgICAgIGJhY2t1cEtleTogZW5jcnlwdGVkQmFja3VwUHJ2LFxuICAgICAgICAgIHJvb3RBZGRyZXNzLFxuICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2UsXG4gICAgICAgICAgZmVlLFxuICAgICAgICAgIGJpdGdvS2V5OiBiaXRnb1B1YixcbiAgICAgICAgICByZWNvdmVyeURlc3RpbmF0aW9uOiByZWNvdmVyeURlc3RpbmF0aW9uLFxuICAgICAgICAgIGZpcnN0Um91bmQ6IDUwMDI1OTYsXG4gICAgICAgICAgbm9kZVBhcmFtcyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lkJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eCcpO1xuICAgICAgICByZWNvdmVyeS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnZmVlJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdjb2luJywgJ3RhbGdvJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdmaXJzdFJvdW5kJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdsYXN0Um91bmQnKTtcbiAgICAgICAgZ2V0QmFsYW5jZVN0dWIuY2FsbENvdW50LnNob3VsZC5lcXVhbCgxKTtcbiAgICAgICAgY29uc3QgZmFjdG9yeSA9IG5ldyBBbGdvTGliLlRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbnMuZ2V0KCdhbGdvJykpO1xuICAgICAgICBjb25zdCB0eEJ1aWxkZXIgPSBmYWN0b3J5LmZyb20ocmVjb3ZlcnkudHgpO1xuICAgICAgICBjb25zdCB0eCA9IGF3YWl0IHR4QnVpbGRlci5idWlsZCgpO1xuICAgICAgICBjb25zdCB0eEJyb2FkY2FzdEZvcm1hdCA9IEJ1ZmZlci5mcm9tKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICAgICAgdHhCcm9hZGNhc3RGb3JtYXQuc2hvdWxkLmRlZXBFcXVhbChyZWNvdmVyeS50eCk7XG4gICAgICAgIGNvbnN0IHR4SnNvbiA9IHR4LnRvSnNvbigpO1xuICAgICAgICB0eEpzb24uYW1vdW50LnNob3VsZC5lcXVhbChleHBlY3RlZEFtb3VudCk7XG4gICAgICAgIHR4SnNvbi50by5zaG91bGQuZXF1YWwocmVjb3ZlcnlEZXN0aW5hdGlvbik7XG4gICAgICAgIHR4SnNvbi5mcm9tLnNob3VsZC5lcXVhbChyb290QWRkcmVzcyk7XG4gICAgICAgIHR4SnNvbi5mZWUuc2hvdWxkLmVxdWFsKGZlZSk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBidWlsZCB1bnNpZ25lZCBzd2VlcCB0eCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZ2V0QmFsYW5jZVN0dWIgPSBzYW5kQm94LnN0dWIoQWxnby5wcm90b3R5cGUsICdnZXRBY2NvdW50QmFsYW5jZScpLnJlc29sdmVzKG5hdGl2ZUJhbGFuY2UpO1xuICAgICAgICBjb25zdCByZWNvdmVyeSA9IGF3YWl0IGJhc2Vjb2luLnJlY292ZXIoe1xuICAgICAgICAgIHVzZXJLZXk6IHVzZXJLcC5wdWIhLFxuICAgICAgICAgIGJhY2t1cEtleTogYmFja3VwS3AucHViISxcbiAgICAgICAgICBiaXRnb0tleTogYml0Z29QdWIsXG4gICAgICAgICAgcm9vdEFkZHJlc3MsXG4gICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICBmZWUsXG4gICAgICAgICAgcmVjb3ZlcnlEZXN0aW5hdGlvbixcbiAgICAgICAgICBmaXJzdFJvdW5kOiA1MDAzNTk2LFxuICAgICAgICAgIG5vZGVQYXJhbXMsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGdldEJhbGFuY2VTdHViLmNhbGxDb3VudC5zaG91bGQuZXF1YWwoMSk7XG5cbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ3R4SGV4Jyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eXBlJyk7XG4gICAgICAgIHJlY292ZXJ5LnNob3VsZC5oYXZlLnByb3BlcnR5KCdhbW91bnQnKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2ZlZUluZm8nKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2NvaW4nLCAndGFsZ28nKTtcbiAgICAgICAgcmVjb3ZlcnkuZmlyc3RSb3VuZC5zaG91bGQubm90LmJlLnVuZGVmaW5lZCgpO1xuICAgICAgICByZWNvdmVyeS5sYXN0Um91bmQuc2hvdWxkLm5vdC5iZS51bmRlZmluZWQoKTtcbiAgICAgICAgcmVjb3Zlcnkuc2hvdWxkLmhhdmUucHJvcGVydHkoJ2tleXMnKTtcbiAgICAgICAgcmVjb3Zlcnkua2V5cy5zaG91bGQuZGVlcEVxdWFsKFt1c2VyS3AucHViLCBiYWNrdXBLcC5wdWIsIGJpdGdvUHViXSk7XG4gICAgICAgIHJlY292ZXJ5LmFkZHJlc3NWZXJzaW9uLnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgICBnZXRCYWxhbmNlU3R1Yi5jYWxsQ291bnQuc2hvdWxkLmVxdWFsKDEpO1xuICAgICAgICBjb25zdCBmYWN0b3J5ID0gbmV3IEFsZ29MaWIuVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2lucy5nZXQoJ2FsZ28nKSk7XG4gICAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGZhY3RvcnkuZnJvbShyZWNvdmVyeS50eEhleCk7XG4gICAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIEJ1ZmZlci5mcm9tKHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCkpLnRvU3RyaW5nKCdoZXgnKS5zaG91bGQuZGVlcEVxdWFsKHJlY292ZXJ5LnR4SGV4KTtcbiAgICAgICAgY29uc3QgdHhKc29uID0gdHgudG9Kc29uKCk7XG4gICAgICAgIHR4SnNvbi5hbW91bnQuc2hvdWxkLmVxdWFsKGV4cGVjdGVkQW1vdW50KTtcbiAgICAgICAgdHhKc29uLnRvLnNob3VsZC5lcXVhbChyZWNvdmVyeURlc3RpbmF0aW9uKTtcbiAgICAgICAgdHhKc29uLmZyb20uc2hvdWxkLmVxdWFsKHJvb3RBZGRyZXNzKTtcbiAgICAgICAgdHhKc29uLmZlZS5zaG91bGQuZXF1YWwoZmVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQXVkaXRLZXknLCAoKSA9PiB7XG4gICAgY29uc3QgeyBrZXkgfSA9IGFsZ29CYWNrdXBLZXk7XG4gICAgY29uc3Qgd2FsbGV0UGFzc3BocmFzZSA9ICdaUThNaHhUODRtNFAnO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZm9yIHZhbGlkIGlucHV0cycsICgpID0+IHtcbiAgICAgIGJhc2Vjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBpZiB0aGUgd2FsbGV0UGFzc3BocmFzZSBpcyBpbmNvcnJlY3QnLCAoKSA9PiB7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgYmFzZWNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICBlbmNyeXB0ZWRQcnY6IGtleSxcbiAgICAgICAgICAgIHdhbGxldFBhc3NwaHJhc2U6ICdmb28nLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICB7IG1lc3NhZ2U6IFwiZmFpbGVkIHRvIGRlY3J5cHQgcHJ2OiBjY206IHRhZyBkb2Vzbid0IG1hdGNoXCIgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdGhlIGtleSBpcyBhbHRlcmVkJywgKCkgPT4ge1xuICAgICAgY29uc3QgYWx0ZXJlZEtleSA9IGtleS5yZXBsYWNlKC9bMC05XS9nLCAnMCcpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGJhc2Vjb2luLmFzc2VydElzVmFsaWRLZXkoe1xuICAgICAgICAgICAgZW5jcnlwdGVkUHJ2OiBhbHRlcmVkS2V5LFxuICAgICAgICAgICAgd2FsbGV0UGFzc3BocmFzZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgeyBtZXNzYWdlOiAnZmFpbGVkIHRvIGRlY3J5cHQgcHJ2OiBqc29uIGRlY3J5cHQ6IGludmFsaWQgcGFyYW1ldGVycycgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgaWYgdGhlIGtleSBpcyBub3QgYSB2YWxpZCBrZXknLCAoKSA9PiB7XG4gICAgICBjb25zdCBpbnZhbGlkS2V5ID0gJyNAKSQjKCQqQCkjKCQqJztcbiAgICAgIGNvbnN0IGVuY3J5cHRlZFBydiA9IGVuY3J5cHQod2FsbGV0UGFzc3BocmFzZSwgaW52YWxpZEtleSk7XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgYmFzZWNvaW4uYXNzZXJ0SXNWYWxpZEtleSh7XG4gICAgICAgICAgICBlbmNyeXB0ZWRQcnYsXG4gICAgICAgICAgICB3YWxsZXRQYXNzcGhyYXNlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICB7IG1lc3NhZ2U6ICdJbnZhbGlkIHByaXZhdGUga2V5OiBJbnZhbGlkIGJhc2UzMiBjaGFyYWN0ZXJzJyB9XG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19