@bitgo-beta/sdk-coin-dot 1.3.3-alpha.472 → 1.3.3-alpha.474

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.
@@ -0,0 +1,409 @@
1
+ "use strict";
2
+ /**
3
+ * WASM Builder Byte Comparison Tests
4
+ *
5
+ * Compare serialized output between:
6
+ * 1. Legacy approach (using @substrate/txwrapper-polkadot)
7
+ * 2. WASM approach (using @bitgo/wasm-dot DotBuilder)
8
+ *
9
+ * For unsigned transactions, legacy toBroadcastFormat() returns the signing payload
10
+ * (via construct.signingPayload). We compare WASM signablePayload() against it.
11
+ *
12
+ * Format difference: txwrapper encodes the call as `Bytes` (Vec<u8>) which includes
13
+ * a SCALE compact-length prefix. subxt encodes it as raw `Call` (no prefix).
14
+ * We strip this prefix from the legacy side before comparing, since the actual
15
+ * call data, era, nonce, tip, and chain context are identical.
16
+ */
17
+ var __importDefault = (this && this.__importDefault) || function (mod) {
18
+ return (mod && mod.__esModule) ? mod : { "default": mod };
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ const assert_1 = __importDefault(require("assert"));
22
+ const statics_1 = require("@bitgo-beta/statics");
23
+ const transactionBuilderFactory_1 = require("../../src/lib/transactionBuilderFactory");
24
+ const iface_1 = require("../../src/lib/iface");
25
+ const fixtures_1 = require("../fixtures");
26
+ const utils_1 = __importDefault(require("../../src/lib/utils"));
27
+ // Import WASM builder
28
+ const wasm_dot_1 = require("@bitgo/wasm-dot");
29
+ describe('WASM vs Legacy Builder Byte Comparison', function () {
30
+ const coin = statics_1.coins.get('tdot');
31
+ // Get material from utils to ensure same metadata as legacy builder
32
+ const material = utils_1.default.getMaterial(coin);
33
+ function createWasmContext(overrides = {}) {
34
+ return {
35
+ sender: fixtures_1.accounts.account1.address,
36
+ nonce: 0,
37
+ tip: 0n,
38
+ material: material,
39
+ validity: {
40
+ firstValid: fixtures_1.westendBlock.blockNumber,
41
+ maxDuration: 2400,
42
+ },
43
+ referenceBlock: fixtures_1.westendBlock.hash,
44
+ ...overrides,
45
+ };
46
+ }
47
+ /**
48
+ * Strip SCALE compact-length prefix from the legacy signing payload.
49
+ *
50
+ * Legacy (txwrapper) encodes the call as `Bytes` type, which adds a compact-length
51
+ * prefix. subxt encodes it as raw `Call` (no prefix). Both produce identical
52
+ * call data + era + nonce + tip + chain context after this prefix.
53
+ */
54
+ function stripCompactPrefix(hex) {
55
+ const data = hex.startsWith('0x') ? hex.slice(2) : hex;
56
+ const bytes = Buffer.from(data, 'hex');
57
+ const mode = bytes[0] & 0b11;
58
+ let offset;
59
+ if (mode === 0b00)
60
+ offset = 1;
61
+ else if (mode === 0b01)
62
+ offset = 2;
63
+ else if (mode === 0b10)
64
+ offset = 4;
65
+ else
66
+ throw new Error('Big compact not supported');
67
+ return '0x' + bytes.slice(offset).toString('hex');
68
+ }
69
+ // ===========================================================================
70
+ // Transfer Transaction Tests
71
+ // ===========================================================================
72
+ describe('Transfer Transactions', function () {
73
+ it('should produce identical signing payload for transfer', async function () {
74
+ const to = fixtures_1.accounts.account2.address;
75
+ const amount = '1000000000000'; // 1 DOT
76
+ const factory = new transactionBuilderFactory_1.TransactionBuilderFactory(coin);
77
+ const legacyBuilder = factory.getTransferBuilder();
78
+ legacyBuilder
79
+ .sender({ address: fixtures_1.accounts.account1.address })
80
+ .to({ address: to })
81
+ .amount(amount)
82
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
83
+ .referenceBlock(fixtures_1.westendBlock.hash)
84
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
85
+ const legacyTx = await legacyBuilder.build();
86
+ const legacyHex = legacyTx.toBroadcastFormat();
87
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'transfer', to, amount: BigInt(amount), keepAlive: true }, createWasmContext());
88
+ const wasmHex = '0x' + Buffer.from(wasmTx.signablePayload()).toString('hex');
89
+ assert_1.default.strictEqual(wasmHex, stripCompactPrefix(legacyHex), 'Signing payload should match');
90
+ });
91
+ it('should produce identical signing payload for transferKeepAlive with different nonce', async function () {
92
+ const to = fixtures_1.accounts.account2.address;
93
+ const amount = '5000000000000'; // 5 DOT
94
+ const factory = new transactionBuilderFactory_1.TransactionBuilderFactory(coin);
95
+ const legacyBuilder = factory.getTransferBuilder();
96
+ legacyBuilder
97
+ .sender({ address: fixtures_1.accounts.account1.address })
98
+ .to({ address: to })
99
+ .amount(amount)
100
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
101
+ .referenceBlock(fixtures_1.westendBlock.hash)
102
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 5 });
103
+ const legacyTx = await legacyBuilder.build();
104
+ const legacyHex = legacyTx.toBroadcastFormat();
105
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'transfer', to, amount: BigInt(amount), keepAlive: true }, createWasmContext({ nonce: 5 }));
106
+ const wasmHex = '0x' + Buffer.from(wasmTx.signablePayload()).toString('hex');
107
+ assert_1.default.strictEqual(wasmHex, stripCompactPrefix(legacyHex), 'Signing payload should match');
108
+ });
109
+ });
110
+ // ===========================================================================
111
+ // Staking Transaction Tests
112
+ // ===========================================================================
113
+ describe('Staking Transactions', function () {
114
+ it('should produce identical signing payload for staking bond', async function () {
115
+ const amount = '10000000000000'; // 10 DOT
116
+ const factory = new transactionBuilderFactory_1.TransactionBuilderFactory(coin);
117
+ const legacyBuilder = factory.getStakingBuilder();
118
+ legacyBuilder
119
+ .sender({ address: fixtures_1.accounts.account1.address })
120
+ .amount(amount)
121
+ .payee('Staked')
122
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
123
+ .referenceBlock(fixtures_1.westendBlock.hash)
124
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
125
+ const legacyTx = await legacyBuilder.build();
126
+ const legacyHex = legacyTx.toBroadcastFormat();
127
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'stake', amount: BigInt(amount), payee: { type: 'staked' } }, createWasmContext());
128
+ const wasmHex = '0x' + Buffer.from(wasmTx.signablePayload()).toString('hex');
129
+ assert_1.default.strictEqual(wasmHex, stripCompactPrefix(legacyHex), 'Signing payload should match');
130
+ });
131
+ it('should produce identical signing payload for staking bond with Stash payee', async function () {
132
+ const amount = '20000000000000'; // 20 DOT
133
+ const factory = new transactionBuilderFactory_1.TransactionBuilderFactory(coin);
134
+ const legacyBuilder = factory.getStakingBuilder();
135
+ legacyBuilder
136
+ .sender({ address: fixtures_1.accounts.account1.address })
137
+ .amount(amount)
138
+ .payee('Stash')
139
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
140
+ .referenceBlock(fixtures_1.westendBlock.hash)
141
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
142
+ const legacyTx = await legacyBuilder.build();
143
+ const legacyHex = legacyTx.toBroadcastFormat();
144
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'stake', amount: BigInt(amount), payee: { type: 'stash' } }, createWasmContext());
145
+ const wasmHex = '0x' + Buffer.from(wasmTx.signablePayload()).toString('hex');
146
+ assert_1.default.strictEqual(wasmHex, stripCompactPrefix(legacyHex), 'Signing payload should match');
147
+ });
148
+ it('should produce identical signing payload for unstake (unbond)', async function () {
149
+ const amount = '5000000000000'; // 5 DOT
150
+ const factory = new transactionBuilderFactory_1.TransactionBuilderFactory(coin);
151
+ const legacyBuilder = factory.getUnstakeBuilder();
152
+ legacyBuilder
153
+ .sender({ address: fixtures_1.accounts.account1.address })
154
+ .amount(amount)
155
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
156
+ .referenceBlock(fixtures_1.westendBlock.hash)
157
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
158
+ const legacyTx = await legacyBuilder.build();
159
+ const legacyHex = legacyTx.toBroadcastFormat();
160
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'unstake', amount: BigInt(amount) }, createWasmContext());
161
+ const wasmHex = '0x' + Buffer.from(wasmTx.signablePayload()).toString('hex');
162
+ assert_1.default.strictEqual(wasmHex, stripCompactPrefix(legacyHex), 'Signing payload should match');
163
+ });
164
+ it('should produce identical signing payload for withdrawUnbonded', async function () {
165
+ const slashingSpans = 0;
166
+ const factory = new transactionBuilderFactory_1.TransactionBuilderFactory(coin);
167
+ const legacyBuilder = factory.getWithdrawUnstakedBuilder();
168
+ legacyBuilder
169
+ .sender({ address: fixtures_1.accounts.account1.address })
170
+ .slashingSpans(slashingSpans)
171
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
172
+ .referenceBlock(fixtures_1.westendBlock.hash)
173
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
174
+ const legacyTx = await legacyBuilder.build();
175
+ const legacyHex = legacyTx.toBroadcastFormat();
176
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'withdrawUnbonded', slashingSpans }, createWasmContext());
177
+ const wasmHex = '0x' + Buffer.from(wasmTx.signablePayload()).toString('hex');
178
+ assert_1.default.strictEqual(wasmHex, stripCompactPrefix(legacyHex), 'Signing payload should match');
179
+ });
180
+ it('should produce identical signing payload for chill (unnominate)', async function () {
181
+ const factory = new transactionBuilderFactory_1.TransactionBuilderFactory(coin);
182
+ const legacyBuilder = factory.getUnnominateBuilder();
183
+ legacyBuilder
184
+ .sender({ address: fixtures_1.accounts.account1.address })
185
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
186
+ .referenceBlock(fixtures_1.westendBlock.hash)
187
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
188
+ const legacyTx = await legacyBuilder.build();
189
+ const legacyHex = legacyTx.toBroadcastFormat();
190
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'chill' }, createWasmContext());
191
+ const wasmHex = '0x' + Buffer.from(wasmTx.signablePayload()).toString('hex');
192
+ assert_1.default.strictEqual(wasmHex, stripCompactPrefix(legacyHex), 'Signing payload should match');
193
+ });
194
+ });
195
+ // ===========================================================================
196
+ // Proxy Transaction Tests
197
+ // ===========================================================================
198
+ describe('Proxy Transactions', function () {
199
+ it('should produce identical signing payload for addProxy', async function () {
200
+ const delegate = fixtures_1.accounts.account2.address;
201
+ const factory = new transactionBuilderFactory_1.TransactionBuilderFactory(coin);
202
+ const legacyBuilder = factory.getAddressInitializationBuilder();
203
+ legacyBuilder
204
+ .sender({ address: fixtures_1.accounts.account1.address })
205
+ .owner({ address: delegate })
206
+ .type(iface_1.ProxyType.ANY)
207
+ .delay('0')
208
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
209
+ .referenceBlock(fixtures_1.westendBlock.hash)
210
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
211
+ const legacyTx = await legacyBuilder.build();
212
+ const legacyHex = legacyTx.toBroadcastFormat();
213
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'addProxy', delegate, proxyType: 'Any', delay: 0 }, createWasmContext());
214
+ const wasmHex = '0x' + Buffer.from(wasmTx.signablePayload()).toString('hex');
215
+ assert_1.default.strictEqual(wasmHex, stripCompactPrefix(legacyHex), 'Signing payload should match');
216
+ });
217
+ it('should produce identical signing payload for addProxy with Staking type', async function () {
218
+ const delegate = fixtures_1.accounts.account2.address;
219
+ const factory = new transactionBuilderFactory_1.TransactionBuilderFactory(coin);
220
+ const legacyBuilder = factory.getAddressInitializationBuilder();
221
+ legacyBuilder
222
+ .sender({ address: fixtures_1.accounts.account1.address })
223
+ .owner({ address: delegate })
224
+ .type(iface_1.ProxyType.STAKING)
225
+ .delay('100')
226
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
227
+ .referenceBlock(fixtures_1.westendBlock.hash)
228
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
229
+ const legacyTx = await legacyBuilder.build();
230
+ const legacyHex = legacyTx.toBroadcastFormat();
231
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'addProxy', delegate, proxyType: 'Staking', delay: 100 }, createWasmContext());
232
+ const wasmHex = '0x' + Buffer.from(wasmTx.signablePayload()).toString('hex');
233
+ assert_1.default.strictEqual(wasmHex, stripCompactPrefix(legacyHex), 'Signing payload should match');
234
+ });
235
+ });
236
+ // ===========================================================================
237
+ // Batch Transaction Tests
238
+ // ===========================================================================
239
+ describe('Batch Transactions', function () {
240
+ it('should produce identical signing payload for batch of transfers', async function () {
241
+ const to1 = fixtures_1.accounts.account2.address;
242
+ const to2 = fixtures_1.accounts.account3.address;
243
+ const amount1 = '1000000000000';
244
+ const amount2 = '2000000000000';
245
+ // Legacy batch requires raw call hex for each sub-call
246
+ const factory = new transactionBuilderFactory_1.TransactionBuilderFactory(coin);
247
+ // Build individual transfers to get their call data for the legacy batch
248
+ const t1 = factory.getTransferBuilder();
249
+ t1.sender({ address: fixtures_1.accounts.account1.address })
250
+ .to({ address: to1 })
251
+ .amount(amount1)
252
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
253
+ .referenceBlock(fixtures_1.westendBlock.hash)
254
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
255
+ const tx1 = await t1.build();
256
+ const t2 = factory.getTransferBuilder();
257
+ t2.sender({ address: fixtures_1.accounts.account1.address })
258
+ .to({ address: to2 })
259
+ .amount(amount2)
260
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
261
+ .referenceBlock(fixtures_1.westendBlock.hash)
262
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
263
+ const tx2 = await t2.build();
264
+ // Extract call data from legacy signing payload for batch construction.
265
+ // Legacy toBroadcastFormat() for unsigned txs returns the signing payload
266
+ // which starts with a compact-length-prefixed call.
267
+ function extractCallFromSigningPayload(signingPayload) {
268
+ const hexData = signingPayload.startsWith('0x') ? signingPayload.slice(2) : signingPayload;
269
+ const bytes = Buffer.from(hexData, 'hex');
270
+ // Decode compact length prefix to find where call data ends
271
+ const mode = bytes[0] & 0b11;
272
+ let callLength;
273
+ let offset;
274
+ if (mode === 0b00) {
275
+ callLength = bytes[0] >> 2;
276
+ offset = 1;
277
+ }
278
+ else if (mode === 0b01) {
279
+ callLength = (bytes[0] | (bytes[1] << 8)) >> 2;
280
+ offset = 2;
281
+ }
282
+ else if (mode === 0b10) {
283
+ callLength = (bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24)) >> 2;
284
+ offset = 4;
285
+ }
286
+ else {
287
+ throw new Error('Unsupported compact length mode');
288
+ }
289
+ return '0x' + bytes.slice(offset, offset + callLength).toString('hex');
290
+ }
291
+ const call1Hex = extractCallFromSigningPayload(tx1.toBroadcastFormat());
292
+ const call2Hex = extractCallFromSigningPayload(tx2.toBroadcastFormat());
293
+ const batchBuilder = factory.getBatchTransactionBuilder();
294
+ batchBuilder
295
+ .sender({ address: fixtures_1.accounts.account1.address })
296
+ .calls([call1Hex, call2Hex])
297
+ .atomic(true)
298
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
299
+ .referenceBlock(fixtures_1.westendBlock.hash)
300
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
301
+ const legacyTx = await batchBuilder.build();
302
+ const legacyHex = legacyTx.toBroadcastFormat();
303
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({
304
+ type: 'batch',
305
+ calls: [
306
+ { type: 'transfer', to: to1, amount: BigInt(amount1), keepAlive: true },
307
+ { type: 'transfer', to: to2, amount: BigInt(amount2), keepAlive: true },
308
+ ],
309
+ atomic: true,
310
+ }, createWasmContext());
311
+ const wasmHex = '0x' + Buffer.from(wasmTx.signablePayload()).toString('hex');
312
+ assert_1.default.strictEqual(wasmHex, stripCompactPrefix(legacyHex), 'Signing payload should match');
313
+ });
314
+ it('should produce identical signing payload for non-atomic batch', async function () {
315
+ const to = fixtures_1.accounts.account2.address;
316
+ const amount = '1000000000000';
317
+ const factory = new transactionBuilderFactory_1.TransactionBuilderFactory(coin);
318
+ const transferBuilder = factory.getTransferBuilder();
319
+ transferBuilder
320
+ .sender({ address: fixtures_1.accounts.account1.address })
321
+ .to({ address: to })
322
+ .amount(amount)
323
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
324
+ .referenceBlock(fixtures_1.westendBlock.hash)
325
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
326
+ const transferTx = await transferBuilder.build();
327
+ function extractCallFromSigningPayload(signingPayload) {
328
+ const hexData = signingPayload.startsWith('0x') ? signingPayload.slice(2) : signingPayload;
329
+ const bytes = Buffer.from(hexData, 'hex');
330
+ const mode = bytes[0] & 0b11;
331
+ let callLength;
332
+ let offset;
333
+ if (mode === 0b00) {
334
+ callLength = bytes[0] >> 2;
335
+ offset = 1;
336
+ }
337
+ else if (mode === 0b01) {
338
+ callLength = (bytes[0] | (bytes[1] << 8)) >> 2;
339
+ offset = 2;
340
+ }
341
+ else if (mode === 0b10) {
342
+ callLength = (bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24)) >> 2;
343
+ offset = 4;
344
+ }
345
+ else {
346
+ throw new Error('Unsupported compact length mode');
347
+ }
348
+ return '0x' + bytes.slice(offset, offset + callLength).toString('hex');
349
+ }
350
+ const callHex = extractCallFromSigningPayload(transferTx.toBroadcastFormat());
351
+ const batchBuilder = factory.getBatchTransactionBuilder();
352
+ batchBuilder
353
+ .sender({ address: fixtures_1.accounts.account1.address })
354
+ .calls([callHex])
355
+ .atomic(false)
356
+ .validity({ firstValid: fixtures_1.westendBlock.blockNumber, maxDuration: 2400 })
357
+ .referenceBlock(fixtures_1.westendBlock.hash)
358
+ .sequenceId({ name: 'Nonce', keyword: 'nonce', value: 0 });
359
+ const legacyTx = await batchBuilder.build();
360
+ const legacyHex = legacyTx.toBroadcastFormat();
361
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({
362
+ type: 'batch',
363
+ calls: [{ type: 'transfer', to, amount: BigInt(amount), keepAlive: true }],
364
+ atomic: false,
365
+ }, createWasmContext());
366
+ const wasmHex = '0x' + Buffer.from(wasmTx.signablePayload()).toString('hex');
367
+ assert_1.default.strictEqual(wasmHex, stripCompactPrefix(legacyHex), 'Signing payload should match');
368
+ });
369
+ });
370
+ // ===========================================================================
371
+ // Intent-based Transaction Building (sanity checks)
372
+ // ===========================================================================
373
+ describe('Intent-based Transaction Building', function () {
374
+ it('should build transfer from intent', async function () {
375
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'transfer', to: fixtures_1.accounts.account2.address, amount: 1000000000000n, keepAlive: true }, createWasmContext());
376
+ const serialized = wasmTx.toBroadcastFormat();
377
+ (0, assert_1.default)(serialized.startsWith('0x'), 'Should be hex encoded');
378
+ (0, assert_1.default)(serialized.length > 10, 'Should have content');
379
+ });
380
+ it('should build stake from intent', async function () {
381
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'stake', amount: 5000000000000n, payee: { type: 'staked' } }, createWasmContext());
382
+ (0, assert_1.default)(wasmTx.toBroadcastFormat().startsWith('0x'));
383
+ });
384
+ it('should build withdrawUnbonded from intent', async function () {
385
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'withdrawUnbonded', slashingSpans: 0 }, createWasmContext());
386
+ (0, assert_1.default)(wasmTx.toBroadcastFormat().startsWith('0x'));
387
+ });
388
+ it('should build chill from intent', async function () {
389
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'chill' }, createWasmContext());
390
+ (0, assert_1.default)(wasmTx.toBroadcastFormat().startsWith('0x'));
391
+ });
392
+ it('should build addProxy from intent', async function () {
393
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({ type: 'addProxy', delegate: fixtures_1.accounts.account2.address, proxyType: 'Any', delay: 0 }, createWasmContext());
394
+ (0, assert_1.default)(wasmTx.toBroadcastFormat().startsWith('0x'));
395
+ });
396
+ it('should build batch from intent', async function () {
397
+ const wasmTx = (0, wasm_dot_1.buildTransaction)({
398
+ type: 'batch',
399
+ calls: [
400
+ { type: 'transfer', to: fixtures_1.accounts.account2.address, amount: 1000000000000n, keepAlive: true },
401
+ { type: 'chill' },
402
+ ],
403
+ atomic: true,
404
+ }, createWasmContext());
405
+ (0, assert_1.default)(wasmTx.toBroadcastFormat().startsWith('0x'));
406
+ });
407
+ });
408
+ });
409
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FzbUJ1aWxkZXJCeXRlQ29tcGFyaXNvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC93YXNtQnVpbGRlckJ5dGVDb21wYXJpc29uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7R0FjRzs7Ozs7QUFFSCxvREFBNEI7QUFDNUIsaURBQTRDO0FBQzVDLHVGQUFvRjtBQUVwRiwrQ0FBZ0Q7QUFDaEQsMENBQXFEO0FBQ3JELGdFQUF3QztBQUV4QyxzQkFBc0I7QUFDdEIsOENBQXFGO0FBRXJGLFFBQVEsQ0FBQyx3Q0FBd0MsRUFBRTtJQUNqRCxNQUFNLElBQUksR0FBRyxlQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRS9CLG9FQUFvRTtJQUNwRSxNQUFNLFFBQVEsR0FBRyxlQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXpDLFNBQVMsaUJBQWlCLENBQUMsWUFBbUMsRUFBRTtRQUM5RCxPQUFPO1lBQ0wsTUFBTSxFQUFFLG1CQUFRLENBQUMsUUFBUSxDQUFDLE9BQU87WUFDakMsS0FBSyxFQUFFLENBQUM7WUFDUixHQUFHLEVBQUUsRUFBRTtZQUNQLFFBQVEsRUFBRSxRQUFvQjtZQUM5QixRQUFRLEVBQUU7Z0JBQ1IsVUFBVSxFQUFFLHVCQUFZLENBQUMsV0FBVztnQkFDcEMsV0FBVyxFQUFFLElBQUk7YUFDbEI7WUFDRCxjQUFjLEVBQUUsdUJBQVksQ0FBQyxJQUFJO1lBQ2pDLEdBQUcsU0FBUztTQUNiLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsU0FBUyxrQkFBa0IsQ0FBQyxHQUFXO1FBQ3JDLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUN2RCxNQUFN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QUUsUUFBUSxFQUFFLG1CQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFDckYsaUJBQWlCLEVBQUUsQ0FDcEIsQ0FBQztZQUNGLElBQUEsZ0JBQU0sRUFBQyxNQUFNLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN0RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRSxLQUFLO1lBQ3hDLE1BQU0sTUFBTSxHQUFHLElBQUEsMkJBQWdCLEVBQzdCO2dCQUNFLElBQUksRUFBRSxPQUFPO2dCQUNiLEtBQUssRUFBRTtvQkFDTCxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLG1CQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUU7b0JBQzVGLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRTtpQkFDbEI7Z0JBQ0QsTUFBTSxFQUFFLElBQUk7YUFDYixFQUNELGlCQUFpQixFQUFFLENBQ3BCLENBQUM7WUFDRixJQUFBLGdCQUFNLEVBQUMsTUFBTSxDQUFDLGlCQUFpQixFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDdEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBXQVNNIEJ1aWxkZXIgQnl0ZSBDb21wYXJpc29uIFRlc3RzXG4gKlxuICogQ29tcGFyZSBzZXJpYWxpemVkIG91dHB1dCBiZXR3ZWVuOlxuICogMS4gTGVnYWN5IGFwcHJvYWNoICh1c2luZyBAc3Vic3RyYXRlL3R4d3JhcHBlci1wb2xrYWRvdClcbiAqIDIuIFdBU00gYXBwcm9hY2ggKHVzaW5nIEBiaXRnby93YXNtLWRvdCBEb3RCdWlsZGVyKVxuICpcbiAqIEZvciB1bnNpZ25lZCB0cmFuc2FjdGlvbnMsIGxlZ2FjeSB0b0Jyb2FkY2FzdEZvcm1hdCgpIHJldHVybnMgdGhlIHNpZ25pbmcgcGF5bG9hZFxuICogKHZpYSBjb25zdHJ1Y3Quc2lnbmluZ1BheWxvYWQpLiBXZSBjb21wYXJlIFdBU00gc2lnbmFibGVQYXlsb2FkKCkgYWdhaW5zdCBpdC5cbiAqXG4gKiBGb3JtYXQgZGlmZmVyZW5jZTogdHh3cmFwcGVyIGVuY29kZXMgdGhlIGNhbGwgYXMgYEJ5dGVzYCAoVmVjPHU4Pikgd2hpY2ggaW5jbHVkZXNcbiAqIGEgU0NBTEUgY29tcGFjdC1sZW5ndGggcHJlZml4LiBzdWJ4dCBlbmNvZGVzIGl0IGFzIHJhdyBgQ2FsbGAgKG5vIHByZWZpeCkuXG4gKiBXZSBzdHJpcCB0aGlzIHByZWZpeCBmcm9tIHRoZSBsZWdhY3kgc2lkZSBiZWZvcmUgY29tcGFyaW5nLCBzaW5jZSB0aGUgYWN0dWFsXG4gKiBjYWxsIGRhdGEsIGVyYSwgbm9uY2UsIHRpcCwgYW5kIGNoYWluIGNvbnRleHQgYXJlIGlkZW50aWNhbC5cbiAqL1xuXG5pbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSB9IGZyb20gJy4uLy4uL3NyYy9saWIvdHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeSc7XG5pbXBvcnQgeyBUcmFuc2ZlckJ1aWxkZXIgfSBmcm9tICcuLi8uLi9zcmMvbGliL3RyYW5zZmVyQnVpbGRlcic7XG5pbXBvcnQgeyBQcm94eVR5cGUgfSBmcm9tICcuLi8uLi9zcmMvbGliL2lmYWNlJztcbmltcG9ydCB7IGFjY291bnRzLCB3ZXN0ZW5kQmxvY2sgfSBmcm9tICcuLi9maXh0dXJlcyc7XG5pbXBvcnQgdXRpbHMgZnJvbSAnLi4vLi4vc3JjL2xpYi91dGlscyc7XG5cbi8vIEltcG9ydCBXQVNNIGJ1aWxkZXJcbmltcG9ydCB7IGJ1aWxkVHJhbnNhY3Rpb24sIHR5cGUgQnVpbGRDb250ZXh0LCB0eXBlIE1hdGVyaWFsIH0gZnJvbSAnQGJpdGdvL3dhc20tZG90JztcblxuZGVzY3JpYmUoJ1dBU00gdnMgTGVnYWN5IEJ1aWxkZXIgQnl0ZSBDb21wYXJpc29uJywgZnVuY3Rpb24gKCkge1xuICBjb25zdCBjb2luID0gY29pbnMuZ2V0KCd0ZG90Jyk7XG5cbiAgLy8gR2V0IG1hdGVyaWFsIGZyb20gdXRpbHMgdG8gZW5zdXJlIHNhbWUgbWV0YWRhdGEgYXMgbGVnYWN5IGJ1aWxkZXJcbiAgY29uc3QgbWF0ZXJpYWwgPSB1dGlscy5nZXRNYXRlcmlhbChjb2luKTtcblxuICBmdW5jdGlvbiBjcmVhdGVXYXNtQ29udGV4dChvdmVycmlkZXM6IFBhcnRpYWw8QnVpbGRDb250ZXh0PiA9IHt9KTogQnVpbGRDb250ZXh0IHtcbiAgICByZXR1cm4ge1xuICAgICAgc2VuZGVyOiBhY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzLFxuICAgICAgbm9uY2U6IDAsXG4gICAgICB0aXA6IDBuLFxuICAgICAgbWF0ZXJpYWw6IG1hdGVyaWFsIGFzIE1hdGVyaWFsLFxuICAgICAgdmFsaWRpdHk6IHtcbiAgICAgICAgZmlyc3RWYWxpZDogd2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLFxuICAgICAgICBtYXhEdXJhdGlvbjogMjQwMCxcbiAgICAgIH0sXG4gICAgICByZWZlcmVuY2VCbG9jazogd2VzdGVuZEJsb2NrLmhhc2gsXG4gICAgICAuLi5vdmVycmlkZXMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdHJpcCBTQ0FMRSBjb21wYWN0LWxlbmd0aCBwcmVmaXggZnJvbSB0aGUgbGVnYWN5IHNpZ25pbmcgcGF5bG9hZC5cbiAgICpcbiAgICogTGVnYWN5ICh0eHdyYXBwZXIpIGVuY29kZXMgdGhlIGNhbGwgYXMgYEJ5dGVzYCB0eXBlLCB3aGljaCBhZGRzIGEgY29tcGFjdC1sZW5ndGhcbiAgICogcHJlZml4LiBzdWJ4dCBlbmNvZGVzIGl0IGFzIHJhdyBgQ2FsbGAgKG5vIHByZWZpeCkuIEJvdGggcHJvZHVjZSBpZGVudGljYWxcbiAgICogY2FsbCBkYXRhICsgZXJhICsgbm9uY2UgKyB0aXAgKyBjaGFpbiBjb250ZXh0IGFmdGVyIHRoaXMgcHJlZml4LlxuICAgKi9cbiAgZnVuY3Rpb24gc3RyaXBDb21wYWN0UHJlZml4KGhleDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBkYXRhID0gaGV4LnN0YXJ0c1dpdGgoJzB4JykgPyBoZXguc2xpY2UoMikgOiBoZXg7XG4gICAgY29uc3QgYnl0ZXMgPSBCdWZmZXIuZnJvbShkYXRhLCAnaGV4Jyk7XG4gICAgY29uc3QgbW9kZSA9IGJ5dGVzWzBdICYgMGIxMTtcbiAgICBsZXQgb2Zmc2V0OiBudW1iZXI7XG4gICAgaWYgKG1vZGUgPT09IDBiMDApIG9mZnNldCA9IDE7XG4gICAgZWxzZSBpZiAobW9kZSA9PT0gMGIwMSkgb2Zmc2V0ID0gMjtcbiAgICBlbHNlIGlmIChtb2RlID09PSAwYjEwKSBvZmZzZXQgPSA0O1xuICAgIGVsc2UgdGhyb3cgbmV3IEVycm9yKCdCaWcgY29tcGFjdCBub3Qgc3VwcG9ydGVkJyk7XG4gICAgcmV0dXJuICcweCcgKyBieXRlcy5zbGljZShvZmZzZXQpLnRvU3RyaW5nKCdoZXgnKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBUcmFuc2ZlciBUcmFuc2FjdGlvbiBUZXN0c1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgZGVzY3JpYmUoJ1RyYW5zZmVyIFRyYW5zYWN0aW9ucycsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgaWRlbnRpY2FsIHNpZ25pbmcgcGF5bG9hZCBmb3IgdHJhbnNmZXInLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0byA9IGFjY291bnRzLmFjY291bnQyLmFkZHJlc3M7XG4gICAgICBjb25zdCBhbW91bnQgPSAnMTAwMDAwMDAwMDAwMCc7IC8vIDEgRE9UXG5cbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2luKTtcbiAgICAgIGNvbnN0IGxlZ2FjeUJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpIGFzIFRyYW5zZmVyQnVpbGRlcjtcblxuICAgICAgbGVnYWN5QnVpbGRlclxuICAgICAgICAuc2VuZGVyKHsgYWRkcmVzczogYWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcyB9KVxuICAgICAgICAudG8oeyBhZGRyZXNzOiB0byB9KVxuICAgICAgICAuYW1vdW50KGFtb3VudClcbiAgICAgICAgLnZhbGlkaXR5KHsgZmlyc3RWYWxpZDogd2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLCBtYXhEdXJhdGlvbjogMjQwMCB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sod2VzdGVuZEJsb2NrLmhhc2gpXG4gICAgICAgIC5zZXF1ZW5jZUlkKHsgbmFtZTogJ05vbmNlJywga2V5d29yZDogJ25vbmNlJywgdmFsdWU6IDAgfSk7XG5cbiAgICAgIGNvbnN0IGxlZ2FjeVR4ID0gYXdhaXQgbGVnYWN5QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgbGVnYWN5SGV4ID0gbGVnYWN5VHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgY29uc3Qgd2FzbVR4ID0gYnVpbGRUcmFuc2FjdGlvbihcbiAgICAgICAgeyB0eXBlOiAndHJhbnNmZXInLCB0bywgYW1vdW50OiBCaWdJbnQoYW1vdW50KSwga2VlcEFsaXZlOiB0cnVlIH0sXG4gICAgICAgIGNyZWF0ZVdhc21Db250ZXh0KClcbiAgICAgICk7XG4gICAgICBjb25zdCB3YXNtSGV4ID0gJzB4JyArIEJ1ZmZlci5mcm9tKHdhc21UeC5zaWduYWJsZVBheWxvYWQoKSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwod2FzbUhleCwgc3RyaXBDb21wYWN0UHJlZml4KGxlZ2FjeUhleCksICdTaWduaW5nIHBheWxvYWQgc2hvdWxkIG1hdGNoJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgaWRlbnRpY2FsIHNpZ25pbmcgcGF5bG9hZCBmb3IgdHJhbnNmZXJLZWVwQWxpdmUgd2l0aCBkaWZmZXJlbnQgbm9uY2UnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0byA9IGFjY291bnRzLmFjY291bnQyLmFkZHJlc3M7XG4gICAgICBjb25zdCBhbW91bnQgPSAnNTAwMDAwMDAwMDAwMCc7IC8vIDUgRE9UXG5cbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2luKTtcbiAgICAgIGNvbnN0IGxlZ2FjeUJ1aWxkZXIgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpIGFzIFRyYW5zZmVyQnVpbGRlcjtcblxuICAgICAgbGVnYWN5QnVpbGRlclxuICAgICAgICAuc2VuZGVyKHsgYWRkcmVzczogYWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcyB9KVxuICAgICAgICAudG8oeyBhZGRyZXNzOiB0byB9KVxuICAgICAgICAuYW1vdW50KGFtb3VudClcbiAgICAgICAgLnZhbGlkaXR5KHsgZmlyc3RWYWxpZDogd2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLCBtYXhEdXJhdGlvbjogMjQwMCB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sod2VzdGVuZEJsb2NrLmhhc2gpXG4gICAgICAgIC5zZXF1ZW5jZUlkKHsgbmFtZTogJ05vbmNlJywga2V5d29yZDogJ25vbmNlJywgdmFsdWU6IDUgfSk7XG5cbiAgICAgIGNvbnN0IGxlZ2FjeVR4ID0gYXdhaXQgbGVnYWN5QnVpbGRlci5idWlsZCgpO1xuICAgICAgY29uc3QgbGVnYWN5SGV4ID0gbGVnYWN5VHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcblxuICAgICAgY29uc3Qgd2FzbVR4ID0gYnVpbGRUcmFuc2FjdGlvbihcbiAgICAgICAgeyB0eXBlOiAndHJhbnNmZXInLCB0bywgYW1vdW50OiBCaWdJbnQoYW1vdW50KSwga2VlcEFsaXZlOiB0cnVlIH0sXG4gICAgICAgIGNyZWF0ZVdhc21Db250ZXh0KHsgbm9uY2U6IDUgfSlcbiAgICAgICk7XG4gICAgICBjb25zdCB3YXNtSGV4ID0gJzB4JyArIEJ1ZmZlci5mcm9tKHdhc21UeC5zaWduYWJsZVBheWxvYWQoKSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwod2FzbUhleCwgc3RyaXBDb21wYWN0UHJlZml4KGxlZ2FjeUhleCksICdTaWduaW5nIHBheWxvYWQgc2hvdWxkIG1hdGNoJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBTdGFraW5nIFRyYW5zYWN0aW9uIFRlc3RzXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBkZXNjcmliZSgnU3Rha2luZyBUcmFuc2FjdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGlkZW50aWNhbCBzaWduaW5nIHBheWxvYWQgZm9yIHN0YWtpbmcgYm9uZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFtb3VudCA9ICcxMDAwMDAwMDAwMDAwMCc7IC8vIDEwIERPVFxuXG4gICAgICBjb25zdCBmYWN0b3J5ID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbik7XG4gICAgICBjb25zdCBsZWdhY3lCdWlsZGVyID0gZmFjdG9yeS5nZXRTdGFraW5nQnVpbGRlcigpO1xuXG4gICAgICBsZWdhY3lCdWlsZGVyXG4gICAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiBhY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzIH0pXG4gICAgICAgIC5hbW91bnQoYW1vdW50KVxuICAgICAgICAucGF5ZWUoJ1N0YWtlZCcpXG4gICAgICAgIC52YWxpZGl0eSh7IGZpcnN0VmFsaWQ6IHdlc3RlbmRCbG9jay5ibG9ja051bWJlciwgbWF4RHVyYXRpb246IDI0MDAgfSlcbiAgICAgICAgLnJlZmVyZW5jZUJsb2NrKHdlc3RlbmRCbG9jay5oYXNoKVxuICAgICAgICAuc2VxdWVuY2VJZCh7IG5hbWU6ICdOb25jZScsIGtleXdvcmQ6ICdub25jZScsIHZhbHVlOiAwIH0pO1xuXG4gICAgICBjb25zdCBsZWdhY3lUeCA9IGF3YWl0IGxlZ2FjeUJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IGxlZ2FjeUhleCA9IGxlZ2FjeVR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGNvbnN0IHdhc21UeCA9IGJ1aWxkVHJhbnNhY3Rpb24oXG4gICAgICAgIHsgdHlwZTogJ3N0YWtlJywgYW1vdW50OiBCaWdJbnQoYW1vdW50KSwgcGF5ZWU6IHsgdHlwZTogJ3N0YWtlZCcgfSB9LFxuICAgICAgICBjcmVhdGVXYXNtQ29udGV4dCgpXG4gICAgICApO1xuICAgICAgY29uc3Qgd2FzbUhleCA9ICcweCcgKyBCdWZmZXIuZnJvbSh3YXNtVHguc2lnbmFibGVQYXlsb2FkKCkpLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHdhc21IZXgsIHN0cmlwQ29tcGFjdFByZWZpeChsZWdhY3lIZXgpLCAnU2lnbmluZyBwYXlsb2FkIHNob3VsZCBtYXRjaCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGlkZW50aWNhbCBzaWduaW5nIHBheWxvYWQgZm9yIHN0YWtpbmcgYm9uZCB3aXRoIFN0YXNoIHBheWVlJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYW1vdW50ID0gJzIwMDAwMDAwMDAwMDAwJzsgLy8gMjAgRE9UXG5cbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2luKTtcbiAgICAgIGNvbnN0IGxlZ2FjeUJ1aWxkZXIgPSBmYWN0b3J5LmdldFN0YWtpbmdCdWlsZGVyKCk7XG5cbiAgICAgIGxlZ2FjeUJ1aWxkZXJcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IGFjY291bnRzLmFjY291bnQxLmFkZHJlc3MgfSlcbiAgICAgICAgLmFtb3VudChhbW91bnQpXG4gICAgICAgIC5wYXllZSgnU3Rhc2gnKVxuICAgICAgICAudmFsaWRpdHkoeyBmaXJzdFZhbGlkOiB3ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsIG1heER1cmF0aW9uOiAyNDAwIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh3ZXN0ZW5kQmxvY2suaGFzaClcbiAgICAgICAgLnNlcXVlbmNlSWQoeyBuYW1lOiAnTm9uY2UnLCBrZXl3b3JkOiAnbm9uY2UnLCB2YWx1ZTogMCB9KTtcblxuICAgICAgY29uc3QgbGVnYWN5VHggPSBhd2FpdCBsZWdhY3lCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCBsZWdhY3lIZXggPSBsZWdhY3lUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBjb25zdCB3YXNtVHggPSBidWlsZFRyYW5zYWN0aW9uKFxuICAgICAgICB7IHR5cGU6ICdzdGFrZScsIGFtb3VudDogQmlnSW50KGFtb3VudCksIHBheWVlOiB7IHR5cGU6ICdzdGFzaCcgfSB9LFxuICAgICAgICBjcmVhdGVXYXNtQ29udGV4dCgpXG4gICAgICApO1xuICAgICAgY29uc3Qgd2FzbUhleCA9ICcweCcgKyBCdWZmZXIuZnJvbSh3YXNtVHguc2lnbmFibGVQYXlsb2FkKCkpLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHdhc21IZXgsIHN0cmlwQ29tcGFjdFByZWZpeChsZWdhY3lIZXgpLCAnU2lnbmluZyBwYXlsb2FkIHNob3VsZCBtYXRjaCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGlkZW50aWNhbCBzaWduaW5nIHBheWxvYWQgZm9yIHVuc3Rha2UgKHVuYm9uZCknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhbW91bnQgPSAnNTAwMDAwMDAwMDAwMCc7IC8vIDUgRE9UXG5cbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2luKTtcbiAgICAgIGNvbnN0IGxlZ2FjeUJ1aWxkZXIgPSBmYWN0b3J5LmdldFVuc3Rha2VCdWlsZGVyKCk7XG5cbiAgICAgIGxlZ2FjeUJ1aWxkZXJcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IGFjY291bnRzLmFjY291bnQxLmFkZHJlc3MgfSlcbiAgICAgICAgLmFtb3VudChhbW91bnQpXG4gICAgICAgIC52YWxpZGl0eSh7IGZpcnN0VmFsaWQ6IHdlc3RlbmRCbG9jay5ibG9ja051bWJlciwgbWF4RHVyYXRpb246IDI0MDAgfSlcbiAgICAgICAgLnJlZmVyZW5jZUJsb2NrKHdlc3RlbmRCbG9jay5oYXNoKVxuICAgICAgICAuc2VxdWVuY2VJZCh7IG5hbWU6ICdOb25jZScsIGtleXdvcmQ6ICdub25jZScsIHZhbHVlOiAwIH0pO1xuXG4gICAgICBjb25zdCBsZWdhY3lUeCA9IGF3YWl0IGxlZ2FjeUJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IGxlZ2FjeUhleCA9IGxlZ2FjeVR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGNvbnN0IHdhc21UeCA9IGJ1aWxkVHJhbnNhY3Rpb24oeyB0eXBlOiAndW5zdGFrZScsIGFtb3VudDogQmlnSW50KGFtb3VudCkgfSwgY3JlYXRlV2FzbUNvbnRleHQoKSk7XG4gICAgICBjb25zdCB3YXNtSGV4ID0gJzB4JyArIEJ1ZmZlci5mcm9tKHdhc21UeC5zaWduYWJsZVBheWxvYWQoKSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwod2FzbUhleCwgc3RyaXBDb21wYWN0UHJlZml4KGxlZ2FjeUhleCksICdTaWduaW5nIHBheWxvYWQgc2hvdWxkIG1hdGNoJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgaWRlbnRpY2FsIHNpZ25pbmcgcGF5bG9hZCBmb3Igd2l0aGRyYXdVbmJvbmRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNsYXNoaW5nU3BhbnMgPSAwO1xuXG4gICAgICBjb25zdCBmYWN0b3J5ID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbik7XG4gICAgICBjb25zdCBsZWdhY3lCdWlsZGVyID0gZmFjdG9yeS5nZXRXaXRoZHJhd1Vuc3Rha2VkQnVpbGRlcigpO1xuXG4gICAgICBsZWdhY3lCdWlsZGVyXG4gICAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiBhY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzIH0pXG4gICAgICAgIC5zbGFzaGluZ1NwYW5zKHNsYXNoaW5nU3BhbnMpXG4gICAgICAgIC52YWxpZGl0eSh7IGZpcnN0VmFsaWQ6IHdlc3RlbmRCbG9jay5ibG9ja051bWJlciwgbWF4RHVyYXRpb246IDI0MDAgfSlcbiAgICAgICAgLnJlZmVyZW5jZUJsb2NrKHdlc3RlbmRCbG9jay5oYXNoKVxuICAgICAgICAuc2VxdWVuY2VJZCh7IG5hbWU6ICdOb25jZScsIGtleXdvcmQ6ICdub25jZScsIHZhbHVlOiAwIH0pO1xuXG4gICAgICBjb25zdCBsZWdhY3lUeCA9IGF3YWl0IGxlZ2FjeUJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IGxlZ2FjeUhleCA9IGxlZ2FjeVR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGNvbnN0IHdhc21UeCA9IGJ1aWxkVHJhbnNhY3Rpb24oeyB0eXBlOiAnd2l0aGRyYXdVbmJvbmRlZCcsIHNsYXNoaW5nU3BhbnMgfSwgY3JlYXRlV2FzbUNvbnRleHQoKSk7XG4gICAgICBjb25zdCB3YXNtSGV4ID0gJzB4JyArIEJ1ZmZlci5mcm9tKHdhc21UeC5zaWduYWJsZVBheWxvYWQoKSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwod2FzbUhleCwgc3RyaXBDb21wYWN0UHJlZml4KGxlZ2FjeUhleCksICdTaWduaW5nIHBheWxvYWQgc2hvdWxkIG1hdGNoJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgaWRlbnRpY2FsIHNpZ25pbmcgcGF5bG9hZCBmb3IgY2hpbGwgKHVubm9taW5hdGUpJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZmFjdG9yeSA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW4pO1xuICAgICAgY29uc3QgbGVnYWN5QnVpbGRlciA9IGZhY3RvcnkuZ2V0VW5ub21pbmF0ZUJ1aWxkZXIoKTtcblxuICAgICAgbGVnYWN5QnVpbGRlclxuICAgICAgICAuc2VuZGVyKHsgYWRkcmVzczogYWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcyB9KVxuICAgICAgICAudmFsaWRpdHkoeyBmaXJzdFZhbGlkOiB3ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsIG1heER1cmF0aW9uOiAyNDAwIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh3ZXN0ZW5kQmxvY2suaGFzaClcbiAgICAgICAgLnNlcXVlbmNlSWQoeyBuYW1lOiAnTm9uY2UnLCBrZXl3b3JkOiAnbm9uY2UnLCB2YWx1ZTogMCB9KTtcblxuICAgICAgY29uc3QgbGVnYWN5VHggPSBhd2FpdCBsZWdhY3lCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCBsZWdhY3lIZXggPSBsZWdhY3lUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBjb25zdCB3YXNtVHggPSBidWlsZFRyYW5zYWN0aW9uKHsgdHlwZTogJ2NoaWxsJyB9LCBjcmVhdGVXYXNtQ29udGV4dCgpKTtcbiAgICAgIGNvbnN0IHdhc21IZXggPSAnMHgnICsgQnVmZmVyLmZyb20od2FzbVR4LnNpZ25hYmxlUGF5bG9hZCgpKS50b1N0cmluZygnaGV4Jyk7XG5cbiAgICAgIGFzc2VydC5zdHJpY3RFcXVhbCh3YXNtSGV4LCBzdHJpcENvbXBhY3RQcmVmaXgobGVnYWN5SGV4KSwgJ1NpZ25pbmcgcGF5bG9hZCBzaG91bGQgbWF0Y2gnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFByb3h5IFRyYW5zYWN0aW9uIFRlc3RzXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBkZXNjcmliZSgnUHJveHkgVHJhbnNhY3Rpb25zJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgcHJvZHVjZSBpZGVudGljYWwgc2lnbmluZyBwYXlsb2FkIGZvciBhZGRQcm94eScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRlbGVnYXRlID0gYWNjb3VudHMuYWNjb3VudDIuYWRkcmVzcztcblxuICAgICAgY29uc3QgZmFjdG9yeSA9IG5ldyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5KGNvaW4pO1xuICAgICAgY29uc3QgbGVnYWN5QnVpbGRlciA9IGZhY3RvcnkuZ2V0QWRkcmVzc0luaXRpYWxpemF0aW9uQnVpbGRlcigpO1xuXG4gICAgICBsZWdhY3lCdWlsZGVyXG4gICAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiBhY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzIH0pXG4gICAgICAgIC5vd25lcih7IGFkZHJlc3M6IGRlbGVnYXRlIH0pXG4gICAgICAgIC50eXBlKFByb3h5VHlwZS5BTlkpXG4gICAgICAgIC5kZWxheSgnMCcpXG4gICAgICAgIC52YWxpZGl0eSh7IGZpcnN0VmFsaWQ6IHdlc3RlbmRCbG9jay5ibG9ja051bWJlciwgbWF4RHVyYXRpb246IDI0MDAgfSlcbiAgICAgICAgLnJlZmVyZW5jZUJsb2NrKHdlc3RlbmRCbG9jay5oYXNoKVxuICAgICAgICAuc2VxdWVuY2VJZCh7IG5hbWU6ICdOb25jZScsIGtleXdvcmQ6ICdub25jZScsIHZhbHVlOiAwIH0pO1xuXG4gICAgICBjb25zdCBsZWdhY3lUeCA9IGF3YWl0IGxlZ2FjeUJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IGxlZ2FjeUhleCA9IGxlZ2FjeVR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGNvbnN0IHdhc21UeCA9IGJ1aWxkVHJhbnNhY3Rpb24oeyB0eXBlOiAnYWRkUHJveHknLCBkZWxlZ2F0ZSwgcHJveHlUeXBlOiAnQW55JywgZGVsYXk6IDAgfSwgY3JlYXRlV2FzbUNvbnRleHQoKSk7XG4gICAgICBjb25zdCB3YXNtSGV4ID0gJzB4JyArIEJ1ZmZlci5mcm9tKHdhc21UeC5zaWduYWJsZVBheWxvYWQoKSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwod2FzbUhleCwgc3RyaXBDb21wYWN0UHJlZml4KGxlZ2FjeUhleCksICdTaWduaW5nIHBheWxvYWQgc2hvdWxkIG1hdGNoJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb2R1Y2UgaWRlbnRpY2FsIHNpZ25pbmcgcGF5bG9hZCBmb3IgYWRkUHJveHkgd2l0aCBTdGFraW5nIHR5cGUnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkZWxlZ2F0ZSA9IGFjY291bnRzLmFjY291bnQyLmFkZHJlc3M7XG5cbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2luKTtcbiAgICAgIGNvbnN0IGxlZ2FjeUJ1aWxkZXIgPSBmYWN0b3J5LmdldEFkZHJlc3NJbml0aWFsaXphdGlvbkJ1aWxkZXIoKTtcblxuICAgICAgbGVnYWN5QnVpbGRlclxuICAgICAgICAuc2VuZGVyKHsgYWRkcmVzczogYWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcyB9KVxuICAgICAgICAub3duZXIoeyBhZGRyZXNzOiBkZWxlZ2F0ZSB9KVxuICAgICAgICAudHlwZShQcm94eVR5cGUuU1RBS0lORylcbiAgICAgICAgLmRlbGF5KCcxMDAnKVxuICAgICAgICAudmFsaWRpdHkoeyBmaXJzdFZhbGlkOiB3ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsIG1heER1cmF0aW9uOiAyNDAwIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh3ZXN0ZW5kQmxvY2suaGFzaClcbiAgICAgICAgLnNlcXVlbmNlSWQoeyBuYW1lOiAnTm9uY2UnLCBrZXl3b3JkOiAnbm9uY2UnLCB2YWx1ZTogMCB9KTtcblxuICAgICAgY29uc3QgbGVnYWN5VHggPSBhd2FpdCBsZWdhY3lCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCBsZWdhY3lIZXggPSBsZWdhY3lUeC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBjb25zdCB3YXNtVHggPSBidWlsZFRyYW5zYWN0aW9uKFxuICAgICAgICB7IHR5cGU6ICdhZGRQcm94eScsIGRlbGVnYXRlLCBwcm94eVR5cGU6ICdTdGFraW5nJywgZGVsYXk6IDEwMCB9LFxuICAgICAgICBjcmVhdGVXYXNtQ29udGV4dCgpXG4gICAgICApO1xuICAgICAgY29uc3Qgd2FzbUhleCA9ICcweCcgKyBCdWZmZXIuZnJvbSh3YXNtVHguc2lnbmFibGVQYXlsb2FkKCkpLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHdhc21IZXgsIHN0cmlwQ29tcGFjdFByZWZpeChsZWdhY3lIZXgpLCAnU2lnbmluZyBwYXlsb2FkIHNob3VsZCBtYXRjaCcpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gQmF0Y2ggVHJhbnNhY3Rpb24gVGVzdHNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGRlc2NyaWJlKCdCYXRjaCBUcmFuc2FjdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGlkZW50aWNhbCBzaWduaW5nIHBheWxvYWQgZm9yIGJhdGNoIG9mIHRyYW5zZmVycycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHRvMSA9IGFjY291bnRzLmFjY291bnQyLmFkZHJlc3M7XG4gICAgICBjb25zdCB0bzIgPSBhY2NvdW50cy5hY2NvdW50My5hZGRyZXNzO1xuICAgICAgY29uc3QgYW1vdW50MSA9ICcxMDAwMDAwMDAwMDAwJztcbiAgICAgIGNvbnN0IGFtb3VudDIgPSAnMjAwMDAwMDAwMDAwMCc7XG5cbiAgICAgIC8vIExlZ2FjeSBiYXRjaCByZXF1aXJlcyByYXcgY2FsbCBoZXggZm9yIGVhY2ggc3ViLWNhbGxcbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2luKTtcblxuICAgICAgLy8gQnVpbGQgaW5kaXZpZHVhbCB0cmFuc2ZlcnMgdG8gZ2V0IHRoZWlyIGNhbGwgZGF0YSBmb3IgdGhlIGxlZ2FjeSBiYXRjaFxuICAgICAgY29uc3QgdDEgPSBmYWN0b3J5LmdldFRyYW5zZmVyQnVpbGRlcigpIGFzIFRyYW5zZmVyQnVpbGRlcjtcbiAgICAgIHQxLnNlbmRlcih7IGFkZHJlc3M6IGFjY291bnRzLmFjY291bnQxLmFkZHJlc3MgfSlcbiAgICAgICAgLnRvKHsgYWRkcmVzczogdG8xIH0pXG4gICAgICAgIC5hbW91bnQoYW1vdW50MSlcbiAgICAgICAgLnZhbGlkaXR5KHsgZmlyc3RWYWxpZDogd2VzdGVuZEJsb2NrLmJsb2NrTnVtYmVyLCBtYXhEdXJhdGlvbjogMjQwMCB9KVxuICAgICAgICAucmVmZXJlbmNlQmxvY2sod2VzdGVuZEJsb2NrLmhhc2gpXG4gICAgICAgIC5zZXF1ZW5jZUlkKHsgbmFtZTogJ05vbmNlJywga2V5d29yZDogJ25vbmNlJywgdmFsdWU6IDAgfSk7XG4gICAgICBjb25zdCB0eDEgPSBhd2FpdCB0MS5idWlsZCgpO1xuXG4gICAgICBjb25zdCB0MiA9IGZhY3RvcnkuZ2V0VHJhbnNmZXJCdWlsZGVyKCkgYXMgVHJhbnNmZXJCdWlsZGVyO1xuICAgICAgdDIuc2VuZGVyKHsgYWRkcmVzczogYWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcyB9KVxuICAgICAgICAudG8oeyBhZGRyZXNzOiB0bzIgfSlcbiAgICAgICAgLmFtb3VudChhbW91bnQyKVxuICAgICAgICAudmFsaWRpdHkoeyBmaXJzdFZhbGlkOiB3ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsIG1heER1cmF0aW9uOiAyNDAwIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh3ZXN0ZW5kQmxvY2suaGFzaClcbiAgICAgICAgLnNlcXVlbmNlSWQoeyBuYW1lOiAnTm9uY2UnLCBrZXl3b3JkOiAnbm9uY2UnLCB2YWx1ZTogMCB9KTtcbiAgICAgIGNvbnN0IHR4MiA9IGF3YWl0IHQyLmJ1aWxkKCk7XG5cbiAgICAgIC8vIEV4dHJhY3QgY2FsbCBkYXRhIGZyb20gbGVnYWN5IHNpZ25pbmcgcGF5bG9hZCBmb3IgYmF0Y2ggY29uc3RydWN0aW9uLlxuICAgICAgLy8gTGVnYWN5IHRvQnJvYWRjYXN0Rm9ybWF0KCkgZm9yIHVuc2lnbmVkIHR4cyByZXR1cm5zIHRoZSBzaWduaW5nIHBheWxvYWRcbiAgICAgIC8vIHdoaWNoIHN0YXJ0cyB3aXRoIGEgY29tcGFjdC1sZW5ndGgtcHJlZml4ZWQgY2FsbC5cbiAgICAgIGZ1bmN0aW9uIGV4dHJhY3RDYWxsRnJvbVNpZ25pbmdQYXlsb2FkKHNpZ25pbmdQYXlsb2FkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBoZXhEYXRhID0gc2lnbmluZ1BheWxvYWQuc3RhcnRzV2l0aCgnMHgnKSA/IHNpZ25pbmdQYXlsb2FkLnNsaWNlKDIpIDogc2lnbmluZ1BheWxvYWQ7XG4gICAgICAgIGNvbnN0IGJ5dGVzID0gQnVmZmVyLmZyb20oaGV4RGF0YSwgJ2hleCcpO1xuICAgICAgICAvLyBEZWNvZGUgY29tcGFjdCBsZW5ndGggcHJlZml4IHRvIGZpbmQgd2hlcmUgY2FsbCBkYXRhIGVuZHNcbiAgICAgICAgY29uc3QgbW9kZSA9IGJ5dGVzWzBdICYgMGIxMTtcbiAgICAgICAgbGV0IGNhbGxMZW5ndGg6IG51bWJlcjtcbiAgICAgICAgbGV0IG9mZnNldDogbnVtYmVyO1xuICAgICAgICBpZiAobW9kZSA9PT0gMGIwMCkge1xuICAgICAgICAgIGNhbGxMZW5ndGggPSBieXRlc1swXSA+PiAyO1xuICAgICAgICAgIG9mZnNldCA9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAobW9kZSA9PT0gMGIwMSkge1xuICAgICAgICAgIGNhbGxMZW5ndGggPSAoYnl0ZXNbMF0gfCAoYnl0ZXNbMV0gPDwgOCkpID4+IDI7XG4gICAgICAgICAgb2Zmc2V0ID0gMjtcbiAgICAgICAgfSBlbHNlIGlmIChtb2RlID09PSAwYjEwKSB7XG4gICAgICAgICAgY2FsbExlbmd0aCA9IChieXRlc1swXSB8IChieXRlc1sxXSA8PCA4KSB8IChieXRlc1syXSA8PCAxNikgfCAoYnl0ZXNbM10gPDwgMjQpKSA+PiAyO1xuICAgICAgICAgIG9mZnNldCA9IDQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjb21wYWN0IGxlbmd0aCBtb2RlJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICcweCcgKyBieXRlcy5zbGljZShvZmZzZXQsIG9mZnNldCArIGNhbGxMZW5ndGgpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2FsbDFIZXggPSBleHRyYWN0Q2FsbEZyb21TaWduaW5nUGF5bG9hZCh0eDEudG9Ccm9hZGNhc3RGb3JtYXQoKSk7XG4gICAgICBjb25zdCBjYWxsMkhleCA9IGV4dHJhY3RDYWxsRnJvbVNpZ25pbmdQYXlsb2FkKHR4Mi50b0Jyb2FkY2FzdEZvcm1hdCgpKTtcblxuICAgICAgY29uc3QgYmF0Y2hCdWlsZGVyID0gZmFjdG9yeS5nZXRCYXRjaFRyYW5zYWN0aW9uQnVpbGRlcigpO1xuICAgICAgYmF0Y2hCdWlsZGVyXG4gICAgICAgIC5zZW5kZXIoeyBhZGRyZXNzOiBhY2NvdW50cy5hY2NvdW50MS5hZGRyZXNzIH0pXG4gICAgICAgIC5jYWxscyhbY2FsbDFIZXgsIGNhbGwySGV4XSlcbiAgICAgICAgLmF0b21pYyh0cnVlKVxuICAgICAgICAudmFsaWRpdHkoeyBmaXJzdFZhbGlkOiB3ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsIG1heER1cmF0aW9uOiAyNDAwIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh3ZXN0ZW5kQmxvY2suaGFzaClcbiAgICAgICAgLnNlcXVlbmNlSWQoeyBuYW1lOiAnTm9uY2UnLCBrZXl3b3JkOiAnbm9uY2UnLCB2YWx1ZTogMCB9KTtcblxuICAgICAgY29uc3QgbGVnYWN5VHggPSBhd2FpdCBiYXRjaEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IGxlZ2FjeUhleCA9IGxlZ2FjeVR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGNvbnN0IHdhc21UeCA9IGJ1aWxkVHJhbnNhY3Rpb24oXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnYmF0Y2gnLFxuICAgICAgICAgIGNhbGxzOiBbXG4gICAgICAgICAgICB7IHR5cGU6ICd0cmFuc2ZlcicsIHRvOiB0bzEsIGFtb3VudDogQmlnSW50KGFtb3VudDEpLCBrZWVwQWxpdmU6IHRydWUgfSxcbiAgICAgICAgICAgIHsgdHlwZTogJ3RyYW5zZmVyJywgdG86IHRvMiwgYW1vdW50OiBCaWdJbnQoYW1vdW50MiksIGtlZXBBbGl2ZTogdHJ1ZSB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgYXRvbWljOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBjcmVhdGVXYXNtQ29udGV4dCgpXG4gICAgICApO1xuICAgICAgY29uc3Qgd2FzbUhleCA9ICcweCcgKyBCdWZmZXIuZnJvbSh3YXNtVHguc2lnbmFibGVQYXlsb2FkKCkpLnRvU3RyaW5nKCdoZXgnKTtcblxuICAgICAgYXNzZXJ0LnN0cmljdEVxdWFsKHdhc21IZXgsIHN0cmlwQ29tcGFjdFByZWZpeChsZWdhY3lIZXgpLCAnU2lnbmluZyBwYXlsb2FkIHNob3VsZCBtYXRjaCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGlkZW50aWNhbCBzaWduaW5nIHBheWxvYWQgZm9yIG5vbi1hdG9taWMgYmF0Y2gnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0byA9IGFjY291bnRzLmFjY291bnQyLmFkZHJlc3M7XG4gICAgICBjb25zdCBhbW91bnQgPSAnMTAwMDAwMDAwMDAwMCc7XG5cbiAgICAgIGNvbnN0IGZhY3RvcnkgPSBuZXcgVHJhbnNhY3Rpb25CdWlsZGVyRmFjdG9yeShjb2luKTtcblxuICAgICAgY29uc3QgdHJhbnNmZXJCdWlsZGVyID0gZmFjdG9yeS5nZXRUcmFuc2ZlckJ1aWxkZXIoKSBhcyBUcmFuc2ZlckJ1aWxkZXI7XG4gICAgICB0cmFuc2ZlckJ1aWxkZXJcbiAgICAgICAgLnNlbmRlcih7IGFkZHJlc3M6IGFjY291bnRzLmFjY291bnQxLmFkZHJlc3MgfSlcbiAgICAgICAgLnRvKHsgYWRkcmVzczogdG8gfSlcbiAgICAgICAgLmFtb3VudChhbW91bnQpXG4gICAgICAgIC52YWxpZGl0eSh7IGZpcnN0VmFsaWQ6IHdlc3RlbmRCbG9jay5ibG9ja051bWJlciwgbWF4RHVyYXRpb246IDI0MDAgfSlcbiAgICAgICAgLnJlZmVyZW5jZUJsb2NrKHdlc3RlbmRCbG9jay5oYXNoKVxuICAgICAgICAuc2VxdWVuY2VJZCh7IG5hbWU6ICdOb25jZScsIGtleXdvcmQ6ICdub25jZScsIHZhbHVlOiAwIH0pO1xuICAgICAgY29uc3QgdHJhbnNmZXJUeCA9IGF3YWl0IHRyYW5zZmVyQnVpbGRlci5idWlsZCgpO1xuXG4gICAgICBmdW5jdGlvbiBleHRyYWN0Q2FsbEZyb21TaWduaW5nUGF5bG9hZChzaWduaW5nUGF5bG9hZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgaGV4RGF0YSA9IHNpZ25pbmdQYXlsb2FkLnN0YXJ0c1dpdGgoJzB4JykgPyBzaWduaW5nUGF5bG9hZC5zbGljZSgyKSA6IHNpZ25pbmdQYXlsb2FkO1xuICAgICAgICBjb25zdCBieXRlcyA9IEJ1ZmZlci5mcm9tKGhleERhdGEsICdoZXgnKTtcbiAgICAgICAgY29uc3QgbW9kZSA9IGJ5dGVzWzBdICYgMGIxMTtcbiAgICAgICAgbGV0IGNhbGxMZW5ndGg6IG51bWJlcjtcbiAgICAgICAgbGV0IG9mZnNldDogbnVtYmVyO1xuICAgICAgICBpZiAobW9kZSA9PT0gMGIwMCkge1xuICAgICAgICAgIGNhbGxMZW5ndGggPSBieXRlc1swXSA+PiAyO1xuICAgICAgICAgIG9mZnNldCA9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAobW9kZSA9PT0gMGIwMSkge1xuICAgICAgICAgIGNhbGxMZW5ndGggPSAoYnl0ZXNbMF0gfCAoYnl0ZXNbMV0gPDwgOCkpID4+IDI7XG4gICAgICAgICAgb2Zmc2V0ID0gMjtcbiAgICAgICAgfSBlbHNlIGlmIChtb2RlID09PSAwYjEwKSB7XG4gICAgICAgICAgY2FsbExlbmd0aCA9IChieXRlc1swXSB8IChieXRlc1sxXSA8PCA4KSB8IChieXRlc1syXSA8PCAxNikgfCAoYnl0ZXNbM10gPDwgMjQpKSA+PiAyO1xuICAgICAgICAgIG9mZnNldCA9IDQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBjb21wYWN0IGxlbmd0aCBtb2RlJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICcweCcgKyBieXRlcy5zbGljZShvZmZzZXQsIG9mZnNldCArIGNhbGxMZW5ndGgpLnRvU3RyaW5nKCdoZXgnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2FsbEhleCA9IGV4dHJhY3RDYWxsRnJvbVNpZ25pbmdQYXlsb2FkKHRyYW5zZmVyVHgudG9Ccm9hZGNhc3RGb3JtYXQoKSk7XG5cbiAgICAgIGNvbnN0IGJhdGNoQnVpbGRlciA9IGZhY3RvcnkuZ2V0QmF0Y2hUcmFuc2FjdGlvbkJ1aWxkZXIoKTtcbiAgICAgIGJhdGNoQnVpbGRlclxuICAgICAgICAuc2VuZGVyKHsgYWRkcmVzczogYWNjb3VudHMuYWNjb3VudDEuYWRkcmVzcyB9KVxuICAgICAgICAuY2FsbHMoW2NhbGxIZXhdKVxuICAgICAgICAuYXRvbWljKGZhbHNlKVxuICAgICAgICAudmFsaWRpdHkoeyBmaXJzdFZhbGlkOiB3ZXN0ZW5kQmxvY2suYmxvY2tOdW1iZXIsIG1heER1cmF0aW9uOiAyNDAwIH0pXG4gICAgICAgIC5yZWZlcmVuY2VCbG9jayh3ZXN0ZW5kQmxvY2suaGFzaClcbiAgICAgICAgLnNlcXVlbmNlSWQoeyBuYW1lOiAnTm9uY2UnLCBrZXl3b3JkOiAnbm9uY2UnLCB2YWx1ZTogMCB9KTtcblxuICAgICAgY29uc3QgbGVnYWN5VHggPSBhd2FpdCBiYXRjaEJ1aWxkZXIuYnVpbGQoKTtcbiAgICAgIGNvbnN0IGxlZ2FjeUhleCA9IGxlZ2FjeVR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIGNvbnN0IHdhc21UeCA9IGJ1aWxkVHJhbnNhY3Rpb24oXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnYmF0Y2gnLFxuICAgICAgICAgIGNhbGxzOiBbeyB0eXBlOiAndHJhbnNmZXInLCB0bywgYW1vdW50OiBCaWdJbnQoYW1vdW50KSwga2VlcEFsaXZlOiB0cnVlIH1dLFxuICAgICAgICAgIGF0b21pYzogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIGNyZWF0ZVdhc21Db250ZXh0KClcbiAgICAgICk7XG4gICAgICBjb25zdCB3YXNtSGV4ID0gJzB4JyArIEJ1ZmZlci5mcm9tKHdhc21UeC5zaWduYWJsZVBheWxvYWQoKSkudG9TdHJpbmcoJ2hleCcpO1xuXG4gICAgICBhc3NlcnQuc3RyaWN0RXF1YWwod2FzbUhleCwgc3RyaXBDb21wYWN0UHJlZml4KGxlZ2FjeUhleCksICdTaWduaW5nIHBheWxvYWQgc2hvdWxkIG1hdGNoJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBJbnRlbnQtYmFzZWQgVHJhbnNhY3Rpb24gQnVpbGRpbmcgKHNhbml0eSBjaGVja3MpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBkZXNjcmliZSgnSW50ZW50LWJhc2VkIFRyYW5zYWN0aW9uIEJ1aWxkaW5nJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgYnVpbGQgdHJhbnNmZXIgZnJvbSBpbnRlbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YXNtVHggPSBidWlsZFRyYW5zYWN0aW9uKFxuICAgICAgICB7IHR5cGU6ICd0cmFuc2ZlcicsIHRvOiBhY2NvdW50cy5hY2NvdW50Mi5hZGRyZXNzLCBhbW91bnQ6IDEwMDAwMDAwMDAwMDBuLCBrZWVwQWxpdmU6IHRydWUgfSxcbiAgICAgICAgY3JlYXRlV2FzbUNvbnRleHQoKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWQgPSB3YXNtVHgudG9Ccm9hZGNhc3RGb3JtYXQoKTtcbiAgICAgIGFzc2VydChzZXJpYWxpemVkLnN0YXJ0c1dpdGgoJzB4JyksICdTaG91bGQgYmUgaGV4IGVuY29kZWQnKTtcbiAgICAgIGFzc2VydChzZXJpYWxpemVkLmxlbmd0aCA+IDEwLCAnU2hvdWxkIGhhdmUgY29udGVudCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCBzdGFrZSBmcm9tIGludGVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhc21UeCA9IGJ1aWxkVHJhbnNhY3Rpb24oXG4gICAgICAgIHsgdHlwZTogJ3N0YWtlJywgYW1vdW50OiA1MDAwMDAwMDAwMDAwbiwgcGF5ZWU6IHsgdHlwZTogJ3N0YWtlZCcgfSB9LFxuICAgICAgICBjcmVhdGVXYXNtQ29udGV4dCgpXG4gICAgICApO1xuICAgICAgYXNzZXJ0KHdhc21UeC50b0Jyb2FkY2FzdEZvcm1hdCgpLnN0YXJ0c1dpdGgoJzB4JykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCB3aXRoZHJhd1VuYm9uZGVkIGZyb20gaW50ZW50JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgd2FzbVR4ID0gYnVpbGRUcmFuc2FjdGlvbih7IHR5cGU6ICd3aXRoZHJhd1VuYm9uZGVkJywgc2xhc2hpbmdTcGFuczogMCB9LCBjcmVhdGVXYXNtQ29udGV4dCgpKTtcbiAgICAgIGFzc2VydCh3YXNtVHgudG9Ccm9hZGNhc3RGb3JtYXQoKS5zdGFydHNXaXRoKCcweCcpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgY2hpbGwgZnJvbSBpbnRlbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YXNtVHggPSBidWlsZFRyYW5zYWN0aW9uKHsgdHlwZTogJ2NoaWxsJyB9LCBjcmVhdGVXYXNtQ29udGV4dCgpKTtcbiAgICAgIGFzc2VydCh3YXNtVHgudG9Ccm9hZGNhc3RGb3JtYXQoKS5zdGFydHNXaXRoKCcweCcpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYnVpbGQgYWRkUHJveHkgZnJvbSBpbnRlbnQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB3YXNtVHggPSBidWlsZFRyYW5zYWN0aW9uKFxuICAgICAgICB7IHR5cGU6ICdhZGRQcm94eScsIGRlbGVnYXRlOiBhY2NvdW50cy5hY2NvdW50Mi5hZGRyZXNzLCBwcm94eVR5cGU6ICdBbnknLCBkZWxheTogMCB9LFxuICAgICAgICBjcmVhdGVXYXNtQ29udGV4dCgpXG4gICAgICApO1xuICAgICAgYXNzZXJ0KHdhc21UeC50b0Jyb2FkY2FzdEZvcm1hdCgpLnN0YXJ0c1dpdGgoJzB4JykpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBidWlsZCBiYXRjaCBmcm9tIGludGVudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHdhc21UeCA9IGJ1aWxkVHJhbnNhY3Rpb24oXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnYmF0Y2gnLFxuICAgICAgICAgIGNhbGxzOiBbXG4gICAgICAgICAgICB7IHR5cGU6ICd0cmFuc2ZlcicsIHRvOiBhY2NvdW50cy5hY2NvdW50Mi5hZGRyZXNzLCBhbW91bnQ6IDEwMDAwMDAwMDAwMDBuLCBrZWVwQWxpdmU6IHRydWUgfSxcbiAgICAgICAgICAgIHsgdHlwZTogJ2NoaWxsJyB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgYXRvbWljOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBjcmVhdGVXYXNtQ29udGV4dCgpXG4gICAgICApO1xuICAgICAgYXNzZXJ0KHdhc21UeC50b0Jyb2FkY2FzdEZvcm1hdCgpLnN0YXJ0c1dpdGgoJzB4JykpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19