cbrowser 18.78.0 → 18.80.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/analysis/accessibility-empathy.d.ts.map +1 -1
- package/dist/analysis/accessibility-empathy.js +395 -66
- package/dist/analysis/accessibility-empathy.js.map +1 -1
- package/dist/analysis/agent-ready-audit.d.ts.map +1 -1
- package/dist/analysis/agent-ready-audit.js +78 -0
- package/dist/analysis/agent-ready-audit.js.map +1 -1
- package/dist/analysis/page-understanding.d.ts +139 -1
- package/dist/analysis/page-understanding.d.ts.map +1 -1
- package/dist/analysis/page-understanding.js +179 -12
- package/dist/analysis/page-understanding.js.map +1 -1
- package/dist/artifact-store.d.ts +19 -5
- package/dist/artifact-store.d.ts.map +1 -1
- package/dist/artifact-store.js +41 -11
- package/dist/artifact-store.js.map +1 -1
- package/dist/browser.d.ts +9 -0
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +81 -5
- package/dist/browser.js.map +1 -1
- package/dist/cli.js +55 -10
- package/dist/cli.js.map +1 -1
- package/dist/cognitive/index.d.ts.map +1 -1
- package/dist/cognitive/index.js +3 -2
- package/dist/cognitive/index.js.map +1 -1
- package/dist/config.d.ts +57 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +234 -7
- package/dist/config.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-server-remote.d.ts.map +1 -1
- package/dist/mcp-server-remote.js +108 -4
- package/dist/mcp-server-remote.js.map +1 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +62 -938
- package/dist/mcp-server.js.map +1 -1
- package/dist/mcp-tools/account-personas.d.ts +41 -0
- package/dist/mcp-tools/account-personas.d.ts.map +1 -0
- package/dist/mcp-tools/account-personas.js +98 -0
- package/dist/mcp-tools/account-personas.js.map +1 -0
- package/dist/mcp-tools/base/analysis-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/analysis-tools.js +12 -2
- package/dist/mcp-tools/base/analysis-tools.js.map +1 -1
- package/dist/mcp-tools/base/artifact-tools.d.ts +3 -0
- package/dist/mcp-tools/base/artifact-tools.d.ts.map +1 -0
- package/dist/mcp-tools/base/artifact-tools.js +78 -0
- package/dist/mcp-tools/base/artifact-tools.js.map +1 -0
- package/dist/mcp-tools/base/audit-tools.d.ts +11 -0
- package/dist/mcp-tools/base/audit-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/audit-tools.js +595 -340
- package/dist/mcp-tools/base/audit-tools.js.map +1 -1
- package/dist/mcp-tools/base/browser-management-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/browser-management-tools.js +18 -0
- package/dist/mcp-tools/base/browser-management-tools.js.map +1 -1
- package/dist/mcp-tools/base/bug-analysis-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/bug-analysis-tools.js +59 -3
- package/dist/mcp-tools/base/bug-analysis-tools.js.map +1 -1
- package/dist/mcp-tools/base/capture-tools.d.ts +37 -0
- package/dist/mcp-tools/base/capture-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/capture-tools.js +267 -6
- package/dist/mcp-tools/base/capture-tools.js.map +1 -1
- package/dist/mcp-tools/base/cognitive-tools.d.ts +12 -0
- package/dist/mcp-tools/base/cognitive-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/cognitive-tools.js +63 -15
- package/dist/mcp-tools/base/cognitive-tools.js.map +1 -1
- package/dist/mcp-tools/base/extraction-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/extraction-tools.js +33 -2
- package/dist/mcp-tools/base/extraction-tools.js.map +1 -1
- package/dist/mcp-tools/base/index.d.ts +2 -0
- package/dist/mcp-tools/base/index.d.ts.map +1 -1
- package/dist/mcp-tools/base/index.js +9 -0
- package/dist/mcp-tools/base/index.js.map +1 -1
- package/dist/mcp-tools/base/marketing-tools.js +3 -3
- package/dist/mcp-tools/base/marketing-tools.js.map +1 -1
- package/dist/mcp-tools/base/persona-comparison-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/persona-comparison-tools.js +529 -40
- package/dist/mcp-tools/base/persona-comparison-tools.js.map +1 -1
- package/dist/mcp-tools/base/site-knowledge-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/site-knowledge-tools.js +36 -3
- package/dist/mcp-tools/base/site-knowledge-tools.js.map +1 -1
- package/dist/mcp-tools/base/values-tools.d.ts +113 -0
- package/dist/mcp-tools/base/values-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/values-tools.js +868 -78
- package/dist/mcp-tools/base/values-tools.js.map +1 -1
- package/dist/mcp-tools/base/visual-testing-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/visual-testing-tools.js +130 -10
- package/dist/mcp-tools/base/visual-testing-tools.js.map +1 -1
- package/dist/mcp-tools/index.d.ts +3 -1
- package/dist/mcp-tools/index.d.ts.map +1 -1
- package/dist/mcp-tools/index.js +3 -28
- package/dist/mcp-tools/index.js.map +1 -1
- package/dist/mcp-tools/persona-creation-tools.d.ts.map +1 -1
- package/dist/mcp-tools/persona-creation-tools.js +363 -20
- package/dist/mcp-tools/persona-creation-tools.js.map +1 -1
- package/dist/mcp-tools/persona-lifecycle-tools.d.ts +3 -0
- package/dist/mcp-tools/persona-lifecycle-tools.d.ts.map +1 -0
- package/dist/mcp-tools/persona-lifecycle-tools.js +406 -0
- package/dist/mcp-tools/persona-lifecycle-tools.js.map +1 -0
- package/dist/mcp-tools/screenshot-utils.d.ts.map +1 -1
- package/dist/mcp-tools/screenshot-utils.js +56 -10
- package/dist/mcp-tools/screenshot-utils.js.map +1 -1
- package/dist/mcp-tools/tier-gate.js +2 -2
- package/dist/mcp-tools/tier-gate.js.map +1 -1
- package/dist/mcp-tools/tool-categories.d.ts.map +1 -1
- package/dist/mcp-tools/tool-categories.js +4 -1
- package/dist/mcp-tools/tool-categories.js.map +1 -1
- package/dist/mcp-tools/ui-resources.d.ts +167 -0
- package/dist/mcp-tools/ui-resources.d.ts.map +1 -0
- package/dist/mcp-tools/ui-resources.js +707 -0
- package/dist/mcp-tools/ui-resources.js.map +1 -0
- package/dist/mcp-tools/widget-kit.d.ts +299 -0
- package/dist/mcp-tools/widget-kit.d.ts.map +1 -0
- package/dist/mcp-tools/widget-kit.js +2034 -0
- package/dist/mcp-tools/widget-kit.js.map +1 -0
- package/dist/mcp-ui-resources.d.ts.map +1 -1
- package/dist/mcp-ui-resources.js +14 -4
- package/dist/mcp-ui-resources.js.map +1 -1
- package/dist/persona-questionnaire.d.ts +69 -1
- package/dist/persona-questionnaire.d.ts.map +1 -1
- package/dist/persona-questionnaire.js +177 -76
- package/dist/persona-questionnaire.js.map +1 -1
- package/dist/persona-scope.d.ts +20 -0
- package/dist/persona-scope.d.ts.map +1 -0
- package/dist/persona-scope.js +59 -0
- package/dist/persona-scope.js.map +1 -0
- package/dist/personas.d.ts +51 -17
- package/dist/personas.d.ts.map +1 -1
- package/dist/personas.js +947 -286
- package/dist/personas.js.map +1 -1
- package/dist/recording/capture-player.d.ts +68 -0
- package/dist/recording/capture-player.d.ts.map +1 -0
- package/dist/recording/capture-player.js +298 -0
- package/dist/recording/capture-player.js.map +1 -0
- package/dist/recording/engine.d.ts +52 -0
- package/dist/recording/engine.d.ts.map +1 -1
- package/dist/recording/engine.js +241 -3
- package/dist/recording/engine.js.map +1 -1
- package/dist/recording/inline-player.d.ts +39 -0
- package/dist/recording/inline-player.d.ts.map +1 -0
- package/dist/recording/inline-player.js +272 -0
- package/dist/recording/inline-player.js.map +1 -0
- package/dist/recording/saliency-overlay.d.ts +133 -0
- package/dist/recording/saliency-overlay.d.ts.map +1 -0
- package/dist/recording/saliency-overlay.js +360 -0
- package/dist/recording/saliency-overlay.js.map +1 -0
- package/dist/recording/types.d.ts +32 -0
- package/dist/recording/types.d.ts.map +1 -1
- package/dist/recording/types.js +46 -0
- package/dist/recording/types.js.map +1 -1
- package/dist/site-model/manager.d.ts +20 -0
- package/dist/site-model/manager.d.ts.map +1 -1
- package/dist/site-model/manager.js +52 -0
- package/dist/site-model/manager.js.map +1 -1
- package/dist/trait-reference.d.ts +26 -2
- package/dist/trait-reference.d.ts.map +1 -1
- package/dist/trait-reference.js +129 -19
- package/dist/trait-reference.js.map +1 -1
- package/dist/types.d.ts +105 -18
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/url-resolution.d.ts +58 -0
- package/dist/url-resolution.d.ts.map +1 -0
- package/dist/url-resolution.js +143 -0
- package/dist/url-resolution.js.map +1 -0
- package/dist/values/big-five-inference.d.ts +121 -0
- package/dist/values/big-five-inference.d.ts.map +1 -0
- package/dist/values/big-five-inference.js +241 -0
- package/dist/values/big-five-inference.js.map +1 -0
- package/dist/values/big-five-values.d.ts +76 -0
- package/dist/values/big-five-values.d.ts.map +1 -0
- package/dist/values/big-five-values.js +152 -0
- package/dist/values/big-five-values.js.map +1 -0
- package/dist/values/index.d.ts +1 -1
- package/dist/values/index.d.ts.map +1 -1
- package/dist/values/index.js +1 -1
- package/dist/values/index.js.map +1 -1
- package/dist/values/persona-completeness.d.ts +91 -0
- package/dist/values/persona-completeness.d.ts.map +1 -0
- package/dist/values/persona-completeness.js +114 -0
- package/dist/values/persona-completeness.js.map +1 -0
- package/dist/values/persona-diff.d.ts +50 -0
- package/dist/values/persona-diff.d.ts.map +1 -0
- package/dist/values/persona-diff.js +126 -0
- package/dist/values/persona-diff.js.map +1 -0
- package/dist/values/persona-values.d.ts +16 -0
- package/dist/values/persona-values.d.ts.map +1 -1
- package/dist/values/persona-values.js +33 -0
- package/dist/values/persona-values.js.map +1 -1
- package/dist/values/schwartz-values.d.ts +9 -1
- package/dist/values/schwartz-values.d.ts.map +1 -1
- package/dist/values/schwartz-values.js +10 -2
- package/dist/values/schwartz-values.js.map +1 -1
- package/dist/values/value-mappings.d.ts +41 -2
- package/dist/values/value-mappings.d.ts.map +1 -1
- package/dist/values/value-mappings.js +65 -8
- package/dist/values/value-mappings.js.map +1 -1
- package/dist/visual/attention-quality.d.ts +27 -0
- package/dist/visual/attention-quality.d.ts.map +1 -1
- package/dist/visual/attention-quality.js +164 -2
- package/dist/visual/attention-quality.js.map +1 -1
- package/dist/visual/attention-transport.d.ts +41 -2
- package/dist/visual/attention-transport.d.ts.map +1 -1
- package/dist/visual/attention-transport.js +98 -26
- package/dist/visual/attention-transport.js.map +1 -1
- package/dist/visual/barrier-overlay-html.d.ts +10 -0
- package/dist/visual/barrier-overlay-html.d.ts.map +1 -1
- package/dist/visual/barrier-overlay-html.js.map +1 -1
- package/dist/visual/cognitive-models.d.ts +109 -13
- package/dist/visual/cognitive-models.d.ts.map +1 -1
- package/dist/visual/cognitive-models.js +166 -3
- package/dist/visual/cognitive-models.js.map +1 -1
- package/dist/visual/cognitive-transport-chain.d.ts +149 -5
- package/dist/visual/cognitive-transport-chain.d.ts.map +1 -1
- package/dist/visual/cognitive-transport-chain.js +558 -30
- package/dist/visual/cognitive-transport-chain.js.map +1 -1
- package/dist/visual/cognitive-transport.d.ts +45 -3
- package/dist/visual/cognitive-transport.d.ts.map +1 -1
- package/dist/visual/cognitive-transport.js +126 -12
- package/dist/visual/cognitive-transport.js.map +1 -1
- package/dist/visual/fixation-corpus.d.ts +52 -0
- package/dist/visual/fixation-corpus.d.ts.map +1 -1
- package/dist/visual/fixation-corpus.js +95 -0
- package/dist/visual/fixation-corpus.js.map +1 -1
- package/dist/visual/llm-relevance.d.ts +193 -0
- package/dist/visual/llm-relevance.d.ts.map +1 -0
- package/dist/visual/llm-relevance.js +480 -0
- package/dist/visual/llm-relevance.js.map +1 -0
- package/dist/visual/perceptual-transport.d.ts +60 -0
- package/dist/visual/perceptual-transport.d.ts.map +1 -1
- package/dist/visual/perceptual-transport.js +228 -19
- package/dist/visual/perceptual-transport.js.map +1 -1
- package/dist/visual/persona-context.d.ts +23 -0
- package/dist/visual/persona-context.d.ts.map +1 -0
- package/dist/visual/persona-context.js +44 -0
- package/dist/visual/persona-context.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-contained HTML player for a capture.
|
|
3
|
+
*
|
|
4
|
+
* A recording produces a GIF, a per-keyframe attention judgement, and a closing
|
|
5
|
+
* narrative. None of that survives an MCP response: video cannot cross the
|
|
6
|
+
* boundary, and a wall of JSON is not something a person reads. This builds one
|
|
7
|
+
* HTML file that carries all of it, gets written to the served artifact
|
|
8
|
+
* directory, and comes back as a URL — so a chat client, a teammate, or a
|
|
9
|
+
* bookmark all resolve to the same thing.
|
|
10
|
+
*
|
|
11
|
+
* SELF-CONTAINED BY CONSTRUCTION. Everything inlines: no CDN, no stylesheet, no
|
|
12
|
+
* script tag pointing anywhere. The artifact directory is served as static files
|
|
13
|
+
* with no build step, and a player that needs a network fetch to render is a
|
|
14
|
+
* player that breaks the first time something upstream moves.
|
|
15
|
+
*
|
|
16
|
+
* The media itself is referenced by URL rather than inlined — a base64 WebM in
|
|
17
|
+
* an HTML file is a multi-megabyte document that no browser enjoys, and both
|
|
18
|
+
* live in the same served directory anyway.
|
|
19
|
+
*
|
|
20
|
+
* @copyright 2026 Alexandria Eden alexandria.shai.eden@gmail.com https://cbrowser.ai
|
|
21
|
+
* @license MIT
|
|
22
|
+
*/
|
|
23
|
+
/** Escape for text nodes and quoted attributes. */
|
|
24
|
+
function esc(s) {
|
|
25
|
+
return s
|
|
26
|
+
.replace(/&/g, "&")
|
|
27
|
+
.replace(/</g, "<")
|
|
28
|
+
.replace(/>/g, ">")
|
|
29
|
+
.replace(/"/g, """)
|
|
30
|
+
.replace(/'/g, "'");
|
|
31
|
+
}
|
|
32
|
+
function fmtTime(ms) {
|
|
33
|
+
const s = ms / 1000;
|
|
34
|
+
return s < 10 ? `${s.toFixed(1)}s` : `${Math.round(s)}s`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build the player document.
|
|
38
|
+
*
|
|
39
|
+
* Returns a complete HTML string; the caller writes it wherever it is served
|
|
40
|
+
* from. Pure, so it is testable without a filesystem or a network.
|
|
41
|
+
*/
|
|
42
|
+
export function buildCapturePlayer(data) {
|
|
43
|
+
const video = data.artifactUrls.webm ?? data.artifactUrls.mp4;
|
|
44
|
+
const image = data.artifactUrls.gif ?? data.artifactUrls.webp;
|
|
45
|
+
const poster = data.contactSheetUrl;
|
|
46
|
+
// Speed control only exists for video. A GIF's frame delays are baked into the
|
|
47
|
+
// file and no browser API changes them, so offering a slider that silently did
|
|
48
|
+
// nothing would be worse than saying which artifact supports it.
|
|
49
|
+
const speedBar = video
|
|
50
|
+
? `<div class="speed" role="group" aria-label="Playback speed">
|
|
51
|
+
<span class="lbl">Speed</span>
|
|
52
|
+
${[0.25, 0.5, 1, 2].map((r) => `<button type="button" data-rate="${r}"${r === 1 ? ' aria-pressed="true"' : ' aria-pressed="false"'}>${r}×</button>`).join("")}
|
|
53
|
+
<button type="button" data-step="-1" title="Previous frame">◂</button>
|
|
54
|
+
<button type="button" data-step="1" title="Next frame">▸</button>
|
|
55
|
+
</div>`
|
|
56
|
+
: image
|
|
57
|
+
? `<p class="speednote">Speed control needs the video artifact — capture with <code>format: "gif,webm"</code> to get it.</p>`
|
|
58
|
+
: "";
|
|
59
|
+
const media = video
|
|
60
|
+
? `<video id="rec" controls loop muted playsinline${poster ? ` poster="${esc(poster)}"` : ""} src="${esc(video)}"></video>`
|
|
61
|
+
: image
|
|
62
|
+
? `<img src="${esc(image)}" alt="Recording of ${esc(data.targetUrl ?? data.slug)}">`
|
|
63
|
+
: `<p class="empty">No playable artifact was produced for this capture.</p>`;
|
|
64
|
+
const acts = (data.interactions ?? []).slice().sort((a, b) => a.atMs - b.atMs);
|
|
65
|
+
const dur = Math.max(1, data.durationMs);
|
|
66
|
+
// Markers are positioned by fraction of capture duration, so the track lines up
|
|
67
|
+
// with the media above it regardless of artifact format. Only the video can be
|
|
68
|
+
// seeked -- for a GIF the markers still read as a record of what happened, they
|
|
69
|
+
// just do not drive playback, and the note says so rather than silently no-op.
|
|
70
|
+
const actTrack = acts.length === 0
|
|
71
|
+
? ""
|
|
72
|
+
: `
|
|
73
|
+
<section class="acts">
|
|
74
|
+
<h2>Interactions</h2>
|
|
75
|
+
<p class="lede">${acts.length} recorded ${acts.length === 1 ? "event" : "events"}${video ? " — select one to jump there." : " — seeking needs the video artifact."}</p>
|
|
76
|
+
<div class="track" role="list">
|
|
77
|
+
${acts.map((a) => `<button type="button" role="listitem" class="mark" data-at="${a.atMs}" style="--x:${((a.atMs / dur) * 100).toFixed(2)}%" title="${esc(a.type)} · ${esc(a.label.slice(0, 60))}"><span class="dot" data-type="${esc(a.type)}"></span></button>`).join("")}
|
|
78
|
+
</div>
|
|
79
|
+
<ol class="actlist">
|
|
80
|
+
${acts.map((a) => `<li><button type="button" data-at="${a.atMs}"><span class="t">${esc(fmtTime(a.atMs))}</span><span class="kind" data-type="${esc(a.type)}">${esc(a.type)}</span><span class="lab">${esc(a.label.slice(0, 90) || "(no label)")}</span></button></li>`).join("")}
|
|
81
|
+
</ol>
|
|
82
|
+
</section>`;
|
|
83
|
+
const moments = data.moments ?? [];
|
|
84
|
+
const timeline = moments.length === 0
|
|
85
|
+
? ""
|
|
86
|
+
: `
|
|
87
|
+
<section>
|
|
88
|
+
<h2>Attention timeline</h2>
|
|
89
|
+
<p class="lede">Judged at each point the interface changed enough to re-evaluate, not on every frame.</p>
|
|
90
|
+
<ol class="moments">
|
|
91
|
+
${moments.map((m) => `
|
|
92
|
+
<li>
|
|
93
|
+
<div class="t">${esc(fmtTime(m.tMs))}<span class="frame">frame ${m.frameIndex}</span></div>
|
|
94
|
+
<div class="body">
|
|
95
|
+
${m.topElements.length > 0 ? `<ul class="els">${m.topElements.map((e) => `
|
|
96
|
+
<li><span class="bar" style="--w:${Math.round(e.score * 100)}%"></span><span class="score">${e.score.toFixed(2)}</span><span class="txt">${esc(e.text.slice(0, 80))}</span><span class="type">${esc(e.type)}</span></li>`).join("")}</ul>` : `<p class="empty">Nothing scored at this moment.</p>`}
|
|
97
|
+
${m.reasoning ? `<p class="why">${esc(m.reasoning)}</p>` : ""}
|
|
98
|
+
</div>
|
|
99
|
+
</li>`).join("")}
|
|
100
|
+
</ol>
|
|
101
|
+
</section>`;
|
|
102
|
+
const summary = data.summary
|
|
103
|
+
? `<section class="summary"><h2>How this went</h2><p>${esc(data.summary)}</p></section>`
|
|
104
|
+
: "";
|
|
105
|
+
const quantityNote = data.overlay
|
|
106
|
+
? data.overlay.quantity === "predicted-attention"
|
|
107
|
+
? `<span class="pill ok">predicted attention · ${data.overlay.domElements} elements</span>`
|
|
108
|
+
: `<span class="pill warn">visual contrast only · no DOM</span>`
|
|
109
|
+
: "";
|
|
110
|
+
const downloads = Object.entries(data.artifactUrls)
|
|
111
|
+
.map(([fmt, url]) => `<a href="${esc(url)}" download>${esc(fmt)}</a>`)
|
|
112
|
+
.join("");
|
|
113
|
+
return `<!doctype html>
|
|
114
|
+
<html lang="en">
|
|
115
|
+
<head>
|
|
116
|
+
<meta charset="utf-8">
|
|
117
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
118
|
+
<title>${esc(data.targetUrl ?? data.slug)} — capture</title>
|
|
119
|
+
<style>
|
|
120
|
+
:root{
|
|
121
|
+
--ink:#12151c; --paper:#f5f6f8; --card:#fff; --rule:#dfe3ea; --muted:#5f6874;
|
|
122
|
+
--accent:#2f4374; --hot:#b3252b; --ok:#2f6b4f; --warn:#8a6314;
|
|
123
|
+
--mono:ui-monospace,"SF Mono","Cascadia Mono",Menlo,Consolas,monospace;
|
|
124
|
+
}
|
|
125
|
+
@media(prefers-color-scheme:dark){:root{
|
|
126
|
+
--ink:#e6e9ef; --paper:#13161d; --card:#1a1e27; --rule:#2c333f; --muted:#98a2b2;
|
|
127
|
+
--accent:#95a9d8; --hot:#e4838a; --ok:#86c4a2; --warn:#d9b25f;
|
|
128
|
+
}}
|
|
129
|
+
*{box-sizing:border-box}
|
|
130
|
+
body{margin:0;background:var(--paper);color:var(--ink);
|
|
131
|
+
font:16px/1.6 "Charter","Iowan Old Style",Palatino,Georgia,serif;-webkit-font-smoothing:antialiased}
|
|
132
|
+
.wrap{max-width:78ch;margin:0 auto;padding:clamp(1.5rem,4vw,3rem) clamp(1rem,4vw,2rem) 5rem;
|
|
133
|
+
display:flex;flex-direction:column;gap:2rem}
|
|
134
|
+
header{display:flex;flex-direction:column;gap:.6rem}
|
|
135
|
+
.eyebrow{font-family:var(--mono);font-size:.7rem;letter-spacing:.13em;text-transform:uppercase;color:var(--accent)}
|
|
136
|
+
h1{margin:0;font-size:clamp(1.4rem,3.5vw,2rem);line-height:1.2;text-wrap:balance;word-break:break-word}
|
|
137
|
+
h2{font-size:1.2rem;margin:0 0 .5rem;padding-bottom:.35rem;border-bottom:1px solid var(--rule)}
|
|
138
|
+
.meta{display:flex;flex-wrap:wrap;gap:.4rem .9rem;font-family:var(--mono);font-size:.74rem;color:var(--muted)}
|
|
139
|
+
.pill{font-family:var(--mono);font-size:.66rem;letter-spacing:.05em;text-transform:uppercase;
|
|
140
|
+
padding:.18rem .5rem;border-radius:100px;white-space:nowrap}
|
|
141
|
+
.pill.ok{background:color-mix(in srgb,var(--ok) 16%,transparent);color:var(--ok)}
|
|
142
|
+
.pill.warn{background:color-mix(in srgb,var(--warn) 18%,transparent);color:var(--warn)}
|
|
143
|
+
figure{margin:0;background:var(--card);border:1px solid var(--rule);border-radius:6px;overflow:hidden}
|
|
144
|
+
video,img{display:block;width:100%;height:auto;background:#000}
|
|
145
|
+
.lede{color:var(--muted);margin:.2rem 0 1rem;font-size:.95rem}
|
|
146
|
+
.speed{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap;margin-top:-1.4rem}
|
|
147
|
+
.speed .lbl{font-family:var(--mono);font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-right:.2rem}
|
|
148
|
+
.speed button{font-family:var(--mono);font-size:.76rem;padding:.28rem .6rem;border:1px solid var(--rule);
|
|
149
|
+
border-radius:3px;background:var(--card);color:var(--ink);cursor:pointer}
|
|
150
|
+
.speed button:hover{border-color:var(--accent)}
|
|
151
|
+
.speed button[aria-pressed="true"]{background:var(--accent);color:var(--card);border-color:var(--accent)}
|
|
152
|
+
.speed button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
|
|
153
|
+
.speednote{font-size:.85rem;color:var(--muted);margin-top:-1.4rem}
|
|
154
|
+
.acts .lede{margin-bottom:.5rem}
|
|
155
|
+
.acts .track{position:relative;height:26px;margin:.2rem 0 .9rem;border-radius:4px;
|
|
156
|
+
background:linear-gradient(90deg,color-mix(in srgb,var(--rule) 55%,transparent),color-mix(in srgb,var(--rule) 20%,transparent));
|
|
157
|
+
border:1px solid var(--rule)}
|
|
158
|
+
.acts .mark{position:absolute;left:var(--x);top:0;height:100%;width:18px;transform:translateX(-9px);
|
|
159
|
+
background:none;border:0;padding:0;cursor:pointer;display:grid;place-items:center}
|
|
160
|
+
.acts .mark .dot{width:11px;height:11px;border-radius:50%;background:var(--accent);
|
|
161
|
+
border:2px solid var(--card);box-shadow:0 0 0 1px var(--accent)}
|
|
162
|
+
.acts .mark .dot[data-type="submit"]{background:#d1495b;box-shadow:0 0 0 1px #d1495b}
|
|
163
|
+
.acts .mark .dot[data-type="input"]{background:#e0a458;box-shadow:0 0 0 1px #e0a458}
|
|
164
|
+
.acts .mark:hover .dot{transform:scale(1.35)}
|
|
165
|
+
.acts .mark:focus-visible{outline:2px solid var(--accent);outline-offset:1px;border-radius:3px}
|
|
166
|
+
.actlist{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.15rem}
|
|
167
|
+
.actlist button{display:flex;gap:.6rem;align-items:baseline;width:100%;text-align:left;
|
|
168
|
+
background:none;border:0;border-radius:4px;padding:.3rem .45rem;cursor:pointer;color:inherit;font:inherit}
|
|
169
|
+
.actlist button:hover{background:color-mix(in srgb,var(--accent) 9%,transparent)}
|
|
170
|
+
.actlist button:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
|
|
171
|
+
.actlist .t{font-family:var(--mono);font-size:.74rem;color:var(--muted);flex:0 0 3.6rem;font-variant-numeric:tabular-nums}
|
|
172
|
+
.actlist .kind{font-family:var(--mono);font-size:.66rem;text-transform:uppercase;letter-spacing:.08em;
|
|
173
|
+
padding:.08rem .34rem;border-radius:3px;background:color-mix(in srgb,var(--accent) 16%,transparent);flex:0 0 auto}
|
|
174
|
+
.actlist .kind[data-type="submit"]{background:color-mix(in srgb,#d1495b 18%,transparent)}
|
|
175
|
+
.actlist .kind[data-type="input"]{background:color-mix(in srgb,#e0a458 22%,transparent)}
|
|
176
|
+
.actlist .lab{font-size:.85rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
177
|
+
@media (prefers-reduced-motion:reduce){.acts .mark:hover .dot{transform:none}}
|
|
178
|
+
.moments{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.9rem}
|
|
179
|
+
.moments>li{display:grid;grid-template-columns:5.5rem 1fr;gap:0 1rem;background:var(--card);
|
|
180
|
+
border:1px solid var(--rule);border-left:3px solid var(--accent);border-radius:4px;padding:.9rem 1rem}
|
|
181
|
+
.t{font-family:var(--mono);font-size:.9rem;font-weight:600;font-variant-numeric:tabular-nums;
|
|
182
|
+
display:flex;flex-direction:column;gap:.15rem}
|
|
183
|
+
.frame{font-weight:400;font-size:.66rem;color:var(--muted)}
|
|
184
|
+
.els{list-style:none;margin:0 0 .5rem;padding:0;display:flex;flex-direction:column;gap:.3rem}
|
|
185
|
+
.els li{display:grid;grid-template-columns:7rem 2.6rem 1fr auto;align-items:center;gap:.5rem;font-size:.86rem}
|
|
186
|
+
/* Track + fill, so a 0.44 reads as visibly under half rather than as a short
|
|
187
|
+
bar the eye has nothing to compare against. */
|
|
188
|
+
.els li>span:first-child{position:relative;height:.5rem;border-radius:2px;
|
|
189
|
+
background:color-mix(in srgb,var(--rule) 70%,transparent)}
|
|
190
|
+
.bar::after{content:"";position:absolute;inset:0 auto 0 0;width:var(--w);
|
|
191
|
+
border-radius:2px;background:linear-gradient(90deg,var(--accent),var(--hot))}
|
|
192
|
+
.score{font-family:var(--mono);font-size:.76rem;font-variant-numeric:tabular-nums;color:var(--muted)}
|
|
193
|
+
.txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
194
|
+
.type{font-family:var(--mono);font-size:.64rem;text-transform:uppercase;color:var(--muted)}
|
|
195
|
+
.why{margin:.4rem 0 0;font-size:.92rem;color:var(--ink)}
|
|
196
|
+
.summary{background:var(--card);border:1px solid var(--rule);border-left:3px solid var(--ok);
|
|
197
|
+
border-radius:4px;padding:1.1rem 1.3rem}
|
|
198
|
+
.summary p{margin:0}
|
|
199
|
+
.empty{color:var(--muted);font-style:italic;margin:0}
|
|
200
|
+
.dl{display:flex;gap:.5rem;flex-wrap:wrap}
|
|
201
|
+
.dl a{font-family:var(--mono);font-size:.72rem;text-transform:uppercase;letter-spacing:.05em;
|
|
202
|
+
padding:.3rem .7rem;border:1px solid var(--rule);border-radius:3px;color:var(--accent);text-decoration:none}
|
|
203
|
+
.dl a:hover,.dl a:focus-visible{border-color:var(--accent)}
|
|
204
|
+
footer{border-top:1px solid var(--rule);padding-top:1rem;font-size:.8rem;color:var(--muted)}
|
|
205
|
+
a:focus-visible,video:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
|
|
206
|
+
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
|
|
207
|
+
@media(max-width:600px){.moments>li{grid-template-columns:1fr;gap:.5rem}
|
|
208
|
+
.els li{grid-template-columns:5rem 2.4rem 1fr;}.type{display:none}}
|
|
209
|
+
</style>
|
|
210
|
+
</head>
|
|
211
|
+
<body>
|
|
212
|
+
<div class="wrap">
|
|
213
|
+
<header>
|
|
214
|
+
<div class="eyebrow">cbrowser capture</div>
|
|
215
|
+
<h1>${esc(data.targetUrl ?? data.slug)}</h1>
|
|
216
|
+
<div class="meta">
|
|
217
|
+
<span>${esc(fmtTime(data.durationMs))}</span>
|
|
218
|
+
<span>${data.frames} frames</span>
|
|
219
|
+
<span>${data.actualFps.toFixed(1)} fps</span>
|
|
220
|
+
${data.personaName ? `<span>persona: ${esc(data.personaName)}</span>` : ""}
|
|
221
|
+
${data.goal ? `<span>goal: ${esc(data.goal)}</span>` : ""}
|
|
222
|
+
${quantityNote}
|
|
223
|
+
</div>
|
|
224
|
+
</header>
|
|
225
|
+
|
|
226
|
+
<figure>${media}</figure>
|
|
227
|
+
${speedBar}
|
|
228
|
+
${actTrack}
|
|
229
|
+
|
|
230
|
+
${summary}
|
|
231
|
+
${timeline}
|
|
232
|
+
|
|
233
|
+
${downloads ? `<section><h2>Files</h2><div class="dl">${downloads}</div></section>` : ""}
|
|
234
|
+
|
|
235
|
+
<footer>
|
|
236
|
+
${data.overlay
|
|
237
|
+
? data.overlay.quantity === "predicted-attention"
|
|
238
|
+
? "Overlay shows the model’s predicted attention, blending visual contrast with DOM semantics. It has not been validated against human eye movements."
|
|
239
|
+
: "Overlay shows visual contrast only — no DOM was available, so the semantic half of the model did not run."
|
|
240
|
+
: "No attention overlay was applied to this capture."}
|
|
241
|
+
</footer>
|
|
242
|
+
</div>
|
|
243
|
+
<script>
|
|
244
|
+
// Interaction seeking lives in its own IIFE: the player script below returns
|
|
245
|
+
// early when there is no <video>, and the markers must still render and respond
|
|
246
|
+
// on a GIF-only capture even though nothing can be seeked.
|
|
247
|
+
(function () {
|
|
248
|
+
var v = document.getElementById("rec");
|
|
249
|
+
document.querySelectorAll("[data-at]").forEach(function (b) {
|
|
250
|
+
b.addEventListener("click", function () {
|
|
251
|
+
var t = parseInt(b.getAttribute("data-at"), 10) / 1000;
|
|
252
|
+
if (v && isFinite(t)) { v.currentTime = t; v.pause(); }
|
|
253
|
+
document.querySelectorAll("[data-at]").forEach(function (o) {
|
|
254
|
+
o.setAttribute("aria-current", o === b ? "true" : "false");
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
})();
|
|
259
|
+
(function () {
|
|
260
|
+
var v = document.getElementById("rec");
|
|
261
|
+
if (!v) return;
|
|
262
|
+
var bar = document.querySelector(".speed");
|
|
263
|
+
if (!bar) return;
|
|
264
|
+
|
|
265
|
+
// Frame step uses the capture's real rate, not a guessed 30fps — stepping by
|
|
266
|
+
// the wrong interval lands between frames and looks like nothing happened.
|
|
267
|
+
var FRAME = ${data.actualFps > 0 ? (1 / data.actualFps).toFixed(4) : "0.25"};
|
|
268
|
+
|
|
269
|
+
bar.addEventListener("click", function (e) {
|
|
270
|
+
var b = e.target.closest("button");
|
|
271
|
+
if (!b) return;
|
|
272
|
+
if (b.dataset.rate) {
|
|
273
|
+
v.playbackRate = parseFloat(b.dataset.rate);
|
|
274
|
+
bar.querySelectorAll("[data-rate]").forEach(function (o) {
|
|
275
|
+
o.setAttribute("aria-pressed", String(o === b));
|
|
276
|
+
});
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (b.dataset.step) {
|
|
280
|
+
v.pause();
|
|
281
|
+
v.currentTime = Math.max(0, v.currentTime + parseInt(b.dataset.step, 10) * FRAME);
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
document.addEventListener("keydown", function (e) {
|
|
286
|
+
if (e.target && /input|textarea/i.test(e.target.tagName)) return;
|
|
287
|
+
if (e.key === "," || e.key === ".") {
|
|
288
|
+
e.preventDefault();
|
|
289
|
+
v.pause();
|
|
290
|
+
v.currentTime = Math.max(0, v.currentTime + (e.key === "." ? FRAME : -FRAME));
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
})();
|
|
294
|
+
</script>
|
|
295
|
+
</body>
|
|
296
|
+
</html>`;
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=capture-player.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture-player.js","sourceRoot":"","sources":["../../src/recording/capture-player.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,6 +50,24 @@ export interface VideoCaptureOptions {
|
|
|
50
50
|
columns?: number;
|
|
51
51
|
maxFrames?: number;
|
|
52
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* Paint the visual-contrast (saliency) map over every frame before encoding.
|
|
55
|
+
*
|
|
56
|
+
* Opt-in because it costs one saliency pass per frame (~0.5-1s each), so a
|
|
57
|
+
* 50-frame capture adds 30-60s. The result is a CONTRAST map, not a gaze
|
|
58
|
+
* prediction — see `saliency-overlay.ts` for why that distinction is load-bearing.
|
|
59
|
+
*/
|
|
60
|
+
saliencyOverlay?: boolean | {
|
|
61
|
+
opacity?: number;
|
|
62
|
+
floor?: number;
|
|
63
|
+
cellSize?: number;
|
|
64
|
+
/** Persona whose priorities weight the semantic half of the blend. */
|
|
65
|
+
persona?: string;
|
|
66
|
+
/** Goal string weighting goal-relevance in the semantic half. */
|
|
67
|
+
goal?: string;
|
|
68
|
+
/** Whether the caller may spend paid model calls on judging and summary. */
|
|
69
|
+
entitled?: boolean;
|
|
70
|
+
};
|
|
53
71
|
/** Delay the first frame until this condition holds. */
|
|
54
72
|
startTrigger?: StartTrigger;
|
|
55
73
|
/** Extra delay after the start trigger fires, in milliseconds. */
|
|
@@ -109,6 +127,40 @@ export declare class VideoCaptureSession {
|
|
|
109
127
|
private startedAtIso;
|
|
110
128
|
private stopWallMs;
|
|
111
129
|
private frames;
|
|
130
|
+
/**
|
|
131
|
+
* DOM as it stood at a point in time, captured on navigation.
|
|
132
|
+
*
|
|
133
|
+
* Reading the DOM once at stop and stamping it across every frame is wrong the
|
|
134
|
+
* moment a capture navigates: frame 0 on the pricing page was being judged
|
|
135
|
+
* against the post-click verification screen, which made every judged moment
|
|
136
|
+
* identical and let the summary confabulate a UX finding out of a tool
|
|
137
|
+
* artifact. One extract per navigation is cheap; per frame would be a
|
|
138
|
+
* page.evaluate on every screencast tick.
|
|
139
|
+
*/
|
|
140
|
+
private domSnapshots;
|
|
141
|
+
/**
|
|
142
|
+
* Scroll position over time, sampled cheaply.
|
|
143
|
+
*
|
|
144
|
+
* Element rects come from getBoundingClientRect, which is VIEWPORT-relative at
|
|
145
|
+
* the instant of extraction. Between snapshots the page keeps scrolling, so a
|
|
146
|
+
* rect captured before a scroll describes a position the element has since
|
|
147
|
+
* left — the heat lands below where the element now is, by exactly the drift.
|
|
148
|
+
* Storing scroll per sample lets the renderer correct each frame back to what
|
|
149
|
+
* was actually on screen.
|
|
150
|
+
*/
|
|
151
|
+
private scrollTrack;
|
|
152
|
+
/**
|
|
153
|
+
* Real interactions, captured from the page rather than inferred.
|
|
154
|
+
*
|
|
155
|
+
* The capture summary previously read the gap between two scripted tool calls
|
|
156
|
+
* as a user deliberating, and recommended a design change to fix the stall it
|
|
157
|
+
* had invented. Gagging the prompt stops the bad sentence; recording what
|
|
158
|
+
* actually happened is what makes the good one possible — and it is the same
|
|
159
|
+
* data needed to draw a ring where a click landed.
|
|
160
|
+
*/
|
|
161
|
+
private interactions;
|
|
162
|
+
private navListener?;
|
|
163
|
+
private scrollTimer?;
|
|
112
164
|
private nextDueMs;
|
|
113
165
|
private writeQueue;
|
|
114
166
|
private consoleEvents;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/recording/engine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA8BH,OAAO,KAAK,EAA8B,OAAO,EAAE,IAAI,EAAW,MAAM,YAAY,CAAC;AAMrF,OAAO,EAKL,KAAK,aAAa,EAElB,KAAK,MAAM,EAGX,KAAK,iBAAiB,EACtB,KAAK,eAAe,EAErB,MAAM,YAAY,CAAC;AAEpB,0CAA0C;AAC1C,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAE5D,6CAA6C;AAC7C,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,aAAa,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,uCAAuC;AACvC,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,wDAAwD;AACxD,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAkBjD,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACzB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE,wDAAwD;IACxD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,4BAA4B;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/recording/engine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA8BH,OAAO,KAAK,EAA8B,OAAO,EAAE,IAAI,EAAW,MAAM,YAAY,CAAC;AAMrF,OAAO,EAKL,KAAK,aAAa,EAElB,KAAK,MAAM,EAGX,KAAK,iBAAiB,EACtB,KAAK,eAAe,EAErB,MAAM,YAAY,CAAC;AAEpB,0CAA0C;AAC1C,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAE5D,6CAA6C;AAC7C,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,aAAa,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1C,uCAAuC;AACvC,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,wDAAwD;AACxD,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAkBjD,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4FAA4F;IAC5F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,aAAa,EAAE,CAAC;IACzB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,GAAG;QAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,sEAAsE;QACtE,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,iEAAiE;QACjE,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,4EAA4E;QAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;IACF,wDAAwD;IACxD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,4BAA4B;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAgFD;;;GAGG;AACH,qBAAa,mBAAmB;IAmH5B,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,OAAO;IApHjB,OAAO,CAAC,IAAI,CAC8B;IAC1C,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,SAAS,CAAM;IAEvB,OAAO,CAAC,KAAK,CAA4C;IACzD,OAAO,CAAC,aAAa,CAAmC;IACxD,OAAO,CAAC,GAAG,CAA2B;IACtC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,QAAQ,CAA4C;IAE5D,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,MAAM,CAAsB;IACpC;;;;;;;;;OASG;IACH,OAAO,CAAC,YAAY,CAAqE;IACzF;;;;;;;;;OASG;IACH,OAAO,CAAC,WAAW,CAAgD;IACnE;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY,CAEZ;IACR,OAAO,CAAC,WAAW,CAAC,CAAa;IACjC,OAAO,CAAC,WAAW,CAAC,CAAiC;IACrD,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,UAAU,CAAuC;IAEzD,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,eAAe,CAAgD;IACvE,OAAO,CAAC,eAAe,CAAyC;IAEhE,OAAO,CAAC,QAAQ,CAAiD;IACjE,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,UAAU,CAA2B;IAC7C;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAIxB,2FAA2F;IAC3F,OAAO,CAAC,WAAW,CAAqB;IACxC,uEAAuE;IACvE,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,UAAU,CAA+B;IAEjD,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,gBAAgB,CAA+B;IACvD,oDAAoD;IACpD,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,eAAe,CAAwC;IAC/D;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAE3C;IAEH;;;;;OAKG;gBAEO,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;IAOnB,KAAK,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAwF3E;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAYzC,MAAM,IAAI,kBAAkB;IAc5B;;;;;;;OAOG;YACW,WAAW;IAyDzB;;;OAGG;YACW,cAAc;IAsB5B;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IA8B5B;;;;;;OAMG;YACW,iBAAiB;IA2B/B,mDAAmD;YACrC,mBAAmB;IAsBjC,8DAA8D;YAChD,gBAAgB;IAc9B;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IAoC7B,+DAA+D;YACjD,kBAAkB;IAchC;;;;;OAKG;IACH,OAAO,CAAC,SAAS;YAuCH,eAAe;IAwB7B,0EAA0E;IAC1E,OAAO,CAAC,mBAAmB;IAc3B;;;OAGG;YACW,kBAAkB;IAYhC;;;;;;;OAOG;IACH,OAAO,CAAC,UAAU;IAYlB;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;YAkCN,mBAAmB;IAiHjC,OAAO,CAAC,mBAAmB;YAWb,MAAM;YAmDN,aAAa;IAwD3B,0EAA0E;YAC5D,WAAW;IAsBzB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAWtB;;;;OAIG;YACW,WAAW;CA2J1B"}
|