@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
@@ -39792,7 +39792,7 @@ function importCommentData({ docx, editor, converter }) {
39792
39792
  const trackedDeletedText = attributes["custom:trackedDeletedText"] !== "null" ? attributes["custom:trackedDeletedText"] : null;
39793
39793
  const date = new Date(createdDate);
39794
39794
  const unixTimestampMs = date.getTime();
39795
- const parsedComment = nodeListHandler.handler({
39795
+ const parsedElements = nodeListHandler.handler({
39796
39796
  nodes: el.elements,
39797
39797
  nodeListHandler,
39798
39798
  docx,
@@ -39800,7 +39800,7 @@ function importCommentData({ docx, editor, converter }) {
39800
39800
  converter,
39801
39801
  path: [el]
39802
39802
  });
39803
- const { attrs } = parsedComment[0];
39803
+ const { attrs } = parsedElements[0];
39804
39804
  const paraId = attrs["w14:paraId"];
39805
39805
  return {
39806
39806
  commentId: internalId || v4(),
@@ -39808,7 +39808,8 @@ function importCommentData({ docx, editor, converter }) {
39808
39808
  creatorName: authorName,
39809
39809
  creatorEmail: authorEmail,
39810
39810
  createdTime: unixTimestampMs,
39811
- textJson: parsedComment[0],
39811
+ textJson: parsedElements[0],
39812
+ elements: parsedElements,
39812
39813
  initials,
39813
39814
  paraId,
39814
39815
  trackedChange,
@@ -39834,7 +39835,12 @@ const generateCommentsWithExtendedData = ({ docx, comments }) => {
39834
39835
  const { elements = [] } = initialElements[0] ?? {};
39835
39836
  const commentEx = elements.filter((el) => el.name === "w15:commentEx");
39836
39837
  return comments.map((comment) => {
39837
- const extendedDef = commentEx.find((ce2) => ce2.attributes["w15:paraId"] === comment.paraId);
39838
+ const extendedDef = commentEx.find((ce2) => {
39839
+ const isIncludedInCommentElements = comment.elements?.some(
39840
+ (el) => el.attrs?.["w14:paraId"] === ce2.attributes["w15:paraId"]
39841
+ );
39842
+ return isIncludedInCommentElements;
39843
+ });
39838
39844
  if (!extendedDef) return { ...comment, isDone: comment.isDone ?? false };
39839
39845
  const { isDone, paraIdParent } = getExtendedDetails(extendedDef);
39840
39846
  let parentComment;
@@ -41955,7 +41961,7 @@ const updateCommentsIdsAndExtensible = (comments = [], commentsIds, extensible)
41955
41961
  name: "w16cex:commentExtensible",
41956
41962
  attributes: {
41957
41963
  "w16cex:durableId": newDurableId,
41958
- "w16cex:dateUtc": toIsoNoFractional()
41964
+ "w16cex:dateUtc": toIsoNoFractional(comment.createdTime)
41959
41965
  }
41960
41966
  };
41961
41967
  extensibleUpdated.elements[0].elements.push(newExtensible);
@@ -42421,7 +42427,7 @@ const _SuperConverter = class _SuperConverter2 {
42421
42427
  static getStoredSuperdocVersion(docx) {
42422
42428
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
42423
42429
  }
42424
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-beta.98") {
42430
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.0.0-next.1") {
42425
42431
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
42426
42432
  }
42427
42433
  /**
@@ -45733,7 +45739,7 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
45733
45739
  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);
45734
45740
  var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
45735
45741
  var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
45736
- 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;
45742
+ 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;
45737
45743
  var GOOD_LEAF_SIZE = 200;
45738
45744
  var RopeSequence = function RopeSequence2() {
45739
45745
  };
@@ -54817,6 +54823,14 @@ const toggleNode = (typeOrName, toggleTypeOrName, attrs = {}) => ({ state: state
54817
54823
  const selectAll = () => ({ state: state2, dispatch }) => selectAll$1(state2, dispatch);
54818
54824
  const deleteSelection = () => ({ state: state2, tr, dispatch }) => {
54819
54825
  const { from: from2, to, empty: empty2 } = state2.selection;
54826
+ if (typeof document !== "undefined" && document.getSelection) {
54827
+ const currentDomSelection = document.getSelection();
54828
+ const selectedLength = currentDomSelection?.toString?.().length;
54829
+ const isCollapsed = currentDomSelection?.isCollapsed;
54830
+ if (!isCollapsed && selectedLength === 1) {
54831
+ return false;
54832
+ }
54833
+ }
54820
54834
  if (empty2) {
54821
54835
  return deleteSelection$1(state2, dispatch);
54822
54836
  }
@@ -57116,12 +57130,14 @@ const prepareCommentsForImport = (doc2, tr, schema, converter) => {
57116
57130
  importedId: node.attrs["w:id"]
57117
57131
  });
57118
57132
  if (type2.name === "commentRangeStart") {
57119
- toMark.push({
57120
- commentId: resolvedCommentId,
57121
- importedId,
57122
- internal,
57123
- start: pos
57124
- });
57133
+ if (!matchingImportedComment?.isDone) {
57134
+ toMark.push({
57135
+ commentId: resolvedCommentId,
57136
+ importedId,
57137
+ internal,
57138
+ start: pos
57139
+ });
57140
+ }
57125
57141
  ensureFallbackComment({
57126
57142
  converter,
57127
57143
  matchingImportedComment,
@@ -59639,7 +59655,7 @@ const isHeadless = (editor) => {
59639
59655
  const shouldSkipNodeView = (editor) => {
59640
59656
  return isHeadless(editor);
59641
59657
  };
59642
- const summaryVersion = "1.0.0-beta.98";
59658
+ const summaryVersion = "1.0.0-next.1";
59643
59659
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
59644
59660
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
59645
59661
  function mapAttributes(attrs) {
@@ -59999,11 +60015,11 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
59999
60015
  if (!this.options.isNewFile || !this.options.collaborationProvider) return;
60000
60016
  const provider = this.options.collaborationProvider;
60001
60017
  const postSyncInit = () => {
60002
- provider.off("synced", postSyncInit);
60018
+ provider.off?.("synced", postSyncInit);
60003
60019
  __privateMethod$1(this, _Editor_instances, insertNewFileData_fn).call(this);
60004
60020
  };
60005
60021
  if (provider.synced) __privateMethod$1(this, _Editor_instances, insertNewFileData_fn).call(this);
60006
- else provider.on("synced", postSyncInit);
60022
+ else provider.on?.("synced", postSyncInit);
60007
60023
  }
60008
60024
  /**
60009
60025
  * Replace content of editor that was created with loadFromSchema option
@@ -60428,7 +60444,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60428
60444
  { default: remarkStringify },
60429
60445
  { default: remarkGfm }
60430
60446
  ] = await Promise.all([
60431
- Promise.resolve().then(() => require("./index-Dg_sTYZK-DYDzxoXL.cjs")),
60447
+ Promise.resolve().then(() => require("./index-Dlj3l0Hk-CJ0YBOja.cjs")),
60432
60448
  Promise.resolve().then(() => require("./index-DRCvimau-H4Ck3S9a.cjs")),
60433
60449
  Promise.resolve().then(() => require("./index-C_x_N6Uh-Db3CUJMX.cjs")),
60434
60450
  Promise.resolve().then(() => require("./index-D_sWOSiG-BtDZzJ6I.cjs")),
@@ -60633,7 +60649,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
60633
60649
  * Process collaboration migrations
60634
60650
  */
60635
60651
  processCollaborationMigrations() {
60636
- console.debug("[checkVersionMigrations] Current editor version", "1.0.0-beta.98");
60652
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.0-next.1");
60637
60653
  if (!this.options.ydoc) return;
60638
60654
  const metaMap = this.options.ydoc.getMap("meta");
60639
60655
  let docVersion = metaMap.get("version");
@@ -63748,6 +63764,7 @@ function hydrateImageBlocks(blocks, mediaFiles) {
63748
63764
  if (cellChanged) {
63749
63765
  return {
63750
63766
  ...cell,
63767
+ // Cast to expected type - hydrateBlock preserves block kinds, just hydrates image sources
63751
63768
  blocks: hydratedBlocks.length > 0 ? hydratedBlocks : cell.blocks,
63752
63769
  paragraph: hydratedParagraph
63753
63770
  };
@@ -67368,7 +67385,7 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
67368
67385
  };
67369
67386
  }
67370
67387
  const hasValidNumbering = rawNumberingProps && isValidNumberingId(rawNumberingProps.numId);
67371
- if (hasValidNumbering) {
67388
+ if (hasValidNumbering && rawNumberingProps) {
67372
67389
  const numberingProps = rawNumberingProps;
67373
67390
  const numId = numberingProps.numId;
67374
67391
  const ilvl = Number.isFinite(numberingProps.ilvl) ? Math.max(0, Math.floor(Number(numberingProps.ilvl))) : 0;
@@ -67408,6 +67425,8 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
67408
67425
  const resolvedCounterValue = path[path.length - 1] ?? counterValue;
67409
67426
  const enrichedNumberingProps = {
67410
67427
  ...numberingProps,
67428
+ numId: numberingProps.numId,
67429
+ ilvl: numberingProps.ilvl,
67411
67430
  path,
67412
67431
  counterValue: resolvedCounterValue
67413
67432
  };
@@ -69504,7 +69523,7 @@ const parseTableCell = (args) => {
69504
69523
  context.nextBlockId,
69505
69524
  context.positions
69506
69525
  );
69507
- if (drawingBlock) {
69526
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69508
69527
  blocks.push(drawingBlock);
69509
69528
  }
69510
69529
  continue;
@@ -69515,7 +69534,7 @@ const parseTableCell = (args) => {
69515
69534
  context.nextBlockId,
69516
69535
  context.positions
69517
69536
  );
69518
- if (drawingBlock) {
69537
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69519
69538
  blocks.push(drawingBlock);
69520
69539
  }
69521
69540
  continue;
@@ -69526,7 +69545,7 @@ const parseTableCell = (args) => {
69526
69545
  context.nextBlockId,
69527
69546
  context.positions
69528
69547
  );
69529
- if (drawingBlock) {
69548
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69530
69549
  blocks.push(drawingBlock);
69531
69550
  }
69532
69551
  continue;
@@ -69537,7 +69556,7 @@ const parseTableCell = (args) => {
69537
69556
  context.nextBlockId,
69538
69557
  context.positions
69539
69558
  );
69540
- if (drawingBlock) {
69559
+ if (drawingBlock && drawingBlock.kind === "drawing") {
69541
69560
  blocks.push(drawingBlock);
69542
69561
  }
69543
69562
  }
@@ -69992,7 +70011,19 @@ function toFlowBlocks(pmDoc, options) {
69992
70011
  bookmarks2,
69993
70012
  hyperlinkConfig2,
69994
70013
  themeColorsParam ?? themeColors,
69995
- paragraphConverter
70014
+ paragraphConverter,
70015
+ converterCtx ?? converterContext,
70016
+ {
70017
+ listCounterContext: { getListCounter, incrementListCounter, resetListCounter },
70018
+ converters: {
70019
+ paragraphToFlowBlocks: paragraphConverter,
70020
+ imageNodeToBlock,
70021
+ vectorShapeNodeToDrawingBlock,
70022
+ shapeGroupNodeToDrawingBlock,
70023
+ shapeContainerNodeToDrawingBlock,
70024
+ shapeTextboxNodeToDrawingBlock
70025
+ }
70026
+ }
69996
70027
  );
69997
70028
  const handlerContext = {
69998
70029
  blocks,
@@ -70013,6 +70044,7 @@ function toFlowBlocks(pmDoc, options) {
70013
70044
  currentParagraphIndex: 0
70014
70045
  },
70015
70046
  converters: {
70047
+ // Type assertion needed due to signature mismatch between actual function and type definition
70016
70048
  paragraphToFlowBlocks: paragraphConverter,
70017
70049
  tableNodeToBlock: tableConverter,
70018
70050
  imageNodeToBlock,
@@ -70108,6 +70140,7 @@ function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaul
70108
70140
  {
70109
70141
  listCounterContext,
70110
70142
  converters: {
70143
+ // Type assertion needed due to signature mismatch between actual function and type definition
70111
70144
  paragraphToFlowBlocks: paragraphToFlowBlocks$1,
70112
70145
  imageNodeToBlock,
70113
70146
  vectorShapeNodeToDrawingBlock,
@@ -70121,7 +70154,7 @@ function paragraphToFlowBlocks(para, nextBlockId, positions, defaultFont, defaul
70121
70154
  converterContext
70122
70155
  );
70123
70156
  }
70124
- function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize, styleContext, trackedChanges, bookmarks, hyperlinkConfig, themeColors, converterContext) {
70157
+ function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize, styleContext, trackedChanges, bookmarks, hyperlinkConfig, themeColors, _paragraphToFlowBlocksParam, converterContext, options) {
70125
70158
  return tableNodeToBlock$1(
70126
70159
  node,
70127
70160
  nextBlockId,
@@ -70135,8 +70168,9 @@ function tableNodeToBlock(node, nextBlockId, positions, defaultFont, defaultSize
70135
70168
  themeColors,
70136
70169
  paragraphToFlowBlocks,
70137
70170
  converterContext,
70138
- {
70171
+ options ?? {
70139
70172
  converters: {
70173
+ // Type assertion needed due to signature mismatch between actual function and type definition
70140
70174
  paragraphToFlowBlocks: paragraphToFlowBlocks$1,
70141
70175
  imageNodeToBlock,
70142
70176
  vectorShapeNodeToDrawingBlock,
@@ -72716,7 +72750,7 @@ const containerStyles = {
72716
72750
  alignItems: "center",
72717
72751
  background: "transparent",
72718
72752
  padding: "0",
72719
- gap: "24px",
72753
+ // gap is set dynamically by renderer based on pageGap option (default: 24px)
72720
72754
  overflowY: "auto"
72721
72755
  };
72722
72756
  const containerStylesHorizontal = {
@@ -72726,7 +72760,7 @@ const containerStylesHorizontal = {
72726
72760
  justifyContent: "safe center",
72727
72761
  background: "transparent",
72728
72762
  padding: "0",
72729
- gap: "20px",
72763
+ // gap is set dynamically by renderer based on pageGap option (default: 20px for horizontal)
72730
72764
  overflowX: "auto",
72731
72765
  minHeight: "100%"
72732
72766
  };
@@ -74424,6 +74458,104 @@ function ensureRulerStyles(doc2) {
74424
74458
  doc2.head?.appendChild(styleEl);
74425
74459
  rulerStylesInjected = true;
74426
74460
  }
74461
+ const hashParagraphBorder$1 = (border) => {
74462
+ const parts = [];
74463
+ if (border.style !== void 0) parts.push(`s:${border.style}`);
74464
+ if (border.width !== void 0) parts.push(`w:${border.width}`);
74465
+ if (border.color !== void 0) parts.push(`c:${border.color}`);
74466
+ if (border.space !== void 0) parts.push(`sp:${border.space}`);
74467
+ return parts.join(",");
74468
+ };
74469
+ const hashParagraphBorders$1 = (borders) => {
74470
+ const parts = [];
74471
+ if (borders.top) parts.push(`t:[${hashParagraphBorder$1(borders.top)}]`);
74472
+ if (borders.right) parts.push(`r:[${hashParagraphBorder$1(borders.right)}]`);
74473
+ if (borders.bottom) parts.push(`b:[${hashParagraphBorder$1(borders.bottom)}]`);
74474
+ if (borders.left) parts.push(`l:[${hashParagraphBorder$1(borders.left)}]`);
74475
+ return parts.join(";");
74476
+ };
74477
+ const isNoneBorder$1 = (value) => {
74478
+ return typeof value === "object" && value !== null && "none" in value && value.none === true;
74479
+ };
74480
+ const isBorderSpec$1 = (value) => {
74481
+ return typeof value === "object" && value !== null && !("none" in value);
74482
+ };
74483
+ const hashBorderSpec$1 = (border) => {
74484
+ const parts = [];
74485
+ if (border.style !== void 0) parts.push(`s:${border.style}`);
74486
+ if (border.width !== void 0) parts.push(`w:${border.width}`);
74487
+ if (border.color !== void 0) parts.push(`c:${border.color}`);
74488
+ if (border.space !== void 0) parts.push(`sp:${border.space}`);
74489
+ return parts.join(",");
74490
+ };
74491
+ const hashTableBorderValue$1 = (borderValue) => {
74492
+ if (borderValue === void 0) return "";
74493
+ if (borderValue === null) return "null";
74494
+ if (isNoneBorder$1(borderValue)) return "none";
74495
+ if (isBorderSpec$1(borderValue)) {
74496
+ return hashBorderSpec$1(borderValue);
74497
+ }
74498
+ return "";
74499
+ };
74500
+ const hashTableBorders$1 = (borders) => {
74501
+ if (!borders) return "";
74502
+ const parts = [];
74503
+ if (borders.top !== void 0) parts.push(`t:[${hashTableBorderValue$1(borders.top)}]`);
74504
+ if (borders.right !== void 0) parts.push(`r:[${hashTableBorderValue$1(borders.right)}]`);
74505
+ if (borders.bottom !== void 0) parts.push(`b:[${hashTableBorderValue$1(borders.bottom)}]`);
74506
+ if (borders.left !== void 0) parts.push(`l:[${hashTableBorderValue$1(borders.left)}]`);
74507
+ if (borders.insideH !== void 0) parts.push(`ih:[${hashTableBorderValue$1(borders.insideH)}]`);
74508
+ if (borders.insideV !== void 0) parts.push(`iv:[${hashTableBorderValue$1(borders.insideV)}]`);
74509
+ return parts.join(";");
74510
+ };
74511
+ const hashCellBorders$1 = (borders) => {
74512
+ if (!borders) return "";
74513
+ const parts = [];
74514
+ if (borders.top) parts.push(`t:[${hashBorderSpec$1(borders.top)}]`);
74515
+ if (borders.right) parts.push(`r:[${hashBorderSpec$1(borders.right)}]`);
74516
+ if (borders.bottom) parts.push(`b:[${hashBorderSpec$1(borders.bottom)}]`);
74517
+ if (borders.left) parts.push(`l:[${hashBorderSpec$1(borders.left)}]`);
74518
+ return parts.join(";");
74519
+ };
74520
+ const hasStringProp = (run2, prop) => {
74521
+ return prop in run2 && typeof run2[prop] === "string";
74522
+ };
74523
+ const hasNumberProp = (run2, prop) => {
74524
+ return prop in run2 && typeof run2[prop] === "number";
74525
+ };
74526
+ const hasBooleanProp = (run2, prop) => {
74527
+ return prop in run2 && typeof run2[prop] === "boolean";
74528
+ };
74529
+ const getRunStringProp = (run2, prop) => {
74530
+ if (hasStringProp(run2, prop)) {
74531
+ return run2[prop];
74532
+ }
74533
+ return "";
74534
+ };
74535
+ const getRunNumberProp = (run2, prop) => {
74536
+ if (hasNumberProp(run2, prop)) {
74537
+ return run2[prop];
74538
+ }
74539
+ return 0;
74540
+ };
74541
+ const getRunBooleanProp = (run2, prop) => {
74542
+ if (hasBooleanProp(run2, prop)) {
74543
+ return run2[prop];
74544
+ }
74545
+ return false;
74546
+ };
74547
+ const getRunUnderlineStyle = (run2) => {
74548
+ if ("underline" in run2 && run2.underline && typeof run2.underline === "object") {
74549
+ return run2.underline.style ?? "";
74550
+ }
74551
+ return "";
74552
+ };
74553
+ const getRunUnderlineColor = (run2) => {
74554
+ if ("underline" in run2 && run2.underline && typeof run2.underline === "object") {
74555
+ return run2.underline.color ?? "";
74556
+ }
74557
+ return "";
74558
+ };
74427
74559
  function isMinimalWordLayout(value) {
74428
74560
  if (typeof value !== "object" || value === null) {
74429
74561
  return false;
@@ -74474,6 +74606,7 @@ function isMinimalWordLayout(value) {
74474
74606
  const LIST_MARKER_GAP$1 = 8;
74475
74607
  const DEFAULT_TAB_INTERVAL_PX$1 = 48;
74476
74608
  const DEFAULT_PAGE_HEIGHT_PX = 1056;
74609
+ const DEFAULT_VIRTUALIZED_PAGE_GAP$1 = 72;
74477
74610
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
74478
74611
  const COMMENT_INTERNAL_COLOR = "#078383";
74479
74612
  const COMMENT_INACTIVE_ALPHA = "22";
@@ -74603,10 +74736,11 @@ const _DomPainter = class _DomPainter2 {
74603
74736
  this.totalPages = 0;
74604
74737
  this.linkIdCounter = 0;
74605
74738
  this.pendingTooltips = /* @__PURE__ */ new WeakMap();
74739
+ this.pageGap = 24;
74606
74740
  this.virtualEnabled = false;
74607
74741
  this.virtualWindow = 5;
74608
74742
  this.virtualOverscan = 0;
74609
- this.virtualGap = 72;
74743
+ this.virtualGap = DEFAULT_VIRTUALIZED_PAGE_GAP$1;
74610
74744
  this.virtualPaddingTop = null;
74611
74745
  this.topSpacerEl = null;
74612
74746
  this.bottomSpacerEl = null;
@@ -74625,13 +74759,14 @@ const _DomPainter = class _DomPainter2 {
74625
74759
  this.blockLookup = this.buildBlockLookup(blocks, measures);
74626
74760
  this.headerProvider = options.headerProvider;
74627
74761
  this.footerProvider = options.footerProvider;
74762
+ const defaultGap = this.layoutMode === "horizontal" ? 20 : 24;
74763
+ this.pageGap = typeof options.pageGap === "number" && Number.isFinite(options.pageGap) ? Math.max(0, options.pageGap) : defaultGap;
74628
74764
  if (this.layoutMode === "vertical" && options.virtualization?.enabled) {
74629
74765
  this.virtualEnabled = true;
74630
74766
  this.virtualWindow = Math.max(1, options.virtualization.window ?? 5);
74631
74767
  this.virtualOverscan = Math.max(0, options.virtualization.overscan ?? 0);
74632
- if (typeof options.virtualization.gap === "number" && Number.isFinite(options.virtualization.gap)) {
74633
- this.virtualGap = Math.max(0, options.virtualization.gap);
74634
- }
74768
+ const hasExplicitVirtualGap = typeof options.virtualization.gap === "number" && Number.isFinite(options.virtualization.gap);
74769
+ this.virtualGap = hasExplicitVirtualGap ? Math.max(0, options.virtualization.gap) : DEFAULT_VIRTUALIZED_PAGE_GAP$1;
74635
74770
  if (typeof options.virtualization.paddingTop === "number" && Number.isFinite(options.virtualization.paddingTop)) {
74636
74771
  this.virtualPaddingTop = Math.max(0, options.virtualization.paddingTop);
74637
74772
  }
@@ -74732,6 +74867,7 @@ const _DomPainter = class _DomPainter2 {
74732
74867
  const mode = this.layoutMode;
74733
74868
  if (mode === "horizontal") {
74734
74869
  applyStyles$2(mount2, containerStylesHorizontal);
74870
+ mount2.style.gap = `${this.pageGap}px`;
74735
74871
  this.renderHorizontal(layout, mount2);
74736
74872
  this.currentLayout = layout;
74737
74873
  this.pageStates = [];
@@ -74754,6 +74890,7 @@ const _DomPainter = class _DomPainter2 {
74754
74890
  this.changedBlocks.clear();
74755
74891
  return;
74756
74892
  }
74893
+ mount2.style.gap = `${this.pageGap}px`;
74757
74894
  if (!this.currentLayout || this.pageStates.length === 0) {
74758
74895
  this.fullRender(layout);
74759
74896
  } else {
@@ -75078,9 +75215,15 @@ const _DomPainter = class _DomPainter2 {
75078
75215
  const container = existing ?? this.doc.createElement("div");
75079
75216
  container.className = className;
75080
75217
  container.innerHTML = "";
75081
- const offset2 = data.offset ?? (kind === "footer" ? pageEl.clientHeight - data.height : 0);
75218
+ const baseOffset = data.offset ?? (kind === "footer" ? pageEl.clientHeight - data.height : 0);
75082
75219
  const marginLeft = data.marginLeft ?? 0;
75083
75220
  const marginRight = page.margins?.right ?? 0;
75221
+ let effectiveHeight = data.height;
75222
+ let effectiveOffset = baseOffset;
75223
+ if (kind === "footer" && typeof data.contentHeight === "number" && Number.isFinite(data.contentHeight) && data.contentHeight > 0 && data.contentHeight > data.height) {
75224
+ effectiveHeight = data.contentHeight;
75225
+ effectiveOffset = baseOffset - (data.contentHeight - data.height);
75226
+ }
75084
75227
  container.style.position = "absolute";
75085
75228
  container.style.left = `${marginLeft}px`;
75086
75229
  if (typeof data.contentWidth === "number") {
@@ -75089,8 +75232,8 @@ const _DomPainter = class _DomPainter2 {
75089
75232
  container.style.width = `calc(100% - ${marginLeft + marginRight}px)`;
75090
75233
  }
75091
75234
  container.style.pointerEvents = "none";
75092
- container.style.height = `${data.height}px`;
75093
- container.style.top = `${Math.max(0, offset2)}px`;
75235
+ container.style.height = `${effectiveHeight}px`;
75236
+ container.style.top = `${Math.max(0, effectiveOffset)}px`;
75094
75237
  container.style.zIndex = "1";
75095
75238
  container.style.overflow = "visible";
75096
75239
  let footerYOffset = 0;
@@ -75099,7 +75242,7 @@ const _DomPainter = class _DomPainter2 {
75099
75242
  const fragHeight = "height" in f2 && typeof f2.height === "number" ? f2.height : this.estimateFragmentHeight(f2);
75100
75243
  return Math.max(max2, f2.y + Math.max(0, fragHeight));
75101
75244
  }, 0);
75102
- footerYOffset = Math.max(0, data.height - contentHeight);
75245
+ footerYOffset = Math.max(0, effectiveHeight - contentHeight);
75103
75246
  }
75104
75247
  const context = {
75105
75248
  pageNumber: page.number,
@@ -77503,7 +77646,7 @@ const deriveBlockVersion = (block) => {
77503
77646
  attrs.indent?.right ?? "",
77504
77647
  attrs.indent?.firstLine ?? "",
77505
77648
  attrs.indent?.hanging ?? "",
77506
- attrs.borders ? JSON.stringify(attrs.borders) : "",
77649
+ attrs.borders ? hashParagraphBorders$1(attrs.borders) : "",
77507
77650
  attrs.shading?.fill ?? "",
77508
77651
  attrs.shading?.color ?? "",
77509
77652
  attrs.direction ?? "",
@@ -77589,22 +77732,82 @@ const deriveBlockVersion = (block) => {
77589
77732
  hash2 = hashNumber(hash2, cellBlocks.length);
77590
77733
  hash2 = hashNumber(hash2, cell.rowSpan ?? 1);
77591
77734
  hash2 = hashNumber(hash2, cell.colSpan ?? 1);
77735
+ if (cell.attrs) {
77736
+ const cellAttrs = cell.attrs;
77737
+ if (cellAttrs.borders) {
77738
+ hash2 = hashString(hash2, hashCellBorders$1(cellAttrs.borders));
77739
+ }
77740
+ if (cellAttrs.padding) {
77741
+ const p = cellAttrs.padding;
77742
+ hash2 = hashNumber(hash2, p.top ?? 0);
77743
+ hash2 = hashNumber(hash2, p.right ?? 0);
77744
+ hash2 = hashNumber(hash2, p.bottom ?? 0);
77745
+ hash2 = hashNumber(hash2, p.left ?? 0);
77746
+ }
77747
+ if (cellAttrs.verticalAlign) {
77748
+ hash2 = hashString(hash2, cellAttrs.verticalAlign);
77749
+ }
77750
+ if (cellAttrs.background) {
77751
+ hash2 = hashString(hash2, cellAttrs.background);
77752
+ }
77753
+ }
77592
77754
  for (const cellBlock of cellBlocks) {
77593
77755
  hash2 = hashString(hash2, cellBlock?.kind ?? "unknown");
77594
77756
  if (cellBlock?.kind === "paragraph") {
77595
- const runs = cellBlock.runs ?? [];
77757
+ const paragraphBlock = cellBlock;
77758
+ const runs = paragraphBlock.runs ?? [];
77596
77759
  hash2 = hashNumber(hash2, runs.length);
77760
+ const attrs = paragraphBlock.attrs;
77761
+ if (attrs) {
77762
+ hash2 = hashString(hash2, attrs.alignment ?? "");
77763
+ hash2 = hashNumber(hash2, attrs.spacing?.before ?? 0);
77764
+ hash2 = hashNumber(hash2, attrs.spacing?.after ?? 0);
77765
+ hash2 = hashNumber(hash2, attrs.spacing?.line ?? 0);
77766
+ hash2 = hashString(hash2, attrs.spacing?.lineRule ?? "");
77767
+ hash2 = hashNumber(hash2, attrs.indent?.left ?? 0);
77768
+ hash2 = hashNumber(hash2, attrs.indent?.right ?? 0);
77769
+ hash2 = hashNumber(hash2, attrs.indent?.firstLine ?? 0);
77770
+ hash2 = hashNumber(hash2, attrs.indent?.hanging ?? 0);
77771
+ hash2 = hashString(hash2, attrs.shading?.fill ?? "");
77772
+ hash2 = hashString(hash2, attrs.shading?.color ?? "");
77773
+ hash2 = hashString(hash2, attrs.direction ?? "");
77774
+ hash2 = hashString(hash2, attrs.rtl ? "1" : "");
77775
+ if (attrs.borders) {
77776
+ hash2 = hashString(hash2, hashParagraphBorders$1(attrs.borders));
77777
+ }
77778
+ }
77597
77779
  for (const run2 of runs) {
77598
77780
  if ("text" in run2 && typeof run2.text === "string") {
77599
77781
  hash2 = hashString(hash2, run2.text);
77600
77782
  }
77601
77783
  hash2 = hashNumber(hash2, run2.pmStart ?? -1);
77602
77784
  hash2 = hashNumber(hash2, run2.pmEnd ?? -1);
77785
+ hash2 = hashString(hash2, getRunStringProp(run2, "color"));
77786
+ hash2 = hashString(hash2, getRunStringProp(run2, "highlight"));
77787
+ hash2 = hashString(hash2, getRunBooleanProp(run2, "bold") ? "1" : "");
77788
+ hash2 = hashString(hash2, getRunBooleanProp(run2, "italic") ? "1" : "");
77789
+ hash2 = hashNumber(hash2, getRunNumberProp(run2, "fontSize"));
77790
+ hash2 = hashString(hash2, getRunStringProp(run2, "fontFamily"));
77791
+ hash2 = hashString(hash2, getRunUnderlineStyle(run2));
77792
+ hash2 = hashString(hash2, getRunUnderlineColor(run2));
77793
+ hash2 = hashString(hash2, getRunBooleanProp(run2, "strike") ? "1" : "");
77603
77794
  }
77604
77795
  }
77605
77796
  }
77606
77797
  }
77607
77798
  }
77799
+ if (tableBlock.attrs) {
77800
+ const tblAttrs = tableBlock.attrs;
77801
+ if (tblAttrs.borders) {
77802
+ hash2 = hashString(hash2, hashTableBorders$1(tblAttrs.borders));
77803
+ }
77804
+ if (tblAttrs.borderCollapse) {
77805
+ hash2 = hashString(hash2, tblAttrs.borderCollapse);
77806
+ }
77807
+ if (tblAttrs.cellSpacing !== void 0) {
77808
+ hash2 = hashNumber(hash2, tblAttrs.cellSpacing);
77809
+ }
77810
+ }
77608
77811
  return [block.id, tableBlock.rows.length, hash2.toString(16)].join("|");
77609
77812
  }
77610
77813
  return block.id;
@@ -77938,6 +78141,7 @@ const createDomPainter = (options) => {
77938
78141
  const painter = new DomPainter(options.blocks, options.measures, {
77939
78142
  pageStyles: options.pageStyles,
77940
78143
  layoutMode: options.layoutMode,
78144
+ pageGap: options.pageGap,
77941
78145
  headerProvider: options.headerProvider,
77942
78146
  footerProvider: options.footerProvider,
77943
78147
  virtualization: options.virtualization,
@@ -78356,7 +78560,7 @@ function isListItem(markerWidth, block) {
78356
78560
  return false;
78357
78561
  }
78358
78562
  const wordLayout = getWordLayoutConfig(block);
78359
- const hasListAttrs = block.attrs?.listItem != null || wordLayout?.marker != null;
78563
+ const hasListAttrs = block.attrs?.listItem != null || block.attrs?.numberingProperties != null || wordLayout?.marker != null;
78360
78564
  if (hasListAttrs) {
78361
78565
  return true;
78362
78566
  }
@@ -78786,7 +78990,7 @@ function computeNextSectionPropsAtBreak(blocks) {
78786
78990
  });
78787
78991
  return nextSectionPropsAtBreak;
78788
78992
  }
78789
- function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight = 0) {
78993
+ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight = 0, maxFooterContentHeight = 0) {
78790
78994
  const next = { ...state2 };
78791
78995
  const calcRequiredTopMargin = (headerDistance, baseTop) => {
78792
78996
  if (maxHeaderContentHeight > 0) {
@@ -78794,6 +78998,12 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78794
78998
  }
78795
78999
  return Math.max(baseTop, headerDistance);
78796
79000
  };
79001
+ const calcRequiredBottomMargin = (footerDistance, baseBottom) => {
79002
+ if (maxFooterContentHeight > 0) {
79003
+ return Math.max(baseBottom, footerDistance + maxFooterContentHeight);
79004
+ }
79005
+ return Math.max(baseBottom, footerDistance);
79006
+ };
78797
79007
  if (block.attrs?.isFirstSection && !next.hasAnyPages) {
78798
79008
  if (block.pageSize) {
78799
79009
  next.activePageSize = { w: block.pageSize.w, h: block.pageSize.h };
@@ -78814,7 +79024,7 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78814
79024
  const footerDistance = Math.max(0, block.margins.footer);
78815
79025
  next.activeFooterDistance = footerDistance;
78816
79026
  next.pendingFooterDistance = footerDistance;
78817
- next.activeBottomMargin = Math.max(baseMargins.bottom, footerDistance);
79027
+ next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, baseMargins.bottom);
78818
79028
  next.pendingBottomMargin = next.activeBottomMargin;
78819
79029
  }
78820
79030
  if (block.columns) {
@@ -78837,8 +79047,14 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
78837
79047
  next.pendingTopMargin = nextTop;
78838
79048
  next.pendingHeaderDistance = nextHeader;
78839
79049
  }
78840
- next.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
78841
- next.pendingFooterDistance = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
79050
+ if (typeof footerPx === "number") {
79051
+ const newFooterDist = Math.max(0, footerPx);
79052
+ next.pendingFooterDistance = newFooterDist;
79053
+ next.pendingBottomMargin = calcRequiredBottomMargin(newFooterDist, baseMargins.bottom);
79054
+ } else {
79055
+ next.pendingBottomMargin = nextBottom;
79056
+ next.pendingFooterDistance = nextFooter;
79057
+ }
78842
79058
  if (block.pageSize) {
78843
79059
  next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
78844
79060
  }
@@ -80438,7 +80654,7 @@ function layoutDocument(blocks, measures, options = {}) {
80438
80654
  if (contentWidth <= 0) {
80439
80655
  throw new Error("layoutDocument: pageSize and margins yield non-positive content area");
80440
80656
  }
80441
- const validateHeaderHeight = (height) => {
80657
+ const validateContentHeight = (height) => {
80442
80658
  if (height === void 0) return 0;
80443
80659
  if (!Number.isFinite(height) || height < 0) return 0;
80444
80660
  return height;
@@ -80446,15 +80662,25 @@ function layoutDocument(blocks, measures, options = {}) {
80446
80662
  const headerContentHeights = options.headerContentHeights;
80447
80663
  const maxHeaderContentHeight = headerContentHeights ? Math.max(
80448
80664
  0,
80449
- validateHeaderHeight(headerContentHeights.default),
80450
- validateHeaderHeight(headerContentHeights.first),
80451
- validateHeaderHeight(headerContentHeights.even),
80452
- validateHeaderHeight(headerContentHeights.odd)
80665
+ validateContentHeight(headerContentHeights.default),
80666
+ validateContentHeight(headerContentHeights.first),
80667
+ validateContentHeight(headerContentHeights.even),
80668
+ validateContentHeight(headerContentHeights.odd)
80453
80669
  ) : 0;
80454
80670
  const headerDistance = margins.header ?? margins.top;
80455
80671
  const effectiveTopMargin = maxHeaderContentHeight > 0 ? Math.max(margins.top, headerDistance + maxHeaderContentHeight) : margins.top;
80672
+ const footerContentHeights = options.footerContentHeights;
80673
+ const maxFooterContentHeight = footerContentHeights ? Math.max(
80674
+ 0,
80675
+ validateContentHeight(footerContentHeights.default),
80676
+ validateContentHeight(footerContentHeights.first),
80677
+ validateContentHeight(footerContentHeights.even),
80678
+ validateContentHeight(footerContentHeights.odd)
80679
+ ) : 0;
80680
+ const footerDistance = margins.footer ?? margins.bottom;
80681
+ const effectiveBottomMargin = maxFooterContentHeight > 0 ? Math.max(margins.bottom, footerDistance + maxFooterContentHeight) : margins.bottom;
80456
80682
  let activeTopMargin = effectiveTopMargin;
80457
- let activeBottomMargin = margins.bottom;
80683
+ let activeBottomMargin = effectiveBottomMargin;
80458
80684
  let pendingTopMargin = null;
80459
80685
  let pendingBottomMargin = null;
80460
80686
  let activeHeaderDistance = margins.header ?? margins.top;
@@ -80477,7 +80703,7 @@ function layoutDocument(blocks, measures, options = {}) {
80477
80703
  const nextSectionPropsAtBreak = computeNextSectionPropsAtBreak(blocks);
80478
80704
  const scheduleSectionBreakCompat = (block, state2, baseMargins) => {
80479
80705
  if (typeof scheduleSectionBreak === "function") {
80480
- return scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight);
80706
+ return scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight, maxFooterContentHeight);
80481
80707
  }
80482
80708
  const next = { ...state2 };
80483
80709
  if (block.attrs?.isFirstSection && !next.hasAnyPages) {
@@ -80498,10 +80724,11 @@ function layoutDocument(blocks, measures, options = {}) {
80498
80724
  next.pendingTopMargin = next.activeTopMargin;
80499
80725
  }
80500
80726
  if (block.margins?.footer !== void 0) {
80501
- const footerDistance = Math.max(0, block.margins.footer);
80502
- next.activeFooterDistance = footerDistance;
80503
- next.pendingFooterDistance = footerDistance;
80504
- next.activeBottomMargin = Math.max(baseMargins.bottom, footerDistance);
80727
+ const footerDistance2 = Math.max(0, block.margins.footer);
80728
+ next.activeFooterDistance = footerDistance2;
80729
+ next.pendingFooterDistance = footerDistance2;
80730
+ const requiredBottom = maxFooterContentHeight > 0 ? footerDistance2 + maxFooterContentHeight : footerDistance2;
80731
+ next.activeBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
80505
80732
  next.pendingBottomMargin = next.activeBottomMargin;
80506
80733
  }
80507
80734
  if (block.columns) {
@@ -80546,7 +80773,13 @@ function layoutDocument(blocks, measures, options = {}) {
80546
80773
  } else {
80547
80774
  next.pendingTopMargin = nextTop;
80548
80775
  }
80549
- next.pendingBottomMargin = typeof footerPx === "number" ? Math.max(baseMargins.bottom, footerPx) : nextBottom;
80776
+ if (typeof footerPx === "number") {
80777
+ const sectionFooter = next.pendingFooterDistance;
80778
+ const requiredBottom = maxFooterContentHeight > 0 ? sectionFooter + maxFooterContentHeight : sectionFooter;
80779
+ next.pendingBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
80780
+ } else {
80781
+ next.pendingBottomMargin = nextBottom;
80782
+ }
80550
80783
  if (block.pageSize) next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
80551
80784
  if (block.orientation) next.pendingOrientation = block.orientation;
80552
80785
  const sectionType = block.type ?? "continuous";
@@ -81297,10 +81530,6 @@ const resolveTrackedChangesEnabled = (attrs, defaultEnabled = true) => {
81297
81530
  }
81298
81531
  return attrs.trackedChangesEnabled !== false;
81299
81532
  };
81300
- const MAX_CACHE_SIZE$1 = 1e4;
81301
- const BYTES_PER_ENTRY_ESTIMATE = 5e3;
81302
- const NORMALIZED_WHITESPACE = /\s+/g;
81303
- const normalizeText = (text) => text.replace(NORMALIZED_WHITESPACE, " ");
81304
81533
  const hashParagraphBorder = (border) => {
81305
81534
  const parts = [];
81306
81535
  if (border.style !== void 0) parts.push(`s:${border.style}`);
@@ -81317,6 +81546,53 @@ const hashParagraphBorders = (borders) => {
81317
81546
  if (borders.left) parts.push(`l:[${hashParagraphBorder(borders.left)}]`);
81318
81547
  return parts.join(";");
81319
81548
  };
81549
+ function isNoneBorder(value) {
81550
+ return typeof value === "object" && value !== null && "none" in value && value.none === true;
81551
+ }
81552
+ function isBorderSpec(value) {
81553
+ return typeof value === "object" && value !== null && !("none" in value);
81554
+ }
81555
+ const hashBorderSpec = (border) => {
81556
+ const parts = [];
81557
+ if (border.style !== void 0) parts.push(`s:${border.style}`);
81558
+ if (border.width !== void 0) parts.push(`w:${border.width}`);
81559
+ if (border.color !== void 0) parts.push(`c:${border.color}`);
81560
+ if (border.space !== void 0) parts.push(`sp:${border.space}`);
81561
+ return parts.join(",");
81562
+ };
81563
+ const hashTableBorderValue = (borderValue) => {
81564
+ if (borderValue === void 0) return "";
81565
+ if (borderValue === null) return "null";
81566
+ if (isNoneBorder(borderValue)) return "none";
81567
+ if (isBorderSpec(borderValue)) {
81568
+ return hashBorderSpec(borderValue);
81569
+ }
81570
+ return "";
81571
+ };
81572
+ const hashTableBorders = (borders) => {
81573
+ if (!borders) return "";
81574
+ const parts = [];
81575
+ if (borders.top !== void 0) parts.push(`t:[${hashTableBorderValue(borders.top)}]`);
81576
+ if (borders.right !== void 0) parts.push(`r:[${hashTableBorderValue(borders.right)}]`);
81577
+ if (borders.bottom !== void 0) parts.push(`b:[${hashTableBorderValue(borders.bottom)}]`);
81578
+ if (borders.left !== void 0) parts.push(`l:[${hashTableBorderValue(borders.left)}]`);
81579
+ if (borders.insideH !== void 0) parts.push(`ih:[${hashTableBorderValue(borders.insideH)}]`);
81580
+ if (borders.insideV !== void 0) parts.push(`iv:[${hashTableBorderValue(borders.insideV)}]`);
81581
+ return parts.join(";");
81582
+ };
81583
+ const hashCellBorders = (borders) => {
81584
+ if (!borders) return "";
81585
+ const parts = [];
81586
+ if (borders.top) parts.push(`t:[${hashBorderSpec(borders.top)}]`);
81587
+ if (borders.right) parts.push(`r:[${hashBorderSpec(borders.right)}]`);
81588
+ if (borders.bottom) parts.push(`b:[${hashBorderSpec(borders.bottom)}]`);
81589
+ if (borders.left) parts.push(`l:[${hashBorderSpec(borders.left)}]`);
81590
+ return parts.join(";");
81591
+ };
81592
+ const MAX_CACHE_SIZE$1 = 1e4;
81593
+ const BYTES_PER_ENTRY_ESTIMATE = 5e3;
81594
+ const NORMALIZED_WHITESPACE = /\s+/g;
81595
+ const normalizeText = (text) => text.replace(NORMALIZED_WHITESPACE, " ");
81320
81596
  const hashParagraphFrame = (frame) => {
81321
81597
  const parts = [];
81322
81598
  if (frame.wrap !== void 0) parts.push(`w:${frame.wrap}`);
@@ -81340,6 +81616,26 @@ const hashRuns = (block) => {
81340
81616
  continue;
81341
81617
  }
81342
81618
  for (const cell of row.cells) {
81619
+ if (cell.attrs) {
81620
+ const cellAttrs = cell.attrs;
81621
+ const cellAttrParts = [];
81622
+ if (cellAttrs.borders) {
81623
+ cellAttrParts.push(`cb:${hashCellBorders(cellAttrs.borders)}`);
81624
+ }
81625
+ if (cellAttrs.padding) {
81626
+ const p = cellAttrs.padding;
81627
+ cellAttrParts.push(`cp:${p.top ?? 0}:${p.right ?? 0}:${p.bottom ?? 0}:${p.left ?? 0}`);
81628
+ }
81629
+ if (cellAttrs.verticalAlign) {
81630
+ cellAttrParts.push(`va:${cellAttrs.verticalAlign}`);
81631
+ }
81632
+ if (cellAttrs.background) {
81633
+ cellAttrParts.push(`bg:${cellAttrs.background}`);
81634
+ }
81635
+ if (cellAttrParts.length > 0) {
81636
+ cellHashes.push(`ca:${cellAttrParts.join(":")}`);
81637
+ }
81638
+ }
81343
81639
  const cellBlocks = cell.blocks ?? (cell.paragraph ? [cell.paragraph] : []);
81344
81640
  for (const cellBlock of cellBlocks) {
81345
81641
  const paragraphBlock = cellBlock;
@@ -81353,12 +81649,14 @@ const hashRuns = (block) => {
81353
81649
  const color = "color" in run2 ? run2.color : void 0;
81354
81650
  const fontSize2 = "fontSize" in run2 ? run2.fontSize : void 0;
81355
81651
  const fontFamily2 = "fontFamily" in run2 ? run2.fontFamily : void 0;
81652
+ const highlight = "highlight" in run2 ? run2.highlight : void 0;
81356
81653
  const marks = [
81357
81654
  bold ? "b" : "",
81358
81655
  italic ? "i" : "",
81359
81656
  color ?? "",
81360
81657
  fontSize2 !== void 0 ? `fs:${fontSize2}` : "",
81361
- fontFamily2 ? `ff:${fontFamily2}` : ""
81658
+ fontFamily2 ? `ff:${fontFamily2}` : "",
81659
+ highlight ? `hl:${highlight}` : ""
81362
81660
  ].join("");
81363
81661
  let trackedKey = "";
81364
81662
  if (hasTrackedChange(run2)) {
@@ -81369,11 +81667,60 @@ const hashRuns = (block) => {
81369
81667
  }
81370
81668
  cellHashes.push(`${text}:${marks}${trackedKey}`);
81371
81669
  }
81670
+ if (paragraphBlock.attrs) {
81671
+ const attrs = paragraphBlock.attrs;
81672
+ const parts = [];
81673
+ if (attrs.alignment) parts.push(`al:${attrs.alignment}`);
81674
+ if (attrs.spacing) {
81675
+ const s2 = attrs.spacing;
81676
+ if (s2.before !== void 0) parts.push(`sb:${s2.before}`);
81677
+ if (s2.after !== void 0) parts.push(`sa:${s2.after}`);
81678
+ if (s2.line !== void 0) parts.push(`sl:${s2.line}`);
81679
+ if (s2.lineRule) parts.push(`sr:${s2.lineRule}`);
81680
+ }
81681
+ if (attrs.indent) {
81682
+ const ind = attrs.indent;
81683
+ if (ind.left !== void 0) parts.push(`il:${ind.left}`);
81684
+ if (ind.right !== void 0) parts.push(`ir:${ind.right}`);
81685
+ if (ind.firstLine !== void 0) parts.push(`if:${ind.firstLine}`);
81686
+ if (ind.hanging !== void 0) parts.push(`ih:${ind.hanging}`);
81687
+ }
81688
+ if (attrs.borders) {
81689
+ parts.push(`br:${hashParagraphBorders(attrs.borders)}`);
81690
+ }
81691
+ if (attrs.shading) {
81692
+ const sh = attrs.shading;
81693
+ if (sh.fill) parts.push(`shf:${sh.fill}`);
81694
+ if (sh.color) parts.push(`shc:${sh.color}`);
81695
+ }
81696
+ if (attrs.direction) parts.push(`dir:${attrs.direction}`);
81697
+ if (attrs.rtl) parts.push("rtl");
81698
+ if (parts.length > 0) {
81699
+ cellHashes.push(`pa:${parts.join(":")}`);
81700
+ }
81701
+ }
81372
81702
  }
81373
81703
  }
81374
81704
  }
81705
+ let tableAttrsKey = "";
81706
+ if (tableBlock.attrs) {
81707
+ const tblAttrs = tableBlock.attrs;
81708
+ const tableAttrParts = [];
81709
+ if (tblAttrs.borders) {
81710
+ tableAttrParts.push(`tb:${hashTableBorders(tblAttrs.borders)}`);
81711
+ }
81712
+ if (tblAttrs.borderCollapse) {
81713
+ tableAttrParts.push(`bc:${tblAttrs.borderCollapse}`);
81714
+ }
81715
+ if (tblAttrs.cellSpacing !== void 0) {
81716
+ tableAttrParts.push(`cs:${tblAttrs.cellSpacing}`);
81717
+ }
81718
+ if (tableAttrParts.length > 0) {
81719
+ tableAttrsKey = `|ta:${tableAttrParts.join(":")}`;
81720
+ }
81721
+ }
81375
81722
  const contentHash = cellHashes.join("|");
81376
- return `${block.id}:table:${contentHash}`;
81723
+ return `${block.id}:table:${contentHash}${tableAttrsKey}`;
81377
81724
  }
81378
81725
  if (block.kind !== "paragraph") return block.id;
81379
81726
  const trackedMode = block.attrs && "trackedChangesMode" in block.attrs && block.attrs.trackedChangesMode || "review";
@@ -81392,12 +81739,14 @@ const hashRuns = (block) => {
81392
81739
  const color = "color" in run2 ? run2.color : void 0;
81393
81740
  const fontSize2 = "fontSize" in run2 ? run2.fontSize : void 0;
81394
81741
  const fontFamily2 = "fontFamily" in run2 ? run2.fontFamily : void 0;
81742
+ const highlight = "highlight" in run2 ? run2.highlight : void 0;
81395
81743
  const marks = [
81396
81744
  bold ? "b" : "",
81397
81745
  italic ? "i" : "",
81398
81746
  color ?? "",
81399
81747
  fontSize2 !== void 0 ? `fs:${fontSize2}` : "",
81400
- fontFamily2 ? `ff:${fontFamily2}` : ""
81748
+ fontFamily2 ? `ff:${fontFamily2}` : "",
81749
+ highlight ? `hl:${highlight}` : ""
81401
81750
  ].join("");
81402
81751
  let trackedKey = "";
81403
81752
  if (hasTrackedChange(run2)) {
@@ -82524,7 +82873,7 @@ const paragraphBlocksEqual = (a, b2) => {
82524
82873
  for (let i = 0; i < a.runs.length; i += 1) {
82525
82874
  const runA = a.runs[i];
82526
82875
  const runB = b2.runs[i];
82527
- 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)) {
82876
+ 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)) {
82528
82877
  return false;
82529
82878
  }
82530
82879
  }
@@ -82893,17 +83242,67 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
82893
83242
  for (const [type2, value] of Object.entries(preHeaderLayouts)) {
82894
83243
  if (!isValidHeaderType(type2)) continue;
82895
83244
  if (value?.layout && typeof value.layout.height === "number") {
82896
- headerContentHeights[type2] = value.layout.height;
83245
+ const height = value.layout.height;
83246
+ if (Number.isFinite(height) && height >= 0) {
83247
+ headerContentHeights[type2] = height;
83248
+ }
82897
83249
  }
82898
83250
  }
82899
83251
  const hfPreEnd = performance.now();
82900
83252
  perfLog(`[Perf] 4.1.5 Pre-layout headers for height: ${(hfPreEnd - hfPreStart).toFixed(2)}ms`);
82901
83253
  }
83254
+ let footerContentHeights;
83255
+ if (headerFooter?.constraints && headerFooter.footerBlocks) {
83256
+ const footerPreStart = performance.now();
83257
+ const measureFn = headerFooter.measure ?? measureBlock2;
83258
+ if (!headerFooter.headerBlocks) {
83259
+ invalidateHeaderFooterCache(
83260
+ headerMeasureCache,
83261
+ headerFooterCacheState,
83262
+ headerFooter.headerBlocks,
83263
+ headerFooter.footerBlocks,
83264
+ headerFooter.constraints,
83265
+ options.sectionMetadata
83266
+ );
83267
+ }
83268
+ const FOOTER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT = 1;
83269
+ try {
83270
+ const preFooterLayouts = await layoutHeaderFooterWithCache(
83271
+ headerFooter.footerBlocks,
83272
+ headerFooter.constraints,
83273
+ measureFn,
83274
+ headerMeasureCache,
83275
+ FOOTER_PRELAYOUT_PLACEHOLDER_PAGE_COUNT,
83276
+ void 0
83277
+ // No page resolver needed for height calculation
83278
+ );
83279
+ const isValidFooterType = (key2) => {
83280
+ return ["default", "first", "even", "odd"].includes(key2);
83281
+ };
83282
+ footerContentHeights = {};
83283
+ for (const [type2, value] of Object.entries(preFooterLayouts)) {
83284
+ if (!isValidFooterType(type2)) continue;
83285
+ if (value?.layout && typeof value.layout.height === "number") {
83286
+ const height = value.layout.height;
83287
+ if (Number.isFinite(height) && height >= 0) {
83288
+ footerContentHeights[type2] = height;
83289
+ }
83290
+ }
83291
+ }
83292
+ } catch (error) {
83293
+ console.error("[Layout] Footer pre-layout failed:", error);
83294
+ footerContentHeights = void 0;
83295
+ }
83296
+ const footerPreEnd = performance.now();
83297
+ perfLog(`[Perf] 4.1.6 Pre-layout footers for height: ${(footerPreEnd - footerPreStart).toFixed(2)}ms`);
83298
+ }
82902
83299
  const layoutStart = performance.now();
82903
83300
  let layout = layoutDocument(nextBlocks, measures, {
82904
83301
  ...options,
82905
83302
  headerContentHeights,
82906
83303
  // Pass header heights to prevent overlap
83304
+ footerContentHeights,
83305
+ // Pass footer heights to prevent overlap
82907
83306
  remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
82908
83307
  });
82909
83308
  const layoutEnd = performance.now();
@@ -82952,6 +83351,8 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
82952
83351
  ...options,
82953
83352
  headerContentHeights,
82954
83353
  // Pass header heights to prevent overlap
83354
+ footerContentHeights,
83355
+ // Pass footer heights to prevent overlap
82955
83356
  remeasureParagraph: (block, maxWidth, firstLineIndent) => remeasureParagraph(block, maxWidth, firstLineIndent)
82956
83357
  });
82957
83358
  const relayoutEnd = performance.now();
@@ -83118,6 +83519,285 @@ async function remeasureAffectedBlocks(blocks, measures, affectedBlockIds, const
83118
83519
  }
83119
83520
  return updatedMeasures;
83120
83521
  }
83522
+ class PageGeometryHelper {
83523
+ /**
83524
+ * Creates a new PageGeometryHelper instance.
83525
+ *
83526
+ * @param config - Page geometry configuration
83527
+ */
83528
+ constructor(config2) {
83529
+ this.cache = null;
83530
+ this.config = config2;
83531
+ }
83532
+ /**
83533
+ * Updates the layout and invalidates the cache.
83534
+ *
83535
+ * Call this whenever the layout changes (new pages, different heights, etc.)
83536
+ *
83537
+ * @param layout - New layout data
83538
+ * @param pageGap - Optional new page gap (if not provided, uses current gap)
83539
+ */
83540
+ updateLayout(layout, pageGap) {
83541
+ this.config.layout = layout;
83542
+ if (pageGap !== void 0) {
83543
+ this.config.pageGap = pageGap;
83544
+ }
83545
+ this.cache = null;
83546
+ }
83547
+ /**
83548
+ * Updates the page gap and invalidates the cache.
83549
+ *
83550
+ * @param pageGap - New gap between pages in pixels
83551
+ */
83552
+ updatePageGap(pageGap) {
83553
+ if (this.config.pageGap !== pageGap) {
83554
+ this.config.pageGap = pageGap;
83555
+ this.cache = null;
83556
+ }
83557
+ }
83558
+ /**
83559
+ * Gets the cumulative Y position (top edge) of a page in container space.
83560
+ *
83561
+ * The returned value is the distance from the top of the container to the
83562
+ * top of the specified page, accounting for all previous pages and gaps.
83563
+ *
83564
+ * @param pageIndex - Zero-based page index
83565
+ * @returns Y position in pixels, or 0 if page index is invalid
83566
+ *
83567
+ * @example
83568
+ * ```typescript
83569
+ * // Get Y position of page 0 (first page)
83570
+ * const y0 = helper.getPageTop(0); // Returns 0
83571
+ *
83572
+ * // Get Y position of page 2 (third page)
83573
+ * // Assumes page 0 height = 1000, page 1 height = 1200, gap = 24
83574
+ * const y2 = helper.getPageTop(2); // Returns 1000 + 24 + 1200 + 24 = 2248
83575
+ * ```
83576
+ */
83577
+ getPageTop(pageIndex) {
83578
+ this.ensureCache();
83579
+ if (pageIndex < 0 || pageIndex >= this.cache.cumulativeY.length) {
83580
+ return 0;
83581
+ }
83582
+ return this.cache.cumulativeY[pageIndex];
83583
+ }
83584
+ /**
83585
+ * Gets the height of a specific page.
83586
+ *
83587
+ * Uses per-page height if available (from layout.pages[i].size?.h),
83588
+ * otherwise falls back to layout.pageSize.h.
83589
+ *
83590
+ * @param pageIndex - Zero-based page index
83591
+ * @returns Page height in pixels, or 0 if page index is invalid
83592
+ *
83593
+ * @example
83594
+ * ```typescript
83595
+ * const height = helper.getPageHeight(0); // Returns page-specific height
83596
+ * ```
83597
+ */
83598
+ getPageHeight(pageIndex) {
83599
+ this.ensureCache();
83600
+ if (pageIndex < 0 || pageIndex >= this.cache.pageHeights.length) {
83601
+ return 0;
83602
+ }
83603
+ return this.cache.pageHeights[pageIndex];
83604
+ }
83605
+ /**
83606
+ * Gets the gap between pages.
83607
+ *
83608
+ * @returns Gap in pixels
83609
+ *
83610
+ * @example
83611
+ * ```typescript
83612
+ * const gap = helper.getPageGap(); // Returns 24
83613
+ * ```
83614
+ */
83615
+ getPageGap() {
83616
+ this.ensureCache();
83617
+ return this.cache.pageGap;
83618
+ }
83619
+ /**
83620
+ * Gets the total height of all pages including gaps.
83621
+ *
83622
+ * Total height = sum of all page heights + (pageCount - 1) * gap
83623
+ *
83624
+ * @returns Total height in pixels
83625
+ *
83626
+ * @example
83627
+ * ```typescript
83628
+ * // 3 pages: heights [1000, 1200, 1000], gap = 24
83629
+ * const total = helper.getTotalHeight();
83630
+ * // Returns 1000 + 24 + 1200 + 24 + 1000 = 3248
83631
+ * ```
83632
+ */
83633
+ getTotalHeight() {
83634
+ this.ensureCache();
83635
+ return this.cache.totalHeight;
83636
+ }
83637
+ /**
83638
+ * Gets the number of pages in the layout.
83639
+ *
83640
+ * @returns Page count
83641
+ */
83642
+ getPageCount() {
83643
+ return this.config.layout.pages.length;
83644
+ }
83645
+ /**
83646
+ * Finds the page index containing a given Y coordinate.
83647
+ *
83648
+ * This performs a linear search through cached cumulative positions.
83649
+ * For large documents, consider adding binary search optimization.
83650
+ *
83651
+ * @param containerY - Y coordinate in container space
83652
+ * @returns Page index, or null if Y is outside all pages
83653
+ *
83654
+ * @example
83655
+ * ```typescript
83656
+ * // Find which page contains Y = 1500
83657
+ * const pageIndex = helper.getPageIndexAtY(1500);
83658
+ * // Returns 1 (second page) if first page ends at Y=1024
83659
+ * ```
83660
+ */
83661
+ getPageIndexAtY(containerY) {
83662
+ this.ensureCache();
83663
+ const cache2 = this.cache;
83664
+ for (let i = 0; i < cache2.cumulativeY.length; i++) {
83665
+ const pageTop = cache2.cumulativeY[i];
83666
+ const pageBottom = pageTop + cache2.pageHeights[i];
83667
+ if (containerY >= pageTop && containerY < pageBottom) {
83668
+ return i;
83669
+ }
83670
+ }
83671
+ return null;
83672
+ }
83673
+ /**
83674
+ * Finds the nearest page index to a given Y coordinate (snap-to-nearest).
83675
+ *
83676
+ * Returns the page containing Y when inside a page; otherwise returns the
83677
+ * closest page based on distance to page center. Useful for dragging through
83678
+ * page gaps where getPageIndexAtY would return null.
83679
+ *
83680
+ * @param containerY - Y coordinate in container space
83681
+ * @returns Nearest page index, or null if there are no pages
83682
+ */
83683
+ getNearestPageIndex(containerY) {
83684
+ this.ensureCache();
83685
+ const cache2 = this.cache;
83686
+ const pageCount = cache2.pageHeights.length;
83687
+ if (pageCount === 0) return null;
83688
+ const direct = this.getPageIndexAtY(containerY);
83689
+ if (direct !== null) return direct;
83690
+ let nearestIndex = 0;
83691
+ let nearestDistance = Infinity;
83692
+ for (let i = 0; i < pageCount; i++) {
83693
+ const top2 = cache2.cumulativeY[i];
83694
+ const height = cache2.pageHeights[i];
83695
+ const center = top2 + height / 2;
83696
+ const distance = Math.abs(containerY - center);
83697
+ if (distance < nearestDistance) {
83698
+ nearestDistance = distance;
83699
+ nearestIndex = i;
83700
+ }
83701
+ }
83702
+ return nearestIndex;
83703
+ }
83704
+ /**
83705
+ * Ensures the cache is built and up-to-date.
83706
+ * Validates cache state and rebuilds if needed.
83707
+ * @private
83708
+ * @throws Never throws - handles errors gracefully with fallback values
83709
+ */
83710
+ ensureCache() {
83711
+ if (this.cache !== null) {
83712
+ if (!Array.isArray(this.cache.cumulativeY) || !Array.isArray(this.cache.pageHeights)) {
83713
+ console.warn("[PageGeometryHelper] Cache corruption detected, rebuilding cache");
83714
+ this.cache = null;
83715
+ } else {
83716
+ return;
83717
+ }
83718
+ }
83719
+ this.buildCache();
83720
+ }
83721
+ /**
83722
+ * Builds the geometry cache from current layout data.
83723
+ * Handles errors gracefully by providing fallback values.
83724
+ * @private
83725
+ * @throws Never throws - catches all errors and provides safe defaults
83726
+ */
83727
+ buildCache() {
83728
+ try {
83729
+ const layout = this.config.layout;
83730
+ if (!layout || !Array.isArray(layout.pages)) {
83731
+ throw new Error("Invalid layout: missing or invalid pages array");
83732
+ }
83733
+ const pageGap = this.config.pageGap ?? layout.pageGap ?? 0;
83734
+ const pageCount = layout.pages.length;
83735
+ if (!Number.isFinite(pageGap) || pageGap < 0) {
83736
+ throw new Error(`Invalid pageGap: ${pageGap} (must be non-negative finite number)`);
83737
+ }
83738
+ const cumulativeY = new Array(pageCount);
83739
+ const pageHeights = new Array(pageCount);
83740
+ let currentY = 0;
83741
+ for (let i = 0; i < pageCount; i++) {
83742
+ const page = layout.pages[i];
83743
+ if (!page) {
83744
+ throw new Error(`Invalid page at index ${i}: page is null or undefined`);
83745
+ }
83746
+ const pageHeight = page.size?.h ?? layout.pageSize.h;
83747
+ if (!Number.isFinite(pageHeight) || pageHeight < 0) {
83748
+ throw new Error(`Invalid page height at index ${i}: ${pageHeight} (must be non-negative finite number)`);
83749
+ }
83750
+ cumulativeY[i] = currentY;
83751
+ pageHeights[i] = pageHeight;
83752
+ currentY += pageHeight;
83753
+ if (i < pageCount - 1) {
83754
+ currentY += pageGap;
83755
+ }
83756
+ }
83757
+ const totalHeight = currentY;
83758
+ this.cache = {
83759
+ cumulativeY,
83760
+ pageHeights,
83761
+ pageGap,
83762
+ totalHeight,
83763
+ layoutVersion: 0
83764
+ // Placeholder for future version tracking
83765
+ };
83766
+ } catch (error) {
83767
+ const errorMessage = error instanceof Error ? error.message : String(error);
83768
+ console.error(`[PageGeometryHelper] Cache build failed: ${errorMessage}. Using fallback empty cache.`);
83769
+ this.cache = {
83770
+ cumulativeY: [],
83771
+ pageHeights: [],
83772
+ pageGap: 0,
83773
+ totalHeight: 0,
83774
+ layoutVersion: 0
83775
+ };
83776
+ }
83777
+ }
83778
+ /**
83779
+ * Clears the cache, forcing recalculation on next access.
83780
+ * Useful for testing or manual cache invalidation.
83781
+ */
83782
+ clearCache() {
83783
+ this.cache = null;
83784
+ }
83785
+ /**
83786
+ * Gets debug information about the current cache state.
83787
+ * @internal
83788
+ */
83789
+ getDebugInfo() {
83790
+ this.ensureCache();
83791
+ return {
83792
+ isCached: this.cache !== null,
83793
+ pageCount: this.config.layout.pages.length,
83794
+ pageGap: this.cache.pageGap,
83795
+ totalHeight: this.cache.totalHeight,
83796
+ cumulativeY: [...this.cache.cumulativeY],
83797
+ pageHeights: [...this.cache.pageHeights]
83798
+ };
83799
+ }
83800
+ }
83121
83801
  var Priority = /* @__PURE__ */ ((Priority2) => {
83122
83802
  Priority2[Priority2["P0"] = 0] = "P0";
83123
83803
  Priority2[Priority2["P1"] = 1] = "P1";
@@ -83411,18 +84091,41 @@ const rangesOverlap = (startA, endA, startB, endB) => {
83411
84091
  const effectiveEndA = endA ?? startA + 1;
83412
84092
  return effectiveEndA > startB && startA < endB;
83413
84093
  };
83414
- function hitTestPage(layout, point) {
84094
+ function hitTestPage(layout, point, geometryHelper) {
84095
+ if (geometryHelper) {
84096
+ const pageIndex = geometryHelper.getPageIndexAtY(point.y);
84097
+ if (pageIndex !== null) {
84098
+ return { pageIndex, page: layout.pages[pageIndex] };
84099
+ }
84100
+ const nearest = geometryHelper.getNearestPageIndex(point.y);
84101
+ if (nearest !== null) {
84102
+ return { pageIndex: nearest, page: layout.pages[nearest] };
84103
+ }
84104
+ return null;
84105
+ }
83415
84106
  const pageGap = layout.pageGap ?? 0;
83416
84107
  let cursorY = 0;
84108
+ let nearestIndex = null;
84109
+ let nearestDistance = Infinity;
83417
84110
  for (let pageIndex = 0; pageIndex < layout.pages.length; pageIndex += 1) {
83418
84111
  const page = layout.pages[pageIndex];
84112
+ const pageHeight = page.size?.h ?? layout.pageSize.h;
83419
84113
  const top2 = cursorY;
83420
- const bottom2 = top2 + layout.pageSize.h;
84114
+ const bottom2 = top2 + pageHeight;
83421
84115
  if (point.y >= top2 && point.y < bottom2) {
83422
84116
  return { pageIndex, page };
83423
84117
  }
84118
+ const center = top2 + pageHeight / 2;
84119
+ const distance = Math.abs(point.y - center);
84120
+ if (distance < nearestDistance) {
84121
+ nearestDistance = distance;
84122
+ nearestIndex = pageIndex;
84123
+ }
83424
84124
  cursorY = bottom2 + pageGap;
83425
84125
  }
84126
+ if (nearestIndex !== null) {
84127
+ return { pageIndex: nearestIndex, page: layout.pages[nearestIndex] };
84128
+ }
83426
84129
  return null;
83427
84130
  }
83428
84131
  function hitTestFragment(layout, pageHit, blocks, measures, point) {
@@ -83583,7 +84286,7 @@ const hitTestTableFragment = (pageHit, blocks, measures, point) => {
83583
84286
  }
83584
84287
  return null;
83585
84288
  };
83586
- function clickToPosition(layout, blocks, measures, containerPoint, domContainer, clientX, clientY) {
84289
+ function clickToPosition(layout, blocks, measures, containerPoint, domContainer, clientX, clientY, geometryHelper) {
83587
84290
  logClickStage("log", "entry", {
83588
84291
  pages: layout.pages.length
83589
84292
  });
@@ -83626,75 +84329,132 @@ function clickToPosition(layout, blocks, measures, containerPoint, domContainer,
83626
84329
  return { pos: domPos, blockId: "", pageIndex: 0, column: 0, lineIndex: -1 };
83627
84330
  }
83628
84331
  }
83629
- const pageHit = hitTestPage(layout, containerPoint);
84332
+ const pageHit = hitTestPage(layout, containerPoint, geometryHelper);
83630
84333
  if (!pageHit) {
83631
84334
  return null;
83632
84335
  }
83633
- const pageGap = layout.pageGap ?? 0;
84336
+ const pageTopY = geometryHelper ? geometryHelper.getPageTop(pageHit.pageIndex) : calculatePageTopFallback(layout, pageHit.pageIndex);
83634
84337
  const pageRelativePoint = {
83635
84338
  x: containerPoint.x,
83636
- y: containerPoint.y - pageHit.pageIndex * (layout.pageSize.h + pageGap)
84339
+ y: containerPoint.y - pageTopY
83637
84340
  };
83638
84341
  logClickStage("log", "page-hit", {
83639
84342
  pageIndex: pageHit.pageIndex
83640
84343
  });
83641
- const fragmentHit = hitTestFragment(layout, pageHit, blocks, measures, pageRelativePoint);
84344
+ let fragmentHit = hitTestFragment(layout, pageHit, blocks, measures, pageRelativePoint);
84345
+ if (!fragmentHit) {
84346
+ const page = pageHit.page;
84347
+ const fragments = page.fragments.filter(
84348
+ (f2) => f2 != null && typeof f2 === "object"
84349
+ );
84350
+ if (fragments.length > 0) {
84351
+ let nearest = null;
84352
+ let nearestDist = Infinity;
84353
+ for (const frag of fragments) {
84354
+ const top2 = frag.y;
84355
+ const bottom2 = frag.y + frag.height;
84356
+ let dist2;
84357
+ if (pageRelativePoint.y < top2) {
84358
+ dist2 = top2 - pageRelativePoint.y;
84359
+ } else if (pageRelativePoint.y > bottom2) {
84360
+ dist2 = pageRelativePoint.y - bottom2;
84361
+ } else {
84362
+ dist2 = 0;
84363
+ }
84364
+ if (dist2 < nearestDist) {
84365
+ nearestDist = dist2;
84366
+ nearest = frag;
84367
+ }
84368
+ }
84369
+ if (nearest) {
84370
+ const blockIndex = findBlockIndexByFragmentId(blocks, nearest.blockId);
84371
+ if (blockIndex !== -1) {
84372
+ const block = blocks[blockIndex];
84373
+ const measure = measures[blockIndex];
84374
+ if (block && measure) {
84375
+ fragmentHit = {
84376
+ fragment: nearest,
84377
+ block,
84378
+ measure,
84379
+ pageIndex: pageHit.pageIndex,
84380
+ pageY: 0
84381
+ };
84382
+ }
84383
+ }
84384
+ }
84385
+ }
84386
+ }
83642
84387
  if (fragmentHit) {
83643
84388
  const { fragment, block, measure, pageIndex, pageY } = fragmentHit;
83644
- if (fragment.kind !== "para" || measure.kind !== "paragraph" || block.kind !== "paragraph") {
83645
- logClickStage("warn", "fragment-type-mismatch", {
83646
- fragmentKind: fragment.kind,
83647
- measureKind: measure.kind,
83648
- blockKind: block.kind
84389
+ if (fragment.kind === "para" && measure.kind === "paragraph" && block.kind === "paragraph") {
84390
+ const lineIndex = findLineIndexAtY(measure, pageY, fragment.fromLine, fragment.toLine);
84391
+ if (lineIndex == null) {
84392
+ logClickStage("warn", "no-line", {
84393
+ blockId: fragment.blockId
84394
+ });
84395
+ return null;
84396
+ }
84397
+ const line = measure.lines[lineIndex];
84398
+ const isRTL = isRtlBlock(block);
84399
+ const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
84400
+ const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
84401
+ const paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
84402
+ const paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
84403
+ const totalIndent = paraIndentLeft + paraIndentRight;
84404
+ const availableWidth = Math.max(0, fragment.width - totalIndent);
84405
+ if (totalIndent > fragment.width) {
84406
+ console.warn(
84407
+ `[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.`
84408
+ );
84409
+ }
84410
+ const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
84411
+ const isListItem3 = markerWidth > 0;
84412
+ const alignmentOverride = isListItem3 ? "left" : void 0;
84413
+ const pos = mapPointToPm(block, line, pageRelativePoint.x - fragment.x, isRTL, availableWidth, alignmentOverride);
84414
+ if (pos == null) {
84415
+ logClickStage("warn", "no-position", {
84416
+ blockId: fragment.blockId
84417
+ });
84418
+ return null;
84419
+ }
84420
+ const column = determineColumn(layout, fragment.x);
84421
+ logPositionDebug({
84422
+ blockId: fragment.blockId,
84423
+ x: pageRelativePoint.x - fragment.x
83649
84424
  });
83650
- return null;
83651
- }
83652
- const lineIndex = findLineIndexAtY(measure, pageY, fragment.fromLine, fragment.toLine);
83653
- if (lineIndex == null) {
83654
- logClickStage("warn", "no-line", {
84425
+ logClickStage("log", "success", {
83655
84426
  blockId: fragment.blockId
83656
84427
  });
83657
- return null;
83658
- }
83659
- const line = measure.lines[lineIndex];
83660
- const isRTL = isRtlBlock(block);
83661
- const indentLeft = typeof block.attrs?.indent?.left === "number" ? block.attrs.indent.left : 0;
83662
- const indentRight = typeof block.attrs?.indent?.right === "number" ? block.attrs.indent.right : 0;
83663
- const paraIndentLeft = Number.isFinite(indentLeft) ? indentLeft : 0;
83664
- const paraIndentRight = Number.isFinite(indentRight) ? indentRight : 0;
83665
- const totalIndent = paraIndentLeft + paraIndentRight;
83666
- const availableWidth = Math.max(0, fragment.width - totalIndent);
83667
- if (totalIndent > fragment.width) {
83668
- console.warn(
83669
- `[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.`
83670
- );
84428
+ return {
84429
+ pos,
84430
+ blockId: fragment.blockId,
84431
+ pageIndex,
84432
+ column,
84433
+ lineIndex
84434
+ // lineIndex is now already absolute (within measure.lines), no need to add fragment.fromLine
84435
+ };
83671
84436
  }
83672
- const markerWidth = fragment.markerWidth ?? measure.marker?.markerWidth ?? 0;
83673
- const isListItem3 = markerWidth > 0;
83674
- const alignmentOverride = isListItem3 ? "left" : void 0;
83675
- const pos = mapPointToPm(block, line, pageRelativePoint.x - fragment.x, isRTL, availableWidth, alignmentOverride);
83676
- if (pos == null) {
83677
- logClickStage("warn", "no-position", {
83678
- blockId: fragment.blockId
84437
+ if (isAtomicFragment(fragment)) {
84438
+ const pmRange = getAtomicPmRange(fragment, block);
84439
+ const pos = pmRange.pmStart ?? pmRange.pmEnd ?? null;
84440
+ if (pos == null) {
84441
+ logClickStage("warn", "atomic-without-range", {
84442
+ fragmentId: fragment.blockId
84443
+ });
84444
+ return null;
84445
+ }
84446
+ logClickStage("log", "success", {
84447
+ blockId: fragment.blockId,
84448
+ column: determineColumn(layout, fragment.x)
83679
84449
  });
83680
- return null;
84450
+ return {
84451
+ pos,
84452
+ blockId: fragment.blockId,
84453
+ pageIndex,
84454
+ column: determineColumn(layout, fragment.x),
84455
+ lineIndex: -1
84456
+ };
83681
84457
  }
83682
- const column = determineColumn(layout, fragment.x);
83683
- logPositionDebug({
83684
- blockId: fragment.blockId,
83685
- x: pageRelativePoint.x - fragment.x
83686
- });
83687
- logClickStage("log", "success", {
83688
- blockId: fragment.blockId
83689
- });
83690
- return {
83691
- pos,
83692
- blockId: fragment.blockId,
83693
- pageIndex,
83694
- column,
83695
- lineIndex
83696
- // lineIndex is now already absolute (within measure.lines), no need to add fragment.fromLine
83697
- };
83698
84458
  }
83699
84459
  const tableHit = hitTestTableFragment(pageHit, blocks, measures, pageRelativePoint);
83700
84460
  if (tableHit) {
@@ -83844,12 +84604,22 @@ const sumLineHeights = (measure, fromLine, toLine) => {
83844
84604
  }
83845
84605
  return height;
83846
84606
  };
83847
- function selectionToRects(layout, blocks, measures, from2, to) {
84607
+ const calculatePageTopFallback = (layout, pageIndex) => {
84608
+ const pageGap = layout.pageGap ?? 0;
84609
+ let y2 = 0;
84610
+ for (let i = 0; i < pageIndex; i++) {
84611
+ const pageHeight = layout.pages[i]?.size?.h ?? layout.pageSize.h;
84612
+ y2 += pageHeight + pageGap;
84613
+ }
84614
+ return y2;
84615
+ };
84616
+ function selectionToRects(layout, blocks, measures, from2, to, geometryHelper) {
83848
84617
  if (from2 === to) {
83849
84618
  return [];
83850
84619
  }
83851
84620
  const rects = [];
83852
84621
  layout.pages.forEach((page, pageIndex) => {
84622
+ const pageTopY = geometryHelper ? geometryHelper.getPageTop(pageIndex) : calculatePageTopFallback(layout, pageIndex);
83853
84623
  page.fragments.forEach((fragment) => {
83854
84624
  if (fragment.kind === "para") {
83855
84625
  const blockIndex = findBlockIndexByFragmentId(blocks, fragment.blockId, { from: from2, to });
@@ -83891,12 +84661,16 @@ function selectionToRects(layout, blocks, measures, from2, to) {
83891
84661
  wordLayout
83892
84662
  });
83893
84663
  const rectX = fragment.x + indentAdjust + Math.min(startX, endX);
83894
- const rectWidth = Math.max(1, Math.abs(endX - startX));
84664
+ const rectWidth = Math.max(
84665
+ 1,
84666
+ Math.min(Math.abs(endX - startX), line.width)
84667
+ // clamp to line width to prevent runaway widths
84668
+ );
83895
84669
  const lineOffset = lineHeightBeforeIndex(measure, index2) - lineHeightBeforeIndex(measure, fragment.fromLine);
83896
84670
  const rectY = fragment.y + lineOffset;
83897
84671
  rects.push({
83898
84672
  x: rectX,
83899
- y: rectY + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84673
+ y: rectY + pageTopY,
83900
84674
  width: rectWidth,
83901
84675
  height: line.lineHeight,
83902
84676
  pageIndex
@@ -84024,12 +84798,16 @@ function selectionToRects(layout, blocks, measures, from2, to) {
84024
84798
  wordLayout: cellWordLayout
84025
84799
  });
84026
84800
  const rectX = fragment.x + cellX + padding.left + textIndentAdjust + Math.min(startX, endX);
84027
- const rectWidth = Math.max(1, Math.abs(endX - startX));
84801
+ const rectWidth = Math.max(
84802
+ 1,
84803
+ Math.min(Math.abs(endX - startX), line.width)
84804
+ // clamp to line width to prevent runaway widths
84805
+ );
84028
84806
  const lineOffset = lineHeightBeforeIndex(info.measure, index2) - lineHeightBeforeIndex(info.measure, info.startLine);
84029
84807
  const rectY = fragment.y + rowOffset + blockTopCursor + lineOffset;
84030
84808
  rects.push({
84031
84809
  x: rectX,
84032
- y: rectY + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84810
+ y: rectY + pageTopY,
84033
84811
  width: rectWidth,
84034
84812
  height: line.lineHeight,
84035
84813
  pageIndex
@@ -84058,7 +84836,7 @@ function selectionToRects(layout, blocks, measures, from2, to) {
84058
84836
  if (!rangesOverlap(pmRange.pmStart, pmRange.pmEnd, from2, to)) return;
84059
84837
  rects.push({
84060
84838
  x: fragment.x,
84061
- y: fragment.y + pageIndex * (layout.pageSize.h + (layout.pageGap ?? 0)),
84839
+ y: fragment.y + pageTopY,
84062
84840
  width: fragment.width,
84063
84841
  height: fragment.height,
84064
84842
  pageIndex
@@ -85174,7 +85952,7 @@ async function measureParagraphBlock(block, maxWidth) {
85174
85952
  const wordEndWithSpace = charPosInRun + (isLastWord ? word.length : word.length + 1);
85175
85953
  const effectiveMaxWidth = currentLine ? currentLine.maxWidth : getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
85176
85954
  if (wordOnlyWidth > effectiveMaxWidth && word.length > 1) {
85177
- if (currentLine && currentLine.width > 0 && currentLine.segments.length > 0) {
85955
+ if (currentLine && currentLine.width > 0 && currentLine.segments && currentLine.segments.length > 0) {
85178
85956
  const metrics = calculateTypographyMetrics(currentLine.maxFontSize, spacing, currentLine.maxFontInfo);
85179
85957
  const { spaceCount: _sc, ...lineBase } = currentLine;
85180
85958
  const completedLine = { ...lineBase, ...metrics };
@@ -85185,7 +85963,7 @@ async function measureParagraphBlock(block, maxWidth) {
85185
85963
  currentLine = null;
85186
85964
  }
85187
85965
  const lineMaxWidth = getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
85188
- const hasTabOnlyLine = currentLine && currentLine.segments.length === 0 && currentLine.width > 0;
85966
+ const hasTabOnlyLine = currentLine && currentLine.segments && currentLine.segments.length === 0 && currentLine.width > 0;
85189
85967
  const remainingWidthAfterTab = hasTabOnlyLine ? currentLine.maxWidth - currentLine.width : lineMaxWidth;
85190
85968
  const chunkWidth = hasTabOnlyLine ? Math.max(remainingWidthAfterTab, lineMaxWidth * 0.25) : lineMaxWidth;
85191
85969
  const chunks = breakWordIntoChunks(word, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run2);
@@ -85196,7 +85974,7 @@ async function measureParagraphBlock(block, maxWidth) {
85196
85974
  const chunkEndChar = chunkCharOffset + chunk.text.length;
85197
85975
  const isLastChunk = chunkIndex === chunks.length - 1;
85198
85976
  const isFirstChunk = chunkIndex === 0;
85199
- if (isFirstChunk && hasTabOnlyLine && currentLine) {
85977
+ if (isFirstChunk && hasTabOnlyLine && currentLine && currentLine.segments) {
85200
85978
  currentLine.toRun = runIndex;
85201
85979
  currentLine.toChar = chunkEndChar;
85202
85980
  currentLine.width = roundValue(currentLine.width + chunk.width);
@@ -86029,6 +86807,7 @@ const createHeaderFooterEditor = ({
86029
86807
  const fontSizeInPixles = fontSizePt * 1.3333;
86030
86808
  const lineHeight2 = fontSizeInPixles * 1.2;
86031
86809
  applyStyleIsolationClass(editorContainer);
86810
+ const isFooter = type2 === "footer";
86032
86811
  Object.assign(editorContainer.style, {
86033
86812
  padding: "0",
86034
86813
  margin: "0",
@@ -86043,7 +86822,7 @@ const createHeaderFooterEditor = ({
86043
86822
  fontFamily: fontFamilyCss || typeface,
86044
86823
  fontSize: `${fontSizeInPixles}px`,
86045
86824
  lineHeight: `${lineHeight2}px`,
86046
- overflow: "hidden",
86825
+ overflow: isFooter ? "visible" : "hidden",
86047
86826
  pointerEvents: "auto",
86048
86827
  // Critical: enables click interaction
86049
86828
  backgroundColor: "white"
@@ -87122,6 +87901,7 @@ class EditorOverlayManager {
87122
87901
  const editorContainer = __privateGet$1(this, _activeEditorHost).querySelector(".super-editor");
87123
87902
  if (editorContainer instanceof HTMLElement) {
87124
87903
  editorContainer.style.top = "0";
87904
+ editorContainer.style.transform = "";
87125
87905
  }
87126
87906
  }
87127
87907
  }
@@ -87297,6 +88077,7 @@ const DEFAULT_PAGE_SIZE = { w: 612, h: 792 };
87297
88077
  const DEFAULT_MARGINS = { top: 72, right: 72, bottom: 72, left: 72 };
87298
88078
  const DEFAULT_VIRTUALIZED_PAGE_GAP = 72;
87299
88079
  const DEFAULT_PAGE_GAP = 24;
88080
+ const DEFAULT_HORIZONTAL_PAGE_GAP = 20;
87300
88081
  const WORD_CHARACTER_REGEX = /[\p{L}\p{N}''_~-]/u;
87301
88082
  const MULTI_CLICK_TIME_THRESHOLD_MS = 400;
87302
88083
  const MULTI_CLICK_DISTANCE_THRESHOLD_PX = 5;
@@ -87320,6 +88101,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87320
88101
  __privateAdd$1(this, _layoutOptions);
87321
88102
  __privateAdd$1(this, _layoutState, { blocks: [], measures: [], layout: null, bookmarks: /* @__PURE__ */ new Map() });
87322
88103
  __privateAdd$1(this, _domPainter, null);
88104
+ __privateAdd$1(this, _pageGeometryHelper, null);
87323
88105
  __privateAdd$1(this, _dragHandlerCleanup, null);
87324
88106
  __privateAdd$1(this, _layoutError, null);
87325
88107
  __privateAdd$1(this, _layoutErrorState, "healthy");
@@ -87472,7 +88254,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87472
88254
  { x: x2, y: y2 },
87473
88255
  __privateGet$1(this, _viewportHost),
87474
88256
  event.clientX,
87475
- event.clientY
88257
+ event.clientY,
88258
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
87476
88259
  );
87477
88260
  const doc22 = __privateGet$1(this, _editor3).state?.doc;
87478
88261
  const hit = rawHit && doc22 ? { ...rawHit, pos: Math.max(0, Math.min(rawHit.pos, doc22.content.size)) } : rawHit;
@@ -87671,7 +88454,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
87671
88454
  { x: normalized.x, y: normalized.y },
87672
88455
  __privateGet$1(this, _viewportHost),
87673
88456
  event.clientX,
87674
- event.clientY
88457
+ event.clientY,
88458
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
87675
88459
  );
87676
88460
  if (!hit) return;
87677
88461
  const currentTableHit = __privateMethod$1(this, _PresentationEditor_instances, hitTestTable_fn).call(this, normalized.x, normalized.y);
@@ -88518,7 +89302,14 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88518
89302
  return __privateMethod$1(this, _PresentationEditor_instances, computeHeaderFooterSelectionRects_fn).call(this, start2, end2);
88519
89303
  }
88520
89304
  if (!__privateGet$1(this, _layoutState).layout) return [];
88521
- const rects = selectionToRects(__privateGet$1(this, _layoutState).layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, start2, end2) ?? [];
89305
+ const rects = selectionToRects(
89306
+ __privateGet$1(this, _layoutState).layout,
89307
+ __privateGet$1(this, _layoutState).blocks,
89308
+ __privateGet$1(this, _layoutState).measures,
89309
+ start2,
89310
+ end2,
89311
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
89312
+ ) ?? [];
88522
89313
  return rects;
88523
89314
  };
88524
89315
  const rawRects = layoutRectSource();
@@ -88783,6 +89574,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88783
89574
  };
88784
89575
  }
88785
89576
  __privateSet(this, _domPainter, null);
89577
+ __privateSet(this, _pageGeometryHelper, null);
88786
89578
  __privateSet(this, _pendingDocChange, true);
88787
89579
  __privateMethod$1(this, _PresentationEditor_instances, scheduleRerender_fn).call(this);
88788
89580
  }
@@ -88815,7 +89607,16 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88815
89607
  x: localX,
88816
89608
  y: headerPageIndex * headerPageHeight + (localY - headerPageIndex * headerPageHeight)
88817
89609
  };
88818
- const hit2 = clickToPosition(context.layout, context.blocks, context.measures, headerPoint) ?? null;
89610
+ const hit2 = clickToPosition(
89611
+ context.layout,
89612
+ context.blocks,
89613
+ context.measures,
89614
+ headerPoint,
89615
+ void 0,
89616
+ void 0,
89617
+ void 0,
89618
+ void 0
89619
+ ) ?? null;
88819
89620
  return hit2;
88820
89621
  }
88821
89622
  if (!__privateGet$1(this, _layoutState).layout) {
@@ -88828,7 +89629,8 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
88828
89629
  normalized,
88829
89630
  __privateGet$1(this, _viewportHost),
88830
89631
  clientX,
88831
- clientY
89632
+ clientY,
89633
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
88832
89634
  ) ?? null;
88833
89635
  return hit;
88834
89636
  }
@@ -89051,6 +89853,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
89051
89853
  __privateSet(this, _session, { mode: "body" });
89052
89854
  __privateSet(this, _activeHeaderFooterEditor, null);
89053
89855
  __privateSet(this, _domPainter, null);
89856
+ __privateSet(this, _pageGeometryHelper, null);
89054
89857
  (_a2 = __privateGet$1(this, _dragHandlerCleanup)) == null ? void 0 : _a2.call(this);
89055
89858
  __privateSet(this, _dragHandlerCleanup, null);
89056
89859
  __privateGet$1(this, _selectionOverlay2)?.remove();
@@ -89104,7 +89907,14 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
89104
89907
  if (!normalized) return false;
89105
89908
  const pmPos = __privateGet$1(this, _layoutState).bookmarks.get(normalized);
89106
89909
  if (pmPos == null) return false;
89107
- const rects = selectionToRects(layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, pmPos, pmPos + 1) ?? [];
89910
+ const rects = selectionToRects(
89911
+ layout,
89912
+ __privateGet$1(this, _layoutState).blocks,
89913
+ __privateGet$1(this, _layoutState).measures,
89914
+ pmPos,
89915
+ pmPos + 1,
89916
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
89917
+ ) ?? [];
89108
89918
  const rect = rects[0];
89109
89919
  let pageIndex = rect?.pageIndex ?? null;
89110
89920
  if (pageIndex == null) {
@@ -89168,6 +89978,7 @@ _hiddenHost = /* @__PURE__ */ new WeakMap();
89168
89978
  _layoutOptions = /* @__PURE__ */ new WeakMap();
89169
89979
  _layoutState = /* @__PURE__ */ new WeakMap();
89170
89980
  _domPainter = /* @__PURE__ */ new WeakMap();
89981
+ _pageGeometryHelper = /* @__PURE__ */ new WeakMap();
89171
89982
  _dragHandlerCleanup = /* @__PURE__ */ new WeakMap();
89172
89983
  _layoutError = /* @__PURE__ */ new WeakMap();
89173
89984
  _layoutErrorState = /* @__PURE__ */ new WeakMap();
@@ -89400,18 +90211,19 @@ normalizeAwarenessStates_fn = function() {
89400
90211
  const normalized = /* @__PURE__ */ new Map();
89401
90212
  states?.forEach((aw, clientId) => {
89402
90213
  if (clientId === provider.awareness?.clientID) return;
89403
- if (!aw.cursor) return;
90214
+ const awState = aw;
90215
+ if (!awState.cursor) return;
89404
90216
  try {
89405
90217
  const anchor = relativePositionToAbsolutePosition(
89406
90218
  ystate.doc,
89407
90219
  ystate.type,
89408
- Y__namespace.createRelativePositionFromJSON(aw.cursor.anchor),
90220
+ Y__namespace.createRelativePositionFromJSON(awState.cursor.anchor),
89409
90221
  ystate.binding.mapping
89410
90222
  );
89411
90223
  const head = relativePositionToAbsolutePosition(
89412
90224
  ystate.doc,
89413
90225
  ystate.type,
89414
- Y__namespace.createRelativePositionFromJSON(aw.cursor.head),
90226
+ Y__namespace.createRelativePositionFromJSON(awState.cursor.head),
89415
90227
  ystate.binding.mapping
89416
90228
  );
89417
90229
  if (anchor === null || head === null) return;
@@ -89423,9 +90235,9 @@ normalizeAwarenessStates_fn = function() {
89423
90235
  normalized.set(clientId, {
89424
90236
  clientId,
89425
90237
  user: {
89426
- name: aw.user?.name,
89427
- email: aw.user?.email,
89428
- color: aw.user?.color || __privateMethod$1(this, _PresentationEditor_instances, getFallbackColor_fn).call(this, clientId)
90238
+ name: awState.user?.name,
90239
+ email: awState.user?.email,
90240
+ color: awState.user?.color || __privateMethod$1(this, _PresentationEditor_instances, getFallbackColor_fn).call(this, clientId)
89429
90241
  },
89430
90242
  anchor: clampedAnchor,
89431
90243
  head: clampedHead,
@@ -89626,7 +90438,7 @@ renderRemoteSelection_fn = function(cursor) {
89626
90438
  if (!layout || !blocks || !measures) return;
89627
90439
  const start2 = Math.min(cursor.anchor, cursor.head);
89628
90440
  const end2 = Math.max(cursor.anchor, cursor.head);
89629
- const rects = selectionToRects(layout, blocks, measures, start2, end2) ?? [];
90441
+ const rects = selectionToRects(layout, blocks, measures, start2, end2, __privateGet$1(this, _pageGeometryHelper) ?? void 0) ?? [];
89630
90442
  const color = __privateMethod$1(this, _PresentationEditor_instances, getValidatedColor_fn).call(this, cursor);
89631
90443
  const opacity = __privateGet$1(this, _layoutOptions).presence?.highlightOpacity ?? 0.35;
89632
90444
  const pageHeight = layout.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
@@ -89986,15 +90798,25 @@ hitTestTable_fn = function(normalizedX, normalizedY) {
89986
90798
  const configuredPageSize = __privateGet$1(this, _layoutOptions).pageSize ?? DEFAULT_PAGE_SIZE;
89987
90799
  let pageY = 0;
89988
90800
  let pageHit = null;
89989
- for (let i = 0; i < layout.pages.length; i++) {
89990
- const page = layout.pages[i];
89991
- const pageHeight = page.size?.h ?? configuredPageSize.h;
89992
- const gap = __privateGet$1(this, _layoutOptions).virtualization?.gap ?? DEFAULT_PAGE_GAP;
89993
- if (normalizedY >= pageY && normalizedY < pageY + pageHeight) {
89994
- pageHit = { pageIndex: i, page };
89995
- break;
90801
+ const geometryHelper = __privateGet$1(this, _pageGeometryHelper);
90802
+ if (geometryHelper) {
90803
+ const idx = geometryHelper.getPageIndexAtY(normalizedY) ?? geometryHelper.getNearestPageIndex(normalizedY);
90804
+ if (idx != null && layout.pages[idx]) {
90805
+ pageHit = { pageIndex: idx, page: layout.pages[idx] };
90806
+ pageY = geometryHelper.getPageTop(idx);
90807
+ }
90808
+ }
90809
+ if (!pageHit) {
90810
+ const gap = layout.pageGap ?? __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this);
90811
+ for (let i = 0; i < layout.pages.length; i++) {
90812
+ const page = layout.pages[i];
90813
+ const pageHeight = page.size?.h ?? configuredPageSize.h;
90814
+ if (normalizedY >= pageY && normalizedY < pageY + pageHeight) {
90815
+ pageHit = { pageIndex: i, page };
90816
+ break;
90817
+ }
90818
+ pageY += pageHeight + gap;
89996
90819
  }
89997
- pageY += pageHeight + gap;
89998
90820
  }
89999
90821
  if (!pageHit) {
90000
90822
  return null;
@@ -90246,12 +91068,7 @@ rerender_fn = async function() {
90246
91068
  return;
90247
91069
  }
90248
91070
  ({ layout, measures } = result);
90249
- if (__privateGet$1(this, _layoutOptions).virtualization?.enabled) {
90250
- const gap = __privateGet$1(this, _layoutOptions).virtualization.gap ?? DEFAULT_VIRTUALIZED_PAGE_GAP;
90251
- layout.pageGap = Math.max(0, gap);
90252
- } else {
90253
- layout.pageGap = DEFAULT_PAGE_GAP;
90254
- }
91071
+ layout.pageGap = __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this);
90255
91072
  headerLayouts = result.headers;
90256
91073
  footerLayouts = result.footers;
90257
91074
  } catch (error) {
@@ -90268,6 +91085,17 @@ rerender_fn = async function() {
90268
91085
  __privateSet(this, _layoutState, { blocks, measures, layout, bookmarks, anchorMap });
90269
91086
  __privateSet(this, _headerLayoutResults, headerLayouts ?? null);
90270
91087
  __privateSet(this, _footerLayoutResults, footerLayouts ?? null);
91088
+ if (__privateGet$1(this, _layoutState).layout) {
91089
+ const pageGap = __privateGet$1(this, _layoutState).layout.pageGap ?? __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this);
91090
+ if (!__privateGet$1(this, _pageGeometryHelper)) {
91091
+ __privateSet(this, _pageGeometryHelper, new PageGeometryHelper({
91092
+ layout: __privateGet$1(this, _layoutState).layout,
91093
+ pageGap
91094
+ }));
91095
+ } else {
91096
+ __privateGet$1(this, _pageGeometryHelper).updateLayout(__privateGet$1(this, _layoutState).layout, pageGap);
91097
+ }
91098
+ }
90271
91099
  await __privateMethod$1(this, _PresentationEditor_instances, layoutPerRIdHeaderFooters_fn).call(this, headerFooterInput, layout, sectionMetadata);
90272
91100
  __privateMethod$1(this, _PresentationEditor_instances, updateDecorationProviders_fn).call(this, layout);
90273
91101
  const painter = __privateMethod$1(this, _PresentationEditor_instances, ensurePainter_fn).call(this, blocks, measures);
@@ -90337,7 +91165,8 @@ ensurePainter_fn = function(blocks, measures) {
90337
91165
  pageStyles: __privateGet$1(this, _layoutOptions).pageStyles,
90338
91166
  headerProvider: __privateGet$1(this, _headerDecorationProvider),
90339
91167
  footerProvider: __privateGet$1(this, _footerDecorationProvider),
90340
- ruler: __privateGet$1(this, _layoutOptions).ruler
91168
+ ruler: __privateGet$1(this, _layoutOptions).ruler,
91169
+ pageGap: __privateGet$1(this, _layoutState).layout?.pageGap ?? __privateMethod$1(this, _PresentationEditor_instances, getEffectivePageGap_fn).call(this)
90341
91170
  }));
90342
91171
  }
90343
91172
  return __privateGet$1(this, _domPainter);
@@ -90425,7 +91254,14 @@ updateSelection_fn = function() {
90425
91254
  }
90426
91255
  return;
90427
91256
  }
90428
- const rects = selectionToRects(layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, from2, to) ?? [];
91257
+ const rects = selectionToRects(
91258
+ layout,
91259
+ __privateGet$1(this, _layoutState).blocks,
91260
+ __privateGet$1(this, _layoutState).measures,
91261
+ from2,
91262
+ to,
91263
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
91264
+ ) ?? [];
90429
91265
  let domStart = null;
90430
91266
  let domEnd = null;
90431
91267
  try {
@@ -90439,7 +91275,9 @@ updateSelection_fn = function() {
90439
91275
  const correctedRects = __privateMethod$1(this, _PresentationEditor_instances, applyDomCorrectionToRects_fn).call(this, rects, domStart, domEnd);
90440
91276
  try {
90441
91277
  __privateGet$1(this, _localSelectionLayer).innerHTML = "";
90442
- __privateMethod$1(this, _PresentationEditor_instances, renderSelectionRects_fn).call(this, correctedRects);
91278
+ if (correctedRects.length > 0) {
91279
+ __privateMethod$1(this, _PresentationEditor_instances, renderSelectionRects_fn).call(this, correctedRects);
91280
+ }
90443
91281
  } catch (error) {
90444
91282
  if (process$1$1.env.NODE_ENV === "development") {
90445
91283
  console.warn("[PresentationEditor] Failed to render selection rects:", error);
@@ -90631,8 +91469,10 @@ createDecorationProvider_fn = function(kind, layout) {
90631
91469
  const pageHeight2 = page?.size?.h ?? layout.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
90632
91470
  const margins2 = pageMargins ?? layout.pages[0]?.margins ?? __privateGet$1(this, _layoutOptions).margins ?? DEFAULT_MARGINS;
90633
91471
  const box2 = __privateMethod$1(this, _PresentationEditor_instances, computeDecorationBox_fn).call(this, kind, margins2, pageHeight2);
91472
+ const layoutMinY2 = rIdLayout.layout.minY ?? 0;
91473
+ const normalizedFragments2 = layoutMinY2 < 0 ? fragments2.map((f2) => ({ ...f2, y: f2.y - layoutMinY2 })) : fragments2;
90634
91474
  return {
90635
- fragments: fragments2,
91475
+ fragments: normalizedFragments2,
90636
91476
  height: box2.height,
90637
91477
  contentHeight: rIdLayout.layout.height ?? box2.height,
90638
91478
  offset: box2.offset,
@@ -90640,6 +91480,7 @@ createDecorationProvider_fn = function(kind, layout) {
90640
91480
  contentWidth: box2.width,
90641
91481
  headerId: sectionRId,
90642
91482
  sectionType: headerFooterType,
91483
+ minY: layoutMinY2,
90643
91484
  box: {
90644
91485
  x: box2.x,
90645
91486
  y: box2.offset,
@@ -90672,8 +91513,10 @@ createDecorationProvider_fn = function(kind, layout) {
90672
91513
  const box = __privateMethod$1(this, _PresentationEditor_instances, computeDecorationBox_fn).call(this, kind, margins, pageHeight);
90673
91514
  const fallbackId = __privateGet$1(this, _headerFooterManager)?.getVariantId(kind, headerFooterType);
90674
91515
  const finalHeaderId = sectionRId ?? fallbackId ?? void 0;
91516
+ const layoutMinY = variant.layout.minY ?? 0;
91517
+ const normalizedFragments = layoutMinY < 0 ? fragments.map((f2) => ({ ...f2, y: f2.y - layoutMinY })) : fragments;
90675
91518
  return {
90676
- fragments,
91519
+ fragments: normalizedFragments,
90677
91520
  height: box.height,
90678
91521
  contentHeight: variant.layout.height ?? box.height,
90679
91522
  offset: box.offset,
@@ -90681,6 +91524,7 @@ createDecorationProvider_fn = function(kind, layout) {
90681
91524
  contentWidth: box.width,
90682
91525
  headerId: finalHeaderId,
90683
91526
  sectionType: headerFooterType,
91527
+ minY: layoutMinY,
90684
91528
  box: {
90685
91529
  x: box.x,
90686
91530
  y: box.offset,
@@ -90795,7 +91639,9 @@ rebuildHeaderFooterRegions_fn = function(layout) {
90795
91639
  localX: footerPayload?.hitRegion?.x ?? footerBox.x,
90796
91640
  localY: footerPayload?.hitRegion?.y ?? footerBox.offset,
90797
91641
  width: footerPayload?.hitRegion?.width ?? footerBox.width,
90798
- height: footerPayload?.hitRegion?.height ?? footerBox.height
91642
+ height: footerPayload?.hitRegion?.height ?? footerBox.height,
91643
+ contentHeight: footerPayload?.contentHeight,
91644
+ minY: footerPayload?.minY
90799
91645
  });
90800
91646
  });
90801
91647
  };
@@ -90925,6 +91771,18 @@ enterHeaderFooterMode_fn = async function(region) {
90925
91771
  });
90926
91772
  return;
90927
91773
  }
91774
+ if (region.kind === "footer") {
91775
+ const editorContainer = editorHost.firstElementChild;
91776
+ if (editorContainer instanceof HTMLElement) {
91777
+ editorContainer.style.overflow = "visible";
91778
+ if (region.minY != null && region.minY < 0) {
91779
+ const shiftDown = Math.abs(region.minY);
91780
+ editorContainer.style.transform = `translateY(${shiftDown}px)`;
91781
+ } else {
91782
+ editorContainer.style.transform = "";
91783
+ }
91784
+ }
91785
+ }
90928
91786
  try {
90929
91787
  editor.setEditable(true);
90930
91788
  editor.setOptions({ documentMode: "editing" });
@@ -91207,6 +92065,15 @@ waitForPageMount_fn = async function(pageIndex, options = {}) {
91207
92065
  checkPage();
91208
92066
  });
91209
92067
  };
92068
+ getEffectivePageGap_fn = function() {
92069
+ if (__privateGet$1(this, _layoutOptions).virtualization?.enabled) {
92070
+ return Math.max(0, __privateGet$1(this, _layoutOptions).virtualization.gap ?? DEFAULT_VIRTUALIZED_PAGE_GAP);
92071
+ }
92072
+ if (__privateGet$1(this, _layoutOptions).layoutMode === "horizontal") {
92073
+ return DEFAULT_HORIZONTAL_PAGE_GAP;
92074
+ }
92075
+ return DEFAULT_PAGE_GAP;
92076
+ };
91210
92077
  getBodyPageHeight_fn = function() {
91211
92078
  return __privateGet$1(this, _layoutState).layout?.pageSize?.h ?? __privateGet$1(this, _layoutOptions).pageSize?.h ?? DEFAULT_PAGE_SIZE.h;
91212
92079
  };
@@ -91230,7 +92097,7 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91230
92097
  dy: domStart.y - layoutY
91231
92098
  };
91232
92099
  }
91233
- return rects.map((rect, idx) => {
92100
+ const corrected = rects.map((rect, idx) => {
91234
92101
  const delta = pageDelta[rect.pageIndex];
91235
92102
  let adjustedX = delta ? rect.x + delta.dx : rect.x;
91236
92103
  let adjustedY = delta ? rect.y + delta.dy : rect.y;
@@ -91245,6 +92112,7 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91245
92112
  }
91246
92113
  if (isLastRect && domEnd && rect.pageIndex === domEnd.pageIndex) {
91247
92114
  const endX = domEnd.x;
92115
+ adjustedX = Math.min(adjustedX, endX);
91248
92116
  adjustedWidth = Math.max(1, endX - adjustedX);
91249
92117
  }
91250
92118
  return {
@@ -91254,6 +92122,29 @@ applyDomCorrectionToRects_fn = function(rects, domStart, domEnd) {
91254
92122
  width: adjustedWidth
91255
92123
  };
91256
92124
  });
92125
+ const MAX_DELTA_PX = 12;
92126
+ let invalid = false;
92127
+ if (domStart && corrected[0]) {
92128
+ const dx = Math.abs(corrected[0].x - domStart.x);
92129
+ const dy = Math.abs(corrected[0].y - domStart.y);
92130
+ if (dx > MAX_DELTA_PX || dy > MAX_DELTA_PX) invalid = true;
92131
+ }
92132
+ if (domEnd && corrected[corrected.length - 1]) {
92133
+ const last = corrected[corrected.length - 1];
92134
+ const dx = Math.abs(last.x + last.width - domEnd.x);
92135
+ const dy = Math.abs(last.y - domEnd.y);
92136
+ if (dx > MAX_DELTA_PX || dy > MAX_DELTA_PX) invalid = true;
92137
+ }
92138
+ if (invalid) {
92139
+ console.warn("[SelectionOverlay] Suppressing selection render due to large DOM/Layout mismatch", {
92140
+ domStart,
92141
+ domEnd,
92142
+ rectStart: corrected[0],
92143
+ rectEnd: corrected[corrected.length - 1]
92144
+ });
92145
+ return [];
92146
+ }
92147
+ return corrected;
91257
92148
  };
91258
92149
  renderCellSelectionOverlay_fn = function(selection, layout) {
91259
92150
  const localSelectionLayer = __privateGet$1(this, _localSelectionLayer);
@@ -91537,7 +92428,7 @@ computeHeaderFooterSelectionRects_fn = function(from2, to) {
91537
92428
  return [];
91538
92429
  }
91539
92430
  if (!bodyLayout) return [];
91540
- const rects = selectionToRects(context.layout, context.blocks, context.measures, from2, to) ?? [];
92431
+ const rects = selectionToRects(context.layout, context.blocks, context.measures, from2, to, void 0) ?? [];
91541
92432
  const headerPageHeight = context.layout.pageSize?.h ?? context.region.height ?? 1;
91542
92433
  const bodyPageHeight = __privateMethod$1(this, _PresentationEditor_instances, getBodyPageHeight_fn).call(this);
91543
92434
  return rects.map((rect) => {
@@ -91820,8 +92711,8 @@ computeCaretLayoutRectGeometry_fn = function(pos, includeDomFallback = true) {
91820
92711
  const zoom2 = __privateGet$1(this, _layoutOptions).zoom ?? 1;
91821
92712
  let domCaretX2 = null;
91822
92713
  let domCaretY2 = null;
91823
- const spanEls2 = pageEl2?.querySelectorAll("span[data-pm-start][data-pm-end]") ?? [];
91824
- for (const spanEl of spanEls2) {
92714
+ const spanEls2 = pageEl2?.querySelectorAll("span[data-pm-start][data-pm-end]");
92715
+ for (const spanEl of Array.from(spanEls2 ?? [])) {
91825
92716
  const pmStart = Number(spanEl.dataset.pmStart);
91826
92717
  const pmEnd = Number(spanEl.dataset.pmEnd);
91827
92718
  if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
@@ -91873,8 +92764,8 @@ computeCaretLayoutRectGeometry_fn = function(pos, includeDomFallback = true) {
91873
92764
  const zoom = __privateGet$1(this, _layoutOptions).zoom ?? 1;
91874
92765
  let domCaretX = null;
91875
92766
  let domCaretY = null;
91876
- const spanEls = pageEl?.querySelectorAll("span[data-pm-start][data-pm-end]") ?? [];
91877
- for (const spanEl of spanEls) {
92767
+ const spanEls = pageEl?.querySelectorAll("span[data-pm-start][data-pm-end]");
92768
+ for (const spanEl of Array.from(spanEls ?? [])) {
91878
92769
  const pmStart = Number(spanEl.dataset.pmStart);
91879
92770
  const pmEnd = Number(spanEl.dataset.pmEnd);
91880
92771
  if (pos >= pmStart && pos <= pmEnd && spanEl.firstChild?.nodeType === Node.TEXT_NODE) {
@@ -92004,7 +92895,14 @@ getCurrentPageIndex_fn = function() {
92004
92895
  if (!layout || !selection) {
92005
92896
  return 0;
92006
92897
  }
92007
- const rects = selectionToRects(layout, __privateGet$1(this, _layoutState).blocks, __privateGet$1(this, _layoutState).measures, selection.from, selection.to) ?? [];
92898
+ const rects = selectionToRects(
92899
+ layout,
92900
+ __privateGet$1(this, _layoutState).blocks,
92901
+ __privateGet$1(this, _layoutState).measures,
92902
+ selection.from,
92903
+ selection.to,
92904
+ __privateGet$1(this, _pageGeometryHelper) ?? void 0
92905
+ ) ?? [];
92008
92906
  if (rects.length > 0) {
92009
92907
  return rects[0]?.pageIndex ?? 0;
92010
92908
  }
@@ -97436,14 +98334,19 @@ const createCell = (cellType, cellContent = null) => {
97436
98334
  }
97437
98335
  return cellType.createAndFill();
97438
98336
  };
97439
- const createTableBorders = ({ size: size2 = 0.66665, color = "#000000" } = {}) => {
98337
+ const createTableBorders = (borderSpec = {}) => {
98338
+ borderSpec = {
98339
+ size: 0.66665,
98340
+ color: "#000000",
98341
+ ...borderSpec
98342
+ };
97440
98343
  return {
97441
- top: { size: size2, color },
97442
- left: { size: size2, color },
97443
- bottom: { size: size2, color },
97444
- right: { size: size2, color },
97445
- insideH: { size: size2, color },
97446
- insideV: { size: size2, color }
98344
+ top: borderSpec,
98345
+ left: borderSpec,
98346
+ bottom: borderSpec,
98347
+ right: borderSpec,
98348
+ insideH: borderSpec,
98349
+ insideV: borderSpec
97447
98350
  };
97448
98351
  };
97449
98352
  const createTable = (schema, rowsCount, colsCount, withHeaderRow, cellContent = null) => {
@@ -97571,12 +98474,17 @@ const deleteTableWhenSelected = ({ editor }) => {
97571
98474
  editor.commands.deleteTable();
97572
98475
  return true;
97573
98476
  };
97574
- const createCellBorders = ({ size: size2 = 0.66665, color = "#000000" } = {}) => {
98477
+ const createCellBorders = (borderSpec = {}) => {
98478
+ borderSpec = {
98479
+ size: 0.66665,
98480
+ color: "#000000",
98481
+ ...borderSpec
98482
+ };
97575
98483
  return {
97576
- top: { size: size2, color },
97577
- left: { size: size2, color },
97578
- bottom: { size: size2, color },
97579
- right: { size: size2, color }
98484
+ top: borderSpec,
98485
+ left: borderSpec,
98486
+ bottom: borderSpec,
98487
+ right: borderSpec
97580
98488
  };
97581
98489
  };
97582
98490
  function cellAround($pos) {
@@ -98343,13 +99251,20 @@ const Table = Node$1.create({
98343
99251
  if (["tableCell", "tableHeader"].includes(node.type.name)) {
98344
99252
  tr.setNodeMarkup(pos, void 0, {
98345
99253
  ...node.attrs,
98346
- borders: createCellBorders({ size: 0 })
99254
+ borders: createCellBorders({ size: 0, space: 0, val: "none", color: "auto" })
98347
99255
  });
98348
99256
  }
98349
99257
  });
98350
99258
  tr.setNodeMarkup(table.pos, void 0, {
98351
99259
  ...table.node.attrs,
98352
- borders: createTableBorders({ size: 0 })
99260
+ borders: createTableBorders({ size: 0 }),
99261
+ // TODO: This works around the issue that table borders are duplicated between
99262
+ // the attributes of the table and the tableProperties attribute.
99263
+ // This can be removed when the redundancy is eliminated.
99264
+ tableProperties: {
99265
+ ...table.node.attrs.tableProperties,
99266
+ borders: createTableBorders({ size: 0, space: 0, val: "none", color: "auto" })
99267
+ }
98353
99268
  });
98354
99269
  return true;
98355
99270
  }
@@ -122351,7 +123266,7 @@ const makeDefaultItems = ({
122351
123266
  }
122352
123267
  },
122353
123268
  {
122354
- label: toolbarTexts2.transparentBorders,
123269
+ label: toolbarTexts2.removeBorders,
122355
123270
  command: "deleteCellAndTableBorders",
122356
123271
  icon: toolbarIcons2.deleteBorders,
122357
123272
  bottomBorder: true,
@@ -122932,7 +123847,7 @@ const toolbarTexts = {
122932
123847
  deleteRow: "Delete row",
122933
123848
  deleteColumn: "Delete column",
122934
123849
  deleteTable: "Delete table",
122935
- transparentBorders: "Transparent borders",
123850
+ removeBorders: "Remove borders",
122936
123851
  mergeCells: "Merge cells",
122937
123852
  splitCell: "Split cell",
122938
123853
  fixTables: "Fix tables",
@@ -123970,7 +124885,7 @@ const TEXTS = {
123970
124885
  deleteRow: "Delete row",
123971
124886
  deleteColumn: "Delete column",
123972
124887
  deleteTable: "Delete table",
123973
- transparentBorders: "Transparent borders",
124888
+ removeBorders: "Remove borders",
123974
124889
  mergeCells: "Merge cells",
123975
124890
  splitCell: "Split cell",
123976
124891
  fixTables: "Fix tables",
@@ -124053,7 +124968,7 @@ const tableActionsOptions = [
124053
124968
  }
124054
124969
  },
124055
124970
  {
124056
- label: TEXTS.transparentBorders,
124971
+ label: TEXTS.removeBorders,
124057
124972
  command: "deleteCellAndTableBorders",
124058
124973
  icon: ICONS.deleteBorders,
124059
124974
  bottomBorder: true,