docgen-utils 1.0.26 → 1.0.28

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.
package/dist/bundle.js CHANGED
@@ -50371,7 +50371,7 @@ var docgen = (() => {
50371
50371
  }
50372
50372
  return { type: "image", imageKey, src, alt, width, height, caption };
50373
50373
  }
50374
- function parseContainerContent(element, cssContext, nextImageKey, inheritedColor) {
50374
+ function parseContainerContent(element, cssContext, _nextImageKey, inheritedColor) {
50375
50375
  const innerElements = [];
50376
50376
  function processInnerNode(node, color) {
50377
50377
  if (node.nodeType === Node.TEXT_NODE) {
@@ -53610,7 +53610,7 @@ var docgen = (() => {
53610
53610
  let populateImageData2 = function(elements) {
53611
53611
  for (const element of elements) {
53612
53612
  if (element.type === "image" && !element.imageData) {
53613
- const lookupKeys = [element.imageKey, element.src].filter((key2) => Boolean(key2));
53613
+ const lookupKeys = [element.src, element.imageKey].filter((key2) => Boolean(key2));
53614
53614
  for (const lookupKey of lookupKeys) {
53615
53615
  if (imageMap.has(lookupKey)) {
53616
53616
  element.imageData = imageMap.get(lookupKey);
@@ -65048,7 +65048,7 @@ var docgen = (() => {
65048
65048
  }
65049
65049
  return `<img src="${dataUri}"${alt} style="${styles.join(";")}">`;
65050
65050
  }
65051
- function renderPositionedElements(positionedElements, sectionProps, styleMap, themeColors, imageMap, docDefaults = {}) {
65051
+ function renderPositionedElements(positionedElements, _sectionProps, styleMap, _themeColors, imageMap, docDefaults = {}) {
65052
65052
  if (positionedElements.length === 0)
65053
65053
  return "";
65054
65054
  let html = "";
@@ -65528,6 +65528,19 @@ ${generateStylesCss(styleMap, themeFonts)}
65528
65528
  const alpha = parseFloat(match[4]);
65529
65529
  return Math.round((1 - alpha) * 100);
65530
65530
  }
65531
+ function getEffectiveOpacity(element, win) {
65532
+ let effectiveOpacity = 1;
65533
+ let current = element;
65534
+ while (current && current !== win.document.body && current !== win.document.documentElement) {
65535
+ const computed = win.getComputedStyle(current);
65536
+ const opacity = parseFloat(computed.opacity);
65537
+ if (!isNaN(opacity) && opacity < 1) {
65538
+ effectiveOpacity *= opacity;
65539
+ }
65540
+ current = current.parentElement;
65541
+ }
65542
+ return effectiveOpacity;
65543
+ }
65531
65544
  function extractDashType(borderStyle) {
65532
65545
  switch (borderStyle.toLowerCase()) {
65533
65546
  case "dashed":
@@ -65578,18 +65591,6 @@ ${generateStylesCss(styleMap, themeFonts)}
65578
65591
  }
65579
65592
  return null;
65580
65593
  }
65581
- function getEffectiveOpacity(el, win) {
65582
- let opacity = 1;
65583
- let node = el;
65584
- while (node && node.tagName !== "HTML") {
65585
- const style = win.getComputedStyle(node);
65586
- const nodeOpacity = parseFloat(style.opacity);
65587
- if (!isNaN(nodeOpacity))
65588
- opacity *= nodeOpacity;
65589
- node = node.parentElement;
65590
- }
65591
- return opacity;
65592
- }
65593
65594
  function splitCssBackgroundGradients(bgImage) {
65594
65595
  if (!bgImage || bgImage === "none")
65595
65596
  return [];
@@ -65990,8 +65991,50 @@ ${generateStylesCss(styleMap, themeFonts)}
65990
65991
  }
65991
65992
  return text;
65992
65993
  }
65994
+ var monospaceFonts = /* @__PURE__ */ new Set([
65995
+ "consolas",
65996
+ "courier",
65997
+ "courier new",
65998
+ "monospace",
65999
+ "monaco",
66000
+ "lucida console",
66001
+ "dejavu sans mono",
66002
+ "source code pro",
66003
+ "fira code",
66004
+ "roboto mono",
66005
+ "jetbrains mono",
66006
+ "inconsolata",
66007
+ "menlo",
66008
+ "sf mono",
66009
+ "ubuntu mono",
66010
+ "droid sans mono",
66011
+ "andale mono",
66012
+ "liberation mono"
66013
+ ]);
66014
+ function isMonospaceFont(fontFamily) {
66015
+ const primaryFont = fontFamily.split(",")[0].trim().replace(/['"]/g, "").toLowerCase();
66016
+ if (monospaceFonts.has(primaryFont)) {
66017
+ return true;
66018
+ }
66019
+ const fonts = fontFamily.toLowerCase();
66020
+ return fonts.includes("monospace") || fonts.includes("consolas") || fonts.includes("courier");
66021
+ }
66022
+ function shouldPreserveWhitespace(computed) {
66023
+ const whiteSpace = computed.whiteSpace;
66024
+ if (whiteSpace === "pre" || whiteSpace === "pre-wrap" || whiteSpace === "pre-line") {
66025
+ return true;
66026
+ }
66027
+ return isMonospaceFont(computed.fontFamily);
66028
+ }
65993
66029
  function getTransformedText(element, computed) {
65994
- const rawText = element.textContent?.trim() || "";
66030
+ const preserveWhitespace = shouldPreserveWhitespace(computed);
66031
+ let rawText;
66032
+ if (preserveWhitespace) {
66033
+ rawText = element.innerText || element.textContent || "";
66034
+ } else {
66035
+ rawText = element.textContent?.trim() || "";
66036
+ }
66037
+ rawText = rawText.replace(/\u00A0/g, " ");
65995
66038
  const textTransform = computed.textTransform;
65996
66039
  if (textTransform && textTransform !== "none") {
65997
66040
  return applyTextTransform2(rawText, textTransform);
@@ -66683,7 +66726,13 @@ ${generateStylesCss(styleMap, themeFonts)}
66683
66726
  const bgImage = pComputed.backgroundImage;
66684
66727
  const hasGradient = bgImage && bgImage !== "none" && (bgImage.includes("linear-gradient") || bgImage.includes("radial-gradient"));
66685
66728
  const hasBgImage = bgImage && bgImage !== "none" && bgImage.includes("url(");
66686
- if (!hasBg && !hasGradient && !hasBgImage)
66729
+ const pseudoBorderTopWidth = parseFloat(pComputed.borderTopWidth) || 0;
66730
+ const pseudoBorderRightWidth = parseFloat(pComputed.borderRightWidth) || 0;
66731
+ const pseudoBorderBottomWidth = parseFloat(pComputed.borderBottomWidth) || 0;
66732
+ const pseudoBorderLeftWidth = parseFloat(pComputed.borderLeftWidth) || 0;
66733
+ const hasPseudoBorder = pseudoBorderTopWidth > 0 || pseudoBorderRightWidth > 0 || pseudoBorderBottomWidth > 0 || pseudoBorderLeftWidth > 0;
66734
+ const hasUniformPseudoBorder = hasPseudoBorder && pseudoBorderTopWidth === pseudoBorderRightWidth && pseudoBorderRightWidth === pseudoBorderBottomWidth && pseudoBorderBottomWidth === pseudoBorderLeftWidth;
66735
+ if (!hasBg && !hasGradient && !hasBgImage && !hasPseudoBorder)
66687
66736
  continue;
66688
66737
  let gradient = null;
66689
66738
  const extraPseudoGradients = [];
@@ -66704,10 +66753,16 @@ ${generateStylesCss(styleMap, themeFonts)}
66704
66753
  let rectRadius = 0;
66705
66754
  const borderRadius = pComputed.borderRadius;
66706
66755
  const radiusValue = parseFloat(borderRadius);
66756
+ const pseudoRadiusTL = parseFloat(pComputed.borderTopLeftRadius) || 0;
66757
+ const pseudoRadiusTR = parseFloat(pComputed.borderTopRightRadius) || 0;
66758
+ const pseudoRadiusBL = parseFloat(pComputed.borderBottomLeftRadius) || 0;
66759
+ const pseudoRadiusBR = parseFloat(pComputed.borderBottomRightRadius) || 0;
66760
+ const hasPseudoRadius = pseudoRadiusTL > 0 || pseudoRadiusTR > 0 || pseudoRadiusBL > 0 || pseudoRadiusBR > 0;
66761
+ const hasNonUniformPseudoRadius = hasPseudoRadius && (pseudoRadiusTL !== pseudoRadiusTR || pseudoRadiusTL !== pseudoRadiusBL || pseudoRadiusTL !== pseudoRadiusBR);
66707
66762
  const isCircularRadius = borderRadius.includes("%") ? radiusValue >= 50 : radiusValue > 0 && radiusValue >= Math.min(pWidth, pHeight) / 2 - 1;
66708
66763
  const aspectRatio = pWidth / pHeight;
66709
66764
  const isEllipse = isCircularRadius && aspectRatio > 0.5 && aspectRatio < 2;
66710
- if (radiusValue > 0 && !isEllipse) {
66765
+ if (radiusValue > 0 && !isEllipse && !hasNonUniformPseudoRadius) {
66711
66766
  if (borderRadius.includes("%")) {
66712
66767
  const minDim = Math.min(pWidth, pHeight);
66713
66768
  rectRadius = radiusValue / 100 * pxToInch(minDim);
@@ -66716,6 +66771,7 @@ ${generateStylesCss(styleMap, themeFonts)}
66716
66771
  }
66717
66772
  }
66718
66773
  const shadow = parseBoxShadow(pComputed.boxShadow);
66774
+ const pseudoRotation = extractRotationAngle(pComputed);
66719
66775
  let effectiveRectRadius = isEllipse ? 0 : rectRadius;
66720
66776
  if (rectRadius === 0 && !isEllipse) {
66721
66777
  const parentComputed = win.getComputedStyle(el);
@@ -66741,6 +66797,244 @@ ${generateStylesCss(styleMap, themeFonts)}
66741
66797
  }
66742
66798
  }
66743
66799
  }
66800
+ let asymmetricCornerGeometry = null;
66801
+ if (rectRadius === 0 && !isEllipse && effectiveRectRadius > 0) {
66802
+ const parentComputed = win.getComputedStyle(el);
66803
+ const parentRadius = parseFloat(parentComputed.borderRadius);
66804
+ const isThinHorizontal = pHeight < parentRadius && pWidth >= parentRadius * 2;
66805
+ const isThinVertical = pWidth < parentRadius && pHeight >= parentRadius * 2;
66806
+ if (isThinHorizontal || isThinVertical) {
66807
+ const parentBorderLeft = parseFloat(parentComputed.borderLeftWidth) || 0;
66808
+ const parentBorderRight = parseFloat(parentComputed.borderRightWidth) || 0;
66809
+ const parentBorderTop = parseFloat(parentComputed.borderTopWidth) || 0;
66810
+ const parentBorderBottom = parseFloat(parentComputed.borderBottomWidth) || 0;
66811
+ const parentInnerWidth = parentRect.width - parentBorderLeft - parentBorderRight;
66812
+ const parentInnerHeight = parentRect.height - parentBorderTop - parentBorderBottom;
66813
+ const flushTop = Math.abs(pTop) < 2;
66814
+ const flushLeft = Math.abs(pLeft) < 2;
66815
+ const flushRight = Math.abs(pLeft + pWidth - parentRect.width) < 2 || Math.abs(pLeft + pWidth - parentInnerWidth) < 2;
66816
+ const flushBottom = Math.abs(pTop + pHeight - parentRect.height) < 2 || Math.abs(pTop + pHeight - parentInnerHeight) < 2;
66817
+ const arcXAtY = (r2, y) => {
66818
+ if (y <= 0)
66819
+ return r2;
66820
+ if (y >= r2)
66821
+ return 0;
66822
+ const dy = r2 - y;
66823
+ return r2 - Math.sqrt(r2 * r2 - dy * dy);
66824
+ };
66825
+ const h = pHeight;
66826
+ const w = pWidth;
66827
+ const r = parentRadius;
66828
+ const EMU_PER_PX3 = 914400 / 96;
66829
+ const points = [];
66830
+ if (isThinHorizontal && flushTop) {
66831
+ const segments = 8;
66832
+ const arcPointsLeft = [];
66833
+ const arcPointsRight = [];
66834
+ for (let i = 0; i <= segments; i++) {
66835
+ const t = i / segments;
66836
+ const y = t * h;
66837
+ const x = arcXAtY(r, y);
66838
+ arcPointsLeft.push({
66839
+ x: Math.round(x * EMU_PER_PX3),
66840
+ y: Math.round(y * EMU_PER_PX3)
66841
+ });
66842
+ arcPointsRight.push({
66843
+ x: Math.round((w - x) * EMU_PER_PX3),
66844
+ y: Math.round(y * EMU_PER_PX3)
66845
+ });
66846
+ }
66847
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
66848
+ points.push({ x: arcPointsRight[0].x, y: arcPointsRight[0].y });
66849
+ for (let i = 1; i <= segments; i++) {
66850
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
66851
+ }
66852
+ points.push({ x: arcPointsLeft[segments].x, y: arcPointsLeft[segments].y });
66853
+ for (let i = segments - 1; i >= 1; i--) {
66854
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
66855
+ }
66856
+ points.push({ x: 0, y: 0, close: true });
66857
+ asymmetricCornerGeometry = points;
66858
+ } else if (isThinHorizontal && flushBottom) {
66859
+ const segments = 8;
66860
+ const arcPointsLeft = [];
66861
+ const arcPointsRight = [];
66862
+ for (let i = 0; i <= segments; i++) {
66863
+ const t = i / segments;
66864
+ const y = t * h;
66865
+ const arcDistance = arcXAtY(r, h - y);
66866
+ arcPointsLeft.push({
66867
+ x: Math.round(arcDistance * EMU_PER_PX3),
66868
+ y: Math.round(y * EMU_PER_PX3)
66869
+ });
66870
+ arcPointsRight.push({
66871
+ x: Math.round((w - arcDistance) * EMU_PER_PX3),
66872
+ y: Math.round(y * EMU_PER_PX3)
66873
+ });
66874
+ }
66875
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
66876
+ points.push({ x: arcPointsRight[0].x, y: arcPointsRight[0].y });
66877
+ for (let i = 1; i <= segments; i++) {
66878
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
66879
+ }
66880
+ points.push({ x: arcPointsLeft[segments].x, y: arcPointsLeft[segments].y });
66881
+ for (let i = segments - 1; i >= 0; i--) {
66882
+ if (i === 0) {
66883
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y, close: true });
66884
+ } else {
66885
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
66886
+ }
66887
+ }
66888
+ asymmetricCornerGeometry = points;
66889
+ } else if (isThinVertical && flushLeft) {
66890
+ const arcYAtX = (radius, x) => {
66891
+ if (x <= 0)
66892
+ return radius;
66893
+ if (x >= radius)
66894
+ return 0;
66895
+ const dx = radius - x;
66896
+ return radius - Math.sqrt(radius * radius - dx * dx);
66897
+ };
66898
+ const segments = 8;
66899
+ const arcPointsTop = [];
66900
+ const arcPointsBottom = [];
66901
+ for (let i = 0; i <= segments; i++) {
66902
+ const t = i / segments;
66903
+ const x = t * w;
66904
+ const arcDistance = arcYAtX(r, x);
66905
+ arcPointsTop.push({
66906
+ x: Math.round(x * EMU_PER_PX3),
66907
+ y: Math.round(arcDistance * EMU_PER_PX3)
66908
+ });
66909
+ arcPointsBottom.push({
66910
+ x: Math.round(x * EMU_PER_PX3),
66911
+ y: Math.round((h - arcDistance) * EMU_PER_PX3)
66912
+ });
66913
+ }
66914
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
66915
+ for (let i = 1; i <= segments; i++) {
66916
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
66917
+ }
66918
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
66919
+ for (let i = segments - 1; i >= 0; i--) {
66920
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
66921
+ }
66922
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
66923
+ asymmetricCornerGeometry = points;
66924
+ } else if (isThinVertical && flushRight) {
66925
+ const arcYAtX = (radius, x) => {
66926
+ if (x <= 0)
66927
+ return radius;
66928
+ if (x >= radius)
66929
+ return 0;
66930
+ const dx = radius - x;
66931
+ return radius - Math.sqrt(radius * radius - dx * dx);
66932
+ };
66933
+ const segments = 8;
66934
+ const arcPointsTop = [];
66935
+ const arcPointsBottom = [];
66936
+ for (let i = 0; i <= segments; i++) {
66937
+ const t = i / segments;
66938
+ const x = t * w;
66939
+ const arcDistance = arcYAtX(r, w - x);
66940
+ arcPointsTop.push({
66941
+ x: Math.round(x * EMU_PER_PX3),
66942
+ y: Math.round(arcDistance * EMU_PER_PX3)
66943
+ });
66944
+ arcPointsBottom.push({
66945
+ x: Math.round(x * EMU_PER_PX3),
66946
+ y: Math.round((h - arcDistance) * EMU_PER_PX3)
66947
+ });
66948
+ }
66949
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
66950
+ for (let i = 1; i <= segments; i++) {
66951
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
66952
+ }
66953
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
66954
+ for (let i = segments - 1; i >= 0; i--) {
66955
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
66956
+ }
66957
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
66958
+ asymmetricCornerGeometry = points;
66959
+ }
66960
+ if (asymmetricCornerGeometry) {
66961
+ effectiveRectRadius = 0;
66962
+ }
66963
+ }
66964
+ }
66965
+ if (!asymmetricCornerGeometry && hasNonUniformPseudoRadius && !isEllipse) {
66966
+ const w = pWidth;
66967
+ const h = pHeight;
66968
+ const EMU_PER_PX3 = 914400 / 96;
66969
+ const widthEmu = Math.round(w * EMU_PER_PX3);
66970
+ const heightEmu = Math.round(h * EMU_PER_PX3);
66971
+ const segments = 8;
66972
+ const points = [];
66973
+ const addCornerArc = (cornerRadius, isRight, isBottom) => {
66974
+ if (cornerRadius <= 0)
66975
+ return;
66976
+ for (let i = 0; i <= segments; i++) {
66977
+ const t = i / segments;
66978
+ const angle = t * Math.PI / 2;
66979
+ let x, y;
66980
+ if (!isRight && !isBottom) {
66981
+ x = cornerRadius * (1 - Math.sin(angle));
66982
+ y = cornerRadius * (1 - Math.cos(angle));
66983
+ } else if (isRight && !isBottom) {
66984
+ x = w - cornerRadius + cornerRadius * Math.sin(angle);
66985
+ y = cornerRadius * (1 - Math.cos(angle));
66986
+ } else if (!isRight && isBottom) {
66987
+ x = cornerRadius * (1 - Math.cos(angle));
66988
+ y = h - cornerRadius + cornerRadius * Math.sin(angle);
66989
+ } else {
66990
+ x = w - cornerRadius + cornerRadius * Math.cos(angle);
66991
+ y = h - cornerRadius + cornerRadius * Math.sin(angle);
66992
+ }
66993
+ x = Math.max(0, Math.min(w, x));
66994
+ y = Math.max(0, Math.min(h, y));
66995
+ points.push({
66996
+ x: Math.round(x * EMU_PER_PX3),
66997
+ y: Math.round(y * EMU_PER_PX3),
66998
+ ...points.length === 0 ? { moveTo: true } : {}
66999
+ });
67000
+ }
67001
+ };
67002
+ if (pseudoRadiusTL > 0) {
67003
+ points.push({ x: Math.round(pseudoRadiusTL * EMU_PER_PX3), y: 0, moveTo: true });
67004
+ } else {
67005
+ points.push({ x: 0, y: 0, moveTo: true });
67006
+ }
67007
+ if (pseudoRadiusTR > 0) {
67008
+ points.push({ x: Math.round((w - pseudoRadiusTR) * EMU_PER_PX3), y: 0 });
67009
+ addCornerArc(pseudoRadiusTR, true, false);
67010
+ } else {
67011
+ points.push({ x: widthEmu, y: 0 });
67012
+ }
67013
+ if (pseudoRadiusBR > 0) {
67014
+ points.push({ x: widthEmu, y: Math.round((h - pseudoRadiusBR) * EMU_PER_PX3) });
67015
+ addCornerArc(pseudoRadiusBR, true, true);
67016
+ } else {
67017
+ points.push({ x: widthEmu, y: heightEmu });
67018
+ }
67019
+ if (pseudoRadiusBL > 0) {
67020
+ points.push({ x: Math.round(pseudoRadiusBL * EMU_PER_PX3), y: heightEmu });
67021
+ addCornerArc(pseudoRadiusBL, false, true);
67022
+ } else {
67023
+ points.push({ x: 0, y: heightEmu });
67024
+ }
67025
+ if (pseudoRadiusTL > 0) {
67026
+ points.push({ x: 0, y: Math.round(pseudoRadiusTL * EMU_PER_PX3) });
67027
+ addCornerArc(pseudoRadiusTL, false, false);
67028
+ }
67029
+ if (points.length > 0) {
67030
+ const firstPoint = points[0];
67031
+ points.push({ x: firstPoint.x, y: firstPoint.y, close: true });
67032
+ }
67033
+ if (points.length > 5) {
67034
+ asymmetricCornerGeometry = points;
67035
+ effectiveRectRadius = 0;
67036
+ }
67037
+ }
66744
67038
  const shapeElement = {
66745
67039
  type: "shape",
66746
67040
  text: "",
@@ -66756,14 +67050,20 @@ ${generateStylesCss(styleMap, themeFonts)}
66756
67050
  fill: hasBg ? rgbToHex(pComputed.backgroundColor) : null,
66757
67051
  gradient,
66758
67052
  transparency: hasBg ? extractAlpha(pComputed.backgroundColor) : null,
66759
- line: null,
67053
+ line: hasUniformPseudoBorder ? {
67054
+ color: rgbToHex(pComputed.borderColor),
67055
+ width: pxToPoints(pComputed.borderTopWidth),
67056
+ transparency: extractAlpha(pComputed.borderColor),
67057
+ dashType: extractDashType(pComputed.borderStyle)
67058
+ } : null,
66760
67059
  rectRadius: effectiveRectRadius,
66761
67060
  shadow,
66762
67061
  opacity: hasOpacity ? elementOpacity : null,
66763
67062
  isEllipse,
66764
67063
  softEdge: null,
66765
- rotate: null,
66766
- customGeometry: null
67064
+ rotate: pseudoRotation,
67065
+ cssTriangle: null,
67066
+ customGeometry: asymmetricCornerGeometry
66767
67067
  }
66768
67068
  };
66769
67069
  results.push(shapeElement);
@@ -66785,6 +67085,7 @@ ${generateStylesCss(styleMap, themeFonts)}
66785
67085
  isEllipse: false,
66786
67086
  softEdge: null,
66787
67087
  rotate: null,
67088
+ cssTriangle: null,
66788
67089
  customGeometry: null
66789
67090
  }
66790
67091
  };
@@ -66793,7 +67094,7 @@ ${generateStylesCss(styleMap, themeFonts)}
66793
67094
  }
66794
67095
  return results;
66795
67096
  }
66796
- function parseInlineFormatting(element, baseOptions, runs, baseTextTransform, win) {
67097
+ function parseInlineFormatting(element, baseOptions, runs, baseTextTransform, win, preserveWhitespace = false) {
66797
67098
  let prevNodeIsText = false;
66798
67099
  let pendingSoftBreak = false;
66799
67100
  element.childNodes.forEach((node) => {
@@ -66802,7 +67103,32 @@ ${generateStylesCss(styleMap, themeFonts)}
66802
67103
  pendingSoftBreak = true;
66803
67104
  prevNodeIsText = false;
66804
67105
  } else if (node.nodeType === Node.TEXT_NODE) {
66805
- const text = textTransform(node.textContent.replace(/\s+/g, " "));
67106
+ let rawText = node.textContent || "";
67107
+ rawText = rawText.replace(/\u00A0/g, " ");
67108
+ let text;
67109
+ if (preserveWhitespace) {
67110
+ const lines = rawText.split("\n");
67111
+ for (let i = 0; i < lines.length; i++) {
67112
+ let lineText = lines[i];
67113
+ lineText = textTransform(lineText);
67114
+ const prevRun2 = runs[runs.length - 1];
67115
+ if (i === 0 && prevNodeIsText && prevRun2 && !pendingSoftBreak) {
67116
+ prevRun2.text += lineText;
67117
+ } else {
67118
+ const runOptions = { ...baseOptions };
67119
+ if (i > 0 || pendingSoftBreak) {
67120
+ runOptions.softBreakBefore = true;
67121
+ pendingSoftBreak = false;
67122
+ }
67123
+ const runText = lineText.length > 0 ? lineText : " ";
67124
+ runs.push({ text: runText, options: runOptions });
67125
+ }
67126
+ }
67127
+ prevNodeIsText = true;
67128
+ return;
67129
+ } else {
67130
+ text = textTransform(rawText.replace(/\s+/g, " "));
67131
+ }
66806
67132
  const prevRun = runs[runs.length - 1];
66807
67133
  if (prevNodeIsText && prevRun && !pendingSoftBreak) {
66808
67134
  prevRun.text += text;
@@ -66858,6 +67184,17 @@ ${generateStylesCss(styleMap, themeFonts)}
66858
67184
  if (transparency !== null)
66859
67185
  options.transparency = transparency;
66860
67186
  }
67187
+ if (computed.backgroundColor && computed.backgroundColor !== "rgba(0, 0, 0, 0)") {
67188
+ const bgAlpha = extractAlpha(computed.backgroundColor);
67189
+ if (bgAlpha !== null && bgAlpha > 0) {
67190
+ options.highlight = {
67191
+ color: rgbToHex(computed.backgroundColor),
67192
+ transparency: bgAlpha
67193
+ };
67194
+ } else {
67195
+ options.highlight = rgbToHex(computed.backgroundColor);
67196
+ }
67197
+ }
66861
67198
  const bgClip = computed.webkitBackgroundClip || computed.backgroundClip;
66862
67199
  const textFillColor = computed.webkitTextFillColor;
66863
67200
  const isTextFillTransparent = textFillColor === "transparent" || textFillColor === "rgba(0, 0, 0, 0)" || textFillColor && textFillColor.includes("rgba") && textFillColor.endsWith(", 0)");
@@ -66871,10 +67208,17 @@ ${generateStylesCss(styleMap, themeFonts)}
66871
67208
  }
66872
67209
  }
66873
67210
  }
66874
- if (computed.fontSize)
66875
- options.fontSize = pxToPoints(computed.fontSize);
66876
- if (computed.fontFamily) {
66877
- options.fontFace = extractFontFace(computed.fontFamily);
67211
+ const inlineFontFace = computed.fontFamily ? extractFontFace(computed.fontFamily) : null;
67212
+ const baseFontFaceForCheck = baseOptions.fontFace || "";
67213
+ const baseFontFaceIsMonospace = baseFontFaceForCheck && isMonospaceFont(baseFontFaceForCheck);
67214
+ if (computed.fontSize) {
67215
+ const shouldKeepBaseFontSize = baseOptions.fontSize && baseFontFaceIsMonospace;
67216
+ if (!shouldKeepBaseFontSize) {
67217
+ options.fontSize = pxToPoints(computed.fontSize);
67218
+ }
67219
+ }
67220
+ if (inlineFontFace) {
67221
+ options.fontFace = inlineFontFace;
66878
67222
  }
66879
67223
  const runLetterSpacing = extractLetterSpacing(computed);
66880
67224
  if (runLetterSpacing !== null)
@@ -66888,18 +67232,65 @@ ${generateStylesCss(styleMap, themeFonts)}
66888
67232
  if (pendingSoftBreak) {
66889
67233
  pendingSoftBreak = false;
66890
67234
  }
66891
- parseInlineFormatting(el, options, runs, textTransform, win);
67235
+ parseInlineFormatting(el, options, runs, textTransform, win, preserveWhitespace);
66892
67236
  if (hadPendingSoftBreak && runs.length > runsBeforeRecurse) {
66893
67237
  runs[runsBeforeRecurse].options = {
66894
67238
  ...runs[runsBeforeRecurse].options,
66895
67239
  softBreakBefore: true
66896
67240
  };
66897
67241
  }
67242
+ } else {
67243
+ const blockTags = /* @__PURE__ */ new Set(["P", "DIV", "LI", "BLOCKQUOTE", "PRE", "H1", "H2", "H3", "H4", "H5", "H6"]);
67244
+ if (blockTags.has(el.tagName)) {
67245
+ const runsBeforeRecurse = runs.length;
67246
+ const hadPendingSoftBreak = pendingSoftBreak;
67247
+ if (pendingSoftBreak) {
67248
+ pendingSoftBreak = false;
67249
+ }
67250
+ let blockPreserveWhitespace = preserveWhitespace;
67251
+ const blockComputed = win.getComputedStyle(el);
67252
+ if (el.tagName === "PRE") {
67253
+ const ws = blockComputed.whiteSpace;
67254
+ blockPreserveWhitespace = ws === "pre" || ws === "pre-wrap" || ws === "pre-line";
67255
+ }
67256
+ const blockOptions = { ...baseOptions };
67257
+ const blockIsBold = blockComputed.fontWeight === "bold" || parseInt(blockComputed.fontWeight) >= 600;
67258
+ if (blockIsBold && !shouldSkipBold(blockComputed.fontFamily)) {
67259
+ blockOptions.bold = true;
67260
+ }
67261
+ if (blockComputed.fontStyle === "italic") {
67262
+ blockOptions.italic = true;
67263
+ }
67264
+ if (blockComputed.textDecoration?.includes("underline")) {
67265
+ blockOptions.underline = true;
67266
+ }
67267
+ if (blockComputed.color && blockComputed.color !== "rgb(0, 0, 0)") {
67268
+ blockOptions.color = rgbToHex(blockComputed.color);
67269
+ const transparency = extractAlpha(blockComputed.color);
67270
+ if (transparency !== null)
67271
+ blockOptions.transparency = transparency;
67272
+ }
67273
+ if (blockComputed.fontSize) {
67274
+ blockOptions.fontSize = pxToPoints(blockComputed.fontSize);
67275
+ }
67276
+ if (blockComputed.fontFamily) {
67277
+ blockOptions.fontFace = extractFontFace(blockComputed.fontFamily);
67278
+ }
67279
+ parseInlineFormatting(el, blockOptions, runs, textTransform, win, blockPreserveWhitespace);
67280
+ if (runs.length > runsBeforeRecurse) {
67281
+ if (hadPendingSoftBreak || runsBeforeRecurse > 0) {
67282
+ runs[runsBeforeRecurse].options = {
67283
+ ...runs[runsBeforeRecurse].options,
67284
+ breakLine: true
67285
+ };
67286
+ }
67287
+ }
67288
+ }
66898
67289
  }
66899
67290
  prevNodeIsText = false;
66900
67291
  }
66901
67292
  });
66902
- if (runs.length > 0) {
67293
+ if (!preserveWhitespace && runs.length > 0) {
66903
67294
  runs[0].text = runs[0].text.replace(/^\s+/, "");
66904
67295
  runs[runs.length - 1].text = runs[runs.length - 1].text.replace(/\s+$/, "");
66905
67296
  }
@@ -66934,7 +67325,7 @@ ${generateStylesCss(styleMap, themeFonts)}
66934
67325
  }
66935
67326
  const elements = [];
66936
67327
  const placeholders = [];
66937
- const textTags = ["P", "H1", "H2", "H3", "H4", "H5", "H6", "UL", "OL", "LI", "SPAN"];
67328
+ const textTags = ["P", "H1", "H2", "H3", "H4", "H5", "H6", "UL", "OL", "LI", "SPAN", "PRE"];
66938
67329
  const processed = /* @__PURE__ */ new Set();
66939
67330
  const bodyPseudoElements = extractPseudoElements(body, win);
66940
67331
  elements.push(...bodyPseudoElements);
@@ -66948,32 +67339,24 @@ ${generateStylesCss(styleMap, themeFonts)}
66948
67339
  const hasBorder = computed2.borderWidth && parseFloat(computed2.borderWidth) > 0 || computed2.borderTopWidth && parseFloat(computed2.borderTopWidth) > 0 || computed2.borderRightWidth && parseFloat(computed2.borderRightWidth) > 0 || computed2.borderBottomWidth && parseFloat(computed2.borderBottomWidth) > 0 || computed2.borderLeftWidth && parseFloat(computed2.borderLeftWidth) > 0;
66949
67340
  const hasShadow = computed2.boxShadow && computed2.boxShadow !== "none";
66950
67341
  if (hasBg || hasBorder || hasShadow) {
66951
- errors.push(`Text element <${el.tagName.toLowerCase()}> has ${hasBg ? "background" : hasBorder ? "border" : "shadow"}. Backgrounds, borders, and shadows are only supported on <div> elements, not text elements.`);
66952
- return;
66953
- }
66954
- }
66955
- if (el.tagName === "SPAN" || el.tagName === "A") {
66956
- const computed2 = win.getComputedStyle(el);
66957
- const hasBg = computed2.backgroundColor && computed2.backgroundColor !== "rgba(0, 0, 0, 0)";
66958
- const hasBorder = computed2.borderWidth && parseFloat(computed2.borderWidth) > 0 || computed2.borderTopWidth && parseFloat(computed2.borderTopWidth) > 0 || computed2.borderRightWidth && parseFloat(computed2.borderRightWidth) > 0 || computed2.borderBottomWidth && parseFloat(computed2.borderBottomWidth) > 0 || computed2.borderLeftWidth && parseFloat(computed2.borderLeftWidth) > 0;
66959
- const spanBgImage = computed2.backgroundImage;
66960
- const hasGradientBg = spanBgImage && spanBgImage !== "none" && (spanBgImage.includes("linear-gradient") || spanBgImage.includes("radial-gradient"));
66961
- const spanBgClip = computed2.webkitBackgroundClip || computed2.backgroundClip;
66962
- const spanTextFillColor = computed2.webkitTextFillColor;
66963
- const isGradientTextFill = hasGradientBg && spanBgClip === "text" && (spanTextFillColor === "transparent" || spanTextFillColor === "rgba(0, 0, 0, 0)" || spanTextFillColor && spanTextFillColor.includes("rgba") && spanTextFillColor.endsWith(", 0)"));
66964
- if (isGradientTextFill) {
66965
- } else if (hasBg || hasBorder || hasGradientBg) {
66966
67342
  const rect2 = htmlEl.getBoundingClientRect();
66967
67343
  if (rect2.width > 0 && rect2.height > 0) {
66968
- const text2 = getTransformedText(htmlEl, computed2);
67344
+ const styledTextDisplay = computed2.display;
67345
+ const styledTextFlexDir = computed2.flexDirection || "row";
67346
+ const styledTextChildCount = el.children.length;
67347
+ const isStyledTextFlexRow = (styledTextDisplay === "flex" || styledTextDisplay === "inline-flex") && (styledTextFlexDir === "row" || styledTextFlexDir === "row-reverse") && styledTextChildCount > 1;
67348
+ const isStyledTextFlexCol = (styledTextDisplay === "flex" || styledTextDisplay === "inline-flex") && (styledTextFlexDir === "column" || styledTextFlexDir === "column-reverse") && styledTextChildCount > 1;
67349
+ const isStyledTextGrid = styledTextDisplay === "grid" || styledTextDisplay === "inline-grid";
67350
+ const shouldMergeStyledText = !isStyledTextFlexRow && !isStyledTextFlexCol && !isStyledTextGrid;
67351
+ const text2 = shouldMergeStyledText ? getTransformedText(htmlEl, computed2) : "";
66969
67352
  const bgGradient = parseCssGradient(computed2.backgroundImage);
66970
67353
  const borderRadius = computed2.borderRadius;
66971
67354
  const radiusValue = parseFloat(borderRadius);
66972
67355
  let rectRadius = 0;
66973
67356
  const isCircularRadius = borderRadius.includes("%") ? radiusValue >= 50 : radiusValue > 0 && radiusValue >= Math.min(rect2.width, rect2.height) / 2 - 1;
66974
67357
  const aspectRatio = rect2.width / rect2.height;
66975
- const spanIsEllipse = isCircularRadius && aspectRatio > 0.5 && aspectRatio < 2;
66976
- if (radiusValue > 0 && !spanIsEllipse) {
67358
+ const styledTextIsEllipse = isCircularRadius && aspectRatio > 0.5 && aspectRatio < 2;
67359
+ if (radiusValue > 0 && !styledTextIsEllipse) {
66977
67360
  if (borderRadius.includes("%")) {
66978
67361
  const minDim = Math.min(rect2.width, rect2.height);
66979
67362
  rectRadius = radiusValue / 100 * pxToInch(minDim);
@@ -66985,12 +67368,19 @@ ${generateStylesCss(styleMap, themeFonts)}
66985
67368
  const borderRight = computed2.borderRightWidth;
66986
67369
  const borderBottom = computed2.borderBottomWidth;
66987
67370
  const borderLeft = computed2.borderLeftWidth;
66988
- const hasUniformBorder = hasBorder && borderTop === borderRight && borderRight === borderBottom && borderBottom === borderLeft;
66989
- const spanOpacity = getEffectiveOpacity(el, win);
66990
- const hasSpanOpacity = spanOpacity < 1;
66991
- const spanShadow = parseBoxShadow(computed2.boxShadow);
66992
- const spanWhiteSpace = computed2.whiteSpace;
66993
- const spanShouldNotWrap = spanWhiteSpace === "nowrap" || spanWhiteSpace === "pre" || rect2.width < 100 || rect2.height < 50;
67371
+ const borders = [parseFloat(borderTop) || 0, parseFloat(borderRight) || 0, parseFloat(borderBottom) || 0, parseFloat(borderLeft) || 0];
67372
+ const hasUniformBorder = hasBorder && borders.every((b) => b === borders[0]);
67373
+ const styledTextOpacity = getEffectiveOpacity(el, win);
67374
+ const hasStyledTextOpacity = styledTextOpacity < 1;
67375
+ const styledTextShadow = parseBoxShadow(computed2.boxShadow);
67376
+ const computedAlign = computed2.textAlign;
67377
+ let textAlign2 = "left";
67378
+ if (computedAlign === "center")
67379
+ textAlign2 = "center";
67380
+ else if (computedAlign === "right")
67381
+ textAlign2 = "right";
67382
+ else if (computedAlign === "justify")
67383
+ textAlign2 = "justify";
66994
67384
  const shapeElement = {
66995
67385
  type: "shape",
66996
67386
  position: {
@@ -67006,9 +67396,10 @@ ${generateStylesCss(styleMap, themeFonts)}
67006
67396
  fontFace: extractFontFace(computed2.fontFamily),
67007
67397
  color: rgbToHex(computed2.color),
67008
67398
  bold: parseInt(computed2.fontWeight) >= 600,
67009
- align: "center",
67399
+ align: textAlign2,
67010
67400
  valign: "middle",
67011
- wrap: !spanShouldNotWrap
67401
+ wrap: true,
67402
+ ...extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {}
67012
67403
  } : null,
67013
67404
  shape: {
67014
67405
  fill: hasBg ? rgbToHex(computed2.backgroundColor) : null,
@@ -67020,153 +67411,1073 @@ ${generateStylesCss(styleMap, themeFonts)}
67020
67411
  transparency: extractAlpha(computed2.borderColor),
67021
67412
  dashType: extractDashType(computed2.borderStyle)
67022
67413
  } : null,
67023
- rectRadius: spanIsEllipse ? 0 : rectRadius,
67024
- shadow: spanShadow,
67025
- opacity: hasSpanOpacity ? spanOpacity : null,
67026
- isEllipse: spanIsEllipse,
67414
+ rectRadius: styledTextIsEllipse ? 0 : rectRadius,
67415
+ shadow: styledTextShadow,
67416
+ opacity: hasStyledTextOpacity ? styledTextOpacity : null,
67417
+ isEllipse: styledTextIsEllipse,
67027
67418
  softEdge: null,
67028
67419
  rotate: null,
67420
+ cssTriangle: null,
67029
67421
  customGeometry: null
67030
67422
  }
67031
67423
  };
67032
67424
  elements.push(shapeElement);
67033
- processed.add(el);
67034
- return;
67035
- }
67036
- }
67037
- const parent = el.parentElement;
67038
- if (parent && parent.tagName === "DIV") {
67039
- const rect2 = htmlEl.getBoundingClientRect();
67040
- const computed22 = win.getComputedStyle(el);
67041
- const text2 = getTransformedText(htmlEl, computed22);
67042
- if (rect2.width > 0 && rect2.height > 0 && text2) {
67043
- const fontSizePx2 = parseFloat(computed22.fontSize);
67044
- const lineHeightPx2 = parseFloat(computed22.lineHeight);
67045
- const lineHeightMultiplier2 = fontSizePx2 > 0 && !isNaN(lineHeightPx2) ? lineHeightPx2 / fontSizePx2 : 1;
67046
- const span2BgClip = computed22.webkitBackgroundClip || computed22.backgroundClip;
67047
- const span2TextFillColor = computed22.webkitTextFillColor;
67048
- const span2IsGradientText = span2BgClip === "text" && (span2TextFillColor === "transparent" || span2TextFillColor === "rgba(0, 0, 0, 0)" || span2TextFillColor && span2TextFillColor.includes("rgba") && span2TextFillColor.endsWith(", 0)"));
67049
- const span2BgImage = computed22.backgroundImage;
67050
- const span2HasGradientBg = span2BgImage && span2BgImage !== "none" && (span2BgImage.includes("linear-gradient") || span2BgImage.includes("radial-gradient"));
67051
- let spanFontFill = void 0;
67052
- let spanTextColor = rgbToHex(computed22.color);
67053
- if (span2IsGradientText && span2HasGradientBg) {
67054
- const spanGradient = parseCssGradient(span2BgImage);
67055
- if (spanGradient) {
67056
- spanFontFill = { type: "gradient", gradient: spanGradient };
67057
- spanTextColor = null;
67058
- }
67059
- }
67060
- const textElement = {
67061
- type: "p",
67062
- text: [{ text: text2, options: spanFontFill ? { fontFill: spanFontFill } : {} }],
67063
- position: {
67064
- x: pxToInch(rect2.left),
67065
- y: pxToInch(rect2.top),
67066
- w: pxToInch(rect2.width),
67067
- h: pxToInch(rect2.height)
67068
- },
67069
- style: {
67070
- fontSize: pxToPoints(computed22.fontSize),
67071
- fontFace: extractFontFace(computed22.fontFamily),
67072
- color: spanTextColor,
67073
- bold: parseInt(computed22.fontWeight) >= 600,
67074
- italic: computed22.fontStyle === "italic",
67075
- align: computed22.textAlign === "center" ? "center" : computed22.textAlign === "right" ? "right" : "left",
67076
- valign: "middle",
67077
- lineSpacing: lineHeightMultiplier2 * pxToPoints(computed22.fontSize),
67078
- fontFill: spanFontFill
67079
- }
67080
- };
67081
- elements.push(textElement);
67082
- processed.add(el);
67083
- return;
67084
- }
67085
- }
67086
- }
67087
- if (el.className && typeof el.className === "string" && el.className.includes("placeholder")) {
67088
- const rect2 = htmlEl.getBoundingClientRect();
67089
- if (rect2.width === 0 || rect2.height === 0) {
67090
- errors.push(`Placeholder "${el.id || "unnamed"}" has ${rect2.width === 0 ? "width: 0" : "height: 0"}. Check the layout CSS.`);
67091
- } else {
67092
- placeholders.push({
67093
- id: el.id || `placeholder-${placeholders.length}`,
67094
- x: pxToInch(rect2.left),
67095
- y: pxToInch(rect2.top),
67096
- w: pxToInch(rect2.width),
67097
- h: pxToInch(rect2.height)
67098
- });
67099
- }
67100
- processed.add(el);
67101
- return;
67102
- }
67103
- if (el.tagName === "IMG") {
67104
- const rect2 = htmlEl.getBoundingClientRect();
67105
- if (rect2.width > 0 && rect2.height > 0) {
67106
- const imgComputed = win.getComputedStyle(el);
67107
- const bodyRect = doc.body.getBoundingClientRect();
67108
- const coversWidth = rect2.width >= bodyRect.width * 0.95;
67109
- const coversHeight = rect2.height >= bodyRect.height * 0.95;
67110
- const nearOrigin = rect2.left <= 10 && rect2.top <= 10;
67111
- const isFullSlideImage = coversWidth && coversHeight && nearOrigin;
67112
- const objectFit = imgComputed.objectFit;
67113
- let imgRectRadius = null;
67114
- let clipLeft = rect2.left;
67115
- let clipTop = rect2.top;
67116
- let clipRight = rect2.right;
67117
- let clipBottom = rect2.bottom;
67118
- let ancestor = el.parentElement;
67119
- while (ancestor && ancestor !== doc.body) {
67120
- const ancestorComputed = win.getComputedStyle(ancestor);
67121
- const ancestorOverflow = ancestorComputed.overflow;
67122
- if (ancestorOverflow === "hidden" || ancestorOverflow === "clip") {
67123
- const ancestorRect = ancestor.getBoundingClientRect();
67124
- clipLeft = Math.max(clipLeft, ancestorRect.left);
67125
- clipTop = Math.max(clipTop, ancestorRect.top);
67126
- clipRight = Math.min(clipRight, ancestorRect.right);
67127
- clipBottom = Math.min(clipBottom, ancestorRect.bottom);
67128
- const ancestorBorderRadius = ancestorComputed.borderRadius;
67129
- if (ancestorBorderRadius && imgRectRadius === null) {
67130
- const radiusValue = parseFloat(ancestorBorderRadius);
67425
+ if (hasBorder && !hasUniformBorder) {
67426
+ const topRightBottomBorders = [borders[0], borders[1], borders[2]].filter((b) => b > 0);
67427
+ const minTopRightBottom = topRightBottomBorders.length > 0 ? Math.min(...topRightBottomBorders) : 0;
67428
+ const topLeftBottomBorders = [borders[0], borders[3], borders[2]].filter((b) => b > 0);
67429
+ const minTopLeftBottom = topLeftBottomBorders.length > 0 ? Math.min(...topLeftBottomBorders) : 0;
67430
+ const borderLeftW = borders[3];
67431
+ const borderRightW = borders[1];
67432
+ const borderLeftHex = rgbToHex(computed2.borderLeftColor);
67433
+ const borderRightHex = rgbToHex(computed2.borderRightColor);
67434
+ const borderTopHex = rgbToHex(computed2.borderTopColor);
67435
+ const borderLeftAlpha = extractAlpha(computed2.borderLeftColor);
67436
+ const borderTopAlpha = extractAlpha(computed2.borderTopColor);
67437
+ const borderRightAlpha = extractAlpha(computed2.borderRightColor);
67438
+ const borderLeftHasDifferentColor = borderTopHex !== borderLeftHex;
67439
+ const borderLeftIsMoreOpaque = (borderLeftAlpha ?? 0) < (borderTopAlpha ?? 0);
67440
+ if (borderLeftW > 0 && !isFullyTransparent(computed2.borderLeftColor) && (borderLeftW > minTopRightBottom || minTopRightBottom === 0 || borderLeftHasDifferentColor || borderLeftIsMoreOpaque)) {
67131
67441
  if (radiusValue > 0) {
67132
- if (ancestorBorderRadius.includes("%")) {
67133
- const minDim = Math.min(ancestorRect.width, ancestorRect.height);
67134
- imgRectRadius = radiusValue / 100 * pxToInch(minDim);
67135
- } else if (ancestorBorderRadius.includes("pt")) {
67136
- imgRectRadius = radiusValue / 72;
67137
- } else {
67138
- imgRectRadius = pxToInch(radiusValue);
67442
+ const w2 = borderLeftW;
67443
+ const h2 = rect2.height;
67444
+ const r = radiusValue;
67445
+ const EMU_PER_PX3 = 914400 / 96;
67446
+ const arcYAtX = (radius, x2) => {
67447
+ if (x2 <= 0)
67448
+ return radius;
67449
+ if (x2 >= radius)
67450
+ return 0;
67451
+ const dx = radius - x2;
67452
+ return radius - Math.sqrt(radius * radius - dx * dx);
67453
+ };
67454
+ const segments = 8;
67455
+ const arcPointsTop = [];
67456
+ const arcPointsBottom = [];
67457
+ for (let i = 0; i <= segments; i++) {
67458
+ const t = i / segments;
67459
+ const x2 = t * w2;
67460
+ const arcDistance = arcYAtX(r, x2);
67461
+ arcPointsTop.push({
67462
+ x: Math.round(x2 * EMU_PER_PX3),
67463
+ y: Math.round(arcDistance * EMU_PER_PX3)
67464
+ });
67465
+ arcPointsBottom.push({
67466
+ x: Math.round(x2 * EMU_PER_PX3),
67467
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
67468
+ });
67139
67469
  }
67140
- }
67141
- }
67142
- }
67143
- ancestor = ancestor.parentElement;
67144
- }
67145
- const clippedW = Math.max(0, clipRight - clipLeft);
67146
- const clippedH = Math.max(0, clipBottom - clipTop);
67147
- const wasClipped = clippedW < rect2.width - 1 || clippedH < rect2.height - 1;
67148
- const cssFilter = imgComputed.filter;
67149
- let imgSrc = el.src;
67150
- let filterPreBaked = false;
67151
- if (cssFilter && cssFilter !== "none") {
67152
- const bakedSrc = applyImageFilter(el, cssFilter);
67153
- if (bakedSrc !== imgSrc) {
67154
- imgSrc = bakedSrc;
67155
- filterPreBaked = true;
67156
- }
67157
- }
67158
- const maskImageProp = imgComputed.maskImage || imgComputed.webkitMaskImage || imgComputed.getPropertyValue("mask-image") || imgComputed.getPropertyValue("-webkit-mask-image");
67159
- const imgOpacity = getEffectiveOpacity(el, win);
67160
- const hasOpacity = imgOpacity < 1 && imgOpacity >= 0;
67161
- let maskApplied = false;
67162
- if (maskImageProp && maskImageProp !== "none" && (maskImageProp.includes("linear-gradient") || maskImageProp.includes("radial-gradient"))) {
67163
- const maskGradient = parseCssGradient(maskImageProp);
67164
- if (maskGradient) {
67165
- const displayW = wasClipped ? clippedW : rect2.width;
67166
- const displayH = wasClipped ? clippedH : rect2.height;
67167
- const maskedSrc = applyImageMask(el, maskGradient, displayW, displayH, hasOpacity ? imgOpacity : void 0);
67168
- if (maskedSrc) {
67169
- imgSrc = maskedSrc;
67470
+ const points = [];
67471
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
67472
+ for (let i = 1; i <= segments; i++) {
67473
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
67474
+ }
67475
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
67476
+ for (let i = segments - 1; i >= 0; i--) {
67477
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
67478
+ }
67479
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
67480
+ const borderLeftShape = {
67481
+ type: "shape",
67482
+ text: "",
67483
+ textRuns: null,
67484
+ style: null,
67485
+ position: {
67486
+ x: pxToInch(rect2.left),
67487
+ y: pxToInch(rect2.top),
67488
+ w: pxToInch(borderLeftW),
67489
+ h: pxToInch(rect2.height)
67490
+ },
67491
+ shape: {
67492
+ fill: rgbToHex(computed2.borderLeftColor),
67493
+ gradient: null,
67494
+ transparency: extractAlpha(computed2.borderLeftColor),
67495
+ line: null,
67496
+ rectRadius: 0,
67497
+ shadow: null,
67498
+ opacity: null,
67499
+ isEllipse: false,
67500
+ softEdge: null,
67501
+ rotate: null,
67502
+ cssTriangle: null,
67503
+ customGeometry: points
67504
+ }
67505
+ };
67506
+ elements.push(borderLeftShape);
67507
+ } else {
67508
+ const borderLeftShape = {
67509
+ type: "shape",
67510
+ text: "",
67511
+ textRuns: null,
67512
+ style: null,
67513
+ position: {
67514
+ x: pxToInch(rect2.left),
67515
+ y: pxToInch(rect2.top),
67516
+ w: pxToInch(borderLeftW),
67517
+ h: pxToInch(rect2.height)
67518
+ },
67519
+ shape: {
67520
+ fill: rgbToHex(computed2.borderLeftColor),
67521
+ gradient: null,
67522
+ transparency: extractAlpha(computed2.borderLeftColor),
67523
+ line: null,
67524
+ rectRadius: 0,
67525
+ shadow: null,
67526
+ opacity: null,
67527
+ isEllipse: false,
67528
+ softEdge: null,
67529
+ rotate: null,
67530
+ cssTriangle: null,
67531
+ customGeometry: null
67532
+ }
67533
+ };
67534
+ elements.push(borderLeftShape);
67535
+ }
67536
+ }
67537
+ const borderRightHasDifferentColor = borderTopHex !== borderRightHex;
67538
+ const borderRightIsMoreOpaque = (borderRightAlpha ?? 0) < (borderTopAlpha ?? 0);
67539
+ if (borderRightW > 0 && !isFullyTransparent(computed2.borderRightColor) && (borderRightW > minTopLeftBottom || minTopLeftBottom === 0 || borderRightHasDifferentColor || borderRightIsMoreOpaque)) {
67540
+ if (radiusValue > 0) {
67541
+ const w2 = borderRightW;
67542
+ const h2 = rect2.height;
67543
+ const r = radiusValue;
67544
+ const EMU_PER_PX3 = 914400 / 96;
67545
+ const arcYAtX = (radius, x2) => {
67546
+ if (x2 <= 0)
67547
+ return radius;
67548
+ if (x2 >= radius)
67549
+ return 0;
67550
+ const dx = radius - x2;
67551
+ return radius - Math.sqrt(radius * radius - dx * dx);
67552
+ };
67553
+ const segments = 8;
67554
+ const arcPointsTop = [];
67555
+ const arcPointsBottom = [];
67556
+ for (let i = 0; i <= segments; i++) {
67557
+ const t = i / segments;
67558
+ const x2 = t * w2;
67559
+ const arcDistance = arcYAtX(r, w2 - x2);
67560
+ arcPointsTop.push({
67561
+ x: Math.round(x2 * EMU_PER_PX3),
67562
+ y: Math.round(arcDistance * EMU_PER_PX3)
67563
+ });
67564
+ arcPointsBottom.push({
67565
+ x: Math.round(x2 * EMU_PER_PX3),
67566
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
67567
+ });
67568
+ }
67569
+ const points = [];
67570
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
67571
+ for (let i = 1; i <= segments; i++) {
67572
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
67573
+ }
67574
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
67575
+ for (let i = segments - 1; i >= 0; i--) {
67576
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
67577
+ }
67578
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
67579
+ const borderRightShape = {
67580
+ type: "shape",
67581
+ text: "",
67582
+ textRuns: null,
67583
+ style: null,
67584
+ position: {
67585
+ x: pxToInch(rect2.left + rect2.width - borderRightW),
67586
+ y: pxToInch(rect2.top),
67587
+ w: pxToInch(borderRightW),
67588
+ h: pxToInch(rect2.height)
67589
+ },
67590
+ shape: {
67591
+ fill: rgbToHex(computed2.borderRightColor),
67592
+ gradient: null,
67593
+ transparency: extractAlpha(computed2.borderRightColor),
67594
+ line: null,
67595
+ rectRadius: 0,
67596
+ shadow: null,
67597
+ opacity: null,
67598
+ isEllipse: false,
67599
+ softEdge: null,
67600
+ rotate: null,
67601
+ cssTriangle: null,
67602
+ customGeometry: points
67603
+ }
67604
+ };
67605
+ elements.push(borderRightShape);
67606
+ } else {
67607
+ const borderRightShape = {
67608
+ type: "shape",
67609
+ text: "",
67610
+ textRuns: null,
67611
+ style: null,
67612
+ position: {
67613
+ x: pxToInch(rect2.left + rect2.width - borderRightW),
67614
+ y: pxToInch(rect2.top),
67615
+ w: pxToInch(borderRightW),
67616
+ h: pxToInch(rect2.height)
67617
+ },
67618
+ shape: {
67619
+ fill: rgbToHex(computed2.borderRightColor),
67620
+ gradient: null,
67621
+ transparency: extractAlpha(computed2.borderRightColor),
67622
+ line: null,
67623
+ rectRadius: 0,
67624
+ shadow: null,
67625
+ opacity: null,
67626
+ isEllipse: false,
67627
+ softEdge: null,
67628
+ rotate: null,
67629
+ cssTriangle: null,
67630
+ customGeometry: null
67631
+ }
67632
+ };
67633
+ elements.push(borderRightShape);
67634
+ }
67635
+ }
67636
+ }
67637
+ const leftRightBottomBorders = [borders[3], borders[1], borders[2]].filter((b) => b > 0);
67638
+ const minLeftRightBottom = leftRightBottomBorders.length > 0 ? Math.min(...leftRightBottomBorders) : 0;
67639
+ const leftRightTopBorders = [borders[3], borders[1], borders[0]].filter((b) => b > 0);
67640
+ const minLeftRightTop = leftRightTopBorders.length > 0 ? Math.min(...leftRightTopBorders) : 0;
67641
+ const borderTopW = borders[0];
67642
+ if (borderTopW > 0 && !isFullyTransparent(computed2.borderTopColor) && (borderTopW > minLeftRightBottom || minLeftRightBottom === 0)) {
67643
+ if (radiusValue > 0) {
67644
+ const w2 = rect2.width;
67645
+ const h2 = borderTopW;
67646
+ const r = radiusValue;
67647
+ const EMU_PER_PX3 = 914400 / 96;
67648
+ const arcXAtY = (radius, y2) => {
67649
+ if (y2 <= 0)
67650
+ return radius;
67651
+ if (y2 >= radius)
67652
+ return 0;
67653
+ const dy = radius - y2;
67654
+ return radius - Math.sqrt(radius * radius - dy * dy);
67655
+ };
67656
+ const segments = 8;
67657
+ const arcPointsLeft = [];
67658
+ const arcPointsRight = [];
67659
+ for (let i = 0; i <= segments; i++) {
67660
+ const t = i / segments;
67661
+ const y2 = t * h2;
67662
+ const arcDistance = arcXAtY(r, y2);
67663
+ arcPointsLeft.push({
67664
+ x: Math.round(arcDistance * EMU_PER_PX3),
67665
+ y: Math.round(y2 * EMU_PER_PX3)
67666
+ });
67667
+ arcPointsRight.push({
67668
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
67669
+ y: Math.round(y2 * EMU_PER_PX3)
67670
+ });
67671
+ }
67672
+ const points = [];
67673
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
67674
+ for (let i = 1; i <= segments; i++) {
67675
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
67676
+ }
67677
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
67678
+ for (let i = segments - 1; i >= 0; i--) {
67679
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
67680
+ }
67681
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
67682
+ const borderTopShape = {
67683
+ type: "shape",
67684
+ text: "",
67685
+ textRuns: null,
67686
+ style: null,
67687
+ position: {
67688
+ x: pxToInch(rect2.left),
67689
+ y: pxToInch(rect2.top),
67690
+ w: pxToInch(rect2.width),
67691
+ h: pxToInch(borderTopW)
67692
+ },
67693
+ shape: {
67694
+ fill: rgbToHex(computed2.borderTopColor),
67695
+ gradient: null,
67696
+ transparency: extractAlpha(computed2.borderTopColor),
67697
+ line: null,
67698
+ rectRadius: 0,
67699
+ shadow: null,
67700
+ opacity: null,
67701
+ isEllipse: false,
67702
+ softEdge: null,
67703
+ rotate: null,
67704
+ cssTriangle: null,
67705
+ customGeometry: points
67706
+ }
67707
+ };
67708
+ elements.push(borderTopShape);
67709
+ } else {
67710
+ const borderTopShape = {
67711
+ type: "shape",
67712
+ text: "",
67713
+ textRuns: null,
67714
+ style: null,
67715
+ position: {
67716
+ x: pxToInch(rect2.left),
67717
+ y: pxToInch(rect2.top),
67718
+ w: pxToInch(rect2.width),
67719
+ h: pxToInch(borderTopW)
67720
+ },
67721
+ shape: {
67722
+ fill: rgbToHex(computed2.borderTopColor),
67723
+ gradient: null,
67724
+ transparency: extractAlpha(computed2.borderTopColor),
67725
+ line: null,
67726
+ rectRadius: 0,
67727
+ shadow: null,
67728
+ opacity: null,
67729
+ isEllipse: false,
67730
+ softEdge: null,
67731
+ rotate: null,
67732
+ cssTriangle: null,
67733
+ customGeometry: null
67734
+ }
67735
+ };
67736
+ elements.push(borderTopShape);
67737
+ }
67738
+ }
67739
+ const borderBottomW = borders[2];
67740
+ if (borderBottomW > 0 && !isFullyTransparent(computed2.borderBottomColor) && (borderBottomW > minLeftRightTop || minLeftRightTop === 0)) {
67741
+ if (radiusValue > 0) {
67742
+ const w2 = rect2.width;
67743
+ const h2 = borderBottomW;
67744
+ const r = radiusValue;
67745
+ const EMU_PER_PX3 = 914400 / 96;
67746
+ const arcXAtY = (radius, y2) => {
67747
+ if (y2 <= 0)
67748
+ return radius;
67749
+ if (y2 >= radius)
67750
+ return 0;
67751
+ const dy = radius - y2;
67752
+ return radius - Math.sqrt(radius * radius - dy * dy);
67753
+ };
67754
+ const segments = 8;
67755
+ const arcPointsLeft = [];
67756
+ const arcPointsRight = [];
67757
+ for (let i = 0; i <= segments; i++) {
67758
+ const t = i / segments;
67759
+ const y2 = t * h2;
67760
+ const arcDistance = arcXAtY(r, h2 - y2);
67761
+ arcPointsLeft.push({
67762
+ x: Math.round(arcDistance * EMU_PER_PX3),
67763
+ y: Math.round(y2 * EMU_PER_PX3)
67764
+ });
67765
+ arcPointsRight.push({
67766
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
67767
+ y: Math.round(y2 * EMU_PER_PX3)
67768
+ });
67769
+ }
67770
+ const points = [];
67771
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
67772
+ for (let i = 1; i <= segments; i++) {
67773
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
67774
+ }
67775
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
67776
+ for (let i = segments - 1; i >= 0; i--) {
67777
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
67778
+ }
67779
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
67780
+ const borderBottomShape = {
67781
+ type: "shape",
67782
+ text: "",
67783
+ textRuns: null,
67784
+ style: null,
67785
+ position: {
67786
+ x: pxToInch(rect2.left),
67787
+ y: pxToInch(rect2.top + rect2.height - borderBottomW),
67788
+ w: pxToInch(rect2.width),
67789
+ h: pxToInch(borderBottomW)
67790
+ },
67791
+ shape: {
67792
+ fill: rgbToHex(computed2.borderBottomColor),
67793
+ gradient: null,
67794
+ transparency: extractAlpha(computed2.borderBottomColor),
67795
+ line: null,
67796
+ rectRadius: 0,
67797
+ shadow: null,
67798
+ opacity: null,
67799
+ isEllipse: false,
67800
+ softEdge: null,
67801
+ rotate: null,
67802
+ cssTriangle: null,
67803
+ customGeometry: points
67804
+ }
67805
+ };
67806
+ elements.push(borderBottomShape);
67807
+ } else {
67808
+ const borderBottomShape = {
67809
+ type: "shape",
67810
+ text: "",
67811
+ textRuns: null,
67812
+ style: null,
67813
+ position: {
67814
+ x: pxToInch(rect2.left),
67815
+ y: pxToInch(rect2.top + rect2.height - borderBottomW),
67816
+ w: pxToInch(rect2.width),
67817
+ h: pxToInch(borderBottomW)
67818
+ },
67819
+ shape: {
67820
+ fill: rgbToHex(computed2.borderBottomColor),
67821
+ gradient: null,
67822
+ transparency: extractAlpha(computed2.borderBottomColor),
67823
+ line: null,
67824
+ rectRadius: 0,
67825
+ shadow: null,
67826
+ opacity: null,
67827
+ isEllipse: false,
67828
+ softEdge: null,
67829
+ rotate: null,
67830
+ cssTriangle: null,
67831
+ customGeometry: null
67832
+ }
67833
+ };
67834
+ elements.push(borderBottomShape);
67835
+ }
67836
+ }
67837
+ }
67838
+ processed.add(el);
67839
+ return;
67840
+ }
67841
+ }
67842
+ if (el.tagName === "SPAN" || el.tagName === "A" || el.tagName === "CODE") {
67843
+ const spanText = el.textContent?.trim() || "";
67844
+ const isEmptyDecorative = spanText.length === 0;
67845
+ const parentTag = el.parentElement?.tagName;
67846
+ const textParentTags = /* @__PURE__ */ new Set(["P", "H1", "H2", "H3", "H4", "H5", "H6", "LI", "TD", "TH", "FIGCAPTION", "BLOCKQUOTE", "LABEL"]);
67847
+ if (parentTag && textParentTags.has(parentTag) && !isEmptyDecorative) {
67848
+ processed.add(el);
67849
+ return;
67850
+ }
67851
+ const computed2 = win.getComputedStyle(el);
67852
+ const hasBg = computed2.backgroundColor && computed2.backgroundColor !== "rgba(0, 0, 0, 0)";
67853
+ const hasBorder = computed2.borderWidth && parseFloat(computed2.borderWidth) > 0 || computed2.borderTopWidth && parseFloat(computed2.borderTopWidth) > 0 || computed2.borderRightWidth && parseFloat(computed2.borderRightWidth) > 0 || computed2.borderBottomWidth && parseFloat(computed2.borderBottomWidth) > 0 || computed2.borderLeftWidth && parseFloat(computed2.borderLeftWidth) > 0;
67854
+ const spanBgImage = computed2.backgroundImage;
67855
+ const hasGradientBg = spanBgImage && spanBgImage !== "none" && (spanBgImage.includes("linear-gradient") || spanBgImage.includes("radial-gradient"));
67856
+ const spanBgClip = computed2.webkitBackgroundClip || computed2.backgroundClip;
67857
+ const spanTextFillColor = computed2.webkitTextFillColor;
67858
+ const isGradientTextFill = hasGradientBg && spanBgClip === "text" && (spanTextFillColor === "transparent" || spanTextFillColor === "rgba(0, 0, 0, 0)" || spanTextFillColor && spanTextFillColor.includes("rgba") && spanTextFillColor.endsWith(", 0)"));
67859
+ if (isGradientTextFill) {
67860
+ } else if (hasBg || hasBorder || hasGradientBg) {
67861
+ const rect2 = htmlEl.getBoundingClientRect();
67862
+ if (rect2.width > 0 && rect2.height > 0) {
67863
+ const text2 = getTransformedText(htmlEl, computed2);
67864
+ const bgGradient = parseCssGradient(computed2.backgroundImage);
67865
+ const borderRadius = computed2.borderRadius;
67866
+ const radiusValue = parseFloat(borderRadius);
67867
+ let rectRadius = 0;
67868
+ const isCircularRadius = borderRadius.includes("%") ? radiusValue >= 50 : radiusValue > 0 && radiusValue >= Math.min(rect2.width, rect2.height) / 2 - 1;
67869
+ const aspectRatio = rect2.width / rect2.height;
67870
+ const spanIsEllipse = isCircularRadius && aspectRatio > 0.5 && aspectRatio < 2;
67871
+ if (radiusValue > 0 && !spanIsEllipse) {
67872
+ if (borderRadius.includes("%")) {
67873
+ const minDim = Math.min(rect2.width, rect2.height);
67874
+ rectRadius = radiusValue / 100 * pxToInch(minDim);
67875
+ } else {
67876
+ rectRadius = pxToInch(radiusValue);
67877
+ }
67878
+ }
67879
+ const borderTop = computed2.borderTopWidth;
67880
+ const borderRight = computed2.borderRightWidth;
67881
+ const borderBottom = computed2.borderBottomWidth;
67882
+ const borderLeft = computed2.borderLeftWidth;
67883
+ const borders = [parseFloat(borderTop) || 0, parseFloat(borderRight) || 0, parseFloat(borderBottom) || 0, parseFloat(borderLeft) || 0];
67884
+ const hasUniformBorder = hasBorder && borders.every((b) => b === borders[0]);
67885
+ const spanOpacity = getEffectiveOpacity(el, win);
67886
+ const hasSpanOpacity = spanOpacity < 1;
67887
+ const spanShadow = parseBoxShadow(computed2.boxShadow);
67888
+ const spanWhiteSpace = computed2.whiteSpace;
67889
+ const spanShouldNotWrap = spanWhiteSpace === "nowrap" || spanWhiteSpace === "pre" || rect2.width < 100 || rect2.height < 50;
67890
+ const shapeElement = {
67891
+ type: "shape",
67892
+ position: {
67893
+ x: pxToInch(rect2.left),
67894
+ y: pxToInch(rect2.top),
67895
+ w: pxToInch(rect2.width),
67896
+ h: pxToInch(rect2.height)
67897
+ },
67898
+ text: text2,
67899
+ textRuns: null,
67900
+ style: text2 ? {
67901
+ fontSize: pxToPoints(computed2.fontSize),
67902
+ fontFace: extractFontFace(computed2.fontFamily),
67903
+ color: rgbToHex(computed2.color),
67904
+ bold: parseInt(computed2.fontWeight) >= 600,
67905
+ align: "center",
67906
+ valign: "middle",
67907
+ wrap: !spanShouldNotWrap,
67908
+ ...extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {}
67909
+ } : null,
67910
+ shape: {
67911
+ fill: hasBg ? rgbToHex(computed2.backgroundColor) : null,
67912
+ gradient: bgGradient,
67913
+ transparency: hasBg ? extractAlpha(computed2.backgroundColor) : null,
67914
+ line: hasUniformBorder ? {
67915
+ color: rgbToHex(computed2.borderColor),
67916
+ width: pxToPoints(borderTop),
67917
+ transparency: extractAlpha(computed2.borderColor),
67918
+ dashType: extractDashType(computed2.borderStyle)
67919
+ } : null,
67920
+ rectRadius: spanIsEllipse ? 0 : rectRadius,
67921
+ shadow: spanShadow,
67922
+ opacity: hasSpanOpacity ? spanOpacity : null,
67923
+ isEllipse: spanIsEllipse,
67924
+ softEdge: null,
67925
+ rotate: null,
67926
+ cssTriangle: null,
67927
+ customGeometry: null
67928
+ }
67929
+ };
67930
+ elements.push(shapeElement);
67931
+ if (hasBorder && !hasUniformBorder) {
67932
+ const topRightBottomBorders = [borders[0], borders[1], borders[2]].filter((b) => b > 0);
67933
+ const minTopRightBottom = topRightBottomBorders.length > 0 ? Math.min(...topRightBottomBorders) : 0;
67934
+ const topLeftBottomBorders = [borders[0], borders[3], borders[2]].filter((b) => b > 0);
67935
+ const minTopLeftBottom = topLeftBottomBorders.length > 0 ? Math.min(...topLeftBottomBorders) : 0;
67936
+ const borderLeftW = borders[3];
67937
+ const borderRightW = borders[1];
67938
+ const borderLeftHex = rgbToHex(computed2.borderLeftColor);
67939
+ const borderRightHex = rgbToHex(computed2.borderRightColor);
67940
+ const borderTopHex = rgbToHex(computed2.borderTopColor);
67941
+ const borderLeftAlpha = extractAlpha(computed2.borderLeftColor);
67942
+ const borderTopAlpha = extractAlpha(computed2.borderTopColor);
67943
+ const borderRightAlpha = extractAlpha(computed2.borderRightColor);
67944
+ const borderLeftHasDifferentColor = borderTopHex !== borderLeftHex;
67945
+ const borderLeftIsMoreOpaque = (borderLeftAlpha ?? 0) < (borderTopAlpha ?? 0);
67946
+ if (borderLeftW > 0 && !isFullyTransparent(computed2.borderLeftColor) && (borderLeftW > minTopRightBottom || minTopRightBottom === 0 || borderLeftHasDifferentColor || borderLeftIsMoreOpaque)) {
67947
+ if (radiusValue > 0) {
67948
+ const w2 = borderLeftW;
67949
+ const h2 = rect2.height;
67950
+ const r = radiusValue;
67951
+ const EMU_PER_PX3 = 914400 / 96;
67952
+ const arcYAtX = (radius, x2) => {
67953
+ if (x2 <= 0)
67954
+ return radius;
67955
+ if (x2 >= radius)
67956
+ return 0;
67957
+ const dx = radius - x2;
67958
+ return radius - Math.sqrt(radius * radius - dx * dx);
67959
+ };
67960
+ const segments = 8;
67961
+ const arcPointsTop = [];
67962
+ const arcPointsBottom = [];
67963
+ for (let i = 0; i <= segments; i++) {
67964
+ const t = i / segments;
67965
+ const x2 = t * w2;
67966
+ const arcDistance = arcYAtX(r, x2);
67967
+ arcPointsTop.push({
67968
+ x: Math.round(x2 * EMU_PER_PX3),
67969
+ y: Math.round(arcDistance * EMU_PER_PX3)
67970
+ });
67971
+ arcPointsBottom.push({
67972
+ x: Math.round(x2 * EMU_PER_PX3),
67973
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
67974
+ });
67975
+ }
67976
+ const points = [];
67977
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
67978
+ for (let i = 1; i <= segments; i++) {
67979
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
67980
+ }
67981
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
67982
+ for (let i = segments - 1; i >= 0; i--) {
67983
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
67984
+ }
67985
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
67986
+ const borderLeftShape = {
67987
+ type: "shape",
67988
+ text: "",
67989
+ textRuns: null,
67990
+ style: null,
67991
+ position: {
67992
+ x: pxToInch(rect2.left),
67993
+ y: pxToInch(rect2.top),
67994
+ w: pxToInch(borderLeftW),
67995
+ h: pxToInch(rect2.height)
67996
+ },
67997
+ shape: {
67998
+ fill: rgbToHex(computed2.borderLeftColor),
67999
+ gradient: null,
68000
+ transparency: extractAlpha(computed2.borderLeftColor),
68001
+ line: null,
68002
+ rectRadius: 0,
68003
+ shadow: null,
68004
+ opacity: null,
68005
+ isEllipse: false,
68006
+ softEdge: null,
68007
+ rotate: null,
68008
+ cssTriangle: null,
68009
+ customGeometry: points
68010
+ }
68011
+ };
68012
+ elements.push(borderLeftShape);
68013
+ } else {
68014
+ const borderLeftShape = {
68015
+ type: "shape",
68016
+ text: "",
68017
+ textRuns: null,
68018
+ style: null,
68019
+ position: {
68020
+ x: pxToInch(rect2.left),
68021
+ y: pxToInch(rect2.top),
68022
+ w: pxToInch(borderLeftW),
68023
+ h: pxToInch(rect2.height)
68024
+ },
68025
+ shape: {
68026
+ fill: rgbToHex(computed2.borderLeftColor),
68027
+ gradient: null,
68028
+ transparency: extractAlpha(computed2.borderLeftColor),
68029
+ line: null,
68030
+ rectRadius: 0,
68031
+ shadow: null,
68032
+ opacity: null,
68033
+ isEllipse: false,
68034
+ softEdge: null,
68035
+ rotate: null,
68036
+ cssTriangle: null,
68037
+ customGeometry: null
68038
+ }
68039
+ };
68040
+ elements.push(borderLeftShape);
68041
+ }
68042
+ }
68043
+ const borderRightHasDifferentColor = borderTopHex !== borderRightHex;
68044
+ const borderRightIsMoreOpaque = (borderRightAlpha ?? 0) < (borderTopAlpha ?? 0);
68045
+ if (borderRightW > 0 && !isFullyTransparent(computed2.borderRightColor) && (borderRightW > minTopLeftBottom || minTopLeftBottom === 0 || borderRightHasDifferentColor || borderRightIsMoreOpaque)) {
68046
+ if (radiusValue > 0) {
68047
+ const w2 = borderRightW;
68048
+ const h2 = rect2.height;
68049
+ const r = radiusValue;
68050
+ const EMU_PER_PX3 = 914400 / 96;
68051
+ const arcYAtX = (radius, x2) => {
68052
+ if (x2 <= 0)
68053
+ return radius;
68054
+ if (x2 >= radius)
68055
+ return 0;
68056
+ const dx = radius - x2;
68057
+ return radius - Math.sqrt(radius * radius - dx * dx);
68058
+ };
68059
+ const segments = 8;
68060
+ const arcPointsTop = [];
68061
+ const arcPointsBottom = [];
68062
+ for (let i = 0; i <= segments; i++) {
68063
+ const t = i / segments;
68064
+ const x2 = t * w2;
68065
+ const arcDistance = arcYAtX(r, w2 - x2);
68066
+ arcPointsTop.push({
68067
+ x: Math.round(x2 * EMU_PER_PX3),
68068
+ y: Math.round(arcDistance * EMU_PER_PX3)
68069
+ });
68070
+ arcPointsBottom.push({
68071
+ x: Math.round(x2 * EMU_PER_PX3),
68072
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
68073
+ });
68074
+ }
68075
+ const points = [];
68076
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
68077
+ for (let i = 1; i <= segments; i++) {
68078
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
68079
+ }
68080
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
68081
+ for (let i = segments - 1; i >= 0; i--) {
68082
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
68083
+ }
68084
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
68085
+ const borderRightShape = {
68086
+ type: "shape",
68087
+ text: "",
68088
+ textRuns: null,
68089
+ style: null,
68090
+ position: {
68091
+ x: pxToInch(rect2.left + rect2.width - borderRightW),
68092
+ y: pxToInch(rect2.top),
68093
+ w: pxToInch(borderRightW),
68094
+ h: pxToInch(rect2.height)
68095
+ },
68096
+ shape: {
68097
+ fill: rgbToHex(computed2.borderRightColor),
68098
+ gradient: null,
68099
+ transparency: extractAlpha(computed2.borderRightColor),
68100
+ line: null,
68101
+ rectRadius: 0,
68102
+ shadow: null,
68103
+ opacity: null,
68104
+ isEllipse: false,
68105
+ softEdge: null,
68106
+ rotate: null,
68107
+ cssTriangle: null,
68108
+ customGeometry: points
68109
+ }
68110
+ };
68111
+ elements.push(borderRightShape);
68112
+ } else {
68113
+ const borderRightShape = {
68114
+ type: "shape",
68115
+ text: "",
68116
+ textRuns: null,
68117
+ style: null,
68118
+ position: {
68119
+ x: pxToInch(rect2.left + rect2.width - borderRightW),
68120
+ y: pxToInch(rect2.top),
68121
+ w: pxToInch(borderRightW),
68122
+ h: pxToInch(rect2.height)
68123
+ },
68124
+ shape: {
68125
+ fill: rgbToHex(computed2.borderRightColor),
68126
+ gradient: null,
68127
+ transparency: extractAlpha(computed2.borderRightColor),
68128
+ line: null,
68129
+ rectRadius: 0,
68130
+ shadow: null,
68131
+ opacity: null,
68132
+ isEllipse: false,
68133
+ softEdge: null,
68134
+ rotate: null,
68135
+ cssTriangle: null,
68136
+ customGeometry: null
68137
+ }
68138
+ };
68139
+ elements.push(borderRightShape);
68140
+ }
68141
+ }
68142
+ }
68143
+ const leftRightBottomBorders = [borders[3], borders[1], borders[2]].filter((b) => b > 0);
68144
+ const minLeftRightBottom = leftRightBottomBorders.length > 0 ? Math.min(...leftRightBottomBorders) : 0;
68145
+ const leftRightTopBorders = [borders[3], borders[1], borders[0]].filter((b) => b > 0);
68146
+ const minLeftRightTop = leftRightTopBorders.length > 0 ? Math.min(...leftRightTopBorders) : 0;
68147
+ const borderTopW = borders[0];
68148
+ if (borderTopW > 0 && !isFullyTransparent(computed2.borderTopColor) && (borderTopW > minLeftRightBottom || minLeftRightBottom === 0)) {
68149
+ if (radiusValue > 0) {
68150
+ const w2 = rect2.width;
68151
+ const h2 = borderTopW;
68152
+ const r = radiusValue;
68153
+ const EMU_PER_PX3 = 914400 / 96;
68154
+ const arcXAtY = (radius, y2) => {
68155
+ if (y2 <= 0)
68156
+ return radius;
68157
+ if (y2 >= radius)
68158
+ return 0;
68159
+ const dy = radius - y2;
68160
+ return radius - Math.sqrt(radius * radius - dy * dy);
68161
+ };
68162
+ const segments = 8;
68163
+ const arcPointsLeft = [];
68164
+ const arcPointsRight = [];
68165
+ for (let i = 0; i <= segments; i++) {
68166
+ const t = i / segments;
68167
+ const y2 = t * h2;
68168
+ const arcDistance = arcXAtY(r, y2);
68169
+ arcPointsLeft.push({
68170
+ x: Math.round(arcDistance * EMU_PER_PX3),
68171
+ y: Math.round(y2 * EMU_PER_PX3)
68172
+ });
68173
+ arcPointsRight.push({
68174
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
68175
+ y: Math.round(y2 * EMU_PER_PX3)
68176
+ });
68177
+ }
68178
+ const points = [];
68179
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
68180
+ for (let i = 1; i <= segments; i++) {
68181
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
68182
+ }
68183
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
68184
+ for (let i = segments - 1; i >= 0; i--) {
68185
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
68186
+ }
68187
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
68188
+ const borderTopShape = {
68189
+ type: "shape",
68190
+ text: "",
68191
+ textRuns: null,
68192
+ style: null,
68193
+ position: {
68194
+ x: pxToInch(rect2.left),
68195
+ y: pxToInch(rect2.top),
68196
+ w: pxToInch(rect2.width),
68197
+ h: pxToInch(borderTopW)
68198
+ },
68199
+ shape: {
68200
+ fill: rgbToHex(computed2.borderTopColor),
68201
+ gradient: null,
68202
+ transparency: extractAlpha(computed2.borderTopColor),
68203
+ line: null,
68204
+ rectRadius: 0,
68205
+ shadow: null,
68206
+ opacity: null,
68207
+ isEllipse: false,
68208
+ softEdge: null,
68209
+ rotate: null,
68210
+ cssTriangle: null,
68211
+ customGeometry: points
68212
+ }
68213
+ };
68214
+ elements.push(borderTopShape);
68215
+ } else {
68216
+ const borderTopShape = {
68217
+ type: "shape",
68218
+ text: "",
68219
+ textRuns: null,
68220
+ style: null,
68221
+ position: {
68222
+ x: pxToInch(rect2.left),
68223
+ y: pxToInch(rect2.top),
68224
+ w: pxToInch(rect2.width),
68225
+ h: pxToInch(borderTopW)
68226
+ },
68227
+ shape: {
68228
+ fill: rgbToHex(computed2.borderTopColor),
68229
+ gradient: null,
68230
+ transparency: extractAlpha(computed2.borderTopColor),
68231
+ line: null,
68232
+ rectRadius: 0,
68233
+ shadow: null,
68234
+ opacity: null,
68235
+ isEllipse: false,
68236
+ softEdge: null,
68237
+ rotate: null,
68238
+ cssTriangle: null,
68239
+ customGeometry: null
68240
+ }
68241
+ };
68242
+ elements.push(borderTopShape);
68243
+ }
68244
+ }
68245
+ const borderBottomW = borders[2];
68246
+ if (borderBottomW > 0 && !isFullyTransparent(computed2.borderBottomColor) && (borderBottomW > minLeftRightTop || minLeftRightTop === 0)) {
68247
+ if (radiusValue > 0) {
68248
+ const w2 = rect2.width;
68249
+ const h2 = borderBottomW;
68250
+ const r = radiusValue;
68251
+ const EMU_PER_PX3 = 914400 / 96;
68252
+ const arcXAtY = (radius, y2) => {
68253
+ if (y2 <= 0)
68254
+ return radius;
68255
+ if (y2 >= radius)
68256
+ return 0;
68257
+ const dy = radius - y2;
68258
+ return radius - Math.sqrt(radius * radius - dy * dy);
68259
+ };
68260
+ const segments = 8;
68261
+ const arcPointsLeft = [];
68262
+ const arcPointsRight = [];
68263
+ for (let i = 0; i <= segments; i++) {
68264
+ const t = i / segments;
68265
+ const y2 = t * h2;
68266
+ const arcDistance = arcXAtY(r, h2 - y2);
68267
+ arcPointsLeft.push({
68268
+ x: Math.round(arcDistance * EMU_PER_PX3),
68269
+ y: Math.round(y2 * EMU_PER_PX3)
68270
+ });
68271
+ arcPointsRight.push({
68272
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
68273
+ y: Math.round(y2 * EMU_PER_PX3)
68274
+ });
68275
+ }
68276
+ const points = [];
68277
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
68278
+ for (let i = 1; i <= segments; i++) {
68279
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
68280
+ }
68281
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
68282
+ for (let i = segments - 1; i >= 0; i--) {
68283
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
68284
+ }
68285
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
68286
+ const borderBottomShape = {
68287
+ type: "shape",
68288
+ text: "",
68289
+ textRuns: null,
68290
+ style: null,
68291
+ position: {
68292
+ x: pxToInch(rect2.left),
68293
+ y: pxToInch(rect2.top + rect2.height - borderBottomW),
68294
+ w: pxToInch(rect2.width),
68295
+ h: pxToInch(borderBottomW)
68296
+ },
68297
+ shape: {
68298
+ fill: rgbToHex(computed2.borderBottomColor),
68299
+ gradient: null,
68300
+ transparency: extractAlpha(computed2.borderBottomColor),
68301
+ line: null,
68302
+ rectRadius: 0,
68303
+ shadow: null,
68304
+ opacity: null,
68305
+ isEllipse: false,
68306
+ softEdge: null,
68307
+ rotate: null,
68308
+ cssTriangle: null,
68309
+ customGeometry: points
68310
+ }
68311
+ };
68312
+ elements.push(borderBottomShape);
68313
+ } else {
68314
+ const borderBottomShape = {
68315
+ type: "shape",
68316
+ text: "",
68317
+ textRuns: null,
68318
+ style: null,
68319
+ position: {
68320
+ x: pxToInch(rect2.left),
68321
+ y: pxToInch(rect2.top + rect2.height - borderBottomW),
68322
+ w: pxToInch(rect2.width),
68323
+ h: pxToInch(borderBottomW)
68324
+ },
68325
+ shape: {
68326
+ fill: rgbToHex(computed2.borderBottomColor),
68327
+ gradient: null,
68328
+ transparency: extractAlpha(computed2.borderBottomColor),
68329
+ line: null,
68330
+ rectRadius: 0,
68331
+ shadow: null,
68332
+ opacity: null,
68333
+ isEllipse: false,
68334
+ softEdge: null,
68335
+ rotate: null,
68336
+ cssTriangle: null,
68337
+ customGeometry: null
68338
+ }
68339
+ };
68340
+ elements.push(borderBottomShape);
68341
+ }
68342
+ }
68343
+ }
68344
+ processed.add(el);
68345
+ return;
68346
+ }
68347
+ const parent = el.parentElement;
68348
+ if (parent && parent.tagName === "DIV") {
68349
+ const rect2 = htmlEl.getBoundingClientRect();
68350
+ const computed22 = win.getComputedStyle(el);
68351
+ const text2 = getTransformedText(htmlEl, computed22);
68352
+ if (rect2.width > 0 && rect2.height > 0 && text2) {
68353
+ const fontSizePx2 = parseFloat(computed22.fontSize);
68354
+ const lineHeightPx2 = parseFloat(computed22.lineHeight);
68355
+ const lineHeightMultiplier2 = fontSizePx2 > 0 && !isNaN(lineHeightPx2) ? lineHeightPx2 / fontSizePx2 : 1;
68356
+ const span2BgClip = computed22.webkitBackgroundClip || computed22.backgroundClip;
68357
+ const span2TextFillColor = computed22.webkitTextFillColor;
68358
+ const span2IsGradientText = span2BgClip === "text" && (span2TextFillColor === "transparent" || span2TextFillColor === "rgba(0, 0, 0, 0)" || span2TextFillColor && span2TextFillColor.includes("rgba") && span2TextFillColor.endsWith(", 0)"));
68359
+ const span2BgImage = computed22.backgroundImage;
68360
+ const span2HasGradientBg = span2BgImage && span2BgImage !== "none" && (span2BgImage.includes("linear-gradient") || span2BgImage.includes("radial-gradient"));
68361
+ let spanFontFill = void 0;
68362
+ let spanTextColor = rgbToHex(computed22.color);
68363
+ if (span2IsGradientText && span2HasGradientBg) {
68364
+ const spanGradient = parseCssGradient(span2BgImage);
68365
+ if (spanGradient) {
68366
+ spanFontFill = { type: "gradient", gradient: spanGradient };
68367
+ spanTextColor = null;
68368
+ }
68369
+ }
68370
+ const textElement = {
68371
+ type: "p",
68372
+ text: [{ text: text2, options: spanFontFill ? { fontFill: spanFontFill } : {} }],
68373
+ position: {
68374
+ x: pxToInch(rect2.left),
68375
+ y: pxToInch(rect2.top),
68376
+ w: pxToInch(rect2.width),
68377
+ h: pxToInch(rect2.height)
68378
+ },
68379
+ style: {
68380
+ fontSize: pxToPoints(computed22.fontSize),
68381
+ fontFace: extractFontFace(computed22.fontFamily),
68382
+ color: spanTextColor,
68383
+ bold: parseInt(computed22.fontWeight) >= 600,
68384
+ italic: computed22.fontStyle === "italic",
68385
+ align: computed22.textAlign === "center" ? "center" : computed22.textAlign === "right" ? "right" : "left",
68386
+ valign: "middle",
68387
+ lineSpacing: lineHeightMultiplier2 * pxToPoints(computed22.fontSize),
68388
+ fontFill: spanFontFill,
68389
+ ...extractAlpha(computed22.color) !== null ? { transparency: extractAlpha(computed22.color) } : {}
68390
+ }
68391
+ };
68392
+ elements.push(textElement);
68393
+ processed.add(el);
68394
+ return;
68395
+ }
68396
+ }
68397
+ }
68398
+ if (el.className && typeof el.className === "string" && el.className.includes("placeholder")) {
68399
+ const rect2 = htmlEl.getBoundingClientRect();
68400
+ if (rect2.width === 0 || rect2.height === 0) {
68401
+ errors.push(`Placeholder "${el.id || "unnamed"}" has ${rect2.width === 0 ? "width: 0" : "height: 0"}. Check the layout CSS.`);
68402
+ } else {
68403
+ placeholders.push({
68404
+ id: el.id || `placeholder-${placeholders.length}`,
68405
+ x: pxToInch(rect2.left),
68406
+ y: pxToInch(rect2.top),
68407
+ w: pxToInch(rect2.width),
68408
+ h: pxToInch(rect2.height)
68409
+ });
68410
+ }
68411
+ processed.add(el);
68412
+ return;
68413
+ }
68414
+ if (el.tagName === "IMG") {
68415
+ const rect2 = htmlEl.getBoundingClientRect();
68416
+ if (rect2.width > 0 && rect2.height > 0) {
68417
+ const imgComputed = win.getComputedStyle(el);
68418
+ const bodyRect = doc.body.getBoundingClientRect();
68419
+ const coversWidth = rect2.width >= bodyRect.width * 0.95;
68420
+ const coversHeight = rect2.height >= bodyRect.height * 0.95;
68421
+ const nearOrigin = rect2.left <= 10 && rect2.top <= 10;
68422
+ const isFullSlideImage = coversWidth && coversHeight && nearOrigin;
68423
+ const objectFit = imgComputed.objectFit;
68424
+ let imgRectRadius = null;
68425
+ let clipLeft = rect2.left;
68426
+ let clipTop = rect2.top;
68427
+ let clipRight = rect2.right;
68428
+ let clipBottom = rect2.bottom;
68429
+ let ancestor = el.parentElement;
68430
+ while (ancestor && ancestor !== doc.body) {
68431
+ const ancestorComputed = win.getComputedStyle(ancestor);
68432
+ const ancestorOverflow = ancestorComputed.overflow;
68433
+ if (ancestorOverflow === "hidden" || ancestorOverflow === "clip") {
68434
+ const ancestorRect = ancestor.getBoundingClientRect();
68435
+ clipLeft = Math.max(clipLeft, ancestorRect.left);
68436
+ clipTop = Math.max(clipTop, ancestorRect.top);
68437
+ clipRight = Math.min(clipRight, ancestorRect.right);
68438
+ clipBottom = Math.min(clipBottom, ancestorRect.bottom);
68439
+ const ancestorBorderRadius = ancestorComputed.borderRadius;
68440
+ if (ancestorBorderRadius && imgRectRadius === null) {
68441
+ const radiusValue = parseFloat(ancestorBorderRadius);
68442
+ if (radiusValue > 0) {
68443
+ if (ancestorBorderRadius.includes("%")) {
68444
+ const minDim = Math.min(ancestorRect.width, ancestorRect.height);
68445
+ imgRectRadius = radiusValue / 100 * pxToInch(minDim);
68446
+ } else if (ancestorBorderRadius.includes("pt")) {
68447
+ imgRectRadius = radiusValue / 72;
68448
+ } else {
68449
+ imgRectRadius = pxToInch(radiusValue);
68450
+ }
68451
+ }
68452
+ }
68453
+ }
68454
+ ancestor = ancestor.parentElement;
68455
+ }
68456
+ const clippedW = Math.max(0, clipRight - clipLeft);
68457
+ const clippedH = Math.max(0, clipBottom - clipTop);
68458
+ const wasClipped = clippedW < rect2.width - 1 || clippedH < rect2.height - 1;
68459
+ const cssFilter = imgComputed.filter;
68460
+ let imgSrc = el.src;
68461
+ let filterPreBaked = false;
68462
+ if (cssFilter && cssFilter !== "none") {
68463
+ const bakedSrc = applyImageFilter(el, cssFilter);
68464
+ if (bakedSrc !== imgSrc) {
68465
+ imgSrc = bakedSrc;
68466
+ filterPreBaked = true;
68467
+ }
68468
+ }
68469
+ const maskImageProp = imgComputed.maskImage || imgComputed.webkitMaskImage || imgComputed.getPropertyValue("mask-image") || imgComputed.getPropertyValue("-webkit-mask-image");
68470
+ const imgOpacity = getEffectiveOpacity(el, win);
68471
+ const hasOpacity = imgOpacity < 1 && imgOpacity >= 0;
68472
+ let maskApplied = false;
68473
+ if (maskImageProp && maskImageProp !== "none" && (maskImageProp.includes("linear-gradient") || maskImageProp.includes("radial-gradient"))) {
68474
+ const maskGradient = parseCssGradient(maskImageProp);
68475
+ if (maskGradient) {
68476
+ const displayW = wasClipped ? clippedW : rect2.width;
68477
+ const displayH = wasClipped ? clippedH : rect2.height;
68478
+ const maskedSrc = applyImageMask(el, maskGradient, displayW, displayH, hasOpacity ? imgOpacity : void 0);
68479
+ if (maskedSrc) {
68480
+ imgSrc = maskedSrc;
67170
68481
  maskApplied = true;
67171
68482
  }
67172
68483
  }
@@ -67270,8 +68581,11 @@ ${generateStylesCss(styleMap, themeFonts)}
67270
68581
  if (!svgClone.hasAttribute("xmlns")) {
67271
68582
  svgClone.setAttribute("xmlns", "http://www.w3.org/2000/svg");
67272
68583
  }
67273
- svgClone.setAttribute("width", String(rect2.width));
67274
- svgClone.setAttribute("height", String(rect2.height));
68584
+ const MIN_SVG_RENDER_SIZE = 128;
68585
+ const svgRenderWidth = Math.max(rect2.width, MIN_SVG_RENDER_SIZE);
68586
+ const svgRenderHeight = Math.max(rect2.height, MIN_SVG_RENDER_SIZE);
68587
+ svgClone.setAttribute("width", String(svgRenderWidth));
68588
+ svgClone.setAttribute("height", String(svgRenderHeight));
67275
68589
  const computedColor = win.getComputedStyle(htmlEl).color;
67276
68590
  const rootStyles = win.getComputedStyle(doc.documentElement);
67277
68591
  const resolveColorValue = (value) => {
@@ -67337,10 +68651,12 @@ ${generateStylesCss(styleMap, themeFonts)}
67337
68651
  const svgString = serializer.serializeToString(svgClone);
67338
68652
  const svgBase64 = btoa(unescape(encodeURIComponent(svgString)));
67339
68653
  const dataUri = `data:image/svg+xml;base64,${svgBase64}`;
68654
+ const svgX = rect2.left;
67340
68655
  let svgY = rect2.top;
67341
68656
  const computedAlign = win.getComputedStyle(htmlEl);
67342
68657
  const verticalAlign = computedAlign.verticalAlign;
67343
- if (verticalAlign === "middle" && el.parentElement) {
68658
+ const svgDisplay = computedAlign.display;
68659
+ if (verticalAlign === "middle" && svgDisplay !== "block" && el.parentElement) {
67344
68660
  const parentComputed = win.getComputedStyle(el.parentElement);
67345
68661
  const parentIsFlex = parentComputed.display === "flex" || parentComputed.display === "inline-flex";
67346
68662
  if (!parentIsFlex) {
@@ -67351,14 +68667,28 @@ ${generateStylesCss(styleMap, themeFonts)}
67351
68667
  }
67352
68668
  }
67353
68669
  const svgEffectiveOpacity = getEffectiveOpacity(el, win);
68670
+ let displayW = pxToInch(rect2.width);
68671
+ let displayH = pxToInch(rect2.height);
68672
+ let displayX = pxToInch(svgX);
68673
+ let displayY = pxToInch(svgY);
68674
+ const MIN_SVG_DISPLAY_SIZE_IN = 0.145;
68675
+ if (displayW < MIN_SVG_DISPLAY_SIZE_IN && displayH < MIN_SVG_DISPLAY_SIZE_IN) {
68676
+ const originalCenterX = displayX + displayW / 2;
68677
+ const originalCenterY = displayY + displayH / 2;
68678
+ const scaleFactor = Math.max(MIN_SVG_DISPLAY_SIZE_IN / displayW, MIN_SVG_DISPLAY_SIZE_IN / displayH);
68679
+ displayW = displayW * scaleFactor;
68680
+ displayH = displayH * scaleFactor;
68681
+ displayX = originalCenterX - displayW / 2;
68682
+ displayY = originalCenterY - displayH / 2;
68683
+ }
67354
68684
  const imageElement = {
67355
68685
  type: "image",
67356
68686
  src: dataUri,
67357
68687
  position: {
67358
- x: pxToInch(rect2.left),
67359
- y: pxToInch(svgY),
67360
- w: pxToInch(rect2.width),
67361
- h: pxToInch(rect2.height)
68688
+ x: displayX,
68689
+ y: displayY,
68690
+ w: displayW,
68691
+ h: displayH
67362
68692
  },
67363
68693
  sizing: null,
67364
68694
  transparency: svgEffectiveOpacity < 1 ? Math.round((1 - svgEffectiveOpacity) * 100) : void 0
@@ -67436,7 +68766,8 @@ ${generateStylesCss(styleMap, themeFonts)}
67436
68766
  processed.add(el);
67437
68767
  return;
67438
68768
  }
67439
- const isContainer = el.tagName === "DIV" && !textTags.includes(el.tagName);
68769
+ const containerTags = /* @__PURE__ */ new Set(["DIV", "TABLE", "TR", "TD", "TH", "TBODY", "THEAD", "TFOOT", "CENTER"]);
68770
+ const isContainer = containerTags.has(el.tagName) && !textTags.includes(el.tagName);
67440
68771
  if (isContainer) {
67441
68772
  const computed2 = win.getComputedStyle(el);
67442
68773
  const divFilterStr = computed2.filter;
@@ -67494,6 +68825,80 @@ ${generateStylesCss(styleMap, themeFonts)}
67494
68825
  }
67495
68826
  }
67496
68827
  }
68828
+ const contentWidth = htmlEl.clientWidth;
68829
+ const contentHeight = htmlEl.clientHeight;
68830
+ const borderTopW = parseFloat(computed2.borderTopWidth) || 0;
68831
+ const borderRightW = parseFloat(computed2.borderRightWidth) || 0;
68832
+ const borderBottomW = parseFloat(computed2.borderBottomWidth) || 0;
68833
+ const borderLeftW = parseFloat(computed2.borderLeftWidth) || 0;
68834
+ if (contentWidth === 0 && contentHeight === 0 && (borderTopW > 0 || borderBottomW > 0 || borderLeftW > 0 || borderRightW > 0)) {
68835
+ const isTopEffectivelyTransparent = borderTopW === 0 || isFullyTransparent(computed2.borderTopColor);
68836
+ const isBottomEffectivelyTransparent = borderBottomW === 0 || isFullyTransparent(computed2.borderBottomColor);
68837
+ const isLeftEffectivelyTransparent = borderLeftW === 0 || isFullyTransparent(computed2.borderLeftColor);
68838
+ const isRightEffectivelyTransparent = borderRightW === 0 || isFullyTransparent(computed2.borderRightColor);
68839
+ let triangleDirection = null;
68840
+ let triangleColor = "";
68841
+ let triangleTransparency = 0;
68842
+ let triangleWidth = 0;
68843
+ let triangleHeight = 0;
68844
+ if (!isBottomEffectivelyTransparent && isLeftEffectivelyTransparent && isRightEffectivelyTransparent && isTopEffectivelyTransparent) {
68845
+ triangleDirection = "up";
68846
+ triangleColor = rgbToHex(computed2.borderBottomColor);
68847
+ triangleTransparency = extractAlpha(computed2.borderBottomColor) ?? 0;
68848
+ triangleWidth = borderLeftW + borderRightW;
68849
+ triangleHeight = borderBottomW;
68850
+ } else if (!isTopEffectivelyTransparent && isLeftEffectivelyTransparent && isRightEffectivelyTransparent && isBottomEffectivelyTransparent) {
68851
+ triangleDirection = "down";
68852
+ triangleColor = rgbToHex(computed2.borderTopColor);
68853
+ triangleTransparency = extractAlpha(computed2.borderTopColor) ?? 0;
68854
+ triangleWidth = borderLeftW + borderRightW;
68855
+ triangleHeight = borderTopW;
68856
+ } else if (!isRightEffectivelyTransparent && isTopEffectivelyTransparent && isBottomEffectivelyTransparent && isLeftEffectivelyTransparent) {
68857
+ triangleDirection = "left";
68858
+ triangleColor = rgbToHex(computed2.borderRightColor);
68859
+ triangleTransparency = extractAlpha(computed2.borderRightColor) ?? 0;
68860
+ triangleWidth = borderRightW;
68861
+ triangleHeight = borderTopW + borderBottomW;
68862
+ } else if (!isLeftEffectivelyTransparent && isTopEffectivelyTransparent && isBottomEffectivelyTransparent && isRightEffectivelyTransparent) {
68863
+ triangleDirection = "right";
68864
+ triangleColor = rgbToHex(computed2.borderLeftColor);
68865
+ triangleTransparency = extractAlpha(computed2.borderLeftColor) ?? 0;
68866
+ triangleWidth = borderLeftW;
68867
+ triangleHeight = borderTopW + borderBottomW;
68868
+ }
68869
+ if (triangleDirection && triangleWidth > 0 && triangleHeight > 0) {
68870
+ const triRect = htmlEl.getBoundingClientRect();
68871
+ const triX = pxToInch(triRect.left);
68872
+ const triY = pxToInch(triRect.top);
68873
+ const triW = pxToInch(triangleWidth);
68874
+ const triH = pxToInch(triangleHeight);
68875
+ const triRotation = extractRotationAngle(computed2);
68876
+ const triangleShape = {
68877
+ type: "shape",
68878
+ text: "",
68879
+ textRuns: null,
68880
+ style: null,
68881
+ position: { x: triX, y: triY, w: triW, h: triH },
68882
+ shape: {
68883
+ fill: triangleColor,
68884
+ gradient: null,
68885
+ transparency: triangleTransparency > 0 ? triangleTransparency : null,
68886
+ line: null,
68887
+ rectRadius: 0,
68888
+ shadow: null,
68889
+ opacity: null,
68890
+ isEllipse: false,
68891
+ softEdge: null,
68892
+ rotate: triRotation,
68893
+ cssTriangle: { direction: triangleDirection },
68894
+ customGeometry: null
68895
+ }
68896
+ };
68897
+ elements.push(triangleShape);
68898
+ processed.add(el);
68899
+ return;
68900
+ }
68901
+ }
67497
68902
  const hasBg = computed2.backgroundColor && computed2.backgroundColor !== "rgba(0, 0, 0, 0)";
67498
68903
  const clipPathValue = computed2.clipPath || computed2.webkitClipPath || "";
67499
68904
  const clipPathPolygon = parseClipPathPolygon(clipPathValue);
@@ -67528,93 +68933,438 @@ ${generateStylesCss(styleMap, themeFonts)}
67528
68933
  };
67529
68934
  elements.push(imgElement);
67530
68935
  }
67531
- bgGradient = null;
67532
- } else if (gradParts.length > 0) {
67533
- bgGradient = parseCssGradient(gradParts[0]);
67534
- for (let gi = 1; gi < Math.min(gradParts.length, 4); gi++) {
67535
- const g = parseCssGradient(gradParts[gi]);
67536
- if (g)
67537
- extraDivGradients.push(g);
68936
+ bgGradient = null;
68937
+ } else if (gradParts.length > 0) {
68938
+ bgGradient = parseCssGradient(gradParts[0]);
68939
+ for (let gi = 1; gi < Math.min(gradParts.length, 4); gi++) {
68940
+ const g = parseCssGradient(gradParts[gi]);
68941
+ if (g)
68942
+ extraDivGradients.push(g);
68943
+ }
68944
+ }
68945
+ } else {
68946
+ const urlMatch = elBgImage.match(/url\(["']?([^"')]+)["']?\)/);
68947
+ if (urlMatch) {
68948
+ bgImageUrl = urlMatch[1];
68949
+ bgImageSize = computed2.backgroundSize || "auto";
68950
+ bgImagePosition = computed2.backgroundPosition || "0% 0%";
68951
+ }
68952
+ }
68953
+ }
68954
+ const borderTop = computed2.borderTopWidth;
68955
+ const borderRight = computed2.borderRightWidth;
68956
+ const borderBottom = computed2.borderBottomWidth;
68957
+ const borderLeft = computed2.borderLeftWidth;
68958
+ const borders = [borderTop, borderRight, borderBottom, borderLeft].map((b) => parseFloat(b) || 0);
68959
+ const hasBorder = borders.some((b) => b > 0);
68960
+ const hasUniformBorder = hasBorder && borders.every((b) => b === borders[0]);
68961
+ const borderShapes = [];
68962
+ const divBorderRadius = parseFloat(computed2.borderRadius) || 0;
68963
+ if (hasBorder && !hasUniformBorder) {
68964
+ const rect2 = htmlEl.getBoundingClientRect();
68965
+ const topRightBottomBorders = [borders[0], borders[1], borders[2]].filter((b) => b > 0);
68966
+ const minTopRightBottom = topRightBottomBorders.length > 0 ? Math.min(...topRightBottomBorders) : 0;
68967
+ const topLeftBottomBorders = [borders[0], borders[3], borders[2]].filter((b) => b > 0);
68968
+ const minTopLeftBottom = topLeftBottomBorders.length > 0 ? Math.min(...topLeftBottomBorders) : 0;
68969
+ const borderLeftHex = rgbToHex(computed2.borderLeftColor);
68970
+ const borderRightHex = rgbToHex(computed2.borderRightColor);
68971
+ const borderTopHex = rgbToHex(computed2.borderTopColor);
68972
+ const borderLeftAlpha = extractAlpha(computed2.borderLeftColor);
68973
+ const borderTopAlpha = extractAlpha(computed2.borderTopColor);
68974
+ const borderRightAlpha = extractAlpha(computed2.borderRightColor);
68975
+ const borderLeftW2 = borders[3];
68976
+ const borderLeftHasDifferentColor = borderTopHex !== borderLeftHex;
68977
+ const borderLeftIsMoreOpaque = (borderLeftAlpha ?? 0) < (borderTopAlpha ?? 0);
68978
+ if (borderLeftW2 > 0 && !isFullyTransparent(computed2.borderLeftColor) && (borderLeftW2 > minTopRightBottom || minTopRightBottom === 0 || borderLeftHasDifferentColor || borderLeftIsMoreOpaque)) {
68979
+ if (divBorderRadius > 0) {
68980
+ const w2 = borderLeftW2;
68981
+ const h2 = rect2.height;
68982
+ const r = divBorderRadius;
68983
+ const EMU_PER_PX3 = 914400 / 96;
68984
+ const arcYAtX = (radius, x2) => {
68985
+ if (x2 <= 0)
68986
+ return radius;
68987
+ if (x2 >= radius)
68988
+ return 0;
68989
+ const dx = radius - x2;
68990
+ return radius - Math.sqrt(radius * radius - dx * dx);
68991
+ };
68992
+ const segments = 8;
68993
+ const arcPointsTop = [];
68994
+ const arcPointsBottom = [];
68995
+ for (let i = 0; i <= segments; i++) {
68996
+ const t = i / segments;
68997
+ const x2 = t * w2;
68998
+ const arcDistance = arcYAtX(r, x2);
68999
+ arcPointsTop.push({
69000
+ x: Math.round(x2 * EMU_PER_PX3),
69001
+ y: Math.round(arcDistance * EMU_PER_PX3)
69002
+ });
69003
+ arcPointsBottom.push({
69004
+ x: Math.round(x2 * EMU_PER_PX3),
69005
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
69006
+ });
69007
+ }
69008
+ const points = [];
69009
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
69010
+ for (let i = 1; i <= segments; i++) {
69011
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
69012
+ }
69013
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
69014
+ for (let i = segments - 1; i >= 0; i--) {
69015
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
69016
+ }
69017
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
69018
+ borderShapes.push({
69019
+ type: "shape",
69020
+ text: "",
69021
+ textRuns: null,
69022
+ style: null,
69023
+ position: {
69024
+ x: pxToInch(rect2.left),
69025
+ y: pxToInch(rect2.top),
69026
+ w: pxToInch(borderLeftW2),
69027
+ h: pxToInch(rect2.height)
69028
+ },
69029
+ shape: {
69030
+ fill: rgbToHex(computed2.borderLeftColor),
69031
+ gradient: null,
69032
+ transparency: extractAlpha(computed2.borderLeftColor),
69033
+ line: null,
69034
+ rectRadius: 0,
69035
+ // Using custom geometry instead
69036
+ shadow: null,
69037
+ opacity: null,
69038
+ isEllipse: false,
69039
+ softEdge: null,
69040
+ rotate: null,
69041
+ cssTriangle: null,
69042
+ customGeometry: points
69043
+ }
69044
+ });
69045
+ } else {
69046
+ borderShapes.push({
69047
+ type: "shape",
69048
+ text: "",
69049
+ textRuns: null,
69050
+ style: null,
69051
+ position: {
69052
+ x: pxToInch(rect2.left),
69053
+ y: pxToInch(rect2.top),
69054
+ w: pxToInch(borderLeftW2),
69055
+ h: pxToInch(rect2.height)
69056
+ },
69057
+ shape: {
69058
+ fill: rgbToHex(computed2.borderLeftColor),
69059
+ gradient: null,
69060
+ transparency: extractAlpha(computed2.borderLeftColor),
69061
+ line: null,
69062
+ rectRadius: 0,
69063
+ shadow: null,
69064
+ opacity: null,
69065
+ isEllipse: false,
69066
+ softEdge: null,
69067
+ rotate: null,
69068
+ cssTriangle: null,
69069
+ customGeometry: null
69070
+ }
69071
+ });
69072
+ }
69073
+ }
69074
+ const borderRightW2 = borders[1];
69075
+ const borderRightHasDifferentColor = borderTopHex !== borderRightHex;
69076
+ const borderRightIsMoreOpaque = (borderRightAlpha ?? 0) < (borderTopAlpha ?? 0);
69077
+ if (borderRightW2 > 0 && !isFullyTransparent(computed2.borderRightColor) && (borderRightW2 > minTopLeftBottom || minTopLeftBottom === 0 || borderRightHasDifferentColor || borderRightIsMoreOpaque)) {
69078
+ if (divBorderRadius > 0) {
69079
+ const w2 = borderRightW2;
69080
+ const h2 = rect2.height;
69081
+ const r = divBorderRadius;
69082
+ const EMU_PER_PX3 = 914400 / 96;
69083
+ const arcYAtX = (radius, x2) => {
69084
+ if (x2 <= 0)
69085
+ return radius;
69086
+ if (x2 >= radius)
69087
+ return 0;
69088
+ const dx = radius - x2;
69089
+ return radius - Math.sqrt(radius * radius - dx * dx);
69090
+ };
69091
+ const segments = 8;
69092
+ const arcPointsTop = [];
69093
+ const arcPointsBottom = [];
69094
+ for (let i = 0; i <= segments; i++) {
69095
+ const t = i / segments;
69096
+ const x2 = t * w2;
69097
+ const arcDistance = arcYAtX(r, w2 - x2);
69098
+ arcPointsTop.push({
69099
+ x: Math.round(x2 * EMU_PER_PX3),
69100
+ y: Math.round(arcDistance * EMU_PER_PX3)
69101
+ });
69102
+ arcPointsBottom.push({
69103
+ x: Math.round(x2 * EMU_PER_PX3),
69104
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
69105
+ });
69106
+ }
69107
+ const points = [];
69108
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
69109
+ for (let i = 1; i <= segments; i++) {
69110
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
69111
+ }
69112
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
69113
+ for (let i = segments - 1; i >= 0; i--) {
69114
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
69115
+ }
69116
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
69117
+ borderShapes.push({
69118
+ type: "shape",
69119
+ text: "",
69120
+ textRuns: null,
69121
+ style: null,
69122
+ position: {
69123
+ x: pxToInch(rect2.left + rect2.width - borderRightW2),
69124
+ y: pxToInch(rect2.top),
69125
+ w: pxToInch(borderRightW2),
69126
+ h: pxToInch(rect2.height)
69127
+ },
69128
+ shape: {
69129
+ fill: rgbToHex(computed2.borderRightColor),
69130
+ gradient: null,
69131
+ transparency: extractAlpha(computed2.borderRightColor),
69132
+ line: null,
69133
+ rectRadius: 0,
69134
+ // Using custom geometry instead
69135
+ shadow: null,
69136
+ opacity: null,
69137
+ isEllipse: false,
69138
+ softEdge: null,
69139
+ rotate: null,
69140
+ cssTriangle: null,
69141
+ customGeometry: points
69142
+ }
69143
+ });
69144
+ } else {
69145
+ borderShapes.push({
69146
+ type: "shape",
69147
+ text: "",
69148
+ textRuns: null,
69149
+ style: null,
69150
+ position: {
69151
+ x: pxToInch(rect2.left + rect2.width - borderRightW2),
69152
+ y: pxToInch(rect2.top),
69153
+ w: pxToInch(borderRightW2),
69154
+ h: pxToInch(rect2.height)
69155
+ },
69156
+ shape: {
69157
+ fill: rgbToHex(computed2.borderRightColor),
69158
+ gradient: null,
69159
+ transparency: extractAlpha(computed2.borderRightColor),
69160
+ line: null,
69161
+ rectRadius: 0,
69162
+ shadow: null,
69163
+ opacity: null,
69164
+ isEllipse: false,
69165
+ softEdge: null,
69166
+ rotate: null,
69167
+ cssTriangle: null,
69168
+ customGeometry: null
69169
+ }
69170
+ });
69171
+ }
69172
+ }
69173
+ const leftRightBottomBorders = [borders[3], borders[1], borders[2]].filter((b) => b > 0);
69174
+ const minLeftRightBottom = leftRightBottomBorders.length > 0 ? Math.min(...leftRightBottomBorders) : 0;
69175
+ const leftRightTopBorders = [borders[3], borders[1], borders[0]].filter((b) => b > 0);
69176
+ const minLeftRightTop = leftRightTopBorders.length > 0 ? Math.min(...leftRightTopBorders) : 0;
69177
+ const borderTopW2 = borders[0];
69178
+ if (borderTopW2 > 0 && !isFullyTransparent(computed2.borderTopColor) && (borderTopW2 > minLeftRightBottom || minLeftRightBottom === 0)) {
69179
+ if (divBorderRadius > 0) {
69180
+ const w2 = rect2.width;
69181
+ const h2 = borderTopW2;
69182
+ const r = divBorderRadius;
69183
+ const EMU_PER_PX3 = 914400 / 96;
69184
+ const arcXAtY = (radius, y2) => {
69185
+ if (y2 <= 0)
69186
+ return radius;
69187
+ if (y2 >= radius)
69188
+ return 0;
69189
+ const dy = radius - y2;
69190
+ return radius - Math.sqrt(radius * radius - dy * dy);
69191
+ };
69192
+ const segments = 8;
69193
+ const arcPointsLeft = [];
69194
+ const arcPointsRight = [];
69195
+ for (let i = 0; i <= segments; i++) {
69196
+ const t = i / segments;
69197
+ const y2 = t * h2;
69198
+ const arcDistance = arcXAtY(r, y2);
69199
+ arcPointsLeft.push({
69200
+ x: Math.round(arcDistance * EMU_PER_PX3),
69201
+ y: Math.round(y2 * EMU_PER_PX3)
69202
+ });
69203
+ arcPointsRight.push({
69204
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
69205
+ y: Math.round(y2 * EMU_PER_PX3)
69206
+ });
69207
+ }
69208
+ const points = [];
69209
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
69210
+ for (let i = 1; i <= segments; i++) {
69211
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
69212
+ }
69213
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
69214
+ for (let i = segments - 1; i >= 0; i--) {
69215
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
69216
+ }
69217
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
69218
+ borderShapes.push({
69219
+ type: "shape",
69220
+ text: "",
69221
+ textRuns: null,
69222
+ style: null,
69223
+ position: {
69224
+ x: pxToInch(rect2.left),
69225
+ y: pxToInch(rect2.top),
69226
+ w: pxToInch(rect2.width),
69227
+ h: pxToInch(borderTopW2)
69228
+ },
69229
+ shape: {
69230
+ fill: rgbToHex(computed2.borderTopColor),
69231
+ gradient: null,
69232
+ transparency: extractAlpha(computed2.borderTopColor),
69233
+ line: null,
69234
+ rectRadius: 0,
69235
+ shadow: null,
69236
+ opacity: null,
69237
+ isEllipse: false,
69238
+ softEdge: null,
69239
+ rotate: null,
69240
+ cssTriangle: null,
69241
+ customGeometry: points
69242
+ }
69243
+ });
69244
+ } else {
69245
+ borderShapes.push({
69246
+ type: "shape",
69247
+ text: "",
69248
+ textRuns: null,
69249
+ style: null,
69250
+ position: {
69251
+ x: pxToInch(rect2.left),
69252
+ y: pxToInch(rect2.top),
69253
+ w: pxToInch(rect2.width),
69254
+ h: pxToInch(borderTopW2)
69255
+ },
69256
+ shape: {
69257
+ fill: rgbToHex(computed2.borderTopColor),
69258
+ gradient: null,
69259
+ transparency: extractAlpha(computed2.borderTopColor),
69260
+ line: null,
69261
+ rectRadius: 0,
69262
+ shadow: null,
69263
+ opacity: null,
69264
+ isEllipse: false,
69265
+ softEdge: null,
69266
+ rotate: null,
69267
+ cssTriangle: null,
69268
+ customGeometry: null
69269
+ }
69270
+ });
69271
+ }
69272
+ }
69273
+ const borderBottomW2 = borders[2];
69274
+ if (borderBottomW2 > 0 && !isFullyTransparent(computed2.borderBottomColor) && (borderBottomW2 > minLeftRightTop || minLeftRightTop === 0)) {
69275
+ if (divBorderRadius > 0) {
69276
+ const w2 = rect2.width;
69277
+ const h2 = borderBottomW2;
69278
+ const r = divBorderRadius;
69279
+ const EMU_PER_PX3 = 914400 / 96;
69280
+ const arcXAtY = (radius, y2) => {
69281
+ if (y2 <= 0)
69282
+ return radius;
69283
+ if (y2 >= radius)
69284
+ return 0;
69285
+ const dy = radius - y2;
69286
+ return radius - Math.sqrt(radius * radius - dy * dy);
69287
+ };
69288
+ const segments = 8;
69289
+ const arcPointsLeft = [];
69290
+ const arcPointsRight = [];
69291
+ for (let i = 0; i <= segments; i++) {
69292
+ const t = i / segments;
69293
+ const y2 = t * h2;
69294
+ const arcDistance = arcXAtY(r, h2 - y2);
69295
+ arcPointsLeft.push({
69296
+ x: Math.round(arcDistance * EMU_PER_PX3),
69297
+ y: Math.round(y2 * EMU_PER_PX3)
69298
+ });
69299
+ arcPointsRight.push({
69300
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
69301
+ y: Math.round(y2 * EMU_PER_PX3)
69302
+ });
69303
+ }
69304
+ const points = [];
69305
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
69306
+ for (let i = 1; i <= segments; i++) {
69307
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
67538
69308
  }
69309
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
69310
+ for (let i = segments - 1; i >= 0; i--) {
69311
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
69312
+ }
69313
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
69314
+ borderShapes.push({
69315
+ type: "shape",
69316
+ text: "",
69317
+ textRuns: null,
69318
+ style: null,
69319
+ position: {
69320
+ x: pxToInch(rect2.left),
69321
+ y: pxToInch(rect2.top + rect2.height - borderBottomW2),
69322
+ w: pxToInch(rect2.width),
69323
+ h: pxToInch(borderBottomW2)
69324
+ },
69325
+ shape: {
69326
+ fill: rgbToHex(computed2.borderBottomColor),
69327
+ gradient: null,
69328
+ transparency: extractAlpha(computed2.borderBottomColor),
69329
+ line: null,
69330
+ rectRadius: 0,
69331
+ shadow: null,
69332
+ opacity: null,
69333
+ isEllipse: false,
69334
+ softEdge: null,
69335
+ rotate: null,
69336
+ cssTriangle: null,
69337
+ customGeometry: points
69338
+ }
69339
+ });
69340
+ } else {
69341
+ borderShapes.push({
69342
+ type: "shape",
69343
+ text: "",
69344
+ textRuns: null,
69345
+ style: null,
69346
+ position: {
69347
+ x: pxToInch(rect2.left),
69348
+ y: pxToInch(rect2.top + rect2.height - borderBottomW2),
69349
+ w: pxToInch(rect2.width),
69350
+ h: pxToInch(borderBottomW2)
69351
+ },
69352
+ shape: {
69353
+ fill: rgbToHex(computed2.borderBottomColor),
69354
+ gradient: null,
69355
+ transparency: extractAlpha(computed2.borderBottomColor),
69356
+ line: null,
69357
+ rectRadius: 0,
69358
+ shadow: null,
69359
+ opacity: null,
69360
+ isEllipse: false,
69361
+ softEdge: null,
69362
+ rotate: null,
69363
+ cssTriangle: null,
69364
+ customGeometry: null
69365
+ }
69366
+ });
67539
69367
  }
67540
- } else {
67541
- const urlMatch = elBgImage.match(/url\(["']?([^"')]+)["']?\)/);
67542
- if (urlMatch) {
67543
- bgImageUrl = urlMatch[1];
67544
- bgImageSize = computed2.backgroundSize || "auto";
67545
- bgImagePosition = computed2.backgroundPosition || "0% 0%";
67546
- }
67547
- }
67548
- }
67549
- const borderTop = computed2.borderTopWidth;
67550
- const borderRight = computed2.borderRightWidth;
67551
- const borderBottom = computed2.borderBottomWidth;
67552
- const borderLeft = computed2.borderLeftWidth;
67553
- const borders = [borderTop, borderRight, borderBottom, borderLeft].map((b) => parseFloat(b) || 0);
67554
- const hasBorder = borders.some((b) => b > 0);
67555
- const hasUniformBorder = hasBorder && borders.every((b) => b === borders[0]);
67556
- const borderLines = [];
67557
- if (hasBorder && !hasUniformBorder) {
67558
- const rect2 = htmlEl.getBoundingClientRect();
67559
- const x2 = pxToInch(rect2.left);
67560
- const y2 = pxToInch(rect2.top);
67561
- const w2 = pxToInch(rect2.width);
67562
- const h2 = pxToInch(rect2.height);
67563
- if (parseFloat(borderTop) > 0 && !isFullyTransparent(computed2.borderTopColor)) {
67564
- const widthPt = pxToPoints(borderTop);
67565
- const inset = widthPt / 72 / 2;
67566
- borderLines.push({
67567
- type: "line",
67568
- x1: x2,
67569
- y1: y2 + inset,
67570
- x2: x2 + w2,
67571
- y2: y2 + inset,
67572
- width: widthPt,
67573
- color: rgbToHex(computed2.borderTopColor),
67574
- transparency: extractAlpha(computed2.borderTopColor)
67575
- });
67576
- }
67577
- if (parseFloat(borderRight) > 0 && !isFullyTransparent(computed2.borderRightColor)) {
67578
- const widthPt = pxToPoints(borderRight);
67579
- const inset = widthPt / 72 / 2;
67580
- borderLines.push({
67581
- type: "line",
67582
- x1: x2 + w2 - inset,
67583
- y1: y2,
67584
- x2: x2 + w2 - inset,
67585
- y2: y2 + h2,
67586
- width: widthPt,
67587
- color: rgbToHex(computed2.borderRightColor),
67588
- transparency: extractAlpha(computed2.borderRightColor)
67589
- });
67590
- }
67591
- if (parseFloat(borderBottom) > 0 && !isFullyTransparent(computed2.borderBottomColor)) {
67592
- const widthPt = pxToPoints(borderBottom);
67593
- const inset = widthPt / 72 / 2;
67594
- borderLines.push({
67595
- type: "line",
67596
- x1: x2,
67597
- y1: y2 + h2 - inset,
67598
- x2: x2 + w2,
67599
- y2: y2 + h2 - inset,
67600
- width: widthPt,
67601
- color: rgbToHex(computed2.borderBottomColor),
67602
- transparency: extractAlpha(computed2.borderBottomColor)
67603
- });
67604
- }
67605
- if (parseFloat(borderLeft) > 0 && !isFullyTransparent(computed2.borderLeftColor)) {
67606
- const widthPt = pxToPoints(borderLeft);
67607
- const inset = widthPt / 72 / 2;
67608
- borderLines.push({
67609
- type: "line",
67610
- x1: x2 + inset,
67611
- y1: y2,
67612
- x2: x2 + inset,
67613
- y2: y2 + h2,
67614
- width: widthPt,
67615
- color: rgbToHex(computed2.borderLeftColor),
67616
- transparency: extractAlpha(computed2.borderLeftColor)
67617
- });
67618
69368
  }
67619
69369
  }
67620
69370
  if (hasBg || hasBorder || bgImageUrl || bgGradient || hasConicGradientImage) {
@@ -67638,7 +69388,7 @@ ${generateStylesCss(styleMap, themeFonts)}
67638
69388
  };
67639
69389
  elements.push(bgImgElement);
67640
69390
  }
67641
- const textTagSet = /* @__PURE__ */ new Set(["P", "H1", "H2", "H3", "H4", "H5", "H6", "SPAN"]);
69391
+ const textTagSet = /* @__PURE__ */ new Set(["P", "H1", "H2", "H3", "H4", "H5", "H6", "SPAN", "PRE"]);
67642
69392
  const allChildren = Array.from(el.children);
67643
69393
  const textChildren = allChildren.filter((child) => {
67644
69394
  if (textTagSet.has(child.tagName)) {
@@ -67654,6 +69404,15 @@ ${generateStylesCss(styleMap, themeFonts)}
67654
69404
  return false;
67655
69405
  }
67656
69406
  }
69407
+ if (["H1", "H2", "H3", "H4", "H5", "H6", "P"].includes(child.tagName)) {
69408
+ const textTagComputed = win.getComputedStyle(child);
69409
+ const textTagHasBg = textTagComputed.backgroundColor && textTagComputed.backgroundColor !== "rgba(0, 0, 0, 0)";
69410
+ const textTagHasBorder = (parseFloat(textTagComputed.borderTopWidth) || 0) > 0 || (parseFloat(textTagComputed.borderRightWidth) || 0) > 0 || (parseFloat(textTagComputed.borderBottomWidth) || 0) > 0 || (parseFloat(textTagComputed.borderLeftWidth) || 0) > 0;
69411
+ const textTagHasShadow = textTagComputed.boxShadow && textTagComputed.boxShadow !== "none";
69412
+ if (textTagHasBg || textTagHasBorder || textTagHasShadow) {
69413
+ return false;
69414
+ }
69415
+ }
67657
69416
  return true;
67658
69417
  }
67659
69418
  if (child.tagName === "DIV") {
@@ -67686,8 +69445,36 @@ ${generateStylesCss(styleMap, themeFonts)}
67686
69445
  }
67687
69446
  return false;
67688
69447
  });
67689
- const decorativeTags = /* @__PURE__ */ new Set(["I", "SVG", "CANVAS", "VIDEO", "AUDIO", "IFRAME"]);
67690
- const nonTextChildren = allChildren.filter((child) => !textTagSet.has(child.tagName) && !decorativeTags.has(child.tagName) && !(child.tagName === "DIV" && textChildren.includes(child)));
69448
+ const decorativeTags = /* @__PURE__ */ new Set(["I", "CANVAS", "VIDEO", "AUDIO", "IFRAME"]);
69449
+ const nonTextChildren = allChildren.filter((child) => {
69450
+ const childTagUpper = child.tagName.toUpperCase();
69451
+ if (textTagSet.has(childTagUpper))
69452
+ return false;
69453
+ if (decorativeTags.has(childTagUpper))
69454
+ return false;
69455
+ if (childTagUpper === "SVG") {
69456
+ const svgComputed = win.getComputedStyle(child);
69457
+ const svgDisplay = svgComputed.display;
69458
+ if (svgDisplay === "block")
69459
+ return true;
69460
+ return false;
69461
+ }
69462
+ if (child.tagName === "DIV" && textChildren.includes(child))
69463
+ return false;
69464
+ if (child.tagName === "DIV") {
69465
+ const divText = child.textContent?.trim();
69466
+ if (!divText) {
69467
+ const childElements = Array.from(child.children);
69468
+ const hasContentChildren = childElements.some((c) => {
69469
+ const tagUpper = c.tagName.toUpperCase();
69470
+ return c.textContent?.trim() || tagUpper === "SVG" || tagUpper === "IMG" || tagUpper === "CANVAS" || tagUpper === "VIDEO" || tagUpper === "I";
69471
+ });
69472
+ if (!hasContentChildren)
69473
+ return false;
69474
+ }
69475
+ }
69476
+ return true;
69477
+ });
67691
69478
  const inlineTextTagsForSimple = /* @__PURE__ */ new Set(["STRONG", "EM", "B", "I", "A", "BR", "SPAN", "MARK", "SMALL", "SUB", "SUP", "CODE", "U", "S", "Q", "CITE", "ABBR", "TIME", "DATA"]);
67692
69479
  const isSingleTextChild = textChildren.length === 1 && (() => {
67693
69480
  const tc = textChildren[0];
@@ -67744,26 +69531,68 @@ ${generateStylesCss(styleMap, themeFonts)}
67744
69531
  let shapeStyle = null;
67745
69532
  const hasTextChildren = textChildren.length > 0;
67746
69533
  let directTextContent = "";
67747
- if (!hasTextChildren) {
67748
- for (const node of Array.from(el.childNodes)) {
67749
- if (node.nodeType === Node.TEXT_NODE) {
67750
- directTextContent += node.textContent || "";
67751
- }
67752
- }
67753
- directTextContent = directTextContent.trim();
67754
- if (directTextContent && computed2.textTransform && computed2.textTransform !== "none") {
67755
- directTextContent = applyTextTransform2(directTextContent, computed2.textTransform);
69534
+ for (const node of Array.from(el.childNodes)) {
69535
+ if (node.nodeType === Node.TEXT_NODE) {
69536
+ directTextContent += node.textContent || "";
67756
69537
  }
67757
69538
  }
69539
+ directTextContent = directTextContent.trim();
69540
+ if (directTextContent && computed2.textTransform && computed2.textTransform !== "none") {
69541
+ directTextContent = applyTextTransform2(directTextContent, computed2.textTransform);
69542
+ }
67758
69543
  const hasDirectText = directTextContent.length > 0;
69544
+ const inlineFormattingTagsForMixed = /* @__PURE__ */ new Set(["STRONG", "EM", "B", "I", "A", "SPAN", "MARK", "SMALL", "SUB", "SUP", "CODE", "U", "S", "Q", "CITE", "ABBR", "TIME", "DATA"]);
69545
+ const hasInlineFormattingChildren = allChildren.some((child) => inlineFormattingTagsForMixed.has(child.tagName));
69546
+ const hasMixedInlineContent = hasDirectText && (hasTextChildren || hasInlineFormattingChildren);
67759
69547
  const isParentFlexRow = isFlexContainer2 && (computed2.flexDirection === "row" || computed2.flexDirection === "row-reverse" || !computed2.flexDirection) && allChildren.length > 1;
69548
+ const isParentFlexColumn = isFlexContainer2 && (computed2.flexDirection === "column" || computed2.flexDirection === "column-reverse") && allChildren.length > 1;
67760
69549
  const isParentGrid = display === "grid" || display === "inline-grid";
67761
- const shouldMergeText = !isParentFlexRow && !isParentGrid && (hasTextChildren && (isSingleTextChild || nonTextChildren.length === 0) || hasDirectText);
69550
+ const shouldMergeText = !isParentFlexRow && !isParentFlexColumn && !isParentGrid && (hasTextChildren && (isSingleTextChild || nonTextChildren.length === 0) || hasDirectText || hasMixedInlineContent);
67762
69551
  if (shouldMergeText) {
67763
- if (isSingleTextChild) {
69552
+ if (hasMixedInlineContent) {
69553
+ const isBold = computed2.fontWeight === "bold" || parseInt(computed2.fontWeight) >= 600;
69554
+ const isItalic = computed2.fontStyle === "italic";
69555
+ const isUnderline = computed2.textDecoration && computed2.textDecoration.includes("underline");
69556
+ const baseRunOptions = {
69557
+ fontSize: pxToPoints(computed2.fontSize),
69558
+ fontFace: extractFontFace(computed2.fontFamily),
69559
+ color: rgbToHex(computed2.color),
69560
+ bold: isBold,
69561
+ italic: isItalic,
69562
+ underline: isUnderline || false,
69563
+ ...extractLetterSpacing(computed2) !== null ? { charSpacing: extractLetterSpacing(computed2) } : {},
69564
+ ...extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {},
69565
+ ...(() => {
69566
+ const ts = parseTextShadow(computed2.textShadow);
69567
+ return ts.glow ? { glow: ts.glow } : {};
69568
+ })()
69569
+ };
69570
+ shapeTextRuns = [];
69571
+ const textTransformFn = (s) => applyTextTransform2(s, computed2.textTransform || "none");
69572
+ parseInlineFormatting(el, baseRunOptions, shapeTextRuns, textTransformFn, win, false);
69573
+ shapeStyle = {
69574
+ fontSize: pxToPoints(computed2.fontSize),
69575
+ fontFace: extractFontFace(computed2.fontFamily),
69576
+ color: rgbToHex(computed2.color),
69577
+ bold: isBold,
69578
+ italic: isItalic,
69579
+ valign: valign2,
69580
+ align,
69581
+ lineSpacing: pxToPoints(computed2.lineHeight) || void 0,
69582
+ margin: [
69583
+ pxToPoints(computed2.paddingLeft),
69584
+ pxToPoints(computed2.paddingRight),
69585
+ pxToPoints(computed2.paddingBottom),
69586
+ pxToPoints(computed2.paddingTop)
69587
+ ],
69588
+ ...extractLetterSpacing(computed2) !== null ? { charSpacing: extractLetterSpacing(computed2) } : {},
69589
+ ...extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {}
69590
+ };
69591
+ el.querySelectorAll("*").forEach((desc) => processed.add(desc));
69592
+ } else if (isSingleTextChild) {
67764
69593
  const textEl = textChildren[0];
67765
69594
  const textComputed = win.getComputedStyle(textEl);
67766
- shapeText = getTransformedText(textEl, textComputed);
69595
+ const hasInlineFormatting2 = textEl.querySelector("b, i, u, strong, em, span, br, code, a, mark, sub, sup, small, s, del, ins, abbr, time, cite, q, dfn, kbd, samp, var");
67767
69596
  let fontFill = null;
67768
69597
  const textBgClip = textComputed.webkitBackgroundClip || textComputed.backgroundClip;
67769
69598
  const textFillColor2 = textComputed.webkitTextFillColor;
@@ -67783,7 +69612,7 @@ ${generateStylesCss(styleMap, themeFonts)}
67783
69612
  bgGradient = null;
67784
69613
  }
67785
69614
  }
67786
- const effectiveColor = textComputed.color !== "rgb(0, 0, 0)" ? textComputed.color : computed2.color;
69615
+ const effectiveColor2 = textComputed.color !== "rgb(0, 0, 0)" ? textComputed.color : computed2.color;
67787
69616
  const isBold = textComputed.fontWeight === "bold" || parseInt(textComputed.fontWeight) >= 600 || computed2.fontWeight === "bold" || parseInt(computed2.fontWeight) >= 600;
67788
69617
  let effectiveAlign = align;
67789
69618
  const childTextAlign = textComputed.textAlign;
@@ -67795,7 +69624,7 @@ ${generateStylesCss(styleMap, themeFonts)}
67795
69624
  shapeStyle = {
67796
69625
  fontSize: pxToPoints(textComputed.fontSize || computed2.fontSize),
67797
69626
  fontFace: extractFontFace(textComputed.fontFamily || computed2.fontFamily),
67798
- color: fontFill ? null : rgbToHex(effectiveColor),
69627
+ color: fontFill ? null : rgbToHex(effectiveColor2),
67799
69628
  fontFill,
67800
69629
  bold: isBold,
67801
69630
  align: effectiveAlign,
@@ -67811,14 +69640,31 @@ ${generateStylesCss(styleMap, themeFonts)}
67811
69640
  shapeStyle.glow = shapeTextShadow.glow;
67812
69641
  if (shapeTextShadow.shadow)
67813
69642
  shapeStyle.textShadow = shapeTextShadow.shadow;
69643
+ if (hasInlineFormatting2) {
69644
+ const textTransformFn = (s) => applyTextTransform2(s, textComputed.textTransform || "none");
69645
+ const baseRunOptions = {
69646
+ fontSize: shapeStyle.fontSize,
69647
+ fontFace: shapeStyle.fontFace,
69648
+ color: shapeStyle.color ?? void 0,
69649
+ bold: shapeStyle.bold
69650
+ };
69651
+ const textPreserveWs = shouldPreserveWhitespace(textComputed) || isMonospaceFont(computed2.fontFamily);
69652
+ shapeTextRuns = parseInlineFormatting(textEl, baseRunOptions, [], textTransformFn, win, textPreserveWs);
69653
+ shapeText = "";
69654
+ } else {
69655
+ const effectivePreserveWs = shouldPreserveWhitespace(textComputed) || isMonospaceFont(computed2.fontFamily);
69656
+ shapeText = getTransformedText(textEl, effectivePreserveWs ? computed2 : textComputed);
69657
+ }
67814
69658
  processed.add(textEl);
67815
69659
  textEl.querySelectorAll("*").forEach((desc) => processed.add(desc));
67816
69660
  } else if (hasTextChildren) {
67817
69661
  shapeTextRuns = [];
69662
+ const parentHasMonospace = isMonospaceFont(computed2.fontFamily);
67818
69663
  textChildren.forEach((textChild, idx) => {
67819
69664
  const textEl = textChild;
67820
69665
  const textComputed = win.getComputedStyle(textEl);
67821
- const fullText = getTransformedText(textEl, textComputed);
69666
+ const effectiveWsStyle = parentHasMonospace ? computed2 : textComputed;
69667
+ const fullText = getTransformedText(textEl, effectiveWsStyle);
67822
69668
  if (!fullText)
67823
69669
  return;
67824
69670
  const isBold = textComputed.fontWeight === "bold" || parseInt(textComputed.fontWeight) >= 600;
@@ -67837,37 +69683,48 @@ ${generateStylesCss(styleMap, themeFonts)}
67837
69683
  return ts.glow ? { glow: ts.glow } : {};
67838
69684
  })()
67839
69685
  };
67840
- const hasBrChildren = textEl.querySelector("br") !== null;
67841
- if (hasBrChildren) {
67842
- let segments = [];
67843
- let currentSegment = "";
67844
- for (const node of Array.from(textEl.childNodes)) {
67845
- if (node.tagName === "BR") {
67846
- segments.push(currentSegment.trim());
67847
- currentSegment = "";
67848
- } else {
67849
- currentSegment += node.textContent || "";
69686
+ const hasInlineFormattingInChild = textEl.querySelector("b, i, u, strong, em, span, br, code, a, mark, sub, sup, small, s, del, ins, abbr, time, cite, q, dfn, kbd, samp, var");
69687
+ if (hasInlineFormattingInChild) {
69688
+ const textTransformFn = (s) => applyTextTransform2(s, textComputed.textTransform || "none");
69689
+ if (idx > 0 && shapeTextRuns.length > 0) {
69690
+ const lastRun = shapeTextRuns[shapeTextRuns.length - 1];
69691
+ lastRun.options = { ...lastRun.options, breakLine: true };
69692
+ }
69693
+ const childPreserveWs = shouldPreserveWhitespace(textComputed) || isMonospaceFont(computed2.fontFamily);
69694
+ parseInlineFormatting(textEl, baseRunOptions, shapeTextRuns, textTransformFn, win, childPreserveWs);
69695
+ } else {
69696
+ const hasBrChildren = textEl.querySelector("br") !== null;
69697
+ if (hasBrChildren) {
69698
+ let segments = [];
69699
+ let currentSegment = "";
69700
+ for (const node of Array.from(textEl.childNodes)) {
69701
+ if (node.tagName === "BR") {
69702
+ segments.push(currentSegment.trim());
69703
+ currentSegment = "";
69704
+ } else {
69705
+ currentSegment += node.textContent || "";
69706
+ }
67850
69707
  }
67851
- }
67852
- if (currentSegment.trim())
67853
- segments.push(currentSegment.trim());
67854
- segments = segments.filter((s) => s.length > 0);
67855
- if (textComputed.textTransform && textComputed.textTransform !== "none") {
67856
- segments = segments.map((s) => applyTextTransform2(s, textComputed.textTransform));
67857
- }
67858
- segments.forEach((segment, segIdx) => {
67859
- const prefix = segIdx === 0 && idx > 0 && shapeTextRuns.length > 0 ? "\n" : "";
67860
- const runText = prefix + segment;
67861
- const options = { ...baseRunOptions };
67862
- if (segIdx > 0) {
67863
- options.softBreakBefore = true;
69708
+ if (currentSegment.trim())
69709
+ segments.push(currentSegment.trim());
69710
+ segments = segments.filter((s) => s.length > 0);
69711
+ if (textComputed.textTransform && textComputed.textTransform !== "none") {
69712
+ segments = segments.map((s) => applyTextTransform2(s, textComputed.textTransform));
67864
69713
  }
69714
+ segments.forEach((segment, segIdx) => {
69715
+ const prefix = segIdx === 0 && idx > 0 && shapeTextRuns.length > 0 ? "\n" : "";
69716
+ const runText = prefix + segment;
69717
+ const options = { ...baseRunOptions };
69718
+ if (segIdx > 0) {
69719
+ options.softBreakBefore = true;
69720
+ }
69721
+ shapeTextRuns.push({ text: runText, options });
69722
+ });
69723
+ } else {
69724
+ const runText = idx > 0 && shapeTextRuns.length > 0 ? "\n" + fullText : fullText;
69725
+ const options = idx > 0 && shapeTextRuns.length > 0 ? { ...baseRunOptions, breakLine: true } : baseRunOptions;
67865
69726
  shapeTextRuns.push({ text: runText, options });
67866
- });
67867
- } else {
67868
- const runText = idx > 0 && shapeTextRuns.length > 0 ? "\n" + fullText : fullText;
67869
- const options = idx > 0 && shapeTextRuns.length > 0 ? { ...baseRunOptions, breakLine: true } : baseRunOptions;
67870
- shapeTextRuns.push({ text: runText, options });
69727
+ }
67871
69728
  }
67872
69729
  processed.add(textEl);
67873
69730
  textEl.querySelectorAll("*").forEach((desc) => processed.add(desc));
@@ -67892,14 +69749,16 @@ ${generateStylesCss(styleMap, themeFonts)}
67892
69749
  align,
67893
69750
  valign: valign2,
67894
69751
  inset: 0,
67895
- wrap: !shouldNotWrap
69752
+ wrap: !shouldNotWrap,
69753
+ ...extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {}
67896
69754
  };
67897
69755
  const ls = extractLetterSpacing(computed2);
67898
69756
  if (ls !== null)
67899
69757
  shapeStyle.charSpacing = ls;
67900
69758
  }
67901
69759
  }
67902
- if (hasBg || hasUniformBorder || bgGradient) {
69760
+ const hasTextToRender = shapeText || shapeTextRuns && shapeTextRuns.length > 0;
69761
+ if (hasBg || hasUniformBorder || bgGradient || hasBorder && hasTextToRender) {
67903
69762
  const elementOpacity = getEffectiveOpacity(htmlEl, win);
67904
69763
  const hasOpacity = elementOpacity < 1;
67905
69764
  let softEdgePt = null;
@@ -67940,11 +69799,436 @@ ${generateStylesCss(styleMap, themeFonts)}
67940
69799
  shapeY = cy - origH / 2;
67941
69800
  }
67942
69801
  }
69802
+ let overflowClipGeometry = null;
69803
+ let clippedShapeX = shapeX;
69804
+ let clippedShapeY = shapeY;
69805
+ let clippedShapeW = shapeW;
69806
+ let clippedShapeH = shapeH;
69807
+ let wasClippedToParent = false;
69808
+ const DEBUG_OVERFLOW = false;
69809
+ if (DEBUG_OVERFLOW)
69810
+ console.log("[OverflowClip] Processing element:", { shapeX, shapeY, shapeW, shapeH, bg: computed2.backgroundColor });
69811
+ let overflowAncestor = htmlEl.parentElement;
69812
+ while (overflowAncestor && overflowAncestor !== doc.body) {
69813
+ const ancestorComputed = win.getComputedStyle(overflowAncestor);
69814
+ const ancestorOverflow = ancestorComputed.overflow;
69815
+ if (ancestorOverflow === "hidden" || ancestorOverflow === "clip") {
69816
+ const ancestorBorderRadius = parseFloat(ancestorComputed.borderRadius) || 0;
69817
+ const ancestorRect = overflowAncestor.getBoundingClientRect();
69818
+ if (DEBUG_OVERFLOW)
69819
+ console.log("[OverflowClip] Found overflow ancestor:", { overflow: ancestorOverflow, borderRadius: ancestorBorderRadius, ancestorRect: { left: ancestorRect.left, top: ancestorRect.top, width: ancestorRect.width, height: ancestorRect.height } });
69820
+ const cssWidth = parseFloat(computed2.width);
69821
+ const cssHeight = parseFloat(computed2.height);
69822
+ const cssTop = parseFloat(computed2.top);
69823
+ const cssRight = parseFloat(computed2.right);
69824
+ const cssBottom = parseFloat(computed2.bottom);
69825
+ const cssLeft = parseFloat(computed2.left);
69826
+ const origW = !isNaN(cssWidth) && cssWidth > 0 ? cssWidth : shapeW;
69827
+ const origH = !isNaN(cssHeight) && cssHeight > 0 ? cssHeight : shapeH;
69828
+ let origRelLeft;
69829
+ let origRelTop;
69830
+ const position = computed2.position;
69831
+ if (position === "absolute" || position === "fixed") {
69832
+ if (!isNaN(cssLeft)) {
69833
+ origRelLeft = cssLeft;
69834
+ } else if (!isNaN(cssRight)) {
69835
+ origRelLeft = ancestorRect.width - cssRight - origW;
69836
+ } else {
69837
+ origRelLeft = shapeX - ancestorRect.left;
69838
+ }
69839
+ if (!isNaN(cssTop)) {
69840
+ origRelTop = cssTop;
69841
+ } else if (!isNaN(cssBottom)) {
69842
+ origRelTop = ancestorRect.height - cssBottom - origH;
69843
+ } else {
69844
+ origRelTop = shapeY - ancestorRect.top;
69845
+ }
69846
+ } else {
69847
+ origRelLeft = shapeX - ancestorRect.left;
69848
+ origRelTop = shapeY - ancestorRect.top;
69849
+ }
69850
+ const origRelRight = origRelLeft + origW;
69851
+ const origRelBottom = origRelTop + origH;
69852
+ if (DEBUG_OVERFLOW) {
69853
+ console.log("[OverflowClip] Element original position:", {
69854
+ origRelLeft,
69855
+ origRelTop,
69856
+ origW,
69857
+ origH,
69858
+ cssTop,
69859
+ cssRight,
69860
+ cssBottom,
69861
+ cssLeft,
69862
+ rectW: shapeW,
69863
+ rectH: shapeH,
69864
+ bgColor: computed2.backgroundColor,
69865
+ isEllipse,
69866
+ borderRadius: borderRadiusStr
69867
+ });
69868
+ }
69869
+ const relLeft = origRelLeft;
69870
+ const relTop = origRelTop;
69871
+ const relRight = origRelRight;
69872
+ const relBottom = origRelBottom;
69873
+ const needsRectClip = relLeft < 0 || relTop < 0 || relRight > ancestorRect.width || relBottom > ancestorRect.height;
69874
+ if (needsRectClip) {
69875
+ if (DEBUG_OVERFLOW)
69876
+ console.log("[OverflowClip] Element needs rect clipping:", { relLeft, relTop, relRight, relBottom });
69877
+ const clippedRelLeft = Math.max(0, relLeft);
69878
+ const clippedRelTop = Math.max(0, relTop);
69879
+ const clippedRelRight = Math.min(ancestorRect.width, relRight);
69880
+ const clippedRelBottom = Math.min(ancestorRect.height, relBottom);
69881
+ clippedShapeX = ancestorRect.left + clippedRelLeft;
69882
+ clippedShapeY = ancestorRect.top + clippedRelTop;
69883
+ clippedShapeW = clippedRelRight - clippedRelLeft;
69884
+ clippedShapeH = clippedRelBottom - clippedRelTop;
69885
+ wasClippedToParent = true;
69886
+ }
69887
+ if (ancestorBorderRadius > 0) {
69888
+ const r = ancestorBorderRadius;
69889
+ const clippedRelLeft = clippedShapeX - ancestorRect.left;
69890
+ const clippedRelTop = clippedShapeY - ancestorRect.top;
69891
+ const clippedRelRight = clippedRelLeft + clippedShapeW;
69892
+ const clippedRelBottom = clippedRelTop + clippedShapeH;
69893
+ const overlapsTL = clippedRelLeft < r && clippedRelTop < r;
69894
+ const overlapsTR = clippedRelRight > ancestorRect.width - r && clippedRelTop < r;
69895
+ const overlapsBL = clippedRelLeft < r && clippedRelBottom > ancestorRect.height - r;
69896
+ const overlapsBR = clippedRelRight > ancestorRect.width - r && clippedRelBottom > ancestorRect.height - r;
69897
+ if ((overlapsTL || overlapsTR || overlapsBL || overlapsBR) && wasClippedToParent) {
69898
+ if (DEBUG_OVERFLOW)
69899
+ console.log("[OverflowClip] Element overlaps corners:", { overlapsTL, overlapsTR, overlapsBL, overlapsBR, clippedRelLeft, clippedRelTop, clippedRelRight, clippedRelBottom, r, isEllipse, wasClippedToParent });
69900
+ const w2 = clippedShapeW;
69901
+ const h2 = clippedShapeH;
69902
+ const EMU_PER_PX3 = 914400 / 96;
69903
+ const widthEmu = Math.round(w2 * EMU_PER_PX3);
69904
+ const heightEmu = Math.round(h2 * EMU_PER_PX3);
69905
+ const segments = 8;
69906
+ const points = [];
69907
+ const addCornerArc = (cornerRelX, cornerRelY, isRight, isBottom, goingClockwise) => {
69908
+ const arcCenterX = isRight ? cornerRelX - r : cornerRelX + r;
69909
+ const arcCenterY = isBottom ? cornerRelY - r : cornerRelY + r;
69910
+ for (let i = 0; i <= segments; i++) {
69911
+ const t = goingClockwise ? i / segments : 1 - i / segments;
69912
+ const angle = t * Math.PI / 2;
69913
+ let arcRelX, arcRelY;
69914
+ if (!isRight && !isBottom) {
69915
+ arcRelX = -r * Math.sin(angle);
69916
+ arcRelY = -r * Math.cos(angle);
69917
+ } else if (isRight && !isBottom) {
69918
+ arcRelX = r * Math.cos(angle);
69919
+ arcRelY = -r * Math.sin(angle);
69920
+ } else if (!isRight && isBottom) {
69921
+ arcRelX = -r * Math.cos(angle);
69922
+ arcRelY = r * Math.sin(angle);
69923
+ } else {
69924
+ arcRelX = r * Math.sin(angle);
69925
+ arcRelY = r * Math.cos(angle);
69926
+ }
69927
+ const x2 = arcCenterX + arcRelX - clippedRelLeft;
69928
+ const y2 = arcCenterY + arcRelY - clippedRelTop;
69929
+ if (x2 >= -0.1 && x2 <= w2 + 0.1 && y2 >= -0.1 && y2 <= h2 + 0.1) {
69930
+ points.push({
69931
+ x: Math.round(Math.max(0, Math.min(w2, x2)) * EMU_PER_PX3),
69932
+ y: Math.round(Math.max(0, Math.min(h2, y2)) * EMU_PER_PX3),
69933
+ ...points.length === 0 ? { moveTo: true } : {}
69934
+ });
69935
+ }
69936
+ }
69937
+ };
69938
+ if (isEllipse && wasClippedToParent) {
69939
+ const ellipseRx = origW / 2;
69940
+ const ellipseRy = origH / 2;
69941
+ const centerXInClipped = relLeft + ellipseRx - clippedRelLeft;
69942
+ const centerYInClipped = relTop + ellipseRy - clippedRelTop;
69943
+ if (DEBUG_OVERFLOW) {
69944
+ console.log("[OverflowClip] Ellipse clipping - origW:", origW, "origH:", origH);
69945
+ console.log("[OverflowClip] Ellipse clipping - rx:", ellipseRx, "ry:", ellipseRy);
69946
+ console.log("[OverflowClip] Ellipse clipping - relLeft:", relLeft, "relTop:", relTop);
69947
+ console.log("[OverflowClip] Ellipse clipping - clippedRelLeft:", clippedRelLeft, "clippedRelTop:", clippedRelTop);
69948
+ console.log("[OverflowClip] Ellipse clipping - centerX:", centerXInClipped, "centerY:", centerYInClipped);
69949
+ console.log("[OverflowClip] Ellipse clipping - w:", w2, "h:", h2);
69950
+ console.log("[OverflowClip] Ellipse clipping - clippedShapeW:", clippedShapeW, "clippedShapeH:", clippedShapeH);
69951
+ }
69952
+ const arcSegments = 64;
69953
+ const pathPoints = [];
69954
+ for (let i = 0; i <= arcSegments; i++) {
69955
+ const angle = i / arcSegments * 2 * Math.PI;
69956
+ const px = centerXInClipped + ellipseRx * Math.cos(angle);
69957
+ const py = centerYInClipped + ellipseRy * Math.sin(angle);
69958
+ const isInside = px >= -0.5 && px <= w2 + 0.5 && py >= -0.5 && py <= h2 + 0.5;
69959
+ if (i > 0) {
69960
+ const prevAngle = (i - 1) / arcSegments * 2 * Math.PI;
69961
+ const prevPx = centerXInClipped + ellipseRx * Math.cos(prevAngle);
69962
+ const prevPy = centerYInClipped + ellipseRy * Math.sin(prevAngle);
69963
+ const prevInside = prevPx >= -0.5 && prevPx <= w2 + 0.5 && prevPy >= -0.5 && prevPy <= h2 + 0.5;
69964
+ if (isInside !== prevInside) {
69965
+ let lowT = 0, highT = 1;
69966
+ for (let iter = 0; iter < 10; iter++) {
69967
+ const midT = (lowT + highT) / 2;
69968
+ const midAngle = prevAngle + midT * (angle - prevAngle);
69969
+ const midPx = centerXInClipped + ellipseRx * Math.cos(midAngle);
69970
+ const midPy = centerYInClipped + ellipseRy * Math.sin(midAngle);
69971
+ const midInside = midPx >= -0.5 && midPx <= w2 + 0.5 && midPy >= -0.5 && midPy <= h2 + 0.5;
69972
+ if (midInside === prevInside)
69973
+ lowT = midT;
69974
+ else
69975
+ highT = midT;
69976
+ }
69977
+ const crossT = (lowT + highT) / 2;
69978
+ const crossAngle = prevAngle + crossT * (angle - prevAngle);
69979
+ const crossPx = centerXInClipped + ellipseRx * Math.cos(crossAngle);
69980
+ const crossPy = centerYInClipped + ellipseRy * Math.sin(crossAngle);
69981
+ let edge = "";
69982
+ if (Math.abs(crossPy) < 1)
69983
+ edge = "top";
69984
+ else if (Math.abs(crossPy - h2) < 1)
69985
+ edge = "bottom";
69986
+ else if (Math.abs(crossPx) < 1)
69987
+ edge = "left";
69988
+ else if (Math.abs(crossPx - w2) < 1)
69989
+ edge = "right";
69990
+ pathPoints.push({
69991
+ x: Math.max(0, Math.min(w2, crossPx)),
69992
+ y: Math.max(0, Math.min(h2, crossPy)),
69993
+ angle: crossAngle,
69994
+ isEntry: isInside,
69995
+ isExit: !isInside,
69996
+ edge
69997
+ });
69998
+ }
69999
+ }
70000
+ if (isInside) {
70001
+ pathPoints.push({
70002
+ x: Math.max(0, Math.min(w2, px)),
70003
+ y: Math.max(0, Math.min(h2, py)),
70004
+ angle
70005
+ });
70006
+ }
70007
+ }
70008
+ if (pathPoints.length >= 3) {
70009
+ if (DEBUG_OVERFLOW) {
70010
+ console.log("[OverflowClip] pathPoints count:", pathPoints.length);
70011
+ const entryPt = pathPoints.find((p) => p.isEntry);
70012
+ const exitPt = pathPoints.find((p) => p.isExit);
70013
+ console.log("[OverflowClip] entry:", entryPt);
70014
+ console.log("[OverflowClip] exit:", exitPt);
70015
+ }
70016
+ const finalPoints = [];
70017
+ for (const p of pathPoints) {
70018
+ if (finalPoints.length > 0) {
70019
+ const last = finalPoints[finalPoints.length - 1];
70020
+ if (Math.abs(p.x - last.x) < 0.5 && Math.abs(p.y - last.y) < 0.5)
70021
+ continue;
70022
+ }
70023
+ finalPoints.push({ x: p.x, y: p.y });
70024
+ }
70025
+ if (finalPoints.length >= 2) {
70026
+ const exitEdge = pathPoints.find((p) => p.isExit)?.edge;
70027
+ const entryEdge = pathPoints.find((p) => p.isEntry)?.edge;
70028
+ if (exitEdge && entryEdge && exitEdge !== entryEdge) {
70029
+ const edgeOrder = ["top", "right", "bottom", "left"];
70030
+ const cornerHasArc = {
70031
+ "top-right": overlapsTR && r > 0,
70032
+ "right-bottom": overlapsBR && r > 0,
70033
+ "bottom-left": overlapsBL && r > 0,
70034
+ "left-top": overlapsTL && r > 0
70035
+ };
70036
+ const cornerPositions = {
70037
+ "top-right": {
70038
+ x: ancestorRect.width - clippedRelLeft,
70039
+ y: 0,
70040
+ arcCenterX: ancestorRect.width - r - clippedRelLeft,
70041
+ arcCenterY: r - clippedRelTop
70042
+ },
70043
+ "right-bottom": {
70044
+ x: ancestorRect.width - clippedRelLeft,
70045
+ y: ancestorRect.height - clippedRelTop,
70046
+ arcCenterX: ancestorRect.width - r - clippedRelLeft,
70047
+ arcCenterY: ancestorRect.height - r - clippedRelTop
70048
+ },
70049
+ "bottom-left": {
70050
+ x: 0 - clippedRelLeft,
70051
+ y: ancestorRect.height - clippedRelTop,
70052
+ arcCenterX: r - clippedRelLeft,
70053
+ arcCenterY: ancestorRect.height - r - clippedRelTop
70054
+ },
70055
+ "left-top": {
70056
+ x: 0 - clippedRelLeft,
70057
+ y: 0,
70058
+ arcCenterX: r - clippedRelLeft,
70059
+ arcCenterY: r - clippedRelTop
70060
+ }
70061
+ };
70062
+ let exitIdx = edgeOrder.indexOf(exitEdge);
70063
+ const entryIdxTarget = edgeOrder.indexOf(entryEdge);
70064
+ while (exitIdx !== entryIdxTarget) {
70065
+ const nextIdx = (exitIdx + 1) % 4;
70066
+ const cornerKey = `${edgeOrder[exitIdx]}-${edgeOrder[nextIdx]}`;
70067
+ const hasArc = cornerHasArc[cornerKey];
70068
+ const cornerPos = cornerPositions[cornerKey];
70069
+ if (hasArc && cornerPos) {
70070
+ const arcCX = cornerPos.arcCenterX;
70071
+ const arcCY = cornerPos.arcCenterY;
70072
+ const arcSegs = 8;
70073
+ let startAngle, endAngle;
70074
+ switch (cornerKey) {
70075
+ case "top-right":
70076
+ startAngle = -Math.PI / 2;
70077
+ endAngle = 0;
70078
+ break;
70079
+ case "right-bottom":
70080
+ startAngle = 0;
70081
+ endAngle = Math.PI / 2;
70082
+ break;
70083
+ case "bottom-left":
70084
+ startAngle = Math.PI / 2;
70085
+ endAngle = Math.PI;
70086
+ break;
70087
+ case "left-top":
70088
+ startAngle = Math.PI;
70089
+ endAngle = Math.PI * 1.5;
70090
+ break;
70091
+ default:
70092
+ startAngle = 0;
70093
+ endAngle = Math.PI / 2;
70094
+ }
70095
+ for (let ai = 0; ai <= arcSegs; ai++) {
70096
+ const t = ai / arcSegs;
70097
+ const angle = startAngle + t * (endAngle - startAngle);
70098
+ const arcX = arcCX + r * Math.cos(angle);
70099
+ const arcY = arcCY + r * Math.sin(angle);
70100
+ if (arcX >= -0.5 && arcX <= w2 + 0.5 && arcY >= -0.5 && arcY <= h2 + 0.5) {
70101
+ const clampedX = Math.max(0, Math.min(w2, arcX));
70102
+ const clampedY = Math.max(0, Math.min(h2, arcY));
70103
+ if (finalPoints.length > 0) {
70104
+ const last = finalPoints[finalPoints.length - 1];
70105
+ if (Math.abs(clampedX - last.x) < 0.5 && Math.abs(clampedY - last.y) < 0.5)
70106
+ continue;
70107
+ }
70108
+ finalPoints.push({ x: clampedX, y: clampedY });
70109
+ }
70110
+ }
70111
+ } else if (cornerPos) {
70112
+ const clampedX = Math.max(0, Math.min(w2, cornerPos.x));
70113
+ const clampedY = Math.max(0, Math.min(h2, cornerPos.y));
70114
+ finalPoints.push({ x: clampedX, y: clampedY });
70115
+ }
70116
+ exitIdx = nextIdx;
70117
+ }
70118
+ }
70119
+ }
70120
+ if (finalPoints.length >= 3) {
70121
+ if (DEBUG_OVERFLOW) {
70122
+ console.log("[OverflowClip] finalPoints count:", finalPoints.length);
70123
+ console.log("[OverflowClip] first 3 points:", JSON.stringify(finalPoints.slice(0, 3)));
70124
+ console.log("[OverflowClip] last 3 points:", JSON.stringify(finalPoints.slice(-3)));
70125
+ }
70126
+ for (let i = 0; i < finalPoints.length; i++) {
70127
+ points.push({
70128
+ x: Math.round(finalPoints[i].x * EMU_PER_PX3),
70129
+ y: Math.round(finalPoints[i].y * EMU_PER_PX3),
70130
+ ...i === 0 ? { moveTo: true } : {}
70131
+ });
70132
+ }
70133
+ points.push({ x: points[0].x, y: points[0].y, close: true });
70134
+ }
70135
+ }
70136
+ } else if (!isEllipse) {
70137
+ const elementBorderRadius = parseFloat(borderRadiusStr) || 0;
70138
+ const elemR = elementBorderRadius;
70139
+ const addElementCornerArc = (isRight, isBottom) => {
70140
+ if (elemR <= 0)
70141
+ return;
70142
+ for (let i = 0; i <= segments; i++) {
70143
+ const t = i / segments;
70144
+ const angle = t * Math.PI / 2;
70145
+ let arcX, arcY;
70146
+ if (!isRight && !isBottom) {
70147
+ arcX = elemR * Math.cos(angle);
70148
+ arcY = elemR * Math.sin(angle);
70149
+ } else if (!isRight && isBottom) {
70150
+ arcX = elemR - elemR * Math.cos(angle);
70151
+ arcY = h2 - elemR + elemR * Math.sin(angle);
70152
+ } else if (isRight && isBottom) {
70153
+ arcX = w2 - elemR + elemR * Math.sin(angle);
70154
+ arcY = h2 - elemR + elemR * Math.cos(angle);
70155
+ } else {
70156
+ arcX = w2 - elemR + elemR * Math.cos(angle);
70157
+ arcY = elemR - elemR * Math.sin(angle);
70158
+ }
70159
+ points.push({
70160
+ x: Math.round(arcX * EMU_PER_PX3),
70161
+ y: Math.round(arcY * EMU_PER_PX3),
70162
+ ...points.length === 0 ? { moveTo: true } : {}
70163
+ });
70164
+ }
70165
+ };
70166
+ const atLeftClipBoundary = wasClippedToParent && clippedRelLeft <= 0.1;
70167
+ const atTopClipBoundary = wasClippedToParent && clippedRelTop <= 0.1;
70168
+ const atRightClipBoundary = wasClippedToParent && clippedRelRight >= ancestorRect.width - 0.1;
70169
+ const atBottomClipBoundary = wasClippedToParent && clippedRelBottom >= ancestorRect.height - 0.1;
70170
+ if (overlapsTL) {
70171
+ addCornerArc(0, 0, false, false, true);
70172
+ } else if (elemR > 0 && !atLeftClipBoundary && !atTopClipBoundary) {
70173
+ addElementCornerArc(false, false);
70174
+ } else {
70175
+ points.push({ x: 0, y: 0, moveTo: true });
70176
+ }
70177
+ if (overlapsBL) {
70178
+ addCornerArc(0, ancestorRect.height, false, true, true);
70179
+ } else if (elemR > 0 && !atLeftClipBoundary && !atBottomClipBoundary) {
70180
+ addElementCornerArc(false, true);
70181
+ } else {
70182
+ points.push({ x: 0, y: heightEmu });
70183
+ }
70184
+ if (overlapsBR) {
70185
+ addCornerArc(ancestorRect.width, ancestorRect.height, true, true, true);
70186
+ } else if (elemR > 0 && !atRightClipBoundary && !atBottomClipBoundary) {
70187
+ addElementCornerArc(true, true);
70188
+ } else {
70189
+ points.push({ x: widthEmu, y: heightEmu });
70190
+ }
70191
+ if (overlapsTR) {
70192
+ addCornerArc(ancestorRect.width, 0, true, false, true);
70193
+ } else if (elemR > 0 && !atRightClipBoundary && !atTopClipBoundary) {
70194
+ addElementCornerArc(true, false);
70195
+ } else {
70196
+ points.push({ x: widthEmu, y: 0 });
70197
+ }
70198
+ points.push({ x: 0, y: 0, close: true });
70199
+ }
70200
+ if (points.length > 5) {
70201
+ overflowClipGeometry = points;
70202
+ if (DEBUG_OVERFLOW)
70203
+ console.log("[OverflowClip] Generated custom geometry with", points.length, "points");
70204
+ } else {
70205
+ if (DEBUG_OVERFLOW)
70206
+ console.log("[OverflowClip] Not enough points for custom geometry:", points.length);
70207
+ }
70208
+ }
70209
+ }
70210
+ break;
70211
+ }
70212
+ overflowAncestor = overflowAncestor.parentElement;
70213
+ }
70214
+ let originalShapeW = shapeW;
70215
+ let originalShapeH = shapeH;
70216
+ if (wasClippedToParent) {
70217
+ originalShapeW = shapeW;
70218
+ originalShapeH = shapeH;
70219
+ shapeX = clippedShapeX;
70220
+ shapeY = clippedShapeY;
70221
+ shapeW = clippedShapeW;
70222
+ shapeH = clippedShapeH;
70223
+ }
70224
+ const hasTextContent = shapeText || shapeTextRuns && shapeTextRuns.length > 0;
70225
+ const shouldSplitTextFromClippedShape = overflowClipGeometry && hasTextContent;
67943
70226
  const shapeElement = {
67944
70227
  type: "shape",
67945
- text: shapeText,
67946
- textRuns: shapeTextRuns,
67947
- style: shapeStyle,
70228
+ // If splitting text from clipped shape, don't include text in the main shape
70229
+ text: shouldSplitTextFromClippedShape ? "" : shapeText,
70230
+ textRuns: shouldSplitTextFromClippedShape ? null : shapeTextRuns,
70231
+ style: shouldSplitTextFromClippedShape ? null : shapeStyle,
67948
70232
  position: {
67949
70233
  x: pxToInch(shapeX),
67950
70234
  y: pxToInch(shapeY),
@@ -67983,7 +70267,8 @@ ${generateStylesCss(styleMap, themeFonts)}
67983
70267
  isEllipse,
67984
70268
  softEdge: softEdgePt,
67985
70269
  rotate: rotationAngle,
67986
- customGeometry: clipPathPolygon ? (() => {
70270
+ cssTriangle: null,
70271
+ customGeometry: overflowClipGeometry ? overflowClipGeometry : clipPathPolygon ? (() => {
67987
70272
  const EMU2 = 914400;
67988
70273
  const pathW = Math.round(shapeW / PX_PER_IN * EMU2);
67989
70274
  const pathH = Math.round(shapeH / PX_PER_IN * EMU2);
@@ -68002,7 +70287,7 @@ ${generateStylesCss(styleMap, themeFonts)}
68002
70287
  };
68003
70288
  if (hasPadding && shapeElement.style && (shapeText || shapeTextRuns && shapeTextRuns.length > 0)) {
68004
70289
  let effectiveLeftPadding = paddingLeft;
68005
- if (hasDirectText && allChildren.length > 0) {
70290
+ if (hasDirectText && allChildren.length > 0 && !hasMixedInlineContent) {
68006
70291
  for (const child of allChildren) {
68007
70292
  if (child.nodeType === Node.ELEMENT_NODE) {
68008
70293
  const childEl = child;
@@ -68029,6 +70314,76 @@ ${generateStylesCss(styleMap, themeFonts)}
68029
70314
  ];
68030
70315
  }
68031
70316
  elements.push(shapeElement);
70317
+ if (!shouldMergeText && textChildren.length > 0) {
70318
+ textChildren.forEach((tc) => {
70319
+ processed.delete(tc);
70320
+ tc.querySelectorAll("*").forEach((desc) => processed.delete(desc));
70321
+ });
70322
+ }
70323
+ if (shouldSplitTextFromClippedShape && overflowClipGeometry) {
70324
+ const originalArea = originalShapeW * originalShapeH;
70325
+ const clippedArea = clippedShapeW * clippedShapeH;
70326
+ const visiblePercent = clippedArea / originalArea * 100;
70327
+ if (DEBUG_OVERFLOW)
70328
+ console.log("[OverflowClip] Text shape visibility:", {
70329
+ originalShapeW,
70330
+ originalShapeH,
70331
+ originalArea,
70332
+ clippedShapeW,
70333
+ clippedShapeH,
70334
+ clippedArea,
70335
+ visiblePercent: visiblePercent.toFixed(1) + "%"
70336
+ });
70337
+ if (visiblePercent >= 50) {
70338
+ const clippedTextShape = {
70339
+ type: "shape",
70340
+ text: shapeText,
70341
+ textRuns: shapeTextRuns,
70342
+ style: shapeStyle,
70343
+ position: {
70344
+ // Use clipped dimensions to constrain text to visible area
70345
+ x: pxToInch(clippedShapeX),
70346
+ y: pxToInch(clippedShapeY),
70347
+ w: pxToInch(clippedShapeW),
70348
+ h: pxToInch(clippedShapeH)
70349
+ },
70350
+ shape: {
70351
+ fill: null,
70352
+ // No fill - just text
70353
+ gradient: null,
70354
+ transparency: null,
70355
+ line: null,
70356
+ rectRadius: 0,
70357
+ shadow: null,
70358
+ opacity: null,
70359
+ isEllipse: false,
70360
+ softEdge: null,
70361
+ rotate: null,
70362
+ cssTriangle: null,
70363
+ customGeometry: null
70364
+ // NO custom geometry - PPTX doesn't clip text to paths
70365
+ }
70366
+ };
70367
+ if (hasPadding && clippedTextShape.style) {
70368
+ clippedTextShape.style.margin = [
70369
+ paddingLeft * PT_PER_PX,
70370
+ // left
70371
+ paddingRight * PT_PER_PX,
70372
+ // right
70373
+ paddingBottom * PT_PER_PX,
70374
+ // bottom
70375
+ paddingTop * PT_PER_PX
70376
+ // top
70377
+ ];
70378
+ }
70379
+ elements.push(clippedTextShape);
70380
+ if (DEBUG_OVERFLOW)
70381
+ console.log("[OverflowClip] Created separate clipped text shape for:", shapeText);
70382
+ } else {
70383
+ if (DEBUG_OVERFLOW)
70384
+ console.log("[OverflowClip] Skipping text (visible area too small):", shapeText);
70385
+ }
70386
+ }
68032
70387
  if (extraDivGradients.length > 0) {
68033
70388
  for (const extraGrad of extraDivGradients) {
68034
70389
  const extraShape = {
@@ -68048,6 +70403,7 @@ ${generateStylesCss(styleMap, themeFonts)}
68048
70403
  isEllipse: false,
68049
70404
  softEdge: null,
68050
70405
  rotate: null,
70406
+ cssTriangle: null,
68051
70407
  customGeometry: null
68052
70408
  }
68053
70409
  };
@@ -68090,6 +70446,7 @@ ${generateStylesCss(styleMap, themeFonts)}
68090
70446
  isEllipse: false,
68091
70447
  softEdge: null,
68092
70448
  rotate: null,
70449
+ cssTriangle: null,
68093
70450
  customGeometry: null
68094
70451
  }
68095
70452
  };
@@ -68102,7 +70459,7 @@ ${generateStylesCss(styleMap, themeFonts)}
68102
70459
  tc.querySelectorAll("*").forEach((desc) => processed.delete(desc));
68103
70460
  });
68104
70461
  }
68105
- elements.push(...borderLines);
70462
+ elements.push(...borderShapes);
68106
70463
  processed.add(el);
68107
70464
  return;
68108
70465
  }
@@ -68200,16 +70557,29 @@ ${generateStylesCss(styleMap, themeFonts)}
68200
70557
  const textHeight = rect2.height;
68201
70558
  let textRuns;
68202
70559
  const isFlexColumn = (plainDivDisplay === "flex" || plainDivDisplay === "inline-flex") && (plainDivFlexDir === "column" || plainDivFlexDir === "column-reverse") && childElements.length > 1;
70560
+ const baseRunOptions = {
70561
+ fontSize: pxToPoints(computed22.fontSize),
70562
+ fontFace: extractFontFace(computed22.fontFamily),
70563
+ color: rgbToHex(computed22.color)
70564
+ };
70565
+ if (parseInt(computed22.fontWeight) >= 600)
70566
+ baseRunOptions.bold = true;
70567
+ if (computed22.fontStyle === "italic")
70568
+ baseRunOptions.italic = true;
70569
+ const colorAlphaTransparency2 = extractAlpha(computed22.color);
70570
+ const elementOpacityVal = getEffectiveOpacity(el, win);
70571
+ if (colorAlphaTransparency2 !== null || elementOpacityVal < 1) {
70572
+ let runTransparency = colorAlphaTransparency2 !== null ? colorAlphaTransparency2 : 0;
70573
+ if (elementOpacityVal < 1) {
70574
+ const existingOpacity = 1 - runTransparency / 100;
70575
+ const combinedOpacity = existingOpacity * elementOpacityVal;
70576
+ runTransparency = Math.round((1 - combinedOpacity) * 100);
70577
+ }
70578
+ if (runTransparency > 0) {
70579
+ baseRunOptions.transparency = runTransparency;
70580
+ }
70581
+ }
68203
70582
  if (allChildrenAreInlineText && childElements.length > 0) {
68204
- const baseRunOptions = {
68205
- fontSize: pxToPoints(computed22.fontSize),
68206
- fontFace: extractFontFace(computed22.fontFamily),
68207
- color: rgbToHex(computed22.color)
68208
- };
68209
- if (parseInt(computed22.fontWeight) >= 600)
68210
- baseRunOptions.bold = true;
68211
- if (computed22.fontStyle === "italic")
68212
- baseRunOptions.italic = true;
68213
70583
  let textTransformFn = (s) => s;
68214
70584
  if (computed22.textTransform && computed22.textTransform !== "none") {
68215
70585
  textTransformFn = (text2) => applyTextTransform2(text2, computed22.textTransform);
@@ -68233,6 +70603,12 @@ ${generateStylesCss(styleMap, themeFonts)}
68233
70603
  const childColor = rgbToHex(childComputed.color);
68234
70604
  if (childColor)
68235
70605
  childRunOptions.color = childColor;
70606
+ const childColorTransparency = extractAlpha(childComputed.color);
70607
+ if (childColorTransparency !== null) {
70608
+ childRunOptions.transparency = childColorTransparency;
70609
+ } else {
70610
+ delete childRunOptions.transparency;
70611
+ }
68236
70612
  if (parseInt(childComputed.fontWeight) >= 600) {
68237
70613
  childRunOptions.bold = true;
68238
70614
  } else if (parseInt(childComputed.fontWeight) < 600) {
@@ -68250,13 +70626,14 @@ ${generateStylesCss(styleMap, themeFonts)}
68250
70626
  textRuns.push({ text: textWithBreak, options: childRunOptions });
68251
70627
  }
68252
70628
  } else {
68253
- textRuns = parseInlineFormatting(el, baseRunOptions, [], textTransformFn, win);
70629
+ const elPreserveWs = shouldPreserveWhitespace(computed22);
70630
+ textRuns = parseInlineFormatting(el, baseRunOptions, [], textTransformFn, win, elPreserveWs);
68254
70631
  }
68255
70632
  if (textRuns.length === 0) {
68256
- textRuns = [{ text: extractedText, options: {} }];
70633
+ textRuns = [{ text: extractedText, options: baseRunOptions }];
68257
70634
  }
68258
70635
  } else {
68259
- textRuns = [{ text: extractedText, options: {} }];
70636
+ textRuns = [{ text: extractedText, options: baseRunOptions }];
68260
70637
  }
68261
70638
  const paddingTop = parseFloat(computed22.paddingTop) || 0;
68262
70639
  const paddingRight = parseFloat(computed22.paddingRight) || 0;
@@ -68284,9 +70661,8 @@ ${generateStylesCss(styleMap, themeFonts)}
68284
70661
  margin: hasPadding ? [paddingLeft * PT_PER_PX, paddingRight * PT_PER_PX, paddingBottom * PT_PER_PX, paddingTop * PT_PER_PX] : void 0
68285
70662
  }
68286
70663
  };
68287
- const textTransparency = extractAlpha(computed22.color);
68288
- if (textTransparency !== null) {
68289
- textElement.style.transparency = textTransparency;
70664
+ if (baseRunOptions.transparency !== void 0 && baseRunOptions.transparency > 0) {
70665
+ textElement.style.transparency = baseRunOptions.transparency;
68290
70666
  }
68291
70667
  const ls = extractLetterSpacing(computed22);
68292
70668
  if (ls !== null)
@@ -68337,7 +70713,8 @@ ${generateStylesCss(styleMap, themeFonts)}
68337
70713
  const liPaddingLeft = parseFloat(liComputed2.paddingLeft) || 0;
68338
70714
  const textLeft = liRect.left + liPaddingLeft;
68339
70715
  const textWidth = liRect.width - liPaddingLeft;
68340
- const runs = parseInlineFormatting(liEl, { breakLine: false }, [], (x2) => x2, win);
70716
+ const liPreserveWs = shouldPreserveWhitespace(liComputed2);
70717
+ const runs = parseInlineFormatting(liEl, { breakLine: false }, [], (x2) => x2, win, liPreserveWs);
68341
70718
  if (runs.length === 0)
68342
70719
  return;
68343
70720
  runs[0].text = runs[0].text.replace(/^[•\-*\u25AA\u25B8]\s*/, "");
@@ -68368,7 +70745,10 @@ ${generateStylesCss(styleMap, themeFonts)}
68368
70745
  }
68369
70746
  liElements.forEach((li, idx) => {
68370
70747
  const isLast = idx === liElements.length - 1;
68371
- const runs = parseInlineFormatting(li, { breakLine: false }, [], (x2) => x2, win);
70748
+ const liEl = li;
70749
+ const liItemComputed = win.getComputedStyle(liEl);
70750
+ const liItemPreserveWs = shouldPreserveWhitespace(liItemComputed);
70751
+ const runs = parseInlineFormatting(li, { breakLine: false }, [], (x2) => x2, win, liItemPreserveWs);
68372
70752
  if (runs.length > 0) {
68373
70753
  runs[0].text = runs[0].text.replace(/^[•\-*\u25AA\u25B8]\s*/, "");
68374
70754
  if (hasNativeBullets) {
@@ -68414,9 +70794,40 @@ ${generateStylesCss(styleMap, themeFonts)}
68414
70794
  return;
68415
70795
  let rect = htmlEl.getBoundingClientRect();
68416
70796
  const computed = win.getComputedStyle(el);
68417
- let text = getTransformedText(htmlEl, computed);
70797
+ let effectiveComputedForWhitespace = computed;
70798
+ const pParentEl = htmlEl.parentElement;
70799
+ if (el.tagName === "P" && pParentEl && pParentEl.tagName === "DIV") {
70800
+ const pParentChildren = Array.from(pParentEl.children);
70801
+ const nonBrChildren = pParentChildren.filter((c) => c.tagName !== "BR");
70802
+ if (nonBrChildren.length === 1 && nonBrChildren[0] === el) {
70803
+ const pParentComputed = win.getComputedStyle(pParentEl);
70804
+ if (isMonospaceFont(pParentComputed.fontFamily)) {
70805
+ effectiveComputedForWhitespace = pParentComputed;
70806
+ }
70807
+ }
70808
+ }
70809
+ let text = getTransformedText(htmlEl, effectiveComputedForWhitespace);
68418
70810
  if (rect.width === 0 || rect.height === 0 || !text)
68419
70811
  return;
70812
+ let effectiveFontSizeForOverflow = computed.fontSize;
70813
+ let effectiveLineHeightForOverflow = computed.lineHeight;
70814
+ if (el.tagName === "P" && pParentEl && pParentEl.tagName === "DIV") {
70815
+ const pParentChildren = Array.from(pParentEl.children);
70816
+ const nonBrChildren = pParentChildren.filter((c) => c.tagName !== "BR");
70817
+ if (nonBrChildren.length === 1 && nonBrChildren[0] === el) {
70818
+ const pParentComputedForOverflow = win.getComputedStyle(pParentEl);
70819
+ effectiveFontSizeForOverflow = pParentComputedForOverflow.fontSize;
70820
+ effectiveLineHeightForOverflow = pParentComputedForOverflow.lineHeight;
70821
+ }
70822
+ }
70823
+ const earlyFontSizePx = parseFloat(effectiveFontSizeForOverflow);
70824
+ const earlyLineHeightPx = parseFloat(effectiveLineHeightForOverflow);
70825
+ if (!isNaN(earlyFontSizePx) && !isNaN(earlyLineHeightPx) && earlyLineHeightPx < earlyFontSizePx) {
70826
+ const lineHeightOverflowOffsetPx = earlyFontSizePx - earlyLineHeightPx;
70827
+ const minHeightPx = earlyFontSizePx * 1.3;
70828
+ const newHeight = Math.max(rect.height, minHeightPx);
70829
+ rect = new DOMRect(rect.x, rect.y + lineHeightOverflowOffsetPx, rect.width, newHeight);
70830
+ }
68420
70831
  const isFlexContainer = computed.display === "flex" || computed.display === "inline-flex";
68421
70832
  let flexContentChild = null;
68422
70833
  if (isFlexContainer && el.children.length > 0) {
@@ -68505,13 +70916,39 @@ ${generateStylesCss(styleMap, themeFonts)}
68505
70916
  valign = "middle";
68506
70917
  }
68507
70918
  }
70919
+ if (!isNaN(earlyFontSizePx) && !isNaN(earlyLineHeightPx) && earlyLineHeightPx < earlyFontSizePx) {
70920
+ valign = "top";
70921
+ }
70922
+ let effectiveColor = computed.color;
70923
+ let effectiveFontFamily = computed.fontFamily;
70924
+ let effectiveFontSize = computed.fontSize;
70925
+ if (el.tagName === "P" && parentEl && parentEl.tagName === "DIV") {
70926
+ const parentChildren = Array.from(parentEl.children);
70927
+ const nonBrChildren = parentChildren.filter((c) => c.tagName !== "BR");
70928
+ if (nonBrChildren.length === 1 && nonBrChildren[0] === el) {
70929
+ const parentComputed = win.getComputedStyle(parentEl);
70930
+ if (parentComputed.color !== computed.color && parentComputed.color !== "rgb(0, 0, 0)") {
70931
+ effectiveColor = parentComputed.color;
70932
+ }
70933
+ if (parentComputed.fontFamily !== computed.fontFamily) {
70934
+ if (isMonospaceFont(parentComputed.fontFamily)) {
70935
+ effectiveFontFamily = parentComputed.fontFamily;
70936
+ }
70937
+ }
70938
+ if (parentComputed.fontSize !== computed.fontSize) {
70939
+ if (isMonospaceFont(parentComputed.fontFamily)) {
70940
+ effectiveFontSize = parentComputed.fontSize;
70941
+ }
70942
+ }
70943
+ }
70944
+ }
68508
70945
  const baseStyle = {
68509
- fontSize: pxToPoints(computed.fontSize),
68510
- fontFace: extractFontFace(computed.fontFamily),
68511
- color: rgbToHex(computed.color),
70946
+ fontSize: pxToPoints(effectiveFontSize),
70947
+ fontFace: extractFontFace(effectiveFontFamily),
70948
+ color: rgbToHex(effectiveColor),
68512
70949
  align: textAlign,
68513
70950
  valign,
68514
- lineSpacing: pxToPoints(computed.fontSize) * lineHeightMultiplier,
70951
+ lineSpacing: pxToPoints(effectiveFontSize) * lineHeightMultiplier,
68515
70952
  paraSpaceBefore: pxToPoints(computed.marginTop),
68516
70953
  paraSpaceAfter: pxToPoints(computed.marginBottom),
68517
70954
  margin: [
@@ -68521,9 +70958,19 @@ ${generateStylesCss(styleMap, themeFonts)}
68521
70958
  pxToPoints(computed.paddingTop)
68522
70959
  ]
68523
70960
  };
68524
- const transparency = extractAlpha(computed.color);
68525
- if (transparency !== null)
68526
- baseStyle.transparency = transparency;
70961
+ const colorAlphaTransparency = extractAlpha(effectiveColor);
70962
+ const effectiveOpacity = getEffectiveOpacity(el, win);
70963
+ if (colorAlphaTransparency !== null || effectiveOpacity < 1) {
70964
+ let finalTransparency = colorAlphaTransparency !== null ? colorAlphaTransparency : 0;
70965
+ if (effectiveOpacity < 1) {
70966
+ const existingOpacity = 1 - finalTransparency / 100;
70967
+ const combinedOpacity = existingOpacity * effectiveOpacity;
70968
+ finalTransparency = Math.round((1 - combinedOpacity) * 100);
70969
+ }
70970
+ if (finalTransparency > 0) {
70971
+ baseStyle.transparency = finalTransparency;
70972
+ }
70973
+ }
68527
70974
  const letterSpacing = extractLetterSpacing(computed);
68528
70975
  if (letterSpacing !== null)
68529
70976
  baseStyle.charSpacing = letterSpacing;
@@ -68548,10 +70995,16 @@ ${generateStylesCss(styleMap, themeFonts)}
68548
70995
  }
68549
70996
  }
68550
70997
  const formattingRoot = flexContentChild ?? el;
68551
- const hasFormatting = formattingRoot.querySelector("b, i, u, strong, em, span, br, code, a, mark, sub, sup, small, s, del, ins, abbr, time, cite, q, dfn, kbd, samp, var");
70998
+ const hasFormatting = formattingRoot.querySelector("b, i, u, strong, em, span, br, code, a, mark, sub, sup, small, s, del, ins, abbr, time, cite, q, dfn, kbd, samp, var, div, p");
68552
70999
  if (hasFormatting) {
68553
71000
  const transformStr = computed.textTransform;
68554
- const runs = parseInlineFormatting(formattingRoot, {}, [], (str) => applyTextTransform2(str, transformStr), win);
71001
+ const textPreserveWs = shouldPreserveWhitespace(effectiveComputedForWhitespace);
71002
+ const baseRunOptions = {
71003
+ fontSize: baseStyle.fontSize,
71004
+ fontFace: baseStyle.fontFace,
71005
+ color: baseStyle.color ?? void 0
71006
+ };
71007
+ const runs = parseInlineFormatting(formattingRoot, baseRunOptions, [], (str) => applyTextTransform2(str, transformStr), win, textPreserveWs);
68555
71008
  const textElement = {
68556
71009
  type: el.tagName.toLowerCase(),
68557
71010
  text: runs,
@@ -68847,7 +71300,24 @@ ${generateStylesCss(styleMap, themeFonts)}
68847
71300
  } else if (el.type === "shape") {
68848
71301
  let shapeType = pres.ShapeType.rect;
68849
71302
  let customGeometryPoints;
68850
- if (el.shape.customGeometry && el.shape.customGeometry.length > 0) {
71303
+ let triangleRotation = null;
71304
+ if (el.shape.cssTriangle) {
71305
+ shapeType = pres.ShapeType.triangle;
71306
+ switch (el.shape.cssTriangle.direction) {
71307
+ case "up":
71308
+ triangleRotation = 0;
71309
+ break;
71310
+ case "down":
71311
+ triangleRotation = 180;
71312
+ break;
71313
+ case "left":
71314
+ triangleRotation = 270;
71315
+ break;
71316
+ case "right":
71317
+ triangleRotation = 90;
71318
+ break;
71319
+ }
71320
+ } else if (el.shape.customGeometry && el.shape.customGeometry.length > 0) {
68851
71321
  shapeType = pres.ShapeType.custGeom;
68852
71322
  customGeometryPoints = el.shape.customGeometry;
68853
71323
  } else if (el.shape.isEllipse) {
@@ -68946,8 +71416,10 @@ ${generateStylesCss(styleMap, themeFonts)}
68946
71416
  shapeOptions.shadow = el.shape.shadow;
68947
71417
  if (el.shape.softEdge)
68948
71418
  shapeOptions.softEdgeRad = el.shape.softEdge;
68949
- if (el.shape.rotate)
68950
- shapeOptions.rotate = el.shape.rotate;
71419
+ const cssRotation = el.shape.rotate ?? 0;
71420
+ const totalRotation = cssRotation + (triangleRotation ?? 0);
71421
+ if (totalRotation !== 0)
71422
+ shapeOptions.rotate = totalRotation;
68951
71423
  if (el.style) {
68952
71424
  if (el.style.fontSize)
68953
71425
  shapeOptions.fontSize = el.style.fontSize;
@@ -68976,6 +71448,11 @@ ${generateStylesCss(styleMap, themeFonts)}
68976
71448
  shapeOptions.inset = el.style.inset;
68977
71449
  if (el.style.charSpacing)
68978
71450
  shapeOptions.charSpacing = el.style.charSpacing;
71451
+ if (el.style.lineSpacing)
71452
+ shapeOptions.lineSpacing = el.style.lineSpacing;
71453
+ if (el.style.transparency !== null && el.style.transparency !== void 0) {
71454
+ shapeOptions.transparency = el.style.transparency;
71455
+ }
68979
71456
  if (el.style.glow) {
68980
71457
  shapeOptions.glow = {
68981
71458
  size: el.style.glow.size,
@@ -68995,10 +71472,14 @@ ${generateStylesCss(styleMap, themeFonts)}
68995
71472
  } else if (el.type === "list") {
68996
71473
  const heightIncrease = el.position.h * 0.15;
68997
71474
  const adjustedH = el.position.h + heightIncrease;
71475
+ const fontSize = el.style.fontSize ?? 12;
71476
+ const bufferPercent = fontSize < 14 ? 0.1 : fontSize < 24 ? 0.07 : 0.05;
71477
+ const widthIncrease = el.position.w * bufferPercent;
71478
+ const adjustedW = el.position.w + widthIncrease;
68998
71479
  const listOptions = {
68999
71480
  x: el.position.x,
69000
71481
  y: el.position.y,
69001
- w: el.position.w,
71482
+ w: adjustedW,
69002
71483
  h: adjustedH,
69003
71484
  fontSize: el.style.fontSize,
69004
71485
  fontFace: el.style.fontFace,
@@ -69019,13 +71500,15 @@ ${generateStylesCss(styleMap, themeFonts)}
69019
71500
  } else {
69020
71501
  const lineHeightPt = el.style.lineSpacing || (el.style.fontSize ?? 0) * 1.2;
69021
71502
  const heightPt = el.position.h * 72;
69022
- const isSingleLine = heightPt <= lineHeightPt * 1.5;
71503
+ const textContent2 = typeof el.text === "string" ? el.text : Array.isArray(el.text) ? el.text.map((r) => r.text).join("") : "";
71504
+ const hasNewlines = textContent2.includes("\n");
71505
+ const isSingleLine = !hasNewlines && heightPt <= lineHeightPt * 1.5;
69023
71506
  let adjustedX = el.position.x;
69024
71507
  let adjustedW;
69025
71508
  let adjustedH = el.position.h;
69026
71509
  if (isSingleLine) {
69027
71510
  const fontSize = el.style.fontSize ?? 12;
69028
- const bufferPercent = fontSize > 36 ? 0.02 : fontSize > 24 ? 0.015 : 0.01;
71511
+ const bufferPercent = fontSize < 14 ? 0.1 : fontSize < 24 ? 0.07 : 0.05;
69029
71512
  const widthIncrease = el.position.w * bufferPercent;
69030
71513
  const align = el.style.align;
69031
71514
  if (align === "center") {
@@ -69049,7 +71532,7 @@ ${generateStylesCss(styleMap, themeFonts)}
69049
71532
  } else {
69050
71533
  adjustedW = el.position.w + widthIncrease;
69051
71534
  }
69052
- const heightIncrease = el.position.h * 0.05;
71535
+ const heightIncrease = hasNewlines ? el.position.h * 1 : el.position.h * 0.05;
69053
71536
  adjustedH = el.position.h + heightIncrease;
69054
71537
  }
69055
71538
  const textOptions = {
@@ -69404,7 +71887,7 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
69404
71887
  }
69405
71888
  html = html.slice(0, start) + html.slice(i);
69406
71889
  }
69407
- html = html.replace(/opacity:\s*0\s*;?(?=\s*[}]|;)/g, "opacity: 1;");
71890
+ html = html.replace(/opacity:\s*0\s*(;?)(?=\s*[}";])/g, "opacity: 1$1");
69408
71891
  html = html.replace(/transition:\s*[^;}]+;?/g, "");
69409
71892
  html = html.replace(/pointer-events:\s*[^;}]+;?/g, "");
69410
71893
  const bodyBlockMatch = html.match(/body\s*\{([^}]*)\}/s);
@@ -76127,8 +78610,11 @@ ${String(ex)}`);
76127
78610
  } else if (opts.color) {
76128
78611
  runProps += genXmlColorSelection({ color: opts.color, transparency: opts.transparency });
76129
78612
  }
76130
- if (opts.highlight)
76131
- runProps += `<a:highlight>${createColorElement(opts.highlight)}</a:highlight>`;
78613
+ if (opts.highlight) {
78614
+ var highlightColor = typeof opts.highlight === "object" ? opts.highlight.color : opts.highlight;
78615
+ var highlightAlpha = typeof opts.highlight === "object" && opts.highlight.transparency != null ? `<a:alpha val="${Math.round((100 - opts.highlight.transparency) * 1e3)}"/>` : "";
78616
+ runProps += `<a:highlight>${createColorElement(highlightColor, highlightAlpha)}</a:highlight>`;
78617
+ }
76132
78618
  if (typeof opts.underline === "object" && opts.underline.color)
76133
78619
  runProps += `<a:uFill>${genXmlColorSelection(opts.underline.color)}</a:uFill>`;
76134
78620
  if (opts.glow)