@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,333 @@
1
+ "use strict";
2
+ /**
3
+ * SochDB gRPC Client - Thin SDK Wrapper
4
+ *
5
+ * This module provides a thin gRPC client wrapper for the SochDB server.
6
+ * All business logic runs on the server (Thick Server / Thin Client architecture).
7
+ *
8
+ * The client is approximately ~250 lines of code, delegating all operations to the server.
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.GrpcClient = exports.SochDBClient = void 0;
45
+ exports.connect = connect;
46
+ const grpc = __importStar(require("@grpc/grpc-js"));
47
+ const protoLoader = __importStar(require("@grpc/proto-loader"));
48
+ const path = __importStar(require("path"));
49
+ /**
50
+ * Thin gRPC client for SochDB.
51
+ *
52
+ * All operations are delegated to the SochDB gRPC server.
53
+ * This client provides a TypeScript interface over the gRPC protocol.
54
+ *
55
+ * Usage:
56
+ * ```typescript
57
+ * const client = new SochDBClient({ address: 'localhost:50051' });
58
+ *
59
+ * // Create collection
60
+ * await client.createCollection('docs', { dimension: 384 });
61
+ *
62
+ * // Add documents
63
+ * await client.addDocuments('docs', [
64
+ * { id: '1', content: 'Hello', embedding: [...] }
65
+ * ]);
66
+ *
67
+ * // Search
68
+ * const results = await client.search('docs', queryVector, 5);
69
+ * ```
70
+ */
71
+ class SochDBClient {
72
+ address;
73
+ credentials;
74
+ stubs = new Map();
75
+ protoPath;
76
+ packageDefinition;
77
+ proto;
78
+ constructor(options = {}) {
79
+ this.address = options.address || 'localhost:50051';
80
+ this.credentials = options.secure
81
+ ? grpc.credentials.createSsl()
82
+ : grpc.credentials.createInsecure();
83
+ this.protoPath = options.protoPath || path.join(__dirname, '../../proto/sochdb.proto');
84
+ // Load proto definition
85
+ this.packageDefinition = protoLoader.loadSync(this.protoPath, {
86
+ keepCase: false,
87
+ longs: String,
88
+ enums: String,
89
+ defaults: true,
90
+ oneofs: true,
91
+ });
92
+ const loadedPackage = grpc.loadPackageDefinition(this.packageDefinition);
93
+ this.proto = loadedPackage?.sochdb?.v1;
94
+ }
95
+ getStub(serviceName) {
96
+ if (!this.stubs.has(serviceName)) {
97
+ const ServiceClass = this.proto?.[serviceName];
98
+ if (!ServiceClass) {
99
+ throw new Error(`Service ${serviceName} not found in proto definition`);
100
+ }
101
+ this.stubs.set(serviceName, new ServiceClass(this.address, this.credentials));
102
+ }
103
+ return this.stubs.get(serviceName);
104
+ }
105
+ promisify(stub, method, request) {
106
+ return new Promise((resolve, reject) => {
107
+ stub[method](request, (error, response) => {
108
+ if (error)
109
+ reject(error);
110
+ else
111
+ resolve(response);
112
+ });
113
+ });
114
+ }
115
+ /**
116
+ * Close all gRPC connections.
117
+ */
118
+ close() {
119
+ for (const stub of this.stubs.values()) {
120
+ grpc.closeClient(stub);
121
+ }
122
+ this.stubs.clear();
123
+ }
124
+ // ===========================================================================
125
+ // Vector Index Operations (VectorIndexService)
126
+ // ===========================================================================
127
+ async createIndex(name, dimension, options = {}) {
128
+ const stub = this.getStub('VectorIndexService');
129
+ const response = await this.promisify(stub, 'createIndex', {
130
+ name,
131
+ dimension,
132
+ metric: options.metric === 'l2' ? 1 : options.metric === 'dot' ? 3 : 2,
133
+ config: {
134
+ maxConnections: options.m || 16,
135
+ efConstruction: options.efConstruction || 200,
136
+ },
137
+ });
138
+ return response.success;
139
+ }
140
+ async insertVectors(indexName, ids, vectors) {
141
+ const stub = this.getStub('VectorIndexService');
142
+ const flatVectors = vectors.flat();
143
+ const response = await this.promisify(stub, 'insertBatch', {
144
+ indexName,
145
+ ids,
146
+ vectors: flatVectors,
147
+ });
148
+ return response.insertedCount;
149
+ }
150
+ async search(indexName, query, k = 10, ef = 50) {
151
+ const stub = this.getStub('VectorIndexService');
152
+ const response = await this.promisify(stub, 'search', {
153
+ indexName,
154
+ query,
155
+ k,
156
+ ef,
157
+ });
158
+ return (response.results || []).map((r) => ({
159
+ id: Number(r.id),
160
+ distance: r.distance,
161
+ }));
162
+ }
163
+ // ===========================================================================
164
+ // Collection Operations (CollectionService)
165
+ // ===========================================================================
166
+ async createCollection(name, options) {
167
+ const stub = this.getStub('CollectionService');
168
+ const response = await this.promisify(stub, 'createCollection', {
169
+ name,
170
+ namespace: options.namespace || 'default',
171
+ dimension: options.dimension,
172
+ metric: options.metric === 'l2' ? 1 : options.metric === 'dot' ? 3 : 2,
173
+ });
174
+ return response.success;
175
+ }
176
+ async addDocuments(collectionName, documents, namespace = 'default') {
177
+ const stub = this.getStub('CollectionService');
178
+ const response = await this.promisify(stub, 'addDocuments', {
179
+ collectionName,
180
+ namespace,
181
+ documents: documents.map((d) => ({
182
+ id: d.id || '',
183
+ content: d.content || '',
184
+ embedding: d.embedding || [],
185
+ metadata: d.metadata || {},
186
+ })),
187
+ });
188
+ return response.ids || [];
189
+ }
190
+ async searchCollection(collectionName, query, k = 10, options = {}) {
191
+ const stub = this.getStub('CollectionService');
192
+ const response = await this.promisify(stub, 'searchCollection', {
193
+ collectionName,
194
+ namespace: options.namespace || 'default',
195
+ query,
196
+ k,
197
+ filter: options.filter || {},
198
+ });
199
+ return (response.results || []).map((r) => ({
200
+ id: r.document.id,
201
+ content: r.document.content,
202
+ embedding: r.document.embedding || [],
203
+ metadata: r.document.metadata || {},
204
+ }));
205
+ }
206
+ // ===========================================================================
207
+ // Graph Operations (GraphService)
208
+ // ===========================================================================
209
+ async addNode(nodeId, nodeType, properties = {}, namespace = 'default') {
210
+ const stub = this.getStub('GraphService');
211
+ const response = await this.promisify(stub, 'addNode', {
212
+ namespace,
213
+ node: { id: nodeId, nodeType, properties },
214
+ });
215
+ return response.success;
216
+ }
217
+ async addEdge(fromId, edgeType, toId, properties = {}, namespace = 'default') {
218
+ const stub = this.getStub('GraphService');
219
+ const response = await this.promisify(stub, 'addEdge', {
220
+ namespace,
221
+ edge: { fromId, edgeType, toId, properties },
222
+ });
223
+ return response.success;
224
+ }
225
+ async traverse(startNode, options = {}) {
226
+ const stub = this.getStub('GraphService');
227
+ const response = await this.promisify(stub, 'traverse', {
228
+ namespace: options.namespace || 'default',
229
+ startNodeId: startNode,
230
+ order: options.order === 'dfs' ? 1 : 0,
231
+ maxDepth: options.maxDepth || 10,
232
+ });
233
+ return {
234
+ nodes: (response.nodes || []).map((n) => ({
235
+ id: n.id,
236
+ nodeType: n.nodeType,
237
+ properties: n.properties || {},
238
+ })),
239
+ edges: (response.edges || []).map((e) => ({
240
+ fromId: e.fromId,
241
+ edgeType: e.edgeType,
242
+ toId: e.toId,
243
+ properties: e.properties || {},
244
+ })),
245
+ };
246
+ }
247
+ // ===========================================================================
248
+ // Semantic Cache Operations (SemanticCacheService)
249
+ // ===========================================================================
250
+ async cacheGet(cacheName, queryEmbedding, threshold = 0.85) {
251
+ const stub = this.getStub('SemanticCacheService');
252
+ const response = await this.promisify(stub, 'get', {
253
+ cacheName,
254
+ queryEmbedding,
255
+ similarityThreshold: threshold,
256
+ });
257
+ return response.hit ? response.cachedValue : null;
258
+ }
259
+ async cachePut(cacheName, key, value, keyEmbedding, ttlSeconds = 0) {
260
+ const stub = this.getStub('SemanticCacheService');
261
+ const response = await this.promisify(stub, 'put', {
262
+ cacheName,
263
+ key,
264
+ value,
265
+ keyEmbedding,
266
+ ttlSeconds,
267
+ });
268
+ return response.success;
269
+ }
270
+ // ===========================================================================
271
+ // Trace Operations (TraceService)
272
+ // ===========================================================================
273
+ async startTrace(name) {
274
+ const stub = this.getStub('TraceService');
275
+ const response = await this.promisify(stub, 'startTrace', { name });
276
+ return { traceId: response.traceId, rootSpanId: response.rootSpanId };
277
+ }
278
+ async startSpan(traceId, parentSpanId, name) {
279
+ const stub = this.getStub('TraceService');
280
+ const response = await this.promisify(stub, 'startSpan', {
281
+ traceId,
282
+ parentSpanId,
283
+ name,
284
+ });
285
+ return response.spanId;
286
+ }
287
+ async endSpan(traceId, spanId, status = 'ok') {
288
+ const stub = this.getStub('TraceService');
289
+ const statusMap = { unset: 0, ok: 1, error: 2 };
290
+ const response = await this.promisify(stub, 'endSpan', {
291
+ traceId,
292
+ spanId,
293
+ status: statusMap[status],
294
+ });
295
+ return Number(response.durationUs);
296
+ }
297
+ // ===========================================================================
298
+ // KV Operations (KvService)
299
+ // ===========================================================================
300
+ async get(key, namespace = 'default') {
301
+ const stub = this.getStub('KvService');
302
+ const response = await this.promisify(stub, 'get', { namespace, key });
303
+ return response.found ? Buffer.from(response.value) : null;
304
+ }
305
+ async put(key, value, namespace = 'default', ttlSeconds = 0) {
306
+ const stub = this.getStub('KvService');
307
+ const response = await this.promisify(stub, 'put', {
308
+ namespace,
309
+ key,
310
+ value,
311
+ ttlSeconds,
312
+ });
313
+ return response.success;
314
+ }
315
+ async delete(key, namespace = 'default') {
316
+ const stub = this.getStub('KvService');
317
+ const response = await this.promisify(stub, 'delete', { namespace, key });
318
+ return response.success;
319
+ }
320
+ }
321
+ exports.SochDBClient = SochDBClient;
322
+ /**
323
+ * Connect to SochDB gRPC server.
324
+ */
325
+ function connect(address = 'localhost:50051', options = {}) {
326
+ if (address.startsWith('grpc://')) {
327
+ address = address.slice(7);
328
+ }
329
+ return new SochDBClient({ address, ...options });
330
+ }
331
+ // Alias for backwards compatibility
332
+ exports.GrpcClient = SochDBClient;
333
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JwYy1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZ3JwYy1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7O0dBT0c7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1aSCwwQkFLQztBQXRaRCxvREFBc0M7QUFDdEMsZ0VBQWtEO0FBQ2xELDJDQUE2QjtBQWtDN0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQWEsWUFBWTtJQUNmLE9BQU8sQ0FBUztJQUNoQixXQUFXLENBQTBCO0lBQ3JDLEtBQUssR0FBcUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNwQyxTQUFTLENBQVM7SUFDbEIsaUJBQWlCLENBQU07SUFDdkIsS0FBSyxDQUFNO0lBRW5CLFlBQVksVUFBK0IsRUFBRTtRQUMzQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksaUJBQWlCLENBQUM7UUFDcEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsTUFBTTtZQUMvQixDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUU7WUFDOUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLDBCQUEwQixDQUFDLENBQUM7UUFFdkYsd0JBQXdCO1FBQ3hCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDNUQsUUFBUSxFQUFFLEtBQUs7WUFDZixLQUFLLEVBQUUsTUFBTTtZQUNiLEtBQUssRUFBRSxNQUFNO1lBQ2IsUUFBUSxFQUFFLElBQUk7WUFDZCxNQUFNLEVBQUUsSUFBSTtTQUNiLENBQUMsQ0FBQztRQUNILE1B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O0lBQzFCLENBQUM7Q0FDRjtBQWxWRCxvQ0FrVkM7QUFFRDs7R0FFRztBQUNILFNBQWdCLE9BQU8sQ0FBQyxVQUFrQixpQkFBaUIsRUFBRSxVQUFnRCxFQUFFO0lBQzdHLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ2xDLE9BQU8sR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFDRCxPQUFPLElBQUksWUFBWSxDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUMsQ0FBQztBQUNuRCxDQUFDO0FBRUQsb0NBQW9DO0FBQ3ZCLFFBQUEsVUFBVSxHQUFHLFlBQVksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU29jaERCIGdSUEMgQ2xpZW50IC0gVGhpbiBTREsgV3JhcHBlclxuICpcbiAqIFRoaXMgbW9kdWxlIHByb3ZpZGVzIGEgdGhpbiBnUlBDIGNsaWVudCB3cmFwcGVyIGZvciB0aGUgU29jaERCIHNlcnZlci5cbiAqIEFsbCBidXNpbmVzcyBsb2dpYyBydW5zIG9uIHRoZSBzZXJ2ZXIgKFRoaWNrIFNlcnZlciAvIFRoaW4gQ2xpZW50IGFyY2hpdGVjdHVyZSkuXG4gKlxuICogVGhlIGNsaWVudCBpcyBhcHByb3hpbWF0ZWx5IH4yNTAgbGluZXMgb2YgY29kZSwgZGVsZWdhdGluZyBhbGwgb3BlcmF0aW9ucyB0byB0aGUgc2VydmVyLlxuICovXG5cbmltcG9ydCAqIGFzIGdycGMgZnJvbSAnQGdycGMvZ3JwYy1qcyc7XG5pbXBvcnQgKiBhcyBwcm90b0xvYWRlciBmcm9tICdAZ3JwYy9wcm90by1sb2FkZXInO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcblxuLy8gVHlwZXNcbmV4cG9ydCBpbnRlcmZhY2UgU2VhcmNoUmVzdWx0IHtcbiAgaWQ6IG51bWJlcjtcbiAgZGlzdGFuY2U6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEb2N1bWVudCB7XG4gIGlkOiBzdHJpbmc7XG4gIGNvbnRlbnQ6IHN0cmluZztcbiAgZW1iZWRkaW5nOiBudW1iZXJbXTtcbiAgbWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3JhcGhOb2RlIHtcbiAgaWQ6IHN0cmluZztcbiAgbm9kZVR5cGU6IHN0cmluZztcbiAgcHJvcGVydGllczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHcmFwaEVkZ2Uge1xuICBmcm9tSWQ6IHN0cmluZztcbiAgZWRnZVR5cGU6IHN0cmluZztcbiAgdG9JZDogc3RyaW5nO1xuICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNvY2hEQkNsaWVudE9wdGlvbnMge1xuICBhZGRyZXNzPzogc3RyaW5nO1xuICBzZWN1cmU/OiBib29sZWFuO1xuICBwcm90b1BhdGg/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhpbiBnUlBDIGNsaWVudCBmb3IgU29jaERCLlxuICpcbiAqIEFsbCBvcGVyYXRpb25zIGFyZSBkZWxlZ2F0ZWQgdG8gdGhlIFNvY2hEQiBnUlBDIHNlcnZlci5cbiAqIFRoaXMgY2xpZW50IHByb3ZpZGVzIGEgVHlwZVNjcmlwdCBpbnRlcmZhY2Ugb3ZlciB0aGUgZ1JQQyBwcm90b2NvbC5cbiAqXG4gKiBVc2FnZTpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGNsaWVudCA9IG5ldyBTb2NoREJDbGllbnQoeyBhZGRyZXNzOiAnbG9jYWxob3N0OjUwMDUxJyB9KTtcbiAqXG4gKiAvLyBDcmVhdGUgY29sbGVjdGlvblxuICogYXdhaXQgY2xpZW50LmNyZWF0ZUNvbGxlY3Rpb24oJ2RvY3MnLCB7IGRpbWVuc2lvbjogMzg0IH0pO1xuICpcbiAqIC8vIEFkZCBkb2N1bWVudHNcbiAqIGF3YWl0IGNsaWVudC5hZGREb2N1bWVudHMoJ2RvY3MnLCBbXG4gKiAgIHsgaWQ6ICcxJywgY29udGVudDogJ0hlbGxvJywgZW1iZWRkaW5nOiBbLi4uXSB9XG4gKiBdKTtcbiAqXG4gKiAvLyBTZWFyY2hcbiAqIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBjbGllbnQuc2VhcmNoKCdkb2NzJywgcXVlcnlWZWN0b3IsIDUpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTb2NoREJDbGllbnQge1xuICBwcml2YXRlIGFkZHJlc3M6IHN0cmluZztcbiAgcHJpdmF0ZSBjcmVkZW50aWFsczogZ3JwYy5DaGFubmVsQ3JlZGVudGlhbHM7XG4gIHByaXZhdGUgc3R1YnM6IE1hcDxzdHJpbmcsIGFueT4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgcHJvdG9QYXRoOiBzdHJpbmc7XG4gIHByaXZhdGUgcGFja2FnZURlZmluaXRpb246IGFueTtcbiAgcHJpdmF0ZSBwcm90bzogYW55O1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFNvY2hEQkNsaWVudE9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuYWRkcmVzcyA9IG9wdGlvbnMuYWRkcmVzcyB8fCAnbG9jYWxob3N0OjUwMDUxJztcbiAgICB0aGlzLmNyZWRlbnRpYWxzID0gb3B0aW9ucy5zZWN1cmVcbiAgICAgID8gZ3JwYy5jcmVkZW50aWFscy5jcmVhdGVTc2woKVxuICAgICAgOiBncnBjLmNyZWRlbnRpYWxzLmNyZWF0ZUluc2VjdXJlKCk7XG4gICAgdGhpcy5wcm90b1BhdGggPSBvcHRpb25zLnByb3RvUGF0aCB8fCBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vLi4vcHJvdG8vc29jaGRiLnByb3RvJyk7XG5cbiAgICAvLyBMb2FkIHByb3RvIGRlZmluaXRpb25cbiAgICB0aGlzLnBhY2thZ2VEZWZpbml0aW9uID0gcHJvdG9Mb2FkZXIubG9hZFN5bmModGhpcy5wcm90b1BhdGgsIHtcbiAgICAgIGtlZXBDYXNlOiBmYWxzZSxcbiAgICAgIGxvbmdzOiBTdHJpbmcsXG4gICAgICBlbnVtczogU3RyaW5nLFxuICAgICAgZGVmYXVsdHM6IHRydWUsXG4gICAgICBvbmVvZnM6IHRydWUsXG4gICAgfSk7XG4gICAgY29uc3QgbG9hZGVkUGFja2FnZSA9IGdycGMubG9hZFBhY2thZ2VEZWZpbml0aW9uKHRoaXMucGFja2FnZURlZmluaXRpb24pIGFzIGFueTtcbiAgICB0aGlzLnByb3RvID0gbG9hZGVkUGFja2FnZT8uc29jaGRiPy52MTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3R1YihzZXJ2aWNlTmFtZTogc3RyaW5nKTogYW55IHtcbiAgICBpZiAoIXRoaXMuc3R1YnMuaGFzKHNlcnZpY2VOYW1lKSkge1xuICAgICAgY29uc3QgU2VydmljZUNsYXNzID0gdGhpcy5wcm90bz8uW3NlcnZpY2VOYW1lXTtcbiAgICAgIGlmICghU2VydmljZUNsYXNzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgU2VydmljZSAke3NlcnZpY2VOYW1lfSBub3QgZm91bmQgaW4gcHJvdG8gZGVmaW5pdGlvbmApO1xuICAgICAgfVxuICAgICAgdGhpcy5zdHVicy5zZXQoc2VydmljZU5hbWUsIG5ldyBTZXJ2aWNlQ2xhc3ModGhpcy5hZGRyZXNzLCB0aGlzLmNyZWRlbnRpYWxzKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnN0dWJzLmdldChzZXJ2aWNlTmFtZSkhO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9taXNpZnk8VD4oc3R1YjogYW55LCBtZXRob2Q6IHN0cmluZywgcmVxdWVzdDogYW55KTogUHJvbWlzZTxUPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHN0dWJbbWV0aG9kXShyZXF1ZXN0LCAoZXJyb3I6IGFueSwgcmVzcG9uc2U6IFQpID0+IHtcbiAgICAgICAgaWYgKGVycm9yKSByZWplY3QoZXJyb3IpO1xuICAgICAgICBlbHNlIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2UgYWxsIGdSUEMgY29ubmVjdGlvbnMuXG4gICAqL1xuICBjbG9zZSgpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IHN0dWIgb2YgdGhpcy5zdHVicy52YWx1ZXMoKSkge1xuICAgICAgZ3JwYy5jbG9zZUNsaWVudChzdHViKTtcbiAgICB9XG4gICAgdGhpcy5zdHVicy5jbGVhcigpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFZlY3RvciBJbmRleCBPcGVyYXRpb25zIChWZWN0b3JJbmRleFNlcnZpY2UpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFzeW5jIGNyZWF0ZUluZGV4KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBkaW1lbnNpb246IG51bWJlcixcbiAgICBvcHRpb25zOiB7IG1ldHJpYz86IHN0cmluZzsgbT86IG51bWJlcjsgZWZDb25zdHJ1Y3Rpb24/OiBudW1iZXIgfSA9IHt9XG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ1ZlY3RvckluZGV4U2VydmljZScpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wcm9taXNpZnk8YW55PihzdHViLCAnY3JlYXRlSW5kZXgnLCB7XG4gICAgICBuYW1lLFxuICAgICAgZGltZW5zaW9uLFxuICAgICAgbWV0cmljOiBvcHRpb25zLm1ldHJpYyA9PT0gJ2wyJyA/IDEgOiBvcHRpb25zLm1ldHJpYyA9PT0gJ2RvdCcgPyAzIDogMixcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBtYXhDb25uZWN0aW9uczogb3B0aW9ucy5tIHx8IDE2LFxuICAgICAgICBlZkNvbnN0cnVjdGlvbjogb3B0aW9ucy5lZkNvbnN0cnVjdGlvbiB8fCAyMDAsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIHJldHVybiByZXNwb25zZS5zdWNjZXNzO1xuICB9XG5cbiAgYXN5bmMgaW5zZXJ0VmVjdG9ycyhcbiAgICBpbmRleE5hbWU6IHN0cmluZyxcbiAgICBpZHM6IG51bWJlcltdLFxuICAgIHZlY3RvcnM6IG51bWJlcltdW11cbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdWZWN0b3JJbmRleFNlcnZpY2UnKTtcbiAgICBjb25zdCBmbGF0VmVjdG9ycyA9IHZlY3RvcnMuZmxhdCgpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wcm9taXNpZnk8YW55PihzdHViLCAnaW5zZXJ0QmF0Y2gnLCB7XG4gICAgICBpbmRleE5hbWUsXG4gICAgICBpZHMsXG4gICAgICB2ZWN0b3JzOiBmbGF0VmVjdG9ycyxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2UuaW5zZXJ0ZWRDb3VudDtcbiAgfVxuXG4gIGFzeW5jIHNlYXJjaChcbiAgICBpbmRleE5hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogbnVtYmVyW10sXG4gICAgazogbnVtYmVyID0gMTAsXG4gICAgZWY6IG51bWJlciA9IDUwXG4gICk6IFByb21pc2U8U2VhcmNoUmVzdWx0W10+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdWZWN0b3JJbmRleFNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ3NlYXJjaCcsIHtcbiAgICAgIGluZGV4TmFtZSxcbiAgICAgIHF1ZXJ5LFxuICAgICAgayxcbiAgICAgIGVmLFxuICAgIH0pO1xuICAgIHJldHVybiAocmVzcG9uc2UucmVzdWx0cyB8fCBbXSkubWFwKChyOiBhbnkpID0+ICh7XG4gICAgICBpZDogTnVtYmVyKHIuaWQpLFxuICAgICAgZGlzdGFuY2U6IHIuZGlzdGFuY2UsXG4gICAgfSkpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIENvbGxlY3Rpb24gT3BlcmF0aW9ucyAoQ29sbGVjdGlvblNlcnZpY2UpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFzeW5jIGNyZWF0ZUNvbGxlY3Rpb24oXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IHsgZGltZW5zaW9uOiBudW1iZXI7IG5hbWVzcGFjZT86IHN0cmluZzsgbWV0cmljPzogc3RyaW5nIH1cbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignQ29sbGVjdGlvblNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ2NyZWF0ZUNvbGxlY3Rpb24nLCB7XG4gICAgICBuYW1lLFxuICAgICAgbmFtZXNwYWNlOiBvcHRpb25zLm5hbWVzcGFjZSB8fCAnZGVmYXVsdCcsXG4gICAgICBkaW1lbnNpb246IG9wdGlvbnMuZGltZW5zaW9uLFxuICAgICAgbWV0cmljOiBvcHRpb25zLm1ldHJpYyA9PT0gJ2wyJyA/IDEgOiBvcHRpb25zLm1ldHJpYyA9PT0gJ2RvdCcgPyAzIDogMixcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2Uuc3VjY2VzcztcbiAgfVxuXG4gIGFzeW5jIGFkZERvY3VtZW50cyhcbiAgICBjb2xsZWN0aW9uTmFtZTogc3RyaW5nLFxuICAgIGRvY3VtZW50czogQXJyYXk8e1xuICAgICAgaWQ/OiBzdHJpbmc7XG4gICAgICBjb250ZW50Pzogc3RyaW5nO1xuICAgICAgZW1iZWRkaW5nPzogbnVtYmVyW107XG4gICAgICBtZXRhZGF0YT86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgfT4sXG4gICAgbmFtZXNwYWNlOiBzdHJpbmcgPSAnZGVmYXVsdCdcbiAgKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ0NvbGxlY3Rpb25TZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdhZGREb2N1bWVudHMnLCB7XG4gICAgICBjb2xsZWN0aW9uTmFtZSxcbiAgICAgIG5hbWVzcGFjZSxcbiAgICAgIGRvY3VtZW50czogZG9jdW1lbnRzLm1hcCgoZCkgPT4gKHtcbiAgICAgICAgaWQ6IGQuaWQgfHwgJycsXG4gICAgICAgIGNvbnRlbnQ6IGQuY29udGVudCB8fCAnJyxcbiAgICAgICAgZW1iZWRkaW5nOiBkLmVtYmVkZGluZyB8fCBbXSxcbiAgICAgICAgbWV0YWRhdGE6IGQubWV0YWRhdGEgfHwge30sXG4gICAgICB9KSksXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmlkcyB8fCBbXTtcbiAgfVxuXG4gIGFzeW5jIHNlYXJjaENvbGxlY3Rpb24oXG4gICAgY29sbGVjdGlvbk5hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogbnVtYmVyW10sXG4gICAgazogbnVtYmVyID0gMTAsXG4gICAgb3B0aW9uczogeyBuYW1lc3BhY2U/OiBzdHJpbmc7IGZpbHRlcj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfSA9IHt9XG4gICk6IFByb21pc2U8RG9jdW1lbnRbXT4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ0NvbGxlY3Rpb25TZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdzZWFyY2hDb2xsZWN0aW9uJywge1xuICAgICAgY29sbGVjdGlvbk5hbWUsXG4gICAgICBuYW1lc3BhY2U6IG9wdGlvbnMubmFtZXNwYWNlIHx8ICdkZWZhdWx0JyxcbiAgICAgIHF1ZXJ5LFxuICAgICAgayxcbiAgICAgIGZpbHRlcjogb3B0aW9ucy5maWx0ZXIgfHwge30sXG4gICAgfSk7XG4gICAgcmV0dXJuIChyZXNwb25zZS5yZXN1bHRzIHx8IFtdKS5tYXAoKHI6IGFueSkgPT4gKHtcbiAgICAgIGlkOiByLmRvY3VtZW50LmlkLFxuICAgICAgY29udGVudDogci5kb2N1bWVudC5jb250ZW50LFxuICAgICAgZW1iZWRkaW5nOiByLmRvY3VtZW50LmVtYmVkZGluZyB8fCBbXSxcbiAgICAgIG1ldGFkYXRhOiByLmRvY3VtZW50Lm1ldGFkYXRhIHx8IHt9LFxuICAgIH0pKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBHcmFwaCBPcGVyYXRpb25zIChHcmFwaFNlcnZpY2UpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFzeW5jIGFkZE5vZGUoXG4gICAgbm9kZUlkOiBzdHJpbmcsXG4gICAgbm9kZVR5cGU6IHN0cmluZyxcbiAgICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge30sXG4gICAgbmFtZXNwYWNlOiBzdHJpbmcgPSAnZGVmYXVsdCdcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignR3JhcGhTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdhZGROb2RlJywge1xuICAgICAgbmFtZXNwYWNlLFxuICAgICAgbm9kZTogeyBpZDogbm9kZUlkLCBub2RlVHlwZSwgcHJvcGVydGllcyB9LFxuICAgIH0pO1xuICAgIHJldHVybiByZXNwb25zZS5zdWNjZXNzO1xuICB9XG5cbiAgYXN5bmMgYWRkRWRnZShcbiAgICBmcm9tSWQ6IHN0cmluZyxcbiAgICBlZGdlVHlwZTogc3RyaW5nLFxuICAgIHRvSWQ6IHN0cmluZyxcbiAgICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge30sXG4gICAgbmFtZXNwYWNlOiBzdHJpbmcgPSAnZGVmYXVsdCdcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignR3JhcGhTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdhZGRFZGdlJywge1xuICAgICAgbmFtZXNwYWNlLFxuICAgICAgZWRnZTogeyBmcm9tSWQsIGVkZ2VUeXBlLCB0b0lkLCBwcm9wZXJ0aWVzIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLnN1Y2Nlc3M7XG4gIH1cblxuICBhc3luYyB0cmF2ZXJzZShcbiAgICBzdGFydE5vZGU6IHN0cmluZyxcbiAgICBvcHRpb25zOiB7IG1heERlcHRoPzogbnVtYmVyOyBvcmRlcj86ICdiZnMnIHwgJ2Rmcyc7IG5hbWVzcGFjZT86IHN0cmluZyB9ID0ge31cbiAgKTogUHJvbWlzZTx7IG5vZGVzOiBHcmFwaE5vZGVbXTsgZWRnZXM6IEdyYXBoRWRnZVtdIH0+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdHcmFwaFNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ3RyYXZlcnNlJywge1xuICAgICAgbmFtZXNwYWNlOiBvcHRpb25zLm5hbWVzcGFjZSB8fCAnZGVmYXVsdCcsXG4gICAgICBzdGFydE5vZGVJZDogc3RhcnROb2RlLFxuICAgICAgb3JkZXI6IG9wdGlvbnMub3JkZXIgPT09ICdkZnMnID8gMSA6IDAsXG4gICAgICBtYXhEZXB0aDogb3B0aW9ucy5tYXhEZXB0aCB8fCAxMCxcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgbm9kZXM6IChyZXNwb25zZS5ub2RlcyB8fCBbXSkubWFwKChuOiBhbnkpID0+ICh7XG4gICAgICAgIGlkOiBuLmlkLFxuICAgICAgICBub2RlVHlwZTogbi5ub2RlVHlwZSxcbiAgICAgICAgcHJvcGVydGllczogbi5wcm9wZXJ0aWVzIHx8IHt9LFxuICAgICAgfSkpLFxuICAgICAgZWRnZXM6IChyZXNwb25zZS5lZGdlcyB8fCBbXSkubWFwKChlOiBhbnkpID0+ICh7XG4gICAgICAgIGZyb21JZDogZS5mcm9tSWQsXG4gICAgICAgIGVkZ2VUeXBlOiBlLmVkZ2VUeXBlLFxuICAgICAgICB0b0lkOiBlLnRvSWQsXG4gICAgICAgIHByb3BlcnRpZXM6IGUucHJvcGVydGllcyB8fCB7fSxcbiAgICAgIH0pKSxcbiAgICB9O1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFNlbWFudGljIENhY2hlIE9wZXJhdGlvbnMgKFNlbWFudGljQ2FjaGVTZXJ2aWNlKVxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBhc3luYyBjYWNoZUdldChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBxdWVyeUVtYmVkZGluZzogbnVtYmVyW10sXG4gICAgdGhyZXNob2xkOiBudW1iZXIgPSAwLjg1XG4gICk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ1NlbWFudGljQ2FjaGVTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdnZXQnLCB7XG4gICAgICBjYWNoZU5hbWUsXG4gICAgICBxdWVyeUVtYmVkZGluZyxcbiAgICAgIHNpbWlsYXJpdHlUaHJlc2hvbGQ6IHRocmVzaG9sZCxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2UuaGl0ID8gcmVzcG9uc2UuY2FjaGVkVmFsdWUgOiBudWxsO1xuICB9XG5cbiAgYXN5bmMgY2FjaGVQdXQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyxcbiAgICBrZXlFbWJlZGRpbmc6IG51bWJlcltdLFxuICAgIHR0bFNlY29uZHM6IG51bWJlciA9IDBcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignU2VtYW50aWNDYWNoZVNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ3B1dCcsIHtcbiAgICAgIGNhY2hlTmFtZSxcbiAgICAgIGtleSxcbiAgICAgIHZhbHVlLFxuICAgICAga2V5RW1iZWRkaW5nLFxuICAgICAgdHRsU2Vjb25kcyxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2Uuc3VjY2VzcztcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBUcmFjZSBPcGVyYXRpb25zIChUcmFjZVNlcnZpY2UpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFzeW5jIHN0YXJ0VHJhY2UobmFtZTogc3RyaW5nKTogUHJvbWlzZTx7IHRyYWNlSWQ6IHN0cmluZzsgcm9vdFNwYW5JZDogc3RyaW5nIH0+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdUcmFjZVNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ3N0YXJ0VHJhY2UnLCB7IG5hbWUgfSk7XG4gICAgcmV0dXJuIHsgdHJhY2VJZDogcmVzcG9uc2UudHJhY2VJZCwgcm9vdFNwYW5JZDogcmVzcG9uc2Uucm9vdFNwYW5JZCB9O1xuICB9XG5cbiAgYXN5bmMgc3RhcnRTcGFuKHRyYWNlSWQ6IHN0cmluZywgcGFyZW50U3BhbklkOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignVHJhY2VTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdzdGFydFNwYW4nLCB7XG4gICAgICB0cmFjZUlkLFxuICAgICAgcGFyZW50U3BhbklkLFxuICAgICAgbmFtZSxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2Uuc3BhbklkO1xuICB9XG5cbiAgYXN5bmMgZW5kU3BhbihcbiAgICB0cmFjZUlkOiBzdHJpbmcsXG4gICAgc3BhbklkOiBzdHJpbmcsXG4gICAgc3RhdHVzOiAnb2snIHwgJ2Vycm9yJyB8ICd1bnNldCcgPSAnb2snXG4gICk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignVHJhY2VTZXJ2aWNlJyk7XG4gICAgY29uc3Qgc3RhdHVzTWFwID0geyB1bnNldDogMCwgb2s6IDEsIGVycm9yOiAyIH07XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdlbmRTcGFuJywge1xuICAgICAgdHJhY2VJZCxcbiAgICAgIHNwYW5JZCxcbiAgICAgIHN0YXR1czogc3RhdHVzTWFwW3N0YXR1c10sXG4gICAgfSk7XG4gICAgcmV0dXJuIE51bWJlcihyZXNwb25zZS5kdXJhdGlvblVzKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBLViBPcGVyYXRpb25zIChLdlNlcnZpY2UpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFzeW5jIGdldChrZXk6IEJ1ZmZlciwgbmFtZXNwYWNlOiBzdHJpbmcgPSAnZGVmYXVsdCcpOiBQcm9taXNlPEJ1ZmZlciB8IG51bGw+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdLdlNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ2dldCcsIHsgbmFtZXNwYWNlLCBrZXkgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLmZvdW5kID8gQnVmZmVyLmZyb20ocmVzcG9uc2UudmFsdWUpIDogbnVsbDtcbiAgfVxuXG4gIGFzeW5jIHB1dChcbiAgICBrZXk6IEJ1ZmZlcixcbiAgICB2YWx1ZTogQnVmZmVyLFxuICAgIG5hbWVzcGFjZTogc3RyaW5nID0gJ2RlZmF1bHQnLFxuICAgIHR0bFNlY29uZHM6IG51bWJlciA9IDBcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignS3ZTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdwdXQnLCB7XG4gICAgICBuYW1lc3BhY2UsXG4gICAgICBrZXksXG4gICAgICB2YWx1ZSxcbiAgICAgIHR0bFNlY29uZHMsXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLnN1Y2Nlc3M7XG4gIH1cblxuICBhc3luYyBkZWxldGUoa2V5OiBCdWZmZXIsIG5hbWVzcGFjZTogc3RyaW5nID0gJ2RlZmF1bHQnKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignS3ZTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdkZWxldGUnLCB7IG5hbWVzcGFjZSwga2V5IH0pO1xuICAgIHJldHVybiByZXNwb25zZS5zdWNjZXNzO1xuICB9XG59XG5cbi8qKlxuICogQ29ubmVjdCB0byBTb2NoREIgZ1JQQyBzZXJ2ZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25uZWN0KGFkZHJlc3M6IHN0cmluZyA9ICdsb2NhbGhvc3Q6NTAwNTEnLCBvcHRpb25zOiBPbWl0PFNvY2hEQkNsaWVudE9wdGlvbnMsICdhZGRyZXNzJz4gPSB7fSk6IFNvY2hEQkNsaWVudCB7XG4gIGlmIChhZGRyZXNzLnN0YXJ0c1dpdGgoJ2dycGM6Ly8nKSkge1xuICAgIGFkZHJlc3MgPSBhZGRyZXNzLnNsaWNlKDcpO1xuICB9XG4gIHJldHVybiBuZXcgU29jaERCQ2xpZW50KHsgYWRkcmVzcywgLi4ub3B0aW9ucyB9KTtcbn1cblxuLy8gQWxpYXMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5leHBvcnQgY29uc3QgR3JwY0NsaWVudCA9IFNvY2hEQkNsaWVudDtcbiJdfQ==
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ /**
3
+ * SochDB Node.js SDK v0.4.0
4
+ *
5
+ * Dual-mode architecture: Embedded (FFI) + Server (gRPC/IPC)
6
+ *
7
+ * Architecture: Flexible Deployment
8
+ * ==================================
9
+ * This SDK supports BOTH modes:
10
+ *
11
+ * 1. Embedded Mode (FFI) - For single-process apps:
12
+ * - Direct FFI bindings to Rust libraries
13
+ * - No server required - just npm install and run
14
+ * - Best for: Local development, simple apps
15
+ *
16
+ * 2. Server Mode (gRPC/IPC) - For distributed systems:
17
+ * - Thin client connecting to sochdb-grpc server
18
+ * - Best for: Production, multi-language, scalability
19
+ *
20
+ * @example Embedded Mode
21
+ * ```typescript
22
+ * import { Database } from '@sochdb/sochdb';
23
+ *
24
+ * // Direct FFI - no server needed
25
+ * const db = await Database.open('./mydb');
26
+ * await db.put(Buffer.from('key'), Buffer.from('value'));
27
+ * await db.close();
28
+ * ```
29
+ *
30
+ * @example Server Mode
31
+ * ```typescript
32
+ * import { SochDBClient } from '@sochdb/sochdb';
33
+ *
34
+ * // Connect to server
35
+ * const client = new SochDBClient({ address: 'localhost:50051' });
36
+ * await client.putKv('key', Buffer.from('value'));
37
+ * ```
38
+ */
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.GrpcClient = exports.DatabaseError = exports.ProtocolError = exports.TransactionError = exports.ConnectionError = exports.SochDBError = exports.Query = exports.FormatConversionError = exports.FormatCapabilities = exports.CanonicalFormat = exports.ContextFormat = exports.WireFormat = exports.IpcClient = exports.SochDBClient = exports.Database = exports.EmbeddedTransaction = exports.EmbeddedDatabase = exports.VERSION = void 0;
41
+ // Version
42
+ exports.VERSION = '0.4.0';
43
+ // Embedded mode (FFI) - NEW
44
+ var embedded_1 = require("./embedded");
45
+ Object.defineProperty(exports, "EmbeddedDatabase", { enumerable: true, get: function () { return embedded_1.EmbeddedDatabase; } });
46
+ var embedded_2 = require("./embedded");
47
+ Object.defineProperty(exports, "EmbeddedTransaction", { enumerable: true, get: function () { return embedded_2.EmbeddedTransaction; } });
48
+ // Embedded mode (FFI) - Convenience alias
49
+ var embedded_3 = require("./embedded");
50
+ Object.defineProperty(exports, "Database", { enumerable: true, get: function () { return embedded_3.EmbeddedDatabase; } });
51
+ // Server mode (gRPC/IPC)
52
+ var grpc_client_1 = require("./grpc-client");
53
+ Object.defineProperty(exports, "SochDBClient", { enumerable: true, get: function () { return grpc_client_1.SochDBClient; } });
54
+ var ipc_client_1 = require("./ipc-client");
55
+ Object.defineProperty(exports, "IpcClient", { enumerable: true, get: function () { return ipc_client_1.IpcClient; } });
56
+ // Format utilities
57
+ var format_1 = require("./format");
58
+ Object.defineProperty(exports, "WireFormat", { enumerable: true, get: function () { return format_1.WireFormat; } });
59
+ Object.defineProperty(exports, "ContextFormat", { enumerable: true, get: function () { return format_1.ContextFormat; } });
60
+ Object.defineProperty(exports, "CanonicalFormat", { enumerable: true, get: function () { return format_1.CanonicalFormat; } });
61
+ Object.defineProperty(exports, "FormatCapabilities", { enumerable: true, get: function () { return format_1.FormatCapabilities; } });
62
+ Object.defineProperty(exports, "FormatConversionError", { enumerable: true, get: function () { return format_1.FormatConversionError; } });
63
+ // Type definitions
64
+ var query_1 = require("./query");
65
+ Object.defineProperty(exports, "Query", { enumerable: true, get: function () { return query_1.Query; } });
66
+ var errors_1 = require("./errors");
67
+ Object.defineProperty(exports, "SochDBError", { enumerable: true, get: function () { return errors_1.SochDBError; } });
68
+ Object.defineProperty(exports, "ConnectionError", { enumerable: true, get: function () { return errors_1.ConnectionError; } });
69
+ Object.defineProperty(exports, "TransactionError", { enumerable: true, get: function () { return errors_1.TransactionError; } });
70
+ Object.defineProperty(exports, "ProtocolError", { enumerable: true, get: function () { return errors_1.ProtocolError; } });
71
+ Object.defineProperty(exports, "DatabaseError", { enumerable: true, get: function () { return errors_1.DatabaseError; } });
72
+ // Convenience alias
73
+ var grpc_client_2 = require("./grpc-client");
74
+ Object.defineProperty(exports, "GrpcClient", { enumerable: true, get: function () { return grpc_client_2.SochDBClient; } });
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQ0c7OztBQUVILFVBQVU7QUFDRyxRQUFBLE9BQU8sR0FBRyxPQUFPLENBQUM7QUFFL0IsNEJBQTRCO0FBQzVCLHVDQUFzRTtBQUE3RCw0R0FBQSxnQkFBZ0IsT0FBQTtBQUN6Qix1Q0FBaUQ7QUFBeEMsK0dBQUEsbUJBQW1CLE9BQUE7QUFFNUIsMENBQTBDO0FBQzFDLHVDQUEwRDtBQUFqRCxvR0FBQSxnQkFBZ0IsT0FBWTtBQUVyQyx5QkFBeUI7QUFDekIsNkNBQTZDO0FBQXBDLDJHQUFBLFlBQVksT0FBQTtBQVFyQiwyQ0FBeUM7QUFBaEMsdUdBQUEsU0FBUyxPQUFBO0FBRWxCLG1CQUFtQjtBQUNuQixtQ0FNa0I7QUFMaEIsb0dBQUEsVUFBVSxPQUFBO0FBQ1YsdUdBQUEsYUFBYSxPQUFBO0FBQ2IseUdBQUEsZUFBZSxPQUFBO0FBQ2YsNEdBQUEsa0JBQWtCLE9BQUE7QUFDbEIsK0dBQUEscUJBQXFCLE9BQUE7QUFHdkIsbUJBQW1CO0FBQ25CLGlDQUFnQztBQUF2Qiw4RkFBQSxLQUFLLE9BQUE7QUFHZCxtQ0FNa0I7QUFMaEIscUdBQUEsV0FBVyxPQUFBO0FBQ1gseUdBQUEsZUFBZSxPQUFBO0FBQ2YsMEdBQUEsZ0JBQWdCLE9BQUE7QUFDaEIsdUdBQUEsYUFBYSxPQUFBO0FBQ2IsdUdBQUEsYUFBYSxPQUFBO0FBR2Ysb0JBQW9CO0FBQ3BCLDZDQUEyRDtBQUFsRCx5R0FBQSxZQUFZLE9BQWMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNvY2hEQiBOb2RlLmpzIFNESyB2MC40LjBcbiAqIFxuICogRHVhbC1tb2RlIGFyY2hpdGVjdHVyZTogRW1iZWRkZWQgKEZGSSkgKyBTZXJ2ZXIgKGdSUEMvSVBDKVxuICogXG4gKiBBcmNoaXRlY3R1cmU6IEZsZXhpYmxlIERlcGxveW1lbnRcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFRoaXMgU0RLIHN1cHBvcnRzIEJPVEggbW9kZXM6XG4gKiBcbiAqIDEuIEVtYmVkZGVkIE1vZGUgKEZGSSkgLSBGb3Igc2luZ2xlLXByb2Nlc3MgYXBwczpcbiAqICAgIC0gRGlyZWN0IEZGSSBiaW5kaW5ncyB0byBSdXN0IGxpYnJhcmllc1xuICogICAgLSBObyBzZXJ2ZXIgcmVxdWlyZWQgLSBqdXN0IG5wbSBpbnN0YWxsIGFuZCBydW5cbiAqICAgIC0gQmVzdCBmb3I6IExvY2FsIGRldmVsb3BtZW50LCBzaW1wbGUgYXBwc1xuICogXG4gKiAyLiBTZXJ2ZXIgTW9kZSAoZ1JQQy9JUEMpIC0gRm9yIGRpc3RyaWJ1dGVkIHN5c3RlbXM6XG4gKiAgICAtIFRoaW4gY2xpZW50IGNvbm5lY3RpbmcgdG8gc29jaGRiLWdycGMgc2VydmVyXG4gKiAgICAtIEJlc3QgZm9yOiBQcm9kdWN0aW9uLCBtdWx0aS1sYW5ndWFnZSwgc2NhbGFiaWxpdHlcbiAqIFxuICogQGV4YW1wbGUgRW1iZWRkZWQgTW9kZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgRGF0YWJhc2UgfSBmcm9tICdAc29jaGRiL3NvY2hkYic7XG4gKiBcbiAqIC8vIERpcmVjdCBGRkkgLSBubyBzZXJ2ZXIgbmVlZGVkXG4gKiBjb25zdCBkYiA9IGF3YWl0IERhdGFiYXNlLm9wZW4oJy4vbXlkYicpO1xuICogYXdhaXQgZGIucHV0KEJ1ZmZlci5mcm9tKCdrZXknKSwgQnVmZmVyLmZyb20oJ3ZhbHVlJykpO1xuICogYXdhaXQgZGIuY2xvc2UoKTtcbiAqIGBgYFxuICogXG4gKiBAZXhhbXBsZSBTZXJ2ZXIgTW9kZVxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgU29jaERCQ2xpZW50IH0gZnJvbSAnQHNvY2hkYi9zb2NoZGInO1xuICogXG4gKiAvLyBDb25uZWN0IHRvIHNlcnZlclxuICogY29uc3QgY2xpZW50ID0gbmV3IFNvY2hEQkNsaWVudCh7IGFkZHJlc3M6ICdsb2NhbGhvc3Q6NTAwNTEnIH0pO1xuICogYXdhaXQgY2xpZW50LnB1dEt2KCdrZXknLCBCdWZmZXIuZnJvbSgndmFsdWUnKSk7XG4gKiBgYGBcbiAqL1xuXG4vLyBWZXJzaW9uXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9ICcwLjQuMCc7XG5cbi8vIEVtYmVkZGVkIG1vZGUgKEZGSSkgLSBORVdcbmV4cG9ydCB7IEVtYmVkZGVkRGF0YWJhc2UsIEVtYmVkZGVkRGF0YWJhc2VDb25maWcgfSBmcm9tICcuL2VtYmVkZGVkJztcbmV4cG9ydCB7IEVtYmVkZGVkVHJhbnNhY3Rpb24gfSBmcm9tICcuL2VtYmVkZGVkJztcblxuLy8gRW1iZWRkZWQgbW9kZSAoRkZJKSAtIENvbnZlbmllbmNlIGFsaWFzXG5leHBvcnQgeyBFbWJlZGRlZERhdGFiYXNlIGFzIERhdGFiYXNlIH0gZnJvbSAnLi9lbWJlZGRlZCc7XG5cbi8vIFNlcnZlciBtb2RlIChnUlBDL0lQQylcbmV4cG9ydCB7IFNvY2hEQkNsaWVudCB9IGZyb20gJy4vZ3JwYy1jbGllbnQnO1xuZXhwb3J0IHR5cGUge1xuICBTZWFyY2hSZXN1bHQsXG4gIERvY3VtZW50LFxuICBHcmFwaE5vZGUsXG4gIEdyYXBoRWRnZSxcbn0gZnJvbSAnLi9ncnBjLWNsaWVudCc7XG5cbmV4cG9ydCB7IElwY0NsaWVudCB9IGZyb20gJy4vaXBjLWNsaWVudCc7XG5cbi8vIEZvcm1hdCB1dGlsaXRpZXNcbmV4cG9ydCB7XG4gIFdpcmVGb3JtYXQsXG4gIENvbnRleHRGb3JtYXQsXG4gIENhbm9uaWNhbEZvcm1hdCxcbiAgRm9ybWF0Q2FwYWJpbGl0aWVzLFxuICBGb3JtYXRDb252ZXJzaW9uRXJyb3IsXG59IGZyb20gJy4vZm9ybWF0JztcblxuLy8gVHlwZSBkZWZpbml0aW9uc1xuZXhwb3J0IHsgUXVlcnkgfSBmcm9tICcuL3F1ZXJ5JztcbmV4cG9ydCB0eXBlIHsgUXVlcnlSZXN1bHQgfSBmcm9tICcuL3F1ZXJ5JztcblxuZXhwb3J0IHtcbiAgU29jaERCRXJyb3IsXG4gIENvbm5lY3Rpb25FcnJvcixcbiAgVHJhbnNhY3Rpb25FcnJvcixcbiAgUHJvdG9jb2xFcnJvcixcbiAgRGF0YWJhc2VFcnJvcixcbn0gZnJvbSAnLi9lcnJvcnMnO1xuXG4vLyBDb252ZW5pZW5jZSBhbGlhc1xuZXhwb3J0IHsgU29jaERCQ2xpZW50IGFzIEdycGNDbGllbnQgfSBmcm9tICcuL2dycGMtY2xpZW50JztcbiJdfQ==