@bitgo-beta/sdk-coin-flrp 1.0.1-beta.294 → 1.0.1-beta.296

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.
@@ -36,16 +36,374 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const statics_1 = require("@bitgo-beta/statics");
37
37
  const assert = __importStar(require("assert"));
38
38
  const utils_1 = require("../../../src/lib/utils");
39
+ const account_1 = require("../../resources/account");
40
+ const secp256k1_1 = require("@bitgo-beta/secp256k1");
41
+ const exportInC_1 = require("../../resources/transactionData/exportInC");
42
+ const importInP_1 = require("../../resources/transactionData/importInP");
39
43
  describe('Utils', function () {
40
44
  let utils;
45
+ const network = statics_1.coins.get('flrp').network;
41
46
  beforeEach(function () {
42
47
  utils = new utils_1.Utils();
43
48
  });
49
+ describe('includeIn', function () {
50
+ it('should return true when all wallet addresses are in UTXO output addresses', function () {
51
+ const walletAddresses = [exportInC_1.EXPORT_IN_C.pAddresses[0], exportInC_1.EXPORT_IN_C.pAddresses[1]];
52
+ const utxoOutputAddresses = [...exportInC_1.EXPORT_IN_C.pAddresses];
53
+ assert.strictEqual(utils.includeIn(walletAddresses, utxoOutputAddresses), true);
54
+ });
55
+ it('should return false when some wallet addresses are not in UTXO output addresses', function () {
56
+ const walletAddresses = [exportInC_1.EXPORT_IN_C.pAddresses[0], account_1.ACCOUNT_3.address];
57
+ const utxoOutputAddresses = [exportInC_1.EXPORT_IN_C.pAddresses[0], exportInC_1.EXPORT_IN_C.pAddresses[1]];
58
+ assert.strictEqual(utils.includeIn(walletAddresses, utxoOutputAddresses), false);
59
+ });
60
+ it('should return true for empty wallet addresses', function () {
61
+ const walletAddresses = [];
62
+ const utxoOutputAddresses = [exportInC_1.EXPORT_IN_C.pAddresses[0]];
63
+ assert.strictEqual(utils.includeIn(walletAddresses, utxoOutputAddresses), true);
64
+ });
65
+ });
66
+ describe('isValidAddress', function () {
67
+ it('should return true for valid mainnet P-chain address', function () {
68
+ assert.strictEqual(utils.isValidAddress(account_1.SEED_ACCOUNT.addressMainnet), true);
69
+ });
70
+ it('should return true for valid testnet P-chain address', function () {
71
+ assert.strictEqual(utils.isValidAddress(account_1.SEED_ACCOUNT.addressTestnet), true);
72
+ });
73
+ it('should return true for valid NodeID address', function () {
74
+ assert.strictEqual(utils.isValidAddress('NodeID-abc123xyz'), true);
75
+ });
76
+ it('should return true for array of valid addresses', function () {
77
+ assert.strictEqual(utils.isValidAddress(exportInC_1.EXPORT_IN_C.pAddresses), true);
78
+ });
79
+ it('should return true for tilde-separated addresses', function () {
80
+ const combined = exportInC_1.EXPORT_IN_C.pAddresses.join('~');
81
+ assert.strictEqual(utils.isValidAddress(combined), true);
82
+ });
83
+ it('should return false for invalid address format', function () {
84
+ assert.strictEqual(utils.isValidAddress('invalid'), false);
85
+ });
86
+ it('should return false for address without prefix', function () {
87
+ assert.strictEqual(utils.isValidAddress('flare1abc123'), false);
88
+ });
89
+ });
90
+ describe('isValidBlockId', function () {
91
+ it('should return true for valid 32-byte hex block ID', function () {
92
+ assert.strictEqual(utils.isValidBlockId(account_1.SEED_ACCOUNT.privateKey), true); // 64 hex chars = 32 bytes
93
+ });
94
+ it('should return false for invalid length block ID', function () {
95
+ assert.strictEqual(utils.isValidBlockId(account_1.INVALID_SHORT_KEYPAIR_KEY), false);
96
+ });
97
+ it('should return false for empty block ID', function () {
98
+ assert.strictEqual(utils.isValidBlockId(''), false);
99
+ });
100
+ });
101
+ describe('isValidPublicKey', function () {
102
+ it('should return true for valid compressed public key starting with 03', function () {
103
+ assert.strictEqual(utils.isValidPublicKey(account_1.SEED_ACCOUNT.publicKey), true);
104
+ });
105
+ it('should return true for valid compressed public key starting with 02', function () {
106
+ assert.strictEqual(utils.isValidPublicKey(account_1.ACCOUNT_1.publicKey), true);
107
+ });
108
+ it('should return true for another valid compressed public key', function () {
109
+ assert.strictEqual(utils.isValidPublicKey(account_1.ACCOUNT_2.publicKey), true);
110
+ });
111
+ it('should return true for valid xpub', function () {
112
+ assert.strictEqual(utils.isValidPublicKey(account_1.SEED_ACCOUNT.xPublicKey), true);
113
+ });
114
+ it('should return true for ACCOUNT_1 xpub', function () {
115
+ assert.strictEqual(utils.isValidPublicKey(account_1.ACCOUNT_1.xPublicKey), true);
116
+ });
117
+ it('should return false for invalid short public key', function () {
118
+ assert.strictEqual(utils.isValidPublicKey(account_1.INVALID_SHORT_KEYPAIR_KEY), false);
119
+ });
120
+ it('should return false for compressed key with wrong prefix', function () {
121
+ const invalidKey = '05' + account_1.SEED_ACCOUNT.privateKey;
122
+ assert.strictEqual(utils.isValidPublicKey(invalidKey), false);
123
+ });
124
+ it('should return false for non-hex public key', function () {
125
+ const invalidKey = 'zz' + account_1.SEED_ACCOUNT.privateKey;
126
+ assert.strictEqual(utils.isValidPublicKey(invalidKey), false);
127
+ });
128
+ });
129
+ describe('isValidPrivateKey', function () {
130
+ it('should return true for valid 64-char hex private key', function () {
131
+ assert.strictEqual(utils.isValidPrivateKey(account_1.SEED_ACCOUNT.privateKey), true);
132
+ });
133
+ it('should return true for ACCOUNT_1 private key', function () {
134
+ assert.strictEqual(utils.isValidPrivateKey(account_1.ACCOUNT_1.privateKey), true);
135
+ });
136
+ it('should return true for ACCOUNT_2 private key', function () {
137
+ assert.strictEqual(utils.isValidPrivateKey(account_1.ACCOUNT_2.privateKey), true);
138
+ });
139
+ it('should return true for valid xprv', function () {
140
+ assert.strictEqual(utils.isValidPrivateKey(account_1.SEED_ACCOUNT.xPrivateKey), true);
141
+ });
142
+ it('should return true for 66-char private key ending with 01', function () {
143
+ const extendedKey = account_1.SEED_ACCOUNT.privateKey + '01';
144
+ assert.strictEqual(utils.isValidPrivateKey(extendedKey), true);
145
+ });
146
+ it('should return false for 66-char private key not ending with 01', function () {
147
+ assert.strictEqual(utils.isValidPrivateKey(account_1.INVALID_LONG_KEYPAIR_PRV), false);
148
+ });
149
+ it('should return false for invalid short private key', function () {
150
+ assert.strictEqual(utils.isValidPrivateKey(account_1.INVALID_SHORT_KEYPAIR_KEY), false);
151
+ });
152
+ it('should return false for non-hex private key', function () {
153
+ const invalidKey = 'zz' + account_1.SEED_ACCOUNT.privateKey.slice(2);
154
+ assert.strictEqual(utils.isValidPrivateKey(invalidKey), false);
155
+ });
156
+ });
157
+ describe('allHexChars', function () {
158
+ it('should return true for valid private key hex', function () {
159
+ assert.strictEqual(utils.allHexChars(account_1.SEED_ACCOUNT.privateKey), true);
160
+ });
161
+ it('should return true for valid public key hex', function () {
162
+ assert.strictEqual(utils.allHexChars(account_1.SEED_ACCOUNT.publicKey), true);
163
+ });
164
+ it('should return true for hex string with 0x prefix', function () {
165
+ assert.strictEqual(utils.allHexChars(exportInC_1.EXPORT_IN_C.cHexAddress), true);
166
+ });
167
+ it('should return true for valid signature hex', function () {
168
+ assert.strictEqual(utils.allHexChars(account_1.SEED_ACCOUNT.signature), true);
169
+ });
170
+ it('should return false for non-hex characters', function () {
171
+ assert.strictEqual(utils.allHexChars('ghijkl'), false);
172
+ });
173
+ it('should return false for empty string', function () {
174
+ assert.strictEqual(utils.allHexChars(''), false);
175
+ });
176
+ });
177
+ describe('createSignature and verifySignature', function () {
178
+ it('should create a valid 65-byte signature', function () {
179
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
180
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
181
+ const signature = utils.createSignature(network, message, privateKey);
182
+ assert.ok(signature instanceof Buffer);
183
+ assert.strictEqual(signature.length, 65);
184
+ });
185
+ it('should verify a valid signature', function () {
186
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
187
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
188
+ const publicKey = Buffer.from(account_1.SEED_ACCOUNT.publicKey, 'hex');
189
+ const signature = utils.createSignature(network, message, privateKey);
190
+ const sigOnly = signature.slice(0, 64);
191
+ const isValid = utils.verifySignature(network, message, sigOnly, publicKey);
192
+ assert.strictEqual(isValid, true);
193
+ });
194
+ it('should return false for invalid signature', function () {
195
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
196
+ const publicKey = Buffer.from(account_1.SEED_ACCOUNT.publicKey, 'hex');
197
+ const invalidSignature = Buffer.alloc(64);
198
+ const isValid = utils.verifySignature(network, message, invalidSignature, publicKey);
199
+ assert.strictEqual(isValid, false);
200
+ });
201
+ it('should create signature with ACCOUNT_1 keys', function () {
202
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
203
+ const privateKey = Buffer.from(account_1.ACCOUNT_1.privateKey, 'hex');
204
+ const signature = utils.createSignature(network, message, privateKey);
205
+ assert.ok(signature instanceof Buffer);
206
+ assert.strictEqual(signature.length, 65);
207
+ });
208
+ });
209
+ describe('createNewSig', function () {
210
+ it('should create a signature from valid signature hex string', function () {
211
+ const sig = utils.createNewSig(account_1.SEED_ACCOUNT.signature);
212
+ assert.ok(sig);
213
+ });
214
+ it('should create a signature from export signature hex', function () {
215
+ const sigHex = utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.signature[0]);
216
+ const sig = utils.createNewSig(sigHex);
217
+ assert.ok(sig);
218
+ });
219
+ it('should pad short hex strings', function () {
220
+ const sigHex = account_1.INVALID_SHORT_KEYPAIR_KEY;
221
+ const sig = utils.createNewSig(sigHex);
222
+ assert.ok(sig);
223
+ });
224
+ });
225
+ describe('createEmptySigWithAddress and getAddressFromEmptySig', function () {
226
+ it('should create empty signature with embedded C-chain address', function () {
227
+ const addressHex = utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.cHexAddress);
228
+ const sig = utils.createEmptySigWithAddress(addressHex);
229
+ assert.ok(sig);
230
+ });
231
+ it('should extract embedded address from empty signature', function () {
232
+ const addressHex = utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.cHexAddress).toLowerCase();
233
+ const sig = utils.createEmptySigWithAddress(addressHex);
234
+ // Get signature bytes and convert to hex
235
+ const sigBytes = sig.toBytes();
236
+ const sigHex = Buffer.from(sigBytes).toString('hex');
237
+ const extractedAddress = utils.getAddressFromEmptySig(sigHex);
238
+ assert.strictEqual(extractedAddress, addressHex);
239
+ });
240
+ it('should handle 0x prefixed address', function () {
241
+ const sig = utils.createEmptySigWithAddress(exportInC_1.EXPORT_IN_C.cHexAddress);
242
+ assert.ok(sig);
243
+ });
244
+ it('should return empty string for short signature', function () {
245
+ const shortSig = account_1.SEED_ACCOUNT.privateKey; // 64 chars, less than 130
246
+ assert.strictEqual(utils.getAddressFromEmptySig(shortSig), '');
247
+ });
248
+ });
249
+ describe('sha256', function () {
250
+ it('should compute SHA256 hash of message', function () {
251
+ const data = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
252
+ const hash = utils.sha256(data);
253
+ assert.ok(hash instanceof Buffer);
254
+ assert.strictEqual(hash.length, 32);
255
+ });
256
+ it('should produce consistent hash for same input', function () {
257
+ const data = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
258
+ const hash1 = utils.sha256(data);
259
+ const hash2 = utils.sha256(data);
260
+ assert.deepStrictEqual(hash1, hash2);
261
+ });
262
+ it('should produce different hash for different input', function () {
263
+ const data1 = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
264
+ const data2 = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'utf8');
265
+ const hash1 = utils.sha256(data1);
266
+ const hash2 = utils.sha256(data2);
267
+ assert.notDeepStrictEqual(hash1, hash2);
268
+ });
269
+ });
270
+ describe('validateRawTransaction', function () {
271
+ it('should not throw for valid unsigned hex transaction', function () {
272
+ const rawTx = utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.unsignedHex);
273
+ assert.doesNotThrow(() => utils.validateRawTransaction(rawTx));
274
+ });
275
+ it('should not throw for valid signed hex transaction', function () {
276
+ const rawTx = utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.signedHex);
277
+ assert.doesNotThrow(() => utils.validateRawTransaction(rawTx));
278
+ });
279
+ it('should not throw for import transaction hex', function () {
280
+ const rawTx = utils.removeHexPrefix(importInP_1.IMPORT_IN_P.unsignedHex);
281
+ assert.doesNotThrow(() => utils.validateRawTransaction(rawTx));
282
+ });
283
+ it('should throw for empty transaction', function () {
284
+ assert.throws(() => utils.validateRawTransaction(''), /Raw transaction is empty/);
285
+ });
286
+ it('should throw for non-hex transaction', function () {
287
+ assert.throws(() => utils.validateRawTransaction('xyz123'), /Raw transaction is not hex string/);
288
+ });
289
+ });
290
+ describe('removeHexPrefix', function () {
291
+ it('should remove 0x prefix from C-chain address', function () {
292
+ assert.strictEqual(utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.cHexAddress), exportInC_1.EXPORT_IN_C.cHexAddress.slice(2));
293
+ });
294
+ it('should remove 0x prefix from unsigned hex', function () {
295
+ assert.strictEqual(utils.removeHexPrefix(exportInC_1.EXPORT_IN_C.unsignedHex), exportInC_1.EXPORT_IN_C.unsignedHex.slice(2));
296
+ });
297
+ it('should return string unchanged if no prefix', function () {
298
+ assert.strictEqual(utils.removeHexPrefix(account_1.SEED_ACCOUNT.privateKey), account_1.SEED_ACCOUNT.privateKey);
299
+ });
300
+ it('should handle empty string', function () {
301
+ assert.strictEqual(utils.removeHexPrefix(''), '');
302
+ });
303
+ });
304
+ describe('outputidxNumberToBuffer and outputidxBufferToNumber', function () {
305
+ it('should convert output index to buffer and back', function () {
306
+ const outputIdx = importInP_1.IMPORT_IN_P.outputs[0].outputidx;
307
+ const buffer = utils.outputidxNumberToBuffer(outputIdx);
308
+ const result = utils.outputidxBufferToNumber(buffer);
309
+ assert.strictEqual(result, outputIdx);
310
+ });
311
+ it('should handle nonce value', function () {
312
+ const nonceStr = exportInC_1.EXPORT_IN_C.nonce.toString();
313
+ const buffer = utils.outputidxNumberToBuffer(nonceStr);
314
+ const result = utils.outputidxBufferToNumber(buffer);
315
+ assert.strictEqual(result, nonceStr);
316
+ });
317
+ it('should produce 4-byte buffer', function () {
318
+ const buffer = utils.outputidxNumberToBuffer('255');
319
+ assert.strictEqual(buffer.length, 4);
320
+ });
321
+ });
322
+ describe('addressToString', function () {
323
+ it('should convert address buffer to mainnet bech32 string', function () {
324
+ const address = account_1.SEED_ACCOUNT.addressMainnet;
325
+ const addressBuffer = utils.parseAddress(address);
326
+ const result = utils.addressToString('flare', 'P', addressBuffer);
327
+ assert.ok(result.startsWith('P-'));
328
+ assert.ok(result.includes('flare'));
329
+ });
330
+ it('should convert address buffer to testnet bech32 string', function () {
331
+ const address = account_1.SEED_ACCOUNT.addressTestnet;
332
+ const addressBuffer = utils.parseAddress(address);
333
+ const result = utils.addressToString('costwo', 'P', addressBuffer);
334
+ assert.ok(result.startsWith('P-'));
335
+ assert.ok(result.includes('costwo'));
336
+ });
337
+ });
338
+ describe('cb58Encode and cb58Decode', function () {
339
+ it('should encode and decode target chain ID correctly', function () {
340
+ const encoded = exportInC_1.EXPORT_IN_C.targetChainId;
341
+ const decoded = utils.cb58Decode(encoded);
342
+ const reEncoded = utils.cb58Encode(decoded);
343
+ assert.strictEqual(reEncoded, encoded);
344
+ });
345
+ it('should encode and decode source chain ID correctly', function () {
346
+ const encoded = importInP_1.IMPORT_IN_P.sourceChainId;
347
+ const decoded = utils.cb58Decode(encoded);
348
+ const reEncoded = utils.cb58Encode(decoded);
349
+ assert.strictEqual(reEncoded, encoded);
350
+ });
351
+ it('should throw for invalid checksum', function () {
352
+ assert.throws(() => utils.cb58Decode('1111111111111'), /Invalid checksum/);
353
+ });
354
+ });
355
+ describe('parseAddress and stringToAddress', function () {
356
+ it('should parse hex address with 0x prefix', function () {
357
+ const buffer = utils.parseAddress(exportInC_1.EXPORT_IN_C.cHexAddress);
358
+ assert.ok(buffer instanceof Buffer);
359
+ assert.strictEqual(buffer.length, 20);
360
+ });
361
+ it('should parse raw hex address from outputs', function () {
362
+ const address = importInP_1.IMPORT_IN_P.outputs[0].addresses[0];
363
+ const buffer = utils.parseAddress(address);
364
+ assert.ok(buffer instanceof Buffer);
365
+ assert.strictEqual(buffer.length, 20);
366
+ });
367
+ it('should parse mainnet bech32 address', function () {
368
+ const buffer = utils.parseAddress(account_1.SEED_ACCOUNT.addressMainnet);
369
+ assert.ok(buffer instanceof Buffer);
370
+ assert.strictEqual(buffer.length, 20);
371
+ });
372
+ it('should parse testnet bech32 address', function () {
373
+ const buffer = utils.parseAddress(account_1.SEED_ACCOUNT.addressTestnet);
374
+ assert.ok(buffer instanceof Buffer);
375
+ assert.strictEqual(buffer.length, 20);
376
+ });
377
+ it('should parse P-chain addresses from export data', function () {
378
+ exportInC_1.EXPORT_IN_C.pAddresses.forEach((address) => {
379
+ const buffer = utils.parseAddress(address);
380
+ assert.ok(buffer instanceof Buffer);
381
+ assert.strictEqual(buffer.length, 20);
382
+ });
383
+ });
384
+ it('should throw for address without dash separator', function () {
385
+ assert.throws(() => utils.parseAddress('flare1abc'), /Valid address should include -/);
386
+ });
387
+ it('should throw for invalid HRP', function () {
388
+ assert.throws(() => utils.parseAddress('P-invalid1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq5evzmy'), /Invalid HRP/);
389
+ });
390
+ });
391
+ describe('flareIdString', function () {
392
+ it('should create Id from private key hex string', function () {
393
+ const id = utils.flareIdString(account_1.SEED_ACCOUNT.privateKey);
394
+ assert.ok(id);
395
+ });
396
+ it('should create Id from asset ID hex', function () {
397
+ // Asset ID is typically 32 bytes (64 hex chars)
398
+ const assetIdHex = account_1.SEED_ACCOUNT.privateKey; // Using as a 32-byte hex
399
+ const id = utils.flareIdString(assetIdHex);
400
+ assert.ok(id);
401
+ });
402
+ });
44
403
  describe('recoverySignature', function () {
45
404
  it('should recover public key from valid signature', function () {
46
- const network = statics_1.coins.get('flrp').network;
47
- const message = Buffer.from('hello world', 'utf8');
48
- const privateKey = Buffer.from('0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', 'hex');
405
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
406
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
49
407
  // Create signature using the same private key
50
408
  const signature = utils.createSignature(network, message, privateKey);
51
409
  // Recover public key
@@ -54,39 +412,42 @@ describe('Utils', function () {
54
412
  assert.strictEqual(recoveredPubKey.length, 33); // Should be compressed public key (33 bytes)
55
413
  });
56
414
  it('should recover same public key for same message and signature', function () {
57
- const network = statics_1.coins.get('flrp').network;
58
- const message = Buffer.from('hello world', 'utf8');
59
- const privateKey = Buffer.from('0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', 'hex');
415
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
416
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
60
417
  const signature = utils.createSignature(network, message, privateKey);
61
418
  const pubKey1 = utils.recoverySignature(network, message, signature);
62
419
  const pubKey2 = utils.recoverySignature(network, message, signature);
63
420
  assert.deepStrictEqual(pubKey1, pubKey2);
64
421
  });
65
422
  it('should recover public key that matches original key', function () {
66
- const network = statics_1.coins.get('flrp').network;
67
- const message = Buffer.from('hello world', 'utf8');
68
- const privateKey = Buffer.from('0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', 'hex');
423
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
424
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
69
425
  // Get original public key
70
- const { ecc } = require('@bitgo-beta/secp256k1');
71
- const originalPubKey = Buffer.from(ecc.pointFromScalar(privateKey, true));
426
+ const originalPubKey = Buffer.from(secp256k1_1.ecc.pointFromScalar(privateKey, true));
72
427
  // Create signature and recover public key
73
428
  const signature = utils.createSignature(network, message, privateKey);
74
429
  const recoveredPubKey = utils.recoverySignature(network, message, signature);
75
430
  // Convert both to hex strings for comparison
76
431
  assert.strictEqual(recoveredPubKey.toString('hex'), originalPubKey.toString('hex'));
77
432
  });
78
- it('should throw error for invalid signature', function () {
79
- const network = statics_1.coins.get('flrp').network;
80
- const message = Buffer.from('hello world', 'utf8');
81
- const invalidSignature = Buffer.from('invalid signature', 'utf8');
433
+ it('should recover public key using ACCOUNT_1 keys', function () {
434
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
435
+ const privateKey = Buffer.from(account_1.ACCOUNT_1.privateKey, 'hex');
436
+ const originalPubKey = Buffer.from(secp256k1_1.ecc.pointFromScalar(privateKey, true));
437
+ const signature = utils.createSignature(network, message, privateKey);
438
+ const recoveredPubKey = utils.recoverySignature(network, message, signature);
439
+ assert.strictEqual(recoveredPubKey.toString('hex'), originalPubKey.toString('hex'));
440
+ });
441
+ it('should throw error for invalid signature length', function () {
442
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
443
+ const invalidSignature = Buffer.from(account_1.INVALID_SHORT_KEYPAIR_KEY, 'hex');
82
444
  assert.throws(() => utils.recoverySignature(network, message, invalidSignature), /Failed to recover signature/);
83
445
  });
84
- it('should throw error for empty message', function () {
85
- const network = statics_1.coins.get('flrp').network;
86
- const message = Buffer.alloc(0);
87
- const signature = Buffer.alloc(65); // Empty but valid length signature (65 bytes: 64 signature + 1 recovery param)
446
+ it('should throw error for signature with invalid recovery parameter', function () {
447
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
448
+ const signature = Buffer.alloc(65); // Valid length but all zeros - invalid signature
88
449
  assert.throws(() => utils.recoverySignature(network, message, signature), /Failed to recover signature/);
89
450
  });
90
451
  });
91
452
  });
92
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsaURBQTBEO0FBQzFELCtDQUFpQztBQUNqQyxrREFBK0M7QUFFL0MsUUFBUSxDQUFDLE9BQU8sRUFBRTtJQUNoQixJQUFJLEtBQVksQ0FBQztJQUVqQixVQUFVLENBQUM7UUFDVCxLQUFLLEdBQUcsSUFBSSxhQUFLLEVBQUUsQ0FBQztJQUN0QixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxtQkFBbUIsRUFBRTtRQUM1QixFQUFFLENBQUMsZ0RBQWdELEVBQUU7WUFDbkQsTUFBTSxPQUFPLEdBQUcsZUFBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUF1QixDQUFDO1lBQzFELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ25ELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0VBQWtFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFMUcsOENBQThDO1lBQzlDLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUV0RSxxQkFBcUI7WUFDckIsTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFFN0UsTUFBTSxDQUFDLEVBQUUsQ0FBQyxlQUFlLFlBQVksTUFBTSxDQUFDLENBQUM7WUFDN0MsTUFBTSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsNkNBQTZDO1FBQy9GLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFB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RTtZQUVuSCxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsQ0FBQyxFQUFFLDZCQUE2QixDQUFDLENBQUM7UUFDM0csQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29pbnMsIEZsYXJlTmV0d29yayB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgeyBVdGlscyB9IGZyb20gJy4uLy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuXG5kZXNjcmliZSgnVXRpbHMnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCB1dGlsczogVXRpbHM7XG5cbiAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgdXRpbHMgPSBuZXcgVXRpbHMoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3JlY292ZXJ5U2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBwdWJsaWMga2V5IGZyb20gdmFsaWQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbmV0d29yayA9IGNvaW5zLmdldCgnZmxycCcpLm5ldHdvcmsgYXMgRmxhcmVOZXR3b3JrO1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdoZWxsbyB3b3JsZCcsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oJzAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYnLCAnaGV4Jyk7XG5cbiAgICAgIC8vIENyZWF0ZSBzaWduYXR1cmUgdXNpbmcgdGhlIHNhbWUgcHJpdmF0ZSBrZXlcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgLy8gUmVjb3ZlciBwdWJsaWMga2V5XG4gICAgICBjb25zdCByZWNvdmVyZWRQdWJLZXkgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpO1xuXG4gICAgICBhc3NlcnQub2socmVjb3ZlcmVkUHViS2V5IGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZWNvdmVyZWRQdWJLZXkubGVuZ3RoLCAzMyk7IC8vIFNob3VsZCBiZSBjb21wcmVzc2VkIHB1YmxpYyBrZXkgKDMzIGJ5dGVzKVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHNhbWUgcHVibGljIGtleSBmb3Igc2FtZSBtZXNzYWdlIGFuZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBuZXR3b3JrID0gY29pbnMuZ2V0KCdmbHJwJykubmV0d29yayBhcyBGbGFyZU5ldHdvcms7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oJ2hlbGxvIHdvcmxkJywgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbSgnMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZicsICdoZXgnKTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgY29uc3QgcHViS2V5MSA9IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ25hdHVyZSk7XG4gICAgICBjb25zdCBwdWJLZXkyID0gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnbmF0dXJlKTtcblxuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChwdWJLZXkxLCBwdWJLZXkyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBwdWJsaWMga2V5IHRoYXQgbWF0Y2hlcyBvcmlnaW5hbCBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBuZXR3b3JrID0gY29pbnMuZ2V0KCdmbHJwJykubmV0d29yayBhcyBGbGFyZU5ldHdvcms7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oJ2hlbGxvIHdvcmxkJywgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbSgnMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZicsICdoZXgnKTtcblxuICAgICAgLy8gR2V0IG9yaWdpbmFsIHB1YmxpYyBrZXlcbiAgICAgIGNvbnN0IHsgZWNjIH0gPSByZXF1aXJlKCdAYml0Z28tYmV0YS9zZWNwMjU2azEnKTtcbiAgICAgIGNvbnN0IG9yaWdpbmFsUHViS2V5ID0gQnVmZmVyLmZyb20oZWNjLnBvaW50RnJvbVNjYWxhcihwcml2YXRlS2V5LCB0cnVlKSBhcyBVaW50OEFycmF5KTtcblxuICAgICAgLy8gQ3JlYXRlIHNpZ25hdHVyZSBhbmQgcmVjb3ZlciBwdWJsaWMga2V5XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG4gICAgICBjb25zdCByZWNvdmVyZWRQdWJLZXkgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpO1xuXG4gICAgICAvLyBDb252ZXJ0IGJvdGggdG8gaGV4IHN0cmluZ3MgZm9yIGNvbXBhcmlzb25cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZWNvdmVyZWRQdWJLZXkudG9TdHJpbmcoJ2hleCcpLCBvcmlnaW5hbFB1YktleS50b1N0cmluZygnaGV4JykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaW52YWxpZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBuZXR3b3JrID0gY29pbnMuZ2V0KCdmbHJwJykubmV0d29yayBhcyBGbGFyZU5ldHdvcms7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oJ2hlbGxvIHdvcmxkJywgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGludmFsaWRTaWduYXR1cmUgPSBCdWZmZXIuZnJvbSgnaW52YWxpZCBzaWduYXR1cmUnLCAndXRmOCcpO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIGludmFsaWRTaWduYXR1cmUpLCAvRmFpbGVkIHRvIHJlY292ZXIgc2lnbmF0dXJlLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBlbXB0eSBtZXNzYWdlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbmV0d29yayA9IGNvaW5zLmdldCgnZmxycCcpLm5ldHdvcmsgYXMgRmxhcmVOZXR3b3JrO1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5hbGxvYygwKTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IEJ1ZmZlci5hbGxvYyg2NSk7IC8vIEVtcHR5IGJ1dCB2YWxpZCBsZW5ndGggc2lnbmF0dXJlICg2NSBieXRlczogNjQgc2lnbmF0dXJlICsgMSByZWNvdmVyeSBwYXJhbSlcblxuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpLCAvRmFpbGVkIHRvIHJlY292ZXIgc2lnbmF0dXJlLyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
453
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsaURBQTBEO0FBQzFELCtDQUFpQztBQUNqQyxrREFBK0M7QUFDL0MscURBT2lDO0FBQ2pDLHFEQUE0QztBQUM1Qyx5RUFBd0U7QUFDeEUseUVBQXdFO0FBRXhFLFFBQVEsQ0FBQyxPQUFPLEVBQUU7SUFDaEIsSUFBSSxLQUFZLENBQUM7SUFDakIsTUFBTSxPQUFPLEdBQUcsZUFBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUF1QixDQUFDO0lBRTFELFVBQVUsQ0FBQztRQUNULEtBQUssR0FBRyxJQUFJLGFBQUssRUFBRSxDQUFDO0lBQ3RCLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFdBQVcsRUFBRTtRQUNwQixFQUFFLENBQUMsMkVBQTJFLEVBQUU7WUFDOUUsTUFBTSxlQUFlLEdBQUcsQ0FBQyx1QkFBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSx1QkFBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9FLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxHQUFHLHVCQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxtQkFBbUIsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2xGLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlGQUFpRixFQUFFO1lBQ3BGLE1BQU0sZUFBZSxHQUFHLENBQUMsdUJBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsbUJBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN2RSxNQUFNLG1CQUFtQixHQUFHLENBQUMsdUJB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LE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUV0RSxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsWUFBWSxNQUFNLENBQUMsQ0FBQztZQUN2QyxNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaUNBQWlDLEVBQUU7WUFDcEMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMxRCxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFZLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQy9ELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0JBQVksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFN0QsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3RFLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRXZDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDNUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMkNBQTJDLEVBQUU7WUFDOUMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMxRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFB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Q0FBQyxDQUFDO1lBQzFELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxpREFBaUQ7WUFFckYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLENBQUMsRUFBRSw2QkFBNkIsQ0FBQyxDQUFDO1FBQzNHLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvaW5zLCBGbGFyZU5ldHdvcmsgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgVXRpbHMgfSBmcm9tICcuLi8uLi8uLi9zcmMvbGliL3V0aWxzJztcbmltcG9ydCB7XG4gIFNFRURfQUNDT1VOVCxcbiAgQUNDT1VOVF8xLFxuICBBQ0NPVU5UXzIsXG4gIEFDQ09VTlRfMyxcbiAgSU5WQUxJRF9TSE9SVF9LRVlQQUlSX0tFWSxcbiAgSU5WQUxJRF9MT05HX0tFWVBBSVJfUFJWLFxufSBmcm9tICcuLi8uLi9yZXNvdXJjZXMvYWNjb3VudCc7XG5pbXBvcnQgeyBlY2MgfSBmcm9tICdAYml0Z28tYmV0YS9zZWNwMjU2azEnO1xuaW1wb3J0IHsgRVhQT1JUX0lOX0MgfSBmcm9tICcuLi8uLi9yZXNvdXJjZXMvdHJhbnNhY3Rpb25EYXRhL2V4cG9ydEluQyc7XG5pbXBvcnQgeyBJTVBPUlRfSU5fUCB9IGZyb20gJy4uLy4uL3Jlc291cmNlcy90cmFuc2FjdGlvbkRhdGEvaW1wb3J0SW5QJztcblxuZGVzY3JpYmUoJ1V0aWxzJywgZnVuY3Rpb24gKCkge1xuICBsZXQgdXRpbHM6IFV0aWxzO1xuICBjb25zdCBuZXR3b3JrID0gY29pbnMuZ2V0KCdmbHJwJykubmV0d29yayBhcyBGbGFyZU5ldHdvcms7XG5cbiAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgdXRpbHMgPSBuZXcgVXRpbHMoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2luY2x1ZGVJbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gYWxsIHdhbGxldCBhZGRyZXNzZXMgYXJlIGluIFVUWE8gb3V0cHV0IGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldEFkZHJlc3NlcyA9IFtFWFBPUlRfSU5fQy5wQWRkcmVzc2VzWzBdLCBFWFBPUlRfSU5fQy5wQWRkcmVzc2VzWzFdXTtcbiAgICAgIGNvbnN0IHV0eG9PdXRwdXRBZGRyZXNzZXMgPSBbLi4uRVhQT1JUX0lOX0MucEFkZHJlc3Nlc107XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaW5jbHVkZUluKHdhbGxldEFkZHJlc3NlcywgdXR4b091dHB1dEFkZHJlc3NlcyksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2Ugd2hlbiBzb21lIHdhbGxldCBhZGRyZXNzZXMgYXJlIG5vdCBpbiBVVFhPIG91dHB1dCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRBZGRyZXNzZXMgPSBbRVhQT1JUX0lOX0MucEFkZHJlc3Nlc1swXSwgQUNDT1VOVF8zLmFkZHJlc3NdO1xuICAgICAgY29uc3QgdXR4b091dHB1dEFkZHJlc3NlcyA9IFtFWFBPUlRfSU5fQy5wQWRkcmVzc2VzWzBdLCBFWFBPUlRfSU5fQy5wQWRkcmVzc2VzWzFdXTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pbmNsdWRlSW4od2FsbGV0QWRkcmVzc2VzLCB1dHhvT3V0cHV0QWRkcmVzc2VzKSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgZW1wdHkgd2FsbGV0IGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldEFkZHJlc3Nlczogc3RyaW5nW10gPSBbXTtcbiAgICAgIGNvbnN0IHV0eG9PdXRwdXRBZGRyZXNzZXMgPSBbRVhQT1JUX0lOX0MucEFkZHJlc3Nlc1swXV07XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaW5jbHVkZUluKHdhbGxldEFkZHJlc3NlcywgdXR4b091dHB1dEFkZHJlc3NlcyksIHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZEFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgbWFpbm5ldCBQLWNoYWluIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoU0VFRF9BQ0NPVU5ULmFkZHJlc3NNYWlubmV0KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCB0ZXN0bmV0IFAtY2hhaW4gYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcyhTRUVEX0FDQ09VTlQuYWRkcmVzc1Rlc3RuZXQpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIE5vZGVJRCBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKCdOb2RlSUQtYWJjMTIzeHl6JyksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgYXJyYXkgb2YgdmFsaWQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKEVYUE9SVF9JTl9DLnBBZGRyZXNzZXMpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHRpbGRlLXNlcGFyYXRlZCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBjb21iaW5lZCA9IEVYUE9SVF9JTl9DLnBBZGRyZXNzZXMuam9pbignficpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKGNvbWJpbmVkKSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgaW52YWxpZCBhZGRyZXNzIGZvcm1hdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcygnaW52YWxpZCcpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgYWRkcmVzcyB3aXRob3V0IHByZWZpeCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcygnZmxhcmUxYWJjMTIzJyksIGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRCbG9ja0lkJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIDMyLWJ5dGUgaGV4IGJsb2NrIElEJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRCbG9ja0lkKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5KSwgdHJ1ZSk7IC8vIDY0IGhleCBjaGFycyA9IDMyIGJ5dGVzXG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgaW52YWxpZCBsZW5ndGggYmxvY2sgSUQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEJsb2NrSWQoSU5WQUxJRF9TSE9SVF9LRVlQQUlSX0tFWSksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBlbXB0eSBibG9jayBJRCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQmxvY2tJZCgnJyksIGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRQdWJsaWNLZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgY29tcHJlc3NlZCBwdWJsaWMga2V5IHN0YXJ0aW5nIHdpdGggMDMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShTRUVEX0FDQ09VTlQucHVibGljS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCBjb21wcmVzc2VkIHB1YmxpYyBrZXkgc3RhcnRpbmcgd2l0aCAwMicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KEFDQ09VTlRfMS5wdWJsaWNLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIGFub3RoZXIgdmFsaWQgY29tcHJlc3NlZCBwdWJsaWMga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQUNDT1VOVF8yLnB1YmxpY0tleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgeHB1YicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KFNFRURfQUNDT1VOVC54UHVibGljS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBBQ0NPVU5UXzEgeHB1YicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KEFDQ09VTlRfMS54UHVibGljS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgaW52YWxpZCBzaG9ydCBwdWJsaWMga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoSU5WQUxJRF9TSE9SVF9LRVlQQUlSX0tFWSksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBjb21wcmVzc2VkIGtleSB3aXRoIHdyb25nIHByZWZpeCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGludmFsaWRLZXkgPSAnMDUnICsgU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShpbnZhbGlkS2V5KSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIG5vbi1oZXggcHVibGljIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGludmFsaWRLZXkgPSAnenonICsgU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShpbnZhbGlkS2V5KSwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZFByaXZhdGVLZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgNjQtY2hhciBoZXggcHJpdmF0ZSBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIEFDQ09VTlRfMSBwcml2YXRlIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShBQ0NPVU5UXzEucHJpdmF0ZUtleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgQUNDT1VOVF8yIHByaXZhdGUga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KEFDQ09VTlRfMi5wcml2YXRlS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCB4cHJ2JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KFNFRURfQUNDT1VOVC54UHJpdmF0ZUtleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgNjYtY2hhciBwcml2YXRlIGtleSBlbmRpbmcgd2l0aCAwMScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4dGVuZGVkS2V5ID0gU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXkgKyAnMDEnO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KGV4dGVuZGVkS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgNjYtY2hhciBwcml2YXRlIGtleSBub3QgZW5kaW5nIHdpdGggMDEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoSU5WQUxJRF9MT05HX0tFWVBBSVJfUFJWKSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGludmFsaWQgc2hvcnQgcHJpdmF0ZSBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoSU5WQUxJRF9TSE9SVF9LRVlQQUlSX0tFWSksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBub24taGV4IHByaXZhdGUga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZEtleSA9ICd6eicgKyBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleS5zbGljZSgyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShpbnZhbGlkS2V5KSwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYWxsSGV4Q2hhcnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgcHJpdmF0ZSBrZXkgaGV4JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmFsbEhleENoYXJzKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCBwdWJsaWMga2V5IGhleCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5hbGxIZXhDaGFycyhTRUVEX0FDQ09VTlQucHVibGljS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBoZXggc3RyaW5nIHdpdGggMHggcHJlZml4JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmFsbEhleENoYXJzKEVYUE9SVF9JTl9DLmNIZXhBZGRyZXNzKSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCBzaWduYXR1cmUgaGV4JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmFsbEhleENoYXJzKFNFRURfQUNDT1VOVC5zaWduYXR1cmUpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBub24taGV4IGNoYXJhY3RlcnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuYWxsSGV4Q2hhcnMoJ2doaWprbCcpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgZW1wdHkgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmFsbEhleENoYXJzKCcnKSwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY3JlYXRlU2lnbmF0dXJlIGFuZCB2ZXJpZnlTaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSB2YWxpZCA2NS1ieXRlIHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSwgJ2hleCcpO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG5cbiAgICAgIGFzc2VydC5vayhzaWduYXR1cmUgaW5zdGFuY2VvZiBCdWZmZXIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNpZ25hdHVyZS5sZW5ndGgsIDY1KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmVyaWZ5IGEgdmFsaWQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LCAnaGV4Jyk7XG4gICAgICBjb25zdCBwdWJsaWNLZXkgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQucHVibGljS2V5LCAnaGV4Jyk7XG5cbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcbiAgICAgIGNvbnN0IHNpZ09ubHkgPSBzaWduYXR1cmUuc2xpY2UoMCwgNjQpO1xuXG4gICAgICBjb25zdCBpc1ZhbGlkID0gdXRpbHMudmVyaWZ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ09ubHksIHB1YmxpY0tleSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaXNWYWxpZCwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgaW52YWxpZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwdWJsaWNLZXkgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQucHVibGljS2V5LCAnaGV4Jyk7XG4gICAgICBjb25zdCBpbnZhbGlkU2lnbmF0dXJlID0gQnVmZmVyLmFsbG9jKDY0KTtcblxuICAgICAgY29uc3QgaXNWYWxpZCA9IHV0aWxzLnZlcmlmeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBpbnZhbGlkU2lnbmF0dXJlLCBwdWJsaWNLZXkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGlzVmFsaWQsIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIHNpZ25hdHVyZSB3aXRoIEFDQ09VTlRfMSBrZXlzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKEFDQ09VTlRfMS5wcml2YXRlS2V5LCAnaGV4Jyk7XG5cbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgYXNzZXJ0Lm9rKHNpZ25hdHVyZSBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2lnbmF0dXJlLmxlbmd0aCwgNjUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY3JlYXRlTmV3U2lnJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgc2lnbmF0dXJlIGZyb20gdmFsaWQgc2lnbmF0dXJlIGhleCBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWcgPSB1dGlscy5jcmVhdGVOZXdTaWcoU0VFRF9BQ0NPVU5ULnNpZ25hdHVyZSk7XG4gICAgICBhc3NlcnQub2soc2lnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIGEgc2lnbmF0dXJlIGZyb20gZXhwb3J0IHNpZ25hdHVyZSBoZXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzaWdIZXggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoRVhQT1JUX0lOX0Muc2lnbmF0dXJlWzBdKTtcbiAgICAgIGNvbnN0IHNpZyA9IHV0aWxzLmNyZWF0ZU5ld1NpZyhzaWdIZXgpO1xuICAgICAgYXNzZXJ0Lm9rKHNpZyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhZCBzaG9ydCBoZXggc3RyaW5ncycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZ0hleCA9IElOVkFMSURfU0hPUlRfS0VZUEFJUl9LRVk7XG4gICAgICBjb25zdCBzaWcgPSB1dGlscy5jcmVhdGVOZXdTaWcoc2lnSGV4KTtcbiAgICAgIGFzc2VydC5vayhzaWcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY3JlYXRlRW1wdHlTaWdXaXRoQWRkcmVzcyBhbmQgZ2V0QWRkcmVzc0Zyb21FbXB0eVNpZycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBlbXB0eSBzaWduYXR1cmUgd2l0aCBlbWJlZGRlZCBDLWNoYWluIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzSGV4ID0gdXRpbHMucmVtb3ZlSGV4UHJlZml4KEVYUE9SVF9JTl9DLmNIZXhBZGRyZXNzKTtcbiAgICAgIGNvbnN0IHNpZyA9IHV0aWxzLmNyZWF0ZUVtcHR5U2lnV2l0aEFkZHJlc3MoYWRkcmVzc0hleCk7XG4gICAgICBhc3NlcnQub2soc2lnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZXh0cmFjdCBlbWJlZGRlZCBhZGRyZXNzIGZyb20gZW1wdHkgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzc0hleCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeChFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcykudG9Mb3dlckNhc2UoKTtcbiAgICAgIGNvbnN0IHNpZyA9IHV0aWxzLmNyZWF0ZUVtcHR5U2lnV2l0aEFkZHJlc3MoYWRkcmVzc0hleCk7XG5cbiAgICAgIC8vIEdldCBzaWduYXR1cmUgYnl0ZXMgYW5kIGNvbnZlcnQgdG8gaGV4XG4gICAgICBjb25zdCBzaWdCeXRlcyA9IHNpZy50b0J5dGVzKCk7XG4gICAgICBjb25zdCBzaWdIZXggPSBCdWZmZXIuZnJvbShzaWdCeXRlcykudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICBjb25zdCBleHRyYWN0ZWRBZGRyZXNzID0gdXRpbHMuZ2V0QWRkcmVzc0Zyb21FbXB0eVNpZyhzaWdIZXgpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGV4dHJhY3RlZEFkZHJlc3MsIGFkZHJlc3NIZXgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgMHggcHJlZml4ZWQgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZyA9IHV0aWxzLmNyZWF0ZUVtcHR5U2lnV2l0aEFkZHJlc3MoRVhQT1JUX0lOX0MuY0hleEFkZHJlc3MpO1xuICAgICAgYXNzZXJ0Lm9rKHNpZyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBlbXB0eSBzdHJpbmcgZm9yIHNob3J0IHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNob3J0U2lnID0gU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXk7IC8vIDY0IGNoYXJzLCBsZXNzIHRoYW4gMTMwXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuZ2V0QWRkcmVzc0Zyb21FbXB0eVNpZyhzaG9ydFNpZyksICcnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3NoYTI1NicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNvbXB1dGUgU0hBMjU2IGhhc2ggb2YgbWVzc2FnZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGhhc2ggPSB1dGlscy5zaGEyNTYoZGF0YSk7XG5cbiAgICAgIGFzc2VydC5vayhoYXNoIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChoYXNoLmxlbmd0aCwgMzIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGNvbnNpc3RlbnQgaGFzaCBmb3Igc2FtZSBpbnB1dCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGhhc2gxID0gdXRpbHMuc2hhMjU2KGRhdGEpO1xuICAgICAgY29uc3QgaGFzaDIgPSB1dGlscy5zaGEyNTYoZGF0YSk7XG5cbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoaGFzaDEsIGhhc2gyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcHJvZHVjZSBkaWZmZXJlbnQgaGFzaCBmb3IgZGlmZmVyZW50IGlucHV0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YTEgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGRhdGEyID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXksICd1dGY4Jyk7XG4gICAgICBjb25zdCBoYXNoMSA9IHV0aWxzLnNoYTI1NihkYXRhMSk7XG4gICAgICBjb25zdCBoYXNoMiA9IHV0aWxzLnNoYTI1NihkYXRhMik7XG5cbiAgICAgIGFzc2VydC5ub3REZWVwU3RyaWN0RXF1YWwoaGFzaDEsIGhhc2gyKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZhbGlkYXRlUmF3VHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBub3QgdGhyb3cgZm9yIHZhbGlkIHVuc2lnbmVkIGhleCB0cmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJhd1R4ID0gdXRpbHMucmVtb3ZlSGV4UHJlZml4KEVYUE9SVF9JTl9DLnVuc2lnbmVkSGV4KTtcbiAgICAgIGFzc2VydC5kb2VzTm90VGhyb3coKCkgPT4gdXRpbHMudmFsaWRhdGVSYXdUcmFuc2FjdGlvbihyYXdUeCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgdGhyb3cgZm9yIHZhbGlkIHNpZ25lZCBoZXggdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCByYXdUeCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeChFWFBPUlRfSU5fQy5zaWduZWRIZXgpO1xuICAgICAgYXNzZXJ0LmRvZXNOb3RUaHJvdygoKSA9PiB1dGlscy52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKHJhd1R4KSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCB0aHJvdyBmb3IgaW1wb3J0IHRyYW5zYWN0aW9uIGhleCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJhd1R4ID0gdXRpbHMucmVtb3ZlSGV4UHJlZml4KElNUE9SVF9JTl9QLnVuc2lnbmVkSGV4KTtcbiAgICAgIGFzc2VydC5kb2VzTm90VGhyb3coKCkgPT4gdXRpbHMudmFsaWRhdGVSYXdUcmFuc2FjdGlvbihyYXdUeCkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgZW1wdHkgdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oJycpLCAvUmF3IHRyYW5zYWN0aW9uIGlzIGVtcHR5Lyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGZvciBub24taGV4IHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB1dGlscy52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKCd4eXoxMjMnKSwgL1JhdyB0cmFuc2FjdGlvbiBpcyBub3QgaGV4IHN0cmluZy8pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncmVtb3ZlSGV4UHJlZml4JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmVtb3ZlIDB4IHByZWZpeCBmcm9tIEMtY2hhaW4gYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5yZW1vdmVIZXhQcmVmaXgoRVhQT1JUX0lOX0MuY0hleEFkZHJlc3MpLCBFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcy5zbGljZSgyKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlbW92ZSAweCBwcmVmaXggZnJvbSB1bnNpZ25lZCBoZXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMucmVtb3ZlSGV4UHJlZml4KEVYUE9SVF9JTl9DLnVuc2lnbmVkSGV4KSwgRVhQT1JUX0lOX0MudW5zaWduZWRIZXguc2xpY2UoMikpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gc3RyaW5nIHVuY2hhbmdlZCBpZiBubyBwcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMucmVtb3ZlSGV4UHJlZml4KFNFRURfQUNDT1VOVC5wcml2YXRlS2V5KSwgU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgZW1wdHkgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLnJlbW92ZUhleFByZWZpeCgnJyksICcnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ291dHB1dGlkeE51bWJlclRvQnVmZmVyIGFuZCBvdXRwdXRpZHhCdWZmZXJUb051bWJlcicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNvbnZlcnQgb3V0cHV0IGluZGV4IHRvIGJ1ZmZlciBhbmQgYmFjaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG91dHB1dElkeCA9IElNUE9SVF9JTl9QLm91dHB1dHNbMF0ub3V0cHV0aWR4O1xuICAgICAgY29uc3QgYnVmZmVyID0gdXRpbHMub3V0cHV0aWR4TnVtYmVyVG9CdWZmZXIob3V0cHV0SWR4KTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzLm91dHB1dGlkeEJ1ZmZlclRvTnVtYmVyKGJ1ZmZlcik7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIG91dHB1dElkeCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBub25jZSB2YWx1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG5vbmNlU3RyID0gRVhQT1JUX0lOX0Mubm9uY2UudG9TdHJpbmcoKTtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IHV0aWxzLm91dHB1dGlkeE51bWJlclRvQnVmZmVyKG5vbmNlU3RyKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzLm91dHB1dGlkeEJ1ZmZlclRvTnVtYmVyKGJ1ZmZlcik7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIG5vbmNlU3RyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcHJvZHVjZSA0LWJ5dGUgYnVmZmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVmZmVyID0gdXRpbHMub3V0cHV0aWR4TnVtYmVyVG9CdWZmZXIoJzI1NScpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlci5sZW5ndGgsIDQpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYWRkcmVzc1RvU3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY29udmVydCBhZGRyZXNzIGJ1ZmZlciB0byBtYWlubmV0IGJlY2gzMiBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gU0VFRF9BQ0NPVU5ULmFkZHJlc3NNYWlubmV0O1xuICAgICAgY29uc3QgYWRkcmVzc0J1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhhZGRyZXNzKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzLmFkZHJlc3NUb1N0cmluZygnZmxhcmUnLCAnUCcsIGFkZHJlc3NCdWZmZXIpO1xuXG4gICAgICBhc3NlcnQub2socmVzdWx0LnN0YXJ0c1dpdGgoJ1AtJykpO1xuICAgICAgYXNzZXJ0Lm9rKHJlc3VsdC5pbmNsdWRlcygnZmxhcmUnKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNvbnZlcnQgYWRkcmVzcyBidWZmZXIgdG8gdGVzdG5ldCBiZWNoMzIgc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9IFNFRURfQUNDT1VOVC5hZGRyZXNzVGVzdG5ldDtcbiAgICAgIGNvbnN0IGFkZHJlc3NCdWZmZXIgPSB1dGlscy5wYXJzZUFkZHJlc3MoYWRkcmVzcyk7XG4gICAgICBjb25zdCByZXN1bHQgPSB1dGlscy5hZGRyZXNzVG9TdHJpbmcoJ2Nvc3R3bycsICdQJywgYWRkcmVzc0J1ZmZlcik7XG5cbiAgICAgIGFzc2VydC5vayhyZXN1bHQuc3RhcnRzV2l0aCgnUC0nKSk7XG4gICAgICBhc3NlcnQub2socmVzdWx0LmluY2x1ZGVzKCdjb3N0d28nKSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjYjU4RW5jb2RlIGFuZCBjYjU4RGVjb2RlJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgZW5jb2RlIGFuZCBkZWNvZGUgdGFyZ2V0IGNoYWluIElEIGNvcnJlY3RseScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVuY29kZWQgPSBFWFBPUlRfSU5fQy50YXJnZXRDaGFpbklkO1xuICAgICAgY29uc3QgZGVjb2RlZCA9IHV0aWxzLmNiNThEZWNvZGUoZW5jb2RlZCk7XG4gICAgICBjb25zdCByZUVuY29kZWQgPSB1dGlscy5jYjU4RW5jb2RlKGRlY29kZWQpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVFbmNvZGVkLCBlbmNvZGVkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZW5jb2RlIGFuZCBkZWNvZGUgc291cmNlIGNoYWluIElEIGNvcnJlY3RseScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGVuY29kZWQgPSBJTVBPUlRfSU5fUC5zb3VyY2VDaGFpbklkO1xuICAgICAgY29uc3QgZGVjb2RlZCA9IHV0aWxzLmNiNThEZWNvZGUoZW5jb2RlZCk7XG4gICAgICBjb25zdCByZUVuY29kZWQgPSB1dGlscy5jYjU4RW5jb2RlKGRlY29kZWQpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVFbmNvZGVkLCBlbmNvZGVkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZm9yIGludmFsaWQgY2hlY2tzdW0nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLmNiNThEZWNvZGUoJzExMTExMTExMTExMTEnKSwgL0ludmFsaWQgY2hlY2tzdW0vKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3BhcnNlQWRkcmVzcyBhbmQgc3RyaW5nVG9BZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcGFyc2UgaGV4IGFkZHJlc3Mgd2l0aCAweCBwcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBidWZmZXIgPSB1dGlscy5wYXJzZUFkZHJlc3MoRVhQT1JUX0lOX0MuY0hleEFkZHJlc3MpO1xuXG4gICAgICBhc3NlcnQub2soYnVmZmVyIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChidWZmZXIubGVuZ3RoLCAyMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIHJhdyBoZXggYWRkcmVzcyBmcm9tIG91dHB1dHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gSU1QT1JUX0lOX1Aub3V0cHV0c1swXS5hZGRyZXNzZXNbMF07XG4gICAgICBjb25zdCBidWZmZXIgPSB1dGlscy5wYXJzZUFkZHJlc3MoYWRkcmVzcyk7XG5cbiAgICAgIGFzc2VydC5vayhidWZmZXIgaW5zdGFuY2VvZiBCdWZmZXIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlci5sZW5ndGgsIDIwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgbWFpbm5ldCBiZWNoMzIgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhTRUVEX0FDQ09VTlQuYWRkcmVzc01haW5uZXQpO1xuXG4gICAgICBhc3NlcnQub2soYnVmZmVyIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChidWZmZXIubGVuZ3RoLCAyMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIHRlc3RuZXQgYmVjaDMyIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBidWZmZXIgPSB1dGlscy5wYXJzZUFkZHJlc3MoU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0KTtcblxuICAgICAgYXNzZXJ0Lm9rKGJ1ZmZlciBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYnVmZmVyLmxlbmd0aCwgMjApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBQLWNoYWluIGFkZHJlc3NlcyBmcm9tIGV4cG9ydCBkYXRhJywgZnVuY3Rpb24gKCkge1xuICAgICAgRVhQT1JUX0lOX0MucEFkZHJlc3Nlcy5mb3JFYWNoKChhZGRyZXNzKSA9PiB7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhhZGRyZXNzKTtcbiAgICAgICAgYXNzZXJ0Lm9rKGJ1ZmZlciBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChidWZmZXIubGVuZ3RoLCAyMCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZm9yIGFkZHJlc3Mgd2l0aG91dCBkYXNoIHNlcGFyYXRvcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMucGFyc2VBZGRyZXNzKCdmbGFyZTFhYmMnKSwgL1ZhbGlkIGFkZHJlc3Mgc2hvdWxkIGluY2x1ZGUgLS8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgaW52YWxpZCBIUlAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLnBhcnNlQWRkcmVzcygnUC1pbnZhbGlkMXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxNWV2em15JyksIC9JbnZhbGlkIEhSUC8pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZmxhcmVJZFN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBJZCBmcm9tIHByaXZhdGUga2V5IGhleCBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpZCA9IHV0aWxzLmZsYXJlSWRTdHJpbmcoU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXkpO1xuICAgICAgYXNzZXJ0Lm9rKGlkKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY3JlYXRlIElkIGZyb20gYXNzZXQgSUQgaGV4JywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gQXNzZXQgSUQgaXMgdHlwaWNhbGx5IDMyIGJ5dGVzICg2NCBoZXggY2hhcnMpXG4gICAgICBjb25zdCBhc3NldElkSGV4ID0gU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXk7IC8vIFVzaW5nIGFzIGEgMzItYnl0ZSBoZXhcbiAgICAgIGNvbnN0IGlkID0gdXRpbHMuZmxhcmVJZFN0cmluZyhhc3NldElkSGV4KTtcbiAgICAgIGFzc2VydC5vayhpZCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdyZWNvdmVyeVNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgcHVibGljIGtleSBmcm9tIHZhbGlkIHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSwgJ2hleCcpO1xuXG4gICAgICAvLyBDcmVhdGUgc2lnbmF0dXJlIHVzaW5nIHRoZSBzYW1lIHByaXZhdGUga2V5XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG5cbiAgICAgIC8vIFJlY292ZXIgcHVibGljIGtleVxuICAgICAgY29uc3QgcmVjb3ZlcmVkUHViS2V5ID0gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnbmF0dXJlKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlY292ZXJlZFB1YktleSBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVjb3ZlcmVkUHViS2V5Lmxlbmd0aCwgMzMpOyAvLyBTaG91bGQgYmUgY29tcHJlc3NlZCBwdWJsaWMga2V5ICgzMyBieXRlcylcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBzYW1lIHB1YmxpYyBrZXkgZm9yIHNhbWUgbWVzc2FnZSBhbmQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LCAnaGV4Jyk7XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG5cbiAgICAgIGNvbnN0IHB1YktleTEgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpO1xuICAgICAgY29uc3QgcHViS2V5MiA9IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ25hdHVyZSk7XG5cbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocHViS2V5MSwgcHViS2V5Mik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgcHVibGljIGtleSB0aGF0IG1hdGNoZXMgb3JpZ2luYWwga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LCAnaGV4Jyk7XG5cbiAgICAgIC8vIEdldCBvcmlnaW5hbCBwdWJsaWMga2V5XG4gICAgICBjb25zdCBvcmlnaW5hbFB1YktleSA9IEJ1ZmZlci5mcm9tKGVjYy5wb2ludEZyb21TY2FsYXIocHJpdmF0ZUtleSwgdHJ1ZSkgYXMgVWludDhBcnJheSk7XG5cbiAgICAgIC8vIENyZWF0ZSBzaWduYXR1cmUgYW5kIHJlY292ZXIgcHVibGljIGtleVxuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHByaXZhdGVLZXkpO1xuICAgICAgY29uc3QgcmVjb3ZlcmVkUHViS2V5ID0gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnbmF0dXJlKTtcblxuICAgICAgLy8gQ29udmVydCBib3RoIHRvIGhleCBzdHJpbmdzIGZvciBjb21wYXJpc29uXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVjb3ZlcmVkUHViS2V5LnRvU3RyaW5nKCdoZXgnKSwgb3JpZ2luYWxQdWJLZXkudG9TdHJpbmcoJ2hleCcpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBwdWJsaWMga2V5IHVzaW5nIEFDQ09VTlRfMSBrZXlzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKEFDQ09VTlRfMS5wcml2YXRlS2V5LCAnaGV4Jyk7XG5cbiAgICAgIGNvbnN0IG9yaWdpbmFsUHViS2V5ID0gQnVmZmVyLmZyb20oZWNjLnBvaW50RnJvbVNjYWxhcihwcml2YXRlS2V5LCB0cnVlKSBhcyBVaW50OEFycmF5KTtcblxuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHByaXZhdGVLZXkpO1xuICAgICAgY29uc3QgcmVjb3ZlcmVkUHViS2V5ID0gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnbmF0dXJlKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlY292ZXJlZFB1YktleS50b1N0cmluZygnaGV4JyksIG9yaWdpbmFsUHViS2V5LnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBpbnZhbGlkIHNpZ25hdHVyZSBsZW5ndGgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBpbnZhbGlkU2lnbmF0dXJlID0gQnVmZmVyLmZyb20oSU5WQUxJRF9TSE9SVF9LRVlQQUlSX0tFWSwgJ2hleCcpO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIGludmFsaWRTaWduYXR1cmUpLCAvRmFpbGVkIHRvIHJlY292ZXIgc2lnbmF0dXJlLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBzaWduYXR1cmUgd2l0aCBpbnZhbGlkIHJlY292ZXJ5IHBhcmFtZXRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IEJ1ZmZlci5hbGxvYyg2NSk7IC8vIFZhbGlkIGxlbmd0aCBidXQgYWxsIHplcm9zIC0gaW52YWxpZCBzaWduYXR1cmVcblxuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpLCAvRmFpbGVkIHRvIHJlY292ZXIgc2lnbmF0dXJlLyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=