@bitgo-beta/sdk-coin-flrp 1.0.1-beta.3 → 1.0.1-beta.300

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 (109) hide show
  1. package/dist/src/flrp.d.ts +75 -61
  2. package/dist/src/flrp.d.ts.map +1 -1
  3. package/dist/src/flrp.js +276 -134
  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 +49 -34
  23. package/dist/src/lib/atomicTransactionBuilder.d.ts.map +1 -1
  24. package/dist/src/lib/atomicTransactionBuilder.js +159 -33
  25. package/dist/src/lib/iface.d.ts +50 -22
  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 +7 -0
  29. package/dist/src/lib/index.d.ts.map +1 -1
  30. package/dist/src/lib/index.js +16 -2
  31. package/dist/src/lib/keyPair.d.ts +5 -5
  32. package/dist/src/lib/keyPair.d.ts.map +1 -1
  33. package/dist/src/lib/keyPair.js +15 -9
  34. package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts +43 -0
  35. package/dist/src/lib/permissionlessValidatorTxBuilder.d.ts.map +1 -0
  36. package/dist/src/lib/permissionlessValidatorTxBuilder.js +132 -0
  37. package/dist/src/lib/transaction.d.ts +51 -0
  38. package/dist/src/lib/transaction.d.ts.map +1 -0
  39. package/dist/src/lib/transaction.js +373 -0
  40. package/dist/src/lib/transactionBuilder.d.ts +107 -0
  41. package/dist/src/lib/transactionBuilder.d.ts.map +1 -0
  42. package/dist/src/lib/transactionBuilder.js +210 -0
  43. package/dist/src/lib/transactionBuilderFactory.d.ts +57 -0
  44. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -0
  45. package/dist/src/lib/transactionBuilderFactory.js +148 -0
  46. package/dist/src/lib/utils.d.ts +78 -102
  47. package/dist/src/lib/utils.d.ts.map +1 -1
  48. package/dist/src/lib/utils.js +220 -246
  49. package/dist/test/resources/account.d.ts +51 -0
  50. package/dist/test/resources/account.d.ts.map +1 -0
  51. package/dist/test/resources/account.js +54 -0
  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 +490 -20
  65. package/dist/test/unit/lib/exportInCTxBuilder.d.ts +2 -0
  66. package/dist/test/unit/lib/exportInCTxBuilder.d.ts.map +1 -0
  67. package/dist/test/unit/lib/exportInCTxBuilder.js +166 -0
  68. package/dist/test/unit/lib/exportInPTxBuilder.d.ts +2 -0
  69. package/dist/test/unit/lib/exportInPTxBuilder.d.ts.map +1 -0
  70. package/dist/test/unit/lib/exportInPTxBuilder.js +121 -0
  71. package/dist/test/unit/lib/importInCTxBuilder.d.ts +2 -0
  72. package/dist/test/unit/lib/importInCTxBuilder.d.ts.map +1 -0
  73. package/dist/test/unit/lib/importInCTxBuilder.js +47 -0
  74. package/dist/test/unit/lib/importInPTxBuilder.d.ts +2 -0
  75. package/dist/test/unit/lib/importInPTxBuilder.d.ts.map +1 -0
  76. package/dist/test/unit/lib/importInPTxBuilder.js +73 -0
  77. package/dist/test/unit/lib/keyPair.d.ts +2 -0
  78. package/dist/test/unit/lib/keyPair.d.ts.map +1 -0
  79. package/dist/test/unit/lib/keyPair.js +158 -0
  80. package/dist/test/unit/lib/signFlowTestSuit.d.ts +20 -0
  81. package/dist/test/unit/lib/signFlowTestSuit.d.ts.map +1 -0
  82. package/dist/test/unit/lib/signFlowTestSuit.js +89 -0
  83. package/dist/test/unit/lib/utils.d.ts +2 -0
  84. package/dist/test/unit/lib/utils.d.ts.map +1 -0
  85. package/dist/test/unit/lib/utils.js +453 -0
  86. package/dist/tsconfig.tsbuildinfo +1 -1
  87. package/package.json +16 -11
  88. package/.eslintignore +0 -5
  89. package/.eslintrc.json +0 -7
  90. package/.mocharc.yml +0 -8
  91. package/CHANGELOG.md +0 -0
  92. package/dist/src/iface.d.ts +0 -25
  93. package/dist/src/iface.d.ts.map +0 -1
  94. package/dist/src/iface.js +0 -3
  95. package/dist/src/lib/constants.d.ts +0 -11
  96. package/dist/src/lib/constants.d.ts.map +0 -1
  97. package/dist/src/lib/constants.js +0 -17
  98. package/dist/src/lib/errors.d.ts +0 -8
  99. package/dist/src/lib/errors.d.ts.map +0 -1
  100. package/dist/src/lib/errors.js +0 -19
  101. package/dist/src/lib/exportInCTxBuilder.d.ts +0 -77
  102. package/dist/src/lib/exportInCTxBuilder.d.ts.map +0 -1
  103. package/dist/src/lib/exportInCTxBuilder.js +0 -164
  104. package/dist/src/lib/exportInPTxBuilder.d.ts +0 -30
  105. package/dist/src/lib/exportInPTxBuilder.d.ts.map +0 -1
  106. package/dist/src/lib/exportInPTxBuilder.js +0 -56
  107. package/dist/test/unit/smoke.d.ts +0 -2
  108. package/dist/test/unit/smoke.d.ts.map +0 -1
  109. package/dist/test/unit/smoke.js +0 -9
@@ -1,60 +1,79 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
35
5
  Object.defineProperty(exports, "__esModule", { value: true });
36
6
  exports.Utils = void 0;
7
+ const flarejs_1 = require("@flarenetwork/flarejs");
37
8
  const sdk_core_1 = require("@bitgo-beta/sdk-core");
38
- const createHash = __importStar(require("create-hash"));
39
- const secp256k1_1 = require("@noble/curves/secp256k1");
40
- const constants_1 = require("./constants");
9
+ const buffer_1 = require("buffer");
10
+ const crypto_1 = require("crypto");
11
+ const secp256k1_1 = require("@bitgo-beta/secp256k1");
12
+ const iface_1 = require("./iface");
13
+ const bs58_1 = __importDefault(require("bs58"));
14
+ const bech32_1 = require("bech32");
41
15
  class Utils {
42
16
  constructor() {
43
- this.parseAddress = (pub) => {
44
- // FlareJS equivalent for address parsing
45
- return Buffer.from(pub, 'hex'); // Simplified implementation
17
+ /**
18
+ * Helper method to convert address components to string
19
+ */
20
+ this.addressToString = (hrp, prefix, address) => {
21
+ // Convert the address bytes to 5-bit words for bech32 encoding
22
+ const words = bech32_1.bech32.toWords(address);
23
+ // Create the full bech32 address with format: P-{hrp}1{bech32_encoded_address}
24
+ return `${prefix}-${bech32_1.bech32.encode(hrp, words)}`;
46
25
  };
26
+ // In utils.ts, add this method to the Utils class:
27
+ /**
28
+ * Parse an address string into a Buffer
29
+ * @param address - The address to parse
30
+ * @returns Buffer containing the parsed address
31
+ */
32
+ this.parseAddress = (address) => {
33
+ return this.stringToAddress(address);
34
+ };
35
+ this.stringToAddress = (address, hrp) => {
36
+ // Handle hex addresses
37
+ if (address.startsWith('0x')) {
38
+ return buffer_1.Buffer.from(address.slice(2), 'hex');
39
+ }
40
+ // Handle raw hex without 0x prefix
41
+ if (/^[0-9a-fA-F]{40}$/.test(address)) {
42
+ return buffer_1.Buffer.from(address, 'hex');
43
+ }
44
+ // Handle Bech32 addresses
45
+ const parts = address.trim().split('-');
46
+ if (parts.length < 2) {
47
+ throw new Error('Error - Valid address should include -');
48
+ }
49
+ const split = parts[1].lastIndexOf('1');
50
+ if (split < 0) {
51
+ throw new Error('Error - Valid bech32 address must include separator (1)');
52
+ }
53
+ const humanReadablePart = parts[1].slice(0, split);
54
+ if (humanReadablePart !== 'flare' && humanReadablePart !== 'costwo') {
55
+ throw new Error('Error - Invalid HRP');
56
+ }
57
+ return buffer_1.Buffer.from(bech32_1.bech32.fromWords(bech32_1.bech32.decode(parts[1]).words));
58
+ };
59
+ }
60
+ isValidTransactionId(txId) {
61
+ throw new Error('Method not implemented.');
62
+ }
63
+ isValidSignature(signature) {
64
+ throw new Error('Method not implemented.');
47
65
  }
66
+ /**
67
+ * Check if addresses in wallet match UTXO output addresses
68
+ */
48
69
  includeIn(walletAddresses, otxoOutputAddresses) {
49
70
  return walletAddresses.map((a) => otxoOutputAddresses.includes(a)).reduce((a, b) => a && b, true);
50
71
  }
51
72
  /**
52
- * Checks if it is a valid address no illegal characters
53
- *
54
- * @param {string} address - address to be validated
55
- * @returns {boolean} - the validation result
73
+ * Validates a Flare address or array of addresses
74
+ * @param {string | string[]} address - address(es) to validate
75
+ * @returns {boolean} - validation result
56
76
  */
57
- /** @inheritdoc */
58
77
  isValidAddress(address) {
59
78
  const addressArr = Array.isArray(address) ? address : address.split('~');
60
79
  for (const address of addressArr) {
@@ -65,65 +84,53 @@ class Utils {
65
84
  return true;
66
85
  }
67
86
  isValidAddressRegex(address) {
68
- return constants_1.ADDRESS_REGEX.test(address);
87
+ return /^(^P||NodeID)-[a-zA-Z0-9]+$/.test(address);
69
88
  }
70
89
  /**
71
- * Checks if it is a valid blockId with length 66 including 0x
72
- *
73
- * @param {string} hash - blockId to be validated
74
- * @returns {boolean} - the validation result
90
+ * Validates a block ID
91
+ * @param {string} hash - block ID to validate
92
+ * @returns {boolean} - validation result
75
93
  */
76
- /** @inheritdoc */
77
94
  isValidBlockId(hash) {
78
- // FlareJS equivalent - check if it's a valid CB58 hash with correct length
79
95
  try {
80
- const decoded = Buffer.from(hash); // FlareJS should provide CB58 utilities
81
- return decoded.length === constants_1.DECODED_BLOCK_ID_LENGTH;
96
+ const decoded = buffer_1.Buffer.from(hash, 'hex');
97
+ return decoded.length === 32;
82
98
  }
83
99
  catch {
84
100
  return false;
85
101
  }
86
102
  }
87
103
  /**
88
- * Checks if the string is a valid protocol public key or
89
- * extended public key.
90
- *
91
- * @param {string} pub - the public key to be validated
92
- * @returns {boolean} - the validation result
104
+ * Validates a public key
105
+ * @param {string} pub - public key to validate
106
+ * @returns {boolean} - validation result
93
107
  */
94
108
  isValidPublicKey(pub) {
95
109
  if ((0, sdk_core_1.isValidXpub)(pub))
96
110
  return true;
97
111
  let pubBuf;
98
- if (pub.length === constants_1.SHORT_PUB_KEY_LENGTH) {
112
+ if (pub.length === 50) {
99
113
  try {
100
- // For FlareJS, we'll need to implement CB58 decode functionality
101
- pubBuf = Buffer.from(pub, 'hex'); // Temporary placeholder
114
+ pubBuf = buffer_1.Buffer.from(pub, 'hex');
102
115
  }
103
116
  catch {
104
117
  return false;
105
118
  }
106
119
  }
107
120
  else {
108
- if (pub.length !== constants_1.COMPRESSED_PUBLIC_KEY_LENGTH && pub.length !== constants_1.UNCOMPRESSED_PUBLIC_KEY_LENGTH) {
121
+ if (pub.length !== 66 && pub.length !== 130)
109
122
  return false;
110
- }
111
123
  const firstByte = pub.slice(0, 2);
112
- // uncompressed public key
113
- if (pub.length === constants_1.UNCOMPRESSED_PUBLIC_KEY_LENGTH && firstByte !== '04') {
124
+ if (pub.length === 130 && firstByte !== '04')
114
125
  return false;
115
- }
116
- // compressed public key
117
- if (pub.length === constants_1.COMPRESSED_PUBLIC_KEY_LENGTH && firstByte !== '02' && firstByte !== '03') {
126
+ if (pub.length === 66 && firstByte !== '02' && firstByte !== '03')
118
127
  return false;
119
- }
120
128
  if (!this.allHexChars(pub))
121
129
  return false;
122
- pubBuf = Buffer.from(pub, 'hex');
130
+ pubBuf = buffer_1.Buffer.from(pub, 'hex');
123
131
  }
124
- // validate the public key using noble secp256k1
125
132
  try {
126
- secp256k1_1.secp256k1.ProjectivePoint.fromHex(pubBuf.toString('hex'));
133
+ secp256k1_1.ecc.isPoint(pubBuf);
127
134
  return true;
128
135
  }
129
136
  catch (e) {
@@ -131,194 +138,131 @@ class Utils {
131
138
  }
132
139
  }
133
140
  /**
134
- * Returns whether or not the string is a valid protocol private key, or extended
135
- * private key.
136
- *
137
- * The protocol key format is described in the @stacks/transactions npm package, in the
138
- * createStacksPrivateKey function:
139
- * https://github.com/blockstack/stacks.js/blob/master/packages/transactions/src/keys.ts#L125
140
- *
141
- * @param {string} prv - the private key (or extended private key) to be validated
142
- * @returns {boolean} - the validation result
141
+ * Validates a private key
142
+ * @param {string} prv - private key to validate
143
+ * @returns {boolean} - validation result
143
144
  */
144
145
  isValidPrivateKey(prv) {
145
146
  if ((0, sdk_core_1.isValidXprv)(prv))
146
147
  return true;
147
- if (prv.length !== constants_1.RAW_PRIVATE_KEY_LENGTH && prv.length !== constants_1.SUFFIXED_PRIVATE_KEY_LENGTH) {
148
+ if (prv.length !== 64 && prv.length !== 66)
148
149
  return false;
149
- }
150
- if (prv.length === constants_1.SUFFIXED_PRIVATE_KEY_LENGTH &&
151
- prv.slice(constants_1.RAW_PRIVATE_KEY_LENGTH) !== constants_1.PRIVATE_KEY_COMPRESSED_SUFFIX) {
150
+ if (prv.length === 66 && prv.slice(64) !== '01')
152
151
  return false;
153
- }
154
152
  return this.allHexChars(prv);
155
153
  }
156
154
  /**
157
- * Returns whether or not the string is a composed of hex chars only
158
- *
159
- * @param {string} maybe - the string to be validated
160
- * @returns {boolean} - the validation result
155
+ * Checks if a string contains only hex characters
161
156
  */
162
- allHexChars(maybe) {
163
- return constants_1.HEX_REGEX.test(maybe);
164
- }
165
- /** @inheritdoc */
166
- isValidSignature(signature) {
167
- throw new sdk_core_1.NotImplementedError('isValidSignature not implemented');
168
- }
169
- /** @inheritdoc */
170
- isValidTransactionId(txId) {
171
- throw new sdk_core_1.NotImplementedError('isValidTransactionId not implemented');
157
+ allHexChars(str) {
158
+ return /^(0x){0,1}([0-9a-f])+$/i.test(str);
172
159
  }
173
160
  /**
174
- * FlareJS wrapper to create signature and return it for credentials
175
- * @param network
176
- * @param message
177
- * @param prv
178
- * @return signature
161
+ * Creates a signature using the Flare network parameters
162
+ * Returns a 65-byte signature (64 bytes signature + 1 byte recovery parameter)
179
163
  */
180
164
  createSignature(network, message, prv) {
181
- // Use secp256k1 directly since FlareJS may not expose KeyPair in the same way
182
- try {
183
- const signature = secp256k1_1.secp256k1.sign(message, prv);
184
- return Buffer.from(signature.toCompactRawBytes());
165
+ const messageHash = this.sha256(message);
166
+ const signature = secp256k1_1.ecc.sign(messageHash, prv);
167
+ // Get the public key from the private key for recovery parameter determination
168
+ const publicKey = secp256k1_1.ecc.pointFromScalar(prv, true);
169
+ if (!publicKey) {
170
+ throw new Error('Failed to derive public key from private key');
185
171
  }
186
- catch (error) {
187
- throw new Error(`Failed to create signature: ${error}`);
172
+ // Try recovery with param 0 and 1 to find the correct one
173
+ let recoveryParam = 0;
174
+ for (let i = 0; i <= 1; i++) {
175
+ const recovered = secp256k1_1.ecc.recoverPublicKey(messageHash, signature, i, true);
176
+ if (recovered && buffer_1.Buffer.from(recovered).equals(buffer_1.Buffer.from(publicKey))) {
177
+ recoveryParam = i;
178
+ break;
179
+ }
188
180
  }
181
+ // Append recovery parameter to create 65-byte signature
182
+ const sigWithRecovery = buffer_1.Buffer.alloc(65);
183
+ buffer_1.Buffer.from(signature).copy(sigWithRecovery, 0);
184
+ sigWithRecovery[64] = recoveryParam;
185
+ return sigWithRecovery;
189
186
  }
190
187
  /**
191
- * FlareJS wrapper to verify signature
192
- * @param network
193
- * @param message
194
- * @param signature
195
- * @param publicKey - public key instead of private key for verification
196
- * @return true if it's verify successful
188
+ * Verifies a signature
197
189
  */
198
190
  verifySignature(network, message, signature, publicKey) {
199
191
  try {
200
- return secp256k1_1.secp256k1.verify(signature, message, publicKey);
192
+ const messageHash = this.sha256(message);
193
+ return secp256k1_1.ecc.verify(messageHash, publicKey, signature);
201
194
  }
202
- catch (error) {
195
+ catch (e) {
203
196
  return false;
204
197
  }
205
198
  }
206
199
  /**
207
- * FlareJS wrapper to recover signature
208
- * @param network
209
- * @param message
210
- * @param signature
211
- * @return recovered public key
200
+ * Creates a new signature object
212
201
  */
213
- recoverySignature(network, message, signature) {
214
- try {
215
- // This would need to be implemented with secp256k1 recovery
216
- // For now, throwing error since recovery logic would need to be adapted
217
- throw new sdk_core_1.NotImplementedError('recoverySignature not fully implemented for FlareJS');
218
- }
219
- catch (error) {
220
- throw new Error(`Failed to recover signature: ${error}`);
221
- }
222
- }
223
- sha256(buf) {
224
- return createHash.default('sha256').update(buf).digest();
202
+ createNewSig(sigHex) {
203
+ const buffer = buffer_1.Buffer.from(sigHex.padStart(130, '0'), 'hex');
204
+ return new flarejs_1.Signature(buffer);
225
205
  }
226
206
  /**
227
- * Check the raw transaction has a valid format in the blockchain context, throw otherwise.
228
- * It's to reuse in TransactionBuilder and TransactionBuilderFactory
229
- *
230
- * @param rawTransaction Transaction as hex string
207
+ * Creates an empty signature with embedded address for signature slot identification.
208
+ * The address is embedded at position 90 (after the first 45 zero bytes).
209
+ * This allows the signing logic to determine which slot belongs to which address.
210
+ * @param addressHex The 20-byte address in hex format (40 chars, without 0x prefix)
231
211
  */
232
- validateRawTransaction(rawTransaction) {
233
- if (!rawTransaction) {
234
- throw new sdk_core_1.InvalidTransactionError('Raw transaction is empty');
235
- }
236
- if (!utils.allHexChars(rawTransaction)) {
237
- throw new sdk_core_1.ParseTransactionError('Raw transaction is not hex string');
238
- }
212
+ createEmptySigWithAddress(addressHex) {
213
+ // First 45 bytes (90 hex chars) are zeros, followed by 20-byte address (40 hex chars)
214
+ const cleanAddr = this.removeHexPrefix(addressHex).toLowerCase();
215
+ const sigHex = '0'.repeat(90) + cleanAddr.padStart(40, '0');
216
+ const buffer = buffer_1.Buffer.from(sigHex, 'hex');
217
+ return new flarejs_1.Signature(buffer);
239
218
  }
240
219
  /**
241
- * Check if tx is for the blockchainId
242
- *
243
- * @param {DeprecatedTx} tx
244
- * @param {string} blockchainId
245
- * @returns true if tx is for blockchainId
220
+ * Extracts the embedded address from an empty signature.
221
+ * Returns the address hex string (40 chars) or empty string if not found.
246
222
  */
247
- isTransactionOf(tx, blockchainId) {
248
- // FlareJS equivalent - this would need proper CB58 encoding implementation
249
- try {
250
- const txRecord = tx;
251
- const unsignedTx = txRecord.getUnsignedTx();
252
- const transaction = unsignedTx.getTransaction();
253
- const txBlockchainId = transaction.getBlockchainID();
254
- return Buffer.from(txBlockchainId).toString('hex') === blockchainId;
255
- }
256
- catch (error) {
257
- return false;
223
+ getAddressFromEmptySig(sig) {
224
+ const cleanSig = this.removeHexPrefix(sig);
225
+ if (cleanSig.length >= 130) {
226
+ // Address is at position 90-130 (last 40 hex chars = 20 bytes)
227
+ return cleanSig.substring(90, 130).toLowerCase();
258
228
  }
229
+ return '';
259
230
  }
260
231
  /**
261
- * Check if Output is from PVM.
262
- * Output could be EVM or PVM output.
263
- * @param {DeprecatedOutput} output
264
- * @returns {boolean} output has transferable output structure
232
+ * Computes SHA256 hash
265
233
  */
266
- deprecatedIsTransferableOutput(output) {
267
- return 'getOutput' in output;
234
+ sha256(buf) {
235
+ return (0, crypto_1.createHash)('sha256').update(buf).digest();
268
236
  }
269
237
  /**
270
- * Check if Output is from PVM.
271
- * Output could be EVM or PVM output.
272
- * @param {Output} output
273
- * @returns {boolean} output is TransferableOutput
238
+ * Validates raw transaction format
274
239
  */
275
- isTransferableOutput(output) {
276
- return typeof output.getOutput === 'function';
240
+ validateRawTransaction(rawTransaction) {
241
+ if (!rawTransaction) {
242
+ throw new sdk_core_1.InvalidTransactionError('Raw transaction is empty');
243
+ }
244
+ if (!this.allHexChars(rawTransaction)) {
245
+ throw new sdk_core_1.ParseTransactionError('Raw transaction is not hex string');
246
+ }
277
247
  }
278
248
  /**
279
- * Return a mapper function to that network address representation.
280
- * @param network required to stringify addresses
281
- * @return mapper function
249
+ * Checks if output is TransferableOutput type
282
250
  */
283
- deprecatedMapOutputToEntry(network) {
284
- return (output) => {
285
- if (this.deprecatedIsTransferableOutput(output)) {
286
- // Simplified implementation for FlareJS
287
- try {
288
- const transferableOutput = output;
289
- const amount = transferableOutput.amount();
290
- // Simplified address handling - would need proper FlareJS address utilities
291
- const address = 'flare-address-placeholder'; // TODO: implement proper address conversion
292
- return {
293
- value: amount.toString(),
294
- address,
295
- };
296
- }
297
- catch (error) {
298
- throw new Error(`Failed to map output: ${error}`);
299
- }
300
- }
301
- else {
302
- // Handle EVM output case - simplified
303
- return {
304
- value: '0', // TODO: implement proper amount extraction
305
- address: '0x0000000000000000000000000000000000000000', // TODO: implement proper address extraction
306
- };
307
- }
308
- };
251
+ isTransferableOutput(output) {
252
+ return output?._type === flarejs_1.TypeSymbols.TransferableOutput;
309
253
  }
310
254
  /**
311
- * Return a mapper function to that network address representation.
312
- * @param network required to stringify addresses
313
- * @return mapper function
255
+ * Maps outputs to entry format
314
256
  */
315
257
  mapOutputToEntry(network) {
316
258
  return (output) => {
317
259
  if (this.isTransferableOutput(output)) {
318
- const transferableOutput = output;
319
- const outputAmount = transferableOutput.amount();
320
- // Simplified address handling for FlareJS
321
- const address = 'flare-address-placeholder'; // TODO: implement proper address conversion
260
+ const outputAmount = output.amount();
261
+ const address = output.output
262
+ .getOwners()
263
+ .map((a) => this.addressToString(network.hrp, network.alias, buffer_1.Buffer.from(a)))
264
+ .sort()
265
+ .join(iface_1.ADDRESS_SEPARATOR);
322
266
  return {
323
267
  value: outputAmount.toString(),
324
268
  address,
@@ -330,61 +274,91 @@ class Utils {
330
274
  };
331
275
  }
332
276
  /**
333
- * remove hex prefix (0x)
334
- * @param hex string
335
- * @returns hex without 0x
277
+ * Removes 0x prefix from hex string
336
278
  */
337
279
  removeHexPrefix(hex) {
338
- if (hex.startsWith('0x')) {
339
- return hex.substring(2);
340
- }
341
- return hex;
280
+ return hex.startsWith('0x') ? hex.substring(2) : hex;
342
281
  }
343
282
  /**
344
- * Outputidx convert from number (as string) to buffer.
345
- * @param {string} outputidx number
346
- * @return {Buffer} buffer of size 4 with that number value
283
+ * Converts output index to buffer
347
284
  */
348
285
  outputidxNumberToBuffer(outputidx) {
349
- return Buffer.from(Number(outputidx).toString(16).padStart(constants_1.OUTPUT_INDEX_HEX_LENGTH, '0'), 'hex');
286
+ return buffer_1.Buffer.from(Number(outputidx).toString(16).padStart(8, '0'), 'hex');
350
287
  }
351
288
  /**
352
- * Outputidx buffer to number (as string)
353
- * @param {Buffer} outputidx
354
- * @return {string} outputidx number
289
+ * Converts output index buffer to number string
355
290
  */
356
291
  outputidxBufferToNumber(outputidx) {
357
292
  return parseInt(outputidx.toString('hex'), 16).toString();
358
293
  }
359
294
  /**
360
- * CB58 decode function - simple Base58 decode implementation
361
- * @param {string} data - CB58 encoded string
362
- * @returns {Buffer} decoded buffer
295
+ * Decodes a base58 string with checksum to a Buffer
363
296
  */
364
- cb58Decode(data) {
365
- // For now, use a simple hex decode as placeholder
366
- // In a full implementation, this would be proper CB58 decoding
367
- try {
368
- return Buffer.from(data, 'hex');
369
- }
370
- catch {
371
- // Fallback to buffer from string
372
- return Buffer.from(data);
297
+ cb58Decode(str) {
298
+ const decoded = bs58_1.default.decode(str);
299
+ if (!this.validateChecksum(buffer_1.Buffer.from(decoded))) {
300
+ throw new Error('Invalid checksum');
373
301
  }
302
+ return buffer_1.Buffer.from(decoded.slice(0, decoded.length - 4));
303
+ }
304
+ /**
305
+ * Validates a checksum on a Buffer and returns true if valid, false if not
306
+ */
307
+ validateChecksum(buff) {
308
+ const hashSlice = buff.slice(buff.length - 4);
309
+ const calculatedHashSlice = (0, crypto_1.createHash)('sha256')
310
+ .update(buff.slice(0, buff.length - 4))
311
+ .digest()
312
+ .slice(28);
313
+ return hashSlice.toString('hex') === calculatedHashSlice.toString('hex');
314
+ }
315
+ /**
316
+ * Encodes a Buffer as a base58 string with checksum
317
+ */
318
+ cb58Encode(bytes) {
319
+ const withChecksum = this.addChecksum(bytes);
320
+ return bs58_1.default.encode(withChecksum);
321
+ }
322
+ /**
323
+ * Adds a checksum to a Buffer and returns the concatenated result
324
+ */
325
+ addChecksum(buff) {
326
+ const hashSlice = (0, crypto_1.createHash)('sha256').update(buff).digest().slice(28);
327
+ return buffer_1.Buffer.concat([buff, hashSlice]);
328
+ }
329
+ flareIdString(value) {
330
+ return new flarejs_1.Id(buffer_1.Buffer.from(value, 'hex'));
374
331
  }
375
332
  /**
376
- * Convert address buffer to bech32 string
377
- * @param {string} hrp - Human readable part
378
- * @param {string} chainid - Chain identifier
379
- * @param {Buffer} addressBuffer - Address buffer
380
- * @returns {string} Address string
333
+ * FlareJS wrapper to recover signature
334
+ * @param network
335
+ * @param message
336
+ * @param signature
337
+ * @return recovered public key
381
338
  */
382
- addressToString(hrp, chainid, addressBuffer) {
383
- // Simple implementation - in practice this would use bech32 encoding
384
- return `${chainid}-${addressBuffer.toString('hex')}`;
339
+ recoverySignature(network, message, signature) {
340
+ try {
341
+ // Hash the message first - must match the hash used in signing
342
+ const messageHash = (0, crypto_1.createHash)('sha256').update(message).digest();
343
+ // Extract recovery parameter and signature
344
+ if (signature.length !== 65) {
345
+ throw new Error('Invalid signature length - expected 65 bytes (64 bytes signature + 1 byte recovery)');
346
+ }
347
+ const recoveryParam = signature[64];
348
+ const sigOnly = signature.slice(0, 64);
349
+ // Recover public key using the provided recovery parameter
350
+ const recovered = secp256k1_1.ecc.recoverPublicKey(messageHash, sigOnly, recoveryParam, true);
351
+ if (!recovered) {
352
+ throw new Error('Failed to recover public key');
353
+ }
354
+ return buffer_1.Buffer.from(recovered);
355
+ }
356
+ catch (error) {
357
+ throw new Error(`Failed to recover signature: ${error.message}`);
358
+ }
385
359
  }
386
360
  }
387
361
  exports.Utils = Utils;
388
362
  const utils = new Utils();
389
363
  exports.default = utils;
390
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLG1EQVE4QjtBQUU5Qix3REFBMEM7QUFDMUMsdURBQW9EO0FBRXBELDJDQVdxQjtBQUVyQixNQUFhLEtBQUs7SUFBbEI7UUE0RlMsaUJBQVksR0FBRyxDQUFDLEdBQVcsRUFBVSxFQUFFO1lBQzVDLHlDQUF5QztZQUN6QyxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsNEJBQTRCO1FBQzlELENBQUMsQ0FBQztJQWlSSixDQUFDO0lBL1dRLFNBQVMsQ0FBQyxlQUF5QixFQUFFLG1CQUE2QjtRQUN2RSxPQUFPLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDcEcsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsa0JBQWtCO0lBQ2xCLGNBQWMsQ0FBQyxPQUEwQjtRQUN2QyxNQUFNLFVBQVUsR0FBYSxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFbkYsS0FBSyxNQUFNLE9BQU8sSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZDLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFF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QVEsRUFBRSxDQUFDO0lBQzVELENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsVUFBVSxDQUFDLElBQVk7UUFDckIsa0RBQWtEO1FBQ2xELCtEQUErRDtRQUMvRCxJQUFJLENBQUM7WUFDSCxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxpQ0FBaUM7WUFDakMsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNCLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsZUFBZSxDQUFDLEdBQVcsRUFBRSxPQUFlLEVBQUUsYUFBcUI7UUFDakUscUVBQXFFO1FBQ3JFLE9BQU8sR0FBRyxPQUFPLElBQUksYUFBYSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO0lBQ3ZELENBQUM7Q0FDRjtBQWhYRCxzQkFnWEM7QUFFRCxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO0FBRTFCLGtCQUFlLEtBQUssQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRyYW5zZmVyYWJsZU91dHB1dCB9IGZyb20gJ0BmbGFyZW5ldHdvcmsvZmxhcmVqcyc7XG5pbXBvcnQge1xuICBCYXNlVXRpbHMsXG4gIEVudHJ5LFxuICBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcixcbiAgaXNWYWxpZFhwcnYsXG4gIGlzVmFsaWRYcHViLFxuICBOb3RJbXBsZW1lbnRlZEVycm9yLFxuICBQYXJzZVRyYW5zYWN0aW9uRXJyb3IsXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEZsYXJlTmV0d29yayB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0ICogYXMgY3JlYXRlSGFzaCBmcm9tICdjcmVhdGUtaGFzaCc7XG5pbXBvcnQgeyBzZWNwMjU2azEgfSBmcm9tICdAbm9ibGUvY3VydmVzL3NlY3AyNTZrMSc7XG5pbXBvcnQgeyBEZXByZWNhdGVkT3V0cHV0LCBEZXByZWNhdGVkVHgsIE91dHB1dCB9IGZyb20gJy4vaWZhY2UnO1xuaW1wb3J0IHtcbiAgREVDT0RFRF9CTE9DS19JRF9MRU5HVEgsXG4gIFNIT1JUX1BVQl9LRVlfTEVOR1RILFxuICBDT01QUkVTU0VEX1BVQkxJQ19LRVlfTEVOR1RILFxuICBVTkNPTVBSRVNTRURfUFVCTElDX0tFWV9MRU5HVEgsXG4gIFJBV19QUklWQVRFX0tFWV9MRU5HVEgsXG4gIFNVRkZJWEVEX1BSSVZBVEVfS0VZX0xFTkdUSCxcbiAgUFJJVkFURV9LRVlfQ09NUFJFU1NFRF9TVUZGSVgsXG4gIE9VVFBVVF9JTkRFWF9IRVhfTEVOR1RILFxuICBBRERSRVNTX1JFR0VYLFxuICBIRVhfUkVHRVgsXG59IGZyb20gJy4vY29uc3RhbnRzJztcblxuZXhwb3J0IGNsYXNzIFV0aWxzIGltcGxlbWVudHMgQmFzZVV0aWxzIHtcbiAgcHVibGljIGluY2x1ZGVJbih3YWxsZXRBZGRyZXNzZXM6IHN0cmluZ1tdLCBvdHhvT3V0cHV0QWRkcmVzc2VzOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB3YWxsZXRBZGRyZXNzZXMubWFwKChhKSA9PiBvdHhvT3V0cHV0QWRkcmVzc2VzLmluY2x1ZGVzKGEpKS5yZWR1Y2UoKGEsIGIpID0+IGEgJiYgYiwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGl0IGlzIGEgdmFsaWQgYWRkcmVzcyBubyBpbGxlZ2FsIGNoYXJhY3RlcnNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFkZHJlc3MgLSBhZGRyZXNzIHRvIGJlIHZhbGlkYXRlZFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB0aGUgdmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBpc1ZhbGlkQWRkcmVzcyhhZGRyZXNzOiBzdHJpbmcgfCBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGFkZHJlc3NBcnI6IHN0cmluZ1tdID0gQXJyYXkuaXNBcnJheShhZGRyZXNzKSA/IGFkZHJlc3MgOiBhZGRyZXNzLnNwbGl0KCd+Jyk7XG5cbiAgICBmb3IgKGNvbnN0IGFkZHJlc3Mgb2YgYWRkcmVzc0Fycikge1xuICAgICAgaWYgKCF0aGlzLmlzVmFsaWRBZGRyZXNzUmVnZXgoYWRkcmVzcykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1ZhbGlkQWRkcmVzc1JlZ2V4KGFkZHJlc3M6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBBRERSRVNTX1JFR0VYLnRlc3QoYWRkcmVzcyk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGl0IGlzIGEgdmFsaWQgYmxvY2tJZCB3aXRoIGxlbmd0aCA2NiBpbmNsdWRpbmcgMHhcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGhhc2ggLSBibG9ja0lkIHRvIGJlIHZhbGlkYXRlZFxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB0aGUgdmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBpc1ZhbGlkQmxvY2tJZChoYXNoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAvLyBGbGFyZUpTIGVxdWl2YWxlbnQgLSBjaGVjayBpZiBpdCdzIGEgdmFsaWQgQ0I1OCBoYXNoIHdpdGggY29ycmVjdCBsZW5ndGhcbiAgICB0cnkge1xuICAgICAgY29uc3QgZGVjb2RlZCA9IEJ1ZmZlci5mcm9tKGhhc2gpOyAvLyBGbGFyZUpTIHNob3VsZCBwcm92aWRlIENCNTggdXRpbGl0aWVzXG4gICAgICByZXR1cm4gZGVjb2RlZC5sZW5ndGggPT09IERFQ09ERURfQkxPQ0tfSURfTEVOR1RIO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIHN0cmluZyBpcyBhIHZhbGlkIHByb3RvY29sIHB1YmxpYyBrZXkgb3JcbiAgICogZXh0ZW5kZWQgcHVibGljIGtleS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHB1YiAtIHRoZSAgcHVibGljIGtleSB0byBiZSB2YWxpZGF0ZWRcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBpc1ZhbGlkUHVibGljS2V5KHB1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKGlzVmFsaWRYcHViKHB1YikpIHJldHVybiB0cnVlO1xuXG4gICAgbGV0IHB1YkJ1ZjogQnVmZmVyO1xuICAgIGlmIChwdWIubGVuZ3RoID09PSBTSE9SVF9QVUJfS0VZX0xFTkdUSCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gRm9yIEZsYXJlSlMsIHdlJ2xsIG5lZWQgdG8gaW1wbGVtZW50IENCNTggZGVjb2RlIGZ1bmN0aW9uYWxpdHlcbiAgICAgICAgcHViQnVmID0gQnVmZmVyLmZyb20ocHViLCAnaGV4Jyk7IC8vIFRlbXBvcmFyeSBwbGFjZWhvbGRlclxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHB1Yi5sZW5ndGggIT09IENPTVBSRVNTRURfUFVCTElDX0tFWV9MRU5HVEggJiYgcHViLmxlbmd0aCAhPT0gVU5DT01QUkVTU0VEX1BVQkxJQ19LRVlfTEVOR1RIKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmlyc3RCeXRlID0gcHViLnNsaWNlKDAsIDIpO1xuXG4gICAgICAvLyB1bmNvbXByZXNzZWQgcHVibGljIGtleVxuICAgICAgaWYgKHB1Yi5sZW5ndGggPT09IFVOQ09NUFJFU1NFRF9QVUJMSUNfS0VZX0xFTkdUSCAmJiBmaXJzdEJ5dGUgIT09ICcwNCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICAvLyBjb21wcmVzc2VkIHB1YmxpYyBrZXlcbiAgICAgIGlmIChwdWIubGVuZ3RoID09PSBDT01QUkVTU0VEX1BVQkxJQ19LRVlfTEVOR1RIICYmIGZpcnN0Qnl0ZSAhPT0gJzAyJyAmJiBmaXJzdEJ5dGUgIT09ICcwMycpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuYWxsSGV4Q2hhcnMocHViKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgcHViQnVmID0gQnVmZmVyLmZyb20ocHViLCAnaGV4Jyk7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHRoZSBwdWJsaWMga2V5IHVzaW5nIG5vYmxlIHNlY3AyNTZrMVxuICAgIHRyeSB7XG4gICAgICBzZWNwMjU2azEuUHJvamVjdGl2ZVBvaW50LmZyb21IZXgocHViQnVmLnRvU3RyaW5nKCdoZXgnKSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHBhcnNlQWRkcmVzcyA9IChwdWI6IHN0cmluZyk6IEJ1ZmZlciA9PiB7XG4gICAgLy8gRmxhcmVKUyBlcXVpdmFsZW50IGZvciBhZGRyZXNzIHBhcnNpbmdcbiAgICByZXR1cm4gQnVmZmVyLmZyb20ocHViLCAnaGV4Jyk7IC8vIFNpbXBsaWZpZWQgaW1wbGVtZW50YXRpb25cbiAgfTtcblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgc3RyaW5nIGlzIGEgdmFsaWQgcHJvdG9jb2wgcHJpdmF0ZSBrZXksIG9yIGV4dGVuZGVkXG4gICAqIHByaXZhdGUga2V5LlxuICAgKlxuICAgKiBUaGUgcHJvdG9jb2wga2V5IGZvcm1hdCBpcyBkZXNjcmliZWQgaW4gdGhlIEBzdGFja3MvdHJhbnNhY3Rpb25zIG5wbSBwYWNrYWdlLCBpbiB0aGVcbiAgICogY3JlYXRlU3RhY2tzUHJpdmF0ZUtleSBmdW5jdGlvbjpcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL2Jsb2Nrc3RhY2svc3RhY2tzLmpzL2Jsb2IvbWFzdGVyL3BhY2thZ2VzL3RyYW5zYWN0aW9ucy9zcmMva2V5cy50cyNMMTI1XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcnYgLSB0aGUgcHJpdmF0ZSBrZXkgKG9yIGV4dGVuZGVkIHByaXZhdGUga2V5KSB0byBiZSB2YWxpZGF0ZWRcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdGhlIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBpc1ZhbGlkUHJpdmF0ZUtleShwcnY6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmIChpc1ZhbGlkWHBydihwcnYpKSByZXR1cm4gdHJ1ZTtcblxuICAgIGlmIChwcnYubGVuZ3RoICE9PSBSQVdfUFJJVkFURV9LRVlfTEVOR1RIICYmIHBydi5sZW5ndGggIT09IFNVRkZJWEVEX1BSSVZBVEVfS0VZX0xFTkdUSCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHBydi5sZW5ndGggPT09IFNVRkZJWEVEX1BSSVZBVEVfS0VZX0xFTkdUSCAmJlxuICAgICAgcHJ2LnNsaWNlKFJBV19QUklWQVRFX0tFWV9MRU5HVEgpICE9PSBQUklWQVRFX0tFWV9DT01QUkVTU0VEX1NVRkZJWFxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmFsbEhleENoYXJzKHBydik7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgc3RyaW5nIGlzIGEgY29tcG9zZWQgb2YgaGV4IGNoYXJzIG9ubHlcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1heWJlIC0gdGhlICBzdHJpbmcgdG8gYmUgdmFsaWRhdGVkXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIHRoZSB2YWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgYWxsSGV4Q2hhcnMobWF5YmU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBIRVhfUkVHRVgudGVzdChtYXliZSk7XG4gIH1cblxuICAvKiogQGluaGVyaXRkb2MgKi9cbiAgaXNWYWxpZFNpZ25hdHVyZShzaWduYXR1cmU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCdpc1ZhbGlkU2lnbmF0dXJlIG5vdCBpbXBsZW1lbnRlZCcpO1xuICB9XG5cbiAgLyoqIEBpbmhlcml0ZG9jICovXG4gIGlzVmFsaWRUcmFuc2FjdGlvbklkKHR4SWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCdpc1ZhbGlkVHJhbnNhY3Rpb25JZCBub3QgaW1wbGVtZW50ZWQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGFyZUpTIHdyYXBwZXIgdG8gY3JlYXRlIHNpZ25hdHVyZSBhbmQgcmV0dXJuIGl0IGZvciBjcmVkZW50aWFsc1xuICAgKiBAcGFyYW0gbmV0d29ya1xuICAgKiBAcGFyYW0gbWVzc2FnZVxuICAgKiBAcGFyYW0gcHJ2XG4gICAqIEByZXR1cm4gc2lnbmF0dXJlXG4gICAqL1xuICBjcmVhdGVTaWduYXR1cmUobmV0d29yazogRmxhcmVOZXR3b3JrLCBtZXNzYWdlOiBCdWZmZXIsIHBydjogQnVmZmVyKTogQnVmZmVyIHtcbiAgICAvLyBVc2Ugc2VjcDI1NmsxIGRpcmVjdGx5IHNpbmNlIEZsYXJlSlMgbWF5IG5vdCBleHBvc2UgS2V5UGFpciBpbiB0aGUgc2FtZSB3YXlcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gc2VjcDI1NmsxLnNpZ24obWVzc2FnZSwgcHJ2KTtcbiAgICAgIHJldHVybiBCdWZmZXIuZnJvbShzaWduYXR1cmUudG9Db21wYWN0UmF3Qnl0ZXMoKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBzaWduYXR1cmU6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZsYXJlSlMgd3JhcHBlciB0byB2ZXJpZnkgc2lnbmF0dXJlXG4gICAqIEBwYXJhbSBuZXR3b3JrXG4gICAqIEBwYXJhbSBtZXNzYWdlXG4gICAqIEBwYXJhbSBzaWduYXR1cmVcbiAgICogQHBhcmFtIHB1YmxpY0tleSAtIHB1YmxpYyBrZXkgaW5zdGVhZCBvZiBwcml2YXRlIGtleSBmb3IgdmVyaWZpY2F0aW9uXG4gICAqIEByZXR1cm4gdHJ1ZSBpZiBpdCdzIHZlcmlmeSBzdWNjZXNzZnVsXG4gICAqL1xuICB2ZXJpZnlTaWduYXR1cmUobmV0d29yazogRmxhcmVOZXR3b3JrLCBtZXNzYWdlOiBCdWZmZXIsIHNpZ25hdHVyZTogQnVmZmVyLCBwdWJsaWNLZXk6IEJ1ZmZlcik6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gc2VjcDI1NmsxLnZlcmlmeShzaWduYXR1cmUsIG1lc3NhZ2UsIHB1YmxpY0tleSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmxhcmVKUyB3cmFwcGVyIHRvIHJlY292ZXIgc2lnbmF0dXJlXG4gICAqIEBwYXJhbSBuZXR3b3JrXG4gICAqIEBwYXJhbSBtZXNzYWdlXG4gICAqIEBwYXJhbSBzaWduYXR1cmVcbiAgICogQHJldHVybiByZWNvdmVyZWQgcHVibGljIGtleVxuICAgKi9cbiAgcmVjb3ZlcnlTaWduYXR1cmUobmV0d29yazogRmxhcmVOZXR3b3JrLCBtZXNzYWdlOiBCdWZmZXIsIHNpZ25hdHVyZTogQnVmZmVyKTogQnVmZmVyIHtcbiAgICB0cnkge1xuICAgICAgLy8gVGhpcyB3b3VsZCBuZWVkIHRvIGJlIGltcGxlbWVudGVkIHdpdGggc2VjcDI1NmsxIHJlY292ZXJ5XG4gICAgICAvLyBGb3Igbm93LCB0aHJvd2luZyBlcnJvciBzaW5jZSByZWNvdmVyeSBsb2dpYyB3b3VsZCBuZWVkIHRvIGJlIGFkYXB0ZWRcbiAgICAgIHRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEVycm9yKCdyZWNvdmVyeVNpZ25hdHVyZSBub3QgZnVsbHkgaW1wbGVtZW50ZWQgZm9yIEZsYXJlSlMnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gcmVjb3ZlciBzaWduYXR1cmU6ICR7ZXJyb3J9YCk7XG4gICAgfVxuICB9XG5cbiAgc2hhMjU2KGJ1ZjogVWludDhBcnJheSk6IEJ1ZmZlciB7XG4gICAgcmV0dXJuIGNyZWF0ZUhhc2guZGVmYXVsdCgnc2hhMjU2JykudXBkYXRlKGJ1ZikuZGlnZXN0KCk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgdGhlIHJhdyB0cmFuc2FjdGlvbiBoYXMgYSB2YWxpZCBmb3JtYXQgaW4gdGhlIGJsb2NrY2hhaW4gY29udGV4dCwgdGhyb3cgb3RoZXJ3aXNlLlxuICAgKiBJdCdzIHRvIHJldXNlIGluIFRyYW5zYWN0aW9uQnVpbGRlciBhbmQgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeVxuICAgKlxuICAgKiBAcGFyYW0gcmF3VHJhbnNhY3Rpb24gVHJhbnNhY3Rpb24gYXMgaGV4IHN0cmluZ1xuICAgKi9cbiAgdmFsaWRhdGVSYXdUcmFuc2FjdGlvbihyYXdUcmFuc2FjdGlvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFyYXdUcmFuc2FjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRUcmFuc2FjdGlvbkVycm9yKCdSYXcgdHJhbnNhY3Rpb24gaXMgZW1wdHknKTtcbiAgICB9XG4gICAgaWYgKCF1dGlscy5hbGxIZXhDaGFycyhyYXdUcmFuc2FjdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZVRyYW5zYWN0aW9uRXJyb3IoJ1JhdyB0cmFuc2FjdGlvbiBpcyBub3QgaGV4IHN0cmluZycpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0eCBpcyBmb3IgdGhlIGJsb2NrY2hhaW5JZFxuICAgKlxuICAgKiBAcGFyYW0ge0RlcHJlY2F0ZWRUeH0gdHhcbiAgICogQHBhcmFtIHtzdHJpbmd9IGJsb2NrY2hhaW5JZFxuICAgKiBAcmV0dXJucyB0cnVlIGlmIHR4IGlzIGZvciBibG9ja2NoYWluSWRcbiAgICovXG4gIGlzVHJhbnNhY3Rpb25PZih0eDogRGVwcmVjYXRlZFR4LCBibG9ja2NoYWluSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIC8vIEZsYXJlSlMgZXF1aXZhbGVudCAtIHRoaXMgd291bGQgbmVlZCBwcm9wZXIgQ0I1OCBlbmNvZGluZyBpbXBsZW1lbnRhdGlvblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB0eFJlY29yZCA9IHR4IGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICBjb25zdCB1bnNpZ25lZFR4ID0gKHR4UmVjb3JkLmdldFVuc2lnbmVkVHggYXMgKCkgPT4gUmVjb3JkPHN0cmluZywgdW5rbm93bj4pKCk7XG4gICAgICBjb25zdCB0cmFuc2FjdGlvbiA9ICh1bnNpZ25lZFR4LmdldFRyYW5zYWN0aW9uIGFzICgpID0+IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSgpO1xuICAgICAgY29uc3QgdHhCbG9ja2NoYWluSWQgPSAodHJhbnNhY3Rpb24uZ2V0QmxvY2tjaGFpbklEIGFzICgpID0+IHVua25vd24pKCk7XG4gICAgICByZXR1cm4gQnVmZmVyLmZyb20odHhCbG9ja2NoYWluSWQgYXMgc3RyaW5nKS50b1N0cmluZygnaGV4JykgPT09IGJsb2NrY2hhaW5JZDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBPdXRwdXQgaXMgZnJvbSBQVk0uXG4gICAqIE91dHB1dCBjb3VsZCBiZSBFVk0gb3IgUFZNIG91dHB1dC5cbiAgICogQHBhcmFtIHtEZXByZWNhdGVkT3V0cHV0fSBvdXRwdXRcbiAgICogQHJldHVybnMge2Jvb2xlYW59IG91dHB1dCBoYXMgdHJhbnNmZXJhYmxlIG91dHB1dCBzdHJ1Y3R1cmVcbiAgICovXG4gIGRlcHJlY2F0ZWRJc1RyYW5zZmVyYWJsZU91dHB1dChvdXRwdXQ6IERlcHJlY2F0ZWRPdXRwdXQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gJ2dldE91dHB1dCcgaW4gKG91dHB1dCBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgT3V0cHV0IGlzIGZyb20gUFZNLlxuICAgKiBPdXRwdXQgY291bGQgYmUgRVZNIG9yIFBWTSBvdXRwdXQuXG4gICAqIEBwYXJhbSB7T3V0cHV0fSBvdXRwdXRcbiAgICogQHJldHVybnMge2Jvb2xlYW59IG91dHB1dCBpcyBUcmFuc2ZlcmFibGVPdXRwdXRcbiAgICovXG4gIGlzVHJhbnNmZXJhYmxlT3V0cHV0KG91dHB1dDogT3V0cHV0KTogb3V0cHV0IGlzIFRyYW5zZmVyYWJsZU91dHB1dCB7XG4gICAgcmV0dXJuIHR5cGVvZiAob3V0cHV0IGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLmdldE91dHB1dCA9PT0gJ2Z1bmN0aW9uJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBtYXBwZXIgZnVuY3Rpb24gdG8gdGhhdCBuZXR3b3JrIGFkZHJlc3MgcmVwcmVzZW50YXRpb24uXG4gICAqIEBwYXJhbSBuZXR3b3JrIHJlcXVpcmVkIHRvIHN0cmluZ2lmeSBhZGRyZXNzZXNcbiAgICogQHJldHVybiBtYXBwZXIgZnVuY3Rpb25cbiAgICovXG4gIGRlcHJlY2F0ZWRNYXBPdXRwdXRUb0VudHJ5KG5ldHdvcms6IEZsYXJlTmV0d29yayk6IChvdXRwdXQ6IERlcHJlY2F0ZWRPdXRwdXQpID0+IEVudHJ5IHtcbiAgICByZXR1cm4gKG91dHB1dDogRGVwcmVjYXRlZE91dHB1dCkgPT4ge1xuICAgICAgaWYgKHRoaXMuZGVwcmVjYXRlZElzVHJhbnNmZXJhYmxlT3V0cHV0KG91dHB1dCkpIHtcbiAgICAgICAgLy8gU2ltcGxpZmllZCBpbXBsZW1lbnRhdGlvbiBmb3IgRmxhcmVKU1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHRyYW5zZmVyYWJsZU91dHB1dCA9IG91dHB1dCBhcyB1bmtub3duIGFzIFRyYW5zZmVyYWJsZU91dHB1dDtcbiAgICAgICAgICBjb25zdCBhbW91bnQgPSB0cmFuc2ZlcmFibGVPdXRwdXQuYW1vdW50KCk7XG5cbiAgICAgICAgICAvLyBTaW1wbGlmaWVkIGFkZHJlc3MgaGFuZGxpbmcgLSB3b3VsZCBuZWVkIHByb3BlciBGbGFyZUpTIGFkZHJlc3MgdXRpbGl0aWVzXG4gICAgICAgICAgY29uc3QgYWRkcmVzcyA9ICdmbGFyZS1hZGRyZXNzLXBsYWNlaG9sZGVyJzsgLy8gVE9ETzogaW1wbGVtZW50IHByb3BlciBhZGRyZXNzIGNvbnZlcnNpb25cblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWx1ZTogYW1vdW50LnRvU3RyaW5nKCksXG4gICAgICAgICAgICBhZGRyZXNzLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gbWFwIG91dHB1dDogJHtlcnJvcn1gKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSGFuZGxlIEVWTSBvdXRwdXQgY2FzZSAtIHNpbXBsaWZpZWRcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB2YWx1ZTogJzAnLCAvLyBUT0RPOiBpbXBsZW1lbnQgcHJvcGVyIGFtb3VudCBleHRyYWN0aW9uXG4gICAgICAgICAgYWRkcmVzczogJzB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsIC8vIFRPRE86IGltcGxlbWVudCBwcm9wZXIgYWRkcmVzcyBleHRyYWN0aW9uXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBtYXBwZXIgZnVuY3Rpb24gdG8gdGhhdCBuZXR3b3JrIGFkZHJlc3MgcmVwcmVzZW50YXRpb24uXG4gICAqIEBwYXJhbSBuZXR3b3JrIHJlcXVpcmVkIHRvIHN0cmluZ2lmeSBhZGRyZXNzZXNcbiAgICogQHJldHVybiBtYXBwZXIgZnVuY3Rpb25cbiAgICovXG4gIG1hcE91dHB1dFRvRW50cnkobmV0d29yazogRmxhcmVOZXR3b3JrKTogKE91dHB1dCkgPT4gRW50cnkge1xuICAgIHJldHVybiAob3V0cHV0OiBPdXRwdXQpID0+IHtcbiAgICAgIGlmICh0aGlzLmlzVHJhbnNmZXJhYmxlT3V0cHV0KG91dHB1dCkpIHtcbiAgICAgICAgY29uc3QgdHJhbnNmZXJhYmxlT3V0cHV0ID0gb3V0cHV0IGFzIFRyYW5zZmVyYWJsZU91dHB1dDtcbiAgICAgICAgY29uc3Qgb3V0cHV0QW1vdW50ID0gdHJhbnNmZXJhYmxlT3V0cHV0LmFtb3VudCgpO1xuXG4gICAgICAgIC8vIFNpbXBsaWZpZWQgYWRkcmVzcyBoYW5kbGluZyBmb3IgRmxhcmVKU1xuICAgICAgICBjb25zdCBhZGRyZXNzID0gJ2ZsYXJlLWFkZHJlc3MtcGxhY2Vob2xkZXInOyAvLyBUT0RPOiBpbXBsZW1lbnQgcHJvcGVyIGFkZHJlc3MgY29udmVyc2lvblxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsdWU6IG91dHB1dEFtb3VudC50b1N0cmluZygpLFxuICAgICAgICAgIGFkZHJlc3MsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgb3V0cHV0IHR5cGUnKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIHJlbW92ZSBoZXggcHJlZml4ICgweClcbiAgICogQHBhcmFtIGhleCBzdHJpbmdcbiAgICogQHJldHVybnMgaGV4IHdpdGhvdXQgMHhcbiAgICovXG4gIHJlbW92ZUhleFByZWZpeChoZXg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKGhleC5zdGFydHNXaXRoKCcweCcpKSB7XG4gICAgICByZXR1cm4gaGV4LnN1YnN0cmluZygyKTtcbiAgICB9XG4gICAgcmV0dXJuIGhleDtcbiAgfVxuXG4gIC8qKlxuICAgKiBPdXRwdXRpZHggY29udmVydCBmcm9tIG51bWJlciAoYXMgc3RyaW5nKSB0byBidWZmZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvdXRwdXRpZHggbnVtYmVyXG4gICAqIEByZXR1cm4ge0J1ZmZlcn0gYnVmZmVyIG9mIHNpemUgNCB3aXRoIHRoYXQgbnVtYmVyIHZhbHVlXG4gICAqL1xuICBvdXRwdXRpZHhOdW1iZXJUb0J1ZmZlcihvdXRwdXRpZHg6IHN0cmluZyk6IEJ1ZmZlciB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKE51bWJlcihvdXRwdXRpZHgpLnRvU3RyaW5nKDE2KS5wYWRTdGFydChPVVRQVVRfSU5ERVhfSEVYX0xFTkdUSCwgJzAnKSwgJ2hleCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIE91dHB1dGlkeCBidWZmZXIgdG8gbnVtYmVyIChhcyBzdHJpbmcpXG4gICAqIEBwYXJhbSB7QnVmZmVyfSBvdXRwdXRpZHhcbiAgICogQHJldHVybiB7c3RyaW5nfSBvdXRwdXRpZHggbnVtYmVyXG4gICAqL1xuICBvdXRwdXRpZHhCdWZmZXJUb051bWJlcihvdXRwdXRpZHg6IEJ1ZmZlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHBhcnNlSW50KG91dHB1dGlkeC50b1N0cmluZygnaGV4JyksIDE2KS50b1N0cmluZygpO1xuICB9XG5cbiAgLyoqXG4gICAqIENCNTggZGVjb2RlIGZ1bmN0aW9uIC0gc2ltcGxlIEJhc2U1OCBkZWNvZGUgaW1wbGVtZW50YXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGEgLSBDQjU4IGVuY29kZWQgc3RyaW5nXG4gICAqIEByZXR1cm5zIHtCdWZmZXJ9IGRlY29kZWQgYnVmZmVyXG4gICAqL1xuICBjYjU4RGVjb2RlKGRhdGE6IHN0cmluZyk6IEJ1ZmZlciB7XG4gICAgLy8gRm9yIG5vdywgdXNlIGEgc2ltcGxlIGhleCBkZWNvZGUgYXMgcGxhY2Vob2xkZXJcbiAgICAvLyBJbiBhIGZ1bGwgaW1wbGVtZW50YXRpb24sIHRoaXMgd291bGQgYmUgcHJvcGVyIENCNTggZGVjb2RpbmdcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRhdGEsICdoZXgnKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIEZhbGxiYWNrIHRvIGJ1ZmZlciBmcm9tIHN0cmluZ1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRhdGEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGFkZHJlc3MgYnVmZmVyIHRvIGJlY2gzMiBzdHJpbmdcbiAgICogQHBhcmFtIHtzdHJpbmd9IGhycCAtIEh1bWFuIHJlYWRhYmxlIHBhcnRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNoYWluaWQgLSBDaGFpbiBpZGVudGlmaWVyXG4gICAqIEBwYXJhbSB7QnVmZmVyfSBhZGRyZXNzQnVmZmVyIC0gQWRkcmVzcyBidWZmZXJcbiAgICogQHJldHVybnMge3N0cmluZ30gQWRkcmVzcyBzdHJpbmdcbiAgICovXG4gIGFkZHJlc3NUb1N0cmluZyhocnA6IHN0cmluZywgY2hhaW5pZDogc3RyaW5nLCBhZGRyZXNzQnVmZmVyOiBCdWZmZXIpOiBzdHJpbmcge1xuICAgIC8vIFNpbXBsZSBpbXBsZW1lbnRhdGlvbiAtIGluIHByYWN0aWNlIHRoaXMgd291bGQgdXNlIGJlY2gzMiBlbmNvZGluZ1xuICAgIHJldHVybiBgJHtjaGFpbmlkfS0ke2FkZHJlc3NCdWZmZXIudG9TdHJpbmcoJ2hleCcpfWA7XG4gIH1cbn1cblxuY29uc3QgdXRpbHMgPSBuZXcgVXRpbHMoKTtcblxuZXhwb3J0IGRlZmF1bHQgdXRpbHM7XG4iXX0=
364
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLG1EQUF1RztBQUN2RyxtREFPOEI7QUFFOUIsbUNBQWdDO0FBQ2hDLG1DQUFvQztBQUNwQyxxREFBNEM7QUFDNUMsbUNBQW9EO0FBQ3BELGdEQUF3QjtBQUN4QixtQ0FBZ0M7QUFFaEMsTUFBYSxLQUFLO0lBQWxCO1FBMFBFOztXQUVHO1FBQ0ksb0JBQWUsR0FBRyxDQUFDLEdBQVcsRUFBRSxNQUFjLEVBQUUsT0FBZSxFQUFVLEVBQUU7WUFDaEYsK0RBQStEO1lBQy9ELE1BQU0sS0FBSyxHQUFHLGVBQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdEMsK0VBQStFO1lBQy9FLE9BQU8sR0FBRyxNQUFNLElBQUksZUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNsRCxDQUFDLENBQUM7UUF5Q0YsbURBQW1EO1FBRW5EOzs7O1dBSUc7UUFDSSxpQkFBWSxHQUFHLENBQUMsT0FBZSxFQUFVLEVBQUU7WUFDaEQsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZDLENBQUMsQ0FBQztRQUVLLG9CQUFlLEdBQUcsQ0FBQyxPQUFlLEVBQUUsR0FBWSxFQUFVLEVBQUU7WUFDakUsdUJBQXVCO1lBQ3ZCLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUM3QixPQUFPLGVBQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM5QyxDQUFDO1lBRUQsbUNBQW1DO1lBQ25DLElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ3RDLE9BQU8sZUFBTSxDQUFDLElB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YSxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNwQyxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUV2QywyREFBMkQ7WUFDM0QsTUFBTSxTQUFTLEdBQUcsZUFBRyxDQUFDLGdCQUFnQixDQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2xGLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDZixNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7WUFDbEQsQ0FBQztZQUVELE9BQU8sZUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNoQyxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ25FLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUF2WEQsc0JBdVhDO0FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztBQUMxQixrQkFBZSxLQUFLLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTaWduYXR1cmUsIFRyYW5zZmVyYWJsZU91dHB1dCwgVHJhbnNmZXJPdXRwdXQsIFR5cGVTeW1ib2xzLCBJZCB9IGZyb20gJ0BmbGFyZW5ldHdvcmsvZmxhcmVqcyc7XG5pbXBvcnQge1xuICBCYXNlVXRpbHMsXG4gIEVudHJ5LFxuICBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcixcbiAgaXNWYWxpZFhwcnYsXG4gIGlzVmFsaWRYcHViLFxuICBQYXJzZVRyYW5zYWN0aW9uRXJyb3IsXG59IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IEZsYXJlTmV0d29yayB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSAnYnVmZmVyJztcbmltcG9ydCB7IGNyZWF0ZUhhc2ggfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgZWNjIH0gZnJvbSAnQGJpdGdvLWJldGEvc2VjcDI1NmsxJztcbmltcG9ydCB7IEFERFJFU1NfU0VQQVJBVE9SLCBPdXRwdXQgfSBmcm9tICcuL2lmYWNlJztcbmltcG9ydCBiczU4IGZyb20gJ2JzNTgnO1xuaW1wb3J0IHsgYmVjaDMyIH0gZnJvbSAnYmVjaDMyJztcblxuZXhwb3J0IGNsYXNzIFV0aWxzIGltcGxlbWVudHMgQmFzZVV0aWxzIHtcbiAgaXNWYWxpZFRyYW5zYWN0aW9uSWQodHhJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNZXRob2Qgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG4gIGlzVmFsaWRTaWduYXR1cmUoc2lnbmF0dXJlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBub3QgaW1wbGVtZW50ZWQuJyk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIGlmIGFkZHJlc3NlcyBpbiB3YWxsZXQgbWF0Y2ggVVRYTyBvdXRwdXQgYWRkcmVzc2VzXG4gICAqL1xuICBwdWJsaWMgaW5jbHVkZUluKHdhbGxldEFkZHJlc3Nlczogc3RyaW5nW10sIG90eG9PdXRwdXRBZGRyZXNzZXM6IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHdhbGxldEFkZHJlc3Nlcy5tYXAoKGEpID0+IG90eG9PdXRwdXRBZGRyZXNzZXMuaW5jbHVkZXMoYSkpLnJlZHVjZSgoYSwgYikgPT4gYSAmJiBiLCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYSBGbGFyZSBhZGRyZXNzIG9yIGFycmF5IG9mIGFkZHJlc3Nlc1xuICAgKiBAcGFyYW0ge3N0cmluZyB8IHN0cmluZ1tdfSBhZGRyZXNzIC0gYWRkcmVzcyhlcykgdG8gdmFsaWRhdGVcbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gdmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIGlzVmFsaWRBZGRyZXNzKGFkZHJlc3M6IHN0cmluZyB8IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYWRkcmVzc0Fycjogc3RyaW5nW10gPSBBcnJheS5pc0FycmF5KGFkZHJlc3MpID8gYWRkcmVzcyA6IGFkZHJlc3Muc3BsaXQoJ34nKTtcblxuICAgIGZvciAoY29uc3QgYWRkcmVzcyBvZiBhZGRyZXNzQXJyKSB7XG4gICAgICBpZiAoIXRoaXMuaXNWYWxpZEFkZHJlc3NSZWdleChhZGRyZXNzKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGlzVmFsaWRBZGRyZXNzUmVnZXgoYWRkcmVzczogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIC9eKF5QfHxOb2RlSUQpLVthLXpBLVowLTldKyQvLnRlc3QoYWRkcmVzcyk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgYmxvY2sgSURcbiAgICogQHBhcmFtIHtzdHJpbmd9IGhhc2ggLSBibG9jayBJRCB0byB2YWxpZGF0ZVxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB2YWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgaXNWYWxpZEJsb2NrSWQoaGFzaDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSBCdWZmZXIuZnJvbShoYXNoLCAnaGV4Jyk7XG4gICAgICByZXR1cm4gZGVjb2RlZC5sZW5ndGggPT09IDMyO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYSBwdWJsaWMga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwdWIgLSBwdWJsaWMga2V5IHRvIHZhbGlkYXRlXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIHZhbGlkYXRpb24gcmVzdWx0XG4gICAqL1xuICBpc1ZhbGlkUHVibGljS2V5KHB1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKGlzVmFsaWRYcHViKHB1YikpIHJldHVybiB0cnVlO1xuXG4gICAgbGV0IHB1YkJ1ZjogQnVmZmVyO1xuICAgIGlmIChwdWIubGVuZ3RoID09PSA1MCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcHViQnVmID0gQnVmZmVyLmZyb20ocHViLCAnaGV4Jyk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAocHViLmxlbmd0aCAhPT0gNjYgJiYgcHViLmxlbmd0aCAhPT0gMTMwKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIGNvbnN0IGZpcnN0Qnl0ZSA9IHB1Yi5zbGljZSgwLCAyKTtcbiAgICAgIGlmIChwdWIubGVuZ3RoID09PSAxMzAgJiYgZmlyc3RCeXRlICE9PSAnMDQnKSByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAocHViLmxlbmd0aCA9PT0gNjYgJiYgZmlyc3RCeXRlICE9PSAnMDInICYmIGZpcnN0Qnl0ZSAhPT0gJzAzJykgcmV0dXJuIGZhbHNlO1xuICAgICAgaWYgKCF0aGlzLmFsbEhleENoYXJzKHB1YikpIHJldHVybiBmYWxzZTtcblxuICAgICAgcHViQnVmID0gQnVmZmVyLmZyb20ocHViLCAnaGV4Jyk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGVjYy5pc1BvaW50KHB1YkJ1Zik7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBhIHByaXZhdGUga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcnYgLSBwcml2YXRlIGtleSB0byB2YWxpZGF0ZVxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSB2YWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgaXNWYWxpZFByaXZhdGVLZXkocHJ2OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoaXNWYWxpZFhwcnYocHJ2KSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKHBydi5sZW5ndGggIT09IDY0ICYmIHBydi5sZW5ndGggIT09IDY2KSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHBydi5sZW5ndGggPT09IDY2ICYmIHBydi5zbGljZSg2NCkgIT09ICcwMScpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdGhpcy5hbGxIZXhDaGFycyhwcnYpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBhIHN0cmluZyBjb250YWlucyBvbmx5IGhleCBjaGFyYWN0ZXJzXG4gICAqL1xuICBhbGxIZXhDaGFycyhzdHI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAvXigweCl7MCwxfShbMC05YS1mXSkrJC9pLnRlc3Qoc3RyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgc2lnbmF0dXJlIHVzaW5nIHRoZSBGbGFyZSBuZXR3b3JrIHBhcmFtZXRlcnNcbiAgICogUmV0dXJucyBhIDY1LWJ5dGUgc2lnbmF0dXJlICg2NCBieXRlcyBzaWduYXR1cmUgKyAxIGJ5dGUgcmVjb3ZlcnkgcGFyYW1ldGVyKVxuICAgKi9cbiAgY3JlYXRlU2lnbmF0dXJlKG5ldHdvcms6IEZsYXJlTmV0d29yaywgbWVzc2FnZTogQnVmZmVyLCBwcnY6IEJ1ZmZlcik6IEJ1ZmZlciB7XG4gICAgY29uc3QgbWVzc2FnZUhhc2ggPSB0aGlzLnNoYTI1NihtZXNzYWdlKTtcbiAgICBjb25zdCBzaWduYXR1cmUgPSBlY2Muc2lnbihtZXNzYWdlSGFzaCwgcHJ2KTtcblxuICAgIC8vIEdldCB0aGUgcHVibGljIGtleSBmcm9tIHRoZSBwcml2YXRlIGtleSBmb3IgcmVjb3ZlcnkgcGFyYW1ldGVyIGRldGVybWluYXRpb25cbiAgICBjb25zdCBwdWJsaWNLZXkgPSBlY2MucG9pbnRGcm9tU2NhbGFyKHBydiwgdHJ1ZSk7XG4gICAgaWYgKCFwdWJsaWNLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGRlcml2ZSBwdWJsaWMga2V5IGZyb20gcHJpdmF0ZSBrZXknKTtcbiAgICB9XG5cbiAgICAvLyBUcnkgcmVjb3Zlcnkgd2l0aCBwYXJhbSAwIGFuZCAxIHRvIGZpbmQgdGhlIGNvcnJlY3Qgb25lXG4gICAgbGV0IHJlY292ZXJ5UGFyYW0gPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IDE7IGkrKykge1xuICAgICAgY29uc3QgcmVjb3ZlcmVkID0gZWNjLnJlY292ZXJQdWJsaWNLZXkobWVzc2FnZUhhc2gsIHNpZ25hdHVyZSwgaSwgdHJ1ZSk7XG4gICAgICBpZiAocmVjb3ZlcmVkICYmIEJ1ZmZlci5mcm9tKHJlY292ZXJlZCkuZXF1YWxzKEJ1ZmZlci5mcm9tKHB1YmxpY0tleSkpKSB7XG4gICAgICAgIHJlY292ZXJ5UGFyYW0gPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBcHBlbmQgcmVjb3ZlcnkgcGFyYW1ldGVyIHRvIGNyZWF0ZSA2NS1ieXRlIHNpZ25hdHVyZVxuICAgIGNvbnN0IHNpZ1dpdGhSZWNvdmVyeSA9IEJ1ZmZlci5hbGxvYyg2NSk7XG4gICAgQnVmZmVyLmZyb20oc2lnbmF0dXJlKS5jb3B5KHNpZ1dpdGhSZWNvdmVyeSwgMCk7XG4gICAgc2lnV2l0aFJlY292ZXJ5WzY0XSA9IHJlY292ZXJ5UGFyYW07XG5cbiAgICByZXR1cm4gc2lnV2l0aFJlY292ZXJ5O1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmaWVzIGEgc2lnbmF0dXJlXG4gICAqL1xuICB2ZXJpZnlTaWduYXR1cmUobmV0d29yazogRmxhcmVOZXR3b3JrLCBtZXNzYWdlOiBCdWZmZXIsIHNpZ25hdHVyZTogQnVmZmVyLCBwdWJsaWNLZXk6IEJ1ZmZlcik6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBtZXNzYWdlSGFzaCA9IHRoaXMuc2hhMjU2KG1lc3NhZ2UpO1xuICAgICAgcmV0dXJuIGVjYy52ZXJpZnkobWVzc2FnZUhhc2gsIHB1YmxpY0tleSwgc2lnbmF0dXJlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgc2lnbmF0dXJlIG9iamVjdFxuICAgKi9cbiAgY3JlYXRlTmV3U2lnKHNpZ0hleDogc3RyaW5nKTogU2lnbmF0dXJlIHtcbiAgICBjb25zdCBidWZmZXIgPSBCdWZmZXIuZnJvbShzaWdIZXgucGFkU3RhcnQoMTMwLCAnMCcpLCAnaGV4Jyk7XG4gICAgcmV0dXJuIG5ldyBTaWduYXR1cmUoYnVmZmVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGVtcHR5IHNpZ25hdHVyZSB3aXRoIGVtYmVkZGVkIGFkZHJlc3MgZm9yIHNpZ25hdHVyZSBzbG90IGlkZW50aWZpY2F0aW9uLlxuICAgKiBUaGUgYWRkcmVzcyBpcyBlbWJlZGRlZCBhdCBwb3NpdGlvbiA5MCAoYWZ0ZXIgdGhlIGZpcnN0IDQ1IHplcm8gYnl0ZXMpLlxuICAgKiBUaGlzIGFsbG93cyB0aGUgc2lnbmluZyBsb2dpYyB0byBkZXRlcm1pbmUgd2hpY2ggc2xvdCBiZWxvbmdzIHRvIHdoaWNoIGFkZHJlc3MuXG4gICAqIEBwYXJhbSBhZGRyZXNzSGV4IFRoZSAyMC1ieXRlIGFkZHJlc3MgaW4gaGV4IGZvcm1hdCAoNDAgY2hhcnMsIHdpdGhvdXQgMHggcHJlZml4KVxuICAgKi9cbiAgY3JlYXRlRW1wdHlTaWdXaXRoQWRkcmVzcyhhZGRyZXNzSGV4OiBzdHJpbmcpOiBTaWduYXR1cmUge1xuICAgIC8vIEZpcnN0IDQ1IGJ5dGVzICg5MCBoZXggY2hhcnMpIGFyZSB6ZXJvcywgZm9sbG93ZWQgYnkgMjAtYnl0ZSBhZGRyZXNzICg0MCBoZXggY2hhcnMpXG4gICAgY29uc3QgY2xlYW5BZGRyID0gdGhpcy5yZW1vdmVIZXhQcmVmaXgoYWRkcmVzc0hleCkudG9Mb3dlckNhc2UoKTtcbiAgICBjb25zdCBzaWdIZXggPSAnMCcucmVwZWF0KDkwKSArIGNsZWFuQWRkci5wYWRTdGFydCg0MCwgJzAnKTtcbiAgICBjb25zdCBidWZmZXIgPSBCdWZmZXIuZnJvbShzaWdIZXgsICdoZXgnKTtcbiAgICByZXR1cm4gbmV3IFNpZ25hdHVyZShidWZmZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3RzIHRoZSBlbWJlZGRlZCBhZGRyZXNzIGZyb20gYW4gZW1wdHkgc2lnbmF0dXJlLlxuICAgKiBSZXR1cm5zIHRoZSBhZGRyZXNzIGhleCBzdHJpbmcgKDQwIGNoYXJzKSBvciBlbXB0eSBzdHJpbmcgaWYgbm90IGZvdW5kLlxuICAgKi9cbiAgZ2V0QWRkcmVzc0Zyb21FbXB0eVNpZyhzaWc6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY2xlYW5TaWcgPSB0aGlzLnJlbW92ZUhleFByZWZpeChzaWcpO1xuICAgIGlmIChjbGVhblNpZy5sZW5ndGggPj0gMTMwKSB7XG4gICAgICAvLyBBZGRyZXNzIGlzIGF0IHBvc2l0aW9uIDkwLTEzMCAobGFzdCA0MCBoZXggY2hhcnMgPSAyMCBieXRlcylcbiAgICAgIHJldHVybiBjbGVhblNpZy5zdWJzdHJpbmcoOTAsIDEzMCkudG9Mb3dlckNhc2UoKTtcbiAgICB9XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGVzIFNIQTI1NiBoYXNoXG4gICAqL1xuICBzaGEyNTYoYnVmOiBVaW50OEFycmF5KTogQnVmZmVyIHtcbiAgICByZXR1cm4gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKGJ1ZikuZGlnZXN0KCk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHJhdyB0cmFuc2FjdGlvbiBmb3JtYXRcbiAgICovXG4gIHZhbGlkYXRlUmF3VHJhbnNhY3Rpb24ocmF3VHJhbnNhY3Rpb246IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghcmF3VHJhbnNhY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBJbnZhbGlkVHJhbnNhY3Rpb25FcnJvcignUmF3IHRyYW5zYWN0aW9uIGlzIGVtcHR5Jyk7XG4gICAgfVxuICAgIGlmICghdGhpcy5hbGxIZXhDaGFycyhyYXdUcmFuc2FjdGlvbikpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZVRyYW5zYWN0aW9uRXJyb3IoJ1JhdyB0cmFuc2FjdGlvbiBpcyBub3QgaGV4IHN0cmluZycpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgb3V0cHV0IGlzIFRyYW5zZmVyYWJsZU91dHB1dCB0eXBlXG4gICAqL1xuICBpc1RyYW5zZmVyYWJsZU91dHB1dChvdXRwdXQ6IE91dHB1dCk6IG91dHB1dCBpcyBUcmFuc2ZlcmFibGVPdXRwdXQge1xuICAgIHJldHVybiBvdXRwdXQ/Ll90eXBlID09PSBUeXBlU3ltYm9scy5UcmFuc2ZlcmFibGVPdXRwdXQ7XG4gIH1cblxuICAvKipcbiAgICogTWFwcyBvdXRwdXRzIHRvIGVudHJ5IGZvcm1hdFxuICAgKi9cbiAgbWFwT3V0cHV0VG9FbnRyeShuZXR3b3JrOiBGbGFyZU5ldHdvcmspOiAoT3V0cHV0KSA9PiBFbnRyeSB7XG4gICAgcmV0dXJuIChvdXRwdXQ6IE91dHB1dCkgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNUcmFuc2ZlcmFibGVPdXRwdXQob3V0cHV0KSkge1xuICAgICAgICBjb25zdCBvdXRwdXRBbW91bnQgPSBvdXRwdXQuYW1vdW50KCk7XG4gICAgICAgIGNvbnN0IGFkZHJlc3MgPSAob3V0cHV0Lm91dHB1dCBhcyBUcmFuc2Zlck91dHB1dClcbiAgICAgICAgICAuZ2V0T3duZXJzKClcbiAgICAgICAgICAubWFwKChhKSA9PiB0aGlzLmFkZHJlc3NUb1N0cmluZyhuZXR3b3JrLmhycCwgbmV0d29yay5hbGlhcywgQnVmZmVyLmZyb20oYSkpKVxuICAgICAgICAgIC5zb3J0KClcbiAgICAgICAgICAuam9pbihBRERSRVNTX1NFUEFSQVRPUik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmFsdWU6IG91dHB1dEFtb3VudC50b1N0cmluZygpLFxuICAgICAgICAgIGFkZHJlc3MsXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgb3V0cHV0IHR5cGUnKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgMHggcHJlZml4IGZyb20gaGV4IHN0cmluZ1xuICAgKi9cbiAgcmVtb3ZlSGV4UHJlZml4KGhleDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gaGV4LnN0YXJ0c1dpdGgoJzB4JykgPyBoZXguc3Vic3RyaW5nKDIpIDogaGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG91dHB1dCBpbmRleCB0byBidWZmZXJcbiAgICovXG4gIG91dHB1dGlkeE51bWJlclRvQnVmZmVyKG91dHB1dGlkeDogc3RyaW5nKTogQnVmZmVyIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oTnVtYmVyKG91dHB1dGlkeCkudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDgsICcwJyksICdoZXgnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvdXRwdXQgaW5kZXggYnVmZmVyIHRvIG51bWJlciBzdHJpbmdcbiAgICovXG4gIG91dHB1dGlkeEJ1ZmZlclRvTnVtYmVyKG91dHB1dGlkeDogQnVmZmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcGFyc2VJbnQob3V0cHV0aWR4LnRvU3RyaW5nKCdoZXgnKSwgMTYpLnRvU3RyaW5nKCk7XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIG1ldGhvZCB0byBjb252ZXJ0IGFkZHJlc3MgY29tcG9uZW50cyB0byBzdHJpbmdcbiAgICovXG4gIHB1YmxpYyBhZGRyZXNzVG9TdHJpbmcgPSAoaHJwOiBzdHJpbmcsIHByZWZpeDogc3RyaW5nLCBhZGRyZXNzOiBCdWZmZXIpOiBzdHJpbmcgPT4ge1xuICAgIC8vIENvbnZlcnQgdGhlIGFkZHJlc3MgYnl0ZXMgdG8gNS1iaXQgd29yZHMgZm9yIGJlY2gzMiBlbmNvZGluZ1xuICAgIGNvbnN0IHdvcmRzID0gYmVjaDMyLnRvV29yZHMoYWRkcmVzcyk7XG4gICAgLy8gQ3JlYXRlIHRoZSBmdWxsIGJlY2gzMiBhZGRyZXNzIHdpdGggZm9ybWF0OiBQLXtocnB9MXtiZWNoMzJfZW5jb2RlZF9hZGRyZXNzfVxuICAgIHJldHVybiBgJHtwcmVmaXh9LSR7YmVjaDMyLmVuY29kZShocnAsIHdvcmRzKX1gO1xuICB9O1xuXG4gIC8qKlxuICAgKiBEZWNvZGVzIGEgYmFzZTU4IHN0cmluZyB3aXRoIGNoZWNrc3VtIHRvIGEgQnVmZmVyXG4gICAqL1xuICBwdWJsaWMgY2I1OERlY29kZShzdHI6IHN0cmluZyk6IEJ1ZmZlciB7XG4gICAgY29uc3QgZGVjb2RlZCA9IGJzNTguZGVjb2RlKHN0cik7XG4gICAgaWYgKCF0aGlzLnZhbGlkYXRlQ2hlY2tzdW0oQnVmZmVyLmZyb20oZGVjb2RlZCkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY2hlY2tzdW0nKTtcbiAgICB9XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRlY29kZWQuc2xpY2UoMCwgZGVjb2RlZC5sZW5ndGggLSA0KSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgY2hlY2tzdW0gb24gYSBCdWZmZXIgYW5kIHJldHVybnMgdHJ1ZSBpZiB2YWxpZCwgZmFsc2UgaWYgbm90XG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlQ2hlY2tzdW0oYnVmZjogQnVmZmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgaGFzaFNsaWNlID0gYnVmZi5zbGljZShidWZmLmxlbmd0aCAtIDQpO1xuICAgIGNvbnN0IGNhbGN1bGF0ZWRIYXNoU2xpY2UgPSBjcmVhdGVIYXNoKCdzaGEyNTYnKVxuICAgICAgLnVwZGF0ZShidWZmLnNsaWNlKDAsIGJ1ZmYubGVuZ3RoIC0gNCkpXG4gICAgICAuZGlnZXN0KClcbiAgICAgIC5zbGljZSgyOCk7XG4gICAgcmV0dXJuIGhhc2hTbGljZS50b1N0cmluZygnaGV4JykgPT09IGNhbGN1bGF0ZWRIYXNoU2xpY2UudG9TdHJpbmcoJ2hleCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuY29kZXMgYSBCdWZmZXIgYXMgYSBiYXNlNTggc3RyaW5nIHdpdGggY2hlY2tzdW1cbiAgICovXG4gIHB1YmxpYyBjYjU4RW5jb2RlKGJ5dGVzOiBCdWZmZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IHdpdGhDaGVja3N1bSA9IHRoaXMuYWRkQ2hlY2tzdW0oYnl0ZXMpO1xuICAgIHJldHVybiBiczU4LmVuY29kZSh3aXRoQ2hlY2tzdW0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBjaGVja3N1bSB0byBhIEJ1ZmZlciBhbmQgcmV0dXJucyB0aGUgY29uY2F0ZW5hdGVkIHJlc3VsdFxuICAgKi9cbiAgcHJpdmF0ZSBhZGRDaGVja3N1bShidWZmOiBCdWZmZXIpOiBCdWZmZXIge1xuICAgIGNvbnN0IGhhc2hTbGljZSA9IGNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShidWZmKS5kaWdlc3QoKS5zbGljZSgyOCk7XG4gICAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW2J1ZmYsIGhhc2hTbGljZV0pO1xuICB9XG5cbiAgLy8gSW4gdXRpbHMudHMsIGFkZCB0aGlzIG1ldGhvZCB0byB0aGUgVXRpbHMgY2xhc3M6XG5cbiAgLyoqXG4gICAqIFBhcnNlIGFuIGFkZHJlc3Mgc3RyaW5nIGludG8gYSBCdWZmZXJcbiAgICogQHBhcmFtIGFkZHJlc3MgLSBUaGUgYWRkcmVzcyB0byBwYXJzZVxuICAgKiBAcmV0dXJucyBCdWZmZXIgY29udGFpbmluZyB0aGUgcGFyc2VkIGFkZHJlc3NcbiAgICovXG4gIHB1YmxpYyBwYXJzZUFkZHJlc3MgPSAoYWRkcmVzczogc3RyaW5nKTogQnVmZmVyID0+IHtcbiAgICByZXR1cm4gdGhpcy5zdHJpbmdUb0FkZHJlc3MoYWRkcmVzcyk7XG4gIH07XG5cbiAgcHVibGljIHN0cmluZ1RvQWRkcmVzcyA9IChhZGRyZXNzOiBzdHJpbmcsIGhycD86IHN0cmluZyk6IEJ1ZmZlciA9PiB7XG4gICAgLy8gSGFuZGxlIGhleCBhZGRyZXNzZXNcbiAgICBpZiAoYWRkcmVzcy5zdGFydHNXaXRoKCcweCcpKSB7XG4gICAgICByZXR1cm4gQnVmZmVyLmZyb20oYWRkcmVzcy5zbGljZSgyKSwgJ2hleCcpO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSByYXcgaGV4IHdpdGhvdXQgMHggcHJlZml4XG4gICAgaWYgKC9eWzAtOWEtZkEtRl17NDB9JC8udGVzdChhZGRyZXNzKSkge1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGFkZHJlc3MsICdoZXgnKTtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgQmVjaDMyIGFkZHJlc3Nlc1xuICAgIGNvbnN0IHBhcnRzID0gYWRkcmVzcy50cmltKCkuc3BsaXQoJy0nKTtcbiAgICBpZiAocGFydHMubGVuZ3RoIDwgMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFcnJvciAtIFZhbGlkIGFkZHJlc3Mgc2hvdWxkIGluY2x1ZGUgLScpO1xuICAgIH1cblxuICAgIGNvbnN0IHNwbGl0ID0gcGFydHNbMV0ubGFzdEluZGV4T2YoJzEnKTtcbiAgICBpZiAoc3BsaXQgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIC0gVmFsaWQgYmVjaDMyIGFkZHJlc3MgbXVzdCBpbmNsdWRlIHNlcGFyYXRvciAoMSknKTtcbiAgICB9XG5cbiAgICBjb25zdCBodW1hblJlYWRhYmxlUGFydCA9IHBhcnRzWzFdLnNsaWNlKDAsIHNwbGl0KTtcbiAgICBpZiAoaHVtYW5SZWFkYWJsZVBhcnQgIT09ICdmbGFyZScgJiYgaHVtYW5SZWFkYWJsZVBhcnQgIT09ICdjb3N0d28nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Vycm9yIC0gSW52YWxpZCBIUlAnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gQnVmZmVyLmZyb20oYmVjaDMyLmZyb21Xb3JkcyhiZWNoMzIuZGVjb2RlKHBhcnRzWzFdKS53b3JkcykpO1xuICB9O1xuXG4gIGZsYXJlSWRTdHJpbmcodmFsdWU6IHN0cmluZyk6IElkIHtcbiAgICByZXR1cm4gbmV3IElkKEJ1ZmZlci5mcm9tKHZhbHVlLCAnaGV4JykpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZsYXJlSlMgd3JhcHBlciB0byByZWNvdmVyIHNpZ25hdHVyZVxuICAgKiBAcGFyYW0gbmV0d29ya1xuICAgKiBAcGFyYW0gbWVzc2FnZVxuICAgKiBAcGFyYW0gc2lnbmF0dXJlXG4gICAqIEByZXR1cm4gcmVjb3ZlcmVkIHB1YmxpYyBrZXlcbiAgICovXG4gIHJlY292ZXJ5U2lnbmF0dXJlKG5ldHdvcms6IEZsYXJlTmV0d29yaywgbWVzc2FnZTogQnVmZmVyLCBzaWduYXR1cmU6IEJ1ZmZlcik6IEJ1ZmZlciB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEhhc2ggdGhlIG1lc3NhZ2UgZmlyc3QgLSBtdXN0IG1hdGNoIHRoZSBoYXNoIHVzZWQgaW4gc2lnbmluZ1xuICAgICAgY29uc3QgbWVzc2FnZUhhc2ggPSBjcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUobWVzc2FnZSkuZGlnZXN0KCk7XG5cbiAgICAgIC8vIEV4dHJhY3QgcmVjb3ZlcnkgcGFyYW1ldGVyIGFuZCBzaWduYXR1cmVcbiAgICAgIGlmIChzaWduYXR1cmUubGVuZ3RoICE9PSA2NSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc2lnbmF0dXJlIGxlbmd0aCAtIGV4cGVjdGVkIDY1IGJ5dGVzICg2NCBieXRlcyBzaWduYXR1cmUgKyAxIGJ5dGUgcmVjb3ZlcnkpJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlY292ZXJ5UGFyYW0gPSBzaWduYXR1cmVbNjRdO1xuICAgICAgY29uc3Qgc2lnT25seSA9IHNpZ25hdHVyZS5zbGljZSgwLCA2NCk7XG5cbiAgICAgIC8vIFJlY292ZXIgcHVibGljIGtleSB1c2luZyB0aGUgcHJvdmlkZWQgcmVjb3ZlcnkgcGFyYW1ldGVyXG4gICAgICBjb25zdCByZWNvdmVyZWQgPSBlY2MucmVjb3ZlclB1YmxpY0tleShtZXNzYWdlSGFzaCwgc2lnT25seSwgcmVjb3ZlcnlQYXJhbSwgdHJ1ZSk7XG4gICAgICBpZiAoIXJlY292ZXJlZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byByZWNvdmVyIHB1YmxpYyBrZXknKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHJlY292ZXJlZCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHJlY292ZXIgc2lnbmF0dXJlOiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IHV0aWxzID0gbmV3IFV0aWxzKCk7XG5leHBvcnQgZGVmYXVsdCB1dGlscztcbiJdfQ==