@bitgo-beta/sdk-coin-flrp 1.0.1-beta.7 → 1.0.1-beta.70

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 (88) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/src/flrp.d.ts +82 -61
  3. package/dist/src/flrp.d.ts.map +1 -1
  4. package/dist/src/flrp.js +293 -134
  5. package/dist/src/lib/atomicTransactionBuilder.d.ts +42 -6
  6. package/dist/src/lib/atomicTransactionBuilder.d.ts.map +1 -1
  7. package/dist/src/lib/atomicTransactionBuilder.js +233 -29
  8. package/dist/src/lib/constants.d.ts +160 -1
  9. package/dist/src/lib/constants.d.ts.map +1 -1
  10. package/dist/src/lib/constants.js +213 -3
  11. package/dist/src/lib/delegatorTxBuilder.d.ts +58 -0
  12. package/dist/src/lib/delegatorTxBuilder.d.ts.map +1 -0
  13. package/dist/src/lib/delegatorTxBuilder.js +224 -0
  14. package/dist/src/lib/exportInCTxBuilder.d.ts +1 -1
  15. package/dist/src/lib/exportInCTxBuilder.d.ts.map +1 -1
  16. package/dist/src/lib/exportInCTxBuilder.js +46 -17
  17. package/dist/src/lib/exportInPTxBuilder.d.ts +1 -1
  18. package/dist/src/lib/exportInPTxBuilder.d.ts.map +1 -1
  19. package/dist/src/lib/exportInPTxBuilder.js +70 -6
  20. package/dist/src/lib/iface.d.ts +52 -1
  21. package/dist/src/lib/iface.d.ts.map +1 -1
  22. package/dist/src/lib/iface.js +1 -1
  23. package/dist/src/lib/importInCTxBuilder.d.ts +67 -0
  24. package/dist/src/lib/importInCTxBuilder.d.ts.map +1 -0
  25. package/dist/src/lib/importInCTxBuilder.js +403 -0
  26. package/dist/src/lib/importInPTxBuilder.d.ts +73 -0
  27. package/dist/src/lib/importInPTxBuilder.d.ts.map +1 -0
  28. package/dist/src/lib/importInPTxBuilder.js +464 -0
  29. package/dist/src/lib/index.d.ts +7 -0
  30. package/dist/src/lib/index.d.ts.map +1 -1
  31. package/dist/src/lib/index.js +15 -2
  32. package/dist/src/lib/keyPair.d.ts.map +1 -1
  33. package/dist/src/lib/keyPair.js +4 -6
  34. package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts +81 -0
  35. package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts.map +1 -0
  36. package/dist/src/lib/permissionlessValidatorTxBuilder.js +248 -0
  37. package/dist/src/lib/transaction.d.ts +111 -0
  38. package/dist/src/lib/transaction.d.ts.map +1 -0
  39. package/dist/src/lib/transaction.js +322 -0
  40. package/dist/src/lib/transactionBuilder.d.ts +85 -0
  41. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  42. package/dist/src/lib/transactionBuilder.js +167 -0
  43. package/dist/src/lib/transactionBuilderFactory.d.ts +37 -0
  44. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -0
  45. package/dist/src/lib/transactionBuilderFactory.js +91 -0
  46. package/dist/src/lib/types.d.ts +78 -0
  47. package/dist/src/lib/types.d.ts.map +1 -0
  48. package/dist/src/lib/types.js +5 -0
  49. package/dist/src/lib/utils.d.ts +59 -0
  50. package/dist/src/lib/utils.d.ts.map +1 -1
  51. package/dist/src/lib/utils.js +160 -52
  52. package/dist/src/lib/validatorTxBuilder.d.ts +40 -0
  53. package/dist/src/lib/validatorTxBuilder.d.ts.map +1 -0
  54. package/dist/src/lib/validatorTxBuilder.js +180 -0
  55. package/dist/test/unit/delegatorTxBuilder.test.d.ts +2 -0
  56. package/dist/test/unit/delegatorTxBuilder.test.d.ts.map +1 -0
  57. package/dist/test/unit/delegatorTxBuilder.test.js +233 -0
  58. package/dist/test/unit/lib/atomicTransactionBuilder.js +37 -11
  59. package/dist/test/unit/lib/exportInCTxBuilder.d.ts +2 -0
  60. package/dist/test/unit/lib/exportInCTxBuilder.d.ts.map +1 -0
  61. package/dist/test/unit/lib/exportInCTxBuilder.js +584 -0
  62. package/dist/test/unit/lib/exportInPTxBuilder.d.ts +2 -0
  63. package/dist/test/unit/lib/exportInPTxBuilder.d.ts.map +1 -0
  64. package/dist/test/unit/lib/exportInPTxBuilder.js +377 -0
  65. package/dist/test/unit/lib/importInCTxBuilder.d.ts +2 -0
  66. package/dist/test/unit/lib/importInCTxBuilder.d.ts.map +1 -0
  67. package/dist/test/unit/lib/importInCTxBuilder.js +257 -0
  68. package/dist/test/unit/lib/importInPTxBuilder.d.ts +2 -0
  69. package/dist/test/unit/lib/importInPTxBuilder.d.ts.map +1 -0
  70. package/dist/test/unit/lib/importInPTxBuilder.js +500 -0
  71. package/dist/test/unit/lib/transaction.d.ts +2 -0
  72. package/dist/test/unit/lib/transaction.d.ts.map +1 -0
  73. package/dist/test/unit/lib/transaction.js +460 -0
  74. package/dist/test/unit/lib/utils.js +55 -1
  75. package/dist/test/unit/permissionlessValidatorTxBuilder.test.d.ts +2 -0
  76. package/dist/test/unit/permissionlessValidatorTxBuilder.test.d.ts.map +1 -0
  77. package/dist/test/unit/permissionlessValidatorTxBuilder.test.js +271 -0
  78. package/dist/test/unit/transactionBuilder.test.d.ts +2 -0
  79. package/dist/test/unit/transactionBuilder.test.d.ts.map +1 -0
  80. package/dist/test/unit/transactionBuilder.test.js +114 -0
  81. package/dist/test/unit/validatorTxBuilder.test.d.ts +2 -0
  82. package/dist/test/unit/validatorTxBuilder.test.d.ts.map +1 -0
  83. package/dist/test/unit/validatorTxBuilder.test.js +293 -0
  84. package/dist/tsconfig.tsbuildinfo +1 -1
  85. package/package.json +8 -11
  86. package/dist/test/unit/lib/exportTxBuilder.d.ts +0 -2
  87. package/dist/test/unit/lib/exportTxBuilder.d.ts.map +0 -1
  88. package/dist/test/unit/lib/exportTxBuilder.js +0 -45
@@ -0,0 +1,460 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const statics_1 = require("@bitgo-beta/statics");
37
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
38
+ const assert = __importStar(require("assert"));
39
+ const transaction_1 = require("../../../src/lib/transaction");
40
+ const keyPair_1 = require("../../../src/lib/keyPair");
41
+ describe('FLRP Transaction', function () {
42
+ let transaction;
43
+ const coinConfig = statics_1.coins.get('tflrp');
44
+ // Helper to create a mock transaction for testing
45
+ const createMockTx = () => ({ test: 'transaction' });
46
+ beforeEach(function () {
47
+ transaction = new transaction_1.Transaction(coinConfig);
48
+ });
49
+ describe('Constructor', function () {
50
+ it('should initialize with correct network configuration', function () {
51
+ assert.strictEqual(transaction._assetId, 'FLR');
52
+ assert.strictEqual(transaction._blockchainID, '11111111111111111111111111111111LpoYY');
53
+ assert.strictEqual(transaction._networkID, 114);
54
+ assert.strictEqual(transaction._threshold, 2);
55
+ assert.strictEqual(transaction._locktime, BigInt(0));
56
+ });
57
+ it('should initialize empty arrays and default values', function () {
58
+ assert.deepStrictEqual(transaction._fromAddresses, []);
59
+ assert.deepStrictEqual(transaction._rewardAddresses, []);
60
+ assert.deepStrictEqual(transaction._utxos, []);
61
+ assert.deepStrictEqual(transaction._fee, {});
62
+ });
63
+ });
64
+ describe('Transaction Type Management', function () {
65
+ it('should set supported transaction types', function () {
66
+ const supportedTypes = [
67
+ sdk_core_1.TransactionType.Export,
68
+ sdk_core_1.TransactionType.Import,
69
+ sdk_core_1.TransactionType.AddValidator,
70
+ sdk_core_1.TransactionType.AddDelegator,
71
+ sdk_core_1.TransactionType.AddPermissionlessValidator,
72
+ sdk_core_1.TransactionType.AddPermissionlessDelegator,
73
+ ];
74
+ supportedTypes.forEach((type) => {
75
+ assert.doesNotThrow(() => {
76
+ transaction.setTransactionType(type);
77
+ assert.strictEqual(transaction._type, type);
78
+ });
79
+ });
80
+ });
81
+ it('should throw error for unsupported transaction types', function () {
82
+ assert.throws(() => {
83
+ transaction.setTransactionType(sdk_core_1.TransactionType.Send);
84
+ }, /Transaction type .* is not supported/);
85
+ });
86
+ });
87
+ describe('Getters', function () {
88
+ it('should return correct flareTransaction', function () {
89
+ const mockTx = createMockTx();
90
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
91
+ transaction.setTransaction(mockTx);
92
+ assert.strictEqual(transaction.flareTransaction, mockTx);
93
+ });
94
+ it('should return empty signature array when no credentials', function () {
95
+ assert.deepStrictEqual(transaction.signature, []);
96
+ });
97
+ it('should return empty credentials array', function () {
98
+ assert.deepStrictEqual(transaction.credentials, []);
99
+ });
100
+ it('should return false for hasCredentials when no credentials', function () {
101
+ assert.strictEqual(transaction.hasCredentials, false);
102
+ });
103
+ it('should return placeholder ID when no transaction set', function () {
104
+ // This should throw error when no transaction is set
105
+ assert.throws(() => {
106
+ transaction.id;
107
+ }, sdk_core_1.InvalidTransactionError);
108
+ });
109
+ it('should return placeholder signablePayload when no transaction set', function () {
110
+ // This should throw error when no transaction is set
111
+ assert.throws(() => {
112
+ void transaction.signablePayload;
113
+ }, sdk_core_1.InvalidTransactionError);
114
+ });
115
+ it('should return formatted fromAddresses', function () {
116
+ transaction._fromAddresses = ['address1', 'address2'];
117
+ const addresses = transaction.fromAddresses;
118
+ assert.deepStrictEqual(addresses, ['address1', 'address2']);
119
+ });
120
+ it('should return formatted rewardAddresses', function () {
121
+ transaction._rewardAddresses = ['reward1', 'reward2'];
122
+ const addresses = transaction.rewardAddresses;
123
+ assert.deepStrictEqual(addresses, ['reward1', 'reward2']);
124
+ });
125
+ });
126
+ describe('Transaction Outputs', function () {
127
+ beforeEach(function () {
128
+ transaction._nodeID = 'test-node-id';
129
+ transaction._stakeAmount = BigInt('1000000000000000'); // 1M FLR
130
+ });
131
+ it('should return empty outputs for Export type', function () {
132
+ transaction.setTransactionType(sdk_core_1.TransactionType.Export);
133
+ const outputs = transaction.outputs;
134
+ assert.deepStrictEqual(outputs, []);
135
+ });
136
+ it('should return empty outputs for Import type', function () {
137
+ transaction.setTransactionType(sdk_core_1.TransactionType.Import);
138
+ const outputs = transaction.outputs;
139
+ assert.deepStrictEqual(outputs, []);
140
+ });
141
+ it('should return staking outputs for AddValidator type', function () {
142
+ transaction.setTransactionType(sdk_core_1.TransactionType.AddValidator);
143
+ const outputs = transaction.outputs;
144
+ assert.strictEqual(outputs.length, 1);
145
+ assert.strictEqual(outputs[0].address, 'test-node-id');
146
+ assert.strictEqual(outputs[0].value, '1000000000000000');
147
+ });
148
+ it('should return staking outputs for AddPermissionlessValidator type', function () {
149
+ transaction.setTransactionType(sdk_core_1.TransactionType.AddPermissionlessValidator);
150
+ const outputs = transaction.outputs;
151
+ assert.strictEqual(outputs.length, 1);
152
+ assert.strictEqual(outputs[0].address, 'test-node-id');
153
+ assert.strictEqual(outputs[0].value, '1000000000000000');
154
+ });
155
+ it('should return staking outputs for AddDelegator type', function () {
156
+ transaction.setTransactionType(sdk_core_1.TransactionType.AddDelegator);
157
+ const outputs = transaction.outputs;
158
+ assert.strictEqual(outputs.length, 1);
159
+ assert.strictEqual(outputs[0].address, 'test-node-id');
160
+ assert.strictEqual(outputs[0].value, '1000000000000000');
161
+ });
162
+ it('should return staking outputs for AddPermissionlessDelegator type', function () {
163
+ transaction.setTransactionType(sdk_core_1.TransactionType.AddPermissionlessDelegator);
164
+ const outputs = transaction.outputs;
165
+ assert.strictEqual(outputs.length, 1);
166
+ assert.strictEqual(outputs[0].address, 'test-node-id');
167
+ assert.strictEqual(outputs[0].value, '1000000000000000');
168
+ });
169
+ it('should return empty outputs for unknown type', function () {
170
+ // Don't set type, should default to empty
171
+ const outputs = transaction.outputs;
172
+ assert.deepStrictEqual(outputs, []);
173
+ });
174
+ });
175
+ describe('Transaction Inputs', function () {
176
+ it('should return inputs from UTXOs', function () {
177
+ transaction._utxos = [
178
+ {
179
+ outputID: 1,
180
+ amount: '1000000',
181
+ txid: 'test-txid-1',
182
+ outputidx: '0',
183
+ threshold: 2,
184
+ addresses: ['addr1', 'addr2'],
185
+ },
186
+ {
187
+ outputID: 2,
188
+ amount: '2000000',
189
+ txid: 'test-txid-2',
190
+ outputidx: '1',
191
+ threshold: 2,
192
+ addresses: ['addr3', 'addr4'],
193
+ },
194
+ ];
195
+ transaction._fromAddresses = ['addr1', 'addr2', 'addr3', 'addr4'];
196
+ const inputs = transaction.inputs;
197
+ assert.strictEqual(inputs.length, 2);
198
+ assert.strictEqual(inputs[0].id, 'test-txid-1:0');
199
+ assert.strictEqual(inputs[0].value, '1000000');
200
+ assert.strictEqual(inputs[0].address, 'addr1~addr2~addr3~addr4');
201
+ assert.strictEqual(inputs[1].id, 'test-txid-2:1');
202
+ assert.strictEqual(inputs[1].value, '2000000');
203
+ });
204
+ it('should return empty inputs when no UTXOs', function () {
205
+ const inputs = transaction.inputs;
206
+ assert.deepStrictEqual(inputs, []);
207
+ });
208
+ });
209
+ describe('Change Outputs', function () {
210
+ it('should return empty change outputs', function () {
211
+ const changeOutputs = transaction.changeOutputs;
212
+ assert.deepStrictEqual(changeOutputs, []);
213
+ });
214
+ });
215
+ describe('Fee Handling', function () {
216
+ it('should return default fee when no fee set', function () {
217
+ const fee = transaction.fee;
218
+ assert.deepStrictEqual(fee, { fee: '0' });
219
+ });
220
+ it('should return custom fee when set', function () {
221
+ transaction._fee = { fee: '1000000' };
222
+ const fee = transaction.fee;
223
+ assert.deepStrictEqual(fee, { fee: '1000000' });
224
+ });
225
+ });
226
+ describe('Signing', function () {
227
+ let keyPair;
228
+ beforeEach(function () {
229
+ // Create a test key pair with a private key
230
+ keyPair = new keyPair_1.KeyPair({ prv: '01'.repeat(32) });
231
+ });
232
+ it('should throw error when no private key', async function () {
233
+ const emptyKeyPair = new keyPair_1.KeyPair();
234
+ await assert.rejects(async () => {
235
+ await transaction.sign(emptyKeyPair);
236
+ }, sdk_core_1.InvalidTransactionError); // Will throw InvalidTransactionError for empty transaction first
237
+ });
238
+ it('should throw error when no transaction to sign', async function () {
239
+ await assert.rejects(async () => {
240
+ await transaction.sign(keyPair);
241
+ }, sdk_core_1.InvalidTransactionError);
242
+ });
243
+ it('should throw error for FlareJS signing not implemented', async function () {
244
+ // Set a mock transaction and mock credentials to pass validation
245
+ const mockTx = createMockTx();
246
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
247
+ transaction.setTransaction(mockTx);
248
+ // Mock hasCredentials to return true
249
+ Object.defineProperty(transaction, 'hasCredentials', {
250
+ get: () => true,
251
+ });
252
+ await assert.rejects(async () => {
253
+ await transaction.sign(keyPair);
254
+ }, /FlareJS signing not yet implemented/);
255
+ });
256
+ });
257
+ describe('Serialization', function () {
258
+ it('should throw error for toBroadcastFormat when no transaction', function () {
259
+ assert.throws(() => {
260
+ transaction.toBroadcastFormat();
261
+ }, sdk_core_1.InvalidTransactionError);
262
+ });
263
+ it('should return placeholder for toBroadcastFormat when transaction set', function () {
264
+ const mockTx = createMockTx();
265
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
266
+ transaction.setTransaction(mockTx);
267
+ const broadcastFormat = transaction.toBroadcastFormat();
268
+ assert.strictEqual(broadcastFormat, 'flare-tx-hex-placeholder');
269
+ });
270
+ it('should throw error for toJson when no transaction', function () {
271
+ assert.throws(() => {
272
+ transaction.toJson();
273
+ }, sdk_core_1.InvalidTransactionError);
274
+ });
275
+ it('should return transaction data for toJson when transaction set', function () {
276
+ const mockTx = createMockTx();
277
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
278
+ transaction.setTransaction(mockTx);
279
+ transaction._fromAddresses = ['addr1'];
280
+ transaction._threshold = 2;
281
+ transaction._locktime = BigInt(100);
282
+ const jsonData = transaction.toJson();
283
+ assert.strictEqual(jsonData.id, 'flare-transaction-id-placeholder');
284
+ assert.deepStrictEqual(jsonData.fromAddresses, ['addr1']);
285
+ assert.strictEqual(jsonData.threshold, 2);
286
+ assert.strictEqual(jsonData.locktime, '100');
287
+ });
288
+ });
289
+ describe('Cross-chain Properties', function () {
290
+ it('should identify Export as cross-chain transaction', function () {
291
+ transaction.setTransactionType(sdk_core_1.TransactionType.Export);
292
+ assert.strictEqual(transaction.isTransactionForCChain, true);
293
+ });
294
+ it('should identify Import as cross-chain transaction', function () {
295
+ transaction.setTransactionType(sdk_core_1.TransactionType.Import);
296
+ assert.strictEqual(transaction.isTransactionForCChain, true);
297
+ });
298
+ it('should identify AddValidator as non-cross-chain transaction', function () {
299
+ transaction.setTransactionType(sdk_core_1.TransactionType.AddValidator);
300
+ assert.strictEqual(transaction.isTransactionForCChain, false);
301
+ });
302
+ });
303
+ describe('Transaction Explanation', function () {
304
+ beforeEach(function () {
305
+ const mockTx = createMockTx();
306
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
307
+ transaction.setTransaction(mockTx);
308
+ transaction._fromAddresses = ['test-address'];
309
+ transaction._fee = { fee: '1000000' };
310
+ });
311
+ it('should explain a basic transaction', function () {
312
+ transaction.setTransactionType(sdk_core_1.TransactionType.Export);
313
+ const explanation = transaction.explainTransaction();
314
+ assert.ok(explanation.displayOrder);
315
+ assert.ok(Array.isArray(explanation.displayOrder));
316
+ assert.strictEqual(explanation.id, 'flare-transaction-id-placeholder');
317
+ assert.deepStrictEqual(explanation.fee, { fee: '1000000' });
318
+ assert.strictEqual(explanation.type, sdk_core_1.TransactionType.Export);
319
+ });
320
+ it('should include reward addresses for staking transactions', function () {
321
+ transaction.setTransactionType(sdk_core_1.TransactionType.AddValidator);
322
+ transaction._rewardAddresses = ['reward-addr-1'];
323
+ const explanation = transaction.explainTransaction();
324
+ assert.ok(explanation.displayOrder);
325
+ assert.ok(explanation.displayOrder.includes('rewardAddresses'));
326
+ assert.deepStrictEqual(explanation.rewardAddresses, ['reward-addr-1']);
327
+ });
328
+ it('should include cross-chain information for export/import', function () {
329
+ transaction.setTransactionType(sdk_core_1.TransactionType.Export);
330
+ const explanation = transaction.explainTransaction();
331
+ assert.ok(explanation.displayOrder);
332
+ assert.ok(explanation.displayOrder.includes('sourceChain'));
333
+ assert.ok(explanation.displayOrder.includes('destinationChain'));
334
+ });
335
+ it('should calculate output amounts correctly', function () {
336
+ transaction._nodeID = 'test-node';
337
+ transaction._stakeAmount = BigInt('5000000000000000');
338
+ transaction.setTransactionType(sdk_core_1.TransactionType.AddValidator);
339
+ const explanation = transaction.explainTransaction();
340
+ assert.strictEqual(explanation.outputAmount, '5000000000000000');
341
+ assert.strictEqual(explanation.changeAmount, '0');
342
+ });
343
+ });
344
+ describe('Signature Creation', function () {
345
+ it('should create signature placeholder', function () {
346
+ const mockPrivateKey = Buffer.from('1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', 'hex');
347
+ const mockTx = createMockTx();
348
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
349
+ transaction.setTransaction(mockTx);
350
+ const signature = transaction.createSignature(mockPrivateKey);
351
+ assert.ok(typeof signature === 'string');
352
+ assert.ok(signature.length > 0);
353
+ });
354
+ });
355
+ describe('Validation', function () {
356
+ it('should allow signing with valid key', function () {
357
+ const keyPair = new keyPair_1.KeyPair({ prv: '01'.repeat(32) });
358
+ const canSign = transaction.canSign({ key: keyPair });
359
+ assert.strictEqual(canSign, true);
360
+ });
361
+ });
362
+ describe('Transaction Setting', function () {
363
+ it('should set transaction correctly', function () {
364
+ const mockTx = createMockTx();
365
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
366
+ transaction.setTransaction(mockTx);
367
+ // Can't directly access _flareTransaction (protected), but can test via getter
368
+ assert.strictEqual(transaction.flareTransaction, mockTx);
369
+ });
370
+ });
371
+ describe('Hex Conversion', function () {
372
+ it('should convert byte array to hex string', function () {
373
+ const byteArray = new Uint8Array([0x01, 0x23, 0xab, 0xcd]);
374
+ const hexString = transaction.toHexString(byteArray);
375
+ assert.strictEqual(hexString, '0123abcd');
376
+ });
377
+ it('should handle empty byte array', function () {
378
+ const byteArray = new Uint8Array([]);
379
+ const hexString = transaction.toHexString(byteArray);
380
+ assert.strictEqual(hexString, '');
381
+ });
382
+ });
383
+ describe('Memo Functionality', function () {
384
+ it('should initialize with empty memo', function () {
385
+ assert.strictEqual(transaction.hasMemo(), false);
386
+ assert.strictEqual(transaction.getMemoString(), '');
387
+ assert.deepStrictEqual(transaction.getMemoBytes(), new Uint8Array());
388
+ });
389
+ it('should set memo from string', function () {
390
+ const memoText = 'Test transaction memo';
391
+ transaction.setMemo(memoText);
392
+ assert.strictEqual(transaction.hasMemo(), true);
393
+ assert.strictEqual(transaction.getMemoString(), memoText);
394
+ assert.deepStrictEqual(transaction.getMemoBytes(), new TextEncoder().encode(memoText));
395
+ });
396
+ it('should set memo from JSON object', function () {
397
+ const memoObj = { user: 'alice', amount: 1000 };
398
+ transaction.setMemoData(memoObj);
399
+ assert.strictEqual(transaction.hasMemo(), true);
400
+ assert.strictEqual(transaction.getMemoString(), JSON.stringify(memoObj));
401
+ });
402
+ it('should set memo from bytes', function () {
403
+ const memoBytes = new TextEncoder().encode('Binary memo data');
404
+ transaction.setMemoData(memoBytes);
405
+ assert.strictEqual(transaction.hasMemo(), true);
406
+ assert.deepStrictEqual(transaction.getMemoBytes(), memoBytes);
407
+ assert.strictEqual(transaction.getMemoString(), 'Binary memo data');
408
+ });
409
+ it('should handle empty string memo', function () {
410
+ transaction.setMemo('');
411
+ assert.strictEqual(transaction.hasMemo(), false);
412
+ assert.strictEqual(transaction.getMemoString(), '');
413
+ });
414
+ it('should handle UTF-8 memo', function () {
415
+ const utf8Memo = 'Hello 世界 🌍 Flare!';
416
+ transaction.setMemo(utf8Memo);
417
+ assert.strictEqual(transaction.hasMemo(), true);
418
+ assert.strictEqual(transaction.getMemoString(), utf8Memo);
419
+ });
420
+ it('should include memo in transaction JSON when present', function () {
421
+ const memoText = 'Transaction metadata';
422
+ transaction.setMemo(memoText);
423
+ // Mock the FlareJS transaction
424
+ const mockTx = createMockTx();
425
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
426
+ transaction.setTransaction(mockTx);
427
+ transaction.setTransactionType(sdk_core_1.TransactionType.Export);
428
+ const txData = transaction.toJson();
429
+ assert.strictEqual(txData.memo, memoText);
430
+ });
431
+ it('should not include memo in JSON when empty', function () {
432
+ // Mock the FlareJS transaction
433
+ const mockTx = createMockTx();
434
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
435
+ transaction.setTransaction(mockTx);
436
+ transaction.setTransactionType(sdk_core_1.TransactionType.Export);
437
+ const txData = transaction.toJson();
438
+ assert.strictEqual(txData.memo, '');
439
+ });
440
+ it('should validate memo size limits', function () {
441
+ // Test large memo - this should be validated by utils
442
+ const largeMemo = 'x'.repeat(5000); // 5KB memo
443
+ transaction.setMemo(largeMemo);
444
+ assert.strictEqual(transaction.getMemoString(), largeMemo);
445
+ });
446
+ it('should handle special characters in memo', function () {
447
+ const specialMemo = 'Special chars: \n\t\r\0\x01\xff';
448
+ transaction.setMemo(specialMemo);
449
+ assert.strictEqual(transaction.getMemoString(), specialMemo);
450
+ });
451
+ it('should throw error for invalid memo format in setMemoData', function () {
452
+ // This should be tested in utils, but we can check basic behavior
453
+ assert.throws(() => {
454
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
455
+ transaction.setMemoData(123);
456
+ });
457
+ });
458
+ });
459
+ });
460
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNhY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3RyYW5zYWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsaURBQTRDO0FBQzVDLG1EQUFnRjtBQUNoRiwrQ0FBaUM7QUFDakMsOERBQTJEO0FBQzNELHNEQUFtRDtBQU9uRCxRQUFRLENBQUMsa0JBQWtCLEVBQUU7SUFDM0IsSUFBSSxXQUF3QixDQUFDO0lBQzdCLE1BQU0sVUFBVSxHQUFHLGVBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFdEMsa0RBQWtEO0lBQ2xELE1BQU0sWUFBWSxHQUFHLEdBQVcsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQztJQUU3RCxVQUFVLENBQUM7UUFDVCxXQUFXLEdBQUcsSUFBSSx5QkFBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzVDLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGFBQWEsRUFBRTtRQUN0QixFQUFFLENBQUMsc0RBQXNELEVBQUU7WUFDekQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ2hELE1BQU0sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSx1Q0FBdUMsQ0FBQyxDQUFDO1lBQ3ZGLE1BQU0sQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNoRCxNQUFNLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDOUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FBQyxD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TUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUU7Z0JBQ2pCLDhEQUE4RDtnQkFDOUQsV0FBVyxDQUFDLFdBQVcsQ0FBQyxHQUFVLENBQUMsQ0FBQztZQUN0QyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvaW5zIH0gZnJvbSAnQGJpdGdvLWJldGEvc3RhdGljcyc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvblR5cGUsIEludmFsaWRUcmFuc2FjdGlvbkVycm9yIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbiB9IGZyb20gJy4uLy4uLy4uL3NyYy9saWIvdHJhbnNhY3Rpb24nO1xuaW1wb3J0IHsgS2V5UGFpciB9IGZyb20gJy4uLy4uLy4uL3NyYy9saWIva2V5UGFpcic7XG5cbi8vIE1vY2sgdHJhbnNhY3Rpb24gZm9yIHRlc3RpbmdcbmludGVyZmFjZSBNb2NrVHgge1xuICB0ZXN0OiBzdHJpbmc7XG59XG5cbmRlc2NyaWJlKCdGTFJQIFRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICBsZXQgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uO1xuICBjb25zdCBjb2luQ29uZmlnID0gY29pbnMuZ2V0KCd0ZmxycCcpO1xuXG4gIC8vIEhlbHBlciB0byBjcmVhdGUgYSBtb2NrIHRyYW5zYWN0aW9uIGZvciB0ZXN0aW5nXG4gIGNvbnN0IGNyZWF0ZU1vY2tUeCA9ICgpOiBNb2NrVHggPT4gKHsgdGVzdDogJ3RyYW5zYWN0aW9uJyB9KTtcblxuICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICB0cmFuc2FjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbihjb2luQ29uZmlnKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0NvbnN0cnVjdG9yJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgaW5pdGlhbGl6ZSB3aXRoIGNvcnJlY3QgbmV0d29yayBjb25maWd1cmF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLl9hc3NldElkLCAnRkxSJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uX2Jsb2NrY2hhaW5JRCwgJzExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExTHBvWVknKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cmFuc2FjdGlvbi5fbmV0d29ya0lELCAxMTQpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLl90aHJlc2hvbGQsIDIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLl9sb2NrdGltZSwgQmlnSW50KDApKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaW5pdGlhbGl6ZSBlbXB0eSBhcnJheXMgYW5kIGRlZmF1bHQgdmFsdWVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbCh0cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3NlcywgW10pO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbCh0cmFuc2FjdGlvbi5fcmV3YXJkQWRkcmVzc2VzLCBbXSk7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLl91dHhvcywgW10pO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbCh0cmFuc2FjdGlvbi5fZmVlLCB7fSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdUcmFuc2FjdGlvbiBUeXBlIE1hbmFnZW1lbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBzZXQgc3VwcG9ydGVkIHRyYW5zYWN0aW9uIHR5cGVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc3VwcG9ydGVkVHlwZXMgPSBbXG4gICAgICAgIFRyYW5zYWN0aW9uVHlwZS5FeHBvcnQsXG4gICAgICAgIFRyYW5zYWN0aW9uVHlwZS5JbXBvcnQsXG4gICAgICAgIFRyYW5zYWN0aW9uVHlwZS5BZGRWYWxpZGF0b3IsXG4gICAgICAgIFRyYW5zYWN0aW9uVHlwZS5BZGREZWxlZ2F0b3IsXG4gICAgICAgIFRyYW5zYWN0aW9uVHlwZS5BZGRQZXJtaXNzaW9ubGVzc1ZhbGlkYXRvcixcbiAgICAgICAgVHJhbnNhY3Rpb25UeXBlLkFkZFBlcm1pc3Npb25sZXNzRGVsZWdhdG9yLFxuICAgICAgXTtcblxuICAgICAgc3VwcG9ydGVkVHlwZXMuZm9yRWFjaCgodHlwZSkgPT4ge1xuICAgICAgICBhc3NlcnQuZG9lc05vdFRocm93KCgpID0+IHtcbiAgICAgICAgICB0cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvblR5cGUodHlwZSk7XG4gICAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLl90eXBlLCB0eXBlKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIHVuc3VwcG9ydGVkIHRyYW5zYWN0aW9uIHR5cGVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICAgIHRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uVHlwZShUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICB9LCAvVHJhbnNhY3Rpb24gdHlwZSAuKiBpcyBub3Qgc3VwcG9ydGVkLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdHZXR0ZXJzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgZmxhcmVUcmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1vY2tUeCA9IGNyZWF0ZU1vY2tUeCgpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIHRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uKG1vY2tUeCBhcyBhbnkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLmZsYXJlVHJhbnNhY3Rpb24sIG1vY2tUeCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBlbXB0eSBzaWduYXR1cmUgYXJyYXkgd2hlbiBubyBjcmVkZW50aWFscycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uc2lnbmF0dXJlLCBbXSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBlbXB0eSBjcmVkZW50aWFscyBhcnJheScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uY3JlZGVudGlhbHMsIFtdKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBoYXNDcmVkZW50aWFscyB3aGVuIG5vIGNyZWRlbnRpYWxzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLmhhc0NyZWRlbnRpYWxzLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBwbGFjZWhvbGRlciBJRCB3aGVuIG5vIHRyYW5zYWN0aW9uIHNldCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFRoaXMgc2hvdWxkIHRocm93IGVycm9yIHdoZW4gbm8gdHJhbnNhY3Rpb24gaXMgc2V0XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHtcbiAgICAgICAgdHJhbnNhY3Rpb24uaWQ7XG4gICAgICB9LCBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBwbGFjZWhvbGRlciBzaWduYWJsZVBheWxvYWQgd2hlbiBubyB0cmFuc2FjdGlvbiBzZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBUaGlzIHNob3VsZCB0aHJvdyBlcnJvciB3aGVuIG5vIHRyYW5zYWN0aW9uIGlzIHNldFxuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICAgIHZvaWQgdHJhbnNhY3Rpb24uc2lnbmFibGVQYXlsb2FkO1xuICAgICAgfSwgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZm9ybWF0dGVkIGZyb21BZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICB0cmFuc2FjdGlvbi5fZnJvbUFkZHJlc3NlcyA9IFsnYWRkcmVzczEnLCAnYWRkcmVzczInXTtcbiAgICAgIGNvbnN0IGFkZHJlc3NlcyA9IHRyYW5zYWN0aW9uLmZyb21BZGRyZXNzZXM7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGFkZHJlc3NlcywgWydhZGRyZXNzMScsICdhZGRyZXNzMiddKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZvcm1hdHRlZCByZXdhcmRBZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICB0cmFuc2FjdGlvbi5fcmV3YXJkQWRkcmVzc2VzID0gWydyZXdhcmQxJywgJ3Jld2FyZDInXTtcbiAgICAgIGNvbnN0IGFkZHJlc3NlcyA9IHRyYW5zYWN0aW9uLnJld2FyZEFkZHJlc3NlcztcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoYWRkcmVzc2VzLCBbJ3Jld2FyZDEnLCAncmV3YXJkMiddKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uIE91dHB1dHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB0cmFuc2FjdGlvbi5fbm9kZUlEID0gJ3Rlc3Qtbm9kZS1pZCc7XG4gICAgICB0cmFuc2FjdGlvbi5fc3Rha2VBbW91bnQgPSBCaWdJbnQoJzEwMDAwMDAwMDAwMDAwMDAnKTsgLy8gMU0gRkxSXG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBlbXB0eSBvdXRwdXRzIGZvciBFeHBvcnQgdHlwZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uVHlwZShUcmFuc2FjdGlvblR5cGUuRXhwb3J0KTtcbiAgICAgIGNvbnN0IG91dHB1dHMgPSB0cmFuc2FjdGlvbi5vdXRwdXRzO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChvdXRwdXRzLCBbXSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBlbXB0eSBvdXRwdXRzIGZvciBJbXBvcnQgdHlwZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uVHlwZShUcmFuc2FjdGlvblR5cGUuSW1wb3J0KTtcbiAgICAgIGNvbnN0IG91dHB1dHMgPSB0cmFuc2FjdGlvbi5vdXRwdXRzO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChvdXRwdXRzLCBbXSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBzdGFraW5nIG91dHB1dHMgZm9yIEFkZFZhbGlkYXRvciB0eXBlJywgZnVuY3Rpb24gKCkge1xuICAgICAgdHJhbnNhY3Rpb24uc2V0VHJhbnNhY3Rpb25UeXBlKFRyYW5zYWN0aW9uVHlwZS5BZGRWYWxpZGF0b3IpO1xuICAgICAgY29uc3Qgb3V0cHV0cyA9IHRyYW5zYWN0aW9uLm91dHB1dHM7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwob3V0cHV0cy5sZW5ndGgsIDEpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG91dHB1dHNbMF0uYWRkcmVzcywgJ3Rlc3Qtbm9kZS1pZCcpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG91dHB1dHNbMF0udmFsdWUsICcxMDAwMDAwMDAwMDAwMDAwJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBzdGFraW5nIG91dHB1dHMgZm9yIEFkZFBlcm1pc3Npb25sZXNzVmFsaWRhdG9yIHR5cGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICB0cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvblR5cGUoVHJhbnNhY3Rpb25UeXBlLkFkZFBlcm1pc3Npb25sZXNzVmFsaWRhdG9yKTtcbiAgICAgIGNvbnN0IG91dHB1dHMgPSB0cmFuc2FjdGlvbi5vdXRwdXRzO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG91dHB1dHMubGVuZ3RoLCAxKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChvdXRwdXRzWzBdLmFkZHJlc3MsICd0ZXN0LW5vZGUtaWQnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChvdXRwdXRzWzBdLnZhbHVlLCAnMTAwMDAwMDAwMDAwMDAwMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gc3Rha2luZyBvdXRwdXRzIGZvciBBZGREZWxlZ2F0b3IgdHlwZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uVHlwZShUcmFuc2FjdGlvblR5cGUuQWRkRGVsZWdhdG9yKTtcbiAgICAgIGNvbnN0IG91dHB1dHMgPSB0cmFuc2FjdGlvbi5vdXRwdXRzO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKG91dHB1dHMubGVuZ3RoLCAxKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChvdXRwdXRzWzBdLmFkZHJlc3MsICd0ZXN0LW5vZGUtaWQnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChvdXRwdXRzWzBdLnZhbHVlLCAnMTAwMDAwMDAwMDAwMDAwMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gc3Rha2luZyBvdXRwdXRzIGZvciBBZGRQZXJtaXNzaW9ubGVzc0RlbGVnYXRvciB0eXBlJywgZnVuY3Rpb24gKCkge1xuICAgICAgdHJhbnNhY3Rpb24uc2V0VHJhbnNhY3Rpb25UeXBlKFRyYW5zYWN0aW9uVHlwZS5BZGRQZXJtaXNzaW9ubGVzc0RlbGVnYXRvcik7XG4gICAgICBjb25zdCBvdXRwdXRzID0gdHJhbnNhY3Rpb24ub3V0cHV0cztcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChvdXRwdXRzLmxlbmd0aCwgMSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwob3V0cHV0c1swXS5hZGRyZXNzLCAndGVzdC1ub2RlLWlkJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwob3V0cHV0c1swXS52YWx1ZSwgJzEwMDAwMDAwMDAwMDAwMDAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGVtcHR5IG91dHB1dHMgZm9yIHVua25vd24gdHlwZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIERvbid0IHNldCB0eXBlLCBzaG91bGQgZGVmYXVsdCB0byBlbXB0eVxuICAgICAgY29uc3Qgb3V0cHV0cyA9IHRyYW5zYWN0aW9uLm91dHB1dHM7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKG91dHB1dHMsIFtdKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uIElucHV0cycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBpbnB1dHMgZnJvbSBVVFhPcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyYW5zYWN0aW9uLl91dHhvcyA9IFtcbiAgICAgICAge1xuICAgICAgICAgIG91dHB1dElEOiAxLFxuICAgICAgICAgIGFtb3VudDogJzEwMDAwMDAnLFxuICAgICAgICAgIHR4aWQ6ICd0ZXN0LXR4aWQtMScsXG4gICAgICAgICAgb3V0cHV0aWR4OiAnMCcsXG4gICAgICAgICAgdGhyZXNob2xkOiAyLFxuICAgICAgICAgIGFkZHJlc3NlczogWydhZGRyMScsICdhZGRyMiddLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgb3V0cHV0SUQ6IDIsXG4gICAgICAgICAgYW1vdW50OiAnMjAwMDAwMCcsXG4gICAgICAgICAgdHhpZDogJ3Rlc3QtdHhpZC0yJyxcbiAgICAgICAgICBvdXRwdXRpZHg6ICcxJyxcbiAgICAgICAgICB0aHJlc2hvbGQ6IDIsXG4gICAgICAgICAgYWRkcmVzc2VzOiBbJ2FkZHIzJywgJ2FkZHI0J10sXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgICAgdHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXMgPSBbJ2FkZHIxJywgJ2FkZHIyJywgJ2FkZHIzJywgJ2FkZHI0J107XG5cbiAgICAgIGNvbnN0IGlucHV0cyA9IHRyYW5zYWN0aW9uLmlucHV0cztcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChpbnB1dHMubGVuZ3RoLCAyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChpbnB1dHNbMF0uaWQsICd0ZXN0LXR4aWQtMTowJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaW5wdXRzWzBdLnZhbHVlLCAnMTAwMDAwMCcpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGlucHV0c1swXS5hZGRyZXNzLCAnYWRkcjF+YWRkcjJ+YWRkcjN+YWRkcjQnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChpbnB1dHNbMV0uaWQsICd0ZXN0LXR4aWQtMjoxJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaW5wdXRzWzFdLnZhbHVlLCAnMjAwMDAwMCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZW1wdHkgaW5wdXRzIHdoZW4gbm8gVVRYT3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnB1dHMgPSB0cmFuc2FjdGlvbi5pbnB1dHM7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGlucHV0cywgW10pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQ2hhbmdlIE91dHB1dHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZW1wdHkgY2hhbmdlIG91dHB1dHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjaGFuZ2VPdXRwdXRzID0gdHJhbnNhY3Rpb24uY2hhbmdlT3V0cHV0cztcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoY2hhbmdlT3V0cHV0cywgW10pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnRmVlIEhhbmRsaW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIGRlZmF1bHQgZmVlIHdoZW4gbm8gZmVlIHNldCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGZlZSA9IHRyYW5zYWN0aW9uLmZlZTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoZmVlLCB7IGZlZTogJzAnIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY3VzdG9tIGZlZSB3aGVuIHNldCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyYW5zYWN0aW9uLl9mZWUgPSB7IGZlZTogJzEwMDAwMDAnIH07XG4gICAgICBjb25zdCBmZWUgPSB0cmFuc2FjdGlvbi5mZWU7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGZlZSwgeyBmZWU6ICcxMDAwMDAwJyB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NpZ25pbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgbGV0IGtleVBhaXI6IEtleVBhaXI7XG5cbiAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIENyZWF0ZSBhIHRlc3Qga2V5IHBhaXIgd2l0aCBhIHByaXZhdGUga2V5XG4gICAgICBrZXlQYWlyID0gbmV3IEtleVBhaXIoeyBwcnY6ICcwMScucmVwZWF0KDMyKSB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiBubyBwcml2YXRlIGtleScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVtcHR5S2V5UGFpciA9IG5ldyBLZXlQYWlyKCk7XG5cbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdHJhbnNhY3Rpb24uc2lnbihlbXB0eUtleVBhaXIpO1xuICAgICAgfSwgSW52YWxpZFRyYW5zYWN0aW9uRXJyb3IpOyAvLyBXaWxsIHRocm93IEludmFsaWRUcmFuc2FjdGlvbkVycm9yIGZvciBlbXB0eSB0cmFuc2FjdGlvbiBmaXJzdFxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIG5vIHRyYW5zYWN0aW9uIHRvIHNpZ24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cyhhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHRyYW5zYWN0aW9uLnNpZ24oa2V5UGFpcik7XG4gICAgICB9LCBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBGbGFyZUpTIHNpZ25pbmcgbm90IGltcGxlbWVudGVkJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gU2V0IGEgbW9jayB0cmFuc2FjdGlvbiBhbmQgbW9jayBjcmVkZW50aWFscyB0byBwYXNzIHZhbGlkYXRpb25cbiAgICAgIGNvbnN0IG1vY2tUeCA9IGNyZWF0ZU1vY2tUeCgpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIHRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uKG1vY2tUeCBhcyBhbnkpO1xuXG4gICAgICAvLyBNb2NrIGhhc0NyZWRlbnRpYWxzIHRvIHJldHVybiB0cnVlXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodHJhbnNhY3Rpb24sICdoYXNDcmVkZW50aWFscycsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiB0cnVlLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdHJhbnNhY3Rpb24uc2lnbihrZXlQYWlyKTtcbiAgICAgIH0sIC9GbGFyZUpTIHNpZ25pbmcgbm90IHlldCBpbXBsZW1lbnRlZC8pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2VyaWFsaXphdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciB0b0Jyb2FkY2FzdEZvcm1hdCB3aGVuIG5vIHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICAgIHRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICB9LCBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBwbGFjZWhvbGRlciBmb3IgdG9Ccm9hZGNhc3RGb3JtYXQgd2hlbiB0cmFuc2FjdGlvbiBzZXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtb2NrVHggPSBjcmVhdGVNb2NrVHgoKTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICB0cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvbihtb2NrVHggYXMgYW55KTtcbiAgICAgIGNvbnN0IGJyb2FkY2FzdEZvcm1hdCA9IHRyYW5zYWN0aW9uLnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYnJvYWRjYXN0Rm9ybWF0LCAnZmxhcmUtdHgtaGV4LXBsYWNlaG9sZGVyJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciB0b0pzb24gd2hlbiBubyB0cmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4ge1xuICAgICAgICB0cmFuc2FjdGlvbi50b0pzb24oKTtcbiAgICAgIH0sIEludmFsaWRUcmFuc2FjdGlvbkVycm9yKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRyYW5zYWN0aW9uIGRhdGEgZm9yIHRvSnNvbiB3aGVuIHRyYW5zYWN0aW9uIHNldCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1vY2tUeCA9IGNyZWF0ZU1vY2tUeCgpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIHRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uKG1vY2tUeCBhcyBhbnkpO1xuICAgICAgdHJhbnNhY3Rpb24uX2Zyb21BZGRyZXNzZXMgPSBbJ2FkZHIxJ107XG4gICAgICB0cmFuc2FjdGlvbi5fdGhyZXNob2xkID0gMjtcbiAgICAgIHRyYW5zYWN0aW9uLl9sb2NrdGltZSA9IEJpZ0ludCgxMDApO1xuXG4gICAgICBjb25zdCBqc29uRGF0YSA9IHRyYW5zYWN0aW9uLnRvSnNvbigpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGpzb25EYXRhLmlkLCAnZmxhcmUtdHJhbnNhY3Rpb24taWQtcGxhY2Vob2xkZXInKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoanNvbkRhdGEuZnJvbUFkZHJlc3NlcywgWydhZGRyMSddKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChqc29uRGF0YS50aHJlc2hvbGQsIDIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGpzb25EYXRhLmxvY2t0aW1lLCAnMTAwJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdDcm9zcy1jaGFpbiBQcm9wZXJ0aWVzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgaWRlbnRpZnkgRXhwb3J0IGFzIGNyb3NzLWNoYWluIHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgdHJhbnNhY3Rpb24uc2V0VHJhbnNhY3Rpb25UeXBlKFRyYW5zYWN0aW9uVHlwZS5FeHBvcnQpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLmlzVHJhbnNhY3Rpb25Gb3JDQ2hhaW4sIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpZGVudGlmeSBJbXBvcnQgYXMgY3Jvc3MtY2hhaW4gdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICB0cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvblR5cGUoVHJhbnNhY3Rpb25UeXBlLkltcG9ydCk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uaXNUcmFuc2FjdGlvbkZvckNDaGFpbiwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGlkZW50aWZ5IEFkZFZhbGlkYXRvciBhcyBub24tY3Jvc3MtY2hhaW4gdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICB0cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvblR5cGUoVHJhbnNhY3Rpb25UeXBlLkFkZFZhbGlkYXRvcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uaXNUcmFuc2FjdGlvbkZvckNDaGFpbiwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVHJhbnNhY3Rpb24gRXhwbGFuYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtb2NrVHggPSBjcmVhdGVNb2NrVHgoKTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICB0cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvbihtb2NrVHggYXMgYW55KTtcbiAgICAgIHRyYW5zYWN0aW9uLl9mcm9tQWRkcmVzc2VzID0gWyd0ZXN0LWFkZHJlc3MnXTtcbiAgICAgIHRyYW5zYWN0aW9uLl9mZWUgPSB7IGZlZTogJzEwMDAwMDAnIH07XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4cGxhaW4gYSBiYXNpYyB0cmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uVHlwZShUcmFuc2FjdGlvblR5cGUuRXhwb3J0KTtcblxuICAgICAgY29uc3QgZXhwbGFuYXRpb24gPSB0cmFuc2FjdGlvbi5leHBsYWluVHJhbnNhY3Rpb24oKTtcbiAgICAgIGFzc2VydC5vayhleHBsYW5hdGlvbi5kaXNwbGF5T3JkZXIpO1xuICAgICAgYXNzZXJ0Lm9rKEFycmF5LmlzQXJyYXkoZXhwbGFuYXRpb24uZGlzcGxheU9yZGVyKSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXhwbGFuYXRpb24uaWQsICdmbGFyZS10cmFuc2FjdGlvbi1pZC1wbGFjZWhvbGRlcicpO1xuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChleHBsYW5hdGlvbi5mZWUsIHsgZmVlOiAnMTAwMDAwMCcgfSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXhwbGFuYXRpb24udHlwZSwgVHJhbnNhY3Rpb25UeXBlLkV4cG9ydCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGluY2x1ZGUgcmV3YXJkIGFkZHJlc3NlcyBmb3Igc3Rha2luZyB0cmFuc2FjdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICB0cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvblR5cGUoVHJhbnNhY3Rpb25UeXBlLkFkZFZhbGlkYXRvcik7XG4gICAgICB0cmFuc2FjdGlvbi5fcmV3YXJkQWRkcmVzc2VzID0gWydyZXdhcmQtYWRkci0xJ107XG5cbiAgICAgIGNvbnN0IGV4cGxhbmF0aW9uID0gdHJhbnNhY3Rpb24uZXhwbGFpblRyYW5zYWN0aW9uKCk7XG4gICAgICBhc3NlcnQub2soZXhwbGFuYXRpb24uZGlzcGxheU9yZGVyKTtcbiAgICAgIGFzc2VydC5vayhleHBsYW5hdGlvbi5kaXNwbGF5T3JkZXIuaW5jbHVkZXMoJ3Jld2FyZEFkZHJlc3NlcycpKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoZXhwbGFuYXRpb24ucmV3YXJkQWRkcmVzc2VzLCBbJ3Jld2FyZC1hZGRyLTEnXSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGluY2x1ZGUgY3Jvc3MtY2hhaW4gaW5mb3JtYXRpb24gZm9yIGV4cG9ydC9pbXBvcnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICB0cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvblR5cGUoVHJhbnNhY3Rpb25UeXBlLkV4cG9ydCk7XG5cbiAgICAgIGNvbnN0IGV4cGxhbmF0aW9uID0gdHJhbnNhY3Rpb24uZXhwbGFpblRyYW5zYWN0aW9uKCk7XG4gICAgICBhc3NlcnQub2soZXhwbGFuYXRpb24uZGlzcGxheU9yZGVyKTtcbiAgICAgIGFzc2VydC5vayhleHBsYW5hdGlvbi5kaXNwbGF5T3JkZXIuaW5jbHVkZXMoJ3NvdXJjZUNoYWluJykpO1xuICAgICAgYXNzZXJ0Lm9rKGV4cGxhbmF0aW9uLmRpc3BsYXlPcmRlci5pbmNsdWRlcygnZGVzdGluYXRpb25DaGFpbicpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY2FsY3VsYXRlIG91dHB1dCBhbW91bnRzIGNvcnJlY3RseScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyYW5zYWN0aW9uLl9ub2RlSUQgPSAndGVzdC1ub2RlJztcbiAgICAgIHRyYW5zYWN0aW9uLl9zdGFrZUFtb3VudCA9IEJpZ0ludCgnNTAwMDAwMDAwMDAwMDAwMCcpO1xuICAgICAgdHJhbnNhY3Rpb24uc2V0VHJhbnNhY3Rpb25UeXBlKFRyYW5zYWN0aW9uVHlwZS5BZGRWYWxpZGF0b3IpO1xuXG4gICAgICBjb25zdCBleHBsYW5hdGlvbiA9IHRyYW5zYWN0aW9uLmV4cGxhaW5UcmFuc2FjdGlvbigpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGV4cGxhbmF0aW9uLm91dHB1dEFtb3VudCwgJzUwMDAwMDAwMDAwMDAwMDAnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChleHBsYW5hdGlvbi5jaGFuZ2VBbW91bnQsICcwJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdTaWduYXR1cmUgQ3JlYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgc2lnbmF0dXJlIHBsYWNlaG9sZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbW9ja1ByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbSgnMTIzNDU2Nzg5MGFiY2RlZjEyMzQ1Njc4OTBhYmNkZWYxMjM0NTY3ODkwYWJjZGVmMTIzNDU2Nzg5MGFiY2RlZicsICdoZXgnKTtcbiAgICAgIGNvbnN0IG1vY2tUeCA9IGNyZWF0ZU1vY2tUeCgpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIHRyYW5zYWN0aW9uLnNldFRyYW5zYWN0aW9uKG1vY2tUeCBhcyBhbnkpO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB0cmFuc2FjdGlvbi5jcmVhdGVTaWduYXR1cmUobW9ja1ByaXZhdGVLZXkpO1xuICAgICAgYXNzZXJ0Lm9rKHR5cGVvZiBzaWduYXR1cmUgPT09ICdzdHJpbmcnKTtcbiAgICAgIGFzc2VydC5vayhzaWduYXR1cmUubGVuZ3RoID4gMCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdWYWxpZGF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgYWxsb3cgc2lnbmluZyB3aXRoIHZhbGlkIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGtleVBhaXIgPSBuZXcgS2V5UGFpcih7IHBydjogJzAxJy5yZXBlYXQoMzIpIH0pO1xuXG4gICAgICBjb25zdCBjYW5TaWduID0gdHJhbnNhY3Rpb24uY2FuU2lnbih7IGtleToga2V5UGFpciB9KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChjYW5TaWduLCB0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uIFNldHRpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBzZXQgdHJhbnNhY3Rpb24gY29ycmVjdGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbW9ja1R4ID0gY3JlYXRlTW9ja1R4KCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgdHJhbnNhY3Rpb24uc2V0VHJhbnNhY3Rpb24obW9ja1R4IGFzIGFueSk7XG4gICAgICAvLyBDYW4ndCBkaXJlY3RseSBhY2Nlc3MgX2ZsYXJlVHJhbnNhY3Rpb24gKHByb3RlY3RlZCksIGJ1dCBjYW4gdGVzdCB2aWEgZ2V0dGVyXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uZmxhcmVUcmFuc2FjdGlvbiwgbW9ja1R4KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0hleCBDb252ZXJzaW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY29udmVydCBieXRlIGFycmF5IHRvIGhleCBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBieXRlQXJyYXkgPSBuZXcgVWludDhBcnJheShbMHgwMSwgMHgyMywgMHhhYiwgMHhjZF0pO1xuICAgICAgY29uc3QgaGV4U3RyaW5nID0gdHJhbnNhY3Rpb24udG9IZXhTdHJpbmcoYnl0ZUFycmF5KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChoZXhTdHJpbmcsICcwMTIzYWJjZCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgZW1wdHkgYnl0ZSBhcnJheScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ5dGVBcnJheSA9IG5ldyBVaW50OEFycmF5KFtdKTtcbiAgICAgIGNvbnN0IGhleFN0cmluZyA9IHRyYW5zYWN0aW9uLnRvSGV4U3RyaW5nKGJ5dGVBcnJheSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaGV4U3RyaW5nLCAnJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdNZW1vIEZ1bmN0aW9uYWxpdHknLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBpbml0aWFsaXplIHdpdGggZW1wdHkgbWVtbycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cmFuc2FjdGlvbi5oYXNNZW1vKCksIGZhbHNlKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cmFuc2FjdGlvbi5nZXRNZW1vU3RyaW5nKCksICcnKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uZ2V0TWVtb0J5dGVzKCksIG5ldyBVaW50OEFycmF5KCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQgbWVtbyBmcm9tIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lbW9UZXh0ID0gJ1Rlc3QgdHJhbnNhY3Rpb24gbWVtbyc7XG4gICAgICB0cmFuc2FjdGlvbi5zZXRNZW1vKG1lbW9UZXh0KTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLmhhc01lbW8oKSwgdHJ1ZSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uZ2V0TWVtb1N0cmluZygpLCBtZW1vVGV4dCk7XG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLmdldE1lbW9CeXRlcygpLCBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobWVtb1RleHQpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2V0IG1lbW8gZnJvbSBKU09OIG9iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lbW9PYmogPSB7IHVzZXI6ICdhbGljZScsIGFtb3VudDogMTAwMCB9O1xuICAgICAgdHJhbnNhY3Rpb24uc2V0TWVtb0RhdGEobWVtb09iaik7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cmFuc2FjdGlvbi5oYXNNZW1vKCksIHRydWUpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLmdldE1lbW9TdHJpbmcoKSwgSlNPTi5zdHJpbmdpZnkobWVtb09iaikpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQgbWVtbyBmcm9tIGJ5dGVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVtb0J5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCdCaW5hcnkgbWVtbyBkYXRhJyk7XG4gICAgICB0cmFuc2FjdGlvbi5zZXRNZW1vRGF0YShtZW1vQnl0ZXMpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uaGFzTWVtbygpLCB0cnVlKTtcbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uZ2V0TWVtb0J5dGVzKCksIG1lbW9CeXRlcyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uZ2V0TWVtb1N0cmluZygpLCAnQmluYXJ5IG1lbW8gZGF0YScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgZW1wdHkgc3RyaW5nIG1lbW8nLCBmdW5jdGlvbiAoKSB7XG4gICAgICB0cmFuc2FjdGlvbi5zZXRNZW1vKCcnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cmFuc2FjdGlvbi5oYXNNZW1vKCksIGZhbHNlKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cmFuc2FjdGlvbi5nZXRNZW1vU3RyaW5nKCksICcnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIFVURi04IG1lbW8nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB1dGY4TWVtbyA9ICdIZWxsbyDkuJbnlYwg8J+MjSBGbGFyZSEnO1xuICAgICAgdHJhbnNhY3Rpb24uc2V0TWVtbyh1dGY4TWVtbyk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0cmFuc2FjdGlvbi5oYXNNZW1vKCksIHRydWUpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLmdldE1lbW9TdHJpbmcoKSwgdXRmOE1lbW8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpbmNsdWRlIG1lbW8gaW4gdHJhbnNhY3Rpb24gSlNPTiB3aGVuIHByZXNlbnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZW1vVGV4dCA9ICdUcmFuc2FjdGlvbiBtZXRhZGF0YSc7XG4gICAgICB0cmFuc2FjdGlvbi5zZXRNZW1vKG1lbW9UZXh0KTtcblxuICAgICAgLy8gTW9jayB0aGUgRmxhcmVKUyB0cmFuc2FjdGlvblxuICAgICAgY29uc3QgbW9ja1R4ID0gY3JlYXRlTW9ja1R4KCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgdHJhbnNhY3Rpb24uc2V0VHJhbnNhY3Rpb24obW9ja1R4IGFzIGFueSk7XG4gICAgICB0cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvblR5cGUoVHJhbnNhY3Rpb25UeXBlLkV4cG9ydCk7XG5cbiAgICAgIGNvbnN0IHR4RGF0YSA9IHRyYW5zYWN0aW9uLnRvSnNvbigpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR4RGF0YS5tZW1vLCBtZW1vVGV4dCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBpbmNsdWRlIG1lbW8gaW4gSlNPTiB3aGVuIGVtcHR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gTW9jayB0aGUgRmxhcmVKUyB0cmFuc2FjdGlvblxuICAgICAgY29uc3QgbW9ja1R4ID0gY3JlYXRlTW9ja1R4KCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgdHJhbnNhY3Rpb24uc2V0VHJhbnNhY3Rpb24obW9ja1R4IGFzIGFueSk7XG4gICAgICB0cmFuc2FjdGlvbi5zZXRUcmFuc2FjdGlvblR5cGUoVHJhbnNhY3Rpb25UeXBlLkV4cG9ydCk7XG5cbiAgICAgIGNvbnN0IHR4RGF0YSA9IHRyYW5zYWN0aW9uLnRvSnNvbigpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR4RGF0YS5tZW1vLCAnJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIG1lbW8gc2l6ZSBsaW1pdHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBUZXN0IGxhcmdlIG1lbW8gLSB0aGlzIHNob3VsZCBiZSB2YWxpZGF0ZWQgYnkgdXRpbHNcbiAgICAgIGNvbnN0IGxhcmdlTWVtbyA9ICd4Jy5yZXBlYXQoNTAwMCk7IC8vIDVLQiBtZW1vXG4gICAgICB0cmFuc2FjdGlvbi5zZXRNZW1vKGxhcmdlTWVtbyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHJhbnNhY3Rpb24uZ2V0TWVtb1N0cmluZygpLCBsYXJnZU1lbW8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgc3BlY2lhbCBjaGFyYWN0ZXJzIGluIG1lbW8nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzcGVjaWFsTWVtbyA9ICdTcGVjaWFsIGNoYXJzOiBcXG5cXHRcXHJcXDBcXHgwMVxceGZmJztcbiAgICAgIHRyYW5zYWN0aW9uLnNldE1lbW8oc3BlY2lhbE1lbW8pO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHRyYW5zYWN0aW9uLmdldE1lbW9TdHJpbmcoKSwgc3BlY2lhbE1lbW8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaW52YWxpZCBtZW1vIGZvcm1hdCBpbiBzZXRNZW1vRGF0YScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIFRoaXMgc2hvdWxkIGJlIHRlc3RlZCBpbiB1dGlscywgYnV0IHdlIGNhbiBjaGVjayBiYXNpYyBiZWhhdmlvclxuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIHRyYW5zYWN0aW9uLnNldE1lbW9EYXRhKDEyMyBhcyBhbnkpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=