oasis-editor 0.0.148 → 0.0.150

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 (48) hide show
  1. package/dist/{OasisEditorApp-B1b1iJOQ.js → OasisEditorApp-CZNfjaj2.js} +661 -79
  2. package/dist/app/controllers/EditorCommandsController.d.ts +4 -0
  3. package/dist/app/controllers/createCropSession.d.ts +1 -0
  4. package/dist/app/controllers/useEditorImageOperations.d.ts +3 -0
  5. package/dist/app/controllers/useEditorSurfaceEvents.d.ts +1 -0
  6. package/dist/assets/importDocxWorker-Ddoy1WwF.js +12 -0
  7. package/dist/core/commands/builtinCommands.d.ts +1 -1
  8. package/dist/core/commands/image.d.ts +16 -1
  9. package/dist/core/commands/publicCommandTypes.d.ts +11 -1
  10. package/dist/core/commands/text.d.ts +1 -1
  11. package/dist/core/commands/textEditing.d.ts +3 -1
  12. package/dist/core/document/clone.d.ts +2 -1
  13. package/dist/core/math/linear.d.ts +5 -0
  14. package/dist/core/model/index.d.ts +4 -2
  15. package/dist/core/model/runKind.d.ts +3 -0
  16. package/dist/core/model/types/layout.d.ts +2 -0
  17. package/dist/core/model/types/math.d.ts +95 -0
  18. package/dist/core/model/types/nodes.d.ts +4 -0
  19. package/dist/core/model/types/primitives.d.ts +16 -0
  20. package/dist/export/docx/docxTypes.d.ts +3 -1
  21. package/dist/export/docx/text/mathXml.d.ts +3 -0
  22. package/dist/export/pdf/OasisPdfWriter.d.ts +2 -1
  23. package/dist/export/pdf/writer/PdfContentStream.d.ts +3 -1
  24. package/dist/i18n/locales/en.d.ts +13 -0
  25. package/dist/i18n/locales/pt-BR.d.ts +13 -0
  26. package/dist/import/docx/math.d.ts +5 -0
  27. package/dist/import/docx/runs/types.d.ts +2 -1
  28. package/dist/{index-CpZO1PF4.js → index-DgN6KXYw.js} +2405 -1510
  29. package/dist/index.d.ts +1 -0
  30. package/dist/oasis-editor.css +1 -1
  31. package/dist/oasis-editor.js +79 -79
  32. package/dist/oasis-editor.umd.cjs +4 -4
  33. package/dist/plugins/internal/essentialsCapabilities.d.ts +14 -1
  34. package/dist/ui/OasisEditorEditorProps.d.ts +3 -0
  35. package/dist/ui/app/EditorDialogsLayer.d.ts +2 -0
  36. package/dist/ui/app/buildEditorViewProps.d.ts +1 -0
  37. package/dist/ui/app/createAppCommandsController.d.ts +8 -0
  38. package/dist/ui/app/createEditorCommandRuntime.d.ts +9 -0
  39. package/dist/ui/app/createEditorInteractionRuntime.d.ts +4 -0
  40. package/dist/ui/app/essentials/types.d.ts +1 -0
  41. package/dist/ui/app/useEditorDialogs.d.ts +11 -0
  42. package/dist/ui/app/useEditorInteractionWiring.d.ts +1 -0
  43. package/dist/ui/components/Dialogs/EquationDialog.d.ts +10 -0
  44. package/dist/ui/cropGeometry.d.ts +4 -3
  45. package/dist/ui/math/mathPainter.d.ts +10 -0
  46. package/dist/ui/overlays/ImageCropPreviewOverlay.d.ts +16 -0
  47. package/package.json +1 -1
  48. package/dist/assets/importDocxWorker-BLm3QMHu.js +0 -12
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
3
3
  var __publicField = (obj, key2, value) => __defNormalProp(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value);
4
- import { E as EMPTY_PROJECTION_CONTEXT, d as domTextMeasurer, g as getProjectedParagraphBlockHeight, e as estimateTableBlockHeight, p as projectParagraphLayout, a as getPageBodyBottom, b as getPageBodyTop, c as getPageContentWidth, F as FOOTNOTE_MARKER_GUTTER_PX, f as getParagraphText, h as getBlockParagraphs, i as getRunFootnoteReference, l as listReferencedEndnotes, j as getFootnoteDisplayMarker, k as createProjectionContext, m as getDocumentSections, n as getRunField, o as projectBlocksLayout, q as assertNever, r as cloneRun, s as createSignal, t as createEditorStateFromDocument, u as createInitialEditorState, S as STANDARD_FONT_SIZES_PT, v as fontSizePxToPt, w as probeLocalFontFamilies, x as createEditorParagraphFromRuns, y as isInlineObjectRun, z as stylesEqual, A as cloneStyle, B as createEditorStyledRun, C as cloneParagraphList, D as cloneParagraph, G as getParagraphLength, H as getActiveZone, I as getActiveSectionIndex, J as getParagraphs, K as normalizeSelection, L as positionToParagraphOffset, M as cloneParagraphs, N as paragraphOffsetToPosition, O as findParagraphIndex, P as createCollapsedSelection, Q as isSelectionCollapsed, R as setValueStyle, T as setBooleanStyle, U as parseFontSizePtToPx, V as formatFontSizePt, W as setParagraphStyleValue, X as createEditorParagraph, Y as cloneBlocks, Z as resolveDefaultParagraphStyleId, _ as findParagraphTablePathLocation, $ as findParagraphLocation, a0 as resolveTablePath, a1 as buildTableCellLayout, a2 as PT_PER_PX, a3 as createEditorTableCell, a4 as createEditorTableRow, a5 as createEditorTable, a6 as clampPosition, a7 as PX_PER_POINT, a8 as underlineStyleToCssDecorationStyle, a9 as resolveImageSrc, aa as listKindForTag, ab as isParagraphTag, ac as collectInlineRuns, ad as parseParagraphStyle, ae as getRunImage, af as InlineShell, ag as BalloonShell, ah as DocumentShell, ai as findParagraphTableLocation, aj as createMemo, ak as getCaretRectFromSnapshot, al as getParagraphRectFromSnapshot, am as createComponent, an as CaretOverlay, ao as Show, ap as createRenderEffect, aq as style, ar as setStyleProperty, as as setAttribute, at as memo, au as template, av as Button, aw as useI18n, ax as createEffect, ay as TextField, az as Dialog, aA as insert, aB as className, aC as Grid, aD as SelectField, aE as StatusText, aF as ColorField, aG as UNDERLINE_STYLE_OPTIONS, aH as Stack, aI as For, aJ as ToggleChip, aK as FormField, aL as Checkbox, aM as FieldGroup, aN as Tabs, aO as NumberField, aP as parseNumber, aQ as createStore, aR as reconcile, aS as RadioGroup, aT as Radio$1, aU as TextAreaField, aV as COMMON_SYMBOLS, aW as getRecentSymbols, aX as SYMBOL_CATEGORIES, aY as rememberSymbol, aZ as delegateEvents, a_ as Text, a$ as SurfaceButton, b0 as onMount, b1 as onCleanup, b2 as CheckIcon, b3 as use, b4 as PluginUiHost, b5 as OasisEditorEditor, b6 as OasisBrandMark, b7 as setPreciseFontPreference, b8 as setWelcomeSeen, b9 as enablePreciseFontMode, ba as WORD_NS$6, bb as XMLSerializer, bc as DOMParser, bd as WORD14_NS, be as mergeNestedExtensionMarkup, bf as resolveOpcRelationships, bg as parseOpcRelationships, bh as JSZip, bi as normalizeOpcPartPath, bj as OPC_CONTENT_TYPES_PATH, bk as getOpcRelationshipOwnerPath, bl as serializeOpcRelationships, bm as OPC_ROOT_RELATIONSHIPS_PATH, bn as hashDocxPartBytes, bo as parseOpcContentTypes, bp as serializeOpcContentTypes, bq as mergeParagraphPropertiesXmlSource, br as setEditorRunOoxmlSource, bs as mergeRunOoxmlSourceIntoGeneratedXml, bt as mergeTableCellPropertiesXmlSource, bu as mergeTableRowPropertiesXmlSource, bv as mergeTablePropertiesXmlSource, bw as exportEditorDocumentToDocxBlob, bx as exportEditorDocumentToDocx, by as pxToPt$1, bz as resolveFloatingObjectRect, bA as getTextBoxFloatingGeometry, bB as getPresetPathSegments, bC as buildListLabels, bD as lineDashPatternPt, bE as DEFAULT_FONT_SIZE_PX, bF as resolveGradientAxis, bG as isDoubleUnderlineStyle, bH as isWavyUnderlineStyle, bI as underlineStyleLineWidthPx, bJ as WAVY_UNDERLINE_WAVELENGTH_PX, bK as WAVY_UNDERLINE_AMPLITUDE_PX, bL as DOUBLE_UNDERLINE_OFFSET_PX, bM as underlineStyleDashArray, bN as resolveEffectiveParagraphStyle, bO as EMPHASIS_GLYPH, bP as parseHexColorToRgb255, bQ as rgb255ToHex, bR as getImageFloatingGeometry, bS as resolveEffectiveTextStyleForParagraph, bT as textStyleToFontSizePt, bU as resolveTextAlignmentBaselineOffset, bV as TEXT_BASELINE_RATIO, bW as resolveRenderedTextChar, bX as resolveOpenTypeFeatureTags, bY as isLowercaseSmallCapsChar, bZ as resolveDecorationLineY, b_ as DOUBLE_STRIKE_OFFSET_PX, b$ as resolveListLabel, c0 as getListLabelInset, c1 as getAlignedListLabelInset, c2 as getParagraphBorderInsets, c3 as buildSegmentTable, c4 as buildCanvasTableLayout, c5 as resolveCanvasTableWidth, c6 as resolveFloatingTableRect, c7 as paragraphBetweenBorderMatches, c8 as normalizeFamily, c9 as ROBOTO_FONT_FILES, ca as loadFontAsset, cb as getRemotePdfFontFaces, cc as OFFICE_COMPAT_FONT_FAMILIES, cd as BinaryReader, ce as buildSfnt, cf as defaultFontDecoderRegistry, cg as SfntFontProgram, ch as zlibSync, ci as renumberImageCaptionsInDocument, cj as collectPdfFontFamilies, ck as outlineFrom, cl as getPageHeaderZoneTop, cm as getPageColumnRects, cn as findFootnoteReference, co as resolveImporterForFile, cp as roundTo, cq as getDocumentSectionsCanonical, cr as getDocumentParagraphsCanonical, cs as getDocumentParagraphs, ct as getImageCaptionText, cu as isImageCaptionParagraph, cv as updateImageCaptionParagraph, cw as createImageCaptionParagraph, cx as renumberImageCaptionParagraphs, cy as getCaptionSelectionOffset, cz as PX_PER_CM, cA as getDocumentPageSettings, cB as getTableCellContentWidthForParagraph, cC as layoutMetricsEpoch, cD as bumpLayoutMetricsEpoch, cE as createCanvasLayoutSnapshotProvider, cF as on, cG as debounce, cH as unwrap, cI as perfTimer, cJ as prepareDocumentFonts, cK as getRunTextBox, cL as EMU_PER_PX, cM as createEditorDocument, cN as resolveResizedDimensions, cO as axisSignForDirection, cP as clamp$1, cQ as MIN_RESIZE_SIZE_PX, cR as resolveTextBoxRenderHeight, cS as getToolbarStyleState, cT as VERTICAL_HIT_WEIGHT, cU as getCachedCanvasImage, cV as measureParagraphMinContentWidthPx, cW as createSectionBoundaryParagraph, cX as normalizePageSettings, cY as DEFAULT_EDITOR_PAGE_SETTINGS, cZ as markStart, c_ as markEnd, c$ as getParagraphEntries, d0 as getParagraphById, d1 as createEditorFootnote, d2 as createFootnoteReferenceRun, d3 as renumberFootnotes, d4 as iterateFootnoteReferenceRuns, d5 as preciseFontModeVersion, d6 as isPreciseFontModeEnabled, d7 as getRunFieldChar, d8 as getRunFieldInstruction, d9 as getHeadingLevel, da as createEditorRun, db as TWIPS_PER_INCH, dc as PX_PER_INCH, dd as togglePreciseFontMode, de as nextFontSizePt, df as previousFontSizePt, dg as fontSizePtToPx, dh as resolveNamedTextStyle, di as resolveNamedTableStyle, dj as resolveEffectiveTableStyle, dk as createDefaultToolbarPreset, dl as MenuRegistry, dm as createToolbarRegistry, dn as Editor, dp as resolveCommandRef, dq as commandRefName, dr as createOasisEditorClient, ds as createEditorZoom, dt as startLongTaskObserver, du as installGlobalReport, dv as applyStoredPreciseFontPreference, dw as getWelcomeSeen, dx as isLocalFontAccessSupported, dy as EDITOR_SCROLL_PADDING_PX, dz as Toolbar, dA as OasisEditorLoading, dB as I18nProvider, dC as createTranslator, dD as registerDomStatsSurface, dE as createEditorLogger } from "./index-CpZO1PF4.js";
4
+ import { E as EMPTY_PROJECTION_CONTEXT, d as domTextMeasurer, g as getProjectedParagraphBlockHeight, e as estimateTableBlockHeight, p as projectParagraphLayout, a as getPageBodyBottom, b as getPageBodyTop, c as getPageContentWidth, F as FOOTNOTE_MARKER_GUTTER_PX, f as getParagraphText, h as getBlockParagraphs, i as getRunFootnoteReference, l as listReferencedEndnotes, j as getFootnoteDisplayMarker, k as createProjectionContext, m as getDocumentSections, n as getRunField, o as projectBlocksLayout, q as assertNever, r as cloneRun, s as createSignal, t as createEditorStateFromDocument, u as createInitialEditorState, S as STANDARD_FONT_SIZES_PT, v as fontSizePxToPt, w as probeLocalFontFamilies, x as createEditorParagraphFromRuns, y as isInlineObjectRun, z as stylesEqual, A as cloneStyle, B as createEditorStyledRun, C as cloneParagraphList, D as cloneParagraph, G as getParagraphLength, H as getActiveZone, I as getActiveSectionIndex, J as getParagraphs, K as normalizeSelection, L as positionToParagraphOffset, M as cloneParagraphs, N as paragraphOffsetToPosition, O as findParagraphIndex, P as createCollapsedSelection, Q as isSelectionCollapsed, R as MATH_OBJECT_REPLACEMENT, T as setValueStyle, U as setBooleanStyle, V as parseFontSizePtToPx, W as formatFontSizePt, X as setParagraphStyleValue, Y as createEditorParagraph, Z as cloneBlocks, _ as resolveDefaultParagraphStyleId, $ as findParagraphTablePathLocation, a0 as findParagraphLocation, a1 as resolveTablePath, a2 as buildTableCellLayout, a3 as PT_PER_PX, a4 as createEditorTableCell, a5 as createEditorTableRow, a6 as createEditorTable, a7 as clampPosition, a8 as PX_PER_POINT, a9 as underlineStyleToCssDecorationStyle, aa as resolveImageSrc, ab as listKindForTag, ac as isParagraphTag, ad as collectInlineRuns, ae as parseParagraphStyle, af as getRunImage, ag as InlineShell, ah as BalloonShell, ai as DocumentShell, aj as findParagraphTableLocation, ak as createMemo, al as getCaretRectFromSnapshot, am as getParagraphRectFromSnapshot, an as createComponent, ao as CaretOverlay, ap as Show, aq as createRenderEffect, ar as style, as as setStyleProperty, at as setAttribute, au as memo, av as template, aw as Button, ax as useI18n, ay as createEffect, az as TextField, aA as Dialog, aB as insert, aC as className, aD as Grid, aE as SelectField, aF as StatusText, aG as ColorField, aH as UNDERLINE_STYLE_OPTIONS, aI as Stack, aJ as For, aK as ToggleChip, aL as FormField, aM as Checkbox, aN as FieldGroup, aO as Tabs, aP as NumberField, aQ as parseNumber, aR as createStore, aS as reconcile, aT as RadioGroup, aU as Radio$1, aV as TextAreaField, aW as COMMON_SYMBOLS, aX as getRecentSymbols, aY as SYMBOL_CATEGORIES, aZ as rememberSymbol, a_ as delegateEvents, a$ as EMPTY_EDITOR_MATH_EXPRESSION, b0 as serializeLinearMath, b1 as parseLinearMath, b2 as Text, b3 as SurfaceButton, b4 as onMount, b5 as onCleanup, b6 as CheckIcon, b7 as use, b8 as PluginUiHost, b9 as OasisEditorEditor, ba as OasisBrandMark, bb as setPreciseFontPreference, bc as setWelcomeSeen, bd as enablePreciseFontMode, be as WORD_NS$6, bf as XMLSerializer, bg as DOMParser, bh as WORD14_NS, bi as mergeNestedExtensionMarkup, bj as resolveOpcRelationships, bk as parseOpcRelationships, bl as JSZip, bm as normalizeOpcPartPath, bn as OPC_CONTENT_TYPES_PATH, bo as getOpcRelationshipOwnerPath, bp as serializeOpcRelationships, bq as OPC_ROOT_RELATIONSHIPS_PATH, br as hashDocxPartBytes, bs as parseOpcContentTypes, bt as serializeOpcContentTypes, bu as mergeParagraphPropertiesXmlSource, bv as setEditorRunOoxmlSource, bw as mergeRunOoxmlSourceIntoGeneratedXml, bx as mergeTableCellPropertiesXmlSource, by as mergeTableRowPropertiesXmlSource, bz as mergeTablePropertiesXmlSource, bA as exportEditorDocumentToDocxBlob, bB as exportEditorDocumentToDocx, bC as pxToPt$1, bD as resolveFloatingObjectRect, bE as getTextBoxFloatingGeometry, bF as getPresetPathSegments, bG as buildListLabels, bH as lineDashPatternPt, bI as DEFAULT_FONT_SIZE_PX, bJ as resolveGradientAxis, bK as isDoubleUnderlineStyle, bL as isWavyUnderlineStyle, bM as underlineStyleLineWidthPx, bN as WAVY_UNDERLINE_WAVELENGTH_PX, bO as WAVY_UNDERLINE_AMPLITUDE_PX, bP as DOUBLE_UNDERLINE_OFFSET_PX, bQ as underlineStyleDashArray, bR as resolveEffectiveParagraphStyle, bS as EMPHASIS_GLYPH, bT as parseHexColorToRgb255, bU as rgb255ToHex, bV as getImageFloatingGeometry, bW as resolveEffectiveTextStyleForParagraph, bX as textStyleToFontSizePt, bY as mathDisplayText, bZ as TEXT_BASELINE_RATIO, b_ as resolveTextAlignmentBaselineOffset, b$ as resolveRenderedTextChar, c0 as resolveOpenTypeFeatureTags, c1 as isLowercaseSmallCapsChar, c2 as resolveDecorationLineY, c3 as DOUBLE_STRIKE_OFFSET_PX, c4 as resolveListLabel, c5 as getListLabelInset, c6 as getAlignedListLabelInset, c7 as getParagraphBorderInsets, c8 as buildSegmentTable, c9 as buildCanvasTableLayout, ca as resolveCanvasTableWidth, cb as resolveFloatingTableRect, cc as paragraphBetweenBorderMatches, cd as normalizeFamily, ce as ROBOTO_FONT_FILES, cf as loadFontAsset, cg as getRemotePdfFontFaces, ch as OFFICE_COMPAT_FONT_FAMILIES, ci as BinaryReader, cj as buildSfnt, ck as defaultFontDecoderRegistry, cl as SfntFontProgram, cm as zlibSync, cn as renumberImageCaptionsInDocument, co as collectPdfFontFamilies, cp as outlineFrom, cq as getPageHeaderZoneTop, cr as getPageColumnRects, cs as findFootnoteReference, ct as resolveImporterForFile, cu as roundTo, cv as getDocumentSectionsCanonical, cw as getDocumentParagraphsCanonical, cx as getDocumentParagraphs, cy as getImageCaptionText, cz as isImageCaptionParagraph, cA as updateImageCaptionParagraph, cB as createImageCaptionParagraph, cC as renumberImageCaptionParagraphs, cD as getCaptionSelectionOffset, cE as PX_PER_CM, cF as getDocumentPageSettings, cG as getTableCellContentWidthForParagraph, cH as layoutMetricsEpoch, cI as bumpLayoutMetricsEpoch, cJ as createCanvasLayoutSnapshotProvider, cK as on, cL as debounce, cM as unwrap, cN as perfTimer, cO as prepareDocumentFonts, cP as getRunTextBox, cQ as EMU_PER_PX, cR as createEditorDocument, cS as resolveResizedDimensions, cT as axisSignForDirection, cU as clamp$1, cV as MIN_RESIZE_SIZE_PX, cW as resolveTextBoxRenderHeight, cX as getToolbarStyleState, cY as VERTICAL_HIT_WEIGHT, cZ as getCachedCanvasImage, c_ as measureParagraphMinContentWidthPx, c$ as createSectionBoundaryParagraph, d0 as normalizePageSettings, d1 as DEFAULT_EDITOR_PAGE_SETTINGS, d2 as markStart, d3 as markEnd, d4 as getParagraphEntries, d5 as getParagraphById, d6 as createEditorFootnote, d7 as createFootnoteReferenceRun, d8 as renumberFootnotes, d9 as iterateFootnoteReferenceRuns, da as preciseFontModeVersion, db as isPreciseFontModeEnabled, dc as getRunFieldChar, dd as getRunFieldInstruction, de as getHeadingLevel, df as createEditorRun, dg as TWIPS_PER_INCH, dh as PX_PER_INCH, di as togglePreciseFontMode, dj as nextFontSizePt, dk as previousFontSizePt, dl as fontSizePtToPx, dm as resolveNamedTextStyle, dn as resolveNamedTableStyle, dp as resolveEffectiveTableStyle, dq as createDefaultToolbarPreset, dr as MenuRegistry, ds as createToolbarRegistry, dt as Editor, du as resolveCommandRef, dv as commandRefName, dw as createOasisEditorClient, dx as createEditorZoom, dy as startLongTaskObserver, dz as installGlobalReport, dA as applyStoredPreciseFontPreference, dB as getWelcomeSeen, dC as isLocalFontAccessSupported, dD as EDITOR_SCROLL_PADDING_PX, dE as Toolbar, dF as OasisEditorLoading, dG as I18nProvider, dH as createTranslator, dI as registerDomStatsSurface, dJ as createEditorLogger } from "./index-DgN6KXYw.js";
5
5
  function projectHeaderFooterBlocksWithDependencies(blocks, deps, context = {}) {
6
6
  const {
7
7
  pageIndex,
@@ -26999,6 +26999,7 @@ function createEditorFocusController() {
26999
26999
  function createEditorDialogs() {
27000
27000
  const [newDocumentDialog, setNewDocumentDialog] = createSignal({ isOpen: false });
27001
27001
  const [symbolDialog, setSymbolDialog] = createSignal({ isOpen: false });
27002
+ const [equationDialog, setEquationDialog] = createSignal({ isOpen: false });
27002
27003
  const [linkDialog, setLinkDialog] = createSignal({
27003
27004
  isOpen: false,
27004
27005
  initialHref: ""
@@ -27132,6 +27133,8 @@ function createEditorDialogs() {
27132
27133
  setNewDocumentDialog,
27133
27134
  symbolDialog,
27134
27135
  setSymbolDialog,
27136
+ equationDialog,
27137
+ setEquationDialog,
27135
27138
  linkDialog,
27136
27139
  setLinkDialog,
27137
27140
  imageAltDialog,
@@ -27312,6 +27315,7 @@ const MERGE_KEYS = {
27312
27315
  imageAlt: "imageAlt",
27313
27316
  imageCaption: "imageCaption",
27314
27317
  imageResize: "imageResize",
27318
+ imageCrop: "imageCrop",
27315
27319
  layoutWrapPolygon: "layoutWrapPolygon",
27316
27320
  specialIndent: "specialIndent",
27317
27321
  paraBorders: "paraBorders",
@@ -28113,6 +28117,48 @@ function insertTextAtSelection(state, text, styleOverride) {
28113
28117
  )
28114
28118
  );
28115
28119
  }
28120
+ function insertMathAtSelection(state, expression) {
28121
+ const collapsedState = isSelectionCollapsed(state.selection) ? state : deleteSelectionRange(state);
28122
+ const { paragraph, index, offset } = getFocusParagraph(collapsedState);
28123
+ const styles = getStyleAtOffset(paragraph, offset);
28124
+ const insertedRun = {
28125
+ id: `run:${Math.random().toString(36).slice(2, 9)}`,
28126
+ text: MATH_OBJECT_REPLACEMENT,
28127
+ styles,
28128
+ kind: "math",
28129
+ math: expression
28130
+ };
28131
+ const nextParagraph = insertRunsAtOffset(paragraph, offset, [insertedRun]);
28132
+ const paragraphs = getParagraphs(collapsedState).map(
28133
+ (candidate, candidateIndex) => candidateIndex === index ? nextParagraph : candidate
28134
+ );
28135
+ return cloneStateWithParagraphs(
28136
+ collapsedState,
28137
+ paragraphs,
28138
+ withSelection(
28139
+ paragraphOffsetToPosition(
28140
+ nextParagraph,
28141
+ offset + MATH_OBJECT_REPLACEMENT.length
28142
+ )
28143
+ )
28144
+ );
28145
+ }
28146
+ function updateMathRun(state, runId, expression) {
28147
+ let changed = false;
28148
+ const paragraphs = getParagraphs(state).map(
28149
+ (paragraph) => {
28150
+ let paragraphChanged = false;
28151
+ const runs = paragraph.runs.map((run) => {
28152
+ if (run.id !== runId || run.kind !== "math") return run;
28153
+ changed = true;
28154
+ paragraphChanged = true;
28155
+ return { ...run, math: expression, text: MATH_OBJECT_REPLACEMENT };
28156
+ });
28157
+ return paragraphChanged ? { ...paragraph, runs } : paragraph;
28158
+ }
28159
+ );
28160
+ return changed ? cloneStateWithParagraphs(state, paragraphs, state.selection) : state;
28161
+ }
28116
28162
  function insertPlainTextAtSelection(state, text, styleOverride) {
28117
28163
  if (text.length === 0) {
28118
28164
  return state;
@@ -31757,14 +31803,14 @@ function DropCaret(props) {
31757
31803
  })
31758
31804
  });
31759
31805
  }
31760
- var _tmpl$$h = /* @__PURE__ */ template(`<div class=oasis-editor-table-resize-guide>`), _tmpl$2$6 = /* @__PURE__ */ template(`<div class=oasis-editor-table-resize-outline>`), _tmpl$3$3 = /* @__PURE__ */ template(`<img class=oasis-editor-image-ghost>`), _tmpl$4$2 = /* @__PURE__ */ template(`<div class=oasis-editor-table-ghost>`);
31806
+ var _tmpl$$i = /* @__PURE__ */ template(`<div class=oasis-editor-table-resize-guide>`), _tmpl$2$7 = /* @__PURE__ */ template(`<div class=oasis-editor-table-resize-outline>`), _tmpl$3$3 = /* @__PURE__ */ template(`<img class=oasis-editor-image-ghost>`), _tmpl$4$2 = /* @__PURE__ */ template(`<div class=oasis-editor-table-ghost>`);
31761
31807
  function EditorDragLayers(props) {
31762
31808
  return [createComponent(Show, {
31763
31809
  get when() {
31764
31810
  return props.tableResize.resizing();
31765
31811
  },
31766
31812
  children: (resizing) => (() => {
31767
- var _el$ = _tmpl$$h();
31813
+ var _el$ = _tmpl$$i();
31768
31814
  createRenderEffect((_p$) => {
31769
31815
  var _v$ = !!(resizing().type === "column"), _v$2 = !!(resizing().type === "row"), _v$3 = {
31770
31816
  ...resizing().type === "column" ? {
@@ -31795,7 +31841,7 @@ function EditorDragLayers(props) {
31795
31841
  return props.tableCornerResize.previewRect();
31796
31842
  },
31797
31843
  children: (rect) => (() => {
31798
- var _el$2 = _tmpl$2$6();
31844
+ var _el$2 = _tmpl$2$7();
31799
31845
  createRenderEffect((_p$) => {
31800
31846
  var _v$4 = `${rect().left}px`, _v$5 = `${rect().top}px`, _v$6 = `${rect().width}px`, _v$7 = `${rect().height}px`;
31801
31847
  _v$4 !== _p$.e && setStyleProperty(_el$2, "left", _p$.e = _v$4);
@@ -32435,11 +32481,11 @@ function useFontDialogController(props) {
32435
32481
  handleApply
32436
32482
  };
32437
32483
  }
32438
- var _tmpl$$g = /* @__PURE__ */ template(`<div>`);
32484
+ var _tmpl$$h = /* @__PURE__ */ template(`<div>`);
32439
32485
  function FontPreview(props) {
32440
32486
  const t = useI18n();
32441
32487
  return (() => {
32442
- var _el$ = _tmpl$$g();
32488
+ var _el$ = _tmpl$$h();
32443
32489
  insert(_el$, () => t("dialog.font.previewText"));
32444
32490
  createRenderEffect((_p$) => {
32445
32491
  var _v$ = props.class ?? "oasis-editor-dialog-preview", _v$2 = props.testId, _v$3 = props.style;
@@ -32455,7 +32501,7 @@ function FontPreview(props) {
32455
32501
  return _el$;
32456
32502
  })();
32457
32503
  }
32458
- var _tmpl$$f = /* @__PURE__ */ template(`<div class="oasis-editor-font-dialog-panel oasis-editor-font-dialog-font-panel">`);
32504
+ var _tmpl$$g = /* @__PURE__ */ template(`<div class="oasis-editor-font-dialog-panel oasis-editor-font-dialog-font-panel">`);
32459
32505
  function FontTab(props) {
32460
32506
  const t = useI18n();
32461
32507
  const {
@@ -32545,7 +32591,7 @@ function FontTab(props) {
32545
32591
  onChange: (checked) => ctrl.updateFontTab("hidden", checked)
32546
32592
  }];
32547
32593
  return (() => {
32548
- var _el$ = _tmpl$$f();
32594
+ var _el$ = _tmpl$$g();
32549
32595
  insert(_el$, createComponent(Grid, {
32550
32596
  container: true,
32551
32597
  spacing: 1.5,
@@ -32879,14 +32925,14 @@ function FontTab(props) {
32879
32925
  return _el$;
32880
32926
  })();
32881
32927
  }
32882
- var _tmpl$$e = /* @__PURE__ */ template(`<div class=oasis-editor-font-dialog-kerning-line>`), _tmpl$2$5 = /* @__PURE__ */ template(`<div class="oasis-editor-font-dialog-panel oasis-editor-font-dialog-advanced-panel">`);
32928
+ var _tmpl$$f = /* @__PURE__ */ template(`<div class=oasis-editor-font-dialog-kerning-line>`), _tmpl$2$6 = /* @__PURE__ */ template(`<div class="oasis-editor-font-dialog-panel oasis-editor-font-dialog-advanced-panel">`);
32883
32929
  function AdvancedFontTab(props) {
32884
32930
  const t = useI18n();
32885
32931
  const {
32886
32932
  ctrl
32887
32933
  } = props;
32888
32934
  return (() => {
32889
- var _el$ = _tmpl$2$5();
32935
+ var _el$ = _tmpl$2$6();
32890
32936
  insert(_el$, createComponent(FieldGroup, {
32891
32937
  "class": "oasis-editor-font-dialog-fieldset",
32892
32938
  get legend() {
@@ -33037,7 +33083,7 @@ function AdvancedFontTab(props) {
33037
33083
  }), createComponent(Grid, {
33038
33084
  size: 12,
33039
33085
  get children() {
33040
- var _el$2 = _tmpl$$e();
33086
+ var _el$2 = _tmpl$$f();
33041
33087
  insert(_el$2, createComponent(Checkbox, {
33042
33088
  "class": "oasis-editor-font-dialog-kerning-toggle",
33043
33089
  get label() {
@@ -33317,7 +33363,7 @@ function FontDialog(props) {
33317
33363
  }
33318
33364
  });
33319
33365
  }
33320
- var _tmpl$$d = /* @__PURE__ */ template(`<div class=oasis-editor-tab-stops><div class=oasis-editor-tab-stops-actions>`), _tmpl$2$4 = /* @__PURE__ */ template(`<div class=oasis-editor-dialog-footer-split><div class=oasis-editor-dialog-footer-start></div><div class=oasis-editor-dialog-footer-end>`);
33366
+ var _tmpl$$e = /* @__PURE__ */ template(`<div class=oasis-editor-tab-stops><div class=oasis-editor-tab-stops-actions>`), _tmpl$2$5 = /* @__PURE__ */ template(`<div class=oasis-editor-dialog-footer-split><div class=oasis-editor-dialog-footer-start></div><div class=oasis-editor-dialog-footer-end>`);
33321
33367
  function toDraft(stop) {
33322
33368
  return {
33323
33369
  position: stop.position,
@@ -33401,7 +33447,7 @@ function TabStopsDialog(props) {
33401
33447
  },
33402
33448
  get footer() {
33403
33449
  return (() => {
33404
- var _el$3 = _tmpl$2$4(), _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling;
33450
+ var _el$3 = _tmpl$2$5(), _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling;
33405
33451
  insert(_el$4, createComponent(Button, {
33406
33452
  variant: "secondary",
33407
33453
  onClick: () => {
@@ -33434,7 +33480,7 @@ function TabStopsDialog(props) {
33434
33480
  })();
33435
33481
  },
33436
33482
  get children() {
33437
- var _el$ = _tmpl$$d(), _el$2 = _el$.firstChild;
33483
+ var _el$ = _tmpl$$e(), _el$2 = _el$.firstChild;
33438
33484
  insert(_el$, createComponent(For, {
33439
33485
  get each() {
33440
33486
  return stops();
@@ -33788,7 +33834,7 @@ function useParagraphDialogController(props) {
33788
33834
  handleSetDefault
33789
33835
  };
33790
33836
  }
33791
- var _tmpl$$c = /* @__PURE__ */ template(`<div class=oasis-editor-paragraph-dialog-panel>`), _tmpl$2$3 = /* @__PURE__ */ template(`<div class=oasis-editor-dialog-preview data-testid=editor-paragraph-dialog-preview>`), _tmpl$3$2 = /* @__PURE__ */ template(`<div class=oasis-editor-dialog-footer-split><div class=oasis-editor-dialog-footer-start></div><div class=oasis-editor-dialog-footer-end>`);
33837
+ var _tmpl$$d = /* @__PURE__ */ template(`<div class=oasis-editor-paragraph-dialog-panel>`), _tmpl$2$4 = /* @__PURE__ */ template(`<div class=oasis-editor-dialog-preview data-testid=editor-paragraph-dialog-preview>`), _tmpl$3$2 = /* @__PURE__ */ template(`<div class=oasis-editor-dialog-footer-split><div class=oasis-editor-dialog-footer-start></div><div class=oasis-editor-dialog-footer-end>`);
33792
33838
  function ParagraphDialog(props) {
33793
33839
  const t = useI18n();
33794
33840
  const [tabsDialogOpen, setTabsDialogOpen] = createSignal(false);
@@ -33895,7 +33941,7 @@ function ParagraphDialog(props) {
33895
33941
  }
33896
33942
  });
33897
33943
  const indentsAndSpacingPanel = (() => {
33898
- var _el$ = _tmpl$$c();
33944
+ var _el$ = _tmpl$$d();
33899
33945
  insert(_el$, createComponent(FieldGroup, {
33900
33946
  "class": "oasis-editor-dialog-fieldset",
33901
33947
  get legend() {
@@ -34365,7 +34411,7 @@ function ParagraphDialog(props) {
34365
34411
  return _el$;
34366
34412
  })();
34367
34413
  const lineAndPageBreaksPanel = (() => {
34368
- var _el$2 = _tmpl$$c();
34414
+ var _el$2 = _tmpl$$d();
34369
34415
  insert(_el$2, createComponent(FieldGroup, {
34370
34416
  "class": "oasis-editor-dialog-fieldset",
34371
34417
  get legend() {
@@ -34495,7 +34541,7 @@ function ParagraphDialog(props) {
34495
34541
  return t("paragraph.preview");
34496
34542
  },
34497
34543
  get children() {
34498
- var _el$3 = _tmpl$2$3();
34544
+ var _el$3 = _tmpl$2$4();
34499
34545
  insert(_el$3, () => t("paragraph.previewText"));
34500
34546
  createRenderEffect((_$p) => style(_el$3, previewStyle(), _$p));
34501
34547
  return _el$3;
@@ -34718,13 +34764,13 @@ function NumField(label, value, setter, testId, disabled = false, allowNegative
34718
34764
  "data-testid": testId
34719
34765
  });
34720
34766
  }
34721
- var _tmpl$$b = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-panel>`);
34767
+ var _tmpl$$c = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-panel>`);
34722
34768
  function TableTabPanel(props) {
34723
34769
  const t = useI18n();
34724
34770
  const form = () => props.ctrl.form;
34725
34771
  const set = props.ctrl.set;
34726
34772
  return (() => {
34727
- var _el$ = _tmpl$$b();
34773
+ var _el$ = _tmpl$$c();
34728
34774
  insert(_el$, createComponent(FieldGroup, {
34729
34775
  "class": "oasis-editor-font-dialog-fieldset",
34730
34776
  get legend() {
@@ -35030,13 +35076,13 @@ function TableTabPanel(props) {
35030
35076
  return _el$;
35031
35077
  })();
35032
35078
  }
35033
- var _tmpl$$a = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-panel>`);
35079
+ var _tmpl$$b = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-panel>`);
35034
35080
  function RowTabPanel(props) {
35035
35081
  const t = useI18n();
35036
35082
  const form = () => props.ctrl.form;
35037
35083
  const set = props.ctrl.set;
35038
35084
  return (() => {
35039
- var _el$ = _tmpl$$a();
35085
+ var _el$ = _tmpl$$b();
35040
35086
  insert(_el$, createComponent(Grid, {
35041
35087
  container: true,
35042
35088
  spacing: 1.5,
@@ -35119,13 +35165,13 @@ function RowTabPanel(props) {
35119
35165
  return _el$;
35120
35166
  })();
35121
35167
  }
35122
- var _tmpl$$9 = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-panel>`);
35168
+ var _tmpl$$a = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-panel>`);
35123
35169
  function ColumnTabPanel(props) {
35124
35170
  const t = useI18n();
35125
35171
  const form = () => props.ctrl.form;
35126
35172
  const set = props.ctrl.set;
35127
35173
  return (() => {
35128
- var _el$ = _tmpl$$9();
35174
+ var _el$ = _tmpl$$a();
35129
35175
  insert(_el$, createComponent(Grid, {
35130
35176
  container: true,
35131
35177
  spacing: 1.5,
@@ -35144,7 +35190,7 @@ function ColumnTabPanel(props) {
35144
35190
  return _el$;
35145
35191
  })();
35146
35192
  }
35147
- var _tmpl$$8 = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-cell-preview data-testid=editor-table-properties-cell-preview>`), _tmpl$2$2 = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-panel>`);
35193
+ var _tmpl$$9 = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-cell-preview data-testid=editor-table-properties-cell-preview>`), _tmpl$2$3 = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-panel>`);
35148
35194
  function CellTabPanel(props) {
35149
35195
  const t = useI18n();
35150
35196
  const form = () => props.ctrl.form;
@@ -35162,7 +35208,7 @@ function CellTabPanel(props) {
35162
35208
  });
35163
35209
  const borderDisabled = () => form().borderStyle === "none";
35164
35210
  return (() => {
35165
- var _el$ = _tmpl$2$2();
35211
+ var _el$ = _tmpl$2$3();
35166
35212
  insert(_el$, createComponent(Grid, {
35167
35213
  container: true,
35168
35214
  spacing: 1.5,
@@ -35549,7 +35595,7 @@ function CellTabPanel(props) {
35549
35595
  })];
35550
35596
  }
35551
35597
  }), (() => {
35552
- var _el$2 = _tmpl$$8();
35598
+ var _el$2 = _tmpl$$9();
35553
35599
  createRenderEffect((_$p) => style(_el$2, borderPreview(), _$p));
35554
35600
  return _el$2;
35555
35601
  })()];
@@ -35558,13 +35604,13 @@ function CellTabPanel(props) {
35558
35604
  return _el$;
35559
35605
  })();
35560
35606
  }
35561
- var _tmpl$$7 = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-panel>`);
35607
+ var _tmpl$$8 = /* @__PURE__ */ template(`<div class=oasis-editor-table-properties-panel>`);
35562
35608
  function AltTextTabPanel(props) {
35563
35609
  const t = useI18n();
35564
35610
  const form = () => props.ctrl.form;
35565
35611
  const set = props.ctrl.set;
35566
35612
  return (() => {
35567
- var _el$ = _tmpl$$7();
35613
+ var _el$ = _tmpl$$8();
35568
35614
  insert(_el$, createComponent(TextField, {
35569
35615
  get label() {
35570
35616
  return t("table.altTitle");
@@ -35676,7 +35722,7 @@ function TablePropertiesDialog(props) {
35676
35722
  }
35677
35723
  });
35678
35724
  }
35679
- var _tmpl$$6 = /* @__PURE__ */ template(`<p data-testid=editor-new-document-message>`);
35725
+ var _tmpl$$7 = /* @__PURE__ */ template(`<p data-testid=editor-new-document-message>`);
35680
35726
  function NewDocumentConfirmationDialog(props) {
35681
35727
  const t = useI18n();
35682
35728
  return createComponent(Dialog, {
@@ -35710,13 +35756,13 @@ function NewDocumentConfirmationDialog(props) {
35710
35756
  });
35711
35757
  },
35712
35758
  get children() {
35713
- var _el$ = _tmpl$$6();
35759
+ var _el$ = _tmpl$$7();
35714
35760
  insert(_el$, () => t("dialog.newDocument.message"));
35715
35761
  return _el$;
35716
35762
  }
35717
35763
  });
35718
35764
  }
35719
- var _tmpl$$5 = /* @__PURE__ */ template(`<div class=oasis-editor-symbol-dialog-controls><label class=oasis-editor-symbol-dialog-field><span></span><select data-testid=editor-symbol-dialog-font></select></label><label class=oasis-editor-symbol-dialog-field><span></span><select data-testid=editor-symbol-dialog-category><option value=all>`), _tmpl$2$1 = /* @__PURE__ */ template(`<div class=oasis-editor-symbol-dialog-recent><span></span><div class=oasis-editor-symbol-dialog-recent-list>`), _tmpl$3$1 = /* @__PURE__ */ template(`<div class=oasis-editor-symbol-dialog-layout><div class=oasis-editor-symbol-dialog-grid role=grid></div><aside class=oasis-editor-symbol-dialog-preview><span class=oasis-editor-symbol-dialog-preview-label></span><span class=oasis-editor-symbol-dialog-preview-character data-testid=editor-symbol-dialog-preview></span><label class=oasis-editor-symbol-dialog-field><span></span><input data-testid=editor-symbol-dialog-code></label><p class=oasis-editor-symbol-dialog-help>`), _tmpl$4$1 = /* @__PURE__ */ template(`<option>`), _tmpl$5$1 = /* @__PURE__ */ template(`<button type=button class=oasis-editor-symbol-dialog-tile>`), _tmpl$6$1 = /* @__PURE__ */ template(`<button type=button class=oasis-editor-symbol-dialog-tile role=gridcell>`);
35765
+ var _tmpl$$6 = /* @__PURE__ */ template(`<div class=oasis-editor-symbol-dialog-controls><label class=oasis-editor-symbol-dialog-field><span></span><select data-testid=editor-symbol-dialog-font></select></label><label class=oasis-editor-symbol-dialog-field><span></span><select data-testid=editor-symbol-dialog-category><option value=all>`), _tmpl$2$2 = /* @__PURE__ */ template(`<div class=oasis-editor-symbol-dialog-recent><span></span><div class=oasis-editor-symbol-dialog-recent-list>`), _tmpl$3$1 = /* @__PURE__ */ template(`<div class=oasis-editor-symbol-dialog-layout><div class=oasis-editor-symbol-dialog-grid role=grid></div><aside class=oasis-editor-symbol-dialog-preview><span class=oasis-editor-symbol-dialog-preview-label></span><span class=oasis-editor-symbol-dialog-preview-character data-testid=editor-symbol-dialog-preview></span><label class=oasis-editor-symbol-dialog-field><span></span><input data-testid=editor-symbol-dialog-code></label><p class=oasis-editor-symbol-dialog-help>`), _tmpl$4$1 = /* @__PURE__ */ template(`<option>`), _tmpl$5$1 = /* @__PURE__ */ template(`<button type=button class=oasis-editor-symbol-dialog-tile>`), _tmpl$6$1 = /* @__PURE__ */ template(`<button type=button class=oasis-editor-symbol-dialog-tile role=gridcell>`);
35720
35766
  const FONT_OPTIONS = ["Segoe UI Symbol", "Arial Unicode MS", "Cambria Math", "Times New Roman"];
35721
35767
  function SymbolDialog(props) {
35722
35768
  const t = useI18n();
@@ -35792,7 +35838,7 @@ function SymbolDialog(props) {
35792
35838
  },
35793
35839
  get children() {
35794
35840
  return [(() => {
35795
- var _el$ = _tmpl$$5(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$2.nextSibling, _el$6 = _el$5.firstChild, _el$7 = _el$6.nextSibling, _el$8 = _el$7.firstChild;
35841
+ var _el$ = _tmpl$$6(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.nextSibling, _el$5 = _el$2.nextSibling, _el$6 = _el$5.firstChild, _el$7 = _el$6.nextSibling, _el$8 = _el$7.firstChild;
35796
35842
  insert(_el$3, () => t("dialog.symbol.font"));
35797
35843
  _el$4.addEventListener("change", (event) => {
35798
35844
  setFont(event.currentTarget.value);
@@ -35830,7 +35876,7 @@ function SymbolDialog(props) {
35830
35876
  return recentSymbols().length > 0;
35831
35877
  },
35832
35878
  get children() {
35833
- var _el$1 = _tmpl$2$1(), _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling;
35879
+ var _el$1 = _tmpl$2$2(), _el$10 = _el$1.firstChild, _el$11 = _el$10.nextSibling;
35834
35880
  insert(_el$10, () => t("dialog.symbol.recent"));
35835
35881
  insert(_el$11, createComponent(For, {
35836
35882
  get each() {
@@ -35902,6 +35948,75 @@ function SymbolDialog(props) {
35902
35948
  });
35903
35949
  }
35904
35950
  delegateEvents(["input", "click", "dblclick"]);
35951
+ var _tmpl$$5 = /* @__PURE__ */ template(`<div class=oasis-editor-equation-editor><div class=oasis-editor-equation-palette></div><label class=oasis-editor-equation-linear><span></span><textarea data-testid=editor-equation-linear></textarea></label><div class=oasis-editor-equation-preview aria-live=polite data-testid=editor-equation-preview>`), _tmpl$2$1 = /* @__PURE__ */ template(`<button type=button data-testid=editor-equation-template>`);
35952
+ const TEMPLATES = [["\\frac{□}{□}", "\\frac{a}{b}"], ["\\sqrt{□}", "\\sqrt{x}"], ["x^□", "x^{2}"], ["x_□", "x_{i}"], ["∑", "\\sum_{i=1}^{n} i"], ["∫", "∫ f(x) dx"], ["[ ]", "(a+b)"], ["[a b]", "\\matrix{a & b \\ c & d}"]];
35953
+ function EquationDialog(props) {
35954
+ const t = useI18n();
35955
+ const [linear, setLinear] = createSignal("");
35956
+ const [expression, setExpression] = createSignal(EMPTY_EDITOR_MATH_EXPRESSION);
35957
+ createEffect(() => {
35958
+ if (!props.isOpen) return;
35959
+ const initial = props.initial ?? EMPTY_EDITOR_MATH_EXPRESSION;
35960
+ setExpression(initial);
35961
+ setLinear(serializeLinearMath(initial));
35962
+ });
35963
+ const updateLinear = (value) => {
35964
+ setLinear(value);
35965
+ setExpression(parseLinearMath(value));
35966
+ };
35967
+ return createComponent(Dialog, {
35968
+ get isOpen() {
35969
+ return props.isOpen;
35970
+ },
35971
+ get title() {
35972
+ return t("dialog.equation.title");
35973
+ },
35974
+ get onClose() {
35975
+ return props.onClose;
35976
+ },
35977
+ size: "lg",
35978
+ closeOnOverlayClick: false,
35979
+ "class": "oasis-editor-equation-dialog",
35980
+ get footer() {
35981
+ return [createComponent(Button, {
35982
+ variant: "secondary",
35983
+ get onClick() {
35984
+ return props.onClose;
35985
+ },
35986
+ get children() {
35987
+ return t("generic.cancel");
35988
+ }
35989
+ }), createComponent(Button, {
35990
+ variant: "primary",
35991
+ onClick: () => props.onApply(expression()),
35992
+ "data-testid": "editor-equation-apply",
35993
+ get children() {
35994
+ return t("dialog.equation.insert");
35995
+ }
35996
+ })];
35997
+ },
35998
+ get children() {
35999
+ var _el$ = _tmpl$$5(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$6 = _el$3.nextSibling;
36000
+ insert(_el$2, createComponent(For, {
36001
+ each: TEMPLATES,
36002
+ children: ([label, value]) => (() => {
36003
+ var _el$7 = _tmpl$2$1();
36004
+ _el$7.$$click = () => updateLinear(value);
36005
+ insert(_el$7, label);
36006
+ return _el$7;
36007
+ })()
36008
+ }));
36009
+ insert(_el$4, () => t("dialog.equation.linear"));
36010
+ _el$5.$$input = (event) => updateLinear(event.currentTarget.value);
36011
+ setAttribute(_el$5, "spellcheck", false);
36012
+ insert(_el$6, () => serializeLinearMath(expression()) || t("dialog.equation.empty"));
36013
+ createRenderEffect(() => setAttribute(_el$2, "aria-label", t("dialog.equation.structures")));
36014
+ createRenderEffect(() => _el$5.value = linear());
36015
+ return _el$;
36016
+ }
36017
+ });
36018
+ }
36019
+ delegateEvents(["input", "click"]);
35905
36020
  var _tmpl$$4 = /* @__PURE__ */ template(`<div class=oasis-editor-find-replace-dialog><div class=oasis-editor-fr-header></div><div class=oasis-editor-fr-body><div class=oasis-editor-fr-input-group><div class=oasis-editor-fr-input-wrapper></div></div><div class=oasis-editor-fr-input-group>`);
35906
36021
  function FindReplaceDialog(props) {
35907
36022
  const t = useI18n();
@@ -36220,7 +36335,9 @@ function EditorDialogsLayer(props) {
36220
36335
  newDocumentDialog,
36221
36336
  setNewDocumentDialog,
36222
36337
  symbolDialog,
36223
- setSymbolDialog
36338
+ setSymbolDialog,
36339
+ equationDialog,
36340
+ setEquationDialog
36224
36341
  } = props.dialogs;
36225
36342
  return [createComponent(NewDocumentConfirmationDialog, {
36226
36343
  get isOpen() {
@@ -36254,6 +36371,25 @@ function EditorDialogsLayer(props) {
36254
36371
  });
36255
36372
  props.insertSymbol(symbol, fontFamily);
36256
36373
  }
36374
+ }), createComponent(EquationDialog, {
36375
+ get isOpen() {
36376
+ return equationDialog().isOpen;
36377
+ },
36378
+ get initial() {
36379
+ return equationDialog().initial;
36380
+ },
36381
+ onClose: () => {
36382
+ setEquationDialog({
36383
+ isOpen: false
36384
+ });
36385
+ props.focusInput();
36386
+ },
36387
+ onApply: (expression) => {
36388
+ setEquationDialog({
36389
+ isOpen: false
36390
+ });
36391
+ props.applyEquation(expression, equationDialog().targetRunId);
36392
+ }
36257
36393
  }), createComponent(LinkDialog, {
36258
36394
  get isOpen() {
36259
36395
  return linkDialog().isOpen;
@@ -36456,6 +36592,7 @@ function buildEditorViewProps(ctx) {
36456
36592
  onTextBoxResizeHandleMouseDown: surface.handleTextBoxResizeHandleMouseDown,
36457
36593
  onImageRotateHandleMouseDown: surface.handleImageRotateHandleMouseDown,
36458
36594
  onImageCropHandleMouseDown: surface.handleImageCropHandleMouseDown,
36595
+ onImageCropBodyMouseDown: surface.handleImageCropBodyMouseDown,
36459
36596
  onTextBoxRotateHandleMouseDown: surface.handleTextBoxRotateHandleMouseDown,
36460
36597
  onTableDragHandleMouseDown: surface.tableDrag.handleMouseDown,
36461
36598
  onTableCornerResizeHandleMouseDown: surface.tableCornerResize.handleMouseDown,
@@ -40835,40 +40972,133 @@ async function registerPdfImageRun(writer, document2, image) {
40835
40972
  perWriter.set(resolvedSrc, preparedPromise);
40836
40973
  return preparedPromise;
40837
40974
  }
40975
+ function transformPath(segments, x, y, width, height, rotation) {
40976
+ if (!rotation) return segments;
40977
+ const cx = x + width / 2;
40978
+ const cy = y + height / 2;
40979
+ const radians = rotation * Math.PI / 180;
40980
+ const rotate = (px, py) => ({
40981
+ x: cx + (px - cx) * Math.cos(radians) - (py - cy) * Math.sin(radians),
40982
+ y: cy + (px - cx) * Math.sin(radians) + (py - cy) * Math.cos(radians)
40983
+ });
40984
+ return segments.map((segment) => {
40985
+ if (segment.type === "close") return segment;
40986
+ if (segment.type === "cubic") {
40987
+ const p1 = rotate(segment.x1, segment.y1);
40988
+ const p2 = rotate(segment.x2, segment.y2);
40989
+ const p3 = rotate(segment.x, segment.y);
40990
+ return {
40991
+ type: "cubic",
40992
+ x1: p1.x,
40993
+ y1: p1.y,
40994
+ x2: p2.x,
40995
+ y2: p2.y,
40996
+ x: p3.x,
40997
+ y: p3.y
40998
+ };
40999
+ }
41000
+ const p = rotate(segment.x, segment.y);
41001
+ return { type: segment.type, x: p.x, y: p.y };
41002
+ });
41003
+ }
40838
41004
  async function drawImageObject(writer, pageIndex, document2, image, x, y, width, height) {
41005
+ var _a;
40839
41006
  const resourceName = await registerPdfImageRun(writer, document2, image);
40840
41007
  if (!resourceName) {
40841
41008
  return;
40842
41009
  }
40843
- writer.drawImage(pageIndex, {
40844
- resourceName,
41010
+ const sourceWidth = image.intrinsicWidth ?? image.width;
41011
+ const sourceHeight = image.intrinsicHeight ?? image.height;
41012
+ const sourceRatio = sourceWidth / Math.max(1, sourceHeight);
41013
+ const frameRatio = width / Math.max(1, height);
41014
+ let drawX = x;
41015
+ let drawY = y;
41016
+ let drawWidth = width;
41017
+ let drawHeight = height;
41018
+ if (image.cropFit === "fit" && sourceRatio > 0) {
41019
+ if (sourceRatio > frameRatio) {
41020
+ drawHeight = width / sourceRatio;
41021
+ drawY += (height - drawHeight) / 2;
41022
+ } else {
41023
+ drawWidth = height * sourceRatio;
41024
+ drawX += (width - drawWidth) / 2;
41025
+ }
41026
+ }
41027
+ const effectiveCrop = image.cropFit === "fill" && !image.crop ? (() => {
41028
+ if (sourceRatio > frameRatio) {
41029
+ const visible = frameRatio / sourceRatio;
41030
+ const trim = Math.max(0, (1 - visible) / 2);
41031
+ return { left: trim, right: trim };
41032
+ }
41033
+ if (sourceRatio < frameRatio) {
41034
+ const visible = sourceRatio / frameRatio;
41035
+ const trim = Math.max(0, (1 - visible) / 2);
41036
+ return { top: trim, bottom: trim };
41037
+ }
41038
+ return void 0;
41039
+ })() : image.crop;
41040
+ const shape = (_a = image.cropShape) == null ? void 0 : _a.preset;
41041
+ const shapePath = shape ? transformPath(
41042
+ getPresetPathSegments(shape, x, y, width, height),
40845
41043
  x,
40846
41044
  y,
40847
41045
  width,
40848
41046
  height,
40849
- rotation: image.rotation,
40850
- crop: image.crop
41047
+ image.rotation ?? 0
41048
+ ) : null;
41049
+ const rotateFitAroundFrame = image.cropFit === "fit" && Boolean(image.rotation);
41050
+ if (shapePath) {
41051
+ writer.saveGraphicsState(pageIndex);
41052
+ writer.clipPath(pageIndex, shapePath);
41053
+ }
41054
+ if (rotateFitAroundFrame) {
41055
+ writer.saveGraphicsState(pageIndex);
41056
+ writer.rotateAbout(
41057
+ pageIndex,
41058
+ x + width / 2,
41059
+ y + height / 2,
41060
+ image.rotation ?? 0
41061
+ );
41062
+ }
41063
+ writer.drawImage(pageIndex, {
41064
+ resourceName,
41065
+ x: drawX,
41066
+ y: drawY,
41067
+ width: drawWidth,
41068
+ height: drawHeight,
41069
+ rotation: rotateFitAroundFrame ? void 0 : image.rotation,
41070
+ crop: effectiveCrop
40851
41071
  });
41072
+ if (rotateFitAroundFrame) writer.restoreGraphicsState(pageIndex);
41073
+ if (shapePath) writer.restoreGraphicsState(pageIndex);
40852
41074
  const border = image.border;
40853
41075
  if (!border) {
40854
41076
  return;
40855
41077
  }
40856
41078
  const rotation = image.rotation;
40857
- if (rotation) {
41079
+ if (rotation && !shapePath) {
40858
41080
  writer.saveGraphicsState(pageIndex);
40859
41081
  writer.rotateAbout(pageIndex, x + width / 2, y + height / 2, rotation);
40860
41082
  }
40861
41083
  const dashArray = lineDashPatternPt(border.dash);
40862
- writer.drawRect(pageIndex, {
40863
- x,
40864
- y,
40865
- width,
40866
- height,
40867
- stroke: border.color,
40868
- lineWidth: border.widthPt ?? 1,
40869
- ...dashArray.length > 0 ? { dashArray } : {}
40870
- });
40871
- if (rotation) {
41084
+ if (shapePath) {
41085
+ writer.drawPath(pageIndex, {
41086
+ segments: shapePath,
41087
+ stroke: border.color,
41088
+ lineWidth: border.widthPt ?? 1
41089
+ });
41090
+ } else {
41091
+ writer.drawRect(pageIndex, {
41092
+ x,
41093
+ y,
41094
+ width,
41095
+ height,
41096
+ stroke: border.color,
41097
+ lineWidth: border.widthPt ?? 1,
41098
+ ...dashArray.length > 0 ? { dashArray } : {}
41099
+ });
41100
+ }
41101
+ if (rotation && !shapePath) {
40872
41102
  writer.restoreGraphicsState(pageIndex);
40873
41103
  }
40874
41104
  }
@@ -41350,7 +41580,7 @@ function emitFragmentGlyphs(chunkCtx, chars, originX, styles, line, fragment, pa
41350
41580
  }
41351
41581
  }
41352
41582
  async function drawFragmentText(writer, pageIndex, paragraph, line, fragment, document2, originX, originY, fontRegistry, drawers) {
41353
- var _a, _b, _c;
41583
+ var _a, _b, _c, _d;
41354
41584
  if (fragment.image) {
41355
41585
  if (fragment.image.floating) return;
41356
41586
  const slot = line.slots.find((c) => c.offset === fragment.startOffset) ?? line.slots.find((c) => c.offset >= fragment.startOffset);
@@ -41383,9 +41613,32 @@ async function drawFragmentText(writer, pageIndex, paragraph, line, fragment, do
41383
41613
  );
41384
41614
  return;
41385
41615
  }
41616
+ if (fragment.math) {
41617
+ const slot = line.slots.find((c) => c.offset === fragment.startOffset) ?? line.slots.find((c) => c.offset >= fragment.startOffset);
41618
+ if (!slot) return;
41619
+ const styles2 = resolveEffectiveTextStyleForParagraph(
41620
+ fragment.styles,
41621
+ (_a = paragraph.style) == null ? void 0 : _a.styleId,
41622
+ document2.styles
41623
+ );
41624
+ const fontFace2 = fontRegistry.resolveFontFace({
41625
+ fontFamily: "Cambria Math",
41626
+ bold: false,
41627
+ italic: false
41628
+ });
41629
+ writer.drawText(pageIndex, {
41630
+ x: pxToPt$1(originX + slot.left),
41631
+ y: pxToPt$1(originY + line.top + line.height * TEXT_BASELINE_RATIO),
41632
+ text: mathDisplayText(fragment.math),
41633
+ fontSize: textStyleToFontSizePt(styles2),
41634
+ color: styles2.color ?? "#000000",
41635
+ fontResourceName: fontFace2.writerResourceName
41636
+ });
41637
+ return;
41638
+ }
41386
41639
  const styles = resolveEffectiveTextStyleForParagraph(
41387
41640
  fragment.styles,
41388
- (_a = paragraph.style) == null ? void 0 : _a.styleId,
41641
+ (_b = paragraph.style) == null ? void 0 : _b.styleId,
41389
41642
  document2.styles
41390
41643
  );
41391
41644
  if (styles.hidden) return;
@@ -41471,7 +41724,7 @@ async function drawFragmentText(writer, pageIndex, paragraph, line, fragment, do
41471
41724
  horizontalScale: styles.characterScale ?? 100,
41472
41725
  fontFeatures
41473
41726
  };
41474
- const mainColor = ((_b = styles.textFill) == null ? void 0 : _b.type) === "solid" ? styles.textFill.color : ((_c = styles.textFill) == null ? void 0 : _c.type) === "gradient" && styles.textFill.stops[0] ? styles.textFill.stops[0].color : styles.color ?? "#000000";
41727
+ const mainColor = ((_c = styles.textFill) == null ? void 0 : _c.type) === "solid" ? styles.textFill.color : ((_d = styles.textFill) == null ? void 0 : _d.type) === "gradient" && styles.textFill.stops[0] ? styles.textFill.stops[0].color : styles.color ?? "#000000";
41475
41728
  const gradientShadingName = resolveGradientShadingName(
41476
41729
  writer,
41477
41730
  pageIndex,
@@ -42553,6 +42806,37 @@ class PdfContentStream {
42553
42806
  "n"
42554
42807
  );
42555
42808
  }
42809
+ /** Intersects the current clip with an arbitrary top-left-origin path. */
42810
+ clipPath(segments) {
42811
+ const page = this.page;
42812
+ if (segments.length === 0) return;
42813
+ const flip = (yy) => page.height - yy;
42814
+ const commands = [];
42815
+ for (const segment of segments) {
42816
+ switch (segment.type) {
42817
+ case "move":
42818
+ commands.push(
42819
+ `${formatNumber(segment.x)} ${formatNumber(flip(segment.y))} m`
42820
+ );
42821
+ break;
42822
+ case "line":
42823
+ commands.push(
42824
+ `${formatNumber(segment.x)} ${formatNumber(flip(segment.y))} l`
42825
+ );
42826
+ break;
42827
+ case "cubic":
42828
+ commands.push(
42829
+ `${formatNumber(segment.x1)} ${formatNumber(flip(segment.y1))} ${formatNumber(segment.x2)} ${formatNumber(flip(segment.y2))} ${formatNumber(segment.x)} ${formatNumber(flip(segment.y))} c`
42830
+ );
42831
+ break;
42832
+ case "close":
42833
+ commands.push("h");
42834
+ break;
42835
+ }
42836
+ }
42837
+ commands.push("W", "n");
42838
+ page.commands.push(commands.join("\n"));
42839
+ }
42556
42840
  drawText(options) {
42557
42841
  if (options.text.length === 0) {
42558
42842
  return;
@@ -44485,6 +44769,10 @@ class OasisPdfWriter {
44485
44769
  var _a;
44486
44770
  (_a = this.streams[pageIndex]) == null ? void 0 : _a.clipRect(x, y, width, height);
44487
44771
  }
44772
+ clipPath(pageIndex, segments) {
44773
+ var _a;
44774
+ (_a = this.streams[pageIndex]) == null ? void 0 : _a.clipPath(segments);
44775
+ }
44488
44776
  drawText(pageIndex, options) {
44489
44777
  var _a;
44490
44778
  (_a = this.streams[pageIndex]) == null ? void 0 : _a.drawText(options);
@@ -45283,6 +45571,72 @@ function applySelectedImageCropAspect(state, mode) {
45283
45571
  }
45284
45572
  return setSelectedImageCrop(state, computeImageAspectCrop(image, mode));
45285
45573
  }
45574
+ function getSelectedImageCropShape(state) {
45575
+ const selectedImage = getSelectedImageRun(state);
45576
+ const image = selectedImage && getRunImage(selectedImage.run);
45577
+ return (image == null ? void 0 : image.cropShape) ?? null;
45578
+ }
45579
+ function setSelectedImageCropShape(state, preset) {
45580
+ const normalized = preset == null ? void 0 : preset.trim();
45581
+ return patchSelectedImage(state, (image) => {
45582
+ const next = { ...image };
45583
+ if (!normalized || normalized === "rect") {
45584
+ delete next.cropShape;
45585
+ } else {
45586
+ next.cropShape = { preset: normalized };
45587
+ if (!next.cropFit) next.cropFit = "fill";
45588
+ }
45589
+ return next;
45590
+ });
45591
+ }
45592
+ function computeImageFillCrop(image) {
45593
+ const sourceWidth = image.intrinsicWidth ?? image.width;
45594
+ const sourceHeight = image.intrinsicHeight ?? image.height;
45595
+ const sourceRatio = sourceWidth > 0 && sourceHeight > 0 ? sourceWidth / sourceHeight : image.width / Math.max(1, image.height);
45596
+ const frameRatio = image.width / Math.max(1, image.height);
45597
+ if (!Number.isFinite(sourceRatio) || !Number.isFinite(frameRatio)) {
45598
+ return {};
45599
+ }
45600
+ if (sourceRatio > frameRatio) {
45601
+ const visibleWidth = frameRatio / sourceRatio;
45602
+ const trim = Math.max(0, (1 - visibleWidth) / 2);
45603
+ return { left: trim, right: trim };
45604
+ }
45605
+ if (sourceRatio < frameRatio) {
45606
+ const visibleHeight = sourceRatio / frameRatio;
45607
+ const trim = Math.max(0, (1 - visibleHeight) / 2);
45608
+ return { top: trim, bottom: trim };
45609
+ }
45610
+ return {};
45611
+ }
45612
+ function applySelectedImageCropFill(state) {
45613
+ const selectedImage = getSelectedImageRun(state);
45614
+ const image = selectedImage && getRunImage(selectedImage.run);
45615
+ if (!image) return state;
45616
+ const cropped = setSelectedImageCrop(state, {
45617
+ crop: computeImageFillCrop(image)
45618
+ });
45619
+ return patchSelectedImage(cropped, (next) => ({
45620
+ ...next,
45621
+ cropFit: "fill"
45622
+ }));
45623
+ }
45624
+ function applySelectedImageCropFit(state) {
45625
+ return patchSelectedImage(state, (image) => {
45626
+ const next = { ...image, cropFit: "fit" };
45627
+ delete next.crop;
45628
+ return next;
45629
+ });
45630
+ }
45631
+ function resetSelectedImageCrop(state) {
45632
+ return patchSelectedImage(state, (image) => {
45633
+ const next = { ...image };
45634
+ delete next.crop;
45635
+ delete next.cropFit;
45636
+ delete next.cropShape;
45637
+ return next;
45638
+ });
45639
+ }
45286
45640
  function getSelectedImageBorder(state) {
45287
45641
  const selectedImage = getSelectedImageRun(state);
45288
45642
  const image = selectedImage && getRunImage(selectedImage.run);
@@ -45597,7 +45951,13 @@ function createImageInsertionService(deps) {
45597
45951
  deps.applyTransactionalState(
45598
45952
  (current) => {
45599
45953
  const targetState = position ? setSelection(current, { anchor: position, focus: position }) : current;
45600
- return insertImageAtSelection(targetState, { src, width, height });
45954
+ return insertImageAtSelection(targetState, {
45955
+ src,
45956
+ width,
45957
+ height,
45958
+ intrinsicWidth: naturalWidth,
45959
+ intrinsicHeight: naturalHeight
45960
+ });
45601
45961
  },
45602
45962
  { mergeKey: MERGE_KEYS.insertImage }
45603
45963
  );
@@ -49018,6 +49378,15 @@ function createRotateSession(adapter, deps) {
49018
49378
  function visibleFraction(near, far) {
49019
49379
  return Math.max(1e-4, 1 - near - far);
49020
49380
  }
49381
+ function clampCropPair(near, far, nextNear, nextFar) {
49382
+ const visible = Math.max(0.01, 1 - near - far);
49383
+ const clampedNear = Math.max(0, Math.min(nextNear, 0.99 - far));
49384
+ const clampedFar = Math.max(0, Math.min(nextFar, 0.99 - clampedNear));
49385
+ if (clampedNear + clampedFar >= 0.99) {
49386
+ return { near: Math.max(0, 0.99 - visible - far), far };
49387
+ }
49388
+ return { near: clampedNear, far: clampedFar };
49389
+ }
49021
49390
  function resolveCroppedImage(geometry, deltaX, deltaY) {
49022
49391
  const { startWidth: W, startHeight: H } = geometry;
49023
49392
  const l0 = geometry.startCrop.left ?? 0;
@@ -49032,26 +49401,36 @@ function resolveCroppedImage(geometry, deltaX, deltaY) {
49032
49401
  let right = r0;
49033
49402
  let width = W;
49034
49403
  if (xs !== 0) {
49035
- const maxGrow = (xs > 0 ? r0 : l0) / kx;
49036
- width = clamp$1(W + deltaX * xs, MIN_RESIZE_SIZE_PX, W + maxGrow);
49037
- const widthDelta = width - W;
49038
- if (xs > 0) {
49039
- right = Math.max(0, r0 - widthDelta * kx);
49404
+ if (xs < 0) {
49405
+ const maxWidth = W + l0 / kx;
49406
+ width = clamp$1(W - deltaX, MIN_RESIZE_SIZE_PX, maxWidth);
49407
+ const pair = clampCropPair(l0, r0, l0 - (width - W) * kx, r0);
49408
+ left = pair.near;
49409
+ right = pair.far;
49040
49410
  } else {
49041
- left = Math.max(0, l0 - widthDelta * kx);
49411
+ const maxWidth = W + r0 / kx;
49412
+ width = clamp$1(W + deltaX, MIN_RESIZE_SIZE_PX, maxWidth);
49413
+ const pair = clampCropPair(l0, r0, l0, r0 - (width - W) * kx);
49414
+ left = pair.near;
49415
+ right = pair.far;
49042
49416
  }
49043
49417
  }
49044
49418
  let top = t0;
49045
49419
  let bottom = b0;
49046
49420
  let height = H;
49047
49421
  if (ys !== 0) {
49048
- const maxGrow = (ys > 0 ? b0 : t0) / ky;
49049
- height = clamp$1(H + deltaY * ys, MIN_RESIZE_SIZE_PX, H + maxGrow);
49050
- const heightDelta = height - H;
49051
- if (ys > 0) {
49052
- bottom = Math.max(0, b0 - heightDelta * ky);
49422
+ if (ys < 0) {
49423
+ const maxHeight = H + t0 / ky;
49424
+ height = clamp$1(H - deltaY, MIN_RESIZE_SIZE_PX, maxHeight);
49425
+ const pair = clampCropPair(t0, b0, t0 - (height - H) * ky, b0);
49426
+ top = pair.near;
49427
+ bottom = pair.far;
49053
49428
  } else {
49054
- top = Math.max(0, t0 - heightDelta * ky);
49429
+ const maxHeight = H + b0 / ky;
49430
+ height = clamp$1(H + deltaY, MIN_RESIZE_SIZE_PX, maxHeight);
49431
+ const pair = clampCropPair(t0, b0, t0, b0 - (height - H) * ky);
49432
+ top = pair.near;
49433
+ bottom = pair.far;
49055
49434
  }
49056
49435
  }
49057
49436
  return {
@@ -49060,6 +49439,29 @@ function resolveCroppedImage(geometry, deltaX, deltaY) {
49060
49439
  height: Math.round(height)
49061
49440
  };
49062
49441
  }
49442
+ function resolveMovedImageCrop(geometry, deltaX, deltaY) {
49443
+ const { startWidth: W, startHeight: H } = geometry;
49444
+ const l0 = geometry.startCrop.left ?? 0;
49445
+ const t0 = geometry.startCrop.top ?? 0;
49446
+ const r0 = geometry.startCrop.right ?? 0;
49447
+ const b0 = geometry.startCrop.bottom ?? 0;
49448
+ const kx = visibleFraction(l0, r0) / W;
49449
+ const ky = visibleFraction(t0, b0) / H;
49450
+ const visibleW = 1 - l0 - r0;
49451
+ const visibleH = 1 - t0 - b0;
49452
+ const nextLeft = Math.max(0, Math.min(1 - visibleW, l0 - deltaX * kx));
49453
+ const nextTop = Math.max(0, Math.min(1 - visibleH, t0 - deltaY * ky));
49454
+ return {
49455
+ crop: {
49456
+ left: nextLeft,
49457
+ right: Math.max(0, 1 - visibleW - nextLeft),
49458
+ top: nextTop,
49459
+ bottom: Math.max(0, 1 - visibleH - nextTop)
49460
+ },
49461
+ width: Math.round(W),
49462
+ height: Math.round(H)
49463
+ };
49464
+ }
49063
49465
  function createCropSession(deps) {
49064
49466
  let active = null;
49065
49467
  const selectionForObject = (state, paragraphId, paragraphOffset) => {
@@ -49090,7 +49492,7 @@ function createCropSession(deps) {
49090
49492
  const z = ((_a = deps.zoomFactor) == null ? void 0 : _a.call(deps)) ?? 1;
49091
49493
  const deltaX = (event.clientX - crop.startClientX) / z;
49092
49494
  const deltaY = (event.clientY - crop.startClientY) / z;
49093
- const result = resolveCroppedImage(crop, deltaX, deltaY);
49495
+ const result = crop.mode === "move" ? resolveMovedImageCrop(crop, deltaX, deltaY) : resolveCroppedImage(crop, deltaX, deltaY);
49094
49496
  const selection = selectionForObject(
49095
49497
  deps.state,
49096
49498
  crop.paragraphId,
@@ -49128,7 +49530,7 @@ function createCropSession(deps) {
49128
49530
  window.removeEventListener("mousemove", handleMouseMove);
49129
49531
  window.removeEventListener("mouseup", handleMouseUp);
49130
49532
  };
49131
- const start = (paragraphId, paragraphOffset, handleDirection, event, initialState) => {
49533
+ const begin = (paragraphId, paragraphOffset, handleDirection, event, initialState, mode) => {
49132
49534
  const selection = selectionForObject(
49133
49535
  initialState,
49134
49536
  paragraphId,
@@ -49154,12 +49556,22 @@ function createCropSession(deps) {
49154
49556
  startWidth: image.width,
49155
49557
  startHeight: image.height,
49156
49558
  startCrop,
49157
- initialState: deps.cloneState(initialState)
49559
+ initialState: deps.cloneState(initialState),
49560
+ mode
49158
49561
  };
49159
49562
  window.addEventListener("mousemove", handleMouseMove);
49160
49563
  window.addEventListener("mouseup", handleMouseUp);
49161
49564
  };
49162
- return { start, stop };
49565
+ const start = (paragraphId, paragraphOffset, handleDirection, event, initialState) => begin(
49566
+ paragraphId,
49567
+ paragraphOffset,
49568
+ handleDirection,
49569
+ event,
49570
+ initialState,
49571
+ "handle"
49572
+ );
49573
+ const startMove = (paragraphId, paragraphOffset, event, initialState) => begin(paragraphId, paragraphOffset, "se", event, initialState, "move");
49574
+ return { start, startMove, stop };
49163
49575
  }
49164
49576
  function createEditorImageOperations(deps) {
49165
49577
  return createEditorImageOperationsImpl(deps);
@@ -49429,6 +49841,11 @@ function createEditorImageOperationsImpl(deps) {
49429
49841
  deps.state
49430
49842
  );
49431
49843
  };
49844
+ const handleImageCropBodyMouseDown = (paragraphId, paragraphOffset, event) => {
49845
+ event.preventDefault();
49846
+ event.stopPropagation();
49847
+ imageCropSession.startMove(paragraphId, paragraphOffset, event, deps.state);
49848
+ };
49432
49849
  return {
49433
49850
  dragging,
49434
49851
  cropMode,
@@ -49446,7 +49863,8 @@ function createEditorImageOperationsImpl(deps) {
49446
49863
  handleImageMouseDown,
49447
49864
  handleImageResizeHandleMouseDown,
49448
49865
  handleImageRotateHandleMouseDown,
49449
- handleImageCropHandleMouseDown
49866
+ handleImageCropHandleMouseDown,
49867
+ handleImageCropBodyMouseDown
49450
49868
  };
49451
49869
  }
49452
49870
  function createEditorTextBoxOperations(deps) {
@@ -51924,6 +52342,27 @@ function createEditorSurfaceEventsImpl(deps) {
51924
52342
  };
51925
52343
  const handleDoubleClickDown = (state, hit, paragraph) => {
51926
52344
  dragAnchor = null;
52345
+ let offset = 0;
52346
+ const mathRun = paragraph.runs.find((run) => {
52347
+ const hitRun = run.kind === "math" && hit.paragraphOffset >= offset && hit.paragraphOffset <= offset + run.text.length;
52348
+ offset += run.text.length;
52349
+ return hitRun;
52350
+ });
52351
+ if ((mathRun == null ? void 0 : mathRun.kind) === "math") {
52352
+ const position = paragraphOffsetToPosition(
52353
+ paragraph,
52354
+ hit.paragraphOffset
52355
+ );
52356
+ applyWithZone(
52357
+ state,
52358
+ hit.zone,
52359
+ setSelection(state, { anchor: position, focus: position }),
52360
+ position
52361
+ );
52362
+ stopDragging();
52363
+ deps.openEquationDialog(mathRun.math, mathRun.id);
52364
+ return;
52365
+ }
51927
52366
  const word = resolveWordSelection(
51928
52367
  getParagraphText(paragraph),
51929
52368
  hit.paragraphOffset
@@ -52788,7 +53227,8 @@ function useEditorInteractionWiring(ctx) {
52788
53227
  textDrag: {
52789
53228
  tryStartTextDrag: textDrag.tryStartTextDrag
52790
53229
  },
52791
- logger: ctx.logger
53230
+ logger: ctx.logger,
53231
+ openEquationDialog: ctx.openEquationDialog
52792
53232
  });
52793
53233
  const textInput = createEditorTextInput({
52794
53234
  state,
@@ -52965,7 +53405,8 @@ function createEditorInteractionRuntimeImpl(deps) {
52965
53405
  styleController,
52966
53406
  getForcePlainTextPaste,
52967
53407
  setForcePlainTextPaste,
52968
- insertImageFromFile
53408
+ insertImageFromFile,
53409
+ openEquationDialog: deps.openEquationDialog
52969
53410
  });
52970
53411
  const onEditorMouseDown = (event) => {
52971
53412
  if (event.button !== 0) {
@@ -54009,7 +54450,36 @@ function createEditorCommandsControllerImpl(deps) {
54009
54450
  return;
54010
54451
  }
54011
54452
  execTransactional(
54012
- (current) => applySelectedImageCropAspect(current, mode)
54453
+ (current) => mode === "reset" ? resetSelectedImageCrop(current) : applySelectedImageCropAspect(current, mode),
54454
+ { mergeKey: MERGE_KEYS.imageCrop }
54455
+ );
54456
+ };
54457
+ const applyImageCropShapeCommand = (preset) => {
54458
+ if (!selectedImageRun()) return;
54459
+ execTransactional(
54460
+ (current) => setSelectedImageCropShape(current, preset),
54461
+ { mergeKey: MERGE_KEYS.imageCrop }
54462
+ );
54463
+ };
54464
+ const applyImageCropFillCommand = () => {
54465
+ if (!selectedImageRun()) return;
54466
+ execTransactional(
54467
+ (current) => applySelectedImageCropFill(current),
54468
+ { mergeKey: MERGE_KEYS.imageCrop }
54469
+ );
54470
+ };
54471
+ const applyImageCropFitCommand = () => {
54472
+ if (!selectedImageRun()) return;
54473
+ execTransactional(
54474
+ (current) => applySelectedImageCropFit(current),
54475
+ { mergeKey: MERGE_KEYS.imageCrop }
54476
+ );
54477
+ };
54478
+ const resetImageCropCommand = () => {
54479
+ if (!selectedImageRun()) return;
54480
+ execTransactional(
54481
+ (current) => resetSelectedImageCrop(current),
54482
+ { mergeKey: MERGE_KEYS.imageCrop }
54013
54483
  );
54014
54484
  };
54015
54485
  const applyImageBorderCommand = (patch) => {
@@ -54051,6 +54521,10 @@ function createEditorCommandsControllerImpl(deps) {
54051
54521
  applyImageWidthCmCommand,
54052
54522
  applyImageHeightCmCommand,
54053
54523
  applyImageCropAspectCommand,
54524
+ applyImageCropShapeCommand,
54525
+ applyImageCropFillCommand,
54526
+ applyImageCropFitCommand,
54527
+ resetImageCropCommand,
54054
54528
  applyImageBorderCommand,
54055
54529
  handleListTab,
54056
54530
  handleListEnter,
@@ -54846,6 +55320,15 @@ function buildCoreFormattingCommands({
54846
55320
  typeof payload.fontFamily === "string" ? payload.fontFamily : null
54847
55321
  );
54848
55322
  }),
55323
+ insertEquation: actionCommand("insertEquation", (p) => {
55324
+ formatting.insertEquation(
55325
+ p
55326
+ );
55327
+ }),
55328
+ updateEquation: actionCommand("updateEquation", (p) => {
55329
+ const payload = p;
55330
+ formatting.updateEquation(payload.runId, payload.expression);
55331
+ }),
54849
55332
  pastePlainText: command("pastePlainText", formatting.pastePlainText),
54850
55333
  bold: command("bold", formatting.bold, () => ({
54851
55334
  isActive: Boolean(s().bold)
@@ -55073,6 +55556,10 @@ function buildDocumentAndBrowserCommands({
55073
55556
  "openSymbolDialog",
55074
55557
  () => document2.openSymbolDialog()
55075
55558
  ),
55559
+ openEquationDialog: actionCommand(
55560
+ "openEquationDialog",
55561
+ () => document2.openEquationDialog()
55562
+ ),
55076
55563
  unlink: actionCommand(
55077
55564
  "unlink",
55078
55565
  () => link.remove(),
@@ -55144,6 +55631,29 @@ function buildDocumentAndBrowserCommands({
55144
55631
  isEnabled: image.isSelected()
55145
55632
  })
55146
55633
  ),
55634
+ imageCropShape: actionCommand(
55635
+ "imageCropShape",
55636
+ (p) => image.applyCropShape(String(p)),
55637
+ () => ({
55638
+ isEnabled: image.isSelected(),
55639
+ value: image.getCropShape()
55640
+ })
55641
+ ),
55642
+ imageCropFill: actionCommand(
55643
+ "imageCropFill",
55644
+ () => image.applyCropFill(),
55645
+ () => ({ isEnabled: image.isSelected() })
55646
+ ),
55647
+ imageCropFit: actionCommand(
55648
+ "imageCropFit",
55649
+ () => image.applyCropFit(),
55650
+ () => ({ isEnabled: image.isSelected() })
55651
+ ),
55652
+ imageCropReset: actionCommand(
55653
+ "imageCropReset",
55654
+ () => image.resetCrop(),
55655
+ () => ({ isEnabled: image.isSelected() })
55656
+ ),
55147
55657
  imageBorder: actionCommand(
55148
55658
  "imageBorder",
55149
55659
  (p) => image.setBorder(p),
@@ -55548,6 +56058,7 @@ function buildEssentialsGate(options) {
55548
56058
  return {
55549
56059
  isCommandEnabled: (commandName) => {
55550
56060
  if (commandName === "openSymbolDialog") return true;
56061
+ if (commandName === "openEquationDialog") return true;
55551
56062
  return !options.isReadOnly() && (commandName !== "insertFootnote" || options.commandsController.canInsertFootnoteCommand());
55552
56063
  }
55553
56064
  };
@@ -55809,6 +56320,23 @@ function buildEssentialsFormatting(options) {
55809
56320
  options.focusInput();
55810
56321
  return true;
55811
56322
  },
56323
+ insertEquation: (expression) => {
56324
+ options.applyTransactionalState(
56325
+ (current) => options.tableOps.applyTableAwareParagraphEdit(
56326
+ current,
56327
+ (temp) => insertMathAtSelection(temp, expression)
56328
+ )
56329
+ );
56330
+ options.focusInput();
56331
+ return true;
56332
+ },
56333
+ updateEquation: (runId, expression) => {
56334
+ options.applyTransactionalState(
56335
+ (current) => updateMathRun(current, runId, expression)
56336
+ );
56337
+ options.focusInput();
56338
+ return true;
56339
+ },
55812
56340
  insertTableOfContents: () => {
55813
56341
  options.applyTransactionalState(
55814
56342
  (current) => insertTableOfContents(current, buildTocPageResolver(current))
@@ -55993,6 +56521,7 @@ function buildEssentialsDocument(options) {
55993
56521
  },
55994
56522
  newDocument: () => options.newDocument(),
55995
56523
  openSymbolDialog: () => options.openSymbolDialog(),
56524
+ openEquationDialog: () => options.openEquationDialog(),
55996
56525
  exportDocx: () => void options.docIO.handleExportDocx(),
55997
56526
  exportPdf: () => void options.docIO.handleExportPdf(),
55998
56527
  importDocument: () => {
@@ -56026,6 +56555,14 @@ function buildEssentialsImage(options) {
56026
56555
  isCropActive: () => options.imageCropMode.isActive(),
56027
56556
  toggleCrop: () => options.imageCropMode.toggle(),
56028
56557
  applyCropAspect: (preset) => options.commandsController.applyImageCropAspectCommand(preset),
56558
+ getCropShape: () => {
56559
+ var _a;
56560
+ return ((_a = getSelectedImageCropShape(options.state())) == null ? void 0 : _a.preset) ?? null;
56561
+ },
56562
+ applyCropShape: (preset) => options.commandsController.applyImageCropShapeCommand(preset),
56563
+ applyCropFill: () => options.commandsController.applyImageCropFillCommand(),
56564
+ applyCropFit: () => options.commandsController.applyImageCropFitCommand(),
56565
+ resetCrop: () => options.commandsController.resetImageCropCommand(),
56029
56566
  getBorder: () => getSelectedImageBorder(options.state()),
56030
56567
  setBorder: (patch) => options.commandsController.applyImageBorderCommand(patch)
56031
56568
  };
@@ -57036,7 +57573,28 @@ function createEditorCommandRuntimeImpl(deps) {
57036
57573
  resetDocument: () => runtimeClient.resetDocument(),
57037
57574
  requestConfirmation: () => deps.setNewDocumentDialog({ isOpen: true })
57038
57575
  }),
57039
- openSymbolDialog: () => deps.setSymbolDialog({ isOpen: true })
57576
+ openSymbolDialog: () => deps.setSymbolDialog({ isOpen: true }),
57577
+ openEquationDialog: () => {
57578
+ const focus = deps.state.selection.focus;
57579
+ const paragraph = getDocumentParagraphs(deps.state.document).find(
57580
+ (block) => block.id === focus.paragraphId
57581
+ );
57582
+ if ((paragraph == null ? void 0 : paragraph.type) === "paragraph") {
57583
+ let offset = 0;
57584
+ for (const run of paragraph.runs) {
57585
+ if (run.kind === "math" && focus.offset >= offset && focus.offset <= offset + run.text.length) {
57586
+ deps.setEquationDialog({
57587
+ isOpen: true,
57588
+ initial: run.math,
57589
+ targetRunId: run.id
57590
+ });
57591
+ return;
57592
+ }
57593
+ offset += run.text.length;
57594
+ }
57595
+ }
57596
+ deps.setEquationDialog({ isOpen: true });
57597
+ }
57040
57598
  },
57041
57599
  externalPlugins: deps.runtimeOptions().plugins,
57042
57600
  t: deps.translator,
@@ -57214,7 +57772,9 @@ function OasisEditorApp(props = {}) {
57214
57772
  newDocumentDialog,
57215
57773
  setNewDocumentDialog,
57216
57774
  symbolDialog,
57217
- setSymbolDialog
57775
+ setSymbolDialog,
57776
+ equationDialog,
57777
+ setEquationDialog
57218
57778
  } = createEditorDialogs();
57219
57779
  const [welcomeOpen, setWelcomeOpen] = createSignal(false);
57220
57780
  const viewportRef = () => focusController.viewportRef;
@@ -57284,7 +57844,14 @@ function OasisEditorApp(props = {}) {
57284
57844
  preferredColumnX,
57285
57845
  setPreferredColumnX,
57286
57846
  documentLayout,
57287
- canvasSnapshotProvider
57847
+ canvasSnapshotProvider,
57848
+ openEquationDialog: (initial, targetRunId) => {
57849
+ setEquationDialog({
57850
+ isOpen: true,
57851
+ initial,
57852
+ targetRunId
57853
+ });
57854
+ }
57288
57855
  });
57289
57856
  const {
57290
57857
  layoutOptionsOverlay,
@@ -57336,7 +57903,8 @@ function OasisEditorApp(props = {}) {
57336
57903
  setImageAltDialog,
57337
57904
  setImageCaptionDialog,
57338
57905
  setNewDocumentDialog,
57339
- setSymbolDialog
57906
+ setSymbolDialog,
57907
+ setEquationDialog
57340
57908
  });
57341
57909
  const {
57342
57910
  commandsController,
@@ -57430,6 +57998,7 @@ function OasisEditorApp(props = {}) {
57430
57998
  handleTextBoxResizeHandleMouseDown: textBoxOps.handleTextBoxResizeHandleMouseDown,
57431
57999
  handleImageRotateHandleMouseDown: imageOps.handleImageRotateHandleMouseDown,
57432
58000
  handleImageCropHandleMouseDown: imageOps.handleImageCropHandleMouseDown,
58001
+ handleImageCropBodyMouseDown: imageOps.handleImageCropBodyMouseDown,
57433
58002
  handleTextBoxRotateHandleMouseDown: textBoxOps.handleTextBoxRotateHandleMouseDown,
57434
58003
  handleEditorContextMenu
57435
58004
  },
@@ -57506,7 +58075,9 @@ function OasisEditorApp(props = {}) {
57506
58075
  newDocumentDialog,
57507
58076
  setNewDocumentDialog,
57508
58077
  symbolDialog,
57509
- setSymbolDialog
58078
+ setSymbolDialog,
58079
+ equationDialog,
58080
+ setEquationDialog
57510
58081
  },
57511
58082
  findReplace: fr,
57512
58083
  fontFamilyOptions: computeFontFamilyOptions2,
@@ -57534,6 +58105,17 @@ function OasisEditorApp(props = {}) {
57534
58105
  });
57535
58106
  focusInput();
57536
58107
  },
58108
+ applyEquation: (expression, targetRunId) => {
58109
+ if (targetRunId) {
58110
+ runtimeEditor().commands.execute("updateEquation", {
58111
+ runId: targetRunId,
58112
+ expression
58113
+ });
58114
+ } else {
58115
+ runtimeEditor().commands.execute("insertEquation", expression);
58116
+ }
58117
+ focusInput();
58118
+ },
57537
58119
  closeContextMenu
57538
58120
  }), null);
57539
58121
  insert(_el$, createComponent(EditorWorkspace, {