@pipelex/mthds-form 0.24.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,9 @@
1
- import { planFileSave, planStuffSave, splitFileName, typedFileStem } from './chunk-ICUEHNEH.js';
1
+ import { planFileSave, planStuffSave, splitFileName, typedFileStem } from './chunk-QWHUUMSB.js';
2
2
  import { seedInputs, closeOptionalStructures, openOptionalStructures } from './chunk-VH5CDQDR.js';
3
3
  import { sourceFileValue, roomForChosenFiles, roomForDroppedFiles, addChosenFiles, placeDroppedFiles, chosenFilesAdded } from './chunk-NSHGLM6A.js';
4
- import { readStuffFile } from './chunk-RRTI7AIR.js';
4
+ import { readStuffFile } from './chunk-QINLJ5RM.js';
5
5
  import { apiInputsFromRunValues, sameRunValues, runValuesFromInputs, setValueAtPath } from './chunk-ZX52CQJ4.js';
6
- import { viewableUrl, isNativeDateNode, isNativeHtmlNode, readHtmlContent, isNativeCompositeNode, readCompositeContent, isNativeValueNode, readDateContent, formatDateContent, readImageContent, readDataUrl, readDocumentContent } from './chunk-CM4KVG53.js';
6
+ import { TYPED_SCALAR_MARKERS, viewableUrl, isNativeDateNode, isNativeHtmlNode, readHtmlContent, isNativeCompositeNode, readCompositeContent, isNativePageNode, nativeVerdictOf, isNativeValueNode, readDateContent, formatDateContent, readPageContent, readYesNoContent, readRatingContent, readChoiceContent, readDocumentContent, readImageContent, readDataUrl } from './chunk-JSPF4BQP.js';
7
7
  import { buildRunFields } from './chunk-ZB4RYUKV.js';
8
8
  import { conceptCategory } from './chunk-FABY3DEY.js';
9
9
  import { acceptLabel, acceptMap, isAcceptedFile, normalizeMimeType, formatOfFilename, DOCUMENT_FORMATS, IMAGE_FORMATS } from './chunk-XCO6GTEC.js';
@@ -12,10 +12,10 @@ import { ownProp } from './chunk-V3OV2XQT.js';
12
12
  import { toStoredDateValue, toDateInputValue } from './chunk-GKV77RAS.js';
13
13
  import { clsx } from 'clsx';
14
14
  import { twMerge } from 'tailwind-merge';
15
- import { ChevronDown, ChevronUp, Check, List, Braces, ListChecks, ToggleLeft, Hash, Image as Image$1, FileText, CalendarDays, Type, Folder, Search, X, ImageIcon, Loader2, ImageOff, Upload, Link2, EyeOff, Eye, Minus, Plus, Trash2, Sparkles, MoreHorizontal, TriangleAlert, FileDown, Copy, Download, ChevronRight } from 'lucide-react';
15
+ import { ChevronDown, ChevronUp, Check, List, Braces, ListChecks, ToggleLeft, Hash, Image as Image$1, FileText, CalendarDays, Type, Folder, Search, X, ImageIcon, Loader2, ImageOff, Upload, Link2, EyeOff, Eye, Minus, Plus, Trash2, Sparkles, MoreHorizontal, TriangleAlert, FileDown, Copy, Download, ChevronRight, ExternalLink, ChevronLeft } from 'lucide-react';
16
16
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
17
17
  import * as React5 from 'react';
18
- import { createContext, use, useId, useMemo, useContext, useState, useEffect, useRef, useLayoutEffect, useCallback, Fragment as Fragment$1 } from 'react';
18
+ import { createContext, use, useId, useMemo, useContext, useState, useEffect, useRef, useLayoutEffect, useCallback, Fragment as Fragment$1, useSyncExternalStore } from 'react';
19
19
  import * as SwitchPrimitives from '@radix-ui/react-switch';
20
20
  import { useDropzone } from 'react-dropzone';
21
21
  import * as DialogPrimitive from '@radix-ui/react-dialog';
@@ -25,6 +25,7 @@ import { cva } from 'class-variance-authority';
25
25
  import * as SelectPrimitive from '@radix-ui/react-select';
26
26
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
27
27
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
28
+ import { createPortal } from 'react-dom';
28
29
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
29
30
  import { marked } from 'marked';
30
31
 
@@ -219,6 +220,7 @@ var DAY_YEAR = new Intl.DateTimeFormat("en-GB", {
219
220
  month: "short",
220
221
  year: "numeric"
221
222
  });
223
+ var PERCENT = new Intl.NumberFormat("en-GB", { style: "percent", maximumFractionDigits: 0 });
222
224
  function formatFileDate(date) {
223
225
  const days = calendarDaysBefore(date);
224
226
  if (days === 0) return `Today, ${TIME.format(date)}`;
@@ -254,6 +256,8 @@ var EN_FIELD_STRINGS = {
254
256
  preview: "Preview",
255
257
  removeFileAria: "Remove file",
256
258
  previewUnavailablePdf: "Preview unavailable - open to view.",
259
+ pdfViewerUnavailable: "This browser cannot show the PDF here.",
260
+ openInNewTab: "Open in a new tab",
257
261
  // U+002D HYPHEN-MINUS, deliberately: not an en dash, not an em dash.
258
262
  resultAbsent: "-",
259
263
  resultAbsentDescription: "Not provided",
@@ -281,6 +285,16 @@ var EN_FIELD_STRINGS = {
281
285
  resultViewGroup: "Result view",
282
286
  yes: "Yes",
283
287
  no: "No",
288
+ yesProbability: (share) => `Probability of yes: ${PERCENT.format(share)}`,
289
+ verdictConfidence: (share) => `Confidence: ${PERCENT.format(share)}`,
290
+ ratingLevel: (position) => `Level ${position}`,
291
+ pageNumber: (position) => `Page ${position}`,
292
+ extractedTable: "Table",
293
+ viewImage: (name) => `View ${name}`,
294
+ imagePosition: (position, count) => `${position} of ${count}`,
295
+ previousImage: "Previous picture",
296
+ nextImage: "Next picture",
297
+ openOriginal: "Open the original",
284
298
  unsupportedFileType: (formats) => `That file type is not supported. Accepted formats: ${formats}.`,
285
299
  dropFilesOrBrowse: "Drop files or click to browse",
286
300
  dropFilesToAdd: "Drop to add the files",
@@ -381,6 +395,7 @@ var DAY_YEAR2 = new Intl.DateTimeFormat("fr-FR", {
381
395
  month: "short",
382
396
  year: "numeric"
383
397
  });
398
+ var PERCENT2 = new Intl.NumberFormat("fr-FR", { style: "percent", maximumFractionDigits: 0 });
384
399
  function formatFileDate2(date) {
385
400
  const days = calendarDaysBefore(date);
386
401
  if (days === 0) return `Aujourd\u2019hui, ${TIME2.format(date)}`;
@@ -424,6 +439,8 @@ var FR_FIELD_STRINGS = {
424
439
  preview: "Aper\xE7u",
425
440
  removeFileAria: "Retirer le fichier",
426
441
  previewUnavailablePdf: "Aper\xE7u indisponible - ouvrez le fichier pour le consulter.",
442
+ pdfViewerUnavailable: "Ce navigateur ne peut pas afficher le PDF ici.",
443
+ openInNewTab: "Ouvrir dans un nouvel onglet",
427
444
  // U+002D HYPHEN-MINUS, as in the English defaults.
428
445
  resultAbsent: "-",
429
446
  resultAbsentDescription: "Non renseign\xE9",
@@ -451,6 +468,16 @@ var FR_FIELD_STRINGS = {
451
468
  resultViewGroup: "Affichage du r\xE9sultat",
452
469
  yes: "Oui",
453
470
  no: "Non",
471
+ yesProbability: (share) => `Probabilit\xE9 du oui\xA0: ${PERCENT2.format(share)}`,
472
+ verdictConfidence: (share) => `Confiance\xA0: ${PERCENT2.format(share)}`,
473
+ ratingLevel: (position) => `Niveau ${position}`,
474
+ pageNumber: (position) => `Page ${position}`,
475
+ extractedTable: "Tableau",
476
+ viewImage: (name) => `Voir ${name}`,
477
+ imagePosition: (position, count) => `${position} sur ${count}`,
478
+ previousImage: "Image pr\xE9c\xE9dente",
479
+ nextImage: "Image suivante",
480
+ openOriginal: "Ouvrir l\u2019original",
454
481
  unsupportedFileType: (formats) => `Ce type de fichier n\u2019est pas pris en charge. Formats accept\xE9s\xA0: ${formats}.`,
455
482
  dropFilesOrBrowse: "D\xE9posez des fichiers ou cliquez pour parcourir",
456
483
  dropFilesToAdd: "D\xE9posez pour ajouter les fichiers",
@@ -829,6 +856,10 @@ function closeAutoFocus(onCloseAutoFocus, returnFocus) {
829
856
  target.focus();
830
857
  };
831
858
  }
859
+ var keepPress = (event) => event.stopPropagation();
860
+ function DialogSurface({ children }) {
861
+ return /* @__PURE__ */ jsx("div", { className: "contents", onClick: keepPress, onMouseDown: keepPress, children });
862
+ }
832
863
  var DialogOverlay = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
833
864
  DialogPrimitive.Overlay,
834
865
  {
@@ -838,7 +869,7 @@ var DialogOverlay = React5.forwardRef(({ className, ...props }, ref) => /* @__PU
838
869
  }
839
870
  ));
840
871
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
841
- var DialogContent = React5.forwardRef(({ className, layout = "dialog", returnFocus, onCloseAutoFocus, children, ...props }, ref) => /* @__PURE__ */ jsxs(Fragment, { children: [
872
+ var DialogContent = React5.forwardRef(({ className, layout = "dialog", returnFocus, onCloseAutoFocus, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogSurface, { children: [
842
873
  /* @__PURE__ */ jsx(DialogOverlay, {}),
843
874
  /* @__PURE__ */ jsx(
844
875
  DialogPrimitive.Content,
@@ -993,7 +1024,6 @@ function FilePicker({
993
1024
  onCloseAutoFocus,
994
1025
  returnFocus: () => returnFocusTo?.current ?? heldFocus.current,
995
1026
  style: drag > 0 ? { transform: `translateY(${drag}px)` } : void 0,
996
- onClick: (event) => event.stopPropagation(),
997
1027
  children: /* @__PURE__ */ jsx(FilePickerBody, { ...props, onDrag: setDrag, onClose: () => onOpenChange(false) })
998
1028
  }
999
1029
  ) });
@@ -1034,7 +1064,7 @@ function FilePickerBody({
1034
1064
  return next;
1035
1065
  });
1036
1066
  const choices = [...chosen.values()];
1037
- const use6 = () => {
1067
+ const use8 = () => {
1038
1068
  if (choices.length === 0) return;
1039
1069
  onUse(choices);
1040
1070
  onClose();
@@ -1139,7 +1169,7 @@ function FilePickerBody({
1139
1169
  "button",
1140
1170
  {
1141
1171
  type: "button",
1142
- onClick: use6,
1172
+ onClick: use8,
1143
1173
  disabled: choices.length === 0,
1144
1174
  className: cn(
1145
1175
  "flex h-12 w-full items-center justify-center rounded-md bg-primary px-4 text-[16px] font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50",
@@ -2250,9 +2280,9 @@ function followingFocusable(from, skip) {
2250
2280
  }
2251
2281
  return null;
2252
2282
  }
2253
- function firstFocusable(within) {
2254
- if (!within) return null;
2255
- for (const element of within.querySelectorAll(FOCUSABLE)) {
2283
+ function firstFocusable(within2) {
2284
+ if (!within2) return null;
2285
+ for (const element of within2.querySelectorAll(FOCUSABLE)) {
2256
2286
  if (takesFocus(element)) return element;
2257
2287
  }
2258
2288
  return null;
@@ -2897,7 +2927,7 @@ function FieldRenderer({ field, value, onChange, id, error, env }) {
2897
2927
  }
2898
2928
  }
2899
2929
  var AlertDialog = AlertDialogPrimitive.Root;
2900
- var AlertDialogContent = React5.forwardRef(({ className, returnFocus, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsxs(Fragment, { children: [
2930
+ var AlertDialogContent = React5.forwardRef(({ className, returnFocus, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsxs(DialogSurface, { children: [
2901
2931
  /* @__PURE__ */ jsx(AlertDialogPrimitive.Overlay, { className: "fixed inset-0 z-50 bg-black/50" }),
2902
2932
  /* @__PURE__ */ jsx(
2903
2933
  AlertDialogPrimitive.Content,
@@ -3079,7 +3109,6 @@ function FillWithExample({
3079
3109
  className: "top-auto max-h-[calc(100dvh-1.5rem)]",
3080
3110
  ref: sheet,
3081
3111
  returnFocus: () => control.current ?? afterControl.current,
3082
- onClick: (event) => event.stopPropagation(),
3083
3112
  children: [
3084
3113
  /* @__PURE__ */ jsx("div", { className: "px-4 pt-4 pb-3", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
3085
3114
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1 space-y-1 pt-1", children: [
@@ -3164,7 +3193,6 @@ function FillWithExample({
3164
3193
  const row = rows.current.get(replacing.id);
3165
3194
  return row?.isConnected ? row : control.current;
3166
3195
  },
3167
- onClick: (event) => event.stopPropagation(),
3168
3196
  children: [
3169
3197
  /* @__PURE__ */ jsx(AlertDialogTitle, { children: s.replaceEnteredTitle }),
3170
3198
  /* @__PURE__ */ jsx(AlertDialogDescription, { children: s.replaceEnteredDescription(replacing.name) }),
@@ -3255,7 +3283,7 @@ function RenameExampleDialog({
3255
3283
  onOpenChange: (next) => {
3256
3284
  if (!next && state !== "busy") onCancel();
3257
3285
  },
3258
- children: /* @__PURE__ */ jsxs(DialogContent, { returnFocus, onClick: (event) => event.stopPropagation(), children: [
3286
+ children: /* @__PURE__ */ jsxs(DialogContent, { returnFocus, children: [
3259
3287
  /* @__PURE__ */ jsx(DialogTitle, { children: s.renameExampleTitle }),
3260
3288
  /* @__PURE__ */ jsx(DialogDescription, { className: "sr-only", children: example.name }),
3261
3289
  /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
@@ -3334,7 +3362,7 @@ function DeleteExampleDialog({
3334
3362
  onOpenChange: (next) => {
3335
3363
  if (!next && state !== "busy") onCancel();
3336
3364
  },
3337
- children: /* @__PURE__ */ jsxs(AlertDialogContent, { returnFocus, onClick: (event) => event.stopPropagation(), children: [
3365
+ children: /* @__PURE__ */ jsxs(AlertDialogContent, { returnFocus, children: [
3338
3366
  /* @__PURE__ */ jsx(AlertDialogTitle, { children: s.deleteExampleTitle(example.name) }),
3339
3367
  /* @__PURE__ */ jsx(AlertDialogDescription, { children: s.deleteExampleDescription }),
3340
3368
  state === "failed" && /* @__PURE__ */ jsx("p", { role: "alert", className: "text-[13px] text-destructive", children: s.deleteFailed }),
@@ -3805,6 +3833,7 @@ function frameDocument(content, { styles, imgSrc, fontSrc }) {
3805
3833
  const head = [
3806
3834
  '<!doctype html><html><head><meta charset="utf-8">',
3807
3835
  `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; img-src ${imgSrc}; font-src ${fontSrc}; base-uri 'none'; form-action 'none'">`,
3836
+ '<meta name="referrer" content="no-referrer">',
3808
3837
  `<style>${styles}</style></head>`
3809
3838
  ].join("");
3810
3839
  if (isWholeDocument(content.innerHtml)) return head + content.innerHtml;
@@ -4085,6 +4114,7 @@ var ResultEnvContext = createContext({});
4085
4114
  function ResultEnvProvider({
4086
4115
  resolveUrl,
4087
4116
  resolveUrls,
4117
+ resolveRendition,
4088
4118
  resolveShareUrl,
4089
4119
  proseImages,
4090
4120
  tableColumns,
@@ -4098,6 +4128,7 @@ function ResultEnvProvider({
4098
4128
  () => ({
4099
4129
  resolveUrl,
4100
4130
  resolveUrls,
4131
+ resolveRendition,
4101
4132
  resolveShareUrl,
4102
4133
  proseImages,
4103
4134
  tableColumns,
@@ -4109,6 +4140,7 @@ function ResultEnvProvider({
4109
4140
  [
4110
4141
  resolveUrl,
4111
4142
  resolveUrls,
4143
+ resolveRendition,
4112
4144
  resolveShareUrl,
4113
4145
  proseImages,
4114
4146
  tableColumns,
@@ -4158,6 +4190,9 @@ function useMarkupResolvers() {
4158
4190
  const { resolveUrl, resolveUrls } = use(ResultEnvContext);
4159
4191
  return useMemo(() => ({ resolveUrl, resolveUrls }), [resolveUrl, resolveUrls]);
4160
4192
  }
4193
+ function useResolveRendition() {
4194
+ return use(ResultEnvContext).resolveRendition;
4195
+ }
4161
4196
  function useResolveShareUrl() {
4162
4197
  return use(ResultEnvContext).resolveShareUrl;
4163
4198
  }
@@ -4213,6 +4248,34 @@ function useTableColumns() {
4213
4248
  function useTableLayout() {
4214
4249
  return use(ResultEnvContext).tableLayout ?? "scroll";
4215
4250
  }
4251
+ var OverlayLayerContext = createContext(null);
4252
+ function OverlayLayer({ children }) {
4253
+ const outer = use(OverlayLayerContext);
4254
+ const [holders, setHolders] = useState(0);
4255
+ const [target, setTarget] = useState(null);
4256
+ const acquire = useCallback(() => {
4257
+ setHolders((count) => count + 1);
4258
+ let released = false;
4259
+ return () => {
4260
+ if (released) return;
4261
+ released = true;
4262
+ setHolders((count) => count - 1);
4263
+ };
4264
+ }, []);
4265
+ const layer = useMemo(() => ({ target, acquire }), [target, acquire]);
4266
+ if (outer) return children;
4267
+ return /* @__PURE__ */ jsxs(OverlayLayerContext, { value: layer, children: [
4268
+ holders > 0 && /* @__PURE__ */ jsx("span", { ref: setTarget, "data-overlay-layer": true, className: "absolute size-0" }),
4269
+ children
4270
+ ] });
4271
+ }
4272
+ function InOverlayLayer({ children }) {
4273
+ const layer = use(OverlayLayerContext);
4274
+ const acquire = layer?.acquire;
4275
+ useEffect(() => acquire?.(), [acquire]);
4276
+ if (!layer) return children;
4277
+ return layer.target ? createPortal(children, layer.target) : null;
4278
+ }
4216
4279
  var ResultLocationContext = createContext(void 0);
4217
4280
  function useResultLocation() {
4218
4281
  return use(ResultLocationContext);
@@ -4224,7 +4287,7 @@ function ResultRoot({
4224
4287
  }) {
4225
4288
  const key = path.join("\0");
4226
4289
  const location = useMemo(() => ({ baseName, path: key.split("\0") }), [baseName, key]);
4227
- return /* @__PURE__ */ jsx(ResultLocationContext, { value: location, children });
4290
+ return /* @__PURE__ */ jsx(ResultLocationContext, { value: location, children: /* @__PURE__ */ jsx(OverlayLayer, { children }) });
4228
4291
  }
4229
4292
  function ResultAt({ segment, children }) {
4230
4293
  const parent = use(ResultLocationContext);
@@ -4311,6 +4374,17 @@ function useFrameFocus(frame) {
4311
4374
  }, [frame]);
4312
4375
  return focused;
4313
4376
  }
4377
+ var subscribe = () => () => {
4378
+ };
4379
+ function browserViewer() {
4380
+ return navigator.pdfViewerEnabled === false ? "no" : "yes";
4381
+ }
4382
+ function serverViewer() {
4383
+ return "unknown";
4384
+ }
4385
+ function usePdfViewer() {
4386
+ return useSyncExternalStore(subscribe, browserViewer, serverViewer);
4387
+ }
4314
4388
  var TooltipProvider = TooltipPrimitive.Provider;
4315
4389
  var TooltipRoot = TooltipPrimitive.Root;
4316
4390
  var TooltipTrigger = TooltipPrimitive.Trigger;
@@ -4523,26 +4597,26 @@ function measureFlow(doc) {
4523
4597
  fixed.push(el);
4524
4598
  return;
4525
4599
  }
4526
- const span = spanOf(el);
4600
+ const span2 = spanOf(el);
4527
4601
  const display = style.display;
4528
4602
  if (FORCED.has(style.breakBefore) || FORCED.has(style.getPropertyValue("page-break-before"))) {
4529
- forced.push(span.top);
4603
+ forced.push(span2.top);
4530
4604
  }
4531
4605
  if (FORCED.has(style.breakAfter) || FORCED.has(style.getPropertyValue("page-break-after"))) {
4532
- forced.push(span.bottom);
4606
+ forced.push(span2.bottom);
4533
4607
  }
4534
- if (AVOIDED.has(style.breakAfter) || HEADING_TAGS.has(el.tagName)) keepAfter.push(span);
4535
- if (AVOIDED.has(style.breakBefore)) keepBefore.push(span);
4608
+ if (AVOIDED.has(style.breakAfter) || HEADING_TAGS.has(el.tagName)) keepAfter.push(span2);
4609
+ if (AVOIDED.has(style.breakBefore)) keepBefore.push(span2);
4536
4610
  const atomic = ATOMIC_TAGS.has(el.tagName) || display.startsWith("inline-");
4537
4611
  if (atomic) {
4538
- if (span.bottom > span.top) hard.push(span);
4612
+ if (span2.bottom > span2.top) hard.push(span2);
4539
4613
  return;
4540
4614
  }
4541
4615
  if (AVOIDED.has(style.breakInside) || AVOIDED.has(style.getPropertyValue("page-break-inside")) || display === "table-row") {
4542
- avoid.push(span);
4616
+ avoid.push(span2);
4543
4617
  }
4544
4618
  if (display === "table" || display === "inline-table") {
4545
- tables.push(tableBox(el, span));
4619
+ tables.push(tableBox(el, span2));
4546
4620
  }
4547
4621
  for (const child of Array.from(el.childNodes)) {
4548
4622
  if (child.nodeType === 1) walk(child);
@@ -4551,8 +4625,8 @@ function measureFlow(doc) {
4551
4625
  }
4552
4626
  }
4553
4627
  };
4554
- const tableBox = (table, span) => {
4555
- const box = { ...span };
4628
+ const tableBox = (table, span2) => {
4629
+ const box = { ...span2 };
4556
4630
  for (const part of Array.from(table.children)) {
4557
4631
  const display = win.getComputedStyle(part).display;
4558
4632
  if (display === "table-header-group" && !box.head) box.head = spanOf(part);
@@ -4565,13 +4639,13 @@ function measureFlow(doc) {
4565
4639
  const lines = [...hard].sort((a, b) => a.top - b.top);
4566
4640
  const firstLineFrom = (at) => lines.find((line) => line.top >= at - 0.5);
4567
4641
  const lastLineBefore = (at) => [...lines].reverse().find((line) => line.bottom <= at + 0.5);
4568
- for (const span of keepAfter) {
4569
- const next = firstLineFrom(span.bottom);
4570
- if (next) avoid.push({ top: span.top, bottom: next.bottom });
4642
+ for (const span2 of keepAfter) {
4643
+ const next = firstLineFrom(span2.bottom);
4644
+ if (next) avoid.push({ top: span2.top, bottom: next.bottom });
4571
4645
  }
4572
- for (const span of keepBefore) {
4573
- const previous = lastLineBefore(span.top);
4574
- const first = firstLineFrom(span.top);
4646
+ for (const span2 of keepBefore) {
4647
+ const previous = lastLineBefore(span2.top);
4648
+ const first = firstLineFrom(span2.top);
4575
4649
  if (previous && first) avoid.push({ top: previous.top, bottom: first.bottom });
4576
4650
  }
4577
4651
  for (const table of tables) {
@@ -4589,17 +4663,17 @@ function measureFlow(doc) {
4589
4663
  function lineSpans(doc, text, y) {
4590
4664
  const range = doc.createRange();
4591
4665
  range.selectNodeContents(text);
4592
- const spans = [];
4666
+ const spans2 = [];
4593
4667
  for (const rect of Array.from(range.getClientRects())) {
4594
4668
  if (rect.height === 0) continue;
4595
- const span = { top: y(rect.top), bottom: y(rect.bottom) };
4596
- const same = spans.find((line) => span.top < line.bottom && span.bottom > line.top);
4669
+ const span2 = { top: y(rect.top), bottom: y(rect.bottom) };
4670
+ const same = spans2.find((line) => span2.top < line.bottom && span2.bottom > line.top);
4597
4671
  if (same) {
4598
- same.top = Math.min(same.top, span.top);
4599
- same.bottom = Math.max(same.bottom, span.bottom);
4600
- } else spans.push(span);
4672
+ same.top = Math.min(same.top, span2.top);
4673
+ same.bottom = Math.max(same.bottom, span2.bottom);
4674
+ } else spans2.push(span2);
4601
4675
  }
4602
- return spans;
4676
+ return spans2;
4603
4677
  }
4604
4678
 
4605
4679
  // src/react/paginate.ts
@@ -4607,7 +4681,7 @@ var EPSILON = 0.5;
4607
4681
  function paginate(layout, pageHeight) {
4608
4682
  const pages = [];
4609
4683
  const end = layout.height;
4610
- const inkBottom = Math.max(0, ...layout.hard.map((span) => span.bottom));
4684
+ const inkBottom = Math.max(0, ...layout.hard.map((span2) => span2.bottom));
4611
4685
  const forced = [...layout.forced].sort((a, b) => a - b);
4612
4686
  let start = 0;
4613
4687
  for (let guard = 0; start < end - EPSILON && guard < 1e4; guard++) {
@@ -4638,12 +4712,12 @@ function paginate(layout, pageHeight) {
4638
4712
  }
4639
4713
  function bestCut(layout, start, limit) {
4640
4714
  const room = limit - start;
4641
- const hard = layout.hard.filter((span) => span.bottom - span.top <= room);
4642
- const avoid = layout.avoid.filter((span) => span.bottom - span.top <= room);
4715
+ const hard = layout.hard.filter((span2) => span2.bottom - span2.top <= room);
4716
+ const avoid = layout.avoid.filter((span2) => span2.bottom - span2.top <= room);
4643
4717
  const candidates = /* @__PURE__ */ new Set([limit]);
4644
- for (const span of [...hard, ...avoid]) {
4645
- candidates.add(span.top);
4646
- candidates.add(span.bottom);
4718
+ for (const span2 of [...hard, ...avoid]) {
4719
+ candidates.add(span2.top);
4720
+ candidates.add(span2.bottom);
4647
4721
  }
4648
4722
  for (const table of layout.tables) {
4649
4723
  candidates.add(table.top);
@@ -4651,19 +4725,19 @@ function bestCut(layout, start, limit) {
4651
4725
  }
4652
4726
  const sorted = [...candidates].filter((at) => at > start + EPSILON && at <= limit + EPSILON).sort((a, b) => b - a);
4653
4727
  for (const constraints of [[...hard, ...avoid], hard]) {
4654
- const cut = sorted.find((at) => !constraints.some((span) => inside(span, at)));
4728
+ const cut = sorted.find((at) => !constraints.some((span2) => inside(span2, at)));
4655
4729
  if (cut !== void 0) return Math.min(cut, limit);
4656
4730
  }
4657
4731
  return limit;
4658
4732
  }
4659
- function inside(span, at) {
4660
- return at > span.top + EPSILON && at < span.bottom - EPSILON;
4733
+ function inside(span2, at) {
4734
+ return at > span2.top + EPSILON && at < span2.bottom - EPSILON;
4661
4735
  }
4662
4736
  function openAt(tables, at) {
4663
4737
  return tables.filter((table) => at > table.top + EPSILON && at < (table.foot?.top ?? table.bottom) - EPSILON).sort((a, b) => a.top - b.top);
4664
4738
  }
4665
- function total(spans) {
4666
- return spans.reduce((sum, span) => sum + (span.bottom - span.top), 0);
4739
+ function total(spans2) {
4740
+ return spans2.reduce((sum, span2) => sum + (span2.bottom - span2.top), 0);
4667
4741
  }
4668
4742
 
4669
4743
  // src/react/print-media.ts
@@ -4929,10 +5003,10 @@ async function paintPage(slice, page, area, scale, quality, flow, overlay) {
4929
5003
  context.fillStyle = "#fff";
4930
5004
  context.fillRect(0, 0, canvas.width, canvas.height);
4931
5005
  let y = page.margin.top;
4932
- for (const span of [...slice.heads, slice.body, ...slice.feet]) {
4933
- const height = span.bottom - span.top;
5006
+ for (const span2 of [...slice.heads, slice.body, ...slice.feet]) {
5007
+ const height = span2.bottom - span2.top;
4934
5008
  if (height <= 0) continue;
4935
- const image = await svgImage(flow, { top: span.top, width: area.width, height }, scale);
5009
+ const image = await svgImage(flow, { top: span2.top, width: area.width, height }, scale);
4936
5010
  context.drawImage(
4937
5011
  image,
4938
5012
  page.margin.left * scale,
@@ -5304,6 +5378,231 @@ function useResolvedMarkup(markup) {
5304
5378
  if (!needed) return markup;
5305
5379
  return shown?.source === markup ? shown.html : void 0;
5306
5380
  }
5381
+ var SWIPE_DISTANCE = 40;
5382
+ function ImageViewer({
5383
+ pictures,
5384
+ index,
5385
+ onIndexChange,
5386
+ onClose,
5387
+ returnFocus
5388
+ }) {
5389
+ const s = useFieldStrings();
5390
+ const panel = useRef(null);
5391
+ const swipe = useRef(null);
5392
+ const count = pictures.length;
5393
+ const at = Math.min(Math.max(index, 0), count - 1);
5394
+ const picture = pictures[at];
5395
+ if (!picture) return null;
5396
+ const several = count > 1;
5397
+ const go = (step) => {
5398
+ const next = at + step;
5399
+ if (next >= 0 && next < count) onIndexChange(next);
5400
+ };
5401
+ const onPointerDown = (event) => {
5402
+ swipe.current = event.pointerType === "touch" && event.isPrimary ? { id: event.pointerId, x: event.clientX, y: event.clientY } : null;
5403
+ };
5404
+ const onPointerUp = (event) => {
5405
+ const start = swipe.current;
5406
+ swipe.current = null;
5407
+ if (!start || start.id !== event.pointerId) return;
5408
+ const across = event.clientX - start.x;
5409
+ const down = event.clientY - start.y;
5410
+ if (Math.abs(across) < SWIPE_DISTANCE || Math.abs(across) < Math.abs(down) * 1.5) return;
5411
+ go(across < 0 ? 1 : -1);
5412
+ };
5413
+ return /* @__PURE__ */ jsx(InOverlayLayer, { children: /* @__PURE__ */ jsx(
5414
+ Dialog,
5415
+ {
5416
+ open: true,
5417
+ onOpenChange: (open) => {
5418
+ if (!open) onClose();
5419
+ },
5420
+ children: /* @__PURE__ */ jsxs(
5421
+ DialogContent,
5422
+ {
5423
+ ref: panel,
5424
+ returnFocus,
5425
+ onOpenAutoFocus: (event) => {
5426
+ event.preventDefault();
5427
+ panel.current?.focus();
5428
+ },
5429
+ onEscapeKeyDown: (event) => {
5430
+ if (event.target instanceof Element && event.target.closest("[data-file-name-backdrop]")) {
5431
+ event.preventDefault();
5432
+ }
5433
+ },
5434
+ onKeyDown: (event) => {
5435
+ if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
5436
+ return;
5437
+ }
5438
+ if (isTextEntry(event.target)) return;
5439
+ if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return;
5440
+ event.preventDefault();
5441
+ event.stopPropagation();
5442
+ go(event.key === "ArrowLeft" ? -1 : 1);
5443
+ },
5444
+ ...picture.caption ? {} : { "aria-describedby": void 0 },
5445
+ className: cn(
5446
+ "m-0 h-dvh w-full max-w-none gap-0 rounded-none border-0 p-0",
5447
+ "sm:m-auto sm:h-[calc(100dvh-4rem)] sm:w-[calc(100%-4rem)] sm:max-w-6xl sm:rounded-xl sm:border"
5448
+ ),
5449
+ children: [
5450
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2 border-b border-border py-1.5 pr-1.5 pl-4", children: [
5451
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
5452
+ /* @__PURE__ */ jsx(DialogTitle, { className: "truncate text-[14px] font-medium", children: picture.name }),
5453
+ several && // A live region from the moment the viewer opens, so each move
5454
+ // is announced: one inserted with its text already in it is not.
5455
+ /* @__PURE__ */ jsx(
5456
+ "p",
5457
+ {
5458
+ "aria-live": "polite",
5459
+ "aria-atomic": "true",
5460
+ className: "text-[12px] text-muted-foreground",
5461
+ children: s.imagePosition(at + 1, count)
5462
+ }
5463
+ )
5464
+ ] }),
5465
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
5466
+ /* @__PURE__ */ jsxs(
5467
+ "a",
5468
+ {
5469
+ href: picture.src,
5470
+ target: "_blank",
5471
+ rel: "noreferrer",
5472
+ className: cn(
5473
+ "inline-flex items-center gap-1.5 rounded-md px-2 py-1 text-[12px] text-muted-foreground hover:bg-muted hover:text-foreground max-sm:size-11 max-sm:justify-center max-sm:p-0",
5474
+ focusOutlineClass
5475
+ ),
5476
+ children: [
5477
+ /* @__PURE__ */ jsx(ExternalLink, { "aria-hidden": true, className: "size-3.5" }),
5478
+ /* @__PURE__ */ jsx("span", { className: "max-sm:sr-only", children: s.openOriginal })
5479
+ ]
5480
+ }
5481
+ ),
5482
+ picture.actions,
5483
+ /* @__PURE__ */ jsx(
5484
+ DialogClose,
5485
+ {
5486
+ "aria-label": s.close,
5487
+ className: cn(
5488
+ "flex size-9 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground max-sm:size-11",
5489
+ focusOutlineClass
5490
+ ),
5491
+ children: /* @__PURE__ */ jsx(X, { "aria-hidden": true, className: "size-4" })
5492
+ }
5493
+ )
5494
+ ] })
5495
+ ] }),
5496
+ /* @__PURE__ */ jsxs(
5497
+ "div",
5498
+ {
5499
+ "data-viewer-stage": true,
5500
+ onPointerDown,
5501
+ onPointerUp,
5502
+ onPointerCancel: () => {
5503
+ swipe.current = null;
5504
+ },
5505
+ className: "relative min-h-0 flex-1 touch-pan-y touch-pinch-zoom",
5506
+ children: [
5507
+ /* @__PURE__ */ jsx(
5508
+ ViewerImage,
5509
+ {
5510
+ src: picture.src,
5511
+ alt: picture.caption ?? picture.name
5512
+ },
5513
+ picture.src
5514
+ ),
5515
+ several && /* @__PURE__ */ jsxs(Fragment, { children: [
5516
+ /* @__PURE__ */ jsx(
5517
+ StepButton2,
5518
+ {
5519
+ label: s.previousImage,
5520
+ unavailable: at === 0,
5521
+ onStep: () => go(-1),
5522
+ className: "left-2",
5523
+ children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": true, className: "size-5" })
5524
+ }
5525
+ ),
5526
+ /* @__PURE__ */ jsx(
5527
+ StepButton2,
5528
+ {
5529
+ label: s.nextImage,
5530
+ unavailable: at === count - 1,
5531
+ onStep: () => go(1),
5532
+ className: "right-2",
5533
+ children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true, className: "size-5" })
5534
+ }
5535
+ )
5536
+ ] })
5537
+ ]
5538
+ }
5539
+ ),
5540
+ picture.caption && /* @__PURE__ */ jsx(DialogDescription, { className: "max-h-24 shrink-0 overflow-y-auto border-t border-border px-4 py-2 text-[13px]", children: picture.caption })
5541
+ ]
5542
+ }
5543
+ )
5544
+ }
5545
+ ) });
5546
+ }
5547
+ function ViewerImage({ src, alt }) {
5548
+ const [loading, setLoading] = useState(true);
5549
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5550
+ loading && /* @__PURE__ */ jsx(
5551
+ "span",
5552
+ {
5553
+ role: "status",
5554
+ "aria-label": alt,
5555
+ className: "absolute inset-0 flex items-center justify-center",
5556
+ children: /* @__PURE__ */ jsx(Loader2, { "aria-hidden": true, className: "size-5 animate-spin text-muted-foreground" })
5557
+ }
5558
+ ),
5559
+ /* @__PURE__ */ jsx(
5560
+ "img",
5561
+ {
5562
+ src,
5563
+ alt,
5564
+ referrerPolicy: "no-referrer",
5565
+ decoding: "async",
5566
+ draggable: false,
5567
+ onLoad: () => setLoading(false),
5568
+ onError: () => setLoading(false),
5569
+ className: cn(
5570
+ "absolute inset-0 size-full object-contain p-2 sm:p-4",
5571
+ loading && "opacity-0"
5572
+ )
5573
+ }
5574
+ )
5575
+ ] });
5576
+ }
5577
+ function StepButton2({
5578
+ label,
5579
+ unavailable,
5580
+ onStep,
5581
+ className,
5582
+ children
5583
+ }) {
5584
+ return /* @__PURE__ */ jsx(
5585
+ "button",
5586
+ {
5587
+ type: "button",
5588
+ "aria-label": label,
5589
+ "aria-disabled": unavailable,
5590
+ onClick: () => {
5591
+ if (!unavailable) onStep();
5592
+ },
5593
+ className: cn(
5594
+ "absolute top-1/2 flex size-11 -translate-y-1/2 items-center justify-center rounded-full border border-border bg-popover/90 text-foreground shadow-sm hover:bg-muted aria-disabled:opacity-40 aria-disabled:hover:bg-popover/90",
5595
+ focusOutlineClass,
5596
+ className
5597
+ ),
5598
+ children
5599
+ }
5600
+ );
5601
+ }
5602
+ function isTextEntry(target) {
5603
+ if (!(target instanceof HTMLElement)) return false;
5604
+ return target.isContentEditable || target.closest("input, textarea, select") !== null;
5605
+ }
5307
5606
  var LEX_OPTIONS = { gfm: true, breaks: true };
5308
5607
  function Markdown({ text, className, proseImages }) {
5309
5608
  const tokens = React5.useMemo(() => marked.lexer(text, LEX_OPTIONS), [text]);
@@ -5524,6 +5823,710 @@ var ENTITIES = {
5524
5823
  function decode(text) {
5525
5824
  return text.replace(/&(?:amp|lt|gt|quot|#39|#x27);/g, (entity) => ENTITIES[entity] ?? entity);
5526
5825
  }
5826
+ function ExtractedPageText({ segments }) {
5827
+ return /* @__PURE__ */ jsx("div", { className: "space-y-2", children: segments.map(
5828
+ (segment, index) => segment.kind === "markdown" ? /* @__PURE__ */ jsx(Markdown, { text: segment.text }, index) : /* @__PURE__ */ jsx(ExtractedTableView, { table: segment.table }, index)
5829
+ ) });
5830
+ }
5831
+ function ExtractedTableView({ table }) {
5832
+ const s = useFieldStrings();
5833
+ const headRows = leadingHeaderRows(table);
5834
+ const head = table.rows.slice(0, headRows);
5835
+ const body = table.rows.slice(headRows);
5836
+ return /* @__PURE__ */ jsxs("figure", { className: "space-y-1.5", children: [
5837
+ table.caption && /* @__PURE__ */ jsx("figcaption", { className: "text-[12.5px] text-muted-foreground", children: table.caption }),
5838
+ table.rows.length > 0 && /* @__PURE__ */ jsx(
5839
+ "div",
5840
+ {
5841
+ role: "group",
5842
+ "aria-label": table.caption ?? s.extractedTable,
5843
+ tabIndex: 0,
5844
+ className: cn("overflow-x-auto rounded-lg border border-border", focusOutlineClass),
5845
+ children: /* @__PURE__ */ jsxs("table", { className: "min-w-full border-collapse text-[12.5px] text-foreground", children: [
5846
+ head.length > 0 && /* @__PURE__ */ jsx("thead", { children: head.map((row, rowIndex) => /* @__PURE__ */ jsx("tr", { className: "border-b border-border bg-card/40", children: row.map((cell, cellIndex) => /* @__PURE__ */ jsx(
5847
+ "th",
5848
+ {
5849
+ scope: "col",
5850
+ ...spans(cell),
5851
+ className: "whitespace-pre-line px-2.5 py-1.5 text-start align-bottom font-semibold",
5852
+ children: cell.text
5853
+ },
5854
+ cellIndex
5855
+ )) }, rowIndex)) }),
5856
+ /* @__PURE__ */ jsx("tbody", { children: body.map((row, rowIndex) => /* @__PURE__ */ jsx("tr", { className: "border-b border-border/60 last:border-b-0", children: row.map(
5857
+ (cell, cellIndex) => cell.header ? /* @__PURE__ */ jsx(
5858
+ "th",
5859
+ {
5860
+ scope: "row",
5861
+ ...spans(cell),
5862
+ className: "whitespace-pre-line px-2.5 py-1.5 text-start align-top font-semibold",
5863
+ children: cell.text
5864
+ },
5865
+ cellIndex
5866
+ ) : /* @__PURE__ */ jsx(
5867
+ "td",
5868
+ {
5869
+ ...spans(cell),
5870
+ className: "whitespace-pre-line px-2.5 py-1.5 align-top",
5871
+ children: cell.text
5872
+ },
5873
+ cellIndex
5874
+ )
5875
+ ) }, rowIndex)) })
5876
+ ] })
5877
+ }
5878
+ )
5879
+ ] });
5880
+ }
5881
+ function leadingHeaderRows(table) {
5882
+ let count = 0;
5883
+ for (const row of table.rows) {
5884
+ if (!row.every((cell) => cell.header)) break;
5885
+ count += 1;
5886
+ }
5887
+ return count === table.rows.length ? 0 : count;
5888
+ }
5889
+ function spans(cell) {
5890
+ return {
5891
+ ...cell.colSpan !== void 0 ? { colSpan: cell.colSpan } : {},
5892
+ ...cell.rowSpan !== void 0 ? { rowSpan: cell.rowSpan } : {}
5893
+ };
5894
+ }
5895
+
5896
+ // src/react/html-entities.ts
5897
+ var HTML_NAMED_ENTITIES = {
5898
+ // The XML marks, their legacy uppercase spellings, and the special marks.
5899
+ apos: 39,
5900
+ AMP: 38,
5901
+ LT: 60,
5902
+ GT: 62,
5903
+ QUOT: 34,
5904
+ COPY: 169,
5905
+ REG: 174,
5906
+ quot: 34,
5907
+ amp: 38,
5908
+ lt: 60,
5909
+ gt: 62,
5910
+ OElig: 338,
5911
+ oelig: 339,
5912
+ Scaron: 352,
5913
+ scaron: 353,
5914
+ Yuml: 376,
5915
+ circ: 710,
5916
+ tilde: 732,
5917
+ ensp: 8194,
5918
+ emsp: 8195,
5919
+ thinsp: 8201,
5920
+ zwnj: 8204,
5921
+ zwj: 8205,
5922
+ lrm: 8206,
5923
+ rlm: 8207,
5924
+ ndash: 8211,
5925
+ mdash: 8212,
5926
+ lsquo: 8216,
5927
+ rsquo: 8217,
5928
+ sbquo: 8218,
5929
+ ldquo: 8220,
5930
+ rdquo: 8221,
5931
+ bdquo: 8222,
5932
+ dagger: 8224,
5933
+ Dagger: 8225,
5934
+ permil: 8240,
5935
+ lsaquo: 8249,
5936
+ rsaquo: 8250,
5937
+ euro: 8364,
5938
+ // Latin-1.
5939
+ nbsp: 160,
5940
+ iexcl: 161,
5941
+ cent: 162,
5942
+ pound: 163,
5943
+ curren: 164,
5944
+ yen: 165,
5945
+ brvbar: 166,
5946
+ sect: 167,
5947
+ uml: 168,
5948
+ copy: 169,
5949
+ ordf: 170,
5950
+ laquo: 171,
5951
+ not: 172,
5952
+ shy: 173,
5953
+ reg: 174,
5954
+ macr: 175,
5955
+ deg: 176,
5956
+ plusmn: 177,
5957
+ sup2: 178,
5958
+ sup3: 179,
5959
+ acute: 180,
5960
+ micro: 181,
5961
+ para: 182,
5962
+ middot: 183,
5963
+ cedil: 184,
5964
+ sup1: 185,
5965
+ ordm: 186,
5966
+ raquo: 187,
5967
+ frac14: 188,
5968
+ frac12: 189,
5969
+ frac34: 190,
5970
+ iquest: 191,
5971
+ Agrave: 192,
5972
+ Aacute: 193,
5973
+ Acirc: 194,
5974
+ Atilde: 195,
5975
+ Auml: 196,
5976
+ Aring: 197,
5977
+ AElig: 198,
5978
+ Ccedil: 199,
5979
+ Egrave: 200,
5980
+ Eacute: 201,
5981
+ Ecirc: 202,
5982
+ Euml: 203,
5983
+ Igrave: 204,
5984
+ Iacute: 205,
5985
+ Icirc: 206,
5986
+ Iuml: 207,
5987
+ ETH: 208,
5988
+ Ntilde: 209,
5989
+ Ograve: 210,
5990
+ Oacute: 211,
5991
+ Ocirc: 212,
5992
+ Otilde: 213,
5993
+ Ouml: 214,
5994
+ times: 215,
5995
+ Oslash: 216,
5996
+ Ugrave: 217,
5997
+ Uacute: 218,
5998
+ Ucirc: 219,
5999
+ Uuml: 220,
6000
+ Yacute: 221,
6001
+ THORN: 222,
6002
+ szlig: 223,
6003
+ agrave: 224,
6004
+ aacute: 225,
6005
+ acirc: 226,
6006
+ atilde: 227,
6007
+ auml: 228,
6008
+ aring: 229,
6009
+ aelig: 230,
6010
+ ccedil: 231,
6011
+ egrave: 232,
6012
+ eacute: 233,
6013
+ ecirc: 234,
6014
+ euml: 235,
6015
+ igrave: 236,
6016
+ iacute: 237,
6017
+ icirc: 238,
6018
+ iuml: 239,
6019
+ eth: 240,
6020
+ ntilde: 241,
6021
+ ograve: 242,
6022
+ oacute: 243,
6023
+ ocirc: 244,
6024
+ otilde: 245,
6025
+ ouml: 246,
6026
+ divide: 247,
6027
+ oslash: 248,
6028
+ ugrave: 249,
6029
+ uacute: 250,
6030
+ ucirc: 251,
6031
+ uuml: 252,
6032
+ yacute: 253,
6033
+ thorn: 254,
6034
+ yuml: 255,
6035
+ // Symbols, mathematical marks and Greek letters.
6036
+ fnof: 402,
6037
+ Alpha: 913,
6038
+ Beta: 914,
6039
+ Gamma: 915,
6040
+ Delta: 916,
6041
+ Epsilon: 917,
6042
+ Zeta: 918,
6043
+ Eta: 919,
6044
+ Theta: 920,
6045
+ Iota: 921,
6046
+ Kappa: 922,
6047
+ Lambda: 923,
6048
+ Mu: 924,
6049
+ Nu: 925,
6050
+ Xi: 926,
6051
+ Omicron: 927,
6052
+ Pi: 928,
6053
+ Rho: 929,
6054
+ Sigma: 931,
6055
+ Tau: 932,
6056
+ Upsilon: 933,
6057
+ Phi: 934,
6058
+ Chi: 935,
6059
+ Psi: 936,
6060
+ Omega: 937,
6061
+ alpha: 945,
6062
+ beta: 946,
6063
+ gamma: 947,
6064
+ delta: 948,
6065
+ epsilon: 949,
6066
+ zeta: 950,
6067
+ eta: 951,
6068
+ theta: 952,
6069
+ iota: 953,
6070
+ kappa: 954,
6071
+ lambda: 955,
6072
+ mu: 956,
6073
+ nu: 957,
6074
+ xi: 958,
6075
+ omicron: 959,
6076
+ pi: 960,
6077
+ rho: 961,
6078
+ sigmaf: 962,
6079
+ sigma: 963,
6080
+ tau: 964,
6081
+ upsilon: 965,
6082
+ phi: 966,
6083
+ chi: 967,
6084
+ psi: 968,
6085
+ omega: 969,
6086
+ thetasym: 977,
6087
+ upsih: 978,
6088
+ piv: 982,
6089
+ bull: 8226,
6090
+ hellip: 8230,
6091
+ prime: 8242,
6092
+ Prime: 8243,
6093
+ oline: 8254,
6094
+ frasl: 8260,
6095
+ image: 8465,
6096
+ weierp: 8472,
6097
+ real: 8476,
6098
+ trade: 8482,
6099
+ alefsym: 8501,
6100
+ larr: 8592,
6101
+ uarr: 8593,
6102
+ rarr: 8594,
6103
+ darr: 8595,
6104
+ harr: 8596,
6105
+ crarr: 8629,
6106
+ lArr: 8656,
6107
+ uArr: 8657,
6108
+ rArr: 8658,
6109
+ dArr: 8659,
6110
+ hArr: 8660,
6111
+ forall: 8704,
6112
+ part: 8706,
6113
+ exist: 8707,
6114
+ empty: 8709,
6115
+ nabla: 8711,
6116
+ isin: 8712,
6117
+ notin: 8713,
6118
+ ni: 8715,
6119
+ prod: 8719,
6120
+ sum: 8721,
6121
+ minus: 8722,
6122
+ lowast: 8727,
6123
+ radic: 8730,
6124
+ prop: 8733,
6125
+ infin: 8734,
6126
+ ang: 8736,
6127
+ and: 8743,
6128
+ or: 8744,
6129
+ cap: 8745,
6130
+ cup: 8746,
6131
+ int: 8747,
6132
+ there4: 8756,
6133
+ sim: 8764,
6134
+ cong: 8773,
6135
+ asymp: 8776,
6136
+ ne: 8800,
6137
+ equiv: 8801,
6138
+ le: 8804,
6139
+ ge: 8805,
6140
+ sub: 8834,
6141
+ sup: 8835,
6142
+ nsub: 8836,
6143
+ sube: 8838,
6144
+ supe: 8839,
6145
+ oplus: 8853,
6146
+ otimes: 8855,
6147
+ perp: 8869,
6148
+ sdot: 8901,
6149
+ lceil: 8968,
6150
+ rceil: 8969,
6151
+ lfloor: 8970,
6152
+ rfloor: 8971,
6153
+ lang: 9001,
6154
+ rang: 9002,
6155
+ loz: 9674,
6156
+ spades: 9824,
6157
+ clubs: 9827,
6158
+ hearts: 9829,
6159
+ diams: 9830
6160
+ };
6161
+ var ENTITY = /&(#x[0-9a-f]+|#\d+|[a-z][a-z0-9]*);/gi;
6162
+ function decodeHtmlEntities(text) {
6163
+ return text.replace(ENTITY, (entity, body) => {
6164
+ if (body.startsWith("#")) {
6165
+ const code2 = body[1] === "x" || body[1] === "X" ? parseInt(body.slice(2), 16) : Number(body.slice(1));
6166
+ return Number.isInteger(code2) && code2 > 0 && code2 <= 1114111 ? String.fromCodePoint(code2) : entity;
6167
+ }
6168
+ const code = ownProp(HTML_NAMED_ENTITIES, body);
6169
+ return typeof code === "number" ? String.fromCodePoint(code) : entity;
6170
+ });
6171
+ }
6172
+
6173
+ // src/react/extracted-text.ts
6174
+ function splitExtractedText(text) {
6175
+ const segments = [];
6176
+ const tableRows = text.includes("|") ? pipeTableRows(text) : [];
6177
+ let markdown = "";
6178
+ let index = 0;
6179
+ while (index < text.length) {
6180
+ if (index === 0 || text[index - 1] === "\n") {
6181
+ const fenceEnd = fencedBlockEnd(text, index);
6182
+ if (fenceEnd !== void 0) {
6183
+ markdown += text.slice(index, fenceEnd);
6184
+ index = fenceEnd;
6185
+ continue;
6186
+ }
6187
+ }
6188
+ const char = text.charAt(index);
6189
+ if (char === "\\" && ESCAPABLE.test(text.charAt(index + 1))) {
6190
+ markdown += text.slice(index, index + 2);
6191
+ index += 2;
6192
+ continue;
6193
+ }
6194
+ if (char === "`") {
6195
+ const end = codeSpanEnd(text, index);
6196
+ markdown += text.slice(index, end);
6197
+ index = end;
6198
+ continue;
6199
+ }
6200
+ if (char === "<") {
6201
+ const markup = readMarkup(text, index);
6202
+ if (markup) {
6203
+ if ("table" in markup) {
6204
+ pushMarkdown(segments, markdown);
6205
+ markdown = "";
6206
+ if (markup.table) segments.push({ kind: "table", table: markup.table });
6207
+ } else if (markup.text === "\n" && within(tableRows, index)) {
6208
+ markdown += " ";
6209
+ } else {
6210
+ markdown += markup.text;
6211
+ }
6212
+ index = markup.end;
6213
+ continue;
6214
+ }
6215
+ }
6216
+ markdown += char;
6217
+ index += 1;
6218
+ }
6219
+ pushMarkdown(segments, markdown);
6220
+ return segments;
6221
+ }
6222
+ function pushMarkdown(segments, text) {
6223
+ if (text.trim() !== "") segments.push({ kind: "markdown", text });
6224
+ }
6225
+ function within(spans2, index) {
6226
+ return spans2.some(([start, end]) => index >= start && index < end);
6227
+ }
6228
+ function pipeTableRows(text) {
6229
+ const lines = [];
6230
+ for (let start = 0; ; ) {
6231
+ const newline = text.indexOf("\n", start);
6232
+ lines.push([start, newline === -1 ? text.length : newline]);
6233
+ if (newline === -1) break;
6234
+ start = newline + 1;
6235
+ }
6236
+ const lineAt = (at) => {
6237
+ const [start, end] = lines[at] ?? [0, 0];
6238
+ return text.slice(start, end);
6239
+ };
6240
+ const rows = [];
6241
+ for (let at = 1; at < lines.length; at += 1) {
6242
+ const header = lineAt(at - 1);
6243
+ const delimiter = lineAt(at);
6244
+ if (!header.includes("|") || !isDelimiterRow(delimiter)) continue;
6245
+ if (rowCells(header).length !== rowCells(delimiter).length) continue;
6246
+ let last = at;
6247
+ while (last + 1 < lines.length && lineAt(last + 1).includes("|")) last += 1;
6248
+ rows.push([lines[at - 1]?.[0] ?? 0, lines[last]?.[1] ?? text.length]);
6249
+ at = last;
6250
+ }
6251
+ return rows;
6252
+ }
6253
+ function rowCells(line) {
6254
+ let row = line.trim();
6255
+ if (row.startsWith("|")) row = row.slice(1);
6256
+ if (row.endsWith("|") && !row.endsWith("\\|")) row = row.slice(0, -1);
6257
+ const cells = [];
6258
+ let cell = "";
6259
+ for (let at = 0; at < row.length; at += 1) {
6260
+ const char = row.charAt(at);
6261
+ if (char === "\\") {
6262
+ cell += row.slice(at, at + 2);
6263
+ at += 1;
6264
+ } else if (char === "|") {
6265
+ cells.push(cell);
6266
+ cell = "";
6267
+ } else {
6268
+ cell += char;
6269
+ }
6270
+ }
6271
+ cells.push(cell);
6272
+ return cells;
6273
+ }
6274
+ function isDelimiterRow(line) {
6275
+ return line.includes("|") && rowCells(line).every((cell) => /^\s*:?-+:?\s*$/.test(cell));
6276
+ }
6277
+ var ESCAPABLE = /^[\x21-\x2f\x3a-\x40\x5b-\x60\x7b-\x7e]$/;
6278
+ var FENCE_OPEN = /[ \t]*(`{3,}|~{3,})([^\n]*)/y;
6279
+ var FENCE_LINE = /^[ \t]*(?:`{3,}|~{3,})/gm;
6280
+ function fencedBlockEnd(text, start) {
6281
+ FENCE_OPEN.lastIndex = start;
6282
+ const open = FENCE_OPEN.exec(text);
6283
+ if (!open) return void 0;
6284
+ const marker = open[1] ?? "";
6285
+ const fenceChar = marker.charAt(0);
6286
+ if (fenceChar === "`" && (open[2] ?? "").includes("`")) return void 0;
6287
+ let lineEnd = text.indexOf("\n", start);
6288
+ while (lineEnd !== -1) {
6289
+ const next = text.indexOf("\n", lineEnd + 1);
6290
+ const end = next === -1 ? text.length : next;
6291
+ const line = text.slice(lineEnd + 1, end).trim();
6292
+ if (line.length >= marker.length && [...line].every((c) => c === fenceChar)) return end;
6293
+ lineEnd = next;
6294
+ }
6295
+ return text.length;
6296
+ }
6297
+ var BLANK_LINE = /\n[ \t]*\n/g;
6298
+ function codeSpanEnd(text, start) {
6299
+ const open = backtickRun(text, start);
6300
+ BLANK_LINE.lastIndex = start;
6301
+ const blank = BLANK_LINE.exec(text);
6302
+ const limit = blank ? blank.index : text.length;
6303
+ let cursor = start + open;
6304
+ for (; ; ) {
6305
+ const next = text.indexOf("`", cursor);
6306
+ if (next === -1 || next >= limit) return start + open;
6307
+ const length = backtickRun(text, next);
6308
+ if (length === open) return next + length;
6309
+ cursor = next + length;
6310
+ }
6311
+ }
6312
+ function backtickRun(text, start) {
6313
+ let end = start;
6314
+ while (text.charAt(end) === "`") end += 1;
6315
+ return end - start;
6316
+ }
6317
+ function nextOutsideFences(text, from, pattern) {
6318
+ let cursor = from;
6319
+ for (; ; ) {
6320
+ pattern.lastIndex = cursor;
6321
+ const match = pattern.exec(text);
6322
+ if (!match) return null;
6323
+ FENCE_LINE.lastIndex = cursor;
6324
+ const fence = FENCE_LINE.exec(text);
6325
+ if (!fence || fence.index >= match.index) return match;
6326
+ cursor = fencedBlockEnd(text, fence.index) ?? fence.index + fence[0].length;
6327
+ }
6328
+ }
6329
+ var COMMENT = /<!--[\s\S]*?-->/g;
6330
+ var COMMENT_END = /-->/g;
6331
+ var TABLE_OPEN = /<table\b[^>]*>/iy;
6332
+ var TABLE_TAG = /<(\/?)table\b[^>]*>/gi;
6333
+ var HTML_TAG = /<(\/?)([a-z][a-z0-9]*)(?=[\s/>])[^<>]*>/iy;
6334
+ var BLOCK_ELEMENTS = /* @__PURE__ */ new Set([
6335
+ "address",
6336
+ "article",
6337
+ "aside",
6338
+ "blockquote",
6339
+ "body",
6340
+ "br",
6341
+ "center",
6342
+ "dd",
6343
+ "details",
6344
+ "dialog",
6345
+ "div",
6346
+ "dl",
6347
+ "dt",
6348
+ "fieldset",
6349
+ "figcaption",
6350
+ "figure",
6351
+ "footer",
6352
+ "form",
6353
+ "h1",
6354
+ "h2",
6355
+ "h3",
6356
+ "h4",
6357
+ "h5",
6358
+ "h6",
6359
+ "head",
6360
+ "header",
6361
+ "hgroup",
6362
+ "hr",
6363
+ "html",
6364
+ "legend",
6365
+ "li",
6366
+ "main",
6367
+ "nav",
6368
+ "ol",
6369
+ "option",
6370
+ "p",
6371
+ "pre",
6372
+ "section",
6373
+ "summary",
6374
+ "title",
6375
+ "ul"
6376
+ ]);
6377
+ var INLINE_ELEMENTS = /* @__PURE__ */ new Set([
6378
+ "a",
6379
+ "abbr",
6380
+ "b",
6381
+ "bdi",
6382
+ "bdo",
6383
+ "big",
6384
+ "cite",
6385
+ "code",
6386
+ "data",
6387
+ "del",
6388
+ "dfn",
6389
+ "em",
6390
+ "font",
6391
+ "i",
6392
+ "img",
6393
+ "ins",
6394
+ "kbd",
6395
+ "label",
6396
+ "mark",
6397
+ "picture",
6398
+ "q",
6399
+ "s",
6400
+ "samp",
6401
+ "small",
6402
+ "source",
6403
+ "span",
6404
+ "strike",
6405
+ "strong",
6406
+ "sub",
6407
+ "sup",
6408
+ "time",
6409
+ "tt",
6410
+ "u",
6411
+ "var",
6412
+ "wbr"
6413
+ ]);
6414
+ var RAW_TEXT_ENDS = /* @__PURE__ */ new Map([
6415
+ ["script", /<\/script\s*>/gi],
6416
+ ["style", /<\/style\s*>/gi]
6417
+ ]);
6418
+ function readMarkup(text, start) {
6419
+ if (text.startsWith("<!--", start)) {
6420
+ const close = nextOutsideFences(text, start + 4, COMMENT_END);
6421
+ return close ? { end: close.index + close[0].length, text: "" } : void 0;
6422
+ }
6423
+ TABLE_OPEN.lastIndex = start;
6424
+ if (TABLE_OPEN.test(text)) {
6425
+ const end2 = tableEnd(text, start);
6426
+ if (end2 === void 0) return void 0;
6427
+ return { end: end2, table: readTable(text.slice(start, end2).replace(COMMENT, "")) };
6428
+ }
6429
+ HTML_TAG.lastIndex = start;
6430
+ const tag = HTML_TAG.exec(text);
6431
+ if (!tag) return void 0;
6432
+ const closing = tag[1] === "/";
6433
+ const name = (tag[2] ?? "").toLowerCase();
6434
+ const end = start + tag[0].length;
6435
+ const rawTextEnd = closing ? void 0 : RAW_TEXT_ENDS.get(name);
6436
+ if (rawTextEnd) {
6437
+ rawTextEnd.lastIndex = end;
6438
+ const close = rawTextEnd.exec(text);
6439
+ return { end: close ? close.index + close[0].length : end, text: "\n" };
6440
+ }
6441
+ if (RAW_TEXT_ENDS.has(name) || BLOCK_ELEMENTS.has(name)) return { end, text: "\n" };
6442
+ if (INLINE_ELEMENTS.has(name)) return { end, text: "" };
6443
+ return void 0;
6444
+ }
6445
+ function tableEnd(text, start) {
6446
+ let depth = 0;
6447
+ let cursor = start;
6448
+ for (; ; ) {
6449
+ const tag = nextOutsideFences(text, cursor, TABLE_TAG);
6450
+ if (!tag) return void 0;
6451
+ depth += tag[1] === "/" ? -1 : 1;
6452
+ cursor = tag.index + tag[0].length;
6453
+ if (depth === 0) return cursor;
6454
+ }
6455
+ }
6456
+ var TABLE_STRUCTURE = /<(\/?)(table|caption|tr|td|th)\b([^>]*)>/gi;
6457
+ function readTable(markup) {
6458
+ let caption = "";
6459
+ let captionStart;
6460
+ const rows = [];
6461
+ let row;
6462
+ let cell;
6463
+ let depth = 0;
6464
+ const endCell = (at) => {
6465
+ if (cell && row) {
6466
+ const colSpan = span(cell.attributes, COLSPAN);
6467
+ const rowSpan = span(cell.attributes, ROWSPAN);
6468
+ row.push({
6469
+ text: cellText(markup.slice(cell.start, at)),
6470
+ header: cell.header,
6471
+ ...colSpan !== void 0 ? { colSpan } : {},
6472
+ ...rowSpan !== void 0 ? { rowSpan } : {}
6473
+ });
6474
+ }
6475
+ cell = void 0;
6476
+ };
6477
+ const endRow = (at) => {
6478
+ endCell(at);
6479
+ if (row && row.length > 0) rows.push(row);
6480
+ row = void 0;
6481
+ };
6482
+ for (const tag of markup.matchAll(TABLE_STRUCTURE)) {
6483
+ const closing = tag[1] === "/";
6484
+ const name = (tag[2] ?? "").toLowerCase();
6485
+ if (name === "table") {
6486
+ depth += closing ? -1 : 1;
6487
+ if (depth === 0) break;
6488
+ continue;
6489
+ }
6490
+ if (depth !== 1) continue;
6491
+ if (name === "caption") {
6492
+ if (!closing && caption === "" && captionStart === void 0) {
6493
+ captionStart = tag.index + tag[0].length;
6494
+ } else if (closing && captionStart !== void 0) {
6495
+ caption = cellText(markup.slice(captionStart, tag.index));
6496
+ captionStart = void 0;
6497
+ }
6498
+ continue;
6499
+ }
6500
+ if (name === "tr") {
6501
+ endRow(tag.index);
6502
+ if (!closing) row = [];
6503
+ continue;
6504
+ }
6505
+ endCell(tag.index);
6506
+ if (!closing && row) {
6507
+ cell = {
6508
+ header: name === "th",
6509
+ attributes: tag[3] ?? "",
6510
+ start: tag.index + tag[0].length
6511
+ };
6512
+ }
6513
+ }
6514
+ endRow(markup.length);
6515
+ if (rows.length === 0 && caption === "") return void 0;
6516
+ return { ...caption !== "" ? { caption } : {}, rows };
6517
+ }
6518
+ var COLSPAN = /\bcolspan\s*=\s*["']?(\d+)/i;
6519
+ var ROWSPAN = /\browspan\s*=\s*["']?(\d+)/i;
6520
+ function span(attributes, pattern) {
6521
+ const match = pattern.exec(attributes);
6522
+ const value = match ? Number(match[1]) : void 0;
6523
+ return value !== void 0 && value > 1 && value <= 1e3 ? value : void 0;
6524
+ }
6525
+ function cellText(markup) {
6526
+ return decodeHtmlEntities(
6527
+ markup.replace(/<br\s*\/?>/gi, "\n").replace(/<\/?(?:table|caption|tr|td|th)\b[^>]*>/gi, "\n").replace(/<[^>]*>/g, "")
6528
+ ).split("\n").map((line) => line.replace(/\s+/g, " ").trim()).filter((line) => line !== "").join("\n");
6529
+ }
5527
6530
  function unwrap(field, value) {
5528
6531
  if (!field.contentKey) return value;
5529
6532
  if (typeof value !== "object" || value === null || Array.isArray(value)) return value;
@@ -5642,6 +6645,7 @@ function pathLabel(url) {
5642
6645
  return segment && segment.length > 0 ? segment : url;
5643
6646
  }
5644
6647
  var FILE_BUTTON_ON_A_PHONE = "max-sm:grid max-sm:size-11 max-sm:place-items-center";
6648
+ var CARD_ACTION = "inline-flex shrink-0 items-center gap-1.5 rounded-md border border-border px-2 py-1 text-[12px] hover:bg-card max-sm:min-h-11 max-sm:px-3";
5645
6649
  function CopyButton({
5646
6650
  value,
5647
6651
  provide,
@@ -5756,7 +6760,7 @@ function useStuffFile(kind, value) {
5756
6760
  const location = useResultLocation();
5757
6761
  return location ? readStuffFile(kind, value, location.path.join(".")) : void 0;
5758
6762
  }
5759
- function FileDownloadButton({ file }) {
6763
+ function FileDownloadButton({ file, labelled = false }) {
5760
6764
  const s = useFieldStrings();
5761
6765
  const location = useResultLocation();
5762
6766
  const resolve = useResolveUrl();
@@ -5785,7 +6789,7 @@ ${planned.url ?? planned.text}`;
5785
6789
  const failed = state === "failed";
5786
6790
  const label = s.downloadFile(planned.name);
5787
6791
  return /* @__PURE__ */ jsxs(Fragment, { children: [
5788
- /* @__PURE__ */ jsx(
6792
+ /* @__PURE__ */ jsxs(
5789
6793
  "button",
5790
6794
  {
5791
6795
  type: "button",
@@ -5804,12 +6808,17 @@ ${planned.url ?? planned.text}`;
5804
6808
  title: failed ? s.downloadFileFailed : label,
5805
6809
  ...failed ? { "aria-describedby": statusId } : {},
5806
6810
  className: cn(
5807
- "shrink-0 rounded p-0.5 hover:bg-card disabled:opacity-60",
6811
+ labelled ? cn(CARD_ACTION, "disabled:opacity-60") : cn(
6812
+ "shrink-0 rounded p-0.5 hover:bg-card disabled:opacity-60",
6813
+ FILE_BUTTON_ON_A_PHONE
6814
+ ),
5808
6815
  focusOutlineClass,
5809
- FILE_BUTTON_ON_A_PHONE,
5810
6816
  failed ? "text-destructive" : "text-muted-foreground hover:text-foreground"
5811
6817
  ),
5812
- children: state === "saving" ? /* @__PURE__ */ jsx(Loader2, { "aria-hidden": true, className: "size-3.5 animate-spin" }) : state === "saved" ? /* @__PURE__ */ jsx(Check, { "aria-hidden": true, className: "size-3.5" }) : failed ? /* @__PURE__ */ jsx(TriangleAlert, { "aria-hidden": true, className: "size-3.5" }) : /* @__PURE__ */ jsx(Download, { "aria-hidden": true, className: "size-3.5" })
6818
+ children: [
6819
+ state === "saving" ? /* @__PURE__ */ jsx(Loader2, { "aria-hidden": true, className: "size-3.5 animate-spin" }) : state === "saved" ? /* @__PURE__ */ jsx(Check, { "aria-hidden": true, className: "size-3.5" }) : failed ? /* @__PURE__ */ jsx(TriangleAlert, { "aria-hidden": true, className: "size-3.5" }) : /* @__PURE__ */ jsx(Download, { "aria-hidden": true, className: "size-3.5" }),
6820
+ labelled && s.download
6821
+ ]
5813
6822
  }
5814
6823
  ),
5815
6824
  /* @__PURE__ */ jsx("span", { id: statusId, role: "status", className: "sr-only", children: failed ? s.downloadFileFailed : "" }),
@@ -5839,7 +6848,32 @@ function previewableUrl(content, resolve) {
5839
6848
  const renderable = content.mimeType ? PREVIEWABLE_MIME_RE.test(content.mimeType) : PREVIEWABLE_EXT_RE.test(named);
5840
6849
  return renderable ? url : void 0;
5841
6850
  }
5842
- function DocumentPreview({ url, name }) {
6851
+ function isPdfDocument(content, url) {
6852
+ return content.mimeType ? /^application\/pdf\s*(;|$)/i.test(content.mimeType) : /\.pdf(\?|#|$)/i.test(content.filename ?? url);
6853
+ }
6854
+ function DocumentPreview({
6855
+ url,
6856
+ name,
6857
+ pdf,
6858
+ file,
6859
+ whole
6860
+ }) {
6861
+ const viewer = usePdfViewer();
6862
+ const size = whole ? WHOLE_RESULT_FRAME : NESTED_FRAME;
6863
+ if (pdf && viewer === "no") return /* @__PURE__ */ jsx(PdfUnavailable, { url, name, file });
6864
+ if (pdf && viewer === "unknown") {
6865
+ return /* @__PURE__ */ jsx(
6866
+ "div",
6867
+ {
6868
+ "aria-hidden": true,
6869
+ className: cn(
6870
+ size,
6871
+ "flex items-center justify-center rounded-lg border border-border bg-card/40"
6872
+ ),
6873
+ children: /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin text-muted-foreground" })
6874
+ }
6875
+ );
6876
+ }
5843
6877
  return /* @__PURE__ */ jsx(
5844
6878
  FocusFrame,
5845
6879
  {
@@ -5847,19 +6881,56 @@ function DocumentPreview({ url, name }) {
5847
6881
  title: name,
5848
6882
  loading: "lazy",
5849
6883
  referrerPolicy: "no-referrer",
5850
- className: "h-112 w-full rounded-lg border border-border bg-card/40"
6884
+ className: cn(size, "rounded-lg border border-border bg-card/40")
5851
6885
  }
5852
6886
  );
5853
6887
  }
5854
- function DocumentValue({ value }) {
6888
+ var NESTED_FRAME = "h-112 w-full";
6889
+ var WHOLE_RESULT_FRAME = "aspect-[1/1.414] max-h-[80vh] min-h-80 w-full";
6890
+ function PdfUnavailable({
6891
+ url,
6892
+ name,
6893
+ file
6894
+ }) {
6895
+ const s = useFieldStrings();
6896
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 rounded-lg border border-border bg-card/40 px-3.5 py-3 sm:flex-row sm:items-center", children: [
6897
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-start gap-2.5", children: [
6898
+ /* @__PURE__ */ jsx(FileText, { "aria-hidden": true, className: "mt-0.5 size-4 shrink-0 text-muted-foreground" }),
6899
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-0.5", children: [
6900
+ /* @__PURE__ */ jsx("p", { title: name, className: "truncate text-[13px] font-medium text-foreground", children: name }),
6901
+ /* @__PURE__ */ jsx("p", { className: "text-[12.5px] leading-relaxed text-muted-foreground", children: s.pdfViewerUnavailable })
6902
+ ] })
6903
+ ] }),
6904
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
6905
+ /* @__PURE__ */ jsxs(
6906
+ "a",
6907
+ {
6908
+ href: url,
6909
+ target: "_blank",
6910
+ rel: "noreferrer",
6911
+ className: cn(CARD_ACTION, "text-foreground", focusOutlineClass),
6912
+ children: [
6913
+ /* @__PURE__ */ jsx(ExternalLink, { "aria-hidden": true, className: "size-3.5" }),
6914
+ s.openInNewTab
6915
+ ]
6916
+ }
6917
+ ),
6918
+ file && /* @__PURE__ */ jsx(FileDownloadButton, { file, labelled: true })
6919
+ ] })
6920
+ ] });
6921
+ }
6922
+ function DocumentValue({ value, whole = false }) {
5855
6923
  const s = useFieldStrings();
5856
6924
  const resolve = useResolveUrl();
6925
+ const isApp = useFieldPresentation() === "app";
5857
6926
  const [open, setOpen] = useState(false);
5858
6927
  const file = useStuffFile("document", value);
5859
6928
  const content = readDocumentContent(value);
5860
6929
  if (!content) return /* @__PURE__ */ jsx(Absent, {});
5861
6930
  const name = content.title ?? content.filename ?? fileLabel(content.url, content.filename, s);
5862
6931
  const preview = previewableUrl(content, resolve);
6932
+ const pdf = preview !== void 0 && isPdfDocument(content, preview);
6933
+ const opened = whole && isApp && pdf;
5863
6934
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
5864
6935
  /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-start gap-2.5", children: [
5865
6936
  /* @__PURE__ */ jsx(FileText, { "aria-hidden": true, className: "mt-0.5 size-4 shrink-0 text-muted-foreground" }),
@@ -5877,7 +6948,7 @@ function DocumentValue({ value }) {
5877
6948
  ),
5878
6949
  content.snippet && /* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-[12px] leading-relaxed text-muted-foreground", children: content.snippet })
5879
6950
  ] }),
5880
- preview && /* @__PURE__ */ jsxs(
6951
+ preview && !opened && /* @__PURE__ */ jsxs(
5881
6952
  "button",
5882
6953
  {
5883
6954
  type: "button",
@@ -5894,56 +6965,98 @@ function DocumentValue({ value }) {
5894
6965
  }
5895
6966
  )
5896
6967
  ] }),
5897
- preview && open && /* @__PURE__ */ jsx(DocumentPreview, { url: preview, name })
6968
+ preview && (opened || open) && /* @__PURE__ */ jsx(DocumentPreview, { url: preview, name, pdf, file, whole: opened })
5898
6969
  ] });
5899
6970
  }
6971
+ var TILE_RENDITION_SIDE = 576;
6972
+ var CELL_RENDITION_HEIGHT = 80;
6973
+ var CELL_RENDITION_WIDTH = 256;
6974
+ function renditionWidth(place, content) {
6975
+ const { width, height } = content;
6976
+ const ratio = width !== void 0 && height !== void 0 && width > 0 && height > 0 ? width / height : void 0;
6977
+ if (place === "tile") {
6978
+ return ratio === void 0 ? TILE_RENDITION_SIDE : Math.ceil(TILE_RENDITION_SIDE * Math.max(1, ratio));
6979
+ }
6980
+ return ratio === void 0 ? CELL_RENDITION_WIDTH : Math.max(CELL_RENDITION_WIDTH, Math.ceil(CELL_RENDITION_HEIGHT * ratio));
6981
+ }
6982
+ function renditionUrl(content, whole, resolveRendition, width) {
6983
+ return viewableUrl(resolveRendition?.(content.url, { width })) ?? whole;
6984
+ }
5900
6985
  function ImageValue({
5901
6986
  value,
5902
6987
  inGallery = false,
5903
6988
  inRow = false,
5904
- compact = false
6989
+ compact = false,
6990
+ downloadable = true,
6991
+ opener
5905
6992
  }) {
5906
6993
  const s = useFieldStrings();
6994
+ const presentation = useFieldPresentation();
5907
6995
  const resolve = useResolveUrl();
5908
- const file = useStuffFile("image", value);
6996
+ const resolveRendition = useResolveRendition();
6997
+ const stuffFile = useStuffFile("image", value);
6998
+ const file = downloadable ? stuffFile : void 0;
6999
+ const [viewing, setViewing] = useState(false);
7000
+ const ownButton = useRef(null);
7001
+ const frame = useRef(null);
5909
7002
  const content = readImageContent(value);
7003
+ const src = content ? paintableUrl(content, resolve) : void 0;
7004
+ if (viewing && src === void 0) setViewing(false);
5910
7005
  if (!content) return /* @__PURE__ */ jsx(Absent, {});
5911
- const src = paintableUrl(content, resolve);
5912
- return /* @__PURE__ */ jsxs("div", { className: inGallery ? "space-y-1" : "space-y-1.5", children: [
5913
- src ? (
5914
- // Wrapped in a link: the picture is a PREVIEW of a file, and clicking a
5915
- // preview to see the thing it previews is what a reader expects. The
5916
- // reference underneath is the other half - a picture with no URL beside
5917
- // it is a result you can look at and cannot use.
7006
+ const place = inGallery ? "tile" : compact ? "cell" : void 0;
7007
+ const drawn = src !== void 0 && place !== void 0 ? renditionUrl(content, src, resolveRendition, renditionWidth(place, content)) : src;
7008
+ const name = src === void 0 ? "" : fileLabel(src, content.filename, s);
7009
+ const fileLine = src !== void 0 && !compact && !(inGallery && presentation === "app");
7010
+ const size = !inGallery && !compact && content.width && content.height ? { width: content.width, height: content.height } : void 0;
7011
+ return /* @__PURE__ */ jsxs("div", { ref: frame, className: inGallery ? "space-y-1" : "space-y-1.5", children: [
7012
+ src !== void 0 && drawn !== void 0 ? (
7013
+ // A button, not a link: the picture opens in the viewer over the
7014
+ // result. Enter and Space open it as a click does.
5918
7015
  /* @__PURE__ */ jsx(
5919
- "a",
7016
+ "button",
5920
7017
  {
5921
- href: src,
5922
- target: "_blank",
5923
- rel: "noreferrer",
5924
- title: content.url,
7018
+ ref: opener ? opener.ref : ownButton,
7019
+ type: "button",
7020
+ onClick: opener ? opener.open : () => setViewing(true),
7021
+ "aria-label": s.viewImage(name),
7022
+ "aria-haspopup": "dialog",
5925
7023
  className: cn(
5926
- inGallery || compact ? "inline-block" : "block w-full",
7024
+ // BLOCK when the picture fills its column. A table cell's
7025
+ // thumbnail sizes itself, and is 44px square at the least below
7026
+ // `sm`, where it is tapped.
7027
+ compact ? "inline-flex items-center justify-center align-top max-sm:min-h-11 max-sm:min-w-11" : "block w-full",
7028
+ "cursor-zoom-in",
5927
7029
  focusOutlineInsetClass
5928
7030
  ),
5929
7031
  children: /* @__PURE__ */ jsx(
5930
7032
  LoadingImage,
5931
7033
  {
5932
- src,
7034
+ src: drawn,
7035
+ ...drawn !== src ? { fallbackSrc: src } : {},
5933
7036
  alt: content.caption ?? s.preview,
7037
+ lazy: inGallery || compact,
7038
+ ...size ? { size } : {},
7039
+ ...inGallery ? (
7040
+ // The tile's box is square before anything arrives, and the
7041
+ // picture covers it once it does: tiles of one size, whatever
7042
+ // the pictures' shapes, and nothing moves when one lands.
7043
+ { box: "aspect-square w-full overflow-hidden" }
7044
+ ) : compact ? { box: "h-10 min-w-10" } : {},
5934
7045
  className: cn(
5935
- inGallery && "block aspect-square w-full object-cover",
5936
- // A cell is one line tall. An image column rendered at the standalone
5937
- // height turns every row into a picture and the table into a
5938
- // slideshow, so a cell gets a thumbnail and the row's expansion gets
5939
- // the picture.
7046
+ inGallery && "absolute inset-0 size-full object-cover",
7047
+ // A cell is one line tall. An image column rendered at the
7048
+ // standalone height turns every row into a picture and the
7049
+ // table into a slideshow, so a cell gets a thumbnail and the
7050
+ // row's expansion gets the picture.
5940
7051
  compact && "h-10 w-auto rounded border border-border object-cover",
5941
7052
  // On its own: the full width it is given, capped generously in
5942
7053
  // height. `max-h-64` was a 256px thumbnail in a panel several
5943
7054
  // times that tall — a generated report image is the RESULT here,
5944
- // not a decoration beside one, and it was unreadable at that size.
5945
- // `object-contain` keeps the aspect ratio when the cap bites.
5946
- !inGallery && !compact && "max-h-176 w-full rounded-lg border border-border object-contain"
7055
+ // not a decoration beside one, and it was unreadable at that
7056
+ // size. `object-contain` keeps the aspect ratio when the cap
7057
+ // bites, and the payload's own width and height, when it states
7058
+ // them, reserve the box before the picture arrives.
7059
+ !inGallery && !compact && "h-auto max-h-176 w-full rounded-lg border border-border object-contain"
5947
7060
  )
5948
7061
  }
5949
7062
  )
@@ -5989,7 +7102,7 @@ function ImageValue({
5989
7102
  file
5990
7103
  }
5991
7104
  ),
5992
- src && !compact && /* @__PURE__ */ jsx("div", { className: inGallery ? "px-2.5" : void 0, children: /* @__PURE__ */ jsx(
7105
+ fileLine && /* @__PURE__ */ jsx("div", { className: inGallery ? "px-2.5" : void 0, children: /* @__PURE__ */ jsx(
5993
7106
  FileRef,
5994
7107
  {
5995
7108
  url: src,
@@ -6008,6 +7121,24 @@ function ImageValue({
6008
7121
  ),
6009
7122
  children: content.caption
6010
7123
  }
7124
+ ),
7125
+ viewing && src !== void 0 && /* @__PURE__ */ jsx(
7126
+ ImageViewer,
7127
+ {
7128
+ pictures: [
7129
+ {
7130
+ src,
7131
+ name,
7132
+ ...content.caption ? { caption: content.caption } : {},
7133
+ actions: /* @__PURE__ */ jsx(FileActions, { copy: { url: src, storageUrl: content.url }, file })
7134
+ }
7135
+ ],
7136
+ index: 0,
7137
+ onIndexChange: () => {
7138
+ },
7139
+ onClose: () => setViewing(false),
7140
+ returnFocus: () => ownButton.current ?? frame.current?.querySelector("a[href], button")
7141
+ }
6011
7142
  )
6012
7143
  ] });
6013
7144
  }
@@ -6043,7 +7174,13 @@ function LeafValue({
6043
7174
  }
6044
7175
  function RecordSummary({ field, value }) {
6045
7176
  const s = useFieldStrings();
7177
+ const presentation = useFieldPresentation();
6046
7178
  if (isNativeDateNode(field)) return /* @__PURE__ */ jsx(DateValue, { value });
7179
+ const verdict = presentation === "app" ? nativeVerdictOf(field) : void 0;
7180
+ const reading = verdict ? readVerdict(verdict, value, s) : void 0;
7181
+ if (reading) {
7182
+ return /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap text-[13px] text-foreground", children: reading.answer });
7183
+ }
6047
7184
  if (!isRecord(value) || Object.keys(value).length === 0) return /* @__PURE__ */ jsx(Absent, {});
6048
7185
  const naming = isNativeHtmlNode(field) ? void 0 : recordNameField(field.fields) ?? field.fields.find((member) => member.kind === "prose");
6049
7186
  if (naming === void 0) {
@@ -6051,32 +7188,59 @@ function RecordSummary({ field, value }) {
6051
7188
  }
6052
7189
  return /* @__PURE__ */ jsx(LeafValue, { field: naming, value: ownProp(value, naming.name), compact: true });
6053
7190
  }
6054
- function LoadingImage({ src, alt, className }) {
7191
+ function LoadingImage({
7192
+ src,
7193
+ fallbackSrc,
7194
+ alt,
7195
+ className,
7196
+ box,
7197
+ size,
7198
+ lazy = false
7199
+ }) {
6055
7200
  const [state, setState] = useState("loading");
6056
- const [current, setCurrent] = useState(src);
6057
- if (current !== src) {
6058
- setCurrent(src);
6059
- setState("loading");
7201
+ const [current, setCurrent] = useState({ src, fallbackSrc });
7202
+ const [shown, setShown] = useState(src);
7203
+ if (current.src !== src || current.fallbackSrc !== fallbackSrc) {
7204
+ const next = current.src !== src ? src : shown === current.fallbackSrc ? fallbackSrc ?? src : shown;
7205
+ setCurrent({ src, fallbackSrc });
7206
+ if (next !== shown) {
7207
+ setShown(next);
7208
+ setState("loading");
7209
+ }
6060
7210
  }
6061
- return /* @__PURE__ */ jsxs("span", { className: "relative block", children: [
7211
+ const reserved = box !== void 0 || size !== void 0;
7212
+ return /* @__PURE__ */ jsxs("span", { className: cn("relative block", box), children: [
6062
7213
  state === "loading" && /* @__PURE__ */ jsx(
6063
7214
  "span",
6064
7215
  {
6065
7216
  role: "status",
6066
7217
  "aria-label": alt,
6067
- className: "absolute inset-0 flex items-center justify-center rounded-lg border border-border bg-card/40",
7218
+ className: cn(
7219
+ "absolute inset-0 flex items-center justify-center",
7220
+ // A box the caller drew is the frame; anything else gets one.
7221
+ box ? "bg-muted/40" : "rounded-lg border border-border bg-card/40"
7222
+ ),
6068
7223
  children: /* @__PURE__ */ jsx(Loader2, { "aria-hidden": true, className: "size-4 animate-spin text-muted-foreground" })
6069
7224
  }
6070
7225
  ),
6071
7226
  /* @__PURE__ */ jsx(
6072
7227
  "img",
6073
7228
  {
6074
- src,
7229
+ src: shown,
6075
7230
  alt,
6076
7231
  referrerPolicy: "no-referrer",
7232
+ decoding: "async",
7233
+ ...lazy ? { loading: "lazy" } : {},
7234
+ ...size ? { width: size.width, height: size.height } : {},
6077
7235
  onLoad: () => setState("done"),
6078
- onError: () => setState("done"),
6079
- className: cn(className, state === "loading" && "min-h-40 opacity-0")
7236
+ onError: () => {
7237
+ if (fallbackSrc !== void 0 && shown !== fallbackSrc) setShown(fallbackSrc);
7238
+ else setState("done");
7239
+ },
7240
+ className: cn(
7241
+ className,
7242
+ state === "loading" && (reserved ? "opacity-0" : "min-h-40 opacity-0")
7243
+ )
6080
7244
  }
6081
7245
  )
6082
7246
  ] });
@@ -6380,42 +7544,157 @@ function ObjectTable({
6380
7544
  );
6381
7545
  }
6382
7546
  function CompositeValue({ members }) {
6383
- return /* @__PURE__ */ jsx("div", { className: "space-y-3", children: members.map((member) => /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
6384
- /* @__PURE__ */ jsx("span", { className: "font-mono text-[12px] font-semibold text-foreground", children: member.name }),
6385
- /* @__PURE__ */ jsx(NativeValue, { value: member.value })
6386
- ] }, member.name)) });
7547
+ const presentation = useFieldPresentation();
7548
+ const isApp = presentation === "app";
7549
+ return /* @__PURE__ */ jsx("div", { className: "space-y-3", children: members.map((member) => {
7550
+ const label = isApp ? humanizeFieldName(member.name) : member.name;
7551
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
7552
+ /* @__PURE__ */ jsx(
7553
+ "span",
7554
+ {
7555
+ className: cn(
7556
+ "font-semibold text-foreground",
7557
+ isApp ? "text-[13.5px]" : "font-mono text-[12px]"
7558
+ ),
7559
+ children: label
7560
+ }
7561
+ ),
7562
+ /* @__PURE__ */ jsx(NativeValue, { value: member.value, label })
7563
+ ] }, member.name);
7564
+ }) });
6387
7565
  }
6388
- function NativeValue({ value }) {
7566
+ function NativeValue({ value, label }) {
6389
7567
  if (value === null || value === void 0 || value === "") return /* @__PURE__ */ jsx(Absent, {});
6390
- const html = readHtmlContent(value);
6391
- if (html) return /* @__PURE__ */ jsx(HtmlPreview, { content: html, downloadPdf: false });
6392
- const date = readDateContent(value);
6393
- if (date) return /* @__PURE__ */ jsx("span", { className: "text-[13px] text-foreground", children: formatDateContent(date) });
6394
- const document2 = readDocumentContent(value);
6395
- if (document2?.url !== void 0) {
6396
- return /* @__PURE__ */ jsx(
6397
- FileRef,
6398
- {
6399
- url: document2.url,
6400
- ...document2.mimeType !== void 0 ? { mimeType: document2.mimeType } : {},
6401
- ...document2.filename !== void 0 ? { filename: document2.filename } : {}
6402
- }
6403
- );
7568
+ if (typeof value === "string") return /* @__PURE__ */ jsx(Markdown, { text: value });
7569
+ if (Array.isArray(value)) return /* @__PURE__ */ jsx(NativeList, { items: value, label });
7570
+ if (!isRecord(value)) return /* @__PURE__ */ jsx(Scalar, { value });
7571
+ const content = readMemberContent(value);
7572
+ switch (content?.model) {
7573
+ case "html":
7574
+ return /* @__PURE__ */ jsx(HtmlPreview, { content: content.html, downloadPdf: false });
7575
+ case "date":
7576
+ return /* @__PURE__ */ jsx("span", { className: "text-[13px] text-foreground", children: formatDateContent(content.date) });
7577
+ case "image":
7578
+ return /* @__PURE__ */ jsx(ImageValue, { value, downloadable: false });
7579
+ case "document":
7580
+ return /* @__PURE__ */ jsx(
7581
+ FileRef,
7582
+ {
7583
+ url: content.document.url,
7584
+ ...content.document.mimeType !== void 0 ? { mimeType: content.document.mimeType } : {},
7585
+ ...content.document.filename !== void 0 ? { filename: content.document.filename } : {}
7586
+ }
7587
+ );
7588
+ case "list":
7589
+ return /* @__PURE__ */ jsx(NativeList, { items: content.items, label });
7590
+ case "text":
7591
+ return content.text === "" ? /* @__PURE__ */ jsx(Absent, {}) : /* @__PURE__ */ jsx(Markdown, { text: content.text });
7592
+ case void 0:
7593
+ return /* @__PURE__ */ jsx(RawValue, { value, compact: false });
7594
+ }
7595
+ }
7596
+ function NativeList({ items, label }) {
7597
+ if (items.length === 0) return /* @__PURE__ */ jsx(Absent, {});
7598
+ if (items.every(isPlainRecord)) return /* @__PURE__ */ jsx(RecordsTable, { items, label });
7599
+ return /* @__PURE__ */ jsx("div", { className: "divide-y divide-border/60 overflow-hidden rounded-lg border border-border", children: items.map((item, index) => /* @__PURE__ */ jsx("div", { className: "bg-card/40 px-3 py-1.5", children: /* @__PURE__ */ jsx(NativeValue, { value: item, label }) }, index)) });
7600
+ }
7601
+ var TEXT_MEMBERS = /* @__PURE__ */ new Set(["text"]);
7602
+ var DATE_MEMBERS = /* @__PURE__ */ new Set(["date", "time", ...TYPED_SCALAR_MARKERS]);
7603
+ var HTML_MEMBERS = /* @__PURE__ */ new Set(["inner_html", "css_class"]);
7604
+ var DOCUMENT_MEMBERS = /* @__PURE__ */ new Set([
7605
+ "url",
7606
+ "public_url",
7607
+ "mime_type",
7608
+ "filename",
7609
+ "title",
7610
+ "snippet"
7611
+ ]);
7612
+ var IMAGE_MEMBERS = /* @__PURE__ */ new Set([
7613
+ "url",
7614
+ "public_url",
7615
+ "source_prompt",
7616
+ "source_negative_prompt",
7617
+ "caption",
7618
+ "mime_type",
7619
+ "width",
7620
+ "height",
7621
+ "filename"
7622
+ ]);
7623
+ var LIST_MEMBERS = /* @__PURE__ */ new Set(["items"]);
7624
+ function holdsOnly(record, members) {
7625
+ return Object.keys(record).every((key) => members.has(key));
7626
+ }
7627
+ function readMemberContent(record) {
7628
+ if (holdsOnly(record, HTML_MEMBERS)) {
7629
+ const html = readHtmlContent(record);
7630
+ if (html) return { model: "html", html };
6404
7631
  }
6405
- if (isRecord(value) && Array.isArray(value.items)) {
6406
- const items = value.items;
6407
- if (items.length === 0) return /* @__PURE__ */ jsx(Absent, {});
6408
- return /* @__PURE__ */ jsx("div", { className: "divide-y divide-border/60 overflow-hidden rounded-lg border border-border", children: items.map((item, index) => /* @__PURE__ */ jsx("div", { className: "bg-card/40 px-3 py-1.5", children: /* @__PURE__ */ jsx(NativeValue, { value: item }) }, index)) });
7632
+ if (holdsOnly(record, DATE_MEMBERS)) {
7633
+ const date = readDateContent(record);
7634
+ if (date) return { model: "date", date };
6409
7635
  }
6410
- if (isRecord(value)) {
6411
- const text = value.text;
6412
- if (typeof text === "string") {
6413
- return text === "" ? /* @__PURE__ */ jsx(Absent, {}) : /* @__PURE__ */ jsx(Markdown, { text });
7636
+ if (holdsOnly(record, IMAGE_MEMBERS)) {
7637
+ const image = readImageContent(record);
7638
+ if (image && (!holdsOnly(record, DOCUMENT_MEMBERS) || image.mimeType?.toLowerCase().startsWith("image/") === true)) {
7639
+ return { model: "image" };
6414
7640
  }
6415
7641
  }
6416
- if (typeof value === "string") return /* @__PURE__ */ jsx(Markdown, { text: value });
6417
- if (typeof value !== "object") return /* @__PURE__ */ jsx(Scalar, { value });
6418
- return /* @__PURE__ */ jsx(RawValue, { value, compact: false });
7642
+ if (holdsOnly(record, DOCUMENT_MEMBERS)) {
7643
+ const document2 = readDocumentContent(record);
7644
+ if (document2) return { model: "document", document: document2 };
7645
+ }
7646
+ if (holdsOnly(record, LIST_MEMBERS)) {
7647
+ const items = ownProp(record, "items");
7648
+ if (Array.isArray(items)) return { model: "list", items };
7649
+ }
7650
+ if (holdsOnly(record, TEXT_MEMBERS)) {
7651
+ const text = ownProp(record, "text");
7652
+ if (typeof text === "string") return { model: "text", text };
7653
+ }
7654
+ return void 0;
7655
+ }
7656
+ function isPlainRecord(value) {
7657
+ if (!isRecord(value) || Object.keys(value).length === 0) return false;
7658
+ return readMemberContent(value) === void 0;
7659
+ }
7660
+ function RecordsTable({
7661
+ items,
7662
+ label
7663
+ }) {
7664
+ const presentation = useFieldPresentation();
7665
+ const isApp = presentation === "app";
7666
+ const columns = [];
7667
+ for (const item of items) {
7668
+ for (const key of Object.keys(item)) if (!columns.includes(key)) columns.push(key);
7669
+ }
7670
+ const columnLabel = (column) => isApp ? humanizeFieldName(column) : column;
7671
+ return /* @__PURE__ */ jsx(
7672
+ "div",
7673
+ {
7674
+ role: "group",
7675
+ "aria-label": label,
7676
+ tabIndex: 0,
7677
+ className: cn("overflow-x-auto rounded-lg border border-border", focusOutlineClass),
7678
+ children: /* @__PURE__ */ jsxs("table", { className: "min-w-full border-collapse text-[12.5px] text-foreground", children: [
7679
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { className: "border-b border-border bg-card/40", children: columns.map((column) => /* @__PURE__ */ jsx(
7680
+ "th",
7681
+ {
7682
+ scope: "col",
7683
+ className: cn(
7684
+ "px-2.5 py-1.5 text-start align-bottom font-semibold",
7685
+ !isApp && "font-mono text-[12px]"
7686
+ ),
7687
+ children: columnLabel(column)
7688
+ },
7689
+ column
7690
+ )) }) }),
7691
+ /* @__PURE__ */ jsx("tbody", { children: items.map((item, index) => /* @__PURE__ */ jsx("tr", { className: "border-b border-border/60 last:border-b-0", children: columns.map((column) => {
7692
+ const cell = ownProp(item, column);
7693
+ return /* @__PURE__ */ jsx("td", { className: "px-2.5 py-1.5 align-top", children: typeof cell === "boolean" ? /* @__PURE__ */ jsx(Bool, { value: cell }) : typeof cell === "object" && cell !== null ? /* @__PURE__ */ jsx(NativeValue, { value: cell, label: columnLabel(column) }) : /* @__PURE__ */ jsx(Scalar, { value: cell }) }, column);
7694
+ }) }, index)) })
7695
+ ] })
7696
+ }
7697
+ );
6419
7698
  }
6420
7699
  function isRecord(value) {
6421
7700
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -6424,12 +7703,65 @@ function ScalarLines({ field, items }) {
6424
7703
  return /* @__PURE__ */ jsx("div", { className: "divide-y divide-border/60 overflow-hidden rounded-lg border border-border", children: items.map((item, index) => /* @__PURE__ */ jsx("div", { className: "bg-card/40 px-3 py-1.5", children: /* @__PURE__ */ jsx(LeafValue, { field, value: item }) }, index)) });
6425
7704
  }
6426
7705
  function ImageGallery({ items }) {
6427
- const anyViewable = items.some((item) => {
7706
+ const s = useFieldStrings();
7707
+ const resolve = useResolveUrl();
7708
+ const [viewing, setViewing] = useState(null);
7709
+ const tiles = useRef(/* @__PURE__ */ new Map());
7710
+ const gallery = useRef(null);
7711
+ const pictures = items.flatMap((item, entry) => {
6428
7712
  const content = readImageContent(item);
6429
- return content ? !!(viewableUrl(content.publicUrl) ?? viewableUrl(content.url)) : false;
7713
+ const src = content ? paintableUrl(content, resolve) : void 0;
7714
+ return content && src !== void 0 ? [{ entry, item, content, src }] : [];
6430
7715
  });
6431
- if (!anyViewable) return /* @__PURE__ */ jsx(FileRows, { items, kind: "image" });
6432
- return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-2", children: items.map((item, index) => /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-lg border border-border bg-card/40", children: /* @__PURE__ */ jsx(ResultAt, { segment: String(index), children: /* @__PURE__ */ jsx(ImageValue, { value: item, inGallery: true }) }) }, index)) });
7716
+ const shown = viewing ? pictures.findIndex((picture) => picture.entry === viewing.entry) : -1;
7717
+ if (viewing && shown === -1) setViewing(null);
7718
+ const returnFocus = (opener) => () => {
7719
+ const first = [...tiles.current.entries()].sort(([a], [b]) => a - b)[0]?.[1];
7720
+ return tiles.current.get(opener) ?? first ?? gallery.current;
7721
+ };
7722
+ const frame = (children) => /* @__PURE__ */ jsx("div", { ref: gallery, tabIndex: -1, className: "outline-none", children });
7723
+ if (pictures.length === 0) return frame(/* @__PURE__ */ jsx(FileRows, { items, kind: "image" }));
7724
+ return frame(
7725
+ /* @__PURE__ */ jsxs(Fragment, { children: [
7726
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-2", children: items.map((item, index) => /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-lg border border-border bg-card/40", children: /* @__PURE__ */ jsx(ResultAt, { segment: String(index), children: /* @__PURE__ */ jsx(
7727
+ ImageValue,
7728
+ {
7729
+ value: item,
7730
+ inGallery: true,
7731
+ opener: {
7732
+ open: () => setViewing({ entry: index, opener: index }),
7733
+ ref: (button) => {
7734
+ if (button) tiles.current.set(index, button);
7735
+ else tiles.current.delete(index);
7736
+ }
7737
+ }
7738
+ }
7739
+ ) }) }, index)) }),
7740
+ viewing && shown !== -1 && /* @__PURE__ */ jsx(
7741
+ ImageViewer,
7742
+ {
7743
+ pictures: pictures.map(({ entry, item, content, src }) => ({
7744
+ src,
7745
+ name: fileLabel(src, content.filename, s),
7746
+ ...content.caption ? { caption: content.caption } : {},
7747
+ actions: /* @__PURE__ */ jsx(ResultAt, { segment: String(entry), children: /* @__PURE__ */ jsx(ViewerFileActions, { value: item, src }) })
7748
+ })),
7749
+ index: shown,
7750
+ onIndexChange: (position) => {
7751
+ const picture = pictures[position];
7752
+ if (picture) setViewing({ entry: picture.entry, opener: viewing.opener });
7753
+ },
7754
+ onClose: () => setViewing(null),
7755
+ returnFocus: returnFocus(viewing.opener)
7756
+ }
7757
+ )
7758
+ ] })
7759
+ );
7760
+ }
7761
+ function ViewerFileActions({ value, src }) {
7762
+ const file = useStuffFile("image", value);
7763
+ const content = readImageContent(value);
7764
+ return /* @__PURE__ */ jsx(FileActions, { copy: { url: src, ...content ? { storageUrl: content.url } : {} }, file });
6433
7765
  }
6434
7766
  function FileRows({ items, kind }) {
6435
7767
  return /* @__PURE__ */ jsx("div", { className: "divide-y divide-border overflow-hidden rounded-lg border border-border", children: items.map((item, index) => /* @__PURE__ */ jsx("div", { className: "bg-card/40 px-3.5 py-2", children: /* @__PURE__ */ jsx(ResultAt, { segment: String(index), children: kind === "document" ? /* @__PURE__ */ jsx(DocumentValue, { value: item }) : /* @__PURE__ */ jsx(ImageValue, { value: item, inRow: true }) }) }, index)) });
@@ -6459,17 +7791,112 @@ function chooseColumns(fields, budget) {
6459
7791
  ...name ? { name } : {}
6460
7792
  };
6461
7793
  }
7794
+ var RAW_PAGE_SOURCES = "data:";
7795
+ function PageValue({ field, value, depth }) {
7796
+ const presentation = useFieldPresentation();
7797
+ const content = readPageContent(value);
7798
+ const text = content?.text;
7799
+ const segments = useMemo(() => text === void 0 ? [] : splitExtractedText(text), [text]);
7800
+ const hasText = segments.length > 0;
7801
+ const rawHtml = hasText ? void 0 : content?.rawHtml;
7802
+ const rawPage = useMemo(
7803
+ () => rawHtml === void 0 ? void 0 : { innerHtml: rawHtml },
7804
+ [rawHtml]
7805
+ );
7806
+ if (!content) return /* @__PURE__ */ jsx(Absent, {});
7807
+ const extracted = hasText || rawPage !== void 0 || content.images.length > 0;
7808
+ const showView = content.pageView !== void 0 && (presentation === "studio" || !extracted);
7809
+ if (!extracted && !showView) return /* @__PURE__ */ jsx(Absent, {});
7810
+ const viewField = field.kind === "object" ? field.fields.find((member) => member.name === "page_view") : void 0;
7811
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
7812
+ hasText && /* @__PURE__ */ jsx(ExtractedPageText, { segments }),
7813
+ rawPage && /* @__PURE__ */ jsx(
7814
+ HtmlPreview,
7815
+ {
7816
+ content: rawPage,
7817
+ downloadPdf: false,
7818
+ imgSrc: RAW_PAGE_SOURCES,
7819
+ fontSrc: RAW_PAGE_SOURCES
7820
+ }
7821
+ ),
7822
+ content.images.length > 0 && /* @__PURE__ */ jsx(ResultAt, { segment: "text_and_images", children: /* @__PURE__ */ jsx(ResultAt, { segment: "images", children: /* @__PURE__ */ jsx(ImageGallery, { items: content.images }) }) }),
7823
+ showView && /* @__PURE__ */ jsx(ResultAt, { segment: "page_view", children: presentation === "studio" && viewField ? /* @__PURE__ */ jsx(ResultField, { field: viewField, value: content.pageView, depth: depth + 1 }) : /* @__PURE__ */ jsx(ImageValue, { value: content.pageView }) })
7824
+ ] });
7825
+ }
7826
+ function readVerdict(verdict, value, s) {
7827
+ if (verdict === "yes_no") {
7828
+ const content2 = readYesNoContent(value);
7829
+ if (!content2) return void 0;
7830
+ return {
7831
+ answer: content2.yesNo ? s.yes : s.no,
7832
+ ...content2.probability !== void 0 ? { measure: s.yesProbability(content2.probability) } : {}
7833
+ };
7834
+ }
7835
+ if (verdict === "rating") {
7836
+ const content2 = readRatingContent(value);
7837
+ if (!content2) return void 0;
7838
+ return {
7839
+ // A scale that names its levels says which one in words; one that does
7840
+ // not is counted from one, as a reader counts.
7841
+ answer: content2.label ?? s.ratingLevel(content2.level + 1),
7842
+ ...content2.confidence !== void 0 ? { measure: s.verdictConfidence(content2.confidence) } : {}
7843
+ };
7844
+ }
7845
+ const content = readChoiceContent(value);
7846
+ if (!content) return void 0;
7847
+ return {
7848
+ answer: humanizeEnumValue(content.choice),
7849
+ ...content.confidence !== void 0 ? { measure: s.verdictConfidence(content.confidence) } : {}
7850
+ };
7851
+ }
7852
+ function VerdictValue({ reading, prominent }) {
7853
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
7854
+ /* @__PURE__ */ jsx(
7855
+ "p",
7856
+ {
7857
+ className: cn(
7858
+ "font-semibold text-foreground",
7859
+ prominent ? "text-[22px] leading-tight" : "text-[15px] leading-snug"
7860
+ ),
7861
+ children: reading.answer
7862
+ }
7863
+ ),
7864
+ reading.measure !== void 0 && /* @__PURE__ */ jsx("p", { className: "text-[12.5px] text-muted-foreground", children: reading.measure })
7865
+ ] });
7866
+ }
7867
+ function isLongText(value) {
7868
+ return typeof value === "string" && (value.includes("\n") || value.length > CELL_LENGTH_LIMIT);
7869
+ }
7870
+ var PanelResultContext = createContext(null);
7871
+ var TITLED_PANEL = { hostHeaded: false };
7872
+ var HOST_HEADED_PANEL = { hostHeaded: true };
7873
+ function PanelResult({
7874
+ hostHeaded,
7875
+ children
7876
+ }) {
7877
+ return /* @__PURE__ */ jsx(PanelResultContext, { value: hostHeaded ? HOST_HEADED_PANEL : TITLED_PANEL, children });
7878
+ }
6462
7879
  function ResultField(props) {
6463
7880
  const location = useResultLocation();
6464
- if (location) return /* @__PURE__ */ jsx(ResultNode, { ...props });
6465
- return /* @__PURE__ */ jsx(ResultRoot, { baseName: props.field.name, path: [props.field.name], children: /* @__PURE__ */ jsx(ResultNode, { ...props }) });
7881
+ const panel = use(PanelResultContext);
7882
+ const node = panel ? /* @__PURE__ */ jsx(PanelResultContext, { value: null, children: /* @__PURE__ */ jsx(ResultNode, { ...props, whole: true, hostHeaded: panel.hostHeaded }) }) : /* @__PURE__ */ jsx(ResultNode, { ...props });
7883
+ if (location) return node;
7884
+ return /* @__PURE__ */ jsx(ResultRoot, { baseName: props.field.name, path: [props.field.name], children: node });
6466
7885
  }
6467
- function ResultNode({ field, value, depth = 0, hideLabel = false }) {
7886
+ function ResultNode({
7887
+ field,
7888
+ value,
7889
+ depth = 0,
7890
+ hideLabel = false,
7891
+ whole = false,
7892
+ hostHeaded = false
7893
+ }) {
6468
7894
  const s = useFieldStrings();
6469
7895
  const unwrapped = unwrap(field, value);
6470
7896
  const pageDownloadShown = useFileDownloadShown("markup");
6471
7897
  const pdfShown = usePdfSaveShown();
6472
7898
  const location = useResultLocation();
7899
+ const isApp = useFieldPresentation() === "app";
6473
7900
  const header = hideLabel ? null : /* @__PURE__ */ jsx(Label2, { field, describe: true });
6474
7901
  const copyText = (field.kind === "text" || field.kind === "prose") && typeof unwrapped === "string" && unwrapped !== "" ? unwrapped : void 0;
6475
7902
  if (isNativeDateNode(field)) {
@@ -6507,9 +7934,24 @@ function ResultNode({ field, value, depth = 0, hideLabel = false }) {
6507
7934
  members && members.length > 0 ? /* @__PURE__ */ jsx(CompositeValue, { members }) : /* @__PURE__ */ jsx(Absent, {})
6508
7935
  ] });
6509
7936
  }
7937
+ if (isNativePageNode(field)) {
7938
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
7939
+ header,
7940
+ /* @__PURE__ */ jsx(PageValue, { field, value: unwrapped, depth })
7941
+ ] });
7942
+ }
7943
+ const verdict = isApp ? nativeVerdictOf(field) : void 0;
7944
+ const reading = verdict ? readVerdict(verdict, unwrapped, s) : void 0;
7945
+ if (reading) {
7946
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
7947
+ header,
7948
+ /* @__PURE__ */ jsx(VerdictValue, { reading, prominent: whole })
7949
+ ] });
7950
+ }
6510
7951
  switch (field.kind) {
6511
7952
  case "object": {
6512
7953
  const memberValue = (child) => typeof unwrapped === "object" && unwrapped !== null ? ownProp(unwrapped, child.name) : void 0;
7954
+ const sharesALine = (child) => isInlineColumn(child) && !(isApp && child.kind === "text" && isLongText(unwrap(child, memberValue(child))));
6513
7955
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
6514
7956
  header,
6515
7957
  /* @__PURE__ */ jsx(
@@ -6541,7 +7983,7 @@ function ResultNode({ field, value, depth = 0, hideLabel = false }) {
6541
7983
  // so does anything with chrome of its own - a table, a gallery, a
6542
7984
  // frame - which beside a label would be squeezed into whatever the
6543
7985
  // longest label left over.
6544
- isInlineColumn(child) ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
7986
+ sharesALine(child) ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
6545
7987
  /* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx(Label2, { field: child, describe: true }) }),
6546
7988
  /* @__PURE__ */ jsx("div", { className: "flex min-w-0 justify-end **:data-chips:justify-end", children: /* @__PURE__ */ jsx("div", { className: "min-w-0 text-left wrap-break-word", children: /* @__PURE__ */ jsx(LeafValue, { field: child, value: memberValue(child) }) }) })
6547
7989
  ] }, child.name) : /* @__PURE__ */ jsx("div", { className: "col-span-2 min-w-0", children: /* @__PURE__ */ jsx(ResultAt, { segment: child.name, children: /* @__PURE__ */ jsx(ResultField, { field: child, value: memberValue(child), depth: depth + 1 }) }) }, child.name)
@@ -6555,7 +7997,7 @@ function ResultNode({ field, value, depth = 0, hideLabel = false }) {
6555
7997
  const items = Array.isArray(unwrapped) ? unwrapped : [];
6556
7998
  const columns = recordColumns(field.item);
6557
7999
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
6558
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2", children: [
8000
+ isApp && hostHeaded ? null : /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline gap-x-2", children: [
6559
8001
  header,
6560
8002
  /* @__PURE__ */ jsx("span", { className: "font-mono text-[10.5px] text-muted-foreground", children: s.itemsCount(items.length) })
6561
8003
  ] }),
@@ -6567,6 +8009,30 @@ function ResultNode({ field, value, depth = 0, hideLabel = false }) {
6567
8009
  // column named by it, and show a composite as JSON. The arm keyed by
6568
8010
  // concept is the one that knows what each entry is.
6569
8011
  /* @__PURE__ */ jsx("div", { className: "divide-y divide-border/60 overflow-hidden rounded-lg border border-border", children: items.map((item, index) => /* @__PURE__ */ jsx("div", { className: "bg-card/40 px-3 py-1.5", children: /* @__PURE__ */ jsx(ResultAt, { segment: String(index), children: /* @__PURE__ */ jsx(ResultField, { field: field.item, value: item, depth: depth + 1, hideLabel: true }) }) }, index)) })
8012
+ ) : isNativePageNode(field.item) ? (
8013
+ // A document's pages, one after the other, each drawn by the page
8014
+ // arm and captioned with its number: a page is a document's unit,
8015
+ // and a table of pages had a row per page and the text nowhere.
8016
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: items.map((item, index) => (
8017
+ // An article, not a section: a named section is a landmark,
8018
+ // and a landmark's name must be unique on the page, which
8019
+ // "Page 1" is not once a host shows two results.
8020
+ /* @__PURE__ */ jsxs(
8021
+ "article",
8022
+ {
8023
+ "aria-label": s.pageNumber(index + 1),
8024
+ className: "space-y-2 rounded-lg border border-border bg-card/40 px-3.5 py-3",
8025
+ children: [
8026
+ /* @__PURE__ */ jsx("span", { className: "text-[12px] font-medium text-muted-foreground", children: s.pageNumber(index + 1) }),
8027
+ /* @__PURE__ */ jsx(ResultAt, { segment: String(index), children: /* @__PURE__ */ jsx(ResultField, { field: field.item, value: item, depth: depth + 1, hideLabel: true }) })
8028
+ ]
8029
+ },
8030
+ index
8031
+ )
8032
+ )) })
8033
+ ) : isApp && nativeVerdictOf(field.item) ? (
8034
+ // Verdicts in `app`, one per line, each drawn by the verdict arm.
8035
+ /* @__PURE__ */ jsx("div", { className: "divide-y divide-border/60 overflow-hidden rounded-lg border border-border", children: items.map((item, index) => /* @__PURE__ */ jsx("div", { className: "bg-card/40 px-3 py-1.5", children: /* @__PURE__ */ jsx(ResultAt, { segment: String(index), children: /* @__PURE__ */ jsx(ResultField, { field: field.item, value: item, depth: depth + 1, hideLabel: true }) }) }, index)) })
6570
8036
  ) : columns ? (
6571
8037
  // Same shape every row: the labels are column headers, not per-row
6572
8038
  // labels. See `ObjectTable`.
@@ -6623,7 +8089,7 @@ function ResultNode({ field, value, depth = 0, hideLabel = false }) {
6623
8089
  /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: header }),
6624
8090
  /* @__PURE__ */ jsx(CopyButton, { value: copyText, label: s.copyText })
6625
8091
  ] }),
6626
- /* @__PURE__ */ jsx(LeafValue, { field, value })
8092
+ isApp && field.kind === "text" && isLongText(unwrapped) ? /* @__PURE__ */ jsx(Markdown, { text: unwrapped }) : field.kind === "document" && whole ? /* @__PURE__ */ jsx(DocumentValue, { value: unwrapped, whole: true }) : /* @__PURE__ */ jsx(LeafValue, { field, value })
6627
8093
  ] });
6628
8094
  }
6629
8095
  return null;
@@ -6785,6 +8251,9 @@ function StuffPanel({
6785
8251
  const labels = { rendered: s.viewRendered, json: s.viewJson };
6786
8252
  const pdfName = page && pdfShown ? pdfFileName(field, value, baseName) : void 0;
6787
8253
  const pageView = page !== void 0 && view !== "json";
8254
+ const titled = presentation !== "app" || name !== void 0 && name !== "" && !page;
8255
+ const switchShown = offered.length > 1;
8256
+ const headerShown = titled || downloadShown || switchShown || page && pdfName !== void 0;
6788
8257
  return /* @__PURE__ */ jsxs(
6789
8258
  "div",
6790
8259
  {
@@ -6799,8 +8268,9 @@ function StuffPanel({
6799
8268
  className
6800
8269
  ),
6801
8270
  children: [
6802
- /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-wrap items-center justify-between gap-x-4 gap-y-1", children: [
6803
- page && presentation === "app" ? /* @__PURE__ */ jsx("div", {}) : /* @__PURE__ */ jsx("div", { className: "min-w-0 space-y-1", children: /* @__PURE__ */ jsx(ResultHeader, { field: named }) }),
8271
+ dialog,
8272
+ headerShown && /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-wrap items-center justify-between gap-x-4 gap-y-1", children: [
8273
+ titled ? /* @__PURE__ */ jsx("div", { className: "min-w-0 space-y-1", children: /* @__PURE__ */ jsx(ResultHeader, { field: named }) }) : /* @__PURE__ */ jsx("div", {}),
6804
8274
  /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [
6805
8275
  page && pdfName !== void 0 && /* @__PURE__ */ jsx(
6806
8276
  PdfDownloadButton,
@@ -6828,8 +8298,7 @@ function StuffPanel({
6828
8298
  ]
6829
8299
  }
6830
8300
  ),
6831
- dialog,
6832
- offered.length > 1 && /* @__PURE__ */ jsx(
8301
+ switchShown && /* @__PURE__ */ jsx(
6833
8302
  "div",
6834
8303
  {
6835
8304
  role: "group",
@@ -6870,7 +8339,7 @@ function StuffPanel({
6870
8339
  // `ResultField`, whose page arm would add a second control row saving
6871
8340
  // the same file, and with no box around it.
6872
8341
  /* @__PURE__ */ jsx(HtmlPreview, { content: page, downloadPdf: false, bare: true, fill: true })
6873
- ) : /* @__PURE__ */ jsx(ResultRoot, { baseName, path: [field.name], children: /* @__PURE__ */ jsx(ResultField, { field, value, hideLabel: true }) })
8342
+ ) : /* @__PURE__ */ jsx(ResultRoot, { baseName, path: [field.name], children: /* @__PURE__ */ jsx(PanelResult, { hostHeaded: !titled, children: /* @__PURE__ */ jsx(ResultField, { field, value, hideLabel: true }) }) })
6874
8343
  ]
6875
8344
  }
6876
8345
  );
@@ -6881,6 +8350,6 @@ function pdfFileName(field, value, baseName) {
6881
8350
  return name === void 0 ? "" : name.replace(/\.[^.]+$/, "");
6882
8351
  }
6883
8352
 
6884
- export { BooleanField, ConceptPill, DEFAULT_FIELD_STRINGS, DateField, DocumentField, EN_FIELD_STRINGS, EnumField, FIELD_STRINGS_BY_LOCALE, FR_FIELD_STRINGS, FieldDomIdProvider, FieldPresentationProvider, FieldRenderer, FieldShell, FieldStringsProvider, FilePicker, FilePickerEntry, FillWithExample, HtmlPreview, ImageField, JsonView, ListField, Markdown, MethodForm, NumberField, ObjectField, OptionalToggle, PdfDownloadButton, ProseField, ResultEnvProvider, ResultField, ResultRoot, SUPPORTED_LOCALES, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, StuffViewer, Switch, TextField, ToggleGroup, ToggleGroupItem, UnknownField, checkedAccentClass, cn, fieldControlClass, fieldStringsFor, focusOutlineClass, humanizeFieldName, linkTextClass, renderHtmlPdf, resolveHtmlStorageUrls, saveInBrowser, selectedBorderClass, selectedFillClass, selectedFillStrongClass, useFieldDomId, useFieldPresentation, useFieldStrings, useMethodForm, useProseImages, useResolveShareUrl, useResolveUrl, useResolvedUrl };
6885
- //# sourceMappingURL=chunk-UGKFWX7L.js.map
6886
- //# sourceMappingURL=chunk-UGKFWX7L.js.map
8353
+ export { BooleanField, ConceptPill, DEFAULT_FIELD_STRINGS, DateField, DocumentField, EN_FIELD_STRINGS, EnumField, FIELD_STRINGS_BY_LOCALE, FR_FIELD_STRINGS, FieldDomIdProvider, FieldPresentationProvider, FieldRenderer, FieldShell, FieldStringsProvider, FilePicker, FilePickerEntry, FillWithExample, HtmlPreview, ImageField, JsonView, ListField, Markdown, MethodForm, NumberField, ObjectField, OptionalToggle, PdfDownloadButton, ProseField, ResultEnvProvider, ResultField, ResultRoot, SUPPORTED_LOCALES, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, StuffViewer, Switch, TextField, ToggleGroup, ToggleGroupItem, UnknownField, checkedAccentClass, cn, fieldControlClass, fieldStringsFor, focusOutlineClass, humanizeFieldName, linkTextClass, renderHtmlPdf, resolveHtmlStorageUrls, saveInBrowser, selectedBorderClass, selectedFillClass, selectedFillStrongClass, useFieldDomId, useFieldPresentation, useFieldStrings, useMethodForm, useProseImages, useResolveRendition, useResolveShareUrl, useResolveUrl, useResolvedUrl };
8354
+ //# sourceMappingURL=chunk-RSYOZZZF.js.map
8355
+ //# sourceMappingURL=chunk-RSYOZZZF.js.map