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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24064,7 +24064,7 @@
24064
24064
  const DRAWING_XML_TAG = "w:drawing";
24065
24065
  const SHAPE_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
24066
24066
  const GROUP_URI = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
24067
- const normalizeTargetPath = (targetPath = "") => {
24067
+ const normalizeTargetPath$1 = (targetPath = "") => {
24068
24068
  if (!targetPath) return targetPath;
24069
24069
  const trimmed = targetPath.replace(/^\/+/, "");
24070
24070
  if (trimmed.startsWith("word/")) return trimmed;
@@ -24223,7 +24223,14 @@
24223
24223
  }
24224
24224
  const stretch = blipFill?.elements.find((el) => el.name === "a:stretch");
24225
24225
  const fillRect = stretch?.elements.find((el) => el.name === "a:fillRect");
24226
+ const srcRect = blipFill?.elements.find((el) => el.name === "a:srcRect");
24227
+ const srcRectAttrs = srcRect?.attributes || {};
24228
+ const srcRectHasNegativeValues = ["l", "t", "r", "b"].some((attr) => {
24229
+ const val = srcRectAttrs[attr];
24230
+ return val != null && parseFloat(val) < 0;
24231
+ });
24226
24232
  const shouldStretch = Boolean(stretch && fillRect);
24233
+ const shouldCover = shouldStretch && !srcRectHasNegativeValues;
24227
24234
  const spPr = picture.elements.find((el) => el.name === "pic:spPr");
24228
24235
  if (spPr) {
24229
24236
  const xfrm = spPr.elements.find((el) => el.name === "a:xfrm");
@@ -24252,7 +24259,7 @@
24252
24259
  }
24253
24260
  const { attributes: relAttributes } = rel;
24254
24261
  const targetPath = relAttributes["Target"];
24255
- const path2 = normalizeTargetPath(targetPath);
24262
+ const path2 = normalizeTargetPath$1(targetPath);
24256
24263
  const extension = path2.substring(path2.lastIndexOf(".") + 1);
24257
24264
  let finalSrc = path2;
24258
24265
  let finalExtension = extension;
@@ -24300,7 +24307,7 @@
24300
24307
  wrapText: wrap2.attrs.wrapText
24301
24308
  } : {},
24302
24309
  wrapTopAndBottom: wrap2.type === "TopAndBottom",
24303
- shouldStretch,
24310
+ shouldCover,
24304
24311
  originalPadding: {
24305
24312
  distT: attributes["distT"],
24306
24313
  distB: attributes["distB"],
@@ -24493,7 +24500,7 @@
24493
24500
  const { elements } = relationships || [];
24494
24501
  const rel = elements?.find((el) => el.attributes["Id"] === rEmbed);
24495
24502
  if (!rel) return null;
24496
- const targetPath = normalizeTargetPath(rel.attributes?.["Target"]);
24503
+ const targetPath = normalizeTargetPath$1(rel.attributes?.["Target"]);
24497
24504
  const path2 = targetPath;
24498
24505
  const nvPicPr = pic.elements?.find((el) => el.name === "pic:nvPicPr");
24499
24506
  const cNvPr = nvPicPr?.elements?.find((el) => el.name === "pic:cNvPr");
@@ -34987,6 +34994,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
34987
34994
  if (!node2 || typeof node2.type !== "string") return;
34988
34995
  const type = node2.type;
34989
34996
  const preservableNodeName = PRESERVABLE_INLINE_XML_NAMES[type];
34997
+ if (type === "image" && node2.attrs?.isAnchor) {
34998
+ result.push(node2);
34999
+ return;
35000
+ }
34990
35001
  if (!INLINE_TYPES.has(type)) {
34991
35002
  result.push(node2);
34992
35003
  } else if (preservableNodeName) {
@@ -35180,6 +35191,137 @@ Please report this to https://github.com/markedjs/marked.`, e) {
35180
35191
  }
35181
35192
  return style2;
35182
35193
  }
35194
+ function handleShapeImageImport({ params: params2, pict }) {
35195
+ const shape = pict.elements?.find((el) => el.name === "v:shape");
35196
+ if (!shape) return null;
35197
+ const imagedata = shape.elements?.find((el) => el.name === "v:imagedata");
35198
+ if (!imagedata) return null;
35199
+ const { docx, filename } = params2;
35200
+ const shapeAttrs = shape.attributes || {};
35201
+ const imagedataAttrs = imagedata.attributes || {};
35202
+ const rId = imagedataAttrs["r:id"];
35203
+ if (!rId) {
35204
+ console.warn("v:imagedata missing r:id attribute");
35205
+ return null;
35206
+ }
35207
+ const currentFile = filename || "document.xml";
35208
+ let rels = docx[`word/_rels/${currentFile}.rels`];
35209
+ if (!rels) rels = docx[`word/_rels/document.xml.rels`];
35210
+ const relationships = rels?.elements?.find((el) => el.name === "Relationships");
35211
+ const { elements } = relationships || [];
35212
+ const rel = elements?.find((el) => el.attributes["Id"] === rId);
35213
+ if (!rel) {
35214
+ console.warn(`Relationship not found for r:id="${rId}"`);
35215
+ return null;
35216
+ }
35217
+ const targetPath = rel.attributes["Target"];
35218
+ const normalizedPath = normalizeTargetPath(targetPath);
35219
+ const style2 = shapeAttrs.style || "";
35220
+ const styleObj = parseVmlStyle(style2);
35221
+ const width = styleObj.width || "100px";
35222
+ const height = styleObj.height || "100px";
35223
+ const position2 = {
35224
+ type: styleObj.position || "absolute",
35225
+ marginLeft: styleObj["margin-left"] || "0",
35226
+ marginTop: styleObj["margin-top"] || "0"
35227
+ };
35228
+ const zIndex = styleObj["z-index"] ? parseInt(styleObj["z-index"], 10) : void 0;
35229
+ const hPosition = styleObj["mso-position-horizontal"] || "center";
35230
+ const vPosition = styleObj["mso-position-vertical"] || "center";
35231
+ const hRelativeTo = styleObj["mso-position-horizontal-relative"] || "margin";
35232
+ const vRelativeTo = styleObj["mso-position-vertical-relative"] || "margin";
35233
+ const gain = imagedataAttrs["gain"];
35234
+ const blacklevel = imagedataAttrs["blacklevel"];
35235
+ const title = imagedataAttrs["o:title"] || "Watermark";
35236
+ const imageNode = {
35237
+ type: "image",
35238
+ attrs: {
35239
+ src: normalizedPath,
35240
+ alt: title,
35241
+ extension: normalizedPath.substring(normalizedPath.lastIndexOf(".") + 1),
35242
+ title,
35243
+ rId,
35244
+ // Store VML-specific attributes for round-trip
35245
+ vmlWatermark: true,
35246
+ vmlStyle: style2,
35247
+ vmlAttributes: shapeAttrs,
35248
+ vmlImagedata: imagedataAttrs,
35249
+ // Positioning
35250
+ isAnchor: true,
35251
+ inline: false,
35252
+ wrap: {
35253
+ type: "None",
35254
+ attrs: {
35255
+ behindDoc: Number.isFinite(zIndex) ? zIndex < 0 : true
35256
+ }
35257
+ },
35258
+ anchorData: {
35259
+ hRelativeFrom: hRelativeTo,
35260
+ vRelativeFrom: vRelativeTo,
35261
+ alignH: hPosition,
35262
+ alignV: vPosition
35263
+ },
35264
+ // Size
35265
+ size: {
35266
+ width: convertToPixels(width),
35267
+ height: convertToPixels(height)
35268
+ },
35269
+ marginOffset: {
35270
+ horizontal: convertToPixels(position2.marginLeft),
35271
+ top: convertToPixels(position2.marginTop)
35272
+ },
35273
+ // Image adjustments
35274
+ ...gain && { gain },
35275
+ ...blacklevel && { blacklevel }
35276
+ }
35277
+ };
35278
+ return imageNode;
35279
+ }
35280
+ function normalizeTargetPath(targetPath = "") {
35281
+ if (!targetPath) return targetPath;
35282
+ const trimmed = targetPath.replace(/^\/+/, "");
35283
+ if (trimmed.startsWith("word/")) return trimmed;
35284
+ if (trimmed.startsWith("media/")) return `word/${trimmed}`;
35285
+ return `word/${trimmed}`;
35286
+ }
35287
+ function parseVmlStyle(style2) {
35288
+ const result = {};
35289
+ if (!style2) return result;
35290
+ const declarations = style2.split(";").filter((s2) => s2.trim());
35291
+ for (const decl of declarations) {
35292
+ const [prop, value] = decl.split(":").map((s2) => s2.trim());
35293
+ if (prop && value) {
35294
+ result[prop] = value;
35295
+ }
35296
+ }
35297
+ return result;
35298
+ }
35299
+ function convertToPixels(value) {
35300
+ if (typeof value === "number") return value;
35301
+ if (!value || typeof value !== "string") return 0;
35302
+ const match = value.match(/^([\d.]+)([a-z%]+)?$/i);
35303
+ if (!match) return 0;
35304
+ const num = parseFloat(match[1]);
35305
+ const unit = match[2] || "px";
35306
+ switch (unit.toLowerCase()) {
35307
+ case "px":
35308
+ return num;
35309
+ case "pt":
35310
+ return num * (96 / 72);
35311
+ // 1pt = 1/72 inch, 96 DPI
35312
+ case "in":
35313
+ return num * 96;
35314
+ case "cm":
35315
+ return num * (96 / 2.54);
35316
+ case "mm":
35317
+ return num * (96 / 25.4);
35318
+ case "pc":
35319
+ return num * 16;
35320
+ // 1pc = 12pt
35321
+ default:
35322
+ return num;
35323
+ }
35324
+ }
35183
35325
  function pictNodeTypeStrategy(node2) {
35184
35326
  const shape = node2.elements?.find((el) => el.name === "v:shape");
35185
35327
  const group = node2.elements?.find((el) => el.name === "v:group");
@@ -35198,6 +35340,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
35198
35340
  if (textbox) {
35199
35341
  return { type: "shapeContainer", handler: handleShapeTextboxImport };
35200
35342
  }
35343
+ const imagedata = shape.elements?.find((el) => el.name === "v:imagedata");
35344
+ if (imagedata) {
35345
+ return { type: "image", handler: handleShapeImageImport };
35346
+ }
35201
35347
  }
35202
35348
  return { type: "unknown", handler: null };
35203
35349
  }
@@ -35296,8 +35442,116 @@ Please report this to https://github.com/markedjs/marked.`, e) {
35296
35442
  };
35297
35443
  return wrapTextInRun(pict);
35298
35444
  }
35445
+ function translateVmlWatermark(params2) {
35446
+ const { node: node2 } = params2;
35447
+ const { attrs } = node2;
35448
+ if (attrs.vmlAttributes && attrs.vmlImagedata) {
35449
+ const shape2 = {
35450
+ name: "v:shape",
35451
+ attributes: attrs.vmlAttributes,
35452
+ elements: [
35453
+ {
35454
+ name: "v:imagedata",
35455
+ attributes: {
35456
+ ...attrs.vmlImagedata,
35457
+ "r:id": attrs.rId
35458
+ }
35459
+ }
35460
+ ]
35461
+ };
35462
+ const pict2 = {
35463
+ name: "w:pict",
35464
+ attributes: {
35465
+ "w14:anchorId": generateRandomSigned32BitIntStrId()
35466
+ },
35467
+ elements: [shape2]
35468
+ };
35469
+ const par2 = {
35470
+ name: "w:p",
35471
+ elements: [wrapTextInRun(pict2)]
35472
+ };
35473
+ return par2;
35474
+ }
35475
+ const style2 = buildVmlStyle(attrs);
35476
+ const shape = {
35477
+ name: "v:shape",
35478
+ attributes: {
35479
+ id: `WordPictureWatermark${generateRandomSigned32BitIntStrId().replace("-", "")}`,
35480
+ "o:spid": `_x0000_s${Math.floor(Math.random() * 1e4)}`,
35481
+ type: "#_x0000_t75",
35482
+ style: style2,
35483
+ "o:allowincell": "f"
35484
+ },
35485
+ elements: [
35486
+ {
35487
+ name: "v:imagedata",
35488
+ attributes: {
35489
+ "r:id": attrs.rId,
35490
+ "o:title": attrs.title || attrs.alt || "Watermark",
35491
+ ...attrs.gain && { gain: attrs.gain },
35492
+ ...attrs.blacklevel && { blacklevel: attrs.blacklevel }
35493
+ }
35494
+ }
35495
+ ]
35496
+ };
35497
+ const pict = {
35498
+ name: "w:pict",
35499
+ attributes: {
35500
+ "w14:anchorId": generateRandomSigned32BitIntStrId()
35501
+ },
35502
+ elements: [shape]
35503
+ };
35504
+ const par = {
35505
+ name: "w:p",
35506
+ elements: [wrapTextInRun(pict)]
35507
+ };
35508
+ return par;
35509
+ }
35510
+ function buildVmlStyle(attrs) {
35511
+ const styles = [];
35512
+ styles.push("position:absolute");
35513
+ if (attrs.size) {
35514
+ if (attrs.size.width) {
35515
+ styles.push(`width:${convertToPt(attrs.size.width)}pt`);
35516
+ }
35517
+ if (attrs.size.height) {
35518
+ styles.push(`height:${convertToPt(attrs.size.height)}pt`);
35519
+ }
35520
+ }
35521
+ if (attrs.marginOffset) {
35522
+ if (attrs.marginOffset.horizontal !== void 0) {
35523
+ styles.push(`margin-left:${convertToPt(attrs.marginOffset.horizontal)}pt`);
35524
+ }
35525
+ if (attrs.marginOffset.top !== void 0) {
35526
+ styles.push(`margin-top:${convertToPt(attrs.marginOffset.top)}pt`);
35527
+ }
35528
+ }
35529
+ if (attrs.wrap?.attrs?.behindDoc) {
35530
+ styles.push("z-index:-251653120");
35531
+ }
35532
+ if (attrs.anchorData) {
35533
+ if (attrs.anchorData.alignH) {
35534
+ styles.push(`mso-position-horizontal:${attrs.anchorData.alignH}`);
35535
+ }
35536
+ if (attrs.anchorData.alignV) {
35537
+ styles.push(`mso-position-vertical:${attrs.anchorData.alignV}`);
35538
+ }
35539
+ if (attrs.anchorData.hRelativeFrom) {
35540
+ styles.push(`mso-position-horizontal-relative:${attrs.anchorData.hRelativeFrom}`);
35541
+ }
35542
+ if (attrs.anchorData.vRelativeFrom) {
35543
+ styles.push(`mso-position-vertical-relative:${attrs.anchorData.vRelativeFrom}`);
35544
+ }
35545
+ }
35546
+ styles.push("mso-width-percent:0");
35547
+ styles.push("mso-height-percent:0");
35548
+ return styles.join(";");
35549
+ }
35550
+ function convertToPt(pixels) {
35551
+ return pixels * 72 / 96;
35552
+ }
35299
35553
  const XML_NODE_NAME = "w:pict";
35300
- const SD_NODE_NAME = ["shapeContainer", "contentBlock"];
35554
+ const SD_NODE_NAME = ["shapeContainer", "contentBlock", "image"];
35301
35555
  const validXmlAttributes = [];
35302
35556
  function encode$1(params2) {
35303
35557
  const { node: node2, pNode } = params2.extraParams;
@@ -35321,6 +35575,12 @@ Please report this to https://github.com/markedjs/marked.`, e) {
35321
35575
  shapeContainer: () => translateShapeContainer(params2),
35322
35576
  shapeTextbox: () => translateShapeTextbox(params2),
35323
35577
  contentBlock: () => translateContentBlock(params2),
35578
+ image: () => {
35579
+ if (node2.attrs?.vmlWatermark) {
35580
+ return translateVmlWatermark(params2);
35581
+ }
35582
+ return null;
35583
+ },
35324
35584
  default: () => null
35325
35585
  };
35326
35586
  const decoder = types2[node2.type] ?? types2.default;
@@ -36436,7 +36696,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
36436
36696
  static getStoredSuperdocVersion(docx) {
36437
36697
  return SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
36438
36698
  }
36439
- static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.4.0-next.1") {
36699
+ static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.4.0-next.3") {
36440
36700
  return SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
36441
36701
  }
36442
36702
  /**
@@ -62252,7 +62512,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
62252
62512
  return false;
62253
62513
  }
62254
62514
  };
62255
- const summaryVersion = "1.4.0-next.1";
62515
+ const summaryVersion = "1.4.0-next.3";
62256
62516
  const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
62257
62517
  const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
62258
62518
  function mapAttributes(attrs) {
@@ -64885,7 +65145,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
64885
65145
  * Process collaboration migrations
64886
65146
  */
64887
65147
  processCollaborationMigrations() {
64888
- console.debug("[checkVersionMigrations] Current editor version", "1.4.0-next.1");
65148
+ console.debug("[checkVersionMigrations] Current editor version", "1.4.0-next.3");
64889
65149
  if (!this.options.ydoc) return;
64890
65150
  const metaMap = this.options.ydoc.getMap("meta");
64891
65151
  let docVersion = metaMap.get("version");
@@ -70619,6 +70879,9 @@ ${l}
70619
70879
  imgEl.style.width = "100%";
70620
70880
  imgEl.style.height = "100%";
70621
70881
  imgEl.style.objectFit = block.objectFit ?? "contain";
70882
+ if (block.objectFit === "cover") {
70883
+ imgEl.style.objectPosition = "left top";
70884
+ }
70622
70885
  imgEl.style.display = "block";
70623
70886
  imageWrapper.appendChild(imgEl);
70624
70887
  content2.appendChild(imageWrapper);
@@ -70648,6 +70911,9 @@ ${l}
70648
70911
  img2.style.width = "100%";
70649
70912
  img2.style.height = "100%";
70650
70913
  img2.style.objectFit = block.objectFit ?? "contain";
70914
+ if (block.objectFit === "cover") {
70915
+ img2.style.objectPosition = "left top";
70916
+ }
70651
70917
  drawingInner.appendChild(img2);
70652
70918
  } else if (renderDrawingContent) {
70653
70919
  const drawingContent = renderDrawingContent(block);
@@ -73220,7 +73486,7 @@ ${l}
73220
73486
  if (fragment.pmEnd != null) {
73221
73487
  fragmentEl.dataset.pmEnd = String(fragment.pmEnd);
73222
73488
  }
73223
- if (fragment.metadata) {
73489
+ if (fragment.metadata && !block.attrs?.vmlWatermark) {
73224
73490
  fragmentEl.setAttribute("data-image-metadata", JSON.stringify(fragment.metadata));
73225
73491
  }
73226
73492
  const img2 = this.doc.createElement("img");
@@ -73231,7 +73497,28 @@ ${l}
73231
73497
  img2.style.width = "100%";
73232
73498
  img2.style.height = "100%";
73233
73499
  img2.style.objectFit = block.objectFit ?? "contain";
73500
+ if (block.objectFit === "cover") {
73501
+ img2.style.objectPosition = "left top";
73502
+ }
73234
73503
  img2.style.display = block.display === "inline" ? "inline-block" : "block";
73504
+ const filters = [];
73505
+ if (block.gain != null || block.blacklevel != null) {
73506
+ if (block.gain && typeof block.gain === "string" && block.gain.endsWith("f")) {
73507
+ const contrast = Math.max(0, parseInt(block.gain) / 65536);
73508
+ if (contrast > 0) {
73509
+ filters.push(`contrast(${contrast})`);
73510
+ }
73511
+ }
73512
+ if (block.blacklevel && typeof block.blacklevel === "string" && block.blacklevel.endsWith("f")) {
73513
+ const brightness = Math.max(0, 1 + parseInt(block.blacklevel) / 327 / 100) + 0.5;
73514
+ if (brightness > 0) {
73515
+ filters.push(`brightness(${brightness})`);
73516
+ }
73517
+ }
73518
+ if (filters.length > 0) {
73519
+ img2.style.filter = filters.join(" ");
73520
+ }
73521
+ }
73235
73522
  fragmentEl.appendChild(img2);
73236
73523
  return fragmentEl;
73237
73524
  } catch (error) {
@@ -73311,6 +73598,9 @@ ${l}
73311
73598
  img2.style.width = "100%";
73312
73599
  img2.style.height = "100%";
73313
73600
  img2.style.objectFit = drawing.objectFit ?? "contain";
73601
+ if (drawing.objectFit === "cover") {
73602
+ img2.style.objectPosition = "left top";
73603
+ }
73314
73604
  img2.style.display = "block";
73315
73605
  return img2;
73316
73606
  }
@@ -78059,13 +78349,8 @@ ${l}
78059
78349
  let baseX;
78060
78350
  let availableWidth;
78061
78351
  if (relativeFrom === "page") {
78062
- if (columns.count === 1) {
78063
- baseX = contentLeft;
78064
- availableWidth = contentWidth;
78065
- } else {
78066
- baseX = 0;
78067
- availableWidth = pageWidth != null ? pageWidth : contentWidth;
78068
- }
78352
+ baseX = 0;
78353
+ availableWidth = pageWidth != null ? pageWidth : contentWidth + marginLeft + marginRight;
78069
78354
  } else if (relativeFrom === "margin") {
78070
78355
  baseX = contentLeft;
78071
78356
  availableWidth = contentWidth;
@@ -79554,7 +79839,9 @@ ${l}
79554
79839
  if (!isImage && !isDrawing) continue;
79555
79840
  const drawingBlock = block;
79556
79841
  const drawingMeasure = measure;
79557
- if (!drawingBlock.anchor?.isAnchored) continue;
79842
+ if (!drawingBlock.anchor?.isAnchored) {
79843
+ continue;
79844
+ }
79558
79845
  if (isPageRelativeAnchor(drawingBlock)) {
79559
79846
  result.push({ block: drawingBlock, measure: drawingMeasure });
79560
79847
  }
@@ -90373,18 +90660,38 @@ ${l}
90373
90660
  return unwrapped.length > 0 ? unwrapped : void 0;
90374
90661
  };
90375
90662
  const styleNodeAttrs = { ...attrs };
90376
- const attrTabStops = unwrapTabStops(styleNodeAttrs.tabStops ?? styleNodeAttrs.tabs) ?? styleNodeAttrs.tabStops;
90377
- const hydratedTabStops = unwrapTabStops(hydrated?.tabStops) ?? hydrated?.tabStops;
90378
- const paragraphTabStops = unwrapTabStops(paragraphProps.tabStops) ?? paragraphProps.tabStops;
90379
- let tabSource = attrTabStops;
90380
- if (!tabSource && hydratedTabStops) {
90381
- tabSource = hydratedTabStops;
90382
- }
90383
- if (!tabSource && paragraphTabStops) {
90384
- tabSource = paragraphTabStops;
90385
- }
90386
- if (tabSource) {
90387
- styleNodeAttrs.tabStops = tabSource;
90663
+ const asTabStopArray = (value) => {
90664
+ return Array.isArray(value) ? value : void 0;
90665
+ };
90666
+ const attrTabStops = unwrapTabStops(styleNodeAttrs.tabStops ?? styleNodeAttrs.tabs) ?? asTabStopArray(styleNodeAttrs.tabStops);
90667
+ const hydratedTabStops = unwrapTabStops(hydrated?.tabStops) ?? asTabStopArray(hydrated?.tabStops);
90668
+ const paragraphTabStops = unwrapTabStops(paragraphProps.tabStops) ?? asTabStopArray(paragraphProps.tabStops);
90669
+ const TAB_STOP_PX_TO_TWIPS = 15;
90670
+ const TAB_STOP_TWIPS_THRESHOLD = 1e3;
90671
+ const getTabStopPosition = (entry) => {
90672
+ const originalPos = pickNumber(entry.originalPos);
90673
+ if (originalPos != null) return originalPos;
90674
+ const posValue = pickNumber(entry.pos ?? entry.position ?? entry.offset);
90675
+ if (posValue == null) return void 0;
90676
+ return posValue > TAB_STOP_TWIPS_THRESHOLD ? posValue : Math.round(posValue * TAB_STOP_PX_TO_TWIPS);
90677
+ };
90678
+ const mergeTabStopSources = (...sources) => {
90679
+ const merged = /* @__PURE__ */ new Map();
90680
+ for (const source of sources) {
90681
+ if (!Array.isArray(source)) continue;
90682
+ for (const stop of source) {
90683
+ if (!stop || typeof stop !== "object") continue;
90684
+ const position2 = getTabStopPosition(stop);
90685
+ if (position2 == null) continue;
90686
+ merged.set(position2, { ...stop });
90687
+ }
90688
+ }
90689
+ if (merged.size === 0) return void 0;
90690
+ return Array.from(merged.entries()).sort(([a2], [b2]) => a2 - b2).map(([, stop]) => stop);
90691
+ };
90692
+ const mergedTabStops = mergeTabStopSources(hydratedTabStops, paragraphTabStops, attrTabStops);
90693
+ if (mergedTabStops) {
90694
+ styleNodeAttrs.tabStops = mergedTabStops;
90388
90695
  if ("tabs" in styleNodeAttrs) {
90389
90696
  delete styleNodeAttrs.tabs;
90390
90697
  }
@@ -90477,6 +90784,11 @@ ${l}
90477
90784
  }
90478
90785
  if (computed2.paragraph.tabs && computed2.paragraph.tabs.length > 0) {
90479
90786
  paragraphAttrs.tabs = computed2.paragraph.tabs.map((tab) => ({ ...tab }));
90787
+ } else if (mergedTabStops) {
90788
+ const normalizedTabs = normalizeOoxmlTabs(mergedTabStops);
90789
+ if (normalizedTabs) {
90790
+ paragraphAttrs.tabs = normalizedTabs;
90791
+ }
90480
90792
  } else if (hydratedTabStops) {
90481
90793
  const normalizedTabs = normalizeOoxmlTabs(hydratedTabStops);
90482
90794
  if (normalizedTabs) {
@@ -91880,9 +92192,19 @@ ${l}
91880
92192
  run2.letterSpacing = twipsToPx$1(runProperties.letterSpacing);
91881
92193
  }
91882
92194
  };
92195
+ const getVanishValue = (runProperties) => {
92196
+ if (!runProperties || typeof runProperties !== "object" || Array.isArray(runProperties)) {
92197
+ return void 0;
92198
+ }
92199
+ if (!Object.prototype.hasOwnProperty.call(runProperties, "vanish")) {
92200
+ return void 0;
92201
+ }
92202
+ return runProperties.vanish === true;
92203
+ };
91883
92204
  function paragraphToFlowBlocks$1(para, nextBlockId, positions, defaultFont, defaultSize, styleContext, listCounterContext, trackedChanges, bookmarks, hyperlinkConfig = DEFAULT_HYPERLINK_CONFIG$1, themeColors, converters, converterContext, enableComments = true) {
91884
92205
  const baseBlockId = nextBlockId("paragraph");
91885
92206
  const paragraphProps = typeof para.attrs?.paragraphProperties === "object" && para.attrs.paragraphProperties !== null ? para.attrs.paragraphProperties : {};
92207
+ const paragraphHiddenByVanish = getVanishValue(paragraphProps.runProperties) === true;
91886
92208
  const paragraphStyleId = typeof para.attrs?.styleId === "string" && para.attrs.styleId.trim() ? para.attrs.styleId : typeof paragraphProps.styleId === "string" && paragraphProps.styleId.trim() ? paragraphProps.styleId : null;
91887
92209
  const paragraphHydration = converterContext ? hydrateParagraphStyleAttrs(para, converterContext) : null;
91888
92210
  let baseRunDefaults = {};
@@ -91981,6 +92303,9 @@ ${l}
91981
92303
  });
91982
92304
  }
91983
92305
  if (!para.content || para.content.length === 0) {
92306
+ if (paragraphHiddenByVanish) {
92307
+ return blocks2;
92308
+ }
91984
92309
  const paraPos = positions.get(para);
91985
92310
  const emptyRun = {
91986
92311
  text: "",
@@ -92002,6 +92327,7 @@ ${l}
92002
92327
  let currentRuns = [];
92003
92328
  let partIndex = 0;
92004
92329
  let tabOrdinal = 0;
92330
+ let suppressedByVanish = false;
92005
92331
  const nextId = () => partIndex === 0 ? baseBlockId : `${baseBlockId}-${partIndex}`;
92006
92332
  const attachAnchorParagraphId = (block, anchorParagraphId) => {
92007
92333
  const applicableKinds = /* @__PURE__ */ new Set(["drawing", "image", "table"]);
@@ -92046,7 +92372,11 @@ ${l}
92046
92372
  runStyleId
92047
92373
  });
92048
92374
  };
92049
- const visitNode = (node2, inheritedMarks = [], activeSdt, activeRunStyleId = null, activeRunProperties) => {
92375
+ const visitNode = (node2, inheritedMarks = [], activeSdt, activeRunStyleId = null, activeRunProperties, activeHidden = false) => {
92376
+ if (activeHidden && node2.type !== "run") {
92377
+ suppressedByVanish = true;
92378
+ return;
92379
+ }
92050
92380
  if (node2.type === "text" && node2.text) {
92051
92381
  const run2 = textNodeToRun(
92052
92382
  node2,
@@ -92077,18 +92407,32 @@ ${l}
92077
92407
  if (node2.type === "run" && Array.isArray(node2.content)) {
92078
92408
  const mergedMarks = [...node2.marks ?? [], ...inheritedMarks ?? []];
92079
92409
  const runProperties = typeof node2.attrs?.runProperties === "object" && node2.attrs.runProperties !== null ? node2.attrs.runProperties : null;
92410
+ const runVanish = getVanishValue(runProperties);
92411
+ const nextHidden = runVanish === void 0 ? activeHidden : runVanish;
92412
+ if (nextHidden) {
92413
+ suppressedByVanish = true;
92414
+ return;
92415
+ }
92080
92416
  const nextRunStyleId = extractRunStyleId(runProperties) ?? activeRunStyleId;
92081
92417
  const nextRunProperties = runProperties ?? activeRunProperties;
92082
- node2.content.forEach((child) => visitNode(child, mergedMarks, activeSdt, nextRunStyleId, nextRunProperties));
92418
+ node2.content.forEach(
92419
+ (child) => visitNode(child, mergedMarks, activeSdt, nextRunStyleId, nextRunProperties, nextHidden)
92420
+ );
92083
92421
  return;
92084
92422
  }
92085
92423
  if (node2.type === "structuredContent" && Array.isArray(node2.content)) {
92086
92424
  const inlineMetadata = resolveNodeSdtMetadata(node2, "structuredContent");
92087
92425
  const nextSdt = inlineMetadata ?? activeSdt;
92088
- node2.content.forEach((child) => visitNode(child, inheritedMarks, nextSdt, activeRunStyleId, activeRunProperties));
92426
+ node2.content.forEach(
92427
+ (child) => visitNode(child, inheritedMarks, nextSdt, activeRunStyleId, activeRunProperties, activeHidden)
92428
+ );
92089
92429
  return;
92090
92430
  }
92091
92431
  if (node2.type === "fieldAnnotation") {
92432
+ if (activeHidden) {
92433
+ suppressedByVanish = true;
92434
+ return;
92435
+ }
92092
92436
  const fieldMetadata = resolveNodeSdtMetadata(node2, "fieldAnnotation");
92093
92437
  let contentText;
92094
92438
  if (Array.isArray(node2.content) && node2.content.length > 0) {
@@ -92107,6 +92451,10 @@ ${l}
92107
92451
  return;
92108
92452
  }
92109
92453
  if (node2.type === "pageReference") {
92454
+ if (activeHidden) {
92455
+ suppressedByVanish = true;
92456
+ return;
92457
+ }
92110
92458
  const instruction = getNodeInstruction(node2) || "";
92111
92459
  const nodeAttrs = typeof node2.attrs === "object" && node2.attrs !== null ? node2.attrs : {};
92112
92460
  const refMarks = Array.isArray(nodeAttrs.marksAsAttrs) ? nodeAttrs.marksAsAttrs : [];
@@ -92240,6 +92588,10 @@ ${l}
92240
92588
  return;
92241
92589
  }
92242
92590
  if (node2.type === "image") {
92591
+ if (activeHidden) {
92592
+ suppressedByVanish = true;
92593
+ return;
92594
+ }
92243
92595
  const isInline2 = isInlineImage(node2);
92244
92596
  if (isInline2) {
92245
92597
  const imageRun = imageNodeToRun(node2, positions, activeSdt);
@@ -92265,6 +92617,10 @@ ${l}
92265
92617
  return;
92266
92618
  }
92267
92619
  if (node2.type === "contentBlock") {
92620
+ if (activeHidden) {
92621
+ suppressedByVanish = true;
92622
+ return;
92623
+ }
92268
92624
  const attrs = node2.attrs ?? {};
92269
92625
  if (attrs.horizontalRule === true) {
92270
92626
  const anchorParagraphId = nextId();
@@ -92283,6 +92639,10 @@ ${l}
92283
92639
  return;
92284
92640
  }
92285
92641
  if (node2.type === "vectorShape") {
92642
+ if (activeHidden) {
92643
+ suppressedByVanish = true;
92644
+ return;
92645
+ }
92286
92646
  const anchorParagraphId = nextId();
92287
92647
  flushParagraph();
92288
92648
  if (converters?.vectorShapeNodeToDrawingBlock) {
@@ -92294,6 +92654,10 @@ ${l}
92294
92654
  return;
92295
92655
  }
92296
92656
  if (node2.type === "shapeGroup") {
92657
+ if (activeHidden) {
92658
+ suppressedByVanish = true;
92659
+ return;
92660
+ }
92297
92661
  const anchorParagraphId = nextId();
92298
92662
  flushParagraph();
92299
92663
  if (converters?.shapeGroupNodeToDrawingBlock) {
@@ -92305,6 +92669,10 @@ ${l}
92305
92669
  return;
92306
92670
  }
92307
92671
  if (node2.type === "shapeContainer") {
92672
+ if (activeHidden) {
92673
+ suppressedByVanish = true;
92674
+ return;
92675
+ }
92308
92676
  const anchorParagraphId = nextId();
92309
92677
  flushParagraph();
92310
92678
  if (converters?.shapeContainerNodeToDrawingBlock) {
@@ -92316,6 +92684,10 @@ ${l}
92316
92684
  return;
92317
92685
  }
92318
92686
  if (node2.type === "shapeTextbox") {
92687
+ if (activeHidden) {
92688
+ suppressedByVanish = true;
92689
+ return;
92690
+ }
92319
92691
  const anchorParagraphId = nextId();
92320
92692
  flushParagraph();
92321
92693
  if (converters?.shapeTextboxNodeToDrawingBlock) {
@@ -92327,6 +92699,10 @@ ${l}
92327
92699
  return;
92328
92700
  }
92329
92701
  if (node2.type === "table") {
92702
+ if (activeHidden) {
92703
+ suppressedByVanish = true;
92704
+ return;
92705
+ }
92330
92706
  const anchorParagraphId = nextId();
92331
92707
  flushParagraph();
92332
92708
  if (converters?.tableNodeToBlock) {
@@ -92350,6 +92726,10 @@ ${l}
92350
92726
  return;
92351
92727
  }
92352
92728
  if (node2.type === "hardBreak" || node2.type === "lineBreak") {
92729
+ if (activeHidden) {
92730
+ suppressedByVanish = true;
92731
+ return;
92732
+ }
92353
92733
  const attrs = node2.attrs ?? {};
92354
92734
  const breakType = attrs.pageBreakType ?? attrs.lineBreakType ?? "line";
92355
92735
  if (breakType === "page") {
@@ -92392,11 +92772,11 @@ ${l}
92392
92772
  }
92393
92773
  };
92394
92774
  para.content.forEach((child) => {
92395
- visitNode(child, [], void 0, null);
92775
+ visitNode(child, [], void 0, null, void 0);
92396
92776
  });
92397
92777
  flushParagraph();
92398
92778
  const hasParagraphBlock = blocks2.some((block) => block.kind === "paragraph");
92399
- if (!hasParagraphBlock) {
92779
+ if (!hasParagraphBlock && !suppressedByVanish && !paragraphHiddenByVanish) {
92400
92780
  blocks2.push({
92401
92781
  kind: "paragraph",
92402
92782
  id: baseBlockId,
@@ -92650,8 +93030,9 @@ ${l}
92650
93030
  const isInline2 = normalizedWrap?.type === "Inline" || typeof attrs.inline === "boolean" && attrs.inline;
92651
93031
  const display = explicitDisplay === "inline" || explicitDisplay === "block" ? explicitDisplay : isInline2 ? "inline" : "block";
92652
93032
  const explicitObjectFit = typeof attrs.objectFit === "string" ? attrs.objectFit : void 0;
93033
+ const shouldCover = attrs.shouldCover === true;
92653
93034
  const isAnchor = anchor?.isAnchored ?? (typeof attrs.isAnchor === "boolean" ? attrs.isAnchor : false);
92654
- const objectFit = isAllowedObjectFit(explicitObjectFit) ? explicitObjectFit : display === "inline" ? "scale-down" : isAnchor ? "contain" : "contain";
93035
+ const objectFit = isAllowedObjectFit(explicitObjectFit) ? explicitObjectFit : shouldCover ? "cover" : display === "inline" ? "scale-down" : isAnchor ? "contain" : "contain";
92655
93036
  return {
92656
93037
  kind: "image",
92657
93038
  id: nextBlockId("image"),
@@ -92666,7 +93047,10 @@ ${l}
92666
93047
  margin: toBoxSpacing(attrs.marginOffset),
92667
93048
  anchor,
92668
93049
  wrap: normalizedWrap,
92669
- attrs: attrsWithPm
93050
+ attrs: attrsWithPm,
93051
+ // VML image adjustments for watermark effects
93052
+ gain: typeof attrs.gain === "string" || typeof attrs.gain === "number" ? attrs.gain : void 0,
93053
+ blacklevel: typeof attrs.blacklevel === "string" || typeof attrs.blacklevel === "number" ? attrs.blacklevel : void 0
92670
93054
  };
92671
93055
  }
92672
93056
  function handleImageNode(node2, context) {
@@ -96616,11 +97000,13 @@ ${l}
96616
97000
  const intrinsic = getIntrinsicImageSize(block, constraints.maxWidth);
96617
97001
  const isBlockBehindDoc = block.anchor?.behindDoc;
96618
97002
  const isBlockWrapBehindDoc = block.wrap?.type === "None" && block.wrap?.behindDoc;
96619
- const bypassWidthConstraint = isBlockBehindDoc || isBlockWrapBehindDoc;
97003
+ const isPageRelativeAnchor2 = block.anchor?.isAnchored && (block.anchor?.hRelativeFrom === "page" || block.anchor?.hRelativeFrom === "margin");
97004
+ const bypassWidthConstraint = isBlockBehindDoc || isBlockWrapBehindDoc || isPageRelativeAnchor2;
96620
97005
  const isWidthConstraintBypassed = bypassWidthConstraint || constraints.maxWidth <= 0;
96621
97006
  const maxWidth = isWidthConstraintBypassed ? intrinsic.width : constraints.maxWidth;
96622
97007
  const hasNegativeVerticalPosition = block.anchor?.isAnchored && (typeof block.anchor?.offsetV === "number" && block.anchor.offsetV < 0 || typeof block.margin?.top === "number" && block.margin.top < 0);
96623
- const maxHeight = hasNegativeVerticalPosition || !constraints.maxHeight || constraints.maxHeight <= 0 ? Infinity : constraints.maxHeight;
97008
+ const shouldBypassHeightConstraint = hasNegativeVerticalPosition || block.objectFit === "cover";
97009
+ const maxHeight = shouldBypassHeightConstraint || !constraints.maxHeight || constraints.maxHeight <= 0 ? Infinity : constraints.maxHeight;
96624
97010
  const widthScale = maxWidth / intrinsic.width;
96625
97011
  const heightScale = maxHeight / intrinsic.height;
96626
97012
  const scale = Math.min(1, widthScale, heightScale);
@@ -111235,18 +111621,18 @@ ${l}
111235
111621
  // Used during DOCX export to restore the original metafile format.
111236
111622
  originalExtension: { rendered: false },
111237
111623
  originalSrc: { rendered: false },
111238
- shouldStretch: {
111624
+ shouldCover: {
111239
111625
  default: false,
111240
111626
  rendered: false
111241
111627
  },
111242
111628
  size: {
111243
111629
  default: {},
111244
- renderDOM: ({ size: size2, shouldStretch }) => {
111630
+ renderDOM: ({ size: size2, shouldCover }) => {
111245
111631
  let style2 = "";
111246
111632
  let { width, height } = size2 ?? {};
111247
111633
  if (width) style2 += `width: ${width}px;`;
111248
- if (height && shouldStretch) {
111249
- style2 += `height: ${height}px; object-fit: fill;`;
111634
+ if (height && shouldCover) {
111635
+ style2 += `height: ${height}px; object-fit: cover; object-position: left top;`;
111250
111636
  } else if (height) style2 += "height: auto;";
111251
111637
  return { style: style2 };
111252
111638
  }
@@ -119405,6 +119791,9 @@ ${l}
119405
119791
  if (!node2 || !nodeNames.includes(node2.type.name)) {
119406
119792
  return DecorationSet.empty;
119407
119793
  }
119794
+ if (node2.attrs?.vmlWatermark === true) {
119795
+ return DecorationSet.empty;
119796
+ }
119408
119797
  const decorations = [];
119409
119798
  if (nodeNames.includes(selection.node?.type.name)) {
119410
119799
  decorations.push(
@@ -119487,6 +119876,7 @@ ${l}
119487
119876
  const pos = Number.parseInt(wrapper.getAttribute("data-pos"), 10);
119488
119877
  const node2 = view.state.doc.nodeAt(pos);
119489
119878
  if (!nodeNames.includes(node2?.type.name)) return;
119879
+ if (node2?.attrs?.vmlWatermark === true) return;
119490
119880
  currentWrapper = wrapper;
119491
119881
  resizeContainer = document.createElement("div");
119492
119882
  resizeContainer.className = "sd-editor-resize-container";
@@ -144773,7 +145163,7 @@ ${reason}`);
144773
145163
  this.config.colors = shuffleArray(this.config.colors);
144774
145164
  this.userColorMap = /* @__PURE__ */ new Map();
144775
145165
  this.colorIndex = 0;
144776
- this.version = "1.4.0-next.1";
145166
+ this.version = "1.4.0-next.3";
144777
145167
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
144778
145168
  this.superdocId = config2.superdocId || v4();
144779
145169
  this.colors = this.config.colors;