@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.
- package/README.md +224 -33
- package/dist/src/kaspa.d.ts +86 -18
- package/dist/src/kaspa.d.ts.map +1 -1
- package/dist/src/kaspa.js +119 -31
- package/dist/src/lib/constants.d.ts +38 -0
- package/dist/src/lib/constants.d.ts.map +1 -1
- package/dist/src/lib/constants.js +56 -5
- package/dist/src/lib/iface.d.ts +28 -17
- package/dist/src/lib/iface.d.ts.map +1 -1
- package/dist/src/lib/iface.js +1 -1
- package/dist/src/lib/index.d.ts +2 -0
- package/dist/src/lib/index.d.ts.map +1 -1
- package/dist/src/lib/index.js +4 -2
- package/dist/src/lib/keyPair.d.ts +6 -2
- package/dist/src/lib/keyPair.d.ts.map +1 -1
- package/dist/src/lib/keyPair.js +7 -4
- package/dist/src/lib/pskt.d.ts +257 -0
- package/dist/src/lib/pskt.d.ts.map +1 -0
- package/dist/src/lib/pskt.js +439 -0
- package/dist/src/lib/sighash.d.ts +34 -13
- package/dist/src/lib/sighash.d.ts.map +1 -1
- package/dist/src/lib/sighash.js +115 -56
- package/dist/src/lib/transaction.d.ts +94 -6
- package/dist/src/lib/transaction.d.ts.map +1 -1
- package/dist/src/lib/transaction.js +199 -21
- package/dist/src/lib/transactionBuilder.d.ts +22 -0
- package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilder.js +53 -5
- package/dist/src/lib/transactionBuilderFactory.d.ts +8 -3
- package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
- package/dist/src/lib/transactionBuilderFactory.js +14 -4
- package/dist/src/lib/utils.d.ts +17 -3
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +45 -11
- package/dist/src/register.js +2 -2
- package/dist/test/fixtures/kaspa.fixtures.d.ts +12 -0
- package/dist/test/fixtures/kaspa.fixtures.d.ts.map +1 -1
- package/dist/test/fixtures/kaspa.fixtures.js +76 -11
- package/dist/test/unit/coin.test.js +129 -9
- package/dist/test/unit/keyPair.test.js +35 -1
- package/dist/test/unit/pskt.test.d.ts +15 -0
- package/dist/test/unit/pskt.test.d.ts.map +1 -0
- package/dist/test/unit/pskt.test.js +383 -0
- package/dist/test/unit/transaction.test.js +291 -11
- package/dist/test/unit/transactionBuilder.test.js +16 -3
- package/dist/test/unit/transactionFlow.test.js +67 -2
- package/dist/test/unit/utils.test.js +63 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -5
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PSKT (Partially Signed Kaspa Transaction) — Unit Tests
|
|
4
|
+
*
|
|
5
|
+
* Covers:
|
|
6
|
+
* - Full role flow: CREATOR → UPDATER → SIGNER → FINALIZER → EXTRACTOR
|
|
7
|
+
* - HSM / external signing path via addSignature()
|
|
8
|
+
* - Multi-party COMBINER role
|
|
9
|
+
* - serialize() / deserialize() round-trip
|
|
10
|
+
* - Extractor output matches Transaction.toBroadcastFormat()
|
|
11
|
+
* - Transaction.toPskt() and Transaction.fromPskt() bridge methods
|
|
12
|
+
* - TransactionBuilder.toPskt() unsigned PSKT construction
|
|
13
|
+
* - Role guard errors
|
|
14
|
+
*/
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
const assert_1 = __importDefault(require("assert"));
|
|
20
|
+
const statics_1 = require("@bitgo-beta/statics");
|
|
21
|
+
const secp256k1_1 = require("@bitgo-beta/secp256k1");
|
|
22
|
+
const pskt_1 = require("../../src/lib/pskt");
|
|
23
|
+
const transaction_1 = require("../../src/lib/transaction");
|
|
24
|
+
const transactionBuilder_1 = require("../../src/lib/transactionBuilder");
|
|
25
|
+
const sighash_1 = require("../../src/lib/sighash");
|
|
26
|
+
const constants_1 = require("../../src/lib/constants");
|
|
27
|
+
const kaspa_fixtures_1 = require("../fixtures/kaspa.fixtures");
|
|
28
|
+
const PRV_KEY_BUF = Buffer.from(kaspa_fixtures_1.KEYS.prv, 'hex');
|
|
29
|
+
const PUB_KEY_BUF = Buffer.from(kaspa_fixtures_1.KEYS.pub, 'hex');
|
|
30
|
+
const X_ONLY_PUB = PUB_KEY_BUF.slice(1); // 32-byte x-only key for Schnorr verify
|
|
31
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
32
|
+
function makePsktInput(utxo) {
|
|
33
|
+
return {
|
|
34
|
+
previousOutpoint: { transactionId: utxo.transactionId, index: utxo.transactionIndex },
|
|
35
|
+
utxoEntry: { amount: utxo.amount, scriptPublicKey: utxo.scriptPublicKey },
|
|
36
|
+
sequence: utxo.sequence,
|
|
37
|
+
sigOpCount: utxo.sigOpCount ?? 1,
|
|
38
|
+
partialSigs: {},
|
|
39
|
+
sighashType: constants_1.SIGHASH_ALL,
|
|
40
|
+
bip32Derivations: {},
|
|
41
|
+
proprietaries: {},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function makePsktOutput() {
|
|
45
|
+
return {
|
|
46
|
+
amount: '99998000',
|
|
47
|
+
scriptPublicKey: { version: 0, scriptPublicKey: kaspa_fixtures_1.SCRIPT_PUBLIC_KEY },
|
|
48
|
+
bip32Derivations: {},
|
|
49
|
+
proprietaries: {},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// ─── Tests ────────────────────────────────────────────────────────────────────
|
|
53
|
+
describe('PSKT — role state machine', function () {
|
|
54
|
+
it('enforces role transitions: CREATOR → UPDATER → SIGNER → FINALIZER → EXTRACTOR', function () {
|
|
55
|
+
const pskt = pskt_1.Pskt.creator();
|
|
56
|
+
assert_1.default.equal(pskt.role, 'CREATOR');
|
|
57
|
+
const updater = pskt.toUpdater();
|
|
58
|
+
assert_1.default.equal(updater.role, 'UPDATER');
|
|
59
|
+
const signer = updater.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
|
|
60
|
+
assert_1.default.equal(signer.role, 'SIGNER');
|
|
61
|
+
const finalizer = signer.sign(PRV_KEY_BUF).toFinalizer();
|
|
62
|
+
assert_1.default.equal(finalizer.role, 'FINALIZER');
|
|
63
|
+
const extractor = finalizer.finalize().toExtractor();
|
|
64
|
+
assert_1.default.equal(extractor.role, 'EXTRACTOR');
|
|
65
|
+
});
|
|
66
|
+
it('enforces role transitions: SIGNER → COMBINER → FINALIZER → EXTRACTOR', function () {
|
|
67
|
+
const signer = pskt_1.Pskt.creator()
|
|
68
|
+
.toUpdater()
|
|
69
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
70
|
+
.output(makePsktOutput())
|
|
71
|
+
.toSigner()
|
|
72
|
+
.sign(PRV_KEY_BUF);
|
|
73
|
+
const combiner = signer.toCombiner();
|
|
74
|
+
assert_1.default.equal(combiner.role, 'COMBINER');
|
|
75
|
+
const finalizer = combiner.toFinalizer();
|
|
76
|
+
assert_1.default.equal(finalizer.role, 'FINALIZER');
|
|
77
|
+
const extractor = finalizer.finalize().toExtractor();
|
|
78
|
+
assert_1.default.equal(extractor.role, 'EXTRACTOR');
|
|
79
|
+
});
|
|
80
|
+
it('throws when calling toUpdater() from SIGNER role', function () {
|
|
81
|
+
const signer = pskt_1.Pskt.creator().toUpdater().input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
|
|
82
|
+
assert_1.default.throws(() => signer.toUpdater(), /role/i);
|
|
83
|
+
});
|
|
84
|
+
it('throws when calling sign() from FINALIZER role', function () {
|
|
85
|
+
const finalizer = pskt_1.Pskt.creator()
|
|
86
|
+
.toUpdater()
|
|
87
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
88
|
+
.output(makePsktOutput())
|
|
89
|
+
.toSigner()
|
|
90
|
+
.sign(PRV_KEY_BUF)
|
|
91
|
+
.toFinalizer();
|
|
92
|
+
assert_1.default.throws(() => finalizer.sign(PRV_KEY_BUF), /role/i);
|
|
93
|
+
});
|
|
94
|
+
it('throws toExtractor() when inputs are not finalized', function () {
|
|
95
|
+
const finalizer = pskt_1.Pskt.creator()
|
|
96
|
+
.toUpdater()
|
|
97
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
98
|
+
.output(makePsktOutput())
|
|
99
|
+
.toSigner()
|
|
100
|
+
.toFinalizer(); // skip signing
|
|
101
|
+
assert_1.default.throws(() => finalizer.toExtractor(), /finalised|finalScriptSig/i);
|
|
102
|
+
});
|
|
103
|
+
it('throws finalize() when input has no partial signatures', function () {
|
|
104
|
+
const finalizer = pskt_1.Pskt.creator()
|
|
105
|
+
.toUpdater()
|
|
106
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
107
|
+
.output(makePsktOutput())
|
|
108
|
+
.toSigner()
|
|
109
|
+
.toFinalizer();
|
|
110
|
+
assert_1.default.throws(() => finalizer.finalize(), /no partial signatures/i);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
describe('PSKT — sign() produces valid Schnorr signatures', function () {
|
|
114
|
+
it('sign() writes partialSigs for each input', function () {
|
|
115
|
+
const signer = pskt_1.Pskt.creator()
|
|
116
|
+
.toUpdater()
|
|
117
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
118
|
+
.output(makePsktOutput())
|
|
119
|
+
.toSigner()
|
|
120
|
+
.sign(PRV_KEY_BUF);
|
|
121
|
+
assert_1.default.equal(signer.inputs.length, 1);
|
|
122
|
+
const sigs = Object.entries(signer.inputs[0].partialSigs);
|
|
123
|
+
assert_1.default.equal(sigs.length, 1, 'should have exactly one partial sig');
|
|
124
|
+
const [pubKeyHex, sigHex] = sigs[0];
|
|
125
|
+
assert_1.default.equal(pubKeyHex, kaspa_fixtures_1.KEYS.pub, 'pubKey key should match');
|
|
126
|
+
assert_1.default.equal(Buffer.from(sigHex, 'hex').length, 64, 'sig should be 64 bytes');
|
|
127
|
+
});
|
|
128
|
+
it('sign() Schnorr signatures verify against the correct per-input sighash', function () {
|
|
129
|
+
const pskt = pskt_1.Pskt.creator()
|
|
130
|
+
.toUpdater()
|
|
131
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
132
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.second))
|
|
133
|
+
.output({
|
|
134
|
+
amount: '299998000',
|
|
135
|
+
scriptPublicKey: { version: 0, scriptPublicKey: kaspa_fixtures_1.SCRIPT_PUBLIC_KEY },
|
|
136
|
+
bip32Derivations: {},
|
|
137
|
+
proprietaries: {},
|
|
138
|
+
})
|
|
139
|
+
.toSigner()
|
|
140
|
+
.sign(PRV_KEY_BUF);
|
|
141
|
+
// Build matching KaspaTransactionData for sighash reference
|
|
142
|
+
const txData = kaspa_fixtures_1.TRANSACTIONS.multiInput;
|
|
143
|
+
for (let i = 0; i < pskt.inputs.length; i++) {
|
|
144
|
+
const sigs = Object.values(pskt.inputs[i].partialSigs);
|
|
145
|
+
assert_1.default.equal(sigs.length, 1);
|
|
146
|
+
const sig = Buffer.from(sigs[0], 'hex');
|
|
147
|
+
const expectedHash = (0, sighash_1.computeKaspaSigningHash)(txData, i, constants_1.SIGHASH_ALL);
|
|
148
|
+
assert_1.default.ok(secp256k1_1.ecc.verifySchnorr(expectedHash, X_ONLY_PUB, sig), `Input[${i}] Schnorr sig should verify`);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
describe('PSKT — addSignature() (HSM / external signing path)', function () {
|
|
153
|
+
it('addSignature() writes the provided sig into partialSigs', function () {
|
|
154
|
+
const signer = pskt_1.Pskt.creator().toUpdater().input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
|
|
155
|
+
// Produce sig externally
|
|
156
|
+
const txData = kaspa_fixtures_1.TRANSACTIONS.simple;
|
|
157
|
+
const sigHash = (0, sighash_1.computeKaspaSigningHash)(txData, 0, constants_1.SIGHASH_ALL);
|
|
158
|
+
const sig = Buffer.from(secp256k1_1.ecc.signSchnorr(sigHash, PRV_KEY_BUF));
|
|
159
|
+
signer.addSignature(0, kaspa_fixtures_1.KEYS.pub, sig.toString('hex'));
|
|
160
|
+
const sigs = Object.entries(signer.inputs[0].partialSigs);
|
|
161
|
+
assert_1.default.equal(sigs.length, 1);
|
|
162
|
+
assert_1.default.equal(sigs[0][0], kaspa_fixtures_1.KEYS.pub);
|
|
163
|
+
assert_1.default.equal(sigs[0][1], sig.toString('hex'));
|
|
164
|
+
});
|
|
165
|
+
it('addSignature() → finalize() produces a valid finalScriptSig', function () {
|
|
166
|
+
const txData = kaspa_fixtures_1.TRANSACTIONS.simple;
|
|
167
|
+
const sigHash = (0, sighash_1.computeKaspaSigningHash)(txData, 0, constants_1.SIGHASH_ALL);
|
|
168
|
+
const sig = Buffer.from(secp256k1_1.ecc.signSchnorr(sigHash, PRV_KEY_BUF));
|
|
169
|
+
const pskt = pskt_1.Pskt.creator()
|
|
170
|
+
.toUpdater()
|
|
171
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
172
|
+
.output(makePsktOutput())
|
|
173
|
+
.toSigner()
|
|
174
|
+
.addSignature(0, kaspa_fixtures_1.KEYS.pub, sig.toString('hex'))
|
|
175
|
+
.toFinalizer()
|
|
176
|
+
.finalize();
|
|
177
|
+
const finalSig = pskt.inputs[0].finalScriptSig;
|
|
178
|
+
assert_1.default.ok(finalSig, 'finalScriptSig should be set');
|
|
179
|
+
const finalBuf = Buffer.from(finalSig, 'hex');
|
|
180
|
+
assert_1.default.equal(finalBuf.length, 66, 'finalScriptSig should be 66 bytes (0x41 + 64-byte sig + 1-byte sighash)');
|
|
181
|
+
assert_1.default.equal(finalBuf[0], 0x41, 'first byte should be OP_DATA_65');
|
|
182
|
+
assert_1.default.equal(finalBuf[65], constants_1.SIGHASH_ALL, 'last byte should be sighash type');
|
|
183
|
+
});
|
|
184
|
+
it('throws on addSignature() with wrong-sized signature', function () {
|
|
185
|
+
const signer = pskt_1.Pskt.creator().toUpdater().input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
|
|
186
|
+
assert_1.default.throws(() => signer.addSignature(0, kaspa_fixtures_1.KEYS.pub, 'deadbeef'), /64-byte/i);
|
|
187
|
+
});
|
|
188
|
+
it('throws on addSignature() with out-of-range input index', function () {
|
|
189
|
+
const signer = pskt_1.Pskt.creator().toUpdater().input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
|
|
190
|
+
assert_1.default.throws(() => signer.addSignature(99, kaspa_fixtures_1.KEYS.pub, 'aa'.repeat(64)), /out of range/i);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
describe('PSKT — combine() merges partialSigs', function () {
|
|
194
|
+
it('combine() merges partial signatures from two signers', function () {
|
|
195
|
+
const buildSigned = () => pskt_1.Pskt.creator()
|
|
196
|
+
.toUpdater()
|
|
197
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
198
|
+
.output(makePsktOutput())
|
|
199
|
+
.toSigner()
|
|
200
|
+
.sign(PRV_KEY_BUF);
|
|
201
|
+
const pskt1 = buildSigned();
|
|
202
|
+
const pskt2 = buildSigned();
|
|
203
|
+
// Both have the same sig; combining should succeed (idempotent)
|
|
204
|
+
const combined = pskt1.toCombiner().combine(pskt2);
|
|
205
|
+
const sigs = Object.entries(combined.inputs[0].partialSigs);
|
|
206
|
+
assert_1.default.equal(sigs.length, 1);
|
|
207
|
+
});
|
|
208
|
+
it('combine() throws on conflicting signatures for the same pubKey', function () {
|
|
209
|
+
// Simulate two different signers by manually injecting different sigs
|
|
210
|
+
const signer1 = pskt_1.Pskt.creator()
|
|
211
|
+
.toUpdater()
|
|
212
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
213
|
+
.output(makePsktOutput())
|
|
214
|
+
.toSigner()
|
|
215
|
+
.addSignature(0, kaspa_fixtures_1.KEYS.pub, 'aa'.repeat(64));
|
|
216
|
+
const signer2 = pskt_1.Pskt.creator()
|
|
217
|
+
.toUpdater()
|
|
218
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
219
|
+
.output(makePsktOutput())
|
|
220
|
+
.toSigner()
|
|
221
|
+
.addSignature(0, kaspa_fixtures_1.KEYS.pub, 'bb'.repeat(64));
|
|
222
|
+
assert_1.default.throws(() => signer1.toCombiner().combine(signer2), /conflicting signature/i);
|
|
223
|
+
});
|
|
224
|
+
it('combine() throws on input count mismatch', function () {
|
|
225
|
+
const a = pskt_1.Pskt.creator()
|
|
226
|
+
.toUpdater()
|
|
227
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
228
|
+
.output(makePsktOutput())
|
|
229
|
+
.toSigner()
|
|
230
|
+
.toCombiner();
|
|
231
|
+
const b = pskt_1.Pskt.creator()
|
|
232
|
+
.toUpdater()
|
|
233
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
234
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.second))
|
|
235
|
+
.output(makePsktOutput())
|
|
236
|
+
.toSigner()
|
|
237
|
+
.toCombiner();
|
|
238
|
+
assert_1.default.throws(() => a.combine(b), /input count mismatch/i);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
describe('PSKT — serialize() / deserialize() round-trip', function () {
|
|
242
|
+
it('round-trips a PSKT in SIGNER role before signing', function () {
|
|
243
|
+
const original = pskt_1.Pskt.creator().toUpdater().input(makePsktInput(kaspa_fixtures_1.UTXOS.simple)).output(makePsktOutput()).toSigner();
|
|
244
|
+
const json = original.serialize();
|
|
245
|
+
assert_1.default.doesNotThrow(() => JSON.parse(json), 'serialized form should be valid JSON');
|
|
246
|
+
const restored = pskt_1.Pskt.deserialize(json);
|
|
247
|
+
assert_1.default.equal(restored.role, 'SIGNER');
|
|
248
|
+
assert_1.default.equal(restored.inputs.length, 1);
|
|
249
|
+
assert_1.default.equal(restored.outputs.length, 1);
|
|
250
|
+
assert_1.default.equal(restored.inputs[0].previousOutpoint.transactionId, kaspa_fixtures_1.UTXOS.simple.transactionId);
|
|
251
|
+
assert_1.default.equal(restored.outputs[0].amount, '99998000');
|
|
252
|
+
});
|
|
253
|
+
it('round-trips a signed PSKT preserving partialSigs', function () {
|
|
254
|
+
const signed = pskt_1.Pskt.creator()
|
|
255
|
+
.toUpdater()
|
|
256
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
257
|
+
.output(makePsktOutput())
|
|
258
|
+
.toSigner()
|
|
259
|
+
.sign(PRV_KEY_BUF);
|
|
260
|
+
const restored = pskt_1.Pskt.deserialize(signed.serialize());
|
|
261
|
+
assert_1.default.equal(restored.role, 'SIGNER');
|
|
262
|
+
const sigs = Object.entries(restored.inputs[0].partialSigs);
|
|
263
|
+
assert_1.default.equal(sigs.length, 1, 'partialSigs should survive round-trip');
|
|
264
|
+
assert_1.default.equal(sigs[0][0], kaspa_fixtures_1.KEYS.pub);
|
|
265
|
+
});
|
|
266
|
+
it('throws on invalid PSKT JSON', function () {
|
|
267
|
+
assert_1.default.throws(() => pskt_1.Pskt.deserialize('not json'), /JSON/i);
|
|
268
|
+
assert_1.default.throws(() => pskt_1.Pskt.deserialize('{}'), /missing required fields/i);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
describe('PSKT — extract() matches Transaction.toBroadcastFormat()', function () {
|
|
272
|
+
it('single-input: extract() === toBroadcastFormat()', function () {
|
|
273
|
+
const tx = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.simple);
|
|
274
|
+
tx.sign(PRV_KEY_BUF);
|
|
275
|
+
// PSKT path
|
|
276
|
+
const broadcastViaPskt = tx
|
|
277
|
+
.toPskt() // SIGNER role, finalScriptSig already set from tx.sign()
|
|
278
|
+
.toFinalizer()
|
|
279
|
+
.finalize()
|
|
280
|
+
.toExtractor()
|
|
281
|
+
.extract();
|
|
282
|
+
// Direct path
|
|
283
|
+
const broadcastDirect = tx.toBroadcastFormat();
|
|
284
|
+
assert_1.default.deepStrictEqual(JSON.parse(broadcastViaPskt), JSON.parse(broadcastDirect));
|
|
285
|
+
});
|
|
286
|
+
it('multi-input: extract() === toBroadcastFormat()', function () {
|
|
287
|
+
const tx = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.multiInput);
|
|
288
|
+
tx.sign(PRV_KEY_BUF);
|
|
289
|
+
const broadcastViaPskt = tx.toPskt().toFinalizer().finalize().toExtractor().extract();
|
|
290
|
+
const broadcastDirect = tx.toBroadcastFormat();
|
|
291
|
+
assert_1.default.deepStrictEqual(JSON.parse(broadcastViaPskt), JSON.parse(broadcastDirect));
|
|
292
|
+
});
|
|
293
|
+
it('PSKT-signed extract() === direct sign + toBroadcastFormat()', function () {
|
|
294
|
+
// Build via PSKT from scratch
|
|
295
|
+
const broadcastViaPskt = pskt_1.Pskt.creator()
|
|
296
|
+
.toUpdater()
|
|
297
|
+
.input(makePsktInput(kaspa_fixtures_1.UTXOS.simple))
|
|
298
|
+
.output(makePsktOutput())
|
|
299
|
+
.toSigner()
|
|
300
|
+
.sign(PRV_KEY_BUF)
|
|
301
|
+
.toFinalizer()
|
|
302
|
+
.finalize()
|
|
303
|
+
.toExtractor()
|
|
304
|
+
.extract();
|
|
305
|
+
// Build via Transaction directly
|
|
306
|
+
const tx = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.simple);
|
|
307
|
+
tx.sign(PRV_KEY_BUF);
|
|
308
|
+
const broadcastDirect = tx.toBroadcastFormat();
|
|
309
|
+
assert_1.default.deepStrictEqual(JSON.parse(broadcastViaPskt), JSON.parse(broadcastDirect));
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
describe('PSKT — Transaction.toPskt() and Transaction.fromPskt()', function () {
|
|
313
|
+
it('toPskt() returns a SIGNER-role PSKT with UTXO data populated', function () {
|
|
314
|
+
const tx = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.simple);
|
|
315
|
+
const pskt = tx.toPskt();
|
|
316
|
+
assert_1.default.equal(pskt.role, 'SIGNER');
|
|
317
|
+
assert_1.default.equal(pskt.inputs.length, 1);
|
|
318
|
+
assert_1.default.equal(pskt.inputs[0].utxoEntry?.amount, kaspa_fixtures_1.UTXOS.simple.amount);
|
|
319
|
+
assert_1.default.equal(pskt.inputs[0].utxoEntry?.scriptPublicKey, kaspa_fixtures_1.UTXOS.simple.scriptPublicKey);
|
|
320
|
+
});
|
|
321
|
+
it('fromPskt() reconstructs a Transaction from a finalised PSKT', function () {
|
|
322
|
+
const original = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.simple);
|
|
323
|
+
original.sign(PRV_KEY_BUF);
|
|
324
|
+
const pskt = original.toPskt().toFinalizer().finalize();
|
|
325
|
+
const restored = transaction_1.Transaction.fromPskt('kaspa', pskt);
|
|
326
|
+
assert_1.default.deepStrictEqual(JSON.parse(restored.toBroadcastFormat()), JSON.parse(original.toBroadcastFormat()));
|
|
327
|
+
});
|
|
328
|
+
it('fromPskt() → verifySignature() succeeds', function () {
|
|
329
|
+
const original = transaction_1.Transaction.fromJson('kaspa', kaspa_fixtures_1.TRANSACTIONS.simple);
|
|
330
|
+
original.sign(PRV_KEY_BUF);
|
|
331
|
+
const pskt = original.toPskt().toFinalizer().finalize();
|
|
332
|
+
const restored = transaction_1.Transaction.fromPskt('kaspa', pskt);
|
|
333
|
+
assert_1.default.ok(restored.verifySignature(PUB_KEY_BUF, 0), 'signature should verify after fromPskt()');
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
describe('PSKT — TransactionBuilder.toPskt()', function () {
|
|
337
|
+
it('returns an UPDATER-role PSKT with all inputs and outputs', async function () {
|
|
338
|
+
const coinConfig = statics_1.coins.get('kaspa');
|
|
339
|
+
const builder = new transactionBuilder_1.TransactionBuilder(coinConfig);
|
|
340
|
+
builder.addInput(kaspa_fixtures_1.UTXOS.simple).to(kaspa_fixtures_1.ADDRESSES.recipient, '99998000').fee('2000');
|
|
341
|
+
const pskt = await builder.toPskt();
|
|
342
|
+
assert_1.default.equal(pskt.role, 'UPDATER');
|
|
343
|
+
assert_1.default.equal(pskt.inputs.length, 1);
|
|
344
|
+
assert_1.default.equal(pskt.outputs.length, 1);
|
|
345
|
+
assert_1.default.equal(pskt.inputs[0].previousOutpoint.transactionId, kaspa_fixtures_1.UTXOS.simple.transactionId);
|
|
346
|
+
assert_1.default.equal(pskt.outputs[0].amount, '99998000');
|
|
347
|
+
});
|
|
348
|
+
it('UPDATER PSKT can be signed and extracted to produce a valid broadcast payload', async function () {
|
|
349
|
+
const coinConfig = statics_1.coins.get('kaspa');
|
|
350
|
+
const builder = new transactionBuilder_1.TransactionBuilder(coinConfig);
|
|
351
|
+
builder.addInput(kaspa_fixtures_1.UTXOS.simple).to(kaspa_fixtures_1.ADDRESSES.recipient, '99998000').fee('2000');
|
|
352
|
+
const broadcast = (await builder.toPskt())
|
|
353
|
+
.toSigner()
|
|
354
|
+
.sign(PRV_KEY_BUF)
|
|
355
|
+
.toFinalizer()
|
|
356
|
+
.finalize()
|
|
357
|
+
.toExtractor()
|
|
358
|
+
.extract();
|
|
359
|
+
assert_1.default.doesNotThrow(() => JSON.parse(broadcast), 'extract() should produce valid JSON');
|
|
360
|
+
const parsed = JSON.parse(broadcast);
|
|
361
|
+
assert_1.default.ok(parsed.inputs[0].signatureScript, 'signatureScript should be set');
|
|
362
|
+
assert_1.default.equal(Buffer.from(parsed.inputs[0].signatureScript, 'hex').length, 66);
|
|
363
|
+
});
|
|
364
|
+
it('PSKT from builder matches broadcast from Transaction.sign()', async function () {
|
|
365
|
+
const coinConfig = statics_1.coins.get('kaspa');
|
|
366
|
+
const builder = new transactionBuilder_1.TransactionBuilder(coinConfig);
|
|
367
|
+
builder.addInput(kaspa_fixtures_1.UTXOS.simple).to(kaspa_fixtures_1.ADDRESSES.recipient, '99998000').fee('2000');
|
|
368
|
+
const broadcastViaPskt = (await builder.toPskt())
|
|
369
|
+
.toSigner()
|
|
370
|
+
.sign(PRV_KEY_BUF)
|
|
371
|
+
.toFinalizer()
|
|
372
|
+
.finalize()
|
|
373
|
+
.toExtractor()
|
|
374
|
+
.extract();
|
|
375
|
+
// Rebuild via standard path
|
|
376
|
+
const builder2 = new transactionBuilder_1.TransactionBuilder(coinConfig);
|
|
377
|
+
builder2.addInput(kaspa_fixtures_1.UTXOS.simple).to(kaspa_fixtures_1.ADDRESSES.recipient, '99998000').fee('2000');
|
|
378
|
+
const tx = (await builder2.build());
|
|
379
|
+
tx.sign(PRV_KEY_BUF);
|
|
380
|
+
assert_1.default.deepStrictEqual(JSON.parse(broadcastViaPskt), JSON.parse(tx.toBroadcastFormat()));
|
|
381
|
+
});
|
|
382
|
+
});
|
|
383
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHNrdC50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdGVzdC91bml0L3Bza3QudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7OztHQVlHOzs7OztBQUVILG9EQUE0QjtBQUM1QixpREFBNEM7QUFDNUMscURBQTRDO0FBQzVDLDZDQUFpRTtBQUNqRSwyREFBd0Q7QUFDeEQseUVBQXNFO0FBQ3RFLG1EQUFnRTtBQUNoRSx1REFBc0Q7QUFDdEQsK0RBQXFHO0FBRXJHLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMscUJBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDakQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxxQkFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNqRCxNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsd0NBQXdDO0FBRWpGLGlGQUFpRjtBQUVqRixTQUFTLGFBQWEsQ0FBQyxJQUE4QjtJQUNuRCxPQUFPO1FBQ0wsZ0JBQWdCLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1FBQ3JGLFNBQVMsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLGVBQWUsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUFFO1FBQ3pFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtRQUN2QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDO1FBQ2hDLFdBQVcsRUFBRSxFQUFFO1FBQ2YsV0FBVyxFQUFFLHVCQUFXO1FBQ3hCLGdCQUFnQixFQUFFLEVBQUU7UUFDcEIsYUFBYSxFQUFFLEVBQUU7S0FDbEIsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLGNBQWM7SUFDckIs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Q0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsMEJBQVMsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRS9FLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQzthQUM5QyxRQUFRLEVBQUU7YUFDVixJQUFJLENBQUMsV0FBVyxDQUFDO2FBQ2pCLFdBQVcsRUFBRTthQUNiLFFBQVEsRUFBRTthQUNWLFdBQVcsRUFBRTthQUNiLE9BQU8sRUFBRSxDQUFDO1FBRWIsNEJBQTRCO1FBQzVCLE1BQU0sUUFBUSxHQUFHLElBQUksdUNBQWtCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDcEQsUUFBUSxDQUFDLFFBQVEsQ0FBQyxzQkFBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQywwQkFBUyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEYsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBZ0IsQ0FBQztRQUNuRCxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRXJCLGdCQUFNLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMzRixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQU0tUIChQYXJ0aWFsbHkgU2lnbmVkIEthc3BhIFRyYW5zYWN0aW9uKSDigJQgVW5pdCBUZXN0c1xuICpcbiAqIENvdmVyczpcbiAqICAgLSBGdWxsIHJvbGUgZmxvdzogQ1JFQVRPUiDihpIgVVBEQVRFUiDihpIgU0lHTkVSIOKGkiBGSU5BTElaRVIg4oaSIEVYVFJBQ1RPUlxuICogICAtIEhTTSAvIGV4dGVybmFsIHNpZ25pbmcgcGF0aCB2aWEgYWRkU2lnbmF0dXJlKClcbiAqICAgLSBNdWx0aS1wYXJ0eSBDT01CSU5FUiByb2xlXG4gKiAgIC0gc2VyaWFsaXplKCkgLyBkZXNlcmlhbGl6ZSgpIHJvdW5kLXRyaXBcbiAqICAgLSBFeHRyYWN0b3Igb3V0cHV0IG1hdGNoZXMgVHJhbnNhY3Rpb24udG9Ccm9hZGNhc3RGb3JtYXQoKVxuICogICAtIFRyYW5zYWN0aW9uLnRvUHNrdCgpIGFuZCBUcmFuc2FjdGlvbi5mcm9tUHNrdCgpIGJyaWRnZSBtZXRob2RzXG4gKiAgIC0gVHJhbnNhY3Rpb25CdWlsZGVyLnRvUHNrdCgpIHVuc2lnbmVkIFBTS1QgY29uc3RydWN0aW9uXG4gKiAgIC0gUm9sZSBndWFyZCBlcnJvcnNcbiAqL1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgZWNjIH0gZnJvbSAnQGJpdGdvLWJldGEvc2VjcDI1NmsxJztcbmltcG9ydCB7IFBza3QsIFBza3RJbnB1dCwgUHNrdE91dHB1dCB9IGZyb20gJy4uLy4uL3NyYy9saWIvcHNrdCc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbiB9IGZyb20gJy4uLy4uL3NyYy9saWIvdHJhbnNhY3Rpb24nO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25CdWlsZGVyIH0gZnJvbSAnLi4vLi4vc3JjL2xpYi90cmFuc2FjdGlvbkJ1aWxkZXInO1xuaW1wb3J0IHsgY29tcHV0ZUthc3BhU2lnbmluZ0hhc2ggfSBmcm9tICcuLi8uLi9zcmMvbGliL3NpZ2hhc2gnO1xuaW1wb3J0IHsgU0lHSEFTSF9BTEwgfSBmcm9tICcuLi8uLi9zcmMvbGliL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBLRVlTLCBBRERSRVNTRVMsIFVUWE9TLCBUUkFOU0FDVElPTlMsIFNDUklQVF9QVUJMSUNfS0VZIH0gZnJvbSAnLi4vZml4dHVyZXMva2FzcGEuZml4dHVyZXMnO1xuXG5jb25zdCBQUlZfS0VZX0JVRiA9IEJ1ZmZlci5mcm9tKEtFWVMucHJ2LCAnaGV4Jyk7XG5jb25zdCBQVUJfS0VZX0JVRiA9IEJ1ZmZlci5mcm9tKEtFWVMucHViLCAnaGV4Jyk7XG5jb25zdCBYX09OTFlfUFVCID0gUFVCX0tFWV9CVUYuc2xpY2UoMSk7IC8vIDMyLWJ5dGUgeC1vbmx5IGtleSBmb3IgU2Nobm9yciB2ZXJpZnlcblxuLy8g4pSA4pSA4pSAIEhlbHBlcnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmZ1bmN0aW9uIG1ha2VQc2t0SW5wdXQodXR4bzogKHR5cGVvZiBVVFhPUylbJ3NpbXBsZSddKTogUHNrdElucHV0IHtcbiAgcmV0dXJuIHtcbiAgICBwcmV2aW91c091dHBvaW50OiB7IHRyYW5zYWN0aW9uSWQ6IHV0eG8udHJhbnNhY3Rpb25JZCwgaW5kZXg6IHV0eG8udHJhbnNhY3Rpb25JbmRleCB9LFxuICAgIHV0eG9FbnRyeTogeyBhbW91bnQ6IHV0eG8uYW1vdW50LCBzY3JpcHRQdWJsaWNLZXk6IHV0eG8uc2NyaXB0UHVibGljS2V5IH0sXG4gICAgc2VxdWVuY2U6IHV0eG8uc2VxdWVuY2UsXG4gICAgc2lnT3BDb3VudDogdXR4by5zaWdPcENvdW50ID8/IDEsXG4gICAgcGFydGlhbFNpZ3M6IHt9LFxuICAgIHNpZ2hhc2hUeXBlOiBTSUdIQVNIX0FMTCxcbiAgICBiaXAzMkRlcml2YXRpb25zOiB7fSxcbiAgICBwcm9wcmlldGFyaWVzOiB7fSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbWFrZVBza3RPdXRwdXQoKTogUHNrdE91dHB1dCB7XG4gIHJldHVybiB7XG4gICAgYW1vdW50OiAnOTk5OTgwMDAnLFxuICAgIHNjcmlwdFB1YmxpY0tleTogeyB2ZXJzaW9uOiAwLCBzY3JpcHRQdWJsaWNLZXk6IFNDUklQVF9QVUJMSUNfS0VZIH0sXG4gICAgYmlwMzJEZXJpdmF0aW9uczoge30sXG4gICAgcHJvcHJpZXRhcmllczoge30sXG4gIH07XG59XG5cbi8vIOKUgOKUgOKUgCBUZXN0cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZGVzY3JpYmUoJ1BTS1Qg4oCUIHJvbGUgc3RhdGUgbWFjaGluZScsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ2VuZm9yY2VzIHJvbGUgdHJhbnNpdGlvbnM6IENSRUFUT1Ig4oaSIFVQREFURVIg4oaSIFNJR05FUiDihpIgRklOQUxJWkVSIOKGkiBFWFRSQUNUT1InLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgcHNrdCA9IFBza3QuY3JlYXRvcigpO1xuICAgIGFzc2VydC5lcXVhbChwc2t0LnJvbGUsICdDUkVBVE9SJyk7XG5cbiAgICBjb25zdCB1cGRhdGVyID0gcHNrdC50b1VwZGF0ZXIoKTtcbiAgICBhc3NlcnQuZXF1YWwodXBkYXRlci5yb2xlLCAnVVBEQVRFUicpO1xuXG4gICAgY29uc3Qgc2lnbmVyID0gdXBkYXRlci5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKS50b1NpZ25lcigpO1xuICAgIGFzc2VydC5lcXVhbChzaWduZXIucm9sZSwgJ1NJR05FUicpO1xuXG4gICAgY29uc3QgZmluYWxpemVyID0gc2lnbmVyLnNpZ24oUFJWX0tFWV9CVUYpLnRvRmluYWxpemVyKCk7XG4gICAgYXNzZXJ0LmVxdWFsKGZpbmFsaXplci5yb2xlLCAnRklOQUxJWkVSJyk7XG5cbiAgICBjb25zdCBleHRyYWN0b3IgPSBmaW5hbGl6ZXIuZmluYWxpemUoKS50b0V4dHJhY3RvcigpO1xuICAgIGFzc2VydC5lcXVhbChleHRyYWN0b3Iucm9sZSwgJ0VYVFJBQ1RPUicpO1xuICB9KTtcblxuICBpdCgnZW5mb3JjZXMgcm9sZSB0cmFuc2l0aW9uczogU0lHTkVSIOKGkiBDT01CSU5FUiDihpIgRklOQUxJWkVSIOKGkiBFWFRSQUNUT1InLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2lnbmVyID0gUHNrdC5jcmVhdG9yKClcbiAgICAgIC50b1VwZGF0ZXIoKVxuICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSlcbiAgICAgIC5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSlcbiAgICAgIC50b1NpZ25lcigpXG4gICAgICAuc2lnbihQUlZfS0VZX0JVRik7XG5cbiAgICBjb25zdCBjb21iaW5lciA9IHNpZ25lci50b0NvbWJpbmVyKCk7XG4gICAgYXNzZXJ0LmVxdWFsKGNvbWJpbmVyLnJvbGUsICdDT01CSU5FUicpO1xuXG4gICAgY29uc3QgZmluYWxpemVyID0gY29tYmluZXIudG9GaW5hbGl6ZXIoKTtcbiAgICBhc3NlcnQuZXF1YWwoZmluYWxpemVyLnJvbGUsICdGSU5BTElaRVInKTtcblxuICAgIGNvbnN0IGV4dHJhY3RvciA9IGZpbmFsaXplci5maW5hbGl6ZSgpLnRvRXh0cmFjdG9yKCk7XG4gICAgYXNzZXJ0LmVxdWFsKGV4dHJhY3Rvci5yb2xlLCAnRVhUUkFDVE9SJyk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgd2hlbiBjYWxsaW5nIHRvVXBkYXRlcigpIGZyb20gU0lHTkVSIHJvbGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2lnbmVyID0gUHNrdC5jcmVhdG9yKCkudG9VcGRhdGVyKCkuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKS5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSkudG9TaWduZXIoKTtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHNpZ25lci50b1VwZGF0ZXIoKSwgL3JvbGUvaSk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgd2hlbiBjYWxsaW5nIHNpZ24oKSBmcm9tIEZJTkFMSVpFUiByb2xlJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGZpbmFsaXplciA9IFBza3QuY3JlYXRvcigpXG4gICAgICAudG9VcGRhdGVyKClcbiAgICAgIC5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpXG4gICAgICAub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpXG4gICAgICAudG9TaWduZXIoKVxuICAgICAgLnNpZ24oUFJWX0tFWV9CVUYpXG4gICAgICAudG9GaW5hbGl6ZXIoKTtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IGZpbmFsaXplci5zaWduKFBSVl9LRVlfQlVGKSwgL3JvbGUvaSk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3MgdG9FeHRyYWN0b3IoKSB3aGVuIGlucHV0cyBhcmUgbm90IGZpbmFsaXplZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBmaW5hbGl6ZXIgPSBQc2t0LmNyZWF0b3IoKVxuICAgICAgLnRvVXBkYXRlcigpXG4gICAgICAuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKVxuICAgICAgLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC50b0ZpbmFsaXplcigpOyAvLyBza2lwIHNpZ25pbmdcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IGZpbmFsaXplci50b0V4dHJhY3RvcigpLCAvZmluYWxpc2VkfGZpbmFsU2NyaXB0U2lnL2kpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIGZpbmFsaXplKCkgd2hlbiBpbnB1dCBoYXMgbm8gcGFydGlhbCBzaWduYXR1cmVzJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGZpbmFsaXplciA9IFBza3QuY3JlYXRvcigpXG4gICAgICAudG9VcGRhdGVyKClcbiAgICAgIC5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpXG4gICAgICAub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpXG4gICAgICAudG9TaWduZXIoKVxuICAgICAgLnRvRmluYWxpemVyKCk7XG4gICAgYXNzZXJ0LnRocm93cygoKSA9PiBmaW5hbGl6ZXIuZmluYWxpemUoKSwgL25vIHBhcnRpYWwgc2lnbmF0dXJlcy9pKTtcbiAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ1BTS1Qg4oCUIHNpZ24oKSBwcm9kdWNlcyB2YWxpZCBTY2hub3JyIHNpZ25hdHVyZXMnLCBmdW5jdGlvbiAoKSB7XG4gIGl0KCdzaWduKCkgd3JpdGVzIHBhcnRpYWxTaWdzIGZvciBlYWNoIGlucHV0JywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNpZ25lciA9IFBza3QuY3JlYXRvcigpXG4gICAgICAudG9VcGRhdGVyKClcbiAgICAgIC5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpXG4gICAgICAub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpXG4gICAgICAudG9TaWduZXIoKVxuICAgICAgLnNpZ24oUFJWX0tFWV9CVUYpO1xuXG4gICAgYXNzZXJ0LmVxdWFsKHNpZ25lci5pbnB1dHMubGVuZ3RoLCAxKTtcbiAgICBjb25zdCBzaWdzID0gT2JqZWN0LmVudHJpZXMoc2lnbmVyLmlucHV0c1swXS5wYXJ0aWFsU2lncyk7XG4gICAgYXNzZXJ0LmVxdWFsKHNpZ3MubGVuZ3RoLCAxLCAnc2hvdWxkIGhhdmUgZXhhY3RseSBvbmUgcGFydGlhbCBzaWcnKTtcbiAgICBjb25zdCBbcHViS2V5SGV4LCBzaWdIZXhdID0gc2lnc1swXTtcbiAgICBhc3NlcnQuZXF1YWwocHViS2V5SGV4LCBLRVlTLnB1YiwgJ3B1YktleSBrZXkgc2hvdWxkIG1hdGNoJyk7XG4gICAgYXNzZXJ0LmVxdWFsKEJ1ZmZlci5mcm9tKHNpZ0hleCwgJ2hleCcpLmxlbmd0aCwgNjQsICdzaWcgc2hvdWxkIGJlIDY0IGJ5dGVzJyk7XG4gIH0pO1xuXG4gIGl0KCdzaWduKCkgU2Nobm9yciBzaWduYXR1cmVzIHZlcmlmeSBhZ2FpbnN0IHRoZSBjb3JyZWN0IHBlci1pbnB1dCBzaWdoYXNoJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHBza3QgPSBQc2t0LmNyZWF0b3IoKVxuICAgICAgLnRvVXBkYXRlcigpXG4gICAgICAuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKVxuICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2Vjb25kKSlcbiAgICAgIC5vdXRwdXQoe1xuICAgICAgICBhbW91bnQ6ICcyOTk5OTgwMDAnLFxuICAgICAgICBzY3JpcHRQdWJsaWNLZXk6IHsgdmVyc2lvbjogMCwgc2NyaXB0UHVibGljS2V5OiBTQ1JJUFRfUFVCTElDX0tFWSB9LFxuICAgICAgICBiaXAzMkRlcml2YXRpb25zOiB7fSxcbiAgICAgICAgcHJvcHJpZXRhcmllczoge30sXG4gICAgICB9KVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC5zaWduKFBSVl9LRVlfQlVGKTtcblxuICAgIC8vIEJ1aWxkIG1hdGNoaW5nIEthc3BhVHJhbnNhY3Rpb25EYXRhIGZvciBzaWdoYXNoIHJlZmVyZW5jZVxuICAgIGNvbnN0IHR4RGF0YSA9IFRSQU5TQUNUSU9OUy5tdWx0aUlucHV0O1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwc2t0LmlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgc2lncyA9IE9iamVjdC52YWx1ZXMocHNrdC5pbnB1dHNbaV0ucGFydGlhbFNpZ3MpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHNpZ3MubGVuZ3RoLCAxKTtcbiAgICAgIGNvbnN0IHNpZyA9IEJ1ZmZlci5mcm9tKHNpZ3NbMF0sICdoZXgnKTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkSGFzaCA9IGNvbXB1dGVLYXNwYVNpZ25pbmdIYXNoKHR4RGF0YSwgaSwgU0lHSEFTSF9BTEwpO1xuICAgICAgYXNzZXJ0Lm9rKGVjYy52ZXJpZnlTY2hub3JyKGV4cGVjdGVkSGFzaCwgWF9PTkxZX1BVQiwgc2lnKSwgYElucHV0WyR7aX1dIFNjaG5vcnIgc2lnIHNob3VsZCB2ZXJpZnlgKTtcbiAgICB9XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBhZGRTaWduYXR1cmUoKSAoSFNNIC8gZXh0ZXJuYWwgc2lnbmluZyBwYXRoKScsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ2FkZFNpZ25hdHVyZSgpIHdyaXRlcyB0aGUgcHJvdmlkZWQgc2lnIGludG8gcGFydGlhbFNpZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2lnbmVyID0gUHNrdC5jcmVhdG9yKCkudG9VcGRhdGVyKCkuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKS5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSkudG9TaWduZXIoKTtcblxuICAgIC8vIFByb2R1Y2Ugc2lnIGV4dGVybmFsbHlcbiAgICBjb25zdCB0eERhdGEgPSBUUkFOU0FDVElPTlMuc2ltcGxlO1xuICAgIGNvbnN0IHNpZ0hhc2ggPSBjb21wdXRlS2FzcGFTaWduaW5nSGFzaCh0eERhdGEsIDAsIFNJR0hBU0hfQUxMKTtcbiAgICBjb25zdCBzaWcgPSBCdWZmZXIuZnJvbShlY2Muc2lnblNjaG5vcnIoc2lnSGFzaCwgUFJWX0tFWV9CVUYpKTtcbiAgICBzaWduZXIuYWRkU2lnbmF0dXJlKDAsIEtFWVMucHViLCBzaWcudG9TdHJpbmcoJ2hleCcpKTtcblxuICAgIGNvbnN0IHNpZ3MgPSBPYmplY3QuZW50cmllcyhzaWduZXIuaW5wdXRzWzBdLnBhcnRpYWxTaWdzKTtcbiAgICBhc3NlcnQuZXF1YWwoc2lncy5sZW5ndGgsIDEpO1xuICAgIGFzc2VydC5lcXVhbChzaWdzWzBdWzBdLCBLRVlTLnB1Yik7XG4gICAgYXNzZXJ0LmVxdWFsKHNpZ3NbMF1bMV0sIHNpZy50b1N0cmluZygnaGV4JykpO1xuICB9KTtcblxuICBpdCgnYWRkU2lnbmF0dXJlKCkg4oaSIGZpbmFsaXplKCkgcHJvZHVjZXMgYSB2YWxpZCBmaW5hbFNjcmlwdFNpZycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB0eERhdGEgPSBUUkFOU0FDVElPTlMuc2ltcGxlO1xuICAgIGNvbnN0IHNpZ0hhc2ggPSBjb21wdXRlS2FzcGFTaWduaW5nSGFzaCh0eERhdGEsIDAsIFNJR0hBU0hfQUxMKTtcbiAgICBjb25zdCBzaWcgPSBCdWZmZXIuZnJvbShlY2Muc2lnblNjaG5vcnIoc2lnSGFzaCwgUFJWX0tFWV9CVUYpKTtcblxuICAgIGNvbnN0IHBza3QgPSBQc2t0LmNyZWF0b3IoKVxuICAgICAgLnRvVXBkYXRlcigpXG4gICAgICAuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKVxuICAgICAgLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC5hZGRTaWduYXR1cmUoMCwgS0VZUy5wdWIsIHNpZy50b1N0cmluZygnaGV4JykpXG4gICAgICAudG9GaW5hbGl6ZXIoKVxuICAgICAgLmZpbmFsaXplKCk7XG5cbiAgICBjb25zdCBmaW5hbFNpZyA9IHBza3QuaW5wdXRzWzBdLmZpbmFsU2NyaXB0U2lnO1xuICAgIGFzc2VydC5vayhmaW5hbFNpZywgJ2ZpbmFsU2NyaXB0U2lnIHNob3VsZCBiZSBzZXQnKTtcbiAgICBjb25zdCBmaW5hbEJ1ZiA9IEJ1ZmZlci5mcm9tKGZpbmFsU2lnLCAnaGV4Jyk7XG4gICAgYXNzZXJ0LmVxdWFsKGZpbmFsQnVmLmxlbmd0aCwgNjYsICdmaW5hbFNjcmlwdFNpZyBzaG91bGQgYmUgNjYgYnl0ZXMgKDB4NDEgKyA2NC1ieXRlIHNpZyArIDEtYnl0ZSBzaWdoYXNoKScpO1xuICAgIGFzc2VydC5lcXVhbChmaW5hbEJ1ZlswXSwgMHg0MSwgJ2ZpcnN0IGJ5dGUgc2hvdWxkIGJlIE9QX0RBVEFfNjUnKTtcbiAgICBhc3NlcnQuZXF1YWwoZmluYWxCdWZbNjVdLCBTSUdIQVNIX0FMTCwgJ2xhc3QgYnl0ZSBzaG91bGQgYmUgc2lnaGFzaCB0eXBlJyk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgb24gYWRkU2lnbmF0dXJlKCkgd2l0aCB3cm9uZy1zaXplZCBzaWduYXR1cmUnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2lnbmVyID0gUHNrdC5jcmVhdG9yKCkudG9VcGRhdGVyKCkuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKS5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSkudG9TaWduZXIoKTtcbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHNpZ25lci5hZGRTaWduYXR1cmUoMCwgS0VZUy5wdWIsICdkZWFkYmVlZicpLCAvNjQtYnl0ZS9pKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyBvbiBhZGRTaWduYXR1cmUoKSB3aXRoIG91dC1vZi1yYW5nZSBpbnB1dCBpbmRleCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBzaWduZXIgPSBQc2t0LmNyZWF0b3IoKS50b1VwZGF0ZXIoKS5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKS50b1NpZ25lcigpO1xuICAgIGFzc2VydC50aHJvd3MoKCkgPT4gc2lnbmVyLmFkZFNpZ25hdHVyZSg5OSwgS0VZUy5wdWIsICdhYScucmVwZWF0KDY0KSksIC9vdXQgb2YgcmFuZ2UvaSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBjb21iaW5lKCkgbWVyZ2VzIHBhcnRpYWxTaWdzJywgZnVuY3Rpb24gKCkge1xuICBpdCgnY29tYmluZSgpIG1lcmdlcyBwYXJ0aWFsIHNpZ25hdHVyZXMgZnJvbSB0d28gc2lnbmVycycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBidWlsZFNpZ25lZCA9ICgpID0+XG4gICAgICBQc2t0LmNyZWF0b3IoKVxuICAgICAgICAudG9VcGRhdGVyKClcbiAgICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSlcbiAgICAgICAgLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKVxuICAgICAgICAudG9TaWduZXIoKVxuICAgICAgICAuc2lnbihQUlZfS0VZX0JVRik7XG5cbiAgICBjb25zdCBwc2t0MSA9IGJ1aWxkU2lnbmVkKCk7XG4gICAgY29uc3QgcHNrdDIgPSBidWlsZFNpZ25lZCgpO1xuXG4gICAgLy8gQm90aCBoYXZlIHRoZSBzYW1lIHNpZzsgY29tYmluaW5nIHNob3VsZCBzdWNjZWVkIChpZGVtcG90ZW50KVxuICAgIGNvbnN0IGNvbWJpbmVkID0gcHNrdDEudG9Db21iaW5lcigpLmNvbWJpbmUocHNrdDIpO1xuICAgIGNvbnN0IHNpZ3MgPSBPYmplY3QuZW50cmllcyhjb21iaW5lZC5pbnB1dHNbMF0ucGFydGlhbFNpZ3MpO1xuICAgIGFzc2VydC5lcXVhbChzaWdzLmxlbmd0aCwgMSk7XG4gIH0pO1xuXG4gIGl0KCdjb21iaW5lKCkgdGhyb3dzIG9uIGNvbmZsaWN0aW5nIHNpZ25hdHVyZXMgZm9yIHRoZSBzYW1lIHB1YktleScsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBTaW11bGF0ZSB0d28gZGlmZmVyZW50IHNpZ25lcnMgYnkgbWFudWFsbHkgaW5qZWN0aW5nIGRpZmZlcmVudCBzaWdzXG4gICAgY29uc3Qgc2lnbmVyMSA9IFBza3QuY3JlYXRvcigpXG4gICAgICAudG9VcGRhdGVyKClcbiAgICAgIC5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNpbXBsZSkpXG4gICAgICAub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpXG4gICAgICAudG9TaWduZXIoKVxuICAgICAgLmFkZFNpZ25hdHVyZSgwLCBLRVlTLnB1YiwgJ2FhJy5yZXBlYXQoNjQpKTtcblxuICAgIGNvbnN0IHNpZ25lcjIgPSBQc2t0LmNyZWF0b3IoKVxuICAgICAgLnRvVXBkYXRlcigpXG4gICAgICAuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKVxuICAgICAgLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC5hZGRTaWduYXR1cmUoMCwgS0VZUy5wdWIsICdiYicucmVwZWF0KDY0KSk7XG5cbiAgICBhc3NlcnQudGhyb3dzKCgpID0+IHNpZ25lcjEudG9Db21iaW5lcigpLmNvbWJpbmUoc2lnbmVyMiksIC9jb25mbGljdGluZyBzaWduYXR1cmUvaSk7XG4gIH0pO1xuXG4gIGl0KCdjb21iaW5lKCkgdGhyb3dzIG9uIGlucHV0IGNvdW50IG1pc21hdGNoJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGEgPSBQc2t0LmNyZWF0b3IoKVxuICAgICAgLnRvVXBkYXRlcigpXG4gICAgICAuaW5wdXQobWFrZVBza3RJbnB1dChVVFhPUy5zaW1wbGUpKVxuICAgICAgLm91dHB1dChtYWtlUHNrdE91dHB1dCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC50b0NvbWJpbmVyKCk7XG5cbiAgICBjb25zdCBiID0gUHNrdC5jcmVhdG9yKClcbiAgICAgIC50b1VwZGF0ZXIoKVxuICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSlcbiAgICAgIC5pbnB1dChtYWtlUHNrdElucHV0KFVUWE9TLnNlY29uZCkpXG4gICAgICAub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpXG4gICAgICAudG9TaWduZXIoKVxuICAgICAgLnRvQ29tYmluZXIoKTtcblxuICAgIGFzc2VydC50aHJvd3MoKCkgPT4gYS5jb21iaW5lKGIpLCAvaW5wdXQgY291bnQgbWlzbWF0Y2gvaSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBzZXJpYWxpemUoKSAvIGRlc2VyaWFsaXplKCkgcm91bmQtdHJpcCcsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ3JvdW5kLXRyaXBzIGEgUFNLVCBpbiBTSUdORVIgcm9sZSBiZWZvcmUgc2lnbmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBvcmlnaW5hbCA9IFBza3QuY3JlYXRvcigpLnRvVXBkYXRlcigpLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSkub3V0cHV0KG1ha2VQc2t0T3V0cHV0KCkpLnRvU2lnbmVyKCk7XG5cbiAgICBjb25zdCBqc29uID0gb3JpZ2luYWwuc2VyaWFsaXplKCk7XG4gICAgYXNzZXJ0LmRvZXNOb3RUaHJvdygoKSA9PiBKU09OLnBhcnNlKGpzb24pLCAnc2VyaWFsaXplZCBmb3JtIHNob3VsZCBiZSB2YWxpZCBKU09OJyk7XG5cbiAgICBjb25zdCByZXN0b3JlZCA9IFBza3QuZGVzZXJpYWxpemUoanNvbik7XG4gICAgYXNzZXJ0LmVxdWFsKHJlc3RvcmVkLnJvbGUsICdTSUdORVInKTtcbiAgICBhc3NlcnQuZXF1YWwocmVzdG9yZWQuaW5wdXRzLmxlbmd0aCwgMSk7XG4gICAgYXNzZXJ0LmVxdWFsKHJlc3RvcmVkLm91dHB1dHMubGVuZ3RoLCAxKTtcbiAgICBhc3NlcnQuZXF1YWwocmVzdG9yZWQuaW5wdXRzWzBdLnByZXZpb3VzT3V0cG9pbnQudHJhbnNhY3Rpb25JZCwgVVRYT1Muc2ltcGxlLnRyYW5zYWN0aW9uSWQpO1xuICAgIGFzc2VydC5lcXVhbChyZXN0b3JlZC5vdXRwdXRzWzBdLmFtb3VudCwgJzk5OTk4MDAwJyk7XG4gIH0pO1xuXG4gIGl0KCdyb3VuZC10cmlwcyBhIHNpZ25lZCBQU0tUIHByZXNlcnZpbmcgcGFydGlhbFNpZ3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2lnbmVkID0gUHNrdC5jcmVhdG9yKClcbiAgICAgIC50b1VwZGF0ZXIoKVxuICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSlcbiAgICAgIC5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSlcbiAgICAgIC50b1NpZ25lcigpXG4gICAgICAuc2lnbihQUlZfS0VZX0JVRik7XG5cbiAgICBjb25zdCByZXN0b3JlZCA9IFBza3QuZGVzZXJpYWxpemUoc2lnbmVkLnNlcmlhbGl6ZSgpKTtcbiAgICBhc3NlcnQuZXF1YWwocmVzdG9yZWQucm9sZSwgJ1NJR05FUicpO1xuICAgIGNvbnN0IHNpZ3MgPSBPYmplY3QuZW50cmllcyhyZXN0b3JlZC5pbnB1dHNbMF0ucGFydGlhbFNpZ3MpO1xuICAgIGFzc2VydC5lcXVhbChzaWdzLmxlbmd0aCwgMSwgJ3BhcnRpYWxTaWdzIHNob3VsZCBzdXJ2aXZlIHJvdW5kLXRyaXAnKTtcbiAgICBhc3NlcnQuZXF1YWwoc2lnc1swXVswXSwgS0VZUy5wdWIpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIG9uIGludmFsaWQgUFNLVCBKU09OJywgZnVuY3Rpb24gKCkge1xuICAgIGFzc2VydC50aHJvd3MoKCkgPT4gUHNrdC5kZXNlcmlhbGl6ZSgnbm90IGpzb24nKSwgL0pTT04vaSk7XG4gICAgYXNzZXJ0LnRocm93cygoKSA9PiBQc2t0LmRlc2VyaWFsaXplKCd7fScpLCAvbWlzc2luZyByZXF1aXJlZCBmaWVsZHMvaSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBleHRyYWN0KCkgbWF0Y2hlcyBUcmFuc2FjdGlvbi50b0Jyb2FkY2FzdEZvcm1hdCgpJywgZnVuY3Rpb24gKCkge1xuICBpdCgnc2luZ2xlLWlucHV0OiBleHRyYWN0KCkgPT09IHRvQnJvYWRjYXN0Rm9ybWF0KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgdHggPSBUcmFuc2FjdGlvbi5mcm9tSnNvbigna2FzcGEnLCBUUkFOU0FDVElPTlMuc2ltcGxlKTtcbiAgICB0eC5zaWduKFBSVl9LRVlfQlVGKTtcblxuICAgIC8vIFBTS1QgcGF0aFxuICAgIGNvbnN0IGJyb2FkY2FzdFZpYVBza3QgPSB0eFxuICAgICAgLnRvUHNrdCgpIC8vIFNJR05FUiByb2xlLCBmaW5hbFNjcmlwdFNpZyBhbHJlYWR5IHNldCBmcm9tIHR4LnNpZ24oKVxuICAgICAgLnRvRmluYWxpemVyKClcbiAgICAgIC5maW5hbGl6ZSgpXG4gICAgICAudG9FeHRyYWN0b3IoKVxuICAgICAgLmV4dHJhY3QoKTtcblxuICAgIC8vIERpcmVjdCBwYXRoXG4gICAgY29uc3QgYnJvYWRjYXN0RGlyZWN0ID0gdHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoSlNPTi5wYXJzZShicm9hZGNhc3RWaWFQc2t0KSwgSlNPTi5wYXJzZShicm9hZGNhc3REaXJlY3QpKTtcbiAgfSk7XG5cbiAgaXQoJ211bHRpLWlucHV0OiBleHRyYWN0KCkgPT09IHRvQnJvYWRjYXN0Rm9ybWF0KCknLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgdHggPSBUcmFuc2FjdGlvbi5mcm9tSnNvbigna2FzcGEnLCBUUkFOU0FDVElPTlMubXVsdGlJbnB1dCk7XG4gICAgdHguc2lnbihQUlZfS0VZX0JVRik7XG5cbiAgICBjb25zdCBicm9hZGNhc3RWaWFQc2t0ID0gdHgudG9Qc2t0KCkudG9GaW5hbGl6ZXIoKS5maW5hbGl6ZSgpLnRvRXh0cmFjdG9yKCkuZXh0cmFjdCgpO1xuICAgIGNvbnN0IGJyb2FkY2FzdERpcmVjdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKEpTT04ucGFyc2UoYnJvYWRjYXN0VmlhUHNrdCksIEpTT04ucGFyc2UoYnJvYWRjYXN0RGlyZWN0KSk7XG4gIH0pO1xuXG4gIGl0KCdQU0tULXNpZ25lZCBleHRyYWN0KCkgPT09IGRpcmVjdCBzaWduICsgdG9Ccm9hZGNhc3RGb3JtYXQoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBCdWlsZCB2aWEgUFNLVCBmcm9tIHNjcmF0Y2hcbiAgICBjb25zdCBicm9hZGNhc3RWaWFQc2t0ID0gUHNrdC5jcmVhdG9yKClcbiAgICAgIC50b1VwZGF0ZXIoKVxuICAgICAgLmlucHV0KG1ha2VQc2t0SW5wdXQoVVRYT1Muc2ltcGxlKSlcbiAgICAgIC5vdXRwdXQobWFrZVBza3RPdXRwdXQoKSlcbiAgICAgIC50b1NpZ25lcigpXG4gICAgICAuc2lnbihQUlZfS0VZX0JVRilcbiAgICAgIC50b0ZpbmFsaXplcigpXG4gICAgICAuZmluYWxpemUoKVxuICAgICAgLnRvRXh0cmFjdG9yKClcbiAgICAgIC5leHRyYWN0KCk7XG5cbiAgICAvLyBCdWlsZCB2aWEgVHJhbnNhY3Rpb24gZGlyZWN0bHlcbiAgICBjb25zdCB0eCA9IFRyYW5zYWN0aW9uLmZyb21Kc29uKCdrYXNwYScsIFRSQU5TQUNUSU9OUy5zaW1wbGUpO1xuICAgIHR4LnNpZ24oUFJWX0tFWV9CVUYpO1xuICAgIGNvbnN0IGJyb2FkY2FzdERpcmVjdCA9IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICBhc3NlcnQuZGVlcFN0cmljdEVxdWFsKEpTT04ucGFyc2UoYnJvYWRjYXN0VmlhUHNrdCksIEpTT04ucGFyc2UoYnJvYWRjYXN0RGlyZWN0KSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBUcmFuc2FjdGlvbi50b1Bza3QoKSBhbmQgVHJhbnNhY3Rpb24uZnJvbVBza3QoKScsIGZ1bmN0aW9uICgpIHtcbiAgaXQoJ3RvUHNrdCgpIHJldHVybnMgYSBTSUdORVItcm9sZSBQU0tUIHdpdGggVVRYTyBkYXRhIHBvcHVsYXRlZCcsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB0eCA9IFRyYW5zYWN0aW9uLmZyb21Kc29uKCdrYXNwYScsIFRSQU5TQUNUSU9OUy5zaW1wbGUpO1xuICAgIGNvbnN0IHBza3QgPSB0eC50b1Bza3QoKTtcbiAgICBhc3NlcnQuZXF1YWwocHNrdC5yb2xlLCAnU0lHTkVSJyk7XG4gICAgYXNzZXJ0LmVxdWFsKHBza3QuaW5wdXRzLmxlbmd0aCwgMSk7XG4gICAgYXNzZXJ0LmVxdWFsKHBza3QuaW5wdXRzWzBdLnV0eG9FbnRyeT8uYW1vdW50LCBVVFhPUy5zaW1wbGUuYW1vdW50KTtcbiAgICBhc3NlcnQuZXF1YWwocHNrdC5pbnB1dHNbMF0udXR4b0VudHJ5Py5zY3JpcHRQdWJsaWNLZXksIFVUWE9TLnNpbXBsZS5zY3JpcHRQdWJsaWNLZXkpO1xuICB9KTtcblxuICBpdCgnZnJvbVBza3QoKSByZWNvbnN0cnVjdHMgYSBUcmFuc2FjdGlvbiBmcm9tIGEgZmluYWxpc2VkIFBTS1QnLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgb3JpZ2luYWwgPSBUcmFuc2FjdGlvbi5mcm9tSnNvbigna2FzcGEnLCBUUkFOU0FDVElPTlMuc2ltcGxlKTtcbiAgICBvcmlnaW5hbC5zaWduKFBSVl9LRVlfQlVGKTtcblxuICAgIGNvbnN0IHBza3QgPSBvcmlnaW5hbC50b1Bza3QoKS50b0ZpbmFsaXplcigpLmZpbmFsaXplKCk7XG4gICAgY29uc3QgcmVzdG9yZWQgPSBUcmFuc2FjdGlvbi5mcm9tUHNrdCgna2FzcGEnLCBwc2t0KTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoSlNPTi5wYXJzZShyZXN0b3JlZC50b0Jyb2FkY2FzdEZvcm1hdCgpKSwgSlNPTi5wYXJzZShvcmlnaW5hbC50b0Jyb2FkY2FzdEZvcm1hdCgpKSk7XG4gIH0pO1xuXG4gIGl0KCdmcm9tUHNrdCgpIOKGkiB2ZXJpZnlTaWduYXR1cmUoKSBzdWNjZWVkcycsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBvcmlnaW5hbCA9IFRyYW5zYWN0aW9uLmZyb21Kc29uKCdrYXNwYScsIFRSQU5TQUNUSU9OUy5zaW1wbGUpO1xuICAgIG9yaWdpbmFsLnNpZ24oUFJWX0tFWV9CVUYpO1xuXG4gICAgY29uc3QgcHNrdCA9IG9yaWdpbmFsLnRvUHNrdCgpLnRvRmluYWxpemVyKCkuZmluYWxpemUoKTtcbiAgICBjb25zdCByZXN0b3JlZCA9IFRyYW5zYWN0aW9uLmZyb21Qc2t0KCdrYXNwYScsIHBza3QpO1xuXG4gICAgYXNzZXJ0Lm9rKHJlc3RvcmVkLnZlcmlmeVNpZ25hdHVyZShQVUJfS0VZX0JVRiwgMCksICdzaWduYXR1cmUgc2hvdWxkIHZlcmlmeSBhZnRlciBmcm9tUHNrdCgpJyk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdQU0tUIOKAlCBUcmFuc2FjdGlvbkJ1aWxkZXIudG9Qc2t0KCknLCBmdW5jdGlvbiAoKSB7XG4gIGl0KCdyZXR1cm5zIGFuIFVQREFURVItcm9sZSBQU0tUIHdpdGggYWxsIGlucHV0cyBhbmQgb3V0cHV0cycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjb2luQ29uZmlnID0gY29pbnMuZ2V0KCdrYXNwYScpO1xuICAgIGNvbnN0IGJ1aWxkZXIgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyKGNvaW5Db25maWcpO1xuICAgIGJ1aWxkZXIuYWRkSW5wdXQoVVRYT1Muc2ltcGxlKS50byhBRERSRVNTRVMucmVjaXBpZW50LCAnOTk5OTgwMDAnKS5mZWUoJzIwMDAnKTtcblxuICAgIGNvbnN0IHBza3QgPSBhd2FpdCBidWlsZGVyLnRvUHNrdCgpO1xuICAgIGFzc2VydC5lcXVhbChwc2t0LnJvbGUsICdVUERBVEVSJyk7XG4gICAgYXNzZXJ0LmVxdWFsKHBza3QuaW5wdXRzLmxlbmd0aCwgMSk7XG4gICAgYXNzZXJ0LmVxdWFsKHBza3Qub3V0cHV0cy5sZW5ndGgsIDEpO1xuICAgIGFzc2VydC5lcXVhbChwc2t0LmlucHV0c1swXS5wcmV2aW91c091dHBvaW50LnRyYW5zYWN0aW9uSWQsIFVUWE9TLnNpbXBsZS50cmFuc2FjdGlvbklkKTtcbiAgICBhc3NlcnQuZXF1YWwocHNrdC5vdXRwdXRzWzBdLmFtb3VudCwgJzk5OTk4MDAwJyk7XG4gIH0pO1xuXG4gIGl0KCdVUERBVEVSIFBTS1QgY2FuIGJlIHNpZ25lZCBhbmQgZXh0cmFjdGVkIHRvIHByb2R1Y2UgYSB2YWxpZCBicm9hZGNhc3QgcGF5bG9hZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjb2luQ29uZmlnID0gY29pbnMuZ2V0KCdrYXNwYScpO1xuICAgIGNvbnN0IGJ1aWxkZXIgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyKGNvaW5Db25maWcpO1xuICAgIGJ1aWxkZXIuYWRkSW5wdXQoVVRYT1Muc2ltcGxlKS50byhBRERSRVNTRVMucmVjaXBpZW50LCAnOTk5OTgwMDAnKS5mZWUoJzIwMDAnKTtcblxuICAgIGNvbnN0IGJyb2FkY2FzdCA9IChhd2FpdCBidWlsZGVyLnRvUHNrdCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC5zaWduKFBSVl9LRVlfQlVGKVxuICAgICAgLnRvRmluYWxpemVyKClcbiAgICAgIC5maW5hbGl6ZSgpXG4gICAgICAudG9FeHRyYWN0b3IoKVxuICAgICAgLmV4dHJhY3QoKTtcblxuICAgIGFzc2VydC5kb2VzTm90VGhyb3coKCkgPT4gSlNPTi5wYXJzZShicm9hZGNhc3QpLCAnZXh0cmFjdCgpIHNob3VsZCBwcm9kdWNlIHZhbGlkIEpTT04nKTtcbiAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGJyb2FkY2FzdCk7XG4gICAgYXNzZXJ0Lm9rKHBhcnNlZC5pbnB1dHNbMF0uc2lnbmF0dXJlU2NyaXB0LCAnc2lnbmF0dXJlU2NyaXB0IHNob3VsZCBiZSBzZXQnKTtcbiAgICBhc3NlcnQuZXF1YWwoQnVmZmVyLmZyb20ocGFyc2VkLmlucHV0c1swXS5zaWduYXR1cmVTY3JpcHQsICdoZXgnKS5sZW5ndGgsIDY2KTtcbiAgfSk7XG5cbiAgaXQoJ1BTS1QgZnJvbSBidWlsZGVyIG1hdGNoZXMgYnJvYWRjYXN0IGZyb20gVHJhbnNhY3Rpb24uc2lnbigpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGNvaW5Db25maWcgPSBjb2lucy5nZXQoJ2thc3BhJyk7XG4gICAgY29uc3QgYnVpbGRlciA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXIoY29pbkNvbmZpZyk7XG4gICAgYnVpbGRlci5hZGRJbnB1dChVVFhPUy5zaW1wbGUpLnRvKEFERFJFU1NFUy5yZWNpcGllbnQsICc5OTk5ODAwMCcpLmZlZSgnMjAwMCcpO1xuXG4gICAgY29uc3QgYnJvYWRjYXN0VmlhUHNrdCA9IChhd2FpdCBidWlsZGVyLnRvUHNrdCgpKVxuICAgICAgLnRvU2lnbmVyKClcbiAgICAgIC5zaWduKFBSVl9LRVlfQlVGKVxuICAgICAgLnRvRmluYWxpemVyKClcbiAgICAgIC5maW5hbGl6ZSgpXG4gICAgICAudG9FeHRyYWN0b3IoKVxuICAgICAgLmV4dHJhY3QoKTtcblxuICAgIC8vIFJlYnVpbGQgdmlhIHN0YW5kYXJkIHBhdGhcbiAgICBjb25zdCBidWlsZGVyMiA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXIoY29pbkNvbmZpZyk7XG4gICAgYnVpbGRlcjIuYWRkSW5wdXQoVVRYT1Muc2ltcGxlKS50byhBRERSRVNTRVMucmVjaXBpZW50LCAnOTk5OTgwMDAnKS5mZWUoJzIwMDAnKTtcbiAgICBjb25zdCB0eCA9IChhd2FpdCBidWlsZGVyMi5idWlsZCgpKSBhcyBUcmFuc2FjdGlvbjtcbiAgICB0eC5zaWduKFBSVl9LRVlfQlVGKTtcblxuICAgIGFzc2VydC5kZWVwU3RyaWN0RXF1YWwoSlNPTi5wYXJzZShicm9hZGNhc3RWaWFQc2t0KSwgSlNPTi5wYXJzZSh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpKSk7XG4gIH0pO1xufSk7XG4iXX0=
|