@cloudvoyant/helix-react 0.15.0 → 0.16.0-rc.202609011023.818ad02

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.cjs CHANGED
@@ -40,11 +40,17 @@ __export(index_exports, {
40
40
  CardHeader: () => CardHeader,
41
41
  CardTitle: () => CardTitle,
42
42
  Center: () => Center,
43
+ Chart: () => Chart,
43
44
  Checkbox: () => Checkbox,
44
45
  CheckboxControl: () => CheckboxControl,
45
46
  CheckboxGroup: () => CheckboxGroup,
46
47
  CheckboxIndicator: () => CheckboxIndicator,
47
48
  CheckboxLabel: () => CheckboxLabel,
49
+ CodeBlock: () => CodeBlock,
50
+ CodeBlockContent: () => CodeBlockContent,
51
+ CodeBlockCopyButton: () => CodeBlockCopyButton,
52
+ CodeBlockHeader: () => CodeBlockHeader,
53
+ CodeBlockTitle: () => CodeBlockTitle,
48
54
  Col: () => Col,
49
55
  Combobox: () => Combobox,
50
56
  ComboboxClear: () => ComboboxClear,
@@ -60,6 +66,7 @@ __export(index_exports, {
60
66
  ComboboxList: () => ComboboxList,
61
67
  ComboboxTrigger: () => ComboboxTrigger,
62
68
  Container: () => Container,
69
+ CopyButton: () => CopyButton,
63
70
  Dialog: () => Dialog,
64
71
  DialogBackdrop: () => DialogBackdrop,
65
72
  DialogContent: () => DialogContent,
@@ -79,9 +86,17 @@ __export(index_exports, {
79
86
  FieldSetError: () => FieldSetError,
80
87
  FieldSetHelper: () => FieldSetHelper,
81
88
  FieldSetLegend: () => FieldSetLegend,
89
+ Figure: () => Figure,
82
90
  HStack: () => HStack,
91
+ InlineLaTeX: () => InlineLaTeX,
83
92
  Input: () => Input2,
84
93
  Item: () => Item,
94
+ LaTeX: () => LaTeX,
95
+ LanguageTabsCodeBlock: () => LanguageTabsCodeBlock,
96
+ Manim: () => Manim,
97
+ Mermaid: () => Mermaid,
98
+ MultiFileCodeBlock: () => MultiFileCodeBlock,
99
+ MultipleChoiceQuestion: () => MultipleChoiceQuestion,
85
100
  Navbar: () => Navbar,
86
101
  NavbarActions: () => NavbarActions,
87
102
  NavbarActivationArea: () => NavbarActivationArea,
@@ -101,11 +116,13 @@ __export(index_exports, {
101
116
  NavbarMobileOverlay: () => NavbarMobileOverlay,
102
117
  NavbarProvider: () => NavbarProvider,
103
118
  NavbarTrigger: () => NavbarTrigger,
119
+ Notice: () => Notice,
104
120
  NumberInput: () => NumberInput,
105
121
  NumberInputControl: () => NumberInputControl,
106
122
  NumberInputDecrement: () => NumberInputDecrement,
107
123
  NumberInputIncrement: () => NumberInputIncrement,
108
124
  NumberInputInput: () => NumberInputInput,
125
+ NumericQuestion: () => NumericQuestion,
109
126
  Page: () => Page,
110
127
  PageContent: () => PageContent,
111
128
  PageFooter: () => PageFooter,
@@ -127,6 +144,11 @@ __export(index_exports, {
127
144
  PopoverTitle: () => PopoverTitle,
128
145
  PopoverTrigger: () => PopoverTrigger,
129
146
  Portal: () => import_portal5.Portal,
147
+ PrevNext: () => PrevNext,
148
+ Quiz: () => Quiz,
149
+ RadioGroup: () => RadioGroup,
150
+ RadioGroupItem: () => RadioGroupItem,
151
+ Reveal: () => Reveal,
130
152
  Row: () => Row,
131
153
  Scroll: () => Scroll,
132
154
  Select: () => Select,
@@ -163,6 +185,7 @@ __export(index_exports, {
163
185
  SidebarRail: () => Rail,
164
186
  SidebarSeparator: () => Separator,
165
187
  SidebarTrigger: () => Trigger,
188
+ SingleChoiceQuestion: () => SingleChoiceQuestion,
166
189
  Splitter: () => Splitter,
167
190
  SplitterPanel: () => SplitterPanel,
168
191
  SplitterResizeTrigger: () => SplitterResizeTrigger,
@@ -204,6 +227,9 @@ __export(index_exports, {
204
227
  WindowResizeTrigger: () => WindowResizeTrigger,
205
228
  WindowStageTrigger: () => WindowStageTrigger,
206
229
  WindowTitle: () => WindowTitle,
230
+ YouTube: () => YouTube,
231
+ YoutubeTimestampAt: () => YoutubeTimestampAt,
232
+ YoutubeTimestamps: () => YoutubeTimestamps,
207
233
  navbarMenuTriggerStyle: () => import_helix49.navbarMenuTriggerStyle,
208
234
  useCheckbox: () => useCheckbox,
209
235
  useCombobox: () => useCombobox,
@@ -215,6 +241,7 @@ __export(index_exports, {
215
241
  useNumberInput: () => useNumberInput,
216
242
  usePopover: () => import_popover.usePopover,
217
243
  usePopoverContext: () => import_popover.usePopoverContext,
244
+ useRadioGroup: () => useRadioGroup,
218
245
  useSelect: () => useSelect,
219
246
  useSidebar: () => useSidebar,
220
247
  useSwitch: () => useSwitch,
@@ -1999,6 +2026,1171 @@ function TagInputClearTrigger({ className, ...props }) {
1999
2026
  }
2000
2027
  var TagInputContext = import_tags_input.TagsInputContext;
2001
2028
  var useTagInput = import_tags_input.useTagsInputContext;
2029
+
2030
+ // src/mermaid.tsx
2031
+ var import_react7 = require("react");
2032
+ var import_factory35 = require("@ark-ui/react/factory");
2033
+ var import_helix59 = require("@cloudvoyant/helix");
2034
+ var import_jsx_runtime58 = require("react/jsx-runtime");
2035
+ function Mermaid({ code, svg, className, ...props }) {
2036
+ const [status, setStatus] = (0, import_react7.useState)(svg !== void 0 ? "done" : "loading");
2037
+ const [rendered, setRendered] = (0, import_react7.useState)(svg ?? null);
2038
+ const aspectRatio = rendered !== null ? (0, import_helix59.mermaidSvgAspectRatio)(rendered) : void 0;
2039
+ (0, import_react7.useEffect)(() => {
2040
+ if (svg !== void 0) return;
2041
+ let cancelled = false;
2042
+ setStatus("loading");
2043
+ setRendered(null);
2044
+ (0, import_helix59.renderMermaidSource)(code).then((markup) => {
2045
+ if (!cancelled) {
2046
+ setRendered(markup);
2047
+ setStatus("done");
2048
+ }
2049
+ }).catch(() => {
2050
+ if (!cancelled) setStatus("error");
2051
+ });
2052
+ return () => {
2053
+ cancelled = true;
2054
+ };
2055
+ }, [code, svg]);
2056
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
2057
+ import_factory35.ark.div,
2058
+ {
2059
+ ...props,
2060
+ "data-mermaid-code": JSON.stringify(code),
2061
+ "data-mermaid-src": rendered !== null ? code : void 0,
2062
+ "data-mermaid-state": status,
2063
+ style: aspectRatio !== void 0 ? { ...props.style, aspectRatio } : props.style,
2064
+ className: (0, import_helix59.cn)(import_helix59.mermaidRootBase, className),
2065
+ children: rendered !== null ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: import_helix59.mermaidSvgBase, dangerouslySetInnerHTML: { __html: rendered } }) : status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("pre", { className: import_helix59.mermaidSourceBase, children: code }) : /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_jsx_runtime58.Fragment, { children: [
2066
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
2067
+ "div",
2068
+ {
2069
+ className: import_helix59.mermaidLoadingBase,
2070
+ role: "status",
2071
+ "aria-label": "Rendering diagram",
2072
+ "data-mermaid-loading": true,
2073
+ children: [
2074
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { "aria-hidden": "true", className: "h-5 w-5 shrink-0 animate-spin rounded-full border-2 border-muted-foreground/25 border-t-muted-foreground" }),
2075
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "text-sm text-muted-foreground", children: "Rendering diagram" })
2076
+ ]
2077
+ }
2078
+ ),
2079
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("noscript", { children: [
2080
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("style", { children: "[data-mermaid-loading]{display:none}" }),
2081
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("pre", { className: import_helix59.mermaidSourceBase, children: code })
2082
+ ] })
2083
+ ] })
2084
+ }
2085
+ );
2086
+ }
2087
+
2088
+ // src/clipboard.tsx
2089
+ var import_clipboard = require("@ark-ui/react/clipboard");
2090
+ var import_helix60 = require("@cloudvoyant/helix");
2091
+ var import_jsx_runtime59 = require("react/jsx-runtime");
2092
+ function CopyIcon() {
2093
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
2094
+ "svg",
2095
+ {
2096
+ xmlns: "http://www.w3.org/2000/svg",
2097
+ viewBox: "0 0 24 24",
2098
+ fill: "none",
2099
+ stroke: "currentColor",
2100
+ strokeWidth: "2",
2101
+ strokeLinecap: "round",
2102
+ strokeLinejoin: "round",
2103
+ "aria-hidden": "true",
2104
+ children: [
2105
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" }),
2106
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
2107
+ ]
2108
+ }
2109
+ );
2110
+ }
2111
+ function CheckIcon() {
2112
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
2113
+ "svg",
2114
+ {
2115
+ xmlns: "http://www.w3.org/2000/svg",
2116
+ viewBox: "0 0 24 24",
2117
+ fill: "none",
2118
+ stroke: "currentColor",
2119
+ strokeWidth: "2",
2120
+ strokeLinecap: "round",
2121
+ strokeLinejoin: "round",
2122
+ "aria-hidden": "true",
2123
+ children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("path", { d: "M20 6 9 17l-5-5" })
2124
+ }
2125
+ );
2126
+ }
2127
+ function CopyButton({ value, label = "Copy", className, ...props }) {
2128
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_clipboard.ClipboardRoot, { value, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_clipboard.ClipboardTrigger, { className: (0, import_helix60.cn)(import_helix60.clipboardTriggerBase, className), "aria-label": label, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_clipboard.ClipboardIndicator, { copied: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(CheckIcon, {}), children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(CopyIcon, {}) }) }) });
2129
+ }
2130
+
2131
+ // src/radio-group.tsx
2132
+ var import_radio_group = require("@ark-ui/react/radio-group");
2133
+ var import_helix61 = require("@cloudvoyant/helix");
2134
+ var import_jsx_runtime60 = require("react/jsx-runtime");
2135
+ function RadioGroup({ className, ...props }) {
2136
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_radio_group.RadioGroupRoot, { className: (0, import_helix61.cn)(import_helix61.radioGroupRootBase, className), ...props });
2137
+ }
2138
+ function RadioGroupItem({ className, children, ...props }) {
2139
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_radio_group.RadioGroupItem, { className: (0, import_helix61.cn)("flex cursor-pointer items-center gap-2.5", className), ...props, children: [
2140
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_radio_group.RadioGroupItemControl, { className: import_helix61.radioGroupItemControlBase, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "size-1.5 rounded-full bg-current hidden [[data-state=checked]>&]:block" }) }),
2141
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_radio_group.RadioGroupItemText, { className: import_helix61.radioGroupItemTextBase, children }),
2142
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_radio_group.RadioGroupItemHiddenInput, {})
2143
+ ] });
2144
+ }
2145
+ var useRadioGroup = import_radio_group.useRadioGroupContext;
2146
+
2147
+ // src/notice.tsx
2148
+ var import_factory36 = require("@ark-ui/react/factory");
2149
+ var import_helix62 = require("@cloudvoyant/helix");
2150
+ var import_jsx_runtime61 = require("react/jsx-runtime");
2151
+ function InfoIcon() {
2152
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
2153
+ "svg",
2154
+ {
2155
+ xmlns: "http://www.w3.org/2000/svg",
2156
+ viewBox: "0 0 24 24",
2157
+ fill: "none",
2158
+ stroke: "currentColor",
2159
+ strokeWidth: "2",
2160
+ strokeLinecap: "round",
2161
+ strokeLinejoin: "round",
2162
+ "aria-hidden": "true",
2163
+ children: [
2164
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
2165
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M12 16v-4" }),
2166
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M12 8h.01" })
2167
+ ]
2168
+ }
2169
+ );
2170
+ }
2171
+ function CheckCircleIcon() {
2172
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
2173
+ "svg",
2174
+ {
2175
+ xmlns: "http://www.w3.org/2000/svg",
2176
+ viewBox: "0 0 24 24",
2177
+ fill: "none",
2178
+ stroke: "currentColor",
2179
+ strokeWidth: "2",
2180
+ strokeLinecap: "round",
2181
+ strokeLinejoin: "round",
2182
+ "aria-hidden": "true",
2183
+ children: [
2184
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
2185
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "m9 12 2 2 4-4" })
2186
+ ]
2187
+ }
2188
+ );
2189
+ }
2190
+ function TriangleAlertIcon() {
2191
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
2192
+ "svg",
2193
+ {
2194
+ xmlns: "http://www.w3.org/2000/svg",
2195
+ viewBox: "0 0 24 24",
2196
+ fill: "none",
2197
+ stroke: "currentColor",
2198
+ strokeWidth: "2",
2199
+ strokeLinecap: "round",
2200
+ strokeLinejoin: "round",
2201
+ "aria-hidden": "true",
2202
+ children: [
2203
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "m21.73 18-8-14a2 2 0 0 0-3.46 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }),
2204
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M12 9v4" }),
2205
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "M12 17h.01" })
2206
+ ]
2207
+ }
2208
+ );
2209
+ }
2210
+ function CircleXIcon() {
2211
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
2212
+ "svg",
2213
+ {
2214
+ xmlns: "http://www.w3.org/2000/svg",
2215
+ viewBox: "0 0 24 24",
2216
+ fill: "none",
2217
+ stroke: "currentColor",
2218
+ strokeWidth: "2",
2219
+ strokeLinecap: "round",
2220
+ strokeLinejoin: "round",
2221
+ "aria-hidden": "true",
2222
+ children: [
2223
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
2224
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "m15 9-6 6" }),
2225
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { d: "m9 9 6 6" })
2226
+ ]
2227
+ }
2228
+ );
2229
+ }
2230
+ var noticeIcons = {
2231
+ info: InfoIcon,
2232
+ success: CheckCircleIcon,
2233
+ warning: TriangleAlertIcon,
2234
+ error: CircleXIcon
2235
+ };
2236
+ function Notice({ variant = "info", title, children, className, ...props }) {
2237
+ const Icon = variant !== null && variant !== void 0 && variant !== "none" ? noticeIcons[variant] : null;
2238
+ const role = variant === "error" ? "alert" : variant === "none" ? void 0 : "status";
2239
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_factory36.ark.div, { role, className: (0, import_helix62.cn)((0, import_helix62.noticeVariants)({ variant }), className), ...props, children: [
2240
+ Icon ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Icon, {}) : null,
2241
+ title ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_factory36.ark.div, { className: import_helix62.noticeTitleBase, children: title }) : null,
2242
+ children ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_factory36.ark.div, { className: import_helix62.noticeDescriptionBase, children }) : null
2243
+ ] });
2244
+ }
2245
+
2246
+ // src/figure.tsx
2247
+ var import_factory37 = require("@ark-ui/react/factory");
2248
+ var import_helix63 = require("@cloudvoyant/helix");
2249
+ var import_jsx_runtime62 = require("react/jsx-runtime");
2250
+ function Figure({ src, alt, img, caption, className, ...props }) {
2251
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_factory37.ark.figure, { className: (0, import_helix63.cn)(import_helix63.figureRootBase, className), ...props, children: [
2252
+ img ?? (src ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_factory37.ark.img, { src, alt, loading: "lazy", className: import_helix63.figureImageBase }) : null),
2253
+ caption ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_factory37.ark.figcaption, { className: import_helix63.figureCaptionBase, children: caption }) : null
2254
+ ] });
2255
+ }
2256
+
2257
+ // src/reveal.tsx
2258
+ var import_collapsible2 = require("@ark-ui/react/collapsible");
2259
+ var import_helix64 = require("@cloudvoyant/helix");
2260
+ var import_jsx_runtime63 = require("react/jsx-runtime");
2261
+ function ChevronRightIcon({ className }) {
2262
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
2263
+ "svg",
2264
+ {
2265
+ xmlns: "http://www.w3.org/2000/svg",
2266
+ viewBox: "0 0 24 24",
2267
+ fill: "none",
2268
+ stroke: "currentColor",
2269
+ strokeWidth: "2",
2270
+ strokeLinecap: "round",
2271
+ strokeLinejoin: "round",
2272
+ "aria-hidden": "true",
2273
+ className,
2274
+ children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("path", { d: "m9 18 6-6-6-6" })
2275
+ }
2276
+ );
2277
+ }
2278
+ function Reveal({ question, children, className, ...props }) {
2279
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_collapsible2.CollapsibleRoot, { className: (0, import_helix64.cn)(import_helix64.revealRootBase, className), ...props, children: [
2280
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_collapsible2.CollapsibleTrigger, { className: import_helix64.revealTriggerBase, children: [
2281
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ChevronRightIcon, { className: import_helix64.revealChevronBase }),
2282
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { children: question })
2283
+ ] }),
2284
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_collapsible2.CollapsibleContent, { className: import_helix64.revealContentBase, children })
2285
+ ] });
2286
+ }
2287
+
2288
+ // src/prevnext.tsx
2289
+ var import_factory38 = require("@ark-ui/react/factory");
2290
+ var import_helix65 = require("@cloudvoyant/helix");
2291
+ var import_jsx_runtime64 = require("react/jsx-runtime");
2292
+ function PrevNext({ prev, next, className, ...props }) {
2293
+ if (!prev && !next) return null;
2294
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_factory38.ark.nav, { className: (0, import_helix65.cn)(import_helix65.prevNextRootBase, className), "aria-label": "Previous and next pages", ...props, children: [
2295
+ prev ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_factory38.ark.a, { href: prev.href, className: import_helix65.prevNextLinkBase, children: [
2296
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_factory38.ark.span, { className: import_helix65.prevNextDirectionBase, children: "Previous" }),
2297
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_factory38.ark.span, { className: import_helix65.prevNextTitleBase, children: [
2298
+ "\u2190 ",
2299
+ prev.title
2300
+ ] })
2301
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_factory38.ark.span, { className: import_helix65.prevNextSpacerBase }),
2302
+ next ? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_factory38.ark.a, { href: next.href, className: (0, import_helix65.cn)(import_helix65.prevNextLinkBase, import_helix65.prevNextLinkNextBase), children: [
2303
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_factory38.ark.span, { className: import_helix65.prevNextDirectionBase, children: "Next" }),
2304
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_factory38.ark.span, { className: import_helix65.prevNextTitleBase, children: [
2305
+ next.title,
2306
+ " \u2192"
2307
+ ] })
2308
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_factory38.ark.span, { className: import_helix65.prevNextSpacerBase })
2309
+ ] });
2310
+ }
2311
+
2312
+ // src/latex.tsx
2313
+ var import_factory39 = require("@ark-ui/react/factory");
2314
+ var import_helix66 = require("@cloudvoyant/helix");
2315
+ var import_jsx_runtime65 = require("react/jsx-runtime");
2316
+ function LaTeX({ latex, html, className, ...props }) {
2317
+ let markup;
2318
+ let error = false;
2319
+ if (html !== void 0) {
2320
+ markup = html;
2321
+ } else {
2322
+ try {
2323
+ markup = (0, import_helix66.toLaTeX)(latex, { displayMode: true });
2324
+ } catch {
2325
+ markup = latex;
2326
+ error = true;
2327
+ }
2328
+ }
2329
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
2330
+ import_factory39.ark.div,
2331
+ {
2332
+ ...props,
2333
+ "data-latex-state": error ? "error" : "done",
2334
+ className: (0, import_helix66.cn)(import_helix66.latexRootBase, import_helix66.latexDisplayBase, className),
2335
+ children: error ? /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("code", { className: import_helix66.latexErrorBase, children: latex }) : /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { dangerouslySetInnerHTML: { __html: markup } })
2336
+ }
2337
+ );
2338
+ }
2339
+ function InlineLaTeX({ latex, html, className, ...props }) {
2340
+ let markup;
2341
+ let error = false;
2342
+ if (html !== void 0) {
2343
+ markup = html;
2344
+ } else {
2345
+ try {
2346
+ markup = (0, import_helix66.toLaTeX)(latex);
2347
+ } catch {
2348
+ markup = latex;
2349
+ error = true;
2350
+ }
2351
+ }
2352
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
2353
+ import_factory39.ark.span,
2354
+ {
2355
+ ...props,
2356
+ "data-latex-state": error ? "error" : "done",
2357
+ className: (0, import_helix66.cn)(import_helix66.latexRootBase, import_helix66.latexInlineBase, className),
2358
+ children: error ? /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("code", { className: import_helix66.latexErrorBase, children: latex }) : /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { dangerouslySetInnerHTML: { __html: markup } })
2359
+ }
2360
+ );
2361
+ }
2362
+
2363
+ // src/code-block.tsx
2364
+ var import_react8 = require("react");
2365
+ var import_factory40 = require("@ark-ui/react/factory");
2366
+ var import_helix67 = require("@cloudvoyant/helix");
2367
+ var import_jsx_runtime66 = require("react/jsx-runtime");
2368
+ var CodeBlockContext = (0, import_react8.createContext)(null);
2369
+ function useCodeBlock() {
2370
+ const ctx = (0, import_react8.useContext)(CodeBlockContext);
2371
+ if (!ctx) throw new Error("CodeBlock parts must be rendered inside a <CodeBlock>.");
2372
+ return ctx;
2373
+ }
2374
+ function CodeRenderer({ code, language, html, showLineNumbers, scrollable, maxHeight, highlightLines }) {
2375
+ const [rendered, setRendered] = (0, import_react8.useState)(html ?? null);
2376
+ (0, import_react8.useEffect)(() => {
2377
+ (0, import_helix67.injectCodeBlockStyles)();
2378
+ }, []);
2379
+ const highlightKey = highlightLines?.join(",");
2380
+ (0, import_react8.useEffect)(() => {
2381
+ if (html !== void 0) return;
2382
+ let cancelled = false;
2383
+ setRendered(null);
2384
+ (0, import_helix67.renderCodeToHtml)(code, language, highlightLines).then((h) => {
2385
+ if (!cancelled) setRendered(h);
2386
+ });
2387
+ return () => {
2388
+ cancelled = true;
2389
+ };
2390
+ }, [code, language, html, highlightKey]);
2391
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
2392
+ "div",
2393
+ {
2394
+ className: (0, import_helix67.cn)(import_helix67.codeBlockBodyBase, scrollable && import_helix67.codeBlockBodyScrollableBase),
2395
+ style: scrollable ? { maxHeight: `${maxHeight}px` } : void 0,
2396
+ children: rendered !== null ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
2397
+ "div",
2398
+ {
2399
+ dangerouslySetInnerHTML: { __html: rendered },
2400
+ className: (0, import_helix67.cn)(
2401
+ import_helix67.codeBlockContentBase,
2402
+ showLineNumbers && import_helix67.codeBlockLineNumbersBase,
2403
+ highlightLines?.length && import_helix67.codeBlockHighlightBase
2404
+ )
2405
+ }
2406
+ ) : /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: import_helix67.codeBlockLoadingBase, children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: import_helix67.codeBlockSpinnerBase }) })
2407
+ }
2408
+ );
2409
+ }
2410
+ function CodeBlock({
2411
+ code,
2412
+ language = "tsx",
2413
+ filename,
2414
+ html,
2415
+ showLineNumbers = false,
2416
+ scrollable = false,
2417
+ maxHeight = 400,
2418
+ highlightLines,
2419
+ className,
2420
+ children,
2421
+ ...props
2422
+ }) {
2423
+ const ctx = { code, language, html, showLineNumbers, scrollable, maxHeight, highlightLines };
2424
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(CodeBlockContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_factory40.ark.div, { "data-code-block": true, className: (0, import_helix67.cn)(import_helix67.codeBlockRootBase, className), ...props, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(import_jsx_runtime66.Fragment, { children: [
2425
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(CodeBlockHeader, { children: [
2426
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(CodeBlockTitle, { children: filename ?? language }),
2427
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "ml-auto", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(CodeBlockCopyButton, {}) })
2428
+ ] }),
2429
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(CodeBlockContent, {})
2430
+ ] }) }) });
2431
+ }
2432
+ function CodeBlockHeader({ className, children, ...props }) {
2433
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_factory40.ark.div, { className: (0, import_helix67.cn)(import_helix67.codeBlockHeaderBase, className), ...props, children });
2434
+ }
2435
+ function CodeBlockTitle({ className, children, ...props }) {
2436
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_factory40.ark.span, { className: (0, import_helix67.cn)(import_helix67.codeBlockTitleBase, className), ...props, children });
2437
+ }
2438
+ function CodeBlockCopyButton({ label = "Copy code", className, ...props }) {
2439
+ const { code } = useCodeBlock();
2440
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_factory40.ark.div, { className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(CopyButton, { value: code, label }) });
2441
+ }
2442
+ function CodeBlockContent({ className, html, ...props }) {
2443
+ const ctx = useCodeBlock();
2444
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(import_factory40.ark.div, { className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(CodeRenderer, { ...ctx, html: html ?? ctx.html }) });
2445
+ }
2446
+ function MultiFileCodeBlock({
2447
+ files,
2448
+ showLineNumbers = false,
2449
+ scrollable = false,
2450
+ maxHeight = 400,
2451
+ className,
2452
+ ...props
2453
+ }) {
2454
+ const [active, setActive] = (0, import_react8.useState)(files[0]?.filename ?? "");
2455
+ const file = files.find((f) => f.filename === active) ?? files[0];
2456
+ (0, import_react8.useEffect)(() => {
2457
+ if (!files.some((f) => f.filename === active)) {
2458
+ setActive(files[0]?.filename ?? "");
2459
+ }
2460
+ }, [files, active]);
2461
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(import_factory40.ark.div, { "data-code-block": true, className: (0, import_helix67.cn)(import_helix67.codeBlockRootBase, className), ...props, children: [
2462
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "flex items-center justify-between border-b bg-muted/50", children: [
2463
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { role: "tablist", "aria-label": "Files", className: "flex overflow-x-auto no-scrollbar pl-1", children: files.map((f) => /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
2464
+ "button",
2465
+ {
2466
+ role: "tab",
2467
+ "aria-selected": active === f.filename,
2468
+ onClick: () => setActive(f.filename),
2469
+ className: (0, import_helix67.cn)(
2470
+ "h-10 shrink-0 border-b-2 px-3 font-mono text-xs transition-colors",
2471
+ active === f.filename ? "border-foreground text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
2472
+ ),
2473
+ children: f.filename
2474
+ },
2475
+ f.filename
2476
+ )) }),
2477
+ file ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "shrink-0 pr-3", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(CopyButton, { value: file.code, label: "Copy code" }) }) : null
2478
+ ] }),
2479
+ file ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
2480
+ CodeRenderer,
2481
+ {
2482
+ code: file.code,
2483
+ language: file.language ?? "tsx",
2484
+ html: file.html,
2485
+ showLineNumbers,
2486
+ scrollable,
2487
+ maxHeight
2488
+ }
2489
+ ) : null
2490
+ ] });
2491
+ }
2492
+ function LanguageTabsCodeBlock({
2493
+ tabs,
2494
+ showLineNumbers = false,
2495
+ scrollable = false,
2496
+ maxHeight = 400,
2497
+ className,
2498
+ ...props
2499
+ }) {
2500
+ const [active, setActive] = (0, import_react8.useState)(tabs[0]?.label ?? "");
2501
+ const tab = tabs.find((t) => t.label === active) ?? tabs[0];
2502
+ (0, import_react8.useEffect)(() => {
2503
+ if (!tabs.some((t) => t.label === active)) {
2504
+ setActive(tabs[0]?.label ?? "");
2505
+ }
2506
+ }, [tabs, active]);
2507
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(import_factory40.ark.div, { "data-code-block": true, className: (0, import_helix67.cn)(import_helix67.codeBlockRootBase, className), ...props, children: [
2508
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(CodeBlockHeader, { children: [
2509
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(CodeBlockTitle, { children: tab?.filename }),
2510
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "ml-auto", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
2511
+ Select,
2512
+ {
2513
+ items: tabs.map((t) => ({ value: t.label, label: t.label })),
2514
+ value: [active],
2515
+ onValueChange: (details) => setActive(details.value[0]),
2516
+ "aria-label": "Language",
2517
+ children: [
2518
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(SelectTrigger, { size: "sm", className: "min-w-28 justify-between font-mono text-xs", children: [
2519
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(SelectValue, {}),
2520
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(SelectIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
2521
+ "svg",
2522
+ {
2523
+ xmlns: "http://www.w3.org/2000/svg",
2524
+ viewBox: "0 0 24 24",
2525
+ fill: "none",
2526
+ stroke: "currentColor",
2527
+ strokeWidth: "2",
2528
+ strokeLinecap: "round",
2529
+ strokeLinejoin: "round",
2530
+ "aria-hidden": "true",
2531
+ children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("path", { d: "m6 9 6 6 6-6" })
2532
+ }
2533
+ ) })
2534
+ ] }),
2535
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(SelectContent, { children: tabs.map((t) => /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(SelectItem, { item: { value: t.label, label: t.label }, children: [
2536
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(SelectItemText, { children: t.label }),
2537
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(SelectItemIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
2538
+ "svg",
2539
+ {
2540
+ xmlns: "http://www.w3.org/2000/svg",
2541
+ viewBox: "0 0 24 24",
2542
+ fill: "none",
2543
+ stroke: "currentColor",
2544
+ strokeWidth: "2",
2545
+ strokeLinecap: "round",
2546
+ strokeLinejoin: "round",
2547
+ "aria-hidden": "true",
2548
+ children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("path", { d: "M20 6 9 17l-5-5" })
2549
+ }
2550
+ ) })
2551
+ ] }, t.label)) })
2552
+ ]
2553
+ }
2554
+ ) })
2555
+ ] }),
2556
+ tab ? /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "relative", children: [
2557
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
2558
+ CodeRenderer,
2559
+ {
2560
+ code: tab.code,
2561
+ language: tab.language ?? "tsx",
2562
+ html: tab.html,
2563
+ showLineNumbers,
2564
+ scrollable,
2565
+ maxHeight
2566
+ }
2567
+ ),
2568
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: import_helix67.codeBlockCopyFloatBase, children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(CopyButton, { value: tab.code, label: "Copy code" }) })
2569
+ ] }) : null
2570
+ ] });
2571
+ }
2572
+
2573
+ // src/manim.tsx
2574
+ var import_react9 = require("react");
2575
+ var import_factory41 = require("@ark-ui/react/factory");
2576
+ var import_helix68 = require("@cloudvoyant/helix");
2577
+ var import_jsx_runtime67 = require("react/jsx-runtime");
2578
+ function Manim({ build, width = 800, height = 450, caption, className, ...props }) {
2579
+ const wrapperRef = (0, import_react9.useRef)(null);
2580
+ const containerRef = (0, import_react9.useRef)(null);
2581
+ const [state, setState] = (0, import_react9.useState)("loading");
2582
+ const [errorMsg, setErrorMsg] = (0, import_react9.useState)("");
2583
+ (0, import_react9.useEffect)(() => {
2584
+ const wrapper = wrapperRef.current;
2585
+ if (!wrapper) return;
2586
+ let disposed = false;
2587
+ let player = null;
2588
+ let resizeTimer;
2589
+ let mountedWidth = 0;
2590
+ let generation = 0;
2591
+ function fail(msg) {
2592
+ if (!disposed) {
2593
+ setErrorMsg(msg);
2594
+ setState("error");
2595
+ }
2596
+ }
2597
+ async function mount(pixelWidth) {
2598
+ const gen = ++generation;
2599
+ try {
2600
+ const manim = await import("manim-web");
2601
+ if (disposed || gen !== generation || !containerRef.current) return;
2602
+ try {
2603
+ player?.dispose?.();
2604
+ } catch {
2605
+ }
2606
+ containerRef.current.replaceChildren();
2607
+ mountedWidth = pixelWidth;
2608
+ player = new manim.Player(containerRef.current, {
2609
+ width: pixelWidth,
2610
+ height: Math.round(pixelWidth * height / width),
2611
+ backgroundOpacity: 0,
2612
+ autoPlay: true,
2613
+ loop: false
2614
+ });
2615
+ setState("ready");
2616
+ await player.sequence(async (scene) => {
2617
+ await build(manim, scene);
2618
+ });
2619
+ } catch (err) {
2620
+ if (gen === generation) {
2621
+ fail(`Failed to load animation: ${err instanceof Error ? err.message : String(err)}`);
2622
+ }
2623
+ }
2624
+ }
2625
+ const initialWidth = Math.floor(wrapper.getBoundingClientRect().width);
2626
+ if (initialWidth > 0) void mount(initialWidth);
2627
+ const observer = new ResizeObserver((entries) => {
2628
+ const measured = Math.floor(entries[0]?.contentRect.width ?? 0);
2629
+ if (measured <= 0 || measured === mountedWidth) return;
2630
+ clearTimeout(resizeTimer);
2631
+ resizeTimer = setTimeout(() => {
2632
+ if (!disposed) void mount(measured);
2633
+ }, 200);
2634
+ });
2635
+ observer.observe(wrapper);
2636
+ return () => {
2637
+ disposed = true;
2638
+ clearTimeout(resizeTimer);
2639
+ observer.disconnect();
2640
+ try {
2641
+ player?.dispose?.();
2642
+ } catch {
2643
+ }
2644
+ };
2645
+ }, [build, width, height]);
2646
+ return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(import_factory41.ark.figure, { "data-manim-state": state, className: (0, import_helix68.cn)(import_helix68.manimRootBase, className), ...props, children: [
2647
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { ref: wrapperRef, className: import_helix68.manimContainerBase, children: [
2648
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { ref: containerRef, className: "w-full" }),
2649
+ state === "loading" && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: import_helix68.manimPlaceholderBase, style: { aspectRatio: `${width} / ${height}` }, children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: import_helix68.manimPlaceholderLabelBase, children: "Loading animation\u2026" }) }),
2650
+ state === "error" && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: import_helix68.manimErrorBase, children: errorMsg })
2651
+ ] }),
2652
+ caption ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_factory41.ark.figcaption, { className: import_helix68.manimCaptionBase, children: caption }) : null
2653
+ ] });
2654
+ }
2655
+
2656
+ // src/youtube.tsx
2657
+ var import_react10 = require("react");
2658
+ var import_factory42 = require("@ark-ui/react/factory");
2659
+ var import_helix69 = require("@cloudvoyant/helix");
2660
+ var import_jsx_runtime68 = require("react/jsx-runtime");
2661
+ function PlayIcon() {
2662
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
2663
+ "svg",
2664
+ {
2665
+ xmlns: "http://www.w3.org/2000/svg",
2666
+ viewBox: "0 0 24 24",
2667
+ fill: "currentColor",
2668
+ className: "h-8 w-8",
2669
+ "aria-hidden": "true",
2670
+ children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("path", { d: "M8 5v14l11-7z" })
2671
+ }
2672
+ );
2673
+ }
2674
+ function ChevronRightIcon2({ className }) {
2675
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
2676
+ "svg",
2677
+ {
2678
+ xmlns: "http://www.w3.org/2000/svg",
2679
+ viewBox: "0 0 24 24",
2680
+ fill: "none",
2681
+ stroke: "currentColor",
2682
+ strokeWidth: "2",
2683
+ strokeLinecap: "round",
2684
+ strokeLinejoin: "round",
2685
+ "aria-hidden": "true",
2686
+ className,
2687
+ children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("path", { d: "m9 18 6-6-6-6" })
2688
+ }
2689
+ );
2690
+ }
2691
+ var YouTubeContext = (0, import_react10.createContext)(null);
2692
+ function useYouTube() {
2693
+ const ctx = (0, import_react10.useContext)(YouTubeContext);
2694
+ if (!ctx) throw new Error("YoutubeTimestamps must be rendered inside a <YouTube>.");
2695
+ return ctx;
2696
+ }
2697
+ function YouTube({ url, title, description, poster, className, children, ...props }) {
2698
+ const videoId = (0, import_helix69.extractYouTubeId)(url);
2699
+ const posterUrl = poster ?? `https://i.ytimg.com/vi/${videoId}/hqdefault.jpg`;
2700
+ const [playing, setPlaying] = (0, import_react10.useState)(false);
2701
+ const [startAt, setStartAt] = (0, import_react10.useState)(null);
2702
+ const seek = (t) => {
2703
+ setStartAt(t);
2704
+ setPlaying(true);
2705
+ };
2706
+ const src = `https://www.youtube-nocookie.com/embed/${videoId}?autoplay=1${startAt != null ? `&start=${startAt}` : ""}`;
2707
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(YouTubeContext.Provider, { value: { url, videoId, seek }, children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_factory42.ark.div, { "data-youtube-id": videoId, className: (0, import_helix69.cn)(import_helix69.youtubeRootBase, className), ...props, children: [
2708
+ title ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_factory42.ark.h3, { className: import_helix69.youtubeTitleBase, children: title }) : null,
2709
+ playing ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
2710
+ "iframe",
2711
+ {
2712
+ src,
2713
+ title: title ?? `YouTube video ${videoId}`,
2714
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
2715
+ allowFullScreen: true,
2716
+ className: "aspect-video w-full rounded-md border border-border"
2717
+ }
2718
+ ) : /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
2719
+ import_factory42.ark.button,
2720
+ {
2721
+ type: "button",
2722
+ className: import_helix69.youtubeFacadeBase,
2723
+ onClick: () => setPlaying(true),
2724
+ "aria-label": title ? `Play video: ${title}` : "Play video",
2725
+ children: [
2726
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_factory42.ark.img, { src: posterUrl, alt: title ?? `YouTube video ${videoId}`, loading: "lazy", className: "h-full w-full object-cover" }),
2727
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_factory42.ark.span, { className: import_helix69.youtubePlayButtonBase, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_factory42.ark.span, { className: import_helix69.youtubePlayButtonInnerBase, children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(PlayIcon, {}) }) })
2728
+ ]
2729
+ }
2730
+ ),
2731
+ description ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_factory42.ark.p, { className: import_helix69.youtubeDescriptionBase, children: description }) : null,
2732
+ children
2733
+ ] }) });
2734
+ }
2735
+ function YoutubeTimestampAt({ t, children, className, ...props }) {
2736
+ const { seek } = useYouTube();
2737
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_factory42.ark.li, { className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_factory42.ark.button, { type: "button", onClick: () => seek(t), className: import_helix69.youtubeChapterButtonBase, children: [
2738
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_factory42.ark.span, { className: import_helix69.youtubeChapterTimeBase, children: (0, import_helix69.formatTime)(t) }),
2739
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_factory42.ark.span, { className: import_helix69.youtubeChapterLabelBase, children })
2740
+ ] }) });
2741
+ }
2742
+ function YoutubeTimestamps({ chapters, children, className, ...props }) {
2743
+ const { url } = useYouTube();
2744
+ const [inferred, setInferred] = (0, import_react10.useState)([]);
2745
+ const [loading, setLoading] = (0, import_react10.useState)(chapters === void 0);
2746
+ (0, import_react10.useEffect)(() => {
2747
+ if (chapters !== void 0) return;
2748
+ let cancelled = false;
2749
+ setLoading(true);
2750
+ (0, import_helix69.fetchYouTubeMetadata)(url).then((meta) => {
2751
+ if (!cancelled) {
2752
+ setInferred(meta.description ? (0, import_helix69.parseYouTubeChapters)(meta.description) : []);
2753
+ setLoading(false);
2754
+ }
2755
+ }).catch(() => {
2756
+ if (!cancelled) setLoading(false);
2757
+ });
2758
+ return () => {
2759
+ cancelled = true;
2760
+ };
2761
+ }, [url, chapters]);
2762
+ const resolved = chapters ?? inferred;
2763
+ const hasChildren = children !== void 0 && children !== null;
2764
+ if (!loading && resolved.length === 0 && !hasChildren) return null;
2765
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_factory42.ark.div, { className: (0, import_helix69.cn)(import_helix69.youtubeChaptersBase, className), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("details", { className: "group", open: true, children: [
2766
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_factory42.ark.summary, { className: import_helix69.youtubeChaptersSummaryBase, children: [
2767
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ChevronRightIcon2, { className: import_helix69.youtubeChaptersChevronBase }),
2768
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: "Timestamps" })
2769
+ ] }),
2770
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(import_factory42.ark.nav, { "aria-label": "Video timestamps", className: import_helix69.youtubeChaptersListBase, children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(import_factory42.ark.ul, { className: "space-y-1", children: [
2771
+ resolved.map((ch) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(YoutubeTimestampAt, { t: ch.t, children: ch.label }, ch.t)),
2772
+ children
2773
+ ] }) })
2774
+ ] }) });
2775
+ }
2776
+
2777
+ // src/chart.tsx
2778
+ var import_factory43 = require("@ark-ui/react/factory");
2779
+ var import_react11 = require("@tanstack/charts/react");
2780
+ var import_helix70 = require("@cloudvoyant/helix");
2781
+ var import_jsx_runtime69 = require("react/jsx-runtime");
2782
+ function Chart({ svg, className, ...props }) {
2783
+ const { type, height = 320 } = props;
2784
+ if (svg !== void 0) {
2785
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_factory43.ark.div, { "data-chart-state": "prerendered", "data-chart-type": type, className: (0, import_helix70.cn)(import_helix70.chartRootBase, className), children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "flex w-full justify-center [&>svg]:max-w-full", dangerouslySetInnerHTML: { __html: svg } }) });
2786
+ }
2787
+ const definition = (0, import_helix70.buildChartDefinition)(props);
2788
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_factory43.ark.div, { "data-chart-state": "ready", "data-chart-type": type, className: (0, import_helix70.cn)(import_helix70.chartRootBase, className), children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(import_react11.Chart, { definition, height, ariaLabel: type === "pie" ? "Pie chart" : "Chart" }) });
2789
+ }
2790
+
2791
+ // src/questions.tsx
2792
+ var import_react12 = require("react");
2793
+ var import_factory44 = require("@ark-ui/react/factory");
2794
+ var import_helix71 = require("@cloudvoyant/helix");
2795
+ var import_jsx_runtime70 = require("react/jsx-runtime");
2796
+ function CheckCircleIcon2() {
2797
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(
2798
+ "svg",
2799
+ {
2800
+ xmlns: "http://www.w3.org/2000/svg",
2801
+ viewBox: "0 0 24 24",
2802
+ fill: "none",
2803
+ stroke: "currentColor",
2804
+ strokeWidth: "2",
2805
+ strokeLinecap: "round",
2806
+ strokeLinejoin: "round",
2807
+ "aria-hidden": "true",
2808
+ className: "size-4 shrink-0",
2809
+ children: [
2810
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
2811
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("path", { d: "m9 12 2 2 4-4" })
2812
+ ]
2813
+ }
2814
+ );
2815
+ }
2816
+ function CircleXIcon2() {
2817
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(
2818
+ "svg",
2819
+ {
2820
+ xmlns: "http://www.w3.org/2000/svg",
2821
+ viewBox: "0 0 24 24",
2822
+ fill: "none",
2823
+ stroke: "currentColor",
2824
+ strokeWidth: "2",
2825
+ strokeLinecap: "round",
2826
+ strokeLinejoin: "round",
2827
+ "aria-hidden": "true",
2828
+ className: "size-4 shrink-0",
2829
+ children: [
2830
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
2831
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("path", { d: "m15 9-6 6" }),
2832
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("path", { d: "m9 9 6 6" })
2833
+ ]
2834
+ }
2835
+ );
2836
+ }
2837
+ function CheckIcon2() {
2838
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
2839
+ "svg",
2840
+ {
2841
+ xmlns: "http://www.w3.org/2000/svg",
2842
+ viewBox: "0 0 24 24",
2843
+ fill: "none",
2844
+ stroke: "currentColor",
2845
+ strokeWidth: "2",
2846
+ strokeLinecap: "round",
2847
+ strokeLinejoin: "round",
2848
+ "aria-hidden": "true",
2849
+ children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("path", { d: "M20 6 9 17l-5-5" })
2850
+ }
2851
+ );
2852
+ }
2853
+ function Feedback({ correct, explanation }) {
2854
+ if (correct === null) return null;
2855
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { "aria-live": "polite", role: "status", className: "mt-3", children: [
2856
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
2857
+ "div",
2858
+ {
2859
+ className: (0, import_helix71.cn)(
2860
+ "flex items-center gap-2 text-sm font-medium",
2861
+ correct ? import_helix71.feedbackCorrectBase : import_helix71.feedbackIncorrectBase
2862
+ ),
2863
+ children: correct ? /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
2864
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(CheckCircleIcon2, {}),
2865
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { children: "Correct" })
2866
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
2867
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(CircleXIcon2, {}),
2868
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { children: "Incorrect" })
2869
+ ] })
2870
+ }
2871
+ ),
2872
+ explanation ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: import_helix71.feedbackExplanationBase, children: explanation }) : null
2873
+ ] });
2874
+ }
2875
+ function SingleChoiceRenderer({
2876
+ prompt,
2877
+ choices,
2878
+ correct,
2879
+ explanation,
2880
+ quiz = false,
2881
+ submitted = false,
2882
+ onAnswerChange,
2883
+ onGraded,
2884
+ className,
2885
+ ...rest
2886
+ }) {
2887
+ const [selected, setSelected] = (0, import_react12.useState)(null);
2888
+ const [result, setResult] = (0, import_react12.useState)(null);
2889
+ (0, import_react12.useEffect)(() => {
2890
+ if (quiz) {
2891
+ const isAnswered = selected !== null;
2892
+ onAnswerChange?.({ answered: isAnswered, correct: isAnswered && selected === correct });
2893
+ }
2894
+ }, [quiz, selected, correct]);
2895
+ const displayResult = quiz ? submitted ? selected === correct : null : result;
2896
+ const handleCheck = () => {
2897
+ if (selected === null) return;
2898
+ const isCorrect = selected === correct;
2899
+ setResult(isCorrect);
2900
+ onGraded?.(isCorrect);
2901
+ };
2902
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: (0, import_helix71.cn)(import_helix71.questionCardBase, className), ...rest, children: [
2903
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: import_helix71.questionPromptBase, children: prompt }),
2904
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
2905
+ RadioGroup,
2906
+ {
2907
+ orientation: "vertical",
2908
+ value: selected !== null ? String(selected) : null,
2909
+ onValueChange: (details) => {
2910
+ if (quiz ? submitted : result !== null) return;
2911
+ setSelected(details.value != null ? Number(details.value) : null);
2912
+ },
2913
+ disabled: quiz ? submitted : result !== null,
2914
+ className: import_helix71.questionGroupBase,
2915
+ children: choices.map((choice, i) => /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
2916
+ RadioGroupItem,
2917
+ {
2918
+ value: String(i),
2919
+ className: (0, import_helix71.cn)(
2920
+ import_helix71.questionOptionBase,
2921
+ displayResult !== null && i === correct && import_helix71.questionOptionCorrectBase,
2922
+ displayResult !== null && i === selected && i !== correct && import_helix71.questionOptionIncorrectBase
2923
+ ),
2924
+ children: choice
2925
+ },
2926
+ i
2927
+ ))
2928
+ }
2929
+ ),
2930
+ !quiz && result === null && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
2931
+ import_factory44.ark.button,
2932
+ {
2933
+ type: "button",
2934
+ onClick: handleCheck,
2935
+ disabled: selected === null,
2936
+ className: import_helix71.questionCheckButtonBase,
2937
+ children: "Check"
2938
+ }
2939
+ ),
2940
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Feedback, { correct: displayResult, explanation: displayResult !== null ? explanation : void 0 })
2941
+ ] });
2942
+ }
2943
+ function MultipleChoiceRenderer({
2944
+ prompt,
2945
+ choices,
2946
+ correct,
2947
+ explanation,
2948
+ quiz = false,
2949
+ submitted = false,
2950
+ onAnswerChange,
2951
+ onGraded,
2952
+ className,
2953
+ ...rest
2954
+ }) {
2955
+ const [selected, setSelected] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
2956
+ const [result, setResult] = (0, import_react12.useState)(null);
2957
+ const computeCorrect = () => {
2958
+ const correctSet = new Set(correct);
2959
+ return selected.size === correctSet.size && [...selected].every((v) => correctSet.has(v));
2960
+ };
2961
+ (0, import_react12.useEffect)(() => {
2962
+ if (quiz) {
2963
+ const isAnswered = selected.size > 0;
2964
+ onAnswerChange?.({ answered: isAnswered, correct: isAnswered && computeCorrect() });
2965
+ }
2966
+ }, [quiz, selected, correct]);
2967
+ const toggleOption = (index) => {
2968
+ if (quiz ? submitted : result !== null) return;
2969
+ setSelected((prev) => {
2970
+ const next = new Set(prev);
2971
+ if (next.has(index)) next.delete(index);
2972
+ else next.add(index);
2973
+ return next;
2974
+ });
2975
+ };
2976
+ const displayResult = quiz ? submitted ? computeCorrect() : null : result;
2977
+ const handleCheck = () => {
2978
+ if (selected.size === 0) return;
2979
+ const isCorrect = computeCorrect();
2980
+ setResult(isCorrect);
2981
+ onGraded?.(isCorrect);
2982
+ };
2983
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: (0, import_helix71.cn)(import_helix71.questionCardBase, className), ...rest, children: [
2984
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: import_helix71.questionPromptBase, children: prompt }),
2985
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { role: "group", className: import_helix71.questionGroupBase, children: choices.map((choice, i) => {
2986
+ const isCorrectOption = correct.includes(i);
2987
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(
2988
+ Checkbox,
2989
+ {
2990
+ checked: selected.has(i),
2991
+ onCheckedChange: () => toggleOption(i),
2992
+ disabled: quiz ? submitted : result !== null,
2993
+ className: (0, import_helix71.cn)(
2994
+ import_helix71.questionOptionBase,
2995
+ displayResult !== null && isCorrectOption && import_helix71.questionOptionCorrectBase,
2996
+ displayResult !== null && selected.has(i) && !isCorrectOption && import_helix71.questionOptionIncorrectBase
2997
+ ),
2998
+ children: [
2999
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(CheckboxControl, { children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(CheckboxIndicator, { children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(CheckIcon2, {}) }) }),
3000
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(CheckboxLabel, { children: choice })
3001
+ ]
3002
+ },
3003
+ i
3004
+ );
3005
+ }) }),
3006
+ !quiz && result === null && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
3007
+ import_factory44.ark.button,
3008
+ {
3009
+ type: "button",
3010
+ onClick: handleCheck,
3011
+ disabled: selected.size === 0,
3012
+ className: import_helix71.questionCheckButtonBase,
3013
+ children: "Check"
3014
+ }
3015
+ ),
3016
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Feedback, { correct: displayResult, explanation: displayResult !== null ? explanation : void 0 })
3017
+ ] });
3018
+ }
3019
+ function NumericRenderer({
3020
+ id,
3021
+ prompt,
3022
+ answer,
3023
+ tolerance = 0,
3024
+ unit,
3025
+ explanation,
3026
+ quiz = false,
3027
+ submitted = false,
3028
+ onAnswerChange,
3029
+ onGraded,
3030
+ className,
3031
+ ...rest
3032
+ }) {
3033
+ const inputId = `q-${id}-input`;
3034
+ const [value, setValue] = (0, import_react12.useState)("");
3035
+ const [result, setResult] = (0, import_react12.useState)(null);
3036
+ const computeCorrect = () => {
3037
+ const parsed = parseFloat(value);
3038
+ return !Number.isNaN(parsed) && Math.abs(parsed - answer) <= tolerance;
3039
+ };
3040
+ (0, import_react12.useEffect)(() => {
3041
+ if (quiz) {
3042
+ const parsed = parseFloat(value);
3043
+ const isAnswered = value.trim() !== "" && !Number.isNaN(parsed);
3044
+ onAnswerChange?.({ answered: isAnswered, correct: isAnswered && computeCorrect() });
3045
+ }
3046
+ }, [quiz, value, answer, tolerance]);
3047
+ const displayResult = quiz ? submitted ? computeCorrect() : null : result;
3048
+ const handleCheck = () => {
3049
+ const parsed = parseFloat(value);
3050
+ if (Number.isNaN(parsed)) return;
3051
+ const isCorrect = Math.abs(parsed - answer) <= tolerance;
3052
+ setResult(isCorrect);
3053
+ onGraded?.(isCorrect);
3054
+ };
3055
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: (0, import_helix71.cn)(import_helix71.questionCardBase, className), ...rest, children: [
3056
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_factory44.ark.label, { htmlFor: inputId, className: import_helix71.questionPromptBase, children: prompt }),
3057
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "flex items-center gap-2", children: [
3058
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
3059
+ import_factory44.ark.input,
3060
+ {
3061
+ id: inputId,
3062
+ type: "text",
3063
+ inputMode: "decimal",
3064
+ value,
3065
+ onChange: (e) => {
3066
+ if (quiz ? submitted : result !== null) return;
3067
+ setValue(e.currentTarget.value);
3068
+ },
3069
+ disabled: quiz ? submitted : result !== null,
3070
+ className: import_helix71.questionInputBase
3071
+ }
3072
+ ),
3073
+ unit ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_factory44.ark.span, { className: import_helix71.questionUnitBase, children: unit }) : null
3074
+ ] }),
3075
+ !quiz && result === null && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
3076
+ import_factory44.ark.button,
3077
+ {
3078
+ type: "button",
3079
+ onClick: handleCheck,
3080
+ disabled: value.trim() === "" || Number.isNaN(parseFloat(value)),
3081
+ className: import_helix71.questionCheckButtonBase,
3082
+ children: "Check"
3083
+ }
3084
+ ),
3085
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(Feedback, { correct: displayResult, explanation: displayResult !== null ? explanation : void 0 })
3086
+ ] });
3087
+ }
3088
+ function SingleChoiceQuestion(props) {
3089
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(SingleChoiceRenderer, { ...props });
3090
+ }
3091
+ function MultipleChoiceQuestion(props) {
3092
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(MultipleChoiceRenderer, { ...props });
3093
+ }
3094
+ function NumericQuestion(props) {
3095
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(NumericRenderer, { ...props });
3096
+ }
3097
+ function Quiz({ id, title, questions, className, ...props }) {
3098
+ const [answers, setAnswers] = (0, import_react12.useState)({});
3099
+ const [submitted, setSubmitted] = (0, import_react12.useState)(false);
3100
+ const [resetKey, setResetKey] = (0, import_react12.useState)(0);
3101
+ const total = questions.length;
3102
+ const allAnswered = questions.length > 0 && questions.every((q) => answers[q.id]?.answered === true);
3103
+ const score = questions.filter((q) => answers[q.id]?.correct === true).length;
3104
+ const pct = total > 0 ? Math.round(score / total * 100) : 0;
3105
+ const handleAnswerChange = (questionId) => (state) => {
3106
+ setAnswers((prev) => ({ ...prev, [questionId]: state }));
3107
+ };
3108
+ const handleReset = () => {
3109
+ setAnswers({});
3110
+ setSubmitted(false);
3111
+ setResetKey((k) => k + 1);
3112
+ };
3113
+ const renderQuestion = (q) => {
3114
+ const key = `${q.id}-${String(resetKey)}`;
3115
+ const quizProps = {
3116
+ quiz: true,
3117
+ submitted,
3118
+ onAnswerChange: handleAnswerChange(q.id)
3119
+ };
3120
+ switch (q.type) {
3121
+ case "single":
3122
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
3123
+ SingleChoiceRenderer,
3124
+ {
3125
+ id: q.id,
3126
+ prompt: q.prompt,
3127
+ choices: q.choices,
3128
+ correct: q.correct,
3129
+ explanation: q.explanation,
3130
+ ...quizProps
3131
+ },
3132
+ key
3133
+ );
3134
+ case "multiple":
3135
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
3136
+ MultipleChoiceRenderer,
3137
+ {
3138
+ id: q.id,
3139
+ prompt: q.prompt,
3140
+ choices: q.choices,
3141
+ correct: q.correct,
3142
+ explanation: q.explanation,
3143
+ ...quizProps
3144
+ },
3145
+ key
3146
+ );
3147
+ case "numeric":
3148
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
3149
+ NumericRenderer,
3150
+ {
3151
+ id: q.id,
3152
+ prompt: q.prompt,
3153
+ answer: q.answer,
3154
+ tolerance: q.tolerance,
3155
+ unit: q.unit,
3156
+ explanation: q.explanation,
3157
+ ...quizProps
3158
+ },
3159
+ key
3160
+ );
3161
+ default:
3162
+ return null;
3163
+ }
3164
+ };
3165
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { "data-quiz-id": id, className: (0, import_helix71.cn)(import_helix71.quizRootBase, className), ...props, children: [
3166
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: import_helix71.quizHeaderBase, children: title ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_factory44.ark.h3, { className: import_helix71.quizTitleBase, children: title }) : null }),
3167
+ questions.map(renderQuestion),
3168
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "mt-4 flex items-center gap-3", children: [
3169
+ !submitted ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
3170
+ import_factory44.ark.button,
3171
+ {
3172
+ type: "button",
3173
+ onClick: () => setSubmitted(true),
3174
+ disabled: !allAnswered,
3175
+ className: import_helix71.quizSubmitButtonBase,
3176
+ children: "Submit"
3177
+ }
3178
+ ) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_factory44.ark.button, { type: "button", onClick: handleReset, className: import_helix71.quizResetButtonBase, children: "Reset" }),
3179
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(import_factory44.ark.span, { role: "status", className: import_helix71.quizScoreBase, children: submitted ? `${score}/${total} (${pct}%)` : `${total} question${total === 1 ? "" : "s"}` })
3180
+ ] }),
3181
+ submitted && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: import_helix71.quizResultBase, children: /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { "aria-live": "polite", role: "status", className: "text-center", children: [
3182
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("p", { className: import_helix71.quizResultTitleBase, children: [
3183
+ score,
3184
+ "/",
3185
+ total,
3186
+ " (",
3187
+ pct,
3188
+ "%)"
3189
+ ] }),
3190
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: import_helix71.quizResultTextBase, children: pct >= 70 ? "Well done!" : "Keep studying and try again." })
3191
+ ] }) })
3192
+ ] });
3193
+ }
2002
3194
  // Annotate the CommonJS export names for ESM import in node:
2003
3195
  0 && (module.exports = {
2004
3196
  Badge,
@@ -2011,11 +3203,17 @@ var useTagInput = import_tags_input.useTagsInputContext;
2011
3203
  CardHeader,
2012
3204
  CardTitle,
2013
3205
  Center,
3206
+ Chart,
2014
3207
  Checkbox,
2015
3208
  CheckboxControl,
2016
3209
  CheckboxGroup,
2017
3210
  CheckboxIndicator,
2018
3211
  CheckboxLabel,
3212
+ CodeBlock,
3213
+ CodeBlockContent,
3214
+ CodeBlockCopyButton,
3215
+ CodeBlockHeader,
3216
+ CodeBlockTitle,
2019
3217
  Col,
2020
3218
  Combobox,
2021
3219
  ComboboxClear,
@@ -2031,6 +3229,7 @@ var useTagInput = import_tags_input.useTagsInputContext;
2031
3229
  ComboboxList,
2032
3230
  ComboboxTrigger,
2033
3231
  Container,
3232
+ CopyButton,
2034
3233
  Dialog,
2035
3234
  DialogBackdrop,
2036
3235
  DialogContent,
@@ -2050,9 +3249,17 @@ var useTagInput = import_tags_input.useTagsInputContext;
2050
3249
  FieldSetError,
2051
3250
  FieldSetHelper,
2052
3251
  FieldSetLegend,
3252
+ Figure,
2053
3253
  HStack,
3254
+ InlineLaTeX,
2054
3255
  Input,
2055
3256
  Item,
3257
+ LaTeX,
3258
+ LanguageTabsCodeBlock,
3259
+ Manim,
3260
+ Mermaid,
3261
+ MultiFileCodeBlock,
3262
+ MultipleChoiceQuestion,
2056
3263
  Navbar,
2057
3264
  NavbarActions,
2058
3265
  NavbarActivationArea,
@@ -2072,11 +3279,13 @@ var useTagInput = import_tags_input.useTagsInputContext;
2072
3279
  NavbarMobileOverlay,
2073
3280
  NavbarProvider,
2074
3281
  NavbarTrigger,
3282
+ Notice,
2075
3283
  NumberInput,
2076
3284
  NumberInputControl,
2077
3285
  NumberInputDecrement,
2078
3286
  NumberInputIncrement,
2079
3287
  NumberInputInput,
3288
+ NumericQuestion,
2080
3289
  Page,
2081
3290
  PageContent,
2082
3291
  PageFooter,
@@ -2098,6 +3307,11 @@ var useTagInput = import_tags_input.useTagsInputContext;
2098
3307
  PopoverTitle,
2099
3308
  PopoverTrigger,
2100
3309
  Portal,
3310
+ PrevNext,
3311
+ Quiz,
3312
+ RadioGroup,
3313
+ RadioGroupItem,
3314
+ Reveal,
2101
3315
  Row,
2102
3316
  Scroll,
2103
3317
  Select,
@@ -2134,6 +3348,7 @@ var useTagInput = import_tags_input.useTagsInputContext;
2134
3348
  SidebarRail,
2135
3349
  SidebarSeparator,
2136
3350
  SidebarTrigger,
3351
+ SingleChoiceQuestion,
2137
3352
  Splitter,
2138
3353
  SplitterPanel,
2139
3354
  SplitterResizeTrigger,
@@ -2175,6 +3390,9 @@ var useTagInput = import_tags_input.useTagsInputContext;
2175
3390
  WindowResizeTrigger,
2176
3391
  WindowStageTrigger,
2177
3392
  WindowTitle,
3393
+ YouTube,
3394
+ YoutubeTimestampAt,
3395
+ YoutubeTimestamps,
2178
3396
  navbarMenuTriggerStyle,
2179
3397
  useCheckbox,
2180
3398
  useCombobox,
@@ -2186,6 +3404,7 @@ var useTagInput = import_tags_input.useTagsInputContext;
2186
3404
  useNumberInput,
2187
3405
  usePopover,
2188
3406
  usePopoverContext,
3407
+ useRadioGroup,
2189
3408
  useSelect,
2190
3409
  useSidebar,
2191
3410
  useSwitch,