@narrative-os/engine 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/canonValidator.d.ts +9 -0
- package/dist/agents/canonValidator.js +51 -0
- package/dist/agents/chapterPlanner.d.ts +50 -0
- package/dist/agents/chapterPlanner.js +250 -0
- package/dist/agents/completeness.d.ts +7 -0
- package/dist/agents/completeness.js +51 -0
- package/dist/agents/memoryExtractor.d.ts +12 -0
- package/dist/agents/memoryExtractor.js +82 -0
- package/dist/agents/stateUpdater.d.ts +30 -0
- package/dist/agents/stateUpdater.js +150 -0
- package/dist/agents/storyDirector.d.ts +40 -0
- package/dist/agents/storyDirector.js +213 -0
- package/dist/agents/summarizer.d.ts +8 -0
- package/dist/agents/summarizer.js +56 -0
- package/dist/agents/tensionController.d.ts +68 -0
- package/dist/agents/tensionController.js +197 -0
- package/dist/agents/writer.d.ts +12 -0
- package/dist/agents/writer.js +148 -0
- package/dist/constraints/constraintGraph.d.ts +117 -0
- package/dist/constraints/constraintGraph.js +381 -0
- package/dist/constraints/validator.d.ts +58 -0
- package/dist/constraints/validator.js +236 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +115 -0
- package/dist/llm/client.d.ts +14 -0
- package/dist/llm/client.js +108 -0
- package/dist/memory/canonStore.d.ts +20 -0
- package/dist/memory/canonStore.js +110 -0
- package/dist/memory/memoryRetriever.d.ts +28 -0
- package/dist/memory/memoryRetriever.js +126 -0
- package/dist/memory/stateUpdater.d.ts +49 -0
- package/dist/memory/stateUpdater.js +315 -0
- package/dist/memory/vectorStore.d.ts +41 -0
- package/dist/memory/vectorStore.js +166 -0
- package/dist/pipeline/generateChapter.d.ts +17 -0
- package/dist/pipeline/generateChapter.js +75 -0
- package/dist/story/bible.d.ts +4 -0
- package/dist/story/bible.js +53 -0
- package/dist/story/state.d.ts +3 -0
- package/dist/story/state.js +27 -0
- package/dist/story/structuredState.d.ts +39 -0
- package/dist/story/structuredState.js +159 -0
- package/dist/test/canon.test.d.ts +1 -0
- package/dist/test/canon.test.js +104 -0
- package/dist/test/chapter-planner.test.d.ts +1 -0
- package/dist/test/chapter-planner.test.js +171 -0
- package/dist/test/constraints.test.d.ts +1 -0
- package/dist/test/constraints.test.js +210 -0
- package/dist/test/simple.test.d.ts +1 -0
- package/dist/test/simple.test.js +51 -0
- package/dist/test/state-updater.test.d.ts +1 -0
- package/dist/test/state-updater.test.js +200 -0
- package/dist/test/story-director.test.d.ts +1 -0
- package/dist/test/story-director.test.js +142 -0
- package/dist/test/structured-state.test.d.ts +1 -0
- package/dist/test/structured-state.test.js +144 -0
- package/dist/test/tension-controller.test.d.ts +1 -0
- package/dist/test/tension-controller.test.js +116 -0
- package/dist/test/vector-memory.test.d.ts +1 -0
- package/dist/test/vector-memory.test.js +153 -0
- package/dist/test/world-simulation.test.d.ts +1 -0
- package/dist/test/world-simulation.test.js +152 -0
- package/dist/types/index.d.ts +79 -0
- package/dist/types/index.js +3 -0
- package/dist/world/characterAgent.d.ts +73 -0
- package/dist/world/characterAgent.js +232 -0
- package/dist/world/eventResolver.d.ts +52 -0
- package/dist/world/eventResolver.js +205 -0
- package/dist/world/worldState.d.ts +93 -0
- package/dist/world/worldState.js +258 -0
- package/package.json +43 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stateUpdaterPipeline = exports.StateUpdaterPipeline = void 0;
|
|
4
|
+
const client_js_1 = require("../llm/client.js");
|
|
5
|
+
const STATE_EXTRACTION_PROMPT = `You are a narrative state extractor. Analyze this chapter and extract all state changes.
|
|
6
|
+
|
|
7
|
+
## Story Bible
|
|
8
|
+
|
|
9
|
+
**Title:** {{title}}
|
|
10
|
+
**Genre:** {{genre}}
|
|
11
|
+
|
|
12
|
+
## Chapter {{chapterNumber}}: {{chapterTitle}}
|
|
13
|
+
|
|
14
|
+
{{chapterContent}}
|
|
15
|
+
|
|
16
|
+
## Current Character States
|
|
17
|
+
|
|
18
|
+
{{characters}}
|
|
19
|
+
|
|
20
|
+
## Current Plot Threads
|
|
21
|
+
|
|
22
|
+
{{plotThreads}}
|
|
23
|
+
|
|
24
|
+
## Extraction Task
|
|
25
|
+
|
|
26
|
+
Extract the following:
|
|
27
|
+
|
|
28
|
+
1. **Character Changes**: How do characters change? (emotion, location, knowledge, relationships, goals)
|
|
29
|
+
2. **Plot Thread Changes**: How do plot threads progress? (status, tension, summary updates)
|
|
30
|
+
3. **New Facts**: Any new canon facts established?
|
|
31
|
+
4. **World Changes**: Any changes to the world setting?
|
|
32
|
+
|
|
33
|
+
Output JSON:
|
|
34
|
+
{
|
|
35
|
+
"characterChanges": [
|
|
36
|
+
{
|
|
37
|
+
"name": "character name",
|
|
38
|
+
"emotionalState": "new emotional state or null",
|
|
39
|
+
"location": "new location or null",
|
|
40
|
+
"newKnowledge": ["facts learned"],
|
|
41
|
+
"relationshipChanges": [{"with": "other character", "newStatus": "relationship"}],
|
|
42
|
+
"newGoal": "new goal or null"
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"plotThreadChanges": [
|
|
46
|
+
{
|
|
47
|
+
"id": "thread id",
|
|
48
|
+
"status": "new status or null",
|
|
49
|
+
"tensionDelta": 0.1,
|
|
50
|
+
"newSummary": "updated summary or null"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"newFacts": [
|
|
54
|
+
{
|
|
55
|
+
"category": "character|world|plot",
|
|
56
|
+
"subject": "subject",
|
|
57
|
+
"attribute": "attribute",
|
|
58
|
+
"value": "value"
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"worldChanges": ["any changes to the world"]
|
|
62
|
+
}`;
|
|
63
|
+
class StateUpdaterPipeline {
|
|
64
|
+
/**
|
|
65
|
+
* Run the complete post-chapter update pipeline
|
|
66
|
+
*/
|
|
67
|
+
async update(context) {
|
|
68
|
+
const { chapter, bible, currentState, canon, vectorStore, constraintGraph } = context;
|
|
69
|
+
const changes = [];
|
|
70
|
+
let memoriesAdded = 0;
|
|
71
|
+
let canonFactsAdded = 0;
|
|
72
|
+
// Step 1: Extract state changes using LLM
|
|
73
|
+
const extraction = await this.extractChanges(chapter, bible, currentState);
|
|
74
|
+
// Step 2: Update structured state
|
|
75
|
+
let newState = { ...currentState };
|
|
76
|
+
newState.chapter = chapter.number;
|
|
77
|
+
// Apply character changes
|
|
78
|
+
for (const change of extraction.characterChanges) {
|
|
79
|
+
if (newState.characters[change.name]) {
|
|
80
|
+
const char = newState.characters[change.name];
|
|
81
|
+
if (change.emotionalState) {
|
|
82
|
+
char.emotionalState = change.emotionalState;
|
|
83
|
+
changes.push({
|
|
84
|
+
type: 'character',
|
|
85
|
+
description: `${change.name} emotional state → ${change.emotionalState}`,
|
|
86
|
+
chapter: chapter.number,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (change.location) {
|
|
90
|
+
const oldLocation = char.location;
|
|
91
|
+
char.location = change.location;
|
|
92
|
+
changes.push({
|
|
93
|
+
type: 'character',
|
|
94
|
+
description: `${change.name} moved: ${oldLocation} → ${change.location}`,
|
|
95
|
+
chapter: chapter.number,
|
|
96
|
+
});
|
|
97
|
+
// Update constraint graph
|
|
98
|
+
constraintGraph.updateCharacterLocation(change.name, change.location, chapter.number);
|
|
99
|
+
}
|
|
100
|
+
if (change.newKnowledge) {
|
|
101
|
+
char.knowledge = [...char.knowledge, ...change.newKnowledge];
|
|
102
|
+
// Add to constraint graph
|
|
103
|
+
for (const knowledge of change.newKnowledge) {
|
|
104
|
+
const factId = `fact-${this.sanitizeId(knowledge)}`;
|
|
105
|
+
if (!constraintGraph.getNode(factId)) {
|
|
106
|
+
constraintGraph.addNode({
|
|
107
|
+
id: factId,
|
|
108
|
+
type: 'fact',
|
|
109
|
+
label: knowledge,
|
|
110
|
+
properties: {},
|
|
111
|
+
chapterEstablished: chapter.number,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
constraintGraph.addEdge({
|
|
115
|
+
id: `edge-${change.name}-knows-${factId}`,
|
|
116
|
+
from: `char-${change.name}`,
|
|
117
|
+
to: factId,
|
|
118
|
+
type: 'knows',
|
|
119
|
+
properties: { since: chapter.number },
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (change.relationshipChanges) {
|
|
124
|
+
for (const rel of change.relationshipChanges) {
|
|
125
|
+
char.relationships[rel.with] = rel.newStatus;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (change.newGoal) {
|
|
129
|
+
char.goals = [...char.goals, change.newGoal];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Apply plot thread changes
|
|
134
|
+
for (const change of extraction.plotThreadChanges) {
|
|
135
|
+
if (newState.plotThreads[change.id]) {
|
|
136
|
+
const thread = newState.plotThreads[change.id];
|
|
137
|
+
if (change.status) {
|
|
138
|
+
thread.status = change.status;
|
|
139
|
+
}
|
|
140
|
+
if (change.tensionDelta) {
|
|
141
|
+
thread.tension = Math.max(0, Math.min(1, thread.tension + change.tensionDelta));
|
|
142
|
+
}
|
|
143
|
+
if (change.newSummary) {
|
|
144
|
+
thread.summary = change.newSummary;
|
|
145
|
+
}
|
|
146
|
+
thread.lastChapter = chapter.number;
|
|
147
|
+
changes.push({
|
|
148
|
+
type: 'plot',
|
|
149
|
+
description: `${thread.name} updated: ${change.status || 'progress'}`,
|
|
150
|
+
chapter: chapter.number,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Step 3: Add new canon facts
|
|
155
|
+
for (const fact of extraction.newFacts) {
|
|
156
|
+
// In real implementation, would add to canon store
|
|
157
|
+
canonFactsAdded++;
|
|
158
|
+
changes.push({
|
|
159
|
+
type: 'canon',
|
|
160
|
+
description: `Canon: ${fact.subject} ${fact.attribute} = ${fact.value}`,
|
|
161
|
+
chapter: chapter.number,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
// Step 4: Extract and add narrative memories
|
|
165
|
+
const memories = await this.extractMemories(chapter, bible);
|
|
166
|
+
for (const memory of memories) {
|
|
167
|
+
await vectorStore.addMemory({
|
|
168
|
+
storyId: chapter.storyId,
|
|
169
|
+
chapterNumber: chapter.number,
|
|
170
|
+
content: memory.content,
|
|
171
|
+
category: memory.category,
|
|
172
|
+
timestamp: new Date(),
|
|
173
|
+
});
|
|
174
|
+
memoriesAdded++;
|
|
175
|
+
}
|
|
176
|
+
changes.push({
|
|
177
|
+
type: 'memory',
|
|
178
|
+
description: `${memoriesAdded} narrative memories extracted`,
|
|
179
|
+
chapter: chapter.number,
|
|
180
|
+
});
|
|
181
|
+
// Step 5: Add event to constraint graph
|
|
182
|
+
constraintGraph.addEvent(`ch${chapter.number}`, chapter.summary, Object.keys(newState.characters), chapter.number);
|
|
183
|
+
// Step 6: Update recent events
|
|
184
|
+
newState.recentEvents = [...newState.recentEvents, chapter.summary].slice(-10);
|
|
185
|
+
return {
|
|
186
|
+
structuredState: newState,
|
|
187
|
+
memoriesAdded,
|
|
188
|
+
canonFactsAdded,
|
|
189
|
+
graphUpdated: true,
|
|
190
|
+
changes,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Extract state changes from chapter
|
|
195
|
+
*/
|
|
196
|
+
async extractChanges(chapter, bible, state) {
|
|
197
|
+
const characters = Object.values(state.characters)
|
|
198
|
+
.map(c => `- ${c.name}: ${c.emotionalState}, at ${c.location}`)
|
|
199
|
+
.join('\n');
|
|
200
|
+
const plotThreads = Object.values(state.plotThreads)
|
|
201
|
+
.map(t => `- ${t.name} (${t.status}, ${Math.round(t.tension * 100)}% tension)`)
|
|
202
|
+
.join('\n');
|
|
203
|
+
const prompt = STATE_EXTRACTION_PROMPT
|
|
204
|
+
.replace('{{title}}', bible.title)
|
|
205
|
+
.replace('{{genre}}', bible.genre)
|
|
206
|
+
.replace('{{chapterNumber}}', chapter.number.toString())
|
|
207
|
+
.replace('{{chapterTitle}}', chapter.title)
|
|
208
|
+
.replace('{{chapterContent}}', chapter.content.substring(0, 5000))
|
|
209
|
+
.replace('{{characters}}', characters)
|
|
210
|
+
.replace('{{plotThreads}}', plotThreads);
|
|
211
|
+
const result = await (0, client_js_1.getLLM)().completeJSON(prompt, {
|
|
212
|
+
temperature: 0.3,
|
|
213
|
+
maxTokens: 2000,
|
|
214
|
+
});
|
|
215
|
+
return result;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Extract narrative memories from chapter
|
|
219
|
+
*/
|
|
220
|
+
async extractMemories(chapter, bible) {
|
|
221
|
+
// Simplified memory extraction
|
|
222
|
+
// In real implementation, would use MemoryExtractor agent
|
|
223
|
+
const memories = [];
|
|
224
|
+
// Extract key events from summary
|
|
225
|
+
if (chapter.summary) {
|
|
226
|
+
memories.push({
|
|
227
|
+
content: chapter.summary,
|
|
228
|
+
category: 'event',
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
// Add chapter title as memory
|
|
232
|
+
memories.push({
|
|
233
|
+
content: `Chapter ${chapter.number}: ${chapter.title}`,
|
|
234
|
+
category: 'plot',
|
|
235
|
+
});
|
|
236
|
+
return memories;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Quick update without LLM (for testing)
|
|
240
|
+
*/
|
|
241
|
+
async quickUpdate(context) {
|
|
242
|
+
const { chapter, currentState, vectorStore, constraintGraph } = context;
|
|
243
|
+
const changes = [];
|
|
244
|
+
let newState = { ...currentState };
|
|
245
|
+
newState.chapter = chapter.number;
|
|
246
|
+
// Add basic memories
|
|
247
|
+
await vectorStore.addMemory({
|
|
248
|
+
storyId: chapter.storyId,
|
|
249
|
+
chapterNumber: chapter.number,
|
|
250
|
+
content: chapter.summary,
|
|
251
|
+
category: 'event',
|
|
252
|
+
timestamp: new Date(),
|
|
253
|
+
});
|
|
254
|
+
await vectorStore.addMemory({
|
|
255
|
+
storyId: chapter.storyId,
|
|
256
|
+
chapterNumber: chapter.number,
|
|
257
|
+
content: `Chapter ${chapter.number}: ${chapter.title}`,
|
|
258
|
+
category: 'plot',
|
|
259
|
+
timestamp: new Date(),
|
|
260
|
+
});
|
|
261
|
+
changes.push({
|
|
262
|
+
type: 'memory',
|
|
263
|
+
description: `2 memories added (quick mode)`,
|
|
264
|
+
chapter: chapter.number,
|
|
265
|
+
});
|
|
266
|
+
// Update recent events
|
|
267
|
+
newState.recentEvents = [...newState.recentEvents, chapter.summary].slice(-10);
|
|
268
|
+
// Add to constraint graph
|
|
269
|
+
constraintGraph.addEvent(`ch${chapter.number}`, chapter.summary, Object.keys(newState.characters), chapter.number);
|
|
270
|
+
return {
|
|
271
|
+
structuredState: newState,
|
|
272
|
+
memoriesAdded: 2,
|
|
273
|
+
canonFactsAdded: 0,
|
|
274
|
+
graphUpdated: true,
|
|
275
|
+
changes,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Format update result
|
|
280
|
+
*/
|
|
281
|
+
formatResult(result) {
|
|
282
|
+
const lines = ['## State Update Result'];
|
|
283
|
+
lines.push(`\n**Memories Added:** ${result.memoriesAdded}`);
|
|
284
|
+
lines.push(`**Canon Facts Added:** ${result.canonFactsAdded}`);
|
|
285
|
+
lines.push(`**Graph Updated:** ${result.graphUpdated ? '✅' : '❌'}`);
|
|
286
|
+
if (result.changes.length > 0) {
|
|
287
|
+
lines.push('\n**Changes:**');
|
|
288
|
+
const byType = {
|
|
289
|
+
character: [],
|
|
290
|
+
plot: [],
|
|
291
|
+
world: [],
|
|
292
|
+
canon: [],
|
|
293
|
+
memory: [],
|
|
294
|
+
};
|
|
295
|
+
for (const change of result.changes) {
|
|
296
|
+
byType[change.type].push(change);
|
|
297
|
+
}
|
|
298
|
+
for (const [type, changes] of Object.entries(byType)) {
|
|
299
|
+
if (changes.length > 0) {
|
|
300
|
+
lines.push(`\n*${type.charAt(0).toUpperCase() + type.slice(1)}:*`);
|
|
301
|
+
for (const change of changes) {
|
|
302
|
+
lines.push(` - ${change.description}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return lines.join('\n');
|
|
308
|
+
}
|
|
309
|
+
sanitizeId(str) {
|
|
310
|
+
return str.replace(/[^a-zA-Z0-9]/g, '_').substring(0, 50);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
exports.StateUpdaterPipeline = StateUpdaterPipeline;
|
|
314
|
+
exports.stateUpdaterPipeline = new StateUpdaterPipeline();
|
|
315
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGVVcGRhdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21lbW9yeS9zdGF0ZVVwZGF0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0RBQTBDO0FBOEIxQyxNQUFNLHVCQUF1QixHQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUF5RDlCLENBQUM7QUFFSCxNQUFhLG9CQUFvQjtJQUMvQjs7T0FFRztJQUNILEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBc0I7UUFDakMsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLEdBQUcsT0FBTyxDQUFDO1FBRXRGLE1BQU0sT0FBTyxHQUFrQixFQUFFLENBQUM7UUFDbEMsSUFBSSxhQUFhLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLElBQUksZUFBZSxHQUFHLENBQUMsQ0FBQztRQUV4QiwwQ0FBMEM7UUFDMUMsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFFM0Usa0NBQWtDO1FBQ2xDLElBQUksUUFBUSxHQUFHLEVBQUUsR0FBRyxZQUFZLEVBQUUsQ0FBQztRQUNuQyxRQUFRLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFFbEMsMEJBQTBCO1FBQzFCLEtBQUssTUFBTSxNQUFNLElBQUksVUFBVSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDakQsSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNyQyxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFFOUMsSUFBSSxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7b0JBQzFCLElBQUksQ0FBQyxjQUFjLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQztvQkFDNUMsT0FBTyxDQUFDLElBQUksQ0FBQzt3QkFDWCxJQUFJLEVBQUUsV0FBVzt3QkFDakIsV0FBVyxFQUFFLEdBQUcsTUFBTSxDQUFDLElBQUksc0JBQXNCLE1BQU0sQ0FBQyxjQUFjLEVBQUU7d0JBQ3hFLE9BQU8sRUFBRSxPQUFPLENBQUMsTUFBTTtxQkFDeEIsQ0FBQyxDQUFDO2dCQUNMLENBQUM7Z0JBRUQsSUFBSSxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQ3BCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ2xDLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztvQkFDaEMsT0FBTyxDQUFDLElBQUksQ0FBQzt3QkFDWCxJQUFJLEVBQUUsV0FBVzt3QkFDakIsV0FBVyxFQUFFLEdBQUcsTUFBTSxDQUFDLElBQUksV0FBVyxXQUFXLE1BQU0sTUFBTSxDQUFDLFFBQVEsRUFBRTt3QkFDeEUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxNQUFNO3FCQUN4QixDQUFDLENBQUM7b0JBRUgsMEJBQTBCO29CQUMxQixlQUFlLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDeEYsQ0FBQztnQkFFRCxJQUFJLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQztvQkFDeEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztvQkFFN0QsMEJBQTBCO29CQUMxQixLQUFLLE1BQU0sU0FBUyxJQUFJLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQzt3QkFDNUMsTUFBTSxNQUFNLEdBQUcsUUFBUSxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7d0JBQ3BELElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7NEJBQ3JDLGVBQWUsQ0FBQyxPQUFPLENBQUM7Z0NBQ3RCLEVBQUUsRUFBRSxNQUFNO2dDQUNWLElBQUksRUFBRSxNQUFNO2dDQUNaLEtBQUssRUFBRSxTQUFTO2dDQUNoQixVQUFVLEVBQUUsRUFBRTtnQ0FDZCxrQkFBa0IsRUFBRSxPQUFPLENBQUMsTUFBTTs2QkFDbkMsQ0FBQyxDQUFDO3dCQUNMLENBQUM7d0JBRUQsZUFBZSxDQUFDLE9BQU8sQ0FBQzs0QkFDdEIsRUFBRSxFQUFFLFFBQVEsTUFBTSxDQUFDLElBQUksVUFBVSxNQUFNLEVBQUU7NEJBQ3pDLElBQUksRUFBRSxRQUFRLE1BQU0sQ0FBQyxJQUFJLEVBQUU7NEJBQzNCLEVBQUUsRUFBRSxNQUFNOzRCQUNWLElBQUksRUFBRSxPQUFPOzRCQUNiLFVBQVUsRUFBRSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsTUFBTSxFQUFFO3lCQUN0QyxDQUFDLENBQUM7b0JBQ0wsQ0FBQztnQkFDSCxDQUFDO2dCQUVELElBQUksTUFBTSxDQUFDLG1CQUFtQixFQUFFLENBQUM7b0JBQy9CLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLG1CQUFtQixFQUFFLENBQUM7d0JBQzdDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUM7b0JBQy9DLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDbkIsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQy9DLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELDRCQUE0QjtRQUM1QixLQUFLLE1BQU0sTUFBTSxJQUFJLFVBQVUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ2xELElBQUksUUFBUSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDcEMsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBRS9DLElBQUksTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO29CQUNsQixNQUFNLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7Z0JBQ2hDLENBQUM7Z0JBRUQsSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7b0JBQ3hCLE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztnQkFDbEYsQ0FBQztnQkFFRCxJQUFJLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztvQkFDdEIsTUFBTSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDO2dCQUNyQyxDQUFDO2dCQUVELE1BQU0sQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztnQkFFcEMsT0FBTyxDQUFDLElBQUksQ0FBQztvQkFDWCxJQUFJLEVBQUUsTUFBTTtvQkFDWixXQUFXLEVBQUUsR0FBRyxNQUFNLENBQUMsSUFBSSxhQUFhLE1BQU0sQ0FBQyxNQUFNLElBQUksVUFBVSxFQUFFO29CQUNyRSxPQUFPLEVBQUUsT0FBTyxDQUFDLE1BQU07aUJBQ3hCLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO1FBRUQsOEJBQThCO1FBQzlCLEtBQUssTUFBTSxJQUFJLElBQUksVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3ZDLG1EQUFtRDtZQUNuRCxlQUFlLEVBQUUsQ0FBQztZQUNsQixPQUFPLENBQUMsSUFBSSxDQUFDO2dCQUNYLElBQUksRUFBRSxPQUFPO2dCQUNiLFdBQVcsRUFBRSxVQUFVLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFNBQVMsTUFBTSxJQUFJLENBQUMsS0FBSyxFQUFFO2dCQUN2RSxPQUFPLEVBQUUsT0FBTyxDQUFDLE1BQU07YUFDeEIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELDZDQUE2QztRQUM3QyxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzVELEtBQUssTUFBTSxNQUFNLElBQUksUUFBUSxFQUFFLENBQUM7WUFDOUIsTUFBTSxXQUFXLENBQUMsU0FBUyxDQUFDO2dCQUMxQixPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87Z0JBQ3hCLGFBQWEsRUFBRSxPQUFPLENBQUMsTUFBTTtnQkFDN0IsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO2dCQUN2QixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7Z0JBQ3pCLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRTthQUN0QixDQUFDLENBQUM7WUFDSCxhQUFhLEVBQUUsQ0FBQztRQUNsQixDQUFDO1FBRUQsT0FBTyxDQUFDLElBQUksQ0FBQztZQUNYLElBQUksRUFBRSxRQUFRO1lBQ2QsV0FBVyxFQUFFLEdBQUcsYUFBYSwrQkFBK0I7WUFDNUQsT0FBTyxFQUFFLE9BQU8sQ0FBQyxNQUFNO1NBQ3hCLENBQUMsQ0FBQztRQUVILHdDQUF3QztRQUN4QyxlQUFlLENBQUMsUUFBUSxDQUN0QixLQUFLLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFDckIsT0FBTyxDQUFDLE9BQU8sRUFDZixNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFDaEMsT0FBTyxDQUFDLE1BQU0sQ0FDZixDQUFDO1FBRUYsK0JBQStCO1FBQy9CLFFBQVEsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRS9FLE9BQU87WUFDTCxlQUFlLEVBQUUsUUFBUTtZQUN6QixhQUFhO1lBQ2IsZUFBZTtZQUNmLFlBQVksRUFBRSxJQUFJO1lBQ2xCLE9BQU87U0FDUixDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0ssS0FBSyxDQUFDLGNBQWMsQ0FDMUIsT0FBZ0IsRUFDaEIsS0FBaUIsRUFDakIsS0FBMkI7UUF3QjNCLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQzthQUMvQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLGNBQWMsUUFBUSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7YUFDOUQsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDO2FBQ2pELEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDO2FBQzlFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVkLE1BQU0sTUFBTSxHQUFHLHVCQUF1QjthQUNuQyxPQUFPLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUM7YUFDakMsT0FBTyxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDO2FBQ2pDLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO2FBQ3ZELE9BQU8sQ0FBQyxrQkFBa0IsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDO2FBQzFDLE9BQU8sQ0FBQyxvQkFBb0IsRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDakUsT0FBTyxDQUFDLGdCQUFnQixFQUFFLFVBQVUsQ0FBQzthQUNyQyxPQUFPLENBQUMsaUJBQWlCLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFFM0MsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFBLGtCQUFNLEdBQUUsQ0FBQyxZQUFZLENBS3ZDLE1BQU0sRUFBRTtZQUNULFdBQVcsRUFBRSxHQUFHO1lBQ2hCLFNBQVMsRUFBRSxJQUFJO1NBQ2hCLENBQUMsQ0FBQztRQUVILE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7T0FFRztJQUNLLEtBQUssQ0FBQyxlQUFlLENBQzNCLE9BQWdCLEVBQ2hCLEtBQWlCO1FBRWpCLCtCQUErQjtRQUMvQiwwREFBMEQ7UUFDMUQsTUFBTSxRQUFRLEdBQXNFLEVBQUUsQ0FBQztRQUV2RixrQ0FBa0M7UUFDbEMsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDcEIsUUFBUSxDQUFDLElBQUksQ0FBQztnQkFDWixPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87Z0JBQ3hCLFFBQVEsRUFBRSxPQUFPO2FBQ2xCLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCw4QkFBOEI7UUFDOUIsUUFBUSxDQUFDLElBQUksQ0FBQztZQUNaLE9BQU8sRUFBRSxXQUFXLE9BQU8sQ0FBQyxNQUFNLEtBQUssT0FBTyxDQUFDLEtBQUssRUFBRTtZQUN0RCxRQUFRLEVBQUUsTUFBTTtTQUNqQixDQUFDLENBQUM7UUFFSCxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsV0FBVyxDQUFDLE9BQXNCO1FBQ3RDLE1BQU0sRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsR0FBRyxPQUFPLENBQUM7UUFFeEUsTUFBTSxPQUFPLEdBQWtCLEVBQUUsQ0FBQztRQUNsQyxJQUFJLFFBQVEsR0FBRyxFQUFFLEdBQUcsWUFBWSxFQUFFLENBQUM7UUFDbkMsUUFBUSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBRWxDLHFCQUFxQjtRQUNyQixNQUFNLFdBQVcsQ0FBQyxTQUFTLENBQUM7WUFDMUIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO1lBQ3hCLGFBQWEsRUFBRSxPQUFPLENBQUMsTUFBTTtZQUM3QixPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87WUFDeEIsUUFBUSxFQUFFLE9BQU87WUFDakIsU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFO1NBQ3RCLENBQUMsQ0FBQztRQUVILE1BQU0sV0FBVyxDQUFDLFNBQVMsQ0FBQztZQUMxQixPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87WUFDeEIsYUFBYSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQzdCLE9BQU8sRUFBRSxXQUFXLE9BQU8sQ0FBQyxNQUFNLEtBQUssT0FBTyxDQUFDLEtBQUssRUFBRTtZQUN0RCxRQUFRLEVBQUUsTUFBTTtZQUNoQixTQUFTLEVBQUUsSUFBSSxJQUFJLEVBQUU7U0FDdEIsQ0FBQyxDQUFDO1FBRUgsT0FBTyxDQUFDLElBQUksQ0FBQztZQUNYLElBQUksRUFBRSxRQUFRO1lBQ2QsV0FBVyxFQUFFLCtCQUErQjtZQUM1QyxPQUFPLEVBQUUsT0FBTyxDQUFDLE1BQU07U0FDeEIsQ0FBQyxDQUFDO1FBRUgsdUJBQXVCO1FBQ3ZCLFFBQVEsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRS9FLDBCQUEwQjtRQUMxQixlQUFlLENBQUMsUUFBUSxDQUN0QixLQUFLLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFDckIsT0FBTyxDQUFDLE9BQU8sRUFDZixNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFDaEMsT0FBTyxDQUFDLE1BQU0sQ0FDZixDQUFDO1FBRUYsT0FBTztZQUNMLGVBQWUsRUFBRSxRQUFRO1lBQ3pCLGFBQWEsRUFBRSxDQUFDO1lBQ2hCLGVBQWUsRUFBRSxDQUFDO1lBQ2xCLFlBQVksRUFBRSxJQUFJO1lBQ2xCLE9BQU87U0FDUixDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0gsWUFBWSxDQUFDLE1BQXlCO1FBQ3BDLE1BQU0sS0FBSyxHQUFhLENBQUMsd0JBQXdCLENBQUMsQ0FBQztRQUVuRCxLQUFLLENBQUMsSUFBSSxDQUFDLHlCQUF5QixNQUFNLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQztRQUM1RCxLQUFLLENBQUMsSUFBSSxDQUFDLDBCQUEwQixNQUFNLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQztRQUMvRCxLQUFLLENBQUMsSUFBSSxDQUFDLHNCQUFzQixNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFFcEUsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM5QixLQUFLLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFFN0IsTUFBTSxNQUFNLEdBQWtDO2dCQUM1QyxTQUFTLEVBQUUsRUFBRTtnQkFDYixJQUFJLEVBQUUsRUFBRTtnQkFDUixLQUFLLEVBQUUsRUFBRTtnQkFDVCxLQUFLLEVBQUUsRUFBRTtnQkFDVCxNQUFNLEVBQUUsRUFBRTthQUNYLENBQUM7WUFFRixLQUFLLE1BQU0sTUFBTSxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDcEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbkMsQ0FBQztZQUVELEtBQUssTUFBTSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7Z0JBQ3JELElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDdkIsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ25FLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7d0JBQzdCLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztvQkFDMUMsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVPLFVBQVUsQ0FBQyxHQUFXO1FBQzVCLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUM1RCxDQUFDO0NBQ0Y7QUF0VkQsb0RBc1ZDO0FBRVksUUFBQSxvQkFBb0IsR0FBRyxJQUFJLG9CQUFvQixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRMTE0gfSBmcm9tICcuLi9sbG0vY2xpZW50LmpzJztcclxuaW1wb3J0IHR5cGUgeyBDaGFwdGVyLCBTdG9yeUJpYmxlIH0gZnJvbSAnLi4vdHlwZXMvaW5kZXguanMnO1xyXG5pbXBvcnQgdHlwZSB7IFN0b3J5U3RydWN0dXJlZFN0YXRlLCBDaGFyYWN0ZXJTdGF0ZSwgUGxvdFRocmVhZFN0YXRlIH0gZnJvbSAnLi4vc3Rvcnkvc3RydWN0dXJlZFN0YXRlLmpzJztcclxuaW1wb3J0IHR5cGUgeyBWZWN0b3JTdG9yZSwgTmFycmF0aXZlTWVtb3J5IH0gZnJvbSAnLi92ZWN0b3JTdG9yZS5qcyc7XHJcbmltcG9ydCB0eXBlIHsgQ2Fub25TdG9yZSB9IGZyb20gJy4vY2Fub25TdG9yZS5qcyc7XHJcbmltcG9ydCB7IENvbnN0cmFpbnRHcmFwaCB9IGZyb20gJy4uL2NvbnN0cmFpbnRzL2NvbnN0cmFpbnRHcmFwaC5qcyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlVXBkYXRlUmVzdWx0IHtcclxuICBzdHJ1Y3R1cmVkU3RhdGU6IFN0b3J5U3RydWN0dXJlZFN0YXRlO1xyXG4gIG1lbW9yaWVzQWRkZWQ6IG51bWJlcjtcclxuICBjYW5vbkZhY3RzQWRkZWQ6IG51bWJlcjtcclxuICBncmFwaFVwZGF0ZWQ6IGJvb2xlYW47XHJcbiAgY2hhbmdlczogU3RhdGVDaGFuZ2VbXTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBTdGF0ZUNoYW5nZSB7XHJcbiAgdHlwZTogJ2NoYXJhY3RlcicgfCAncGxvdCcgfCAnd29ybGQnIHwgJ2Nhbm9uJyB8ICdtZW1vcnknO1xyXG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XHJcbiAgY2hhcHRlcjogbnVtYmVyO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFVwZGF0ZUNvbnRleHQge1xyXG4gIGNoYXB0ZXI6IENoYXB0ZXI7XHJcbiAgYmlibGU6IFN0b3J5QmlibGU7XHJcbiAgY3VycmVudFN0YXRlOiBTdG9yeVN0cnVjdHVyZWRTdGF0ZTtcclxuICBjYW5vbjogQ2Fub25TdG9yZTtcclxuICB2ZWN0b3JTdG9yZTogVmVjdG9yU3RvcmU7XHJcbiAgY29uc3RyYWludEdyYXBoOiBDb25zdHJhaW50R3JhcGg7XHJcbn1cclxuXHJcbmNvbnN0IFNUQVRFX0VYVFJBQ1RJT05fUFJPTVBUID0gYFlvdSBhcmUgYSBuYXJyYXRpdmUgc3RhdGUgZXh0cmFjdG9yLiBBbmFseXplIHRoaXMgY2hhcHRlciBhbmQgZXh0cmFjdCBhbGwgc3RhdGUgY2hhbmdlcy5cclxuXHJcbiMjIFN0b3J5IEJpYmxlXHJcblxyXG4qKlRpdGxlOioqIHt7dGl0bGV9fVxyXG4qKkdlbnJlOioqIHt7Z2VucmV9fVxyXG5cclxuIyMgQ2hhcHRlciB7e2NoYXB0ZXJOdW1iZXJ9fToge3tjaGFwdGVyVGl0bGV9fVxyXG5cclxue3tjaGFwdGVyQ29udGVudH19XHJcblxyXG4jIyBDdXJyZW50IENoYXJhY3RlciBTdGF0ZXNcclxuXHJcbnt7Y2hhcmFjdGVyc319XHJcblxyXG4jIyBDdXJyZW50IFBsb3QgVGhyZWFkc1xyXG5cclxue3twbG90VGhyZWFkc319XHJcblxyXG4jIyBFeHRyYWN0aW9uIFRhc2tcclxuXHJcbkV4dHJhY3QgdGhlIGZvbGxvd2luZzpcclxuXHJcbjEuICoqQ2hhcmFjdGVyIENoYW5nZXMqKjogSG93IGRvIGNoYXJhY3RlcnMgY2hhbmdlPyAoZW1vdGlvbiwgbG9jYXRpb24sIGtub3dsZWRnZSwgcmVsYXRpb25zaGlwcywgZ29hbHMpXHJcbjIuICoqUGxvdCBUaHJlYWQgQ2hhbmdlcyoqOiBIb3cgZG8gcGxvdCB0aHJlYWRzIHByb2dyZXNzPyAoc3RhdHVzLCB0ZW5zaW9uLCBzdW1tYXJ5IHVwZGF0ZXMpXHJcbjMuICoqTmV3IEZhY3RzKio6IEFueSBuZXcgY2Fub24gZmFjdHMgZXN0YWJsaXNoZWQ/XHJcbjQuICoqV29ybGQgQ2hhbmdlcyoqOiBBbnkgY2hhbmdlcyB0byB0aGUgd29ybGQgc2V0dGluZz9cclxuXHJcbk91dHB1dCBKU09OOlxyXG57XHJcbiAgXCJjaGFyYWN0ZXJDaGFuZ2VzXCI6IFtcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiY2hhcmFjdGVyIG5hbWVcIixcclxuICAgICAgXCJlbW90aW9uYWxTdGF0ZVwiOiBcIm5ldyBlbW90aW9uYWwgc3RhdGUgb3IgbnVsbFwiLFxyXG4gICAgICBcImxvY2F0aW9uXCI6IFwibmV3IGxvY2F0aW9uIG9yIG51bGxcIixcclxuICAgICAgXCJuZXdLbm93bGVkZ2VcIjogW1wiZmFjdHMgbGVhcm5lZFwiXSxcclxuICAgICAgXCJyZWxhdGlvbnNoaXBDaGFuZ2VzXCI6IFt7XCJ3aXRoXCI6IFwib3RoZXIgY2hhcmFjdGVyXCIsIFwibmV3U3RhdHVzXCI6IFwicmVsYXRpb25zaGlwXCJ9XSxcclxuICAgICAgXCJuZXdHb2FsXCI6IFwibmV3IGdvYWwgb3IgbnVsbFwiXHJcbiAgICB9XHJcbiAgXSxcclxuICBcInBsb3RUaHJlYWRDaGFuZ2VzXCI6IFtcclxuICAgIHtcclxuICAgICAgXCJpZFwiOiBcInRocmVhZCBpZFwiLFxyXG4gICAgICBcInN0YXR1c1wiOiBcIm5ldyBzdGF0dXMgb3IgbnVsbFwiLFxyXG4gICAgICBcInRlbnNpb25EZWx0YVwiOiAwLjEsXHJcbiAgICAgIFwibmV3U3VtbWFyeVwiOiBcInVwZGF0ZWQgc3VtbWFyeSBvciBudWxsXCJcclxuICAgIH1cclxuICBdLFxyXG4gIFwibmV3RmFjdHNcIjogW1xyXG4gICAge1xyXG4gICAgICBcImNhdGVnb3J5XCI6IFwiY2hhcmFjdGVyfHdvcmxkfHBsb3RcIixcclxuICAgICAgXCJzdWJqZWN0XCI6IFwic3ViamVjdFwiLFxyXG4gICAgICBcImF0dHJpYnV0ZVwiOiBcImF0dHJpYnV0ZVwiLFxyXG4gICAgICBcInZhbHVlXCI6IFwidmFsdWVcIlxyXG4gICAgfVxyXG4gIF0sXHJcbiAgXCJ3b3JsZENoYW5nZXNcIjogW1wiYW55IGNoYW5nZXMgdG8gdGhlIHdvcmxkXCJdXHJcbn1gO1xyXG5cclxuZXhwb3J0IGNsYXNzIFN0YXRlVXBkYXRlclBpcGVsaW5lIHtcclxuICAvKipcclxuICAgKiBSdW4gdGhlIGNvbXBsZXRlIHBvc3QtY2hhcHRlciB1cGRhdGUgcGlwZWxpbmVcclxuICAgKi9cclxuICBhc3luYyB1cGRhdGUoY29udGV4dDogVXBkYXRlQ29udGV4dCk6IFByb21pc2U8U3RhdGVVcGRhdGVSZXN1bHQ+IHtcclxuICAgIGNvbnN0IHsgY2hhcHRlciwgYmlibGUsIGN1cnJlbnRTdGF0ZSwgY2Fub24sIHZlY3RvclN0b3JlLCBjb25zdHJhaW50R3JhcGggfSA9IGNvbnRleHQ7XHJcbiAgICBcclxuICAgIGNvbnN0IGNoYW5nZXM6IFN0YXRlQ2hhbmdlW10gPSBbXTtcclxuICAgIGxldCBtZW1vcmllc0FkZGVkID0gMDtcclxuICAgIGxldCBjYW5vbkZhY3RzQWRkZWQgPSAwO1xyXG4gICAgXHJcbiAgICAvLyBTdGVwIDE6IEV4dHJhY3Qgc3RhdGUgY2hhbmdlcyB1c2luZyBMTE1cclxuICAgIGNvbnN0IGV4dHJhY3Rpb24gPSBhd2FpdCB0aGlzLmV4dHJhY3RDaGFuZ2VzKGNoYXB0ZXIsIGJpYmxlLCBjdXJyZW50U3RhdGUpO1xyXG4gICAgXHJcbiAgICAvLyBTdGVwIDI6IFVwZGF0ZSBzdHJ1Y3R1cmVkIHN0YXRlXHJcbiAgICBsZXQgbmV3U3RhdGUgPSB7IC4uLmN1cnJlbnRTdGF0ZSB9O1xyXG4gICAgbmV3U3RhdGUuY2hhcHRlciA9IGNoYXB0ZXIubnVtYmVyO1xyXG4gICAgXHJcbiAgICAvLyBBcHBseSBjaGFyYWN0ZXIgY2hhbmdlc1xyXG4gICAgZm9yIChjb25zdCBjaGFuZ2Ugb2YgZXh0cmFjdGlvbi5jaGFyYWN0ZXJDaGFuZ2VzKSB7XHJcbiAgICAgIGlmIChuZXdTdGF0ZS5jaGFyYWN0ZXJzW2NoYW5nZS5uYW1lXSkge1xyXG4gICAgICAgIGNvbnN0IGNoYXIgPSBuZXdTdGF0ZS5jaGFyYWN0ZXJzW2NoYW5nZS5uYW1lXTtcclxuICAgICAgICBcclxuICAgICAgICBpZiAoY2hhbmdlLmVtb3Rpb25hbFN0YXRlKSB7XHJcbiAgICAgICAgICBjaGFyLmVtb3Rpb25hbFN0YXRlID0gY2hhbmdlLmVtb3Rpb25hbFN0YXRlO1xyXG4gICAgICAgICAgY2hhbmdlcy5wdXNoKHtcclxuICAgICAgICAgICAgdHlwZTogJ2NoYXJhY3RlcicsXHJcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgJHtjaGFuZ2UubmFtZX0gZW1vdGlvbmFsIHN0YXRlIOKGkiAke2NoYW5nZS5lbW90aW9uYWxTdGF0ZX1gLFxyXG4gICAgICAgICAgICBjaGFwdGVyOiBjaGFwdGVyLm51bWJlcixcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICBpZiAoY2hhbmdlLmxvY2F0aW9uKSB7XHJcbiAgICAgICAgICBjb25zdCBvbGRMb2NhdGlvbiA9IGNoYXIubG9jYXRpb247XHJcbiAgICAgICAgICBjaGFyLmxvY2F0aW9uID0gY2hhbmdlLmxvY2F0aW9uO1xyXG4gICAgICAgICAgY2hhbmdlcy5wdXNoKHtcclxuICAgICAgICAgICAgdHlwZTogJ2NoYXJhY3RlcicsXHJcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgJHtjaGFuZ2UubmFtZX0gbW92ZWQ6ICR7b2xkTG9jYXRpb259IOKGkiAke2NoYW5nZS5sb2NhdGlvbn1gLFxyXG4gICAgICAgICAgICBjaGFwdGVyOiBjaGFwdGVyLm51bWJlcixcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICAvLyBVcGRhdGUgY29uc3RyYWludCBncmFwaFxyXG4gICAgICAgICAgY29uc3RyYWludEdyYXBoLnVwZGF0ZUNoYXJhY3RlckxvY2F0aW9uKGNoYW5nZS5uYW1lLCBjaGFuZ2UubG9jYXRpb24sIGNoYXB0ZXIubnVtYmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKGNoYW5nZS5uZXdLbm93bGVkZ2UpIHtcclxuICAgICAgICAgIGNoYXIua25vd2xlZGdlID0gWy4uLmNoYXIua25vd2xlZGdlLCAuLi5jaGFuZ2UubmV3S25vd2xlZGdlXTtcclxuICAgICAgICAgIFxyXG4gICAgICAgICAgLy8gQWRkIHRvIGNvbnN0cmFpbnQgZ3JhcGhcclxuICAgICAgICAgIGZvciAoY29uc3Qga25vd2xlZGdlIG9mIGNoYW5nZS5uZXdLbm93bGVkZ2UpIHtcclxuICAgICAgICAgICAgY29uc3QgZmFjdElkID0gYGZhY3QtJHt0aGlzLnNhbml0aXplSWQoa25vd2xlZGdlKX1gO1xyXG4gICAgICAgICAgICBpZiAoIWNvbnN0cmFpbnRHcmFwaC5nZXROb2RlKGZhY3RJZCkpIHtcclxuICAgICAgICAgICAgICBjb25zdHJhaW50R3JhcGguYWRkTm9kZSh7XHJcbiAgICAgICAgICAgICAgICBpZDogZmFjdElkLFxyXG4gICAgICAgICAgICAgICAgdHlwZTogJ2ZhY3QnLFxyXG4gICAgICAgICAgICAgICAgbGFiZWw6IGtub3dsZWRnZSxcclxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXM6IHt9LFxyXG4gICAgICAgICAgICAgICAgY2hhcHRlckVzdGFibGlzaGVkOiBjaGFwdGVyLm51bWJlcixcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgY29uc3RyYWludEdyYXBoLmFkZEVkZ2Uoe1xyXG4gICAgICAgICAgICAgIGlkOiBgZWRnZS0ke2NoYW5nZS5uYW1lfS1rbm93cy0ke2ZhY3RJZH1gLFxyXG4gICAgICAgICAgICAgIGZyb206IGBjaGFyLSR7Y2hhbmdlLm5hbWV9YCxcclxuICAgICAgICAgICAgICB0bzogZmFjdElkLFxyXG4gICAgICAgICAgICAgIHR5cGU6ICdrbm93cycsXHJcbiAgICAgICAgICAgICAgcHJvcGVydGllczogeyBzaW5jZTogY2hhcHRlci5udW1iZXIgfSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChjaGFuZ2UucmVsYXRpb25zaGlwQ2hhbmdlcykge1xyXG4gICAgICAgICAgZm9yIChjb25zdCByZWwgb2YgY2hhbmdlLnJlbGF0aW9uc2hpcENoYW5nZXMpIHtcclxuICAgICAgICAgICAgY2hhci5yZWxhdGlvbnNoaXBzW3JlbC53aXRoXSA9IHJlbC5uZXdTdGF0dXM7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChjaGFuZ2UubmV3R29hbCkge1xyXG4gICAgICAgICAgY2hhci5nb2FscyA9IFsuLi5jaGFyLmdvYWxzLCBjaGFuZ2UubmV3R29hbF07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIC8vIEFwcGx5IHBsb3QgdGhyZWFkIGNoYW5nZXNcclxuICAgIGZvciAoY29uc3QgY2hhbmdlIG9mIGV4dHJhY3Rpb24ucGxvdFRocmVhZENoYW5nZXMpIHtcclxuICAgICAgaWYgKG5ld1N0YXRlLnBsb3RUaHJlYWRzW2NoYW5nZS5pZF0pIHtcclxuICAgICAgICBjb25zdCB0aHJlYWQgPSBuZXdTdGF0ZS5wbG90VGhyZWFkc1tjaGFuZ2UuaWRdO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChjaGFuZ2Uuc3RhdHVzKSB7XHJcbiAgICAgICAgICB0aHJlYWQuc3RhdHVzID0gY2hhbmdlLnN0YXR1cztcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKGNoYW5nZS50ZW5zaW9uRGVsdGEpIHtcclxuICAgICAgICAgIHRocmVhZC50ZW5zaW9uID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgdGhyZWFkLnRlbnNpb24gKyBjaGFuZ2UudGVuc2lvbkRlbHRhKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChjaGFuZ2UubmV3U3VtbWFyeSkge1xyXG4gICAgICAgICAgdGhyZWFkLnN1bW1hcnkgPSBjaGFuZ2UubmV3U3VtbWFyeTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhyZWFkLmxhc3RDaGFwdGVyID0gY2hhcHRlci5udW1iZXI7XHJcbiAgICAgICAgXHJcbiAgICAgICAgY2hhbmdlcy5wdXNoKHtcclxuICAgICAgICAgIHR5cGU6ICdwbG90JyxcclxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgJHt0aHJlYWQubmFtZX0gdXBkYXRlZDogJHtjaGFuZ2Uuc3RhdHVzIHx8ICdwcm9ncmVzcyd9YCxcclxuICAgICAgICAgIGNoYXB0ZXI6IGNoYXB0ZXIubnVtYmVyLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIC8vIFN0ZXAgMzogQWRkIG5ldyBjYW5vbiBmYWN0c1xyXG4gICAgZm9yIChjb25zdCBmYWN0IG9mIGV4dHJhY3Rpb24ubmV3RmFjdHMpIHtcclxuICAgICAgLy8gSW4gcmVhbCBpbXBsZW1lbnRhdGlvbiwgd291bGQgYWRkIHRvIGNhbm9uIHN0b3JlXHJcbiAgICAgIGNhbm9uRmFjdHNBZGRlZCsrO1xyXG4gICAgICBjaGFuZ2VzLnB1c2goe1xyXG4gICAgICAgIHR5cGU6ICdjYW5vbicsXHJcbiAgICAgICAgZGVzY3JpcHRpb246IGBDYW5vbjogJHtmYWN0LnN1YmplY3R9ICR7ZmFjdC5hdHRyaWJ1dGV9ID0gJHtmYWN0LnZhbHVlfWAsXHJcbiAgICAgICAgY2hhcHRlcjogY2hhcHRlci5udW1iZXIsXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLyBTdGVwIDQ6IEV4dHJhY3QgYW5kIGFkZCBuYXJyYXRpdmUgbWVtb3JpZXNcclxuICAgIGNvbnN0IG1lbW9yaWVzID0gYXdhaXQgdGhpcy5leHRyYWN0TWVtb3JpZXMoY2hhcHRlciwgYmlibGUpO1xyXG4gICAgZm9yIChjb25zdCBtZW1vcnkgb2YgbWVtb3JpZXMpIHtcclxuICAgICAgYXdhaXQgdmVjdG9yU3RvcmUuYWRkTWVtb3J5KHtcclxuICAgICAgICBzdG9yeUlkOiBjaGFwdGVyLnN0b3J5SWQsXHJcbiAgICAgICAgY2hhcHRlck51bWJlcjogY2hhcHRlci5udW1iZXIsXHJcbiAgICAgICAgY29udGVudDogbWVtb3J5LmNvbnRlbnQsXHJcbiAgICAgICAgY2F0ZWdvcnk6IG1lbW9yeS5jYXRlZ29yeSxcclxuICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXHJcbiAgICAgIH0pO1xyXG4gICAgICBtZW1vcmllc0FkZGVkKys7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGNoYW5nZXMucHVzaCh7XHJcbiAgICAgIHR5cGU6ICdtZW1vcnknLFxyXG4gICAgICBkZXNjcmlwdGlvbjogYCR7bWVtb3JpZXNBZGRlZH0gbmFycmF0aXZlIG1lbW9yaWVzIGV4dHJhY3RlZGAsXHJcbiAgICAgIGNoYXB0ZXI6IGNoYXB0ZXIubnVtYmVyLFxyXG4gICAgfSk7XHJcbiAgICBcclxuICAgIC8vIFN0ZXAgNTogQWRkIGV2ZW50IHRvIGNvbnN0cmFpbnQgZ3JhcGhcclxuICAgIGNvbnN0cmFpbnRHcmFwaC5hZGRFdmVudChcclxuICAgICAgYGNoJHtjaGFwdGVyLm51bWJlcn1gLFxyXG4gICAgICBjaGFwdGVyLnN1bW1hcnksXHJcbiAgICAgIE9iamVjdC5rZXlzKG5ld1N0YXRlLmNoYXJhY3RlcnMpLFxyXG4gICAgICBjaGFwdGVyLm51bWJlclxyXG4gICAgKTtcclxuICAgIFxyXG4gICAgLy8gU3RlcCA2OiBVcGRhdGUgcmVjZW50IGV2ZW50c1xyXG4gICAgbmV3U3RhdGUucmVjZW50RXZlbnRzID0gWy4uLm5ld1N0YXRlLnJlY2VudEV2ZW50cywgY2hhcHRlci5zdW1tYXJ5XS5zbGljZSgtMTApO1xyXG4gICAgXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBzdHJ1Y3R1cmVkU3RhdGU6IG5ld1N0YXRlLFxyXG4gICAgICBtZW1vcmllc0FkZGVkLFxyXG4gICAgICBjYW5vbkZhY3RzQWRkZWQsXHJcbiAgICAgIGdyYXBoVXBkYXRlZDogdHJ1ZSxcclxuICAgICAgY2hhbmdlcyxcclxuICAgIH07XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIEV4dHJhY3Qgc3RhdGUgY2hhbmdlcyBmcm9tIGNoYXB0ZXJcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIGV4dHJhY3RDaGFuZ2VzKFxyXG4gICAgY2hhcHRlcjogQ2hhcHRlcixcclxuICAgIGJpYmxlOiBTdG9yeUJpYmxlLFxyXG4gICAgc3RhdGU6IFN0b3J5U3RydWN0dXJlZFN0YXRlXHJcbiAgKTogUHJvbWlzZTx7XHJcbiAgICBjaGFyYWN0ZXJDaGFuZ2VzOiBBcnJheTx7XHJcbiAgICAgIG5hbWU6IHN0cmluZztcclxuICAgICAgZW1vdGlvbmFsU3RhdGU/OiBzdHJpbmc7XHJcbiAgICAgIGxvY2F0aW9uPzogc3RyaW5nO1xyXG4gICAgICBuZXdLbm93bGVkZ2U/OiBzdHJpbmdbXTtcclxuICAgICAgcmVsYXRpb25zaGlwQ2hhbmdlcz86IEFycmF5PHsgd2l0aDogc3RyaW5nOyBuZXdTdGF0dXM6IHN0cmluZyB9PjtcclxuICAgICAgbmV3R29hbD86IHN0cmluZztcclxuICAgIH0+O1xyXG4gICAgcGxvdFRocmVhZENoYW5nZXM6IEFycmF5PHtcclxuICAgICAgaWQ6IHN0cmluZztcclxuICAgICAgc3RhdHVzPzogJ2Rvcm1hbnQnIHwgJ2FjdGl2ZScgfCAnZXNjYWxhdGluZycgfCAncmVzb2x2ZWQnO1xyXG4gICAgICB0ZW5zaW9uRGVsdGE/OiBudW1iZXI7XHJcbiAgICAgIG5ld1N1bW1hcnk/OiBzdHJpbmc7XHJcbiAgICB9PjtcclxuICAgIG5ld0ZhY3RzOiBBcnJheTx7XHJcbiAgICAgIGNhdGVnb3J5OiAnY2hhcmFjdGVyJyB8ICd3b3JsZCcgfCAncGxvdCc7XHJcbiAgICAgIHN1YmplY3Q6IHN0cmluZztcclxuICAgICAgYXR0cmlidXRlOiBzdHJpbmc7XHJcbiAgICAgIHZhbHVlOiBzdHJpbmc7XHJcbiAgICB9PjtcclxuICAgIHdvcmxkQ2hhbmdlczogc3RyaW5nW107XHJcbiAgfT4ge1xyXG4gICAgY29uc3QgY2hhcmFjdGVycyA9IE9iamVjdC52YWx1ZXMoc3RhdGUuY2hhcmFjdGVycylcclxuICAgICAgLm1hcChjID0+IGAtICR7Yy5uYW1lfTogJHtjLmVtb3Rpb25hbFN0YXRlfSwgYXQgJHtjLmxvY2F0aW9ufWApXHJcbiAgICAgIC5qb2luKCdcXG4nKTtcclxuICAgIFxyXG4gICAgY29uc3QgcGxvdFRocmVhZHMgPSBPYmplY3QudmFsdWVzKHN0YXRlLnBsb3RUaHJlYWRzKVxyXG4gICAgICAubWFwKHQgPT4gYC0gJHt0Lm5hbWV9ICgke3Quc3RhdHVzfSwgJHtNYXRoLnJvdW5kKHQudGVuc2lvbiAqIDEwMCl9JSB0ZW5zaW9uKWApXHJcbiAgICAgIC5qb2luKCdcXG4nKTtcclxuICAgIFxyXG4gICAgY29uc3QgcHJvbXB0ID0gU1RBVEVfRVhUUkFDVElPTl9QUk9NUFRcclxuICAgICAgLnJlcGxhY2UoJ3t7dGl0bGV9fScsIGJpYmxlLnRpdGxlKVxyXG4gICAgICAucmVwbGFjZSgne3tnZW5yZX19JywgYmlibGUuZ2VucmUpXHJcbiAgICAgIC5yZXBsYWNlKCd7e2NoYXB0ZXJOdW1iZXJ9fScsIGNoYXB0ZXIubnVtYmVyLnRvU3RyaW5nKCkpXHJcbiAgICAgIC5yZXBsYWNlKCd7e2NoYXB0ZXJUaXRsZX19JywgY2hhcHRlci50aXRsZSlcclxuICAgICAgLnJlcGxhY2UoJ3t7Y2hhcHRlckNvbnRlbnR9fScsIGNoYXB0ZXIuY29udGVudC5zdWJzdHJpbmcoMCwgNTAwMCkpXHJcbiAgICAgIC5yZXBsYWNlKCd7e2NoYXJhY3RlcnN9fScsIGNoYXJhY3RlcnMpXHJcbiAgICAgIC5yZXBsYWNlKCd7e3Bsb3RUaHJlYWRzfX0nLCBwbG90VGhyZWFkcyk7XHJcbiAgICBcclxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdldExMTSgpLmNvbXBsZXRlSlNPTjx7XHJcbiAgICAgIGNoYXJhY3RlckNoYW5nZXM6IGFueVtdO1xyXG4gICAgICBwbG90VGhyZWFkQ2hhbmdlczogYW55W107XHJcbiAgICAgIG5ld0ZhY3RzOiBhbnlbXTtcclxuICAgICAgd29ybGRDaGFuZ2VzOiBzdHJpbmdbXTtcclxuICAgIH0+KHByb21wdCwge1xyXG4gICAgICB0ZW1wZXJhdHVyZTogMC4zLFxyXG4gICAgICBtYXhUb2tlbnM6IDIwMDAsXHJcbiAgICB9KTtcclxuICAgIFxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcbiAgXHJcbiAgLyoqXHJcbiAgICogRXh0cmFjdCBuYXJyYXRpdmUgbWVtb3JpZXMgZnJvbSBjaGFwdGVyXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhc3luYyBleHRyYWN0TWVtb3JpZXMoXHJcbiAgICBjaGFwdGVyOiBDaGFwdGVyLFxyXG4gICAgYmlibGU6IFN0b3J5QmlibGVcclxuICApOiBQcm9taXNlPEFycmF5PHsgY29udGVudDogc3RyaW5nOyBjYXRlZ29yeTogTmFycmF0aXZlTWVtb3J5WydjYXRlZ29yeSddIH0+PiB7XHJcbiAgICAvLyBTaW1wbGlmaWVkIG1lbW9yeSBleHRyYWN0aW9uXHJcbiAgICAvLyBJbiByZWFsIGltcGxlbWVudGF0aW9uLCB3b3VsZCB1c2UgTWVtb3J5RXh0cmFjdG9yIGFnZW50XHJcbiAgICBjb25zdCBtZW1vcmllczogQXJyYXk8eyBjb250ZW50OiBzdHJpbmc7IGNhdGVnb3J5OiBOYXJyYXRpdmVNZW1vcnlbJ2NhdGVnb3J5J10gfT4gPSBbXTtcclxuICAgIFxyXG4gICAgLy8gRXh0cmFjdCBrZXkgZXZlbnRzIGZyb20gc3VtbWFyeVxyXG4gICAgaWYgKGNoYXB0ZXIuc3VtbWFyeSkge1xyXG4gICAgICBtZW1vcmllcy5wdXNoKHtcclxuICAgICAgICBjb250ZW50OiBjaGFwdGVyLnN1bW1hcnksXHJcbiAgICAgICAgY2F0ZWdvcnk6ICdldmVudCcsXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLyBBZGQgY2hhcHRlciB0aXRsZSBhcyBtZW1vcnlcclxuICAgIG1lbW9yaWVzLnB1c2goe1xyXG4gICAgICBjb250ZW50OiBgQ2hhcHRlciAke2NoYXB0ZXIubnVtYmVyfTogJHtjaGFwdGVyLnRpdGxlfWAsXHJcbiAgICAgIGNhdGVnb3J5OiAncGxvdCcsXHJcbiAgICB9KTtcclxuICAgIFxyXG4gICAgcmV0dXJuIG1lbW9yaWVzO1xyXG4gIH1cclxuICBcclxuICAvKipcclxuICAgKiBRdWljayB1cGRhdGUgd2l0aG91dCBMTE0gKGZvciB0ZXN0aW5nKVxyXG4gICAqL1xyXG4gIGFzeW5jIHF1aWNrVXBkYXRlKGNvbnRleHQ6IFVwZGF0ZUNvbnRleHQpOiBQcm9taXNlPFN0YXRlVXBkYXRlUmVzdWx0PiB7XHJcbiAgICBjb25zdCB7IGNoYXB0ZXIsIGN1cnJlbnRTdGF0ZSwgdmVjdG9yU3RvcmUsIGNvbnN0cmFpbnRHcmFwaCB9ID0gY29udGV4dDtcclxuICAgIFxyXG4gICAgY29uc3QgY2hhbmdlczogU3RhdGVDaGFuZ2VbXSA9IFtdO1xyXG4gICAgbGV0IG5ld1N0YXRlID0geyAuLi5jdXJyZW50U3RhdGUgfTtcclxuICAgIG5ld1N0YXRlLmNoYXB0ZXIgPSBjaGFwdGVyLm51bWJlcjtcclxuICAgIFxyXG4gICAgLy8gQWRkIGJhc2ljIG1lbW9yaWVzXHJcbiAgICBhd2FpdCB2ZWN0b3JTdG9yZS5hZGRNZW1vcnkoe1xyXG4gICAgICBzdG9yeUlkOiBjaGFwdGVyLnN0b3J5SWQsXHJcbiAgICAgIGNoYXB0ZXJOdW1iZXI6IGNoYXB0ZXIubnVtYmVyLFxyXG4gICAgICBjb250ZW50OiBjaGFwdGVyLnN1bW1hcnksXHJcbiAgICAgIGNhdGVnb3J5OiAnZXZlbnQnLFxyXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXHJcbiAgICB9KTtcclxuICAgIFxyXG4gICAgYXdhaXQgdmVjdG9yU3RvcmUuYWRkTWVtb3J5KHtcclxuICAgICAgc3RvcnlJZDogY2hhcHRlci5zdG9yeUlkLFxyXG4gICAgICBjaGFwdGVyTnVtYmVyOiBjaGFwdGVyLm51bWJlcixcclxuICAgICAgY29udGVudDogYENoYXB0ZXIgJHtjaGFwdGVyLm51bWJlcn06ICR7Y2hhcHRlci50aXRsZX1gLFxyXG4gICAgICBjYXRlZ29yeTogJ3Bsb3QnLFxyXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXHJcbiAgICB9KTtcclxuICAgIFxyXG4gICAgY2hhbmdlcy5wdXNoKHtcclxuICAgICAgdHlwZTogJ21lbW9yeScsXHJcbiAgICAgIGRlc2NyaXB0aW9uOiBgMiBtZW1vcmllcyBhZGRlZCAocXVpY2sgbW9kZSlgLFxyXG4gICAgICBjaGFwdGVyOiBjaGFwdGVyLm51bWJlcixcclxuICAgIH0pO1xyXG4gICAgXHJcbiAgICAvLyBVcGRhdGUgcmVjZW50IGV2ZW50c1xyXG4gICAgbmV3U3RhdGUucmVjZW50RXZlbnRzID0gWy4uLm5ld1N0YXRlLnJlY2VudEV2ZW50cywgY2hhcHRlci5zdW1tYXJ5XS5zbGljZSgtMTApO1xyXG4gICAgXHJcbiAgICAvLyBBZGQgdG8gY29uc3RyYWludCBncmFwaFxyXG4gICAgY29uc3RyYWludEdyYXBoLmFkZEV2ZW50KFxyXG4gICAgICBgY2gke2NoYXB0ZXIubnVtYmVyfWAsXHJcbiAgICAgIGNoYXB0ZXIuc3VtbWFyeSxcclxuICAgICAgT2JqZWN0LmtleXMobmV3U3RhdGUuY2hhcmFjdGVycyksXHJcbiAgICAgIGNoYXB0ZXIubnVtYmVyXHJcbiAgICApO1xyXG4gICAgXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBzdHJ1Y3R1cmVkU3RhdGU6IG5ld1N0YXRlLFxyXG4gICAgICBtZW1vcmllc0FkZGVkOiAyLFxyXG4gICAgICBjYW5vbkZhY3RzQWRkZWQ6IDAsXHJcbiAgICAgIGdyYXBoVXBkYXRlZDogdHJ1ZSxcclxuICAgICAgY2hhbmdlcyxcclxuICAgIH07XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIEZvcm1hdCB1cGRhdGUgcmVzdWx0XHJcbiAgICovXHJcbiAgZm9ybWF0UmVzdWx0KHJlc3VsdDogU3RhdGVVcGRhdGVSZXN1bHQpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gWycjIyBTdGF0ZSBVcGRhdGUgUmVzdWx0J107XHJcbiAgICBcclxuICAgIGxpbmVzLnB1c2goYFxcbioqTWVtb3JpZXMgQWRkZWQ6KiogJHtyZXN1bHQubWVtb3JpZXNBZGRlZH1gKTtcclxuICAgIGxpbmVzLnB1c2goYCoqQ2Fub24gRmFjdHMgQWRkZWQ6KiogJHtyZXN1bHQuY2Fub25GYWN0c0FkZGVkfWApO1xyXG4gICAgbGluZXMucHVzaChgKipHcmFwaCBVcGRhdGVkOioqICR7cmVzdWx0LmdyYXBoVXBkYXRlZCA/ICfinIUnIDogJ+KdjCd9YCk7XHJcbiAgICBcclxuICAgIGlmIChyZXN1bHQuY2hhbmdlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGxpbmVzLnB1c2goJ1xcbioqQ2hhbmdlczoqKicpO1xyXG4gICAgICBcclxuICAgICAgY29uc3QgYnlUeXBlOiBSZWNvcmQ8c3RyaW5nLCBTdGF0ZUNoYW5nZVtdPiA9IHtcclxuICAgICAgICBjaGFyYWN0ZXI6IFtdLFxyXG4gICAgICAgIHBsb3Q6IFtdLFxyXG4gICAgICAgIHdvcmxkOiBbXSxcclxuICAgICAgICBjYW5vbjogW10sXHJcbiAgICAgICAgbWVtb3J5OiBbXSxcclxuICAgICAgfTtcclxuICAgICAgXHJcbiAgICAgIGZvciAoY29uc3QgY2hhbmdlIG9mIHJlc3VsdC5jaGFuZ2VzKSB7XHJcbiAgICAgICAgYnlUeXBlW2NoYW5nZS50eXBlXS5wdXNoKGNoYW5nZSk7XHJcbiAgICAgIH1cclxuICAgICAgXHJcbiAgICAgIGZvciAoY29uc3QgW3R5cGUsIGNoYW5nZXNdIG9mIE9iamVjdC5lbnRyaWVzKGJ5VHlwZSkpIHtcclxuICAgICAgICBpZiAoY2hhbmdlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICBsaW5lcy5wdXNoKGBcXG4qJHt0eXBlLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgdHlwZS5zbGljZSgxKX06KmApO1xyXG4gICAgICAgICAgZm9yIChjb25zdCBjaGFuZ2Ugb2YgY2hhbmdlcykge1xyXG4gICAgICAgICAgICBsaW5lcy5wdXNoKGAgIC0gJHtjaGFuZ2UuZGVzY3JpcHRpb259YCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHJldHVybiBsaW5lcy5qb2luKCdcXG4nKTtcclxuICB9XHJcbiAgXHJcbiAgcHJpdmF0ZSBzYW5pdGl6ZUlkKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBzdHIucmVwbGFjZSgvW15hLXpBLVowLTldL2csICdfJykuc3Vic3RyaW5nKDAsIDUwKTtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBzdGF0ZVVwZGF0ZXJQaXBlbGluZSA9IG5ldyBTdGF0ZVVwZGF0ZXJQaXBlbGluZSgpO1xyXG4iXX0=
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface NarrativeMemory {
|
|
2
|
+
id: number;
|
|
3
|
+
storyId: string;
|
|
4
|
+
chapterNumber: number;
|
|
5
|
+
content: string;
|
|
6
|
+
category: 'event' | 'character' | 'world' | 'plot';
|
|
7
|
+
timestamp: Date;
|
|
8
|
+
embedding?: number[];
|
|
9
|
+
}
|
|
10
|
+
export interface MemorySearchResult {
|
|
11
|
+
memory: NarrativeMemory;
|
|
12
|
+
score: number;
|
|
13
|
+
}
|
|
14
|
+
export declare class VectorStore {
|
|
15
|
+
private index;
|
|
16
|
+
private memories;
|
|
17
|
+
private dimension;
|
|
18
|
+
private storyId;
|
|
19
|
+
private nextId;
|
|
20
|
+
constructor(storyId: string);
|
|
21
|
+
initialize(maxElements?: number): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Resize the index to accommodate more memories
|
|
24
|
+
*/
|
|
25
|
+
resizeIndex(newMaxElements: number): void;
|
|
26
|
+
/**
|
|
27
|
+
* Ensure capacity for upcoming memories
|
|
28
|
+
*/
|
|
29
|
+
ensureCapacity(additionalMemories: number): void;
|
|
30
|
+
addMemory(memory: Omit<NarrativeMemory, 'id' | 'embedding'>): Promise<NarrativeMemory>;
|
|
31
|
+
searchSimilar(query: string, k?: number): Promise<MemorySearchResult[]>;
|
|
32
|
+
searchByCategory(query: string, category: NarrativeMemory['category'], k?: number): Promise<MemorySearchResult[]>;
|
|
33
|
+
getMemoriesByChapter(chapterNumber: number): NarrativeMemory[];
|
|
34
|
+
getAllMemories(): NarrativeMemory[];
|
|
35
|
+
private generateEmbedding;
|
|
36
|
+
private generateMockEmbedding;
|
|
37
|
+
serialize(): string;
|
|
38
|
+
load(data: string): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export declare function getVectorStore(storyId: string): VectorStore;
|
|
41
|
+
export declare function clearVectorStore(storyId: string): void;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VectorStore = void 0;
|
|
4
|
+
exports.getVectorStore = getVectorStore;
|
|
5
|
+
exports.clearVectorStore = clearVectorStore;
|
|
6
|
+
const client_js_1 = require("../llm/client.js");
|
|
7
|
+
const hnswlib_node_1 = require("hnswlib-node");
|
|
8
|
+
class VectorStore {
|
|
9
|
+
index = null;
|
|
10
|
+
memories = new Map();
|
|
11
|
+
dimension = 1536; // text-embedding-3-small dimension
|
|
12
|
+
storyId;
|
|
13
|
+
nextId = 0;
|
|
14
|
+
constructor(storyId) {
|
|
15
|
+
this.storyId = storyId;
|
|
16
|
+
}
|
|
17
|
+
async initialize(maxElements = 10000) {
|
|
18
|
+
this.index = new hnswlib_node_1.HierarchicalNSW('cosine', this.dimension);
|
|
19
|
+
this.index.initIndex(maxElements, 16, 200);
|
|
20
|
+
this.nextId = 0;
|
|
21
|
+
this.memories.clear();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resize the index to accommodate more memories
|
|
25
|
+
*/
|
|
26
|
+
resizeIndex(newMaxElements) {
|
|
27
|
+
if (!this.index) {
|
|
28
|
+
throw new Error('VectorStore not initialized. Call initialize() first.');
|
|
29
|
+
}
|
|
30
|
+
if (newMaxElements <= this.memories.size) {
|
|
31
|
+
return; // No need to resize
|
|
32
|
+
}
|
|
33
|
+
this.index.resizeIndex(newMaxElements);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Ensure capacity for upcoming memories
|
|
37
|
+
*/
|
|
38
|
+
ensureCapacity(additionalMemories) {
|
|
39
|
+
const requiredCapacity = this.memories.size + additionalMemories;
|
|
40
|
+
const currentCapacity = this.index?.getMaxElements() || 0;
|
|
41
|
+
if (requiredCapacity > currentCapacity) {
|
|
42
|
+
// Add 50% more capacity or use required, whichever is larger
|
|
43
|
+
const newCapacity = Math.max(Math.floor(currentCapacity * 1.5), requiredCapacity);
|
|
44
|
+
this.resizeIndex(newCapacity);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async addMemory(memory) {
|
|
48
|
+
if (!this.index) {
|
|
49
|
+
throw new Error('VectorStore not initialized. Call initialize() first.');
|
|
50
|
+
}
|
|
51
|
+
// Auto-resize if we're near capacity (add 50% more)
|
|
52
|
+
const currentCapacity = this.index.getMaxElements();
|
|
53
|
+
if (this.memories.size >= currentCapacity - 1) {
|
|
54
|
+
this.resizeIndex(Math.floor(currentCapacity * 1.5));
|
|
55
|
+
}
|
|
56
|
+
const id = this.nextId++;
|
|
57
|
+
// Generate embedding using OpenAI
|
|
58
|
+
const embedding = await this.generateEmbedding(memory.content);
|
|
59
|
+
const fullMemory = {
|
|
60
|
+
...memory,
|
|
61
|
+
id,
|
|
62
|
+
embedding,
|
|
63
|
+
};
|
|
64
|
+
// Add to HNSW index
|
|
65
|
+
this.index.addPoint(embedding, id);
|
|
66
|
+
this.memories.set(id, fullMemory);
|
|
67
|
+
return fullMemory;
|
|
68
|
+
}
|
|
69
|
+
async searchSimilar(query, k = 5) {
|
|
70
|
+
if (!this.index) {
|
|
71
|
+
throw new Error('VectorStore not initialized. Call initialize() first.');
|
|
72
|
+
}
|
|
73
|
+
const queryEmbedding = await this.generateEmbedding(query);
|
|
74
|
+
const results = this.index.searchKnn(queryEmbedding, k);
|
|
75
|
+
return results.neighbors.map((id, i) => ({
|
|
76
|
+
memory: this.memories.get(id),
|
|
77
|
+
score: results.distances[i],
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
async searchByCategory(query, category, k = 5) {
|
|
81
|
+
const results = await this.searchSimilar(query, k * 2);
|
|
82
|
+
return results
|
|
83
|
+
.filter(r => r.memory.category === category)
|
|
84
|
+
.slice(0, k);
|
|
85
|
+
}
|
|
86
|
+
getMemoriesByChapter(chapterNumber) {
|
|
87
|
+
return Array.from(this.memories.values())
|
|
88
|
+
.filter(m => m.chapterNumber === chapterNumber);
|
|
89
|
+
}
|
|
90
|
+
getAllMemories() {
|
|
91
|
+
return Array.from(this.memories.values());
|
|
92
|
+
}
|
|
93
|
+
async generateEmbedding(text) {
|
|
94
|
+
// Check if we should use mock embeddings (for testing without OpenAI)
|
|
95
|
+
if (process.env.USE_MOCK_EMBEDDINGS === 'true') {
|
|
96
|
+
return this.generateMockEmbedding(text);
|
|
97
|
+
}
|
|
98
|
+
const llm = (0, client_js_1.getLLM)();
|
|
99
|
+
const openai = llm.provider;
|
|
100
|
+
// Access the underlying OpenAI client for embeddings
|
|
101
|
+
const client = openai.client;
|
|
102
|
+
try {
|
|
103
|
+
const response = await client.embeddings.create({
|
|
104
|
+
model: 'text-embedding-3-small',
|
|
105
|
+
input: text,
|
|
106
|
+
});
|
|
107
|
+
return response.data[0].embedding;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
// Fall back to mock embeddings if the API fails (e.g., DeepSeek doesn't support embeddings)
|
|
111
|
+
console.log(' [VectorStore] Using mock embeddings (API unavailable)');
|
|
112
|
+
return this.generateMockEmbedding(text);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
generateMockEmbedding(text) {
|
|
116
|
+
// Generate a deterministic mock embedding based on text content
|
|
117
|
+
// This is NOT for production - just for testing without OpenAI API
|
|
118
|
+
const embedding = [];
|
|
119
|
+
let seed = 0;
|
|
120
|
+
for (let i = 0; i < text.length; i++) {
|
|
121
|
+
seed += text.charCodeAt(i);
|
|
122
|
+
}
|
|
123
|
+
for (let i = 0; i < this.dimension; i++) {
|
|
124
|
+
// Simple pseudo-random based on seed
|
|
125
|
+
seed = (seed * 9301 + 49297) % 233280;
|
|
126
|
+
embedding.push((seed / 233280) * 2 - 1); // Range: -1 to 1
|
|
127
|
+
}
|
|
128
|
+
// Normalize the vector
|
|
129
|
+
const norm = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
|
|
130
|
+
return embedding.map(val => val / norm);
|
|
131
|
+
}
|
|
132
|
+
// Serialize for persistence
|
|
133
|
+
serialize() {
|
|
134
|
+
return JSON.stringify({
|
|
135
|
+
storyId: this.storyId,
|
|
136
|
+
nextId: this.nextId,
|
|
137
|
+
memories: Array.from(this.memories.entries()),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
// Deserialize from saved state
|
|
141
|
+
async load(data) {
|
|
142
|
+
const parsed = JSON.parse(data);
|
|
143
|
+
this.memories = new Map(parsed.memories);
|
|
144
|
+
this.nextId = parsed.nextId || this.memories.size;
|
|
145
|
+
// Rebuild HNSW index
|
|
146
|
+
await this.initialize();
|
|
147
|
+
for (const [id, memory] of this.memories) {
|
|
148
|
+
if (memory.embedding) {
|
|
149
|
+
this.index.addPoint(memory.embedding, id);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
exports.VectorStore = VectorStore;
|
|
155
|
+
// Factory for story-specific stores
|
|
156
|
+
const stores = new Map();
|
|
157
|
+
function getVectorStore(storyId) {
|
|
158
|
+
if (!stores.has(storyId)) {
|
|
159
|
+
stores.set(storyId, new VectorStore(storyId));
|
|
160
|
+
}
|
|
161
|
+
return stores.get(storyId);
|
|
162
|
+
}
|
|
163
|
+
function clearVectorStore(storyId) {
|
|
164
|
+
stores.delete(storyId);
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVjdG9yU3RvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWVtb3J5L3ZlY3RvclN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQXFNQSx3Q0FLQztBQUVELDRDQUVDO0FBOU1ELGdEQUEwQztBQUMxQywrQ0FBK0M7QUFpQi9DLE1BQWEsV0FBVztJQUNkLEtBQUssR0FBMkIsSUFBSSxDQUFDO0lBQ3JDLFFBQVEsR0FBaUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNuRCxTQUFTLEdBQVcsSUFBSSxDQUFDLENBQUMsbUNBQW1DO0lBQzdELE9BQU8sQ0FBUztJQUNoQixNQUFNLEdBQVcsQ0FBQyxDQUFDO0lBRTNCLFlBQVksT0FBZTtRQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztJQUN6QixDQUFDO0lBRUQsS0FBSyxDQUFDLFVBQVUsQ0FBQyxjQUFzQixLQUFLO1FBQzFDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSw4QkFBZSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUNoQixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7T0FFRztJQUNILFdBQVcsQ0FBQyxjQUFzQjtRQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMsdURBQXVELENBQUMsQ0FBQztRQUMzRSxDQUFDO1FBRUQsSUFBSSxjQUFjLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN6QyxPQUFPLENBQUMsb0JBQW9CO1FBQzlCLENBQUM7UUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxjQUFjLENBQUMsa0JBQTBCO1FBQ3ZDLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsa0JBQWtCLENBQUM7UUFDakUsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFMUQsSUFBSSxnQkFBZ0IsR0FBRyxlQUFlLEVBQUUsQ0FBQztZQUN2Qyw2REFBNkQ7WUFDN0QsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxHQUFHLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xGLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDaEMsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQWlEO1FBQy9ELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1FBQzNFLENBQUM7UUFFRCxvREFBb0Q7UUFDcEQsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNwRCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxJQUFJLGVBQWUsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM5QyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUVELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUV6QixrQ0FBa0M7UUFDbEMsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRS9ELE1BQU0sVUFBVSxHQUFvQjtZQUNsQyxHQUFHLE1BQU07WUFDVCxFQUFFO1lBQ0YsU0FBUztTQUNWLENBQUM7UUFFRixvQkFBb0I7UUFDcEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ25DLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUVsQyxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0lBRUQsS0FBSyxDQUFDLGFBQWEsQ0FBQyxLQUFhLEVBQUUsSUFBWSxDQUFDO1FBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1FBQzNFLENBQUM7UUFFRCxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFeEQsT0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQVUsRUFBRSxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdkQsTUFBTSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBRTtZQUM5QixLQUFLLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7U0FDNUIsQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsS0FBSyxDQUFDLGdCQUFnQixDQUFDLEtBQWEsRUFBRSxRQUFxQyxFQUFFLElBQVksQ0FBQztRQUN4RixNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN2RCxPQUFPLE9BQU87YUFDWCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUM7YUFDM0MsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNqQixDQUFDO0lBRUQsb0JBQW9CLENBQUMsYUFBcUI7UUFDeEMsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7YUFDdEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLGFBQWEsS0FBSyxhQUFhLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQsY0FBYztRQUNaLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVPLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFZO1FBQzFDLHNFQUFzRTtRQUN0RSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDL0MsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUMsQ0FBQztRQUVELE1BQU0sR0FBRyxHQUFHLElBQUEsa0JBQU0sR0FBRSxDQUFDO1FBQ3JCLE1BQU0sTUFBTSxHQUFJLEdBQVcsQ0FBQyxRQUFRLENBQUM7UUFFckMscURBQXFEO1FBQ3JELE1BQU0sTUFBTSxHQUFJLE1BQWMsQ0FBQyxNQUFNLENBQUM7UUFFdEMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztnQkFDOUMsS0FBSyxFQUFFLHdCQUF3QjtnQkFDL0IsS0FBSyxFQUFFLElBQUk7YUFDWixDQUFDLENBQUM7WUFDSCxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ3BDLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsNEZBQTRGO1lBQzVGLE9BQU8sQ0FBQyxHQUFHLENBQUMseURBQXlELENBQUMsQ0FBQztZQUN2RSxPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyxDQUFDO0lBQ0gsQ0FBQztJQUVPLHFCQUFxQixDQUFDLElBQVk7UUFDeEMsZ0VBQWdFO1FBQ2hFLG1FQUFtRTtRQUNuRSxNQUFNLFNBQVMsR0FBYSxFQUFFLENBQUM7UUFDL0IsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNyQyxJQUFJLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBRUQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUN4QyxxQ0FBcUM7WUFDckMsSUFBSSxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUksR0FBRyxLQUFLLENBQUMsR0FBRyxNQUFNLENBQUM7WUFDdEMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUI7UUFDNUQsQ0FBQztRQUVELHVCQUF1QjtRQUN2QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNFLE9BQU8sU0FBUyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsNEJBQTRCO0lBQzVCLFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDcEIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtZQUNuQixRQUFRLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQzlDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCwrQkFBK0I7SUFDL0IsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFZO1FBQ3JCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO1FBRWxELHFCQUFxQjtRQUNyQixNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN4QixLQUFLLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3pDLElBQUksTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNyQixJQUFJLENBQUMsS0FBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzdDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBOUtELGtDQThLQztBQUVELG9DQUFvQztBQUNwQyxNQUFNLE1BQU0sR0FBNkIsSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUVuRCxTQUFnQixjQUFjLENBQUMsT0FBZTtJQUM1QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUUsQ0FBQztBQUM5QixDQUFDO0FBRUQsU0FBZ0IsZ0JBQWdCLENBQUMsT0FBZTtJQUM5QyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRMTE0gfSBmcm9tICcuLi9sbG0vY2xpZW50LmpzJztcclxuaW1wb3J0IHsgSGllcmFyY2hpY2FsTlNXIH0gZnJvbSAnaG5zd2xpYi1ub2RlJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTmFycmF0aXZlTWVtb3J5IHtcclxuICBpZDogbnVtYmVyO1xyXG4gIHN0b3J5SWQ6IHN0cmluZztcclxuICBjaGFwdGVyTnVtYmVyOiBudW1iZXI7XHJcbiAgY29udGVudDogc3RyaW5nO1xyXG4gIGNhdGVnb3J5OiAnZXZlbnQnIHwgJ2NoYXJhY3RlcicgfCAnd29ybGQnIHwgJ3Bsb3QnO1xyXG4gIHRpbWVzdGFtcDogRGF0ZTtcclxuICBlbWJlZGRpbmc/OiBudW1iZXJbXTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBNZW1vcnlTZWFyY2hSZXN1bHQge1xyXG4gIG1lbW9yeTogTmFycmF0aXZlTWVtb3J5O1xyXG4gIHNjb3JlOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBWZWN0b3JTdG9yZSB7XHJcbiAgcHJpdmF0ZSBpbmRleDogSGllcmFyY2hpY2FsTlNXIHwgbnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSBtZW1vcmllczogTWFwPG51bWJlciwgTmFycmF0aXZlTWVtb3J5PiA9IG5ldyBNYXAoKTtcclxuICBwcml2YXRlIGRpbWVuc2lvbjogbnVtYmVyID0gMTUzNjsgLy8gdGV4dC1lbWJlZGRpbmctMy1zbWFsbCBkaW1lbnNpb25cclxuICBwcml2YXRlIHN0b3J5SWQ6IHN0cmluZztcclxuICBwcml2YXRlIG5leHRJZDogbnVtYmVyID0gMDtcclxuXHJcbiAgY29uc3RydWN0b3Ioc3RvcnlJZDogc3RyaW5nKSB7XHJcbiAgICB0aGlzLnN0b3J5SWQgPSBzdG9yeUlkO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgaW5pdGlhbGl6ZShtYXhFbGVtZW50czogbnVtYmVyID0gMTAwMDApOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHRoaXMuaW5kZXggPSBuZXcgSGllcmFyY2hpY2FsTlNXKCdjb3NpbmUnLCB0aGlzLmRpbWVuc2lvbik7XHJcbiAgICB0aGlzLmluZGV4LmluaXRJbmRleChtYXhFbGVtZW50cywgMTYsIDIwMCk7XHJcbiAgICB0aGlzLm5leHRJZCA9IDA7XHJcbiAgICB0aGlzLm1lbW9yaWVzLmNsZWFyKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXNpemUgdGhlIGluZGV4IHRvIGFjY29tbW9kYXRlIG1vcmUgbWVtb3JpZXNcclxuICAgKi9cclxuICByZXNpemVJbmRleChuZXdNYXhFbGVtZW50czogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuaW5kZXgpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWZWN0b3JTdG9yZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdGlhbGl6ZSgpIGZpcnN0LicpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBpZiAobmV3TWF4RWxlbWVudHMgPD0gdGhpcy5tZW1vcmllcy5zaXplKSB7XHJcbiAgICAgIHJldHVybjsgLy8gTm8gbmVlZCB0byByZXNpemVcclxuICAgIH1cclxuICAgIFxyXG4gICAgdGhpcy5pbmRleC5yZXNpemVJbmRleChuZXdNYXhFbGVtZW50cyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFbnN1cmUgY2FwYWNpdHkgZm9yIHVwY29taW5nIG1lbW9yaWVzXHJcbiAgICovXHJcbiAgZW5zdXJlQ2FwYWNpdHkoYWRkaXRpb25hbE1lbW9yaWVzOiBudW1iZXIpOiB2b2lkIHtcclxuICAgIGNvbnN0IHJlcXVpcmVkQ2FwYWNpdHkgPSB0aGlzLm1lbW9yaWVzLnNpemUgKyBhZGRpdGlvbmFsTWVtb3JpZXM7XHJcbiAgICBjb25zdCBjdXJyZW50Q2FwYWNpdHkgPSB0aGlzLmluZGV4Py5nZXRNYXhFbGVtZW50cygpIHx8IDA7XHJcbiAgICBcclxuICAgIGlmIChyZXF1aXJlZENhcGFjaXR5ID4gY3VycmVudENhcGFjaXR5KSB7XHJcbiAgICAgIC8vIEFkZCA1MCUgbW9yZSBjYXBhY2l0eSBvciB1c2UgcmVxdWlyZWQsIHdoaWNoZXZlciBpcyBsYXJnZXJcclxuICAgICAgY29uc3QgbmV3Q2FwYWNpdHkgPSBNYXRoLm1heChNYXRoLmZsb29yKGN1cnJlbnRDYXBhY2l0eSAqIDEuNSksIHJlcXVpcmVkQ2FwYWNpdHkpO1xyXG4gICAgICB0aGlzLnJlc2l6ZUluZGV4KG5ld0NhcGFjaXR5KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGFzeW5jIGFkZE1lbW9yeShtZW1vcnk6IE9taXQ8TmFycmF0aXZlTWVtb3J5LCAnaWQnIHwgJ2VtYmVkZGluZyc+KTogUHJvbWlzZTxOYXJyYXRpdmVNZW1vcnk+IHtcclxuICAgIGlmICghdGhpcy5pbmRleCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1ZlY3RvclN0b3JlIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0aWFsaXplKCkgZmlyc3QuJyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQXV0by1yZXNpemUgaWYgd2UncmUgbmVhciBjYXBhY2l0eSAoYWRkIDUwJSBtb3JlKVxyXG4gICAgY29uc3QgY3VycmVudENhcGFjaXR5ID0gdGhpcy5pbmRleC5nZXRNYXhFbGVtZW50cygpO1xyXG4gICAgaWYgKHRoaXMubWVtb3JpZXMuc2l6ZSA+PSBjdXJyZW50Q2FwYWNpdHkgLSAxKSB7XHJcbiAgICAgIHRoaXMucmVzaXplSW5kZXgoTWF0aC5mbG9vcihjdXJyZW50Q2FwYWNpdHkgKiAxLjUpKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBpZCA9IHRoaXMubmV4dElkKys7XHJcbiAgICBcclxuICAgIC8vIEdlbmVyYXRlIGVtYmVkZGluZyB1c2luZyBPcGVuQUlcclxuICAgIGNvbnN0IGVtYmVkZGluZyA9IGF3YWl0IHRoaXMuZ2VuZXJhdGVFbWJlZGRpbmcobWVtb3J5LmNvbnRlbnQpO1xyXG4gICAgXHJcbiAgICBjb25zdCBmdWxsTWVtb3J5OiBOYXJyYXRpdmVNZW1vcnkgPSB7XHJcbiAgICAgIC4uLm1lbW9yeSxcclxuICAgICAgaWQsXHJcbiAgICAgIGVtYmVkZGluZyxcclxuICAgIH07XHJcblxyXG4gICAgLy8gQWRkIHRvIEhOU1cgaW5kZXhcclxuICAgIHRoaXMuaW5kZXguYWRkUG9pbnQoZW1iZWRkaW5nLCBpZCk7XHJcbiAgICB0aGlzLm1lbW9yaWVzLnNldChpZCwgZnVsbE1lbW9yeSk7XHJcblxyXG4gICAgcmV0dXJuIGZ1bGxNZW1vcnk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBzZWFyY2hTaW1pbGFyKHF1ZXJ5OiBzdHJpbmcsIGs6IG51bWJlciA9IDUpOiBQcm9taXNlPE1lbW9yeVNlYXJjaFJlc3VsdFtdPiB7XHJcbiAgICBpZiAoIXRoaXMuaW5kZXgpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdWZWN0b3JTdG9yZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdGlhbGl6ZSgpIGZpcnN0LicpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHF1ZXJ5RW1iZWRkaW5nID0gYXdhaXQgdGhpcy5nZW5lcmF0ZUVtYmVkZGluZyhxdWVyeSk7XHJcbiAgICBjb25zdCByZXN1bHRzID0gdGhpcy5pbmRleC5zZWFyY2hLbm4ocXVlcnlFbWJlZGRpbmcsIGspO1xyXG5cclxuICAgIHJldHVybiByZXN1bHRzLm5laWdoYm9ycy5tYXAoKGlkOiBudW1iZXIsIGk6IG51bWJlcikgPT4gKHtcclxuICAgICAgbWVtb3J5OiB0aGlzLm1lbW9yaWVzLmdldChpZCkhLFxyXG4gICAgICBzY29yZTogcmVzdWx0cy5kaXN0YW5jZXNbaV0sXHJcbiAgICB9KSk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBzZWFyY2hCeUNhdGVnb3J5KHF1ZXJ5OiBzdHJpbmcsIGNhdGVnb3J5OiBOYXJyYXRpdmVNZW1vcnlbJ2NhdGVnb3J5J10sIGs6IG51bWJlciA9IDUpOiBQcm9taXNlPE1lbW9yeVNlYXJjaFJlc3VsdFtdPiB7XHJcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5zZWFyY2hTaW1pbGFyKHF1ZXJ5LCBrICogMik7XHJcbiAgICByZXR1cm4gcmVzdWx0c1xyXG4gICAgICAuZmlsdGVyKHIgPT4gci5tZW1vcnkuY2F0ZWdvcnkgPT09IGNhdGVnb3J5KVxyXG4gICAgICAuc2xpY2UoMCwgayk7XHJcbiAgfVxyXG5cclxuICBnZXRNZW1vcmllc0J5Q2hhcHRlcihjaGFwdGVyTnVtYmVyOiBudW1iZXIpOiBOYXJyYXRpdmVNZW1vcnlbXSB7XHJcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLm1lbW9yaWVzLnZhbHVlcygpKVxyXG4gICAgICAuZmlsdGVyKG0gPT4gbS5jaGFwdGVyTnVtYmVyID09PSBjaGFwdGVyTnVtYmVyKTtcclxuICB9XHJcblxyXG4gIGdldEFsbE1lbW9yaWVzKCk6IE5hcnJhdGl2ZU1lbW9yeVtdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMubWVtb3JpZXMudmFsdWVzKCkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBnZW5lcmF0ZUVtYmVkZGluZyh0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcltdPiB7XHJcbiAgICAvLyBDaGVjayBpZiB3ZSBzaG91bGQgdXNlIG1vY2sgZW1iZWRkaW5ncyAoZm9yIHRlc3Rpbmcgd2l0aG91dCBPcGVuQUkpXHJcbiAgICBpZiAocHJvY2Vzcy5lbnYuVVNFX01PQ0tfRU1CRURESU5HUyA9PT0gJ3RydWUnKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmdlbmVyYXRlTW9ja0VtYmVkZGluZyh0ZXh0KTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBsbG0gPSBnZXRMTE0oKTtcclxuICAgIGNvbnN0IG9wZW5haSA9IChsbG0gYXMgYW55KS5wcm92aWRlcjtcclxuICAgIFxyXG4gICAgLy8gQWNjZXNzIHRoZSB1bmRlcmx5aW5nIE9wZW5BSSBjbGllbnQgZm9yIGVtYmVkZGluZ3NcclxuICAgIGNvbnN0IGNsaWVudCA9IChvcGVuYWkgYXMgYW55KS5jbGllbnQ7XHJcbiAgICBcclxuICAgIHRyeSB7XHJcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LmVtYmVkZGluZ3MuY3JlYXRlKHtcclxuICAgICAgICBtb2RlbDogJ3RleHQtZW1iZWRkaW5nLTMtc21hbGwnLFxyXG4gICAgICAgIGlucHV0OiB0ZXh0LFxyXG4gICAgICB9KTtcclxuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGFbMF0uZW1iZWRkaW5nO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgLy8gRmFsbCBiYWNrIHRvIG1vY2sgZW1iZWRkaW5ncyBpZiB0aGUgQVBJIGZhaWxzIChlLmcuLCBEZWVwU2VlayBkb2Vzbid0IHN1cHBvcnQgZW1iZWRkaW5ncylcclxuICAgICAgY29uc29sZS5sb2coJyAgW1ZlY3RvclN0b3JlXSBVc2luZyBtb2NrIGVtYmVkZGluZ3MgKEFQSSB1bmF2YWlsYWJsZSknKTtcclxuICAgICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVNb2NrRW1iZWRkaW5nKHRleHQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZW5lcmF0ZU1vY2tFbWJlZGRpbmcodGV4dDogc3RyaW5nKTogbnVtYmVyW10ge1xyXG4gICAgLy8gR2VuZXJhdGUgYSBkZXRlcm1pbmlzdGljIG1vY2sgZW1iZWRkaW5nIGJhc2VkIG9uIHRleHQgY29udGVudFxyXG4gICAgLy8gVGhpcyBpcyBOT1QgZm9yIHByb2R1Y3Rpb24gLSBqdXN0IGZvciB0ZXN0aW5nIHdpdGhvdXQgT3BlbkFJIEFQSVxyXG4gICAgY29uc3QgZW1iZWRkaW5nOiBudW1iZXJbXSA9IFtdO1xyXG4gICAgbGV0IHNlZWQgPSAwO1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgIHNlZWQgKz0gdGV4dC5jaGFyQ29kZUF0KGkpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGltZW5zaW9uOyBpKyspIHtcclxuICAgICAgLy8gU2ltcGxlIHBzZXVkby1yYW5kb20gYmFzZWQgb24gc2VlZFxyXG4gICAgICBzZWVkID0gKHNlZWQgKiA5MzAxICsgNDkyOTcpICUgMjMzMjgwO1xyXG4gICAgICBlbWJlZGRpbmcucHVzaCgoc2VlZCAvIDIzMzI4MCkgKiAyIC0gMSk7IC8vIFJhbmdlOiAtMSB0byAxXHJcbiAgICB9XHJcbiAgICBcclxuICAgIC8vIE5vcm1hbGl6ZSB0aGUgdmVjdG9yXHJcbiAgICBjb25zdCBub3JtID0gTWF0aC5zcXJ0KGVtYmVkZGluZy5yZWR1Y2UoKHN1bSwgdmFsKSA9PiBzdW0gKyB2YWwgKiB2YWwsIDApKTtcclxuICAgIHJldHVybiBlbWJlZGRpbmcubWFwKHZhbCA9PiB2YWwgLyBub3JtKTtcclxuICB9XHJcblxyXG4gIC8vIFNlcmlhbGl6ZSBmb3IgcGVyc2lzdGVuY2VcclxuICBzZXJpYWxpemUoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7XHJcbiAgICAgIHN0b3J5SWQ6IHRoaXMuc3RvcnlJZCxcclxuICAgICAgbmV4dElkOiB0aGlzLm5leHRJZCxcclxuICAgICAgbWVtb3JpZXM6IEFycmF5LmZyb20odGhpcy5tZW1vcmllcy5lbnRyaWVzKCkpLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyBEZXNlcmlhbGl6ZSBmcm9tIHNhdmVkIHN0YXRlXHJcbiAgYXN5bmMgbG9hZChkYXRhOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoZGF0YSk7XHJcbiAgICB0aGlzLm1lbW9yaWVzID0gbmV3IE1hcChwYXJzZWQubWVtb3JpZXMpO1xyXG4gICAgdGhpcy5uZXh0SWQgPSBwYXJzZWQubmV4dElkIHx8IHRoaXMubWVtb3JpZXMuc2l6ZTtcclxuICAgIFxyXG4gICAgLy8gUmVidWlsZCBITlNXIGluZGV4XHJcbiAgICBhd2FpdCB0aGlzLmluaXRpYWxpemUoKTtcclxuICAgIGZvciAoY29uc3QgW2lkLCBtZW1vcnldIG9mIHRoaXMubWVtb3JpZXMpIHtcclxuICAgICAgaWYgKG1lbW9yeS5lbWJlZGRpbmcpIHtcclxuICAgICAgICB0aGlzLmluZGV4IS5hZGRQb2ludChtZW1vcnkuZW1iZWRkaW5nLCBpZCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbi8vIEZhY3RvcnkgZm9yIHN0b3J5LXNwZWNpZmljIHN0b3Jlc1xyXG5jb25zdCBzdG9yZXM6IE1hcDxzdHJpbmcsIFZlY3RvclN0b3JlPiA9IG5ldyBNYXAoKTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRWZWN0b3JTdG9yZShzdG9yeUlkOiBzdHJpbmcpOiBWZWN0b3JTdG9yZSB7XHJcbiAgaWYgKCFzdG9yZXMuaGFzKHN0b3J5SWQpKSB7XHJcbiAgICBzdG9yZXMuc2V0KHN0b3J5SWQsIG5ldyBWZWN0b3JTdG9yZShzdG9yeUlkKSk7XHJcbiAgfVxyXG4gIHJldHVybiBzdG9yZXMuZ2V0KHN0b3J5SWQpITtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyVmVjdG9yU3RvcmUoc3RvcnlJZDogc3RyaW5nKTogdm9pZCB7XHJcbiAgc3RvcmVzLmRlbGV0ZShzdG9yeUlkKTtcclxufVxyXG4iXX0=
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { GenerationContext, Chapter, ChapterSummary } from '../types/index.js';
|
|
2
|
+
import type { CanonStore } from '../memory/canonStore.js';
|
|
3
|
+
import type { VectorStore } from '../memory/vectorStore.js';
|
|
4
|
+
export interface GenerateChapterResult {
|
|
5
|
+
chapter: Chapter;
|
|
6
|
+
summary: ChapterSummary;
|
|
7
|
+
violations: string[];
|
|
8
|
+
memoriesExtracted: number;
|
|
9
|
+
}
|
|
10
|
+
export interface GenerateChapterOptions {
|
|
11
|
+
canon?: CanonStore;
|
|
12
|
+
vectorStore?: VectorStore;
|
|
13
|
+
validateCanon?: boolean;
|
|
14
|
+
maxContinuationAttempts?: number;
|
|
15
|
+
retrieveMemories?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function generateChapter(context: GenerationContext, options?: GenerateChapterOptions): Promise<GenerateChapterResult>;
|