@harbour-enterprises/superdoc 1.4.0-next.1 → 1.4.0-next.2

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.
@@ -19027,7 +19027,7 @@ function isMetafileExtension(extension) {
19027
19027
  const DRAWING_XML_TAG = "w:drawing";
19028
19028
  const SHAPE_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
19029
19029
  const GROUP_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
19030
- const normalizeTargetPath = (targetPath = "") => {
19030
+ const normalizeTargetPath$1 = (targetPath = "") => {
19031
19031
  if (!targetPath) return targetPath;
19032
19032
  const trimmed = targetPath.replace(/^\/+/, "");
19033
19033
  if (trimmed.startsWith("word/")) return trimmed;
@@ -19186,7 +19186,14 @@ function handleImageNode(node, params, isAnchor) {
19186
19186
  }
19187
19187
  const stretch = blipFill?.elements.find((el) => el.name === "a:stretch");
19188
19188
  const fillRect = stretch?.elements.find((el) => el.name === "a:fillRect");
19189
+ const srcRect = blipFill?.elements.find((el) => el.name === "a:srcRect");
19190
+ const srcRectAttrs = srcRect?.attributes || {};
19191
+ const srcRectHasNegativeValues = ["l", "t", "r", "b"].some((attr) => {
19192
+ const val = srcRectAttrs[attr];
19193
+ return val != null && parseFloat(val) < 0;
19194
+ });
19189
19195
  const shouldStretch = Boolean(stretch && fillRect);
19196
+ const shouldCover = shouldStretch && !srcRectHasNegativeValues;
19190
19197
  const spPr = picture.elements.find((el) => el.name === "pic:spPr");
19191
19198
  if (spPr) {
19192
19199
  const xfrm = spPr.elements.find((el) => el.name === "a:xfrm");
@@ -19215,7 +19222,7 @@ function handleImageNode(node, params, isAnchor) {
19215
19222
  }
19216
19223
  const { attributes: relAttributes } = rel;
19217
19224
  const targetPath = relAttributes["Target"];
19218
- const path = normalizeTargetPath(targetPath);
19225
+ const path = normalizeTargetPath$1(targetPath);
19219
19226
  const extension = path.substring(path.lastIndexOf(".") + 1);
19220
19227
  let finalSrc = path;
19221
19228
  let finalExtension = extension;
@@ -19263,7 +19270,7 @@ function handleImageNode(node, params, isAnchor) {
19263
19270
  wrapText: wrap2.attrs.wrapText
19264
19271
  } : {},
19265
19272
  wrapTopAndBottom: wrap2.type === "TopAndBottom",
19266
- shouldStretch,
19273
+ shouldCover,
19267
19274
  originalPadding: {
19268
19275
  distT: attributes["distT"],
19269
19276
  distB: attributes["distB"],
@@ -19456,7 +19463,7 @@ const handleShapeGroup = (params, node, graphicData, size, padding, marginOffset
19456
19463
  const { elements } = relationships || [];
19457
19464
  const rel = elements?.find((el) => el.attributes["Id"] === rEmbed);
19458
19465
  if (!rel) return null;
19459
- const targetPath = normalizeTargetPath(rel.attributes?.["Target"]);
19466
+ const targetPath = normalizeTargetPath$1(rel.attributes?.["Target"]);
19460
19467
  const path = targetPath;
19461
19468
  const nvPicPr = pic.elements?.find((el) => el.name === "pic:nvPicPr");
19462
19469
  const cNvPr = nvPicPr?.elements?.find((el) => el.name === "pic:cNvPr");
@@ -29560,6 +29567,10 @@ function filterOutRootInlineNodes(content = []) {
29560
29567
  if (!node || typeof node.type !== "string") return;
29561
29568
  const type = node.type;
29562
29569
  const preservableNodeName = PRESERVABLE_INLINE_XML_NAMES[type];
29570
+ if (type === "image" && node.attrs?.isAnchor) {
29571
+ result.push(node);
29572
+ return;
29573
+ }
29563
29574
  if (!INLINE_TYPES.has(type)) {
29564
29575
  result.push(node);
29565
29576
  } else if (preservableNodeName) {
@@ -29753,6 +29764,137 @@ function buildStyles(styleObject) {
29753
29764
  }
29754
29765
  return style;
29755
29766
  }
29767
+ function handleShapeImageImport({ params, pict }) {
29768
+ const shape = pict.elements?.find((el) => el.name === "v:shape");
29769
+ if (!shape) return null;
29770
+ const imagedata = shape.elements?.find((el) => el.name === "v:imagedata");
29771
+ if (!imagedata) return null;
29772
+ const { docx, filename } = params;
29773
+ const shapeAttrs = shape.attributes || {};
29774
+ const imagedataAttrs = imagedata.attributes || {};
29775
+ const rId = imagedataAttrs["r:id"];
29776
+ if (!rId) {
29777
+ console.warn("v:imagedata missing r:id attribute");
29778
+ return null;
29779
+ }
29780
+ const currentFile = filename || "document.xml";
29781
+ let rels = docx[`word/_rels/${currentFile}.rels`];
29782
+ if (!rels) rels = docx[`word/_rels/document.xml.rels`];
29783
+ const relationships = rels?.elements?.find((el) => el.name === "Relationships");
29784
+ const { elements } = relationships || [];
29785
+ const rel = elements?.find((el) => el.attributes["Id"] === rId);
29786
+ if (!rel) {
29787
+ console.warn(`Relationship not found for r:id="${rId}"`);
29788
+ return null;
29789
+ }
29790
+ const targetPath = rel.attributes["Target"];
29791
+ const normalizedPath = normalizeTargetPath(targetPath);
29792
+ const style = shapeAttrs.style || "";
29793
+ const styleObj = parseVmlStyle(style);
29794
+ const width = styleObj.width || "100px";
29795
+ const height = styleObj.height || "100px";
29796
+ const position = {
29797
+ type: styleObj.position || "absolute",
29798
+ marginLeft: styleObj["margin-left"] || "0",
29799
+ marginTop: styleObj["margin-top"] || "0"
29800
+ };
29801
+ const zIndex = styleObj["z-index"] ? parseInt(styleObj["z-index"], 10) : void 0;
29802
+ const hPosition = styleObj["mso-position-horizontal"] || "center";
29803
+ const vPosition = styleObj["mso-position-vertical"] || "center";
29804
+ const hRelativeTo = styleObj["mso-position-horizontal-relative"] || "margin";
29805
+ const vRelativeTo = styleObj["mso-position-vertical-relative"] || "margin";
29806
+ const gain = imagedataAttrs["gain"];
29807
+ const blacklevel = imagedataAttrs["blacklevel"];
29808
+ const title = imagedataAttrs["o:title"] || "Watermark";
29809
+ const imageNode = {
29810
+ type: "image",
29811
+ attrs: {
29812
+ src: normalizedPath,
29813
+ alt: title,
29814
+ extension: normalizedPath.substring(normalizedPath.lastIndexOf(".") + 1),
29815
+ title,
29816
+ rId,
29817
+ // Store VML-specific attributes for round-trip
29818
+ vmlWatermark: true,
29819
+ vmlStyle: style,
29820
+ vmlAttributes: shapeAttrs,
29821
+ vmlImagedata: imagedataAttrs,
29822
+ // Positioning
29823
+ isAnchor: true,
29824
+ inline: false,
29825
+ wrap: {
29826
+ type: "None",
29827
+ attrs: {
29828
+ behindDoc: Number.isFinite(zIndex) ? zIndex < 0 : true
29829
+ }
29830
+ },
29831
+ anchorData: {
29832
+ hRelativeFrom: hRelativeTo,
29833
+ vRelativeFrom: vRelativeTo,
29834
+ alignH: hPosition,
29835
+ alignV: vPosition
29836
+ },
29837
+ // Size
29838
+ size: {
29839
+ width: convertToPixels(width),
29840
+ height: convertToPixels(height)
29841
+ },
29842
+ marginOffset: {
29843
+ horizontal: convertToPixels(position.marginLeft),
29844
+ top: convertToPixels(position.marginTop)
29845
+ },
29846
+ // Image adjustments
29847
+ ...gain && { gain },
29848
+ ...blacklevel && { blacklevel }
29849
+ }
29850
+ };
29851
+ return imageNode;
29852
+ }
29853
+ function normalizeTargetPath(targetPath = "") {
29854
+ if (!targetPath) return targetPath;
29855
+ const trimmed = targetPath.replace(/^\/+/, "");
29856
+ if (trimmed.startsWith("word/")) return trimmed;
29857
+ if (trimmed.startsWith("media/")) return `word/${trimmed}`;
29858
+ return `word/${trimmed}`;
29859
+ }
29860
+ function parseVmlStyle(style) {
29861
+ const result = {};
29862
+ if (!style) return result;
29863
+ const declarations = style.split(";").filter((s) => s.trim());
29864
+ for (const decl of declarations) {
29865
+ const [prop, value] = decl.split(":").map((s) => s.trim());
29866
+ if (prop && value) {
29867
+ result[prop] = value;
29868
+ }
29869
+ }
29870
+ return result;
29871
+ }
29872
+ function convertToPixels(value) {
29873
+ if (typeof value === "number") return value;
29874
+ if (!value || typeof value !== "string") return 0;
29875
+ const match = value.match(/^([\d.]+)([a-z%]+)?$/i);
29876
+ if (!match) return 0;
29877
+ const num = parseFloat(match[1]);
29878
+ const unit = match[2] || "px";
29879
+ switch (unit.toLowerCase()) {
29880
+ case "px":
29881
+ return num;
29882
+ case "pt":
29883
+ return num * (96 / 72);
29884
+ // 1pt = 1/72 inch, 96 DPI
29885
+ case "in":
29886
+ return num * 96;
29887
+ case "cm":
29888
+ return num * (96 / 2.54);
29889
+ case "mm":
29890
+ return num * (96 / 25.4);
29891
+ case "pc":
29892
+ return num * 16;
29893
+ // 1pc = 12pt
29894
+ default:
29895
+ return num;
29896
+ }
29897
+ }
29756
29898
  function pictNodeTypeStrategy(node) {
29757
29899
  const shape = node.elements?.find((el) => el.name === "v:shape");
29758
29900
  const group = node.elements?.find((el) => el.name === "v:group");
@@ -29771,6 +29913,10 @@ function pictNodeTypeStrategy(node) {
29771
29913
  if (textbox) {
29772
29914
  return { type: "shapeContainer", handler: handleShapeTextboxImport };
29773
29915
  }
29916
+ const imagedata = shape.elements?.find((el) => el.name === "v:imagedata");
29917
+ if (imagedata) {
29918
+ return { type: "image", handler: handleShapeImageImport };
29919
+ }
29774
29920
  }
29775
29921
  return { type: "unknown", handler: null };
29776
29922
  }
@@ -29869,8 +30015,116 @@ function translateVRectContentBlock(params) {
29869
30015
  };
29870
30016
  return wrapTextInRun(pict);
29871
30017
  }
30018
+ function translateVmlWatermark(params) {
30019
+ const { node } = params;
30020
+ const { attrs } = node;
30021
+ if (attrs.vmlAttributes && attrs.vmlImagedata) {
30022
+ const shape2 = {
30023
+ name: "v:shape",
30024
+ attributes: attrs.vmlAttributes,
30025
+ elements: [
30026
+ {
30027
+ name: "v:imagedata",
30028
+ attributes: {
30029
+ ...attrs.vmlImagedata,
30030
+ "r:id": attrs.rId
30031
+ }
30032
+ }
30033
+ ]
30034
+ };
30035
+ const pict2 = {
30036
+ name: "w:pict",
30037
+ attributes: {
30038
+ "w14:anchorId": generateRandomSigned32BitIntStrId()
30039
+ },
30040
+ elements: [shape2]
30041
+ };
30042
+ const par2 = {
30043
+ name: "w:p",
30044
+ elements: [wrapTextInRun(pict2)]
30045
+ };
30046
+ return par2;
30047
+ }
30048
+ const style = buildVmlStyle(attrs);
30049
+ const shape = {
30050
+ name: "v:shape",
30051
+ attributes: {
30052
+ id: `WordPictureWatermark${generateRandomSigned32BitIntStrId().replace("-", "")}`,
30053
+ "o:spid": `_x0000_s${Math.floor(Math.random() * 1e4)}`,
30054
+ type: "#_x0000_t75",
30055
+ style,
30056
+ "o:allowincell": "f"
30057
+ },
30058
+ elements: [
30059
+ {
30060
+ name: "v:imagedata",
30061
+ attributes: {
30062
+ "r:id": attrs.rId,
30063
+ "o:title": attrs.title || attrs.alt || "Watermark",
30064
+ ...attrs.gain && { gain: attrs.gain },
30065
+ ...attrs.blacklevel && { blacklevel: attrs.blacklevel }
30066
+ }
30067
+ }
30068
+ ]
30069
+ };
30070
+ const pict = {
30071
+ name: "w:pict",
30072
+ attributes: {
30073
+ "w14:anchorId": generateRandomSigned32BitIntStrId()
30074
+ },
30075
+ elements: [shape]
30076
+ };
30077
+ const par = {
30078
+ name: "w:p",
30079
+ elements: [wrapTextInRun(pict)]
30080
+ };
30081
+ return par;
30082
+ }
30083
+ function buildVmlStyle(attrs) {
30084
+ const styles = [];
30085
+ styles.push("position:absolute");
30086
+ if (attrs.size) {
30087
+ if (attrs.size.width) {
30088
+ styles.push(`width:${convertToPt(attrs.size.width)}pt`);
30089
+ }
30090
+ if (attrs.size.height) {
30091
+ styles.push(`height:${convertToPt(attrs.size.height)}pt`);
30092
+ }
30093
+ }
30094
+ if (attrs.marginOffset) {
30095
+ if (attrs.marginOffset.horizontal !== void 0) {
30096
+ styles.push(`margin-left:${convertToPt(attrs.marginOffset.horizontal)}pt`);
30097
+ }
30098
+ if (attrs.marginOffset.top !== void 0) {
30099
+ styles.push(`margin-top:${convertToPt(attrs.marginOffset.top)}pt`);
30100
+ }
30101
+ }
30102
+ if (attrs.wrap?.attrs?.behindDoc) {
30103
+ styles.push("z-index:-251653120");
30104
+ }
30105
+ if (attrs.anchorData) {
30106
+ if (attrs.anchorData.alignH) {
30107
+ styles.push(`mso-position-horizontal:${attrs.anchorData.alignH}`);
30108
+ }
30109
+ if (attrs.anchorData.alignV) {
30110
+ styles.push(`mso-position-vertical:${attrs.anchorData.alignV}`);
30111
+ }
30112
+ if (attrs.anchorData.hRelativeFrom) {
30113
+ styles.push(`mso-position-horizontal-relative:${attrs.anchorData.hRelativeFrom}`);
30114
+ }
30115
+ if (attrs.anchorData.vRelativeFrom) {
30116
+ styles.push(`mso-position-vertical-relative:${attrs.anchorData.vRelativeFrom}`);
30117
+ }
30118
+ }
30119
+ styles.push("mso-width-percent:0");
30120
+ styles.push("mso-height-percent:0");
30121
+ return styles.join(";");
30122
+ }
30123
+ function convertToPt(pixels) {
30124
+ return pixels * 72 / 96;
30125
+ }
29872
30126
  const XML_NODE_NAME = "w:pict";
29873
- const SD_NODE_NAME = ["shapeContainer", "contentBlock"];
30127
+ const SD_NODE_NAME = ["shapeContainer", "contentBlock", "image"];
29874
30128
  const validXmlAttributes = [];
29875
30129
  function encode(params) {
29876
30130
  const { node, pNode } = params.extraParams;
@@ -29894,6 +30148,12 @@ function decode(params) {
29894
30148
  shapeContainer: () => translateShapeContainer(params),
29895
30149
  shapeTextbox: () => translateShapeTextbox(params),
29896
30150
  contentBlock: () => translateContentBlock(params),
30151
+ image: () => {
30152
+ if (node.attrs?.vmlWatermark) {
30153
+ return translateVmlWatermark(params);
30154
+ }
30155
+ return null;
30156
+ },
29897
30157
  default: () => null
29898
30158
  };
29899
30159
  const decoder = types[node.type] ?? types.default;
@@ -31009,7 +31269,7 @@ class SuperConverter {
31009
31269
  static getStoredSuperdocVersion(docx) {
31010
31270
  return SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
31011
31271
  }
31012
- static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.4.0-next.1") {
31272
+ static setStoredSuperdocVersion(docx = this.convertedXml, version = "1.4.0-next.2") {
31013
31273
  return SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version, false);
31014
31274
  }
31015
31275
  /**
@@ -1,5 +1,5 @@
1
- import { B as BIT8, M as MAX_SAFE_INTEGER, c as create, a as BITS7, u as utf8TextDecoder, b as create$1, s as setIfUndefined, d as create$2, f as from, e as floor$1, g as equalityDeep, w as writeVarUint, h as writeVarString, t as toUint8Array, i as createEncoder, j as createInjectionKey, k as toString, l as throwError, m as useSsrAdapter, n as configProviderInjectionKey, o as cssrAnchorMetaName, p as globalStyle, q as cB, r as c, v as isMounted, x as commonVariables$2, y as cM, z as cNotM, A as cE, C as derived, D as changeColor, E as insideModal, F as insidePopover, G as resolveWrappedSlot, H as on, I as warnOnce, J as useConfig, K as useMergedState, L as useMemo, N as useTheme, O as useRtl, P as createKey, Q as useThemeClass, R as createId, S as call, T as render, U as messageProviderInjectionKey, V as messageApiInjectionKey, W as fromBase64, X as onChange, Y as varStorage, Z as toBase64, _ as createUint8ArrayFromArrayBuffer, $ as offChange, a0 as writeVarUint8Array, a1 as map, a2 as length, a3 as isNode, a4 as min, a5 as pow, a6 as comments_module_events, a7 as getFileObject, a8 as getTrackChanges, a9 as CommentsPluginKey, aa as TrackChangesBasePluginKey, ab as Editor, ac as getRichTextExtensions, ad as ellipsisVerticalSvg, ae as xmarkIconSvg, af as checkIconSvg, ag as caretDownIconSvg, ah as commentIconSvg, ai as _export_sfc, aj as NDropdown, ak as SuperInput, al as vClickOutside, am as PresentationEditor, an as SuperEditor, ao as AIWriter, ap as NConfigProvider, aq as SuperToolbar } from "./index-CEcYlysg.es.js";
2
- import "./SuperConverter-CFRB4XNw.es.js";
1
+ import { B as BIT8, M as MAX_SAFE_INTEGER, c as create, a as BITS7, u as utf8TextDecoder, b as create$1, s as setIfUndefined, d as create$2, f as from, e as floor$1, g as equalityDeep, w as writeVarUint, h as writeVarString, t as toUint8Array, i as createEncoder, j as createInjectionKey, k as toString, l as throwError, m as useSsrAdapter, n as configProviderInjectionKey, o as cssrAnchorMetaName, p as globalStyle, q as cB, r as c, v as isMounted, x as commonVariables$2, y as cM, z as cNotM, A as cE, C as derived, D as changeColor, E as insideModal, F as insidePopover, G as resolveWrappedSlot, H as on, I as warnOnce, J as useConfig, K as useMergedState, L as useMemo, N as useTheme, O as useRtl, P as createKey, Q as useThemeClass, R as createId, S as call, T as render, U as messageProviderInjectionKey, V as messageApiInjectionKey, W as fromBase64, X as onChange, Y as varStorage, Z as toBase64, _ as createUint8ArrayFromArrayBuffer, $ as offChange, a0 as writeVarUint8Array, a1 as map, a2 as length, a3 as isNode, a4 as min, a5 as pow, a6 as comments_module_events, a7 as getFileObject, a8 as getTrackChanges, a9 as CommentsPluginKey, aa as TrackChangesBasePluginKey, ab as Editor, ac as getRichTextExtensions, ad as ellipsisVerticalSvg, ae as xmarkIconSvg, af as checkIconSvg, ag as caretDownIconSvg, ah as commentIconSvg, ai as _export_sfc, aj as NDropdown, ak as SuperInput, al as vClickOutside, am as PresentationEditor, an as SuperEditor, ao as AIWriter, ap as NConfigProvider, aq as SuperToolbar } from "./index-dnQEKI-e.es.js";
2
+ import "./SuperConverter-DxlpZQZQ.es.js";
3
3
  import { B as BlankDOCX } from "./blank-docx-ABm6XYAA.es.js";
4
4
  import { E as EventEmitter } from "./eventemitter3-CwrdEv8r.es.js";
5
5
  import { HocuspocusProvider, HocuspocusProviderWebsocket } from "@hocuspocus/provider";
@@ -7479,7 +7479,7 @@ const _sfc_main = {
7479
7479
  __name: "SuperDoc",
7480
7480
  emits: ["selection-update"],
7481
7481
  setup(__props, { emit: __emit }) {
7482
- const PdfViewer = defineAsyncComponent(() => import("./PdfViewer-DRTk3dY6.es.js"));
7482
+ const PdfViewer = defineAsyncComponent(() => import("./PdfViewer-Dnv-LGqI.es.js"));
7483
7483
  const superdocStore = useSuperdocStore();
7484
7484
  const commentsStore = useCommentsStore();
7485
7485
  const {
@@ -8433,7 +8433,7 @@ class SuperDoc extends EventEmitter {
8433
8433
  this.config.colors = shuffleArray(this.config.colors);
8434
8434
  this.userColorMap = /* @__PURE__ */ new Map();
8435
8435
  this.colorIndex = 0;
8436
- this.version = "1.4.0-next.1";
8436
+ this.version = "1.4.0-next.2";
8437
8437
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
8438
8438
  this.superdocId = config.superdocId || v4();
8439
8439
  this.colors = this.config.colors;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  const jszip = require("./jszip-C8_CqJxM.cjs");
3
3
  const helpers$1 = require("./helpers-nOdwpmwb.cjs");
4
- const superEditor_converter = require("./SuperConverter-CgY28MJz.cjs");
4
+ const superEditor_converter = require("./SuperConverter-Dy4wkQEB.cjs");
5
5
  const vue = require("./vue-De9wkgLl.cjs");
6
6
  require("./jszip.min-BPh2MMAa.cjs");
7
7
  const eventemitter3 = require("./eventemitter3-BQuRcMPI.cjs");
@@ -15457,7 +15457,7 @@ const canUseDOM = () => {
15457
15457
  return false;
15458
15458
  }
15459
15459
  };
15460
- const summaryVersion = "1.4.0-next.1";
15460
+ const summaryVersion = "1.4.0-next.2";
15461
15461
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
15462
15462
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
15463
15463
  function mapAttributes(attrs) {
@@ -18089,7 +18089,7 @@ class Editor extends EventEmitter {
18089
18089
  * Process collaboration migrations
18090
18090
  */
18091
18091
  processCollaborationMigrations() {
18092
- console.debug("[checkVersionMigrations] Current editor version", "1.4.0-next.1");
18092
+ console.debug("[checkVersionMigrations] Current editor version", "1.4.0-next.2");
18093
18093
  if (!this.options.ydoc) return;
18094
18094
  const metaMap = this.options.ydoc.getMap("meta");
18095
18095
  let docVersion = metaMap.get("version");
@@ -23822,6 +23822,9 @@ const renderTableCell = (deps) => {
23822
23822
  imgEl.style.width = "100%";
23823
23823
  imgEl.style.height = "100%";
23824
23824
  imgEl.style.objectFit = block.objectFit ?? "contain";
23825
+ if (block.objectFit === "cover") {
23826
+ imgEl.style.objectPosition = "left top";
23827
+ }
23825
23828
  imgEl.style.display = "block";
23826
23829
  imageWrapper.appendChild(imgEl);
23827
23830
  content.appendChild(imageWrapper);
@@ -23851,6 +23854,9 @@ const renderTableCell = (deps) => {
23851
23854
  img.style.width = "100%";
23852
23855
  img.style.height = "100%";
23853
23856
  img.style.objectFit = block.objectFit ?? "contain";
23857
+ if (block.objectFit === "cover") {
23858
+ img.style.objectPosition = "left top";
23859
+ }
23854
23860
  drawingInner.appendChild(img);
23855
23861
  } else if (renderDrawingContent) {
23856
23862
  const drawingContent = renderDrawingContent(block);
@@ -26422,7 +26428,7 @@ class DomPainter {
26422
26428
  if (fragment.pmEnd != null) {
26423
26429
  fragmentEl.dataset.pmEnd = String(fragment.pmEnd);
26424
26430
  }
26425
- if (fragment.metadata) {
26431
+ if (fragment.metadata && !block.attrs?.vmlWatermark) {
26426
26432
  fragmentEl.setAttribute("data-image-metadata", JSON.stringify(fragment.metadata));
26427
26433
  }
26428
26434
  const img = this.doc.createElement("img");
@@ -26433,7 +26439,28 @@ class DomPainter {
26433
26439
  img.style.width = "100%";
26434
26440
  img.style.height = "100%";
26435
26441
  img.style.objectFit = block.objectFit ?? "contain";
26442
+ if (block.objectFit === "cover") {
26443
+ img.style.objectPosition = "left top";
26444
+ }
26436
26445
  img.style.display = block.display === "inline" ? "inline-block" : "block";
26446
+ const filters = [];
26447
+ if (block.gain != null || block.blacklevel != null) {
26448
+ if (block.gain && typeof block.gain === "string" && block.gain.endsWith("f")) {
26449
+ const contrast = Math.max(0, parseInt(block.gain) / 65536);
26450
+ if (contrast > 0) {
26451
+ filters.push(`contrast(${contrast})`);
26452
+ }
26453
+ }
26454
+ if (block.blacklevel && typeof block.blacklevel === "string" && block.blacklevel.endsWith("f")) {
26455
+ const brightness = Math.max(0, 1 + parseInt(block.blacklevel) / 327 / 100) + 0.5;
26456
+ if (brightness > 0) {
26457
+ filters.push(`brightness(${brightness})`);
26458
+ }
26459
+ }
26460
+ if (filters.length > 0) {
26461
+ img.style.filter = filters.join(" ");
26462
+ }
26463
+ }
26437
26464
  fragmentEl.appendChild(img);
26438
26465
  return fragmentEl;
26439
26466
  } catch (error) {
@@ -26513,6 +26540,9 @@ class DomPainter {
26513
26540
  img.style.width = "100%";
26514
26541
  img.style.height = "100%";
26515
26542
  img.style.objectFit = drawing.objectFit ?? "contain";
26543
+ if (drawing.objectFit === "cover") {
26544
+ img.style.objectPosition = "left top";
26545
+ }
26516
26546
  img.style.display = "block";
26517
26547
  return img;
26518
26548
  }
@@ -31263,13 +31293,8 @@ function computeAnchorX(anchor, columnIndex, columns, imageWidth, margins, pageW
31263
31293
  let baseX;
31264
31294
  let availableWidth;
31265
31295
  if (relativeFrom === "page") {
31266
- if (columns.count === 1) {
31267
- baseX = contentLeft;
31268
- availableWidth = contentWidth;
31269
- } else {
31270
- baseX = 0;
31271
- availableWidth = pageWidth != null ? pageWidth : contentWidth;
31272
- }
31296
+ baseX = 0;
31297
+ availableWidth = pageWidth != null ? pageWidth : contentWidth + marginLeft + marginRight;
31273
31298
  } else if (relativeFrom === "margin") {
31274
31299
  baseX = contentLeft;
31275
31300
  availableWidth = contentWidth;
@@ -32758,7 +32783,9 @@ function collectPreRegisteredAnchors(blocks, measures) {
32758
32783
  if (!isImage && !isDrawing) continue;
32759
32784
  const drawingBlock = block;
32760
32785
  const drawingMeasure = measure;
32761
- if (!drawingBlock.anchor?.isAnchored) continue;
32786
+ if (!drawingBlock.anchor?.isAnchored) {
32787
+ continue;
32788
+ }
32762
32789
  if (isPageRelativeAnchor(drawingBlock)) {
32763
32790
  result.push({ block: drawingBlock, measure: drawingMeasure });
32764
32791
  }
@@ -45906,8 +45933,9 @@ function imageNodeToBlock(node, nextBlockId, positions, _trackedMeta, _trackedCh
45906
45933
  const isInline2 = normalizedWrap?.type === "Inline" || typeof attrs.inline === "boolean" && attrs.inline;
45907
45934
  const display = explicitDisplay === "inline" || explicitDisplay === "block" ? explicitDisplay : isInline2 ? "inline" : "block";
45908
45935
  const explicitObjectFit = typeof attrs.objectFit === "string" ? attrs.objectFit : void 0;
45936
+ const shouldCover = attrs.shouldCover === true;
45909
45937
  const isAnchor = anchor?.isAnchored ?? (typeof attrs.isAnchor === "boolean" ? attrs.isAnchor : false);
45910
- const objectFit = isAllowedObjectFit(explicitObjectFit) ? explicitObjectFit : display === "inline" ? "scale-down" : isAnchor ? "contain" : "contain";
45938
+ const objectFit = isAllowedObjectFit(explicitObjectFit) ? explicitObjectFit : shouldCover ? "cover" : display === "inline" ? "scale-down" : isAnchor ? "contain" : "contain";
45911
45939
  return {
45912
45940
  kind: "image",
45913
45941
  id: nextBlockId("image"),
@@ -45922,7 +45950,10 @@ function imageNodeToBlock(node, nextBlockId, positions, _trackedMeta, _trackedCh
45922
45950
  margin: toBoxSpacing(attrs.marginOffset),
45923
45951
  anchor,
45924
45952
  wrap: normalizedWrap,
45925
- attrs: attrsWithPm
45953
+ attrs: attrsWithPm,
45954
+ // VML image adjustments for watermark effects
45955
+ gain: typeof attrs.gain === "string" || typeof attrs.gain === "number" ? attrs.gain : void 0,
45956
+ blacklevel: typeof attrs.blacklevel === "string" || typeof attrs.blacklevel === "number" ? attrs.blacklevel : void 0
45926
45957
  };
45927
45958
  }
45928
45959
  function handleImageNode(node, context) {
@@ -49872,11 +49903,13 @@ async function measureImageBlock(block, constraints) {
49872
49903
  const intrinsic = getIntrinsicImageSize(block, constraints.maxWidth);
49873
49904
  const isBlockBehindDoc = block.anchor?.behindDoc;
49874
49905
  const isBlockWrapBehindDoc = block.wrap?.type === "None" && block.wrap?.behindDoc;
49875
- const bypassWidthConstraint = isBlockBehindDoc || isBlockWrapBehindDoc;
49906
+ const isPageRelativeAnchor2 = block.anchor?.isAnchored && (block.anchor?.hRelativeFrom === "page" || block.anchor?.hRelativeFrom === "margin");
49907
+ const bypassWidthConstraint = isBlockBehindDoc || isBlockWrapBehindDoc || isPageRelativeAnchor2;
49876
49908
  const isWidthConstraintBypassed = bypassWidthConstraint || constraints.maxWidth <= 0;
49877
49909
  const maxWidth = isWidthConstraintBypassed ? intrinsic.width : constraints.maxWidth;
49878
49910
  const hasNegativeVerticalPosition = block.anchor?.isAnchored && (typeof block.anchor?.offsetV === "number" && block.anchor.offsetV < 0 || typeof block.margin?.top === "number" && block.margin.top < 0);
49879
- const maxHeight = hasNegativeVerticalPosition || !constraints.maxHeight || constraints.maxHeight <= 0 ? Infinity : constraints.maxHeight;
49911
+ const shouldBypassHeightConstraint = hasNegativeVerticalPosition || block.objectFit === "cover";
49912
+ const maxHeight = shouldBypassHeightConstraint || !constraints.maxHeight || constraints.maxHeight <= 0 ? Infinity : constraints.maxHeight;
49880
49913
  const widthScale = maxWidth / intrinsic.width;
49881
49914
  const heightScale = maxHeight / intrinsic.height;
49882
49915
  const scale = Math.min(1, widthScale, heightScale);
@@ -64538,18 +64571,18 @@ const Image = Node$1.create({
64538
64571
  // Used during DOCX export to restore the original metafile format.
64539
64572
  originalExtension: { rendered: false },
64540
64573
  originalSrc: { rendered: false },
64541
- shouldStretch: {
64574
+ shouldCover: {
64542
64575
  default: false,
64543
64576
  rendered: false
64544
64577
  },
64545
64578
  size: {
64546
64579
  default: {},
64547
- renderDOM: ({ size: size2, shouldStretch }) => {
64580
+ renderDOM: ({ size: size2, shouldCover }) => {
64548
64581
  let style2 = "";
64549
64582
  let { width, height } = size2 ?? {};
64550
64583
  if (width) style2 += `width: ${width}px;`;
64551
- if (height && shouldStretch) {
64552
- style2 += `height: ${height}px; object-fit: fill;`;
64584
+ if (height && shouldCover) {
64585
+ style2 += `height: ${height}px; object-fit: cover; object-position: left top;`;
64553
64586
  } else if (height) style2 += "height: auto;";
64554
64587
  return { style: style2 };
64555
64588
  }
@@ -72832,6 +72865,9 @@ const nodeResizer = (nodeNames = ["image"], editor) => {
72832
72865
  if (!node || !nodeNames.includes(node.type.name)) {
72833
72866
  return DecorationSet.empty;
72834
72867
  }
72868
+ if (node.attrs?.vmlWatermark === true) {
72869
+ return DecorationSet.empty;
72870
+ }
72835
72871
  const decorations = [];
72836
72872
  if (nodeNames.includes(selection.node?.type.name)) {
72837
72873
  decorations.push(
@@ -72914,6 +72950,7 @@ const nodeResizer = (nodeNames = ["image"], editor) => {
72914
72950
  const pos = Number.parseInt(wrapper.getAttribute("data-pos"), 10);
72915
72951
  const node = view.state.doc.nodeAt(pos);
72916
72952
  if (!nodeNames.includes(node?.type.name)) return;
72953
+ if (node?.attrs?.vmlWatermark === true) return;
72917
72954
  currentWrapper = wrapper;
72918
72955
  resizeContainer = document.createElement("div");
72919
72956
  resizeContainer.className = "sd-editor-resize-container";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
- const index = require("./index-C3KRKogJ.cjs");
3
- require("./SuperConverter-CgY28MJz.cjs");
2
+ const index = require("./index-DJuBZura.cjs");
3
+ require("./SuperConverter-Dy4wkQEB.cjs");
4
4
  const blankDocx = require("./blank-docx-DfW3Eeh2.cjs");
5
5
  const eventemitter3 = require("./eventemitter3-BQuRcMPI.cjs");
6
6
  const provider = require("@hocuspocus/provider");
@@ -7496,7 +7496,7 @@ const _sfc_main = {
7496
7496
  __name: "SuperDoc",
7497
7497
  emits: ["selection-update"],
7498
7498
  setup(__props, { emit: __emit }) {
7499
- const PdfViewer = vue.defineAsyncComponent(() => Promise.resolve().then(() => require("./PdfViewer-H9_8IbtN.cjs")));
7499
+ const PdfViewer = vue.defineAsyncComponent(() => Promise.resolve().then(() => require("./PdfViewer-DqN1vOXI.cjs")));
7500
7500
  const superdocStore = useSuperdocStore();
7501
7501
  const commentsStore = useCommentsStore();
7502
7502
  const {
@@ -8450,7 +8450,7 @@ class SuperDoc extends eventemitter3.EventEmitter {
8450
8450
  this.config.colors = shuffleArray(this.config.colors);
8451
8451
  this.userColorMap = /* @__PURE__ */ new Map();
8452
8452
  this.colorIndex = 0;
8453
- this.version = "1.4.0-next.1";
8453
+ this.version = "1.4.0-next.2";
8454
8454
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
8455
8455
  this.superdocId = config.superdocId || uuid.v4();
8456
8456
  this.colors = this.config.colors;