@bitgo/sdk-coin-flrp 1.3.4 → 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.
Files changed (131) hide show
  1. package/dist/src/flrp.d.ts +9 -16
  2. package/dist/src/flrp.d.ts.map +1 -1
  3. package/dist/src/flrp.js +49 -75
  4. package/dist/src/index.d.ts +0 -1
  5. package/dist/src/index.d.ts.map +1 -1
  6. package/dist/src/index.js +1 -2
  7. package/dist/src/lib/ExportInCTxBuilder.d.ts +51 -0
  8. package/dist/src/lib/ExportInCTxBuilder.d.ts.map +1 -0
  9. package/dist/src/lib/ExportInCTxBuilder.js +188 -0
  10. package/dist/src/lib/ExportInPTxBuilder.d.ts +47 -0
  11. package/dist/src/lib/ExportInPTxBuilder.d.ts.map +1 -0
  12. package/dist/src/lib/ExportInPTxBuilder.js +273 -0
  13. package/dist/src/lib/ImportInCTxBuilder.d.ts +48 -0
  14. package/dist/src/lib/ImportInCTxBuilder.d.ts.map +1 -0
  15. package/dist/src/lib/ImportInCTxBuilder.js +215 -0
  16. package/dist/src/lib/ImportInPTxBuilder.d.ts +33 -0
  17. package/dist/src/lib/ImportInPTxBuilder.d.ts.map +1 -0
  18. package/dist/src/lib/ImportInPTxBuilder.js +180 -0
  19. package/dist/src/lib/atomicInCTransactionBuilder.d.ts +18 -16
  20. package/dist/src/lib/atomicInCTransactionBuilder.d.ts.map +1 -1
  21. package/dist/src/lib/atomicInCTransactionBuilder.js +38 -36
  22. package/dist/src/lib/atomicTransactionBuilder.d.ts +42 -79
  23. package/dist/src/lib/atomicTransactionBuilder.d.ts.map +1 -1
  24. package/dist/src/lib/atomicTransactionBuilder.js +138 -281
  25. package/dist/src/lib/iface.d.ts +38 -61
  26. package/dist/src/lib/iface.d.ts.map +1 -1
  27. package/dist/src/lib/iface.js +13 -14
  28. package/dist/src/lib/index.d.ts +2 -3
  29. package/dist/src/lib/index.d.ts.map +1 -1
  30. package/dist/src/lib/index.js +5 -6
  31. package/dist/src/lib/keyPair.d.ts +1 -1
  32. package/dist/src/lib/keyPair.d.ts.map +1 -1
  33. package/dist/src/lib/keyPair.js +9 -5
  34. package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts +29 -67
  35. package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts.map +1 -1
  36. package/dist/src/lib/permissionlessValidatorTxBuilder.js +89 -205
  37. package/dist/src/lib/transaction.d.ts +11 -71
  38. package/dist/src/lib/transaction.d.ts.map +1 -1
  39. package/dist/src/lib/transaction.js +255 -204
  40. package/dist/src/lib/transactionBuilder.d.ts +56 -34
  41. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  42. package/dist/src/lib/transactionBuilder.js +113 -70
  43. package/dist/src/lib/transactionBuilderFactory.d.ts +50 -30
  44. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  45. package/dist/src/lib/transactionBuilderFactory.js +129 -72
  46. package/dist/src/lib/utils.d.ts +67 -153
  47. package/dist/src/lib/utils.d.ts.map +1 -1
  48. package/dist/src/lib/utils.js +178 -397
  49. package/dist/test/resources/account.d.ts +2 -0
  50. package/dist/test/resources/account.d.ts.map +1 -1
  51. package/dist/test/resources/account.js +3 -1
  52. package/dist/test/resources/transactionData/exportInC.d.ts +20 -0
  53. package/dist/test/resources/transactionData/exportInC.d.ts.map +1 -0
  54. package/dist/test/resources/transactionData/exportInC.js +34 -0
  55. package/dist/test/resources/transactionData/exportInP.d.ts +69 -0
  56. package/dist/test/resources/transactionData/exportInP.d.ts.map +1 -0
  57. package/dist/test/resources/transactionData/exportInP.js +140 -0
  58. package/dist/test/resources/transactionData/importInC.d.ts +27 -0
  59. package/dist/test/resources/transactionData/importInC.d.ts.map +1 -0
  60. package/dist/test/resources/transactionData/importInC.js +44 -0
  61. package/dist/test/resources/transactionData/importInP.d.ts +35 -0
  62. package/dist/test/resources/transactionData/importInP.d.ts.map +1 -0
  63. package/dist/test/resources/transactionData/importInP.js +58 -0
  64. package/dist/test/unit/flrp.js +449 -68
  65. package/dist/test/unit/lib/exportInCTxBuilder.js +95 -513
  66. package/dist/test/unit/lib/exportInPTxBuilder.d.ts +1 -1
  67. package/dist/test/unit/lib/exportInPTxBuilder.d.ts.map +1 -1
  68. package/dist/test/unit/lib/exportInPTxBuilder.js +110 -366
  69. package/dist/test/unit/lib/importInCTxBuilder.d.ts +1 -1
  70. package/dist/test/unit/lib/importInCTxBuilder.d.ts.map +1 -1
  71. package/dist/test/unit/lib/importInCTxBuilder.js +40 -251
  72. package/dist/test/unit/lib/importInPTxBuilder.d.ts +1 -1
  73. package/dist/test/unit/lib/importInPTxBuilder.d.ts.map +1 -1
  74. package/dist/test/unit/lib/importInPTxBuilder.js +61 -489
  75. package/dist/test/unit/lib/signFlowTestSuit.d.ts +20 -0
  76. package/dist/test/unit/lib/signFlowTestSuit.d.ts.map +1 -0
  77. package/dist/test/unit/lib/signFlowTestSuit.js +89 -0
  78. package/dist/test/unit/lib/utils.js +367 -279
  79. package/dist/tsconfig.tsbuildinfo +1 -1
  80. package/package.json +11 -8
  81. package/dist/src/iface.d.ts +0 -25
  82. package/dist/src/iface.d.ts.map +0 -1
  83. package/dist/src/iface.js +0 -3
  84. package/dist/src/lib/constants.d.ts +0 -170
  85. package/dist/src/lib/constants.d.ts.map +0 -1
  86. package/dist/src/lib/constants.js +0 -227
  87. package/dist/src/lib/delegatorTxBuilder.d.ts +0 -58
  88. package/dist/src/lib/delegatorTxBuilder.d.ts.map +0 -1
  89. package/dist/src/lib/delegatorTxBuilder.js +0 -224
  90. package/dist/src/lib/errors.d.ts +0 -8
  91. package/dist/src/lib/errors.d.ts.map +0 -1
  92. package/dist/src/lib/errors.js +0 -19
  93. package/dist/src/lib/exportInCTxBuilder.d.ts +0 -77
  94. package/dist/src/lib/exportInCTxBuilder.d.ts.map +0 -1
  95. package/dist/src/lib/exportInCTxBuilder.js +0 -199
  96. package/dist/src/lib/exportInPTxBuilder.d.ts +0 -30
  97. package/dist/src/lib/exportInPTxBuilder.d.ts.map +0 -1
  98. package/dist/src/lib/exportInPTxBuilder.js +0 -120
  99. package/dist/src/lib/importInCTxBuilder.d.ts +0 -67
  100. package/dist/src/lib/importInCTxBuilder.d.ts.map +0 -1
  101. package/dist/src/lib/importInCTxBuilder.js +0 -403
  102. package/dist/src/lib/importInPTxBuilder.d.ts +0 -73
  103. package/dist/src/lib/importInPTxBuilder.d.ts.map +0 -1
  104. package/dist/src/lib/importInPTxBuilder.js +0 -464
  105. package/dist/src/lib/types.d.ts +0 -78
  106. package/dist/src/lib/types.d.ts.map +0 -1
  107. package/dist/src/lib/types.js +0 -5
  108. package/dist/src/lib/validatorTxBuilder.d.ts +0 -40
  109. package/dist/src/lib/validatorTxBuilder.d.ts.map +0 -1
  110. package/dist/src/lib/validatorTxBuilder.js +0 -180
  111. package/dist/test/unit/delegatorTxBuilder.test.d.ts +0 -2
  112. package/dist/test/unit/delegatorTxBuilder.test.d.ts.map +0 -1
  113. package/dist/test/unit/delegatorTxBuilder.test.js +0 -233
  114. package/dist/test/unit/lib/atomicTransactionBuilder.d.ts +0 -2
  115. package/dist/test/unit/lib/atomicTransactionBuilder.d.ts.map +0 -1
  116. package/dist/test/unit/lib/atomicTransactionBuilder.js +0 -222
  117. package/dist/test/unit/lib/transaction.d.ts +0 -2
  118. package/dist/test/unit/lib/transaction.d.ts.map +0 -1
  119. package/dist/test/unit/lib/transaction.js +0 -460
  120. package/dist/test/unit/permissionlessValidatorTxBuilder.test.d.ts +0 -2
  121. package/dist/test/unit/permissionlessValidatorTxBuilder.test.d.ts.map +0 -1
  122. package/dist/test/unit/permissionlessValidatorTxBuilder.test.js +0 -271
  123. package/dist/test/unit/smoke.d.ts +0 -2
  124. package/dist/test/unit/smoke.d.ts.map +0 -1
  125. package/dist/test/unit/smoke.js +0 -23
  126. package/dist/test/unit/transactionBuilder.test.d.ts +0 -2
  127. package/dist/test/unit/transactionBuilder.test.d.ts.map +0 -1
  128. package/dist/test/unit/transactionBuilder.test.js +0 -114
  129. package/dist/test/unit/validatorTxBuilder.test.d.ts +0 -2
  130. package/dist/test/unit/validatorTxBuilder.test.d.ts.map +0 -1
  131. package/dist/test/unit/validatorTxBuilder.test.js +0 -293
@@ -34,332 +34,420 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const statics_1 = require("@bitgo/statics");
37
- const sdk_core_1 = require("@bitgo/sdk-core");
38
37
  const assert = __importStar(require("assert"));
39
38
  const utils_1 = require("../../../src/lib/utils");
40
- const lib_1 = require("../../../src/lib");
41
- const testData = __importStar(require("../../resources/account"));
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");
42
43
  describe('Utils', function () {
43
44
  let utils;
44
- const network = statics_1.coins.get('tflrp').network;
45
+ const network = statics_1.coins.get('flrp').network;
45
46
  beforeEach(function () {
46
47
  utils = new utils_1.Utils();
47
48
  });
48
49
  describe('includeIn', function () {
49
- it('should return true when all wallet addresses are in output addresses', function () {
50
- const walletAddresses = [testData.ACCOUNT_1.addressMainnet, testData.ACCOUNT_3.address];
51
- const outputAddresses = [
52
- testData.ACCOUNT_1.addressMainnet,
53
- testData.ACCOUNT_3.address,
54
- testData.ACCOUNT_4.address,
55
- ];
56
- assert.strictEqual(utils.includeIn(walletAddresses, outputAddresses), true);
57
- });
58
- it('should return false when not all wallet addresses are in output addresses', function () {
59
- const walletAddresses = [testData.ACCOUNT_1.addressMainnet, testData.ACCOUNT_3.address];
60
- const outputAddresses = [testData.ACCOUNT_3.address, testData.ACCOUNT_4.address];
61
- assert.strictEqual(utils.includeIn(walletAddresses, outputAddresses), false);
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);
62
59
  });
63
60
  it('should return true for empty wallet addresses', function () {
64
61
  const walletAddresses = [];
65
- const outputAddresses = [testData.ACCOUNT_1.addressMainnet, testData.ACCOUNT_3.address];
66
- assert.strictEqual(utils.includeIn(walletAddresses, outputAddresses), true);
67
- });
68
- it('should return false when wallet address not found in empty output addresses', function () {
69
- const walletAddresses = [testData.ACCOUNT_1.addressMainnet];
70
- const outputAddresses = [];
71
- assert.strictEqual(utils.includeIn(walletAddresses, outputAddresses), false);
62
+ const utxoOutputAddresses = [exportInC_1.EXPORT_IN_C.pAddresses[0]];
63
+ assert.strictEqual(utils.includeIn(walletAddresses, utxoOutputAddresses), true);
72
64
  });
73
65
  });
74
66
  describe('isValidAddress', function () {
75
- it('should validate single valid Flare addresses', function () {
76
- const validAddresses = [
77
- testData.SEED_ACCOUNT.addressMainnet,
78
- testData.SEED_ACCOUNT.addressTestnet,
79
- testData.ACCOUNT_1.addressMainnet,
80
- testData.ACCOUNT_1.addressTestnet,
81
- ];
82
- validAddresses.forEach((addr) => {
83
- const result = utils.isValidAddress(addr);
84
- assert.strictEqual(typeof result, 'boolean');
85
- assert.strictEqual(result, true);
86
- });
67
+ it('should return true for valid mainnet P-chain address', function () {
68
+ assert.strictEqual(utils.isValidAddress(account_1.SEED_ACCOUNT.addressMainnet), true);
87
69
  });
88
- it('should validate array of addresses', function () {
89
- const addresses = [
90
- testData.SEED_ACCOUNT.addressMainnet,
91
- testData.SEED_ACCOUNT.addressTestnet,
92
- testData.ACCOUNT_1.addressMainnet,
93
- testData.ACCOUNT_1.addressTestnet,
94
- ];
95
- const result = utils.isValidAddress(addresses);
96
- assert.strictEqual(typeof result, 'boolean');
97
- assert.strictEqual(result, true);
98
- });
99
- it('should validate addresses separated by ~', function () {
100
- const addressString = testData.SEED_ACCOUNT.addressTestnet +
101
- '~' +
102
- testData.ACCOUNT_1.addressTestnet +
103
- '~' +
104
- testData.ACCOUNT_4.address;
105
- const result = utils.isValidAddress(addressString);
106
- assert.strictEqual(typeof result, 'boolean');
107
- assert.strictEqual(result, true);
108
- });
109
- it('should reject obviously invalid addresses', function () {
110
- const invalidAddresses = [
111
- '',
112
- 'invalid',
113
- '123',
114
- 'bitcoin1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq',
115
- 'eth:0x1234567890123456789012345678901234567890',
116
- ];
117
- invalidAddresses.forEach((addr) => {
118
- const result = utils.isValidAddress(addr);
119
- assert.strictEqual(typeof result, 'boolean');
120
- assert.strictEqual(result, false);
121
- });
70
+ it('should return true for valid testnet P-chain address', function () {
71
+ assert.strictEqual(utils.isValidAddress(account_1.SEED_ACCOUNT.addressTestnet), true);
122
72
  });
123
- });
124
- describe('isValidAddressRegex', function () {
125
- it('should test address format with regex', function () {
126
- const testAddress = testData.SEED_ACCOUNT.addressTestnet;
127
- const result = utils['isValidAddressRegex'](testAddress);
128
- assert.strictEqual(typeof result, 'boolean');
129
- assert.strictEqual(result, true);
73
+ it('should return true for valid NodeID address', function () {
74
+ assert.strictEqual(utils.isValidAddress('NodeID-abc123xyz'), true);
130
75
  });
131
- it('should reject empty strings', function () {
132
- const result = utils['isValidAddressRegex']('');
133
- assert.strictEqual(result, false);
76
+ it('should return true for array of valid addresses', function () {
77
+ assert.strictEqual(utils.isValidAddress(exportInC_1.EXPORT_IN_C.pAddresses), true);
134
78
  });
135
- });
136
- describe('isValidTransactionId', function () {
137
- it('should return true for valid transaction IDs', function () {
138
- const validTxIds = [
139
- '6wewzpFrTDPGmFfRJoT9YyGVxsRDxQXu6pz6LSXLf2eU6StBe',
140
- '3SuMRBREQwhsR1qQYjSpHPNgwV7keXQbKBgP8jULnKdz7ppEV',
141
- '2ExGh7o1c4gQtQrzDt2BvJxg42FswGWaLY7NEXCqcejPxjSTij',
142
- ];
143
- validTxIds.forEach((txId) => {
144
- const result = utils.isValidTransactionId(txId);
145
- assert.strictEqual(typeof result, 'boolean');
146
- assert.strictEqual(result, true);
147
- });
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);
148
82
  });
149
- it('should return false for invalid transaction IDs', function () {
150
- const invalidTxIds = [
151
- '',
152
- '123',
153
- 'invalidtxid',
154
- '0xaf32fd2276be99560e5218d79f9c3d2f29c126fa61b60b08a42c1be430f877df',
155
- ];
156
- invalidTxIds.forEach((txId) => {
157
- const result = utils.isValidTransactionId(txId);
158
- assert.strictEqual(typeof result, 'boolean');
159
- assert.strictEqual(result, false);
160
- });
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);
161
88
  });
162
89
  });
163
90
  describe('isValidBlockId', function () {
164
- it('should return true for valid block IDs', function () {
165
- const validTxIds = [
166
- 'mg3B2HsQ8Pqe63J2arXi6uD3wGJV1fgCNe5bRufDToAgVRVBp',
167
- 'rVWodN2iTugUMckkgf8ntXcoyuduey24ZgXCMi66mrFegcV4R',
168
- '2MrU9G74ra9QX99wQRxvKrbzV93i6Ua7KgHMETVMSYoJq2tb5g',
169
- ];
170
- validTxIds.forEach((txId) => {
171
- const result = utils.isValidBlockId(txId);
172
- assert.strictEqual(typeof result, 'boolean');
173
- assert.strictEqual(result, true);
174
- });
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
175
93
  });
176
- it('should return false for invalid block IDs', function () {
177
- const invalidTxIds = [
178
- '',
179
- '123',
180
- 'invalidtxid',
181
- '0xa2379e3804e603357e3a670f2696852aae8ffe2f22a7b79f7fba86f78c8f3290',
182
- ];
183
- invalidTxIds.forEach((txId) => {
184
- const result = utils.isValidBlockId(txId);
185
- assert.strictEqual(typeof result, 'boolean');
186
- assert.strictEqual(result, false);
187
- });
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);
188
127
  });
189
128
  });
190
- describe('isValidSignature', function () {
191
- it('should throw NotImplementedError', function () {
192
- assert.throws(() => utils.isValidSignature('signature123'), sdk_core_1.NotImplementedError, 'isValidSignature not implemented');
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);
193
155
  });
194
156
  });
195
- describe('createSignature', function () {
196
- it('should create signature using secp256k1', function () {
197
- const message = Buffer.from(testData.SEED_ACCOUNT.message, 'utf8');
198
- const privateKey = Buffer.from(testData.SEED_ACCOUNT.privateKey, 'hex');
199
- const signature = utils.createSignature(network, message, privateKey).toString('hex');
200
- assert.ok(signature.length > 0);
201
- assert.strictEqual(signature, testData.SEED_ACCOUNT.signature);
202
- });
203
- it('should create different signatures for different messages', function () {
204
- const message1 = Buffer.from('message 1', 'utf8');
205
- const message2 = Buffer.from('message 2', 'utf8');
206
- const privateKey = Buffer.from(testData.SEED_ACCOUNT.privateKey, 'hex');
207
- const sig1 = utils.createSignature(network, message1, privateKey);
208
- const sig2 = utils.createSignature(network, message2, privateKey);
209
- assert.notDeepStrictEqual(sig1, sig2);
210
- });
211
- it('should throw error for invalid private key', function () {
212
- const message = Buffer.from('hello world', 'utf8');
213
- const invalidPrivateKey = Buffer.from('invalid', 'utf8');
214
- assert.throws(() => utils.createSignature(network, message, invalidPrivateKey), /Failed to create signature/);
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);
215
175
  });
216
176
  });
217
- describe('verifySignature', function () {
218
- it('should verify valid signature', function () {
219
- const message = Buffer.from(testData.SEED_ACCOUNT.message, 'utf8');
220
- const privateKey = Buffer.from(testData.SEED_ACCOUNT.privateKey, 'hex');
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');
221
189
  const signature = utils.createSignature(network, message, privateKey);
222
- const publicKey = Buffer.from(testData.SEED_ACCOUNT.publicKey, 'hex'); // Compressed public key format
223
- const isValid = utils.verifySignature(network, message, signature, publicKey);
224
- assert.strictEqual(typeof isValid, 'boolean');
190
+ const sigOnly = signature.slice(0, 64);
191
+ const isValid = utils.verifySignature(network, message, sigOnly, publicKey);
225
192
  assert.strictEqual(isValid, true);
226
193
  });
227
194
  it('should return false for invalid signature', function () {
228
- const message = Buffer.from('hello world', 'utf8');
229
- const invalidSignature = Buffer.from('invalid signature', 'utf8');
230
- const publicKey = Buffer.from('02' + '0'.repeat(62), 'hex');
231
- const result = utils.verifySignature(network, message, invalidSignature, publicKey);
232
- assert.strictEqual(result, false);
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);
233
207
  });
234
208
  });
235
- describe('recoverySignature', function () {
236
- it('should recover signature', () => {
237
- const compressed = true;
238
- const keyPair = new lib_1.KeyPair({ prv: testData.SEED_ACCOUNT.flrpPrivateKey });
239
- const prv = keyPair.getPrivateKey();
240
- const pub = keyPair.getPublicKey({ compressed });
241
- const message = Buffer.from(testData.SEED_ACCOUNT.message, 'hex');
242
- const signature = utils.createSignature(network, message, prv);
243
- utils.recoverySignature(network, message, signature).should.deepEqual(pub);
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);
244
213
  });
245
- it('should recover same public key for same message and signature', function () {
246
- const message = Buffer.from(testData.SEED_ACCOUNT.message, 'utf8');
247
- const privateKey = Buffer.from(testData.SEED_ACCOUNT.privateKey, 'hex');
248
- const signature = utils.createSignature(network, message, privateKey);
249
- const pubKey1 = utils.recoverySignature(network, message, signature);
250
- const pubKey2 = utils.recoverySignature(network, message, signature);
251
- assert.deepStrictEqual(pubKey1, pubKey2);
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);
252
218
  });
253
- it('should throw error for invalid signature', function () {
254
- const message = Buffer.from(testData.SEED_ACCOUNT.message, 'utf8');
255
- const invalidSignature = Buffer.from('invalid signature', 'utf8');
256
- assert.throws(() => utils.recoverySignature(network, message, invalidSignature), /Failed to recover signature/);
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);
257
223
  });
258
- it('should throw error for empty message', function () {
259
- const message = Buffer.alloc(0);
260
- const signature = Buffer.alloc(65); // Empty but valid length signature (65 bytes: 64 signature + 1 recovery param)
261
- assert.throws(() => utils.recoverySignature(network, message, signature), /Failed to recover signature/);
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);
262
320
  });
263
321
  });
264
- describe('address parsing utilities', function () {
265
- it('should handle address separator constants', function () {
266
- const { ADDRESS_SEPARATOR } = require('../../../src/lib/iface');
267
- assert.strictEqual(ADDRESS_SEPARATOR, '~');
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'));
268
336
  });
269
- it('should handle input separator constants', function () {
270
- const { INPUT_SEPARATOR } = require('../../../src/lib/iface');
271
- assert.strictEqual(INPUT_SEPARATOR, ':');
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/);
272
353
  });
273
354
  });
274
- describe('error handling', function () {
275
- it('should properly extend base utils', function () {
276
- // Test that utils class exists and has expected methods
277
- assert.ok('isValidAddress' in utils);
278
- assert.ok('includeIn' in utils);
279
- assert.ok('createSignature' in utils);
280
- assert.ok('verifySignature' in utils);
281
- });
282
- it('should handle parsing errors gracefully', function () {
283
- // Test that utils can handle malformed input without crashing
284
- // Note: These may throw errors, which is acceptable behavior
285
- try {
286
- utils.isValidAddress(null);
287
- utils.isValidAddress(undefined);
288
- }
289
- catch (error) {
290
- // Expected behavior - utils should handle or throw meaningful errors
291
- assert.ok(error instanceof Error);
292
- }
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/);
293
389
  });
294
390
  });
295
- describe('constants validation', function () {
296
- it('should have correct constant values', function () {
297
- const constants = require('../../../src/lib/constants');
298
- assert.strictEqual(typeof constants.DECODED_BLOCK_ID_LENGTH, 'number');
299
- assert.strictEqual(typeof constants.SHORT_PUB_KEY_LENGTH, 'number');
300
- assert.strictEqual(typeof constants.COMPRESSED_PUBLIC_KEY_LENGTH, 'number');
301
- assert.strictEqual(typeof constants.UNCOMPRESSED_PUBLIC_KEY_LENGTH, 'number');
302
- assert.strictEqual(typeof constants.RAW_PRIVATE_KEY_LENGTH, 'number');
303
- assert.strictEqual(typeof constants.SUFFIXED_PRIVATE_KEY_LENGTH, 'number');
304
- assert.strictEqual(typeof constants.PRIVATE_KEY_COMPRESSED_SUFFIX, 'string');
305
- assert.strictEqual(typeof constants.OUTPUT_INDEX_HEX_LENGTH, 'number');
306
- assert.ok(constants.ADDRESS_REGEX instanceof RegExp);
307
- assert.ok(constants.HEX_REGEX instanceof RegExp);
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);
308
401
  });
309
402
  });
310
- describe('Memo Utilities', function () {
311
- it('should convert string to bytes', function () {
312
- const text = 'Hello Flare';
313
- const bytes = utils.stringToBytes(text);
314
- assert.ok(bytes instanceof Uint8Array);
315
- assert.strictEqual(utils.bytesToString(bytes), text);
316
- });
317
- it('should handle UTF-8 strings', function () {
318
- const text = 'Hello 世界 🌍';
319
- const bytes = utils.stringToBytes(text);
320
- assert.strictEqual(utils.bytesToString(bytes), text);
321
- });
322
- it('should create memo bytes from string', function () {
323
- const text = 'Memo text';
324
- const bytes = utils.createMemoBytes(text);
325
- assert.ok(bytes instanceof Uint8Array);
326
- assert.strictEqual(utils.parseMemoBytes(bytes), text);
327
- });
328
- it('should create memo bytes from JSON object', function () {
329
- const obj = { type: 'payment', amount: 1000 };
330
- const bytes = utils.createMemoBytes(obj);
331
- const parsed = utils.parseMemoBytes(bytes);
332
- assert.strictEqual(parsed, JSON.stringify(obj));
333
- });
334
- it('should handle Uint8Array input', function () {
335
- const originalBytes = new Uint8Array([1, 2, 3, 4]);
336
- const bytes = utils.createMemoBytes(originalBytes);
337
- assert.deepStrictEqual(bytes, originalBytes);
338
- });
339
- it('should throw error for invalid memo type', function () {
340
- assert.throws(() => {
341
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
342
- utils.createMemoBytes(123);
343
- }, /Invalid memo format/);
344
- });
345
- it('should parse empty memo', function () {
346
- const emptyBytes = new Uint8Array([]);
347
- const parsed = utils.parseMemoBytes(emptyBytes);
348
- assert.strictEqual(parsed, '');
349
- });
350
- it('should validate memo size', function () {
351
- const smallMemo = new Uint8Array([1, 2, 3]);
352
- const largeMemo = new Uint8Array(5000);
353
- assert.strictEqual(utils.validateMemoSize(smallMemo), true);
354
- assert.strictEqual(utils.validateMemoSize(largeMemo), false);
355
- assert.strictEqual(utils.validateMemoSize(largeMemo, 6000), true);
356
- });
357
- it('should handle special characters in memo', function () {
358
- const specialText = 'Special: \n\t\r\0';
359
- const bytes = utils.createMemoBytes(specialText);
360
- const parsed = utils.parseMemoBytes(bytes);
361
- assert.strictEqual(parsed, specialText);
403
+ describe('recoverySignature', function () {
404
+ it('should recover public key from valid signature', function () {
405
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
406
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
407
+ // Create signature using the same private key
408
+ const signature = utils.createSignature(network, message, privateKey);
409
+ // Recover public key
410
+ const recoveredPubKey = utils.recoverySignature(network, message, signature);
411
+ assert.ok(recoveredPubKey instanceof Buffer);
412
+ assert.strictEqual(recoveredPubKey.length, 33); // Should be compressed public key (33 bytes)
413
+ });
414
+ it('should recover same public key for same message and signature', function () {
415
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
416
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
417
+ const signature = utils.createSignature(network, message, privateKey);
418
+ const pubKey1 = utils.recoverySignature(network, message, signature);
419
+ const pubKey2 = utils.recoverySignature(network, message, signature);
420
+ assert.deepStrictEqual(pubKey1, pubKey2);
421
+ });
422
+ it('should recover public key that matches original key', function () {
423
+ const message = Buffer.from(account_1.SEED_ACCOUNT.message, 'utf8');
424
+ const privateKey = Buffer.from(account_1.SEED_ACCOUNT.privateKey, 'hex');
425
+ // Get original public key
426
+ const originalPubKey = Buffer.from(secp256k1_1.ecc.pointFromScalar(privateKey, true));
427
+ // Create signature and recover public key
428
+ const signature = utils.createSignature(network, message, privateKey);
429
+ const recoveredPubKey = utils.recoverySignature(network, message, signature);
430
+ // Convert both to hex strings for comparison
431
+ assert.strictEqual(recoveredPubKey.toString('hex'), originalPubKey.toString('hex'));
432
+ });
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');
444
+ assert.throws(() => utils.recoverySignature(network, message, invalidSignature), /Failed to recover signature/);
445
+ });
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
449
+ assert.throws(() => utils.recoverySignature(network, message, signature), /Failed to recover signature/);
362
450
  });
363
451
  });
364
452
  });
365
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNENBQXFEO0FBQ3JELDhDQUFzRDtBQUN0RCwrQ0FBaUM7QUFDakMsa0RBQStDO0FBQy9DLDBDQUEyQztBQUMzQyxrRUFBb0Q7QUFFcEQsUUFBUSxDQUFDLE9BQU8sRUFBRTtJQUNoQixJQUFJLEtBQVksQ0FBQztJQUNqQixNQUFNLE9BQU8sR0FBRyxlQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQXVCLENBQUM7SUFFM0QsVUFBVSxDQUFDO1FBQ1QsS0FBSyxHQUFHLElBQUksYUFBSyxFQUFFLENBQUM7SUFDdEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsV0FBVyxFQUFFO1FBQ3BCLEVBQUUsQ0FBQyxzRUFBc0UsRUFBRTtZQUN6RSxNQUFNLGVBQWUsR0FBRyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDeEYsTUFBTSxlQUFlLEdBQUc7Z0JBQ3RCLFFBQVEsQ0FBQyxTQUFTLENBQUMsY0FBYztnQkFDakMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxPQUFPO2dCQUMxQixRQUFRLENBQUMsU0FBUyxDQUFDLE9BQU87YUFDM0IsQ0FBQztZQUVGLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsZUFBZSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMkVBQTJFLEVBQUU7WUFDOUUsTUFBTSxlQUFlLEdBQUcsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLE9B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SyxDQUFDLENBQUM7WUFFM0MsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29pbnMsIEZsYXJlTmV0d29yayB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcbmltcG9ydCB7IE5vdEltcGxlbWVudGVkRXJyb3IgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0ICogYXMgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgeyBVdGlscyB9IGZyb20gJy4uLy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuaW1wb3J0IHsgS2V5UGFpciB9IGZyb20gJy4uLy4uLy4uL3NyYy9saWInO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vLi4vcmVzb3VyY2VzL2FjY291bnQnO1xuXG5kZXNjcmliZSgnVXRpbHMnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCB1dGlsczogVXRpbHM7XG4gIGNvbnN0IG5ldHdvcmsgPSBjb2lucy5nZXQoJ3RmbHJwJykubmV0d29yayBhcyBGbGFyZU5ldHdvcms7XG5cbiAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgdXRpbHMgPSBuZXcgVXRpbHMoKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2luY2x1ZGVJbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIHdoZW4gYWxsIHdhbGxldCBhZGRyZXNzZXMgYXJlIGluIG91dHB1dCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRBZGRyZXNzZXMgPSBbdGVzdERhdGEuQUNDT1VOVF8xLmFkZHJlc3NNYWlubmV0LCB0ZXN0RGF0YS5BQ0NPVU5UXzMuYWRkcmVzc107XG4gICAgICBjb25zdCBvdXRwdXRBZGRyZXNzZXMgPSBbXG4gICAgICAgIHRlc3REYXRhLkFDQ09VTlRfMS5hZGRyZXNzTWFpbm5ldCxcbiAgICAgICAgdGVzdERhdGEuQUNDT1VOVF8zLmFkZHJlc3MsXG4gICAgICAgIHRlc3REYXRhLkFDQ09VTlRfNC5hZGRyZXNzLFxuICAgICAgXTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmluY2x1ZGVJbih3YWxsZXRBZGRyZXNzZXMsIG91dHB1dEFkZHJlc3NlcyksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2Ugd2hlbiBub3QgYWxsIHdhbGxldCBhZGRyZXNzZXMgYXJlIGluIG91dHB1dCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRBZGRyZXNzZXMgPSBbdGVzdERhdGEuQUNDT1VOVF8xLmFkZHJlc3NNYWlubmV0LCB0ZXN0RGF0YS5BQ0NPVU5UXzMuYWRkcmVzc107XG4gICAgICBjb25zdCBvdXRwdXRBZGRyZXNzZXMgPSBbdGVzdERhdGEuQUNDT1VOVF8zLmFkZHJlc3MsIHRlc3REYXRhLkFDQ09VTlRfNC5hZGRyZXNzXTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmluY2x1ZGVJbih3YWxsZXRBZGRyZXNzZXMsIG91dHB1dEFkZHJlc3NlcyksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIGVtcHR5IHdhbGxldCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRBZGRyZXNzZXM6IHN0cmluZ1tdID0gW107XG4gICAgICBjb25zdCBvdXRwdXRBZGRyZXNzZXMgPSBbdGVzdERhdGEuQUNDT1VOVF8xLmFkZHJlc3NNYWlubmV0LCB0ZXN0RGF0YS5BQ0NPVU5UXzMuYWRkcmVzc107XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pbmNsdWRlSW4od2FsbGV0QWRkcmVzc2VzLCBvdXRwdXRBZGRyZXNzZXMpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIHdoZW4gd2FsbGV0IGFkZHJlc3Mgbm90IGZvdW5kIGluIGVtcHR5IG91dHB1dCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YWxsZXRBZGRyZXNzZXMgPSBbdGVzdERhdGEuQUNDT1VOVF8xLmFkZHJlc3NNYWlubmV0XTtcbiAgICAgIGNvbnN0IG91dHB1dEFkZHJlc3Nlczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmluY2x1ZGVJbih3YWxsZXRBZGRyZXNzZXMsIG91dHB1dEFkZHJlc3NlcyksIGZhbHNlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRBZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgc2luZ2xlIHZhbGlkIEZsYXJlIGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZhbGlkQWRkcmVzc2VzID0gW1xuICAgICAgICB0ZXN0RGF0YS5TRUVEX0FDQ09VTlQuYWRkcmVzc01haW5uZXQsXG4gICAgICAgIHRlc3REYXRhLlNFRURfQUNDT1VOVC5hZGRyZXNzVGVzdG5ldCxcbiAgICAgICAgdGVzdERhdGEuQUNDT1VOVF8xLmFkZHJlc3NNYWlubmV0LFxuICAgICAgICB0ZXN0RGF0YS5BQ0NPVU5UXzEuYWRkcmVzc1Rlc3RuZXQsXG4gICAgICBdO1xuXG4gICAgICB2YWxpZEFkZHJlc3Nlcy5mb3JFYWNoKChhZGRyKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHIpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHlwZW9mIHJlc3VsdCwgJ2Jvb2xlYW4nKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgdHJ1ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgYXJyYXkgb2YgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzc2VzID0gW1xuICAgICAgICB0ZXN0RGF0YS5TRUVEX0FDQ09VTlQuYWRkcmVzc01haW5uZXQsXG4gICAgICAgIHRlc3REYXRhLlNFRURfQUNDT1VOVC5hZGRyZXNzVGVzdG5ldCxcbiAgICAgICAgdGVzdERhdGEuQUNDT1VOVF8xLmFkZHJlc3NNYWlubmV0LFxuICAgICAgICB0ZXN0RGF0YS5BQ0NPVU5UXzEuYWRkcmVzc1Rlc3RuZXQsXG4gICAgICBdO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSB1dGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzZXMpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiByZXN1bHQsICdib29sZWFuJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgYWRkcmVzc2VzIHNlcGFyYXRlZCBieSB+JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzc1N0cmluZyA9XG4gICAgICAgIHRlc3REYXRhLlNFRURfQUNDT1VOVC5hZGRyZXNzVGVzdG5ldCArXG4gICAgICAgICd+JyArXG4gICAgICAgIHRlc3REYXRhLkFDQ09VTlRfMS5hZGRyZXNzVGVzdG5ldCArXG4gICAgICAgICd+JyArXG4gICAgICAgIHRlc3REYXRhLkFDQ09VTlRfNC5hZGRyZXNzO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSB1dGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyZXNzU3RyaW5nKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgcmVzdWx0LCAnYm9vbGVhbicpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlamVjdCBvYnZpb3VzbHkgaW52YWxpZCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkQWRkcmVzc2VzID0gW1xuICAgICAgICAnJyxcbiAgICAgICAgJ2ludmFsaWQnLFxuICAgICAgICAnMTIzJyxcbiAgICAgICAgJ2JpdGNvaW4xcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcScsXG4gICAgICAgICdldGg6MHgxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwJyxcbiAgICAgIF07XG5cbiAgICAgIGludmFsaWRBZGRyZXNzZXMuZm9yRWFjaCgoYWRkcikgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB1dGlscy5pc1ZhbGlkQWRkcmVzcyhhZGRyKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiByZXN1bHQsICdib29sZWFuJyk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIGZhbHNlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZEFkZHJlc3NSZWdleCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHRlc3QgYWRkcmVzcyBmb3JtYXQgd2l0aCByZWdleCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRlc3RBZGRyZXNzID0gdGVzdERhdGEuU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0O1xuICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHNbJ2lzVmFsaWRBZGRyZXNzUmVnZXgnXSh0ZXN0QWRkcmVzcyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHlwZW9mIHJlc3VsdCwgJ2Jvb2xlYW4nKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3QgZW1wdHkgc3RyaW5ncycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzWydpc1ZhbGlkQWRkcmVzc1JlZ2V4J10oJycpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZFRyYW5zYWN0aW9uSWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgdHJhbnNhY3Rpb24gSURzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdmFsaWRUeElkcyA9IFtcbiAgICAgICAgJzZ3ZXd6cEZyVERQR21GZlJKb1Q5WXlHVnhzUkR4UVh1NnB6NkxTWExmMmVVNlN0QmUnLFxuICAgICAgICAnM1N1TVJCUkVRd2hzUjFxUVlqU3BIUE5nd1Y3a2VYUWJLQmdQOGpVTG5LZHo3cHBFVicsXG4gICAgICAgICcyRXhHaDdvMWM0Z1F0UXJ6RHQyQnZKeGc0MkZzd0dXYUxZN05FWENxY2VqUHhqU1RpaicsXG4gICAgICBdO1xuXG4gICAgICB2YWxpZFR4SWRzLmZvckVhY2goKHR4SWQpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHMuaXNWYWxpZFRyYW5zYWN0aW9uSWQodHhJZCk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgcmVzdWx0LCAnYm9vbGVhbicpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LCB0cnVlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIHRyYW5zYWN0aW9uIElEcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGludmFsaWRUeElkcyA9IFtcbiAgICAgICAgJycsXG4gICAgICAgICcxMjMnLFxuICAgICAgICAnaW52YWxpZHR4aWQnLFxuICAgICAgICAnMHhhZjMyZmQyMjc2YmU5OTU2MGU1MjE4ZDc5ZjljM2QyZjI5YzEyNmZhNjFiNjBiMDhhNDJjMWJlNDMwZjg3N2RmJyxcbiAgICAgIF07XG5cbiAgICAgIGludmFsaWRUeElkcy5mb3JFYWNoKCh0eElkKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzLmlzVmFsaWRUcmFuc2FjdGlvbklkKHR4SWQpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHlwZW9mIHJlc3VsdCwgJ2Jvb2xlYW4nKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgZmFsc2UpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1ZhbGlkQmxvY2tJZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCBibG9jayBJRHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB2YWxpZFR4SWRzID0gW1xuICAgICAgICAnbWczQjJIc1E4UHFlNjNKMmFyWGk2dUQzd0dKVjFmZ0NOZTViUnVmRFRvQWdWUlZCcCcsXG4gICAgICAgICdyVldvZE4yaVR1Z1VNY2trZ2Y4bnRYY295dWR1ZXkyNFpnWENNaTY2bXJGZWdjVjRSJyxcbiAgICAgICAgJzJNclU5Rzc0cmE5UVg5OXdRUnh2S3JielY5M2k2VWE3S2dITUVUVk1TWW9KcTJ0YjVnJyxcbiAgICAgIF07XG5cbiAgICAgIHZhbGlkVHhJZHMuZm9yRWFjaCgodHhJZCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB1dGlscy5pc1ZhbGlkQmxvY2tJZCh0eElkKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiByZXN1bHQsICdib29sZWFuJyk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZXN1bHQsIHRydWUpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGludmFsaWQgYmxvY2sgSURzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZFR4SWRzID0gW1xuICAgICAgICAnJyxcbiAgICAgICAgJzEyMycsXG4gICAgICAgICdpbnZhbGlkdHhpZCcsXG4gICAgICAgICcweGEyMzc5ZTM4MDRlNjAzMzU3ZTNhNjcwZjI2OTY4NTJhYWU4ZmZlMmYyMmE3Yjc5ZjdmYmE4NmY3OGM4ZjMyOTAnLFxuICAgICAgXTtcblxuICAgICAgaW52YWxpZFR4SWRzLmZvckVhY2goKHR4SWQpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHMuaXNWYWxpZEJsb2NrSWQodHhJZCk7XG4gICAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgcmVzdWx0LCAnYm9vbGVhbicpO1xuICAgICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVzdWx0LCBmYWxzZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2lzVmFsaWRTaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBOb3RJbXBsZW1lbnRlZEVycm9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4gdXRpbHMuaXNWYWxpZFNpZ25hdHVyZSgnc2lnbmF0dXJlMTIzJyksXG4gICAgICAgIE5vdEltcGxlbWVudGVkRXJyb3IsXG4gICAgICAgICdpc1ZhbGlkU2lnbmF0dXJlIG5vdCBpbXBsZW1lbnRlZCdcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjcmVhdGVTaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgc2lnbmF0dXJlIHVzaW5nIHNlY3AyNTZrMScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSh0ZXN0RGF0YS5TRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbSh0ZXN0RGF0YS5TRUVEX0FDQ09VTlQucHJpdmF0ZUtleSwgJ2hleCcpO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICBhc3NlcnQub2soc2lnbmF0dXJlLmxlbmd0aCA+IDApO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHNpZ25hdHVyZSwgdGVzdERhdGEuU0VFRF9BQ0NPVU5ULnNpZ25hdHVyZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBkaWZmZXJlbnQgc2lnbmF0dXJlcyBmb3IgZGlmZmVyZW50IG1lc3NhZ2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZTEgPSBCdWZmZXIuZnJvbSgnbWVzc2FnZSAxJywgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2UyID0gQnVmZmVyLmZyb20oJ21lc3NhZ2UgMicsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20odGVzdERhdGEuU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXksICdoZXgnKTtcblxuICAgICAgY29uc3Qgc2lnMSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlMSwgcHJpdmF0ZUtleSk7XG4gICAgICBjb25zdCBzaWcyID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UyLCBwcml2YXRlS2V5KTtcblxuICAgICAgYXNzZXJ0Lm5vdERlZXBTdHJpY3RFcXVhbChzaWcxLCBzaWcyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGludmFsaWQgcHJpdmF0ZSBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oJ2hlbGxvIHdvcmxkJywgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGludmFsaWRQcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oJ2ludmFsaWQnLCAndXRmOCcpO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBpbnZhbGlkUHJpdmF0ZUtleSksIC9GYWlsZWQgdG8gY3JlYXRlIHNpZ25hdHVyZS8pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmVyaWZ5U2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdmVyaWZ5IHZhbGlkIHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSh0ZXN0RGF0YS5TRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbSh0ZXN0RGF0YS5TRUVEX0FDQ09VTlQucHJpdmF0ZUtleSwgJ2hleCcpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHByaXZhdGVLZXkpO1xuICAgICAgY29uc3QgcHVibGljS2V5ID0gQnVmZmVyLmZyb20odGVzdERhdGEuU0VFRF9BQ0NPVU5ULnB1YmxpY0tleSwgJ2hleCcpOyAvLyBDb21wcmVzc2VkIHB1YmxpYyBrZXkgZm9ybWF0XG4gICAgICBjb25zdCBpc1ZhbGlkID0gdXRpbHMudmVyaWZ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ25hdHVyZSwgcHVibGljS2V5KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgaXNWYWxpZCwgJ2Jvb2xlYW4nKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChpc1ZhbGlkLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSgnaGVsbG8gd29ybGQnLCAndXRmOCcpO1xuICAgICAgY29uc3QgaW52YWxpZFNpZ25hdHVyZSA9IEJ1ZmZlci5mcm9tKCdpbnZhbGlkIHNpZ25hdHVyZScsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwdWJsaWNLZXkgPSBCdWZmZXIuZnJvbSgnMDInICsgJzAnLnJlcGVhdCg2MiksICdoZXgnKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzLnZlcmlmeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBpbnZhbGlkU2lnbmF0dXJlLCBwdWJsaWNLZXkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncmVjb3ZlcnlTaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHNpZ25hdHVyZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbXByZXNzZWQgPSB0cnVlO1xuICAgICAgY29uc3Qga2V5UGFpciA9IG5ldyBLZXlQYWlyKHsgcHJ2OiB0ZXN0RGF0YS5TRUVEX0FDQ09VTlQuZmxycFByaXZhdGVLZXkgfSk7XG4gICAgICBjb25zdCBwcnYgPSBrZXlQYWlyLmdldFByaXZhdGVLZXkoKTtcbiAgICAgIGNvbnN0IHB1YiA9IGtleVBhaXIuZ2V0UHVibGljS2V5KHsgY29tcHJlc3NlZCB9KTtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSh0ZXN0RGF0YS5TRUVEX0FDQ09VTlQubWVzc2FnZSwgJ2hleCcpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHBydiEpO1xuICAgICAgdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnbmF0dXJlKS5zaG91bGQuZGVlcEVxdWFsKHB1Yik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlY292ZXIgc2FtZSBwdWJsaWMga2V5IGZvciBzYW1lIG1lc3NhZ2UgYW5kIHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbSh0ZXN0RGF0YS5TRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHByaXZhdGVLZXkgPSBCdWZmZXIuZnJvbSh0ZXN0RGF0YS5TRUVEX0FDQ09VTlQucHJpdmF0ZUtleSwgJ2hleCcpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHByaXZhdGVLZXkpO1xuXG4gICAgICBjb25zdCBwdWJLZXkxID0gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnbmF0dXJlKTtcbiAgICAgIGNvbnN0IHB1YktleTIgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpO1xuXG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKHB1YktleTEsIHB1YktleTIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgaW52YWxpZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20odGVzdERhdGEuU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBpbnZhbGlkU2lnbmF0dXJlID0gQnVmZmVyLmZyb20oJ2ludmFsaWQgc2lnbmF0dXJlJywgJ3V0ZjgnKTtcblxuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBpbnZhbGlkU2lnbmF0dXJlKSwgL0ZhaWxlZCB0byByZWNvdmVyIHNpZ25hdHVyZS8pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciBmb3IgZW1wdHkgbWVzc2FnZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuYWxsb2MoMCk7XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSBCdWZmZXIuYWxsb2MoNjUpOyAvLyBFbXB0eSBidXQgdmFsaWQgbGVuZ3RoIHNpZ25hdHVyZSAoNjUgYnl0ZXM6IDY0IHNpZ25hdHVyZSArIDEgcmVjb3ZlcnkgcGFyYW0pXG5cbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnbmF0dXJlKSwgL0ZhaWxlZCB0byByZWNvdmVyIHNpZ25hdHVyZS8pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYWRkcmVzcyBwYXJzaW5nIHV0aWxpdGllcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBhZGRyZXNzIHNlcGFyYXRvciBjb25zdGFudHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB7IEFERFJFU1NfU0VQQVJBVE9SIH0gPSByZXF1aXJlKCcuLi8uLi8uLi9zcmMvbGliL2lmYWNlJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoQUREUkVTU19TRVBBUkFUT1IsICd+Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBpbnB1dCBzZXBhcmF0b3IgY29uc3RhbnRzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgeyBJTlBVVF9TRVBBUkFUT1IgfSA9IHJlcXVpcmUoJy4uLy4uLy4uL3NyYy9saWIvaWZhY2UnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChJTlBVVF9TRVBBUkFUT1IsICc6Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdlcnJvciBoYW5kbGluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHByb3Blcmx5IGV4dGVuZCBiYXNlIHV0aWxzJywgZnVuY3Rpb24gKCkge1xuICAgICAgLy8gVGVzdCB0aGF0IHV0aWxzIGNsYXNzIGV4aXN0cyBhbmQgaGFzIGV4cGVjdGVkIG1ldGhvZHNcbiAgICAgIGFzc2VydC5vaygnaXNWYWxpZEFkZHJlc3MnIGluIHV0aWxzKTtcbiAgICAgIGFzc2VydC5vaygnaW5jbHVkZUluJyBpbiB1dGlscyk7XG4gICAgICBhc3NlcnQub2soJ2NyZWF0ZVNpZ25hdHVyZScgaW4gdXRpbHMpO1xuICAgICAgYXNzZXJ0Lm9rKCd2ZXJpZnlTaWduYXR1cmUnIGluIHV0aWxzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIHBhcnNpbmcgZXJyb3JzIGdyYWNlZnVsbHknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBUZXN0IHRoYXQgdXRpbHMgY2FuIGhhbmRsZSBtYWxmb3JtZWQgaW5wdXQgd2l0aG91dCBjcmFzaGluZ1xuICAgICAgLy8gTm90ZTogVGhlc2UgbWF5IHRocm93IGVycm9ycywgd2hpY2ggaXMgYWNjZXB0YWJsZSBiZWhhdmlvclxuICAgICAgdHJ5IHtcbiAgICAgICAgdXRpbHMuaXNWYWxpZEFkZHJlc3MobnVsbCBhcyB1bmtub3duIGFzIHN0cmluZyk7XG4gICAgICAgIHV0aWxzLmlzVmFsaWRBZGRyZXNzKHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIHN0cmluZyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBFeHBlY3RlZCBiZWhhdmlvciAtIHV0aWxzIHNob3VsZCBoYW5kbGUgb3IgdGhyb3cgbWVhbmluZ2Z1bCBlcnJvcnNcbiAgICAgICAgYXNzZXJ0Lm9rKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnY29uc3RhbnRzIHZhbGlkYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3QgY29uc3RhbnQgdmFsdWVzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgY29uc3RhbnRzID0gcmVxdWlyZSgnLi4vLi4vLi4vc3JjL2xpYi9jb25zdGFudHMnKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiBjb25zdGFudHMuREVDT0RFRF9CTE9DS19JRF9MRU5HVEgsICdudW1iZXInKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgY29uc3RhbnRzLlNIT1JUX1BVQl9LRVlfTEVOR1RILCAnbnVtYmVyJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHlwZW9mIGNvbnN0YW50cy5DT01QUkVTU0VEX1BVQkxJQ19LRVlfTEVOR1RILCAnbnVtYmVyJyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodHlwZW9mIGNvbnN0YW50cy5VTkNPTVBSRVNTRURfUFVCTElDX0tFWV9MRU5HVEgsICdudW1iZXInKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgY29uc3RhbnRzLlJBV19QUklWQVRFX0tFWV9MRU5HVEgsICdudW1iZXInKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgY29uc3RhbnRzLlNVRkZJWEVEX1BSSVZBVEVfS0VZX0xFTkdUSCwgJ251bWJlcicpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHR5cGVvZiBjb25zdGFudHMuUFJJVkFURV9LRVlfQ09NUFJFU1NFRF9TVUZGSVgsICdzdHJpbmcnKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh0eXBlb2YgY29uc3RhbnRzLk9VVFBVVF9JTkRFWF9IRVhfTEVOR1RILCAnbnVtYmVyJyk7XG4gICAgICBhc3NlcnQub2soY29uc3RhbnRzLkFERFJFU1NfUkVHRVggaW5zdGFuY2VvZiBSZWdFeHApO1xuICAgICAgYXNzZXJ0Lm9rKGNvbnN0YW50cy5IRVhfUkVHRVggaW5zdGFuY2VvZiBSZWdFeHApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnTWVtbyBVdGlsaXRpZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjb252ZXJ0IHN0cmluZyB0byBieXRlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRleHQgPSAnSGVsbG8gRmxhcmUnO1xuICAgICAgY29uc3QgYnl0ZXMgPSB1dGlscy5zdHJpbmdUb0J5dGVzKHRleHQpO1xuXG4gICAgICBhc3NlcnQub2soYnl0ZXMgaW5zdGFuY2VvZiBVaW50OEFycmF5KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5ieXRlc1RvU3RyaW5nKGJ5dGVzKSwgdGV4dCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBVVEYtOCBzdHJpbmdzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGV4dCA9ICdIZWxsbyDkuJbnlYwg8J+MjSc7XG4gICAgICBjb25zdCBieXRlcyA9IHV0aWxzLnN0cmluZ1RvQnl0ZXModGV4dCk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5ieXRlc1RvU3RyaW5nKGJ5dGVzKSwgdGV4dCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBtZW1vIGJ5dGVzIGZyb20gc3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdGV4dCA9ICdNZW1vIHRleHQnO1xuICAgICAgY29uc3QgYnl0ZXMgPSB1dGlscy5jcmVhdGVNZW1vQnl0ZXModGV4dCk7XG5cbiAgICAgIGFzc2VydC5vayhieXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLnBhcnNlTWVtb0J5dGVzKGJ5dGVzKSwgdGV4dCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBtZW1vIGJ5dGVzIGZyb20gSlNPTiBvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBvYmogPSB7IHR5cGU6ICdwYXltZW50JywgYW1vdW50OiAxMDAwIH07XG4gICAgICBjb25zdCBieXRlcyA9IHV0aWxzLmNyZWF0ZU1lbW9CeXRlcyhvYmopO1xuICAgICAgY29uc3QgcGFyc2VkID0gdXRpbHMucGFyc2VNZW1vQnl0ZXMoYnl0ZXMpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLCBKU09OLnN0cmluZ2lmeShvYmopKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIFVpbnQ4QXJyYXkgaW5wdXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBvcmlnaW5hbEJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoWzEsIDIsIDMsIDRdKTtcbiAgICAgIGNvbnN0IGJ5dGVzID0gdXRpbHMuY3JlYXRlTWVtb0J5dGVzKG9yaWdpbmFsQnl0ZXMpO1xuXG4gICAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKGJ5dGVzLCBvcmlnaW5hbEJ5dGVzKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGludmFsaWQgbWVtbyB0eXBlJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgIHV0aWxzLmNyZWF0ZU1lbW9CeXRlcygxMjMgYXMgYW55KTtcbiAgICAgIH0sIC9JbnZhbGlkIG1lbW8gZm9ybWF0Lyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIGVtcHR5IG1lbW8nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBlbXB0eUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoW10pO1xuICAgICAgY29uc3QgcGFyc2VkID0gdXRpbHMucGFyc2VNZW1vQnl0ZXMoZW1wdHlCeXRlcyk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChwYXJzZWQsICcnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgbWVtbyBzaXplJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc21hbGxNZW1vID0gbmV3IFVpbnQ4QXJyYXkoWzEsIDIsIDNdKTtcbiAgICAgIGNvbnN0IGxhcmdlTWVtbyA9IG5ldyBVaW50OEFycmF5KDUwMDApO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMudmFsaWRhdGVNZW1vU2l6ZShzbWFsbE1lbW8pLCB0cnVlKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy52YWxpZGF0ZU1lbW9TaXplKGxhcmdlTWVtbyksIGZhbHNlKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy52YWxpZGF0ZU1lbW9TaXplKGxhcmdlTWVtbywgNjAwMCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgc3BlY2lhbCBjaGFyYWN0ZXJzIGluIG1lbW8nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBzcGVjaWFsVGV4dCA9ICdTcGVjaWFsOiBcXG5cXHRcXHJcXDAnO1xuICAgICAgY29uc3QgYnl0ZXMgPSB1dGlscy5jcmVhdGVNZW1vQnl0ZXMoc3BlY2lhbFRleHQpO1xuICAgICAgY29uc3QgcGFyc2VkID0gdXRpbHMucGFyc2VNZW1vQnl0ZXMoYnl0ZXMpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocGFyc2VkLCBzcGVjaWFsVGV4dCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
453
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNENBQXFEO0FBQ3JELCtDQUFpQztBQUNqQyxrREFBK0M7QUFDL0MscURBT2lDO0FBQ2pDLGdEQUF1QztBQUN2Qyx5RUFBd0U7QUFDeEUseUVBQXdFO0FBRXhFLFFBQVEsQ0FBQyxPQUFPLEVBQUU7SUFDaEIsSUFBSSxLQUFZLENBQUM7SUFDakIsTUFBTSxPQUFPLEdBQUcsZUFBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUF1QixDQUFDO0lBRTFELFVBQVUsQ0FBQztRQUNULEtBQUssR0FBRyxJQUFJLGFBQUssRUFBRSxDQUFDO0lBQ3RCLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLFdBQVcsRUFBRTtRQUNwQixFQUFFLENBQUMsMkVBQTJFLEVBQUU7WUFDOUUsTUFBTSxlQUFlLEdBQUcsQ0FBQyx1QkFBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSx1QkFBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9FLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxHQUFHLHVCQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxtQkFBbUIsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2xGLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGlGQUFpRixFQUFFO1lBQ3BGLE1BQU0sZUFBZSxHQUFHLENBQUMsdUJBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsbUJBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN2RSxNQUFNLG1CQUFtQixHQUFHLENBQUMsdUJBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsdUJBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuRixNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLG1CQUFtQixDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbkYsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0NBQStDLEVBQUU7WUFDbEQsTUFBTSxlQUFlLEdBQWEsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyx1QkFBVyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hELE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsbUJBQW1CLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNsRixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGdCQUFnQixFQUFFO1FBQ3pCLEVBQUUsQ0FBQyxzREFBc0QsRUFBRTtZQUN6RCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsc0JBQVksQ0FBQyxjQUFjLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM5RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzREFBc0QsRUFBRTtZQUN6RCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsc0JBQVksQ0FBQyxjQUFjLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM5RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw2Q0FBNkMsRUFBRTtZQUNoRCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsa0JBQWtCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNyRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxpREFBaUQsRUFBRTtZQUNwRCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsdUJBQVcsQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN6RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRTtZQUNyRCxNQUFNLFFBQVEsR0FBRyx1QkFBVyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbEQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzNELENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGdEQUFnRCxFQUFFO1lBQ25ELE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM3RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxnREFBZ0QsRUFBRTtZQUNuRCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbEUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtRQUN6QixFQUFFLENBQUMsbURBQW1ELEVBQUU7WUFDdEQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLHNCQUFZLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQywwQkFBMEI7UUFDckcsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaURBQWlELEVBQUU7WUFDcEQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLG1DQUF5QixDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDN0UsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsd0NBQXdDLEVBQUU7WUFDM0MsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3RELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsa0JBQWtCLEVBQUU7UUFDM0IsRUFBRSxDQUFDLHFFQUFxRSxFQUFFO1lBQ3hFLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLHNCQUFZLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDM0UsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMscUVBQXFFLEVBQUU7WUFDeEUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsbUJBQVMsQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN4RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0REFBNEQsRUFBRTtZQUMvRCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxtQkFBUyxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1DQUFtQyxFQUFFO1lBQ3RDLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLHNCQUFZLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDNUUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsdUNBQXVDLEVBQUU7WUFDMUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsbUJBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN6RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxrREFBa0QsRUFBRTtZQUNyRCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxtQ0FBeUIsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9FLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDBEQUEwRCxFQUFFO1lBQzdELE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxzQkFBWSxDQUFDLFVBQVUsQ0FBQztZQUNsRCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNoRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0Q0FBNEMsRUFBRTtZQUMvQyxNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsc0JBQVksQ0FBQyxVQUFVLENBQUM7WUFDbEQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxtQkFBbUIsRUFBRTtRQUM1QixFQUFFLENBQUMsc0RBQXNELEVBQUU7WUFDekQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsc0JBQVksQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM3RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRTtZQUNqRCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxtQkFBUyxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzFFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLG1CQUFTLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDMUUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsbUNBQW1DLEVBQUU7WUFDdEMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsc0JBQVksQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM5RSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywyREFBMkQsRUFBRTtZQUM5RCxNQUFNLFdBQVcsR0FBRyxzQkFBWSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7WUFDbkQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDakUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0VBQWdFLEVBQUU7WUFDbkUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsa0NBQXdCLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxtREFBbUQsRUFBRTtZQUN0RCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxtQ0FBeUIsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hGLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDZDQUE2QyxFQUFFO1lBQ2hELE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxzQkFBWSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0QsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDakUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxhQUFhLEVBQUU7UUFDdEIsRUFBRSxDQUFDLDhDQUE4QyxFQUFFO1lBQ2pELE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxzQkFBWSxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3ZFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDZDQUE2QyxFQUFFO1lBQ2hELE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxzQkFBWSxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3RFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGtEQUFrRCxFQUFFO1lBQ3JELE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyx1QkFBVyxDQUFDLFdBQVcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3ZFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDRDQUE0QyxFQUFFO1lBQy9DLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxzQkFBWSxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3RFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDRDQUE0QyxFQUFFO1lBQy9DLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxzQ0FBc0MsRUFBRTtZQUN6QyxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbkQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxxQ0FBcUMsRUFBRTtRQUM5QyxFQUFFLENBQUMseUNBQXlDLEVBQUU7WUFDNUMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMxRCxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFZLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBRS9ELE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUV0RSxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsWUFBWSxNQUFNLENBQUMsQ0FBQztZQUN2QyxNQUFNLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsaUNBQWlDLEVBQUU7WUFDcEMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMxRCxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFZLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQy9ELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0JBQVksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFN0QsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3RFLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRXZDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDNUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMkNBQTJDLEVBQUU7WUFDOUMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxzQkFBWSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMxRCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsSUFB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Q0FBQyxDQUFDO1lBQzFELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxpREFBaUQ7WUFFckYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLENBQUMsRUFBRSw2QkFBNkIsQ0FBQyxDQUFDO1FBQzNHLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvaW5zLCBGbGFyZU5ldHdvcmsgfSBmcm9tICdAYml0Z28vc3RhdGljcyc7XG5pbXBvcnQgKiBhcyBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IFV0aWxzIH0gZnJvbSAnLi4vLi4vLi4vc3JjL2xpYi91dGlscyc7XG5pbXBvcnQge1xuICBTRUVEX0FDQ09VTlQsXG4gIEFDQ09VTlRfMSxcbiAgQUNDT1VOVF8yLFxuICBBQ0NPVU5UXzMsXG4gIElOVkFMSURfU0hPUlRfS0VZUEFJUl9LRVksXG4gIElOVkFMSURfTE9OR19LRVlQQUlSX1BSVixcbn0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL2FjY291bnQnO1xuaW1wb3J0IHsgZWNjIH0gZnJvbSAnQGJpdGdvL3NlY3AyNTZrMSc7XG5pbXBvcnQgeyBFWFBPUlRfSU5fQyB9IGZyb20gJy4uLy4uL3Jlc291cmNlcy90cmFuc2FjdGlvbkRhdGEvZXhwb3J0SW5DJztcbmltcG9ydCB7IElNUE9SVF9JTl9QIH0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL3RyYW5zYWN0aW9uRGF0YS9pbXBvcnRJblAnO1xuXG5kZXNjcmliZSgnVXRpbHMnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCB1dGlsczogVXRpbHM7XG4gIGNvbnN0IG5ldHdvcmsgPSBjb2lucy5nZXQoJ2ZscnAnKS5uZXR3b3JrIGFzIEZsYXJlTmV0d29yaztcblxuICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICB1dGlscyA9IG5ldyBVdGlscygpO1xuICB9KTtcblxuICBkZXNjcmliZSgnaW5jbHVkZUluJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgd2hlbiBhbGwgd2FsbGV0IGFkZHJlc3NlcyBhcmUgaW4gVVRYTyBvdXRwdXQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0QWRkcmVzc2VzID0gW0VYUE9SVF9JTl9DLnBBZGRyZXNzZXNbMF0sIEVYUE9SVF9JTl9DLnBBZGRyZXNzZXNbMV1dO1xuICAgICAgY29uc3QgdXR4b091dHB1dEFkZHJlc3NlcyA9IFsuLi5FWFBPUlRfSU5fQy5wQWRkcmVzc2VzXTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pbmNsdWRlSW4od2FsbGV0QWRkcmVzc2VzLCB1dHhvT3V0cHV0QWRkcmVzc2VzKSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSB3aGVuIHNvbWUgd2FsbGV0IGFkZHJlc3NlcyBhcmUgbm90IGluIFVUWE8gb3V0cHV0IGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhbGxldEFkZHJlc3NlcyA9IFtFWFBPUlRfSU5fQy5wQWRkcmVzc2VzWzBdLCBBQ0NPVU5UXzMuYWRkcmVzc107XG4gICAgICBjb25zdCB1dHhvT3V0cHV0QWRkcmVzc2VzID0gW0VYUE9SVF9JTl9DLnBBZGRyZXNzZXNbMF0sIEVYUE9SVF9JTl9DLnBBZGRyZXNzZXNbMV1dO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmluY2x1ZGVJbih3YWxsZXRBZGRyZXNzZXMsIHV0eG9PdXRwdXRBZGRyZXNzZXMpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBlbXB0eSB3YWxsZXQgYWRkcmVzc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FsbGV0QWRkcmVzc2VzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgY29uc3QgdXR4b091dHB1dEFkZHJlc3NlcyA9IFtFWFBPUlRfSU5fQy5wQWRkcmVzc2VzWzBdXTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pbmNsdWRlSW4od2FsbGV0QWRkcmVzc2VzLCB1dHhvT3V0cHV0QWRkcmVzc2VzKSwgdHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1ZhbGlkQWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCBtYWlubmV0IFAtY2hhaW4gYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQWRkcmVzcyhTRUVEX0FDQ09VTlQuYWRkcmVzc01haW5uZXQpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIHRlc3RuZXQgUC1jaGFpbiBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKFNFRURfQUNDT1VOVC5hZGRyZXNzVGVzdG5ldCksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgTm9kZUlEIGFkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoJ05vZGVJRC1hYmMxMjN4eXonKSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBhcnJheSBvZiB2YWxpZCBhZGRyZXNzZXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoRVhQT1JUX0lOX0MucEFkZHJlc3NlcyksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdGlsZGUtc2VwYXJhdGVkIGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGNvbWJpbmVkID0gRVhQT1JUX0lOX0MucEFkZHJlc3Nlcy5qb2luKCd+Jyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEFkZHJlc3MoY29tYmluZWQpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIGFkZHJlc3MgZm9ybWF0JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKCdpbnZhbGlkJyksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBhZGRyZXNzIHdpdGhvdXQgcHJlZml4JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRBZGRyZXNzKCdmbGFyZTFhYmMxMjMnKSwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZEJsb2NrSWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgdmFsaWQgMzItYnl0ZSBoZXggYmxvY2sgSUQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZEJsb2NrSWQoU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXkpLCB0cnVlKTsgLy8gNjQgaGV4IGNoYXJzID0gMzIgYnl0ZXNcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIGxlbmd0aCBibG9jayBJRCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkQmxvY2tJZChJTlZBTElEX1NIT1JUX0tFWVBBSVJfS0VZKSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGVtcHR5IGJsb2NrIElEJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRCbG9ja0lkKCcnKSwgZmFsc2UpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnaXNWYWxpZFB1YmxpY0tleScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCBjb21wcmVzc2VkIHB1YmxpYyBrZXkgc3RhcnRpbmcgd2l0aCAwMycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KFNFRURfQUNDT1VOVC5wdWJsaWNLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIGNvbXByZXNzZWQgcHVibGljIGtleSBzdGFydGluZyB3aXRoIDAyJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQUNDT1VOVF8xLnB1YmxpY0tleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgYW5vdGhlciB2YWxpZCBjb21wcmVzc2VkIHB1YmxpYyBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShBQ0NPVU5UXzIucHVibGljS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCB4cHViJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoU0VFRF9BQ0NPVU5ULnhQdWJsaWNLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIEFDQ09VTlRfMSB4cHViJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoQUNDT1VOVF8xLnhQdWJsaWNLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIHNob3J0IHB1YmxpYyBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFB1YmxpY0tleShJTlZBTElEX1NIT1JUX0tFWVBBSVJfS0VZKSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIGNvbXByZXNzZWQga2V5IHdpdGggd3JvbmcgcHJlZml4JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZEtleSA9ICcwNScgKyBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KGludmFsaWRLZXkpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3Igbm9uLWhleCBwdWJsaWMga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgaW52YWxpZEtleSA9ICd6eicgKyBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHVibGljS2V5KGludmFsaWRLZXkpLCBmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdpc1ZhbGlkUHJpdmF0ZUtleScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCA2NC1jaGFyIGhleCBwcml2YXRlIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdHJ1ZSBmb3IgQUNDT1VOVF8xIHByaXZhdGUga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KEFDQ09VTlRfMS5wcml2YXRlS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciBBQ0NPVU5UXzIgcHJpdmF0ZSBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoQUNDT1VOVF8yLnByaXZhdGVLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIHhwcnYnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoU0VFRF9BQ0NPVU5ULnhQcml2YXRlS2V5KSwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciA2Ni1jaGFyIHByaXZhdGUga2V5IGVuZGluZyB3aXRoIDAxJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZXh0ZW5kZWRLZXkgPSBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSArICcwMSc7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuaXNWYWxpZFByaXZhdGVLZXkoZXh0ZW5kZWRLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciA2Ni1jaGFyIHByaXZhdGUga2V5IG5vdCBlbmRpbmcgd2l0aCAwMScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShJTlZBTElEX0xPTkdfS0VZUEFJUl9QUlYpLCBmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgaW52YWxpZCBzaG9ydCBwcml2YXRlIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5pc1ZhbGlkUHJpdmF0ZUtleShJTlZBTElEX1NIT1JUX0tFWVBBSVJfS0VZKSwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIG5vbi1oZXggcHJpdmF0ZSBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBpbnZhbGlkS2V5ID0gJ3p6JyArIFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LnNsaWNlKDIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KGludmFsaWRLZXkpLCBmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdhbGxIZXhDaGFycycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB0cnVlIGZvciB2YWxpZCBwcml2YXRlIGtleSBoZXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuYWxsSGV4Q2hhcnMoU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIHB1YmxpYyBrZXkgaGV4JywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLmFsbEhleENoYXJzKFNFRURfQUNDT1VOVC5wdWJsaWNLZXkpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIGhleCBzdHJpbmcgd2l0aCAweCBwcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuYWxsSGV4Q2hhcnMoRVhQT1JUX0lOX0MuY0hleEFkZHJlc3MpLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRydWUgZm9yIHZhbGlkIHNpZ25hdHVyZSBoZXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuYWxsSGV4Q2hhcnMoU0VFRF9BQ0NPVU5ULnNpZ25hdHVyZSksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZmFsc2UgZm9yIG5vbi1oZXggY2hhcmFjdGVycycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5hbGxIZXhDaGFycygnZ2hpamtsJyksIGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBlbXB0eSBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMuYWxsSGV4Q2hhcnMoJycpLCBmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjcmVhdGVTaWduYXR1cmUgYW5kIHZlcmlmeVNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNyZWF0ZSBhIHZhbGlkIDY1LWJ5dGUgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LCAnaGV4Jyk7XG5cbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgYXNzZXJ0Lm9rKHNpZ25hdHVyZSBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoc2lnbmF0dXJlLmxlbmd0aCwgNjUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB2ZXJpZnkgYSB2YWxpZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXksICdoZXgnKTtcbiAgICAgIGNvbnN0IHB1YmxpY0tleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wdWJsaWNLZXksICdoZXgnKTtcblxuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHByaXZhdGVLZXkpO1xuICAgICAgY29uc3Qgc2lnT25seSA9IHNpZ25hdHVyZS5zbGljZSgwLCA2NCk7XG5cbiAgICAgIGNvbnN0IGlzVmFsaWQgPSB1dGlscy52ZXJpZnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnT25seSwgcHVibGljS2V5KTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChpc1ZhbGlkLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGZhbHNlIGZvciBpbnZhbGlkIHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHB1YmxpY0tleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wdWJsaWNLZXksICdoZXgnKTtcbiAgICAgIGNvbnN0IGludmFsaWRTaWduYXR1cmUgPSBCdWZmZXIuYWxsb2MoNjQpO1xuXG4gICAgICBjb25zdCBpc1ZhbGlkID0gdXRpbHMudmVyaWZ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIGludmFsaWRTaWduYXR1cmUsIHB1YmxpY0tleSk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoaXNWYWxpZCwgZmFsc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgc2lnbmF0dXJlIHdpdGggQUNDT1VOVF8xIGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oQUNDT1VOVF8xLnByaXZhdGVLZXksICdoZXgnKTtcblxuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gdXRpbHMuY3JlYXRlU2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHByaXZhdGVLZXkpO1xuXG4gICAgICBhc3NlcnQub2soc2lnbmF0dXJlIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChzaWduYXR1cmUubGVuZ3RoLCA2NSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjcmVhdGVOZXdTaWcnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSBzaWduYXR1cmUgZnJvbSB2YWxpZCBzaWduYXR1cmUgaGV4IHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZyA9IHV0aWxzLmNyZWF0ZU5ld1NpZyhTRUVEX0FDQ09VTlQuc2lnbmF0dXJlKTtcbiAgICAgIGFzc2VydC5vayhzaWcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSBzaWduYXR1cmUgZnJvbSBleHBvcnQgc2lnbmF0dXJlIGhleCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpZ0hleCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeChFWFBPUlRfSU5fQy5zaWduYXR1cmVbMF0pO1xuICAgICAgY29uc3Qgc2lnID0gdXRpbHMuY3JlYXRlTmV3U2lnKHNpZ0hleCk7XG4gICAgICBhc3NlcnQub2soc2lnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFkIHNob3J0IGhleCBzdHJpbmdzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnSGV4ID0gSU5WQUxJRF9TSE9SVF9LRVlQQUlSX0tFWTtcbiAgICAgIGNvbnN0IHNpZyA9IHV0aWxzLmNyZWF0ZU5ld1NpZyhzaWdIZXgpO1xuICAgICAgYXNzZXJ0Lm9rKHNpZyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdjcmVhdGVFbXB0eVNpZ1dpdGhBZGRyZXNzIGFuZCBnZXRBZGRyZXNzRnJvbUVtcHR5U2lnJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY3JlYXRlIGVtcHR5IHNpZ25hdHVyZSB3aXRoIGVtYmVkZGVkIEMtY2hhaW4gYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3NIZXggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoRVhQT1JUX0lOX0MuY0hleEFkZHJlc3MpO1xuICAgICAgY29uc3Qgc2lnID0gdXRpbHMuY3JlYXRlRW1wdHlTaWdXaXRoQWRkcmVzcyhhZGRyZXNzSGV4KTtcbiAgICAgIGFzc2VydC5vayhzaWcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleHRyYWN0IGVtYmVkZGVkIGFkZHJlc3MgZnJvbSBlbXB0eSBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzSGV4ID0gdXRpbHMucmVtb3ZlSGV4UHJlZml4KEVYUE9SVF9JTl9DLmNIZXhBZGRyZXNzKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgY29uc3Qgc2lnID0gdXRpbHMuY3JlYXRlRW1wdHlTaWdXaXRoQWRkcmVzcyhhZGRyZXNzSGV4KTtcblxuICAgICAgLy8gR2V0IHNpZ25hdHVyZSBieXRlcyBhbmQgY29udmVydCB0byBoZXhcbiAgICAgIGNvbnN0IHNpZ0J5dGVzID0gc2lnLnRvQnl0ZXMoKTtcbiAgICAgIGNvbnN0IHNpZ0hleCA9IEJ1ZmZlci5mcm9tKHNpZ0J5dGVzKS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgIGNvbnN0IGV4dHJhY3RlZEFkZHJlc3MgPSB1dGlscy5nZXRBZGRyZXNzRnJvbUVtcHR5U2lnKHNpZ0hleCk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoZXh0cmFjdGVkQWRkcmVzcywgYWRkcmVzc0hleCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSAweCBwcmVmaXhlZCBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2lnID0gdXRpbHMuY3JlYXRlRW1wdHlTaWdXaXRoQWRkcmVzcyhFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcyk7XG4gICAgICBhc3NlcnQub2soc2lnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGVtcHR5IHN0cmluZyBmb3Igc2hvcnQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgc2hvcnRTaWcgPSBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleTsgLy8gNjQgY2hhcnMsIGxlc3MgdGhhbiAxMzBcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5nZXRBZGRyZXNzRnJvbUVtcHR5U2lnKHNob3J0U2lnKSwgJycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnc2hhMjU2JywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY29tcHV0ZSBTSEEyNTYgaGFzaCBvZiBtZXNzYWdlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgaGFzaCA9IHV0aWxzLnNoYTI1NihkYXRhKTtcblxuICAgICAgYXNzZXJ0Lm9rKGhhc2ggaW5zdGFuY2VvZiBCdWZmZXIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGhhc2gubGVuZ3RoLCAzMik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgY29uc2lzdGVudCBoYXNoIGZvciBzYW1lIGlucHV0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgaGFzaDEgPSB1dGlscy5zaGEyNTYoZGF0YSk7XG4gICAgICBjb25zdCBoYXNoMiA9IHV0aWxzLnNoYTI1NihkYXRhKTtcblxuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChoYXNoMSwgaGFzaDIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGRpZmZlcmVudCBoYXNoIGZvciBkaWZmZXJlbnQgaW5wdXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhMSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgZGF0YTIgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGhhc2gxID0gdXRpbHMuc2hhMjU2KGRhdGExKTtcbiAgICAgIGNvbnN0IGhhc2gyID0gdXRpbHMuc2hhMjU2KGRhdGEyKTtcblxuICAgICAgYXNzZXJ0Lm5vdERlZXBTdHJpY3RFcXVhbChoYXNoMSwgaGFzaDIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmFsaWRhdGVSYXdUcmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIG5vdCB0aHJvdyBmb3IgdmFsaWQgdW5zaWduZWQgaGV4IHRyYW5zYWN0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmF3VHggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoRVhQT1JUX0lOX0MudW5zaWduZWRIZXgpO1xuICAgICAgYXNzZXJ0LmRvZXNOb3RUaHJvdygoKSA9PiB1dGlscy52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKHJhd1R4KSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCB0aHJvdyBmb3IgdmFsaWQgc2lnbmVkIGhleCB0cmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHJhd1R4ID0gdXRpbHMucmVtb3ZlSGV4UHJlZml4KEVYUE9SVF9JTl9DLnNpZ25lZEhleCk7XG4gICAgICBhc3NlcnQuZG9lc05vdFRocm93KCgpID0+IHV0aWxzLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24ocmF3VHgpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IHRocm93IGZvciBpbXBvcnQgdHJhbnNhY3Rpb24gaGV4JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcmF3VHggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoSU1QT1JUX0lOX1AudW5zaWduZWRIZXgpO1xuICAgICAgYXNzZXJ0LmRvZXNOb3RUaHJvdygoKSA9PiB1dGlscy52YWxpZGF0ZVJhd1RyYW5zYWN0aW9uKHJhd1R4KSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGZvciBlbXB0eSB0cmFuc2FjdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMudmFsaWRhdGVSYXdUcmFuc2FjdGlvbignJyksIC9SYXcgdHJhbnNhY3Rpb24gaXMgZW1wdHkvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZm9yIG5vbi1oZXggdHJhbnNhY3Rpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLnZhbGlkYXRlUmF3VHJhbnNhY3Rpb24oJ3h5ejEyMycpLCAvUmF3IHRyYW5zYWN0aW9uIGlzIG5vdCBoZXggc3RyaW5nLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdyZW1vdmVIZXhQcmVmaXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZW1vdmUgMHggcHJlZml4IGZyb20gQy1jaGFpbiBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHV0aWxzLnJlbW92ZUhleFByZWZpeChFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcyksIEVYUE9SVF9JTl9DLmNIZXhBZGRyZXNzLnNsaWNlKDIpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVtb3ZlIDB4IHByZWZpeCBmcm9tIHVuc2lnbmVkIGhleCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5yZW1vdmVIZXhQcmVmaXgoRVhQT1JUX0lOX0MudW5zaWduZWRIZXgpLCBFWFBPUlRfSU5fQy51bnNpZ25lZEhleC5zbGljZSgyKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBzdHJpbmcgdW5jaGFuZ2VkIGlmIG5vIHByZWZpeCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh1dGlscy5yZW1vdmVIZXhQcmVmaXgoU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXkpLCBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBlbXB0eSBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwodXRpbHMucmVtb3ZlSGV4UHJlZml4KCcnKSwgJycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnb3V0cHV0aWR4TnVtYmVyVG9CdWZmZXIgYW5kIG91dHB1dGlkeEJ1ZmZlclRvTnVtYmVyJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY29udmVydCBvdXRwdXQgaW5kZXggdG8gYnVmZmVyIGFuZCBiYWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgb3V0cHV0SWR4ID0gSU1QT1JUX0lOX1Aub3V0cHV0c1swXS5vdXRwdXRpZHg7XG4gICAgICBjb25zdCBidWZmZXIgPSB1dGlscy5vdXRwdXRpZHhOdW1iZXJUb0J1ZmZlcihvdXRwdXRJZHgpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHMub3V0cHV0aWR4QnVmZmVyVG9OdW1iZXIoYnVmZmVyKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgb3V0cHV0SWR4KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIG5vbmNlIHZhbHVlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgbm9uY2VTdHIgPSBFWFBPUlRfSU5fQy5ub25jZS50b1N0cmluZygpO1xuICAgICAgY29uc3QgYnVmZmVyID0gdXRpbHMub3V0cHV0aWR4TnVtYmVyVG9CdWZmZXIobm9uY2VTdHIpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHMub3V0cHV0aWR4QnVmZmVyVG9OdW1iZXIoYnVmZmVyKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHJlc3VsdCwgbm9uY2VTdHIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIDQtYnl0ZSBidWZmZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBidWZmZXIgPSB1dGlscy5vdXRwdXRpZHhOdW1iZXJUb0J1ZmZlcignMjU1Jyk7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYnVmZmVyLmxlbmd0aCwgNCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdhZGRyZXNzVG9TdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBjb252ZXJ0IGFkZHJlc3MgYnVmZmVyIHRvIG1haW5uZXQgYmVjaDMyIHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBTRUVEX0FDQ09VTlQuYWRkcmVzc01haW5uZXQ7XG4gICAgICBjb25zdCBhZGRyZXNzQnVmZmVyID0gdXRpbHMucGFyc2VBZGRyZXNzKGFkZHJlc3MpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdXRpbHMuYWRkcmVzc1RvU3RyaW5nKCdmbGFyZScsICdQJywgYWRkcmVzc0J1ZmZlcik7XG5cbiAgICAgIGFzc2VydC5vayhyZXN1bHQuc3RhcnRzV2l0aCgnUC0nKSk7XG4gICAgICBhc3NlcnQub2socmVzdWx0LmluY2x1ZGVzKCdmbGFyZScpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29udmVydCBhZGRyZXNzIGJ1ZmZlciB0byB0ZXN0bmV0IGJlY2gzMiBzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0O1xuICAgICAgY29uc3QgYWRkcmVzc0J1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhhZGRyZXNzKTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHV0aWxzLmFkZHJlc3NUb1N0cmluZygnY29zdHdvJywgJ1AnLCBhZGRyZXNzQnVmZmVyKTtcblxuICAgICAgYXNzZXJ0Lm9rKHJlc3VsdC5zdGFydHNXaXRoKCdQLScpKTtcbiAgICAgIGFzc2VydC5vayhyZXN1bHQuaW5jbHVkZXMoJ2Nvc3R3bycpKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2NiNThFbmNvZGUgYW5kIGNiNThEZWNvZGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBlbmNvZGUgYW5kIGRlY29kZSB0YXJnZXQgY2hhaW4gSUQgY29ycmVjdGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZW5jb2RlZCA9IEVYUE9SVF9JTl9DLnRhcmdldENoYWluSWQ7XG4gICAgICBjb25zdCBkZWNvZGVkID0gdXRpbHMuY2I1OERlY29kZShlbmNvZGVkKTtcbiAgICAgIGNvbnN0IHJlRW5jb2RlZCA9IHV0aWxzLmNiNThFbmNvZGUoZGVjb2RlZCk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZUVuY29kZWQsIGVuY29kZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlbmNvZGUgYW5kIGRlY29kZSBzb3VyY2UgY2hhaW4gSUQgY29ycmVjdGx5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZW5jb2RlZCA9IElNUE9SVF9JTl9QLnNvdXJjZUNoYWluSWQ7XG4gICAgICBjb25zdCBkZWNvZGVkID0gdXRpbHMuY2I1OERlY29kZShlbmNvZGVkKTtcbiAgICAgIGNvbnN0IHJlRW5jb2RlZCA9IHV0aWxzLmNiNThFbmNvZGUoZGVjb2RlZCk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZUVuY29kZWQsIGVuY29kZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgaW52YWxpZCBjaGVja3N1bScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMuY2I1OERlY29kZSgnMTExMTExMTExMTExMScpLCAvSW52YWxpZCBjaGVja3N1bS8pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncGFyc2VBZGRyZXNzIGFuZCBzdHJpbmdUb0FkZHJlc3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBoZXggYWRkcmVzcyB3aXRoIDB4IHByZWZpeCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhFWFBPUlRfSU5fQy5jSGV4QWRkcmVzcyk7XG5cbiAgICAgIGFzc2VydC5vayhidWZmZXIgaW5zdGFuY2VvZiBCdWZmZXIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlci5sZW5ndGgsIDIwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgcmF3IGhleCBhZGRyZXNzIGZyb20gb3V0cHV0cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBJTVBPUlRfSU5fUC5vdXRwdXRzWzBdLmFkZHJlc3Nlc1swXTtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhhZGRyZXNzKTtcblxuICAgICAgYXNzZXJ0Lm9rKGJ1ZmZlciBpbnN0YW5jZW9mIEJ1ZmZlcik7XG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwoYnVmZmVyLmxlbmd0aCwgMjApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwYXJzZSBtYWlubmV0IGJlY2gzMiBhZGRyZXNzJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYnVmZmVyID0gdXRpbHMucGFyc2VBZGRyZXNzKFNFRURfQUNDT1VOVC5hZGRyZXNzTWFpbm5ldCk7XG5cbiAgICAgIGFzc2VydC5vayhidWZmZXIgaW5zdGFuY2VvZiBCdWZmZXIpO1xuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlci5sZW5ndGgsIDIwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcGFyc2UgdGVzdG5ldCBiZWNoMzIgYWRkcmVzcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IHV0aWxzLnBhcnNlQWRkcmVzcyhTRUVEX0FDQ09VTlQuYWRkcmVzc1Rlc3RuZXQpO1xuXG4gICAgICBhc3NlcnQub2soYnVmZmVyIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChidWZmZXIubGVuZ3RoLCAyMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhcnNlIFAtY2hhaW4gYWRkcmVzc2VzIGZyb20gZXhwb3J0IGRhdGEnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBFWFBPUlRfSU5fQy5wQWRkcmVzc2VzLmZvckVhY2goKGFkZHJlc3MpID0+IHtcbiAgICAgICAgY29uc3QgYnVmZmVyID0gdXRpbHMucGFyc2VBZGRyZXNzKGFkZHJlc3MpO1xuICAgICAgICBhc3NlcnQub2soYnVmZmVyIGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKGJ1ZmZlci5sZW5ndGgsIDIwKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBmb3IgYWRkcmVzcyB3aXRob3V0IGRhc2ggc2VwYXJhdG9yJywgZnVuY3Rpb24gKCkge1xuICAgICAgYXNzZXJ0LnRocm93cygoKSA9PiB1dGlscy5wYXJzZUFkZHJlc3MoJ2ZsYXJlMWFiYycpLCAvVmFsaWQgYWRkcmVzcyBzaG91bGQgaW5jbHVkZSAtLyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGZvciBpbnZhbGlkIEhSUCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMucGFyc2VBZGRyZXNzKCdQLWludmFsaWQxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXE1ZXZ6bXknKSwgL0ludmFsaWQgSFJQLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdmbGFyZUlkU3RyaW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgY3JlYXRlIElkIGZyb20gcHJpdmF0ZSBrZXkgaGV4IHN0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGlkID0gdXRpbHMuZmxhcmVJZFN0cmluZyhTRUVEX0FDQ09VTlQucHJpdmF0ZUtleSk7XG4gICAgICBhc3NlcnQub2soaWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgSWQgZnJvbSBhc3NldCBJRCBoZXgnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBBc3NldCBJRCBpcyB0eXBpY2FsbHkgMzIgYnl0ZXMgKDY0IGhleCBjaGFycylcbiAgICAgIGNvbnN0IGFzc2V0SWRIZXggPSBTRUVEX0FDQ09VTlQucHJpdmF0ZUtleTsgLy8gVXNpbmcgYXMgYSAzMi1ieXRlIGhleFxuICAgICAgY29uc3QgaWQgPSB1dGlscy5mbGFyZUlkU3RyaW5nKGFzc2V0SWRIZXgpO1xuICAgICAgYXNzZXJ0Lm9rKGlkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3JlY292ZXJ5U2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBwdWJsaWMga2V5IGZyb20gdmFsaWQgc2lnbmF0dXJlJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3QgcHJpdmF0ZUtleSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5wcml2YXRlS2V5LCAnaGV4Jyk7XG5cbiAgICAgIC8vIENyZWF0ZSBzaWduYXR1cmUgdXNpbmcgdGhlIHNhbWUgcHJpdmF0ZSBrZXlcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgLy8gUmVjb3ZlciBwdWJsaWMga2V5XG4gICAgICBjb25zdCByZWNvdmVyZWRQdWJLZXkgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpO1xuXG4gICAgICBhc3NlcnQub2socmVjb3ZlcmVkUHViS2V5IGluc3RhbmNlb2YgQnVmZmVyKTtcbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZWNvdmVyZWRQdWJLZXkubGVuZ3RoLCAzMyk7IC8vIFNob3VsZCBiZSBjb21wcmVzc2VkIHB1YmxpYyBrZXkgKDMzIGJ5dGVzKVxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHNhbWUgcHVibGljIGtleSBmb3Igc2FtZSBtZXNzYWdlIGFuZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXksICdoZXgnKTtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IHV0aWxzLmNyZWF0ZVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBwcml2YXRlS2V5KTtcblxuICAgICAgY29uc3QgcHViS2V5MSA9IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ25hdHVyZSk7XG4gICAgICBjb25zdCBwdWJLZXkyID0gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgc2lnbmF0dXJlKTtcblxuICAgICAgYXNzZXJ0LmRlZXBTdHJpY3RFcXVhbChwdWJLZXkxLCBwdWJLZXkyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVjb3ZlciBwdWJsaWMga2V5IHRoYXQgbWF0Y2hlcyBvcmlnaW5hbCBrZXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULnByaXZhdGVLZXksICdoZXgnKTtcblxuICAgICAgLy8gR2V0IG9yaWdpbmFsIHB1YmxpYyBrZXlcbiAgICAgIGNvbnN0IG9yaWdpbmFsUHViS2V5ID0gQnVmZmVyLmZyb20oZWNjLnBvaW50RnJvbVNjYWxhcihwcml2YXRlS2V5LCB0cnVlKSBhcyBVaW50OEFycmF5KTtcblxuICAgICAgLy8gQ3JlYXRlIHNpZ25hdHVyZSBhbmQgcmVjb3ZlciBwdWJsaWMga2V5XG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG4gICAgICBjb25zdCByZWNvdmVyZWRQdWJLZXkgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpO1xuXG4gICAgICAvLyBDb252ZXJ0IGJvdGggdG8gaGV4IHN0cmluZ3MgZm9yIGNvbXBhcmlzb25cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbChyZWNvdmVyZWRQdWJLZXkudG9TdHJpbmcoJ2hleCcpLCBvcmlnaW5hbFB1YktleS50b1N0cmluZygnaGV4JykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWNvdmVyIHB1YmxpYyBrZXkgdXNpbmcgQUNDT1VOVF8xIGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gQnVmZmVyLmZyb20oU0VFRF9BQ0NPVU5ULm1lc3NhZ2UsICd1dGY4Jyk7XG4gICAgICBjb25zdCBwcml2YXRlS2V5ID0gQnVmZmVyLmZyb20oQUNDT1VOVF8xLnByaXZhdGVLZXksICdoZXgnKTtcblxuICAgICAgY29uc3Qgb3JpZ2luYWxQdWJLZXkgPSBCdWZmZXIuZnJvbShlY2MucG9pbnRGcm9tU2NhbGFyKHByaXZhdGVLZXksIHRydWUpIGFzIFVpbnQ4QXJyYXkpO1xuXG4gICAgICBjb25zdCBzaWduYXR1cmUgPSB1dGlscy5jcmVhdGVTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgcHJpdmF0ZUtleSk7XG4gICAgICBjb25zdCByZWNvdmVyZWRQdWJLZXkgPSB1dGlscy5yZWNvdmVyeVNpZ25hdHVyZShuZXR3b3JrLCBtZXNzYWdlLCBzaWduYXR1cmUpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwocmVjb3ZlcmVkUHViS2V5LnRvU3RyaW5nKCdoZXgnKSwgb3JpZ2luYWxQdWJLZXkudG9TdHJpbmcoJ2hleCcpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIGludmFsaWQgc2lnbmF0dXJlIGxlbmd0aCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuZnJvbShTRUVEX0FDQ09VTlQubWVzc2FnZSwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IGludmFsaWRTaWduYXR1cmUgPSBCdWZmZXIuZnJvbShJTlZBTElEX1NIT1JUX0tFWVBBSVJfS0VZLCAnaGV4Jyk7XG5cbiAgICAgIGFzc2VydC50aHJvd3MoKCkgPT4gdXRpbHMucmVjb3ZlcnlTaWduYXR1cmUobmV0d29yaywgbWVzc2FnZSwgaW52YWxpZFNpZ25hdHVyZSksIC9GYWlsZWQgdG8gcmVjb3ZlciBzaWduYXR1cmUvKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3IgZm9yIHNpZ25hdHVyZSB3aXRoIGludmFsaWQgcmVjb3ZlcnkgcGFyYW1ldGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IEJ1ZmZlci5mcm9tKFNFRURfQUNDT1VOVC5tZXNzYWdlLCAndXRmOCcpO1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gQnVmZmVyLmFsbG9jKDY1KTsgLy8gVmFsaWQgbGVuZ3RoIGJ1dCBhbGwgemVyb3MgLSBpbnZhbGlkIHNpZ25hdHVyZVxuXG4gICAgICBhc3NlcnQudGhyb3dzKCgpID0+IHV0aWxzLnJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcmssIG1lc3NhZ2UsIHNpZ25hdHVyZSksIC9GYWlsZWQgdG8gcmVjb3ZlciBzaWduYXR1cmUvKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==