@tangle-network/browser-agent-driver 0.12.1 → 0.14.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.
Files changed (90) hide show
  1. package/README.md +81 -0
  2. package/dist/brain/index.d.ts.map +1 -1
  3. package/dist/brain/index.js +88 -6
  4. package/dist/brain/index.js.map +1 -1
  5. package/dist/cli-design-audit.d.ts +2 -0
  6. package/dist/cli-design-audit.d.ts.map +1 -1
  7. package/dist/cli-design-audit.js +111 -303
  8. package/dist/cli-design-audit.js.map +1 -1
  9. package/dist/cli-view.d.ts +83 -0
  10. package/dist/cli-view.d.ts.map +1 -0
  11. package/dist/cli-view.js +397 -0
  12. package/dist/cli-view.js.map +1 -0
  13. package/dist/cli.js +32 -1
  14. package/dist/cli.js.map +1 -1
  15. package/dist/design/audit/classify.d.ts +20 -0
  16. package/dist/design/audit/classify.d.ts.map +1 -0
  17. package/dist/design/audit/classify.js +148 -0
  18. package/dist/design/audit/classify.js.map +1 -0
  19. package/dist/design/audit/evaluate.d.ts +49 -0
  20. package/dist/design/audit/evaluate.d.ts.map +1 -0
  21. package/dist/design/audit/evaluate.js +355 -0
  22. package/dist/design/audit/evaluate.js.map +1 -0
  23. package/dist/design/audit/measure/a11y.d.ts +25 -0
  24. package/dist/design/audit/measure/a11y.d.ts.map +1 -0
  25. package/dist/design/audit/measure/a11y.js +144 -0
  26. package/dist/design/audit/measure/a11y.js.map +1 -0
  27. package/dist/design/audit/measure/contrast.d.ts +18 -0
  28. package/dist/design/audit/measure/contrast.d.ts.map +1 -0
  29. package/dist/design/audit/measure/contrast.js +201 -0
  30. package/dist/design/audit/measure/contrast.js.map +1 -0
  31. package/dist/design/audit/measure/index.d.ts +14 -0
  32. package/dist/design/audit/measure/index.d.ts.map +1 -0
  33. package/dist/design/audit/measure/index.js +38 -0
  34. package/dist/design/audit/measure/index.js.map +1 -0
  35. package/dist/design/audit/pipeline.d.ts +33 -0
  36. package/dist/design/audit/pipeline.d.ts.map +1 -0
  37. package/dist/design/audit/pipeline.js +109 -0
  38. package/dist/design/audit/pipeline.js.map +1 -0
  39. package/dist/design/audit/roi.d.ts +49 -0
  40. package/dist/design/audit/roi.d.ts.map +1 -0
  41. package/dist/design/audit/roi.js +157 -0
  42. package/dist/design/audit/roi.js.map +1 -0
  43. package/dist/design/audit/rubric/fragments/domain-ai.md +19 -0
  44. package/dist/design/audit/rubric/fragments/domain-crypto.md +24 -0
  45. package/dist/design/audit/rubric/fragments/domain-devtools.md +21 -0
  46. package/dist/design/audit/rubric/fragments/domain-fintech.md +19 -0
  47. package/dist/design/audit/rubric/fragments/maturity-prototype.md +36 -0
  48. package/dist/design/audit/rubric/fragments/type-blog.md +22 -0
  49. package/dist/design/audit/rubric/fragments/type-docs.md +23 -0
  50. package/dist/design/audit/rubric/fragments/type-ecommerce.md +23 -0
  51. package/dist/design/audit/rubric/fragments/type-marketing.md +22 -0
  52. package/dist/design/audit/rubric/fragments/type-saas-app.md +20 -0
  53. package/dist/design/audit/rubric/fragments/universal-calibration.md +16 -0
  54. package/dist/design/audit/rubric/fragments/universal-effort-anchor.md +46 -0
  55. package/dist/design/audit/rubric/fragments/universal-foundation.md +49 -0
  56. package/dist/design/audit/rubric/loader.d.ts +49 -0
  57. package/dist/design/audit/rubric/loader.d.ts.map +1 -0
  58. package/dist/design/audit/rubric/loader.js +216 -0
  59. package/dist/design/audit/rubric/loader.js.map +1 -0
  60. package/dist/design/audit/types.d.ts +166 -0
  61. package/dist/design/audit/types.d.ts.map +1 -0
  62. package/dist/design/audit/types.js +8 -0
  63. package/dist/design/audit/types.js.map +1 -0
  64. package/dist/drivers/cursor-overlay.d.ts +26 -0
  65. package/dist/drivers/cursor-overlay.d.ts.map +1 -0
  66. package/dist/drivers/cursor-overlay.js +235 -0
  67. package/dist/drivers/cursor-overlay.js.map +1 -0
  68. package/dist/drivers/playwright.d.ts +32 -0
  69. package/dist/drivers/playwright.d.ts.map +1 -1
  70. package/dist/drivers/playwright.js +79 -0
  71. package/dist/drivers/playwright.js.map +1 -1
  72. package/dist/drivers/steel.d.ts +135 -0
  73. package/dist/drivers/steel.d.ts.map +1 -0
  74. package/dist/drivers/steel.js +236 -0
  75. package/dist/drivers/steel.js.map +1 -0
  76. package/dist/index.d.ts +2 -0
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +1 -0
  79. package/dist/index.js.map +1 -1
  80. package/dist/provider-defaults.d.ts +19 -1
  81. package/dist/provider-defaults.d.ts.map +1 -1
  82. package/dist/provider-defaults.js +34 -0
  83. package/dist/provider-defaults.js.map +1 -1
  84. package/dist/test-runner.d.ts.map +1 -1
  85. package/dist/test-runner.js +51 -14
  86. package/dist/test-runner.js.map +1 -1
  87. package/dist/types.d.ts +10 -0
  88. package/dist/types.d.ts.map +1 -1
  89. package/dist/viewer/viewer.html +940 -0
  90. package/package.json +3 -2
@@ -0,0 +1,397 @@
1
+ /**
2
+ * CLI handler for `bad view <run-dir>`.
3
+ *
4
+ * Spins up a tiny static HTTP server in front of the run's artifact
5
+ * directory and opens the viewer in the user's default browser.
6
+ *
7
+ * No build pipeline, no React, no separate package — viewer.html is a
8
+ * single self-contained file shipped in the package and copied to dist
9
+ * at build time by `scripts/copy-static-assets.mjs`.
10
+ *
11
+ * Library-friendly: this module throws typed errors instead of calling
12
+ * `process.exit`. The CLI dispatcher catches and exits.
13
+ */
14
+ import * as fs from 'node:fs';
15
+ import * as path from 'node:path';
16
+ import * as http from 'node:http';
17
+ import { fileURLToPath } from 'node:url';
18
+ import { spawn } from 'node:child_process';
19
+ import chalk from 'chalk';
20
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
21
+ /** Resolved at module load — single canonical path, no runtime probing. */
22
+ const VIEWER_HTML_PATH = (() => {
23
+ // Production: dist/cli-view.js + dist/viewer/viewer.html
24
+ const distPath = path.join(__dirname, 'viewer/viewer.html');
25
+ if (fs.existsSync(distPath))
26
+ return distPath;
27
+ // Source dev mode: src/cli-view.ts + src/viewer/viewer.html
28
+ const srcPath = path.join(__dirname, '../viewer/viewer.html');
29
+ if (fs.existsSync(srcPath))
30
+ return srcPath;
31
+ // Last-resort: walking up one more level (for unusual layouts)
32
+ const upPath = path.join(__dirname, '../../src/viewer/viewer.html');
33
+ if (fs.existsSync(upPath))
34
+ return upPath;
35
+ return '';
36
+ })();
37
+ export class ViewError extends Error {
38
+ constructor(message) {
39
+ super(message);
40
+ this.name = 'ViewError';
41
+ }
42
+ }
43
+ /**
44
+ * Resolves a `report.json` file inside a run directory. Searches the
45
+ * run directory itself first, then one level deep.
46
+ */
47
+ export function findReportJson(runDir) {
48
+ const direct = path.join(runDir, 'report.json');
49
+ if (fs.existsSync(direct))
50
+ return direct;
51
+ try {
52
+ for (const entry of fs.readdirSync(runDir, { withFileTypes: true })) {
53
+ if (entry.isDirectory()) {
54
+ const sub = path.join(runDir, entry.name, 'report.json');
55
+ if (fs.existsSync(sub))
56
+ return sub;
57
+ }
58
+ }
59
+ }
60
+ catch {
61
+ /* ignore unreadable dir */
62
+ }
63
+ return null;
64
+ }
65
+ /**
66
+ * Find all recording.webm files anywhere under the report root (one level
67
+ * deep — agent runs put them in `<run>/<test-id>/recording.webm`). Returns
68
+ * an array of `{ testId, relPath }` so the viewer can show one player per
69
+ * test case in a multi-test suite run.
70
+ *
71
+ * Skips 0-byte files (Playwright sometimes writes the path before flushing
72
+ * the video on context close, leaving an empty placeholder) — the viewer
73
+ * will fall back to per-turn screenshots when no usable recording exists.
74
+ */
75
+ export function findRecordings(reportRoot) {
76
+ const out = [];
77
+ const isUsableRecording = (filePath) => {
78
+ try {
79
+ const stats = fs.statSync(filePath);
80
+ return stats.isFile() && stats.size > 0;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ };
86
+ try {
87
+ for (const entry of fs.readdirSync(reportRoot, { withFileTypes: true })) {
88
+ if (entry.isDirectory()) {
89
+ const recording = path.join(reportRoot, entry.name, 'recording.webm');
90
+ if (isUsableRecording(recording)) {
91
+ out.push({ testId: entry.name, relPath: `${entry.name}/recording.webm` });
92
+ }
93
+ }
94
+ else if (entry.name === 'recording.webm') {
95
+ const recording = path.join(reportRoot, entry.name);
96
+ if (isUsableRecording(recording)) {
97
+ out.push({ testId: 'default', relPath: 'recording.webm' });
98
+ }
99
+ }
100
+ }
101
+ }
102
+ catch {
103
+ /* ignore */
104
+ }
105
+ return out;
106
+ }
107
+ /**
108
+ * Normalize the report shape so the viewer sees a consistent format.
109
+ *
110
+ * Two distinct shapes flow through here:
111
+ * - **Design audit** (cli-design-audit.ts): top-level `pages[]`, each
112
+ * with screenshot file paths and findings. Native shape — passed through.
113
+ * - **Agent run** (test-runner.ts → FilesystemSink): top-level
114
+ * `results[].agentResult.turns[]` where each turn has `state.screenshot`
115
+ * as a raw base64 string. Unwrapped to a normalized `{ tests[]: { ...,
116
+ * turns[] } }` shape with screenshots converted to data URLs.
117
+ *
118
+ * Recordings discovered on disk are attached to the matching test by id.
119
+ */
120
+ export function normalizeReport(raw, recordings) {
121
+ const data = raw;
122
+ if (!data || typeof data !== 'object')
123
+ return { error: 'invalid report' };
124
+ // Design audit shape — has top-level `pages[]`. Pass through.
125
+ if (Array.isArray(data.pages)) {
126
+ return data;
127
+ }
128
+ // Agent run shape — has top-level `results[]` with `.agentResult.turns[]`.
129
+ if (Array.isArray(data.results)) {
130
+ const results = data.results;
131
+ const tests = results.map(r => {
132
+ const agentResult = (r.agentResult ?? {});
133
+ const turns = (agentResult.turns ?? []).map(t => {
134
+ const state = (t.state ?? {});
135
+ const screenshot = state.screenshot;
136
+ // Convert raw base64 → data URL so the <img> tag renders it.
137
+ // NOTE: JPEG base64 starts with `/9j/` (first byte 0xFF), so the
138
+ // leading slash is NOT a path indicator. Detect format properly:
139
+ // - already a data: URL → leave it
140
+ // - absolute file path or http(s) URL → leave it (legacy on-disk runs)
141
+ // - everything else → assume base64, prefix as JPEG data URL
142
+ const screenshotDataUrl = !screenshot
143
+ ? screenshot
144
+ : screenshot.startsWith('data:')
145
+ ? screenshot
146
+ : screenshot.startsWith('http://') || screenshot.startsWith('https://')
147
+ ? screenshot
148
+ : screenshot.startsWith('/') && (screenshot.endsWith('.png') || screenshot.endsWith('.jpg') || screenshot.endsWith('.jpeg') || screenshot.endsWith('.webp'))
149
+ ? screenshot
150
+ : `data:image/jpeg;base64,${screenshot}`;
151
+ return {
152
+ ...t,
153
+ state: { ...state, screenshot: screenshotDataUrl },
154
+ };
155
+ });
156
+ const testCase = (r.testCase ?? {});
157
+ const testId = (testCase.id ?? testCase.name ?? 'cli-task');
158
+ const recording = recordings.find(rec => rec.testId === testId)
159
+ ?? recordings.find(rec => rec.testId === 'default');
160
+ return {
161
+ id: testId,
162
+ name: testCase.name ?? testId,
163
+ success: agentResult.success ?? r.agentSuccess,
164
+ verdict: r.verdict,
165
+ turnsUsed: r.turnsUsed,
166
+ durationMs: r.durationMs,
167
+ estimatedCostUsd: r.estimatedCostUsd,
168
+ recording: recording ? recording.relPath : null,
169
+ turns,
170
+ };
171
+ });
172
+ return {
173
+ ...data,
174
+ // Both fields present so existing readers still work; the viewer
175
+ // prefers `tests[]` for agent runs.
176
+ tests,
177
+ };
178
+ }
179
+ // Single agent result shape (no suite wrapper) — `turns[]` directly.
180
+ if (Array.isArray(data.turns)) {
181
+ const turns = (data.turns).map(t => {
182
+ const state = (t.state ?? {});
183
+ const screenshot = state.screenshot;
184
+ const screenshotDataUrl = !screenshot
185
+ ? screenshot
186
+ : screenshot.startsWith('data:')
187
+ ? screenshot
188
+ : screenshot.startsWith('http://') || screenshot.startsWith('https://')
189
+ ? screenshot
190
+ : screenshot.startsWith('/') && (screenshot.endsWith('.png') || screenshot.endsWith('.jpg') || screenshot.endsWith('.jpeg') || screenshot.endsWith('.webp'))
191
+ ? screenshot
192
+ : `data:image/jpeg;base64,${screenshot}`;
193
+ return { ...t, state: { ...state, screenshot: screenshotDataUrl } };
194
+ });
195
+ const recording = recordings.find(rec => rec.testId === 'default') ?? recordings[0];
196
+ return {
197
+ ...data,
198
+ tests: [{
199
+ id: 'default',
200
+ name: 'run',
201
+ recording: recording ? recording.relPath : null,
202
+ turns,
203
+ }],
204
+ };
205
+ }
206
+ return data;
207
+ }
208
+ /**
209
+ * Escape a JSON string for safe inlining inside a `<script>` block.
210
+ *
211
+ * The hazards:
212
+ * - `</script` (any case): closes the script tag mid-string
213
+ * - `<!--`: opens an HTML comment, toggles parser modes
214
+ * - U+2028 / U+2029: legal in JSON, illegal in pre-ES2019 JS string literals
215
+ *
216
+ * Exported for testing.
217
+ */
218
+ export function escapeJsonForScript(json) {
219
+ return json
220
+ .replace(/<\/(script)/gi, '<\\/$1')
221
+ .replace(/<!--/g, '<\\!--')
222
+ .replace(/\u2028/g, '\\u2028')
223
+ .replace(/\u2029/g, '\\u2029');
224
+ }
225
+ const MIME = {
226
+ '.html': 'text/html; charset=utf-8',
227
+ '.htm': 'text/html; charset=utf-8',
228
+ '.json': 'application/json; charset=utf-8',
229
+ '.txt': 'text/plain; charset=utf-8',
230
+ '.md': 'text/markdown; charset=utf-8',
231
+ '.png': 'image/png',
232
+ '.jpg': 'image/jpeg',
233
+ '.jpeg': 'image/jpeg',
234
+ '.webp': 'image/webp',
235
+ '.gif': 'image/gif',
236
+ '.svg': 'image/svg+xml',
237
+ '.ico': 'image/x-icon',
238
+ '.css': 'text/css',
239
+ '.js': 'application/javascript',
240
+ '.mjs': 'application/javascript',
241
+ '.map': 'application/json',
242
+ '.webm': 'video/webm',
243
+ '.mp4': 'video/mp4',
244
+ '.mov': 'video/quicktime',
245
+ };
246
+ function openInBrowser(url) {
247
+ const cmd = process.platform === 'darwin' ? 'open'
248
+ : process.platform === 'win32' ? 'start'
249
+ : 'xdg-open';
250
+ try {
251
+ spawn(cmd, [url], { detached: true, stdio: 'ignore' }).unref();
252
+ }
253
+ catch {
254
+ // Best-effort — user can copy the URL from the terminal
255
+ }
256
+ }
257
+ /**
258
+ * Listen on a port, auto-incrementing on EADDRINUSE up to `maxRetries` times.
259
+ */
260
+ async function listenWithRetry(server, startPort, maxRetries) {
261
+ for (let i = 0; i <= maxRetries; i++) {
262
+ const port = startPort + i;
263
+ try {
264
+ await new Promise((resolve, reject) => {
265
+ const onError = (err) => {
266
+ server.removeListener('listening', onListening);
267
+ reject(err);
268
+ };
269
+ const onListening = () => {
270
+ server.removeListener('error', onError);
271
+ resolve();
272
+ };
273
+ server.once('error', onError);
274
+ server.once('listening', onListening);
275
+ server.listen(port, '127.0.0.1');
276
+ });
277
+ return port;
278
+ }
279
+ catch (err) {
280
+ const code = err.code;
281
+ if (code !== 'EADDRINUSE')
282
+ throw err;
283
+ // Try the next port
284
+ continue;
285
+ }
286
+ }
287
+ throw new ViewError(`could not bind to any port in range ${startPort}–${startPort + maxRetries} (all in use)`);
288
+ }
289
+ export async function runView(opts) {
290
+ const runDir = path.resolve(opts.runDir);
291
+ if (!fs.existsSync(runDir) || !fs.statSync(runDir).isDirectory()) {
292
+ throw new ViewError(`run directory not found: ${runDir}`);
293
+ }
294
+ const reportPath = findReportJson(runDir);
295
+ if (!reportPath) {
296
+ throw new ViewError(`no report.json found in ${runDir} or its subdirectories`);
297
+ }
298
+ if (!VIEWER_HTML_PATH) {
299
+ throw new ViewError('viewer.html not found. The package may be missing dist/viewer/viewer.html — try reinstalling.');
300
+ }
301
+ const reportRoot = path.dirname(reportPath);
302
+ const viewerSource = fs.readFileSync(VIEWER_HTML_PATH, 'utf-8');
303
+ const reportRaw = fs.readFileSync(reportPath, 'utf-8');
304
+ // Parse the report, discover any recording.webm files alongside it, and
305
+ // normalize the shape so the viewer sees a consistent format whether
306
+ // this is a design-audit run or an agent suite run.
307
+ let reportObj;
308
+ try {
309
+ reportObj = JSON.parse(reportRaw);
310
+ }
311
+ catch {
312
+ throw new ViewError(`report.json is not valid JSON: ${reportPath}`);
313
+ }
314
+ const recordings = findRecordings(reportRoot);
315
+ const normalized = normalizeReport(reportObj, recordings);
316
+ const reportJson = JSON.stringify(normalized);
317
+ const safeJson = escapeJsonForScript(reportJson);
318
+ const inlinedHtml = viewerSource.replace('const runData = window.__bad_runData || null;', `const runData = ${safeJson};`);
319
+ const server = http.createServer((req, res) => {
320
+ const urlPath = (req.url ?? '/').split('?')[0];
321
+ if (urlPath === '/' || urlPath === '/index.html') {
322
+ res.writeHead(200, { 'Content-Type': MIME['.html'] });
323
+ res.end(inlinedHtml);
324
+ return;
325
+ }
326
+ // Path-traversal protection: resolve, check the path stays inside
327
+ // reportRoot via path.relative (startsWith on the prefix is buggy
328
+ // because /tmp/runA-evil shares a prefix with /tmp/runA), and
329
+ // resolve symlinks so they can't escape the sandbox.
330
+ const decoded = decodeURIComponent(urlPath);
331
+ const candidate = path.resolve(reportRoot, decoded.replace(/^\/+/, ''));
332
+ const rel = path.relative(reportRoot, candidate);
333
+ if (rel.startsWith('..') || path.isAbsolute(rel)) {
334
+ res.writeHead(403);
335
+ res.end('forbidden');
336
+ return;
337
+ }
338
+ let realPath;
339
+ try {
340
+ realPath = fs.realpathSync(candidate);
341
+ }
342
+ catch {
343
+ res.writeHead(404);
344
+ res.end('not found');
345
+ return;
346
+ }
347
+ const realRel = path.relative(reportRoot, realPath);
348
+ if (realRel.startsWith('..') || path.isAbsolute(realRel)) {
349
+ // Symlink escaped the sandbox
350
+ res.writeHead(403);
351
+ res.end('forbidden');
352
+ return;
353
+ }
354
+ if (!fs.statSync(realPath).isFile()) {
355
+ res.writeHead(404);
356
+ res.end('not found');
357
+ return;
358
+ }
359
+ const ext = path.extname(realPath).toLowerCase();
360
+ res.writeHead(200, {
361
+ 'Content-Type': MIME[ext] ?? 'application/octet-stream',
362
+ 'Cache-Control': 'no-cache',
363
+ });
364
+ fs.createReadStream(realPath).pipe(res);
365
+ });
366
+ const port = await listenWithRetry(server, opts.port ?? 7777, opts.portRetries ?? 10);
367
+ const url = `http://localhost:${port}`;
368
+ console.log('');
369
+ console.log(` ${chalk.bold('bad view')}`);
370
+ console.log(` ${chalk.dim('Run:')} ${reportRoot}`);
371
+ console.log(` ${chalk.dim('URL:')} ${chalk.cyan(url)}`);
372
+ console.log(` ${chalk.dim('Press Ctrl+C to stop')}`);
373
+ console.log('');
374
+ if (!opts.noOpen) {
375
+ openInBrowser(url);
376
+ }
377
+ const close = () => new Promise(resolve => {
378
+ server.close(() => resolve());
379
+ });
380
+ return { url, close };
381
+ }
382
+ /**
383
+ * CLI entrypoint that calls runView and keeps the process alive until SIGINT.
384
+ * Throws ViewError on failure — the dispatcher in cli.ts catches and exits.
385
+ */
386
+ export async function runViewCli(opts) {
387
+ const { close } = await runView(opts);
388
+ // Keep alive until SIGINT
389
+ await new Promise(resolve => {
390
+ const onSigint = () => {
391
+ console.log('\n closing viewer…');
392
+ void close().then(resolve);
393
+ };
394
+ process.once('SIGINT', onSigint);
395
+ });
396
+ }
397
+ //# sourceMappingURL=cli-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-view.js","sourceRoot":"","sources":["../src/cli-view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9D,2EAA2E;AAC3E,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE;IAC7B,yDAAyD;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAA;IAC3D,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC5C,4DAA4D;IAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAA;IAC7D,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAA;IAC1C,+DAA+D;IAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,8BAA8B,CAAC,CAAA;IACnE,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAA;IACxC,OAAO,EAAE,CAAA;AACX,CAAC,CAAC,EAAE,CAAA;AAaJ,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,WAAW,CAAA;IACzB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAA;IAExC,IAAI,CAAC;QACH,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACpE,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;gBACxD,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,OAAO,GAAG,CAAA;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,2BAA2B;IAC7B,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,MAAM,GAAG,GAA+C,EAAE,CAAA;IAC1D,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAW,EAAE;QACtD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;YACnC,OAAO,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,CAAA;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC,CAAA;IACD,IAAI,CAAC;QACH,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YACxE,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAA;gBACrE,IAAI,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;oBACjC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAA;gBAC3E,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;gBACnD,IAAI,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;oBACjC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAA;gBAC5D,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAY,EACZ,UAAsD;IAEtD,MAAM,IAAI,GAAG,GAA8B,CAAA;IAC3C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAA;IAEzE,8DAA8D;IAC9D,IAAI,KAAK,CAAC,OAAO,CAAE,IAA4B,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,2EAA2E;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAE,IAA8B,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3D,MAAM,OAAO,GAAI,IAAoD,CAAC,OAAO,CAAA;QAC7E,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAC5B,MAAM,WAAW,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,EAAE,CAA4B,CAAA;YACpE,MAAM,KAAK,GAAI,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE,CAAoC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;gBAClF,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAA;gBACxD,MAAM,UAAU,GAAG,KAAK,CAAC,UAAgC,CAAA;gBACzD,6DAA6D;gBAC7D,iEAAiE;gBACjE,iEAAiE;gBACjE,qCAAqC;gBACrC,yEAAyE;gBACzE,+DAA+D;gBAC/D,MAAM,iBAAiB,GAAG,CAAC,UAAU;oBACnC,CAAC,CAAC,UAAU;oBACZ,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC;wBAC9B,CAAC,CAAC,UAAU;wBACZ,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC;4BACrE,CAAC,CAAC,UAAU;4BACZ,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gCAC1J,CAAC,CAAC,UAAU;gCACZ,CAAC,CAAC,0BAA0B,UAAU,EAAE,CAAA;gBAChD,OAAO;oBACL,GAAG,CAAC;oBACJ,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE;iBACnD,CAAA;YACH,CAAC,CAAC,CAAA;YACF,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAA4B,CAAA;YAC9D,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,IAAI,IAAI,UAAU,CAAW,CAAA;YACrE,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC;mBAC1D,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAA;YACrD,OAAO;gBACL,EAAE,EAAE,MAAM;gBACV,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,MAAM;gBAC7B,OAAO,EAAE,WAAW,CAAC,OAAO,IAAI,CAAC,CAAC,YAAY;gBAC9C,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;gBACpC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;gBAC/C,KAAK;aACN,CAAA;QACH,CAAC,CAAC,CAAA;QACF,OAAO;YACL,GAAG,IAAI;YACP,iEAAiE;YACjE,oCAAoC;YACpC,KAAK;SACN,CAAA;IACH,CAAC;IAED,qEAAqE;IACrE,IAAI,KAAK,CAAC,OAAO,CAAE,IAA4B,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,MAAM,KAAK,GAAG,CAAE,IAAkD,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAChF,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAA;YACxD,MAAM,UAAU,GAAG,KAAK,CAAC,UAAgC,CAAA;YACzD,MAAM,iBAAiB,GAAG,CAAC,UAAU;gBACnC,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC;oBAC9B,CAAC,CAAC,UAAU;oBACZ,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC;wBACrE,CAAC,CAAC,UAAU;wBACZ,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;4BAC1J,CAAC,CAAC,UAAU;4BACZ,CAAC,CAAC,0BAA0B,UAAU,EAAE,CAAA;YAChD,OAAO,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,EAAE,CAAA;QACrE,CAAC,CAAC,CAAA;QACF,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;QACnF,OAAO;YACL,GAAG,IAAI;YACP,KAAK,EAAE,CAAC;oBACN,EAAE,EAAE,SAAS;oBACb,IAAI,EAAE,KAAK;oBACX,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;oBAC/C,KAAK;iBACN,CAAC;SACH,CAAA;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI;SACR,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC;SAClC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC;SAC1B,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC;SAC7B,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;AAClC,CAAC;AAED,MAAM,IAAI,GAA2B;IACnC,OAAO,EAAE,0BAA0B;IACnC,MAAM,EAAE,0BAA0B;IAClC,OAAO,EAAE,iCAAiC;IAC1C,MAAM,EAAE,2BAA2B;IACnC,KAAK,EAAE,8BAA8B;IACrC,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,cAAc;IACtB,MAAM,EAAE,UAAU;IAClB,KAAK,EAAE,wBAAwB;IAC/B,MAAM,EAAE,wBAAwB;IAChC,MAAM,EAAE,kBAAkB;IAC1B,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,iBAAiB;CAC1B,CAAA;AAED,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM;QAChD,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO;YACxC,CAAC,CAAC,UAAU,CAAA;IACd,IAAI,CAAC;QACH,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,CAAA;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;IAC1D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,eAAe,CAC5B,MAAmB,EACnB,SAAiB,EACjB,UAAkB;IAElB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,SAAS,GAAG,CAAC,CAAA;QAC1B,IAAI,CAAC;YACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,OAAO,GAAG,CAAC,GAA0B,EAAE,EAAE;oBAC7C,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;oBAC/C,MAAM,CAAC,GAAG,CAAC,CAAA;gBACb,CAAC,CAAA;gBACD,MAAM,WAAW,GAAG,GAAG,EAAE;oBACvB,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;oBACvC,OAAO,EAAE,CAAA;gBACX,CAAC,CAAA;gBACD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;gBAC7B,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;gBACrC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;YAClC,CAAC,CAAC,CAAA;YACF,OAAO,IAAI,CAAA;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAA;YAChD,IAAI,IAAI,KAAK,YAAY;gBAAE,MAAM,GAAG,CAAA;YACpC,oBAAoB;YACpB,SAAQ;QACV,CAAC;IACH,CAAC;IACD,MAAM,IAAI,SAAS,CACjB,uCAAuC,SAAS,IAAI,SAAS,GAAG,UAAU,eAAe,CAC1F,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAiB;IAI7C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACxC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACjE,MAAM,IAAI,SAAS,CAAC,4BAA4B,MAAM,EAAE,CAAC,CAAA;IAC3D,CAAC;IAED,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC,CAAA;IACzC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,SAAS,CAAC,2BAA2B,MAAM,wBAAwB,CAAC,CAAA;IAChF,CAAC;IAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,MAAM,IAAI,SAAS,CACjB,+FAA+F,CAChG,CAAA;IACH,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAC3C,MAAM,YAAY,GAAG,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAA;IAC/D,MAAM,SAAS,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IAEtD,wEAAwE;IACxE,qEAAqE;IACrE,oDAAoD;IACpD,IAAI,SAAkB,CAAA;IACtB,IAAI,CAAC;QACH,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,SAAS,CAAC,kCAAkC,UAAU,EAAE,CAAC,CAAA;IACrE,CAAC;IACD,MAAM,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC,CAAA;IAC7C,MAAM,UAAU,GAAG,eAAe,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;IACzD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAA;IAEhD,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,CACtC,+CAA+C,EAC/C,mBAAmB,QAAQ,GAAG,CAC/B,CAAA;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC5C,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAC9C,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;YACjD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;YACrD,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;YACpB,OAAM;QACR,CAAC;QAED,kEAAkE;QAClE,kEAAkE;QAClE,8DAA8D;QAC9D,qDAAqD;QACrD,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAA;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAA;QACvE,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;QAChD,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;YAClB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;YACpB,OAAM;QACR,CAAC;QACD,IAAI,QAAgB,CAAA;QACpB,IAAI,CAAC;YACH,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;YAClB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;YACpB,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;QACnD,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzD,8BAA8B;YAC9B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;YAClB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;YACpB,OAAM;QACR,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YACpC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;YAClB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;YACpB,OAAM;QACR,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAA;QAChD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,0BAA0B;YACvD,eAAe,EAAE,UAAU;SAC5B,CAAC,CAAA;QACF,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAA;IACrF,MAAM,GAAG,GAAG,oBAAoB,IAAI,EAAE,CAAA;IAEtC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC,CAAA;IACnD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACxD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAA;IACrD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAEf,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,aAAa,CAAC,GAAG,CAAC,CAAA;IACpB,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,EAAE,CACjB,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;QAC1B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;IAEJ,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAiB;IAChD,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAErC,0BAA0B;IAC1B,MAAM,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;QAChC,MAAM,QAAQ,GAAG,GAAG,EAAE;YACpB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAA;YAClC,KAAK,KAAK,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC5B,CAAC,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAClC,CAAC,CAAC,CAAA;AACJ,CAAC"}
package/dist/cli.js CHANGED
@@ -108,6 +108,12 @@ async function main() {
108
108
  'evolve-rounds': { type: 'string' },
109
109
  'project-dir': { type: 'string' },
110
110
  reproducibility: { type: 'boolean' },
111
+ 'rubrics-dir': { type: 'string' },
112
+ // bad view
113
+ port: { type: 'string' },
114
+ 'no-open': { type: 'boolean' },
115
+ // bad run --show-cursor (overlay)
116
+ 'show-cursor': { type: 'boolean' },
111
117
  // showcase
112
118
  script: { type: 'string' },
113
119
  capture: { type: 'string' },
@@ -178,6 +184,29 @@ async function main() {
178
184
  process.exit(0);
179
185
  }
180
186
  const command = positionals[0];
187
+ if (command === 'view') {
188
+ const runDir = positionals[1];
189
+ if (!runDir) {
190
+ cliError('usage: bad view <run-directory>');
191
+ process.exit(1);
192
+ }
193
+ const { runViewCli, ViewError } = await import('./cli-view.js');
194
+ try {
195
+ await runViewCli({
196
+ runDir,
197
+ port: values.port ? parseInt(values.port) : undefined,
198
+ noOpen: values['no-open'],
199
+ });
200
+ }
201
+ catch (err) {
202
+ if (err instanceof ViewError) {
203
+ cliError(err.message);
204
+ process.exit(1);
205
+ }
206
+ throw err;
207
+ }
208
+ return;
209
+ }
181
210
  if (command === 'design-audit') {
182
211
  if (!values.url) {
183
212
  cliError('--url is required for design-audit.');
@@ -226,6 +255,7 @@ async function main() {
226
255
  evolveRounds: values['evolve-rounds'] ? parseInt(values['evolve-rounds']) : undefined,
227
256
  projectDir: values['project-dir'],
228
257
  reproducibility: values.reproducibility,
258
+ rubricsDir: values['rubrics-dir'],
229
259
  });
230
260
  process.exit(0);
231
261
  }
@@ -315,7 +345,7 @@ async function main() {
315
345
  process.exit(1);
316
346
  }
317
347
  if (command !== 'run') {
318
- cliError(`Unknown command: ${command}. Use "run", "runs", "design-audit", "showcase", or "auth".`);
348
+ cliError(`Unknown command: ${command}. Use "run", "runs", "design-audit", "view", "showcase", or "auth".`);
319
349
  process.exit(1);
320
350
  }
321
351
  // Validate inputs
@@ -1146,6 +1176,7 @@ async function main() {
1146
1176
  timeout: actionTimeout,
1147
1177
  visionStrategy: config.visionStrategy,
1148
1178
  screenshotInterval,
1179
+ showCursor: values['show-cursor'],
1149
1180
  });
1150
1181
  // Apply resource blocking if configured
1151
1182
  const resourceBlockingStartedAt = Date.now();