@bitgo-beta/sdk-coin-kaspa 0.0.1-beta.21 → 0.0.1-beta.211

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 (49) hide show
  1. package/README.md +224 -33
  2. package/dist/src/kaspa.d.ts +86 -18
  3. package/dist/src/kaspa.d.ts.map +1 -1
  4. package/dist/src/kaspa.js +119 -31
  5. package/dist/src/lib/constants.d.ts +38 -0
  6. package/dist/src/lib/constants.d.ts.map +1 -1
  7. package/dist/src/lib/constants.js +56 -5
  8. package/dist/src/lib/iface.d.ts +28 -17
  9. package/dist/src/lib/iface.d.ts.map +1 -1
  10. package/dist/src/lib/iface.js +1 -1
  11. package/dist/src/lib/index.d.ts +2 -0
  12. package/dist/src/lib/index.d.ts.map +1 -1
  13. package/dist/src/lib/index.js +4 -2
  14. package/dist/src/lib/keyPair.d.ts +6 -2
  15. package/dist/src/lib/keyPair.d.ts.map +1 -1
  16. package/dist/src/lib/keyPair.js +7 -4
  17. package/dist/src/lib/pskt.d.ts +257 -0
  18. package/dist/src/lib/pskt.d.ts.map +1 -0
  19. package/dist/src/lib/pskt.js +439 -0
  20. package/dist/src/lib/sighash.d.ts +34 -13
  21. package/dist/src/lib/sighash.d.ts.map +1 -1
  22. package/dist/src/lib/sighash.js +115 -56
  23. package/dist/src/lib/transaction.d.ts +94 -6
  24. package/dist/src/lib/transaction.d.ts.map +1 -1
  25. package/dist/src/lib/transaction.js +199 -21
  26. package/dist/src/lib/transactionBuilder.d.ts +22 -0
  27. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  28. package/dist/src/lib/transactionBuilder.js +53 -5
  29. package/dist/src/lib/transactionBuilderFactory.d.ts +8 -3
  30. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  31. package/dist/src/lib/transactionBuilderFactory.js +14 -4
  32. package/dist/src/lib/utils.d.ts +17 -3
  33. package/dist/src/lib/utils.d.ts.map +1 -1
  34. package/dist/src/lib/utils.js +45 -11
  35. package/dist/src/register.js +2 -2
  36. package/dist/test/fixtures/kaspa.fixtures.d.ts +12 -0
  37. package/dist/test/fixtures/kaspa.fixtures.d.ts.map +1 -1
  38. package/dist/test/fixtures/kaspa.fixtures.js +76 -11
  39. package/dist/test/unit/coin.test.js +129 -9
  40. package/dist/test/unit/keyPair.test.js +35 -1
  41. package/dist/test/unit/pskt.test.d.ts +15 -0
  42. package/dist/test/unit/pskt.test.d.ts.map +1 -0
  43. package/dist/test/unit/pskt.test.js +383 -0
  44. package/dist/test/unit/transaction.test.js +291 -11
  45. package/dist/test/unit/transactionBuilder.test.js +16 -3
  46. package/dist/test/unit/transactionFlow.test.js +67 -2
  47. package/dist/test/unit/utils.test.js +63 -4
  48. package/dist/tsconfig.tsbuildinfo +1 -1
  49. package/package.json +6 -5
@@ -1,38 +1,60 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SCRIPT_PUBLIC_KEY_VERSION = exports.OP_CHECKSIG_SCHNORR = exports.SIGHASH_ANYONECANPAY = exports.SIGHASH_SINGLE = exports.SIGHASH_NONE = exports.SIGHASH_ALL = void 0;
4
3
  exports.buildP2PKScriptPublicKey = buildP2PKScriptPublicKey;
5
4
  exports.compressedToXOnly = compressedToXOnly;
6
5
  exports.computeKaspaSigningHash = computeKaspaSigningHash;
6
+ exports.computeKaspaEcdsaSigningHash = computeKaspaEcdsaSigningHash;
7
7
  /**
8
8
  * Kaspa transaction sighash computation.
9
9
  *
10
- * BIP-143-like scheme using Blake2b-256. All integer fields are little-endian.
10
+ * BIP-143-like scheme using keyed Blake2b-256. All integer fields are
11
+ * little-endian.
12
+ *
13
+ * ALL hashes (intermediate and final) use the same keyed Blake2b-256 hasher:
14
+ * blake2b_256(data, key="TransactionSigningHash")
11
15
  *
12
16
  * Reference (authoritative implementation):
17
+ * https://github.com/kaspanet/rusty-kaspa/blob/master/crypto/hashes/src/hashers.rs
13
18
  * https://github.com/kaspanet/rusty-kaspa/blob/master/consensus/core/src/hashing/sighash.rs
14
19
  */
15
20
  const blakejs_1 = require("blakejs");
16
- // SigHash type flags
17
- exports.SIGHASH_ALL = 0x01;
18
- exports.SIGHASH_NONE = 0x02;
19
- exports.SIGHASH_SINGLE = 0x04;
20
- exports.SIGHASH_ANYONECANPAY = 0x80;
21
- // Script constants
22
- exports.OP_CHECKSIG_SCHNORR = 0xab; // Kaspa Schnorr checksig opcode
23
- exports.SCRIPT_PUBLIC_KEY_VERSION = 0; // Standard P2PK version
24
- function blake2b256(data) {
25
- return Buffer.from((0, blakejs_1.blake2b)(data, undefined, 32));
21
+ const crypto_1 = require("crypto");
22
+ const constants_1 = require("./constants");
23
+ /**
24
+ * The Blake2b key used for ALL sighash operations in Kaspa.
25
+ * Defined in rusty-kaspa crypto/hashes/src/hashers.rs:
26
+ * blake2b_hasher! { struct TransactionSigningHash => b"TransactionSigningHash", ... }
27
+ * which resolves to:
28
+ * blake2b_simd::Params::new().hash_length(32).key(b"TransactionSigningHash").to_state()
29
+ */
30
+ const SIGNING_HASH_KEY = Buffer.from('TransactionSigningHash', 'ascii');
31
+ function kblake2b(data) {
32
+ return Buffer.from((0, blakejs_1.blake2b)(data, SIGNING_HASH_KEY, 32));
26
33
  }
27
34
  /**
28
- * Build P2PK Schnorr scriptPublicKey from a 32-byte x-only public key.
29
- * Format: DATA_32(0x20) + xOnlyPubKey(32 bytes) + OP_CHECKSIG_SCHNORR(0xAB)
35
+ * Build a Kaspa P2PK scriptPublicKey.
36
+ *
37
+ * @param pubKey - For SCHNORR: 32-byte x-only key.
38
+ * For ECDSA: 33-byte compressed key.
39
+ * @param type - Address type (default: SCHNORR / v0).
40
+ *
41
+ * Resulting script formats (per rusty-kaspa crypto/txscript/src/standard.rs):
42
+ * SCHNORR (v0): OP_DATA_32(0x20) || xOnlyPubKey(32B) || OpCheckSig(0xAC)
43
+ * ECDSA (v1): OP_DATA_33(0x21) || compressedPubKey(33B) || OpCheckSigECDSA(0xAB)
30
44
  */
31
- function buildP2PKScriptPublicKey(xOnlyPubKey) {
32
- if (xOnlyPubKey.length !== 32) {
33
- throw new Error(`Expected 32-byte x-only pubkey, got ${xOnlyPubKey.length}`);
45
+ function buildP2PKScriptPublicKey(pubKey, type = constants_1.KaspaScriptType.SCHNORR) {
46
+ if (type === constants_1.KaspaScriptType.SCHNORR) {
47
+ if (pubKey.length !== 32) {
48
+ throw new Error(`SCHNORR script expects 32-byte x-only pubkey, got ${pubKey.length}`);
49
+ }
50
+ return Buffer.concat([Buffer.from([0x20]), pubKey, Buffer.from([constants_1.OP_CHECKSIG_SCHNORR])]);
51
+ }
52
+ else {
53
+ if (pubKey.length !== 33) {
54
+ throw new Error(`ECDSA script expects 33-byte compressed pubkey, got ${pubKey.length}`);
55
+ }
56
+ return Buffer.concat([Buffer.from([0x21]), pubKey, Buffer.from([constants_1.OP_CHECKSIG_ECDSA])]);
34
57
  }
35
- return Buffer.concat([Buffer.from([0x20]), xOnlyPubKey, Buffer.from([exports.OP_CHECKSIG_SCHNORR])]);
36
58
  }
37
59
  /**
38
60
  * Derive x-only public key from 33-byte compressed public key.
@@ -51,23 +73,28 @@ function hashPreviousOutputs(inputs) {
51
73
  buf.writeUInt32LE(inp.transactionIndex, 32);
52
74
  return buf;
53
75
  });
54
- return blake2b256(Buffer.concat(parts));
76
+ return kblake2b(Buffer.concat(parts));
55
77
  }
56
78
  function hashSequences(inputs) {
57
79
  const buf = Buffer.alloc(inputs.length * 8);
58
80
  inputs.forEach((inp, i) => {
59
81
  buf.writeBigUInt64LE(BigInt(inp.sequence || '0'), i * 8);
60
82
  });
61
- return blake2b256(buf);
83
+ return kblake2b(buf);
62
84
  }
63
85
  function hashSigOpCounts(inputs) {
64
86
  const bytes = inputs.map((inp) => inp.sigOpCount ?? 1);
65
- return blake2b256(Buffer.from(bytes));
87
+ return kblake2b(Buffer.from(bytes));
66
88
  }
89
+ /**
90
+ * Serialize one output for hashing.
91
+ * Matches hash_output() + hash_script_public_key() in rusty-kaspa:
92
+ * write_u64(value) + write_u16(spk.version) + write_var_bytes(spk.script)
93
+ * where write_var_bytes = write_u64(len) + write(bytes).
94
+ */
67
95
  function serializeOutput(output) {
68
96
  const scriptBytes = Buffer.from(output.scriptPublicKey || '', 'hex');
69
- const spkVersion = 0; // standard P2PK
70
- // value (u64 LE, 8) + spk_version (u16 LE, 2) + script_length (u64 LE, 8) + script
97
+ const spkVersion = 0;
71
98
  const buf = Buffer.alloc(8 + 2 + 8 + scriptBytes.length);
72
99
  let offset = 0;
73
100
  buf.writeBigUInt64LE(BigInt(output.amount), offset);
@@ -81,58 +108,65 @@ function serializeOutput(output) {
81
108
  }
82
109
  function hashOutputs(tx, inputIndex, sigHashType) {
83
110
  const baseType = sigHashType & 0x1f;
84
- if (baseType === exports.SIGHASH_NONE) {
85
- return Buffer.alloc(32); // zero hash
111
+ if (baseType === constants_1.SIGHASH_NONE) {
112
+ return Buffer.alloc(32);
86
113
  }
87
- if (baseType === exports.SIGHASH_SINGLE) {
114
+ if (baseType === constants_1.SIGHASH_SINGLE) {
88
115
  if (inputIndex >= tx.outputs.length) {
89
116
  return Buffer.alloc(32);
90
117
  }
91
- return blake2b256(serializeOutput(tx.outputs[inputIndex]));
118
+ return kblake2b(serializeOutput(tx.outputs[inputIndex]));
92
119
  }
93
120
  // SIGHASH_ALL
94
- const parts = tx.outputs.map(serializeOutput);
95
- return blake2b256(Buffer.concat(parts));
121
+ return kblake2b(Buffer.concat(tx.outputs.map(serializeOutput)));
96
122
  }
97
123
  function hashPayload(tx) {
98
124
  const subnetId = Buffer.from(tx.subnetworkId || '0000000000000000000000000000000000000000', 'hex');
99
- // If subnetwork is native (all zeros), payloadHash is zero
125
+ // Native subnetwork (all zeros) with empty payload → zero hash
100
126
  if (subnetId.every((b) => b === 0)) {
101
127
  return Buffer.alloc(32);
102
128
  }
103
- return blake2b256(Buffer.from(tx.payload || '', 'hex'));
129
+ // write_var_bytes(payload): u64 length prefix + payload bytes
130
+ const payloadBytes = Buffer.from(tx.payload || '', 'hex');
131
+ const lenBuf = Buffer.alloc(8);
132
+ lenBuf.writeBigUInt64LE(BigInt(payloadBytes.length));
133
+ return kblake2b(Buffer.concat([lenBuf, payloadBytes]));
104
134
  }
105
135
  /**
106
- * Compute the Kaspa sighash for a specific input.
136
+ * Compute the Kaspa Schnorr sighash for a specific input.
137
+ *
138
+ * Matches calc_schnorr_signature_hash() in rusty-kaspa sighash.rs exactly.
139
+ * All intermediate and the final hash use keyed Blake2b-256 with
140
+ * key = "TransactionSigningHash".
107
141
  *
108
- * @param tx Full transaction data
109
- * @param inputIndex Index of the input being signed
110
- * @param sigHashType SigHash type flags (use SIGHASH_ALL = 0x01 for standard)
142
+ * @param tx Full transaction data — inputs must carry amount + scriptPublicKey
143
+ * @param inputIndex 0-based index of the input being signed
144
+ * @param sigHashType SigHash type flags (SIGHASH_ALL = 0x01 for standard)
111
145
  */
112
- function computeKaspaSigningHash(tx, inputIndex, sigHashType = exports.SIGHASH_ALL) {
113
- const anyoneCanPay = !!(sigHashType & exports.SIGHASH_ANYONECANPAY);
146
+ function computeKaspaSigningHash(tx, inputIndex, sigHashType = constants_1.SIGHASH_ALL) {
147
+ const anyoneCanPay = !!(sigHashType & constants_1.SIGHASH_ANYONECANPAY);
114
148
  const baseType = sigHashType & 0x1f;
115
149
  const input = tx.inputs[inputIndex];
116
150
  if (!input) {
117
151
  throw new Error(`Input index ${inputIndex} out of range`);
118
152
  }
119
- // Conditional intermediate hashes
153
+ // Intermediate hashes
120
154
  const prevOutputsHash = anyoneCanPay ? Buffer.alloc(32) : hashPreviousOutputs(tx.inputs);
121
- const seqHash = anyoneCanPay || baseType === exports.SIGHASH_SINGLE || baseType === exports.SIGHASH_NONE
155
+ const seqHash = anyoneCanPay || baseType === constants_1.SIGHASH_SINGLE || baseType === constants_1.SIGHASH_NONE
122
156
  ? Buffer.alloc(32)
123
157
  : hashSequences(tx.inputs);
124
158
  const sigOpHash = anyoneCanPay ? Buffer.alloc(32) : hashSigOpCounts(tx.inputs);
125
159
  const outsHash = hashOutputs(tx, inputIndex, sigHashType);
126
160
  const payloadHash = hashPayload(tx);
127
- // Parse the current input's script public key
161
+ // Current input's scriptPublicKey (from the UTXO being spent)
128
162
  const scriptBytes = Buffer.from(input.scriptPublicKey || '', 'hex');
129
- const spkVersion = 0; // standard P2PK
163
+ const spkVersion = 0;
130
164
  const subnetId = Buffer.from(tx.subnetworkId || '0000000000000000000000000000000000000000', 'hex');
131
- // Build the preimage
165
+ // Build the preimage — field order matches calc_schnorr_signature_hash() exactly
132
166
  const fixedSize = 2 + 32 + 32 + 32 + 32 + 4 + 2 + 8 + 8 + 8 + 1 + 32 + 8 + 20 + 8 + 32 + 1;
133
167
  const preimage = Buffer.alloc(fixedSize + scriptBytes.length);
134
168
  let offset = 0;
135
- // 1. version
169
+ // 1. tx.version (u16 LE)
136
170
  preimage.writeUInt16LE(tx.version ?? 0, offset);
137
171
  offset += 2;
138
172
  // 2. previousOutputsHash
@@ -144,40 +178,40 @@ function computeKaspaSigningHash(tx, inputIndex, sigHashType = exports.SIGHASH_A
144
178
  // 4. sigOpCountsHash
145
179
  sigOpHash.copy(preimage, offset);
146
180
  offset += 32;
147
- // 5. current input's previous outpoint txId
181
+ // 5. input.previousOutpoint.transactionId (32 bytes)
148
182
  Buffer.from(input.transactionId, 'hex').copy(preimage, offset);
149
183
  offset += 32;
150
- // 6. current input's previous outpoint index
184
+ // 6. input.previousOutpoint.index (u32 LE)
151
185
  preimage.writeUInt32LE(input.transactionIndex, offset);
152
186
  offset += 4;
153
- // 7. scriptPublicKey version
187
+ // 7. scriptPublicKey.version (u16 LE)
154
188
  preimage.writeUInt16LE(spkVersion, offset);
155
189
  offset += 2;
156
- // 8. scriptPublicKey length (u64 LE)
190
+ // 8. scriptPublicKey.script length (u64 LE) — write_var_bytes length prefix
157
191
  preimage.writeBigUInt64LE(BigInt(scriptBytes.length), offset);
158
192
  offset += 8;
159
- // 9. scriptPublicKey bytes
193
+ // 9. scriptPublicKey.script bytes
160
194
  scriptBytes.copy(preimage, offset);
161
195
  offset += scriptBytes.length;
162
- // 10. value (amount in sompi, u64 LE)
196
+ // 10. input UTXO amount (u64 LE)
163
197
  preimage.writeBigUInt64LE(BigInt(input.amount), offset);
164
198
  offset += 8;
165
- // 11. sequence (u64 LE)
199
+ // 11. input.sequence (u64 LE)
166
200
  preimage.writeBigUInt64LE(BigInt(input.sequence || '0'), offset);
167
201
  offset += 8;
168
- // 12. sigOpCount (u8)
202
+ // 12. input.sigOpCount (u8)
169
203
  preimage.writeUInt8(input.sigOpCount ?? 1, offset);
170
204
  offset += 1;
171
205
  // 13. outputsHash
172
206
  outsHash.copy(preimage, offset);
173
207
  offset += 32;
174
- // 14. locktime (u64 LE)
208
+ // 14. tx.lockTime (u64 LE)
175
209
  preimage.writeBigUInt64LE(BigInt(tx.lockTime || '0'), offset);
176
210
  offset += 8;
177
- // 15. subnetworkId (20 bytes)
211
+ // 15. tx.subnetworkId (20 bytes)
178
212
  subnetId.copy(preimage, offset);
179
213
  offset += 20;
180
- // 16. gas (u64 LE) — always 0 for native KASPA
214
+ // 16. tx.gas (u64 LE) — always 0 for native KASPA
181
215
  preimage.writeBigUInt64LE(0n, offset);
182
216
  offset += 8;
183
217
  // 17. payloadHash
@@ -186,6 +220,31 @@ function computeKaspaSigningHash(tx, inputIndex, sigHashType = exports.SIGHASH_A
186
220
  // 18. sigHashType (u8)
187
221
  preimage.writeUInt8(sigHashType, offset);
188
222
  offset += 1;
189
- return blake2b256(preimage.slice(0, offset));
223
+ return kblake2b(preimage.slice(0, offset));
224
+ }
225
+ /**
226
+ * SHA-256 domain separator for ECDSA signing.
227
+ * Matches TransactionSigningHashECDSA in rusty-kaspa/crypto/hashes/src/hashers.rs:
228
+ * sha256_hasher! { struct TransactionSigningHashECDSA => "TransactionSigningHashECDSA" }
229
+ * The hasher is seeded with SHA256("TransactionSigningHashECDSA") before any data.
230
+ */
231
+ const ECDSA_DOMAIN_SEP = Buffer.from((0, crypto_1.createHash)('sha256').update('TransactionSigningHashECDSA').digest());
232
+ /**
233
+ * Compute the Kaspa ECDSA sighash for a specific input.
234
+ *
235
+ * ECDSA signing uses a two-step hash defined in rusty-kaspa sighash.rs:
236
+ * 1. schnorr_hash = blake2b256_keyed("TransactionSigningHash", preimage)
237
+ * 2. ecdsa_hash = SHA256( SHA256("TransactionSigningHashECDSA") || schnorr_hash )
238
+ *
239
+ * This differs from the Schnorr hash — using the Schnorr hash for ECDSA signing
240
+ * will produce a locally-valid signature that the network always rejects.
241
+ *
242
+ * @param tx Full transaction data with UTXO amount + scriptPublicKey on inputs
243
+ * @param inputIndex 0-based index of the input being signed
244
+ * @param sigHashType SigHash type flags (SIGHASH_ALL = 0x01)
245
+ */
246
+ function computeKaspaEcdsaSigningHash(tx, inputIndex, sigHashType = constants_1.SIGHASH_ALL) {
247
+ const schnorrHash = computeKaspaSigningHash(tx, inputIndex, sigHashType);
248
+ return Buffer.from((0, crypto_1.createHash)('sha256').update(ECDSA_DOMAIN_SEP).update(schnorrHash).digest());
190
249
  }
191
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnaGFzaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvc2lnaGFzaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUE2QkEsNERBS0M7QUFLRCw4Q0FLQztBQTJFRCwwREEwR0M7QUFqT0Q7Ozs7Ozs7R0FPRztBQUNILHFDQUFrQztBQUdsQyxxQkFBcUI7QUFDUixRQUFBLFdBQVcsR0FBRyxJQUFJLENBQUM7QUFDbkIsUUFBQSxZQUFZLEdBQUcsSUFBSSxDQUFDO0FBQ3BCLFFBQUEsY0FBYyxHQUFHLElBQUksQ0FBQztBQUN0QixRQUFBLG9CQUFvQixHQUFHLElBQUksQ0FBQztBQUV6QyxtQkFBbUI7QUFDTixRQUFBLG1CQUFtQixHQUFHLElBQUksQ0FBQyxDQUFDLGdDQUFnQztBQUM1RCxRQUFBLHlCQUF5QixHQUFHLENBQUMsQ0FBQyxDQUFDLHdCQUF3QjtBQUVwRSxTQUFTLFVBQVUsQ0FBQyxJQUFZO0lBQzlCLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFBLGlCQUFPLEVBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQix3QkFBd0IsQ0FBQyxXQUFtQjtJQUMxRCxJQUFJLFdBQVcsQ0FBQyxNQUFNLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDOUIsTUFBTSxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsMkJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMvRixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFnQixpQkFBaUIsQ0FBQyxn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TUFBTSxJQUFJLENBQUMsQ0FBQztJQUVaLGtCQUFrQjtJQUNsQixRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNoQyxNQUFNLElBQUksRUFBRSxDQUFDO0lBRWIsd0JBQXdCO0lBQ3hCLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFFBQVEsSUFBSSxHQUFHLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUM5RCxNQUFNLElBQUksQ0FBQyxDQUFDO0lBRVosOEJBQThCO0lBQzlCLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2hDLE1BQU0sSUFBSSxFQUFFLENBQUM7SUFFYiwrQ0FBK0M7SUFDL0MsUUFBUSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN0QyxNQUFNLElBQUksQ0FBQyxDQUFDO0lBRVosa0JBQWtCO0lBQ2xCLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ25DLE1BQU0sSUFBSSxFQUFFLENBQUM7SUFFYix1QkFBdUI7SUFDdkIsUUFBUSxDQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDekMsTUFBTSxJQUFJLENBQUMsQ0FBQztJQUVaLE9BQU8sVUFBVSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDL0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogS2FzcGEgdHJhbnNhY3Rpb24gc2lnaGFzaCBjb21wdXRhdGlvbi5cbiAqXG4gKiBCSVAtMTQzLWxpa2Ugc2NoZW1lIHVzaW5nIEJsYWtlMmItMjU2LiBBbGwgaW50ZWdlciBmaWVsZHMgYXJlIGxpdHRsZS1lbmRpYW4uXG4gKlxuICogUmVmZXJlbmNlIChhdXRob3JpdGF0aXZlIGltcGxlbWVudGF0aW9uKTpcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9rYXNwYW5ldC9ydXN0eS1rYXNwYS9ibG9iL21hc3Rlci9jb25zZW5zdXMvY29yZS9zcmMvaGFzaGluZy9zaWdoYXNoLnJzXG4gKi9cbmltcG9ydCB7IGJsYWtlMmIgfSBmcm9tICdibGFrZWpzJztcbmltcG9ydCB7IEthc3BhVHJhbnNhY3Rpb25EYXRhLCBLYXNwYVV0eG9JbnB1dCwgS2FzcGFUcmFuc2FjdGlvbk91dHB1dCB9IGZyb20gJy4vaWZhY2UnO1xuXG4vLyBTaWdIYXNoIHR5cGUgZmxhZ3NcbmV4cG9ydCBjb25zdCBTSUdIQVNIX0FMTCA9IDB4MDE7XG5leHBvcnQgY29uc3QgU0lHSEFTSF9OT05FID0gMHgwMjtcbmV4cG9ydCBjb25zdCBTSUdIQVNIX1NJTkdMRSA9IDB4MDQ7XG5leHBvcnQgY29uc3QgU0lHSEFTSF9BTllPTkVDQU5QQVkgPSAweDgwO1xuXG4vLyBTY3JpcHQgY29uc3RhbnRzXG5leHBvcnQgY29uc3QgT1BfQ0hFQ0tTSUdfU0NITk9SUiA9IDB4YWI7IC8vIEthc3BhIFNjaG5vcnIgY2hlY2tzaWcgb3Bjb2RlXG5leHBvcnQgY29uc3QgU0NSSVBUX1BVQkxJQ19LRVlfVkVSU0lPTiA9IDA7IC8vIFN0YW5kYXJkIFAyUEsgdmVyc2lvblxuXG5mdW5jdGlvbiBibGFrZTJiMjU2KGRhdGE6IEJ1ZmZlcik6IEJ1ZmZlciB7XG4gIHJldHVybiBCdWZmZXIuZnJvbShibGFrZTJiKGRhdGEsIHVuZGVmaW5lZCwgMzIpKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBQMlBLIFNjaG5vcnIgc2NyaXB0UHVibGljS2V5IGZyb20gYSAzMi1ieXRlIHgtb25seSBwdWJsaWMga2V5LlxuICogRm9ybWF0OiBEQVRBXzMyKDB4MjApICsgeE9ubHlQdWJLZXkoMzIgYnl0ZXMpICsgT1BfQ0hFQ0tTSUdfU0NITk9SUigweEFCKVxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRQMlBLU2NyaXB0UHVibGljS2V5KHhPbmx5UHViS2V5OiBCdWZmZXIpOiBCdWZmZXIge1xuICBpZiAoeE9ubHlQdWJLZXkubGVuZ3RoICE9PSAzMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgMzItYnl0ZSB4LW9ubHkgcHVia2V5LCBnb3QgJHt4T25seVB1YktleS5sZW5ndGh9YCk7XG4gIH1cbiAgcmV0dXJuIEJ1ZmZlci5jb25jYXQoW0J1ZmZlci5mcm9tKFsweDIwXSksIHhPbmx5UHViS2V5LCBCdWZmZXIuZnJvbShbT1BfQ0hFQ0tTSUdfU0NITk9SUl0pXSk7XG59XG5cbi8qKlxuICogRGVyaXZlIHgtb25seSBwdWJsaWMga2V5IGZyb20gMzMtYnl0ZSBjb21wcmVzc2VkIHB1YmxpYyBrZXkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wcmVzc2VkVG9YT25seShjb21wcmVzc2VkUHViS2V5OiBCdWZmZXIpOiBCdWZmZXIge1xuICBpZiAoY29tcHJlc3NlZFB1YktleS5sZW5ndGggIT09IDMzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAzMy1ieXRlIGNvbXByZXNzZWQgcHVia2V5LCBnb3QgJHtjb21wcmVzc2VkUHViS2V5Lmxlbmd0aH1gKTtcbiAgfVxuICByZXR1cm4gY29tcHJlc3NlZFB1YktleS5zbGljZSgxKTsgLy8gZHJvcCB0aGUgMDIvMDMgcHJlZml4IGJ5dGVcbn1cblxuLy8gLS0tIEludGVybWVkaWF0ZSBoYXNoIGhlbHBlcnMgLS0tXG5cbmZ1bmN0aW9uIGhhc2hQcmV2aW91c091dHB1dHMoaW5wdXRzOiBLYXNwYVV0eG9JbnB1dFtdKTogQnVmZmVyIHtcbiAgY29uc3QgcGFydHMgPSBpbnB1dHMubWFwKChpbnApID0+IHtcbiAgICBjb25zdCBidWYgPSBCdWZmZXIuYWxsb2MoMzYpO1xuICAgIEJ1ZmZlci5mcm9tKGlucC50cmFuc2FjdGlvbklkLCAnaGV4JykuY29weShidWYsIDApO1xuICAgIGJ1Zi53cml0ZVVJbnQzMkxFKGlucC50cmFuc2FjdGlvbkluZGV4LCAzMik7XG4gICAgcmV0dXJuIGJ1ZjtcbiAgfSk7XG4gIHJldHVybiBibGFrZTJiMjU2KEJ1ZmZlci5jb25jYXQocGFydHMpKTtcbn1cblxuZnVuY3Rpb24gaGFzaFNlcXVlbmNlcyhpbnB1dHM6IEthc3BhVXR4b0lucHV0W10pOiBCdWZmZXIge1xuICBjb25zdCBidWYgPSBCdWZmZXIuYWxsb2MoaW5wdXRzLmxlbmd0aCAqIDgpO1xuICBpbnB1dHMuZm9yRWFjaCgoaW5wLCBpKSA9PiB7XG4gICAgYnVmLndyaXRlQmlnVUludDY0TEUoQmlnSW50KGlucC5zZXF1ZW5jZSB8fCAnMCcpLCBpICogOCk7XG4gIH0pO1xuICByZXR1cm4gYmxha2UyYjI1NihidWYpO1xufVxuXG5mdW5jdGlvbiBoYXNoU2lnT3BDb3VudHMoaW5wdXRzOiBLYXNwYVV0eG9JbnB1dFtdKTogQnVmZmVyIHtcbiAgY29uc3QgYnl0ZXMgPSBpbnB1dHMubWFwKChpbnApID0+IGlucC5zaWdPcENvdW50ID8/IDEpO1xuICByZXR1cm4gYmxha2UyYjI1NihCdWZmZXIuZnJvbShieXRlcykpO1xufVxuXG5mdW5jdGlvbiBzZXJpYWxpemVPdXRwdXQob3V0cHV0OiBLYXNwYVRyYW5zYWN0aW9uT3V0cHV0KTogQnVmZmVyIHtcbiAgY29uc3Qgc2NyaXB0Qnl0ZXMgPSBCdWZmZXIuZnJvbShvdXRwdXQuc2NyaXB0UHVibGljS2V5IHx8ICcnLCAnaGV4Jyk7XG4gIGNvbnN0IHNwa1ZlcnNpb24gPSAwOyAvLyBzdGFuZGFyZCBQMlBLXG4gIC8vIHZhbHVlICh1NjQgTEUsIDgpICsgc3BrX3ZlcnNpb24gKHUxNiBMRSwgMikgKyBzY3JpcHRfbGVuZ3RoICh1NjQgTEUsIDgpICsgc2NyaXB0XG4gIGNvbnN0IGJ1ZiA9IEJ1ZmZlci5hbGxvYyg4ICsgMiArIDggKyBzY3JpcHRCeXRlcy5sZW5ndGgpO1xuICBsZXQgb2Zmc2V0ID0gMDtcbiAgYnVmLndyaXRlQmlnVUludDY0TEUoQmlnSW50KG91dHB1dC5hbW91bnQpLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gODtcbiAgYnVmLndyaXRlVUludDE2TEUoc3BrVmVyc2lvbiwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDI7XG4gIGJ1Zi53cml0ZUJpZ1VJbnQ2NExFKEJpZ0ludChzY3JpcHRCeXRlcy5sZW5ndGgpLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gODtcbiAgc2NyaXB0Qnl0ZXMuY29weShidWYsIG9mZnNldCk7XG4gIHJldHVybiBidWY7XG59XG5cbmZ1bmN0aW9uIGhhc2hPdXRwdXRzKHR4OiBLYXNwYVRyYW5zYWN0aW9uRGF0YSwgaW5wdXRJbmRleDogbnVtYmVyLCBzaWdIYXNoVHlwZTogbnVtYmVyKTogQnVmZmVyIHtcbiAgY29uc3QgYmFzZVR5cGUgPSBzaWdIYXNoVHlwZSAmIDB4MWY7XG4gIGlmIChiYXNlVHlwZSA9PT0gU0lHSEFTSF9OT05FKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygzMik7IC8vIHplcm8gaGFzaFxuICB9XG4gIGlmIChiYXNlVHlwZSA9PT0gU0lHSEFTSF9TSU5HTEUpIHtcbiAgICBpZiAoaW5wdXRJbmRleCA+PSB0eC5vdXRwdXRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygzMik7XG4gICAgfVxuICAgIHJldHVybiBibGFrZTJiMjU2KHNlcmlhbGl6ZU91dHB1dCh0eC5vdXRwdXRzW2lucHV0SW5kZXhdKSk7XG4gIH1cbiAgLy8gU0lHSEFTSF9BTExcbiAgY29uc3QgcGFydHMgPSB0eC5vdXRwdXRzLm1hcChzZXJpYWxpemVPdXRwdXQpO1xuICByZXR1cm4gYmxha2UyYjI1NihCdWZmZXIuY29uY2F0KHBhcnRzKSk7XG59XG5cbmZ1bmN0aW9uIGhhc2hQYXlsb2FkKHR4OiBLYXNwYVRyYW5zYWN0aW9uRGF0YSk6IEJ1ZmZlciB7XG4gIGNvbnN0IHN1Ym5ldElkID0gQnVmZmVyLmZyb20odHguc3VibmV0d29ya0lkIHx8ICcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJywgJ2hleCcpO1xuICAvLyBJZiBzdWJuZXR3b3JrIGlzIG5hdGl2ZSAoYWxsIHplcm9zKSwgcGF5bG9hZEhhc2ggaXMgemVyb1xuICBpZiAoc3VibmV0SWQuZXZlcnkoKGIpID0+IGIgPT09IDApKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygzMik7XG4gIH1cbiAgcmV0dXJuIGJsYWtlMmIyNTYoQnVmZmVyLmZyb20odHgucGF5bG9hZCB8fCAnJywgJ2hleCcpKTtcbn1cblxuLyoqXG4gKiBDb21wdXRlIHRoZSBLYXNwYSBzaWdoYXNoIGZvciBhIHNwZWNpZmljIGlucHV0LlxuICpcbiAqIEBwYXJhbSB0eCAgICAgICAgRnVsbCB0cmFuc2FjdGlvbiBkYXRhXG4gKiBAcGFyYW0gaW5wdXRJbmRleCBJbmRleCBvZiB0aGUgaW5wdXQgYmVpbmcgc2lnbmVkXG4gKiBAcGFyYW0gc2lnSGFzaFR5cGUgU2lnSGFzaCB0eXBlIGZsYWdzICh1c2UgU0lHSEFTSF9BTEwgPSAweDAxIGZvciBzdGFuZGFyZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVLYXNwYVNpZ25pbmdIYXNoKFxuICB0eDogS2FzcGFUcmFuc2FjdGlvbkRhdGEsXG4gIGlucHV0SW5kZXg6IG51bWJlcixcbiAgc2lnSGFzaFR5cGU6IG51bWJlciA9IFNJR0hBU0hfQUxMXG4pOiBCdWZmZXIge1xuICBjb25zdCBhbnlvbmVDYW5QYXkgPSAhIShzaWdIYXNoVHlwZSAmIFNJR0hBU0hfQU5ZT05FQ0FOUEFZKTtcbiAgY29uc3QgYmFzZVR5cGUgPSBzaWdIYXNoVHlwZSAmIDB4MWY7XG5cbiAgY29uc3QgaW5wdXQgPSB0eC5pbnB1dHNbaW5wdXRJbmRleF07XG4gIGlmICghaW5wdXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYElucHV0IGluZGV4ICR7aW5wdXRJbmRleH0gb3V0IG9mIHJhbmdlYCk7XG4gIH1cblxuICAvLyBDb25kaXRpb25hbCBpbnRlcm1lZGlhdGUgaGFzaGVzXG4gIGNvbnN0IHByZXZPdXRwdXRzSGFzaCA9IGFueW9uZUNhblBheSA/IEJ1ZmZlci5hbGxvYygzMikgOiBoYXNoUHJldmlvdXNPdXRwdXRzKHR4LmlucHV0cyk7XG4gIGNvbnN0IHNlcUhhc2ggPVxuICAgIGFueW9uZUNhblBheSB8fCBiYXNlVHlwZSA9PT0gU0lHSEFTSF9TSU5HTEUgfHwgYmFzZVR5cGUgPT09IFNJR0hBU0hfTk9ORVxuICAgICAgPyBCdWZmZXIuYWxsb2MoMzIpXG4gICAgICA6IGhhc2hTZXF1ZW5jZXModHguaW5wdXRzKTtcbiAgY29uc3Qgc2lnT3BIYXNoID0gYW55b25lQ2FuUGF5ID8gQnVmZmVyLmFsbG9jKDMyKSA6IGhhc2hTaWdPcENvdW50cyh0eC5pbnB1dHMpO1xuICBjb25zdCBvdXRzSGFzaCA9IGhhc2hPdXRwdXRzKHR4LCBpbnB1dEluZGV4LCBzaWdIYXNoVHlwZSk7XG4gIGNvbnN0IHBheWxvYWRIYXNoID0gaGFzaFBheWxvYWQodHgpO1xuXG4gIC8vIFBhcnNlIHRoZSBjdXJyZW50IGlucHV0J3Mgc2NyaXB0IHB1YmxpYyBrZXlcbiAgY29uc3Qgc2NyaXB0Qnl0ZXMgPSBCdWZmZXIuZnJvbShpbnB1dC5zY3JpcHRQdWJsaWNLZXkgfHwgJycsICdoZXgnKTtcbiAgY29uc3Qgc3BrVmVyc2lvbiA9IDA7IC8vIHN0YW5kYXJkIFAyUEtcbiAgY29uc3Qgc3VibmV0SWQgPSBCdWZmZXIuZnJvbSh0eC5zdWJuZXR3b3JrSWQgfHwgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAnLCAnaGV4Jyk7XG5cbiAgLy8gQnVpbGQgdGhlIHByZWltYWdlXG4gIGNvbnN0IGZpeGVkU2l6ZSA9IDIgKyAzMiArIDMyICsgMzIgKyAzMiArIDQgKyAyICsgOCArIDggKyA4ICsgMSArIDMyICsgOCArIDIwICsgOCArIDMyICsgMTtcbiAgY29uc3QgcHJlaW1hZ2UgPSBCdWZmZXIuYWxsb2MoZml4ZWRTaXplICsgc2NyaXB0Qnl0ZXMubGVuZ3RoKTtcbiAgbGV0IG9mZnNldCA9IDA7XG5cbiAgLy8gMS4gdmVyc2lvblxuICBwcmVpbWFnZS53cml0ZVVJbnQxNkxFKHR4LnZlcnNpb24gPz8gMCwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDI7XG5cbiAgLy8gMi4gcHJldmlvdXNPdXRwdXRzSGFzaFxuICBwcmV2T3V0cHV0c0hhc2guY29weShwcmVpbWFnZSwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDMyO1xuXG4gIC8vIDMuIHNlcXVlbmNlc0hhc2hcbiAgc2VxSGFzaC5jb3B5KHByZWltYWdlLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gMzI7XG5cbiAgLy8gNC4gc2lnT3BDb3VudHNIYXNoXG4gIHNpZ09wSGFzaC5jb3B5KHByZWltYWdlLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gMzI7XG5cbiAgLy8gNS4gY3VycmVudCBpbnB1dCdzIHByZXZpb3VzIG91dHBvaW50IHR4SWRcbiAgQnVmZmVyLmZyb20oaW5wdXQudHJhbnNhY3Rpb25JZCwgJ2hleCcpLmNvcHkocHJlaW1hZ2UsIG9mZnNldCk7XG4gIG9mZnNldCArPSAzMjtcblxuICAvLyA2LiBjdXJyZW50IGlucHV0J3MgcHJldmlvdXMgb3V0cG9pbnQgaW5kZXhcbiAgcHJlaW1hZ2Uud3JpdGVVSW50MzJMRShpbnB1dC50cmFuc2FjdGlvbkluZGV4LCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gNDtcblxuICAvLyA3LiBzY3JpcHRQdWJsaWNLZXkgdmVyc2lvblxuICBwcmVpbWFnZS53cml0ZVVJbnQxNkxFKHNwa1ZlcnNpb24sIG9mZnNldCk7XG4gIG9mZnNldCArPSAyO1xuXG4gIC8vIDguIHNjcmlwdFB1YmxpY0tleSBsZW5ndGggKHU2NCBMRSlcbiAgcHJlaW1hZ2Uud3JpdGVCaWdVSW50NjRMRShCaWdJbnQoc2NyaXB0Qnl0ZXMubGVuZ3RoKSwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDg7XG5cbiAgLy8gOS4gc2NyaXB0UHVibGljS2V5IGJ5dGVzXG4gIHNjcmlwdEJ5dGVzLmNvcHkocHJlaW1hZ2UsIG9mZnNldCk7XG4gIG9mZnNldCArPSBzY3JpcHRCeXRlcy5sZW5ndGg7XG5cbiAgLy8gMTAuIHZhbHVlIChhbW91bnQgaW4gc29tcGksIHU2NCBMRSlcbiAgcHJlaW1hZ2Uud3JpdGVCaWdVSW50NjRMRShCaWdJbnQoaW5wdXQuYW1vdW50KSwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDg7XG5cbiAgLy8gMTEuIHNlcXVlbmNlICh1NjQgTEUpXG4gIHByZWltYWdlLndyaXRlQmlnVUludDY0TEUoQmlnSW50KGlucHV0LnNlcXVlbmNlIHx8ICcwJyksIG9mZnNldCk7XG4gIG9mZnNldCArPSA4O1xuXG4gIC8vIDEyLiBzaWdPcENvdW50ICh1OClcbiAgcHJlaW1hZ2Uud3JpdGVVSW50OChpbnB1dC5zaWdPcENvdW50ID8/IDEsIG9mZnNldCk7XG4gIG9mZnNldCArPSAxO1xuXG4gIC8vIDEzLiBvdXRwdXRzSGFzaFxuICBvdXRzSGFzaC5jb3B5KHByZWltYWdlLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gMzI7XG5cbiAgLy8gMTQuIGxvY2t0aW1lICh1NjQgTEUpXG4gIHByZWltYWdlLndyaXRlQmlnVUludDY0TEUoQmlnSW50KHR4LmxvY2tUaW1lIHx8ICcwJyksIG9mZnNldCk7XG4gIG9mZnNldCArPSA4O1xuXG4gIC8vIDE1LiBzdWJuZXR3b3JrSWQgKDIwIGJ5dGVzKVxuICBzdWJuZXRJZC5jb3B5KHByZWltYWdlLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gMjA7XG5cbiAgLy8gMTYuIGdhcyAodTY0IExFKSDigJQgYWx3YXlzIDAgZm9yIG5hdGl2ZSBLQVNQQVxuICBwcmVpbWFnZS53cml0ZUJpZ1VJbnQ2NExFKDBuLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gODtcblxuICAvLyAxNy4gcGF5bG9hZEhhc2hcbiAgcGF5bG9hZEhhc2guY29weShwcmVpbWFnZSwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDMyO1xuXG4gIC8vIDE4LiBzaWdIYXNoVHlwZSAodTgpXG4gIHByZWltYWdlLndyaXRlVUludDgoc2lnSGFzaFR5cGUsIG9mZnNldCk7XG4gIG9mZnNldCArPSAxO1xuXG4gIHJldHVybiBibGFrZTJiMjU2KHByZWltYWdlLnNsaWNlKDAsIG9mZnNldCkpO1xufVxuIl19
250
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnaGFzaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvc2lnaGFzaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWtEQSw0REFZQztBQUtELDhDQUtDO0FBdUZELDBEQXlGQztBQXdCRCxvRUFPQztBQXZSRDs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxxQ0FBa0M7QUFDbEMsbUNBQW9DO0FBRXBDLDJDQVFxQjtBQUVyQjs7Ozs7O0dBTUc7QUFDSCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFFeEUsU0FBUyxRQUFRLENBQUMsSUFBWTtJQUM1QixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBQSxpQkFBTyxFQUFDLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzFELENBQUM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsU0FBZ0Isd0JBQXdCLENBQUMsTUFBYyxFQUFFLE9BQXdCLDJCQUFlLENBQUMsT0FBTztJQUN0RyxJQUFJLElBQUksS0FBSywyQkFBZSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3JDLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxFQUFFLEVBQUUsQ0FBQztZQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLHFEQUFxRCxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN4RixDQUFDO1FBQ0QsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQywrQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFGLENBQUM7U0FBTSxDQUFDO1FBQ04sSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQ3pCLE1BQU0s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SUFDbkMsTUFBTSxJQUFJLEVBQUUsQ0FBQztJQUNiLHVCQUF1QjtJQUN2QixRQUFRLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN6QyxNQUFNLElBQUksQ0FBQyxDQUFDO0lBRVosT0FBTyxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUM3QyxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLGdCQUFnQixHQUFXLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBQSxtQkFBVSxFQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7QUFFbEg7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILFNBQWdCLDRCQUE0QixDQUMxQyxFQUF3QixFQUN4QixVQUFrQixFQUNsQixjQUFzQix1QkFBVztJQUVqQyxNQUFNLFdBQVcsR0FBRyx1QkFBdUIsQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3pFLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFBLG1CQUFVLEVBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7QUFDakcsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogS2FzcGEgdHJhbnNhY3Rpb24gc2lnaGFzaCBjb21wdXRhdGlvbi5cbiAqXG4gKiBCSVAtMTQzLWxpa2Ugc2NoZW1lIHVzaW5nIGtleWVkIEJsYWtlMmItMjU2LiBBbGwgaW50ZWdlciBmaWVsZHMgYXJlXG4gKiBsaXR0bGUtZW5kaWFuLlxuICpcbiAqIEFMTCBoYXNoZXMgKGludGVybWVkaWF0ZSBhbmQgZmluYWwpIHVzZSB0aGUgc2FtZSBrZXllZCBCbGFrZTJiLTI1NiBoYXNoZXI6XG4gKiAgIGJsYWtlMmJfMjU2KGRhdGEsIGtleT1cIlRyYW5zYWN0aW9uU2lnbmluZ0hhc2hcIilcbiAqXG4gKiBSZWZlcmVuY2UgKGF1dGhvcml0YXRpdmUgaW1wbGVtZW50YXRpb24pOlxuICogaHR0cHM6Ly9naXRodWIuY29tL2thc3BhbmV0L3J1c3R5LWthc3BhL2Jsb2IvbWFzdGVyL2NyeXB0by9oYXNoZXMvc3JjL2hhc2hlcnMucnNcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9rYXNwYW5ldC9ydXN0eS1rYXNwYS9ibG9iL21hc3Rlci9jb25zZW5zdXMvY29yZS9zcmMvaGFzaGluZy9zaWdoYXNoLnJzXG4gKi9cbmltcG9ydCB7IGJsYWtlMmIgfSBmcm9tICdibGFrZWpzJztcbmltcG9ydCB7IGNyZWF0ZUhhc2ggfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgS2FzcGFUcmFuc2FjdGlvbkRhdGEsIEthc3BhVXR4b0lucHV0LCBLYXNwYVRyYW5zYWN0aW9uT3V0cHV0IH0gZnJvbSAnLi9pZmFjZSc7XG5pbXBvcnQge1xuICBTSUdIQVNIX0FMTCxcbiAgU0lHSEFTSF9OT05FLFxuICBTSUdIQVNIX1NJTkdMRSxcbiAgU0lHSEFTSF9BTllPTkVDQU5QQVksXG4gIE9QX0NIRUNLU0lHX1NDSE5PUlIsXG4gIE9QX0NIRUNLU0lHX0VDRFNBLFxuICBLYXNwYVNjcmlwdFR5cGUsXG59IGZyb20gJy4vY29uc3RhbnRzJztcblxuLyoqXG4gKiBUaGUgQmxha2UyYiBrZXkgdXNlZCBmb3IgQUxMIHNpZ2hhc2ggb3BlcmF0aW9ucyBpbiBLYXNwYS5cbiAqIERlZmluZWQgaW4gcnVzdHkta2FzcGEgY3J5cHRvL2hhc2hlcy9zcmMvaGFzaGVycy5yczpcbiAqICAgYmxha2UyYl9oYXNoZXIhIHsgc3RydWN0IFRyYW5zYWN0aW9uU2lnbmluZ0hhc2ggPT4gYlwiVHJhbnNhY3Rpb25TaWduaW5nSGFzaFwiLCAuLi4gfVxuICogd2hpY2ggcmVzb2x2ZXMgdG86XG4gKiAgIGJsYWtlMmJfc2ltZDo6UGFyYW1zOjpuZXcoKS5oYXNoX2xlbmd0aCgzMikua2V5KGJcIlRyYW5zYWN0aW9uU2lnbmluZ0hhc2hcIikudG9fc3RhdGUoKVxuICovXG5jb25zdCBTSUdOSU5HX0hBU0hfS0VZID0gQnVmZmVyLmZyb20oJ1RyYW5zYWN0aW9uU2lnbmluZ0hhc2gnLCAnYXNjaWknKTtcblxuZnVuY3Rpb24ga2JsYWtlMmIoZGF0YTogQnVmZmVyKTogQnVmZmVyIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKGJsYWtlMmIoZGF0YSwgU0lHTklOR19IQVNIX0tFWSwgMzIpKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIEthc3BhIFAyUEsgc2NyaXB0UHVibGljS2V5LlxuICpcbiAqIEBwYXJhbSBwdWJLZXkgLSBGb3IgU0NITk9SUjogMzItYnl0ZSB4LW9ubHkga2V5LlxuICogICAgICAgICAgICAgICAgIEZvciBFQ0RTQTogICAzMy1ieXRlIGNvbXByZXNzZWQga2V5LlxuICogQHBhcmFtIHR5cGUgICAtIEFkZHJlc3MgdHlwZSAoZGVmYXVsdDogU0NITk9SUiAvIHYwKS5cbiAqXG4gKiBSZXN1bHRpbmcgc2NyaXB0IGZvcm1hdHMgKHBlciBydXN0eS1rYXNwYSBjcnlwdG8vdHhzY3JpcHQvc3JjL3N0YW5kYXJkLnJzKTpcbiAqICAgU0NITk9SUiAodjApOiBPUF9EQVRBXzMyKDB4MjApIHx8IHhPbmx5UHViS2V5KDMyQikgICAgICB8fCBPcENoZWNrU2lnKDB4QUMpXG4gKiAgIEVDRFNBICAgKHYxKTogT1BfREFUQV8zMygweDIxKSB8fCBjb21wcmVzc2VkUHViS2V5KDMzQikgfHwgT3BDaGVja1NpZ0VDRFNBKDB4QUIpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFAyUEtTY3JpcHRQdWJsaWNLZXkocHViS2V5OiBCdWZmZXIsIHR5cGU6IEthc3BhU2NyaXB0VHlwZSA9IEthc3BhU2NyaXB0VHlwZS5TQ0hOT1JSKTogQnVmZmVyIHtcbiAgaWYgKHR5cGUgPT09IEthc3BhU2NyaXB0VHlwZS5TQ0hOT1JSKSB7XG4gICAgaWYgKHB1YktleS5sZW5ndGggIT09IDMyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFNDSE5PUlIgc2NyaXB0IGV4cGVjdHMgMzItYnl0ZSB4LW9ubHkgcHVia2V5LCBnb3QgJHtwdWJLZXkubGVuZ3RofWApO1xuICAgIH1cbiAgICByZXR1cm4gQnVmZmVyLmNvbmNhdChbQnVmZmVyLmZyb20oWzB4MjBdKSwgcHViS2V5LCBCdWZmZXIuZnJvbShbT1BfQ0hFQ0tTSUdfU0NITk9SUl0pXSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHB1YktleS5sZW5ndGggIT09IDMzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEVDRFNBIHNjcmlwdCBleHBlY3RzIDMzLWJ5dGUgY29tcHJlc3NlZCBwdWJrZXksIGdvdCAke3B1YktleS5sZW5ndGh9YCk7XG4gICAgfVxuICAgIHJldHVybiBCdWZmZXIuY29uY2F0KFtCdWZmZXIuZnJvbShbMHgyMV0pLCBwdWJLZXksIEJ1ZmZlci5mcm9tKFtPUF9DSEVDS1NJR19FQ0RTQV0pXSk7XG4gIH1cbn1cblxuLyoqXG4gKiBEZXJpdmUgeC1vbmx5IHB1YmxpYyBrZXkgZnJvbSAzMy1ieXRlIGNvbXByZXNzZWQgcHVibGljIGtleS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXByZXNzZWRUb1hPbmx5KGNvbXByZXNzZWRQdWJLZXk6IEJ1ZmZlcik6IEJ1ZmZlciB7XG4gIGlmIChjb21wcmVzc2VkUHViS2V5Lmxlbmd0aCAhPT0gMzMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIDMzLWJ5dGUgY29tcHJlc3NlZCBwdWJrZXksIGdvdCAke2NvbXByZXNzZWRQdWJLZXkubGVuZ3RofWApO1xuICB9XG4gIHJldHVybiBjb21wcmVzc2VkUHViS2V5LnNsaWNlKDEpOyAvLyBkcm9wIHRoZSAwMi8wMyBwcmVmaXggYnl0ZVxufVxuXG4vLyAtLS0gSW50ZXJtZWRpYXRlIGhhc2ggaGVscGVycyAtLS1cblxuZnVuY3Rpb24gaGFzaFByZXZpb3VzT3V0cHV0cyhpbnB1dHM6IEthc3BhVXR4b0lucHV0W10pOiBCdWZmZXIge1xuICBjb25zdCBwYXJ0cyA9IGlucHV0cy5tYXAoKGlucCkgPT4ge1xuICAgIGNvbnN0IGJ1ZiA9IEJ1ZmZlci5hbGxvYygzNik7XG4gICAgQnVmZmVyLmZyb20oaW5wLnRyYW5zYWN0aW9uSWQsICdoZXgnKS5jb3B5KGJ1ZiwgMCk7XG4gICAgYnVmLndyaXRlVUludDMyTEUoaW5wLnRyYW5zYWN0aW9uSW5kZXgsIDMyKTtcbiAgICByZXR1cm4gYnVmO1xuICB9KTtcbiAgcmV0dXJuIGtibGFrZTJiKEJ1ZmZlci5jb25jYXQocGFydHMpKTtcbn1cblxuZnVuY3Rpb24gaGFzaFNlcXVlbmNlcyhpbnB1dHM6IEthc3BhVXR4b0lucHV0W10pOiBCdWZmZXIge1xuICBjb25zdCBidWYgPSBCdWZmZXIuYWxsb2MoaW5wdXRzLmxlbmd0aCAqIDgpO1xuICBpbnB1dHMuZm9yRWFjaCgoaW5wLCBpKSA9PiB7XG4gICAgYnVmLndyaXRlQmlnVUludDY0TEUoQmlnSW50KGlucC5zZXF1ZW5jZSB8fCAnMCcpLCBpICogOCk7XG4gIH0pO1xuICByZXR1cm4ga2JsYWtlMmIoYnVmKTtcbn1cblxuZnVuY3Rpb24gaGFzaFNpZ09wQ291bnRzKGlucHV0czogS2FzcGFVdHhvSW5wdXRbXSk6IEJ1ZmZlciB7XG4gIGNvbnN0IGJ5dGVzID0gaW5wdXRzLm1hcCgoaW5wKSA9PiBpbnAuc2lnT3BDb3VudCA/PyAxKTtcbiAgcmV0dXJuIGtibGFrZTJiKEJ1ZmZlci5mcm9tKGJ5dGVzKSk7XG59XG5cbi8qKlxuICogU2VyaWFsaXplIG9uZSBvdXRwdXQgZm9yIGhhc2hpbmcuXG4gKiBNYXRjaGVzIGhhc2hfb3V0cHV0KCkgKyBoYXNoX3NjcmlwdF9wdWJsaWNfa2V5KCkgaW4gcnVzdHkta2FzcGE6XG4gKiAgIHdyaXRlX3U2NCh2YWx1ZSkgKyB3cml0ZV91MTYoc3BrLnZlcnNpb24pICsgd3JpdGVfdmFyX2J5dGVzKHNway5zY3JpcHQpXG4gKiB3aGVyZSB3cml0ZV92YXJfYnl0ZXMgPSB3cml0ZV91NjQobGVuKSArIHdyaXRlKGJ5dGVzKS5cbiAqL1xuZnVuY3Rpb24gc2VyaWFsaXplT3V0cHV0KG91dHB1dDogS2FzcGFUcmFuc2FjdGlvbk91dHB1dCk6IEJ1ZmZlciB7XG4gIGNvbnN0IHNjcmlwdEJ5dGVzID0gQnVmZmVyLmZyb20ob3V0cHV0LnNjcmlwdFB1YmxpY0tleSB8fCAnJywgJ2hleCcpO1xuICBjb25zdCBzcGtWZXJzaW9uID0gMDtcbiAgY29uc3QgYnVmID0gQnVmZmVyLmFsbG9jKDggKyAyICsgOCArIHNjcmlwdEJ5dGVzLmxlbmd0aCk7XG4gIGxldCBvZmZzZXQgPSAwO1xuICBidWYud3JpdGVCaWdVSW50NjRMRShCaWdJbnQob3V0cHV0LmFtb3VudCksIG9mZnNldCk7XG4gIG9mZnNldCArPSA4O1xuICBidWYud3JpdGVVSW50MTZMRShzcGtWZXJzaW9uLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gMjtcbiAgYnVmLndyaXRlQmlnVUludDY0TEUoQmlnSW50KHNjcmlwdEJ5dGVzLmxlbmd0aCksIG9mZnNldCk7XG4gIG9mZnNldCArPSA4O1xuICBzY3JpcHRCeXRlcy5jb3B5KGJ1Ziwgb2Zmc2V0KTtcbiAgcmV0dXJuIGJ1Zjtcbn1cblxuZnVuY3Rpb24gaGFzaE91dHB1dHModHg6IEthc3BhVHJhbnNhY3Rpb25EYXRhLCBpbnB1dEluZGV4OiBudW1iZXIsIHNpZ0hhc2hUeXBlOiBudW1iZXIpOiBCdWZmZXIge1xuICBjb25zdCBiYXNlVHlwZSA9IHNpZ0hhc2hUeXBlICYgMHgxZjtcbiAgaWYgKGJhc2VUeXBlID09PSBTSUdIQVNIX05PTkUpIHtcbiAgICByZXR1cm4gQnVmZmVyLmFsbG9jKDMyKTtcbiAgfVxuICBpZiAoYmFzZVR5cGUgPT09IFNJR0hBU0hfU0lOR0xFKSB7XG4gICAgaWYgKGlucHV0SW5kZXggPj0gdHgub3V0cHV0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBCdWZmZXIuYWxsb2MoMzIpO1xuICAgIH1cbiAgICByZXR1cm4ga2JsYWtlMmIoc2VyaWFsaXplT3V0cHV0KHR4Lm91dHB1dHNbaW5wdXRJbmRleF0pKTtcbiAgfVxuICAvLyBTSUdIQVNIX0FMTFxuICByZXR1cm4ga2JsYWtlMmIoQnVmZmVyLmNvbmNhdCh0eC5vdXRwdXRzLm1hcChzZXJpYWxpemVPdXRwdXQpKSk7XG59XG5cbmZ1bmN0aW9uIGhhc2hQYXlsb2FkKHR4OiBLYXNwYVRyYW5zYWN0aW9uRGF0YSk6IEJ1ZmZlciB7XG4gIGNvbnN0IHN1Ym5ldElkID0gQnVmZmVyLmZyb20odHguc3VibmV0d29ya0lkIHx8ICcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwJywgJ2hleCcpO1xuICAvLyBOYXRpdmUgc3VibmV0d29yayAoYWxsIHplcm9zKSB3aXRoIGVtcHR5IHBheWxvYWQg4oaSIHplcm8gaGFzaFxuICBpZiAoc3VibmV0SWQuZXZlcnkoKGIpID0+IGIgPT09IDApKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5hbGxvYygzMik7XG4gIH1cbiAgLy8gd3JpdGVfdmFyX2J5dGVzKHBheWxvYWQpOiB1NjQgbGVuZ3RoIHByZWZpeCArIHBheWxvYWQgYnl0ZXNcbiAgY29uc3QgcGF5bG9hZEJ5dGVzID0gQnVmZmVyLmZyb20odHgucGF5bG9hZCB8fCAnJywgJ2hleCcpO1xuICBjb25zdCBsZW5CdWYgPSBCdWZmZXIuYWxsb2MoOCk7XG4gIGxlbkJ1Zi53cml0ZUJpZ1VJbnQ2NExFKEJpZ0ludChwYXlsb2FkQnl0ZXMubGVuZ3RoKSk7XG4gIHJldHVybiBrYmxha2UyYihCdWZmZXIuY29uY2F0KFtsZW5CdWYsIHBheWxvYWRCeXRlc10pKTtcbn1cblxuLyoqXG4gKiBDb21wdXRlIHRoZSBLYXNwYSBTY2hub3JyIHNpZ2hhc2ggZm9yIGEgc3BlY2lmaWMgaW5wdXQuXG4gKlxuICogTWF0Y2hlcyBjYWxjX3NjaG5vcnJfc2lnbmF0dXJlX2hhc2goKSBpbiBydXN0eS1rYXNwYSBzaWdoYXNoLnJzIGV4YWN0bHkuXG4gKiBBbGwgaW50ZXJtZWRpYXRlIGFuZCB0aGUgZmluYWwgaGFzaCB1c2Uga2V5ZWQgQmxha2UyYi0yNTYgd2l0aFxuICoga2V5ID0gXCJUcmFuc2FjdGlvblNpZ25pbmdIYXNoXCIuXG4gKlxuICogQHBhcmFtIHR4ICAgICAgICAgRnVsbCB0cmFuc2FjdGlvbiBkYXRhIOKAlCBpbnB1dHMgbXVzdCBjYXJyeSBhbW91bnQgKyBzY3JpcHRQdWJsaWNLZXlcbiAqIEBwYXJhbSBpbnB1dEluZGV4IDAtYmFzZWQgaW5kZXggb2YgdGhlIGlucHV0IGJlaW5nIHNpZ25lZFxuICogQHBhcmFtIHNpZ0hhc2hUeXBlIFNpZ0hhc2ggdHlwZSBmbGFncyAoU0lHSEFTSF9BTEwgPSAweDAxIGZvciBzdGFuZGFyZClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVLYXNwYVNpZ25pbmdIYXNoKFxuICB0eDogS2FzcGFUcmFuc2FjdGlvbkRhdGEsXG4gIGlucHV0SW5kZXg6IG51bWJlcixcbiAgc2lnSGFzaFR5cGU6IG51bWJlciA9IFNJR0hBU0hfQUxMXG4pOiBCdWZmZXIge1xuICBjb25zdCBhbnlvbmVDYW5QYXkgPSAhIShzaWdIYXNoVHlwZSAmIFNJR0hBU0hfQU5ZT05FQ0FOUEFZKTtcbiAgY29uc3QgYmFzZVR5cGUgPSBzaWdIYXNoVHlwZSAmIDB4MWY7XG5cbiAgY29uc3QgaW5wdXQgPSB0eC5pbnB1dHNbaW5wdXRJbmRleF07XG4gIGlmICghaW5wdXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYElucHV0IGluZGV4ICR7aW5wdXRJbmRleH0gb3V0IG9mIHJhbmdlYCk7XG4gIH1cblxuICAvLyBJbnRlcm1lZGlhdGUgaGFzaGVzXG4gIGNvbnN0IHByZXZPdXRwdXRzSGFzaCA9IGFueW9uZUNhblBheSA/IEJ1ZmZlci5hbGxvYygzMikgOiBoYXNoUHJldmlvdXNPdXRwdXRzKHR4LmlucHV0cyk7XG4gIGNvbnN0IHNlcUhhc2ggPVxuICAgIGFueW9uZUNhblBheSB8fCBiYXNlVHlwZSA9PT0gU0lHSEFTSF9TSU5HTEUgfHwgYmFzZVR5cGUgPT09IFNJR0hBU0hfTk9ORVxuICAgICAgPyBCdWZmZXIuYWxsb2MoMzIpXG4gICAgICA6IGhhc2hTZXF1ZW5jZXModHguaW5wdXRzKTtcbiAgY29uc3Qgc2lnT3BIYXNoID0gYW55b25lQ2FuUGF5ID8gQnVmZmVyLmFsbG9jKDMyKSA6IGhhc2hTaWdPcENvdW50cyh0eC5pbnB1dHMpO1xuICBjb25zdCBvdXRzSGFzaCA9IGhhc2hPdXRwdXRzKHR4LCBpbnB1dEluZGV4LCBzaWdIYXNoVHlwZSk7XG4gIGNvbnN0IHBheWxvYWRIYXNoID0gaGFzaFBheWxvYWQodHgpO1xuXG4gIC8vIEN1cnJlbnQgaW5wdXQncyBzY3JpcHRQdWJsaWNLZXkgKGZyb20gdGhlIFVUWE8gYmVpbmcgc3BlbnQpXG4gIGNvbnN0IHNjcmlwdEJ5dGVzID0gQnVmZmVyLmZyb20oaW5wdXQuc2NyaXB0UHVibGljS2V5IHx8ICcnLCAnaGV4Jyk7XG4gIGNvbnN0IHNwa1ZlcnNpb24gPSAwO1xuICBjb25zdCBzdWJuZXRJZCA9IEJ1ZmZlci5mcm9tKHR4LnN1Ym5ldHdvcmtJZCB8fCAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCcsICdoZXgnKTtcblxuICAvLyBCdWlsZCB0aGUgcHJlaW1hZ2Ug4oCUIGZpZWxkIG9yZGVyIG1hdGNoZXMgY2FsY19zY2hub3JyX3NpZ25hdHVyZV9oYXNoKCkgZXhhY3RseVxuICBjb25zdCBmaXhlZFNpemUgPSAyICsgMzIgKyAzMiArIDMyICsgMzIgKyA0ICsgMiArIDggKyA4ICsgOCArIDEgKyAzMiArIDggKyAyMCArIDggKyAzMiArIDE7XG4gIGNvbnN0IHByZWltYWdlID0gQnVmZmVyLmFsbG9jKGZpeGVkU2l6ZSArIHNjcmlwdEJ5dGVzLmxlbmd0aCk7XG4gIGxldCBvZmZzZXQgPSAwO1xuXG4gIC8vIDEuIHR4LnZlcnNpb24gKHUxNiBMRSlcbiAgcHJlaW1hZ2Uud3JpdGVVSW50MTZMRSh0eC52ZXJzaW9uID8/IDAsIG9mZnNldCk7XG4gIG9mZnNldCArPSAyO1xuICAvLyAyLiBwcmV2aW91c091dHB1dHNIYXNoXG4gIHByZXZPdXRwdXRzSGFzaC5jb3B5KHByZWltYWdlLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gMzI7XG4gIC8vIDMuIHNlcXVlbmNlc0hhc2hcbiAgc2VxSGFzaC5jb3B5KHByZWltYWdlLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gMzI7XG4gIC8vIDQuIHNpZ09wQ291bnRzSGFzaFxuICBzaWdPcEhhc2guY29weShwcmVpbWFnZSwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDMyO1xuICAvLyA1LiBpbnB1dC5wcmV2aW91c091dHBvaW50LnRyYW5zYWN0aW9uSWQgKDMyIGJ5dGVzKVxuICBCdWZmZXIuZnJvbShpbnB1dC50cmFuc2FjdGlvbklkLCAnaGV4JykuY29weShwcmVpbWFnZSwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDMyO1xuICAvLyA2LiBpbnB1dC5wcmV2aW91c091dHBvaW50LmluZGV4ICh1MzIgTEUpXG4gIHByZWltYWdlLndyaXRlVUludDMyTEUoaW5wdXQudHJhbnNhY3Rpb25JbmRleCwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDQ7XG4gIC8vIDcuIHNjcmlwdFB1YmxpY0tleS52ZXJzaW9uICh1MTYgTEUpXG4gIHByZWltYWdlLndyaXRlVUludDE2TEUoc3BrVmVyc2lvbiwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDI7XG4gIC8vIDguIHNjcmlwdFB1YmxpY0tleS5zY3JpcHQgbGVuZ3RoICh1NjQgTEUpIOKAlCB3cml0ZV92YXJfYnl0ZXMgbGVuZ3RoIHByZWZpeFxuICBwcmVpbWFnZS53cml0ZUJpZ1VJbnQ2NExFKEJpZ0ludChzY3JpcHRCeXRlcy5sZW5ndGgpLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gODtcbiAgLy8gOS4gc2NyaXB0UHVibGljS2V5LnNjcmlwdCBieXRlc1xuICBzY3JpcHRCeXRlcy5jb3B5KHByZWltYWdlLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gc2NyaXB0Qnl0ZXMubGVuZ3RoO1xuICAvLyAxMC4gaW5wdXQgVVRYTyBhbW91bnQgKHU2NCBMRSlcbiAgcHJlaW1hZ2Uud3JpdGVCaWdVSW50NjRMRShCaWdJbnQoaW5wdXQuYW1vdW50KSwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDg7XG4gIC8vIDExLiBpbnB1dC5zZXF1ZW5jZSAodTY0IExFKVxuICBwcmVpbWFnZS53cml0ZUJpZ1VJbnQ2NExFKEJpZ0ludChpbnB1dC5zZXF1ZW5jZSB8fCAnMCcpLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gODtcbiAgLy8gMTIuIGlucHV0LnNpZ09wQ291bnQgKHU4KVxuICBwcmVpbWFnZS53cml0ZVVJbnQ4KGlucHV0LnNpZ09wQ291bnQgPz8gMSwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDE7XG4gIC8vIDEzLiBvdXRwdXRzSGFzaFxuICBvdXRzSGFzaC5jb3B5KHByZWltYWdlLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gMzI7XG4gIC8vIDE0LiB0eC5sb2NrVGltZSAodTY0IExFKVxuICBwcmVpbWFnZS53cml0ZUJpZ1VJbnQ2NExFKEJpZ0ludCh0eC5sb2NrVGltZSB8fCAnMCcpLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gODtcbiAgLy8gMTUuIHR4LnN1Ym5ldHdvcmtJZCAoMjAgYnl0ZXMpXG4gIHN1Ym5ldElkLmNvcHkocHJlaW1hZ2UsIG9mZnNldCk7XG4gIG9mZnNldCArPSAyMDtcbiAgLy8gMTYuIHR4LmdhcyAodTY0IExFKSDigJQgYWx3YXlzIDAgZm9yIG5hdGl2ZSBLQVNQQVxuICBwcmVpbWFnZS53cml0ZUJpZ1VJbnQ2NExFKDBuLCBvZmZzZXQpO1xuICBvZmZzZXQgKz0gODtcbiAgLy8gMTcuIHBheWxvYWRIYXNoXG4gIHBheWxvYWRIYXNoLmNvcHkocHJlaW1hZ2UsIG9mZnNldCk7XG4gIG9mZnNldCArPSAzMjtcbiAgLy8gMTguIHNpZ0hhc2hUeXBlICh1OClcbiAgcHJlaW1hZ2Uud3JpdGVVSW50OChzaWdIYXNoVHlwZSwgb2Zmc2V0KTtcbiAgb2Zmc2V0ICs9IDE7XG5cbiAgcmV0dXJuIGtibGFrZTJiKHByZWltYWdlLnNsaWNlKDAsIG9mZnNldCkpO1xufVxuXG4vKipcbiAqIFNIQS0yNTYgZG9tYWluIHNlcGFyYXRvciBmb3IgRUNEU0Egc2lnbmluZy5cbiAqIE1hdGNoZXMgVHJhbnNhY3Rpb25TaWduaW5nSGFzaEVDRFNBIGluIHJ1c3R5LWthc3BhL2NyeXB0by9oYXNoZXMvc3JjL2hhc2hlcnMucnM6XG4gKiAgIHNoYTI1Nl9oYXNoZXIhIHsgc3RydWN0IFRyYW5zYWN0aW9uU2lnbmluZ0hhc2hFQ0RTQSA9PiBcIlRyYW5zYWN0aW9uU2lnbmluZ0hhc2hFQ0RTQVwiIH1cbiAqIFRoZSBoYXNoZXIgaXMgc2VlZGVkIHdpdGggU0hBMjU2KFwiVHJhbnNhY3Rpb25TaWduaW5nSGFzaEVDRFNBXCIpIGJlZm9yZSBhbnkgZGF0YS5cbiAqL1xuY29uc3QgRUNEU0FfRE9NQUlOX1NFUDogQnVmZmVyID0gQnVmZmVyLmZyb20oY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKCdUcmFuc2FjdGlvblNpZ25pbmdIYXNoRUNEU0EnKS5kaWdlc3QoKSk7XG5cbi8qKlxuICogQ29tcHV0ZSB0aGUgS2FzcGEgRUNEU0Egc2lnaGFzaCBmb3IgYSBzcGVjaWZpYyBpbnB1dC5cbiAqXG4gKiBFQ0RTQSBzaWduaW5nIHVzZXMgYSB0d28tc3RlcCBoYXNoIGRlZmluZWQgaW4gcnVzdHkta2FzcGEgc2lnaGFzaC5yczpcbiAqICAgMS4gc2Nobm9ycl9oYXNoICA9IGJsYWtlMmIyNTZfa2V5ZWQoXCJUcmFuc2FjdGlvblNpZ25pbmdIYXNoXCIsIHByZWltYWdlKVxuICogICAyLiBlY2RzYV9oYXNoICAgID0gU0hBMjU2KCBTSEEyNTYoXCJUcmFuc2FjdGlvblNpZ25pbmdIYXNoRUNEU0FcIikgfHwgc2Nobm9ycl9oYXNoIClcbiAqXG4gKiBUaGlzIGRpZmZlcnMgZnJvbSB0aGUgU2Nobm9yciBoYXNoIOKAlCB1c2luZyB0aGUgU2Nobm9yciBoYXNoIGZvciBFQ0RTQSBzaWduaW5nXG4gKiB3aWxsIHByb2R1Y2UgYSBsb2NhbGx5LXZhbGlkIHNpZ25hdHVyZSB0aGF0IHRoZSBuZXR3b3JrIGFsd2F5cyByZWplY3RzLlxuICpcbiAqIEBwYXJhbSB0eCAgICAgICAgIEZ1bGwgdHJhbnNhY3Rpb24gZGF0YSB3aXRoIFVUWE8gYW1vdW50ICsgc2NyaXB0UHVibGljS2V5IG9uIGlucHV0c1xuICogQHBhcmFtIGlucHV0SW5kZXggMC1iYXNlZCBpbmRleCBvZiB0aGUgaW5wdXQgYmVpbmcgc2lnbmVkXG4gKiBAcGFyYW0gc2lnSGFzaFR5cGUgU2lnSGFzaCB0eXBlIGZsYWdzIChTSUdIQVNIX0FMTCA9IDB4MDEpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlS2FzcGFFY2RzYVNpZ25pbmdIYXNoKFxuICB0eDogS2FzcGFUcmFuc2FjdGlvbkRhdGEsXG4gIGlucHV0SW5kZXg6IG51bWJlcixcbiAgc2lnSGFzaFR5cGU6IG51bWJlciA9IFNJR0hBU0hfQUxMXG4pOiBCdWZmZXIge1xuICBjb25zdCBzY2hub3JySGFzaCA9IGNvbXB1dGVLYXNwYVNpZ25pbmdIYXNoKHR4LCBpbnB1dEluZGV4LCBzaWdIYXNoVHlwZSk7XG4gIHJldHVybiBCdWZmZXIuZnJvbShjcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUoRUNEU0FfRE9NQUlOX1NFUCkudXBkYXRlKHNjaG5vcnJIYXNoKS5kaWdlc3QoKSk7XG59XG4iXX0=
@@ -1,5 +1,6 @@
1
1
  import { BaseKey, BaseTransaction } from '@bitgo-beta/sdk-core';
2
2
  import { KaspaTransactionData, TransactionExplanation } from './iface';
3
+ import { Pskt } from './pskt';
3
4
  export declare class Transaction extends BaseTransaction {
4
5
  protected _txData: KaspaTransactionData;
5
6
  constructor(coin: string, txData?: KaspaTransactionData);
@@ -7,16 +8,60 @@ export declare class Transaction extends BaseTransaction {
7
8
  get id(): string;
8
9
  get txData(): KaspaTransactionData;
9
10
  /**
10
- * Sign all inputs with the given private key using Schnorr signatures.
11
+ * Get the transaction fee in sompi.
12
+ * If fee was explicitly set, returns that. Otherwise computes from inputs - outputs.
13
+ */
14
+ get fee(): string;
15
+ /**
16
+ * Returns one sighash Buffer per input — the set of messages that must be
17
+ * signed for a multi-input MPCv2 ceremony.
18
+ *
19
+ * Kaspa uses a BIP-143-like sighash scheme (Blake2b) where each input commits
20
+ * to its own index, so input[i] has a distinct hash that cannot be re-used for
21
+ * input[j]. A correct multi-input MPCv2 flow runs one DKLS session per input
22
+ * in parallel and applies each resulting signature via addSignatureForInput().
23
+ *
24
+ * The hash type is automatically selected per input:
25
+ * - Schnorr (scriptPublicKey ends 0xAC): keyed Blake2b-256
26
+ * - ECDSA (scriptPublicKey ends 0xAB): keyed Blake2b-256 + SHA256 double-hash
27
+ */
28
+ get signablePayloads(): Buffer[];
29
+ /**
30
+ * Apply a signature to a single specific input.
31
+ *
32
+ * Used in the multi-input MPCv2 flow where each input is signed by an
33
+ * independent DKLS session that commits to that input's sighash. Call this
34
+ * once per input with the signature produced for that input's signablePayloads[i].
11
35
  *
12
- * @param privateKey 32-byte private key buffer
36
+ * @param index 0-based index of the input to sign
37
+ * @param publicKey compressed secp256k1 public key (33 bytes hex) — not used in
38
+ * the scriptSig bytes but kept for symmetry with addSignature
39
+ * @param signature 64-byte signature buffer for input[index]
40
+ * @param sigHashType SigHash type (default: SIGHASH_ALL)
41
+ */
42
+ addSignatureForInput(index: number, publicKey: string, signature: Buffer, sigHashType?: number): void;
43
+ /**
44
+ * Sign all inputs with the given private key.
45
+ *
46
+ * Automatically selects the signature algorithm per input by inspecting each
47
+ * input's scriptPublicKey:
48
+ * - Schnorr (last opcode 0xAC, v0 address): BIP-340 Schnorr + Blake2b sighash
49
+ * - ECDSA (last opcode 0xAB, v1 address): secp256k1 ECDSA + Blake2b+SHA256 sighash
50
+ *
51
+ * A single transaction may mix both address types and each input will be
52
+ * signed correctly without any extra parameters.
53
+ *
54
+ * @param privateKey 32-byte private key buffer
13
55
  * @param sigHashType SigHash type (default: SIGHASH_ALL = 0x01)
14
56
  */
15
57
  sign(privateKey: Buffer, sigHashType?: number): void;
16
58
  /**
17
- * Verify that a Schnorr signature on a specific input is valid.
59
+ * Verify that the signature on a specific input is valid.
60
+ *
61
+ * Automatically selects the verification algorithm based on the input's
62
+ * scriptPublicKey (ECDSA for 0xAB, Schnorr for 0xAC), matching `sign()`.
18
63
  *
19
- * @param publicKey 33-byte compressed public key (or 32-byte x-only)
64
+ * @param publicKey 33-byte compressed public key (or 32-byte x-only for Schnorr)
20
65
  * @param inputIndex Index of the input to verify
21
66
  * @param sigHashType SigHash type used when signing
22
67
  */
@@ -26,11 +71,26 @@ export declare class Transaction extends BaseTransaction {
26
71
  */
27
72
  explainTransaction(): TransactionExplanation;
28
73
  /**
29
- * Serialize the transaction to a JSON string (broadcast format).
74
+ * Serialize the transaction to the Kaspa REST API JSON string.
75
+ *
76
+ * This is the wire format accepted by the Kaspa node REST API for broadcasting.
77
+ * Unsigned transactions (signatureScript = "") use this same structure; once
78
+ * all inputs are signed the same format is submitted to the node.
79
+ *
80
+ * Note: inputs in this format carry only `previousOutpoint`, `signatureScript`,
81
+ * `sequence`, and `sigOpCount`. The `amount` and `scriptPublicKey` fields needed
82
+ * for sighash computation are NOT present here — they live in `toJson()`.
30
83
  */
31
84
  toBroadcastFormat(): string;
32
85
  /**
33
- * Serialize transaction to hex (JSON-encoded then hex-encoded).
86
+ * Serialize transaction to hex using the internal `KaspaTransactionData` format.
87
+ *
88
+ * This hex is used for SDK-internal round-trips (builder serialisation / deserialisation)
89
+ * because the internal format preserves `amount` and `scriptPublicKey` on inputs,
90
+ * which are required for sighash computation but are not present in the REST API format.
91
+ *
92
+ * Use `Buffer.from(tx.toBroadcastFormat()).toString('hex')` when you need the hex
93
+ * representation of the broadcast / HSM wire format.
34
94
  */
35
95
  toHex(): string;
36
96
  /**
@@ -49,5 +109,33 @@ export declare class Transaction extends BaseTransaction {
49
109
  get signature(): string[];
50
110
  /** @inheritDoc */
51
111
  canSign(_key: BaseKey): boolean;
112
+ /**
113
+ * Convert this transaction to a PSKT in SIGNER role.
114
+ *
115
+ * The PSKT is populated with UTXO data from each input so that sighash
116
+ * computation is possible immediately. Any existing `signatureScript` on an
117
+ * input is carried into the PSKT as `finalScriptSig`.
118
+ *
119
+ * Typical use:
120
+ * ```ts
121
+ * const pskt = tx.toPskt()
122
+ * .sign(privateKey)
123
+ * .toFinalizer()
124
+ * .finalize()
125
+ * .toExtractor();
126
+ * const broadcastJson = pskt.extract();
127
+ * ```
128
+ */
129
+ toPskt(): Pskt;
130
+ /**
131
+ * Reconstruct a Transaction from a PSKT (any role).
132
+ *
133
+ * `finalScriptSig` from each PSKT input is mapped to `signatureScript` so
134
+ * that the resulting transaction is signed if the PSKT has been finalised.
135
+ *
136
+ * @param coin Coin name string (e.g. 'kaspa', 'tkaspa')
137
+ * @param pskt A Pskt instance (typically at FINALIZER or EXTRACTOR role)
138
+ */
139
+ static fromPskt(coin: string, pskt: Pskt): Transaction;
52
140
  }
53
141
  //# sourceMappingURL=transaction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../../src/lib/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,eAAe,EAAmB,MAAM,sBAAsB,CAAC;AAEjF,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAGvE,qBAAa,WAAY,SAAQ,eAAe;IAC9C,SAAS,CAAC,OAAO,EAAE,oBAAoB,CAAC;gBAE5B,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,oBAAoB;IASvD,kBAAkB;IAClB,IAAI,EAAE,IAAI,MAAM,CAEf;IAED,IAAI,MAAM,IAAI,oBAAoB,CAEjC;IAED;;;;;OAKG;IACH,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,GAAE,MAAoB,GAAG,IAAI;IAajE;;;;;;OAMG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAE,MAAoB,GAAG,OAAO;IAgBlG;;OAEG;IACH,kBAAkB,IAAI,sBAAsB;IA8B5C;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAI3B;;OAEG;IACH,KAAK,IAAI,MAAM;IAIf;;OAEG;IACH,MAAM,IAAI,oBAAoB;IAI9B;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW;IAKtD;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,WAAW;IAK/E,kBAAkB;IAClB,IAAI,SAAS,IAAI,MAAM,EAAE,CAExB;IAED,kBAAkB;IAClB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;CAGhC"}
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../../src/lib/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,eAAe,EAAmB,MAAM,sBAAsB,CAAC;AAEjF,OAAO,EAAE,oBAAoB,EAAkB,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAGvF,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAY9B,qBAAa,WAAY,SAAQ,eAAe;IAC9C,SAAS,CAAC,OAAO,EAAE,oBAAoB,CAAC;gBAE5B,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,oBAAoB;IAWvD,kBAAkB;IAClB,IAAI,EAAE,IAAI,MAAM,CAEf;IAED,IAAI,MAAM,IAAI,oBAAoB,CAEjC;IAED;;;OAGG;IACH,IAAI,GAAG,IAAI,MAAM,CAahB;IAED;;;;;;;;;;;;OAYG;IACH,IAAI,gBAAgB,IAAI,MAAM,EAAE,CAS/B;IAED;;;;;;;;;;;;OAYG;IACH,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAE,MAAoB,GAAG,IAAI;IAalH;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,GAAE,MAAoB,GAAG,IAAI;IAwBjE;;;;;;;;;OASG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAE,MAAoB,GAAG,OAAO;IAyBlG;;OAEG;IACH,kBAAkB,IAAI,sBAAsB;IA8B5C;;;;;;;;;;OAUG;IACH,iBAAiB,IAAI,MAAM;IA0B3B;;;;;;;;;OASG;IACH,KAAK,IAAI,MAAM;IAIf;;OAEG;IACH,MAAM,IAAI,oBAAoB;IAI9B;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW;IAKtD;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,WAAW;IAK/E,kBAAkB;IAClB,IAAI,SAAS,IAAI,MAAM,EAAE,CAExB;IAED,kBAAkB;IAClB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAI/B;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,IAAI,IAAI;IAId;;;;;;;;OAQG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW;CAGvD"}