@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,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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JwYy1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZ3JwYy1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7O0dBT0c7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW1aSCwwQkFLQztBQXRaRCxvREFBc0M7QUFDdEMsZ0VBQWtEO0FBQ2xELDJDQUE2QjtBQWtDN0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILE1BQWEsWUFBWTtJQVF2QixZQUFZLFVBQStCLEVBQUU7UUFMckMsVUFBSyxHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBTTFDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQztRQUNwRCxJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxNQUFNO1lBQy9CLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRTtZQUM5QixDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztRQUV2Rix3QkFBd0I7UUFDeEIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUM1RCxRQUFRLEVBQUUsS0FBSztZQUNmLEtBQUssRUFBRSxNQUFNO1lBQ2IsS0FBSyxFQUFFLE1BQU07WUFDYixRQUFRLEVBQUUsSUFBSTtZQUNkLE1BQU0sRUFBRSxJQUFJO1NBQ2IsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBUSxDQUFDO1FBQ2hGLElBQUksQ0FBQyxLQUFLLEdBQUcsYUFBYSxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQUM7SUFDekMsQ0FBQztJQUVPLE9BQU8sQ0FBQyxXQUFtQjtRQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDL0MsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUNsQixNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsV0FBVyxnQ0FBZ0MsQ0FBQyxDQUFDO1lBQzFFLENBQUM7WUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUNoRixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUUsQ0FBQztJQUN0QyxDQUFDO0lBRU8sU0FBUyxDQUFJLElBQVMsRUFBRSxNQUFjLEVBQUUsT0FBWTtRQUMxRCxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxLQUFVLEVBQUUsUUFBVyxFQUFFLEVBQUU7Z0JBQ2hELElBQUksS0FBSztvQkFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7O29CQUNwQixPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDekIsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUs7UUFDSCxLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztZQUN2QyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pCLENBQUM7UUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCw4RUFBOEU7SUFDOUUsK0NBQStDO0lBQy9DLDhFQUE4RTtJQUU5RSxLQUFLLENBQUMsV0FBVyxDQUNmLElBQVksRUFDWixTQUFpQixFQUNqQixVQUFvRSxFQUFFO1FBRXRFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUNoRCxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQU0sSUFBSSxFQUFFLGFBQWEsRUFBRTtZQUM5RCxJQUFJO1lBQ0osU0FBUztZQUNULE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RFLE1BQU0sRUFBRTtnQkFDTixjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFO2dCQUMvQixjQUFjLEVBQUUsT0FBTyxDQUFDLGNBQWMsSUFBSSxHQUFHO2FBQzlDO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxRQUFRLENBQUMsT0FBTyxDQUFDO0lBQzFCLENBQUM7SUFFRCxLQUFLLENBQUMsYUFBYSxDQUNqQixTQUFpQixFQUNqQixHQUFhLEVBQ2IsT0FBbUI7UUFFbkIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNuQyxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQU0sSUFBSSxFQUFFLGFBQWEsRUFBRTtZQUM5RCxTQUFTO1lBQ1QsR0FBRztZQUNILE9BQU8sRUFBRSxXQUFXO1NBQ3JCLENBQUMsQ0FBQztRQUNILE9BQU8sUUFBUSxDQUFDLGFBQWEsQ0FBQztJQUNoQyxDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU0sQ0FDVixTQUFpQixFQUNqQixLQUFlLEVBQ2YsSUFBWSxFQUFFLEVBQ2QsS0FBYSxFQUFFO1FBRWYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBTSxJQUFJLEVBQUUsUUFBUSxFQUFFO1lBQ3pELFNBQVM7WUFDVCxLQUFLO1lBQ0wsQ0FBQztZQUNELEVBQUU7U0FDSCxDQUFDLENBQUM7UUFDSCxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDL0MsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2hCLFFBQVEsRUFBRSxDQUFDLENBQUMsUUFBUTtTQUNyQixDQUFDLENBQUMsQ0FBQztJQUNOLENBQUM7SUFFRCw4RUFBOEU7SUFDOUUsNENBQTRDO0lBQzVDLDhFQUE4RTtJQUU5RSxLQUFLLENBQUMsZ0JBQWdCLENBQ3BCLElBQVksRUFDWixPQUFtRTtRQUVuRSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDL0MsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFNLElBQUksRUFBRSxrQkFBa0IsRUFBRTtZQUNuRSxJQUFJO1lBQ0osU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLElBQUksU0FBUztZQUN6QyxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7WUFDNUIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDdkUsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxRQUFRLENBQUMsT0FBTyxDQUFDO0lBQzFCLENBQUM7SUFFRCxLQUFLLENBQUMsWUFBWSxDQUNoQixjQUFzQixFQUN0QixTQUtFLEVBQ0YsWUFBb0IsU0FBUztRQUU3QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDL0MsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFNLElBQUksRUFBRSxjQUFjLEVBQUU7WUFDL0QsY0FBYztZQUNkLFNBQVM7WUFDVCxTQUFTLEVBQUUsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDL0IsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRTtnQkFDZCxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sSUFBSSxFQUFFO2dCQUN4QixTQUFTLEVBQUUsQ0FBQyxDQUFDLFNBQVMsSUFBSSxFQUFFO2dCQUM1QixRQUFRLEVBQUUsQ0FBQyxDQUFDLFFBQVEsSUFBSSxFQUFFO2FBQzNCLENBQUMsQ0FBQztTQUNKLENBQUMsQ0FBQztRQUNILE9BQU8sUUFBUSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVELEtBQUssQ0FBQyxnQkFBZ0IsQ0FDcEIsY0FBc0IsRUFDdEIsS0FBZSxFQUNmLElBQVksRUFBRSxFQUNkLFVBQW1FLEVBQUU7UUFFckUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBTSxJQUFJLEVBQUUsa0JBQWtCLEVBQUU7WUFDbkUsY0FBYztZQUNkLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUyxJQUFJLFNBQVM7WUFDekMsS0FBSztZQUNMLENBQUM7WUFDRCxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sSUFBSSxFQUFFO1NBQzdCLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMvQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFO1lBQ2pCLE9BQU8sRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU87WUFDM0IsU0FBUyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxJQUFJLEVBQUU7WUFDckMsUUFBUSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxJQUFJLEVBQUU7U0FDcEMsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsOEVBQThFO0lBQzlFLGtDQUFrQztJQUNsQyw4RUFBOEU7SUFFOUUsS0FBSyxDQUFDLE9BQU8sQ0FDWCxNQUFjLEVBQ2QsUUFBZ0IsRUFDaEIsYUFBcUMsRUFBRSxFQUN2QyxZQUFvQixTQUFTO1FBRTdCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDMUMsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFNLElBQUksRUFBRSxTQUFTLEVBQUU7WUFDMUQsU0FBUztZQUNULElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRTtTQUMzQyxDQUFDLENBQUM7UUFDSCxPQUFPLFFBQVEsQ0FBQyxPQUFPLENBQUM7SUFDMUIsQ0FBQztJQUVELEtBQUssQ0FBQyxPQUFPLENBQ1gsTUFBYyxFQUNkLFFBQWdCLEVBQ2hCLElBQVksRUFDWixhQUFxQyxFQUFFLEVBQ3ZDLFlBQW9CLFNBQVM7UUFFN0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUMxQyxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQU0sSUFBSSxFQUFFLFNBQVMsRUFBRTtZQUMxRCxTQUFTO1lBQ1QsSUFBSSxFQUFFLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO1NBQzdDLENBQUMsQ0FBQztRQUNILE9BQU8sUUFBUSxDQUFDLE9BQU8sQ0FBQztJQUMxQixDQUFDO0lBRUQsS0FBSyxDQUFDLFFBQVEsQ0FDWixTQUFpQixFQUNqQixVQUE0RSxFQUFFO1FBRTlFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDMUMsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFNLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDM0QsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLElBQUksU0FBUztZQUN6QyxXQUFXLEVBQUUsU0FBUztZQUN0QixLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0QyxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVEsSUFBSSxFQUFFO1NBQ2pDLENBQUMsQ0FBQztRQUNILE9BQU87WUFDTCxLQUFLLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDN0MsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFO2dCQUNSLFFBQVEsRUFBRSxDQUFDLENBQUMsUUFBUTtnQkFDcEIsVUFBVSxFQUFFLENBQUMsQ0FBQyxVQUFVLElBQUksRUFBRTthQUMvQixDQUFDLENBQUM7WUFDSCxLQUFLLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDN0MsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNO2dCQUNoQixRQUFRLEVBQUUsQ0FBQyxDQUFDLFFBQVE7Z0JBQ3BCLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSTtnQkFDWixVQUFVLEVBQUUsQ0FBQyxDQUFDLFVBQVUsSUFBSSxFQUFFO2FBQy9CLENBQUMsQ0FBQztTQUNKLENBQUM7SUFDSixDQUFDO0lBRUQsOEVBQThFO0lBQzlFLG1EQUFtRDtJQUNuRCw4RUFBOEU7SUFFOUUsS0FBSyxDQUFDLFFBQVEsQ0FDWixTQUFpQixFQUNqQixjQUF3QixFQUN4QixZQUFvQixJQUFJO1FBRXhCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUNsRCxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQU0sSUFBSSxFQUFFLEtBQUssRUFBRTtZQUN0RCxTQUFTO1lBQ1QsY0FBYztZQUNkLG1CQUFtQixFQUFFLFNBQVM7U0FDL0IsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDcEQsQ0FBQztJQUVELEtBQUssQ0FBQyxRQUFRLENBQ1osU0FBaUIsRUFDakIsR0FBVyxFQUNYLEtBQWEsRUFDYixZQUFzQixFQUN0QixhQUFxQixDQUFDO1FBRXRCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUNsRCxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQU0sSUFBSSxFQUFFLEtBQUssRUFBRTtZQUN0RCxTQUFTO1lBQ1QsR0FBRztZQUNILEtBQUs7WUFDTCxZQUFZO1lBQ1osVUFBVTtTQUNYLENBQUMsQ0FBQztRQUNILE9BQU8sUUFBUSxDQUFDLE9BQU8sQ0FBQztJQUMxQixDQUFDO0lBRUQsOEVBQThFO0lBQzlFLGtDQUFrQztJQUNsQyw4RUFBOEU7SUFFOUUsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFZO1FBQzNCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDMUMsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFNLElBQUksRUFBRSxZQUFZLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3pFLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3hFLENBQUM7SUFFRCxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQWUsRUFBRSxZQUFvQixFQUFFLElBQVk7UUFDakUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUMxQyxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQU0sSUFBSSxFQUFFLFdBQVcsRUFBRTtZQUM1RCxPQUFPO1lBQ1AsWUFBWTtZQUNaLElBQUk7U0FDTCxDQUFDLENBQUM7UUFDSCxPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUM7SUFDekIsQ0FBQztJQUVELEtBQUssQ0FBQyxPQUFPLENBQ1gsT0FBZSxFQUNmLE1BQWMsRUFDZCxTQUFtQyxJQUFJO1FBRXZDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDMUMsTUFBTSxTQUFTLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ2hELE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBTSxJQUFJLEVBQUUsU0FBUyxFQUFFO1lBQzFELE9BQU87WUFDUCxNQUFNO1lBQ04sTUFBTSxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUM7U0FDMUIsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRCw4RUFBOEU7SUFDOUUsNEJBQTRCO0lBQzVCLDhFQUE4RTtJQUU5RSxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQVcsRUFBRSxZQUFvQixTQUFTO1FBQ2xELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdkMsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFNLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUM1RSxPQUFPLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDN0QsQ0FBQztJQUVELEtBQUssQ0FBQyxHQUFHLENBQ1AsR0FBVyxFQUNYLEtBQWEsRUFDYixZQUFvQixTQUFTLEVBQzdCLGFBQXFCLENBQUM7UUFFdEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUN2QyxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQU0sSUFBSSxFQUFFLEtBQUssRUFBRTtZQUN0RCxTQUFTO1lBQ1QsR0FBRztZQUNILEtBQUs7WUFDTCxVQUFVO1NBQ1gsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxRQUFRLENBQUMsT0FBTyxDQUFDO0lBQzFCLENBQUM7SUFFRCxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQVcsRUFBRSxZQUFvQixTQUFTO1FBQ3JELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdkMsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFNLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUMvRSxPQUFPLFFBQVEsQ0FBQyxPQUFPLENBQUM7SUFDMUIsQ0FBQztDQUNGO0FBbFZELG9DQWtWQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsT0FBTyxDQUFDLFVBQWtCLGlCQUFpQixFQUFFLFVBQWdELEVBQUU7SUFDN0csSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDbEMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUNELE9BQU8sSUFBSSxZQUFZLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFFRCxvQ0FBb0M7QUFDdkIsUUFBQSxVQUFVLEdBQUcsWUFBWSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTb2NoREIgZ1JQQyBDbGllbnQgLSBUaGluIFNESyBXcmFwcGVyXG4gKlxuICogVGhpcyBtb2R1bGUgcHJvdmlkZXMgYSB0aGluIGdSUEMgY2xpZW50IHdyYXBwZXIgZm9yIHRoZSBTb2NoREIgc2VydmVyLlxuICogQWxsIGJ1c2luZXNzIGxvZ2ljIHJ1bnMgb24gdGhlIHNlcnZlciAoVGhpY2sgU2VydmVyIC8gVGhpbiBDbGllbnQgYXJjaGl0ZWN0dXJlKS5cbiAqXG4gKiBUaGUgY2xpZW50IGlzIGFwcHJveGltYXRlbHkgfjI1MCBsaW5lcyBvZiBjb2RlLCBkZWxlZ2F0aW5nIGFsbCBvcGVyYXRpb25zIHRvIHRoZSBzZXJ2ZXIuXG4gKi9cblxuaW1wb3J0ICogYXMgZ3JwYyBmcm9tICdAZ3JwYy9ncnBjLWpzJztcbmltcG9ydCAqIGFzIHByb3RvTG9hZGVyIGZyb20gJ0BncnBjL3Byb3RvLWxvYWRlcic7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuXG4vLyBUeXBlc1xuZXhwb3J0IGludGVyZmFjZSBTZWFyY2hSZXN1bHQge1xuICBpZDogbnVtYmVyO1xuICBkaXN0YW5jZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERvY3VtZW50IHtcbiAgaWQ6IHN0cmluZztcbiAgY29udGVudDogc3RyaW5nO1xuICBlbWJlZGRpbmc6IG51bWJlcltdO1xuICBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHcmFwaE5vZGUge1xuICBpZDogc3RyaW5nO1xuICBub2RlVHlwZTogc3RyaW5nO1xuICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+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==