@bitgo/sdk-coin-flrp 1.4.0 → 1.4.1
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.
- package/dist/src/flrp.d.ts +68 -6
- package/dist/src/flrp.d.ts.map +1 -1
- package/dist/src/flrp.js +272 -13
- package/dist/src/lib/ExportInCTxBuilder.d.ts.map +1 -1
- package/dist/src/lib/ExportInCTxBuilder.js +4 -2
- package/dist/src/lib/atomicTransactionBuilder.d.ts +1 -1
- package/dist/src/lib/atomicTransactionBuilder.js +1 -1
- package/dist/src/lib/iface.d.ts +27 -49
- package/dist/src/lib/iface.d.ts.map +1 -1
- package/dist/src/lib/iface.js +2 -15
- package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts +0 -3
- package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts.map +1 -1
- package/dist/src/lib/permissionlessValidatorTxBuilder.js +1 -3
- package/dist/src/lib/transaction.d.ts +5 -0
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +106 -4
- package/dist/src/lib/transactionBuilderFactory.d.ts +16 -1
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilderFactory.js +60 -62
- package/dist/src/lib/utils.d.ts +3 -11
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +9 -35
- package/dist/test/resources/account.d.ts +2 -0
- package/dist/test/resources/account.d.ts.map +1 -1
- package/dist/test/resources/account.js +3 -1
- package/dist/test/unit/flrp.d.ts +2 -0
- package/dist/test/unit/flrp.d.ts.map +1 -0
- package/dist/test/unit/flrp.js +499 -0
- package/dist/test/unit/lib/utils.js +381 -20
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -4
|
@@ -36,16 +36,374 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
const statics_1 = require("@bitgo/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/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
|
|
47
|
-
const
|
|
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
|
|
58
|
-
const
|
|
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
|
|
67
|
-
const
|
|
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
|
|
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
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
const
|
|
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
|
|
85
|
-
const
|
|
86
|
-
const
|
|
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNENBQXFEO0FBQ3JELCtDQUFpQztBQUNqQyxrREFBK0M7QUFFL0MsUUFBUSxDQUFDLE9BQU8sRUFBRTtJQUNoQixJQUFJLEtBQVksQ0FBQztJQUVqQixVQUFVLENBQUM7UUFDVCxLQUFLLEdBQUcsSUFBSSxhQUFLLEVBQUUsQ0FBQztJQUN0QixDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxtQkFBbUIsRUFBRTtRQUM1QixFQUFFLENBQUMsZ0RBQWdELEVBQUU7WUFDbkQsTUFBTSxPQUFPLEdBQUcsZUFBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUF1QixDQUFDO1lBQzFELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ25ELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0VBQWtFLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFMUcsOENBQThDO1lBQzlDLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUV0RSxxQkFBcUI7WUFDckIsTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFFN0UsTUFBTSxDQUFDLEVBQUUsQ0FBQyxlQUFlLFlBQVksTUFBTSxDQUFDLENBQUM7WUFDN0MsTUFBTSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsNkNBQTZDO1FBQy9GLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFB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RTtZQUVuSCxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsQ0FBQyxFQUFFLDZCQUE2QixDQUFDLENBQUM7UUFDM0csQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29pbnMsIEZsYXJlTmV0d29yayB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcbmltcG9ydCAqIGFzIGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgVXRpbHMgfSBmcm9tICcuLi8uLi8uLi9zcmMvbGliL3V0aWxzJztcblxuZGVzY3JpYmUoJ1V0aWxzJywgZnVuY3Rpb24gKCkge1xuICBsZXQgdXRpbHM6IFV0aWxzO1xuXG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgIHV0aWxzID0gbmV3IFV0aWxzKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdyZWNvdmVyeVNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgcHVibGljIGtleSBmcm9tIHZhbGlkIHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG5ldHdvcmsgPSBjb2lucy5nZXQoJ2ZscnAnKS5uZXR3b3JrIGFzIEZsYXJlTmV0d29yaztcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSgnaGVsbG8gd29ybGQnLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKCcwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmJywgJ2hleCcpO1xuXG4gICAgICAvLyBDcmVhdGUgc2lnbmF0dXJlIHVzaW5nIHRoZSBzYW1lIHByaXZhdGUga2V5XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG5cbiAgICAgIC8vIFJlY292ZXIgcHVibGljIGtleVxuICAgICAgY29uc3QgcmVjb3ZlcmVkUHViS2V5ID0gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnbmF0dXJlKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlY292ZXJlZFB1YktleSBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVjb3ZlcmVkUHViS2V5Lmxlbmd0aCwgMzMpOyAvLyBTaG91bGQgYmUgY29tcHJlc3NlZCBwdWJsaWMga2V5ICgzMyBieXRlcylcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBzYW1lIHB1YmxpYyBrZXkgZm9yIHNhbWUgbWVzc2FnZSBhbmQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbmV0d29yayA9IGNvaW5zLmdldCgnZmxycCcpLm5ldHdvcmsgYXMgRmxhcmVOZXR3b3JrO1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdoZWxsbyB3b3JsZCcsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oJzAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYnLCAnaGV4Jyk7XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG5cbiAgICAgIGNvbnN0IHB1YktleTEgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpO1xuICAgICAgY29uc3QgcHViS2V5MiA9IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ25hdHVyZSk7XG5cbiAgICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwocHViS2V5MSwgcHViS2V5Mik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgcHVibGljIGtleSB0aGF0IG1hdGNoZXMgb3JpZ2luYWwga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbmV0d29yayA9IGNvaW5zLmdldCgnZmxycCcpLm5ldHdvcmsgYXMgRmxhcmVOZXR3b3JrO1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKCdoZWxsbyB3b3JsZCcsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oJzAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYnLCAnaGV4Jyk7XG5cbiAgICAgIC8vIEdldCBvcmlnaW5hbCBwdWJsaWMga2V5XG4gICAgICBjb25zdCB7IGVjYyB9ID0gcmVxdWlyZSgnQGJpdGdvL3NlY3AyNTZrMScpO1xuICAgICAgY29uc3Qgb3JpZ2luYWxQdWJLZXkgPSBCdWZmZXIuZnJvbShlY2MucG9pbnRGcm9tU2NhbGFyKHByaXZhdGVLZXksIHRydWUpIGFzIFVpbnQ4QXJyYXkpO1xuXG4gICAgICAvLyBDcmVhdGUgc2lnbmF0dXJlIGFuZCByZWNvdmVyIHB1YmxpYyBrZXlcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcbiAgICAgIGNvbnN0IHJlY292ZXJlZFB1YktleSA9IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ25hdHVyZSk7XG5cbiAgICAgIC8vIENvbnZlcnQgYm90aCB0byBoZXggc3RyaW5ncyBmb3IgY29tcGFyaXNvblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlY292ZXJlZFB1YktleS50b1N0cmluZygnaGV4JyksIG9yaWdpbmFsUHViS2V5LnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIGZvciBpbnZhbGlkIHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG5ldHdvcmsgPSBjb2lucy5nZXQoJ2ZscnAnKS5uZXR3b3JrIGFzIEZsYXJlTmV0d29yaztcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSgnaGVsbG8gd29ybGQnLCAndXRmOCcpO1xuICAgICAgY29uc3QgaW52YWxpZFNpZ25hdHVyZSA9IEJ1ZmZlci5mcm9tKCdpbnZhbGlkIHNpZ25hdHVyZScsICd1dGY4Jyk7XG5cbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgaW52YWxpZFNpZ25hdHVyZSksIC9GYWlsZWQgdG8gcmVjb3ZlciBzaWduYXR1cmUvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGVtcHR5IG1lc3NhZ2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBuZXR3b3JrID0gY29pbnMuZ2V0KCdmbHJwJykubmV0d29yayBhcyBGbGFyZU5ldHdvcms7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmFsbG9jKDApO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gQnVmZmVyLmFsbG9jKDY1KTsgLy8gRW1wdHkgYnV0IHZhbGlkIGxlbmd0aCBzaWduYXR1cmUgKDY1IGJ5dGVzOiA2NCBzaWduYXR1cmUgKyAxIHJlY292ZXJ5IHBhcmFtKVxuXG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ25hdHVyZSksIC9GYWlsZWQgdG8gcmVjb3ZlciBzaWduYXR1cmUvKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
|
|
453
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNENBQXFEO0FBQ3JELCtDQUFpQztBQUNqQyxrREFBK0M7QUFDL0MscURBT2lDO0FBQ2pDLGdEQUF1QztBQUN2Qyx5RUFBd0U7QUFDeEUseUVBQXdFO0FBRXhFLFFBQVEsQ0FBQyxPQUFPLEVBQUU7SUFDaEIsSUFBSSxLQUFZLENBQUM7SUFDakIsTUFBTSxPQUFPLEdBQUcsZUFBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUF1QixDQUFDO0lBRTFELFVBQVUsQ0FBQztRQUNULEtBQUssR0FBRyxJQUFJLGFBQUssRUFBRSxDQUFDO0lBQ3RCLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFdBQVcsRUFBRTtRQUNwQixFQUFFLENBQUMsMkVBQTJFLEVBQUU7WUFDOUUsTUFBTSxlQUFlLEdBQUcsQ0FBQyx1QkFBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSx1QkFBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9FLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxHQUFHLHVCQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxtQkFBbUIsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2xGLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlGQUFpRixFQUFFO1lBQ3BGLE1BQU0sZUFBZSxHQUFHLENBQUMsdUJBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsbUJBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN2RSxNQUFNLG1CQUFtQixHQUFHLENBQUMsdUJB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LE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUV0RSxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsWUFBWSxNQUFNLENBQUMsQ0FBQztZQUN2QyxNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaUNBQWlDLEVBQUU7WUFDcEMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMxRCxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFZLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQy9ELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0JBQVksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFN0QsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3RFLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRXZDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDNUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMkNBQTJDLEVBQUU7WUFDOUMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMxRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFB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Q0FBQyxDQUFDO1lBQzFELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxpREFBaUQ7WUFFckYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLENBQUMsRUFBRSw2QkFBNkIsQ0FBQyxDQUFDO1FBQzNHLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvaW5zLCBGbGFyZU5ldHdvcmsgfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5pbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IFV0aWxzIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2xpYi91dGlscyc7XG5pbXBvcnQge1xuICBTRUVEX0FDQ09VTlQsXG4gIEFDQ09VTlRfMSxcbiAgQUNDT1VOVF8yLFxuICBBQ0NPVU5UXzMsXG4gIElOVkFMSURfU0hPUlRfS0VZUEFJUl9LRVksXG4gIElOVkFMSURfTE9OR19LRVlQQUlSX1BSVixcbn0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL2FjY291bnQnO1xuaW1wb3J0IHsgZWNjIH0gZnJvbSAnQGJpdGdvL3NlY3AyNTZrMSc7XG5pbXBvcnQgeyBFWFBPUlRfSU5fQyB9IGZyb20gJy4uLy4uL3Jlc291cmNlcy90cmFuc2FjdGlvbkRhdGEvZXhwb3J0SW5DJztcbmltcG9ydCB7IElNUE9SVF9JTl9QIH0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL3RyYW5zYWN0aW9uRGF0YS9pbXBvcnRJblAnO1xuXG5kZXNjcmliZSgnVXRpbHMnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCB1dGlsczogVXRpbHM7XG4gIGNvbnN0IG5ldHdvcmsgPSBjb2lucy5nZXQoJ2ZscnAnKS5uZXR3b3JrIGFzIEZsYXJlTmV0d29yaztcblxuICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICB1dGlscyA9IG5ldyBVdGlscygpO1xuICB9KTtcblxuICBkZXNjcmliZSgnaW5jbHVkZUluJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgd2hlbiBhbGwgd2FsbGV0IGFkZHJlc3NlcyBhcmUgaW4gVVRYTyBvdXRwdXQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0QWRkcmVzc2VzID0gW0VYUE9SVF9JTl9DLnBBZGRyZXNzZXNbMF0sIEVYUE9SVF9JTl9DLnBBZGRyZXNzZXNbMV1dO1xuICAgICAgY29uc3QgdXR4b091dHB1dEFkZHJlc3NlcyA9IFsuLi5FWFBPUlRfSU5fQy5wQWRkcmVzc2VzXTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pbmNsdWRlSW4od2FsbGV0QWRkcmVzc2VzLCB1dHhvT3V0cHV0QWRkcmVzc2VzKSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSB3aGVuIHNvbWUgd2FsbGV0IGFkZHJlc3NlcyBhcmUgbm90IGluIFVUWE8gb3V0cHV0IGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldEFkZHJlc3NlcyA9IFtFWFBPUlRfSU5fQy5wQWRkcmVzc2VzWzBdLCBBQ0NPVU5UXzMuYWRkcmVzc107XG4gICAgICBjb25zdCB1dHhvT3V0cHV0QWRkcmVzc2VzID0gW0VYUE9SVF9JTl9DLnBBZGRyZXNzZXNbMF0sIEVYUE9SVF9JTl9DLnBBZGRyZXNzZXNbMV1dO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmluY2x1ZGVJbih3YWxsZXRBZGRyZXNzZXMsIHV0eG9PdXRwdXRBZGRyZXNzZXMpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBlbXB0eSB3YWxsZXQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0QWRkcmVzc2VzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgY29uc3QgdXR4b091dHB1dEFkZHJlc3NlcyA9IFtFWFBPUlRfSU5fQy5wQWRkcmVzc2VzWzBdXTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pbmNsdWRlSW4od2FsbGV0QWRkcmVzc2VzLCB1dHhvT3V0cHV0QWRkcmVzc2VzKSwgdHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1ZhbGlkQWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCBtYWlubmV0IFAtY2hhaW4gYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcyhTRUVEX0FDQ09VTlQuYWRkcmVzc01haW5uZXQpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIHRlc3RuZXQgUC1jaGFpbiBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKFNFRURfQUNDT1VOVC5hZGRyZXNzVGVzdG5ldCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgTm9kZUlEIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoJ05vZGVJRC1hYmMxMjN4eXonKSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBhcnJheSBvZiB2YWxpZCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoRVhQT1JUX0lOX0MucEFkZHJlc3NlcyksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdGlsZGUtc2VwYXJhdGVkIGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvbWJpbmVkID0gRVhQT1JUX0lOX0MucEFkZHJlc3Nlcy5qb2luKCd+Jyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoY29tYmluZWQpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIGFkZHJlc3MgZm9ybWF0JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKCdpbnZhbGlkJyksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBhZGRyZXNzIHdpdGhvdXQgcHJlZml4JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKCdmbGFyZTFhYmMxMjMnKSwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZEJsb2NrSWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgMzItYnl0ZSBoZXggYmxvY2sgSUQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEJsb2NrSWQoU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXkpLCB0cnVlKTsgLy8gNjQgaGV4IGNoYXJzID0gMzIgYnl0ZXNcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIGxlbmd0aCBibG9jayBJRCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQmxvY2tJZChJTlZBTElEX1NIT1JUX0tFWVBBSVJfS0VZKSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGVtcHR5IGJsb2NrIElEJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRCbG9ja0lkKCcnKSwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZFB1YmxpY0tleScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCBjb21wcmVzc2VkIHB1YmxpYyBrZXkgc3RhcnRpbmcgd2l0aCAwMycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KFNFRURfQUNDT1VOVC5wdWJsaWNLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIGNvbXByZXNzZWQgcHVibGljIGtleSBzdGFydGluZyB3aXRoIDAyJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQUNDT1VOVF8xLnB1YmxpY0tleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgYW5vdGhlciB2YWxpZCBjb21wcmVzc2VkIHB1YmxpYyBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShBQ0NPVU5UXzIucHVibGljS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCB4cHViJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoU0VFRF9BQ0NPVU5ULnhQdWJsaWNLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIEFDQ09VTlRfMSB4cHViJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQUNDT1VOVF8xLnhQdWJsaWNLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIHNob3J0IHB1YmxpYyBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShJTlZBTElEX1NIT1JUX0tFWVBBSVJfS0VZKSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGNvbXByZXNzZWQga2V5IHdpdGggd3JvbmcgcHJlZml4JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZEtleSA9ICcwNScgKyBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KGludmFsaWRLZXkpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3Igbm9uLWhleCBwdWJsaWMga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZEtleSA9ICd6eicgKyBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KGludmFsaWRLZXkpLCBmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1ZhbGlkUHJpdmF0ZUtleScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCA2NC1jaGFyIGhleCBwcml2YXRlIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgQUNDT1VOVF8xIHByaXZhdGUga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KEFDQ09VTlRfMS5wcml2YXRlS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBBQ0NPVU5UXzIgcHJpdmF0ZSBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoQUNDT1VOVF8yLnByaXZhdGVLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIHhwcnYnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoU0VFRF9BQ0NPVU5ULnhQcml2YXRlS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciA2Ni1jaGFyIHByaXZhdGUga2V5IGVuZGluZyB3aXRoIDAxJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXh0ZW5kZWRLZXkgPSBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSArICcwMSc7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoZXh0ZW5kZWRLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciA2Ni1jaGFyIHByaXZhdGUga2V5IG5vdCBlbmRpbmcgd2l0aCAwMScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShJTlZBTElEX0xPTkdfS0VZUEFJUl9QUlYpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgaW52YWxpZCBzaG9ydCBwcml2YXRlIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShJTlZBTElEX1NIT1JUX0tFWVBBSVJfS0VZKSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIG5vbi1oZXggcHJpdmF0ZSBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkS2V5ID0gJ3p6JyArIFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LnNsaWNlKDIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KGludmFsaWRLZXkpLCBmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdhbGxIZXhDaGFycycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCBwcml2YXRlIGtleSBoZXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuYWxsSGV4Q2hhcnMoU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIHB1YmxpYyBrZXkgaGV4JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmFsbEhleENoYXJzKFNFRURfQUNDT1VOVC5wdWJsaWNLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIGhleCBzdHJpbmcgd2l0aCAweCBwcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuYWxsSGV4Q2hhcnMoRVhQT1JUX0lOX0MuY0hleEFkZHJlc3MpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIHNpZ25hdHVyZSBoZXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuYWxsSGV4Q2hhcnMoU0VFRF9BQ0NPVU5ULnNpZ25hdHVyZSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIG5vbi1oZXggY2hhcmFjdGVycycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5hbGxIZXhDaGFycygnZ2hpamtsJyksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBlbXB0eSBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuYWxsSGV4Q2hhcnMoJycpLCBmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjcmVhdGVTaWduYXR1cmUgYW5kIHZlcmlmeVNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIHZhbGlkIDY1LWJ5dGUgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LCAnaGV4Jyk7XG5cbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgYXNzZXJ0Lm9rKHNpZ25hdHVyZSBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2lnbmF0dXJlLmxlbmd0aCwgNjUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSB2YWxpZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXksICdoZXgnKTtcbiAgICAgIGNvbnN0IHB1YmxpY0tleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wdWJsaWNLZXksICdoZXgnKTtcblxuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHByaXZhdGVLZXkpO1xuICAgICAgY29uc3Qgc2lnT25seSA9IHNpZ25hdHVyZS5zbGljZSgwLCA2NCk7XG5cbiAgICAgIGNvbnN0IGlzVmFsaWQgPSB1dGlscy52ZXJpZnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnT25seSwgcHVibGljS2V5KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChpc1ZhbGlkLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHB1YmxpY0tleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wdWJsaWNLZXksICdoZXgnKTtcbiAgICAgIGNvbnN0IGludmFsaWRTaWduYXR1cmUgPSBCdWZmZXIuYWxsb2MoNjQpO1xuXG4gICAgICBjb25zdCBpc1ZhbGlkID0gdXRpbHMudmVyaWZ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIGludmFsaWRTaWduYXR1cmUsIHB1YmxpY0tleSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaXNWYWxpZCwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgc2lnbmF0dXJlIHdpdGggQUNDT1VOVF8xIGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oQUNDT1VOVF8xLnByaXZhdGVLZXksICdoZXgnKTtcblxuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHByaXZhdGVLZXkpO1xuXG4gICAgICBhc3NlcnQub2soc2lnbmF0dXJlIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaWduYXR1cmUubGVuZ3RoLCA2NSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjcmVhdGVOZXdTaWcnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSBzaWduYXR1cmUgZnJvbSB2YWxpZCBzaWduYXR1cmUgaGV4IHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZyA9IHV0aWxzLmNyZWF0ZU5ld1NpZyhTRUVEX0FDQ09VTlQuc2lnbmF0dXJlKTtcbiAgICAgIGFzc2VydC5vayhzaWcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSBzaWduYXR1cmUgZnJvbSBleHBvcnQgc2lnbmF0dXJlIGhleCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZ0hleCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeChFWFBPUlRfSU5fQy5zaWduYXR1cmVbMF0pO1xuICAgICAgY29uc3Qgc2lnID0gdXRpbHMuY3JlYXRlTmV3U2lnKHNpZ0hleCk7XG4gICAgICBhc3NlcnQub2soc2lnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFkIHNob3J0IGhleCBzdHJpbmdzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnSGV4ID0gSU5WQUxJRF9TSE9SVF9LRVlQQUlSX0tFWTtcbiAgICAgIGNvbnN0IHNpZyA9IHV0aWxzLmNyZWF0ZU5ld1NpZyhzaWdIZXgpO1xuICAgICAgYXNzZXJ0Lm9rKHNpZyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjcmVhdGVFbXB0eVNpZ1dpdGhBZGRyZXNzIGFuZCBnZXRBZGRyZXNzRnJvbUVtcHR5U2lnJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY3JlYXRlIGVtcHR5IHNpZ25hdHVyZSB3aXRoIGVtYmVkZGVkIEMtY2hhaW4gYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3NIZXggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoRVhQT1JUX0lOX0MuY0hleEFkZHJlc3MpO1xuICAgICAgY29uc3Qgc2lnID0gdXRpbHMuY3JlYXRlRW1wdHlTaWdXaXRoQWRkcmVzcyhhZGRyZXNzSGV4KTtcbiAgICAgIGFzc2VydC5vayhzaWcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHRyYWN0IGVtYmVkZGVkIGFkZHJlc3MgZnJvbSBlbXB0eSBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzSGV4ID0gdXRpbHMucmVtb3ZlSGV4UHJlZml4KEVYUE9SVF9JTl9DLmNIZXhBZGRyZXNzKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgY29uc3Qgc2lnID0gdXRpbHMuY3JlYXRlRW1wdHlTaWdXaXRoQWRkcmVzcyhhZGRyZXNzSGV4KTtcblxuICAgICAgLy8gR2V0IHNpZ25hdHVyZSBieXRlcyBhbmQgY29udmVydCB0byBoZXhcbiAgICAgIGNvbnN0IHNpZ0J5dGVzID0gc2lnLnRvQnl0ZXMoKTtcbiAgICAgIGNvbnN0IHNpZ0hleCA9IEJ1ZmZlci5mcm9tKHNpZ0J5dGVzKS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgIGNvbnN0IGV4dHJhY3RlZEFkZHJlc3MgPSB1dGlscy5nZXRBZGRyZXNzRnJvbUVtcHR5U2lnKHNpZ0hleCk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXh0cmFjdGVkQWRkcmVzcywgYWRkcmVzc0hleCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSAweCBwcmVmaXhlZCBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnID0gdXRpbHMuY3JlYXRlRW1wdHlTaWdXaXRoQWRkcmVzcyhFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcyk7XG4gICAgICBhc3NlcnQub2soc2lnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGVtcHR5IHN0cmluZyBmb3Igc2hvcnQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2hvcnRTaWcgPSBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleTsgLy8gNjQgY2hhcnMsIGxlc3MgdGhhbiAxMzBcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5nZXRBZGRyZXNzRnJvbUVtcHR5U2lnKHNob3J0U2lnKSwgJycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc2hhMjU2JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY29tcHV0ZSBTSEEyNTYgaGFzaCBvZiBtZXNzYWdlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgaGFzaCA9IHV0aWxzLnNoYTI1NihkYXRhKTtcblxuICAgICAgYXNzZXJ0Lm9rKGhhc2ggaW5zdGFuY2VvZiBCdWZmZXIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGhhc2gubGVuZ3RoLCAzMik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgY29uc2lzdGVudCBoYXNoIGZvciBzYW1lIGlucHV0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgaGFzaDEgPSB1dGlscy5zaGEyNTYoZGF0YSk7XG4gICAgICBjb25zdCBoYXNoMiA9IHV0aWxzLnNoYTI1NihkYXRhKTtcblxuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChoYXNoMSwgaGFzaDIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGRpZmZlcmVudCBoYXNoIGZvciBkaWZmZXJlbnQgaW5wdXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhMSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgZGF0YTIgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGhhc2gxID0gdXRpbHMuc2hhMjU2KGRhdGExKTtcbiAgICAgIGNvbnN0IGhhc2gyID0gdXRpbHMuc2hhMjU2KGRhdGEyKTtcblxuICAgICAgYXNzZXJ0Lm5vdERlZXBTdHJpY3RFcXVhbChoYXNoMSwgaGFzaDIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmFsaWRhdGVSYXdUcmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIG5vdCB0aHJvdyBmb3IgdmFsaWQgdW5zaWduZWQgaGV4IHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmF3VHggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoRVhQT1JUX0lOX0MudW5zaWduZWRIZXgpO1xuICAgICAgYXNzZXJ0LmRvZXNOb3RUaHJvdygoKSA9PiB1dGlscy52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKHJhd1R4KSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCB0aHJvdyBmb3IgdmFsaWQgc2lnbmVkIGhleCB0cmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJhd1R4ID0gdXRpbHMucmVtb3ZlSGV4UHJlZml4KEVYUE9SVF9JTl9DLnNpZ25lZEhleCk7XG4gICAgICBhc3NlcnQuZG9lc05vdFRocm93KCgpID0+IHV0aWxzLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24ocmF3VHgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IHRocm93IGZvciBpbXBvcnQgdHJhbnNhY3Rpb24gaGV4JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmF3VHggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoSU1QT1JUX0lOX1AudW5zaWduZWRIZXgpO1xuICAgICAgYXNzZXJ0LmRvZXNOb3RUaHJvdygoKSA9PiB1dGlscy52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKHJhd1R4KSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGZvciBlbXB0eSB0cmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMudmFsaWRhdGVSYXdUcmFuc2FjdGlvbignJyksIC9SYXcgdHJhbnNhY3Rpb24gaXMgZW1wdHkvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZm9yIG5vbi1oZXggdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oJ3h5ejEyMycpLCAvUmF3IHRyYW5zYWN0aW9uIGlzIG5vdCBoZXggc3RyaW5nLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdyZW1vdmVIZXhQcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZW1vdmUgMHggcHJlZml4IGZyb20gQy1jaGFpbiBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLnJlbW92ZUhleFByZWZpeChFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcyksIEVYUE9SVF9JTl9DLmNIZXhBZGRyZXNzLnNsaWNlKDIpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVtb3ZlIDB4IHByZWZpeCBmcm9tIHVuc2lnbmVkIGhleCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5yZW1vdmVIZXhQcmVmaXgoRVhQT1JUX0lOX0MudW5zaWduZWRIZXgpLCBFWFBPUlRfSU5fQy51bnNpZ25lZEhleC5zbGljZSgyKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBzdHJpbmcgdW5jaGFuZ2VkIGlmIG5vIHByZWZpeCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5yZW1vdmVIZXhQcmVmaXgoU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXkpLCBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBlbXB0eSBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMucmVtb3ZlSGV4UHJlZml4KCcnKSwgJycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnb3V0cHV0aWR4TnVtYmVyVG9CdWZmZXIgYW5kIG91dHB1dGlkeEJ1ZmZlclRvTnVtYmVyJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY29udmVydCBvdXRwdXQgaW5kZXggdG8gYnVmZmVyIGFuZCBiYWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgb3V0cHV0SWR4ID0gSU1QT1JUX0lOX1Aub3V0cHV0c1swXS5vdXRwdXRpZHg7XG4gICAgICBjb25zdCBidWZmZXIgPSB1dGlscy5vdXRwdXRpZHhOdW1iZXJUb0J1ZmZlcihvdXRwdXRJZHgpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHMub3V0cHV0aWR4QnVmZmVyVG9OdW1iZXIoYnVmZmVyKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgb3V0cHV0SWR4KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIG5vbmNlIHZhbHVlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgbm9uY2VTdHIgPSBFWFBPUlRfSU5fQy5ub25jZS50b1N0cmluZygpO1xuICAgICAgY29uc3QgYnVmZmVyID0gdXRpbHMub3V0cHV0aWR4TnVtYmVyVG9CdWZmZXIobm9uY2VTdHIpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHMub3V0cHV0aWR4QnVmZmVyVG9OdW1iZXIoYnVmZmVyKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgbm9uY2VTdHIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIDQtYnl0ZSBidWZmZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBidWZmZXIgPSB1dGlscy5vdXRwdXRpZHhOdW1iZXJUb0J1ZmZlcignMjU1Jyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYnVmZmVyLmxlbmd0aCwgNCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdhZGRyZXNzVG9TdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjb252ZXJ0IGFkZHJlc3MgYnVmZmVyIHRvIG1haW5uZXQgYmVjaDMyIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBTRUVEX0FDQ09VTlQuYWRkcmVzc01haW5uZXQ7XG4gICAgICBjb25zdCBhZGRyZXNzQnVmZmVyID0gdXRpbHMucGFyc2VBZGRyZXNzKGFkZHJlc3MpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHMuYWRkcmVzc1RvU3RyaW5nKCdmbGFyZScsICdQJywgYWRkcmVzc0J1ZmZlcik7XG5cbiAgICAgIGFzc2VydC5vayhyZXN1bHQuc3RhcnRzV2l0aCgnUC0nKSk7XG4gICAgICBhc3NlcnQub2socmVzdWx0LmluY2x1ZGVzKCdmbGFyZScpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29udmVydCBhZGRyZXNzIGJ1ZmZlciB0byB0ZXN0bmV0IGJlY2gzMiBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0O1xuICAgICAgY29uc3QgYWRkcmVzc0J1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhhZGRyZXNzKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzLmFkZHJlc3NUb1N0cmluZygnY29zdHdvJywgJ1AnLCBhZGRyZXNzQnVmZmVyKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3VsdC5zdGFydHNXaXRoKCdQLScpKTtcbiAgICAgIGFzc2VydC5vayhyZXN1bHQuaW5jbHVkZXMoJ2Nvc3R3bycpKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NiNThFbmNvZGUgYW5kIGNiNThEZWNvZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBlbmNvZGUgYW5kIGRlY29kZSB0YXJnZXQgY2hhaW4gSUQgY29ycmVjdGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZW5jb2RlZCA9IEVYUE9SVF9JTl9DLnRhcmdldENoYWluSWQ7XG4gICAgICBjb25zdCBkZWNvZGVkID0gdXRpbHMuY2I1OERlY29kZShlbmNvZGVkKTtcbiAgICAgIGNvbnN0IHJlRW5jb2RlZCA9IHV0aWxzLmNiNThFbmNvZGUoZGVjb2RlZCk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZUVuY29kZWQsIGVuY29kZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmNvZGUgYW5kIGRlY29kZSBzb3VyY2UgY2hhaW4gSUQgY29ycmVjdGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZW5jb2RlZCA9IElNUE9SVF9JTl9QLnNvdXJjZUNoYWluSWQ7XG4gICAgICBjb25zdCBkZWNvZGVkID0gdXRpbHMuY2I1OERlY29kZShlbmNvZGVkKTtcbiAgICAgIGNvbnN0IHJlRW5jb2RlZCA9IHV0aWxzLmNiNThFbmNvZGUoZGVjb2RlZCk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZUVuY29kZWQsIGVuY29kZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgaW52YWxpZCBjaGVja3N1bScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMuY2I1OERlY29kZSgnMTExMTExMTExMTExMScpLCAvSW52YWxpZCBjaGVja3N1bS8pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncGFyc2VBZGRyZXNzIGFuZCBzdHJpbmdUb0FkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBoZXggYWRkcmVzcyB3aXRoIDB4IHByZWZpeCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcyk7XG5cbiAgICAgIGFzc2VydC5vayhidWZmZXIgaW5zdGFuY2VvZiBCdWZmZXIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlci5sZW5ndGgsIDIwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgcmF3IGhleCBhZGRyZXNzIGZyb20gb3V0cHV0cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBJTVBPUlRfSU5fUC5vdXRwdXRzWzBdLmFkZHJlc3Nlc1swXTtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhhZGRyZXNzKTtcblxuICAgICAgYXNzZXJ0Lm9rKGJ1ZmZlciBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYnVmZmVyLmxlbmd0aCwgMjApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBtYWlubmV0IGJlY2gzMiBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVmZmVyID0gdXRpbHMucGFyc2VBZGRyZXNzKFNFRURfQUNDT1VOVC5hZGRyZXNzTWFpbm5ldCk7XG5cbiAgICAgIGFzc2VydC5vayhidWZmZXIgaW5zdGFuY2VvZiBCdWZmZXIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlci5sZW5ndGgsIDIwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgdGVzdG5ldCBiZWNoMzIgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhTRUVEX0FDQ09VTlQuYWRkcmVzc1Rlc3RuZXQpO1xuXG4gICAgICBhc3NlcnQub2soYnVmZmVyIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChidWZmZXIubGVuZ3RoLCAyMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIFAtY2hhaW4gYWRkcmVzc2VzIGZyb20gZXhwb3J0IGRhdGEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBFWFBPUlRfSU5fQy5wQWRkcmVzc2VzLmZvckVhY2goKGFkZHJlc3MpID0+IHtcbiAgICAgICAgY29uc3QgYnVmZmVyID0gdXRpbHMucGFyc2VBZGRyZXNzKGFkZHJlc3MpO1xuICAgICAgICBhc3NlcnQub2soYnVmZmVyIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlci5sZW5ndGgsIDIwKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgYWRkcmVzcyB3aXRob3V0IGRhc2ggc2VwYXJhdG9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB1dGlscy5wYXJzZUFkZHJlc3MoJ2ZsYXJlMWFiYycpLCAvVmFsaWQgYWRkcmVzcyBzaG91bGQgaW5jbHVkZSAtLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGZvciBpbnZhbGlkIEhSUCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMucGFyc2VBZGRyZXNzKCdQLWludmFsaWQxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE1ZXZ6bXknKSwgL0ludmFsaWQgSFJQLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdmbGFyZUlkU3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY3JlYXRlIElkIGZyb20gcHJpdmF0ZSBrZXkgaGV4IHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGlkID0gdXRpbHMuZmxhcmVJZFN0cmluZyhTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSk7XG4gICAgICBhc3NlcnQub2soaWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgSWQgZnJvbSBhc3NldCBJRCBoZXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBBc3NldCBJRCBpcyB0eXBpY2FsbHkgMzIgYnl0ZXMgKDY0IGhleCBjaGFycylcbiAgICAgIGNvbnN0IGFzc2V0SWRIZXggPSBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleTsgLy8gVXNpbmcgYXMgYSAzMi1ieXRlIGhleFxuICAgICAgY29uc3QgaWQgPSB1dGlscy5mbGFyZUlkU3RyaW5nKGFzc2V0SWRIZXgpO1xuICAgICAgYXNzZXJ0Lm9rKGlkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3JlY292ZXJ5U2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBwdWJsaWMga2V5IGZyb20gdmFsaWQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LCAnaGV4Jyk7XG5cbiAgICAgIC8vIENyZWF0ZSBzaWduYXR1cmUgdXNpbmcgdGhlIHNhbWUgcHJpdmF0ZSBrZXlcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgLy8gUmVjb3ZlciBwdWJsaWMga2V5XG4gICAgICBjb25zdCByZWNvdmVyZWRQdWJLZXkgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpO1xuXG4gICAgICBhc3NlcnQub2socmVjb3ZlcmVkUHViS2V5IGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZWNvdmVyZWRQdWJLZXkubGVuZ3RoLCAzMyk7IC8vIFNob3VsZCBiZSBjb21wcmVzc2VkIHB1YmxpYyBrZXkgKDMzIGJ5dGVzKVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHNhbWUgcHVibGljIGtleSBmb3Igc2FtZSBtZXNzYWdlIGFuZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXksICdoZXgnKTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgY29uc3QgcHViS2V5MSA9IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ25hdHVyZSk7XG4gICAgICBjb25zdCBwdWJLZXkyID0gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnbmF0dXJlKTtcblxuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChwdWJLZXkxLCBwdWJLZXkyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBwdWJsaWMga2V5IHRoYXQgbWF0Y2hlcyBvcmlnaW5hbCBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXksICdoZXgnKTtcblxuICAgICAgLy8gR2V0IG9yaWdpbmFsIHB1YmxpYyBrZXlcbiAgICAgIGNvbnN0IG9yaWdpbmFsUHViS2V5ID0gQnVmZmVyLmZyb20oZWNjLnBvaW50RnJvbVNjYWxhcihwcml2YXRlS2V5LCB0cnVlKSBhcyBVaW50OEFycmF5KTtcblxuICAgICAgLy8gQ3JlYXRlIHNpZ25hdHVyZSBhbmQgcmVjb3ZlciBwdWJsaWMga2V5XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG4gICAgICBjb25zdCByZWNvdmVyZWRQdWJLZXkgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpO1xuXG4gICAgICAvLyBDb252ZXJ0IGJvdGggdG8gaGV4IHN0cmluZ3MgZm9yIGNvbXBhcmlzb25cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZWNvdmVyZWRQdWJLZXkudG9TdHJpbmcoJ2hleCcpLCBvcmlnaW5hbFB1YktleS50b1N0cmluZygnaGV4JykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHB1YmxpYyBrZXkgdXNpbmcgQUNDT1VOVF8xIGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oQUNDT1VOVF8xLnByaXZhdGVLZXksICdoZXgnKTtcblxuICAgICAgY29uc3Qgb3JpZ2luYWxQdWJLZXkgPSBCdWZmZXIuZnJvbShlY2MucG9pbnRGcm9tU2NhbGFyKHByaXZhdGVLZXksIHRydWUpIGFzIFVpbnQ4QXJyYXkpO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG4gICAgICBjb25zdCByZWNvdmVyZWRQdWJLZXkgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVjb3ZlcmVkUHViS2V5LnRvU3RyaW5nKCdoZXgnKSwgb3JpZ2luYWxQdWJLZXkudG9TdHJpbmcoJ2hleCcpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGludmFsaWQgc2lnbmF0dXJlIGxlbmd0aCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGludmFsaWRTaWduYXR1cmUgPSBCdWZmZXIuZnJvbShJTlZBTElEX1NIT1JUX0tFWVBBSVJfS0VZLCAnaGV4Jyk7XG5cbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgaW52YWxpZFNpZ25hdHVyZSksIC9GYWlsZWQgdG8gcmVjb3ZlciBzaWduYXR1cmUvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIHNpZ25hdHVyZSB3aXRoIGludmFsaWQgcmVjb3ZlcnkgcGFyYW1ldGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gQnVmZmVyLmFsbG9jKDY1KTsgLy8gVmFsaWQgbGVuZ3RoIGJ1dCBhbGwgemVyb3MgLSBpbnZhbGlkIHNpZ25hdHVyZVxuXG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ25hdHVyZSksIC9GYWlsZWQgdG8gcmVjb3ZlciBzaWduYXR1cmUvKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
|