@djolex999/vir-cli 0.13.0 → 0.14.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.
@@ -0,0 +1,226 @@
1
+ import { closeSync, openSync, readSync, readdirSync } from "node:fs";
2
+ import { basename, dirname, join, relative, sep } from "node:path";
3
+ import { computeCost } from "../cost/pricing.js";
4
+ function defaultReadDir(path) {
5
+ try {
6
+ return readdirSync(path, { withFileTypes: true })
7
+ .filter((e) => e.isDirectory())
8
+ .map((e) => e.name);
9
+ }
10
+ catch {
11
+ return [];
12
+ }
13
+ }
14
+ // Claude Code encodes a session's cwd into the transcript dir name by
15
+ // replacing every non-alphanumeric character with "-". Apply the same
16
+ // encoding to real dir names so on-disk candidates compare against the
17
+ // encoded segments byte-for-byte.
18
+ function encodeSegment(name) {
19
+ return name.replace(/[^A-Za-z0-9]/g, "-");
20
+ }
21
+ // Walk the real filesystem from `cur`, consuming `remaining` (the encoded
22
+ // path with its leading dash stripped). Dashes are ambiguous — they encode
23
+ // both path separators and literal dashes/dots/spaces — so try candidates
24
+ // longest-encoding-first and backtrack: only a FULL resolution counts.
25
+ // Returns the on-disk basename of the resolved leaf, or null.
26
+ function resolveEncoded(cur, remaining, readDir) {
27
+ const candidates = readDir(cur)
28
+ .map((name) => ({ name, enc: encodeSegment(name) }))
29
+ .filter(({ enc }) => enc.length > 0 &&
30
+ (enc === remaining || remaining.startsWith(enc + "-")))
31
+ .sort((a, b) => b.enc.length - a.enc.length);
32
+ for (const { name, enc } of candidates) {
33
+ if (enc === remaining)
34
+ return name;
35
+ const leaf = resolveEncoded(join(cur, name), remaining.slice(enc.length + 1), readDir);
36
+ if (leaf !== null)
37
+ return leaf;
38
+ }
39
+ return null;
40
+ }
41
+ // Decode a transcript directory name ("-Users-me-projects-my-app") to its
42
+ // project name ("my-app") by resolving the encoded absolute path against
43
+ // directories that actually exist on disk, longest match wins. Falls back to
44
+ // the raw dir name when nothing fully resolves — never throws, never guesses.
45
+ export function decodeProjectName(dirName, projectsDir, deps) {
46
+ const readDir = deps?.readDir ?? defaultReadDir;
47
+ const name = dirName.includes("/") && dirName.startsWith(projectsDir)
48
+ ? basename(dirName)
49
+ : dirName;
50
+ if (!name.startsWith("-"))
51
+ return name;
52
+ const leaf = resolveEncoded("/", name.slice(1), readDir);
53
+ return leaf ?? name;
54
+ }
55
+ export function classifyTranscript(path, projectsDir) {
56
+ const rel = relative(projectsDir, path);
57
+ if (rel.startsWith(".."))
58
+ return "session";
59
+ const segments = rel.split(sep);
60
+ // segments[0] is the encoded project dir; look for `subagents` below it.
61
+ const subIdx = segments.indexOf("subagents", 1);
62
+ if (subIdx === -1)
63
+ return "session";
64
+ const below = segments.slice(subIdx + 1);
65
+ const isWorkflow = below.some((s) => s === "workflows" || s.startsWith("wf_"));
66
+ return isWorkflow ? "workflow" : "sidechain";
67
+ }
68
+ // SDK launch signature: the first `type:"user"` line's `entrypoint` starting
69
+ // with "sdk" marks an agent-internal transcript (review/verify harness agents
70
+ // stored top-level). Keyed on entrypoint ONLY — promptSource reads "sdk" even
71
+ // on desktop-launched human sessions (the C23 serbeval trap), and turn count
72
+ // would kill single-prompt autonomous runs. Returns the entrypoint, or null
73
+ // for human sessions, truncated heads, or anything unparseable — a miss here
74
+ // falls through to the parser backstop, never to a paid call.
75
+ export function sniffAgentEntrypoint(head) {
76
+ for (const line of head.split("\n")) {
77
+ if (line.trim().length === 0)
78
+ continue;
79
+ let evt;
80
+ try {
81
+ evt = JSON.parse(line);
82
+ }
83
+ catch {
84
+ // truncated tail line or garbage — never a user line we can trust
85
+ continue;
86
+ }
87
+ if (evt.type !== "user")
88
+ continue;
89
+ return typeof evt.entrypoint === "string" &&
90
+ evt.entrypoint.startsWith("sdk")
91
+ ? evt.entrypoint
92
+ : null;
93
+ }
94
+ return null;
95
+ }
96
+ // Chunk size for the scan-time sniff. Review-agent first prompts embed whole
97
+ // diffs, so the first user line can be >100KB — and a queue-operation enqueue
98
+ // preamble DUPLICATES that prompt before it (observed: 133KB enqueue + 134KB
99
+ // user line, neither alone over one chunk, together past it). So the reader
100
+ // below keeps appending chunks until a COMPLETE user line is buffered instead
101
+ // of stopping at a fixed byte count — raising the constant would just lose
102
+ // the same race at a bigger size, since the preamble scales with the prompt.
103
+ export const SNIFF_HEAD_BYTES = 262_144;
104
+ // Hard ceiling — a pathological transcript must not drag the scan toward a
105
+ // full-file read. Past this, the sniff gives up (null → interactive; never
106
+ // downgrade what we can't see — the parser backstop still catches it later).
107
+ export const SNIFF_CAP_BYTES = 4 * SNIFF_HEAD_BYTES;
108
+ // True when a complete line in the buffer parses as a user event. The final
109
+ // line is complete only at EOF — a mid-line chunk boundary must not count.
110
+ function hasCompleteUserLine(head, eof) {
111
+ const lines = head.split("\n");
112
+ const complete = eof ? lines.length : lines.length - 1;
113
+ for (let i = 0; i < complete; i++) {
114
+ const line = lines[i];
115
+ if (line === undefined || line.trim().length === 0)
116
+ continue;
117
+ try {
118
+ if (JSON.parse(line).type === "user")
119
+ return true;
120
+ }
121
+ catch {
122
+ // non-JSON or garbage line — keep scanning
123
+ }
124
+ }
125
+ return false;
126
+ }
127
+ export function readTranscriptHead(path, bytes = SNIFF_HEAD_BYTES, cap = SNIFF_CAP_BYTES) {
128
+ try {
129
+ const fd = openSync(path, "r");
130
+ try {
131
+ const buf = Buffer.alloc(bytes);
132
+ // Decode from the concatenated bytes each round — decoding chunks
133
+ // separately would corrupt a multi-byte char split across a boundary.
134
+ const chunks = [];
135
+ let pos = 0;
136
+ for (;;) {
137
+ const n = readSync(fd, buf, 0, bytes, pos);
138
+ chunks.push(Buffer.from(buf.subarray(0, n)));
139
+ pos += n;
140
+ const eof = n < bytes;
141
+ const head = Buffer.concat(chunks).toString("utf8");
142
+ if (eof || pos >= cap || hasCompleteUserLine(head, eof))
143
+ return head;
144
+ }
145
+ }
146
+ finally {
147
+ closeSync(fd);
148
+ }
149
+ }
150
+ catch {
151
+ return "";
152
+ }
153
+ }
154
+ // Rough triage category for the init wizard's counts line
155
+ // ("21 interactive · 67 SDK-launched · 9 stubs"). Display-only — the run
156
+ // gate uses sniffAgentEntrypoint directly. A stub is a tiny COMPLETE
157
+ // transcript (head covers the whole file) with ≤10 non-blank lines: /clear
158
+ // markers and aborted launches. A truncated head is always interactive —
159
+ // never downgrade what we can't see.
160
+ export function categorizeTranscriptHead(head, sizeBytes) {
161
+ if (sniffAgentEntrypoint(head) !== null)
162
+ return "agent";
163
+ const complete = head.length >= sizeBytes;
164
+ const lines = head.split("\n").filter((l) => l.trim().length > 0).length;
165
+ return complete && lines <= 10 ? "stub" : "interactive";
166
+ }
167
+ export function decideProject(name, configured, flags) {
168
+ const configuredDecision = configured[name];
169
+ if (configuredDecision === "exclude")
170
+ return "exclude";
171
+ if (flags?.excludeProject?.includes(name) === true)
172
+ return "flag-skip";
173
+ if (flags?.only !== undefined &&
174
+ flags.only.length > 0 &&
175
+ !flags.only.includes(name)) {
176
+ return "flag-skip";
177
+ }
178
+ return configuredDecision === "include" ? "include" : "pending";
179
+ }
180
+ // Group discovered sessions by decoded project name. Two transcript dirs can
181
+ // decode to the same project (rare, but a renamed cwd does it) — they merge.
182
+ // The decode cache matters: decodeProjectName walks the filesystem, and a
183
+ // scan can hold hundreds of sessions across a handful of dirs.
184
+ export function groupByProject(sessions, projectsDir, deps) {
185
+ const cache = new Map();
186
+ const groups = new Map();
187
+ for (const s of sessions) {
188
+ // The project dir is the FIRST segment under projectsDir — workflow and
189
+ // subagent transcripts nest one level deeper (<encoded>/<session-id>/
190
+ // wf_*.jsonl) and must group under their project, not the inner dir.
191
+ const rel = relative(projectsDir, s.path);
192
+ const dirName = !rel.startsWith("..") && rel.includes(sep)
193
+ ? (rel.split(sep)[0] ?? basename(dirname(s.path)))
194
+ : basename(dirname(s.path));
195
+ let name = cache.get(dirName);
196
+ if (name === undefined) {
197
+ name = decodeProjectName(dirName, projectsDir, deps);
198
+ cache.set(dirName, name);
199
+ }
200
+ let g = groups.get(name);
201
+ if (!g) {
202
+ g = { name, sessions: [], totalBytes: 0 };
203
+ groups.set(name, g);
204
+ }
205
+ g.sessions.push(s);
206
+ g.totalBytes += s.size;
207
+ }
208
+ return groups;
209
+ }
210
+ // Rough per-session cost estimate from raw transcript size — for the triage
211
+ // UIs (init multi-select, undecided prompt, `vir projects`), NOT billing.
212
+ // Derivation from real dry-run calibration: transcript prose+tools ≈ half the
213
+ // JSONL bytes, the moderate tool filter keeps ~45% of that, chars/3 density
214
+ // → distill input ≈ bytes/13; classify sees prose only ≈ bytes/60. Upper
215
+ // bound: heuristic-filtered sessions actually cost nothing.
216
+ const DISTILL_BYTES_PER_TOKEN = 13;
217
+ const CLASSIFY_BYTES_PER_TOKEN = 60;
218
+ const MAX_DISTILL_INPUT_TOKENS = 150_000;
219
+ const MAX_CLASSIFY_INPUT_TOKENS = 30_000;
220
+ export function estimateSessionCost(provider, classifyModel, distillModel, sizeBytes, pricing, kieTopUpTier) {
221
+ const classifyIn = Math.min(Math.ceil(sizeBytes / CLASSIFY_BYTES_PER_TOKEN), MAX_CLASSIFY_INPUT_TOKENS);
222
+ const distillIn = Math.min(Math.ceil(sizeBytes / DISTILL_BYTES_PER_TOKEN), MAX_DISTILL_INPUT_TOKENS);
223
+ return (computeCost(provider, classifyModel, classifyIn, 350, pricing, kieTopUpTier) +
224
+ computeCost(provider, distillModel, distillIn, 4500, pricing, kieTopUpTier));
225
+ }
226
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/pipeline/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,WAAW,EAAyB,MAAM,oBAAoB,CAAC;AAQxE,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;aAC9C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;aAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,sEAAsE;AACtE,sEAAsE;AACtE,uEAAuE;AACvE,kCAAkC;AAClC,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED,0EAA0E;AAC1E,2EAA2E;AAC3E,0EAA0E;AAC1E,uEAAuE;AACvE,8DAA8D;AAC9D,SAAS,cAAc,CACrB,GAAW,EACX,SAAiB,EACjB,OAAmC;IAEnC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC;SAC5B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACnD,MAAM,CACL,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CACV,GAAG,CAAC,MAAM,GAAG,CAAC;QACd,CAAC,GAAG,KAAK,SAAS,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CACzD;SACA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/C,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,UAAU,EAAE,CAAC;QACvC,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACnC,MAAM,IAAI,GAAG,cAAc,CACzB,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EACf,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,EAC/B,OAAO,CACR,CAAC;QACF,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,0EAA0E;AAC1E,yEAAyE;AACzE,6EAA6E;AAC7E,8EAA8E;AAC9E,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,WAAmB,EACnB,IAA0B;IAE1B,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,cAAc,CAAC;IAChD,MAAM,IAAI,GACR,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC;QACtD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QACnB,CAAC,CAAC,OAAO,CAAC;IACd,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACzD,OAAO,IAAI,IAAI,IAAI,CAAC;AACtB,CAAC;AAYD,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,WAAmB;IAEnB,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACxC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,yEAAyE;IACzE,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAChD,IAAI,MAAM,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAC3B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,WAAW,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAChD,CAAC;IACF,OAAO,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;AAC/C,CAAC;AAED,6EAA6E;AAC7E,8EAA8E;AAC9E,8EAA8E;AAC9E,6EAA6E;AAC7E,4EAA4E;AAC5E,6EAA6E;AAC7E,8DAA8D;AAC9D,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACvC,IAAI,GAA6C,CAAC;QAClD,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA6C,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;YAClE,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM;YAAE,SAAS;QAClC,OAAO,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ;YACvC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC;YAChC,CAAC,CAAC,GAAG,CAAC,UAAU;YAChB,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6EAA6E;AAC7E,8EAA8E;AAC9E,6EAA6E;AAC7E,4EAA4E;AAC5E,8EAA8E;AAC9E,2EAA2E;AAC3E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AACxC,2EAA2E;AAC3E,2EAA2E;AAC3E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAG,gBAAgB,CAAC;AAEpD,4EAA4E;AAC5E,2EAA2E;AAC3E,SAAS,mBAAmB,CAAC,IAAY,EAAE,GAAY;IACrD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAC7D,IAAI,CAAC;YACH,IAAK,IAAI,CAAC,KAAK,CAAC,IAAI,CAAwB,CAAC,IAAI,KAAK,MAAM;gBAAE,OAAO,IAAI,CAAC;QAC5E,CAAC;QAAC,MAAM,CAAC;YACP,2CAA2C;QAC7C,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,QAAgB,gBAAgB,EAChC,MAAc,eAAe;IAE7B,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChC,kEAAkE;YAClE,sEAAsE;YACtE,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,SAAS,CAAC;gBACR,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;gBAC3C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7C,GAAG,IAAI,CAAC,CAAC;gBACT,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC;gBACtB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACpD,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,mBAAmB,CAAC,IAAI,EAAE,GAAG,CAAC;oBAAE,OAAO,IAAI,CAAC;YACvE,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,SAAS,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,0DAA0D;AAC1D,yEAAyE;AACzE,qEAAqE;AACrE,2EAA2E;AAC3E,yEAAyE;AACzE,qCAAqC;AACrC,MAAM,UAAU,wBAAwB,CACtC,IAAY,EACZ,SAAiB;IAEjB,IAAI,oBAAoB,CAAC,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,OAAO,CAAC;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IACzE,OAAO,QAAQ,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC;AAC1D,CAAC;AAcD,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,UAAiD,EACjD,KAAuB;IAEvB,MAAM,kBAAkB,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,kBAAkB,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACvD,IAAI,KAAK,EAAE,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,WAAW,CAAC;IACvE,IACE,KAAK,EAAE,IAAI,KAAK,SAAS;QACzB,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QACrB,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC1B,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,OAAO,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAClE,CAAC;AAQD,6EAA6E;AAC7E,6EAA6E;AAC7E,0EAA0E;AAC1E,+DAA+D;AAC/D,MAAM,UAAU,cAAc,CAC5B,QAA6D,EAC7D,WAAmB,EACnB,IAA0B;IAE1B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,wEAAwE;QACxE,sEAAsE;QACtE,qEAAqE;QACrE,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,OAAO,GACX,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;YACxC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAClD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAChC,IAAI,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,IAAI,GAAG,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;YACrD,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACtB,CAAC;QACD,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,IAAI,CAAC;IACzB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4EAA4E;AAC5E,0EAA0E;AAC1E,8EAA8E;AAC9E,4EAA4E;AAC5E,yEAAyE;AACzE,4DAA4D;AAC5D,MAAM,uBAAuB,GAAG,EAAE,CAAC;AACnC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AACpC,MAAM,wBAAwB,GAAG,OAAO,CAAC;AACzC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAEzC,MAAM,UAAU,mBAAmB,CACjC,QAA6B,EAC7B,aAAqB,EACrB,YAAoB,EACpB,SAAiB,EACjB,OAA0B,EAC1B,YAAkC;IAElC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CACzB,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,wBAAwB,CAAC,EAC/C,yBAAyB,CAC1B,CAAC;IACF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CACxB,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,uBAAuB,CAAC,EAC9C,wBAAwB,CACzB,CAAC;IACF,OAAO,CACL,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,CAAC;QAC5E,WAAW,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAC5E,CAAC;AACJ,CAAC"}