@sentropic/h2a-runtime 0.88.0 → 0.89.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attach.d.ts +21 -0
- package/dist/attach.d.ts.map +1 -1
- package/dist/attach.js +69 -1
- package/dist/attach.js.map +1 -1
- package/dist/file-lock.d.ts +34 -0
- package/dist/file-lock.d.ts.map +1 -0
- package/dist/file-lock.js +96 -0
- package/dist/file-lock.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +289 -18
- package/dist/index.js.map +1 -1
- package/dist/llm-gateway-runtime/accounts.d.ts.map +1 -1
- package/dist/llm-gateway-runtime/accounts.js +3 -0
- package/dist/llm-gateway-runtime/accounts.js.map +1 -1
- package/dist/llm-gateway-runtime/proxy-anthropic.d.ts.map +1 -1
- package/dist/llm-gateway-runtime/proxy-anthropic.js +24 -0
- package/dist/llm-gateway-runtime/proxy-anthropic.js.map +1 -1
- package/dist/llm-gateway-runtime/proxy-openai.d.ts.map +1 -1
- package/dist/llm-gateway-runtime/proxy-openai.js +53 -2
- package/dist/llm-gateway-runtime/proxy-openai.js.map +1 -1
- package/dist/proc-cpu.d.ts +55 -0
- package/dist/proc-cpu.d.ts.map +1 -0
- package/dist/proc-cpu.js +133 -0
- package/dist/proc-cpu.js.map +1 -0
- package/dist/prompt-delivery.d.ts +159 -0
- package/dist/prompt-delivery.d.ts.map +1 -0
- package/dist/prompt-delivery.js +469 -0
- package/dist/prompt-delivery.js.map +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +7 -69
- package/dist/registry.js.map +1 -1
- package/dist/restore.d.ts +20 -4
- package/dist/restore.d.ts.map +1 -1
- package/dist/restore.js +26 -4
- package/dist/restore.js.map +1 -1
- package/dist/session-lease.d.ts +266 -0
- package/dist/session-lease.d.ts.map +1 -0
- package/dist/session-lease.js +342 -0
- package/dist/session-lease.js.map +1 -0
- package/dist/tmux.d.ts +77 -2
- package/dist/tmux.d.ts.map +1 -1
- package/dist/tmux.js +269 -23
- package/dist/tmux.js.map +1 -1
- package/package.json +1 -1
package/dist/proc-cpu.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CPU time of a process TREE, from /proc.
|
|
3
|
+
*
|
|
4
|
+
* Liveness in this repo is CPU time, never a PID: a lane blocked on a modal
|
|
5
|
+
* shows a perfectly healthy process with 1s of CPU in 33 minutes. The tree
|
|
6
|
+
* matters because a launch wrapper may keep a shell as the pane's process while
|
|
7
|
+
* the agent runs as its child.
|
|
8
|
+
*
|
|
9
|
+
* The values are a SIGNAL, not an exact accounting: clock ticks are assumed to
|
|
10
|
+
* be the Linux default of 100 Hz, and only live descendants are counted (a
|
|
11
|
+
* finished child's time is not reclaimed here). Callers compare deltas well
|
|
12
|
+
* above that noise, so the approximation never decides anything on its own.
|
|
13
|
+
*/
|
|
14
|
+
export const DEFAULT_CLOCK_TICKS_PER_SECOND = 100;
|
|
15
|
+
/**
|
|
16
|
+
* Parse one /proc/<pid>/stat line. `comm` may contain spaces and parentheses,
|
|
17
|
+
* so every field is read AFTER the last ')' — splitting on whitespace from the
|
|
18
|
+
* start silently shifts every index for a process named "(my app)".
|
|
19
|
+
*/
|
|
20
|
+
export function parseProcStat(content, clockTicksPerSecond = DEFAULT_CLOCK_TICKS_PER_SECOND) {
|
|
21
|
+
const close = content.lastIndexOf(")");
|
|
22
|
+
if (close === -1)
|
|
23
|
+
return undefined;
|
|
24
|
+
const fields = content.slice(close + 1).trim().split(/\s+/);
|
|
25
|
+
// After comm: [0]=state, [1]=ppid … [11]=utime, [12]=stime (procfs 3,4,14,15).
|
|
26
|
+
const ppid = Number.parseInt(fields[1] ?? "", 10);
|
|
27
|
+
const utime = Number.parseInt(fields[11] ?? "", 10);
|
|
28
|
+
const stime = Number.parseInt(fields[12] ?? "", 10);
|
|
29
|
+
if (!Number.isInteger(ppid) || !Number.isInteger(utime) || !Number.isInteger(stime)) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
ppid,
|
|
34
|
+
cpuMs: ((utime + stime) / clockTicksPerSecond) * 1000,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Total CPU of `rootPid` plus every live descendant. Returns undefined when the
|
|
39
|
+
* root itself is unknown, so "cannot tell" is never reported as "idle".
|
|
40
|
+
*/
|
|
41
|
+
export function sumTreeCpuMs(rootPid, entries) {
|
|
42
|
+
const byParent = new Map();
|
|
43
|
+
const byPid = new Map();
|
|
44
|
+
for (const entry of entries) {
|
|
45
|
+
byPid.set(entry.pid, entry);
|
|
46
|
+
const siblings = byParent.get(entry.ppid);
|
|
47
|
+
if (siblings)
|
|
48
|
+
siblings.push(entry);
|
|
49
|
+
else
|
|
50
|
+
byParent.set(entry.ppid, [entry]);
|
|
51
|
+
}
|
|
52
|
+
const root = byPid.get(rootPid);
|
|
53
|
+
if (!root)
|
|
54
|
+
return undefined;
|
|
55
|
+
let total = 0;
|
|
56
|
+
const queue = [rootPid];
|
|
57
|
+
const seen = new Set();
|
|
58
|
+
while (queue.length > 0) {
|
|
59
|
+
const pid = queue.pop();
|
|
60
|
+
if (seen.has(pid))
|
|
61
|
+
continue; // a /proc snapshot can race into a cycle
|
|
62
|
+
seen.add(pid);
|
|
63
|
+
total += byPid.get(pid)?.cpuMs ?? 0;
|
|
64
|
+
for (const child of byParent.get(pid) ?? [])
|
|
65
|
+
queue.push(child.pid);
|
|
66
|
+
}
|
|
67
|
+
return total;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The descendant actually doing the work.
|
|
71
|
+
*
|
|
72
|
+
* Measured 2026-07-29: a launch reported pid 3392709 (the `node` wrapper) with
|
|
73
|
+
* 0s of CPU after 37s while its child `codex` (3392862) had burned 13s. A
|
|
74
|
+
* liveness check on the REPORTED pid therefore returns a false negative on a
|
|
75
|
+
* perfectly healthy agent, and would call a live wrapper with a dead worker
|
|
76
|
+
* alive. Returns the busiest process in the tree, or the root when it is alone.
|
|
77
|
+
*/
|
|
78
|
+
export function busiestDescendant(rootPid, entries) {
|
|
79
|
+
const list = [...entries];
|
|
80
|
+
const byPid = new Map(list.map((entry) => [entry.pid, entry]));
|
|
81
|
+
const root = byPid.get(rootPid);
|
|
82
|
+
if (!root)
|
|
83
|
+
return undefined;
|
|
84
|
+
const byParent = new Map();
|
|
85
|
+
for (const entry of list) {
|
|
86
|
+
const siblings = byParent.get(entry.ppid);
|
|
87
|
+
if (siblings)
|
|
88
|
+
siblings.push(entry);
|
|
89
|
+
else
|
|
90
|
+
byParent.set(entry.ppid, [entry]);
|
|
91
|
+
}
|
|
92
|
+
let best = rootPid;
|
|
93
|
+
let bestCpu = root.cpuMs;
|
|
94
|
+
const queue = [rootPid];
|
|
95
|
+
const seen = new Set();
|
|
96
|
+
while (queue.length > 0) {
|
|
97
|
+
const pid = queue.pop();
|
|
98
|
+
if (seen.has(pid))
|
|
99
|
+
continue;
|
|
100
|
+
seen.add(pid);
|
|
101
|
+
for (const child of byParent.get(pid) ?? []) {
|
|
102
|
+
if (child.cpuMs > bestCpu) {
|
|
103
|
+
bestCpu = child.cpuMs;
|
|
104
|
+
best = child.pid;
|
|
105
|
+
}
|
|
106
|
+
queue.push(child.pid);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return best;
|
|
110
|
+
}
|
|
111
|
+
/** Snapshot /proc once, parsed into entries. */
|
|
112
|
+
export function snapshotProc(deps) {
|
|
113
|
+
const entries = [];
|
|
114
|
+
for (const pid of deps.listPids()) {
|
|
115
|
+
const raw = deps.readStat(pid);
|
|
116
|
+
if (raw === undefined)
|
|
117
|
+
continue; // exited between listing and reading
|
|
118
|
+
const parsed = parseProcStat(raw, deps.clockTicksPerSecond);
|
|
119
|
+
if (!parsed)
|
|
120
|
+
continue;
|
|
121
|
+
entries.push({ pid, ppid: parsed.ppid, cpuMs: parsed.cpuMs });
|
|
122
|
+
}
|
|
123
|
+
return entries;
|
|
124
|
+
}
|
|
125
|
+
/** Snapshot /proc and total the tree rooted at `rootPid`. */
|
|
126
|
+
export function readProcessTreeCpuMs(rootPid, deps) {
|
|
127
|
+
return sumTreeCpuMs(rootPid, snapshotProc(deps));
|
|
128
|
+
}
|
|
129
|
+
/** Snapshot /proc and name the process actually doing the work. */
|
|
130
|
+
export function readWorkerPid(rootPid, deps) {
|
|
131
|
+
return busiestDescendant(rootPid, snapshotProc(deps));
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=proc-cpu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proc-cpu.js","sourceRoot":"","sources":["../src/proc-cpu.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initial-prompt delivery for managed INTERACTIVE sessions.
|
|
3
|
+
*
|
|
4
|
+
* Measured on the real hosts (codex-cli 0.145.0, Claude Code 2.1.220) on
|
|
5
|
+
* 2026-07-29, through the real `h2a run` path:
|
|
6
|
+
*
|
|
7
|
+
* - `tmux new-session -d` returns as soon as the PANE exists. 15ms later the
|
|
8
|
+
* pane is still EMPTY: the CLI has drawn nothing. A prompt pasted then is
|
|
9
|
+
* ECHOED BY THE RAW TERMINAL — it is visibly "in the pane" while no composer
|
|
10
|
+
* exists to hold it — and the TUI discards it when it takes over the screen.
|
|
11
|
+
* Both profiles lost their brief that way and sat on their placeholder with
|
|
12
|
+
* ~0s of CPU while `run` reported state:"started".
|
|
13
|
+
* - `paste-buffer` WITHOUT `-p` submits a multi-line brief line by line: line 1
|
|
14
|
+
* became its own request while line 2 stayed in the composer. With `-p` the
|
|
15
|
+
* whole block lands as one entry that a single Enter submits.
|
|
16
|
+
* - An Enter fired while the host was still rendering was swallowed, leaving
|
|
17
|
+
* the brief composed but unsent — and the startup CPU burn (+1950ms) looked
|
|
18
|
+
* exactly like work.
|
|
19
|
+
* - Host modals swallow the brief the same silent way. THREE showed up in one
|
|
20
|
+
* afternoon: directory trust, "Update available!", "Hooks need review".
|
|
21
|
+
*
|
|
22
|
+
* Hence the shape of this module: type ONCE, into a host that has drawn its UI
|
|
23
|
+
* and gone quiet, then prove the text is there, then submit, then judge work
|
|
24
|
+
* against the host's own idle rate. Nothing here reports success because a tmux
|
|
25
|
+
* command exited 0 — that is what let a launch claim `started` while the agent
|
|
26
|
+
* was inert for 33 minutes.
|
|
27
|
+
*/
|
|
28
|
+
/** A host modal that will never be answered inside a background lane. */
|
|
29
|
+
export type HostModal = {
|
|
30
|
+
readonly reason: string;
|
|
31
|
+
readonly hint: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Is the pane sitting on a host modal that consumes the brief? Returns the
|
|
35
|
+
* exact reason so the launch can FAIL LOUDLY instead of waiting forever.
|
|
36
|
+
*/
|
|
37
|
+
export declare function detectHostModal(capture: string): HostModal | undefined;
|
|
38
|
+
/** Collapse every whitespace run so a soft-wrapped composer still matches. */
|
|
39
|
+
export declare function normalizePaneText(text: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Fingerprints used to PROVE the pasted text reached the composer — one from
|
|
42
|
+
* each end.
|
|
43
|
+
*
|
|
44
|
+
* A composer that overflows shows only part of the brief, and which part it
|
|
45
|
+
* keeps is a host rendering choice (measured: Claude Code keeps the HEAD and
|
|
46
|
+
* cuts the tail). Looking for either end means the proof does not depend on
|
|
47
|
+
* that choice.
|
|
48
|
+
*/
|
|
49
|
+
export declare function promptProbes(prompt: string): ReadonlyArray<string>;
|
|
50
|
+
/**
|
|
51
|
+
* A long paste is COLLAPSED by both hosts instead of being shown as text.
|
|
52
|
+
* Measured 2026-07-29 with a 10977-character brief:
|
|
53
|
+
* codex -> "› [Pasted Content 10977 chars]"
|
|
54
|
+
* claude -> "❯ [Pasted text #1 +71 lines]"
|
|
55
|
+
* The brief's own words appear NOWHERE in the pane, so a fingerprint search
|
|
56
|
+
* alone would reject every long brief — and lane briefs are long. The marker is
|
|
57
|
+
* in fact stronger evidence: it states the size the host received, so it can be
|
|
58
|
+
* checked against what was sent.
|
|
59
|
+
*/
|
|
60
|
+
export type CollapsedPaste = {
|
|
61
|
+
readonly kind: "chars";
|
|
62
|
+
readonly value: number;
|
|
63
|
+
} | {
|
|
64
|
+
readonly kind: "lines";
|
|
65
|
+
readonly value: number;
|
|
66
|
+
};
|
|
67
|
+
export declare function detectCollapsedPaste(capture: string): CollapsedPaste | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Does a collapsed-paste marker account for the brief we sent? Compared with a
|
|
70
|
+
* tolerance: hosts differ on counting UTF-8 bytes vs code points, and the line
|
|
71
|
+
* count is reported as "additional" lines.
|
|
72
|
+
*/
|
|
73
|
+
export declare function collapsedPasteMatches(marker: CollapsedPaste, prompt: string): boolean;
|
|
74
|
+
/** How many times does the fingerprint appear in a pane capture? */
|
|
75
|
+
export declare function countOccurrences(capture: string, probe: string): number;
|
|
76
|
+
/**
|
|
77
|
+
* Has the host actually DRAWN its interface?
|
|
78
|
+
*
|
|
79
|
+
* 15ms after `new-session` the pane is still empty, and a paste there is merely
|
|
80
|
+
* echoed by the raw terminal. Requiring real drawn content is what separates
|
|
81
|
+
* "the composer holds my brief" from "the terminal echoed my keystrokes".
|
|
82
|
+
*/
|
|
83
|
+
export declare function paneHasDrawnUi(capture: string, minLines?: number): boolean;
|
|
84
|
+
export type PromptDeliveryDeps = {
|
|
85
|
+
/** Visible text of the pane, or undefined when tmux cannot be read. */
|
|
86
|
+
readonly capturePane: (pane: string) => string | undefined;
|
|
87
|
+
/** Best-effort composer wipe (never relied upon: delivery types once). */
|
|
88
|
+
readonly clearComposer: (pane: string) => boolean;
|
|
89
|
+
/** Paste text as ONE bracketed block (no per-line submission). */
|
|
90
|
+
readonly pasteBlock: (pane: string, text: string) => boolean;
|
|
91
|
+
/** Send the single Enter that submits the composed block. */
|
|
92
|
+
readonly submit: (pane: string) => boolean;
|
|
93
|
+
/** CPU time consumed by the pane's process tree, in ms. */
|
|
94
|
+
readonly cpuMs: (pane: string) => number | undefined;
|
|
95
|
+
readonly sleep: (ms: number) => void;
|
|
96
|
+
readonly now: () => number;
|
|
97
|
+
};
|
|
98
|
+
export type PromptDeliveryOptions = {
|
|
99
|
+
/** Budget for the host to become ready (default 90s). */
|
|
100
|
+
readonly timeoutMs?: number;
|
|
101
|
+
/** Delay between readiness observations (default 750ms). */
|
|
102
|
+
readonly pollMs?: number;
|
|
103
|
+
/** Window in which real work must show up after submitting (default 30s). */
|
|
104
|
+
readonly activityMs?: number;
|
|
105
|
+
/** CPU above the host's idle rate that counts as work (default 300ms). */
|
|
106
|
+
readonly activityCpuMs?: number;
|
|
107
|
+
/** Sampling window used to decide the host has gone quiet (default 2s). */
|
|
108
|
+
readonly quietMs?: number;
|
|
109
|
+
/** CPU under which the host counts as quiet, per window (default 40ms). */
|
|
110
|
+
readonly quietCpuMs?: number;
|
|
111
|
+
/**
|
|
112
|
+
* Highest steady CPU rate (ms of CPU per ms of clock) still treated as "waiting
|
|
113
|
+
* for input" — default 0.3, i.e. a third of one core. Above it a host is busy,
|
|
114
|
+
* not idle, and an Enter typed into it can be swallowed.
|
|
115
|
+
*/
|
|
116
|
+
readonly maxIdleRate?: number;
|
|
117
|
+
/** How long to wait for the composer to RENDER the paste (default 8s). */
|
|
118
|
+
readonly landedMs?: number;
|
|
119
|
+
};
|
|
120
|
+
/** How the brief was proven present: visible text, or a collapsed-paste marker. */
|
|
121
|
+
export type LandedEvidence = "composer-text" | "collapsed-paste";
|
|
122
|
+
export type PromptDeliveryResult = {
|
|
123
|
+
readonly state: "working";
|
|
124
|
+
readonly waitedMs: number;
|
|
125
|
+
readonly cpuDeltaMs: number;
|
|
126
|
+
readonly evidence: LandedEvidence;
|
|
127
|
+
} | {
|
|
128
|
+
readonly state: "submitted-idle";
|
|
129
|
+
readonly waitedMs: number;
|
|
130
|
+
readonly cpuDeltaMs: number;
|
|
131
|
+
readonly evidence: LandedEvidence;
|
|
132
|
+
} | {
|
|
133
|
+
readonly state: "host-modal";
|
|
134
|
+
readonly reason: string;
|
|
135
|
+
readonly hint: string;
|
|
136
|
+
readonly capture: string;
|
|
137
|
+
} | {
|
|
138
|
+
readonly state: "undelivered";
|
|
139
|
+
readonly reason: string;
|
|
140
|
+
readonly waitedMs: number;
|
|
141
|
+
readonly capture: string;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Sleep without spinning. `Atomics.wait` on a private SharedArrayBuffer is the
|
|
145
|
+
* repo's synchronous-wait primitive (same as the local-files lock), so delivery
|
|
146
|
+
* stays synchronous instead of rippling async through the launch path.
|
|
147
|
+
*/
|
|
148
|
+
export declare function sleepSync(ms: number): void;
|
|
149
|
+
/** Last non-empty lines of a capture, for an actionable failure message. */
|
|
150
|
+
export declare function captureTail(capture: string, lines?: number): string;
|
|
151
|
+
/**
|
|
152
|
+
* Deliver `prompt` to a live agent pane and REPORT WHAT WAS OBSERVED.
|
|
153
|
+
*
|
|
154
|
+
* Types the brief EXACTLY ONCE. Retrying a paste is what stacked twelve copies
|
|
155
|
+
* of a brief into one composer when a wipe silently failed, so a brief that
|
|
156
|
+
* cannot be proven present is a failure to report, never a paste to repeat.
|
|
157
|
+
*/
|
|
158
|
+
export declare function deliverInitialPrompt(pane: string, prompt: string, deps: PromptDeliveryDeps, options?: PromptDeliveryOptions): PromptDeliveryResult;
|
|
159
|
+
//# sourceMappingURL=prompt-delivery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-delivery.d.ts","sourceRoot":"","sources":["../src/prompt-delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,yEAAyE;AACzE,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAwCF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CActE;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAelE;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,GACd,cAAc,GAAG,SAAS,CAM5B;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAkBT;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAYvE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,OAAO,CAKrE;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC3D,0EAA0E;IAC1E,QAAQ,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAClD,kEAAkE;IAClE,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7D,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAEjE,MAAM,MAAM,oBAAoB,GAC5B;IACE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CACnC,GACD;IACE,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CACnC,GACD;IACE,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,GACD;IACE,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AA0BN;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAQ1C;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,MAAM,CAO9D;AA+ED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,kBAAkB,EACxB,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CA6LtB"}
|