@semiont/react-ui 0.5.19 → 0.5.20

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.
Files changed (32) hide show
  1. package/dist/{PdfAnnotationCanvas.client-75GY2EDR.js → PdfAnnotationCanvas.client-V7Q3BEEQ.js} +42 -45
  2. package/dist/PdfAnnotationCanvas.client-V7Q3BEEQ.js.map +1 -0
  3. package/dist/index.d.ts +231 -55
  4. package/dist/index.js +2115 -2161
  5. package/dist/index.js.map +1 -1
  6. package/package.json +4 -4
  7. package/src/components/AssistProgress.tsx +170 -0
  8. package/src/components/__tests__/AssistProgress.test.tsx +164 -0
  9. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +23 -54
  10. package/src/components/pdf-annotation/__tests__/rects-for-page.test.ts +96 -0
  11. package/src/components/pdf-annotation/rects-for-page.ts +47 -0
  12. package/src/components/resource/ResourceViewer.tsx +23 -55
  13. package/src/components/resource/panels/AssessmentPanel.tsx +1 -1
  14. package/src/components/resource/panels/AssistSection.tsx +111 -180
  15. package/src/components/resource/panels/AssistShell.tsx +77 -0
  16. package/src/components/resource/panels/CommentsPanel.tsx +1 -1
  17. package/src/components/resource/panels/HighlightPanel.tsx +1 -1
  18. package/src/components/resource/panels/ReferenceEntry.tsx +8 -1
  19. package/src/components/resource/panels/ReferencesPanel.tsx +101 -132
  20. package/src/components/resource/panels/TaggingPanel.tsx +23 -86
  21. package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +6 -14
  22. package/src/components/resource/panels/__tests__/AssistShell.test.tsx +59 -0
  23. package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +20 -0
  24. package/src/components/resource/panels/__tests__/ReferencesPanel.observable-flow.test.tsx +0 -1
  25. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +14 -20
  26. package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +30 -0
  27. package/src/features/resource-compose/components/ResourceComposePage.tsx +19 -1
  28. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +24 -64
  29. package/src/styles/features/compose.css +7 -0
  30. package/dist/PdfAnnotationCanvas.client-75GY2EDR.js.map +0 -1
  31. package/src/components/AnnotateReferencesProgressWidget.tsx +0 -125
  32. package/src/components/__tests__/AnnotateReferencesProgressWidget.test.tsx +0 -101
@@ -10,12 +10,30 @@ import "./chunk-O23TLLXW.js";
10
10
  // src/components/pdf-annotation/PdfAnnotationCanvas.tsx
11
11
  import { useRef, useState, useCallback, useEffect, useMemo } from "react";
12
12
  import { resourceId as toResourceId } from "@semiont/core";
13
- import {
14
- getTargetSelector,
15
- createFragmentSelector,
16
- parseFragmentSelector,
17
- getPageFromFragment
18
- } from "@semiont/core";
13
+ import { createFragmentSelector } from "@semiont/core";
14
+
15
+ // src/components/pdf-annotation/rects-for-page.ts
16
+ import { getTargetSelector, parseFragmentSelector } from "@semiont/core";
17
+ function fragmentSelectors(target) {
18
+ const selector = getTargetSelector(target);
19
+ if (!selector) return [];
20
+ const selectors = Array.isArray(selector) ? selector : [selector];
21
+ return selectors.filter((s) => s.type === "FragmentSelector").map((s) => s);
22
+ }
23
+ function rectsForPage(annotations, pageNumber) {
24
+ const rects = [];
25
+ for (const annotation of annotations) {
26
+ fragmentSelectors(annotation.target).forEach((sel, selectorIndex) => {
27
+ const coord = parseFragmentSelector(sel.value);
28
+ if (coord && coord.page === pageNumber) {
29
+ rects.push({ annId: annotation.id, selectorIndex, coord, annotation });
30
+ }
31
+ });
32
+ }
33
+ return rects;
34
+ }
35
+
36
+ // src/components/pdf-annotation/PdfAnnotationCanvas.tsx
19
37
  import { createHoverHandlers } from "@semiont/sdk";
20
38
 
21
39
  // src/lib/pdf-coordinates.ts
@@ -206,26 +224,22 @@ function PdfAnnotationCanvas({
206
224
  if (dragDistance < MIN_DRAG_DISTANCE) {
207
225
  if (existingAnnotations.length > 0) {
208
226
  let hitRect;
209
- const clickedAnnotation = pageAnnotations.find((ann) => {
210
- const fragmentSel = getFragmentSelector(ann.target);
211
- if (!fragmentSel) return false;
212
- const pdfCoord2 = parseFragmentSelector(fragmentSel.value);
213
- if (!pdfCoord2) return false;
214
- const rect = pdfToCanvasCoordinates(pdfCoord2, pageDimensions.height, 1);
227
+ const hit = rectsForPage(existingAnnotations, pageNumber).find((r) => {
228
+ const rect = pdfToCanvasCoordinates(r.coord, pageDimensions.height, 1);
215
229
  const scaleX2 = displayDimensions.width / pageDimensions.width;
216
230
  const scaleY2 = displayDimensions.height / pageDimensions.height;
217
231
  const displayX = rect.x * scaleX2;
218
232
  const displayY = rect.y * scaleY2;
219
233
  const displayWidth = rect.width * scaleX2;
220
234
  const displayHeight = rect.height * scaleY2;
221
- const hit = selection.endX >= displayX && selection.endX <= displayX + displayWidth && selection.endY >= displayY && selection.endY <= displayY + displayHeight;
222
- if (hit && imageRef.current) {
235
+ const inside = selection.endX >= displayX && selection.endX <= displayX + displayWidth && selection.endY >= displayY && selection.endY <= displayY + displayHeight;
236
+ if (inside && imageRef.current) {
223
237
  hitRect = toViewportAnchorRect(imageRef.current.getBoundingClientRect(), displayX, displayY, displayWidth, displayHeight);
224
238
  }
225
- return hit;
239
+ return inside;
226
240
  });
227
- if (clickedAnnotation) {
228
- session?.client.browse.click(clickedAnnotation.id, clickedAnnotation.motivation, hitRect);
241
+ if (hit) {
242
+ session?.client.browse.click(hit.annId, hit.annotation.motivation, hitRect);
229
243
  setIsDrawing(false);
230
244
  setSelection(null);
231
245
  return;
@@ -264,21 +278,8 @@ function PdfAnnotationCanvas({
264
278
  );
265
279
  }
266
280
  setIsDrawing(false);
267
- }, [isDrawing, selection, pageNumber, pageDimensions, displayDimensions, selectedMotivation, existingAnnotations]);
268
- const getFragmentSelector = (target) => {
269
- const selector = getTargetSelector(target);
270
- if (!selector) return null;
271
- const selectors = Array.isArray(selector) ? selector : [selector];
272
- const found = selectors.find((s) => s.type === "FragmentSelector");
273
- if (!found || found.type !== "FragmentSelector") return null;
274
- return found;
275
- };
276
- const pageAnnotations = existingAnnotations.filter((ann) => {
277
- const fragmentSel = getFragmentSelector(ann.target);
278
- if (!fragmentSel) return false;
279
- const page = getPageFromFragment(fragmentSel.value);
280
- return page === pageNumber;
281
- });
281
+ }, [isDrawing, selection, pageNumber, pageDimensions, displayDimensions, selectedMotivation, existingAnnotations, session, resourceUri]);
282
+ const pageRects = rectsForPage(existingAnnotations, pageNumber);
282
283
  const { handleMouseEnter, handleMouseLeave } = useMemo(
283
284
  () => createHoverHandlers((id) => session?.client.beckon.hover(id), hoverDelayMs),
284
285
  [session, hoverDelayMs]
@@ -336,17 +337,13 @@ function PdfAnnotationCanvas({
336
337
  width: displayDimensions.width,
337
338
  height: displayDimensions.height,
338
339
  children: [
339
- pageAnnotations.map((ann) => {
340
- const fragmentSel = getFragmentSelector(ann.target);
341
- if (!fragmentSel) return null;
342
- const pdfCoord = parseFragmentSelector(fragmentSel.value);
343
- if (!pdfCoord) return null;
344
- const rect = pdfToCanvasCoordinates(pdfCoord, pageDimensions.height, 1);
340
+ pageRects.map((r) => {
341
+ const rect = pdfToCanvasCoordinates(r.coord, pageDimensions.height, 1);
345
342
  const scaleX = displayDimensions.width / pageDimensions.width;
346
343
  const scaleY = displayDimensions.height / pageDimensions.height;
347
- const isHovered = ann.id === hoveredAnnotationId;
348
- const isSelected = ann.id === selectedAnnotationId;
349
- const annMotivation = ann.motivation;
344
+ const isHovered = r.annId === hoveredAnnotationId;
345
+ const isSelected = r.annId === selectedAnnotationId;
346
+ const annMotivation = r.annotation.motivation;
350
347
  const { stroke: annStroke, fill: annFill } = getMotivationColor(annMotivation);
351
348
  return /* @__PURE__ */ jsx(
352
349
  "rect",
@@ -363,11 +360,11 @@ function PdfAnnotationCanvas({
363
360
  cursor: "pointer",
364
361
  opacity: isSelected ? 1 : isHovered ? 0.9 : 0.7
365
362
  },
366
- onClick: (e) => session?.client.browse.click(ann.id, ann.motivation, e.currentTarget.getBoundingClientRect()),
367
- onMouseEnter: () => handleMouseEnter(ann.id),
363
+ onClick: (e) => session?.client.browse.click(r.annId, r.annotation.motivation, e.currentTarget.getBoundingClientRect()),
364
+ onMouseEnter: () => handleMouseEnter(r.annId),
368
365
  onMouseLeave: handleMouseLeave
369
366
  },
370
- ann.id
367
+ `${r.annId}:${r.selectorIndex}`
371
368
  );
372
369
  }),
373
370
  selection && (() => {
@@ -427,4 +424,4 @@ function PdfAnnotationCanvas({
427
424
  export {
428
425
  PdfAnnotationCanvas
429
426
  };
430
- //# sourceMappingURL=PdfAnnotationCanvas.client-75GY2EDR.js.map
427
+ //# sourceMappingURL=PdfAnnotationCanvas.client-V7Q3BEEQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/pdf-annotation/PdfAnnotationCanvas.tsx","../src/components/pdf-annotation/rects-for-page.ts","../src/lib/pdf-coordinates.ts"],"sourcesContent":["'use client';\n\nimport React, { useRef, useState, useCallback, useEffect, useMemo } from 'react';\nimport type { Annotation, AnchorRect } from '@semiont/core';\nimport { resourceId as toResourceId } from '@semiont/core';\nimport { toViewportAnchorRect } from '../../lib/anchor-rect';\nimport { createFragmentSelector } from '@semiont/core';\nimport { rectsForPage } from './rects-for-page';\nimport { createHoverHandlers, type SemiontSession } from '@semiont/sdk';\nimport type { SelectionMotivation } from '../annotation/AnnotateToolbar';\nimport {\n canvasToPdfCoordinates,\n pdfToCanvasCoordinates,\n type CanvasRectangle\n} from '../../lib/pdf-coordinates';\nimport {\n loadPdfDocument,\n renderPdfPageToDataUrl,\n type PDFDocumentProxy\n} from '../../lib/browser-pdfjs';\nimport './PdfAnnotationCanvas.css';\n\nexport type DrawingMode = 'rectangle' | 'circle' | 'polygon' | null;\n\n/**\n * Get color for annotation based on motivation\n */\nfunction getMotivationColor(motivation: SelectionMotivation | null): { stroke: string; fill: string } {\n if (!motivation) {\n return { stroke: 'rgb(156, 163, 175)', fill: 'rgba(156, 163, 175, 0.2)' };\n }\n\n switch (motivation) {\n case 'highlighting':\n return { stroke: 'rgb(250, 204, 21)', fill: 'rgba(250, 204, 21, 0.3)' };\n case 'linking':\n return { stroke: 'rgb(59, 130, 246)', fill: 'rgba(59, 130, 246, 0.2)' };\n case 'assessing':\n return { stroke: 'rgb(239, 68, 68)', fill: 'rgba(239, 68, 68, 0.2)' };\n case 'commenting':\n return { stroke: 'rgb(255, 255, 255)', fill: 'rgba(255, 255, 255, 0.2)' };\n default:\n return { stroke: 'rgb(156, 163, 175)', fill: 'rgba(156, 163, 175, 0.2)' };\n }\n}\n\ninterface PdfAnnotationCanvasProps {\n pdfUrl: string;\n /** The '@id' of the annotated resource — stamped as `source` on mark:requested (multi-viewer routing). */\n resourceUri: string;\n existingAnnotations?: Annotation[];\n drawingMode: DrawingMode;\n selectedMotivation?: SelectionMotivation | null;\n session?: SemiontSession | null | undefined;\n hoveredAnnotationId?: string | null;\n selectedAnnotationId?: string | null;\n hoverDelayMs?: number;\n}\n\n/**\n * PDF annotation canvas with page navigation and rectangle drawing\n *\n * @emits browse:click - Annotation clicked on PDF. Payload: { annotationId: string, motivation: Motivation }\n * @emits mark:requested - New annotation drawn on PDF. Payload: { selector: FragmentSelector, motivation: SelectionMotivation }\n * @emits beckon:hover - Annotation hovered or unhovered. Payload: { annotationId: string | null }\n */\nexport function PdfAnnotationCanvas({\n pdfUrl,\n resourceUri,\n existingAnnotations = [],\n drawingMode,\n selectedMotivation,\n session,\n hoveredAnnotationId,\n selectedAnnotationId,\n hoverDelayMs = 150\n}: PdfAnnotationCanvasProps) {\n // PDF state\n const [pdfDoc, setPdfDoc] = useState<PDFDocumentProxy | null>(null);\n const [numPages, setNumPages] = useState<number>(0);\n const [pageNumber, setPageNumber] = useState(1);\n const [pageImageUrl, setPageImageUrl] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [pageDimensions, setPageDimensions] = useState<{ width: number; height: number } | null>(null);\n const [displayDimensions, setDisplayDimensions] = useState<{ width: number; height: number } | null>(null);\n const [scale] = useState(1.5); // Fixed scale for better quality\n\n // Drawing state\n const [isDrawing, setIsDrawing] = useState(false);\n const [selection, setSelection] = useState<CanvasRectangle | null>(null);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const imageRef = useRef<HTMLImageElement>(null);\n\n // Load PDF document on mount\n useEffect(() => {\n let cancelled = false;\n\n async function loadPdf() {\n try {\n setIsLoading(true);\n setError(null);\n\n const doc = await loadPdfDocument(pdfUrl);\n\n if (cancelled) return;\n\n setPdfDoc(doc);\n setNumPages(doc.numPages);\n setIsLoading(false);\n } catch (err) {\n if (cancelled) return;\n\n console.error('Error loading PDF:', err);\n setError('Failed to load PDF');\n setIsLoading(false);\n }\n }\n\n loadPdf();\n\n return () => {\n cancelled = true;\n };\n }, [pdfUrl]);\n\n // Load current page when page number changes\n useEffect(() => {\n if (!pdfDoc) return;\n\n let cancelled = false;\n const doc = pdfDoc;\n\n async function loadPage() {\n try {\n const page = await doc.getPage(pageNumber);\n\n if (cancelled) return;\n\n // Get page dimensions (at scale 1.0)\n const viewport = page.getViewport({ scale: 1.0 });\n setPageDimensions({\n width: viewport.width,\n height: viewport.height\n });\n\n // Render page to image\n const { dataUrl } = await renderPdfPageToDataUrl(page, scale);\n\n if (cancelled) return;\n\n setPageImageUrl(dataUrl);\n } catch (err) {\n if (cancelled) return;\n\n console.error('Error loading page:', err);\n setError('Failed to load page');\n }\n }\n\n loadPage();\n\n return () => {\n cancelled = true;\n };\n }, [pdfDoc, pageNumber, scale]);\n\n // Update display dimensions on resize\n useEffect(() => {\n const updateDisplayDimensions = () => {\n if (imageRef.current) {\n setDisplayDimensions({\n width: imageRef.current.clientWidth,\n height: imageRef.current.clientHeight\n });\n }\n };\n\n updateDisplayDimensions();\n\n // Use ResizeObserver to detect image element size changes\n // This catches: sidebar open/close, window resize, font size changes, etc.\n let resizeObserver: ResizeObserver | null = null;\n\n try {\n resizeObserver = new ResizeObserver(updateDisplayDimensions);\n if (imageRef.current) {\n resizeObserver.observe(imageRef.current);\n }\n } catch (error) {\n // Fallback for browsers without ResizeObserver support\n console.warn('ResizeObserver not supported, falling back to window resize listener');\n window.addEventListener('resize', updateDisplayDimensions);\n }\n\n return () => {\n if (resizeObserver) {\n resizeObserver.disconnect();\n } else {\n window.removeEventListener('resize', updateDisplayDimensions);\n }\n };\n }, [pageImageUrl]);\n\n // Mouse event handlers for drawing\n const handleMouseDown = useCallback((e: React.MouseEvent) => {\n if (!drawingMode) return;\n if (!imageRef.current) return;\n\n const rect = imageRef.current.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n\n // Clear any previous selection when starting new drawing\n setIsDrawing(true);\n setSelection({\n startX: x,\n startY: y,\n endX: x,\n endY: y\n });\n }, [drawingMode]);\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (!isDrawing || !selection || !imageRef.current) return;\n\n const rect = imageRef.current.getBoundingClientRect();\n\n setSelection({\n ...selection,\n endX: e.clientX - rect.left,\n endY: e.clientY - rect.top\n });\n }, [isDrawing, selection]);\n\n const handleMouseUp = useCallback(() => {\n if (!isDrawing || !selection || !pageDimensions || !displayDimensions || !session) {\n setIsDrawing(false);\n setSelection(null);\n return;\n }\n\n // Calculate drag distance\n const dragDistance = Math.sqrt(\n Math.pow(selection.endX - selection.startX, 2) +\n Math.pow(selection.endY - selection.startY, 2)\n );\n\n // Minimum drag threshold in pixels (10px)\n const MIN_DRAG_DISTANCE = 10;\n\n if (dragDistance < MIN_DRAG_DISTANCE) {\n // This was a click, not a drag - check if we clicked an existing annotation\n if (existingAnnotations.length > 0) {\n // The hit-test owns the coordinate transform — capture the hit\n // annotation's viewport rect for the emission below (A1 anchor).\n let hitRect: AnchorRect | undefined;\n const hit = rectsForPage(existingAnnotations, pageNumber).find(r => {\n const rect = pdfToCanvasCoordinates(r.coord, pageDimensions.height, 1.0);\n\n // Scale to display coordinates\n const scaleX = displayDimensions.width / pageDimensions.width;\n const scaleY = displayDimensions.height / pageDimensions.height;\n\n const displayX = rect.x * scaleX;\n const displayY = rect.y * scaleY;\n const displayWidth = rect.width * scaleX;\n const displayHeight = rect.height * scaleY;\n\n const inside = (\n selection.endX >= displayX &&\n selection.endX <= displayX + displayWidth &&\n selection.endY >= displayY &&\n selection.endY <= displayY + displayHeight\n );\n if (inside && imageRef.current) {\n hitRect = toViewportAnchorRect(imageRef.current.getBoundingClientRect(), displayX, displayY, displayWidth, displayHeight);\n }\n return inside;\n });\n\n if (hit) {\n session?.client.browse.click(hit.annId, hit.annotation.motivation, hitRect);\n setIsDrawing(false);\n setSelection(null);\n return;\n }\n }\n\n // Click on empty space - do nothing\n setIsDrawing(false);\n setSelection(null);\n return;\n }\n\n // This was a drag - create new annotation\n // Scale selection from display coordinates to native page coordinates\n const scaleX = pageDimensions.width / displayDimensions.width;\n const scaleY = pageDimensions.height / displayDimensions.height;\n\n const nativeSelection: CanvasRectangle = {\n startX: selection.startX * scaleX,\n startY: selection.startY * scaleY,\n endX: selection.endX * scaleX,\n endY: selection.endY * scaleY\n };\n\n // Convert canvas coordinates to PDF coordinates\n const pdfCoord = canvasToPdfCoordinates(\n nativeSelection,\n pageNumber,\n pageDimensions.width,\n pageDimensions.height,\n 1.0 // Use scale 1.0 since we already scaled to native coords\n );\n\n // Create FragmentSelector\n const fragmentSelector = createFragmentSelector(pdfCoord);\n\n // Emit annotation:requested event with FragmentSelector\n if (selectedMotivation) {\n session.client.mark.request(\n toResourceId(resourceUri),\n {\n type: 'FragmentSelector',\n conformsTo: 'http://tools.ietf.org/rfc/rfc3778',\n value: fragmentSelector,\n },\n selectedMotivation,\n );\n }\n\n // Keep drawing state active to show preview until annotation is persisted\n // The parent component should clear this by changing drawingMode after save\n setIsDrawing(false);\n // Note: We keep selection so the preview remains visible\n // It will be cleared when drawingMode changes or user starts new selection\n }, [isDrawing, selection, pageNumber, pageDimensions, displayDimensions, selectedMotivation, existingAnnotations, session, resourceUri]);\n\n // Every FragmentSelector rect on the current page — one per line for a\n // multi-line (multi-selector) annotation, exactly one for a manual annotation.\n const pageRects = rectsForPage(existingAnnotations, pageNumber);\n\n // Hover handlers with currentHover guard and dwell delay\n const { handleMouseEnter, handleMouseLeave } = useMemo(\n () => createHoverHandlers((id) => session?.client.beckon.hover(id), hoverDelayMs),\n [session, hoverDelayMs]\n );\n\n // Calculate motivation color\n const { stroke, fill } = getMotivationColor(selectedMotivation ?? null);\n\n if (error) {\n return <div className=\"semiont-pdf-annotation-canvas__error\">{error}</div>;\n }\n\n return (\n <div className=\"semiont-pdf-annotation-canvas\">\n {isLoading && <div className=\"semiont-pdf-annotation-canvas__loading\">Loading PDF...</div>}\n\n <div\n ref={containerRef}\n className=\"semiont-pdf-annotation-canvas__container\"\n style={{ display: isLoading ? 'none' : undefined }}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={() => {\n if (isDrawing) {\n setIsDrawing(false);\n setSelection(null);\n }\n }}\n data-drawing-mode={drawingMode || 'none'}\n >\n {/* PDF page rendered as image */}\n {pageImageUrl && (\n <img\n ref={imageRef}\n src={pageImageUrl}\n alt={`PDF page ${pageNumber}`}\n className=\"semiont-pdf-annotation-canvas__image\"\n draggable={false}\n style={{ pointerEvents: 'none' }}\n onLoad={() => {\n // Use double RAF to ensure layout is complete even in onLoad\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (imageRef.current) {\n setDisplayDimensions({\n width: imageRef.current.clientWidth,\n height: imageRef.current.clientHeight\n });\n }\n });\n });\n }}\n />\n )}\n\n {/* SVG overlay for annotations */}\n {displayDimensions && pageDimensions && (\n <div className=\"semiont-pdf-annotation-canvas__overlay-container\">\n <div className=\"semiont-pdf-annotation-canvas__overlay\">\n <svg\n className=\"semiont-pdf-annotation-canvas__svg\"\n width={displayDimensions.width}\n height={displayDimensions.height}\n >\n {/* Render existing annotations for this page */}\n {pageRects.map(r => {\n const rect = pdfToCanvasCoordinates(r.coord, pageDimensions.height, 1.0);\n\n // Scale to display coordinates\n const scaleX = displayDimensions.width / pageDimensions.width;\n const scaleY = displayDimensions.height / pageDimensions.height;\n\n const isHovered = r.annId === hoveredAnnotationId;\n const isSelected = r.annId === selectedAnnotationId;\n\n // Colour by the annotation's own motivation (not the toolbar's).\n const annMotivation = r.annotation.motivation as SelectionMotivation | null;\n const { stroke: annStroke, fill: annFill } = getMotivationColor(annMotivation);\n\n return (\n <rect\n key={`${r.annId}:${r.selectorIndex}`}\n x={rect.x * scaleX}\n y={rect.y * scaleY}\n width={rect.width * scaleX}\n height={rect.height * scaleY}\n stroke={annStroke}\n strokeWidth={isSelected ? 4 : isHovered ? 3 : 2}\n fill={annFill}\n style={{\n pointerEvents: 'auto',\n cursor: 'pointer',\n opacity: isSelected ? 1 : isHovered ? 0.9 : 0.7\n }}\n onClick={(e) => session?.client.browse.click(r.annId, r.annotation.motivation, e.currentTarget.getBoundingClientRect())}\n onMouseEnter={() => handleMouseEnter(r.annId)}\n onMouseLeave={handleMouseLeave}\n />\n );\n })}\n\n {/* Render current selection while drawing or awaiting save */}\n {selection && (() => {\n const rectX = Math.min(selection.startX, selection.endX);\n const rectY = Math.min(selection.startY, selection.endY);\n const rectWidth = Math.abs(selection.endX - selection.startX);\n const rectHeight = Math.abs(selection.endY - selection.startY);\n\n // PDF only supports rectangle shapes (FragmentSelector with viewrect)\n // Circle/polygon are disabled in the UI for PDF media types\n return (\n <rect\n x={rectX}\n y={rectY}\n width={rectWidth}\n height={rectHeight}\n stroke={stroke}\n strokeWidth={2}\n strokeDasharray=\"5,5\"\n fill={fill}\n pointerEvents=\"none\"\n />\n );\n })()}\n </svg>\n </div>\n </div>\n )}\n </div>\n\n {/* Page navigation controls */}\n {numPages > 0 && (\n <div className=\"semiont-pdf-annotation-canvas__controls\">\n <button\n disabled={pageNumber <= 1}\n onClick={() => setPageNumber(pageNumber - 1)}\n className=\"semiont-pdf-annotation-canvas__button\"\n >\n Previous\n </button>\n <span className=\"semiont-pdf-annotation-canvas__page-info\">\n Page {pageNumber} of {numPages}\n </span>\n <button\n disabled={pageNumber >= numPages}\n onClick={() => setPageNumber(pageNumber + 1)}\n className=\"semiont-pdf-annotation-canvas__button\"\n >\n Next\n </button>\n </div>\n )}\n </div>\n );\n}\n","import type { Annotation, PdfCoordinate } from '@semiont/core';\nimport { getTargetSelector, parseFragmentSelector } from '@semiont/core';\n\n/** One FragmentSelector rectangle to paint on a PDF page. */\nexport interface PageRect {\n /** Owning annotation id — shared by every rect of a multi-line annotation (hover/click routing). */\n annId: Annotation['id'];\n /** Index within the annotation's FragmentSelectors — the stable half of the React key. */\n selectorIndex: number;\n /** PDF-point geometry for this rect. */\n coord: PdfCoordinate;\n /** Owning annotation (motivation colour, etc.). */\n annotation: Annotation;\n}\n\n/** Every FragmentSelector on a target, in order (`target.selector` may be one or an array). */\nfunction fragmentSelectors(target: Annotation['target']): { value: string }[] {\n const selector = getTargetSelector(target);\n if (!selector) return [];\n const selectors = Array.isArray(selector) ? selector : [selector];\n return selectors\n .filter(s => s.type === 'FragmentSelector')\n .map(s => s as { type: 'FragmentSelector'; value: string });\n}\n\n/**\n * The rectangles to paint on `pageNumber`: one entry per FragmentSelector whose\n * viewrect page matches. A multi-line (multi-selector) annotation therefore yields\n * one rect per line; a single-selector (manual) annotation yields exactly one.\n *\n * Pure — no React/DOM. `PdfAnnotationCanvas` maps this to `<rect>` keyed\n * `${annId}:${selectorIndex}`, and the rects-for-page axioms exercise it directly.\n * Geometry stays deferred: each `coord` still goes through `pdfToCanvasCoordinates`\n * at paint time (itself covered by the coordinate-transform axioms).\n */\nexport function rectsForPage(annotations: Annotation[], pageNumber: number): PageRect[] {\n const rects: PageRect[] = [];\n for (const annotation of annotations) {\n fragmentSelectors(annotation.target).forEach((sel, selectorIndex) => {\n const coord = parseFragmentSelector(sel.value);\n if (coord && coord.page === pageNumber) {\n rects.push({ annId: annotation.id, selectorIndex, coord, annotation });\n }\n });\n }\n return rects;\n}\n","/**\n * PDF Canvas Coordinate Transforms\n *\n * Converts between canvas space (pixels, top-left origin, Y increases downward)\n * and PDF space (points, bottom-left origin, Y increases upward) — the Y-flip and\n * scale. UI-only: the server has no canvas.\n *\n * `PdfCoordinate` and the viewrect FragmentSelector codec live in `@semiont/core`.\n *\n * Based on RFC 3778 PDF Fragment Identifiers:\n * https://tools.ietf.org/html/rfc3778\n */\n\nimport type { PdfCoordinate } from '@semiont/core';\n\nexport interface Rectangle {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface CanvasRectangle {\n startX: number;\n startY: number;\n endX: number;\n endY: number;\n}\n\n/**\n * Convert canvas coordinates to PDF coordinates\n *\n * Canvas: Origin at top-left, Y increases downward\n * PDF: Origin at bottom-left, Y increases upward\n *\n * @param canvasRect - Rectangle in canvas pixel coordinates\n * @param page - PDF page number (1-indexed)\n * @param pageWidth - PDF page width in points\n * @param pageHeight - PDF page height in points\n * @param scale - Current canvas scale factor\n */\nexport function canvasToPdfCoordinates(\n canvasRect: CanvasRectangle,\n page: number,\n _pageWidth: number,\n pageHeight: number,\n scale: number = 1\n): PdfCoordinate {\n // Normalize rectangle (handle drag in any direction)\n const x1 = Math.min(canvasRect.startX, canvasRect.endX);\n const y1 = Math.min(canvasRect.startY, canvasRect.endY);\n const x2 = Math.max(canvasRect.startX, canvasRect.endX);\n const y2 = Math.max(canvasRect.startY, canvasRect.endY);\n\n // Convert from canvas pixels to PDF points\n const pdfX = x1 / scale;\n const pdfWidth = (x2 - x1) / scale;\n\n // Flip Y coordinate (canvas top-left to PDF bottom-left)\n const pdfY = pageHeight - (y2 / scale);\n const pdfHeight = (y2 - y1) / scale;\n\n return {\n page,\n x: Math.round(pdfX),\n y: Math.round(pdfY),\n width: Math.round(pdfWidth),\n height: Math.round(pdfHeight)\n };\n}\n\n/**\n * Convert PDF coordinates to canvas coordinates\n *\n * @param pdfCoord - Coordinates in PDF space\n * @param pageHeight - PDF page height in points\n * @param scale - Current canvas scale factor\n */\nexport function pdfToCanvasCoordinates(\n pdfCoord: PdfCoordinate,\n pageHeight: number,\n scale: number = 1\n): Rectangle {\n // Convert from PDF points to canvas pixels\n const canvasX = pdfCoord.x * scale;\n const canvasWidth = pdfCoord.width * scale;\n\n // Flip Y coordinate (PDF bottom-left to canvas top-left)\n const canvasY = (pageHeight - pdfCoord.y - pdfCoord.height) * scale;\n const canvasHeight = pdfCoord.height * scale;\n\n return {\n x: canvasX,\n y: canvasY,\n width: canvasWidth,\n height: canvasHeight\n };\n}\n"],"mappings":";;;;;;;;;;AAEA,SAAgB,QAAQ,UAAU,aAAa,WAAW,eAAe;AAEzE,SAAS,cAAc,oBAAoB;AAE3C,SAAS,8BAA8B;;;ACLvC,SAAS,mBAAmB,6BAA6B;AAezD,SAAS,kBAAkB,QAAmD;AAC5E,QAAM,WAAW,kBAAkB,MAAM;AACzC,MAAI,CAAC,SAAU,QAAO,CAAC;AACvB,QAAM,YAAY,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;AAChE,SAAO,UACJ,OAAO,OAAK,EAAE,SAAS,kBAAkB,EACzC,IAAI,OAAK,CAAgD;AAC9D;AAYO,SAAS,aAAa,aAA2B,YAAgC;AACtF,QAAM,QAAoB,CAAC;AAC3B,aAAW,cAAc,aAAa;AACpC,sBAAkB,WAAW,MAAM,EAAE,QAAQ,CAAC,KAAK,kBAAkB;AACnE,YAAM,QAAQ,sBAAsB,IAAI,KAAK;AAC7C,UAAI,SAAS,MAAM,SAAS,YAAY;AACtC,cAAM,KAAK,EAAE,OAAO,WAAW,IAAI,eAAe,OAAO,WAAW,CAAC;AAAA,MACvE;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;ADtCA,SAAS,2BAAgD;;;AEiClD,SAAS,uBACd,YACA,MACA,YACA,YACA,QAAgB,GACD;AAEf,QAAM,KAAK,KAAK,IAAI,WAAW,QAAQ,WAAW,IAAI;AACtD,QAAM,KAAK,KAAK,IAAI,WAAW,QAAQ,WAAW,IAAI;AACtD,QAAM,KAAK,KAAK,IAAI,WAAW,QAAQ,WAAW,IAAI;AACtD,QAAM,KAAK,KAAK,IAAI,WAAW,QAAQ,WAAW,IAAI;AAGtD,QAAM,OAAO,KAAK;AAClB,QAAM,YAAY,KAAK,MAAM;AAG7B,QAAM,OAAO,aAAc,KAAK;AAChC,QAAM,aAAa,KAAK,MAAM;AAE9B,SAAO;AAAA,IACL;AAAA,IACA,GAAG,KAAK,MAAM,IAAI;AAAA,IAClB,GAAG,KAAK,MAAM,IAAI;AAAA,IAClB,OAAO,KAAK,MAAM,QAAQ;AAAA,IAC1B,QAAQ,KAAK,MAAM,SAAS;AAAA,EAC9B;AACF;AASO,SAAS,uBACd,UACA,YACA,QAAgB,GACL;AAEX,QAAM,UAAU,SAAS,IAAI;AAC7B,QAAM,cAAc,SAAS,QAAQ;AAGrC,QAAM,WAAW,aAAa,SAAS,IAAI,SAAS,UAAU;AAC9D,QAAM,eAAe,SAAS,SAAS;AAEvC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AACF;;;AFiQW,cAmDG,YAnDH;AAvUX,SAAS,mBAAmB,YAA0E;AACpG,MAAI,CAAC,YAAY;AACf,WAAO,EAAE,QAAQ,sBAAsB,MAAM,2BAA2B;AAAA,EAC1E;AAEA,UAAQ,YAAY;AAAA,IAClB,KAAK;AACH,aAAO,EAAE,QAAQ,qBAAqB,MAAM,0BAA0B;AAAA,IACxE,KAAK;AACH,aAAO,EAAE,QAAQ,qBAAqB,MAAM,0BAA0B;AAAA,IACxE,KAAK;AACH,aAAO,EAAE,QAAQ,oBAAoB,MAAM,yBAAyB;AAAA,IACtE,KAAK;AACH,aAAO,EAAE,QAAQ,sBAAsB,MAAM,2BAA2B;AAAA,IAC1E;AACE,aAAO,EAAE,QAAQ,sBAAsB,MAAM,2BAA2B;AAAA,EAC5E;AACF;AAsBO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA,sBAAsB,CAAC;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AACjB,GAA6B;AAE3B,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAkC,IAAI;AAClE,QAAM,CAAC,UAAU,WAAW,IAAI,SAAiB,CAAC;AAClD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,CAAC;AAC9C,QAAM,CAAC,cAAc,eAAe,IAAI,SAAwB,IAAI;AACpE,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,IAAI;AAC/C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAmD,IAAI;AACnG,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAmD,IAAI;AACzG,QAAM,CAAC,KAAK,IAAI,SAAS,GAAG;AAG5B,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAiC,IAAI;AAEvE,QAAM,eAAe,OAAuB,IAAI;AAChD,QAAM,WAAW,OAAyB,IAAI;AAG9C,YAAU,MAAM;AACd,QAAI,YAAY;AAEhB,mBAAe,UAAU;AACvB,UAAI;AACF,qBAAa,IAAI;AACjB,iBAAS,IAAI;AAEb,cAAM,MAAM,MAAM,gBAAgB,MAAM;AAExC,YAAI,UAAW;AAEf,kBAAU,GAAG;AACb,oBAAY,IAAI,QAAQ;AACxB,qBAAa,KAAK;AAAA,MACpB,SAAS,KAAK;AACZ,YAAI,UAAW;AAEf,gBAAQ,MAAM,sBAAsB,GAAG;AACvC,iBAAS,oBAAoB;AAC7B,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAEA,YAAQ;AAER,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAGX,YAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AAEb,QAAI,YAAY;AAChB,UAAM,MAAM;AAEZ,mBAAe,WAAW;AACxB,UAAI;AACF,cAAM,OAAO,MAAM,IAAI,QAAQ,UAAU;AAEzC,YAAI,UAAW;AAGf,cAAM,WAAW,KAAK,YAAY,EAAE,OAAO,EAAI,CAAC;AAChD,0BAAkB;AAAA,UAChB,OAAO,SAAS;AAAA,UAChB,QAAQ,SAAS;AAAA,QACnB,CAAC;AAGD,cAAM,EAAE,QAAQ,IAAI,MAAM,uBAAuB,MAAM,KAAK;AAE5D,YAAI,UAAW;AAEf,wBAAgB,OAAO;AAAA,MACzB,SAAS,KAAK;AACZ,YAAI,UAAW;AAEf,gBAAQ,MAAM,uBAAuB,GAAG;AACxC,iBAAS,qBAAqB;AAAA,MAChC;AAAA,IACF;AAEA,aAAS;AAET,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,QAAQ,YAAY,KAAK,CAAC;AAG9B,YAAU,MAAM;AACd,UAAM,0BAA0B,MAAM;AACpC,UAAI,SAAS,SAAS;AACpB,6BAAqB;AAAA,UACnB,OAAO,SAAS,QAAQ;AAAA,UACxB,QAAQ,SAAS,QAAQ;AAAA,QAC3B,CAAC;AAAA,MACH;AAAA,IACF;AAEA,4BAAwB;AAIxB,QAAI,iBAAwC;AAE5C,QAAI;AACF,uBAAiB,IAAI,eAAe,uBAAuB;AAC3D,UAAI,SAAS,SAAS;AACpB,uBAAe,QAAQ,SAAS,OAAO;AAAA,MACzC;AAAA,IACF,SAASA,QAAO;AAEd,cAAQ,KAAK,sEAAsE;AACnF,aAAO,iBAAiB,UAAU,uBAAuB;AAAA,IAC3D;AAEA,WAAO,MAAM;AACX,UAAI,gBAAgB;AAClB,uBAAe,WAAW;AAAA,MAC5B,OAAO;AACL,eAAO,oBAAoB,UAAU,uBAAuB;AAAA,MAC9D;AAAA,IACF;AAAA,EACF,GAAG,CAAC,YAAY,CAAC;AAGjB,QAAM,kBAAkB,YAAY,CAAC,MAAwB;AAC3D,QAAI,CAAC,YAAa;AAClB,QAAI,CAAC,SAAS,QAAS;AAEvB,UAAM,OAAO,SAAS,QAAQ,sBAAsB;AACpD,UAAM,IAAI,EAAE,UAAU,KAAK;AAC3B,UAAM,IAAI,EAAE,UAAU,KAAK;AAG3B,iBAAa,IAAI;AACjB,iBAAa;AAAA,MACX,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AAAA,EACH,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,kBAAkB,YAAY,CAAC,MAAwB;AAC3D,QAAI,CAAC,aAAa,CAAC,aAAa,CAAC,SAAS,QAAS;AAEnD,UAAM,OAAO,SAAS,QAAQ,sBAAsB;AAEpD,iBAAa;AAAA,MACX,GAAG;AAAA,MACH,MAAM,EAAE,UAAU,KAAK;AAAA,MACvB,MAAM,EAAE,UAAU,KAAK;AAAA,IACzB,CAAC;AAAA,EACH,GAAG,CAAC,WAAW,SAAS,CAAC;AAEzB,QAAM,gBAAgB,YAAY,MAAM;AACtC,QAAI,CAAC,aAAa,CAAC,aAAa,CAAC,kBAAkB,CAAC,qBAAqB,CAAC,SAAS;AACjF,mBAAa,KAAK;AAClB,mBAAa,IAAI;AACjB;AAAA,IACF;AAGA,UAAM,eAAe,KAAK;AAAA,MACxB,KAAK,IAAI,UAAU,OAAO,UAAU,QAAQ,CAAC,IAC7C,KAAK,IAAI,UAAU,OAAO,UAAU,QAAQ,CAAC;AAAA,IAC/C;AAGA,UAAM,oBAAoB;AAE1B,QAAI,eAAe,mBAAmB;AAEpC,UAAI,oBAAoB,SAAS,GAAG;AAGlC,YAAI;AACJ,cAAM,MAAM,aAAa,qBAAqB,UAAU,EAAE,KAAK,OAAK;AAClE,gBAAM,OAAO,uBAAuB,EAAE,OAAO,eAAe,QAAQ,CAAG;AAGvE,gBAAMC,UAAS,kBAAkB,QAAQ,eAAe;AACxD,gBAAMC,UAAS,kBAAkB,SAAS,eAAe;AAEzD,gBAAM,WAAW,KAAK,IAAID;AAC1B,gBAAM,WAAW,KAAK,IAAIC;AAC1B,gBAAM,eAAe,KAAK,QAAQD;AAClC,gBAAM,gBAAgB,KAAK,SAASC;AAEpC,gBAAM,SACJ,UAAU,QAAQ,YAClB,UAAU,QAAQ,WAAW,gBAC7B,UAAU,QAAQ,YAClB,UAAU,QAAQ,WAAW;AAE/B,cAAI,UAAU,SAAS,SAAS;AAC9B,sBAAU,qBAAqB,SAAS,QAAQ,sBAAsB,GAAG,UAAU,UAAU,cAAc,aAAa;AAAA,UAC1H;AACA,iBAAO;AAAA,QACT,CAAC;AAED,YAAI,KAAK;AACP,mBAAS,OAAO,OAAO,MAAM,IAAI,OAAO,IAAI,WAAW,YAAY,OAAO;AAC1E,uBAAa,KAAK;AAClB,uBAAa,IAAI;AACjB;AAAA,QACF;AAAA,MACF;AAGA,mBAAa,KAAK;AAClB,mBAAa,IAAI;AACjB;AAAA,IACF;AAIA,UAAM,SAAS,eAAe,QAAQ,kBAAkB;AACxD,UAAM,SAAS,eAAe,SAAS,kBAAkB;AAEzD,UAAM,kBAAmC;AAAA,MACvC,QAAQ,UAAU,SAAS;AAAA,MAC3B,QAAQ,UAAU,SAAS;AAAA,MAC3B,MAAM,UAAU,OAAO;AAAA,MACvB,MAAM,UAAU,OAAO;AAAA,IACzB;AAGA,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf,eAAe;AAAA,MACf;AAAA;AAAA,IACF;AAGA,UAAM,mBAAmB,uBAAuB,QAAQ;AAGxD,QAAI,oBAAoB;AACtB,cAAQ,OAAO,KAAK;AAAA,QAClB,aAAa,WAAW;AAAA,QACxB;AAAA,UACE,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,OAAO;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAIA,iBAAa,KAAK;AAAA,EAGpB,GAAG,CAAC,WAAW,WAAW,YAAY,gBAAgB,mBAAmB,oBAAoB,qBAAqB,SAAS,WAAW,CAAC;AAIvI,QAAM,YAAY,aAAa,qBAAqB,UAAU;AAG9D,QAAM,EAAE,kBAAkB,iBAAiB,IAAI;AAAA,IAC7C,MAAM,oBAAoB,CAAC,OAAO,SAAS,OAAO,OAAO,MAAM,EAAE,GAAG,YAAY;AAAA,IAChF,CAAC,SAAS,YAAY;AAAA,EACxB;AAGA,QAAM,EAAE,QAAQ,KAAK,IAAI,mBAAmB,sBAAsB,IAAI;AAEtE,MAAI,OAAO;AACT,WAAO,oBAAC,SAAI,WAAU,wCAAwC,iBAAM;AAAA,EACtE;AAEA,SACE,qBAAC,SAAI,WAAU,iCACZ;AAAA,iBAAa,oBAAC,SAAI,WAAU,0CAAyC,4BAAc;AAAA,IAEpF;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAU;AAAA,QACV,OAAO,EAAE,SAAS,YAAY,SAAS,OAAU;AAAA,QACjD,aAAa;AAAA,QACb,aAAa;AAAA,QACb,WAAW;AAAA,QACX,cAAc,MAAM;AAClB,cAAI,WAAW;AACb,yBAAa,KAAK;AAClB,yBAAa,IAAI;AAAA,UACnB;AAAA,QACF;AAAA,QACA,qBAAmB,eAAe;AAAA,QAGjC;AAAA,0BACC;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,KAAK;AAAA,cACL,KAAK,YAAY,UAAU;AAAA,cAC3B,WAAU;AAAA,cACV,WAAW;AAAA,cACX,OAAO,EAAE,eAAe,OAAO;AAAA,cAC/B,QAAQ,MAAM;AAEZ,sCAAsB,MAAM;AAC1B,wCAAsB,MAAM;AAC1B,wBAAI,SAAS,SAAS;AACpB,2CAAqB;AAAA,wBACnB,OAAO,SAAS,QAAQ;AAAA,wBACxB,QAAQ,SAAS,QAAQ;AAAA,sBAC3B,CAAC;AAAA,oBACH;AAAA,kBACF,CAAC;AAAA,gBACH,CAAC;AAAA,cACH;AAAA;AAAA,UACF;AAAA,UAID,qBAAqB,kBACpB,oBAAC,SAAI,WAAU,oDACb,8BAAC,SAAI,WAAU,0CACb;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,OAAO,kBAAkB;AAAA,cACzB,QAAQ,kBAAkB;AAAA,cAGzB;AAAA,0BAAU,IAAI,OAAK;AAClB,wBAAM,OAAO,uBAAuB,EAAE,OAAO,eAAe,QAAQ,CAAG;AAGvE,wBAAM,SAAS,kBAAkB,QAAQ,eAAe;AACxD,wBAAM,SAAS,kBAAkB,SAAS,eAAe;AAEzD,wBAAM,YAAY,EAAE,UAAU;AAC9B,wBAAM,aAAa,EAAE,UAAU;AAG/B,wBAAM,gBAAgB,EAAE,WAAW;AACnC,wBAAM,EAAE,QAAQ,WAAW,MAAM,QAAQ,IAAI,mBAAmB,aAAa;AAE7E,yBACE;AAAA,oBAAC;AAAA;AAAA,sBAEC,GAAG,KAAK,IAAI;AAAA,sBACZ,GAAG,KAAK,IAAI;AAAA,sBACZ,OAAO,KAAK,QAAQ;AAAA,sBACpB,QAAQ,KAAK,SAAS;AAAA,sBACtB,QAAQ;AAAA,sBACR,aAAa,aAAa,IAAI,YAAY,IAAI;AAAA,sBAC9C,MAAM;AAAA,sBACN,OAAO;AAAA,wBACL,eAAe;AAAA,wBACf,QAAQ;AAAA,wBACR,SAAS,aAAa,IAAI,YAAY,MAAM;AAAA,sBAC9C;AAAA,sBACA,SAAS,CAAC,MAAM,SAAS,OAAO,OAAO,MAAM,EAAE,OAAO,EAAE,WAAW,YAAY,EAAE,cAAc,sBAAsB,CAAC;AAAA,sBACtH,cAAc,MAAM,iBAAiB,EAAE,KAAK;AAAA,sBAC5C,cAAc;AAAA;AAAA,oBAfT,GAAG,EAAE,KAAK,IAAI,EAAE,aAAa;AAAA,kBAgBpC;AAAA,gBAEJ,CAAC;AAAA,gBAGA,cAAc,MAAM;AACnB,wBAAM,QAAQ,KAAK,IAAI,UAAU,QAAQ,UAAU,IAAI;AACvD,wBAAM,QAAQ,KAAK,IAAI,UAAU,QAAQ,UAAU,IAAI;AACvD,wBAAM,YAAY,KAAK,IAAI,UAAU,OAAO,UAAU,MAAM;AAC5D,wBAAM,aAAa,KAAK,IAAI,UAAU,OAAO,UAAU,MAAM;AAI7D,yBACE;AAAA,oBAAC;AAAA;AAAA,sBACC,GAAG;AAAA,sBACH,GAAG;AAAA,sBACH,OAAO;AAAA,sBACP,QAAQ;AAAA,sBACR;AAAA,sBACA,aAAa;AAAA,sBACb,iBAAgB;AAAA,sBAChB;AAAA,sBACA,eAAc;AAAA;AAAA,kBAChB;AAAA,gBAEJ,GAAG;AAAA;AAAA;AAAA,UACL,GACF,GACF;AAAA;AAAA;AAAA,IAEJ;AAAA,IAGC,WAAW,KACV,qBAAC,SAAI,WAAU,2CACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,UAAU,cAAc;AAAA,UACxB,SAAS,MAAM,cAAc,aAAa,CAAC;AAAA,UAC3C,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,MACA,qBAAC,UAAK,WAAU,4CAA2C;AAAA;AAAA,QACnD;AAAA,QAAW;AAAA,QAAK;AAAA,SACxB;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,UAAU,cAAc;AAAA,UACxB,SAAS,MAAM,cAAc,aAAa,CAAC;AAAA,UAC3C,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,OACF;AAAA,KAEJ;AAEJ;","names":["error","scaleX","scaleY"]}
package/dist/index.d.ts CHANGED
@@ -215,7 +215,7 @@ interface TranslationManager {
215
215
  */
216
216
 
217
217
  type SemiontResource$1 = ResourceDescriptor;
218
- type Motivation$8 = components['schemas']['Motivation'];
218
+ type Motivation$7 = components['schemas']['Motivation'];
219
219
  /**
220
220
  * Selection for creating annotations
221
221
  */
@@ -242,7 +242,7 @@ interface TextSelection {
242
242
  * No aliasing, wrappers, or compatibility layers elsewhere.
243
243
  */
244
244
 
245
- type Motivation$7 = components['schemas']['Motivation'];
245
+ type Motivation$6 = components['schemas']['Motivation'];
246
246
  /**
247
247
  * Detection configuration for SSE-based annotation detection
248
248
  */
@@ -269,7 +269,7 @@ interface CreateConfig {
269
269
  * Handles clicks, hovers, detection, and other operations for one annotation type
270
270
  */
271
271
  interface Annotator {
272
- motivation: Motivation$7;
272
+ motivation: Motivation$6;
273
273
  internalType: string;
274
274
  displayName: string;
275
275
  description: string;
@@ -286,7 +286,155 @@ interface Annotator {
286
286
  /**
287
287
  * Static annotator definitions - single source of truth
288
288
  */
289
- declare const ANNOTATORS: Record<string, Annotator>;
289
+ declare const ANNOTATORS: {
290
+ highlight: {
291
+ motivation: "highlighting";
292
+ internalType: string;
293
+ displayName: string;
294
+ description: string;
295
+ className: string;
296
+ iconEmoji: string;
297
+ isClickable: true;
298
+ hasHoverInteraction: true;
299
+ hasSidePanel: true;
300
+ matchesAnnotation: (ann: Annotation) => boolean;
301
+ announceOnCreate: string;
302
+ create: {
303
+ bodyBuilder: "empty";
304
+ refetchAfter: false;
305
+ };
306
+ detection: {
307
+ sseMethod: "detectHighlights";
308
+ countField: "createdCount";
309
+ displayNamePlural: string;
310
+ displayNameSingular: string;
311
+ formatRequestParams: (args: unknown[]) => {
312
+ label: string;
313
+ value: string;
314
+ }[];
315
+ };
316
+ };
317
+ comment: {
318
+ motivation: "commenting";
319
+ internalType: string;
320
+ displayName: string;
321
+ description: string;
322
+ className: string;
323
+ iconEmoji: string;
324
+ isClickable: true;
325
+ hasHoverInteraction: true;
326
+ hasSidePanel: true;
327
+ matchesAnnotation: (ann: Annotation) => boolean;
328
+ announceOnCreate: string;
329
+ create: {
330
+ bodyBuilder: "text";
331
+ refetchAfter: false;
332
+ };
333
+ detection: {
334
+ sseMethod: "detectComments";
335
+ countField: "createdCount";
336
+ displayNamePlural: string;
337
+ displayNameSingular: string;
338
+ formatRequestParams: (args: unknown[]) => {
339
+ label: string;
340
+ value: string;
341
+ }[];
342
+ };
343
+ };
344
+ assessment: {
345
+ motivation: "assessing";
346
+ internalType: string;
347
+ displayName: string;
348
+ description: string;
349
+ className: string;
350
+ iconEmoji: string;
351
+ isClickable: true;
352
+ hasHoverInteraction: true;
353
+ hasSidePanel: true;
354
+ matchesAnnotation: (ann: Annotation) => boolean;
355
+ announceOnCreate: string;
356
+ create: {
357
+ bodyBuilder: "text";
358
+ refetchAfter: false;
359
+ };
360
+ detection: {
361
+ sseMethod: "detectAssessments";
362
+ countField: "createdCount";
363
+ displayNamePlural: string;
364
+ displayNameSingular: string;
365
+ formatRequestParams: (args: unknown[]) => {
366
+ label: string;
367
+ value: string;
368
+ }[];
369
+ };
370
+ };
371
+ reference: {
372
+ motivation: "linking";
373
+ internalType: string;
374
+ displayName: string;
375
+ description: string;
376
+ className: string;
377
+ iconEmoji: string;
378
+ isClickable: true;
379
+ hasHoverInteraction: true;
380
+ hasSidePanel: true;
381
+ matchesAnnotation: (ann: Annotation) => boolean;
382
+ announceOnCreate: string;
383
+ create: {
384
+ bodyBuilder: "entityTag";
385
+ refetchAfter: true;
386
+ };
387
+ detection: {
388
+ sseMethod: "detectReferences";
389
+ countField: "foundCount";
390
+ displayNamePlural: string;
391
+ displayNameSingular: string;
392
+ formatRequestParams: (args: unknown[]) => {
393
+ label: string;
394
+ value: string;
395
+ }[];
396
+ };
397
+ };
398
+ tag: {
399
+ motivation: "tagging";
400
+ internalType: string;
401
+ displayName: string;
402
+ description: string;
403
+ className: string;
404
+ iconEmoji: string;
405
+ isClickable: true;
406
+ hasHoverInteraction: true;
407
+ hasSidePanel: true;
408
+ matchesAnnotation: (ann: Annotation) => boolean;
409
+ announceOnCreate: string;
410
+ create: {
411
+ bodyBuilder: "dualTag";
412
+ refetchAfter: false;
413
+ successMessage: string;
414
+ };
415
+ detection: {
416
+ sseMethod: "detectTags";
417
+ countField: "tagsCreated";
418
+ displayNamePlural: string;
419
+ displayNameSingular: string;
420
+ formatRequestParams: (args: unknown[]) => {
421
+ label: string;
422
+ value: string;
423
+ }[];
424
+ };
425
+ };
426
+ };
427
+ /** Keys of the annotator registry — also the annotations panel's tab keys. */
428
+ type AnnotatorKey = keyof typeof ANNOTATORS;
429
+ /**
430
+ * Annotator key (= panel tab key) for a motivation — derived from
431
+ * {@link ANNOTATORS}, the single motivation↔annotator source, so no second
432
+ * hand-written map can drift. Takes `string`, not `Motivation`: the schemas
433
+ * type motivation properly (`BrowsePanelOpenEvent.motivation` is a `Motivation`
434
+ * `$ref`), but `panel:open` is not wire-validated at runtime, so loose strings
435
+ * can still arrive — callers at that boundary must handle `undefined`.
436
+ */
437
+ declare function annotatorKeyForMotivation(motivation: string): AnnotatorKey | undefined;
290
438
 
291
439
  /**
292
440
  * Centralized button styles matching Figma design
@@ -1286,39 +1434,77 @@ interface Props$b {
1286
1434
  }
1287
1435
  declare function CodeMirrorRenderer({ content, segments, onChange, editable, newAnnotationIds, hoveredAnnotationId, scrollToAnnotationId, sourceView, showLineNumbers, enableWidgets, session, getTargetResourceName, generatingReferenceId, hoverDelayMs }: Props$b): React$1.JSX.Element;
1288
1436
 
1289
- type Motivation$6 = components['schemas']['Motivation'];
1290
- type JobProgress$7 = components['schemas']['JobProgress'];
1291
- interface JobProgressWidgetTranslations {
1292
- /** Header title (e.g. "Annotating Entity References" / "Generating Resource"). */
1293
- title: string;
1437
+ type JobProgress$8 = components['schemas']['JobProgress'];
1438
+ interface AssistProgressTranslations {
1439
+ /** Header title (e.g. "Annotating Entity References" / "Generating Resource"). Omit for the headerless inline style. */
1440
+ title?: string;
1294
1441
  /** Cancel-button title attribute. */
1295
- cancel: string;
1442
+ cancel?: string;
1296
1443
  /** Default in-progress status message (used when the job sends no `message`). */
1297
- inProgress: string;
1298
- complete: string;
1299
- failed: string;
1300
- /** Completed entity-type log line (annotation flow only). */
1444
+ inProgress?: string;
1445
+ /** Status copy for the terminal 'complete' stage. */
1446
+ complete?: string;
1447
+ /** Fallback status copy for the terminal 'error' stage. */
1448
+ failed?: string;
1449
+ /** Completed entity-type log line (reference flow). */
1301
1450
  found?: (count: number) => string;
1302
- /** Current entity-type status (annotation flow only). */
1303
- current?: (entityType: string) => string;
1451
+ /** Current-work detail line (reference flow). */
1452
+ current?: (label: string) => string;
1453
+ /** Dismiss-button label. */
1454
+ close?: string;
1455
+ }
1456
+ interface AssistProgressProps {
1457
+ progress: JobProgress$8;
1458
+ /** CSS `data-type` hook ('highlight' | 'comment' | … | 'reference' | 'tag' | 'generation'). */
1459
+ dataType: string;
1460
+ /** Cancel the underlying job — rendered while running when provided. Caller wires `client.job.cancelRequest(...)`. */
1461
+ onCancel?: () => void;
1462
+ /**
1463
+ * Dismiss the display — rendered whenever provided. WHEN dismissal is
1464
+ * offered is the caller's policy (AssistShell withholds the callback while
1465
+ * the assist is still running). Caller wires `client.mark.dismissProgress()`.
1466
+ */
1467
+ onDismiss?: () => void;
1468
+ /** Render the percentage bar (tag flow's visual; percentage itself comes from `progress`). */
1469
+ showPercentBar?: boolean;
1470
+ translations?: AssistProgressTranslations;
1304
1471
  }
1305
- interface AnnotateReferencesProgressWidgetProps {
1306
- progress: JobProgress$7 | null;
1307
- /** CSS `data-type` hook. */
1308
- annotationType?: Motivation$6 | 'reference' | 'generation';
1309
- /** Job type the cancel button requests. */
1310
- cancelJobType: 'annotation' | 'generation';
1311
- translations: JobProgressWidgetTranslations;
1472
+ /**
1473
+ * The one job-progress renderer (#7) unifies the three previous shapes
1474
+ * (AssistSection's inline block, the reference/generation widget, TaggingPanel's
1475
+ * inline block). Presentational and provider-free: no session, no context —
1476
+ * cancel/dismiss arrive as callbacks, so it renders identically on the page and
1477
+ * in embeddable (bring-your-own-session) hosts. Feature blocks are
1478
+ * data-presence-driven: each call site keeps its established visuals by passing
1479
+ * the data and translations it always had.
1480
+ */
1481
+ declare function AssistProgress({ progress, dataType, onCancel, onDismiss, showPercentBar, translations: tr, }: AssistProgressProps): React$1.JSX.Element;
1482
+
1483
+ type JobProgress$7 = components['schemas']['JobProgress'];
1484
+ interface AssistShellProps {
1485
+ /** localStorage persist-key suffix and CSS `data-type` ('highlight' | 'comment' | 'assessment' | 'reference' | 'tag'). */
1486
+ assistType: string;
1487
+ /** Collapsible section title (already translated). */
1488
+ title: string;
1489
+ isAssisting: boolean;
1490
+ progress: JobProgress$7 | null | undefined;
1491
+ /** The per-motivation form (fields + submit) — shown when no progress is displayed. */
1492
+ form: ReactNode;
1493
+ /**
1494
+ * Pass-through config for the progress renderer (cancel/dismiss wiring,
1495
+ * translations, percent bar). Dismiss policy lives HERE: the shell forwards
1496
+ * `onDismiss` only once the assist is no longer running.
1497
+ */
1498
+ progressProps?: Omit<AssistProgressProps, 'progress' | 'dataType'>;
1312
1499
  }
1313
1500
  /**
1314
- * Job-progress widget (header + cancel + status). Shared by the annotation
1315
- * (reference) flow and the resource-generate flow the title, status copy, and
1316
- * cancel job type are supplied by the caller so neither flow's wording leaks into
1317
- * the other.
1318
- *
1319
- * @emits job:cancel-requested - User requested to cancel the job. Payload: { jobType: string }
1501
+ * The one assist-section chrome (#7): collapsible header with persisted expand
1502
+ * state, the assisting wrapper, and the form-vs-progress switch. Every
1503
+ * motivation's panel composes this shell with its own fields the fields
1504
+ * differ per motivation by design (instructions/tone/density vs entity chips
1505
+ * vs schema+categories), so the shell owns only what is genuinely shared.
1320
1506
  */
1321
- declare function AnnotateReferencesProgressWidget({ progress, annotationType, cancelJobType, translations: tr }: AnnotateReferencesProgressWidgetProps): React$1.JSX.Element | null;
1507
+ declare function AssistShell({ assistType, title, isAssisting, progress, form, progressProps }: AssistShellProps): React$1.JSX.Element;
1322
1508
 
1323
1509
  interface Props$a {
1324
1510
  children: ReactNode;
@@ -1782,9 +1968,6 @@ declare function HistoryEvent({ event, annotations, allEvents, isRelated, t, Lin
1782
1968
  *
1783
1969
  * Event flow:
1784
1970
  * make-meaning → EventLog → SSE → EventBus → ResourceViewer → Cache invalidation
1785
- *
1786
- * Phase 2 complete: Event-based cache invalidation replaces manual refetch
1787
- * Phase 3 complete: Fully event-driven - all user interactions use unified event bus
1788
1971
  */
1789
1972
  interface Props$4 {
1790
1973
  resource: ResourceDescriptor & {
@@ -1838,13 +2021,14 @@ interface Props$4 {
1838
2021
  showToolbar?: boolean;
1839
2022
  }
1840
2023
  /**
1841
- * @emits mark:delete - User requested to delete annotation. Payload: { annotationId: string }
1842
- * @emits panel:open - Request to open panel with annotation. Payload: { panel: string, scrollToAnnotationId?: string, motivation?: Motivation }
2024
+ * Deletion calls `session.client.mark.delete(...)` directly (no bus emit);
2025
+ * panel opening invokes the host's `onOpenPanel` callback the host owns
2026
+ * the panel and any `panel:open` emission.
1843
2027
  *
1844
2028
  * @subscribes mark:added - New annotation was added. Payload: { annotation: Annotation }
1845
2029
  * @subscribes mark:removed - Annotation was removed. Payload: { annotationId: string }
1846
2030
  * @subscribes mark:body-updated - Annotation was updated. Payload: { annotation: Annotation }
1847
- * @subscribes browse:click - User clicked on annotation. Payload: { annotationId: string }
2031
+ * @subscribes browse:click - User clicked on annotation. Payload: { annotationId: string, motivation, anchorRect? }
1848
2032
  */
1849
2033
  declare function ResourceViewer({ resource, annotations, session, onOpenResource, onOpenPanel, onLinkClick, onReferenceHover, inline, newAnnotationIds, generatingReferenceId, showLineNumbers, hoverDelayMs, hoveredAnnotationId: hoveredAnnotationIdProp, annotateMode: annotateModeProp, onAnnotateModeChange, clickAction: clickActionProp, onClickActionChange, selectionMotivation: selectionMotivationProp, onSelectionMotivationChange, shape: shapeProp, onShapeChange, showToolbar, }: Props$4): React__default.JSX.Element;
1850
2034
 
@@ -1971,13 +2155,10 @@ interface AssistSectionProps {
1971
2155
  progress?: JobProgress$4 | null | undefined;
1972
2156
  }
1973
2157
  /**
1974
- * Shared assist section for Highlight, Assessment, and Comment panels
1975
- *
1976
- * Provides:
1977
- * - Optional instructions textarea
1978
- * - Optional tone selector (for comments)
1979
- * - Assist button with sparkle animation
1980
- * - Progress display during annotation assist
2158
+ * Assist fields for the text motivations (highlight, assessment, comment):
2159
+ * instructions, tone (comment/assessment), density — composed into the shared
2160
+ * AssistShell chrome. Reference and tag panels compose the same shell with
2161
+ * their own fields (entity chips; schema + categories).
1981
2162
  *
1982
2163
  * @emits mark:assist-request - Start assist for annotation type. Payload: { motivation: Motivation, options: { instructions?: string, tone?: string, density?: number } }
1983
2164
  * @emits mark:progress-dismiss - Dismiss the annotation progress display
@@ -3983,20 +4164,15 @@ interface ResourceViewerPageProps {
3983
4164
  * @subscribes mark:unarchive - Unarchive the current resource
3984
4165
  * @subscribes yield:clone - Clone the current resource
3985
4166
  * @subscribes beckon:sparkle - Trigger sparkle animation
3986
- * @subscribes mark:added - Annotation was created
3987
- * @subscribes mark:removed - Annotation was deleted
3988
- * @subscribes mark:create-failed - Annotation creation failed
3989
- * @subscribes mark:delete-failed - Annotation deletion failed
3990
- * @subscribes mark:body-updated - Annotation body was updated
3991
- * @subscribes annotate:body-update-failed - Annotation body update failed
4167
+ * @subscribes mark:added - Annotation was created (sparkle)
3992
4168
  * @subscribes settings:theme-changed - UI theme changed
3993
4169
  * @subscribes settings:line-numbers-toggled - Line numbers display toggled
3994
- * @subscribes detection:complete - Detection completed
3995
- * @subscribes detection:failed - Detection failed
3996
- * @subscribes generation:complete - Generation completed
3997
- * @subscribes generation:failed - Generation failed
3998
4170
  * @subscribes browse:reference-navigate - Navigate to a referenced document
3999
4171
  * @subscribes browse:entity-type-clicked - Navigate filtered by entity type
4172
+ *
4173
+ * Outcome-notification channels (mark:create-error, mark:delete-error,
4174
+ * bind:body-error, job:complete, job:fail, mark:assist-timeout) are
4175
+ * subscribed by useOutcomeToasts.
4000
4176
  */
4001
4177
  declare function ResourceViewerPage({ resource, rUri, locale, Link, routes, ToolbarPanels, refetchDocument, streamStatus, knowledgeBaseName, }: ResourceViewerPageProps): React__default.JSX.Element;
4002
4178
 
@@ -4146,5 +4322,5 @@ declare function useShellStateUnit(): ShellStateUnit;
4146
4322
  */
4147
4323
  declare function useObservable<T>(obs$: Observable<T> | null | undefined): T | undefined;
4148
4324
 
4149
- export { ANNOTATORS, AVAILABLE_LOCALES, AdminDevOpsPage, AdminExchangePage, AdminSecurityPage, AdminUsersPage, AnnotateReferencesProgressWidget, AnnotateToolbar, AnnotateView, AnnotationHistory, AnnotationOverlay, AnnotationProvider, AssessmentEntry, AssessmentPanel, AssistSection, AsyncErrorBoundary, AuthErrorDisplay, BrowseView, Button, ButtonGroup, COMMON_PANELS, CodeMirrorRenderer, CollaborationPanel, CollapsibleResourceNavigation, CommentEntry, CommentsPanel, ComposeLoadingState, EntityTagsPage, EntityTypeBadges, ErrorBoundary, ExportCard, Footer, HighlightEntry, HighlightPanel, HistoryEvent, ImageBrowseRenderer, ImageURLSchema, ImageViewer, ImportCard, ImportProgress, JsonLdPanel, JsonLdView, KeyboardShortcutsHelpModal, LeftSidebar, LinkedDataPage, LiveRegionProvider, NavigationMenu, OAuthUserSchema, ObservableLink, PageLayout, PanelHeader, PdfBrowseRenderer, PermissionDeniedModal, PopupContainer, PopupHeader, ProtectedErrorBoundary, RESOURCE_PANELS, RecentDocumentsPage, ReferenceEntry, ReferenceResolutionWidget, ReferenceWizardModal, ReferencesPanel, ResizeHandle, ResourceAnnotationsProvider, ResourceCard, ResourceComposePage, ResourceDiscoveryPage, ResourceErrorState, ResourceGenerateModal, ResourceInfoPanel, ResourceLoadingState, ResourceSearchModal, ResourceTagsInline, ResourceViewer, ResourceViewerPage, SearchModal, SelectedTextDisplay, SemiontBranding, SemiontFavicon, SemiontProvider, SessionExpiredModal, SessionExpiryBanner, SessionTimer, SettingsPanel, SignInForm, SignUpForm, SimpleNavigation, SkipLinks, SortableResourceTab, StatisticsPanel, StatusDisplay, SvgDrawingCanvas, TagEntry, TagSchemasPage, TaggingPanel, TextBrowseRenderer, ThemeProvider, ToastContainer, ToastProvider, Toolbar, TranslationProvider, UnifiedAnnotationsPanel, UnifiedHeader, UploadProgressBar, UserMenuSkeleton, WebBrowserStorage, WelcomePage, applyHighlights, buildSourceToRenderedMap, buildTextNodeIndex, buttonStyles, clearHighlights, createAdminSecurityStateUnit, createAdminUsersStateUnit, createComposePageStateUnit, createDiscoverStateUnit, createEntityTagsStateUnit, createExchangeStateUnit, createResourceLoaderStateUnit, createResourceViewerPageStateUnit, createSessionStateUnit, createShellStateUnit, createWelcomeStateUnit, cssVariables, defaultBrowseRenderers, faviconPaths, formatTime, generateCSSVariables, getResourceIcon, getSelectedShapeForSelectorType, getSelectorType, getShortcutDisplay, getSupportedShapes, hideWidgetPreview, isShapeSupported, jsonLightHighlightStyle, jsonLightTheme, resolveAnnotationRanges, sanitizeImageURL, saveSelectedShapeForSelectorType, setPdfWorkerSrc, showWidgetPreview, supportsDetection, toOverlayAnnotations, tokens, useAnnotationManager, useDebounce, useDebouncedCallback, useDocumentAnnouncements, useDoubleKeyPress, useDropdown, useEventSubscription, useEventSubscriptions, useFormAnnouncements, useHoverDelay, useHoverEmitter, useIsTyping, useKBDiscovery, useKeyboardShortcuts, useLanguageChangeAnnouncements, useLineNumbers, useLiveRegion, useLoadingState, useLocalStorage, useMediaToken, useObservable, useObservableExternalNavigation, useObservableRouter, usePanelWidth, usePendingCreation, usePreloadTranslations, useResourceAnnotations, useResourceContent, useResourceGather, useResourceLoader, useResourceLoadingAnnouncements, useRovingTabIndex, useSearchAnnouncements, useSemiont, useSessionEventSubscriptions, useSessionExpiry, useShellStateUnit, useStateUnit, useTheme, useToast, useToolbarPrefs, useTranslations };
4150
- export type { AdminDevOpsPageProps, AdminExchangePageProps, AdminExchangePageTranslations, AdminSecurityPageProps, AdminSecurityStateUnit, AdminUser, AdminUserStats, AdminUsersPageProps, AdminUsersStateUnit, AnnotationConfig, AnnotationCreationHandler, AnnotationGroups, AnnotationHandlers, AnnotationManager, AnnotationProviderProps, AnnotationUIState, AnnotationsCollection, Annotator, AuthErrorDisplayProps, AvailableLocale, BorderRadiusToken, BrowseMediaRenderers, ButtonGroupProps, ButtonProps, ClickAction, CloneData, CollapsibleResourceNavigationProps, ColorToken, ComposeLoadingStateProps, ComposeMode, ComposePageStateUnit, ComposeParams, CreateAnnotationParams, CreateConfig, DeleteAnnotationParams, DetectionConfig, DevOpsFeature, DiscoverStateUnit, DrawingMode, EntityTagsPageProps, EntityTagsStateUnit, ExchangeStateUnit, ExportCardProps, ExportCardTranslations, HoverEmitterProps, ImportCardProps, ImportCardTranslations, ImportPreview, ImportProgressProps, ImportProgressTranslations, JobProgressWidgetTranslations, KBDiscoveryOptions, KBDiscoveryResult, KeyboardShortcut, LinkComponentProps, LinkedDataPageProps, LinkedDataPageTranslations, MediaRendererProps, Motivation$8 as Motivation, NavigationItem, NavigationMenuHelper, NavigationProps, OAuthProvider, OAuthUser, ObservableLinkProps, OverlayAnnotation, PendingCreation, RecentDocumentsPageProps, ReferenceData, ReferenceHover, ReferenceWizardModalProps, ResolvedTheme, ResourceCardProps, ResourceComposePageProps, ResourceDiscoveryPageProps, ResourceErrorStateProps, ResourceGatherOptions, ResourceGenerateModalProps, ResourceGenerateModalTranslations, ResourceLoaderStateUnit, ResourceSearchModalProps, ResourceViewerPageProps, ResourceViewerPageStateUnit, RouteBuilder, SaveResourceParams$1 as SaveResourceParams, SearchModalProps, SelectionMotivation, SelectorType, SemiontProviderProps, SemiontResource$1 as SemiontResource, SessionStateUnit, ShadowToken, ShapeType, ShellStateUnit, ShellStateUnitOptions, SignInFormProps, SignUpFormProps, SimpleNavigationItem, SimpleNavigationProps, SortableResourceTabProps, SpacingToken, TagSchemasPageProps, TextSegment, TextSelection, Theme, ToastMessage, ToastType, ToolbarPanelType, ToolbarPart, ToolbarPrefs, TransitionToken, TranslationManager, TranslationProviderProps, TypographyToken, UICreateAnnotationParams, UploadProgressBarProps, UseMediaTokenResult, UseResourceContentResult, UseResourceGatherResult, UseResourceLoaderResult, WelcomePageProps, WelcomeStateUnit, WizardState };
4325
+ export { ANNOTATORS, AVAILABLE_LOCALES, AdminDevOpsPage, AdminExchangePage, AdminSecurityPage, AdminUsersPage, AnnotateToolbar, AnnotateView, AnnotationHistory, AnnotationOverlay, AnnotationProvider, AssessmentEntry, AssessmentPanel, AssistProgress, AssistSection, AssistShell, AsyncErrorBoundary, AuthErrorDisplay, BrowseView, Button, ButtonGroup, COMMON_PANELS, CodeMirrorRenderer, CollaborationPanel, CollapsibleResourceNavigation, CommentEntry, CommentsPanel, ComposeLoadingState, EntityTagsPage, EntityTypeBadges, ErrorBoundary, ExportCard, Footer, HighlightEntry, HighlightPanel, HistoryEvent, ImageBrowseRenderer, ImageURLSchema, ImageViewer, ImportCard, ImportProgress, JsonLdPanel, JsonLdView, KeyboardShortcutsHelpModal, LeftSidebar, LinkedDataPage, LiveRegionProvider, NavigationMenu, OAuthUserSchema, ObservableLink, PageLayout, PanelHeader, PdfBrowseRenderer, PermissionDeniedModal, PopupContainer, PopupHeader, ProtectedErrorBoundary, RESOURCE_PANELS, RecentDocumentsPage, ReferenceEntry, ReferenceResolutionWidget, ReferenceWizardModal, ReferencesPanel, ResizeHandle, ResourceAnnotationsProvider, ResourceCard, ResourceComposePage, ResourceDiscoveryPage, ResourceErrorState, ResourceGenerateModal, ResourceInfoPanel, ResourceLoadingState, ResourceSearchModal, ResourceTagsInline, ResourceViewer, ResourceViewerPage, SearchModal, SelectedTextDisplay, SemiontBranding, SemiontFavicon, SemiontProvider, SessionExpiredModal, SessionExpiryBanner, SessionTimer, SettingsPanel, SignInForm, SignUpForm, SimpleNavigation, SkipLinks, SortableResourceTab, StatisticsPanel, StatusDisplay, SvgDrawingCanvas, TagEntry, TagSchemasPage, TaggingPanel, TextBrowseRenderer, ThemeProvider, ToastContainer, ToastProvider, Toolbar, TranslationProvider, UnifiedAnnotationsPanel, UnifiedHeader, UploadProgressBar, UserMenuSkeleton, WebBrowserStorage, WelcomePage, annotatorKeyForMotivation, applyHighlights, buildSourceToRenderedMap, buildTextNodeIndex, buttonStyles, clearHighlights, createAdminSecurityStateUnit, createAdminUsersStateUnit, createComposePageStateUnit, createDiscoverStateUnit, createEntityTagsStateUnit, createExchangeStateUnit, createResourceLoaderStateUnit, createResourceViewerPageStateUnit, createSessionStateUnit, createShellStateUnit, createWelcomeStateUnit, cssVariables, defaultBrowseRenderers, faviconPaths, formatTime, generateCSSVariables, getResourceIcon, getSelectedShapeForSelectorType, getSelectorType, getShortcutDisplay, getSupportedShapes, hideWidgetPreview, isShapeSupported, jsonLightHighlightStyle, jsonLightTheme, resolveAnnotationRanges, sanitizeImageURL, saveSelectedShapeForSelectorType, setPdfWorkerSrc, showWidgetPreview, supportsDetection, toOverlayAnnotations, tokens, useAnnotationManager, useDebounce, useDebouncedCallback, useDocumentAnnouncements, useDoubleKeyPress, useDropdown, useEventSubscription, useEventSubscriptions, useFormAnnouncements, useHoverDelay, useHoverEmitter, useIsTyping, useKBDiscovery, useKeyboardShortcuts, useLanguageChangeAnnouncements, useLineNumbers, useLiveRegion, useLoadingState, useLocalStorage, useMediaToken, useObservable, useObservableExternalNavigation, useObservableRouter, usePanelWidth, usePendingCreation, usePreloadTranslations, useResourceAnnotations, useResourceContent, useResourceGather, useResourceLoader, useResourceLoadingAnnouncements, useRovingTabIndex, useSearchAnnouncements, useSemiont, useSessionEventSubscriptions, useSessionExpiry, useShellStateUnit, useStateUnit, useTheme, useToast, useToolbarPrefs, useTranslations };
4326
+ export type { AdminDevOpsPageProps, AdminExchangePageProps, AdminExchangePageTranslations, AdminSecurityPageProps, AdminSecurityStateUnit, AdminUser, AdminUserStats, AdminUsersPageProps, AdminUsersStateUnit, AnnotationConfig, AnnotationCreationHandler, AnnotationGroups, AnnotationHandlers, AnnotationManager, AnnotationProviderProps, AnnotationUIState, AnnotationsCollection, Annotator, AnnotatorKey, AssistProgressProps, AssistProgressTranslations, AssistShellProps, AuthErrorDisplayProps, AvailableLocale, BorderRadiusToken, BrowseMediaRenderers, ButtonGroupProps, ButtonProps, ClickAction, CloneData, CollapsibleResourceNavigationProps, ColorToken, ComposeLoadingStateProps, ComposeMode, ComposePageStateUnit, ComposeParams, CreateAnnotationParams, CreateConfig, DeleteAnnotationParams, DetectionConfig, DevOpsFeature, DiscoverStateUnit, DrawingMode, EntityTagsPageProps, EntityTagsStateUnit, ExchangeStateUnit, ExportCardProps, ExportCardTranslations, HoverEmitterProps, ImportCardProps, ImportCardTranslations, ImportPreview, ImportProgressProps, ImportProgressTranslations, KBDiscoveryOptions, KBDiscoveryResult, KeyboardShortcut, LinkComponentProps, LinkedDataPageProps, LinkedDataPageTranslations, MediaRendererProps, Motivation$7 as Motivation, NavigationItem, NavigationMenuHelper, NavigationProps, OAuthProvider, OAuthUser, ObservableLinkProps, OverlayAnnotation, PendingCreation, RecentDocumentsPageProps, ReferenceData, ReferenceHover, ReferenceWizardModalProps, ResolvedTheme, ResourceCardProps, ResourceComposePageProps, ResourceDiscoveryPageProps, ResourceErrorStateProps, ResourceGatherOptions, ResourceGenerateModalProps, ResourceGenerateModalTranslations, ResourceLoaderStateUnit, ResourceSearchModalProps, ResourceViewerPageProps, ResourceViewerPageStateUnit, RouteBuilder, SaveResourceParams$1 as SaveResourceParams, SearchModalProps, SelectionMotivation, SelectorType, SemiontProviderProps, SemiontResource$1 as SemiontResource, SessionStateUnit, ShadowToken, ShapeType, ShellStateUnit, ShellStateUnitOptions, SignInFormProps, SignUpFormProps, SimpleNavigationItem, SimpleNavigationProps, SortableResourceTabProps, SpacingToken, TagSchemasPageProps, TextSegment, TextSelection, Theme, ToastMessage, ToastType, ToolbarPanelType, ToolbarPart, ToolbarPrefs, TransitionToken, TranslationManager, TranslationProviderProps, TypographyToken, UICreateAnnotationParams, UploadProgressBarProps, UseMediaTokenResult, UseResourceContentResult, UseResourceGatherResult, UseResourceLoaderResult, WelcomePageProps, WelcomeStateUnit, WizardState };