@claudexor/control-api 1.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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +7 -0
  3. package/dist/artifact-paths.d.ts +3 -0
  4. package/dist/artifact-paths.d.ts.map +1 -0
  5. package/dist/artifact-paths.js +36 -0
  6. package/dist/artifact-paths.js.map +1 -0
  7. package/dist/candidates.d.ts +3 -0
  8. package/dist/candidates.d.ts.map +1 -0
  9. package/dist/candidates.js +77 -0
  10. package/dist/candidates.js.map +1 -0
  11. package/dist/daemon-server.d.ts +196 -0
  12. package/dist/daemon-server.d.ts.map +1 -0
  13. package/dist/daemon-server.js +1971 -0
  14. package/dist/daemon-server.js.map +1 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +2 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/run-events-stream.d.ts +28 -0
  20. package/dist/run-events-stream.d.ts.map +1 -0
  21. package/dist/run-events-stream.js +146 -0
  22. package/dist/run-events-stream.js.map +1 -0
  23. package/dist/run-start.d.ts +14 -0
  24. package/dist/run-start.d.ts.map +1 -0
  25. package/dist/run-start.js +99 -0
  26. package/dist/run-start.js.map +1 -0
  27. package/dist/run-timeline.d.ts +22 -0
  28. package/dist/run-timeline.d.ts.map +1 -0
  29. package/dist/run-timeline.js +155 -0
  30. package/dist/run-timeline.js.map +1 -0
  31. package/dist/sse-shared.d.ts +11 -0
  32. package/dist/sse-shared.d.ts.map +1 -0
  33. package/dist/sse-shared.js +47 -0
  34. package/dist/sse-shared.js.map +1 -0
  35. package/dist/thread-projection.d.ts +12 -0
  36. package/dist/thread-projection.d.ts.map +1 -0
  37. package/dist/thread-projection.js +83 -0
  38. package/dist/thread-projection.js.map +1 -0
  39. package/dist/thread-turn-routes.d.ts +63 -0
  40. package/dist/thread-turn-routes.d.ts.map +1 -0
  41. package/dist/thread-turn-routes.js +317 -0
  42. package/dist/thread-turn-routes.js.map +1 -0
  43. package/package.json +45 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 joi-lab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # @claudexor/control-api
2
+
3
+ Internal package of [Claudexor](https://github.com/razzant/claudexor) — Loopback HTTP+SSE control surface for GUI/service clients: token-auth, Host/Origin guard, live run event stream with Last-Event-ID replay. Runner injected (no second scheduler).
4
+
5
+ Published as part of the Claudexor toolchain; it follows the monorepo's
6
+ lockstep version and has no separate semver contract. Use the `claudexor`
7
+ CLI (or `@claudexor/cli`) as the supported entry point.
@@ -0,0 +1,3 @@
1
+ export declare function safeArtifactPath(root: string, requested: string): string | null;
2
+ export declare function safeArtifactRoot(root: string): string | null;
3
+ //# sourceMappingURL=artifact-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-paths.d.ts","sourceRoot":"","sources":["../src/artifact-paths.ts"],"names":[],"mappings":"AASA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAa/E;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK5D"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Path-confinement guards for run-artifact reads: every artifact fetch must
3
+ * resolve INSIDE the run/artifact root, symlinks are refused (a symlinked
4
+ * artifact could read arbitrary host files into an HTTP response), and `..`
5
+ * traversal is structurally impossible.
6
+ */
7
+ import { existsSync, lstatSync, realpathSync } from "node:fs";
8
+ import { normalize, resolve, sep } from "node:path";
9
+ export function safeArtifactPath(root, requested) {
10
+ if (requested.includes("\0"))
11
+ return null;
12
+ const parts = requested.split(/[\\/]+/).filter(Boolean);
13
+ if (parts.includes(".."))
14
+ return null;
15
+ const base = safeArtifactRoot(root);
16
+ if (!base)
17
+ return null;
18
+ const clean = normalize(parts.join(sep));
19
+ const abs = resolve(base, clean);
20
+ if (!existsSync(abs))
21
+ return null;
22
+ const lst = lstatSync(abs);
23
+ if (lst.isSymbolicLink())
24
+ return null;
25
+ const real = realpathSync(abs);
26
+ return real === base || real.startsWith(base + sep) ? real : null;
27
+ }
28
+ export function safeArtifactRoot(root) {
29
+ if (!root || !existsSync(root))
30
+ return null;
31
+ const st = lstatSync(root);
32
+ if (st.isSymbolicLink() || !st.isDirectory())
33
+ return null;
34
+ return realpathSync(root);
35
+ }
36
+ //# sourceMappingURL=artifact-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-paths.js","sourceRoot":"","sources":["../src/artifact-paths.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEpD,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,SAAiB;IAC9D,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACxD,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,GAAG,CAAC,cAAc,EAAE;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE;QAAE,OAAO,IAAI,CAAC;IAC1D,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { ControlCandidate, type DecisionRecord } from "@claudexor/schema";
2
+ export declare function candidatesFor(runDir: string, decision: DecisionRecord | null): ControlCandidate[];
3
+ //# sourceMappingURL=candidates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidates.d.ts","sourceRoot":"","sources":["../src/candidates.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAA6B,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAkBrG,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,GAAG,gBAAgB,EAAE,CA2CjG"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Candidate-card projection: attempts/<id>/attempt.yaml +
3
+ * reviews/<id>.yaml + the decision winner -> ControlCandidate[]. Pure
4
+ * artifact reads — the engine wrote the evidence; this only projects it.
5
+ */
6
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ import { parse as parseYaml } from "yaml";
9
+ import { ControlCandidate, ReviewFinding, isBlocking } from "@claudexor/schema";
10
+ export function candidatesFor(runDir, decision) {
11
+ const attemptsDir = join(runDir, "attempts");
12
+ if (!existsSync(attemptsDir))
13
+ return [];
14
+ const out = [];
15
+ for (const attemptId of safeReaddir(attemptsDir)) {
16
+ const raw = readYamlMaybe(join(attemptsDir, attemptId, "attempt.yaml"));
17
+ if (!raw || typeof raw.attempt_id !== "string" || typeof raw.harness_id !== "string")
18
+ continue;
19
+ const review = readYamlMaybe(join(runDir, "reviews", `${attemptId}.yaml`));
20
+ const rawFindings = Array.isArray(review?.findings) ? review.findings : [];
21
+ // Blocking is the SCHEMA's judgment (isBlocking: accepted
22
+ // BLOCK/FIX_FIRST with evidence, or NEEDS_HUMAN) — never a projection-
23
+ // local severity list that can drift from the contract.
24
+ const blockers = rawFindings.filter((f) => {
25
+ const parsed = ReviewFinding.safeParse(f);
26
+ return parsed.success && isBlocking(parsed.data);
27
+ }).length;
28
+ const gates = Array.isArray(raw.gates) ? raw.gates : [];
29
+ const parsed = ControlCandidate.safeParse({
30
+ attemptId: raw.attempt_id,
31
+ harnessId: raw.harness_id,
32
+ label: typeof raw.label === "string" ? raw.label : null,
33
+ costUsd: typeof raw.cost_usd === "number" ? raw.cost_usd : 0,
34
+ costEstimated: raw.cost_estimated === true,
35
+ errored: raw.errored === true,
36
+ gatesPassed: gates.filter((g) => g.status === "passed").length,
37
+ gatesTotal: gates.length,
38
+ blockers,
39
+ reviewVerified: review?.review_verified === true,
40
+ finalReviewClean: review ? blockers === 0 : null,
41
+ winner: decision?.winner === raw.attempt_id,
42
+ diffstat: raw.diffstat && typeof raw.diffstat === "object"
43
+ ? {
44
+ files: numberOr(raw.diffstat.files, 0),
45
+ additions: numberOr(raw.diffstat.additions, 0),
46
+ deletions: numberOr(raw.diffstat.deletions, 0),
47
+ }
48
+ : null,
49
+ });
50
+ if (parsed.success)
51
+ out.push(parsed.data);
52
+ }
53
+ // Stable order: labels (A, B, ...) then attempt ids — matches race lanes.
54
+ return out.sort((a, b) => (a.label ?? a.attemptId).localeCompare(b.label ?? b.attemptId));
55
+ }
56
+ function numberOr(v, fallback) {
57
+ return typeof v === "number" && Number.isFinite(v) && v >= 0 ? v : fallback;
58
+ }
59
+ function readYamlMaybe(path) {
60
+ try {
61
+ if (!existsSync(path))
62
+ return null;
63
+ return (parseYaml(readFileSync(path, "utf8")) ?? null);
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ }
69
+ function safeReaddir(dir) {
70
+ try {
71
+ return readdirSync(dir);
72
+ }
73
+ catch {
74
+ return [];
75
+ }
76
+ }
77
+ //# sourceMappingURL=candidates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidates.js","sourceRoot":"","sources":["../src/candidates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,196 @@
1
+ export { normalizeRunStartRequest } from "./run-start.js";
2
+ import { AttachmentInput, type ControlPendingInteraction } from "@claudexor/schema";
3
+ export interface DaemonRunRecord {
4
+ id: string;
5
+ state: string;
6
+ runId?: string;
7
+ taskId?: string;
8
+ runDir?: string;
9
+ error?: string;
10
+ params?: unknown;
11
+ createdAt?: string;
12
+ startedAt?: string;
13
+ finishedAt?: string;
14
+ }
15
+ export interface DaemonFacadeClient {
16
+ enqueue(params: unknown): Promise<{
17
+ id: string;
18
+ state: string;
19
+ }>;
20
+ status(id: string): Promise<DaemonRunRecord>;
21
+ list(): Promise<DaemonRunRecord[]>;
22
+ cancel(id: string): Promise<unknown>;
23
+ }
24
+ export interface DaemonControlApiOptions {
25
+ token: string;
26
+ daemon: DaemonFacadeClient;
27
+ host?: string;
28
+ port?: number;
29
+ pollMs?: number;
30
+ /** SSE comment-ping cadence so quiet phases are distinguishable from dead connections. */
31
+ heartbeatMs?: number;
32
+ runStartTimeoutMs?: number;
33
+ /**
34
+ * In-process run-event push source (the daemon's RunEventBus). The events
35
+ * FILE stays the canonical ordered log: a push only pokes the tailer so SSE
36
+ * latency drops from poll cadence to immediate, with the poll as fallback.
37
+ */
38
+ bus?: {
39
+ subscribe(listener: (event: {
40
+ run_id: string;
41
+ }) => void): () => void;
42
+ };
43
+ services?: {
44
+ harnesses?: () => Promise<unknown>;
45
+ /** Derived AgentCapabilityCatalog (GET /agent-capabilities). */
46
+ agentCapabilities?: () => Promise<unknown>;
47
+ /** Enumerable models for one harness (ADP4); thin projection over the adapter's optional models(). */
48
+ harnessModels?: (input: {
49
+ harnessId: string;
50
+ }) => Promise<unknown>;
51
+ createSetupJob?: (input: unknown) => Promise<unknown>;
52
+ listSetupJobs?: () => Promise<unknown>;
53
+ setupJobStatus?: (input: unknown) => Promise<unknown>;
54
+ cancelSetupJob?: (input: unknown) => Promise<unknown>;
55
+ confirmSetupJob?: (input: unknown) => Promise<unknown>;
56
+ settings?: () => Promise<unknown>;
57
+ updateSettings?: (patch: unknown) => Promise<unknown>;
58
+ listSecrets?: () => Promise<unknown>;
59
+ setSecret?: (input: unknown) => Promise<unknown>;
60
+ deleteSecret?: (name: string) => Promise<unknown>;
61
+ specQuestions?: (input: unknown) => Promise<unknown>;
62
+ specFreeze?: (input: unknown) => Promise<unknown>;
63
+ /** Live waiting_on_user state (daemon InteractionRegistry projections). */
64
+ pendingInteractions?: (runId: string) => ControlPendingInteraction[];
65
+ answerInteraction?: (runId: string, interactionId: string, answers: unknown) => {
66
+ status: string;
67
+ message?: string;
68
+ };
69
+ /** Thread/session SSOT (chat/session-first). */
70
+ createThread?: (input: unknown) => Promise<unknown>;
71
+ listThreads?: () => Promise<{
72
+ threads: unknown[];
73
+ }>;
74
+ threadDetail?: (id: string) => Promise<{
75
+ thread: unknown;
76
+ sessions: unknown[];
77
+ turns: unknown[];
78
+ }>;
79
+ /** Single-writer turn creation (run_id bound later by the daemon runner). */
80
+ createThreadTurn?: (id: string, prompt: string, opts: {
81
+ kind?: unknown;
82
+ parentRunId?: string | null;
83
+ planRunId?: string | null;
84
+ attachments?: AttachmentInput[];
85
+ }) => Promise<unknown>;
86
+ /** Rename / archive a thread or switch its sticky primary/pool. */
87
+ updateThread?: (id: string, patch: {
88
+ title?: string;
89
+ state?: string;
90
+ primaryHarness?: string | null;
91
+ eligibleHarnesses?: string[];
92
+ }) => Promise<unknown>;
93
+ /** Deliver an isolated thread's accumulated worktree diff to the project. */
94
+ applyThread?: (id: string, opts: {
95
+ mode: string;
96
+ branch?: string;
97
+ message?: string;
98
+ }) => Promise<unknown>;
99
+ /** Persist why a turn's run could not be enqueued (runless-turn honesty).
100
+ * `code` is the typed throw's machine code (null if none); `retryable`
101
+ * false marks refusals with no recorded job to replay. */
102
+ setTurnEnqueueError?: (turnId: string, message: string, code: string | null, retryable?: boolean) => void;
103
+ /** User-level trust: enumerate per-repo trust files (Settings projection). */
104
+ listTrust?: () => Promise<unknown>;
105
+ /** NARROW trust write: grant/revoke full access for ONE repo — the same
106
+ * user-level file `claudexor trust` owns; every other trust field stays
107
+ * CLI-only. */
108
+ updateTrust?: (input: {
109
+ repoRoot: string;
110
+ allowFullAccess: boolean;
111
+ }) => Promise<unknown>;
112
+ };
113
+ }
114
+ /**
115
+ * HTTP/SSE facade over the durable daemon. Canonical run/job state comes from the
116
+ * daemon (`jobs.json` over the unix-socket JSON-RPC API). This server is a live
117
+ * viewport only: POST/GET/cancel delegate to daemon, and event streams replay/tail
118
+ * the canonical `.claudexor/runs/<runId>/events.jsonl` file.
119
+ */
120
+ export declare class DaemonControlApiServer {
121
+ private readonly opts;
122
+ private server?;
123
+ private readonly sseClients;
124
+ /** Per-thread turn submission chains (serialize head_run_id lineage updates). */
125
+ private readonly threadTurnChains;
126
+ constructor(opts: DaemonControlApiOptions);
127
+ start(): Promise<{
128
+ host: string;
129
+ port: number;
130
+ }>;
131
+ stop(): Promise<void>;
132
+ private tokenMatches;
133
+ private authorized;
134
+ /**
135
+ * ONE owner of the bad-request envelope: status from the typed error,
136
+ * message text, and the machine-readable `code` (e.g.
137
+ * inline_secret_rejected) when the error carries one.
138
+ */
139
+ private requestError;
140
+ private json;
141
+ private readBody;
142
+ private onRequest;
143
+ private handle;
144
+ private service;
145
+ /**
146
+ * Live setup-job lifecycle stream: emits a `status` event on every state or
147
+ * message transition until the job reaches a terminal state. Backed by
148
+ * polling the job service (the manager has no event bus), which is exactly
149
+ * what the previous one-shot stub forced every client to reimplement.
150
+ */
151
+ private streamSetupJobEvents;
152
+ private waitForRunStart;
153
+ private findRun;
154
+ /** Bound helper context for the extracted thread-turn write routes.
155
+ * Callers guard the required services (threadDetail/createThreadTurn)
156
+ * before routing here. */
157
+ private threadTurnRouteCtx;
158
+ /** Read a run's text artifact (e.g. final/plan.md) for the "Implement plan" turn. */
159
+ private readRunArtifactText;
160
+ private readonly summaryCache;
161
+ /**
162
+ * GET /runs is the app's main screen and used to re-read every artifact for
163
+ * every retained job on every poll (O(jobs x file size) sync I/O). Terminal
164
+ * runs change only when their artifacts change, so summaries are cached on a
165
+ * state+artifact-mtime fingerprint.
166
+ */
167
+ private summarizeRunCached;
168
+ /**
169
+ * Cached artifact projection + LIVE waiting_on_user overlay. Pending
170
+ * interactions are in-process daemon state, not an artifact, so they must
171
+ * never be frozen into the fingerprint cache.
172
+ */
173
+ private summarizeRunLive;
174
+ /**
175
+ * Degrade contract shared by GET /runs and the thread-detail turn cards:
176
+ * one unprojectable job record becomes a diagnostic row, never a 500 for
177
+ * the whole list/thread.
178
+ */
179
+ private summarizeRunOrDiagnostic;
180
+ private lastEventId;
181
+ private streamEvents;
182
+ /**
183
+ * Global live-only event multiplex (GET /events): every run's events as they
184
+ * happen, tagged with run_id, no replay. Documented asymmetry vs the per-run
185
+ * stream: reconnecting clients re-snapshot /runs first, then resume per-run
186
+ * streams (which DO replay via persisted seq) where they need gap-free state.
187
+ */
188
+ private streamGlobalEvents;
189
+ private pendingInteractionsFor;
190
+ }
191
+ /** A run's project root, taken from its TYPED scope — NOT by path-slicing the
192
+ * runDir. Slicing on `.claudexor` would resolve a no-project run (whose run dir
193
+ * is `~/.claudexor/runs/<id>`) to the user's HOME and let /produced list
194
+ * `~/artifacts` (review-flagged). Null for scope `none` ⇒ no produced outputs. */
195
+ export declare function producedRepoRoot(rec: DaemonRunRecord): string | null;
196
+ //# sourceMappingURL=daemon-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-server.d.ts","sourceRoot":"","sources":["../src/daemon-server.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,EAGL,eAAe,EAkCf,KAAK,yBAAyB,EAsB/B,MAAM,mBAAmB,CAAC;AAK3B,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC7C,IAAI,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,GAAG,CAAC,EAAE;QAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,KAAK,IAAI,GAAG,MAAM,IAAI,CAAA;KAAE,CAAC;IAC/E,QAAQ,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QACnC,gEAAgE;QAChE,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QAC3C,sGAAsG;QACtG,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;YAAE,SAAS,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACnE,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACtD,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QACvC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACtD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACtD,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACvD,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QAClC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACtD,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QACrC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QAClD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACrD,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QAClD,2EAA2E;QAC3E,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,yBAAyB,EAAE,CAAC;QACrE,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACrH,gDAAgD;QAChD,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACpD,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;YAAE,OAAO,EAAE,OAAO,EAAE,CAAA;SAAE,CAAC,CAAC;QACpD,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;YAAE,MAAM,EAAE,OAAO,CAAC;YAAC,QAAQ,EAAE,OAAO,EAAE,CAAC;YAAC,KAAK,EAAE,OAAO,EAAE,CAAA;SAAE,CAAC,CAAC;QACnG,6EAA6E;QAC7E,gBAAgB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;YAAE,IAAI,CAAC,EAAE,OAAO,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YAAC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAA;SAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACvL,mEAAmE;QACnE,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QACzJ,6EAA6E;QAC7E,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1G;;kEAE0D;QAC1D,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;QAC1G,8EAA8E;QAC9E,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QACnC;;uBAEe;QACf,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,eAAe,EAAE,OAAO,CAAA;SAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KAC3F,CAAC;CACH;AA6BD;;;;;GAKG;AACH,qBAAa,sBAAsB;IAMrB,OAAO,CAAC,QAAQ,CAAC,IAAI;IALjC,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IACxD,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoC;gBAExC,IAAI,EAAE,uBAAuB;IAEpD,KAAK,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAYhD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,UAAU;IAMlB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,IAAI;YAME,QAAQ;IAkBtB,OAAO,CAAC,SAAS;YAWH,MAAM;YAwwBN,OAAO;IAuBrB;;;;;OAKG;YACW,oBAAoB;YAuEpB,eAAe;YAcf,OAAO;IAMrB;;8BAE0B;IAC1B,OAAO,CAAC,kBAAkB;IAgB1B,qFAAqF;YACvE,mBAAmB;IAUjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0E;IAEvG;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAahC,OAAO,CAAC,WAAW;YAQL,YAAY;IAU1B;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAsC1B,OAAO,CAAC,sBAAsB;CAO/B;AA6gBD;;;mFAGmF;AACnF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAGpE"}