superdoc 1.0.0-beta.99 → 1.0.0-next.1

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 (28) hide show
  1. package/dist/chunks/{PdfViewer-DF-v5Yrr.es.js → PdfViewer-BKujh9gl.es.js} +1 -1
  2. package/dist/chunks/{PdfViewer-BtuTHUW7.cjs → PdfViewer-Cu04k0JZ.cjs} +1 -1
  3. package/dist/chunks/{index-BBu9BBvp.cjs → index-CZ4149Px.cjs} +3 -3
  4. package/dist/chunks/{index-CJy3FxL7.es.js → index-Cl0tjE1C.es.js} +3 -3
  5. package/dist/chunks/{index-BB0msI45-DUPBw4Bh.es.js → index-Dlj3l0Hk-BuYH_UIe.es.js} +1 -1
  6. package/dist/chunks/{index-BB0msI45-CPU6Ak2R.cjs → index-Dlj3l0Hk-CJ0YBOja.cjs} +1 -1
  7. package/dist/chunks/{super-editor.es-C04sFzVD.cjs → super-editor.es-CjRtsxTt.cjs} +973 -178
  8. package/dist/chunks/{super-editor.es-BiaFIbw-.es.js → super-editor.es-D0WByw5h.es.js} +973 -178
  9. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  10. package/dist/super-editor/ai-writer.es.js +2 -2
  11. package/dist/super-editor/chunks/{converter-B_cVJPnh.js → converter-BS4FD8AG.js} +12 -6
  12. package/dist/super-editor/chunks/{docx-zipper-fPWx7kV0.js → docx-zipper-DpiCpt0d.js} +1 -1
  13. package/dist/super-editor/chunks/{editor-DS9z42Je.js → editor-BeacbTQe.js} +963 -170
  14. package/dist/super-editor/chunks/{index-BB0msI45.js → index-Dlj3l0Hk.js} +1 -1
  15. package/dist/super-editor/chunks/{toolbar-aIFlIr6h.js → toolbar-BNQDvBCn.js} +2 -2
  16. package/dist/super-editor/converter.es.js +1 -1
  17. package/dist/super-editor/docx-zipper.es.js +2 -2
  18. package/dist/super-editor/editor.es.js +3 -3
  19. package/dist/super-editor/file-zipper.es.js +1 -1
  20. package/dist/super-editor/super-editor.es.js +10 -10
  21. package/dist/super-editor/toolbar.es.js +2 -2
  22. package/dist/super-editor.cjs +1 -1
  23. package/dist/super-editor.es.js +1 -1
  24. package/dist/superdoc.cjs +2 -2
  25. package/dist/superdoc.es.js +2 -2
  26. package/dist/superdoc.umd.js +975 -180
  27. package/dist/superdoc.umd.js.map +1 -1
  28. package/package.json +10 -1
@@ -39775,7 +39775,7 @@ function importCommentData({ docx, editor, converter }) {
39775
39775
  const trackedDeletedText = attributes["custom:trackedDeletedText"] !== "null" ? attributes["custom:trackedDeletedText"] : null;
39776
39776
  const date = new Date(createdDate);
39777
39777
  const unixTimestampMs = date.getTime();
39778
- const parsedComment = nodeListHandler.handler({
39778
+ const parsedElements = nodeListHandler.handler({
39779
39779
  nodes: el.elements,
39780
39780
  nodeListHandler,
39781
39781
  docx,
@@ -39783,7 +39783,7 @@ function importCommentData({ docx, editor, converter }) {
39783
39783
  converter,
39784
39784
  path: [el]
39785
39785
  });
39786
- const { attrs } = parsedComment[0];
39786
+ const { attrs } = parsedElements[0];
39787
39787
  const paraId = attrs["w14:paraId"];
39788
39788
  return {
39789
39789
  commentId: internalId || v4(),
@@ -39791,7 +39791,8 @@ function importCommentData({ docx, editor, converter }) {
39791
39791
  creatorName: authorName,
39792
39792
  creatorEmail: authorEmail,
39793
39793
  createdTime: unixTimestampMs,
39794
- textJson: parsedComment[0],
39794
+ textJson: parsedElements[0],
39795
+ elements: parsedElements,
39795
39796
  initials,
39796
39797
  paraId,
39797
39798
  trackedChange,
@@ -39817,7 +39818,12 @@ const generateCommentsWithExtendedData = ({ docx, comments }) => {
39817
39818
  const { elements = [] } = initialElements[0] ?? {};
39818
39819
  const commentEx = elements.filter((el) => el.name === "w15:commentEx");
39819
39820
  return comments.map((comment) => {
39820
- const extendedDef = commentEx.find((ce2) => ce2.attributes["w15:paraId"] === comment.paraId);
39821
+ const extendedDef = commentEx.find((ce2) => {
39822
+ const isIncludedInCommentElements = comment.elements?.some(
39823
+ (el) => el.attrs?.["w14:paraId"] === ce2.attributes["w15:paraId"]
39824
+ );
39825
+ return isIncludedInCommentElements;
39826
+ });
39821
39827
  if (!extendedDef) return { ...comment, isDone: comment.isDone ?? false };
39822
39828
  const { isDone, paraIdParent } = getExtendedDetails(extendedDef);
39823
39829
  let parentComment;
@@ -41938,7 +41944,7 @@ const updateCommentsIdsAndExtensible = (comments = [], commentsIds, extensible)
41938
41944
  name: "w16cex:commentExtensible",
41939
41945
  attributes: {
41940
41946
  "w16cex:durableId": newDurableId,
41941
- "w16cex:dateUtc": toIsoNoFractional()
41947
+ "w16cex:dateUtc": toIsoNoFractional(comment.createdTime)
41942
41948
  }
41943
41949
  };
41944
41950
  extensibleUpdated.elements[0].elements.push(newExtensible);
@@ -42404,7 +42410,7 @@ const _SuperConverter = class _SuperConverter2 {
42404
42410
  static getStoredSuperdocVersion(docx) {
42405
42411
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
42406
42412
  }
42407
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.99") {
42413
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-next.1") {
42408
42414
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
42409
42415
  }
42410
42416
  /**
@@ -45716,7 +45722,7 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
45716
45722
  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);
45717
45723
  var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
45718
45724
  var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
45719
- 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, _cellAnchor, _cellDragMode, _remoteCursorState, _remoteCursorElements, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _scrollTimeout, _lastRemoteCursorRenderTime, _remoteCursorThrottleTimeout, _PresentationEditor_instances, collectCommentPositions_fn, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, updateLocalAwarenessCursor_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, focusEditorAfterImageSelection_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, getCellPosFromTableHit_fn, getTablePosFromHit_fn, shouldUseCellSelection_fn, setCellAnchor_fn, clearCellAnchor_fn, hitTestTable_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, computeExpectedSectionType_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, computeAnchorMap_fn, waitForPageMount_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, applyDomCorrectionToRects_fn, renderCellSelectionOverlay_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, getPageOffsetX_fn, convertPageLocalToOverlayCoords_fn, computeDomCaretPageLocal_fn, normalizeClientPoint_fn, computeCaretLayoutRectGeometry_fn, computeCaretLayoutRect_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;
45725
+ 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, _pageGeometryHelper, _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, _cellAnchor, _cellDragMode, _remoteCursorState, _remoteCursorElements, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _scrollTimeout, _lastRemoteCursorRenderTime, _remoteCursorThrottleTimeout, _PresentationEditor_instances, collectCommentPositions_fn, aggregateLayoutBounds_fn, safeCleanup_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, updateLocalAwarenessCursor_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, focusEditorAfterImageSelection_fn, setupInputBridge_fn, initHeaderFooterRegistry_fn, _handlePointerDown, getFirstTextPosition_fn, registerPointerClick_fn, getCellPosFromTableHit_fn, getTablePosFromHit_fn, shouldUseCellSelection_fn, setCellAnchor_fn, clearCellAnchor_fn, hitTestTable_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, computeExpectedSectionType_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, computeAnchorMap_fn, waitForPageMount_fn, getEffectivePageGap_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, applyDomCorrectionToRects_fn, renderCellSelectionOverlay_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, getPageOffsetX_fn, convertPageLocalToOverlayCoords_fn, computeDomCaretPageLocal_fn, normalizeClientPoint_fn, computeCaretLayoutRectGeometry_fn, computeCaretLayoutRect_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;
45720
45726
  var GOOD_LEAF_SIZE = 200;
45721
45727
  var RopeSequence = function RopeSequence2() {
45722
45728
  };
@@ -54800,6 +54806,14 @@ const toggleNode = (typeOrName, toggleTypeOrName, attrs = {}) => ({ state: state
54800
54806
  const selectAll = () => ({ state: state2, dispatch }) => selectAll$1(state2, dispatch);
54801
54807
  const deleteSelection = () => ({ state: state2, tr, dispatch }) => {
54802
54808
  const { from: from2, to, empty: empty2 } = state2.selection;
54809
+ if (typeof document !== "undefined" && document.getSelection) {
54810
+ const currentDomSelection = document.getSelection();
54811
+ const selectedLength = currentDomSelection?.toString?.().length;
54812
+ const isCollapsed = currentDomSelection?.isCollapsed;
54813
+ if (!isCollapsed && selectedLength === 1) {
54814
+ return false;
54815
+ }
54816
+ }
54803
54817
  if (empty2) {
54804
54818
  return deleteSelection$1(state2, dispatch);
54805
54819
  }
@@ -57099,12 +57113,14 @@ const prepareCommentsForImport = (doc2, tr, schema, converter) => {
57099
57113
  importedId: node.attrs["w:id"]
57100
57114
  });
57101
57115
  if (type2.name === "commentRangeStart") {
57102
- toMark.push({
57103
- commentId: resolvedCommentId,
57104
- importedId,
57105
- internal,
57106
- start: pos
57107
- });
57116
+ if (!matchingImportedComment?.isDone) {
57117
+ toMark.push({
57118
+ commentId: resolvedCommentId,
57119
+ importedId,
57120
+ internal,
57121
+ start: pos
57122
+ });
57123
+ }
57108
57124
  ensureFallbackComment({
57109
57125
  converter,
57110
57126
  matchingImportedComment,
@@ -59622,7 +59638,7 @@ const isHeadless = (editor) => {
59622
59638
  const shouldSkipNodeView = (editor) => {
59623
59639
  return isHeadless(editor);
59624
59640
  };
59625
- const summaryVersion = "1.0.0-beta.99";
59641
+ const summaryVersion = "1.0.0-next.1";
59626
59642
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
59627
59643
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
59628
59644
  function mapAttributes(attrs) {
@@ -59982,11 +59998,11 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
59982
59998
  if (!this.options.isNewFile || !this.options.collaborationProvider) return;
59983
59999
  const provider = this.options.collaborationProvider;
59984
60000
  const postSyncInit = () => {
59985
- provider.off("synced", postSyncInit);
60001
+ provider.off?.("synced", postSyncInit);
59986
60002
  __privateMethod$1(this, _Editor_instances, insertNewFileData_fn).call(this);
59987
60003
  };
59988
60004
  if (provider.synced) __privateMethod$1(this, _Editor_instances, insertNewFileData_fn).call(this);
59989
- else provider.on("synced", postSyncInit);
60005
+ else provider.on?.("synced", postSyncInit);
59990
60006
  }
59991
60007
  /**
59992
60008
  * Replace content of editor that was created with loadFromSchema option
@@ -60411,7 +60427,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60411
60427
  { default: remarkStringify },
60412
60428
  { default: remarkGfm }
60413
60429
  ] = await Promise.all([
60414
- import("./index-BB0msI45-DUPBw4Bh.es.js"),
60430
+ import("./index-Dlj3l0Hk-BuYH_UIe.es.js"),
60415
60431
  import("./index-DRCvimau-Cw339678.es.js"),
60416
60432
  import("./index-C_x_N6Uh-DJn8hIEt.es.js"),
60417
60433
  import("./index-D_sWOSiG-DE96TaT5.es.js"),
@@ -60616,7 +60632,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60616
60632
  * Process collaboration migrations
60617
60633
  */
60618
60634
  processCollaborationMigrations() {
60619
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.99");
60635
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-next.1");
60620
60636
  if (!this.options.ydoc) return;
60621
60637
  const metaMap = this.options.ydoc.getMap("meta");
60622
60638
  let docVersion = metaMap.get("version");
@@ -63731,6 +63747,7 @@ function hydrateImageBlocks(blocks, mediaFiles) {
63731
63747
  if (cellChanged) {
63732
63748
  return {
63733
63749
  ...cell,
63750
+ // Cast to expected type - hydrateBlock preserves block kinds, just hydrates image sources
63734
63751
  blocks: hydratedBlocks.length > 0 ? hydratedBlocks : cell.blocks,
63735
63752
  paragraph: hydratedParagraph
63736
63753
  };
@@ -67351,7 +67368,7 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
67351
67368
  };
67352
67369
  }
67353
67370
  const hasValidNumbering = rawNumberingProps && isValidNumberingId(rawNumberingProps.numId);
67354
- if (hasValidNumbering) {
67371
+ if (hasValidNumbering && rawNumberingProps) {
67355
67372
  const numberingProps = rawNumberingProps;
67356
67373
  const numId = numberingProps.numId;
67357
67374
  const ilvl = Number.isFinite(numberingProps.ilvl) ? Math.max(0, Math.floor(Number(numberingProps.ilvl))) : 0;
@@ -67391,6 +67408,8 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
67391
67408
  const resolvedCounterValue = path[path.length - 1] ?? counterValue;
67392
67409
  const enrichedNumberingProps = {
67393
67410
  ...numberingProps,
67411
+ numId: numberingProps.numId,
67412
+ ilvl: numberingProps.ilvl,
67394
67413
  path,
67395
67414
  counterValue: resolvedCounterValue
67396
67415
  };
@@ -69487,7 +69506,7 @@ const parseTableCell = (args) => {
69487
69506
  context.nextBlockId,
69488
69507
  context.positions
69489
69508
  );
69490
- if (drawingBlock) {
69509
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69491
69510
  blocks.push(drawingBlock);
69492
69511
  }
69493
69512
  continue;
@@ -69498,7 +69517,7 @@ const parseTableCell = (args) => {
69498
69517
  context.nextBlockId,
69499
69518
  context.positions
69500
69519
  );
69501
- if (drawingBlock) {
69520
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69502
69521
  blocks.push(drawingBlock);
69503
69522
  }
69504
69523
  continue;
@@ -69509,7 +69528,7 @@ const parseTableCell = (args) => {
69509
69528
  context.nextBlockId,
69510
69529
  context.positions
69511
69530
  );
69512
- if (drawingBlock) {
69531
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69513
69532
  blocks.push(drawingBlock);
69514
69533
  }
69515
69534
  continue;
@@ -69520,7 +69539,7 @@ const parseTableCell = (args) => {
69520
69539
  context.nextBlockId,
69521
69540
  context.positions
69522
69541
  );
69523
- if (drawingBlock) {
69542
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69524
69543
  blocks.push(drawingBlock);
69525
69544
  }
69526
69545
  }
@@ -69975,7 +69994,19 @@ function toFlowBlocks(pmDoc, options) {
69975
69994
  bookmarks2,
69976
69995
  hyperlinkConfig2,
69977
69996
  themeColorsParam ?? themeColors,
69978
- paragraphConverter
69997
+ paragraphConverter,
69998
+ converterCtx ?? converterContext,
69999
+ {
70000
+ listCounterContext: { getListCounter, incrementListCounter, resetListCounter },
70001
+ converters: {
70002
+ paragraphToFlowBlocks: paragraphConverter,
70003
+ imageNodeToBlock,
70004
+ vectorShapeNodeToDrawingBlock,
70005
+ shapeGroupNodeToDrawingBlock,
70006
+ shapeContainerNodeToDrawingBlock,
70007
+ shapeTextboxNodeToDrawingBlock
70008
+ }
70009
+ }
69979
70010
  );
69980
70011
  const handlerContext = {
69981
70012
  blocks,
@@ -69996,6 +70027,7 @@ function toFlowBlocks(pmDoc, options) {
69996
70027
  currentParagraphIndex: 0
69997
70028
  },
69998
70029
  converters: {
70030
+ // Type assertion needed due to signature mismatch between actual function and type definition
69999
70031
  paragraphToFlowBlocks: paragraphConverter,
70000
70032
  tableNodeToBlock: tableConverter,
70001
70033
  imageNodeToBlock,
@@ -70091,6 +70123,7 @@ function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaul
70091
70123
  {
70092
70124
  listCounterContext,
70093
70125
  converters: {
70126
+ // Type assertion needed due to signature mismatch between actual function and type definition
70094
70127
  paragraphToFlowBlocks: paragraphToFlowBlocks$1,
70095
70128
  imageNodeToBlock,
70096
70129
  vectorShapeNodeToDrawingBlock,
@@ -70104,7 +70137,7 @@ function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaul
70104
70137
  converterContext
70105
70138
  );
70106
70139
  }
70107
- function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize, styleContext, trackedChanges, bookmarks, hyperlinkConfig, themeColors, converterContext) {
70140
+ function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize, styleContext, trackedChanges, bookmarks, hyperlinkConfig, themeColors, _paragraphToFlowBlocksParam, converterContext, options) {
70108
70141
  return tableNodeToBlock$1(
70109
70142
  node,
70110
70143
  nextBlockId,
@@ -70118,8 +70151,9 @@ function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize
70118
70151
  themeColors,
70119
70152
  paragraphToFlowBlocks,
70120
70153
  converterContext,
70121
- {
70154
+ options ?? {
70122
70155
  converters: {
70156
+ // Type assertion needed due to signature mismatch between actual function and type definition
70123
70157
  paragraphToFlowBlocks: paragraphToFlowBlocks$1,
70124
70158
  imageNodeToBlock,
70125
70159
  vectorShapeNodeToDrawingBlock,
@@ -72699,7 +72733,7 @@ const containerStyles = {
72699
72733
  alignItems: "center",
72700
72734
  background: "transparent",
72701
72735
  padding: "0",
72702
- gap: "24px",
72736
+ // gap is set dynamically by renderer based on pageGap option (default: 24px)
72703
72737
  overflowY: "auto"
72704
72738
  };
72705
72739
  const containerStylesHorizontal = {
@@ -72709,7 +72743,7 @@ const containerStylesHorizontal = {
72709
72743
  justifyContent: "safe center",
72710
72744
  background: "transparent",
72711
72745
  padding: "0",
72712
- gap: "20px",
72746
+ // gap is set dynamically by renderer based on pageGap option (default: 20px for horizontal)
72713
72747
  overflowX: "auto",
72714
72748
  minHeight: "100%"
72715
72749
  };
@@ -74423,6 +74457,49 @@ const hashParagraphBorders$1 = (borders) => {
74423
74457
  if (borders.left) parts.push(`l:[${hashParagraphBorder$1(borders.left)}]`);
74424
74458
  return parts.join(";");
74425
74459
  };
74460
+ const isNoneBorder$1 = (value) => {
74461
+ return typeof value === "object" && value !== null && "none" in value && value.none === true;
74462
+ };
74463
+ const isBorderSpec$1 = (value) => {
74464
+ return typeof value === "object" && value !== null && !("none" in value);
74465
+ };
74466
+ const hashBorderSpec$1 = (border) => {
74467
+ const parts = [];
74468
+ if (border.style !== void 0) parts.push(`s:${border.style}`);
74469
+ if (border.width !== void 0) parts.push(`w:${border.width}`);
74470
+ if (border.color !== void 0) parts.push(`c:${border.color}`);
74471
+ if (border.space !== void 0) parts.push(`sp:${border.space}`);
74472
+ return parts.join(",");
74473
+ };
74474
+ const hashTableBorderValue$1 = (borderValue) => {
74475
+ if (borderValue === void 0) return "";
74476
+ if (borderValue === null) return "null";
74477
+ if (isNoneBorder$1(borderValue)) return "none";
74478
+ if (isBorderSpec$1(borderValue)) {
74479
+ return hashBorderSpec$1(borderValue);
74480
+ }
74481
+ return "";
74482
+ };
74483
+ const hashTableBorders$1 = (borders) => {
74484
+ if (!borders) return "";
74485
+ const parts = [];
74486
+ if (borders.top !== void 0) parts.push(`t:[${hashTableBorderValue$1(borders.top)}]`);
74487
+ if (borders.right !== void 0) parts.push(`r:[${hashTableBorderValue$1(borders.right)}]`);
74488
+ if (borders.bottom !== void 0) parts.push(`b:[${hashTableBorderValue$1(borders.bottom)}]`);
74489
+ if (borders.left !== void 0) parts.push(`l:[${hashTableBorderValue$1(borders.left)}]`);
74490
+ if (borders.insideH !== void 0) parts.push(`ih:[${hashTableBorderValue$1(borders.insideH)}]`);
74491
+ if (borders.insideV !== void 0) parts.push(`iv:[${hashTableBorderValue$1(borders.insideV)}]`);
74492
+ return parts.join(";");
74493
+ };
74494
+ const hashCellBorders$1 = (borders) => {
74495
+ if (!borders) return "";
74496
+ const parts = [];
74497
+ if (borders.top) parts.push(`t:[${hashBorderSpec$1(borders.top)}]`);
74498
+ if (borders.right) parts.push(`r:[${hashBorderSpec$1(borders.right)}]`);
74499
+ if (borders.bottom) parts.push(`b:[${hashBorderSpec$1(borders.bottom)}]`);
74500
+ if (borders.left) parts.push(`l:[${hashBorderSpec$1(borders.left)}]`);
74501
+ return parts.join(";");
74502
+ };
74426
74503
  const hasStringProp = (run2, prop) => {
74427
74504
  return prop in run2 && typeof run2[prop] === "string";
74428
74505
  };
@@ -74512,6 +74589,7 @@ function isMinimalWordLayout(value) {
74512
74589
  const LIST_MARKER_GAP$1 = 8;
74513
74590
  const DEFAULT_TAB_INTERVAL_PX$1 = 48;
74514
74591
  const DEFAULT_PAGE_HEIGHT_PX = 1056;
74592
+ const DEFAULT_VIRTUALIZED_PAGE_GAP$1 = 72;
74515
74593
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
74516
74594
  const COMMENT_INTERNAL_COLOR = "#078383";
74517
74595
  const COMMENT_INACTIVE_ALPHA = "22";
@@ -74641,10 +74719,11 @@ const _DomPainter = class _DomPainter2 {
74641
74719
  this.totalPages = 0;
74642
74720
  this.linkIdCounter = 0;
74643
74721
  this.pendingTooltips = /* @__PURE__ */ new WeakMap();
74722
+ this.pageGap = 24;
74644
74723
  this.virtualEnabled = false;
74645
74724
  this.virtualWindow = 5;
74646
74725
  this.virtualOverscan = 0;
74647
- this.virtualGap = 72;
74726
+ this.virtualGap = DEFAULT_VIRTUALIZED_PAGE_GAP$1;
74648
74727
  this.virtualPaddingTop = null;
74649
74728
  this.topSpacerEl = null;
74650
74729
  this.bottomSpacerEl = null;
@@ -74663,13 +74742,14 @@ const _DomPainter = class _DomPainter2 {
74663
74742
  this.blockLookup = this.buildBlockLookup(blocks, measures);
74664
74743
  this.headerProvider = options.headerProvider;
74665
74744
  this.footerProvider = options.footerProvider;
74745
+ const defaultGap = this.layoutMode === "horizontal" ? 20 : 24;
74746
+ this.pageGap = typeof options.pageGap === "number" && Number.isFinite(options.pageGap) ? Math.max(0, options.pageGap) : defaultGap;
74666
74747
  if (this.layoutMode === "vertical" && options.virtualization?.enabled) {
74667
74748
  this.virtualEnabled = true;
74668
74749
  this.virtualWindow = Math.max(1, options.virtualization.window ?? 5);
74669
74750
  this.virtualOverscan = Math.max(0, options.virtualization.overscan ?? 0);
74670
- if (typeof options.virtualization.gap === "number" && Number.isFinite(options.virtualization.gap)) {
74671
- this.virtualGap = Math.max(0, options.virtualization.gap);
74672
- }
74751
+ const hasExplicitVirtualGap = typeof options.virtualization.gap === "number" && Number.isFinite(options.virtualization.gap);
74752
+ this.virtualGap = hasExplicitVirtualGap ? Math.max(0, options.virtualization.gap) : DEFAULT_VIRTUALIZED_PAGE_GAP$1;
74673
74753
  if (typeof options.virtualization.paddingTop === "number" && Number.isFinite(options.virtualization.paddingTop)) {
74674
74754
  this.virtualPaddingTop = Math.max(0, options.virtualization.paddingTop);
74675
74755
  }
@@ -74770,6 +74850,7 @@ const _DomPainter = class _DomPainter2 {
74770
74850
  const mode = this.layoutMode;
74771
74851
  if (mode === "horizontal") {
74772
74852
  applyStyles$2(mount2, containerStylesHorizontal);
74853
+ mount2.style.gap = `${this.pageGap}px`;
74773
74854
  this.renderHorizontal(layout, mount2);
74774
74855
  this.currentLayout = layout;
74775
74856
  this.pageStates = [];
@@ -74792,6 +74873,7 @@ const _DomPainter = class _DomPainter2 {
74792
74873
  this.changedBlocks.clear();
74793
74874
  return;
74794
74875
  }
74876
+ mount2.style.gap = `${this.pageGap}px`;
74795
74877
  if (!this.currentLayout || this.pageStates.length === 0) {
74796
74878
  this.fullRender(layout);
74797
74879
  } else {
@@ -75116,9 +75198,15 @@ const _DomPainter = class _DomPainter2 {
75116
75198
  const container = existing ?? this.doc.createElement("div");
75117
75199
  container.className = className;
75118
75200
  container.innerHTML = "";
75119
- const offset2 = data.offset ?? (kind === "footer" ? pageEl.clientHeight - data.height : 0);
75201
+ const baseOffset = data.offset ?? (kind === "footer" ? pageEl.clientHeight - data.height : 0);
75120
75202
  const marginLeft = data.marginLeft ?? 0;
75121
75203
  const marginRight = page.margins?.right ?? 0;
75204
+ let effectiveHeight = data.height;
75205
+ let effectiveOffset = baseOffset;
75206
+ if (kind === "footer" && typeof data.contentHeight === "number" && Number.isFinite(data.contentHeight) && data.contentHeight > 0 && data.contentHeight > data.height) {
75207
+ effectiveHeight = data.contentHeight;
75208
+ effectiveOffset = baseOffset - (data.contentHeight - data.height);
75209
+ }
75122
75210
  container.style.position = "absolute";
75123
75211
  container.style.left = `${marginLeft}px`;
75124
75212
  if (typeof data.contentWidth === "number") {
@@ -75127,8 +75215,8 @@ const _DomPainter = class _DomPainter2 {
75127
75215
  container.style.width = `calc(100% - ${marginLeft + marginRight}px)`;
75128
75216
  }
75129
75217
  container.style.pointerEvents = "none";
75130
- container.style.height = `${data.height}px`;
75131
- container.style.top = `${Math.max(0, offset2)}px`;
75218
+ container.style.height = `${effectiveHeight}px`;
75219
+ container.style.top = `${Math.max(0, effectiveOffset)}px`;
75132
75220
  container.style.zIndex = "1";
75133
75221
  container.style.overflow = "visible";
75134
75222
  let footerYOffset = 0;
@@ -75137,7 +75225,7 @@ const _DomPainter = class _DomPainter2 {
75137
75225
  const fragHeight = "height" in f2 && typeof f2.height === "number" ? f2.height : this.estimateFragmentHeight(f2);
75138
75226
  return Math.max(max2, f2.y + Math.max(0, fragHeight));
75139
75227
  }, 0);
75140
- footerYOffset = Math.max(0, data.height - contentHeight);
75228
+ footerYOffset = Math.max(0, effectiveHeight - contentHeight);
75141
75229
  }
75142
75230
  const context = {
75143
75231
  pageNumber: page.number,
@@ -77627,6 +77715,25 @@ const deriveBlockVersion = (block) => {
77627
77715
  hash2 = hashNumber(hash2, cellBlocks.length);
77628
77716
  hash2 = hashNumber(hash2, cell.rowSpan ?? 1);
77629
77717
  hash2 = hashNumber(hash2, cell.colSpan ?? 1);
77718
+ if (cell.attrs) {
77719
+ const cellAttrs = cell.attrs;
77720
+ if (cellAttrs.borders) {
77721
+ hash2 = hashString(hash2, hashCellBorders$1(cellAttrs.borders));
77722
+ }
77723
+ if (cellAttrs.padding) {
77724
+ const p = cellAttrs.padding;
77725
+ hash2 = hashNumber(hash2, p.top ?? 0);
77726
+ hash2 = hashNumber(hash2, p.right ?? 0);
77727
+ hash2 = hashNumber(hash2, p.bottom ?? 0);
77728
+ hash2 = hashNumber(hash2, p.left ?? 0);
77729
+ }
77730
+ if (cellAttrs.verticalAlign) {
77731
+ hash2 = hashString(hash2, cellAttrs.verticalAlign);
77732
+ }
77733
+ if (cellAttrs.background) {
77734
+ hash2 = hashString(hash2, cellAttrs.background);
77735
+ }
77736
+ }
77630
77737
  for (const cellBlock of cellBlocks) {
77631
77738
  hash2 = hashString(hash2, cellBlock?.kind ?? "unknown");
77632
77739
  if (cellBlock?.kind === "paragraph") {
@@ -77672,6 +77779,18 @@ const deriveBlockVersion = (block) => {
77672
77779
  }
77673
77780
  }
77674
77781
  }
77782
+ if (tableBlock.attrs) {
77783
+ const tblAttrs = tableBlock.attrs;
77784
+ if (tblAttrs.borders) {
77785
+ hash2 = hashString(hash2, hashTableBorders$1(tblAttrs.borders));
77786
+ }
77787
+ if (tblAttrs.borderCollapse) {
77788
+ hash2 = hashString(hash2, tblAttrs.borderCollapse);
77789
+ }
77790
+ if (tblAttrs.cellSpacing !== void 0) {
77791
+ hash2 = hashNumber(hash2, tblAttrs.cellSpacing);
77792
+ }
77793
+ }
77675
77794
  return [block.id, tableBlock.rows.length, hash2.toString(16)].join("|");
77676
77795
  }
77677
77796
  return block.id;
@@ -78005,6 +78124,7 @@ const createDomPainter = (options) => {
78005
78124
  const painter = new DomPainter(options.blocks, options.measures, {
78006
78125
  pageStyles: options.pageStyles,
78007
78126
  layoutMode: options.layoutMode,
78127
+ pageGap: options.pageGap,
78008
78128
  headerProvider: options.headerProvider,
78009
78129
  footerProvider: options.footerProvider,
78010
78130
  virtualization: options.virtualization,
@@ -78423,7 +78543,7 @@ function isListItem(markerWidth, block) {
78423
78543
  return false;
78424
78544
  }
78425
78545
  const wordLayout = getWordLayoutConfig(block);
78426
- const hasListAttrs = block.attrs?.listItem != null || wordLayout?.marker != null;
78546
+ const hasListAttrs = block.attrs?.listItem != null || block.attrs?.numberingProperties != null || wordLayout?.marker != null;
78427
78547
  if (hasListAttrs) {
78428
78548
  return true;
78429
78549
  }
@@ -78853,7 +78973,7 @@ function computeNextSectionPropsAtBreak(blocks) {
78853
78973
  });
78854
78974
  return nextSectionPropsAtBreak;
78855
78975
  }
78856
- function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight = 0) {
78976
+ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight = 0, maxFooterContentHeight = 0) {
78857
78977
  const next = { ...state2 };
78858
78978
  const calcRequiredTopMargin = (headerDistance, baseTop) => {
78859
78979
  if (maxHeaderContentHeight > 0) {
@@ -78861,6 +78981,12 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78861
78981
  }
78862
78982
  return Math.max(baseTop, headerDistance);
78863
78983
  };
78984
+ const calcRequiredBottomMargin = (footerDistance, baseBottom) => {
78985
+ if (maxFooterContentHeight > 0) {
78986
+ return Math.max(baseBottom, footerDistance + maxFooterContentHeight);
78987
+ }
78988
+ return Math.max(baseBottom, footerDistance);
78989
+ };
78864
78990
  if (block.attrs?.isFirstSection && !next.hasAnyPages) {
78865
78991
  if (block.pageSize) {
78866
78992
  next.activePageSize = { w: block.pageSize.w, h: block.pageSize.h };
@@ -78881,7 +79007,7 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78881
79007
  const footerDistance = Math.max(0, block.margins.footer);
78882
79008
  next.activeFooterDistance = footerDistance;
78883
79009
  next.pendingFooterDistance = footerDistance;
78884
- next.activeBottomMargin = Math.max(baseMargins.bottom, footerDistance);
79010
+ next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, baseMargins.bottom);
78885
79011
  next.pendingBottomMargin = next.activeBottomMargin;
78886
79012
  }
78887
79013
  if (block.columns) {
@@ -78904,8 +79030,14 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78904
79030
  next.pendingTopMargin = nextTop;
78905
79031
  next.pendingHeaderDistance = nextHeader;
78906
79032
  }
78907
- next.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
78908
- next.pendingFooterDistance = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
79033
+ if (typeof footerPx === "number") {
79034
+ const newFooterDist = Math.max(0, footerPx);
79035
+ next.pendingFooterDistance = newFooterDist;
79036
+ next.pendingBottomMargin = calcRequiredBottomMargin(newFooterDist, baseMargins.bottom);
79037
+ } else {
79038
+ next.pendingBottomMargin = nextBottom;
79039
+ next.pendingFooterDistance = nextFooter;
79040
+ }
78909
79041
  if (block.pageSize) {
78910
79042
  next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
78911
79043
  }
@@ -80505,7 +80637,7 @@ function layoutDocument(blocks, measures, options = {}) {
80505
80637
  if (contentWidth <= 0) {
80506
80638
  throw new Error("layoutDocument: pageSize and margins yield non-positive content area");
80507
80639
  }
80508
- const validateHeaderHeight = (height) => {
80640
+ const validateContentHeight = (height) => {
80509
80641
  if (height === void 0) return 0;
80510
80642
  if (!Number.isFinite(height) || height < 0) return 0;
80511
80643
  return height;
@@ -80513,15 +80645,25 @@ function layoutDocument(blocks, measures, options = {}) {
80513
80645
  const headerContentHeights = options.headerContentHeights;
80514
80646
  const maxHeaderContentHeight = headerContentHeights ? Math.max(
80515
80647
  0,
80516
- validateHeaderHeight(headerContentHeights.default),
80517
- validateHeaderHeight(headerContentHeights.first),
80518
- validateHeaderHeight(headerContentHeights.even),
80519
- validateHeaderHeight(headerContentHeights.odd)
80648
+ validateContentHeight(headerContentHeights.default),
80649
+ validateContentHeight(headerContentHeights.first),
80650
+ validateContentHeight(headerContentHeights.even),
80651
+ validateContentHeight(headerContentHeights.odd)
80520
80652
  ) : 0;
80521
80653
  const headerDistance = margins.header ?? margins.top;
80522
80654
  const effectiveTopMargin = maxHeaderContentHeight > 0 ? Math.max(margins.top, headerDistance + maxHeaderContentHeight) : margins.top;
80655
+ const footerContentHeights = options.footerContentHeights;
80656
+ const maxFooterContentHeight = footerContentHeights ? Math.max(
80657
+ 0,
80658
+ validateContentHeight(footerContentHeights.default),
80659
+ validateContentHeight(footerContentHeights.first),
80660
+ validateContentHeight(footerContentHeights.even),
80661
+ validateContentHeight(footerContentHeights.odd)
80662
+ ) : 0;
80663
+ const footerDistance = margins.footer ?? margins.bottom;
80664
+ const effectiveBottomMargin = maxFooterContentHeight > 0 ? Math.max(margins.bottom, footerDistance + maxFooterContentHeight) : margins.bottom;
80523
80665
  let activeTopMargin = effectiveTopMargin;
80524
- let activeBottomMargin = margins.bottom;
80666
+ let activeBottomMargin = effectiveBottomMargin;
80525
80667
  let pendingTopMargin = null;
80526
80668
  let pendingBottomMargin = null;
80527
80669
  let activeHeaderDistance = margins.header ?? margins.top;
@@ -80544,7 +80686,7 @@ function layoutDocument(blocks, measures, options = {}) {
80544
80686
  const nextSectionPropsAtBreak = computeNextSectionPropsAtBreak(blocks);
80545
80687
  const scheduleSectionBreakCompat = (block, state2, baseMargins) => {
80546
80688
  if (typeof scheduleSectionBreak === "function") {
80547
- return scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight);
80689
+ return scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight, maxFooterContentHeight);
80548
80690
  }
80549
80691
  const next = { ...state2 };
80550
80692
  if (block.attrs?.isFirstSection && !next.hasAnyPages) {
@@ -80565,10 +80707,11 @@ function layoutDocument(blocks, measures, options = {}) {
80565
80707
  next.pendingTopMargin = next.activeTopMargin;
80566
80708
  }
80567
80709
  if (block.margins?.footer !== void 0) {
80568
- const footerDistance = Math.max(0, block.margins.footer);
80569
- next.activeFooterDistance = footerDistance;
80570
- next.pendingFooterDistance = footerDistance;
80571
- next.activeBottomMargin = Math.max(baseMargins.bottom, footerDistance);
80710
+ const footerDistance2 = Math.max(0, block.margins.footer);
80711
+ next.activeFooterDistance = footerDistance2;
80712
+ next.pendingFooterDistance = footerDistance2;
80713
+ const requiredBottom = maxFooterContentHeight > 0 ? footerDistance2 + maxFooterContentHeight : footerDistance2;
80714
+ next.activeBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
80572
80715
  next.pendingBottomMargin = next.activeBottomMargin;
80573
80716
  }
80574
80717
  if (block.columns) {
@@ -80613,7 +80756,13 @@ function layoutDocument(blocks, measures, options = {}) {
80613
80756
  } else {
80614
80757
  next.pendingTopMargin = nextTop;
80615
80758
  }
80616
- next.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
80759
+ if (typeof footerPx === "number") {
80760
+ const sectionFooter = next.pendingFooterDistance;
80761
+ const requiredBottom = maxFooterContentHeight > 0 ? sectionFooter + maxFooterContentHeight : sectionFooter;
80762
+ next.pendingBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
80763
+ } else {
80764
+ next.pendingBottomMargin = nextBottom;
80765
+ }
80617
80766
  if (block.pageSize) next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
80618
80767
  if (block.orientation) next.pendingOrientation = block.orientation;
80619
80768
  const sectionType = block.type ?? "continuous";
@@ -81380,6 +81529,49 @@ const hashParagraphBorders = (borders) => {
81380
81529
  if (borders.left) parts.push(`l:[${hashParagraphBorder(borders.left)}]`);
81381
81530
  return parts.join(";");
81382
81531
  };
81532
+ function isNoneBorder(value) {
81533
+ return typeof value === "object" && value !== null && "none" in value && value.none === true;
81534
+ }
81535
+ function isBorderSpec(value) {
81536
+ return typeof value === "object" && value !== null && !("none" in value);
81537
+ }
81538
+ const hashBorderSpec = (border) => {
81539
+ const parts = [];
81540
+ if (border.style !== void 0) parts.push(`s:${border.style}`);
81541
+ if (border.width !== void 0) parts.push(`w:${border.width}`);
81542
+ if (border.color !== void 0) parts.push(`c:${border.color}`);
81543
+ if (border.space !== void 0) parts.push(`sp:${border.space}`);
81544
+ return parts.join(",");
81545
+ };
81546
+ const hashTableBorderValue = (borderValue) => {
81547
+ if (borderValue === void 0) return "";
81548
+ if (borderValue === null) return "null";
81549
+ if (isNoneBorder(borderValue)) return "none";
81550
+ if (isBorderSpec(borderValue)) {
81551
+ return hashBorderSpec(borderValue);
81552
+ }
81553
+ return "";
81554
+ };
81555
+ const hashTableBorders = (borders) => {
81556
+ if (!borders) return "";
81557
+ const parts = [];
81558
+ if (borders.top !== void 0) parts.push(`t:[${hashTableBorderValue(borders.top)}]`);
81559
+ if (borders.right !== void 0) parts.push(`r:[${hashTableBorderValue(borders.right)}]`);
81560
+ if (borders.bottom !== void 0) parts.push(`b:[${hashTableBorderValue(borders.bottom)}]`);
81561
+ if (borders.left !== void 0) parts.push(`l:[${hashTableBorderValue(borders.left)}]`);
81562
+ if (borders.insideH !== void 0) parts.push(`ih:[${hashTableBorderValue(borders.insideH)}]`);
81563
+ if (borders.insideV !== void 0) parts.push(`iv:[${hashTableBorderValue(borders.insideV)}]`);
81564
+ return parts.join(";");
81565
+ };
81566
+ const hashCellBorders = (borders) => {
81567
+ if (!borders) return "";
81568
+ const parts = [];
81569
+ if (borders.top) parts.push(`t:[${hashBorderSpec(borders.top)}]`);
81570
+ if (borders.right) parts.push(`r:[${hashBorderSpec(borders.right)}]`);
81571
+ if (borders.bottom) parts.push(`b:[${hashBorderSpec(borders.bottom)}]`);
81572
+ if (borders.left) parts.push(`l:[${hashBorderSpec(borders.left)}]`);
81573
+ return parts.join(";");
81574
+ };
81383
81575
  const MAX_CACHE_SIZE$1 = 1e4;
81384
81576
  const BYTES_PER_ENTRY_ESTIMATE = 5e3;
81385
81577
  const NORMALIZED_WHITESPACE = /\s+/g;
@@ -81407,6 +81599,26 @@ const hashRuns = (block) => {
81407
81599
  continue;
81408
81600
  }
81409
81601
  for (const cell of row.cells) {
81602
+ if (cell.attrs) {
81603
+ const cellAttrs = cell.attrs;
81604
+ const cellAttrParts = [];
81605
+ if (cellAttrs.borders) {
81606
+ cellAttrParts.push(`cb:${hashCellBorders(cellAttrs.borders)}`);
81607
+ }
81608
+ if (cellAttrs.padding) {
81609
+ const p = cellAttrs.padding;
81610
+ cellAttrParts.push(`cp:${p.top ?? 0}:${p.right ?? 0}:${p.bottom ?? 0}:${p.left ?? 0}`);
81611
+ }
81612
+ if (cellAttrs.verticalAlign) {
81613
+ cellAttrParts.push(`va:${cellAttrs.verticalAlign}`);
81614
+ }
81615
+ if (cellAttrs.background) {
81616
+ cellAttrParts.push(`bg:${cellAttrs.background}`);
81617
+ }
81618
+ if (cellAttrParts.length > 0) {
81619
+ cellHashes.push(`ca:${cellAttrParts.join(":")}`);
81620
+ }
81621
+ }
81410
81622
  const cellBlocks = cell.blocks ?? (cell.paragraph ? [cell.paragraph] : []);
81411
81623
  for (const cellBlock of cellBlocks) {
81412
81624
  const paragraphBlock = cellBlock;
@@ -81473,8 +81685,25 @@ const hashRuns = (block) => {
81473
81685
  }
81474
81686
  }
81475
81687
  }
81688
+ let tableAttrsKey = "";
81689
+ if (tableBlock.attrs) {
81690
+ const tblAttrs = tableBlock.attrs;
81691
+ const tableAttrParts = [];
81692
+ if (tblAttrs.borders) {
81693
+ tableAttrParts.push(`tb:${hashTableBorders(tblAttrs.borders)}`);
81694
+ }
81695
+ if (tblAttrs.borderCollapse) {
81696
+ tableAttrParts.push(`bc:${tblAttrs.borderCollapse}`);
81697
+ }
81698
+ if (tblAttrs.cellSpacing !== void 0) {
81699
+ tableAttrParts.push(`cs:${tblAttrs.cellSpacing}`);
81700
+ }
81701
+ if (tableAttrParts.length > 0) {
81702
+ tableAttrsKey = `|ta:${tableAttrParts.join(":")}`;
81703
+ }
81704
+ }
81476
81705
  const contentHash = cellHashes.join("|");
81477
- return `${block.id}:table:${contentHash}`;
81706
+ return `${block.id}:table:${contentHash}${tableAttrsKey}`;
81478
81707
  }
81479
81708
  if (block.kind !== "paragraph") return block.id;
81480
81709
  const trackedMode = block.attrs && "trackedChangesMode" in block.attrs && block.attrs.trackedChangesMode || "review";
@@ -82996,17 +83225,67 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
82996
83225
  for (const [type2, value] of Object.entries(preHeaderLayouts)) {
82997
83226
  if (!isValidHeaderType(type2)) continue;
82998
83227
  if (value?.layout && typeof value.layout.height === "number") {
82999
- headerContentHeights[type2] = value.layout.height;
83228
+ const height = value.layout.height;
83229
+ if (Number.isFinite(height) && height >= 0) {
83230
+ headerContentHeights[type2] = height;
83231
+ }
83000
83232
  }
83001
83233
  }
83002
83234
  const hfPreEnd = performance.now();
83003
83235
  perfLog(`[Perf] 4.1.5 Pre-layout headers for height: ${(hfPreEnd - hfPreStart).toFixed(2)}ms`);
83004
83236
  }
83237
+ let footerContentHeights;
83238
+ if (headerFooter?.constraints && headerFooter.footerBlocks) {
83239
+ const footerPreStart = performance.now();
83240
+ const measureFn = headerFooter.measure ?? measureBlock2;
83241
+ if (!headerFooter.headerBlocks) {
83242
+ invalidateHeaderFooterCache(
83243
+ headerMeasureCache,
83244
+ headerFooterCacheState,
83245
+ headerFooter.headerBlocks,
83246
+ headerFooter.footerBlocks,
83247
+ headerFooter.constraints,
83248
+ options.sectionMetadata
83249
+ );
83250
+ }
83251
+ const FOOTER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT = 1;
83252
+ try {
83253
+ const preFooterLayouts = await layoutHeaderFooterWithCache(
83254
+ headerFooter.footerBlocks,
83255
+ headerFooter.constraints,
83256
+ measureFn,
83257
+ headerMeasureCache,
83258
+ FOOTER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT,
83259
+ void 0
83260
+ // No page resolver needed for height calculation
83261
+ );
83262
+ const isValidFooterType = (key2) => {
83263
+ return ["default", "first", "even", "odd"].includes(key2);
83264
+ };
83265
+ footerContentHeights = {};
83266
+ for (const [type2, value] of Object.entries(preFooterLayouts)) {
83267
+ if (!isValidFooterType(type2)) continue;
83268
+ if (value?.layout && typeof value.layout.height === "number") {
83269
+ const height = value.layout.height;
83270
+ if (Number.isFinite(height) && height >= 0) {
83271
+ footerContentHeights[type2] = height;
83272
+ }
83273
+ }
83274
+ }
83275
+ } catch (error) {
83276
+ console.error("[Layout] Footer pre-layout failed:", error);
83277
+ footerContentHeights = void 0;
83278
+ }
83279
+ const footerPreEnd = performance.now();
83280
+ perfLog(`[Perf] 4.1.6 Pre-layout footers for height: ${(footerPreEnd - footerPreStart).toFixed(2)}ms`);
83281
+ }
83005
83282
  const layoutStart = performance.now();
83006
83283
  let layout = layoutDocument(nextBlocks, measures, {
83007
83284
  ...options,
83008
83285
  headerContentHeights,
83009
83286
  // Pass header heights to prevent overlap
83287
+ footerContentHeights,
83288
+ // Pass footer heights to prevent overlap
83010
83289
  remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
83011
83290
  });
83012
83291
  const layoutEnd = performance.now();
@@ -83055,6 +83334,8 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
83055
83334
  ...options,
83056
83335
  headerContentHeights,
83057
83336
  // Pass header heights to prevent overlap
83337
+ footerContentHeights,
83338
+ // Pass footer heights to prevent overlap
83058
83339
  remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
83059
83340
  });
83060
83341
  const relayoutEnd = performance.now();
@@ -83221,6 +83502,285 @@ async function remeasureAffectedBlocks(blocks, measures, affectedBlockIds, const
83221
83502
  }
83222
83503
  return updatedMeasures;
83223
83504
  }
83505
+ class PageGeometryHelper {
83506
+ /**
83507
+ * Creates a new PageGeometryHelper instance.
83508
+ *
83509
+ * @param config - Page geometry configuration
83510
+ */
83511
+ constructor(config2) {
83512
+ this.cache = null;
83513
+ this.config = config2;
83514
+ }
83515
+ /**
83516
+ * Updates the layout and invalidates the cache.
83517
+ *
83518
+ * Call this whenever the layout changes (new pages, different heights, etc.)
83519
+ *
83520
+ * @param layout - New layout data
83521
+ * @param pageGap - Optional new page gap (if not provided, uses current gap)
83522
+ */
83523
+ updateLayout(layout, pageGap) {
83524
+ this.config.layout = layout;
83525
+ if (pageGap !== void 0) {
83526
+ this.config.pageGap = pageGap;
83527
+ }
83528
+ this.cache = null;
83529
+ }
83530
+ /**
83531
+ * Updates the page gap and invalidates the cache.
83532
+ *
83533
+ * @param pageGap - New gap between pages in pixels
83534
+ */
83535
+ updatePageGap(pageGap) {
83536
+ if (this.config.pageGap !== pageGap) {
83537
+ this.config.pageGap = pageGap;
83538
+ this.cache = null;
83539
+ }
83540
+ }
83541
+ /**
83542
+ * Gets the cumulative Y position (top edge) of a page in container space.
83543
+ *
83544
+ * The returned value is the distance from the top of the container to the
83545
+ * top of the specified page, accounting for all previous pages and gaps.
83546
+ *
83547
+ * @param pageIndex - Zero-based page index
83548
+ * @returns Y position in pixels, or 0 if page index is invalid
83549
+ *
83550
+ * @example
83551
+ * ```typescript
83552
+ * // Get Y position of page 0 (first page)
83553
+ * const y0 = helper.getPageTop(0); // Returns 0
83554
+ *
83555
+ * // Get Y position of page 2 (third page)
83556
+ * // Assumes page 0 height = 1000, page 1 height = 1200, gap = 24
83557
+ * const y2 = helper.getPageTop(2); // Returns 1000 + 24 + 1200 + 24 = 2248
83558
+ * ```
83559
+ */
83560
+ getPageTop(pageIndex) {
83561
+ this.ensureCache();
83562
+ if (pageIndex < 0 || pageIndex >= this.cache.cumulativeY.length) {
83563
+ return 0;
83564
+ }
83565
+ return this.cache.cumulativeY[pageIndex];
83566
+ }
83567
+ /**
83568
+ * Gets the height of a specific page.
83569
+ *
83570
+ * Uses per-page height if available (from layout.pages[i].size?.h),
83571
+ * otherwise falls back to layout.pageSize.h.
83572
+ *
83573
+ * @param pageIndex - Zero-based page index
83574
+ * @returns Page height in pixels, or 0 if page index is invalid
83575
+ *
83576
+ * @example
83577
+ * ```typescript
83578
+ * const height = helper.getPageHeight(0); // Returns page-specific height
83579
+ * ```
83580
+ */
83581
+ getPageHeight(pageIndex) {
83582
+ this.ensureCache();
83583
+ if (pageIndex < 0 || pageIndex >= this.cache.pageHeights.length) {
83584
+ return 0;
83585
+ }
83586
+ return this.cache.pageHeights[pageIndex];
83587
+ }
83588
+ /**
83589
+ * Gets the gap between pages.
83590
+ *
83591
+ * @returns Gap in pixels
83592
+ *
83593
+ * @example
83594
+ * ```typescript
83595
+ * const gap = helper.getPageGap(); // Returns 24
83596
+ * ```
83597
+ */
83598
+ getPageGap() {
83599
+ this.ensureCache();
83600
+ return this.cache.pageGap;
83601
+ }
83602
+ /**
83603
+ * Gets the total height of all pages including gaps.
83604
+ *
83605
+ * Total height = sum of all page heights + (pageCount - 1) * gap
83606
+ *
83607
+ * @returns Total height in pixels
83608
+ *
83609
+ * @example
83610
+ * ```typescript
83611
+ * // 3 pages: heights [1000, 1200, 1000], gap = 24
83612
+ * const total = helper.getTotalHeight();
83613
+ * // Returns 1000 + 24 + 1200 + 24 + 1000 = 3248
83614
+ * ```
83615
+ */
83616
+ getTotalHeight() {
83617
+ this.ensureCache();
83618
+ return this.cache.totalHeight;
83619
+ }
83620
+ /**
83621
+ * Gets the number of pages in the layout.
83622
+ *
83623
+ * @returns Page count
83624
+ */
83625
+ getPageCount() {
83626
+ return this.config.layout.pages.length;
83627
+ }
83628
+ /**
83629
+ * Finds the page index containing a given Y coordinate.
83630
+ *
83631
+ * This performs a linear search through cached cumulative positions.
83632
+ * For large documents, consider adding binary search optimization.
83633
+ *
83634
+ * @param containerY - Y coordinate in container space
83635
+ * @returns Page index, or null if Y is outside all pages
83636
+ *
83637
+ * @example
83638
+ * ```typescript
83639
+ * // Find which page contains Y = 1500
83640
+ * const pageIndex = helper.getPageIndexAtY(1500);
83641
+ * // Returns 1 (second page) if first page ends at Y=1024
83642
+ * ```
83643
+ */
83644
+ getPageIndexAtY(containerY) {
83645
+ this.ensureCache();
83646
+ const cache2 = this.cache;
83647
+ for (let i = 0; i < cache2.cumulativeY.length; i++) {
83648
+ const pageTop = cache2.cumulativeY[i];
83649
+ const pageBottom = pageTop + cache2.pageHeights[i];
83650
+ if (containerY >= pageTop && containerY < pageBottom) {
83651
+ return i;
83652
+ }
83653
+ }
83654
+ return null;
83655
+ }
83656
+ /**
83657
+ * Finds the nearest page index to a given Y coordinate (snap-to-nearest).
83658
+ *
83659
+ * Returns the page containing Y when inside a page; otherwise returns the
83660
+ * closest page based on distance to page center. Useful for dragging through
83661
+ * page gaps where getPageIndexAtY would return null.
83662
+ *
83663
+ * @param containerY - Y coordinate in container space
83664
+ * @returns Nearest page index, or null if there are no pages
83665
+ */
83666
+ getNearestPageIndex(containerY) {
83667
+ this.ensureCache();
83668
+ const cache2 = this.cache;
83669
+ const pageCount = cache2.pageHeights.length;
83670
+ if (pageCount === 0) return null;
83671
+ const direct = this.getPageIndexAtY(containerY);
83672
+ if (direct !== null) return direct;
83673
+ let nearestIndex = 0;
83674
+ let nearestDistance = Infinity;
83675
+ for (let i = 0; i < pageCount; i++) {
83676
+ const top2 = cache2.cumulativeY[i];
83677
+ const height = cache2.pageHeights[i];
83678
+ const center = top2 + height / 2;
83679
+ const distance = Math.abs(containerY - center);
83680
+ if (distance < nearestDistance) {
83681
+ nearestDistance = distance;
83682
+ nearestIndex = i;
83683
+ }
83684
+ }
83685
+ return nearestIndex;
83686
+ }
83687
+ /**
83688
+ * Ensures the cache is built and up-to-date.
83689
+ * Validates cache state and rebuilds if needed.
83690
+ * @private
83691
+ * @throws Never throws - handles errors gracefully with fallback values
83692
+ */
83693
+ ensureCache() {
83694
+ if (this.cache !== null) {
83695
+ if (!Array.isArray(this.cache.cumulativeY) || !Array.isArray(this.cache.pageHeights)) {
83696
+ console.warn("[PageGeometryHelper] Cache corruption detected, rebuilding cache");
83697
+ this.cache = null;
83698
+ } else {
83699
+ return;
83700
+ }
83701
+ }
83702
+ this.buildCache();
83703
+ }
83704
+ /**
83705
+ * Builds the geometry cache from current layout data.
83706
+ * Handles errors gracefully by providing fallback values.
83707
+ * @private
83708
+ * @throws Never throws - catches all errors and provides safe defaults
83709
+ */
83710
+ buildCache() {
83711
+ try {
83712
+ const layout = this.config.layout;
83713
+ if (!layout || !Array.isArray(layout.pages)) {
83714
+ throw new Error("Invalid layout: missing or invalid pages array");
83715
+ }
83716
+ const pageGap = this.config.pageGap ?? layout.pageGap ?? 0;
83717
+ const pageCount = layout.pages.length;
83718
+ if (!Number.isFinite(pageGap) || pageGap < 0) {
83719
+ throw new Error(`Invalid pageGap: ${pageGap} (must be non-negative finite number)`);
83720
+ }
83721
+ const cumulativeY = new Array(pageCount);
83722
+ const pageHeights = new Array(pageCount);
83723
+ let currentY = 0;
83724
+ for (let i = 0; i < pageCount; i++) {
83725
+ const page = layout.pages[i];
83726
+ if (!page) {
83727
+ throw new Error(`Invalid page at index ${i}: page is null or undefined`);
83728
+ }
83729
+ const pageHeight = page.size?.h ?? layout.pageSize.h;
83730
+ if (!Number.isFinite(pageHeight) || pageHeight < 0) {
83731
+ throw new Error(`Invalid page height at index ${i}: ${pageHeight} (must be non-negative finite number)`);
83732
+ }
83733
+ cumulativeY[i] = currentY;
83734
+ pageHeights[i] = pageHeight;
83735
+ currentY += pageHeight;
83736
+ if (i < pageCount - 1) {
83737
+ currentY += pageGap;
83738
+ }
83739
+ }
83740
+ const totalHeight = currentY;
83741
+ this.cache = {
83742
+ cumulativeY,
83743
+ pageHeights,
83744
+ pageGap,
83745
+ totalHeight,
83746
+ layoutVersion: 0
83747
+ // Placeholder for future version tracking
83748
+ };
83749
+ } catch (error) {
83750
+ const errorMessage = error instanceof Error ? error.message : String(error);
83751
+ console.error(`[PageGeometryHelper] Cache build failed: ${errorMessage}. Using fallback empty cache.`);
83752
+ this.cache = {
83753
+ cumulativeY: [],
83754
+ pageHeights: [],
83755
+ pageGap: 0,
83756
+ totalHeight: 0,
83757
+ layoutVersion: 0
83758
+ };
83759
+ }
83760
+ }
83761
+ /**
83762
+ * Clears the cache, forcing recalculation on next access.
83763
+ * Useful for testing or manual cache invalidation.
83764
+ */
83765
+ clearCache() {
83766
+ this.cache = null;
83767
+ }
83768
+ /**
83769
+ * Gets debug information about the current cache state.
83770
+ * @internal
83771
+ */
83772
+ getDebugInfo() {
83773
+ this.ensureCache();
83774
+ return {
83775
+ isCached: this.cache !== null,
83776
+ pageCount: this.config.layout.pages.length,
83777
+ pageGap: this.cache.pageGap,
83778
+ totalHeight: this.cache.totalHeight,
83779
+ cumulativeY: [...this.cache.cumulativeY],
83780
+ pageHeights: [...this.cache.pageHeights]
83781
+ };
83782
+ }
83783
+ }
83224
83784
  var Priority = /* @__PURE__ */ ((Priority2) => {
83225
83785
  Priority2[Priority2["P0"] = 0] = "P0";
83226
83786
  Priority2[Priority2["P1"] = 1] = "P1";
@@ -83514,18 +84074,41 @@ const rangesOverlap = (startA, endA, startB, endB) => {
83514
84074
  const effectiveEndA = endA ?? startA + 1;
83515
84075
  return effectiveEndA > startB && startA < endB;
83516
84076
  };
83517
- function hitTestPage(layout, point) {
84077
+ function hitTestPage(layout, point, geometryHelper) {
84078
+ if (geometryHelper) {
84079
+ const pageIndex = geometryHelper.getPageIndexAtY(point.y);
84080
+ if (pageIndex !== null) {
84081
+ return { pageIndex, page: layout.pages[pageIndex] };
84082
+ }
84083
+ const nearest = geometryHelper.getNearestPageIndex(point.y);
84084
+ if (nearest !== null) {
84085
+ return { pageIndex: nearest, page: layout.pages[nearest] };
84086
+ }
84087
+ return null;
84088
+ }
83518
84089
  const pageGap = layout.pageGap ?? 0;
83519
84090
  let cursorY = 0;
84091
+ let nearestIndex = null;
84092
+ let nearestDistance = Infinity;
83520
84093
  for (let pageIndex = 0; pageIndex < layout.pages.length; pageIndex += 1) {
83521
84094
  const page = layout.pages[pageIndex];
84095
+ const pageHeight = page.size?.h ?? layout.pageSize.h;
83522
84096
  const top2 = cursorY;
83523
- const bottom2 = top2 + layout.pageSize.h;
84097
+ const bottom2 = top2 + pageHeight;
83524
84098
  if (point.y >= top2 && point.y < bottom2) {
83525
84099
  return { pageIndex, page };
83526
84100
  }
84101
+ const center = top2 + pageHeight / 2;
84102
+ const distance = Math.abs(point.y - center);
84103
+ if (distance < nearestDistance) {
84104
+ nearestDistance = distance;
84105
+ nearestIndex = pageIndex;
84106
+ }
83527
84107
  cursorY = bottom2 + pageGap;
83528
84108
  }
84109
+ if (nearestIndex !== null) {
84110
+ return { pageIndex: nearestIndex, page: layout.pages[nearestIndex] };
84111
+ }
83529
84112
  return null;
83530
84113
  }
83531
84114
  function hitTestFragment(layout, pageHit, blocks, measures, point) {
@@ -83686,7 +84269,7 @@ const hitTestTableFragment = (pageHit, blocks, measures, point) => {
83686
84269
  }
83687
84270
  return null;
83688
84271
  };
83689
- function clickToPosition(layout, blocks, measures, containerPoint, domContainer, clientX, clientY) {
84272
+ function clickToPosition(layout, blocks, measures, containerPoint, domContainer, clientX, clientY, geometryHelper) {
83690
84273
  logClickStage("log", "entry", {
83691
84274
  pages: layout.pages.length
83692
84275
  });
@@ -83729,75 +84312,132 @@ function clickToPosition(layout, blocks, measures, containerPoint, domContainer,
83729
84312
  return { pos: domPos, blockId: "", pageIndex: 0, column: 0, lineIndex: -1 };
83730
84313
  }
83731
84314
  }
83732
- const pageHit = hitTestPage(layout, containerPoint);
84315
+ const pageHit = hitTestPage(layout, containerPoint, geometryHelper);
83733
84316
  if (!pageHit) {
83734
84317
  return null;
83735
84318
  }
83736
- const pageGap = layout.pageGap ?? 0;
84319
+ const pageTopY = geometryHelper ? geometryHelper.getPageTop(pageHit.pageIndex) : calculatePageTopFallback(layout, pageHit.pageIndex);
83737
84320
  const pageRelativePoint = {
83738
84321
  x: containerPoint.x,
83739
- y: containerPoint.y - pageHit.pageIndex * (layout.pageSize.h + pageGap)
84322
+ y: containerPoint.y - pageTopY
83740
84323
  };
83741
84324
  logClickStage("log", "page-hit", {
83742
84325
  pageIndex: pageHit.pageIndex
83743
84326
  });
83744
- const fragmentHit = hitTestFragment(layout, pageHit, blocks, measures, pageRelativePoint);
84327
+ let fragmentHit = hitTestFragment(layout, pageHit, blocks, measures, pageRelativePoint);
84328
+ if (!fragmentHit) {
84329
+ const page = pageHit.page;
84330
+ const fragments = page.fragments.filter(
84331
+ (f2) => f2 != null && typeof f2 === "object"
84332
+ );
84333
+ if (fragments.length > 0) {
84334
+ let nearest = null;
84335
+ let nearestDist = Infinity;
84336
+ for (const frag of fragments) {
84337
+ const top2 = frag.y;
84338
+ const bottom2 = frag.y + frag.height;
84339
+ let dist2;
84340
+ if (pageRelativePoint.y < top2) {
84341
+ dist2 = top2 - pageRelativePoint.y;
84342
+ } else if (pageRelativePoint.y > bottom2) {
84343
+ dist2 = pageRelativePoint.y - bottom2;
84344
+ } else {
84345
+ dist2 = 0;
84346
+ }
84347
+ if (dist2 < nearestDist) {
84348
+ nearestDist = dist2;
84349
+ nearest = frag;
84350
+ }
84351
+ }
84352
+ if (nearest) {
84353
+ const blockIndex = findBlockIndexByFragmentId(blocks, nearest.blockId);
84354
+ if (blockIndex !== -1) {
84355
+ const block = blocks[blockIndex];
84356
+ const measure = measures[blockIndex];
84357
+ if (block && measure) {
84358
+ fragmentHit = {
84359
+ fragment: nearest,
84360
+ block,
84361
+ measure,
84362
+ pageIndex: pageHit.pageIndex,
84363
+ pageY: 0
84364
+ };
84365
+ }
84366
+ }
84367
+ }
84368
+ }
84369
+ }
83745
84370
  if (fragmentHit) {
83746
84371
  const { fragment, block, measure, pageIndex, pageY } = fragmentHit;
83747
- if (fragment.kind !== "para" || measure.kind !== "paragraph" || block.kind !== "paragraph") {
83748
- logClickStage("warn", "fragment-type-mismatch", {
83749
- fragmentKind: fragment.kind,
83750
- measureKind: measure.kind,
83751
- blockKind: block.kind
84372
+ if (fragment.kind === "para" && measure.kind === "paragraph" && block.kind === "paragraph") {
84373
+ const lineIndex = findLineIndexAtY(measure, pageY, fragment.fromLine, fragment.toLine);
84374
+ if (lineIndex == null) {
84375
+ logClickStage("warn", "no-line", {
84376
+ blockId: fragment.blockId
84377
+ });
84378
+ return null;
84379
+ }
84380
+ const line = measure.lines[lineIndex];
84381
+ const isRTL = isRtlBlock(block);
84382
+ const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
84383
+ const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
84384
+ const paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
84385
+ const paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
84386
+ const totalIndent = paraIndentLeft + paraIndentRight;
84387
+ const availableWidth = Math.max(0, fragment.width - totalIndent);
84388
+ if (totalIndent > fragment.width) {
84389
+ console.warn(
84390
+ `[clickToPosition] Paragraph indents (${totalIndent}px) exceed fragment width (${fragment.width}px) for block ${fragment.blockId}. This may indicate a layout miscalculation. Available width clamped to 0.`
84391
+ );
84392
+ }
84393
+ const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
84394
+ const isListItem3 = markerWidth > 0;
84395
+ const alignmentOverride = isListItem3 ? "left" : void 0;
84396
+ const pos = mapPointToPm(block, line, pageRelativePoint.x - fragment.x, isRTL, availableWidth, alignmentOverride);
84397
+ if (pos == null) {
84398
+ logClickStage("warn", "no-position", {
84399
+ blockId: fragment.blockId
84400
+ });
84401
+ return null;
84402
+ }
84403
+ const column = determineColumn(layout, fragment.x);
84404
+ logPositionDebug({
84405
+ blockId: fragment.blockId,
84406
+ x: pageRelativePoint.x - fragment.x
83752
84407
  });
83753
- return null;
83754
- }
83755
- const lineIndex = findLineIndexAtY(measure, pageY, fragment.fromLine, fragment.toLine);
83756
- if (lineIndex == null) {
83757
- logClickStage("warn", "no-line", {
84408
+ logClickStage("log", "success", {
83758
84409
  blockId: fragment.blockId
83759
84410
  });
83760
- return null;
83761
- }
83762
- const line = measure.lines[lineIndex];
83763
- const isRTL = isRtlBlock(block);
83764
- const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
83765
- const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
83766
- const paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
83767
- const paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
83768
- const totalIndent = paraIndentLeft + paraIndentRight;
83769
- const availableWidth = Math.max(0, fragment.width - totalIndent);
83770
- if (totalIndent > fragment.width) {
83771
- console.warn(
83772
- `[clickToPosition] Paragraph indents (${totalIndent}px) exceed fragment width (${fragment.width}px) for block ${fragment.blockId}. This may indicate a layout miscalculation. Available width clamped to 0.`
83773
- );
84411
+ return {
84412
+ pos,
84413
+ blockId: fragment.blockId,
84414
+ pageIndex,
84415
+ column,
84416
+ lineIndex
84417
+ // lineIndex is now already absolute (within measure.lines), no need to add fragment.fromLine
84418
+ };
83774
84419
  }
83775
- const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
83776
- const isListItem3 = markerWidth > 0;
83777
- const alignmentOverride = isListItem3 ? "left" : void 0;
83778
- const pos = mapPointToPm(block, line, pageRelativePoint.x - fragment.x, isRTL, availableWidth, alignmentOverride);
83779
- if (pos == null) {
83780
- logClickStage("warn", "no-position", {
83781
- blockId: fragment.blockId
84420
+ if (isAtomicFragment(fragment)) {
84421
+ const pmRange = getAtomicPmRange(fragment, block);
84422
+ const pos = pmRange.pmStart ?? pmRange.pmEnd ?? null;
84423
+ if (pos == null) {
84424
+ logClickStage("warn", "atomic-without-range", {
84425
+ fragmentId: fragment.blockId
84426
+ });
84427
+ return null;
84428
+ }
84429
+ logClickStage("log", "success", {
84430
+ blockId: fragment.blockId,
84431
+ column: determineColumn(layout, fragment.x)
83782
84432
  });
83783
- return null;
84433
+ return {
84434
+ pos,
84435
+ blockId: fragment.blockId,
84436
+ pageIndex,
84437
+ column: determineColumn(layout, fragment.x),
84438
+ lineIndex: -1
84439
+ };
83784
84440
  }
83785
- const column = determineColumn(layout, fragment.x);
83786
- logPositionDebug({
83787
- blockId: fragment.blockId,
83788
- x: pageRelativePoint.x - fragment.x
83789
- });
83790
- logClickStage("log", "success", {
83791
- blockId: fragment.blockId
83792
- });
83793
- return {
83794
- pos,
83795
- blockId: fragment.blockId,
83796
- pageIndex,
83797
- column,
83798
- lineIndex
83799
- // lineIndex is now already absolute (within measure.lines), no need to add fragment.fromLine
83800
- };
83801
84441
  }
83802
84442
  const tableHit = hitTestTableFragment(pageHit, blocks, measures, pageRelativePoint);
83803
84443
  if (tableHit) {
@@ -83947,12 +84587,22 @@ const sumLineHeights = (measure, fromLine, toLine) => {
83947
84587
  }
83948
84588
  return height;
83949
84589
  };
83950
- function selectionToRects(layout, blocks, measures, from2, to) {
84590
+ const calculatePageTopFallback = (layout, pageIndex) => {
84591
+ const pageGap = layout.pageGap ?? 0;
84592
+ let y2 = 0;
84593
+ for (let i = 0; i < pageIndex; i++) {
84594
+ const pageHeight = layout.pages[i]?.size?.h ?? layout.pageSize.h;
84595
+ y2 += pageHeight + pageGap;
84596
+ }
84597
+ return y2;
84598
+ };
84599
+ function selectionToRects(layout, blocks, measures, from2, to, geometryHelper) {
83951
84600
  if (from2 === to) {
83952
84601
  return [];
83953
84602
  }
83954
84603
  const rects = [];
83955
84604
  layout.pages.forEach((page, pageIndex) => {
84605
+ const pageTopY = geometryHelper ? geometryHelper.getPageTop(pageIndex) : calculatePageTopFallback(layout, pageIndex);
83956
84606
  page.fragments.forEach((fragment) => {
83957
84607
  if (fragment.kind === "para") {
83958
84608
  const blockIndex = findBlockIndexByFragmentId(blocks, fragment.blockId, { from: from2, to });
@@ -83994,12 +84644,16 @@ function selectionToRects(layout, blocks, measures, from2, to) {
83994
84644
  wordLayout
83995
84645
  });
83996
84646
  const rectX = fragment.x + indentAdjust + Math.min(startX, endX);
83997
- const rectWidth = Math.max(1, Math.abs(endX - startX));
84647
+ const rectWidth = Math.max(
84648
+ 1,
84649
+ Math.min(Math.abs(endX - startX), line.width)
84650
+ // clamp to line width to prevent runaway widths
84651
+ );
83998
84652
  const lineOffset = lineHeightBeforeIndex(measure, index2) - lineHeightBeforeIndex(measure, fragment.fromLine);
83999
84653
  const rectY = fragment.y + lineOffset;
84000
84654
  rects.push({
84001
84655
  x: rectX,
84002
- y: rectY + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84656
+ y: rectY + pageTopY,
84003
84657
  width: rectWidth,
84004
84658
  height: line.lineHeight,
84005
84659
  pageIndex
@@ -84127,12 +84781,16 @@ function selectionToRects(layout, blocks, measures, from2, to) {
84127
84781
  wordLayout: cellWordLayout
84128
84782
  });
84129
84783
  const rectX = fragment.x + cellX + padding.left + textIndentAdjust + Math.min(startX, endX);
84130
- const rectWidth = Math.max(1, Math.abs(endX - startX));
84784
+ const rectWidth = Math.max(
84785
+ 1,
84786
+ Math.min(Math.abs(endX - startX), line.width)
84787
+ // clamp to line width to prevent runaway widths
84788
+ );
84131
84789
  const lineOffset = lineHeightBeforeIndex(info.measure, index2) - lineHeightBeforeIndex(info.measure, info.startLine);
84132
84790
  const rectY = fragment.y + rowOffset + blockTopCursor + lineOffset;
84133
84791
  rects.push({
84134
84792
  x: rectX,
84135
- y: rectY + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84793
+ y: rectY + pageTopY,
84136
84794
  width: rectWidth,
84137
84795
  height: line.lineHeight,
84138
84796
  pageIndex
@@ -84161,7 +84819,7 @@ function selectionToRects(layout, blocks, measures, from2, to) {
84161
84819
  if (!rangesOverlap(pmRange.pmStart, pmRange.pmEnd, from2, to)) return;
84162
84820
  rects.push({
84163
84821
  x: fragment.x,
84164
- y: fragment.y + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84822
+ y: fragment.y + pageTopY,
84165
84823
  width: fragment.width,
84166
84824
  height: fragment.height,
84167
84825
  pageIndex
@@ -85277,7 +85935,7 @@ async function measureParagraphBlock(block, maxWidth) {
85277
85935
  const wordEndWithSpace = charPosInRun + (isLastWord ? word.length : word.length + 1);
85278
85936
  const effectiveMaxWidth = currentLine ? currentLine.maxWidth : getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
85279
85937
  if (wordOnlyWidth > effectiveMaxWidth && word.length > 1) {
85280
- if (currentLine && currentLine.width > 0 && currentLine.segments.length > 0) {
85938
+ if (currentLine && currentLine.width > 0 && currentLine.segments && currentLine.segments.length > 0) {
85281
85939
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
85282
85940
  const { spaceCount: _sc, ...lineBase } = currentLine;
85283
85941
  const completedLine = { ...lineBase, ...metrics };
@@ -85288,7 +85946,7 @@ async function measureParagraphBlock(block, maxWidth) {
85288
85946
  currentLine = null;
85289
85947
  }
85290
85948
  const lineMaxWidth = getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
85291
- const hasTabOnlyLine = currentLine && currentLine.segments.length === 0 && currentLine.width > 0;
85949
+ const hasTabOnlyLine = currentLine && currentLine.segments && currentLine.segments.length === 0 && currentLine.width > 0;
85292
85950
  const remainingWidthAfterTab = hasTabOnlyLine ? currentLine.maxWidth - currentLine.width : lineMaxWidth;
85293
85951
  const chunkWidth = hasTabOnlyLine ? Math.max(remainingWidthAfterTab, lineMaxWidth * 0.25) : lineMaxWidth;
85294
85952
  const chunks = breakWordIntoChunks(word, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run2);
@@ -85299,7 +85957,7 @@ async function measureParagraphBlock(block, maxWidth) {
85299
85957
  const chunkEndChar = chunkCharOffset + chunk.text.length;
85300
85958
  const isLastChunk = chunkIndex === chunks.length - 1;
85301
85959
  const isFirstChunk = chunkIndex === 0;
85302
- if (isFirstChunk && hasTabOnlyLine && currentLine) {
85960
+ if (isFirstChunk && hasTabOnlyLine && currentLine && currentLine.segments) {
85303
85961
  currentLine.toRun = runIndex;
85304
85962
  currentLine.toChar = chunkEndChar;
85305
85963
  currentLine.width = roundValue(currentLine.width + chunk.width);
@@ -86132,6 +86790,7 @@ const createHeaderFooterEditor = ({
86132
86790
  const fontSizeInPixles = fontSizePt * 1.3333;
86133
86791
  const lineHeight2 = fontSizeInPixles * 1.2;
86134
86792
  applyStyleIsolationClass(editorContainer);
86793
+ const isFooter = type2 === "footer";
86135
86794
  Object.assign(editorContainer.style, {
86136
86795
  padding: "0",
86137
86796
  margin: "0",
@@ -86146,7 +86805,7 @@ const createHeaderFooterEditor = ({
86146
86805
  fontFamily: fontFamilyCss || typeface,
86147
86806
  fontSize: `${fontSizeInPixles}px`,
86148
86807
  lineHeight: `${lineHeight2}px`,
86149
- overflow: "hidden",
86808
+ overflow: isFooter ? "visible" : "hidden",
86150
86809
  pointerEvents: "auto",
86151
86810
  // Critical: enables click interaction
86152
86811
  backgroundColor: "white"
@@ -87225,6 +87884,7 @@ class EditorOverlayManager {
87225
87884
  const editorContainer = __privateGet$1(this, _activeEditorHost).querySelector(".super-editor");
87226
87885
  if (editorContainer instanceof HTMLElement) {
87227
87886
  editorContainer.style.top = "0";
87887
+ editorContainer.style.transform = "";
87228
87888
  }
87229
87889
  }
87230
87890
  }
@@ -87400,6 +88060,7 @@ const DEFAULT_PAGE_SIZE = { w: 612, h: 792 };
87400
88060
  const DEFAULT_MARGINS = { top: 72, right: 72, bottom: 72, left: 72 };
87401
88061
  const DEFAULT_VIRTUALIZED_PAGE_GAP = 72;
87402
88062
  const DEFAULT_PAGE_GAP = 24;
88063
+ const DEFAULT_HORIZONTAL_PAGE_GAP = 20;
87403
88064
  const WORD_CHARACTER_REGEX = /[\p{L}\p{N}''_~-]/u;
87404
88065
  const MULTI_CLICK_TIME_THRESHOLD_MS = 400;
87405
88066
  const MULTI_CLICK_DISTANCE_THRESHOLD_PX = 5;
@@ -87423,6 +88084,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87423
88084
  __privateAdd$1(this, _layoutOptions);
87424
88085
  __privateAdd$1(this, _layoutState, { blocks: [], measures: [], layout: null, bookmarks: /* @__PURE__ */ new Map() });
87425
88086
  __privateAdd$1(this, _domPainter, null);
88087
+ __privateAdd$1(this, _pageGeometryHelper, null);
87426
88088
  __privateAdd$1(this, _dragHandlerCleanup, null);
87427
88089
  __privateAdd$1(this, _layoutError, null);
87428
88090
  __privateAdd$1(this, _layoutErrorState, "healthy");
@@ -87575,7 +88237,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87575
88237
  { x: x2, y: y2 },
87576
88238
  __privateGet$1(this, _viewportHost),
87577
88239
  event.clientX,
87578
- event.clientY
88240
+ event.clientY,
88241
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
87579
88242
  );
87580
88243
  const doc22 = __privateGet$1(this, _editor3).state?.doc;
87581
88244
  const hit = rawHit && doc22 ? { ...rawHit, pos: Math.max(0, Math.min(rawHit.pos, doc22.content.size)) } : rawHit;
@@ -87774,7 +88437,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87774
88437
  { x: normalized.x, y: normalized.y },
87775
88438
  __privateGet$1(this, _viewportHost),
87776
88439
  event.clientX,
87777
- event.clientY
88440
+ event.clientY,
88441
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
87778
88442
  );
87779
88443
  if (!hit) return;
87780
88444
  const currentTableHit = __privateMethod$1(this, _PresentationEditor_instances, hitTestTable_fn).call(this, normalized.x, normalized.y);
@@ -88621,7 +89285,14 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88621
89285
  return __privateMethod$1(this, _PresentationEditor_instances, computeHeaderFooterSelectionRects_fn).call(this, start2, end2);
88622
89286
  }
88623
89287
  if (!__privateGet$1(this, _layoutState).layout) return [];
88624
- const rects = selectionToRects(__privateGet$1(this, _layoutState).layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, start2, end2) ?? [];
89288
+ const rects = selectionToRects(
89289
+ __privateGet$1(this, _layoutState).layout,
89290
+ __privateGet$1(this, _layoutState).blocks,
89291
+ __privateGet$1(this, _layoutState).measures,
89292
+ start2,
89293
+ end2,
89294
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
89295
+ ) ?? [];
88625
89296
  return rects;
88626
89297
  };
88627
89298
  const rawRects = layoutRectSource();
@@ -88886,6 +89557,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88886
89557
  };
88887
89558
  }
88888
89559
  __privateSet(this, _domPainter, null);
89560
+ __privateSet(this, _pageGeometryHelper, null);
88889
89561
  __privateSet(this, _pendingDocChange, true);
88890
89562
  __privateMethod$1(this, _PresentationEditor_instances, scheduleRerender_fn).call(this);
88891
89563
  }
@@ -88918,7 +89590,16 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88918
89590
  x: localX,
88919
89591
  y: headerPageIndex * headerPageHeight + (localY - headerPageIndex * headerPageHeight)
88920
89592
  };
88921
- const hit2 = clickToPosition(context.layout, context.blocks, context.measures, headerPoint) ?? null;
89593
+ const hit2 = clickToPosition(
89594
+ context.layout,
89595
+ context.blocks,
89596
+ context.measures,
89597
+ headerPoint,
89598
+ void 0,
89599
+ void 0,
89600
+ void 0,
89601
+ void 0
89602
+ ) ?? null;
88922
89603
  return hit2;
88923
89604
  }
88924
89605
  if (!__privateGet$1(this, _layoutState).layout) {
@@ -88931,7 +89612,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88931
89612
  normalized,
88932
89613
  __privateGet$1(this, _viewportHost),
88933
89614
  clientX,
88934
- clientY
89615
+ clientY,
89616
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
88935
89617
  ) ?? null;
88936
89618
  return hit;
88937
89619
  }
@@ -89154,6 +89836,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
89154
89836
  __privateSet(this, _session, { mode: "body" });
89155
89837
  __privateSet(this, _activeHeaderFooterEditor, null);
89156
89838
  __privateSet(this, _domPainter, null);
89839
+ __privateSet(this, _pageGeometryHelper, null);
89157
89840
  (_a2 = __privateGet$1(this, _dragHandlerCleanup)) == null ? void 0 : _a2.call(this);
89158
89841
  __privateSet(this, _dragHandlerCleanup, null);
89159
89842
  __privateGet$1(this, _selectionOverlay2)?.remove();
@@ -89207,7 +89890,14 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
89207
89890
  if (!normalized) return false;
89208
89891
  const pmPos = __privateGet$1(this, _layoutState).bookmarks.get(normalized);
89209
89892
  if (pmPos == null) return false;
89210
- const rects = selectionToRects(layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, pmPos, pmPos + 1) ?? [];
89893
+ const rects = selectionToRects(
89894
+ layout,
89895
+ __privateGet$1(this, _layoutState).blocks,
89896
+ __privateGet$1(this, _layoutState).measures,
89897
+ pmPos,
89898
+ pmPos + 1,
89899
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
89900
+ ) ?? [];
89211
89901
  const rect = rects[0];
89212
89902
  let pageIndex = rect?.pageIndex ?? null;
89213
89903
  if (pageIndex == null) {
@@ -89271,6 +89961,7 @@ _hiddenHost = /* @__PURE__ */ new WeakMap();
89271
89961
  _layoutOptions = /* @__PURE__ */ new WeakMap();
89272
89962
  _layoutState = /* @__PURE__ */ new WeakMap();
89273
89963
  _domPainter = /* @__PURE__ */ new WeakMap();
89964
+ _pageGeometryHelper = /* @__PURE__ */ new WeakMap();
89274
89965
  _dragHandlerCleanup = /* @__PURE__ */ new WeakMap();
89275
89966
  _layoutError = /* @__PURE__ */ new WeakMap();
89276
89967
  _layoutErrorState = /* @__PURE__ */ new WeakMap();
@@ -89503,18 +90194,19 @@ normalizeAwarenessStates_fn = function() {
89503
90194
  const normalized = /* @__PURE__ */ new Map();
89504
90195
  states?.forEach((aw, clientId) => {
89505
90196
  if (clientId === provider.awareness?.clientID) return;
89506
- if (!aw.cursor) return;
90197
+ const awState = aw;
90198
+ if (!awState.cursor) return;
89507
90199
  try {
89508
90200
  const anchor = relativePositionToAbsolutePosition(
89509
90201
  ystate.doc,
89510
90202
  ystate.type,
89511
- Y.createRelativePositionFromJSON(aw.cursor.anchor),
90203
+ Y.createRelativePositionFromJSON(awState.cursor.anchor),
89512
90204
  ystate.binding.mapping
89513
90205
  );
89514
90206
  const head = relativePositionToAbsolutePosition(
89515
90207
  ystate.doc,
89516
90208
  ystate.type,
89517
- Y.createRelativePositionFromJSON(aw.cursor.head),
90209
+ Y.createRelativePositionFromJSON(awState.cursor.head),
89518
90210
  ystate.binding.mapping
89519
90211
  );
89520
90212
  if (anchor === null || head === null) return;
@@ -89526,9 +90218,9 @@ normalizeAwarenessStates_fn = function() {
89526
90218
  normalized.set(clientId, {
89527
90219
  clientId,
89528
90220
  user: {
89529
- name: aw.user?.name,
89530
- email: aw.user?.email,
89531
- color: aw.user?.color || __privateMethod$1(this, _PresentationEditor_instances, getFallbackColor_fn).call(this, clientId)
90221
+ name: awState.user?.name,
90222
+ email: awState.user?.email,
90223
+ color: awState.user?.color || __privateMethod$1(this, _PresentationEditor_instances, getFallbackColor_fn).call(this, clientId)
89532
90224
  },
89533
90225
  anchor: clampedAnchor,
89534
90226
  head: clampedHead,
@@ -89729,7 +90421,7 @@ renderRemoteSelection_fn = function(cursor) {
89729
90421
  if (!layout || !blocks || !measures) return;
89730
90422
  const start2 = Math.min(cursor.anchor, cursor.head);
89731
90423
  const end2 = Math.max(cursor.anchor, cursor.head);
89732
- const rects = selectionToRects(layout, blocks, measures, start2, end2) ?? [];
90424
+ const rects = selectionToRects(layout, blocks, measures, start2, end2, __privateGet$1(this, _pageGeometryHelper) ?? void 0) ?? [];
89733
90425
  const color = __privateMethod$1(this, _PresentationEditor_instances, getValidatedColor_fn).call(this, cursor);
89734
90426
  const opacity = __privateGet$1(this, _layoutOptions).presence?.highlightOpacity ?? 0.35;
89735
90427
  const pageHeight = layout.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
@@ -90089,15 +90781,25 @@ hitTestTable_fn = function(normalizedX, normalizedY) {
90089
90781
  const configuredPageSize = __privateGet$1(this, _layoutOptions).pageSize ?? DEFAULT_PAGE_SIZE;
90090
90782
  let pageY = 0;
90091
90783
  let pageHit = null;
90092
- for (let i = 0; i < layout.pages.length; i++) {
90093
- const page = layout.pages[i];
90094
- const pageHeight = page.size?.h ?? configuredPageSize.h;
90095
- const gap = __privateGet$1(this, _layoutOptions).virtualization?.gap ?? DEFAULT_PAGE_GAP;
90096
- if (normalizedY >= pageY && normalizedY < pageY + pageHeight) {
90097
- pageHit = { pageIndex: i, page };
90098
- break;
90784
+ const geometryHelper = __privateGet$1(this, _pageGeometryHelper);
90785
+ if (geometryHelper) {
90786
+ const idx = geometryHelper.getPageIndexAtY(normalizedY) ?? geometryHelper.getNearestPageIndex(normalizedY);
90787
+ if (idx != null && layout.pages[idx]) {
90788
+ pageHit = { pageIndex: idx, page: layout.pages[idx] };
90789
+ pageY = geometryHelper.getPageTop(idx);
90790
+ }
90791
+ }
90792
+ if (!pageHit) {
90793
+ const gap = layout.pageGap ?? __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this);
90794
+ for (let i = 0; i < layout.pages.length; i++) {
90795
+ const page = layout.pages[i];
90796
+ const pageHeight = page.size?.h ?? configuredPageSize.h;
90797
+ if (normalizedY >= pageY && normalizedY < pageY + pageHeight) {
90798
+ pageHit = { pageIndex: i, page };
90799
+ break;
90800
+ }
90801
+ pageY += pageHeight + gap;
90099
90802
  }
90100
- pageY += pageHeight + gap;
90101
90803
  }
90102
90804
  if (!pageHit) {
90103
90805
  return null;
@@ -90349,12 +91051,7 @@ rerender_fn = async function() {
90349
91051
  return;
90350
91052
  }
90351
91053
  ({ layout, measures } = result);
90352
- if (__privateGet$1(this, _layoutOptions).virtualization?.enabled) {
90353
- const gap = __privateGet$1(this, _layoutOptions).virtualization.gap ?? DEFAULT_VIRTUALIZED_PAGE_GAP;
90354
- layout.pageGap = Math.max(0, gap);
90355
- } else {
90356
- layout.pageGap = DEFAULT_PAGE_GAP;
90357
- }
91054
+ layout.pageGap = __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this);
90358
91055
  headerLayouts = result.headers;
90359
91056
  footerLayouts = result.footers;
90360
91057
  } catch (error) {
@@ -90371,6 +91068,17 @@ rerender_fn = async function() {
90371
91068
  __privateSet(this, _layoutState, { blocks, measures, layout, bookmarks, anchorMap });
90372
91069
  __privateSet(this, _headerLayoutResults, headerLayouts ?? null);
90373
91070
  __privateSet(this, _footerLayoutResults, footerLayouts ?? null);
91071
+ if (__privateGet$1(this, _layoutState).layout) {
91072
+ const pageGap = __privateGet$1(this, _layoutState).layout.pageGap ?? __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this);
91073
+ if (!__privateGet$1(this, _pageGeometryHelper)) {
91074
+ __privateSet(this, _pageGeometryHelper, new PageGeometryHelper({
91075
+ layout: __privateGet$1(this, _layoutState).layout,
91076
+ pageGap
91077
+ }));
91078
+ } else {
91079
+ __privateGet$1(this, _pageGeometryHelper).updateLayout(__privateGet$1(this, _layoutState).layout, pageGap);
91080
+ }
91081
+ }
90374
91082
  await __privateMethod$1(this, _PresentationEditor_instances, layoutPerRIdHeaderFooters_fn).call(this, headerFooterInput, layout, sectionMetadata);
90375
91083
  __privateMethod$1(this, _PresentationEditor_instances, updateDecorationProviders_fn).call(this, layout);
90376
91084
  const painter = __privateMethod$1(this, _PresentationEditor_instances, ensurePainter_fn).call(this, blocks, measures);
@@ -90440,7 +91148,8 @@ ensurePainter_fn = function(blocks, measures) {
90440
91148
  pageStyles: __privateGet$1(this, _layoutOptions).pageStyles,
90441
91149
  headerProvider: __privateGet$1(this, _headerDecorationProvider),
90442
91150
  footerProvider: __privateGet$1(this, _footerDecorationProvider),
90443
- ruler: __privateGet$1(this, _layoutOptions).ruler
91151
+ ruler: __privateGet$1(this, _layoutOptions).ruler,
91152
+ pageGap: __privateGet$1(this, _layoutState).layout?.pageGap ?? __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this)
90444
91153
  }));
90445
91154
  }
90446
91155
  return __privateGet$1(this, _domPainter);
@@ -90528,7 +91237,14 @@ updateSelection_fn = function() {
90528
91237
  }
90529
91238
  return;
90530
91239
  }
90531
- const rects = selectionToRects(layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, from2, to) ?? [];
91240
+ const rects = selectionToRects(
91241
+ layout,
91242
+ __privateGet$1(this, _layoutState).blocks,
91243
+ __privateGet$1(this, _layoutState).measures,
91244
+ from2,
91245
+ to,
91246
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
91247
+ ) ?? [];
90532
91248
  let domStart = null;
90533
91249
  let domEnd = null;
90534
91250
  try {
@@ -90542,7 +91258,9 @@ updateSelection_fn = function() {
90542
91258
  const correctedRects = __privateMethod$1(this, _PresentationEditor_instances, applyDomCorrectionToRects_fn).call(this, rects, domStart, domEnd);
90543
91259
  try {
90544
91260
  __privateGet$1(this, _localSelectionLayer).innerHTML = "";
90545
- __privateMethod$1(this, _PresentationEditor_instances, renderSelectionRects_fn).call(this, correctedRects);
91261
+ if (correctedRects.length > 0) {
91262
+ __privateMethod$1(this, _PresentationEditor_instances, renderSelectionRects_fn).call(this, correctedRects);
91263
+ }
90546
91264
  } catch (error) {
90547
91265
  if (process$1$1.env.NODE_ENV === "development") {
90548
91266
  console.warn("[PresentationEditor] Failed to render selection rects:", error);
@@ -90734,8 +91452,10 @@ createDecorationProvider_fn = function(kind, layout) {
90734
91452
  const pageHeight2 = page?.size?.h ?? layout.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
90735
91453
  const margins2 = pageMargins ?? layout.pages[0]?.margins ?? __privateGet$1(this, _layoutOptions).margins ?? DEFAULT_MARGINS;
90736
91454
  const box2 = __privateMethod$1(this, _PresentationEditor_instances, computeDecorationBox_fn).call(this, kind, margins2, pageHeight2);
91455
+ const layoutMinY2 = rIdLayout.layout.minY ?? 0;
91456
+ const normalizedFragments2 = layoutMinY2 < 0 ? fragments2.map((f2) => ({ ...f2, y: f2.y - layoutMinY2 })) : fragments2;
90737
91457
  return {
90738
- fragments: fragments2,
91458
+ fragments: normalizedFragments2,
90739
91459
  height: box2.height,
90740
91460
  contentHeight: rIdLayout.layout.height ?? box2.height,
90741
91461
  offset: box2.offset,
@@ -90743,6 +91463,7 @@ createDecorationProvider_fn = function(kind, layout) {
90743
91463
  contentWidth: box2.width,
90744
91464
  headerId: sectionRId,
90745
91465
  sectionType: headerFooterType,
91466
+ minY: layoutMinY2,
90746
91467
  box: {
90747
91468
  x: box2.x,
90748
91469
  y: box2.offset,
@@ -90775,8 +91496,10 @@ createDecorationProvider_fn = function(kind, layout) {
90775
91496
  const box = __privateMethod$1(this, _PresentationEditor_instances, computeDecorationBox_fn).call(this, kind, margins, pageHeight);
90776
91497
  const fallbackId = __privateGet$1(this, _headerFooterManager)?.getVariantId(kind, headerFooterType);
90777
91498
  const finalHeaderId = sectionRId ?? fallbackId ?? void 0;
91499
+ const layoutMinY = variant.layout.minY ?? 0;
91500
+ const normalizedFragments = layoutMinY < 0 ? fragments.map((f2) => ({ ...f2, y: f2.y - layoutMinY })) : fragments;
90778
91501
  return {
90779
- fragments,
91502
+ fragments: normalizedFragments,
90780
91503
  height: box.height,
90781
91504
  contentHeight: variant.layout.height ?? box.height,
90782
91505
  offset: box.offset,
@@ -90784,6 +91507,7 @@ createDecorationProvider_fn = function(kind, layout) {
90784
91507
  contentWidth: box.width,
90785
91508
  headerId: finalHeaderId,
90786
91509
  sectionType: headerFooterType,
91510
+ minY: layoutMinY,
90787
91511
  box: {
90788
91512
  x: box.x,
90789
91513
  y: box.offset,
@@ -90898,7 +91622,9 @@ rebuildHeaderFooterRegions_fn = function(layout) {
90898
91622
  localX: footerPayload?.hitRegion?.x ?? footerBox.x,
90899
91623
  localY: footerPayload?.hitRegion?.y ?? footerBox.offset,
90900
91624
  width: footerPayload?.hitRegion?.width ?? footerBox.width,
90901
- height: footerPayload?.hitRegion?.height ?? footerBox.height
91625
+ height: footerPayload?.hitRegion?.height ?? footerBox.height,
91626
+ contentHeight: footerPayload?.contentHeight,
91627
+ minY: footerPayload?.minY
90902
91628
  });
90903
91629
  });
90904
91630
  };
@@ -91028,6 +91754,18 @@ enterHeaderFooterMode_fn = async function(region) {
91028
91754
  });
91029
91755
  return;
91030
91756
  }
91757
+ if (region.kind === "footer") {
91758
+ const editorContainer = editorHost.firstElementChild;
91759
+ if (editorContainer instanceof HTMLElement) {
91760
+ editorContainer.style.overflow = "visible";
91761
+ if (region.minY != null && region.minY < 0) {
91762
+ const shiftDown = Math.abs(region.minY);
91763
+ editorContainer.style.transform = `translateY(${shiftDown}px)`;
91764
+ } else {
91765
+ editorContainer.style.transform = "";
91766
+ }
91767
+ }
91768
+ }
91031
91769
  try {
91032
91770
  editor.setEditable(true);
91033
91771
  editor.setOptions({ documentMode: "editing" });
@@ -91310,6 +92048,15 @@ waitForPageMount_fn = async function(pageIndex, options = {}) {
91310
92048
  checkPage();
91311
92049
  });
91312
92050
  };
92051
+ getEffectivePageGap_fn = function() {
92052
+ if (__privateGet$1(this, _layoutOptions).virtualization?.enabled) {
92053
+ return Math.max(0, __privateGet$1(this, _layoutOptions).virtualization.gap ?? DEFAULT_VIRTUALIZED_PAGE_GAP);
92054
+ }
92055
+ if (__privateGet$1(this, _layoutOptions).layoutMode === "horizontal") {
92056
+ return DEFAULT_HORIZONTAL_PAGE_GAP;
92057
+ }
92058
+ return DEFAULT_PAGE_GAP;
92059
+ };
91313
92060
  getBodyPageHeight_fn = function() {
91314
92061
  return __privateGet$1(this, _layoutState).layout?.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
91315
92062
  };
@@ -91333,7 +92080,7 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91333
92080
  dy: domStart.y - layoutY
91334
92081
  };
91335
92082
  }
91336
- return rects.map((rect, idx) => {
92083
+ const corrected = rects.map((rect, idx) => {
91337
92084
  const delta = pageDelta[rect.pageIndex];
91338
92085
  let adjustedX = delta ? rect.x + delta.dx : rect.x;
91339
92086
  let adjustedY = delta ? rect.y + delta.dy : rect.y;
@@ -91348,6 +92095,7 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91348
92095
  }
91349
92096
  if (isLastRect && domEnd && rect.pageIndex === domEnd.pageIndex) {
91350
92097
  const endX = domEnd.x;
92098
+ adjustedX = Math.min(adjustedX, endX);
91351
92099
  adjustedWidth = Math.max(1, endX - adjustedX);
91352
92100
  }
91353
92101
  return {
@@ -91357,6 +92105,29 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91357
92105
  width: adjustedWidth
91358
92106
  };
91359
92107
  });
92108
+ const MAX_DELTA_PX = 12;
92109
+ let invalid = false;
92110
+ if (domStart && corrected[0]) {
92111
+ const dx = Math.abs(corrected[0].x - domStart.x);
92112
+ const dy = Math.abs(corrected[0].y - domStart.y);
92113
+ if (dx > MAX_DELTA_PX || dy > MAX_DELTA_PX) invalid = true;
92114
+ }
92115
+ if (domEnd && corrected[corrected.length - 1]) {
92116
+ const last = corrected[corrected.length - 1];
92117
+ const dx = Math.abs(last.x + last.width - domEnd.x);
92118
+ const dy = Math.abs(last.y - domEnd.y);
92119
+ if (dx > MAX_DELTA_PX || dy > MAX_DELTA_PX) invalid = true;
92120
+ }
92121
+ if (invalid) {
92122
+ console.warn("[SelectionOverlay] Suppressing selection render due to large DOM/Layout mismatch", {
92123
+ domStart,
92124
+ domEnd,
92125
+ rectStart: corrected[0],
92126
+ rectEnd: corrected[corrected.length - 1]
92127
+ });
92128
+ return [];
92129
+ }
92130
+ return corrected;
91360
92131
  };
91361
92132
  renderCellSelectionOverlay_fn = function(selection, layout) {
91362
92133
  const localSelectionLayer = __privateGet$1(this, _localSelectionLayer);
@@ -91640,7 +92411,7 @@ computeHeaderFooterSelectionRects_fn = function(from2, to) {
91640
92411
  return [];
91641
92412
  }
91642
92413
  if (!bodyLayout) return [];
91643
- const rects = selectionToRects(context.layout, context.blocks, context.measures, from2, to) ?? [];
92414
+ const rects = selectionToRects(context.layout, context.blocks, context.measures, from2, to, void 0) ?? [];
91644
92415
  const headerPageHeight = context.layout.pageSize?.h ?? context.region.height ?? 1;
91645
92416
  const bodyPageHeight = __privateMethod$1(this, _PresentationEditor_instances, getBodyPageHeight_fn).call(this);
91646
92417
  return rects.map((rect) => {
@@ -91923,8 +92694,8 @@ computeCaretLayoutRectGeometry_fn = function(pos, includeDomFallback = true) {
91923
92694
  const zoom2 = __privateGet$1(this, _layoutOptions).zoom ?? 1;
91924
92695
  let domCaretX2 = null;
91925
92696
  let domCaretY2 = null;
91926
- const spanEls2 = pageEl2?.querySelectorAll("span[data-pm-start][data-pm-end]") ?? [];
91927
- for (const spanEl of spanEls2) {
92697
+ const spanEls2 = pageEl2?.querySelectorAll("span[data-pm-start][data-pm-end]");
92698
+ for (const spanEl of Array.from(spanEls2 ?? [])) {
91928
92699
  const pmStart = Number(spanEl.dataset.pmStart);
91929
92700
  const pmEnd = Number(spanEl.dataset.pmEnd);
91930
92701
  if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
@@ -91976,8 +92747,8 @@ computeCaretLayoutRectGeometry_fn = function(pos, includeDomFallback = true) {
91976
92747
  const zoom = __privateGet$1(this, _layoutOptions).zoom ?? 1;
91977
92748
  let domCaretX = null;
91978
92749
  let domCaretY = null;
91979
- const spanEls = pageEl?.querySelectorAll("span[data-pm-start][data-pm-end]") ?? [];
91980
- for (const spanEl of spanEls) {
92750
+ const spanEls = pageEl?.querySelectorAll("span[data-pm-start][data-pm-end]");
92751
+ for (const spanEl of Array.from(spanEls ?? [])) {
91981
92752
  const pmStart = Number(spanEl.dataset.pmStart);
91982
92753
  const pmEnd = Number(spanEl.dataset.pmEnd);
91983
92754
  if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
@@ -92107,7 +92878,14 @@ getCurrentPageIndex_fn = function() {
92107
92878
  if (!layout || !selection) {
92108
92879
  return 0;
92109
92880
  }
92110
- const rects = selectionToRects(layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, selection.from, selection.to) ?? [];
92881
+ const rects = selectionToRects(
92882
+ layout,
92883
+ __privateGet$1(this, _layoutState).blocks,
92884
+ __privateGet$1(this, _layoutState).measures,
92885
+ selection.from,
92886
+ selection.to,
92887
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
92888
+ ) ?? [];
92111
92889
  if (rects.length > 0) {
92112
92890
  return rects[0]?.pageIndex ?? 0;
92113
92891
  }
@@ -97539,14 +98317,19 @@ const createCell = (cellType, cellContent = null) => {
97539
98317
  }
97540
98318
  return cellType.createAndFill();
97541
98319
  };
97542
- const createTableBorders = ({ size: size2 = 0.66665, color = "#000000" } = {}) => {
98320
+ const createTableBorders = (borderSpec = {}) => {
98321
+ borderSpec = {
98322
+ size: 0.66665,
98323
+ color: "#000000",
98324
+ ...borderSpec
98325
+ };
97543
98326
  return {
97544
- top: { size: size2, color },
97545
- left: { size: size2, color },
97546
- bottom: { size: size2, color },
97547
- right: { size: size2, color },
97548
- insideH: { size: size2, color },
97549
- insideV: { size: size2, color }
98327
+ top: borderSpec,
98328
+ left: borderSpec,
98329
+ bottom: borderSpec,
98330
+ right: borderSpec,
98331
+ insideH: borderSpec,
98332
+ insideV: borderSpec
97550
98333
  };
97551
98334
  };
97552
98335
  const createTable = (schema, rowsCount, colsCount, withHeaderRow, cellContent = null) => {
@@ -97674,12 +98457,17 @@ const deleteTableWhenSelected = ({ editor }) => {
97674
98457
  editor.commands.deleteTable();
97675
98458
  return true;
97676
98459
  };
97677
- const createCellBorders = ({ size: size2 = 0.66665, color = "#000000" } = {}) => {
98460
+ const createCellBorders = (borderSpec = {}) => {
98461
+ borderSpec = {
98462
+ size: 0.66665,
98463
+ color: "#000000",
98464
+ ...borderSpec
98465
+ };
97678
98466
  return {
97679
- top: { size: size2, color },
97680
- left: { size: size2, color },
97681
- bottom: { size: size2, color },
97682
- right: { size: size2, color }
98467
+ top: borderSpec,
98468
+ left: borderSpec,
98469
+ bottom: borderSpec,
98470
+ right: borderSpec
97683
98471
  };
97684
98472
  };
97685
98473
  function cellAround($pos) {
@@ -98446,13 +99234,20 @@ const Table = Node$1.create({
98446
99234
  if (["tableCell", "tableHeader"].includes(node.type.name)) {
98447
99235
  tr.setNodeMarkup(pos, void 0, {
98448
99236
  ...node.attrs,
98449
- borders: createCellBorders({ size: 0 })
99237
+ borders: createCellBorders({ size: 0, space: 0, val: "none", color: "auto" })
98450
99238
  });
98451
99239
  }
98452
99240
  });
98453
99241
  tr.setNodeMarkup(table.pos, void 0, {
98454
99242
  ...table.node.attrs,
98455
- borders: createTableBorders({ size: 0 })
99243
+ borders: createTableBorders({ size: 0 }),
99244
+ // TODO: This works around the issue that table borders are duplicated between
99245
+ // the attributes of the table and the tableProperties attribute.
99246
+ // This can be removed when the redundancy is eliminated.
99247
+ tableProperties: {
99248
+ ...table.node.attrs.tableProperties,
99249
+ borders: createTableBorders({ size: 0, space: 0, val: "none", color: "auto" })
99250
+ }
98456
99251
  });
98457
99252
  return true;
98458
99253
  }
@@ -122454,7 +123249,7 @@ const makeDefaultItems = ({
122454
123249
  }
122455
123250
  },
122456
123251
  {
122457
- label: toolbarTexts2.transparentBorders,
123252
+ label: toolbarTexts2.removeBorders,
122458
123253
  command: "deleteCellAndTableBorders",
122459
123254
  icon: toolbarIcons2.deleteBorders,
122460
123255
  bottomBorder: true,
@@ -123035,7 +123830,7 @@ const toolbarTexts = {
123035
123830
  deleteRow: "Delete row",
123036
123831
  deleteColumn: "Delete column",
123037
123832
  deleteTable: "Delete table",
123038
- transparentBorders: "Transparent borders",
123833
+ removeBorders: "Remove borders",
123039
123834
  mergeCells: "Merge cells",
123040
123835
  splitCell: "Split cell",
123041
123836
  fixTables: "Fix tables",
@@ -124073,7 +124868,7 @@ const TEXTS = {
124073
124868
  deleteRow: "Delete row",
124074
124869
  deleteColumn: "Delete column",
124075
124870
  deleteTable: "Delete table",
124076
- transparentBorders: "Transparent borders",
124871
+ removeBorders: "Remove borders",
124077
124872
  mergeCells: "Merge cells",
124078
124873
  splitCell: "Split cell",
124079
124874
  fixTables: "Fix tables",
@@ -124156,7 +124951,7 @@ const tableActionsOptions = [
124156
124951
  }
124157
124952
  },
124158
124953
  {
124159
- label: TEXTS.transparentBorders,
124954
+ label: TEXTS.removeBorders,
124160
124955
  command: "deleteCellAndTableBorders",
124161
124956
  icon: ICONS.deleteBorders,
124162
124957
  bottomBorder: true,