@harbour-enterprises/superdoc 2.0.0-next.2 → 2.0.0-next.20

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 (34) hide show
  1. package/dist/chunks/{PdfViewer-CWO98Qls.cjs → PdfViewer-Y5Q3KpNr.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-C4xgIIbF.es.js → PdfViewer-ag_ZFG_a.es.js} +1 -1
  3. package/dist/chunks/{index-BY-3Vl72.cjs → index-CWNzyoyI.cjs} +4 -6
  4. package/dist/chunks/{index-s9GUR_Gc.es.js → index-Dymes5hN.es.js} +4 -6
  5. package/dist/chunks/{index-BqPa6D4q-8U4x8RP6.es.js → index-XnRj2biz-CWqMvtJZ.es.js} +1 -1
  6. package/dist/chunks/{index-BqPa6D4q-Dulj8zfc.cjs → index-XnRj2biz-DiLIwrZX.cjs} +1 -1
  7. package/dist/chunks/{super-editor.es-CT28vUbx.es.js → super-editor.es-BBUBeVVw.es.js} +950 -202
  8. package/dist/chunks/{super-editor.es-BM-ulSRj.cjs → super-editor.es-DwEkOdPH.cjs} +950 -202
  9. package/dist/packages/superdoc/src/core/SuperDoc.d.ts +3 -3
  10. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  11. package/dist/packages/superdoc/src/core/types/index.d.ts +173 -0
  12. package/dist/packages/superdoc/src/core/types/index.d.ts.map +1 -1
  13. package/dist/packages/superdoc/src/stores/comments-store.d.ts.map +1 -1
  14. package/dist/style.css +14 -6
  15. package/dist/super-editor/ai-writer.es.js +2 -2
  16. package/dist/super-editor/chunks/{converter-CDlAWcRu.js → converter-CFpzAUl1.js} +49 -9
  17. package/dist/super-editor/chunks/{docx-zipper-B2VXuf8h.js → docx-zipper-B4U-khNy.js} +1 -1
  18. package/dist/super-editor/chunks/{editor-B4Q_tNET.js → editor-CUCVDSiG.js} +894 -196
  19. package/dist/super-editor/chunks/{index-BqPa6D4q.js → index-XnRj2biz.js} +1 -1
  20. package/dist/super-editor/chunks/{toolbar-BD-lDCLr.js → toolbar-DXUz-ZeU.js} +2 -2
  21. package/dist/super-editor/converter.es.js +1 -1
  22. package/dist/super-editor/docx-zipper.es.js +2 -2
  23. package/dist/super-editor/editor.es.js +3 -3
  24. package/dist/super-editor/file-zipper.es.js +1 -1
  25. package/dist/super-editor/style.css +14 -6
  26. package/dist/super-editor/super-editor.es.js +19 -9
  27. package/dist/super-editor/toolbar.es.js +2 -2
  28. package/dist/super-editor.cjs +1 -1
  29. package/dist/super-editor.es.js +1 -1
  30. package/dist/superdoc.cjs +2 -2
  31. package/dist/superdoc.es.js +2 -2
  32. package/dist/superdoc.umd.js +953 -207
  33. package/dist/superdoc.umd.js.map +1 -1
  34. package/package.json +1 -1
@@ -38546,8 +38546,6 @@ const decode$7 = (params2) => {
38546
38546
  );
38547
38547
  const isInternal = parentComment?.isInternal || originalComment.isInternal;
38548
38548
  if (commentsExportType === "external" && isInternal) return;
38549
- const isResolved = !!originalComment.resolvedTime;
38550
- if (isResolved) return;
38551
38549
  if (node.type !== "commentRangeStart" && node.type !== "commentRangeEnd") {
38552
38550
  return;
38553
38551
  }
@@ -39216,11 +39214,15 @@ const encode$1 = (params2, encodedAttrs = {}) => {
39216
39214
  }
39217
39215
  if (elements.length === 1) {
39218
39216
  text = elements[0].text;
39219
- const xmlSpace = encodedAttrs.xmlSpace ?? elements[0]?.attributes?.["xml:space"];
39217
+ const docXmlSpace = params2.converter?.documentAttributes?.["xml:space"];
39218
+ const xmlSpace = encodedAttrs.xmlSpace ?? attributes?.["xml:space"] ?? elements[0]?.attributes?.["xml:space"] ?? docXmlSpace;
39220
39219
  if (xmlSpace !== "preserve" && typeof text === "string") {
39221
39220
  text = text.replace(/^[ \t\n\r]+/, "").replace(/[ \t\n\r]+$/, "");
39222
39221
  }
39223
39222
  text = text.replace(/\[\[sdspace\]\]/g, "");
39223
+ if (xmlSpace !== "preserve" && typeof text === "string" && !text.trim()) {
39224
+ return null;
39225
+ }
39224
39226
  } else if (!elements.length && encodedAttrs.xmlSpace === "preserve") {
39225
39227
  text = " ";
39226
39228
  } else return null;
@@ -42203,8 +42205,46 @@ const _SuperConverter = class _SuperConverter2 {
42203
42205
  this.declaration = this.initialJSON?.declaration;
42204
42206
  this.resolveDocumentGuid();
42205
42207
  }
42208
+ /**
42209
+ * Parses XML content into JSON format while preserving whitespace-only text runs.
42210
+ *
42211
+ * This method wraps xml-js's xml2json parser with additional preprocessing to prevent
42212
+ * the parser from dropping whitespace-only content in <w:t> and <w:delText> elements.
42213
+ * This is critical for correctly handling documents that rely on document-level
42214
+ * xml:space="preserve" rather than per-element attributes, which is common in
42215
+ * PDF-to-DOCX converted documents.
42216
+ *
42217
+ * The whitespace preservation strategy:
42218
+ * 1. Before parsing, wraps whitespace-only content with [[sdspace]] placeholders
42219
+ * 2. xml-js parser preserves the placeholder-wrapped text
42220
+ * 3. During text node processing (t-translator.js), placeholders are removed
42221
+ *
42222
+ * @param {string} xml - The XML string to parse
42223
+ * @returns {Object} The parsed JSON representation of the XML document
42224
+ *
42225
+ * @example
42226
+ * // Handles whitespace-only text runs
42227
+ * const xml = '<w:t> </w:t>';
42228
+ * const result = parseXmlToJson(xml);
42229
+ * // Result preserves the space: { elements: [{ text: '[[sdspace]] [[sdspace]]' }] }
42230
+ *
42231
+ * @example
42232
+ * // Handles elements with attributes
42233
+ * const xml = '<w:t xml:space="preserve"> text </w:t>';
42234
+ * const result = parseXmlToJson(xml);
42235
+ * // Preserves content and attributes
42236
+ *
42237
+ * @example
42238
+ * // Handles both w:t and w:delText elements
42239
+ * const xml = '<w:delText> </w:delText>';
42240
+ * const result = parseXmlToJson(xml);
42241
+ * // Preserves whitespace in deleted text
42242
+ */
42206
42243
  parseXmlToJson(xml) {
42207
- const newXml = xml.replace(/(<w:t xml:space="preserve">)(\s+)(<\/w:t>)/g, "$1[[sdspace]]$2[[sdspace]]$3");
42244
+ const newXml = xml.replace(
42245
+ /(<w:(?:t|delText)(?:\s[^>]*)?>)(\s+)(<\/w:(?:t|delText)>)/g,
42246
+ "$1[[sdspace]]$2[[sdspace]]$3"
42247
+ );
42208
42248
  return JSON.parse(xmljs.xml2json(newXml, null, 2));
42209
42249
  }
42210
42250
  /**
@@ -42427,7 +42467,7 @@ const _SuperConverter = class _SuperConverter2 {
42427
42467
  static getStoredSuperdocVersion(docx) {
42428
42468
  return _SuperConverter2.getStoredCustomProperty(docx, "SuperdocVersion");
42429
42469
  }
42430
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "2.0.0-next.2") {
42470
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "2.0.0-next.20") {
42431
42471
  return _SuperConverter2.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
42432
42472
  }
42433
42473
  /**
@@ -45739,7 +45779,7 @@ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "rea
45739
45779
  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);
45740
45780
  var __privateSet = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
45741
45781
  var __privateMethod$1 = (obj, member, method) => (__accessCheck$1(obj, member, "access private method"), method);
45742
- var _a, _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, _currentEpoch, _mapsByFromEpoch, _maxEpochsToKeep, _EpochPositionMapper_instances, pruneByCurrentEpoch_fn, _entries, _windowRoot, _getPainterHost, _onRebuild, _observer, _rebuildScheduled, _rebuildRafId, _docEpoch, _layoutEpoch, _layoutUpdating, _pending, _scheduled, _rafHandle, _scheduler, _SelectionSyncCoordinator_instances, isSafeToRender_fn, maybeSchedule_fn, cancelScheduledRender_fn, _windowRoot2, _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, _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, _selectionSync, _remoteCursorUpdateScheduled, _epochMapper, _layoutEpoch2, _domPositionIndex, _domIndexObserverManager, _debugLastPointer, _debugLastHit, _pendingMarginClick, _rafHandle2, _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, _a11ySelectionAnnounceTimeout, _a11yLastAnnouncedSelectionKey, _hoverRegion, _clickCount, _lastClickTime, _lastClickPosition, _lastSelectedImageBlockId, _dragAnchor, _dragAnchorPageIndex, _isDragging, _dragExtensionMode, _dragLastPointer, _dragLastRawHit, _dragUsedPageNotMountedFallback, _cellAnchor, _cellDragMode, _remoteCursorState, _remoteCursorElements, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _scrollTimeout, _lastRemoteCursorRenderTime, _remoteCursorThrottleTimeout, _PresentationEditor_instances, wrapHiddenEditorFocus_fn, collectCommentPositions_fn, updateSelectionDebugHud_fn, computePendingMarginClick_fn, aggregateLayoutBounds_fn, rebuildDomPositionIndex_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, updateLocalAwarenessCursor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_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, _handlePointerMove, _handlePointerLeave, _handleVisibleHostFocusIn, _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, syncHiddenEditorA11yAttributes_fn, scheduleA11ySelectionAnnouncement_fn, announceSelectionNow_fn, validateHeaderFooterEditPermission_fn, emitHeaderFooterEditBlocked_fn, resolveDescriptorForRegion_fn, createDefaultHeaderFooter_fn, getPageElement_fn, isSelectionAwareVirtualizationEnabled_fn, updateSelectionVirtualizationPins_fn, finalizeDragSelectionWithDom_fn, scrollPageIntoView_fn, waitForPageMount_fn, getEffectivePageGap_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, renderCellSelectionOverlay_fn, renderHoverRegion_fn, clearHoverRegion_fn, getHeaderFooterContext_fn, computeHeaderFooterSelectionRects_fn, syncTrackedChangesPreferences_fn, deriveTrackedChangesMode_fn, deriveTrackedChangesEnabled_fn, getTrackChangesPluginState_fn, computeDefaultLayoutDefaults_fn, applyZoom_fn, getPageOffsetX_fn, convertPageLocalToOverlayCoords_fn, computeSelectionRectsFromDom_fn, computeDomCaretPageLocal_fn, normalizeClientPoint_fn, computeCaretLayoutRectGeometry_fn, computeCaretLayoutRect_fn, getCurrentPageIndex_fn, findRegionForPage_fn, handleLayoutError_fn, decorateError_fn, showLayoutErrorBanner_fn, dismissErrorBanner_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;
45782
+ var _a, _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, _currentEpoch, _mapsByFromEpoch, _maxEpochsToKeep, _EpochPositionMapper_instances, pruneByCurrentEpoch_fn, _entries, _windowRoot, _getPainterHost, _onRebuild, _observer, _rebuildScheduled, _rebuildRafId, _docEpoch, _layoutEpoch, _layoutUpdating, _pending, _scheduled, _rafHandle, _scheduler, _SelectionSyncCoordinator_instances, isSafeToRender_fn, maybeSchedule_fn, cancelScheduledRender_fn, _windowRoot2, _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, _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, _selectionSync, _remoteCursorUpdateScheduled, _epochMapper, _layoutEpoch2, _domPositionIndex, _domIndexObserverManager, _debugLastPointer, _debugLastHit, _pendingMarginClick, _rafHandle2, _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, _a11ySelectionAnnounceTimeout, _a11yLastAnnouncedSelectionKey, _hoverRegion, _clickCount, _lastClickTime, _lastClickPosition, _lastSelectedImageBlockId, _dragAnchor, _dragAnchorPageIndex, _isDragging, _dragExtensionMode, _dragLastPointer, _dragLastRawHit, _dragUsedPageNotMountedFallback, _cellAnchor, _cellDragMode, _remoteCursorState, _remoteCursorElements, _remoteCursorDirty, _remoteCursorOverlay, _localSelectionLayer, _awarenessCleanup, _scrollCleanup, _scrollTimeout, _lastRemoteCursorRenderTime, _remoteCursorThrottleTimeout, _PresentationEditor_instances, wrapHiddenEditorFocus_fn, syncDocumentModeClass_fn, collectCommentPositions_fn, updateSelectionDebugHud_fn, computePendingMarginClick_fn, aggregateLayoutBounds_fn, rebuildDomPositionIndex_fn, setupEditorListeners_fn, setupCollaborationCursors_fn, updateLocalAwarenessCursor_fn, scheduleRemoteCursorUpdate_fn, scheduleRemoteCursorReRender_fn, updateRemoteCursors_fn, renderRemoteCursors_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, _handlePointerMove, _handlePointerLeave, _handleVisibleHostFocusIn, _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, syncHiddenEditorA11yAttributes_fn, scheduleA11ySelectionAnnouncement_fn, announceSelectionNow_fn, validateHeaderFooterEditPermission_fn, emitHeaderFooterEditBlocked_fn, resolveDescriptorForRegion_fn, createDefaultHeaderFooter_fn, getPageElement_fn, isSelectionAwareVirtualizationEnabled_fn, updateSelectionVirtualizationPins_fn, finalizeDragSelectionWithDom_fn, scrollPageIntoView_fn, waitForPageMount_fn, getEffectivePageGap_fn, getBodyPageHeight_fn, getHeaderFooterPageHeight_fn, renderCellSelectionOverlay_fn, renderHoverRegion_fn, clearHoverRegion_fn, getHeaderFooterContext_fn, computeHeaderFooterSelectionRects_fn, syncTrackedChangesPreferences_fn, deriveTrackedChangesMode_fn, deriveTrackedChangesEnabled_fn, getTrackChangesPluginState_fn, computeDefaultLayoutDefaults_fn, applyZoom_fn, getPageOffsetX_fn, convertPageLocalToOverlayCoords_fn, computeSelectionRectsFromDom_fn, computeDomCaretPageLocal_fn, normalizeClientPoint_fn, computeCaretLayoutRectGeometry_fn, computeCaretLayoutRect_fn, getCurrentPageIndex_fn, findRegionForPage_fn, handleLayoutError_fn, decorateError_fn, showLayoutErrorBanner_fn, dismissErrorBanner_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;
45743
45783
  var GOOD_LEAF_SIZE = 200;
45744
45784
  var RopeSequence = function RopeSequence2() {
45745
45785
  };
@@ -57575,6 +57615,9 @@ const findMarkPosition = (doc2, pos, markName) => {
57575
57615
  return null;
57576
57616
  }
57577
57617
  const actualMark = start2.node.marks.find((mark) => mark.type.name === markName);
57618
+ if (!actualMark) {
57619
+ return null;
57620
+ }
57578
57621
  let startIndex = $pos.index();
57579
57622
  let startPos = $pos.start() + start2.offset;
57580
57623
  while (startIndex > 0 && actualMark.isInSet(parent.child(startIndex - 1).marks)) {
@@ -57864,6 +57907,70 @@ const getCommentPositionsById = (commentId, doc2) => {
57864
57907
  });
57865
57908
  return positions;
57866
57909
  };
57910
+ const getCommentMarkSegmentsById = (commentId, doc2) => {
57911
+ const segments = [];
57912
+ doc2.descendants((node, pos) => {
57913
+ if (!node.isInline) return;
57914
+ const commentMark = node.marks?.find(
57915
+ (mark) => mark.type.name === CommentMarkName$1 && mark.attrs?.commentId === commentId
57916
+ );
57917
+ if (!commentMark) return;
57918
+ segments.push({
57919
+ from: pos,
57920
+ to: pos + node.nodeSize,
57921
+ attrs: commentMark.attrs || {}
57922
+ });
57923
+ });
57924
+ return segments;
57925
+ };
57926
+ const getCommentMarkRangesById = (commentId, doc2) => {
57927
+ const segments = getCommentMarkSegmentsById(commentId, doc2);
57928
+ if (!segments.length) return { segments, ranges: [] };
57929
+ const ranges = [];
57930
+ let active = null;
57931
+ segments.forEach((seg) => {
57932
+ if (!active) {
57933
+ active = {
57934
+ from: seg.from,
57935
+ to: seg.to,
57936
+ internal: !!seg.attrs?.internal
57937
+ };
57938
+ return;
57939
+ }
57940
+ if (seg.from <= active.to) {
57941
+ active.to = Math.max(active.to, seg.to);
57942
+ return;
57943
+ }
57944
+ ranges.push(active);
57945
+ active = {
57946
+ from: seg.from,
57947
+ to: seg.to,
57948
+ internal: !!seg.attrs?.internal
57949
+ };
57950
+ });
57951
+ if (active) ranges.push(active);
57952
+ return { segments, ranges };
57953
+ };
57954
+ const resolveCommentById = ({ commentId, state: state2, tr, dispatch }) => {
57955
+ const { schema } = state2;
57956
+ const markType = schema.marks?.[CommentMarkName$1];
57957
+ if (!markType) return false;
57958
+ const { segments, ranges } = getCommentMarkRangesById(commentId, state2.doc);
57959
+ if (!segments.length) return false;
57960
+ segments.forEach(({ from: from2, to, attrs }) => {
57961
+ tr.removeMark(from2, to, markType.create(attrs));
57962
+ });
57963
+ const startType = schema.nodes?.commentRangeStart;
57964
+ const endType = schema.nodes?.commentRangeEnd;
57965
+ if (startType && endType) {
57966
+ ranges.slice().sort((a, b2) => b2.from - a.from).forEach(({ from: from2, to, internal }) => {
57967
+ tr.insert(to, endType.create({ "w:id": commentId }));
57968
+ tr.insert(from2, startType.create({ "w:id": commentId, internal }));
57969
+ });
57970
+ }
57971
+ dispatch(tr);
57972
+ return true;
57973
+ };
57867
57974
  const prepareCommentsForExport = (doc2, tr, schema, comments = []) => {
57868
57975
  const commentMap = /* @__PURE__ */ new Map();
57869
57976
  comments.forEach((c2) => {
@@ -57970,6 +58077,7 @@ const getPreparedComment = (attrs) => {
57970
58077
  const prepareCommentsForImport = (doc2, tr, schema, converter) => {
57971
58078
  const toMark = [];
57972
58079
  const toDelete = [];
58080
+ const toUpdate = [];
57973
58081
  doc2.descendants((node, pos) => {
57974
58082
  const { type: type2 } = node;
57975
58083
  const commentNodes = ["commentRangeStart", "commentRangeEnd", "commentReference"];
@@ -57978,8 +58086,9 @@ const prepareCommentsForImport = (doc2, tr, schema, converter) => {
57978
58086
  converter,
57979
58087
  importedId: node.attrs["w:id"]
57980
58088
  });
58089
+ const isDone = !!matchingImportedComment?.isDone;
57981
58090
  if (type2.name === "commentRangeStart") {
57982
- if (!matchingImportedComment?.isDone) {
58091
+ if (!isDone) {
57983
58092
  toMark.push({
57984
58093
  commentId: resolvedCommentId,
57985
58094
  importedId,
@@ -57993,8 +58102,29 @@ const prepareCommentsForImport = (doc2, tr, schema, converter) => {
57993
58102
  commentId: resolvedCommentId,
57994
58103
  importedId
57995
58104
  });
57996
- toDelete.push({ start: pos, end: pos + 1 });
58105
+ if (isDone) {
58106
+ toUpdate.push({
58107
+ pos,
58108
+ attrs: {
58109
+ ...node.attrs,
58110
+ "w:id": resolvedCommentId,
58111
+ internal
58112
+ }
58113
+ });
58114
+ } else {
58115
+ toDelete.push({ start: pos, end: pos + 1 });
58116
+ }
57997
58117
  } else if (type2.name === "commentRangeEnd") {
58118
+ if (isDone) {
58119
+ toUpdate.push({
58120
+ pos,
58121
+ attrs: {
58122
+ ...node.attrs,
58123
+ "w:id": resolvedCommentId
58124
+ }
58125
+ });
58126
+ return;
58127
+ }
57998
58128
  const itemToMark = toMark.find((p) => p.importedId === importedId);
57999
58129
  if (!itemToMark) return;
58000
58130
  const { start: start2 } = itemToMark;
@@ -58009,6 +58139,11 @@ const prepareCommentsForImport = (doc2, tr, schema, converter) => {
58009
58139
  toDelete.push({ start: pos, end: pos + 1 });
58010
58140
  }
58011
58141
  });
58142
+ if (typeof tr.setNodeMarkup === "function") {
58143
+ toUpdate.sort((a, b2) => b2.pos - a.pos).forEach(({ pos, attrs }) => {
58144
+ tr.setNodeMarkup(pos, void 0, attrs);
58145
+ });
58146
+ }
58012
58147
  toDelete.sort((a, b2) => b2.start - a.start).forEach(({ start: start2, end: end2 }) => {
58013
58148
  tr.delete(start2, end2);
58014
58149
  });
@@ -58202,7 +58337,7 @@ const CommentsPlugin = Extension.create({
58202
58337
  },
58203
58338
  resolveComment: ({ commentId }) => ({ tr, dispatch, state: state2 }) => {
58204
58339
  tr.setMeta(CommentsPluginKey, { event: "update" });
58205
- removeCommentsById({ commentId, state: state2, tr, dispatch });
58340
+ return resolveCommentById({ commentId, state: state2, tr, dispatch });
58206
58341
  },
58207
58342
  setCursorById: (id) => ({ state: state2, editor }) => {
58208
58343
  const { from: from2 } = findRangeById(state2.doc, id) || {};
@@ -58635,47 +58770,58 @@ function findRangeById(doc2, id) {
58635
58770
  return from2 !== null && to !== null ? { from: from2, to } : null;
58636
58771
  }
58637
58772
  const replaceStep = ({ state: state2, tr, step, newTr, map: map22, user, date, originalStep, originalStepIndex }) => {
58638
- const deletionMarkSchema = state2.schema.marks[TrackDeleteMarkName$1];
58639
- const deletionMark = findMark(state2, deletionMarkSchema, false);
58640
- const positionTo = deletionMark ? deletionMark.to : step.to;
58641
- const newStep = new ReplaceStep(
58642
- positionTo,
58643
- // We insert all the same steps, but with "from"/"to" both set to "to" in order not to delete content. Mapped as needed.
58644
- positionTo,
58645
- step.slice,
58646
- step.structure
58647
- );
58648
- const invertStep = originalStep.invert(tr.docs[originalStepIndex]).map(map22);
58649
- map22.appendMap(invertStep.getMap());
58650
- const meta = {};
58651
- if (newStep) {
58652
- const trTemp = state2.apply(newTr).tr;
58653
- if (trTemp.maybeStep(newStep).failed) {
58654
- return;
58655
- }
58656
- const mappedNewStepTo = newStep.getMap().map(newStep.to);
58657
- const insertedMark = markInsertion({
58658
- tr: trTemp,
58659
- from: newStep.from,
58660
- to: mappedNewStepTo,
58661
- user,
58662
- date
58663
- });
58664
- const condensedStep = new ReplaceStep(newStep.from, newStep.to, trTemp.doc.slice(newStep.from, mappedNewStepTo));
58665
- newTr.step(condensedStep);
58666
- const mirrorIndex = map22.maps.length - 1;
58667
- map22.appendMap(condensedStep.getMap(), mirrorIndex);
58668
- if (newStep.from !== mappedNewStepTo) {
58669
- meta.insertedMark = insertedMark;
58670
- meta.step = condensedStep;
58773
+ const trTemp = state2.apply(newTr).tr;
58774
+ let positionTo = step.to;
58775
+ const probePos = Math.max(step.from, step.to - 1);
58776
+ const deletionSpan = findMarkPosition(trTemp.doc, probePos, TrackDeleteMarkName$1);
58777
+ if (deletionSpan && deletionSpan.to > positionTo) {
58778
+ positionTo = deletionSpan.to;
58779
+ }
58780
+ const tryInsert = (slice2) => {
58781
+ const insertionStep = new ReplaceStep(positionTo, positionTo, slice2, false);
58782
+ if (trTemp.maybeStep(insertionStep).failed) return null;
58783
+ return {
58784
+ insertedFrom: insertionStep.from,
58785
+ insertedTo: insertionStep.getMap().map(insertionStep.to, 1)
58786
+ };
58787
+ };
58788
+ const insertion = tryInsert(step.slice) || tryInsert(Slice.maxOpen(step.slice.content, true));
58789
+ if (!insertion) {
58790
+ if (!newTr.maybeStep(step).failed) {
58791
+ map22.appendMap(step.getMap());
58671
58792
  }
58672
- if (!newTr.selection.eq(trTemp.selection)) {
58673
- newTr.setSelection(trTemp.selection);
58793
+ return;
58794
+ }
58795
+ const meta = {};
58796
+ const insertedMark = markInsertion({
58797
+ tr: trTemp,
58798
+ from: insertion.insertedFrom,
58799
+ to: insertion.insertedTo,
58800
+ user,
58801
+ date
58802
+ });
58803
+ const trackedInsertedSlice = trTemp.doc.slice(insertion.insertedFrom, insertion.insertedTo);
58804
+ const condensedStep = new ReplaceStep(positionTo, positionTo, trackedInsertedSlice, false);
58805
+ if (newTr.maybeStep(condensedStep).failed) {
58806
+ if (!newTr.maybeStep(step).failed) {
58807
+ map22.appendMap(step.getMap());
58674
58808
  }
58809
+ return;
58810
+ }
58811
+ const invertStep = originalStep.invert(tr.docs[originalStepIndex]).map(map22);
58812
+ map22.appendMap(invertStep.getMap());
58813
+ const mirrorIndex = map22.maps.length - 1;
58814
+ map22.appendMap(condensedStep.getMap(), mirrorIndex);
58815
+ if (insertion.insertedFrom !== insertion.insertedTo) {
58816
+ meta.insertedMark = insertedMark;
58817
+ meta.step = condensedStep;
58818
+ }
58819
+ if (!newTr.selection.eq(trTemp.selection)) {
58820
+ newTr.setSelection(trTemp.selection);
58675
58821
  }
58676
58822
  if (step.from !== step.to) {
58677
58823
  const {
58678
- deletionMark: deletionMark2,
58824
+ deletionMark,
58679
58825
  deletionMap,
58680
58826
  nodes: deletionNodes
58681
58827
  } = markDeletion({
@@ -58687,7 +58833,7 @@ const replaceStep = ({ state: state2, tr, step, newTr, map: map22, user, date, o
58687
58833
  id: meta.insertedMark?.attrs?.id
58688
58834
  });
58689
58835
  meta.deletionNodes = deletionNodes;
58690
- meta.deletionMark = deletionMark2;
58836
+ meta.deletionMark = deletionMark;
58691
58837
  map22.appendMapping(deletionMap);
58692
58838
  }
58693
58839
  newTr.setMeta(TrackChangesBasePluginKey, meta);
@@ -60508,7 +60654,7 @@ const isHeadless = (editor) => {
60508
60654
  const shouldSkipNodeView = (editor) => {
60509
60655
  return isHeadless(editor);
60510
60656
  };
60511
- const summaryVersion = "2.0.0-next.2";
60657
+ const summaryVersion = "2.0.0-next.20";
60512
60658
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
60513
60659
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
60514
60660
  function mapAttributes(attrs) {
@@ -61297,7 +61443,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
61297
61443
  { default: remarkStringify },
61298
61444
  { default: remarkGfm }
61299
61445
  ] = await Promise.all([
61300
- Promise.resolve().then(() => require("./index-BqPa6D4q-Dulj8zfc.cjs")),
61446
+ Promise.resolve().then(() => require("./index-XnRj2biz-DiLIwrZX.cjs")),
61301
61447
  Promise.resolve().then(() => require("./index-DRCvimau-H4Ck3S9a.cjs")),
61302
61448
  Promise.resolve().then(() => require("./index-C_x_N6Uh-Db3CUJMX.cjs")),
61303
61449
  Promise.resolve().then(() => require("./index-D_sWOSiG-BtDZzJ6I.cjs")),
@@ -61502,7 +61648,7 @@ const _Editor = class _Editor2 extends EventEmitter$1 {
61502
61648
  * Process collaboration migrations
61503
61649
  */
61504
61650
  processCollaborationMigrations() {
61505
- console.debug("[checkVersionMigrations] Current editor version", "2.0.0-next.2");
61651
+ console.debug("[checkVersionMigrations] Current editor version", "2.0.0-next.20");
61506
61652
  if (!this.options.ydoc) return;
61507
61653
  const metaMap = this.options.ydoc.getMap("meta");
61508
61654
  let docVersion = metaMap.get("version");
@@ -67066,6 +67212,24 @@ const SDT_CONTAINER_STYLES = `
67066
67212
  display: block;
67067
67213
  }
67068
67214
 
67215
+ /* Viewing mode: remove structured content affordances */
67216
+ .presentation-editor--viewing .superdoc-structured-content-block,
67217
+ .presentation-editor--viewing .superdoc-structured-content-inline {
67218
+ background: none;
67219
+ border: none;
67220
+ padding: 0;
67221
+ }
67222
+
67223
+ .presentation-editor--viewing .superdoc-structured-content-inline:hover {
67224
+ background: none;
67225
+ border: none;
67226
+ }
67227
+
67228
+ .presentation-editor--viewing .superdoc-structured-content__label,
67229
+ .presentation-editor--viewing .superdoc-structured-content-inline__label {
67230
+ display: none !important;
67231
+ }
67232
+
67069
67233
  /* Print mode: hide visual styling for SDT containers */
67070
67234
  @media print {
67071
67235
  .superdoc-document-section,
@@ -68754,7 +68918,7 @@ function isMinimalWordLayout(value) {
68754
68918
  return true;
68755
68919
  }
68756
68920
  const LIST_MARKER_GAP$2 = 8;
68757
- const DEFAULT_TAB_INTERVAL_PX$1 = 48;
68921
+ const DEFAULT_TAB_INTERVAL_PX$2 = 48;
68758
68922
  const DEFAULT_PAGE_HEIGHT_PX = 1056;
68759
68923
  const DEFAULT_VIRTUALIZED_PAGE_GAP$1 = 72;
68760
68924
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
@@ -69681,6 +69845,7 @@ const _DomPainter = class _DomPainter2 {
69681
69845
  const block = lookup2.block;
69682
69846
  const measure = lookup2.measure;
69683
69847
  const wordLayout = isMinimalWordLayout(block.attrs?.wordLayout) ? block.attrs.wordLayout : void 0;
69848
+ const alignment2 = block.attrs?.alignment;
69684
69849
  const fragmentEl = this.doc.createElement("div");
69685
69850
  fragmentEl.classList.add(CLASS_NAMES$1.fragment);
69686
69851
  const isTocEntry = block.attrs?.isTocEntry;
@@ -69759,7 +69924,7 @@ const _DomPainter = class _DomPainter2 {
69759
69924
  const textStart = paraIndentLeft + firstLine;
69760
69925
  tabWidth = textStart - currentPos;
69761
69926
  if (tabWidth <= 0) {
69762
- tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
69927
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
69763
69928
  } else if (tabWidth < LIST_MARKER_GAP$2) {
69764
69929
  tabWidth = LIST_MARKER_GAP$2;
69765
69930
  }
@@ -69786,6 +69951,21 @@ const _DomPainter = class _DomPainter2 {
69786
69951
  let availableWidthOverride = line.maxWidth != null ? Math.min(line.maxWidth, fallbackAvailableWidth) : fallbackAvailableWidth;
69787
69952
  if (index2 === 0 && listFirstLineMarkerTabWidth != null) {
69788
69953
  availableWidthOverride = fragment.width - listFirstLineMarkerTabWidth - Math.max(0, paraIndentRight);
69954
+ if (alignment2 === "justify" || alignment2 === "both") {
69955
+ console.log(
69956
+ "[justify-debug][painter-firstline-available]",
69957
+ JSON.stringify({
69958
+ blockId: block.id,
69959
+ fragmentWidth: fragment.width,
69960
+ markerTabWidth: listFirstLineMarkerTabWidth,
69961
+ paraIndentRight,
69962
+ availableWidthOverride,
69963
+ lineMaxWidth: line.maxWidth ?? null,
69964
+ lineWidth: line.width,
69965
+ lineNaturalWidth: line.naturalWidth ?? null
69966
+ })
69967
+ );
69968
+ }
69789
69969
  }
69790
69970
  const isLastLineOfFragment = index2 === lines.length - 1;
69791
69971
  const isLastLineOfParagraph = isLastLineOfFragment && !fragment.continuesOnNext;
@@ -69911,7 +70091,7 @@ const _DomPainter = class _DomPainter2 {
69911
70091
  const textStart = paraIndentLeft + firstLine;
69912
70092
  tabWidth = textStart - currentPos;
69913
70093
  if (tabWidth <= 0) {
69914
- tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
70094
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
69915
70095
  } else if (tabWidth < LIST_MARKER_GAP$2) {
69916
70096
  tabWidth = LIST_MARKER_GAP$2;
69917
70097
  }
@@ -71445,6 +71625,23 @@ const _DomPainter = class _DomPainter2 {
71445
71625
  if (spacingPerSpace !== 0) {
71446
71626
  el.style.wordSpacing = `${spacingPerSpace}px`;
71447
71627
  }
71628
+ if (justifyShouldApply && spacingPerSpace < 0) {
71629
+ console.log(
71630
+ "[justify-debug][painter-wordspacing-negative]",
71631
+ JSON.stringify({
71632
+ blockId: block.id,
71633
+ lineIndex: lineIndex ?? null,
71634
+ alignment: alignment2 ?? null,
71635
+ availableWidth,
71636
+ lineWidth,
71637
+ lineMaxWidth: line.maxWidth ?? null,
71638
+ lineNaturalWidth: line.naturalWidth ?? null,
71639
+ spaceCount,
71640
+ hasExplicitPositioning: Boolean(hasExplicitPositioning),
71641
+ skipJustify: Boolean(skipJustify)
71642
+ })
71643
+ );
71644
+ }
71448
71645
  if (hasExplicitPositioning && line.segments) {
71449
71646
  const paraIndent = block.attrs?.indent;
71450
71647
  const indentLeft = paraIndent?.left ?? 0;
@@ -73638,6 +73835,28 @@ let measurementCtx = null;
73638
73835
  const TAB_CHAR_LENGTH = 1;
73639
73836
  const SPACE_CHARS = SPACE_CHARS$1;
73640
73837
  const isTabRun$1 = (run2) => run2?.kind === "tab";
73838
+ const isWordChar$3 = (char) => {
73839
+ if (!char) return false;
73840
+ const code = char.charCodeAt(0);
73841
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
73842
+ };
73843
+ const capitalizeText$2 = (text) => {
73844
+ if (!text) return text;
73845
+ let result = "";
73846
+ for (let i = 0; i < text.length; i += 1) {
73847
+ const prevChar = i > 0 ? text[i - 1] : "";
73848
+ const ch = text[i];
73849
+ result += isWordChar$3(ch) && !isWordChar$3(prevChar) ? ch.toUpperCase() : ch;
73850
+ }
73851
+ return result;
73852
+ };
73853
+ const applyTextTransform$2 = (text, transform) => {
73854
+ if (!text || !transform || transform === "none") return text;
73855
+ if (transform === "uppercase") return text.toUpperCase();
73856
+ if (transform === "lowercase") return text.toLowerCase();
73857
+ if (transform === "capitalize") return capitalizeText$2(text);
73858
+ return text;
73859
+ };
73641
73860
  function getMeasurementContext() {
73642
73861
  if (measurementCtx) return measurementCtx;
73643
73862
  if (typeof document === "undefined") {
@@ -73813,17 +74032,19 @@ function measureCharacterX(block, line, charOffset, availableWidthOverride, alig
73813
74032
  }
73814
74033
  const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
73815
74034
  const runLength = text.length;
74035
+ const transform = isTabRun$1(run2) || "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? void 0 : run2.textTransform;
74036
+ const displayText = applyTextTransform$2(text, transform);
73816
74037
  if (currentCharOffset + runLength >= charOffset) {
73817
74038
  const offsetInRun = charOffset - currentCharOffset;
73818
74039
  ctx2.font = getRunFontString(run2);
73819
- const textUpToTarget = text.slice(0, offsetInRun);
74040
+ const textUpToTarget = displayText.slice(0, offsetInRun);
73820
74041
  const measured2 = ctx2.measureText(textUpToTarget);
73821
74042
  const spacingWidth = computeLetterSpacingWidth(run2, offsetInRun, runLength);
73822
- const spacesInPortion = justify.extraPerSpace !== 0 ? countSpaces(textUpToTarget) : 0;
74043
+ const spacesInPortion = justify.extraPerSpace !== 0 ? countSpaces(text.slice(0, offsetInRun)) : 0;
73823
74044
  return alignmentOffset + currentX + measured2.width + spacingWidth + justify.extraPerSpace * (spaceTally + spacesInPortion);
73824
74045
  }
73825
74046
  ctx2.font = getRunFontString(run2);
73826
- const measured = ctx2.measureText(text);
74047
+ const measured = ctx2.measureText(displayText);
73827
74048
  const runLetterSpacing = computeLetterSpacingWidth(run2, runLength, runLength);
73828
74049
  const spacesInRun = justify.extraPerSpace !== 0 ? countSpaces(text) : 0;
73829
74050
  currentX += measured.width + runLetterSpacing + justify.extraPerSpace * spacesInRun;
@@ -73862,8 +74083,10 @@ function measureCharacterXSegmentBased(block, line, charOffset, ctx2) {
73862
74083
  return segmentBaseX + (offsetInSegment >= segmentChars ? segment.width ?? 0 : 0);
73863
74084
  }
73864
74085
  const text = run2.text ?? "";
73865
- const segmentText = text.slice(segment.fromChar, segment.toChar);
73866
- const textUpToTarget = segmentText.slice(0, offsetInSegment);
74086
+ const transform = "textTransform" in run2 ? run2.textTransform : void 0;
74087
+ const displayText = applyTextTransform$2(text, transform);
74088
+ const displaySegmentText = displayText.slice(segment.fromChar, segment.toChar);
74089
+ const textUpToTarget = displaySegmentText.slice(0, offsetInSegment);
73867
74090
  ctx2.font = getRunFontString(run2);
73868
74091
  const measured = ctx2.measureText(textUpToTarget);
73869
74092
  const spacingWidth = computeLetterSpacingWidth(run2, offsetInSegment, segmentChars);
@@ -73959,12 +74182,14 @@ function findCharacterAtX(block, line, x2, pmStart, availableWidthOverride, alig
73959
74182
  }
73960
74183
  const text = "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
73961
74184
  const runLength = text.length;
74185
+ const transform = isTabRun$1(run2) || "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? void 0 : run2.textTransform;
74186
+ const displayText = applyTextTransform$2(text, transform);
73962
74187
  if (runLength === 0) continue;
73963
74188
  ctx2.font = getRunFontString(run2);
73964
74189
  for (let i = 0; i <= runLength; i++) {
73965
- const textUpToChar = text.slice(0, i);
74190
+ const textUpToChar = displayText.slice(0, i);
73966
74191
  const measured2 = ctx2.measureText(textUpToChar);
73967
- const spacesInPortion = justify.extraPerSpace > 0 ? countSpaces(textUpToChar) : 0;
74192
+ const spacesInPortion = justify.extraPerSpace > 0 ? countSpaces(text.slice(0, i)) : 0;
73968
74193
  const charX = currentX + measured2.width + computeLetterSpacingWidth(run2, i, runLength) + justify.extraPerSpace * (spaceTally + spacesInPortion);
73969
74194
  if (charX >= safeX) {
73970
74195
  if (i === 0) {
@@ -73974,7 +74199,7 @@ function findCharacterAtX(block, line, x2, pmStart, availableWidthOverride, alig
73974
74199
  pmPosition: pmPosition3
73975
74200
  };
73976
74201
  }
73977
- const prevText = text.slice(0, i - 1);
74202
+ const prevText = displayText.slice(0, i - 1);
73978
74203
  const prevMeasured = ctx2.measureText(prevText);
73979
74204
  const prevX = currentX + prevMeasured.width + computeLetterSpacingWidth(run2, i - 1, runLength);
73980
74205
  const distToPrev = Math.abs(safeX - prevX);
@@ -73987,7 +74212,7 @@ function findCharacterAtX(block, line, x2, pmStart, availableWidthOverride, alig
73987
74212
  };
73988
74213
  }
73989
74214
  }
73990
- const measured = ctx2.measureText(text);
74215
+ const measured = ctx2.measureText(displayText);
73991
74216
  const runLetterSpacing = computeLetterSpacingWidth(run2, runLength, runLength);
73992
74217
  const spacesInRun = justify.extraPerSpace > 0 ? countSpaces(text) : 0;
73993
74218
  currentX += measured.width + runLetterSpacing + justify.extraPerSpace * spacesInRun;
@@ -74418,6 +74643,83 @@ function findCharIndexAtX(textNode, container, targetX) {
74418
74643
  }
74419
74644
  return index2;
74420
74645
  }
74646
+ const LIST_MARKER_GAP$1 = 8;
74647
+ const MIN_MARKER_GUTTER = 24;
74648
+ const DEFAULT_LIST_INDENT_BASE_PX = 24;
74649
+ const DEFAULT_LIST_INDENT_STEP_PX = 24;
74650
+ const DEFAULT_LIST_HANGING_PX$1 = 18;
74651
+ const SPACE_SUFFIX_GAP_PX = 4;
74652
+ const DEFAULT_TAB_INTERVAL_PX$1 = 48;
74653
+ function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, measureMarkerText) {
74654
+ const marker = wordLayout?.marker;
74655
+ if (!marker) {
74656
+ const textStartPx = wordLayout?.firstLineIndentMode === true && typeof wordLayout.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
74657
+ return textStartPx;
74658
+ }
74659
+ const markerBoxWidth = typeof marker.markerBoxWidthPx === "number" && Number.isFinite(marker.markerBoxWidthPx) ? marker.markerBoxWidthPx : 0;
74660
+ let markerTextWidth = typeof marker.glyphWidthPx === "number" && Number.isFinite(marker.glyphWidthPx) ? marker.glyphWidthPx : void 0;
74661
+ if (markerTextWidth == null && marker.markerText) {
74662
+ markerTextWidth = measureMarkerText(marker.markerText, marker);
74663
+ }
74664
+ if (!Number.isFinite(markerTextWidth) || markerTextWidth !== void 0 && markerTextWidth < 0) {
74665
+ markerTextWidth = markerBoxWidth;
74666
+ }
74667
+ const finalMarkerTextWidth = Math.max(0, markerTextWidth ?? 0);
74668
+ let markerStartPos;
74669
+ if (wordLayout?.firstLineIndentMode === true && typeof marker.markerX === "number" && Number.isFinite(marker.markerX)) {
74670
+ markerStartPos = marker.markerX;
74671
+ } else {
74672
+ markerStartPos = indentLeft - hanging + firstLine;
74673
+ }
74674
+ if (!Number.isFinite(markerStartPos)) {
74675
+ markerStartPos = 0;
74676
+ }
74677
+ const currentPos = markerStartPos + finalMarkerTextWidth;
74678
+ const suffix2 = marker.suffix ?? "tab";
74679
+ if (suffix2 === "space") {
74680
+ return markerStartPos + finalMarkerTextWidth + SPACE_SUFFIX_GAP_PX;
74681
+ }
74682
+ if (suffix2 === "nothing") {
74683
+ return markerStartPos + finalMarkerTextWidth;
74684
+ }
74685
+ const markerJustification = marker.justification ?? "left";
74686
+ if (markerJustification !== "left") {
74687
+ const gutterWidth = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
74688
+ return markerStartPos + finalMarkerTextWidth + Math.max(gutterWidth, LIST_MARKER_GAP$1);
74689
+ }
74690
+ if (wordLayout?.firstLineIndentMode === true) {
74691
+ let targetTabStop;
74692
+ if (Array.isArray(wordLayout.tabsPx)) {
74693
+ for (const tab of wordLayout.tabsPx) {
74694
+ if (typeof tab === "number" && tab > currentPos) {
74695
+ targetTabStop = tab;
74696
+ break;
74697
+ }
74698
+ }
74699
+ }
74700
+ const textStartTarget = typeof marker.textStartX === "number" && Number.isFinite(marker.textStartX) ? marker.textStartX : wordLayout.textStartPx;
74701
+ let tabWidth2;
74702
+ if (targetTabStop !== void 0) {
74703
+ tabWidth2 = targetTabStop - currentPos;
74704
+ } else if (textStartTarget !== void 0 && Number.isFinite(textStartTarget) && textStartTarget > currentPos) {
74705
+ tabWidth2 = textStartTarget - currentPos;
74706
+ } else {
74707
+ tabWidth2 = LIST_MARKER_GAP$1;
74708
+ }
74709
+ if (tabWidth2 < LIST_MARKER_GAP$1) {
74710
+ tabWidth2 = LIST_MARKER_GAP$1;
74711
+ }
74712
+ return markerStartPos + finalMarkerTextWidth + tabWidth2;
74713
+ }
74714
+ const textStart = indentLeft + firstLine;
74715
+ let tabWidth = textStart - currentPos;
74716
+ if (tabWidth <= 0) {
74717
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
74718
+ } else if (tabWidth < LIST_MARKER_GAP$1) {
74719
+ tabWidth = LIST_MARKER_GAP$1;
74720
+ }
74721
+ return markerStartPos + finalMarkerTextWidth + tabWidth;
74722
+ }
74421
74723
  function getWordLayoutConfig(block) {
74422
74724
  if (!block || block.kind !== "paragraph") {
74423
74725
  return void 0;
@@ -74450,9 +74752,16 @@ function calculateTextStartIndent(params2) {
74450
74752
  const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
74451
74753
  let indentAdjust = paraIndentLeft;
74452
74754
  if (isListItem2 && isFirstLine && isFirstLineIndentMode) {
74755
+ const resolvedTextStart = resolveListTextStartPx(
74756
+ wordLayout,
74757
+ paraIndentLeft,
74758
+ Math.max(firstLineIndent, 0),
74759
+ Math.max(hangingIndent, 0),
74760
+ () => markerWidth
74761
+ // Use provided markerWidth since we don't have canvas access here
74762
+ );
74453
74763
  const textStartFallback = paraIndentLeft + Math.max(firstLineIndent, 0) + markerWidth;
74454
- const markerTextStartX = wordLayout?.marker?.textStartX;
74455
- indentAdjust = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : textStartFallback;
74764
+ indentAdjust = typeof resolvedTextStart === "number" && Number.isFinite(resolvedTextStart) ? resolvedTextStart : textStartFallback;
74456
74765
  } else if (isFirstLine && !isListItem2) {
74457
74766
  indentAdjust += firstLineOffset;
74458
74767
  }
@@ -74608,7 +74917,10 @@ function getHeaderFooterTypeForSection(pageNumber, sectionIndex, identifier, opt
74608
74917
  }
74609
74918
  function createFloatingObjectManager(columns, margins, pageWidth) {
74610
74919
  const zones = [];
74611
- const marginLeft = Math.max(0, margins?.left ?? 0);
74920
+ let currentColumns = columns;
74921
+ let currentMargins = margins;
74922
+ let currentPageWidth = pageWidth;
74923
+ let marginLeft = Math.max(0, currentMargins?.left ?? 0);
74612
74924
  return {
74613
74925
  registerDrawing(drawingBlock, measure, anchorY, columnIndex, pageNumber) {
74614
74926
  if (!drawingBlock.anchor?.isAnchored) {
@@ -74621,7 +74933,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74621
74933
  }
74622
74934
  const objectWidth = measure.width ?? 0;
74623
74935
  const objectHeight = measure.height ?? 0;
74624
- const x2 = computeAnchorX(anchor, columnIndex, columns, objectWidth, margins, pageWidth);
74936
+ const x2 = computeAnchorX(anchor, columnIndex, currentColumns, objectWidth, currentMargins, currentPageWidth);
74625
74937
  const y2 = anchorY + (anchor.offsetV ?? 0);
74626
74938
  const zone = {
74627
74939
  imageBlockId: drawingBlock.id,
@@ -74655,7 +74967,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74655
74967
  }
74656
74968
  const tableWidth = measure.totalWidth ?? 0;
74657
74969
  const tableHeight = measure.totalHeight ?? 0;
74658
- const x2 = computeTableAnchorX(anchor, columnIndex, columns, tableWidth, margins, pageWidth);
74970
+ const x2 = computeTableAnchorX(anchor, columnIndex, currentColumns, tableWidth, currentMargins, currentPageWidth);
74659
74971
  const y2 = anchorY + (anchor.offsetV ?? 0);
74660
74972
  const zone = {
74661
74973
  imageBlockId: tableBlock.id,
@@ -74703,7 +75015,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74703
75015
  }
74704
75016
  const leftFloats = [];
74705
75017
  const rightFloats = [];
74706
- const columnOrigin = marginLeft + columnIndex * (columns.width + columns.gap);
75018
+ const columnOrigin = marginLeft + columnIndex * (currentColumns.width + currentColumns.gap);
74707
75019
  const columnCenter = columnOrigin + baseWidth / 2;
74708
75020
  for (const zone of wrappingZones) {
74709
75021
  if (zone.wrapMode === "left") {
@@ -74742,6 +75054,22 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
74742
75054
  },
74743
75055
  clear() {
74744
75056
  zones.length = 0;
75057
+ },
75058
+ /**
75059
+ * Update layout context used for positioning and wrapping (columns, margins, page width).
75060
+ * This method should be called when the layout configuration changes (e.g., section breaks,
75061
+ * column changes, page size changes) to ensure floating objects are positioned and wrapped
75062
+ * correctly relative to the new layout boundaries.
75063
+ *
75064
+ * @param nextColumns - Column layout configuration (width, gap, count)
75065
+ * @param nextMargins - Optional page margins (left, right) in pixels
75066
+ * @param nextPageWidth - Optional total page width in pixels
75067
+ */
75068
+ setLayoutContext(nextColumns, nextMargins, nextPageWidth) {
75069
+ currentColumns = nextColumns;
75070
+ currentMargins = nextMargins;
75071
+ currentPageWidth = nextPageWidth;
75072
+ marginLeft = Math.max(0, currentMargins?.left ?? 0);
74745
75073
  }
74746
75074
  };
74747
75075
  }
@@ -74841,7 +75169,14 @@ function computeNextSectionPropsAtBreak(blocks) {
74841
75169
  const props = {};
74842
75170
  if (source.kind !== "sectionBreak") return props;
74843
75171
  if (source.margins) {
74844
- props.margins = { header: source.margins.header, footer: source.margins.footer };
75172
+ props.margins = {
75173
+ header: source.margins.header,
75174
+ footer: source.margins.footer,
75175
+ top: source.margins.top,
75176
+ right: source.margins.right,
75177
+ bottom: source.margins.bottom,
75178
+ left: source.margins.left
75179
+ };
74845
75180
  }
74846
75181
  if (source.pageSize) {
74847
75182
  props.pageSize = { w: source.pageSize.w, h: source.pageSize.h };
@@ -74889,20 +75224,36 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
74889
75224
  next.activeOrientation = block.orientation;
74890
75225
  next.pendingOrientation = null;
74891
75226
  }
75227
+ const headerDistance = typeof block.margins?.header === "number" ? Math.max(0, block.margins.header) : next.activeHeaderDistance;
75228
+ const footerDistance = typeof block.margins?.footer === "number" ? Math.max(0, block.margins.footer) : next.activeFooterDistance;
75229
+ const sectionTop = typeof block.margins?.top === "number" ? Math.max(0, block.margins.top) : baseMargins.top;
75230
+ const sectionBottom = typeof block.margins?.bottom === "number" ? Math.max(0, block.margins.bottom) : baseMargins.bottom;
74892
75231
  if (block.margins?.header !== void 0) {
74893
- const headerDistance = Math.max(0, block.margins.header);
74894
75232
  next.activeHeaderDistance = headerDistance;
74895
75233
  next.pendingHeaderDistance = headerDistance;
74896
- next.activeTopMargin = calcRequiredTopMargin(headerDistance, baseMargins.top);
74897
- next.pendingTopMargin = next.activeTopMargin;
74898
75234
  }
74899
75235
  if (block.margins?.footer !== void 0) {
74900
- const footerDistance = Math.max(0, block.margins.footer);
74901
75236
  next.activeFooterDistance = footerDistance;
74902
75237
  next.pendingFooterDistance = footerDistance;
74903
- next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, baseMargins.bottom);
75238
+ }
75239
+ if (block.margins?.top !== void 0 || block.margins?.header !== void 0) {
75240
+ next.activeTopMargin = calcRequiredTopMargin(headerDistance, sectionTop);
75241
+ next.pendingTopMargin = next.activeTopMargin;
75242
+ }
75243
+ if (block.margins?.bottom !== void 0 || block.margins?.footer !== void 0) {
75244
+ next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, sectionBottom);
74904
75245
  next.pendingBottomMargin = next.activeBottomMargin;
74905
75246
  }
75247
+ if (block.margins?.left !== void 0) {
75248
+ const leftMargin = Math.max(0, block.margins.left);
75249
+ next.activeLeftMargin = leftMargin;
75250
+ next.pendingLeftMargin = leftMargin;
75251
+ }
75252
+ if (block.margins?.right !== void 0) {
75253
+ const rightMargin = Math.max(0, block.margins.right);
75254
+ next.activeRightMargin = rightMargin;
75255
+ next.pendingRightMargin = rightMargin;
75256
+ }
74906
75257
  if (block.columns) {
74907
75258
  next.activeColumns = { count: block.columns.count, gap: block.columns.gap };
74908
75259
  next.pendingColumns = null;
@@ -74911,26 +75262,42 @@ function scheduleSectionBreak(block, state2, baseMargins, maxHeaderContentHeight
74911
75262
  }
74912
75263
  const headerPx = block.margins?.header;
74913
75264
  const footerPx = block.margins?.footer;
75265
+ const topPx = block.margins?.top;
75266
+ const bottomPx = block.margins?.bottom;
74914
75267
  const nextTop = next.pendingTopMargin ?? next.activeTopMargin;
74915
75268
  const nextBottom = next.pendingBottomMargin ?? next.activeBottomMargin;
75269
+ const nextLeft = next.pendingLeftMargin ?? next.activeLeftMargin;
75270
+ const nextRight = next.pendingRightMargin ?? next.activeRightMargin;
74916
75271
  const nextHeader = next.pendingHeaderDistance ?? next.activeHeaderDistance;
74917
75272
  const nextFooter = next.pendingFooterDistance ?? next.activeFooterDistance;
74918
- if (typeof headerPx === "number") {
74919
- const newHeaderDist = Math.max(0, headerPx);
75273
+ if (typeof headerPx === "number" || typeof topPx === "number") {
75274
+ const newHeaderDist = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
75275
+ const sectionTop = typeof topPx === "number" ? Math.max(0, topPx) : baseMargins.top;
74920
75276
  next.pendingHeaderDistance = newHeaderDist;
74921
- next.pendingTopMargin = calcRequiredTopMargin(newHeaderDist, baseMargins.top);
75277
+ next.pendingTopMargin = calcRequiredTopMargin(newHeaderDist, sectionTop);
74922
75278
  } else {
74923
75279
  next.pendingTopMargin = nextTop;
74924
75280
  next.pendingHeaderDistance = nextHeader;
74925
75281
  }
74926
- if (typeof footerPx === "number") {
74927
- const newFooterDist = Math.max(0, footerPx);
75282
+ if (typeof footerPx === "number" || typeof bottomPx === "number") {
75283
+ const newFooterDist = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
75284
+ const sectionBottom = typeof bottomPx === "number" ? Math.max(0, bottomPx) : baseMargins.bottom;
74928
75285
  next.pendingFooterDistance = newFooterDist;
74929
- next.pendingBottomMargin = calcRequiredBottomMargin(newFooterDist, baseMargins.bottom);
75286
+ next.pendingBottomMargin = calcRequiredBottomMargin(newFooterDist, sectionBottom);
74930
75287
  } else {
74931
75288
  next.pendingBottomMargin = nextBottom;
74932
75289
  next.pendingFooterDistance = nextFooter;
74933
75290
  }
75291
+ if (typeof block.margins?.left === "number") {
75292
+ next.pendingLeftMargin = Math.max(0, block.margins.left);
75293
+ } else {
75294
+ next.pendingLeftMargin = nextLeft;
75295
+ }
75296
+ if (typeof block.margins?.right === "number") {
75297
+ next.pendingRightMargin = Math.max(0, block.margins.right);
75298
+ } else {
75299
+ next.pendingRightMargin = nextRight;
75300
+ }
74934
75301
  if (block.pageSize) {
74935
75302
  next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
74936
75303
  }
@@ -74990,6 +75357,12 @@ function applyPendingToActive(state2) {
74990
75357
  if (next.pendingBottomMargin != null) {
74991
75358
  next.activeBottomMargin = next.pendingBottomMargin;
74992
75359
  }
75360
+ if (next.pendingLeftMargin != null) {
75361
+ next.activeLeftMargin = next.pendingLeftMargin;
75362
+ }
75363
+ if (next.pendingRightMargin != null) {
75364
+ next.activeRightMargin = next.pendingRightMargin;
75365
+ }
74993
75366
  if (next.pendingHeaderDistance != null) {
74994
75367
  next.activeHeaderDistance = next.pendingHeaderDistance;
74995
75368
  }
@@ -75007,6 +75380,8 @@ function applyPendingToActive(state2) {
75007
75380
  }
75008
75381
  next.pendingTopMargin = null;
75009
75382
  next.pendingBottomMargin = null;
75383
+ next.pendingLeftMargin = null;
75384
+ next.pendingRightMargin = null;
75010
75385
  next.pendingHeaderDistance = null;
75011
75386
  next.pendingFooterDistance = null;
75012
75387
  next.pendingPageSize = null;
@@ -75235,7 +75610,8 @@ function layoutParagraphBlock(ctx2, anchors) {
75235
75610
  if (typeof remeasureParagraph2 === "function" && typeof measurementWidth === "number" && measurementWidth > remeasureWidth) {
75236
75611
  const firstLineIndent = calculateFirstLineIndent(block, measure);
75237
75612
  const newMeasure = remeasureParagraph2(block, columnWidth, firstLineIndent);
75238
- lines = normalizeLines(newMeasure);
75613
+ const newLines = normalizeLines(newMeasure);
75614
+ lines = newLines;
75239
75615
  didRemeasureForColumnWidth = true;
75240
75616
  }
75241
75617
  let fromLine = 0;
@@ -75317,7 +75693,8 @@ function layoutParagraphBlock(ctx2, anchors) {
75317
75693
  if (narrowestRemeasureWidth < remeasureWidth) {
75318
75694
  const firstLineIndent = calculateFirstLineIndent(block, measure);
75319
75695
  const newMeasure = remeasureParagraph2(block, narrowestRemeasureWidth, firstLineIndent);
75320
- lines = normalizeLines(newMeasure);
75696
+ const newLines = normalizeLines(newMeasure);
75697
+ lines = newLines;
75321
75698
  didRemeasureForFloats = true;
75322
75699
  }
75323
75700
  }
@@ -75661,6 +76038,94 @@ function getCellPadding(cellIdx, blockRow) {
75661
76038
  function getCellTotalLines(cell) {
75662
76039
  return getCellLines(cell).length;
75663
76040
  }
76041
+ function mergePmRange(target, range2) {
76042
+ if (typeof range2.pmStart === "number") {
76043
+ target.pmStart = target.pmStart == null ? range2.pmStart : Math.min(target.pmStart, range2.pmStart);
76044
+ }
76045
+ if (typeof range2.pmEnd === "number") {
76046
+ target.pmEnd = target.pmEnd == null ? range2.pmEnd : Math.max(target.pmEnd, range2.pmEnd);
76047
+ }
76048
+ }
76049
+ function computeCellPmRange(cell, cellMeasure, fromLine, toLine) {
76050
+ const range2 = {};
76051
+ if (!cell || !cellMeasure) return range2;
76052
+ const cellBlocks = cell.blocks ?? (cell.paragraph ? [cell.paragraph] : []);
76053
+ const blockMeasures = cellMeasure.blocks ?? (cellMeasure.paragraph ? [cellMeasure.paragraph] : []);
76054
+ const maxBlocks = Math.min(cellBlocks.length, blockMeasures.length);
76055
+ let cumulativeLineCount = 0;
76056
+ for (let i = 0; i < maxBlocks; i++) {
76057
+ const block = cellBlocks[i];
76058
+ const blockMeasure = blockMeasures[i];
76059
+ if (blockMeasure.kind === "paragraph" && block?.kind === "paragraph") {
76060
+ const paraMeasure = blockMeasure;
76061
+ const lines = paraMeasure.lines;
76062
+ const blockLineCount = lines?.length ?? 0;
76063
+ const blockStartGlobal = cumulativeLineCount;
76064
+ const blockEndGlobal = cumulativeLineCount + blockLineCount;
76065
+ const localFrom = Math.max(fromLine, blockStartGlobal) - blockStartGlobal;
76066
+ const localTo = Math.min(toLine, blockEndGlobal) - blockStartGlobal;
76067
+ if (lines && lines.length > 0 && localFrom < localTo) {
76068
+ mergePmRange(range2, computeFragmentPmRange(block, lines, localFrom, localTo));
76069
+ } else {
76070
+ mergePmRange(range2, extractBlockPmRange(block));
76071
+ }
76072
+ cumulativeLineCount += blockLineCount;
76073
+ continue;
76074
+ }
76075
+ mergePmRange(range2, extractBlockPmRange(block));
76076
+ }
76077
+ return range2;
76078
+ }
76079
+ function computeTableFragmentPmRange(block, measure, fromRow, toRow, partialRow) {
76080
+ const range2 = {};
76081
+ for (let rowIndex = fromRow; rowIndex < toRow; rowIndex++) {
76082
+ const row = block.rows[rowIndex];
76083
+ const rowMeasure = measure.rows[rowIndex];
76084
+ if (!row || !rowMeasure) continue;
76085
+ const isPartial = partialRow?.rowIndex === rowIndex;
76086
+ const cellCount = Math.min(row.cells.length, rowMeasure.cells.length);
76087
+ for (let cellIndex = 0; cellIndex < cellCount; cellIndex++) {
76088
+ const cell = row.cells[cellIndex];
76089
+ const cellMeasure = rowMeasure.cells[cellIndex];
76090
+ if (!cell || !cellMeasure) continue;
76091
+ const totalLines = getCellTotalLines(cellMeasure);
76092
+ let fromLine = 0;
76093
+ let toLine = totalLines;
76094
+ if (isPartial) {
76095
+ const hasValidFromLineByCell = partialRow?.fromLineByCell && cellIndex < partialRow.fromLineByCell.length;
76096
+ const hasValidToLineByCell = partialRow?.toLineByCell && cellIndex < partialRow.toLineByCell.length;
76097
+ if (hasValidFromLineByCell) {
76098
+ const rawFrom = partialRow.fromLineByCell[cellIndex];
76099
+ if (typeof rawFrom === "number" && rawFrom >= 0) {
76100
+ fromLine = rawFrom;
76101
+ }
76102
+ }
76103
+ if (hasValidToLineByCell) {
76104
+ const rawTo = partialRow.toLineByCell[cellIndex];
76105
+ if (typeof rawTo === "number") {
76106
+ toLine = rawTo === -1 ? totalLines : rawTo;
76107
+ }
76108
+ }
76109
+ }
76110
+ fromLine = Math.max(0, Math.min(fromLine, totalLines));
76111
+ toLine = Math.max(0, Math.min(toLine, totalLines));
76112
+ if (toLine < fromLine) {
76113
+ toLine = fromLine;
76114
+ }
76115
+ mergePmRange(range2, computeCellPmRange(cell, cellMeasure, fromLine, toLine));
76116
+ }
76117
+ }
76118
+ return range2;
76119
+ }
76120
+ function applyTableFragmentPmRange(fragment, block, measure) {
76121
+ const range2 = computeTableFragmentPmRange(block, measure, fragment.fromRow, fragment.toRow, fragment.partialRow);
76122
+ if (range2.pmStart != null) {
76123
+ fragment.pmStart = range2.pmStart;
76124
+ }
76125
+ if (range2.pmEnd != null) {
76126
+ fragment.pmEnd = range2.pmEnd;
76127
+ }
76128
+ }
75664
76129
  function computePartialRow(rowIndex, blockRow, measure, availableHeight, fromLineByCell) {
75665
76130
  const row = measure.rows[rowIndex];
75666
76131
  if (!row) {
@@ -75805,6 +76270,7 @@ function layoutMonolithicTable(context) {
75805
76270
  height,
75806
76271
  metadata
75807
76272
  };
76273
+ applyTableFragmentPmRange(fragment, context.block, context.measure);
75808
76274
  state2.page.fragments.push(fragment);
75809
76275
  state2.cursorY += height;
75810
76276
  }
@@ -75883,6 +76349,7 @@ function layoutTableBlock({
75883
76349
  height,
75884
76350
  metadata
75885
76351
  };
76352
+ applyTableFragmentPmRange(fragment, block, measure);
75886
76353
  state2.page.fragments.push(fragment);
75887
76354
  state2.cursorY += height;
75888
76355
  return;
@@ -75946,6 +76413,7 @@ function layoutTableBlock({
75946
76413
  partialRow: continuationPartialRow,
75947
76414
  metadata: generateFragmentMetadata(measure)
75948
76415
  };
76416
+ applyTableFragmentPmRange(fragment2, block, measure);
75949
76417
  state2.page.fragments.push(fragment2);
75950
76418
  state2.cursorY += fragmentHeight2;
75951
76419
  }
@@ -75990,6 +76458,7 @@ function layoutTableBlock({
75990
76458
  partialRow: forcedPartialRow,
75991
76459
  metadata: generateFragmentMetadata(measure)
75992
76460
  };
76461
+ applyTableFragmentPmRange(fragment2, block, measure);
75993
76462
  state2.page.fragments.push(fragment2);
75994
76463
  state2.cursorY += fragmentHeight2;
75995
76464
  pendingPartialRow = forcedPartialRow;
@@ -76025,6 +76494,7 @@ function layoutTableBlock({
76025
76494
  partialRow: partialRow || void 0,
76026
76495
  metadata: generateFragmentMetadata(measure)
76027
76496
  };
76497
+ applyTableFragmentPmRange(fragment, block, measure);
76028
76498
  state2.page.fragments.push(fragment);
76029
76499
  state2.cursorY += fragmentHeight;
76030
76500
  if (partialRow && !partialRow.isLastPart) {
@@ -76042,7 +76512,7 @@ function createAnchoredTableFragment(block, measure, x2, y2) {
76042
76512
  columnBoundaries: generateColumnBoundaries(measure),
76043
76513
  coordinateSystem: "fragment"
76044
76514
  };
76045
- return {
76515
+ const fragment = {
76046
76516
  kind: "table",
76047
76517
  blockId: block.id,
76048
76518
  fromRow: 0,
@@ -76053,6 +76523,8 @@ function createAnchoredTableFragment(block, measure, x2, y2) {
76053
76523
  height: measure.totalHeight ?? 0,
76054
76524
  metadata
76055
76525
  };
76526
+ applyTableFragmentPmRange(fragment, block, measure);
76527
+ return fragment;
76056
76528
  }
76057
76529
  function isPageRelativeAnchor(block) {
76058
76530
  const vRelativeFrom = block.anchor?.vRelativeFrom;
@@ -76474,8 +76946,8 @@ function layoutDocument(blocks, measures, options = {}) {
76474
76946
  header: options.margins?.header ?? options.margins?.top ?? DEFAULT_MARGINS$2.top,
76475
76947
  footer: options.margins?.footer ?? options.margins?.bottom ?? DEFAULT_MARGINS$2.bottom
76476
76948
  };
76477
- const contentWidth = pageSize.w - (margins.left + margins.right);
76478
- if (contentWidth <= 0) {
76949
+ const baseContentWidth = pageSize.w - (margins.left + margins.right);
76950
+ if (baseContentWidth <= 0) {
76479
76951
  throw new Error("layoutDocument: pageSize and margins yield non-positive content area");
76480
76952
  }
76481
76953
  const validateContentHeight = (height) => {
@@ -76505,8 +76977,12 @@ function layoutDocument(blocks, measures, options = {}) {
76505
76977
  const effectiveBottomMargin = maxFooterContentHeight > 0 ? Math.max(margins.bottom, footerDistance + maxFooterContentHeight) : margins.bottom;
76506
76978
  let activeTopMargin = effectiveTopMargin;
76507
76979
  let activeBottomMargin = effectiveBottomMargin;
76980
+ let activeLeftMargin = margins.left;
76981
+ let activeRightMargin = margins.right;
76508
76982
  let pendingTopMargin = null;
76509
76983
  let pendingBottomMargin = null;
76984
+ let pendingLeftMargin = null;
76985
+ let pendingRightMargin = null;
76510
76986
  let activeHeaderDistance = margins.header ?? margins.top;
76511
76987
  let pendingHeaderDistance = null;
76512
76988
  let activeFooterDistance = margins.footer ?? margins.bottom;
@@ -76519,10 +76995,11 @@ function layoutDocument(blocks, measures, options = {}) {
76519
76995
  let pendingOrientation = null;
76520
76996
  let activeVAlign = null;
76521
76997
  let pendingVAlign = null;
76998
+ const paginatorMargins = { left: activeLeftMargin, right: activeRightMargin };
76522
76999
  const floatManager = createFloatingObjectManager(
76523
- normalizeColumns(activeColumns, contentWidth),
76524
- { left: margins.left, right: margins.right },
76525
- pageSize.w
77000
+ normalizeColumns(activeColumns, activePageSize.w - (activeLeftMargin + activeRightMargin)),
77001
+ { left: activeLeftMargin, right: activeRightMargin },
77002
+ activePageSize.w
76526
77003
  );
76527
77004
  const nextSectionPropsAtBreak = computeNextSectionPropsAtBreak(blocks);
76528
77005
  const scheduleSectionBreakCompat = (block, state2, baseMargins) => {
@@ -76539,22 +77016,38 @@ function layoutDocument(blocks, measures, options = {}) {
76539
77016
  next.activeOrientation = block.orientation;
76540
77017
  next.pendingOrientation = null;
76541
77018
  }
77019
+ const headerDistance2 = typeof block.margins?.header === "number" ? Math.max(0, block.margins.header) : next.activeHeaderDistance;
77020
+ const footerDistance2 = typeof block.margins?.footer === "number" ? Math.max(0, block.margins.footer) : next.activeFooterDistance;
77021
+ const sectionTop = typeof block.margins?.top === "number" ? Math.max(0, block.margins.top) : baseMargins.top;
77022
+ const sectionBottom = typeof block.margins?.bottom === "number" ? Math.max(0, block.margins.bottom) : baseMargins.bottom;
76542
77023
  if (block.margins?.header !== void 0) {
76543
- const headerDist = Math.max(0, block.margins.header);
76544
- next.activeHeaderDistance = headerDist;
76545
- next.pendingHeaderDistance = headerDist;
76546
- const requiredTop = maxHeaderContentHeight > 0 ? headerDist + maxHeaderContentHeight : headerDist;
76547
- next.activeTopMargin = Math.max(baseMargins.top, requiredTop);
76548
- next.pendingTopMargin = next.activeTopMargin;
77024
+ next.activeHeaderDistance = headerDistance2;
77025
+ next.pendingHeaderDistance = headerDistance2;
76549
77026
  }
76550
77027
  if (block.margins?.footer !== void 0) {
76551
- const footerDistance2 = Math.max(0, block.margins.footer);
76552
77028
  next.activeFooterDistance = footerDistance2;
76553
77029
  next.pendingFooterDistance = footerDistance2;
77030
+ }
77031
+ if (block.margins?.top !== void 0 || block.margins?.header !== void 0) {
77032
+ const requiredTop = maxHeaderContentHeight > 0 ? headerDistance2 + maxHeaderContentHeight : headerDistance2;
77033
+ next.activeTopMargin = Math.max(sectionTop, requiredTop);
77034
+ next.pendingTopMargin = next.activeTopMargin;
77035
+ }
77036
+ if (block.margins?.bottom !== void 0 || block.margins?.footer !== void 0) {
76554
77037
  const requiredBottom = maxFooterContentHeight > 0 ? footerDistance2 + maxFooterContentHeight : footerDistance2;
76555
- next.activeBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
77038
+ next.activeBottomMargin = Math.max(sectionBottom, requiredBottom);
76556
77039
  next.pendingBottomMargin = next.activeBottomMargin;
76557
77040
  }
77041
+ if (block.margins?.left !== void 0) {
77042
+ const leftMargin = Math.max(0, block.margins.left);
77043
+ next.activeLeftMargin = leftMargin;
77044
+ next.pendingLeftMargin = leftMargin;
77045
+ }
77046
+ if (block.margins?.right !== void 0) {
77047
+ const rightMargin = Math.max(0, block.margins.right);
77048
+ next.activeRightMargin = rightMargin;
77049
+ next.pendingRightMargin = rightMargin;
77050
+ }
76558
77051
  if (block.columns) {
76559
77052
  next.activeColumns = { count: block.columns.count, gap: block.columns.gap };
76560
77053
  next.pendingColumns = null;
@@ -76583,27 +77076,35 @@ function layoutDocument(blocks, measures, options = {}) {
76583
77076
  const headerPx = block.margins?.header;
76584
77077
  const footerPx = block.margins?.footer;
76585
77078
  const topPx = block.margins?.top;
77079
+ const bottomPx = block.margins?.bottom;
77080
+ const leftPx = block.margins?.left;
77081
+ const rightPx = block.margins?.right;
76586
77082
  const nextTop = next.pendingTopMargin ?? next.activeTopMargin;
76587
77083
  const nextBottom = next.pendingBottomMargin ?? next.activeBottomMargin;
77084
+ const nextLeft = next.pendingLeftMargin ?? next.activeLeftMargin;
77085
+ const nextRight = next.pendingRightMargin ?? next.activeRightMargin;
76588
77086
  const nextHeader = next.pendingHeaderDistance ?? next.activeHeaderDistance;
76589
77087
  const nextFooter = next.pendingFooterDistance ?? next.activeFooterDistance;
76590
77088
  next.pendingHeaderDistance = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
76591
77089
  next.pendingFooterDistance = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
76592
77090
  if (typeof headerPx === "number" || typeof topPx === "number") {
76593
- const sectionTop = topPx ?? baseMargins.top;
77091
+ const sectionTop = typeof topPx === "number" ? Math.max(0, topPx) : baseMargins.top;
76594
77092
  const sectionHeader = next.pendingHeaderDistance;
76595
77093
  const requiredTop = maxHeaderContentHeight > 0 ? sectionHeader + maxHeaderContentHeight : sectionHeader;
76596
77094
  next.pendingTopMargin = Math.max(sectionTop, requiredTop);
76597
77095
  } else {
76598
77096
  next.pendingTopMargin = nextTop;
76599
77097
  }
76600
- if (typeof footerPx === "number") {
77098
+ if (typeof footerPx === "number" || typeof bottomPx === "number") {
76601
77099
  const sectionFooter = next.pendingFooterDistance;
77100
+ const sectionBottom = typeof bottomPx === "number" ? Math.max(0, bottomPx) : baseMargins.bottom;
76602
77101
  const requiredBottom = maxFooterContentHeight > 0 ? sectionFooter + maxFooterContentHeight : sectionFooter;
76603
- next.pendingBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
77102
+ next.pendingBottomMargin = Math.max(sectionBottom, requiredBottom);
76604
77103
  } else {
76605
77104
  next.pendingBottomMargin = nextBottom;
76606
77105
  }
77106
+ next.pendingLeftMargin = typeof leftPx === "number" ? Math.max(0, leftPx) : nextLeft;
77107
+ next.pendingRightMargin = typeof rightPx === "number" ? Math.max(0, rightPx) : nextRight;
76607
77108
  if (block.pageSize) next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
76608
77109
  if (block.orientation) next.pendingOrientation = block.orientation;
76609
77110
  const sectionType = block.type ?? "continuous";
@@ -76688,7 +77189,7 @@ function layoutDocument(blocks, measures, options = {}) {
76688
77189
  let activeSectionIndex = initialSectionMetadata?.sectionIndex ?? 0;
76689
77190
  let pendingSectionIndex = null;
76690
77191
  const paginator = createPaginator({
76691
- margins: { left: margins.left, right: margins.right },
77192
+ margins: paginatorMargins,
76692
77193
  getActiveTopMargin: () => activeTopMargin,
76693
77194
  getActiveBottomMargin: () => activeBottomMargin,
76694
77195
  getActiveHeaderDistance: () => activeHeaderDistance,
@@ -76703,8 +77204,12 @@ function layoutDocument(blocks, measures, options = {}) {
76703
77204
  const applied = applyPendingToActive({
76704
77205
  activeTopMargin,
76705
77206
  activeBottomMargin,
77207
+ activeLeftMargin,
77208
+ activeRightMargin,
76706
77209
  pendingTopMargin,
76707
77210
  pendingBottomMargin,
77211
+ pendingLeftMargin,
77212
+ pendingRightMargin,
76708
77213
  activeHeaderDistance,
76709
77214
  activeFooterDistance,
76710
77215
  pendingHeaderDistance,
@@ -76719,8 +77224,12 @@ function layoutDocument(blocks, measures, options = {}) {
76719
77224
  });
76720
77225
  activeTopMargin = applied.activeTopMargin;
76721
77226
  activeBottomMargin = applied.activeBottomMargin;
77227
+ activeLeftMargin = applied.activeLeftMargin;
77228
+ activeRightMargin = applied.activeRightMargin;
76722
77229
  pendingTopMargin = applied.pendingTopMargin;
76723
77230
  pendingBottomMargin = applied.pendingBottomMargin;
77231
+ pendingLeftMargin = applied.pendingLeftMargin;
77232
+ pendingRightMargin = applied.pendingRightMargin;
76724
77233
  activeHeaderDistance = applied.activeHeaderDistance;
76725
77234
  activeFooterDistance = applied.activeFooterDistance;
76726
77235
  pendingHeaderDistance = applied.pendingHeaderDistance;
@@ -76732,6 +77241,14 @@ function layoutDocument(blocks, measures, options = {}) {
76732
77241
  activeOrientation = applied.activeOrientation;
76733
77242
  pendingOrientation = applied.pendingOrientation;
76734
77243
  cachedColumnsState.state = null;
77244
+ paginatorMargins.left = activeLeftMargin;
77245
+ paginatorMargins.right = activeRightMargin;
77246
+ const contentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
77247
+ floatManager.setLayoutContext(
77248
+ normalizeColumns(activeColumns, contentWidth),
77249
+ { left: activeLeftMargin, right: activeRightMargin },
77250
+ activePageSize.w
77251
+ );
76735
77252
  if (pendingNumbering) {
76736
77253
  if (pendingNumbering.format) activeNumberFormat = pendingNumbering.format;
76737
77254
  if (typeof pendingNumbering.start === "number" && Number.isFinite(pendingNumbering.start)) {
@@ -76776,7 +77293,7 @@ function layoutDocument(blocks, measures, options = {}) {
76776
77293
  const getActiveColumnsForState = paginator.getActiveColumnsForState;
76777
77294
  let cachedColumnsState = { state: null, constraintIndex: -2, contentWidth: -1, colsConfig: null, normalized: null };
76778
77295
  const getCurrentColumns = () => {
76779
- const currentContentWidth = activePageSize.w - (margins.left + margins.right);
77296
+ const currentContentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
76780
77297
  const state2 = states[states.length - 1] ?? null;
76781
77298
  const colsConfig = state2 ? getActiveColumnsForState(state2) : activeColumns;
76782
77299
  const constraintIndex = state2 ? state2.activeConstraintIndex : -1;
@@ -76809,6 +77326,12 @@ function layoutDocument(blocks, measures, options = {}) {
76809
77326
  layoutLog(` Current page: ${state2.page.number}, cursorY: ${state2.cursorY}`);
76810
77327
  activeColumns = newColumns;
76811
77328
  cachedColumnsState.state = null;
77329
+ const contentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
77330
+ floatManager.setLayoutContext(
77331
+ normalizeColumns(activeColumns, contentWidth),
77332
+ { left: activeLeftMargin, right: activeRightMargin },
77333
+ activePageSize.w
77334
+ );
76812
77335
  };
76813
77336
  const anchoredByParagraph = collectAnchoredDrawings(blocks, measures);
76814
77337
  const anchoredTablesByParagraph = collectAnchoredTables(blocks, measures);
@@ -76840,10 +77363,10 @@ function layoutDocument(blocks, measures, options = {}) {
76840
77363
  if (alignV === "top") {
76841
77364
  anchorY = offsetV;
76842
77365
  } else if (alignV === "bottom") {
76843
- const pageHeight = contentBottom + margins.bottom;
77366
+ const pageHeight = contentBottom + (state2.page.margins?.bottom ?? activeBottomMargin);
76844
77367
  anchorY = pageHeight - imageHeight + offsetV;
76845
77368
  } else if (alignV === "center") {
76846
- const pageHeight = contentBottom + margins.bottom;
77369
+ const pageHeight = contentBottom + (state2.page.margins?.bottom ?? activeBottomMargin);
76847
77370
  anchorY = (pageHeight - imageHeight) / 2 + offsetV;
76848
77371
  } else {
76849
77372
  anchorY = offsetV;
@@ -76854,11 +77377,11 @@ function layoutDocument(blocks, measures, options = {}) {
76854
77377
  const anchorX = entry.block.anchor ? computeAnchorX(
76855
77378
  entry.block.anchor,
76856
77379
  state2.columnIndex,
76857
- normalizeColumns(activeColumns, contentWidth),
77380
+ normalizeColumns(activeColumns, activePageSize.w - (activeLeftMargin + activeRightMargin)),
76858
77381
  entry.measure.width,
76859
- { left: margins.left, right: margins.right },
77382
+ { left: activeLeftMargin, right: activeRightMargin },
76860
77383
  activePageSize.w
76861
- ) : margins.left;
77384
+ ) : activeLeftMargin;
76862
77385
  floatManager.registerDrawing(entry.block, entry.measure, anchorY, state2.columnIndex, state2.page.number);
76863
77386
  preRegisteredPositions.set(entry.block.id, { anchorX, anchorY, pageNumber: state2.page.number });
76864
77387
  }
@@ -76896,8 +77419,12 @@ function layoutDocument(blocks, measures, options = {}) {
76896
77419
  const sectionState = {
76897
77420
  activeTopMargin,
76898
77421
  activeBottomMargin,
77422
+ activeLeftMargin,
77423
+ activeRightMargin,
76899
77424
  pendingTopMargin,
76900
77425
  pendingBottomMargin,
77426
+ pendingLeftMargin,
77427
+ pendingRightMargin,
76901
77428
  activeHeaderDistance,
76902
77429
  activeFooterDistance,
76903
77430
  pendingHeaderDistance,
@@ -76931,8 +77458,12 @@ function layoutDocument(blocks, measures, options = {}) {
76931
77458
  layoutLog(`[Layout] ========== END SECTION BREAK ==========`);
76932
77459
  activeTopMargin = updatedState.activeTopMargin;
76933
77460
  activeBottomMargin = updatedState.activeBottomMargin;
77461
+ activeLeftMargin = updatedState.activeLeftMargin;
77462
+ activeRightMargin = updatedState.activeRightMargin;
76934
77463
  pendingTopMargin = updatedState.pendingTopMargin;
76935
77464
  pendingBottomMargin = updatedState.pendingBottomMargin;
77465
+ pendingLeftMargin = updatedState.pendingLeftMargin;
77466
+ pendingRightMargin = updatedState.pendingRightMargin;
76936
77467
  activeHeaderDistance = updatedState.activeHeaderDistance;
76937
77468
  activeFooterDistance = updatedState.activeFooterDistance;
76938
77469
  pendingHeaderDistance = updatedState.pendingHeaderDistance;
@@ -77070,8 +77601,8 @@ function layoutDocument(blocks, measures, options = {}) {
77070
77601
  pageMargins: {
77071
77602
  top: activeTopMargin,
77072
77603
  bottom: activeBottomMargin,
77073
- left: margins.left,
77074
- right: margins.right
77604
+ left: activeLeftMargin,
77605
+ right: activeRightMargin
77075
77606
  },
77076
77607
  columns: getCurrentColumns(),
77077
77608
  placedAnchoredIds
@@ -77093,9 +77624,9 @@ function layoutDocument(blocks, measures, options = {}) {
77093
77624
  const cols = getCurrentColumns();
77094
77625
  let maxWidth;
77095
77626
  if (relativeFrom === "page") {
77096
- maxWidth = cols.count === 1 ? activePageSize.w - margins.left - margins.right : activePageSize.w;
77627
+ maxWidth = cols.count === 1 ? activePageSize.w - (activeLeftMargin + activeRightMargin) : activePageSize.w;
77097
77628
  } else if (relativeFrom === "margin") {
77098
- maxWidth = activePageSize.w - margins.left - margins.right;
77629
+ maxWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
77099
77630
  } else {
77100
77631
  maxWidth = cols.width;
77101
77632
  }
@@ -77255,6 +77786,9 @@ function layoutHeaderFooter(blocks, measures, constraints) {
77255
77786
  if (!Number.isFinite(height) || height <= 0) {
77256
77787
  throw new Error("layoutHeaderFooter: height must be positive");
77257
77788
  }
77789
+ const maxBehindDocOverflow = Math.max(192, height * 4);
77790
+ const minBehindDocY = -maxBehindDocOverflow;
77791
+ const maxBehindDocY = height + maxBehindDocOverflow;
77258
77792
  const marginLeft = constraints.margins?.left ?? 0;
77259
77793
  const transformedBlocks = marginLeft > 0 ? blocks.map((block) => {
77260
77794
  const hasPageRelativeAnchor = (block.kind === "image" || block.kind === "drawing") && block.anchor?.hRelativeFrom === "page" && block.anchor.offsetH != null;
@@ -77285,6 +77819,18 @@ function layoutHeaderFooter(blocks, measures, constraints) {
77285
77819
  if (idx == null) continue;
77286
77820
  const block = blocks[idx];
77287
77821
  const measure = measures[idx];
77822
+ const isAnchoredFragment = (fragment.kind === "image" || fragment.kind === "drawing") && fragment.isAnchored === true;
77823
+ if (isAnchoredFragment) {
77824
+ if (block.kind !== "image" && block.kind !== "drawing") {
77825
+ throw new Error(
77826
+ `Type mismatch: fragment kind is ${fragment.kind} but block kind is ${block.kind} for block ${block.id}`
77827
+ );
77828
+ }
77829
+ const anchoredBlock = block;
77830
+ if (anchoredBlock.anchor?.behindDoc && (fragment.y < minBehindDocY || fragment.y > maxBehindDocY)) {
77831
+ continue;
77832
+ }
77833
+ }
77288
77834
  if (fragment.y < minY) minY = fragment.y;
77289
77835
  let bottom2 = fragment.y;
77290
77836
  if (fragment.kind === "para" && measure?.kind === "paragraph") {
@@ -78282,11 +78828,11 @@ function findWordBoundaries(blocks, pos) {
78282
78828
  if (text.length === 0) return null;
78283
78829
  const clampedPos = Math.max(0, Math.min(localPos, text.length));
78284
78830
  let wordStart = clampedPos;
78285
- while (wordStart > 0 && isWordChar(text[wordStart - 1])) {
78831
+ while (wordStart > 0 && isWordChar$2(text[wordStart - 1])) {
78286
78832
  wordStart--;
78287
78833
  }
78288
78834
  let wordEnd = clampedPos;
78289
- while (wordEnd < text.length && isWordChar(text[wordEnd])) {
78835
+ while (wordEnd < text.length && isWordChar$2(text[wordEnd])) {
78290
78836
  wordEnd++;
78291
78837
  }
78292
78838
  if (wordStart === wordEnd) {
@@ -78349,7 +78895,7 @@ function findBlockAtPosition(blocks, pos) {
78349
78895
  }
78350
78896
  return null;
78351
78897
  }
78352
- function isWordChar(char) {
78898
+ function isWordChar$2(char) {
78353
78899
  return /[\p{L}\p{N}_]/u.test(char);
78354
78900
  }
78355
78901
  function isWhitespace(char) {
@@ -78384,6 +78930,29 @@ function fontString(run2) {
78384
78930
  function runText(run2) {
78385
78931
  return "src" in run2 || run2.kind === "lineBreak" || run2.kind === "break" || run2.kind === "fieldAnnotation" ? "" : run2.text ?? "";
78386
78932
  }
78933
+ const isWordChar$1 = (char) => {
78934
+ if (!char) return false;
78935
+ const code = char.charCodeAt(0);
78936
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
78937
+ };
78938
+ const capitalizeText$1 = (text, fullText, startOffset) => {
78939
+ if (!text) return text;
78940
+ const hasFullText = typeof startOffset === "number" && fullText != null;
78941
+ let result = "";
78942
+ for (let i = 0; i < text.length; i += 1) {
78943
+ const prevChar = hasFullText ? startOffset + i > 0 ? fullText[startOffset + i - 1] : "" : i > 0 ? text[i - 1] : "";
78944
+ const ch = text[i];
78945
+ result += isWordChar$1(ch) && !isWordChar$1(prevChar) ? ch.toUpperCase() : ch;
78946
+ }
78947
+ return result;
78948
+ };
78949
+ const applyTextTransform$1 = (text, transform, fullText, startOffset) => {
78950
+ if (!text || !transform || transform === "none") return text;
78951
+ if (transform === "uppercase") return text.toUpperCase();
78952
+ if (transform === "lowercase") return text.toLowerCase();
78953
+ if (transform === "capitalize") return capitalizeText$1(text, fullText, startOffset);
78954
+ return text;
78955
+ };
78387
78956
  const DEFAULT_TAB_INTERVAL_TWIPS$1 = 720;
78388
78957
  const TWIPS_PER_INCH$4 = 1440;
78389
78958
  const PX_PER_INCH$3 = 96;
@@ -78392,6 +78961,13 @@ const TAB_EPSILON$1 = 0.1;
78392
78961
  const WIDTH_FUDGE_PX = 0.5;
78393
78962
  const twipsToPx$2 = (twips) => twips / TWIPS_PER_PX$1;
78394
78963
  const pxToTwips$1 = (px) => Math.round(px * TWIPS_PER_PX$1);
78964
+ const markerFontString = (run2) => {
78965
+ const size2 = run2?.fontSize ?? 16;
78966
+ const family = run2?.fontFamily ?? "Arial";
78967
+ const italic = run2?.italic ? "italic " : "";
78968
+ const bold = run2?.bold ? "bold " : "";
78969
+ return `${italic}${bold}${size2}px ${family}`.trim();
78970
+ };
78395
78971
  const buildTabStopsPx$1 = (indent, tabs, tabIntervalTwips) => {
78396
78972
  const paragraphIndentTwips = {
78397
78973
  left: pxToTwips$1(Math.max(0, indent?.left ?? 0)),
@@ -78422,7 +78998,9 @@ const getNextTabStopPx$1 = (currentX, tabStops, startIndex) => {
78422
78998
  };
78423
78999
  function measureRunSliceWidth(run2, fromChar, toChar) {
78424
79000
  const context = getCtx();
78425
- const text = runText(run2).slice(fromChar, toChar);
79001
+ const fullText = runText(run2);
79002
+ const transform = isTextRun$2(run2) ? run2.textTransform : void 0;
79003
+ const text = applyTextTransform$1(fullText.slice(fromChar, toChar), transform, fullText, fromChar);
78426
79004
  if (!context) {
78427
79005
  const textRun = isTextRun$2(run2) ? run2 : null;
78428
79006
  const size2 = textRun?.fontSize ?? 16;
@@ -78468,8 +79046,21 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
78468
79046
  const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
78469
79047
  const markerTextStartX = wordLayout?.marker?.textStartX;
78470
79048
  const textStartPx = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
78471
- const treatAsHanging = textStartPx && indentLeft === 0 && indentHanging === 0;
78472
- const firstLineWidth = typeof textStartPx === "number" && textStartPx > indentLeft && !treatAsHanging ? Math.max(1, maxWidth - textStartPx - indentRight) : Math.max(1, contentWidth - rawFirstLineOffset);
79049
+ const resolvedTextStartPx = resolveListTextStartPx(
79050
+ wordLayout,
79051
+ indentLeft,
79052
+ indentFirstLine,
79053
+ indentHanging,
79054
+ (markerText, marker) => {
79055
+ const context = getCtx();
79056
+ if (!context) return 0;
79057
+ context.font = markerFontString(marker.run);
79058
+ return context.measureText(markerText).width;
79059
+ }
79060
+ );
79061
+ const effectiveTextStartPx = resolvedTextStartPx ?? textStartPx;
79062
+ const treatAsHanging = !wordLayout?.marker && effectiveTextStartPx && indentLeft === 0 && indentHanging === 0;
79063
+ const firstLineWidth = typeof effectiveTextStartPx === "number" && effectiveTextStartPx > indentLeft && !treatAsHanging ? Math.max(1, maxWidth - effectiveTextStartPx - indentRight) : Math.max(1, contentWidth - rawFirstLineOffset);
78473
79064
  const tabStops = buildTabStopsPx$1(indent, attrs?.tabs, attrs?.tabIntervalTwips);
78474
79065
  let currentRun = 0;
78475
79066
  let currentChar = 0;
@@ -79009,7 +79600,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
79009
79600
  if (dirty.deletedBlockIds.length > 0) {
79010
79601
  measureCache.invalidate(dirty.deletedBlockIds);
79011
79602
  }
79012
- const { measurementWidth, measurementHeight } = resolveMeasurementConstraints(options);
79603
+ const { measurementWidth, measurementHeight } = resolveMeasurementConstraints(options, nextBlocks);
79013
79604
  if (measurementWidth <= 0 || measurementHeight <= 0) {
79014
79605
  throw new Error("incrementalLayout: invalid measurement constraints resolved from options");
79015
79606
  }
@@ -79278,7 +79869,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
79278
79869
  const DEFAULT_PAGE_SIZE$1 = { w: 612, h: 792 };
79279
79870
  const DEFAULT_MARGINS$1 = { top: 72, right: 72, bottom: 72, left: 72 };
79280
79871
  const normalizeMargin = (value, fallback) => Number.isFinite(value) ? value : fallback;
79281
- function resolveMeasurementConstraints(options) {
79872
+ function resolveMeasurementConstraints(options, blocks) {
79282
79873
  const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE$1;
79283
79874
  const margins = {
79284
79875
  top: normalizeMargin(options.margins?.top, DEFAULT_MARGINS$1.top),
@@ -79286,23 +79877,41 @@ function resolveMeasurementConstraints(options) {
79286
79877
  bottom: normalizeMargin(options.margins?.bottom, DEFAULT_MARGINS$1.bottom),
79287
79878
  left: normalizeMargin(options.margins?.left, DEFAULT_MARGINS$1.left)
79288
79879
  };
79289
- const contentWidth = pageSize.w - (margins.left + margins.right);
79290
- const contentHeight = pageSize.h - (margins.top + margins.bottom);
79291
- const columns = options.columns;
79292
- if (columns && columns.count > 1) {
79880
+ const baseContentWidth = pageSize.w - (margins.left + margins.right);
79881
+ const baseContentHeight = pageSize.h - (margins.top + margins.bottom);
79882
+ const computeColumnWidth = (contentWidth, columns) => {
79883
+ if (!columns || columns.count <= 1) return contentWidth;
79293
79884
  const gap = Math.max(0, columns.gap ?? 0);
79294
79885
  const totalGap = gap * (columns.count - 1);
79295
- const columnWidth = (contentWidth - totalGap) / columns.count;
79296
- if (columnWidth > 0) {
79297
- return {
79298
- measurementWidth: columnWidth,
79299
- measurementHeight: contentHeight
79886
+ return (contentWidth - totalGap) / columns.count;
79887
+ };
79888
+ let measurementWidth = computeColumnWidth(baseContentWidth, options.columns);
79889
+ let measurementHeight = baseContentHeight;
79890
+ if (blocks && blocks.length > 0) {
79891
+ for (const block of blocks) {
79892
+ if (block.kind !== "sectionBreak") continue;
79893
+ const sectionPageSize = block.pageSize ?? pageSize;
79894
+ const sectionMargins = {
79895
+ top: normalizeMargin(block.margins?.top, margins.top),
79896
+ right: normalizeMargin(block.margins?.right, margins.right),
79897
+ bottom: normalizeMargin(block.margins?.bottom, margins.bottom),
79898
+ left: normalizeMargin(block.margins?.left, margins.left)
79300
79899
  };
79900
+ const contentWidth = sectionPageSize.w - (sectionMargins.left + sectionMargins.right);
79901
+ const contentHeight = sectionPageSize.h - (sectionMargins.top + sectionMargins.bottom);
79902
+ if (contentWidth <= 0 || contentHeight <= 0) continue;
79903
+ const columnWidth = computeColumnWidth(contentWidth, block.columns ?? options.columns);
79904
+ if (columnWidth > measurementWidth) {
79905
+ measurementWidth = columnWidth;
79906
+ }
79907
+ if (contentHeight > measurementHeight) {
79908
+ measurementHeight = contentHeight;
79909
+ }
79301
79910
  }
79302
79911
  }
79303
79912
  return {
79304
- measurementWidth: contentWidth,
79305
- measurementHeight: contentHeight
79913
+ measurementWidth,
79914
+ measurementHeight
79306
79915
  };
79307
79916
  }
79308
79917
  const serializeHeaderFooterResults = (kind, batch) => {
@@ -81692,14 +82301,15 @@ function getAtomNodeTypes(schema) {
81692
82301
  if (!schema) return [];
81693
82302
  const types2 = [];
81694
82303
  try {
81695
- schema.nodes.forEach((nodeType, name) => {
82304
+ for (const name in schema.nodes) {
81696
82305
  if (name === "text") {
81697
- return;
82306
+ continue;
81698
82307
  }
81699
- if (nodeType.isAtom || nodeType.isLeaf) {
82308
+ const nodeType = schema.nodes[name];
82309
+ if (nodeType && (nodeType.isAtom || nodeType.isLeaf)) {
81700
82310
  types2.push(name);
81701
82311
  }
81702
- });
82312
+ }
81703
82313
  } catch {
81704
82314
  return [];
81705
82315
  }
@@ -83102,6 +83712,7 @@ function shouldRequirePageBoundary(current, next) {
83102
83712
  function hasIntrinsicBoundarySignals(_2) {
83103
83713
  return false;
83104
83714
  }
83715
+ const DEFAULT_HEADER_FOOTER_MARGIN_PX = 0;
83105
83716
  function shouldIgnoreSectionBreak(paragraph, index2, total, hasBodySectPr) {
83106
83717
  const paragraphAttrs = paragraph.attrs ?? {};
83107
83718
  const paragraphProperties = paragraphAttrs?.paragraphProperties;
@@ -83142,14 +83753,15 @@ function buildSectionRangesFromParagraphs(paragraphs, hasBodySectPr) {
83142
83753
  const sectionData = extractSectionData(item.node);
83143
83754
  if (!sectionData) return;
83144
83755
  const sectPr = getSectPrFromNode(item.node);
83756
+ const hasAnyMargin = sectionData.headerPx != null || sectionData.footerPx != null || sectionData.topPx != null || sectionData.rightPx != null || sectionData.bottomPx != null || sectionData.leftPx != null;
83145
83757
  const range2 = {
83146
83758
  sectionIndex: idx,
83147
83759
  startParagraphIndex: currentStart,
83148
83760
  endParagraphIndex: item.index,
83149
83761
  sectPr,
83150
- margins: sectionData.headerPx != null || sectionData.footerPx != null ? {
83151
- header: sectionData.headerPx ?? 0,
83152
- footer: sectionData.footerPx ?? 0,
83762
+ margins: hasAnyMargin ? {
83763
+ header: sectionData.headerPx ?? DEFAULT_HEADER_FOOTER_MARGIN_PX,
83764
+ footer: sectionData.footerPx ?? DEFAULT_HEADER_FOOTER_MARGIN_PX,
83153
83765
  top: sectionData.topPx,
83154
83766
  right: sectionData.rightPx,
83155
83767
  bottom: sectionData.bottomPx,
@@ -83191,14 +83803,15 @@ function createFinalSectionFromBodySectPr(bodySectPr, currentStart, totalParagra
83191
83803
  };
83192
83804
  const bodySectionData = extractSectionData(tempNode);
83193
83805
  if (!bodySectionData) return null;
83806
+ const hasAnyMargin = bodySectionData.headerPx != null || bodySectionData.footerPx != null || bodySectionData.topPx != null || bodySectionData.rightPx != null || bodySectionData.bottomPx != null || bodySectionData.leftPx != null;
83194
83807
  return {
83195
83808
  sectionIndex,
83196
83809
  startParagraphIndex: currentStart,
83197
83810
  endParagraphIndex: totalParagraphs - 1,
83198
83811
  sectPr: bodySectPr,
83199
- margins: bodySectionData.headerPx != null || bodySectionData.footerPx != null ? {
83200
- header: bodySectionData.headerPx ?? 0,
83201
- footer: bodySectionData.footerPx ?? 0,
83812
+ margins: hasAnyMargin ? {
83813
+ header: bodySectionData.headerPx ?? DEFAULT_HEADER_FOOTER_MARGIN_PX,
83814
+ footer: bodySectionData.footerPx ?? DEFAULT_HEADER_FOOTER_MARGIN_PX,
83202
83815
  top: bodySectionData.topPx,
83203
83816
  right: bodySectionData.rightPx,
83204
83817
  bottom: bodySectionData.bottomPx,
@@ -84182,11 +84795,27 @@ const collectTrackedChangeFromMarks = (marks) => {
84182
84795
  }, void 0);
84183
84796
  };
84184
84797
  const normalizeUnderlineStyle = (value) => {
84185
- if (value === "none") {
84186
- return void 0;
84798
+ if (value === void 0 || value === null) {
84799
+ return "single";
84187
84800
  }
84188
- if (value === "double" || value === "dotted" || value === "dashed" || value === "wavy") {
84189
- return value;
84801
+ if (typeof value === "boolean") {
84802
+ return value ? "single" : void 0;
84803
+ }
84804
+ if (typeof value === "number") {
84805
+ return value === 0 ? void 0 : "single";
84806
+ }
84807
+ if (typeof value === "string") {
84808
+ const normalized = value.trim().toLowerCase();
84809
+ if (!normalized) {
84810
+ return "single";
84811
+ }
84812
+ if (normalized === "none" || normalized === "0" || normalized === "false" || normalized === "off") {
84813
+ return void 0;
84814
+ }
84815
+ if (normalized === "double" || normalized === "dotted" || normalized === "dashed" || normalized === "wavy") {
84816
+ return normalized;
84817
+ }
84818
+ return "single";
84190
84819
  }
84191
84820
  return "single";
84192
84821
  };
@@ -84338,13 +84967,16 @@ const applyMarksToRun = (run2, marks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG
84338
84967
  break;
84339
84968
  }
84340
84969
  case "underline": {
84341
- const style2 = normalizeUnderlineStyle(mark.attrs?.underlineType);
84970
+ const underlineValue = mark.attrs?.underlineType ?? mark.attrs?.value ?? mark.attrs?.underline ?? mark.attrs?.style;
84971
+ const style2 = normalizeUnderlineStyle(underlineValue);
84342
84972
  if (style2) {
84343
84973
  const underlineColor = resolveColorFromAttributes(mark.attrs ?? {}, themeColors);
84344
84974
  run2.underline = {
84345
84975
  style: style2,
84346
84976
  color: underlineColor ?? run2.underline?.color
84347
84977
  };
84978
+ } else if (underlineValue !== void 0 && underlineValue !== null) {
84979
+ delete run2.underline;
84348
84980
  }
84349
84981
  break;
84350
84982
  }
@@ -85280,8 +85912,8 @@ function buildSdtCacheKey(nodeType, attrs, explicitKey) {
85280
85912
  }
85281
85913
  return void 0;
85282
85914
  }
85283
- const DEFAULT_LIST_HANGING_PX$1 = 18;
85284
- const LIST_MARKER_GAP$1 = 8;
85915
+ const DEFAULT_LIST_HANGING_PX = 18;
85916
+ const LIST_MARKER_GAP = 8;
85285
85917
  const DEFAULT_BULLET_GLYPH = "•";
85286
85918
  const DEFAULT_DECIMAL_PATTERN = "%1.";
85287
85919
  const ASCII_UPPERCASE_A = 65;
@@ -85692,7 +86324,7 @@ function computeWordParagraphLayout(input) {
85692
86324
  let markerBoxWidthPx;
85693
86325
  let markerX;
85694
86326
  if (hasFirstLineIndent) {
85695
- markerBoxWidthPx = glyphWidthPx != null && glyphWidthPx > 0 ? glyphWidthPx + LIST_MARKER_GAP$1 : DEFAULT_LIST_HANGING_PX$1;
86327
+ markerBoxWidthPx = glyphWidthPx != null && glyphWidthPx > 0 ? glyphWidthPx + LIST_MARKER_GAP : DEFAULT_LIST_HANGING_PX;
85696
86328
  markerX = indentLeftPx + (firstLinePx ?? 0);
85697
86329
  layout.textStartPx = markerX + markerBoxWidthPx;
85698
86330
  layout.hangingPx = 0;
@@ -85792,12 +86424,12 @@ const resolveMarkerBoxWidth = (hangingPxRaw, glyphWidthPx) => {
85792
86424
  let markerBox = Math.max(hangingPxRaw || 0, 0);
85793
86425
  if (markerBox <= 0) {
85794
86426
  if (glyphWidthPx != null && glyphWidthPx > 0) {
85795
- markerBox = glyphWidthPx + LIST_MARKER_GAP$1;
86427
+ markerBox = glyphWidthPx + LIST_MARKER_GAP;
85796
86428
  } else {
85797
- markerBox = DEFAULT_LIST_HANGING_PX$1;
86429
+ markerBox = DEFAULT_LIST_HANGING_PX;
85798
86430
  }
85799
- } else if (glyphWidthPx != null && glyphWidthPx + LIST_MARKER_GAP$1 > markerBox) {
85800
- markerBox = glyphWidthPx + LIST_MARKER_GAP$1;
86431
+ } else if (glyphWidthPx != null && glyphWidthPx + LIST_MARKER_GAP > markerBox) {
86432
+ markerBox = glyphWidthPx + LIST_MARKER_GAP;
85801
86433
  }
85802
86434
  return markerBox;
85803
86435
  };
@@ -85817,7 +86449,7 @@ const buildMarkerLayout = ({
85817
86449
  textStartX: textStartPx,
85818
86450
  baselineOffsetPx: markerRun.baselineShift ?? 0,
85819
86451
  // Gutter is the small gap between marker and text, not the full marker box width
85820
- gutterWidthPx: LIST_MARKER_GAP$1,
86452
+ gutterWidthPx: LIST_MARKER_GAP,
85821
86453
  justification: numbering.lvlJc ?? "left",
85822
86454
  suffix: normalizeSuffix$1(numbering.suffix) ?? "tab",
85823
86455
  run: markerRun,
@@ -85907,7 +86539,10 @@ const hydrateParagraphStyleAttrs = (para, context, preResolved) => {
85907
86539
  tabStops: cloneIfObject(resolvedExtended.tabStops),
85908
86540
  keepLines: resolvedExtended.keepLines,
85909
86541
  keepNext: resolvedExtended.keepNext,
85910
- numberingProperties: cloneIfObject(resolvedAsRecord.numberingProperties)
86542
+ numberingProperties: cloneIfObject(resolvedAsRecord.numberingProperties),
86543
+ // Extract contextualSpacing from style resolution - this is a sibling to spacing in OOXML,
86544
+ // not nested within it. When true, suppresses spacing between paragraphs of the same style.
86545
+ contextualSpacing: resolvedExtended.contextualSpacing
85911
86546
  };
85912
86547
  return hydrated;
85913
86548
  };
@@ -86509,6 +87144,31 @@ const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleCont
86509
87144
  return null;
86510
87145
  }
86511
87146
  };
87147
+ const normalizeWordLayoutForIndent = (wordLayout, paragraphIndent) => {
87148
+ const resolvedIndent = wordLayout.resolvedIndent ?? paragraphIndent ?? {};
87149
+ const indentLeft = isFiniteNumber(resolvedIndent.left) ? resolvedIndent.left : 0;
87150
+ const firstLine = isFiniteNumber(resolvedIndent.firstLine) ? resolvedIndent.firstLine : 0;
87151
+ const hanging = isFiniteNumber(resolvedIndent.hanging) ? resolvedIndent.hanging : 0;
87152
+ const shouldFirstLineIndentMode = firstLine > 0 && !hanging;
87153
+ if (wordLayout.firstLineIndentMode === true && !shouldFirstLineIndentMode) {
87154
+ wordLayout.firstLineIndentMode = false;
87155
+ }
87156
+ if (wordLayout.firstLineIndentMode === true) {
87157
+ if (isFiniteNumber(wordLayout.textStartPx)) {
87158
+ if (wordLayout.marker && (!isFiniteNumber(wordLayout.marker.textStartX) || wordLayout.marker.textStartX !== wordLayout.textStartPx)) {
87159
+ wordLayout.marker.textStartX = wordLayout.textStartPx;
87160
+ }
87161
+ } else if (wordLayout.marker && isFiniteNumber(wordLayout.marker.textStartX)) {
87162
+ wordLayout.textStartPx = wordLayout.marker.textStartX;
87163
+ }
87164
+ } else {
87165
+ wordLayout.textStartPx = indentLeft;
87166
+ if (wordLayout.marker) {
87167
+ wordLayout.marker.textStartX = indentLeft;
87168
+ }
87169
+ }
87170
+ return wordLayout;
87171
+ };
86512
87172
  const computeParagraphAttrs = (para, styleContext, listCounterContext, converterContext, hydrationOverride) => {
86513
87173
  const attrs = para.attrs ?? {};
86514
87174
  const paragraphProps = typeof attrs.paragraphProperties === "object" && attrs.paragraphProperties !== null ? attrs.paragraphProperties : {};
@@ -86617,7 +87277,7 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
86617
87277
  paragraphAttrs.spacing.afterAutospacing = normalizedSpacing.afterAutospacing;
86618
87278
  }
86619
87279
  }
86620
- const contextualSpacingValue = normalizedSpacing?.contextualSpacing ?? safeGetProperty(paragraphProps, "contextualSpacing") ?? safeGetProperty(attrs, "contextualSpacing");
87280
+ const contextualSpacingValue = normalizedSpacing?.contextualSpacing ?? safeGetProperty(paragraphProps, "contextualSpacing") ?? safeGetProperty(attrs, "contextualSpacing") ?? hydrated?.contextualSpacing;
86621
87281
  if (contextualSpacingValue != null) {
86622
87282
  paragraphAttrs.contextualSpacing = isTruthy(contextualSpacingValue);
86623
87283
  }
@@ -86831,8 +87491,11 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
86831
87491
  let wordLayout = computeWordLayoutForParagraph(paragraphAttrs, enrichedNumberingProps, styleContext);
86832
87492
  if (!wordLayout && enrichedNumberingProps.resolvedLevelIndent) {
86833
87493
  const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
86834
- const firstLinePx = resolvedIndentPx?.firstLine ?? 0;
86835
- if (firstLinePx > 0) {
87494
+ const baseIndent = resolvedIndentPx ?? enrichedNumberingProps.resolvedLevelIndent;
87495
+ const mergedIndent = { ...baseIndent, ...paragraphAttrs.indent ?? {} };
87496
+ const firstLinePx = isFiniteNumber(mergedIndent.firstLine) ? mergedIndent.firstLine : 0;
87497
+ const hangingPx = isFiniteNumber(mergedIndent.hanging) ? mergedIndent.hanging : 0;
87498
+ if (firstLinePx > 0 && !hangingPx) {
86836
87499
  wordLayout = {
86837
87500
  // Treat as first-line-indent mode: text starts after the marker+firstLine offset.
86838
87501
  firstLineIndentMode: true,
@@ -86840,10 +87503,13 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
86840
87503
  };
86841
87504
  }
86842
87505
  }
86843
- if (wordLayout && (!wordLayout.textStartPx || !Number.isFinite(wordLayout.textStartPx)) && enrichedNumberingProps.resolvedLevelIndent) {
87506
+ if (wordLayout && !Number.isFinite(wordLayout.textStartPx) && enrichedNumberingProps.resolvedLevelIndent) {
86844
87507
  const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
86845
- const firstLinePx = resolvedIndentPx?.firstLine ?? 0;
86846
- if (firstLinePx > 0) {
87508
+ const baseIndent = resolvedIndentPx ?? enrichedNumberingProps.resolvedLevelIndent;
87509
+ const mergedIndent = { ...baseIndent, ...paragraphAttrs.indent ?? {} };
87510
+ const firstLinePx = isFiniteNumber(mergedIndent.firstLine) ? mergedIndent.firstLine : 0;
87511
+ const hangingPx = isFiniteNumber(mergedIndent.hanging) ? mergedIndent.hanging : 0;
87512
+ if (firstLinePx > 0 && !hangingPx) {
86847
87513
  wordLayout = {
86848
87514
  ...wordLayout,
86849
87515
  firstLineIndentMode: wordLayout.firstLineIndentMode ?? true,
@@ -86863,6 +87529,7 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
86863
87529
  wordLayout.marker.suffix = listRendering.suffix;
86864
87530
  }
86865
87531
  }
87532
+ wordLayout = normalizeWordLayoutForIndent(wordLayout, paragraphAttrs.indent);
86866
87533
  paragraphAttrs.wordLayout = wordLayout;
86867
87534
  }
86868
87535
  if (enrichedNumberingProps.resolvedLevelIndent) {
@@ -90979,11 +91646,6 @@ function initHeaderFooterRegistry({
90979
91646
  cleanups
90980
91647
  };
90981
91648
  }
90982
- const LIST_MARKER_GAP = 8;
90983
- const MIN_MARKER_GUTTER = 24;
90984
- const DEFAULT_LIST_INDENT_BASE_PX = 24;
90985
- const DEFAULT_LIST_INDENT_STEP_PX = 24;
90986
- const DEFAULT_LIST_HANGING_PX = 18;
90987
91649
  function calculateRotatedBounds(input) {
90988
91650
  const width = Math.max(0, input.width);
90989
91651
  const height = Math.max(0, input.height);
@@ -91153,7 +91815,7 @@ function measureText(text, font, ctx2, _fontFamily, _letterSpacing) {
91153
91815
  return Math.max(advanceWidth, paintedWidth);
91154
91816
  }
91155
91817
  const MIN_SINGLE_LINE_PX = 12 * 96 / 72;
91156
- const LINE_HEIGHT_SAFETY_MARGIN_PX = 1;
91818
+ const WORD_SINGLE_LINE_SPACING_MULTIPLIER = 1.15;
91157
91819
  function calculateTypographyMetrics(fontSize2, spacing, fontInfo) {
91158
91820
  let ascent;
91159
91821
  let descent;
@@ -91166,7 +91828,7 @@ function calculateTypographyMetrics(fontSize2, spacing, fontInfo) {
91166
91828
  ascent = roundValue(fontSize2 * 0.8);
91167
91829
  descent = roundValue(fontSize2 * 0.2);
91168
91830
  }
91169
- const baseLineHeight = Math.max(ascent + descent + LINE_HEIGHT_SAFETY_MARGIN_PX, MIN_SINGLE_LINE_PX);
91831
+ const baseLineHeight = Math.max(fontSize2 * WORD_SINGLE_LINE_SPACING_MULTIPLIER, ascent + descent, MIN_SINGLE_LINE_PX);
91170
91832
  const lineHeight2 = roundValue(resolveLineHeight(spacing, baseLineHeight));
91171
91833
  return {
91172
91834
  ascent,
@@ -91247,8 +91909,25 @@ async function measureParagraphBlock(block, maxWidth) {
91247
91909
  const rawTextStartPx = wordLayout?.textStartPx;
91248
91910
  const markerTextStartX = wordLayout?.marker?.textStartX;
91249
91911
  const textStartPx = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof rawTextStartPx === "number" && Number.isFinite(rawTextStartPx) ? rawTextStartPx : void 0;
91250
- if (typeof textStartPx === "number" && textStartPx > indentLeft) {
91251
- initialAvailableWidth = Math.max(1, maxWidth - textStartPx - indentRight);
91912
+ const resolvedTextStartPx = resolveListTextStartPx(
91913
+ wordLayout,
91914
+ indentLeft,
91915
+ firstLine,
91916
+ hanging,
91917
+ (markerText, marker) => {
91918
+ const markerRun = {
91919
+ fontFamily: toCssFontFamily(marker.run?.fontFamily) ?? marker.run?.fontFamily ?? "Arial",
91920
+ fontSize: marker.run?.fontSize ?? 16,
91921
+ bold: marker.run?.bold ?? false,
91922
+ italic: marker.run?.italic ?? false
91923
+ };
91924
+ const { font: markerFont } = buildFontString(markerRun);
91925
+ return measureText(markerText, markerFont, ctx2);
91926
+ }
91927
+ );
91928
+ const effectiveTextStartPx = resolvedTextStartPx ?? textStartPx;
91929
+ if (typeof effectiveTextStartPx === "number" && effectiveTextStartPx > indentLeft) {
91930
+ initialAvailableWidth = Math.max(1, maxWidth - effectiveTextStartPx - indentRight);
91252
91931
  } else {
91253
91932
  initialAvailableWidth = Math.max(1, contentWidth - firstLineOffset);
91254
91933
  }
@@ -91335,7 +92014,7 @@ async function measureParagraphBlock(block, maxWidth) {
91335
92014
  pendingTabAlignment = null;
91336
92015
  return startX;
91337
92016
  };
91338
- const alignSegmentAtTab = (segmentText, font, runContext) => {
92017
+ const alignSegmentAtTab = (segmentText, font, runContext, segmentStartChar) => {
91339
92018
  if (!pendingTabAlignment || !currentLine) return void 0;
91340
92019
  const { val } = pendingTabAlignment;
91341
92020
  let segmentWidth = 0;
@@ -91344,11 +92023,11 @@ async function measureParagraphBlock(block, maxWidth) {
91344
92023
  const idx = segmentText.indexOf(decimalSeparator);
91345
92024
  if (idx >= 0) {
91346
92025
  const beforeText = segmentText.slice(0, idx);
91347
- beforeDecimalWidth = beforeText.length > 0 ? measureRunWidth(beforeText, font, ctx2, runContext) : 0;
92026
+ beforeDecimalWidth = beforeText.length > 0 ? measureRunWidth(beforeText, font, ctx2, runContext, segmentStartChar) : 0;
91348
92027
  }
91349
- segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext) : 0;
92028
+ segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext, segmentStartChar) : 0;
91350
92029
  } else if (val === "end" || val === "center") {
91351
- segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext) : 0;
92030
+ segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext, segmentStartChar) : 0;
91352
92031
  }
91353
92032
  return alignPendingTabForWidth(segmentWidth, beforeDecimalWidth);
91354
92033
  };
@@ -91400,8 +92079,8 @@ async function measureParagraphBlock(block, maxWidth) {
91400
92079
  const { font } = buildFontString(
91401
92080
  lastRun
91402
92081
  );
91403
- const fullWidth = measureRunWidth(sliceText, font, ctx2, lastRun);
91404
- const keptWidth = keptText.length > 0 ? measureRunWidth(keptText, font, ctx2, lastRun) : 0;
92082
+ const fullWidth = measureRunWidth(sliceText, font, ctx2, lastRun, sliceStart);
92083
+ const keptWidth = keptText.length > 0 ? measureRunWidth(keptText, font, ctx2, lastRun, sliceStart) : 0;
91405
92084
  const delta = Math.max(0, fullWidth - keptWidth);
91406
92085
  lineToTrim.width = roundValue(Math.max(0, lineToTrim.width - delta));
91407
92086
  lineToTrim.spaceCount = Math.max(0, lineToTrim.spaceCount - trimCount);
@@ -91612,7 +92291,8 @@ async function measureParagraphBlock(block, maxWidth) {
91612
92291
  continue;
91613
92292
  }
91614
92293
  if (isFieldAnnotationRun(run2)) {
91615
- const displayText = run2.displayLabel || "";
92294
+ const rawDisplayText = run2.displayLabel || "";
92295
+ const displayText = applyTextTransform(rawDisplayText, run2);
91616
92296
  const annotationFontSize = typeof run2.fontSize === "number" ? run2.fontSize : typeof run2.fontSize === "string" ? parseFloat(run2.fontSize) || DEFAULT_FIELD_ANNOTATION_FONT_SIZE : DEFAULT_FIELD_ANNOTATION_FONT_SIZE;
91617
92297
  const annotationFontFamily = run2.fontFamily || "Arial, sans-serif";
91618
92298
  const fontWeight = run2.bold ? "bold" : "normal";
@@ -91715,7 +92395,7 @@ async function measureParagraphBlock(block, maxWidth) {
91715
92395
  const spacesLength = segment.length;
91716
92396
  const spacesStartChar = charPosInRun;
91717
92397
  const spacesEndChar = charPosInRun + spacesLength;
91718
- const spacesWidth = measureRunWidth(segment, font, ctx2, run2);
92398
+ const spacesWidth = measureRunWidth(segment, font, ctx2, run2, spacesStartChar);
91719
92399
  if (!currentLine) {
91720
92400
  currentLine = {
91721
92401
  fromRun: runIndex,
@@ -91779,7 +92459,7 @@ async function measureParagraphBlock(block, maxWidth) {
91779
92459
  }
91780
92460
  let segmentStartX;
91781
92461
  if (currentLine && pendingTabAlignment) {
91782
- segmentStartX = alignSegmentAtTab(segment, font, run2);
92462
+ segmentStartX = alignSegmentAtTab(segment, font, run2, charPosInRun);
91783
92463
  if (segmentStartX == null) {
91784
92464
  segmentStartX = currentLine.width;
91785
92465
  }
@@ -91789,7 +92469,7 @@ async function measureParagraphBlock(block, maxWidth) {
91789
92469
  if (word2 === "") {
91790
92470
  const spaceStartChar = charPosInRun;
91791
92471
  const spaceEndChar = charPosInRun + 1;
91792
- const singleSpaceWidth = measureRunWidth(" ", font, ctx2, run2);
92472
+ const singleSpaceWidth = measureRunWidth(" ", font, ctx2, run2, spaceStartChar);
91793
92473
  if (!currentLine) {
91794
92474
  currentLine = {
91795
92475
  fromRun: runIndex,
@@ -91840,12 +92520,12 @@ async function measureParagraphBlock(block, maxWidth) {
91840
92520
  charPosInRun = spaceEndChar;
91841
92521
  continue;
91842
92522
  }
91843
- const wordOnlyWidth = measureRunWidth(word2, font, ctx2, run2);
91844
- const shouldIncludeDelimiterSpace = wordIndex < lastNonEmptyWordIndex;
91845
- const spaceWidth = shouldIncludeDelimiterSpace ? measureRunWidth(" ", font, ctx2, run2) : 0;
91846
- const wordCommitWidth = wordOnlyWidth + spaceWidth;
91847
92523
  const wordStartChar = charPosInRun;
92524
+ const wordOnlyWidth = measureRunWidth(word2, font, ctx2, run2, wordStartChar);
92525
+ const shouldIncludeDelimiterSpace = wordIndex < lastNonEmptyWordIndex;
91848
92526
  const wordEndNoSpace = charPosInRun + word2.length;
92527
+ const spaceWidth = shouldIncludeDelimiterSpace ? measureRunWidth(" ", font, ctx2, run2, wordEndNoSpace) : 0;
92528
+ const wordCommitWidth = wordOnlyWidth + spaceWidth;
91849
92529
  const wordEndWithSpace = wordEndNoSpace + (shouldIncludeDelimiterSpace ? 1 : 0);
91850
92530
  const effectiveMaxWidth = currentLine ? currentLine.maxWidth : getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
91851
92531
  if (wordOnlyWidth > effectiveMaxWidth && word2.length > 1) {
@@ -91864,7 +92544,7 @@ async function measureParagraphBlock(block, maxWidth) {
91864
92544
  const hasTabOnlyLine = currentLine && currentLine.segments && currentLine.segments.length === 0 && currentLine.width > 0;
91865
92545
  const remainingWidthAfterTab = hasTabOnlyLine ? currentLine.maxWidth - currentLine.width : lineMaxWidth;
91866
92546
  const chunkWidth = hasTabOnlyLine ? Math.max(remainingWidthAfterTab, lineMaxWidth * 0.25) : lineMaxWidth;
91867
- const chunks = breakWordIntoChunks(word2, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run2);
92547
+ const chunks = breakWordIntoChunks(word2, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run2, wordStartChar);
91868
92548
  let chunkCharOffset = wordStartChar;
91869
92549
  for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
91870
92550
  const chunk = chunks[chunkIndex];
@@ -91966,6 +92646,10 @@ async function measureParagraphBlock(block, maxWidth) {
91966
92646
  currentLine.width = roundValue(currentLine.width + spaceWidth + ls);
91967
92647
  charPosInRun = wordEndWithSpace;
91968
92648
  currentLine.spaceCount += 1;
92649
+ if (currentLine.segments?.[0]) {
92650
+ currentLine.segments[0].toChar = wordEndWithSpace;
92651
+ currentLine.segments[0].width += spaceWidth;
92652
+ }
91969
92653
  } else {
91970
92654
  charPosInRun = wordEndWithSpace;
91971
92655
  }
@@ -91988,7 +92672,7 @@ async function measureParagraphBlock(block, maxWidth) {
91988
92672
  if (candidateSpaces > 0) {
91989
92673
  const overflow = totalWidthWithWord - availableWidth;
91990
92674
  if (overflow > 0) {
91991
- const baseSpaceWidth = spaceWidth || measureRunWidth(" ", font, ctx2, run2) || Math.max(1, boundarySpacing);
92675
+ const baseSpaceWidth = spaceWidth || measureRunWidth(" ", font, ctx2, run2, wordEndNoSpace) || Math.max(1, boundarySpacing);
91992
92676
  const perSpaceCompression = overflow / candidateSpaces;
91993
92677
  const maxPerSpaceCompression = baseSpaceWidth * 0.25;
91994
92678
  if (perSpaceCompression <= maxPerSpaceCompression) {
@@ -92028,6 +92712,10 @@ async function measureParagraphBlock(block, maxWidth) {
92028
92712
  currentLine.width = roundValue(currentLine.width + spaceWidth + (run2.letterSpacing ?? 0));
92029
92713
  charPosInRun = wordEndWithSpace;
92030
92714
  currentLine.spaceCount += 1;
92715
+ if (currentLine.segments?.[0]) {
92716
+ currentLine.segments[0].toChar = wordEndWithSpace;
92717
+ currentLine.segments[0].width += spaceWidth;
92718
+ }
92031
92719
  } else {
92032
92720
  charPosInRun = wordEndWithSpace;
92033
92721
  }
@@ -92163,8 +92851,8 @@ async function measureParagraphBlock(block, maxWidth) {
92163
92851
  const { font: markerFont } = buildFontString(markerRun);
92164
92852
  const markerText = wordLayout.marker.markerText ?? "";
92165
92853
  const glyphWidth = markerText ? measureText(markerText, markerFont, ctx2) : 0;
92166
- const gutter = typeof wordLayout.marker.gutterWidthPx === "number" && isFinite(wordLayout.marker.gutterWidthPx) && wordLayout.marker.gutterWidthPx >= 0 ? wordLayout.marker.gutterWidthPx : LIST_MARKER_GAP;
92167
- const markerBoxWidth = Math.max(wordLayout.marker.markerBoxWidthPx ?? 0, glyphWidth + LIST_MARKER_GAP);
92854
+ const gutter = typeof wordLayout.marker.gutterWidthPx === "number" && isFinite(wordLayout.marker.gutterWidthPx) && wordLayout.marker.gutterWidthPx >= 0 ? wordLayout.marker.gutterWidthPx : LIST_MARKER_GAP$1;
92855
+ const markerBoxWidth = Math.max(wordLayout.marker.markerBoxWidthPx ?? 0, glyphWidth + LIST_MARKER_GAP$1);
92168
92856
  markerInfo = {
92169
92857
  markerWidth: markerBoxWidth,
92170
92858
  markerTextWidth: glyphWidth,
@@ -92508,7 +93196,7 @@ async function measureListBlock(block, constraints) {
92508
93196
  markerTextWidth = markerText ? measureText(markerText, markerFont, ctx2) : 0;
92509
93197
  indentLeft = resolveIndentLeft(item);
92510
93198
  const indentHanging = resolveIndentHanging(item);
92511
- markerWidth = Math.max(MIN_MARKER_GUTTER, markerTextWidth + LIST_MARKER_GAP, indentHanging);
93199
+ markerWidth = Math.max(MIN_MARKER_GUTTER, markerTextWidth + LIST_MARKER_GAP$1, indentHanging);
92512
93200
  }
92513
93201
  const paragraphWidth = Math.max(1, constraints.maxWidth - indentLeft - markerWidth);
92514
93202
  const paragraphMeasure = await measureParagraphBlock(item.paragraph, paragraphWidth);
@@ -92534,16 +93222,46 @@ const getPrimaryRun = (paragraph) => {
92534
93222
  fontSize: 16
92535
93223
  };
92536
93224
  };
92537
- const measureRunWidth = (text, font, ctx2, run2) => {
93225
+ const isWordChar = (char) => {
93226
+ if (!char) return false;
93227
+ const code = char.charCodeAt(0);
93228
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
93229
+ };
93230
+ const capitalizeText = (text, fullText, startOffset) => {
93231
+ if (!text) return text;
93232
+ const hasFullText = typeof startOffset === "number" && fullText != null;
93233
+ let result = "";
93234
+ for (let i = 0; i < text.length; i += 1) {
93235
+ const prevChar = hasFullText ? startOffset + i > 0 ? fullText[startOffset + i - 1] : "" : i > 0 ? text[i - 1] : "";
93236
+ const ch = text[i];
93237
+ result += isWordChar(ch) && !isWordChar(prevChar) ? ch.toUpperCase() : ch;
93238
+ }
93239
+ return result;
93240
+ };
93241
+ const applyTextTransform = (text, run2, startOffset) => {
93242
+ const transform = "textTransform" in run2 ? run2.textTransform : void 0;
93243
+ if (!text || !transform || transform === "none") return text;
93244
+ if (transform === "uppercase") return text.toUpperCase();
93245
+ if (transform === "lowercase") return text.toLowerCase();
93246
+ if (transform === "capitalize") {
93247
+ const fullText = "text" in run2 && typeof run2.text === "string" ? run2.text : text;
93248
+ return capitalizeText(text, fullText, startOffset);
93249
+ }
93250
+ return text;
93251
+ };
93252
+ const measureRunWidth = (text, font, ctx2, run2, startOffset) => {
92538
93253
  const letterSpacing = run2.kind === "text" || run2.kind === void 0 ? run2.letterSpacing || 0 : 0;
92539
- const width = getMeasuredTextWidth(text, font, letterSpacing, ctx2);
93254
+ const displayText = applyTextTransform(text, run2, startOffset);
93255
+ const width = getMeasuredTextWidth(displayText, font, letterSpacing, ctx2);
92540
93256
  return roundValue(width);
92541
93257
  };
92542
- const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run2) => {
93258
+ const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run2, startOffset) => {
92543
93259
  const chunks = [];
93260
+ const baseOffset = typeof startOffset === "number" ? startOffset : 0;
92544
93261
  if (maxWidth <= 0) {
92545
- for (const char of word2) {
92546
- const charWidth = measureRunWidth(char, font, ctx2, run2);
93262
+ for (let i = 0; i < word2.length; i++) {
93263
+ const char = word2[i];
93264
+ const charWidth = measureRunWidth(char, font, ctx2, run2, baseOffset + i);
92547
93265
  chunks.push({ text: char, width: charWidth });
92548
93266
  }
92549
93267
  return chunks;
@@ -92553,11 +93271,11 @@ const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run2) => {
92553
93271
  for (let i = 0; i < word2.length; i++) {
92554
93272
  const char = word2[i];
92555
93273
  const testChunk = currentChunk + char;
92556
- const testWidth = measureRunWidth(testChunk, font, ctx2, run2);
93274
+ const testWidth = measureRunWidth(testChunk, font, ctx2, run2, baseOffset);
92557
93275
  if (testWidth > maxWidth && currentChunk.length > 0) {
92558
93276
  chunks.push({ text: currentChunk, width: currentWidth });
92559
93277
  currentChunk = char;
92560
- currentWidth = measureRunWidth(char, font, ctx2, run2);
93278
+ currentWidth = measureRunWidth(char, font, ctx2, run2, baseOffset + i);
92561
93279
  } else {
92562
93280
  currentChunk = testChunk;
92563
93281
  currentWidth = testWidth;
@@ -92611,12 +93329,13 @@ const measureDropCap = (ctx2, descriptor, spacing) => {
92611
93329
  italic: run2.italic
92612
93330
  });
92613
93331
  ctx2.font = font;
92614
- const metrics = ctx2.measureText(run2.text);
93332
+ const displayText = applyTextTransform(run2.text, run2);
93333
+ const metrics = ctx2.measureText(displayText);
92615
93334
  const advanceWidth = metrics.width;
92616
93335
  const paintedWidth = (metrics.actualBoundingBoxLeft || 0) + (metrics.actualBoundingBoxRight || 0);
92617
93336
  const textWidth = Math.max(advanceWidth, paintedWidth);
92618
93337
  const width = roundValue(textWidth + DROP_CAP_PADDING_PX);
92619
- const baseLineHeight = resolveLineHeight(spacing, run2.fontSize * 1.2);
93338
+ const baseLineHeight = resolveLineHeight(spacing, run2.fontSize * WORD_SINGLE_LINE_SPACING_MULTIPLIER);
92620
93339
  const height = roundValue(baseLineHeight * lines);
92621
93340
  return {
92622
93341
  width,
@@ -92637,7 +93356,7 @@ const resolveIndentHanging = (item) => {
92637
93356
  if (indentHanging > 0) {
92638
93357
  return indentHanging;
92639
93358
  }
92640
- return DEFAULT_LIST_HANGING_PX;
93359
+ return DEFAULT_LIST_HANGING_PX$1;
92641
93360
  };
92642
93361
  const buildTabStopsPx = (indent, tabs, tabIntervalTwips) => {
92643
93362
  const paragraphIndentTwips = {
@@ -92843,6 +93562,9 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
92843
93562
  if (event.button !== 0) {
92844
93563
  return;
92845
93564
  }
93565
+ if (event.ctrlKey && navigator.platform.includes("Mac")) {
93566
+ return;
93567
+ }
92846
93568
  __privateSet(this, _pendingMarginClick, null);
92847
93569
  const target = event.target;
92848
93570
  if (target?.closest?.(".superdoc-ruler-handle") != null) {
@@ -93339,6 +94061,10 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
93339
94061
  __privateMethod$1(this, _PresentationEditor_instances, clearHoverRegion_fn).call(this);
93340
94062
  return;
93341
94063
  }
94064
+ if (__privateGet$1(this, _documentMode) === "viewing") {
94065
+ __privateMethod$1(this, _PresentationEditor_instances, clearHoverRegion_fn).call(this);
94066
+ return;
94067
+ }
93342
94068
  const region = __privateMethod$1(this, _PresentationEditor_instances, hitTestHeaderFooterRegion_fn).call(this, normalized.x, normalized.y);
93343
94069
  if (!region) {
93344
94070
  __privateMethod$1(this, _PresentationEditor_instances, clearHoverRegion_fn).call(this);
@@ -93567,6 +94293,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
93567
94293
  __privateSet(this, _visibleHost, options.element);
93568
94294
  __privateGet$1(this, _visibleHost).innerHTML = "";
93569
94295
  __privateGet$1(this, _visibleHost).classList.add("presentation-editor");
94296
+ __privateMethod$1(this, _PresentationEditor_instances, syncDocumentModeClass_fn).call(this);
93570
94297
  if (!__privateGet$1(this, _visibleHost).hasAttribute("tabindex")) {
93571
94298
  __privateGet$1(this, _visibleHost).tabIndex = 0;
93572
94299
  }
@@ -94062,6 +94789,7 @@ const _PresentationEditor = class _PresentationEditor2 extends EventEmitter$1 {
94062
94789
  }
94063
94790
  __privateSet(this, _documentMode, mode);
94064
94791
  __privateGet$1(this, _editor3).setDocumentMode(mode);
94792
+ __privateMethod$1(this, _PresentationEditor_instances, syncDocumentModeClass_fn).call(this);
94065
94793
  __privateMethod$1(this, _PresentationEditor_instances, syncHiddenEditorA11yAttributes_fn).call(this);
94066
94794
  const trackedChangesChanged = __privateMethod$1(this, _PresentationEditor_instances, syncTrackedChangesPreferences_fn).call(this);
94067
94795
  if (trackedChangesChanged) {
@@ -94972,6 +95700,10 @@ wrapHiddenEditorFocus_fn = function() {
94972
95700
  }
94973
95701
  };
94974
95702
  };
95703
+ syncDocumentModeClass_fn = function() {
95704
+ if (!__privateGet$1(this, _visibleHost)) return;
95705
+ __privateGet$1(this, _visibleHost).classList.toggle("presentation-editor--viewing", __privateGet$1(this, _documentMode) === "viewing");
95706
+ };
94975
95707
  collectCommentPositions_fn = function() {
94976
95708
  return collectCommentPositions(__privateGet$1(this, _editor3)?.state?.doc ?? null, {
94977
95709
  commentMarkName: CommentMarkName,
@@ -95605,7 +96337,7 @@ rerender_fn = async function() {
95605
96337
  const atomNodeTypes = getAtomNodeTypes(__privateGet$1(this, _editor3)?.schema ?? null);
95606
96338
  const positionMap = __privateGet$1(this, _editor3)?.state?.doc && docJson ? buildPositionMapFromPmDoc(__privateGet$1(this, _editor3).state.doc, docJson) : null;
95607
96339
  const result = toFlowBlocks(docJson, {
95608
- mediaFiles: __privateGet$1(this, _options).mediaFiles,
96340
+ mediaFiles: __privateGet$1(this, _editor3)?.storage?.image?.media,
95609
96341
  emitSectionBreaks: true,
95610
96342
  sectionMetadata,
95611
96343
  trackedChangesMode: __privateGet$1(this, _trackedChangesMode),
@@ -96672,6 +97404,10 @@ renderCellSelectionOverlay_fn = function(selection, layout) {
96672
97404
  });
96673
97405
  };
96674
97406
  renderHoverRegion_fn = function(region) {
97407
+ if (__privateGet$1(this, _documentMode) === "viewing") {
97408
+ __privateMethod$1(this, _PresentationEditor_instances, clearHoverRegion_fn).call(this);
97409
+ return;
97410
+ }
96675
97411
  if (!__privateGet$1(this, _hoverOverlay) || !__privateGet$1(this, _hoverTooltip)) return;
96676
97412
  const coords = __privateMethod$1(this, _PresentationEditor_instances, convertPageLocalToOverlayCoords_fn).call(this, region.pageIndex, region.localX, region.localY);
96677
97413
  if (!coords) {
@@ -98252,6 +98988,8 @@ const SlashMenu = Extension.create({
98252
98988
  const cbRect = containingBlock.getBoundingClientRect();
98253
98989
  left2 -= cbRect.left;
98254
98990
  top2 -= cbRect.top;
98991
+ left2 += containingBlock.scrollLeft || 0;
98992
+ top2 += containingBlock.scrollTop || 0;
98255
98993
  } catch (error) {
98256
98994
  console.warn("SlashMenu: Failed to adjust for containing block", error);
98257
98995
  }
@@ -114159,7 +114897,7 @@ const nodeResizer = (nodeNames = ["image"], editor) => {
114159
114897
  document.addEventListener("mousedown", globalMousedownHandler);
114160
114898
  scrollHandler = () => {
114161
114899
  if (currentWrapper && resizeContainer) {
114162
- updateHandlePositions(currentWrapper.firstElementChild);
114900
+ updateHandlePositions(currentWrapper);
114163
114901
  }
114164
114902
  };
114165
114903
  window.addEventListener("scroll", scrollHandler, true);
@@ -114221,7 +114959,7 @@ const nodeResizer = (nodeNames = ["image"], editor) => {
114221
114959
  }
114222
114960
  applyStyleIsolationClass(resizeContainer);
114223
114961
  document.body.appendChild(resizeContainer);
114224
- updateHandlePositions(wrapper.firstElementChild);
114962
+ updateHandlePositions(wrapper);
114225
114963
  }
114226
114964
  function hideResizeHandles() {
114227
114965
  if (resizeContainer?.parentNode) {
@@ -129590,7 +130328,7 @@ const _sfc_main$8 = {
129590
130328
  if (open) {
129591
130329
  vue.nextTick(() => {
129592
130330
  if (searchInput.value) {
129593
- searchInput.value.focus();
130331
+ searchInput.value.focus({ preventScroll: true });
129594
130332
  }
129595
130333
  });
129596
130334
  }
@@ -129695,7 +130433,11 @@ const _sfc_main$8 = {
129695
130433
  };
129696
130434
  const handleGlobalOutsideClick = (event) => {
129697
130435
  if (isOpen.value && menuRef.value && !menuRef.value.contains(event.target)) {
129698
- moveCursorToMouseEvent(event, props.editor);
130436
+ const isCtrlClickOnMac = event.ctrlKey && isMacOS();
130437
+ const isLeftClick = event.button === 0 && !isCtrlClickOnMac;
130438
+ if (isLeftClick) {
130439
+ moveCursorToMouseEvent(event, props.editor);
130440
+ }
129699
130441
  closeMenu({ restoreCursor: false });
129700
130442
  }
129701
130443
  };
@@ -131817,6 +132559,12 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
131817
132559
  if (props.options?.suppressSkeletonLoader || !props.options?.collaborationProvider) editorReady.value = true;
131818
132560
  });
131819
132561
  const handleMarginClick = (event) => {
132562
+ if (event.button !== 0) {
132563
+ return;
132564
+ }
132565
+ if (event.ctrlKey && isMacOS()) {
132566
+ return;
132567
+ }
131820
132568
  if (event.target.classList.contains("ProseMirror")) return;
131821
132569
  onMarginClickCursorChange(event, activeEditor.value);
131822
132570
  };
@@ -131955,7 +132703,7 @@ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
131955
132703
  };
131956
132704
  }
131957
132705
  });
131958
- const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-209a1e8b"]]);
132706
+ const SuperEditor = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-c9a3c876"]]);
131959
132707
  const _hoisted_1 = ["innerHTML"];
131960
132708
  const _sfc_main = {
131961
132709
  __name: "SuperInput",