@semiont/react-ui 0.2.33-build.82 → 0.2.33-build.84

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 (35) hide show
  1. package/dist/{PdfAnnotationCanvas.client-RAJRPQLU.mjs → PdfAnnotationCanvas.client-FGV33CWN.mjs} +9 -14
  2. package/dist/PdfAnnotationCanvas.client-FGV33CWN.mjs.map +1 -0
  3. package/dist/chunk-FC6SGLLT.mjs +141 -0
  4. package/dist/chunk-FC6SGLLT.mjs.map +1 -0
  5. package/dist/chunk-XS27QKGP.mjs +55 -0
  6. package/dist/chunk-XS27QKGP.mjs.map +1 -0
  7. package/dist/{chunk-QB52Q7EQ.mjs → chunk-YPYLOBA2.mjs} +31 -81
  8. package/dist/chunk-YPYLOBA2.mjs.map +1 -0
  9. package/dist/index.css +16 -0
  10. package/dist/index.css.map +1 -1
  11. package/dist/index.d.mts +24 -1
  12. package/dist/index.mjs +353 -428
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/test-utils.mjs +5 -3
  15. package/dist/test-utils.mjs.map +1 -1
  16. package/package.json +1 -1
  17. package/src/components/CodeMirrorRenderer.tsx +8 -8
  18. package/src/components/annotation/AnnotateToolbar.tsx +4 -1
  19. package/src/components/image-annotation/AnnotationOverlay.tsx +6 -17
  20. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +6 -17
  21. package/src/components/resource/BrowseView.tsx +8 -8
  22. package/src/components/resource/__tests__/BrowseView.test.tsx +20 -12
  23. package/src/components/resource/panels/AssessmentEntry.tsx +3 -6
  24. package/src/components/resource/panels/CommentEntry.tsx +3 -6
  25. package/src/components/resource/panels/HighlightEntry.tsx +3 -6
  26. package/src/components/resource/panels/ReferenceEntry.tsx +3 -6
  27. package/src/components/resource/panels/TagEntry.tsx +3 -6
  28. package/src/components/resource/panels/TaggingPanel.tsx +5 -0
  29. package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +42 -4
  30. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +44 -0
  31. package/src/components/toolbar/Toolbar.css +20 -0
  32. package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +312 -0
  33. package/src/styles/features/resource-viewer.css +203 -0
  34. package/dist/PdfAnnotationCanvas.client-RAJRPQLU.mjs.map +0 -1
  35. package/dist/chunk-QB52Q7EQ.mjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,22 +1,32 @@
1
1
  'use client';
2
+ import {
3
+ HOVER_DELAY_MS,
4
+ createHoverHandlers,
5
+ useAttentionFlow,
6
+ useEventSubscription,
7
+ useEventSubscriptions,
8
+ useHoverEmitter
9
+ } from "./chunk-FC6SGLLT.mjs";
2
10
  import {
3
11
  AVAILABLE_LOCALES,
4
12
  ApiClientProvider,
5
- EventBusProvider,
6
13
  OpenResourcesProvider,
7
14
  SessionProvider,
8
15
  ToastContainer,
9
16
  ToastProvider,
10
17
  TranslationProvider,
11
- resetEventBusForTesting,
12
18
  useApiClient,
13
- useEventBus,
14
19
  useOpenResources,
15
20
  usePreloadTranslations,
16
21
  useSessionContext,
17
22
  useToast,
18
23
  useTranslations
19
- } from "./chunk-QB52Q7EQ.mjs";
24
+ } from "./chunk-YPYLOBA2.mjs";
25
+ import {
26
+ EventBusProvider,
27
+ resetEventBusForTesting,
28
+ useEventBus
29
+ } from "./chunk-XS27QKGP.mjs";
20
30
  import "./chunk-D7NBW4RV.mjs";
21
31
  import {
22
32
  __commonJS,
@@ -18930,59 +18940,8 @@ function useCacheManager() {
18930
18940
  return context;
18931
18941
  }
18932
18942
 
18933
- // src/contexts/useEventSubscription.ts
18934
- import { useEffect as useEffect10, useRef as useRef7, useMemo } from "react";
18935
- function useEventSubscription(eventName, handler) {
18936
- const eventBus = useEventBus();
18937
- const handlerRef = useRef7(handler);
18938
- useEffect10(() => {
18939
- handlerRef.current = handler;
18940
- });
18941
- useEffect10(() => {
18942
- const stableHandler = (payload) => {
18943
- handlerRef.current(payload);
18944
- };
18945
- eventBus.on(eventName, stableHandler);
18946
- return () => {
18947
- eventBus.off(eventName, stableHandler);
18948
- };
18949
- }, [eventName]);
18950
- }
18951
- function useEventSubscriptions(subscriptions) {
18952
- const eventBus = useEventBus();
18953
- const handlersRef = useRef7(subscriptions);
18954
- useEffect10(() => {
18955
- handlersRef.current = subscriptions;
18956
- });
18957
- const eventNames = useMemo(
18958
- () => Object.keys(subscriptions).sort(),
18959
- // eslint-disable-next-line react-hooks/exhaustive-deps
18960
- [Object.keys(subscriptions).sort().join(",")]
18961
- );
18962
- useEffect10(() => {
18963
- const stableHandlers = /* @__PURE__ */ new Map();
18964
- for (const eventName of eventNames) {
18965
- const stableHandler = (payload) => {
18966
- const currentHandler = handlersRef.current[eventName];
18967
- if (currentHandler) {
18968
- currentHandler(payload);
18969
- } else {
18970
- console.warn("[useEventSubscriptions] No current handler found for:", eventName);
18971
- }
18972
- };
18973
- stableHandlers.set(eventName, stableHandler);
18974
- eventBus.on(eventName, stableHandler);
18975
- }
18976
- return () => {
18977
- for (const [eventName, stableHandler] of stableHandlers) {
18978
- eventBus.off(eventName, stableHandler);
18979
- }
18980
- };
18981
- }, [eventNames]);
18982
- }
18983
-
18984
18943
  // src/contexts/ResourceAnnotationsContext.tsx
18985
- import { createContext as createContext6, useContext as useContext6, useState as useState9, useCallback as useCallback9, useMemo as useMemo2 } from "react";
18944
+ import { createContext as createContext6, useContext as useContext6, useState as useState9, useCallback as useCallback9, useMemo } from "react";
18986
18945
 
18987
18946
  // src/components/LiveRegion.tsx
18988
18947
  import { useState as useState8, createContext as createContext5, useContext as useContext5, useCallback as useCallback8 } from "react";
@@ -19198,7 +19157,7 @@ function ResourceAnnotationsProvider({ children }) {
19198
19157
  });
19199
19158
  }, 6e3);
19200
19159
  }, []);
19201
- const contextValue = useMemo2(
19160
+ const contextValue = useMemo(
19202
19161
  () => ({
19203
19162
  newAnnotationIds,
19204
19163
  createAnnotation,
@@ -19218,7 +19177,7 @@ function useResourceAnnotations() {
19218
19177
  }
19219
19178
 
19220
19179
  // src/components/CodeMirrorRenderer.tsx
19221
- import { useEffect as useEffect11, useRef as useRef8 } from "react";
19180
+ import { useEffect as useEffect10, useRef as useRef7 } from "react";
19222
19181
 
19223
19182
  // ../../node_modules/@codemirror/autocomplete/dist/index.js
19224
19183
  var CompletionContext = class {
@@ -26693,18 +26652,18 @@ function CodeMirrorRenderer({
26693
26652
  getTargetDocumentName,
26694
26653
  generatingReferenceId
26695
26654
  }) {
26696
- const containerRef = useRef8(null);
26697
- const viewRef = useRef8(null);
26698
- const contentRef = useRef8(content4);
26655
+ const containerRef = useRef7(null);
26656
+ const viewRef = useRef7(null);
26657
+ const contentRef = useRef7(content4);
26699
26658
  const convertedSegments = convertSegmentPositions(segments, content4);
26700
- const segmentsRef = useRef8(convertedSegments);
26701
- const lineNumbersCompartment = useRef8(new Compartment());
26702
- const eventBusRef = useRef8(eventBus);
26703
- const getTargetDocumentNameRef = useRef8(getTargetDocumentName);
26659
+ const segmentsRef = useRef7(convertedSegments);
26660
+ const lineNumbersCompartment = useRef7(new Compartment());
26661
+ const eventBusRef = useRef7(eventBus);
26662
+ const getTargetDocumentNameRef = useRef7(getTargetDocumentName);
26704
26663
  segmentsRef.current = segments;
26705
26664
  eventBusRef.current = eventBus;
26706
26665
  getTargetDocumentNameRef.current = getTargetDocumentName;
26707
- useEffect11(() => {
26666
+ useEffect10(() => {
26708
26667
  if (!containerRef.current || viewRef.current) return;
26709
26668
  const annotationDecorationsField = createAnnotationDecorationsField();
26710
26669
  const state = EditorState.create({
@@ -26794,31 +26753,31 @@ function CodeMirrorRenderer({
26794
26753
  contentRef.current = content4;
26795
26754
  containerRef.current.__cmView = view;
26796
26755
  const container = view.dom;
26756
+ const { handleMouseEnter, handleMouseLeave, cleanup: cleanupHover } = createHoverHandlers(
26757
+ (annotationId) => eventBusRef.current?.emit("annotation:hover", { annotationId })
26758
+ );
26797
26759
  const handleMouseOver = (e6) => {
26798
26760
  const target = e6.target;
26799
26761
  const annotationElement = target.closest("[data-annotation-id]");
26800
26762
  const annotationId = annotationElement?.getAttribute("data-annotation-id");
26801
- if (annotationId && eventBusRef.current) {
26802
- eventBusRef.current.emit("annotation:hover", { annotationId });
26803
- }
26763
+ if (annotationId) handleMouseEnter(annotationId);
26804
26764
  };
26805
26765
  const handleMouseOut = (e6) => {
26806
26766
  const target = e6.target;
26807
26767
  const annotationElement = target.closest("[data-annotation-id]");
26808
- if (annotationElement && eventBusRef.current) {
26809
- eventBusRef.current.emit("annotation:hover", { annotationId: null });
26810
- }
26768
+ if (annotationElement) handleMouseLeave();
26811
26769
  };
26812
26770
  container.addEventListener("mouseover", handleMouseOver);
26813
26771
  container.addEventListener("mouseout", handleMouseOut);
26814
26772
  return () => {
26815
26773
  container.removeEventListener("mouseover", handleMouseOver);
26816
26774
  container.removeEventListener("mouseout", handleMouseOut);
26775
+ cleanupHover();
26817
26776
  view.destroy();
26818
26777
  viewRef.current = null;
26819
26778
  };
26820
26779
  }, []);
26821
- useEffect11(() => {
26780
+ useEffect10(() => {
26822
26781
  if (!viewRef.current) return;
26823
26782
  const currentContent = viewRef.current.state.doc.toString();
26824
26783
  if (content4 === currentContent) return;
@@ -26834,19 +26793,19 @@ function CodeMirrorRenderer({
26834
26793
  });
26835
26794
  contentRef.current = content4;
26836
26795
  }, [content4]);
26837
- useEffect11(() => {
26796
+ useEffect10(() => {
26838
26797
  if (!viewRef.current) return;
26839
26798
  viewRef.current.dispatch({
26840
26799
  effects: lineNumbersCompartment.current.reconfigure(showLineNumbers ? lineNumbers() : [])
26841
26800
  });
26842
26801
  }, [showLineNumbers]);
26843
- useEffect11(() => {
26802
+ useEffect10(() => {
26844
26803
  if (!viewRef.current) return;
26845
26804
  viewRef.current.dispatch({
26846
26805
  effects: updateAnnotationsEffect.of({ segments: convertedSegments, ...newAnnotationIds && { newAnnotationIds } })
26847
26806
  });
26848
26807
  }, [convertedSegments, newAnnotationIds]);
26849
- useEffect11(() => {
26808
+ useEffect10(() => {
26850
26809
  if (!viewRef.current || !enableWidgets) return;
26851
26810
  viewRef.current.dispatch({
26852
26811
  effects: updateWidgetsEffect.of({
@@ -26858,7 +26817,7 @@ function CodeMirrorRenderer({
26858
26817
  })
26859
26818
  });
26860
26819
  }, [content4, convertedSegments, enableWidgets, generatingReferenceId]);
26861
- useEffect11(() => {
26820
+ useEffect10(() => {
26862
26821
  if (!viewRef.current || !hoveredAnnotationId) return void 0;
26863
26822
  const view = viewRef.current;
26864
26823
  const element2 = view.contentDOM.querySelector(
@@ -26886,7 +26845,7 @@ function CodeMirrorRenderer({
26886
26845
  element2.classList.remove("annotation-pulse");
26887
26846
  };
26888
26847
  }, [hoveredAnnotationId]);
26889
- useEffect11(() => {
26848
+ useEffect10(() => {
26890
26849
  if (!viewRef.current || !hoveredCommentId) return void 0;
26891
26850
  const view = viewRef.current;
26892
26851
  const element2 = view.contentDOM.querySelector(
@@ -26914,7 +26873,7 @@ function CodeMirrorRenderer({
26914
26873
  element2.classList.remove("annotation-pulse");
26915
26874
  };
26916
26875
  }, [hoveredCommentId]);
26917
- useEffect11(() => {
26876
+ useEffect10(() => {
26918
26877
  if (!viewRef.current || !scrollToAnnotationId) return;
26919
26878
  const view = viewRef.current;
26920
26879
  const element2 = view.contentDOM.querySelector(
@@ -27113,7 +27072,7 @@ function AsyncErrorBoundary({ children }) {
27113
27072
  }
27114
27073
 
27115
27074
  // src/components/ResizeHandle.tsx
27116
- import { useRef as useRef9, useCallback as useCallback10, useEffect as useEffect12, useState as useState10 } from "react";
27075
+ import { useRef as useRef8, useCallback as useCallback10, useEffect as useEffect11, useState as useState10 } from "react";
27117
27076
  import { jsx as jsx11 } from "react/jsx-runtime";
27118
27077
  function ResizeHandle({
27119
27078
  onResize,
@@ -27123,10 +27082,10 @@ function ResizeHandle({
27123
27082
  ariaLabel = "Resize panel"
27124
27083
  }) {
27125
27084
  const [isDragging, setIsDragging] = useState10(false);
27126
- const startXRef = useRef9(0);
27127
- const startWidthRef = useRef9(0);
27128
- const onResizeRef = useRef9(onResize);
27129
- useEffect12(() => {
27085
+ const startXRef = useRef8(0);
27086
+ const startWidthRef = useRef8(0);
27087
+ const onResizeRef = useRef8(onResize);
27088
+ useEffect11(() => {
27130
27089
  onResizeRef.current = onResize;
27131
27090
  });
27132
27091
  const handleMouseDown = useCallback10((e6) => {
@@ -27177,7 +27136,7 @@ function ResizeHandle({
27177
27136
  onResizeRef.current(constrainedWidth);
27178
27137
  }
27179
27138
  }, [minWidth, maxWidth, position3]);
27180
- useEffect12(() => {
27139
+ useEffect11(() => {
27181
27140
  if (isDragging) {
27182
27141
  document.addEventListener("mousemove", handleMouseMove);
27183
27142
  document.addEventListener("mouseup", handleMouseUp);
@@ -27335,7 +27294,7 @@ function Toolbar({
27335
27294
  }
27336
27295
 
27337
27296
  // src/components/settings/SettingsPanel.tsx
27338
- import React6, { useEffect as useEffect13 } from "react";
27297
+ import React6, { useEffect as useEffect12 } from "react";
27339
27298
  import { LOCALES } from "@semiont/api-client";
27340
27299
  import { jsx as jsx14, jsxs as jsxs5 } from "react/jsx-runtime";
27341
27300
  function SettingsPanel({
@@ -27353,7 +27312,7 @@ function SettingsPanel({
27353
27312
  announceLanguageChanging(localeName);
27354
27313
  eventBus.emit("settings:locale-changed", { locale: newLocale });
27355
27314
  };
27356
- useEffect13(() => {
27315
+ useEffect12(() => {
27357
27316
  if (locale !== previousLocale && !isPendingLocaleChange) {
27358
27317
  const localeName = LOCALES.find((l10) => l10.code === locale)?.nativeName || locale;
27359
27318
  announceLanguageChanged(localeName);
@@ -27450,7 +27409,7 @@ function SettingsPanel({
27450
27409
  }
27451
27410
 
27452
27411
  // src/components/annotation/AnnotateToolbar.tsx
27453
- import React7, { useState as useState11, useRef as useRef10, useEffect as useEffect14 } from "react";
27412
+ import React7, { useState as useState11, useRef as useRef9, useEffect as useEffect13 } from "react";
27454
27413
  import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
27455
27414
  function DropdownGroup({
27456
27415
  label,
@@ -27461,7 +27420,7 @@ function DropdownGroup({
27461
27420
  onPin,
27462
27421
  containerRef
27463
27422
  }) {
27464
- const dropdownRef = useRef10(null);
27423
+ const dropdownRef = useRef9(null);
27465
27424
  const handleKeyDown = (event) => {
27466
27425
  if (event.key === "Enter" || event.key === " ") {
27467
27426
  event.preventDefault();
@@ -27532,15 +27491,15 @@ function AnnotateToolbar({
27532
27491
  const [selectionPinned, setSelectionPinned] = useState11(false);
27533
27492
  const [shapeHovered, setShapeHovered] = useState11(false);
27534
27493
  const [shapePinned, setShapePinned] = useState11(false);
27535
- const modeRef = useRef10(null);
27536
- const clickRef = useRef10(null);
27537
- const selectionRef = useRef10(null);
27538
- const shapeRef = useRef10(null);
27494
+ const modeRef = useRef9(null);
27495
+ const clickRef = useRef9(null);
27496
+ const selectionRef = useRef9(null);
27497
+ const shapeRef = useRef9(null);
27539
27498
  const modeExpanded = modeHovered || modePinned;
27540
27499
  const clickExpanded = clickHovered || clickPinned;
27541
27500
  const selectionExpanded = selectionHovered || selectionPinned;
27542
27501
  const shapeExpanded = shapeHovered || shapePinned;
27543
- useEffect14(() => {
27502
+ useEffect13(() => {
27544
27503
  const handleClickOutside = (event) => {
27545
27504
  if (modePinned && modeRef.current && !modeRef.current.contains(event.target)) {
27546
27505
  setModePinned(false);
@@ -27558,7 +27517,7 @@ function AnnotateToolbar({
27558
27517
  document.addEventListener("mousedown", handleClickOutside);
27559
27518
  return () => document.removeEventListener("mousedown", handleClickOutside);
27560
27519
  }, [modePinned, clickPinned, selectionPinned, shapePinned]);
27561
- useEffect14(() => {
27520
+ useEffect13(() => {
27562
27521
  const handleEscape = (event) => {
27563
27522
  if (event.key === "Escape") {
27564
27523
  setModePinned(false);
@@ -27658,10 +27617,17 @@ function AnnotateToolbar({
27658
27617
  onHoverChange: setClickHovered,
27659
27618
  onPin: () => setClickPinned(!clickPinned),
27660
27619
  containerRef: clickRef,
27661
- collapsedContent: /* @__PURE__ */ jsxs6("div", { className: "semiont-dropdown-display", children: [
27662
- /* @__PURE__ */ jsx15("span", { className: "semiont-dropdown-icon", children: clickActions.find((a15) => a15.action === selectedClick)?.icon }),
27663
- /* @__PURE__ */ jsx15("span", { className: "semiont-dropdown-label", children: clickActions.find((a15) => a15.action === selectedClick)?.label })
27664
- ] }),
27620
+ collapsedContent: /* @__PURE__ */ jsxs6(
27621
+ "div",
27622
+ {
27623
+ className: "semiont-dropdown-display",
27624
+ "data-delete": clickActions.find((a15) => a15.action === selectedClick)?.isDelete ? "true" : "false",
27625
+ children: [
27626
+ /* @__PURE__ */ jsx15("span", { className: "semiont-dropdown-icon", children: clickActions.find((a15) => a15.action === selectedClick)?.icon }),
27627
+ /* @__PURE__ */ jsx15("span", { className: "semiont-dropdown-label", children: clickActions.find((a15) => a15.action === selectedClick)?.label })
27628
+ ]
27629
+ }
27630
+ ),
27665
27631
  expandedContent: /* @__PURE__ */ jsx15(Fragment2, { children: clickActions.map(({ action, icon, label, isDelete }) => /* @__PURE__ */ jsx15(React7.Fragment, { children: renderButton(icon, label, selectedClick === action, () => handleClickClick(action), isDelete) }, action)) })
27666
27632
  }
27667
27633
  ),
@@ -27733,7 +27699,7 @@ function AnnotateToolbar({
27733
27699
  }
27734
27700
 
27735
27701
  // src/components/annotation-popups/JsonLdView.tsx
27736
- import { useEffect as useEffect15, useRef as useRef11 } from "react";
27702
+ import { useEffect as useEffect14, useRef as useRef10 } from "react";
27737
27703
 
27738
27704
  // ../../node_modules/@lezer/json/dist/index.js
27739
27705
  var jsonHighlighting = styleTags({
@@ -27937,14 +27903,14 @@ var oneDark = [oneDarkTheme, /* @__PURE__ */ syntaxHighlighting(oneDarkHighlight
27937
27903
  // src/components/annotation-popups/JsonLdView.tsx
27938
27904
  import { jsx as jsx16, jsxs as jsxs7 } from "react/jsx-runtime";
27939
27905
  function JsonLdView({ annotation, onBack }) {
27940
- const editorRef = useRef11(null);
27941
- const viewRef = useRef11(null);
27906
+ const editorRef = useRef10(null);
27907
+ const viewRef = useRef10(null);
27942
27908
  const { showLineNumbers } = useLineNumbers();
27943
- const onBackRef = useRef11(onBack);
27944
- useEffect15(() => {
27909
+ const onBackRef = useRef10(onBack);
27910
+ useEffect14(() => {
27945
27911
  onBackRef.current = onBack;
27946
27912
  });
27947
- useEffect15(() => {
27913
+ useEffect14(() => {
27948
27914
  const handleKeyDown = (e6) => {
27949
27915
  if (e6.key === "Escape") {
27950
27916
  onBackRef.current();
@@ -27953,7 +27919,7 @@ function JsonLdView({ annotation, onBack }) {
27953
27919
  window.addEventListener("keydown", handleKeyDown);
27954
27920
  return () => window.removeEventListener("keydown", handleKeyDown);
27955
27921
  }, []);
27956
- useEffect15(() => {
27922
+ useEffect14(() => {
27957
27923
  if (!editorRef.current) return;
27958
27924
  const isDarkMode = document.documentElement.classList.contains("dark");
27959
27925
  const jsonContent = JSON.stringify(annotation, null, 2);
@@ -29623,7 +29589,7 @@ function PopupContainer({ children, position: position3, onClose, isOpen, wide =
29623
29589
  }
29624
29590
 
29625
29591
  // src/components/image-annotation/AnnotationOverlay.tsx
29626
- import { useRef as useRef12 } from "react";
29592
+ import { useMemo as useMemo2 } from "react";
29627
29593
  import { getSvgSelector, isHighlight as isHighlight3, isReference as isReference3, isAssessment as isAssessment2, isComment as isComment3, isTag as isTag4, isBodyResolved, isResolvedReference as isResolvedReference3 } from "@semiont/api-client";
29628
29594
  import { parseSvgSelector } from "@semiont/api-client";
29629
29595
  import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
@@ -29669,19 +29635,10 @@ function AnnotationOverlay({
29669
29635
  }) {
29670
29636
  const scaleX = displayWidth / imageWidth;
29671
29637
  const scaleY = displayHeight / imageHeight;
29672
- const currentHover = useRef12(null);
29673
- const handleMouseEnter = (annotationId) => {
29674
- if (currentHover.current !== annotationId) {
29675
- currentHover.current = annotationId;
29676
- eventBus?.emit("annotation:hover", { annotationId });
29677
- }
29678
- };
29679
- const handleMouseLeave = () => {
29680
- if (currentHover.current !== null) {
29681
- currentHover.current = null;
29682
- eventBus?.emit("annotation:hover", { annotationId: null });
29683
- }
29684
- };
29638
+ const { handleMouseEnter, handleMouseLeave } = useMemo2(
29639
+ () => createHoverHandlers((annotationId) => eventBus?.emit("annotation:hover", { annotationId })),
29640
+ [eventBus]
29641
+ );
29685
29642
  return /* @__PURE__ */ jsx18(
29686
29643
  "svg",
29687
29644
  {
@@ -29847,7 +29804,7 @@ function AnnotationOverlay({
29847
29804
  }
29848
29805
 
29849
29806
  // src/components/image-annotation/SvgDrawingCanvas.tsx
29850
- import { useRef as useRef13, useState as useState13, useEffect as useEffect17, useCallback as useCallback11, useMemo as useMemo3 } from "react";
29807
+ import { useRef as useRef11, useState as useState13, useEffect as useEffect16, useCallback as useCallback11, useMemo as useMemo3 } from "react";
29851
29808
  import { createRectangleSvg, createCircleSvg, createPolygonSvg, scaleSvgToNative, parseSvgSelector as parseSvgSelector2 } from "@semiont/api-client";
29852
29809
  import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
29853
29810
  function getMotivationColor(motivation) {
@@ -29884,14 +29841,14 @@ function SvgDrawingCanvas({
29884
29841
  const resourceId = resourceUri2.split("/").pop();
29885
29842
  return `/api/resources/${resourceId}`;
29886
29843
  }, [resourceUri2]);
29887
- const containerRef = useRef13(null);
29888
- const imageRef = useRef13(null);
29844
+ const containerRef = useRef11(null);
29845
+ const imageRef = useRef11(null);
29889
29846
  const [imageDimensions, setImageDimensions] = useState13(null);
29890
29847
  const [displayDimensions, setDisplayDimensions] = useState13(null);
29891
29848
  const [isDrawing, setIsDrawing] = useState13(false);
29892
29849
  const [startPoint, setStartPoint] = useState13(null);
29893
29850
  const [currentPoint, setCurrentPoint] = useState13(null);
29894
- useEffect17(() => {
29851
+ useEffect16(() => {
29895
29852
  const img = new Image();
29896
29853
  img.onload = () => {
29897
29854
  setImageDimensions({
@@ -29901,7 +29858,7 @@ function SvgDrawingCanvas({
29901
29858
  };
29902
29859
  img.src = imageUrl;
29903
29860
  }, [imageUrl]);
29904
- useEffect17(() => {
29861
+ useEffect16(() => {
29905
29862
  const updateDisplayDimensions = () => {
29906
29863
  if (imageRef.current) {
29907
29864
  setDisplayDimensions({
@@ -30337,7 +30294,7 @@ function KeyboardShortcutsHelpModal({ isOpen, onClose }) {
30337
30294
  }
30338
30295
 
30339
30296
  // src/components/modals/ProposeEntitiesModal.tsx
30340
- import { useEffect as useEffect18, useState as useState14, Fragment as Fragment5 } from "react";
30297
+ import { useEffect as useEffect17, useState as useState14, Fragment as Fragment5 } from "react";
30341
30298
  import { jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
30342
30299
  var STORAGE_KEY = "userPreferredEntityTypes";
30343
30300
  function ProposeEntitiesModal({
@@ -30349,7 +30306,7 @@ function ProposeEntitiesModal({
30349
30306
  const entityTypesAPI = useEntityTypes();
30350
30307
  const { data: entityTypesData } = entityTypesAPI.list.useQuery();
30351
30308
  const allEntityTypes = entityTypesData?.entityTypes || [];
30352
- useEffect18(() => {
30309
+ useEffect17(() => {
30353
30310
  if (isOpen) {
30354
30311
  try {
30355
30312
  const saved = sessionStorage.getItem(STORAGE_KEY);
@@ -30459,11 +30416,11 @@ function ProposeEntitiesModal({
30459
30416
  }
30460
30417
 
30461
30418
  // src/components/resource/AnnotateView.tsx
30462
- import { useRef as useRef14, useEffect as useEffect19, useCallback as useCallback12, lazy, Suspense } from "react";
30419
+ import { useRef as useRef12, useEffect as useEffect18, useCallback as useCallback12, lazy, Suspense } from "react";
30463
30420
  import { getTextPositionSelector, getTextQuoteSelector, getTargetSelector, getMimeCategory, isPdfMimeType as isPdfMimeType2, resourceUri as toResourceUri } from "@semiont/api-client";
30464
30421
  import { findTextWithContext } from "@semiont/api-client";
30465
30422
  import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
30466
- var PdfAnnotationCanvas = lazy(() => import("./PdfAnnotationCanvas.client-RAJRPQLU.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
30423
+ var PdfAnnotationCanvas = lazy(() => import("./PdfAnnotationCanvas.client-FGV33CWN.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
30467
30424
  function extractContext(content4, start2, end) {
30468
30425
  const CONTEXT_LENGTH = 32;
30469
30426
  const result = {};
@@ -30545,14 +30502,14 @@ function AnnotateView({
30545
30502
  annotateMode
30546
30503
  }) {
30547
30504
  const { newAnnotationIds } = useResourceAnnotations();
30548
- const containerRef = useRef14(null);
30505
+ const containerRef = useRef12(null);
30549
30506
  const eventBus = useEventBus();
30550
30507
  const category = getMimeCategory(mimeType);
30551
30508
  const { highlights, references, assessments, comments, tags: tags3 } = annotations;
30552
30509
  const allAnnotations = [...highlights, ...references, ...assessments, ...comments, ...tags3];
30553
30510
  const segments = segmentTextWithAnnotations(content4, allAnnotations);
30554
30511
  const { selectedMotivation, selectedClick, selectedShape, hoveredAnnotationId, hoveredCommentId, scrollToAnnotationId } = uiState;
30555
- const onUIStateChangeRef = useRef14(onUIStateChange);
30512
+ const onUIStateChangeRef = useRef12(onUIStateChange);
30556
30513
  onUIStateChangeRef.current = onUIStateChange;
30557
30514
  const handleToolbarSelectionChanged = useCallback12(({ motivation }) => {
30558
30515
  onUIStateChangeRef.current?.({ selectedMotivation: motivation });
@@ -30572,7 +30529,7 @@ function AnnotateView({
30572
30529
  "toolbar:shape-changed": handleToolbarShapeChanged,
30573
30530
  "annotation:hover": handleAnnotationHover
30574
30531
  });
30575
- useEffect19(() => {
30532
+ useEffect18(() => {
30576
30533
  const container = containerRef.current;
30577
30534
  if (!container) return;
30578
30535
  let clickedOnAnnotation = false;
@@ -30769,11 +30726,11 @@ function AnnotateView({
30769
30726
  }
30770
30727
 
30771
30728
  // src/components/resource/AnnotationHistory.tsx
30772
- import { useEffect as useEffect21, useRef as useRef16 } from "react";
30729
+ import { useEffect as useEffect20, useRef as useRef14 } from "react";
30773
30730
  import { getAnnotationUriFromEvent as getAnnotationUriFromEvent2 } from "@semiont/core";
30774
30731
 
30775
30732
  // src/components/resource/HistoryEvent.tsx
30776
- import { useRef as useRef15, useCallback as useCallback13, useEffect as useEffect20 } from "react";
30733
+ import { useRef as useRef13, useCallback as useCallback13, useEffect as useEffect19 } from "react";
30777
30734
  import { getAnnotationUriFromEvent } from "@semiont/core";
30778
30735
 
30779
30736
  // src/components/resource/event-formatting.ts
@@ -31013,9 +30970,9 @@ function HistoryEvent({
31013
30970
  const annotationUri2 = getAnnotationUriFromEvent(event);
31014
30971
  const creationDetails = getResourceCreationDetails(event);
31015
30972
  const entityTypes = getEventEntityTypes(event);
31016
- const hoverTimeoutRef = useRef15(null);
31017
- const onEventHoverRef = useRef15(onEventHover);
31018
- useEffect20(() => {
30973
+ const hoverTimeoutRef = useRef13(null);
30974
+ const onEventHoverRef = useRef13(onEventHover);
30975
+ useEffect19(() => {
31019
30976
  onEventHoverRef.current = onEventHover;
31020
30977
  });
31021
30978
  const handleEmojiMouseEnter = useCallback13(() => {
@@ -31119,15 +31076,15 @@ function AnnotationHistory({ rUri, hoveredAnnotationId, onEventHover, onEventCli
31119
31076
  const { data: eventsData, isLoading: loading, isError: error } = resources.events.useQuery(rUri);
31120
31077
  const { data: annotationsData } = resources.annotations.useQuery(rUri);
31121
31078
  const annotations = annotationsData?.annotations || [];
31122
- const eventRefs = useRef16(/* @__PURE__ */ new Map());
31123
- const containerRef = useRef16(null);
31079
+ const eventRefs = useRef14(/* @__PURE__ */ new Map());
31080
+ const containerRef = useRef14(null);
31124
31081
  const events2 = !eventsData?.events ? [] : [...eventsData.events].filter((e6) => {
31125
31082
  const eventType = e6.event.type;
31126
31083
  return eventType !== "job.started" && eventType !== "job.progress" && eventType !== "job.completed";
31127
31084
  }).sort(
31128
31085
  (a15, b8) => a15.metadata.sequenceNumber - b8.metadata.sequenceNumber
31129
31086
  );
31130
- useEffect21(() => {
31087
+ useEffect20(() => {
31131
31088
  if (containerRef.current && events2.length > 0) {
31132
31089
  requestAnimationFrame(() => {
31133
31090
  if (containerRef.current) {
@@ -31136,7 +31093,7 @@ function AnnotationHistory({ rUri, hoveredAnnotationId, onEventHover, onEventCli
31136
31093
  });
31137
31094
  }
31138
31095
  }, [events2.length]);
31139
- useEffect21(() => {
31096
+ useEffect20(() => {
31140
31097
  if (!hoveredAnnotationId) return;
31141
31098
  const eventElement = eventRefs.current.get(hoveredAnnotationId);
31142
31099
  if (eventElement && containerRef.current) {
@@ -31194,7 +31151,7 @@ function AnnotationHistory({ rUri, hoveredAnnotationId, onEventHover, onEventCli
31194
31151
  }
31195
31152
 
31196
31153
  // src/components/resource/BrowseView.tsx
31197
- import { useEffect as useEffect23, useRef as useRef17, useCallback as useCallback14, lazy as lazy2, Suspense as Suspense2 } from "react";
31154
+ import { useEffect as useEffect22, useRef as useRef15, useCallback as useCallback14, lazy as lazy2, Suspense as Suspense2 } from "react";
31198
31155
 
31199
31156
  // ../../node_modules/devlop/lib/default.js
31200
31157
  function ok2() {
@@ -33069,7 +33026,7 @@ var urlAttributes = {
33069
33026
 
33070
33027
  // ../../node_modules/react-markdown/lib/index.js
33071
33028
  import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
33072
- import { useEffect as useEffect22, useState as useState15 } from "react";
33029
+ import { useEffect as useEffect21, useState as useState15 } from "react";
33073
33030
 
33074
33031
  // ../../node_modules/mdast-util-to-string/lib/index.js
33075
33032
  var emptyOptions2 = {};
@@ -45527,7 +45484,7 @@ function ImageViewer({ resourceUri: resourceUri2, alt = "Resource image" }) {
45527
45484
 
45528
45485
  // src/components/resource/BrowseView.tsx
45529
45486
  import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
45530
- var PdfAnnotationCanvas2 = lazy2(() => import("./PdfAnnotationCanvas.client-RAJRPQLU.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
45487
+ var PdfAnnotationCanvas2 = lazy2(() => import("./PdfAnnotationCanvas.client-FGV33CWN.mjs").then((mod) => ({ default: mod.PdfAnnotationCanvas })));
45531
45488
  function prepareAnnotations(annotations) {
45532
45489
  return annotations.map((ann) => {
45533
45490
  const targetSelector = getTargetSelector3(ann.target);
@@ -45557,12 +45514,12 @@ function BrowseView({
45557
45514
  }) {
45558
45515
  const { newAnnotationIds } = useResourceAnnotations();
45559
45516
  const eventBus = useEventBus();
45560
- const containerRef = useRef17(null);
45517
+ const containerRef = useRef15(null);
45561
45518
  const category = getMimeCategory2(mimeType);
45562
45519
  const { highlights, references, assessments, comments, tags: tags3 } = annotations;
45563
45520
  const allAnnotations = [...highlights, ...references, ...assessments, ...comments, ...tags3];
45564
45521
  const preparedAnnotations = prepareAnnotations(allAnnotations);
45565
- useEffect23(() => {
45522
+ useEffect22(() => {
45566
45523
  if (!containerRef.current) return;
45567
45524
  const container = containerRef.current;
45568
45525
  const handleClick = (e6) => {
@@ -45578,20 +45535,19 @@ function BrowseView({
45578
45535
  }
45579
45536
  }
45580
45537
  };
45538
+ const { handleMouseEnter, handleMouseLeave, cleanup: cleanupHover } = createHoverHandlers(
45539
+ (annotationId) => eventBus.emit("annotation:hover", { annotationId })
45540
+ );
45581
45541
  const handleMouseOver = (e6) => {
45582
45542
  const target = e6.target;
45583
45543
  const annotationElement = target.closest("[data-annotation-id]");
45584
45544
  const annotationId = annotationElement?.getAttribute("data-annotation-id");
45585
- if (annotationId) {
45586
- eventBus.emit("annotation:hover", { annotationId });
45587
- }
45545
+ if (annotationId) handleMouseEnter(annotationId);
45588
45546
  };
45589
45547
  const handleMouseOut = (e6) => {
45590
45548
  const target = e6.target;
45591
45549
  const annotationElement = target.closest("[data-annotation-id]");
45592
- if (annotationElement) {
45593
- eventBus.emit("annotation:hover", { annotationId: null });
45594
- }
45550
+ if (annotationElement) handleMouseLeave();
45595
45551
  };
45596
45552
  if (newAnnotationIds) {
45597
45553
  const annotationSpans = container.querySelectorAll("[data-annotation-id]");
@@ -45609,6 +45565,7 @@ function BrowseView({
45609
45565
  container.removeEventListener("click", handleClick);
45610
45566
  container.removeEventListener("mouseover", handleMouseOver);
45611
45567
  container.removeEventListener("mouseout", handleMouseOut);
45568
+ cleanupHover();
45612
45569
  };
45613
45570
  }, [content4, allAnnotations, newAnnotationIds]);
45614
45571
  const scrollToAnnotation = useCallback14((annotationId, removePulse = false) => {
@@ -45741,7 +45698,7 @@ function BrowseView({
45741
45698
  }
45742
45699
 
45743
45700
  // src/components/resource/ResourceViewer.tsx
45744
- import { useState as useState16, useEffect as useEffect24, useCallback as useCallback15, useRef as useRef18 } from "react";
45701
+ import { useState as useState16, useEffect as useEffect23, useCallback as useCallback15, useRef as useRef16 } from "react";
45745
45702
  import { getExactText as getExactText3, getTargetSelector as getTargetSelector4, resourceUri, isHighlight as isHighlight4, isAssessment as isAssessment3, isReference as isReference4, isComment as isComment4, isTag as isTag5, getBodySource as getBodySource4 } from "@semiont/api-client";
45746
45703
  import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
45747
45704
  function ResourceViewer({
@@ -45752,7 +45709,7 @@ function ResourceViewer({
45752
45709
  hoveredAnnotationId: hoveredAnnotationIdProp
45753
45710
  }) {
45754
45711
  const t12 = useTranslations("ResourceViewer");
45755
- const documentViewerRef = useRef18(null);
45712
+ const documentViewerRef = useRef16(null);
45756
45713
  const eventBus = useEventBus();
45757
45714
  const navigate = useObservableExternalNavigation();
45758
45715
  const { highlights, references, assessments, comments, tags: tags3 } = annotations;
@@ -45774,7 +45731,7 @@ function ResourceViewer({
45774
45731
  }
45775
45732
  return false;
45776
45733
  });
45777
- useEffect24(() => {
45734
+ useEffect23(() => {
45778
45735
  if (typeof window !== "undefined") {
45779
45736
  localStorage.setItem("annotateMode", annotateMode.toString());
45780
45737
  }
@@ -45831,20 +45788,20 @@ function ResourceViewer({
45831
45788
  const handleToolbarShapeChanged = useCallback15(({ shape }) => {
45832
45789
  setSelectedShape(shape);
45833
45790
  }, []);
45834
- useEffect24(() => {
45791
+ useEffect23(() => {
45835
45792
  if (selectedMotivation === null) {
45836
45793
  localStorage.setItem("semiont-toolbar-selection", "null");
45837
45794
  } else {
45838
45795
  localStorage.setItem("semiont-toolbar-selection", selectedMotivation);
45839
45796
  }
45840
45797
  }, [selectedMotivation]);
45841
- useEffect24(() => {
45798
+ useEffect23(() => {
45842
45799
  localStorage.setItem("semiont-toolbar-click", selectedClick);
45843
45800
  }, [selectedClick]);
45844
- useEffect24(() => {
45801
+ useEffect23(() => {
45845
45802
  saveSelectedShapeForSelectorType(selectorType, selectedShape);
45846
45803
  }, [selectorType, selectedShape]);
45847
- useEffect24(() => {
45804
+ useEffect23(() => {
45848
45805
  const shapeForType = getSelectedShapeForSelectorType(selectorType);
45849
45806
  if (shapeForType !== selectedShape) {
45850
45807
  setSelectedShape(shapeForType);
@@ -46095,6 +46052,7 @@ var AssessmentEntry = forwardRef(
46095
46052
  isHovered = false
46096
46053
  }, ref) {
46097
46054
  const eventBus = useEventBus();
46055
+ const hoverProps = useHoverEmitter(assessment.id);
46098
46056
  const selectedText = getAnnotationExactText(assessment);
46099
46057
  const assessmentText = getAssessmentText(assessment);
46100
46058
  return /* @__PURE__ */ jsxs19(
@@ -46107,12 +46065,7 @@ var AssessmentEntry = forwardRef(
46107
46065
  onClick: () => {
46108
46066
  eventBus.emit("annotation:click", { annotationId: assessment.id, motivation: assessment.motivation });
46109
46067
  },
46110
- onMouseEnter: () => {
46111
- eventBus.emit("annotation:hover", { annotationId: assessment.id });
46112
- },
46113
- onMouseLeave: () => {
46114
- eventBus.emit("annotation:hover", { annotationId: null });
46115
- },
46068
+ ...hoverProps,
46116
46069
  children: [
46117
46070
  selectedText && /* @__PURE__ */ jsxs19("div", { className: "semiont-annotation-entry__quote", "data-type": "assessment", children: [
46118
46071
  '"',
@@ -46134,11 +46087,11 @@ var AssessmentEntry = forwardRef(
46134
46087
  );
46135
46088
 
46136
46089
  // src/components/resource/panels/AssessmentPanel.tsx
46137
- import { useState as useState18, useEffect as useEffect26, useRef as useRef19, useCallback as useCallback17, useMemo as useMemo4 } from "react";
46090
+ import { useState as useState18, useEffect as useEffect25, useRef as useRef17, useCallback as useCallback17, useMemo as useMemo4 } from "react";
46138
46091
  import { getTextPositionSelector as getTextPositionSelector3, getTargetSelector as getTargetSelector5 } from "@semiont/api-client";
46139
46092
 
46140
46093
  // src/components/resource/panels/DetectSection.tsx
46141
- import { useState as useState17, useEffect as useEffect25, useCallback as useCallback16 } from "react";
46094
+ import { useState as useState17, useEffect as useEffect24, useCallback as useCallback16 } from "react";
46142
46095
  import { Fragment as Fragment7, jsx as jsx30, jsxs as jsxs20 } from "react/jsx-runtime";
46143
46096
  function DetectSection({
46144
46097
  annotationType,
@@ -46158,7 +46111,7 @@ function DetectSection({
46158
46111
  const stored = localStorage.getItem(`detect-section-expanded-${annotationType}`);
46159
46112
  return stored ? stored === "true" : true;
46160
46113
  });
46161
- useEffect25(() => {
46114
+ useEffect24(() => {
46162
46115
  if (typeof window === "undefined") return;
46163
46116
  localStorage.setItem(`detect-section-expanded-${annotationType}`, String(isExpanded));
46164
46117
  }, [isExpanded, annotationType]);
@@ -46382,8 +46335,8 @@ function AssessmentPanel({
46382
46335
  const eventBus = useEventBus();
46383
46336
  const [newAssessmentText, setNewAssessmentText] = useState18("");
46384
46337
  const [focusedAnnotationId, setFocusedAnnotationId] = useState18(null);
46385
- const containerRef = useRef19(null);
46386
- const entryRefs = useRef19(/* @__PURE__ */ new Map());
46338
+ const containerRef = useRef17(null);
46339
+ const entryRefs = useRef17(/* @__PURE__ */ new Map());
46387
46340
  const sortedAnnotations = useMemo4(() => {
46388
46341
  return [...annotations].sort((a15, b8) => {
46389
46342
  const aSelector = getTextPositionSelector3(getTargetSelector5(a15.target));
@@ -46399,7 +46352,7 @@ function AssessmentPanel({
46399
46352
  entryRefs.current.delete(id2);
46400
46353
  }
46401
46354
  }, []);
46402
- useEffect26(() => {
46355
+ useEffect25(() => {
46403
46356
  if (!scrollToAnnotationId) return;
46404
46357
  const element2 = entryRefs.current.get(scrollToAnnotationId);
46405
46358
  if (element2 && containerRef.current) {
@@ -46414,7 +46367,7 @@ function AssessmentPanel({
46414
46367
  if (onScrollCompleted) onScrollCompleted();
46415
46368
  }
46416
46369
  }, [scrollToAnnotationId]);
46417
- useEffect26(() => {
46370
+ useEffect25(() => {
46418
46371
  if (!hoveredAnnotationId) return;
46419
46372
  const element2 = entryRefs.current.get(hoveredAnnotationId);
46420
46373
  if (!element2 || !containerRef.current) return;
@@ -46441,7 +46394,7 @@ function AssessmentPanel({
46441
46394
  setNewAssessmentText("");
46442
46395
  }
46443
46396
  };
46444
- useEffect26(() => {
46397
+ useEffect25(() => {
46445
46398
  if (!pendingAnnotation) return;
46446
46399
  const handleEscape = (e6) => {
46447
46400
  if (e6.key === "Escape") {
@@ -46613,7 +46566,7 @@ function CollaborationPanel({
46613
46566
  }
46614
46567
 
46615
46568
  // src/components/resource/panels/CommentEntry.tsx
46616
- import { useState as useState19, useEffect as useEffect27, useRef as useRef20, forwardRef as forwardRef2, useImperativeHandle } from "react";
46569
+ import { useState as useState19, useEffect as useEffect26, useRef as useRef18, forwardRef as forwardRef2, useImperativeHandle } from "react";
46617
46570
  import { getAnnotationExactText as getAnnotationExactText2, getCommentText } from "@semiont/api-client";
46618
46571
  import { jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
46619
46572
  function formatRelativeTime3(isoString) {
@@ -46639,13 +46592,14 @@ var CommentEntry = forwardRef2(
46639
46592
  }, ref) {
46640
46593
  const t12 = useTranslations("CommentsPanel");
46641
46594
  const eventBus = useEventBus();
46595
+ const hoverProps = useHoverEmitter(comment2.id);
46642
46596
  const [isEditing, setIsEditing] = useState19(false);
46643
46597
  const [editText, setEditText] = useState19("");
46644
- const internalRef = useRef20(null);
46598
+ const internalRef = useRef18(null);
46645
46599
  useImperativeHandle(ref, () => internalRef.current);
46646
46600
  const commentText = getCommentText(comment2) || "";
46647
46601
  const selectedText = getAnnotationExactText2(comment2);
46648
- useEffect27(() => {
46602
+ useEffect26(() => {
46649
46603
  if (isFocused && internalRef.current) {
46650
46604
  internalRef.current.scrollIntoView({
46651
46605
  behavior: "smooth",
@@ -46674,12 +46628,7 @@ var CommentEntry = forwardRef2(
46674
46628
  onClick: () => {
46675
46629
  eventBus.emit("annotation:click", { annotationId: comment2.id, motivation: comment2.motivation });
46676
46630
  },
46677
- onMouseEnter: () => {
46678
- eventBus.emit("annotation:hover", { annotationId: comment2.id });
46679
- },
46680
- onMouseLeave: () => {
46681
- eventBus.emit("annotation:hover", { annotationId: null });
46682
- },
46631
+ ...hoverProps,
46683
46632
  children: [
46684
46633
  selectedText && /* @__PURE__ */ jsxs24("div", { className: "semiont-annotation-entry__quote", "data-type": "comment", children: [
46685
46634
  '"',
@@ -46749,7 +46698,7 @@ var CommentEntry = forwardRef2(
46749
46698
  );
46750
46699
 
46751
46700
  // src/components/resource/panels/CommentsPanel.tsx
46752
- import { useState as useState20, useEffect as useEffect28, useRef as useRef21, useCallback as useCallback18, useMemo as useMemo5 } from "react";
46701
+ import { useState as useState20, useEffect as useEffect27, useRef as useRef19, useCallback as useCallback18, useMemo as useMemo5 } from "react";
46753
46702
  import { getTextPositionSelector as getTextPositionSelector4, getTargetSelector as getTargetSelector6 } from "@semiont/api-client";
46754
46703
  import { jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
46755
46704
  function getSelectorDisplayText2(selector) {
@@ -46779,8 +46728,8 @@ function CommentsPanel({
46779
46728
  const eventBus = useEventBus();
46780
46729
  const [newCommentText, setNewCommentText] = useState20("");
46781
46730
  const [focusedAnnotationId, setFocusedAnnotationId] = useState20(null);
46782
- const containerRef = useRef21(null);
46783
- const entryRefs = useRef21(/* @__PURE__ */ new Map());
46731
+ const containerRef = useRef19(null);
46732
+ const entryRefs = useRef19(/* @__PURE__ */ new Map());
46784
46733
  const sortedAnnotations = useMemo5(() => {
46785
46734
  return [...annotations].sort((a15, b8) => {
46786
46735
  const aSelector = getTextPositionSelector4(getTargetSelector6(a15.target));
@@ -46796,7 +46745,7 @@ function CommentsPanel({
46796
46745
  entryRefs.current.delete(id2);
46797
46746
  }
46798
46747
  }, []);
46799
- useEffect28(() => {
46748
+ useEffect27(() => {
46800
46749
  if (!scrollToAnnotationId) return;
46801
46750
  const element2 = entryRefs.current.get(scrollToAnnotationId);
46802
46751
  if (element2 && containerRef.current) {
@@ -46813,7 +46762,7 @@ function CommentsPanel({
46813
46762
  }
46814
46763
  }
46815
46764
  }, [scrollToAnnotationId]);
46816
- useEffect28(() => {
46765
+ useEffect27(() => {
46817
46766
  if (!hoveredAnnotationId) return;
46818
46767
  const element2 = entryRefs.current.get(hoveredAnnotationId);
46819
46768
  if (!element2 || !containerRef.current) return;
@@ -46846,7 +46795,7 @@ function CommentsPanel({
46846
46795
  setNewCommentText("");
46847
46796
  }
46848
46797
  };
46849
- useEffect28(() => {
46798
+ useEffect27(() => {
46850
46799
  if (!pendingAnnotation) return;
46851
46800
  const handleEscape = (e6) => {
46852
46801
  if (e6.key === "Escape") {
@@ -46959,6 +46908,7 @@ var HighlightEntry = forwardRef3(
46959
46908
  isHovered = false
46960
46909
  }, ref) {
46961
46910
  const eventBus = useEventBus();
46911
+ const hoverProps = useHoverEmitter(highlight.id);
46962
46912
  const selectedText = getAnnotationExactText3(highlight);
46963
46913
  return /* @__PURE__ */ jsxs26(
46964
46914
  "div",
@@ -46970,12 +46920,7 @@ var HighlightEntry = forwardRef3(
46970
46920
  onClick: () => {
46971
46921
  eventBus.emit("annotation:click", { annotationId: highlight.id, motivation: highlight.motivation });
46972
46922
  },
46973
- onMouseEnter: () => {
46974
- eventBus.emit("annotation:hover", { annotationId: highlight.id });
46975
- },
46976
- onMouseLeave: () => {
46977
- eventBus.emit("annotation:hover", { annotationId: null });
46978
- },
46923
+ ...hoverProps,
46979
46924
  children: [
46980
46925
  selectedText && /* @__PURE__ */ jsxs26("div", { className: "semiont-annotation-entry__quote", "data-type": "highlight", children: [
46981
46926
  '"',
@@ -46996,7 +46941,7 @@ var HighlightEntry = forwardRef3(
46996
46941
  );
46997
46942
 
46998
46943
  // src/components/resource/panels/HighlightPanel.tsx
46999
- import { useEffect as useEffect29, useState as useState21, useRef as useRef22, useCallback as useCallback19, useMemo as useMemo6 } from "react";
46944
+ import { useEffect as useEffect28, useState as useState21, useRef as useRef20, useCallback as useCallback19, useMemo as useMemo6 } from "react";
47000
46945
  import { getTextPositionSelector as getTextPositionSelector5, getTargetSelector as getTargetSelector7 } from "@semiont/api-client";
47001
46946
  import { jsx as jsx36, jsxs as jsxs27 } from "react/jsx-runtime";
47002
46947
  function HighlightPanel({
@@ -47012,8 +46957,8 @@ function HighlightPanel({
47012
46957
  const t12 = useTranslations("HighlightPanel");
47013
46958
  const eventBus = useEventBus();
47014
46959
  const [focusedAnnotationId, setFocusedAnnotationId] = useState21(null);
47015
- const containerRef = useRef22(null);
47016
- const entryRefs = useRef22(/* @__PURE__ */ new Map());
46960
+ const containerRef = useRef20(null);
46961
+ const entryRefs = useRef20(/* @__PURE__ */ new Map());
47017
46962
  const sortedAnnotations = useMemo6(() => {
47018
46963
  return [...annotations].sort((a15, b8) => {
47019
46964
  const aSelector = getTextPositionSelector5(getTargetSelector7(a15.target));
@@ -47029,7 +46974,7 @@ function HighlightPanel({
47029
46974
  entryRefs.current.delete(id2);
47030
46975
  }
47031
46976
  }, []);
47032
- useEffect29(() => {
46977
+ useEffect28(() => {
47033
46978
  if (!scrollToAnnotationId) return;
47034
46979
  const element2 = entryRefs.current.get(scrollToAnnotationId);
47035
46980
  if (element2 && containerRef.current) {
@@ -47044,7 +46989,7 @@ function HighlightPanel({
47044
46989
  if (onScrollCompleted) onScrollCompleted();
47045
46990
  }
47046
46991
  }, [scrollToAnnotationId]);
47047
- useEffect29(() => {
46992
+ useEffect28(() => {
47048
46993
  if (!hoveredAnnotationId) return;
47049
46994
  const element2 = entryRefs.current.get(hoveredAnnotationId);
47050
46995
  if (!element2 || !containerRef.current) return;
@@ -47067,7 +47012,7 @@ function HighlightPanel({
47067
47012
  useEventSubscriptions({
47068
47013
  "annotation:click": handleAnnotationClick
47069
47014
  });
47070
- useEffect29(() => {
47015
+ useEffect28(() => {
47071
47016
  if (pendingAnnotation && pendingAnnotation.motivation === "highlighting") {
47072
47017
  eventBus.emit("annotation:create", {
47073
47018
  motivation: "highlighting",
@@ -47102,13 +47047,13 @@ function HighlightPanel({
47102
47047
  }
47103
47048
 
47104
47049
  // src/components/resource/panels/JsonLdPanel.tsx
47105
- import { useEffect as useEffect30, useRef as useRef23 } from "react";
47050
+ import { useEffect as useEffect29, useRef as useRef21 } from "react";
47106
47051
  import { jsx as jsx37, jsxs as jsxs28 } from "react/jsx-runtime";
47107
47052
  function JsonLdPanel({ resource: semiontResource }) {
47108
- const editorRef = useRef23(null);
47109
- const viewRef = useRef23(null);
47053
+ const editorRef = useRef21(null);
47054
+ const viewRef = useRef21(null);
47110
47055
  const { showLineNumbers } = useLineNumbers();
47111
- useEffect30(() => {
47056
+ useEffect29(() => {
47112
47057
  if (!editorRef.current) return;
47113
47058
  const isDarkMode = document.documentElement?.classList.contains("dark") ?? false;
47114
47059
  const jsonLdContent = JSON.stringify(semiontResource, null, 2);
@@ -47186,6 +47131,7 @@ var ReferenceEntry = forwardRef4(
47186
47131
  const t12 = useTranslations("ReferencesPanel");
47187
47132
  const eventBus = useEventBus();
47188
47133
  const navigate = useObservableExternalNavigation();
47134
+ const hoverProps = useHoverEmitter(reference.id);
47189
47135
  const selectedText = getAnnotationExactText4(reference) || "";
47190
47136
  const isResolved = isBodyResolved2(reference.body);
47191
47137
  const resolvedResourceUri = isResolved ? getBodySource5(reference.body) : null;
@@ -47248,12 +47194,7 @@ var ReferenceEntry = forwardRef4(
47248
47194
  onClick: () => {
47249
47195
  eventBus.emit("annotation:click", { annotationId: reference.id, motivation: reference.motivation });
47250
47196
  },
47251
- onMouseEnter: () => {
47252
- eventBus.emit("annotation:hover", { annotationId: reference.id });
47253
- },
47254
- onMouseLeave: () => {
47255
- eventBus.emit("annotation:hover", { annotationId: null });
47256
- },
47197
+ ...hoverProps,
47257
47198
  children: [
47258
47199
  /* @__PURE__ */ jsxs29("div", { className: "semiont-annotation-entry__header", children: [
47259
47200
  /* @__PURE__ */ jsx38("span", { className: "semiont-reference-icon", title: isResolved ? t12("resolved") : t12("stub"), children: isResolved ? "\u{1F517}" : "\u2753" }),
@@ -47344,7 +47285,7 @@ var ReferenceEntry = forwardRef4(
47344
47285
  );
47345
47286
 
47346
47287
  // src/components/resource/panels/ReferencesPanel.tsx
47347
- import { useState as useState22, useRef as useRef24, useEffect as useEffect31, useCallback as useCallback20, useMemo as useMemo7 } from "react";
47288
+ import { useState as useState22, useRef as useRef22, useEffect as useEffect30, useCallback as useCallback20, useMemo as useMemo7 } from "react";
47348
47289
  import { getTextPositionSelector as getTextPositionSelector6, getTargetSelector as getTargetSelector9 } from "@semiont/api-client";
47349
47290
  import { Fragment as Fragment8, jsx as jsx39, jsxs as jsxs30 } from "react/jsx-runtime";
47350
47291
  function getSelectorDisplayText3(selector) {
@@ -47384,17 +47325,17 @@ function ReferencesPanel({
47384
47325
  const [pendingEntityTypes, setPendingEntityTypes] = useState22([]);
47385
47326
  const [includeDescriptiveReferences, setIncludeDescriptiveReferences] = useState22(false);
47386
47327
  const [focusedAnnotationId, setFocusedAnnotationId] = useState22(null);
47387
- const containerRef = useRef24(null);
47328
+ const containerRef = useRef22(null);
47388
47329
  const [isDetectExpanded, setIsDetectExpanded] = useState22(() => {
47389
47330
  if (typeof window === "undefined") return true;
47390
47331
  const stored = localStorage.getItem("detect-section-expanded-reference");
47391
47332
  return stored ? stored === "true" : true;
47392
47333
  });
47393
- useEffect31(() => {
47334
+ useEffect30(() => {
47394
47335
  if (typeof window === "undefined") return;
47395
47336
  localStorage.setItem("detect-section-expanded-reference", String(isDetectExpanded));
47396
47337
  }, [isDetectExpanded]);
47397
- const entryRefs = useRef24(/* @__PURE__ */ new Map());
47338
+ const entryRefs = useRef22(/* @__PURE__ */ new Map());
47398
47339
  const sortedAnnotations = useMemo7(() => {
47399
47340
  return [...annotations].sort((a15, b8) => {
47400
47341
  const aSelector = getTextPositionSelector6(getTargetSelector9(a15.target));
@@ -47410,7 +47351,7 @@ function ReferencesPanel({
47410
47351
  entryRefs.current.delete(id2);
47411
47352
  }
47412
47353
  }, []);
47413
- useEffect31(() => {
47354
+ useEffect30(() => {
47414
47355
  if (!scrollToAnnotationId) return;
47415
47356
  const element2 = entryRefs.current.get(scrollToAnnotationId);
47416
47357
  if (element2 && containerRef.current) {
@@ -47429,7 +47370,7 @@ function ReferencesPanel({
47429
47370
  console.warn("[ReferencesPanel] Element not found for scrollToAnnotationId:", scrollToAnnotationId);
47430
47371
  }
47431
47372
  }, [scrollToAnnotationId]);
47432
- useEffect31(() => {
47373
+ useEffect30(() => {
47433
47374
  if (!hoveredAnnotationId) return;
47434
47375
  const element2 = entryRefs.current.get(hoveredAnnotationId);
47435
47376
  if (!element2 || !containerRef.current) return;
@@ -47462,8 +47403,8 @@ function ReferencesPanel({
47462
47403
  }
47463
47404
  });
47464
47405
  };
47465
- const hasSavedLogRef = useRef24(false);
47466
- useEffect31(() => {
47406
+ const hasSavedLogRef = useRef22(false);
47407
+ useEffect30(() => {
47467
47408
  if (isDetecting) {
47468
47409
  hasSavedLogRef.current = false;
47469
47410
  return;
@@ -47490,7 +47431,7 @@ function ReferencesPanel({
47490
47431
  setPendingEntityTypes([]);
47491
47432
  }
47492
47433
  };
47493
- useEffect31(() => {
47434
+ useEffect30(() => {
47494
47435
  if (!pendingAnnotation) return;
47495
47436
  const handleEscape = (e6) => {
47496
47437
  if (e6.key === "Escape") {
@@ -47881,6 +47822,7 @@ var TagEntry = forwardRef5(
47881
47822
  isHovered = false
47882
47823
  }, ref) {
47883
47824
  const eventBus = useEventBus();
47825
+ const hoverProps = useHoverEmitter(tag.id);
47884
47826
  const selectedText = getAnnotationExactText5(tag);
47885
47827
  const category = getTagCategory(tag);
47886
47828
  const schemaId = getTagSchemaId(tag);
@@ -47892,12 +47834,7 @@ var TagEntry = forwardRef5(
47892
47834
  onClick: () => {
47893
47835
  eventBus.emit("annotation:click", { annotationId: tag.id, motivation: tag.motivation });
47894
47836
  },
47895
- onMouseEnter: () => {
47896
- eventBus.emit("annotation:hover", { annotationId: tag.id });
47897
- },
47898
- onMouseLeave: () => {
47899
- eventBus.emit("annotation:hover", { annotationId: null });
47900
- },
47837
+ ...hoverProps,
47901
47838
  className: `semiont-annotation-entry${isHovered ? " semiont-annotation-pulse" : ""}`,
47902
47839
  "data-type": "tag",
47903
47840
  "data-focused": isFocused ? "true" : "false",
@@ -47919,7 +47856,7 @@ var TagEntry = forwardRef5(
47919
47856
  );
47920
47857
 
47921
47858
  // src/components/resource/panels/TaggingPanel.tsx
47922
- import { useState as useState23, useEffect as useEffect32, useRef as useRef25, useCallback as useCallback21, useMemo as useMemo8 } from "react";
47859
+ import { useState as useState23, useEffect as useEffect31, useRef as useRef23, useCallback as useCallback21, useMemo as useMemo8 } from "react";
47923
47860
  import { getTextPositionSelector as getTextPositionSelector7, getTargetSelector as getTargetSelector10 } from "@semiont/api-client";
47924
47861
  import { Fragment as Fragment10, jsx as jsx43, jsxs as jsxs34 } from "react/jsx-runtime";
47925
47862
  function getSelectorDisplayText4(selector) {
@@ -47950,13 +47887,13 @@ function TaggingPanel({
47950
47887
  const [selectedSchemaId, setSelectedSchemaId] = useState23("legal-irac");
47951
47888
  const [selectedCategories, setSelectedCategories] = useState23(/* @__PURE__ */ new Set());
47952
47889
  const [focusedAnnotationId, setFocusedAnnotationId] = useState23(null);
47953
- const containerRef = useRef25(null);
47890
+ const containerRef = useRef23(null);
47954
47891
  const [isDetectExpanded, setIsDetectExpanded] = useState23(() => {
47955
47892
  if (typeof window === "undefined") return true;
47956
47893
  const stored = localStorage.getItem("detect-section-expanded-tag");
47957
47894
  return stored ? stored === "true" : true;
47958
47895
  });
47959
- useEffect32(() => {
47896
+ useEffect31(() => {
47960
47897
  if (typeof window === "undefined") return;
47961
47898
  localStorage.setItem("detect-section-expanded-tag", String(isDetectExpanded));
47962
47899
  }, [isDetectExpanded]);
@@ -47967,7 +47904,7 @@ function TaggingPanel({
47967
47904
  useEventSubscriptions({
47968
47905
  "annotation:click": handleAnnotationClick
47969
47906
  });
47970
- const entryRefs = useRef25(/* @__PURE__ */ new Map());
47907
+ const entryRefs = useRef23(/* @__PURE__ */ new Map());
47971
47908
  const sortedAnnotations = useMemo8(() => {
47972
47909
  return [...annotations].sort((a15, b8) => {
47973
47910
  const aSelector = getTextPositionSelector7(getTargetSelector10(a15.target));
@@ -47983,7 +47920,7 @@ function TaggingPanel({
47983
47920
  entryRefs.current.delete(id2);
47984
47921
  }
47985
47922
  }, []);
47986
- useEffect32(() => {
47923
+ useEffect31(() => {
47987
47924
  if (!scrollToAnnotationId) return;
47988
47925
  const element2 = entryRefs.current.get(scrollToAnnotationId);
47989
47926
  if (element2 && containerRef.current) {
@@ -47998,7 +47935,7 @@ function TaggingPanel({
47998
47935
  if (onScrollCompleted) onScrollCompleted();
47999
47936
  }
48000
47937
  }, [scrollToAnnotationId]);
48001
- useEffect32(() => {
47938
+ useEffect31(() => {
48002
47939
  if (!hoveredAnnotationId) return;
48003
47940
  const element2 = entryRefs.current.get(hoveredAnnotationId);
48004
47941
  if (!element2 || !containerRef.current) return;
@@ -48049,7 +47986,7 @@ function TaggingPanel({
48049
47986
  setSelectedCategories(/* @__PURE__ */ new Set());
48050
47987
  }
48051
47988
  };
48052
- useEffect32(() => {
47989
+ useEffect31(() => {
48053
47990
  if (!pendingAnnotation) return;
48054
47991
  const handleEscape = (e6) => {
48055
47992
  if (e6.key === "Escape") {
@@ -48099,6 +48036,11 @@ function TaggingPanel({
48099
48036
  type: "TextualBody",
48100
48037
  value: e6.target.value,
48101
48038
  purpose: "tagging"
48039
+ },
48040
+ {
48041
+ type: "TextualBody",
48042
+ value: selectedSchemaId,
48043
+ purpose: "classifying"
48102
48044
  }
48103
48045
  ]
48104
48046
  });
@@ -48271,7 +48213,7 @@ function TaggingPanel({
48271
48213
  }
48272
48214
 
48273
48215
  // src/components/resource/panels/UnifiedAnnotationsPanel.tsx
48274
- import { useState as useState24, useEffect as useEffect33 } from "react";
48216
+ import { useState as useState24, useEffect as useEffect32 } from "react";
48275
48217
  import { jsx as jsx44, jsxs as jsxs35 } from "react/jsx-runtime";
48276
48218
  var TAB_ORDER = ["statistics", "reference", "highlight", "assessment", "comment", "tag"];
48277
48219
  function UnifiedAnnotationsPanel(props) {
@@ -48302,17 +48244,17 @@ function UnifiedAnnotationsPanel(props) {
48302
48244
  }
48303
48245
  return props.initialTab || "statistics";
48304
48246
  });
48305
- useEffect33(() => {
48247
+ useEffect32(() => {
48306
48248
  if (typeof window === "undefined") return;
48307
48249
  const storageKey = props.resourceId ? `annotations-tab-${props.resourceId}` : "annotations-tab-global";
48308
48250
  localStorage.setItem(storageKey, activeTab);
48309
48251
  }, [activeTab, props.resourceId]);
48310
- useEffect33(() => {
48252
+ useEffect32(() => {
48311
48253
  if (props.initialTab && props.initialTabGeneration !== void 0) {
48312
48254
  setActiveTab(props.initialTab);
48313
48255
  }
48314
48256
  }, [props.initialTabGeneration]);
48315
- useEffect33(() => {
48257
+ useEffect32(() => {
48316
48258
  if (props.pendingAnnotation) {
48317
48259
  const motivationToTab = {
48318
48260
  "linking": "reference",
@@ -48601,7 +48543,7 @@ function NavigationMenu({
48601
48543
  }
48602
48544
 
48603
48545
  // src/components/navigation/ObservableLink.tsx
48604
- import { useCallback as useCallback22, useRef as useRef26, useEffect as useEffect34 } from "react";
48546
+ import { useCallback as useCallback22, useRef as useRef24, useEffect as useEffect33 } from "react";
48605
48547
  import { jsx as jsx47 } from "react/jsx-runtime";
48606
48548
  function ObservableLink({
48607
48549
  href,
@@ -48611,8 +48553,8 @@ function ObservableLink({
48611
48553
  ...anchorProps
48612
48554
  }) {
48613
48555
  const eventBus = useEventBus();
48614
- const onClickRef = useRef26(onClick);
48615
- useEffect34(() => {
48556
+ const onClickRef = useRef24(onClick);
48557
+ useEffect33(() => {
48616
48558
  onClickRef.current = onClick;
48617
48559
  });
48618
48560
  const handleClick = useCallback22((e6) => {
@@ -48634,7 +48576,7 @@ function ObservableLink({
48634
48576
  }
48635
48577
 
48636
48578
  // src/components/navigation/SimpleNavigation.tsx
48637
- import { useState as useState26, useRef as useRef27, useEffect as useEffect35 } from "react";
48579
+ import { useState as useState26, useRef as useRef25, useEffect as useEffect34 } from "react";
48638
48580
  import { jsx as jsx48, jsxs as jsxs38 } from "react/jsx-runtime";
48639
48581
  function SimpleNavigation({
48640
48582
  title,
@@ -48650,11 +48592,11 @@ function SimpleNavigation({
48650
48592
  const ChevronLeftIcon = icons.chevronLeft;
48651
48593
  const BarsIcon = icons.bars;
48652
48594
  const [isDropdownOpen, setIsDropdownOpen] = useState26(false);
48653
- const dropdownRef = useRef27(null);
48595
+ const dropdownRef = useRef25(null);
48654
48596
  const eventBus = useEventBus();
48655
48597
  const toggleDropdown = () => setIsDropdownOpen(!isDropdownOpen);
48656
48598
  const closeDropdown = () => setIsDropdownOpen(false);
48657
- useEffect35(() => {
48599
+ useEffect34(() => {
48658
48600
  const handleClickOutside = (event) => {
48659
48601
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
48660
48602
  closeDropdown();
@@ -48730,14 +48672,14 @@ function SimpleNavigation({
48730
48672
  }
48731
48673
 
48732
48674
  // src/components/navigation/CollapsibleResourceNavigation.tsx
48733
- import { useCallback as useCallback28, useState as useState30, useRef as useRef32, useEffect as useEffect40 } from "react";
48675
+ import { useCallback as useCallback28, useState as useState30, useRef as useRef30, useEffect as useEffect39 } from "react";
48734
48676
 
48735
48677
  // ../../node_modules/@dnd-kit/core/dist/core.esm.js
48736
- import React20, { createContext as createContext7, useContext as useContext7, useEffect as useEffect37, useState as useState28, useCallback as useCallback25, useMemo as useMemo10, useRef as useRef29, memo, useReducer, cloneElement, forwardRef as forwardRef6 } from "react";
48678
+ import React20, { createContext as createContext7, useContext as useContext7, useEffect as useEffect36, useState as useState28, useCallback as useCallback25, useMemo as useMemo10, useRef as useRef27, memo, useReducer, cloneElement, forwardRef as forwardRef6 } from "react";
48737
48679
  import { createPortal, unstable_batchedUpdates } from "react-dom";
48738
48680
 
48739
48681
  // ../../node_modules/@dnd-kit/utilities/dist/utilities.esm.js
48740
- import { useMemo as useMemo9, useLayoutEffect, useEffect as useEffect36, useRef as useRef28, useCallback as useCallback23 } from "react";
48682
+ import { useMemo as useMemo9, useLayoutEffect, useEffect as useEffect35, useRef as useRef26, useCallback as useCallback23 } from "react";
48741
48683
  function useCombinedRefs() {
48742
48684
  for (var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++) {
48743
48685
  refs[_key] = arguments[_key];
@@ -48805,9 +48747,9 @@ function getOwnerDocument(target) {
48805
48747
  }
48806
48748
  return document;
48807
48749
  }
48808
- var useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect36;
48750
+ var useIsomorphicLayoutEffect = canUseDOM ? useLayoutEffect : useEffect35;
48809
48751
  function useEvent(handler) {
48810
- const handlerRef = useRef28(handler);
48752
+ const handlerRef = useRef26(handler);
48811
48753
  useIsomorphicLayoutEffect(() => {
48812
48754
  handlerRef.current = handler;
48813
48755
  });
@@ -48819,7 +48761,7 @@ function useEvent(handler) {
48819
48761
  }, []);
48820
48762
  }
48821
48763
  function useInterval() {
48822
- const intervalRef = useRef28(null);
48764
+ const intervalRef = useRef26(null);
48823
48765
  const set = useCallback23((listener, duration) => {
48824
48766
  intervalRef.current = setInterval(listener, duration);
48825
48767
  }, []);
@@ -48835,7 +48777,7 @@ function useLatestValue(value, dependencies) {
48835
48777
  if (dependencies === void 0) {
48836
48778
  dependencies = [value];
48837
48779
  }
48838
- const valueRef = useRef28(value);
48780
+ const valueRef = useRef26(value);
48839
48781
  useIsomorphicLayoutEffect(() => {
48840
48782
  if (valueRef.current !== value) {
48841
48783
  valueRef.current = value;
@@ -48844,7 +48786,7 @@ function useLatestValue(value, dependencies) {
48844
48786
  return valueRef;
48845
48787
  }
48846
48788
  function useLazyMemo(callback, dependencies) {
48847
- const valueRef = useRef28();
48789
+ const valueRef = useRef26();
48848
48790
  return useMemo9(
48849
48791
  () => {
48850
48792
  const newValue = callback(valueRef.current);
@@ -48857,7 +48799,7 @@ function useLazyMemo(callback, dependencies) {
48857
48799
  }
48858
48800
  function useNodeRef(onChange) {
48859
48801
  const onChangeHandler = useEvent(onChange);
48860
- const node2 = useRef28(null);
48802
+ const node2 = useRef26(null);
48861
48803
  const setNodeRef = useCallback23(
48862
48804
  (element2) => {
48863
48805
  if (element2 !== node2.current) {
@@ -48871,8 +48813,8 @@ function useNodeRef(onChange) {
48871
48813
  return [node2, setNodeRef];
48872
48814
  }
48873
48815
  function usePrevious(value) {
48874
- const ref = useRef28();
48875
- useEffect36(() => {
48816
+ const ref = useRef26();
48817
+ useEffect35(() => {
48876
48818
  ref.current = value;
48877
48819
  }, [value]);
48878
48820
  return ref.current;
@@ -49072,7 +49014,7 @@ function useAnnouncement() {
49072
49014
  var DndMonitorContext = /* @__PURE__ */ createContext7(null);
49073
49015
  function useDndMonitor(listener) {
49074
49016
  const registerListener = useContext7(DndMonitorContext);
49075
- useEffect37(() => {
49017
+ useEffect36(() => {
49076
49018
  if (!registerListener) {
49077
49019
  throw new Error("useDndMonitor must be used within a children of <DndContext>");
49078
49020
  }
@@ -49148,7 +49090,7 @@ function Accessibility(_ref) {
49148
49090
  } = useAnnouncement();
49149
49091
  const liveRegionId = useUniqueId("DndLiveRegion");
49150
49092
  const [mounted, setMounted] = useState28(false);
49151
- useEffect37(() => {
49093
+ useEffect36(() => {
49152
49094
  setMounted(true);
49153
49095
  }, []);
49154
49096
  useDndMonitor(useMemo10(() => ({
@@ -50484,11 +50426,11 @@ function useAutoScroller(_ref) {
50484
50426
  disabled: !enabled
50485
50427
  });
50486
50428
  const [setAutoScrollInterval, clearAutoScrollInterval] = useInterval();
50487
- const scrollSpeed = useRef29({
50429
+ const scrollSpeed = useRef27({
50488
50430
  x: 0,
50489
50431
  y: 0
50490
50432
  });
50491
- const scrollDirection = useRef29({
50433
+ const scrollDirection = useRef27({
50492
50434
  x: 0,
50493
50435
  y: 0
50494
50436
  });
@@ -50505,7 +50447,7 @@ function useAutoScroller(_ref) {
50505
50447
  return draggingRect;
50506
50448
  }
50507
50449
  }, [activator, draggingRect, pointerCoordinates]);
50508
- const scrollContainerRef = useRef29(null);
50450
+ const scrollContainerRef = useRef27(null);
50509
50451
  const autoScroll = useCallback25(() => {
50510
50452
  const scrollContainer = scrollContainerRef.current;
50511
50453
  if (!scrollContainer) {
@@ -50516,7 +50458,7 @@ function useAutoScroller(_ref) {
50516
50458
  scrollContainer.scrollBy(scrollLeft, scrollTop);
50517
50459
  }, []);
50518
50460
  const sortedScrollableAncestors = useMemo10(() => order2 === TraversalOrder.TreeOrder ? [...scrollableAncestors].reverse() : scrollableAncestors, [order2, scrollableAncestors]);
50519
- useEffect37(
50461
+ useEffect36(
50520
50462
  () => {
50521
50463
  if (!enabled || !scrollableAncestors.length || !rect) {
50522
50464
  clearAutoScrollInterval();
@@ -50663,7 +50605,7 @@ function useDroppableMeasuring(containers, _ref) {
50663
50605
  measure,
50664
50606
  strategy
50665
50607
  } = config;
50666
- const containersRef = useRef29(containers);
50608
+ const containersRef = useRef27(containers);
50667
50609
  const disabled = isDisabled();
50668
50610
  const disabledRef = useLatestValue(disabled);
50669
50611
  const measureDroppableContainers = useCallback25(function(ids2) {
@@ -50680,7 +50622,7 @@ function useDroppableMeasuring(containers, _ref) {
50680
50622
  return value.concat(ids2.filter((id2) => !value.includes(id2)));
50681
50623
  });
50682
50624
  }, [disabledRef]);
50683
- const timeoutId = useRef29(null);
50625
+ const timeoutId = useRef27(null);
50684
50626
  const droppableRects = useLazyMemo((previousValue) => {
50685
50627
  if (disabled && !dragging) {
50686
50628
  return defaultValue;
@@ -50706,10 +50648,10 @@ function useDroppableMeasuring(containers, _ref) {
50706
50648
  }
50707
50649
  return previousValue;
50708
50650
  }, [containers, queue, dragging, disabled, measure]);
50709
- useEffect37(() => {
50651
+ useEffect36(() => {
50710
50652
  containersRef.current = containers;
50711
50653
  }, [containers]);
50712
- useEffect37(
50654
+ useEffect36(
50713
50655
  () => {
50714
50656
  if (disabled) {
50715
50657
  return;
@@ -50719,7 +50661,7 @@ function useDroppableMeasuring(containers, _ref) {
50719
50661
  // eslint-disable-next-line react-hooks/exhaustive-deps
50720
50662
  [dragging, disabled]
50721
50663
  );
50722
- useEffect37(
50664
+ useEffect36(
50723
50665
  () => {
50724
50666
  if (queue && queue.length > 0) {
50725
50667
  setQueue(null);
@@ -50728,7 +50670,7 @@ function useDroppableMeasuring(containers, _ref) {
50728
50670
  //eslint-disable-next-line react-hooks/exhaustive-deps
50729
50671
  [JSON.stringify(queue)]
50730
50672
  );
50731
- useEffect37(
50673
+ useEffect36(
50732
50674
  () => {
50733
50675
  if (disabled || typeof frequency !== "number" || timeoutId.current !== null) {
50734
50676
  return;
@@ -50786,7 +50728,7 @@ function useMutationObserver(_ref) {
50786
50728
  } = window;
50787
50729
  return new MutationObserver2(handleMutations);
50788
50730
  }, [handleMutations, disabled]);
50789
- useEffect37(() => {
50731
+ useEffect36(() => {
50790
50732
  return () => mutationObserver == null ? void 0 : mutationObserver.disconnect();
50791
50733
  }, [mutationObserver]);
50792
50734
  return mutationObserver;
@@ -50810,7 +50752,7 @@ function useResizeObserver(_ref) {
50810
50752
  // eslint-disable-next-line react-hooks/exhaustive-deps
50811
50753
  [disabled]
50812
50754
  );
50813
- useEffect37(() => {
50755
+ useEffect36(() => {
50814
50756
  return () => resizeObserver == null ? void 0 : resizeObserver.disconnect();
50815
50757
  }, [resizeObserver]);
50816
50758
  return resizeObserver;
@@ -50880,7 +50822,7 @@ function useRectDelta(rect) {
50880
50822
  }
50881
50823
  var defaultValue$1 = [];
50882
50824
  function useScrollableAncestors(node2) {
50883
- const previousNode = useRef29(node2);
50825
+ const previousNode = useRef27(node2);
50884
50826
  const ancestors = useLazyMemo((previousValue) => {
50885
50827
  if (!node2) {
50886
50828
  return defaultValue$1;
@@ -50890,14 +50832,14 @@ function useScrollableAncestors(node2) {
50890
50832
  }
50891
50833
  return getScrollableAncestors(node2);
50892
50834
  }, [node2]);
50893
- useEffect37(() => {
50835
+ useEffect36(() => {
50894
50836
  previousNode.current = node2;
50895
50837
  }, [node2]);
50896
50838
  return ancestors;
50897
50839
  }
50898
50840
  function useScrollOffsets(elements) {
50899
50841
  const [scrollCoordinates, setScrollCoordinates] = useState28(null);
50900
- const prevElements = useRef29(elements);
50842
+ const prevElements = useRef27(elements);
50901
50843
  const handleScroll = useCallback25((event) => {
50902
50844
  const scrollingElement = getScrollableElement(event.target);
50903
50845
  if (!scrollingElement) {
@@ -50911,7 +50853,7 @@ function useScrollOffsets(elements) {
50911
50853
  return new Map(scrollCoordinates2);
50912
50854
  });
50913
50855
  }, []);
50914
- useEffect37(() => {
50856
+ useEffect36(() => {
50915
50857
  const previousElements = prevElements.current;
50916
50858
  if (elements !== previousElements) {
50917
50859
  cleanup(previousElements);
@@ -50950,15 +50892,15 @@ function useScrollOffsetsDelta(scrollOffsets, dependencies) {
50950
50892
  if (dependencies === void 0) {
50951
50893
  dependencies = [];
50952
50894
  }
50953
- const initialScrollOffsets = useRef29(null);
50954
- useEffect37(
50895
+ const initialScrollOffsets = useRef27(null);
50896
+ useEffect36(
50955
50897
  () => {
50956
50898
  initialScrollOffsets.current = null;
50957
50899
  },
50958
50900
  // eslint-disable-next-line react-hooks/exhaustive-deps
50959
50901
  dependencies
50960
50902
  );
50961
- useEffect37(() => {
50903
+ useEffect36(() => {
50962
50904
  const hasScrollOffsets = scrollOffsets !== defaultCoordinates;
50963
50905
  if (hasScrollOffsets && !initialScrollOffsets.current) {
50964
50906
  initialScrollOffsets.current = scrollOffsets;
@@ -50970,7 +50912,7 @@ function useScrollOffsetsDelta(scrollOffsets, dependencies) {
50970
50912
  return initialScrollOffsets.current ? subtract(scrollOffsets, initialScrollOffsets.current) : defaultCoordinates;
50971
50913
  }
50972
50914
  function useSensorSetup(sensors) {
50973
- useEffect37(
50915
+ useEffect36(
50974
50916
  () => {
50975
50917
  if (!canUseDOM) {
50976
50918
  return;
@@ -51310,7 +51252,7 @@ function RestoreFocus(_ref) {
51310
51252
  } = useContext7(InternalContext);
51311
51253
  const previousActivatorEvent = usePrevious(activatorEvent);
51312
51254
  const previousActiveId = usePrevious(active == null ? void 0 : active.id);
51313
- useEffect37(() => {
51255
+ useEffect36(() => {
51314
51256
  if (disabled) {
51315
51257
  return;
51316
51258
  }
@@ -51387,7 +51329,7 @@ function useLayoutShiftScrollCompensation(_ref) {
51387
51329
  initialRect,
51388
51330
  config = true
51389
51331
  } = _ref;
51390
- const initialized = useRef29(false);
51332
+ const initialized = useRef27(false);
51391
51333
  const {
51392
51334
  x: x8,
51393
51335
  y: y4
@@ -51468,7 +51410,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51468
51410
  }
51469
51411
  } = state;
51470
51412
  const node2 = activeId != null ? draggableNodes.get(activeId) : null;
51471
- const activeRects = useRef29({
51413
+ const activeRects = useRef27({
51472
51414
  initial: null,
51473
51415
  translated: null
51474
51416
  });
@@ -51481,7 +51423,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51481
51423
  rect: activeRects
51482
51424
  } : null;
51483
51425
  }, [activeId, node2]);
51484
- const activeRef = useRef29(null);
51426
+ const activeRef = useRef27(null);
51485
51427
  const [activeSensor, setActiveSensor] = useState28(null);
51486
51428
  const [activatorEvent, setActivatorEvent] = useState28(null);
51487
51429
  const latestProps = useLatestValue(props, Object.values(props));
@@ -51509,7 +51451,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51509
51451
  });
51510
51452
  const activeNodeRect = useRect(activeNode, measuringConfiguration.draggable.measure, initialActiveNodeRect);
51511
51453
  const containerNodeRect = useRect(activeNode ? activeNode.parentElement : null);
51512
- const sensorContext = useRef29({
51454
+ const sensorContext = useRef27({
51513
51455
  activatorEvent: null,
51514
51456
  active: null,
51515
51457
  activeNode,
@@ -51570,7 +51512,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51570
51512
  const [over, setOver] = useState28(null);
51571
51513
  const appliedTranslate = usesDragOverlay ? modifiedTranslate : add(modifiedTranslate, activeNodeScrollDelta);
51572
51514
  const transform = adjustScale(appliedTranslate, (_over$rect = over == null ? void 0 : over.rect) != null ? _over$rect : null, activeNodeRect);
51573
- const activeSensorRef = useRef29(null);
51515
+ const activeSensorRef = useRef27(null);
51574
51516
  const instantiateSensor = useCallback25(
51575
51517
  (event, _ref2) => {
51576
51518
  let {
@@ -51761,7 +51703,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51761
51703
  setStatus(Status.Initialized);
51762
51704
  }
51763
51705
  }, [activeNodeRect, status]);
51764
- useEffect37(
51706
+ useEffect36(
51765
51707
  () => {
51766
51708
  const {
51767
51709
  onDragMove
@@ -51796,7 +51738,7 @@ var DndContext = /* @__PURE__ */ memo(function DndContext2(_ref) {
51796
51738
  // eslint-disable-next-line react-hooks/exhaustive-deps
51797
51739
  [scrollAdjustedTranslate.x, scrollAdjustedTranslate.y]
51798
51740
  );
51799
- useEffect37(
51741
+ useEffect36(
51800
51742
  () => {
51801
51743
  const {
51802
51744
  active: active2,
@@ -52029,12 +51971,12 @@ function useDroppable(_ref) {
52029
51971
  over,
52030
51972
  measureDroppableContainers
52031
51973
  } = useContext7(InternalContext);
52032
- const previous3 = useRef29({
51974
+ const previous3 = useRef27({
52033
51975
  disabled
52034
51976
  });
52035
- const resizeObserverConnected = useRef29(false);
52036
- const rect = useRef29(null);
52037
- const callbackId = useRef29(null);
51977
+ const resizeObserverConnected = useRef27(false);
51978
+ const rect = useRef27(null);
51979
+ const callbackId = useRef27(null);
52038
51980
  const {
52039
51981
  disabled: resizeObserverDisabled,
52040
51982
  updateMeasurementsFor,
@@ -52079,7 +52021,7 @@ function useDroppable(_ref) {
52079
52021
  }, [resizeObserver]);
52080
52022
  const [nodeRef, setNodeRef] = useNodeRef(handleNodeChange);
52081
52023
  const dataRef = useLatestValue(data2);
52082
- useEffect37(() => {
52024
+ useEffect36(() => {
52083
52025
  if (!resizeObserver || !nodeRef.current) {
52084
52026
  return;
52085
52027
  }
@@ -52087,7 +52029,7 @@ function useDroppable(_ref) {
52087
52029
  resizeObserverConnected.current = false;
52088
52030
  resizeObserver.observe(nodeRef.current);
52089
52031
  }, [nodeRef, resizeObserver]);
52090
- useEffect37(
52032
+ useEffect36(
52091
52033
  () => {
52092
52034
  dispatch({
52093
52035
  type: Action.RegisterDroppable,
@@ -52109,7 +52051,7 @@ function useDroppable(_ref) {
52109
52051
  // eslint-disable-next-line react-hooks/exhaustive-deps
52110
52052
  [id2]
52111
52053
  );
52112
- useEffect37(() => {
52054
+ useEffect36(() => {
52113
52055
  if (disabled !== previous3.current.disabled) {
52114
52056
  dispatch({
52115
52057
  type: Action.SetDroppableDisabled,
@@ -52131,7 +52073,7 @@ function useDroppable(_ref) {
52131
52073
  }
52132
52074
 
52133
52075
  // ../../node_modules/@dnd-kit/sortable/dist/sortable.esm.js
52134
- import React21, { useMemo as useMemo11, useRef as useRef30, useEffect as useEffect38, useState as useState29, useContext as useContext8 } from "react";
52076
+ import React21, { useMemo as useMemo11, useRef as useRef28, useEffect as useEffect37, useState as useState29, useContext as useContext8 } from "react";
52135
52077
  function arrayMove(array, from, to) {
52136
52078
  const newArray = array.slice();
52137
52079
  newArray.splice(to < 0 ? newArray.length + to : to, 0, newArray.splice(from, 1)[0]);
@@ -52289,7 +52231,7 @@ function SortableContext(_ref) {
52289
52231
  const isDragging = active != null;
52290
52232
  const activeIndex = active ? items.indexOf(active.id) : -1;
52291
52233
  const overIndex = over ? items.indexOf(over.id) : -1;
52292
- const previousItemsRef = useRef30(items);
52234
+ const previousItemsRef = useRef28(items);
52293
52235
  const itemsHaveChanged = !itemsEqual(items, previousItemsRef.current);
52294
52236
  const disableTransforms = overIndex !== -1 && activeIndex === -1 || itemsHaveChanged;
52295
52237
  const disabled = normalizeDisabled(disabledProp);
@@ -52298,7 +52240,7 @@ function SortableContext(_ref) {
52298
52240
  measureDroppableContainers(items);
52299
52241
  }
52300
52242
  }, [itemsHaveChanged, items, isDragging, measureDroppableContainers]);
52301
- useEffect38(() => {
52243
+ useEffect37(() => {
52302
52244
  previousItemsRef.current = items;
52303
52245
  }, [items]);
52304
52246
  const contextValue = useMemo11(
@@ -52373,7 +52315,7 @@ function useDerivedTransform(_ref) {
52373
52315
  rect
52374
52316
  } = _ref;
52375
52317
  const [derivedTransform, setDerivedtransform] = useState29(null);
52376
- const previousIndex = useRef30(index2);
52318
+ const previousIndex = useRef28(index2);
52377
52319
  useIsomorphicLayoutEffect(() => {
52378
52320
  if (!disabled && index2 !== previousIndex.current && node2.current) {
52379
52321
  const initial = rect.current;
@@ -52396,7 +52338,7 @@ function useDerivedTransform(_ref) {
52396
52338
  previousIndex.current = index2;
52397
52339
  }
52398
52340
  }, [disabled, index2, node2, rect]);
52399
- useEffect38(() => {
52341
+ useEffect37(() => {
52400
52342
  if (derivedTransform) {
52401
52343
  setDerivedtransform(null);
52402
52344
  }
@@ -52491,7 +52433,7 @@ function useSortable(_ref) {
52491
52433
  overIndex
52492
52434
  }) : index2;
52493
52435
  const activeId = active == null ? void 0 : active.id;
52494
- const previous3 = useRef30({
52436
+ const previous3 = useRef28({
52495
52437
  activeId,
52496
52438
  items,
52497
52439
  newIndex,
@@ -52518,7 +52460,7 @@ function useSortable(_ref) {
52518
52460
  node: node2,
52519
52461
  rect
52520
52462
  });
52521
- useEffect38(() => {
52463
+ useEffect37(() => {
52522
52464
  if (isSorting && previous3.current.newIndex !== newIndex) {
52523
52465
  previous3.current.newIndex = newIndex;
52524
52466
  }
@@ -52529,7 +52471,7 @@ function useSortable(_ref) {
52529
52471
  previous3.current.items = items;
52530
52472
  }
52531
52473
  }, [isSorting, newIndex, containerId, items]);
52532
- useEffect38(() => {
52474
+ useEffect37(() => {
52533
52475
  if (activeId === previous3.current.activeId) {
52534
52476
  return;
52535
52477
  }
@@ -52714,7 +52656,7 @@ function isAfter(a15, b8) {
52714
52656
  }
52715
52657
 
52716
52658
  // src/components/navigation/SortableResourceTab.tsx
52717
- import { useCallback as useCallback26, useRef as useRef31, useEffect as useEffect39 } from "react";
52659
+ import { useCallback as useCallback26, useRef as useRef29, useEffect as useEffect38 } from "react";
52718
52660
  import { jsx as jsx49, jsxs as jsxs39 } from "react/jsx-runtime";
52719
52661
  function SortableResourceTab({
52720
52662
  resource,
@@ -52737,8 +52679,8 @@ function SortableResourceTab({
52737
52679
  transition,
52738
52680
  isDragging: isSortableDragging
52739
52681
  } = useSortable({ id: resource.id });
52740
- const onReorderRef = useRef31(onReorder);
52741
- useEffect39(() => {
52682
+ const onReorderRef = useRef29(onReorder);
52683
+ useEffect38(() => {
52742
52684
  onReorderRef.current = onReorder;
52743
52685
  });
52744
52686
  const style = {
@@ -52865,7 +52807,7 @@ function CollapsibleResourceNavigation({
52865
52807
  const ChevronLeftIcon = icons.chevronLeft;
52866
52808
  const BarsIcon = icons.bars;
52867
52809
  const [isDropdownOpen, setIsDropdownOpen] = useState30(false);
52868
- const dropdownRef = useRef32(null);
52810
+ const dropdownRef = useRef30(null);
52869
52811
  const { announcePickup, announceDrop, announceKeyboardReorder, announceCannotMove } = useDragAnnouncements();
52870
52812
  const t12 = useTranslations("CollapsibleResourceNavigation");
52871
52813
  const eventBus = useEventBus();
@@ -52880,7 +52822,7 @@ function CollapsibleResourceNavigation({
52880
52822
  };
52881
52823
  const toggleDropdown = () => setIsDropdownOpen(!isDropdownOpen);
52882
52824
  const closeDropdown = () => setIsDropdownOpen(false);
52883
- useEffect40(() => {
52825
+ useEffect39(() => {
52884
52826
  const handleClickOutside = (event) => {
52885
52827
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
52886
52828
  closeDropdown();
@@ -53078,7 +53020,7 @@ function CollapsibleResourceNavigation({
53078
53020
  }
53079
53021
 
53080
53022
  // src/components/modals/SearchModal.tsx
53081
- import { useState as useState31, useEffect as useEffect41, Fragment as Fragment13 } from "react";
53023
+ import { useState as useState31, useEffect as useEffect40, Fragment as Fragment13 } from "react";
53082
53024
 
53083
53025
  // src/hooks/useSearchAnnouncements.ts
53084
53026
  import { useCallback as useCallback29 } from "react";
@@ -53135,7 +53077,7 @@ function SearchModal({
53135
53077
  enter: translations.enter || "Enter",
53136
53078
  esc: translations.esc || "ESC"
53137
53079
  };
53138
- useEffect41(() => {
53080
+ useEffect40(() => {
53139
53081
  const timer = setTimeout(() => {
53140
53082
  setDebouncedQuery(query);
53141
53083
  }, 300);
@@ -53143,7 +53085,7 @@ function SearchModal({
53143
53085
  }, [query]);
53144
53086
  const searchData = { resources: [], entities: [] };
53145
53087
  const loading = false;
53146
- useEffect41(() => {
53088
+ useEffect40(() => {
53147
53089
  if (isOpen) {
53148
53090
  setQuery("");
53149
53091
  setDebouncedQuery("");
@@ -53151,7 +53093,7 @@ function SearchModal({
53151
53093
  setSelectedIndex(0);
53152
53094
  }
53153
53095
  }, [isOpen]);
53154
- useEffect41(() => {
53096
+ useEffect40(() => {
53155
53097
  if (!debouncedQuery.trim()) {
53156
53098
  setResults([]);
53157
53099
  return;
@@ -53282,7 +53224,7 @@ function SearchModal({
53282
53224
  }
53283
53225
 
53284
53226
  // src/components/modals/ResourceSearchModal.tsx
53285
- import { useState as useState32, useEffect as useEffect42, Fragment as Fragment14 } from "react";
53227
+ import { useState as useState32, useEffect as useEffect41, Fragment as Fragment14 } from "react";
53286
53228
  import { jsx as jsx52, jsxs as jsxs42 } from "react/jsx-runtime";
53287
53229
  function ResourceSearchModal({
53288
53230
  isOpen,
@@ -53301,7 +53243,7 @@ function ResourceSearchModal({
53301
53243
  noResults: translations.noResults || "No documents found",
53302
53244
  close: translations.close || "\u2715"
53303
53245
  };
53304
- useEffect42(() => {
53246
+ useEffect41(() => {
53305
53247
  const timer = setTimeout(() => {
53306
53248
  setDebouncedSearch(search2);
53307
53249
  }, 300);
@@ -53323,17 +53265,17 @@ function ResourceSearchModal({
53323
53265
  mediaType
53324
53266
  };
53325
53267
  }) || [];
53326
- useEffect42(() => {
53268
+ useEffect41(() => {
53327
53269
  if (!loading && debouncedSearch) {
53328
53270
  announceSearchResults(results.length, debouncedSearch);
53329
53271
  }
53330
53272
  }, [loading, results.length, debouncedSearch]);
53331
- useEffect42(() => {
53273
+ useEffect41(() => {
53332
53274
  if (loading && debouncedSearch) {
53333
53275
  announceSearching();
53334
53276
  }
53335
53277
  }, [loading, debouncedSearch]);
53336
- useEffect42(() => {
53278
+ useEffect41(() => {
53337
53279
  if (isOpen && searchTerm) {
53338
53280
  setSearch(searchTerm);
53339
53281
  setDebouncedSearch(searchTerm);
@@ -53762,7 +53704,7 @@ function UnifiedHeader({
53762
53704
  }
53763
53705
 
53764
53706
  // src/components/layout/LeftSidebar.tsx
53765
- import { useState as useState34, useEffect as useEffect43 } from "react";
53707
+ import { useState as useState34, useEffect as useEffect42 } from "react";
53766
53708
  import { jsx as jsx59, jsxs as jsxs49 } from "react/jsx-runtime";
53767
53709
  function LeftSidebar({
53768
53710
  Link,
@@ -53787,7 +53729,7 @@ function LeftSidebar({
53787
53729
  // 25rem
53788
53730
  storageKey: "semiont-left-sidebar-width"
53789
53731
  });
53790
- useEffect43(() => {
53732
+ useEffect42(() => {
53791
53733
  if (collapsible) {
53792
53734
  const saved = localStorage.getItem(storageKey);
53793
53735
  if (saved === "true") {
@@ -55892,7 +55834,7 @@ function TagSchemasPage({
55892
55834
  }
55893
55835
 
55894
55836
  // src/features/resource-compose/components/ResourceComposePage.tsx
55895
- import { useState as useState37, useEffect as useEffect44 } from "react";
55837
+ import { useState as useState37, useEffect as useEffect43 } from "react";
55896
55838
  import { isImageMimeType, isPdfMimeType as isPdfMimeType4, LOCALES as LOCALES2 } from "@semiont/api-client";
55897
55839
  import { jsx as jsx76, jsxs as jsxs64 } from "react/jsx-runtime";
55898
55840
  function ResourceComposePage({
@@ -55923,7 +55865,7 @@ function ResourceComposePage({
55923
55865
  const [selectedLanguage, setSelectedLanguage] = useState37(initialLocale);
55924
55866
  const [selectedCharset, setSelectedCharset] = useState37("");
55925
55867
  const [archiveOriginal, setArchiveOriginal] = useState37(true);
55926
- useEffect44(() => {
55868
+ useEffect43(() => {
55927
55869
  if (mode === "clone" && cloneData) {
55928
55870
  setNewResourceName(cloneData.sourceResource.name);
55929
55871
  setNewResourceContent(cloneData.sourceContent);
@@ -55956,7 +55898,7 @@ function ResourceComposePage({
55956
55898
  reader.readAsText(file);
55957
55899
  }
55958
55900
  };
55959
- useEffect44(() => {
55901
+ useEffect43(() => {
55960
55902
  return () => {
55961
55903
  if (filePreviewUrl) {
55962
55904
  URL.revokeObjectURL(filePreviewUrl);
@@ -56304,7 +56246,7 @@ function ResourceComposePage({
56304
56246
  }
56305
56247
 
56306
56248
  // src/features/resource-discovery/components/ResourceDiscoveryPage.tsx
56307
- import { useState as useState38, useCallback as useCallback30, useRef as useRef33 } from "react";
56249
+ import { useState as useState38, useCallback as useCallback30, useRef as useRef31 } from "react";
56308
56250
  import { getResourceId as getResourceId2 } from "@semiont/api-client";
56309
56251
 
56310
56252
  // src/features/resource-discovery/components/ResourceCard.tsx
@@ -56395,7 +56337,7 @@ function ResourceDiscoveryPage({
56395
56337
  { orientation: "grid", cols: 2 }
56396
56338
  // 2 columns on medium+ screens
56397
56339
  );
56398
- const onNavigateToResourceRef = useRef33(onNavigateToResource);
56340
+ const onNavigateToResourceRef = useRef31(onNavigateToResource);
56399
56341
  onNavigateToResourceRef.current = onNavigateToResource;
56400
56342
  const handleEntityTypeFilter = useCallback30((entityType4) => {
56401
56343
  setSelectedEntityType(entityType4);
@@ -56538,13 +56480,13 @@ function ResourceDiscoveryPage({
56538
56480
  }
56539
56481
 
56540
56482
  // src/features/resource-viewer/components/ResourceViewerPage.tsx
56541
- import { useState as useState45, useEffect as useEffect50, useCallback as useCallback36, useMemo as useMemo12 } from "react";
56483
+ import { useState as useState44, useEffect as useEffect49, useCallback as useCallback35, useMemo as useMemo12 } from "react";
56542
56484
  import { useQueryClient as useQueryClient2 } from "@tanstack/react-query";
56543
56485
  import { getLanguage, getPrimaryRepresentation, resourceAnnotationUri as resourceAnnotationUri3, getPrimaryMediaType as getPrimaryMediaType2 } from "@semiont/api-client";
56544
56486
  import { uriToAnnotationId as uriToAnnotationId2 } from "@semiont/core";
56545
56487
 
56546
56488
  // src/hooks/useResolutionFlow.ts
56547
- import { useCallback as useCallback31, useEffect as useEffect45, useRef as useRef34, useState as useState39 } from "react";
56489
+ import { useCallback as useCallback31, useEffect as useEffect44, useRef as useRef32, useState as useState39 } from "react";
56548
56490
  import { resourceAnnotationUri, accessToken as accessToken3 } from "@semiont/api-client";
56549
56491
  import { uriToAnnotationIdOrPassthrough } from "@semiont/core";
56550
56492
  function toAccessToken2(token) {
@@ -56559,19 +56501,19 @@ function useResolutionFlow(rUri) {
56559
56501
  const onCloseSearchModal = useCallback31(() => {
56560
56502
  setSearchModalOpen(false);
56561
56503
  }, []);
56562
- const rUriRef = useRef34(rUri);
56563
- useEffect45(() => {
56504
+ const rUriRef = useRef32(rUri);
56505
+ useEffect44(() => {
56564
56506
  rUriRef.current = rUri;
56565
56507
  });
56566
- const clientRef = useRef34(client);
56567
- useEffect45(() => {
56508
+ const clientRef = useRef32(client);
56509
+ useEffect44(() => {
56568
56510
  clientRef.current = client;
56569
56511
  });
56570
- const tokenRef = useRef34(token);
56571
- useEffect45(() => {
56512
+ const tokenRef = useRef32(token);
56513
+ useEffect44(() => {
56572
56514
  tokenRef.current = token;
56573
56515
  });
56574
- useEffect45(() => {
56516
+ useEffect44(() => {
56575
56517
  const handleAnnotationUpdateBody = async (event) => {
56576
56518
  try {
56577
56519
  const annotationIdSegment = uriToAnnotationIdOrPassthrough(event.annotationUri);
@@ -56599,7 +56541,7 @@ function useResolutionFlow(rUri) {
56599
56541
  eventBus.off("reference:link", handleReferenceLink);
56600
56542
  };
56601
56543
  }, [eventBus]);
56602
- useEffect45(() => {
56544
+ useEffect44(() => {
56603
56545
  const handleResolutionSearchRequested = (event) => {
56604
56546
  setPendingReferenceId(event.referenceId);
56605
56547
  setSearchModalOpen(true);
@@ -56613,7 +56555,7 @@ function useResolutionFlow(rUri) {
56613
56555
  }
56614
56556
 
56615
56557
  // src/hooks/useDetectionFlow.ts
56616
- import { useState as useState40, useRef as useRef35, useEffect as useEffect46, useCallback as useCallback32 } from "react";
56558
+ import { useState as useState40, useRef as useRef33, useEffect as useEffect45, useCallback as useCallback32 } from "react";
56617
56559
  import { resourceAnnotationUri as resourceAnnotationUri2, accessToken as accessToken4, entityType as entityType3 } from "@semiont/api-client";
56618
56560
  import { uriToAnnotationIdOrPassthrough as uriToAnnotationIdOrPassthrough2 } from "@semiont/core";
56619
56561
  function toAccessToken3(token) {
@@ -56623,16 +56565,16 @@ function useDetectionFlow(rUri) {
56623
56565
  const eventBus = useEventBus();
56624
56566
  const client = useApiClient();
56625
56567
  const token = useAuthToken();
56626
- const clientRef = useRef35(client);
56627
- const rUriRef = useRef35(rUri);
56628
- const tokenRef = useRef35(token);
56629
- useEffect46(() => {
56568
+ const clientRef = useRef33(client);
56569
+ const rUriRef = useRef33(rUri);
56570
+ const tokenRef = useRef33(token);
56571
+ useEffect45(() => {
56630
56572
  clientRef.current = client;
56631
56573
  });
56632
- useEffect46(() => {
56574
+ useEffect45(() => {
56633
56575
  rUriRef.current = rUri;
56634
56576
  });
56635
- useEffect46(() => {
56577
+ useEffect45(() => {
56636
56578
  tokenRef.current = token;
56637
56579
  });
56638
56580
  const [pendingAnnotation, setPendingAnnotation] = useState40(null);
@@ -56704,8 +56646,8 @@ function useDetectionFlow(rUri) {
56704
56646
  }, []);
56705
56647
  const [detectingMotivation, setDetectingMotivation] = useState40(null);
56706
56648
  const [detectionProgress, setDetectionProgress] = useState40(null);
56707
- const detectionStreamRef = useRef35(null);
56708
- const progressDismissTimeoutRef = useRef35(null);
56649
+ const detectionStreamRef = useRef33(null);
56650
+ const progressDismissTimeoutRef = useRef33(null);
56709
56651
  const handleDetectionProgress = useCallback32((chunk) => {
56710
56652
  setDetectionProgress(chunk);
56711
56653
  }, []);
@@ -56739,7 +56681,7 @@ function useDetectionFlow(rUri) {
56739
56681
  }
56740
56682
  setDetectionProgress(null);
56741
56683
  }, []);
56742
- useEffect46(() => {
56684
+ useEffect45(() => {
56743
56685
  const handleAnnotationCreate = async (event) => {
56744
56686
  const currentClient = clientRef.current;
56745
56687
  const currentRUri = rUriRef.current;
@@ -56754,6 +56696,7 @@ function useDetectionFlow(rUri) {
56754
56696
  body: event.body
56755
56697
  }, { auth: toAccessToken3(tokenRef.current) });
56756
56698
  if (result.annotation) {
56699
+ setPendingAnnotation(null);
56757
56700
  eventBus.emit("annotation:created", { annotation: result.annotation });
56758
56701
  }
56759
56702
  } catch (error) {
@@ -56925,7 +56868,7 @@ function useDetectionFlow(rUri) {
56925
56868
  "detection:failed": handleDetectionFailed,
56926
56869
  "detection:dismiss-progress": handleDetectionDismissProgress
56927
56870
  });
56928
- useEffect46(() => {
56871
+ useEffect45(() => {
56929
56872
  return () => {
56930
56873
  if (progressDismissTimeoutRef.current) {
56931
56874
  clearTimeout(progressDismissTimeoutRef.current);
@@ -56940,40 +56883,19 @@ function useDetectionFlow(rUri) {
56940
56883
  };
56941
56884
  }
56942
56885
 
56943
- // src/hooks/useAttentionFlow.ts
56944
- import { useState as useState41, useCallback as useCallback33 } from "react";
56945
- function useAttentionFlow() {
56946
- const eventBus = useEventBus();
56947
- const [hoveredAnnotationId, setHoveredAnnotationId] = useState41(null);
56948
- const handleAnnotationHover = useCallback33(({ annotationId }) => {
56949
- setHoveredAnnotationId(annotationId);
56950
- if (annotationId) {
56951
- eventBus.emit("annotation:sparkle", { annotationId });
56952
- }
56953
- }, []);
56954
- const handleAnnotationClick = useCallback33(({ annotationId }) => {
56955
- eventBus.emit("annotation:focus", { annotationId });
56956
- }, []);
56957
- useEventSubscriptions({
56958
- "annotation:hover": handleAnnotationHover,
56959
- "annotation:click": handleAnnotationClick
56960
- });
56961
- return { hoveredAnnotationId };
56962
- }
56963
-
56964
56886
  // src/hooks/usePanelNavigation.ts
56965
- import { useState as useState42, useCallback as useCallback34, useEffect as useEffect47 } from "react";
56887
+ import { useState as useState41, useCallback as useCallback33, useEffect as useEffect46 } from "react";
56966
56888
  function usePanelNavigation() {
56967
- const [activePanel, setActivePanel] = useState42(() => {
56889
+ const [activePanel, setActivePanel] = useState41(() => {
56968
56890
  if (typeof window !== "undefined") {
56969
56891
  const saved = localStorage.getItem("activeToolbarPanel");
56970
56892
  return saved || null;
56971
56893
  }
56972
56894
  return null;
56973
56895
  });
56974
- const [scrollToAnnotationId, setScrollToAnnotationId] = useState42(null);
56975
- const [panelInitialTab, setPanelInitialTab] = useState42(null);
56976
- useEffect47(() => {
56896
+ const [scrollToAnnotationId, setScrollToAnnotationId] = useState41(null);
56897
+ const [panelInitialTab, setPanelInitialTab] = useState41(null);
56898
+ useEffect46(() => {
56977
56899
  if (typeof window === "undefined") return;
56978
56900
  if (activePanel) {
56979
56901
  localStorage.setItem("activeToolbarPanel", activePanel);
@@ -56981,13 +56903,13 @@ function usePanelNavigation() {
56981
56903
  localStorage.removeItem("activeToolbarPanel");
56982
56904
  }
56983
56905
  }, [activePanel]);
56984
- const handleScrollCompleted = useCallback34(() => {
56906
+ const handleScrollCompleted = useCallback33(() => {
56985
56907
  setScrollToAnnotationId(null);
56986
56908
  }, []);
56987
- const handlePanelToggle = useCallback34(({ panel }) => {
56909
+ const handlePanelToggle = useCallback33(({ panel }) => {
56988
56910
  setActivePanel((current) => current === panel ? null : panel);
56989
56911
  }, []);
56990
- const handlePanelOpen = useCallback34(({ panel, scrollToAnnotationId: scrollTarget, motivation }) => {
56912
+ const handlePanelOpen = useCallback33(({ panel, scrollToAnnotationId: scrollTarget, motivation }) => {
56991
56913
  if (scrollTarget) {
56992
56914
  setScrollToAnnotationId(scrollTarget);
56993
56915
  }
@@ -57004,7 +56926,7 @@ function usePanelNavigation() {
57004
56926
  }
57005
56927
  setActivePanel(panel);
57006
56928
  }, []);
57007
- const handlePanelClose = useCallback34(() => {
56929
+ const handlePanelClose = useCallback33(() => {
57008
56930
  setActivePanel(null);
57009
56931
  }, []);
57010
56932
  useEventSubscriptions({
@@ -57021,7 +56943,7 @@ function usePanelNavigation() {
57021
56943
  }
57022
56944
 
57023
56945
  // src/hooks/useGenerationFlow.ts
57024
- import { useState as useState43, useCallback as useCallback35, useEffect as useEffect48, useRef as useRef36 } from "react";
56946
+ import { useState as useState42, useCallback as useCallback34, useEffect as useEffect47, useRef as useRef34 } from "react";
57025
56947
  import { annotationUri, accessToken as accessToken5 } from "@semiont/api-client";
57026
56948
  function toAccessToken4(token) {
57027
56949
  return token ? accessToken5(token) : void 0;
@@ -57030,28 +56952,28 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
57030
56952
  const eventBus = useEventBus();
57031
56953
  const client = useApiClient();
57032
56954
  const token = useAuthToken();
57033
- const clientRef = useRef36(client);
57034
- const tokenRef = useRef36(token);
57035
- useEffect48(() => {
56955
+ const clientRef = useRef34(client);
56956
+ const tokenRef = useRef34(token);
56957
+ useEffect47(() => {
57036
56958
  clientRef.current = client;
57037
56959
  });
57038
- useEffect48(() => {
56960
+ useEffect47(() => {
57039
56961
  tokenRef.current = token;
57040
56962
  });
57041
- const generationStreamRef = useRef36(null);
57042
- const [isGenerating, setIsGenerating] = useState43(false);
57043
- const [generationProgress, setGenerationProgress] = useState43(null);
57044
- const handleProgressEvent = useCallback35((chunk) => {
56963
+ const generationStreamRef = useRef34(null);
56964
+ const [isGenerating, setIsGenerating] = useState42(false);
56965
+ const [generationProgress, setGenerationProgress] = useState42(null);
56966
+ const handleProgressEvent = useCallback34((chunk) => {
57045
56967
  setGenerationProgress(chunk);
57046
56968
  setIsGenerating(true);
57047
56969
  }, []);
57048
- const clearProgress = useCallback35(() => {
56970
+ const clearProgress = useCallback34(() => {
57049
56971
  setGenerationProgress(null);
57050
56972
  }, []);
57051
- const [generationModalOpen, setGenerationModalOpen] = useState43(false);
57052
- const [generationReferenceId, setGenerationReferenceId] = useState43(null);
57053
- const [generationDefaultTitle, setGenerationDefaultTitle] = useState43("");
57054
- const handleGenerateDocument = useCallback35((referenceId, options) => {
56973
+ const [generationModalOpen, setGenerationModalOpen] = useState42(false);
56974
+ const [generationReferenceId, setGenerationReferenceId] = useState42(null);
56975
+ const [generationDefaultTitle, setGenerationDefaultTitle] = useState42("");
56976
+ const handleGenerateDocument = useCallback34((referenceId, options) => {
57055
56977
  if (!options.context) {
57056
56978
  setGenerationReferenceId(referenceId);
57057
56979
  setGenerationDefaultTitle(options.title);
@@ -57072,16 +56994,16 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
57072
56994
  }
57073
56995
  });
57074
56996
  }, [resourceId, clearNewAnnotationId, locale]);
57075
- const handleCloseGenerationModal = useCallback35(() => {
56997
+ const handleCloseGenerationModal = useCallback34(() => {
57076
56998
  setGenerationModalOpen(false);
57077
56999
  }, []);
57078
- const handleGenerationModalOpen = useCallback35(({ annotationUri: annUri, resourceUri: resourceUri2, defaultTitle }) => {
57000
+ const handleGenerationModalOpen = useCallback34(({ annotationUri: annUri, resourceUri: resourceUri2, defaultTitle }) => {
57079
57001
  setGenerationReferenceId(annUri);
57080
57002
  setGenerationDefaultTitle(defaultTitle);
57081
57003
  setGenerationModalOpen(true);
57082
57004
  eventBus.emit("context:retrieval-requested", { annotationUri: annUri, resourceUri: resourceUri2 });
57083
57005
  }, []);
57084
- const handleGenerationComplete = useCallback35(({ progress }) => {
57006
+ const handleGenerationComplete = useCallback34(({ progress }) => {
57085
57007
  setGenerationProgress(progress);
57086
57008
  setIsGenerating(false);
57087
57009
  if (progress.resourceName) {
@@ -57094,12 +57016,12 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
57094
57016
  }
57095
57017
  setTimeout(() => clearProgress(), 2e3);
57096
57018
  }, [showSuccess, cacheManager, clearProgress]);
57097
- const handleGenerationFailed = useCallback35(({ error }) => {
57019
+ const handleGenerationFailed = useCallback34(({ error }) => {
57098
57020
  setGenerationProgress(null);
57099
57021
  setIsGenerating(false);
57100
57022
  showError(`Resource generation failed: ${error.message}`);
57101
57023
  }, [showError]);
57102
- useEffect48(() => {
57024
+ useEffect47(() => {
57103
57025
  const handleGenerationStart = async (event) => {
57104
57026
  console.log("[useGenerationFlow] handleGenerationStart called", { annotationUri: event.annotationUri, options: event.options });
57105
57027
  try {
@@ -57180,26 +57102,26 @@ function useGenerationFlow(locale, resourceId, showSuccess, showError, cacheMana
57180
57102
  }
57181
57103
 
57182
57104
  // src/hooks/useContextRetrievalFlow.ts
57183
- import { useState as useState44, useEffect as useEffect49, useRef as useRef37 } from "react";
57105
+ import { useState as useState43, useEffect as useEffect48, useRef as useRef35 } from "react";
57184
57106
  import { accessToken as accessToken6 } from "@semiont/api-client";
57185
57107
  function toAccessToken5(token) {
57186
57108
  return token ? accessToken6(token) : void 0;
57187
57109
  }
57188
57110
  function useContextRetrievalFlow(emitter, config) {
57189
57111
  const token = useAuthToken();
57190
- const [retrievalContext, setRetrievalContext] = useState44(null);
57191
- const [retrievalLoading, setRetrievalLoading] = useState44(false);
57192
- const [retrievalError, setRetrievalError] = useState44(null);
57193
- const [retrievalAnnotationUri, setRetrievalAnnotationUri] = useState44(null);
57194
- const configRef = useRef37(config);
57195
- const tokenRef = useRef37(token);
57196
- useEffect49(() => {
57112
+ const [retrievalContext, setRetrievalContext] = useState43(null);
57113
+ const [retrievalLoading, setRetrievalLoading] = useState43(false);
57114
+ const [retrievalError, setRetrievalError] = useState43(null);
57115
+ const [retrievalAnnotationUri, setRetrievalAnnotationUri] = useState43(null);
57116
+ const configRef = useRef35(config);
57117
+ const tokenRef = useRef35(token);
57118
+ useEffect48(() => {
57197
57119
  configRef.current = config;
57198
57120
  });
57199
- useEffect49(() => {
57121
+ useEffect48(() => {
57200
57122
  tokenRef.current = token;
57201
57123
  });
57202
- useEffect49(() => {
57124
+ useEffect48(() => {
57203
57125
  const handleContextRetrievalRequested = async (event) => {
57204
57126
  setRetrievalLoading(true);
57205
57127
  setRetrievalError(null);
@@ -57294,7 +57216,7 @@ function ResourceViewerPage({
57294
57216
  },
57295
57217
  500
57296
57218
  );
57297
- useEffect50(() => {
57219
+ useEffect49(() => {
57298
57220
  if (resource && rUri) {
57299
57221
  const resourceIdSegment = rUri.split("/").pop() || "";
57300
57222
  const mediaType = getPrimaryMediaType2(resource);
@@ -57308,13 +57230,13 @@ function ResourceViewerPage({
57308
57230
  rUri,
57309
57231
  autoConnect: true,
57310
57232
  // Annotation events - use debounced invalidation to batch rapid updates
57311
- onAnnotationAdded: useCallback36((_event) => {
57233
+ onAnnotationAdded: useCallback35((_event) => {
57312
57234
  debouncedInvalidateAnnotations();
57313
57235
  }, [debouncedInvalidateAnnotations]),
57314
- onAnnotationRemoved: useCallback36((_event) => {
57236
+ onAnnotationRemoved: useCallback35((_event) => {
57315
57237
  debouncedInvalidateAnnotations();
57316
57238
  }, [debouncedInvalidateAnnotations]),
57317
- onAnnotationBodyUpdated: useCallback36((event) => {
57239
+ onAnnotationBodyUpdated: useCallback35((event) => {
57318
57240
  queryClient.setQueryData(QUERY_KEYS.resources.annotations(rUri), (old) => {
57319
57241
  if (!old) return old;
57320
57242
  return {
@@ -57351,30 +57273,30 @@ function ResourceViewerPage({
57351
57273
  queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(rUri) });
57352
57274
  }, [queryClient, rUri]),
57353
57275
  // Document status events
57354
- onDocumentArchived: useCallback36((_event) => {
57276
+ onDocumentArchived: useCallback35((_event) => {
57355
57277
  refetchDocument();
57356
57278
  showSuccess("This document has been archived");
57357
57279
  debouncedInvalidateAnnotations();
57358
57280
  }, [refetchDocument, showSuccess, debouncedInvalidateAnnotations]),
57359
- onDocumentUnarchived: useCallback36((_event) => {
57281
+ onDocumentUnarchived: useCallback35((_event) => {
57360
57282
  refetchDocument();
57361
57283
  showSuccess("This document has been unarchived");
57362
57284
  debouncedInvalidateAnnotations();
57363
57285
  }, [refetchDocument, showSuccess, debouncedInvalidateAnnotations]),
57364
57286
  // Entity tag events
57365
- onEntityTagAdded: useCallback36((_event) => {
57287
+ onEntityTagAdded: useCallback35((_event) => {
57366
57288
  refetchDocument();
57367
57289
  debouncedInvalidateAnnotations();
57368
57290
  }, [refetchDocument, debouncedInvalidateAnnotations]),
57369
- onEntityTagRemoved: useCallback36((_event) => {
57291
+ onEntityTagRemoved: useCallback35((_event) => {
57370
57292
  refetchDocument();
57371
57293
  debouncedInvalidateAnnotations();
57372
57294
  }, [refetchDocument, debouncedInvalidateAnnotations]),
57373
- onError: useCallback36((error) => {
57295
+ onError: useCallback35((error) => {
57374
57296
  console.error("[RealTime] Event stream error:", error);
57375
57297
  }, [])
57376
57298
  });
57377
- const handleResourceArchive = useCallback36(async () => {
57299
+ const handleResourceArchive = useCallback35(async () => {
57378
57300
  try {
57379
57301
  await resources.update.useMutation().mutateAsync({ rUri, data: { archived: true } });
57380
57302
  await refetchDocument();
@@ -57384,7 +57306,7 @@ function ResourceViewerPage({
57384
57306
  showError("Failed to archive document");
57385
57307
  }
57386
57308
  }, [resources.update, rUri, refetchDocument, showSuccess, showError]);
57387
- const handleResourceUnarchive = useCallback36(async () => {
57309
+ const handleResourceUnarchive = useCallback35(async () => {
57388
57310
  try {
57389
57311
  await resources.update.useMutation().mutateAsync({ rUri, data: { archived: false } });
57390
57312
  await refetchDocument();
@@ -57394,7 +57316,7 @@ function ResourceViewerPage({
57394
57316
  showError("Failed to unarchive document");
57395
57317
  }
57396
57318
  }, [resources.update, rUri, refetchDocument, showSuccess, showError]);
57397
- const handleResourceClone = useCallback36(async () => {
57319
+ const handleResourceClone = useCallback35(async () => {
57398
57320
  try {
57399
57321
  const result2 = await resources.generateCloneToken.useMutation().mutateAsync(rUri);
57400
57322
  const token = result2.token;
@@ -57406,34 +57328,34 @@ function ResourceViewerPage({
57406
57328
  showError("Failed to generate clone link");
57407
57329
  }
57408
57330
  }, [resources.generateCloneToken, rUri, showSuccess, showError]);
57409
- const handleAnnotationSparkle = useCallback36(({ annotationId }) => {
57331
+ const handleAnnotationSparkle = useCallback35(({ annotationId }) => {
57410
57332
  triggerSparkleAnimation(annotationId);
57411
57333
  }, [triggerSparkleAnimation]);
57412
- const handleAnnotationCreated = useCallback36(({ annotation }) => {
57334
+ const handleAnnotationCreated = useCallback35(({ annotation }) => {
57413
57335
  triggerSparkleAnimation(annotation.id);
57414
57336
  debouncedInvalidateAnnotations();
57415
57337
  }, [triggerSparkleAnimation, debouncedInvalidateAnnotations]);
57416
- const handleAnnotationCreateFailed = useCallback36(() => showError("Failed to create annotation"), [showError]);
57417
- const handleAnnotationDeleteFailed = useCallback36(() => showError("Failed to delete annotation"), [showError]);
57418
- const handleAnnotationBodyUpdated = useCallback36(() => {
57338
+ const handleAnnotationCreateFailed = useCallback35(() => showError("Failed to create annotation"), [showError]);
57339
+ const handleAnnotationDeleteFailed = useCallback35(() => showError("Failed to delete annotation"), [showError]);
57340
+ const handleAnnotationBodyUpdated = useCallback35(() => {
57419
57341
  }, []);
57420
- const handleAnnotationBodyUpdateFailed = useCallback36(() => showError("Failed to update annotation"), [showError]);
57421
- const handleSettingsThemeChanged = useCallback36(({ theme: theme3 }) => setTheme(theme3), [setTheme]);
57422
- const handleDetectionComplete = useCallback36(() => {
57342
+ const handleAnnotationBodyUpdateFailed = useCallback35(() => showError("Failed to update annotation"), [showError]);
57343
+ const handleSettingsThemeChanged = useCallback35(({ theme: theme3 }) => setTheme(theme3), [setTheme]);
57344
+ const handleDetectionComplete = useCallback35(() => {
57423
57345
  showSuccess("Detection complete");
57424
57346
  queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.annotations(rUri) });
57425
57347
  queryClient.invalidateQueries({ queryKey: QUERY_KEYS.resources.events(rUri) });
57426
57348
  }, [showSuccess, queryClient, rUri]);
57427
- const handleDetectionFailed = useCallback36(() => showError("Detection failed"), [showError]);
57428
- const handleGenerationComplete = useCallback36(() => showSuccess("Document generated"), [showSuccess]);
57429
- const handleGenerationFailed = useCallback36(() => showError("Failed to generate document"), [showError]);
57430
- const handleReferenceNavigate = useCallback36(({ documentId }) => {
57349
+ const handleDetectionFailed = useCallback35(() => showError("Detection failed"), [showError]);
57350
+ const handleGenerationComplete = useCallback35(() => showSuccess("Document generated"), [showSuccess]);
57351
+ const handleGenerationFailed = useCallback35(() => showError("Failed to generate document"), [showError]);
57352
+ const handleReferenceNavigate = useCallback35(({ documentId }) => {
57431
57353
  if (routes.resource) {
57432
57354
  const path2 = routes.resource.replace("[resourceId]", encodeURIComponent(documentId));
57433
57355
  eventBus.emit("navigation:router-push", { path: path2, reason: "reference-link" });
57434
57356
  }
57435
57357
  }, [routes.resource]);
57436
- const handleEntityTypeClicked = useCallback36(({ entityType: entityType4 }) => {
57358
+ const handleEntityTypeClicked = useCallback35(({ entityType: entityType4 }) => {
57437
57359
  if (routes.know) {
57438
57360
  const path2 = `${routes.know}?entityType=${encodeURIComponent(entityType4)}`;
57439
57361
  eventBus.emit("navigation:router-push", { path: path2, reason: "entity-type-filter" });
@@ -57463,7 +57385,7 @@ function ResourceViewerPage({
57463
57385
  announceResourceLoading,
57464
57386
  announceResourceLoaded
57465
57387
  } = useResourceLoadingAnnouncements();
57466
- useEffect50(() => {
57388
+ useEffect49(() => {
57467
57389
  if (contentLoading) {
57468
57390
  announceResourceLoading(resource.name);
57469
57391
  } else if (content4) {
@@ -57474,7 +57396,7 @@ function ResourceViewerPage({
57474
57396
  const primaryRep = getPrimaryRepresentation(resource);
57475
57397
  const primaryMediaType = primaryRep?.mediaType;
57476
57398
  const primaryByteSize = primaryRep?.byteSize;
57477
- const [annotateMode, _setAnnotateMode] = useState45(() => {
57399
+ const [annotateMode, _setAnnotateMode] = useState44(() => {
57478
57400
  if (typeof window !== "undefined") {
57479
57401
  return localStorage.getItem("annotateMode") === "true";
57480
57402
  }
@@ -57498,12 +57420,12 @@ function ResourceViewerPage({
57498
57420
  }
57499
57421
  const groups = result;
57500
57422
  const resourceWithContent = { ...resource, content: content4 };
57501
- const handleEventHover = useCallback36((annotationId) => {
57423
+ const handleEventHover = useCallback35((annotationId) => {
57502
57424
  if (annotationId) {
57503
57425
  eventBus.emit("annotation:sparkle", { annotationId });
57504
57426
  }
57505
57427
  }, []);
57506
- const handleEventClick = useCallback36((_annotationId) => {
57428
+ const handleEventClick = useCallback35((_annotationId) => {
57507
57429
  }, []);
57508
57430
  return /* @__PURE__ */ jsxs67("div", { className: `semiont-document-viewer${activePanel ? " semiont-document-viewer--panel-open" : ""}`, children: [
57509
57431
  /* @__PURE__ */ jsxs67("div", { className: "semiont-document-viewer__main", children: [
@@ -57701,6 +57623,7 @@ export {
57701
57623
  ErrorBoundary,
57702
57624
  EventBusProvider,
57703
57625
  Footer,
57626
+ HOVER_DELAY_MS,
57704
57627
  HighlightEntry,
57705
57628
  HighlightPanel,
57706
57629
  HistoryEvent,
@@ -57769,6 +57692,7 @@ export {
57769
57692
  buttonStyles,
57770
57693
  createCancelDetectionHandler,
57771
57694
  createDetectionHandler,
57695
+ createHoverHandlers,
57772
57696
  cssVariables,
57773
57697
  dispatch401Error,
57774
57698
  dispatch403Error,
@@ -57819,6 +57743,7 @@ export {
57819
57743
  useFormAnnouncements,
57820
57744
  useGenerationFlow,
57821
57745
  useHealth,
57746
+ useHoverEmitter,
57822
57747
  useIsTyping,
57823
57748
  useKeyboardShortcuts,
57824
57749
  useLanguageChangeAnnouncements,