@sochdb/sochdb 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +3349 -0
  3. package/_bin/aarch64-apple-darwin/libsochdb_storage.dylib +0 -0
  4. package/_bin/aarch64-apple-darwin/sochdb-bulk +0 -0
  5. package/_bin/aarch64-apple-darwin/sochdb-grpc-server +0 -0
  6. package/_bin/aarch64-apple-darwin/sochdb-server +0 -0
  7. package/_bin/x86_64-pc-windows-msvc/sochdb-bulk.exe +0 -0
  8. package/_bin/x86_64-pc-windows-msvc/sochdb-grpc-server.exe +0 -0
  9. package/_bin/x86_64-pc-windows-msvc/sochdb_storage.dll +0 -0
  10. package/_bin/x86_64-unknown-linux-gnu/libsochdb_storage.so +0 -0
  11. package/_bin/x86_64-unknown-linux-gnu/sochdb-bulk +0 -0
  12. package/_bin/x86_64-unknown-linux-gnu/sochdb-grpc-server +0 -0
  13. package/_bin/x86_64-unknown-linux-gnu/sochdb-server +0 -0
  14. package/bin/sochdb-bulk.js +80 -0
  15. package/bin/sochdb-grpc-server.js +80 -0
  16. package/bin/sochdb-server.js +84 -0
  17. package/dist/cjs/analytics.js +196 -0
  18. package/dist/cjs/database.js +929 -0
  19. package/dist/cjs/embedded/database.js +236 -0
  20. package/dist/cjs/embedded/ffi/bindings.js +113 -0
  21. package/dist/cjs/embedded/ffi/library-finder.js +135 -0
  22. package/dist/cjs/embedded/index.js +14 -0
  23. package/dist/cjs/embedded/transaction.js +172 -0
  24. package/dist/cjs/errors.js +71 -0
  25. package/dist/cjs/format.js +176 -0
  26. package/dist/cjs/grpc-client.js +328 -0
  27. package/dist/cjs/index.js +75 -0
  28. package/dist/cjs/ipc-client.js +504 -0
  29. package/dist/cjs/query.js +154 -0
  30. package/dist/cjs/server-manager.js +295 -0
  31. package/dist/cjs/sql-engine.js +874 -0
  32. package/dist/esm/analytics.js +196 -0
  33. package/dist/esm/database.js +931 -0
  34. package/dist/esm/embedded/database.js +239 -0
  35. package/dist/esm/embedded/ffi/bindings.js +142 -0
  36. package/dist/esm/embedded/ffi/library-finder.js +135 -0
  37. package/dist/esm/embedded/index.js +14 -0
  38. package/dist/esm/embedded/transaction.js +176 -0
  39. package/dist/esm/errors.js +71 -0
  40. package/dist/esm/format.js +179 -0
  41. package/dist/esm/grpc-client.js +333 -0
  42. package/dist/esm/index.js +75 -0
  43. package/dist/esm/ipc-client.js +505 -0
  44. package/dist/esm/query.js +159 -0
  45. package/dist/esm/server-manager.js +295 -0
  46. package/dist/esm/sql-engine.js +875 -0
  47. package/dist/types/analytics.d.ts +66 -0
  48. package/dist/types/analytics.d.ts.map +1 -0
  49. package/dist/types/database.d.ts +523 -0
  50. package/dist/types/database.d.ts.map +1 -0
  51. package/dist/types/embedded/database.d.ts +105 -0
  52. package/dist/types/embedded/database.d.ts.map +1 -0
  53. package/dist/types/embedded/ffi/bindings.d.ts +24 -0
  54. package/dist/types/embedded/ffi/bindings.d.ts.map +1 -0
  55. package/dist/types/embedded/ffi/library-finder.d.ts +17 -0
  56. package/dist/types/embedded/ffi/library-finder.d.ts.map +1 -0
  57. package/dist/types/embedded/index.d.ts +9 -0
  58. package/dist/types/embedded/index.d.ts.map +1 -0
  59. package/dist/types/embedded/transaction.d.ts +21 -0
  60. package/dist/types/embedded/transaction.d.ts.map +1 -0
  61. package/dist/types/errors.d.ts +36 -0
  62. package/dist/types/errors.d.ts.map +1 -0
  63. package/dist/types/format.d.ts +117 -0
  64. package/dist/types/format.d.ts.map +1 -0
  65. package/dist/types/grpc-client.d.ts +120 -0
  66. package/dist/types/grpc-client.d.ts.map +1 -0
  67. package/dist/types/index.d.ts +50 -0
  68. package/dist/types/index.d.ts.map +1 -0
  69. package/dist/types/ipc-client.d.ts +177 -0
  70. package/dist/types/ipc-client.d.ts.map +1 -0
  71. package/dist/types/query.d.ts +85 -0
  72. package/dist/types/query.d.ts.map +1 -0
  73. package/dist/types/server-manager.d.ts +29 -0
  74. package/dist/types/server-manager.d.ts.map +1 -0
  75. package/dist/types/sql-engine.d.ts +100 -0
  76. package/dist/types/sql-engine.d.ts.map +1 -0
  77. package/package.json +90 -0
  78. package/scripts/postinstall.js +50 -0
@@ -0,0 +1,504 @@
1
+ "use strict";
2
+ /**
3
+ * SochDB IPC Client
4
+ *
5
+ * Connects to a SochDB IPC server via Unix domain socket.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.IpcClient = exports.OpCode = void 0;
44
+ // Copyright 2025 Sushanth (https://github.com/sushanthpy)
45
+ //
46
+ // Licensed under the Apache License, Version 2.0 (the "License");
47
+ // you may not use this file except in compliance with the License.
48
+ // You may obtain a copy of the License at
49
+ //
50
+ // http://www.apache.org/licenses/LICENSE-2.0
51
+ const net = __importStar(require("net"));
52
+ const errors_1 = require("./errors");
53
+ const query_1 = require("./query");
54
+ /**
55
+ * Wire protocol opcodes.
56
+ */
57
+ exports.OpCode = {
58
+ // Client → Server (must match sochdb-storage/src/ipc_server.rs)
59
+ Put: 0x01,
60
+ Get: 0x02,
61
+ Delete: 0x03,
62
+ BeginTxn: 0x04,
63
+ CommitTxn: 0x05,
64
+ AbortTxn: 0x06,
65
+ Query: 0x07,
66
+ CreateTable: 0x08,
67
+ PutPath: 0x09,
68
+ GetPath: 0x0A,
69
+ Scan: 0x0B,
70
+ Checkpoint: 0x0C,
71
+ Stats: 0x0D,
72
+ Ping: 0x0E,
73
+ // Server → Client
74
+ OK: 0x80,
75
+ Error: 0x81,
76
+ Value: 0x82,
77
+ TxnId: 0x83,
78
+ Row: 0x84,
79
+ EndStream: 0x85,
80
+ StatsResp: 0x86,
81
+ Pong: 0x87,
82
+ };
83
+ // Internal OpCode map for backwards compatibility
84
+ const InternalOpCode = {
85
+ PUT: exports.OpCode.Put,
86
+ GET: exports.OpCode.Get,
87
+ DELETE: exports.OpCode.Delete,
88
+ BEGIN_TXN: exports.OpCode.BeginTxn,
89
+ COMMIT_TXN: exports.OpCode.CommitTxn,
90
+ ABORT_TXN: exports.OpCode.AbortTxn,
91
+ QUERY: exports.OpCode.Query,
92
+ PUT_PATH: exports.OpCode.PutPath,
93
+ GET_PATH: exports.OpCode.GetPath,
94
+ SCAN: exports.OpCode.Scan,
95
+ CHECKPOINT: exports.OpCode.Checkpoint,
96
+ STATS: exports.OpCode.Stats,
97
+ PING: exports.OpCode.Ping,
98
+ OK: exports.OpCode.OK,
99
+ ERROR: exports.OpCode.Error,
100
+ VALUE: exports.OpCode.Value,
101
+ TXN_ID: exports.OpCode.TxnId,
102
+ ROW: exports.OpCode.Row,
103
+ END_STREAM: exports.OpCode.EndStream,
104
+ STATS_RESP: exports.OpCode.StatsResp,
105
+ PONG: exports.OpCode.Pong,
106
+ };
107
+ const MAX_MESSAGE_SIZE = 16 * 1024 * 1024; // 16 MB
108
+ /**
109
+ * IPC Client for SochDB.
110
+ *
111
+ * Connects to a SochDB server via Unix domain socket.
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * import { IpcClient } from '@sushanth/sochdb';
116
+ *
117
+ * const client = await IpcClient.connect('/tmp/sochdb.sock');
118
+ *
119
+ * await client.put(Buffer.from('key'), Buffer.from('value'));
120
+ * const value = await client.get(Buffer.from('key'));
121
+ *
122
+ * await client.close();
123
+ * ```
124
+ */
125
+ class IpcClient {
126
+ constructor(config) {
127
+ this._socket = null;
128
+ this._pendingReads = [];
129
+ this._readBuffer = Buffer.alloc(0);
130
+ this._closed = false;
131
+ this._config = {
132
+ connectTimeout: 5000,
133
+ readTimeout: 30000,
134
+ ...config,
135
+ };
136
+ }
137
+ /**
138
+ * Connect to a SochDB IPC server.
139
+ *
140
+ * @param socketPath - Path to the Unix domain socket
141
+ * @returns A connected IpcClient instance
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * const client = await IpcClient.connect('/tmp/sochdb.sock');
146
+ * ```
147
+ */
148
+ static async connect(socketPath) {
149
+ const client = new IpcClient({ socketPath });
150
+ await client._connect();
151
+ return client;
152
+ }
153
+ async _connect() {
154
+ return new Promise((resolve, reject) => {
155
+ const socket = net.createConnection({ path: this._config.socketPath }, () => {
156
+ this._socket = socket;
157
+ resolve();
158
+ });
159
+ socket.setTimeout(this._config.connectTimeout);
160
+ socket.on('timeout', () => {
161
+ socket.destroy();
162
+ reject(new errors_1.ConnectionError('Connection timeout'));
163
+ });
164
+ socket.on('error', (err) => {
165
+ reject(new errors_1.ConnectionError(`Connection failed: ${err.message}`));
166
+ });
167
+ socket.on('data', (data) => {
168
+ this._readBuffer = Buffer.concat([this._readBuffer, data]);
169
+ this._processBuffer();
170
+ });
171
+ socket.on('close', () => {
172
+ this._closed = true;
173
+ for (const pending of this._pendingReads) {
174
+ pending.reject(new errors_1.ConnectionError('Connection closed'));
175
+ }
176
+ this._pendingReads = [];
177
+ });
178
+ });
179
+ }
180
+ _processBuffer() {
181
+ // Process complete messages from the buffer
182
+ while (this._readBuffer.length >= 5 && this._pendingReads.length > 0) {
183
+ const length = this._readBuffer.readUInt32LE(1);
184
+ const totalLength = 5 + length;
185
+ if (this._readBuffer.length >= totalLength) {
186
+ const message = this._readBuffer.subarray(0, totalLength);
187
+ this._readBuffer = this._readBuffer.subarray(totalLength);
188
+ const pending = this._pendingReads.shift();
189
+ if (pending) {
190
+ pending.resolve(message);
191
+ }
192
+ }
193
+ else {
194
+ break;
195
+ }
196
+ }
197
+ }
198
+ async _send(opcode, payload = Buffer.alloc(0)) {
199
+ if (this._closed || !this._socket) {
200
+ throw new errors_1.ConnectionError('Not connected');
201
+ }
202
+ // Encode message: opcode (1) + length (4 LE) + payload
203
+ const message = Buffer.alloc(5 + payload.length);
204
+ message.writeUInt8(opcode, 0);
205
+ message.writeUInt32LE(payload.length, 1);
206
+ payload.copy(message, 5);
207
+ return new Promise((resolve, reject) => {
208
+ this._pendingReads.push({ resolve, reject });
209
+ this._socket.write(message, (err) => {
210
+ if (err) {
211
+ this._pendingReads.pop();
212
+ reject(new errors_1.ConnectionError(`Write failed: ${err.message}`));
213
+ }
214
+ });
215
+ // Set timeout for response
216
+ setTimeout(() => {
217
+ const idx = this._pendingReads.findIndex((p) => p.resolve === resolve);
218
+ if (idx !== -1) {
219
+ this._pendingReads.splice(idx, 1);
220
+ reject(new errors_1.ConnectionError('Read timeout'));
221
+ }
222
+ }, this._config.readTimeout);
223
+ });
224
+ }
225
+ _parseResponse(response) {
226
+ const opcode = response.readUInt8(0);
227
+ const length = response.readUInt32LE(1);
228
+ const payload = response.subarray(5, 5 + length);
229
+ if (opcode === InternalOpCode.ERROR) {
230
+ throw new errors_1.ProtocolError(payload.toString('utf8'));
231
+ }
232
+ return { opcode, payload };
233
+ }
234
+ /**
235
+ * Encode a key for the wire protocol.
236
+ * @internal
237
+ */
238
+ static encodeKey(key) {
239
+ // Format: [length:4][op:1][key_len:4][key:...]
240
+ const msgLen = 1 + 4 + key.length;
241
+ const msg = Buffer.alloc(4 + msgLen);
242
+ msg.writeUInt32BE(msgLen, 0);
243
+ msg.writeUInt8(InternalOpCode.GET, 4);
244
+ msg.writeUInt32BE(key.length, 5);
245
+ key.copy(msg, 9);
246
+ return msg;
247
+ }
248
+ /**
249
+ * Encode a key-value pair for the wire protocol.
250
+ * @internal
251
+ */
252
+ static encodeKeyValue(key, value) {
253
+ // Format: [length:4][op:1][key_len:4][key:...][value_len:4][value:...]
254
+ const msgLen = 1 + 4 + key.length + 4 + value.length;
255
+ const msg = Buffer.alloc(4 + msgLen);
256
+ msg.writeUInt32BE(msgLen, 0);
257
+ msg.writeUInt8(InternalOpCode.PUT, 4);
258
+ msg.writeUInt32BE(key.length, 5);
259
+ key.copy(msg, 9);
260
+ msg.writeUInt32BE(value.length, 9 + key.length);
261
+ value.copy(msg, 13 + key.length);
262
+ return msg;
263
+ }
264
+ /**
265
+ * Get a value by key.
266
+ */
267
+ async get(key) {
268
+ const response = await this._send(InternalOpCode.GET, key);
269
+ const { opcode, payload } = this._parseResponse(response);
270
+ if (opcode === InternalOpCode.VALUE) {
271
+ // If payload is empty, the key doesn't exist
272
+ if (payload.length === 0) {
273
+ return null;
274
+ }
275
+ return payload;
276
+ }
277
+ return null;
278
+ }
279
+ /**
280
+ * Put a key-value pair.
281
+ */
282
+ async put(key, value) {
283
+ // Encode: key_len (4 LE) + key + value
284
+ const payload = Buffer.alloc(4 + key.length + value.length);
285
+ payload.writeUInt32LE(key.length, 0);
286
+ key.copy(payload, 4);
287
+ value.copy(payload, 4 + key.length);
288
+ const response = await this._send(InternalOpCode.PUT, payload);
289
+ this._parseResponse(response);
290
+ }
291
+ /**
292
+ * Delete a key.
293
+ */
294
+ async delete(key) {
295
+ const response = await this._send(InternalOpCode.DELETE, key);
296
+ this._parseResponse(response);
297
+ }
298
+ /**
299
+ * Get a value by path.
300
+ * Wire format: path_count(2 LE) + [path_len(2 LE) + path_segment]...
301
+ */
302
+ async getPath(path) {
303
+ // Encode path as single segment for now (could split on '/' for multi-segment)
304
+ const pathBuf = Buffer.from(path, 'utf8');
305
+ const payload = Buffer.alloc(2 + 2 + pathBuf.length);
306
+ payload.writeUInt16LE(1, 0); // path_count = 1
307
+ payload.writeUInt16LE(pathBuf.length, 2); // path_len
308
+ pathBuf.copy(payload, 4); // path
309
+ const response = await this._send(InternalOpCode.GET_PATH, payload);
310
+ const { opcode, payload: responsePayload } = this._parseResponse(response);
311
+ if (opcode === InternalOpCode.VALUE) {
312
+ // If payload is empty, the key doesn't exist
313
+ if (responsePayload.length === 0) {
314
+ return null;
315
+ }
316
+ return responsePayload;
317
+ }
318
+ return null;
319
+ }
320
+ /**
321
+ * Put a value at a path.
322
+ * Wire format: path_count(2 LE) + [path_len(2 LE) + path_segment]... + value
323
+ */
324
+ async putPath(path, value) {
325
+ const pathBuf = Buffer.from(path, 'utf8');
326
+ const payload = Buffer.alloc(2 + 2 + pathBuf.length + value.length);
327
+ payload.writeUInt16LE(1, 0); // path_count = 1
328
+ payload.writeUInt16LE(pathBuf.length, 2); // path_len
329
+ pathBuf.copy(payload, 4); // path
330
+ value.copy(payload, 4 + pathBuf.length); // value
331
+ const response = await this._send(InternalOpCode.PUT_PATH, payload);
332
+ this._parseResponse(response);
333
+ }
334
+ /**
335
+ * Execute a query and return TOON-formatted results.
336
+ *
337
+ * Wire format: path_len(2) + path + limit(4) + offset(4) + cols_count(2) + [col_len(2) + col]...
338
+ */
339
+ async query(pathPrefix, options) {
340
+ const opts = options || {};
341
+ const pathBuf = Buffer.from(pathPrefix, 'utf8');
342
+ const columns = opts.columns || [];
343
+ // Calculate payload size
344
+ let size = 2 + pathBuf.length + 4 + 4 + 2;
345
+ for (const col of columns) {
346
+ size += 2 + Buffer.byteLength(col, 'utf8');
347
+ }
348
+ const payload = Buffer.alloc(size);
349
+ let offset = 0;
350
+ // Path: path_len(2 LE) + path
351
+ payload.writeUInt16LE(pathBuf.length, offset);
352
+ offset += 2;
353
+ pathBuf.copy(payload, offset);
354
+ offset += pathBuf.length;
355
+ // Limit (4 LE) - 0 means no limit
356
+ payload.writeUInt32LE(opts.limit || 0, offset);
357
+ offset += 4;
358
+ // Offset (4 LE)
359
+ payload.writeUInt32LE(opts.offset || 0, offset);
360
+ offset += 4;
361
+ // Columns: count(2 LE) + [col_len(2 LE) + col]...
362
+ payload.writeUInt16LE(columns.length, offset);
363
+ offset += 2;
364
+ for (const col of columns) {
365
+ const colBuf = Buffer.from(col, 'utf8');
366
+ payload.writeUInt16LE(colBuf.length, offset);
367
+ offset += 2;
368
+ colBuf.copy(payload, offset);
369
+ offset += colBuf.length;
370
+ }
371
+ const response = await this._send(InternalOpCode.QUERY, payload);
372
+ const { payload: resultPayload } = this._parseResponse(response);
373
+ return resultPayload.toString('utf8');
374
+ }
375
+ /**
376
+ * Scan for keys with a prefix, returning key-value pairs.
377
+ * This is the preferred method for simple prefix-based iteration.
378
+ *
379
+ * Wire format: prefix string
380
+ * Response format: count(4 LE) + [key_len(2 LE) + key + val_len(4 LE) + val]...
381
+ */
382
+ async scan(prefix) {
383
+ const prefixBuf = Buffer.from(prefix, 'utf8');
384
+ const response = await this._send(InternalOpCode.SCAN, prefixBuf);
385
+ const { opcode, payload } = this._parseResponse(response);
386
+ if (opcode !== InternalOpCode.VALUE && opcode !== InternalOpCode.OK) {
387
+ throw new errors_1.ProtocolError(`Unexpected scan response opcode: 0x${opcode.toString(16)}`);
388
+ }
389
+ if (payload.length < 4) {
390
+ return []; // Empty result
391
+ }
392
+ // Parse response: count(4 LE) + [key_len(2 LE) + key + val_len(4 LE) + val]...
393
+ const count = payload.readUInt32LE(0);
394
+ const results = [];
395
+ let offset = 4;
396
+ for (let i = 0; i < count; i++) {
397
+ if (offset + 2 > payload.length) {
398
+ throw new errors_1.ProtocolError('Truncated scan response (key_len)');
399
+ }
400
+ const keyLen = payload.readUInt16LE(offset);
401
+ offset += 2;
402
+ if (offset + keyLen + 4 > payload.length) {
403
+ throw new errors_1.ProtocolError('Truncated scan response (key+val_len)');
404
+ }
405
+ const key = payload.subarray(offset, offset + keyLen);
406
+ offset += keyLen;
407
+ const valLen = payload.readUInt32LE(offset);
408
+ offset += 4;
409
+ if (offset + valLen > payload.length) {
410
+ throw new errors_1.ProtocolError('Truncated scan response (value)');
411
+ }
412
+ const value = payload.subarray(offset, offset + valLen);
413
+ offset += valLen;
414
+ results.push({ key, value });
415
+ }
416
+ return results;
417
+ }
418
+ /**
419
+ * Create a query builder.
420
+ */
421
+ queryBuilder(pathPrefix) {
422
+ return new query_1.Query(this, pathPrefix);
423
+ }
424
+ /**
425
+ * Begin a new transaction.
426
+ */
427
+ async beginTransaction() {
428
+ const response = await this._send(InternalOpCode.BEGIN_TXN);
429
+ const { opcode, payload } = this._parseResponse(response);
430
+ if (opcode === InternalOpCode.TXN_ID) {
431
+ return payload.readBigUInt64LE(0);
432
+ }
433
+ throw new errors_1.TransactionError('Failed to begin transaction');
434
+ }
435
+ /**
436
+ * Commit a transaction.
437
+ */
438
+ async commitTransaction(txnId) {
439
+ const payload = Buffer.alloc(8);
440
+ payload.writeBigUInt64LE(txnId, 0);
441
+ const response = await this._send(InternalOpCode.COMMIT_TXN, payload);
442
+ this._parseResponse(response);
443
+ }
444
+ /**
445
+ * Abort a transaction.
446
+ */
447
+ async abortTransaction(txnId) {
448
+ const payload = Buffer.alloc(8);
449
+ payload.writeBigUInt64LE(txnId, 0);
450
+ const response = await this._send(InternalOpCode.ABORT_TXN, payload);
451
+ this._parseResponse(response);
452
+ }
453
+ /**
454
+ * Force a checkpoint.
455
+ */
456
+ async checkpoint() {
457
+ const response = await this._send(InternalOpCode.CHECKPOINT);
458
+ this._parseResponse(response);
459
+ }
460
+ /**
461
+ * Get storage statistics.
462
+ */
463
+ async stats() {
464
+ const response = await this._send(InternalOpCode.STATS);
465
+ const { payload } = this._parseResponse(response);
466
+ const json = JSON.parse(payload.toString('utf8'));
467
+ return {
468
+ memtableSizeBytes: json.memtable_size_bytes || 0,
469
+ walSizeBytes: json.wal_size_bytes || 0,
470
+ activeTransactions: json.active_transactions || 0,
471
+ };
472
+ }
473
+ /**
474
+ * Ping the server.
475
+ */
476
+ async ping() {
477
+ try {
478
+ const response = await this._send(InternalOpCode.PING);
479
+ const { opcode } = this._parseResponse(response);
480
+ return opcode === InternalOpCode.PONG;
481
+ }
482
+ catch {
483
+ return false;
484
+ }
485
+ }
486
+ /**
487
+ * Close the connection.
488
+ */
489
+ async close() {
490
+ if (this._closed)
491
+ return;
492
+ this._closed = true;
493
+ if (this._socket) {
494
+ return new Promise((resolve) => {
495
+ this._socket.end(() => {
496
+ this._socket = null;
497
+ resolve();
498
+ });
499
+ });
500
+ }
501
+ }
502
+ }
503
+ exports.IpcClient = IpcClient;
504
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXBjLWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9pcGMtY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7O0dBTUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVILDBEQUEwRDtBQUMxRCxFQUFFO0FBQ0Ysa0VBQWtFO0FBQ2xFLG1FQUFtRTtBQUNuRSwwQ0FBMEM7QUFDMUMsRUFBRTtBQUNGLGlEQUFpRDtBQUVqRCx5Q0FBMkI7QUFDM0IscUNBQTRFO0FBQzVFLG1DQUFnQztBQUVoQzs7R0FFRztBQUNVLFFBQUEsTUFBTSxHQUFHO0lBQ3BCLGdFQUFnRTtJQUNoRSxHQUFHLEVBQUUsSUFBSTtJQUNULEdBQUcsRUFBRSxJQUFJO0lBQ1QsTUFBTSxFQUFFLElBQUk7SUFDWixRQUFRLEVBQUUsSUFBSTtJQUNkLFNBQVMsRUFBRSxJQUFJO0lBQ2YsUUFBUSxFQUFFLElBQUk7SUFDZCxLQUFLLEVBQUUsSUFBSTtJQUNYLFdBQVcsRUFBRSxJQUFJO0lBQ2pCLE9BQU8sRUFBRSxJQUFJO0lBQ2IsT0FBTyxFQUFFLElBQUk7SUFDYixJQUFJLEVBQUUsSUFBSTtJQUNWLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLEtBQUssRUFBRSxJQUFJO0lBQ1gsSUFBSSxFQUFFLElBQUk7SUFFVixrQkFBa0I7SUFDbEIsRUFBRSxFQUFFLElBQUk7SUFDUixLQUFLLEVBQUUsSUFBSTtJQUNYLEtBQUssRUFBRSxJQUFJO0lBQ1gsS0FBSyxFQUFFLElBQUk7SUFDWCxHQUFHLEVBQUUsSUFBSTtJQUNULFNBQVMsRUFBRSxJQUFJO0lBQ2YsU0FBUyxFQUFFLElBQUk7SUFDZixJQUFJLEVBQUUsSUFBSTtDQUNGLENBQUM7QUFFWCxrREFBa0Q7QUFDbEQsTUFBTSxjQUFjLEdBQUc7SUFDckIsR0FBRyxFQUFFLGNBQU0sQ0FBQyxHQUFHO0lBQ2YsR0FBRyxFQUFFLGNBQU0sQ0FBQyxHQUFHO0lBQ2YsTUFB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O0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLElBQUk7UUFDUixJQUFJLENBQUM7WUFDSCxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2pELE9BQU8sTUFBTSxLQUFLLGNBQWMsQ0FBQyxJQUFJLENBQUM7UUFDeEMsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxLQUFLO1FBQ1QsSUFBSSxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU87UUFDekIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFFcEIsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO2dCQUM3QixJQUFJLENBQUMsT0FBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7b0JBQ3JCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO29CQUNwQixPQUFPLEVBQUUsQ0FBQztnQkFDWixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7Q0FDRjtBQWhjRCw4QkFnY0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNvY2hEQiBJUEMgQ2xpZW50XG4gKlxuICogQ29ubmVjdHMgdG8gYSBTb2NoREIgSVBDIHNlcnZlciB2aWEgVW5peCBkb21haW4gc29ja2V0LlxuICpcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICovXG5cbi8vIENvcHlyaWdodCAyMDI1IFN1c2hhbnRoIChodHRwczovL2dpdGh1Yi5jb20vc3VzaGFudGhweSlcbi8vXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuLy8gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4vL1xuLy8gICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5pbXBvcnQgKiBhcyBuZXQgZnJvbSAnbmV0JztcbmltcG9ydCB7IENvbm5lY3Rpb25FcnJvciwgUHJvdG9jb2xFcnJvciwgVHJhbnNhY3Rpb25FcnJvciB9IGZyb20gJy4vZXJyb3JzJztcbmltcG9ydCB7IFF1ZXJ5IH0gZnJvbSAnLi9xdWVyeSc7XG5cbi8qKlxuICogV2lyZSBwcm90b2NvbCBvcGNvZGVzLlxuICovXG5leHBvcnQgY29uc3QgT3BDb2RlID0ge1xuICAvLyBDbGllbnQg4oaSIFNlcnZlciAobXVzdCBtYXRjaCBzb2NoZGItc3RvcmFnZS9zcmMvaXBjX3NlcnZlci5ycylcbiAgUHV0OiAweDAxLFxuICBHZXQ6IDB4MDIsXG4gIERlbGV0ZTogMHgwMyxcbiAgQmVnaW5UeG46IDB4MDQsXG4gIENvbW1pdFR4bjogMHgwNSxcbiAgQWJvcnRUeG46IDB4MDYsXG4gIFF1ZXJ5OiAweDA3LFxuICBDcmVhdGVUYWJsZTogMHgwOCxcbiAgUHV0UGF0aDogMHgwOSxcbiAgR2V0UGF0aDogMHgwQSxcbiAgU2NhbjogMHgwQixcbiAgQ2hlY2twb2ludDogMHgwQyxcbiAgU3RhdHM6IDB4MEQsXG4gIFBpbmc6IDB4MEUsXG5cbiAgLy8gU2VydmVyIOKGkiBDbGllbnRcbiAgT0s6IDB4ODAsXG4gIEVycm9yOiAweDgxLFxuICBWYWx1ZTogMHg4MixcbiAgVHhuSWQ6IDB4ODMsXG4gIFJvdzogMHg4NCxcbiAgRW5kU3RyZWFtOiAweDg1LFxuICBTdGF0c1Jlc3A6IDB4ODYsXG4gIFBvbmc6IDB4ODcsXG59IGFzIGNvbnN0O1xuXG4vLyBJbnRlcm5hbCBPcENvZGUgbWFwIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuY29uc3QgSW50ZXJuYWxPcENvZGUgPSB7XG4gIFBVVDogT3BDb2RlLlB1dCxcbiAgR0VUOiBPcENvZGUuR2V0LFxuICBERUxFVEU6IE9wQ29kZS5EZWxldGUsXG4gIEJFR0lOX1RYTjogT3BDb2RlLkJlZ2luVHhuLFxuICBDT01NSVRfVFhOOiBPcENvZGUuQ29tbWl0VHhuLFxuICBBQk9SVF9UWE46IE9wQ29kZS5BYm9ydFR4bixcbiAgUVVFUlk6IE9wQ29kZS5RdWVyeSxcbiAgUFVUX1BBVEg6IE9wQ29kZS5QdXRQYXRoLFxuICBHRVRfUEFUSDogT3BDb2RlLkdldFBhdGgsXG4gIFNDQU46IE9wQ29kZS5TY2FuLFxuICBDSEVDS1BPSU5UOiBPcENvZGUuQ2hlY2twb2ludCxcbiAgU1RBVFM6IE9wQ29kZS5TdGF0cyxcbiAgUElORzogT3BDb2RlLlBpbmcsXG4gIE9LOiBPcENvZGUuT0ssXG4gIEVSUk9SOiBPcENvZGUuRXJyb3IsXG4gIFZBTFVFOiBPcENvZGUuVmFsdWUsXG4gIFRYTl9JRDogT3BDb2RlLlR4bklkLFxuICBST1c6IE9wQ29kZS5Sb3csXG4gIEVORF9TVFJFQU06IE9wQ29kZS5FbmRTdHJlYW0sXG4gIFNUQVRTX1JFU1A6IE9wQ29kZS5TdGF0c1Jlc3AsXG4gIFBPTkc6IE9wQ29kZS5Qb25nLFxufSBhcyBjb25zdDtcblxuY29uc3QgTUFYX01FU1NBR0VfU0laRSA9IDE2ICogMTAyNCAqIDEwMjQ7IC8vIDE2IE1CXG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBJcGNDbGllbnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSXBjQ2xpZW50Q29uZmlnIHtcbiAgLyoqIFBhdGggdG8gVW5peCBkb21haW4gc29ja2V0ICovXG4gIHNvY2tldFBhdGg6IHN0cmluZztcbiAgLyoqIENvbm5lY3Rpb24gdGltZW91dCBpbiBtaWxsaXNlY29uZHMgKGRlZmF1bHQ6IDUwMDApICovXG4gIGNvbm5lY3RUaW1lb3V0PzogbnVtYmVyO1xuICAvKiogUmVhZCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcyAoZGVmYXVsdDogMzAwMDApICovXG4gIHJlYWRUaW1lb3V0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIElQQyBDbGllbnQgZm9yIFNvY2hEQi5cbiAqXG4gKiBDb25uZWN0cyB0byBhIFNvY2hEQiBzZXJ2ZXIgdmlhIFVuaXggZG9tYWluIHNvY2tldC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgSXBjQ2xpZW50IH0gZnJvbSAnQHN1c2hhbnRoL3NvY2hkYic7XG4gKlxuICogY29uc3QgY2xpZW50ID0gYXdhaXQgSXBjQ2xpZW50LmNvbm5lY3QoJy90bXAvc29jaGRiLnNvY2snKTtcbiAqXG4gKiBhd2FpdCBjbGllbnQucHV0KEJ1ZmZlci5mcm9tKCdrZXknKSwgQnVmZmVyLmZyb20oJ3ZhbHVlJykpO1xuICogY29uc3QgdmFsdWUgPSBhd2FpdCBjbGllbnQuZ2V0KEJ1ZmZlci5mcm9tKCdrZXknKSk7XG4gKlxuICogYXdhaXQgY2xpZW50LmNsb3NlKCk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIElwY0NsaWVudCB7XG4gIHByaXZhdGUgX3NvY2tldDogbmV0LlNvY2tldCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF9jb25maWc6IFJlcXVpcmVkPElwY0NsaWVudENvbmZpZz47XG4gIHByaXZhdGUgX3BlbmRpbmdSZWFkczogQXJyYXk8e1xuICAgIHJlc29sdmU6IChidWY6IEJ1ZmZlcikgPT4gdm9pZDtcbiAgICByZWplY3Q6IChlcnI6IEVycm9yKSA9PiB2b2lkO1xuICB9PiA9IFtdO1xuICBwcml2YXRlIF9yZWFkQnVmZmVyOiBCdWZmZXIgPSBCdWZmZXIuYWxsb2MoMCk7XG4gIHByaXZhdGUgX2Nsb3NlZCA9IGZhbHNlO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoY29uZmlnOiBJcGNDbGllbnRDb25maWcpIHtcbiAgICB0aGlzLl9jb25maWcgPSB7XG4gICAgICBjb25uZWN0VGltZW91dDogNTAwMCxcbiAgICAgIHJlYWRUaW1lb3V0OiAzMDAwMCxcbiAgICAgIC4uLmNvbmZpZyxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbm5lY3QgdG8gYSBTb2NoREIgSVBDIHNlcnZlci5cbiAgICpcbiAgICogQHBhcmFtIHNvY2tldFBhdGggLSBQYXRoIHRvIHRoZSBVbml4IGRvbWFpbiBzb2NrZXRcbiAgICogQHJldHVybnMgQSBjb25uZWN0ZWQgSXBjQ2xpZW50IGluc3RhbmNlXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHR5cGVzY3JpcHRcbiAgICogY29uc3QgY2xpZW50ID0gYXdhaXQgSXBjQ2xpZW50LmNvbm5lY3QoJy90bXAvc29jaGRiLnNvY2snKTtcbiAgICogYGBgXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgY29ubmVjdChzb2NrZXRQYXRoOiBzdHJpbmcpOiBQcm9taXNlPElwY0NsaWVudD4ge1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBJcGNDbGllbnQoeyBzb2NrZXRQYXRoIH0pO1xuICAgIGF3YWl0IGNsaWVudC5fY29ubmVjdCgpO1xuICAgIHJldHVybiBjbGllbnQ7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIF9jb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBzb2NrZXQgPSBuZXQuY3JlYXRlQ29ubmVjdGlvbihcbiAgICAgICAgeyBwYXRoOiB0aGlzLl9jb25maWcuc29ja2V0UGF0aCB9LFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5fc29ja2V0ID0gc29ja2V0O1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgKTtcblxuICAgICAgc29ja2V0LnNldFRpbWVvdXQodGhpcy5fY29uZmlnLmNvbm5lY3RUaW1lb3V0KTtcblxuICAgICAgc29ja2V0Lm9uKCd0aW1lb3V0JywgKCkgPT4ge1xuICAgICAgICBzb2NrZXQuZGVzdHJveSgpO1xuICAgICAgICByZWplY3QobmV3IENvbm5lY3Rpb25FcnJvcignQ29ubmVjdGlvbiB0aW1lb3V0JykpO1xuICAgICAgfSk7XG5cbiAgICAgIHNvY2tldC5vbignZXJyb3InLCAoZXJyKSA9PiB7XG4gICAgICAgIHJlamVjdChuZXcgQ29ubmVjdGlvbkVycm9yKGBDb25uZWN0aW9uIGZhaWxlZDogJHtlcnIubWVzc2FnZX1gKSk7XG4gICAgICB9KTtcblxuICAgICAgc29ja2V0Lm9uKCdkYXRhJywgKGRhdGEpID0+IHtcbiAgICAgICAgdGhpcy5fcmVhZEJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuX3JlYWRCdWZmZXIsIGRhdGFdKTtcbiAgICAgICAgdGhpcy5fcHJvY2Vzc0J1ZmZlcigpO1xuICAgICAgfSk7XG5cbiAgICAgIHNvY2tldC5vbignY2xvc2UnLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuX2Nsb3NlZCA9IHRydWU7XG4gICAgICAgIGZvciAoY29uc3QgcGVuZGluZyBvZiB0aGlzLl9wZW5kaW5nUmVhZHMpIHtcbiAgICAgICAgICBwZW5kaW5nLnJlamVjdChuZXcgQ29ubmVjdGlvbkVycm9yKCdDb25uZWN0aW9uIGNsb3NlZCcpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9wZW5kaW5nUmVhZHMgPSBbXTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfcHJvY2Vzc0J1ZmZlcigpOiB2b2lkIHtcbiAgICAvLyBQcm9jZXNzIGNvbXBsZXRlIG1lc3NhZ2VzIGZyb20gdGhlIGJ1ZmZlclxuICAgIHdoaWxlICh0aGlzLl9yZWFkQnVmZmVyLmxlbmd0aCA+PSA1ICYmIHRoaXMuX3BlbmRpbmdSZWFkcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSB0aGlzLl9yZWFkQnVmZmVyLnJlYWRVSW50MzJMRSgxKTtcbiAgICAgIGNvbnN0IHRvdGFsTGVuZ3RoID0gNSArIGxlbmd0aDtcblxuICAgICAgaWYgKHRoaXMuX3JlYWRCdWZmZXIubGVuZ3RoID49IHRvdGFsTGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLl9yZWFkQnVmZmVyLnN1YmFycmF5KDAsIHRvdGFsTGVuZ3RoKTtcbiAgICAgICAgdGhpcy5fcmVhZEJ1ZmZlciA9IHRoaXMuX3JlYWRCdWZmZXIuc3ViYXJyYXkodG90YWxMZW5ndGgpO1xuXG4gICAgICAgIGNvbnN0IHBlbmRpbmcgPSB0aGlzLl9wZW5kaW5nUmVhZHMuc2hpZnQoKTtcbiAgICAgICAgaWYgKHBlbmRpbmcpIHtcbiAgICAgICAgICBwZW5kaW5nLnJlc29sdmUobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgX3NlbmQob3Bjb2RlOiBudW1iZXIsIHBheWxvYWQ6IEJ1ZmZlciA9IEJ1ZmZlci5hbGxvYygwKSk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgaWYgKHRoaXMuX2Nsb3NlZCB8fCAhdGhpcy5fc29ja2V0KSB7XG4gICAgICB0aHJvdyBuZXcgQ29ubmVjdGlvbkVycm9yKCdOb3QgY29ubmVjdGVkJyk7XG4gICAgfVxuXG4gICAgLy8gRW5jb2RlIG1lc3NhZ2U6IG9wY29kZSAoMSkgKyBsZW5ndGggKDQgTEUpICsgcGF5bG9hZFxuICAgIGNvbnN0IG1lc3NhZ2UgPSBCdWZmZXIuYWxsb2MoNSArIHBheWxvYWQubGVuZ3RoKTtcbiAgICBtZXNzYWdlLndyaXRlVUludDgob3Bjb2RlLCAwKTtcbiAgICBtZXNzYWdlLndyaXRlVUludDMyTEUocGF5bG9hZC5sZW5ndGgsIDEpO1xuICAgIHBheWxvYWQuY29weShtZXNzYWdlLCA1KTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLl9wZW5kaW5nUmVhZHMucHVzaCh7IHJlc29sdmUsIHJlamVjdCB9KTtcblxuICAgICAgdGhpcy5fc29ja2V0IS53cml0ZShtZXNzYWdlLCAoZXJyKSA9PiB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICB0aGlzLl9wZW5kaW5nUmVhZHMucG9wKCk7XG4gICAgICAgICAgcmVqZWN0KG5ldyBDb25uZWN0aW9uRXJyb3IoYFdyaXRlIGZhaWxlZDogJHtlcnIubWVzc2FnZX1gKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvLyBTZXQgdGltZW91dCBmb3IgcmVzcG9uc2VcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBjb25zdCBpZHggPSB0aGlzLl9wZW5kaW5nUmVhZHMuZmluZEluZGV4KChwKSA9PiBwLnJlc29sdmUgPT09IHJlc29sdmUpO1xuICAgICAgICBpZiAoaWR4ICE9PSAtMSkge1xuICAgICAgICAgIHRoaXMuX3BlbmRpbmdSZWFkcy5zcGxpY2UoaWR4LCAxKTtcbiAgICAgICAgICByZWplY3QobmV3IENvbm5lY3Rpb25FcnJvcignUmVhZCB0aW1lb3V0JykpO1xuICAgICAgICB9XG4gICAgICB9LCB0aGlzLl9jb25maWcucmVhZFRpbWVvdXQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfcGFyc2VSZXNwb25zZShyZXNwb25zZTogQnVmZmVyKTogeyBvcGNvZGU6IG51bWJlcjsgcGF5bG9hZDogQnVmZmVyIH0ge1xuICAgIGNvbnN0IG9wY29kZSA9IHJlc3BvbnNlLnJlYWRVSW50OCgwKTtcbiAgICBjb25zdCBsZW5ndGggPSByZXNwb25zZS5yZWFkVUludDMyTEUoMSk7XG4gICAgY29uc3QgcGF5bG9hZCA9IHJlc3BvbnNlLnN1YmFycmF5KDUsIDUgKyBsZW5ndGgpO1xuXG4gICAgaWYgKG9wY29kZSA9PT0gSW50ZXJuYWxPcENvZGUuRVJST1IpIHtcbiAgICAgIHRocm93IG5ldyBQcm90b2NvbEVycm9yKHBheWxvYWQudG9TdHJpbmcoJ3V0ZjgnKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgb3Bjb2RlLCBwYXlsb2FkIH07XG4gIH1cblxuICAvKipcbiAgICogRW5jb2RlIGEga2V5IGZvciB0aGUgd2lyZSBwcm90b2NvbC5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBzdGF0aWMgZW5jb2RlS2V5KGtleTogQnVmZmVyKTogQnVmZmVyIHtcbiAgICAvLyBGb3JtYXQ6IFtsZW5ndGg6NF1bb3A6MV1ba2V5X2xlbjo0XVtrZXk6Li4uXVxuICAgIGNvbnN0IG1zZ0xlbiA9IDEgKyA0ICsga2V5Lmxlbmd0aDtcbiAgICBjb25zdCBtc2cgPSBCdWZmZXIuYWxsb2MoNCArIG1zZ0xlbik7XG4gICAgbXNnLndyaXRlVUludDMyQkUobXNnTGVuLCAwKTtcbiAgICBtc2cud3JpdGVVSW50OChJbnRlcm5hbE9wQ29kZS5HRVQsIDQpO1xuICAgIG1zZy53cml0ZVVJbnQzMkJFKGtleS5sZW5ndGgsIDUpO1xuICAgIGtleS5jb3B5KG1zZywgOSk7XG4gICAgcmV0dXJuIG1zZztcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmNvZGUgYSBrZXktdmFsdWUgcGFpciBmb3IgdGhlIHdpcmUgcHJvdG9jb2wuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgc3RhdGljIGVuY29kZUtleVZhbHVlKGtleTogQnVmZmVyLCB2YWx1ZTogQnVmZmVyKTogQnVmZmVyIHtcbiAgICAvLyBGb3JtYXQ6IFtsZW5ndGg6NF1bb3A6MV1ba2V5X2xlbjo0XVtrZXk6Li4uXVt2YWx1ZV9sZW46NF1bdmFsdWU6Li4uXVxuICAgIGNvbnN0IG1zZ0xlbiA9IDEgKyA0ICsga2V5Lmxlbmd0aCArIDQgKyB2YWx1ZS5sZW5ndGg7XG4gICAgY29uc3QgbXNnID0gQnVmZmVyLmFsbG9jKDQgKyBtc2dMZW4pO1xuICAgIG1zZy53cml0ZVVJbnQzMkJFKG1zZ0xlbiwgMCk7XG4gICAgbXNnLndyaXRlVUludDgoSW50ZXJuYWxPcENvZGUuUFVULCA0KTtcbiAgICBtc2cud3JpdGVVSW50MzJCRShrZXkubGVuZ3RoLCA1KTtcbiAgICBrZXkuY29weShtc2csIDkpO1xuICAgIG1zZy53cml0ZVVJbnQzMkJFKHZhbHVlLmxlbmd0aCwgOSArIGtleS5sZW5ndGgpO1xuICAgIHZhbHVlLmNvcHkobXNnLCAxMyArIGtleS5sZW5ndGgpO1xuICAgIHJldHVybiBtc2c7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgdmFsdWUgYnkga2V5LlxuICAgKi9cbiAgYXN5bmMgZ2V0KGtleTogQnVmZmVyKTogUHJvbWlzZTxCdWZmZXIgfCBudWxsPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9zZW5kKEludGVybmFsT3BDb2RlLkdFVCwga2V5KTtcbiAgICBjb25zdCB7IG9wY29kZSwgcGF5bG9hZCB9ID0gdGhpcy5fcGFyc2VSZXNwb25zZShyZXNwb25zZSk7XG5cbiAgICBpZiAob3Bjb2RlID09PSBJbnRlcm5hbE9wQ29kZS5WQUxVRSkge1xuICAgICAgLy8gSWYgcGF5bG9hZCBpcyBlbXB0eSwgdGhlIGtleSBkb2Vzbid0IGV4aXN0XG4gICAgICBpZiAocGF5bG9hZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gcGF5bG9hZDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUHV0IGEga2V5LXZhbHVlIHBhaXIuXG4gICAqL1xuICBhc3luYyBwdXQoa2V5OiBCdWZmZXIsIHZhbHVlOiBCdWZmZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBFbmNvZGU6IGtleV9sZW4gKDQgTEUpICsga2V5ICsgdmFsdWVcbiAgICBjb25zdCBwYXlsb2FkID0gQnVmZmVyLmFsbG9jKDQgKyBrZXkubGVuZ3RoICsgdmFsdWUubGVuZ3RoKTtcbiAgICBwYXlsb2FkLndyaXRlVUludDMyTEUoa2V5Lmxlbmd0aCwgMCk7XG4gICAga2V5LmNvcHkocGF5bG9hZCwgNCk7XG4gICAgdmFsdWUuY29weShwYXlsb2FkLCA0ICsga2V5Lmxlbmd0aCk7XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmQoSW50ZXJuYWxPcENvZGUuUFVULCBwYXlsb2FkKTtcbiAgICB0aGlzLl9wYXJzZVJlc3BvbnNlKHJlc3BvbnNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYSBrZXkuXG4gICAqL1xuICBhc3luYyBkZWxldGUoa2V5OiBCdWZmZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmQoSW50ZXJuYWxPcENvZGUuREVMRVRFLCBrZXkpO1xuICAgIHRoaXMuX3BhcnNlUmVzcG9uc2UocmVzcG9uc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHZhbHVlIGJ5IHBhdGguXG4gICAqIFdpcmUgZm9ybWF0OiBwYXRoX2NvdW50KDIgTEUpICsgW3BhdGhfbGVuKDIgTEUpICsgcGF0aF9zZWdtZW50XS4uLlxuICAgKi9cbiAgYXN5bmMgZ2V0UGF0aChwYXRoOiBzdHJpbmcpOiBQcm9taXNlPEJ1ZmZlciB8IG51bGw+IHtcbiAgICAvLyBFbmNvZGUgcGF0aCBhcyBzaW5nbGUgc2VnbWVudCBmb3Igbm93IChjb3VsZCBzcGxpdCBvbiAnLycgZm9yIG11bHRpLXNlZ21lbnQpXG4gICAgY29uc3QgcGF0aEJ1ZiA9IEJ1ZmZlci5mcm9tKHBhdGgsICd1dGY4Jyk7XG4gICAgY29uc3QgcGF5bG9hZCA9IEJ1ZmZlci5hbGxvYygyICsgMiArIHBhdGhCdWYubGVuZ3RoKTtcbiAgICBwYXlsb2FkLndyaXRlVUludDE2TEUoMSwgMCk7IC8vIHBhdGhfY291bnQgPSAxXG4gICAgcGF5bG9hZC53cml0ZVVJbnQxNkxFKHBhdGhCdWYubGVuZ3RoLCAyKTsgLy8gcGF0aF9sZW5cbiAgICBwYXRoQnVmLmNvcHkocGF5bG9hZCwgNCk7IC8vIHBhdGhcbiAgICBcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmQoSW50ZXJuYWxPcENvZGUuR0VUX1BBVEgsIHBheWxvYWQpO1xuICAgIGNvbnN0IHsgb3Bjb2RlLCBwYXlsb2FkOiByZXNwb25zZVBheWxvYWQgfSA9IHRoaXMuX3BhcnNlUmVzcG9uc2UocmVzcG9uc2UpO1xuXG4gICAgaWYgKG9wY29kZSA9PT0gSW50ZXJuYWxPcENvZGUuVkFMVUUpIHtcbiAgICAgIC8vIElmIHBheWxvYWQgaXMgZW1wdHksIHRoZSBrZXkgZG9lc24ndCBleGlzdFxuICAgICAgaWYgKHJlc3BvbnNlUGF5bG9hZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzcG9uc2VQYXlsb2FkO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdXQgYSB2YWx1ZSBhdCBhIHBhdGguXG4gICAqIFdpcmUgZm9ybWF0OiBwYXRoX2NvdW50KDIgTEUpICsgW3BhdGhfbGVuKDIgTEUpICsgcGF0aF9zZWdtZW50XS4uLiArIHZhbHVlXG4gICAqL1xuICBhc3luYyBwdXRQYXRoKHBhdGg6IHN0cmluZywgdmFsdWU6IEJ1ZmZlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHBhdGhCdWYgPSBCdWZmZXIuZnJvbShwYXRoLCAndXRmOCcpO1xuICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuYWxsb2MoMiArIDIgKyBwYXRoQnVmLmxlbmd0aCArIHZhbHVlLmxlbmd0aCk7XG4gICAgcGF5bG9hZC53cml0ZVVJbnQxNkxFKDEsIDApOyAvLyBwYXRoX2NvdW50ID0gMVxuICAgIHBheWxvYWQud3JpdGVVSW50MTZMRShwYXRoQnVmLmxlbmd0aCwgMik7IC8vIHBhdGhfbGVuXG4gICAgcGF0aEJ1Zi5jb3B5KHBheWxvYWQsIDQpOyAvLyBwYXRoXG4gICAgdmFsdWUuY29weShwYXlsb2FkLCA0ICsgcGF0aEJ1Zi5sZW5ndGgpOyAvLyB2YWx1ZVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9zZW5kKEludGVybmFsT3BDb2RlLlBVVF9QQVRILCBwYXlsb2FkKTtcbiAgICB0aGlzLl9wYXJzZVJlc3BvbnNlKHJlc3BvbnNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIGEgcXVlcnkgYW5kIHJldHVybiBUT09OLWZvcm1hdHRlZCByZXN1bHRzLlxuICAgKiBcbiAgICogV2lyZSBmb3JtYXQ6IHBhdGhfbGVuKDIpICsgcGF0aCArIGxpbWl0KDQpICsgb2Zmc2V0KDQpICsgY29sc19jb3VudCgyKSArIFtjb2xfbGVuKDIpICsgY29sXS4uLlxuICAgKi9cbiAgYXN5bmMgcXVlcnkoXG4gICAgcGF0aFByZWZpeDogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiB7IGxpbWl0PzogbnVtYmVyOyBvZmZzZXQ/OiBudW1iZXI7IGNvbHVtbnM/OiBzdHJpbmdbXSB9XG4gICk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3Qgb3B0cyA9IG9wdGlvbnMgfHwge307XG4gICAgY29uc3QgcGF0aEJ1ZiA9IEJ1ZmZlci5mcm9tKHBhdGhQcmVmaXgsICd1dGY4Jyk7XG4gICAgY29uc3QgY29sdW1ucyA9IG9wdHMuY29sdW1ucyB8fCBbXTtcbiAgICBcbiAgICAvLyBDYWxjdWxhdGUgcGF5bG9hZCBzaXplXG4gICAgbGV0IHNpemUgPSAyICsgcGF0aEJ1Zi5sZW5ndGggKyA0ICsgNCArIDI7XG4gICAgZm9yIChjb25zdCBjb2wgb2YgY29sdW1ucykge1xuICAgICAgc2l6ZSArPSAyICsgQnVmZmVyLmJ5dGVMZW5ndGgoY29sLCAndXRmOCcpO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBwYXlsb2FkID0gQnVmZmVyLmFsbG9jKHNpemUpO1xuICAgIGxldCBvZmZzZXQgPSAwO1xuICAgIFxuICAgIC8vIFBhdGg6IHBhdGhfbGVuKDIgTEUpICsgcGF0aFxuICAgIHBheWxvYWQud3JpdGVVSW50MTZMRShwYXRoQnVmLmxlbmd0aCwgb2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gMjtcbiAgICBwYXRoQnVmLmNvcHkocGF5bG9hZCwgb2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gcGF0aEJ1Zi5sZW5ndGg7XG4gICAgXG4gICAgLy8gTGltaXQgKDQgTEUpIC0gMCBtZWFucyBubyBsaW1pdFxuICAgIHBheWxvYWQud3JpdGVVSW50MzJMRShvcHRzLmxpbWl0IHx8IDAsIG9mZnNldCk7XG4gICAgb2Zmc2V0ICs9IDQ7XG4gICAgXG4gICAgLy8gT2Zmc2V0ICg0IExFKVxuICAgIHBheWxvYWQud3JpdGVVSW50MzJMRShvcHRzLm9mZnNldCB8fCAwLCBvZmZzZXQpO1xuICAgIG9mZnNldCArPSA0O1xuICAgIFxuICAgIC8vIENvbHVtbnM6IGNvdW50KDIgTEUpICsgW2NvbF9sZW4oMiBMRSkgKyBjb2xdLi4uXG4gICAgcGF5bG9hZC53cml0ZVVJbnQxNkxFKGNvbHVtbnMubGVuZ3RoLCBvZmZzZXQpO1xuICAgIG9mZnNldCArPSAyO1xuICAgIGZvciAoY29uc3QgY29sIG9mIGNvbHVtbnMpIHtcbiAgICAgIGNvbnN0IGNvbEJ1ZiA9IEJ1ZmZlci5mcm9tKGNvbCwgJ3V0ZjgnKTtcbiAgICAgIHBheWxvYWQud3JpdGVVSW50MTZMRShjb2xCdWYubGVuZ3RoLCBvZmZzZXQpO1xuICAgICAgb2Zmc2V0ICs9IDI7XG4gICAgICBjb2xCdWYuY29weShwYXlsb2FkLCBvZmZzZXQpO1xuICAgICAgb2Zmc2V0ICs9IGNvbEJ1Zi5sZW5ndGg7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9zZW5kKEludGVybmFsT3BDb2RlLlFVRVJZLCBwYXlsb2FkKTtcbiAgICBjb25zdCB7IHBheWxvYWQ6IHJlc3VsdFBheWxvYWQgfSA9IHRoaXMuX3BhcnNlUmVzcG9uc2UocmVzcG9uc2UpO1xuXG4gICAgcmV0dXJuIHJlc3VsdFBheWxvYWQudG9TdHJpbmcoJ3V0ZjgnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTY2FuIGZvciBrZXlzIHdpdGggYSBwcmVmaXgsIHJldHVybmluZyBrZXktdmFsdWUgcGFpcnMuXG4gICAqIFRoaXMgaXMgdGhlIHByZWZlcnJlZCBtZXRob2QgZm9yIHNpbXBsZSBwcmVmaXgtYmFzZWQgaXRlcmF0aW9uLlxuICAgKiBcbiAgICogV2lyZSBmb3JtYXQ6IHByZWZpeCBzdHJpbmdcbiAgICogUmVzcG9uc2UgZm9ybWF0OiBjb3VudCg0IExFKSArIFtrZXlfbGVuKDIgTEUpICsga2V5ICsgdmFsX2xlbig0IExFKSArIHZhbF0uLi5cbiAgICovXG4gIGFzeW5jIHNjYW4ocHJlZml4OiBzdHJpbmcpOiBQcm9taXNlPEFycmF5PHsga2V5OiBCdWZmZXI7IHZhbHVlOiBCdWZmZXIgfT4+IHtcbiAgICBjb25zdCBwcmVmaXhCdWYgPSBCdWZmZXIuZnJvbShwcmVmaXgsICd1dGY4Jyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLl9zZW5kKEludGVybmFsT3BDb2RlLlNDQU4sIHByZWZpeEJ1Zik7XG4gICAgY29uc3QgeyBvcGNvZGUsIHBheWxvYWQgfSA9IHRoaXMuX3BhcnNlUmVzcG9uc2UocmVzcG9uc2UpO1xuXG4gICAgaWYgKG9wY29kZSAhPT0gSW50ZXJuYWxPcENvZGUuVkFMVUUgJiYgb3Bjb2RlICE9PSBJbnRlcm5hbE9wQ29kZS5PSykge1xuICAgICAgdGhyb3cgbmV3IFByb3RvY29sRXJyb3IoYFVuZXhwZWN0ZWQgc2NhbiByZXNwb25zZSBvcGNvZGU6IDB4JHtvcGNvZGUudG9TdHJpbmcoMTYpfWApO1xuICAgIH1cblxuICAgIGlmIChwYXlsb2FkLmxlbmd0aCA8IDQpIHtcbiAgICAgIHJldHVybiBbXTsgLy8gRW1wdHkgcmVzdWx0XG4gICAgfVxuXG4gICAgLy8gUGFyc2UgcmVzcG9uc2U6IGNvdW50KDQgTEUpICsgW2tleV9sZW4oMiBMRSkgKyBrZXkgKyB2YWxfbGVuKDQgTEUpICsgdmFsXS4uLlxuICAgIGNvbnN0IGNvdW50ID0gcGF5bG9hZC5yZWFkVUludDMyTEUoMCk7XG4gICAgY29uc3QgcmVzdWx0czogQXJyYXk8eyBrZXk6IEJ1ZmZlcjsgdmFsdWU6IEJ1ZmZlciB9PiA9IFtdO1xuICAgIGxldCBvZmZzZXQgPSA0O1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICBpZiAob2Zmc2V0ICsgMiA+IHBheWxvYWQubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBQcm90b2NvbEVycm9yKCdUcnVuY2F0ZWQgc2NhbiByZXNwb25zZSAoa2V5X2xlbiknKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGtleUxlbiA9IHBheWxvYWQucmVhZFVJbnQxNkxFKG9mZnNldCk7XG4gICAgICBvZmZzZXQgKz0gMjtcblxuICAgICAgaWYgKG9mZnNldCArIGtleUxlbiArIDQgPiBwYXlsb2FkLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgUHJvdG9jb2xFcnJvcignVHJ1bmNhdGVkIHNjYW4gcmVzcG9uc2UgKGtleSt2YWxfbGVuKScpO1xuICAgICAgfVxuICAgICAgY29uc3Qga2V5ID0gcGF5bG9hZC5zdWJhcnJheShvZmZzZXQsIG9mZnNldCArIGtleUxlbik7XG4gICAgICBvZmZzZXQgKz0ga2V5TGVuO1xuXG4gICAgICBjb25zdCB2YWxMZW4gPSBwYXlsb2FkLnJlYWRVSW50MzJMRShvZmZzZXQpO1xuICAgICAgb2Zmc2V0ICs9IDQ7XG5cbiAgICAgIGlmIChvZmZzZXQgKyB2YWxMZW4gPiBwYXlsb2FkLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgUHJvdG9jb2xFcnJvcignVHJ1bmNhdGVkIHNjYW4gcmVzcG9uc2UgKHZhbHVlKScpO1xuICAgICAgfVxuICAgICAgY29uc3QgdmFsdWUgPSBwYXlsb2FkLnN1YmFycmF5KG9mZnNldCwgb2Zmc2V0ICsgdmFsTGVuKTtcbiAgICAgIG9mZnNldCArPSB2YWxMZW47XG5cbiAgICAgIHJlc3VsdHMucHVzaCh7IGtleSwgdmFsdWUgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgcXVlcnkgYnVpbGRlci5cbiAgICovXG4gIHF1ZXJ5QnVpbGRlcihwYXRoUHJlZml4OiBzdHJpbmcpOiBRdWVyeSB7XG4gICAgcmV0dXJuIG5ldyBRdWVyeSh0aGlzLCBwYXRoUHJlZml4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCZWdpbiBhIG5ldyB0cmFuc2FjdGlvbi5cbiAgICovXG4gIGFzeW5jIGJlZ2luVHJhbnNhY3Rpb24oKTogUHJvbWlzZTxiaWdpbnQ+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmQoSW50ZXJuYWxPcENvZGUuQkVHSU5fVFhOKTtcbiAgICBjb25zdCB7IG9wY29kZSwgcGF5bG9hZCB9ID0gdGhpcy5fcGFyc2VSZXNwb25zZShyZXNwb25zZSk7XG5cbiAgICBpZiAob3Bjb2RlID09PSBJbnRlcm5hbE9wQ29kZS5UWE5fSUQpIHtcbiAgICAgIHJldHVybiBwYXlsb2FkLnJlYWRCaWdVSW50NjRMRSgwKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFRyYW5zYWN0aW9uRXJyb3IoJ0ZhaWxlZCB0byBiZWdpbiB0cmFuc2FjdGlvbicpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbW1pdCBhIHRyYW5zYWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgY29tbWl0VHJhbnNhY3Rpb24odHhuSWQ6IGJpZ2ludCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuYWxsb2MoOCk7XG4gICAgcGF5bG9hZC53cml0ZUJpZ1VJbnQ2NExFKHR4bklkLCAwKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmQoSW50ZXJuYWxPcENvZGUuQ09NTUlUX1RYTiwgcGF5bG9hZCk7XG4gICAgdGhpcy5fcGFyc2VSZXNwb25zZShyZXNwb25zZSk7XG4gIH1cblxuICAvKipcbiAgICogQWJvcnQgYSB0cmFuc2FjdGlvbi5cbiAgICovXG4gIGFzeW5jIGFib3J0VHJhbnNhY3Rpb24odHhuSWQ6IGJpZ2ludCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHBheWxvYWQgPSBCdWZmZXIuYWxsb2MoOCk7XG4gICAgcGF5bG9hZC53cml0ZUJpZ1VJbnQ2NExFKHR4bklkLCAwKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmQoSW50ZXJuYWxPcENvZGUuQUJPUlRfVFhOLCBwYXlsb2FkKTtcbiAgICB0aGlzLl9wYXJzZVJlc3BvbnNlKHJlc3BvbnNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3JjZSBhIGNoZWNrcG9pbnQuXG4gICAqL1xuICBhc3luYyBjaGVja3BvaW50KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2VuZChJbnRlcm5hbE9wQ29kZS5DSEVDS1BPSU5UKTtcbiAgICB0aGlzLl9wYXJzZVJlc3BvbnNlKHJlc3BvbnNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc3RvcmFnZSBzdGF0aXN0aWNzLlxuICAgKi9cbiAgYXN5bmMgc3RhdHMoKTogUHJvbWlzZTx7XG4gICAgbWVtdGFibGVTaXplQnl0ZXM6IG51bWJlcjtcbiAgICB3YWxTaXplQnl0ZXM6IG51bWJlcjtcbiAgICBhY3RpdmVUcmFuc2FjdGlvbnM6IG51bWJlcjtcbiAgfT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5fc2VuZChJbnRlcm5hbE9wQ29kZS5TVEFUUyk7XG4gICAgY29uc3QgeyBwYXlsb2FkIH0gPSB0aGlzLl9wYXJzZVJlc3BvbnNlKHJlc3BvbnNlKTtcbiAgICBjb25zdCBqc29uID0gSlNPTi5wYXJzZShwYXlsb2FkLnRvU3RyaW5nKCd1dGY4JykpO1xuICAgIHJldHVybiB7XG4gICAgICBtZW10YWJsZVNpemVCeXRlczoganNvbi5tZW10YWJsZV9zaXplX2J5dGVzIHx8IDAsXG4gICAgICB3YWxTaXplQnl0ZXM6IGpzb24ud2FsX3NpemVfYnl0ZXMgfHwgMCxcbiAgICAgIGFjdGl2ZVRyYW5zYWN0aW9uczoganNvbi5hY3RpdmVfdHJhbnNhY3Rpb25zIHx8IDAsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQaW5nIHRoZSBzZXJ2ZXIuXG4gICAqL1xuICBhc3luYyBwaW5nKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3NlbmQoSW50ZXJuYWxPcENvZGUuUElORyk7XG4gICAgICBjb25zdCB7IG9wY29kZSB9ID0gdGhpcy5fcGFyc2VSZXNwb25zZShyZXNwb25zZSk7XG4gICAgICByZXR1cm4gb3Bjb2RlID09PSBJbnRlcm5hbE9wQ29kZS5QT05HO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSB0aGUgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIGNsb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLl9jbG9zZWQpIHJldHVybjtcbiAgICB0aGlzLl9jbG9zZWQgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMuX3NvY2tldCkge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIHRoaXMuX3NvY2tldCEuZW5kKCgpID0+IHtcbiAgICAgICAgICB0aGlzLl9zb2NrZXQgPSBudWxsO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==