docgen-utils 1.0.27 → 1.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +3 -3
  2. package/dist/bundle.js +2896 -389
  3. package/dist/bundle.min.js +105 -103
  4. package/dist/cli.js +142 -79
  5. package/dist/packages/cli/commands/export-docs.d.ts +1 -0
  6. package/dist/packages/cli/commands/export-docs.d.ts.map +1 -1
  7. package/dist/packages/cli/commands/export-docs.js +15 -5
  8. package/dist/packages/cli/commands/export-docs.js.map +1 -1
  9. package/dist/packages/cli/commands/export-slides.d.ts +1 -1
  10. package/dist/packages/cli/commands/export-slides.d.ts.map +1 -1
  11. package/dist/packages/cli/commands/export-slides.js +15 -5
  12. package/dist/packages/cli/commands/export-slides.js.map +1 -1
  13. package/dist/packages/cli/index.js +9 -6
  14. package/dist/packages/cli/index.js.map +1 -1
  15. package/dist/packages/docs/convert.d.ts.map +1 -1
  16. package/dist/packages/docs/convert.js +0 -197
  17. package/dist/packages/docs/convert.js.map +1 -1
  18. package/dist/packages/docs/import-docx.d.ts.map +1 -1
  19. package/dist/packages/docs/import-docx.js +1 -6
  20. package/dist/packages/docs/import-docx.js.map +1 -1
  21. package/dist/packages/docs/parse.js +1 -1
  22. package/dist/packages/docs/parse.js.map +1 -1
  23. package/dist/packages/shared/convert-to-pdf.d.ts +16 -0
  24. package/dist/packages/shared/convert-to-pdf.d.ts.map +1 -0
  25. package/dist/packages/shared/convert-to-pdf.js +65 -0
  26. package/dist/packages/shared/convert-to-pdf.js.map +1 -0
  27. package/dist/packages/slides/common.d.ts +44 -2
  28. package/dist/packages/slides/common.d.ts.map +1 -1
  29. package/dist/packages/slides/convert.d.ts.map +1 -1
  30. package/dist/packages/slides/convert.js +66 -14
  31. package/dist/packages/slides/convert.js.map +1 -1
  32. package/dist/packages/slides/parse.d.ts.map +1 -1
  33. package/dist/packages/slides/parse.js +3546 -393
  34. package/dist/packages/slides/parse.js.map +1 -1
  35. package/dist/packages/slides/transform.d.ts.map +1 -1
  36. package/dist/packages/slides/transform.js +2 -1
  37. package/dist/packages/slides/transform.js.map +1 -1
  38. package/dist/packages/slides/vendor/VENDORING.md +1 -0
  39. package/dist/packages/slides/vendor/pptxgen.d.ts +2 -2
  40. package/dist/packages/slides/vendor/pptxgen.js +8 -2
  41. package/package.json +1 -1
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) {
@@ -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,28 @@ ${generateStylesCss(styleMap, themeFonts)}
65528
65528
  const alpha = parseFloat(match[4]);
65529
65529
  return Math.round((1 - alpha) * 100);
65530
65530
  }
65531
+ function extractZIndex(computed) {
65532
+ const zIndex = computed.zIndex;
65533
+ if (zIndex === "auto" || zIndex === "")
65534
+ return void 0;
65535
+ const parsed = parseInt(zIndex, 10);
65536
+ if (isNaN(parsed))
65537
+ return void 0;
65538
+ return parsed;
65539
+ }
65540
+ function getEffectiveOpacity(element, win) {
65541
+ let effectiveOpacity = 1;
65542
+ let current = element;
65543
+ while (current && current !== win.document.body && current !== win.document.documentElement) {
65544
+ const computed = win.getComputedStyle(current);
65545
+ const opacity = parseFloat(computed.opacity);
65546
+ if (!isNaN(opacity) && opacity < 1) {
65547
+ effectiveOpacity *= opacity;
65548
+ }
65549
+ current = current.parentElement;
65550
+ }
65551
+ return effectiveOpacity;
65552
+ }
65531
65553
  function extractDashType(borderStyle) {
65532
65554
  switch (borderStyle.toLowerCase()) {
65533
65555
  case "dashed":
@@ -65578,18 +65600,6 @@ ${generateStylesCss(styleMap, themeFonts)}
65578
65600
  }
65579
65601
  return null;
65580
65602
  }
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
65603
  function splitCssBackgroundGradients(bgImage) {
65594
65604
  if (!bgImage || bgImage === "none")
65595
65605
  return [];
@@ -65990,8 +66000,50 @@ ${generateStylesCss(styleMap, themeFonts)}
65990
66000
  }
65991
66001
  return text;
65992
66002
  }
66003
+ var monospaceFonts = /* @__PURE__ */ new Set([
66004
+ "consolas",
66005
+ "courier",
66006
+ "courier new",
66007
+ "monospace",
66008
+ "monaco",
66009
+ "lucida console",
66010
+ "dejavu sans mono",
66011
+ "source code pro",
66012
+ "fira code",
66013
+ "roboto mono",
66014
+ "jetbrains mono",
66015
+ "inconsolata",
66016
+ "menlo",
66017
+ "sf mono",
66018
+ "ubuntu mono",
66019
+ "droid sans mono",
66020
+ "andale mono",
66021
+ "liberation mono"
66022
+ ]);
66023
+ function isMonospaceFont(fontFamily) {
66024
+ const primaryFont = fontFamily.split(",")[0].trim().replace(/['"]/g, "").toLowerCase();
66025
+ if (monospaceFonts.has(primaryFont)) {
66026
+ return true;
66027
+ }
66028
+ const fonts = fontFamily.toLowerCase();
66029
+ return fonts.includes("monospace") || fonts.includes("consolas") || fonts.includes("courier");
66030
+ }
66031
+ function shouldPreserveWhitespace(computed) {
66032
+ const whiteSpace = computed.whiteSpace;
66033
+ if (whiteSpace === "pre" || whiteSpace === "pre-wrap" || whiteSpace === "pre-line") {
66034
+ return true;
66035
+ }
66036
+ return isMonospaceFont(computed.fontFamily);
66037
+ }
65993
66038
  function getTransformedText(element, computed) {
65994
- const rawText = element.textContent?.trim() || "";
66039
+ const preserveWhitespace = shouldPreserveWhitespace(computed);
66040
+ let rawText;
66041
+ if (preserveWhitespace) {
66042
+ rawText = element.innerText || element.textContent || "";
66043
+ } else {
66044
+ rawText = element.textContent?.trim() || "";
66045
+ }
66046
+ rawText = rawText.replace(/\u00A0/g, " ");
65995
66047
  const textTransform = computed.textTransform;
65996
66048
  if (textTransform && textTransform !== "none") {
65997
66049
  return applyTextTransform2(rawText, textTransform);
@@ -66542,6 +66594,8 @@ ${generateStylesCss(styleMap, themeFonts)}
66542
66594
  const parentRect = el.getBoundingClientRect();
66543
66595
  if (parentRect.width <= 0 || parentRect.height <= 0)
66544
66596
  return results;
66597
+ const parentComputed = win.getComputedStyle(el);
66598
+ const parentZIndex = extractZIndex(parentComputed);
66545
66599
  for (const pseudo of ["::before", "::after"]) {
66546
66600
  const pComputed = win.getComputedStyle(el, pseudo);
66547
66601
  const content = pComputed.content;
@@ -66579,16 +66633,16 @@ ${generateStylesCss(styleMap, themeFonts)}
66579
66633
  pTop = 0;
66580
66634
  const pseudoPos = pComputed.position;
66581
66635
  if (!pseudoPos || pseudoPos === "static") {
66582
- const parentComputed = win.getComputedStyle(el);
66583
- const parentDisplay = parentComputed.display;
66636
+ const parentComputed2 = win.getComputedStyle(el);
66637
+ const parentDisplay = parentComputed2.display;
66584
66638
  const isFlex = parentDisplay === "flex" || parentDisplay === "inline-flex";
66585
66639
  const isGrid = parentDisplay === "grid" || parentDisplay === "inline-grid";
66586
66640
  if (isFlex) {
66587
- const flexDir = parentComputed.flexDirection || "row";
66641
+ const flexDir = parentComputed2.flexDirection || "row";
66588
66642
  const isRow = flexDir === "row" || flexDir === "row-reverse";
66589
66643
  const isReverse = flexDir.endsWith("-reverse");
66590
66644
  const alignSelf = pComputed.alignSelf;
66591
- const effectiveAlign = alignSelf && alignSelf !== "auto" ? alignSelf : parentComputed.alignItems || "stretch";
66645
+ const effectiveAlign = alignSelf && alignSelf !== "auto" ? alignSelf : parentComputed2.alignItems || "stretch";
66592
66646
  const mTop = parseFloat(pComputed.marginTop) || 0;
66593
66647
  const mRight = parseFloat(pComputed.marginRight) || 0;
66594
66648
  const mBottom = parseFloat(pComputed.marginBottom) || 0;
@@ -66611,8 +66665,8 @@ ${generateStylesCss(styleMap, themeFonts)}
66611
66665
  crossOffset = crossMarginBefore;
66612
66666
  break;
66613
66667
  }
66614
- const gapProp = isRow ? parentComputed.columnGap : parentComputed.rowGap;
66615
- const mainGap = parseFloat(gapProp) || parseFloat(parentComputed.gap) || 0;
66668
+ const gapProp = isRow ? parentComputed2.columnGap : parentComputed2.rowGap;
66669
+ const mainGap = parseFloat(gapProp) || parseFloat(parentComputed2.gap) || 0;
66616
66670
  const realChildren = Array.from(el.children).filter((c) => {
66617
66671
  const s = win.getComputedStyle(c);
66618
66672
  return s.display !== "none" && s.position !== "absolute" && s.position !== "fixed";
@@ -66636,7 +66690,7 @@ ${generateStylesCss(styleMap, themeFonts)}
66636
66690
  mainOffset = marginBefore;
66637
66691
  }
66638
66692
  } else {
66639
- const justify = parentComputed.justifyContent || "normal";
66693
+ const justify = parentComputed2.justifyContent || "normal";
66640
66694
  const mainSize = isRow ? parentRect.width : parentRect.height;
66641
66695
  const pseudoMainOuter = isRow ? pWidth + mLeft + mRight : pHeight + mTop + mBottom;
66642
66696
  const marginBefore = isRow ? mLeft : mTop;
@@ -66652,9 +66706,9 @@ ${generateStylesCss(styleMap, themeFonts)}
66652
66706
  pTop = isRow ? crossOffset : mainOffset;
66653
66707
  } else if (isGrid) {
66654
66708
  const alignSelf = pComputed.alignSelf;
66655
- const alignItems = alignSelf && alignSelf !== "auto" ? alignSelf : parentComputed.alignItems || "stretch";
66709
+ const alignItems = alignSelf && alignSelf !== "auto" ? alignSelf : parentComputed2.alignItems || "stretch";
66656
66710
  const justifySelf = pComputed.justifySelf;
66657
- const justifyItems = justifySelf && justifySelf !== "auto" ? justifySelf : parentComputed.justifyItems || "stretch";
66711
+ const justifyItems = justifySelf && justifySelf !== "auto" ? justifySelf : parentComputed2.justifyItems || "stretch";
66658
66712
  if (alignItems === "center") {
66659
66713
  pTop = (parentRect.height - pHeight) / 2;
66660
66714
  } else if (alignItems === "end") {
@@ -66683,7 +66737,13 @@ ${generateStylesCss(styleMap, themeFonts)}
66683
66737
  const bgImage = pComputed.backgroundImage;
66684
66738
  const hasGradient = bgImage && bgImage !== "none" && (bgImage.includes("linear-gradient") || bgImage.includes("radial-gradient"));
66685
66739
  const hasBgImage = bgImage && bgImage !== "none" && bgImage.includes("url(");
66686
- if (!hasBg && !hasGradient && !hasBgImage)
66740
+ const pseudoBorderTopWidth = parseFloat(pComputed.borderTopWidth) || 0;
66741
+ const pseudoBorderRightWidth = parseFloat(pComputed.borderRightWidth) || 0;
66742
+ const pseudoBorderBottomWidth = parseFloat(pComputed.borderBottomWidth) || 0;
66743
+ const pseudoBorderLeftWidth = parseFloat(pComputed.borderLeftWidth) || 0;
66744
+ const hasPseudoBorder = pseudoBorderTopWidth > 0 || pseudoBorderRightWidth > 0 || pseudoBorderBottomWidth > 0 || pseudoBorderLeftWidth > 0;
66745
+ const hasUniformPseudoBorder = hasPseudoBorder && pseudoBorderTopWidth === pseudoBorderRightWidth && pseudoBorderRightWidth === pseudoBorderBottomWidth && pseudoBorderBottomWidth === pseudoBorderLeftWidth;
66746
+ if (!hasBg && !hasGradient && !hasBgImage && !hasPseudoBorder)
66687
66747
  continue;
66688
66748
  let gradient = null;
66689
66749
  const extraPseudoGradients = [];
@@ -66704,10 +66764,16 @@ ${generateStylesCss(styleMap, themeFonts)}
66704
66764
  let rectRadius = 0;
66705
66765
  const borderRadius = pComputed.borderRadius;
66706
66766
  const radiusValue = parseFloat(borderRadius);
66767
+ const pseudoRadiusTL = parseFloat(pComputed.borderTopLeftRadius) || 0;
66768
+ const pseudoRadiusTR = parseFloat(pComputed.borderTopRightRadius) || 0;
66769
+ const pseudoRadiusBL = parseFloat(pComputed.borderBottomLeftRadius) || 0;
66770
+ const pseudoRadiusBR = parseFloat(pComputed.borderBottomRightRadius) || 0;
66771
+ const hasPseudoRadius = pseudoRadiusTL > 0 || pseudoRadiusTR > 0 || pseudoRadiusBL > 0 || pseudoRadiusBR > 0;
66772
+ const hasNonUniformPseudoRadius = hasPseudoRadius && (pseudoRadiusTL !== pseudoRadiusTR || pseudoRadiusTL !== pseudoRadiusBL || pseudoRadiusTL !== pseudoRadiusBR);
66707
66773
  const isCircularRadius = borderRadius.includes("%") ? radiusValue >= 50 : radiusValue > 0 && radiusValue >= Math.min(pWidth, pHeight) / 2 - 1;
66708
66774
  const aspectRatio = pWidth / pHeight;
66709
66775
  const isEllipse = isCircularRadius && aspectRatio > 0.5 && aspectRatio < 2;
66710
- if (radiusValue > 0 && !isEllipse) {
66776
+ if (radiusValue > 0 && !isEllipse && !hasNonUniformPseudoRadius) {
66711
66777
  if (borderRadius.includes("%")) {
66712
66778
  const minDim = Math.min(pWidth, pHeight);
66713
66779
  rectRadius = radiusValue / 100 * pxToInch(minDim);
@@ -66716,17 +66782,18 @@ ${generateStylesCss(styleMap, themeFonts)}
66716
66782
  }
66717
66783
  }
66718
66784
  const shadow = parseBoxShadow(pComputed.boxShadow);
66785
+ const pseudoRotation = extractRotationAngle(pComputed);
66719
66786
  let effectiveRectRadius = isEllipse ? 0 : rectRadius;
66720
66787
  if (rectRadius === 0 && !isEllipse) {
66721
- const parentComputed = win.getComputedStyle(el);
66722
- const parentOverflow = parentComputed.overflow;
66788
+ const parentComputed2 = win.getComputedStyle(el);
66789
+ const parentOverflow = parentComputed2.overflow;
66723
66790
  if (parentOverflow === "hidden" || parentOverflow === "clip") {
66724
- const parentRadius = parseFloat(parentComputed.borderRadius);
66791
+ const parentRadius = parseFloat(parentComputed2.borderRadius);
66725
66792
  if (parentRadius > 0) {
66726
- const parentBorderLeft = parseFloat(parentComputed.borderLeftWidth) || 0;
66727
- const parentBorderRight = parseFloat(parentComputed.borderRightWidth) || 0;
66728
- const parentBorderTop = parseFloat(parentComputed.borderTopWidth) || 0;
66729
- const parentBorderBottom = parseFloat(parentComputed.borderBottomWidth) || 0;
66793
+ const parentBorderLeft = parseFloat(parentComputed2.borderLeftWidth) || 0;
66794
+ const parentBorderRight = parseFloat(parentComputed2.borderRightWidth) || 0;
66795
+ const parentBorderTop = parseFloat(parentComputed2.borderTopWidth) || 0;
66796
+ const parentBorderBottom = parseFloat(parentComputed2.borderBottomWidth) || 0;
66730
66797
  const parentInnerWidth = parentRect.width - parentBorderLeft - parentBorderRight;
66731
66798
  const parentInnerHeight = parentRect.height - parentBorderTop - parentBorderBottom;
66732
66799
  const flushTop = Math.abs(pTop) < 2;
@@ -66741,6 +66808,244 @@ ${generateStylesCss(styleMap, themeFonts)}
66741
66808
  }
66742
66809
  }
66743
66810
  }
66811
+ let asymmetricCornerGeometry = null;
66812
+ if (rectRadius === 0 && !isEllipse && effectiveRectRadius > 0) {
66813
+ const parentComputed2 = win.getComputedStyle(el);
66814
+ const parentRadius = parseFloat(parentComputed2.borderRadius);
66815
+ const isThinHorizontal = pHeight < parentRadius && pWidth >= parentRadius * 2;
66816
+ const isThinVertical = pWidth < parentRadius && pHeight >= parentRadius * 2;
66817
+ if (isThinHorizontal || isThinVertical) {
66818
+ const parentBorderLeft = parseFloat(parentComputed2.borderLeftWidth) || 0;
66819
+ const parentBorderRight = parseFloat(parentComputed2.borderRightWidth) || 0;
66820
+ const parentBorderTop = parseFloat(parentComputed2.borderTopWidth) || 0;
66821
+ const parentBorderBottom = parseFloat(parentComputed2.borderBottomWidth) || 0;
66822
+ const parentInnerWidth = parentRect.width - parentBorderLeft - parentBorderRight;
66823
+ const parentInnerHeight = parentRect.height - parentBorderTop - parentBorderBottom;
66824
+ const flushTop = Math.abs(pTop) < 2;
66825
+ const flushLeft = Math.abs(pLeft) < 2;
66826
+ const flushRight = Math.abs(pLeft + pWidth - parentRect.width) < 2 || Math.abs(pLeft + pWidth - parentInnerWidth) < 2;
66827
+ const flushBottom = Math.abs(pTop + pHeight - parentRect.height) < 2 || Math.abs(pTop + pHeight - parentInnerHeight) < 2;
66828
+ const arcXAtY = (r2, y) => {
66829
+ if (y <= 0)
66830
+ return r2;
66831
+ if (y >= r2)
66832
+ return 0;
66833
+ const dy = r2 - y;
66834
+ return r2 - Math.sqrt(r2 * r2 - dy * dy);
66835
+ };
66836
+ const h = pHeight;
66837
+ const w = pWidth;
66838
+ const r = parentRadius;
66839
+ const EMU_PER_PX3 = 914400 / 96;
66840
+ const points = [];
66841
+ if (isThinHorizontal && flushTop) {
66842
+ const segments = 8;
66843
+ const arcPointsLeft = [];
66844
+ const arcPointsRight = [];
66845
+ for (let i = 0; i <= segments; i++) {
66846
+ const t = i / segments;
66847
+ const y = t * h;
66848
+ const x = arcXAtY(r, y);
66849
+ arcPointsLeft.push({
66850
+ x: Math.round(x * EMU_PER_PX3),
66851
+ y: Math.round(y * EMU_PER_PX3)
66852
+ });
66853
+ arcPointsRight.push({
66854
+ x: Math.round((w - x) * EMU_PER_PX3),
66855
+ y: Math.round(y * EMU_PER_PX3)
66856
+ });
66857
+ }
66858
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
66859
+ points.push({ x: arcPointsRight[0].x, y: arcPointsRight[0].y });
66860
+ for (let i = 1; i <= segments; i++) {
66861
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
66862
+ }
66863
+ points.push({ x: arcPointsLeft[segments].x, y: arcPointsLeft[segments].y });
66864
+ for (let i = segments - 1; i >= 1; i--) {
66865
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
66866
+ }
66867
+ points.push({ x: 0, y: 0, close: true });
66868
+ asymmetricCornerGeometry = points;
66869
+ } else if (isThinHorizontal && flushBottom) {
66870
+ const segments = 8;
66871
+ const arcPointsLeft = [];
66872
+ const arcPointsRight = [];
66873
+ for (let i = 0; i <= segments; i++) {
66874
+ const t = i / segments;
66875
+ const y = t * h;
66876
+ const arcDistance = arcXAtY(r, h - y);
66877
+ arcPointsLeft.push({
66878
+ x: Math.round(arcDistance * EMU_PER_PX3),
66879
+ y: Math.round(y * EMU_PER_PX3)
66880
+ });
66881
+ arcPointsRight.push({
66882
+ x: Math.round((w - arcDistance) * EMU_PER_PX3),
66883
+ y: Math.round(y * EMU_PER_PX3)
66884
+ });
66885
+ }
66886
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
66887
+ points.push({ x: arcPointsRight[0].x, y: arcPointsRight[0].y });
66888
+ for (let i = 1; i <= segments; i++) {
66889
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
66890
+ }
66891
+ points.push({ x: arcPointsLeft[segments].x, y: arcPointsLeft[segments].y });
66892
+ for (let i = segments - 1; i >= 0; i--) {
66893
+ if (i === 0) {
66894
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y, close: true });
66895
+ } else {
66896
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
66897
+ }
66898
+ }
66899
+ asymmetricCornerGeometry = points;
66900
+ } else if (isThinVertical && flushLeft) {
66901
+ const arcYAtX = (radius, x) => {
66902
+ if (x <= 0)
66903
+ return radius;
66904
+ if (x >= radius)
66905
+ return 0;
66906
+ const dx = radius - x;
66907
+ return radius - Math.sqrt(radius * radius - dx * dx);
66908
+ };
66909
+ const segments = 8;
66910
+ const arcPointsTop = [];
66911
+ const arcPointsBottom = [];
66912
+ for (let i = 0; i <= segments; i++) {
66913
+ const t = i / segments;
66914
+ const x = t * w;
66915
+ const arcDistance = arcYAtX(r, x);
66916
+ arcPointsTop.push({
66917
+ x: Math.round(x * EMU_PER_PX3),
66918
+ y: Math.round(arcDistance * EMU_PER_PX3)
66919
+ });
66920
+ arcPointsBottom.push({
66921
+ x: Math.round(x * EMU_PER_PX3),
66922
+ y: Math.round((h - arcDistance) * EMU_PER_PX3)
66923
+ });
66924
+ }
66925
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
66926
+ for (let i = 1; i <= segments; i++) {
66927
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
66928
+ }
66929
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
66930
+ for (let i = segments - 1; i >= 0; i--) {
66931
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
66932
+ }
66933
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
66934
+ asymmetricCornerGeometry = points;
66935
+ } else if (isThinVertical && flushRight) {
66936
+ const arcYAtX = (radius, x) => {
66937
+ if (x <= 0)
66938
+ return radius;
66939
+ if (x >= radius)
66940
+ return 0;
66941
+ const dx = radius - x;
66942
+ return radius - Math.sqrt(radius * radius - dx * dx);
66943
+ };
66944
+ const segments = 8;
66945
+ const arcPointsTop = [];
66946
+ const arcPointsBottom = [];
66947
+ for (let i = 0; i <= segments; i++) {
66948
+ const t = i / segments;
66949
+ const x = t * w;
66950
+ const arcDistance = arcYAtX(r, w - x);
66951
+ arcPointsTop.push({
66952
+ x: Math.round(x * EMU_PER_PX3),
66953
+ y: Math.round(arcDistance * EMU_PER_PX3)
66954
+ });
66955
+ arcPointsBottom.push({
66956
+ x: Math.round(x * EMU_PER_PX3),
66957
+ y: Math.round((h - arcDistance) * EMU_PER_PX3)
66958
+ });
66959
+ }
66960
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
66961
+ for (let i = 1; i <= segments; i++) {
66962
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
66963
+ }
66964
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
66965
+ for (let i = segments - 1; i >= 0; i--) {
66966
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
66967
+ }
66968
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
66969
+ asymmetricCornerGeometry = points;
66970
+ }
66971
+ if (asymmetricCornerGeometry) {
66972
+ effectiveRectRadius = 0;
66973
+ }
66974
+ }
66975
+ }
66976
+ if (!asymmetricCornerGeometry && hasNonUniformPseudoRadius && !isEllipse) {
66977
+ const w = pWidth;
66978
+ const h = pHeight;
66979
+ const EMU_PER_PX3 = 914400 / 96;
66980
+ const widthEmu = Math.round(w * EMU_PER_PX3);
66981
+ const heightEmu = Math.round(h * EMU_PER_PX3);
66982
+ const segments = 8;
66983
+ const points = [];
66984
+ const addCornerArc = (cornerRadius, isRight, isBottom) => {
66985
+ if (cornerRadius <= 0)
66986
+ return;
66987
+ for (let i = 0; i <= segments; i++) {
66988
+ const t = i / segments;
66989
+ const angle = t * Math.PI / 2;
66990
+ let x, y;
66991
+ if (!isRight && !isBottom) {
66992
+ x = cornerRadius * (1 - Math.sin(angle));
66993
+ y = cornerRadius * (1 - Math.cos(angle));
66994
+ } else if (isRight && !isBottom) {
66995
+ x = w - cornerRadius + cornerRadius * Math.sin(angle);
66996
+ y = cornerRadius * (1 - Math.cos(angle));
66997
+ } else if (!isRight && isBottom) {
66998
+ x = cornerRadius * (1 - Math.cos(angle));
66999
+ y = h - cornerRadius + cornerRadius * Math.sin(angle);
67000
+ } else {
67001
+ x = w - cornerRadius + cornerRadius * Math.cos(angle);
67002
+ y = h - cornerRadius + cornerRadius * Math.sin(angle);
67003
+ }
67004
+ x = Math.max(0, Math.min(w, x));
67005
+ y = Math.max(0, Math.min(h, y));
67006
+ points.push({
67007
+ x: Math.round(x * EMU_PER_PX3),
67008
+ y: Math.round(y * EMU_PER_PX3),
67009
+ ...points.length === 0 ? { moveTo: true } : {}
67010
+ });
67011
+ }
67012
+ };
67013
+ if (pseudoRadiusTL > 0) {
67014
+ points.push({ x: Math.round(pseudoRadiusTL * EMU_PER_PX3), y: 0, moveTo: true });
67015
+ } else {
67016
+ points.push({ x: 0, y: 0, moveTo: true });
67017
+ }
67018
+ if (pseudoRadiusTR > 0) {
67019
+ points.push({ x: Math.round((w - pseudoRadiusTR) * EMU_PER_PX3), y: 0 });
67020
+ addCornerArc(pseudoRadiusTR, true, false);
67021
+ } else {
67022
+ points.push({ x: widthEmu, y: 0 });
67023
+ }
67024
+ if (pseudoRadiusBR > 0) {
67025
+ points.push({ x: widthEmu, y: Math.round((h - pseudoRadiusBR) * EMU_PER_PX3) });
67026
+ addCornerArc(pseudoRadiusBR, true, true);
67027
+ } else {
67028
+ points.push({ x: widthEmu, y: heightEmu });
67029
+ }
67030
+ if (pseudoRadiusBL > 0) {
67031
+ points.push({ x: Math.round(pseudoRadiusBL * EMU_PER_PX3), y: heightEmu });
67032
+ addCornerArc(pseudoRadiusBL, false, true);
67033
+ } else {
67034
+ points.push({ x: 0, y: heightEmu });
67035
+ }
67036
+ if (pseudoRadiusTL > 0) {
67037
+ points.push({ x: 0, y: Math.round(pseudoRadiusTL * EMU_PER_PX3) });
67038
+ addCornerArc(pseudoRadiusTL, false, false);
67039
+ }
67040
+ if (points.length > 0) {
67041
+ const firstPoint = points[0];
67042
+ points.push({ x: firstPoint.x, y: firstPoint.y, close: true });
67043
+ }
67044
+ if (points.length > 5) {
67045
+ asymmetricCornerGeometry = points;
67046
+ effectiveRectRadius = 0;
67047
+ }
67048
+ }
66744
67049
  const shapeElement = {
66745
67050
  type: "shape",
66746
67051
  text: "",
@@ -66756,15 +67061,22 @@ ${generateStylesCss(styleMap, themeFonts)}
66756
67061
  fill: hasBg ? rgbToHex(pComputed.backgroundColor) : null,
66757
67062
  gradient,
66758
67063
  transparency: hasBg ? extractAlpha(pComputed.backgroundColor) : null,
66759
- line: null,
67064
+ line: hasUniformPseudoBorder ? {
67065
+ color: rgbToHex(pComputed.borderColor),
67066
+ width: pxToPoints(pComputed.borderTopWidth),
67067
+ transparency: extractAlpha(pComputed.borderColor),
67068
+ dashType: extractDashType(pComputed.borderStyle)
67069
+ } : null,
66760
67070
  rectRadius: effectiveRectRadius,
66761
67071
  shadow,
66762
67072
  opacity: hasOpacity ? elementOpacity : null,
66763
67073
  isEllipse,
66764
67074
  softEdge: null,
66765
- rotate: null,
66766
- customGeometry: null
66767
- }
67075
+ rotate: pseudoRotation,
67076
+ cssTriangle: null,
67077
+ customGeometry: asymmetricCornerGeometry
67078
+ },
67079
+ zIndex: parentZIndex
66768
67080
  };
66769
67081
  results.push(shapeElement);
66770
67082
  for (const extraGrad of extraPseudoGradients) {
@@ -66785,15 +67097,17 @@ ${generateStylesCss(styleMap, themeFonts)}
66785
67097
  isEllipse: false,
66786
67098
  softEdge: null,
66787
67099
  rotate: null,
67100
+ cssTriangle: null,
66788
67101
  customGeometry: null
66789
- }
67102
+ },
67103
+ zIndex: parentZIndex
66790
67104
  };
66791
67105
  results.push(extraShape);
66792
67106
  }
66793
67107
  }
66794
67108
  return results;
66795
67109
  }
66796
- function parseInlineFormatting(element, baseOptions, runs, baseTextTransform, win) {
67110
+ function parseInlineFormatting(element, baseOptions, runs, baseTextTransform, win, preserveWhitespace = false) {
66797
67111
  let prevNodeIsText = false;
66798
67112
  let pendingSoftBreak = false;
66799
67113
  element.childNodes.forEach((node) => {
@@ -66802,7 +67116,32 @@ ${generateStylesCss(styleMap, themeFonts)}
66802
67116
  pendingSoftBreak = true;
66803
67117
  prevNodeIsText = false;
66804
67118
  } else if (node.nodeType === Node.TEXT_NODE) {
66805
- const text = textTransform(node.textContent.replace(/\s+/g, " "));
67119
+ let rawText = node.textContent || "";
67120
+ rawText = rawText.replace(/\u00A0/g, " ");
67121
+ let text;
67122
+ if (preserveWhitespace) {
67123
+ const lines = rawText.split("\n");
67124
+ for (let i = 0; i < lines.length; i++) {
67125
+ let lineText = lines[i];
67126
+ lineText = textTransform(lineText);
67127
+ const prevRun2 = runs[runs.length - 1];
67128
+ if (i === 0 && prevNodeIsText && prevRun2 && !pendingSoftBreak) {
67129
+ prevRun2.text += lineText;
67130
+ } else {
67131
+ const runOptions = { ...baseOptions };
67132
+ if (i > 0 || pendingSoftBreak) {
67133
+ runOptions.softBreakBefore = true;
67134
+ pendingSoftBreak = false;
67135
+ }
67136
+ const runText = lineText.length > 0 ? lineText : " ";
67137
+ runs.push({ text: runText, options: runOptions });
67138
+ }
67139
+ }
67140
+ prevNodeIsText = true;
67141
+ return;
67142
+ } else {
67143
+ text = textTransform(rawText.replace(/\s+/g, " "));
67144
+ }
66806
67145
  const prevRun = runs[runs.length - 1];
66807
67146
  if (prevNodeIsText && prevRun && !pendingSoftBreak) {
66808
67147
  prevRun.text += text;
@@ -66858,6 +67197,17 @@ ${generateStylesCss(styleMap, themeFonts)}
66858
67197
  if (transparency !== null)
66859
67198
  options.transparency = transparency;
66860
67199
  }
67200
+ if (computed.backgroundColor && computed.backgroundColor !== "rgba(0, 0, 0, 0)") {
67201
+ const bgAlpha = extractAlpha(computed.backgroundColor);
67202
+ if (bgAlpha !== null && bgAlpha > 0) {
67203
+ options.highlight = {
67204
+ color: rgbToHex(computed.backgroundColor),
67205
+ transparency: bgAlpha
67206
+ };
67207
+ } else {
67208
+ options.highlight = rgbToHex(computed.backgroundColor);
67209
+ }
67210
+ }
66861
67211
  const bgClip = computed.webkitBackgroundClip || computed.backgroundClip;
66862
67212
  const textFillColor = computed.webkitTextFillColor;
66863
67213
  const isTextFillTransparent = textFillColor === "transparent" || textFillColor === "rgba(0, 0, 0, 0)" || textFillColor && textFillColor.includes("rgba") && textFillColor.endsWith(", 0)");
@@ -66871,10 +67221,17 @@ ${generateStylesCss(styleMap, themeFonts)}
66871
67221
  }
66872
67222
  }
66873
67223
  }
66874
- if (computed.fontSize)
66875
- options.fontSize = pxToPoints(computed.fontSize);
66876
- if (computed.fontFamily) {
66877
- options.fontFace = extractFontFace(computed.fontFamily);
67224
+ const inlineFontFace = computed.fontFamily ? extractFontFace(computed.fontFamily) : null;
67225
+ const baseFontFaceForCheck = baseOptions.fontFace || "";
67226
+ const baseFontFaceIsMonospace = baseFontFaceForCheck && isMonospaceFont(baseFontFaceForCheck);
67227
+ if (computed.fontSize) {
67228
+ const shouldKeepBaseFontSize = baseOptions.fontSize && baseFontFaceIsMonospace;
67229
+ if (!shouldKeepBaseFontSize) {
67230
+ options.fontSize = pxToPoints(computed.fontSize);
67231
+ }
67232
+ }
67233
+ if (inlineFontFace) {
67234
+ options.fontFace = inlineFontFace;
66878
67235
  }
66879
67236
  const runLetterSpacing = extractLetterSpacing(computed);
66880
67237
  if (runLetterSpacing !== null)
@@ -66888,18 +67245,65 @@ ${generateStylesCss(styleMap, themeFonts)}
66888
67245
  if (pendingSoftBreak) {
66889
67246
  pendingSoftBreak = false;
66890
67247
  }
66891
- parseInlineFormatting(el, options, runs, textTransform, win);
67248
+ parseInlineFormatting(el, options, runs, textTransform, win, preserveWhitespace);
66892
67249
  if (hadPendingSoftBreak && runs.length > runsBeforeRecurse) {
66893
67250
  runs[runsBeforeRecurse].options = {
66894
67251
  ...runs[runsBeforeRecurse].options,
66895
67252
  softBreakBefore: true
66896
67253
  };
66897
67254
  }
67255
+ } else {
67256
+ const blockTags = /* @__PURE__ */ new Set(["P", "DIV", "LI", "BLOCKQUOTE", "PRE", "H1", "H2", "H3", "H4", "H5", "H6"]);
67257
+ if (blockTags.has(el.tagName)) {
67258
+ const runsBeforeRecurse = runs.length;
67259
+ const hadPendingSoftBreak = pendingSoftBreak;
67260
+ if (pendingSoftBreak) {
67261
+ pendingSoftBreak = false;
67262
+ }
67263
+ let blockPreserveWhitespace = preserveWhitespace;
67264
+ const blockComputed = win.getComputedStyle(el);
67265
+ if (el.tagName === "PRE") {
67266
+ const ws = blockComputed.whiteSpace;
67267
+ blockPreserveWhitespace = ws === "pre" || ws === "pre-wrap" || ws === "pre-line";
67268
+ }
67269
+ const blockOptions = { ...baseOptions };
67270
+ const blockIsBold = blockComputed.fontWeight === "bold" || parseInt(blockComputed.fontWeight) >= 600;
67271
+ if (blockIsBold && !shouldSkipBold(blockComputed.fontFamily)) {
67272
+ blockOptions.bold = true;
67273
+ }
67274
+ if (blockComputed.fontStyle === "italic") {
67275
+ blockOptions.italic = true;
67276
+ }
67277
+ if (blockComputed.textDecoration?.includes("underline")) {
67278
+ blockOptions.underline = true;
67279
+ }
67280
+ if (blockComputed.color && blockComputed.color !== "rgb(0, 0, 0)") {
67281
+ blockOptions.color = rgbToHex(blockComputed.color);
67282
+ const transparency = extractAlpha(blockComputed.color);
67283
+ if (transparency !== null)
67284
+ blockOptions.transparency = transparency;
67285
+ }
67286
+ if (blockComputed.fontSize) {
67287
+ blockOptions.fontSize = pxToPoints(blockComputed.fontSize);
67288
+ }
67289
+ if (blockComputed.fontFamily) {
67290
+ blockOptions.fontFace = extractFontFace(blockComputed.fontFamily);
67291
+ }
67292
+ parseInlineFormatting(el, blockOptions, runs, textTransform, win, blockPreserveWhitespace);
67293
+ if (runs.length > runsBeforeRecurse) {
67294
+ if (hadPendingSoftBreak || runsBeforeRecurse > 0) {
67295
+ runs[runsBeforeRecurse].options = {
67296
+ ...runs[runsBeforeRecurse].options,
67297
+ breakLine: true
67298
+ };
67299
+ }
67300
+ }
67301
+ }
66898
67302
  }
66899
67303
  prevNodeIsText = false;
66900
67304
  }
66901
67305
  });
66902
- if (runs.length > 0) {
67306
+ if (!preserveWhitespace && runs.length > 0) {
66903
67307
  runs[0].text = runs[0].text.replace(/^\s+/, "");
66904
67308
  runs[runs.length - 1].text = runs[runs.length - 1].text.replace(/\s+$/, "");
66905
67309
  }
@@ -66934,7 +67338,7 @@ ${generateStylesCss(styleMap, themeFonts)}
66934
67338
  }
66935
67339
  const elements = [];
66936
67340
  const placeholders = [];
66937
- const textTags = ["P", "H1", "H2", "H3", "H4", "H5", "H6", "UL", "OL", "LI", "SPAN"];
67341
+ const textTags = ["P", "H1", "H2", "H3", "H4", "H5", "H6", "UL", "OL", "LI", "SPAN", "PRE"];
66938
67342
  const processed = /* @__PURE__ */ new Set();
66939
67343
  const bodyPseudoElements = extractPseudoElements(body, win);
66940
67344
  elements.push(...bodyPseudoElements);
@@ -66948,32 +67352,24 @@ ${generateStylesCss(styleMap, themeFonts)}
66948
67352
  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
67353
  const hasShadow = computed2.boxShadow && computed2.boxShadow !== "none";
66950
67354
  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
67355
  const rect2 = htmlEl.getBoundingClientRect();
66967
67356
  if (rect2.width > 0 && rect2.height > 0) {
66968
- const text2 = getTransformedText(htmlEl, computed2);
67357
+ const styledTextDisplay = computed2.display;
67358
+ const styledTextFlexDir = computed2.flexDirection || "row";
67359
+ const styledTextChildCount = el.children.length;
67360
+ const isStyledTextFlexRow = (styledTextDisplay === "flex" || styledTextDisplay === "inline-flex") && (styledTextFlexDir === "row" || styledTextFlexDir === "row-reverse") && styledTextChildCount > 1;
67361
+ const isStyledTextFlexCol = (styledTextDisplay === "flex" || styledTextDisplay === "inline-flex") && (styledTextFlexDir === "column" || styledTextFlexDir === "column-reverse") && styledTextChildCount > 1;
67362
+ const isStyledTextGrid = styledTextDisplay === "grid" || styledTextDisplay === "inline-grid";
67363
+ const shouldMergeStyledText = !isStyledTextFlexRow && !isStyledTextFlexCol && !isStyledTextGrid;
67364
+ const text2 = shouldMergeStyledText ? getTransformedText(htmlEl, computed2) : "";
66969
67365
  const bgGradient = parseCssGradient(computed2.backgroundImage);
66970
67366
  const borderRadius = computed2.borderRadius;
66971
67367
  const radiusValue = parseFloat(borderRadius);
66972
67368
  let rectRadius = 0;
66973
67369
  const isCircularRadius = borderRadius.includes("%") ? radiusValue >= 50 : radiusValue > 0 && radiusValue >= Math.min(rect2.width, rect2.height) / 2 - 1;
66974
67370
  const aspectRatio = rect2.width / rect2.height;
66975
- const spanIsEllipse = isCircularRadius && aspectRatio > 0.5 && aspectRatio < 2;
66976
- if (radiusValue > 0 && !spanIsEllipse) {
67371
+ const styledTextIsEllipse = isCircularRadius && aspectRatio > 0.5 && aspectRatio < 2;
67372
+ if (radiusValue > 0 && !styledTextIsEllipse) {
66977
67373
  if (borderRadius.includes("%")) {
66978
67374
  const minDim = Math.min(rect2.width, rect2.height);
66979
67375
  rectRadius = radiusValue / 100 * pxToInch(minDim);
@@ -66985,12 +67381,19 @@ ${generateStylesCss(styleMap, themeFonts)}
66985
67381
  const borderRight = computed2.borderRightWidth;
66986
67382
  const borderBottom = computed2.borderBottomWidth;
66987
67383
  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;
67384
+ const borders = [parseFloat(borderTop) || 0, parseFloat(borderRight) || 0, parseFloat(borderBottom) || 0, parseFloat(borderLeft) || 0];
67385
+ const hasUniformBorder = hasBorder && borders.every((b) => b === borders[0]);
67386
+ const styledTextOpacity = getEffectiveOpacity(el, win);
67387
+ const hasStyledTextOpacity = styledTextOpacity < 1;
67388
+ const styledTextShadow = parseBoxShadow(computed2.boxShadow);
67389
+ const computedAlign = computed2.textAlign;
67390
+ let textAlign2 = "left";
67391
+ if (computedAlign === "center")
67392
+ textAlign2 = "center";
67393
+ else if (computedAlign === "right")
67394
+ textAlign2 = "right";
67395
+ else if (computedAlign === "justify")
67396
+ textAlign2 = "justify";
66994
67397
  const shapeElement = {
66995
67398
  type: "shape",
66996
67399
  position: {
@@ -67006,9 +67409,10 @@ ${generateStylesCss(styleMap, themeFonts)}
67006
67409
  fontFace: extractFontFace(computed2.fontFamily),
67007
67410
  color: rgbToHex(computed2.color),
67008
67411
  bold: parseInt(computed2.fontWeight) >= 600,
67009
- align: "center",
67412
+ align: textAlign2,
67010
67413
  valign: "middle",
67011
- wrap: !spanShouldNotWrap
67414
+ wrap: true,
67415
+ ...extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {}
67012
67416
  } : null,
67013
67417
  shape: {
67014
67418
  fill: hasBg ? rgbToHex(computed2.backgroundColor) : null,
@@ -67020,144 +67424,1066 @@ ${generateStylesCss(styleMap, themeFonts)}
67020
67424
  transparency: extractAlpha(computed2.borderColor),
67021
67425
  dashType: extractDashType(computed2.borderStyle)
67022
67426
  } : null,
67023
- rectRadius: spanIsEllipse ? 0 : rectRadius,
67024
- shadow: spanShadow,
67025
- opacity: hasSpanOpacity ? spanOpacity : null,
67026
- isEllipse: spanIsEllipse,
67427
+ rectRadius: styledTextIsEllipse ? 0 : rectRadius,
67428
+ shadow: styledTextShadow,
67429
+ opacity: hasStyledTextOpacity ? styledTextOpacity : null,
67430
+ isEllipse: styledTextIsEllipse,
67027
67431
  softEdge: null,
67028
67432
  rotate: null,
67433
+ cssTriangle: null,
67029
67434
  customGeometry: null
67030
- }
67031
- };
67032
- 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
67435
  },
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
- }
67436
+ zIndex: extractZIndex(computed2)
67080
67437
  };
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);
67438
+ elements.push(shapeElement);
67439
+ if (hasBorder && !hasUniformBorder) {
67440
+ const topRightBottomBorders = [borders[0], borders[1], borders[2]].filter((b) => b > 0);
67441
+ const minTopRightBottom = topRightBottomBorders.length > 0 ? Math.min(...topRightBottomBorders) : 0;
67442
+ const topLeftBottomBorders = [borders[0], borders[3], borders[2]].filter((b) => b > 0);
67443
+ const minTopLeftBottom = topLeftBottomBorders.length > 0 ? Math.min(...topLeftBottomBorders) : 0;
67444
+ const borderLeftW = borders[3];
67445
+ const borderRightW = borders[1];
67446
+ const borderLeftHex = rgbToHex(computed2.borderLeftColor);
67447
+ const borderRightHex = rgbToHex(computed2.borderRightColor);
67448
+ const borderTopHex = rgbToHex(computed2.borderTopColor);
67449
+ const borderLeftAlpha = extractAlpha(computed2.borderLeftColor);
67450
+ const borderTopAlpha = extractAlpha(computed2.borderTopColor);
67451
+ const borderRightAlpha = extractAlpha(computed2.borderRightColor);
67452
+ const borderLeftHasDifferentColor = borderTopHex !== borderLeftHex;
67453
+ const borderLeftIsMoreOpaque = (borderLeftAlpha ?? 0) < (borderTopAlpha ?? 0);
67454
+ if (borderLeftW > 0 && !isFullyTransparent(computed2.borderLeftColor) && (borderLeftW > minTopRightBottom || minTopRightBottom === 0 || borderLeftHasDifferentColor || borderLeftIsMoreOpaque)) {
67131
67455
  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);
67456
+ const w2 = borderLeftW;
67457
+ const h2 = rect2.height;
67458
+ const r = radiusValue;
67459
+ const EMU_PER_PX3 = 914400 / 96;
67460
+ const arcYAtX = (radius, x2) => {
67461
+ if (x2 <= 0)
67462
+ return radius;
67463
+ if (x2 >= radius)
67464
+ return 0;
67465
+ const dx = radius - x2;
67466
+ return radius - Math.sqrt(radius * radius - dx * dx);
67467
+ };
67468
+ const segments = 8;
67469
+ const arcPointsTop = [];
67470
+ const arcPointsBottom = [];
67471
+ for (let i = 0; i <= segments; i++) {
67472
+ const t = i / segments;
67473
+ const x2 = t * w2;
67474
+ const arcDistance = arcYAtX(r, x2);
67475
+ arcPointsTop.push({
67476
+ x: Math.round(x2 * EMU_PER_PX3),
67477
+ y: Math.round(arcDistance * EMU_PER_PX3)
67478
+ });
67479
+ arcPointsBottom.push({
67480
+ x: Math.round(x2 * EMU_PER_PX3),
67481
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
67482
+ });
67139
67483
  }
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;
67484
+ const points = [];
67485
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
67486
+ for (let i = 1; i <= segments; i++) {
67487
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
67488
+ }
67489
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
67490
+ for (let i = segments - 1; i >= 0; i--) {
67491
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
67492
+ }
67493
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
67494
+ const borderLeftShape = {
67495
+ type: "shape",
67496
+ text: "",
67497
+ textRuns: null,
67498
+ style: null,
67499
+ position: {
67500
+ x: pxToInch(rect2.left),
67501
+ y: pxToInch(rect2.top),
67502
+ w: pxToInch(borderLeftW),
67503
+ h: pxToInch(rect2.height)
67504
+ },
67505
+ shape: {
67506
+ fill: rgbToHex(computed2.borderLeftColor),
67507
+ gradient: null,
67508
+ transparency: extractAlpha(computed2.borderLeftColor),
67509
+ line: null,
67510
+ rectRadius: 0,
67511
+ shadow: null,
67512
+ opacity: null,
67513
+ isEllipse: false,
67514
+ softEdge: null,
67515
+ rotate: null,
67516
+ cssTriangle: null,
67517
+ customGeometry: points
67518
+ }
67519
+ };
67520
+ elements.push(borderLeftShape);
67521
+ } else {
67522
+ const borderLeftShape = {
67523
+ type: "shape",
67524
+ text: "",
67525
+ textRuns: null,
67526
+ style: null,
67527
+ position: {
67528
+ x: pxToInch(rect2.left),
67529
+ y: pxToInch(rect2.top),
67530
+ w: pxToInch(borderLeftW),
67531
+ h: pxToInch(rect2.height)
67532
+ },
67533
+ shape: {
67534
+ fill: rgbToHex(computed2.borderLeftColor),
67535
+ gradient: null,
67536
+ transparency: extractAlpha(computed2.borderLeftColor),
67537
+ line: null,
67538
+ rectRadius: 0,
67539
+ shadow: null,
67540
+ opacity: null,
67541
+ isEllipse: false,
67542
+ softEdge: null,
67543
+ rotate: null,
67544
+ cssTriangle: null,
67545
+ customGeometry: null
67546
+ }
67547
+ };
67548
+ elements.push(borderLeftShape);
67549
+ }
67550
+ }
67551
+ const borderRightHasDifferentColor = borderTopHex !== borderRightHex;
67552
+ const borderRightIsMoreOpaque = (borderRightAlpha ?? 0) < (borderTopAlpha ?? 0);
67553
+ if (borderRightW > 0 && !isFullyTransparent(computed2.borderRightColor) && (borderRightW > minTopLeftBottom || minTopLeftBottom === 0 || borderRightHasDifferentColor || borderRightIsMoreOpaque)) {
67554
+ if (radiusValue > 0) {
67555
+ const w2 = borderRightW;
67556
+ const h2 = rect2.height;
67557
+ const r = radiusValue;
67558
+ const EMU_PER_PX3 = 914400 / 96;
67559
+ const arcYAtX = (radius, x2) => {
67560
+ if (x2 <= 0)
67561
+ return radius;
67562
+ if (x2 >= radius)
67563
+ return 0;
67564
+ const dx = radius - x2;
67565
+ return radius - Math.sqrt(radius * radius - dx * dx);
67566
+ };
67567
+ const segments = 8;
67568
+ const arcPointsTop = [];
67569
+ const arcPointsBottom = [];
67570
+ for (let i = 0; i <= segments; i++) {
67571
+ const t = i / segments;
67572
+ const x2 = t * w2;
67573
+ const arcDistance = arcYAtX(r, w2 - x2);
67574
+ arcPointsTop.push({
67575
+ x: Math.round(x2 * EMU_PER_PX3),
67576
+ y: Math.round(arcDistance * EMU_PER_PX3)
67577
+ });
67578
+ arcPointsBottom.push({
67579
+ x: Math.round(x2 * EMU_PER_PX3),
67580
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
67581
+ });
67582
+ }
67583
+ const points = [];
67584
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
67585
+ for (let i = 1; i <= segments; i++) {
67586
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
67587
+ }
67588
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
67589
+ for (let i = segments - 1; i >= 0; i--) {
67590
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
67591
+ }
67592
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
67593
+ const borderRightShape = {
67594
+ type: "shape",
67595
+ text: "",
67596
+ textRuns: null,
67597
+ style: null,
67598
+ position: {
67599
+ x: pxToInch(rect2.left + rect2.width - borderRightW),
67600
+ y: pxToInch(rect2.top),
67601
+ w: pxToInch(borderRightW),
67602
+ h: pxToInch(rect2.height)
67603
+ },
67604
+ shape: {
67605
+ fill: rgbToHex(computed2.borderRightColor),
67606
+ gradient: null,
67607
+ transparency: extractAlpha(computed2.borderRightColor),
67608
+ line: null,
67609
+ rectRadius: 0,
67610
+ shadow: null,
67611
+ opacity: null,
67612
+ isEllipse: false,
67613
+ softEdge: null,
67614
+ rotate: null,
67615
+ cssTriangle: null,
67616
+ customGeometry: points
67617
+ }
67618
+ };
67619
+ elements.push(borderRightShape);
67620
+ } else {
67621
+ const borderRightShape = {
67622
+ type: "shape",
67623
+ text: "",
67624
+ textRuns: null,
67625
+ style: null,
67626
+ position: {
67627
+ x: pxToInch(rect2.left + rect2.width - borderRightW),
67628
+ y: pxToInch(rect2.top),
67629
+ w: pxToInch(borderRightW),
67630
+ h: pxToInch(rect2.height)
67631
+ },
67632
+ shape: {
67633
+ fill: rgbToHex(computed2.borderRightColor),
67634
+ gradient: null,
67635
+ transparency: extractAlpha(computed2.borderRightColor),
67636
+ line: null,
67637
+ rectRadius: 0,
67638
+ shadow: null,
67639
+ opacity: null,
67640
+ isEllipse: false,
67641
+ softEdge: null,
67642
+ rotate: null,
67643
+ cssTriangle: null,
67644
+ customGeometry: null
67645
+ }
67646
+ };
67647
+ elements.push(borderRightShape);
67648
+ }
67649
+ }
67650
+ }
67651
+ const leftRightBottomBorders = [borders[3], borders[1], borders[2]].filter((b) => b > 0);
67652
+ const minLeftRightBottom = leftRightBottomBorders.length > 0 ? Math.min(...leftRightBottomBorders) : 0;
67653
+ const leftRightTopBorders = [borders[3], borders[1], borders[0]].filter((b) => b > 0);
67654
+ const minLeftRightTop = leftRightTopBorders.length > 0 ? Math.min(...leftRightTopBorders) : 0;
67655
+ const borderTopW = borders[0];
67656
+ if (borderTopW > 0 && !isFullyTransparent(computed2.borderTopColor) && (borderTopW > minLeftRightBottom || minLeftRightBottom === 0)) {
67657
+ if (radiusValue > 0) {
67658
+ const w2 = rect2.width;
67659
+ const h2 = borderTopW;
67660
+ const r = radiusValue;
67661
+ const EMU_PER_PX3 = 914400 / 96;
67662
+ const arcXAtY = (radius, y2) => {
67663
+ if (y2 <= 0)
67664
+ return radius;
67665
+ if (y2 >= radius)
67666
+ return 0;
67667
+ const dy = radius - y2;
67668
+ return radius - Math.sqrt(radius * radius - dy * dy);
67669
+ };
67670
+ const segments = 8;
67671
+ const arcPointsLeft = [];
67672
+ const arcPointsRight = [];
67673
+ for (let i = 0; i <= segments; i++) {
67674
+ const t = i / segments;
67675
+ const y2 = t * h2;
67676
+ const arcDistance = arcXAtY(r, y2);
67677
+ arcPointsLeft.push({
67678
+ x: Math.round(arcDistance * EMU_PER_PX3),
67679
+ y: Math.round(y2 * EMU_PER_PX3)
67680
+ });
67681
+ arcPointsRight.push({
67682
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
67683
+ y: Math.round(y2 * EMU_PER_PX3)
67684
+ });
67685
+ }
67686
+ const points = [];
67687
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
67688
+ for (let i = 1; i <= segments; i++) {
67689
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
67690
+ }
67691
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
67692
+ for (let i = segments - 1; i >= 0; i--) {
67693
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
67694
+ }
67695
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
67696
+ const borderTopShape = {
67697
+ type: "shape",
67698
+ text: "",
67699
+ textRuns: null,
67700
+ style: null,
67701
+ position: {
67702
+ x: pxToInch(rect2.left),
67703
+ y: pxToInch(rect2.top),
67704
+ w: pxToInch(rect2.width),
67705
+ h: pxToInch(borderTopW)
67706
+ },
67707
+ shape: {
67708
+ fill: rgbToHex(computed2.borderTopColor),
67709
+ gradient: null,
67710
+ transparency: extractAlpha(computed2.borderTopColor),
67711
+ line: null,
67712
+ rectRadius: 0,
67713
+ shadow: null,
67714
+ opacity: null,
67715
+ isEllipse: false,
67716
+ softEdge: null,
67717
+ rotate: null,
67718
+ cssTriangle: null,
67719
+ customGeometry: points
67720
+ }
67721
+ };
67722
+ elements.push(borderTopShape);
67723
+ } else {
67724
+ const borderTopShape = {
67725
+ type: "shape",
67726
+ text: "",
67727
+ textRuns: null,
67728
+ style: null,
67729
+ position: {
67730
+ x: pxToInch(rect2.left),
67731
+ y: pxToInch(rect2.top),
67732
+ w: pxToInch(rect2.width),
67733
+ h: pxToInch(borderTopW)
67734
+ },
67735
+ shape: {
67736
+ fill: rgbToHex(computed2.borderTopColor),
67737
+ gradient: null,
67738
+ transparency: extractAlpha(computed2.borderTopColor),
67739
+ line: null,
67740
+ rectRadius: 0,
67741
+ shadow: null,
67742
+ opacity: null,
67743
+ isEllipse: false,
67744
+ softEdge: null,
67745
+ rotate: null,
67746
+ cssTriangle: null,
67747
+ customGeometry: null
67748
+ }
67749
+ };
67750
+ elements.push(borderTopShape);
67751
+ }
67752
+ }
67753
+ const borderBottomW = borders[2];
67754
+ if (borderBottomW > 0 && !isFullyTransparent(computed2.borderBottomColor) && (borderBottomW > minLeftRightTop || minLeftRightTop === 0)) {
67755
+ if (radiusValue > 0) {
67756
+ const w2 = rect2.width;
67757
+ const h2 = borderBottomW;
67758
+ const r = radiusValue;
67759
+ const EMU_PER_PX3 = 914400 / 96;
67760
+ const arcXAtY = (radius, y2) => {
67761
+ if (y2 <= 0)
67762
+ return radius;
67763
+ if (y2 >= radius)
67764
+ return 0;
67765
+ const dy = radius - y2;
67766
+ return radius - Math.sqrt(radius * radius - dy * dy);
67767
+ };
67768
+ const segments = 8;
67769
+ const arcPointsLeft = [];
67770
+ const arcPointsRight = [];
67771
+ for (let i = 0; i <= segments; i++) {
67772
+ const t = i / segments;
67773
+ const y2 = t * h2;
67774
+ const arcDistance = arcXAtY(r, h2 - y2);
67775
+ arcPointsLeft.push({
67776
+ x: Math.round(arcDistance * EMU_PER_PX3),
67777
+ y: Math.round(y2 * EMU_PER_PX3)
67778
+ });
67779
+ arcPointsRight.push({
67780
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
67781
+ y: Math.round(y2 * EMU_PER_PX3)
67782
+ });
67783
+ }
67784
+ const points = [];
67785
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
67786
+ for (let i = 1; i <= segments; i++) {
67787
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
67788
+ }
67789
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
67790
+ for (let i = segments - 1; i >= 0; i--) {
67791
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
67792
+ }
67793
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
67794
+ const borderBottomShape = {
67795
+ type: "shape",
67796
+ text: "",
67797
+ textRuns: null,
67798
+ style: null,
67799
+ position: {
67800
+ x: pxToInch(rect2.left),
67801
+ y: pxToInch(rect2.top + rect2.height - borderBottomW),
67802
+ w: pxToInch(rect2.width),
67803
+ h: pxToInch(borderBottomW)
67804
+ },
67805
+ shape: {
67806
+ fill: rgbToHex(computed2.borderBottomColor),
67807
+ gradient: null,
67808
+ transparency: extractAlpha(computed2.borderBottomColor),
67809
+ line: null,
67810
+ rectRadius: 0,
67811
+ shadow: null,
67812
+ opacity: null,
67813
+ isEllipse: false,
67814
+ softEdge: null,
67815
+ rotate: null,
67816
+ cssTriangle: null,
67817
+ customGeometry: points
67818
+ }
67819
+ };
67820
+ elements.push(borderBottomShape);
67821
+ } else {
67822
+ const borderBottomShape = {
67823
+ type: "shape",
67824
+ text: "",
67825
+ textRuns: null,
67826
+ style: null,
67827
+ position: {
67828
+ x: pxToInch(rect2.left),
67829
+ y: pxToInch(rect2.top + rect2.height - borderBottomW),
67830
+ w: pxToInch(rect2.width),
67831
+ h: pxToInch(borderBottomW)
67832
+ },
67833
+ shape: {
67834
+ fill: rgbToHex(computed2.borderBottomColor),
67835
+ gradient: null,
67836
+ transparency: extractAlpha(computed2.borderBottomColor),
67837
+ line: null,
67838
+ rectRadius: 0,
67839
+ shadow: null,
67840
+ opacity: null,
67841
+ isEllipse: false,
67842
+ softEdge: null,
67843
+ rotate: null,
67844
+ cssTriangle: null,
67845
+ customGeometry: null
67846
+ }
67847
+ };
67848
+ elements.push(borderBottomShape);
67849
+ }
67850
+ }
67851
+ }
67852
+ processed.add(el);
67853
+ return;
67854
+ }
67855
+ }
67856
+ if (el.tagName === "SPAN" || el.tagName === "A" || el.tagName === "CODE") {
67857
+ const spanText = el.textContent?.trim() || "";
67858
+ const isEmptyDecorative = spanText.length === 0;
67859
+ const parentTag = el.parentElement?.tagName;
67860
+ const textParentTags = /* @__PURE__ */ new Set(["P", "H1", "H2", "H3", "H4", "H5", "H6", "LI", "TD", "TH", "FIGCAPTION", "BLOCKQUOTE", "LABEL"]);
67861
+ if (parentTag && textParentTags.has(parentTag) && !isEmptyDecorative) {
67862
+ processed.add(el);
67863
+ return;
67864
+ }
67865
+ const computed2 = win.getComputedStyle(el);
67866
+ const hasBg = computed2.backgroundColor && computed2.backgroundColor !== "rgba(0, 0, 0, 0)";
67867
+ 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;
67868
+ const spanBgImage = computed2.backgroundImage;
67869
+ const hasGradientBg = spanBgImage && spanBgImage !== "none" && (spanBgImage.includes("linear-gradient") || spanBgImage.includes("radial-gradient"));
67870
+ const spanBgClip = computed2.webkitBackgroundClip || computed2.backgroundClip;
67871
+ const spanTextFillColor = computed2.webkitTextFillColor;
67872
+ const isGradientTextFill = hasGradientBg && spanBgClip === "text" && (spanTextFillColor === "transparent" || spanTextFillColor === "rgba(0, 0, 0, 0)" || spanTextFillColor && spanTextFillColor.includes("rgba") && spanTextFillColor.endsWith(", 0)"));
67873
+ if (isGradientTextFill) {
67874
+ } else if (hasBg || hasBorder || hasGradientBg) {
67875
+ const rect2 = htmlEl.getBoundingClientRect();
67876
+ if (rect2.width > 0 && rect2.height > 0) {
67877
+ const text2 = getTransformedText(htmlEl, computed2);
67878
+ const bgGradient = parseCssGradient(computed2.backgroundImage);
67879
+ const borderRadius = computed2.borderRadius;
67880
+ const radiusValue = parseFloat(borderRadius);
67881
+ let rectRadius = 0;
67882
+ const isCircularRadius = borderRadius.includes("%") ? radiusValue >= 50 : radiusValue > 0 && radiusValue >= Math.min(rect2.width, rect2.height) / 2 - 1;
67883
+ const aspectRatio = rect2.width / rect2.height;
67884
+ const spanIsEllipse = isCircularRadius && aspectRatio > 0.5 && aspectRatio < 2;
67885
+ if (radiusValue > 0 && !spanIsEllipse) {
67886
+ if (borderRadius.includes("%")) {
67887
+ const minDim = Math.min(rect2.width, rect2.height);
67888
+ rectRadius = radiusValue / 100 * pxToInch(minDim);
67889
+ } else {
67890
+ rectRadius = pxToInch(radiusValue);
67891
+ }
67892
+ }
67893
+ const borderTop = computed2.borderTopWidth;
67894
+ const borderRight = computed2.borderRightWidth;
67895
+ const borderBottom = computed2.borderBottomWidth;
67896
+ const borderLeft = computed2.borderLeftWidth;
67897
+ const borders = [parseFloat(borderTop) || 0, parseFloat(borderRight) || 0, parseFloat(borderBottom) || 0, parseFloat(borderLeft) || 0];
67898
+ const hasUniformBorder = hasBorder && borders.every((b) => b === borders[0]);
67899
+ const spanOpacity = getEffectiveOpacity(el, win);
67900
+ const hasSpanOpacity = spanOpacity < 1;
67901
+ const spanShadow = parseBoxShadow(computed2.boxShadow);
67902
+ const spanWhiteSpace = computed2.whiteSpace;
67903
+ const spanShouldNotWrap = spanWhiteSpace === "nowrap" || spanWhiteSpace === "pre" || rect2.width < 100 || rect2.height < 50;
67904
+ const shapeElement = {
67905
+ type: "shape",
67906
+ position: {
67907
+ x: pxToInch(rect2.left),
67908
+ y: pxToInch(rect2.top),
67909
+ w: pxToInch(rect2.width),
67910
+ h: pxToInch(rect2.height)
67911
+ },
67912
+ text: text2,
67913
+ textRuns: null,
67914
+ style: text2 ? {
67915
+ fontSize: pxToPoints(computed2.fontSize),
67916
+ fontFace: extractFontFace(computed2.fontFamily),
67917
+ color: rgbToHex(computed2.color),
67918
+ bold: parseInt(computed2.fontWeight) >= 600,
67919
+ align: "center",
67920
+ valign: "middle",
67921
+ wrap: !spanShouldNotWrap,
67922
+ ...extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {}
67923
+ } : null,
67924
+ shape: {
67925
+ fill: hasBg ? rgbToHex(computed2.backgroundColor) : null,
67926
+ gradient: bgGradient,
67927
+ transparency: hasBg ? extractAlpha(computed2.backgroundColor) : null,
67928
+ line: hasUniformBorder ? {
67929
+ color: rgbToHex(computed2.borderColor),
67930
+ width: pxToPoints(borderTop),
67931
+ transparency: extractAlpha(computed2.borderColor),
67932
+ dashType: extractDashType(computed2.borderStyle)
67933
+ } : null,
67934
+ rectRadius: spanIsEllipse ? 0 : rectRadius,
67935
+ shadow: spanShadow,
67936
+ opacity: hasSpanOpacity ? spanOpacity : null,
67937
+ isEllipse: spanIsEllipse,
67938
+ softEdge: null,
67939
+ rotate: null,
67940
+ cssTriangle: null,
67941
+ customGeometry: null
67942
+ },
67943
+ zIndex: extractZIndex(computed2)
67944
+ };
67945
+ elements.push(shapeElement);
67946
+ if (hasBorder && !hasUniformBorder) {
67947
+ const topRightBottomBorders = [borders[0], borders[1], borders[2]].filter((b) => b > 0);
67948
+ const minTopRightBottom = topRightBottomBorders.length > 0 ? Math.min(...topRightBottomBorders) : 0;
67949
+ const topLeftBottomBorders = [borders[0], borders[3], borders[2]].filter((b) => b > 0);
67950
+ const minTopLeftBottom = topLeftBottomBorders.length > 0 ? Math.min(...topLeftBottomBorders) : 0;
67951
+ const borderLeftW = borders[3];
67952
+ const borderRightW = borders[1];
67953
+ const borderLeftHex = rgbToHex(computed2.borderLeftColor);
67954
+ const borderRightHex = rgbToHex(computed2.borderRightColor);
67955
+ const borderTopHex = rgbToHex(computed2.borderTopColor);
67956
+ const borderLeftAlpha = extractAlpha(computed2.borderLeftColor);
67957
+ const borderTopAlpha = extractAlpha(computed2.borderTopColor);
67958
+ const borderRightAlpha = extractAlpha(computed2.borderRightColor);
67959
+ const borderLeftHasDifferentColor = borderTopHex !== borderLeftHex;
67960
+ const borderLeftIsMoreOpaque = (borderLeftAlpha ?? 0) < (borderTopAlpha ?? 0);
67961
+ if (borderLeftW > 0 && !isFullyTransparent(computed2.borderLeftColor) && (borderLeftW > minTopRightBottom || minTopRightBottom === 0 || borderLeftHasDifferentColor || borderLeftIsMoreOpaque)) {
67962
+ if (radiusValue > 0) {
67963
+ const w2 = borderLeftW;
67964
+ const h2 = rect2.height;
67965
+ const r = radiusValue;
67966
+ const EMU_PER_PX3 = 914400 / 96;
67967
+ const arcYAtX = (radius, x2) => {
67968
+ if (x2 <= 0)
67969
+ return radius;
67970
+ if (x2 >= radius)
67971
+ return 0;
67972
+ const dx = radius - x2;
67973
+ return radius - Math.sqrt(radius * radius - dx * dx);
67974
+ };
67975
+ const segments = 8;
67976
+ const arcPointsTop = [];
67977
+ const arcPointsBottom = [];
67978
+ for (let i = 0; i <= segments; i++) {
67979
+ const t = i / segments;
67980
+ const x2 = t * w2;
67981
+ const arcDistance = arcYAtX(r, x2);
67982
+ arcPointsTop.push({
67983
+ x: Math.round(x2 * EMU_PER_PX3),
67984
+ y: Math.round(arcDistance * EMU_PER_PX3)
67985
+ });
67986
+ arcPointsBottom.push({
67987
+ x: Math.round(x2 * EMU_PER_PX3),
67988
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
67989
+ });
67990
+ }
67991
+ const points = [];
67992
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
67993
+ for (let i = 1; i <= segments; i++) {
67994
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
67995
+ }
67996
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
67997
+ for (let i = segments - 1; i >= 0; i--) {
67998
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
67999
+ }
68000
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
68001
+ const borderLeftShape = {
68002
+ type: "shape",
68003
+ text: "",
68004
+ textRuns: null,
68005
+ style: null,
68006
+ position: {
68007
+ x: pxToInch(rect2.left),
68008
+ y: pxToInch(rect2.top),
68009
+ w: pxToInch(borderLeftW),
68010
+ h: pxToInch(rect2.height)
68011
+ },
68012
+ shape: {
68013
+ fill: rgbToHex(computed2.borderLeftColor),
68014
+ gradient: null,
68015
+ transparency: extractAlpha(computed2.borderLeftColor),
68016
+ line: null,
68017
+ rectRadius: 0,
68018
+ shadow: null,
68019
+ opacity: null,
68020
+ isEllipse: false,
68021
+ softEdge: null,
68022
+ rotate: null,
68023
+ cssTriangle: null,
68024
+ customGeometry: points
68025
+ }
68026
+ };
68027
+ elements.push(borderLeftShape);
68028
+ } else {
68029
+ const borderLeftShape = {
68030
+ type: "shape",
68031
+ text: "",
68032
+ textRuns: null,
68033
+ style: null,
68034
+ position: {
68035
+ x: pxToInch(rect2.left),
68036
+ y: pxToInch(rect2.top),
68037
+ w: pxToInch(borderLeftW),
68038
+ h: pxToInch(rect2.height)
68039
+ },
68040
+ shape: {
68041
+ fill: rgbToHex(computed2.borderLeftColor),
68042
+ gradient: null,
68043
+ transparency: extractAlpha(computed2.borderLeftColor),
68044
+ line: null,
68045
+ rectRadius: 0,
68046
+ shadow: null,
68047
+ opacity: null,
68048
+ isEllipse: false,
68049
+ softEdge: null,
68050
+ rotate: null,
68051
+ cssTriangle: null,
68052
+ customGeometry: null
68053
+ }
68054
+ };
68055
+ elements.push(borderLeftShape);
68056
+ }
68057
+ }
68058
+ const borderRightHasDifferentColor = borderTopHex !== borderRightHex;
68059
+ const borderRightIsMoreOpaque = (borderRightAlpha ?? 0) < (borderTopAlpha ?? 0);
68060
+ if (borderRightW > 0 && !isFullyTransparent(computed2.borderRightColor) && (borderRightW > minTopLeftBottom || minTopLeftBottom === 0 || borderRightHasDifferentColor || borderRightIsMoreOpaque)) {
68061
+ if (radiusValue > 0) {
68062
+ const w2 = borderRightW;
68063
+ const h2 = rect2.height;
68064
+ const r = radiusValue;
68065
+ const EMU_PER_PX3 = 914400 / 96;
68066
+ const arcYAtX = (radius, x2) => {
68067
+ if (x2 <= 0)
68068
+ return radius;
68069
+ if (x2 >= radius)
68070
+ return 0;
68071
+ const dx = radius - x2;
68072
+ return radius - Math.sqrt(radius * radius - dx * dx);
68073
+ };
68074
+ const segments = 8;
68075
+ const arcPointsTop = [];
68076
+ const arcPointsBottom = [];
68077
+ for (let i = 0; i <= segments; i++) {
68078
+ const t = i / segments;
68079
+ const x2 = t * w2;
68080
+ const arcDistance = arcYAtX(r, w2 - x2);
68081
+ arcPointsTop.push({
68082
+ x: Math.round(x2 * EMU_PER_PX3),
68083
+ y: Math.round(arcDistance * EMU_PER_PX3)
68084
+ });
68085
+ arcPointsBottom.push({
68086
+ x: Math.round(x2 * EMU_PER_PX3),
68087
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
68088
+ });
68089
+ }
68090
+ const points = [];
68091
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
68092
+ for (let i = 1; i <= segments; i++) {
68093
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
68094
+ }
68095
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
68096
+ for (let i = segments - 1; i >= 0; i--) {
68097
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
68098
+ }
68099
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
68100
+ const borderRightShape = {
68101
+ type: "shape",
68102
+ text: "",
68103
+ textRuns: null,
68104
+ style: null,
68105
+ position: {
68106
+ x: pxToInch(rect2.left + rect2.width - borderRightW),
68107
+ y: pxToInch(rect2.top),
68108
+ w: pxToInch(borderRightW),
68109
+ h: pxToInch(rect2.height)
68110
+ },
68111
+ shape: {
68112
+ fill: rgbToHex(computed2.borderRightColor),
68113
+ gradient: null,
68114
+ transparency: extractAlpha(computed2.borderRightColor),
68115
+ line: null,
68116
+ rectRadius: 0,
68117
+ shadow: null,
68118
+ opacity: null,
68119
+ isEllipse: false,
68120
+ softEdge: null,
68121
+ rotate: null,
68122
+ cssTriangle: null,
68123
+ customGeometry: points
68124
+ }
68125
+ };
68126
+ elements.push(borderRightShape);
68127
+ } else {
68128
+ const borderRightShape = {
68129
+ type: "shape",
68130
+ text: "",
68131
+ textRuns: null,
68132
+ style: null,
68133
+ position: {
68134
+ x: pxToInch(rect2.left + rect2.width - borderRightW),
68135
+ y: pxToInch(rect2.top),
68136
+ w: pxToInch(borderRightW),
68137
+ h: pxToInch(rect2.height)
68138
+ },
68139
+ shape: {
68140
+ fill: rgbToHex(computed2.borderRightColor),
68141
+ gradient: null,
68142
+ transparency: extractAlpha(computed2.borderRightColor),
68143
+ line: null,
68144
+ rectRadius: 0,
68145
+ shadow: null,
68146
+ opacity: null,
68147
+ isEllipse: false,
68148
+ softEdge: null,
68149
+ rotate: null,
68150
+ cssTriangle: null,
68151
+ customGeometry: null
68152
+ }
68153
+ };
68154
+ elements.push(borderRightShape);
68155
+ }
68156
+ }
68157
+ }
68158
+ const leftRightBottomBorders = [borders[3], borders[1], borders[2]].filter((b) => b > 0);
68159
+ const minLeftRightBottom = leftRightBottomBorders.length > 0 ? Math.min(...leftRightBottomBorders) : 0;
68160
+ const leftRightTopBorders = [borders[3], borders[1], borders[0]].filter((b) => b > 0);
68161
+ const minLeftRightTop = leftRightTopBorders.length > 0 ? Math.min(...leftRightTopBorders) : 0;
68162
+ const borderTopW = borders[0];
68163
+ if (borderTopW > 0 && !isFullyTransparent(computed2.borderTopColor) && (borderTopW > minLeftRightBottom || minLeftRightBottom === 0)) {
68164
+ if (radiusValue > 0) {
68165
+ const w2 = rect2.width;
68166
+ const h2 = borderTopW;
68167
+ const r = radiusValue;
68168
+ const EMU_PER_PX3 = 914400 / 96;
68169
+ const arcXAtY = (radius, y2) => {
68170
+ if (y2 <= 0)
68171
+ return radius;
68172
+ if (y2 >= radius)
68173
+ return 0;
68174
+ const dy = radius - y2;
68175
+ return radius - Math.sqrt(radius * radius - dy * dy);
68176
+ };
68177
+ const segments = 8;
68178
+ const arcPointsLeft = [];
68179
+ const arcPointsRight = [];
68180
+ for (let i = 0; i <= segments; i++) {
68181
+ const t = i / segments;
68182
+ const y2 = t * h2;
68183
+ const arcDistance = arcXAtY(r, y2);
68184
+ arcPointsLeft.push({
68185
+ x: Math.round(arcDistance * EMU_PER_PX3),
68186
+ y: Math.round(y2 * EMU_PER_PX3)
68187
+ });
68188
+ arcPointsRight.push({
68189
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
68190
+ y: Math.round(y2 * EMU_PER_PX3)
68191
+ });
68192
+ }
68193
+ const points = [];
68194
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
68195
+ for (let i = 1; i <= segments; i++) {
68196
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
68197
+ }
68198
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
68199
+ for (let i = segments - 1; i >= 0; i--) {
68200
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
68201
+ }
68202
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
68203
+ const borderTopShape = {
68204
+ type: "shape",
68205
+ text: "",
68206
+ textRuns: null,
68207
+ style: null,
68208
+ position: {
68209
+ x: pxToInch(rect2.left),
68210
+ y: pxToInch(rect2.top),
68211
+ w: pxToInch(rect2.width),
68212
+ h: pxToInch(borderTopW)
68213
+ },
68214
+ shape: {
68215
+ fill: rgbToHex(computed2.borderTopColor),
68216
+ gradient: null,
68217
+ transparency: extractAlpha(computed2.borderTopColor),
68218
+ line: null,
68219
+ rectRadius: 0,
68220
+ shadow: null,
68221
+ opacity: null,
68222
+ isEllipse: false,
68223
+ softEdge: null,
68224
+ rotate: null,
68225
+ cssTriangle: null,
68226
+ customGeometry: points
68227
+ }
68228
+ };
68229
+ elements.push(borderTopShape);
68230
+ } else {
68231
+ const borderTopShape = {
68232
+ type: "shape",
68233
+ text: "",
68234
+ textRuns: null,
68235
+ style: null,
68236
+ position: {
68237
+ x: pxToInch(rect2.left),
68238
+ y: pxToInch(rect2.top),
68239
+ w: pxToInch(rect2.width),
68240
+ h: pxToInch(borderTopW)
68241
+ },
68242
+ shape: {
68243
+ fill: rgbToHex(computed2.borderTopColor),
68244
+ gradient: null,
68245
+ transparency: extractAlpha(computed2.borderTopColor),
68246
+ line: null,
68247
+ rectRadius: 0,
68248
+ shadow: null,
68249
+ opacity: null,
68250
+ isEllipse: false,
68251
+ softEdge: null,
68252
+ rotate: null,
68253
+ cssTriangle: null,
68254
+ customGeometry: null
68255
+ }
68256
+ };
68257
+ elements.push(borderTopShape);
68258
+ }
68259
+ }
68260
+ const borderBottomW = borders[2];
68261
+ if (borderBottomW > 0 && !isFullyTransparent(computed2.borderBottomColor) && (borderBottomW > minLeftRightTop || minLeftRightTop === 0)) {
68262
+ if (radiusValue > 0) {
68263
+ const w2 = rect2.width;
68264
+ const h2 = borderBottomW;
68265
+ const r = radiusValue;
68266
+ const EMU_PER_PX3 = 914400 / 96;
68267
+ const arcXAtY = (radius, y2) => {
68268
+ if (y2 <= 0)
68269
+ return radius;
68270
+ if (y2 >= radius)
68271
+ return 0;
68272
+ const dy = radius - y2;
68273
+ return radius - Math.sqrt(radius * radius - dy * dy);
68274
+ };
68275
+ const segments = 8;
68276
+ const arcPointsLeft = [];
68277
+ const arcPointsRight = [];
68278
+ for (let i = 0; i <= segments; i++) {
68279
+ const t = i / segments;
68280
+ const y2 = t * h2;
68281
+ const arcDistance = arcXAtY(r, h2 - y2);
68282
+ arcPointsLeft.push({
68283
+ x: Math.round(arcDistance * EMU_PER_PX3),
68284
+ y: Math.round(y2 * EMU_PER_PX3)
68285
+ });
68286
+ arcPointsRight.push({
68287
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
68288
+ y: Math.round(y2 * EMU_PER_PX3)
68289
+ });
68290
+ }
68291
+ const points = [];
68292
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
68293
+ for (let i = 1; i <= segments; i++) {
68294
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
68295
+ }
68296
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
68297
+ for (let i = segments - 1; i >= 0; i--) {
68298
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
68299
+ }
68300
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
68301
+ const borderBottomShape = {
68302
+ type: "shape",
68303
+ text: "",
68304
+ textRuns: null,
68305
+ style: null,
68306
+ position: {
68307
+ x: pxToInch(rect2.left),
68308
+ y: pxToInch(rect2.top + rect2.height - borderBottomW),
68309
+ w: pxToInch(rect2.width),
68310
+ h: pxToInch(borderBottomW)
68311
+ },
68312
+ shape: {
68313
+ fill: rgbToHex(computed2.borderBottomColor),
68314
+ gradient: null,
68315
+ transparency: extractAlpha(computed2.borderBottomColor),
68316
+ line: null,
68317
+ rectRadius: 0,
68318
+ shadow: null,
68319
+ opacity: null,
68320
+ isEllipse: false,
68321
+ softEdge: null,
68322
+ rotate: null,
68323
+ cssTriangle: null,
68324
+ customGeometry: points
68325
+ }
68326
+ };
68327
+ elements.push(borderBottomShape);
68328
+ } else {
68329
+ const borderBottomShape = {
68330
+ type: "shape",
68331
+ text: "",
68332
+ textRuns: null,
68333
+ style: null,
68334
+ position: {
68335
+ x: pxToInch(rect2.left),
68336
+ y: pxToInch(rect2.top + rect2.height - borderBottomW),
68337
+ w: pxToInch(rect2.width),
68338
+ h: pxToInch(borderBottomW)
68339
+ },
68340
+ shape: {
68341
+ fill: rgbToHex(computed2.borderBottomColor),
68342
+ gradient: null,
68343
+ transparency: extractAlpha(computed2.borderBottomColor),
68344
+ line: null,
68345
+ rectRadius: 0,
68346
+ shadow: null,
68347
+ opacity: null,
68348
+ isEllipse: false,
68349
+ softEdge: null,
68350
+ rotate: null,
68351
+ cssTriangle: null,
68352
+ customGeometry: null
68353
+ }
68354
+ };
68355
+ elements.push(borderBottomShape);
68356
+ }
68357
+ }
68358
+ }
68359
+ processed.add(el);
68360
+ return;
68361
+ }
68362
+ const parent = el.parentElement;
68363
+ if (parent && parent.tagName === "DIV") {
68364
+ const rect2 = htmlEl.getBoundingClientRect();
68365
+ const computed22 = win.getComputedStyle(el);
68366
+ const text2 = getTransformedText(htmlEl, computed22);
68367
+ if (rect2.width > 0 && rect2.height > 0 && text2) {
68368
+ const fontSizePx2 = parseFloat(computed22.fontSize);
68369
+ const lineHeightPx2 = parseFloat(computed22.lineHeight);
68370
+ const lineHeightMultiplier2 = fontSizePx2 > 0 && !isNaN(lineHeightPx2) ? lineHeightPx2 / fontSizePx2 : 1;
68371
+ const span2BgClip = computed22.webkitBackgroundClip || computed22.backgroundClip;
68372
+ const span2TextFillColor = computed22.webkitTextFillColor;
68373
+ const span2IsGradientText = span2BgClip === "text" && (span2TextFillColor === "transparent" || span2TextFillColor === "rgba(0, 0, 0, 0)" || span2TextFillColor && span2TextFillColor.includes("rgba") && span2TextFillColor.endsWith(", 0)"));
68374
+ const span2BgImage = computed22.backgroundImage;
68375
+ const span2HasGradientBg = span2BgImage && span2BgImage !== "none" && (span2BgImage.includes("linear-gradient") || span2BgImage.includes("radial-gradient"));
68376
+ let spanFontFill = void 0;
68377
+ let spanTextColor = rgbToHex(computed22.color);
68378
+ if (span2IsGradientText && span2HasGradientBg) {
68379
+ const spanGradient = parseCssGradient(span2BgImage);
68380
+ if (spanGradient) {
68381
+ spanFontFill = { type: "gradient", gradient: spanGradient };
68382
+ spanTextColor = null;
68383
+ }
68384
+ }
68385
+ const textElement = {
68386
+ type: "p",
68387
+ text: [{ text: text2, options: spanFontFill ? { fontFill: spanFontFill } : {} }],
68388
+ position: {
68389
+ x: pxToInch(rect2.left),
68390
+ y: pxToInch(rect2.top),
68391
+ w: pxToInch(rect2.width),
68392
+ h: pxToInch(rect2.height)
68393
+ },
68394
+ style: {
68395
+ fontSize: pxToPoints(computed22.fontSize),
68396
+ fontFace: extractFontFace(computed22.fontFamily),
68397
+ color: spanTextColor,
68398
+ bold: parseInt(computed22.fontWeight) >= 600,
68399
+ italic: computed22.fontStyle === "italic",
68400
+ align: computed22.textAlign === "center" ? "center" : computed22.textAlign === "right" ? "right" : "left",
68401
+ valign: "middle",
68402
+ lineSpacing: lineHeightMultiplier2 * pxToPoints(computed22.fontSize),
68403
+ fontFill: spanFontFill,
68404
+ ...extractAlpha(computed22.color) !== null ? { transparency: extractAlpha(computed22.color) } : {}
68405
+ }
68406
+ };
68407
+ elements.push(textElement);
68408
+ processed.add(el);
68409
+ return;
68410
+ }
68411
+ }
68412
+ }
68413
+ if (el.className && typeof el.className === "string" && el.className.includes("placeholder")) {
68414
+ const rect2 = htmlEl.getBoundingClientRect();
68415
+ if (rect2.width === 0 || rect2.height === 0) {
68416
+ errors.push(`Placeholder "${el.id || "unnamed"}" has ${rect2.width === 0 ? "width: 0" : "height: 0"}. Check the layout CSS.`);
68417
+ } else {
68418
+ placeholders.push({
68419
+ id: el.id || `placeholder-${placeholders.length}`,
68420
+ x: pxToInch(rect2.left),
68421
+ y: pxToInch(rect2.top),
68422
+ w: pxToInch(rect2.width),
68423
+ h: pxToInch(rect2.height)
68424
+ });
68425
+ }
68426
+ processed.add(el);
68427
+ return;
68428
+ }
68429
+ if (el.tagName === "IMG") {
68430
+ const rect2 = htmlEl.getBoundingClientRect();
68431
+ if (rect2.width > 0 && rect2.height > 0) {
68432
+ const imgComputed = win.getComputedStyle(el);
68433
+ const bodyRect = doc.body.getBoundingClientRect();
68434
+ const coversWidth = rect2.width >= bodyRect.width * 0.95;
68435
+ const coversHeight = rect2.height >= bodyRect.height * 0.95;
68436
+ const nearOrigin = rect2.left <= 10 && rect2.top <= 10;
68437
+ const isFullSlideImage = coversWidth && coversHeight && nearOrigin;
68438
+ const objectFit = imgComputed.objectFit;
68439
+ let imgRectRadius = null;
68440
+ let clipLeft = rect2.left;
68441
+ let clipTop = rect2.top;
68442
+ let clipRight = rect2.right;
68443
+ let clipBottom = rect2.bottom;
68444
+ let ancestor = el.parentElement;
68445
+ while (ancestor && ancestor !== doc.body) {
68446
+ const ancestorComputed = win.getComputedStyle(ancestor);
68447
+ const ancestorOverflow = ancestorComputed.overflow;
68448
+ if (ancestorOverflow === "hidden" || ancestorOverflow === "clip") {
68449
+ const ancestorRect = ancestor.getBoundingClientRect();
68450
+ clipLeft = Math.max(clipLeft, ancestorRect.left);
68451
+ clipTop = Math.max(clipTop, ancestorRect.top);
68452
+ clipRight = Math.min(clipRight, ancestorRect.right);
68453
+ clipBottom = Math.min(clipBottom, ancestorRect.bottom);
68454
+ const ancestorBorderRadius = ancestorComputed.borderRadius;
68455
+ if (ancestorBorderRadius && imgRectRadius === null) {
68456
+ const radiusValue = parseFloat(ancestorBorderRadius);
68457
+ if (radiusValue > 0) {
68458
+ if (ancestorBorderRadius.includes("%")) {
68459
+ const minDim = Math.min(ancestorRect.width, ancestorRect.height);
68460
+ imgRectRadius = radiusValue / 100 * pxToInch(minDim);
68461
+ } else if (ancestorBorderRadius.includes("pt")) {
68462
+ imgRectRadius = radiusValue / 72;
68463
+ } else {
68464
+ imgRectRadius = pxToInch(radiusValue);
68465
+ }
68466
+ }
68467
+ }
68468
+ }
68469
+ ancestor = ancestor.parentElement;
68470
+ }
68471
+ const clippedW = Math.max(0, clipRight - clipLeft);
68472
+ const clippedH = Math.max(0, clipBottom - clipTop);
68473
+ const wasClipped = clippedW < rect2.width - 1 || clippedH < rect2.height - 1;
68474
+ const cssFilter = imgComputed.filter;
68475
+ let imgSrc = el.src;
68476
+ let filterPreBaked = false;
68477
+ if (cssFilter && cssFilter !== "none") {
68478
+ const bakedSrc = applyImageFilter(el, cssFilter);
68479
+ if (bakedSrc !== imgSrc) {
68480
+ imgSrc = bakedSrc;
68481
+ filterPreBaked = true;
68482
+ }
68483
+ }
68484
+ const maskImageProp = imgComputed.maskImage || imgComputed.webkitMaskImage || imgComputed.getPropertyValue("mask-image") || imgComputed.getPropertyValue("-webkit-mask-image");
68485
+ const imgOpacity = getEffectiveOpacity(el, win);
68486
+ const hasOpacity = imgOpacity < 1 && imgOpacity >= 0;
67161
68487
  let maskApplied = false;
67162
68488
  if (maskImageProp && maskImageProp !== "none" && (maskImageProp.includes("linear-gradient") || maskImageProp.includes("radial-gradient"))) {
67163
68489
  const maskGradient = parseCssGradient(maskImageProp);
@@ -67270,8 +68596,11 @@ ${generateStylesCss(styleMap, themeFonts)}
67270
68596
  if (!svgClone.hasAttribute("xmlns")) {
67271
68597
  svgClone.setAttribute("xmlns", "http://www.w3.org/2000/svg");
67272
68598
  }
67273
- svgClone.setAttribute("width", String(rect2.width));
67274
- svgClone.setAttribute("height", String(rect2.height));
68599
+ const MIN_SVG_RENDER_SIZE = 128;
68600
+ const svgRenderWidth = Math.max(rect2.width, MIN_SVG_RENDER_SIZE);
68601
+ const svgRenderHeight = Math.max(rect2.height, MIN_SVG_RENDER_SIZE);
68602
+ svgClone.setAttribute("width", String(svgRenderWidth));
68603
+ svgClone.setAttribute("height", String(svgRenderHeight));
67275
68604
  const computedColor = win.getComputedStyle(htmlEl).color;
67276
68605
  const rootStyles = win.getComputedStyle(doc.documentElement);
67277
68606
  const resolveColorValue = (value) => {
@@ -67337,10 +68666,12 @@ ${generateStylesCss(styleMap, themeFonts)}
67337
68666
  const svgString = serializer.serializeToString(svgClone);
67338
68667
  const svgBase64 = btoa(unescape(encodeURIComponent(svgString)));
67339
68668
  const dataUri = `data:image/svg+xml;base64,${svgBase64}`;
68669
+ const svgX = rect2.left;
67340
68670
  let svgY = rect2.top;
67341
68671
  const computedAlign = win.getComputedStyle(htmlEl);
67342
68672
  const verticalAlign = computedAlign.verticalAlign;
67343
- if (verticalAlign === "middle" && el.parentElement) {
68673
+ const svgDisplay = computedAlign.display;
68674
+ if (verticalAlign === "middle" && svgDisplay !== "block" && el.parentElement) {
67344
68675
  const parentComputed = win.getComputedStyle(el.parentElement);
67345
68676
  const parentIsFlex = parentComputed.display === "flex" || parentComputed.display === "inline-flex";
67346
68677
  if (!parentIsFlex) {
@@ -67351,14 +68682,28 @@ ${generateStylesCss(styleMap, themeFonts)}
67351
68682
  }
67352
68683
  }
67353
68684
  const svgEffectiveOpacity = getEffectiveOpacity(el, win);
68685
+ let displayW = pxToInch(rect2.width);
68686
+ let displayH = pxToInch(rect2.height);
68687
+ let displayX = pxToInch(svgX);
68688
+ let displayY = pxToInch(svgY);
68689
+ const MIN_SVG_DISPLAY_SIZE_IN = 0.145;
68690
+ if (displayW < MIN_SVG_DISPLAY_SIZE_IN && displayH < MIN_SVG_DISPLAY_SIZE_IN) {
68691
+ const originalCenterX = displayX + displayW / 2;
68692
+ const originalCenterY = displayY + displayH / 2;
68693
+ const scaleFactor = Math.max(MIN_SVG_DISPLAY_SIZE_IN / displayW, MIN_SVG_DISPLAY_SIZE_IN / displayH);
68694
+ displayW = displayW * scaleFactor;
68695
+ displayH = displayH * scaleFactor;
68696
+ displayX = originalCenterX - displayW / 2;
68697
+ displayY = originalCenterY - displayH / 2;
68698
+ }
67354
68699
  const imageElement = {
67355
68700
  type: "image",
67356
68701
  src: dataUri,
67357
68702
  position: {
67358
- x: pxToInch(rect2.left),
67359
- y: pxToInch(svgY),
67360
- w: pxToInch(rect2.width),
67361
- h: pxToInch(rect2.height)
68703
+ x: displayX,
68704
+ y: displayY,
68705
+ w: displayW,
68706
+ h: displayH
67362
68707
  },
67363
68708
  sizing: null,
67364
68709
  transparency: svgEffectiveOpacity < 1 ? Math.round((1 - svgEffectiveOpacity) * 100) : void 0
@@ -67436,7 +68781,8 @@ ${generateStylesCss(styleMap, themeFonts)}
67436
68781
  processed.add(el);
67437
68782
  return;
67438
68783
  }
67439
- const isContainer = el.tagName === "DIV" && !textTags.includes(el.tagName);
68784
+ const containerTags = /* @__PURE__ */ new Set(["DIV", "TABLE", "TR", "TD", "TH", "TBODY", "THEAD", "TFOOT", "CENTER"]);
68785
+ const isContainer = containerTags.has(el.tagName) && !textTags.includes(el.tagName);
67440
68786
  if (isContainer) {
67441
68787
  const computed2 = win.getComputedStyle(el);
67442
68788
  const divFilterStr = computed2.filter;
@@ -67494,6 +68840,80 @@ ${generateStylesCss(styleMap, themeFonts)}
67494
68840
  }
67495
68841
  }
67496
68842
  }
68843
+ const contentWidth = htmlEl.clientWidth;
68844
+ const contentHeight = htmlEl.clientHeight;
68845
+ const borderTopW = parseFloat(computed2.borderTopWidth) || 0;
68846
+ const borderRightW = parseFloat(computed2.borderRightWidth) || 0;
68847
+ const borderBottomW = parseFloat(computed2.borderBottomWidth) || 0;
68848
+ const borderLeftW = parseFloat(computed2.borderLeftWidth) || 0;
68849
+ if (contentWidth === 0 && contentHeight === 0 && (borderTopW > 0 || borderBottomW > 0 || borderLeftW > 0 || borderRightW > 0)) {
68850
+ const isTopEffectivelyTransparent = borderTopW === 0 || isFullyTransparent(computed2.borderTopColor);
68851
+ const isBottomEffectivelyTransparent = borderBottomW === 0 || isFullyTransparent(computed2.borderBottomColor);
68852
+ const isLeftEffectivelyTransparent = borderLeftW === 0 || isFullyTransparent(computed2.borderLeftColor);
68853
+ const isRightEffectivelyTransparent = borderRightW === 0 || isFullyTransparent(computed2.borderRightColor);
68854
+ let triangleDirection = null;
68855
+ let triangleColor = "";
68856
+ let triangleTransparency = 0;
68857
+ let triangleWidth = 0;
68858
+ let triangleHeight = 0;
68859
+ if (!isBottomEffectivelyTransparent && isLeftEffectivelyTransparent && isRightEffectivelyTransparent && isTopEffectivelyTransparent) {
68860
+ triangleDirection = "up";
68861
+ triangleColor = rgbToHex(computed2.borderBottomColor);
68862
+ triangleTransparency = extractAlpha(computed2.borderBottomColor) ?? 0;
68863
+ triangleWidth = borderLeftW + borderRightW;
68864
+ triangleHeight = borderBottomW;
68865
+ } else if (!isTopEffectivelyTransparent && isLeftEffectivelyTransparent && isRightEffectivelyTransparent && isBottomEffectivelyTransparent) {
68866
+ triangleDirection = "down";
68867
+ triangleColor = rgbToHex(computed2.borderTopColor);
68868
+ triangleTransparency = extractAlpha(computed2.borderTopColor) ?? 0;
68869
+ triangleWidth = borderLeftW + borderRightW;
68870
+ triangleHeight = borderTopW;
68871
+ } else if (!isRightEffectivelyTransparent && isTopEffectivelyTransparent && isBottomEffectivelyTransparent && isLeftEffectivelyTransparent) {
68872
+ triangleDirection = "left";
68873
+ triangleColor = rgbToHex(computed2.borderRightColor);
68874
+ triangleTransparency = extractAlpha(computed2.borderRightColor) ?? 0;
68875
+ triangleWidth = borderRightW;
68876
+ triangleHeight = borderTopW + borderBottomW;
68877
+ } else if (!isLeftEffectivelyTransparent && isTopEffectivelyTransparent && isBottomEffectivelyTransparent && isRightEffectivelyTransparent) {
68878
+ triangleDirection = "right";
68879
+ triangleColor = rgbToHex(computed2.borderLeftColor);
68880
+ triangleTransparency = extractAlpha(computed2.borderLeftColor) ?? 0;
68881
+ triangleWidth = borderLeftW;
68882
+ triangleHeight = borderTopW + borderBottomW;
68883
+ }
68884
+ if (triangleDirection && triangleWidth > 0 && triangleHeight > 0) {
68885
+ const triRect = htmlEl.getBoundingClientRect();
68886
+ const triX = pxToInch(triRect.left);
68887
+ const triY = pxToInch(triRect.top);
68888
+ const triW = pxToInch(triangleWidth);
68889
+ const triH = pxToInch(triangleHeight);
68890
+ const triRotation = extractRotationAngle(computed2);
68891
+ const triangleShape = {
68892
+ type: "shape",
68893
+ text: "",
68894
+ textRuns: null,
68895
+ style: null,
68896
+ position: { x: triX, y: triY, w: triW, h: triH },
68897
+ shape: {
68898
+ fill: triangleColor,
68899
+ gradient: null,
68900
+ transparency: triangleTransparency > 0 ? triangleTransparency : null,
68901
+ line: null,
68902
+ rectRadius: 0,
68903
+ shadow: null,
68904
+ opacity: null,
68905
+ isEllipse: false,
68906
+ softEdge: null,
68907
+ rotate: triRotation,
68908
+ cssTriangle: { direction: triangleDirection },
68909
+ customGeometry: null
68910
+ }
68911
+ };
68912
+ elements.push(triangleShape);
68913
+ processed.add(el);
68914
+ return;
68915
+ }
68916
+ }
67497
68917
  const hasBg = computed2.backgroundColor && computed2.backgroundColor !== "rgba(0, 0, 0, 0)";
67498
68918
  const clipPathValue = computed2.clipPath || computed2.webkitClipPath || "";
67499
68919
  const clipPathPolygon = parseClipPathPolygon(clipPathValue);
@@ -67528,93 +68948,438 @@ ${generateStylesCss(styleMap, themeFonts)}
67528
68948
  };
67529
68949
  elements.push(imgElement);
67530
68950
  }
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);
68951
+ bgGradient = null;
68952
+ } else if (gradParts.length > 0) {
68953
+ bgGradient = parseCssGradient(gradParts[0]);
68954
+ for (let gi = 1; gi < Math.min(gradParts.length, 4); gi++) {
68955
+ const g = parseCssGradient(gradParts[gi]);
68956
+ if (g)
68957
+ extraDivGradients.push(g);
68958
+ }
68959
+ }
68960
+ } else {
68961
+ const urlMatch = elBgImage.match(/url\(["']?([^"')]+)["']?\)/);
68962
+ if (urlMatch) {
68963
+ bgImageUrl = urlMatch[1];
68964
+ bgImageSize = computed2.backgroundSize || "auto";
68965
+ bgImagePosition = computed2.backgroundPosition || "0% 0%";
68966
+ }
68967
+ }
68968
+ }
68969
+ const borderTop = computed2.borderTopWidth;
68970
+ const borderRight = computed2.borderRightWidth;
68971
+ const borderBottom = computed2.borderBottomWidth;
68972
+ const borderLeft = computed2.borderLeftWidth;
68973
+ const borders = [borderTop, borderRight, borderBottom, borderLeft].map((b) => parseFloat(b) || 0);
68974
+ const hasBorder = borders.some((b) => b > 0);
68975
+ const hasUniformBorder = hasBorder && borders.every((b) => b === borders[0]);
68976
+ const borderShapes = [];
68977
+ const divBorderRadius = parseFloat(computed2.borderRadius) || 0;
68978
+ if (hasBorder && !hasUniformBorder) {
68979
+ const rect2 = htmlEl.getBoundingClientRect();
68980
+ const topRightBottomBorders = [borders[0], borders[1], borders[2]].filter((b) => b > 0);
68981
+ const minTopRightBottom = topRightBottomBorders.length > 0 ? Math.min(...topRightBottomBorders) : 0;
68982
+ const topLeftBottomBorders = [borders[0], borders[3], borders[2]].filter((b) => b > 0);
68983
+ const minTopLeftBottom = topLeftBottomBorders.length > 0 ? Math.min(...topLeftBottomBorders) : 0;
68984
+ const borderLeftHex = rgbToHex(computed2.borderLeftColor);
68985
+ const borderRightHex = rgbToHex(computed2.borderRightColor);
68986
+ const borderTopHex = rgbToHex(computed2.borderTopColor);
68987
+ const borderLeftAlpha = extractAlpha(computed2.borderLeftColor);
68988
+ const borderTopAlpha = extractAlpha(computed2.borderTopColor);
68989
+ const borderRightAlpha = extractAlpha(computed2.borderRightColor);
68990
+ const borderLeftW2 = borders[3];
68991
+ const borderLeftHasDifferentColor = borderTopHex !== borderLeftHex;
68992
+ const borderLeftIsMoreOpaque = (borderLeftAlpha ?? 0) < (borderTopAlpha ?? 0);
68993
+ if (borderLeftW2 > 0 && !isFullyTransparent(computed2.borderLeftColor) && (borderLeftW2 > minTopRightBottom || minTopRightBottom === 0 || borderLeftHasDifferentColor || borderLeftIsMoreOpaque)) {
68994
+ if (divBorderRadius > 0) {
68995
+ const w2 = borderLeftW2;
68996
+ const h2 = rect2.height;
68997
+ const r = divBorderRadius;
68998
+ const EMU_PER_PX3 = 914400 / 96;
68999
+ const arcYAtX = (radius, x2) => {
69000
+ if (x2 <= 0)
69001
+ return radius;
69002
+ if (x2 >= radius)
69003
+ return 0;
69004
+ const dx = radius - x2;
69005
+ return radius - Math.sqrt(radius * radius - dx * dx);
69006
+ };
69007
+ const segments = 8;
69008
+ const arcPointsTop = [];
69009
+ const arcPointsBottom = [];
69010
+ for (let i = 0; i <= segments; i++) {
69011
+ const t = i / segments;
69012
+ const x2 = t * w2;
69013
+ const arcDistance = arcYAtX(r, x2);
69014
+ arcPointsTop.push({
69015
+ x: Math.round(x2 * EMU_PER_PX3),
69016
+ y: Math.round(arcDistance * EMU_PER_PX3)
69017
+ });
69018
+ arcPointsBottom.push({
69019
+ x: Math.round(x2 * EMU_PER_PX3),
69020
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
69021
+ });
69022
+ }
69023
+ const points = [];
69024
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
69025
+ for (let i = 1; i <= segments; i++) {
69026
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
69027
+ }
69028
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
69029
+ for (let i = segments - 1; i >= 0; i--) {
69030
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
69031
+ }
69032
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
69033
+ borderShapes.push({
69034
+ type: "shape",
69035
+ text: "",
69036
+ textRuns: null,
69037
+ style: null,
69038
+ position: {
69039
+ x: pxToInch(rect2.left),
69040
+ y: pxToInch(rect2.top),
69041
+ w: pxToInch(borderLeftW2),
69042
+ h: pxToInch(rect2.height)
69043
+ },
69044
+ shape: {
69045
+ fill: rgbToHex(computed2.borderLeftColor),
69046
+ gradient: null,
69047
+ transparency: extractAlpha(computed2.borderLeftColor),
69048
+ line: null,
69049
+ rectRadius: 0,
69050
+ // Using custom geometry instead
69051
+ shadow: null,
69052
+ opacity: null,
69053
+ isEllipse: false,
69054
+ softEdge: null,
69055
+ rotate: null,
69056
+ cssTriangle: null,
69057
+ customGeometry: points
69058
+ }
69059
+ });
69060
+ } else {
69061
+ borderShapes.push({
69062
+ type: "shape",
69063
+ text: "",
69064
+ textRuns: null,
69065
+ style: null,
69066
+ position: {
69067
+ x: pxToInch(rect2.left),
69068
+ y: pxToInch(rect2.top),
69069
+ w: pxToInch(borderLeftW2),
69070
+ h: pxToInch(rect2.height)
69071
+ },
69072
+ shape: {
69073
+ fill: rgbToHex(computed2.borderLeftColor),
69074
+ gradient: null,
69075
+ transparency: extractAlpha(computed2.borderLeftColor),
69076
+ line: null,
69077
+ rectRadius: 0,
69078
+ shadow: null,
69079
+ opacity: null,
69080
+ isEllipse: false,
69081
+ softEdge: null,
69082
+ rotate: null,
69083
+ cssTriangle: null,
69084
+ customGeometry: null
69085
+ }
69086
+ });
69087
+ }
69088
+ }
69089
+ const borderRightW2 = borders[1];
69090
+ const borderRightHasDifferentColor = borderTopHex !== borderRightHex;
69091
+ const borderRightIsMoreOpaque = (borderRightAlpha ?? 0) < (borderTopAlpha ?? 0);
69092
+ if (borderRightW2 > 0 && !isFullyTransparent(computed2.borderRightColor) && (borderRightW2 > minTopLeftBottom || minTopLeftBottom === 0 || borderRightHasDifferentColor || borderRightIsMoreOpaque)) {
69093
+ if (divBorderRadius > 0) {
69094
+ const w2 = borderRightW2;
69095
+ const h2 = rect2.height;
69096
+ const r = divBorderRadius;
69097
+ const EMU_PER_PX3 = 914400 / 96;
69098
+ const arcYAtX = (radius, x2) => {
69099
+ if (x2 <= 0)
69100
+ return radius;
69101
+ if (x2 >= radius)
69102
+ return 0;
69103
+ const dx = radius - x2;
69104
+ return radius - Math.sqrt(radius * radius - dx * dx);
69105
+ };
69106
+ const segments = 8;
69107
+ const arcPointsTop = [];
69108
+ const arcPointsBottom = [];
69109
+ for (let i = 0; i <= segments; i++) {
69110
+ const t = i / segments;
69111
+ const x2 = t * w2;
69112
+ const arcDistance = arcYAtX(r, w2 - x2);
69113
+ arcPointsTop.push({
69114
+ x: Math.round(x2 * EMU_PER_PX3),
69115
+ y: Math.round(arcDistance * EMU_PER_PX3)
69116
+ });
69117
+ arcPointsBottom.push({
69118
+ x: Math.round(x2 * EMU_PER_PX3),
69119
+ y: Math.round((h2 - arcDistance) * EMU_PER_PX3)
69120
+ });
69121
+ }
69122
+ const points = [];
69123
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, moveTo: true });
69124
+ for (let i = 1; i <= segments; i++) {
69125
+ points.push({ x: arcPointsTop[i].x, y: arcPointsTop[i].y });
69126
+ }
69127
+ points.push({ x: arcPointsBottom[segments].x, y: arcPointsBottom[segments].y });
69128
+ for (let i = segments - 1; i >= 0; i--) {
69129
+ points.push({ x: arcPointsBottom[i].x, y: arcPointsBottom[i].y });
69130
+ }
69131
+ points.push({ x: arcPointsTop[0].x, y: arcPointsTop[0].y, close: true });
69132
+ borderShapes.push({
69133
+ type: "shape",
69134
+ text: "",
69135
+ textRuns: null,
69136
+ style: null,
69137
+ position: {
69138
+ x: pxToInch(rect2.left + rect2.width - borderRightW2),
69139
+ y: pxToInch(rect2.top),
69140
+ w: pxToInch(borderRightW2),
69141
+ h: pxToInch(rect2.height)
69142
+ },
69143
+ shape: {
69144
+ fill: rgbToHex(computed2.borderRightColor),
69145
+ gradient: null,
69146
+ transparency: extractAlpha(computed2.borderRightColor),
69147
+ line: null,
69148
+ rectRadius: 0,
69149
+ // Using custom geometry instead
69150
+ shadow: null,
69151
+ opacity: null,
69152
+ isEllipse: false,
69153
+ softEdge: null,
69154
+ rotate: null,
69155
+ cssTriangle: null,
69156
+ customGeometry: points
69157
+ }
69158
+ });
69159
+ } else {
69160
+ borderShapes.push({
69161
+ type: "shape",
69162
+ text: "",
69163
+ textRuns: null,
69164
+ style: null,
69165
+ position: {
69166
+ x: pxToInch(rect2.left + rect2.width - borderRightW2),
69167
+ y: pxToInch(rect2.top),
69168
+ w: pxToInch(borderRightW2),
69169
+ h: pxToInch(rect2.height)
69170
+ },
69171
+ shape: {
69172
+ fill: rgbToHex(computed2.borderRightColor),
69173
+ gradient: null,
69174
+ transparency: extractAlpha(computed2.borderRightColor),
69175
+ line: null,
69176
+ rectRadius: 0,
69177
+ shadow: null,
69178
+ opacity: null,
69179
+ isEllipse: false,
69180
+ softEdge: null,
69181
+ rotate: null,
69182
+ cssTriangle: null,
69183
+ customGeometry: null
69184
+ }
69185
+ });
69186
+ }
69187
+ }
69188
+ const leftRightBottomBorders = [borders[3], borders[1], borders[2]].filter((b) => b > 0);
69189
+ const minLeftRightBottom = leftRightBottomBorders.length > 0 ? Math.min(...leftRightBottomBorders) : 0;
69190
+ const leftRightTopBorders = [borders[3], borders[1], borders[0]].filter((b) => b > 0);
69191
+ const minLeftRightTop = leftRightTopBorders.length > 0 ? Math.min(...leftRightTopBorders) : 0;
69192
+ const borderTopW2 = borders[0];
69193
+ if (borderTopW2 > 0 && !isFullyTransparent(computed2.borderTopColor) && (borderTopW2 > minLeftRightBottom || minLeftRightBottom === 0)) {
69194
+ if (divBorderRadius > 0) {
69195
+ const w2 = rect2.width;
69196
+ const h2 = borderTopW2;
69197
+ const r = divBorderRadius;
69198
+ const EMU_PER_PX3 = 914400 / 96;
69199
+ const arcXAtY = (radius, y2) => {
69200
+ if (y2 <= 0)
69201
+ return radius;
69202
+ if (y2 >= radius)
69203
+ return 0;
69204
+ const dy = radius - y2;
69205
+ return radius - Math.sqrt(radius * radius - dy * dy);
69206
+ };
69207
+ const segments = 8;
69208
+ const arcPointsLeft = [];
69209
+ const arcPointsRight = [];
69210
+ for (let i = 0; i <= segments; i++) {
69211
+ const t = i / segments;
69212
+ const y2 = t * h2;
69213
+ const arcDistance = arcXAtY(r, y2);
69214
+ arcPointsLeft.push({
69215
+ x: Math.round(arcDistance * EMU_PER_PX3),
69216
+ y: Math.round(y2 * EMU_PER_PX3)
69217
+ });
69218
+ arcPointsRight.push({
69219
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
69220
+ y: Math.round(y2 * EMU_PER_PX3)
69221
+ });
69222
+ }
69223
+ const points = [];
69224
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
69225
+ for (let i = 1; i <= segments; i++) {
69226
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
69227
+ }
69228
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
69229
+ for (let i = segments - 1; i >= 0; i--) {
69230
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
69231
+ }
69232
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
69233
+ borderShapes.push({
69234
+ type: "shape",
69235
+ text: "",
69236
+ textRuns: null,
69237
+ style: null,
69238
+ position: {
69239
+ x: pxToInch(rect2.left),
69240
+ y: pxToInch(rect2.top),
69241
+ w: pxToInch(rect2.width),
69242
+ h: pxToInch(borderTopW2)
69243
+ },
69244
+ shape: {
69245
+ fill: rgbToHex(computed2.borderTopColor),
69246
+ gradient: null,
69247
+ transparency: extractAlpha(computed2.borderTopColor),
69248
+ line: null,
69249
+ rectRadius: 0,
69250
+ shadow: null,
69251
+ opacity: null,
69252
+ isEllipse: false,
69253
+ softEdge: null,
69254
+ rotate: null,
69255
+ cssTriangle: null,
69256
+ customGeometry: points
69257
+ }
69258
+ });
69259
+ } else {
69260
+ borderShapes.push({
69261
+ type: "shape",
69262
+ text: "",
69263
+ textRuns: null,
69264
+ style: null,
69265
+ position: {
69266
+ x: pxToInch(rect2.left),
69267
+ y: pxToInch(rect2.top),
69268
+ w: pxToInch(rect2.width),
69269
+ h: pxToInch(borderTopW2)
69270
+ },
69271
+ shape: {
69272
+ fill: rgbToHex(computed2.borderTopColor),
69273
+ gradient: null,
69274
+ transparency: extractAlpha(computed2.borderTopColor),
69275
+ line: null,
69276
+ rectRadius: 0,
69277
+ shadow: null,
69278
+ opacity: null,
69279
+ isEllipse: false,
69280
+ softEdge: null,
69281
+ rotate: null,
69282
+ cssTriangle: null,
69283
+ customGeometry: null
69284
+ }
69285
+ });
69286
+ }
69287
+ }
69288
+ const borderBottomW2 = borders[2];
69289
+ if (borderBottomW2 > 0 && !isFullyTransparent(computed2.borderBottomColor) && (borderBottomW2 > minLeftRightTop || minLeftRightTop === 0)) {
69290
+ if (divBorderRadius > 0) {
69291
+ const w2 = rect2.width;
69292
+ const h2 = borderBottomW2;
69293
+ const r = divBorderRadius;
69294
+ const EMU_PER_PX3 = 914400 / 96;
69295
+ const arcXAtY = (radius, y2) => {
69296
+ if (y2 <= 0)
69297
+ return radius;
69298
+ if (y2 >= radius)
69299
+ return 0;
69300
+ const dy = radius - y2;
69301
+ return radius - Math.sqrt(radius * radius - dy * dy);
69302
+ };
69303
+ const segments = 8;
69304
+ const arcPointsLeft = [];
69305
+ const arcPointsRight = [];
69306
+ for (let i = 0; i <= segments; i++) {
69307
+ const t = i / segments;
69308
+ const y2 = t * h2;
69309
+ const arcDistance = arcXAtY(r, h2 - y2);
69310
+ arcPointsLeft.push({
69311
+ x: Math.round(arcDistance * EMU_PER_PX3),
69312
+ y: Math.round(y2 * EMU_PER_PX3)
69313
+ });
69314
+ arcPointsRight.push({
69315
+ x: Math.round((w2 - arcDistance) * EMU_PER_PX3),
69316
+ y: Math.round(y2 * EMU_PER_PX3)
69317
+ });
69318
+ }
69319
+ const points = [];
69320
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, moveTo: true });
69321
+ for (let i = 1; i <= segments; i++) {
69322
+ points.push({ x: arcPointsLeft[i].x, y: arcPointsLeft[i].y });
67538
69323
  }
69324
+ points.push({ x: arcPointsRight[segments].x, y: arcPointsRight[segments].y });
69325
+ for (let i = segments - 1; i >= 0; i--) {
69326
+ points.push({ x: arcPointsRight[i].x, y: arcPointsRight[i].y });
69327
+ }
69328
+ points.push({ x: arcPointsLeft[0].x, y: arcPointsLeft[0].y, close: true });
69329
+ borderShapes.push({
69330
+ type: "shape",
69331
+ text: "",
69332
+ textRuns: null,
69333
+ style: null,
69334
+ position: {
69335
+ x: pxToInch(rect2.left),
69336
+ y: pxToInch(rect2.top + rect2.height - borderBottomW2),
69337
+ w: pxToInch(rect2.width),
69338
+ h: pxToInch(borderBottomW2)
69339
+ },
69340
+ shape: {
69341
+ fill: rgbToHex(computed2.borderBottomColor),
69342
+ gradient: null,
69343
+ transparency: extractAlpha(computed2.borderBottomColor),
69344
+ line: null,
69345
+ rectRadius: 0,
69346
+ shadow: null,
69347
+ opacity: null,
69348
+ isEllipse: false,
69349
+ softEdge: null,
69350
+ rotate: null,
69351
+ cssTriangle: null,
69352
+ customGeometry: points
69353
+ }
69354
+ });
69355
+ } else {
69356
+ borderShapes.push({
69357
+ type: "shape",
69358
+ text: "",
69359
+ textRuns: null,
69360
+ style: null,
69361
+ position: {
69362
+ x: pxToInch(rect2.left),
69363
+ y: pxToInch(rect2.top + rect2.height - borderBottomW2),
69364
+ w: pxToInch(rect2.width),
69365
+ h: pxToInch(borderBottomW2)
69366
+ },
69367
+ shape: {
69368
+ fill: rgbToHex(computed2.borderBottomColor),
69369
+ gradient: null,
69370
+ transparency: extractAlpha(computed2.borderBottomColor),
69371
+ line: null,
69372
+ rectRadius: 0,
69373
+ shadow: null,
69374
+ opacity: null,
69375
+ isEllipse: false,
69376
+ softEdge: null,
69377
+ rotate: null,
69378
+ cssTriangle: null,
69379
+ customGeometry: null
69380
+ }
69381
+ });
67539
69382
  }
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
69383
  }
67619
69384
  }
67620
69385
  if (hasBg || hasBorder || bgImageUrl || bgGradient || hasConicGradientImage) {
@@ -67638,7 +69403,7 @@ ${generateStylesCss(styleMap, themeFonts)}
67638
69403
  };
67639
69404
  elements.push(bgImgElement);
67640
69405
  }
67641
- const textTagSet = /* @__PURE__ */ new Set(["P", "H1", "H2", "H3", "H4", "H5", "H6", "SPAN"]);
69406
+ const textTagSet = /* @__PURE__ */ new Set(["P", "H1", "H2", "H3", "H4", "H5", "H6", "SPAN", "PRE"]);
67642
69407
  const allChildren = Array.from(el.children);
67643
69408
  const textChildren = allChildren.filter((child) => {
67644
69409
  if (textTagSet.has(child.tagName)) {
@@ -67654,6 +69419,15 @@ ${generateStylesCss(styleMap, themeFonts)}
67654
69419
  return false;
67655
69420
  }
67656
69421
  }
69422
+ if (["H1", "H2", "H3", "H4", "H5", "H6", "P"].includes(child.tagName)) {
69423
+ const textTagComputed = win.getComputedStyle(child);
69424
+ const textTagHasBg = textTagComputed.backgroundColor && textTagComputed.backgroundColor !== "rgba(0, 0, 0, 0)";
69425
+ const textTagHasBorder = (parseFloat(textTagComputed.borderTopWidth) || 0) > 0 || (parseFloat(textTagComputed.borderRightWidth) || 0) > 0 || (parseFloat(textTagComputed.borderBottomWidth) || 0) > 0 || (parseFloat(textTagComputed.borderLeftWidth) || 0) > 0;
69426
+ const textTagHasShadow = textTagComputed.boxShadow && textTagComputed.boxShadow !== "none";
69427
+ if (textTagHasBg || textTagHasBorder || textTagHasShadow) {
69428
+ return false;
69429
+ }
69430
+ }
67657
69431
  return true;
67658
69432
  }
67659
69433
  if (child.tagName === "DIV") {
@@ -67686,8 +69460,36 @@ ${generateStylesCss(styleMap, themeFonts)}
67686
69460
  }
67687
69461
  return false;
67688
69462
  });
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)));
69463
+ const decorativeTags = /* @__PURE__ */ new Set(["I", "CANVAS", "VIDEO", "AUDIO", "IFRAME"]);
69464
+ const nonTextChildren = allChildren.filter((child) => {
69465
+ const childTagUpper = child.tagName.toUpperCase();
69466
+ if (textTagSet.has(childTagUpper))
69467
+ return false;
69468
+ if (decorativeTags.has(childTagUpper))
69469
+ return false;
69470
+ if (childTagUpper === "SVG") {
69471
+ const svgComputed = win.getComputedStyle(child);
69472
+ const svgDisplay = svgComputed.display;
69473
+ if (svgDisplay === "block")
69474
+ return true;
69475
+ return false;
69476
+ }
69477
+ if (child.tagName === "DIV" && textChildren.includes(child))
69478
+ return false;
69479
+ if (child.tagName === "DIV") {
69480
+ const divText = child.textContent?.trim();
69481
+ if (!divText) {
69482
+ const childElements = Array.from(child.children);
69483
+ const hasContentChildren = childElements.some((c) => {
69484
+ const tagUpper = c.tagName.toUpperCase();
69485
+ return c.textContent?.trim() || tagUpper === "SVG" || tagUpper === "IMG" || tagUpper === "CANVAS" || tagUpper === "VIDEO" || tagUpper === "I";
69486
+ });
69487
+ if (!hasContentChildren)
69488
+ return false;
69489
+ }
69490
+ }
69491
+ return true;
69492
+ });
67691
69493
  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
69494
  const isSingleTextChild = textChildren.length === 1 && (() => {
67693
69495
  const tc = textChildren[0];
@@ -67744,26 +69546,68 @@ ${generateStylesCss(styleMap, themeFonts)}
67744
69546
  let shapeStyle = null;
67745
69547
  const hasTextChildren = textChildren.length > 0;
67746
69548
  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);
69549
+ for (const node of Array.from(el.childNodes)) {
69550
+ if (node.nodeType === Node.TEXT_NODE) {
69551
+ directTextContent += node.textContent || "";
67756
69552
  }
67757
69553
  }
69554
+ directTextContent = directTextContent.trim();
69555
+ if (directTextContent && computed2.textTransform && computed2.textTransform !== "none") {
69556
+ directTextContent = applyTextTransform2(directTextContent, computed2.textTransform);
69557
+ }
67758
69558
  const hasDirectText = directTextContent.length > 0;
69559
+ const inlineFormattingTagsForMixed = /* @__PURE__ */ new Set(["STRONG", "EM", "B", "I", "A", "SPAN", "MARK", "SMALL", "SUB", "SUP", "CODE", "U", "S", "Q", "CITE", "ABBR", "TIME", "DATA"]);
69560
+ const hasInlineFormattingChildren = allChildren.some((child) => inlineFormattingTagsForMixed.has(child.tagName));
69561
+ const hasMixedInlineContent = hasDirectText && (hasTextChildren || hasInlineFormattingChildren);
67759
69562
  const isParentFlexRow = isFlexContainer2 && (computed2.flexDirection === "row" || computed2.flexDirection === "row-reverse" || !computed2.flexDirection) && allChildren.length > 1;
69563
+ const isParentFlexColumn = isFlexContainer2 && (computed2.flexDirection === "column" || computed2.flexDirection === "column-reverse") && allChildren.length > 1;
67760
69564
  const isParentGrid = display === "grid" || display === "inline-grid";
67761
- const shouldMergeText = !isParentFlexRow && !isParentGrid && (hasTextChildren && (isSingleTextChild || nonTextChildren.length === 0) || hasDirectText);
69565
+ const shouldMergeText = !isParentFlexRow && !isParentFlexColumn && !isParentGrid && (hasTextChildren && (isSingleTextChild || nonTextChildren.length === 0) || hasDirectText || hasMixedInlineContent);
67762
69566
  if (shouldMergeText) {
67763
- if (isSingleTextChild) {
69567
+ if (hasMixedInlineContent) {
69568
+ const isBold = computed2.fontWeight === "bold" || parseInt(computed2.fontWeight) >= 600;
69569
+ const isItalic = computed2.fontStyle === "italic";
69570
+ const isUnderline = computed2.textDecoration && computed2.textDecoration.includes("underline");
69571
+ const baseRunOptions = {
69572
+ fontSize: pxToPoints(computed2.fontSize),
69573
+ fontFace: extractFontFace(computed2.fontFamily),
69574
+ color: rgbToHex(computed2.color),
69575
+ bold: isBold,
69576
+ italic: isItalic,
69577
+ underline: isUnderline || false,
69578
+ ...extractLetterSpacing(computed2) !== null ? { charSpacing: extractLetterSpacing(computed2) } : {},
69579
+ ...extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {},
69580
+ ...(() => {
69581
+ const ts = parseTextShadow(computed2.textShadow);
69582
+ return ts.glow ? { glow: ts.glow } : {};
69583
+ })()
69584
+ };
69585
+ shapeTextRuns = [];
69586
+ const textTransformFn = (s) => applyTextTransform2(s, computed2.textTransform || "none");
69587
+ parseInlineFormatting(el, baseRunOptions, shapeTextRuns, textTransformFn, win, false);
69588
+ shapeStyle = {
69589
+ fontSize: pxToPoints(computed2.fontSize),
69590
+ fontFace: extractFontFace(computed2.fontFamily),
69591
+ color: rgbToHex(computed2.color),
69592
+ bold: isBold,
69593
+ italic: isItalic,
69594
+ valign: valign2,
69595
+ align,
69596
+ lineSpacing: pxToPoints(computed2.lineHeight) || void 0,
69597
+ margin: [
69598
+ pxToPoints(computed2.paddingLeft),
69599
+ pxToPoints(computed2.paddingRight),
69600
+ pxToPoints(computed2.paddingBottom),
69601
+ pxToPoints(computed2.paddingTop)
69602
+ ],
69603
+ ...extractLetterSpacing(computed2) !== null ? { charSpacing: extractLetterSpacing(computed2) } : {},
69604
+ ...extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {}
69605
+ };
69606
+ el.querySelectorAll("*").forEach((desc) => processed.add(desc));
69607
+ } else if (isSingleTextChild) {
67764
69608
  const textEl = textChildren[0];
67765
69609
  const textComputed = win.getComputedStyle(textEl);
67766
- shapeText = getTransformedText(textEl, textComputed);
69610
+ 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
69611
  let fontFill = null;
67768
69612
  const textBgClip = textComputed.webkitBackgroundClip || textComputed.backgroundClip;
67769
69613
  const textFillColor2 = textComputed.webkitTextFillColor;
@@ -67783,7 +69627,7 @@ ${generateStylesCss(styleMap, themeFonts)}
67783
69627
  bgGradient = null;
67784
69628
  }
67785
69629
  }
67786
- const effectiveColor = textComputed.color !== "rgb(0, 0, 0)" ? textComputed.color : computed2.color;
69630
+ const effectiveColor2 = textComputed.color !== "rgb(0, 0, 0)" ? textComputed.color : computed2.color;
67787
69631
  const isBold = textComputed.fontWeight === "bold" || parseInt(textComputed.fontWeight) >= 600 || computed2.fontWeight === "bold" || parseInt(computed2.fontWeight) >= 600;
67788
69632
  let effectiveAlign = align;
67789
69633
  const childTextAlign = textComputed.textAlign;
@@ -67795,7 +69639,7 @@ ${generateStylesCss(styleMap, themeFonts)}
67795
69639
  shapeStyle = {
67796
69640
  fontSize: pxToPoints(textComputed.fontSize || computed2.fontSize),
67797
69641
  fontFace: extractFontFace(textComputed.fontFamily || computed2.fontFamily),
67798
- color: fontFill ? null : rgbToHex(effectiveColor),
69642
+ color: fontFill ? null : rgbToHex(effectiveColor2),
67799
69643
  fontFill,
67800
69644
  bold: isBold,
67801
69645
  align: effectiveAlign,
@@ -67811,14 +69655,31 @@ ${generateStylesCss(styleMap, themeFonts)}
67811
69655
  shapeStyle.glow = shapeTextShadow.glow;
67812
69656
  if (shapeTextShadow.shadow)
67813
69657
  shapeStyle.textShadow = shapeTextShadow.shadow;
69658
+ if (hasInlineFormatting2) {
69659
+ const textTransformFn = (s) => applyTextTransform2(s, textComputed.textTransform || "none");
69660
+ const baseRunOptions = {
69661
+ fontSize: shapeStyle.fontSize,
69662
+ fontFace: shapeStyle.fontFace,
69663
+ color: shapeStyle.color ?? void 0,
69664
+ bold: shapeStyle.bold
69665
+ };
69666
+ const textPreserveWs = shouldPreserveWhitespace(textComputed) || isMonospaceFont(computed2.fontFamily);
69667
+ shapeTextRuns = parseInlineFormatting(textEl, baseRunOptions, [], textTransformFn, win, textPreserveWs);
69668
+ shapeText = "";
69669
+ } else {
69670
+ const effectivePreserveWs = shouldPreserveWhitespace(textComputed) || isMonospaceFont(computed2.fontFamily);
69671
+ shapeText = getTransformedText(textEl, effectivePreserveWs ? computed2 : textComputed);
69672
+ }
67814
69673
  processed.add(textEl);
67815
69674
  textEl.querySelectorAll("*").forEach((desc) => processed.add(desc));
67816
69675
  } else if (hasTextChildren) {
67817
69676
  shapeTextRuns = [];
69677
+ const parentHasMonospace = isMonospaceFont(computed2.fontFamily);
67818
69678
  textChildren.forEach((textChild, idx) => {
67819
69679
  const textEl = textChild;
67820
69680
  const textComputed = win.getComputedStyle(textEl);
67821
- const fullText = getTransformedText(textEl, textComputed);
69681
+ const effectiveWsStyle = parentHasMonospace ? computed2 : textComputed;
69682
+ const fullText = getTransformedText(textEl, effectiveWsStyle);
67822
69683
  if (!fullText)
67823
69684
  return;
67824
69685
  const isBold = textComputed.fontWeight === "bold" || parseInt(textComputed.fontWeight) >= 600;
@@ -67837,37 +69698,48 @@ ${generateStylesCss(styleMap, themeFonts)}
67837
69698
  return ts.glow ? { glow: ts.glow } : {};
67838
69699
  })()
67839
69700
  };
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 || "";
69701
+ 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");
69702
+ if (hasInlineFormattingInChild) {
69703
+ const textTransformFn = (s) => applyTextTransform2(s, textComputed.textTransform || "none");
69704
+ if (idx > 0 && shapeTextRuns.length > 0) {
69705
+ const lastRun = shapeTextRuns[shapeTextRuns.length - 1];
69706
+ lastRun.options = { ...lastRun.options, breakLine: true };
69707
+ }
69708
+ const childPreserveWs = shouldPreserveWhitespace(textComputed) || isMonospaceFont(computed2.fontFamily);
69709
+ parseInlineFormatting(textEl, baseRunOptions, shapeTextRuns, textTransformFn, win, childPreserveWs);
69710
+ } else {
69711
+ const hasBrChildren = textEl.querySelector("br") !== null;
69712
+ if (hasBrChildren) {
69713
+ let segments = [];
69714
+ let currentSegment = "";
69715
+ for (const node of Array.from(textEl.childNodes)) {
69716
+ if (node.tagName === "BR") {
69717
+ segments.push(currentSegment.trim());
69718
+ currentSegment = "";
69719
+ } else {
69720
+ currentSegment += node.textContent || "";
69721
+ }
67850
69722
  }
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;
69723
+ if (currentSegment.trim())
69724
+ segments.push(currentSegment.trim());
69725
+ segments = segments.filter((s) => s.length > 0);
69726
+ if (textComputed.textTransform && textComputed.textTransform !== "none") {
69727
+ segments = segments.map((s) => applyTextTransform2(s, textComputed.textTransform));
67864
69728
  }
69729
+ segments.forEach((segment, segIdx) => {
69730
+ const prefix = segIdx === 0 && idx > 0 && shapeTextRuns.length > 0 ? "\n" : "";
69731
+ const runText = prefix + segment;
69732
+ const options = { ...baseRunOptions };
69733
+ if (segIdx > 0) {
69734
+ options.softBreakBefore = true;
69735
+ }
69736
+ shapeTextRuns.push({ text: runText, options });
69737
+ });
69738
+ } else {
69739
+ const runText = idx > 0 && shapeTextRuns.length > 0 ? "\n" + fullText : fullText;
69740
+ const options = idx > 0 && shapeTextRuns.length > 0 ? { ...baseRunOptions, breakLine: true } : baseRunOptions;
67865
69741
  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 });
69742
+ }
67871
69743
  }
67872
69744
  processed.add(textEl);
67873
69745
  textEl.querySelectorAll("*").forEach((desc) => processed.add(desc));
@@ -67892,14 +69764,16 @@ ${generateStylesCss(styleMap, themeFonts)}
67892
69764
  align,
67893
69765
  valign: valign2,
67894
69766
  inset: 0,
67895
- wrap: !shouldNotWrap
69767
+ wrap: !shouldNotWrap,
69768
+ ...extractAlpha(computed2.color) !== null ? { transparency: extractAlpha(computed2.color) } : {}
67896
69769
  };
67897
69770
  const ls = extractLetterSpacing(computed2);
67898
69771
  if (ls !== null)
67899
69772
  shapeStyle.charSpacing = ls;
67900
69773
  }
67901
69774
  }
67902
- if (hasBg || hasUniformBorder || bgGradient) {
69775
+ const hasTextToRender = shapeText || shapeTextRuns && shapeTextRuns.length > 0;
69776
+ if (hasBg || hasUniformBorder || bgGradient || hasBorder && hasTextToRender) {
67903
69777
  const elementOpacity = getEffectiveOpacity(htmlEl, win);
67904
69778
  const hasOpacity = elementOpacity < 1;
67905
69779
  let softEdgePt = null;
@@ -67940,11 +69814,436 @@ ${generateStylesCss(styleMap, themeFonts)}
67940
69814
  shapeY = cy - origH / 2;
67941
69815
  }
67942
69816
  }
69817
+ let overflowClipGeometry = null;
69818
+ let clippedShapeX = shapeX;
69819
+ let clippedShapeY = shapeY;
69820
+ let clippedShapeW = shapeW;
69821
+ let clippedShapeH = shapeH;
69822
+ let wasClippedToParent = false;
69823
+ const DEBUG_OVERFLOW = false;
69824
+ if (DEBUG_OVERFLOW)
69825
+ console.log("[OverflowClip] Processing element:", { shapeX, shapeY, shapeW, shapeH, bg: computed2.backgroundColor });
69826
+ let overflowAncestor = htmlEl.parentElement;
69827
+ while (overflowAncestor && overflowAncestor !== doc.body) {
69828
+ const ancestorComputed = win.getComputedStyle(overflowAncestor);
69829
+ const ancestorOverflow = ancestorComputed.overflow;
69830
+ if (ancestorOverflow === "hidden" || ancestorOverflow === "clip") {
69831
+ const ancestorBorderRadius = parseFloat(ancestorComputed.borderRadius) || 0;
69832
+ const ancestorRect = overflowAncestor.getBoundingClientRect();
69833
+ if (DEBUG_OVERFLOW)
69834
+ console.log("[OverflowClip] Found overflow ancestor:", { overflow: ancestorOverflow, borderRadius: ancestorBorderRadius, ancestorRect: { left: ancestorRect.left, top: ancestorRect.top, width: ancestorRect.width, height: ancestorRect.height } });
69835
+ const cssWidth = parseFloat(computed2.width);
69836
+ const cssHeight = parseFloat(computed2.height);
69837
+ const cssTop = parseFloat(computed2.top);
69838
+ const cssRight = parseFloat(computed2.right);
69839
+ const cssBottom = parseFloat(computed2.bottom);
69840
+ const cssLeft = parseFloat(computed2.left);
69841
+ const origW = !isNaN(cssWidth) && cssWidth > 0 ? cssWidth : shapeW;
69842
+ const origH = !isNaN(cssHeight) && cssHeight > 0 ? cssHeight : shapeH;
69843
+ let origRelLeft;
69844
+ let origRelTop;
69845
+ const position = computed2.position;
69846
+ if (position === "absolute" || position === "fixed") {
69847
+ if (!isNaN(cssLeft)) {
69848
+ origRelLeft = cssLeft;
69849
+ } else if (!isNaN(cssRight)) {
69850
+ origRelLeft = ancestorRect.width - cssRight - origW;
69851
+ } else {
69852
+ origRelLeft = shapeX - ancestorRect.left;
69853
+ }
69854
+ if (!isNaN(cssTop)) {
69855
+ origRelTop = cssTop;
69856
+ } else if (!isNaN(cssBottom)) {
69857
+ origRelTop = ancestorRect.height - cssBottom - origH;
69858
+ } else {
69859
+ origRelTop = shapeY - ancestorRect.top;
69860
+ }
69861
+ } else {
69862
+ origRelLeft = shapeX - ancestorRect.left;
69863
+ origRelTop = shapeY - ancestorRect.top;
69864
+ }
69865
+ const origRelRight = origRelLeft + origW;
69866
+ const origRelBottom = origRelTop + origH;
69867
+ if (DEBUG_OVERFLOW) {
69868
+ console.log("[OverflowClip] Element original position:", {
69869
+ origRelLeft,
69870
+ origRelTop,
69871
+ origW,
69872
+ origH,
69873
+ cssTop,
69874
+ cssRight,
69875
+ cssBottom,
69876
+ cssLeft,
69877
+ rectW: shapeW,
69878
+ rectH: shapeH,
69879
+ bgColor: computed2.backgroundColor,
69880
+ isEllipse,
69881
+ borderRadius: borderRadiusStr
69882
+ });
69883
+ }
69884
+ const relLeft = origRelLeft;
69885
+ const relTop = origRelTop;
69886
+ const relRight = origRelRight;
69887
+ const relBottom = origRelBottom;
69888
+ const needsRectClip = relLeft < 0 || relTop < 0 || relRight > ancestorRect.width || relBottom > ancestorRect.height;
69889
+ if (needsRectClip) {
69890
+ if (DEBUG_OVERFLOW)
69891
+ console.log("[OverflowClip] Element needs rect clipping:", { relLeft, relTop, relRight, relBottom });
69892
+ const clippedRelLeft = Math.max(0, relLeft);
69893
+ const clippedRelTop = Math.max(0, relTop);
69894
+ const clippedRelRight = Math.min(ancestorRect.width, relRight);
69895
+ const clippedRelBottom = Math.min(ancestorRect.height, relBottom);
69896
+ clippedShapeX = ancestorRect.left + clippedRelLeft;
69897
+ clippedShapeY = ancestorRect.top + clippedRelTop;
69898
+ clippedShapeW = clippedRelRight - clippedRelLeft;
69899
+ clippedShapeH = clippedRelBottom - clippedRelTop;
69900
+ wasClippedToParent = true;
69901
+ }
69902
+ if (ancestorBorderRadius > 0) {
69903
+ const r = ancestorBorderRadius;
69904
+ const clippedRelLeft = clippedShapeX - ancestorRect.left;
69905
+ const clippedRelTop = clippedShapeY - ancestorRect.top;
69906
+ const clippedRelRight = clippedRelLeft + clippedShapeW;
69907
+ const clippedRelBottom = clippedRelTop + clippedShapeH;
69908
+ const overlapsTL = clippedRelLeft < r && clippedRelTop < r;
69909
+ const overlapsTR = clippedRelRight > ancestorRect.width - r && clippedRelTop < r;
69910
+ const overlapsBL = clippedRelLeft < r && clippedRelBottom > ancestorRect.height - r;
69911
+ const overlapsBR = clippedRelRight > ancestorRect.width - r && clippedRelBottom > ancestorRect.height - r;
69912
+ if ((overlapsTL || overlapsTR || overlapsBL || overlapsBR) && wasClippedToParent) {
69913
+ if (DEBUG_OVERFLOW)
69914
+ console.log("[OverflowClip] Element overlaps corners:", { overlapsTL, overlapsTR, overlapsBL, overlapsBR, clippedRelLeft, clippedRelTop, clippedRelRight, clippedRelBottom, r, isEllipse, wasClippedToParent });
69915
+ const w2 = clippedShapeW;
69916
+ const h2 = clippedShapeH;
69917
+ const EMU_PER_PX3 = 914400 / 96;
69918
+ const widthEmu = Math.round(w2 * EMU_PER_PX3);
69919
+ const heightEmu = Math.round(h2 * EMU_PER_PX3);
69920
+ const segments = 8;
69921
+ const points = [];
69922
+ const addCornerArc = (cornerRelX, cornerRelY, isRight, isBottom, goingClockwise) => {
69923
+ const arcCenterX = isRight ? cornerRelX - r : cornerRelX + r;
69924
+ const arcCenterY = isBottom ? cornerRelY - r : cornerRelY + r;
69925
+ for (let i = 0; i <= segments; i++) {
69926
+ const t = goingClockwise ? i / segments : 1 - i / segments;
69927
+ const angle = t * Math.PI / 2;
69928
+ let arcRelX, arcRelY;
69929
+ if (!isRight && !isBottom) {
69930
+ arcRelX = -r * Math.sin(angle);
69931
+ arcRelY = -r * Math.cos(angle);
69932
+ } else if (isRight && !isBottom) {
69933
+ arcRelX = r * Math.cos(angle);
69934
+ arcRelY = -r * Math.sin(angle);
69935
+ } else if (!isRight && isBottom) {
69936
+ arcRelX = -r * Math.cos(angle);
69937
+ arcRelY = r * Math.sin(angle);
69938
+ } else {
69939
+ arcRelX = r * Math.sin(angle);
69940
+ arcRelY = r * Math.cos(angle);
69941
+ }
69942
+ const x2 = arcCenterX + arcRelX - clippedRelLeft;
69943
+ const y2 = arcCenterY + arcRelY - clippedRelTop;
69944
+ if (x2 >= -0.1 && x2 <= w2 + 0.1 && y2 >= -0.1 && y2 <= h2 + 0.1) {
69945
+ points.push({
69946
+ x: Math.round(Math.max(0, Math.min(w2, x2)) * EMU_PER_PX3),
69947
+ y: Math.round(Math.max(0, Math.min(h2, y2)) * EMU_PER_PX3),
69948
+ ...points.length === 0 ? { moveTo: true } : {}
69949
+ });
69950
+ }
69951
+ }
69952
+ };
69953
+ if (isEllipse && wasClippedToParent) {
69954
+ const ellipseRx = origW / 2;
69955
+ const ellipseRy = origH / 2;
69956
+ const centerXInClipped = relLeft + ellipseRx - clippedRelLeft;
69957
+ const centerYInClipped = relTop + ellipseRy - clippedRelTop;
69958
+ if (DEBUG_OVERFLOW) {
69959
+ console.log("[OverflowClip] Ellipse clipping - origW:", origW, "origH:", origH);
69960
+ console.log("[OverflowClip] Ellipse clipping - rx:", ellipseRx, "ry:", ellipseRy);
69961
+ console.log("[OverflowClip] Ellipse clipping - relLeft:", relLeft, "relTop:", relTop);
69962
+ console.log("[OverflowClip] Ellipse clipping - clippedRelLeft:", clippedRelLeft, "clippedRelTop:", clippedRelTop);
69963
+ console.log("[OverflowClip] Ellipse clipping - centerX:", centerXInClipped, "centerY:", centerYInClipped);
69964
+ console.log("[OverflowClip] Ellipse clipping - w:", w2, "h:", h2);
69965
+ console.log("[OverflowClip] Ellipse clipping - clippedShapeW:", clippedShapeW, "clippedShapeH:", clippedShapeH);
69966
+ }
69967
+ const arcSegments = 64;
69968
+ const pathPoints = [];
69969
+ for (let i = 0; i <= arcSegments; i++) {
69970
+ const angle = i / arcSegments * 2 * Math.PI;
69971
+ const px = centerXInClipped + ellipseRx * Math.cos(angle);
69972
+ const py = centerYInClipped + ellipseRy * Math.sin(angle);
69973
+ const isInside = px >= -0.5 && px <= w2 + 0.5 && py >= -0.5 && py <= h2 + 0.5;
69974
+ if (i > 0) {
69975
+ const prevAngle = (i - 1) / arcSegments * 2 * Math.PI;
69976
+ const prevPx = centerXInClipped + ellipseRx * Math.cos(prevAngle);
69977
+ const prevPy = centerYInClipped + ellipseRy * Math.sin(prevAngle);
69978
+ const prevInside = prevPx >= -0.5 && prevPx <= w2 + 0.5 && prevPy >= -0.5 && prevPy <= h2 + 0.5;
69979
+ if (isInside !== prevInside) {
69980
+ let lowT = 0, highT = 1;
69981
+ for (let iter = 0; iter < 10; iter++) {
69982
+ const midT = (lowT + highT) / 2;
69983
+ const midAngle = prevAngle + midT * (angle - prevAngle);
69984
+ const midPx = centerXInClipped + ellipseRx * Math.cos(midAngle);
69985
+ const midPy = centerYInClipped + ellipseRy * Math.sin(midAngle);
69986
+ const midInside = midPx >= -0.5 && midPx <= w2 + 0.5 && midPy >= -0.5 && midPy <= h2 + 0.5;
69987
+ if (midInside === prevInside)
69988
+ lowT = midT;
69989
+ else
69990
+ highT = midT;
69991
+ }
69992
+ const crossT = (lowT + highT) / 2;
69993
+ const crossAngle = prevAngle + crossT * (angle - prevAngle);
69994
+ const crossPx = centerXInClipped + ellipseRx * Math.cos(crossAngle);
69995
+ const crossPy = centerYInClipped + ellipseRy * Math.sin(crossAngle);
69996
+ let edge = "";
69997
+ if (Math.abs(crossPy) < 1)
69998
+ edge = "top";
69999
+ else if (Math.abs(crossPy - h2) < 1)
70000
+ edge = "bottom";
70001
+ else if (Math.abs(crossPx) < 1)
70002
+ edge = "left";
70003
+ else if (Math.abs(crossPx - w2) < 1)
70004
+ edge = "right";
70005
+ pathPoints.push({
70006
+ x: Math.max(0, Math.min(w2, crossPx)),
70007
+ y: Math.max(0, Math.min(h2, crossPy)),
70008
+ angle: crossAngle,
70009
+ isEntry: isInside,
70010
+ isExit: !isInside,
70011
+ edge
70012
+ });
70013
+ }
70014
+ }
70015
+ if (isInside) {
70016
+ pathPoints.push({
70017
+ x: Math.max(0, Math.min(w2, px)),
70018
+ y: Math.max(0, Math.min(h2, py)),
70019
+ angle
70020
+ });
70021
+ }
70022
+ }
70023
+ if (pathPoints.length >= 3) {
70024
+ if (DEBUG_OVERFLOW) {
70025
+ console.log("[OverflowClip] pathPoints count:", pathPoints.length);
70026
+ const entryPt = pathPoints.find((p) => p.isEntry);
70027
+ const exitPt = pathPoints.find((p) => p.isExit);
70028
+ console.log("[OverflowClip] entry:", entryPt);
70029
+ console.log("[OverflowClip] exit:", exitPt);
70030
+ }
70031
+ const finalPoints = [];
70032
+ for (const p of pathPoints) {
70033
+ if (finalPoints.length > 0) {
70034
+ const last = finalPoints[finalPoints.length - 1];
70035
+ if (Math.abs(p.x - last.x) < 0.5 && Math.abs(p.y - last.y) < 0.5)
70036
+ continue;
70037
+ }
70038
+ finalPoints.push({ x: p.x, y: p.y });
70039
+ }
70040
+ if (finalPoints.length >= 2) {
70041
+ const exitEdge = pathPoints.find((p) => p.isExit)?.edge;
70042
+ const entryEdge = pathPoints.find((p) => p.isEntry)?.edge;
70043
+ if (exitEdge && entryEdge && exitEdge !== entryEdge) {
70044
+ const edgeOrder = ["top", "right", "bottom", "left"];
70045
+ const cornerHasArc = {
70046
+ "top-right": overlapsTR && r > 0,
70047
+ "right-bottom": overlapsBR && r > 0,
70048
+ "bottom-left": overlapsBL && r > 0,
70049
+ "left-top": overlapsTL && r > 0
70050
+ };
70051
+ const cornerPositions = {
70052
+ "top-right": {
70053
+ x: ancestorRect.width - clippedRelLeft,
70054
+ y: 0,
70055
+ arcCenterX: ancestorRect.width - r - clippedRelLeft,
70056
+ arcCenterY: r - clippedRelTop
70057
+ },
70058
+ "right-bottom": {
70059
+ x: ancestorRect.width - clippedRelLeft,
70060
+ y: ancestorRect.height - clippedRelTop,
70061
+ arcCenterX: ancestorRect.width - r - clippedRelLeft,
70062
+ arcCenterY: ancestorRect.height - r - clippedRelTop
70063
+ },
70064
+ "bottom-left": {
70065
+ x: 0 - clippedRelLeft,
70066
+ y: ancestorRect.height - clippedRelTop,
70067
+ arcCenterX: r - clippedRelLeft,
70068
+ arcCenterY: ancestorRect.height - r - clippedRelTop
70069
+ },
70070
+ "left-top": {
70071
+ x: 0 - clippedRelLeft,
70072
+ y: 0,
70073
+ arcCenterX: r - clippedRelLeft,
70074
+ arcCenterY: r - clippedRelTop
70075
+ }
70076
+ };
70077
+ let exitIdx = edgeOrder.indexOf(exitEdge);
70078
+ const entryIdxTarget = edgeOrder.indexOf(entryEdge);
70079
+ while (exitIdx !== entryIdxTarget) {
70080
+ const nextIdx = (exitIdx + 1) % 4;
70081
+ const cornerKey = `${edgeOrder[exitIdx]}-${edgeOrder[nextIdx]}`;
70082
+ const hasArc = cornerHasArc[cornerKey];
70083
+ const cornerPos = cornerPositions[cornerKey];
70084
+ if (hasArc && cornerPos) {
70085
+ const arcCX = cornerPos.arcCenterX;
70086
+ const arcCY = cornerPos.arcCenterY;
70087
+ const arcSegs = 8;
70088
+ let startAngle, endAngle;
70089
+ switch (cornerKey) {
70090
+ case "top-right":
70091
+ startAngle = -Math.PI / 2;
70092
+ endAngle = 0;
70093
+ break;
70094
+ case "right-bottom":
70095
+ startAngle = 0;
70096
+ endAngle = Math.PI / 2;
70097
+ break;
70098
+ case "bottom-left":
70099
+ startAngle = Math.PI / 2;
70100
+ endAngle = Math.PI;
70101
+ break;
70102
+ case "left-top":
70103
+ startAngle = Math.PI;
70104
+ endAngle = Math.PI * 1.5;
70105
+ break;
70106
+ default:
70107
+ startAngle = 0;
70108
+ endAngle = Math.PI / 2;
70109
+ }
70110
+ for (let ai = 0; ai <= arcSegs; ai++) {
70111
+ const t = ai / arcSegs;
70112
+ const angle = startAngle + t * (endAngle - startAngle);
70113
+ const arcX = arcCX + r * Math.cos(angle);
70114
+ const arcY = arcCY + r * Math.sin(angle);
70115
+ if (arcX >= -0.5 && arcX <= w2 + 0.5 && arcY >= -0.5 && arcY <= h2 + 0.5) {
70116
+ const clampedX = Math.max(0, Math.min(w2, arcX));
70117
+ const clampedY = Math.max(0, Math.min(h2, arcY));
70118
+ if (finalPoints.length > 0) {
70119
+ const last = finalPoints[finalPoints.length - 1];
70120
+ if (Math.abs(clampedX - last.x) < 0.5 && Math.abs(clampedY - last.y) < 0.5)
70121
+ continue;
70122
+ }
70123
+ finalPoints.push({ x: clampedX, y: clampedY });
70124
+ }
70125
+ }
70126
+ } else if (cornerPos) {
70127
+ const clampedX = Math.max(0, Math.min(w2, cornerPos.x));
70128
+ const clampedY = Math.max(0, Math.min(h2, cornerPos.y));
70129
+ finalPoints.push({ x: clampedX, y: clampedY });
70130
+ }
70131
+ exitIdx = nextIdx;
70132
+ }
70133
+ }
70134
+ }
70135
+ if (finalPoints.length >= 3) {
70136
+ if (DEBUG_OVERFLOW) {
70137
+ console.log("[OverflowClip] finalPoints count:", finalPoints.length);
70138
+ console.log("[OverflowClip] first 3 points:", JSON.stringify(finalPoints.slice(0, 3)));
70139
+ console.log("[OverflowClip] last 3 points:", JSON.stringify(finalPoints.slice(-3)));
70140
+ }
70141
+ for (let i = 0; i < finalPoints.length; i++) {
70142
+ points.push({
70143
+ x: Math.round(finalPoints[i].x * EMU_PER_PX3),
70144
+ y: Math.round(finalPoints[i].y * EMU_PER_PX3),
70145
+ ...i === 0 ? { moveTo: true } : {}
70146
+ });
70147
+ }
70148
+ points.push({ x: points[0].x, y: points[0].y, close: true });
70149
+ }
70150
+ }
70151
+ } else if (!isEllipse) {
70152
+ const elementBorderRadius = parseFloat(borderRadiusStr) || 0;
70153
+ const elemR = elementBorderRadius;
70154
+ const addElementCornerArc = (isRight, isBottom) => {
70155
+ if (elemR <= 0)
70156
+ return;
70157
+ for (let i = 0; i <= segments; i++) {
70158
+ const t = i / segments;
70159
+ const angle = t * Math.PI / 2;
70160
+ let arcX, arcY;
70161
+ if (!isRight && !isBottom) {
70162
+ arcX = elemR * Math.cos(angle);
70163
+ arcY = elemR * Math.sin(angle);
70164
+ } else if (!isRight && isBottom) {
70165
+ arcX = elemR - elemR * Math.cos(angle);
70166
+ arcY = h2 - elemR + elemR * Math.sin(angle);
70167
+ } else if (isRight && isBottom) {
70168
+ arcX = w2 - elemR + elemR * Math.sin(angle);
70169
+ arcY = h2 - elemR + elemR * Math.cos(angle);
70170
+ } else {
70171
+ arcX = w2 - elemR + elemR * Math.cos(angle);
70172
+ arcY = elemR - elemR * Math.sin(angle);
70173
+ }
70174
+ points.push({
70175
+ x: Math.round(arcX * EMU_PER_PX3),
70176
+ y: Math.round(arcY * EMU_PER_PX3),
70177
+ ...points.length === 0 ? { moveTo: true } : {}
70178
+ });
70179
+ }
70180
+ };
70181
+ const atLeftClipBoundary = wasClippedToParent && clippedRelLeft <= 0.1;
70182
+ const atTopClipBoundary = wasClippedToParent && clippedRelTop <= 0.1;
70183
+ const atRightClipBoundary = wasClippedToParent && clippedRelRight >= ancestorRect.width - 0.1;
70184
+ const atBottomClipBoundary = wasClippedToParent && clippedRelBottom >= ancestorRect.height - 0.1;
70185
+ if (overlapsTL) {
70186
+ addCornerArc(0, 0, false, false, true);
70187
+ } else if (elemR > 0 && !atLeftClipBoundary && !atTopClipBoundary) {
70188
+ addElementCornerArc(false, false);
70189
+ } else {
70190
+ points.push({ x: 0, y: 0, moveTo: true });
70191
+ }
70192
+ if (overlapsBL) {
70193
+ addCornerArc(0, ancestorRect.height, false, true, true);
70194
+ } else if (elemR > 0 && !atLeftClipBoundary && !atBottomClipBoundary) {
70195
+ addElementCornerArc(false, true);
70196
+ } else {
70197
+ points.push({ x: 0, y: heightEmu });
70198
+ }
70199
+ if (overlapsBR) {
70200
+ addCornerArc(ancestorRect.width, ancestorRect.height, true, true, true);
70201
+ } else if (elemR > 0 && !atRightClipBoundary && !atBottomClipBoundary) {
70202
+ addElementCornerArc(true, true);
70203
+ } else {
70204
+ points.push({ x: widthEmu, y: heightEmu });
70205
+ }
70206
+ if (overlapsTR) {
70207
+ addCornerArc(ancestorRect.width, 0, true, false, true);
70208
+ } else if (elemR > 0 && !atRightClipBoundary && !atTopClipBoundary) {
70209
+ addElementCornerArc(true, false);
70210
+ } else {
70211
+ points.push({ x: widthEmu, y: 0 });
70212
+ }
70213
+ points.push({ x: 0, y: 0, close: true });
70214
+ }
70215
+ if (points.length > 5) {
70216
+ overflowClipGeometry = points;
70217
+ if (DEBUG_OVERFLOW)
70218
+ console.log("[OverflowClip] Generated custom geometry with", points.length, "points");
70219
+ } else {
70220
+ if (DEBUG_OVERFLOW)
70221
+ console.log("[OverflowClip] Not enough points for custom geometry:", points.length);
70222
+ }
70223
+ }
70224
+ }
70225
+ break;
70226
+ }
70227
+ overflowAncestor = overflowAncestor.parentElement;
70228
+ }
70229
+ let originalShapeW = shapeW;
70230
+ let originalShapeH = shapeH;
70231
+ if (wasClippedToParent) {
70232
+ originalShapeW = shapeW;
70233
+ originalShapeH = shapeH;
70234
+ shapeX = clippedShapeX;
70235
+ shapeY = clippedShapeY;
70236
+ shapeW = clippedShapeW;
70237
+ shapeH = clippedShapeH;
70238
+ }
70239
+ const hasTextContent = shapeText || shapeTextRuns && shapeTextRuns.length > 0;
70240
+ const shouldSplitTextFromClippedShape = overflowClipGeometry && hasTextContent;
67943
70241
  const shapeElement = {
67944
70242
  type: "shape",
67945
- text: shapeText,
67946
- textRuns: shapeTextRuns,
67947
- style: shapeStyle,
70243
+ // If splitting text from clipped shape, don't include text in the main shape
70244
+ text: shouldSplitTextFromClippedShape ? "" : shapeText,
70245
+ textRuns: shouldSplitTextFromClippedShape ? null : shapeTextRuns,
70246
+ style: shouldSplitTextFromClippedShape ? null : shapeStyle,
67948
70247
  position: {
67949
70248
  x: pxToInch(shapeX),
67950
70249
  y: pxToInch(shapeY),
@@ -67983,7 +70282,8 @@ ${generateStylesCss(styleMap, themeFonts)}
67983
70282
  isEllipse,
67984
70283
  softEdge: softEdgePt,
67985
70284
  rotate: rotationAngle,
67986
- customGeometry: clipPathPolygon ? (() => {
70285
+ cssTriangle: null,
70286
+ customGeometry: overflowClipGeometry ? overflowClipGeometry : clipPathPolygon ? (() => {
67987
70287
  const EMU2 = 914400;
67988
70288
  const pathW = Math.round(shapeW / PX_PER_IN * EMU2);
67989
70289
  const pathH = Math.round(shapeH / PX_PER_IN * EMU2);
@@ -67998,11 +70298,12 @@ ${generateStylesCss(styleMap, themeFonts)}
67998
70298
  points.push({ x: 0, y: 0, close: true });
67999
70299
  return points;
68000
70300
  })() : null
68001
- }
70301
+ },
70302
+ zIndex: extractZIndex(computed2)
68002
70303
  };
68003
70304
  if (hasPadding && shapeElement.style && (shapeText || shapeTextRuns && shapeTextRuns.length > 0)) {
68004
70305
  let effectiveLeftPadding = paddingLeft;
68005
- if (hasDirectText && allChildren.length > 0) {
70306
+ if (hasDirectText && allChildren.length > 0 && !hasMixedInlineContent) {
68006
70307
  for (const child of allChildren) {
68007
70308
  if (child.nodeType === Node.ELEMENT_NODE) {
68008
70309
  const childEl = child;
@@ -68029,6 +70330,76 @@ ${generateStylesCss(styleMap, themeFonts)}
68029
70330
  ];
68030
70331
  }
68031
70332
  elements.push(shapeElement);
70333
+ if (!shouldMergeText && textChildren.length > 0) {
70334
+ textChildren.forEach((tc) => {
70335
+ processed.delete(tc);
70336
+ tc.querySelectorAll("*").forEach((desc) => processed.delete(desc));
70337
+ });
70338
+ }
70339
+ if (shouldSplitTextFromClippedShape && overflowClipGeometry) {
70340
+ const originalArea = originalShapeW * originalShapeH;
70341
+ const clippedArea = clippedShapeW * clippedShapeH;
70342
+ const visiblePercent = clippedArea / originalArea * 100;
70343
+ if (DEBUG_OVERFLOW)
70344
+ console.log("[OverflowClip] Text shape visibility:", {
70345
+ originalShapeW,
70346
+ originalShapeH,
70347
+ originalArea,
70348
+ clippedShapeW,
70349
+ clippedShapeH,
70350
+ clippedArea,
70351
+ visiblePercent: visiblePercent.toFixed(1) + "%"
70352
+ });
70353
+ if (visiblePercent >= 50) {
70354
+ const clippedTextShape = {
70355
+ type: "shape",
70356
+ text: shapeText,
70357
+ textRuns: shapeTextRuns,
70358
+ style: shapeStyle,
70359
+ position: {
70360
+ // Use clipped dimensions to constrain text to visible area
70361
+ x: pxToInch(clippedShapeX),
70362
+ y: pxToInch(clippedShapeY),
70363
+ w: pxToInch(clippedShapeW),
70364
+ h: pxToInch(clippedShapeH)
70365
+ },
70366
+ shape: {
70367
+ fill: null,
70368
+ // No fill - just text
70369
+ gradient: null,
70370
+ transparency: null,
70371
+ line: null,
70372
+ rectRadius: 0,
70373
+ shadow: null,
70374
+ opacity: null,
70375
+ isEllipse: false,
70376
+ softEdge: null,
70377
+ rotate: null,
70378
+ cssTriangle: null,
70379
+ customGeometry: null
70380
+ // NO custom geometry - PPTX doesn't clip text to paths
70381
+ }
70382
+ };
70383
+ if (hasPadding && clippedTextShape.style) {
70384
+ clippedTextShape.style.margin = [
70385
+ paddingLeft * PT_PER_PX,
70386
+ // left
70387
+ paddingRight * PT_PER_PX,
70388
+ // right
70389
+ paddingBottom * PT_PER_PX,
70390
+ // bottom
70391
+ paddingTop * PT_PER_PX
70392
+ // top
70393
+ ];
70394
+ }
70395
+ elements.push(clippedTextShape);
70396
+ if (DEBUG_OVERFLOW)
70397
+ console.log("[OverflowClip] Created separate clipped text shape for:", shapeText);
70398
+ } else {
70399
+ if (DEBUG_OVERFLOW)
70400
+ console.log("[OverflowClip] Skipping text (visible area too small):", shapeText);
70401
+ }
70402
+ }
68032
70403
  if (extraDivGradients.length > 0) {
68033
70404
  for (const extraGrad of extraDivGradients) {
68034
70405
  const extraShape = {
@@ -68048,6 +70419,7 @@ ${generateStylesCss(styleMap, themeFonts)}
68048
70419
  isEllipse: false,
68049
70420
  softEdge: null,
68050
70421
  rotate: null,
70422
+ cssTriangle: null,
68051
70423
  customGeometry: null
68052
70424
  }
68053
70425
  };
@@ -68090,6 +70462,7 @@ ${generateStylesCss(styleMap, themeFonts)}
68090
70462
  isEllipse: false,
68091
70463
  softEdge: null,
68092
70464
  rotate: null,
70465
+ cssTriangle: null,
68093
70466
  customGeometry: null
68094
70467
  }
68095
70468
  };
@@ -68102,7 +70475,7 @@ ${generateStylesCss(styleMap, themeFonts)}
68102
70475
  tc.querySelectorAll("*").forEach((desc) => processed.delete(desc));
68103
70476
  });
68104
70477
  }
68105
- elements.push(...borderLines);
70478
+ elements.push(...borderShapes);
68106
70479
  processed.add(el);
68107
70480
  return;
68108
70481
  }
@@ -68200,16 +70573,29 @@ ${generateStylesCss(styleMap, themeFonts)}
68200
70573
  const textHeight = rect2.height;
68201
70574
  let textRuns;
68202
70575
  const isFlexColumn = (plainDivDisplay === "flex" || plainDivDisplay === "inline-flex") && (plainDivFlexDir === "column" || plainDivFlexDir === "column-reverse") && childElements.length > 1;
70576
+ const baseRunOptions = {
70577
+ fontSize: pxToPoints(computed22.fontSize),
70578
+ fontFace: extractFontFace(computed22.fontFamily),
70579
+ color: rgbToHex(computed22.color)
70580
+ };
70581
+ if (parseInt(computed22.fontWeight) >= 600)
70582
+ baseRunOptions.bold = true;
70583
+ if (computed22.fontStyle === "italic")
70584
+ baseRunOptions.italic = true;
70585
+ const colorAlphaTransparency2 = extractAlpha(computed22.color);
70586
+ const elementOpacityVal = getEffectiveOpacity(el, win);
70587
+ if (colorAlphaTransparency2 !== null || elementOpacityVal < 1) {
70588
+ let runTransparency = colorAlphaTransparency2 !== null ? colorAlphaTransparency2 : 0;
70589
+ if (elementOpacityVal < 1) {
70590
+ const existingOpacity = 1 - runTransparency / 100;
70591
+ const combinedOpacity = existingOpacity * elementOpacityVal;
70592
+ runTransparency = Math.round((1 - combinedOpacity) * 100);
70593
+ }
70594
+ if (runTransparency > 0) {
70595
+ baseRunOptions.transparency = runTransparency;
70596
+ }
70597
+ }
68203
70598
  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
70599
  let textTransformFn = (s) => s;
68214
70600
  if (computed22.textTransform && computed22.textTransform !== "none") {
68215
70601
  textTransformFn = (text2) => applyTextTransform2(text2, computed22.textTransform);
@@ -68233,6 +70619,12 @@ ${generateStylesCss(styleMap, themeFonts)}
68233
70619
  const childColor = rgbToHex(childComputed.color);
68234
70620
  if (childColor)
68235
70621
  childRunOptions.color = childColor;
70622
+ const childColorTransparency = extractAlpha(childComputed.color);
70623
+ if (childColorTransparency !== null) {
70624
+ childRunOptions.transparency = childColorTransparency;
70625
+ } else {
70626
+ delete childRunOptions.transparency;
70627
+ }
68236
70628
  if (parseInt(childComputed.fontWeight) >= 600) {
68237
70629
  childRunOptions.bold = true;
68238
70630
  } else if (parseInt(childComputed.fontWeight) < 600) {
@@ -68250,13 +70642,14 @@ ${generateStylesCss(styleMap, themeFonts)}
68250
70642
  textRuns.push({ text: textWithBreak, options: childRunOptions });
68251
70643
  }
68252
70644
  } else {
68253
- textRuns = parseInlineFormatting(el, baseRunOptions, [], textTransformFn, win);
70645
+ const elPreserveWs = shouldPreserveWhitespace(computed22);
70646
+ textRuns = parseInlineFormatting(el, baseRunOptions, [], textTransformFn, win, elPreserveWs);
68254
70647
  }
68255
70648
  if (textRuns.length === 0) {
68256
- textRuns = [{ text: extractedText, options: {} }];
70649
+ textRuns = [{ text: extractedText, options: baseRunOptions }];
68257
70650
  }
68258
70651
  } else {
68259
- textRuns = [{ text: extractedText, options: {} }];
70652
+ textRuns = [{ text: extractedText, options: baseRunOptions }];
68260
70653
  }
68261
70654
  const paddingTop = parseFloat(computed22.paddingTop) || 0;
68262
70655
  const paddingRight = parseFloat(computed22.paddingRight) || 0;
@@ -68284,9 +70677,8 @@ ${generateStylesCss(styleMap, themeFonts)}
68284
70677
  margin: hasPadding ? [paddingLeft * PT_PER_PX, paddingRight * PT_PER_PX, paddingBottom * PT_PER_PX, paddingTop * PT_PER_PX] : void 0
68285
70678
  }
68286
70679
  };
68287
- const textTransparency = extractAlpha(computed22.color);
68288
- if (textTransparency !== null) {
68289
- textElement.style.transparency = textTransparency;
70680
+ if (baseRunOptions.transparency !== void 0 && baseRunOptions.transparency > 0) {
70681
+ textElement.style.transparency = baseRunOptions.transparency;
68290
70682
  }
68291
70683
  const ls = extractLetterSpacing(computed22);
68292
70684
  if (ls !== null)
@@ -68337,7 +70729,8 @@ ${generateStylesCss(styleMap, themeFonts)}
68337
70729
  const liPaddingLeft = parseFloat(liComputed2.paddingLeft) || 0;
68338
70730
  const textLeft = liRect.left + liPaddingLeft;
68339
70731
  const textWidth = liRect.width - liPaddingLeft;
68340
- const runs = parseInlineFormatting(liEl, { breakLine: false }, [], (x2) => x2, win);
70732
+ const liPreserveWs = shouldPreserveWhitespace(liComputed2);
70733
+ const runs = parseInlineFormatting(liEl, { breakLine: false }, [], (x2) => x2, win, liPreserveWs);
68341
70734
  if (runs.length === 0)
68342
70735
  return;
68343
70736
  runs[0].text = runs[0].text.replace(/^[•\-*\u25AA\u25B8]\s*/, "");
@@ -68368,7 +70761,10 @@ ${generateStylesCss(styleMap, themeFonts)}
68368
70761
  }
68369
70762
  liElements.forEach((li, idx) => {
68370
70763
  const isLast = idx === liElements.length - 1;
68371
- const runs = parseInlineFormatting(li, { breakLine: false }, [], (x2) => x2, win);
70764
+ const liEl = li;
70765
+ const liItemComputed = win.getComputedStyle(liEl);
70766
+ const liItemPreserveWs = shouldPreserveWhitespace(liItemComputed);
70767
+ const runs = parseInlineFormatting(li, { breakLine: false }, [], (x2) => x2, win, liItemPreserveWs);
68372
70768
  if (runs.length > 0) {
68373
70769
  runs[0].text = runs[0].text.replace(/^[•\-*\u25AA\u25B8]\s*/, "");
68374
70770
  if (hasNativeBullets) {
@@ -68414,9 +70810,40 @@ ${generateStylesCss(styleMap, themeFonts)}
68414
70810
  return;
68415
70811
  let rect = htmlEl.getBoundingClientRect();
68416
70812
  const computed = win.getComputedStyle(el);
68417
- let text = getTransformedText(htmlEl, computed);
70813
+ let effectiveComputedForWhitespace = computed;
70814
+ const pParentEl = htmlEl.parentElement;
70815
+ if (el.tagName === "P" && pParentEl && pParentEl.tagName === "DIV") {
70816
+ const pParentChildren = Array.from(pParentEl.children);
70817
+ const nonBrChildren = pParentChildren.filter((c) => c.tagName !== "BR");
70818
+ if (nonBrChildren.length === 1 && nonBrChildren[0] === el) {
70819
+ const pParentComputed = win.getComputedStyle(pParentEl);
70820
+ if (isMonospaceFont(pParentComputed.fontFamily)) {
70821
+ effectiveComputedForWhitespace = pParentComputed;
70822
+ }
70823
+ }
70824
+ }
70825
+ let text = getTransformedText(htmlEl, effectiveComputedForWhitespace);
68418
70826
  if (rect.width === 0 || rect.height === 0 || !text)
68419
70827
  return;
70828
+ let effectiveFontSizeForOverflow = computed.fontSize;
70829
+ let effectiveLineHeightForOverflow = computed.lineHeight;
70830
+ if (el.tagName === "P" && pParentEl && pParentEl.tagName === "DIV") {
70831
+ const pParentChildren = Array.from(pParentEl.children);
70832
+ const nonBrChildren = pParentChildren.filter((c) => c.tagName !== "BR");
70833
+ if (nonBrChildren.length === 1 && nonBrChildren[0] === el) {
70834
+ const pParentComputedForOverflow = win.getComputedStyle(pParentEl);
70835
+ effectiveFontSizeForOverflow = pParentComputedForOverflow.fontSize;
70836
+ effectiveLineHeightForOverflow = pParentComputedForOverflow.lineHeight;
70837
+ }
70838
+ }
70839
+ const earlyFontSizePx = parseFloat(effectiveFontSizeForOverflow);
70840
+ const earlyLineHeightPx = parseFloat(effectiveLineHeightForOverflow);
70841
+ if (!isNaN(earlyFontSizePx) && !isNaN(earlyLineHeightPx) && earlyLineHeightPx < earlyFontSizePx) {
70842
+ const lineHeightOverflowOffsetPx = earlyFontSizePx - earlyLineHeightPx;
70843
+ const minHeightPx = earlyFontSizePx * 1.3;
70844
+ const newHeight = Math.max(rect.height, minHeightPx);
70845
+ rect = new DOMRect(rect.x, rect.y + lineHeightOverflowOffsetPx, rect.width, newHeight);
70846
+ }
68420
70847
  const isFlexContainer = computed.display === "flex" || computed.display === "inline-flex";
68421
70848
  let flexContentChild = null;
68422
70849
  if (isFlexContainer && el.children.length > 0) {
@@ -68505,13 +70932,39 @@ ${generateStylesCss(styleMap, themeFonts)}
68505
70932
  valign = "middle";
68506
70933
  }
68507
70934
  }
70935
+ if (!isNaN(earlyFontSizePx) && !isNaN(earlyLineHeightPx) && earlyLineHeightPx < earlyFontSizePx) {
70936
+ valign = "top";
70937
+ }
70938
+ let effectiveColor = computed.color;
70939
+ let effectiveFontFamily = computed.fontFamily;
70940
+ let effectiveFontSize = computed.fontSize;
70941
+ if (el.tagName === "P" && parentEl && parentEl.tagName === "DIV") {
70942
+ const parentChildren = Array.from(parentEl.children);
70943
+ const nonBrChildren = parentChildren.filter((c) => c.tagName !== "BR");
70944
+ if (nonBrChildren.length === 1 && nonBrChildren[0] === el) {
70945
+ const parentComputed = win.getComputedStyle(parentEl);
70946
+ if (parentComputed.color !== computed.color && parentComputed.color !== "rgb(0, 0, 0)") {
70947
+ effectiveColor = parentComputed.color;
70948
+ }
70949
+ if (parentComputed.fontFamily !== computed.fontFamily) {
70950
+ if (isMonospaceFont(parentComputed.fontFamily)) {
70951
+ effectiveFontFamily = parentComputed.fontFamily;
70952
+ }
70953
+ }
70954
+ if (parentComputed.fontSize !== computed.fontSize) {
70955
+ if (isMonospaceFont(parentComputed.fontFamily)) {
70956
+ effectiveFontSize = parentComputed.fontSize;
70957
+ }
70958
+ }
70959
+ }
70960
+ }
68508
70961
  const baseStyle = {
68509
- fontSize: pxToPoints(computed.fontSize),
68510
- fontFace: extractFontFace(computed.fontFamily),
68511
- color: rgbToHex(computed.color),
70962
+ fontSize: pxToPoints(effectiveFontSize),
70963
+ fontFace: extractFontFace(effectiveFontFamily),
70964
+ color: rgbToHex(effectiveColor),
68512
70965
  align: textAlign,
68513
70966
  valign,
68514
- lineSpacing: pxToPoints(computed.fontSize) * lineHeightMultiplier,
70967
+ lineSpacing: pxToPoints(effectiveFontSize) * lineHeightMultiplier,
68515
70968
  paraSpaceBefore: pxToPoints(computed.marginTop),
68516
70969
  paraSpaceAfter: pxToPoints(computed.marginBottom),
68517
70970
  margin: [
@@ -68521,9 +70974,19 @@ ${generateStylesCss(styleMap, themeFonts)}
68521
70974
  pxToPoints(computed.paddingTop)
68522
70975
  ]
68523
70976
  };
68524
- const transparency = extractAlpha(computed.color);
68525
- if (transparency !== null)
68526
- baseStyle.transparency = transparency;
70977
+ const colorAlphaTransparency = extractAlpha(effectiveColor);
70978
+ const effectiveOpacity = getEffectiveOpacity(el, win);
70979
+ if (colorAlphaTransparency !== null || effectiveOpacity < 1) {
70980
+ let finalTransparency = colorAlphaTransparency !== null ? colorAlphaTransparency : 0;
70981
+ if (effectiveOpacity < 1) {
70982
+ const existingOpacity = 1 - finalTransparency / 100;
70983
+ const combinedOpacity = existingOpacity * effectiveOpacity;
70984
+ finalTransparency = Math.round((1 - combinedOpacity) * 100);
70985
+ }
70986
+ if (finalTransparency > 0) {
70987
+ baseStyle.transparency = finalTransparency;
70988
+ }
70989
+ }
68527
70990
  const letterSpacing = extractLetterSpacing(computed);
68528
70991
  if (letterSpacing !== null)
68529
70992
  baseStyle.charSpacing = letterSpacing;
@@ -68548,10 +71011,16 @@ ${generateStylesCss(styleMap, themeFonts)}
68548
71011
  }
68549
71012
  }
68550
71013
  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");
71014
+ 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
71015
  if (hasFormatting) {
68553
71016
  const transformStr = computed.textTransform;
68554
- const runs = parseInlineFormatting(formattingRoot, {}, [], (str) => applyTextTransform2(str, transformStr), win);
71017
+ const textPreserveWs = shouldPreserveWhitespace(effectiveComputedForWhitespace);
71018
+ const baseRunOptions = {
71019
+ fontSize: baseStyle.fontSize,
71020
+ fontFace: baseStyle.fontFace,
71021
+ color: baseStyle.color ?? void 0
71022
+ };
71023
+ const runs = parseInlineFormatting(formattingRoot, baseRunOptions, [], (str) => applyTextTransform2(str, transformStr), win, textPreserveWs);
68555
71024
  const textElement = {
68556
71025
  type: el.tagName.toLowerCase(),
68557
71026
  text: runs,
@@ -68601,6 +71070,11 @@ ${generateStylesCss(styleMap, themeFonts)}
68601
71070
  const pseudoElements = extractPseudoElements(htmlDiv, win);
68602
71071
  elements.push(...pseudoElements);
68603
71072
  });
71073
+ elements.sort((a, b) => {
71074
+ const zIndexA = "zIndex" in a && a.zIndex !== void 0 ? a.zIndex : 0;
71075
+ const zIndexB = "zIndex" in b && b.zIndex !== void 0 ? b.zIndex : 0;
71076
+ return zIndexA - zIndexB;
71077
+ });
68604
71078
  return { background, elements, placeholders, errors };
68605
71079
  }
68606
71080
 
@@ -68847,7 +71321,24 @@ ${generateStylesCss(styleMap, themeFonts)}
68847
71321
  } else if (el.type === "shape") {
68848
71322
  let shapeType = pres.ShapeType.rect;
68849
71323
  let customGeometryPoints;
68850
- if (el.shape.customGeometry && el.shape.customGeometry.length > 0) {
71324
+ let triangleRotation = null;
71325
+ if (el.shape.cssTriangle) {
71326
+ shapeType = pres.ShapeType.triangle;
71327
+ switch (el.shape.cssTriangle.direction) {
71328
+ case "up":
71329
+ triangleRotation = 0;
71330
+ break;
71331
+ case "down":
71332
+ triangleRotation = 180;
71333
+ break;
71334
+ case "left":
71335
+ triangleRotation = 270;
71336
+ break;
71337
+ case "right":
71338
+ triangleRotation = 90;
71339
+ break;
71340
+ }
71341
+ } else if (el.shape.customGeometry && el.shape.customGeometry.length > 0) {
68851
71342
  shapeType = pres.ShapeType.custGeom;
68852
71343
  customGeometryPoints = el.shape.customGeometry;
68853
71344
  } else if (el.shape.isEllipse) {
@@ -68946,8 +71437,10 @@ ${generateStylesCss(styleMap, themeFonts)}
68946
71437
  shapeOptions.shadow = el.shape.shadow;
68947
71438
  if (el.shape.softEdge)
68948
71439
  shapeOptions.softEdgeRad = el.shape.softEdge;
68949
- if (el.shape.rotate)
68950
- shapeOptions.rotate = el.shape.rotate;
71440
+ const cssRotation = el.shape.rotate ?? 0;
71441
+ const totalRotation = cssRotation + (triangleRotation ?? 0);
71442
+ if (totalRotation !== 0)
71443
+ shapeOptions.rotate = totalRotation;
68951
71444
  if (el.style) {
68952
71445
  if (el.style.fontSize)
68953
71446
  shapeOptions.fontSize = el.style.fontSize;
@@ -68976,6 +71469,11 @@ ${generateStylesCss(styleMap, themeFonts)}
68976
71469
  shapeOptions.inset = el.style.inset;
68977
71470
  if (el.style.charSpacing)
68978
71471
  shapeOptions.charSpacing = el.style.charSpacing;
71472
+ if (el.style.lineSpacing)
71473
+ shapeOptions.lineSpacing = el.style.lineSpacing;
71474
+ if (el.style.transparency !== null && el.style.transparency !== void 0) {
71475
+ shapeOptions.transparency = el.style.transparency;
71476
+ }
68979
71477
  if (el.style.glow) {
68980
71478
  shapeOptions.glow = {
68981
71479
  size: el.style.glow.size,
@@ -68995,10 +71493,14 @@ ${generateStylesCss(styleMap, themeFonts)}
68995
71493
  } else if (el.type === "list") {
68996
71494
  const heightIncrease = el.position.h * 0.15;
68997
71495
  const adjustedH = el.position.h + heightIncrease;
71496
+ const fontSize = el.style.fontSize ?? 12;
71497
+ const bufferPercent = fontSize < 14 ? 0.1 : fontSize < 24 ? 0.07 : 0.05;
71498
+ const widthIncrease = el.position.w * bufferPercent;
71499
+ const adjustedW = el.position.w + widthIncrease;
68998
71500
  const listOptions = {
68999
71501
  x: el.position.x,
69000
71502
  y: el.position.y,
69001
- w: el.position.w,
71503
+ w: adjustedW,
69002
71504
  h: adjustedH,
69003
71505
  fontSize: el.style.fontSize,
69004
71506
  fontFace: el.style.fontFace,
@@ -69019,13 +71521,15 @@ ${generateStylesCss(styleMap, themeFonts)}
69019
71521
  } else {
69020
71522
  const lineHeightPt = el.style.lineSpacing || (el.style.fontSize ?? 0) * 1.2;
69021
71523
  const heightPt = el.position.h * 72;
69022
- const isSingleLine = heightPt <= lineHeightPt * 1.5;
71524
+ const textContent2 = typeof el.text === "string" ? el.text : Array.isArray(el.text) ? el.text.map((r) => r.text).join("") : "";
71525
+ const hasNewlines = textContent2.includes("\n");
71526
+ const isSingleLine = !hasNewlines && heightPt <= lineHeightPt * 1.5;
69023
71527
  let adjustedX = el.position.x;
69024
71528
  let adjustedW;
69025
71529
  let adjustedH = el.position.h;
69026
71530
  if (isSingleLine) {
69027
71531
  const fontSize = el.style.fontSize ?? 12;
69028
- const bufferPercent = fontSize > 36 ? 0.02 : fontSize > 24 ? 0.015 : 0.01;
71532
+ const bufferPercent = fontSize < 14 ? 0.1 : fontSize < 24 ? 0.07 : 0.05;
69029
71533
  const widthIncrease = el.position.w * bufferPercent;
69030
71534
  const align = el.style.align;
69031
71535
  if (align === "center") {
@@ -69049,7 +71553,7 @@ ${generateStylesCss(styleMap, themeFonts)}
69049
71553
  } else {
69050
71554
  adjustedW = el.position.w + widthIncrease;
69051
71555
  }
69052
- const heightIncrease = el.position.h * 0.05;
71556
+ const heightIncrease = hasNewlines ? el.position.h * 1 : el.position.h * 0.05;
69053
71557
  adjustedH = el.position.h + heightIncrease;
69054
71558
  }
69055
71559
  const textOptions = {
@@ -69404,7 +71908,7 @@ ${validationErrors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`;
69404
71908
  }
69405
71909
  html = html.slice(0, start) + html.slice(i);
69406
71910
  }
69407
- html = html.replace(/opacity:\s*0\s*;?(?=\s*[}]|;)/g, "opacity: 1;");
71911
+ html = html.replace(/opacity:\s*0\s*(;?)(?=\s*[}";])/g, "opacity: 1$1");
69408
71912
  html = html.replace(/transition:\s*[^;}]+;?/g, "");
69409
71913
  html = html.replace(/pointer-events:\s*[^;}]+;?/g, "");
69410
71914
  const bodyBlockMatch = html.match(/body\s*\{([^}]*)\}/s);
@@ -76127,8 +78631,11 @@ ${String(ex)}`);
76127
78631
  } else if (opts.color) {
76128
78632
  runProps += genXmlColorSelection({ color: opts.color, transparency: opts.transparency });
76129
78633
  }
76130
- if (opts.highlight)
76131
- runProps += `<a:highlight>${createColorElement(opts.highlight)}</a:highlight>`;
78634
+ if (opts.highlight) {
78635
+ var highlightColor = typeof opts.highlight === "object" ? opts.highlight.color : opts.highlight;
78636
+ var highlightAlpha = typeof opts.highlight === "object" && opts.highlight.transparency != null ? `<a:alpha val="${Math.round((100 - opts.highlight.transparency) * 1e3)}"/>` : "";
78637
+ runProps += `<a:highlight>${createColorElement(highlightColor, highlightAlpha)}</a:highlight>`;
78638
+ }
76132
78639
  if (typeof opts.underline === "object" && opts.underline.color)
76133
78640
  runProps += `<a:uFill>${genXmlColorSelection(opts.underline.color)}</a:uFill>`;
76134
78641
  if (opts.glow)