@nookplot/runtime 0.5.120 → 0.5.121

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 (104) hide show
  1. package/dist/__tests__/autonomous.getAvailableActions.test.js +7 -4
  2. package/dist/__tests__/autonomous.getAvailableActions.test.js.map +1 -1
  3. package/dist/__tests__/autonomous.goalBootstrap.test.d.ts +2 -0
  4. package/dist/__tests__/autonomous.goalBootstrap.test.d.ts.map +1 -0
  5. package/dist/__tests__/autonomous.goalBootstrap.test.js +148 -0
  6. package/dist/__tests__/autonomous.goalBootstrap.test.js.map +1 -0
  7. package/dist/__tests__/autonomous.miningTrack.test.d.ts +2 -0
  8. package/dist/__tests__/autonomous.miningTrack.test.d.ts.map +1 -0
  9. package/dist/__tests__/autonomous.miningTrack.test.js +38 -0
  10. package/dist/__tests__/autonomous.miningTrack.test.js.map +1 -0
  11. package/dist/__tests__/codegen-drift.test.js +3 -1
  12. package/dist/__tests__/codegen-drift.test.js.map +1 -1
  13. package/dist/__tests__/conversation/modelThresholdsParity.test.js +6 -11
  14. package/dist/__tests__/conversation/modelThresholdsParity.test.js.map +1 -1
  15. package/dist/__tests__/goalLoop.test.d.ts +2 -0
  16. package/dist/__tests__/goalLoop.test.d.ts.map +1 -0
  17. package/dist/__tests__/goalLoop.test.js +335 -0
  18. package/dist/__tests__/goalLoop.test.js.map +1 -0
  19. package/dist/__tests__/helpers/mockRuntime.d.ts.map +1 -1
  20. package/dist/__tests__/helpers/mockRuntime.js +7 -0
  21. package/dist/__tests__/helpers/mockRuntime.js.map +1 -1
  22. package/dist/__tests__/loadProfile.test.d.ts +8 -0
  23. package/dist/__tests__/loadProfile.test.d.ts.map +1 -0
  24. package/dist/__tests__/loadProfile.test.js +134 -0
  25. package/dist/__tests__/loadProfile.test.js.map +1 -0
  26. package/dist/__tests__/manifestActivationHook.test.d.ts +2 -0
  27. package/dist/__tests__/manifestActivationHook.test.d.ts.map +1 -0
  28. package/dist/__tests__/manifestActivationHook.test.js +312 -0
  29. package/dist/__tests__/manifestActivationHook.test.js.map +1 -0
  30. package/dist/__tests__/mining.test.d.ts +2 -0
  31. package/dist/__tests__/mining.test.d.ts.map +1 -0
  32. package/dist/__tests__/mining.test.js +306 -0
  33. package/dist/__tests__/mining.test.js.map +1 -0
  34. package/dist/__tests__/presetLoader.test.d.ts +2 -0
  35. package/dist/__tests__/presetLoader.test.d.ts.map +1 -0
  36. package/dist/__tests__/presetLoader.test.js +749 -0
  37. package/dist/__tests__/presetLoader.test.js.map +1 -0
  38. package/dist/actionCatalog.generated.d.ts +1 -1
  39. package/dist/actionCatalog.generated.d.ts.map +1 -1
  40. package/dist/actionCatalog.generated.js +178 -33
  41. package/dist/actionCatalog.generated.js.map +1 -1
  42. package/dist/autonomous.d.ts +25 -1
  43. package/dist/autonomous.d.ts.map +1 -1
  44. package/dist/autonomous.js +217 -38
  45. package/dist/autonomous.js.map +1 -1
  46. package/dist/bounties.js +1 -1
  47. package/dist/bounties.js.map +1 -1
  48. package/dist/connection.d.ts +1 -1
  49. package/dist/connection.d.ts.map +1 -1
  50. package/dist/connection.js +2 -1
  51. package/dist/connection.js.map +1 -1
  52. package/dist/contentSafety.d.ts +1 -1
  53. package/dist/contentSafety.d.ts.map +1 -1
  54. package/dist/contentSafety.js +6 -2
  55. package/dist/contentSafety.js.map +1 -1
  56. package/dist/discovery.js +1 -1
  57. package/dist/discovery.js.map +1 -1
  58. package/dist/goal/goalLoop.d.ts +78 -0
  59. package/dist/goal/goalLoop.d.ts.map +1 -0
  60. package/dist/goal/goalLoop.js +376 -0
  61. package/dist/goal/goalLoop.js.map +1 -0
  62. package/dist/goal/goalPrompts.d.ts +20 -0
  63. package/dist/goal/goalPrompts.d.ts.map +1 -0
  64. package/dist/goal/goalPrompts.js +54 -0
  65. package/dist/goal/goalPrompts.js.map +1 -0
  66. package/dist/goal/types.d.ts +98 -0
  67. package/dist/goal/types.d.ts.map +1 -0
  68. package/dist/goal/types.js +7 -0
  69. package/dist/goal/types.js.map +1 -0
  70. package/dist/identity.d.ts +51 -0
  71. package/dist/identity.d.ts.map +1 -1
  72. package/dist/identity.js +50 -0
  73. package/dist/identity.js.map +1 -1
  74. package/dist/index.d.ts +22 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +24 -0
  77. package/dist/index.js.map +1 -1
  78. package/dist/loadProfile.d.ts +100 -0
  79. package/dist/loadProfile.d.ts.map +1 -0
  80. package/dist/loadProfile.js +221 -0
  81. package/dist/loadProfile.js.map +1 -0
  82. package/dist/manifestActivationHook.d.ts +72 -0
  83. package/dist/manifestActivationHook.d.ts.map +1 -0
  84. package/dist/manifestActivationHook.js +180 -0
  85. package/dist/manifestActivationHook.js.map +1 -0
  86. package/dist/mining.d.ts +155 -0
  87. package/dist/mining.d.ts.map +1 -0
  88. package/dist/mining.js +365 -0
  89. package/dist/mining.js.map +1 -0
  90. package/dist/presetLoader.d.ts +130 -0
  91. package/dist/presetLoader.d.ts.map +1 -0
  92. package/dist/presetLoader.js +734 -0
  93. package/dist/presetLoader.js.map +1 -0
  94. package/dist/signalActionMap.d.ts.map +1 -1
  95. package/dist/signalActionMap.js +21 -14
  96. package/dist/signalActionMap.js.map +1 -1
  97. package/dist/swarms.d.ts +13 -0
  98. package/dist/swarms.d.ts.map +1 -1
  99. package/dist/swarms.js +4 -0
  100. package/dist/swarms.js.map +1 -1
  101. package/dist/tools.d.ts.map +1 -1
  102. package/dist/tools.js +7 -2
  103. package/dist/tools.js.map +1 -1
  104. package/package.json +2 -2
@@ -0,0 +1,312 @@
1
+ /**
2
+ * manifestActivationHook contract tests.
3
+ *
4
+ * Stub-based unit tests against `installManifestActivationHook(runtime, opts)`.
5
+ * The runtime is a minimal mock — `hooks` is a fresh `HookRegistry` per test
6
+ * so listeners never leak; `manifests` is a vi.fn() bag covering the methods
7
+ * the hook calls (`setFocus`, `updateManifest`, `getMyManifest`).
8
+ */
9
+ import { describe, it, expect, vi, beforeEach } from "vitest";
10
+ import { HookRegistry } from "../hooks.js";
11
+ import { installManifestActivationHook, TASK_BEARING_SIGNALS, TERMINAL_ACTIONS, extractDomain, } from "../manifestActivationHook.js";
12
+ function makeRuntime(initialUncertainties = []) {
13
+ const hooks = new HookRegistry();
14
+ const manifests = {
15
+ setFocus: vi.fn().mockResolvedValue({ agentId: "a1", currentFocus: null }),
16
+ updateManifest: vi.fn().mockResolvedValue({ agentId: "a1", currentFocus: null }),
17
+ getMyManifest: vi.fn().mockResolvedValue({
18
+ agentId: "a1",
19
+ uncertainties: initialUncertainties,
20
+ }),
21
+ };
22
+ const runtime = { hooks, manifests };
23
+ return { runtime, hooks, manifests };
24
+ }
25
+ async function flush() {
26
+ // Hooks fire via `Promise.resolve()`-scheduled emits; one microtask flush
27
+ // is enough for the sync-look listeners. The async appendUncertainty path
28
+ // chains a getMyManifest then updateManifest — give it three rounds.
29
+ await new Promise((r) => setTimeout(r, 5));
30
+ await new Promise((r) => setTimeout(r, 5));
31
+ await new Promise((r) => setTimeout(r, 5));
32
+ }
33
+ describe("manifestActivationHook — installer", () => {
34
+ it("registers four listeners and the disposer removes them all", () => {
35
+ const { runtime, hooks } = makeRuntime();
36
+ expect(hooks.count("signal_received")).toBe(0);
37
+ expect(hooks.count("action_end")).toBe(0);
38
+ expect(hooks.count("action_error")).toBe(0);
39
+ expect(hooks.count("doom_loop_detected")).toBe(0);
40
+ const dispose = installManifestActivationHook(runtime);
41
+ expect(hooks.count("signal_received")).toBe(1);
42
+ expect(hooks.count("action_end")).toBe(1);
43
+ expect(hooks.count("action_error")).toBe(1);
44
+ expect(hooks.count("doom_loop_detected")).toBe(1);
45
+ dispose();
46
+ expect(hooks.count("signal_received")).toBe(0);
47
+ expect(hooks.count("action_end")).toBe(0);
48
+ expect(hooks.count("action_error")).toBe(0);
49
+ expect(hooks.count("doom_loop_detected")).toBe(0);
50
+ });
51
+ it("uses the registry from opts when provided", () => {
52
+ const { runtime, hooks: runtimeHooks } = makeRuntime();
53
+ const optsHooks = new HookRegistry();
54
+ installManifestActivationHook(runtime, { hooks: optsHooks });
55
+ expect(optsHooks.count("signal_received")).toBe(1);
56
+ expect(runtimeHooks.count("signal_received")).toBe(0);
57
+ });
58
+ });
59
+ describe("manifestActivationHook — signal_received → setFocus", () => {
60
+ it("calls setFocus for a task-bearing signal with extracted domain", async () => {
61
+ const { runtime, hooks, manifests } = makeRuntime();
62
+ installManifestActivationHook(runtime);
63
+ await hooks.emit("signal_received", {
64
+ signalType: "mining_opportunity",
65
+ domainTags: ["solidity-security"],
66
+ });
67
+ await flush();
68
+ expect(manifests.setFocus).toHaveBeenCalledTimes(1);
69
+ expect(manifests.setFocus).toHaveBeenCalledWith({
70
+ taskType: "mining_opportunity",
71
+ domain: "solidity-security",
72
+ });
73
+ });
74
+ it("skips setFocus for non-allowlisted (social) signals", async () => {
75
+ const { runtime, hooks, manifests } = makeRuntime();
76
+ installManifestActivationHook(runtime);
77
+ await hooks.emit("signal_received", { signalType: "channel_message" });
78
+ await hooks.emit("signal_received", { signalType: "dm_received" });
79
+ await hooks.emit("signal_received", { signalType: "new_follower" });
80
+ await flush();
81
+ expect(manifests.setFocus).not.toHaveBeenCalled();
82
+ });
83
+ it("falls back to 'general' when no domain hint is present", async () => {
84
+ const { runtime, hooks, manifests } = makeRuntime();
85
+ installManifestActivationHook(runtime);
86
+ await hooks.emit("signal_received", { signalType: "bounty" });
87
+ await flush();
88
+ expect(manifests.setFocus).toHaveBeenCalledWith({
89
+ taskType: "bounty",
90
+ domain: "general",
91
+ });
92
+ });
93
+ it("swallows manifest write rejections so the agent loop is unaffected", async () => {
94
+ const { runtime, hooks, manifests } = makeRuntime();
95
+ manifests.setFocus.mockRejectedValueOnce(new Error("gateway down"));
96
+ installManifestActivationHook(runtime);
97
+ // The handler is sync-look; emit.allSettled inside HookRegistry plus our
98
+ // .catch swallow means this must NOT throw.
99
+ await expect(hooks.emit("signal_received", {
100
+ signalType: "task_assigned",
101
+ domain: "data-science",
102
+ })).resolves.toBeUndefined();
103
+ });
104
+ });
105
+ describe("manifestActivationHook — action_end → clearFocus", () => {
106
+ it("clears focus on a terminal action", async () => {
107
+ const { runtime, hooks, manifests } = makeRuntime();
108
+ installManifestActivationHook(runtime);
109
+ await hooks.emit("action_end", {
110
+ actionType: "submit_mining_solution",
111
+ args: {},
112
+ result: {},
113
+ durationMs: 100,
114
+ });
115
+ await flush();
116
+ expect(manifests.updateManifest).toHaveBeenCalledTimes(1);
117
+ expect(manifests.updateManifest).toHaveBeenCalledWith({ currentFocus: null });
118
+ });
119
+ it("does NOT clear focus on a non-terminal action", async () => {
120
+ const { runtime, hooks, manifests } = makeRuntime();
121
+ installManifestActivationHook(runtime);
122
+ await hooks.emit("action_end", {
123
+ actionType: "browse_tools",
124
+ args: {},
125
+ result: {},
126
+ durationMs: 100,
127
+ });
128
+ await hooks.emit("action_end", {
129
+ actionType: "get_my_balance",
130
+ args: {},
131
+ result: {},
132
+ durationMs: 100,
133
+ });
134
+ await flush();
135
+ expect(manifests.updateManifest).not.toHaveBeenCalled();
136
+ });
137
+ });
138
+ describe("manifestActivationHook — action_error debounce", () => {
139
+ beforeEach(() => {
140
+ vi.useFakeTimers();
141
+ });
142
+ it("does not write after 1 error", async () => {
143
+ vi.useRealTimers();
144
+ const { runtime, hooks, manifests } = makeRuntime();
145
+ installManifestActivationHook(runtime);
146
+ await hooks.emit("action_error", {
147
+ actionType: "submit_mining_solution",
148
+ args: {},
149
+ error: new Error("network blip"),
150
+ durationMs: 100,
151
+ });
152
+ await flush();
153
+ expect(manifests.getMyManifest).not.toHaveBeenCalled();
154
+ expect(manifests.updateManifest).not.toHaveBeenCalled();
155
+ });
156
+ it("writes one uncertainty after 3 errors of the same actionType inside the window", async () => {
157
+ vi.useRealTimers();
158
+ const { runtime, hooks, manifests } = makeRuntime();
159
+ installManifestActivationHook(runtime);
160
+ for (let i = 0; i < 3; i++) {
161
+ await hooks.emit("action_error", {
162
+ actionType: "submit_mining_solution",
163
+ args: {},
164
+ error: new Error(`fail-${i}`),
165
+ durationMs: 50,
166
+ });
167
+ }
168
+ await flush();
169
+ expect(manifests.getMyManifest).toHaveBeenCalledTimes(1);
170
+ expect(manifests.updateManifest).toHaveBeenCalledTimes(1);
171
+ const call = manifests.updateManifest.mock.calls[0][0];
172
+ expect(call.uncertainties).toHaveLength(1);
173
+ expect(call.uncertainties[0].description).toContain("Stuck on submit_mining_solution");
174
+ expect(call.uncertainties[0].description).toContain("fail-2");
175
+ expect(call.uncertainties[0].valueOfResolution).toBe(0.7);
176
+ });
177
+ it("resets the counter when errors are spread beyond the window", async () => {
178
+ vi.useRealTimers();
179
+ const { runtime, hooks, manifests } = makeRuntime();
180
+ installManifestActivationHook(runtime, { errorDebounceWindowMs: 50 });
181
+ await hooks.emit("action_error", {
182
+ actionType: "deliver_work",
183
+ args: {},
184
+ error: new Error("a"),
185
+ durationMs: 0,
186
+ });
187
+ await new Promise((r) => setTimeout(r, 80)); // exceeds 50ms window
188
+ await hooks.emit("action_error", {
189
+ actionType: "deliver_work",
190
+ args: {},
191
+ error: new Error("b"),
192
+ durationMs: 0,
193
+ });
194
+ await flush();
195
+ // First error opens window, second resets — only 2 emissions, no 3rd inside window.
196
+ expect(manifests.updateManifest).not.toHaveBeenCalled();
197
+ });
198
+ it("does not conflate counters across different actionTypes", async () => {
199
+ vi.useRealTimers();
200
+ const { runtime, hooks, manifests } = makeRuntime();
201
+ installManifestActivationHook(runtime);
202
+ await hooks.emit("action_error", { actionType: "A", args: {}, error: new Error("x"), durationMs: 0 });
203
+ await hooks.emit("action_error", { actionType: "B", args: {}, error: new Error("x"), durationMs: 0 });
204
+ await hooks.emit("action_error", { actionType: "A", args: {}, error: new Error("x"), durationMs: 0 });
205
+ await flush();
206
+ // 2 A errors + 1 B error → no threshold trip.
207
+ expect(manifests.updateManifest).not.toHaveBeenCalled();
208
+ });
209
+ });
210
+ describe("manifestActivationHook — doom_loop_detected", () => {
211
+ it("appends an uncertainty unconditionally", async () => {
212
+ const { runtime, hooks, manifests } = makeRuntime();
213
+ installManifestActivationHook(runtime);
214
+ await hooks.emit("doom_loop_detected", {
215
+ offender: "submit_mining_solution",
216
+ triggers: 1,
217
+ actionType: "submit_mining_solution",
218
+ });
219
+ await flush();
220
+ expect(manifests.updateManifest).toHaveBeenCalledTimes(1);
221
+ const call = manifests.updateManifest.mock.calls[0][0];
222
+ expect(call.uncertainties[0].description).toBe("Doom loop on submit_mining_solution");
223
+ expect(call.uncertainties[0].valueOfResolution).toBe(0.9);
224
+ });
225
+ });
226
+ describe("manifestActivationHook — uncertainty cap", () => {
227
+ it("drops the oldest entry FIFO when at the 20-cap", async () => {
228
+ const existing = Array.from({ length: 20 }, (_, i) => ({
229
+ description: `old-${i}`,
230
+ valueOfResolution: 0.5,
231
+ }));
232
+ const { runtime, hooks, manifests } = makeRuntime(existing);
233
+ installManifestActivationHook(runtime);
234
+ await hooks.emit("doom_loop_detected", {
235
+ offender: "X",
236
+ triggers: 1,
237
+ actionType: "X",
238
+ });
239
+ await flush();
240
+ const call = manifests.updateManifest.mock.calls[0][0];
241
+ expect(call.uncertainties).toHaveLength(20);
242
+ // Oldest dropped, newest appended.
243
+ expect(call.uncertainties[0].description).toBe("old-1");
244
+ expect(call.uncertainties[19].description).toBe("Doom loop on X");
245
+ });
246
+ it("respects a custom cap", async () => {
247
+ const existing = Array.from({ length: 5 }, (_, i) => ({
248
+ description: `old-${i}`,
249
+ valueOfResolution: 0.5,
250
+ }));
251
+ const { runtime, hooks, manifests } = makeRuntime(existing);
252
+ installManifestActivationHook(runtime, { maxUncertainties: 5 });
253
+ await hooks.emit("doom_loop_detected", {
254
+ offender: "Y",
255
+ triggers: 1,
256
+ actionType: "Y",
257
+ });
258
+ await flush();
259
+ const call = manifests.updateManifest.mock.calls[0][0];
260
+ expect(call.uncertainties).toHaveLength(5);
261
+ expect(call.uncertainties[4].description).toBe("Doom loop on Y");
262
+ });
263
+ });
264
+ describe("manifestActivationHook — extractDomain", () => {
265
+ it("prefers domainTags[0] when present", () => {
266
+ expect(extractDomain({ signalType: "x", domainTags: ["alpha", "beta"] }))
267
+ .toBe("alpha");
268
+ });
269
+ it("falls back to domain field", () => {
270
+ expect(extractDomain({ signalType: "x", domain: "bio" }))
271
+ .toBe("bio");
272
+ });
273
+ it("falls back to skillDomain", () => {
274
+ expect(extractDomain({ signalType: "x", skillDomain: "code-review" }))
275
+ .toBe("code-review");
276
+ });
277
+ it("falls back to metadata.domain", () => {
278
+ expect(extractDomain({ signalType: "x", metadata: { domain: "math" } })).toBe("math");
279
+ });
280
+ it("falls back to community when present", () => {
281
+ expect(extractDomain({ signalType: "x", community: "defi" })).toBe("defi");
282
+ });
283
+ it("returns 'general' as last resort", () => {
284
+ expect(extractDomain({ signalType: "x" })).toBe("general");
285
+ });
286
+ it("ignores empty domainTags array", () => {
287
+ expect(extractDomain({ signalType: "x", domainTags: [] }))
288
+ .toBe("general");
289
+ });
290
+ });
291
+ describe("manifestActivationHook — allowlists", () => {
292
+ it("TASK_BEARING_SIGNALS is non-empty and excludes social signals", () => {
293
+ expect(TASK_BEARING_SIGNALS.size).toBeGreaterThan(10);
294
+ expect(TASK_BEARING_SIGNALS.has("channel_message")).toBe(false);
295
+ expect(TASK_BEARING_SIGNALS.has("dm_received")).toBe(false);
296
+ expect(TASK_BEARING_SIGNALS.has("new_follower")).toBe(false);
297
+ expect(TASK_BEARING_SIGNALS.has("attestation_received")).toBe(false);
298
+ expect(TASK_BEARING_SIGNALS.has("welcome_guide")).toBe(false);
299
+ });
300
+ it("TERMINAL_ACTIONS includes the canonical work-completion actions", () => {
301
+ expect(TERMINAL_ACTIONS.has("submit_mining_solution")).toBe(true);
302
+ expect(TERMINAL_ACTIONS.has("deliver_work")).toBe(true);
303
+ expect(TERMINAL_ACTIONS.has("mark_task_done")).toBe(true);
304
+ expect(TERMINAL_ACTIONS.has("resolve_clarification")).toBe(true);
305
+ });
306
+ it("TERMINAL_ACTIONS excludes read-only / browse actions", () => {
307
+ expect(TERMINAL_ACTIONS.has("browse_tools")).toBe(false);
308
+ expect(TERMINAL_ACTIONS.has("get_my_balance")).toBe(false);
309
+ expect(TERMINAL_ACTIONS.has("nookplot_get_manifest")).toBe(false);
310
+ });
311
+ });
312
+ //# sourceMappingURL=manifestActivationHook.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifestActivationHook.test.js","sourceRoot":"","sources":["../../src/__tests__/manifestActivationHook.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,6BAA6B,EAC7B,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,GACd,MAAM,8BAA8B,CAAC;AAUtC,SAAS,WAAW,CAAC,uBAAkC,EAAE;IAKvD,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE,CAAC;IACjC,MAAM,SAAS,GAAkB;QAC/B,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QAC1E,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;QAChF,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YACvC,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,oBAAoB;SACpC,CAAC;KACH,CAAC;IACF,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,SAAS,EAAgC,CAAC;IACnE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,KAAK;IAClB,0EAA0E;IAC1E,0EAA0E;IAC1E,qEAAqE;IACrE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,WAAW,EAAE,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAElD,MAAM,OAAO,GAAG,6BAA6B,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAElD,OAAO,EAAE,CAAC;QACV,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,WAAW,EAAE,CAAC;QACvD,MAAM,SAAS,GAAG,IAAI,YAAY,EAAE,CAAC;QACrC,6BAA6B,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7D,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qDAAqD,EAAE,GAAG,EAAE;IACnE,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;QACpD,6BAA6B,CAAC,OAAO,CAAC,CAAC;QAEvC,MAAM,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAClC,UAAU,EAAE,oBAAoB;YAChC,UAAU,EAAE,CAAC,mBAAmB,CAAC;SACR,CAAC,CAAC;QAC7B,MAAM,KAAK,EAAE,CAAC;QAEd,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC;YAC9C,QAAQ,EAAE,oBAAoB;YAC9B,MAAM,EAAE,mBAAmB;SAC5B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;QACpD,6BAA6B,CAAC,OAAO,CAAC,CAAC;QAEvC,MAAM,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,UAAU,EAAE,iBAAiB,EAAiB,CAAC,CAAC;QACtF,MAAM,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,UAAU,EAAE,aAAa,EAAiB,CAAC,CAAC;QAClF,MAAM,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,UAAU,EAAE,cAAc,EAAiB,CAAC,CAAC;QACnF,MAAM,KAAK,EAAE,CAAC;QAEd,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;QACpD,6BAA6B,CAAC,OAAO,CAAC,CAAC;QAEvC,MAAM,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAiB,CAAC,CAAC;QAC7E,MAAM,KAAK,EAAE,CAAC;QAEd,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC;YAC9C,QAAQ,EAAE,QAAQ;YAClB,MAAM,EAAE,SAAS;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;QACpD,SAAS,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;QACpE,6BAA6B,CAAC,OAAO,CAAC,CAAC;QAEvC,yEAAyE;QACzE,4CAA4C;QAC5C,MAAM,MAAM,CACV,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAC5B,UAAU,EAAE,eAAe;YAC3B,MAAM,EAAE,cAAc;SACG,CAAC,CAC7B,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;QACpD,6BAA6B,CAAC,OAAO,CAAC,CAAC;QAEvC,MAAM,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE;YAC7B,UAAU,EAAE,wBAAwB;YACpC,IAAI,EAAE,EAAE;YACR,MAAM,EAAE,EAAE;YACV,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,KAAK,EAAE,CAAC;QAEd,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1D,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,oBAAoB,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;QACpD,6BAA6B,CAAC,OAAO,CAAC,CAAC;QAEvC,MAAM,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE;YAC7B,UAAU,EAAE,cAAc;YAC1B,IAAI,EAAE,EAAE;YACR,MAAM,EAAE,EAAE;YACV,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE;YAC7B,UAAU,EAAE,gBAAgB;YAC5B,IAAI,EAAE,EAAE;YACR,MAAM,EAAE,EAAE;YACV,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,KAAK,EAAE,CAAC;QAEd,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;IAC9D,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;QACpD,6BAA6B,CAAC,OAAO,CAAC,CAAC;QAEvC,MAAM,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE;YAC/B,UAAU,EAAE,wBAAwB;YACpC,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,IAAI,KAAK,CAAC,cAAc,CAAC;YAChC,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,KAAK,EAAE,CAAC;QAEd,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACvD,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;QACpD,6BAA6B,CAAC,OAAO,CAAC,CAAC;QAEvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE;gBAC/B,UAAU,EAAE,wBAAwB;gBACpC,IAAI,EAAE,EAAE;gBACR,KAAK,EAAE,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,UAAU,EAAE,EAAE;aACf,CAAC,CAAC;QACL,CAAC;QACD,MAAM,KAAK,EAAE,CAAC;QAEd,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAErD,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;QACvF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC9D,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;QACpD,6BAA6B,CAAC,OAAO,EAAE,EAAE,qBAAqB,EAAE,EAAE,EAAE,CAAC,CAAC;QAEtE,MAAM,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE;YAC/B,UAAU,EAAE,cAAc;YAC1B,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC;YACrB,UAAU,EAAE,CAAC;SACd,CAAC,CAAC;QACH,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,sBAAsB;QACnE,MAAM,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE;YAC/B,UAAU,EAAE,cAAc;YAC1B,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC;YACrB,UAAU,EAAE,CAAC;SACd,CAAC,CAAC;QACH,MAAM,KAAK,EAAE,CAAC;QAEd,oFAAoF;QACpF,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;QACpD,6BAA6B,CAAC,OAAO,CAAC,CAAC;QAEvC,MAAM,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QACtG,MAAM,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QACtG,MAAM,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QACtG,MAAM,KAAK,EAAE,CAAC;QAEd,8CAA8C;QAC9C,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6CAA6C,EAAE,GAAG,EAAE;IAC3D,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,CAAC;QACpD,6BAA6B,CAAC,OAAO,CAAC,CAAC;QAEvC,MAAM,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE;YACrC,QAAQ,EAAE,wBAAwB;YAClC,QAAQ,EAAE,CAAC;YACX,UAAU,EAAE,wBAAwB;SACrC,CAAC,CAAC;QACH,MAAM,KAAK,EAAE,CAAC;QAEd,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAErD,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACtF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0CAA0C,EAAE,GAAG,EAAE;IACxD,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACrD,WAAW,EAAE,OAAO,CAAC,EAAE;YACvB,iBAAiB,EAAE,GAAG;SACvB,CAAC,CAAC,CAAC;QACJ,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC5D,6BAA6B,CAAC,OAAO,CAAC,CAAC;QAEvC,MAAM,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE;YACrC,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,CAAC;YACX,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,KAAK,EAAE,CAAC;QAEd,MAAM,IAAI,GAAG,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAErD,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAC5C,mCAAmC;QACnC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YACpD,WAAW,EAAE,OAAO,CAAC,EAAE;YACvB,iBAAiB,EAAE,GAAG;SACvB,CAAC,CAAC,CAAC;QACJ,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC5D,6BAA6B,CAAC,OAAO,EAAE,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC;QAEhE,MAAM,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE;YACrC,QAAQ,EAAE,GAAG;YACb,QAAQ,EAAE,CAAC;YACX,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;QACH,MAAM,KAAK,EAAE,CAAC;QAEd,MAAM,IAAI,GAAG,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAErD,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,wCAAwC,EAAE,GAAG,EAAE;IACtD,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,EAA4B,CAAC,CAAC;aAChG,IAAI,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAA4B,CAAC,CAAC;aAChF,IAAI,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,aAAa,EAA4B,CAAC,CAAC;aAC7F,IAAI,CAAC,aAAa,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CACJ,aAAa,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAA4B,CAAC,CAC3F,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5F,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,GAAG,EAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,EAA4B,CAAC,CAAC;aACjF,IAAI,CAAC,SAAS,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;IACnD,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QACtD,MAAM,CAAC,oBAAoB,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChE,MAAM,CAAC,oBAAoB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5D,MAAM,CAAC,oBAAoB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7D,MAAM,CAAC,oBAAoB,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrE,MAAM,CAAC,oBAAoB,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClE,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3D,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mining.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mining.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mining.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,306 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { MiningManager, trackOf } from "../mining.js";
3
+ // ─── Mock builders ────────────────────────────────────────────────────
4
+ function createMockConnection() {
5
+ return {
6
+ request: vi.fn(),
7
+ gatewayUrl: "https://gateway.nookplot.com",
8
+ apiKey: "test-api-key",
9
+ };
10
+ }
11
+ function createMockEconomy() {
12
+ return {
13
+ inference: vi.fn().mockResolvedValue({ content: "x".repeat(200) }),
14
+ };
15
+ }
16
+ function setupResponses(connection, knowledgeIds, rlmIds = [], embedIds = []) {
17
+ connection.request.mockImplementation(async (method, path) => {
18
+ if (method === "GET" && path.startsWith("/v1/mining/earnings-preview")) {
19
+ return {
20
+ tracks: [
21
+ { track: "knowledge", openCount: knowledgeIds.length },
22
+ { track: "embedding", openCount: embedIds.length },
23
+ { track: "rlm", openCount: rlmIds.length },
24
+ ],
25
+ };
26
+ }
27
+ if (method === "GET" && path.startsWith("/v1/mining/challenges?status=open&sourceType=rlm_trajectory")) {
28
+ return {
29
+ challenges: rlmIds.map((id, i) => ({
30
+ id, title: `RLM ${i}`, difficulty: "medium",
31
+ estimatedRewardNook: 50_000, sourceType: "rlm_trajectory", closesAt: "2030-01-01T00:00:00Z",
32
+ })),
33
+ };
34
+ }
35
+ if (method === "GET" && path.startsWith("/v1/mining/challenges?status=open")) {
36
+ return {
37
+ challenges: knowledgeIds.map((id, i) => ({
38
+ id, title: `Knowledge ${i}`, difficulty: i === 0 ? "expert" : "easy",
39
+ estimatedRewardNook: 100_000 - i * 1000, sourceType: "agent_authored",
40
+ closesAt: "2030-01-01T00:00:00Z",
41
+ })),
42
+ };
43
+ }
44
+ if (method === "GET" && path.startsWith("/v1/mining/embedding-challenges?status=open")) {
45
+ return {
46
+ challenges: embedIds.map((id, i) => ({
47
+ id, title: `Embedding ${i}`, difficulty: "easy",
48
+ estimatedRewardNook: 5_000, sourceType: "embedding_generation", closesAt: "2030-01-01T00:00:00Z",
49
+ })),
50
+ };
51
+ }
52
+ if (method === "GET" && path.startsWith("/v1/mining/embedding-challenges/")) {
53
+ return { prompts: ["a", "b"], dimensions: 768 };
54
+ }
55
+ if (method === "POST" && path.startsWith("/v1/mining/submissions/")) {
56
+ return { submissionId: `sub-${path.split("/").pop()}` };
57
+ }
58
+ if (method === "POST" && path.includes("/v1/mining/embedding-challenges/") && path.endsWith("/submit")) {
59
+ return { submissionId: `embed-sub` };
60
+ }
61
+ throw new Error(`Unmocked request: ${method} ${path}`);
62
+ });
63
+ }
64
+ // ─── Tests ────────────────────────────────────────────────────────────
65
+ describe("trackOf", () => {
66
+ it("classifies known source types", () => {
67
+ expect(trackOf("embedding_generation")).toBe("embedding");
68
+ expect(trackOf("rlm_trajectory")).toBe("rlm");
69
+ expect(trackOf("rlm_audit")).toBe("rlm");
70
+ expect(trackOf("agent_authored")).toBe("knowledge");
71
+ expect(trackOf("paper_reproduction")).toBe("knowledge");
72
+ });
73
+ });
74
+ describe("MiningManager.runOnce", () => {
75
+ let connection;
76
+ let economy;
77
+ let manager;
78
+ beforeEach(() => {
79
+ connection = createMockConnection();
80
+ economy = createMockEconomy();
81
+ manager = new MiningManager(connection, economy);
82
+ });
83
+ it("submits the highest-ranked challenge across enabled tracks", async () => {
84
+ setupResponses(connection, ["k1", "k2"], [], []);
85
+ const results = await manager.runOnce({ tracks: ["knowledge"] });
86
+ expect(results).toHaveLength(1);
87
+ expect(results[0].track).toBe("knowledge");
88
+ expect(results[0].status).toBe("submitted");
89
+ // k1 is "expert" difficulty so it ranks above k2.
90
+ expect(results[0].challengeId).toBe("k1");
91
+ expect(economy.inference).toHaveBeenCalledOnce();
92
+ });
93
+ it("dry-run does not submit", async () => {
94
+ setupResponses(connection, ["k1"], [], []);
95
+ const results = await manager.runOnce({ tracks: ["knowledge"], dryRun: true });
96
+ expect(results[0].status).toBe("skipped");
97
+ expect(results[0].reason).toBe("dry-run");
98
+ // No POST.
99
+ const posts = connection.request.mock.calls.filter((c) => c[0] === "POST");
100
+ expect(posts).toHaveLength(0);
101
+ });
102
+ it("returns empty array when no tracks have open challenges", async () => {
103
+ setupResponses(connection, [], [], []);
104
+ const results = await manager.runOnce({ tracks: ["knowledge", "embedding", "rlm"] });
105
+ expect(results).toEqual([]);
106
+ });
107
+ it("isolates per-track discovery failures (one track erroring does not poison others)", async () => {
108
+ connection.request.mockImplementation(async (method, path) => {
109
+ if (method === "GET" && path.startsWith("/v1/mining/embedding-challenges?")) {
110
+ throw new Error("embedding endpoint exploded");
111
+ }
112
+ if (method === "GET" && path.startsWith("/v1/mining/challenges?status=open&sourceType=rlm_trajectory")) {
113
+ return { challenges: [] };
114
+ }
115
+ if (method === "GET" && path.startsWith("/v1/mining/challenges?status=open")) {
116
+ return {
117
+ challenges: [{
118
+ id: "k1", title: "K", difficulty: "easy",
119
+ estimatedRewardNook: 1000, sourceType: "agent_authored", closesAt: "2030-01-01T00:00:00Z",
120
+ }],
121
+ };
122
+ }
123
+ if (method === "POST" && path.startsWith("/v1/mining/submissions/")) {
124
+ return { submissionId: "sub-k1" };
125
+ }
126
+ throw new Error(`unexpected ${method} ${path}`);
127
+ });
128
+ const results = await manager.runOnce({ tracks: ["knowledge", "embedding"] });
129
+ expect(results).toHaveLength(1);
130
+ expect(results[0].track).toBe("knowledge");
131
+ expect(results[0].status).toBe("submitted");
132
+ });
133
+ it("auto-resolves tracks via earnings-preview when tracks: 'auto'", async () => {
134
+ setupResponses(connection, ["k1"], [], []);
135
+ const results = await manager.runOnce({ tracks: "auto" });
136
+ expect(results[0].track).toBe("knowledge");
137
+ const previewCall = connection.request.mock.calls.find((c) => typeof c[1] === "string" && c[1].startsWith("/v1/mining/earnings-preview"));
138
+ expect(previewCall).toBeTruthy();
139
+ });
140
+ it("skips embedding when no generateEmbeddings callback is provided", async () => {
141
+ setupResponses(connection, [], [], ["e1"]);
142
+ const results = await manager.runOnce({ tracks: ["embedding"] });
143
+ expect(results[0].track).toBe("embedding");
144
+ expect(results[0].status).toBe("skipped");
145
+ expect(results[0].reason).toMatch(/generateEmbeddings/);
146
+ });
147
+ it("submits embedding via callback when provided", async () => {
148
+ setupResponses(connection, [], [], ["e1"]);
149
+ const generateEmbeddings = vi.fn().mockResolvedValue([Array(768).fill(0.1), Array(768).fill(0.2)]);
150
+ const results = await manager.runOnce({ tracks: ["embedding"], generateEmbeddings });
151
+ expect(results[0].status).toBe("submitted");
152
+ expect(generateEmbeddings).toHaveBeenCalledWith(["a", "b"], 768);
153
+ });
154
+ it("skips RLM by default with a deferred reason; uses solveRlm callback when provided", async () => {
155
+ setupResponses(connection, [], ["r1"], []);
156
+ const defaultResults = await manager.runOnce({ tracks: ["rlm"] });
157
+ expect(defaultResults[0].status).toBe("skipped");
158
+ expect(defaultResults[0].reason).toMatch(/RLM/);
159
+ const solveRlm = vi.fn().mockResolvedValue({
160
+ track: "rlm", challengeId: "r1", status: "submitted",
161
+ submissionId: "rlm-sub",
162
+ });
163
+ const customResults = await manager.runOnce({ tracks: ["rlm"], solveRlm });
164
+ expect(customResults[0].status).toBe("submitted");
165
+ expect(solveRlm).toHaveBeenCalledOnce();
166
+ });
167
+ });
168
+ describe("MiningManager.start", () => {
169
+ let connection;
170
+ let economy;
171
+ let manager;
172
+ beforeEach(() => {
173
+ connection = createMockConnection();
174
+ economy = createMockEconomy();
175
+ manager = new MiningManager(connection, economy);
176
+ });
177
+ it("once mode runs until queue drains and then resolves done", async () => {
178
+ let calls = 0;
179
+ connection.request.mockImplementation(async (method, path) => {
180
+ if (method === "GET" && path.startsWith("/v1/mining/challenges?status=open&sourceType=rlm_trajectory")) {
181
+ return { challenges: [] };
182
+ }
183
+ if (method === "GET" && path.startsWith("/v1/mining/challenges?status=open")) {
184
+ calls++;
185
+ if (calls === 1) {
186
+ return {
187
+ challenges: [{
188
+ id: "k1", title: "K", difficulty: "easy",
189
+ estimatedRewardNook: 1000, sourceType: "agent_authored", closesAt: "2030-01-01T00:00:00Z",
190
+ }],
191
+ };
192
+ }
193
+ return { challenges: [] };
194
+ }
195
+ if (method === "POST" && path.startsWith("/v1/mining/submissions/")) {
196
+ return { submissionId: "sub-k1" };
197
+ }
198
+ throw new Error(`unexpected ${method} ${path}`);
199
+ });
200
+ const session = await manager.start({ tracks: ["knowledge"], once: true, tickIntervalMs: 5 });
201
+ await session.done;
202
+ const stats = session.stats();
203
+ expect(stats.submitted).toBe(1);
204
+ expect(stats.byTrack.knowledge.submitted).toBe(1);
205
+ });
206
+ it("respects maxCredits — stops when budget is exhausted", async () => {
207
+ let challengeIdx = 0;
208
+ connection.request.mockImplementation(async (method, path) => {
209
+ if (method === "GET" && path.startsWith("/v1/mining/challenges?status=open&sourceType=rlm_trajectory")) {
210
+ return { challenges: [] };
211
+ }
212
+ if (method === "GET" && path.startsWith("/v1/mining/challenges?status=open")) {
213
+ return {
214
+ challenges: [{
215
+ id: `k${challengeIdx++}`, title: "K", difficulty: "easy",
216
+ estimatedRewardNook: 1000, sourceType: "agent_authored", closesAt: "2030-01-01T00:00:00Z",
217
+ }],
218
+ };
219
+ }
220
+ if (method === "POST" && path.startsWith("/v1/mining/submissions/")) {
221
+ return { submissionId: "sub" };
222
+ }
223
+ throw new Error(`unexpected ${method} ${path}`);
224
+ });
225
+ const session = await manager.start({
226
+ tracks: ["knowledge"],
227
+ maxCredits: 100, // each knowledge solve charges 50 → loop should stop after 2 solves
228
+ tickIntervalMs: 5,
229
+ });
230
+ // Wait briefly for the loop to spin and then stop on budget.
231
+ await new Promise((r) => setTimeout(r, 80));
232
+ await session.stop();
233
+ const stats = session.stats();
234
+ expect(stats.creditsSpent).toBeGreaterThanOrEqual(100);
235
+ expect(stats.submitted).toBeGreaterThanOrEqual(2);
236
+ });
237
+ it("rejects a second start() while a session is active", async () => {
238
+ setupResponses(connection, [], [], []);
239
+ const session = await manager.start({ tracks: ["knowledge"], tickIntervalMs: 5 });
240
+ await expect(manager.start({ tracks: ["knowledge"] })).rejects.toThrow(/already active/);
241
+ await session.stop();
242
+ });
243
+ it("dry-run skips count separately from real skips in stats.dryRun", async () => {
244
+ // Drains after one tick: discover returns k1 the first time, then [].
245
+ // (Real gateway moves a claimed challenge out of the open list; the mock
246
+ // simulates that so once-mode doesn't loop on the same challenge forever.)
247
+ let knowledgeCalls = 0;
248
+ connection.request.mockImplementation(async (method, path) => {
249
+ if (method === "GET" && path.startsWith("/v1/mining/challenges?status=open&sourceType=rlm_trajectory")) {
250
+ return { challenges: [] };
251
+ }
252
+ if (method === "GET" && path.startsWith("/v1/mining/challenges?status=open")) {
253
+ knowledgeCalls++;
254
+ if (knowledgeCalls === 1) {
255
+ return { challenges: [{
256
+ id: "k1", title: "K", difficulty: "easy",
257
+ estimatedRewardNook: 1000, sourceType: "agent_authored",
258
+ closesAt: "2030-01-01T00:00:00Z",
259
+ }] };
260
+ }
261
+ return { challenges: [] };
262
+ }
263
+ throw new Error(`unexpected ${method} ${path}`);
264
+ });
265
+ const session = await manager.start({
266
+ tracks: ["knowledge"],
267
+ dryRun: true,
268
+ once: true,
269
+ tickIntervalMs: 5,
270
+ });
271
+ await session.done;
272
+ const stats = session.stats();
273
+ expect(stats.dryRun).toBe(1);
274
+ expect(stats.skipped).toBe(0);
275
+ expect(stats.submitted).toBe(0);
276
+ });
277
+ });
278
+ describe("MiningManager.runOnce — explain mode", () => {
279
+ it("logs scoring math when explain: true", async () => {
280
+ const connection = createMockConnection();
281
+ const economy = createMockEconomy();
282
+ const logs = [];
283
+ const manager = new MiningManager(connection, economy);
284
+ setupResponses(connection, ["k1", "k2", "k3"]);
285
+ await manager.runOnce({
286
+ tracks: ["knowledge"],
287
+ explain: true,
288
+ log: (m) => logs.push(m),
289
+ });
290
+ const rankLines = logs.filter((l) => l.startsWith("[mining][rank]"));
291
+ expect(rankLines.length).toBeGreaterThan(0);
292
+ expect(rankLines[0]).toMatch(/score=/);
293
+ });
294
+ });
295
+ // Type sanity check
296
+ describe("ChallengeSummary type", () => {
297
+ it("compiles with expected fields", () => {
298
+ const s = {
299
+ id: "x", track: "knowledge", title: "t", difficulty: "easy",
300
+ estimatedRewardNook: 0, domainTags: [], sourceType: "agent_authored",
301
+ closesAt: "2030-01-01T00:00:00Z",
302
+ };
303
+ expect(s.track).toBe("knowledge");
304
+ });
305
+ });
306
+ //# sourceMappingURL=mining.test.js.map