@opengeni/react 5.2.0-canary.1 → 6.0.0-canary.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.
@@ -1,4 +1,4 @@
1
1
  export { inlineHtmlDocument } from "./components/artifacts/inline-html-document.js";
2
- export { useRetainedImageObjectUrl } from "./timeline/retained-image.js";
2
+ export { isRetainedImageContentType, useRetainedImageObjectUrl } from "./timeline/retained-image.js";
3
3
  /** Public artifact surfaces. Import from `@opengeni/react/artifacts`. */
4
4
  export { ArtifactSurface, DocumentArtifactSurface, DocumentEditor, DocumentProjectionArtifactSurface, DocumentProjectionEditor, BrowserEditableArtifactWorkbench, EditableDocumentArtifactSurface, EditableArtifactWorkbench, EditableArtifactWorkbenchHost, EditablePresentationArtifactSurface, EditableSpreadsheetArtifactSurface, EditableSpreadsheetGrid, PresentationArtifactSurface, PresentationEditor, PresentationProjectionArtifactSurface, PresentationProjectionEditor, PublishedHtmlArtifactFrame, PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX, openGeniSiteBridgePortFromBootstrap, publishedHtmlArtifactDocument, SpreadsheetArtifactSurface, SpreadsheetGrid, SpreadsheetProjectionGrid, type ArtifactModality, type ArtifactSurfaceProps, type DocumentArtifactSurfaceProps, type DocumentCommit, type DocumentCommitHandler, type DocumentEditorProps, type DocumentEditorProjection, type DocumentLayoutMode, type DocumentProjectionArtifactSurfaceProps, type DocumentProjectionBlock, type DocumentProjectionChange, type DocumentProjectionComment, type DocumentProjectionEditorProps, type DocumentProjectionPageBreak, type DocumentProjectionPageGeometry, type DocumentProjectionParagraph, type DocumentProjectionParagraphStyle, type DocumentProjectionSection, type DocumentProjectionTable, type DocumentProjectionTextRun, type DocumentProjectionTextStyle, type DocumentSelection, type BrowserEditableArtifactWorkbenchOptions, type BrowserEditableArtifactWorkbenchProps, type EditableDocumentArtifactSurfaceProps, type EditableArtifactWorkbenchHostProps, type EditableArtifactWorkbenchProps, type EditablePresentationArtifactSurfaceProps, type EditableSpreadsheetArtifactSurfaceProps, type EditableSpreadsheetGridProps, type PresentationArtifactSurfaceProps, type PresentationCommit, type PresentationCommitHandler, type PresentationEditorProps, type PresentationEditorProjection, type PresentationProjectionArtifactSurfaceProps, type PresentationProjectionChart, type PresentationProjectionChartSeries, type PresentationProjectionConnector, type PresentationProjectionEditorProps, type PublishedHtmlArtifactFrameProps, type PublishedHtmlArtifactToolBridge, type PresentationProjectionElementMetadata, type PresentationProjectionElement, type PresentationProjectionFill, type PresentationProjectionGroup, type PresentationProjectionImage, type PresentationProjectionLine, type PresentationProjectionPosition, type PresentationProjectionRichText, type PresentationProjectionShape, type PresentationProjectionTable, type PresentationProjectionTableCell, type PresentationProjectionTextParagraph, type PresentationProjectionTextRun, type PresentationProjectionTextStyle, type PresentationSlideProjection, type SpreadsheetArtifactSurfaceProps, type SpreadsheetCommit, type SpreadsheetRangeCommit, type SpreadsheetGridProps, type SpreadsheetGridProjection, type SpreadsheetProjectionCell, type SpreadsheetProjectionGridProps, type SpreadsheetSelection, type SpreadsheetViewport, } from "./components/artifacts/index.js";
package/dist/artifacts.js CHANGED
@@ -19,8 +19,9 @@ import {
19
19
  publishedHtmlArtifactDocument
20
20
  } from "./chunk-UGMKPUEM.js";
21
21
  import {
22
+ isRetainedImageContentType,
22
23
  useRetainedImageObjectUrl
23
- } from "./chunk-2TKI3WEG.js";
24
+ } from "./chunk-WYWRYUNQ.js";
24
25
  import {
25
26
  EditableSpreadsheetArtifactSurface,
26
27
  EditableSpreadsheetGrid,
@@ -1562,6 +1563,7 @@ export {
1562
1563
  SpreadsheetGrid,
1563
1564
  SpreadsheetProjectionGrid,
1564
1565
  inlineHtmlDocument,
1566
+ isRetainedImageContentType,
1565
1567
  openGeniSiteBridgePortFromBootstrap,
1566
1568
  publishedHtmlArtifactDocument,
1567
1569
  useRetainedImageObjectUrl
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/artifacts/visualization-assets.gen.ts","../src/components/artifacts/inline-html-document.ts","../src/components/artifacts/editable-artifact-workbench.tsx"],"sourcesContent":["// Generated by scripts/generate-visualization-assets.ts.\nexport const VISUALIZATION_CSS = \"/* Adapted from Codex visualize 1.0.32; shared with the OpenGeni visualization skill. */\\n:root {\\n color-scheme: light dark;\\n background-color: var(\\n --background,\\n var(--color-background-primary, light-dark(rgb(255 255 255), rgb(24 24 24)))\\n ) !important;\\n\\n /* Agent-facing contract; keep in sync with SKILL.md. */\\n --background: var(\\n --color-background-primary,\\n light-dark(rgb(255 255 255), rgb(24 24 24))\\n );\\n --foreground: var(\\n --color-text-primary,\\n light-dark(rgb(26 28 31), rgb(255 255 255))\\n );\\n --card: color-mix(in oklab, var(--foreground) 5%, var(--background));\\n --card-foreground: var(\\n --color-text-primary,\\n light-dark(rgb(26 28 31), rgb(255 255 255))\\n );\\n --popover: var(\\n --color-background-secondary,\\n light-dark(rgb(255 255 255), rgb(45 45 45))\\n );\\n --popover-foreground: var(\\n --color-text-primary,\\n light-dark(rgb(26 28 31), rgb(255 255 255))\\n );\\n --primary: var(\\n --color-text-info,\\n light-dark(rgb(51 156 255), rgb(131 195 255))\\n );\\n --primary-foreground: var(\\n --color-text-inverse,\\n light-dark(rgb(255 255 255), rgb(13 13 13))\\n );\\n --secondary: var(\\n --color-background-secondary,\\n light-dark(rgb(255 255 255 / 96%), rgb(54 54 54 / 96%))\\n );\\n --secondary-foreground: var(\\n --color-text-primary,\\n light-dark(rgb(26 28 31), rgb(255 255 255))\\n );\\n --muted: color-mix(in srgb, var(--foreground) 10%, transparent);\\n --muted-foreground: var(\\n --color-text-secondary,\\n light-dark(rgb(26 28 31 / 49.4%), rgb(255 255 255 / 49.8%))\\n );\\n --accent: var(\\n --color-background-info,\\n light-dark(rgb(229 242 255), rgb(13 39 63))\\n );\\n --accent-foreground: var(\\n --color-text-info,\\n light-dark(rgb(51 156 255), rgb(131 195 255))\\n );\\n --destructive: var(\\n --color-text-warning,\\n light-dark(rgb(226 85 7), rgb(255 133 73))\\n );\\n --border: var(\\n --color-border-secondary,\\n light-dark(rgb(26 28 31 / 8%), rgb(255 255 255 / 8.2%))\\n );\\n --input: var(\\n --color-border-primary,\\n light-dark(\\n rgb(26 28 31 / 11.8%),\\n color-mix(in oklab, rgb(0 0 0) 10%, transparent)\\n )\\n );\\n --ring: var(\\n --color-ring-primary,\\n light-dark(rgb(51 156 255), rgb(131 195 255 / 76%))\\n );\\n --font-size-base: var(--font-text-md-size, 14px);\\n --blue: light-dark(rgb(51 156 255), rgb(51 156 255));\\n --orange: light-dark(rgb(226 85 7), rgb(251 106 34));\\n --green: light-dark(rgb(0 162 64), rgb(64 201 119));\\n --red: light-dark(rgb(224 46 42), rgb(255 103 100));\\n --purple: light-dark(rgb(146 79 247), rgb(173 123 249));\\n --yellow: light-dark(rgb(255 195 0), rgb(255 210 64));\\n --viz-series-1: var(--primary);\\n --viz-series-2: light-dark(rgb(243 136 59), rgb(245 154 86));\\n --viz-series-3: light-dark(rgb(93 201 119), rgb(116 213 139));\\n --viz-series-4: light-dark(rgb(235 119 177), rgb(240 143 192));\\n --viz-series-5: light-dark(rgb(155 121 236), rgb(170 145 239));\\n --viz-series-6: light-dark(rgb(58 185 177), rgb(90 203 194));\\n\\n /* Internal implementation variables; not part of the agent contract. */\\n --font-sans: -apple-system, system-ui, \\\"Segoe UI\\\", sans-serif;\\n --font-mono:\\n ui-monospace, SFMono-Regular, \\\"SF Mono\\\", Menlo, Consolas, \\\"Liberation Mono\\\",\\n monospace;\\n --font-size-normal: max(11px, var(--font-size-base));\\n --font-size-tooltip: calc(var(--font-size-base) - 1px);\\n --font-size-small: max(11px, calc(var(--font-size-base) - 2px));\\n --font-size-h1: calc(var(--font-size-normal) * 1.7142857143);\\n --font-size-h2: calc(var(--font-size-normal) * 1.4285714286);\\n --font-size-h3: calc(var(--font-size-normal) * 1.2857142857);\\n --font-weight-normal: 430;\\n --font-weight-medium: 500;\\n --icon-size: 16px;\\n --line-height-normal: calc(var(--font-size-normal) * 1.5);\\n --line-height-tooltip: calc(var(--font-size-tooltip) * 1.4285714286);\\n --line-height-small: calc(var(--font-size-small) + 4px);\\n --corner-shape: round;\\n --radius: var(--border-radius-lg, 10px);\\n --radius-sm: calc(var(--radius) * 0.6);\\n --radius-md: calc(var(--radius) * 0.8);\\n --radius-lg: var(--radius);\\n --radius-2xl: calc(var(--radius) * 1.6);\\n --radius-full: 9999px;\\n --shadow-sm: 0 1px 2px -1px rgb(0 0 0 / 8%);\\n --checkmark-image: url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 17 17'%3E%3Cpath d='M 12.8961 3.64101C13.1297 3.41418 13.4984 3.37523 13.7779 3.56581C14.0571 3.75635 14.1554 4.11331 14.0299 4.41347L13.9615 4.53847L7.71151 13.7045C7.59411 13.8767 7.4063 13.9877 7.19881 14.0072C6.99136 14.0267 6.78564 13.9533 6.63826 13.806L2.88826 10.056L2.79842 9.9457C2.6192 9.67407 2.64927 9.30496 2.88826 9.06581C3.12738 8.82669 3.49647 8.79676 3.76815 8.97597L3.8785 9.06581L7.03084 12.2182L12.8053 3.74941L12.8961 3.64101Z'/%3E%3C/svg%3E\\\");\\n\\n /* Legacy aliases; not part of the current agent contract. */\\n --viz-bg: transparent;\\n --viz-panel: var(--card);\\n --viz-border: var(--border);\\n --viz-text: var(--foreground);\\n --viz-muted: var(--muted-foreground);\\n --viz-accent: var(--primary);\\n --viz-accent-text: var(--primary-foreground);\\n --viz-accent-bg: var(--accent);\\n --viz-font-size: var(--font-size-base);\\n --viz-warning: var(--destructive);\\n}\\n\\n:root[data-theme=\\\"light\\\"] {\\n color-scheme: light;\\n}\\n\\n:root[data-theme=\\\"dark\\\"] {\\n color-scheme: dark;\\n}\\n\\n* {\\n box-sizing: border-box;\\n}\\n\\nhtml > body {\\n /* Preserve MCP aliases for older inline renderers without creating :root cycles. */\\n --color-background-primary: var(\\n --background,\\n light-dark(rgb(255 255 255), rgb(24 24 24))\\n );\\n --color-text-primary: var(\\n --foreground,\\n light-dark(rgb(26 28 31), rgb(255 255 255))\\n );\\n --color-border-secondary: var(\\n --border,\\n light-dark(rgb(26 28 31 / 8%), rgb(255 255 255 / 8.2%))\\n );\\n\\n margin: 0;\\n padding: var(--visualize-paint-gutter, 16px);\\n color: var(--foreground);\\n background: transparent !important;\\n font-family: var(--font-sans) !important;\\n font-size: var(--font-size-normal);\\n font-weight: var(--font-weight-normal);\\n line-height: var(--line-height-normal);\\n}\\n\\na {\\n color: color-mix(in srgb, var(--viz-accent) 80%, var(--viz-text) 20%);\\n cursor: pointer;\\n font-weight: var(--font-weight-medium, 500);\\n text-decoration: none;\\n text-underline-offset: 2px;\\n}\\n\\na:is(:hover, :focus-visible) {\\n text-decoration-line: underline;\\n text-decoration-style: dashed;\\n text-decoration-thickness: 0.5px;\\n}\\n\\nh1,\\nh2,\\nh3,\\nh4,\\nh5,\\nh6,\\np {\\n margin-block: 0;\\n}\\n\\nh1 {\\n font-size: var(--font-size-h1);\\n font-weight: var(--font-weight-medium);\\n line-height: 1.25;\\n}\\n\\nh2 {\\n font-size: var(--font-size-h2);\\n font-weight: var(--font-weight-medium);\\n line-height: 1.25;\\n}\\n\\nh3,\\nh4,\\nh5,\\nh6 {\\n font-size: var(--font-size-h3);\\n font-weight: var(--font-weight-medium);\\n line-height: 1.3;\\n}\\n\\nb,\\nstrong,\\nth {\\n font-weight: var(--font-weight-medium);\\n}\\n\\ncode:not(pre code) {\\n display: inline;\\n padding: 1px 6px;\\n border-radius: var(--radius-sm);\\n corner-shape: var(--corner-shape);\\n background: var(--muted);\\n font-family: var(--font-mono);\\n font-size: 0.92em;\\n overflow-wrap: anywhere;\\n -webkit-box-decoration-break: clone;\\n box-decoration-break: clone;\\n word-break: break-word;\\n}\\n\\n.table-responsive {\\n width: 100%;\\n overflow-x: auto;\\n scrollbar-width: thin;\\n}\\n\\n.table {\\n width: 100%;\\n border-collapse: collapse;\\n color: var(--foreground);\\n font: inherit;\\n text-align: start;\\n}\\n\\n.table :is(th, td) {\\n padding-block: 10px;\\n padding-inline: 0 24px;\\n overflow-wrap: anywhere;\\n border-bottom: 1px solid var(--border);\\n text-align: start;\\n vertical-align: top;\\n}\\n\\n.table-responsive > .table :is(th, td) {\\n overflow-wrap: break-word;\\n}\\n\\n.table :is(th, td):last-child {\\n padding-inline-end: 0;\\n}\\n\\n.table :is(caption, thead th) {\\n font-weight: 600;\\n}\\n\\n.table thead th {\\n padding-block: 8px;\\n border-bottom-color: color-mix(in srgb, var(--foreground) 16%, transparent);\\n}\\n\\n.table tbody tr:last-child :is(th, td) {\\n border-bottom: 0;\\n}\\n\\n.table.table-sm :is(th, td) {\\n padding-block: 6px;\\n}\\n\\n.table.table-sm :is(th, td):not(:last-child) {\\n padding-inline-end: 16px;\\n}\\n\\n.table :is(.text-end, [align=\\\"right\\\"]) {\\n text-align: end;\\n font-variant-numeric: tabular-nums;\\n}\\n\\n.table :is(.text-center, [align=\\\"center\\\"]) {\\n text-align: center;\\n}\\n\\n.table .text-nowrap {\\n white-space: nowrap;\\n}\\n\\n#widget {\\n display: flex;\\n flex-direction: column;\\n gap: 12px;\\n width: 100%;\\n padding: 0;\\n background: transparent !important;\\n}\\n\\n.card {\\n min-width: 0;\\n padding: 12px;\\n overflow: hidden;\\n overflow-wrap: break-word;\\n border-radius: var(--radius-2xl);\\n corner-shape: var(--corner-shape);\\n color: var(--card-foreground);\\n background: var(--card);\\n}\\n\\n#widget > :not(.card, .progress) {\\n width: 100% !important;\\n max-width: none !important;\\n margin: 0 !important;\\n padding: 0 !important;\\n border: 0 !important;\\n border-radius: 0 !important;\\n background: transparent !important;\\n box-shadow: none !important;\\n}\\n\\n.tooltip {\\n position: fixed;\\n z-index: 50;\\n top: 0;\\n left: 0;\\n width: max-content;\\n max-width: min(\\n 20rem,\\n var(--tooltip-available-width, calc(100vw - 10px)),\\n calc(100vw - 10px)\\n );\\n max-height: min(\\n var(--tooltip-available-height, calc(100vh - 10px)),\\n calc(100vh - 10px)\\n );\\n padding: 4px 8px;\\n border: 1px solid var(--border);\\n border-radius: var(--radius-lg);\\n corner-shape: var(--corner-shape);\\n color: var(--popover-foreground);\\n background: var(--popover);\\n box-shadow: none;\\n font-size: var(--font-size-tooltip);\\n line-height: var(--line-height-tooltip);\\n overflow-wrap: break-word;\\n white-space: normal;\\n pointer-events: none;\\n user-select: none;\\n}\\n\\n.viz-grid {\\n display: grid;\\n grid-template-columns: repeat(auto-fit, minmax(max(180px, 24%), 1fr));\\n gap: 10px;\\n}\\n\\n.viz-stat {\\n display: flex;\\n flex-direction: column;\\n gap: 2px;\\n}\\n\\n.viz-stat-value {\\n font-size: var(--font-size-h2);\\n font-weight: var(--font-weight-medium);\\n line-height: 1.25;\\n}\\n\\n.viz-row {\\n display: flex;\\n flex-wrap: wrap;\\n align-items: center;\\n gap: 10px;\\n}\\n\\nhr {\\n width: 100%;\\n height: 1px;\\n margin-block: 6px;\\n border: 0;\\n background: var(--border);\\n}\\n\\n.nav {\\n display: flex;\\n min-width: 0;\\n align-items: center;\\n gap: 4px;\\n}\\n\\n.progress {\\n display: flex;\\n height: 8px;\\n margin-block: calc((var(--line-height-normal, 1.5em) - 8px) / 2);\\n overflow: hidden;\\n border: 0;\\n border-radius: var(--radius-full);\\n background: var(--muted);\\n}\\n\\n.progress-bar:only-child {\\n border-radius: var(--radius-full);\\n}\\n\\n.progress-bar {\\n height: 100%;\\n flex-shrink: 0;\\n border: 0;\\n background: var(--viz-series-1);\\n}\\n\\n.viz-badge {\\n padding: 3px 8px;\\n border-radius: var(--radius-full);\\n color: var(--accent-foreground);\\n background: var(--accent);\\n font-weight: var(--font-weight-medium);\\n}\\n\\nsmall,\\n.text-small,\\n.viz-badge {\\n font-size: var(--font-size-small);\\n line-height: var(--line-height-small);\\n}\\n\\n.text-muted {\\n color: var(--muted-foreground);\\n}\\n\\n.tabular-nums {\\n font-variant-numeric: tabular-nums;\\n}\\n\\n.sr-only {\\n position: absolute;\\n width: 1px;\\n height: 1px;\\n padding: 0;\\n overflow: hidden;\\n clip: rect(0, 0, 0, 0);\\n white-space: nowrap;\\n border: 0;\\n}\\n\\n.viz-controls {\\n display: flex;\\n flex-wrap: wrap;\\n align-items: center;\\n gap: 8px;\\n}\\n\\n.viz-controls > .form-label {\\n display: grid;\\n min-width: min(100%, 260px);\\n flex: 1 1 280px;\\n grid-template-columns: minmax(0, 1fr) auto;\\n align-items: baseline;\\n gap: 2px 12px;\\n margin-bottom: 0;\\n}\\n\\n.viz-controls > .form-label > :is(.form-control, .form-range, .form-select) {\\n grid-column: 1 / -1;\\n}\\n\\n.btn,\\n.nav-link,\\n.form-check-input,\\n.form-control,\\n.form-range,\\n.form-select {\\n font: inherit;\\n}\\n\\n.btn,\\n.nav-link {\\n appearance: button;\\n display: inline-flex;\\n inline-size: fit-content;\\n max-inline-size: 100%;\\n min-height: 28px;\\n align-items: center;\\n justify-content: center;\\n gap: 4px;\\n margin: 0;\\n padding: 0 8px;\\n -webkit-app-region: no-drag;\\n border: 1px solid var(--input);\\n border-radius: var(--radius-lg);\\n corner-shape: var(--corner-shape);\\n color: var(--secondary-foreground);\\n background: var(--secondary);\\n cursor: var(--cursor-interaction, pointer);\\n text-align: center;\\n text-decoration: none;\\n white-space: nowrap;\\n user-select: none;\\n -webkit-font-smoothing: antialiased;\\n}\\n\\n.btn:is(.btn-block, .viz-tile) {\\n inline-size: 100%;\\n}\\n\\n.btn.viz-tile {\\n min-width: 0;\\n overflow-wrap: anywhere;\\n white-space: normal;\\n}\\n\\na.btn {\\n cursor: pointer;\\n text-decoration: none;\\n}\\n\\n.btn:not(:disabled):hover,\\n.nav-link:not(:disabled):not([aria-disabled=\\\"true\\\"]):hover {\\n background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));\\n}\\n\\n.btn-primary {\\n border-color: transparent;\\n color: var(--primary-foreground);\\n background: var(--foreground);\\n background-clip: padding-box;\\n}\\n\\n.btn-primary .text-muted {\\n color: color-mix(in srgb, var(--primary-foreground) 50%, transparent);\\n}\\n\\n.btn-primary:not(:disabled):hover {\\n background: color-mix(in srgb, var(--foreground) 80%, transparent);\\n background-clip: padding-box;\\n}\\n\\n.btn-ghost {\\n border-color: transparent;\\n color: var(--muted-foreground);\\n background: transparent;\\n}\\n\\n.btn-ghost:not(:disabled):hover {\\n color: var(--foreground);\\n background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));\\n}\\n\\n.nav-pills .nav-link {\\n min-width: 0;\\n border-color: transparent;\\n color: var(--muted-foreground);\\n background: transparent;\\n}\\n\\n.nav-justified .nav-link {\\n flex: 1 1 0;\\n overflow-wrap: anywhere;\\n white-space: normal;\\n}\\n\\n.nav-pills .nav-link.active {\\n color: var(--foreground);\\n background: var(--muted);\\n}\\n\\n.btn:disabled,\\n.nav-link:disabled,\\n.nav-link[aria-disabled=\\\"true\\\"] {\\n cursor: not-allowed;\\n opacity: 0.4;\\n}\\n\\n[data-lucide] {\\n stroke-width: 1.6;\\n}\\n\\n.form-label {\\n display: block;\\n margin-bottom: 6px;\\n color: var(--foreground);\\n}\\n\\n.form-control {\\n display: block;\\n width: 100%;\\n min-height: 28px;\\n padding: 0 8px;\\n outline: none;\\n border: 1px solid var(--input);\\n border-radius: var(--radius-lg);\\n corner-shape: var(--corner-shape);\\n color: var(--foreground);\\n background: var(--secondary);\\n}\\n\\n.form-control::placeholder {\\n color: var(--muted-foreground);\\n}\\n\\n.form-control[type=\\\"file\\\"] {\\n padding: 0;\\n overflow: hidden;\\n cursor: var(--cursor-interaction, pointer);\\n}\\n\\n.form-control[type=\\\"file\\\"]::file-selector-button {\\n min-height: 26px;\\n margin-right: 8px;\\n padding: 0 8px;\\n border: 0;\\n border-right: 1px solid var(--input);\\n color: var(--secondary-foreground);\\n background: var(--secondary);\\n cursor: inherit;\\n font: inherit;\\n}\\n\\n.form-control[type=\\\"file\\\"]:not(:disabled):hover::file-selector-button {\\n background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));\\n}\\n\\n.form-control-color[type=\\\"color\\\"] {\\n width: 40px;\\n height: 28px;\\n padding: 3px;\\n cursor: var(--cursor-interaction, pointer);\\n}\\n\\n.form-control-color[type=\\\"color\\\"]::-webkit-color-swatch-wrapper {\\n padding: 0;\\n}\\n\\n.form-control-color[type=\\\"color\\\"]::-webkit-color-swatch {\\n border: 0;\\n border-radius: calc(var(--radius-lg) - 4px);\\n corner-shape: var(--corner-shape);\\n}\\n\\ntextarea.form-control {\\n height: auto;\\n min-height: 72px;\\n padding: 8px 10px;\\n resize: vertical;\\n}\\n\\n.form-control:focus-visible {\\n border-color: var(--ring);\\n box-shadow: inset 0 0 0 1px var(--ring);\\n}\\n\\n.form-control:disabled,\\n.form-select:disabled {\\n cursor: not-allowed;\\n opacity: 0.4;\\n}\\n\\n.form-select {\\n appearance: none;\\n display: block;\\n width: 100%;\\n min-height: 28px;\\n margin: 0;\\n padding: 0 32px 0 8px;\\n outline: none;\\n border: 1px solid var(--input);\\n border-radius: var(--radius-lg);\\n corner-shape: var(--corner-shape);\\n color: var(--foreground);\\n background-color: var(--secondary);\\n background-image:\\n linear-gradient(45deg, transparent 50%, var(--muted-foreground) 50%),\\n linear-gradient(135deg, var(--muted-foreground) 50%, transparent 50%);\\n background-position:\\n calc(100% - 14px) 50%,\\n calc(100% - 10px) 50%;\\n background-repeat: no-repeat;\\n background-size: 4px 4px;\\n cursor: var(--cursor-interaction, default);\\n}\\n\\n.form-select:not(:disabled):hover {\\n background-color: color-mix(in srgb, var(--foreground) 6%, var(--secondary));\\n}\\n\\n.form-select:focus-visible {\\n border-color: var(--ring);\\n box-shadow: inset 0 0 0 1px var(--ring);\\n}\\n\\n.form-check {\\n display: flex;\\n min-height: 20px;\\n align-items: center;\\n gap: 6px;\\n}\\n\\n.form-check-input {\\n appearance: none;\\n width: 14px;\\n height: 14px;\\n flex: 0 0 auto;\\n margin: 0;\\n border: 1px solid var(--input);\\n color: var(--primary-foreground);\\n background-color: transparent;\\n cursor: var(--cursor-interaction, default);\\n transition:\\n background-color 150ms,\\n border-color 150ms,\\n box-shadow 150ms;\\n}\\n\\n.form-check:not(.form-switch) .form-check-input[type=\\\"checkbox\\\"] {\\n border-color: var(--input);\\n border-radius: var(--radius-sm);\\n corner-shape: var(--corner-shape);\\n background-color: var(--secondary);\\n box-shadow: var(--shadow-sm);\\n}\\n\\n.form-check:not(.form-switch)\\n .form-check-input:not(:disabled):not(:checked):hover {\\n background-color: var(--card);\\n}\\n\\n.form-check:not(.form-switch) .form-check-input[type=\\\"checkbox\\\"]:checked {\\n border-color: var(--primary);\\n background-color: var(--primary);\\n}\\n\\n.form-check:not(.form-switch)\\n .form-check-input[type=\\\"checkbox\\\"]:checked::before {\\n display: block;\\n width: 100%;\\n height: 100%;\\n background: var(--primary-foreground);\\n content: \\\"\\\";\\n mask: var(--checkmark-image) center / 12px 12px no-repeat;\\n}\\n\\n.form-check-input[type=\\\"radio\\\"] {\\n width: 14px;\\n height: 14px;\\n border-radius: var(--radius-full);\\n}\\n\\n.form-check-input[type=\\\"radio\\\"]:checked {\\n border: 2px solid var(--primary);\\n background:\\n radial-gradient(circle, var(--primary-foreground) 0 2.5px, transparent 3px),\\n var(--primary);\\n}\\n\\n.form-check:not(.form-switch) .form-check-input:focus-visible {\\n outline: 2px solid var(--ring);\\n outline-offset: 2px;\\n}\\n\\n.form-check:not(.form-switch) .form-check-input:disabled {\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\n.form-check:not(.form-switch) .form-check-input:disabled + .form-check-label {\\n cursor: not-allowed;\\n}\\n\\n.form-switch .form-check-input:disabled,\\n.form-switch .form-check-input:disabled + .form-check-label {\\n cursor: not-allowed;\\n opacity: 0.6;\\n}\\n\\n.form-check-label {\\n color: var(--foreground);\\n cursor: var(--cursor-interaction, default);\\n}\\n\\n.form-switch .form-check-input {\\n position: relative;\\n width: 32px;\\n height: 20px;\\n border: 0;\\n border-radius: var(--radius-full);\\n background: var(--muted);\\n box-shadow: none;\\n transition: background-color 200ms cubic-bezier(0, 0, 0.2, 1);\\n}\\n\\n.form-switch .form-check-input::before {\\n position: absolute;\\n top: 50%;\\n left: 0;\\n width: 16px;\\n height: 16px;\\n box-sizing: border-box;\\n border: 1px solid light-dark(var(--primary-foreground), var(--foreground));\\n border-radius: var(--radius-full);\\n background: light-dark(var(--primary-foreground), var(--foreground));\\n box-shadow: var(--shadow-sm);\\n content: \\\"\\\";\\n transform: translate(2px, -50%);\\n transition: transform 200ms cubic-bezier(0, 0, 0.2, 1);\\n}\\n\\n.form-switch .form-check-input:checked {\\n background: var(--primary);\\n}\\n\\n.form-switch .form-check-input:checked::before {\\n transform: translate(14px, -50%);\\n}\\n\\n.form-switch .form-check-input:focus-visible {\\n box-shadow: 0 0 0 2px var(--ring);\\n}\\n\\n.form-range {\\n appearance: none;\\n display: block;\\n width: 100%;\\n height: 28px;\\n flex: 1;\\n margin: 0;\\n padding: 0;\\n outline: none;\\n border: 0;\\n accent-color: var(--primary);\\n background: linear-gradient(\\n color-mix(in srgb, var(--foreground) 7%, transparent),\\n color-mix(in srgb, var(--foreground) 7%, transparent)\\n )\\n center / 100% 2px no-repeat;\\n}\\n\\n.form-range::-webkit-slider-runnable-track {\\n height: 28px;\\n background: transparent;\\n}\\n\\n.form-range::-webkit-slider-thumb {\\n appearance: none;\\n width: 20px;\\n height: 20px;\\n margin-top: 4px;\\n border: 1px solid var(--border);\\n border-radius: var(--radius-full);\\n background: light-dark(var(--primary-foreground), var(--foreground));\\n}\\n\\n.form-range:focus-visible::-webkit-slider-thumb {\\n border-color: var(--ring);\\n box-shadow: inset 0 0 0 1px var(--ring);\\n}\\n\\n.form-range::-moz-range-track {\\n height: 28px;\\n background: transparent;\\n}\\n\\n.form-range::-moz-range-thumb {\\n width: 20px;\\n height: 20px;\\n border: 1px solid var(--border);\\n border-radius: var(--radius-full);\\n background: light-dark(var(--primary-foreground), var(--foreground));\\n}\\n\\n.form-range:focus-visible::-moz-range-thumb {\\n border-color: var(--ring);\\n box-shadow: inset 0 0 0 1px var(--ring);\\n}\\n\\n.form-range:disabled {\\n cursor: not-allowed;\\n opacity: 0.4;\\n}\\n\\n.btn:not(.btn-primary, .viz-tile):is(\\n [aria-pressed=\\\"true\\\"],\\n [aria-selected=\\\"true\\\"],\\n .is-selected\\n) {\\n border-color: var(--primary);\\n color: var(--primary-foreground);\\n background: var(--primary);\\n}\\n\\n.btn.viz-tile:is([aria-pressed=\\\"true\\\"], [aria-selected=\\\"true\\\"], .is-selected) {\\n border-color: var(--primary);\\n box-shadow: inset 0 0 0 1px var(--primary);\\n}\\n\\n.btn:focus-visible,\\n.nav-link:focus-visible {\\n outline: 2px solid var(--ring);\\n outline-offset: 2px;\\n}\\n\\n@media (pointer: coarse) {\\n .btn,\\n .nav-link,\\n .form-control,\\n .form-select {\\n min-width: 44px;\\n min-height: 44px;\\n }\\n\\n /* Keep small-screen WebKit from zooming when a text field receives focus. */\\n .form-control,\\n .form-select {\\n font-size: max(16px, var(--font-size-normal));\\n }\\n\\n .form-control[type=\\\"file\\\"]::file-selector-button {\\n min-width: 44px;\\n min-height: 44px;\\n }\\n\\n .form-control-color[type=\\\"color\\\"] {\\n width: 44px;\\n height: 44px;\\n }\\n\\n .form-control:is(\\n [type=\\\"date\\\"],\\n [type=\\\"datetime-local\\\"],\\n [type=\\\"month\\\"],\\n [type=\\\"time\\\"],\\n [type=\\\"week\\\"]\\n ) {\\n min-width: 0;\\n max-width: 100%;\\n padding-block: 8px;\\n }\\n\\n .form-check {\\n min-height: 44px;\\n padding-inline: 15px;\\n }\\n\\n .form-check-input {\\n position: relative;\\n }\\n\\n .form-check-input::after {\\n position: absolute;\\n top: 50%;\\n left: 50%;\\n width: 44px;\\n height: 44px;\\n content: \\\"\\\";\\n transform: translate(-50%, -50%);\\n }\\n\\n .form-check-label {\\n display: inline-flex;\\n min-width: 44px;\\n min-height: 44px;\\n align-items: center;\\n }\\n\\n .form-range {\\n height: 44px;\\n touch-action: pan-y;\\n }\\n\\n .form-range::-webkit-slider-runnable-track {\\n height: 44px;\\n }\\n\\n .form-range::-moz-range-track {\\n height: 44px;\\n }\\n\\n .form-range::-webkit-slider-thumb {\\n margin-top: 12px;\\n }\\n}\\n\\nsvg {\\n display: block;\\n max-width: 100%;\\n height: auto;\\n}\\n\\n#widget > svg {\\n width: 100%;\\n}\\n\\n/* Model-authored chart rules can otherwise stretch icons after these styles load. */\\nsvg.lucide {\\n display: block;\\n width: var(--icon-size) !important;\\n height: var(--icon-size) !important;\\n flex: none;\\n margin: 0 !important;\\n stroke-width: 1.6;\\n}\\n\\n.text-warning,\\n.text-destructive {\\n color: var(--destructive);\\n}\\n\";\nexport const VISUALIZATION_HELPERS = \"\\n<script src=\\\"https://unpkg.com/@floating-ui/core@1.7.3/dist/floating-ui.core.umd.min.js\\\"></script>\\n<script src=\\\"https://unpkg.com/@floating-ui/dom@1.7.4/dist/floating-ui.dom.umd.min.js\\\"></script>\\n<script>\\n (() => {\\n if (window.FloatingUIDOM == null) {\\n return;\\n }\\n const { autoUpdate, computePosition, flip, offset, shift, size } = window.FloatingUIDOM;\\n const tooltipPlacements = new Set([\\\"top\\\", \\\"right\\\", \\\"bottom\\\", \\\"left\\\"]);\\n const tooltipId = `codex-visualization-tooltip-${\\n window.crypto?.randomUUID?.() ?? Date.now().toString(36)\\n }`;\\n const tooltipGap = 5;\\n const hoverDelay = 700;\\n const skipDelay = 300;\\n let activeTrigger = null;\\n let pendingTrigger = null;\\n let tooltip = null;\\n let openTimeout = null;\\n let autoUpdateCleanup = null;\\n let positionRequest = 0;\\n let skipDelayUntil = 0;\\n let lastPointerWasTouch = false;\\n let pinnedByTouch = false;\\n\\n const getTrigger = (target) =>\\n target?.nodeType === Node.ELEMENT_NODE ? target.closest(\\\"[data-tooltip]\\\") : null;\\n const containsTarget = (trigger, target) =>\\n target?.nodeType != null && trigger.contains(target);\\n const getContent = (trigger) => trigger.getAttribute(\\\"data-tooltip\\\")?.trim() ?? \\\"\\\";\\n const getPlacement = (trigger) => {\\n const placement = trigger.getAttribute(\\\"data-tooltip-placement\\\");\\n return tooltipPlacements.has(placement) ? placement : \\\"top\\\";\\n };\\n const getTooltip = () => {\\n if (tooltip == null) {\\n tooltip = document.createElement(\\\"div\\\");\\n tooltip.id = tooltipId;\\n tooltip.className = \\\"tooltip\\\";\\n tooltip.setAttribute(\\\"role\\\", \\\"tooltip\\\");\\n }\\n return tooltip;\\n };\\n const setDescribedBy = (trigger, described) => {\\n const ids = new Set(\\n (trigger.getAttribute(\\\"aria-describedby\\\") ?? \\\"\\\").split(/\\\\s+/).filter(Boolean),\\n );\\n if (described) {\\n ids.add(tooltipId);\\n } else {\\n ids.delete(tooltipId);\\n }\\n if (ids.size === 0) {\\n trigger.removeAttribute(\\\"aria-describedby\\\");\\n } else {\\n trigger.setAttribute(\\\"aria-describedby\\\", [...ids].join(\\\" \\\"));\\n }\\n };\\n const clearOpenTimeout = () => {\\n if (openTimeout != null) {\\n window.clearTimeout(openTimeout);\\n openTimeout = null;\\n }\\n pendingTrigger = null;\\n };\\n const closeTooltip = (activateSkipDelay = true) => {\\n clearOpenTimeout();\\n pinnedByTouch = false;\\n positionRequest += 1;\\n autoUpdateCleanup?.();\\n autoUpdateCleanup = null;\\n if (activeTrigger == null) {\\n return;\\n }\\n setDescribedBy(activeTrigger, false);\\n activeTrigger = null;\\n tooltip?.remove();\\n if (activateSkipDelay) {\\n skipDelayUntil = Date.now() + skipDelay;\\n }\\n };\\n const updatePosition = (trigger, floating) => {\\n const request = ++positionRequest;\\n void computePosition(trigger, floating, {\\n middleware: [\\n offset(tooltipGap),\\n flip({ padding: tooltipGap }),\\n shift({ padding: tooltipGap }),\\n size({\\n padding: tooltipGap,\\n apply({ availableHeight, availableWidth, elements }) {\\n elements.floating.style.setProperty(\\n \\\"--tooltip-available-width\\\",\\n `${Math.max(0, availableWidth)}px`,\\n );\\n elements.floating.style.setProperty(\\n \\\"--tooltip-available-height\\\",\\n `${Math.max(0, availableHeight)}px`,\\n );\\n },\\n }),\\n ],\\n placement: getPlacement(trigger),\\n strategy: \\\"fixed\\\",\\n })\\n .then(({ x, y }) => {\\n if (activeTrigger !== trigger || request !== positionRequest) {\\n return;\\n }\\n const scale = window.devicePixelRatio || 1;\\n floating.style.transform = `translate(${Math.round(x * scale) / scale}px, ${Math.round(y * scale) / scale}px)`;\\n floating.style.visibility = \\\"visible\\\";\\n })\\n .catch(() => {\\n if (activeTrigger === trigger && request === positionRequest) {\\n closeTooltip(false);\\n }\\n });\\n };\\n const openTooltip = (trigger) => {\\n const content = getContent(trigger);\\n if (!trigger.isConnected || content.length === 0) {\\n return;\\n }\\n clearOpenTimeout();\\n if (activeTrigger === trigger) {\\n return;\\n }\\n closeTooltip();\\n const floating = getTooltip();\\n floating.textContent = content;\\n floating.style.visibility = \\\"hidden\\\";\\n floating.style.transform = \\\"translate(0, 0)\\\";\\n document.body.appendChild(floating);\\n activeTrigger = trigger;\\n setDescribedBy(trigger, true);\\n autoUpdateCleanup = autoUpdate(trigger, floating, () => {\\n updatePosition(trigger, floating);\\n });\\n };\\n const requestOpen = (trigger, immediate = false) => {\\n if (\\n getContent(trigger).length === 0 ||\\n activeTrigger === trigger ||\\n pendingTrigger === trigger\\n ) {\\n return;\\n }\\n clearOpenTimeout();\\n pendingTrigger = trigger;\\n const delay =\\n immediate || activeTrigger != null || Date.now() < skipDelayUntil ? 0 : hoverDelay;\\n if (delay === 0) {\\n openTooltip(trigger);\\n return;\\n }\\n openTimeout = window.setTimeout(() => {\\n openTimeout = null;\\n pendingTrigger = null;\\n openTooltip(trigger);\\n }, delay);\\n };\\n const handlePointerOpen = (event) => {\\n if (event.pointerType === \\\"touch\\\") {\\n return;\\n }\\n const trigger = getTrigger(event.target);\\n if (trigger == null || containsTarget(trigger, event.relatedTarget)) {\\n return;\\n }\\n requestOpen(trigger);\\n };\\n const handlePointer = (event) => {\\n lastPointerWasTouch = event.type === \\\"pointerdown\\\" && event.pointerType === \\\"touch\\\";\\n };\\n const handleTouchClick = (event) => {\\n const isTouch = event.pointerType === \\\"touch\\\" || lastPointerWasTouch;\\n lastPointerWasTouch = false;\\n if (!isTouch || event.detail === 0) {\\n return;\\n }\\n const trigger = getTrigger(event.target);\\n if (\\n trigger == null ||\\n !trigger.isConnected ||\\n getContent(trigger).length === 0 ||\\n (pinnedByTouch && activeTrigger === trigger)\\n ) {\\n if (pinnedByTouch) {\\n closeTooltip();\\n }\\n return;\\n }\\n openTooltip(trigger);\\n pinnedByTouch = activeTrigger === trigger;\\n window.setTimeout(() => {\\n if (activeTrigger === trigger && !trigger.isConnected) {\\n closeTooltip(false);\\n }\\n }, 0);\\n };\\n const handleLeave = (event) => {\\n if (pinnedByTouch) {\\n return;\\n }\\n const trigger = getTrigger(event.target);\\n if (trigger == null || containsTarget(trigger, event.relatedTarget)) {\\n return;\\n }\\n if (activeTrigger === trigger || pendingTrigger === trigger) {\\n closeTooltip();\\n }\\n };\\n const handleFocusIn = (event) => {\\n const trigger = getTrigger(event.target);\\n if (trigger?.matches(\\\":focus-visible\\\")) {\\n requestOpen(trigger, true);\\n }\\n };\\n const handleKeyDown = (event) => {\\n if (event.key === \\\"Escape\\\") {\\n closeTooltip();\\n }\\n };\\n const handleContextMenu = (event) => {\\n lastPointerWasTouch = false;\\n const trigger = getTrigger(event.target);\\n if (activeTrigger === trigger || pendingTrigger === trigger) {\\n closeTooltip();\\n }\\n };\\n const destroy = () => {\\n closeTooltip(false);\\n lastPointerWasTouch = false;\\n document.removeEventListener(\\\"pointerover\\\", handlePointerOpen);\\n document.removeEventListener(\\\"pointerdown\\\", handlePointer);\\n document.removeEventListener(\\\"pointercancel\\\", handlePointer);\\n document.removeEventListener(\\\"click\\\", handleTouchClick);\\n document.removeEventListener(\\\"pointerout\\\", handleLeave);\\n document.removeEventListener(\\\"focusin\\\", handleFocusIn);\\n document.removeEventListener(\\\"focusout\\\", handleLeave);\\n document.removeEventListener(\\\"keydown\\\", handleKeyDown);\\n document.removeEventListener(\\\"contextmenu\\\", handleContextMenu);\\n tooltip = null;\\n };\\n\\n document.addEventListener(\\\"pointerover\\\", handlePointerOpen);\\n document.addEventListener(\\\"pointerdown\\\", handlePointer);\\n document.addEventListener(\\\"pointercancel\\\", handlePointer);\\n document.addEventListener(\\\"click\\\", handleTouchClick);\\n document.addEventListener(\\\"pointerout\\\", handleLeave);\\n document.addEventListener(\\\"focusin\\\", handleFocusIn);\\n document.addEventListener(\\\"focusout\\\", handleLeave);\\n document.addEventListener(\\\"keydown\\\", handleKeyDown);\\n document.addEventListener(\\\"contextmenu\\\", handleContextMenu);\\n window.addEventListener(\\\"pagehide\\\", destroy, { once: true });\\n })();\\n</script>\\n<script id=\\\"codex-visualization-tabs\\\">\\n (() => {\\n const selector = '.nav[role=\\\"tablist\\\"] [role=\\\"tab\\\"]';\\n const disabled = ':disabled,[aria-disabled=\\\"true\\\"]';\\n const selectTab = (selected) => {\\n const panelId = selected.getAttribute(\\\"aria-controls\\\");\\n for (const tab of selected.closest('[role=\\\"tablist\\\"]').querySelectorAll('[role=\\\"tab\\\"]')) {\\n const active = tab === selected;\\n tab.classList.toggle(\\\"active\\\", active);\\n tab.setAttribute(\\\"aria-selected\\\", String(active));\\n const id = tab.getAttribute(\\\"aria-controls\\\");\\n const panel = id && document.getElementById(id);\\n if (panel != null) {\\n panel.hidden = id !== panelId;\\n if (!panel.hidden && selected.id) {\\n panel.setAttribute(\\\"aria-labelledby\\\", selected.id);\\n }\\n }\\n }\\n };\\n const interact = (event) => {\\n const tab = event.target?.closest?.(selector);\\n if (event.defaultPrevented || tab == null || tab.matches(disabled)) {\\n return;\\n }\\n if (event.type === \\\"click\\\") {\\n selectTab(tab);\\n return;\\n }\\n const tabs = Array.from(\\n tab.closest('[role=\\\"tablist\\\"]').querySelectorAll('[role=\\\"tab\\\"]'),\\n ).filter((candidate) => !candidate.matches(disabled));\\n const current = tabs.indexOf(tab);\\n let next;\\n if (event.key === \\\"ArrowRight\\\" || event.key === \\\"ArrowDown\\\") {\\n next = (current + 1) % tabs.length;\\n } else if (event.key === \\\"ArrowLeft\\\" || event.key === \\\"ArrowUp\\\") {\\n next = (current + tabs.length - 1) % tabs.length;\\n } else if (event.key === \\\"Home\\\") {\\n next = 0;\\n } else if (event.key === \\\"End\\\") {\\n next = tabs.length - 1;\\n } else {\\n return;\\n }\\n event.preventDefault();\\n tabs[next].focus();\\n selectTab(tabs[next]);\\n };\\n\\n for (const list of document.querySelectorAll('.nav[role=\\\"tablist\\\"]')) {\\n const selected =\\n list.querySelector('[role=\\\"tab\\\"][aria-selected=\\\"true\\\"]') ??\\n list.querySelector('[role=\\\"tab\\\"].active') ??\\n list.querySelector('[role=\\\"tab\\\"]');\\n if (selected != null) {\\n selectTab(selected);\\n }\\n }\\n document.addEventListener(\\\"click\\\", interact);\\n document.addEventListener(\\\"keydown\\\", interact);\\n window.addEventListener(\\n \\\"pagehide\\\",\\n () => {\\n document.removeEventListener(\\\"click\\\", interact);\\n document.removeEventListener(\\\"keydown\\\", interact);\\n },\\n { once: true },\\n );\\n })();\\n</script>\\n<script\\n id=\\\"codex-visualization-lucide\\\"\\n async\\n src=\\\"https://unpkg.com/lucide@1.17.0/dist/umd/lucide.js\\\"\\n></script>\\n<script>\\n (() => {\\n const initialize = () => {\\n globalThis.lucide?.createIcons({ attrs: { width: 16, height: 16 } });\\n };\\n if (globalThis.lucide != null) {\\n initialize();\\n return;\\n }\\n document\\n .getElementById(\\\"codex-visualization-lucide\\\")\\n ?.addEventListener(\\\"load\\\", initialize, { once: true });\\n })();\\n</script>\\n\";\n","import { VISUALIZATION_CSS, VISUALIZATION_HELPERS } from \"./visualization-assets.gen\";\n\n/** Conversation styling/helpers only. Rendering and tool transport remain in the Site frame. */\nexport function inlineHtmlDocument(fragment: string): string {\n return (\n '<!doctype html><html><head><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><style>' +\n VISUALIZATION_CSS +\n \"</style><style>html,body{margin:0;min-height:0}body{padding:16px;box-sizing:border-box}</style></head><body>\" +\n fragment +\n VISUALIZATION_HELPERS +\n `<script>\n(()=>{\n window.addEventListener('message',event=>{\n if(event.source!==parent||event.data?.type!=='opengeni.preview.theme')return;\n if(event.data.theme==='light'||event.data.theme==='dark')document.documentElement.style.colorScheme=event.data.theme;\n previous=0;resize();\n });\n let previous=0;\n const resize=()=>{const height=Math.ceil(document.body.getBoundingClientRect().height);if(height!==previous){previous=height;parent.postMessage({type:'opengeni.preview.height',height},'*')}};\n new ResizeObserver(resize).observe(document.body);resize();\n})();\n</script></body></html>`\n );\n}\n","import {\n createBrowserEditableArtifactSession,\n type CreateBrowserEditableArtifactSessionOptions,\n type EditableArtifactBrowserRuntime,\n type EditableArtifactSession,\n} from \"@opengeni/sdk/editable-artifacts\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { EditableArtifactMessage } from \"./editable-artifact-ui\";\nimport {\n EditableDocumentArtifactSurface,\n type EditableDocumentArtifactSurfaceProps,\n} from \"./editable-document\";\nimport {\n EditablePresentationArtifactSurface,\n type EditablePresentationArtifactSurfaceProps,\n} from \"./editable-presentation\";\nimport {\n EditableSpreadsheetArtifactSurface,\n type EditableSpreadsheetArtifactSurfaceProps,\n} from \"./editable-spreadsheet\";\n\nexport type EditableArtifactWorkbenchProps = Readonly<{\n session: EditableArtifactSession;\n document?: Omit<EditableDocumentArtifactSurfaceProps, \"session\">;\n spreadsheet?: Omit<EditableSpreadsheetArtifactSurfaceProps, \"session\">;\n presentation?: Omit<EditablePresentationArtifactSurfaceProps, \"session\">;\n}>;\n\nexport type EditableArtifactWorkbenchHostProps = Omit<EditableArtifactWorkbenchProps, \"session\"> &\n Readonly<{\n /**\n * Complete identity of the browser session authority. Change this when the\n * artifact, deployment, principal, or authorization epoch changes.\n */\n sessionKey: string;\n /** Called for the active keyed lifecycle and again only after replacement or retry. */\n createSession: () => EditableArtifactSession;\n }>;\n\ntype DefaultBrowserArtifactTransport = Omit<\n NonNullable<CreateBrowserEditableArtifactSessionOptions[\"transport\"]>,\n \"apiKey\" | \"fetch\" | \"headers\" | \"webSocketFactory\"\n> &\n Readonly<{\n /** Static deployment auth headers; rotate authorizationEpoch when they change. */\n headers?: Readonly<Record<string, string>>;\n }>;\n\nexport type BrowserEditableArtifactWorkbenchOptions = Omit<\n CreateBrowserEditableArtifactSessionOptions,\n \"runtime\" | \"storage\" | \"transport\"\n> &\n Readonly<{\n /** Default module Worker only; custom Worker hosts use EditableArtifactWorkbenchHost. */\n runtime: Omit<EditableArtifactBrowserRuntime, \"workerFactory\">;\n /** Default fetch/WebSocket only; static deployment auth headers are supported. */\n transport?: DefaultBrowserArtifactTransport;\n }>;\n\nexport type BrowserEditableArtifactWorkbenchProps = Omit<\n EditableArtifactWorkbenchProps,\n \"session\"\n> &\n Readonly<{ options: BrowserEditableArtifactWorkbenchOptions }>;\n\n/**\n * One modality-neutral SDK workbench. Embedding hosts keep one route/component;\n * each artifact still renders through its complete first-party editor surface.\n */\nexport function EditableArtifactWorkbench({\n session,\n document,\n spreadsheet,\n presentation,\n}: EditableArtifactWorkbenchProps) {\n switch (session.modality) {\n case \"document\":\n return (\n <EditableDocumentArtifactSurface\n {...document}\n session={session}\n title={document?.title ?? \"Document\"}\n />\n );\n case \"spreadsheet\":\n return <EditableSpreadsheetArtifactSurface {...spreadsheet} session={session} />;\n case \"presentation\":\n return <EditablePresentationArtifactSurface {...presentation} session={session} />;\n }\n}\n\n/**\n * Route/embed composition that owns exactly one SDK session. The host supplies\n * the authenticated SDK factory; React guarantees replacement and teardown.\n */\nexport function EditableArtifactWorkbenchHost({\n sessionKey,\n createSession,\n document,\n spreadsheet,\n presentation,\n}: EditableArtifactWorkbenchHostProps) {\n const createSessionRef = useRef(createSession);\n const [retryEpoch, setRetryEpoch] = useState(0);\n const [state, setState] = useState<\n | Readonly<{ key: string; session: EditableArtifactSession; error: null }>\n | Readonly<{ key: string | null; session: null; error: Error | null }>\n >({ key: null, session: null, error: null });\n\n useEffect(() => {\n createSessionRef.current = createSession;\n }, [createSession]);\n\n useEffect(() => {\n let owned: EditableArtifactSession | null = null;\n setState({ key: sessionKey, session: null, error: null });\n try {\n owned = createSessionRef.current();\n setState({ key: sessionKey, session: owned, error: null });\n } catch (cause) {\n setState({\n key: sessionKey,\n session: null,\n error: cause instanceof Error ? cause : new Error(\"Could not create artifact session\"),\n });\n }\n return () => {\n const closing = owned;\n owned = null;\n if (closing) void closing.close().catch(() => undefined);\n };\n }, [retryEpoch, sessionKey]);\n\n const retry = useCallback(() => setRetryEpoch((value) => value + 1), []);\n const currentError = state.key === sessionKey ? state.error : null;\n if (state.key === sessionKey && state.session) {\n return (\n <EditableArtifactWorkbench\n session={state.session}\n {...(document ? { document } : {})}\n {...(spreadsheet ? { spreadsheet } : {})}\n {...(presentation ? { presentation } : {})}\n />\n );\n }\n return (\n <EditableArtifactMessage\n title={currentError ? \"Could not open this artifact\" : \"Opening artifact\"}\n detail={currentError?.message ?? \"Starting the secure editing session…\"}\n retry={currentError ? retry : undefined}\n />\n );\n}\n\n/**\n * Complete default-browser composition for embedders: verified WASM Worker,\n * durable IndexedDB state, authenticated live sync, teardown, and the matching\n * first-party editor. Advanced/custom transports compose the lower-level host.\n */\nexport function BrowserEditableArtifactWorkbench({\n options,\n document,\n spreadsheet,\n presentation,\n}: BrowserEditableArtifactWorkbenchProps) {\n const sessionKey = browserSessionKey(options);\n const createSession = useCallback(() => createBrowserEditableArtifactSession(options), [options]);\n return (\n <EditableArtifactWorkbenchHost\n sessionKey={sessionKey}\n createSession={createSession}\n {...(document ? { document } : {})}\n {...(spreadsheet ? { spreadsheet } : {})}\n {...(presentation ? { presentation } : {})}\n />\n );\n}\n\nfunction browserSessionKey(options: BrowserEditableArtifactWorkbenchOptions): string {\n const transport = options.transport\n ? {\n ...options.transport,\n // Credentials must not be copied into React lifecycle keys. The\n // authorization epoch is the explicit credential/grant rotation fence.\n headers: options.transport.headers\n ? Object.keys(options.transport.headers).sort()\n : undefined,\n }\n : null;\n return JSON.stringify(\n {\n baseUrl: options.baseUrl,\n workspaceId: options.workspaceId,\n artifact: { id: options.artifact.id, modality: options.artifact.modality },\n storageAuthority: options.storageAuthority,\n runtime: options.runtime,\n replicaId: options.replicaId ?? null,\n transport,\n },\n (_key, value: unknown) => (value instanceof URL ? value.href : value),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACO,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAC1B,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACC9B,SAAS,mBAAmB,UAA0B;AAC3D,SACE,0GACA,oBACA,iHACA,WACA,wBACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaJ;;;ACvBA;AAAA,EACE;AAAA,OAIK;AACP,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AAyEjD;AATD,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmC;AACjC,UAAQ,QAAQ,UAAU;AAAA,IACxB,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACE,GAAG;AAAA,UACJ;AAAA,UACA,OAAO,UAAU,SAAS;AAAA;AAAA,MAC5B;AAAA,IAEJ,KAAK;AACH,aAAO,oBAAC,sCAAoC,GAAG,aAAa,SAAkB;AAAA,IAChF,KAAK;AACH,aAAO,oBAAC,uCAAqC,GAAG,cAAc,SAAkB;AAAA,EACpF;AACF;AAMO,SAAS,8BAA8B;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuC;AACrC,QAAM,mBAAmB,OAAO,aAAa;AAC7C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,CAAC;AAC9C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAGxB,EAAE,KAAK,MAAM,SAAS,MAAM,OAAO,KAAK,CAAC;AAE3C,YAAU,MAAM;AACd,qBAAiB,UAAU;AAAA,EAC7B,GAAG,CAAC,aAAa,CAAC;AAElB,YAAU,MAAM;AACd,QAAI,QAAwC;AAC5C,aAAS,EAAE,KAAK,YAAY,SAAS,MAAM,OAAO,KAAK,CAAC;AACxD,QAAI;AACF,cAAQ,iBAAiB,QAAQ;AACjC,eAAS,EAAE,KAAK,YAAY,SAAS,OAAO,OAAO,KAAK,CAAC;AAAA,IAC3D,SAAS,OAAO;AACd,eAAS;AAAA,QACP,KAAK;AAAA,QACL,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,mCAAmC;AAAA,MACvF,CAAC;AAAA,IACH;AACA,WAAO,MAAM;AACX,YAAM,UAAU;AAChB,cAAQ;AACR,UAAI,QAAS,MAAK,QAAQ,MAAM,EAAE,MAAM,MAAM,MAAS;AAAA,IACzD;AAAA,EACF,GAAG,CAAC,YAAY,UAAU,CAAC;AAE3B,QAAM,QAAQ,YAAY,MAAM,cAAc,CAAC,UAAU,QAAQ,CAAC,GAAG,CAAC,CAAC;AACvE,QAAM,eAAe,MAAM,QAAQ,aAAa,MAAM,QAAQ;AAC9D,MAAI,MAAM,QAAQ,cAAc,MAAM,SAAS;AAC7C,WACE;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,MAAM;AAAA,QACd,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,QAC/B,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,QACrC,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA;AAAA,IAC1C;AAAA,EAEJ;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,eAAe,iCAAiC;AAAA,MACvD,QAAQ,cAAc,WAAW;AAAA,MACjC,OAAO,eAAe,QAAQ;AAAA;AAAA,EAChC;AAEJ;AAOO,SAAS,iCAAiC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0C;AACxC,QAAM,aAAa,kBAAkB,OAAO;AAC5C,QAAM,gBAAgB,YAAY,MAAM,qCAAqC,OAAO,GAAG,CAAC,OAAO,CAAC;AAChG,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACC,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,MAC/B,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,MACrC,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA;AAAA,EAC1C;AAEJ;AAEA,SAAS,kBAAkB,SAA0D;AACnF,QAAM,YAAY,QAAQ,YACtB;AAAA,IACE,GAAG,QAAQ;AAAA;AAAA;AAAA,IAGX,SAAS,QAAQ,UAAU,UACvB,OAAO,KAAK,QAAQ,UAAU,OAAO,EAAE,KAAK,IAC5C;AAAA,EACN,IACA;AACJ,SAAO,KAAK;AAAA,IACV;AAAA,MACE,SAAS,QAAQ;AAAA,MACjB,aAAa,QAAQ;AAAA,MACrB,UAAU,EAAE,IAAI,QAAQ,SAAS,IAAI,UAAU,QAAQ,SAAS,SAAS;AAAA,MACzE,kBAAkB,QAAQ;AAAA,MAC1B,SAAS,QAAQ;AAAA,MACjB,WAAW,QAAQ,aAAa;AAAA,MAChC;AAAA,IACF;AAAA,IACA,CAAC,MAAM,UAAoB,iBAAiB,MAAM,MAAM,OAAO;AAAA,EACjE;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/components/artifacts/visualization-assets.gen.ts","../src/components/artifacts/inline-html-document.ts","../src/components/artifacts/editable-artifact-workbench.tsx"],"sourcesContent":["// Generated by scripts/generate-visualization-assets.ts.\nexport const VISUALIZATION_CSS = \"/* Adapted from Codex visualize 1.0.32; shared with the OpenGeni visualization skill. */\\n:root {\\n color-scheme: light dark;\\n background-color: var(\\n --background,\\n var(--color-background-primary, light-dark(rgb(255 255 255), rgb(24 24 24)))\\n ) !important;\\n\\n /* Agent-facing contract; keep in sync with SKILL.md. */\\n --background: var(\\n --color-background-primary,\\n light-dark(rgb(255 255 255), rgb(24 24 24))\\n );\\n --foreground: var(\\n --color-text-primary,\\n light-dark(rgb(26 28 31), rgb(255 255 255))\\n );\\n --card: color-mix(in oklab, var(--foreground) 5%, var(--background));\\n --card-foreground: var(\\n --color-text-primary,\\n light-dark(rgb(26 28 31), rgb(255 255 255))\\n );\\n --popover: var(\\n --color-background-secondary,\\n light-dark(rgb(255 255 255), rgb(45 45 45))\\n );\\n --popover-foreground: var(\\n --color-text-primary,\\n light-dark(rgb(26 28 31), rgb(255 255 255))\\n );\\n --primary: var(\\n --color-text-info,\\n light-dark(rgb(51 156 255), rgb(131 195 255))\\n );\\n --primary-foreground: var(\\n --color-text-inverse,\\n light-dark(rgb(255 255 255), rgb(13 13 13))\\n );\\n --secondary: var(\\n --color-background-secondary,\\n light-dark(rgb(255 255 255 / 96%), rgb(54 54 54 / 96%))\\n );\\n --secondary-foreground: var(\\n --color-text-primary,\\n light-dark(rgb(26 28 31), rgb(255 255 255))\\n );\\n --muted: color-mix(in srgb, var(--foreground) 10%, transparent);\\n --muted-foreground: var(\\n --color-text-secondary,\\n light-dark(rgb(26 28 31 / 49.4%), rgb(255 255 255 / 49.8%))\\n );\\n --accent: var(\\n --color-background-info,\\n light-dark(rgb(229 242 255), rgb(13 39 63))\\n );\\n --accent-foreground: var(\\n --color-text-info,\\n light-dark(rgb(51 156 255), rgb(131 195 255))\\n );\\n --destructive: var(\\n --color-text-warning,\\n light-dark(rgb(226 85 7), rgb(255 133 73))\\n );\\n --border: var(\\n --color-border-secondary,\\n light-dark(rgb(26 28 31 / 8%), rgb(255 255 255 / 8.2%))\\n );\\n --input: var(\\n --color-border-primary,\\n light-dark(\\n rgb(26 28 31 / 11.8%),\\n color-mix(in oklab, rgb(0 0 0) 10%, transparent)\\n )\\n );\\n --ring: var(\\n --color-ring-primary,\\n light-dark(rgb(51 156 255), rgb(131 195 255 / 76%))\\n );\\n --font-size-base: var(--font-text-md-size, 14px);\\n --blue: light-dark(rgb(51 156 255), rgb(51 156 255));\\n --orange: light-dark(rgb(226 85 7), rgb(251 106 34));\\n --green: light-dark(rgb(0 162 64), rgb(64 201 119));\\n --red: light-dark(rgb(224 46 42), rgb(255 103 100));\\n --purple: light-dark(rgb(146 79 247), rgb(173 123 249));\\n --yellow: light-dark(rgb(255 195 0), rgb(255 210 64));\\n --viz-series-1: var(--primary);\\n --viz-series-2: light-dark(rgb(243 136 59), rgb(245 154 86));\\n --viz-series-3: light-dark(rgb(93 201 119), rgb(116 213 139));\\n --viz-series-4: light-dark(rgb(235 119 177), rgb(240 143 192));\\n --viz-series-5: light-dark(rgb(155 121 236), rgb(170 145 239));\\n --viz-series-6: light-dark(rgb(58 185 177), rgb(90 203 194));\\n\\n /* Internal implementation variables; not part of the agent contract. */\\n --font-sans: -apple-system, system-ui, \\\"Segoe UI\\\", sans-serif;\\n --font-mono:\\n ui-monospace, SFMono-Regular, \\\"SF Mono\\\", Menlo, Consolas, \\\"Liberation Mono\\\",\\n monospace;\\n --font-size-normal: max(11px, var(--font-size-base));\\n --font-size-tooltip: calc(var(--font-size-base) - 1px);\\n --font-size-small: max(11px, calc(var(--font-size-base) - 2px));\\n --font-size-h1: calc(var(--font-size-normal) * 1.7142857143);\\n --font-size-h2: calc(var(--font-size-normal) * 1.4285714286);\\n --font-size-h3: calc(var(--font-size-normal) * 1.2857142857);\\n --font-weight-normal: 430;\\n --font-weight-medium: 500;\\n --icon-size: 16px;\\n --line-height-normal: calc(var(--font-size-normal) * 1.5);\\n --line-height-tooltip: calc(var(--font-size-tooltip) * 1.4285714286);\\n --line-height-small: calc(var(--font-size-small) + 4px);\\n --corner-shape: round;\\n --radius: var(--border-radius-lg, 10px);\\n --radius-sm: calc(var(--radius) * 0.6);\\n --radius-md: calc(var(--radius) * 0.8);\\n --radius-lg: var(--radius);\\n --radius-2xl: calc(var(--radius) * 1.6);\\n --radius-full: 9999px;\\n --shadow-sm: 0 1px 2px -1px rgb(0 0 0 / 8%);\\n --checkmark-image: url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 17 17'%3E%3Cpath d='M 12.8961 3.64101C13.1297 3.41418 13.4984 3.37523 13.7779 3.56581C14.0571 3.75635 14.1554 4.11331 14.0299 4.41347L13.9615 4.53847L7.71151 13.7045C7.59411 13.8767 7.4063 13.9877 7.19881 14.0072C6.99136 14.0267 6.78564 13.9533 6.63826 13.806L2.88826 10.056L2.79842 9.9457C2.6192 9.67407 2.64927 9.30496 2.88826 9.06581C3.12738 8.82669 3.49647 8.79676 3.76815 8.97597L3.8785 9.06581L7.03084 12.2182L12.8053 3.74941L12.8961 3.64101Z'/%3E%3C/svg%3E\\\");\\n\\n /* Legacy aliases; not part of the current agent contract. */\\n --viz-bg: transparent;\\n --viz-panel: var(--card);\\n --viz-border: var(--border);\\n --viz-text: var(--foreground);\\n --viz-muted: var(--muted-foreground);\\n --viz-accent: var(--primary);\\n --viz-accent-text: var(--primary-foreground);\\n --viz-accent-bg: var(--accent);\\n --viz-font-size: var(--font-size-base);\\n --viz-warning: var(--destructive);\\n}\\n\\n:root[data-theme=\\\"light\\\"] {\\n color-scheme: light;\\n}\\n\\n:root[data-theme=\\\"dark\\\"] {\\n color-scheme: dark;\\n}\\n\\n* {\\n box-sizing: border-box;\\n}\\n\\nhtml > body {\\n /* Preserve MCP aliases for older inline renderers without creating :root cycles. */\\n --color-background-primary: var(\\n --background,\\n light-dark(rgb(255 255 255), rgb(24 24 24))\\n );\\n --color-text-primary: var(\\n --foreground,\\n light-dark(rgb(26 28 31), rgb(255 255 255))\\n );\\n --color-border-secondary: var(\\n --border,\\n light-dark(rgb(26 28 31 / 8%), rgb(255 255 255 / 8.2%))\\n );\\n\\n margin: 0;\\n padding: var(--visualize-paint-gutter, 16px);\\n color: var(--foreground);\\n background: transparent !important;\\n font-family: var(--font-sans) !important;\\n font-size: var(--font-size-normal);\\n font-weight: var(--font-weight-normal);\\n line-height: var(--line-height-normal);\\n}\\n\\na {\\n color: color-mix(in srgb, var(--viz-accent) 80%, var(--viz-text) 20%);\\n cursor: pointer;\\n font-weight: var(--font-weight-medium, 500);\\n text-decoration: none;\\n text-underline-offset: 2px;\\n}\\n\\na:is(:hover, :focus-visible) {\\n text-decoration-line: underline;\\n text-decoration-style: dashed;\\n text-decoration-thickness: 0.5px;\\n}\\n\\nh1,\\nh2,\\nh3,\\nh4,\\nh5,\\nh6,\\np {\\n margin-block: 0;\\n}\\n\\nh1 {\\n font-size: var(--font-size-h1);\\n font-weight: var(--font-weight-medium);\\n line-height: 1.25;\\n}\\n\\nh2 {\\n font-size: var(--font-size-h2);\\n font-weight: var(--font-weight-medium);\\n line-height: 1.25;\\n}\\n\\nh3,\\nh4,\\nh5,\\nh6 {\\n font-size: var(--font-size-h3);\\n font-weight: var(--font-weight-medium);\\n line-height: 1.3;\\n}\\n\\nb,\\nstrong,\\nth {\\n font-weight: var(--font-weight-medium);\\n}\\n\\ncode:not(pre code) {\\n display: inline;\\n padding: 1px 6px;\\n border-radius: var(--radius-sm);\\n corner-shape: var(--corner-shape);\\n background: var(--muted);\\n font-family: var(--font-mono);\\n font-size: 0.92em;\\n overflow-wrap: anywhere;\\n -webkit-box-decoration-break: clone;\\n box-decoration-break: clone;\\n word-break: break-word;\\n}\\n\\n.table-responsive {\\n width: 100%;\\n overflow-x: auto;\\n scrollbar-width: thin;\\n}\\n\\n.table {\\n width: 100%;\\n border-collapse: collapse;\\n color: var(--foreground);\\n font: inherit;\\n text-align: start;\\n}\\n\\n.table :is(th, td) {\\n padding-block: 10px;\\n padding-inline: 0 24px;\\n overflow-wrap: anywhere;\\n border-bottom: 1px solid var(--border);\\n text-align: start;\\n vertical-align: top;\\n}\\n\\n.table-responsive > .table :is(th, td) {\\n overflow-wrap: break-word;\\n}\\n\\n.table :is(th, td):last-child {\\n padding-inline-end: 0;\\n}\\n\\n.table :is(caption, thead th) {\\n font-weight: 600;\\n}\\n\\n.table thead th {\\n padding-block: 8px;\\n border-bottom-color: color-mix(in srgb, var(--foreground) 16%, transparent);\\n}\\n\\n.table tbody tr:last-child :is(th, td) {\\n border-bottom: 0;\\n}\\n\\n.table.table-sm :is(th, td) {\\n padding-block: 6px;\\n}\\n\\n.table.table-sm :is(th, td):not(:last-child) {\\n padding-inline-end: 16px;\\n}\\n\\n.table :is(.text-end, [align=\\\"right\\\"]) {\\n text-align: end;\\n font-variant-numeric: tabular-nums;\\n}\\n\\n.table :is(.text-center, [align=\\\"center\\\"]) {\\n text-align: center;\\n}\\n\\n.table .text-nowrap {\\n white-space: nowrap;\\n}\\n\\n#widget {\\n display: flex;\\n flex-direction: column;\\n gap: 12px;\\n width: 100%;\\n padding: 0;\\n background: transparent !important;\\n}\\n\\n.card {\\n min-width: 0;\\n padding: 12px;\\n overflow: hidden;\\n overflow-wrap: break-word;\\n border-radius: var(--radius-2xl);\\n corner-shape: var(--corner-shape);\\n color: var(--card-foreground);\\n background: var(--card);\\n}\\n\\n#widget > :not(.card, .progress) {\\n width: 100% !important;\\n max-width: none !important;\\n margin: 0 !important;\\n padding: 0 !important;\\n border: 0 !important;\\n border-radius: 0 !important;\\n background: transparent !important;\\n box-shadow: none !important;\\n}\\n\\n.tooltip {\\n position: fixed;\\n z-index: 50;\\n top: 0;\\n left: 0;\\n width: max-content;\\n max-width: min(\\n 20rem,\\n var(--tooltip-available-width, calc(100vw - 10px)),\\n calc(100vw - 10px)\\n );\\n max-height: min(\\n var(--tooltip-available-height, calc(100vh - 10px)),\\n calc(100vh - 10px)\\n );\\n padding: 4px 8px;\\n border: 1px solid var(--border);\\n border-radius: var(--radius-lg);\\n corner-shape: var(--corner-shape);\\n color: var(--popover-foreground);\\n background: var(--popover);\\n box-shadow: none;\\n font-size: var(--font-size-tooltip);\\n line-height: var(--line-height-tooltip);\\n overflow-wrap: break-word;\\n white-space: normal;\\n pointer-events: none;\\n user-select: none;\\n}\\n\\n.viz-grid {\\n display: grid;\\n grid-template-columns: repeat(auto-fit, minmax(max(180px, 24%), 1fr));\\n gap: 10px;\\n}\\n\\n.viz-stat {\\n display: flex;\\n flex-direction: column;\\n gap: 2px;\\n}\\n\\n.viz-stat-value {\\n font-size: var(--font-size-h2);\\n font-weight: var(--font-weight-medium);\\n line-height: 1.25;\\n}\\n\\n.viz-row {\\n display: flex;\\n flex-wrap: wrap;\\n align-items: center;\\n gap: 10px;\\n}\\n\\nhr {\\n width: 100%;\\n height: 1px;\\n margin-block: 6px;\\n border: 0;\\n background: var(--border);\\n}\\n\\n.nav {\\n display: flex;\\n min-width: 0;\\n align-items: center;\\n gap: 4px;\\n}\\n\\n.progress {\\n display: flex;\\n height: 8px;\\n margin-block: calc((var(--line-height-normal, 1.5em) - 8px) / 2);\\n overflow: hidden;\\n border: 0;\\n border-radius: var(--radius-full);\\n background: var(--muted);\\n}\\n\\n.progress-bar:only-child {\\n border-radius: var(--radius-full);\\n}\\n\\n.progress-bar {\\n height: 100%;\\n flex-shrink: 0;\\n border: 0;\\n background: var(--viz-series-1);\\n}\\n\\n.viz-badge {\\n padding: 3px 8px;\\n border-radius: var(--radius-full);\\n color: var(--accent-foreground);\\n background: var(--accent);\\n font-weight: var(--font-weight-medium);\\n}\\n\\nsmall,\\n.text-small,\\n.viz-badge {\\n font-size: var(--font-size-small);\\n line-height: var(--line-height-small);\\n}\\n\\n.text-muted {\\n color: var(--muted-foreground);\\n}\\n\\n.tabular-nums {\\n font-variant-numeric: tabular-nums;\\n}\\n\\n.sr-only {\\n position: absolute;\\n width: 1px;\\n height: 1px;\\n padding: 0;\\n overflow: hidden;\\n clip: rect(0, 0, 0, 0);\\n white-space: nowrap;\\n border: 0;\\n}\\n\\n.viz-controls {\\n display: flex;\\n flex-wrap: wrap;\\n align-items: center;\\n gap: 8px;\\n}\\n\\n.viz-controls > .form-label {\\n display: grid;\\n min-width: min(100%, 260px);\\n flex: 1 1 280px;\\n grid-template-columns: minmax(0, 1fr) auto;\\n align-items: baseline;\\n gap: 2px 12px;\\n margin-bottom: 0;\\n}\\n\\n.viz-controls > .form-label > :is(.form-control, .form-range, .form-select) {\\n grid-column: 1 / -1;\\n}\\n\\n.btn,\\n.nav-link,\\n.form-check-input,\\n.form-control,\\n.form-range,\\n.form-select {\\n font: inherit;\\n}\\n\\n.btn,\\n.nav-link {\\n appearance: button;\\n display: inline-flex;\\n inline-size: fit-content;\\n max-inline-size: 100%;\\n min-height: 28px;\\n align-items: center;\\n justify-content: center;\\n gap: 4px;\\n margin: 0;\\n padding: 0 8px;\\n -webkit-app-region: no-drag;\\n border: 1px solid var(--input);\\n border-radius: var(--radius-lg);\\n corner-shape: var(--corner-shape);\\n color: var(--secondary-foreground);\\n background: var(--secondary);\\n cursor: var(--cursor-interaction, pointer);\\n text-align: center;\\n text-decoration: none;\\n white-space: nowrap;\\n user-select: none;\\n -webkit-font-smoothing: antialiased;\\n}\\n\\n.btn:is(.btn-block, .viz-tile) {\\n inline-size: 100%;\\n}\\n\\n.btn.viz-tile {\\n min-width: 0;\\n overflow-wrap: anywhere;\\n white-space: normal;\\n}\\n\\na.btn {\\n cursor: pointer;\\n text-decoration: none;\\n}\\n\\n.btn:not(:disabled):hover,\\n.nav-link:not(:disabled):not([aria-disabled=\\\"true\\\"]):hover {\\n background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));\\n}\\n\\n.btn-primary {\\n border-color: transparent;\\n color: var(--primary-foreground);\\n background: var(--foreground);\\n background-clip: padding-box;\\n}\\n\\n.btn-primary .text-muted {\\n color: color-mix(in srgb, var(--primary-foreground) 50%, transparent);\\n}\\n\\n.btn-primary:not(:disabled):hover {\\n background: color-mix(in srgb, var(--foreground) 80%, transparent);\\n background-clip: padding-box;\\n}\\n\\n.btn-ghost {\\n border-color: transparent;\\n color: var(--muted-foreground);\\n background: transparent;\\n}\\n\\n.btn-ghost:not(:disabled):hover {\\n color: var(--foreground);\\n background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));\\n}\\n\\n.nav-pills .nav-link {\\n min-width: 0;\\n border-color: transparent;\\n color: var(--muted-foreground);\\n background: transparent;\\n}\\n\\n.nav-justified .nav-link {\\n flex: 1 1 0;\\n overflow-wrap: anywhere;\\n white-space: normal;\\n}\\n\\n.nav-pills .nav-link.active {\\n color: var(--foreground);\\n background: var(--muted);\\n}\\n\\n.btn:disabled,\\n.nav-link:disabled,\\n.nav-link[aria-disabled=\\\"true\\\"] {\\n cursor: not-allowed;\\n opacity: 0.4;\\n}\\n\\n[data-lucide] {\\n stroke-width: 1.6;\\n}\\n\\n.form-label {\\n display: block;\\n margin-bottom: 6px;\\n color: var(--foreground);\\n}\\n\\n.form-control {\\n display: block;\\n width: 100%;\\n min-height: 28px;\\n padding: 0 8px;\\n outline: none;\\n border: 1px solid var(--input);\\n border-radius: var(--radius-lg);\\n corner-shape: var(--corner-shape);\\n color: var(--foreground);\\n background: var(--secondary);\\n}\\n\\n.form-control::placeholder {\\n color: var(--muted-foreground);\\n}\\n\\n.form-control[type=\\\"file\\\"] {\\n padding: 0;\\n overflow: hidden;\\n cursor: var(--cursor-interaction, pointer);\\n}\\n\\n.form-control[type=\\\"file\\\"]::file-selector-button {\\n min-height: 26px;\\n margin-right: 8px;\\n padding: 0 8px;\\n border: 0;\\n border-right: 1px solid var(--input);\\n color: var(--secondary-foreground);\\n background: var(--secondary);\\n cursor: inherit;\\n font: inherit;\\n}\\n\\n.form-control[type=\\\"file\\\"]:not(:disabled):hover::file-selector-button {\\n background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));\\n}\\n\\n.form-control-color[type=\\\"color\\\"] {\\n width: 40px;\\n height: 28px;\\n padding: 3px;\\n cursor: var(--cursor-interaction, pointer);\\n}\\n\\n.form-control-color[type=\\\"color\\\"]::-webkit-color-swatch-wrapper {\\n padding: 0;\\n}\\n\\n.form-control-color[type=\\\"color\\\"]::-webkit-color-swatch {\\n border: 0;\\n border-radius: calc(var(--radius-lg) - 4px);\\n corner-shape: var(--corner-shape);\\n}\\n\\ntextarea.form-control {\\n height: auto;\\n min-height: 72px;\\n padding: 8px 10px;\\n resize: vertical;\\n}\\n\\n.form-control:focus-visible {\\n border-color: var(--ring);\\n box-shadow: inset 0 0 0 1px var(--ring);\\n}\\n\\n.form-control:disabled,\\n.form-select:disabled {\\n cursor: not-allowed;\\n opacity: 0.4;\\n}\\n\\n.form-select {\\n appearance: none;\\n display: block;\\n width: 100%;\\n min-height: 28px;\\n margin: 0;\\n padding: 0 32px 0 8px;\\n outline: none;\\n border: 1px solid var(--input);\\n border-radius: var(--radius-lg);\\n corner-shape: var(--corner-shape);\\n color: var(--foreground);\\n background-color: var(--secondary);\\n background-image:\\n linear-gradient(45deg, transparent 50%, var(--muted-foreground) 50%),\\n linear-gradient(135deg, var(--muted-foreground) 50%, transparent 50%);\\n background-position:\\n calc(100% - 14px) 50%,\\n calc(100% - 10px) 50%;\\n background-repeat: no-repeat;\\n background-size: 4px 4px;\\n cursor: var(--cursor-interaction, default);\\n}\\n\\n.form-select:not(:disabled):hover {\\n background-color: color-mix(in srgb, var(--foreground) 6%, var(--secondary));\\n}\\n\\n.form-select:focus-visible {\\n border-color: var(--ring);\\n box-shadow: inset 0 0 0 1px var(--ring);\\n}\\n\\n.form-check {\\n display: flex;\\n min-height: 20px;\\n align-items: center;\\n gap: 6px;\\n}\\n\\n.form-check-input {\\n appearance: none;\\n width: 14px;\\n height: 14px;\\n flex: 0 0 auto;\\n margin: 0;\\n border: 1px solid var(--input);\\n color: var(--primary-foreground);\\n background-color: transparent;\\n cursor: var(--cursor-interaction, default);\\n transition:\\n background-color 150ms,\\n border-color 150ms,\\n box-shadow 150ms;\\n}\\n\\n.form-check:not(.form-switch) .form-check-input[type=\\\"checkbox\\\"] {\\n border-color: var(--input);\\n border-radius: var(--radius-sm);\\n corner-shape: var(--corner-shape);\\n background-color: var(--secondary);\\n box-shadow: var(--shadow-sm);\\n}\\n\\n.form-check:not(.form-switch)\\n .form-check-input:not(:disabled):not(:checked):hover {\\n background-color: var(--card);\\n}\\n\\n.form-check:not(.form-switch) .form-check-input[type=\\\"checkbox\\\"]:checked {\\n border-color: var(--primary);\\n background-color: var(--primary);\\n}\\n\\n.form-check:not(.form-switch)\\n .form-check-input[type=\\\"checkbox\\\"]:checked::before {\\n display: block;\\n width: 100%;\\n height: 100%;\\n background: var(--primary-foreground);\\n content: \\\"\\\";\\n mask: var(--checkmark-image) center / 12px 12px no-repeat;\\n}\\n\\n.form-check-input[type=\\\"radio\\\"] {\\n width: 14px;\\n height: 14px;\\n border-radius: var(--radius-full);\\n}\\n\\n.form-check-input[type=\\\"radio\\\"]:checked {\\n border: 2px solid var(--primary);\\n background:\\n radial-gradient(circle, var(--primary-foreground) 0 2.5px, transparent 3px),\\n var(--primary);\\n}\\n\\n.form-check:not(.form-switch) .form-check-input:focus-visible {\\n outline: 2px solid var(--ring);\\n outline-offset: 2px;\\n}\\n\\n.form-check:not(.form-switch) .form-check-input:disabled {\\n cursor: not-allowed;\\n pointer-events: none;\\n}\\n\\n.form-check:not(.form-switch) .form-check-input:disabled + .form-check-label {\\n cursor: not-allowed;\\n}\\n\\n.form-switch .form-check-input:disabled,\\n.form-switch .form-check-input:disabled + .form-check-label {\\n cursor: not-allowed;\\n opacity: 0.6;\\n}\\n\\n.form-check-label {\\n color: var(--foreground);\\n cursor: var(--cursor-interaction, default);\\n}\\n\\n.form-switch .form-check-input {\\n position: relative;\\n width: 32px;\\n height: 20px;\\n border: 0;\\n border-radius: var(--radius-full);\\n background: var(--muted);\\n box-shadow: none;\\n transition: background-color 200ms cubic-bezier(0, 0, 0.2, 1);\\n}\\n\\n.form-switch .form-check-input::before {\\n position: absolute;\\n top: 50%;\\n left: 0;\\n width: 16px;\\n height: 16px;\\n box-sizing: border-box;\\n border: 1px solid light-dark(var(--primary-foreground), var(--foreground));\\n border-radius: var(--radius-full);\\n background: light-dark(var(--primary-foreground), var(--foreground));\\n box-shadow: var(--shadow-sm);\\n content: \\\"\\\";\\n transform: translate(2px, -50%);\\n transition: transform 200ms cubic-bezier(0, 0, 0.2, 1);\\n}\\n\\n.form-switch .form-check-input:checked {\\n background: var(--primary);\\n}\\n\\n.form-switch .form-check-input:checked::before {\\n transform: translate(14px, -50%);\\n}\\n\\n.form-switch .form-check-input:focus-visible {\\n box-shadow: 0 0 0 2px var(--ring);\\n}\\n\\n.form-range {\\n appearance: none;\\n display: block;\\n width: 100%;\\n height: 28px;\\n flex: 1;\\n margin: 0;\\n padding: 0;\\n outline: none;\\n border: 0;\\n accent-color: var(--primary);\\n background: linear-gradient(\\n color-mix(in srgb, var(--foreground) 7%, transparent),\\n color-mix(in srgb, var(--foreground) 7%, transparent)\\n )\\n center / 100% 2px no-repeat;\\n}\\n\\n.form-range::-webkit-slider-runnable-track {\\n height: 28px;\\n background: transparent;\\n}\\n\\n.form-range::-webkit-slider-thumb {\\n appearance: none;\\n width: 20px;\\n height: 20px;\\n margin-top: 4px;\\n border: 1px solid var(--border);\\n border-radius: var(--radius-full);\\n background: light-dark(var(--primary-foreground), var(--foreground));\\n}\\n\\n.form-range:focus-visible::-webkit-slider-thumb {\\n border-color: var(--ring);\\n box-shadow: inset 0 0 0 1px var(--ring);\\n}\\n\\n.form-range::-moz-range-track {\\n height: 28px;\\n background: transparent;\\n}\\n\\n.form-range::-moz-range-thumb {\\n width: 20px;\\n height: 20px;\\n border: 1px solid var(--border);\\n border-radius: var(--radius-full);\\n background: light-dark(var(--primary-foreground), var(--foreground));\\n}\\n\\n.form-range:focus-visible::-moz-range-thumb {\\n border-color: var(--ring);\\n box-shadow: inset 0 0 0 1px var(--ring);\\n}\\n\\n.form-range:disabled {\\n cursor: not-allowed;\\n opacity: 0.4;\\n}\\n\\n.btn:not(.btn-primary, .viz-tile):is(\\n [aria-pressed=\\\"true\\\"],\\n [aria-selected=\\\"true\\\"],\\n .is-selected\\n) {\\n border-color: var(--primary);\\n color: var(--primary-foreground);\\n background: var(--primary);\\n}\\n\\n.btn.viz-tile:is([aria-pressed=\\\"true\\\"], [aria-selected=\\\"true\\\"], .is-selected) {\\n border-color: var(--primary);\\n box-shadow: inset 0 0 0 1px var(--primary);\\n}\\n\\n.btn:focus-visible,\\n.nav-link:focus-visible {\\n outline: 2px solid var(--ring);\\n outline-offset: 2px;\\n}\\n\\n@media (pointer: coarse) {\\n .btn,\\n .nav-link,\\n .form-control,\\n .form-select {\\n min-width: 44px;\\n min-height: 44px;\\n }\\n\\n /* Keep small-screen WebKit from zooming when a text field receives focus. */\\n .form-control,\\n .form-select {\\n font-size: max(16px, var(--font-size-normal));\\n }\\n\\n .form-control[type=\\\"file\\\"]::file-selector-button {\\n min-width: 44px;\\n min-height: 44px;\\n }\\n\\n .form-control-color[type=\\\"color\\\"] {\\n width: 44px;\\n height: 44px;\\n }\\n\\n .form-control:is(\\n [type=\\\"date\\\"],\\n [type=\\\"datetime-local\\\"],\\n [type=\\\"month\\\"],\\n [type=\\\"time\\\"],\\n [type=\\\"week\\\"]\\n ) {\\n min-width: 0;\\n max-width: 100%;\\n padding-block: 8px;\\n }\\n\\n .form-check {\\n min-height: 44px;\\n padding-inline: 15px;\\n }\\n\\n .form-check-input {\\n position: relative;\\n }\\n\\n .form-check-input::after {\\n position: absolute;\\n top: 50%;\\n left: 50%;\\n width: 44px;\\n height: 44px;\\n content: \\\"\\\";\\n transform: translate(-50%, -50%);\\n }\\n\\n .form-check-label {\\n display: inline-flex;\\n min-width: 44px;\\n min-height: 44px;\\n align-items: center;\\n }\\n\\n .form-range {\\n height: 44px;\\n touch-action: pan-y;\\n }\\n\\n .form-range::-webkit-slider-runnable-track {\\n height: 44px;\\n }\\n\\n .form-range::-moz-range-track {\\n height: 44px;\\n }\\n\\n .form-range::-webkit-slider-thumb {\\n margin-top: 12px;\\n }\\n}\\n\\nsvg {\\n display: block;\\n max-width: 100%;\\n height: auto;\\n}\\n\\n#widget > svg {\\n width: 100%;\\n}\\n\\n/* Model-authored chart rules can otherwise stretch icons after these styles load. */\\nsvg.lucide {\\n display: block;\\n width: var(--icon-size) !important;\\n height: var(--icon-size) !important;\\n flex: none;\\n margin: 0 !important;\\n stroke-width: 1.6;\\n}\\n\\n.text-warning,\\n.text-destructive {\\n color: var(--destructive);\\n}\\n\";\nexport const VISUALIZATION_HELPERS = \"\\n<script src=\\\"https://unpkg.com/@floating-ui/core@1.7.3/dist/floating-ui.core.umd.min.js\\\"></script>\\n<script src=\\\"https://unpkg.com/@floating-ui/dom@1.7.4/dist/floating-ui.dom.umd.min.js\\\"></script>\\n<script>\\n (() => {\\n if (window.FloatingUIDOM == null) {\\n return;\\n }\\n const { autoUpdate, computePosition, flip, offset, shift, size } = window.FloatingUIDOM;\\n const tooltipPlacements = new Set([\\\"top\\\", \\\"right\\\", \\\"bottom\\\", \\\"left\\\"]);\\n const tooltipId = `codex-visualization-tooltip-${\\n window.crypto?.randomUUID?.() ?? Date.now().toString(36)\\n }`;\\n const tooltipGap = 5;\\n const hoverDelay = 700;\\n const skipDelay = 300;\\n let activeTrigger = null;\\n let pendingTrigger = null;\\n let tooltip = null;\\n let openTimeout = null;\\n let autoUpdateCleanup = null;\\n let positionRequest = 0;\\n let skipDelayUntil = 0;\\n let lastPointerWasTouch = false;\\n let pinnedByTouch = false;\\n\\n const getTrigger = (target) =>\\n target?.nodeType === Node.ELEMENT_NODE ? target.closest(\\\"[data-tooltip]\\\") : null;\\n const containsTarget = (trigger, target) =>\\n target?.nodeType != null && trigger.contains(target);\\n const getContent = (trigger) => trigger.getAttribute(\\\"data-tooltip\\\")?.trim() ?? \\\"\\\";\\n const getPlacement = (trigger) => {\\n const placement = trigger.getAttribute(\\\"data-tooltip-placement\\\");\\n return tooltipPlacements.has(placement) ? placement : \\\"top\\\";\\n };\\n const getTooltip = () => {\\n if (tooltip == null) {\\n tooltip = document.createElement(\\\"div\\\");\\n tooltip.id = tooltipId;\\n tooltip.className = \\\"tooltip\\\";\\n tooltip.setAttribute(\\\"role\\\", \\\"tooltip\\\");\\n }\\n return tooltip;\\n };\\n const setDescribedBy = (trigger, described) => {\\n const ids = new Set(\\n (trigger.getAttribute(\\\"aria-describedby\\\") ?? \\\"\\\").split(/\\\\s+/).filter(Boolean),\\n );\\n if (described) {\\n ids.add(tooltipId);\\n } else {\\n ids.delete(tooltipId);\\n }\\n if (ids.size === 0) {\\n trigger.removeAttribute(\\\"aria-describedby\\\");\\n } else {\\n trigger.setAttribute(\\\"aria-describedby\\\", [...ids].join(\\\" \\\"));\\n }\\n };\\n const clearOpenTimeout = () => {\\n if (openTimeout != null) {\\n window.clearTimeout(openTimeout);\\n openTimeout = null;\\n }\\n pendingTrigger = null;\\n };\\n const closeTooltip = (activateSkipDelay = true) => {\\n clearOpenTimeout();\\n pinnedByTouch = false;\\n positionRequest += 1;\\n autoUpdateCleanup?.();\\n autoUpdateCleanup = null;\\n if (activeTrigger == null) {\\n return;\\n }\\n setDescribedBy(activeTrigger, false);\\n activeTrigger = null;\\n tooltip?.remove();\\n if (activateSkipDelay) {\\n skipDelayUntil = Date.now() + skipDelay;\\n }\\n };\\n const updatePosition = (trigger, floating) => {\\n const request = ++positionRequest;\\n void computePosition(trigger, floating, {\\n middleware: [\\n offset(tooltipGap),\\n flip({ padding: tooltipGap }),\\n shift({ padding: tooltipGap }),\\n size({\\n padding: tooltipGap,\\n apply({ availableHeight, availableWidth, elements }) {\\n elements.floating.style.setProperty(\\n \\\"--tooltip-available-width\\\",\\n `${Math.max(0, availableWidth)}px`,\\n );\\n elements.floating.style.setProperty(\\n \\\"--tooltip-available-height\\\",\\n `${Math.max(0, availableHeight)}px`,\\n );\\n },\\n }),\\n ],\\n placement: getPlacement(trigger),\\n strategy: \\\"fixed\\\",\\n })\\n .then(({ x, y }) => {\\n if (activeTrigger !== trigger || request !== positionRequest) {\\n return;\\n }\\n const scale = window.devicePixelRatio || 1;\\n floating.style.transform = `translate(${Math.round(x * scale) / scale}px, ${Math.round(y * scale) / scale}px)`;\\n floating.style.visibility = \\\"visible\\\";\\n })\\n .catch(() => {\\n if (activeTrigger === trigger && request === positionRequest) {\\n closeTooltip(false);\\n }\\n });\\n };\\n const openTooltip = (trigger) => {\\n const content = getContent(trigger);\\n if (!trigger.isConnected || content.length === 0) {\\n return;\\n }\\n clearOpenTimeout();\\n if (activeTrigger === trigger) {\\n return;\\n }\\n closeTooltip();\\n const floating = getTooltip();\\n floating.textContent = content;\\n floating.style.visibility = \\\"hidden\\\";\\n floating.style.transform = \\\"translate(0, 0)\\\";\\n document.body.appendChild(floating);\\n activeTrigger = trigger;\\n setDescribedBy(trigger, true);\\n autoUpdateCleanup = autoUpdate(trigger, floating, () => {\\n updatePosition(trigger, floating);\\n });\\n };\\n const requestOpen = (trigger, immediate = false) => {\\n if (\\n getContent(trigger).length === 0 ||\\n activeTrigger === trigger ||\\n pendingTrigger === trigger\\n ) {\\n return;\\n }\\n clearOpenTimeout();\\n pendingTrigger = trigger;\\n const delay =\\n immediate || activeTrigger != null || Date.now() < skipDelayUntil ? 0 : hoverDelay;\\n if (delay === 0) {\\n openTooltip(trigger);\\n return;\\n }\\n openTimeout = window.setTimeout(() => {\\n openTimeout = null;\\n pendingTrigger = null;\\n openTooltip(trigger);\\n }, delay);\\n };\\n const handlePointerOpen = (event) => {\\n if (event.pointerType === \\\"touch\\\") {\\n return;\\n }\\n const trigger = getTrigger(event.target);\\n if (trigger == null || containsTarget(trigger, event.relatedTarget)) {\\n return;\\n }\\n requestOpen(trigger);\\n };\\n const handlePointer = (event) => {\\n lastPointerWasTouch = event.type === \\\"pointerdown\\\" && event.pointerType === \\\"touch\\\";\\n };\\n const handleTouchClick = (event) => {\\n const isTouch = event.pointerType === \\\"touch\\\" || lastPointerWasTouch;\\n lastPointerWasTouch = false;\\n if (!isTouch || event.detail === 0) {\\n return;\\n }\\n const trigger = getTrigger(event.target);\\n if (\\n trigger == null ||\\n !trigger.isConnected ||\\n getContent(trigger).length === 0 ||\\n (pinnedByTouch && activeTrigger === trigger)\\n ) {\\n if (pinnedByTouch) {\\n closeTooltip();\\n }\\n return;\\n }\\n openTooltip(trigger);\\n pinnedByTouch = activeTrigger === trigger;\\n window.setTimeout(() => {\\n if (activeTrigger === trigger && !trigger.isConnected) {\\n closeTooltip(false);\\n }\\n }, 0);\\n };\\n const handleLeave = (event) => {\\n if (pinnedByTouch) {\\n return;\\n }\\n const trigger = getTrigger(event.target);\\n if (trigger == null || containsTarget(trigger, event.relatedTarget)) {\\n return;\\n }\\n if (activeTrigger === trigger || pendingTrigger === trigger) {\\n closeTooltip();\\n }\\n };\\n const handleFocusIn = (event) => {\\n const trigger = getTrigger(event.target);\\n if (trigger?.matches(\\\":focus-visible\\\")) {\\n requestOpen(trigger, true);\\n }\\n };\\n const handleKeyDown = (event) => {\\n if (event.key === \\\"Escape\\\") {\\n closeTooltip();\\n }\\n };\\n const handleContextMenu = (event) => {\\n lastPointerWasTouch = false;\\n const trigger = getTrigger(event.target);\\n if (activeTrigger === trigger || pendingTrigger === trigger) {\\n closeTooltip();\\n }\\n };\\n const destroy = () => {\\n closeTooltip(false);\\n lastPointerWasTouch = false;\\n document.removeEventListener(\\\"pointerover\\\", handlePointerOpen);\\n document.removeEventListener(\\\"pointerdown\\\", handlePointer);\\n document.removeEventListener(\\\"pointercancel\\\", handlePointer);\\n document.removeEventListener(\\\"click\\\", handleTouchClick);\\n document.removeEventListener(\\\"pointerout\\\", handleLeave);\\n document.removeEventListener(\\\"focusin\\\", handleFocusIn);\\n document.removeEventListener(\\\"focusout\\\", handleLeave);\\n document.removeEventListener(\\\"keydown\\\", handleKeyDown);\\n document.removeEventListener(\\\"contextmenu\\\", handleContextMenu);\\n tooltip = null;\\n };\\n\\n document.addEventListener(\\\"pointerover\\\", handlePointerOpen);\\n document.addEventListener(\\\"pointerdown\\\", handlePointer);\\n document.addEventListener(\\\"pointercancel\\\", handlePointer);\\n document.addEventListener(\\\"click\\\", handleTouchClick);\\n document.addEventListener(\\\"pointerout\\\", handleLeave);\\n document.addEventListener(\\\"focusin\\\", handleFocusIn);\\n document.addEventListener(\\\"focusout\\\", handleLeave);\\n document.addEventListener(\\\"keydown\\\", handleKeyDown);\\n document.addEventListener(\\\"contextmenu\\\", handleContextMenu);\\n window.addEventListener(\\\"pagehide\\\", destroy, { once: true });\\n })();\\n</script>\\n<script id=\\\"codex-visualization-tabs\\\">\\n (() => {\\n const selector = '.nav[role=\\\"tablist\\\"] [role=\\\"tab\\\"]';\\n const disabled = ':disabled,[aria-disabled=\\\"true\\\"]';\\n const selectTab = (selected) => {\\n const panelId = selected.getAttribute(\\\"aria-controls\\\");\\n for (const tab of selected.closest('[role=\\\"tablist\\\"]').querySelectorAll('[role=\\\"tab\\\"]')) {\\n const active = tab === selected;\\n tab.classList.toggle(\\\"active\\\", active);\\n tab.setAttribute(\\\"aria-selected\\\", String(active));\\n const id = tab.getAttribute(\\\"aria-controls\\\");\\n const panel = id && document.getElementById(id);\\n if (panel != null) {\\n panel.hidden = id !== panelId;\\n if (!panel.hidden && selected.id) {\\n panel.setAttribute(\\\"aria-labelledby\\\", selected.id);\\n }\\n }\\n }\\n };\\n const interact = (event) => {\\n const tab = event.target?.closest?.(selector);\\n if (event.defaultPrevented || tab == null || tab.matches(disabled)) {\\n return;\\n }\\n if (event.type === \\\"click\\\") {\\n selectTab(tab);\\n return;\\n }\\n const tabs = Array.from(\\n tab.closest('[role=\\\"tablist\\\"]').querySelectorAll('[role=\\\"tab\\\"]'),\\n ).filter((candidate) => !candidate.matches(disabled));\\n const current = tabs.indexOf(tab);\\n let next;\\n if (event.key === \\\"ArrowRight\\\" || event.key === \\\"ArrowDown\\\") {\\n next = (current + 1) % tabs.length;\\n } else if (event.key === \\\"ArrowLeft\\\" || event.key === \\\"ArrowUp\\\") {\\n next = (current + tabs.length - 1) % tabs.length;\\n } else if (event.key === \\\"Home\\\") {\\n next = 0;\\n } else if (event.key === \\\"End\\\") {\\n next = tabs.length - 1;\\n } else {\\n return;\\n }\\n event.preventDefault();\\n tabs[next].focus();\\n selectTab(tabs[next]);\\n };\\n\\n for (const list of document.querySelectorAll('.nav[role=\\\"tablist\\\"]')) {\\n const selected =\\n list.querySelector('[role=\\\"tab\\\"][aria-selected=\\\"true\\\"]') ??\\n list.querySelector('[role=\\\"tab\\\"].active') ??\\n list.querySelector('[role=\\\"tab\\\"]');\\n if (selected != null) {\\n selectTab(selected);\\n }\\n }\\n document.addEventListener(\\\"click\\\", interact);\\n document.addEventListener(\\\"keydown\\\", interact);\\n window.addEventListener(\\n \\\"pagehide\\\",\\n () => {\\n document.removeEventListener(\\\"click\\\", interact);\\n document.removeEventListener(\\\"keydown\\\", interact);\\n },\\n { once: true },\\n );\\n })();\\n</script>\\n<script\\n id=\\\"codex-visualization-lucide\\\"\\n async\\n src=\\\"https://unpkg.com/lucide@1.17.0/dist/umd/lucide.js\\\"\\n></script>\\n<script>\\n (() => {\\n const initialize = () => {\\n globalThis.lucide?.createIcons({ attrs: { width: 16, height: 16 } });\\n };\\n if (globalThis.lucide != null) {\\n initialize();\\n return;\\n }\\n document\\n .getElementById(\\\"codex-visualization-lucide\\\")\\n ?.addEventListener(\\\"load\\\", initialize, { once: true });\\n })();\\n</script>\\n\";\n","import { VISUALIZATION_CSS, VISUALIZATION_HELPERS } from \"./visualization-assets.gen\";\n\n/** Conversation styling/helpers only. Rendering and tool transport remain in the Site frame. */\nexport function inlineHtmlDocument(fragment: string): string {\n return (\n '<!doctype html><html><head><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><style>' +\n VISUALIZATION_CSS +\n \"</style><style>html,body{margin:0;min-height:0}body{padding:16px;box-sizing:border-box}</style></head><body>\" +\n fragment +\n VISUALIZATION_HELPERS +\n `<script>\n(()=>{\n window.addEventListener('message',event=>{\n if(event.source!==parent||event.data?.type!=='opengeni.preview.theme')return;\n if(event.data.theme==='light'||event.data.theme==='dark')document.documentElement.style.colorScheme=event.data.theme;\n previous=0;resize();\n });\n let previous=0;\n const resize=()=>{const height=Math.ceil(document.body.getBoundingClientRect().height);if(height!==previous){previous=height;parent.postMessage({type:'opengeni.preview.height',height},'*')}};\n new ResizeObserver(resize).observe(document.body);resize();\n})();\n</script></body></html>`\n );\n}\n","import {\n createBrowserEditableArtifactSession,\n type CreateBrowserEditableArtifactSessionOptions,\n type EditableArtifactBrowserRuntime,\n type EditableArtifactSession,\n} from \"@opengeni/sdk/editable-artifacts\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { EditableArtifactMessage } from \"./editable-artifact-ui\";\nimport {\n EditableDocumentArtifactSurface,\n type EditableDocumentArtifactSurfaceProps,\n} from \"./editable-document\";\nimport {\n EditablePresentationArtifactSurface,\n type EditablePresentationArtifactSurfaceProps,\n} from \"./editable-presentation\";\nimport {\n EditableSpreadsheetArtifactSurface,\n type EditableSpreadsheetArtifactSurfaceProps,\n} from \"./editable-spreadsheet\";\n\nexport type EditableArtifactWorkbenchProps = Readonly<{\n session: EditableArtifactSession;\n document?: Omit<EditableDocumentArtifactSurfaceProps, \"session\">;\n spreadsheet?: Omit<EditableSpreadsheetArtifactSurfaceProps, \"session\">;\n presentation?: Omit<EditablePresentationArtifactSurfaceProps, \"session\">;\n}>;\n\nexport type EditableArtifactWorkbenchHostProps = Omit<EditableArtifactWorkbenchProps, \"session\"> &\n Readonly<{\n /**\n * Complete identity of the browser session authority. Change this when the\n * artifact, deployment, principal, or authorization epoch changes.\n */\n sessionKey: string;\n /** Called for the active keyed lifecycle and again only after replacement or retry. */\n createSession: () => EditableArtifactSession;\n }>;\n\ntype DefaultBrowserArtifactTransport = Omit<\n NonNullable<CreateBrowserEditableArtifactSessionOptions[\"transport\"]>,\n \"apiKey\" | \"fetch\" | \"headers\" | \"webSocketFactory\"\n> &\n Readonly<{\n /** Static deployment auth headers; rotate authorizationEpoch when they change. */\n headers?: Readonly<Record<string, string>>;\n }>;\n\nexport type BrowserEditableArtifactWorkbenchOptions = Omit<\n CreateBrowserEditableArtifactSessionOptions,\n \"runtime\" | \"storage\" | \"transport\"\n> &\n Readonly<{\n /** Default module Worker only; custom Worker hosts use EditableArtifactWorkbenchHost. */\n runtime: Omit<EditableArtifactBrowserRuntime, \"workerFactory\">;\n /** Default fetch/WebSocket only; static deployment auth headers are supported. */\n transport?: DefaultBrowserArtifactTransport;\n }>;\n\nexport type BrowserEditableArtifactWorkbenchProps = Omit<\n EditableArtifactWorkbenchProps,\n \"session\"\n> &\n Readonly<{ options: BrowserEditableArtifactWorkbenchOptions }>;\n\n/**\n * One modality-neutral SDK workbench. Embedding hosts keep one route/component;\n * each artifact still renders through its complete first-party editor surface.\n */\nexport function EditableArtifactWorkbench({\n session,\n document,\n spreadsheet,\n presentation,\n}: EditableArtifactWorkbenchProps) {\n switch (session.modality) {\n case \"document\":\n return (\n <EditableDocumentArtifactSurface\n {...document}\n session={session}\n title={document?.title ?? \"Document\"}\n />\n );\n case \"spreadsheet\":\n return <EditableSpreadsheetArtifactSurface {...spreadsheet} session={session} />;\n case \"presentation\":\n return <EditablePresentationArtifactSurface {...presentation} session={session} />;\n }\n}\n\n/**\n * Route/embed composition that owns exactly one SDK session. The host supplies\n * the authenticated SDK factory; React guarantees replacement and teardown.\n */\nexport function EditableArtifactWorkbenchHost({\n sessionKey,\n createSession,\n document,\n spreadsheet,\n presentation,\n}: EditableArtifactWorkbenchHostProps) {\n const createSessionRef = useRef(createSession);\n const [retryEpoch, setRetryEpoch] = useState(0);\n const [state, setState] = useState<\n | Readonly<{ key: string; session: EditableArtifactSession; error: null }>\n | Readonly<{ key: string | null; session: null; error: Error | null }>\n >({ key: null, session: null, error: null });\n\n useEffect(() => {\n createSessionRef.current = createSession;\n }, [createSession]);\n\n useEffect(() => {\n let owned: EditableArtifactSession | null = null;\n setState({ key: sessionKey, session: null, error: null });\n try {\n owned = createSessionRef.current();\n setState({ key: sessionKey, session: owned, error: null });\n } catch (cause) {\n setState({\n key: sessionKey,\n session: null,\n error: cause instanceof Error ? cause : new Error(\"Could not create artifact session\"),\n });\n }\n return () => {\n const closing = owned;\n owned = null;\n if (closing) void closing.close().catch(() => undefined);\n };\n }, [retryEpoch, sessionKey]);\n\n const retry = useCallback(() => setRetryEpoch((value) => value + 1), []);\n const currentError = state.key === sessionKey ? state.error : null;\n if (state.key === sessionKey && state.session) {\n return (\n <EditableArtifactWorkbench\n session={state.session}\n {...(document ? { document } : {})}\n {...(spreadsheet ? { spreadsheet } : {})}\n {...(presentation ? { presentation } : {})}\n />\n );\n }\n return (\n <EditableArtifactMessage\n title={currentError ? \"Could not open this artifact\" : \"Opening artifact\"}\n detail={currentError?.message ?? \"Starting the secure editing session…\"}\n retry={currentError ? retry : undefined}\n />\n );\n}\n\n/**\n * Complete default-browser composition for embedders: verified WASM Worker,\n * durable IndexedDB state, authenticated live sync, teardown, and the matching\n * first-party editor. Advanced/custom transports compose the lower-level host.\n */\nexport function BrowserEditableArtifactWorkbench({\n options,\n document,\n spreadsheet,\n presentation,\n}: BrowserEditableArtifactWorkbenchProps) {\n const sessionKey = browserSessionKey(options);\n const createSession = useCallback(() => createBrowserEditableArtifactSession(options), [options]);\n return (\n <EditableArtifactWorkbenchHost\n sessionKey={sessionKey}\n createSession={createSession}\n {...(document ? { document } : {})}\n {...(spreadsheet ? { spreadsheet } : {})}\n {...(presentation ? { presentation } : {})}\n />\n );\n}\n\nfunction browserSessionKey(options: BrowserEditableArtifactWorkbenchOptions): string {\n const transport = options.transport\n ? {\n ...options.transport,\n // Credentials must not be copied into React lifecycle keys. The\n // authorization epoch is the explicit credential/grant rotation fence.\n headers: options.transport.headers\n ? Object.keys(options.transport.headers).sort()\n : undefined,\n }\n : null;\n return JSON.stringify(\n {\n baseUrl: options.baseUrl,\n workspaceId: options.workspaceId,\n artifact: { id: options.artifact.id, modality: options.artifact.modality },\n storageAuthority: options.storageAuthority,\n runtime: options.runtime,\n replicaId: options.replicaId ?? null,\n transport,\n },\n (_key, value: unknown) => (value instanceof URL ? value.href : value),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACO,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAC1B,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","names":[]}
@@ -46,8 +46,9 @@ import {
46
46
  TooltipTrigger
47
47
  } from "./chunk-HQV2I5HV.js";
48
48
  import {
49
+ isRetainedImageContentType,
49
50
  useRetainedImageObjectUrl
50
- } from "./chunk-2TKI3WEG.js";
51
+ } from "./chunk-WYWRYUNQ.js";
51
52
  import {
52
53
  ModelPolicyPicker
53
54
  } from "./chunk-R4KRSFGA.js";
@@ -2733,16 +2734,20 @@ function RetainedSessionImageDisclosure({
2733
2734
  lightboxLabel,
2734
2735
  batched,
2735
2736
  failed,
2736
- cancelled
2737
+ cancelled,
2738
+ filename,
2739
+ defaultOpen,
2740
+ children
2737
2741
  }) {
2738
2742
  const state = useRetainedImageObjectUrl(artifact, load);
2739
- const downloadFilename = retainedImageFilename(artifact);
2743
+ const downloadFilename = filename ?? retainedImageFilename(artifact);
2740
2744
  return /* @__PURE__ */ jsxs6(
2741
2745
  ActivityDisclosure,
2742
2746
  {
2743
2747
  icon,
2744
2748
  iconTone: failed ? "failed" : state.kind === "ready" ? "accent" : "muted",
2745
2749
  title,
2750
+ defaultOpen,
2746
2751
  failed,
2747
2752
  cancelled,
2748
2753
  preview: state.kind === "loading" ? `loading retained ${noun}\u2026` : state.kind === "error" ? `${noun} retrieval failed` : state.kind === "unavailable" ? `${noun} ${state.label}` : void 0,
@@ -2785,7 +2790,8 @@ function RetainedSessionImageDisclosure({
2785
2790
  batched ? /* @__PURE__ */ jsxs6(BodyNote, { children: [
2786
2791
  "batched: ",
2787
2792
  batched
2788
- ] }) : null
2793
+ ] }) : null,
2794
+ children
2789
2795
  ]
2790
2796
  }
2791
2797
  );
@@ -2865,6 +2871,20 @@ function SandboxFilePublishRenderer({ item, loadRetainedArtifact }) {
2865
2871
  if (!receipt || isError || item.status === "failed") {
2866
2872
  return /* @__PURE__ */ jsx9(GenericRenderer, { item });
2867
2873
  }
2874
+ const workspaceId = /^\/v1\/workspaces\/([0-9a-f-]+)\/artifacts\//.exec(
2875
+ receipt.artifact.retrieval.path
2876
+ )?.[1];
2877
+ const openLink = workspaceId ? /* @__PURE__ */ jsx9(
2878
+ "a",
2879
+ {
2880
+ href: `/workspaces/${workspaceId}/artifacts/files/${receipt.artifact.artifactId}`,
2881
+ "aria-label": `Open ${receipt.filename} in Artifacts`,
2882
+ className: "inline-flex min-h-7 items-center rounded-og-sm px-2 text-og-sm font-medium text-og-accent-strong hover:bg-og-surface-2 hover:underline focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-10",
2883
+ onClick: (event) => event.stopPropagation(),
2884
+ onKeyDown: (event) => event.stopPropagation(),
2885
+ children: "Open in Artifacts"
2886
+ }
2887
+ ) : null;
2868
2888
  const download = async () => {
2869
2889
  if (!loadRetainedArtifact) {
2870
2890
  setDownloadState("error");
@@ -2893,7 +2913,43 @@ function SandboxFilePublishRenderer({ item, loadRetainedArtifact }) {
2893
2913
  if (urlToRevoke) setTimeout(() => URL.revokeObjectURL(urlToRevoke), 0);
2894
2914
  }
2895
2915
  };
2896
- return /* @__PURE__ */ jsx9(
2916
+ const downloadButton = /* @__PURE__ */ jsxs6(
2917
+ "button",
2918
+ {
2919
+ type: "button",
2920
+ onClick: () => void download(),
2921
+ disabled: downloadState === "loading",
2922
+ className: "inline-flex items-center gap-1.5 rounded-og-sm border border-og-border px-2.5 py-1.5 text-og-sm font-medium text-og-fg transition-colors hover:border-og-border-strong hover:bg-og-surface-2 disabled:cursor-wait disabled:opacity-60",
2923
+ children: [
2924
+ /* @__PURE__ */ jsx9(DownloadIcon, { className: "size-3.5" }),
2925
+ downloadState === "loading" ? "Preparing\u2026" : downloadState === "error" ? "Retry download" : "Download"
2926
+ ]
2927
+ }
2928
+ );
2929
+ if (isRetainedImageContentType(receipt.artifact.contentType)) {
2930
+ return /* @__PURE__ */ jsxs6(
2931
+ RetainedSessionImageDisclosure,
2932
+ {
2933
+ artifact: receipt.artifact,
2934
+ load: loadRetainedArtifact,
2935
+ title: `Published ${receipt.filename}`,
2936
+ caption: receipt.filename,
2937
+ noun: "image",
2938
+ icon: /* @__PURE__ */ jsx9(ImageIcon, { className: ICON_SIZE }),
2939
+ lightboxLabel: "Image",
2940
+ batched: null,
2941
+ failed: false,
2942
+ cancelled: false,
2943
+ filename: receipt.filename,
2944
+ defaultOpen: true,
2945
+ children: [
2946
+ downloadButton,
2947
+ openLink
2948
+ ]
2949
+ }
2950
+ );
2951
+ }
2952
+ return /* @__PURE__ */ jsxs6(
2897
2953
  ActivityDisclosure,
2898
2954
  {
2899
2955
  icon: /* @__PURE__ */ jsx9(DownloadIcon, { className: ICON_SIZE }),
@@ -2901,19 +2957,10 @@ function SandboxFilePublishRenderer({ item, loadRetainedArtifact }) {
2901
2957
  title: `Published ${receipt.filename}`,
2902
2958
  defaultOpen: true,
2903
2959
  preview: formatBytes(receipt.artifact.originalBytes),
2904
- children: /* @__PURE__ */ jsxs6(
2905
- "button",
2906
- {
2907
- type: "button",
2908
- onClick: () => void download(),
2909
- disabled: downloadState === "loading",
2910
- className: "inline-flex items-center gap-1.5 rounded-og-sm border border-og-border px-2.5 py-1.5 text-og-sm font-medium text-og-fg transition-colors hover:border-og-border-strong hover:bg-og-surface-2 disabled:cursor-wait disabled:opacity-60",
2911
- children: [
2912
- /* @__PURE__ */ jsx9(DownloadIcon, { className: "size-3.5" }),
2913
- downloadState === "loading" ? "Preparing\u2026" : downloadState === "error" ? "Retry download" : "Download"
2914
- ]
2915
- }
2916
- )
2960
+ children: [
2961
+ downloadButton,
2962
+ openLink
2963
+ ]
2917
2964
  }
2918
2965
  );
2919
2966
  }
@@ -5536,6 +5583,7 @@ function ChildSessionLink({
5536
5583
  }
5537
5584
 
5538
5585
  // src/components/message-timeline.tsx
5586
+ import { parseSandboxFileArtifactReceipt as parseSandboxFileArtifactReceipt2 } from "@opengeni/sdk";
5539
5587
  import { dequal } from "dequal/lite";
5540
5588
  import {
5541
5589
  ArrowDownIcon,
@@ -7508,10 +7556,11 @@ var TimelineGroupView = memo(function TimelineGroupView2({
7508
7556
  previousSingleActivity.current = work.length === 1 ? work[0] : void 0;
7509
7557
  }, [group]);
7510
7558
  const foldMemory = useFoldMemory();
7511
- const activityShouldFold = group.kind === "activity" && !!(group.outcome || foldLiveCluster && clusterIsSettled(group));
7512
- const containsGeneratedImage = timelineGroupContainsGeneratedImage(group);
7559
+ const containsPresentedImage = timelineGroupContainsPresentedImage(group);
7560
+ const hasRememberedImageFold = group.kind === "activity" && containsPresentedImage && foldMemory?.has(group.id);
7561
+ const activityShouldFold = group.kind === "activity" && !containsPresentedImage && !!(group.outcome || foldLiveCluster && clusterIsSettled(group));
7513
7562
  const liveActivitySettle = useLiveSettleFold(activityShouldFold && !insideTurn);
7514
- const turnDefaultOpen = !insideTurn && group.kind === "turn" && (group.outcome === "failed" || timelineGroupContainsAuthNeeded(group) || containsGeneratedImage);
7563
+ const turnDefaultOpen = !insideTurn && group.kind === "turn" && (group.outcome === "failed" || timelineGroupContainsAuthNeeded(group) || containsPresentedImage);
7515
7564
  if (group.kind === "turn" && foldMemory && !insideTurn) {
7516
7565
  inheritFoldRestingState(
7517
7566
  foldMemory,
@@ -7539,7 +7588,7 @@ var TimelineGroupView = memo(function TimelineGroupView2({
7539
7588
  }
7540
7589
  );
7541
7590
  }
7542
- if (turnSummary?.rolling && !startupDetails && group.items.filter((item) => item.kind !== "startup-phase").length === 1) {
7591
+ if (turnSummary?.rolling && !startupDetails && !hasRememberedImageFold && group.items.filter((item) => item.kind !== "startup-phase").length === 1) {
7543
7592
  return /* @__PURE__ */ jsx19(
7544
7593
  ActivityRail,
7545
7594
  {
@@ -7557,7 +7606,7 @@ var TimelineGroupView = memo(function TimelineGroupView2({
7557
7606
  if (insideTurn) {
7558
7607
  const visibleActivity = group.items.filter((item) => item.kind !== "startup-phase");
7559
7608
  const singleThought = !startupDetails && visibleActivity.length === 1 && visibleActivity[0]?.kind === "reasoning";
7560
- const useNestedChip = nestClusterChips && activityShouldFold && !containsGeneratedImage && !singleThought;
7609
+ const useNestedChip = nestClusterChips && (activityShouldFold || hasRememberedImageFold) && !singleThought;
7561
7610
  if (!useNestedChip) {
7562
7611
  return /* @__PURE__ */ jsx19(
7563
7612
  ActivityRail,
@@ -7605,8 +7654,8 @@ var TimelineGroupView = memo(function TimelineGroupView2({
7605
7654
  items: group.items,
7606
7655
  outcome: group.outcome,
7607
7656
  failureText: group.failureText,
7608
- defaultOpen: group.outcome === "failed" || !turnSummary?.rolling && !activityShouldFold ? true : void 0,
7609
- liveHeader: turnSummary?.rolling && !group.outcome && !foldLiveCluster ? /* @__PURE__ */ jsx19(
7657
+ defaultOpen: group.outcome === "failed" || containsPresentedImage || !turnSummary?.rolling && !activityShouldFold ? true : void 0,
7658
+ liveHeader: turnSummary?.rolling && !containsPresentedImage && !group.outcome && !foldLiveCluster ? /* @__PURE__ */ jsx19(
7610
7659
  RollingActivity,
7611
7660
  {
7612
7661
  items: group.items,
@@ -7630,7 +7679,8 @@ var TimelineGroupView = memo(function TimelineGroupView2({
7630
7679
  bare: true
7631
7680
  }
7632
7681
  ) }) })
7633
- }
7682
+ },
7683
+ containsPresentedImage ? "primary-image" : "activity"
7634
7684
  );
7635
7685
  case "turn": {
7636
7686
  const activityItems = flattenActivityItems(group.groups);
@@ -7761,16 +7811,23 @@ function timelineGroupContainsAuthNeeded(group) {
7761
7811
  return group.groups.some(timelineGroupContainsAuthNeeded);
7762
7812
  }
7763
7813
  }
7764
- function timelineGroupContainsGeneratedImage(group) {
7814
+ function timelineGroupContainsPresentedImage(group) {
7765
7815
  switch (group.kind) {
7766
7816
  case "item":
7767
7817
  return false;
7768
7818
  case "activity":
7769
- return group.items.some(
7770
- (item) => item.kind === "tool-call" && item.name === "generate_image"
7771
- );
7819
+ return group.items.some((item) => {
7820
+ if (item.kind !== "tool-call") return false;
7821
+ const name = mcpToolLeaf(item.name);
7822
+ if (name === "generate_image" || name === "image_generation_call") return true;
7823
+ if (item.status !== "complete" || name !== "sandbox_file_publish") return false;
7824
+ const output = unwrapMcpOutput(item.output);
7825
+ if (output.isError) return false;
7826
+ const receipt = parseSandboxFileArtifactReceipt2(output.text);
7827
+ return receipt !== null && isRetainedImageContentType(receipt.artifact.contentType);
7828
+ });
7772
7829
  case "turn":
7773
- return group.groups.some(timelineGroupContainsGeneratedImage);
7830
+ return group.groups.some(timelineGroupContainsPresentedImage);
7774
7831
  }
7775
7832
  }
7776
7833
  function timelineGroupItemIds(group) {
@@ -10745,4 +10802,4 @@ export {
10745
10802
  SessionCommandsPanel,
10746
10803
  StartupTimings
10747
10804
  };
10748
- //# sourceMappingURL=chunk-O4NQNMPG.js.map
10805
+ //# sourceMappingURL=chunk-CC7AVRIJ.js.map