@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,381 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConstraintGraph = void 0;
|
|
4
|
+
exports.createConstraintGraph = createConstraintGraph;
|
|
5
|
+
class ConstraintGraph {
|
|
6
|
+
nodes = new Map();
|
|
7
|
+
edges = new Map();
|
|
8
|
+
adjacencyList = new Map();
|
|
9
|
+
/**
|
|
10
|
+
* Add a node to the graph
|
|
11
|
+
*/
|
|
12
|
+
addNode(node) {
|
|
13
|
+
this.nodes.set(node.id, node);
|
|
14
|
+
if (!this.adjacencyList.has(node.id)) {
|
|
15
|
+
this.adjacencyList.set(node.id, new Set());
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Add an edge between nodes
|
|
20
|
+
*/
|
|
21
|
+
addEdge(edge) {
|
|
22
|
+
// Validate nodes exist
|
|
23
|
+
if (!this.nodes.has(edge.from) || !this.nodes.has(edge.to)) {
|
|
24
|
+
throw new Error(`Cannot add edge: node not found (${edge.from} -> ${edge.to})`);
|
|
25
|
+
}
|
|
26
|
+
this.edges.set(edge.id, edge);
|
|
27
|
+
// Update adjacency list
|
|
28
|
+
const fromSet = this.adjacencyList.get(edge.from);
|
|
29
|
+
if (fromSet) {
|
|
30
|
+
fromSet.add(edge.to);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get a node by ID
|
|
35
|
+
*/
|
|
36
|
+
getNode(id) {
|
|
37
|
+
return this.nodes.get(id);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get all edges from a node
|
|
41
|
+
*/
|
|
42
|
+
getEdgesFrom(nodeId) {
|
|
43
|
+
return Array.from(this.edges.values()).filter(e => e.from === nodeId);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get all edges to a node
|
|
47
|
+
*/
|
|
48
|
+
getEdgesTo(nodeId) {
|
|
49
|
+
return Array.from(this.edges.values()).filter(e => e.to === nodeId);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get neighbors of a node
|
|
53
|
+
*/
|
|
54
|
+
getNeighbors(nodeId) {
|
|
55
|
+
const neighborIds = this.adjacencyList.get(nodeId);
|
|
56
|
+
if (!neighborIds)
|
|
57
|
+
return [];
|
|
58
|
+
return Array.from(neighborIds)
|
|
59
|
+
.map(id => this.nodes.get(id))
|
|
60
|
+
.filter((n) => n !== undefined);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Add character to graph
|
|
64
|
+
*/
|
|
65
|
+
addCharacter(character, chapter) {
|
|
66
|
+
const charNode = {
|
|
67
|
+
id: `char-${character.name}`,
|
|
68
|
+
type: 'character',
|
|
69
|
+
label: character.name,
|
|
70
|
+
properties: {
|
|
71
|
+
emotionalState: character.emotionalState,
|
|
72
|
+
location: character.location,
|
|
73
|
+
goals: character.goals,
|
|
74
|
+
},
|
|
75
|
+
chapterEstablished: chapter,
|
|
76
|
+
};
|
|
77
|
+
this.addNode(charNode);
|
|
78
|
+
// Add location edge
|
|
79
|
+
this.addEdge({
|
|
80
|
+
id: `edge-${character.name}-loc`,
|
|
81
|
+
from: charNode.id,
|
|
82
|
+
to: `loc-${character.location}`,
|
|
83
|
+
type: 'located_at',
|
|
84
|
+
properties: { since: chapter },
|
|
85
|
+
});
|
|
86
|
+
// Add knowledge nodes and edges
|
|
87
|
+
for (const knowledge of character.knowledge) {
|
|
88
|
+
const factId = `fact-${this.sanitizeId(knowledge)}`;
|
|
89
|
+
if (!this.nodes.has(factId)) {
|
|
90
|
+
this.addNode({
|
|
91
|
+
id: factId,
|
|
92
|
+
type: 'fact',
|
|
93
|
+
label: knowledge,
|
|
94
|
+
properties: {},
|
|
95
|
+
chapterEstablished: chapter,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
this.addEdge({
|
|
99
|
+
id: `edge-${character.name}-knows-${factId}`,
|
|
100
|
+
from: charNode.id,
|
|
101
|
+
to: factId,
|
|
102
|
+
type: 'knows',
|
|
103
|
+
properties: { since: chapter },
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Add location to graph
|
|
109
|
+
*/
|
|
110
|
+
addLocation(name, description, chapter) {
|
|
111
|
+
const locNode = {
|
|
112
|
+
id: `loc-${name}`,
|
|
113
|
+
type: 'location',
|
|
114
|
+
label: name,
|
|
115
|
+
properties: { description },
|
|
116
|
+
chapterEstablished: chapter,
|
|
117
|
+
};
|
|
118
|
+
this.addNode(locNode);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Add event to graph
|
|
122
|
+
*/
|
|
123
|
+
addEvent(id, description, participants, chapter) {
|
|
124
|
+
const eventNode = {
|
|
125
|
+
id: `event-${id}`,
|
|
126
|
+
type: 'event',
|
|
127
|
+
label: description,
|
|
128
|
+
properties: { participants },
|
|
129
|
+
chapterEstablished: chapter,
|
|
130
|
+
};
|
|
131
|
+
this.addNode(eventNode);
|
|
132
|
+
// Connect participants to event
|
|
133
|
+
for (const participant of participants) {
|
|
134
|
+
const charId = `char-${participant}`;
|
|
135
|
+
if (this.nodes.has(charId)) {
|
|
136
|
+
this.addEdge({
|
|
137
|
+
id: `edge-${participant}-participates-${id}`,
|
|
138
|
+
from: charId,
|
|
139
|
+
to: eventNode.id,
|
|
140
|
+
type: 'participates_in',
|
|
141
|
+
properties: { chapter },
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Update character location
|
|
148
|
+
*/
|
|
149
|
+
updateCharacterLocation(characterName, newLocation, chapter) {
|
|
150
|
+
const charId = `char-${characterName}`;
|
|
151
|
+
const charNode = this.nodes.get(charId);
|
|
152
|
+
if (charNode) {
|
|
153
|
+
// Update properties
|
|
154
|
+
charNode.properties.location = newLocation;
|
|
155
|
+
// Remove old location edges
|
|
156
|
+
const oldEdges = this.getEdgesFrom(charId).filter(e => e.type === 'located_at');
|
|
157
|
+
for (const edge of oldEdges) {
|
|
158
|
+
this.edges.delete(edge.id);
|
|
159
|
+
const adjSet = this.adjacencyList.get(edge.from);
|
|
160
|
+
if (adjSet) {
|
|
161
|
+
adjSet.delete(edge.to);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Add new location edge
|
|
165
|
+
this.addEdge({
|
|
166
|
+
id: `edge-${characterName}-loc-${chapter}`,
|
|
167
|
+
from: charId,
|
|
168
|
+
to: `loc-${newLocation}`,
|
|
169
|
+
type: 'located_at',
|
|
170
|
+
properties: { since: chapter },
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Check for constraint violations
|
|
176
|
+
*/
|
|
177
|
+
checkConstraints(currentChapter) {
|
|
178
|
+
const violations = [];
|
|
179
|
+
// Check location consistency
|
|
180
|
+
violations.push(...this.checkLocationConsistency(currentChapter));
|
|
181
|
+
// Check knowledge consistency
|
|
182
|
+
violations.push(...this.checkKnowledgeConsistency(currentChapter));
|
|
183
|
+
// Check timeline consistency
|
|
184
|
+
violations.push(...this.checkTimelineConsistency(currentChapter));
|
|
185
|
+
// Check logical consistency
|
|
186
|
+
violations.push(...this.checkLogicalConsistency(currentChapter));
|
|
187
|
+
return violations;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Check location consistency (no teleporting)
|
|
191
|
+
*/
|
|
192
|
+
checkLocationConsistency(currentChapter) {
|
|
193
|
+
const violations = [];
|
|
194
|
+
for (const node of this.nodes.values()) {
|
|
195
|
+
if (node.type === 'character') {
|
|
196
|
+
const locationEdges = this.getEdgesFrom(node.id).filter(e => e.type === 'located_at');
|
|
197
|
+
// Sort by chapter
|
|
198
|
+
const sortedEdges = locationEdges.sort((a, b) => (a.properties.since || 0) - (b.properties.since || 0));
|
|
199
|
+
// Check for impossible movements (simplified)
|
|
200
|
+
// In a real implementation, you'd check travel times between locations
|
|
201
|
+
for (let i = 1; i < sortedEdges.length; i++) {
|
|
202
|
+
const prevEdge = sortedEdges[i - 1];
|
|
203
|
+
const currEdge = sortedEdges[i];
|
|
204
|
+
const timeDiff = (currEdge.properties.since || 0) - (prevEdge.properties.since || 0);
|
|
205
|
+
// If moved in same chapter, might be suspicious
|
|
206
|
+
if (timeDiff === 0 && currEdge.properties.since === currentChapter) {
|
|
207
|
+
violations.push({
|
|
208
|
+
type: 'location',
|
|
209
|
+
severity: 'warning',
|
|
210
|
+
description: `${node.label} moved from ${prevEdge.to} to ${currEdge.to} instantly`,
|
|
211
|
+
nodes: [node.id],
|
|
212
|
+
suggestedFix: 'Add travel scene or justify rapid movement',
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return violations;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Check knowledge consistency (no impossible knowledge)
|
|
222
|
+
*/
|
|
223
|
+
checkKnowledgeConsistency(currentChapter) {
|
|
224
|
+
const violations = [];
|
|
225
|
+
for (const node of this.nodes.values()) {
|
|
226
|
+
if (node.type === 'character') {
|
|
227
|
+
const knowledgeEdges = this.getEdgesFrom(node.id).filter(e => e.type === 'knows');
|
|
228
|
+
for (const edge of knowledgeEdges) {
|
|
229
|
+
const factNode = this.nodes.get(edge.to);
|
|
230
|
+
if (factNode && factNode.chapterEstablished) {
|
|
231
|
+
const knownSince = edge.properties.since || currentChapter;
|
|
232
|
+
// Check if character knew fact before it was established
|
|
233
|
+
if (knownSince < factNode.chapterEstablished) {
|
|
234
|
+
violations.push({
|
|
235
|
+
type: 'knowledge',
|
|
236
|
+
severity: 'error',
|
|
237
|
+
description: `${node.label} knows "${factNode.label}" before it happened (Ch ${knownSince} vs Ch ${factNode.chapterEstablished})`,
|
|
238
|
+
nodes: [node.id, factNode.id],
|
|
239
|
+
suggestedFix: 'Remove knowledge or adjust timeline',
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return violations;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Check timeline consistency
|
|
250
|
+
*/
|
|
251
|
+
checkTimelineConsistency(currentChapter) {
|
|
252
|
+
const violations = [];
|
|
253
|
+
// Check for events that reference future chapters
|
|
254
|
+
for (const node of this.nodes.values()) {
|
|
255
|
+
if (node.type === 'event' && node.chapterEstablished) {
|
|
256
|
+
if (node.chapterEstablished > currentChapter) {
|
|
257
|
+
violations.push({
|
|
258
|
+
type: 'timeline',
|
|
259
|
+
severity: 'error',
|
|
260
|
+
description: `Event "${node.label}" is set in future chapter ${node.chapterEstablished} but we're in chapter ${currentChapter}`,
|
|
261
|
+
nodes: [node.id],
|
|
262
|
+
suggestedFix: 'Adjust event chapter or remove reference',
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return violations;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Check logical consistency
|
|
271
|
+
*/
|
|
272
|
+
checkLogicalConsistency(currentChapter) {
|
|
273
|
+
const violations = [];
|
|
274
|
+
// Check for characters participating in events when not present
|
|
275
|
+
for (const node of this.nodes.values()) {
|
|
276
|
+
if (node.type === 'event') {
|
|
277
|
+
const participants = node.properties.participants || [];
|
|
278
|
+
for (const participant of participants) {
|
|
279
|
+
const charId = `char-${participant}`;
|
|
280
|
+
const charNode = this.nodes.get(charId);
|
|
281
|
+
if (charNode) {
|
|
282
|
+
// Check if character was alive/present at event time
|
|
283
|
+
if (charNode.chapterEstablished && node.chapterEstablished) {
|
|
284
|
+
if (charNode.chapterEstablished > node.chapterEstablished) {
|
|
285
|
+
violations.push({
|
|
286
|
+
type: 'logic',
|
|
287
|
+
severity: 'error',
|
|
288
|
+
description: `${participant} participates in event before they were introduced`,
|
|
289
|
+
nodes: [charId, node.id],
|
|
290
|
+
suggestedFix: 'Adjust character introduction or event timing',
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return violations;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Query what a character knows
|
|
302
|
+
*/
|
|
303
|
+
getCharacterKnowledge(characterName) {
|
|
304
|
+
const charId = `char-${characterName}`;
|
|
305
|
+
const knowledgeEdges = this.getEdgesFrom(charId).filter(e => e.type === 'knows');
|
|
306
|
+
return knowledgeEdges
|
|
307
|
+
.map(edge => this.nodes.get(edge.to))
|
|
308
|
+
.filter((n) => n !== undefined && n.type === 'fact');
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Query where a character is
|
|
312
|
+
*/
|
|
313
|
+
getCharacterLocation(characterName) {
|
|
314
|
+
const charId = `char-${characterName}`;
|
|
315
|
+
const locationEdge = this.getEdgesFrom(charId).find(e => e.type === 'located_at');
|
|
316
|
+
if (locationEdge) {
|
|
317
|
+
const locNode = this.nodes.get(locationEdge.to);
|
|
318
|
+
return locNode?.label;
|
|
319
|
+
}
|
|
320
|
+
return undefined;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Serialize graph
|
|
324
|
+
*/
|
|
325
|
+
serialize() {
|
|
326
|
+
return JSON.stringify({
|
|
327
|
+
nodes: Array.from(this.nodes.entries()),
|
|
328
|
+
edges: Array.from(this.edges.entries()),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Load graph from serialized data
|
|
333
|
+
*/
|
|
334
|
+
load(data) {
|
|
335
|
+
const parsed = JSON.parse(data);
|
|
336
|
+
this.nodes = new Map(parsed.nodes);
|
|
337
|
+
this.edges = new Map(parsed.edges);
|
|
338
|
+
// Rebuild adjacency list
|
|
339
|
+
this.adjacencyList = new Map();
|
|
340
|
+
for (const [id, node] of this.nodes) {
|
|
341
|
+
this.adjacencyList.set(id, new Set());
|
|
342
|
+
}
|
|
343
|
+
for (const edge of this.edges.values()) {
|
|
344
|
+
const set = this.adjacencyList.get(edge.from);
|
|
345
|
+
if (set) {
|
|
346
|
+
set.add(edge.to);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Get graph statistics
|
|
352
|
+
*/
|
|
353
|
+
getStats() {
|
|
354
|
+
const byType = {
|
|
355
|
+
character: 0,
|
|
356
|
+
location: 0,
|
|
357
|
+
fact: 0,
|
|
358
|
+
event: 0,
|
|
359
|
+
item: 0,
|
|
360
|
+
};
|
|
361
|
+
for (const node of this.nodes.values()) {
|
|
362
|
+
byType[node.type]++;
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
nodes: this.nodes.size,
|
|
366
|
+
edges: this.edges.size,
|
|
367
|
+
byType,
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Sanitize string for use as ID
|
|
372
|
+
*/
|
|
373
|
+
sanitizeId(str) {
|
|
374
|
+
return str.replace(/[^a-zA-Z0-9]/g, '_').substring(0, 50);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
exports.ConstraintGraph = ConstraintGraph;
|
|
378
|
+
function createConstraintGraph() {
|
|
379
|
+
return new ConstraintGraph();
|
|
380
|
+
}
|
|
381
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RyYWludEdyYXBoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbnN0cmFpbnRzL2NvbnN0cmFpbnRHcmFwaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFtZEEsc0RBRUM7QUF6YkQsTUFBYSxlQUFlO0lBQ2xCLEtBQUssR0FBZ0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUMvQyxLQUFLLEdBQWdDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDL0MsYUFBYSxHQUE2QixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBRTVEOztPQUVHO0lBQ0gsT0FBTyxDQUFDLElBQW9CO1FBQzFCLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxPQUFPLENBQUMsSUFBb0I7UUFDMUIsdUJBQXVCO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUMzRCxNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxJQUFJLENBQUMsSUFBSSxPQUFPLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2xGLENBQUM7UUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxD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dkMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3RCLENBQUM7UUFFRCxPQUFPO1lBQ0wsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTtZQUN0QixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJO1lBQ3RCLE1BQU07U0FDUCxDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0ssVUFBVSxDQUFDLEdBQVc7UUFDNUIsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzVELENBQUM7Q0FDRjtBQXJiRCwwQ0FxYkM7QUFFRCxTQUFnQixxQkFBcUI7SUFDbkMsT0FBTyxJQUFJLGVBQWUsRUFBRSxDQUFDO0FBQy9CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IENoYXJhY3RlclN0YXRlIH0gZnJvbSAnLi4vc3Rvcnkvc3RydWN0dXJlZFN0YXRlLmpzJztcclxuXHJcbmV4cG9ydCB0eXBlIE5vZGVUeXBlID0gJ2NoYXJhY3RlcicgfCAnbG9jYXRpb24nIHwgJ2ZhY3QnIHwgJ2V2ZW50JyB8ICdpdGVtJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQ29uc3RyYWludE5vZGUge1xyXG4gIGlkOiBzdHJpbmc7XHJcbiAgdHlwZTogTm9kZVR5cGU7XHJcbiAgbGFiZWw6IHN0cmluZztcclxuICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xyXG4gIGNoYXB0ZXJFc3RhYmxpc2hlZD86IG51bWJlcjtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDb25zdHJhaW50RWRnZSB7XHJcbiAgaWQ6IHN0cmluZztcclxuICBmcm9tOiBzdHJpbmc7XHJcbiAgdG86IHN0cmluZztcclxuICB0eXBlOiBzdHJpbmc7XHJcbiAgcHJvcGVydGllczogUmVjb3JkPHN0cmluZywgYW55PjtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDb25zdHJhaW50VmlvbGF0aW9uIHtcclxuICB0eXBlOiAnY2Fub24nIHwgJ2xvY2F0aW9uJyB8ICdrbm93bGVkZ2UnIHwgJ3RpbWVsaW5lJyB8ICdsb2dpYyc7XHJcbiAgc2V2ZXJpdHk6ICdlcnJvcicgfCAnd2FybmluZyc7XHJcbiAgZGVzY3JpcHRpb246IHN0cmluZztcclxuICBub2Rlczogc3RyaW5nW107XHJcbiAgc3VnZ2VzdGVkRml4Pzogc3RyaW5nO1xyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgQ29uc3RyYWludEdyYXBoIHtcclxuICBwcml2YXRlIG5vZGVzOiBNYXA8c3RyaW5nLCBDb25zdHJhaW50Tm9kZT4gPSBuZXcgTWFwKCk7XHJcbiAgcHJpdmF0ZSBlZGdlczogTWFwPHN0cmluZywgQ29uc3RyYWludEVkZ2U+ID0gbmV3IE1hcCgpO1xyXG4gIHByaXZhdGUgYWRqYWNlbmN5TGlzdDogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+ID0gbmV3IE1hcCgpO1xyXG4gIFxyXG4gIC8qKlxyXG4gICAqIEFkZCBhIG5vZGUgdG8gdGhlIGdyYXBoXHJcbiAgICovXHJcbiAgYWRkTm9kZShub2RlOiBDb25zdHJhaW50Tm9kZSk6IHZvaWQge1xyXG4gICAgdGhpcy5ub2Rlcy5zZXQobm9kZS5pZCwgbm9kZSk7XHJcbiAgICBpZiAoIXRoaXMuYWRqYWNlbmN5TGlzdC5oYXMobm9kZS5pZCkpIHtcclxuICAgICAgdGhpcy5hZGphY2VuY3lMaXN0LnNldChub2RlLmlkLCBuZXcgU2V0KCkpO1xyXG4gICAgfVxyXG4gIH1cclxuICBcclxuICAvKipcclxuICAgKiBBZGQgYW4gZWRnZSBiZXR3ZWVuIG5vZGVzXHJcbiAgICovXHJcbiAgYWRkRWRnZShlZGdlOiBDb25zdHJhaW50RWRnZSk6IHZvaWQge1xyXG4gICAgLy8gVmFsaWRhdGUgbm9kZXMgZXhpc3RcclxuICAgIGlmICghdGhpcy5ub2Rlcy5oYXMoZWRnZS5mcm9tKSB8fCAhdGhpcy5ub2Rlcy5oYXMoZWRnZS50bykpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgYWRkIGVkZ2U6IG5vZGUgbm90IGZvdW5kICgke2VkZ2UuZnJvbX0gLT4gJHtlZGdlLnRvfSlgKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgdGhpcy5lZGdlcy5zZXQoZWRnZS5pZCwgZWRnZSk7XHJcbiAgICBcclxuICAgIC8vIFVwZGF0ZSBhZGphY2VuY3kgbGlzdFxyXG4gICAgY29uc3QgZnJvbVNldCA9IHRoaXMuYWRqYWNlbmN5TGlzdC5nZXQoZWRnZS5mcm9tKTtcclxuICAgIGlmIChmcm9tU2V0KSB7XHJcbiAgICAgIGZyb21TZXQuYWRkKGVkZ2UudG8pO1xyXG4gICAgfVxyXG4gIH1cclxuICBcclxuICAvKipcclxuICAgKiBHZXQgYSBub2RlIGJ5IElEXHJcbiAgICovXHJcbiAgZ2V0Tm9kZShpZDogc3RyaW5nKTogQ29uc3RyYWludE5vZGUgfCB1bmRlZmluZWQge1xyXG4gICAgcmV0dXJuIHRoaXMubm9kZXMuZ2V0KGlkKTtcclxuICB9XHJcbiAgXHJcbiAgLyoqXHJcbiAgICogR2V0IGFsbCBlZGdlcyBmcm9tIGEgbm9kZVxyXG4gICAqL1xyXG4gIGdldEVkZ2VzRnJvbShub2RlSWQ6IHN0cmluZyk6IENvbnN0cmFpbnRFZGdlW10ge1xyXG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5lZGdlcy52YWx1ZXMoKSkuZmlsdGVyKGUgPT4gZS5mcm9tID09PSBub2RlSWQpO1xyXG4gIH1cclxuICBcclxuICAvKipcclxuICAgKiBHZXQgYWxsIGVkZ2VzIHRvIGEgbm9kZVxyXG4gICAqL1xyXG4gIGdldEVkZ2VzVG8obm9kZUlkOiBzdHJpbmcpOiBDb25zdHJhaW50RWRnZVtdIHtcclxuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuZWRnZXMudmFsdWVzKCkpLmZpbHRlcihlID0+IGUudG8gPT09IG5vZGVJZCk7XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIEdldCBuZWlnaGJvcnMgb2YgYSBub2RlXHJcbiAgICovXHJcbiAgZ2V0TmVpZ2hib3JzKG5vZGVJZDogc3RyaW5nKTogQ29uc3RyYWludE5vZGVbXSB7XHJcbiAgICBjb25zdCBuZWlnaGJvcklkcyA9IHRoaXMuYWRqYWNlbmN5TGlzdC5nZXQobm9kZUlkKTtcclxuICAgIGlmICghbmVpZ2hib3JJZHMpIHJldHVybiBbXTtcclxuICAgIFxyXG4gICAgcmV0dXJuIEFycmF5LmZyb20obmVpZ2hib3JJZHMpXHJcbiAgICAgIC5tYXAoaWQgPT4gdGhpcy5ub2Rlcy5nZXQoaWQpKVxyXG4gICAgICAuZmlsdGVyKChuKTogbiBpcyBDb25zdHJhaW50Tm9kZSA9PiBuICE9PSB1bmRlZmluZWQpO1xyXG4gIH1cclxuICBcclxuICAvKipcclxuICAgKiBBZGQgY2hhcmFjdGVyIHRvIGdyYXBoXHJcbiAgICovXHJcbiAgYWRkQ2hhcmFjdGVyKGNoYXJhY3RlcjogQ2hhcmFjdGVyU3RhdGUsIGNoYXB0ZXI6IG51bWJlcik6IHZvaWQge1xyXG4gICAgY29uc3QgY2hhck5vZGU6IENvbnN0cmFpbnROb2RlID0ge1xyXG4gICAgICBpZDogYGNoYXItJHtjaGFyYWN0ZXIubmFtZX1gLFxyXG4gICAgICB0eXBlOiAnY2hhcmFjdGVyJyxcclxuICAgICAgbGFiZWw6IGNoYXJhY3Rlci5uYW1lLFxyXG4gICAgICBwcm9wZXJ0aWVzOiB7XHJcbiAgICAgICAgZW1vdGlvbmFsU3RhdGU6IGNoYXJhY3Rlci5lbW90aW9uYWxTdGF0ZSxcclxuICAgICAgICBsb2NhdGlvbjogY2hhcmFjdGVyLmxvY2F0aW9uLFxyXG4gICAgICAgIGdvYWxzOiBjaGFyYWN0ZXIuZ29hbHMsXHJcbiAgICAgIH0sXHJcbiAgICAgIGNoYXB0ZXJFc3RhYmxpc2hlZDogY2hhcHRlcixcclxuICAgIH07XHJcbiAgICBcclxuICAgIHRoaXMuYWRkTm9kZShjaGFyTm9kZSk7XHJcbiAgICBcclxuICAgIC8vIEFkZCBsb2NhdGlvbiBlZGdlXHJcbiAgICB0aGlzLmFkZEVkZ2Uoe1xyXG4gICAgICBpZDogYGVkZ2UtJHtjaGFyYWN0ZXIubmFtZX0tbG9jYCxcclxuICAgICAgZnJvbTogY2hhck5vZGUuaWQsXHJcbiAgICAgIHRvOiBgbG9jLSR7Y2hhcmFjdGVyLmxvY2F0aW9ufWAsXHJcbiAgICAgIHR5cGU6ICdsb2NhdGVkX2F0JyxcclxuICAgICAgcHJvcGVydGllczogeyBzaW5jZTogY2hhcHRlciB9LFxyXG4gICAgfSk7XHJcbiAgICBcclxuICAgIC8vIEFkZCBrbm93bGVkZ2Ugbm9kZXMgYW5kIGVkZ2VzXHJcbiAgICBmb3IgKGNvbnN0IGtub3dsZWRnZSBvZiBjaGFyYWN0ZXIua25vd2xlZGdlKSB7XHJcbiAgICAgIGNvbnN0IGZhY3RJZCA9IGBmYWN0LSR7dGhpcy5zYW5pdGl6ZUlkKGtub3dsZWRnZSl9YDtcclxuICAgICAgaWYgKCF0aGlzLm5vZGVzLmhhcyhmYWN0SWQpKSB7XHJcbiAgICAgICAgdGhpcy5hZGROb2RlKHtcclxuICAgICAgICAgIGlkOiBmYWN0SWQsXHJcbiAgICAgICAgICB0eXBlOiAnZmFjdCcsXHJcbiAgICAgICAgICBsYWJlbDoga25vd2xlZGdlLFxyXG4gICAgICAgICAgcHJvcGVydGllczoge30sXHJcbiAgICAgICAgICBjaGFwdGVyRXN0YWJsaXNoZWQ6IGNoYXB0ZXIsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgICAgXHJcbiAgICAgIHRoaXMuYWRkRWRnZSh7XHJcbiAgICAgICAgaWQ6IGBlZGdlLSR7Y2hhcmFjdGVyLm5hbWV9LWtub3dzLSR7ZmFjdElkfWAsXHJcbiAgICAgICAgZnJvbTogY2hhck5vZGUuaWQsXHJcbiAgICAgICAgdG86IGZhY3RJZCxcclxuICAgICAgICB0eXBlOiAna25vd3MnLFxyXG4gICAgICAgIHByb3BlcnRpZXM6IHsgc2luY2U6IGNoYXB0ZXIgfSxcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIEFkZCBsb2NhdGlvbiB0byBncmFwaFxyXG4gICAqL1xyXG4gIGFkZExvY2F0aW9uKG5hbWU6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZywgY2hhcHRlcjogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBjb25zdCBsb2NOb2RlOiBDb25zdHJhaW50Tm9kZSA9IHtcclxuICAgICAgaWQ6IGBsb2MtJHtuYW1lfWAsXHJcbiAgICAgIHR5cGU6ICdsb2NhdGlvbicsXHJcbiAgICAgIGxhYmVsOiBuYW1lLFxyXG4gICAgICBwcm9wZXJ0aWVzOiB7IGRlc2NyaXB0aW9uIH0sXHJcbiAgICAgIGNoYXB0ZXJFc3RhYmxpc2hlZDogY2hhcHRlcixcclxuICAgIH07XHJcbiAgICBcclxuICAgIHRoaXMuYWRkTm9kZShsb2NOb2RlKTtcclxuICB9XHJcbiAgXHJcbiAgLyoqXHJcbiAgICogQWRkIGV2ZW50IHRvIGdyYXBoXHJcbiAgICovXHJcbiAgYWRkRXZlbnQoXHJcbiAgICBpZDogc3RyaW5nLFxyXG4gICAgZGVzY3JpcHRpb246IHN0cmluZyxcclxuICAgIHBhcnRpY2lwYW50czogc3RyaW5nW10sXHJcbiAgICBjaGFwdGVyOiBudW1iZXJcclxuICApOiB2b2lkIHtcclxuICAgIGNvbnN0IGV2ZW50Tm9kZTogQ29uc3RyYWludE5vZGUgPSB7XHJcbiAgICAgIGlkOiBgZXZlbnQtJHtpZH1gLFxyXG4gICAgICB0eXBlOiAnZXZlbnQnLFxyXG4gICAgICBsYWJlbDogZGVzY3JpcHRpb24sXHJcbiAgICAgIHByb3BlcnRpZXM6IHsgcGFydGljaXBhbnRzIH0sXHJcbiAgICAgIGNoYXB0ZXJFc3RhYmxpc2hlZDogY2hhcHRlcixcclxuICAgIH07XHJcbiAgICBcclxuICAgIHRoaXMuYWRkTm9kZShldmVudE5vZGUpO1xyXG4gICAgXHJcbiAgICAvLyBDb25uZWN0IHBhcnRpY2lwYW50cyB0byBldmVudFxyXG4gICAgZm9yIChjb25zdCBwYXJ0aWNpcGFudCBvZiBwYXJ0aWNpcGFudHMpIHtcclxuICAgICAgY29uc3QgY2hhcklkID0gYGNoYXItJHtwYXJ0aWNpcGFudH1gO1xyXG4gICAgICBpZiAodGhpcy5ub2Rlcy5oYXMoY2hhcklkKSkge1xyXG4gICAgICAgIHRoaXMuYWRkRWRnZSh7XHJcbiAgICAgICAgICBpZDogYGVkZ2UtJHtwYXJ0aWNpcGFudH0tcGFydGljaXBhdGVzLSR7aWR9YCxcclxuICAgICAgICAgIGZyb206IGNoYXJJZCxcclxuICAgICAgICAgIHRvOiBldmVudE5vZGUuaWQsXHJcbiAgICAgICAgICB0eXBlOiAncGFydGljaXBhdGVzX2luJyxcclxuICAgICAgICAgIHByb3BlcnRpZXM6IHsgY2hhcHRlciB9LFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIFVwZGF0ZSBjaGFyYWN0ZXIgbG9jYXRpb25cclxuICAgKi9cclxuICB1cGRhdGVDaGFyYWN0ZXJMb2NhdGlvbihjaGFyYWN0ZXJOYW1lOiBzdHJpbmcsIG5ld0xvY2F0aW9uOiBzdHJpbmcsIGNoYXB0ZXI6IG51bWJlcik6IHZvaWQge1xyXG4gICAgY29uc3QgY2hhcklkID0gYGNoYXItJHtjaGFyYWN0ZXJOYW1lfWA7XHJcbiAgICBjb25zdCBjaGFyTm9kZSA9IHRoaXMubm9kZXMuZ2V0KGNoYXJJZCk7XHJcbiAgICBcclxuICAgIGlmIChjaGFyTm9kZSkge1xyXG4gICAgICAvLyBVcGRhdGUgcHJvcGVydGllc1xyXG4gICAgICBjaGFyTm9kZS5wcm9wZXJ0aWVzLmxvY2F0aW9uID0gbmV3TG9jYXRpb247XHJcbiAgICAgIFxyXG4gICAgICAvLyBSZW1vdmUgb2xkIGxvY2F0aW9uIGVkZ2VzXHJcbiAgICAgIGNvbnN0IG9sZEVkZ2VzID0gdGhpcy5nZXRFZGdlc0Zyb20oY2hhcklkKS5maWx0ZXIoZSA9PiBlLnR5cGUgPT09ICdsb2NhdGVkX2F0Jyk7XHJcbiAgICAgIGZvciAoY29uc3QgZWRnZSBvZiBvbGRFZGdlcykge1xyXG4gICAgICAgIHRoaXMuZWRnZXMuZGVsZXRlKGVkZ2UuaWQpO1xyXG4gICAgICAgIGNvbnN0IGFkalNldCA9IHRoaXMuYWRqYWNlbmN5TGlzdC5nZXQoZWRnZS5mcm9tKTtcclxuICAgICAgICBpZiAoYWRqU2V0KSB7XHJcbiAgICAgICAgICBhZGpTZXQuZGVsZXRlKGVkZ2UudG8pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBcclxuICAgICAgLy8gQWRkIG5ldyBsb2NhdGlvbiBlZGdlXHJcbiAgICAgIHRoaXMuYWRkRWRnZSh7XHJcbiAgICAgICAgaWQ6IGBlZGdlLSR7Y2hhcmFjdGVyTmFtZX0tbG9jLSR7Y2hhcHRlcn1gLFxyXG4gICAgICAgIGZyb206IGNoYXJJZCxcclxuICAgICAgICB0bzogYGxvYy0ke25ld0xvY2F0aW9ufWAsXHJcbiAgICAgICAgdHlwZTogJ2xvY2F0ZWRfYXQnLFxyXG4gICAgICAgIHByb3BlcnRpZXM6IHsgc2luY2U6IGNoYXB0ZXIgfSxcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGZvciBjb25zdHJhaW50IHZpb2xhdGlvbnNcclxuICAgKi9cclxuICBjaGVja0NvbnN0cmFpbnRzKGN1cnJlbnRDaGFwdGVyOiBudW1iZXIpOiBDb25zdHJhaW50VmlvbGF0aW9uW10ge1xyXG4gICAgY29uc3QgdmlvbGF0aW9uczogQ29uc3RyYWludFZpb2xhdGlvbltdID0gW107XHJcbiAgICBcclxuICAgIC8vIENoZWNrIGxvY2F0aW9uIGNvbnNpc3RlbmN5XHJcbiAgICB2aW9sYXRpb25zLnB1c2goLi4udGhpcy5jaGVja0xvY2F0aW9uQ29uc2lzdGVuY3koY3VycmVudENoYXB0ZXIpKTtcclxuICAgIFxyXG4gICAgLy8gQ2hlY2sga25vd2xlZGdlIGNvbnNpc3RlbmN5XHJcbiAgICB2aW9sYXRpb25zLnB1c2goLi4udGhpcy5jaGVja0tub3dsZWRnZUNvbnNpc3RlbmN5KGN1cnJlbnRDaGFwdGVyKSk7XHJcbiAgICBcclxuICAgIC8vIENoZWNrIHRpbWVsaW5lIGNvbnNpc3RlbmN5XHJcbiAgICB2aW9sYXRpb25zLnB1c2goLi4udGhpcy5jaGVja1RpbWVsaW5lQ29uc2lzdGVuY3koY3VycmVudENoYXB0ZXIpKTtcclxuICAgIFxyXG4gICAgLy8gQ2hlY2sgbG9naWNhbCBjb25zaXN0ZW5jeVxyXG4gICAgdmlvbGF0aW9ucy5wdXNoKC4uLnRoaXMuY2hlY2tMb2dpY2FsQ29uc2lzdGVuY3koY3VycmVudENoYXB0ZXIpKTtcclxuICAgIFxyXG4gICAgcmV0dXJuIHZpb2xhdGlvbnM7XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGxvY2F0aW9uIGNvbnNpc3RlbmN5IChubyB0ZWxlcG9ydGluZylcclxuICAgKi9cclxuICBwcml2YXRlIGNoZWNrTG9jYXRpb25Db25zaXN0ZW5jeShjdXJyZW50Q2hhcHRlcjogbnVtYmVyKTogQ29uc3RyYWludFZpb2xhdGlvbltdIHtcclxuICAgIGNvbnN0IHZpb2xhdGlvbnM6IENvbnN0cmFpbnRWaW9sYXRpb25bXSA9IFtdO1xyXG4gICAgXHJcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5ub2Rlcy52YWx1ZXMoKSkge1xyXG4gICAgICBpZiAobm9kZS50eXBlID09PSAnY2hhcmFjdGVyJykge1xyXG4gICAgICAgIGNvbnN0IGxvY2F0aW9uRWRnZXMgPSB0aGlzLmdldEVkZ2VzRnJvbShub2RlLmlkKS5maWx0ZXIoZSA9PiBlLnR5cGUgPT09ICdsb2NhdGVkX2F0Jyk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gU29ydCBieSBjaGFwdGVyXHJcbiAgICAgICAgY29uc3Qgc29ydGVkRWRnZXMgPSBsb2NhdGlvbkVkZ2VzLnNvcnQoKGEsIGIpID0+IFxyXG4gICAgICAgICAgKGEucHJvcGVydGllcy5zaW5jZSB8fCAwKSAtIChiLnByb3BlcnRpZXMuc2luY2UgfHwgMClcclxuICAgICAgICApO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIENoZWNrIGZvciBpbXBvc3NpYmxlIG1vdmVtZW50cyAoc2ltcGxpZmllZClcclxuICAgICAgICAvLyBJbiBhIHJlYWwgaW1wbGVtZW50YXRpb24sIHlvdSdkIGNoZWNrIHRyYXZlbCB0aW1lcyBiZXR3ZWVuIGxvY2F0aW9uc1xyXG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgc29ydGVkRWRnZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgIGNvbnN0IHByZXZFZGdlID0gc29ydGVkRWRnZXNbaSAtIDFdO1xyXG4gICAgICAgICAgY29uc3QgY3VyckVkZ2UgPSBzb3J0ZWRFZGdlc1tpXTtcclxuICAgICAgICAgIGNvbnN0IHRpbWVEaWZmID0gKGN1cnJFZGdlLnByb3BlcnRpZXMuc2luY2UgfHwgMCkgLSAocHJldkVkZ2UucHJvcGVydGllcy5zaW5jZSB8fCAwKTtcclxuICAgICAgICAgIFxyXG4gICAgICAgICAgLy8gSWYgbW92ZWQgaW4gc2FtZSBjaGFwdGVyLCBtaWdodCBiZSBzdXNwaWNpb3VzXHJcbiAgICAgICAgICBpZiAodGltZURpZmYgPT09IDAgJiYgY3VyckVkZ2UucHJvcGVydGllcy5zaW5jZSA9PT0gY3VycmVudENoYXB0ZXIpIHtcclxuICAgICAgICAgICAgdmlvbGF0aW9ucy5wdXNoKHtcclxuICAgICAgICAgICAgICB0eXBlOiAnbG9jYXRpb24nLFxyXG4gICAgICAgICAgICAgIHNldmVyaXR5OiAnd2FybmluZycsXHJcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGAke25vZGUubGFiZWx9IG1vdmVkIGZyb20gJHtwcmV2RWRnZS50b30gdG8gJHtjdXJyRWRnZS50b30gaW5zdGFudGx5YCxcclxuICAgICAgICAgICAgICBub2RlczogW25vZGUuaWRdLFxyXG4gICAgICAgICAgICAgIHN1Z2dlc3RlZEZpeDogJ0FkZCB0cmF2ZWwgc2NlbmUgb3IganVzdGlmeSByYXBpZCBtb3ZlbWVudCcsXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICByZXR1cm4gdmlvbGF0aW9ucztcclxuICB9XHJcbiAgXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sga25vd2xlZGdlIGNvbnNpc3RlbmN5IChubyBpbXBvc3NpYmxlIGtub3dsZWRnZSlcclxuICAgKi9cclxuICBwcml2YXRlIGNoZWNrS25vd2xlZGdlQ29uc2lzdGVuY3koY3VycmVudENoYXB0ZXI6IG51bWJlcik6IENvbnN0cmFpbnRWaW9sYXRpb25bXSB7XHJcbiAgICBjb25zdCB2aW9sYXRpb25zOiBDb25zdHJhaW50VmlvbGF0aW9uW10gPSBbXTtcclxuICAgIFxyXG4gICAgZm9yIChjb25zdCBub2RlIG9mIHRoaXMubm9kZXMudmFsdWVzKCkpIHtcclxuICAgICAgaWYgKG5vZGUudHlwZSA9PT0gJ2NoYXJhY3RlcicpIHtcclxuICAgICAgICBjb25zdCBrbm93bGVkZ2VFZGdlcyA9IHRoaXMuZ2V0RWRnZXNGcm9tKG5vZGUuaWQpLmZpbHRlcihlID0+IGUudHlwZSA9PT0gJ2tub3dzJyk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgZm9yIChjb25zdCBlZGdlIG9mIGtub3dsZWRnZUVkZ2VzKSB7XHJcbiAgICAgICAgICBjb25zdCBmYWN0Tm9kZSA9IHRoaXMubm9kZXMuZ2V0KGVkZ2UudG8pO1xyXG4gICAgICAgICAgaWYgKGZhY3ROb2RlICYmIGZhY3ROb2RlLmNoYXB0ZXJFc3RhYmxpc2hlZCkge1xyXG4gICAgICAgICAgICBjb25zdCBrbm93blNpbmNlID0gZWRnZS5wcm9wZXJ0aWVzLnNpbmNlIHx8IGN1cnJlbnRDaGFwdGVyO1xyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgY2hhcmFjdGVyIGtuZXcgZmFjdCBiZWZvcmUgaXQgd2FzIGVzdGFibGlzaGVkXHJcbiAgICAgICAgICAgIGlmIChrbm93blNpbmNlIDwgZmFjdE5vZGUuY2hhcHRlckVzdGFibGlzaGVkKSB7XHJcbiAgICAgICAgICAgICAgdmlvbGF0aW9ucy5wdXNoKHtcclxuICAgICAgICAgICAgICAgIHR5cGU6ICdrbm93bGVkZ2UnLFxyXG4gICAgICAgICAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXHJcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogYCR7bm9kZS5sYWJlbH0ga25vd3MgXCIke2ZhY3ROb2RlLmxhYmVsfVwiIGJlZm9yZSBpdCBoYXBwZW5lZCAoQ2ggJHtrbm93blNpbmNlfSB2cyBDaCAke2ZhY3ROb2RlLmNoYXB0ZXJFc3RhYmxpc2hlZH0pYCxcclxuICAgICAgICAgICAgICAgIG5vZGVzOiBbbm9kZS5pZCwgZmFjdE5vZGUuaWRdLFxyXG4gICAgICAgICAgICAgICAgc3VnZ2VzdGVkRml4OiAnUmVtb3ZlIGtub3dsZWRnZSBvciBhZGp1c3QgdGltZWxpbmUnLFxyXG4gICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHJldHVybiB2aW9sYXRpb25zO1xyXG4gIH1cclxuICBcclxuICAvKipcclxuICAgKiBDaGVjayB0aW1lbGluZSBjb25zaXN0ZW5jeVxyXG4gICAqL1xyXG4gIHByaXZhdGUgY2hlY2tUaW1lbGluZUNvbnNpc3RlbmN5KGN1cnJlbnRDaGFwdGVyOiBudW1iZXIpOiBDb25zdHJhaW50VmlvbGF0aW9uW10ge1xyXG4gICAgY29uc3QgdmlvbGF0aW9uczogQ29uc3RyYWludFZpb2xhdGlvbltdID0gW107XHJcbiAgICBcclxuICAgIC8vIENoZWNrIGZvciBldmVudHMgdGhhdCByZWZlcmVuY2UgZnV0dXJlIGNoYXB0ZXJzXHJcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5ub2Rlcy52YWx1ZXMoKSkge1xyXG4gICAgICBpZiAobm9kZS50eXBlID09PSAnZXZlbnQnICYmIG5vZGUuY2hhcHRlckVzdGFibGlzaGVkKSB7XHJcbiAgICAgICAgaWYgKG5vZGUuY2hhcHRlckVzdGFibGlzaGVkID4gY3VycmVudENoYXB0ZXIpIHtcclxuICAgICAgICAgIHZpb2xhdGlvbnMucHVzaCh7XHJcbiAgICAgICAgICAgIHR5cGU6ICd0aW1lbGluZScsXHJcbiAgICAgICAgICAgIHNldmVyaXR5OiAnZXJyb3InLFxyXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYEV2ZW50IFwiJHtub2RlLmxhYmVsfVwiIGlzIHNldCBpbiBmdXR1cmUgY2hhcHRlciAke25vZGUuY2hhcHRlckVzdGFibGlzaGVkfSBidXQgd2UncmUgaW4gY2hhcHRlciAke2N1cnJlbnRDaGFwdGVyfWAsXHJcbiAgICAgICAgICAgIG5vZGVzOiBbbm9kZS5pZF0sXHJcbiAgICAgICAgICAgIHN1Z2dlc3RlZEZpeDogJ0FkanVzdCBldmVudCBjaGFwdGVyIG9yIHJlbW92ZSByZWZlcmVuY2UnLFxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHJldHVybiB2aW9sYXRpb25zO1xyXG4gIH1cclxuICBcclxuICAvKipcclxuICAgKiBDaGVjayBsb2dpY2FsIGNvbnNpc3RlbmN5XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBjaGVja0xvZ2ljYWxDb25zaXN0ZW5jeShjdXJyZW50Q2hhcHRlcjogbnVtYmVyKTogQ29uc3RyYWludFZpb2xhdGlvbltdIHtcclxuICAgIGNvbnN0IHZpb2xhdGlvbnM6IENvbnN0cmFpbnRWaW9sYXRpb25bXSA9IFtdO1xyXG4gICAgXHJcbiAgICAvLyBDaGVjayBmb3IgY2hhcmFjdGVycyBwYXJ0aWNpcGF0aW5nIGluIGV2ZW50cyB3aGVuIG5vdCBwcmVzZW50XHJcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgdGhpcy5ub2Rlcy52YWx1ZXMoKSkge1xyXG4gICAgICBpZiAobm9kZS50eXBlID09PSAnZXZlbnQnKSB7XHJcbiAgICAgICAgY29uc3QgcGFydGljaXBhbnRzID0gbm9kZS5wcm9wZXJ0aWVzLnBhcnRpY2lwYW50cyB8fCBbXTtcclxuICAgICAgICBcclxuICAgICAgICBmb3IgKGNvbnN0IHBhcnRpY2lwYW50IG9mIHBhcnRpY2lwYW50cykge1xyXG4gICAgICAgICAgY29uc3QgY2hhcklkID0gYGNoYXItJHtwYXJ0aWNpcGFudH1gO1xyXG4gICAgICAgICAgY29uc3QgY2hhck5vZGUgPSB0aGlzLm5vZGVzLmdldChjaGFySWQpO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICBpZiAoY2hhck5vZGUpIHtcclxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgY2hhcmFjdGVyIHdhcyBhbGl2ZS9wcmVzZW50IGF0IGV2ZW50IHRpbWVcclxuICAgICAgICAgICAgaWYgKGNoYXJOb2RlLmNoYXB0ZXJFc3RhYmxpc2hlZCAmJiBub2RlLmNoYXB0ZXJFc3RhYmxpc2hlZCkge1xyXG4gICAgICAgICAgICAgIGlmIChjaGFyTm9kZS5jaGFwdGVyRXN0YWJsaXNoZWQgPiBub2RlLmNoYXB0ZXJFc3RhYmxpc2hlZCkge1xyXG4gICAgICAgICAgICAgICAgdmlvbGF0aW9ucy5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgdHlwZTogJ2xvZ2ljJyxcclxuICAgICAgICAgICAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXHJcbiAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgJHtwYXJ0aWNpcGFudH0gcGFydGljaXBhdGVzIGluIGV2ZW50IGJlZm9yZSB0aGV5IHdlcmUgaW50cm9kdWNlZGAsXHJcbiAgICAgICAgICAgICAgICAgIG5vZGVzOiBbY2hhcklkLCBub2RlLmlkXSxcclxuICAgICAgICAgICAgICAgICAgc3VnZ2VzdGVkRml4OiAnQWRqdXN0IGNoYXJhY3RlciBpbnRyb2R1Y3Rpb24gb3IgZXZlbnQgdGltaW5nJyxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICByZXR1cm4gdmlvbGF0aW9ucztcclxuICB9XHJcbiAgXHJcbiAgLyoqXHJcbiAgICogUXVlcnkgd2hhdCBhIGNoYXJhY3RlciBrbm93c1xyXG4gICAqL1xyXG4gIGdldENoYXJhY3Rlcktub3dsZWRnZShjaGFyYWN0ZXJOYW1lOiBzdHJpbmcpOiBDb25zdHJhaW50Tm9kZVtdIHtcclxuICAgIGNvbnN0IGNoYXJJZCA9IGBjaGFyLSR7Y2hhcmFjdGVyTmFtZX1gO1xyXG4gICAgY29uc3Qga25vd2xlZGdlRWRnZXMgPSB0aGlzLmdldEVkZ2VzRnJvbShjaGFySWQpLmZpbHRlcihlID0+IGUudHlwZSA9PT0gJ2tub3dzJyk7XHJcbiAgICBcclxuICAgIHJldHVybiBrbm93bGVkZ2VFZGdlc1xyXG4gICAgICAubWFwKGVkZ2UgPT4gdGhpcy5ub2Rlcy5nZXQoZWRnZS50bykpXHJcbiAgICAgIC5maWx0ZXIoKG4pOiBuIGlzIENvbnN0cmFpbnROb2RlID0+IG4gIT09IHVuZGVmaW5lZCAmJiBuLnR5cGUgPT09ICdmYWN0Jyk7XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIFF1ZXJ5IHdoZXJlIGEgY2hhcmFjdGVyIGlzXHJcbiAgICovXHJcbiAgZ2V0Q2hhcmFjdGVyTG9jYXRpb24oY2hhcmFjdGVyTmFtZTogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcclxuICAgIGNvbnN0IGNoYXJJZCA9IGBjaGFyLSR7Y2hhcmFjdGVyTmFtZX1gO1xyXG4gICAgY29uc3QgbG9jYXRpb25FZGdlID0gdGhpcy5nZXRFZGdlc0Zyb20oY2hhcklkKS5maW5kKGUgPT4gZS50eXBlID09PSAnbG9jYXRlZF9hdCcpO1xyXG4gICAgXHJcbiAgICBpZiAobG9jYXRpb25FZGdlKSB7XHJcbiAgICAgIGNvbnN0IGxvY05vZGUgPSB0aGlzLm5vZGVzLmdldChsb2NhdGlvbkVkZ2UudG8pO1xyXG4gICAgICByZXR1cm4gbG9jTm9kZT8ubGFiZWw7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIFNlcmlhbGl6ZSBncmFwaFxyXG4gICAqL1xyXG4gIHNlcmlhbGl6ZSgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtcclxuICAgICAgbm9kZXM6IEFycmF5LmZyb20odGhpcy5ub2Rlcy5lbnRyaWVzKCkpLFxyXG4gICAgICBlZGdlczogQXJyYXkuZnJvbSh0aGlzLmVkZ2VzLmVudHJpZXMoKSksXHJcbiAgICB9KTtcclxuICB9XHJcbiAgXHJcbiAgLyoqXHJcbiAgICogTG9hZCBncmFwaCBmcm9tIHNlcmlhbGl6ZWQgZGF0YVxyXG4gICAqL1xyXG4gIGxvYWQoZGF0YTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGRhdGEpO1xyXG4gICAgdGhpcy5ub2RlcyA9IG5ldyBNYXAocGFyc2VkLm5vZGVzKTtcclxuICAgIHRoaXMuZWRnZXMgPSBuZXcgTWFwKHBhcnNlZC5lZGdlcyk7XHJcbiAgICBcclxuICAgIC8vIFJlYnVpbGQgYWRqYWNlbmN5IGxpc3RcclxuICAgIHRoaXMuYWRqYWNlbmN5TGlzdCA9IG5ldyBNYXAoKTtcclxuICAgIGZvciAoY29uc3QgW2lkLCBub2RlXSBvZiB0aGlzLm5vZGVzKSB7XHJcbiAgICAgIHRoaXMuYWRqYWNlbmN5TGlzdC5zZXQoaWQsIG5ldyBTZXQoKSk7XHJcbiAgICB9XHJcbiAgICBmb3IgKGNvbnN0IGVkZ2Ugb2YgdGhpcy5lZGdlcy52YWx1ZXMoKSkge1xyXG4gICAgICBjb25zdCBzZXQgPSB0aGlzLmFkamFjZW5jeUxpc3QuZ2V0KGVkZ2UuZnJvbSk7XHJcbiAgICAgIGlmIChzZXQpIHtcclxuICAgICAgICBzZXQuYWRkKGVkZ2UudG8pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIEdldCBncmFwaCBzdGF0aXN0aWNzXHJcbiAgICovXHJcbiAgZ2V0U3RhdHMoKTogeyBub2RlczogbnVtYmVyOyBlZGdlczogbnVtYmVyOyBieVR5cGU6IFJlY29yZDxOb2RlVHlwZSwgbnVtYmVyPiB9IHtcclxuICAgIGNvbnN0IGJ5VHlwZTogUmVjb3JkPE5vZGVUeXBlLCBudW1iZXI+ID0ge1xyXG4gICAgICBjaGFyYWN0ZXI6IDAsXHJcbiAgICAgIGxvY2F0aW9uOiAwLFxyXG4gICAgICBmYWN0OiAwLFxyXG4gICAgICBldmVudDogMCxcclxuICAgICAgaXRlbTogMCxcclxuICAgIH07XHJcbiAgICBcclxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLm5vZGVzLnZhbHVlcygpKSB7XHJcbiAgICAgIGJ5VHlwZVtub2RlLnR5cGVdKys7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHJldHVybiB7XHJcbiAgICAgIG5vZGVzOiB0aGlzLm5vZGVzLnNpemUsXHJcbiAgICAgIGVkZ2VzOiB0aGlzLmVkZ2VzLnNpemUsXHJcbiAgICAgIGJ5VHlwZSxcclxuICAgIH07XHJcbiAgfVxyXG4gIFxyXG4gIC8qKlxyXG4gICAqIFNhbml0aXplIHN0cmluZyBmb3IgdXNlIGFzIElEXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzYW5pdGl6ZUlkKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBzdHIucmVwbGFjZSgvW15hLXpBLVowLTldL2csICdfJykuc3Vic3RyaW5nKDAsIDUwKTtcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDb25zdHJhaW50R3JhcGgoKTogQ29uc3RyYWludEdyYXBoIHtcclxuICByZXR1cm4gbmV3IENvbnN0cmFpbnRHcmFwaCgpO1xyXG59XHJcbiJdfQ==
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Chapter, StoryBible } from '../types/index.js';
|
|
2
|
+
import type { StoryStructuredState } from '../story/structuredState.js';
|
|
3
|
+
import type { CanonStore } from '../memory/canonStore.js';
|
|
4
|
+
import { ConstraintGraph, type ConstraintViolation } from './constraintGraph.js';
|
|
5
|
+
export interface ValidationResult {
|
|
6
|
+
valid: boolean;
|
|
7
|
+
violations: ConstraintViolation[];
|
|
8
|
+
summary: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ChapterValidationContext {
|
|
11
|
+
chapter: Chapter;
|
|
12
|
+
bible: StoryBible;
|
|
13
|
+
structuredState: StoryStructuredState;
|
|
14
|
+
canon: CanonStore;
|
|
15
|
+
previousChapters: Chapter[];
|
|
16
|
+
constraintGraph: ConstraintGraph;
|
|
17
|
+
}
|
|
18
|
+
export declare class Validator {
|
|
19
|
+
private constraintGraph;
|
|
20
|
+
constructor(constraintGraph?: ConstraintGraph);
|
|
21
|
+
/**
|
|
22
|
+
* Validate a chapter using both graph-based and LLM-based checks
|
|
23
|
+
*/
|
|
24
|
+
validateChapter(context: ChapterValidationContext): Promise<ValidationResult>;
|
|
25
|
+
/**
|
|
26
|
+
* LLM-based validation
|
|
27
|
+
*/
|
|
28
|
+
private llmValidate;
|
|
29
|
+
/**
|
|
30
|
+
* Quick validation without LLM (for testing/fallback)
|
|
31
|
+
*/
|
|
32
|
+
quickValidate(context: ChapterValidationContext): ValidationResult;
|
|
33
|
+
/**
|
|
34
|
+
* Basic canon check (keyword matching)
|
|
35
|
+
*/
|
|
36
|
+
private checkCanonBasic;
|
|
37
|
+
/**
|
|
38
|
+
* Format canon for prompt
|
|
39
|
+
*/
|
|
40
|
+
private formatCanon;
|
|
41
|
+
/**
|
|
42
|
+
* Format characters for prompt
|
|
43
|
+
*/
|
|
44
|
+
private formatCharacters;
|
|
45
|
+
/**
|
|
46
|
+
* Format plot threads for prompt
|
|
47
|
+
*/
|
|
48
|
+
private formatPlotThreads;
|
|
49
|
+
/**
|
|
50
|
+
* Format validation result for display
|
|
51
|
+
*/
|
|
52
|
+
formatResult(result: ValidationResult): string;
|
|
53
|
+
/**
|
|
54
|
+
* Get the constraint graph
|
|
55
|
+
*/
|
|
56
|
+
getConstraintGraph(): ConstraintGraph;
|
|
57
|
+
}
|
|
58
|
+
export declare const validator: Validator;
|