simfile 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/README.md +143 -0
  2. package/dist/cli/index.d.ts +3 -0
  3. package/dist/cli/index.d.ts.map +1 -0
  4. package/dist/cli/index.js +348 -0
  5. package/dist/coverage/index.d.ts +2 -0
  6. package/dist/coverage/index.d.ts.map +1 -0
  7. package/dist/coverage/index.js +1 -0
  8. package/dist/coverage/matrix.d.ts +21 -0
  9. package/dist/coverage/matrix.d.ts.map +1 -0
  10. package/dist/coverage/matrix.js +173 -0
  11. package/dist/coverage/render.d.ts +3 -0
  12. package/dist/coverage/render.d.ts.map +1 -0
  13. package/dist/coverage/render.js +26 -0
  14. package/dist/index.d.ts +8 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +7 -0
  17. package/dist/kernel/duration.d.ts +9 -0
  18. package/dist/kernel/duration.d.ts.map +1 -0
  19. package/dist/kernel/duration.js +44 -0
  20. package/dist/kernel/index.d.ts +4 -0
  21. package/dist/kernel/index.d.ts.map +1 -0
  22. package/dist/kernel/index.js +3 -0
  23. package/dist/kernel/range.d.ts +6 -0
  24. package/dist/kernel/range.d.ts.map +1 -0
  25. package/dist/kernel/range.js +16 -0
  26. package/dist/kernel/stochastic.d.ts +10 -0
  27. package/dist/kernel/stochastic.d.ts.map +1 -0
  28. package/dist/kernel/stochastic.js +25 -0
  29. package/dist/ledger/index.d.ts +4 -0
  30. package/dist/ledger/index.d.ts.map +1 -0
  31. package/dist/ledger/index.js +3 -0
  32. package/dist/ledger/markers.d.ts +46 -0
  33. package/dist/ledger/markers.d.ts.map +1 -0
  34. package/dist/ledger/markers.js +108 -0
  35. package/dist/ledger/stable.d.ts +65 -0
  36. package/dist/ledger/stable.d.ts.map +1 -0
  37. package/dist/ledger/stable.js +78 -0
  38. package/dist/ledger/validation.d.ts +16 -0
  39. package/dist/ledger/validation.d.ts.map +1 -0
  40. package/dist/ledger/validation.js +127 -0
  41. package/dist/moltnet/index.d.ts +3 -0
  42. package/dist/moltnet/index.d.ts.map +1 -0
  43. package/dist/moltnet/index.js +2 -0
  44. package/dist/moltnet/transcript-export.d.ts +34 -0
  45. package/dist/moltnet/transcript-export.d.ts.map +1 -0
  46. package/dist/moltnet/transcript-export.js +68 -0
  47. package/dist/moltnet/world-participant.d.ts +77 -0
  48. package/dist/moltnet/world-participant.d.ts.map +1 -0
  49. package/dist/moltnet/world-participant.js +221 -0
  50. package/dist/observe/artifacts.d.ts +16 -0
  51. package/dist/observe/artifacts.d.ts.map +1 -0
  52. package/dist/observe/artifacts.js +31 -0
  53. package/dist/observe/causalStreams.d.ts +19 -0
  54. package/dist/observe/causalStreams.d.ts.map +1 -0
  55. package/dist/observe/causalStreams.js +38 -0
  56. package/dist/observe/compute.d.ts +17 -0
  57. package/dist/observe/compute.d.ts.map +1 -0
  58. package/dist/observe/compute.js +97 -0
  59. package/dist/observe/index.d.ts +11 -0
  60. package/dist/observe/index.d.ts.map +1 -0
  61. package/dist/observe/index.js +10 -0
  62. package/dist/observe/manifest.d.ts +79 -0
  63. package/dist/observe/manifest.d.ts.map +1 -0
  64. package/dist/observe/manifest.js +87 -0
  65. package/dist/observe/memoryBanks.d.ts +38 -0
  66. package/dist/observe/memoryBanks.d.ts.map +1 -0
  67. package/dist/observe/memoryBanks.js +86 -0
  68. package/dist/observe/observe.d.ts +32 -0
  69. package/dist/observe/observe.d.ts.map +1 -0
  70. package/dist/observe/observe.js +73 -0
  71. package/dist/observe/report.d.ts +165 -0
  72. package/dist/observe/report.d.ts.map +1 -0
  73. package/dist/observe/report.js +138 -0
  74. package/dist/observe/seedSpread.d.ts +49 -0
  75. package/dist/observe/seedSpread.d.ts.map +1 -0
  76. package/dist/observe/seedSpread.js +262 -0
  77. package/dist/observe/seedSpreadArtifacts.d.ts +49 -0
  78. package/dist/observe/seedSpreadArtifacts.d.ts.map +1 -0
  79. package/dist/observe/seedSpreadArtifacts.js +118 -0
  80. package/dist/observe/spreadMatcher.d.ts +45 -0
  81. package/dist/observe/spreadMatcher.d.ts.map +1 -0
  82. package/dist/observe/spreadMatcher.js +124 -0
  83. package/dist/report/index.d.ts +4 -0
  84. package/dist/report/index.d.ts.map +1 -0
  85. package/dist/report/index.js +3 -0
  86. package/dist/report/probeArtifact.d.ts +26 -0
  87. package/dist/report/probeArtifact.d.ts.map +1 -0
  88. package/dist/report/probeArtifact.js +119 -0
  89. package/dist/report/probes.d.ts +52 -0
  90. package/dist/report/probes.d.ts.map +1 -0
  91. package/dist/report/probes.js +164 -0
  92. package/dist/report/score.d.ts +27 -0
  93. package/dist/report/score.d.ts.map +1 -0
  94. package/dist/report/score.js +14 -0
  95. package/dist/report/transcripts.d.ts +12 -0
  96. package/dist/report/transcripts.d.ts.map +1 -0
  97. package/dist/report/transcripts.js +17 -0
  98. package/dist/runtime/causal-fixture.d.ts +26 -0
  99. package/dist/runtime/causal-fixture.d.ts.map +1 -0
  100. package/dist/runtime/causal-fixture.js +36 -0
  101. package/dist/runtime/clock.d.ts +25 -0
  102. package/dist/runtime/clock.d.ts.map +1 -0
  103. package/dist/runtime/clock.js +63 -0
  104. package/dist/runtime/condition.d.ts +55 -0
  105. package/dist/runtime/condition.d.ts.map +1 -0
  106. package/dist/runtime/condition.js +122 -0
  107. package/dist/runtime/emit-causal-fixture.d.ts +2 -0
  108. package/dist/runtime/emit-causal-fixture.d.ts.map +1 -0
  109. package/dist/runtime/emit-causal-fixture.js +45 -0
  110. package/dist/runtime/expression.d.ts +11 -0
  111. package/dist/runtime/expression.d.ts.map +1 -0
  112. package/dist/runtime/expression.js +305 -0
  113. package/dist/runtime/numeric.d.ts +7 -0
  114. package/dist/runtime/numeric.d.ts.map +1 -0
  115. package/dist/runtime/numeric.js +11 -0
  116. package/dist/runtime/rule-actions.d.ts +5 -0
  117. package/dist/runtime/rule-actions.d.ts.map +1 -0
  118. package/dist/runtime/rule-actions.js +82 -0
  119. package/dist/runtime/run-record.d.ts +73 -0
  120. package/dist/runtime/run-record.d.ts.map +1 -0
  121. package/dist/runtime/run-record.js +179 -0
  122. package/dist/runtime/step-tick.d.ts +43 -0
  123. package/dist/runtime/step-tick.d.ts.map +1 -0
  124. package/dist/runtime/step-tick.js +177 -0
  125. package/dist/runtime/trace-compile.d.ts +66 -0
  126. package/dist/runtime/trace-compile.d.ts.map +1 -0
  127. package/dist/runtime/trace-compile.js +157 -0
  128. package/dist/runtime/trace-export.d.ts +5 -0
  129. package/dist/runtime/trace-export.d.ts.map +1 -0
  130. package/dist/runtime/trace-export.js +4 -0
  131. package/dist/runtime/trace-run.d.ts +15 -0
  132. package/dist/runtime/trace-run.d.ts.map +1 -0
  133. package/dist/runtime/trace-run.js +92 -0
  134. package/dist/runtime/trace.d.ts +10 -0
  135. package/dist/runtime/trace.d.ts.map +1 -0
  136. package/dist/runtime/trace.js +9 -0
  137. package/dist/runtime/types.d.ts +61 -0
  138. package/dist/runtime/types.d.ts.map +1 -0
  139. package/dist/runtime/types.js +1 -0
  140. package/dist/runtime/viewer-trace.d.ts +64 -0
  141. package/dist/runtime/viewer-trace.d.ts.map +1 -0
  142. package/dist/runtime/viewer-trace.js +164 -0
  143. package/dist/runtime/world-act.d.ts +55 -0
  144. package/dist/runtime/world-act.d.ts.map +1 -0
  145. package/dist/runtime/world-act.js +156 -0
  146. package/dist/schema/binding.d.ts +23 -0
  147. package/dist/schema/binding.d.ts.map +1 -0
  148. package/dist/schema/binding.js +249 -0
  149. package/dist/schema/index.d.ts +5 -0
  150. package/dist/schema/index.d.ts.map +1 -0
  151. package/dist/schema/index.js +4 -0
  152. package/dist/schema/model.d.ts +244 -0
  153. package/dist/schema/model.d.ts.map +1 -0
  154. package/dist/schema/model.js +222 -0
  155. package/dist/schema/parse.d.ts +10 -0
  156. package/dist/schema/parse.d.ts.map +1 -0
  157. package/dist/schema/parse.js +15 -0
  158. package/dist/schema/semantic.d.ts +3 -0
  159. package/dist/schema/semantic.d.ts.map +1 -0
  160. package/dist/schema/semantic.js +135 -0
  161. package/dist/sims/composeRunManifest.d.ts +54 -0
  162. package/dist/sims/composeRunManifest.d.ts.map +1 -0
  163. package/dist/sims/composeRunManifest.js +40 -0
  164. package/dist/sims/composedJungianSimDriver.d.ts +50 -0
  165. package/dist/sims/composedJungianSimDriver.d.ts.map +1 -0
  166. package/dist/sims/composedJungianSimDriver.js +199 -0
  167. package/dist/sims/composedOfficeSimDriver.d.ts +53 -0
  168. package/dist/sims/composedOfficeSimDriver.d.ts.map +1 -0
  169. package/dist/sims/composedOfficeSimDriver.js +162 -0
  170. package/dist/sims/exchangeWait.d.ts +56 -0
  171. package/dist/sims/exchangeWait.d.ts.map +1 -0
  172. package/dist/sims/exchangeWait.js +66 -0
  173. package/dist/sims/index.d.ts +14 -0
  174. package/dist/sims/index.d.ts.map +1 -0
  175. package/dist/sims/index.js +13 -0
  176. package/dist/sims/moltnetRoomClient.d.ts +47 -0
  177. package/dist/sims/moltnetRoomClient.d.ts.map +1 -0
  178. package/dist/sims/moltnetRoomClient.js +41 -0
  179. package/dist/sims/poll.d.ts +19 -0
  180. package/dist/sims/poll.d.ts.map +1 -0
  181. package/dist/sims/poll.js +23 -0
  182. package/dist/sims/spawnfileCli.d.ts +49 -0
  183. package/dist/sims/spawnfileCli.d.ts.map +1 -0
  184. package/dist/sims/spawnfileCli.js +90 -0
  185. package/dist/sims/spawnfileReceipts.d.ts +76 -0
  186. package/dist/sims/spawnfileReceipts.d.ts.map +1 -0
  187. package/dist/sims/spawnfileReceipts.js +107 -0
  188. package/dist/sims/worldDrivenOfficeSimDriver.d.ts +59 -0
  189. package/dist/sims/worldDrivenOfficeSimDriver.d.ts.map +1 -0
  190. package/dist/sims/worldDrivenOfficeSimDriver.js +182 -0
  191. package/dist/sims/worldLedgerWriter.d.ts +32 -0
  192. package/dist/sims/worldLedgerWriter.d.ts.map +1 -0
  193. package/dist/sims/worldLedgerWriter.js +39 -0
  194. package/dist/sims/worldSeedLint.d.ts +42 -0
  195. package/dist/sims/worldSeedLint.d.ts.map +1 -0
  196. package/dist/sims/worldSeedLint.js +73 -0
  197. package/dist/sims/worldTickIngest.d.ts +27 -0
  198. package/dist/sims/worldTickIngest.d.ts.map +1 -0
  199. package/dist/sims/worldTickIngest.js +35 -0
  200. package/dist/sims/worldTickLoop.d.ts +64 -0
  201. package/dist/sims/worldTickLoop.d.ts.map +1 -0
  202. package/dist/sims/worldTickLoop.js +122 -0
  203. package/dist/view/engineProvenance.d.ts +46 -0
  204. package/dist/view/engineProvenance.d.ts.map +1 -0
  205. package/dist/view/engineProvenance.js +76 -0
  206. package/dist/view/index.d.ts +14 -0
  207. package/dist/view/index.d.ts.map +1 -0
  208. package/dist/view/index.js +107 -0
  209. package/dist/view/membranes.d.ts +14 -0
  210. package/dist/view/membranes.d.ts.map +1 -0
  211. package/dist/view/membranes.js +127 -0
  212. package/dist/view/runDetect.d.ts +2 -0
  213. package/dist/view/runDetect.d.ts.map +1 -0
  214. package/dist/view/runDetect.js +47 -0
  215. package/dist/view/runRawArtifacts.d.ts +48 -0
  216. package/dist/view/runRawArtifacts.d.ts.map +1 -0
  217. package/dist/view/runRawArtifacts.js +143 -0
  218. package/dist/view/runTimeline.d.ts +24 -0
  219. package/dist/view/runTimeline.d.ts.map +1 -0
  220. package/dist/view/runTimeline.js +204 -0
  221. package/dist/view/runTimelineRecords.d.ts +42 -0
  222. package/dist/view/runTimelineRecords.d.ts.map +1 -0
  223. package/dist/view/runTimelineRecords.js +244 -0
  224. package/dist/view/runTimelineRefs.d.ts +27 -0
  225. package/dist/view/runTimelineRefs.d.ts.map +1 -0
  226. package/dist/view/runTimelineRefs.js +31 -0
  227. package/dist/view/runTimelineTypes.d.ts +99 -0
  228. package/dist/view/runTimelineTypes.d.ts.map +1 -0
  229. package/dist/view/runTimelineTypes.js +1 -0
  230. package/dist/view/runViewModel.d.ts +21 -0
  231. package/dist/view/runViewModel.d.ts.map +1 -0
  232. package/dist/view/runViewModel.js +66 -0
  233. package/dist/view/runViewModelCompute.d.ts +24 -0
  234. package/dist/view/runViewModelCompute.d.ts.map +1 -0
  235. package/dist/view/runViewModelCompute.js +157 -0
  236. package/dist/view/runViewModelTypes.d.ts +177 -0
  237. package/dist/view/runViewModelTypes.d.ts.map +1 -0
  238. package/dist/view/runViewModelTypes.js +1 -0
  239. package/dist/view/runWorldTrace.d.ts +97 -0
  240. package/dist/view/runWorldTrace.d.ts.map +1 -0
  241. package/dist/view/runWorldTrace.js +88 -0
  242. package/dist/view/server.d.ts +12 -0
  243. package/dist/view/server.d.ts.map +1 -0
  244. package/dist/view/server.js +306 -0
  245. package/package.json +65 -0
  246. package/web/dist/assets/index-CJHLjfsG.js +49 -0
  247. package/web/dist/assets/index-DJOsPsU8.css +1 -0
  248. package/web/dist/index.html +13 -0
  249. package/web/dist/models/AnimatedMushnub.glb +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seedSpreadArtifacts.d.ts","sourceRoot":"","sources":["../../src/observe/seedSpreadArtifacts.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAEH,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AA4BD;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,uBAAuB,EAAE,CAepG,CAAC;AAyBF;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,GACtC,QAAQ,MAAM,KACb,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAmBzC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAgB7F,CAAC"}
@@ -0,0 +1,118 @@
1
+ import { readFile, readdir } from "node:fs/promises";
2
+ import path from "node:path";
3
+ const walkFiles = async (root) => {
4
+ const entries = await readdir(root, { withFileTypes: true }).catch(() => []);
5
+ const files = [];
6
+ for (const entry of entries) {
7
+ const entryPath = path.join(root, entry.name);
8
+ if (entry.isDirectory()) {
9
+ files.push(...(await walkFiles(entryPath)));
10
+ }
11
+ else if (entry.isFile()) {
12
+ files.push(entryPath);
13
+ }
14
+ }
15
+ return files;
16
+ };
17
+ const messageText = (parts) => (parts ?? [])
18
+ .filter((part) => part.kind === "text" && typeof part.text === "string")
19
+ .map((part) => part.text)
20
+ .join(" ");
21
+ /**
22
+ * Reads every `transcript.json` under `<runDir>/raw/moltnet/**` (today a
23
+ * single file; globbed so a future multi-network export nesting transcripts
24
+ * per network/room still gets picked up) and flattens every conversation's
25
+ * messages to `{id, fromId, text}`. Only the `moltnet.transcript-export.v1`
26
+ * export shape (`{conversations:[{messages}]}`) is read here — the seed-spread
27
+ * path only ever runs against a real composed/world-driven run, never the
28
+ * hand-authored golden-fixture shape (which never carries `seed_declaration`).
29
+ */
30
+ export const readSpreadTranscriptMessages = async (runDir) => {
31
+ const moltnetDir = path.join(runDir, "raw", "moltnet");
32
+ const files = (await walkFiles(moltnetDir)).filter((file) => file.endsWith("transcript.json")).sort();
33
+ const messages = [];
34
+ for (const file of files) {
35
+ const raw = JSON.parse(await readFile(file, "utf8"));
36
+ for (const conversation of raw.conversations ?? []) {
37
+ for (const message of conversation.messages ?? []) {
38
+ if (typeof message.id !== "string")
39
+ continue;
40
+ messages.push({ id: message.id, fromId: message.from?.id, text: messageText(message.parts) });
41
+ }
42
+ }
43
+ }
44
+ return messages;
45
+ };
46
+ /** Skips a line that fails to parse rather than crashing the whole read —
47
+ * these are diagnostic bank/tick artifacts, never the causal ledger itself. */
48
+ const parseJsonlLines = (text) => {
49
+ const parsed = [];
50
+ for (const rawLine of text.split(/\r?\n/u)) {
51
+ const line = rawLine.trim();
52
+ if (line.length === 0)
53
+ continue;
54
+ try {
55
+ parsed.push(JSON.parse(line));
56
+ }
57
+ catch {
58
+ continue;
59
+ }
60
+ }
61
+ return parsed;
62
+ };
63
+ /**
64
+ * Reads every mneme bank's `events.jsonl` (the write-side/interim signal —
65
+ * same file `memoryBanks.ts` falls back to) into `{id, type, agentId, text}`,
66
+ * keyed by bank directory name. Every field is read verbatim from the
67
+ * sealed file; a malformed line is skipped rather than crashing the whole
68
+ * read (mirrors this folder's "report, don't stitch" posture for a
69
+ * diagnostic-only artifact).
70
+ */
71
+ export const readSpreadMnemeEventsByBank = async (runDir) => {
72
+ const mnemeDir = path.join(runDir, "raw", "mneme");
73
+ const bankDirs = await readdir(mnemeDir, { withFileTypes: true }).catch(() => []);
74
+ const byBank = new Map();
75
+ for (const entry of bankDirs) {
76
+ if (!entry.isDirectory())
77
+ continue;
78
+ const text = await readFile(path.join(mnemeDir, entry.name, "events.jsonl"), "utf8").catch(() => null);
79
+ if (text === null)
80
+ continue;
81
+ const events = [];
82
+ for (const line of parseJsonlLines(text)) {
83
+ const row = line;
84
+ if (typeof row.id !== "string" || typeof row.type !== "string")
85
+ continue;
86
+ events.push({ id: row.id, type: row.type, agentId: row.principal?.agentId, text: row.content?.text ?? "" });
87
+ }
88
+ byBank.set(entry.name, events);
89
+ }
90
+ return byBank;
91
+ };
92
+ /**
93
+ * Reads `<runDir>/world/ingested-messages.jsonl` (note: NOT under `raw/` —
94
+ * `worldLedgerWriter.ts`'s own diagnostic, one line per tick,
95
+ * `{tick, message_ids}`) into a `message_id -> tick` map: the one exact,
96
+ * non-wall-clock fact the live world loop recorded about when it folded a
97
+ * given Moltnet message into the run. Absent entirely for a run that wasn't
98
+ * world-driven (batch `composedOfficeSimDriver`-style runs never write this
99
+ * file) — returns an empty map rather than failing.
100
+ */
101
+ export const readTickByIngestedMessageId = async (runDir) => {
102
+ const filePath = path.join(runDir, "world", "ingested-messages.jsonl");
103
+ const text = await readFile(filePath, "utf8").catch(() => null);
104
+ if (text === null)
105
+ return new Map();
106
+ const byMessageId = new Map();
107
+ for (const line of parseJsonlLines(text)) {
108
+ const row = line;
109
+ if (typeof row.tick !== "number" || !Array.isArray(row.message_ids))
110
+ continue;
111
+ for (const messageId of row.message_ids) {
112
+ if (typeof messageId === "string" && !byMessageId.has(messageId)) {
113
+ byMessageId.set(messageId, row.tick);
114
+ }
115
+ }
116
+ }
117
+ return byMessageId;
118
+ };
@@ -0,0 +1,45 @@
1
+ export declare const DEFAULT_EDIT_DISTANCE = 2;
2
+ export type ParsedSpreadMatcherPolicy = {
3
+ readonly kind: "exact";
4
+ } | {
5
+ readonly kind: "edit-distance";
6
+ readonly maxDistance: number;
7
+ };
8
+ export interface SpreadMatchResult {
9
+ matched: boolean;
10
+ /** Zero for a miss; otherwise the normalized closeness of the best match. */
11
+ fidelity: number;
12
+ }
13
+ export declare class UnsupportedSpreadMatcherPolicyError extends Error {
14
+ readonly policy: string;
15
+ constructor(policy: string);
16
+ }
17
+ export declare class InvalidSpreadMatcherPolicyError extends Error {
18
+ readonly policy: string;
19
+ constructor(policy: string);
20
+ }
21
+ /**
22
+ * Parses the manifest's pinned matcher policy. `edit-distance` defaults to
23
+ * k=2. `edit-distance:<k>` is the canonical parameterized spelling; the
24
+ * contract-style `edit-distance<=<k>` and `edit-distance≤<k>` spellings are
25
+ * accepted too. Bounds must be non-negative safe integers.
26
+ *
27
+ * Embedding/judge spellings are recognized but throw a typed error because
28
+ * this runtime-neutral build has no model with which to execute them.
29
+ */
30
+ export declare const parseSpreadMatcherPolicy: (policy: string) => ParsedSpreadMatcherPolicy;
31
+ /** Standard Levenshtein distance over Unicode code points, not UTF-16 units. */
32
+ export declare const levenshteinDistance: (left: string, right: string) => number;
33
+ /**
34
+ * Finds a seed occurrence under a pinned matcher policy.
35
+ *
36
+ * Exact matching delegates to `containsAlias`, preserving its case-insensitive
37
+ * Unicode word boundaries. Edit-distance matching NFC-normalizes and case-folds
38
+ * lexical words, then compares each token-set entry with viable contiguous text
39
+ * windows (punctuation/whitespace between words normalize to one space). A
40
+ * qualifying pair's fidelity is
41
+ * `1 - distance / max(codePointLength(candidate), codePointLength(seed))`;
42
+ * the highest qualifying fidelity wins.
43
+ */
44
+ export declare const matchSeedSpread: (text: string, tokenSet: readonly string[], matcherPolicy: string | ParsedSpreadMatcherPolicy) => SpreadMatchResult;
45
+ //# sourceMappingURL=spreadMatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spreadMatcher.d.ts","sourceRoot":"","sources":["../../src/observe/spreadMatcher.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,MAAM,MAAM,yBAAyB,GACjC;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,mCAAoC,SAAQ,KAAK;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM;CAK3B;AAED,qBAAa,+BAAgC,SAAQ,KAAK;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,MAAM;CAK3B;AAKD;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GAAI,QAAQ,MAAM,KAAG,yBAgBzD,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,OAAO,MAAM,KAAG,MAmBjE,CAAC;AAwDF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,MAAM,EACZ,UAAU,SAAS,MAAM,EAAE,EAC3B,eAAe,MAAM,GAAG,yBAAyB,KAChD,iBAaF,CAAC"}
@@ -0,0 +1,124 @@
1
+ import { containsAlias } from "../ledger/markers.js";
2
+ export const DEFAULT_EDIT_DISTANCE = 2;
3
+ export class UnsupportedSpreadMatcherPolicyError extends Error {
4
+ policy;
5
+ constructor(policy) {
6
+ super(`unsupported policy in this build: "${policy}" requires an embedding or judge model`);
7
+ this.name = "UnsupportedSpreadMatcherPolicyError";
8
+ this.policy = policy;
9
+ }
10
+ }
11
+ export class InvalidSpreadMatcherPolicyError extends Error {
12
+ policy;
13
+ constructor(policy) {
14
+ super(`invalid seed spread matcher policy: "${policy}"`);
15
+ this.name = "InvalidSpreadMatcherPolicyError";
16
+ this.policy = policy;
17
+ }
18
+ }
19
+ const EDIT_DISTANCE_POLICY = /^edit-distance(?:\s*(?::|<=|≤)\s*(\d+))?$/u;
20
+ const EMBEDDING_POLICY = /^embedding(?:$|\s*(?::|>=|≥))/u;
21
+ /**
22
+ * Parses the manifest's pinned matcher policy. `edit-distance` defaults to
23
+ * k=2. `edit-distance:<k>` is the canonical parameterized spelling; the
24
+ * contract-style `edit-distance<=<k>` and `edit-distance≤<k>` spellings are
25
+ * accepted too. Bounds must be non-negative safe integers.
26
+ *
27
+ * Embedding/judge spellings are recognized but throw a typed error because
28
+ * this runtime-neutral build has no model with which to execute them.
29
+ */
30
+ export const parseSpreadMatcherPolicy = (policy) => {
31
+ const normalized = policy.trim();
32
+ if (normalized === "exact")
33
+ return { kind: "exact" };
34
+ const editDistance = EDIT_DISTANCE_POLICY.exec(normalized);
35
+ if (editDistance) {
36
+ const maxDistance = editDistance[1] === undefined ? DEFAULT_EDIT_DISTANCE : Number(editDistance[1]);
37
+ if (Number.isSafeInteger(maxDistance))
38
+ return { kind: "edit-distance", maxDistance };
39
+ throw new InvalidSpreadMatcherPolicyError(policy);
40
+ }
41
+ if (EMBEDDING_POLICY.test(normalized) || normalized === "judge" || normalized === "judge-model") {
42
+ throw new UnsupportedSpreadMatcherPolicyError(policy);
43
+ }
44
+ throw new InvalidSpreadMatcherPolicyError(policy);
45
+ };
46
+ /** Standard Levenshtein distance over Unicode code points, not UTF-16 units. */
47
+ export const levenshteinDistance = (left, right) => {
48
+ const leftPoints = [...left];
49
+ const rightPoints = [...right];
50
+ let previous = Array.from({ length: rightPoints.length + 1 }, (_, index) => index);
51
+ for (let leftIndex = 1; leftIndex <= leftPoints.length; leftIndex += 1) {
52
+ const current = [leftIndex];
53
+ for (let rightIndex = 1; rightIndex <= rightPoints.length; rightIndex += 1) {
54
+ const substitutionCost = leftPoints[leftIndex - 1] === rightPoints[rightIndex - 1] ? 0 : 1;
55
+ current[rightIndex] = Math.min(current[rightIndex - 1] + 1, previous[rightIndex] + 1, previous[rightIndex - 1] + substitutionCost);
56
+ }
57
+ previous = current;
58
+ }
59
+ return previous[rightPoints.length];
60
+ };
61
+ const lexicalWords = (value) => (value.normalize("NFC").match(/[\p{L}\p{M}\p{N}_]+/gu) ?? []).map((word) => word.toLowerCase());
62
+ const codePointLength = (value) => [...value].length;
63
+ const bestWindowMatch = (textWords, seedWords, maxDistance) => {
64
+ let matched = false;
65
+ let bestFidelity = 0;
66
+ const normalizedSeed = seedWords.join(" ");
67
+ const seedLength = codePointLength(normalizedSeed);
68
+ for (let start = 0; start < textWords.length; start += 1) {
69
+ const candidateWords = [];
70
+ for (let end = start; end < textWords.length; end += 1) {
71
+ candidateWords.push(textWords[end]);
72
+ const candidate = candidateWords.join(" ");
73
+ const candidateLength = codePointLength(candidate);
74
+ if (candidateLength > seedLength + maxDistance)
75
+ break;
76
+ if (Math.abs(candidateLength - seedLength) > maxDistance)
77
+ continue;
78
+ const distance = levenshteinDistance(candidate, normalizedSeed);
79
+ if (distance > maxDistance)
80
+ continue;
81
+ matched = true;
82
+ const denominator = Math.max(candidateLength, seedLength);
83
+ const fidelity = denominator === 0 ? 1 : 1 - distance / denominator;
84
+ bestFidelity = Math.max(bestFidelity, fidelity);
85
+ }
86
+ }
87
+ return { matched, fidelity: matched ? bestFidelity : 0 };
88
+ };
89
+ const editDistanceMatch = (text, tokenSet, maxDistance) => {
90
+ const textWords = lexicalWords(text);
91
+ let bestMatch = { matched: false, fidelity: 0 };
92
+ for (const token of tokenSet) {
93
+ const seedWords = lexicalWords(token);
94
+ if (seedWords.length === 0)
95
+ continue;
96
+ const aliasMatch = bestWindowMatch(textWords, seedWords, maxDistance);
97
+ if (aliasMatch.matched && (!bestMatch.matched || aliasMatch.fidelity > bestMatch.fidelity)) {
98
+ bestMatch = aliasMatch;
99
+ }
100
+ }
101
+ return bestMatch;
102
+ };
103
+ /**
104
+ * Finds a seed occurrence under a pinned matcher policy.
105
+ *
106
+ * Exact matching delegates to `containsAlias`, preserving its case-insensitive
107
+ * Unicode word boundaries. Edit-distance matching NFC-normalizes and case-folds
108
+ * lexical words, then compares each token-set entry with viable contiguous text
109
+ * windows (punctuation/whitespace between words normalize to one space). A
110
+ * qualifying pair's fidelity is
111
+ * `1 - distance / max(codePointLength(candidate), codePointLength(seed))`;
112
+ * the highest qualifying fidelity wins.
113
+ */
114
+ export const matchSeedSpread = (text, tokenSet, matcherPolicy) => {
115
+ const policy = typeof matcherPolicy === "string" ? parseSpreadMatcherPolicy(matcherPolicy) : matcherPolicy;
116
+ if (policy.kind === "edit-distance" && (!Number.isSafeInteger(policy.maxDistance) || policy.maxDistance < 0)) {
117
+ throw new InvalidSpreadMatcherPolicyError(JSON.stringify(policy));
118
+ }
119
+ if (policy.kind === "exact") {
120
+ const matched = tokenSet.some((token) => containsAlias(text, token));
121
+ return { matched, fidelity: matched ? 1 : 0 };
122
+ }
123
+ return editDistanceMatch(text, tokenSet, policy.maxDistance);
124
+ };
@@ -0,0 +1,4 @@
1
+ export * from "./probes.js";
2
+ export * from "./score.js";
3
+ export * from "./transcripts.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./probes.js";
2
+ export * from "./score.js";
3
+ export * from "./transcripts.js";
@@ -0,0 +1,26 @@
1
+ import type { LedgerEvent } from "../ledger/markers.js";
2
+ export interface ProbeSample {
3
+ evidence_id?: string;
4
+ event_id?: string;
5
+ tick?: number;
6
+ sim_time?: number;
7
+ phase?: string;
8
+ variables?: Record<string, number>;
9
+ }
10
+ export interface ProbeArtifact {
11
+ events: readonly LedgerEvent[];
12
+ samples?: readonly ProbeSample[];
13
+ }
14
+ export interface ProbeOccurrence {
15
+ evidenceId: string;
16
+ simTime?: number;
17
+ tick?: number;
18
+ phase?: string;
19
+ variables?: Readonly<Record<string, number>>;
20
+ event?: LedgerEvent;
21
+ }
22
+ export declare const normalizeProbeArtifact: (input: readonly LedgerEvent[] | ProbeArtifact) => ProbeArtifact;
23
+ export declare const buildSampleOccurrences: (events: readonly LedgerEvent[], explicitSamples: readonly ProbeSample[]) => ProbeOccurrence[];
24
+ export declare const buildEventOccurrences: (events: readonly LedgerEvent[]) => ProbeOccurrence[];
25
+ export declare const attachVariablesToEventOccurrences: (events: readonly ProbeOccurrence[], samples: readonly ProbeOccurrence[]) => ProbeOccurrence[];
26
+ //# sourceMappingURL=probeArtifact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probeArtifact.d.ts","sourceRoot":"","sources":["../../src/report/probeArtifact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAqCD,eAAO,MAAM,sBAAsB,GAAI,OAAO,SAAS,WAAW,EAAE,GAAG,aAAa,KAAG,aAMtF,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,QAAQ,SAAS,WAAW,EAAE,EAC9B,iBAAiB,SAAS,WAAW,EAAE,KACtC,eAAe,EA0DjB,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,SAAS,WAAW,EAAE,KAAG,eAAe,EAwBrF,CAAC;AAEF,eAAO,MAAM,iCAAiC,GAC5C,QAAQ,SAAS,eAAe,EAAE,EAClC,SAAS,SAAS,eAAe,EAAE,KAClC,eAAe,EAcjB,CAAC"}
@@ -0,0 +1,119 @@
1
+ const isObject = (value) => typeof value === "object" && value !== null;
2
+ const evidenceId = (event, fallbackIndex) => event.event_id ?? `index:${fallbackIndex}`;
3
+ const clockSampleFromEvent = (event, index) => {
4
+ if (event.kind !== "clock.sync" || !isObject(event.payload)) {
5
+ return undefined;
6
+ }
7
+ const payload = event.payload;
8
+ const tick = typeof payload.tick === "number" && Number.isFinite(payload.tick) ? payload.tick : undefined;
9
+ const simTime = typeof event.sim_time === "number" && Number.isFinite(event.sim_time)
10
+ ? event.sim_time
11
+ : typeof payload.sim_time === "number" && Number.isFinite(payload.sim_time)
12
+ ? payload.sim_time
13
+ : undefined;
14
+ const phase = typeof payload.phase === "string" ? payload.phase : undefined;
15
+ return {
16
+ evidenceId: evidenceId(event, index),
17
+ tick,
18
+ simTime,
19
+ phase
20
+ };
21
+ };
22
+ const explicitSampleId = (sample, index) => sample.evidence_id ?? sample.event_id ?? `sample:${index}`;
23
+ export const normalizeProbeArtifact = (input) => {
24
+ if (Array.isArray(input)) {
25
+ return { events: input, samples: [] };
26
+ }
27
+ const artifact = input;
28
+ return { events: artifact.events, samples: artifact.samples ?? [] };
29
+ };
30
+ export const buildSampleOccurrences = (events, explicitSamples) => {
31
+ const clockSamples = events
32
+ .map((event, index) => clockSampleFromEvent(event, index))
33
+ .filter((sample) => sample !== undefined);
34
+ const explicitByTick = new Map();
35
+ const explicitByEvidence = new Map();
36
+ const matchedExplicit = new Set();
37
+ explicitSamples.forEach((sample, index) => {
38
+ if (sample.tick !== undefined && !explicitByTick.has(sample.tick)) {
39
+ explicitByTick.set(sample.tick, { sample, index });
40
+ }
41
+ const sampleId = explicitSampleId(sample, index);
42
+ if (!explicitByEvidence.has(sampleId)) {
43
+ explicitByEvidence.set(sampleId, { sample, index });
44
+ }
45
+ });
46
+ const normalized = clockSamples.map((clockSample) => {
47
+ const byEvidence = explicitByEvidence.get(clockSample.evidenceId);
48
+ const byTick = clockSample.tick !== undefined ? explicitByTick.get(clockSample.tick) : undefined;
49
+ const explicit = byEvidence ?? byTick;
50
+ if (explicit) {
51
+ matchedExplicit.add(explicit.index);
52
+ }
53
+ return {
54
+ evidenceId: explicit ? explicitSampleId(explicit.sample, explicit.index) : clockSample.evidenceId,
55
+ tick: explicit?.sample.tick ?? clockSample.tick,
56
+ simTime: explicit?.sample.sim_time ?? clockSample.simTime,
57
+ phase: explicit?.sample.phase ?? clockSample.phase,
58
+ variables: explicit?.sample.variables
59
+ };
60
+ });
61
+ explicitSamples.forEach((sample, index) => {
62
+ if (matchedExplicit.has(index)) {
63
+ return;
64
+ }
65
+ normalized.push({
66
+ evidenceId: explicitSampleId(sample, index),
67
+ tick: sample.tick,
68
+ simTime: sample.sim_time,
69
+ phase: sample.phase,
70
+ variables: sample.variables
71
+ });
72
+ });
73
+ return normalized.sort((left, right) => {
74
+ const leftTick = left.tick ?? Number.MAX_SAFE_INTEGER;
75
+ const rightTick = right.tick ?? Number.MAX_SAFE_INTEGER;
76
+ if (leftTick !== rightTick) {
77
+ return leftTick - rightTick;
78
+ }
79
+ const leftTime = left.simTime ?? Number.MAX_SAFE_INTEGER;
80
+ const rightTime = right.simTime ?? Number.MAX_SAFE_INTEGER;
81
+ return leftTime - rightTime;
82
+ });
83
+ };
84
+ export const buildEventOccurrences = (events) => {
85
+ const occurrences = [];
86
+ let activeTick;
87
+ let activePhase;
88
+ let activeSimTime;
89
+ events.forEach((event, index) => {
90
+ const clockSample = clockSampleFromEvent(event, index);
91
+ if (clockSample) {
92
+ activeTick = clockSample.tick;
93
+ activePhase = clockSample.phase;
94
+ activeSimTime = clockSample.simTime;
95
+ }
96
+ occurrences.push({
97
+ evidenceId: evidenceId(event, index),
98
+ simTime: event.sim_time ?? activeSimTime,
99
+ tick: activeTick,
100
+ phase: activePhase,
101
+ event
102
+ });
103
+ });
104
+ return occurrences;
105
+ };
106
+ export const attachVariablesToEventOccurrences = (events, samples) => {
107
+ const sampleByTick = new Map();
108
+ samples.forEach((sample) => {
109
+ if (sample.tick !== undefined && !sampleByTick.has(sample.tick)) {
110
+ sampleByTick.set(sample.tick, sample);
111
+ }
112
+ });
113
+ return events.map((event) => ({
114
+ ...event,
115
+ variables: event.tick !== undefined ? sampleByTick.get(event.tick)?.variables : undefined,
116
+ phase: event.tick !== undefined ? sampleByTick.get(event.tick)?.phase ?? event.phase : event.phase,
117
+ simTime: event.tick !== undefined ? sampleByTick.get(event.tick)?.simTime ?? event.simTime : event.simTime
118
+ }));
119
+ };
@@ -0,0 +1,52 @@
1
+ import type { LedgerEvent } from "../ledger/markers.js";
2
+ import { type ProbeArtifact } from "./probeArtifact.js";
3
+ export interface ProbeEventAtom {
4
+ event: string;
5
+ target?: string;
6
+ actor?: string;
7
+ scope?: string;
8
+ }
9
+ export interface ProbeVariableAtom {
10
+ variable: string;
11
+ above?: number;
12
+ below?: number;
13
+ for?: string;
14
+ }
15
+ export interface ProbePhaseAtom {
16
+ phase: string;
17
+ }
18
+ export interface ProbeAllNode {
19
+ all: readonly ProbeNode[];
20
+ }
21
+ export interface ProbeAnyNode {
22
+ any: readonly ProbeNode[];
23
+ }
24
+ export interface ProbeNotNode {
25
+ not: ProbeNode;
26
+ }
27
+ export type ProbeNode = ProbeEventAtom | ProbeVariableAtom | ProbePhaseAtom | ProbeAllNode | ProbeAnyNode | ProbeNotNode;
28
+ export type ProbeExpectation = {
29
+ at_least: number;
30
+ } | {
31
+ at_most: number;
32
+ } | {
33
+ always: true;
34
+ } | {
35
+ at_end: true;
36
+ };
37
+ export interface ProbeDefinition {
38
+ when: ProbeNode;
39
+ expect: ProbeExpectation;
40
+ after?: ProbeWhenCondition;
41
+ within?: string;
42
+ }
43
+ export type ProbeWhenCondition = ProbeNode;
44
+ export type { ProbeArtifact, ProbeSample } from "./probeArtifact.js";
45
+ export interface ProbeEvaluationResult {
46
+ probeId: string;
47
+ passed: boolean;
48
+ evidence: string[];
49
+ count: number;
50
+ }
51
+ export declare const evaluateProbe: (probeId: string, artifactOrEvents: readonly LedgerEvent[] | ProbeArtifact, probe: ProbeDefinition) => ProbeEvaluationResult;
52
+ //# sourceMappingURL=probes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probes.d.ts","sourceRoot":"","sources":["../../src/report/probes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAKL,KAAK,aAAa,EAGnB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,SAAS,SAAS,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,SAAS,SAAS,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,SAAS,CAAC;CAChB;AAED,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,iBAAiB,GAAG,cAAc,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,CAAC;AAEzH,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GACpB;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GACnB;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,GAChB;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,CAAC;AAErB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAE3C,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAErE,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAwKD,eAAO,MAAM,aAAa,GACxB,SAAS,MAAM,EACf,kBAAkB,SAAS,WAAW,EAAE,GAAG,aAAa,EACxD,OAAO,eAAe,KACrB,qBAoCF,CAAC"}