{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "bounding-box-citations",
  "title": "Bounding Box Citations",
  "description": "An extraction citation panel connected to source bounding boxes and editable values.",
  "dependencies": [
    "@glideapps/glide-data-grid@6.0.4-alpha24",
    "@pierre/diffs@^1.1.22",
    "@base-ui/react@^1.4.1"
  ],
  "registryDependencies": [
    "utils",
    "button",
    "input",
    "scroll-area",
    "tabs",
    "tooltip"
  ],
  "files": [
    {
      "path": "components/extend/bounding-box-citations.tsx",
      "content": "\"use client\"\n\nimport { ScrollArea as ScrollAreaPrimitive } from \"@base-ui/react/scroll-area\"\nimport {\n  DataEditor,\n  emptyGridSelection,\n  GridCellKind,\n  TextCellEntry,\n  type EditableGridCell,\n  type GridCell,\n  type GridColumn,\n  type GridMouseEventArgs,\n  type GridSelection,\n  type Item,\n  type NumberCell,\n  type ProvideEditorComponent,\n  type Rectangle,\n  type TextCell,\n  type Theme,\n} from \"@glideapps/glide-data-grid\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n  ScrollArea as InlineScrollArea,\n  ScrollBar,\n} from \"@/components/ui/scroll-area\"\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\"\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\"\nimport { IconPlaceholder } from \"@/components/icon-placeholder\"\n\nimport \"@glideapps/glide-data-grid/dist/index.css\"\n\nimport * as React from \"react\"\nimport { Virtualizer as DiffsVirtualizer } from \"@pierre/diffs\"\nimport {\n  File,\n  MultiFileDiff,\n  VirtualizerContext,\n  WorkerPoolContextProvider,\n  type VirtualFileMetrics,\n  type WorkerInitializationRenderOptions,\n  type WorkerPoolOptions,\n} from \"@pierre/diffs/react\"\nimport { flushSync } from \"react-dom\"\n\nfunction InputNumericGlyph(props: InlineRegistryIconProps) {\n  return (\n    <IconPlaceholder\n      lucide=\"Hash\"\n      tabler=\"IconNumber123\"\n      hugeicons=\"InputNumericIcon\"\n      phosphor=\"NumpadIcon\"\n      remixicon=\"RiHashtag\"\n      {...props}\n    />\n  )\n}\nfunction InputTextGlyph(props: InlineRegistryIconProps) {\n  return (\n    <IconPlaceholder\n      lucide=\"TextCursorInput\"\n      tabler=\"IconForms\"\n      hugeicons=\"InputTextIcon\"\n      phosphor=\"TextboxIcon\"\n      remixicon=\"RiInputField\"\n      {...props}\n    />\n  )\n}\nfunction SecondBracketGlyph(props: InlineRegistryIconProps) {\n  return (\n    <IconPlaceholder\n      lucide=\"Brackets\"\n      tabler=\"IconBrackets\"\n      hugeicons=\"SecondBracketIcon\"\n      phosphor=\"BracketsSquareIcon\"\n      remixicon=\"RiBracketsLine\"\n      {...props}\n    />\n  )\n}\nfunction SourceCodeSquareGlyph(props: InlineRegistryIconProps) {\n  return (\n    <IconPlaceholder\n      lucide=\"SquareCode\"\n      tabler=\"IconSourceCode\"\n      hugeicons=\"SourceCodeSquareIcon\"\n      phosphor=\"CodeIcon\"\n      remixicon=\"RiCodeBlock\"\n      {...props}\n    />\n  )\n}\nfunction TextCheckGlyph(props: InlineRegistryIconProps) {\n  return (\n    <IconPlaceholder\n      lucide=\"CaptionsIcon\"\n      tabler=\"IconTextCaption\"\n      hugeicons=\"TextCheckIcon\"\n      phosphor=\"TextTIcon\"\n      remixicon=\"RiTextWrap\"\n      {...props}\n    />\n  )\n}\nexport type JsonPrimitive = string | number | boolean | null\nexport type JsonValue = JsonPrimitive | JsonObject | JsonArray\nexport type JsonObject = {\n  [key: string]: JsonValue\n}\nexport type JsonArray = JsonValue[]\nexport type SchemaPropertyType =\n  | \"string\"\n  | \"number\"\n  | \"integer\"\n  | \"boolean\"\n  | \"object\"\n  | \"array\"\nexport type ReviewFieldSchema = {\n  type: SchemaPropertyType\n  title?: string\n  description?: string\n  enum?: Array<string | number>\n  properties?: Record<string, ReviewFieldSchema>\n  items?: ReviewFieldSchema\n}\nexport type HighlightArea = {\n  left: number\n  top: number\n  width: number\n  height: number\n}\nexport type ReviewField = {\n  key: string\n  schema: ReviewFieldSchema\n  actual: JsonValue\n  expected: JsonValue\n  location?: ReviewLocation\n  metadataPath?: string\n}\nexport type ReviewLocation = {\n  page: number\n  area: HighlightArea\n}\nexport type ReviewCitation = {\n  page: number\n  polygon?: Array<{\n    x: number\n    y: number\n  }>\n  pageWidth: number\n  pageHeight: number\n}\nexport type ReviewMetadataEntry = {\n  citations?: ReviewCitation[]\n}\nfunction ScrollAreaVirtualizer({\n  children,\n  className,\n  contentClassName,\n  contentStyle,\n  scrollFade = true,\n}: {\n  children: React.ReactNode\n  className?: string\n  contentClassName?: string\n  contentStyle?: React.CSSProperties\n  scrollFade?: boolean\n}) {\n  const [virtualizer] = React.useState(() =>\n    typeof window !== \"undefined\" ? new DiffsVirtualizer() : undefined\n  )\n  const viewportRef = React.useRef<HTMLDivElement | null>(null)\n  const contentRef = React.useRef<HTMLDivElement | null>(null)\n  const syncVirtualizer = React.useCallback(() => {\n    if (!virtualizer) return\n    const viewport = viewportRef.current\n    const content = contentRef.current\n    if (viewport && content) {\n      virtualizer.setup(viewport, content)\n      return\n    }\n    virtualizer.cleanUp()\n  }, [virtualizer])\n  const setViewportRef = React.useCallback(\n    (node: HTMLDivElement | null) => {\n      viewportRef.current = node\n      syncVirtualizer()\n    },\n    [syncVirtualizer]\n  )\n  const setContentRef = React.useCallback(\n    (node: HTMLDivElement | null) => {\n      contentRef.current = node\n      syncVirtualizer()\n    },\n    [syncVirtualizer]\n  )\n  React.useEffect(() => {\n    return () => virtualizer?.cleanUp()\n  }, [virtualizer])\n  return (\n    <VirtualizerContext.Provider value={virtualizer}>\n      <InlineScrollArea2\n        className={className}\n        scrollFade={scrollFade}\n        scrollbarOverflowOnly\n        viewportRef={setViewportRef}\n      >\n        <div\n          ref={setContentRef}\n          className={contentClassName}\n          style={contentStyle}\n        >\n          {children}\n        </div>\n      </InlineScrollArea2>\n    </VirtualizerContext.Provider>\n  )\n}\nconst REVIEW_HIGHLIGHT_STYLE =\n  \"border-blue-500/70 bg-blue-500/12 shadow-[0_4px_16px_rgb(59_130_246_/_10%)]\"\nconst CODE_FILE_THEME = {\n  \"--diffs-light-bg\": \"var(--color-code)\",\n  \"--diffs-dark-bg\": \"var(--color-code)\",\n  \"--diffs-light\": \"var(--color-code-foreground)\",\n  \"--diffs-dark\": \"var(--color-code-foreground)\",\n  \"--diffs-bg-context-override\": \"var(--color-code)\",\n  \"--diffs-bg-context-gutter-override\": \"var(--color-code)\",\n  \"--diffs-bg-buffer-override\": \"var(--color-code)\",\n  \"--diffs-fg-number-override\": \"var(--color-muted-foreground)\",\n  \"--diffs-font-size\": \"0.8rem\",\n  \"--diffs-line-height\": \"1.625\",\n} as React.CSSProperties\nconst CODE_FONT_SIZE_PX = 12.8\nconst CODE_LINE_HEIGHT_PX = CODE_FONT_SIZE_PX * 1.625\nconst CODE_VIRTUAL_FILE_METRICS = {\n  hunkLineCount: 50,\n  lineHeight: CODE_LINE_HEIGHT_PX,\n  diffHeaderHeight: 44,\n  spacing: 8,\n  paddingTop: 0,\n  paddingBottom: 8,\n} satisfies VirtualFileMetrics\nconst CODE_HIGHLIGHTER_OPTIONS = {\n  theme: {\n    light: \"pierre-light-soft\",\n    dark: \"pierre-dark-soft\",\n  },\n  langs: [\"json\"],\n} satisfies WorkerInitializationRenderOptions\nconst CODE_WORKER_POOL_OPTIONS = {\n  workerFactory: () =>\n    new Worker(new URL(\"@pierre/diffs/worker/worker.js\", import.meta.url), {\n      type: \"module\",\n    }),\n} satisfies WorkerPoolOptions\nfunction readIsDarkTheme() {\n  return (\n    typeof document !== \"undefined\" &&\n    document.documentElement.classList.contains(\"dark\")\n  )\n}\n// A single shared MutationObserver backs every consumer. Each grid previously\n// created its own observer (two, via useHumanReviewGridTheme), so opening a\n// nested array view spun up and tore down several observers at once.\nconst darkThemeListeners = new Set<(isDark: boolean) => void>()\nlet darkThemeObserver: MutationObserver | null = null\nlet sharedIsDarkTheme = false\nfunction ensureDarkThemeObserver() {\n  if (\n    darkThemeObserver ||\n    typeof document === \"undefined\" ||\n    typeof MutationObserver === \"undefined\"\n  ) {\n    return\n  }\n  sharedIsDarkTheme = readIsDarkTheme()\n  darkThemeObserver = new MutationObserver(() => {\n    const nextIsDark = readIsDarkTheme()\n    if (nextIsDark === sharedIsDarkTheme) return\n    sharedIsDarkTheme = nextIsDark\n    darkThemeListeners.forEach((listener) => listener(nextIsDark))\n  })\n  darkThemeObserver.observe(document.documentElement, {\n    attributes: true,\n    attributeFilter: [\"class\"],\n  })\n}\nfunction subscribeToDarkTheme(listener: () => void) {\n  ensureDarkThemeObserver()\n  darkThemeListeners.add(listener)\n  return () => {\n    darkThemeListeners.delete(listener)\n    if (darkThemeListeners.size === 0 && darkThemeObserver) {\n      darkThemeObserver.disconnect()\n      darkThemeObserver = null\n    }\n  }\n}\nfunction useIsDarkTheme() {\n  return React.useSyncExternalStore(\n    subscribeToDarkTheme,\n    readIsDarkTheme,\n    () => false\n  )\n}\nfunction useHumanReviewGridTheme() {\n  const isDark = useIsDarkTheme()\n  return React.useMemo<Partial<Theme>>(\n    () => ({\n      accentColor: isDark ? \"rgb(96, 165, 250)\" : \"rgb(37, 99, 235)\",\n      accentLight: isDark ? \"rgba(29, 78, 216, 0.15)\" : \"rgb(219, 234, 254)\",\n      accentFg: \"rgb(255, 255, 255)\",\n      textDark: isDark ? \"rgb(229, 229, 229)\" : \"rgb(23, 23, 23)\",\n      textMedium: isDark ? \"rgb(163, 163, 163)\" : \"rgb(82, 82, 82)\",\n      textLight: isDark ? \"rgb(115, 115, 115)\" : \"rgb(163, 163, 163)\",\n      textBubble: isDark ? \"rgb(245, 245, 245)\" : \"rgb(23, 23, 23)\",\n      textHeader: isDark ? \"rgb(245, 245, 245)\" : \"rgb(23, 23, 23)\",\n      textGroupHeader: isDark ? \"rgb(163, 163, 163)\" : \"rgb(82, 82, 82)\",\n      bgCell: isDark ? \"rgb(10, 10, 10)\" : \"rgb(255, 255, 255)\",\n      bgCellMedium: isDark ? \"rgb(23, 23, 23)\" : \"rgb(250, 250, 250)\",\n      bgHeader: isDark ? \"rgb(23, 23, 23)\" : \"rgb(250, 250, 250)\",\n      bgHeaderHasFocus: isDark ? \"rgb(38, 38, 38)\" : \"rgb(245, 245, 245)\",\n      bgHeaderHovered: isDark ? \"rgb(38, 38, 38)\" : \"rgb(245, 245, 245)\",\n      borderColor: isDark ? \"rgb(38, 38, 38)\" : \"rgb(229, 229, 229)\",\n      horizontalBorderColor: isDark ? \"rgb(38, 38, 38)\" : \"rgb(229, 229, 229)\",\n      cellHorizontalPadding: 8,\n      cellVerticalPadding: 3,\n      headerIconSize: 18,\n      baseFontStyle: \"13px\",\n      headerFontStyle: \"600 13px\",\n      markerFontStyle: \"11px\",\n      fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n      editorFontSize: \"13px\",\n    }),\n    [isDark]\n  )\n}\nexport const REVIEW_FIELDS: ReviewField[] = [\n  {\n    key: \"statement_period\",\n    schema: {\n      type: \"string\",\n      title: \"Statement period\",\n      description: \"Date range covered by the bank statement.\",\n    },\n    actual: \"Jan 1-31, 2026\",\n    expected: \"January 1-31, 2026\",\n    location: {\n      page: 1,\n      area: { left: 31, top: 30, width: 40, height: 5.8 },\n    },\n  },\n  {\n    key: \"transactions\",\n    schema: {\n      type: \"array\",\n      title: \"Transactions\",\n      description: \"Posted account activity during the statement period.\",\n      items: {\n        type: \"object\",\n        properties: {\n          date: {\n            type: \"string\",\n            title: \"Date\",\n          },\n          description: {\n            type: \"string\",\n            title: \"Description\",\n          },\n          amount: {\n            type: \"number\",\n            title: \"Amount\",\n          },\n          category: {\n            type: \"string\",\n            title: \"Category\",\n          },\n          merchant: {\n            type: \"object\",\n            title: \"Merchant\",\n            properties: {\n              name: {\n                type: \"string\",\n                title: \"Name\",\n              },\n              city: {\n                type: \"string\",\n                title: \"City\",\n              },\n              risk_level: {\n                type: \"string\",\n                title: \"Risk level\",\n              },\n            },\n          },\n          tags: {\n            type: \"array\",\n            title: \"Tags\",\n            items: {\n              type: \"string\",\n              title: \"Tag\",\n            },\n          },\n        },\n      },\n    },\n    actual: [\n      {\n        date: \"2026-01-03\",\n        description: \"ACH CREDIT PAYROLL\",\n        amount: 4250,\n        category: \"Deposit\",\n        merchant: {\n          name: \"Acme Payroll\",\n          city: \"New York\",\n          risk_level: \"low\",\n        },\n        tags: [\"payroll\", \"recurring\"],\n      },\n      {\n        date: \"2026-01-12\",\n        description: \"POS PURCHASE GROCERY MART\",\n        amount: -86.42,\n        category: \"Debit\",\n        merchant: {\n          name: \"Grocery Mart\",\n          city: \"Brooklyn\",\n          risk_level: \"medium\",\n        },\n        tags: [\"card\", \"groceries\"],\n      },\n    ],\n    expected: [\n      {\n        date: \"2026-01-03\",\n        description: \"ACH CREDIT PAYROLL\",\n        amount: 4250,\n        category: \"Deposit\",\n        merchant: {\n          name: \"Acme Payroll\",\n          city: \"New York\",\n          risk_level: \"low\",\n        },\n        tags: [\"payroll\", \"recurring\"],\n      },\n      {\n        date: \"2026-01-12\",\n        description: \"POS PURCHASE GROCERY MART\",\n        amount: -68.42,\n        category: \"Debit\",\n        merchant: {\n          name: \"Grocery Mart\",\n          city: \"Brooklyn\",\n          risk_level: \"low\",\n        },\n        tags: [\"card\", \"groceries\", \"needs_review\"],\n      },\n    ],\n    location: {\n      page: 1,\n      area: { left: 13.5, top: 66, width: 73.5, height: 7.5 },\n    },\n  },\n  {\n    key: \"ending_balance\",\n    schema: {\n      type: \"number\",\n      title: \"Ending balance\",\n      description: \"Final account balance at the end of the statement period.\",\n    },\n    actual: 12840.18,\n    expected: 12858.18,\n    location: {\n      page: 1,\n      area: { left: 13.5, top: 66, width: 73.5, height: 7.5 },\n    },\n  },\n  {\n    key: \"overdraft_protection_enabled\",\n    schema: {\n      type: \"boolean\",\n      title: \"Overdraft protection enabled\",\n      description: \"Whether overdraft protection is enabled for the account.\",\n    },\n    actual: false,\n    expected: true,\n    location: {\n      page: 2,\n      area: { left: 9.5, top: 12, width: 81, height: 11.5 },\n    },\n  },\n  {\n    key: \"account_details\",\n    schema: {\n      type: \"object\",\n      title: \"Account details\",\n      description: \"Account owner and identifying details from the statement.\",\n      properties: {\n        holder_name: {\n          type: \"string\",\n          title: \"Holder name\",\n        },\n        account_last_four: {\n          type: \"string\",\n          title: \"Account last four\",\n        },\n        account_type: {\n          type: \"string\",\n          title: \"Account type\",\n        },\n        mailing_address: {\n          type: \"object\",\n          title: \"Mailing address\",\n          properties: {\n            line_1: {\n              type: \"string\",\n              title: \"Line 1\",\n            },\n            city: {\n              type: \"string\",\n              title: \"City\",\n            },\n            state: {\n              type: \"string\",\n              title: \"State\",\n            },\n          },\n        },\n        linked_accounts: {\n          type: \"array\",\n          title: \"Linked accounts\",\n          items: {\n            type: \"object\",\n            properties: {\n              nickname: {\n                type: \"string\",\n                title: \"Nickname\",\n              },\n              last_four: {\n                type: \"string\",\n                title: \"Last four\",\n              },\n            },\n          },\n        },\n      },\n    },\n    actual: {\n      holder_name: \"Jordan Lee\",\n      account_last_four: \"4821\",\n      account_type: \"Checking\",\n      mailing_address: {\n        line_1: \"42 Market Street\",\n        city: \"Brooklyn\",\n        state: \"NY\",\n      },\n      linked_accounts: [\n        {\n          nickname: \"Operations reserve\",\n          last_four: \"1842\",\n        },\n      ],\n    },\n    expected: {\n      holder_name: \"Jordan Lee\",\n      account_last_four: \"4821\",\n      account_type: \"Premier Checking\",\n      mailing_address: {\n        line_1: \"42 Market Street\",\n        city: \"New York\",\n        state: \"NY\",\n      },\n      linked_accounts: [\n        {\n          nickname: \"Operations reserve\",\n          last_four: \"1842\",\n        },\n        {\n          nickname: \"Payroll sweep\",\n          last_four: \"9174\",\n        },\n      ],\n    },\n  },\n]\nfunction getCitationLocation(\n  citation: ReviewCitation\n): ReviewLocation | undefined {\n  const polygon = citation.polygon\n  if (!polygon?.length || !citation.pageWidth || !citation.pageHeight) {\n    return undefined\n  }\n  const xs = polygon.map((point) => point.x)\n  const ys = polygon.map((point) => point.y)\n  const left = Math.min(...xs)\n  const top = Math.min(...ys)\n  const right = Math.max(...xs)\n  const bottom = Math.max(...ys)\n  return {\n    page: citation.page,\n    area: {\n      left: (left / citation.pageWidth) * 100,\n      top: (top / citation.pageHeight) * 100,\n      width: ((right - left) / citation.pageWidth) * 100,\n      height: ((bottom - top) / citation.pageHeight) * 100,\n    },\n  }\n}\nexport function getMetadataLocation(\n  metadata: Record<string, ReviewMetadataEntry> | undefined,\n  metadataPath: string | undefined\n) {\n  if (!metadata || !metadataPath) return undefined\n  const citation = metadata[metadataPath]?.citations?.find(\n    (candidate) => candidate.polygon?.length\n  )\n  return citation ? getCitationLocation(citation) : undefined\n}\nexport function getReviewFieldLocation(\n  field: ReviewField | undefined,\n  resolveLocation?: (metadataPath: string) => ReviewLocation | undefined\n) {\n  if (!field) return undefined\n  return (\n    field.location ??\n    resolveLocation?.(field.metadataPath ?? field.key) ??\n    undefined\n  )\n}\nexport function getReviewLocationKey(location: ReviewLocation | undefined) {\n  if (!location) return null\n  const { area } = location\n  return [location.page, area.left, area.top, area.width, area.height].join(\":\")\n}\nfunction valuesFromFields(\n  fields: ReviewField[],\n  valueKey: \"actual\" | \"expected\"\n) {\n  return fields.reduce<JsonObject>((values, field) => {\n    values[field.key] = field[valueKey]\n    return values\n  }, {})\n}\nfunction formatJson(value: unknown) {\n  return JSON.stringify(value, null, 2)\n}\nfunction isJsonObject(value: JsonValue): value is JsonObject {\n  return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\nfunction isJsonArray(value: JsonValue): value is JsonArray {\n  return Array.isArray(value)\n}\nfunction getObjectValue(value: JsonValue, key: string): JsonValue {\n  if (!isJsonObject(value)) return null\n  return value[key] ?? null\n}\nfunction setObjectValue(\n  value: JsonValue,\n  key: string,\n  childValue: JsonValue\n): JsonObject {\n  return {\n    ...(isJsonObject(value) ? value : {}),\n    [key]: childValue,\n  }\n}\nfunction getArrayValue(value: JsonValue): JsonArray {\n  return isJsonArray(value) ? value : []\n}\nfunction setArrayItemValue(\n  value: JsonValue,\n  index: number,\n  childValue: JsonValue\n): JsonArray {\n  const nextValue = getArrayValue(value).slice()\n  nextValue[index] = childValue\n  return nextValue\n}\nfunction getPrimitiveValue(value: JsonValue): JsonPrimitive {\n  return isJsonObject(value) || isJsonArray(value) ? null : value\n}\nfunction jsonValuesEqual(left: JsonValue, right: JsonValue) {\n  return formatJson(left) === formatJson(right)\n}\nexport function findReviewField(\n  fields: ReviewField[],\n  fieldKey: string | undefined\n): ReviewField | undefined {\n  if (!fieldKey) return undefined\n  for (const field of fields) {\n    if (field.key === fieldKey) return field\n    if (field.schema.type === \"object\") {\n      const childFields = Object.entries(field.schema.properties ?? {}).map(\n        ([key, schema]): ReviewField => ({\n          key: `${field.key}.${key}`,\n          schema,\n          actual: getObjectValue(field.actual, key),\n          expected: getObjectValue(field.expected, key),\n          metadataPath: `${field.metadataPath ?? field.key}.${key}`,\n        })\n      )\n      const childField = findReviewField(childFields, fieldKey)\n      if (childField) return childField\n    }\n  }\n  return undefined\n}\nfunction formatValue(value: JsonValue) {\n  if (value === null) return \"NULL\"\n  if (isJsonObject(value) || isJsonArray(value)) return formatJson(value)\n  if (typeof value === \"boolean\") return value ? \"true\" : \"false\"\n  return String(value)\n}\nfunction areGridRangesEqual(\n  left: Readonly<Rectangle> | undefined,\n  right: Readonly<Rectangle> | undefined\n) {\n  return (\n    left === right ||\n    (left !== undefined &&\n      right !== undefined &&\n      left.x === right.x &&\n      left.y === right.y &&\n      left.width === right.width &&\n      left.height === right.height)\n  )\n}\nfunction areGridRangeStacksEqual(\n  left: readonly Readonly<Rectangle>[] | undefined,\n  right: readonly Readonly<Rectangle>[] | undefined\n) {\n  if (left === right) return true\n  if (!left || !right || left.length !== right.length) return false\n  return left.every((range, index) => areGridRangesEqual(range, right[index]))\n}\nfunction areGridSelectionsEqual(left: GridSelection, right: GridSelection) {\n  const leftCurrent = left.current\n  const rightCurrent = right.current\n  return (\n    leftCurrent?.cell[0] === rightCurrent?.cell[0] &&\n    leftCurrent?.cell[1] === rightCurrent?.cell[1] &&\n    areGridRangesEqual(leftCurrent?.range, rightCurrent?.range) &&\n    areGridRangeStacksEqual(\n      leftCurrent?.rangeStack,\n      rightCurrent?.rangeStack\n    ) &&\n    left.columns.equals(right.columns) &&\n    left.rows.equals(right.rows)\n  )\n}\nfunction getGridSelectionRanges(selection: GridSelection | undefined) {\n  const current = selection?.current\n  if (!current) return []\n  return [...(current.rangeStack ?? []), current.range]\n}\nfunction areArrayNestedViewsEqual(\n  left: ArrayNestedView[],\n  right: ArrayNestedView[]\n) {\n  if (left === right) return true\n  if (left.length !== right.length) return false\n  return left.every((view, index) => {\n    const other = right[index]\n    return (\n      view.rowIndex === other?.rowIndex &&\n      view.columnId === other.columnId &&\n      view.title === other.title &&\n      view.schema === other.schema &&\n      Object.is(view.value, other.value)\n    )\n  })\n}\ntype HumanReviewOverlayCell = TextCell | NumberCell\ntype HumanReviewTextOverlayEditorProps = React.ComponentProps<\n  ProvideEditorComponent<HumanReviewOverlayCell>\n> & {\n  overlayOpenRef: React.RefObject<boolean>\n  readOnly?: boolean\n}\nfunction HumanReviewTextOverlayEditor({\n  isHighlighted,\n  onFinishedEditing,\n  overlayOpenRef,\n  readOnly = false,\n  validatedSelection,\n  value,\n}: HumanReviewTextOverlayEditorProps) {\n  const initialValue =\n    value.kind === GridCellKind.Number ? value.displayData : value.data\n  const [entryValue, setEntryValue] = React.useState(initialValue)\n  const latestValueRef = React.useRef(initialValue)\n  const finishedRef = React.useRef(false)\n  const finishEditing = React.useCallback(\n    (\n      shouldSave: boolean,\n      movement: readonly [-1 | 0 | 1, -1 | 0 | 1] = [0, 0]\n    ) => {\n      if (finishedRef.current) return\n      finishedRef.current = true\n      overlayOpenRef.current = false\n      if (!shouldSave || readOnly) {\n        onFinishedEditing(undefined, movement)\n        return\n      }\n      if (value.kind === GridCellKind.Number) {\n        const numericValue = Number(latestValueRef.current)\n        onFinishedEditing(\n          {\n            ...value,\n            data: Number.isFinite(numericValue) ? numericValue : value.data,\n            displayData: latestValueRef.current,\n          },\n          movement\n        )\n        return\n      }\n      onFinishedEditing(\n        {\n          ...value,\n          data: latestValueRef.current,\n          displayData: latestValueRef.current,\n        },\n        movement\n      )\n    },\n    [onFinishedEditing, overlayOpenRef, readOnly, value]\n  )\n  const handleEntryChange = React.useCallback(\n    (event: React.ChangeEvent<HTMLTextAreaElement>) => {\n      event.stopPropagation()\n      latestValueRef.current = event.target.value\n      setEntryValue(event.target.value)\n    },\n    []\n  )\n  const handleKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n      event.stopPropagation()\n      if (event.key === \"Escape\") {\n        event.preventDefault()\n        finishEditing(false)\n        return\n      }\n      if (event.key === \"Tab\") {\n        event.preventDefault()\n        finishEditing(true, [event.shiftKey ? -1 : 1, 0])\n        return\n      }\n      if (event.key === \"Enter\" && !event.shiftKey) {\n        event.preventDefault()\n        finishEditing(true, [0, 1])\n      }\n    },\n    [finishEditing]\n  )\n  React.useEffect(() => {\n    overlayOpenRef.current = true\n    return () => {\n      overlayOpenRef.current = false\n    }\n  }, [overlayOpenRef])\n  React.useEffect(() => {\n    const handlePointerOutside = (event: PointerEvent | MouseEvent) => {\n      const input = document.querySelector<HTMLTextAreaElement>(\".gdg-input\")\n      const overlayRoot = input?.closest(\".gdg-clip-region\")\n      if (!overlayRoot || overlayRoot.contains(event.target as Node | null)) {\n        return\n      }\n      finishEditing(true)\n    }\n    document.addEventListener(\"pointerdown\", handlePointerOutside, true)\n    document.addEventListener(\"contextmenu\", handlePointerOutside, true)\n    return () => {\n      document.removeEventListener(\"pointerdown\", handlePointerOutside, true)\n      document.removeEventListener(\"contextmenu\", handlePointerOutside, true)\n    }\n  }, [finishEditing])\n  return (\n    <TextCellEntry\n      autoFocus={!readOnly}\n      disabled={readOnly}\n      highlight={isHighlighted}\n      value={entryValue}\n      validatedSelection={validatedSelection}\n      altNewline\n      onChange={handleEntryChange}\n      onKeyDown={handleKeyDown}\n    />\n  )\n}\nfunction getFieldIcon(type: SchemaPropertyType) {\n  if (type === \"number\" || type === \"integer\") return InputNumericGlyph\n  if (type === \"boolean\") return TextCheckGlyph\n  if (type === \"array\") return SecondBracketGlyph\n  if (type === \"object\") return SourceCodeSquareGlyph\n  return InputTextGlyph\n}\nfunction HumanReviewValueInput({\n  readOnly = false,\n  schema,\n  value,\n  onChange,\n}: {\n  readOnly?: boolean\n  schema: ReviewFieldSchema\n  value: JsonPrimitive\n  onChange: (value: JsonPrimitive) => void\n}) {\n  if (schema.enum?.length) {\n    return (\n      <span className=\"relative inline-flex w-full rounded-lg border border-input bg-background text-sm text-foreground shadow-xs/5 dark:bg-input/32\">\n        <select\n          disabled={readOnly}\n          value={value === null ? \"\" : String(value)}\n          onChange={(event) => onChange(event.target.value)}\n          className=\"h-8.5 w-full appearance-none rounded-[inherit] bg-transparent px-3 text-sm outline-none sm:h-7.5\"\n        >\n          {schema.enum.map((option) => (\n            <option key={String(option)} value={String(option)}>\n              {String(option)}\n            </option>\n          ))}\n        </select>\n      </span>\n    )\n  }\n  if (schema.type === \"number\" || schema.type === \"integer\") {\n    return (\n      <Input\n        readOnly={readOnly}\n        type=\"number\"\n        value={value === null ? \"\" : String(value)}\n        onChange={(event) => {\n          const nextValue = event.currentTarget.value\n          onChange(nextValue === \"\" ? null : Number(nextValue))\n        }}\n      />\n    )\n  }\n  if (schema.type === \"boolean\") {\n    return (\n      <div className=\"grid grid-cols-2 gap-1 rounded-lg bg-muted p-0.5\">\n        {[true, false].map((option) => (\n          <Button\n            key={String(option)}\n            type=\"button\"\n            size=\"sm\"\n            variant={value === option ? \"outline\" : \"ghost\"}\n            className={cn(\n              \"h-7 shadow-none\",\n              value === option && \"bg-background dark:bg-input\"\n            )}\n            disabled={readOnly}\n            onClick={() => onChange(option)}\n          >\n            {option ? \"True\" : \"False\"}\n          </Button>\n        ))}\n      </div>\n    )\n  }\n  return (\n    <Input\n      readOnly={readOnly}\n      value={value === null ? \"\" : String(value)}\n      onChange={(event) => onChange(event.currentTarget.value)}\n    />\n  )\n}\nfunction getArrayItemSchema(schema: ReviewFieldSchema): ReviewFieldSchema {\n  return schema.items ?? { type: \"string\" }\n}\nfunction isComplexSchema(schema: ReviewFieldSchema) {\n  return schema.type === \"object\" || schema.type === \"array\"\n}\nfunction summarizeComplexValue(value: JsonValue) {\n  if (isJsonArray(value)) return `${value.length} items`\n  if (isJsonObject(value)) return `${Object.keys(value).length} fields`\n  return formatValue(value)\n}\nfunction getCellValueForArrayColumn(\n  rowValue: JsonValue,\n  itemSchema: ReviewFieldSchema,\n  columnId: string\n) {\n  if (itemSchema.type === \"object\") {\n    return getObjectValue(rowValue, columnId)\n  }\n  return rowValue\n}\nfunction getCellSchemaForArrayColumn(\n  itemSchema: ReviewFieldSchema,\n  columnId: string\n) {\n  if (itemSchema.type === \"object\") {\n    return itemSchema.properties?.[columnId] ?? { type: \"string\" }\n  }\n  return itemSchema\n}\nfunction applyPrimitiveEdit(\n  schema: ReviewFieldSchema,\n  value: EditableGridCell\n): JsonValue | undefined {\n  if (schema.type === \"boolean\" && value.kind === GridCellKind.Boolean) {\n    return value.data\n  }\n  if (\n    (schema.type === \"number\" || schema.type === \"integer\") &&\n    value.kind === GridCellKind.Number\n  ) {\n    return value.data ?? null\n  }\n  if (value.kind === GridCellKind.Text) {\n    if (schema.type === \"number\" || schema.type === \"integer\") {\n      return value.data.trim() === \"\" ? null : Number(value.data)\n    }\n    return value.data\n  }\n  return undefined\n}\ntype ArrayNestedView = {\n  rowIndex: number\n  columnId: string\n  title: string\n  schema: ReviewFieldSchema\n  value: JsonValue\n}\ntype ArrayReviewSide = \"actual\" | \"expected\"\ntype SyncedArrayNestedView = {\n  activeSide: ArrayReviewSide | null\n  stack: ArrayNestedView[]\n}\ntype SyncedArraySelection = {\n  activeSide: ArrayReviewSide | null\n  depth: number\n  gridSelection: GridSelection\n}\nexport type HumanReviewTheme = \"light\" | \"dark\"\nconst EMPTY_SYNCED_ARRAY_NESTED_VIEW: SyncedArrayNestedView = {\n  activeSide: null,\n  stack: [],\n}\nconst EMPTY_SYNCED_ARRAY_SELECTION: SyncedArraySelection = {\n  activeSide: null,\n  depth: 0,\n  gridSelection: emptyGridSelection,\n}\nfunction setNestedArrayValue({\n  value,\n  schema,\n  nestedStack,\n  nextNestedValue,\n}: {\n  value: JsonValue\n  schema: ReviewFieldSchema\n  nestedStack: ArrayNestedView[]\n  nextNestedValue: JsonValue\n}): JsonValue {\n  const [currentView, ...remainingViews] = nestedStack\n  if (!currentView) return nextNestedValue\n  const itemSchema = getArrayItemSchema(schema)\n  const rowValue = getArrayValue(value)[currentView.rowIndex] ?? null\n  const cellSchema = getCellSchemaForArrayColumn(\n    itemSchema,\n    currentView.columnId\n  )\n  const currentCellValue = getCellValueForArrayColumn(\n    rowValue,\n    itemSchema,\n    currentView.columnId\n  )\n  const nextCellValue: JsonValue = remainingViews.length\n    ? setNestedArrayValue({\n        value: currentCellValue,\n        schema: cellSchema,\n        nestedStack: remainingViews,\n        nextNestedValue,\n      })\n    : nextNestedValue\n  const nextRowValue: JsonValue =\n    itemSchema.type === \"object\"\n      ? setObjectValue(rowValue, currentView.columnId, nextCellValue)\n      : nextCellValue\n  return setArrayItemValue(value, currentView.rowIndex, nextRowValue)\n}\nfunction getNestedArrayValue({\n  value,\n  schema,\n  nestedStack,\n}: {\n  value: JsonValue\n  schema: ReviewFieldSchema\n  nestedStack: ArrayNestedView[]\n}): JsonValue {\n  const [currentView, ...remainingViews] = nestedStack\n  if (!currentView) return value\n  const itemSchema = getArrayItemSchema(schema)\n  const rowValue = getArrayValue(value)[currentView.rowIndex] ?? null\n  const cellSchema = getCellSchemaForArrayColumn(\n    itemSchema,\n    currentView.columnId\n  )\n  const cellValue = getCellValueForArrayColumn(\n    rowValue,\n    itemSchema,\n    currentView.columnId\n  )\n  if (!remainingViews.length) return cellValue\n  return getNestedArrayValue({\n    value: cellValue,\n    schema: cellSchema,\n    nestedStack: remainingViews,\n  })\n}\nfunction HumanReviewArrayValueGrid({\n  activeNestedSide = null,\n  activeSelectionSide = null,\n  label,\n  nestedStackBaseDepth = 0,\n  readOnly = false,\n  schema,\n  selectionDepth = 0,\n  sharedGridSelection,\n  sharedNestedStack,\n  value,\n  viewSide = \"expected\",\n  metadataPath,\n  onChange,\n  onGridSelectionChange,\n  onLocationHover,\n  onNestedStackChange,\n  resolveArrayItemMetadataPath,\n  resolveLocation,\n}: {\n  activeNestedSide?: ArrayReviewSide | null\n  activeSelectionSide?: ArrayReviewSide | null\n  label: string\n  nestedStackBaseDepth?: number\n  readOnly?: boolean\n  schema: ReviewFieldSchema\n  selectionDepth?: number\n  sharedGridSelection?: GridSelection\n  sharedNestedStack?: ArrayNestedView[]\n  value: JsonValue\n  viewSide?: ArrayReviewSide\n  metadataPath?: string\n  onChange?: (value: JsonValue) => void\n  onGridSelectionChange?: (\n    selection: GridSelection,\n    side: ArrayReviewSide,\n    depth: number\n  ) => void\n  onNestedStackChange?: (\n    stack: ArrayNestedView[],\n    side: ArrayReviewSide\n  ) => void\n  onLocationHover?: (location?: ReviewLocation) => void\n  resolveArrayItemMetadataPath?: (\n    metadataPath: string,\n    rowIndex: number,\n    rowValue: JsonValue\n  ) => string | undefined\n  resolveLocation?: (metadataPath: string) => ReviewLocation | undefined\n}) {\n  const rows = getArrayValue(value)\n  const itemSchema = getArrayItemSchema(schema)\n  const gridTheme = useHumanReviewGridTheme()\n  const isDark = useIsDarkTheme()\n  const [localNestedStack, setLocalNestedStack] = React.useState<\n    ArrayNestedView[]\n  >([])\n  const [localGridSelection, setLocalGridSelection] =\n    React.useState<GridSelection>(emptyGridSelection)\n  const fastTextOverlayOpenRef = React.useRef(false)\n  const nestedStack = sharedNestedStack ?? localNestedStack\n  const visibleNestedStack = nestedStack.slice(nestedStackBaseDepth)\n  const activeNestedView = visibleNestedStack[0] ?? null\n  const activeNestedValue = activeNestedView\n    ? getNestedArrayValue({\n        value,\n        schema,\n        nestedStack: [activeNestedView],\n      })\n    : null\n  const isActiveNestedSource =\n    Boolean(activeNestedView) && activeNestedSide === viewSide\n  const isMirroredNestedTarget =\n    Boolean(activeNestedView) &&\n    activeNestedSide !== null &&\n    activeNestedSide !== viewSide\n  const blueCellText = isDark ? \"rgb(147, 197, 253)\" : \"rgb(37, 99, 235)\"\n  const selectedCellBackground = isDark\n    ? \"rgba(37, 99, 235, 0.2)\"\n    : \"rgba(219, 234, 254, 0.85)\"\n  const mirroredCellBackground = isDark\n    ? \"rgba(167, 139, 250, 0.18)\"\n    : \"rgba(237, 233, 254, 0.9)\"\n  const mirroredHighlightRegions = React.useMemo<\n    React.ComponentProps<typeof DataEditor>[\"highlightRegions\"]\n  >(() => {\n    if (\n      !activeSelectionSide ||\n      activeSelectionSide === viewSide ||\n      selectionDepth !== nestedStackBaseDepth\n    ) {\n      return undefined\n    }\n    const ranges = getGridSelectionRanges(sharedGridSelection)\n    if (!ranges.length) return undefined\n    return ranges.map((range) => ({\n      color: mirroredCellBackground,\n      range,\n      style: \"dashed\" as const,\n    }))\n  }, [\n    activeSelectionSide,\n    mirroredCellBackground,\n    nestedStackBaseDepth,\n    selectionDepth,\n    sharedGridSelection,\n    viewSide,\n  ])\n  const setNestedStack = React.useCallback(\n    (\n      updater:\n        | ArrayNestedView[]\n        | ((current: ArrayNestedView[]) => ArrayNestedView[])\n    ) => {\n      if (onNestedStackChange) {\n        const nextStack =\n          typeof updater === \"function\" ? updater(nestedStack) : updater\n        onNestedStackChange(nextStack, viewSide)\n        return\n      }\n      setLocalNestedStack(updater)\n    },\n    [nestedStack, onNestedStackChange, viewSide]\n  )\n  const handleGridSelectionChange = React.useCallback(\n    (selection: GridSelection) => {\n      flushSync(() => {\n        setLocalGridSelection((current) =>\n          areGridSelectionsEqual(current, selection) ? current : selection\n        )\n      })\n      if (onGridSelectionChange) {\n        if (\n          activeSelectionSide === viewSide &&\n          sharedGridSelection &&\n          areGridSelectionsEqual(sharedGridSelection, selection)\n        ) {\n          return\n        }\n        React.startTransition(() => {\n          onGridSelectionChange(selection, viewSide, nestedStackBaseDepth)\n        })\n        return\n      }\n    },\n    [\n      activeSelectionSide,\n      nestedStackBaseDepth,\n      onGridSelectionChange,\n      sharedGridSelection,\n      viewSide,\n    ]\n  )\n  const columns = React.useMemo<GridColumn[]>(() => {\n    if (itemSchema.type === \"object\") {\n      const propertyEntries = Object.entries(itemSchema.properties ?? {})\n      if (propertyEntries.length) {\n        return propertyEntries.map(([key, propertySchema]) => ({\n          id: key,\n          title: propertySchema.title ?? key,\n          width: isComplexSchema(propertySchema) ? 148 : 132,\n        }))\n      }\n    }\n    return [\n      {\n        id: \"value\",\n        title: itemSchema.title ?? \"Value\",\n        width: isComplexSchema(itemSchema) ? 148 : 180,\n      },\n    ]\n  }, [itemSchema])\n  const getCellContent = React.useCallback(\n    ([col, row]: Item): GridCell => {\n      const column = columns[col]\n      const columnId = String(column?.id ?? \"value\")\n      const rowValue = rows[row] ?? null\n      const cellSchema = getCellSchemaForArrayColumn(itemSchema, columnId)\n      const cellValue = getCellValueForArrayColumn(\n        rowValue,\n        itemSchema,\n        columnId\n      )\n      const matchedNestedCell =\n        activeNestedView?.rowIndex === row &&\n        activeNestedView.columnId === columnId\n      const nestedCellTheme: Partial<Theme> | undefined = matchedNestedCell\n        ? {\n            bgCell: isMirroredNestedTarget\n              ? mirroredCellBackground\n              : selectedCellBackground,\n            textDark: blueCellText,\n          }\n        : undefined\n      if (isComplexSchema(cellSchema)) {\n        return {\n          kind: GridCellKind.Text,\n          data: summarizeComplexValue(cellValue),\n          displayData: summarizeComplexValue(cellValue),\n          allowOverlay: false,\n          readonly: true,\n          cursor: \"pointer\",\n          activationBehaviorOverride: \"double-click\",\n          themeOverride: {\n            textDark: blueCellText,\n            ...(nestedCellTheme ?? {}),\n          },\n        }\n      }\n      if (cellSchema.type === \"boolean\") {\n        return {\n          kind: GridCellKind.Boolean,\n          data: typeof cellValue === \"boolean\" ? cellValue : false,\n          allowOverlay: false,\n          readonly: readOnly,\n        }\n      }\n      if (cellSchema.type === \"number\" || cellSchema.type === \"integer\") {\n        return {\n          kind: GridCellKind.Number,\n          data: typeof cellValue === \"number\" ? cellValue : undefined,\n          displayData: typeof cellValue === \"number\" ? String(cellValue) : \"\",\n          allowOverlay: true,\n          readonly: false,\n        }\n      }\n      return {\n        kind: GridCellKind.Text,\n        data:\n          cellValue === null ||\n          isJsonObject(cellValue) ||\n          isJsonArray(cellValue)\n            ? \"\"\n            : String(cellValue),\n        displayData:\n          cellValue === null ||\n          isJsonObject(cellValue) ||\n          isJsonArray(cellValue)\n            ? \"\"\n            : String(cellValue),\n        allowOverlay: true,\n        readonly: false,\n      }\n    },\n    [\n      activeNestedView,\n      blueCellText,\n      columns,\n      isMirroredNestedTarget,\n      itemSchema,\n      mirroredCellBackground,\n      readOnly,\n      rows,\n      selectedCellBackground,\n    ]\n  )\n  const updateCellValue = React.useCallback(\n    ([col, row]: Item, nextCell: EditableGridCell) => {\n      if (readOnly || !onChange) return\n      const column = columns[col]\n      const columnId = String(column?.id ?? \"value\")\n      const rowValue = rows[row] ?? null\n      const cellSchema = getCellSchemaForArrayColumn(itemSchema, columnId)\n      const nextValue = applyPrimitiveEdit(cellSchema, nextCell)\n      if (nextValue === undefined) return\n      const nextRowValue =\n        itemSchema.type === \"object\"\n          ? setObjectValue(rowValue, columnId, nextValue)\n          : nextValue\n      onChange(setArrayItemValue(value, row, nextRowValue))\n    },\n    [columns, itemSchema, onChange, readOnly, rows, value]\n  )\n  const provideEditor = React.useCallback<\n    NonNullable<React.ComponentProps<typeof DataEditor>[\"provideEditor\"]>\n  >(\n    (cell) => {\n      if (\n        cell.kind !== GridCellKind.Text &&\n        cell.kind !== GridCellKind.Number\n      ) {\n        return undefined\n      }\n      return {\n        editor: (props) => {\n          if (\n            props.value.kind !== GridCellKind.Text &&\n            props.value.kind !== GridCellKind.Number\n          ) {\n            return null\n          }\n          return (\n            <HumanReviewTextOverlayEditor\n              {...(props as React.ComponentProps<\n                ProvideEditorComponent<HumanReviewOverlayCell>\n              >)}\n              overlayOpenRef={fastTextOverlayOpenRef}\n              readOnly={readOnly}\n            />\n          )\n        },\n      }\n    },\n    [readOnly]\n  )\n  const handleOutsideClick = React.useCallback(\n    () => !fastTextOverlayOpenRef.current,\n    []\n  )\n  const handleItemHovered = React.useCallback(\n    (args: GridMouseEventArgs) => {\n      if (!onLocationHover || !resolveLocation || !metadataPath) return\n      if (args.kind !== \"cell\") {\n        onLocationHover(undefined)\n        return\n      }\n      const [col, row] = args.location\n      const column = columns[col]\n      const rowValue = rows[row]\n      if (!column || rowValue === undefined) {\n        onLocationHover(undefined)\n        return\n      }\n      const columnId = String(column.id ?? \"value\")\n      const rowMetadataPath = resolveArrayItemMetadataPath\n        ? resolveArrayItemMetadataPath(metadataPath, row, rowValue)\n        : `${metadataPath}[${row}]`\n      if (!rowMetadataPath) {\n        onLocationHover(undefined)\n        return\n      }\n      const propertyMetadataPath =\n        itemSchema.type === \"object\"\n          ? `${rowMetadataPath}.${columnId}`\n          : rowMetadataPath\n      onLocationHover(\n        resolveLocation(propertyMetadataPath) ??\n          resolveLocation(rowMetadataPath)\n      )\n    },\n    [\n      columns,\n      itemSchema.type,\n      metadataPath,\n      onLocationHover,\n      resolveArrayItemMetadataPath,\n      resolveLocation,\n      rows,\n    ]\n  )\n  const openNestedCell = React.useCallback(\n    ([col, row]: Item) => {\n      const column = columns[col]\n      const columnId = String(column?.id ?? \"value\")\n      const rowValue = rows[row] ?? null\n      const cellSchema = getCellSchemaForArrayColumn(itemSchema, columnId)\n      if (!isComplexSchema(cellSchema)) return\n      setNestedStack((current) => {\n        const nextView = {\n          rowIndex: row,\n          columnId,\n          title: `${column?.title ?? columnId} / row ${row + 1}`,\n          schema: cellSchema,\n          value: getCellValueForArrayColumn(rowValue, itemSchema, columnId),\n        }\n        const currentView = current[nestedStackBaseDepth]\n        if (\n          currentView?.rowIndex === nextView.rowIndex &&\n          currentView.columnId === nextView.columnId\n        ) {\n          return current\n        }\n        return [...current.slice(0, nestedStackBaseDepth), nextView]\n      })\n    },\n    [columns, itemSchema, nestedStackBaseDepth, rows, setNestedStack]\n  )\n  const updateNestedValue = React.useCallback(\n    (nextNestedValue: JsonValue) => {\n      if (!activeNestedView || readOnly || !onChange) return\n      onChange(\n        setNestedArrayValue({\n          value,\n          schema,\n          nestedStack: visibleNestedStack.slice(0, 1),\n          nextNestedValue,\n        })\n      )\n      setNestedStack((current) =>\n        current.map((view, index) =>\n          index === nestedStackBaseDepth\n            ? { ...view, value: nextNestedValue }\n            : view\n        )\n      )\n    },\n    [\n      activeNestedView,\n      nestedStackBaseDepth,\n      onChange,\n      readOnly,\n      schema,\n      setNestedStack,\n      value,\n      visibleNestedStack,\n    ]\n  )\n  return (\n    <div\n      onMouseLeave={() => onLocationHover?.(undefined)}\n      className={cn(\n        \"relative overflow-hidden rounded-md border bg-background transition-[border-color,background-color,box-shadow] focus-within:border-blue-500/50 focus-within:shadow-[0_0_0_1px_rgb(59_130_246_/_8%)] hover:border-blue-500/50\",\n        isActiveNestedSource &&\n          \"border-blue-500/60 bg-blue-500/5 shadow-[0_0_0_1px_rgb(59_130_246_/_10%)]\"\n      )}\n    >\n      <div>\n        <div className=\"flex h-8 items-center justify-between gap-2 border-b px-2 text-[11px] font-medium text-muted-foreground\">\n          <span>{label}</span>\n          <span>{rows.length} rows</span>\n        </div>\n        <div className=\"h-[220px]\">\n          <DataEditor\n            columns={columns}\n            rows={rows.length}\n            getCellContent={getCellContent}\n            cellActivationBehavior=\"double-click\"\n            gridSelection={localGridSelection}\n            highlightRegions={mirroredHighlightRegions}\n            onCellEdited={updateCellValue}\n            onCellActivated={openNestedCell}\n            onGridSelectionChange={handleGridSelectionChange}\n            onItemHovered={handleItemHovered}\n            provideEditor={provideEditor}\n            isOutsideClick={handleOutsideClick}\n            rowMarkers=\"number\"\n            smoothScrollX\n            smoothScrollY\n            theme={gridTheme}\n            width=\"100%\"\n            height=\"100%\"\n            rowHeight={32}\n            headerHeight={34}\n          />\n        </div>\n      </div>\n      {activeNestedView ? (\n        <div className=\"absolute inset-0 z-10 flex flex-col bg-background\">\n          <div className=\"flex h-8 items-center gap-2 border-b px-2\">\n            <Button\n              type=\"button\"\n              variant=\"ghost\"\n              size=\"icon-sm\"\n              className=\"size-6 text-muted-foreground\"\n              onClick={() =>\n                setNestedStack((current) =>\n                  current.slice(\n                    0,\n                    Math.max(nestedStackBaseDepth, current.length - 1)\n                  )\n                )\n              }\n              aria-label=\"Back to parent array\"\n            >\n              <IconPlaceholder\n                lucide=\"ChevronLeft\"\n                tabler=\"IconChevronLeft\"\n                hugeicons=\"ArrowLeft01Icon\"\n                phosphor=\"CaretLeftIcon\"\n                remixicon=\"RiArrowLeftSLine\"\n                className=\"size-3.5\"\n              />\n            </Button>\n            <div className=\"min-w-0 flex-1 truncate text-xs font-medium text-foreground\">\n              {activeNestedView.title}\n            </div>\n          </div>\n          <div className=\"min-h-0 flex-1 overflow-auto p-2\">\n            {activeNestedView.schema.type === \"array\" ? (\n              <HumanReviewArrayValueGrid\n                label={\n                  activeNestedView.schema.title ?? activeNestedView.columnId\n                }\n                nestedStackBaseDepth={nestedStackBaseDepth + 1}\n                readOnly={readOnly}\n                schema={activeNestedView.schema}\n                sharedGridSelection={sharedGridSelection}\n                sharedNestedStack={sharedNestedStack}\n                value={activeNestedValue}\n                viewSide={viewSide}\n                activeNestedSide={activeNestedSide}\n                activeSelectionSide={activeSelectionSide}\n                selectionDepth={selectionDepth}\n                onChange={updateNestedValue}\n                onGridSelectionChange={onGridSelectionChange}\n                onNestedStackChange={onNestedStackChange}\n                resolveArrayItemMetadataPath={resolveArrayItemMetadataPath}\n                resolveLocation={resolveLocation}\n              />\n            ) : (\n              <HumanReviewObjectValueEditor\n                schema={activeNestedView.schema}\n                value={activeNestedValue}\n                originalValue={activeNestedValue}\n                readOnly={readOnly}\n                onChange={updateNestedValue}\n              />\n            )}\n          </div>\n        </div>\n      ) : null}\n    </div>\n  )\n}\nfunction HumanReviewObjectValueEditor({\n  schema,\n  value,\n  originalValue,\n  readOnly = false,\n  onChange,\n}: {\n  schema: ReviewFieldSchema\n  value: JsonValue\n  originalValue: JsonValue\n  readOnly?: boolean\n  onChange: (value: JsonValue) => void\n}) {\n  const propertyEntries = Object.entries(schema.properties ?? {})\n  if (!propertyEntries.length) {\n    return (\n      <div className=\"rounded-md bg-background px-2 py-1.5 text-sm text-muted-foreground\">\n        No properties\n      </div>\n    )\n  }\n  return (\n    <div className=\"space-y-2\">\n      {propertyEntries.map(([propertyKey, propertySchema]) => (\n        <HumanReviewFieldCard\n          key={propertyKey}\n          field={{\n            key: propertyKey,\n            schema: propertySchema,\n            actual: getObjectValue(originalValue, propertyKey),\n            expected: getObjectValue(originalValue, propertyKey),\n          }}\n          value={getObjectValue(value, propertyKey)}\n          originalValue={getObjectValue(originalValue, propertyKey)}\n          readOnly={readOnly}\n          onChange={(childValue) =>\n            !readOnly &&\n            onChange(setObjectValue(value, propertyKey, childValue))\n          }\n          onUndo={() =>\n            !readOnly &&\n            onChange(\n              setObjectValue(\n                value,\n                propertyKey,\n                getObjectValue(originalValue, propertyKey)\n              )\n            )\n          }\n          onSetNull={() =>\n            !readOnly && onChange(setObjectValue(value, propertyKey, null))\n          }\n        />\n      ))}\n    </div>\n  )\n}\ntype HumanReviewFieldCardProps = {\n  field: ReviewField\n  value: JsonValue\n  originalValue: JsonValue\n  active?: boolean\n  activeFieldKey?: string\n  readOnly?: boolean\n  showExpected?: boolean\n  onChange: (value: JsonValue) => void\n  onFieldFocus?: (field: ReviewField) => void\n  onLocationHover?: (location?: ReviewLocation) => void\n  onUndo: () => void\n  onSetNull: () => void\n  resolveArrayItemMetadataPath?: (\n    metadataPath: string,\n    rowIndex: number,\n    rowValue: JsonValue\n  ) => string | undefined\n  resolveLocation?: (metadataPath: string) => ReviewLocation | undefined\n}\nfunction areHumanReviewFieldCardPropsEqual(\n  previous: HumanReviewFieldCardProps,\n  next: HumanReviewFieldCardProps\n) {\n  return (\n    previous.field === next.field &&\n    Object.is(previous.value, next.value) &&\n    Object.is(previous.originalValue, next.originalValue) &&\n    previous.active === next.active &&\n    previous.activeFieldKey === next.activeFieldKey &&\n    previous.readOnly === next.readOnly &&\n    previous.showExpected === next.showExpected &&\n    previous.onFieldFocus === next.onFieldFocus &&\n    previous.onLocationHover === next.onLocationHover &&\n    previous.resolveArrayItemMetadataPath ===\n      next.resolveArrayItemMetadataPath &&\n    previous.resolveLocation === next.resolveLocation\n  )\n}\nconst HumanReviewFieldCard = React.memo(\n  HumanReviewFieldCardBase,\n  areHumanReviewFieldCardPropsEqual\n)\nfunction HumanReviewFieldCardBase({\n  field,\n  value,\n  originalValue,\n  active,\n  activeFieldKey,\n  readOnly = false,\n  showExpected = true,\n  onChange,\n  onFieldFocus,\n  onLocationHover,\n  onUndo,\n  onSetNull,\n  resolveArrayItemMetadataPath,\n  resolveLocation,\n}: HumanReviewFieldCardProps) {\n  const isExpectedEditable = showExpected && !readOnly\n  const modified = showExpected && !jsonValuesEqual(value, originalValue)\n  const fieldTypeIcon = React.createElement(getFieldIcon(field.schema.type), {\n    className: \"size-3.5\",\n  })\n  const propertyEntries = Object.entries(field.schema.properties ?? {})\n  const [syncedArrayNestedView, setSyncedArrayNestedView] =\n    React.useState<SyncedArrayNestedView>(EMPTY_SYNCED_ARRAY_NESTED_VIEW)\n  const [syncedArraySelection, setSyncedArraySelection] =\n    React.useState<SyncedArraySelection>(EMPTY_SYNCED_ARRAY_SELECTION)\n  const updateSyncedArrayNestedView = React.useCallback(\n    (stack: ArrayNestedView[], side: ArrayReviewSide) => {\n      const activeSide = stack.length ? side : null\n      setSyncedArrayNestedView((current) =>\n        current.activeSide === activeSide &&\n        areArrayNestedViewsEqual(current.stack, stack)\n          ? current\n          : {\n              activeSide,\n              stack,\n            }\n      )\n    },\n    []\n  )\n  const updateSyncedArraySelection = React.useCallback(\n    (gridSelection: GridSelection, side: ArrayReviewSide, depth: number) => {\n      const activeSide = gridSelection.current ? side : null\n      setSyncedArraySelection((current) =>\n        current.activeSide === activeSide &&\n        current.depth === depth &&\n        areGridSelectionsEqual(current.gridSelection, gridSelection)\n          ? current\n          : {\n              activeSide,\n              depth,\n              gridSelection,\n            }\n      )\n    },\n    []\n  )\n  const focusAndHoverField = React.useCallback(() => {\n    onFieldFocus?.(field)\n    onLocationHover?.(getReviewFieldLocation(field, resolveLocation))\n  }, [field, onFieldFocus, onLocationHover, resolveLocation])\n  return (\n    <div\n      tabIndex={0}\n      onFocusCapture={focusAndHoverField}\n      onMouseEnter={focusAndHoverField}\n      onMouseLeave={() => onLocationHover?.(undefined)}\n      className={cn(\n        \"rounded-lg border bg-background p-3 transition-[border-color,background-color,box-shadow] focus-within:border-blue-500/50 focus-within:bg-blue-500/5 hover:border-blue-500/50 hover:bg-blue-500/5 focus-visible:ring-2 focus-visible:ring-blue-500/20 focus-visible:outline-none\",\n        active &&\n          \"border-blue-500/60 bg-blue-500/5 shadow-[0_0_0_1px_rgb(59_130_246_/_8%)]\"\n      )}\n    >\n      <div className=\"mb-3 flex min-h-8 items-start justify-between gap-3\">\n        <div className=\"min-w-0\">\n          <div className=\"flex min-w-0 items-center gap-2\">\n            <div className=\"min-w-0\">\n              <div className=\"truncate text-sm font-medium\">\n                {field.schema.title ?? field.key}\n              </div>\n            </div>\n            <span\n              className={cn(\n                \"size-2 shrink-0 rounded-full bg-amber-400\",\n                !modified && \"opacity-0\"\n              )}\n            />\n          </div>\n          <div className=\"truncate text-xs text-muted-foreground\">\n            {field.key}\n          </div>\n        </div>\n        <div className=\"flex shrink-0 items-center gap-1\">\n          {isExpectedEditable && modified ? (\n            <Tooltip>\n              <TooltipTrigger\n                render={\n                  <Button\n                    type=\"button\"\n                    variant=\"ghost\"\n                    size=\"icon-sm\"\n                    className=\"text-muted-foreground\"\n                    onClick={onUndo}\n                    aria-label={`Undo ${field.key}`}\n                  >\n                    <IconPlaceholder\n                      lucide=\"Undo2\"\n                      tabler=\"IconArrowBackUp\"\n                      hugeicons=\"Undo02Icon\"\n                      phosphor=\"ArrowUUpLeftIcon\"\n                      remixicon=\"RiArrowGoBackLine\"\n                      className=\"size-4\"\n                    />\n                  </Button>\n                }\n              ></TooltipTrigger>\n              <TooltipContent>Revert changes</TooltipContent>\n            </Tooltip>\n          ) : null}\n          {isExpectedEditable ? (\n            <Tooltip>\n              <TooltipTrigger\n                render={\n                  <Button\n                    type=\"button\"\n                    variant=\"ghost\"\n                    size=\"icon-sm\"\n                    className=\"text-muted-foreground\"\n                    onClick={onSetNull}\n                    aria-label={`Set ${field.key} to null`}\n                  >\n                    <IconPlaceholder\n                      lucide=\"CircleX\"\n                      tabler=\"IconCircleX\"\n                      hugeicons=\"CancelCircleIcon\"\n                      phosphor=\"XCircleIcon\"\n                      remixicon=\"RiCloseCircleLine\"\n                      className=\"size-4\"\n                    />\n                  </Button>\n                }\n              ></TooltipTrigger>\n              <TooltipContent>Set to NULL</TooltipContent>\n            </Tooltip>\n          ) : null}\n          <div className=\"flex h-6 items-center gap-1 rounded-md border bg-muted/50 px-1.5 text-xs text-muted-foreground\">\n            {fieldTypeIcon}\n            {field.schema.type}\n          </div>\n        </div>\n      </div>\n      {field.schema.type === \"object\" ? (\n        <div className=\"rounded-md border bg-muted/25 p-2\">\n          <div className=\"mb-2 flex items-center justify-between gap-3 text-[11px] font-medium text-muted-foreground\">\n            <span>Properties</span>\n            <span>{propertyEntries.length} fields</span>\n          </div>\n          <div className=\"space-y-2\">\n            {propertyEntries.length ? (\n              propertyEntries.map(([propertyKey, schema]) => {\n                const childField: ReviewField = {\n                  key: `${field.key}.${propertyKey}`,\n                  schema,\n                  actual: getObjectValue(field.actual, propertyKey),\n                  expected: getObjectValue(originalValue, propertyKey),\n                  metadataPath: `${field.metadataPath ?? field.key}.${propertyKey}`,\n                }\n                return (\n                  <HumanReviewFieldCard\n                    key={childField.key}\n                    field={childField}\n                    value={getObjectValue(value, propertyKey)}\n                    originalValue={childField.expected}\n                    active={childField.key === activeFieldKey}\n                    activeFieldKey={activeFieldKey}\n                    readOnly={readOnly}\n                    showExpected={showExpected}\n                    onChange={(childValue) =>\n                      onChange(setObjectValue(value, propertyKey, childValue))\n                    }\n                    onFieldFocus={onFieldFocus}\n                    onLocationHover={onLocationHover}\n                    onUndo={() =>\n                      onChange(\n                        setObjectValue(value, propertyKey, childField.expected)\n                      )\n                    }\n                    onSetNull={() =>\n                      onChange(setObjectValue(value, propertyKey, null))\n                    }\n                    resolveArrayItemMetadataPath={resolveArrayItemMetadataPath}\n                    resolveLocation={resolveLocation}\n                  />\n                )\n              })\n            ) : (\n              <div className=\"rounded-md bg-background px-2 py-1.5 text-sm text-muted-foreground\">\n                No properties\n              </div>\n            )}\n          </div>\n        </div>\n      ) : field.schema.type === \"array\" ? (\n        <div className=\"grid gap-2\">\n          <HumanReviewArrayValueGrid\n            activeNestedSide={syncedArrayNestedView.activeSide}\n            activeSelectionSide={syncedArraySelection.activeSide}\n            label=\"Actual\"\n            metadataPath={field.metadataPath ?? field.key}\n            readOnly\n            resolveArrayItemMetadataPath={resolveArrayItemMetadataPath}\n            resolveLocation={resolveLocation}\n            schema={field.schema}\n            selectionDepth={syncedArraySelection.depth}\n            sharedGridSelection={syncedArraySelection.gridSelection}\n            sharedNestedStack={syncedArrayNestedView.stack}\n            value={field.actual}\n            viewSide=\"actual\"\n            onGridSelectionChange={updateSyncedArraySelection}\n            onLocationHover={onLocationHover}\n            onNestedStackChange={updateSyncedArrayNestedView}\n          />\n          {showExpected ? (\n            <HumanReviewArrayValueGrid\n              activeNestedSide={syncedArrayNestedView.activeSide}\n              activeSelectionSide={syncedArraySelection.activeSide}\n              label=\"Expected\"\n              metadataPath={field.metadataPath ?? field.key}\n              readOnly={readOnly}\n              resolveArrayItemMetadataPath={resolveArrayItemMetadataPath}\n              resolveLocation={resolveLocation}\n              schema={field.schema}\n              selectionDepth={syncedArraySelection.depth}\n              sharedGridSelection={syncedArraySelection.gridSelection}\n              sharedNestedStack={syncedArrayNestedView.stack}\n              value={value}\n              viewSide=\"expected\"\n              onChange={onChange}\n              onGridSelectionChange={updateSyncedArraySelection}\n              onLocationHover={onLocationHover}\n              onNestedStackChange={updateSyncedArrayNestedView}\n            />\n          ) : null}\n        </div>\n      ) : (\n        <div className={cn(\"grid gap-2\", showExpected && \"sm:grid-cols-2\")}>\n          <div className=\"rounded-md border bg-muted/30 p-2\">\n            {field.schema.description ? (\n              <p className=\"mb-2 text-xs text-muted-foreground\">\n                {field.schema.description}\n              </p>\n            ) : null}\n            <div className=\"mb-1 text-[11px] font-medium text-muted-foreground\">\n              Actual\n            </div>\n            <div className=\"min-h-7 rounded-md bg-background px-2 py-1.5 text-sm\">\n              {formatValue(field.actual)}\n            </div>\n          </div>\n          {showExpected ? (\n            <div className=\"rounded-md border bg-muted/30 p-2\">\n              <div className=\"mb-1 text-[11px] font-medium text-muted-foreground\">\n                Expected\n              </div>\n              <HumanReviewValueInput\n                readOnly={readOnly}\n                schema={field.schema}\n                value={getPrimitiveValue(value)}\n                onChange={onChange}\n              />\n            </div>\n          ) : null}\n        </div>\n      )}\n    </div>\n  )\n}\nexport function HumanReviewHighlight({\n  location,\n}: {\n  location: ReviewLocation\n}) {\n  const area = location.area\n  return (\n    <div\n      className={cn(\n        \"pointer-events-none absolute z-10 border\",\n        REVIEW_HIGHLIGHT_STYLE\n      )}\n      style={{\n        left: `${area.left}%`,\n        top: `${area.top}%`,\n        width: `${area.width}%`,\n        height: `${area.height}%`,\n      }}\n    />\n  )\n}\nexport function JsonDiffView({\n  actual,\n  expected,\n  theme = \"light\",\n}: {\n  actual: JsonObject\n  expected: JsonObject\n  theme?: HumanReviewTheme\n}) {\n  const oldFile = React.useMemo(\n    () => ({\n      name: \"actual.json\",\n      contents: formatJson(actual),\n      lang: \"json\",\n    }),\n    [actual]\n  )\n  const newFile = React.useMemo(\n    () => ({\n      name: \"expected.json\",\n      contents: formatJson(expected),\n      lang: \"json\",\n    }),\n    [expected]\n  )\n  return (\n    <ScrollAreaVirtualizer\n      className=\"h-full bg-surface/60\"\n      contentClassName=\"min-w-full\"\n    >\n      <div className=\"bounding-box-citations-diff h-full text-xs\">\n        <MultiFileDiff\n          className=\"block min-w-full\"\n          oldFile={oldFile}\n          newFile={newFile}\n          options={{\n            diffStyle: \"split\",\n            disableFileHeader: true,\n            diffIndicators: \"bars\",\n            hunkSeparators: \"line-info-basic\",\n            overflow: \"wrap\",\n            themeType: theme,\n            theme: {\n              light: \"pierre-light-soft\",\n              dark: \"pierre-dark-soft\",\n            },\n          }}\n        />\n      </div>\n    </ScrollAreaVirtualizer>\n  )\n}\nexport function JsonCodeView({\n  name = \"actual.json\",\n  theme = \"light\",\n  value,\n}: {\n  name?: string\n  theme?: HumanReviewTheme\n  value: JsonValue\n}) {\n  const file = React.useMemo(() => {\n    const contents = formatJson(value)\n    return {\n      name,\n      contents,\n      lang: \"json\" as const,\n      cacheKey: contents,\n    }\n  }, [name, value])\n  return (\n    <div\n      data-rehype-pretty-code-figure\n      className=\"relative m-0! h-full overflow-hidden rounded-none! bg-code text-code-foreground\"\n    >\n      <WorkerPoolContextProvider\n        poolOptions={CODE_WORKER_POOL_OPTIONS}\n        highlighterOptions={CODE_HIGHLIGHTER_OPTIONS}\n      >\n        <ScrollAreaVirtualizer\n          key={`${file.cacheKey}:${theme}`}\n          className=\"h-full min-w-0\"\n          contentClassName=\"min-w-full\"\n        >\n          <File\n            key={`${file.cacheKey}:${theme}`}\n            className=\"block min-w-full\"\n            file={file}\n            metrics={CODE_VIRTUAL_FILE_METRICS}\n            style={CODE_FILE_THEME}\n            options={{\n              disableFileHeader: true,\n              overflow: \"scroll\",\n              themeType: theme,\n              theme: {\n                light: \"pierre-light-soft\",\n                dark: \"pierre-dark-soft\",\n              },\n            }}\n          />\n        </ScrollAreaVirtualizer>\n      </WorkerPoolContextProvider>\n    </div>\n  )\n}\nexport function HumanReviewPanel({\n  fields = REVIEW_FIELDS,\n  activeFieldKey,\n  className,\n  onFieldFocus,\n  onLocationHover,\n  resolveArrayItemMetadataPath,\n  resolveLocation,\n  showExpected = true,\n  theme = \"light\",\n}: {\n  fields?: ReviewField[]\n  activeFieldKey?: string\n  className?: string\n  onFieldFocus?: (field: ReviewField) => void\n  onLocationHover?: (location?: ReviewLocation) => void\n  resolveArrayItemMetadataPath?: (\n    metadataPath: string,\n    rowIndex: number,\n    rowValue: JsonValue\n  ) => string | undefined\n  resolveLocation?: (metadataPath: string) => ReviewLocation | undefined\n  showExpected?: boolean\n  theme?: HumanReviewTheme\n} = {}) {\n  const [activeTab, setActiveTab] = React.useState(\"form\")\n  const actualValues = React.useMemo(\n    () => valuesFromFields(fields, \"actual\"),\n    [fields]\n  )\n  const initialExpectedValues = React.useMemo(\n    () => valuesFromFields(fields, \"expected\"),\n    [fields]\n  )\n  const [expected, setExpected] = React.useState<JsonObject>(\n    initialExpectedValues\n  )\n  const [previousExpectedValues, setPreviousExpectedValues] = React.useState(\n    initialExpectedValues\n  )\n  if (!Object.is(previousExpectedValues, initialExpectedValues)) {\n    setPreviousExpectedValues(initialExpectedValues)\n    setExpected(initialExpectedValues)\n  }\n  const updateValue = React.useCallback((key: string, value: JsonValue) => {\n    setExpected((current) =>\n      Object.is(current[key], value) ? current : { ...current, [key]: value }\n    )\n  }, [])\n  return (\n    <TooltipProvider delay={200}>\n      <Tabs\n        value={activeTab}\n        onValueChange={setActiveTab}\n        className={cn(\"flex h-[560px] flex-col gap-0 bg-background\", className)}\n      >\n        <div className=\"flex min-h-12 items-center justify-between gap-3 border-b px-3\">\n          <TabsList className=\"h-8 sm:h-7\">\n            <TabsTrigger value=\"form\" className=\"h-7 sm:h-6\">\n              <IconPlaceholder\n                lucide=\"CaptionsIcon\"\n                tabler=\"IconTextCaption\"\n                hugeicons=\"TextCheckIcon\"\n                phosphor=\"TextTIcon\"\n                remixicon=\"RiTextWrap\"\n                className=\"size-4\"\n              />\n              Form\n            </TabsTrigger>\n            <TabsTrigger value=\"json\" className=\"h-7 sm:h-6\">\n              <IconPlaceholder\n                lucide=\"SquareCode\"\n                tabler=\"IconSourceCode\"\n                hugeicons=\"SourceCodeSquareIcon\"\n                phosphor=\"CodeIcon\"\n                remixicon=\"RiCodeBlock\"\n                className=\"size-4\"\n              />\n              JSON\n            </TabsTrigger>\n          </TabsList>\n        </div>\n        <TabsContent value=\"form\" keepMounted className=\"min-h-0 flex-1\">\n          <InlineScrollArea2 className=\"h-full\" scrollFade>\n            <div className=\"space-y-3 p-3\">\n              {fields.map((field) => (\n                <HumanReviewFieldCard\n                  key={field.key}\n                  field={field}\n                  value={\n                    showExpected ? (expected[field.key] ?? null) : field.actual\n                  }\n                  originalValue={showExpected ? field.expected : field.actual}\n                  active={\n                    field.key === activeFieldKey ||\n                    activeFieldKey?.startsWith(`${field.key}.`)\n                  }\n                  activeFieldKey={activeFieldKey}\n                  showExpected={showExpected}\n                  onChange={(value) => updateValue(field.key, value)}\n                  onFieldFocus={onFieldFocus}\n                  onLocationHover={onLocationHover}\n                  onUndo={() => updateValue(field.key, field.expected)}\n                  onSetNull={() => updateValue(field.key, null)}\n                  resolveArrayItemMetadataPath={resolveArrayItemMetadataPath}\n                  resolveLocation={resolveLocation}\n                />\n              ))}\n            </div>\n          </InlineScrollArea2>\n        </TabsContent>\n        <TabsContent value=\"json\" keepMounted className=\"min-h-0 flex-1\">\n          {showExpected ? (\n            <JsonDiffView\n              actual={actualValues}\n              expected={expected}\n              theme={theme}\n            />\n          ) : (\n            <JsonCodeView value={actualValues} theme={theme} />\n          )}\n        </TabsContent>\n      </Tabs>\n    </TooltipProvider>\n  )\n}\ntype InlineRegistryIconProps = Omit<\n  React.ComponentProps<\"svg\">,\n  \"children\" | \"strokeWidth\"\n> & { strokeWidth?: number }\nfunction InlineScrollArea2({\n  className,\n  children,\n  orientation = \"both\",\n  scrollFade = false,\n  scrollbarGutter = false,\n  scrollbarOverflowOnly = false,\n  viewportClassName,\n  viewportProps,\n  viewportRef,\n  ...props\n}: InlineScrollAreaProps) {\n  const {\n    className: viewportPropsClassName,\n    ref: viewportPropsRef,\n    ...resolvedViewportProps\n  } = viewportProps ?? {}\n  const composedViewportRef = React.useMemo(\n    () => InlineComposeRefs(viewportPropsRef, viewportRef),\n    [viewportPropsRef, viewportRef]\n  )\n\n  if (\n    !viewportProps &&\n    !viewportRef &&\n    !viewportClassName &&\n    !scrollFade &&\n    !scrollbarGutter &&\n    !scrollbarOverflowOnly\n  ) {\n    return (\n      <InlineScrollArea\n        {...props}\n        className={cn(\n          \"size-full min-h-0\",\n          orientation === \"horizontal\" &&\n            \"[&>[data-orientation=vertical]]:hidden\",\n          className\n        )}\n      >\n        {children}\n        {orientation !== \"vertical\" ? (\n          <ScrollBar orientation=\"horizontal\" />\n        ) : null}\n      </InlineScrollArea>\n    )\n  }\n\n  return (\n    <ScrollAreaPrimitive.Root\n      className={cn(\n        \"size-full min-h-0\",\n        scrollbarOverflowOnly &&\n          \"[&:not(:has([data-slot=scroll-area-viewport][data-has-overflow-x]))_[data-orientation=horizontal]]:hidden [&:not(:has([data-slot=scroll-area-viewport][data-has-overflow-y]))_[data-orientation=vertical]]:hidden\",\n        className\n      )}\n      {...props}\n    >\n      <ScrollAreaPrimitive.Viewport\n        {...resolvedViewportProps}\n        ref={composedViewportRef}\n        className={cn(\n          \"h-full rounded-[inherit] outline-none focus-visible:ring-2 focus-visible:ring-ring\",\n          scrollFade &&\n            \"mask-t-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-start)))] mask-r-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-end)))] mask-b-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-end)))] mask-l-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-start)))] [--fade-size:1.5rem]\",\n          scrollbarGutter && orientation !== \"vertical\" && \"pb-3.5\",\n          scrollbarGutter && orientation !== \"horizontal\" && \"pe-3.5\",\n          viewportPropsClassName,\n          viewportClassName\n        )}\n        data-slot=\"scroll-area-viewport\"\n      >\n        {children}\n      </ScrollAreaPrimitive.Viewport>\n      {orientation !== \"horizontal\" ? (\n        <ScrollBar orientation=\"vertical\" />\n      ) : null}\n      {orientation !== \"vertical\" ? (\n        <ScrollBar orientation=\"horizontal\" />\n      ) : null}\n      {orientation === \"both\" ? <ScrollAreaPrimitive.Corner /> : null}\n    </ScrollAreaPrimitive.Root>\n  )\n}\ntype InlineScrollAreaProps = ScrollAreaPrimitive.Root.Props & {\n  orientation?: \"vertical\" | \"horizontal\" | \"both\"\n  scrollFade?: boolean\n  scrollbarGutter?: boolean\n  scrollbarOverflowOnly?: boolean\n  viewportClassName?: string\n  viewportProps?: ScrollAreaPrimitive.Viewport.Props\n  viewportRef?: React.Ref<HTMLDivElement>\n}\nfunction InlineComposeRefs<T>(...refs: Array<React.Ref<T> | undefined>) {\n  return (node: T | null) => {\n    for (const ref of refs) {\n      if (!ref) continue\n      if (typeof ref === \"function\") ref(node)\n      else ref.current = node\n    }\n  }\n}\n",
      "type": "registry:ui",
      "target": "@components/extend/bounding-box-citations.tsx"
    }
  ],
  "categories": [
    "documents"
  ],
  "type": "registry:ui"
}
