@aperture-browser/session-react 0.0.0-init.0 → 0.0.0-nightly.100.78b4e7ef6edc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,24 +1,25 @@
1
- import { a as makeApertureRuntime, c as collaborationPaintLifetimeMs, d as RuntimeProviderMissingError, f as useBaseUrl, g as useRuntime, h as useRunApi, i as ApertureProvider, l as useLiveSession, m as useFork, n as parseShareToken, o as useBrowserControl, p as useEffectCallback, r as useSharedSession, s as SessionViewport, t as LiveSessionError, u as RuntimeProvider } from "./headless-CKFacFX3.js";
1
+ import { a as makeApertureRuntime, c as collaborationPaintLifetimeMs, d as RuntimeProviderMissingError, f as useBaseUrl, g as useRuntime, h as useRunApi, i as ApertureProvider, l as useLiveSession, m as useFork, n as shareSessionAccess, o as useBrowserControl, p as useEffectCallback, r as useSession, s as SessionViewport, t as LiveSessionError, u as RuntimeProvider } from "./headless-CPoXwbFz.js";
2
2
  import { Fragment, createContext, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
3
3
  import * as Effect from "effect/Effect";
4
4
  import { VIEWPORT_DEVICE_SCALE_FACTORS, VIEWPORT_PRESETS, createViewportPreset, formatViewportScale } from "@aperture-browser/live-session";
5
5
  import * as Data from "effect/Data";
6
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
- import { ArrowLeft, ArrowRight, CheckIcon, ChevronRightIcon, Circle, CircleCheckIcon, Copy, Download, Gauge, Globe2, Info, InfoIcon, Link2Off, Loader2, Loader2Icon, Lock, LockOpen, Maximize2, Monitor, MoreVertical, MousePointer2, OctagonXIcon, PanelBottom, PanelRight, Pencil, Plus, Radio, RefreshCw, RotateCcw, Share2, Square, TriangleAlertIcon, Unplug, Wrench, X } from "lucide-react";
7
+ import { ArrowLeft, ArrowRight, CheckIcon, ChevronRightIcon, Circle, CircleCheckIcon, Copy, Download, Eye, Gauge, Globe2, Hand, Info, InfoIcon, Link2Off, Loader2, Loader2Icon, Lock, LockOpen, Maximize2, Monitor, MonitorPause, MoreVertical, MousePointer2, OctagonXIcon, PanelBottom, PanelRight, Pencil, Plus, Radio, RefreshCw, RotateCcw, Share2, Square, TriangleAlertIcon, Unplug, Wrench, X } from "lucide-react";
8
8
  import { cva } from "class-variance-authority";
9
9
  import { clsx } from "clsx";
10
- import { twMerge } from "tailwind-merge";
10
+ import { extendTailwindMerge } from "tailwind-merge";
11
11
  import { useTheme } from "next-themes";
12
12
  import { Toaster, toast } from "sonner";
13
- import { Tooltip } from "@base-ui/react/tooltip";
14
13
  import * as ResizablePrimitive from "react-resizable-panels";
15
14
  import { usePanelRef } from "react-resizable-panels";
16
15
  import * as Schedule from "effect/Schedule";
17
16
  import { Button } from "@base-ui/react/button";
18
17
  import { ContextMenu } from "@base-ui/react/context-menu";
19
18
  import { Input } from "@base-ui/react/input";
19
+ import { Tooltip } from "@base-ui/react/tooltip";
20
20
  import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
21
21
  import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
22
+ import { PreviewCard } from "@base-ui/react/preview-card";
22
23
  import { ScrollArea } from "@base-ui/react/scroll-area";
23
24
  import "@base-ui/react/separator";
24
25
  import { Menu } from "@base-ui/react/menu";
@@ -27,6 +28,7 @@ import { Popover } from "@base-ui/react/popover";
27
28
  import { mergeProps } from "@base-ui/react/merge-props";
28
29
  import { useRender } from "@base-ui/react/use-render";
29
30
  //#region ../ui/src/utils.ts
31
+ const twMerge = extendTailwindMerge({ prefix: "aperture" });
30
32
  function cn(...inputs) {
31
33
  return twMerge(clsx(inputs));
32
34
  }
@@ -35,21 +37,21 @@ function cn(...inputs) {
35
37
  function Empty({ className, ...props }) {
36
38
  return /* @__PURE__ */ jsx("div", {
37
39
  "data-slot": "empty",
38
- className: cn("flex w-full min-w-0 flex-1 flex-col items-center justify-center gap-4 rounded-xl border-dashed p-6 text-center text-balance", className),
40
+ className: cn("aperture:flex aperture:w-full aperture:min-w-0 aperture:flex-1 aperture:flex-col aperture:items-center aperture:justify-center aperture:gap-4 aperture:rounded-xl aperture:border-dashed aperture:p-6 aperture:text-center aperture:text-balance", className),
39
41
  ...props
40
42
  });
41
43
  }
42
44
  function EmptyHeader({ className, ...props }) {
43
45
  return /* @__PURE__ */ jsx("div", {
44
46
  "data-slot": "empty-header",
45
- className: cn("flex max-w-sm flex-col items-center gap-2", className),
47
+ className: cn("aperture:flex aperture:max-w-sm aperture:flex-col aperture:items-center aperture:gap-2", className),
46
48
  ...props
47
49
  });
48
50
  }
49
- const emptyMediaVariants = cva("mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0", {
51
+ const emptyMediaVariants = cva("aperture:mb-2 aperture:flex aperture:shrink-0 aperture:items-center aperture:justify-center aperture:[&_svg]:pointer-events-none aperture:[&_svg]:shrink-0", {
50
52
  variants: { variant: {
51
- default: "bg-transparent",
52
- icon: "flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-4"
53
+ default: "aperture:bg-transparent",
54
+ icon: "aperture:flex aperture:size-8 aperture:shrink-0 aperture:items-center aperture:justify-center aperture:rounded-lg aperture:bg-muted aperture:text-foreground aperture:[&_svg:not([class*='size-'])]:size-4"
53
55
  } },
54
56
  defaultVariants: { variant: "default" }
55
57
  });
@@ -67,14 +69,14 @@ function EmptyMedia({ className, variant = "default", ...props }) {
67
69
  function EmptyTitle({ className, ...props }) {
68
70
  return /* @__PURE__ */ jsx("div", {
69
71
  "data-slot": "empty-title",
70
- className: cn("text-sm font-medium tracking-tight", className),
72
+ className: cn("aperture:text-sm aperture:font-medium aperture:tracking-tight", className),
71
73
  ...props
72
74
  });
73
75
  }
74
76
  function EmptyDescription({ className, ...props }) {
75
77
  return /* @__PURE__ */ jsx("div", {
76
78
  "data-slot": "empty-description",
77
- className: cn("text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary", className),
79
+ className: cn("aperture:text-sm/relaxed aperture:text-muted-foreground aperture:[&>a]:underline aperture:[&>a]:underline-offset-4 aperture:[&>a:hover]:text-primary", className),
78
80
  ...props
79
81
  });
80
82
  }
@@ -84,13 +86,13 @@ const Toaster$1 = ({ ...props }) => {
84
86
  const { theme = "system" } = useTheme();
85
87
  return /* @__PURE__ */ jsx(Toaster, {
86
88
  theme,
87
- className: "toaster group",
89
+ className: "toaster aperture:group",
88
90
  icons: {
89
- success: /* @__PURE__ */ jsx(CircleCheckIcon, { className: "size-4" }),
90
- info: /* @__PURE__ */ jsx(InfoIcon, { className: "size-4" }),
91
- warning: /* @__PURE__ */ jsx(TriangleAlertIcon, { className: "size-4" }),
92
- error: /* @__PURE__ */ jsx(OctagonXIcon, { className: "size-4" }),
93
- loading: /* @__PURE__ */ jsx(Loader2Icon, { className: "size-4 animate-spin" })
91
+ success: /* @__PURE__ */ jsx(CircleCheckIcon, { className: "aperture:size-4" }),
92
+ info: /* @__PURE__ */ jsx(InfoIcon, { className: "aperture:size-4" }),
93
+ warning: /* @__PURE__ */ jsx(TriangleAlertIcon, { className: "aperture:size-4" }),
94
+ error: /* @__PURE__ */ jsx(OctagonXIcon, { className: "aperture:size-4" }),
95
+ loading: /* @__PURE__ */ jsx(Loader2Icon, { className: "aperture:size-4 aperture:animate-spin" })
94
96
  },
95
97
  style: {
96
98
  "--normal-bg": "var(--popover)",
@@ -103,57 +105,6 @@ const Toaster$1 = ({ ...props }) => {
103
105
  });
104
106
  };
105
107
  //#endregion
106
- //#region ../ui/src/portal.tsx
107
- const PortalContainerContext = createContext(null);
108
- function PortalContainerProvider({ container, children }) {
109
- return /* @__PURE__ */ jsx(PortalContainerContext.Provider, {
110
- value: container,
111
- children
112
- });
113
- }
114
- function usePortalContainer() {
115
- return useContext(PortalContainerContext) ?? void 0;
116
- }
117
- //#endregion
118
- //#region ../ui/src/components/tooltip.tsx
119
- function TooltipProvider({ delay = 0, ...props }) {
120
- return /* @__PURE__ */ jsx(Tooltip.Provider, {
121
- "data-slot": "tooltip-provider",
122
- delay,
123
- ...props
124
- });
125
- }
126
- function Tooltip$1({ ...props }) {
127
- return /* @__PURE__ */ jsx(Tooltip.Root, {
128
- "data-slot": "tooltip",
129
- ...props
130
- });
131
- }
132
- function TooltipTrigger({ ...props }) {
133
- return /* @__PURE__ */ jsx(Tooltip.Trigger, {
134
- "data-slot": "tooltip-trigger",
135
- ...props
136
- });
137
- }
138
- function TooltipContent({ className, side = "top", sideOffset = 4, align = "center", alignOffset = 0, children, ...props }) {
139
- return /* @__PURE__ */ jsx(Tooltip.Portal, {
140
- container: usePortalContainer(),
141
- children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
142
- align,
143
- alignOffset,
144
- side,
145
- sideOffset,
146
- className: "isolate z-50",
147
- children: /* @__PURE__ */ jsxs(Tooltip.Popup, {
148
- "data-slot": "tooltip-content",
149
- className: cn("z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
150
- ...props,
151
- children: [children, /* @__PURE__ */ jsx(Tooltip.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" })]
152
- })
153
- })
154
- });
155
- }
156
- //#endregion
157
108
  //#region src/features.ts
158
109
  function resolveSessionFeatures(features) {
159
110
  return {
@@ -170,25 +121,25 @@ function resolveSessionFeatures(features) {
170
121
  }
171
122
  //#endregion
172
123
  //#region ../ui/src/components/button.tsx
173
- const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm leading-none font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
124
+ const buttonVariants = cva("aperture:group/button aperture:inline-flex aperture:shrink-0 aperture:items-center aperture:justify-center aperture:rounded-lg aperture:border aperture:border-transparent aperture:bg-clip-padding aperture:text-sm aperture:leading-none aperture:font-medium aperture:whitespace-nowrap aperture:transition-all aperture:outline-none aperture:select-none aperture:focus-visible:border-ring aperture:focus-visible:ring-3 aperture:focus-visible:ring-ring/50 aperture:active:not-aria-[haspopup]:translate-y-px aperture:disabled:pointer-events-none aperture:disabled:opacity-50 aperture:aria-invalid:border-destructive aperture:aria-invalid:ring-3 aperture:aria-invalid:ring-destructive/20 aperture:dark:aria-invalid:border-destructive/50 aperture:dark:aria-invalid:ring-destructive/40 aperture:[&_svg]:pointer-events-none aperture:[&_svg]:shrink-0 aperture:[&_svg:not([class*='size-'])]:size-4", {
174
125
  variants: {
175
126
  variant: {
176
- default: "bg-primary text-primary-foreground hover:bg-primary/80",
177
- outline: "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
178
- secondary: "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
179
- ghost: "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
180
- destructive: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
181
- link: "text-primary underline-offset-4 hover:underline"
127
+ default: "aperture:bg-primary aperture:text-primary-foreground aperture:hover:bg-primary/80",
128
+ outline: "aperture:border-border aperture:bg-background aperture:hover:bg-muted aperture:hover:text-foreground aperture:aria-expanded:bg-muted aperture:aria-expanded:text-foreground aperture:dark:border-input aperture:dark:bg-input/30 aperture:dark:hover:bg-input/50",
129
+ secondary: "aperture:bg-secondary aperture:text-secondary-foreground aperture:hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aperture:aria-expanded:bg-secondary aperture:aria-expanded:text-secondary-foreground",
130
+ ghost: "aperture:hover:bg-muted aperture:hover:text-foreground aperture:aria-expanded:bg-muted aperture:aria-expanded:text-foreground aperture:dark:hover:bg-muted/50",
131
+ destructive: "aperture:bg-destructive/10 aperture:text-destructive aperture:hover:bg-destructive/20 aperture:focus-visible:border-destructive/40 aperture:focus-visible:ring-destructive/20 aperture:dark:bg-destructive/20 aperture:dark:hover:bg-destructive/30 aperture:dark:focus-visible:ring-destructive/40",
132
+ link: "aperture:text-primary aperture:underline-offset-4 aperture:hover:underline"
182
133
  },
183
134
  size: {
184
- default: "h-8 gap-1.5 px-2.5 pt-px has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
185
- xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 pt-px text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
186
- sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 pt-px text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
187
- lg: "h-9 gap-1.5 px-2.5 pt-px has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
188
- icon: "size-8",
189
- "icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
190
- "icon-sm": "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
191
- "icon-lg": "size-9"
135
+ default: "aperture:h-8 aperture:gap-1.5 aperture:px-2.5 aperture:pt-px aperture:has-data-[icon=inline-end]:pr-2 aperture:has-data-[icon=inline-start]:pl-2",
136
+ xs: "aperture:h-6 aperture:gap-1 aperture:rounded-[min(--theme(--radius-md),10px)] aperture:px-2 aperture:pt-px aperture:text-xs aperture:in-data-[slot=button-group]:rounded-lg aperture:has-data-[icon=inline-end]:pr-1.5 aperture:has-data-[icon=inline-start]:pl-1.5 aperture:[&_svg:not([class*='size-'])]:size-3",
137
+ sm: "aperture:h-7 aperture:gap-1 aperture:rounded-[min(--theme(--radius-md),12px)] aperture:px-2.5 aperture:pt-px aperture:text-[0.8rem] aperture:in-data-[slot=button-group]:rounded-lg aperture:has-data-[icon=inline-end]:pr-1.5 aperture:has-data-[icon=inline-start]:pl-1.5 aperture:[&_svg:not([class*='size-'])]:size-3.5",
138
+ lg: "aperture:h-9 aperture:gap-1.5 aperture:px-2.5 aperture:pt-px aperture:has-data-[icon=inline-end]:pr-2 aperture:has-data-[icon=inline-start]:pl-2",
139
+ icon: "aperture:size-8",
140
+ "icon-xs": "aperture:size-6 aperture:rounded-[min(--theme(--radius-md),10px)] aperture:in-data-[slot=button-group]:rounded-lg aperture:[&_svg:not([class*='size-'])]:size-3",
141
+ "icon-sm": "aperture:size-7 aperture:rounded-[min(--theme(--radius-md),12px)] aperture:in-data-[slot=button-group]:rounded-lg",
142
+ "icon-lg": "aperture:size-9"
192
143
  }
193
144
  },
194
145
  defaultVariants: {
@@ -208,6 +159,18 @@ function Button$1({ className, variant = "default", size = "default", ...props }
208
159
  });
209
160
  }
210
161
  //#endregion
162
+ //#region ../ui/src/portal.tsx
163
+ const PortalContainerContext = createContext(void 0);
164
+ function PortalContainerProvider({ container, children }) {
165
+ return /* @__PURE__ */ jsx(PortalContainerContext.Provider, {
166
+ value: container,
167
+ children
168
+ });
169
+ }
170
+ function usePortalContainer() {
171
+ return useContext(PortalContainerContext);
172
+ }
173
+ //#endregion
211
174
  //#region ../ui/src/components/context-menu.tsx
212
175
  function ContextMenu$1({ ...props }) {
213
176
  return /* @__PURE__ */ jsx(ContextMenu.Root, {
@@ -218,7 +181,7 @@ function ContextMenu$1({ ...props }) {
218
181
  function ContextMenuTrigger({ className, ...props }) {
219
182
  return /* @__PURE__ */ jsx(ContextMenu.Trigger, {
220
183
  "data-slot": "context-menu-trigger",
221
- className: cn("select-none", className),
184
+ className: cn("aperture:select-none", className),
222
185
  ...props
223
186
  });
224
187
  }
@@ -226,14 +189,14 @@ function ContextMenuContent({ className, align = "start", alignOffset = 4, side
226
189
  return /* @__PURE__ */ jsx(ContextMenu.Portal, {
227
190
  container: usePortalContainer(),
228
191
  children: /* @__PURE__ */ jsx(ContextMenu.Positioner, {
229
- className: "isolate z-50 outline-none",
192
+ className: "aperture:isolate aperture:z-50 aperture:outline-none",
230
193
  align,
231
194
  alignOffset,
232
195
  side,
233
196
  sideOffset,
234
197
  children: /* @__PURE__ */ jsx(ContextMenu.Popup, {
235
198
  "data-slot": "context-menu-content",
236
- className: cn("z-50 max-h-(--available-height) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
199
+ className: cn("aperture:z-50 aperture:max-h-(--available-height) aperture:min-w-36 aperture:origin-(--transform-origin) aperture:overflow-x-hidden aperture:overflow-y-auto aperture:rounded-lg aperture:bg-popover aperture:p-1 aperture:text-popover-foreground aperture:shadow-md aperture:ring-1 aperture:ring-foreground/10 aperture:duration-100 aperture:outline-none aperture:data-[side=bottom]:slide-in-from-top-2 aperture:data-[side=inline-end]:slide-in-from-left-2 aperture:data-[side=inline-start]:slide-in-from-right-2 aperture:data-[side=left]:slide-in-from-right-2 aperture:data-[side=right]:slide-in-from-left-2 aperture:data-[side=top]:slide-in-from-bottom-2 aperture:data-open:animate-in aperture:data-open:fade-in-0 aperture:data-open:zoom-in-95 aperture:data-closed:animate-out aperture:data-closed:fade-out-0 aperture:data-closed:zoom-out-95", className),
237
200
  ...props
238
201
  })
239
202
  })
@@ -249,7 +212,7 @@ function ContextMenuLabel({ className, inset, ...props }) {
249
212
  return /* @__PURE__ */ jsx(ContextMenu.GroupLabel, {
250
213
  "data-slot": "context-menu-label",
251
214
  "data-inset": inset,
252
- className: cn("px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7", className),
215
+ className: cn("aperture:px-1.5 aperture:py-1 aperture:text-xs aperture:font-medium aperture:text-muted-foreground aperture:data-inset:pl-7", className),
253
216
  ...props
254
217
  });
255
218
  }
@@ -258,7 +221,7 @@ function ContextMenuItem({ className, inset, variant = "default", ...props }) {
258
221
  "data-slot": "context-menu-item",
259
222
  "data-inset": inset,
260
223
  "data-variant": variant,
261
- className: cn("group/context-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 focus:*:[svg]:text-accent-foreground data-[variant=destructive]:*:[svg]:text-destructive", className),
224
+ className: cn("aperture:group/context-menu-item aperture:relative aperture:flex aperture:cursor-default aperture:items-center aperture:gap-1.5 aperture:rounded-md aperture:px-1.5 aperture:py-1 aperture:text-sm aperture:outline-hidden aperture:select-none aperture:focus:bg-accent aperture:focus:text-accent-foreground aperture:data-inset:pl-7 aperture:data-[variant=destructive]:text-destructive aperture:data-[variant=destructive]:focus:bg-destructive/10 aperture:data-[variant=destructive]:focus:text-destructive aperture:dark:data-[variant=destructive]:focus:bg-destructive/20 aperture:data-disabled:pointer-events-none aperture:data-disabled:opacity-50 aperture:[&_svg]:pointer-events-none aperture:[&_svg]:shrink-0 aperture:[&_svg:not([class*='size-'])]:size-4 aperture:focus:*:[svg]:text-accent-foreground aperture:data-[variant=destructive]:*:[svg]:text-destructive", className),
262
225
  ...props
263
226
  });
264
227
  }
@@ -272,10 +235,10 @@ function ContextMenuRadioItem({ className, children, inset, ...props }) {
272
235
  return /* @__PURE__ */ jsxs(ContextMenu.RadioItem, {
273
236
  "data-slot": "context-menu-radio-item",
274
237
  "data-inset": inset,
275
- className: cn("relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
238
+ className: cn("aperture:relative aperture:flex aperture:cursor-default aperture:items-center aperture:gap-1.5 aperture:rounded-md aperture:py-1 aperture:pr-8 aperture:pl-1.5 aperture:text-sm aperture:outline-hidden aperture:select-none aperture:focus:bg-accent aperture:focus:text-accent-foreground aperture:data-inset:pl-7 aperture:data-disabled:pointer-events-none aperture:data-disabled:opacity-50 aperture:[&_svg]:pointer-events-none aperture:[&_svg]:shrink-0 aperture:[&_svg:not([class*='size-'])]:size-4", className),
276
239
  ...props,
277
240
  children: [/* @__PURE__ */ jsx("span", {
278
- className: "pointer-events-none absolute right-2",
241
+ className: "aperture:pointer-events-none aperture:absolute aperture:right-2",
279
242
  children: /* @__PURE__ */ jsx(ContextMenu.RadioItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, {}) })
280
243
  }), children]
281
244
  });
@@ -283,7 +246,7 @@ function ContextMenuRadioItem({ className, children, inset, ...props }) {
283
246
  function ContextMenuSeparator({ className, ...props }) {
284
247
  return /* @__PURE__ */ jsx(ContextMenu.Separator, {
285
248
  "data-slot": "context-menu-separator",
286
- className: cn("-mx-1 my-1 h-px bg-border", className),
249
+ className: cn("aperture:-mx-1 aperture:my-1 aperture:h-px aperture:bg-border", className),
287
250
  ...props
288
251
  });
289
252
  }
@@ -293,7 +256,7 @@ function Input$1({ className, type, ...props }) {
293
256
  return /* @__PURE__ */ jsx(Input, {
294
257
  type,
295
258
  "data-slot": "input",
296
- className: cn("h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40", className),
259
+ className: cn("aperture:h-8 aperture:w-full aperture:min-w-0 aperture:rounded-lg aperture:border aperture:border-input aperture:bg-transparent aperture:px-2.5 aperture:py-1 aperture:text-base aperture:transition-colors aperture:outline-none aperture:file:inline-flex aperture:file:h-6 aperture:file:border-0 aperture:file:bg-transparent aperture:file:text-sm aperture:file:font-medium aperture:file:text-foreground aperture:placeholder:text-muted-foreground aperture:focus-visible:border-ring aperture:focus-visible:ring-3 aperture:focus-visible:ring-ring/50 aperture:disabled:pointer-events-none aperture:disabled:cursor-not-allowed aperture:disabled:bg-input/50 aperture:disabled:opacity-50 aperture:aria-invalid:border-destructive aperture:aria-invalid:ring-3 aperture:aria-invalid:ring-destructive/20 aperture:md:text-sm aperture:dark:bg-input/30 aperture:dark:disabled:bg-input/80 aperture:dark:aria-invalid:border-destructive/50 aperture:dark:aria-invalid:ring-destructive/40", className),
297
260
  ...props
298
261
  });
299
262
  }
@@ -303,52 +266,125 @@ function InputGroup({ className, ...props }) {
303
266
  return /* @__PURE__ */ jsx("div", {
304
267
  "data-slot": "input-group",
305
268
  role: "group",
306
- className: cn("group/input-group relative flex h-8 w-full min-w-0 items-center rounded-lg border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5", className),
269
+ className: cn("aperture:group/input-group aperture:relative aperture:flex aperture:h-8 aperture:w-full aperture:min-w-0 aperture:items-center aperture:rounded-lg aperture:border aperture:border-input aperture:transition-colors aperture:outline-none aperture:in-data-[slot=combobox-content]:focus-within:border-inherit aperture:in-data-[slot=combobox-content]:focus-within:ring-0 aperture:has-disabled:bg-input/50 aperture:has-disabled:opacity-50 aperture:has-[[data-slot=input-group-control]:focus-visible]:border-ring aperture:has-[[data-slot=input-group-control]:focus-visible]:ring-3 aperture:has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 aperture:has-[[data-slot][aria-invalid=true]]:border-destructive aperture:has-[[data-slot][aria-invalid=true]]:ring-3 aperture:has-[[data-slot][aria-invalid=true]]:ring-destructive/20 aperture:has-[>[data-align=block-end]]:h-auto aperture:has-[>[data-align=block-end]]:flex-col aperture:has-[>[data-align=block-start]]:h-auto aperture:has-[>[data-align=block-start]]:flex-col aperture:has-[>textarea]:h-auto aperture:dark:bg-input/30 aperture:dark:has-disabled:bg-input/80 aperture:dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 aperture:has-[>[data-align=block-end]]:[&>input]:pt-3 aperture:has-[>[data-align=block-start]]:[&>input]:pb-3 aperture:has-[>[data-align=inline-end]]:[&>input]:pr-1.5 aperture:has-[>[data-align=inline-start]]:[&>input]:pl-1.5", className),
307
270
  ...props
308
271
  });
309
272
  }
310
- cva("flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4", {
273
+ cva("aperture:flex aperture:h-auto aperture:cursor-text aperture:items-center aperture:justify-center aperture:gap-2 aperture:py-1.5 aperture:text-sm aperture:font-medium aperture:text-muted-foreground aperture:select-none aperture:group-data-[disabled=true]/input-group:opacity-50 aperture:[&>kbd]:rounded-[calc(var(--radius)-5px)] aperture:[&>svg:not([class*='size-'])]:size-4", {
311
274
  variants: { align: {
312
- "inline-start": "order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]",
313
- "inline-end": "order-last pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]",
314
- "block-start": "order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
315
- "block-end": "order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2"
275
+ "inline-start": "aperture:order-first aperture:pl-2 aperture:has-[>button]:ml-[-0.3rem] aperture:has-[>kbd]:ml-[-0.15rem]",
276
+ "inline-end": "aperture:order-last aperture:pr-2 aperture:has-[>button]:mr-[-0.3rem] aperture:has-[>kbd]:mr-[-0.15rem]",
277
+ "block-start": "aperture:order-first aperture:w-full aperture:justify-start aperture:px-2.5 aperture:pt-2 aperture:group-has-[>input]/input-group:pt-2 aperture:[[class~='aperture:border-b']]:pb-2",
278
+ "block-end": "aperture:order-last aperture:w-full aperture:justify-start aperture:px-2.5 aperture:pb-2 aperture:group-has-[>input]/input-group:pb-2 aperture:[[class~='aperture:border-t']]:pt-2"
316
279
  } },
317
280
  defaultVariants: { align: "inline-start" }
318
281
  });
319
- cva("flex items-center gap-2 text-sm shadow-none", {
282
+ cva("aperture:flex aperture:items-center aperture:gap-2 aperture:text-sm aperture:shadow-none", {
320
283
  variants: { size: {
321
- xs: "h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
284
+ xs: "aperture:h-6 aperture:gap-1 aperture:rounded-[calc(var(--radius)-3px)] aperture:px-1.5 aperture:[&>svg:not([class*='size-'])]:size-3.5",
322
285
  sm: "",
323
- "icon-xs": "size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0",
324
- "icon-sm": "size-8 p-0 has-[>svg]:p-0"
286
+ "icon-xs": "aperture:size-6 aperture:rounded-[calc(var(--radius)-3px)] aperture:p-0 aperture:has-[>svg]:p-0",
287
+ "icon-sm": "aperture:size-8 aperture:p-0 aperture:has-[>svg]:p-0"
325
288
  } },
326
289
  defaultVariants: { size: "xs" }
327
290
  });
328
291
  function InputGroupInput({ className, ...props }) {
329
292
  return /* @__PURE__ */ jsx(Input$1, {
330
293
  "data-slot": "input-group-control",
331
- className: cn("flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent", className),
294
+ className: cn("aperture:flex-1 aperture:rounded-none aperture:border-0 aperture:bg-transparent aperture:shadow-none aperture:ring-0 aperture:focus-visible:ring-0 aperture:disabled:bg-transparent aperture:aria-invalid:ring-0 aperture:dark:bg-transparent aperture:dark:disabled:bg-transparent", className),
332
295
  ...props
333
296
  });
334
297
  }
335
298
  //#endregion
299
+ //#region ../ui/src/components/tooltip.tsx
300
+ function TooltipProvider({ delay = 0, ...props }) {
301
+ return /* @__PURE__ */ jsx(Tooltip.Provider, {
302
+ "data-slot": "tooltip-provider",
303
+ delay,
304
+ ...props
305
+ });
306
+ }
307
+ function Tooltip$1({ ...props }) {
308
+ return /* @__PURE__ */ jsx(Tooltip.Root, {
309
+ "data-slot": "tooltip",
310
+ ...props
311
+ });
312
+ }
313
+ function TooltipTrigger({ ...props }) {
314
+ return /* @__PURE__ */ jsx(Tooltip.Trigger, {
315
+ "data-slot": "tooltip-trigger",
316
+ ...props
317
+ });
318
+ }
319
+ function TooltipContent({ className, side = "top", sideOffset = 4, align = "center", alignOffset = 0, children, ...props }) {
320
+ return /* @__PURE__ */ jsx(Tooltip.Portal, {
321
+ container: usePortalContainer(),
322
+ children: /* @__PURE__ */ jsx(Tooltip.Positioner, {
323
+ align,
324
+ alignOffset,
325
+ side,
326
+ sideOffset,
327
+ className: "aperture:isolate aperture:z-50",
328
+ children: /* @__PURE__ */ jsxs(Tooltip.Popup, {
329
+ "data-slot": "tooltip-content",
330
+ className: cn("aperture:z-50 aperture:inline-flex aperture:w-fit aperture:max-w-xs aperture:origin-(--transform-origin) aperture:items-center aperture:gap-1.5 aperture:rounded-md aperture:bg-foreground aperture:px-3 aperture:py-1.5 aperture:text-xs aperture:text-background aperture:has-data-[slot=kbd]:pr-1.5 aperture:data-[side=bottom]:slide-in-from-top-2 aperture:data-[side=inline-end]:slide-in-from-left-2 aperture:data-[side=inline-start]:slide-in-from-right-2 aperture:data-[side=left]:slide-in-from-right-2 aperture:data-[side=right]:slide-in-from-left-2 aperture:data-[side=top]:slide-in-from-bottom-2 aperture:**:data-[slot=kbd]:relative aperture:**:data-[slot=kbd]:isolate aperture:**:data-[slot=kbd]:z-50 aperture:**:data-[slot=kbd]:rounded-sm aperture:data-[state=delayed-open]:animate-in aperture:data-[state=delayed-open]:fade-in-0 aperture:data-[state=delayed-open]:zoom-in-95 aperture:data-open:animate-in aperture:data-open:fade-in-0 aperture:data-open:zoom-in-95 aperture:data-closed:animate-out aperture:data-closed:fade-out-0 aperture:data-closed:zoom-out-95", className),
331
+ ...props,
332
+ children: [children, /* @__PURE__ */ jsx(Tooltip.Arrow, { className: "aperture:z-50 aperture:size-2.5 aperture:translate-y-[calc(-50%-2px)] aperture:rotate-45 aperture:rounded-[2px] aperture:bg-foreground aperture:fill-foreground aperture:data-[side=bottom]:top-1 aperture:data-[side=inline-end]:top-1/2! aperture:data-[side=inline-end]:-left-1 aperture:data-[side=inline-end]:-translate-y-1/2 aperture:data-[side=inline-start]:top-1/2! aperture:data-[side=inline-start]:-right-1 aperture:data-[side=inline-start]:-translate-y-1/2 aperture:data-[side=left]:top-1/2! aperture:data-[side=left]:-right-1 aperture:data-[side=left]:-translate-y-1/2 aperture:data-[side=right]:top-1/2! aperture:data-[side=right]:-left-1 aperture:data-[side=right]:-translate-y-1/2 aperture:data-[side=top]:-bottom-2.5" })]
333
+ })
334
+ })
335
+ });
336
+ }
337
+ //#endregion
338
+ //#region ../ui/src/components/hover-card.tsx
339
+ function HoverCard(props) {
340
+ return /* @__PURE__ */ jsx(PreviewCard.Root, {
341
+ "data-slot": "hover-card",
342
+ ...props
343
+ });
344
+ }
345
+ function HoverCardTrigger(props) {
346
+ return /* @__PURE__ */ jsx(PreviewCard.Trigger, {
347
+ "data-slot": "hover-card-trigger",
348
+ ...props
349
+ });
350
+ }
351
+ function HoverCardContent({ className, side = "bottom", sideOffset = 4, align = "center", alignOffset = 0, collisionPadding, ...props }) {
352
+ return /* @__PURE__ */ jsx(PreviewCard.Portal, {
353
+ container: usePortalContainer(),
354
+ children: /* @__PURE__ */ jsx(PreviewCard.Positioner, {
355
+ align,
356
+ alignOffset,
357
+ side,
358
+ sideOffset,
359
+ collisionPadding,
360
+ className: "aperture:isolate aperture:z-50",
361
+ children: /* @__PURE__ */ jsx(PreviewCard.Popup, {
362
+ "data-slot": "hover-card-content",
363
+ className: cn("aperture:z-50 aperture:w-64 aperture:rounded-lg aperture:bg-popover aperture:p-2.5 aperture:text-sm aperture:text-popover-foreground aperture:shadow-md aperture:ring-1 aperture:ring-foreground/10 aperture:outline-hidden", className),
364
+ ...props
365
+ })
366
+ })
367
+ });
368
+ }
369
+ const createHoverCardHandle = PreviewCard.createHandle;
370
+ //#endregion
336
371
  //#region ../ui/src/components/scroll-area.tsx
337
- function ScrollArea$1({ className, viewportClassName, scrollbars = "vertical", children, ...props }) {
372
+ function ScrollArea$1({ className, viewportClassName, viewportRef, scrollbars = "vertical", children, ...props }) {
338
373
  const vertical = scrollbars === "vertical" || scrollbars === "both";
339
374
  const horizontal = scrollbars === "horizontal" || scrollbars === "both";
340
375
  return /* @__PURE__ */ jsxs(ScrollArea.Root, {
341
376
  "data-slot": "scroll-area",
342
- className: cn("relative", className),
377
+ className: cn("aperture:relative", className),
343
378
  ...props,
344
379
  children: [
345
380
  /* @__PURE__ */ jsx(ScrollArea.Viewport, {
381
+ ref: viewportRef,
346
382
  "data-slot": "scroll-area-viewport",
347
383
  style: {
348
384
  overflowX: horizontal ? "scroll" : "hidden",
349
385
  overflowY: vertical ? "scroll" : "hidden"
350
386
  },
351
- className: cn("size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1", viewportClassName),
387
+ className: cn("aperture:size-full aperture:rounded-[inherit] aperture:transition-[color,box-shadow] aperture:outline-none aperture:focus-visible:ring-[3px] aperture:focus-visible:ring-ring/50 aperture:focus-visible:outline-1", viewportClassName),
352
388
  children
353
389
  }),
354
390
  vertical ? /* @__PURE__ */ jsx(ScrollBar, {}) : null,
@@ -362,11 +398,11 @@ function ScrollBar({ className, orientation = "vertical", ...props }) {
362
398
  "data-slot": "scroll-area-scrollbar",
363
399
  "data-orientation": orientation,
364
400
  orientation,
365
- className: cn("flex touch-none p-px transition-colors select-none hover:bg-muted/50 data-[orientation=horizontal]:h-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:border-t data-[orientation=horizontal]:border-t-transparent data-[orientation=vertical]:h-full data-[orientation=vertical]:w-2.5 data-[orientation=vertical]:border-l data-[orientation=vertical]:border-l-transparent", className),
401
+ className: cn("aperture:flex aperture:touch-none aperture:p-px aperture:transition-colors aperture:select-none aperture:hover:bg-muted/50 aperture:data-[orientation=horizontal]:h-2.5 aperture:data-[orientation=horizontal]:flex-col aperture:data-[orientation=horizontal]:border-t aperture:data-[orientation=horizontal]:border-t-transparent aperture:data-[orientation=vertical]:h-full aperture:data-[orientation=vertical]:w-2.5 aperture:data-[orientation=vertical]:border-l aperture:data-[orientation=vertical]:border-l-transparent", className),
366
402
  ...props,
367
403
  children: /* @__PURE__ */ jsx(ScrollArea.Thumb, {
368
404
  "data-slot": "scroll-area-thumb",
369
- className: "relative flex-1 rounded-full bg-foreground/35 transition-colors hover:bg-foreground/55"
405
+ className: "aperture:relative aperture:flex-1 aperture:rounded-full aperture:bg-foreground/35 aperture:transition-colors aperture:hover:bg-foreground/55"
370
406
  })
371
407
  });
372
408
  }
@@ -402,19 +438,20 @@ const copyTextWithToast = (value, onCopied = () => {}) => copyText(value).pipe(E
402
438
  //#endregion
403
439
  //#region src/components/browser-tab-strip.tsx
404
440
  const BROWSER_TAB_DRAG_KIND = "browser-tab";
405
- function BrowserTabStrip({ targets, activeTargetId, recordingTargetIds, devToolsTargetIds, disabled, mutationDisabled, onActivate, onCreate, onDuplicate, onClose, onReload, onReorder }) {
441
+ function BrowserTabStrip({ targets, activeTargetId, recordingTargetIds, devToolsTargetIds, disabled, mutationDisabled, onActivate, onCreate, onDuplicate, onClose, onReload, onReorder, loadThumbnail = null }) {
442
+ const [previewHandle] = useState(() => createHoverCardHandle());
406
443
  if (targets.length === 0) return /* @__PURE__ */ jsxs("div", {
407
- className: "flex h-8 min-w-0 flex-1 items-center gap-2 px-2 text-xs text-muted-foreground",
444
+ className: "aperture:flex aperture:h-8 aperture:min-w-0 aperture:flex-1 aperture:items-center aperture:gap-2 aperture:px-2 aperture:text-xs aperture:text-muted-foreground",
408
445
  children: [/* @__PURE__ */ jsx("span", { children: "No tabs" }), /* @__PURE__ */ jsx(NewTabButton, {
409
446
  disabled: disabled || mutationDisabled,
410
447
  onCreate
411
448
  })]
412
449
  });
413
- return /* @__PURE__ */ jsx(ScrollArea$1, {
450
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ScrollArea$1, {
414
451
  scrollbars: "horizontal",
415
- className: "h-8 min-w-0 flex-1",
452
+ className: "aperture:h-8 aperture:min-w-0 aperture:flex-1",
416
453
  children: /* @__PURE__ */ jsxs("div", {
417
- className: "flex min-w-max items-end gap-0.5 px-1 pt-1",
454
+ className: "aperture:flex aperture:min-w-max aperture:items-end aperture:gap-0.5 aperture:px-1 aperture:pt-1",
418
455
  children: [targets.map((target, index) => {
419
456
  return /* @__PURE__ */ jsx(BrowserTab, {
420
457
  target,
@@ -428,6 +465,7 @@ function BrowserTabStrip({ targets, activeTargetId, recordingTargetIds, devTools
428
465
  onClose,
429
466
  onReload,
430
467
  onReorder,
468
+ previewHandle: loadThumbnail ? previewHandle : null,
431
469
  closeOtherTargetIds: targets.filter((current) => current.id !== target.id).map((current) => current.id),
432
470
  closeRightTargetIds: targets.slice(index + 1).map((current) => current.id)
433
471
  }, target.id);
@@ -436,9 +474,18 @@ function BrowserTabStrip({ targets, activeTargetId, recordingTargetIds, devTools
436
474
  onCreate
437
475
  })]
438
476
  })
439
- });
477
+ }), loadThumbnail ? /* @__PURE__ */ jsx(HoverCard, {
478
+ handle: previewHandle,
479
+ children: ({ payload }) => {
480
+ const target = targets.find((current) => current.id === payload);
481
+ return target ? /* @__PURE__ */ jsx(TabPreview, {
482
+ target,
483
+ loadThumbnail
484
+ }, target.id) : null;
485
+ }
486
+ }) : null] });
440
487
  }
441
- function BrowserTab({ target, active, recording, devToolsOpen, disabled, mutationDisabled, onActivate, onDuplicate, onClose, onReload, onReorder, closeOtherTargetIds, closeRightTargetIds }) {
488
+ function BrowserTab({ target, active, recording, devToolsOpen, disabled, mutationDisabled, onActivate, onDuplicate, onClose, onReload, onReorder, previewHandle, closeOtherTargetIds, closeRightTargetIds }) {
442
489
  const tabRef = useRef(null);
443
490
  const [dragging, setDragging] = useState(false);
444
491
  const [dropPlacement, setDropPlacement] = useState(null);
@@ -478,49 +525,55 @@ function BrowserTab({ target, active, recording, devToolsOpen, disabled, mutatio
478
525
  }
479
526
  }));
480
527
  }, [onReorder, target.id]);
481
- return /* @__PURE__ */ jsxs(ContextMenu$1, { children: [/* @__PURE__ */ jsxs(ContextMenuTrigger, {
482
- render: /* @__PURE__ */ jsx("div", {
483
- ref: tabRef,
484
- "data-browser-tab": true,
485
- className: cn("group relative flex h-7 w-52 max-w-[38vw] min-w-28 cursor-grab select-none items-center gap-1.5 rounded-t-lg border border-b-0 px-2 text-left text-xs transition-[background-color,border-color,color,opacity] active:cursor-grabbing", active ? "border-border bg-background text-foreground" : "border-transparent bg-muted/55 text-muted-foreground hover:bg-muted", dragging && "opacity-60"),
486
- title: target.url || "about:blank",
487
- onMouseDown: (event) => {
488
- if (event.button === 1) event.preventDefault();
489
- },
490
- onAuxClick: (event) => {
491
- if (event.button === 1 && !disabled && !mutationDisabled) {
492
- event.preventDefault();
493
- onClose(target.id);
494
- }
528
+ const tab = /* @__PURE__ */ jsx("div", {
529
+ ref: tabRef,
530
+ "data-browser-tab": true,
531
+ className: cn("aperture:group aperture:relative aperture:flex aperture:h-7 aperture:w-52 aperture:max-w-[38vw] aperture:min-w-28 aperture:cursor-grab aperture:select-none aperture:items-center aperture:gap-1.5 aperture:rounded-t-lg aperture:border aperture:border-b-0 aperture:px-2 aperture:text-left aperture:text-xs aperture:transition-[background-color,border-color,color,opacity] aperture:active:cursor-grabbing", active ? "aperture:border-border aperture:bg-background aperture:text-foreground" : "aperture:border-transparent aperture:bg-muted/55 aperture:text-muted-foreground aperture:hover:bg-muted", dragging && "aperture:opacity-60"),
532
+ onMouseDown: (event) => {
533
+ if (event.button === 1) event.preventDefault();
534
+ },
535
+ onAuxClick: (event) => {
536
+ if (event.button === 1 && !disabled && !mutationDisabled) {
537
+ event.preventDefault();
538
+ onClose(target.id);
495
539
  }
496
- }),
540
+ }
541
+ });
542
+ return /* @__PURE__ */ jsxs(ContextMenu$1, { children: [/* @__PURE__ */ jsxs(ContextMenuTrigger, {
543
+ render: previewHandle ? /* @__PURE__ */ jsx(HoverCardTrigger, {
544
+ handle: previewHandle,
545
+ payload: target.id,
546
+ delay: 0,
547
+ closeDelay: 0,
548
+ render: tab
549
+ }) : tab,
497
550
  children: [
498
- /* @__PURE__ */ jsx("span", { className: cn("pointer-events-none absolute inset-y-1 left-0 w-0.5 rounded-full bg-primary opacity-0", dropPlacement === "before" && "opacity-100") }),
499
- /* @__PURE__ */ jsx("span", { className: cn("pointer-events-none absolute inset-y-1 right-0 w-0.5 rounded-full bg-primary opacity-0", dropPlacement === "after" && "opacity-100") }),
551
+ /* @__PURE__ */ jsx("span", { className: cn("aperture:pointer-events-none aperture:absolute aperture:inset-y-1 aperture:left-0 aperture:w-0.5 aperture:rounded-full aperture:bg-primary aperture:opacity-0", dropPlacement === "before" && "aperture:opacity-100") }),
552
+ /* @__PURE__ */ jsx("span", { className: cn("aperture:pointer-events-none aperture:absolute aperture:inset-y-1 aperture:right-0 aperture:w-0.5 aperture:rounded-full aperture:bg-primary aperture:opacity-0", dropPlacement === "after" && "aperture:opacity-100") }),
500
553
  /* @__PURE__ */ jsxs("button", {
501
554
  type: "button",
502
555
  "aria-current": active ? "page" : void 0,
503
556
  disabled,
504
- className: "flex min-w-0 flex-1 items-center gap-1.5 text-left",
557
+ className: "aperture:flex aperture:min-w-0 aperture:flex-1 aperture:items-center aperture:gap-1.5 aperture:text-left",
505
558
  onClick: () => onActivate(target.id),
506
559
  children: [
507
560
  /* @__PURE__ */ jsx(TabFavicon, { url: target.url }),
508
561
  devToolsOpen ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Wrench, {
509
562
  "aria-hidden": true,
510
- className: "size-3.5 shrink-0 text-muted-foreground"
563
+ className: "aperture:size-3.5 aperture:shrink-0 aperture:text-muted-foreground"
511
564
  }), /* @__PURE__ */ jsx("span", {
512
- className: "sr-only",
565
+ className: "aperture:sr-only",
513
566
  children: "DevTools open"
514
567
  })] }) : null,
515
568
  recording ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
516
569
  "aria-hidden": true,
517
- className: "size-2 shrink-0 rounded-full bg-destructive"
570
+ className: "aperture:size-2 aperture:shrink-0 aperture:rounded-full aperture:bg-destructive"
518
571
  }), /* @__PURE__ */ jsx("span", {
519
- className: "sr-only",
572
+ className: "aperture:sr-only",
520
573
  children: "Recording"
521
574
  })] }) : null,
522
575
  /* @__PURE__ */ jsx("span", {
523
- className: "min-w-0 truncate font-mono",
576
+ className: "aperture:min-w-0 aperture:truncate aperture:font-mono",
524
577
  children: label
525
578
  })
526
579
  ]
@@ -530,7 +583,7 @@ function BrowserTab({ target, active, recording, devToolsOpen, disabled, mutatio
530
583
  type: "button",
531
584
  variant: "ghost",
532
585
  size: "icon-xs",
533
- className: "shrink-0 opacity-55 hover:opacity-100 group-hover:opacity-100",
586
+ className: "aperture:shrink-0 aperture:opacity-55 aperture:hover:opacity-100 aperture:group-hover:opacity-100",
534
587
  "aria-label": "Close tab",
535
588
  disabled: disabled || mutationDisabled,
536
589
  onClick: () => onClose(target.id)
@@ -542,7 +595,7 @@ function BrowserTab({ target, active, recording, devToolsOpen, disabled, mutatio
542
595
  })] })
543
596
  ]
544
597
  }), /* @__PURE__ */ jsxs(ContextMenuContent, {
545
- className: "min-w-48",
598
+ className: "aperture:min-w-48",
546
599
  children: [
547
600
  /* @__PURE__ */ jsxs(ContextMenuGroup, { children: [
548
601
  /* @__PURE__ */ jsx(ContextMenuItem, {
@@ -591,7 +644,7 @@ function NewTabButton({ disabled, onCreate }) {
591
644
  type: "button",
592
645
  variant: "ghost",
593
646
  size: "icon-xs",
594
- className: "mb-px shrink-0",
647
+ className: "aperture:mb-px aperture:shrink-0",
595
648
  "aria-label": "New tab",
596
649
  disabled,
597
650
  onClick: onCreate
@@ -608,11 +661,11 @@ function TabFavicon({ url }) {
608
661
  useEffect(() => {
609
662
  setFailed(false);
610
663
  }, [faviconUrl]);
611
- if (!faviconUrl || failed) return /* @__PURE__ */ jsx(Globe2, { className: "size-4 shrink-0 text-muted-foreground" });
664
+ if (!faviconUrl || failed) return /* @__PURE__ */ jsx(Globe2, { className: "aperture:size-4 aperture:shrink-0 aperture:text-muted-foreground" });
612
665
  return /* @__PURE__ */ jsx("img", {
613
666
  src: faviconUrl,
614
667
  alt: "",
615
- className: "size-4 shrink-0",
668
+ className: "aperture:size-4 aperture:shrink-0",
616
669
  onError: () => setFailed(true)
617
670
  });
618
671
  }
@@ -641,12 +694,53 @@ function dropPlacementFromClientX(element, clientX) {
641
694
  const rect = element.getBoundingClientRect();
642
695
  return clientX < rect.left + rect.width / 2 ? "before" : "after";
643
696
  }
697
+ function TabPreview({ target, loadThumbnail }) {
698
+ return /* @__PURE__ */ jsxs(HoverCardContent, {
699
+ "data-browser-tab-preview": true,
700
+ align: "start",
701
+ sideOffset: 8,
702
+ collisionPadding: 16,
703
+ className: "aperture:pointer-events-none aperture:flex aperture:w-80 aperture:max-w-[calc(100vw-2rem)] aperture:flex-col aperture:gap-2 aperture:p-2",
704
+ children: [
705
+ /* @__PURE__ */ jsx(TabThumbnail, {
706
+ targetId: target.id,
707
+ loadThumbnail
708
+ }),
709
+ /* @__PURE__ */ jsx("span", {
710
+ className: "aperture:truncate aperture:text-xs aperture:font-medium",
711
+ children: target.title || simplifyUrl(target.url)
712
+ }),
713
+ /* @__PURE__ */ jsx("span", {
714
+ className: "aperture:truncate aperture:font-mono aperture:text-xs aperture:text-muted-foreground",
715
+ children: target.url || "about:blank"
716
+ })
717
+ ]
718
+ });
719
+ }
720
+ function TabThumbnail({ targetId, loadThumbnail }) {
721
+ const [src, setSrc] = useState(null);
722
+ useFork(() => Effect.gen(function* () {
723
+ const blob = yield* loadThumbnail(targetId);
724
+ const objectUrl = URL.createObjectURL(blob);
725
+ yield* Effect.addFinalizer(() => Effect.sync(() => URL.revokeObjectURL(objectUrl)));
726
+ setSrc(objectUrl);
727
+ return yield* Effect.never;
728
+ }).pipe(Effect.catch(() => Effect.void), Effect.scoped), [loadThumbnail, targetId]);
729
+ return /* @__PURE__ */ jsx("div", {
730
+ className: "aperture:aspect-video aperture:w-full aperture:overflow-hidden aperture:rounded-md aperture:bg-muted",
731
+ children: src ? /* @__PURE__ */ jsx("img", {
732
+ src,
733
+ alt: "",
734
+ className: "aperture:size-full aperture:object-cover aperture:object-top"
735
+ }) : null
736
+ });
737
+ }
644
738
  //#endregion
645
739
  //#region ../ui/src/components/label.tsx
646
740
  function Label({ className, ...props }) {
647
741
  return /* @__PURE__ */ jsx("label", {
648
742
  "data-slot": "label",
649
- className: cn("flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className),
743
+ className: cn("aperture:flex aperture:items-center aperture:gap-2 aperture:text-sm aperture:leading-none aperture:font-medium aperture:select-none aperture:group-data-[disabled=true]:pointer-events-none aperture:group-data-[disabled=true]:opacity-50 aperture:peer-disabled:cursor-not-allowed aperture:peer-disabled:opacity-50", className),
650
744
  ...props
651
745
  });
652
746
  }
@@ -655,15 +749,15 @@ function Label({ className, ...props }) {
655
749
  function FieldGroup({ className, ...props }) {
656
750
  return /* @__PURE__ */ jsx("div", {
657
751
  "data-slot": "field-group",
658
- className: cn("group/field-group @container/field-group flex w-full flex-col gap-5 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4", className),
752
+ className: cn("aperture:group/field-group aperture:@container/field-group aperture:flex aperture:w-full aperture:flex-col aperture:gap-5 aperture:data-[slot=checkbox-group]:gap-3 aperture:*:data-[slot=field-group]:gap-4", className),
659
753
  ...props
660
754
  });
661
755
  }
662
- const fieldVariants = cva("group/field flex w-full gap-2 data-[invalid=true]:text-destructive", {
756
+ const fieldVariants = cva("aperture:group/field aperture:flex aperture:w-full aperture:gap-2 aperture:data-[invalid=true]:text-destructive", {
663
757
  variants: { orientation: {
664
- vertical: "flex-col *:w-full [&>.sr-only]:w-auto",
665
- horizontal: "flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
666
- responsive: "flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px"
758
+ vertical: "aperture:flex-col aperture:*:w-full aperture:[&>.sr-only]:w-auto",
759
+ horizontal: "aperture:flex-row aperture:items-center aperture:has-[>[data-slot=field-content]]:items-start aperture:*:data-[slot=field-label]:flex-auto aperture:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
760
+ responsive: "aperture:flex-col aperture:*:w-full aperture:@md/field-group:flex-row aperture:@md/field-group:items-center aperture:@md/field-group:*:w-auto aperture:@md/field-group:has-[>[data-slot=field-content]]:items-start aperture:@md/field-group:*:data-[slot=field-label]:flex-auto aperture:[&>.sr-only]:w-auto aperture:@md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px"
667
761
  } },
668
762
  defaultVariants: { orientation: "vertical" }
669
763
  });
@@ -679,7 +773,7 @@ function Field({ className, orientation = "vertical", ...props }) {
679
773
  function FieldLabel({ className, ...props }) {
680
774
  return /* @__PURE__ */ jsx(Label, {
681
775
  "data-slot": "field-label",
682
- className: cn("group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:border-primary/30 has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded-lg has-[>[data-slot=field]]:border *:data-[slot=field]:p-2.5 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10", "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col", className),
776
+ className: cn("aperture:group/field-label aperture:peer/field-label aperture:flex aperture:w-fit aperture:gap-2 aperture:leading-snug aperture:group-data-[disabled=true]/field:opacity-50 aperture:has-data-checked:border-primary/30 aperture:has-data-checked:bg-primary/5 aperture:has-[>[data-slot=field]]:rounded-lg aperture:has-[>[data-slot=field]]:border aperture:*:data-[slot=field]:p-2.5 aperture:dark:has-data-checked:border-primary/20 aperture:dark:has-data-checked:bg-primary/10", "aperture:has-[>[data-slot=field]]:w-full aperture:has-[>[data-slot=field]]:flex-col", className),
683
777
  ...props
684
778
  });
685
779
  }
@@ -701,14 +795,14 @@ function DropdownMenuContent({ align = "start", alignOffset = 0, side = "bottom"
701
795
  return /* @__PURE__ */ jsx(Menu.Portal, {
702
796
  container: usePortalContainer(),
703
797
  children: /* @__PURE__ */ jsx(Menu.Positioner, {
704
- className: "isolate z-50 outline-none",
798
+ className: "aperture:isolate aperture:z-50 aperture:outline-none",
705
799
  align,
706
800
  alignOffset,
707
801
  side,
708
802
  sideOffset,
709
803
  children: /* @__PURE__ */ jsx(Menu.Popup, {
710
804
  "data-slot": "dropdown-menu-content",
711
- className: cn("z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95", className),
805
+ className: cn("aperture:z-50 aperture:max-h-(--available-height) aperture:w-(--anchor-width) aperture:min-w-32 aperture:origin-(--transform-origin) aperture:overflow-x-hidden aperture:overflow-y-auto aperture:rounded-lg aperture:bg-popover aperture:p-1 aperture:text-popover-foreground aperture:shadow-md aperture:ring-1 aperture:ring-foreground/10 aperture:duration-100 aperture:outline-none aperture:data-[side=bottom]:slide-in-from-top-2 aperture:data-[side=inline-end]:slide-in-from-left-2 aperture:data-[side=inline-start]:slide-in-from-right-2 aperture:data-[side=left]:slide-in-from-right-2 aperture:data-[side=right]:slide-in-from-left-2 aperture:data-[side=top]:slide-in-from-bottom-2 aperture:data-open:animate-in aperture:data-open:fade-in-0 aperture:data-open:zoom-in-95 aperture:data-closed:animate-out aperture:data-closed:overflow-hidden aperture:data-closed:fade-out-0 aperture:data-closed:zoom-out-95", className),
712
806
  ...props
713
807
  })
714
808
  })
@@ -724,7 +818,7 @@ function DropdownMenuLabel({ className, inset, ...props }) {
724
818
  return /* @__PURE__ */ jsx("div", {
725
819
  "data-slot": "dropdown-menu-label",
726
820
  "data-inset": inset,
727
- className: cn("px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7", className),
821
+ className: cn("aperture:px-1.5 aperture:py-1 aperture:text-xs aperture:font-medium aperture:text-muted-foreground aperture:data-inset:pl-7", className),
728
822
  ...props
729
823
  });
730
824
  }
@@ -733,7 +827,7 @@ function DropdownMenuItem({ className, inset, variant = "default", ...props }) {
733
827
  "data-slot": "dropdown-menu-item",
734
828
  "data-inset": inset,
735
829
  "data-variant": variant,
736
- className: cn("group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive", className),
830
+ className: cn("aperture:group/dropdown-menu-item aperture:relative aperture:flex aperture:cursor-default aperture:items-center aperture:gap-1.5 aperture:rounded-md aperture:px-1.5 aperture:py-1 aperture:text-sm aperture:outline-hidden aperture:select-none aperture:focus:bg-accent aperture:focus:text-accent-foreground aperture:not-data-[variant=destructive]:focus:**:text-accent-foreground aperture:data-inset:pl-7 aperture:data-[variant=destructive]:text-destructive aperture:data-[variant=destructive]:focus:bg-destructive/10 aperture:data-[variant=destructive]:focus:text-destructive aperture:dark:data-[variant=destructive]:focus:bg-destructive/20 aperture:data-disabled:pointer-events-none aperture:data-disabled:opacity-50 aperture:[&_svg]:pointer-events-none aperture:[&_svg]:shrink-0 aperture:[&_svg:not([class*='size-'])]:size-4 aperture:data-[variant=destructive]:*:[svg]:text-destructive", className),
737
831
  ...props
738
832
  });
739
833
  }
@@ -747,15 +841,15 @@ function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
747
841
  return /* @__PURE__ */ jsxs(Menu.SubmenuTrigger, {
748
842
  "data-slot": "dropdown-menu-sub-trigger",
749
843
  "data-inset": inset,
750
- className: cn("flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
844
+ className: cn("aperture:flex aperture:cursor-default aperture:items-center aperture:gap-1.5 aperture:rounded-md aperture:px-1.5 aperture:py-1 aperture:text-sm aperture:outline-hidden aperture:select-none aperture:focus:bg-accent aperture:focus:text-accent-foreground aperture:not-data-[variant=destructive]:focus:**:text-accent-foreground aperture:data-inset:pl-7 aperture:data-popup-open:bg-accent aperture:data-popup-open:text-accent-foreground aperture:data-open:bg-accent aperture:data-open:text-accent-foreground aperture:[&_svg]:pointer-events-none aperture:[&_svg]:shrink-0 aperture:[&_svg:not([class*='size-'])]:size-4", className),
751
845
  ...props,
752
- children: [children, /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto" })]
846
+ children: [children, /* @__PURE__ */ jsx(ChevronRightIcon, { className: "aperture:ml-auto" })]
753
847
  });
754
848
  }
755
849
  function DropdownMenuSubContent({ align = "start", alignOffset = -3, side = "right", sideOffset = 0, className, ...props }) {
756
850
  return /* @__PURE__ */ jsx(DropdownMenuContent, {
757
851
  "data-slot": "dropdown-menu-sub-content",
758
- className: cn("w-auto min-w-[96px] rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
852
+ className: cn("aperture:w-auto aperture:min-w-[96px] aperture:rounded-lg aperture:bg-popover aperture:p-1 aperture:text-popover-foreground aperture:shadow-lg aperture:ring-1 aperture:ring-foreground/10 aperture:duration-100 aperture:data-[side=bottom]:slide-in-from-top-2 aperture:data-[side=left]:slide-in-from-right-2 aperture:data-[side=right]:slide-in-from-left-2 aperture:data-[side=top]:slide-in-from-bottom-2 aperture:data-open:animate-in aperture:data-open:fade-in-0 aperture:data-open:zoom-in-95 aperture:data-closed:animate-out aperture:data-closed:fade-out-0 aperture:data-closed:zoom-out-95", className),
759
853
  align,
760
854
  alignOffset,
761
855
  side,
@@ -767,11 +861,11 @@ function DropdownMenuCheckboxItem({ className, children, checked, inset, ...prop
767
861
  return /* @__PURE__ */ jsxs(Menu.CheckboxItem, {
768
862
  "data-slot": "dropdown-menu-checkbox-item",
769
863
  "data-inset": inset,
770
- className: cn("relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
864
+ className: cn("aperture:relative aperture:flex aperture:cursor-default aperture:items-center aperture:gap-1.5 aperture:rounded-md aperture:py-1 aperture:pr-8 aperture:pl-1.5 aperture:text-sm aperture:outline-hidden aperture:select-none aperture:focus:bg-accent aperture:focus:text-accent-foreground aperture:focus:**:text-accent-foreground aperture:data-inset:pl-7 aperture:data-disabled:pointer-events-none aperture:data-disabled:opacity-50 aperture:[&_svg]:pointer-events-none aperture:[&_svg]:shrink-0 aperture:[&_svg:not([class*='size-'])]:size-4", className),
771
865
  checked,
772
866
  ...props,
773
867
  children: [/* @__PURE__ */ jsx("span", {
774
- className: "pointer-events-none absolute right-2 flex items-center justify-center",
868
+ className: "aperture:pointer-events-none aperture:absolute aperture:right-2 aperture:flex aperture:items-center aperture:justify-center",
775
869
  "data-slot": "dropdown-menu-checkbox-item-indicator",
776
870
  children: /* @__PURE__ */ jsx(Menu.CheckboxItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, {}) })
777
871
  }), children]
@@ -787,10 +881,10 @@ function DropdownMenuRadioItem({ className, children, inset, ...props }) {
787
881
  return /* @__PURE__ */ jsxs(Menu.RadioItem, {
788
882
  "data-slot": "dropdown-menu-radio-item",
789
883
  "data-inset": inset,
790
- className: cn("relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className),
884
+ className: cn("aperture:relative aperture:flex aperture:cursor-default aperture:items-center aperture:gap-1.5 aperture:rounded-md aperture:py-1 aperture:pr-8 aperture:pl-1.5 aperture:text-sm aperture:outline-hidden aperture:select-none aperture:focus:bg-accent aperture:focus:text-accent-foreground aperture:focus:**:text-accent-foreground aperture:data-inset:pl-7 aperture:data-disabled:pointer-events-none aperture:data-disabled:opacity-50 aperture:[&_svg]:pointer-events-none aperture:[&_svg]:shrink-0 aperture:[&_svg:not([class*='size-'])]:size-4", className),
791
885
  ...props,
792
886
  children: [/* @__PURE__ */ jsx("span", {
793
- className: "pointer-events-none absolute right-2 flex items-center justify-center",
887
+ className: "aperture:pointer-events-none aperture:absolute aperture:right-2 aperture:flex aperture:items-center aperture:justify-center",
794
888
  "data-slot": "dropdown-menu-radio-item-indicator",
795
889
  children: /* @__PURE__ */ jsx(Menu.RadioItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, {}) })
796
890
  }), children]
@@ -799,7 +893,7 @@ function DropdownMenuRadioItem({ className, children, inset, ...props }) {
799
893
  function DropdownMenuSeparator({ className, ...props }) {
800
894
  return /* @__PURE__ */ jsx(Menu.Separator, {
801
895
  "data-slot": "dropdown-menu-separator",
802
- className: cn("-mx-1 my-1 h-px bg-border", className),
896
+ className: cn("aperture:-mx-1 aperture:my-1 aperture:h-px aperture:bg-border", className),
803
897
  ...props
804
898
  });
805
899
  }
@@ -861,8 +955,9 @@ const VIEWPORT_LIMITS = {
861
955
  function BrowserMenus({ control, cdpUrl, shareUrls, busy, connected, localCursorEnabled, onLocalCursorChange, onReconnect, onSessionDetails, now }) {
862
956
  const runningRecordings = control.recordings.filter((recording) => recording.status === "starting" || recording.status === "running");
863
957
  const recordingActive = runningRecordings.length > 0;
958
+ const viewportConnected = connected && control.collaboration.role !== "viewer";
864
959
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
865
- className: "shrink-0 sm:hidden",
960
+ className: "aperture:shrink-0 aperture:sm:hidden",
866
961
  children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(Tooltip$1, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
867
962
  render: /* @__PURE__ */ jsx(DropdownMenuTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
868
963
  type: "button",
@@ -876,7 +971,7 @@ function BrowserMenus({ control, cdpUrl, shareUrls, busy, connected, localCursor
876
971
  children: recordingActive ? "Browser menu, recording active" : "Browser menu"
877
972
  })] }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
878
973
  align: "end",
879
- className: "w-72",
974
+ className: "aperture:w-72",
880
975
  children: [
881
976
  /* @__PURE__ */ jsx(RestMenuItems, {
882
977
  control,
@@ -887,14 +982,14 @@ function BrowserMenus({ control, cdpUrl, shareUrls, busy, connected, localCursor
887
982
  /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
888
983
  /* @__PURE__ */ jsx(RecordingMenuItems, {
889
984
  control,
890
- connected: connected && control.collaboration.role === "owner",
985
+ connected,
891
986
  runningRecordings,
892
987
  now
893
988
  }),
894
989
  /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
895
990
  /* @__PURE__ */ jsx(ViewportStreamMenuItems, {
896
991
  control,
897
- connected: connected && control.collaboration.role !== "viewer",
992
+ connected: viewportConnected,
898
993
  localCursorEnabled,
899
994
  onLocalCursorChange,
900
995
  busy,
@@ -903,7 +998,7 @@ function BrowserMenus({ control, cdpUrl, shareUrls, busy, connected, localCursor
903
998
  ]
904
999
  })] })
905
1000
  }), /* @__PURE__ */ jsxs("div", {
906
- className: "hidden shrink-0 items-center gap-0.5 sm:flex",
1001
+ className: "aperture:hidden aperture:shrink-0 aperture:items-center aperture:gap-0.5 aperture:sm:flex",
907
1002
  children: [
908
1003
  /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(Tooltip$1, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
909
1004
  render: /* @__PURE__ */ jsx(DropdownMenuTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
@@ -918,14 +1013,18 @@ function BrowserMenus({ control, cdpUrl, shareUrls, busy, connected, localCursor
918
1013
  children: recordingActive ? "Recording in progress" : "Recording"
919
1014
  })] }), /* @__PURE__ */ jsx(DropdownMenuContent, {
920
1015
  align: "end",
921
- className: "w-72",
1016
+ className: "aperture:w-72",
922
1017
  children: /* @__PURE__ */ jsx(RecordingMenuItems, {
923
1018
  control,
924
- connected: connected && control.collaboration.role === "owner",
1019
+ connected,
925
1020
  runningRecordings,
926
1021
  now
927
1022
  })
928
1023
  })] }),
1024
+ /* @__PURE__ */ jsx(ViewportPausedIndicator, {
1025
+ control,
1026
+ connected: viewportConnected
1027
+ }),
929
1028
  /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(Tooltip$1, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
930
1029
  render: /* @__PURE__ */ jsx(DropdownMenuTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
931
1030
  type: "button",
@@ -939,10 +1038,10 @@ function BrowserMenus({ control, cdpUrl, shareUrls, busy, connected, localCursor
939
1038
  children: "Viewport and stream"
940
1039
  })] }), /* @__PURE__ */ jsx(DropdownMenuContent, {
941
1040
  align: "end",
942
- className: "w-56",
1041
+ className: "aperture:w-56",
943
1042
  children: /* @__PURE__ */ jsx(ViewportStreamMenuItems, {
944
1043
  control,
945
- connected: connected && control.collaboration.role !== "viewer",
1044
+ connected: viewportConnected,
946
1045
  localCursorEnabled,
947
1046
  onLocalCursorChange,
948
1047
  busy,
@@ -962,7 +1061,7 @@ function BrowserMenus({ control, cdpUrl, shareUrls, busy, connected, localCursor
962
1061
  children: "More browser actions"
963
1062
  })] }), /* @__PURE__ */ jsx(DropdownMenuContent, {
964
1063
  align: "end",
965
- className: "w-48",
1064
+ className: "aperture:w-48",
966
1065
  children: /* @__PURE__ */ jsx(RestMenuItems, {
967
1066
  control,
968
1067
  cdpUrl,
@@ -1045,7 +1144,7 @@ function InputControlMenuItem({ control }) {
1045
1144
  });
1046
1145
  }
1047
1146
  function RecordingMenuItems({ control, connected, runningRecordings, now }) {
1048
- const recordingAvailable = connected && control.collaboration.role === "owner";
1147
+ const recordingAvailable = connected && control.canRecord;
1049
1148
  const canStart = recordingAvailable && Boolean(control.activeTargetId) && !control.recordingBusy;
1050
1149
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
1051
1150
  /* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Recording" }),
@@ -1053,9 +1152,9 @@ function RecordingMenuItems({ control, connected, runningRecordings, now }) {
1053
1152
  disabled: !canStart,
1054
1153
  onClick: () => control.startRecording("tab"),
1055
1154
  children: [/* @__PURE__ */ jsx(Circle, {}), /* @__PURE__ */ jsxs("span", {
1056
- className: "flex min-w-0 flex-col",
1155
+ className: "aperture:flex aperture:min-w-0 aperture:flex-col",
1057
1156
  children: [/* @__PURE__ */ jsx("span", { children: "Record this tab" }), /* @__PURE__ */ jsx("span", {
1058
- className: "text-xs text-muted-foreground",
1157
+ className: "aperture:text-xs aperture:text-muted-foreground",
1059
1158
  children: "Stay pinned to this target"
1060
1159
  })]
1061
1160
  })]
@@ -1064,9 +1163,9 @@ function RecordingMenuItems({ control, connected, runningRecordings, now }) {
1064
1163
  disabled: !canStart,
1065
1164
  onClick: () => control.startRecording("viewer"),
1066
1165
  children: [/* @__PURE__ */ jsx(Monitor, {}), /* @__PURE__ */ jsxs("span", {
1067
- className: "flex min-w-0 flex-col",
1166
+ className: "aperture:flex aperture:min-w-0 aperture:flex-col",
1068
1167
  children: [/* @__PURE__ */ jsx("span", { children: "Record this viewer" }), /* @__PURE__ */ jsx("span", {
1069
- className: "text-xs text-muted-foreground",
1168
+ className: "aperture:text-xs aperture:text-muted-foreground",
1070
1169
  children: recordingAvailable ? "Follow tab switches" : "Owner connection required"
1071
1170
  })]
1072
1171
  })]
@@ -1075,9 +1174,9 @@ function RecordingMenuItems({ control, connected, runningRecordings, now }) {
1075
1174
  const target = control.targets.find((candidate) => candidate.id === recording.targetId);
1076
1175
  return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(DropdownMenuSeparator, {}), /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
1077
1176
  /* @__PURE__ */ jsx(DropdownMenuLabel, { children: /* @__PURE__ */ jsxs("span", {
1078
- className: "flex min-w-0 items-center justify-between gap-2",
1177
+ className: "aperture:flex aperture:min-w-0 aperture:items-center aperture:justify-between aperture:gap-2",
1079
1178
  children: [/* @__PURE__ */ jsxs("span", {
1080
- className: "truncate",
1179
+ className: "aperture:truncate",
1081
1180
  children: [
1082
1181
  recording.mode === "viewer" ? "Viewer" : "Tab",
1083
1182
  ":",
@@ -1085,7 +1184,7 @@ function RecordingMenuItems({ control, connected, runningRecordings, now }) {
1085
1184
  target?.title || recording.targetId.slice(0, 8)
1086
1185
  ]
1087
1186
  }), /* @__PURE__ */ jsx("span", {
1088
- className: "shrink-0 tabular-nums",
1187
+ className: "aperture:shrink-0 aperture:tabular-nums",
1089
1188
  children: formatElapsed(recording.startedAt, now)
1090
1189
  })]
1091
1190
  }) }),
@@ -1118,6 +1217,12 @@ function ViewportStreamMenuItems({ control, connected, localCursorEnabled, onLoc
1118
1217
  onCheckedChange: control.setRemoteCursorEnabled,
1119
1218
  children: [/* @__PURE__ */ jsx(MousePointer2, {}), "Remote cursor"]
1120
1219
  }),
1220
+ /* @__PURE__ */ jsxs(DropdownMenuCheckboxItem, {
1221
+ disabled: !connected || !control.canRecord,
1222
+ checked: control.watchableAutomation,
1223
+ onCheckedChange: control.setWatchableAutomation,
1224
+ children: [/* @__PURE__ */ jsx(Eye, {}), "Watchable automation"]
1225
+ }),
1121
1226
  /* @__PURE__ */ jsxs(DropdownMenuCheckboxItem, {
1122
1227
  checked: localCursorEnabled,
1123
1228
  onCheckedChange: onLocalCursorChange,
@@ -1135,7 +1240,7 @@ function StreamMenu({ control, qualityUpdatesEnabled }) {
1135
1240
  const source = control.mediaPath === "websocket-live" ? "jpeg" : qualityUpdatesEnabled ? settings?.profile : "webrtc";
1136
1241
  const disabled = control.mediaSwitching || control.phase !== "connected";
1137
1242
  return /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [/* @__PURE__ */ jsxs(DropdownMenuSubTrigger, { children: [/* @__PURE__ */ jsx(Gauge, {}), "Stream"] }), /* @__PURE__ */ jsx(DropdownMenuSubContent, {
1138
- className: "w-64",
1243
+ className: "aperture:w-64",
1139
1244
  children: /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [
1140
1245
  /* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Source" }),
1141
1246
  /* @__PURE__ */ jsxs(DropdownMenuRadioGroup, {
@@ -1163,9 +1268,9 @@ function StreamMenu({ control, qualityUpdatesEnabled }) {
1163
1268
  value: "webrtc",
1164
1269
  disabled,
1165
1270
  children: /* @__PURE__ */ jsxs("span", {
1166
- className: "flex min-w-0 flex-col",
1271
+ className: "aperture:flex aperture:min-w-0 aperture:flex-col",
1167
1272
  children: [/* @__PURE__ */ jsx("span", { children: "WebRTC" }), /* @__PURE__ */ jsx("span", {
1168
- className: "text-xs text-muted-foreground",
1273
+ className: "aperture:text-xs aperture:text-muted-foreground",
1169
1274
  children: "Live video"
1170
1275
  })]
1171
1276
  })
@@ -1174,9 +1279,9 @@ function StreamMenu({ control, qualityUpdatesEnabled }) {
1174
1279
  value: profile.id,
1175
1280
  disabled: disabled || !settings,
1176
1281
  children: /* @__PURE__ */ jsxs("span", {
1177
- className: "flex min-w-0 flex-col",
1282
+ className: "aperture:flex aperture:min-w-0 aperture:flex-col",
1178
1283
  children: [/* @__PURE__ */ jsx("span", { children: profile.label }), /* @__PURE__ */ jsxs("span", {
1179
- className: "text-xs text-muted-foreground",
1284
+ className: "aperture:text-xs aperture:text-muted-foreground",
1180
1285
  children: [profile.codec, " · WebRTC"]
1181
1286
  })]
1182
1287
  })
@@ -1185,9 +1290,9 @@ function StreamMenu({ control, qualityUpdatesEnabled }) {
1185
1290
  value: "jpeg",
1186
1291
  disabled,
1187
1292
  children: /* @__PURE__ */ jsxs("span", {
1188
- className: "flex min-w-0 flex-col",
1293
+ className: "aperture:flex aperture:min-w-0 aperture:flex-col",
1189
1294
  children: [/* @__PURE__ */ jsx("span", { children: "JPEG" }), /* @__PURE__ */ jsx("span", {
1190
- className: "text-xs text-muted-foreground",
1295
+ className: "aperture:text-xs aperture:text-muted-foreground",
1191
1296
  children: "WebSocket raster stream"
1192
1297
  })]
1193
1298
  })
@@ -1210,9 +1315,9 @@ function StreamMenu({ control, qualityUpdatesEnabled }) {
1210
1315
  value: preset.id,
1211
1316
  disabled,
1212
1317
  children: /* @__PURE__ */ jsxs("span", {
1213
- className: "flex min-w-0 flex-col",
1318
+ className: "aperture:flex aperture:min-w-0 aperture:flex-col",
1214
1319
  children: [/* @__PURE__ */ jsx("span", { children: preset.label }), /* @__PURE__ */ jsx("span", {
1215
- className: "text-xs text-muted-foreground",
1320
+ className: "aperture:text-xs aperture:text-muted-foreground",
1216
1321
  children: preset.detail
1217
1322
  })]
1218
1323
  })
@@ -1228,9 +1333,43 @@ function StreamMenu({ control, qualityUpdatesEnabled }) {
1228
1333
  ] })
1229
1334
  })] });
1230
1335
  }
1336
+ function viewportSizeController(control) {
1337
+ const ownership = control.viewportOwnership;
1338
+ const ownerClientId = ownership?.ownerClientId ?? null;
1339
+ if (ownership === null || ownerClientId === control.collaboration.clientId) return null;
1340
+ const ownerName = control.collaboration.participants.find((participant) => participant.clientId === ownerClientId)?.name ?? null;
1341
+ if (ownerName !== null) return `Size controlled by ${ownerName}`;
1342
+ return control.viewportAutoSync ? "Paused: size was set explicitly" : null;
1343
+ }
1344
+ function ViewportPausedIndicator({ control, connected }) {
1345
+ const sizeController = viewportSizeController(control);
1346
+ if (!control.viewportAutoSync || control.viewportAutoSizeActive || sizeController === null) return null;
1347
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsxs(Tooltip$1, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
1348
+ render: /* @__PURE__ */ jsx(DropdownMenuTrigger, { render: /* @__PURE__ */ jsx(Button$1, {
1349
+ type: "button",
1350
+ variant: "ghost",
1351
+ size: "icon-sm",
1352
+ className: "aperture:text-muted-foreground",
1353
+ "aria-label": `Auto-size paused. ${sizeController}`
1354
+ }) }),
1355
+ children: /* @__PURE__ */ jsx(MonitorPause, {})
1356
+ }), /* @__PURE__ */ jsx(TooltipContent, {
1357
+ side: "bottom",
1358
+ children: sizeController
1359
+ })] }), /* @__PURE__ */ jsx(DropdownMenuContent, {
1360
+ align: "end",
1361
+ className: "aperture:w-56",
1362
+ children: /* @__PURE__ */ jsxs(DropdownMenuGroup, { children: [/* @__PURE__ */ jsx(DropdownMenuLabel, { children: sizeController }), /* @__PURE__ */ jsxs(DropdownMenuItem, {
1363
+ disabled: !connected,
1364
+ onClick: () => control.takeOverViewport(),
1365
+ children: [/* @__PURE__ */ jsx(Hand, {}), "Take over size"]
1366
+ })] })
1367
+ })] });
1368
+ }
1231
1369
  function ViewportMenu({ control, connected }) {
1370
+ const sizeController = viewportSizeController(control);
1232
1371
  return /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [/* @__PURE__ */ jsxs(DropdownMenuSubTrigger, { children: [/* @__PURE__ */ jsx(Monitor, {}), "Viewport"] }), /* @__PURE__ */ jsxs(DropdownMenuSubContent, {
1233
- className: "w-64",
1372
+ className: "aperture:w-64",
1234
1373
  children: [
1235
1374
  /* @__PURE__ */ jsx(DropdownMenuLabel, { children: "Viewport" }),
1236
1375
  /* @__PURE__ */ jsxs(DropdownMenuItem, {
@@ -1242,7 +1381,23 @@ function ViewportMenu({ control, connected }) {
1242
1381
  disabled: !connected || !control.browserViewportSize,
1243
1382
  checked: control.viewportAutoSync,
1244
1383
  onCheckedChange: control.setViewportAutoSync,
1245
- children: [/* @__PURE__ */ jsx(Monitor, {}), "Auto sync browser size"]
1384
+ children: [/* @__PURE__ */ jsx(Monitor, {}), /* @__PURE__ */ jsxs("span", {
1385
+ className: "aperture:flex aperture:min-w-0 aperture:flex-col",
1386
+ children: [/* @__PURE__ */ jsx("span", { children: "Auto-size" }), sizeController !== null ? /* @__PURE__ */ jsx("span", {
1387
+ className: "aperture:truncate aperture:text-xs aperture:text-muted-foreground",
1388
+ children: sizeController
1389
+ }) : null]
1390
+ })]
1391
+ }),
1392
+ sizeController !== null ? /* @__PURE__ */ jsxs(DropdownMenuItem, {
1393
+ disabled: !connected || !control.browserViewportSize,
1394
+ onClick: () => control.takeOverViewport(),
1395
+ children: [/* @__PURE__ */ jsx(Hand, {}), "Take over size"]
1396
+ }) : null,
1397
+ /* @__PURE__ */ jsxs(DropdownMenuCheckboxItem, {
1398
+ checked: control.viewportAutoSizeDefault,
1399
+ onCheckedChange: control.setViewportAutoSizeDefault,
1400
+ children: [/* @__PURE__ */ jsx(Monitor, {}), "Auto-size by default"]
1246
1401
  }),
1247
1402
  /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
1248
1403
  /* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
@@ -1300,16 +1455,16 @@ function CustomViewportSettings({ viewport, connected, onApply }) {
1300
1455
  });
1301
1456
  const unchanged = nextViewport ? viewport.width === nextViewport.width && viewport.height === nextViewport.height && viewport.deviceScaleFactor === nextViewport.deviceScaleFactor : false;
1302
1457
  return /* @__PURE__ */ jsxs("div", {
1303
- className: "grid gap-2 px-2 py-1.5",
1458
+ className: "aperture:grid aperture:gap-2 aperture:px-2 aperture:py-1.5",
1304
1459
  onClick: (event) => event.stopPropagation(),
1305
1460
  onKeyDown: (event) => event.stopPropagation(),
1306
1461
  children: [
1307
1462
  /* @__PURE__ */ jsx(DropdownMenuLabel, {
1308
- className: "px-0",
1463
+ className: "aperture:px-0",
1309
1464
  children: "Custom"
1310
1465
  }),
1311
1466
  /* @__PURE__ */ jsxs("div", {
1312
- className: "grid grid-cols-3 gap-2",
1467
+ className: "aperture:grid aperture:grid-cols-3 aperture:gap-2",
1313
1468
  children: [
1314
1469
  /* @__PURE__ */ jsx(StreamNumberField, {
1315
1470
  label: "Width",
@@ -1331,7 +1486,7 @@ function CustomViewportSettings({ viewport, connected, onApply }) {
1331
1486
  /* @__PURE__ */ jsx(Button$1, {
1332
1487
  type: "button",
1333
1488
  size: "sm",
1334
- className: "h-7",
1489
+ className: "aperture:h-7",
1335
1490
  disabled: !connected || !nextViewport || unchanged,
1336
1491
  onClick: () => {
1337
1492
  if (nextViewport) onApply(nextViewport);
@@ -1354,16 +1509,16 @@ function CustomStreamSettings({ settings, disabled, onApply }) {
1354
1509
  });
1355
1510
  const unchanged = settings.fps === nextSettings?.fps && settings.bitrateKbps === nextSettings?.bitrateKbps;
1356
1511
  return /* @__PURE__ */ jsxs(FieldGroup, {
1357
- className: "gap-2 px-2 py-1.5",
1512
+ className: "aperture:gap-2 aperture:px-2 aperture:py-1.5",
1358
1513
  onClick: (event) => event.stopPropagation(),
1359
1514
  onKeyDown: (event) => event.stopPropagation(),
1360
1515
  children: [
1361
1516
  /* @__PURE__ */ jsx(DropdownMenuLabel, {
1362
- className: "px-0",
1517
+ className: "aperture:px-0",
1363
1518
  children: "Custom"
1364
1519
  }),
1365
1520
  /* @__PURE__ */ jsxs("div", {
1366
- className: "grid grid-cols-2 gap-2",
1521
+ className: "aperture:grid aperture:grid-cols-2 aperture:gap-2",
1367
1522
  children: [/* @__PURE__ */ jsx(StreamNumberField, {
1368
1523
  label: "FPS",
1369
1524
  value: fps,
@@ -1377,7 +1532,7 @@ function CustomStreamSettings({ settings, disabled, onApply }) {
1377
1532
  /* @__PURE__ */ jsx(Button$1, {
1378
1533
  type: "button",
1379
1534
  size: "sm",
1380
- className: "h-7 w-full",
1535
+ className: "aperture:h-7 aperture:w-full",
1381
1536
  disabled: disabled || !nextSettings || unchanged,
1382
1537
  onClick: () => {
1383
1538
  if (nextSettings) onApply({
@@ -1393,7 +1548,7 @@ function CustomStreamSettings({ settings, disabled, onApply }) {
1393
1548
  function StreamNumberField({ label, value, onChange }) {
1394
1549
  const id = useId();
1395
1550
  return /* @__PURE__ */ jsxs(Field, {
1396
- className: "gap-1",
1551
+ className: "aperture:gap-1",
1397
1552
  children: [/* @__PURE__ */ jsx(FieldLabel, {
1398
1553
  htmlFor: id,
1399
1554
  children: label
@@ -1404,14 +1559,14 @@ function StreamNumberField({ label, value, onChange }) {
1404
1559
  value,
1405
1560
  onChange: (event) => onChange(digitsOnly(event.currentTarget.value)),
1406
1561
  onFocus: (event) => event.currentTarget.select(),
1407
- className: "h-7"
1562
+ className: "aperture:h-7"
1408
1563
  })]
1409
1564
  });
1410
1565
  }
1411
1566
  function ViewportScaleField({ label, value, onChange }) {
1412
1567
  const id = useId();
1413
1568
  return /* @__PURE__ */ jsxs(Field, {
1414
- className: "gap-1",
1569
+ className: "aperture:gap-1",
1415
1570
  children: [/* @__PURE__ */ jsx(FieldLabel, {
1416
1571
  htmlFor: id,
1417
1572
  children: label
@@ -1422,7 +1577,7 @@ function ViewportScaleField({ label, value, onChange }) {
1422
1577
  value,
1423
1578
  onChange: (event) => onChange(decimalNumber(event.currentTarget.value)),
1424
1579
  onFocus: (event) => event.currentTarget.select(),
1425
- className: "h-7"
1580
+ className: "aperture:h-7"
1426
1581
  })]
1427
1582
  });
1428
1583
  }
@@ -1481,28 +1636,28 @@ function Avatar$1({ className, size = "default", ...props }) {
1481
1636
  return /* @__PURE__ */ jsx(Avatar.Root, {
1482
1637
  "data-slot": "avatar",
1483
1638
  "data-size": size,
1484
- className: cn("group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten", className),
1639
+ className: cn("aperture:group/avatar aperture:relative aperture:flex aperture:size-8 aperture:shrink-0 aperture:rounded-full aperture:select-none aperture:after:absolute aperture:after:inset-0 aperture:after:rounded-full aperture:after:border aperture:after:border-border aperture:after:mix-blend-darken aperture:data-[size=lg]:size-10 aperture:data-[size=sm]:size-6 aperture:dark:after:mix-blend-lighten", className),
1485
1640
  ...props
1486
1641
  });
1487
1642
  }
1488
1643
  function AvatarImage({ className, ...props }) {
1489
1644
  return /* @__PURE__ */ jsx(Avatar.Image, {
1490
1645
  "data-slot": "avatar-image",
1491
- className: cn("aspect-square size-full rounded-full object-cover", className),
1646
+ className: cn("aperture:aspect-square aperture:size-full aperture:rounded-full aperture:object-cover", className),
1492
1647
  ...props
1493
1648
  });
1494
1649
  }
1495
1650
  function AvatarFallback({ className, ...props }) {
1496
1651
  return /* @__PURE__ */ jsx(Avatar.Fallback, {
1497
1652
  "data-slot": "avatar-fallback",
1498
- className: cn("flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs", className),
1653
+ className: cn("aperture:flex aperture:size-full aperture:items-center aperture:justify-center aperture:rounded-full aperture:bg-muted aperture:text-sm aperture:text-muted-foreground aperture:group-data-[size=sm]/avatar:text-xs", className),
1499
1654
  ...props
1500
1655
  });
1501
1656
  }
1502
1657
  function AvatarBadge({ className, ...props }) {
1503
1658
  return /* @__PURE__ */ jsx("span", {
1504
1659
  "data-slot": "avatar-badge",
1505
- className: cn("absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none", "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden", "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2", "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2", className),
1660
+ className: cn("aperture:absolute aperture:right-0 aperture:bottom-0 aperture:z-10 aperture:inline-flex aperture:items-center aperture:justify-center aperture:rounded-full aperture:bg-primary aperture:text-primary-foreground aperture:bg-blend-color aperture:ring-2 aperture:ring-background aperture:select-none", "aperture:group-data-[size=sm]/avatar:size-2 aperture:group-data-[size=sm]/avatar:[&>svg]:hidden", "aperture:group-data-[size=default]/avatar:size-2.5 aperture:group-data-[size=default]/avatar:[&>svg]:size-2", "aperture:group-data-[size=lg]/avatar:size-3 aperture:group-data-[size=lg]/avatar:[&>svg]:size-2", className),
1506
1661
  ...props
1507
1662
  });
1508
1663
  }
@@ -1528,10 +1683,10 @@ function PopoverContent({ className, align = "center", alignOffset = 0, side = "
1528
1683
  alignOffset,
1529
1684
  side,
1530
1685
  sideOffset,
1531
- className: "isolate z-50",
1686
+ className: "aperture:isolate aperture:z-50",
1532
1687
  children: /* @__PURE__ */ jsx(Popover.Popup, {
1533
1688
  "data-slot": "popover-content",
1534
- className: cn("z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
1689
+ className: cn("aperture:z-50 aperture:flex aperture:w-72 aperture:origin-(--transform-origin) aperture:flex-col aperture:gap-2.5 aperture:rounded-lg aperture:bg-popover aperture:p-2.5 aperture:text-sm aperture:text-popover-foreground aperture:shadow-md aperture:ring-1 aperture:ring-foreground/10 aperture:outline-hidden aperture:duration-100 aperture:data-[side=bottom]:slide-in-from-top-2 aperture:data-[side=inline-end]:slide-in-from-left-2 aperture:data-[side=inline-start]:slide-in-from-right-2 aperture:data-[side=left]:slide-in-from-right-2 aperture:data-[side=right]:slide-in-from-left-2 aperture:data-[side=top]:slide-in-from-bottom-2 aperture:data-open:animate-in aperture:data-open:fade-in-0 aperture:data-open:zoom-in-95 aperture:data-closed:animate-out aperture:data-closed:fade-out-0 aperture:data-closed:zoom-out-95", className),
1535
1690
  ...props
1536
1691
  })
1537
1692
  })
@@ -1540,7 +1695,7 @@ function PopoverContent({ className, align = "center", alignOffset = 0, side = "
1540
1695
  function PopoverTitle({ className, ...props }) {
1541
1696
  return /* @__PURE__ */ jsx(Popover.Title, {
1542
1697
  "data-slot": "popover-title",
1543
- className: cn("font-medium", className),
1698
+ className: cn("aperture:font-medium", className),
1544
1699
  ...props
1545
1700
  });
1546
1701
  }
@@ -1558,10 +1713,10 @@ function CollaborationPresence({ collaboration }) {
1558
1713
  const overflow = participants.length - visible.length;
1559
1714
  if (visible.length === 0) return null;
1560
1715
  return /* @__PURE__ */ jsxs("div", {
1561
- className: "group flex shrink-0 items-center px-2",
1716
+ className: "aperture:group aperture:flex aperture:shrink-0 aperture:items-center aperture:px-2",
1562
1717
  "aria-label": "Session participants",
1563
1718
  children: [overflow > 0 ? /* @__PURE__ */ jsx("div", {
1564
- className: "relative transition-[margin] duration-200",
1719
+ className: "aperture:relative aperture:transition-[margin] aperture:duration-200",
1565
1720
  style: { zIndex: visible.length + 1 },
1566
1721
  children: /* @__PURE__ */ jsx(OverflowParticipants, {
1567
1722
  overflow,
@@ -1569,7 +1724,7 @@ function CollaborationPresence({ collaboration }) {
1569
1724
  collaboration
1570
1725
  })
1571
1726
  }) : null, visible.map((participant, index) => /* @__PURE__ */ jsx("div", {
1572
- className: cn("relative transition-[margin] duration-200", (index > 0 || overflow > 0) && "-ml-4 group-hover:ml-0 group-focus-within:ml-0"),
1727
+ className: cn("aperture:relative aperture:transition-[margin] aperture:duration-200", (index > 0 || overflow > 0) && "aperture:-ml-4 aperture:group-hover:ml-0 aperture:group-focus-within:ml-0"),
1573
1728
  style: { zIndex: visible.length - index },
1574
1729
  children: /* @__PURE__ */ jsx(ParticipantButton, {
1575
1730
  participant,
@@ -1584,18 +1739,18 @@ function OverflowParticipants({ overflow, participants, collaboration }) {
1584
1739
  type: "button",
1585
1740
  variant: "ghost",
1586
1741
  size: "icon-sm",
1587
- className: "shrink-0 rounded-full border bg-background text-[0.65rem] text-muted-foreground",
1742
+ className: "aperture:shrink-0 aperture:rounded-full aperture:border aperture:bg-background aperture:text-[0.65rem] aperture:text-muted-foreground",
1588
1743
  "aria-label": `${overflow} more participants`
1589
1744
  }),
1590
1745
  children: ["+", overflow]
1591
1746
  }), /* @__PURE__ */ jsxs(PopoverContent, {
1592
1747
  align: "end",
1593
- className: "w-auto gap-2",
1748
+ className: "aperture:w-auto aperture:gap-2",
1594
1749
  children: [/* @__PURE__ */ jsx(PopoverTitle, {
1595
- className: "text-xs text-muted-foreground",
1750
+ className: "aperture:text-xs aperture:text-muted-foreground",
1596
1751
  children: "Everyone"
1597
1752
  }), /* @__PURE__ */ jsx("div", {
1598
- className: "flex flex-wrap items-center gap-1",
1753
+ className: "aperture:flex aperture:flex-wrap aperture:items-center aperture:gap-1",
1599
1754
  children: participants.map((participant) => /* @__PURE__ */ jsx(ParticipantButton, {
1600
1755
  participant,
1601
1756
  collaboration
@@ -1610,13 +1765,13 @@ function ParticipantButton({ participant, collaboration }) {
1610
1765
  const label = local ? `${participant.name} (you)` : !followable ? participant.name : following ? `${participant.name} · click to stop following` : `${participant.name} · click to follow`;
1611
1766
  return /* @__PURE__ */ jsxs(Tooltip$1, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
1612
1767
  render: local || !followable ? /* @__PURE__ */ jsx("span", {
1613
- className: "inline-flex size-7 shrink-0 items-center justify-center rounded-full",
1768
+ className: "aperture:inline-flex aperture:size-7 aperture:shrink-0 aperture:items-center aperture:justify-center aperture:rounded-full",
1614
1769
  "aria-label": label
1615
1770
  }) : /* @__PURE__ */ jsx(Button$1, {
1616
1771
  type: "button",
1617
1772
  variant: following ? "secondary" : "ghost",
1618
1773
  size: "icon-sm",
1619
- className: "shrink-0 rounded-full p-0",
1774
+ className: "aperture:shrink-0 aperture:rounded-full aperture:p-0",
1620
1775
  "aria-label": label,
1621
1776
  "aria-pressed": following,
1622
1777
  onClick: () => collaboration.follow(following ? null : participant.clientId)
@@ -1634,7 +1789,7 @@ function ParticipantAvatar({ participant, following }) {
1634
1789
  const controlClaimed = participant.holdingInput && participant.leaseMode === "explicit";
1635
1790
  return /* @__PURE__ */ jsxs(Avatar$1, {
1636
1791
  size: "sm",
1637
- className: cn("shrink-0 ring-2 ring-background", following && "ring-ring"),
1792
+ className: cn("aperture:shrink-0 aperture:ring-2 aperture:ring-background", following && "aperture:ring-ring"),
1638
1793
  children: [
1639
1794
  /* @__PURE__ */ jsx(AvatarImage, {
1640
1795
  src: gravatarURL(participant.avatarHash),
@@ -1642,7 +1797,7 @@ function ParticipantAvatar({ participant, following }) {
1642
1797
  }),
1643
1798
  /* @__PURE__ */ jsx(AvatarFallback, { children: initials(participant.name) }),
1644
1799
  participant.holdingInput ? /* @__PURE__ */ jsx(AvatarBadge, {
1645
- className: cn("bg-emerald-500", controlClaimed && "group-data-[size=sm]/avatar:size-3 group-data-[size=sm]/avatar:[&>svg]:!block group-data-[size=sm]/avatar:[&>svg]:size-2"),
1800
+ className: cn("aperture:bg-emerald-500", controlClaimed && "aperture:group-data-[size=sm]/avatar:size-3 aperture:group-data-[size=sm]/avatar:[&>svg]:!block aperture:group-data-[size=sm]/avatar:[&>svg]:size-2"),
1646
1801
  title: controlClaimed ? "Control claimed" : "Has input control",
1647
1802
  children: controlClaimed ? /* @__PURE__ */ jsx(Lock, {}) : /* @__PURE__ */ jsx(Radio, {})
1648
1803
  }) : null
@@ -1665,6 +1820,8 @@ function BrowserToolbar({ control, leading, features, collaborationRole, cdpUrl,
1665
1820
  const browserMutationEnabled = connected && collaborationRole !== "viewer";
1666
1821
  const drawingAvailable = connected && control.collaboration.phase === "connected" && Boolean(control.activeTargetId);
1667
1822
  const loading = control.activeTarget?.loading ?? false;
1823
+ const canGoBack = control.activeTarget?.canGoBack ?? true;
1824
+ const canGoForward = control.activeTarget?.canGoForward ?? true;
1668
1825
  const runningRecordings = control.recordings.filter((recording) => recording.status === "starting" || recording.status === "running");
1669
1826
  const hasRunningRecordings = runningRecordings.length > 0;
1670
1827
  const recordingTargetIds = new Set(runningRecordings.map((recording) => recording.targetId));
@@ -1677,10 +1834,10 @@ function BrowserToolbar({ control, leading, features, collaborationRole, cdpUrl,
1677
1834
  setUrlDraft(null);
1678
1835
  }
1679
1836
  return /* @__PURE__ */ jsxs("div", {
1680
- className: "flex min-w-0 flex-col bg-background",
1837
+ className: "aperture:flex aperture:min-w-0 aperture:flex-col aperture:bg-background",
1681
1838
  children: [leading || features.tabs || features.presence ? /* @__PURE__ */ jsxs("div", {
1682
1839
  "data-workbench-titlebar": true,
1683
- className: "flex min-w-0 shrink-0 items-stretch border-b bg-muted/35",
1840
+ className: "aperture:flex aperture:min-w-0 aperture:shrink-0 aperture:items-stretch aperture:border-b aperture:bg-muted/35",
1684
1841
  children: [
1685
1842
  leading,
1686
1843
  features.tabs ? /* @__PURE__ */ jsx(BrowserTabStrip, {
@@ -1695,25 +1852,26 @@ function BrowserToolbar({ control, leading, features, collaborationRole, cdpUrl,
1695
1852
  onDuplicate: control.duplicateTarget,
1696
1853
  onClose: control.closeTarget,
1697
1854
  onReload: control.reload,
1698
- onReorder: control.reorderTargets
1699
- }) : /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1" }),
1855
+ onReorder: control.reorderTargets,
1856
+ loadThumbnail: control.loadTargetThumbnail
1857
+ }) : /* @__PURE__ */ jsx("div", { className: "aperture:min-w-0 aperture:flex-1" }),
1700
1858
  features.presence ? /* @__PURE__ */ jsx(CollaborationPresence, { collaboration: control.collaboration }) : null
1701
1859
  ]
1702
1860
  }) : null, features.navigation || features.addressBar || features.drawing || features.devTools || features.menus ? /* @__PURE__ */ jsxs("div", {
1703
- className: "flex h-9 items-center gap-1 px-1.5",
1861
+ className: "aperture:flex aperture:h-9 aperture:items-center aperture:gap-1 aperture:px-1.5",
1704
1862
  children: [
1705
1863
  features.navigation ? /* @__PURE__ */ jsxs("div", {
1706
- className: "flex shrink-0 items-center gap-0.5",
1864
+ className: "aperture:flex aperture:shrink-0 aperture:items-center aperture:gap-0.5",
1707
1865
  children: [
1708
1866
  /* @__PURE__ */ jsx(ToolbarButton, {
1709
1867
  label: "Back",
1710
- disabled: !browserMutationEnabled,
1868
+ disabled: !browserMutationEnabled || !canGoBack,
1711
1869
  onClick: () => control.historyBack(),
1712
1870
  children: /* @__PURE__ */ jsx(ArrowLeft, {})
1713
1871
  }),
1714
1872
  /* @__PURE__ */ jsx(ToolbarButton, {
1715
1873
  label: "Forward",
1716
- disabled: !browserMutationEnabled,
1874
+ disabled: !browserMutationEnabled || !canGoForward,
1717
1875
  onClick: () => control.historyForward(),
1718
1876
  children: /* @__PURE__ */ jsx(ArrowRight, {})
1719
1877
  }),
@@ -1729,7 +1887,7 @@ function BrowserToolbar({ control, leading, features, collaborationRole, cdpUrl,
1729
1887
  ]
1730
1888
  }) : null,
1731
1889
  features.addressBar ? /* @__PURE__ */ jsx(InputGroup, {
1732
- className: "h-7 border-transparent bg-transparent transition-colors hover:border-input/50 hover:bg-muted/35 has-[[data-slot=input-group-control]:focus-visible]:border-input/70 has-[[data-slot=input-group-control]:focus-visible]:bg-background has-[[data-slot=input-group-control]:focus-visible]:ring-2 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/20 dark:hover:bg-input/20",
1890
+ className: "aperture:h-7 aperture:border-transparent aperture:bg-transparent aperture:transition-colors aperture:hover:border-input/50 aperture:hover:bg-muted/35 aperture:has-[[data-slot=input-group-control]:focus-visible]:border-input/70 aperture:has-[[data-slot=input-group-control]:focus-visible]:bg-background aperture:has-[[data-slot=input-group-control]:focus-visible]:ring-2 aperture:has-[[data-slot=input-group-control]:focus-visible]:ring-ring/20 aperture:dark:hover:bg-input/20",
1733
1891
  children: /* @__PURE__ */ jsx(InputGroupInput, {
1734
1892
  value: urlDraft ?? displayUrl,
1735
1893
  onChange: (event) => setUrlDraft(event.target.value),
@@ -1741,17 +1899,17 @@ function BrowserToolbar({ control, leading, features, collaborationRole, cdpUrl,
1741
1899
  }
1742
1900
  },
1743
1901
  placeholder: "URL",
1744
- className: "h-7 px-2 font-mono text-xs text-muted-foreground transition-colors focus-visible:text-foreground",
1902
+ className: "aperture:h-7 aperture:px-2 aperture:font-mono aperture:text-xs aperture:text-muted-foreground aperture:transition-colors aperture:focus-visible:text-foreground",
1745
1903
  disabled: !browserMutationEnabled
1746
1904
  })
1747
- }) : /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1" }),
1748
- busy ? /* @__PURE__ */ jsx(Loader2, { className: "size-4 shrink-0 animate-spin text-muted-foreground" }) : null,
1905
+ }) : /* @__PURE__ */ jsx("div", { className: "aperture:min-w-0 aperture:flex-1" }),
1906
+ busy ? /* @__PURE__ */ jsx(Loader2, { className: "aperture:size-4 aperture:shrink-0 aperture:animate-spin aperture:text-muted-foreground" }) : null,
1749
1907
  features.drawing ? /* @__PURE__ */ jsxs(Tooltip$1, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
1750
1908
  render: /* @__PURE__ */ jsx(Button$1, {
1751
1909
  type: "button",
1752
1910
  variant: paintingEnabled ? "secondary" : "ghost",
1753
1911
  size: "icon-sm",
1754
- className: "shrink-0",
1912
+ className: "aperture:shrink-0",
1755
1913
  disabled: !paintingEnabled && !drawingAvailable,
1756
1914
  "aria-label": paintingEnabled ? "Stop drawing" : "Draw on this tab",
1757
1915
  "aria-pressed": paintingEnabled,
@@ -1852,14 +2010,14 @@ function isLikelyHost(value) {
1852
2010
  }
1853
2011
  //#endregion
1854
2012
  //#region ../ui/src/components/badge.tsx
1855
- const badgeVariants = cva("group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!", {
2013
+ const badgeVariants = cva("aperture:group/badge aperture:inline-flex aperture:h-5 aperture:w-fit aperture:shrink-0 aperture:items-center aperture:justify-center aperture:gap-1 aperture:overflow-hidden aperture:rounded-4xl aperture:border aperture:border-transparent aperture:px-2 aperture:py-0.5 aperture:text-xs aperture:font-medium aperture:whitespace-nowrap aperture:transition-all aperture:focus-visible:border-ring aperture:focus-visible:ring-[3px] aperture:focus-visible:ring-ring/50 aperture:has-data-[icon=inline-end]:pr-1.5 aperture:has-data-[icon=inline-start]:pl-1.5 aperture:aria-invalid:border-destructive aperture:aria-invalid:ring-destructive/20 aperture:dark:aria-invalid:ring-destructive/40 aperture:[&>svg]:pointer-events-none aperture:[&>svg]:size-3!", {
1856
2014
  variants: { variant: {
1857
- default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
1858
- secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
1859
- destructive: "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
1860
- outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
1861
- ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
1862
- link: "text-primary underline-offset-4 hover:underline"
2015
+ default: "aperture:bg-primary aperture:text-primary-foreground aperture:[a]:hover:bg-primary/80",
2016
+ secondary: "aperture:bg-secondary aperture:text-secondary-foreground aperture:[a]:hover:bg-secondary/80",
2017
+ destructive: "aperture:bg-destructive/10 aperture:text-destructive aperture:focus-visible:ring-destructive/20 aperture:dark:bg-destructive/20 aperture:dark:focus-visible:ring-destructive/40 aperture:[a]:hover:bg-destructive/20",
2018
+ outline: "aperture:border-border aperture:text-foreground aperture:[a]:hover:bg-muted aperture:[a]:hover:text-muted-foreground",
2019
+ ghost: "aperture:hover:bg-muted aperture:hover:text-muted-foreground aperture:dark:hover:bg-muted/50",
2020
+ link: "aperture:text-primary aperture:underline-offset-4 aperture:hover:underline"
1863
2021
  } },
1864
2022
  defaultVariants: { variant: "default" }
1865
2023
  });
@@ -1885,7 +2043,7 @@ function showNotice(notice) {
1885
2043
  function BrowserViewport({ statusBadge = true, className, ...props }) {
1886
2044
  return /* @__PURE__ */ jsx(SessionViewport, {
1887
2045
  ...props,
1888
- className: className ?? "bg-background",
2046
+ className: className ?? "aperture:bg-background",
1889
2047
  onNotice: showNotice,
1890
2048
  renderOverlay: (overlay) => /* @__PURE__ */ jsx(ViewportOverlay, {
1891
2049
  overlay,
@@ -1896,26 +2054,26 @@ function BrowserViewport({ statusBadge = true, className, ...props }) {
1896
2054
  function ViewportOverlay({ overlay, statusBadge }) {
1897
2055
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1898
2056
  overlay.placeholder ? /* @__PURE__ */ jsx("div", {
1899
- className: "pointer-events-none absolute inset-0 flex items-center justify-center",
2057
+ className: "aperture:pointer-events-none aperture:absolute aperture:inset-0 aperture:flex aperture:items-center aperture:justify-center",
1900
2058
  children: /* @__PURE__ */ jsx(ViewportPlaceholder, { placeholder: overlay.placeholder })
1901
2059
  }) : null,
1902
2060
  statusBadge ? /* @__PURE__ */ jsx("div", {
1903
- className: "pointer-events-none absolute right-2 bottom-2 flex items-center gap-1.5",
2061
+ className: "aperture:pointer-events-none aperture:absolute aperture:right-2 aperture:bottom-2 aperture:flex aperture:items-center aperture:gap-1.5",
1904
2062
  children: /* @__PURE__ */ jsx(StatusBadge, { status: overlay.status })
1905
2063
  }) : null,
1906
2064
  overlay.followedCursor ? /* @__PURE__ */ jsxs("div", {
1907
- className: "pointer-events-none absolute z-30 flex translate-x-[-2px] translate-y-[-2px] items-start text-primary drop-shadow-sm",
2065
+ className: "aperture:pointer-events-none aperture:absolute aperture:z-30 aperture:flex aperture:translate-x-[-2px] aperture:translate-y-[-2px] aperture:items-start aperture:text-primary aperture:drop-shadow-sm",
1908
2066
  style: {
1909
2067
  left: overlay.followedCursor.x,
1910
2068
  top: overlay.followedCursor.y
1911
2069
  },
1912
- children: [/* @__PURE__ */ jsx(MousePointer2, { className: "size-5 fill-primary stroke-background stroke-[1.5]" }), /* @__PURE__ */ jsx("span", {
1913
- className: "mt-4 -ml-1 rounded bg-primary px-1.5 py-0.5 text-[10px] leading-none font-medium whitespace-nowrap text-primary-foreground",
2070
+ children: [/* @__PURE__ */ jsx(MousePointer2, { className: "aperture:size-5 aperture:fill-primary aperture:stroke-background aperture:stroke-[1.5]" }), /* @__PURE__ */ jsx("span", {
2071
+ className: "aperture:mt-4 aperture:-ml-1 aperture:rounded aperture:bg-primary aperture:px-1.5 aperture:py-0.5 aperture:text-[10px] aperture:leading-none aperture:font-medium aperture:whitespace-nowrap aperture:text-primary-foreground",
1914
2072
  children: overlay.followedCursor.name
1915
2073
  })]
1916
2074
  }) : null,
1917
2075
  overlay.cursorHint ? /* @__PURE__ */ jsx("div", {
1918
- className: "pointer-events-none absolute z-20 max-w-64 translate-x-3 translate-y-3 rounded-md border bg-popover px-2 py-1 text-xs text-popover-foreground shadow-md",
2076
+ className: "aperture:pointer-events-none aperture:absolute aperture:z-20 aperture:max-w-64 aperture:translate-x-3 aperture:translate-y-3 aperture:rounded-md aperture:border aperture:bg-popover aperture:px-2 aperture:py-1 aperture:text-xs aperture:text-popover-foreground aperture:shadow-md",
1919
2077
  style: {
1920
2078
  left: overlay.cursorHint.x,
1921
2079
  top: overlay.cursorHint.y
@@ -1923,7 +2081,7 @@ function ViewportOverlay({ overlay, statusBadge }) {
1923
2081
  children: overlay.cursorHint.text
1924
2082
  }) : null,
1925
2083
  overlay.collaborationError ? /* @__PURE__ */ jsx("div", {
1926
- className: "pointer-events-none absolute bottom-10 left-2 max-w-[80%] rounded-md border border-amber-500/40 bg-background/90 px-2 py-1 text-xs text-amber-800 dark:text-amber-300",
2084
+ className: "aperture:pointer-events-none aperture:absolute aperture:bottom-10 aperture:left-2 aperture:max-w-[80%] aperture:rounded-md aperture:border aperture:border-amber-500/40 aperture:bg-background/90 aperture:px-2 aperture:py-1 aperture:text-xs aperture:text-amber-800 aperture:dark:text-amber-300",
1927
2085
  children: overlay.collaborationError
1928
2086
  }) : null
1929
2087
  ] });
@@ -1937,14 +2095,14 @@ const placeholderLabels = {
1937
2095
  };
1938
2096
  function ViewportPlaceholder({ placeholder }) {
1939
2097
  return /* @__PURE__ */ jsxs("div", {
1940
- className: "flex flex-col items-center gap-2 text-sm text-muted-foreground",
1941
- children: [placeholder === "disconnected" ? /* @__PURE__ */ jsx(Unplug, { className: "size-5" }) : /* @__PURE__ */ jsx(Loader2, { className: "size-5 animate-spin" }), placeholderLabels[placeholder]]
2098
+ className: "aperture:flex aperture:flex-col aperture:items-center aperture:gap-2 aperture:text-sm aperture:text-muted-foreground",
2099
+ children: [placeholder === "disconnected" ? /* @__PURE__ */ jsx(Unplug, { className: "aperture:size-5" }) : /* @__PURE__ */ jsx(Loader2, { className: "aperture:size-5 aperture:animate-spin" }), placeholderLabels[placeholder]]
1942
2100
  });
1943
2101
  }
1944
2102
  function StatusBadge({ status }) {
1945
2103
  if (status === "webrtc" || status === "websocket") return /* @__PURE__ */ jsx(Badge, {
1946
2104
  variant: "secondary",
1947
- className: "bg-emerald-500/15 text-emerald-700 dark:text-emerald-300",
2105
+ className: "aperture:bg-emerald-500/15 aperture:text-emerald-700 aperture:dark:text-emerald-300",
1948
2106
  children: status
1949
2107
  });
1950
2108
  return /* @__PURE__ */ jsx(Badge, {
@@ -1965,7 +2123,7 @@ function BrowserDevToolsPane({ cdpUrl, targetId }) {
1965
2123
  return frame.toString();
1966
2124
  }, [cdpUrl, targetId]);
1967
2125
  if (!src) return /* @__PURE__ */ jsx(Empty, {
1968
- className: "h-full rounded-none border-none",
2126
+ className: "aperture:h-full aperture:rounded-none aperture:border-none",
1969
2127
  children: /* @__PURE__ */ jsxs(EmptyHeader, { children: [
1970
2128
  /* @__PURE__ */ jsx(EmptyMedia, {
1971
2129
  variant: "icon",
@@ -1976,7 +2134,7 @@ function BrowserDevToolsPane({ cdpUrl, targetId }) {
1976
2134
  ] })
1977
2135
  });
1978
2136
  return /* @__PURE__ */ jsx("iframe", {
1979
- className: "h-full w-full border-0 bg-background",
2137
+ className: "aperture:h-full aperture:w-full aperture:border-0 aperture:bg-background",
1980
2138
  src,
1981
2139
  title: "Browser DevTools",
1982
2140
  allow: "clipboard-read; clipboard-write",
@@ -1988,7 +2146,7 @@ function BrowserDevToolsPane({ cdpUrl, targetId }) {
1988
2146
  function ResizablePanelGroup({ className, ...props }) {
1989
2147
  return /* @__PURE__ */ jsx(ResizablePrimitive.Group, {
1990
2148
  "data-slot": "resizable-panel-group",
1991
- className: cn("flex h-full w-full aria-[orientation=vertical]:flex-col", className),
2149
+ className: cn("aperture:flex aperture:h-full aperture:w-full aperture:aria-[orientation=vertical]:flex-col", className),
1992
2150
  ...props
1993
2151
  });
1994
2152
  }
@@ -2001,9 +2159,9 @@ function ResizablePanel({ ...props }) {
2001
2159
  function ResizableHandle({ withHandle, className, ...props }) {
2002
2160
  return /* @__PURE__ */ jsx(ResizablePrimitive.Separator, {
2003
2161
  "data-slot": "resizable-handle",
2004
- className: cn("relative flex w-px items-center justify-center bg-border ring-offset-background after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-hidden aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90", className),
2162
+ className: cn("aperture:relative aperture:flex aperture:w-px aperture:items-center aperture:justify-center aperture:bg-border aperture:ring-offset-background aperture:after:absolute aperture:after:inset-y-0 aperture:after:left-1/2 aperture:after:w-1 aperture:after:-translate-x-1/2 aperture:focus-visible:ring-1 aperture:focus-visible:ring-ring aperture:focus-visible:outline-hidden aperture:aria-[orientation=horizontal]:h-px aperture:aria-[orientation=horizontal]:w-full aperture:aria-[orientation=horizontal]:after:left-0 aperture:aria-[orientation=horizontal]:after:h-1 aperture:aria-[orientation=horizontal]:after:w-full aperture:aria-[orientation=horizontal]:after:translate-x-0 aperture:aria-[orientation=horizontal]:after:-translate-y-1/2 aperture:[&[aria-orientation=horizontal]>div]:rotate-90", className),
2005
2163
  ...props,
2006
- children: withHandle && /* @__PURE__ */ jsx("div", { className: "z-10 flex h-6 w-1 shrink-0 rounded-lg bg-border" })
2164
+ children: withHandle && /* @__PURE__ */ jsx("div", { className: "aperture:z-10 aperture:flex aperture:h-6 aperture:w-1 aperture:shrink-0 aperture:rounded-lg aperture:bg-border" })
2007
2165
  });
2008
2166
  }
2009
2167
  //#endregion
@@ -2052,8 +2210,16 @@ function BrowserControlPane({ control, leading, features: featureOverrides, coll
2052
2210
  window.localStorage.setItem(LOCAL_CURSOR_STORAGE_KEY, String(enabled));
2053
2211
  } catch {}
2054
2212
  }
2213
+ const viewport = /* @__PURE__ */ jsx(BrowserViewport, {
2214
+ control,
2215
+ viewport: control.viewport,
2216
+ localCursorEnabled,
2217
+ paintingEnabled: features.drawing && paintingEnabled,
2218
+ onPaintingEnabledChange: setPaintingEnabled,
2219
+ statusBadge: features.statusBadge
2220
+ });
2055
2221
  return /* @__PURE__ */ jsxs("div", {
2056
- className: "flex h-full min-h-0 min-w-0 flex-1 flex-col overflow-hidden",
2222
+ className: "aperture:flex aperture:h-full aperture:min-h-0 aperture:min-w-0 aperture:flex-1 aperture:flex-col aperture:overflow-hidden",
2057
2223
  children: [/* @__PURE__ */ jsx(BrowserToolbar, {
2058
2224
  control,
2059
2225
  leading,
@@ -2071,22 +2237,15 @@ function BrowserControlPane({ control, leading, features: featureOverrides, coll
2071
2237
  onDevToolsOpenChange: handleDevToolsOpenChange,
2072
2238
  onDevToolsDockChange: setDevToolsDock,
2073
2239
  onSessionDetails
2074
- }), /* @__PURE__ */ jsxs(ResizablePanelGroup, {
2240
+ }), features.devTools ? /* @__PURE__ */ jsxs(ResizablePanelGroup, {
2075
2241
  orientation: devToolsDock === "bottom" ? "vertical" : "horizontal",
2076
- className: "min-h-0 min-w-0 flex-1 has-[[data-separator=active]]:[&_iframe]:pointer-events-none",
2242
+ className: "aperture:min-h-0 aperture:min-w-0 aperture:flex-1 aperture:has-[[data-separator=active]]:[&_iframe]:pointer-events-none",
2077
2243
  children: [
2078
2244
  /* @__PURE__ */ jsx(ResizablePanel, {
2079
- className: "flex min-h-0 min-w-0",
2245
+ className: "aperture:flex aperture:min-h-0 aperture:min-w-0",
2080
2246
  defaultSize: "60%",
2081
2247
  minSize: "20%",
2082
- children: /* @__PURE__ */ jsx(BrowserViewport, {
2083
- control,
2084
- viewport: control.viewport,
2085
- localCursorEnabled,
2086
- paintingEnabled: features.drawing && paintingEnabled,
2087
- onPaintingEnabledChange: setPaintingEnabled,
2088
- statusBadge: features.statusBadge
2089
- })
2248
+ children: viewport
2090
2249
  }),
2091
2250
  /* @__PURE__ */ jsx(ResizableHandle, {
2092
2251
  withHandle: true,
@@ -2095,12 +2254,12 @@ function BrowserControlPane({ control, leading, features: featureOverrides, coll
2095
2254
  }),
2096
2255
  /* @__PURE__ */ jsx(ResizablePanel, {
2097
2256
  panelRef: devToolsPanelRef,
2098
- className: "flex min-h-0 min-w-0",
2257
+ className: "aperture:flex aperture:min-h-0 aperture:min-w-0",
2099
2258
  collapsible: true,
2100
2259
  defaultSize: "40%",
2101
2260
  minSize: "20%",
2102
- children: Array.from(features.devTools ? devToolsTargetIds : [], (targetId) => /* @__PURE__ */ jsx("div", {
2103
- className: "h-full min-h-0 w-full min-w-0",
2261
+ children: Array.from(devToolsTargetIds, (targetId) => /* @__PURE__ */ jsx("div", {
2262
+ className: "aperture:h-full aperture:min-h-0 aperture:w-full aperture:min-w-0",
2104
2263
  hidden: targetId !== activeTargetId,
2105
2264
  children: /* @__PURE__ */ jsx(BrowserDevToolsPane, {
2106
2265
  cdpUrl,
@@ -2109,28 +2268,19 @@ function BrowserControlPane({ control, leading, features: featureOverrides, coll
2109
2268
  }, targetId))
2110
2269
  })
2111
2270
  ]
2112
- })]
2271
+ }) : viewport]
2113
2272
  });
2114
2273
  }
2115
2274
  //#endregion
2116
- //#region src/aperture-session.tsx
2117
- function ApertureSession({ baseUrl, theme = "system", className, ...props }) {
2275
+ //#region src/ui-root.tsx
2276
+ function ApertureUIRoot({ theme = "system", className, children }) {
2118
2277
  const [root, setRoot] = useState(null);
2119
- const dark = useDarkTheme(theme);
2120
2278
  return /* @__PURE__ */ jsx("div", {
2121
2279
  ref: setRoot,
2122
- className: cn("aperture-root relative h-full w-full", dark && "dark", className),
2123
- children: root ? /* @__PURE__ */ jsx(ApertureProvider, {
2124
- baseUrl,
2125
- children: /* @__PURE__ */ jsx(PortalContainerProvider, {
2126
- container: root,
2127
- children: /* @__PURE__ */ jsxs(TooltipProvider, { children: [/* @__PURE__ */ jsx(SharedSession, { ...props }), props.features?.toaster !== false ? /* @__PURE__ */ jsx(Toaster$1, {
2128
- theme: dark ? "dark" : "light",
2129
- richColors: true,
2130
- closeButton: true,
2131
- position: "bottom-center"
2132
- }) : null] })
2133
- })
2280
+ className: cn("aperture-root aperture:relative aperture:h-full aperture:w-full", useDarkTheme(theme) && "aperture-dark", className),
2281
+ children: root ? /* @__PURE__ */ jsx(PortalContainerProvider, {
2282
+ container: root,
2283
+ children: /* @__PURE__ */ jsx(TooltipProvider, { children })
2134
2284
  }) : null
2135
2285
  });
2136
2286
  }
@@ -2146,36 +2296,58 @@ function useDarkTheme(theme) {
2146
2296
  }, [theme]);
2147
2297
  return theme === "dark" || theme === "system" && systemDark;
2148
2298
  }
2149
- function SharedSession({ token, features, leading }) {
2150
- const { status, share, control } = useSharedSession({
2151
- token,
2299
+ //#endregion
2300
+ //#region src/aperture-session.tsx
2301
+ function ApertureSession({ theme = "system", className, ...props }) {
2302
+ return /* @__PURE__ */ jsx(ApertureUIRoot, {
2303
+ theme,
2304
+ className,
2305
+ children: /* @__PURE__ */ jsxs(ApertureProvider, {
2306
+ baseUrl: props.access?.baseUrl,
2307
+ children: [/* @__PURE__ */ jsx(Session, { ...props }), props.features?.toaster !== false ? /* @__PURE__ */ jsx(Toaster$1, {
2308
+ theme,
2309
+ richColors: true,
2310
+ closeButton: true,
2311
+ position: "bottom-center"
2312
+ }) : null]
2313
+ })
2314
+ });
2315
+ }
2316
+ function Session({ access, features, leading }) {
2317
+ const { status, control } = useSession({
2318
+ access,
2152
2319
  onNotice: showNotice
2153
2320
  });
2154
2321
  switch (status) {
2155
2322
  case "invalid": return /* @__PURE__ */ jsx(SessionState, {
2156
2323
  icon: /* @__PURE__ */ jsx(Link2Off, {}),
2157
- title: "Invalid share link",
2158
- description: "This link does not contain a valid session capability."
2324
+ title: "Invalid session access",
2325
+ description: "Provide a valid session connection."
2159
2326
  });
2160
2327
  case "loading": return /* @__PURE__ */ jsx(SessionState, {
2161
- icon: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }),
2162
- title: "Opening shared session"
2328
+ icon: /* @__PURE__ */ jsx(Loader2, { className: "aperture:animate-spin" }),
2329
+ title: "Opening session"
2330
+ });
2331
+ case "denied": return /* @__PURE__ */ jsx(SessionState, {
2332
+ icon: /* @__PURE__ */ jsx(Link2Off, {}),
2333
+ title: "Session access denied",
2334
+ description: "Sign in to the app or ask for access to this session."
2163
2335
  });
2164
2336
  case "expired": return /* @__PURE__ */ jsx(SessionState, {
2165
2337
  icon: /* @__PURE__ */ jsx(Link2Off, {}),
2166
- title: "Share link expired",
2167
- description: "This session capability has expired. Ask the session owner for a new link."
2338
+ title: "Session access expired",
2339
+ description: "Ask the session owner to renew access."
2168
2340
  });
2169
2341
  case "unavailable": return /* @__PURE__ */ jsx(SessionState, {
2170
2342
  icon: /* @__PURE__ */ jsx(Link2Off, {}),
2171
- title: "Shared session unavailable",
2172
- description: "This link is invalid, revoked, or the shared session is no longer available."
2343
+ title: "Session unavailable",
2344
+ description: "This session is unavailable or access has been revoked."
2173
2345
  });
2174
2346
  case "ready": return /* @__PURE__ */ jsx("div", {
2175
- className: "flex h-full min-h-0 flex-1 flex-col overflow-hidden bg-background",
2347
+ className: "aperture:flex aperture:h-full aperture:min-h-0 aperture:flex-1 aperture:flex-col aperture:overflow-hidden aperture:bg-background",
2176
2348
  children: /* @__PURE__ */ jsx(BrowserControlPane, {
2177
2349
  control,
2178
- collaborationRole: share?.role ?? "viewer",
2350
+ collaborationRole: control.collaboration.role,
2179
2351
  cdpUrl: null,
2180
2352
  shareUrls: null,
2181
2353
  leading,
@@ -2195,7 +2367,7 @@ function devToolsUrl(origin, cdpUrl, sessionToken) {
2195
2367
  }
2196
2368
  function SessionState({ icon, title, description }) {
2197
2369
  return /* @__PURE__ */ jsx(Empty, {
2198
- className: "h-full border-none",
2370
+ className: "aperture:h-full aperture:border-none",
2199
2371
  children: /* @__PURE__ */ jsxs(EmptyHeader, { children: [
2200
2372
  /* @__PURE__ */ jsx(EmptyMedia, {
2201
2373
  variant: "icon",
@@ -2207,6 +2379,6 @@ function SessionState({ icon, title, description }) {
2207
2379
  });
2208
2380
  }
2209
2381
  //#endregion
2210
- export { ApertureProvider, ApertureSession, BrowserControlPane, BrowserViewport, ClipboardError, LiveSessionError, RuntimeProvider, RuntimeProviderMissingError, SessionViewport, SharedSession, collaborationPaintLifetimeMs, copyText, copyTextWithToast, devToolsUrl, makeApertureRuntime, parseShareToken, resolveSessionFeatures, showNotice, useBaseUrl, useBrowserControl, useEffectCallback, useFork, useLiveSession, useRunApi, useRuntime, useSharedSession };
2382
+ export { ApertureProvider, ApertureSession, ApertureUIRoot, BrowserControlPane, BrowserViewport, ClipboardError, LiveSessionError, RuntimeProvider, RuntimeProviderMissingError, Session, SessionViewport, collaborationPaintLifetimeMs, copyText, copyTextWithToast, devToolsUrl, makeApertureRuntime, resolveSessionFeatures, shareSessionAccess, showNotice, useBaseUrl, useBrowserControl, useEffectCallback, useFork, useLiveSession, useRunApi, useRuntime, useSession };
2211
2383
 
2212
2384
  //# sourceMappingURL=index.js.map