@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.
- package/LICENSE +201 -0
- package/README.md +3349 -0
- package/_bin/aarch64-apple-darwin/libsochdb_storage.dylib +0 -0
- package/_bin/aarch64-apple-darwin/sochdb-bulk +0 -0
- package/_bin/aarch64-apple-darwin/sochdb-grpc-server +0 -0
- package/_bin/aarch64-apple-darwin/sochdb-server +0 -0
- package/_bin/x86_64-pc-windows-msvc/sochdb-bulk.exe +0 -0
- package/_bin/x86_64-pc-windows-msvc/sochdb-grpc-server.exe +0 -0
- package/_bin/x86_64-pc-windows-msvc/sochdb_storage.dll +0 -0
- package/_bin/x86_64-unknown-linux-gnu/libsochdb_storage.so +0 -0
- package/_bin/x86_64-unknown-linux-gnu/sochdb-bulk +0 -0
- package/_bin/x86_64-unknown-linux-gnu/sochdb-grpc-server +0 -0
- package/_bin/x86_64-unknown-linux-gnu/sochdb-server +0 -0
- package/bin/sochdb-bulk.js +80 -0
- package/bin/sochdb-grpc-server.js +80 -0
- package/bin/sochdb-server.js +84 -0
- package/dist/cjs/analytics.js +196 -0
- package/dist/cjs/database.js +929 -0
- package/dist/cjs/embedded/database.js +236 -0
- package/dist/cjs/embedded/ffi/bindings.js +113 -0
- package/dist/cjs/embedded/ffi/library-finder.js +135 -0
- package/dist/cjs/embedded/index.js +14 -0
- package/dist/cjs/embedded/transaction.js +172 -0
- package/dist/cjs/errors.js +71 -0
- package/dist/cjs/format.js +176 -0
- package/dist/cjs/grpc-client.js +328 -0
- package/dist/cjs/index.js +75 -0
- package/dist/cjs/ipc-client.js +504 -0
- package/dist/cjs/query.js +154 -0
- package/dist/cjs/server-manager.js +295 -0
- package/dist/cjs/sql-engine.js +874 -0
- package/dist/esm/analytics.js +196 -0
- package/dist/esm/database.js +931 -0
- package/dist/esm/embedded/database.js +239 -0
- package/dist/esm/embedded/ffi/bindings.js +142 -0
- package/dist/esm/embedded/ffi/library-finder.js +135 -0
- package/dist/esm/embedded/index.js +14 -0
- package/dist/esm/embedded/transaction.js +176 -0
- package/dist/esm/errors.js +71 -0
- package/dist/esm/format.js +179 -0
- package/dist/esm/grpc-client.js +333 -0
- package/dist/esm/index.js +75 -0
- package/dist/esm/ipc-client.js +505 -0
- package/dist/esm/query.js +159 -0
- package/dist/esm/server-manager.js +295 -0
- package/dist/esm/sql-engine.js +875 -0
- package/dist/types/analytics.d.ts +66 -0
- package/dist/types/analytics.d.ts.map +1 -0
- package/dist/types/database.d.ts +523 -0
- package/dist/types/database.d.ts.map +1 -0
- package/dist/types/embedded/database.d.ts +105 -0
- package/dist/types/embedded/database.d.ts.map +1 -0
- package/dist/types/embedded/ffi/bindings.d.ts +24 -0
- package/dist/types/embedded/ffi/bindings.d.ts.map +1 -0
- package/dist/types/embedded/ffi/library-finder.d.ts +17 -0
- package/dist/types/embedded/ffi/library-finder.d.ts.map +1 -0
- package/dist/types/embedded/index.d.ts +9 -0
- package/dist/types/embedded/index.d.ts.map +1 -0
- package/dist/types/embedded/transaction.d.ts +21 -0
- package/dist/types/embedded/transaction.d.ts.map +1 -0
- package/dist/types/errors.d.ts +36 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/format.d.ts +117 -0
- package/dist/types/format.d.ts.map +1 -0
- package/dist/types/grpc-client.d.ts +120 -0
- package/dist/types/grpc-client.d.ts.map +1 -0
- package/dist/types/index.d.ts +50 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/ipc-client.d.ts +177 -0
- package/dist/types/ipc-client.d.ts.map +1 -0
- package/dist/types/query.d.ts +85 -0
- package/dist/types/query.d.ts.map +1 -0
- package/dist/types/server-manager.d.ts +29 -0
- package/dist/types/server-manager.d.ts.map +1 -0
- package/dist/types/sql-engine.d.ts +100 -0
- package/dist/types/sql-engine.d.ts.map +1 -0
- package/package.json +90 -0
- package/scripts/postinstall.js +50 -0
|
@@ -0,0 +1,328 @@
|
|
|
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
|
+
constructor(options = {}) {
|
|
73
|
+
this.stubs = new Map();
|
|
74
|
+
this.address = options.address || 'localhost:50051';
|
|
75
|
+
this.credentials = options.secure
|
|
76
|
+
? grpc.credentials.createSsl()
|
|
77
|
+
: grpc.credentials.createInsecure();
|
|
78
|
+
this.protoPath = options.protoPath || path.join(__dirname, '../../proto/sochdb.proto');
|
|
79
|
+
// Load proto definition
|
|
80
|
+
this.packageDefinition = protoLoader.loadSync(this.protoPath, {
|
|
81
|
+
keepCase: false,
|
|
82
|
+
longs: String,
|
|
83
|
+
enums: String,
|
|
84
|
+
defaults: true,
|
|
85
|
+
oneofs: true,
|
|
86
|
+
});
|
|
87
|
+
const loadedPackage = grpc.loadPackageDefinition(this.packageDefinition);
|
|
88
|
+
this.proto = loadedPackage?.sochdb?.v1;
|
|
89
|
+
}
|
|
90
|
+
getStub(serviceName) {
|
|
91
|
+
if (!this.stubs.has(serviceName)) {
|
|
92
|
+
const ServiceClass = this.proto?.[serviceName];
|
|
93
|
+
if (!ServiceClass) {
|
|
94
|
+
throw new Error(`Service ${serviceName} not found in proto definition`);
|
|
95
|
+
}
|
|
96
|
+
this.stubs.set(serviceName, new ServiceClass(this.address, this.credentials));
|
|
97
|
+
}
|
|
98
|
+
return this.stubs.get(serviceName);
|
|
99
|
+
}
|
|
100
|
+
promisify(stub, method, request) {
|
|
101
|
+
return new Promise((resolve, reject) => {
|
|
102
|
+
stub[method](request, (error, response) => {
|
|
103
|
+
if (error)
|
|
104
|
+
reject(error);
|
|
105
|
+
else
|
|
106
|
+
resolve(response);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Close all gRPC connections.
|
|
112
|
+
*/
|
|
113
|
+
close() {
|
|
114
|
+
for (const stub of this.stubs.values()) {
|
|
115
|
+
grpc.closeClient(stub);
|
|
116
|
+
}
|
|
117
|
+
this.stubs.clear();
|
|
118
|
+
}
|
|
119
|
+
// ===========================================================================
|
|
120
|
+
// Vector Index Operations (VectorIndexService)
|
|
121
|
+
// ===========================================================================
|
|
122
|
+
async createIndex(name, dimension, options = {}) {
|
|
123
|
+
const stub = this.getStub('VectorIndexService');
|
|
124
|
+
const response = await this.promisify(stub, 'createIndex', {
|
|
125
|
+
name,
|
|
126
|
+
dimension,
|
|
127
|
+
metric: options.metric === 'l2' ? 1 : options.metric === 'dot' ? 3 : 2,
|
|
128
|
+
config: {
|
|
129
|
+
maxConnections: options.m || 16,
|
|
130
|
+
efConstruction: options.efConstruction || 200,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
return response.success;
|
|
134
|
+
}
|
|
135
|
+
async insertVectors(indexName, ids, vectors) {
|
|
136
|
+
const stub = this.getStub('VectorIndexService');
|
|
137
|
+
const flatVectors = vectors.flat();
|
|
138
|
+
const response = await this.promisify(stub, 'insertBatch', {
|
|
139
|
+
indexName,
|
|
140
|
+
ids,
|
|
141
|
+
vectors: flatVectors,
|
|
142
|
+
});
|
|
143
|
+
return response.insertedCount;
|
|
144
|
+
}
|
|
145
|
+
async search(indexName, query, k = 10, ef = 50) {
|
|
146
|
+
const stub = this.getStub('VectorIndexService');
|
|
147
|
+
const response = await this.promisify(stub, 'search', {
|
|
148
|
+
indexName,
|
|
149
|
+
query,
|
|
150
|
+
k,
|
|
151
|
+
ef,
|
|
152
|
+
});
|
|
153
|
+
return (response.results || []).map((r) => ({
|
|
154
|
+
id: Number(r.id),
|
|
155
|
+
distance: r.distance,
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
// ===========================================================================
|
|
159
|
+
// Collection Operations (CollectionService)
|
|
160
|
+
// ===========================================================================
|
|
161
|
+
async createCollection(name, options) {
|
|
162
|
+
const stub = this.getStub('CollectionService');
|
|
163
|
+
const response = await this.promisify(stub, 'createCollection', {
|
|
164
|
+
name,
|
|
165
|
+
namespace: options.namespace || 'default',
|
|
166
|
+
dimension: options.dimension,
|
|
167
|
+
metric: options.metric === 'l2' ? 1 : options.metric === 'dot' ? 3 : 2,
|
|
168
|
+
});
|
|
169
|
+
return response.success;
|
|
170
|
+
}
|
|
171
|
+
async addDocuments(collectionName, documents, namespace = 'default') {
|
|
172
|
+
const stub = this.getStub('CollectionService');
|
|
173
|
+
const response = await this.promisify(stub, 'addDocuments', {
|
|
174
|
+
collectionName,
|
|
175
|
+
namespace,
|
|
176
|
+
documents: documents.map((d) => ({
|
|
177
|
+
id: d.id || '',
|
|
178
|
+
content: d.content || '',
|
|
179
|
+
embedding: d.embedding || [],
|
|
180
|
+
metadata: d.metadata || {},
|
|
181
|
+
})),
|
|
182
|
+
});
|
|
183
|
+
return response.ids || [];
|
|
184
|
+
}
|
|
185
|
+
async searchCollection(collectionName, query, k = 10, options = {}) {
|
|
186
|
+
const stub = this.getStub('CollectionService');
|
|
187
|
+
const response = await this.promisify(stub, 'searchCollection', {
|
|
188
|
+
collectionName,
|
|
189
|
+
namespace: options.namespace || 'default',
|
|
190
|
+
query,
|
|
191
|
+
k,
|
|
192
|
+
filter: options.filter || {},
|
|
193
|
+
});
|
|
194
|
+
return (response.results || []).map((r) => ({
|
|
195
|
+
id: r.document.id,
|
|
196
|
+
content: r.document.content,
|
|
197
|
+
embedding: r.document.embedding || [],
|
|
198
|
+
metadata: r.document.metadata || {},
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
// ===========================================================================
|
|
202
|
+
// Graph Operations (GraphService)
|
|
203
|
+
// ===========================================================================
|
|
204
|
+
async addNode(nodeId, nodeType, properties = {}, namespace = 'default') {
|
|
205
|
+
const stub = this.getStub('GraphService');
|
|
206
|
+
const response = await this.promisify(stub, 'addNode', {
|
|
207
|
+
namespace,
|
|
208
|
+
node: { id: nodeId, nodeType, properties },
|
|
209
|
+
});
|
|
210
|
+
return response.success;
|
|
211
|
+
}
|
|
212
|
+
async addEdge(fromId, edgeType, toId, properties = {}, namespace = 'default') {
|
|
213
|
+
const stub = this.getStub('GraphService');
|
|
214
|
+
const response = await this.promisify(stub, 'addEdge', {
|
|
215
|
+
namespace,
|
|
216
|
+
edge: { fromId, edgeType, toId, properties },
|
|
217
|
+
});
|
|
218
|
+
return response.success;
|
|
219
|
+
}
|
|
220
|
+
async traverse(startNode, options = {}) {
|
|
221
|
+
const stub = this.getStub('GraphService');
|
|
222
|
+
const response = await this.promisify(stub, 'traverse', {
|
|
223
|
+
namespace: options.namespace || 'default',
|
|
224
|
+
startNodeId: startNode,
|
|
225
|
+
order: options.order === 'dfs' ? 1 : 0,
|
|
226
|
+
maxDepth: options.maxDepth || 10,
|
|
227
|
+
});
|
|
228
|
+
return {
|
|
229
|
+
nodes: (response.nodes || []).map((n) => ({
|
|
230
|
+
id: n.id,
|
|
231
|
+
nodeType: n.nodeType,
|
|
232
|
+
properties: n.properties || {},
|
|
233
|
+
})),
|
|
234
|
+
edges: (response.edges || []).map((e) => ({
|
|
235
|
+
fromId: e.fromId,
|
|
236
|
+
edgeType: e.edgeType,
|
|
237
|
+
toId: e.toId,
|
|
238
|
+
properties: e.properties || {},
|
|
239
|
+
})),
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
// ===========================================================================
|
|
243
|
+
// Semantic Cache Operations (SemanticCacheService)
|
|
244
|
+
// ===========================================================================
|
|
245
|
+
async cacheGet(cacheName, queryEmbedding, threshold = 0.85) {
|
|
246
|
+
const stub = this.getStub('SemanticCacheService');
|
|
247
|
+
const response = await this.promisify(stub, 'get', {
|
|
248
|
+
cacheName,
|
|
249
|
+
queryEmbedding,
|
|
250
|
+
similarityThreshold: threshold,
|
|
251
|
+
});
|
|
252
|
+
return response.hit ? response.cachedValue : null;
|
|
253
|
+
}
|
|
254
|
+
async cachePut(cacheName, key, value, keyEmbedding, ttlSeconds = 0) {
|
|
255
|
+
const stub = this.getStub('SemanticCacheService');
|
|
256
|
+
const response = await this.promisify(stub, 'put', {
|
|
257
|
+
cacheName,
|
|
258
|
+
key,
|
|
259
|
+
value,
|
|
260
|
+
keyEmbedding,
|
|
261
|
+
ttlSeconds,
|
|
262
|
+
});
|
|
263
|
+
return response.success;
|
|
264
|
+
}
|
|
265
|
+
// ===========================================================================
|
|
266
|
+
// Trace Operations (TraceService)
|
|
267
|
+
// ===========================================================================
|
|
268
|
+
async startTrace(name) {
|
|
269
|
+
const stub = this.getStub('TraceService');
|
|
270
|
+
const response = await this.promisify(stub, 'startTrace', { name });
|
|
271
|
+
return { traceId: response.traceId, rootSpanId: response.rootSpanId };
|
|
272
|
+
}
|
|
273
|
+
async startSpan(traceId, parentSpanId, name) {
|
|
274
|
+
const stub = this.getStub('TraceService');
|
|
275
|
+
const response = await this.promisify(stub, 'startSpan', {
|
|
276
|
+
traceId,
|
|
277
|
+
parentSpanId,
|
|
278
|
+
name,
|
|
279
|
+
});
|
|
280
|
+
return response.spanId;
|
|
281
|
+
}
|
|
282
|
+
async endSpan(traceId, spanId, status = 'ok') {
|
|
283
|
+
const stub = this.getStub('TraceService');
|
|
284
|
+
const statusMap = { unset: 0, ok: 1, error: 2 };
|
|
285
|
+
const response = await this.promisify(stub, 'endSpan', {
|
|
286
|
+
traceId,
|
|
287
|
+
spanId,
|
|
288
|
+
status: statusMap[status],
|
|
289
|
+
});
|
|
290
|
+
return Number(response.durationUs);
|
|
291
|
+
}
|
|
292
|
+
// ===========================================================================
|
|
293
|
+
// KV Operations (KvService)
|
|
294
|
+
// ===========================================================================
|
|
295
|
+
async get(key, namespace = 'default') {
|
|
296
|
+
const stub = this.getStub('KvService');
|
|
297
|
+
const response = await this.promisify(stub, 'get', { namespace, key });
|
|
298
|
+
return response.found ? Buffer.from(response.value) : null;
|
|
299
|
+
}
|
|
300
|
+
async put(key, value, namespace = 'default', ttlSeconds = 0) {
|
|
301
|
+
const stub = this.getStub('KvService');
|
|
302
|
+
const response = await this.promisify(stub, 'put', {
|
|
303
|
+
namespace,
|
|
304
|
+
key,
|
|
305
|
+
value,
|
|
306
|
+
ttlSeconds,
|
|
307
|
+
});
|
|
308
|
+
return response.success;
|
|
309
|
+
}
|
|
310
|
+
async delete(key, namespace = 'default') {
|
|
311
|
+
const stub = this.getStub('KvService');
|
|
312
|
+
const response = await this.promisify(stub, 'delete', { namespace, key });
|
|
313
|
+
return response.success;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
exports.SochDBClient = SochDBClient;
|
|
317
|
+
/**
|
|
318
|
+
* Connect to SochDB gRPC server.
|
|
319
|
+
*/
|
|
320
|
+
function connect(address = 'localhost:50051', options = {}) {
|
|
321
|
+
if (address.startsWith('grpc://')) {
|
|
322
|
+
address = address.slice(7);
|
|
323
|
+
}
|
|
324
|
+
return new SochDBClient({ address, ...options });
|
|
325
|
+
}
|
|
326
|
+
// Alias for backwards compatibility
|
|
327
|
+
exports.GrpcClient = SochDBClient;
|
|
328
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JwYy1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZ3JwYy1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7O0dBT0c7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1aSCwwQkFLQztBQXRaRCxvREFBc0M7QUFDdEMsZ0VBQWtEO0FBQ2xELDJDQUE2QjtBQWtDN0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQWEsWUFBWTtJQVF2QixZQUFZLFVBQStCLEVBQUU7UUFMckMsVUFBSyxHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBTTFDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQztRQUNwRCxJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxNQUFNO1lBQy9CLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRTtZQUM5QixDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztRQUV2Rix3QkFBd0I7UUFDeEIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUM1RCxRQUFRLEVBQUUsS0FBSztZQUNmLEtBQUssRUFBRSxNQUFNO1lBQ2IsS0FBSyxFQUFFLE1BQU07WUFDYixRQUFRLEVBQUUsSUFBSTtZQUNkLE1BQU0sRUFBRSxJQUFJO1NBQ2IsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBUSxDQUFDO1FBQ2hGLElBQUksQ0FBQyxLQUFL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QWdELEVBQUU7SUFDN0csSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDbEMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUNELE9BQU8sSUFBSSxZQUFZLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFFRCxvQ0FBb0M7QUFDdkIsUUFBQSxVQUFVLEdBQUcsWUFBWSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTb2NoREIgZ1JQQyBDbGllbnQgLSBUaGluIFNESyBXcmFwcGVyXG4gKlxuICogVGhpcyBtb2R1bGUgcHJvdmlkZXMgYSB0aGluIGdSUEMgY2xpZW50IHdyYXBwZXIgZm9yIHRoZSBTb2NoREIgc2VydmVyLlxuICogQWxsIGJ1c2luZXNzIGxvZ2ljIHJ1bnMgb24gdGhlIHNlcnZlciAoVGhpY2sgU2VydmVyIC8gVGhpbiBDbGllbnQgYXJjaGl0ZWN0dXJlKS5cbiAqXG4gKiBUaGUgY2xpZW50IGlzIGFwcHJveGltYXRlbHkgfjI1MCBsaW5lcyBvZiBjb2RlLCBkZWxlZ2F0aW5nIGFsbCBvcGVyYXRpb25zIHRvIHRoZSBzZXJ2ZXIuXG4gKi9cblxuaW1wb3J0ICogYXMgZ3JwYyBmcm9tICdAZ3JwYy9ncnBjLWpzJztcbmltcG9ydCAqIGFzIHByb3RvTG9hZGVyIGZyb20gJ0BncnBjL3Byb3RvLWxvYWRlcic7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuXG4vLyBUeXBlc1xuZXhwb3J0IGludGVyZmFjZSBTZWFyY2hSZXN1bHQge1xuICBpZDogbnVtYmVyO1xuICBkaXN0YW5jZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERvY3VtZW50IHtcbiAgaWQ6IHN0cmluZztcbiAgY29udGVudDogc3RyaW5nO1xuICBlbWJlZGRpbmc6IG51bWJlcltdO1xuICBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHcmFwaE5vZGUge1xuICBpZDogc3RyaW5nO1xuICBub2RlVHlwZTogc3RyaW5nO1xuICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdyYXBoRWRnZSB7XG4gIGZyb21JZDogc3RyaW5nO1xuICBlZGdlVHlwZTogc3RyaW5nO1xuICB0b0lkOiBzdHJpbmc7XG4gIHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU29jaERCQ2xpZW50T3B0aW9ucyB7XG4gIGFkZHJlc3M/OiBzdHJpbmc7XG4gIHNlY3VyZT86IGJvb2xlYW47XG4gIHByb3RvUGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGluIGdSUEMgY2xpZW50IGZvciBTb2NoREIuXG4gKlxuICogQWxsIG9wZXJhdGlvbnMgYXJlIGRlbGVnYXRlZCB0byB0aGUgU29jaERCIGdSUEMgc2VydmVyLlxuICogVGhpcyBjbGllbnQgcHJvdmlkZXMgYSBUeXBlU2NyaXB0IGludGVyZmFjZSBvdmVyIHRoZSBnUlBDIHByb3RvY29sLlxuICpcbiAqIFVzYWdlOlxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgY2xpZW50ID0gbmV3IFNvY2hEQkNsaWVudCh7IGFkZHJlc3M6ICdsb2NhbGhvc3Q6NTAwNTEnIH0pO1xuICpcbiAqIC8vIENyZWF0ZSBjb2xsZWN0aW9uXG4gKiBhd2FpdCBjbGllbnQuY3JlYXRlQ29sbGVjdGlvbignZG9jcycsIHsgZGltZW5zaW9uOiAzODQgfSk7XG4gKlxuICogLy8gQWRkIGRvY3VtZW50c1xuICogYXdhaXQgY2xpZW50LmFkZERvY3VtZW50cygnZG9jcycsIFtcbiAqICAgeyBpZDogJzEnLCBjb250ZW50OiAnSGVsbG8nLCBlbWJlZGRpbmc6IFsuLi5dIH1cbiAqIF0pO1xuICpcbiAqIC8vIFNlYXJjaFxuICogY29uc3QgcmVzdWx0cyA9IGF3YWl0IGNsaWVudC5zZWFyY2goJ2RvY3MnLCBxdWVyeVZlY3RvciwgNSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFNvY2hEQkNsaWVudCB7XG4gIHByaXZhdGUgYWRkcmVzczogc3RyaW5nO1xuICBwcml2YXRlIGNyZWRlbnRpYWxzOiBncnBjLkNoYW5uZWxDcmVkZW50aWFscztcbiAgcHJpdmF0ZSBzdHViczogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBwcm90b1BhdGg6IHN0cmluZztcbiAgcHJpdmF0ZSBwYWNrYWdlRGVmaW5pdGlvbjogYW55O1xuICBwcml2YXRlIHByb3RvOiBhbnk7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogU29jaERCQ2xpZW50T3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5hZGRyZXNzID0gb3B0aW9ucy5hZGRyZXNzIHx8ICdsb2NhbGhvc3Q6NTAwNTEnO1xuICAgIHRoaXMuY3JlZGVudGlhbHMgPSBvcHRpb25zLnNlY3VyZVxuICAgICAgPyBncnBjLmNyZWRlbnRpYWxzLmNyZWF0ZVNzbCgpXG4gICAgICA6IGdycGMuY3JlZGVudGlhbHMuY3JlYXRlSW5zZWN1cmUoKTtcbiAgICB0aGlzLnByb3RvUGF0aCA9IG9wdGlvbnMucHJvdG9QYXRoIHx8IHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi8uLi9wcm90by9zb2NoZGIucHJvdG8nKTtcblxuICAgIC8vIExvYWQgcHJvdG8gZGVmaW5pdGlvblxuICAgIHRoaXMucGFja2FnZURlZmluaXRpb24gPSBwcm90b0xvYWRlci5sb2FkU3luYyh0aGlzLnByb3RvUGF0aCwge1xuICAgICAga2VlcENhc2U6IGZhbHNlLFxuICAgICAgbG9uZ3M6IFN0cmluZyxcbiAgICAgIGVudW1zOiBTdHJpbmcsXG4gICAgICBkZWZhdWx0czogdHJ1ZSxcbiAgICAgIG9uZW9mczogdHJ1ZSxcbiAgICB9KTtcbiAgICBjb25zdCBsb2FkZWRQYWNrYWdlID0gZ3JwYy5sb2FkUGFja2FnZURlZmluaXRpb24odGhpcy5wYWNrYWdlRGVmaW5pdGlvbikgYXMgYW55O1xuICAgIHRoaXMucHJvdG8gPSBsb2FkZWRQYWNrYWdlPy5zb2NoZGI/LnYxO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTdHViKHNlcnZpY2VOYW1lOiBzdHJpbmcpOiBhbnkge1xuICAgIGlmICghdGhpcy5zdHVicy5oYXMoc2VydmljZU5hbWUpKSB7XG4gICAgICBjb25zdCBTZXJ2aWNlQ2xhc3MgPSB0aGlzLnByb3RvPy5bc2VydmljZU5hbWVdO1xuICAgICAgaWYgKCFTZXJ2aWNlQ2xhc3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTZXJ2aWNlICR7c2VydmljZU5hbWV9IG5vdCBmb3VuZCBpbiBwcm90byBkZWZpbml0aW9uYCk7XG4gICAgICB9XG4gICAgICB0aGlzLnN0dWJzLnNldChzZXJ2aWNlTmFtZSwgbmV3IFNlcnZpY2VDbGFzcyh0aGlzLmFkZHJlc3MsIHRoaXMuY3JlZGVudGlhbHMpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3R1YnMuZ2V0KHNlcnZpY2VOYW1lKSE7XG4gIH1cblxuICBwcml2YXRlIHByb21pc2lmeTxUPihzdHViOiBhbnksIG1ldGhvZDogc3RyaW5nLCByZXF1ZXN0OiBhbnkpOiBQcm9taXNlPFQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgc3R1YlttZXRob2RdKHJlcXVlc3QsIChlcnJvcjogYW55LCByZXNwb25zZTogVCkgPT4ge1xuICAgICAgICBpZiAoZXJyb3IpIHJlamVjdChlcnJvcik7XG4gICAgICAgIGVsc2UgcmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSBhbGwgZ1JQQyBjb25uZWN0aW9ucy5cbiAgICovXG4gIGNsb3NlKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3Qgc3R1YiBvZiB0aGlzLnN0dWJzLnZhbHVlcygpKSB7XG4gICAgICBncnBjLmNsb3NlQ2xpZW50KHN0dWIpO1xuICAgIH1cbiAgICB0aGlzLnN0dWJzLmNsZWFyKCk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gVmVjdG9yIEluZGV4IE9wZXJhdGlvbnMgKFZlY3RvckluZGV4U2VydmljZSlcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgYXN5bmMgY3JlYXRlSW5kZXgoXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGRpbWVuc2lvbjogbnVtYmVyLFxuICAgIG9wdGlvbnM6IHsgbWV0cmljPzogc3RyaW5nOyBtPzogbnVtYmVyOyBlZkNvbnN0cnVjdGlvbj86IG51bWJlciB9ID0ge31cbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignVmVjdG9ySW5kZXhTZXJ2aWNlJyk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdjcmVhdGVJbmRleCcsIHtcbiAgICAgIG5hbWUsXG4gICAgICBkaW1lbnNpb24sXG4gICAgICBtZXRyaWM6IG9wdGlvbnMubWV0cmljID09PSAnbDInID8gMSA6IG9wdGlvbnMubWV0cmljID09PSAnZG90JyA/IDMgOiAyLFxuICAgICAgY29uZmlnOiB7XG4gICAgICAgIG1heENvbm5lY3Rpb25zOiBvcHRpb25zLm0gfHwgMTYsXG4gICAgICAgIGVmQ29uc3RydWN0aW9uOiBvcHRpb25zLmVmQ29uc3RydWN0aW9uIHx8IDIwMCxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLnN1Y2Nlc3M7XG4gIH1cblxuICBhc3luYyBpbnNlcnRWZWN0b3JzKFxuICAgIGluZGV4TmFtZTogc3RyaW5nLFxuICAgIGlkczogbnVtYmVyW10sXG4gICAgdmVjdG9yczogbnVtYmVyW11bXVxuICApOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ1ZlY3RvckluZGV4U2VydmljZScpO1xuICAgIGNvbnN0IGZsYXRWZWN0b3JzID0gdmVjdG9ycy5mbGF0KCk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnByb21pc2lmeTxhbnk+KHN0dWIsICdpbnNlcnRCYXRjaCcsIHtcbiAgICAgIGluZGV4TmFtZSxcbiAgICAgIGlkcyxcbiAgICAgIHZlY3RvcnM6IGZsYXRWZWN0b3JzLFxuICAgIH0pO1xuICAgIHJldHVybiByZXNwb25zZS5pbnNlcnRlZENvdW50O1xuICB9XG5cbiAgYXN5bmMgc2VhcmNoKFxuICAgIGluZGV4TmFtZTogc3RyaW5nLFxuICAgIHF1ZXJ5OiBudW1iZXJbXSxcbiAgICBrOiBudW1iZXIgPSAxMCxcbiAgICBlZjogbnVtYmVyID0gNTBcbiAgKTogUHJvbWlzZTxTZWFyY2hSZXN1bHRbXT4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ1ZlY3RvckluZGV4U2VydmljZScpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wcm9taXNpZnk8YW55PihzdHViLCAnc2VhcmNoJywge1xuICAgICAgaW5kZXhOYW1lLFxuICAgICAgcXVlcnksXG4gICAgICBrLFxuICAgICAgZWYsXG4gICAgfSk7XG4gICAgcmV0dXJuIChyZXNwb25zZS5yZXN1bHRzIHx8IFtdKS5tYXAoKHI6IGFueSkgPT4gKHtcbiAgICAgIGlkOiBOdW1iZXIoci5pZCksXG4gICAgICBkaXN0YW5jZTogci5kaXN0YW5jZSxcbiAgICB9KSk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gQ29sbGVjdGlvbiBPcGVyYXRpb25zIChDb2xsZWN0aW9uU2VydmljZSlcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgYXN5bmMgY3JlYXRlQ29sbGVjdGlvbihcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgb3B0aW9uczogeyBkaW1lbnNpb246IG51bWJlcjsgbmFtZXNwYWNlPzogc3RyaW5nOyBtZXRyaWM/OiBzdHJpbmcgfVxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdDb2xsZWN0aW9uU2VydmljZScpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wcm9taXNpZnk8YW55PihzdHViLCAnY3JlYXRlQ29sbGVjdGlvbicsIHtcbiAgICAgIG5hbWUsXG4gICAgICBuYW1lc3BhY2U6IG9wdGlvbnMubmFtZXNwYWNlIHx8ICdkZWZhdWx0JyxcbiAgICAgIGRpbWVuc2lvbjogb3B0aW9ucy5kaW1lbnNpb24sXG4gICAgICBtZXRyaWM6IG9wdGlvbnMubWV0cmljID09PSAnbDInID8gMSA6IG9wdGlvbnMubWV0cmljID09PSAnZG90JyA/IDMgOiAyLFxuICAgIH0pO1xuICAgIHJldHVybiByZXNwb25zZS5zdWNjZXNzO1xuICB9XG5cbiAgYXN5bmMgYWRkRG9jdW1lbnRzKFxuICAgIGNvbGxlY3Rpb25OYW1lOiBzdHJpbmcsXG4gICAgZG9jdW1lbnRzOiBBcnJheTx7XG4gICAgICBpZD86IHN0cmluZztcbiAgICAgIGNvbnRlbnQ/OiBzdHJpbmc7XG4gICAgICBlbWJlZGRpbmc/OiBudW1iZXJbXTtcbiAgICAgIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICB9PixcbiAgICBuYW1lc3BhY2U6IHN0cmluZyA9ICdkZWZhdWx0J1xuICApOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignQ29sbGVjdGlvblNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ2FkZERvY3VtZW50cycsIHtcbiAgICAgIGNvbGxlY3Rpb25OYW1lLFxuICAgICAgbmFtZXNwYWNlLFxuICAgICAgZG9jdW1lbnRzOiBkb2N1bWVudHMubWFwKChkKSA9PiAoe1xuICAgICAgICBpZDogZC5pZCB8fCAnJyxcbiAgICAgICAgY29udGVudDogZC5jb250ZW50IHx8ICcnLFxuICAgICAgICBlbWJlZGRpbmc6IGQuZW1iZWRkaW5nIHx8IFtdLFxuICAgICAgICBtZXRhZGF0YTogZC5tZXRhZGF0YSB8fCB7fSxcbiAgICAgIH0pKSxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2UuaWRzIHx8IFtdO1xuICB9XG5cbiAgYXN5bmMgc2VhcmNoQ29sbGVjdGlvbihcbiAgICBjb2xsZWN0aW9uTmFtZTogc3RyaW5nLFxuICAgIHF1ZXJ5OiBudW1iZXJbXSxcbiAgICBrOiBudW1iZXIgPSAxMCxcbiAgICBvcHRpb25zOiB7IG5hbWVzcGFjZT86IHN0cmluZzsgZmlsdGVyPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB9ID0ge31cbiAgKTogUHJvbWlzZTxEb2N1bWVudFtdPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignQ29sbGVjdGlvblNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ3NlYXJjaENvbGxlY3Rpb24nLCB7XG4gICAgICBjb2xsZWN0aW9uTmFtZSxcbiAgICAgIG5hbWVzcGFjZTogb3B0aW9ucy5uYW1lc3BhY2UgfHwgJ2RlZmF1bHQnLFxuICAgICAgcXVlcnksXG4gICAgICBrLFxuICAgICAgZmlsdGVyOiBvcHRpb25zLmZpbHRlciB8fCB7fSxcbiAgICB9KTtcbiAgICByZXR1cm4gKHJlc3BvbnNlLnJlc3VsdHMgfHwgW10pLm1hcCgocjogYW55KSA9PiAoe1xuICAgICAgaWQ6IHIuZG9jdW1lbnQuaWQsXG4gICAgICBjb250ZW50OiByLmRvY3VtZW50LmNvbnRlbnQsXG4gICAgICBlbWJlZGRpbmc6IHIuZG9jdW1lbnQuZW1iZWRkaW5nIHx8IFtdLFxuICAgICAgbWV0YWRhdGE6IHIuZG9jdW1lbnQubWV0YWRhdGEgfHwge30sXG4gICAgfSkpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIEdyYXBoIE9wZXJhdGlvbnMgKEdyYXBoU2VydmljZSlcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgYXN5bmMgYWRkTm9kZShcbiAgICBub2RlSWQ6IHN0cmluZyxcbiAgICBub2RlVHlwZTogc3RyaW5nLFxuICAgIHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fSxcbiAgICBuYW1lc3BhY2U6IHN0cmluZyA9ICdkZWZhdWx0J1xuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdHcmFwaFNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ2FkZE5vZGUnLCB7XG4gICAgICBuYW1lc3BhY2UsXG4gICAgICBub2RlOiB7IGlkOiBub2RlSWQsIG5vZGVUeXBlLCBwcm9wZXJ0aWVzIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLnN1Y2Nlc3M7XG4gIH1cblxuICBhc3luYyBhZGRFZGdlKFxuICAgIGZyb21JZDogc3RyaW5nLFxuICAgIGVkZ2VUeXBlOiBzdHJpbmcsXG4gICAgdG9JZDogc3RyaW5nLFxuICAgIHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fSxcbiAgICBuYW1lc3BhY2U6IHN0cmluZyA9ICdkZWZhdWx0J1xuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdHcmFwaFNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ2FkZEVkZ2UnLCB7XG4gICAgICBuYW1lc3BhY2UsXG4gICAgICBlZGdlOiB7IGZyb21JZCwgZWRnZVR5cGUsIHRvSWQsIHByb3BlcnRpZXMgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2Uuc3VjY2VzcztcbiAgfVxuXG4gIGFzeW5jIHRyYXZlcnNlKFxuICAgIHN0YXJ0Tm9kZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IHsgbWF4RGVwdGg/OiBudW1iZXI7IG9yZGVyPzogJ2JmcycgfCAnZGZzJzsgbmFtZXNwYWNlPzogc3RyaW5nIH0gPSB7fVxuICApOiBQcm9taXNlPHsgbm9kZXM6IEdyYXBoTm9kZVtdOyBlZGdlczogR3JhcGhFZGdlW10gfT4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ0dyYXBoU2VydmljZScpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wcm9taXNpZnk8YW55PihzdHViLCAndHJhdmVyc2UnLCB7XG4gICAgICBuYW1lc3BhY2U6IG9wdGlvbnMubmFtZXNwYWNlIHx8ICdkZWZhdWx0JyxcbiAgICAgIHN0YXJ0Tm9kZUlkOiBzdGFydE5vZGUsXG4gICAgICBvcmRlcjogb3B0aW9ucy5vcmRlciA9PT0gJ2RmcycgPyAxIDogMCxcbiAgICAgIG1heERlcHRoOiBvcHRpb25zLm1heERlcHRoIHx8IDEwLFxuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBub2RlczogKHJlc3BvbnNlLm5vZGVzIHx8IFtdKS5tYXAoKG46IGFueSkgPT4gKHtcbiAgICAgICAgaWQ6IG4uaWQsXG4gICAgICAgIG5vZGVUeXBlOiBuLm5vZGVUeXBlLFxuICAgICAgICBwcm9wZXJ0aWVzOiBuLnByb3BlcnRpZXMgfHwge30sXG4gICAgICB9KSksXG4gICAgICBlZGdlczogKHJlc3BvbnNlLmVkZ2VzIHx8IFtdKS5tYXAoKGU6IGFueSkgPT4gKHtcbiAgICAgICAgZnJvbUlkOiBlLmZyb21JZCxcbiAgICAgICAgZWRnZVR5cGU6IGUuZWRnZVR5cGUsXG4gICAgICAgIHRvSWQ6IGUudG9JZCxcbiAgICAgICAgcHJvcGVydGllczogZS5wcm9wZXJ0aWVzIHx8IHt9LFxuICAgICAgfSkpLFxuICAgIH07XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gU2VtYW50aWMgQ2FjaGUgT3BlcmF0aW9ucyAoU2VtYW50aWNDYWNoZVNlcnZpY2UpXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGFzeW5jIGNhY2hlR2V0KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHF1ZXJ5RW1iZWRkaW5nOiBudW1iZXJbXSxcbiAgICB0aHJlc2hvbGQ6IG51bWJlciA9IDAuODVcbiAgKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gICAgY29uc3Qgc3R1YiA9IHRoaXMuZ2V0U3R1YignU2VtYW50aWNDYWNoZVNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ2dldCcsIHtcbiAgICAgIGNhY2hlTmFtZSxcbiAgICAgIHF1ZXJ5RW1iZWRkaW5nLFxuICAgICAgc2ltaWxhcml0eVRocmVzaG9sZDogdGhyZXNob2xkLFxuICAgIH0pO1xuICAgIHJldHVybiByZXNwb25zZS5oaXQgPyByZXNwb25zZS5jYWNoZWRWYWx1ZSA6IG51bGw7XG4gIH1cblxuICBhc3luYyBjYWNoZVB1dChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyxcbiAgICB2YWx1ZTogc3RyaW5nLFxuICAgIGtleUVtYmVkZGluZzogbnVtYmVyW10sXG4gICAgdHRsU2Vjb25kczogbnVtYmVyID0gMFxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdTZW1hbnRpY0NhY2hlU2VydmljZScpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wcm9taXNpZnk8YW55PihzdHViLCAncHV0Jywge1xuICAgICAgY2FjaGVOYW1lLFxuICAgICAga2V5LFxuICAgICAgdmFsdWUsXG4gICAgICBrZXlFbWJlZGRpbmcsXG4gICAgICB0dGxTZWNvbmRzLFxuICAgIH0pO1xuICAgIHJldHVybiByZXNwb25zZS5zdWNjZXNzO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFRyYWNlIE9wZXJhdGlvbnMgKFRyYWNlU2VydmljZSlcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgYXN5bmMgc3RhcnRUcmFjZShuYW1lOiBzdHJpbmcpOiBQcm9taXNlPHsgdHJhY2VJZDogc3RyaW5nOyByb290U3BhbklkOiBzdHJpbmcgfT4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ1RyYWNlU2VydmljZScpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wcm9taXNpZnk8YW55PihzdHViLCAnc3RhcnRUcmFjZScsIHsgbmFtZSB9KTtcbiAgICByZXR1cm4geyB0cmFjZUlkOiByZXNwb25zZS50cmFjZUlkLCByb290U3BhbklkOiByZXNwb25zZS5yb290U3BhbklkIH07XG4gIH1cblxuICBhc3luYyBzdGFydFNwYW4odHJhY2VJZDogc3RyaW5nLCBwYXJlbnRTcGFuSWQ6IHN0cmluZywgbmFtZTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdUcmFjZVNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ3N0YXJ0U3BhbicsIHtcbiAgICAgIHRyYWNlSWQsXG4gICAgICBwYXJlbnRTcGFuSWQsXG4gICAgICBuYW1lLFxuICAgIH0pO1xuICAgIHJldHVybiByZXNwb25zZS5zcGFuSWQ7XG4gIH1cblxuICBhc3luYyBlbmRTcGFuKFxuICAgIHRyYWNlSWQ6IHN0cmluZyxcbiAgICBzcGFuSWQ6IHN0cmluZyxcbiAgICBzdGF0dXM6ICdvaycgfCAnZXJyb3InIHwgJ3Vuc2V0JyA9ICdvaydcbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdUcmFjZVNlcnZpY2UnKTtcbiAgICBjb25zdCBzdGF0dXNNYXAgPSB7IHVuc2V0OiAwLCBvazogMSwgZXJyb3I6IDIgfTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ2VuZFNwYW4nLCB7XG4gICAgICB0cmFjZUlkLFxuICAgICAgc3BhbklkLFxuICAgICAgc3RhdHVzOiBzdGF0dXNNYXBbc3RhdHVzXSxcbiAgICB9KTtcbiAgICByZXR1cm4gTnVtYmVyKHJlc3BvbnNlLmR1cmF0aW9uVXMpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIEtWIE9wZXJhdGlvbnMgKEt2U2VydmljZSlcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgYXN5bmMgZ2V0KGtleTogQnVmZmVyLCBuYW1lc3BhY2U6IHN0cmluZyA9ICdkZWZhdWx0Jyk6IFByb21pc2U8QnVmZmVyIHwgbnVsbD4ge1xuICAgIGNvbnN0IHN0dWIgPSB0aGlzLmdldFN0dWIoJ0t2U2VydmljZScpO1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wcm9taXNpZnk8YW55PihzdHViLCAnZ2V0JywgeyBuYW1lc3BhY2UsIGtleSB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2UuZm91bmQgPyBCdWZmZXIuZnJvbShyZXNwb25zZS52YWx1ZSkgOiBudWxsO1xuICB9XG5cbiAgYXN5bmMgcHV0KFxuICAgIGtleTogQnVmZmVyLFxuICAgIHZhbHVlOiBCdWZmZXIsXG4gICAgbmFtZXNwYWNlOiBzdHJpbmcgPSAnZGVmYXVsdCcsXG4gICAgdHRsU2Vjb25kczogbnVtYmVyID0gMFxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdLdlNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ3B1dCcsIHtcbiAgICAgIG5hbWVzcGFjZSxcbiAgICAgIGtleSxcbiAgICAgIHZhbHVlLFxuICAgICAgdHRsU2Vjb25kcyxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzcG9uc2Uuc3VjY2VzcztcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZShrZXk6IEJ1ZmZlciwgbmFtZXNwYWNlOiBzdHJpbmcgPSAnZGVmYXVsdCcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBzdHViID0gdGhpcy5nZXRTdHViKCdLdlNlcnZpY2UnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMucHJvbWlzaWZ5PGFueT4oc3R1YiwgJ2RlbGV0ZScsIHsgbmFtZXNwYWNlLCBrZXkgfSk7XG4gICAgcmV0dXJuIHJlc3BvbnNlLnN1Y2Nlc3M7XG4gIH1cbn1cblxuLyoqXG4gKiBDb25uZWN0IHRvIFNvY2hEQiBnUlBDIHNlcnZlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbm5lY3QoYWRkcmVzczogc3RyaW5nID0gJ2xvY2FsaG9zdDo1MDA1MScsIG9wdGlvbnM6IE9taXQ8U29jaERCQ2xpZW50T3B0aW9ucywgJ2FkZHJlc3MnPiA9IHt9KTogU29jaERCQ2xpZW50IHtcbiAgaWYgKGFkZHJlc3Muc3RhcnRzV2l0aCgnZ3JwYzovLycpKSB7XG4gICAgYWRkcmVzcyA9IGFkZHJlc3Muc2xpY2UoNyk7XG4gIH1cbiAgcmV0dXJuIG5ldyBTb2NoREJDbGllbnQoeyBhZGRyZXNzLCAuLi5vcHRpb25zIH0pO1xufVxuXG4vLyBBbGlhcyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbmV4cG9ydCBjb25zdCBHcnBjQ2xpZW50ID0gU29jaERCQ2xpZW50O1xuIl19
|
|
@@ -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==
|