superdoc 1.0.0-beta.30 → 1.0.0-beta.32

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 (27) hide show
  1. package/dist/chunks/{PdfViewer-BADCvUNL.cjs → PdfViewer-CTKbqDWv.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-C2nY5qD8.es.js → PdfViewer-edjIRb_p.es.js} +1 -1
  3. package/dist/chunks/{index-DTgPk1zO.cjs → index-Cajp7-Xa.cjs} +3 -3
  4. package/dist/chunks/{index-DmelLGEj.es.js → index-Pwv0a9G5.es.js} +3 -3
  5. package/dist/chunks/{index-DUzV7kkk-BvBMF_lo.es.js → index-SGV4U12y-BPGxOtvI.es.js} +1 -1
  6. package/dist/chunks/{index-DUzV7kkk-CM3uwGCb.cjs → index-SGV4U12y-Dh5jaROA.cjs} +1 -1
  7. package/dist/chunks/{super-editor.es-463G9jKM.cjs → super-editor.es-BbbbKgEs.cjs} +1729 -105
  8. package/dist/chunks/{super-editor.es-Be9785LD.es.js → super-editor.es-CdGsYGU1.es.js} +1729 -105
  9. package/dist/super-editor/ai-writer.es.js +2 -2
  10. package/dist/super-editor/chunks/{converter-U59bT3FO.js → converter-CpuOoAUa.js} +1 -1
  11. package/dist/super-editor/chunks/{docx-zipper-DSnoGkju.js → docx-zipper-Dk99r397.js} +1 -1
  12. package/dist/super-editor/chunks/{editor-DRHVtMIR.js → editor-CFv-RJI-.js} +1776 -90
  13. package/dist/super-editor/chunks/{index-DUzV7kkk.js → index-SGV4U12y.js} +1 -1
  14. package/dist/super-editor/chunks/{toolbar-DbBLxo6N.js → toolbar-CQr3Xnx9.js} +2 -2
  15. package/dist/super-editor/converter.es.js +1 -1
  16. package/dist/super-editor/docx-zipper.es.js +2 -2
  17. package/dist/super-editor/editor.es.js +3 -3
  18. package/dist/super-editor/file-zipper.es.js +1 -1
  19. package/dist/super-editor/super-editor.es.js +6 -6
  20. package/dist/super-editor/toolbar.es.js +2 -2
  21. package/dist/super-editor.cjs +1 -1
  22. package/dist/super-editor.es.js +1 -1
  23. package/dist/superdoc.cjs +2 -2
  24. package/dist/superdoc.es.js +2 -2
  25. package/dist/superdoc.umd.js +1715 -91
  26. package/dist/superdoc.umd.js.map +1 -1
  27. package/package.json +1 -1
@@ -41859,7 +41859,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
41859
41859
  static getStoredSuperdocVersion(docx) {
41860
41860
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
41861
41861
  }
41862
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.30") {
41862
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.32") {
41863
41863
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
41864
41864
  }
41865
41865
  /**
@@ -53022,7 +53022,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
53022
53022
  var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
53023
53023
  var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
53024
53024
  var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
53025
- var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, dispatchWithFallback_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, getPluginKeyName_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _map, _editor2, _descriptors, _collections, _editorEntries, _maxCachedEditors, _editorAccessOrder, _pendingCreations, _cacheHits, _cacheMisses, _evictions, _HeaderFooterEditorManager_instances, hasConverter_fn, extractCollections_fn, collectDescriptors_fn, teardownMissingEditors_fn, teardownEditors_fn, createEditor_fn, createEditorContainer_fn, registerConverterEditor_fn, unregisterConverterEditor_fn, updateAccessOrder_fn, enforceCacheSizeLimit_fn, _manager, _mediaFiles, _blockCache, _HeaderFooterLayoutAdapter_instances, getBlocks_fn, getConverterContext_fn, _selectionOverlay, _activeEditorHost, _activeDecorationContainer, _activeRegion, _borderLine, _dimmingOverlay, _EditorOverlayManager_instances, findDecorationContainer_fn, ensureEditorHost_fn, positionEditorHost_fn, showHeaderFooterBorder_fn, hideHeaderFooterBorder_fn, _instances, _options, _editor3, _visibleHost, _viewportHost, _painterHost, _selectionOverlay2, _hiddenHost, _layoutOptions, _layoutState, _domPainter, _layoutError, _layoutErrorState, _errorBanner, _errorBannerMessage, _telemetryEmitter, _renderScheduled, _pendingDocChange, _isRerendering, _selectionUpdateScheduled, _remoteCursorUpdateScheduled, _rafHandle, _editorListeners, _sectionMetadata, _documentMode, _inputBridge, _trackedChangesMode, _trackedChangesEnabled, _trackedChangesOverrides, _headerFooterManager, _headerFooterAdapter, _headerFooterIdentifier, _multiSectionIdentifier, _headerLayoutResults, _footerLayoutResults, _headerLayoutsByRId, _footerLayoutsByRId, _headerDecorationProvider, _footerDecorationProvider, _headerFooterManagerCleanups, _headerRegions, _footerRegions, _session, _activeHeaderFooterEditor, _overlayManager, _hoverOverlay, _hoverTooltip, _modeBanner, _ariaLiveRegion, _hoverRegion, _clickCount, _lastClickTime, _lastClickPosition, _lastSelectedImageBlockId, _remoteCursorState, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _remoteCursorRafHandle, _scrollTimeout, _PresentationEditor_instances, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, normalizeAwarenessStates_fn, getFallbackColor_fn, getValidatedColor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_fn, renderRemoteCaret_fn, renderRemoteCursorLabel_fn, renderRemoteSelection_fn, setupPointerHandlers_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, selectWordAt_fn, selectParagraphAt_fn, isWordCharacter_fn, _handlePointerMove, _handlePointerLeave, _handleDoubleClick, _handleKeyDown, focusHeaderFooterShortcut_fn, scheduleRerender_fn, flushRerenderQueue_fn, rerender_fn, ensurePainter_fn, scheduleSelectionUpdate_fn, updateSelection_fn, resolveLayoutOptions_fn, buildHeaderFooterInput_fn, computeHeaderFooterConstraints_fn, layoutPerRIdHeaderFooters_fn, updateDecorationProviders_fn, createDecorationProvider_fn, findHeaderFooterPageForPageNumber_fn, computeDecorationBox_fn, rebuildHeaderFooterRegions_fn, hitTestHeaderFooterRegion_fn, pointInRegion_fn, activateHeaderFooterRegion_fn, enterHeaderFooterMode_fn, exitHeaderFooterMode_fn, getActiveDomTarget_fn, emitHeaderFooterModeChanged_fn, emitHeaderFooterEditingContext_fn, updateAwarenessSession_fn, updateModeBanner_fn, announce_fn, validateHeaderFooterEditPermission_fn, emitHeaderFooterEditBlocked_fn, resolveDescriptorForRegion_fn, createDefaultHeaderFooter_fn, getPageElement_fn, scrollPageIntoView_fn, waitForPageMount_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, renderSelectionRects_fn, renderHoverRegion_fn, clearHoverRegion_fn, renderCaretOverlay_fn, getHeaderFooterContext_fn, computeHeaderFooterSelectionRects_fn, syncTrackedChangesPreferences_fn, deriveTrackedChangesMode_fn, deriveTrackedChangesEnabled_fn, getTrackChangesPluginState_fn, computeDefaultLayoutDefaults_fn, parseColumns_fn, inchesToPx_fn, applyZoom_fn, createLayoutMetrics_fn, convertPageLocalToOverlayCoords_fn, normalizeClientPoint_fn, computeCaretLayoutRect_fn, computeCaretLayoutRectFromDOM_fn, computeTableCaretLayoutRect_fn, findLineContainingPos_fn, lineHeightBeforeIndex_fn, getCurrentPageIndex_fn, findRegionForPage_fn, handleLayoutError_fn, decorateError_fn, showLayoutErrorBanner_fn, dismissErrorBanner_fn, createHiddenHost_fn, _windowRoot, _layoutSurfaces, _getTargetDom, _isEditable, _onTargetChanged, _listeners, _currentTarget, _destroyed, _useWindowFallback, _PresentationInputBridge_instances, addListener_fn, dispatchToTarget_fn, forwardKeyboardEvent_fn, forwardTextEvent_fn, forwardCompositionEvent_fn, forwardContextMenu_fn, isEventOnActiveTarget_fn, shouldSkipSurface_fn, isInLayoutSurface_fn, getListenerTargets_fn, isPlainCharacterKey_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ParagraphNodeView_instances, checkShouldUpdate_fn, updateHTMLAttributes_fn, updateDOMStyles_fn, resolveNeighborParagraphProperties_fn, updateListStyles_fn, initList_fn, checkIsList_fn, createMarker_fn, createSeparator_fn, calculateTabSeparatorStyle_fn, calculateMarkerStyle_fn, removeList_fn, getParagraphContext_fn, scheduleAnimation_fn, cancelScheduledAnimation_fn, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn, _VectorShapeView_instances, ensureParentPositioned_fn, _ShapeGroupView_instances, ensureParentPositioned_fn2;
53025
+ var _Attribute_static, getGlobalAttributes_fn, getNodeAndMarksAttributes_fn, _Schema_static, createNodesSchema_fn, createMarksSchema_fn, _events, _ExtensionService_instances, setupExtensions_fn, attachEditorEvents_fn, _editor, _stateValidators, _xmlValidators, _requiredNodeTypes, _requiredMarkTypes, _SuperValidator_instances, initializeValidators_fn, collectValidatorRequirements_fn, analyzeDocument_fn, dispatchWithFallback_fn, _commandService, _Editor_instances, initContainerElement_fn, init_fn, initRichText_fn, onFocus_fn, checkHeadless_fn, registerCopyHandler_fn, insertNewFileData_fn, getPluginKeyName_fn, createExtensionService_fn, createCommandService_fn, createConverter_fn, initMedia_fn, initFonts_fn, checkFonts_fn, determineUnsupportedFonts_fn, createSchema_fn, generatePmData_fn, createView_fn, onCollaborationReady_fn, initComments_fn, dispatchTransaction_fn, handleNodeSelection_fn, prepareDocumentForImport_fn, prepareDocumentForExport_fn, endCollaboration_fn, validateDocumentInit_fn, validateDocumentExport_fn, initDevTools_fn, _map, _editor2, _descriptors, _collections, _editorEntries, _maxCachedEditors, _editorAccessOrder, _pendingCreations, _cacheHits, _cacheMisses, _evictions, _HeaderFooterEditorManager_instances, hasConverter_fn, extractCollections_fn, collectDescriptors_fn, teardownMissingEditors_fn, teardownEditors_fn, createEditor_fn, createEditorContainer_fn, registerConverterEditor_fn, unregisterConverterEditor_fn, updateAccessOrder_fn, enforceCacheSizeLimit_fn, _manager, _mediaFiles, _blockCache, _HeaderFooterLayoutAdapter_instances, getBlocks_fn, getConverterContext_fn, _selectionOverlay, _activeEditorHost, _activeDecorationContainer, _activeRegion, _borderLine, _dimmingOverlay, _EditorOverlayManager_instances, findDecorationContainer_fn, ensureEditorHost_fn, positionEditorHost_fn, showHeaderFooterBorder_fn, hideHeaderFooterBorder_fn, _instances, _options, _editor3, _visibleHost, _viewportHost, _painterHost, _selectionOverlay2, _hiddenHost, _layoutOptions, _layoutState, _domPainter, _dragHandlerCleanup, _layoutError, _layoutErrorState, _errorBanner, _errorBannerMessage, _telemetryEmitter, _renderScheduled, _pendingDocChange, _isRerendering, _selectionUpdateScheduled, _remoteCursorUpdateScheduled, _rafHandle, _editorListeners, _sectionMetadata, _documentMode, _inputBridge, _trackedChangesMode, _trackedChangesEnabled, _trackedChangesOverrides, _headerFooterManager, _headerFooterAdapter, _headerFooterIdentifier, _multiSectionIdentifier, _headerLayoutResults, _footerLayoutResults, _headerLayoutsByRId, _footerLayoutsByRId, _headerDecorationProvider, _footerDecorationProvider, _headerFooterManagerCleanups, _headerRegions, _footerRegions, _session, _activeHeaderFooterEditor, _overlayManager, _hoverOverlay, _hoverTooltip, _modeBanner, _ariaLiveRegion, _hoverRegion, _clickCount, _lastClickTime, _lastClickPosition, _lastSelectedImageBlockId, _dragAnchor, _isDragging, _dragExtensionMode, _remoteCursorState, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _remoteCursorRafHandle, _scrollTimeout, _PresentationEditor_instances, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, normalizeAwarenessStates_fn, getFallbackColor_fn, getValidatedColor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_fn, renderRemoteCaret_fn, renderRemoteCursorLabel_fn, renderRemoteSelection_fn, setupPointerHandlers_fn, setupDragHandlers_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, selectWordAt_fn, selectParagraphAt_fn, calculateExtendedSelection_fn, isWordCharacter_fn, _handlePointerMove, _handlePointerLeave, _handlePointerUp, _handleDragOver, _handleDrop, _handleDoubleClick, _handleKeyDown, focusHeaderFooterShortcut_fn, scheduleRerender_fn, flushRerenderQueue_fn, rerender_fn, ensurePainter_fn, scheduleSelectionUpdate_fn, updateSelection_fn, resolveLayoutOptions_fn, buildHeaderFooterInput_fn, computeHeaderFooterConstraints_fn, layoutPerRIdHeaderFooters_fn, updateDecorationProviders_fn, createDecorationProvider_fn, findHeaderFooterPageForPageNumber_fn, computeDecorationBox_fn, rebuildHeaderFooterRegions_fn, hitTestHeaderFooterRegion_fn, pointInRegion_fn, activateHeaderFooterRegion_fn, enterHeaderFooterMode_fn, exitHeaderFooterMode_fn, getActiveDomTarget_fn, emitHeaderFooterModeChanged_fn, emitHeaderFooterEditingContext_fn, updateAwarenessSession_fn, updateModeBanner_fn, announce_fn, validateHeaderFooterEditPermission_fn, emitHeaderFooterEditBlocked_fn, resolveDescriptorForRegion_fn, createDefaultHeaderFooter_fn, getPageElement_fn, scrollPageIntoView_fn, waitForPageMount_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, renderSelectionRects_fn, renderHoverRegion_fn, clearHoverRegion_fn, renderCaretOverlay_fn, getHeaderFooterContext_fn, computeHeaderFooterSelectionRects_fn, syncTrackedChangesPreferences_fn, deriveTrackedChangesMode_fn, deriveTrackedChangesEnabled_fn, getTrackChangesPluginState_fn, computeDefaultLayoutDefaults_fn, parseColumns_fn, inchesToPx_fn, applyZoom_fn, createLayoutMetrics_fn, convertPageLocalToOverlayCoords_fn, normalizeClientPoint_fn, computeCaretLayoutRect_fn, computeCaretLayoutRectFromDOM_fn, computeTableCaretLayoutRect_fn, findLineContainingPos_fn, lineHeightBeforeIndex_fn, getCurrentPageIndex_fn, findRegionForPage_fn, handleLayoutError_fn, decorateError_fn, showLayoutErrorBanner_fn, dismissErrorBanner_fn, createHiddenHost_fn, _windowRoot, _layoutSurfaces, _getTargetDom, _isEditable, _onTargetChanged, _listeners, _currentTarget, _destroyed, _useWindowFallback, _PresentationInputBridge_instances, addListener_fn, dispatchToTarget_fn, forwardKeyboardEvent_fn, forwardTextEvent_fn, forwardCompositionEvent_fn, forwardContextMenu_fn, isEventOnActiveTarget_fn, shouldSkipSurface_fn, isInLayoutSurface_fn, getListenerTargets_fn, isPlainCharacterKey_fn, _DocumentSectionView_instances, init_fn2, addToolTip_fn, _ParagraphNodeView_instances, checkShouldUpdate_fn, updateHTMLAttributes_fn, updateDOMStyles_fn, resolveNeighborParagraphProperties_fn, updateListStyles_fn, initList_fn, checkIsList_fn, createMarker_fn, createSeparator_fn, calculateTabSeparatorStyle_fn, calculateMarkerStyle_fn, removeList_fn, getParagraphContext_fn, scheduleAnimation_fn, cancelScheduledAnimation_fn, _FieldAnnotationView_instances, createAnnotation_fn, _AutoPageNumberNodeView_instances, renderDom_fn, scheduleUpdateNodeStyle_fn, _VectorShapeView_instances, ensureParentPositioned_fn, _ShapeGroupView_instances, ensureParentPositioned_fn2;
53026
53026
  var GOOD_LEAF_SIZE = 200;
53027
53027
  var RopeSequence = function RopeSequence2() {
53028
53028
  };
@@ -66889,7 +66889,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
66889
66889
  const shouldSkipNodeView = (editor) => {
66890
66890
  return isHeadless(editor);
66891
66891
  };
66892
- const summaryVersion = "1.0.0-beta.30";
66892
+ const summaryVersion = "1.0.0-beta.32";
66893
66893
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
66894
66894
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
66895
66895
  function mapAttributes(attrs) {
@@ -67678,7 +67678,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
67678
67678
  { default: remarkStringify2 },
67679
67679
  { default: remarkGfm2 }
67680
67680
  ] = await Promise.all([
67681
- Promise.resolve().then(() => indexDUzV7kkk),
67681
+ Promise.resolve().then(() => indexSGV4U12y),
67682
67682
  Promise.resolve().then(() => indexDRCvimau),
67683
67683
  Promise.resolve().then(() => indexC_x_N6Uh),
67684
67684
  Promise.resolve().then(() => indexD_sWOSiG),
@@ -67883,7 +67883,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
67883
67883
  * Process collaboration migrations
67884
67884
  */
67885
67885
  processCollaborationMigrations() {
67886
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.30");
67886
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.32");
67887
67887
  if (!this.options.ydoc) return;
67888
67888
  const metaMap = this.options.ydoc.getMap("meta");
67889
67889
  let docVersion = metaMap.get("version");
@@ -69920,9 +69920,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
69920
69920
  case TRACK_INSERT_MARK:
69921
69921
  case TRACK_DELETE_MARK:
69922
69922
  case TRACK_FORMAT_MARK: {
69923
- const tracked = buildTrackedChangeMetaFromMark(mark2);
69924
- if (tracked) {
69925
- run2.trackedChange = selectTrackedChangeMeta(run2.trackedChange, tracked);
69923
+ if (!isTabRun2) {
69924
+ const tracked = buildTrackedChangeMetaFromMark(mark2);
69925
+ if (tracked) {
69926
+ run2.trackedChange = selectTrackedChangeMeta(run2.trackedChange, tracked);
69927
+ }
69926
69928
  }
69927
69929
  break;
69928
69930
  }
@@ -73023,7 +73025,27 @@ Please report this to https://github.com/markedjs/marked.`, e) {
73023
73025
  blocks2.push(block);
73024
73026
  recordBlockKind(block.kind);
73025
73027
  });
73026
- } else if (child.type === "table") ;
73028
+ } else if (child.type === "table") {
73029
+ const tableNodeToBlock2 = converters?.tableNodeToBlock;
73030
+ if (tableNodeToBlock2) {
73031
+ const tableBlock = tableNodeToBlock2(
73032
+ child,
73033
+ nextBlockId,
73034
+ positions,
73035
+ defaultFont,
73036
+ defaultSize,
73037
+ styleContext,
73038
+ trackedChangesConfig,
73039
+ bookmarks,
73040
+ hyperlinkConfig
73041
+ );
73042
+ if (tableBlock) {
73043
+ applySdtMetadataToTableBlock(tableBlock, structuredContentMetadata);
73044
+ blocks2.push(tableBlock);
73045
+ recordBlockKind(tableBlock.kind);
73046
+ }
73047
+ }
73048
+ }
73027
73049
  });
73028
73050
  }
73029
73051
  function processParagraphChild(child, sectionMetadata, context, output, converters) {
@@ -73493,6 +73515,65 @@ Please report this to https://github.com/markedjs/marked.`, e) {
73493
73515
  }
73494
73516
  return run2;
73495
73517
  }
73518
+ function fieldAnnotationNodeToRun(node2, positions, fieldMetadata) {
73519
+ const attrs = node2.attrs ?? {};
73520
+ const rawVariant = attrs.type ?? fieldMetadata?.variant ?? "text";
73521
+ const validVariants = ["text", "image", "signature", "checkbox", "html", "link"];
73522
+ const variant = validVariants.includes(rawVariant) ? rawVariant : "text";
73523
+ const displayLabel = (typeof attrs.displayLabel === "string" ? attrs.displayLabel : void 0) || (typeof attrs.defaultDisplayLabel === "string" ? attrs.defaultDisplayLabel : void 0) || (typeof fieldMetadata?.displayLabel === "string" ? fieldMetadata.displayLabel : void 0) || (typeof fieldMetadata?.defaultDisplayLabel === "string" ? fieldMetadata.defaultDisplayLabel : void 0) || (typeof attrs.alias === "string" ? attrs.alias : void 0) || (typeof fieldMetadata?.alias === "string" ? fieldMetadata.alias : void 0) || "";
73524
+ const run2 = {
73525
+ kind: "fieldAnnotation",
73526
+ variant,
73527
+ displayLabel
73528
+ };
73529
+ const fieldId = typeof attrs.fieldId === "string" ? attrs.fieldId : fieldMetadata?.fieldId;
73530
+ if (fieldId) run2.fieldId = fieldId;
73531
+ const fieldType = typeof attrs.fieldType === "string" ? attrs.fieldType : fieldMetadata?.fieldType;
73532
+ if (fieldType) run2.fieldType = fieldType;
73533
+ const fieldColor = typeof attrs.fieldColor === "string" ? attrs.fieldColor : fieldMetadata?.fieldColor;
73534
+ if (fieldColor) run2.fieldColor = fieldColor;
73535
+ const borderColor = typeof attrs.borderColor === "string" ? attrs.borderColor : fieldMetadata?.borderColor;
73536
+ if (borderColor) run2.borderColor = borderColor;
73537
+ const highlighted = attrs.highlighted ?? fieldMetadata?.highlighted;
73538
+ if (highlighted === false) run2.highlighted = false;
73539
+ if (attrs.hidden === true || fieldMetadata?.hidden === true) run2.hidden = true;
73540
+ const visibility = attrs.visibility ?? fieldMetadata?.visibility;
73541
+ if (visibility === "hidden") run2.visibility = "hidden";
73542
+ const imageSrc = typeof attrs.imageSrc === "string" ? attrs.imageSrc : fieldMetadata?.imageSrc;
73543
+ if (imageSrc) run2.imageSrc = imageSrc;
73544
+ const linkUrl = typeof attrs.linkUrl === "string" ? attrs.linkUrl : fieldMetadata?.linkUrl;
73545
+ if (linkUrl) run2.linkUrl = linkUrl;
73546
+ const rawHtml = attrs.rawHtml ?? fieldMetadata?.rawHtml;
73547
+ if (typeof rawHtml === "string") run2.rawHtml = rawHtml;
73548
+ const size2 = attrs.size ?? fieldMetadata?.size;
73549
+ if (size2 && (typeof size2.width === "number" || typeof size2.height === "number")) {
73550
+ run2.size = {
73551
+ width: typeof size2.width === "number" ? size2.width : void 0,
73552
+ height: typeof size2.height === "number" ? size2.height : void 0
73553
+ };
73554
+ }
73555
+ const fontFamily2 = attrs.fontFamily ?? fieldMetadata?.fontFamily;
73556
+ if (typeof fontFamily2 === "string") run2.fontFamily = fontFamily2;
73557
+ const fontSize2 = attrs.fontSize ?? fieldMetadata?.fontSize;
73558
+ if (typeof fontSize2 === "string" || typeof fontSize2 === "number") run2.fontSize = fontSize2;
73559
+ const textColor = attrs.textColor ?? fieldMetadata?.textColor;
73560
+ if (typeof textColor === "string") run2.textColor = textColor;
73561
+ const textHighlight = attrs.textHighlight ?? fieldMetadata?.textHighlight;
73562
+ if (typeof textHighlight === "string") run2.textHighlight = textHighlight;
73563
+ const formatting = fieldMetadata?.formatting;
73564
+ if (attrs.bold === true || formatting?.bold === true) run2.bold = true;
73565
+ if (attrs.italic === true || formatting?.italic === true) run2.italic = true;
73566
+ if (attrs.underline === true || formatting?.underline === true) run2.underline = true;
73567
+ const pos = positions.get(node2);
73568
+ if (pos) {
73569
+ run2.pmStart = pos.start;
73570
+ run2.pmEnd = pos.end;
73571
+ }
73572
+ if (fieldMetadata) {
73573
+ run2.sdt = fieldMetadata;
73574
+ }
73575
+ return run2;
73576
+ }
73496
73577
  const isTextRun$1 = (run2) => run2.kind !== "tab";
73497
73578
  const dataAttrsCompatible = (a2, b2) => {
73498
73579
  const aAttrs = a2.dataAttrs;
@@ -73788,28 +73869,20 @@ Please report this to https://github.com/markedjs/marked.`, e) {
73788
73869
  }
73789
73870
  if (node2.type === "fieldAnnotation") {
73790
73871
  const fieldMetadata = resolveNodeSdtMetadata(node2, "fieldAnnotation");
73872
+ let contentText;
73791
73873
  if (Array.isArray(node2.content) && node2.content.length > 0) {
73792
- node2.content.forEach((child) => visitNode(child, inheritedMarks, fieldMetadata ?? activeSdt, activeRunStyleId));
73793
- } else {
73794
- const nodeAttrs = typeof node2.attrs === "object" && node2.attrs !== null ? node2.attrs : {};
73795
- const label = (typeof nodeAttrs.displayLabel === "string" ? nodeAttrs.displayLabel : void 0) || (typeof nodeAttrs.defaultDisplayLabel === "string" ? nodeAttrs.defaultDisplayLabel : void 0) || (typeof nodeAttrs.alias === "string" ? nodeAttrs.alias : void 0) || "";
73796
- if (label && typeof label === "string") {
73797
- const run2 = textNodeToRun(
73798
- { type: "text", text: label },
73799
- positions,
73800
- defaultFont,
73801
- defaultSize,
73802
- inheritedMarks,
73803
- fieldMetadata ?? activeSdt,
73804
- hyperlinkConfig,
73805
- themeColors
73806
- );
73807
- const inlineStyleId = getInlineStyleId(inheritedMarks);
73808
- applyRunStyles2(run2, inlineStyleId, activeRunStyleId);
73809
- applyBaseRunDefaults(run2, baseRunDefaults, defaultFont, defaultSize);
73810
- currentRuns.push(run2);
73811
- }
73874
+ const extractText = (n) => {
73875
+ if (n.type === "text" && typeof n.text === "string") return n.text;
73876
+ if (Array.isArray(n.content)) {
73877
+ return n.content.map(extractText).join("");
73878
+ }
73879
+ return "";
73880
+ };
73881
+ contentText = node2.content.map(extractText).join("");
73812
73882
  }
73883
+ const nodeForRun = contentText && contentText.length > 0 ? { ...node2, attrs: { ...node2.attrs ?? {}, displayLabel: contentText } } : node2;
73884
+ const run2 = fieldAnnotationNodeToRun(nodeForRun, positions, fieldMetadata);
73885
+ currentRuns.push(run2);
73813
73886
  return;
73814
73887
  }
73815
73888
  if (node2.type === "pageReference") {
@@ -74646,9 +74719,9 @@ Please report this to https://github.com/markedjs/marked.`, e) {
74646
74719
  }
74647
74720
  const attrs = spacingEl.attributes;
74648
74721
  const spacing = {};
74649
- const before = parseIntSafe(attrs["w:before"]);
74650
- const after = parseIntSafe(attrs["w:after"]);
74651
- const line = parseIntSafe(attrs["w:line"]);
74722
+ const before = parseIntSafe$1(attrs["w:before"]);
74723
+ const after = parseIntSafe$1(attrs["w:after"]);
74724
+ const line = parseIntSafe$1(attrs["w:line"]);
74652
74725
  const rawLineRule = attrs["w:lineRule"];
74653
74726
  const lineRule = rawLineRule === "auto" || rawLineRule === "exact" || rawLineRule === "atLeast" ? rawLineRule : void 0;
74654
74727
  if (before != null) spacing.before = twipsToPx$1(before);
@@ -74663,11 +74736,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
74663
74736
  if (lineRule) spacing.lineRule = lineRule;
74664
74737
  const result = Object.keys(spacing).length > 0 ? { spacing } : void 0;
74665
74738
  return result;
74666
- } catch (err) {
74739
+ } catch {
74667
74740
  return void 0;
74668
74741
  }
74669
74742
  };
74670
- const parseIntSafe = (value) => {
74743
+ const parseIntSafe$1 = (value) => {
74671
74744
  if (value == null) return void 0;
74672
74745
  const num = typeof value === "number" ? value : parseInt(String(value), 10);
74673
74746
  return Number.isFinite(num) ? num : void 0;
@@ -75319,7 +75392,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75319
75392
  return measurementCtx;
75320
75393
  }
75321
75394
  function getRunFontString(run2) {
75322
- if (run2.kind === "tab" || run2.kind === "lineBreak" || run2.kind === "break" || "src" in run2) {
75395
+ if (run2.kind === "tab" || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" || "src" in run2) {
75323
75396
  return "normal normal 16px Arial";
75324
75397
  }
75325
75398
  const style2 = run2.italic ? "italic" : "normal";
@@ -75350,6 +75423,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75350
75423
  result.push(run2);
75351
75424
  continue;
75352
75425
  }
75426
+ if (run2.kind === "fieldAnnotation") {
75427
+ result.push(run2);
75428
+ continue;
75429
+ }
75353
75430
  const text2 = run2.text ?? "";
75354
75431
  const isFirstRun = runIndex === line.fromRun;
75355
75432
  const isLastRun = runIndex === line.toRun;
@@ -75383,7 +75460,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75383
75460
  1,
75384
75461
  runs22.reduce((sum, run2) => {
75385
75462
  if (isTabRun$1(run2)) return sum + TAB_CHAR_LENGTH;
75386
- if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break") return sum;
75463
+ if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation")
75464
+ return sum;
75387
75465
  return sum + (run2.text ?? "").length;
75388
75466
  }, 0)
75389
75467
  );
@@ -75404,7 +75482,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75404
75482
  currentCharOffset += runLength2;
75405
75483
  continue;
75406
75484
  }
75407
- const text2 = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" ? "" : run2.text ?? "";
75485
+ const text2 = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
75408
75486
  const runLength = text2.length;
75409
75487
  if (currentCharOffset + runLength >= charOffset) {
75410
75488
  const offsetInRun = charOffset - currentCharOffset;
@@ -75447,7 +75525,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75447
75525
  if (isTabRun$1(run2)) {
75448
75526
  return segmentBaseX + (offsetInSegment > 0 ? segment.width ?? 0 : 0);
75449
75527
  }
75450
- if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break") {
75528
+ if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation") {
75451
75529
  return segmentBaseX + (offsetInSegment >= segmentChars ? segment.width ?? 0 : 0);
75452
75530
  }
75453
75531
  const text2 = run2.text ?? "";
@@ -75462,6 +75540,38 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75462
75540
  }
75463
75541
  return line.width;
75464
75542
  }
75543
+ function charOffsetToPm(block, line, charOffset, fallbackPmStart) {
75544
+ if (!Number.isFinite(charOffset) || !Number.isFinite(fallbackPmStart)) {
75545
+ console.warn("[charOffsetToPm] Invalid input:", { charOffset, fallbackPmStart });
75546
+ return fallbackPmStart;
75547
+ }
75548
+ const safeCharOffset = Math.max(0, charOffset);
75549
+ if (block.kind !== "paragraph") {
75550
+ return fallbackPmStart + safeCharOffset;
75551
+ }
75552
+ const runs2 = sliceRunsForLine$1(block, line);
75553
+ let cursor = 0;
75554
+ let lastPm = fallbackPmStart;
75555
+ for (const run2 of runs2) {
75556
+ const isTab = isTabRun$1(run2);
75557
+ const text2 = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
75558
+ const runLength = isTab ? TAB_CHAR_LENGTH : text2.length;
75559
+ const runPmStart = typeof run2.pmStart === "number" ? run2.pmStart : null;
75560
+ const runPmEnd = typeof run2.pmEnd === "number" ? run2.pmEnd : runPmStart != null ? runPmStart + runLength : null;
75561
+ if (runPmStart != null) {
75562
+ lastPm = runPmStart;
75563
+ }
75564
+ if (safeCharOffset <= cursor + runLength) {
75565
+ const offsetInRun = Math.max(0, safeCharOffset - cursor);
75566
+ return runPmStart != null ? runPmStart + Math.min(offsetInRun, runLength) : fallbackPmStart + safeCharOffset;
75567
+ }
75568
+ if (runPmEnd != null) {
75569
+ lastPm = runPmEnd;
75570
+ }
75571
+ cursor += runLength;
75572
+ }
75573
+ return lastPm;
75574
+ }
75465
75575
  function findCharacterAtX(block, line, x2, pmStart) {
75466
75576
  const ctx2 = getMeasurementContext();
75467
75577
  if (!ctx2) {
@@ -75470,15 +75580,17 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75470
75580
  1,
75471
75581
  runs22.reduce((sum, run2) => {
75472
75582
  if (isTabRun$1(run2)) return sum + TAB_CHAR_LENGTH;
75473
- if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break") return sum;
75583
+ if ("src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation")
75584
+ return sum;
75474
75585
  return sum + (run2.text ?? "").length;
75475
75586
  }, 0)
75476
75587
  );
75477
75588
  const ratio = Math.max(0, Math.min(1, x2 / line.width));
75478
75589
  const charOffset = Math.round(ratio * charsInLine);
75590
+ const pmPosition2 = charOffsetToPm(block, line, charOffset, pmStart);
75479
75591
  return {
75480
75592
  charOffset,
75481
- pmPosition: pmStart + charOffset
75593
+ pmPosition: pmPosition2
75482
75594
  };
75483
75595
  }
75484
75596
  const runs2 = sliceRunsForLine$1(block, line);
@@ -75494,18 +75606,17 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75494
75606
  const midpoint = startX + tabWidth / 2;
75495
75607
  const offsetInRun = safeX < midpoint ? 0 : TAB_CHAR_LENGTH;
75496
75608
  const charOffset = currentCharOffset + offsetInRun;
75497
- const pmBase = run2.pmStart ?? pmStart + currentCharOffset;
75498
- const pmPosition = pmBase + offsetInRun;
75609
+ const pmPosition2 = charOffsetToPm(block, line, charOffset, pmStart);
75499
75610
  return {
75500
75611
  charOffset,
75501
- pmPosition
75612
+ pmPosition: pmPosition2
75502
75613
  };
75503
75614
  }
75504
75615
  currentX = endX;
75505
75616
  currentCharOffset += TAB_CHAR_LENGTH;
75506
75617
  continue;
75507
75618
  }
75508
- const text2 = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" ? "" : run2.text ?? "";
75619
+ const text2 = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
75509
75620
  const runLength = text2.length;
75510
75621
  if (runLength === 0) continue;
75511
75622
  ctx2.font = getRunFontString(run2);
@@ -75515,9 +75626,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75515
75626
  const charX = currentX + measured2.width + computeLetterSpacingWidth(run2, i2, runLength);
75516
75627
  if (charX >= safeX) {
75517
75628
  if (i2 === 0) {
75629
+ const pmPosition3 = charOffsetToPm(block, line, currentCharOffset, pmStart);
75518
75630
  return {
75519
75631
  charOffset: currentCharOffset,
75520
- pmPosition: pmStart + currentCharOffset
75632
+ pmPosition: pmPosition3
75521
75633
  };
75522
75634
  }
75523
75635
  const prevText = text2.slice(0, i2 - 1);
@@ -75526,9 +75638,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75526
75638
  const distToPrev = Math.abs(safeX - prevX);
75527
75639
  const distToCurrent = Math.abs(safeX - charX);
75528
75640
  const charOffset = distToPrev < distToCurrent ? currentCharOffset + i2 - 1 : currentCharOffset + i2;
75641
+ const pmPosition2 = charOffsetToPm(block, line, charOffset, pmStart);
75529
75642
  return {
75530
75643
  charOffset,
75531
- pmPosition: pmStart + charOffset
75644
+ pmPosition: pmPosition2
75532
75645
  };
75533
75646
  }
75534
75647
  }
@@ -75536,13 +75649,14 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75536
75649
  currentX += measured.width + computeLetterSpacingWidth(run2, runLength, runLength);
75537
75650
  currentCharOffset += runLength;
75538
75651
  }
75652
+ const pmPosition = charOffsetToPm(block, line, currentCharOffset, pmStart);
75539
75653
  return {
75540
75654
  charOffset: currentCharOffset,
75541
- pmPosition: pmStart + currentCharOffset
75655
+ pmPosition
75542
75656
  };
75543
75657
  }
75544
75658
  const computeLetterSpacingWidth = (run2, precedingChars, runLength) => {
75545
- if (isTabRun$1(run2) || "src" in run2 || !("letterSpacing" in run2) || !run2.letterSpacing) {
75659
+ if (isTabRun$1(run2) || "src" in run2 || run2.kind === "fieldAnnotation" || !("letterSpacing" in run2) || !run2.letterSpacing) {
75546
75660
  return 0;
75547
75661
  }
75548
75662
  const maxGaps = Math.max(runLength - 1, 0);
@@ -75639,6 +75753,17 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75639
75753
  pmStart: fragmentEl.dataset.pmStart,
75640
75754
  pmEnd: fragmentEl.dataset.pmEnd
75641
75755
  });
75756
+ const hitChainLine = hitChain.find(
75757
+ (el) => el.classList?.contains?.(CLASS_NAMES$1.line) && el.dataset?.pmStart !== void 0 && el.dataset?.pmEnd !== void 0
75758
+ );
75759
+ if (hitChainLine) {
75760
+ log("Using hit chain line directly:", {
75761
+ pmStart: hitChainLine.dataset.pmStart,
75762
+ pmEnd: hitChainLine.dataset.pmEnd
75763
+ });
75764
+ const result2 = processLineElement(hitChainLine, viewX);
75765
+ return result2;
75766
+ }
75642
75767
  const result = processFragment(fragmentEl, viewX, viewY);
75643
75768
  return result;
75644
75769
  }
@@ -75704,7 +75829,82 @@ Please report this to https://github.com/markedjs/marked.`, e) {
75704
75829
  if (!Number.isFinite(lineStart) || !Number.isFinite(lineEnd)) {
75705
75830
  return null;
75706
75831
  }
75707
- const spanEls = Array.from(lineEl.querySelectorAll("span, a"));
75832
+ const spanEls = Array.from(lineEl.querySelectorAll("span, a")).filter(
75833
+ (el) => el.dataset.pmStart !== void 0 && el.dataset.pmEnd !== void 0
75834
+ );
75835
+ log(
75836
+ "Spans/anchors in line:",
75837
+ spanEls.map((el, i2) => {
75838
+ const rect = el.getBoundingClientRect();
75839
+ return {
75840
+ index: i2,
75841
+ tag: el.tagName,
75842
+ pmStart: el.dataset.pmStart,
75843
+ pmEnd: el.dataset.pmEnd,
75844
+ text: el.textContent?.substring(0, 20) + (el.textContent && el.textContent.length > 20 ? "..." : ""),
75845
+ visibility: el.style.visibility,
75846
+ rect: { left: rect.left, right: rect.right, width: rect.width }
75847
+ };
75848
+ })
75849
+ );
75850
+ if (spanEls.length === 0) {
75851
+ return lineStart;
75852
+ }
75853
+ const firstRect = spanEls[0].getBoundingClientRect();
75854
+ if (viewX <= firstRect.left) {
75855
+ return lineStart;
75856
+ }
75857
+ const lastRect = spanEls[spanEls.length - 1].getBoundingClientRect();
75858
+ if (viewX >= lastRect.right) {
75859
+ return lineEnd;
75860
+ }
75861
+ const targetEl = findSpanAtX(spanEls, viewX);
75862
+ if (!targetEl) {
75863
+ return lineStart;
75864
+ }
75865
+ const spanStart = Number(targetEl.dataset.pmStart ?? "NaN");
75866
+ const spanEnd = Number(targetEl.dataset.pmEnd ?? "NaN");
75867
+ const targetRect = targetEl.getBoundingClientRect();
75868
+ log("Target element:", {
75869
+ tag: targetEl.tagName,
75870
+ pmStart: spanStart,
75871
+ pmEnd: spanEnd,
75872
+ text: targetEl.textContent?.substring(0, 30),
75873
+ visibility: targetEl.style.visibility,
75874
+ rect: { left: targetRect.left, right: targetRect.right, width: targetRect.width },
75875
+ pageX: viewX,
75876
+ pageY: viewY
75877
+ });
75878
+ if (!Number.isFinite(spanStart) || !Number.isFinite(spanEnd)) {
75879
+ return null;
75880
+ }
75881
+ const firstChild = targetEl.firstChild;
75882
+ if (!firstChild || firstChild.nodeType !== Node.TEXT_NODE || !firstChild.textContent) {
75883
+ const elRect = targetEl.getBoundingClientRect();
75884
+ const closerToLeft = Math.abs(viewX - elRect.left) <= Math.abs(viewX - elRect.right);
75885
+ const snapPos = closerToLeft ? spanStart : spanEnd;
75886
+ return snapPos;
75887
+ }
75888
+ const textNode = firstChild;
75889
+ const charIndex = findCharIndexAtX(textNode, targetEl, viewX);
75890
+ const pos = spanStart + charIndex;
75891
+ return pos;
75892
+ }
75893
+ function processLineElement(lineEl, viewX) {
75894
+ const lineStart = Number(lineEl.dataset.pmStart ?? "NaN");
75895
+ const lineEnd = Number(lineEl.dataset.pmEnd ?? "NaN");
75896
+ const lineRect = lineEl.getBoundingClientRect();
75897
+ log("processLineElement:", {
75898
+ pmStart: lineStart,
75899
+ pmEnd: lineEnd,
75900
+ rect: { top: lineRect.top, bottom: lineRect.bottom, left: lineRect.left, right: lineRect.right }
75901
+ });
75902
+ if (!Number.isFinite(lineStart) || !Number.isFinite(lineEnd)) {
75903
+ return null;
75904
+ }
75905
+ const spanEls = Array.from(lineEl.querySelectorAll("span, a")).filter(
75906
+ (el) => el.dataset.pmStart !== void 0 && el.dataset.pmEnd !== void 0
75907
+ );
75708
75908
  log(
75709
75909
  "Spans/anchors in line:",
75710
75910
  spanEls.map((el, i2) => {
@@ -78651,7 +78851,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
78651
78851
  return `img:${srcHash}:${imgRun.width}x${imgRun.height}`;
78652
78852
  }
78653
78853
  const text2 = normalizeText(
78654
- "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" ? "" : run2.text ?? ""
78854
+ "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? ""
78655
78855
  );
78656
78856
  const bold = "bold" in run2 ? run2.bold : false;
78657
78857
  const italic = "italic" in run2 ? run2.italic : false;
@@ -79310,6 +79510,88 @@ Please report this to https://github.com/markedjs/marked.`, e) {
79310
79510
  }
79311
79511
  return result;
79312
79512
  }
79513
+ function findWordBoundaries(blocks2, pos) {
79514
+ const blockInfo = findBlockAtPosition(blocks2, pos);
79515
+ if (!blockInfo) return null;
79516
+ const { block, localPos } = blockInfo;
79517
+ if (block.kind !== "paragraph") return null;
79518
+ const { text: text2, pmStart } = extractBlockText(block);
79519
+ if (text2.length === 0) return null;
79520
+ const clampedPos = Math.max(0, Math.min(localPos, text2.length));
79521
+ let wordStart = clampedPos;
79522
+ while (wordStart > 0 && isWordChar(text2[wordStart - 1])) {
79523
+ wordStart--;
79524
+ }
79525
+ let wordEnd = clampedPos;
79526
+ while (wordEnd < text2.length && isWordChar(text2[wordEnd])) {
79527
+ wordEnd++;
79528
+ }
79529
+ if (wordStart === wordEnd) {
79530
+ while (wordStart > 0 && isWhitespace$1(text2[wordStart - 1])) {
79531
+ wordStart--;
79532
+ }
79533
+ while (wordEnd < text2.length && isWhitespace$1(text2[wordEnd])) {
79534
+ wordEnd++;
79535
+ }
79536
+ if (wordStart === wordEnd) {
79537
+ return null;
79538
+ }
79539
+ }
79540
+ return {
79541
+ from: pmStart + wordStart,
79542
+ to: pmStart + wordEnd
79543
+ };
79544
+ }
79545
+ function findParagraphBoundaries(blocks2, pos) {
79546
+ const blockInfo = findBlockAtPosition(blocks2, pos);
79547
+ if (!blockInfo) return null;
79548
+ const { block } = blockInfo;
79549
+ if (block.kind === "paragraph") {
79550
+ const { pmStart, pmEnd } = extractBlockText(block);
79551
+ return { from: pmStart, to: pmEnd };
79552
+ }
79553
+ if (block.kind === "image") {
79554
+ return { from: pos, to: pos + 1 };
79555
+ }
79556
+ return null;
79557
+ }
79558
+ function extractBlockText(block) {
79559
+ if (block.kind !== "paragraph") {
79560
+ return { text: "", pmStart: 0, pmEnd: 0 };
79561
+ }
79562
+ let text2 = "";
79563
+ let pmStart = Infinity;
79564
+ let pmEnd = 0;
79565
+ for (const run2 of block.runs) {
79566
+ text2 += "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text;
79567
+ if (run2.pmStart !== void 0) {
79568
+ pmStart = Math.min(pmStart, run2.pmStart);
79569
+ }
79570
+ if (run2.pmEnd !== void 0) {
79571
+ pmEnd = Math.max(pmEnd, run2.pmEnd);
79572
+ }
79573
+ }
79574
+ if (pmStart === Infinity) pmStart = 0;
79575
+ if (pmEnd === 0 && text2.length > 0) pmEnd = pmStart + text2.length;
79576
+ return { text: text2, pmStart, pmEnd };
79577
+ }
79578
+ function findBlockAtPosition(blocks2, pos) {
79579
+ for (const block of blocks2) {
79580
+ if (block.kind === "paragraph") {
79581
+ const { pmStart, pmEnd } = extractBlockText(block);
79582
+ if (pos >= pmStart && pos <= pmEnd) {
79583
+ return { block, localPos: pos - pmStart };
79584
+ }
79585
+ }
79586
+ }
79587
+ return null;
79588
+ }
79589
+ function isWordChar(char) {
79590
+ return /[\p{L}\p{N}_]/u.test(char);
79591
+ }
79592
+ function isWhitespace$1(char) {
79593
+ return /\s/.test(char);
79594
+ }
79313
79595
  let canvas = null;
79314
79596
  let ctx$2 = null;
79315
79597
  function getCtx() {
@@ -79331,7 +79613,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
79331
79613
  return `${italic}${bold}${size2}px ${family}`.trim();
79332
79614
  }
79333
79615
  function runText(run2) {
79334
- return "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" ? "" : run2.text ?? "";
79616
+ return "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
79335
79617
  }
79336
79618
  function measureRunSliceWidth(run2, fromChar, toChar) {
79337
79619
  const context = getCtx();
@@ -79493,7 +79775,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
79493
79775
  for (let i2 = 0; i2 < a2.runs.length; i2 += 1) {
79494
79776
  const runA = a2.runs[i2];
79495
79777
  const runB = b2.runs[i2];
79496
- if (("src" in runA || runA.kind === "lineBreak" || runA.kind === "break" ? "" : runA.text) !== ("src" in runB || runB.kind === "lineBreak" || runB.kind === "break" ? "" : runB.text) || ("bold" in runA ? runA.bold : false) !== ("bold" in runB ? runB.bold : false) || ("italic" in runA ? runA.italic : false) !== ("italic" in runB ? runB.italic : false) || ("color" in runA ? runA.color : void 0) !== ("color" in runB ? runB.color : void 0) || getTrackedChangeKey(runA) !== getTrackedChangeKey(runB)) {
79778
+ if (("src" in runA || runA.kind === "lineBreak" || runA.kind === "break" || runA.kind === "fieldAnnotation" ? "" : runA.text) !== ("src" in runB || runB.kind === "lineBreak" || runB.kind === "break" || runB.kind === "fieldAnnotation" ? "" : runB.text) || ("bold" in runA ? runA.bold : false) !== ("bold" in runB ? runB.bold : false) || ("italic" in runA ? runA.italic : false) !== ("italic" in runB ? runB.italic : false) || ("color" in runA ? runA.color : void 0) !== ("color" in runB ? runB.color : void 0) || getTrackedChangeKey(runA) !== getTrackedChangeKey(runB)) {
79497
79779
  return false;
79498
79780
  }
79499
79781
  }
@@ -79613,7 +79895,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
79613
79895
  parts.push(block.id);
79614
79896
  if (block.kind === "paragraph") {
79615
79897
  for (const run2 of block.runs) {
79616
- if (!("src" in run2) && run2.kind !== "lineBreak" && run2.kind !== "break") {
79898
+ if (!("src" in run2) && run2.kind !== "lineBreak" && run2.kind !== "break" && run2.kind !== "fieldAnnotation") {
79617
79899
  parts.push(run2.text ?? "");
79618
79900
  }
79619
79901
  if ("bold" in run2 && run2.bold) parts.push("b");
@@ -80098,11 +80380,266 @@ Please report this to https://github.com/markedjs/marked.`, e) {
80098
80380
  /** P3: Heavy debounce for full document layout */
80099
80381
  [Priority.P3]: 150
80100
80382
  });
80383
+ const DEFAULT_MIME_TYPE$1 = "application/x-field-annotation";
80384
+ const LEGACY_MIME_TYPE = "fieldAnnotation";
80385
+ function parseIntSafe(value) {
80386
+ if (!value) return void 0;
80387
+ const parsed = parseInt(value, 10);
80388
+ return Number.isFinite(parsed) ? parsed : void 0;
80389
+ }
80390
+ function extractFieldAnnotationData(element2) {
80391
+ const dataset = element2.dataset;
80392
+ const attributes = {};
80393
+ for (const key2 in dataset) {
80394
+ const value = dataset[key2];
80395
+ if (value !== void 0) {
80396
+ attributes[key2] = value;
80397
+ }
80398
+ }
80399
+ return {
80400
+ fieldId: dataset.fieldId,
80401
+ fieldType: dataset.fieldType,
80402
+ variant: dataset.variant ?? dataset.type,
80403
+ displayLabel: dataset.displayLabel,
80404
+ pmStart: parseIntSafe(dataset.pmStart),
80405
+ pmEnd: parseIntSafe(dataset.pmEnd),
80406
+ attributes
80407
+ };
80408
+ }
80409
+ class DragHandler {
80410
+ /**
80411
+ * Creates a new DragHandler instance.
80412
+ *
80413
+ * @param container - The DOM container element (typically .superdoc-layout)
80414
+ * @param config - Configuration options and callbacks
80415
+ */
80416
+ constructor(container, config2 = {}) {
80417
+ this.container = container;
80418
+ this.config = config2;
80419
+ this.mimeType = config2.mimeType ?? DEFAULT_MIME_TYPE$1;
80420
+ this.boundHandlers = {
80421
+ dragstart: this.handleDragStart.bind(this),
80422
+ dragover: this.handleDragOver.bind(this),
80423
+ drop: this.handleDrop.bind(this),
80424
+ dragend: this.handleDragEnd.bind(this),
80425
+ dragleave: this.handleDragLeave.bind(this)
80426
+ };
80427
+ this.windowDragoverHandler = this.handleWindowDragOver.bind(this);
80428
+ this.windowDropHandler = this.handleWindowDrop.bind(this);
80429
+ this.attachListeners();
80430
+ }
80431
+ /**
80432
+ * Attaches event listeners to the container and window.
80433
+ */
80434
+ attachListeners() {
80435
+ this.container.addEventListener("dragstart", this.boundHandlers.dragstart);
80436
+ this.container.addEventListener("dragover", this.boundHandlers.dragover);
80437
+ this.container.addEventListener("drop", this.boundHandlers.drop);
80438
+ this.container.addEventListener("dragend", this.boundHandlers.dragend);
80439
+ this.container.addEventListener("dragleave", this.boundHandlers.dragleave);
80440
+ window.addEventListener("dragover", this.windowDragoverHandler, false);
80441
+ window.addEventListener("drop", this.windowDropHandler, false);
80442
+ }
80443
+ /**
80444
+ * Removes event listeners from the container and window.
80445
+ */
80446
+ removeListeners() {
80447
+ this.container.removeEventListener("dragstart", this.boundHandlers.dragstart);
80448
+ this.container.removeEventListener("dragover", this.boundHandlers.dragover);
80449
+ this.container.removeEventListener("drop", this.boundHandlers.drop);
80450
+ this.container.removeEventListener("dragend", this.boundHandlers.dragend);
80451
+ this.container.removeEventListener("dragleave", this.boundHandlers.dragleave);
80452
+ window.removeEventListener("dragover", this.windowDragoverHandler, false);
80453
+ window.removeEventListener("drop", this.windowDropHandler, false);
80454
+ }
80455
+ /**
80456
+ * Handles dragover at window level to allow drops on overlay elements.
80457
+ * This ensures preventDefault is called even when dragging over selection
80458
+ * highlights or other UI elements that sit on top of the layout content.
80459
+ */
80460
+ handleWindowDragOver(event) {
80461
+ if (this.hasFieldAnnotationData(event)) {
80462
+ event.preventDefault();
80463
+ if (event.dataTransfer) {
80464
+ event.dataTransfer.dropEffect = "move";
80465
+ }
80466
+ const target = event.target;
80467
+ if (!this.container.contains(target)) {
80468
+ this.config.onDragOver?.({
80469
+ event,
80470
+ clientX: event.clientX,
80471
+ clientY: event.clientY,
80472
+ hasFieldAnnotation: true
80473
+ });
80474
+ }
80475
+ }
80476
+ }
80477
+ /**
80478
+ * Handles drop at window level to catch drops on overlay elements.
80479
+ * If the drop target is outside the container, we process it here.
80480
+ */
80481
+ handleWindowDrop(event) {
80482
+ if (this.hasFieldAnnotationData(event)) {
80483
+ const target = event.target;
80484
+ if (!this.container.contains(target)) {
80485
+ this.handleDrop(event);
80486
+ }
80487
+ }
80488
+ }
80489
+ /**
80490
+ * Handles the dragstart event.
80491
+ * Sets up dataTransfer with field annotation data and drag image.
80492
+ */
80493
+ handleDragStart(event) {
80494
+ const target = event.target;
80495
+ if (!target?.dataset?.draggable || target.dataset.draggable !== "true") {
80496
+ return;
80497
+ }
80498
+ const data = extractFieldAnnotationData(target);
80499
+ if (event.dataTransfer) {
80500
+ const jsonData = JSON.stringify({
80501
+ attributes: data.attributes,
80502
+ sourceField: data
80503
+ });
80504
+ event.dataTransfer.setData(this.mimeType, jsonData);
80505
+ event.dataTransfer.setData(LEGACY_MIME_TYPE, jsonData);
80506
+ event.dataTransfer.setData("text/plain", data.displayLabel ?? "Field Annotation");
80507
+ event.dataTransfer.setDragImage(target, 0, 0);
80508
+ event.dataTransfer.effectAllowed = "move";
80509
+ }
80510
+ this.config.onDragStart?.({
80511
+ event,
80512
+ element: target,
80513
+ data
80514
+ });
80515
+ }
80516
+ /**
80517
+ * Handles the dragover event.
80518
+ * Provides visual feedback and determines if drop is allowed.
80519
+ */
80520
+ handleDragOver(event) {
80521
+ const hasFieldAnnotation = this.hasFieldAnnotationData(event);
80522
+ if (hasFieldAnnotation) {
80523
+ event.preventDefault();
80524
+ if (event.dataTransfer) {
80525
+ event.dataTransfer.dropEffect = "move";
80526
+ }
80527
+ this.container.classList.add("drag-over");
80528
+ }
80529
+ this.config.onDragOver?.({
80530
+ event,
80531
+ clientX: event.clientX,
80532
+ clientY: event.clientY,
80533
+ hasFieldAnnotation
80534
+ });
80535
+ }
80536
+ /**
80537
+ * Handles the dragleave event.
80538
+ * Removes visual feedback when drag leaves the container.
80539
+ */
80540
+ handleDragLeave(event) {
80541
+ const relatedTarget = event.relatedTarget;
80542
+ if (!relatedTarget || !this.container.contains(relatedTarget)) {
80543
+ this.container.classList.remove("drag-over");
80544
+ }
80545
+ }
80546
+ /**
80547
+ * Handles the drop event.
80548
+ * Maps drop coordinates to ProseMirror position and emits drop event.
80549
+ */
80550
+ handleDrop(event) {
80551
+ this.container.classList.remove("drag-over");
80552
+ if (!this.hasFieldAnnotationData(event)) {
80553
+ return;
80554
+ }
80555
+ event.preventDefault();
80556
+ const data = this.extractDragData(event);
80557
+ if (!data) {
80558
+ return;
80559
+ }
80560
+ const pmPosition = clickToPositionDom(this.container, event.clientX, event.clientY);
80561
+ this.config.onDrop?.({
80562
+ event,
80563
+ data,
80564
+ pmPosition,
80565
+ clientX: event.clientX,
80566
+ clientY: event.clientY
80567
+ });
80568
+ }
80569
+ /**
80570
+ * Handles the dragend event.
80571
+ * Cleans up drag state.
80572
+ */
80573
+ handleDragEnd(event) {
80574
+ this.container.classList.remove("drag-over");
80575
+ this.config.onDragEnd?.(event);
80576
+ }
80577
+ /**
80578
+ * Checks if a drag event contains field annotation data.
80579
+ */
80580
+ hasFieldAnnotationData(event) {
80581
+ if (!event.dataTransfer) {
80582
+ return false;
80583
+ }
80584
+ const types2 = event.dataTransfer.types;
80585
+ return types2.includes(this.mimeType) || types2.includes(LEGACY_MIME_TYPE);
80586
+ }
80587
+ /**
80588
+ * Extracts field annotation data from a drag event's dataTransfer.
80589
+ */
80590
+ extractDragData(event) {
80591
+ if (!event.dataTransfer) {
80592
+ return null;
80593
+ }
80594
+ let jsonData = event.dataTransfer.getData(this.mimeType);
80595
+ if (!jsonData) {
80596
+ jsonData = event.dataTransfer.getData(LEGACY_MIME_TYPE);
80597
+ }
80598
+ if (!jsonData) {
80599
+ return null;
80600
+ }
80601
+ try {
80602
+ const parsed = JSON.parse(jsonData);
80603
+ return parsed.sourceField ?? parsed.attributes ?? parsed;
80604
+ } catch {
80605
+ return null;
80606
+ }
80607
+ }
80608
+ /**
80609
+ * Updates the configuration options.
80610
+ *
80611
+ * @param config - New configuration options to merge
80612
+ */
80613
+ updateConfig(config2) {
80614
+ this.config = { ...this.config, ...config2 };
80615
+ if (config2.mimeType) {
80616
+ this.mimeType = config2.mimeType;
80617
+ }
80618
+ }
80619
+ /**
80620
+ * Destroys the drag handler and removes all event listeners.
80621
+ * Call this when the layout engine is unmounted or the container is removed.
80622
+ */
80623
+ destroy() {
80624
+ this.removeListeners();
80625
+ this.container.classList.remove("drag-over");
80626
+ }
80627
+ }
80628
+ function createDragHandler(container, config2 = {}) {
80629
+ const handler2 = new DragHandler(container, config2);
80630
+ return () => handler2.destroy();
80631
+ }
80101
80632
  const isAtomicFragment = (fragment) => {
80102
80633
  return fragment.kind === "drawing" || fragment.kind === "image";
80103
80634
  };
80104
80635
  const logClickStage = (_level, _stage, _payload) => {
80105
80636
  };
80637
+ const logPositionDebug = (payload) => {
80638
+ return;
80639
+ };
80640
+ const logSelectionMapDebug = (payload) => {
80641
+ return;
80642
+ };
80106
80643
  const blockPmRangeFromAttrs = (block) => {
80107
80644
  const attrs = block?.attrs;
80108
80645
  const pmStart = typeof attrs?.pmStart === "number" ? attrs.pmStart : void 0;
@@ -80372,6 +80909,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
80372
80909
  return null;
80373
80910
  }
80374
80911
  const column = determineColumn(layout, fragment.x);
80912
+ logPositionDebug({
80913
+ blockId: fragment.blockId,
80914
+ x: pageRelativePoint.x - fragment.x
80915
+ });
80375
80916
  logClickStage("log", "success", {
80376
80917
  blockId: fragment.blockId
80377
80918
  });
@@ -80480,10 +81021,13 @@ Please report this to https://github.com/markedjs/marked.`, e) {
80480
81021
  const sliceFrom = Math.max(range2.pmStart, from2);
80481
81022
  const sliceTo = Math.min(range2.pmEnd, to);
80482
81023
  if (sliceFrom >= sliceTo) return;
80483
- const x1 = mapPmToX(block, line, sliceFrom - range2.pmStart, fragment.width);
80484
- const x2 = mapPmToX(block, line, sliceTo - range2.pmStart, fragment.width);
80485
- const rectX = fragment.x + Math.min(x1, x2);
80486
- const rectWidth = Math.max(1, Math.abs(x2 - x1));
81024
+ const charOffsetFrom = pmPosToCharOffset(block, line, sliceFrom);
81025
+ const charOffsetTo = pmPosToCharOffset(block, line, sliceTo);
81026
+ const startX = mapPmToX(block, line, charOffsetFrom, fragment.width);
81027
+ const endX = mapPmToX(block, line, charOffsetTo, fragment.width);
81028
+ const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
81029
+ const rectX = fragment.x + markerWidth + Math.min(startX, endX);
81030
+ const rectWidth = Math.max(1, Math.abs(endX - startX));
80487
81031
  const lineOffset = lineHeightBeforeIndex(measure, index2) - lineHeightBeforeIndex(measure, fragment.fromLine);
80488
81032
  const rectY = fragment.y + lineOffset;
80489
81033
  rects.push({
@@ -80623,7 +81167,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
80623
81167
  for (let runIndex = line.fromRun; runIndex <= line.toRun; runIndex += 1) {
80624
81168
  const run2 = block.runs[runIndex];
80625
81169
  if (!run2) continue;
80626
- const text2 = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" ? "" : run2.text ?? "";
81170
+ const text2 = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
80627
81171
  const runLength = text2.length;
80628
81172
  const runPmStart = run2.pmStart ?? null;
80629
81173
  const runPmEnd = run2.pmEnd ?? (runPmStart != null ? runPmStart + runLength : null);
@@ -80641,6 +81185,57 @@ Please report this to https://github.com/markedjs/marked.`, e) {
80641
81185
  }
80642
81186
  return { pmStart, pmEnd };
80643
81187
  }
81188
+ function pmPosToCharOffset(block, line, pmPos) {
81189
+ if (block.kind !== "paragraph") return 0;
81190
+ let charOffset = 0;
81191
+ for (let runIndex = line.fromRun; runIndex <= line.toRun; runIndex += 1) {
81192
+ const run2 = block.runs[runIndex];
81193
+ if (!run2) continue;
81194
+ const text2 = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
81195
+ const runTextLength = text2.length;
81196
+ const runPmStart = run2.pmStart ?? null;
81197
+ const runPmEnd = run2.pmEnd ?? (runPmStart != null ? runPmStart + runTextLength : null);
81198
+ if (runPmStart == null || runPmEnd == null || runTextLength === 0) continue;
81199
+ const isFirstRun = runIndex === line.fromRun;
81200
+ const isLastRun = runIndex === line.toRun;
81201
+ const lineStartChar = isFirstRun ? line.fromChar : 0;
81202
+ const lineEndChar = isLastRun ? line.toChar : runTextLength;
81203
+ const runSliceCharCount = lineEndChar - lineStartChar;
81204
+ const runPmRange = runPmEnd - runPmStart;
81205
+ const runSlicePmStart = runPmStart + lineStartChar / runTextLength * runPmRange;
81206
+ const runSlicePmEnd = runPmStart + lineEndChar / runTextLength * runPmRange;
81207
+ if (pmPos >= runSlicePmStart && pmPos <= runSlicePmEnd) {
81208
+ const runSlicePmRange = runSlicePmEnd - runSlicePmStart;
81209
+ if (runSlicePmRange > 0) {
81210
+ const pmOffsetInSlice = pmPos - runSlicePmStart;
81211
+ const charOffsetInSlice = Math.round(pmOffsetInSlice / runSlicePmRange * runSliceCharCount);
81212
+ const result = charOffset + Math.min(charOffsetInSlice, runSliceCharCount);
81213
+ const runText2 = text2;
81214
+ const offsetInRun = result - charOffset - (isFirstRun ? 0 : 0);
81215
+ logSelectionMapDebug({
81216
+ blockId: block.id,
81217
+ lineFromRun: line.fromRun,
81218
+ lineToRun: line.toRun,
81219
+ runTextPreview: runText2.slice(Math.max(0, offsetInRun - 10), Math.min(runText2.length, offsetInRun + 10))
81220
+ });
81221
+ return result;
81222
+ }
81223
+ logSelectionMapDebug({
81224
+ blockId: block.id
81225
+ });
81226
+ return charOffset;
81227
+ }
81228
+ if (pmPos > runSlicePmEnd) {
81229
+ charOffset += runSliceCharCount;
81230
+ }
81231
+ }
81232
+ logSelectionMapDebug({
81233
+ blockId: block.id,
81234
+ lineFromRun: line.fromRun,
81235
+ lineToRun: line.toRun
81236
+ });
81237
+ return charOffset;
81238
+ }
80644
81239
  const determineColumn = (layout, fragmentX) => {
80645
81240
  const columns = layout.columns;
80646
81241
  if (!columns || columns.count <= 1) return 0;
@@ -80685,8 +81280,8 @@ Please report this to https://github.com/markedjs/marked.`, e) {
80685
81280
  if (isRTL) {
80686
81281
  const charOffset = result.charOffset;
80687
81282
  const charsInLine = Math.max(1, line.toChar - line.fromChar);
80688
- const reversedOffset = charsInLine - charOffset;
80689
- return range2.pmStart + reversedOffset;
81283
+ const reversedOffset = Math.max(0, Math.min(charsInLine, charsInLine - charOffset));
81284
+ return charOffsetToPm(block, line, reversedOffset, range2.pmStart);
80690
81285
  }
80691
81286
  return result.pmPosition;
80692
81287
  };
@@ -83128,10 +83723,228 @@ ${l}
83128
83723
  .superdoc-layout .track-format-dec.highlighted {
83129
83724
  border-bottom: 2px solid gold;
83130
83725
  }
83726
+ `;
83727
+ const SDT_CONTAINER_STYLES = `
83728
+ /* Document Section - Block-level container with gray border and hover tooltip */
83729
+ .superdoc-document-section {
83730
+ background-color: #fafafa;
83731
+ border: 1px solid #ababab;
83732
+ border-radius: 4px;
83733
+ position: relative;
83734
+ box-sizing: border-box;
83735
+ }
83736
+
83737
+ /* Document section tooltip - positioned above the fragment */
83738
+ .superdoc-document-section__tooltip {
83739
+ position: absolute;
83740
+ top: -19px;
83741
+ left: -1px;
83742
+ max-width: 100px;
83743
+ min-width: 0;
83744
+ height: 18px;
83745
+ border: 1px solid #ababab;
83746
+ border-bottom: none;
83747
+ border-radius: 6px 6px 0 0;
83748
+ padding: 0 8px;
83749
+ align-items: center;
83750
+ font-size: 10px;
83751
+ display: none;
83752
+ z-index: 100;
83753
+ background-color: #fafafa;
83754
+ pointer-events: none;
83755
+ }
83756
+
83757
+ .superdoc-document-section__tooltip span {
83758
+ max-width: 100%;
83759
+ overflow: hidden;
83760
+ white-space: nowrap;
83761
+ text-overflow: ellipsis;
83762
+ }
83763
+
83764
+ /* Show tooltip on hover - adjust border radius to connect with tooltip tab */
83765
+ .superdoc-document-section:hover {
83766
+ border-radius: 0 4px 4px 4px;
83767
+ }
83768
+
83769
+ .superdoc-document-section:hover .superdoc-document-section__tooltip {
83770
+ display: flex;
83771
+ align-items: center;
83772
+ }
83773
+
83774
+ /* Continuation styling: first fragment has top corners, last has bottom corners */
83775
+ .superdoc-document-section[data-sdt-container-start="true"] {
83776
+ border-radius: 4px 4px 0 0;
83777
+ }
83778
+
83779
+ .superdoc-document-section[data-sdt-container-end="true"] {
83780
+ border-radius: 0 0 4px 4px;
83781
+ }
83782
+
83783
+ .superdoc-document-section[data-sdt-container-start="true"][data-sdt-container-end="true"] {
83784
+ border-radius: 4px;
83785
+ }
83786
+
83787
+ .superdoc-document-section[data-sdt-container-start="true"]:hover {
83788
+ border-radius: 0 4px 0 0;
83789
+ }
83790
+
83791
+ /* Middle fragments have no border radius */
83792
+ .superdoc-document-section:not([data-sdt-container-start="true"]):not([data-sdt-container-end="true"]) {
83793
+ border-radius: 0;
83794
+ border-top: none;
83795
+ }
83796
+
83797
+ /* Structured Content Block - Blue border container */
83798
+ .superdoc-structured-content-block {
83799
+ padding: 1px;
83800
+ box-sizing: border-box;
83801
+ border-radius: 4px;
83802
+ border: 1px solid #629be7;
83803
+ position: relative;
83804
+ }
83805
+
83806
+ /* Structured content drag handle/label - positioned above */
83807
+ .superdoc-structured-content__label {
83808
+ font-size: 10px;
83809
+ align-items: center;
83810
+ justify-content: center;
83811
+ position: absolute;
83812
+ left: 2px;
83813
+ top: -19px;
83814
+ width: calc(100% - 4px);
83815
+ max-width: 110px;
83816
+ min-width: 0;
83817
+ height: 18px;
83818
+ padding: 0 4px;
83819
+ border: 1px solid #629be7;
83820
+ border-bottom: none;
83821
+ border-radius: 6px 6px 0 0;
83822
+ background-color: #629be7dd;
83823
+ box-sizing: border-box;
83824
+ z-index: 10;
83825
+ display: none;
83826
+ pointer-events: none;
83827
+ }
83828
+
83829
+ .superdoc-structured-content__label span {
83830
+ max-width: 100%;
83831
+ overflow: hidden;
83832
+ white-space: nowrap;
83833
+ text-overflow: ellipsis;
83834
+ }
83835
+
83836
+ .superdoc-structured-content-block:hover .superdoc-structured-content__label {
83837
+ display: inline-flex;
83838
+ }
83839
+
83840
+ /* Continuation styling for structured content blocks */
83841
+ .superdoc-structured-content-block[data-sdt-container-start="true"] {
83842
+ border-radius: 4px 4px 0 0;
83843
+ }
83844
+
83845
+ .superdoc-structured-content-block[data-sdt-container-end="true"] {
83846
+ border-radius: 0 0 4px 4px;
83847
+ }
83848
+
83849
+ .superdoc-structured-content-block[data-sdt-container-start="true"][data-sdt-container-end="true"] {
83850
+ border-radius: 4px;
83851
+ }
83852
+
83853
+ .superdoc-structured-content-block:not([data-sdt-container-start="true"]):not([data-sdt-container-end="true"]) {
83854
+ border-radius: 0;
83855
+ border-top: none;
83856
+ }
83857
+
83858
+ /* Structured Content Inline - Inline wrapper with blue border */
83859
+ .superdoc-structured-content-inline {
83860
+ padding: 1px;
83861
+ box-sizing: border-box;
83862
+ border-radius: 4px;
83863
+ border: 1px solid #629be7;
83864
+ position: relative;
83865
+ display: inline;
83866
+ }
83867
+
83868
+ /* Hover effect for inline structured content */
83869
+ .superdoc-structured-content-inline:hover {
83870
+ background-color: rgba(98, 155, 231, 0.15);
83871
+ border-color: #4a8ad9;
83872
+ }
83873
+
83874
+ /* Inline structured content label - shown on hover */
83875
+ .superdoc-structured-content-inline__label {
83876
+ position: absolute;
83877
+ bottom: calc(100% + 2px);
83878
+ left: 50%;
83879
+ transform: translateX(-50%);
83880
+ font-size: 10px;
83881
+ padding: 2px 6px;
83882
+ background-color: #629be7dd;
83883
+ color: white;
83884
+ border-radius: 4px;
83885
+ white-space: nowrap;
83886
+ z-index: 100;
83887
+ display: none;
83888
+ pointer-events: none;
83889
+ }
83890
+
83891
+ .superdoc-structured-content-inline:hover .superdoc-structured-content-inline__label {
83892
+ display: block;
83893
+ }
83894
+
83895
+ /* Print mode: hide visual styling for SDT containers */
83896
+ @media print {
83897
+ .superdoc-document-section,
83898
+ .superdoc-structured-content-block,
83899
+ .superdoc-structured-content-inline {
83900
+ background: none;
83901
+ border: none;
83902
+ padding: 0;
83903
+ }
83904
+
83905
+ .superdoc-document-section__tooltip,
83906
+ .superdoc-structured-content__label,
83907
+ .superdoc-structured-content-inline__label {
83908
+ display: none !important;
83909
+ }
83910
+ }
83911
+ `;
83912
+ const FIELD_ANNOTATION_STYLES = `
83913
+ /* Field annotation draggable styles */
83914
+ .superdoc-layout .annotation[data-draggable="true"] {
83915
+ cursor: grab;
83916
+ user-select: none;
83917
+ -webkit-user-select: none;
83918
+ }
83919
+
83920
+ .superdoc-layout .annotation[data-draggable="true"]:hover {
83921
+ opacity: 0.9;
83922
+ }
83923
+
83924
+ .superdoc-layout .annotation[data-draggable="true"]:active {
83925
+ cursor: grabbing;
83926
+ }
83927
+
83928
+ /* Drag over indicator for drop targets */
83929
+ .superdoc-layout.drag-over {
83930
+ outline: 2px dashed #b015b3;
83931
+ outline-offset: -2px;
83932
+ }
83933
+
83934
+ /* Drop zone indicator */
83935
+ .superdoc-layout .superdoc-drop-indicator {
83936
+ position: absolute;
83937
+ width: 2px;
83938
+ background-color: #b015b3;
83939
+ pointer-events: none;
83940
+ z-index: 1000;
83941
+ }
83131
83942
  `;
83132
83943
  let printStylesInjected = false;
83133
83944
  let linkStylesInjected = false;
83134
83945
  let trackChangeStylesInjected = false;
83946
+ let sdtContainerStylesInjected = false;
83947
+ let fieldAnnotationStylesInjected = false;
83135
83948
  const ensurePrintStyles = (doc2) => {
83136
83949
  if (printStylesInjected || !doc2) return;
83137
83950
  const styleEl = doc2.createElement("style");
@@ -83156,6 +83969,22 @@ ${l}
83156
83969
  doc2.head?.appendChild(styleEl);
83157
83970
  trackChangeStylesInjected = true;
83158
83971
  };
83972
+ const ensureSdtContainerStyles = (doc2) => {
83973
+ if (sdtContainerStylesInjected || !doc2) return;
83974
+ const styleEl = doc2.createElement("style");
83975
+ styleEl.setAttribute("data-superdoc-sdt-container-styles", "true");
83976
+ styleEl.textContent = SDT_CONTAINER_STYLES;
83977
+ doc2.head?.appendChild(styleEl);
83978
+ sdtContainerStylesInjected = true;
83979
+ };
83980
+ const ensureFieldAnnotationStyles = (doc2) => {
83981
+ if (fieldAnnotationStylesInjected || !doc2) return;
83982
+ const styleEl = doc2.createElement("style");
83983
+ styleEl.setAttribute("data-superdoc-field-annotation-styles", "true");
83984
+ styleEl.textContent = FIELD_ANNOTATION_STYLES;
83985
+ doc2.head?.appendChild(styleEl);
83986
+ fieldAnnotationStylesInjected = true;
83987
+ };
83159
83988
  const ALLOWED_BORDER_STYLES = /* @__PURE__ */ new Set([
83160
83989
  "none",
83161
83990
  "single",
@@ -83485,6 +84314,50 @@ ${l}
83485
84314
  container.appendChild(cellElement);
83486
84315
  }
83487
84316
  };
84317
+ function isStructuredContentMetadata(sdt) {
84318
+ return sdt !== null && sdt !== void 0 && typeof sdt === "object" && "type" in sdt && sdt.type === "structuredContent";
84319
+ }
84320
+ function isDocumentSectionMetadata(sdt) {
84321
+ return sdt !== null && sdt !== void 0 && typeof sdt === "object" && "type" in sdt && sdt.type === "documentSection";
84322
+ }
84323
+ function getSdtContainerConfig(sdt) {
84324
+ if (isDocumentSectionMetadata(sdt)) {
84325
+ return {
84326
+ className: "superdoc-document-section",
84327
+ labelText: sdt.title ?? "Document section",
84328
+ labelClassName: "superdoc-document-section__tooltip",
84329
+ isStart: true,
84330
+ isEnd: true
84331
+ };
84332
+ }
84333
+ if (isStructuredContentMetadata(sdt) && sdt.scope === "block") {
84334
+ return {
84335
+ className: "superdoc-structured-content-block",
84336
+ labelText: sdt.alias ?? "Structured content",
84337
+ labelClassName: "superdoc-structured-content__label",
84338
+ isStart: true,
84339
+ isEnd: true
84340
+ };
84341
+ }
84342
+ return null;
84343
+ }
84344
+ function applySdtContainerStyling(doc2, container, sdt, containerSdt) {
84345
+ let config2 = getSdtContainerConfig(sdt);
84346
+ if (!config2 && containerSdt) {
84347
+ config2 = getSdtContainerConfig(containerSdt);
84348
+ }
84349
+ if (!config2) return;
84350
+ container.classList.add(config2.className);
84351
+ container.dataset.sdtContainerStart = String(config2.isStart);
84352
+ container.dataset.sdtContainerEnd = String(config2.isEnd);
84353
+ container.style.overflow = "visible";
84354
+ const labelEl = doc2.createElement("div");
84355
+ labelEl.className = config2.labelClassName;
84356
+ const labelText = doc2.createElement("span");
84357
+ labelText.textContent = config2.labelText;
84358
+ labelEl.appendChild(labelText);
84359
+ container.appendChild(labelEl);
84360
+ }
83488
84361
  const renderTableFragment = (deps) => {
83489
84362
  const { doc: doc2, fragment, blockLookup, context, renderLine, applyFragmentFrame, applySdtDataset, applyStyles: applyStyles2 } = deps;
83490
84363
  if (!doc2) {
@@ -83521,6 +84394,7 @@ ${l}
83521
84394
  applyFragmentFrame(container, fragment);
83522
84395
  container.style.height = `${fragment.height}px`;
83523
84396
  applySdtDataset(container, block.attrs?.sdt);
84397
+ applySdtContainerStyling(doc2, container, block.attrs?.sdt);
83524
84398
  container.classList.add("superdoc-table-fragment");
83525
84399
  if (fragment.metadata?.columnBoundaries) {
83526
84400
  const columnCount = measure.columnWidths.length;
@@ -83987,6 +84861,8 @@ ${l}
83987
84861
  ensurePrintStyles(doc2);
83988
84862
  ensureLinkStyles(doc2);
83989
84863
  ensureTrackChangeStyles(doc2);
84864
+ ensureFieldAnnotationStyles(doc2);
84865
+ ensureSdtContainerStyles(doc2);
83990
84866
  mount2.classList.add(CLASS_NAMES.container);
83991
84867
  if (this.mount && this.mount !== mount2) {
83992
84868
  this.resetState();
@@ -84509,7 +85385,8 @@ ${l}
84509
85385
  fragmentEl.classList.add(CLASS_NAMES.fragment);
84510
85386
  const isTocEntry = block.attrs?.isTocEntry;
84511
85387
  const hasMarker = !fragment.continuesFromPrev && fragment.markerWidth && wordLayout?.marker;
84512
- const styles = isTocEntry ? { ...fragmentStyles, whiteSpace: "nowrap" } : hasMarker ? { ...fragmentStyles, overflow: "visible" } : fragmentStyles;
85388
+ const hasSdtContainer = block.attrs?.sdt?.type === "documentSection" || block.attrs?.sdt?.type === "structuredContent" || block.attrs?.containerSdt?.type === "documentSection" || block.attrs?.containerSdt?.type === "structuredContent";
85389
+ const styles = isTocEntry ? { ...fragmentStyles, whiteSpace: "nowrap" } : hasMarker || hasSdtContainer ? { ...fragmentStyles, overflow: "visible" } : fragmentStyles;
84513
85390
  applyStyles$2(fragmentEl, styles);
84514
85391
  this.applyFragmentFrame(fragmentEl, fragment, context.section);
84515
85392
  if (isTocEntry) {
@@ -84529,6 +85406,7 @@ ${l}
84529
85406
  }
84530
85407
  this.applySdtDataset(fragmentEl, block.attrs?.sdt);
84531
85408
  this.applyContainerSdtDataset(fragmentEl, block.attrs?.containerSdt);
85409
+ applySdtContainerStyling(this.doc, fragmentEl, block.attrs?.sdt, block.attrs?.containerSdt);
84532
85410
  const dropCapDescriptor = block.attrs?.dropCapDescriptor;
84533
85411
  const dropCapMeasure = measure.dropCap;
84534
85412
  if (dropCapDescriptor && dropCapMeasure && !fragment.continuesFromPrev) {
@@ -84543,8 +85421,22 @@ ${l}
84543
85421
  const paraIndentRight = paraIndent?.right ?? 0;
84544
85422
  const suppressFirstLineIndent = block.attrs?.suppressFirstLineIndent === true;
84545
85423
  const firstLineOffset = suppressFirstLineIndent ? 0 : (paraIndent?.firstLine ?? 0) - (paraIndent?.hanging ?? 0);
85424
+ const isListParagraph = !!(fragment.markerWidth && wordLayout?.marker);
85425
+ const lastRun = block.runs.length > 0 ? block.runs[block.runs.length - 1] : null;
85426
+ const paragraphEndsWithLineBreak = lastRun?.kind === "lineBreak";
84546
85427
  lines.forEach((line, index2) => {
84547
- const lineEl = this.renderLine(block, line, context);
85428
+ const availableWidthOverride = Math.max(0, fragment.width - (paraIndentLeft + paraIndentRight));
85429
+ const isLastLineOfFragment = index2 === lines.length - 1;
85430
+ const isLastLineOfParagraph = isLastLineOfFragment && !fragment.continuesOnNext;
85431
+ const shouldSkipJustifyForLastLine = isLastLineOfParagraph && !paragraphEndsWithLineBreak;
85432
+ const lineEl = this.renderLine(
85433
+ block,
85434
+ line,
85435
+ context,
85436
+ availableWidthOverride,
85437
+ fragment.fromLine + index2,
85438
+ isListParagraph || shouldSkipJustifyForLastLine
85439
+ );
84548
85440
  const isListFirstLine = index2 === 0 && !fragment.continuesFromPrev && fragment.markerWidth && wordLayout?.marker;
84549
85441
  const hasExplicitSegmentPositioning = line.segments?.some((seg) => seg.x !== void 0);
84550
85442
  const isFirstLine = index2 === 0 && !fragment.continuesFromPrev;
@@ -84733,6 +85625,7 @@ ${l}
84733
85625
  fragmentEl.dataset.itemId = fragment.itemId;
84734
85626
  const paragraphMetadata = item.paragraph.attrs?.sdt;
84735
85627
  this.applySdtDataset(fragmentEl, paragraphMetadata);
85628
+ applySdtContainerStyling(this.doc, fragmentEl, paragraphMetadata, item.paragraph.attrs?.containerSdt);
84736
85629
  if (fragment.continuesFromPrev) {
84737
85630
  fragmentEl.dataset.continuesFromPrev = "true";
84738
85631
  }
@@ -84773,8 +85666,13 @@ ${l}
84773
85666
  const lines = itemMeasure.paragraph.lines.slice(fragment.fromLine, fragment.toLine);
84774
85667
  const contentAttrs = wordLayout ? item.paragraph.attrs : stripListIndent(item.paragraph.attrs);
84775
85668
  applyParagraphBlockStyles(contentEl, contentAttrs);
84776
- lines.forEach((line) => {
84777
- const lineEl = this.renderLine(item.paragraph, line, context);
85669
+ contentEl.style.textAlign = "left";
85670
+ const paraForList = {
85671
+ ...item.paragraph,
85672
+ attrs: { ...item.paragraph.attrs || {}, alignment: "left" }
85673
+ };
85674
+ lines.forEach((line, idx) => {
85675
+ const lineEl = this.renderLine(paraForList, line, context, fragment.width, fragment.fromLine + idx, true);
84778
85676
  contentEl.appendChild(lineEl);
84779
85677
  });
84780
85678
  fragmentEl.appendChild(contentEl);
@@ -85296,12 +86194,15 @@ ${l}
85296
86194
  const applyFragmentFrameWithSection = (el, frag) => {
85297
86195
  this.applyFragmentFrame(el, frag, context.section);
85298
86196
  };
86197
+ const renderLineForTableCell = (block, line, ctx2) => {
86198
+ return this.renderLine(block, line, ctx2, void 0, void 0, true);
86199
+ };
85299
86200
  return renderTableFragment({
85300
86201
  doc: this.doc,
85301
86202
  fragment,
85302
86203
  context,
85303
86204
  blockLookup: this.blockLookup,
85304
- renderLine: this.renderLine.bind(this),
86205
+ renderLine: renderLineForTableCell,
85305
86206
  applyFragmentFrame: applyFragmentFrameWithSection,
85306
86207
  applySdtDataset: this.applySdtDataset.bind(this),
85307
86208
  applyStyles: applyStyles$2
@@ -85496,10 +86397,19 @@ ${l}
85496
86397
  isBreakRun(run2) {
85497
86398
  return run2.kind === "break";
85498
86399
  }
86400
+ /**
86401
+ * Type guard to check if a run is a field annotation run.
86402
+ */
86403
+ isFieldAnnotationRun(run2) {
86404
+ return run2.kind === "fieldAnnotation";
86405
+ }
85499
86406
  renderRun(run2, context, trackedConfig) {
85500
86407
  if (this.isImageRun(run2)) {
85501
86408
  return this.renderImageRun(run2);
85502
86409
  }
86410
+ if (this.isFieldAnnotationRun(run2)) {
86411
+ return this.renderFieldAnnotationRun(run2);
86412
+ }
85503
86413
  if (this.isLineBreakRun(run2)) {
85504
86414
  return null;
85505
86415
  }
@@ -85636,7 +86546,212 @@ ${l}
85636
86546
  }
85637
86547
  return img2;
85638
86548
  }
85639
- renderLine(block, line, context) {
86549
+ /**
86550
+ * Renders a FieldAnnotationRun as an inline "pill" element matching super-editor's visual appearance.
86551
+ *
86552
+ * Field annotations are styled inline elements that display form fields with:
86553
+ * - Outer span with border, border-radius, padding, and background color
86554
+ * - Inner span containing the displayLabel or type-specific content (image, link, etc.)
86555
+ *
86556
+ * @param run - The FieldAnnotationRun to render containing field configuration and styling
86557
+ * @returns HTMLElement (span) or null if document is not available
86558
+ *
86559
+ * @example
86560
+ * ```typescript
86561
+ * // Text variant
86562
+ * renderFieldAnnotationRun({ kind: 'fieldAnnotation', variant: 'text', displayLabel: 'Full Name', fieldColor: '#980043' })
86563
+ * // Returns: <span class="annotation" style="border: 2px solid #b015b3; ..."><span class="annotation-content">Full Name</span></span>
86564
+ *
86565
+ * // Image variant with imageSrc
86566
+ * renderFieldAnnotationRun({ kind: 'fieldAnnotation', variant: 'image', displayLabel: 'Photo', imageSrc: 'data:image/png;...' })
86567
+ * // Returns: <span class="annotation"><span class="annotation-content"><img src="..." /></span></span>
86568
+ *
86569
+ * // Link variant
86570
+ * renderFieldAnnotationRun({ kind: 'fieldAnnotation', variant: 'link', displayLabel: 'Website', linkUrl: 'https://example.com' })
86571
+ * // Returns: <span class="annotation"><span class="annotation-content"><a href="...">https://example.com</a></span></span>
86572
+ * ```
86573
+ */
86574
+ renderFieldAnnotationRun(run2) {
86575
+ if (!this.doc) {
86576
+ return null;
86577
+ }
86578
+ if (run2.hidden) {
86579
+ const hidden2 = this.doc.createElement("span");
86580
+ hidden2.style.display = "none";
86581
+ if (run2.pmStart != null) hidden2.dataset.pmStart = String(run2.pmStart);
86582
+ if (run2.pmEnd != null) hidden2.dataset.pmEnd = String(run2.pmEnd);
86583
+ return hidden2;
86584
+ }
86585
+ const defaultBorderColor = "#b015b3";
86586
+ const defaultFieldColor = "#980043";
86587
+ const annotation = this.doc.createElement("span");
86588
+ annotation.classList.add("annotation");
86589
+ annotation.setAttribute("aria-label", "Field annotation");
86590
+ const showHighlight = run2.highlighted !== false;
86591
+ if (showHighlight) {
86592
+ const borderColor = run2.borderColor || defaultBorderColor;
86593
+ annotation.style.border = `2px solid ${borderColor}`;
86594
+ annotation.style.borderRadius = "2px";
86595
+ annotation.style.padding = "1px 2px";
86596
+ annotation.style.boxSizing = "border-box";
86597
+ const fieldColor = run2.fieldColor || defaultFieldColor;
86598
+ const bgColor = fieldColor.length === 7 ? `${fieldColor}33` : fieldColor;
86599
+ if (run2.textHighlight) {
86600
+ annotation.style.backgroundColor = run2.textHighlight;
86601
+ } else {
86602
+ annotation.style.backgroundColor = bgColor;
86603
+ }
86604
+ }
86605
+ if (run2.visibility === "hidden") {
86606
+ annotation.style.visibility = "hidden";
86607
+ }
86608
+ if (run2.size) {
86609
+ if (run2.size.width) {
86610
+ annotation.style.width = `${run2.size.width}px`;
86611
+ annotation.style.display = "inline-block";
86612
+ annotation.style.overflow = "hidden";
86613
+ }
86614
+ if (run2.size.height) {
86615
+ annotation.style.height = `${run2.size.height}px`;
86616
+ }
86617
+ }
86618
+ if (run2.fontFamily) {
86619
+ annotation.style.fontFamily = run2.fontFamily;
86620
+ }
86621
+ if (run2.fontSize) {
86622
+ const fontSize2 = typeof run2.fontSize === "number" ? `${run2.fontSize}pt` : run2.fontSize;
86623
+ annotation.style.fontSize = fontSize2;
86624
+ }
86625
+ if (run2.textColor) {
86626
+ annotation.style.color = run2.textColor;
86627
+ }
86628
+ if (run2.bold) {
86629
+ annotation.style.fontWeight = "bold";
86630
+ }
86631
+ if (run2.italic) {
86632
+ annotation.style.fontStyle = "italic";
86633
+ }
86634
+ if (run2.underline) {
86635
+ annotation.style.textDecoration = "underline";
86636
+ }
86637
+ annotation.style.zIndex = "1";
86638
+ const content2 = this.doc.createElement("span");
86639
+ content2.classList.add("annotation-content");
86640
+ content2.style.pointerEvents = "none";
86641
+ content2.setAttribute("contenteditable", "false");
86642
+ switch (run2.variant) {
86643
+ case "image":
86644
+ case "signature": {
86645
+ if (run2.imageSrc) {
86646
+ const img2 = this.doc.createElement("img");
86647
+ const isDataUrl = run2.imageSrc.startsWith("data:");
86648
+ if (isDataUrl) {
86649
+ if (run2.imageSrc.length <= MAX_DATA_URL_LENGTH && VALID_IMAGE_DATA_URL.test(run2.imageSrc)) {
86650
+ img2.src = run2.imageSrc;
86651
+ } else {
86652
+ content2.textContent = run2.displayLabel;
86653
+ break;
86654
+ }
86655
+ } else {
86656
+ const sanitized = sanitizeHref(run2.imageSrc);
86657
+ if (sanitized) {
86658
+ img2.src = sanitized.href;
86659
+ } else {
86660
+ content2.textContent = run2.displayLabel;
86661
+ break;
86662
+ }
86663
+ }
86664
+ img2.alt = run2.displayLabel;
86665
+ img2.style.height = "auto";
86666
+ img2.style.maxWidth = "100%";
86667
+ img2.style.pointerEvents = "none";
86668
+ img2.style.verticalAlign = "middle";
86669
+ if (run2.variant === "signature") {
86670
+ img2.style.maxHeight = "28px";
86671
+ }
86672
+ content2.appendChild(img2);
86673
+ annotation.style.display = "inline-block";
86674
+ content2.style.display = "inline-block";
86675
+ } else {
86676
+ content2.textContent = run2.displayLabel || (run2.variant === "signature" ? "Signature" : "");
86677
+ }
86678
+ break;
86679
+ }
86680
+ case "link": {
86681
+ if (run2.linkUrl) {
86682
+ const link2 = this.doc.createElement("a");
86683
+ const sanitized = sanitizeHref(run2.linkUrl);
86684
+ if (sanitized) {
86685
+ link2.href = sanitized.href;
86686
+ link2.target = "_blank";
86687
+ link2.rel = "noopener noreferrer";
86688
+ link2.textContent = run2.linkUrl;
86689
+ link2.style.textDecoration = "none";
86690
+ content2.style.pointerEvents = "all";
86691
+ content2.appendChild(link2);
86692
+ } else {
86693
+ content2.textContent = run2.displayLabel;
86694
+ }
86695
+ } else {
86696
+ content2.textContent = run2.displayLabel;
86697
+ }
86698
+ break;
86699
+ }
86700
+ case "html": {
86701
+ if (run2.rawHtml && typeof run2.rawHtml === "string") {
86702
+ content2.textContent = run2.displayLabel;
86703
+ annotation.style.display = "inline-block";
86704
+ content2.style.display = "inline-block";
86705
+ } else {
86706
+ content2.textContent = run2.displayLabel;
86707
+ }
86708
+ break;
86709
+ }
86710
+ case "text":
86711
+ case "checkbox":
86712
+ default: {
86713
+ content2.textContent = run2.displayLabel;
86714
+ break;
86715
+ }
86716
+ }
86717
+ annotation.appendChild(content2);
86718
+ annotation.dataset.type = run2.variant;
86719
+ if (run2.fieldId) {
86720
+ annotation.dataset.fieldId = run2.fieldId;
86721
+ }
86722
+ if (run2.fieldType) {
86723
+ annotation.dataset.fieldType = run2.fieldType;
86724
+ }
86725
+ annotation.draggable = true;
86726
+ annotation.dataset.draggable = "true";
86727
+ if (run2.displayLabel) {
86728
+ annotation.dataset.displayLabel = run2.displayLabel;
86729
+ }
86730
+ if (run2.variant) {
86731
+ annotation.dataset.variant = run2.variant;
86732
+ }
86733
+ assertPmPositions(run2, "field annotation run");
86734
+ if (run2.pmStart != null) {
86735
+ annotation.dataset.pmStart = String(run2.pmStart);
86736
+ }
86737
+ if (run2.pmEnd != null) {
86738
+ annotation.dataset.pmEnd = String(run2.pmEnd);
86739
+ }
86740
+ this.applySdtDataset(annotation, run2.sdt);
86741
+ return annotation;
86742
+ }
86743
+ /**
86744
+ * Renders a single line of a paragraph block.
86745
+ *
86746
+ * @param block - The paragraph block containing the line
86747
+ * @param line - The line measurement data
86748
+ * @param context - Rendering context with fragment information
86749
+ * @param availableWidthOverride - Optional override for available width used in justification calculations
86750
+ * @param lineIndex - Optional zero-based index of the line within the fragment
86751
+ * @param skipJustify - When true, prevents justification even if alignment is 'justify'
86752
+ * @returns The rendered line element
86753
+ */
86754
+ renderLine(block, line, context, availableWidthOverride, lineIndex, skipJustify) {
85640
86755
  if (!this.doc) {
85641
86756
  throw new Error("DomPainter: document is not available");
85642
86757
  }
@@ -85648,8 +86763,10 @@ ${l}
85648
86763
  el.setAttribute("styleid", styleId);
85649
86764
  }
85650
86765
  const alignment2 = block.attrs?.alignment;
85651
- if (alignment2 === "center" || alignment2 === "right" || alignment2 === "justify") {
85652
- el.style.textAlign = alignment2 === "justify" ? "justify" : alignment2;
86766
+ if (alignment2 === "center" || alignment2 === "right") {
86767
+ el.style.textAlign = alignment2;
86768
+ } else if (alignment2 === "justify") {
86769
+ el.style.textAlign = "left";
85653
86770
  } else {
85654
86771
  el.style.textAlign = "left";
85655
86772
  }
@@ -85662,6 +86779,7 @@ ${l}
85662
86779
  }
85663
86780
  const runsForLine = sliceRunsForLine(block, line);
85664
86781
  const trackedConfig = this.resolveTrackedChangesConfig(block);
86782
+ const textSlices = runsForLine.length > 0 ? runsForLine.filter((r2) => (r2.kind === "text" || r2.kind === void 0) && "text" in r2 && r2.text != null).map((r2) => r2.text) : gatherTextSlicesForLine(block, line);
85665
86783
  if (runsForLine.length === 0) {
85666
86784
  const span = this.doc.createElement("span");
85667
86785
  span.innerHTML = "&nbsp;";
@@ -85708,6 +86826,19 @@ ${l}
85708
86826
  });
85709
86827
  }
85710
86828
  const hasExplicitPositioning = line.segments?.some((seg) => seg.x !== void 0);
86829
+ const availableWidth = availableWidthOverride ?? line.maxWidth ?? line.width;
86830
+ const shouldJustify = !skipJustify && alignment2 === "justify" && !hasExplicitPositioning;
86831
+ if (shouldJustify) {
86832
+ const spaceCount = textSlices.reduce(
86833
+ (sum, s2) => sum + Array.from(s2).filter((ch) => ch === " " || ch === " ").length,
86834
+ 0
86835
+ );
86836
+ const slack = Math.max(0, availableWidth - line.width);
86837
+ if (spaceCount > 0 && slack > 0) {
86838
+ const extraPerSpace = slack / spaceCount;
86839
+ el.style.wordSpacing = `${extraPerSpace}px`;
86840
+ }
86841
+ }
85711
86842
  if (hasExplicitPositioning && line.segments) {
85712
86843
  let cumulativeX = 0;
85713
86844
  const segmentsByRun = /* @__PURE__ */ new Map();
@@ -85786,6 +86917,22 @@ ${l}
85786
86917
  if (this.isBreakRun(baseRun)) {
85787
86918
  continue;
85788
86919
  }
86920
+ if (this.isFieldAnnotationRun(baseRun)) {
86921
+ const elem = this.renderRun(baseRun, context, trackedConfig);
86922
+ if (elem) {
86923
+ if (styleId) {
86924
+ elem.setAttribute("styleid", styleId);
86925
+ }
86926
+ const runSegments2 = segmentsByRun.get(runIndex);
86927
+ const segX = runSegments2 && runSegments2[0]?.x !== void 0 ? runSegments2[0].x : cumulativeX;
86928
+ const segWidth = (runSegments2 && runSegments2[0]?.width !== void 0 ? runSegments2[0].width : 0) ?? 0;
86929
+ elem.style.position = "absolute";
86930
+ elem.style.left = `${segX}px`;
86931
+ el.appendChild(elem);
86932
+ cumulativeX = segX + segWidth;
86933
+ }
86934
+ continue;
86935
+ }
85789
86936
  const runSegments = segmentsByRun.get(runIndex);
85790
86937
  if (!runSegments || runSegments.length === 0) {
85791
86938
  continue;
@@ -85831,7 +86978,22 @@ ${l}
85831
86978
  });
85832
86979
  }
85833
86980
  } else {
86981
+ let currentInlineSdtWrapper = null;
86982
+ let currentInlineSdtId = null;
86983
+ const closeCurrentWrapper = () => {
86984
+ if (currentInlineSdtWrapper) {
86985
+ el.appendChild(currentInlineSdtWrapper);
86986
+ currentInlineSdtWrapper = null;
86987
+ currentInlineSdtId = null;
86988
+ }
86989
+ };
85834
86990
  runsForLine.forEach((run2) => {
86991
+ const runSdt = run2.sdt;
86992
+ const isInlineSdt = runSdt?.type === "structuredContent" && runSdt?.scope === "inline";
86993
+ const runSdtId = isInlineSdt && runSdt?.id ? String(runSdt.id) : null;
86994
+ if (runSdtId !== currentInlineSdtId) {
86995
+ closeCurrentWrapper();
86996
+ }
85835
86997
  if (run2.kind === "tab") {
85836
86998
  const tabEl = this.doc.createElement("span");
85837
86999
  tabEl.classList.add("superdoc-tab");
@@ -85859,9 +87021,37 @@ ${l}
85859
87021
  if (styleId) {
85860
87022
  elem.setAttribute("styleid", styleId);
85861
87023
  }
85862
- el.appendChild(elem);
87024
+ if (isInlineSdt && runSdtId && this.doc) {
87025
+ if (!currentInlineSdtWrapper) {
87026
+ currentInlineSdtWrapper = this.doc.createElement("span");
87027
+ currentInlineSdtWrapper.className = "superdoc-structured-content-inline";
87028
+ currentInlineSdtId = runSdtId;
87029
+ this.applySdtDataset(currentInlineSdtWrapper, runSdt);
87030
+ const alias = runSdt?.alias || "Inline content";
87031
+ const labelEl = this.doc.createElement("span");
87032
+ labelEl.className = "superdoc-structured-content-inline__label";
87033
+ labelEl.textContent = alias;
87034
+ currentInlineSdtWrapper.appendChild(labelEl);
87035
+ }
87036
+ const wrapperPmStart = currentInlineSdtWrapper.dataset.pmStart;
87037
+ const wrapperPmEnd = currentInlineSdtWrapper.dataset.pmEnd;
87038
+ if (run2.pmStart != null) {
87039
+ if (!wrapperPmStart || run2.pmStart < parseInt(wrapperPmStart, 10)) {
87040
+ currentInlineSdtWrapper.dataset.pmStart = String(run2.pmStart);
87041
+ }
87042
+ }
87043
+ if (run2.pmEnd != null) {
87044
+ if (!wrapperPmEnd || run2.pmEnd > parseInt(wrapperPmEnd, 10)) {
87045
+ currentInlineSdtWrapper.dataset.pmEnd = String(run2.pmEnd);
87046
+ }
87047
+ }
87048
+ currentInlineSdtWrapper.appendChild(elem);
87049
+ } else {
87050
+ el.appendChild(elem);
87051
+ }
85863
87052
  }
85864
87053
  });
87054
+ closeCurrentWrapper();
85865
87055
  }
85866
87056
  const anchors = el.querySelectorAll("a[href]");
85867
87057
  anchors.forEach((anchor) => {
@@ -86369,7 +87559,7 @@ ${l}
86369
87559
  return block.id;
86370
87560
  };
86371
87561
  const applyRunStyles = (element2, run2, _isLink = false) => {
86372
- if (run2.kind === "tab" || run2.kind === "image" || run2.kind === "lineBreak" || run2.kind === "break") {
87562
+ if (run2.kind === "tab" || run2.kind === "image" || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation") {
86373
87563
  return;
86374
87564
  }
86375
87565
  element2.style.fontFamily = run2.fontFamily;
@@ -86491,6 +87681,23 @@ ${l}
86491
87681
  if (!shading?.fill) return;
86492
87682
  element2.style.backgroundColor = shading.fill;
86493
87683
  };
87684
+ const gatherTextSlicesForLine = (block, line) => {
87685
+ const slices = [];
87686
+ const startRun = line.fromRun ?? 0;
87687
+ const endRun = line.toRun ?? startRun;
87688
+ for (let runIndex = startRun; runIndex <= endRun; runIndex += 1) {
87689
+ const run2 = block.runs[runIndex];
87690
+ if (!run2 || run2.kind !== "text" && run2.kind !== void 0 || !("text" in run2) || !run2.text) continue;
87691
+ const isFirst = runIndex === startRun;
87692
+ const isLast = runIndex === endRun;
87693
+ const start2 = isFirst ? line.fromChar ?? 0 : 0;
87694
+ const end2 = isLast ? line.toChar ?? run2.text.length : run2.text.length;
87695
+ if (start2 >= end2) continue;
87696
+ const slice2 = run2.text.slice(start2, end2);
87697
+ if (slice2) slices.push(slice2);
87698
+ }
87699
+ return slices;
87700
+ };
86494
87701
  const sliceRunsForLine = (block, line) => {
86495
87702
  const result = [];
86496
87703
  for (let runIndex = line.fromRun; runIndex <= line.toRun; runIndex += 1) {
@@ -86512,6 +87719,10 @@ ${l}
86512
87719
  result.push(run2);
86513
87720
  continue;
86514
87721
  }
87722
+ if (run2.kind === "fieldAnnotation") {
87723
+ result.push(run2);
87724
+ continue;
87725
+ }
86515
87726
  if (!("text" in run2)) {
86516
87727
  continue;
86517
87728
  }
@@ -86827,6 +88038,10 @@ ${l}
86827
88038
  const TAB_EPSILON = 0.1;
86828
88039
  const DEFAULT_DECIMAL_SEPARATOR = ".";
86829
88040
  const ALLOWED_TAB_VALS = /* @__PURE__ */ new Set(["start", "center", "end", "decimal", "bar", "clear"]);
88041
+ const FIELD_ANNOTATION_PILL_PADDING = 8;
88042
+ const FIELD_ANNOTATION_LINE_HEIGHT_MULTIPLIER = 1.2;
88043
+ const FIELD_ANNOTATION_VERTICAL_PADDING = 6;
88044
+ const DEFAULT_FIELD_ANNOTATION_FONT_SIZE = 16;
86830
88045
  const roundValue = (value) => value;
86831
88046
  function getCanvasContext() {
86832
88047
  if (!canvasContext) {
@@ -86906,6 +88121,9 @@ ${l}
86906
88121
  function isLineBreakRun(run2) {
86907
88122
  return run2.kind === "lineBreak";
86908
88123
  }
88124
+ function isFieldAnnotationRun(run2) {
88125
+ return run2.kind === "fieldAnnotation";
88126
+ }
86909
88127
  async function measureBlock(block, constraints) {
86910
88128
  const normalized = normalizeConstraints(constraints);
86911
88129
  if (block.kind === "drawing") {
@@ -87272,6 +88490,92 @@ ${l}
87272
88490
  lastAppliedTabAlign = null;
87273
88491
  continue;
87274
88492
  }
88493
+ if (isFieldAnnotationRun(run2)) {
88494
+ const displayText = run2.displayLabel || "";
88495
+ const annotationFontSize = typeof run2.fontSize === "number" ? run2.fontSize : typeof run2.fontSize === "string" ? parseFloat(run2.fontSize) || DEFAULT_FIELD_ANNOTATION_FONT_SIZE : DEFAULT_FIELD_ANNOTATION_FONT_SIZE;
88496
+ const annotationFontFamily = run2.fontFamily || "Arial, sans-serif";
88497
+ const fontWeight = run2.bold ? "bold" : "normal";
88498
+ const fontStyle = run2.italic ? "italic" : "normal";
88499
+ const annotationFont = `${fontStyle} ${fontWeight} ${annotationFontSize}px ${annotationFontFamily}`;
88500
+ ctx2.font = annotationFont;
88501
+ const textWidth = displayText ? ctx2.measureText(displayText).width : 0;
88502
+ const annotationWidth = textWidth + FIELD_ANNOTATION_PILL_PADDING;
88503
+ const annotationHeight = annotationFontSize * FIELD_ANNOTATION_LINE_HEIGHT_MULTIPLIER + FIELD_ANNOTATION_VERTICAL_PADDING;
88504
+ let annotationStartX;
88505
+ if (pendingTabAlignment && currentLine) {
88506
+ annotationStartX = alignPendingTabForWidth(annotationWidth);
88507
+ }
88508
+ if (!currentLine) {
88509
+ currentLine = {
88510
+ fromRun: runIndex,
88511
+ fromChar: 0,
88512
+ toRun: runIndex,
88513
+ toChar: 1,
88514
+ // Field annotations are atomic units
88515
+ width: annotationWidth,
88516
+ maxFontSize: annotationHeight,
88517
+ maxWidth: getEffectiveWidth(initialAvailableWidth),
88518
+ segments: [
88519
+ {
88520
+ runIndex,
88521
+ fromChar: 0,
88522
+ toChar: 1,
88523
+ width: annotationWidth,
88524
+ ...annotationStartX !== void 0 ? { x: annotationStartX } : {}
88525
+ }
88526
+ ]
88527
+ };
88528
+ continue;
88529
+ }
88530
+ if (currentLine.width + annotationWidth > currentLine.maxWidth && currentLine.width > 0) {
88531
+ const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
88532
+ const completedLine = {
88533
+ ...currentLine,
88534
+ ...metrics
88535
+ };
88536
+ addBarTabsToLine(completedLine);
88537
+ lines.push(completedLine);
88538
+ tabStopCursor = 0;
88539
+ pendingTabAlignment = null;
88540
+ lastAppliedTabAlign = null;
88541
+ currentLine = {
88542
+ fromRun: runIndex,
88543
+ fromChar: 0,
88544
+ toRun: runIndex,
88545
+ toChar: 1,
88546
+ width: annotationWidth,
88547
+ maxFontSize: annotationHeight,
88548
+ maxWidth: getEffectiveWidth(contentWidth),
88549
+ segments: [
88550
+ {
88551
+ runIndex,
88552
+ fromChar: 0,
88553
+ toChar: 1,
88554
+ width: annotationWidth
88555
+ }
88556
+ ]
88557
+ };
88558
+ } else {
88559
+ currentLine.toRun = runIndex;
88560
+ currentLine.toChar = 1;
88561
+ currentLine.width = roundValue(currentLine.width + annotationWidth);
88562
+ currentLine.maxFontSize = Math.max(currentLine.maxFontSize, annotationHeight);
88563
+ if (!currentLine.segments) currentLine.segments = [];
88564
+ currentLine.segments.push({
88565
+ runIndex,
88566
+ fromChar: 0,
88567
+ toChar: 1,
88568
+ width: annotationWidth,
88569
+ ...annotationStartX !== void 0 ? { x: annotationStartX } : {}
88570
+ });
88571
+ }
88572
+ const tabAlign = lastAppliedTabAlign;
88573
+ if (tabAlign && currentLine && tabAlign.val === "end") {
88574
+ currentLine.width = roundValue(tabAlign.target);
88575
+ }
88576
+ lastAppliedTabAlign = null;
88577
+ continue;
88578
+ }
87275
88579
  if (!("text" in run2) || !("fontSize" in run2)) {
87276
88580
  continue;
87277
88581
  }
@@ -89236,6 +90540,12 @@ ${l}
89236
90540
  }
89237
90541
  return false;
89238
90542
  }
90543
+ function isValidFieldAnnotationAttributes(attrs) {
90544
+ if (!attrs || typeof attrs !== "object") return false;
90545
+ const a2 = attrs;
90546
+ return typeof a2.fieldId === "string" && typeof a2.fieldType === "string" && typeof a2.displayLabel === "string" && typeof a2.type === "string";
90547
+ }
90548
+ const FIELD_ANNOTATION_DATA_TYPE = "fieldAnnotation";
89239
90549
  const DEFAULT_PAGE_SIZE = { w: 612, h: 792 };
89240
90550
  const DEFAULT_MARGINS = { top: 72, right: 72, bottom: 72, left: 72 };
89241
90551
  const WORD_CHARACTER_REGEX = /[\p{L}\p{N}''_~-]/u;
@@ -89261,6 +90571,7 @@ ${l}
89261
90571
  __privateAdd$1(this, _layoutOptions);
89262
90572
  __privateAdd$1(this, _layoutState, { blocks: [], measures: [], layout: null });
89263
90573
  __privateAdd$1(this, _domPainter, null);
90574
+ __privateAdd$1(this, _dragHandlerCleanup, null);
89264
90575
  __privateAdd$1(this, _layoutError, null);
89265
90576
  __privateAdd$1(this, _layoutErrorState, "healthy");
89266
90577
  __privateAdd$1(this, _errorBanner, null);
@@ -89304,6 +90615,9 @@ ${l}
89304
90615
  __privateAdd$1(this, _lastClickTime, 0);
89305
90616
  __privateAdd$1(this, _lastClickPosition, { x: 0, y: 0 });
89306
90617
  __privateAdd$1(this, _lastSelectedImageBlockId, null);
90618
+ __privateAdd$1(this, _dragAnchor, null);
90619
+ __privateAdd$1(this, _isDragging, false);
90620
+ __privateAdd$1(this, _dragExtensionMode, "char");
89307
90621
  __privateAdd$1(this, _remoteCursorState, /* @__PURE__ */ new Map());
89308
90622
  __privateAdd$1(this, _remoteCursorDirty, false);
89309
90623
  __privateAdd$1(this, _remoteCursorOverlay, null);
@@ -89316,8 +90630,12 @@ ${l}
89316
90630
  if (event.button !== 0) {
89317
90631
  return;
89318
90632
  }
90633
+ const target = event.target;
90634
+ const isDraggableAnnotation = target?.closest?.('[data-draggable="true"]') != null;
89319
90635
  if (!__privateGet$1(this, _layoutState).layout) {
89320
- event.preventDefault();
90636
+ if (!isDraggableAnnotation) {
90637
+ event.preventDefault();
90638
+ }
89321
90639
  if (document.activeElement instanceof HTMLElement) {
89322
90640
  document.activeElement.blur();
89323
90641
  }
@@ -89326,10 +90644,10 @@ ${l}
89326
90644
  return;
89327
90645
  }
89328
90646
  const validPos = __privateMethod$1(this, _PresentationEditor_instances, getFirstTextPosition_fn).call(this);
89329
- const doc22 = __privateGet$1(this, _editor3)?.state?.doc;
89330
- if (doc22) {
90647
+ const doc222 = __privateGet$1(this, _editor3)?.state?.doc;
90648
+ if (doc222) {
89331
90649
  try {
89332
- const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(doc22, validPos));
90650
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(doc222, validPos));
89333
90651
  __privateGet$1(this, _editor3).view?.dispatch(tr);
89334
90652
  } catch (error) {
89335
90653
  if (process$1$1.env.NODE_ENV === "development") {
@@ -89365,7 +90683,7 @@ ${l}
89365
90683
  if (headerFooterRegion) {
89366
90684
  return;
89367
90685
  }
89368
- const hit = clickToPosition(
90686
+ const rawHit = clickToPosition(
89369
90687
  __privateGet$1(this, _layoutState).layout,
89370
90688
  __privateGet$1(this, _layoutState).blocks,
89371
90689
  __privateGet$1(this, _layoutState).measures,
@@ -89374,7 +90692,11 @@ ${l}
89374
90692
  event.clientX,
89375
90693
  event.clientY
89376
90694
  );
89377
- event.preventDefault();
90695
+ const doc22 = __privateGet$1(this, _editor3).state?.doc;
90696
+ const hit = rawHit && doc22 ? { ...rawHit, pos: Math.max(0, Math.min(rawHit.pos, doc22.content.size)) } : rawHit;
90697
+ if (!isDraggableAnnotation) {
90698
+ event.preventDefault();
90699
+ }
89378
90700
  if (!hit) {
89379
90701
  if (document.activeElement instanceof HTMLElement) {
89380
90702
  document.activeElement.blur();
@@ -89382,10 +90704,10 @@ ${l}
89382
90704
  const editorDom2 = __privateGet$1(this, _editor3).view?.dom;
89383
90705
  if (editorDom2) {
89384
90706
  const validPos = __privateMethod$1(this, _PresentationEditor_instances, getFirstTextPosition_fn).call(this);
89385
- const doc22 = __privateGet$1(this, _editor3)?.state?.doc;
89386
- if (doc22) {
90707
+ const doc222 = __privateGet$1(this, _editor3)?.state?.doc;
90708
+ if (doc222) {
89387
90709
  try {
89388
- const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(doc22, validPos));
90710
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(doc222, validPos));
89389
90711
  __privateGet$1(this, _editor3).view?.dispatch(tr);
89390
90712
  } catch (error) {
89391
90713
  if (process$1$1.env.NODE_ENV === "development") {
@@ -89406,9 +90728,9 @@ ${l}
89406
90728
  hit.pos
89407
90729
  );
89408
90730
  if (fragmentHit && (fragmentHit.fragment.kind === "image" || fragmentHit.fragment.kind === "drawing")) {
89409
- const doc22 = __privateGet$1(this, _editor3).state.doc;
90731
+ const doc222 = __privateGet$1(this, _editor3).state.doc;
89410
90732
  try {
89411
- const tr = __privateGet$1(this, _editor3).state.tr.setSelection(NodeSelection.create(doc22, hit.pos));
90733
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(NodeSelection.create(doc222, hit.pos));
89412
90734
  __privateGet$1(this, _editor3).view?.dispatch(tr);
89413
90735
  if (__privateGet$1(this, _lastSelectedImageBlockId) && __privateGet$1(this, _lastSelectedImageBlockId) !== fragmentHit.fragment.blockId) {
89414
90736
  this.emit("imageDeselected", { blockId: __privateGet$1(this, _lastSelectedImageBlockId) });
@@ -89446,18 +90768,61 @@ ${l}
89446
90768
  this.emit("imageDeselected", { blockId: __privateGet$1(this, _lastSelectedImageBlockId) });
89447
90769
  __privateSet(this, _lastSelectedImageBlockId, null);
89448
90770
  }
90771
+ if (event.shiftKey && __privateGet$1(this, _editor3).state.selection.$anchor) {
90772
+ const anchor = __privateGet$1(this, _editor3).state.selection.anchor;
90773
+ const head = hit.pos;
90774
+ const { selAnchor, selHead } = __privateMethod$1(this, _PresentationEditor_instances, calculateExtendedSelection_fn).call(this, anchor, head, __privateGet$1(this, _dragExtensionMode));
90775
+ try {
90776
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(__privateGet$1(this, _editor3).state.doc, selAnchor, selHead));
90777
+ __privateGet$1(this, _editor3).view?.dispatch(tr);
90778
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
90779
+ } catch (error) {
90780
+ console.warn("[SELECTION] Failed to extend selection on shift+click:", {
90781
+ error,
90782
+ anchor,
90783
+ head,
90784
+ selAnchor,
90785
+ selHead,
90786
+ mode: __privateGet$1(this, _dragExtensionMode)
90787
+ });
90788
+ }
90789
+ if (document.activeElement instanceof HTMLElement) {
90790
+ document.activeElement.blur();
90791
+ }
90792
+ const editorDom2 = __privateGet$1(this, _editor3).view?.dom;
90793
+ if (editorDom2) {
90794
+ editorDom2.focus();
90795
+ __privateGet$1(this, _editor3).view?.focus();
90796
+ }
90797
+ return;
90798
+ }
89449
90799
  const clickDepth = __privateMethod$1(this, _PresentationEditor_instances, registerPointerClick_fn).call(this, event);
90800
+ if (clickDepth === 1) {
90801
+ __privateSet(this, _dragAnchor, hit.pos);
90802
+ }
90803
+ __privateSet(this, _isDragging, true);
90804
+ if (clickDepth >= 3) {
90805
+ __privateSet(this, _dragExtensionMode, "para");
90806
+ } else if (clickDepth === 2) {
90807
+ __privateSet(this, _dragExtensionMode, "word");
90808
+ } else {
90809
+ __privateSet(this, _dragExtensionMode, "char");
90810
+ }
90811
+ if (typeof __privateGet$1(this, _viewportHost).setPointerCapture === "function") {
90812
+ __privateGet$1(this, _viewportHost).setPointerCapture(event.pointerId);
90813
+ }
89450
90814
  let handledByDepth = false;
89451
90815
  if (__privateGet$1(this, _session).mode === "body") {
90816
+ const selectionPos = clickDepth >= 2 && __privateGet$1(this, _dragAnchor) !== null ? __privateGet$1(this, _dragAnchor) : hit.pos;
89452
90817
  if (clickDepth >= 3) {
89453
- handledByDepth = __privateMethod$1(this, _PresentationEditor_instances, selectParagraphAt_fn).call(this, hit.pos);
90818
+ handledByDepth = __privateMethod$1(this, _PresentationEditor_instances, selectParagraphAt_fn).call(this, selectionPos);
89454
90819
  } else if (clickDepth === 2) {
89455
- handledByDepth = __privateMethod$1(this, _PresentationEditor_instances, selectWordAt_fn).call(this, hit.pos);
90820
+ handledByDepth = __privateMethod$1(this, _PresentationEditor_instances, selectWordAt_fn).call(this, selectionPos);
89456
90821
  }
89457
90822
  }
89458
90823
  if (!handledByDepth) {
89459
- const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(__privateGet$1(this, _editor3).state.doc, hit.pos));
89460
90824
  try {
90825
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(__privateGet$1(this, _editor3).state.doc, hit.pos));
89461
90826
  __privateGet$1(this, _editor3).view?.dispatch(tr);
89462
90827
  } catch {
89463
90828
  }
@@ -89477,6 +90842,36 @@ ${l}
89477
90842
  if (!__privateGet$1(this, _layoutState).layout) return;
89478
90843
  const normalized = __privateMethod$1(this, _PresentationEditor_instances, normalizeClientPoint_fn).call(this, event.clientX, event.clientY);
89479
90844
  if (!normalized) return;
90845
+ if (__privateGet$1(this, _isDragging) && __privateGet$1(this, _dragAnchor) !== null && event.buttons & 1) {
90846
+ const hit = clickToPosition(
90847
+ __privateGet$1(this, _layoutState).layout,
90848
+ __privateGet$1(this, _layoutState).blocks,
90849
+ __privateGet$1(this, _layoutState).measures,
90850
+ { x: normalized.x, y: normalized.y },
90851
+ __privateGet$1(this, _viewportHost),
90852
+ event.clientX,
90853
+ event.clientY
90854
+ );
90855
+ if (!hit) return;
90856
+ const anchor = __privateGet$1(this, _dragAnchor);
90857
+ const head = hit.pos;
90858
+ const { selAnchor, selHead } = __privateMethod$1(this, _PresentationEditor_instances, calculateExtendedSelection_fn).call(this, anchor, head, __privateGet$1(this, _dragExtensionMode));
90859
+ try {
90860
+ const tr = __privateGet$1(this, _editor3).state.tr.setSelection(TextSelection$1.create(__privateGet$1(this, _editor3).state.doc, selAnchor, selHead));
90861
+ __privateGet$1(this, _editor3).view?.dispatch(tr);
90862
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
90863
+ } catch (error) {
90864
+ console.warn("[SELECTION] Failed to extend selection during drag:", {
90865
+ error,
90866
+ anchor,
90867
+ head,
90868
+ selAnchor,
90869
+ selHead,
90870
+ mode: __privateGet$1(this, _dragExtensionMode)
90871
+ });
90872
+ }
90873
+ return;
90874
+ }
89480
90875
  if (__privateGet$1(this, _session).mode !== "body") {
89481
90876
  __privateMethod$1(this, _PresentationEditor_instances, clearHoverRegion_fn).call(this);
89482
90877
  return;
@@ -89495,6 +90890,97 @@ ${l}
89495
90890
  __privateAdd$1(this, _handlePointerLeave, () => {
89496
90891
  __privateMethod$1(this, _PresentationEditor_instances, clearHoverRegion_fn).call(this);
89497
90892
  });
90893
+ __privateAdd$1(this, _handlePointerUp, (event) => {
90894
+ if (!__privateGet$1(this, _isDragging)) return;
90895
+ if (typeof __privateGet$1(this, _viewportHost).hasPointerCapture === "function" && typeof __privateGet$1(this, _viewportHost).releasePointerCapture === "function" && __privateGet$1(this, _viewportHost).hasPointerCapture(event.pointerId)) {
90896
+ __privateGet$1(this, _viewportHost).releasePointerCapture(event.pointerId);
90897
+ }
90898
+ __privateSet(this, _isDragging, false);
90899
+ });
90900
+ __privateAdd$1(this, _handleDragOver, (event) => {
90901
+ const activeEditor = this.getActiveEditor();
90902
+ if (!activeEditor?.isEditable) {
90903
+ return;
90904
+ }
90905
+ event.preventDefault();
90906
+ if (event.dataTransfer) {
90907
+ event.dataTransfer.dropEffect = "copy";
90908
+ }
90909
+ const dt = event.dataTransfer;
90910
+ const hasFieldAnnotation = dt?.types?.includes(FIELD_ANNOTATION_DATA_TYPE) || Boolean(dt?.getData?.(FIELD_ANNOTATION_DATA_TYPE));
90911
+ if (!hasFieldAnnotation) {
90912
+ return;
90913
+ }
90914
+ const hit = this.hitTest(event.clientX, event.clientY);
90915
+ const doc22 = activeEditor.state?.doc;
90916
+ if (!hit || !doc22) {
90917
+ return;
90918
+ }
90919
+ const pos = Math.min(Math.max(hit.pos, 1), doc22.content.size);
90920
+ const currentSelection = activeEditor.state.selection;
90921
+ const isSameCursor = currentSelection instanceof TextSelection$1 && currentSelection.from === pos && currentSelection.to === pos;
90922
+ if (isSameCursor) {
90923
+ return;
90924
+ }
90925
+ try {
90926
+ const tr = activeEditor.state.tr.setSelection(TextSelection$1.create(doc22, pos)).setMeta("addToHistory", false);
90927
+ activeEditor.view?.dispatch(tr);
90928
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
90929
+ } catch (error) {
90930
+ if (process$1$1.env.NODE_ENV === "development") {
90931
+ console.debug("[PresentationEditor] Drag position update skipped:", error);
90932
+ }
90933
+ }
90934
+ });
90935
+ __privateAdd$1(this, _handleDrop, (event) => {
90936
+ const activeEditor = this.getActiveEditor();
90937
+ if (!activeEditor?.isEditable) {
90938
+ return;
90939
+ }
90940
+ if (event.dataTransfer?.types?.includes("application/x-field-annotation")) {
90941
+ return;
90942
+ }
90943
+ event.preventDefault();
90944
+ event.stopPropagation();
90945
+ const fieldAnnotationData = event.dataTransfer?.getData(FIELD_ANNOTATION_DATA_TYPE);
90946
+ if (!fieldAnnotationData) {
90947
+ return;
90948
+ }
90949
+ const hit = this.hitTest(event.clientX, event.clientY);
90950
+ const selection = activeEditor.state?.selection;
90951
+ const fallbackPos = selection?.from ?? activeEditor.state?.doc?.content.size ?? null;
90952
+ const pos = hit?.pos ?? fallbackPos;
90953
+ if (pos == null) {
90954
+ return;
90955
+ }
90956
+ let parsedData = null;
90957
+ try {
90958
+ parsedData = JSON.parse(fieldAnnotationData);
90959
+ } catch {
90960
+ return;
90961
+ }
90962
+ const { attributes, sourceField } = parsedData ?? {};
90963
+ activeEditor.emit?.("fieldAnnotationDropped", {
90964
+ sourceField,
90965
+ editor: activeEditor,
90966
+ coordinates: hit,
90967
+ pos
90968
+ });
90969
+ if (attributes && isValidFieldAnnotationAttributes(attributes)) {
90970
+ activeEditor.commands?.addFieldAnnotation?.(pos, attributes, true);
90971
+ const posAfter = Math.min(pos + 1, activeEditor.state?.doc?.content.size ?? pos + 1);
90972
+ const tr = activeEditor.state?.tr.setSelection(TextSelection$1.create(activeEditor.state.doc, posAfter));
90973
+ if (tr) {
90974
+ activeEditor.view?.dispatch(tr);
90975
+ }
90976
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
90977
+ }
90978
+ const editorDom = activeEditor.view?.dom;
90979
+ if (editorDom) {
90980
+ editorDom.focus();
90981
+ activeEditor.view?.focus();
90982
+ }
90983
+ });
89498
90984
  __privateAdd$1(this, _handleDoubleClick, (event) => {
89499
90985
  if (event.button !== 0) return;
89500
90986
  if (!__privateGet$1(this, _layoutState).layout) return;
@@ -89684,6 +91170,7 @@ ${l}
89684
91170
  __privateMethod$1(this, _PresentationEditor_instances, applyZoom_fn).call(this);
89685
91171
  __privateMethod$1(this, _PresentationEditor_instances, setupEditorListeners_fn).call(this);
89686
91172
  __privateMethod$1(this, _PresentationEditor_instances, setupPointerHandlers_fn).call(this);
91173
+ __privateMethod$1(this, _PresentationEditor_instances, setupDragHandlers_fn).call(this);
89687
91174
  __privateMethod$1(this, _PresentationEditor_instances, setupInputBridge_fn).call(this);
89688
91175
  __privateMethod$1(this, _PresentationEditor_instances, syncTrackedChangesPreferences_fn).call(this);
89689
91176
  if (options.documentId) {
@@ -90395,6 +91882,7 @@ ${l}
90395
91882
  * Safe to call during partial initialization.
90396
91883
  */
90397
91884
  destroy() {
91885
+ var _a2;
90398
91886
  if (__privateGet$1(this, _rafHandle) != null) {
90399
91887
  __privateMethod$1(this, _PresentationEditor_instances, safeCleanup_fn).call(this, () => {
90400
91888
  const win = __privateGet$1(this, _visibleHost)?.ownerDocument?.defaultView ?? window;
@@ -90414,7 +91902,10 @@ ${l}
90414
91902
  __privateGet$1(this, _viewportHost)?.removeEventListener("pointerdown", __privateGet$1(this, _handlePointerDown));
90415
91903
  __privateGet$1(this, _viewportHost)?.removeEventListener("dblclick", __privateGet$1(this, _handleDoubleClick));
90416
91904
  __privateGet$1(this, _viewportHost)?.removeEventListener("pointermove", __privateGet$1(this, _handlePointerMove));
91905
+ __privateGet$1(this, _viewportHost)?.removeEventListener("pointerup", __privateGet$1(this, _handlePointerUp));
90417
91906
  __privateGet$1(this, _viewportHost)?.removeEventListener("pointerleave", __privateGet$1(this, _handlePointerLeave));
91907
+ __privateGet$1(this, _viewportHost)?.removeEventListener("dragover", __privateGet$1(this, _handleDragOver));
91908
+ __privateGet$1(this, _viewportHost)?.removeEventListener("drop", __privateGet$1(this, _handleDrop));
90418
91909
  __privateGet$1(this, _visibleHost)?.removeEventListener("keydown", __privateGet$1(this, _handleKeyDown));
90419
91910
  __privateGet$1(this, _inputBridge)?.notifyTargetChanged();
90420
91911
  __privateGet$1(this, _inputBridge)?.destroy();
@@ -90453,6 +91944,8 @@ ${l}
90453
91944
  __privateSet(this, _session, { mode: "body" });
90454
91945
  __privateSet(this, _activeHeaderFooterEditor, null);
90455
91946
  __privateSet(this, _domPainter, null);
91947
+ (_a2 = __privateGet$1(this, _dragHandlerCleanup)) == null ? void 0 : _a2.call(this);
91948
+ __privateSet(this, _dragHandlerCleanup, null);
90456
91949
  __privateGet$1(this, _selectionOverlay2)?.remove();
90457
91950
  __privateGet$1(this, _painterHost)?.remove();
90458
91951
  __privateGet$1(this, _hiddenHost)?.remove();
@@ -90480,6 +91973,7 @@ ${l}
90480
91973
  _layoutOptions = /* @__PURE__ */ new WeakMap();
90481
91974
  _layoutState = /* @__PURE__ */ new WeakMap();
90482
91975
  _domPainter = /* @__PURE__ */ new WeakMap();
91976
+ _dragHandlerCleanup = /* @__PURE__ */ new WeakMap();
90483
91977
  _layoutError = /* @__PURE__ */ new WeakMap();
90484
91978
  _layoutErrorState = /* @__PURE__ */ new WeakMap();
90485
91979
  _errorBanner = /* @__PURE__ */ new WeakMap();
@@ -90523,6 +92017,9 @@ ${l}
90523
92017
  _lastClickTime = /* @__PURE__ */ new WeakMap();
90524
92018
  _lastClickPosition = /* @__PURE__ */ new WeakMap();
90525
92019
  _lastSelectedImageBlockId = /* @__PURE__ */ new WeakMap();
92020
+ _dragAnchor = /* @__PURE__ */ new WeakMap();
92021
+ _isDragging = /* @__PURE__ */ new WeakMap();
92022
+ _dragExtensionMode = /* @__PURE__ */ new WeakMap();
90526
92023
  _remoteCursorState = /* @__PURE__ */ new WeakMap();
90527
92024
  _remoteCursorDirty = /* @__PURE__ */ new WeakMap();
90528
92025
  _remoteCursorOverlay = /* @__PURE__ */ new WeakMap();
@@ -90858,9 +92355,101 @@ ${l}
90858
92355
  __privateGet$1(this, _viewportHost).addEventListener("pointerdown", __privateGet$1(this, _handlePointerDown));
90859
92356
  __privateGet$1(this, _viewportHost).addEventListener("dblclick", __privateGet$1(this, _handleDoubleClick));
90860
92357
  __privateGet$1(this, _viewportHost).addEventListener("pointermove", __privateGet$1(this, _handlePointerMove));
92358
+ __privateGet$1(this, _viewportHost).addEventListener("pointerup", __privateGet$1(this, _handlePointerUp));
90861
92359
  __privateGet$1(this, _viewportHost).addEventListener("pointerleave", __privateGet$1(this, _handlePointerLeave));
92360
+ __privateGet$1(this, _viewportHost).addEventListener("dragover", __privateGet$1(this, _handleDragOver));
92361
+ __privateGet$1(this, _viewportHost).addEventListener("drop", __privateGet$1(this, _handleDrop));
90862
92362
  __privateGet$1(this, _visibleHost).addEventListener("keydown", __privateGet$1(this, _handleKeyDown));
90863
92363
  };
92364
+ setupDragHandlers_fn = function() {
92365
+ var _a2;
92366
+ (_a2 = __privateGet$1(this, _dragHandlerCleanup)) == null ? void 0 : _a2.call(this);
92367
+ __privateSet(this, _dragHandlerCleanup, null);
92368
+ __privateSet(this, _dragHandlerCleanup, createDragHandler(__privateGet$1(this, _painterHost), {
92369
+ onDragOver: (event) => {
92370
+ if (!event.hasFieldAnnotation || event.event.clientX === 0) {
92371
+ return;
92372
+ }
92373
+ const activeEditor = this.getActiveEditor();
92374
+ if (!activeEditor?.isEditable) {
92375
+ return;
92376
+ }
92377
+ const hit = this.hitTest(event.clientX, event.clientY);
92378
+ const doc2 = activeEditor.state?.doc;
92379
+ if (!hit || !doc2) {
92380
+ return;
92381
+ }
92382
+ const pos = Math.min(Math.max(hit.pos, 1), doc2.content.size);
92383
+ const currentSelection = activeEditor.state.selection;
92384
+ if (currentSelection instanceof TextSelection$1 && currentSelection.from === pos && currentSelection.to === pos) {
92385
+ return;
92386
+ }
92387
+ try {
92388
+ const tr = activeEditor.state.tr.setSelection(TextSelection$1.create(doc2, pos)).setMeta("addToHistory", false);
92389
+ activeEditor.view?.dispatch(tr);
92390
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
92391
+ } catch {
92392
+ }
92393
+ },
92394
+ onDrop: (event) => {
92395
+ event.event.preventDefault();
92396
+ event.event.stopPropagation();
92397
+ if (event.pmPosition === null) {
92398
+ return;
92399
+ }
92400
+ const activeEditor = this.getActiveEditor();
92401
+ const { state: state2, view } = activeEditor;
92402
+ if (!state2 || !view) {
92403
+ return;
92404
+ }
92405
+ const fieldId = event.data.fieldId;
92406
+ if (fieldId) {
92407
+ const targetPos = event.pmPosition;
92408
+ let sourceStart = null;
92409
+ let sourceEnd = null;
92410
+ let sourceNode = null;
92411
+ state2.doc.descendants((node2, pos) => {
92412
+ if (node2.type.name === "fieldAnnotation" && node2.attrs.fieldId === fieldId) {
92413
+ sourceStart = pos;
92414
+ sourceEnd = pos + node2.nodeSize;
92415
+ sourceNode = node2;
92416
+ return false;
92417
+ }
92418
+ return true;
92419
+ });
92420
+ if (sourceStart === null || sourceEnd === null || !sourceNode) {
92421
+ return;
92422
+ }
92423
+ if (targetPos >= sourceStart && targetPos <= sourceEnd) {
92424
+ return;
92425
+ }
92426
+ const tr = state2.tr;
92427
+ tr.delete(sourceStart, sourceEnd);
92428
+ const mappedTarget = tr.mapping.map(targetPos);
92429
+ if (mappedTarget < 0 || mappedTarget > tr.doc.content.size) {
92430
+ return;
92431
+ }
92432
+ tr.insert(mappedTarget, sourceNode);
92433
+ tr.setMeta("uiEvent", "drop");
92434
+ view.dispatch(tr);
92435
+ return;
92436
+ }
92437
+ const attrs = event.data.attributes;
92438
+ if (attrs && isValidFieldAnnotationAttributes(attrs)) {
92439
+ const inserted = activeEditor.commands?.addFieldAnnotation?.(event.pmPosition, attrs, true);
92440
+ if (inserted) {
92441
+ __privateMethod$1(this, _PresentationEditor_instances, scheduleSelectionUpdate_fn).call(this);
92442
+ }
92443
+ return;
92444
+ }
92445
+ activeEditor.emit("fieldAnnotationDropped", {
92446
+ sourceField: event.data,
92447
+ editor: activeEditor,
92448
+ coordinates: { pos: event.pmPosition }
92449
+ });
92450
+ }
92451
+ }));
92452
+ };
90864
92453
  setupInputBridge_fn = function() {
90865
92454
  __privateGet$1(this, _inputBridge)?.destroy();
90866
92455
  const win = __privateGet$1(this, _visibleHost).ownerDocument?.defaultView ?? window;
@@ -90937,8 +92526,11 @@ ${l}
90937
92526
  registerPointerClick_fn = function(event) {
90938
92527
  const MAX_CLICK_COUNT = 3;
90939
92528
  const time2 = event.timeStamp ?? performance.now();
90940
- const withinTime = time2 - __privateGet$1(this, _lastClickTime) <= MULTI_CLICK_TIME_THRESHOLD_MS;
90941
- const withinDistance = Math.abs(event.clientX - __privateGet$1(this, _lastClickPosition).x) <= MULTI_CLICK_DISTANCE_THRESHOLD_PX && Math.abs(event.clientY - __privateGet$1(this, _lastClickPosition).y) <= MULTI_CLICK_DISTANCE_THRESHOLD_PX;
92529
+ const timeDelta = time2 - __privateGet$1(this, _lastClickTime);
92530
+ const withinTime = timeDelta <= MULTI_CLICK_TIME_THRESHOLD_MS;
92531
+ const distanceX = Math.abs(event.clientX - __privateGet$1(this, _lastClickPosition).x);
92532
+ const distanceY = Math.abs(event.clientY - __privateGet$1(this, _lastClickPosition).y);
92533
+ const withinDistance = distanceX <= MULTI_CLICK_DISTANCE_THRESHOLD_PX && distanceY <= MULTI_CLICK_DISTANCE_THRESHOLD_PX;
90942
92534
  if (withinTime && withinDistance) {
90943
92535
  __privateSet(this, _clickCount, Math.min(__privateGet$1(this, _clickCount) + 1, MAX_CLICK_COUNT));
90944
92536
  } else {
@@ -90953,6 +92545,9 @@ ${l}
90953
92545
  if (!state2?.doc) {
90954
92546
  return false;
90955
92547
  }
92548
+ if (pos < 0 || pos > state2.doc.content.size) {
92549
+ return false;
92550
+ }
90956
92551
  const $pos = state2.doc.resolve(pos);
90957
92552
  let textblockPos = $pos;
90958
92553
  while (textblockPos.depth > 0) {
@@ -91039,6 +92634,30 @@ ${l}
91039
92634
  return false;
91040
92635
  }
91041
92636
  };
92637
+ calculateExtendedSelection_fn = function(anchor, head, mode) {
92638
+ if (mode === "word") {
92639
+ const anchorBounds = findWordBoundaries(__privateGet$1(this, _layoutState).blocks, anchor);
92640
+ const headBounds = findWordBoundaries(__privateGet$1(this, _layoutState).blocks, head);
92641
+ if (anchorBounds && headBounds) {
92642
+ if (head >= anchor) {
92643
+ return { selAnchor: anchorBounds.from, selHead: headBounds.to };
92644
+ } else {
92645
+ return { selAnchor: anchorBounds.to, selHead: headBounds.from };
92646
+ }
92647
+ }
92648
+ } else if (mode === "para") {
92649
+ const anchorBounds = findParagraphBoundaries(__privateGet$1(this, _layoutState).blocks, anchor);
92650
+ const headBounds = findParagraphBoundaries(__privateGet$1(this, _layoutState).blocks, head);
92651
+ if (anchorBounds && headBounds) {
92652
+ if (head >= anchor) {
92653
+ return { selAnchor: anchorBounds.from, selHead: headBounds.to };
92654
+ } else {
92655
+ return { selAnchor: anchorBounds.to, selHead: headBounds.from };
92656
+ }
92657
+ }
92658
+ }
92659
+ return { selAnchor: anchor, selHead: head };
92660
+ };
91042
92661
  isWordCharacter_fn = function(char) {
91043
92662
  if (!char) {
91044
92663
  return false;
@@ -91047,6 +92666,9 @@ ${l}
91047
92666
  };
91048
92667
  _handlePointerMove = /* @__PURE__ */ new WeakMap();
91049
92668
  _handlePointerLeave = /* @__PURE__ */ new WeakMap();
92669
+ _handlePointerUp = /* @__PURE__ */ new WeakMap();
92670
+ _handleDragOver = /* @__PURE__ */ new WeakMap();
92671
+ _handleDrop = /* @__PURE__ */ new WeakMap();
91050
92672
  _handleDoubleClick = /* @__PURE__ */ new WeakMap();
91051
92673
  _handleKeyDown = /* @__PURE__ */ new WeakMap();
91052
92674
  focusHeaderFooterShortcut_fn = function(kind) {
@@ -92219,10 +93841,12 @@ ${l}
92219
93841
  }
92220
93842
  const pageRect = pageEl.getBoundingClientRect();
92221
93843
  const overlayRect = __privateGet$1(this, _selectionOverlay2).getBoundingClientRect();
92222
- const zoom = __privateGet$1(this, _layoutOptions).zoom ?? 1;
93844
+ const layoutPageSize = __privateGet$1(this, _layoutState).layout?.pageSize;
93845
+ const scaleX = layoutPageSize && typeof layoutPageSize.w === "number" && layoutPageSize.w > 0 ? pageRect.width / layoutPageSize.w : 1;
93846
+ const scaleY = layoutPageSize && typeof layoutPageSize.h === "number" && layoutPageSize.h > 0 ? pageRect.height / layoutPageSize.h : 1;
92223
93847
  return {
92224
- x: pageRect.left - overlayRect.left + pageLocalX * zoom,
92225
- y: pageRect.top - overlayRect.top + pageLocalY * zoom
93848
+ x: pageRect.left - overlayRect.left + pageLocalX * scaleX,
93849
+ y: pageRect.top - overlayRect.top + pageLocalY * scaleY
92226
93850
  };
92227
93851
  };
92228
93852
  normalizeClientPoint_fn = function(clientX, clientY) {
@@ -145776,7 +147400,7 @@ ${style2}
145776
147400
  this.config.colors = shuffleArray(this.config.colors);
145777
147401
  this.userColorMap = /* @__PURE__ */ new Map();
145778
147402
  this.colorIndex = 0;
145779
- this.version = "1.0.0-beta.30";
147403
+ this.version = "1.0.0-beta.32";
145780
147404
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
145781
147405
  this.superdocId = config2.superdocId || v4();
145782
147406
  this.colors = this.config.colors;
@@ -148220,7 +149844,7 @@ ${style2}
148220
149844
  value && typeof value === "object" && "byteLength" in value && "byteOffset" in value
148221
149845
  );
148222
149846
  }
148223
- const indexDUzV7kkk = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
149847
+ const indexSGV4U12y = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
148224
149848
  __proto__: null,
148225
149849
  unified
148226
149850
  }, Symbol.toStringTag, { value: "Module" }));