superdoc 1.0.2 → 1.0.3

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 (30) hide show
  1. package/dist/chunks/{PdfViewer-Dk7wI3bm.cjs → PdfViewer-2wYU1nQs.cjs} +1 -1
  2. package/dist/chunks/{PdfViewer-C51KNTCu.es.js → PdfViewer-Brf64q-p.es.js} +1 -1
  3. package/dist/chunks/{index-DDZ1ZT8N-DzepXBTN.cjs → index-BFesQTtm-DF8MwT73.cjs} +1 -1
  4. package/dist/chunks/{index-DDZ1ZT8N-MJzqg0qg.es.js → index-BFesQTtm-DNeH374x.es.js} +1 -1
  5. package/dist/chunks/{index-Cf7hdzkm.cjs → index-DeETxTrW.cjs} +3 -3
  6. package/dist/chunks/{index-rtbawgUA.es.js → index-KBIvw6xZ.es.js} +3 -3
  7. package/dist/chunks/{super-editor.es-BijxiFs9.cjs → super-editor.es-C_LoTWvJ.cjs} +687 -136
  8. package/dist/chunks/{super-editor.es-DFXddrgb.es.js → super-editor.es-DWpzsMUa.es.js} +687 -136
  9. package/dist/packages/superdoc/src/core/SuperDoc.d.ts.map +1 -1
  10. package/dist/style.css +6 -6
  11. package/dist/super-editor/ai-writer.es.js +2 -2
  12. package/dist/super-editor/chunks/{converter-VYPiNbpo.js → converter-BhELnOP5.js} +1 -1
  13. package/dist/super-editor/chunks/{docx-zipper-D8Tzq3RX.js → docx-zipper-Bwi8bTEB.js} +1 -1
  14. package/dist/super-editor/chunks/{editor-mgoEnsBi.js → editor-Dyj08tpz.js} +684 -150
  15. package/dist/super-editor/chunks/{index-DDZ1ZT8N.js → index-BFesQTtm.js} +1 -1
  16. package/dist/super-editor/chunks/{toolbar-DULgxvjl.js → toolbar-DRFf1nRv.js} +2 -2
  17. package/dist/super-editor/converter.es.js +1 -1
  18. package/dist/super-editor/docx-zipper.es.js +2 -2
  19. package/dist/super-editor/editor.es.js +3 -3
  20. package/dist/super-editor/file-zipper.es.js +1 -1
  21. package/dist/super-editor/style.css +6 -6
  22. package/dist/super-editor/super-editor.es.js +41 -17
  23. package/dist/super-editor/toolbar.es.js +2 -2
  24. package/dist/super-editor.cjs +1 -1
  25. package/dist/super-editor.es.js +1 -1
  26. package/dist/superdoc.cjs +2 -2
  27. package/dist/superdoc.es.js +2 -2
  28. package/dist/superdoc.umd.js +689 -138
  29. package/dist/superdoc.umd.js.map +1 -1
  30. package/package.json +1 -1
@@ -12,8 +12,8 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
12
12
  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, hideDimmingOverlay_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;
13
13
  import * as Y from "yjs";
14
14
  import { UndoManager, Item as Item$1, ContentType, Text as Text$1, XmlElement, encodeStateAsUpdate } from "yjs";
15
- import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$2, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as htmlHandler, E as ReplaceStep, G as twipsToInches, H as inchesToTwips, I as ptToTwips, J as getResolvedParagraphProperties, K as linesToTwips, L as changeListLevel, O as findParentNode, Q as isList, U as updateNumberingProperties, V as ListHelpers, W as isMacOS, X as isIOS, Y as getSchemaTypeByName, Z as inputRulesPlugin, _ as TrackDeleteMarkName$1, $ as TrackInsertMarkName$1, a0 as v4, a1 as TrackFormatMarkName$1, a2 as comments_module_events, a3 as findMark, a4 as objectIncludes, a5 as AddMarkStep, a6 as RemoveMarkStep, a7 as twipsToLines, a8 as pixelsToTwips, a9 as helpers, aa as posToDOMRect, ab as CommandService, ac as SuperConverter, ad as createDocument, ae as createDocFromMarkdown, af as createDocFromHTML, ag as EditorState, ah as isActive, ai as unflattenListsInHtml, aj as SelectionRange, ak as Transform, al as resolveParagraphProperties, am as _getReferencedTableStyles, an as parseSizeUnit, ao as minMax, ap as updateDOMAttributes, aq as findChildren$5, ar as generateRandomSigned32BitIntStrId, as as decodeRPrFromMarks, at as calculateResolvedParagraphProperties, au as resolveRunProperties, av as encodeCSSFromPPr, aw as twipsToPixels$2, ax as encodeCSSFromRPr, ay as generateOrderedListIndex, az as docxNumberingHelpers, aA as InputRule, aB as convertSizeToCSS, aC as findParentNodeClosestToPos, aD as isInTable$1, aE as generateDocxRandomId, aF as insertNewRelationship, aG as inchesToPixels, aH as kebabCase, aI as getUnderlineCssString } from "./converter-VYPiNbpo.js";
16
- import { D as DocxZipper } from "./docx-zipper-D8Tzq3RX.js";
15
+ import { P as PluginKey, a as Plugin, M as Mapping, N as NodeSelection, S as Selection, T as TextSelection, b as Slice, D as DOMSerializer, F as Fragment, c as DOMParser$1, d as Mark$1, e as dropPoint, A as AllSelection, p as process$1, B as Buffer2, f as callOrGet, g as getExtensionConfigField, h as getMarkType, i as getMarksFromSelection, j as getNodeType, k as getSchemaTypeNameByName, l as Schema$2, m as cleanSchemaItem, n as canSplit, o as defaultBlockAt$1, q as liftTarget, r as canJoin, s as joinPoint, t as replaceStep$1, R as ReplaceAroundStep$1, u as isTextSelection, v as getMarkRange, w as isMarkActive, x as isNodeActive, y as deleteProps, z as processContent, C as htmlHandler, E as ReplaceStep, G as twipsToInches, H as inchesToTwips, I as ptToTwips, J as getResolvedParagraphProperties, K as linesToTwips, L as changeListLevel, O as findParentNode, Q as isList, U as updateNumberingProperties, V as ListHelpers, W as isMacOS, X as isIOS, Y as getSchemaTypeByName, Z as inputRulesPlugin, _ as TrackDeleteMarkName$1, $ as TrackInsertMarkName$1, a0 as v4, a1 as TrackFormatMarkName$1, a2 as comments_module_events, a3 as findMark, a4 as objectIncludes, a5 as AddMarkStep, a6 as RemoveMarkStep, a7 as twipsToLines, a8 as pixelsToTwips, a9 as helpers, aa as posToDOMRect, ab as CommandService, ac as SuperConverter, ad as createDocument, ae as createDocFromMarkdown, af as createDocFromHTML, ag as EditorState, ah as isActive, ai as unflattenListsInHtml, aj as SelectionRange, ak as Transform, al as resolveParagraphProperties, am as _getReferencedTableStyles, an as parseSizeUnit, ao as minMax, ap as updateDOMAttributes, aq as findChildren$5, ar as generateRandomSigned32BitIntStrId, as as decodeRPrFromMarks, at as calculateResolvedParagraphProperties, au as resolveRunProperties, av as encodeCSSFromPPr, aw as twipsToPixels$2, ax as encodeCSSFromRPr, ay as generateOrderedListIndex, az as docxNumberingHelpers, aA as InputRule, aB as convertSizeToCSS, aC as findParentNodeClosestToPos, aD as isInTable$1, aE as generateDocxRandomId, aF as insertNewRelationship, aG as inchesToPixels, aH as kebabCase, aI as getUnderlineCssString } from "./converter-BhELnOP5.js";
16
+ import { D as DocxZipper } from "./docx-zipper-Bwi8bTEB.js";
17
17
  import { ref, computed, createElementBlock, openBlock, withModifiers, Fragment as Fragment$1, renderList, normalizeClass, createCommentVNode, toDisplayString, createElementVNode, createApp } from "vue";
18
18
  var GOOD_LEAF_SIZE = 200;
19
19
  var RopeSequence = function RopeSequence2() {
@@ -14815,7 +14815,7 @@ const isHeadless = (editor) => {
14815
14815
  const shouldSkipNodeView = (editor) => {
14816
14816
  return isHeadless(editor);
14817
14817
  };
14818
- const summaryVersion = "1.0.2";
14818
+ const summaryVersion = "1.0.3";
14819
14819
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
14820
14820
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
14821
14821
  function mapAttributes(attrs) {
@@ -15607,7 +15607,7 @@ const _Editor = class _Editor extends EventEmitter {
15607
15607
  { default: remarkStringify },
15608
15608
  { default: remarkGfm }
15609
15609
  ] = await Promise.all([
15610
- import("./index-DDZ1ZT8N.js"),
15610
+ import("./index-BFesQTtm.js"),
15611
15611
  import("./index-DRCvimau.js"),
15612
15612
  import("./index-C_x_N6Uh.js"),
15613
15613
  import("./index-D_sWOSiG.js"),
@@ -15812,7 +15812,7 @@ const _Editor = class _Editor extends EventEmitter {
15812
15812
  * Process collaboration migrations
15813
15813
  */
15814
15814
  processCollaborationMigrations() {
15815
- console.debug("[checkVersionMigrations] Current editor version", "1.0.2");
15815
+ console.debug("[checkVersionMigrations] Current editor version", "1.0.3");
15816
15816
  if (!this.options.ydoc) return;
15817
15817
  const metaMap = this.options.ydoc.getMap("meta");
15818
15818
  let docVersion = metaMap.get("version");
@@ -23152,7 +23152,7 @@ function isMinimalWordLayout(value) {
23152
23152
  return true;
23153
23153
  }
23154
23154
  const LIST_MARKER_GAP$2 = 8;
23155
- const DEFAULT_TAB_INTERVAL_PX$1 = 48;
23155
+ const DEFAULT_TAB_INTERVAL_PX$2 = 48;
23156
23156
  const DEFAULT_PAGE_HEIGHT_PX = 1056;
23157
23157
  const DEFAULT_VIRTUALIZED_PAGE_GAP$1 = 72;
23158
23158
  const COMMENT_EXTERNAL_COLOR = "#B1124B";
@@ -24079,6 +24079,7 @@ const _DomPainter = class _DomPainter {
24079
24079
  const block = lookup.block;
24080
24080
  const measure = lookup.measure;
24081
24081
  const wordLayout = isMinimalWordLayout(block.attrs?.wordLayout) ? block.attrs.wordLayout : void 0;
24082
+ const alignment = block.attrs?.alignment;
24082
24083
  const fragmentEl = this.doc.createElement("div");
24083
24084
  fragmentEl.classList.add(CLASS_NAMES$1.fragment);
24084
24085
  const isTocEntry = block.attrs?.isTocEntry;
@@ -24157,7 +24158,7 @@ const _DomPainter = class _DomPainter {
24157
24158
  const textStart = paraIndentLeft + firstLine;
24158
24159
  tabWidth = textStart - currentPos;
24159
24160
  if (tabWidth <= 0) {
24160
- tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
24161
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
24161
24162
  } else if (tabWidth < LIST_MARKER_GAP$2) {
24162
24163
  tabWidth = LIST_MARKER_GAP$2;
24163
24164
  }
@@ -24184,6 +24185,21 @@ const _DomPainter = class _DomPainter {
24184
24185
  let availableWidthOverride = line.maxWidth != null ? Math.min(line.maxWidth, fallbackAvailableWidth) : fallbackAvailableWidth;
24185
24186
  if (index2 === 0 && listFirstLineMarkerTabWidth != null) {
24186
24187
  availableWidthOverride = fragment.width - listFirstLineMarkerTabWidth - Math.max(0, paraIndentRight);
24188
+ if (alignment === "justify" || alignment === "both") {
24189
+ console.log(
24190
+ "[justify-debug][painter-firstline-available]",
24191
+ JSON.stringify({
24192
+ blockId: block.id,
24193
+ fragmentWidth: fragment.width,
24194
+ markerTabWidth: listFirstLineMarkerTabWidth,
24195
+ paraIndentRight,
24196
+ availableWidthOverride,
24197
+ lineMaxWidth: line.maxWidth ?? null,
24198
+ lineWidth: line.width,
24199
+ lineNaturalWidth: line.naturalWidth ?? null
24200
+ })
24201
+ );
24202
+ }
24187
24203
  }
24188
24204
  const isLastLineOfFragment = index2 === lines.length - 1;
24189
24205
  const isLastLineOfParagraph = isLastLineOfFragment && !fragment.continuesOnNext;
@@ -24309,7 +24325,7 @@ const _DomPainter = class _DomPainter {
24309
24325
  const textStart = paraIndentLeft + firstLine;
24310
24326
  tabWidth = textStart - currentPos;
24311
24327
  if (tabWidth <= 0) {
24312
- tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
24328
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$2 - currentPos % DEFAULT_TAB_INTERVAL_PX$2;
24313
24329
  } else if (tabWidth < LIST_MARKER_GAP$2) {
24314
24330
  tabWidth = LIST_MARKER_GAP$2;
24315
24331
  }
@@ -25843,6 +25859,23 @@ const _DomPainter = class _DomPainter {
25843
25859
  if (spacingPerSpace !== 0) {
25844
25860
  el.style.wordSpacing = `${spacingPerSpace}px`;
25845
25861
  }
25862
+ if (justifyShouldApply && spacingPerSpace < 0) {
25863
+ console.log(
25864
+ "[justify-debug][painter-wordspacing-negative]",
25865
+ JSON.stringify({
25866
+ blockId: block.id,
25867
+ lineIndex: lineIndex ?? null,
25868
+ alignment: alignment ?? null,
25869
+ availableWidth,
25870
+ lineWidth,
25871
+ lineMaxWidth: line.maxWidth ?? null,
25872
+ lineNaturalWidth: line.naturalWidth ?? null,
25873
+ spaceCount,
25874
+ hasExplicitPositioning: Boolean(hasExplicitPositioning),
25875
+ skipJustify: Boolean(skipJustify)
25876
+ })
25877
+ );
25878
+ }
25846
25879
  if (hasExplicitPositioning && line.segments) {
25847
25880
  const paraIndent = block.attrs?.indent;
25848
25881
  const indentLeft = paraIndent?.left ?? 0;
@@ -28036,6 +28069,28 @@ let measurementCtx = null;
28036
28069
  const TAB_CHAR_LENGTH = 1;
28037
28070
  const SPACE_CHARS = SPACE_CHARS$1;
28038
28071
  const isTabRun$1 = (run) => run?.kind === "tab";
28072
+ const isWordChar$3 = (char) => {
28073
+ if (!char) return false;
28074
+ const code = char.charCodeAt(0);
28075
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
28076
+ };
28077
+ const capitalizeText$2 = (text) => {
28078
+ if (!text) return text;
28079
+ let result = "";
28080
+ for (let i = 0; i < text.length; i += 1) {
28081
+ const prevChar = i > 0 ? text[i - 1] : "";
28082
+ const ch = text[i];
28083
+ result += isWordChar$3(ch) && !isWordChar$3(prevChar) ? ch.toUpperCase() : ch;
28084
+ }
28085
+ return result;
28086
+ };
28087
+ const applyTextTransform$2 = (text, transform) => {
28088
+ if (!text || !transform || transform === "none") return text;
28089
+ if (transform === "uppercase") return text.toUpperCase();
28090
+ if (transform === "lowercase") return text.toLowerCase();
28091
+ if (transform === "capitalize") return capitalizeText$2(text);
28092
+ return text;
28093
+ };
28039
28094
  function getMeasurementContext() {
28040
28095
  if (measurementCtx) return measurementCtx;
28041
28096
  if (typeof document === "undefined") {
@@ -28211,17 +28266,18 @@ function measureCharacterX(block, line, charOffset, availableWidthOverride, alig
28211
28266
  }
28212
28267
  const text = "src" in run || run.kind === "lineBreak" || run.kind === "break" || run.kind === "fieldAnnotation" ? "" : run.text ?? "";
28213
28268
  const runLength = text.length;
28269
+ const displayText = applyTextTransform$2(text, run.textTransform);
28214
28270
  if (currentCharOffset + runLength >= charOffset) {
28215
28271
  const offsetInRun = charOffset - currentCharOffset;
28216
28272
  ctx2.font = getRunFontString(run);
28217
- const textUpToTarget = text.slice(0, offsetInRun);
28273
+ const textUpToTarget = displayText.slice(0, offsetInRun);
28218
28274
  const measured2 = ctx2.measureText(textUpToTarget);
28219
28275
  const spacingWidth = computeLetterSpacingWidth(run, offsetInRun, runLength);
28220
- const spacesInPortion = justify.extraPerSpace !== 0 ? countSpaces(textUpToTarget) : 0;
28276
+ const spacesInPortion = justify.extraPerSpace !== 0 ? countSpaces(text.slice(0, offsetInRun)) : 0;
28221
28277
  return alignmentOffset + currentX + measured2.width + spacingWidth + justify.extraPerSpace * (spaceTally + spacesInPortion);
28222
28278
  }
28223
28279
  ctx2.font = getRunFontString(run);
28224
- const measured = ctx2.measureText(text);
28280
+ const measured = ctx2.measureText(displayText);
28225
28281
  const runLetterSpacing = computeLetterSpacingWidth(run, runLength, runLength);
28226
28282
  const spacesInRun = justify.extraPerSpace !== 0 ? countSpaces(text) : 0;
28227
28283
  currentX += measured.width + runLetterSpacing + justify.extraPerSpace * spacesInRun;
@@ -28260,8 +28316,9 @@ function measureCharacterXSegmentBased(block, line, charOffset, ctx2) {
28260
28316
  return segmentBaseX + (offsetInSegment >= segmentChars ? segment.width ?? 0 : 0);
28261
28317
  }
28262
28318
  const text = run.text ?? "";
28263
- const segmentText = text.slice(segment.fromChar, segment.toChar);
28264
- const textUpToTarget = segmentText.slice(0, offsetInSegment);
28319
+ const displayText = applyTextTransform$2(text, run.textTransform);
28320
+ const displaySegmentText = displayText.slice(segment.fromChar, segment.toChar);
28321
+ const textUpToTarget = displaySegmentText.slice(0, offsetInSegment);
28265
28322
  ctx2.font = getRunFontString(run);
28266
28323
  const measured = ctx2.measureText(textUpToTarget);
28267
28324
  const spacingWidth = computeLetterSpacingWidth(run, offsetInSegment, segmentChars);
@@ -28357,12 +28414,13 @@ function findCharacterAtX(block, line, x, pmStart, availableWidthOverride, align
28357
28414
  }
28358
28415
  const text = "src" in run || run.kind === "lineBreak" || run.kind === "break" || run.kind === "fieldAnnotation" ? "" : run.text ?? "";
28359
28416
  const runLength = text.length;
28417
+ const displayText = applyTextTransform$2(text, run.textTransform);
28360
28418
  if (runLength === 0) continue;
28361
28419
  ctx2.font = getRunFontString(run);
28362
28420
  for (let i = 0; i <= runLength; i++) {
28363
- const textUpToChar = text.slice(0, i);
28421
+ const textUpToChar = displayText.slice(0, i);
28364
28422
  const measured2 = ctx2.measureText(textUpToChar);
28365
- const spacesInPortion = justify.extraPerSpace > 0 ? countSpaces(textUpToChar) : 0;
28423
+ const spacesInPortion = justify.extraPerSpace > 0 ? countSpaces(text.slice(0, i)) : 0;
28366
28424
  const charX = currentX + measured2.width + computeLetterSpacingWidth(run, i, runLength) + justify.extraPerSpace * (spaceTally + spacesInPortion);
28367
28425
  if (charX >= safeX) {
28368
28426
  if (i === 0) {
@@ -28372,7 +28430,7 @@ function findCharacterAtX(block, line, x, pmStart, availableWidthOverride, align
28372
28430
  pmPosition: pmPosition3
28373
28431
  };
28374
28432
  }
28375
- const prevText = text.slice(0, i - 1);
28433
+ const prevText = displayText.slice(0, i - 1);
28376
28434
  const prevMeasured = ctx2.measureText(prevText);
28377
28435
  const prevX = currentX + prevMeasured.width + computeLetterSpacingWidth(run, i - 1, runLength);
28378
28436
  const distToPrev = Math.abs(safeX - prevX);
@@ -28385,7 +28443,7 @@ function findCharacterAtX(block, line, x, pmStart, availableWidthOverride, align
28385
28443
  };
28386
28444
  }
28387
28445
  }
28388
- const measured = ctx2.measureText(text);
28446
+ const measured = ctx2.measureText(displayText);
28389
28447
  const runLetterSpacing = computeLetterSpacingWidth(run, runLength, runLength);
28390
28448
  const spacesInRun = justify.extraPerSpace > 0 ? countSpaces(text) : 0;
28391
28449
  currentX += measured.width + runLetterSpacing + justify.extraPerSpace * spacesInRun;
@@ -28816,6 +28874,83 @@ function findCharIndexAtX(textNode, container, targetX) {
28816
28874
  }
28817
28875
  return index2;
28818
28876
  }
28877
+ const LIST_MARKER_GAP$1 = 8;
28878
+ const MIN_MARKER_GUTTER = 24;
28879
+ const DEFAULT_LIST_INDENT_BASE_PX = 24;
28880
+ const DEFAULT_LIST_INDENT_STEP_PX = 24;
28881
+ const DEFAULT_LIST_HANGING_PX$1 = 18;
28882
+ const SPACE_SUFFIX_GAP_PX = 4;
28883
+ const DEFAULT_TAB_INTERVAL_PX$1 = 48;
28884
+ function resolveListTextStartPx(wordLayout, indentLeft, firstLine, hanging, measureMarkerText) {
28885
+ const marker = wordLayout?.marker;
28886
+ if (!marker) {
28887
+ const textStartPx = wordLayout?.firstLineIndentMode === true && typeof wordLayout.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
28888
+ return textStartPx;
28889
+ }
28890
+ const markerBoxWidth = typeof marker.markerBoxWidthPx === "number" && Number.isFinite(marker.markerBoxWidthPx) ? marker.markerBoxWidthPx : 0;
28891
+ let markerTextWidth = typeof marker.glyphWidthPx === "number" && Number.isFinite(marker.glyphWidthPx) ? marker.glyphWidthPx : void 0;
28892
+ if (markerTextWidth == null && marker.markerText) {
28893
+ markerTextWidth = measureMarkerText(marker.markerText, marker);
28894
+ }
28895
+ if (!Number.isFinite(markerTextWidth) || markerTextWidth < 0) {
28896
+ markerTextWidth = markerBoxWidth;
28897
+ }
28898
+ markerTextWidth = Math.max(0, markerTextWidth);
28899
+ let markerStartPos;
28900
+ if (wordLayout?.firstLineIndentMode === true && Number.isFinite(marker.markerX)) {
28901
+ markerStartPos = marker.markerX;
28902
+ } else {
28903
+ markerStartPos = indentLeft - hanging + firstLine;
28904
+ }
28905
+ if (!Number.isFinite(markerStartPos)) {
28906
+ markerStartPos = 0;
28907
+ }
28908
+ const currentPos = markerStartPos + markerTextWidth;
28909
+ const suffix = marker.suffix ?? "tab";
28910
+ if (suffix === "space") {
28911
+ return markerStartPos + markerTextWidth + SPACE_SUFFIX_GAP_PX;
28912
+ }
28913
+ if (suffix === "nothing") {
28914
+ return markerStartPos + markerTextWidth;
28915
+ }
28916
+ const markerJustification = marker.justification ?? "left";
28917
+ if (markerJustification !== "left") {
28918
+ const gutterWidth = typeof marker.gutterWidthPx === "number" && Number.isFinite(marker.gutterWidthPx) && marker.gutterWidthPx > 0 ? marker.gutterWidthPx : LIST_MARKER_GAP$1;
28919
+ return markerStartPos + markerTextWidth + Math.max(gutterWidth, LIST_MARKER_GAP$1);
28920
+ }
28921
+ if (wordLayout?.firstLineIndentMode === true) {
28922
+ let targetTabStop;
28923
+ if (Array.isArray(wordLayout.tabsPx)) {
28924
+ for (const tab of wordLayout.tabsPx) {
28925
+ if (typeof tab === "number" && tab > currentPos) {
28926
+ targetTabStop = tab;
28927
+ break;
28928
+ }
28929
+ }
28930
+ }
28931
+ const textStartTarget = typeof marker.textStartX === "number" && Number.isFinite(marker.textStartX) ? marker.textStartX : wordLayout.textStartPx;
28932
+ let tabWidth2;
28933
+ if (targetTabStop !== void 0) {
28934
+ tabWidth2 = targetTabStop - currentPos;
28935
+ } else if (textStartTarget !== void 0 && Number.isFinite(textStartTarget) && textStartTarget > currentPos) {
28936
+ tabWidth2 = textStartTarget - currentPos;
28937
+ } else {
28938
+ tabWidth2 = LIST_MARKER_GAP$1;
28939
+ }
28940
+ if (tabWidth2 < LIST_MARKER_GAP$1) {
28941
+ tabWidth2 = LIST_MARKER_GAP$1;
28942
+ }
28943
+ return markerStartPos + markerTextWidth + tabWidth2;
28944
+ }
28945
+ const textStart = indentLeft + firstLine;
28946
+ let tabWidth = textStart - currentPos;
28947
+ if (tabWidth <= 0) {
28948
+ tabWidth = DEFAULT_TAB_INTERVAL_PX$1 - currentPos % DEFAULT_TAB_INTERVAL_PX$1;
28949
+ } else if (tabWidth < LIST_MARKER_GAP$1) {
28950
+ tabWidth = LIST_MARKER_GAP$1;
28951
+ }
28952
+ return markerStartPos + markerTextWidth + tabWidth;
28953
+ }
28819
28954
  function getWordLayoutConfig(block) {
28820
28955
  if (!block || block.kind !== "paragraph") {
28821
28956
  return void 0;
@@ -28848,9 +28983,16 @@ function calculateTextStartIndent(params2) {
28848
28983
  const isFirstLineIndentMode = wordLayout?.firstLineIndentMode === true;
28849
28984
  let indentAdjust = paraIndentLeft;
28850
28985
  if (isListItem2 && isFirstLine && isFirstLineIndentMode) {
28986
+ const resolvedTextStart = resolveListTextStartPx(
28987
+ wordLayout,
28988
+ paraIndentLeft,
28989
+ Math.max(firstLineIndent, 0),
28990
+ Math.max(hangingIndent, 0),
28991
+ () => markerWidth
28992
+ // Use provided markerWidth since we don't have canvas access here
28993
+ );
28851
28994
  const textStartFallback = paraIndentLeft + Math.max(firstLineIndent, 0) + markerWidth;
28852
- const markerTextStartX = wordLayout?.marker?.textStartX;
28853
- indentAdjust = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : textStartFallback;
28995
+ indentAdjust = typeof resolvedTextStart === "number" && Number.isFinite(resolvedTextStart) ? resolvedTextStart : textStartFallback;
28854
28996
  } else if (isFirstLine && !isListItem2) {
28855
28997
  indentAdjust += firstLineOffset;
28856
28998
  }
@@ -29006,7 +29148,10 @@ function getHeaderFooterTypeForSection(pageNumber, sectionIndex, identifier, opt
29006
29148
  }
29007
29149
  function createFloatingObjectManager(columns, margins, pageWidth) {
29008
29150
  const zones = [];
29009
- const marginLeft = Math.max(0, margins?.left ?? 0);
29151
+ let currentColumns = columns;
29152
+ let currentMargins = margins;
29153
+ let currentPageWidth = pageWidth;
29154
+ let marginLeft = Math.max(0, currentMargins?.left ?? 0);
29010
29155
  return {
29011
29156
  registerDrawing(drawingBlock, measure, anchorY, columnIndex, pageNumber) {
29012
29157
  if (!drawingBlock.anchor?.isAnchored) {
@@ -29019,7 +29164,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
29019
29164
  }
29020
29165
  const objectWidth = measure.width ?? 0;
29021
29166
  const objectHeight = measure.height ?? 0;
29022
- const x = computeAnchorX(anchor, columnIndex, columns, objectWidth, margins, pageWidth);
29167
+ const x = computeAnchorX(anchor, columnIndex, currentColumns, objectWidth, currentMargins, currentPageWidth);
29023
29168
  const y = anchorY + (anchor.offsetV ?? 0);
29024
29169
  const zone = {
29025
29170
  imageBlockId: drawingBlock.id,
@@ -29053,7 +29198,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
29053
29198
  }
29054
29199
  const tableWidth = measure.totalWidth ?? 0;
29055
29200
  const tableHeight = measure.totalHeight ?? 0;
29056
- const x = computeTableAnchorX(anchor, columnIndex, columns, tableWidth, margins, pageWidth);
29201
+ const x = computeTableAnchorX(anchor, columnIndex, currentColumns, tableWidth, currentMargins, currentPageWidth);
29057
29202
  const y = anchorY + (anchor.offsetV ?? 0);
29058
29203
  const zone = {
29059
29204
  imageBlockId: tableBlock.id,
@@ -29101,7 +29246,7 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
29101
29246
  }
29102
29247
  const leftFloats = [];
29103
29248
  const rightFloats = [];
29104
- const columnOrigin = marginLeft + columnIndex * (columns.width + columns.gap);
29249
+ const columnOrigin = marginLeft + columnIndex * (currentColumns.width + currentColumns.gap);
29105
29250
  const columnCenter = columnOrigin + baseWidth / 2;
29106
29251
  for (const zone of wrappingZones) {
29107
29252
  if (zone.wrapMode === "left") {
@@ -29140,6 +29285,22 @@ function createFloatingObjectManager(columns, margins, pageWidth) {
29140
29285
  },
29141
29286
  clear() {
29142
29287
  zones.length = 0;
29288
+ },
29289
+ /**
29290
+ * Update layout context used for positioning and wrapping (columns, margins, page width).
29291
+ * This method should be called when the layout configuration changes (e.g., section breaks,
29292
+ * column changes, page size changes) to ensure floating objects are positioned and wrapped
29293
+ * correctly relative to the new layout boundaries.
29294
+ *
29295
+ * @param nextColumns - Column layout configuration (width, gap, count)
29296
+ * @param nextMargins - Optional page margins (left, right) in pixels
29297
+ * @param nextPageWidth - Optional total page width in pixels
29298
+ */
29299
+ setLayoutContext(nextColumns, nextMargins, nextPageWidth) {
29300
+ currentColumns = nextColumns;
29301
+ currentMargins = nextMargins;
29302
+ currentPageWidth = nextPageWidth;
29303
+ marginLeft = Math.max(0, currentMargins?.left ?? 0);
29143
29304
  }
29144
29305
  };
29145
29306
  }
@@ -29239,7 +29400,14 @@ function computeNextSectionPropsAtBreak(blocks) {
29239
29400
  const props = {};
29240
29401
  if (source.kind !== "sectionBreak") return props;
29241
29402
  if (source.margins) {
29242
- props.margins = { header: source.margins.header, footer: source.margins.footer };
29403
+ props.margins = {
29404
+ header: source.margins.header,
29405
+ footer: source.margins.footer,
29406
+ top: source.margins.top,
29407
+ right: source.margins.right,
29408
+ bottom: source.margins.bottom,
29409
+ left: source.margins.left
29410
+ };
29243
29411
  }
29244
29412
  if (source.pageSize) {
29245
29413
  props.pageSize = { w: source.pageSize.w, h: source.pageSize.h };
@@ -29287,20 +29455,36 @@ function scheduleSectionBreak(block, state, baseMargins, maxHeaderContentHeight
29287
29455
  next.activeOrientation = block.orientation;
29288
29456
  next.pendingOrientation = null;
29289
29457
  }
29458
+ const headerDistance = typeof block.margins?.header === "number" ? Math.max(0, block.margins.header) : next.activeHeaderDistance;
29459
+ const footerDistance = typeof block.margins?.footer === "number" ? Math.max(0, block.margins.footer) : next.activeFooterDistance;
29460
+ const sectionTop = typeof block.margins?.top === "number" ? Math.max(0, block.margins.top) : baseMargins.top;
29461
+ const sectionBottom = typeof block.margins?.bottom === "number" ? Math.max(0, block.margins.bottom) : baseMargins.bottom;
29290
29462
  if (block.margins?.header !== void 0) {
29291
- const headerDistance = Math.max(0, block.margins.header);
29292
29463
  next.activeHeaderDistance = headerDistance;
29293
29464
  next.pendingHeaderDistance = headerDistance;
29294
- next.activeTopMargin = calcRequiredTopMargin(headerDistance, baseMargins.top);
29295
- next.pendingTopMargin = next.activeTopMargin;
29296
29465
  }
29297
29466
  if (block.margins?.footer !== void 0) {
29298
- const footerDistance = Math.max(0, block.margins.footer);
29299
29467
  next.activeFooterDistance = footerDistance;
29300
29468
  next.pendingFooterDistance = footerDistance;
29301
- next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, baseMargins.bottom);
29469
+ }
29470
+ if (block.margins?.top !== void 0 || block.margins?.header !== void 0) {
29471
+ next.activeTopMargin = calcRequiredTopMargin(headerDistance, sectionTop);
29472
+ next.pendingTopMargin = next.activeTopMargin;
29473
+ }
29474
+ if (block.margins?.bottom !== void 0 || block.margins?.footer !== void 0) {
29475
+ next.activeBottomMargin = calcRequiredBottomMargin(footerDistance, sectionBottom);
29302
29476
  next.pendingBottomMargin = next.activeBottomMargin;
29303
29477
  }
29478
+ if (block.margins?.left !== void 0) {
29479
+ const leftMargin = Math.max(0, block.margins.left);
29480
+ next.activeLeftMargin = leftMargin;
29481
+ next.pendingLeftMargin = leftMargin;
29482
+ }
29483
+ if (block.margins?.right !== void 0) {
29484
+ const rightMargin = Math.max(0, block.margins.right);
29485
+ next.activeRightMargin = rightMargin;
29486
+ next.pendingRightMargin = rightMargin;
29487
+ }
29304
29488
  if (block.columns) {
29305
29489
  next.activeColumns = { count: block.columns.count, gap: block.columns.gap };
29306
29490
  next.pendingColumns = null;
@@ -29309,26 +29493,42 @@ function scheduleSectionBreak(block, state, baseMargins, maxHeaderContentHeight
29309
29493
  }
29310
29494
  const headerPx = block.margins?.header;
29311
29495
  const footerPx = block.margins?.footer;
29496
+ const topPx = block.margins?.top;
29497
+ const bottomPx = block.margins?.bottom;
29312
29498
  const nextTop = next.pendingTopMargin ?? next.activeTopMargin;
29313
29499
  const nextBottom = next.pendingBottomMargin ?? next.activeBottomMargin;
29500
+ const nextLeft = next.pendingLeftMargin ?? next.activeLeftMargin;
29501
+ const nextRight = next.pendingRightMargin ?? next.activeRightMargin;
29314
29502
  const nextHeader = next.pendingHeaderDistance ?? next.activeHeaderDistance;
29315
29503
  const nextFooter = next.pendingFooterDistance ?? next.activeFooterDistance;
29316
- if (typeof headerPx === "number") {
29317
- const newHeaderDist = Math.max(0, headerPx);
29504
+ if (typeof headerPx === "number" || typeof topPx === "number") {
29505
+ const newHeaderDist = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
29506
+ const sectionTop = typeof topPx === "number" ? Math.max(0, topPx) : baseMargins.top;
29318
29507
  next.pendingHeaderDistance = newHeaderDist;
29319
- next.pendingTopMargin = calcRequiredTopMargin(newHeaderDist, baseMargins.top);
29508
+ next.pendingTopMargin = calcRequiredTopMargin(newHeaderDist, sectionTop);
29320
29509
  } else {
29321
29510
  next.pendingTopMargin = nextTop;
29322
29511
  next.pendingHeaderDistance = nextHeader;
29323
29512
  }
29324
- if (typeof footerPx === "number") {
29325
- const newFooterDist = Math.max(0, footerPx);
29513
+ if (typeof footerPx === "number" || typeof bottomPx === "number") {
29514
+ const newFooterDist = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
29515
+ const sectionBottom = typeof bottomPx === "number" ? Math.max(0, bottomPx) : baseMargins.bottom;
29326
29516
  next.pendingFooterDistance = newFooterDist;
29327
- next.pendingBottomMargin = calcRequiredBottomMargin(newFooterDist, baseMargins.bottom);
29517
+ next.pendingBottomMargin = calcRequiredBottomMargin(newFooterDist, sectionBottom);
29328
29518
  } else {
29329
29519
  next.pendingBottomMargin = nextBottom;
29330
29520
  next.pendingFooterDistance = nextFooter;
29331
29521
  }
29522
+ if (typeof block.margins?.left === "number") {
29523
+ next.pendingLeftMargin = Math.max(0, block.margins.left);
29524
+ } else {
29525
+ next.pendingLeftMargin = nextLeft;
29526
+ }
29527
+ if (typeof block.margins?.right === "number") {
29528
+ next.pendingRightMargin = Math.max(0, block.margins.right);
29529
+ } else {
29530
+ next.pendingRightMargin = nextRight;
29531
+ }
29332
29532
  if (block.pageSize) {
29333
29533
  next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
29334
29534
  }
@@ -29388,6 +29588,12 @@ function applyPendingToActive(state) {
29388
29588
  if (next.pendingBottomMargin != null) {
29389
29589
  next.activeBottomMargin = next.pendingBottomMargin;
29390
29590
  }
29591
+ if (next.pendingLeftMargin != null) {
29592
+ next.activeLeftMargin = next.pendingLeftMargin;
29593
+ }
29594
+ if (next.pendingRightMargin != null) {
29595
+ next.activeRightMargin = next.pendingRightMargin;
29596
+ }
29391
29597
  if (next.pendingHeaderDistance != null) {
29392
29598
  next.activeHeaderDistance = next.pendingHeaderDistance;
29393
29599
  }
@@ -29405,6 +29611,8 @@ function applyPendingToActive(state) {
29405
29611
  }
29406
29612
  next.pendingTopMargin = null;
29407
29613
  next.pendingBottomMargin = null;
29614
+ next.pendingLeftMargin = null;
29615
+ next.pendingRightMargin = null;
29408
29616
  next.pendingHeaderDistance = null;
29409
29617
  next.pendingFooterDistance = null;
29410
29618
  next.pendingPageSize = null;
@@ -29633,7 +29841,8 @@ function layoutParagraphBlock(ctx2, anchors) {
29633
29841
  if (typeof remeasureParagraph2 === "function" && typeof measurementWidth === "number" && measurementWidth > remeasureWidth) {
29634
29842
  const firstLineIndent = calculateFirstLineIndent(block, measure);
29635
29843
  const newMeasure = remeasureParagraph2(block, columnWidth, firstLineIndent);
29636
- lines = normalizeLines(newMeasure);
29844
+ const newLines = normalizeLines(newMeasure);
29845
+ lines = newLines;
29637
29846
  didRemeasureForColumnWidth = true;
29638
29847
  }
29639
29848
  let fromLine = 0;
@@ -29715,7 +29924,8 @@ function layoutParagraphBlock(ctx2, anchors) {
29715
29924
  if (narrowestRemeasureWidth < remeasureWidth) {
29716
29925
  const firstLineIndent = calculateFirstLineIndent(block, measure);
29717
29926
  const newMeasure = remeasureParagraph2(block, narrowestRemeasureWidth, firstLineIndent);
29718
- lines = normalizeLines(newMeasure);
29927
+ const newLines = normalizeLines(newMeasure);
29928
+ lines = newLines;
29719
29929
  didRemeasureForFloats = true;
29720
29930
  }
29721
29931
  }
@@ -30059,6 +30269,94 @@ function getCellPadding(cellIdx, blockRow) {
30059
30269
  function getCellTotalLines(cell) {
30060
30270
  return getCellLines(cell).length;
30061
30271
  }
30272
+ function mergePmRange(target, range) {
30273
+ if (typeof range.pmStart === "number") {
30274
+ target.pmStart = target.pmStart == null ? range.pmStart : Math.min(target.pmStart, range.pmStart);
30275
+ }
30276
+ if (typeof range.pmEnd === "number") {
30277
+ target.pmEnd = target.pmEnd == null ? range.pmEnd : Math.max(target.pmEnd, range.pmEnd);
30278
+ }
30279
+ }
30280
+ function computeCellPmRange(cell, cellMeasure, fromLine, toLine) {
30281
+ const range = {};
30282
+ if (!cell || !cellMeasure) return range;
30283
+ const cellBlocks = cell.blocks ?? (cell.paragraph ? [cell.paragraph] : []);
30284
+ const blockMeasures = cellMeasure.blocks ?? (cellMeasure.paragraph ? [cellMeasure.paragraph] : []);
30285
+ const maxBlocks = Math.min(cellBlocks.length, blockMeasures.length);
30286
+ let cumulativeLineCount = 0;
30287
+ for (let i = 0; i < maxBlocks; i++) {
30288
+ const block = cellBlocks[i];
30289
+ const blockMeasure = blockMeasures[i];
30290
+ if (blockMeasure.kind === "paragraph" && block?.kind === "paragraph") {
30291
+ const paraMeasure = blockMeasure;
30292
+ const lines = paraMeasure.lines;
30293
+ const blockLineCount = lines?.length ?? 0;
30294
+ const blockStartGlobal = cumulativeLineCount;
30295
+ const blockEndGlobal = cumulativeLineCount + blockLineCount;
30296
+ const localFrom = Math.max(fromLine, blockStartGlobal) - blockStartGlobal;
30297
+ const localTo = Math.min(toLine, blockEndGlobal) - blockStartGlobal;
30298
+ if (lines && lines.length > 0 && localFrom < localTo) {
30299
+ mergePmRange(range, computeFragmentPmRange(block, lines, localFrom, localTo));
30300
+ } else {
30301
+ mergePmRange(range, extractBlockPmRange(block));
30302
+ }
30303
+ cumulativeLineCount += blockLineCount;
30304
+ continue;
30305
+ }
30306
+ mergePmRange(range, extractBlockPmRange(block));
30307
+ }
30308
+ return range;
30309
+ }
30310
+ function computeTableFragmentPmRange(block, measure, fromRow, toRow, partialRow) {
30311
+ const range = {};
30312
+ for (let rowIndex = fromRow; rowIndex < toRow; rowIndex++) {
30313
+ const row = block.rows[rowIndex];
30314
+ const rowMeasure = measure.rows[rowIndex];
30315
+ if (!row || !rowMeasure) continue;
30316
+ const isPartial = partialRow?.rowIndex === rowIndex;
30317
+ const cellCount = Math.min(row.cells.length, rowMeasure.cells.length);
30318
+ for (let cellIndex = 0; cellIndex < cellCount; cellIndex++) {
30319
+ const cell = row.cells[cellIndex];
30320
+ const cellMeasure = rowMeasure.cells[cellIndex];
30321
+ if (!cell || !cellMeasure) continue;
30322
+ const totalLines = getCellTotalLines(cellMeasure);
30323
+ let fromLine = 0;
30324
+ let toLine = totalLines;
30325
+ if (isPartial) {
30326
+ const hasValidFromLineByCell = partialRow?.fromLineByCell && cellIndex < partialRow.fromLineByCell.length;
30327
+ const hasValidToLineByCell = partialRow?.toLineByCell && cellIndex < partialRow.toLineByCell.length;
30328
+ if (hasValidFromLineByCell) {
30329
+ const rawFrom = partialRow.fromLineByCell[cellIndex];
30330
+ if (typeof rawFrom === "number" && rawFrom >= 0) {
30331
+ fromLine = rawFrom;
30332
+ }
30333
+ }
30334
+ if (hasValidToLineByCell) {
30335
+ const rawTo = partialRow.toLineByCell[cellIndex];
30336
+ if (typeof rawTo === "number") {
30337
+ toLine = rawTo === -1 ? totalLines : rawTo;
30338
+ }
30339
+ }
30340
+ }
30341
+ fromLine = Math.max(0, Math.min(fromLine, totalLines));
30342
+ toLine = Math.max(0, Math.min(toLine, totalLines));
30343
+ if (toLine < fromLine) {
30344
+ toLine = fromLine;
30345
+ }
30346
+ mergePmRange(range, computeCellPmRange(cell, cellMeasure, fromLine, toLine));
30347
+ }
30348
+ }
30349
+ return range;
30350
+ }
30351
+ function applyTableFragmentPmRange(fragment, block, measure) {
30352
+ const range = computeTableFragmentPmRange(block, measure, fragment.fromRow, fragment.toRow, fragment.partialRow);
30353
+ if (range.pmStart != null) {
30354
+ fragment.pmStart = range.pmStart;
30355
+ }
30356
+ if (range.pmEnd != null) {
30357
+ fragment.pmEnd = range.pmEnd;
30358
+ }
30359
+ }
30062
30360
  function computePartialRow(rowIndex, blockRow, measure, availableHeight, fromLineByCell) {
30063
30361
  const row = measure.rows[rowIndex];
30064
30362
  if (!row) {
@@ -30203,6 +30501,7 @@ function layoutMonolithicTable(context) {
30203
30501
  height,
30204
30502
  metadata
30205
30503
  };
30504
+ applyTableFragmentPmRange(fragment, context.block, context.measure);
30206
30505
  state.page.fragments.push(fragment);
30207
30506
  state.cursorY += height;
30208
30507
  }
@@ -30281,6 +30580,7 @@ function layoutTableBlock({
30281
30580
  height,
30282
30581
  metadata
30283
30582
  };
30583
+ applyTableFragmentPmRange(fragment, block, measure);
30284
30584
  state.page.fragments.push(fragment);
30285
30585
  state.cursorY += height;
30286
30586
  return;
@@ -30344,6 +30644,7 @@ function layoutTableBlock({
30344
30644
  partialRow: continuationPartialRow,
30345
30645
  metadata: generateFragmentMetadata(measure)
30346
30646
  };
30647
+ applyTableFragmentPmRange(fragment2, block, measure);
30347
30648
  state.page.fragments.push(fragment2);
30348
30649
  state.cursorY += fragmentHeight2;
30349
30650
  }
@@ -30388,6 +30689,7 @@ function layoutTableBlock({
30388
30689
  partialRow: forcedPartialRow,
30389
30690
  metadata: generateFragmentMetadata(measure)
30390
30691
  };
30692
+ applyTableFragmentPmRange(fragment2, block, measure);
30391
30693
  state.page.fragments.push(fragment2);
30392
30694
  state.cursorY += fragmentHeight2;
30393
30695
  pendingPartialRow = forcedPartialRow;
@@ -30423,6 +30725,7 @@ function layoutTableBlock({
30423
30725
  partialRow: partialRow || void 0,
30424
30726
  metadata: generateFragmentMetadata(measure)
30425
30727
  };
30728
+ applyTableFragmentPmRange(fragment, block, measure);
30426
30729
  state.page.fragments.push(fragment);
30427
30730
  state.cursorY += fragmentHeight;
30428
30731
  if (partialRow && !partialRow.isLastPart) {
@@ -30440,7 +30743,7 @@ function createAnchoredTableFragment(block, measure, x, y) {
30440
30743
  columnBoundaries: generateColumnBoundaries(measure),
30441
30744
  coordinateSystem: "fragment"
30442
30745
  };
30443
- return {
30746
+ const fragment = {
30444
30747
  kind: "table",
30445
30748
  blockId: block.id,
30446
30749
  fromRow: 0,
@@ -30451,6 +30754,8 @@ function createAnchoredTableFragment(block, measure, x, y) {
30451
30754
  height: measure.totalHeight ?? 0,
30452
30755
  metadata
30453
30756
  };
30757
+ applyTableFragmentPmRange(fragment, block, measure);
30758
+ return fragment;
30454
30759
  }
30455
30760
  function isPageRelativeAnchor(block) {
30456
30761
  const vRelativeFrom = block.anchor?.vRelativeFrom;
@@ -30872,8 +31177,8 @@ function layoutDocument(blocks, measures, options = {}) {
30872
31177
  header: options.margins?.header ?? options.margins?.top ?? DEFAULT_MARGINS$2.top,
30873
31178
  footer: options.margins?.footer ?? options.margins?.bottom ?? DEFAULT_MARGINS$2.bottom
30874
31179
  };
30875
- const contentWidth = pageSize.w - (margins.left + margins.right);
30876
- if (contentWidth <= 0) {
31180
+ const baseContentWidth = pageSize.w - (margins.left + margins.right);
31181
+ if (baseContentWidth <= 0) {
30877
31182
  throw new Error("layoutDocument: pageSize and margins yield non-positive content area");
30878
31183
  }
30879
31184
  const validateContentHeight = (height) => {
@@ -30903,8 +31208,12 @@ function layoutDocument(blocks, measures, options = {}) {
30903
31208
  const effectiveBottomMargin = maxFooterContentHeight > 0 ? Math.max(margins.bottom, footerDistance + maxFooterContentHeight) : margins.bottom;
30904
31209
  let activeTopMargin = effectiveTopMargin;
30905
31210
  let activeBottomMargin = effectiveBottomMargin;
31211
+ let activeLeftMargin = margins.left;
31212
+ let activeRightMargin = margins.right;
30906
31213
  let pendingTopMargin = null;
30907
31214
  let pendingBottomMargin = null;
31215
+ let pendingLeftMargin = null;
31216
+ let pendingRightMargin = null;
30908
31217
  let activeHeaderDistance = margins.header ?? margins.top;
30909
31218
  let pendingHeaderDistance = null;
30910
31219
  let activeFooterDistance = margins.footer ?? margins.bottom;
@@ -30917,10 +31226,11 @@ function layoutDocument(blocks, measures, options = {}) {
30917
31226
  let pendingOrientation = null;
30918
31227
  let activeVAlign = null;
30919
31228
  let pendingVAlign = null;
31229
+ const paginatorMargins = { left: activeLeftMargin, right: activeRightMargin };
30920
31230
  const floatManager = createFloatingObjectManager(
30921
- normalizeColumns(activeColumns, contentWidth),
30922
- { left: margins.left, right: margins.right },
30923
- pageSize.w
31231
+ normalizeColumns(activeColumns, activePageSize.w - (activeLeftMargin + activeRightMargin)),
31232
+ { left: activeLeftMargin, right: activeRightMargin },
31233
+ activePageSize.w
30924
31234
  );
30925
31235
  const nextSectionPropsAtBreak = computeNextSectionPropsAtBreak(blocks);
30926
31236
  const scheduleSectionBreakCompat = (block, state, baseMargins) => {
@@ -30937,22 +31247,38 @@ function layoutDocument(blocks, measures, options = {}) {
30937
31247
  next.activeOrientation = block.orientation;
30938
31248
  next.pendingOrientation = null;
30939
31249
  }
31250
+ const headerDistance2 = typeof block.margins?.header === "number" ? Math.max(0, block.margins.header) : next.activeHeaderDistance;
31251
+ const footerDistance2 = typeof block.margins?.footer === "number" ? Math.max(0, block.margins.footer) : next.activeFooterDistance;
31252
+ const sectionTop = typeof block.margins?.top === "number" ? Math.max(0, block.margins.top) : baseMargins.top;
31253
+ const sectionBottom = typeof block.margins?.bottom === "number" ? Math.max(0, block.margins.bottom) : baseMargins.bottom;
30940
31254
  if (block.margins?.header !== void 0) {
30941
- const headerDist = Math.max(0, block.margins.header);
30942
- next.activeHeaderDistance = headerDist;
30943
- next.pendingHeaderDistance = headerDist;
30944
- const requiredTop = maxHeaderContentHeight > 0 ? headerDist + maxHeaderContentHeight : headerDist;
30945
- next.activeTopMargin = Math.max(baseMargins.top, requiredTop);
30946
- next.pendingTopMargin = next.activeTopMargin;
31255
+ next.activeHeaderDistance = headerDistance2;
31256
+ next.pendingHeaderDistance = headerDistance2;
30947
31257
  }
30948
31258
  if (block.margins?.footer !== void 0) {
30949
- const footerDistance2 = Math.max(0, block.margins.footer);
30950
31259
  next.activeFooterDistance = footerDistance2;
30951
31260
  next.pendingFooterDistance = footerDistance2;
31261
+ }
31262
+ if (block.margins?.top !== void 0 || block.margins?.header !== void 0) {
31263
+ const requiredTop = maxHeaderContentHeight > 0 ? headerDistance2 + maxHeaderContentHeight : headerDistance2;
31264
+ next.activeTopMargin = Math.max(sectionTop, requiredTop);
31265
+ next.pendingTopMargin = next.activeTopMargin;
31266
+ }
31267
+ if (block.margins?.bottom !== void 0 || block.margins?.footer !== void 0) {
30952
31268
  const requiredBottom = maxFooterContentHeight > 0 ? footerDistance2 + maxFooterContentHeight : footerDistance2;
30953
- next.activeBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
31269
+ next.activeBottomMargin = Math.max(sectionBottom, requiredBottom);
30954
31270
  next.pendingBottomMargin = next.activeBottomMargin;
30955
31271
  }
31272
+ if (block.margins?.left !== void 0) {
31273
+ const leftMargin = Math.max(0, block.margins.left);
31274
+ next.activeLeftMargin = leftMargin;
31275
+ next.pendingLeftMargin = leftMargin;
31276
+ }
31277
+ if (block.margins?.right !== void 0) {
31278
+ const rightMargin = Math.max(0, block.margins.right);
31279
+ next.activeRightMargin = rightMargin;
31280
+ next.pendingRightMargin = rightMargin;
31281
+ }
30956
31282
  if (block.columns) {
30957
31283
  next.activeColumns = { count: block.columns.count, gap: block.columns.gap };
30958
31284
  next.pendingColumns = null;
@@ -30981,27 +31307,35 @@ function layoutDocument(blocks, measures, options = {}) {
30981
31307
  const headerPx = block.margins?.header;
30982
31308
  const footerPx = block.margins?.footer;
30983
31309
  const topPx = block.margins?.top;
31310
+ const bottomPx = block.margins?.bottom;
31311
+ const leftPx = block.margins?.left;
31312
+ const rightPx = block.margins?.right;
30984
31313
  const nextTop = next.pendingTopMargin ?? next.activeTopMargin;
30985
31314
  const nextBottom = next.pendingBottomMargin ?? next.activeBottomMargin;
31315
+ const nextLeft = next.pendingLeftMargin ?? next.activeLeftMargin;
31316
+ const nextRight = next.pendingRightMargin ?? next.activeRightMargin;
30986
31317
  const nextHeader = next.pendingHeaderDistance ?? next.activeHeaderDistance;
30987
31318
  const nextFooter = next.pendingFooterDistance ?? next.activeFooterDistance;
30988
31319
  next.pendingHeaderDistance = typeof headerPx === "number" ? Math.max(0, headerPx) : nextHeader;
30989
31320
  next.pendingFooterDistance = typeof footerPx === "number" ? Math.max(0, footerPx) : nextFooter;
30990
31321
  if (typeof headerPx === "number" || typeof topPx === "number") {
30991
- const sectionTop = topPx ?? baseMargins.top;
31322
+ const sectionTop = typeof topPx === "number" ? Math.max(0, topPx) : baseMargins.top;
30992
31323
  const sectionHeader = next.pendingHeaderDistance;
30993
31324
  const requiredTop = maxHeaderContentHeight > 0 ? sectionHeader + maxHeaderContentHeight : sectionHeader;
30994
31325
  next.pendingTopMargin = Math.max(sectionTop, requiredTop);
30995
31326
  } else {
30996
31327
  next.pendingTopMargin = nextTop;
30997
31328
  }
30998
- if (typeof footerPx === "number") {
31329
+ if (typeof footerPx === "number" || typeof bottomPx === "number") {
30999
31330
  const sectionFooter = next.pendingFooterDistance;
31331
+ const sectionBottom = typeof bottomPx === "number" ? Math.max(0, bottomPx) : baseMargins.bottom;
31000
31332
  const requiredBottom = maxFooterContentHeight > 0 ? sectionFooter + maxFooterContentHeight : sectionFooter;
31001
- next.pendingBottomMargin = Math.max(baseMargins.bottom, requiredBottom);
31333
+ next.pendingBottomMargin = Math.max(sectionBottom, requiredBottom);
31002
31334
  } else {
31003
31335
  next.pendingBottomMargin = nextBottom;
31004
31336
  }
31337
+ next.pendingLeftMargin = typeof leftPx === "number" ? Math.max(0, leftPx) : nextLeft;
31338
+ next.pendingRightMargin = typeof rightPx === "number" ? Math.max(0, rightPx) : nextRight;
31005
31339
  if (block.pageSize) next.pendingPageSize = { w: block.pageSize.w, h: block.pageSize.h };
31006
31340
  if (block.orientation) next.pendingOrientation = block.orientation;
31007
31341
  const sectionType = block.type ?? "continuous";
@@ -31086,7 +31420,7 @@ function layoutDocument(blocks, measures, options = {}) {
31086
31420
  let activeSectionIndex = initialSectionMetadata?.sectionIndex ?? 0;
31087
31421
  let pendingSectionIndex = null;
31088
31422
  const paginator = createPaginator({
31089
- margins: { left: margins.left, right: margins.right },
31423
+ margins: paginatorMargins,
31090
31424
  getActiveTopMargin: () => activeTopMargin,
31091
31425
  getActiveBottomMargin: () => activeBottomMargin,
31092
31426
  getActiveHeaderDistance: () => activeHeaderDistance,
@@ -31101,8 +31435,12 @@ function layoutDocument(blocks, measures, options = {}) {
31101
31435
  const applied = applyPendingToActive({
31102
31436
  activeTopMargin,
31103
31437
  activeBottomMargin,
31438
+ activeLeftMargin,
31439
+ activeRightMargin,
31104
31440
  pendingTopMargin,
31105
31441
  pendingBottomMargin,
31442
+ pendingLeftMargin,
31443
+ pendingRightMargin,
31106
31444
  activeHeaderDistance,
31107
31445
  activeFooterDistance,
31108
31446
  pendingHeaderDistance,
@@ -31117,8 +31455,12 @@ function layoutDocument(blocks, measures, options = {}) {
31117
31455
  });
31118
31456
  activeTopMargin = applied.activeTopMargin;
31119
31457
  activeBottomMargin = applied.activeBottomMargin;
31458
+ activeLeftMargin = applied.activeLeftMargin;
31459
+ activeRightMargin = applied.activeRightMargin;
31120
31460
  pendingTopMargin = applied.pendingTopMargin;
31121
31461
  pendingBottomMargin = applied.pendingBottomMargin;
31462
+ pendingLeftMargin = applied.pendingLeftMargin;
31463
+ pendingRightMargin = applied.pendingRightMargin;
31122
31464
  activeHeaderDistance = applied.activeHeaderDistance;
31123
31465
  activeFooterDistance = applied.activeFooterDistance;
31124
31466
  pendingHeaderDistance = applied.pendingHeaderDistance;
@@ -31130,6 +31472,14 @@ function layoutDocument(blocks, measures, options = {}) {
31130
31472
  activeOrientation = applied.activeOrientation;
31131
31473
  pendingOrientation = applied.pendingOrientation;
31132
31474
  cachedColumnsState.state = null;
31475
+ paginatorMargins.left = activeLeftMargin;
31476
+ paginatorMargins.right = activeRightMargin;
31477
+ const contentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
31478
+ floatManager.setLayoutContext(
31479
+ normalizeColumns(activeColumns, contentWidth),
31480
+ { left: activeLeftMargin, right: activeRightMargin },
31481
+ activePageSize.w
31482
+ );
31133
31483
  if (pendingNumbering) {
31134
31484
  if (pendingNumbering.format) activeNumberFormat = pendingNumbering.format;
31135
31485
  if (typeof pendingNumbering.start === "number" && Number.isFinite(pendingNumbering.start)) {
@@ -31174,7 +31524,7 @@ function layoutDocument(blocks, measures, options = {}) {
31174
31524
  const getActiveColumnsForState = paginator.getActiveColumnsForState;
31175
31525
  let cachedColumnsState = { state: null, constraintIndex: -2, contentWidth: -1, colsConfig: null, normalized: null };
31176
31526
  const getCurrentColumns = () => {
31177
- const currentContentWidth = activePageSize.w - (margins.left + margins.right);
31527
+ const currentContentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
31178
31528
  const state = states[states.length - 1] ?? null;
31179
31529
  const colsConfig = state ? getActiveColumnsForState(state) : activeColumns;
31180
31530
  const constraintIndex = state ? state.activeConstraintIndex : -1;
@@ -31207,6 +31557,12 @@ function layoutDocument(blocks, measures, options = {}) {
31207
31557
  layoutLog(` Current page: ${state.page.number}, cursorY: ${state.cursorY}`);
31208
31558
  activeColumns = newColumns;
31209
31559
  cachedColumnsState.state = null;
31560
+ const contentWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
31561
+ floatManager.setLayoutContext(
31562
+ normalizeColumns(activeColumns, contentWidth),
31563
+ { left: activeLeftMargin, right: activeRightMargin },
31564
+ activePageSize.w
31565
+ );
31210
31566
  };
31211
31567
  const anchoredByParagraph = collectAnchoredDrawings(blocks, measures);
31212
31568
  const anchoredTablesByParagraph = collectAnchoredTables(blocks, measures);
@@ -31238,10 +31594,10 @@ function layoutDocument(blocks, measures, options = {}) {
31238
31594
  if (alignV === "top") {
31239
31595
  anchorY = offsetV;
31240
31596
  } else if (alignV === "bottom") {
31241
- const pageHeight = contentBottom + margins.bottom;
31597
+ const pageHeight = contentBottom + (state.page.margins?.bottom ?? activeBottomMargin);
31242
31598
  anchorY = pageHeight - imageHeight + offsetV;
31243
31599
  } else if (alignV === "center") {
31244
- const pageHeight = contentBottom + margins.bottom;
31600
+ const pageHeight = contentBottom + (state.page.margins?.bottom ?? activeBottomMargin);
31245
31601
  anchorY = (pageHeight - imageHeight) / 2 + offsetV;
31246
31602
  } else {
31247
31603
  anchorY = offsetV;
@@ -31252,11 +31608,11 @@ function layoutDocument(blocks, measures, options = {}) {
31252
31608
  const anchorX = entry.block.anchor ? computeAnchorX(
31253
31609
  entry.block.anchor,
31254
31610
  state.columnIndex,
31255
- normalizeColumns(activeColumns, contentWidth),
31611
+ normalizeColumns(activeColumns, activePageSize.w - (activeLeftMargin + activeRightMargin)),
31256
31612
  entry.measure.width,
31257
- { left: margins.left, right: margins.right },
31613
+ { left: activeLeftMargin, right: activeRightMargin },
31258
31614
  activePageSize.w
31259
- ) : margins.left;
31615
+ ) : activeLeftMargin;
31260
31616
  floatManager.registerDrawing(entry.block, entry.measure, anchorY, state.columnIndex, state.page.number);
31261
31617
  preRegisteredPositions.set(entry.block.id, { anchorX, anchorY, pageNumber: state.page.number });
31262
31618
  }
@@ -31294,8 +31650,12 @@ function layoutDocument(blocks, measures, options = {}) {
31294
31650
  const sectionState = {
31295
31651
  activeTopMargin,
31296
31652
  activeBottomMargin,
31653
+ activeLeftMargin,
31654
+ activeRightMargin,
31297
31655
  pendingTopMargin,
31298
31656
  pendingBottomMargin,
31657
+ pendingLeftMargin,
31658
+ pendingRightMargin,
31299
31659
  activeHeaderDistance,
31300
31660
  activeFooterDistance,
31301
31661
  pendingHeaderDistance,
@@ -31329,8 +31689,12 @@ function layoutDocument(blocks, measures, options = {}) {
31329
31689
  layoutLog(`[Layout] ========== END SECTION BREAK ==========`);
31330
31690
  activeTopMargin = updatedState.activeTopMargin;
31331
31691
  activeBottomMargin = updatedState.activeBottomMargin;
31692
+ activeLeftMargin = updatedState.activeLeftMargin;
31693
+ activeRightMargin = updatedState.activeRightMargin;
31332
31694
  pendingTopMargin = updatedState.pendingTopMargin;
31333
31695
  pendingBottomMargin = updatedState.pendingBottomMargin;
31696
+ pendingLeftMargin = updatedState.pendingLeftMargin;
31697
+ pendingRightMargin = updatedState.pendingRightMargin;
31334
31698
  activeHeaderDistance = updatedState.activeHeaderDistance;
31335
31699
  activeFooterDistance = updatedState.activeFooterDistance;
31336
31700
  pendingHeaderDistance = updatedState.pendingHeaderDistance;
@@ -31468,8 +31832,8 @@ function layoutDocument(blocks, measures, options = {}) {
31468
31832
  pageMargins: {
31469
31833
  top: activeTopMargin,
31470
31834
  bottom: activeBottomMargin,
31471
- left: margins.left,
31472
- right: margins.right
31835
+ left: activeLeftMargin,
31836
+ right: activeRightMargin
31473
31837
  },
31474
31838
  columns: getCurrentColumns(),
31475
31839
  placedAnchoredIds
@@ -31491,9 +31855,9 @@ function layoutDocument(blocks, measures, options = {}) {
31491
31855
  const cols = getCurrentColumns();
31492
31856
  let maxWidth;
31493
31857
  if (relativeFrom === "page") {
31494
- maxWidth = cols.count === 1 ? activePageSize.w - margins.left - margins.right : activePageSize.w;
31858
+ maxWidth = cols.count === 1 ? activePageSize.w - (activeLeftMargin + activeRightMargin) : activePageSize.w;
31495
31859
  } else if (relativeFrom === "margin") {
31496
- maxWidth = activePageSize.w - margins.left - margins.right;
31860
+ maxWidth = activePageSize.w - (activeLeftMargin + activeRightMargin);
31497
31861
  } else {
31498
31862
  maxWidth = cols.width;
31499
31863
  }
@@ -31653,6 +32017,9 @@ function layoutHeaderFooter(blocks, measures, constraints) {
31653
32017
  if (!Number.isFinite(height) || height <= 0) {
31654
32018
  throw new Error("layoutHeaderFooter: height must be positive");
31655
32019
  }
32020
+ const maxBehindDocOverflow = Math.max(192, height * 4);
32021
+ const minBehindDocY = -maxBehindDocOverflow;
32022
+ const maxBehindDocY = height + maxBehindDocOverflow;
31656
32023
  const marginLeft = constraints.margins?.left ?? 0;
31657
32024
  const transformedBlocks = marginLeft > 0 ? blocks.map((block) => {
31658
32025
  const hasPageRelativeAnchor = (block.kind === "image" || block.kind === "drawing") && block.anchor?.hRelativeFrom === "page" && block.anchor.offsetH != null;
@@ -31683,6 +32050,18 @@ function layoutHeaderFooter(blocks, measures, constraints) {
31683
32050
  if (idx == null) continue;
31684
32051
  const block = blocks[idx];
31685
32052
  const measure = measures[idx];
32053
+ const isAnchoredFragment = (fragment.kind === "image" || fragment.kind === "drawing") && fragment.isAnchored === true;
32054
+ if (isAnchoredFragment) {
32055
+ if (block.kind !== "image" && block.kind !== "drawing") {
32056
+ throw new Error(
32057
+ `Type mismatch: fragment kind is ${fragment.kind} but block kind is ${block.kind} for block ${block.id}`
32058
+ );
32059
+ }
32060
+ const anchoredBlock = block;
32061
+ if (anchoredBlock.anchor?.behindDoc && (fragment.y < minBehindDocY || fragment.y > maxBehindDocY)) {
32062
+ continue;
32063
+ }
32064
+ }
31686
32065
  if (fragment.y < minY) minY = fragment.y;
31687
32066
  let bottom2 = fragment.y;
31688
32067
  if (fragment.kind === "para" && measure?.kind === "paragraph") {
@@ -32680,11 +33059,11 @@ function findWordBoundaries(blocks, pos) {
32680
33059
  if (text.length === 0) return null;
32681
33060
  const clampedPos = Math.max(0, Math.min(localPos, text.length));
32682
33061
  let wordStart = clampedPos;
32683
- while (wordStart > 0 && isWordChar(text[wordStart - 1])) {
33062
+ while (wordStart > 0 && isWordChar$2(text[wordStart - 1])) {
32684
33063
  wordStart--;
32685
33064
  }
32686
33065
  let wordEnd = clampedPos;
32687
- while (wordEnd < text.length && isWordChar(text[wordEnd])) {
33066
+ while (wordEnd < text.length && isWordChar$2(text[wordEnd])) {
32688
33067
  wordEnd++;
32689
33068
  }
32690
33069
  if (wordStart === wordEnd) {
@@ -32747,7 +33126,7 @@ function findBlockAtPosition(blocks, pos) {
32747
33126
  }
32748
33127
  return null;
32749
33128
  }
32750
- function isWordChar(char) {
33129
+ function isWordChar$2(char) {
32751
33130
  return /[\p{L}\p{N}_]/u.test(char);
32752
33131
  }
32753
33132
  function isWhitespace(char) {
@@ -32782,6 +33161,29 @@ function fontString(run) {
32782
33161
  function runText(run) {
32783
33162
  return "src" in run || run.kind === "lineBreak" || run.kind === "break" || run.kind === "fieldAnnotation" ? "" : run.text ?? "";
32784
33163
  }
33164
+ const isWordChar$1 = (char) => {
33165
+ if (!char) return false;
33166
+ const code = char.charCodeAt(0);
33167
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
33168
+ };
33169
+ const capitalizeText$1 = (text, fullText, startOffset) => {
33170
+ if (!text) return text;
33171
+ const hasFullText = typeof startOffset === "number" && fullText != null;
33172
+ let result = "";
33173
+ for (let i = 0; i < text.length; i += 1) {
33174
+ const prevChar = hasFullText ? startOffset + i > 0 ? fullText[startOffset + i - 1] : "" : i > 0 ? text[i - 1] : "";
33175
+ const ch = text[i];
33176
+ result += isWordChar$1(ch) && !isWordChar$1(prevChar) ? ch.toUpperCase() : ch;
33177
+ }
33178
+ return result;
33179
+ };
33180
+ const applyTextTransform$1 = (text, transform, fullText, startOffset) => {
33181
+ if (!text || !transform || transform === "none") return text;
33182
+ if (transform === "uppercase") return text.toUpperCase();
33183
+ if (transform === "lowercase") return text.toLowerCase();
33184
+ if (transform === "capitalize") return capitalizeText$1(text, fullText, startOffset);
33185
+ return text;
33186
+ };
32785
33187
  const DEFAULT_TAB_INTERVAL_TWIPS$1 = 720;
32786
33188
  const TWIPS_PER_INCH$4 = 1440;
32787
33189
  const PX_PER_INCH$3 = 96;
@@ -32790,6 +33192,13 @@ const TAB_EPSILON$1 = 0.1;
32790
33192
  const WIDTH_FUDGE_PX = 0.5;
32791
33193
  const twipsToPx$2 = (twips) => twips / TWIPS_PER_PX$1;
32792
33194
  const pxToTwips$1 = (px) => Math.round(px * TWIPS_PER_PX$1);
33195
+ const markerFontString = (run) => {
33196
+ const size2 = run?.fontSize ?? 16;
33197
+ const family = run?.fontFamily ?? "Arial";
33198
+ const italic = run?.italic ? "italic " : "";
33199
+ const bold = run?.bold ? "bold " : "";
33200
+ return `${italic}${bold}${size2}px ${family}`.trim();
33201
+ };
32793
33202
  const buildTabStopsPx$1 = (indent, tabs, tabIntervalTwips) => {
32794
33203
  const paragraphIndentTwips = {
32795
33204
  left: pxToTwips$1(Math.max(0, indent?.left ?? 0)),
@@ -32820,7 +33229,8 @@ const getNextTabStopPx$1 = (currentX, tabStops, startIndex) => {
32820
33229
  };
32821
33230
  function measureRunSliceWidth(run, fromChar, toChar) {
32822
33231
  const context = getCtx();
32823
- const text = runText(run).slice(fromChar, toChar);
33232
+ const fullText = runText(run);
33233
+ const text = applyTextTransform$1(fullText.slice(fromChar, toChar), run.textTransform, fullText, fromChar);
32824
33234
  if (!context) {
32825
33235
  const textRun = isTextRun$2(run) ? run : null;
32826
33236
  const size2 = textRun?.fontSize ?? 16;
@@ -32866,8 +33276,21 @@ function remeasureParagraph(block, maxWidth, firstLineIndent = 0) {
32866
33276
  const contentWidth = Math.max(1, maxWidth - indentLeft - indentRight);
32867
33277
  const markerTextStartX = wordLayout?.marker?.textStartX;
32868
33278
  const textStartPx = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof wordLayout?.textStartPx === "number" && Number.isFinite(wordLayout.textStartPx) ? wordLayout.textStartPx : void 0;
32869
- const treatAsHanging = textStartPx && indentLeft === 0 && indentHanging === 0;
32870
- const firstLineWidth = typeof textStartPx === "number" && textStartPx > indentLeft && !treatAsHanging ? Math.max(1, maxWidth - textStartPx - indentRight) : Math.max(1, contentWidth - rawFirstLineOffset);
33279
+ const resolvedTextStartPx = resolveListTextStartPx(
33280
+ wordLayout,
33281
+ indentLeft,
33282
+ indentFirstLine,
33283
+ indentHanging,
33284
+ (markerText, marker) => {
33285
+ const context = getCtx();
33286
+ if (!context) return 0;
33287
+ context.font = markerFontString(marker.run);
33288
+ return context.measureText(markerText).width;
33289
+ }
33290
+ );
33291
+ const effectiveTextStartPx = resolvedTextStartPx ?? textStartPx;
33292
+ const treatAsHanging = !wordLayout?.marker && effectiveTextStartPx && indentLeft === 0 && indentHanging === 0;
33293
+ const firstLineWidth = typeof effectiveTextStartPx === "number" && effectiveTextStartPx > indentLeft && !treatAsHanging ? Math.max(1, maxWidth - effectiveTextStartPx - indentRight) : Math.max(1, contentWidth - rawFirstLineOffset);
32871
33294
  const tabStops = buildTabStopsPx$1(indent, attrs?.tabs, attrs?.tabIntervalTwips);
32872
33295
  let currentRun = 0;
32873
33296
  let currentChar = 0;
@@ -33407,7 +33830,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
33407
33830
  if (dirty.deletedBlockIds.length > 0) {
33408
33831
  measureCache.invalidate(dirty.deletedBlockIds);
33409
33832
  }
33410
- const { measurementWidth, measurementHeight } = resolveMeasurementConstraints(options);
33833
+ const { measurementWidth, measurementHeight } = resolveMeasurementConstraints(options, nextBlocks);
33411
33834
  if (measurementWidth <= 0 || measurementHeight <= 0) {
33412
33835
  throw new Error("incrementalLayout: invalid measurement constraints resolved from options");
33413
33836
  }
@@ -33676,7 +34099,7 @@ async function incrementalLayout(previousBlocks, _previousLayout, nextBlocks, op
33676
34099
  const DEFAULT_PAGE_SIZE$1 = { w: 612, h: 792 };
33677
34100
  const DEFAULT_MARGINS$1 = { top: 72, right: 72, bottom: 72, left: 72 };
33678
34101
  const normalizeMargin = (value, fallback) => Number.isFinite(value) ? value : fallback;
33679
- function resolveMeasurementConstraints(options) {
34102
+ function resolveMeasurementConstraints(options, blocks) {
33680
34103
  const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE$1;
33681
34104
  const margins = {
33682
34105
  top: normalizeMargin(options.margins?.top, DEFAULT_MARGINS$1.top),
@@ -33684,23 +34107,41 @@ function resolveMeasurementConstraints(options) {
33684
34107
  bottom: normalizeMargin(options.margins?.bottom, DEFAULT_MARGINS$1.bottom),
33685
34108
  left: normalizeMargin(options.margins?.left, DEFAULT_MARGINS$1.left)
33686
34109
  };
33687
- const contentWidth = pageSize.w - (margins.left + margins.right);
33688
- const contentHeight = pageSize.h - (margins.top + margins.bottom);
33689
- const columns = options.columns;
33690
- if (columns && columns.count > 1) {
34110
+ const baseContentWidth = pageSize.w - (margins.left + margins.right);
34111
+ const baseContentHeight = pageSize.h - (margins.top + margins.bottom);
34112
+ const computeColumnWidth = (contentWidth, columns) => {
34113
+ if (!columns || columns.count <= 1) return contentWidth;
33691
34114
  const gap = Math.max(0, columns.gap ?? 0);
33692
34115
  const totalGap = gap * (columns.count - 1);
33693
- const columnWidth = (contentWidth - totalGap) / columns.count;
33694
- if (columnWidth > 0) {
33695
- return {
33696
- measurementWidth: columnWidth,
33697
- measurementHeight: contentHeight
34116
+ return (contentWidth - totalGap) / columns.count;
34117
+ };
34118
+ let measurementWidth = computeColumnWidth(baseContentWidth, options.columns);
34119
+ let measurementHeight = baseContentHeight;
34120
+ if (blocks && blocks.length > 0) {
34121
+ for (const block of blocks) {
34122
+ if (block.kind !== "sectionBreak") continue;
34123
+ const sectionPageSize = block.pageSize ?? pageSize;
34124
+ const sectionMargins = {
34125
+ top: normalizeMargin(block.margins?.top, margins.top),
34126
+ right: normalizeMargin(block.margins?.right, margins.right),
34127
+ bottom: normalizeMargin(block.margins?.bottom, margins.bottom),
34128
+ left: normalizeMargin(block.margins?.left, margins.left)
33698
34129
  };
34130
+ const contentWidth = sectionPageSize.w - (sectionMargins.left + sectionMargins.right);
34131
+ const contentHeight = sectionPageSize.h - (sectionMargins.top + sectionMargins.bottom);
34132
+ if (contentWidth <= 0 || contentHeight <= 0) continue;
34133
+ const columnWidth = computeColumnWidth(contentWidth, block.columns ?? options.columns);
34134
+ if (columnWidth > measurementWidth) {
34135
+ measurementWidth = columnWidth;
34136
+ }
34137
+ if (contentHeight > measurementHeight) {
34138
+ measurementHeight = contentHeight;
34139
+ }
33699
34140
  }
33700
34141
  }
33701
34142
  return {
33702
- measurementWidth: contentWidth,
33703
- measurementHeight: contentHeight
34143
+ measurementWidth,
34144
+ measurementHeight
33704
34145
  };
33705
34146
  }
33706
34147
  const serializeHeaderFooterResults = (kind, batch) => {
@@ -35767,6 +36208,7 @@ function isInRegisteredSurface(event) {
35767
36208
  }
35768
36209
  return false;
35769
36210
  }
36211
+ const SLASH_MENU_HANDLED_FLAG = "__sdHandledBySlashMenu";
35770
36212
  class PresentationInputBridge {
35771
36213
  /**
35772
36214
  * Creates a new PresentationInputBridge that forwards user input events from the visible layout
@@ -36002,9 +36444,19 @@ forwardCompositionEvent_fn = function(event) {
36002
36444
  /**
36003
36445
  * Forwards context menu events to the hidden editor.
36004
36446
  *
36447
+ * Checks if the SlashMenu component has already handled the event by inspecting
36448
+ * the SLASH_MENU_HANDLED_FLAG. If the flag is set, the event is not forwarded,
36449
+ * preventing duplicate context menu handling. This coordination allows SlashMenu
36450
+ * to intercept right-clicks in the capture phase and prevent the default editor
36451
+ * context menu from appearing.
36452
+ *
36005
36453
  * @param event - The context menu event from the layout surface
36006
36454
  */
36007
36455
  forwardContextMenu_fn = function(event) {
36456
+ const handledBySlashMenu = Boolean(event[SLASH_MENU_HANDLED_FLAG]);
36457
+ if (handledBySlashMenu) {
36458
+ return;
36459
+ }
36008
36460
  if (!__privateGet(this, _isEditable).call(this)) {
36009
36461
  return;
36010
36462
  }
@@ -39736,8 +40188,8 @@ function buildSdtCacheKey(nodeType, attrs, explicitKey) {
39736
40188
  }
39737
40189
  return void 0;
39738
40190
  }
39739
- const DEFAULT_LIST_HANGING_PX$1 = 18;
39740
- const LIST_MARKER_GAP$1 = 8;
40191
+ const DEFAULT_LIST_HANGING_PX = 18;
40192
+ const LIST_MARKER_GAP = 8;
39741
40193
  const DEFAULT_BULLET_GLYPH = "•";
39742
40194
  const DEFAULT_DECIMAL_PATTERN = "%1.";
39743
40195
  const ASCII_UPPERCASE_A = 65;
@@ -40148,7 +40600,7 @@ function computeWordParagraphLayout(input) {
40148
40600
  let markerBoxWidthPx;
40149
40601
  let markerX;
40150
40602
  if (hasFirstLineIndent) {
40151
- markerBoxWidthPx = glyphWidthPx != null && glyphWidthPx > 0 ? glyphWidthPx + LIST_MARKER_GAP$1 : DEFAULT_LIST_HANGING_PX$1;
40603
+ markerBoxWidthPx = glyphWidthPx != null && glyphWidthPx > 0 ? glyphWidthPx + LIST_MARKER_GAP : DEFAULT_LIST_HANGING_PX;
40152
40604
  markerX = indentLeftPx + (firstLinePx ?? 0);
40153
40605
  layout.textStartPx = markerX + markerBoxWidthPx;
40154
40606
  layout.hangingPx = 0;
@@ -40248,12 +40700,12 @@ const resolveMarkerBoxWidth = (hangingPxRaw, glyphWidthPx) => {
40248
40700
  let markerBox = Math.max(hangingPxRaw || 0, 0);
40249
40701
  if (markerBox <= 0) {
40250
40702
  if (glyphWidthPx != null && glyphWidthPx > 0) {
40251
- markerBox = glyphWidthPx + LIST_MARKER_GAP$1;
40703
+ markerBox = glyphWidthPx + LIST_MARKER_GAP;
40252
40704
  } else {
40253
- markerBox = DEFAULT_LIST_HANGING_PX$1;
40705
+ markerBox = DEFAULT_LIST_HANGING_PX;
40254
40706
  }
40255
- } else if (glyphWidthPx != null && glyphWidthPx + LIST_MARKER_GAP$1 > markerBox) {
40256
- markerBox = glyphWidthPx + LIST_MARKER_GAP$1;
40707
+ } else if (glyphWidthPx != null && glyphWidthPx + LIST_MARKER_GAP > markerBox) {
40708
+ markerBox = glyphWidthPx + LIST_MARKER_GAP;
40257
40709
  }
40258
40710
  return markerBox;
40259
40711
  };
@@ -40273,7 +40725,7 @@ const buildMarkerLayout = ({
40273
40725
  textStartX: textStartPx,
40274
40726
  baselineOffsetPx: markerRun.baselineShift ?? 0,
40275
40727
  // Gutter is the small gap between marker and text, not the full marker box width
40276
- gutterWidthPx: LIST_MARKER_GAP$1,
40728
+ gutterWidthPx: LIST_MARKER_GAP,
40277
40729
  justification: numbering.lvlJc ?? "left",
40278
40730
  suffix: normalizeSuffix$1(numbering.suffix) ?? "tab",
40279
40731
  run: markerRun,
@@ -40965,6 +41417,31 @@ const computeWordLayoutForParagraph = (paragraphAttrs, numberingProps, styleCont
40965
41417
  return null;
40966
41418
  }
40967
41419
  };
41420
+ const normalizeWordLayoutForIndent = (wordLayout, paragraphIndent) => {
41421
+ const resolvedIndent = wordLayout.resolvedIndent ?? paragraphIndent ?? {};
41422
+ const indentLeft = isFiniteNumber(resolvedIndent.left) ? resolvedIndent.left : 0;
41423
+ const firstLine = isFiniteNumber(resolvedIndent.firstLine) ? resolvedIndent.firstLine : 0;
41424
+ const hanging = isFiniteNumber(resolvedIndent.hanging) ? resolvedIndent.hanging : 0;
41425
+ const shouldFirstLineIndentMode = firstLine > 0 && !hanging;
41426
+ if (wordLayout.firstLineIndentMode === true && !shouldFirstLineIndentMode) {
41427
+ wordLayout.firstLineIndentMode = false;
41428
+ }
41429
+ if (wordLayout.firstLineIndentMode === true) {
41430
+ if (isFiniteNumber(wordLayout.textStartPx)) {
41431
+ if (wordLayout.marker && (!isFiniteNumber(wordLayout.marker.textStartX) || wordLayout.marker.textStartX !== wordLayout.textStartPx)) {
41432
+ wordLayout.marker.textStartX = wordLayout.textStartPx;
41433
+ }
41434
+ } else if (wordLayout.marker && isFiniteNumber(wordLayout.marker.textStartX)) {
41435
+ wordLayout.textStartPx = wordLayout.marker.textStartX;
41436
+ }
41437
+ } else {
41438
+ wordLayout.textStartPx = indentLeft;
41439
+ if (wordLayout.marker) {
41440
+ wordLayout.marker.textStartX = indentLeft;
41441
+ }
41442
+ }
41443
+ return wordLayout;
41444
+ };
40968
41445
  const computeParagraphAttrs = (para, styleContext, listCounterContext, converterContext, hydrationOverride) => {
40969
41446
  const attrs = para.attrs ?? {};
40970
41447
  const paragraphProps = typeof attrs.paragraphProperties === "object" && attrs.paragraphProperties !== null ? attrs.paragraphProperties : {};
@@ -41287,8 +41764,11 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
41287
41764
  let wordLayout = computeWordLayoutForParagraph(paragraphAttrs, enrichedNumberingProps, styleContext);
41288
41765
  if (!wordLayout && enrichedNumberingProps.resolvedLevelIndent) {
41289
41766
  const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
41290
- const firstLinePx = resolvedIndentPx?.firstLine ?? 0;
41291
- if (firstLinePx > 0) {
41767
+ const baseIndent = resolvedIndentPx ?? enrichedNumberingProps.resolvedLevelIndent;
41768
+ const mergedIndent = { ...baseIndent, ...paragraphAttrs.indent ?? {} };
41769
+ const firstLinePx = isFiniteNumber(mergedIndent.firstLine) ? mergedIndent.firstLine : 0;
41770
+ const hangingPx = isFiniteNumber(mergedIndent.hanging) ? mergedIndent.hanging : 0;
41771
+ if (firstLinePx > 0 && !hangingPx) {
41292
41772
  wordLayout = {
41293
41773
  // Treat as first-line-indent mode: text starts after the marker+firstLine offset.
41294
41774
  firstLineIndentMode: true,
@@ -41296,10 +41776,13 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
41296
41776
  };
41297
41777
  }
41298
41778
  }
41299
- if (wordLayout && (!wordLayout.textStartPx || !Number.isFinite(wordLayout.textStartPx)) && enrichedNumberingProps.resolvedLevelIndent) {
41779
+ if (wordLayout && !Number.isFinite(wordLayout.textStartPx) && enrichedNumberingProps.resolvedLevelIndent) {
41300
41780
  const resolvedIndentPx = convertIndentTwipsToPx(enrichedNumberingProps.resolvedLevelIndent);
41301
- const firstLinePx = resolvedIndentPx?.firstLine ?? 0;
41302
- if (firstLinePx > 0) {
41781
+ const baseIndent = resolvedIndentPx ?? enrichedNumberingProps.resolvedLevelIndent;
41782
+ const mergedIndent = { ...baseIndent, ...paragraphAttrs.indent ?? {} };
41783
+ const firstLinePx = isFiniteNumber(mergedIndent.firstLine) ? mergedIndent.firstLine : 0;
41784
+ const hangingPx = isFiniteNumber(mergedIndent.hanging) ? mergedIndent.hanging : 0;
41785
+ if (firstLinePx > 0 && !hangingPx) {
41303
41786
  wordLayout = {
41304
41787
  ...wordLayout,
41305
41788
  firstLineIndentMode: wordLayout.firstLineIndentMode ?? true,
@@ -41319,6 +41802,7 @@ const computeParagraphAttrs = (para, styleContext, listCounterContext, converter
41319
41802
  wordLayout.marker.suffix = listRendering.suffix;
41320
41803
  }
41321
41804
  }
41805
+ wordLayout = normalizeWordLayoutForIndent(wordLayout, paragraphAttrs.indent);
41322
41806
  paragraphAttrs.wordLayout = wordLayout;
41323
41807
  }
41324
41808
  if (enrichedNumberingProps.resolvedLevelIndent) {
@@ -45552,11 +46036,6 @@ function initHeaderFooterRegistry({
45552
46036
  cleanups
45553
46037
  };
45554
46038
  }
45555
- const LIST_MARKER_GAP = 8;
45556
- const MIN_MARKER_GUTTER = 24;
45557
- const DEFAULT_LIST_INDENT_BASE_PX = 24;
45558
- const DEFAULT_LIST_INDENT_STEP_PX = 24;
45559
- const DEFAULT_LIST_HANGING_PX = 18;
45560
46039
  function calculateRotatedBounds(input) {
45561
46040
  const width = Math.max(0, input.width);
45562
46041
  const height = Math.max(0, input.height);
@@ -45820,8 +46299,25 @@ async function measureParagraphBlock(block, maxWidth) {
45820
46299
  const rawTextStartPx = wordLayout?.textStartPx;
45821
46300
  const markerTextStartX = wordLayout?.marker?.textStartX;
45822
46301
  const textStartPx = typeof markerTextStartX === "number" && Number.isFinite(markerTextStartX) ? markerTextStartX : typeof rawTextStartPx === "number" && Number.isFinite(rawTextStartPx) ? rawTextStartPx : void 0;
45823
- if (typeof textStartPx === "number" && textStartPx > indentLeft) {
45824
- initialAvailableWidth = Math.max(1, maxWidth - textStartPx - indentRight);
46302
+ const resolvedTextStartPx = resolveListTextStartPx(
46303
+ wordLayout,
46304
+ indentLeft,
46305
+ firstLine,
46306
+ hanging,
46307
+ (markerText, marker) => {
46308
+ const markerRun = {
46309
+ fontFamily: toCssFontFamily(marker.run?.fontFamily) ?? marker.run?.fontFamily ?? "Arial",
46310
+ fontSize: marker.run?.fontSize ?? 16,
46311
+ bold: marker.run?.bold ?? false,
46312
+ italic: marker.run?.italic ?? false
46313
+ };
46314
+ const { font: markerFont } = buildFontString(markerRun);
46315
+ return measureText(markerText, markerFont, ctx2);
46316
+ }
46317
+ );
46318
+ const effectiveTextStartPx = resolvedTextStartPx ?? textStartPx;
46319
+ if (typeof effectiveTextStartPx === "number" && effectiveTextStartPx > indentLeft) {
46320
+ initialAvailableWidth = Math.max(1, maxWidth - effectiveTextStartPx - indentRight);
45825
46321
  } else {
45826
46322
  initialAvailableWidth = Math.max(1, contentWidth - firstLineOffset);
45827
46323
  }
@@ -45908,7 +46404,7 @@ async function measureParagraphBlock(block, maxWidth) {
45908
46404
  pendingTabAlignment = null;
45909
46405
  return startX;
45910
46406
  };
45911
- const alignSegmentAtTab = (segmentText, font, runContext) => {
46407
+ const alignSegmentAtTab = (segmentText, font, runContext, segmentStartChar) => {
45912
46408
  if (!pendingTabAlignment || !currentLine) return void 0;
45913
46409
  const { val } = pendingTabAlignment;
45914
46410
  let segmentWidth = 0;
@@ -45917,11 +46413,11 @@ async function measureParagraphBlock(block, maxWidth) {
45917
46413
  const idx = segmentText.indexOf(decimalSeparator);
45918
46414
  if (idx >= 0) {
45919
46415
  const beforeText = segmentText.slice(0, idx);
45920
- beforeDecimalWidth = beforeText.length > 0 ? measureRunWidth(beforeText, font, ctx2, runContext) : 0;
46416
+ beforeDecimalWidth = beforeText.length > 0 ? measureRunWidth(beforeText, font, ctx2, runContext, segmentStartChar) : 0;
45921
46417
  }
45922
- segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext) : 0;
46418
+ segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext, segmentStartChar) : 0;
45923
46419
  } else if (val === "end" || val === "center") {
45924
- segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext) : 0;
46420
+ segmentWidth = segmentText.length > 0 ? measureRunWidth(segmentText, font, ctx2, runContext, segmentStartChar) : 0;
45925
46421
  }
45926
46422
  return alignPendingTabForWidth(segmentWidth, beforeDecimalWidth);
45927
46423
  };
@@ -45973,8 +46469,8 @@ async function measureParagraphBlock(block, maxWidth) {
45973
46469
  const { font } = buildFontString(
45974
46470
  lastRun
45975
46471
  );
45976
- const fullWidth = measureRunWidth(sliceText, font, ctx2, lastRun);
45977
- const keptWidth = keptText.length > 0 ? measureRunWidth(keptText, font, ctx2, lastRun) : 0;
46472
+ const fullWidth = measureRunWidth(sliceText, font, ctx2, lastRun, sliceStart);
46473
+ const keptWidth = keptText.length > 0 ? measureRunWidth(keptText, font, ctx2, lastRun, sliceStart) : 0;
45978
46474
  const delta = Math.max(0, fullWidth - keptWidth);
45979
46475
  lineToTrim.width = roundValue(Math.max(0, lineToTrim.width - delta));
45980
46476
  lineToTrim.spaceCount = Math.max(0, lineToTrim.spaceCount - trimCount);
@@ -46185,7 +46681,8 @@ async function measureParagraphBlock(block, maxWidth) {
46185
46681
  continue;
46186
46682
  }
46187
46683
  if (isFieldAnnotationRun(run)) {
46188
- const displayText = run.displayLabel || "";
46684
+ const rawDisplayText = run.displayLabel || "";
46685
+ const displayText = applyTextTransform(rawDisplayText, run);
46189
46686
  const annotationFontSize = typeof run.fontSize === "number" ? run.fontSize : typeof run.fontSize === "string" ? parseFloat(run.fontSize) || DEFAULT_FIELD_ANNOTATION_FONT_SIZE : DEFAULT_FIELD_ANNOTATION_FONT_SIZE;
46190
46687
  const annotationFontFamily = run.fontFamily || "Arial, sans-serif";
46191
46688
  const fontWeight = run.bold ? "bold" : "normal";
@@ -46288,7 +46785,7 @@ async function measureParagraphBlock(block, maxWidth) {
46288
46785
  const spacesLength = segment.length;
46289
46786
  const spacesStartChar = charPosInRun;
46290
46787
  const spacesEndChar = charPosInRun + spacesLength;
46291
- const spacesWidth = measureRunWidth(segment, font, ctx2, run);
46788
+ const spacesWidth = measureRunWidth(segment, font, ctx2, run, spacesStartChar);
46292
46789
  if (!currentLine) {
46293
46790
  currentLine = {
46294
46791
  fromRun: runIndex,
@@ -46352,7 +46849,7 @@ async function measureParagraphBlock(block, maxWidth) {
46352
46849
  }
46353
46850
  let segmentStartX;
46354
46851
  if (currentLine && pendingTabAlignment) {
46355
- segmentStartX = alignSegmentAtTab(segment, font, run);
46852
+ segmentStartX = alignSegmentAtTab(segment, font, run, charPosInRun);
46356
46853
  if (segmentStartX == null) {
46357
46854
  segmentStartX = currentLine.width;
46358
46855
  }
@@ -46362,7 +46859,7 @@ async function measureParagraphBlock(block, maxWidth) {
46362
46859
  if (word2 === "") {
46363
46860
  const spaceStartChar = charPosInRun;
46364
46861
  const spaceEndChar = charPosInRun + 1;
46365
- const singleSpaceWidth = measureRunWidth(" ", font, ctx2, run);
46862
+ const singleSpaceWidth = measureRunWidth(" ", font, ctx2, run, spaceStartChar);
46366
46863
  if (!currentLine) {
46367
46864
  currentLine = {
46368
46865
  fromRun: runIndex,
@@ -46413,12 +46910,12 @@ async function measureParagraphBlock(block, maxWidth) {
46413
46910
  charPosInRun = spaceEndChar;
46414
46911
  continue;
46415
46912
  }
46416
- const wordOnlyWidth = measureRunWidth(word2, font, ctx2, run);
46417
- const shouldIncludeDelimiterSpace = wordIndex < lastNonEmptyWordIndex;
46418
- const spaceWidth = shouldIncludeDelimiterSpace ? measureRunWidth(" ", font, ctx2, run) : 0;
46419
- const wordCommitWidth = wordOnlyWidth + spaceWidth;
46420
46913
  const wordStartChar = charPosInRun;
46914
+ const wordOnlyWidth = measureRunWidth(word2, font, ctx2, run, wordStartChar);
46915
+ const shouldIncludeDelimiterSpace = wordIndex < lastNonEmptyWordIndex;
46421
46916
  const wordEndNoSpace = charPosInRun + word2.length;
46917
+ const spaceWidth = shouldIncludeDelimiterSpace ? measureRunWidth(" ", font, ctx2, run, wordEndNoSpace) : 0;
46918
+ const wordCommitWidth = wordOnlyWidth + spaceWidth;
46422
46919
  const wordEndWithSpace = wordEndNoSpace + (shouldIncludeDelimiterSpace ? 1 : 0);
46423
46920
  const effectiveMaxWidth = currentLine ? currentLine.maxWidth : getEffectiveWidth(lines.length === 0 ? initialAvailableWidth : contentWidth);
46424
46921
  if (wordOnlyWidth > effectiveMaxWidth && word2.length > 1) {
@@ -46437,7 +46934,7 @@ async function measureParagraphBlock(block, maxWidth) {
46437
46934
  const hasTabOnlyLine = currentLine && currentLine.segments && currentLine.segments.length === 0 && currentLine.width > 0;
46438
46935
  const remainingWidthAfterTab = hasTabOnlyLine ? currentLine.maxWidth - currentLine.width : lineMaxWidth;
46439
46936
  const chunkWidth = hasTabOnlyLine ? Math.max(remainingWidthAfterTab, lineMaxWidth * 0.25) : lineMaxWidth;
46440
- const chunks = breakWordIntoChunks(word2, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run);
46937
+ const chunks = breakWordIntoChunks(word2, chunkWidth - WIDTH_FUDGE_PX2, font, ctx2, run, wordStartChar);
46441
46938
  let chunkCharOffset = wordStartChar;
46442
46939
  for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
46443
46940
  const chunk = chunks[chunkIndex];
@@ -46561,7 +47058,7 @@ async function measureParagraphBlock(block, maxWidth) {
46561
47058
  if (candidateSpaces > 0) {
46562
47059
  const overflow = totalWidthWithWord - availableWidth;
46563
47060
  if (overflow > 0) {
46564
- const baseSpaceWidth = spaceWidth || measureRunWidth(" ", font, ctx2, run) || Math.max(1, boundarySpacing);
47061
+ const baseSpaceWidth = spaceWidth || measureRunWidth(" ", font, ctx2, run, wordEndNoSpace) || Math.max(1, boundarySpacing);
46565
47062
  const perSpaceCompression = overflow / candidateSpaces;
46566
47063
  const maxPerSpaceCompression = baseSpaceWidth * 0.25;
46567
47064
  if (perSpaceCompression <= maxPerSpaceCompression) {
@@ -46736,8 +47233,8 @@ async function measureParagraphBlock(block, maxWidth) {
46736
47233
  const { font: markerFont } = buildFontString(markerRun);
46737
47234
  const markerText = wordLayout.marker.markerText ?? "";
46738
47235
  const glyphWidth = markerText ? measureText(markerText, markerFont, ctx2) : 0;
46739
- const gutter = typeof wordLayout.marker.gutterWidthPx === "number" && isFinite(wordLayout.marker.gutterWidthPx) && wordLayout.marker.gutterWidthPx >= 0 ? wordLayout.marker.gutterWidthPx : LIST_MARKER_GAP;
46740
- const markerBoxWidth = Math.max(wordLayout.marker.markerBoxWidthPx ?? 0, glyphWidth + LIST_MARKER_GAP);
47236
+ const gutter = typeof wordLayout.marker.gutterWidthPx === "number" && isFinite(wordLayout.marker.gutterWidthPx) && wordLayout.marker.gutterWidthPx >= 0 ? wordLayout.marker.gutterWidthPx : LIST_MARKER_GAP$1;
47237
+ const markerBoxWidth = Math.max(wordLayout.marker.markerBoxWidthPx ?? 0, glyphWidth + LIST_MARKER_GAP$1);
46741
47238
  markerInfo = {
46742
47239
  markerWidth: markerBoxWidth,
46743
47240
  markerTextWidth: glyphWidth,
@@ -47081,7 +47578,7 @@ async function measureListBlock(block, constraints) {
47081
47578
  markerTextWidth = markerText ? measureText(markerText, markerFont, ctx2) : 0;
47082
47579
  indentLeft = resolveIndentLeft(item);
47083
47580
  const indentHanging = resolveIndentHanging(item);
47084
- markerWidth = Math.max(MIN_MARKER_GUTTER, markerTextWidth + LIST_MARKER_GAP, indentHanging);
47581
+ markerWidth = Math.max(MIN_MARKER_GUTTER, markerTextWidth + LIST_MARKER_GAP$1, indentHanging);
47085
47582
  }
47086
47583
  const paragraphWidth = Math.max(1, constraints.maxWidth - indentLeft - markerWidth);
47087
47584
  const paragraphMeasure = await measureParagraphBlock(item.paragraph, paragraphWidth);
@@ -47107,16 +47604,46 @@ const getPrimaryRun = (paragraph) => {
47107
47604
  fontSize: 16
47108
47605
  };
47109
47606
  };
47110
- const measureRunWidth = (text, font, ctx2, run) => {
47607
+ const isWordChar = (char) => {
47608
+ if (!char) return false;
47609
+ const code = char.charCodeAt(0);
47610
+ return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122 || char === "'";
47611
+ };
47612
+ const capitalizeText = (text, fullText, startOffset) => {
47613
+ if (!text) return text;
47614
+ const hasFullText = typeof startOffset === "number" && fullText != null;
47615
+ let result = "";
47616
+ for (let i = 0; i < text.length; i += 1) {
47617
+ const prevChar = hasFullText ? startOffset + i > 0 ? fullText[startOffset + i - 1] : "" : i > 0 ? text[i - 1] : "";
47618
+ const ch = text[i];
47619
+ result += isWordChar(ch) && !isWordChar(prevChar) ? ch.toUpperCase() : ch;
47620
+ }
47621
+ return result;
47622
+ };
47623
+ const applyTextTransform = (text, run, startOffset) => {
47624
+ const transform = run.textTransform;
47625
+ if (!text || !transform || transform === "none") return text;
47626
+ if (transform === "uppercase") return text.toUpperCase();
47627
+ if (transform === "lowercase") return text.toLowerCase();
47628
+ if (transform === "capitalize") {
47629
+ const fullText = "text" in run && typeof run.text === "string" ? run.text : text;
47630
+ return capitalizeText(text, fullText, startOffset);
47631
+ }
47632
+ return text;
47633
+ };
47634
+ const measureRunWidth = (text, font, ctx2, run, startOffset) => {
47111
47635
  const letterSpacing = run.kind === "text" || run.kind === void 0 ? run.letterSpacing || 0 : 0;
47112
- const width = getMeasuredTextWidth(text, font, letterSpacing, ctx2);
47636
+ const displayText = applyTextTransform(text, run, startOffset);
47637
+ const width = getMeasuredTextWidth(displayText, font, letterSpacing, ctx2);
47113
47638
  return roundValue(width);
47114
47639
  };
47115
- const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run) => {
47640
+ const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run, startOffset) => {
47116
47641
  const chunks = [];
47642
+ const baseOffset = typeof startOffset === "number" ? startOffset : 0;
47117
47643
  if (maxWidth <= 0) {
47118
- for (const char of word2) {
47119
- const charWidth = measureRunWidth(char, font, ctx2, run);
47644
+ for (let i = 0; i < word2.length; i++) {
47645
+ const char = word2[i];
47646
+ const charWidth = measureRunWidth(char, font, ctx2, run, baseOffset + i);
47120
47647
  chunks.push({ text: char, width: charWidth });
47121
47648
  }
47122
47649
  return chunks;
@@ -47126,11 +47653,11 @@ const breakWordIntoChunks = (word2, maxWidth, font, ctx2, run) => {
47126
47653
  for (let i = 0; i < word2.length; i++) {
47127
47654
  const char = word2[i];
47128
47655
  const testChunk = currentChunk + char;
47129
- const testWidth = measureRunWidth(testChunk, font, ctx2, run);
47656
+ const testWidth = measureRunWidth(testChunk, font, ctx2, run, baseOffset);
47130
47657
  if (testWidth > maxWidth && currentChunk.length > 0) {
47131
47658
  chunks.push({ text: currentChunk, width: currentWidth });
47132
47659
  currentChunk = char;
47133
- currentWidth = measureRunWidth(char, font, ctx2, run);
47660
+ currentWidth = measureRunWidth(char, font, ctx2, run, baseOffset + i);
47134
47661
  } else {
47135
47662
  currentChunk = testChunk;
47136
47663
  currentWidth = testWidth;
@@ -47184,7 +47711,8 @@ const measureDropCap = (ctx2, descriptor, spacing) => {
47184
47711
  italic: run.italic
47185
47712
  });
47186
47713
  ctx2.font = font;
47187
- const metrics = ctx2.measureText(run.text);
47714
+ const displayText = applyTextTransform(run.text, run);
47715
+ const metrics = ctx2.measureText(displayText);
47188
47716
  const advanceWidth = metrics.width;
47189
47717
  const paintedWidth = (metrics.actualBoundingBoxLeft || 0) + (metrics.actualBoundingBoxRight || 0);
47190
47718
  const textWidth = Math.max(advanceWidth, paintedWidth);
@@ -47210,7 +47738,7 @@ const resolveIndentHanging = (item) => {
47210
47738
  if (indentHanging > 0) {
47211
47739
  return indentHanging;
47212
47740
  }
47213
- return DEFAULT_LIST_HANGING_PX;
47741
+ return DEFAULT_LIST_HANGING_PX$1;
47214
47742
  };
47215
47743
  const buildTabStopsPx = (indent, tabs, tabIntervalTwips) => {
47216
47744
  const paragraphIndentTwips = {
@@ -47432,6 +47960,9 @@ const _PresentationEditor = class _PresentationEditor extends EventEmitter {
47432
47960
  if (event.button !== 0) {
47433
47961
  return;
47434
47962
  }
47963
+ if (event.ctrlKey && navigator.platform.includes("Mac")) {
47964
+ return;
47965
+ }
47435
47966
  __privateSet(this, _pendingMarginClick, null);
47436
47967
  const target = event.target;
47437
47968
  if (target?.closest?.(".superdoc-ruler-handle") != null) {
@@ -53357,6 +53888,8 @@ const SlashMenu = Extension.create({
53357
53888
  const cbRect = containingBlock.getBoundingClientRect();
53358
53889
  left2 -= cbRect.left;
53359
53890
  top2 -= cbRect.top;
53891
+ left2 += containingBlock.scrollLeft || 0;
53892
+ top2 += containingBlock.scrollTop || 0;
53360
53893
  } catch (error) {
53361
53894
  console.warn("SlashMenu: Failed to adjust for containing block", error);
53362
53895
  }
@@ -69660,19 +70193,20 @@ const getStarterExtensions = () => {
69660
70193
  ];
69661
70194
  };
69662
70195
  export {
69663
- Attribute as A,
69664
- index$1 as B,
69665
- index as C,
70196
+ Extension as A,
70197
+ Attribute as B,
70198
+ index$1 as C,
69666
70199
  DecorationSet as D,
69667
70200
  Editor as E,
69668
- AnnotatorHelpers as F,
69669
- SectionHelpers as G,
69670
- getAllowedImageDimensions as H,
69671
- CommentsPluginKey as I,
70201
+ index as F,
70202
+ AnnotatorHelpers as G,
70203
+ SectionHelpers as H,
70204
+ getAllowedImageDimensions as I,
70205
+ CommentsPluginKey as J,
69672
70206
  Mark as M,
69673
70207
  Node$1 as N,
69674
70208
  PresentationEditor as P,
69675
- SlashMenuPluginKey as S,
70209
+ SLASH_MENU_HANDLED_FLAG as S,
69676
70210
  TrackChangesBasePluginKey as T,
69677
70211
  _export_sfc as _,
69678
70212
  getQuickFormatList as a,
@@ -69687,18 +70221,18 @@ export {
69687
70221
  redoDepth as j,
69688
70222
  getEditorSurfaceElement as k,
69689
70223
  collectTrackedChangesForContext as l,
69690
- generateRulerDefinition as m,
69691
- clampHandlePosition as n,
69692
- calculateMarginFromHandle as o,
69693
- measureCache as p,
69694
- isHeadless as q,
70224
+ SlashMenuPluginKey as m,
70225
+ generateRulerDefinition as n,
70226
+ clampHandlePosition as o,
70227
+ calculateMarginFromHandle as p,
70228
+ measureCache as q,
69695
70229
  replaceSelectionWithImagePlaceholder as r,
69696
70230
  shouldBypassContextMenu as s,
69697
- getStarterExtensions as t,
70231
+ isHeadless as t,
69698
70232
  useHighContrastMode as u,
69699
- Placeholder as v,
69700
- getRichTextExtensions as w,
69701
- Decoration as x,
70233
+ getStarterExtensions as v,
70234
+ Placeholder as w,
70235
+ getRichTextExtensions as x,
69702
70236
  yUndoPluginKey as y,
69703
- Extension as z
70237
+ Decoration as z
69704
70238
  };