@thijshakkenberg/valkyrie-mom-mcp 2.2.0 → 2.3.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/.claude-plugin/plugin.json +1 -1
- package/README.md +24 -4
- package/agents/scenario-designer.md +2 -1
- package/dist/catalogs/extract-catalogs.js +4 -1
- package/dist/catalogs/extract-catalogs.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +28 -0
- package/dist/server.js.map +1 -1
- package/dist/story/story-graph.d.ts +55 -0
- package/dist/story/story-graph.d.ts.map +1 -0
- package/dist/story/story-graph.js +391 -0
- package/dist/story/story-graph.js.map +1 -0
- package/package.json +3 -2
- package/skills/scenario/SKILL.md +1 -0
- package/src/catalogs/extract-catalogs.ts +4 -4
- package/src/server.ts +30 -0
- package/src/story/story-graph.ts +392 -0
package/README.md
CHANGED
|
@@ -53,6 +53,16 @@ Add to your MCP client config (e.g., `~/.claude/mcp.json` or Claude Desktop sett
|
|
|
53
53
|
|
|
54
54
|
This gives you the MCP tools and resources, but not the skills or agent (those require Claude Code).
|
|
55
55
|
|
|
56
|
+
### As a Hermes Agent plugin
|
|
57
|
+
|
|
58
|
+
[Hermes Agent](https://hermes-agent.nousresearch.com/docs/user-guide/features/plugins) installs the repository as a plugin with every tool and all skills:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
hermes plugins install thijs-hakkenberg/ValkyrieMCP --enable
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The plugin registers the MCP tools as native Hermes tools (toolset `valkyrie-mom`) and the skills as `valkyrie-mom:<skill>` (e.g. `skill_view("valkyrie-mom:artwork")`). On the first tool call it starts the matching `@thijshakkenberg/valkyrie-mom-mcp` version with `npx` (Node.js 20+ required) and keeps it running for the session, since the scenario being edited lives there. Pictures that tools return, such as `render_map`, are saved under `~/.hermes/cache/valkyrie-mom/` and their paths are given in the result. For a local checkout, set `VALKYRIE_MCP_COMMAND="npx tsx /path/to/ValkyrieMCP/src/index.ts"`.
|
|
65
|
+
|
|
56
66
|
### From source
|
|
57
67
|
|
|
58
68
|
```bash
|
|
@@ -113,6 +123,11 @@ npx tsx src/index.ts # Run MCP server via stdio
|
|
|
113
123
|
| `suggest_tile_layout` | Suggest coordinates for large (7x7) tiles in linear, L-shape, or hub-spoke layouts |
|
|
114
124
|
| `place_tile_relative` | Position and rotation for a new tile against an existing one, with a door lined up |
|
|
115
125
|
|
|
126
|
+
### Story
|
|
127
|
+
| Tool | Description |
|
|
128
|
+
|------|-------------|
|
|
129
|
+
| `story_graph` | Project the storyline as a graph: a condensed text outline (buttons, conditions, effects, placed tokens, puzzles, monster events, endings, never-reached events), Mermaid, or an HTML page with the rendered flowchart |
|
|
130
|
+
|
|
116
131
|
### Artwork
|
|
117
132
|
| Tool | Description |
|
|
118
133
|
|------|-------------|
|
|
@@ -211,24 +226,29 @@ The server validates scenarios against 18 rule categories, checked against Valky
|
|
|
211
226
|
## Development
|
|
212
227
|
|
|
213
228
|
```bash
|
|
214
|
-
npm test
|
|
229
|
+
npm test # Run all tests
|
|
215
230
|
npm run test:watch # Watch mode
|
|
216
231
|
npm run lint # Type check
|
|
217
232
|
npm run build # Compile to dist/
|
|
233
|
+
npm run hermes:tools # Re-export the Hermes plugin tool list after changing tools or the version
|
|
218
234
|
```
|
|
219
235
|
|
|
220
236
|
## Project Structure
|
|
221
237
|
|
|
222
238
|
```
|
|
223
|
-
.claude-plugin/
|
|
224
|
-
|
|
239
|
+
.claude-plugin/ Claude Code plugin manifest
|
|
240
|
+
plugin.yaml Hermes Agent plugin manifest (+ __init__.py entry point)
|
|
241
|
+
hermes_bridge/ Hermes plugin: MCP stdio client, tool registration, exported tools.json
|
|
242
|
+
skills/ 8 skill SKILL.md files (Claude Code and Hermes)
|
|
225
243
|
agents/ Scenario designer agent
|
|
226
244
|
src/
|
|
227
245
|
io/ INI parser/writer, localization CSV, ZIP packager
|
|
228
246
|
model/ ScenarioModel, LocalizationStore, component types
|
|
229
|
-
validation/
|
|
247
|
+
validation/ Rules + orchestrator
|
|
230
248
|
rules/ Individual validation rule implementations
|
|
231
249
|
tools/ MCP tool implementations
|
|
250
|
+
story/ Storyline graph: outline, Mermaid, HTML
|
|
251
|
+
artwork/ ComfyUI (FLUX.2 [klein]) artwork generation
|
|
232
252
|
resources/ Format documentation resources
|
|
233
253
|
catalogs/ 846-entry game content catalog
|
|
234
254
|
diagnostics/ Bug report builder, session trace, ring buffer
|
|
@@ -45,6 +45,7 @@ You are an autonomous Mansions of Madness 2nd Edition scenario designer. You cre
|
|
|
45
45
|
- Set up mythos scaling for tension progression
|
|
46
46
|
- Write atmospheric narrative text in the Lovecraftian horror style
|
|
47
47
|
- Validate scenarios for correctness and completeness
|
|
48
|
+
- Review the storyline as a condensed event tree (`story_graph`) and explain it to the user
|
|
48
49
|
|
|
49
50
|
## Available Skills
|
|
50
51
|
|
|
@@ -112,7 +113,7 @@ Use these skills for detailed pattern guidance:
|
|
|
112
113
|
7. Add spawns with `upsert_spawn`
|
|
113
114
|
8. Configure items with `upsert_item`
|
|
114
115
|
9. Write all narrative with `set_localization`
|
|
115
|
-
10. Validate with `validate_scenario`
|
|
116
|
+
10. Validate with `validate_scenario`, then read the plot back with `story_graph` (outline) to check branches, endings and never-reached events
|
|
116
117
|
11. Save with `save_scenario` (edits stay in memory until saved or built)
|
|
117
118
|
12. Build with `build_scenario`
|
|
118
119
|
|
|
@@ -105,7 +105,10 @@ function generateCatalogSource(catalogs) {
|
|
|
105
105
|
const isMainModule = process.argv[1] && (process.argv[1].endsWith('extract-catalogs.ts') ||
|
|
106
106
|
process.argv[1].endsWith('extract-catalogs.js'));
|
|
107
107
|
if (isMainModule) {
|
|
108
|
-
|
|
108
|
+
// The Valkyrie source checkout, by default next to this repository
|
|
109
|
+
const valkyrieRepo = process.env.VALKYRIE_SOURCE_DIR
|
|
110
|
+
?? path.join(path.dirname(path.dirname(path.dirname(import.meta.dirname ?? '.'))), 'valkyrie');
|
|
111
|
+
const valkyrieContentDir = path.join(valkyrieRepo, 'unity', 'Assets', 'StreamingAssets', 'content', 'MoM');
|
|
109
112
|
if (!fs.existsSync(valkyrieContentDir)) {
|
|
110
113
|
console.error(`Valkyrie content not found at: ${valkyrieContentDir}`);
|
|
111
114
|
console.error('Make sure the Valkyrie repo is cloned at the expected path.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract-catalogs.js","sourceRoot":"","sources":["../../src/catalogs/extract-catalogs.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"extract-catalogs.js","sourceRoot":"","sources":["../../src/catalogs/extract-catalogs.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA8EpE,wBAAgB,YAAY,IAAI,SAAS,CAqdxC"}
|
package/dist/server.js
CHANGED
|
@@ -12,6 +12,7 @@ import { getMapAscii, suggestTileLayout, placeTileRelative } from './tools/map.j
|
|
|
12
12
|
import { renderMap } from './map/render.js';
|
|
13
13
|
import { searchGameContent } from './tools/reference.js';
|
|
14
14
|
import { toPackageName, writePackageManifest } from './io/package-manifest.js';
|
|
15
|
+
import { buildStoryGraph, renderMermaid, renderOutline, renderStoryHtml } from './story/story-graph.js';
|
|
15
16
|
import { DEFAULT_COMFYUI_URL, generateArtwork, getArtworkStatus, setupInstructions } from './artwork/comfyui.js';
|
|
16
17
|
import { EVENT_FORMAT_DOC, LOCALIZATION_FORMAT_DOC, COMPONENT_FORMAT_DOC, PATTERN_REFERENCE_DOC, } from './resources/format-docs.js';
|
|
17
18
|
import { SessionTrace } from './diagnostics/session-trace.js';
|
|
@@ -198,6 +199,33 @@ export function createServer() {
|
|
|
198
199
|
],
|
|
199
200
|
};
|
|
200
201
|
});
|
|
202
|
+
server.tool('story_graph', 'Project the scenario\'s storyline as a graph: what each button, trigger, placed token, item inspection and monster event leads to. '
|
|
203
|
+
+ 'format=outline (default) is a condensed text tree: one line per event with its first words, conditions (if ...), effects (variables, +placed/−removed) and END; straight chains stay on one level, decisions indent, repeats point back (↩), and endings and never-reached events are listed. '
|
|
204
|
+
+ 'format=mermaid gives a flowchart definition. outputPath (.html) writes a page with the rendered chart and the outline for people. Use it to review or explain the plot, and to find dead ends and loops', {
|
|
205
|
+
format: z.enum(['outline', 'mermaid']).optional().describe('outline (default) or mermaid'),
|
|
206
|
+
root: z.string().optional().describe('Only the part of the story that follows this component (e.g. EventScream)'),
|
|
207
|
+
maxDepth: z.number().int().optional().describe('Stop expanding below this depth (default 30)'),
|
|
208
|
+
outputPath: z.string().optional().describe('Also write the result: .html (chart + outline page), .mmd/.md (Mermaid) or .txt (outline)'),
|
|
209
|
+
}, async ({ format, root, maxDepth, outputPath }) => {
|
|
210
|
+
const model = getModel();
|
|
211
|
+
if (root && !model.get(root))
|
|
212
|
+
throw new Error(`No component named "${root}"`);
|
|
213
|
+
const graph = buildStoryGraph(model);
|
|
214
|
+
const text = format === 'mermaid' ? renderMermaid(graph) : renderOutline(graph, { root, maxDepth });
|
|
215
|
+
let note = '';
|
|
216
|
+
if (outputPath) {
|
|
217
|
+
const file = path.isAbsolute(outputPath) || !model.scenarioDir ? outputPath : path.resolve(outputPath);
|
|
218
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
219
|
+
if (/\.html?$/i.test(file))
|
|
220
|
+
fs.writeFileSync(file, renderStoryHtml(graph));
|
|
221
|
+
else if (/\.(mmd|md)$/i.test(file))
|
|
222
|
+
fs.writeFileSync(file, file.endsWith('.md') ? `\`\`\`mermaid\n${renderMermaid(graph)}\n\`\`\`\n` : renderMermaid(graph));
|
|
223
|
+
else
|
|
224
|
+
fs.writeFileSync(file, text);
|
|
225
|
+
note = `\n\nWritten to ${file}`;
|
|
226
|
+
}
|
|
227
|
+
return { content: [{ type: 'text', text: text + note }] };
|
|
228
|
+
});
|
|
201
229
|
// ── Artwork Tools ──
|
|
202
230
|
server.tool('artwork_status', 'Check whether a local ComfyUI server with FLUX.2 [klein] 4B is ready for generate_artwork, and how to set up what is missing (comfy-cli install, launch and model downloads)', { comfyUrl: z.string().optional().describe(`ComfyUI address (default ${DEFAULT_COMFYUI_URL}, or VALKYRIE_COMFYUI_URL)`) }, async ({ comfyUrl }) => {
|
|
203
231
|
const status = await getArtworkStatus(comfyUrl ?? DEFAULT_COMFYUI_URL);
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ScenarioModel } from '../model/scenario-model.js';
|
|
2
|
+
/**
|
|
3
|
+
* The storyline as a graph: what runs what, the way Valkyrie plays it. Nodes are components that
|
|
4
|
+
* run (events, puzzles, spawns) or that players click or inspect (tokens, UI buttons, items);
|
|
5
|
+
* edges are buttons, board items placed by `add`, item inspection, monster events and
|
|
6
|
+
* Defeated triggers. Rendered as a condensed outline for authors and agents, or as Mermaid.
|
|
7
|
+
*/
|
|
8
|
+
export type EdgeKind = 'button' | 'places' | 'click' | 'inspect' | 'activation' | 'evade' | 'horror' | 'defeated';
|
|
9
|
+
export interface StoryEdge {
|
|
10
|
+
from: string;
|
|
11
|
+
to: string;
|
|
12
|
+
kind: EdgeKind;
|
|
13
|
+
/** Button text, or a short description of the connection */
|
|
14
|
+
label: string;
|
|
15
|
+
/** Several targets on one button: Valkyrie runs the first whose conditions pass, or a random one */
|
|
16
|
+
choice?: 'first' | 'random';
|
|
17
|
+
}
|
|
18
|
+
export interface StoryNode {
|
|
19
|
+
name: string;
|
|
20
|
+
kind: 'dialog' | 'hidden' | 'puzzle' | 'spawn' | 'token' | 'ui' | 'item' | 'monster';
|
|
21
|
+
summary: string;
|
|
22
|
+
conditions?: string;
|
|
23
|
+
effects: string[];
|
|
24
|
+
ending?: 'end';
|
|
25
|
+
trigger?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface StoryGraph {
|
|
28
|
+
title: string;
|
|
29
|
+
nodes: Map<string, StoryNode>;
|
|
30
|
+
edges: StoryEdge[];
|
|
31
|
+
/** Entry points: triggers, and items held from the start */
|
|
32
|
+
roots: Array<{
|
|
33
|
+
label: string;
|
|
34
|
+
node: string;
|
|
35
|
+
}>;
|
|
36
|
+
unreachable: string[];
|
|
37
|
+
}
|
|
38
|
+
/** "VarOperation:a,==,1 VarTestsLogicalOperator:AND VarOperation:b,>=,2" → "a==1 AND b>=2" */
|
|
39
|
+
export declare function compactConditions(vartests: string | undefined): string | undefined;
|
|
40
|
+
/** "Suspicion,+,1 $end,=,1" → ["Suspicion+=1", "END"] */
|
|
41
|
+
export declare function compactOperations(ops: string | undefined): string[];
|
|
42
|
+
export declare function buildStoryGraph(model: ScenarioModel): StoryGraph;
|
|
43
|
+
export interface OutlineOptions {
|
|
44
|
+
/** Start from this component instead of the scenario's entry points */
|
|
45
|
+
root?: string;
|
|
46
|
+
/** Stop expanding below this depth (default 30) */
|
|
47
|
+
maxDepth?: number;
|
|
48
|
+
}
|
|
49
|
+
/** Condensed text projection: each component expanded once, later visits point back to it */
|
|
50
|
+
export declare function renderOutline(g: StoryGraph, opts?: OutlineOptions): string;
|
|
51
|
+
/** Mermaid flowchart of the same graph */
|
|
52
|
+
export declare function renderMermaid(g: StoryGraph): string;
|
|
53
|
+
/** Self-contained page: the Mermaid chart (rendered in the browser) above the outline */
|
|
54
|
+
export declare function renderStoryHtml(g: StoryGraph): string;
|
|
55
|
+
//# sourceMappingURL=story-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"story-graph.d.ts","sourceRoot":"","sources":["../../src/story/story-graph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIhE;;;;;GAKG;AAEH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;AAElH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,oGAAoG;IACpG,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IACrF,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC9B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,4DAA4D;IAC5D,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAmBD,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAUlF;AAED,yDAAyD;AACzD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAOnE;AAMD,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CA8IhE;AAgBD,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,GAAE,cAAmB,GAAG,MAAM,CAkE9E;AAUD,0CAA0C;AAC1C,wBAAgB,aAAa,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAkCnD;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAwBrD"}
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { parseRefList } from '../model/component-types.js';
|
|
2
|
+
import { computeReachability, isStartingItem } from '../validation/rules/game-flow.js';
|
|
3
|
+
import { checkTrigger } from '../validation/rules/triggers.js';
|
|
4
|
+
const RUNNABLE = ['Event', 'Puzzle', 'Spawn'];
|
|
5
|
+
const isRunnable = (n) => RUNNABLE.some(p => n.startsWith(p));
|
|
6
|
+
/** Localized text as one short line: markup stripped, text codes kept readable */
|
|
7
|
+
function summarize(text, max = 90, loc) {
|
|
8
|
+
if (!text || text.trim() === '.')
|
|
9
|
+
return '';
|
|
10
|
+
const plain = text
|
|
11
|
+
.replace(/^\|\|\|/, '')
|
|
12
|
+
.replace(/<[^>]+>/g, '')
|
|
13
|
+
.replace(/\\n|\n/g, ' ')
|
|
14
|
+
.replace(/\{qst:(\w+)\}/g, (_, k) => loc?.(k) ?? k)
|
|
15
|
+
.replace(/\{(?:c|var):([^}]+)\}/g, '$1')
|
|
16
|
+
.replace(/\s+/g, ' ')
|
|
17
|
+
.trim();
|
|
18
|
+
return plain.length > max ? `${plain.slice(0, max - 1).trimEnd()}…` : plain;
|
|
19
|
+
}
|
|
20
|
+
/** "VarOperation:a,==,1 VarTestsLogicalOperator:AND VarOperation:b,>=,2" → "a==1 AND b>=2" */
|
|
21
|
+
export function compactConditions(vartests) {
|
|
22
|
+
if (!vartests?.trim())
|
|
23
|
+
return undefined;
|
|
24
|
+
const parts = vartests.trim().split(/\s+/).map(t => {
|
|
25
|
+
const op = t.match(/^VarOperation:([^,]+),([^,]+),(.+)$/);
|
|
26
|
+
if (op)
|
|
27
|
+
return `${op[1]}${op[2]}${op[3]}`;
|
|
28
|
+
const logic = t.match(/^VarTestsLogicalOperator:(\w+)$/);
|
|
29
|
+
if (logic)
|
|
30
|
+
return logic[1];
|
|
31
|
+
return t.replace(/^VarTests\w*:/, '');
|
|
32
|
+
});
|
|
33
|
+
return parts.join(' ');
|
|
34
|
+
}
|
|
35
|
+
/** "Suspicion,+,1 $end,=,1" → ["Suspicion+=1", "END"] */
|
|
36
|
+
export function compactOperations(ops) {
|
|
37
|
+
return (ops ?? '').split(/\s+/).filter(Boolean).map(op => {
|
|
38
|
+
const [v, o, x] = op.split(',');
|
|
39
|
+
if (v === '$end' && o === '=' && x !== '0')
|
|
40
|
+
return 'END';
|
|
41
|
+
if (o === '=')
|
|
42
|
+
return `${v}=${x}`;
|
|
43
|
+
return `${v}${o}=${x}`;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function buttonLabel(model, name, i) {
|
|
47
|
+
return summarize(model.localization.get(`${name}.button${i}`), 40, k => model.localization.get(k));
|
|
48
|
+
}
|
|
49
|
+
export function buildStoryGraph(model) {
|
|
50
|
+
const nodes = new Map();
|
|
51
|
+
const edges = [];
|
|
52
|
+
const loc = (k) => model.localization.get(k);
|
|
53
|
+
const ensure = (name) => {
|
|
54
|
+
const existing = nodes.get(name);
|
|
55
|
+
if (existing)
|
|
56
|
+
return existing;
|
|
57
|
+
const comp = model.get(name);
|
|
58
|
+
if (!comp)
|
|
59
|
+
return undefined;
|
|
60
|
+
const d = comp.data;
|
|
61
|
+
let kind;
|
|
62
|
+
if (name.startsWith('Puzzle'))
|
|
63
|
+
kind = 'puzzle';
|
|
64
|
+
else if (name.startsWith('Spawn'))
|
|
65
|
+
kind = 'spawn';
|
|
66
|
+
else if (name.startsWith('Token'))
|
|
67
|
+
kind = 'token';
|
|
68
|
+
else if (name.startsWith('UI'))
|
|
69
|
+
kind = 'ui';
|
|
70
|
+
else if (name.startsWith('QItem'))
|
|
71
|
+
kind = 'item';
|
|
72
|
+
else if (name.startsWith('CustomMonster'))
|
|
73
|
+
kind = 'monster';
|
|
74
|
+
else
|
|
75
|
+
kind = d.display?.toLowerCase() === 'false' ? 'hidden' : 'dialog';
|
|
76
|
+
const effects = compactOperations(d.operations);
|
|
77
|
+
const placed = parseRefList(d.add ?? '');
|
|
78
|
+
const removed = parseRefList(d.remove ?? '');
|
|
79
|
+
if (placed.length)
|
|
80
|
+
effects.push(`+${placed.join(' +')}`);
|
|
81
|
+
if (removed.length)
|
|
82
|
+
effects.push(`−${removed.join(' −')}`);
|
|
83
|
+
if (kind === 'puzzle')
|
|
84
|
+
effects.unshift(`${d.class ?? 'slide'} puzzle ${d.skill ?? '{observation}'}${d.puzzlesolution ? ` = ${d.puzzlesolution}` : ''}`);
|
|
85
|
+
if (kind === 'spawn' && d.monster)
|
|
86
|
+
effects.unshift(`monster ${d.monster}`);
|
|
87
|
+
let summary = summarize(loc(`${name}.text`), 80, loc);
|
|
88
|
+
if (kind === 'spawn')
|
|
89
|
+
summary = summarize(loc(`${name}.uniquetitle`)) || summary;
|
|
90
|
+
if (kind === 'ui')
|
|
91
|
+
summary = summarize(loc(`${name}.uitext`)) || summary;
|
|
92
|
+
if (kind === 'monster')
|
|
93
|
+
summary = summarize(loc(`${name}.monstername`)) || '';
|
|
94
|
+
const node = {
|
|
95
|
+
name, kind, summary, effects,
|
|
96
|
+
conditions: compactConditions(d.vartests),
|
|
97
|
+
ending: effects.includes('END') ? 'end' : undefined,
|
|
98
|
+
trigger: d.trigger?.trim() || undefined,
|
|
99
|
+
};
|
|
100
|
+
nodes.set(name, node);
|
|
101
|
+
return node;
|
|
102
|
+
};
|
|
103
|
+
const visited = new Set();
|
|
104
|
+
const visit = (name) => {
|
|
105
|
+
if (visited.has(name) || !ensure(name))
|
|
106
|
+
return;
|
|
107
|
+
visited.add(name);
|
|
108
|
+
const d = model.get(name).data;
|
|
109
|
+
const buttons = Math.max(parseInt(d.buttons ?? '0', 10) || 0, 1);
|
|
110
|
+
const hidden = nodes.get(name).kind === 'hidden';
|
|
111
|
+
// Buttons (hidden events always follow button 1; tokens and UI run their buttons when clicked)
|
|
112
|
+
for (let i = 1; i <= 6; i++) {
|
|
113
|
+
const targets = parseRefList(d[`event${i}`] ?? '');
|
|
114
|
+
if (targets.length === 0)
|
|
115
|
+
continue;
|
|
116
|
+
if (i > buttons && !name.startsWith('Token'))
|
|
117
|
+
continue;
|
|
118
|
+
const label = hidden ? '' : (buttonLabel(model, name, i) || (buttons > 1 ? `button ${i}` : ''));
|
|
119
|
+
const choice = targets.length > 1 ? (d.randomevents?.toLowerCase() === 'true' ? 'random' : 'first') : undefined;
|
|
120
|
+
for (const t of targets) {
|
|
121
|
+
if (!model.get(t))
|
|
122
|
+
continue;
|
|
123
|
+
edges.push({ from: name, to: t, kind: name.startsWith('Puzzle') ? 'button' : 'button', label, choice });
|
|
124
|
+
visit(t);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Board items and items this component places: clicking or inspecting them continues the story
|
|
128
|
+
for (const ref of parseRefList(d.add ?? '')) {
|
|
129
|
+
const target = model.get(ref);
|
|
130
|
+
if (!target)
|
|
131
|
+
continue;
|
|
132
|
+
const clickable = (ref.startsWith('Token') || ref.startsWith('UI'))
|
|
133
|
+
&& [1, 2, 3, 4, 5, 6].some(i => parseRefList(target.data[`event${i}`] ?? '').length > 0);
|
|
134
|
+
if (clickable) {
|
|
135
|
+
edges.push({ from: name, to: ref, kind: 'places', label: 'places' });
|
|
136
|
+
visit(ref);
|
|
137
|
+
}
|
|
138
|
+
else if (ref.startsWith('QItem') && target.data.inspect) {
|
|
139
|
+
edges.push({ from: name, to: ref, kind: 'places', label: 'gives' });
|
|
140
|
+
visitItem(ref);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Monster phase, evade and horror events of what this spawn puts on the board
|
|
144
|
+
if (name.startsWith('Spawn')) {
|
|
145
|
+
for (const m of parseRefList(d.monster ?? '')) {
|
|
146
|
+
const cm = model.get(m);
|
|
147
|
+
if (!cm)
|
|
148
|
+
continue;
|
|
149
|
+
const acts = parseRefList(cm.data.activation ?? '').filter(a => a.startsWith('Event'));
|
|
150
|
+
for (const a of acts) {
|
|
151
|
+
edges.push({ from: name, to: a, kind: 'activation', label: 'each monster phase' });
|
|
152
|
+
visit(a);
|
|
153
|
+
}
|
|
154
|
+
for (const [f, kind, label] of [['evadeevent', 'evade', 'on evade'], ['horrorevent', 'horror', 'on horror check']]) {
|
|
155
|
+
if (cm.data[f] && model.get(cm.data[f])) {
|
|
156
|
+
edges.push({ from: name, to: cm.data[f], kind, label });
|
|
157
|
+
visit(cm.data[f]);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
const visitItem = (item) => {
|
|
164
|
+
if (visited.has(item) || !ensure(item))
|
|
165
|
+
return;
|
|
166
|
+
visited.add(item);
|
|
167
|
+
for (const e of parseRefList(model.get(item).data.inspect ?? '')) {
|
|
168
|
+
if (!model.get(e))
|
|
169
|
+
continue;
|
|
170
|
+
edges.push({ from: item, to: e, kind: 'inspect', label: 'inspect' });
|
|
171
|
+
visit(e);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
// Entry points: EventStart first, then other triggers, starting items; Defeated triggers hang off their spawn
|
|
175
|
+
const roots = [];
|
|
176
|
+
const defeated = [];
|
|
177
|
+
const triggered = model.getAll().filter(c => c.data.trigger?.trim() && isRunnable(c.name));
|
|
178
|
+
triggered.sort((a, b) => Number(b.data.trigger === 'EventStart') - Number(a.data.trigger === 'EventStart'));
|
|
179
|
+
for (const comp of triggered) {
|
|
180
|
+
const trigger = comp.data.trigger.trim();
|
|
181
|
+
const check = checkTrigger(model, trigger);
|
|
182
|
+
if (!check.ok)
|
|
183
|
+
continue;
|
|
184
|
+
if (check.defeated) {
|
|
185
|
+
defeated.push({ event: comp.name, target: check.defeated });
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
roots.push({ label: trigger === 'EventStart' ? 'Game start' : `Trigger ${trigger}`, node: comp.name });
|
|
189
|
+
}
|
|
190
|
+
for (const r of roots)
|
|
191
|
+
visit(r.node);
|
|
192
|
+
for (const item of model.getByType('QItem')) {
|
|
193
|
+
if (isStartingItem(item.data) && item.data.inspect) {
|
|
194
|
+
roots.push({ label: 'Starting item', node: item.name });
|
|
195
|
+
visitItem(item.name);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Defeated<X>: from each spawn that puts X (or a monster of type X) on the board
|
|
199
|
+
let grew = true;
|
|
200
|
+
while (grew) {
|
|
201
|
+
grew = false;
|
|
202
|
+
for (const t of defeated) {
|
|
203
|
+
const sources = [...nodes.keys()].filter(n => n === t.target
|
|
204
|
+
|| (n.startsWith('Spawn') && parseRefList(model.get(n)?.data.monster ?? '').includes(t.target)));
|
|
205
|
+
for (const s of sources) {
|
|
206
|
+
if (edges.some(e => e.from === s && e.to === t.event))
|
|
207
|
+
continue;
|
|
208
|
+
edges.push({ from: s, to: t.event, kind: 'defeated', label: 'when defeated' });
|
|
209
|
+
if (!visited.has(t.event))
|
|
210
|
+
grew = true;
|
|
211
|
+
visit(t.event);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const { runs } = computeReachability(model);
|
|
216
|
+
const unreachable = model.getAll()
|
|
217
|
+
.filter(c => isRunnable(c.name) && !visited.has(c.name) && !runs.has(c.name))
|
|
218
|
+
.map(c => c.name);
|
|
219
|
+
return { title: loc('quest.name') ?? 'Scenario', nodes, edges, roots, unreachable };
|
|
220
|
+
}
|
|
221
|
+
const ICON = {
|
|
222
|
+
dialog: '▶', hidden: '·', puzzle: '◆', spawn: '☠', token: '⊕', ui: '▣', item: '✉', monster: '☠',
|
|
223
|
+
};
|
|
224
|
+
function nodeLine(n) {
|
|
225
|
+
const parts = [`${ICON[n.kind]} ${n.name}`];
|
|
226
|
+
if (n.conditions)
|
|
227
|
+
parts.push(`if ${n.conditions}`);
|
|
228
|
+
if (n.summary)
|
|
229
|
+
parts.push(`"${n.summary}"`);
|
|
230
|
+
const effects = n.effects.filter(e => e !== 'END');
|
|
231
|
+
if (effects.length)
|
|
232
|
+
parts.push(`⟨${effects.join(', ')}⟩`);
|
|
233
|
+
if (n.ending)
|
|
234
|
+
parts.push('✦ END');
|
|
235
|
+
return parts.join(' ');
|
|
236
|
+
}
|
|
237
|
+
/** Condensed text projection: each component expanded once, later visits point back to it */
|
|
238
|
+
export function renderOutline(g, opts = {}) {
|
|
239
|
+
const maxDepth = opts.maxDepth ?? 30;
|
|
240
|
+
const out = [];
|
|
241
|
+
const printed = new Set();
|
|
242
|
+
const byFrom = new Map();
|
|
243
|
+
for (const e of g.edges)
|
|
244
|
+
byFrom.set(e.from, [...(byFrom.get(e.from) ?? []), e]);
|
|
245
|
+
// Straight chains stay on one level; only decisions (several buttons, choices, placed items) indent
|
|
246
|
+
const walk = (name, depth, indent, lead) => {
|
|
247
|
+
const n = g.nodes.get(name);
|
|
248
|
+
if (!n)
|
|
249
|
+
return;
|
|
250
|
+
if (printed.has(name)) {
|
|
251
|
+
out.push(`${indent}${lead}↩ ${name}`);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
printed.add(name);
|
|
255
|
+
out.push(`${indent}${lead}${nodeLine(n)}`);
|
|
256
|
+
// What follows a "• " choice belongs to it, so it lines up under the choice's text
|
|
257
|
+
if (lead === '• ')
|
|
258
|
+
indent += ' ';
|
|
259
|
+
if (depth >= maxDepth) {
|
|
260
|
+
out.push(`${indent} …`);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const groups = new Map();
|
|
264
|
+
for (const e of byFrom.get(name) ?? []) {
|
|
265
|
+
const key = `${e.kind}|${e.label}|${e.choice ?? ''}`;
|
|
266
|
+
groups.set(key, [...(groups.get(key) ?? []), e]);
|
|
267
|
+
}
|
|
268
|
+
const labelOf = (e, many) => {
|
|
269
|
+
let label = e.kind === 'button' ? (e.label ? `[${e.label}]` : '→') : `(${e.label})`;
|
|
270
|
+
if (e.choice && many)
|
|
271
|
+
label += e.choice === 'random' ? ' one at random:' : ' first that passes:';
|
|
272
|
+
return label;
|
|
273
|
+
};
|
|
274
|
+
const list = [...groups.values()];
|
|
275
|
+
if (list.length === 1 && list[0].length === 1) {
|
|
276
|
+
walk(list[0][0].to, depth + 1, indent, `${labelOf(list[0][0], false)} `);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const inner = `${indent} `;
|
|
280
|
+
for (const group of list) {
|
|
281
|
+
if (group.length === 1)
|
|
282
|
+
walk(group[0].to, depth + 1, inner, `${labelOf(group[0], false)} `);
|
|
283
|
+
else {
|
|
284
|
+
out.push(`${inner}${labelOf(group[0], true)}`);
|
|
285
|
+
for (const t of group)
|
|
286
|
+
walk(t.to, depth + 1, `${inner} `, '• ');
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
out.push(`Storyline of "${g.title}": ${[...g.nodes.values()].filter(n => n.kind === 'dialog' || n.kind === 'hidden').length} events, ${g.edges.length} connections`);
|
|
291
|
+
out.push('Legend: ▶ dialog · hidden event ◆ puzzle ☠ spawn/monster ⊕ token ▣ UI button ✉ item [button] → next ↩ already shown above ⟨effects⟩ ✦ END');
|
|
292
|
+
if (opts.root) {
|
|
293
|
+
out.push('');
|
|
294
|
+
walk(opts.root, 0, '', '');
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
for (const r of g.roots) {
|
|
298
|
+
out.push('', `== ${r.label} ==`);
|
|
299
|
+
walk(r.node, 0, '', '');
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (!opts.root) {
|
|
303
|
+
const endings = [...g.nodes.values()].filter(n => n.ending);
|
|
304
|
+
if (endings.length) {
|
|
305
|
+
out.push('', '== Endings ==');
|
|
306
|
+
const parents = (name) => g.edges.filter(e => e.to === name).map(e => e.from);
|
|
307
|
+
for (const n of endings) {
|
|
308
|
+
const via = parents(n.name).map(p => g.nodes.get(p)?.kind === 'hidden' ? parents(p).concat(p) : [p]).flat();
|
|
309
|
+
out.push(`✦ ${n.name}${via.length ? ` ← ${[...new Set(via)].join(', ')}` : ''}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (g.unreachable.length)
|
|
313
|
+
out.push('', '== Never reached ==', g.unreachable.join(', '));
|
|
314
|
+
}
|
|
315
|
+
return out.join('\n');
|
|
316
|
+
}
|
|
317
|
+
function mermaidId(name) {
|
|
318
|
+
return name.replace(/[^A-Za-z0-9_]/g, '_');
|
|
319
|
+
}
|
|
320
|
+
function mermaidText(s) {
|
|
321
|
+
return s.replace(/"/g, "'").replace(/[<>]/g, '').replace(/[[\]{}|]/g, ' ');
|
|
322
|
+
}
|
|
323
|
+
/** Mermaid flowchart of the same graph */
|
|
324
|
+
export function renderMermaid(g) {
|
|
325
|
+
const lines = ['flowchart TD'];
|
|
326
|
+
const shape = (n) => {
|
|
327
|
+
const summary = n.summary ? `<br/><small>${mermaidText(n.summary.slice(0, 48))}</small>` : '';
|
|
328
|
+
const cond = n.conditions ? `<br/><i>if ${mermaidText(n.conditions)}</i>` : '';
|
|
329
|
+
const text = `"${n.name}${cond}${summary}"`;
|
|
330
|
+
switch (n.kind) {
|
|
331
|
+
case 'puzzle': return `{{${text}}}`;
|
|
332
|
+
case 'spawn':
|
|
333
|
+
case 'monster': return `[/${text}/]`;
|
|
334
|
+
case 'token':
|
|
335
|
+
case 'ui':
|
|
336
|
+
case 'item': return `>${text}]`;
|
|
337
|
+
case 'hidden': return `(${text})`;
|
|
338
|
+
default: return n.ending ? `([${text}])` : `[${text}]`;
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
for (const r of g.roots)
|
|
342
|
+
lines.push(` root_${mermaidId(r.node)}(("${mermaidText(r.label)}")) --> ${mermaidId(r.node)}`);
|
|
343
|
+
for (const n of g.nodes.values())
|
|
344
|
+
lines.push(` ${mermaidId(n.name)}${shape(n)}`);
|
|
345
|
+
for (const e of g.edges) {
|
|
346
|
+
const label = e.kind === 'button' ? e.label : e.label;
|
|
347
|
+
const arrow = e.kind === 'button' ? '-->' : '-.->';
|
|
348
|
+
lines.push(` ${mermaidId(e.from)} ${arrow}${label ? `|"${mermaidText(label)}"|` : ''} ${mermaidId(e.to)}`);
|
|
349
|
+
}
|
|
350
|
+
lines.push(' classDef hidden fill:#2a2a33,stroke:#666,color:#bbb,stroke-dasharray:3 3');
|
|
351
|
+
lines.push(' classDef ending fill:#4a1d1d,stroke:#d66,color:#fff');
|
|
352
|
+
lines.push(' classDef puzzle fill:#1d3a4a,stroke:#6bd,color:#fff');
|
|
353
|
+
lines.push(' classDef board fill:#3a341d,stroke:#db6,color:#fff');
|
|
354
|
+
const cls = (k, pred) => {
|
|
355
|
+
const ids = [...g.nodes.values()].filter(pred).map(n => mermaidId(n.name));
|
|
356
|
+
if (ids.length)
|
|
357
|
+
lines.push(` class ${ids.join(',')} ${k}`);
|
|
358
|
+
};
|
|
359
|
+
cls('hidden', n => n.kind === 'hidden' && !n.ending);
|
|
360
|
+
cls('ending', n => !!n.ending);
|
|
361
|
+
cls('puzzle', n => n.kind === 'puzzle');
|
|
362
|
+
cls('board', n => n.kind === 'token' || n.kind === 'ui' || n.kind === 'item');
|
|
363
|
+
return lines.join('\n');
|
|
364
|
+
}
|
|
365
|
+
/** Self-contained page: the Mermaid chart (rendered in the browser) above the outline */
|
|
366
|
+
export function renderStoryHtml(g) {
|
|
367
|
+
const esc = (s) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
368
|
+
return `<!doctype html>
|
|
369
|
+
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
370
|
+
<title>${esc(g.title)} storyline</title>
|
|
371
|
+
<style>
|
|
372
|
+
:root { color-scheme: dark; }
|
|
373
|
+
body { margin: 0; background: #16161c; color: #e8e6e1; font: 15px/1.5 system-ui, sans-serif; }
|
|
374
|
+
header { padding: 20px 24px 8px; } h1 { margin: 0; font-size: 22px; } p { margin: 4px 0; color: #a9a6a0; }
|
|
375
|
+
.chart { overflow: auto; padding: 16px 24px; border-top: 1px solid #2c2c36; border-bottom: 1px solid #2c2c36; }
|
|
376
|
+
pre { margin: 0; padding: 16px 24px; white-space: pre-wrap; font: 13px/1.45 ui-monospace, Menlo, monospace; }
|
|
377
|
+
</style></head>
|
|
378
|
+
<body>
|
|
379
|
+
<header><h1>${esc(g.title)}</h1><p>Storyline: ${g.nodes.size} components, ${g.edges.length} connections. Solid arrows are buttons; dotted arrows are board items, inspection and monster events.</p></header>
|
|
380
|
+
<div class="chart"><pre class="mermaid">
|
|
381
|
+
${esc(renderMermaid(g))}
|
|
382
|
+
</pre></div>
|
|
383
|
+
<pre>${esc(renderOutline(g))}</pre>
|
|
384
|
+
<script type="module">
|
|
385
|
+
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
|
386
|
+
mermaid.initialize({ startOnLoad: true, theme: 'dark', maxTextSize: 500000, maxEdges: 5000, flowchart: { htmlLabels: true, curve: 'basis' } });
|
|
387
|
+
</script>
|
|
388
|
+
</body></html>
|
|
389
|
+
`;
|
|
390
|
+
}
|
|
391
|
+
//# sourceMappingURL=story-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"story-graph.js","sourceRoot":"","sources":["../../src/story/story-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAwC/D,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC9C,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtE,kFAAkF;AAClF,SAAS,SAAS,CAAC,IAAwB,EAAE,GAAG,GAAG,EAAE,EAAE,GAAuC;IAC5F,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,IAAI;SACf,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;SACtB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAS,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SAC1D,OAAO,CAAC,wBAAwB,EAAE,IAAI,CAAC;SACvC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IACV,OAAO,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9E,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,iBAAiB,CAAC,QAA4B;IAC5D,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QACjD,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAC1D,IAAI,EAAE;YAAE,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACzD,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,iBAAiB,CAAC,GAAuB;IACvD,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;QACvD,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,KAAK,CAAC;QACzD,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,KAAoB,EAAE,IAAY,EAAE,CAAS;IAChE,OAAO,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACrG,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAoB;IAClD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC3C,MAAM,KAAK,GAAgB,EAAE,CAAC;IAC9B,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,CAAC,IAAY,EAAyB,EAAE;QACrD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;QACpB,IAAI,IAAuB,CAAC;QAC5B,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,IAAI,GAAG,QAAQ,CAAC;aAC1C,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,IAAI,GAAG,OAAO,CAAC;aAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,IAAI,GAAG,OAAO,CAAC;aAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,IAAI,GAAG,IAAI,CAAC;aACvC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,IAAI,GAAG,MAAM,CAAC;aAC5C,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC;YAAE,IAAI,GAAG,SAAS,CAAC;;YACvD,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;QAEvE,MAAM,OAAO,GAAG,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QAC7C,IAAI,MAAM,CAAC,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzD,IAAI,OAAO,CAAC,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3D,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,OAAO,WAAW,CAAC,CAAC,KAAK,IAAI,eAAe,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxJ,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,OAAO;YAAE,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAE3E,IAAI,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;QACtD,IAAI,IAAI,KAAK,OAAO;YAAE,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,cAAc,CAAC,CAAC,IAAI,OAAO,CAAC;QACjF,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,IAAI,OAAO,CAAC;QACzE,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC;QAE9E,MAAM,IAAI,GAAc;YACtB,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO;YAC5B,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC;YACzC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;YACnD,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,SAAS;SACxC,CAAC;QACF,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE;QAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO;QAC/C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,IAAI,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,IAAI,KAAK,QAAQ,CAAC;QAElD,+FAA+F;QAC/F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;YACnD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACnC,IAAI,CAAC,GAAG,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAS;YACvD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAChG,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAChH,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,SAAS;gBAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;gBACxG,KAAK,CAAC,CAAC,CAAC,CAAC;YACX,CAAC;QACH,CAAC;QACD,+FAA+F;QAC/F,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC9B,IAAI,CAAC,MAAM;gBAAE,SAAS;YACtB,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;mBAC9D,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC3F,IAAI,SAAS,EAAE,CAAC;gBACd,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACrE,KAAK,CAAC,GAAG,CAAC,CAAC;YACb,CAAC;iBAAM,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC1D,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBACpE,SAAS,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;QACD,8EAA8E;QAC9E,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7B,KAAK,MAAM,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;gBAC9C,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACxB,IAAI,CAAC,EAAE;oBAAE,SAAS;gBAClB,MAAM,IAAI,GAAG,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;gBACvF,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;oBAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;oBAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAAC,CAAC;gBACvH,KAAK,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,aAAa,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAU,EAAE,CAAC;oBAC5H,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;wBAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;wBAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC;oBAAC,CAAC;gBAC7H,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE;QACjC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO;QAC/C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,KAAK,MAAM,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;YAClE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,SAAS;YAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YACrE,KAAK,CAAC,CAAC,CAAC,CAAC;QACX,CAAC;IACH,CAAC,CAAC;IAEF,8GAA8G;IAC9G,MAAM,KAAK,GAAwB,EAAE,CAAC;IACtC,MAAM,QAAQ,GAA6C,EAAE,CAAC;IAC9D,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3F,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,YAAY,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC;IAC5G,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAQ,CAAC,IAAI,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,EAAE;YAAE,SAAS;QACxB,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC9F,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACzG,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACxD,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,iFAAiF;IACjF,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,GAAG,KAAK,CAAC;QACb,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM;mBACvD,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACnG,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC;oBAAE,SAAS;gBAChE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;gBAC/E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;oBAAE,IAAI,GAAG,IAAI,CAAC;gBACvC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,EAAE;SAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SAC5E,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEpB,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AACtF,CAAC;AAED,MAAM,IAAI,GAAsC;IAC9C,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG;CAChG,CAAC;AAEF,SAAS,QAAQ,CAAC,CAAY;IAC5B,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,CAAC,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IACnD,IAAI,CAAC,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;IACnD,IAAI,OAAO,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1D,IAAI,CAAC,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AASD,6FAA6F;AAC7F,MAAM,UAAU,aAAa,CAAC,CAAa,EAAE,OAAuB,EAAE;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;IACrC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK;QAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEhF,oGAAoG;IACpG,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,MAAc,EAAE,IAAY,EAAE,EAAE;QACzE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAAC,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3C,mFAAmF;QACnF,IAAI,IAAI,KAAK,IAAI;YAAE,MAAM,IAAI,IAAI,CAAC;QAClC,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;YAAC,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACrD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,CAAY,EAAE,IAAa,EAAE,EAAE;YAC9C,IAAI,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC;YACpF,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI;gBAAE,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,qBAAqB,CAAC;YACjG,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QACF,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YACzE,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,GAAG,MAAM,IAAI,CAAC;QAC5B,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;YACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;iBACvF,CAAC;gBACJ,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC/C,KAAK,MAAM,CAAC,IAAI,KAAK;oBAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,EAAE,IAAI,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,MAAM,YAAY,CAAC,CAAC,KAAK,CAAC,MAAM,cAAc,CAAC,CAAC;IACrK,GAAG,CAAC,IAAI,CAAC,qJAAqJ,CAAC,CAAC;IAChK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7B,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACxB,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;YACjC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC5D,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;YAC9B,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACtF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC5G,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnF,CAAC;QACH,CAAC;QACD,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,qBAAqB,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AAC7E,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,aAAa,CAAC,CAAa;IACzC,MAAM,KAAK,GAAG,CAAC,cAAc,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,CAAC,CAAY,EAAE,EAAE;QAC7B,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,CAAC;QAC5C,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,QAAQ,CAAC,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC;YACpC,KAAK,OAAO,CAAC;YAAC,KAAK,SAAS,CAAC,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC;YACnD,KAAK,OAAO,CAAC;YAAC,KAAK,IAAI,CAAC;YAAC,KAAK,MAAM,CAAC,CAAC,OAAO,IAAI,IAAI,GAAG,CAAC;YACzD,KAAK,QAAQ,CAAC,CAAC,OAAO,IAAI,IAAI,GAAG,CAAC;YAClC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC;QACzD,CAAC;IACH,CAAC,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzH,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACtD,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QACnD,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9G,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;IACzF,KAAK,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;IACpE,KAAK,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;IACpE,KAAK,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;IACnE,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,IAA+B,EAAE,EAAE;QACzD,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3E,IAAI,GAAG,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC;IACF,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACrD,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC/B,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACxC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAC9E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,eAAe,CAAC,CAAa;IAC3C,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAChG,OAAO;;SAEA,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;;;;;;;;;cASP,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,CAAC,KAAK,CAAC,MAAM;;EAExF,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;;OAEhB,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;;;;;;CAM3B,CAAC;AACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thijshakkenberg/valkyrie-mom-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "MCP server for AI-assisted Mansions of Madness scenario creation with Valkyrie",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"extract-catalogs": "tsx src/catalogs/extract-catalogs.ts",
|
|
45
45
|
"lint": "tsc --noEmit",
|
|
46
46
|
"convert-tiles": "tsx scripts/convert-tile-images.ts",
|
|
47
|
-
"prepublishOnly": "npm run lint && npm run test && npm run build"
|
|
47
|
+
"prepublishOnly": "npm run lint && npm run test && npm run build",
|
|
48
|
+
"hermes:tools": "tsx scripts/export-hermes-tools.ts"
|
|
48
49
|
},
|
|
49
50
|
"dependencies": {
|
|
50
51
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
package/skills/scenario/SKILL.md
CHANGED
|
@@ -90,6 +90,7 @@ Use `set_localization` to write all text:
|
|
|
90
90
|
### Step 9: Validate & Build
|
|
91
91
|
|
|
92
92
|
1. `validate_scenario` - fix any errors reported
|
|
93
|
+
1. `story_graph` - read the storyline back as a condensed tree: check every branch leads somewhere, every ending is reachable, and nothing is listed under "Never reached"
|
|
93
94
|
2. `save_scenario` - write the files so Valkyrie's editor sees them (edits stay in memory until saved)
|
|
94
95
|
3. `build_scenario` - create the .valkyrie package, its manifest `.ini` and cover image (default `Desktop/<Package>/`, like Valkyrie's Create Package)
|
|
95
96
|
|
|
@@ -140,10 +140,10 @@ const isMainModule = process.argv[1] && (
|
|
|
140
140
|
);
|
|
141
141
|
|
|
142
142
|
if (isMainModule) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
'
|
|
146
|
-
);
|
|
143
|
+
// The Valkyrie source checkout, by default next to this repository
|
|
144
|
+
const valkyrieRepo = process.env.VALKYRIE_SOURCE_DIR
|
|
145
|
+
?? path.join(path.dirname(path.dirname(path.dirname(import.meta.dirname ?? '.'))), 'valkyrie');
|
|
146
|
+
const valkyrieContentDir = path.join(valkyrieRepo, 'unity', 'Assets', 'StreamingAssets', 'content', 'MoM');
|
|
147
147
|
|
|
148
148
|
if (!fs.existsSync(valkyrieContentDir)) {
|
|
149
149
|
console.error(`Valkyrie content not found at: ${valkyrieContentDir}`);
|
package/src/server.ts
CHANGED
|
@@ -34,6 +34,7 @@ import { getMapAscii, suggestTileLayout, placeTileRelative } from './tools/map.j
|
|
|
34
34
|
import { renderMap } from './map/render.js';
|
|
35
35
|
import { searchGameContent } from './tools/reference.js';
|
|
36
36
|
import { toPackageName, writePackageManifest } from './io/package-manifest.js';
|
|
37
|
+
import { buildStoryGraph, renderMermaid, renderOutline, renderStoryHtml } from './story/story-graph.js';
|
|
37
38
|
import { DEFAULT_COMFYUI_URL, generateArtwork, getArtworkStatus, setupInstructions } from './artwork/comfyui.js';
|
|
38
39
|
import {
|
|
39
40
|
EVENT_FORMAT_DOC,
|
|
@@ -313,6 +314,35 @@ export function createServer(): McpServer {
|
|
|
313
314
|
},
|
|
314
315
|
);
|
|
315
316
|
|
|
317
|
+
server.tool(
|
|
318
|
+
'story_graph',
|
|
319
|
+
'Project the scenario\'s storyline as a graph: what each button, trigger, placed token, item inspection and monster event leads to. '
|
|
320
|
+
+ 'format=outline (default) is a condensed text tree: one line per event with its first words, conditions (if ...), effects (variables, +placed/−removed) and END; straight chains stay on one level, decisions indent, repeats point back (↩), and endings and never-reached events are listed. '
|
|
321
|
+
+ 'format=mermaid gives a flowchart definition. outputPath (.html) writes a page with the rendered chart and the outline for people. Use it to review or explain the plot, and to find dead ends and loops',
|
|
322
|
+
{
|
|
323
|
+
format: z.enum(['outline', 'mermaid']).optional().describe('outline (default) or mermaid'),
|
|
324
|
+
root: z.string().optional().describe('Only the part of the story that follows this component (e.g. EventScream)'),
|
|
325
|
+
maxDepth: z.number().int().optional().describe('Stop expanding below this depth (default 30)'),
|
|
326
|
+
outputPath: z.string().optional().describe('Also write the result: .html (chart + outline page), .mmd/.md (Mermaid) or .txt (outline)'),
|
|
327
|
+
},
|
|
328
|
+
async ({ format, root, maxDepth, outputPath }) => {
|
|
329
|
+
const model = getModel();
|
|
330
|
+
if (root && !model.get(root)) throw new Error(`No component named "${root}"`);
|
|
331
|
+
const graph = buildStoryGraph(model);
|
|
332
|
+
const text = format === 'mermaid' ? renderMermaid(graph) : renderOutline(graph, { root, maxDepth });
|
|
333
|
+
let note = '';
|
|
334
|
+
if (outputPath) {
|
|
335
|
+
const file = path.isAbsolute(outputPath) || !model.scenarioDir ? outputPath : path.resolve(outputPath);
|
|
336
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
337
|
+
if (/\.html?$/i.test(file)) fs.writeFileSync(file, renderStoryHtml(graph));
|
|
338
|
+
else if (/\.(mmd|md)$/i.test(file)) fs.writeFileSync(file, file.endsWith('.md') ? `\`\`\`mermaid\n${renderMermaid(graph)}\n\`\`\`\n` : renderMermaid(graph));
|
|
339
|
+
else fs.writeFileSync(file, text);
|
|
340
|
+
note = `\n\nWritten to ${file}`;
|
|
341
|
+
}
|
|
342
|
+
return { content: [{ type: 'text', text: text + note }] };
|
|
343
|
+
},
|
|
344
|
+
);
|
|
345
|
+
|
|
316
346
|
// ── Artwork Tools ──
|
|
317
347
|
|
|
318
348
|
server.tool(
|
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
import { parseRefList } from '../model/component-types.js';
|
|
2
|
+
import type { ScenarioModel } from '../model/scenario-model.js';
|
|
3
|
+
import { computeReachability, isStartingItem } from '../validation/rules/game-flow.js';
|
|
4
|
+
import { checkTrigger } from '../validation/rules/triggers.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The storyline as a graph: what runs what, the way Valkyrie plays it. Nodes are components that
|
|
8
|
+
* run (events, puzzles, spawns) or that players click or inspect (tokens, UI buttons, items);
|
|
9
|
+
* edges are buttons, board items placed by `add`, item inspection, monster events and
|
|
10
|
+
* Defeated triggers. Rendered as a condensed outline for authors and agents, or as Mermaid.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export type EdgeKind = 'button' | 'places' | 'click' | 'inspect' | 'activation' | 'evade' | 'horror' | 'defeated';
|
|
14
|
+
|
|
15
|
+
export interface StoryEdge {
|
|
16
|
+
from: string;
|
|
17
|
+
to: string;
|
|
18
|
+
kind: EdgeKind;
|
|
19
|
+
/** Button text, or a short description of the connection */
|
|
20
|
+
label: string;
|
|
21
|
+
/** Several targets on one button: Valkyrie runs the first whose conditions pass, or a random one */
|
|
22
|
+
choice?: 'first' | 'random';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface StoryNode {
|
|
26
|
+
name: string;
|
|
27
|
+
kind: 'dialog' | 'hidden' | 'puzzle' | 'spawn' | 'token' | 'ui' | 'item' | 'monster';
|
|
28
|
+
summary: string;
|
|
29
|
+
conditions?: string;
|
|
30
|
+
effects: string[];
|
|
31
|
+
ending?: 'end';
|
|
32
|
+
trigger?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface StoryGraph {
|
|
36
|
+
title: string;
|
|
37
|
+
nodes: Map<string, StoryNode>;
|
|
38
|
+
edges: StoryEdge[];
|
|
39
|
+
/** Entry points: triggers, and items held from the start */
|
|
40
|
+
roots: Array<{ label: string; node: string }>;
|
|
41
|
+
unreachable: string[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const RUNNABLE = ['Event', 'Puzzle', 'Spawn'];
|
|
45
|
+
const isRunnable = (n: string) => RUNNABLE.some(p => n.startsWith(p));
|
|
46
|
+
|
|
47
|
+
/** Localized text as one short line: markup stripped, text codes kept readable */
|
|
48
|
+
function summarize(text: string | undefined, max = 90, loc?: (k: string) => string | undefined): string {
|
|
49
|
+
if (!text || text.trim() === '.') return '';
|
|
50
|
+
const plain = text
|
|
51
|
+
.replace(/^\|\|\|/, '')
|
|
52
|
+
.replace(/<[^>]+>/g, '')
|
|
53
|
+
.replace(/\\n|\n/g, ' ')
|
|
54
|
+
.replace(/\{qst:(\w+)\}/g, (_, k: string) => loc?.(k) ?? k)
|
|
55
|
+
.replace(/\{(?:c|var):([^}]+)\}/g, '$1')
|
|
56
|
+
.replace(/\s+/g, ' ')
|
|
57
|
+
.trim();
|
|
58
|
+
return plain.length > max ? `${plain.slice(0, max - 1).trimEnd()}…` : plain;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** "VarOperation:a,==,1 VarTestsLogicalOperator:AND VarOperation:b,>=,2" → "a==1 AND b>=2" */
|
|
62
|
+
export function compactConditions(vartests: string | undefined): string | undefined {
|
|
63
|
+
if (!vartests?.trim()) return undefined;
|
|
64
|
+
const parts = vartests.trim().split(/\s+/).map(t => {
|
|
65
|
+
const op = t.match(/^VarOperation:([^,]+),([^,]+),(.+)$/);
|
|
66
|
+
if (op) return `${op[1]}${op[2]}${op[3]}`;
|
|
67
|
+
const logic = t.match(/^VarTestsLogicalOperator:(\w+)$/);
|
|
68
|
+
if (logic) return logic[1];
|
|
69
|
+
return t.replace(/^VarTests\w*:/, '');
|
|
70
|
+
});
|
|
71
|
+
return parts.join(' ');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** "Suspicion,+,1 $end,=,1" → ["Suspicion+=1", "END"] */
|
|
75
|
+
export function compactOperations(ops: string | undefined): string[] {
|
|
76
|
+
return (ops ?? '').split(/\s+/).filter(Boolean).map(op => {
|
|
77
|
+
const [v, o, x] = op.split(',');
|
|
78
|
+
if (v === '$end' && o === '=' && x !== '0') return 'END';
|
|
79
|
+
if (o === '=') return `${v}=${x}`;
|
|
80
|
+
return `${v}${o}=${x}`;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function buttonLabel(model: ScenarioModel, name: string, i: number): string {
|
|
85
|
+
return summarize(model.localization.get(`${name}.button${i}`), 40, k => model.localization.get(k));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function buildStoryGraph(model: ScenarioModel): StoryGraph {
|
|
89
|
+
const nodes = new Map<string, StoryNode>();
|
|
90
|
+
const edges: StoryEdge[] = [];
|
|
91
|
+
const loc = (k: string) => model.localization.get(k);
|
|
92
|
+
|
|
93
|
+
const ensure = (name: string): StoryNode | undefined => {
|
|
94
|
+
const existing = nodes.get(name);
|
|
95
|
+
if (existing) return existing;
|
|
96
|
+
const comp = model.get(name);
|
|
97
|
+
if (!comp) return undefined;
|
|
98
|
+
const d = comp.data;
|
|
99
|
+
let kind: StoryNode['kind'];
|
|
100
|
+
if (name.startsWith('Puzzle')) kind = 'puzzle';
|
|
101
|
+
else if (name.startsWith('Spawn')) kind = 'spawn';
|
|
102
|
+
else if (name.startsWith('Token')) kind = 'token';
|
|
103
|
+
else if (name.startsWith('UI')) kind = 'ui';
|
|
104
|
+
else if (name.startsWith('QItem')) kind = 'item';
|
|
105
|
+
else if (name.startsWith('CustomMonster')) kind = 'monster';
|
|
106
|
+
else kind = d.display?.toLowerCase() === 'false' ? 'hidden' : 'dialog';
|
|
107
|
+
|
|
108
|
+
const effects = compactOperations(d.operations);
|
|
109
|
+
const placed = parseRefList(d.add ?? '');
|
|
110
|
+
const removed = parseRefList(d.remove ?? '');
|
|
111
|
+
if (placed.length) effects.push(`+${placed.join(' +')}`);
|
|
112
|
+
if (removed.length) effects.push(`−${removed.join(' −')}`);
|
|
113
|
+
if (kind === 'puzzle') effects.unshift(`${d.class ?? 'slide'} puzzle ${d.skill ?? '{observation}'}${d.puzzlesolution ? ` = ${d.puzzlesolution}` : ''}`);
|
|
114
|
+
if (kind === 'spawn' && d.monster) effects.unshift(`monster ${d.monster}`);
|
|
115
|
+
|
|
116
|
+
let summary = summarize(loc(`${name}.text`), 80, loc);
|
|
117
|
+
if (kind === 'spawn') summary = summarize(loc(`${name}.uniquetitle`)) || summary;
|
|
118
|
+
if (kind === 'ui') summary = summarize(loc(`${name}.uitext`)) || summary;
|
|
119
|
+
if (kind === 'monster') summary = summarize(loc(`${name}.monstername`)) || '';
|
|
120
|
+
|
|
121
|
+
const node: StoryNode = {
|
|
122
|
+
name, kind, summary, effects,
|
|
123
|
+
conditions: compactConditions(d.vartests),
|
|
124
|
+
ending: effects.includes('END') ? 'end' : undefined,
|
|
125
|
+
trigger: d.trigger?.trim() || undefined,
|
|
126
|
+
};
|
|
127
|
+
nodes.set(name, node);
|
|
128
|
+
return node;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const visited = new Set<string>();
|
|
132
|
+
const visit = (name: string) => {
|
|
133
|
+
if (visited.has(name) || !ensure(name)) return;
|
|
134
|
+
visited.add(name);
|
|
135
|
+
const d = model.get(name)!.data;
|
|
136
|
+
const buttons = Math.max(parseInt(d.buttons ?? '0', 10) || 0, 1);
|
|
137
|
+
const hidden = nodes.get(name)!.kind === 'hidden';
|
|
138
|
+
|
|
139
|
+
// Buttons (hidden events always follow button 1; tokens and UI run their buttons when clicked)
|
|
140
|
+
for (let i = 1; i <= 6; i++) {
|
|
141
|
+
const targets = parseRefList(d[`event${i}`] ?? '');
|
|
142
|
+
if (targets.length === 0) continue;
|
|
143
|
+
if (i > buttons && !name.startsWith('Token')) continue;
|
|
144
|
+
const label = hidden ? '' : (buttonLabel(model, name, i) || (buttons > 1 ? `button ${i}` : ''));
|
|
145
|
+
const choice = targets.length > 1 ? (d.randomevents?.toLowerCase() === 'true' ? 'random' : 'first') : undefined;
|
|
146
|
+
for (const t of targets) {
|
|
147
|
+
if (!model.get(t)) continue;
|
|
148
|
+
edges.push({ from: name, to: t, kind: name.startsWith('Puzzle') ? 'button' : 'button', label, choice });
|
|
149
|
+
visit(t);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Board items and items this component places: clicking or inspecting them continues the story
|
|
153
|
+
for (const ref of parseRefList(d.add ?? '')) {
|
|
154
|
+
const target = model.get(ref);
|
|
155
|
+
if (!target) continue;
|
|
156
|
+
const clickable = (ref.startsWith('Token') || ref.startsWith('UI'))
|
|
157
|
+
&& [1, 2, 3, 4, 5, 6].some(i => parseRefList(target.data[`event${i}`] ?? '').length > 0);
|
|
158
|
+
if (clickable) {
|
|
159
|
+
edges.push({ from: name, to: ref, kind: 'places', label: 'places' });
|
|
160
|
+
visit(ref);
|
|
161
|
+
} else if (ref.startsWith('QItem') && target.data.inspect) {
|
|
162
|
+
edges.push({ from: name, to: ref, kind: 'places', label: 'gives' });
|
|
163
|
+
visitItem(ref);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Monster phase, evade and horror events of what this spawn puts on the board
|
|
167
|
+
if (name.startsWith('Spawn')) {
|
|
168
|
+
for (const m of parseRefList(d.monster ?? '')) {
|
|
169
|
+
const cm = model.get(m);
|
|
170
|
+
if (!cm) continue;
|
|
171
|
+
const acts = parseRefList(cm.data.activation ?? '').filter(a => a.startsWith('Event'));
|
|
172
|
+
for (const a of acts) { edges.push({ from: name, to: a, kind: 'activation', label: 'each monster phase' }); visit(a); }
|
|
173
|
+
for (const [f, kind, label] of [['evadeevent', 'evade', 'on evade'], ['horrorevent', 'horror', 'on horror check']] as const) {
|
|
174
|
+
if (cm.data[f] && model.get(cm.data[f]!)) { edges.push({ from: name, to: cm.data[f]!, kind, label }); visit(cm.data[f]!); }
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
const visitItem = (item: string) => {
|
|
180
|
+
if (visited.has(item) || !ensure(item)) return;
|
|
181
|
+
visited.add(item);
|
|
182
|
+
for (const e of parseRefList(model.get(item)!.data.inspect ?? '')) {
|
|
183
|
+
if (!model.get(e)) continue;
|
|
184
|
+
edges.push({ from: item, to: e, kind: 'inspect', label: 'inspect' });
|
|
185
|
+
visit(e);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// Entry points: EventStart first, then other triggers, starting items; Defeated triggers hang off their spawn
|
|
190
|
+
const roots: StoryGraph['roots'] = [];
|
|
191
|
+
const defeated: Array<{ event: string; target: string }> = [];
|
|
192
|
+
const triggered = model.getAll().filter(c => c.data.trigger?.trim() && isRunnable(c.name));
|
|
193
|
+
triggered.sort((a, b) => Number(b.data.trigger === 'EventStart') - Number(a.data.trigger === 'EventStart'));
|
|
194
|
+
for (const comp of triggered) {
|
|
195
|
+
const trigger = comp.data.trigger!.trim();
|
|
196
|
+
const check = checkTrigger(model, trigger);
|
|
197
|
+
if (!check.ok) continue;
|
|
198
|
+
if (check.defeated) { defeated.push({ event: comp.name, target: check.defeated }); continue; }
|
|
199
|
+
roots.push({ label: trigger === 'EventStart' ? 'Game start' : `Trigger ${trigger}`, node: comp.name });
|
|
200
|
+
}
|
|
201
|
+
for (const r of roots) visit(r.node);
|
|
202
|
+
for (const item of model.getByType('QItem')) {
|
|
203
|
+
if (isStartingItem(item.data) && item.data.inspect) {
|
|
204
|
+
roots.push({ label: 'Starting item', node: item.name });
|
|
205
|
+
visitItem(item.name);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Defeated<X>: from each spawn that puts X (or a monster of type X) on the board
|
|
209
|
+
let grew = true;
|
|
210
|
+
while (grew) {
|
|
211
|
+
grew = false;
|
|
212
|
+
for (const t of defeated) {
|
|
213
|
+
const sources = [...nodes.keys()].filter(n => n === t.target
|
|
214
|
+
|| (n.startsWith('Spawn') && parseRefList(model.get(n)?.data.monster ?? '').includes(t.target)));
|
|
215
|
+
for (const s of sources) {
|
|
216
|
+
if (edges.some(e => e.from === s && e.to === t.event)) continue;
|
|
217
|
+
edges.push({ from: s, to: t.event, kind: 'defeated', label: 'when defeated' });
|
|
218
|
+
if (!visited.has(t.event)) grew = true;
|
|
219
|
+
visit(t.event);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const { runs } = computeReachability(model);
|
|
225
|
+
const unreachable = model.getAll()
|
|
226
|
+
.filter(c => isRunnable(c.name) && !visited.has(c.name) && !runs.has(c.name))
|
|
227
|
+
.map(c => c.name);
|
|
228
|
+
|
|
229
|
+
return { title: loc('quest.name') ?? 'Scenario', nodes, edges, roots, unreachable };
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const ICON: Record<StoryNode['kind'], string> = {
|
|
233
|
+
dialog: '▶', hidden: '·', puzzle: '◆', spawn: '☠', token: '⊕', ui: '▣', item: '✉', monster: '☠',
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
function nodeLine(n: StoryNode): string {
|
|
237
|
+
const parts = [`${ICON[n.kind]} ${n.name}`];
|
|
238
|
+
if (n.conditions) parts.push(`if ${n.conditions}`);
|
|
239
|
+
if (n.summary) parts.push(`"${n.summary}"`);
|
|
240
|
+
const effects = n.effects.filter(e => e !== 'END');
|
|
241
|
+
if (effects.length) parts.push(`⟨${effects.join(', ')}⟩`);
|
|
242
|
+
if (n.ending) parts.push('✦ END');
|
|
243
|
+
return parts.join(' ');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export interface OutlineOptions {
|
|
247
|
+
/** Start from this component instead of the scenario's entry points */
|
|
248
|
+
root?: string;
|
|
249
|
+
/** Stop expanding below this depth (default 30) */
|
|
250
|
+
maxDepth?: number;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** Condensed text projection: each component expanded once, later visits point back to it */
|
|
254
|
+
export function renderOutline(g: StoryGraph, opts: OutlineOptions = {}): string {
|
|
255
|
+
const maxDepth = opts.maxDepth ?? 30;
|
|
256
|
+
const out: string[] = [];
|
|
257
|
+
const printed = new Set<string>();
|
|
258
|
+
const byFrom = new Map<string, StoryEdge[]>();
|
|
259
|
+
for (const e of g.edges) byFrom.set(e.from, [...(byFrom.get(e.from) ?? []), e]);
|
|
260
|
+
|
|
261
|
+
// Straight chains stay on one level; only decisions (several buttons, choices, placed items) indent
|
|
262
|
+
const walk = (name: string, depth: number, indent: string, lead: string) => {
|
|
263
|
+
const n = g.nodes.get(name);
|
|
264
|
+
if (!n) return;
|
|
265
|
+
if (printed.has(name)) { out.push(`${indent}${lead}↩ ${name}`); return; }
|
|
266
|
+
printed.add(name);
|
|
267
|
+
out.push(`${indent}${lead}${nodeLine(n)}`);
|
|
268
|
+
// What follows a "• " choice belongs to it, so it lines up under the choice's text
|
|
269
|
+
if (lead === '• ') indent += ' ';
|
|
270
|
+
if (depth >= maxDepth) { out.push(`${indent} …`); return; }
|
|
271
|
+
const groups = new Map<string, StoryEdge[]>();
|
|
272
|
+
for (const e of byFrom.get(name) ?? []) {
|
|
273
|
+
const key = `${e.kind}|${e.label}|${e.choice ?? ''}`;
|
|
274
|
+
groups.set(key, [...(groups.get(key) ?? []), e]);
|
|
275
|
+
}
|
|
276
|
+
const labelOf = (e: StoryEdge, many: boolean) => {
|
|
277
|
+
let label = e.kind === 'button' ? (e.label ? `[${e.label}]` : '→') : `(${e.label})`;
|
|
278
|
+
if (e.choice && many) label += e.choice === 'random' ? ' one at random:' : ' first that passes:';
|
|
279
|
+
return label;
|
|
280
|
+
};
|
|
281
|
+
const list = [...groups.values()];
|
|
282
|
+
if (list.length === 1 && list[0].length === 1) {
|
|
283
|
+
walk(list[0][0].to, depth + 1, indent, `${labelOf(list[0][0], false)} `);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const inner = `${indent} `;
|
|
287
|
+
for (const group of list) {
|
|
288
|
+
if (group.length === 1) walk(group[0].to, depth + 1, inner, `${labelOf(group[0], false)} `);
|
|
289
|
+
else {
|
|
290
|
+
out.push(`${inner}${labelOf(group[0], true)}`);
|
|
291
|
+
for (const t of group) walk(t.to, depth + 1, `${inner} `, '• ');
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
out.push(`Storyline of "${g.title}": ${[...g.nodes.values()].filter(n => n.kind === 'dialog' || n.kind === 'hidden').length} events, ${g.edges.length} connections`);
|
|
297
|
+
out.push('Legend: ▶ dialog · hidden event ◆ puzzle ☠ spawn/monster ⊕ token ▣ UI button ✉ item [button] → next ↩ already shown above ⟨effects⟩ ✦ END');
|
|
298
|
+
if (opts.root) {
|
|
299
|
+
out.push('');
|
|
300
|
+
walk(opts.root, 0, '', '');
|
|
301
|
+
} else {
|
|
302
|
+
for (const r of g.roots) {
|
|
303
|
+
out.push('', `== ${r.label} ==`);
|
|
304
|
+
walk(r.node, 0, '', '');
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (!opts.root) {
|
|
308
|
+
const endings = [...g.nodes.values()].filter(n => n.ending);
|
|
309
|
+
if (endings.length) {
|
|
310
|
+
out.push('', '== Endings ==');
|
|
311
|
+
const parents = (name: string) => g.edges.filter(e => e.to === name).map(e => e.from);
|
|
312
|
+
for (const n of endings) {
|
|
313
|
+
const via = parents(n.name).map(p => g.nodes.get(p)?.kind === 'hidden' ? parents(p).concat(p) : [p]).flat();
|
|
314
|
+
out.push(`✦ ${n.name}${via.length ? ` ← ${[...new Set(via)].join(', ')}` : ''}`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (g.unreachable.length) out.push('', '== Never reached ==', g.unreachable.join(', '));
|
|
318
|
+
}
|
|
319
|
+
return out.join('\n');
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function mermaidId(name: string): string {
|
|
323
|
+
return name.replace(/[^A-Za-z0-9_]/g, '_');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function mermaidText(s: string): string {
|
|
327
|
+
return s.replace(/"/g, "'").replace(/[<>]/g, '').replace(/[[\]{}|]/g, ' ');
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** Mermaid flowchart of the same graph */
|
|
331
|
+
export function renderMermaid(g: StoryGraph): string {
|
|
332
|
+
const lines = ['flowchart TD'];
|
|
333
|
+
const shape = (n: StoryNode) => {
|
|
334
|
+
const summary = n.summary ? `<br/><small>${mermaidText(n.summary.slice(0, 48))}</small>` : '';
|
|
335
|
+
const cond = n.conditions ? `<br/><i>if ${mermaidText(n.conditions)}</i>` : '';
|
|
336
|
+
const text = `"${n.name}${cond}${summary}"`;
|
|
337
|
+
switch (n.kind) {
|
|
338
|
+
case 'puzzle': return `{{${text}}}`;
|
|
339
|
+
case 'spawn': case 'monster': return `[/${text}/]`;
|
|
340
|
+
case 'token': case 'ui': case 'item': return `>${text}]`;
|
|
341
|
+
case 'hidden': return `(${text})`;
|
|
342
|
+
default: return n.ending ? `([${text}])` : `[${text}]`;
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
for (const r of g.roots) lines.push(` root_${mermaidId(r.node)}(("${mermaidText(r.label)}")) --> ${mermaidId(r.node)}`);
|
|
346
|
+
for (const n of g.nodes.values()) lines.push(` ${mermaidId(n.name)}${shape(n)}`);
|
|
347
|
+
for (const e of g.edges) {
|
|
348
|
+
const label = e.kind === 'button' ? e.label : e.label;
|
|
349
|
+
const arrow = e.kind === 'button' ? '-->' : '-.->';
|
|
350
|
+
lines.push(` ${mermaidId(e.from)} ${arrow}${label ? `|"${mermaidText(label)}"|` : ''} ${mermaidId(e.to)}`);
|
|
351
|
+
}
|
|
352
|
+
lines.push(' classDef hidden fill:#2a2a33,stroke:#666,color:#bbb,stroke-dasharray:3 3');
|
|
353
|
+
lines.push(' classDef ending fill:#4a1d1d,stroke:#d66,color:#fff');
|
|
354
|
+
lines.push(' classDef puzzle fill:#1d3a4a,stroke:#6bd,color:#fff');
|
|
355
|
+
lines.push(' classDef board fill:#3a341d,stroke:#db6,color:#fff');
|
|
356
|
+
const cls = (k: string, pred: (n: StoryNode) => boolean) => {
|
|
357
|
+
const ids = [...g.nodes.values()].filter(pred).map(n => mermaidId(n.name));
|
|
358
|
+
if (ids.length) lines.push(` class ${ids.join(',')} ${k}`);
|
|
359
|
+
};
|
|
360
|
+
cls('hidden', n => n.kind === 'hidden' && !n.ending);
|
|
361
|
+
cls('ending', n => !!n.ending);
|
|
362
|
+
cls('puzzle', n => n.kind === 'puzzle');
|
|
363
|
+
cls('board', n => n.kind === 'token' || n.kind === 'ui' || n.kind === 'item');
|
|
364
|
+
return lines.join('\n');
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** Self-contained page: the Mermaid chart (rendered in the browser) above the outline */
|
|
368
|
+
export function renderStoryHtml(g: StoryGraph): string {
|
|
369
|
+
const esc = (s: string) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
370
|
+
return `<!doctype html>
|
|
371
|
+
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
372
|
+
<title>${esc(g.title)} storyline</title>
|
|
373
|
+
<style>
|
|
374
|
+
:root { color-scheme: dark; }
|
|
375
|
+
body { margin: 0; background: #16161c; color: #e8e6e1; font: 15px/1.5 system-ui, sans-serif; }
|
|
376
|
+
header { padding: 20px 24px 8px; } h1 { margin: 0; font-size: 22px; } p { margin: 4px 0; color: #a9a6a0; }
|
|
377
|
+
.chart { overflow: auto; padding: 16px 24px; border-top: 1px solid #2c2c36; border-bottom: 1px solid #2c2c36; }
|
|
378
|
+
pre { margin: 0; padding: 16px 24px; white-space: pre-wrap; font: 13px/1.45 ui-monospace, Menlo, monospace; }
|
|
379
|
+
</style></head>
|
|
380
|
+
<body>
|
|
381
|
+
<header><h1>${esc(g.title)}</h1><p>Storyline: ${g.nodes.size} components, ${g.edges.length} connections. Solid arrows are buttons; dotted arrows are board items, inspection and monster events.</p></header>
|
|
382
|
+
<div class="chart"><pre class="mermaid">
|
|
383
|
+
${esc(renderMermaid(g))}
|
|
384
|
+
</pre></div>
|
|
385
|
+
<pre>${esc(renderOutline(g))}</pre>
|
|
386
|
+
<script type="module">
|
|
387
|
+
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
|
|
388
|
+
mermaid.initialize({ startOnLoad: true, theme: 'dark', maxTextSize: 500000, maxEdges: 5000, flowchart: { htmlLabels: true, curve: 'basis' } });
|
|
389
|
+
</script>
|
|
390
|
+
</body></html>
|
|
391
|
+
`;
|
|
392
|
+
}
|