@harbour-enterprises/superdoc 1.0.0-beta.98 → 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 (29) hide show
  1. package/dist/chunks/{PdfViewer-1_KffD-j.es.js → PdfViewer-BKujh9gl.es.js} +1 -1
  2. package/dist/chunks/{PdfViewer-D1Ot32kX.cjs → PdfViewer-Cu04k0JZ.cjs} +1 -1
  3. package/dist/chunks/{index-CUO7gEi8.cjs → index-CZ4149Px.cjs} +5 -14
  4. package/dist/chunks/{index-CP2_WwLA.es.js → index-Cl0tjE1C.es.js} +5 -14
  5. package/dist/chunks/{index-Dg_sTYZK-D20z8mus.es.js → index-Dlj3l0Hk-BuYH_UIe.es.js} +1 -1
  6. package/dist/chunks/{index-Dg_sTYZK-DYDzxoXL.cjs → index-Dlj3l0Hk-CJ0YBOja.cjs} +1 -1
  7. package/dist/chunks/{super-editor.es-DN_dgBH0.cjs → super-editor.es-CjRtsxTt.cjs} +1102 -187
  8. package/dist/chunks/{super-editor.es-3dJOUw65.es.js → super-editor.es-D0WByw5h.es.js} +1102 -187
  9. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  10. package/dist/style.css +6 -6
  11. package/dist/super-editor/ai-writer.es.js +2 -2
  12. package/dist/super-editor/chunks/{converter-Oj-eTB79.js → converter-BS4FD8AG.js} +12 -6
  13. package/dist/super-editor/chunks/{docx-zipper-Dl188zQ3.js → docx-zipper-DpiCpt0d.js} +1 -1
  14. package/dist/super-editor/chunks/{editor-DBXoaaWP.js → editor-BeacbTQe.js} +1092 -179
  15. package/dist/super-editor/chunks/{index-Dg_sTYZK.js → index-Dlj3l0Hk.js} +1 -1
  16. package/dist/super-editor/chunks/{toolbar-PlGGj0Ew.js → toolbar-BNQDvBCn.js} +2 -2
  17. package/dist/super-editor/converter.es.js +1 -1
  18. package/dist/super-editor/docx-zipper.es.js +2 -2
  19. package/dist/super-editor/editor.es.js +3 -3
  20. package/dist/super-editor/file-zipper.es.js +1 -1
  21. package/dist/super-editor/super-editor.es.js +10 -10
  22. package/dist/super-editor/toolbar.es.js +2 -2
  23. package/dist/super-editor.cjs +1 -1
  24. package/dist/super-editor.es.js +1 -1
  25. package/dist/superdoc.cjs +2 -2
  26. package/dist/superdoc.es.js +2 -2
  27. package/dist/superdoc.umd.js +1106 -200
  28. package/dist/superdoc.umd.js.map +1 -1
  29. 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.98") {
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.98";
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-Dg_sTYZK-D20z8mus.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.98");
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
  };
@@ -74407,6 +74441,104 @@ function ensureRulerStyles(doc2) {
74407
74441
  doc2.head?.appendChild(styleEl);
74408
74442
  rulerStylesInjected = true;
74409
74443
  }
74444
+ const hashParagraphBorder$1 = (border) => {
74445
+ const parts = [];
74446
+ if (border.style !== void 0) parts.push(`s:${border.style}`);
74447
+ if (border.width !== void 0) parts.push(`w:${border.width}`);
74448
+ if (border.color !== void 0) parts.push(`c:${border.color}`);
74449
+ if (border.space !== void 0) parts.push(`sp:${border.space}`);
74450
+ return parts.join(",");
74451
+ };
74452
+ const hashParagraphBorders$1 = (borders) => {
74453
+ const parts = [];
74454
+ if (borders.top) parts.push(`t:[${hashParagraphBorder$1(borders.top)}]`);
74455
+ if (borders.right) parts.push(`r:[${hashParagraphBorder$1(borders.right)}]`);
74456
+ if (borders.bottom) parts.push(`b:[${hashParagraphBorder$1(borders.bottom)}]`);
74457
+ if (borders.left) parts.push(`l:[${hashParagraphBorder$1(borders.left)}]`);
74458
+ return parts.join(";");
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
+ };
74503
+ const hasStringProp = (run2, prop) => {
74504
+ return prop in run2 && typeof run2[prop] === "string";
74505
+ };
74506
+ const hasNumberProp = (run2, prop) => {
74507
+ return prop in run2 && typeof run2[prop] === "number";
74508
+ };
74509
+ const hasBooleanProp = (run2, prop) => {
74510
+ return prop in run2 && typeof run2[prop] === "boolean";
74511
+ };
74512
+ const getRunStringProp = (run2, prop) => {
74513
+ if (hasStringProp(run2, prop)) {
74514
+ return run2[prop];
74515
+ }
74516
+ return "";
74517
+ };
74518
+ const getRunNumberProp = (run2, prop) => {
74519
+ if (hasNumberProp(run2, prop)) {
74520
+ return run2[prop];
74521
+ }
74522
+ return 0;
74523
+ };
74524
+ const getRunBooleanProp = (run2, prop) => {
74525
+ if (hasBooleanProp(run2, prop)) {
74526
+ return run2[prop];
74527
+ }
74528
+ return false;
74529
+ };
74530
+ const getRunUnderlineStyle = (run2) => {
74531
+ if ("underline" in run2 && run2.underline && typeof run2.underline === "object") {
74532
+ return run2.underline.style ?? "";
74533
+ }
74534
+ return "";
74535
+ };
74536
+ const getRunUnderlineColor = (run2) => {
74537
+ if ("underline" in run2 && run2.underline && typeof run2.underline === "object") {
74538
+ return run2.underline.color ?? "";
74539
+ }
74540
+ return "";
74541
+ };
74410
74542
  function isMinimalWordLayout(value) {
74411
74543
  if (typeof value !== "object" || value === null) {
74412
74544
  return false;
@@ -74457,6 +74589,7 @@ function isMinimalWordLayout(value) {
74457
74589
  const LIST_MARKER_GAP$1 = 8;
74458
74590
  const DEFAULT_TAB_INTERVAL_PX$1 = 48;
74459
74591
  const DEFAULT_PAGE_HEIGHT_PX = 1056;
74592
+ const DEFAULT_VIRTUALIZED_PAGE_GAP$1 = 72;
74460
74593
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
74461
74594
  const COMMENT_INTERNAL_COLOR = "#078383";
74462
74595
  const COMMENT_INACTIVE_ALPHA = "22";
@@ -74586,10 +74719,11 @@ const _DomPainter = class _DomPainter2 {
74586
74719
  this.totalPages = 0;
74587
74720
  this.linkIdCounter = 0;
74588
74721
  this.pendingTooltips = /* @__PURE__ */ new WeakMap();
74722
+ this.pageGap = 24;
74589
74723
  this.virtualEnabled = false;
74590
74724
  this.virtualWindow = 5;
74591
74725
  this.virtualOverscan = 0;
74592
- this.virtualGap = 72;
74726
+ this.virtualGap = DEFAULT_VIRTUALIZED_PAGE_GAP$1;
74593
74727
  this.virtualPaddingTop = null;
74594
74728
  this.topSpacerEl = null;
74595
74729
  this.bottomSpacerEl = null;
@@ -74608,13 +74742,14 @@ const _DomPainter = class _DomPainter2 {
74608
74742
  this.blockLookup = this.buildBlockLookup(blocks, measures);
74609
74743
  this.headerProvider = options.headerProvider;
74610
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;
74611
74747
  if (this.layoutMode === "vertical" && options.virtualization?.enabled) {
74612
74748
  this.virtualEnabled = true;
74613
74749
  this.virtualWindow = Math.max(1, options.virtualization.window ?? 5);
74614
74750
  this.virtualOverscan = Math.max(0, options.virtualization.overscan ?? 0);
74615
- if (typeof options.virtualization.gap === "number" && Number.isFinite(options.virtualization.gap)) {
74616
- this.virtualGap = Math.max(0, options.virtualization.gap);
74617
- }
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;
74618
74753
  if (typeof options.virtualization.paddingTop === "number" && Number.isFinite(options.virtualization.paddingTop)) {
74619
74754
  this.virtualPaddingTop = Math.max(0, options.virtualization.paddingTop);
74620
74755
  }
@@ -74715,6 +74850,7 @@ const _DomPainter = class _DomPainter2 {
74715
74850
  const mode = this.layoutMode;
74716
74851
  if (mode === "horizontal") {
74717
74852
  applyStyles$2(mount2, containerStylesHorizontal);
74853
+ mount2.style.gap = `${this.pageGap}px`;
74718
74854
  this.renderHorizontal(layout, mount2);
74719
74855
  this.currentLayout = layout;
74720
74856
  this.pageStates = [];
@@ -74737,6 +74873,7 @@ const _DomPainter = class _DomPainter2 {
74737
74873
  this.changedBlocks.clear();
74738
74874
  return;
74739
74875
  }
74876
+ mount2.style.gap = `${this.pageGap}px`;
74740
74877
  if (!this.currentLayout || this.pageStates.length === 0) {
74741
74878
  this.fullRender(layout);
74742
74879
  } else {
@@ -75061,9 +75198,15 @@ const _DomPainter = class _DomPainter2 {
75061
75198
  const container = existing ?? this.doc.createElement("div");
75062
75199
  container.className = className;
75063
75200
  container.innerHTML = "";
75064
- const offset2 = data.offset ?? (kind === "footer" ? pageEl.clientHeight - data.height : 0);
75201
+ const baseOffset = data.offset ?? (kind === "footer" ? pageEl.clientHeight - data.height : 0);
75065
75202
  const marginLeft = data.marginLeft ?? 0;
75066
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
+ }
75067
75210
  container.style.position = "absolute";
75068
75211
  container.style.left = `${marginLeft}px`;
75069
75212
  if (typeof data.contentWidth === "number") {
@@ -75072,8 +75215,8 @@ const _DomPainter = class _DomPainter2 {
75072
75215
  container.style.width = `calc(100% - ${marginLeft + marginRight}px)`;
75073
75216
  }
75074
75217
  container.style.pointerEvents = "none";
75075
- container.style.height = `${data.height}px`;
75076
- container.style.top = `${Math.max(0, offset2)}px`;
75218
+ container.style.height = `${effectiveHeight}px`;
75219
+ container.style.top = `${Math.max(0, effectiveOffset)}px`;
75077
75220
  container.style.zIndex = "1";
75078
75221
  container.style.overflow = "visible";
75079
75222
  let footerYOffset = 0;
@@ -75082,7 +75225,7 @@ const _DomPainter = class _DomPainter2 {
75082
75225
  const fragHeight = "height" in f2 && typeof f2.height === "number" ? f2.height : this.estimateFragmentHeight(f2);
75083
75226
  return Math.max(max2, f2.y + Math.max(0, fragHeight));
75084
75227
  }, 0);
75085
- footerYOffset = Math.max(0, data.height - contentHeight);
75228
+ footerYOffset = Math.max(0, effectiveHeight - contentHeight);
75086
75229
  }
75087
75230
  const context = {
75088
75231
  pageNumber: page.number,
@@ -77486,7 +77629,7 @@ const deriveBlockVersion = (block) => {
77486
77629
  attrs.indent?.right ?? "",
77487
77630
  attrs.indent?.firstLine ?? "",
77488
77631
  attrs.indent?.hanging ?? "",
77489
- attrs.borders ? JSON.stringify(attrs.borders) : "",
77632
+ attrs.borders ? hashParagraphBorders$1(attrs.borders) : "",
77490
77633
  attrs.shading?.fill ?? "",
77491
77634
  attrs.shading?.color ?? "",
77492
77635
  attrs.direction ?? "",
@@ -77572,22 +77715,82 @@ const deriveBlockVersion = (block) => {
77572
77715
  hash2 = hashNumber(hash2, cellBlocks.length);
77573
77716
  hash2 = hashNumber(hash2, cell.rowSpan ?? 1);
77574
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
+ }
77575
77737
  for (const cellBlock of cellBlocks) {
77576
77738
  hash2 = hashString(hash2, cellBlock?.kind ?? "unknown");
77577
77739
  if (cellBlock?.kind === "paragraph") {
77578
- const runs = cellBlock.runs ?? [];
77740
+ const paragraphBlock = cellBlock;
77741
+ const runs = paragraphBlock.runs ?? [];
77579
77742
  hash2 = hashNumber(hash2, runs.length);
77743
+ const attrs = paragraphBlock.attrs;
77744
+ if (attrs) {
77745
+ hash2 = hashString(hash2, attrs.alignment ?? "");
77746
+ hash2 = hashNumber(hash2, attrs.spacing?.before ?? 0);
77747
+ hash2 = hashNumber(hash2, attrs.spacing?.after ?? 0);
77748
+ hash2 = hashNumber(hash2, attrs.spacing?.line ?? 0);
77749
+ hash2 = hashString(hash2, attrs.spacing?.lineRule ?? "");
77750
+ hash2 = hashNumber(hash2, attrs.indent?.left ?? 0);
77751
+ hash2 = hashNumber(hash2, attrs.indent?.right ?? 0);
77752
+ hash2 = hashNumber(hash2, attrs.indent?.firstLine ?? 0);
77753
+ hash2 = hashNumber(hash2, attrs.indent?.hanging ?? 0);
77754
+ hash2 = hashString(hash2, attrs.shading?.fill ?? "");
77755
+ hash2 = hashString(hash2, attrs.shading?.color ?? "");
77756
+ hash2 = hashString(hash2, attrs.direction ?? "");
77757
+ hash2 = hashString(hash2, attrs.rtl ? "1" : "");
77758
+ if (attrs.borders) {
77759
+ hash2 = hashString(hash2, hashParagraphBorders$1(attrs.borders));
77760
+ }
77761
+ }
77580
77762
  for (const run2 of runs) {
77581
77763
  if ("text" in run2 && typeof run2.text === "string") {
77582
77764
  hash2 = hashString(hash2, run2.text);
77583
77765
  }
77584
77766
  hash2 = hashNumber(hash2, run2.pmStart ?? -1);
77585
77767
  hash2 = hashNumber(hash2, run2.pmEnd ?? -1);
77768
+ hash2 = hashString(hash2, getRunStringProp(run2, "color"));
77769
+ hash2 = hashString(hash2, getRunStringProp(run2, "highlight"));
77770
+ hash2 = hashString(hash2, getRunBooleanProp(run2, "bold") ? "1" : "");
77771
+ hash2 = hashString(hash2, getRunBooleanProp(run2, "italic") ? "1" : "");
77772
+ hash2 = hashNumber(hash2, getRunNumberProp(run2, "fontSize"));
77773
+ hash2 = hashString(hash2, getRunStringProp(run2, "fontFamily"));
77774
+ hash2 = hashString(hash2, getRunUnderlineStyle(run2));
77775
+ hash2 = hashString(hash2, getRunUnderlineColor(run2));
77776
+ hash2 = hashString(hash2, getRunBooleanProp(run2, "strike") ? "1" : "");
77586
77777
  }
77587
77778
  }
77588
77779
  }
77589
77780
  }
77590
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
+ }
77591
77794
  return [block.id, tableBlock.rows.length, hash2.toString(16)].join("|");
77592
77795
  }
77593
77796
  return block.id;
@@ -77921,6 +78124,7 @@ const createDomPainter = (options) => {
77921
78124
  const painter = new DomPainter(options.blocks, options.measures, {
77922
78125
  pageStyles: options.pageStyles,
77923
78126
  layoutMode: options.layoutMode,
78127
+ pageGap: options.pageGap,
77924
78128
  headerProvider: options.headerProvider,
77925
78129
  footerProvider: options.footerProvider,
77926
78130
  virtualization: options.virtualization,
@@ -78339,7 +78543,7 @@ function isListItem(markerWidth, block) {
78339
78543
  return false;
78340
78544
  }
78341
78545
  const wordLayout = getWordLayoutConfig(block);
78342
- const hasListAttrs = block.attrs?.listItem != null || wordLayout?.marker != null;
78546
+ const hasListAttrs = block.attrs?.listItem != null || block.attrs?.numberingProperties != null || wordLayout?.marker != null;
78343
78547
  if (hasListAttrs) {
78344
78548
  return true;
78345
78549
  }
@@ -78769,7 +78973,7 @@ function computeNextSectionPropsAtBreak(blocks) {
78769
78973
  });
78770
78974
  return nextSectionPropsAtBreak;
78771
78975
  }
78772
- function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight = 0) {
78976
+ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight = 0, maxFooterContentHeight = 0) {
78773
78977
  const next = { ...state2 };
78774
78978
  const calcRequiredTopMargin = (headerDistance, baseTop) => {
78775
78979
  if (maxHeaderContentHeight > 0) {
@@ -78777,6 +78981,12 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78777
78981
  }
78778
78982
  return Math.max(baseTop, headerDistance);
78779
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
+ };
78780
78990
  if (block.attrs?.isFirstSection && !next.hasAnyPages) {
78781
78991
  if (block.pageSize) {
78782
78992
  next.activePageSize = { w: block.pageSize.w, h: block.pageSize.h };
@@ -78797,7 +79007,7 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78797
79007
  const footerDistance = Math.max(0, block.margins.footer);
78798
79008
  next.activeFooterDistance = footerDistance;
78799
79009
  next.pendingFooterDistance = footerDistance;
78800
- next.activeBottomMargin = Math.max(baseMargins.bottom, footerDistance);
79010
+ next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, baseMargins.bottom);
78801
79011
  next.pendingBottomMargin = next.activeBottomMargin;
78802
79012
  }
78803
79013
  if (block.columns) {
@@ -78820,8 +79030,14 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78820
79030
  next.pendingTopMargin = nextTop;
78821
79031
  next.pendingHeaderDistance = nextHeader;
78822
79032
  }
78823
- next.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
78824
- 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
+ }
78825
79041
  if (block.pageSize) {
78826
79042
  next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
78827
79043
  }
@@ -80421,7 +80637,7 @@ function layoutDocument(blocks, measures, options = {}) {
80421
80637
  if (contentWidth <= 0) {
80422
80638
  throw new Error("layoutDocument: pageSize and margins yield non-positive content area");
80423
80639
  }
80424
- const validateHeaderHeight = (height) => {
80640
+ const validateContentHeight = (height) => {
80425
80641
  if (height === void 0) return 0;
80426
80642
  if (!Number.isFinite(height) || height < 0) return 0;
80427
80643
  return height;
@@ -80429,15 +80645,25 @@ function layoutDocument(blocks, measures, options = {}) {
80429
80645
  const headerContentHeights = options.headerContentHeights;
80430
80646
  const maxHeaderContentHeight = headerContentHeights ? Math.max(
80431
80647
  0,
80432
- validateHeaderHeight(headerContentHeights.default),
80433
- validateHeaderHeight(headerContentHeights.first),
80434
- validateHeaderHeight(headerContentHeights.even),
80435
- validateHeaderHeight(headerContentHeights.odd)
80648
+ validateContentHeight(headerContentHeights.default),
80649
+ validateContentHeight(headerContentHeights.first),
80650
+ validateContentHeight(headerContentHeights.even),
80651
+ validateContentHeight(headerContentHeights.odd)
80436
80652
  ) : 0;
80437
80653
  const headerDistance = margins.header ?? margins.top;
80438
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;
80439
80665
  let activeTopMargin = effectiveTopMargin;
80440
- let activeBottomMargin = margins.bottom;
80666
+ let activeBottomMargin = effectiveBottomMargin;
80441
80667
  let pendingTopMargin = null;
80442
80668
  let pendingBottomMargin = null;
80443
80669
  let activeHeaderDistance = margins.header ?? margins.top;
@@ -80460,7 +80686,7 @@ function layoutDocument(blocks, measures, options = {}) {
80460
80686
  const nextSectionPropsAtBreak = computeNextSectionPropsAtBreak(blocks);
80461
80687
  const scheduleSectionBreakCompat = (block, state2, baseMargins) => {
80462
80688
  if (typeof scheduleSectionBreak === "function") {
80463
- return scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight);
80689
+ return scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight, maxFooterContentHeight);
80464
80690
  }
80465
80691
  const next = { ...state2 };
80466
80692
  if (block.attrs?.isFirstSection && !next.hasAnyPages) {
@@ -80481,10 +80707,11 @@ function layoutDocument(blocks, measures, options = {}) {
80481
80707
  next.pendingTopMargin = next.activeTopMargin;
80482
80708
  }
80483
80709
  if (block.margins?.footer !== void 0) {
80484
- const footerDistance = Math.max(0, block.margins.footer);
80485
- next.activeFooterDistance = footerDistance;
80486
- next.pendingFooterDistance = footerDistance;
80487
- 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);
80488
80715
  next.pendingBottomMargin = next.activeBottomMargin;
80489
80716
  }
80490
80717
  if (block.columns) {
@@ -80529,7 +80756,13 @@ function layoutDocument(blocks, measures, options = {}) {
80529
80756
  } else {
80530
80757
  next.pendingTopMargin = nextTop;
80531
80758
  }
80532
- 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
+ }
80533
80766
  if (block.pageSize) next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
80534
80767
  if (block.orientation) next.pendingOrientation = block.orientation;
80535
80768
  const sectionType = block.type ?? "continuous";
@@ -81280,10 +81513,6 @@ const resolveTrackedChangesEnabled = (attrs, defaultEnabled = true) => {
81280
81513
  }
81281
81514
  return attrs.trackedChangesEnabled !== false;
81282
81515
  };
81283
- const MAX_CACHE_SIZE$1 = 1e4;
81284
- const BYTES_PER_ENTRY_ESTIMATE = 5e3;
81285
- const NORMALIZED_WHITESPACE = /\s+/g;
81286
- const normalizeText = (text) => text.replace(NORMALIZED_WHITESPACE, " ");
81287
81516
  const hashParagraphBorder = (border) => {
81288
81517
  const parts = [];
81289
81518
  if (border.style !== void 0) parts.push(`s:${border.style}`);
@@ -81300,6 +81529,53 @@ const hashParagraphBorders = (borders) => {
81300
81529
  if (borders.left) parts.push(`l:[${hashParagraphBorder(borders.left)}]`);
81301
81530
  return parts.join(";");
81302
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
+ };
81575
+ const MAX_CACHE_SIZE$1 = 1e4;
81576
+ const BYTES_PER_ENTRY_ESTIMATE = 5e3;
81577
+ const NORMALIZED_WHITESPACE = /\s+/g;
81578
+ const normalizeText = (text) => text.replace(NORMALIZED_WHITESPACE, " ");
81303
81579
  const hashParagraphFrame = (frame) => {
81304
81580
  const parts = [];
81305
81581
  if (frame.wrap !== void 0) parts.push(`w:${frame.wrap}`);
@@ -81323,6 +81599,26 @@ const hashRuns = (block) => {
81323
81599
  continue;
81324
81600
  }
81325
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
+ }
81326
81622
  const cellBlocks = cell.blocks ?? (cell.paragraph ? [cell.paragraph] : []);
81327
81623
  for (const cellBlock of cellBlocks) {
81328
81624
  const paragraphBlock = cellBlock;
@@ -81336,12 +81632,14 @@ const hashRuns = (block) => {
81336
81632
  const color = "color" in run2 ? run2.color : void 0;
81337
81633
  const fontSize2 = "fontSize" in run2 ? run2.fontSize : void 0;
81338
81634
  const fontFamily2 = "fontFamily" in run2 ? run2.fontFamily : void 0;
81635
+ const highlight = "highlight" in run2 ? run2.highlight : void 0;
81339
81636
  const marks = [
81340
81637
  bold ? "b" : "",
81341
81638
  italic ? "i" : "",
81342
81639
  color ?? "",
81343
81640
  fontSize2 !== void 0 ? `fs:${fontSize2}` : "",
81344
- fontFamily2 ? `ff:${fontFamily2}` : ""
81641
+ fontFamily2 ? `ff:${fontFamily2}` : "",
81642
+ highlight ? `hl:${highlight}` : ""
81345
81643
  ].join("");
81346
81644
  let trackedKey = "";
81347
81645
  if (hasTrackedChange(run2)) {
@@ -81352,11 +81650,60 @@ const hashRuns = (block) => {
81352
81650
  }
81353
81651
  cellHashes.push(`${text}:${marks}${trackedKey}`);
81354
81652
  }
81653
+ if (paragraphBlock.attrs) {
81654
+ const attrs = paragraphBlock.attrs;
81655
+ const parts = [];
81656
+ if (attrs.alignment) parts.push(`al:${attrs.alignment}`);
81657
+ if (attrs.spacing) {
81658
+ const s2 = attrs.spacing;
81659
+ if (s2.before !== void 0) parts.push(`sb:${s2.before}`);
81660
+ if (s2.after !== void 0) parts.push(`sa:${s2.after}`);
81661
+ if (s2.line !== void 0) parts.push(`sl:${s2.line}`);
81662
+ if (s2.lineRule) parts.push(`sr:${s2.lineRule}`);
81663
+ }
81664
+ if (attrs.indent) {
81665
+ const ind = attrs.indent;
81666
+ if (ind.left !== void 0) parts.push(`il:${ind.left}`);
81667
+ if (ind.right !== void 0) parts.push(`ir:${ind.right}`);
81668
+ if (ind.firstLine !== void 0) parts.push(`if:${ind.firstLine}`);
81669
+ if (ind.hanging !== void 0) parts.push(`ih:${ind.hanging}`);
81670
+ }
81671
+ if (attrs.borders) {
81672
+ parts.push(`br:${hashParagraphBorders(attrs.borders)}`);
81673
+ }
81674
+ if (attrs.shading) {
81675
+ const sh = attrs.shading;
81676
+ if (sh.fill) parts.push(`shf:${sh.fill}`);
81677
+ if (sh.color) parts.push(`shc:${sh.color}`);
81678
+ }
81679
+ if (attrs.direction) parts.push(`dir:${attrs.direction}`);
81680
+ if (attrs.rtl) parts.push("rtl");
81681
+ if (parts.length > 0) {
81682
+ cellHashes.push(`pa:${parts.join(":")}`);
81683
+ }
81684
+ }
81355
81685
  }
81356
81686
  }
81357
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
+ }
81358
81705
  const contentHash = cellHashes.join("|");
81359
- return `${block.id}:table:${contentHash}`;
81706
+ return `${block.id}:table:${contentHash}${tableAttrsKey}`;
81360
81707
  }
81361
81708
  if (block.kind !== "paragraph") return block.id;
81362
81709
  const trackedMode = block.attrs && "trackedChangesMode" in block.attrs && block.attrs.trackedChangesMode || "review";
@@ -81375,12 +81722,14 @@ const hashRuns = (block) => {
81375
81722
  const color = "color" in run2 ? run2.color : void 0;
81376
81723
  const fontSize2 = "fontSize" in run2 ? run2.fontSize : void 0;
81377
81724
  const fontFamily2 = "fontFamily" in run2 ? run2.fontFamily : void 0;
81725
+ const highlight = "highlight" in run2 ? run2.highlight : void 0;
81378
81726
  const marks = [
81379
81727
  bold ? "b" : "",
81380
81728
  italic ? "i" : "",
81381
81729
  color ?? "",
81382
81730
  fontSize2 !== void 0 ? `fs:${fontSize2}` : "",
81383
- fontFamily2 ? `ff:${fontFamily2}` : ""
81731
+ fontFamily2 ? `ff:${fontFamily2}` : "",
81732
+ highlight ? `hl:${highlight}` : ""
81384
81733
  ].join("");
81385
81734
  let trackedKey = "";
81386
81735
  if (hasTrackedChange(run2)) {
@@ -82507,7 +82856,7 @@ const paragraphBlocksEqual = (a, b2) => {
82507
82856
  for (let i = 0; i < a.runs.length; i += 1) {
82508
82857
  const runA = a.runs[i];
82509
82858
  const runB = b2.runs[i];
82510
- if (("src" in runA || runA.kind === "lineBreak" || runA.kind === "break" || runA.kind === "fieldAnnotation" ? "" : runA.text) !== ("src" in runB || runB.kind === "lineBreak" || runB.kind === "break" || runB.kind === "fieldAnnotation" ? "" : runB.text) || ("bold" in runA ? runA.bold : false) !== ("bold" in runB ? runB.bold : false) || ("italic" in runA ? runA.italic : false) !== ("italic" in runB ? runB.italic : false) || ("color" in runA ? runA.color : void 0) !== ("color" in runB ? runB.color : void 0) || ("fontSize" in runA ? runA.fontSize : void 0) !== ("fontSize" in runB ? runB.fontSize : void 0) || ("fontFamily" in runA ? runA.fontFamily : void 0) !== ("fontFamily" in runB ? runB.fontFamily : void 0) || getTrackedChangeKey(runA) !== getTrackedChangeKey(runB)) {
82859
+ if (("src" in runA || runA.kind === "lineBreak" || runA.kind === "break" || runA.kind === "fieldAnnotation" ? "" : runA.text) !== ("src" in runB || runB.kind === "lineBreak" || runB.kind === "break" || runB.kind === "fieldAnnotation" ? "" : runB.text) || ("bold" in runA ? runA.bold : false) !== ("bold" in runB ? runB.bold : false) || ("italic" in runA ? runA.italic : false) !== ("italic" in runB ? runB.italic : false) || ("color" in runA ? runA.color : void 0) !== ("color" in runB ? runB.color : void 0) || ("fontSize" in runA ? runA.fontSize : void 0) !== ("fontSize" in runB ? runB.fontSize : void 0) || ("fontFamily" in runA ? runA.fontFamily : void 0) !== ("fontFamily" in runB ? runB.fontFamily : void 0) || ("highlight" in runA ? runA.highlight : void 0) !== ("highlight" in runB ? runB.highlight : void 0) || getTrackedChangeKey(runA) !== getTrackedChangeKey(runB)) {
82511
82860
  return false;
82512
82861
  }
82513
82862
  }
@@ -82876,17 +83225,67 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
82876
83225
  for (const [type2, value] of Object.entries(preHeaderLayouts)) {
82877
83226
  if (!isValidHeaderType(type2)) continue;
82878
83227
  if (value?.layout && typeof value.layout.height === "number") {
82879
- headerContentHeights[type2] = value.layout.height;
83228
+ const height = value.layout.height;
83229
+ if (Number.isFinite(height) && height >= 0) {
83230
+ headerContentHeights[type2] = height;
83231
+ }
82880
83232
  }
82881
83233
  }
82882
83234
  const hfPreEnd = performance.now();
82883
83235
  perfLog(`[Perf] 4.1.5 Pre-layout headers for height: ${(hfPreEnd - hfPreStart).toFixed(2)}ms`);
82884
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
+ }
82885
83282
  const layoutStart = performance.now();
82886
83283
  let layout = layoutDocument(nextBlocks, measures, {
82887
83284
  ...options,
82888
83285
  headerContentHeights,
82889
83286
  // Pass header heights to prevent overlap
83287
+ footerContentHeights,
83288
+ // Pass footer heights to prevent overlap
82890
83289
  remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
82891
83290
  });
82892
83291
  const layoutEnd = performance.now();
@@ -82935,6 +83334,8 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
82935
83334
  ...options,
82936
83335
  headerContentHeights,
82937
83336
  // Pass header heights to prevent overlap
83337
+ footerContentHeights,
83338
+ // Pass footer heights to prevent overlap
82938
83339
  remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
82939
83340
  });
82940
83341
  const relayoutEnd = performance.now();
@@ -83101,6 +83502,285 @@ async function remeasureAffectedBlocks(blocks, measures, affectedBlockIds, const
83101
83502
  }
83102
83503
  return updatedMeasures;
83103
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
+ }
83104
83784
  var Priority = /* @__PURE__ */ ((Priority2) => {
83105
83785
  Priority2[Priority2["P0"] = 0] = "P0";
83106
83786
  Priority2[Priority2["P1"] = 1] = "P1";
@@ -83394,18 +84074,41 @@ const rangesOverlap = (startA, endA, startB, endB) => {
83394
84074
  const effectiveEndA = endA ?? startA + 1;
83395
84075
  return effectiveEndA > startB && startA < endB;
83396
84076
  };
83397
- 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
+ }
83398
84089
  const pageGap = layout.pageGap ?? 0;
83399
84090
  let cursorY = 0;
84091
+ let nearestIndex = null;
84092
+ let nearestDistance = Infinity;
83400
84093
  for (let pageIndex = 0; pageIndex < layout.pages.length; pageIndex += 1) {
83401
84094
  const page = layout.pages[pageIndex];
84095
+ const pageHeight = page.size?.h ?? layout.pageSize.h;
83402
84096
  const top2 = cursorY;
83403
- const bottom2 = top2 + layout.pageSize.h;
84097
+ const bottom2 = top2 + pageHeight;
83404
84098
  if (point.y >= top2 && point.y < bottom2) {
83405
84099
  return { pageIndex, page };
83406
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
+ }
83407
84107
  cursorY = bottom2 + pageGap;
83408
84108
  }
84109
+ if (nearestIndex !== null) {
84110
+ return { pageIndex: nearestIndex, page: layout.pages[nearestIndex] };
84111
+ }
83409
84112
  return null;
83410
84113
  }
83411
84114
  function hitTestFragment(layout, pageHit, blocks, measures, point) {
@@ -83566,7 +84269,7 @@ const hitTestTableFragment = (pageHit, blocks, measures, point) => {
83566
84269
  }
83567
84270
  return null;
83568
84271
  };
83569
- function clickToPosition(layout, blocks, measures, containerPoint, domContainer, clientX, clientY) {
84272
+ function clickToPosition(layout, blocks, measures, containerPoint, domContainer, clientX, clientY, geometryHelper) {
83570
84273
  logClickStage("log", "entry", {
83571
84274
  pages: layout.pages.length
83572
84275
  });
@@ -83609,75 +84312,132 @@ function clickToPosition(layout, blocks, measures, containerPoint, domContainer,
83609
84312
  return { pos: domPos, blockId: "", pageIndex: 0, column: 0, lineIndex: -1 };
83610
84313
  }
83611
84314
  }
83612
- const pageHit = hitTestPage(layout, containerPoint);
84315
+ const pageHit = hitTestPage(layout, containerPoint, geometryHelper);
83613
84316
  if (!pageHit) {
83614
84317
  return null;
83615
84318
  }
83616
- const pageGap = layout.pageGap ?? 0;
84319
+ const pageTopY = geometryHelper ? geometryHelper.getPageTop(pageHit.pageIndex) : calculatePageTopFallback(layout, pageHit.pageIndex);
83617
84320
  const pageRelativePoint = {
83618
84321
  x: containerPoint.x,
83619
- y: containerPoint.y - pageHit.pageIndex * (layout.pageSize.h + pageGap)
84322
+ y: containerPoint.y - pageTopY
83620
84323
  };
83621
84324
  logClickStage("log", "page-hit", {
83622
84325
  pageIndex: pageHit.pageIndex
83623
84326
  });
83624
- 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
+ }
83625
84370
  if (fragmentHit) {
83626
84371
  const { fragment, block, measure, pageIndex, pageY } = fragmentHit;
83627
- if (fragment.kind !== "para" || measure.kind !== "paragraph" || block.kind !== "paragraph") {
83628
- logClickStage("warn", "fragment-type-mismatch", {
83629
- fragmentKind: fragment.kind,
83630
- measureKind: measure.kind,
83631
- 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
83632
84407
  });
83633
- return null;
83634
- }
83635
- const lineIndex = findLineIndexAtY(measure, pageY, fragment.fromLine, fragment.toLine);
83636
- if (lineIndex == null) {
83637
- logClickStage("warn", "no-line", {
84408
+ logClickStage("log", "success", {
83638
84409
  blockId: fragment.blockId
83639
84410
  });
83640
- return null;
83641
- }
83642
- const line = measure.lines[lineIndex];
83643
- const isRTL = isRtlBlock(block);
83644
- const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
83645
- const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
83646
- const paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
83647
- const paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
83648
- const totalIndent = paraIndentLeft + paraIndentRight;
83649
- const availableWidth = Math.max(0, fragment.width - totalIndent);
83650
- if (totalIndent > fragment.width) {
83651
- console.warn(
83652
- `[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.`
83653
- );
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
+ };
83654
84419
  }
83655
- const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
83656
- const isListItem3 = markerWidth > 0;
83657
- const alignmentOverride = isListItem3 ? "left" : void 0;
83658
- const pos = mapPointToPm(block, line, pageRelativePoint.x - fragment.x, isRTL, availableWidth, alignmentOverride);
83659
- if (pos == null) {
83660
- logClickStage("warn", "no-position", {
83661
- 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)
83662
84432
  });
83663
- return null;
84433
+ return {
84434
+ pos,
84435
+ blockId: fragment.blockId,
84436
+ pageIndex,
84437
+ column: determineColumn(layout, fragment.x),
84438
+ lineIndex: -1
84439
+ };
83664
84440
  }
83665
- const column = determineColumn(layout, fragment.x);
83666
- logPositionDebug({
83667
- blockId: fragment.blockId,
83668
- x: pageRelativePoint.x - fragment.x
83669
- });
83670
- logClickStage("log", "success", {
83671
- blockId: fragment.blockId
83672
- });
83673
- return {
83674
- pos,
83675
- blockId: fragment.blockId,
83676
- pageIndex,
83677
- column,
83678
- lineIndex
83679
- // lineIndex is now already absolute (within measure.lines), no need to add fragment.fromLine
83680
- };
83681
84441
  }
83682
84442
  const tableHit = hitTestTableFragment(pageHit, blocks, measures, pageRelativePoint);
83683
84443
  if (tableHit) {
@@ -83827,12 +84587,22 @@ const sumLineHeights = (measure, fromLine, toLine) => {
83827
84587
  }
83828
84588
  return height;
83829
84589
  };
83830
- 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) {
83831
84600
  if (from2 === to) {
83832
84601
  return [];
83833
84602
  }
83834
84603
  const rects = [];
83835
84604
  layout.pages.forEach((page, pageIndex) => {
84605
+ const pageTopY = geometryHelper ? geometryHelper.getPageTop(pageIndex) : calculatePageTopFallback(layout, pageIndex);
83836
84606
  page.fragments.forEach((fragment) => {
83837
84607
  if (fragment.kind === "para") {
83838
84608
  const blockIndex = findBlockIndexByFragmentId(blocks, fragment.blockId, { from: from2, to });
@@ -83874,12 +84644,16 @@ function selectionToRects(layout, blocks, measures, from2, to) {
83874
84644
  wordLayout
83875
84645
  });
83876
84646
  const rectX = fragment.x + indentAdjust + Math.min(startX, endX);
83877
- 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
+ );
83878
84652
  const lineOffset = lineHeightBeforeIndex(measure, index2) - lineHeightBeforeIndex(measure, fragment.fromLine);
83879
84653
  const rectY = fragment.y + lineOffset;
83880
84654
  rects.push({
83881
84655
  x: rectX,
83882
- y: rectY + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84656
+ y: rectY + pageTopY,
83883
84657
  width: rectWidth,
83884
84658
  height: line.lineHeight,
83885
84659
  pageIndex
@@ -84007,12 +84781,16 @@ function selectionToRects(layout, blocks, measures, from2, to) {
84007
84781
  wordLayout: cellWordLayout
84008
84782
  });
84009
84783
  const rectX = fragment.x + cellX + padding.left + textIndentAdjust + Math.min(startX, endX);
84010
- 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
+ );
84011
84789
  const lineOffset = lineHeightBeforeIndex(info.measure, index2) - lineHeightBeforeIndex(info.measure, info.startLine);
84012
84790
  const rectY = fragment.y + rowOffset + blockTopCursor + lineOffset;
84013
84791
  rects.push({
84014
84792
  x: rectX,
84015
- y: rectY + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84793
+ y: rectY + pageTopY,
84016
84794
  width: rectWidth,
84017
84795
  height: line.lineHeight,
84018
84796
  pageIndex
@@ -84041,7 +84819,7 @@ function selectionToRects(layout, blocks, measures, from2, to) {
84041
84819
  if (!rangesOverlap(pmRange.pmStart, pmRange.pmEnd, from2, to)) return;
84042
84820
  rects.push({
84043
84821
  x: fragment.x,
84044
- y: fragment.y + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84822
+ y: fragment.y + pageTopY,
84045
84823
  width: fragment.width,
84046
84824
  height: fragment.height,
84047
84825
  pageIndex
@@ -85157,7 +85935,7 @@ async function measureParagraphBlock(block, maxWidth) {
85157
85935
  const wordEndWithSpace = charPosInRun + (isLastWord ? word.length : word.length + 1);
85158
85936
  const effectiveMaxWidth = currentLine ? currentLine.maxWidth : getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
85159
85937
  if (wordOnlyWidth > effectiveMaxWidth && word.length > 1) {
85160
- if (currentLine && currentLine.width > 0 && currentLine.segments.length > 0) {
85938
+ if (currentLine && currentLine.width > 0 && currentLine.segments && currentLine.segments.length > 0) {
85161
85939
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
85162
85940
  const { spaceCount: _sc, ...lineBase } = currentLine;
85163
85941
  const completedLine = { ...lineBase, ...metrics };
@@ -85168,7 +85946,7 @@ async function measureParagraphBlock(block, maxWidth) {
85168
85946
  currentLine = null;
85169
85947
  }
85170
85948
  const lineMaxWidth = getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
85171
- const hasTabOnlyLine = currentLine && currentLine.segments.length === 0 && currentLine.width > 0;
85949
+ const hasTabOnlyLine = currentLine && currentLine.segments && currentLine.segments.length === 0 && currentLine.width > 0;
85172
85950
  const remainingWidthAfterTab = hasTabOnlyLine ? currentLine.maxWidth - currentLine.width : lineMaxWidth;
85173
85951
  const chunkWidth = hasTabOnlyLine ? Math.max(remainingWidthAfterTab, lineMaxWidth * 0.25) : lineMaxWidth;
85174
85952
  const chunks = breakWordIntoChunks(word, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run2);
@@ -85179,7 +85957,7 @@ async function measureParagraphBlock(block, maxWidth) {
85179
85957
  const chunkEndChar = chunkCharOffset + chunk.text.length;
85180
85958
  const isLastChunk = chunkIndex === chunks.length - 1;
85181
85959
  const isFirstChunk = chunkIndex === 0;
85182
- if (isFirstChunk && hasTabOnlyLine && currentLine) {
85960
+ if (isFirstChunk && hasTabOnlyLine && currentLine && currentLine.segments) {
85183
85961
  currentLine.toRun = runIndex;
85184
85962
  currentLine.toChar = chunkEndChar;
85185
85963
  currentLine.width = roundValue(currentLine.width + chunk.width);
@@ -86012,6 +86790,7 @@ const createHeaderFooterEditor = ({
86012
86790
  const fontSizeInPixles = fontSizePt * 1.3333;
86013
86791
  const lineHeight2 = fontSizeInPixles * 1.2;
86014
86792
  applyStyleIsolationClass(editorContainer);
86793
+ const isFooter = type2 === "footer";
86015
86794
  Object.assign(editorContainer.style, {
86016
86795
  padding: "0",
86017
86796
  margin: "0",
@@ -86026,7 +86805,7 @@ const createHeaderFooterEditor = ({
86026
86805
  fontFamily: fontFamilyCss || typeface,
86027
86806
  fontSize: `${fontSizeInPixles}px`,
86028
86807
  lineHeight: `${lineHeight2}px`,
86029
- overflow: "hidden",
86808
+ overflow: isFooter ? "visible" : "hidden",
86030
86809
  pointerEvents: "auto",
86031
86810
  // Critical: enables click interaction
86032
86811
  backgroundColor: "white"
@@ -87105,6 +87884,7 @@ class EditorOverlayManager {
87105
87884
  const editorContainer = __privateGet$1(this, _activeEditorHost).querySelector(".super-editor");
87106
87885
  if (editorContainer instanceof HTMLElement) {
87107
87886
  editorContainer.style.top = "0";
87887
+ editorContainer.style.transform = "";
87108
87888
  }
87109
87889
  }
87110
87890
  }
@@ -87280,6 +88060,7 @@ const DEFAULT_PAGE_SIZE = { w: 612, h: 792 };
87280
88060
  const DEFAULT_MARGINS = { top: 72, right: 72, bottom: 72, left: 72 };
87281
88061
  const DEFAULT_VIRTUALIZED_PAGE_GAP = 72;
87282
88062
  const DEFAULT_PAGE_GAP = 24;
88063
+ const DEFAULT_HORIZONTAL_PAGE_GAP = 20;
87283
88064
  const WORD_CHARACTER_REGEX = /[\p{L}\p{N}''_~-]/u;
87284
88065
  const MULTI_CLICK_TIME_THRESHOLD_MS = 400;
87285
88066
  const MULTI_CLICK_DISTANCE_THRESHOLD_PX = 5;
@@ -87303,6 +88084,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87303
88084
  __privateAdd$1(this, _layoutOptions);
87304
88085
  __privateAdd$1(this, _layoutState, { blocks: [], measures: [], layout: null, bookmarks: /* @__PURE__ */ new Map() });
87305
88086
  __privateAdd$1(this, _domPainter, null);
88087
+ __privateAdd$1(this, _pageGeometryHelper, null);
87306
88088
  __privateAdd$1(this, _dragHandlerCleanup, null);
87307
88089
  __privateAdd$1(this, _layoutError, null);
87308
88090
  __privateAdd$1(this, _layoutErrorState, "healthy");
@@ -87455,7 +88237,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87455
88237
  { x: x2, y: y2 },
87456
88238
  __privateGet$1(this, _viewportHost),
87457
88239
  event.clientX,
87458
- event.clientY
88240
+ event.clientY,
88241
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
87459
88242
  );
87460
88243
  const doc22 = __privateGet$1(this, _editor3).state?.doc;
87461
88244
  const hit = rawHit && doc22 ? { ...rawHit, pos: Math.max(0, Math.min(rawHit.pos, doc22.content.size)) } : rawHit;
@@ -87654,7 +88437,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87654
88437
  { x: normalized.x, y: normalized.y },
87655
88438
  __privateGet$1(this, _viewportHost),
87656
88439
  event.clientX,
87657
- event.clientY
88440
+ event.clientY,
88441
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
87658
88442
  );
87659
88443
  if (!hit) return;
87660
88444
  const currentTableHit = __privateMethod$1(this, _PresentationEditor_instances, hitTestTable_fn).call(this, normalized.x, normalized.y);
@@ -88501,7 +89285,14 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88501
89285
  return __privateMethod$1(this, _PresentationEditor_instances, computeHeaderFooterSelectionRects_fn).call(this, start2, end2);
88502
89286
  }
88503
89287
  if (!__privateGet$1(this, _layoutState).layout) return [];
88504
- 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
+ ) ?? [];
88505
89296
  return rects;
88506
89297
  };
88507
89298
  const rawRects = layoutRectSource();
@@ -88766,6 +89557,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88766
89557
  };
88767
89558
  }
88768
89559
  __privateSet(this, _domPainter, null);
89560
+ __privateSet(this, _pageGeometryHelper, null);
88769
89561
  __privateSet(this, _pendingDocChange, true);
88770
89562
  __privateMethod$1(this, _PresentationEditor_instances, scheduleRerender_fn).call(this);
88771
89563
  }
@@ -88798,7 +89590,16 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88798
89590
  x: localX,
88799
89591
  y: headerPageIndex * headerPageHeight + (localY - headerPageIndex * headerPageHeight)
88800
89592
  };
88801
- 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;
88802
89603
  return hit2;
88803
89604
  }
88804
89605
  if (!__privateGet$1(this, _layoutState).layout) {
@@ -88811,7 +89612,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88811
89612
  normalized,
88812
89613
  __privateGet$1(this, _viewportHost),
88813
89614
  clientX,
88814
- clientY
89615
+ clientY,
89616
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
88815
89617
  ) ?? null;
88816
89618
  return hit;
88817
89619
  }
@@ -89034,6 +89836,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
89034
89836
  __privateSet(this, _session, { mode: "body" });
89035
89837
  __privateSet(this, _activeHeaderFooterEditor, null);
89036
89838
  __privateSet(this, _domPainter, null);
89839
+ __privateSet(this, _pageGeometryHelper, null);
89037
89840
  (_a2 = __privateGet$1(this, _dragHandlerCleanup)) == null ? void 0 : _a2.call(this);
89038
89841
  __privateSet(this, _dragHandlerCleanup, null);
89039
89842
  __privateGet$1(this, _selectionOverlay2)?.remove();
@@ -89087,7 +89890,14 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
89087
89890
  if (!normalized) return false;
89088
89891
  const pmPos = __privateGet$1(this, _layoutState).bookmarks.get(normalized);
89089
89892
  if (pmPos == null) return false;
89090
- 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
+ ) ?? [];
89091
89901
  const rect = rects[0];
89092
89902
  let pageIndex = rect?.pageIndex ?? null;
89093
89903
  if (pageIndex == null) {
@@ -89151,6 +89961,7 @@ _hiddenHost = /* @__PURE__ */ new WeakMap();
89151
89961
  _layoutOptions = /* @__PURE__ */ new WeakMap();
89152
89962
  _layoutState = /* @__PURE__ */ new WeakMap();
89153
89963
  _domPainter = /* @__PURE__ */ new WeakMap();
89964
+ _pageGeometryHelper = /* @__PURE__ */ new WeakMap();
89154
89965
  _dragHandlerCleanup = /* @__PURE__ */ new WeakMap();
89155
89966
  _layoutError = /* @__PURE__ */ new WeakMap();
89156
89967
  _layoutErrorState = /* @__PURE__ */ new WeakMap();
@@ -89383,18 +90194,19 @@ normalizeAwarenessStates_fn = function() {
89383
90194
  const normalized = /* @__PURE__ */ new Map();
89384
90195
  states?.forEach((aw, clientId) => {
89385
90196
  if (clientId === provider.awareness?.clientID) return;
89386
- if (!aw.cursor) return;
90197
+ const awState = aw;
90198
+ if (!awState.cursor) return;
89387
90199
  try {
89388
90200
  const anchor = relativePositionToAbsolutePosition(
89389
90201
  ystate.doc,
89390
90202
  ystate.type,
89391
- Y.createRelativePositionFromJSON(aw.cursor.anchor),
90203
+ Y.createRelativePositionFromJSON(awState.cursor.anchor),
89392
90204
  ystate.binding.mapping
89393
90205
  );
89394
90206
  const head = relativePositionToAbsolutePosition(
89395
90207
  ystate.doc,
89396
90208
  ystate.type,
89397
- Y.createRelativePositionFromJSON(aw.cursor.head),
90209
+ Y.createRelativePositionFromJSON(awState.cursor.head),
89398
90210
  ystate.binding.mapping
89399
90211
  );
89400
90212
  if (anchor === null || head === null) return;
@@ -89406,9 +90218,9 @@ normalizeAwarenessStates_fn = function() {
89406
90218
  normalized.set(clientId, {
89407
90219
  clientId,
89408
90220
  user: {
89409
- name: aw.user?.name,
89410
- email: aw.user?.email,
89411
- 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)
89412
90224
  },
89413
90225
  anchor: clampedAnchor,
89414
90226
  head: clampedHead,
@@ -89609,7 +90421,7 @@ renderRemoteSelection_fn = function(cursor) {
89609
90421
  if (!layout || !blocks || !measures) return;
89610
90422
  const start2 = Math.min(cursor.anchor, cursor.head);
89611
90423
  const end2 = Math.max(cursor.anchor, cursor.head);
89612
- const rects = selectionToRects(layout, blocks, measures, start2, end2) ?? [];
90424
+ const rects = selectionToRects(layout, blocks, measures, start2, end2, __privateGet$1(this, _pageGeometryHelper) ?? void 0) ?? [];
89613
90425
  const color = __privateMethod$1(this, _PresentationEditor_instances, getValidatedColor_fn).call(this, cursor);
89614
90426
  const opacity = __privateGet$1(this, _layoutOptions).presence?.highlightOpacity ?? 0.35;
89615
90427
  const pageHeight = layout.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
@@ -89969,15 +90781,25 @@ hitTestTable_fn = function(normalizedX, normalizedY) {
89969
90781
  const configuredPageSize = __privateGet$1(this, _layoutOptions).pageSize ?? DEFAULT_PAGE_SIZE;
89970
90782
  let pageY = 0;
89971
90783
  let pageHit = null;
89972
- for (let i = 0; i < layout.pages.length; i++) {
89973
- const page = layout.pages[i];
89974
- const pageHeight = page.size?.h ?? configuredPageSize.h;
89975
- const gap = __privateGet$1(this, _layoutOptions).virtualization?.gap ?? DEFAULT_PAGE_GAP;
89976
- if (normalizedY >= pageY && normalizedY < pageY + pageHeight) {
89977
- pageHit = { pageIndex: i, page };
89978
- 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;
89979
90802
  }
89980
- pageY += pageHeight + gap;
89981
90803
  }
89982
90804
  if (!pageHit) {
89983
90805
  return null;
@@ -90229,12 +91051,7 @@ rerender_fn = async function() {
90229
91051
  return;
90230
91052
  }
90231
91053
  ({ layout, measures } = result);
90232
- if (__privateGet$1(this, _layoutOptions).virtualization?.enabled) {
90233
- const gap = __privateGet$1(this, _layoutOptions).virtualization.gap ?? DEFAULT_VIRTUALIZED_PAGE_GAP;
90234
- layout.pageGap = Math.max(0, gap);
90235
- } else {
90236
- layout.pageGap = DEFAULT_PAGE_GAP;
90237
- }
91054
+ layout.pageGap = __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this);
90238
91055
  headerLayouts = result.headers;
90239
91056
  footerLayouts = result.footers;
90240
91057
  } catch (error) {
@@ -90251,6 +91068,17 @@ rerender_fn = async function() {
90251
91068
  __privateSet(this, _layoutState, { blocks, measures, layout, bookmarks, anchorMap });
90252
91069
  __privateSet(this, _headerLayoutResults, headerLayouts ?? null);
90253
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
+ }
90254
91082
  await __privateMethod$1(this, _PresentationEditor_instances, layoutPerRIdHeaderFooters_fn).call(this, headerFooterInput, layout, sectionMetadata);
90255
91083
  __privateMethod$1(this, _PresentationEditor_instances, updateDecorationProviders_fn).call(this, layout);
90256
91084
  const painter = __privateMethod$1(this, _PresentationEditor_instances, ensurePainter_fn).call(this, blocks, measures);
@@ -90320,7 +91148,8 @@ ensurePainter_fn = function(blocks, measures) {
90320
91148
  pageStyles: __privateGet$1(this, _layoutOptions).pageStyles,
90321
91149
  headerProvider: __privateGet$1(this, _headerDecorationProvider),
90322
91150
  footerProvider: __privateGet$1(this, _footerDecorationProvider),
90323
- 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)
90324
91153
  }));
90325
91154
  }
90326
91155
  return __privateGet$1(this, _domPainter);
@@ -90408,7 +91237,14 @@ updateSelection_fn = function() {
90408
91237
  }
90409
91238
  return;
90410
91239
  }
90411
- 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
+ ) ?? [];
90412
91248
  let domStart = null;
90413
91249
  let domEnd = null;
90414
91250
  try {
@@ -90422,7 +91258,9 @@ updateSelection_fn = function() {
90422
91258
  const correctedRects = __privateMethod$1(this, _PresentationEditor_instances, applyDomCorrectionToRects_fn).call(this, rects, domStart, domEnd);
90423
91259
  try {
90424
91260
  __privateGet$1(this, _localSelectionLayer).innerHTML = "";
90425
- __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
+ }
90426
91264
  } catch (error) {
90427
91265
  if (process$1$1.env.NODE_ENV === "development") {
90428
91266
  console.warn("[PresentationEditor] Failed to render selection rects:", error);
@@ -90614,8 +91452,10 @@ createDecorationProvider_fn = function(kind, layout) {
90614
91452
  const pageHeight2 = page?.size?.h ?? layout.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
90615
91453
  const margins2 = pageMargins ?? layout.pages[0]?.margins ?? __privateGet$1(this, _layoutOptions).margins ?? DEFAULT_MARGINS;
90616
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;
90617
91457
  return {
90618
- fragments: fragments2,
91458
+ fragments: normalizedFragments2,
90619
91459
  height: box2.height,
90620
91460
  contentHeight: rIdLayout.layout.height ?? box2.height,
90621
91461
  offset: box2.offset,
@@ -90623,6 +91463,7 @@ createDecorationProvider_fn = function(kind, layout) {
90623
91463
  contentWidth: box2.width,
90624
91464
  headerId: sectionRId,
90625
91465
  sectionType: headerFooterType,
91466
+ minY: layoutMinY2,
90626
91467
  box: {
90627
91468
  x: box2.x,
90628
91469
  y: box2.offset,
@@ -90655,8 +91496,10 @@ createDecorationProvider_fn = function(kind, layout) {
90655
91496
  const box = __privateMethod$1(this, _PresentationEditor_instances, computeDecorationBox_fn).call(this, kind, margins, pageHeight);
90656
91497
  const fallbackId = __privateGet$1(this, _headerFooterManager)?.getVariantId(kind, headerFooterType);
90657
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;
90658
91501
  return {
90659
- fragments,
91502
+ fragments: normalizedFragments,
90660
91503
  height: box.height,
90661
91504
  contentHeight: variant.layout.height ?? box.height,
90662
91505
  offset: box.offset,
@@ -90664,6 +91507,7 @@ createDecorationProvider_fn = function(kind, layout) {
90664
91507
  contentWidth: box.width,
90665
91508
  headerId: finalHeaderId,
90666
91509
  sectionType: headerFooterType,
91510
+ minY: layoutMinY,
90667
91511
  box: {
90668
91512
  x: box.x,
90669
91513
  y: box.offset,
@@ -90778,7 +91622,9 @@ rebuildHeaderFooterRegions_fn = function(layout) {
90778
91622
  localX: footerPayload?.hitRegion?.x ?? footerBox.x,
90779
91623
  localY: footerPayload?.hitRegion?.y ?? footerBox.offset,
90780
91624
  width: footerPayload?.hitRegion?.width ?? footerBox.width,
90781
- height: footerPayload?.hitRegion?.height ?? footerBox.height
91625
+ height: footerPayload?.hitRegion?.height ?? footerBox.height,
91626
+ contentHeight: footerPayload?.contentHeight,
91627
+ minY: footerPayload?.minY
90782
91628
  });
90783
91629
  });
90784
91630
  };
@@ -90908,6 +91754,18 @@ enterHeaderFooterMode_fn = async function(region) {
90908
91754
  });
90909
91755
  return;
90910
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
+ }
90911
91769
  try {
90912
91770
  editor.setEditable(true);
90913
91771
  editor.setOptions({ documentMode: "editing" });
@@ -91190,6 +92048,15 @@ waitForPageMount_fn = async function(pageIndex, options = {}) {
91190
92048
  checkPage();
91191
92049
  });
91192
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
+ };
91193
92060
  getBodyPageHeight_fn = function() {
91194
92061
  return __privateGet$1(this, _layoutState).layout?.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
91195
92062
  };
@@ -91213,7 +92080,7 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91213
92080
  dy: domStart.y - layoutY
91214
92081
  };
91215
92082
  }
91216
- return rects.map((rect, idx) => {
92083
+ const corrected = rects.map((rect, idx) => {
91217
92084
  const delta = pageDelta[rect.pageIndex];
91218
92085
  let adjustedX = delta ? rect.x + delta.dx : rect.x;
91219
92086
  let adjustedY = delta ? rect.y + delta.dy : rect.y;
@@ -91228,6 +92095,7 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91228
92095
  }
91229
92096
  if (isLastRect && domEnd && rect.pageIndex === domEnd.pageIndex) {
91230
92097
  const endX = domEnd.x;
92098
+ adjustedX = Math.min(adjustedX, endX);
91231
92099
  adjustedWidth = Math.max(1, endX - adjustedX);
91232
92100
  }
91233
92101
  return {
@@ -91237,6 +92105,29 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91237
92105
  width: adjustedWidth
91238
92106
  };
91239
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;
91240
92131
  };
91241
92132
  renderCellSelectionOverlay_fn = function(selection, layout) {
91242
92133
  const localSelectionLayer = __privateGet$1(this, _localSelectionLayer);
@@ -91520,7 +92411,7 @@ computeHeaderFooterSelectionRects_fn = function(from2, to) {
91520
92411
  return [];
91521
92412
  }
91522
92413
  if (!bodyLayout) return [];
91523
- 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) ?? [];
91524
92415
  const headerPageHeight = context.layout.pageSize?.h ?? context.region.height ?? 1;
91525
92416
  const bodyPageHeight = __privateMethod$1(this, _PresentationEditor_instances, getBodyPageHeight_fn).call(this);
91526
92417
  return rects.map((rect) => {
@@ -91803,8 +92694,8 @@ computeCaretLayoutRectGeometry_fn = function(pos, includeDomFallback = true) {
91803
92694
  const zoom2 = __privateGet$1(this, _layoutOptions).zoom ?? 1;
91804
92695
  let domCaretX2 = null;
91805
92696
  let domCaretY2 = null;
91806
- const spanEls2 = pageEl2?.querySelectorAll("span[data-pm-start][data-pm-end]") ?? [];
91807
- 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 ?? [])) {
91808
92699
  const pmStart = Number(spanEl.dataset.pmStart);
91809
92700
  const pmEnd = Number(spanEl.dataset.pmEnd);
91810
92701
  if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
@@ -91856,8 +92747,8 @@ computeCaretLayoutRectGeometry_fn = function(pos, includeDomFallback = true) {
91856
92747
  const zoom = __privateGet$1(this, _layoutOptions).zoom ?? 1;
91857
92748
  let domCaretX = null;
91858
92749
  let domCaretY = null;
91859
- const spanEls = pageEl?.querySelectorAll("span[data-pm-start][data-pm-end]") ?? [];
91860
- 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 ?? [])) {
91861
92752
  const pmStart = Number(spanEl.dataset.pmStart);
91862
92753
  const pmEnd = Number(spanEl.dataset.pmEnd);
91863
92754
  if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
@@ -91987,7 +92878,14 @@ getCurrentPageIndex_fn = function() {
91987
92878
  if (!layout || !selection) {
91988
92879
  return 0;
91989
92880
  }
91990
- 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
+ ) ?? [];
91991
92889
  if (rects.length > 0) {
91992
92890
  return rects[0]?.pageIndex ?? 0;
91993
92891
  }
@@ -97419,14 +98317,19 @@ const createCell = (cellType, cellContent = null) => {
97419
98317
  }
97420
98318
  return cellType.createAndFill();
97421
98319
  };
97422
- const createTableBorders = ({ size: size2 = 0.66665, color = "#000000" } = {}) => {
98320
+ const createTableBorders = (borderSpec = {}) => {
98321
+ borderSpec = {
98322
+ size: 0.66665,
98323
+ color: "#000000",
98324
+ ...borderSpec
98325
+ };
97423
98326
  return {
97424
- top: { size: size2, color },
97425
- left: { size: size2, color },
97426
- bottom: { size: size2, color },
97427
- right: { size: size2, color },
97428
- insideH: { size: size2, color },
97429
- insideV: { size: size2, color }
98327
+ top: borderSpec,
98328
+ left: borderSpec,
98329
+ bottom: borderSpec,
98330
+ right: borderSpec,
98331
+ insideH: borderSpec,
98332
+ insideV: borderSpec
97430
98333
  };
97431
98334
  };
97432
98335
  const createTable = (schema, rowsCount, colsCount, withHeaderRow, cellContent = null) => {
@@ -97554,12 +98457,17 @@ const deleteTableWhenSelected = ({ editor }) => {
97554
98457
  editor.commands.deleteTable();
97555
98458
  return true;
97556
98459
  };
97557
- const createCellBorders = ({ size: size2 = 0.66665, color = "#000000" } = {}) => {
98460
+ const createCellBorders = (borderSpec = {}) => {
98461
+ borderSpec = {
98462
+ size: 0.66665,
98463
+ color: "#000000",
98464
+ ...borderSpec
98465
+ };
97558
98466
  return {
97559
- top: { size: size2, color },
97560
- left: { size: size2, color },
97561
- bottom: { size: size2, color },
97562
- right: { size: size2, color }
98467
+ top: borderSpec,
98468
+ left: borderSpec,
98469
+ bottom: borderSpec,
98470
+ right: borderSpec
97563
98471
  };
97564
98472
  };
97565
98473
  function cellAround($pos) {
@@ -98326,13 +99234,20 @@ const Table = Node$1.create({
98326
99234
  if (["tableCell", "tableHeader"].includes(node.type.name)) {
98327
99235
  tr.setNodeMarkup(pos, void 0, {
98328
99236
  ...node.attrs,
98329
- borders: createCellBorders({ size: 0 })
99237
+ borders: createCellBorders({ size: 0, space: 0, val: "none", color: "auto" })
98330
99238
  });
98331
99239
  }
98332
99240
  });
98333
99241
  tr.setNodeMarkup(table.pos, void 0, {
98334
99242
  ...table.node.attrs,
98335
- 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
+ }
98336
99251
  });
98337
99252
  return true;
98338
99253
  }
@@ -122334,7 +123249,7 @@ const makeDefaultItems = ({
122334
123249
  }
122335
123250
  },
122336
123251
  {
122337
- label: toolbarTexts2.transparentBorders,
123252
+ label: toolbarTexts2.removeBorders,
122338
123253
  command: "deleteCellAndTableBorders",
122339
123254
  icon: toolbarIcons2.deleteBorders,
122340
123255
  bottomBorder: true,
@@ -122915,7 +123830,7 @@ const toolbarTexts = {
122915
123830
  deleteRow: "Delete row",
122916
123831
  deleteColumn: "Delete column",
122917
123832
  deleteTable: "Delete table",
122918
- transparentBorders: "Transparent borders",
123833
+ removeBorders: "Remove borders",
122919
123834
  mergeCells: "Merge cells",
122920
123835
  splitCell: "Split cell",
122921
123836
  fixTables: "Fix tables",
@@ -123953,7 +124868,7 @@ const TEXTS = {
123953
124868
  deleteRow: "Delete row",
123954
124869
  deleteColumn: "Delete column",
123955
124870
  deleteTable: "Delete table",
123956
- transparentBorders: "Transparent borders",
124871
+ removeBorders: "Remove borders",
123957
124872
  mergeCells: "Merge cells",
123958
124873
  splitCell: "Split cell",
123959
124874
  fixTables: "Fix tables",
@@ -124036,7 +124951,7 @@ const tableActionsOptions = [
124036
124951
  }
124037
124952
  },
124038
124953
  {
124039
- label: TEXTS.transparentBorders,
124954
+ label: TEXTS.removeBorders,
124040
124955
  command: "deleteCellAndTableBorders",
124041
124956
  icon: ICONS.deleteBorders,
124042
124957
  bottomBorder: true,