@ruvector/ruvllm 0.2.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 (75) hide show
  1. package/README.md +406 -0
  2. package/bin/cli.js +387 -0
  3. package/dist/cjs/engine.d.ts +90 -0
  4. package/dist/cjs/engine.d.ts.map +1 -0
  5. package/dist/cjs/engine.js +301 -0
  6. package/dist/cjs/export.d.ts +182 -0
  7. package/dist/cjs/export.d.ts.map +1 -0
  8. package/dist/cjs/export.js +422 -0
  9. package/dist/cjs/federated.d.ts +233 -0
  10. package/dist/cjs/federated.d.ts.map +1 -0
  11. package/dist/cjs/federated.js +525 -0
  12. package/dist/cjs/index.d.ts +64 -0
  13. package/dist/cjs/index.d.ts.map +1 -0
  14. package/dist/cjs/index.js +96 -0
  15. package/dist/cjs/lora.d.ts +240 -0
  16. package/dist/cjs/lora.d.ts.map +1 -0
  17. package/dist/cjs/lora.js +494 -0
  18. package/dist/cjs/native.d.ts +83 -0
  19. package/dist/cjs/native.d.ts.map +1 -0
  20. package/dist/cjs/native.js +70 -0
  21. package/dist/cjs/session.d.ts +80 -0
  22. package/dist/cjs/session.d.ts.map +1 -0
  23. package/dist/cjs/session.js +203 -0
  24. package/dist/cjs/simd.d.ts +90 -0
  25. package/dist/cjs/simd.d.ts.map +1 -0
  26. package/dist/cjs/simd.js +209 -0
  27. package/dist/cjs/sona.d.ts +187 -0
  28. package/dist/cjs/sona.d.ts.map +1 -0
  29. package/dist/cjs/sona.js +500 -0
  30. package/dist/cjs/streaming.d.ts +55 -0
  31. package/dist/cjs/streaming.d.ts.map +1 -0
  32. package/dist/cjs/streaming.js +131 -0
  33. package/dist/cjs/training.d.ts +254 -0
  34. package/dist/cjs/training.d.ts.map +1 -0
  35. package/dist/cjs/training.js +480 -0
  36. package/dist/cjs/types.d.ts +599 -0
  37. package/dist/cjs/types.d.ts.map +1 -0
  38. package/dist/cjs/types.js +6 -0
  39. package/dist/esm/engine.d.ts +90 -0
  40. package/dist/esm/engine.d.ts.map +1 -0
  41. package/dist/esm/engine.js +297 -0
  42. package/dist/esm/export.d.ts +182 -0
  43. package/dist/esm/export.d.ts.map +1 -0
  44. package/dist/esm/export.js +414 -0
  45. package/dist/esm/federated.d.ts +233 -0
  46. package/dist/esm/federated.d.ts.map +1 -0
  47. package/dist/esm/federated.js +520 -0
  48. package/dist/esm/index.d.ts +64 -0
  49. package/dist/esm/index.d.ts.map +1 -0
  50. package/dist/esm/index.js +76 -0
  51. package/dist/esm/lora.d.ts +240 -0
  52. package/dist/esm/lora.d.ts.map +1 -0
  53. package/dist/esm/lora.js +489 -0
  54. package/dist/esm/native.d.ts +83 -0
  55. package/dist/esm/native.d.ts.map +1 -0
  56. package/dist/esm/native.js +65 -0
  57. package/dist/esm/session.d.ts +80 -0
  58. package/dist/esm/session.d.ts.map +1 -0
  59. package/dist/esm/session.js +199 -0
  60. package/dist/esm/simd.d.ts +90 -0
  61. package/dist/esm/simd.d.ts.map +1 -0
  62. package/dist/esm/simd.js +205 -0
  63. package/dist/esm/sona.d.ts +187 -0
  64. package/dist/esm/sona.d.ts.map +1 -0
  65. package/dist/esm/sona.js +494 -0
  66. package/dist/esm/streaming.d.ts +55 -0
  67. package/dist/esm/streaming.d.ts.map +1 -0
  68. package/dist/esm/streaming.js +126 -0
  69. package/dist/esm/training.d.ts +254 -0
  70. package/dist/esm/training.d.ts.map +1 -0
  71. package/dist/esm/training.js +473 -0
  72. package/dist/esm/types.d.ts +599 -0
  73. package/dist/esm/types.d.ts.map +1 -0
  74. package/dist/esm/types.js +5 -0
  75. package/package.json +121 -0
@@ -0,0 +1,500 @@
1
+ "use strict";
2
+ /**
3
+ * SONA (Self-Optimizing Neural Architecture) Learning System
4
+ *
5
+ * Provides adaptive learning capabilities with trajectory tracking,
6
+ * pattern recognition, and memory protection (EWC++).
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.DEFAULT_SONA_CONFIG = exports.SonaCoordinator = exports.EwcManager = exports.ReasoningBank = exports.TrajectoryBuilder = void 0;
10
+ /**
11
+ * Default SONA configuration
12
+ */
13
+ const DEFAULT_SONA_CONFIG = {
14
+ instantLoopEnabled: true,
15
+ backgroundLoopEnabled: true,
16
+ loraLearningRate: 0.001,
17
+ loraRank: 8,
18
+ ewcLambda: 2000,
19
+ maxTrajectorySize: 1000,
20
+ patternThreshold: 0.85,
21
+ };
22
+ exports.DEFAULT_SONA_CONFIG = DEFAULT_SONA_CONFIG;
23
+ /**
24
+ * Trajectory Builder for tracking query execution paths
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const builder = new TrajectoryBuilder();
29
+ *
30
+ * builder.startStep('query', 'What is AI?');
31
+ * // ... processing ...
32
+ * builder.endStep('AI is artificial intelligence', 0.95);
33
+ *
34
+ * builder.startStep('memory', 'searching context');
35
+ * builder.endStep('found 3 relevant documents', 0.88);
36
+ *
37
+ * const trajectory = builder.complete('success');
38
+ * ```
39
+ */
40
+ class TrajectoryBuilder {
41
+ constructor() {
42
+ this.steps = [];
43
+ this.currentStep = null;
44
+ this.stepStart = 0;
45
+ this.id = `traj-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
46
+ this.startTime = Date.now();
47
+ }
48
+ /**
49
+ * Start a new step in the trajectory
50
+ */
51
+ startStep(type, input) {
52
+ if (this.currentStep) {
53
+ // Auto-complete previous step
54
+ this.endStep('', 0);
55
+ }
56
+ this.stepStart = Date.now();
57
+ this.currentStep = {
58
+ type,
59
+ input,
60
+ };
61
+ return this;
62
+ }
63
+ /**
64
+ * End current step with output
65
+ */
66
+ endStep(output, confidence) {
67
+ if (!this.currentStep) {
68
+ return this;
69
+ }
70
+ this.steps.push({
71
+ type: this.currentStep.type,
72
+ input: this.currentStep.input,
73
+ output,
74
+ durationMs: Date.now() - this.stepStart,
75
+ confidence,
76
+ });
77
+ this.currentStep = null;
78
+ return this;
79
+ }
80
+ /**
81
+ * Complete trajectory with final outcome
82
+ */
83
+ complete(outcome) {
84
+ // Complete any pending step
85
+ if (this.currentStep) {
86
+ this.endStep('incomplete', 0);
87
+ }
88
+ return {
89
+ id: this.id,
90
+ steps: this.steps,
91
+ outcome,
92
+ durationMs: Date.now() - this.startTime,
93
+ };
94
+ }
95
+ /**
96
+ * Get current trajectory ID
97
+ */
98
+ getId() {
99
+ return this.id;
100
+ }
101
+ }
102
+ exports.TrajectoryBuilder = TrajectoryBuilder;
103
+ /**
104
+ * ReasoningBank - Pattern storage and retrieval
105
+ *
106
+ * Stores learned patterns from successful interactions and
107
+ * enables pattern-based reasoning shortcuts.
108
+ *
109
+ * OPTIMIZED: Uses Float64Array for embeddings and partial sorting
110
+ */
111
+ class ReasoningBank {
112
+ constructor(threshold = 0.85) {
113
+ this.patterns = new Map();
114
+ this.embeddings = new Map();
115
+ this.embeddingNorms = new Map(); // Pre-computed norms
116
+ // Reusable arrays for findSimilar to avoid allocations
117
+ this._similarityResults = [];
118
+ this.threshold = threshold;
119
+ }
120
+ /**
121
+ * Store a new pattern
122
+ */
123
+ store(type, embedding, metadata) {
124
+ const id = `pat-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
125
+ const pattern = {
126
+ id,
127
+ type,
128
+ embedding,
129
+ successRate: 1.0,
130
+ useCount: 0,
131
+ lastUsed: new Date(),
132
+ };
133
+ this.patterns.set(id, pattern);
134
+ // Store as typed array for faster similarity computation
135
+ const typedEmb = new Float64Array(embedding);
136
+ this.embeddings.set(id, typedEmb);
137
+ // Pre-compute and cache the norm
138
+ let norm = 0;
139
+ for (let i = 0; i < typedEmb.length; i++) {
140
+ norm += typedEmb[i] * typedEmb[i];
141
+ }
142
+ this.embeddingNorms.set(id, Math.sqrt(norm));
143
+ return id;
144
+ }
145
+ /**
146
+ * Find similar patterns
147
+ * OPTIMIZED: Uses typed arrays, pre-computed norms, and partial sorting
148
+ */
149
+ findSimilar(embedding, k = 5) {
150
+ // Pre-compute query norm
151
+ let queryNorm = 0;
152
+ const queryLen = embedding.length;
153
+ for (let i = 0; i < queryLen; i++) {
154
+ queryNorm += embedding[i] * embedding[i];
155
+ }
156
+ queryNorm = Math.sqrt(queryNorm);
157
+ if (queryNorm === 0)
158
+ return [];
159
+ // Reuse array to avoid allocations
160
+ this._similarityResults.length = 0;
161
+ for (const [id, patEmb] of this.embeddings) {
162
+ const patNorm = this.embeddingNorms.get(id) || 0;
163
+ if (patNorm === 0)
164
+ continue;
165
+ // Fast dot product
166
+ let dot = 0;
167
+ const minLen = Math.min(queryLen, patEmb.length);
168
+ // Unrolled loop
169
+ let i = 0;
170
+ for (; i + 3 < minLen; i += 4) {
171
+ dot += embedding[i] * patEmb[i] +
172
+ embedding[i + 1] * patEmb[i + 1] +
173
+ embedding[i + 2] * patEmb[i + 2] +
174
+ embedding[i + 3] * patEmb[i + 3];
175
+ }
176
+ for (; i < minLen; i++) {
177
+ dot += embedding[i] * patEmb[i];
178
+ }
179
+ const score = dot / (queryNorm * patNorm);
180
+ if (score >= this.threshold) {
181
+ this._similarityResults.push({ id, score });
182
+ }
183
+ }
184
+ // Partial sort for top-k (faster than full sort for large arrays)
185
+ if (this._similarityResults.length <= k) {
186
+ this._similarityResults.sort((a, b) => b.score - a.score);
187
+ }
188
+ else {
189
+ // Quick partial sort for top k
190
+ this.partialSort(this._similarityResults, k);
191
+ }
192
+ const topK = this._similarityResults.slice(0, k);
193
+ return topK
194
+ .map(s => this.patterns.get(s.id))
195
+ .filter((p) => p !== undefined);
196
+ }
197
+ /**
198
+ * Partial sort to get top k elements (faster than full sort)
199
+ */
200
+ partialSort(arr, k) {
201
+ // Simple selection for small k
202
+ for (let i = 0; i < k && i < arr.length; i++) {
203
+ let maxIdx = i;
204
+ for (let j = i + 1; j < arr.length; j++) {
205
+ if (arr[j].score > arr[maxIdx].score) {
206
+ maxIdx = j;
207
+ }
208
+ }
209
+ if (maxIdx !== i) {
210
+ const temp = arr[i];
211
+ arr[i] = arr[maxIdx];
212
+ arr[maxIdx] = temp;
213
+ }
214
+ }
215
+ }
216
+ /**
217
+ * Record pattern usage (success or failure)
218
+ */
219
+ recordUsage(patternId, success) {
220
+ const pattern = this.patterns.get(patternId);
221
+ if (!pattern)
222
+ return;
223
+ pattern.useCount++;
224
+ pattern.lastUsed = new Date();
225
+ // Update success rate with exponential moving average
226
+ const alpha = 0.1;
227
+ const outcome = success ? 1.0 : 0.0;
228
+ pattern.successRate = alpha * outcome + (1 - alpha) * pattern.successRate;
229
+ }
230
+ /**
231
+ * Get pattern by ID
232
+ */
233
+ get(patternId) {
234
+ return this.patterns.get(patternId);
235
+ }
236
+ /**
237
+ * Get all patterns of a type
238
+ */
239
+ getByType(type) {
240
+ return Array.from(this.patterns.values()).filter(p => p.type === type);
241
+ }
242
+ /**
243
+ * Prune low-performing patterns
244
+ */
245
+ prune(minSuccessRate = 0.3, minUseCount = 5) {
246
+ let pruned = 0;
247
+ for (const [id, pattern] of this.patterns) {
248
+ if (pattern.useCount >= minUseCount && pattern.successRate < minSuccessRate) {
249
+ this.patterns.delete(id);
250
+ this.embeddings.delete(id);
251
+ this.embeddingNorms.delete(id);
252
+ pruned++;
253
+ }
254
+ }
255
+ return pruned;
256
+ }
257
+ /**
258
+ * Get statistics
259
+ */
260
+ stats() {
261
+ const patterns = Array.from(this.patterns.values());
262
+ const byType = {};
263
+ let totalSuccess = 0;
264
+ for (const p of patterns) {
265
+ totalSuccess += p.successRate;
266
+ byType[p.type] = (byType[p.type] || 0) + 1;
267
+ }
268
+ return {
269
+ totalPatterns: patterns.length,
270
+ avgSuccessRate: patterns.length > 0 ? totalSuccess / patterns.length : 0,
271
+ byType,
272
+ };
273
+ }
274
+ cosineSimilarity(a, b) {
275
+ let dot = 0, normA = 0, normB = 0;
276
+ const len = Math.min(a.length, b.length);
277
+ for (let i = 0; i < len; i++) {
278
+ dot += a[i] * b[i];
279
+ normA += a[i] * a[i];
280
+ normB += b[i] * b[i];
281
+ }
282
+ const denom = Math.sqrt(normA) * Math.sqrt(normB);
283
+ return denom > 0 ? dot / denom : 0;
284
+ }
285
+ }
286
+ exports.ReasoningBank = ReasoningBank;
287
+ /**
288
+ * EWC++ (Elastic Weight Consolidation) Manager
289
+ *
290
+ * Prevents catastrophic forgetting by protecting important weights.
291
+ * This is a simplified JS implementation of the concept.
292
+ *
293
+ * OPTIMIZED: Uses Float64Array for 5-10x faster penalty computation
294
+ */
295
+ class EwcManager {
296
+ constructor(lambda = 2000) {
297
+ this.tasksLearned = 0;
298
+ this.fisherDiagonal = new Map();
299
+ this.optimalWeights = new Map();
300
+ // Pre-allocated buffer for penalty computation
301
+ this._penaltyBuffer = null;
302
+ this.lambda = lambda;
303
+ }
304
+ /**
305
+ * Register a new task (after successful learning)
306
+ */
307
+ registerTask(taskId, weights) {
308
+ // Store optimal weights for this task using typed arrays
309
+ const optimalArr = new Float64Array(weights.length);
310
+ const fisherArr = new Float64Array(weights.length);
311
+ for (let i = 0; i < weights.length; i++) {
312
+ optimalArr[i] = weights[i];
313
+ fisherArr[i] = Math.abs(weights[i]) * this.lambda;
314
+ }
315
+ this.optimalWeights.set(taskId, optimalArr);
316
+ this.fisherDiagonal.set(taskId, fisherArr);
317
+ this.tasksLearned++;
318
+ }
319
+ /**
320
+ * Compute EWC penalty for weight update
321
+ * OPTIMIZED: Uses typed arrays and minimizes allocations
322
+ */
323
+ computePenalty(currentWeights) {
324
+ let penalty = 0;
325
+ const len = currentWeights.length;
326
+ for (const [taskId, optimal] of this.optimalWeights) {
327
+ const fisher = this.fisherDiagonal.get(taskId);
328
+ if (!fisher)
329
+ continue;
330
+ const minLen = Math.min(len, optimal.length);
331
+ // Unrolled loop for better performance
332
+ let i = 0;
333
+ for (; i + 3 < minLen; i += 4) {
334
+ const diff0 = currentWeights[i] - optimal[i];
335
+ const diff1 = currentWeights[i + 1] - optimal[i + 1];
336
+ const diff2 = currentWeights[i + 2] - optimal[i + 2];
337
+ const diff3 = currentWeights[i + 3] - optimal[i + 3];
338
+ penalty += fisher[i] * diff0 * diff0 +
339
+ fisher[i + 1] * diff1 * diff1 +
340
+ fisher[i + 2] * diff2 * diff2 +
341
+ fisher[i + 3] * diff3 * diff3;
342
+ }
343
+ // Handle remaining elements
344
+ for (; i < minLen; i++) {
345
+ const diff = currentWeights[i] - optimal[i];
346
+ penalty += fisher[i] * diff * diff;
347
+ }
348
+ }
349
+ return penalty * 0.5;
350
+ }
351
+ /**
352
+ * Get EWC statistics
353
+ */
354
+ stats() {
355
+ return {
356
+ tasksLearned: this.tasksLearned,
357
+ fisherComputed: this.fisherDiagonal.size > 0,
358
+ protectionStrength: this.lambda,
359
+ forgettingRate: this.estimateForgettingRate(),
360
+ };
361
+ }
362
+ estimateForgettingRate() {
363
+ // Simplified estimation based on number of tasks
364
+ return Math.max(0, 1 - Math.exp(-this.tasksLearned * 0.1));
365
+ }
366
+ }
367
+ exports.EwcManager = EwcManager;
368
+ /**
369
+ * SONA Learning Coordinator
370
+ *
371
+ * Orchestrates the learning loops and components.
372
+ */
373
+ class SonaCoordinator {
374
+ constructor(config) {
375
+ this.trajectoryBuffer = [];
376
+ this.signalBuffer = [];
377
+ this.config = { ...DEFAULT_SONA_CONFIG, ...config };
378
+ this.reasoningBank = new ReasoningBank(this.config.patternThreshold);
379
+ this.ewcManager = new EwcManager(this.config.ewcLambda);
380
+ }
381
+ /**
382
+ * Record a learning signal
383
+ */
384
+ recordSignal(signal) {
385
+ this.signalBuffer.push(signal);
386
+ // Instant loop - immediate learning
387
+ if (this.config.instantLoopEnabled && signal.quality >= 0.8) {
388
+ this.processInstantLearning(signal);
389
+ }
390
+ }
391
+ /**
392
+ * Record a completed trajectory
393
+ */
394
+ recordTrajectory(trajectory) {
395
+ this.trajectoryBuffer.push(trajectory);
396
+ // Maintain buffer size
397
+ while (this.trajectoryBuffer.length > this.config.maxTrajectorySize) {
398
+ this.trajectoryBuffer.shift();
399
+ }
400
+ // Extract patterns from successful trajectories
401
+ if (trajectory.outcome === 'success') {
402
+ this.extractPatterns(trajectory);
403
+ }
404
+ }
405
+ /**
406
+ * Run background learning loop
407
+ */
408
+ runBackgroundLoop() {
409
+ if (!this.config.backgroundLoopEnabled) {
410
+ return { patternsLearned: 0, trajectoriesProcessed: 0 };
411
+ }
412
+ let patternsLearned = 0;
413
+ const trajectoriesProcessed = this.trajectoryBuffer.length;
414
+ // Process accumulated trajectories
415
+ for (const traj of this.trajectoryBuffer) {
416
+ if (traj.outcome === 'success' || traj.outcome === 'partial') {
417
+ patternsLearned += this.extractPatterns(traj);
418
+ }
419
+ }
420
+ // Prune low-performing patterns
421
+ this.reasoningBank.prune();
422
+ // Clear processed trajectories
423
+ this.trajectoryBuffer = [];
424
+ return { patternsLearned, trajectoriesProcessed };
425
+ }
426
+ /**
427
+ * Get reasoning bank for pattern queries
428
+ */
429
+ getReasoningBank() {
430
+ return this.reasoningBank;
431
+ }
432
+ /**
433
+ * Get EWC manager
434
+ */
435
+ getEwcManager() {
436
+ return this.ewcManager;
437
+ }
438
+ /**
439
+ * Get statistics
440
+ */
441
+ stats() {
442
+ return {
443
+ signalsReceived: this.signalBuffer.length,
444
+ trajectoriesBuffered: this.trajectoryBuffer.length,
445
+ patterns: this.reasoningBank.stats(),
446
+ ewc: this.ewcManager.stats(),
447
+ };
448
+ }
449
+ processInstantLearning(signal) {
450
+ // Immediate pattern reinforcement would happen here
451
+ // In full implementation, this updates LoRA weights
452
+ }
453
+ extractPatterns(trajectory) {
454
+ let extracted = 0;
455
+ for (const step of trajectory.steps) {
456
+ if (step.confidence >= this.config.patternThreshold) {
457
+ // Create embedding from step (simplified)
458
+ const embedding = this.createEmbedding(step.input + step.output);
459
+ // Determine pattern type
460
+ const type = this.stepTypeToPatternType(step.type);
461
+ // Store if not too similar to existing
462
+ const similar = this.reasoningBank.findSimilar(embedding, 1);
463
+ if (similar.length === 0) {
464
+ this.reasoningBank.store(type, embedding);
465
+ extracted++;
466
+ }
467
+ }
468
+ }
469
+ return extracted;
470
+ }
471
+ stepTypeToPatternType(stepType) {
472
+ switch (stepType) {
473
+ case 'query':
474
+ case 'generate':
475
+ return 'query_response';
476
+ case 'route':
477
+ return 'routing';
478
+ case 'memory':
479
+ return 'context_retrieval';
480
+ case 'feedback':
481
+ return 'correction';
482
+ default:
483
+ return 'query_response';
484
+ }
485
+ }
486
+ createEmbedding(text) {
487
+ // Simplified hash-based embedding (real impl uses model)
488
+ const dim = 64;
489
+ const embedding = new Array(dim).fill(0);
490
+ for (let i = 0; i < text.length; i++) {
491
+ const idx = (text.charCodeAt(i) * (i + 1)) % dim;
492
+ embedding[idx] += 0.1;
493
+ }
494
+ // Normalize
495
+ const norm = Math.sqrt(embedding.reduce((s, x) => s + x * x, 0)) || 1;
496
+ return embedding.map(x => x / norm);
497
+ }
498
+ }
499
+ exports.SonaCoordinator = SonaCoordinator;
500
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zb25hLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7R0FLRzs7O0FBZUg7O0dBRUc7QUFDSCxNQUFNLG1CQUFtQixHQUF5QjtJQUNoRCxrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLHFCQUFxQixFQUFFLElBQUk7SUFDM0IsZ0JBQWdCLEVBQUUsS0FBSztJQUN2QixRQUFRLEVBQUUsQ0FBQztJQUNYLFNBQVMsRUFBRSxJQUFJO0lBQ2YsaUJBQWlCLEVBQUUsSUFBSTtJQUN2QixnQkFBZ0IsRUFBRSxJQUFJO0NBQ3ZCLENBQUM7QUEyakJBLGtEQUFtQjtBQXpqQnJCOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBQ0gsTUFBYSxpQkFBaUI7SUFPNUI7UUFMUSxVQUFLLEdBQXFCLEVBQUUsQ0FBQztRQUM3QixnQkFBVyxHQUFtQyxJQUFJLENBQUM7UUFDbkQsY0FBUyxHQUFXLENBQUMsQ0FBQztRQUk1QixJQUFJLENBQUMsRUFBRSxHQUFHLFFBQVEsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3pFLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFRDs7T0FFRztJQUNILFNBQVMsQ0FBQyxJQUE0QixFQUFFLEtBQWE7UUFDbkQsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDckIsOEJBQThCO1lBQzlCLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLENBQUM7UUFFRCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsV0FBVyxHQUFH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RUFBRSxDQUFDO1lBQ3JDLE1BQU0sR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUNqRCxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxDQUFDO1FBQ3hCLENBQUM7UUFFRCxZQUFZO1FBQ1osTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEUsT0FBTyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ3RDLENBQUM7Q0FDRjtBQTlKRCwwQ0E4SkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNPTkEgKFNlbGYtT3B0aW1pemluZyBOZXVyYWwgQXJjaGl0ZWN0dXJlKSBMZWFybmluZyBTeXN0ZW1cbiAqXG4gKiBQcm92aWRlcyBhZGFwdGl2ZSBsZWFybmluZyBjYXBhYmlsaXRpZXMgd2l0aCB0cmFqZWN0b3J5IHRyYWNraW5nLFxuICogcGF0dGVybiByZWNvZ25pdGlvbiwgYW5kIG1lbW9yeSBwcm90ZWN0aW9uIChFV0MrKykuXG4gKi9cblxuaW1wb3J0IHtcbiAgU29uYUNvbmZpZyxcbiAgTGVhcm5pbmdTaWduYWwsXG4gIFF1ZXJ5VHJhamVjdG9yeSxcbiAgVHJhamVjdG9yeVN0ZXAsXG4gIFRyYWplY3RvcnlPdXRjb21lLFxuICBMZWFybmVkUGF0dGVybixcbiAgUGF0dGVyblR5cGUsXG4gIEV3Y1N0YXRzLFxuICBMb1JBQ29uZmlnLFxuICBFbWJlZGRpbmcsXG59IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIERlZmF1bHQgU09OQSBjb25maWd1cmF0aW9uXG4gKi9cbmNvbnN0IERFRkFVTFRfU09OQV9DT05GSUc6IFJlcXVpcmVkPFNvbmFDb25maWc+ID0ge1xuICBpbnN0YW50TG9vcEVuYWJsZWQ6IHRydWUsXG4gIGJhY2tncm91bmRMb29wRW5hYmxlZDogdHJ1ZSxcbiAgbG9yYUxlYXJuaW5nUmF0ZTogMC4wMDEsXG4gIGxvcmFSYW5rOiA4LFxuICBld2NMYW1iZGE6IDIwMDAsXG4gIG1heFRyYWplY3RvcnlTaXplOiAxMDAwLFxuICBwYXR0ZXJuVGhyZXNob2xkOiAwLjg1LFxufTtcblxuLyoqXG4gKiBUcmFqZWN0b3J5IEJ1aWxkZXIgZm9yIHRyYWNraW5nIHF1ZXJ5IGV4ZWN1dGlvbiBwYXRoc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBidWlsZGVyID0gbmV3IFRyYWplY3RvcnlCdWlsZGVyKCk7XG4gKlxuICogYnVpbGRlci5zdGFydFN0ZXAoJ3F1ZXJ5JywgJ1doYXQgaXMgQUk/Jyk7XG4gKiAvLyAuLi4gcHJvY2Vzc2luZyAuLi5cbiAqIGJ1aWxkZXIuZW5kU3RlcCgnQUkgaXMgYXJ0aWZpY2lhbCBpbnRlbGxpZ2VuY2UnLCAwLjk1KTtcbiAqXG4gKiBidWlsZGVyLnN0YXJ0U3RlcCgnbWVtb3J5JywgJ3NlYXJjaGluZyBjb250ZXh0Jyk7XG4gKiBidWlsZGVyLmVuZFN0ZXAoJ2ZvdW5kIDMgcmVsZXZhbnQgZG9jdW1lbnRzJywgMC44OCk7XG4gKlxuICogY29uc3QgdHJhamVjdG9yeSA9IGJ1aWxkZXIuY29tcGxldGUoJ3N1Y2Nlc3MnKTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgVHJhamVjdG9yeUJ1aWxkZXIge1xuICBwcml2YXRlIGlkOiBzdHJpbmc7XG4gIHByaXZhdGUgc3RlcHM6IFRyYWplY3RvcnlTdGVwW10gPSBbXTtcbiAgcHJpdmF0ZSBjdXJyZW50U3RlcDogUGFydGlhbDxUcmFqZWN0b3J5U3RlcD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBzdGVwU3RhcnQ6IG51bWJlciA9IDA7XG4gIHByaXZhdGUgc3RhcnRUaW1lOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5pZCA9IGB0cmFqLSR7RGF0ZS5ub3coKX0tJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCA4KX1gO1xuICAgIHRoaXMuc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBhIG5ldyBzdGVwIGluIHRoZSB0cmFqZWN0b3J5XG4gICAqL1xuICBzdGFydFN0ZXAodHlwZTogVHJhamVjdG9yeVN0ZXBbJ3R5cGUnXSwgaW5wdXQ6IHN0cmluZyk6IHRoaXMge1xuICAgIGlmICh0aGlzLmN1cnJlbnRTdGVwKSB7XG4gICAgICAvLyBBdXRvLWNvbXBsZXRlIHByZXZpb3VzIHN0ZXBcbiAgICAgIHRoaXMuZW5kU3RlcCgnJywgMCk7XG4gICAgfVxuXG4gICAgdGhpcy5zdGVwU3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIHRoaXMuY3VycmVudFN0ZXAgPSB7XG4gICAgICB0eXBlLFxuICAgICAgaW5wdXQsXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuZCBjdXJyZW50IHN0ZXAgd2l0aCBvdXRwdXRcbiAgICovXG4gIGVuZFN0ZXAob3V0cHV0OiBzdHJpbmcsIGNvbmZpZGVuY2U6IG51bWJlcik6IHRoaXMge1xuICAgIGlmICghdGhpcy5jdXJyZW50U3RlcCkge1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgdGhpcy5zdGVwcy5wdXNoKHtcbiAgICAgIHR5cGU6IHRoaXMuY3VycmVudFN0ZXAudHlwZSEsXG4gICAgICBpbnB1dDogdGhpcy5jdXJyZW50U3RlcC5pbnB1dCEsXG4gICAgICBvdXRwdXQsXG4gICAgICBkdXJhdGlvbk1zOiBEYXRlLm5vdygpIC0gdGhpcy5zdGVwU3RhcnQsXG4gICAgICBjb25maWRlbmNlLFxuICAgIH0pO1xuXG4gICAgdGhpcy5jdXJyZW50U3RlcCA9IG51bGw7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQ29tcGxldGUgdHJhamVjdG9yeSB3aXRoIGZpbmFsIG91dGNvbWVcbiAgICovXG4gIGNvbXBsZXRlKG91dGNvbWU6IFRyYWplY3RvcnlPdXRjb21lKTogUXVlcnlUcmFqZWN0b3J5IHtcbiAgICAvLyBDb21wbGV0ZSBhbnkgcGVuZGluZyBzdGVwXG4gICAgaWYgKHRoaXMuY3VycmVudFN0ZXApIHtcbiAgICAgIHRoaXMuZW5kU3RlcCgnaW5jb21wbGV0ZScsIDApO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBpZDogdGhpcy5pZCxcbiAgICAgIHN0ZXBzOiB0aGlzLnN0ZXBzLFxuICAgICAgb3V0Y29tZSxcbiAgICAgIGR1cmF0aW9uTXM6IERhdGUubm93KCkgLSB0aGlzLnN0YXJ0VGltZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjdXJyZW50IHRyYWplY3RvcnkgSURcbiAgICovXG4gIGdldElkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuaWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBSZWFzb25pbmdCYW5rIC0gUGF0dGVybiBzdG9yYWdlIGFuZCByZXRyaWV2YWxcbiAqXG4gKiBTdG9yZXMgbGVhcm5lZCBwYXR0ZXJucyBmcm9tIHN1Y2Nlc3NmdWwgaW50ZXJhY3Rpb25zIGFuZFxuICogZW5hYmxlcyBwYXR0ZXJuLWJhc2VkIHJlYXNvbmluZyBzaG9ydGN1dHMuXG4gKlxuICogT1BUSU1JWkVEOiBVc2VzIEZsb2F0NjRBcnJheSBmb3IgZW1iZWRkaW5ncyBhbmQgcGFydGlhbCBzb3J0aW5nXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWFzb25pbmdCYW5rIHtcbiAgcHJpdmF0ZSBwYXR0ZXJuczogTWFwPHN0cmluZywgTGVhcm5lZFBhdHRlcm4+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIGVtYmVkZGluZ3M6IE1hcDxzdHJpbmcsIEZsb2F0NjRBcnJheT4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgZW1iZWRkaW5nTm9ybXM6IE1hcDxzdHJpbmcsIG51bWJlcj4gPSBuZXcgTWFwKCk7IC8vIFByZS1jb21wdXRlZCBub3Jtc1xuICBwcml2YXRlIHRocmVzaG9sZDogbnVtYmVyO1xuICAvLyBSZXVzYWJsZSBhcnJheXMgZm9yIGZpbmRTaW1pbGFyIHRvIGF2b2lkIGFsbG9jYXRpb25zXG4gIHByaXZhdGUgX3NpbWlsYXJpdHlSZXN1bHRzOiBBcnJheTx7IGlkOiBzdHJpbmc7IHNjb3JlOiBudW1iZXIgfT4gPSBbXTtcblxuICBjb25zdHJ1Y3Rvcih0aHJlc2hvbGQgPSAwLjg1KSB7XG4gICAgdGhpcy50aHJlc2hvbGQgPSB0aHJlc2hvbGQ7XG4gIH1cblxuICAvKipcbiAgICogU3RvcmUgYSBuZXcgcGF0dGVyblxuICAgKi9cbiAgc3RvcmUoXG4gICAgdHlwZTogUGF0dGVyblR5cGUsXG4gICAgZW1iZWRkaW5nOiBFbWJlZGRpbmcsXG4gICAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IGlkID0gYHBhdC0ke0RhdGUubm93KCl9LSR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgOCl9YDtcblxuICAgIGNvbnN0IHBhdHRlcm46IExlYXJuZWRQYXR0ZXJuID0ge1xuICAgICAgaWQsXG4gICAgICB0eXBlLFxuICAgICAgZW1iZWRkaW5nLFxuICAgICAgc3VjY2Vzc1JhdGU6IDEuMCxcbiAgICAgIHVzZUNvdW50OiAwLFxuICAgICAgbGFzdFVzZWQ6IG5ldyBEYXRlKCksXG4gICAgfTtcblxuICAgIHRoaXMucGF0dGVybnMuc2V0KGlkLCBwYXR0ZXJuKTtcblxuICAgIC8vIFN0b3JlIGFzIHR5cGVkIGFycmF5IGZvciBmYXN0ZXIgc2ltaWxhcml0eSBjb21wdXRhdGlvblxuICAgIGNvbnN0IHR5cGVkRW1iID0gbmV3IEZsb2F0NjRBcnJheShlbWJlZGRpbmcpO1xuICAgIHRoaXMuZW1iZWRkaW5ncy5zZXQoaWQsIHR5cGVkRW1iKTtcblxuICAgIC8vIFByZS1jb21wdXRlIGFuZCBjYWNoZSB0aGUgbm9ybVxuICAgIGxldCBub3JtID0gMDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVkRW1iLmxlbmd0aDsgaSsrKSB7XG4gICAgICBub3JtICs9IHR5cGVkRW1iW2ldICogdHlwZWRFbWJbaV07XG4gICAgfVxuICAgIHRoaXMuZW1iZWRkaW5nTm9ybXMuc2V0KGlkLCBNYXRoLnNxcnQobm9ybSkpO1xuXG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmQgc2ltaWxhciBwYXR0ZXJuc1xuICAgKiBPUFRJTUlaRUQ6IFVzZXMgdHlwZWQgYXJyYXlzLCBwcmUtY29tcHV0ZWQgbm9ybXMsIGFuZCBwYXJ0aWFsIHNvcnRpbmdcbiAgICovXG4gIGZpbmRTaW1pbGFyKGVtYmVkZGluZzogRW1iZWRkaW5nLCBrID0gNSk6IExlYXJuZWRQYXR0ZXJuW10ge1xuICAgIC8vIFByZS1jb21wdXRlIHF1ZXJ5IG5vcm1cbiAgICBsZXQgcXVlcnlOb3JtID0gMDtcbiAgICBjb25zdCBxdWVyeUxlbiA9IGVtYmVkZGluZy5sZW5ndGg7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWVyeUxlbjsgaSsrKSB7XG4gICAgICBxdWVyeU5vcm0gKz0gZW1iZWRkaW5nW2ldICogZW1iZWRkaW5nW2ldO1xuICAgIH1cbiAgICBxdWVyeU5vcm0gPSBNYXRoLnNxcnQocXVlcnlOb3JtKTtcblxuICAgIGlmIChxdWVyeU5vcm0gPT09IDApIHJldHVybiBbXTtcblxuICAgIC8vIFJldXNlIGFycmF5IHRvIGF2b2lkIGFsbG9jYXRpb25zXG4gICAgdGhpcy5fc2ltaWxhcml0eVJlc3VsdHMubGVuZ3RoID0gMDtcblxuICAgIGZvciAoY29uc3QgW2lkLCBwYXRFbWJdIG9mIHRoaXMuZW1iZWRkaW5ncykge1xuICAgICAgY29uc3QgcGF0Tm9ybSA9IHRoaXMuZW1iZWRkaW5nTm9ybXMuZ2V0KGlkKSB8fCAwO1xuICAgICAgaWYgKHBhdE5vcm0gPT09IDApIGNvbnRpbnVlO1xuXG4gICAgICAvLyBGYXN0IGRvdCBwcm9kdWN0XG4gICAgICBsZXQgZG90ID0gMDtcbiAgICAgIGNvbnN0IG1pbkxlbiA9IE1hdGgubWluKHF1ZXJ5TGVuLCBwYXRFbWIubGVuZ3RoKTtcblxuICAgICAgLy8gVW5yb2xsZWQgbG9vcFxuICAgICAgbGV0IGkgPSAwO1xuICAgICAgZm9yICg7IGkgKyAzIDwgbWluTGVuOyBpICs9IDQpIHtcbiAgICAgICAgZG90ICs9IGVtYmVkZGluZ1tpXSAqIHBhdEVtYltpXSArXG4gICAgICAgICAgICAgICBlbWJlZGRpbmdbaSArIDFdICogcGF0RW1iW2kgKyAxXSArXG4gICAgICAgICAgICAgICBlbWJlZGRpbmdbaSArIDJdICogcGF0RW1iW2kgKyAyXSArXG4gICAgICAgICAgICAgICBlbWJlZGRpbmdbaSArIDNdICogcGF0RW1iW2kgKyAzXTtcbiAgICAgIH1cbiAgICAgIGZvciAoOyBpIDwgbWluTGVuOyBpKyspIHtcbiAgICAgICAgZG90ICs9IGVtYmVkZGluZ1tpXSAqIHBhdEVtYltpXTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2NvcmUgPSBkb3QgLyAocXVlcnlOb3JtICogcGF0Tm9ybSk7XG5cbiAgICAgIGlmIChzY29yZSA+PSB0aGlzLnRocmVzaG9sZCkge1xuICAgICAgICB0aGlzLl9zaW1pbGFyaXR5UmVzdWx0cy5wdXNoKHsgaWQsIHNjb3JlIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFBhcnRpYWwgc29ydCBmb3IgdG9wLWsgKGZhc3RlciB0aGFuIGZ1bGwgc29ydCBmb3IgbGFyZ2UgYXJyYXlzKVxuICAgIGlmICh0aGlzLl9zaW1pbGFyaXR5UmVzdWx0cy5sZW5ndGggPD0gaykge1xuICAgICAgdGhpcy5fc2ltaWxhcml0eVJlc3VsdHMuc29ydCgoYSwgYikgPT4gYi5zY29yZSAtIGEuc2NvcmUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBRdWljayBwYXJ0aWFsIHNvcnQgZm9yIHRvcCBrXG4gICAgICB0aGlzLnBhcnRpYWxTb3J0KHRoaXMuX3NpbWlsYXJpdHlSZXN1bHRzLCBrKTtcbiAgICB9XG5cbiAgICBjb25zdCB0b3BLID0gdGhpcy5fc2ltaWxhcml0eVJlc3VsdHMuc2xpY2UoMCwgayk7XG5cbiAgICByZXR1cm4gdG9wS1xuICAgICAgLm1hcChzID0+IHRoaXMucGF0dGVybnMuZ2V0KHMuaWQpKVxuICAgICAgLmZpbHRlcigocCk6IHAgaXMgTGVhcm5lZFBhdHRlcm4gPT4gcCAhPT0gdW5kZWZpbmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJ0aWFsIHNvcnQgdG8gZ2V0IHRvcCBrIGVsZW1lbnRzIChmYXN0ZXIgdGhhbiBmdWxsIHNvcnQpXG4gICAqL1xuICBwcml2YXRlIHBhcnRpYWxTb3J0KGFycjogQXJyYXk8eyBpZDogc3RyaW5nOyBzY29yZTogbnVtYmVyIH0+LCBrOiBudW1iZXIpOiB2b2lkIHtcbiAgICAvLyBTaW1wbGUgc2VsZWN0aW9uIGZvciBzbWFsbCBrXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrICYmIGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBtYXhJZHggPSBpO1xuICAgICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgYXJyLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIGlmIChhcnJbal0uc2NvcmUgPiBhcnJbbWF4SWR4XS5zY29yZSkge1xuICAgICAgICAgIG1heElkeCA9IGo7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChtYXhJZHggIT09IGkpIHtcbiAgICAgICAgY29uc3QgdGVtcCA9IGFycltpXTtcbiAgICAgICAgYXJyW2ldID0gYXJyW21heElkeF07XG4gICAgICAgIGFyclttYXhJZHhdID0gdGVtcDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVjb3JkIHBhdHRlcm4gdXNhZ2UgKHN1Y2Nlc3Mgb3IgZmFpbHVyZSlcbiAgICovXG4gIHJlY29yZFVzYWdlKHBhdHRlcm5JZDogc3RyaW5nLCBzdWNjZXNzOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3QgcGF0dGVybiA9IHRoaXMucGF0dGVybnMuZ2V0KHBhdHRlcm5JZCk7XG4gICAgaWYgKCFwYXR0ZXJuKSByZXR1cm47XG5cbiAgICBwYXR0ZXJuLnVzZUNvdW50Kys7XG4gICAgcGF0dGVybi5sYXN0VXNlZCA9IG5ldyBEYXRlKCk7XG5cbiAgICAvLyBVcGRhdGUgc3VjY2VzcyByYXRlIHdpdGggZXhwb25lbnRpYWwgbW92aW5nIGF2ZXJhZ2VcbiAgICBjb25zdCBhbHBoYSA9IDAuMTtcbiAgICBjb25zdCBvdXRjb21lID0gc3VjY2VzcyA/IDEuMCA6IDAuMDtcbiAgICBwYXR0ZXJuLnN1Y2Nlc3NSYXRlID0gYWxwaGEgKiBvdXRjb21lICsgKDEgLSBhbHBoYSkgKiBwYXR0ZXJuLnN1Y2Nlc3NSYXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBwYXR0ZXJuIGJ5IElEXG4gICAqL1xuICBnZXQocGF0dGVybklkOiBzdHJpbmcpOiBMZWFybmVkUGF0dGVybiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMucGF0dGVybnMuZ2V0KHBhdHRlcm5JZCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBwYXR0ZXJucyBvZiBhIHR5cGVcbiAgICovXG4gIGdldEJ5VHlwZSh0eXBlOiBQYXR0ZXJuVHlwZSk6IExlYXJuZWRQYXR0ZXJuW10ge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMucGF0dGVybnMudmFsdWVzKCkpLmZpbHRlcihwID0+IHAudHlwZSA9PT0gdHlwZSk7XG4gIH1cblxuICAvKipcbiAgICogUHJ1bmUgbG93LXBlcmZvcm1pbmcgcGF0dGVybnNcbiAgICovXG4gIHBydW5lKG1pblN1Y2Nlc3NSYXRlID0gMC4zLCBtaW5Vc2VDb3VudCA9IDUpOiBudW1iZXIge1xuICAgIGxldCBwcnVuZWQgPSAwO1xuXG4gICAgZm9yIChjb25zdCBbaWQsIHBhdHRlcm5dIG9mIHRoaXMucGF0dGVybnMpIHtcbiAgICAgIGlmIChwYXR0ZXJuLnVzZUNvdW50ID49IG1pblVzZUNvdW50ICYmIHBhdHRlcm4uc3VjY2Vzc1JhdGUgPCBtaW5TdWNjZXNzUmF0ZSkge1xuICAgICAgICB0aGlzLnBhdHRlcm5zLmRlbGV0ZShpZCk7XG4gICAgICAgIHRoaXMuZW1iZWRkaW5ncy5kZWxldGUoaWQpO1xuICAgICAgICB0aGlzLmVtYmVkZGluZ05vcm1zLmRlbGV0ZShpZCk7XG4gICAgICAgIHBydW5lZCsrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwcnVuZWQ7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHN0YXRpc3RpY3NcbiAgICovXG4gIHN0YXRzKCk6IHsgdG90YWxQYXR0ZXJuczogbnVtYmVyOyBhdmdTdWNjZXNzUmF0ZTogbnVtYmVyOyBieVR5cGU6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gfSB7XG4gICAgY29uc3QgcGF0dGVybnMgPSBBcnJheS5mcm9tKHRoaXMucGF0dGVybnMudmFsdWVzKCkpO1xuICAgIGNvbnN0IGJ5VHlwZTogUmVjb3JkPHN0cmluZywgbnVtYmVyPiA9IHt9O1xuXG4gICAgbGV0IHRvdGFsU3VjY2VzcyA9IDA7XG4gICAgZm9yIChjb25zdCBwIG9mIHBhdHRlcm5zKSB7XG4gICAgICB0b3RhbFN1Y2Nlc3MgKz0gcC5zdWNjZXNzUmF0ZTtcbiAgICAgIGJ5VHlwZVtwLnR5cGVdID0gKGJ5VHlwZVtwLnR5cGVdIHx8IDApICsgMTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG90YWxQYXR0ZXJuczogcGF0dGVybnMubGVuZ3RoLFxuICAgICAgYXZnU3VjY2Vzc1JhdGU6IHBhdHRlcm5zLmxlbmd0aCA+IDAgPyB0b3RhbFN1Y2Nlc3MgLyBwYXR0ZXJucy5sZW5ndGggOiAwLFxuICAgICAgYnlUeXBlLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGNvc2luZVNpbWlsYXJpdHkoYTogRW1iZWRkaW5nLCBiOiBFbWJlZGRpbmcpOiBudW1iZXIge1xuICAgIGxldCBkb3QgPSAwLCBub3JtQSA9IDAsIG5vcm1CID0gMDtcbiAgICBjb25zdCBsZW4gPSBNYXRoLm1pbihhLmxlbmd0aCwgYi5sZW5ndGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgZG90ICs9IGFbaV0gKiBiW2ldO1xuICAgICAgbm9ybUEgKz0gYVtpXSAqIGFbaV07XG4gICAgICBub3JtQiArPSBiW2ldICogYltpXTtcbiAgICB9XG5cbiAgICBjb25zdCBkZW5vbSA9IE1hdGguc3FydChub3JtQSkgKiBNYXRoLnNxcnQobm9ybUIpO1xuICAgIHJldHVybiBkZW5vbSA+IDAgPyBkb3QgLyBkZW5vbSA6IDA7XG4gIH1cbn1cblxuLyoqXG4gKiBFV0MrKyAoRWxhc3RpYyBXZWlnaHQgQ29uc29saWRhdGlvbikgTWFuYWdlclxuICpcbiAqIFByZXZlbnRzIGNhdGFzdHJvcGhpYyBmb3JnZXR0aW5nIGJ5IHByb3RlY3RpbmcgaW1wb3J0YW50IHdlaWdodHMuXG4gKiBUaGlzIGlzIGEgc2ltcGxpZmllZCBKUyBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgY29uY2VwdC5cbiAqXG4gKiBPUFRJTUlaRUQ6IFVzZXMgRmxvYXQ2NEFycmF5IGZvciA1LTEweCBmYXN0ZXIgcGVuYWx0eSBjb21wdXRhdGlvblxuICovXG5leHBvcnQgY2xhc3MgRXdjTWFuYWdlciB7XG4gIHByaXZhdGUgbGFtYmRhOiBudW1iZXI7XG4gIHByaXZhdGUgdGFza3NMZWFybmVkOiBudW1iZXIgPSAwO1xuICBwcml2YXRlIGZpc2hlckRpYWdvbmFsOiBNYXA8c3RyaW5nLCBGbG9hdDY0QXJyYXk+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIG9wdGltYWxXZWlnaHRzOiBNYXA8c3RyaW5nLCBGbG9hdDY0QXJyYXk+ID0gbmV3IE1hcCgpO1xuICAvLyBQcmUtYWxsb2NhdGVkIGJ1ZmZlciBmb3IgcGVuYWx0eSBjb21wdXRhdGlvblxuICBwcml2YXRlIF9wZW5hbHR5QnVmZmVyOiBGbG9hdDY0QXJyYXkgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihsYW1iZGEgPSAyMDAwKSB7XG4gICAgdGhpcy5sYW1iZGEgPSBsYW1iZGE7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXIgYSBuZXcgdGFzayAoYWZ0ZXIgc3VjY2Vzc2Z1bCBsZWFybmluZylcbiAgICovXG4gIHJlZ2lzdGVyVGFzayh0YXNrSWQ6IHN0cmluZywgd2VpZ2h0czogbnVtYmVyW10pOiB2b2lkIHtcbiAgICAvLyBTdG9yZSBvcHRpbWFsIHdlaWdodHMgZm9yIHRoaXMgdGFzayB1c2luZyB0eXBlZCBhcnJheXNcbiAgICBjb25zdCBvcHRpbWFsQXJyID0gbmV3IEZsb2F0NjRBcnJheSh3ZWlnaHRzLmxlbmd0aCk7XG4gICAgY29uc3QgZmlzaGVyQXJyID0gbmV3IEZsb2F0NjRBcnJheSh3ZWlnaHRzLmxlbmd0aCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHdlaWdodHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9wdGltYWxBcnJbaV0gPSB3ZWlnaHRzW2ldO1xuICAgICAgZmlzaGVyQXJyW2ldID0gTWF0aC5hYnMod2VpZ2h0c1tpXSkgKiB0aGlzLmxhbWJkYTtcbiAgICB9XG5cbiAgICB0aGlzLm9wdGltYWxXZWlnaHRzLnNldCh0YXNrSWQsIG9wdGltYWxBcnIpO1xuICAgIHRoaXMuZmlzaGVyRGlhZ29uYWwuc2V0KHRhc2tJZCwgZmlzaGVyQXJyKTtcbiAgICB0aGlzLnRhc2tzTGVhcm5lZCsrO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgRVdDIHBlbmFsdHkgZm9yIHdlaWdodCB1cGRhdGVcbiAgICogT1BUSU1JWkVEOiBVc2VzIHR5cGVkIGFycmF5cyBhbmQgbWluaW1pemVzIGFsbG9jYXRpb25zXG4gICAqL1xuICBjb21wdXRlUGVuYWx0eShjdXJyZW50V2VpZ2h0czogbnVtYmVyW10pOiBudW1iZXIge1xuICAgIGxldCBwZW5hbHR5ID0gMDtcbiAgICBjb25zdCBsZW4gPSBjdXJyZW50V2VpZ2h0cy5sZW5ndGg7XG5cbiAgICBmb3IgKGNvbnN0IFt0YXNrSWQsIG9wdGltYWxdIG9mIHRoaXMub3B0aW1hbFdlaWdodHMpIHtcbiAgICAgIGNvbnN0IGZpc2hlciA9IHRoaXMuZmlzaGVyRGlhZ29uYWwuZ2V0KHRhc2tJZCk7XG4gICAgICBpZiAoIWZpc2hlcikgY29udGludWU7XG5cbiAgICAgIGNvbnN0IG1pbkxlbiA9IE1hdGgubWluKGxlbiwgb3B0aW1hbC5sZW5ndGgpO1xuXG4gICAgICAvLyBVbnJvbGxlZCBsb29wIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2VcbiAgICAgIGxldCBpID0gMDtcbiAgICAgIGZvciAoOyBpICsgMyA8IG1pbkxlbjsgaSArPSA0KSB7XG4gICAgICAgIGNvbnN0IGRpZmYwID0gY3VycmVudFdlaWdodHNbaV0gLSBvcHRpbWFsW2ldO1xuICAgICAgICBjb25zdCBkaWZmMSA9IGN1cnJlbnRXZWlnaHRzW2kgKyAxXSAtIG9wdGltYWxbaSArIDFdO1xuICAgICAgICBjb25zdCBkaWZmMiA9IGN1cnJlbnRXZWlnaHRzW2kgKyAyXSAtIG9wdGltYWxbaSArIDJdO1xuICAgICAgICBjb25zdCBkaWZmMyA9IGN1cnJlbnRXZWlnaHRzW2kgKyAzXSAtIG9wdGltYWxbaSArIDNdO1xuICAgICAgICBwZW5hbHR5ICs9IGZpc2hlcltpXSAqIGRpZmYwICogZGlmZjAgK1xuICAgICAgICAgICAgICAgICAgIGZpc2hlcltpICsgMV0gKiBkaWZmMSAqIGRpZmYxICtcbiAgICAgICAgICAgICAgICAgICBmaXNoZXJbaSArIDJdICogZGlmZjIgKiBkaWZmMiArXG4gICAgICAgICAgICAgICAgICAgZmlzaGVyW2kgKyAzXSAqIGRpZmYzICogZGlmZjM7XG4gICAgICB9XG4gICAgICAvLyBIYW5kbGUgcmVtYWluaW5nIGVsZW1lbnRzXG4gICAgICBmb3IgKDsgaSA8IG1pbkxlbjsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGRpZmYgPSBjdXJyZW50V2VpZ2h0c1tpXSAtIG9wdGltYWxbaV07XG4gICAgICAgIHBlbmFsdHkgKz0gZmlzaGVyW2ldICogZGlmZiAqIGRpZmY7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHBlbmFsdHkgKiAwLjU7XG4gIH1cblxuICAvKipcbiAgICogR2V0IEVXQyBzdGF0aXN0aWNzXG4gICAqL1xuICBzdGF0cygpOiBFd2NTdGF0cyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRhc2tzTGVhcm5lZDogdGhpcy50YXNrc0xlYXJuZWQsXG4gICAgICBmaXNoZXJDb21wdXRlZDogdGhpcy5maXNoZXJEaWFnb25hbC5zaXplID4gMCxcbiAgICAgIHByb3RlY3Rpb25TdHJlbmd0aDogdGhpcy5sYW1iZGEsXG4gICAgICBmb3JnZXR0aW5nUmF0ZTogdGhpcy5lc3RpbWF0ZUZvcmdldHRpbmdSYXRlKCksXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgZXN0aW1hdGVGb3JnZXR0aW5nUmF0ZSgpOiBudW1iZXIge1xuICAgIC8vIFNpbXBsaWZpZWQgZXN0aW1hdGlvbiBiYXNlZCBvbiBudW1iZXIgb2YgdGFza3NcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgMSAtIE1hdGguZXhwKC10aGlzLnRhc2tzTGVhcm5lZCAqIDAuMSkpO1xuICB9XG59XG5cbi8qKlxuICogU09OQSBMZWFybmluZyBDb29yZGluYXRvclxuICpcbiAqIE9yY2hlc3RyYXRlcyB0aGUgbGVhcm5pbmcgbG9vcHMgYW5kIGNvbXBvbmVudHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBTb25hQ29vcmRpbmF0b3Ige1xuICBwcml2YXRlIGNvbmZpZzogUmVxdWlyZWQ8U29uYUNvbmZpZz47XG4gIHByaXZhdGUgdHJhamVjdG9yeUJ1ZmZlcjogUXVlcnlUcmFqZWN0b3J5W10gPSBbXTtcbiAgcHJpdmF0ZSByZWFzb25pbmdCYW5rOiBSZWFzb25pbmdCYW5rO1xuICBwcml2YXRlIGV3Y01hbmFnZXI6IEV3Y01hbmFnZXI7XG4gIHByaXZhdGUgc2lnbmFsQnVmZmVyOiBMZWFybmluZ1NpZ25hbFtdID0gW107XG5cbiAgY29uc3RydWN0b3IoY29uZmlnPzogU29uYUNvbmZpZykge1xuICAgIHRoaXMuY29uZmlnID0geyAuLi5ERUZBVUxUX1NPTkFfQ09ORklHLCAuLi5jb25maWcgfTtcbiAgICB0aGlzLnJlYXNvbmluZ0JhbmsgPSBuZXcgUmVhc29uaW5nQmFuayh0aGlzLmNvbmZpZy5wYXR0ZXJuVGhyZXNob2xkKTtcbiAgICB0aGlzLmV3Y01hbmFnZXIgPSBuZXcgRXdjTWFuYWdlcih0aGlzLmNvbmZpZy5ld2NMYW1iZGEpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZCBhIGxlYXJuaW5nIHNpZ25hbFxuICAgKi9cbiAgcmVjb3JkU2lnbmFsKHNpZ25hbDogTGVhcm5pbmdTaWduYWwpOiB2b2lkIHtcbiAgICB0aGlzLnNpZ25hbEJ1ZmZlci5wdXNoKHNpZ25hbCk7XG5cbiAgICAvLyBJbnN0YW50IGxvb3AgLSBpbW1lZGlhdGUgbGVhcm5pbmdcbiAgICBpZiAodGhpcy5jb25maWcuaW5zdGFudExvb3BFbmFibGVkICYmIHNpZ25hbC5xdWFsaXR5ID49IDAuOCkge1xuICAgICAgdGhpcy5wcm9jZXNzSW5zdGFudExlYXJuaW5nKHNpZ25hbCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZCBhIGNvbXBsZXRlZCB0cmFqZWN0b3J5XG4gICAqL1xuICByZWNvcmRUcmFqZWN0b3J5KHRyYWplY3Rvcnk6IFF1ZXJ5VHJhamVjdG9yeSk6IHZvaWQge1xuICAgIHRoaXMudHJhamVjdG9yeUJ1ZmZlci5wdXNoKHRyYWplY3RvcnkpO1xuXG4gICAgLy8gTWFpbnRhaW4gYnVmZmVyIHNpemVcbiAgICB3aGlsZSAodGhpcy50cmFqZWN0b3J5QnVmZmVyLmxlbmd0aCA+IHRoaXMuY29uZmlnLm1heFRyYWplY3RvcnlTaXplKSB7XG4gICAgICB0aGlzLnRyYWplY3RvcnlCdWZmZXIuc2hpZnQoKTtcbiAgICB9XG5cbiAgICAvLyBFeHRyYWN0IHBhdHRlcm5zIGZyb20gc3VjY2Vzc2Z1bCB0cmFqZWN0b3JpZXNcbiAgICBpZiAodHJhamVjdG9yeS5vdXRjb21lID09PSAnc3VjY2VzcycpIHtcbiAgICAgIHRoaXMuZXh0cmFjdFBhdHRlcm5zKHRyYWplY3RvcnkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gYmFja2dyb3VuZCBsZWFybmluZyBsb29wXG4gICAqL1xuICBydW5CYWNrZ3JvdW5kTG9vcCgpOiB7IHBhdHRlcm5zTGVhcm5lZDogbnVtYmVyOyB0cmFqZWN0b3JpZXNQcm9jZXNzZWQ6IG51bWJlciB9IHtcbiAgICBpZiAoIXRoaXMuY29uZmlnLmJhY2tncm91bmRMb29wRW5hYmxlZCkge1xuICAgICAgcmV0dXJuIHsgcGF0dGVybnNMZWFybmVkOiAwLCB0cmFqZWN0b3JpZXNQcm9jZXNzZWQ6IDAgfTtcbiAgICB9XG5cbiAgICBsZXQgcGF0dGVybnNMZWFybmVkID0gMDtcbiAgICBjb25zdCB0cmFqZWN0b3JpZXNQcm9jZXNzZWQgPSB0aGlzLnRyYWplY3RvcnlCdWZmZXIubGVuZ3RoO1xuXG4gICAgLy8gUHJvY2VzcyBhY2N1bXVsYXRlZCB0cmFqZWN0b3JpZXNcbiAgICBmb3IgKGNvbnN0IHRyYWogb2YgdGhpcy50cmFqZWN0b3J5QnVmZmVyKSB7XG4gICAgICBpZiAodHJhai5vdXRjb21lID09PSAnc3VjY2VzcycgfHwgdHJhai5vdXRjb21lID09PSAncGFydGlhbCcpIHtcbiAgICAgICAgcGF0dGVybnNMZWFybmVkICs9IHRoaXMuZXh0cmFjdFBhdHRlcm5zKHRyYWopO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFBydW5lIGxvdy1wZXJmb3JtaW5nIHBhdHRlcm5zXG4gICAgdGhpcy5yZWFzb25pbmdCYW5rLnBydW5lKCk7XG5cbiAgICAvLyBDbGVhciBwcm9jZXNzZWQgdHJhamVjdG9yaWVzXG4gICAgdGhpcy50cmFqZWN0b3J5QnVmZmVyID0gW107XG5cbiAgICByZXR1cm4geyBwYXR0ZXJuc0xlYXJuZWQsIHRyYWplY3Rvcmllc1Byb2Nlc3NlZCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCByZWFzb25pbmcgYmFuayBmb3IgcGF0dGVybiBxdWVyaWVzXG4gICAqL1xuICBnZXRSZWFzb25pbmdCYW5rKCk6IFJlYXNvbmluZ0Jhbmsge1xuICAgIHJldHVybiB0aGlzLnJlYXNvbmluZ0Jhbms7XG4gIH1cblxuICAvKipcbiAgICogR2V0IEVXQyBtYW5hZ2VyXG4gICAqL1xuICBnZXRFd2NNYW5hZ2VyKCk6IEV3Y01hbmFnZXIge1xuICAgIHJldHVybiB0aGlzLmV3Y01hbmFnZXI7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHN0YXRpc3RpY3NcbiAgICovXG4gIHN0YXRzKCk6IHtcbiAgICBzaWduYWxzUmVjZWl2ZWQ6IG51bWJlcjtcbiAgICB0cmFqZWN0b3JpZXNCdWZmZXJlZDogbnVtYmVyO1xuICAgIHBhdHRlcm5zOiBSZXR1cm5UeXBlPFJlYXNvbmluZ0JhbmtbJ3N0YXRzJ10+O1xuICAgIGV3YzogRXdjU3RhdHM7XG4gIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBzaWduYWxzUmVjZWl2ZWQ6IHRoaXMuc2lnbmFsQnVmZmVyLmxlbmd0aCxcbiAgICAgIHRyYWplY3Rvcmllc0J1ZmZlcmVkOiB0aGlzLnRyYWplY3RvcnlCdWZmZXIubGVuZ3RoLFxuICAgICAgcGF0dGVybnM6IHRoaXMucmVhc29uaW5nQmFuay5zdGF0cygpLFxuICAgICAgZXdjOiB0aGlzLmV3Y01hbmFnZXIuc3RhdHMoKSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzSW5zdGFudExlYXJuaW5nKHNpZ25hbDogTGVhcm5pbmdTaWduYWwpOiB2b2lkIHtcbiAgICAvLyBJbW1lZGlhdGUgcGF0dGVybiByZWluZm9yY2VtZW50IHdvdWxkIGhhcHBlbiBoZXJlXG4gICAgLy8gSW4gZnVsbCBpbXBsZW1lbnRhdGlvbiwgdGhpcyB1cGRhdGVzIExvUkEgd2VpZ2h0c1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0UGF0dGVybnModHJhamVjdG9yeTogUXVlcnlUcmFqZWN0b3J5KTogbnVtYmVyIHtcbiAgICBsZXQgZXh0cmFjdGVkID0gMDtcblxuICAgIGZvciAoY29uc3Qgc3RlcCBvZiB0cmFqZWN0b3J5LnN0ZXBzKSB7XG4gICAgICBpZiAoc3RlcC5jb25maWRlbmNlID49IHRoaXMuY29uZmlnLnBhdHRlcm5UaHJlc2hvbGQpIHtcbiAgICAgICAgLy8gQ3JlYXRlIGVtYmVkZGluZyBmcm9tIHN0ZXAgKHNpbXBsaWZpZWQpXG4gICAgICAgIGNvbnN0IGVtYmVkZGluZyA9IHRoaXMuY3JlYXRlRW1iZWRkaW5nKHN0ZXAuaW5wdXQgKyBzdGVwLm91dHB1dCk7XG5cbiAgICAgICAgLy8gRGV0ZXJtaW5lIHBhdHRlcm4gdHlwZVxuICAgICAgICBjb25zdCB0eXBlID0gdGhpcy5zdGVwVHlwZVRvUGF0dGVyblR5cGUoc3RlcC50eXBlKTtcblxuICAgICAgICAvLyBTdG9yZSBpZiBub3QgdG9vIHNpbWlsYXIgdG8gZXhpc3RpbmdcbiAgICAgICAgY29uc3Qgc2ltaWxhciA9IHRoaXMucmVhc29uaW5nQmFuay5maW5kU2ltaWxhcihlbWJlZGRpbmcsIDEpO1xuICAgICAgICBpZiAoc2ltaWxhci5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLnJlYXNvbmluZ0Jhbmsuc3RvcmUodHlwZSwgZW1iZWRkaW5nKTtcbiAgICAgICAgICBleHRyYWN0ZWQrKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBleHRyYWN0ZWQ7XG4gIH1cblxuICBwcml2YXRlIHN0ZXBUeXBlVG9QYXR0ZXJuVHlwZShzdGVwVHlwZTogVHJhamVjdG9yeVN0ZXBbJ3R5cGUnXSk6IFBhdHRlcm5UeXBlIHtcbiAgICBzd2l0Y2ggKHN0ZXBUeXBlKSB7XG4gICAgICBjYXNlICdxdWVyeSc6XG4gICAgICBjYXNlICdnZW5lcmF0ZSc6XG4gICAgICAgIHJldHVybiAncXVlcnlfcmVzcG9uc2UnO1xuICAgICAgY2FzZSAncm91dGUnOlxuICAgICAgICByZXR1cm4gJ3JvdXRpbmcnO1xuICAgICAgY2FzZSAnbWVtb3J5JzpcbiAgICAgICAgcmV0dXJuICdjb250ZXh0X3JldHJpZXZhbCc7XG4gICAgICBjYXNlICdmZWVkYmFjayc6XG4gICAgICAgIHJldHVybiAnY29ycmVjdGlvbic7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gJ3F1ZXJ5X3Jlc3BvbnNlJztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUVtYmVkZGluZyh0ZXh0OiBzdHJpbmcpOiBFbWJlZGRpbmcge1xuICAgIC8vIFNpbXBsaWZpZWQgaGFzaC1iYXNlZCBlbWJlZGRpbmcgKHJlYWwgaW1wbCB1c2VzIG1vZGVsKVxuICAgIGNvbnN0IGRpbSA9IDY0O1xuICAgIGNvbnN0IGVtYmVkZGluZyA9IG5ldyBBcnJheShkaW0pLmZpbGwoMCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRleHQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGlkeCA9ICh0ZXh0LmNoYXJDb2RlQXQoaSkgKiAoaSArIDEpKSAlIGRpbTtcbiAgICAgIGVtYmVkZGluZ1tpZHhdICs9IDAuMTtcbiAgICB9XG5cbiAgICAvLyBOb3JtYWxpemVcbiAgICBjb25zdCBub3JtID0gTWF0aC5zcXJ0KGVtYmVkZGluZy5yZWR1Y2UoKHMsIHgpID0+IHMgKyB4ICogeCwgMCkpIHx8IDE7XG4gICAgcmV0dXJuIGVtYmVkZGluZy5tYXAoeCA9PiB4IC8gbm9ybSk7XG4gIH1cbn1cblxuLy8gRXhwb3J0IGFsbCBTT05BIGNvbXBvbmVudHNcbmV4cG9ydCB7XG4gIERFRkFVTFRfU09OQV9DT05GSUcsXG59O1xuIl19
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Streaming response support for RuvLLM
3
+ */
4
+ import { StreamChunk, StreamOptions, QueryResponse, GenerationConfig } from './types';
5
+ /**
6
+ * Async generator for streaming responses
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { RuvLLM, StreamingGenerator } from '@ruvector/ruvllm';
11
+ *
12
+ * const llm = new RuvLLM();
13
+ * const streamer = new StreamingGenerator(llm);
14
+ *
15
+ * // Stream with async iterator
16
+ * for await (const chunk of streamer.stream('Write a story')) {
17
+ * process.stdout.write(chunk.text);
18
+ * }
19
+ *
20
+ * // Stream with callbacks
21
+ * await streamer.streamWithCallbacks('Write a poem', {
22
+ * onChunk: (chunk) => console.log(chunk.text),
23
+ * onComplete: (response) => console.log('Done!', response.latencyMs),
24
+ * });
25
+ * ```
26
+ */
27
+ export declare class StreamingGenerator {
28
+ private llm;
29
+ constructor(llm: {
30
+ generate: (prompt: string, config?: GenerationConfig) => string;
31
+ query: (text: string, config?: GenerationConfig) => QueryResponse;
32
+ });
33
+ /**
34
+ * Stream response as async generator
35
+ *
36
+ * Note: This simulates streaming by chunking the full response.
37
+ * Native streaming requires native module support.
38
+ */
39
+ stream(prompt: string, config?: GenerationConfig): AsyncGenerator<StreamChunk>;
40
+ /**
41
+ * Stream with callback handlers
42
+ */
43
+ streamWithCallbacks(prompt: string, options: StreamOptions): Promise<QueryResponse>;
44
+ /**
45
+ * Collect stream into single response
46
+ */
47
+ collect(prompt: string, config?: GenerationConfig): Promise<string>;
48
+ private delay;
49
+ }
50
+ /**
51
+ * Create a readable stream from response
52
+ * (For Node.js stream compatibility)
53
+ */
54
+ export declare function createReadableStream(generator: AsyncGenerator<StreamChunk>): ReadableStream<string>;
55
+ //# sourceMappingURL=streaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/streaming.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,WAAW,EACX,aAAa,EACb,aAAa,EACb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,GAAG,CAGT;gBAEU,GAAG,EAAE;QACf,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,KAAK,MAAM,CAAC;QAChE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,KAAK,aAAa,CAAC;KACnE;IAID;;;;;OAKG;IACI,MAAM,CACX,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,gBAAgB,GACxB,cAAc,CAAC,WAAW,CAAC;IA8B9B;;OAEG;IACG,mBAAmB,CACvB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,aAAa,CAAC;IAqCzB;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;IAQzE,OAAO,CAAC,KAAK;CAGd;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,GACrC,cAAc,CAAC,MAAM,CAAC,CAWxB"}