pptx-react-viewer 4.26.0 → 4.27.0

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 (172) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/{AiChatPanel-TIJ3MRTR.mjs → AiChatPanel-3J6XGIJ4.mjs} +3 -7
  3. package/dist/AiChatPanel-3J6XGIJ4.mjs.br +0 -0
  4. package/dist/AiChatPanel-3J6XGIJ4.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-PGZDMW4M.js → AiChatPanel-EGTSK4T5.js} +27 -31
  6. package/dist/AiChatPanel-EGTSK4T5.js.br +0 -0
  7. package/dist/AiChatPanel-EGTSK4T5.js.gz +0 -0
  8. package/dist/{Model3DScene-SJGIK2TB.mjs → Model3DScene-2V2GQ6FY.mjs} +2 -2
  9. package/dist/Model3DScene-2V2GQ6FY.mjs.br +0 -0
  10. package/dist/Model3DScene-2V2GQ6FY.mjs.gz +0 -0
  11. package/dist/{Model3DScene-LQBTZGVN.js → Model3DScene-Q3XEZSWV.js} +3 -3
  12. package/dist/Model3DScene-Q3XEZSWV.js.br +2 -0
  13. package/dist/Model3DScene-Q3XEZSWV.js.gz +0 -0
  14. package/dist/{UTIF-CNNXS5Z5.mjs → UTIF-RPFRSSC5.mjs} +3 -3
  15. package/dist/UTIF-RPFRSSC5.mjs.br +0 -0
  16. package/dist/UTIF-RPFRSSC5.mjs.gz +0 -0
  17. package/dist/{UTIF-6SHLXCNF.js → UTIF-XWCKRN6V.js} +21 -21
  18. package/dist/UTIF-XWCKRN6V.js.br +0 -0
  19. package/dist/UTIF-XWCKRN6V.js.gz +0 -0
  20. package/dist/{chunk-K564H64A.mjs → chunk-34AXBLYH.mjs} +51 -104
  21. package/dist/chunk-34AXBLYH.mjs.br +0 -0
  22. package/dist/chunk-34AXBLYH.mjs.gz +0 -0
  23. package/dist/{chunk-ZW2WNQN7.js → chunk-5RQTZ376.js} +1207 -1185
  24. package/dist/chunk-5RQTZ376.js.br +0 -0
  25. package/dist/chunk-5RQTZ376.js.gz +0 -0
  26. package/dist/{chunk-XGB3TDIC.mjs → chunk-6DZX6EAA.mjs} +1 -5
  27. package/dist/chunk-6DZX6EAA.mjs.br +0 -0
  28. package/dist/chunk-6DZX6EAA.mjs.gz +0 -0
  29. package/dist/{chunk-PW3YOZFA.js → chunk-MQCBMO6A.js} +909 -923
  30. package/dist/chunk-MQCBMO6A.js.br +0 -0
  31. package/dist/chunk-MQCBMO6A.js.gz +0 -0
  32. package/dist/{chunk-4VNS5WPM.js → chunk-QGM4M3NI.js} +0 -5
  33. package/dist/chunk-QGM4M3NI.js.br +0 -0
  34. package/dist/chunk-QGM4M3NI.js.gz +0 -0
  35. package/dist/{chunk-UHW3R465.js → chunk-TYJZJJZ6.mjs} +13071 -119039
  36. package/dist/chunk-TYJZJJZ6.mjs.br +0 -0
  37. package/dist/chunk-TYJZJJZ6.mjs.gz +0 -0
  38. package/dist/{chunk-LCWNHXHZ.mjs → chunk-WK6JBJCT.js} +13439 -117785
  39. package/dist/chunk-WK6JBJCT.js.br +0 -0
  40. package/dist/chunk-WK6JBJCT.js.gz +0 -0
  41. package/dist/{chunk-QJNZZBVF.mjs → chunk-ZK7UEEXE.mjs} +71 -92
  42. package/dist/chunk-ZK7UEEXE.mjs.br +0 -0
  43. package/dist/chunk-ZK7UEEXE.mjs.gz +0 -0
  44. package/dist/i18n.d.ts +1 -46
  45. package/dist/i18n.js +5 -5
  46. package/dist/i18n.js.br +2 -2
  47. package/dist/i18n.js.gz +0 -0
  48. package/dist/i18n.mjs +2 -2
  49. package/dist/i18n.mjs.br +0 -0
  50. package/dist/i18n.mjs.gz +0 -0
  51. package/dist/index.d.ts +11 -3703
  52. package/dist/index.js +96 -97
  53. package/dist/index.js.br +0 -0
  54. package/dist/index.js.gz +0 -0
  55. package/dist/index.mjs +6 -7
  56. package/dist/index.mjs.br +0 -0
  57. package/dist/index.mjs.gz +0 -0
  58. package/dist/internals.d.ts +5 -3847
  59. package/dist/internals.js +114 -115
  60. package/dist/internals.js.br +0 -0
  61. package/dist/internals.js.gz +0 -0
  62. package/dist/internals.mjs +4 -5
  63. package/dist/internals.mjs.br +0 -0
  64. package/dist/internals.mjs.gz +0 -0
  65. package/dist/{chunk-NJYF5KTY.mjs → three.module-A6ACXOES.mjs} +2 -0
  66. package/dist/three.module-A6ACXOES.mjs.br +0 -0
  67. package/dist/three.module-A6ACXOES.mjs.gz +0 -0
  68. package/dist/{chunk-QS3GAPPA.js → three.module-IORLGCSX.js} +2 -0
  69. package/dist/three.module-IORLGCSX.js.br +0 -0
  70. package/dist/three.module-IORLGCSX.js.gz +0 -0
  71. package/dist/viewer/index.d.ts +12 -2633
  72. package/dist/viewer/index.js +35 -37
  73. package/dist/viewer/index.js.br +0 -0
  74. package/dist/viewer/index.js.gz +0 -0
  75. package/dist/viewer/index.mjs +5 -7
  76. package/dist/viewer/index.mjs.br +0 -0
  77. package/dist/viewer/index.mjs.gz +0 -0
  78. package/dist/{y-webrtc-F2H7BRUK.js → y-webrtc-6LID3XZO.js} +5 -5
  79. package/dist/y-webrtc-6LID3XZO.js.br +0 -0
  80. package/dist/y-webrtc-6LID3XZO.js.gz +0 -0
  81. package/dist/{y-webrtc-GAHCEZSS.mjs → y-webrtc-F5IA7T5S.mjs} +1 -1
  82. package/dist/y-webrtc-F5IA7T5S.mjs.br +0 -0
  83. package/dist/y-webrtc-F5IA7T5S.mjs.gz +0 -0
  84. package/dist/{y-websocket-FBMB63F4.js → y-websocket-HOY2HFMH.js} +1 -1
  85. package/dist/y-websocket-HOY2HFMH.js.br +0 -0
  86. package/dist/y-websocket-HOY2HFMH.js.gz +0 -0
  87. package/dist/{y-websocket-MAGDFVLN.mjs → y-websocket-VGLBV2HJ.mjs} +1 -1
  88. package/dist/y-websocket-VGLBV2HJ.mjs.br +0 -0
  89. package/dist/y-websocket-VGLBV2HJ.mjs.gz +0 -0
  90. package/package.json +3 -4
  91. package/dist/AiChatPanel-PGZDMW4M.js.br +0 -0
  92. package/dist/AiChatPanel-PGZDMW4M.js.gz +0 -0
  93. package/dist/AiChatPanel-TIJ3MRTR.mjs.br +0 -0
  94. package/dist/AiChatPanel-TIJ3MRTR.mjs.gz +0 -0
  95. package/dist/GLTFLoader-O7FNKCHG.mjs +0 -2649
  96. package/dist/GLTFLoader-O7FNKCHG.mjs.br +0 -0
  97. package/dist/GLTFLoader-O7FNKCHG.mjs.gz +0 -0
  98. package/dist/GLTFLoader-UM56GMCK.js +0 -2651
  99. package/dist/GLTFLoader-UM56GMCK.js.br +0 -0
  100. package/dist/GLTFLoader-UM56GMCK.js.gz +0 -0
  101. package/dist/Model3DScene-LQBTZGVN.js.br +0 -0
  102. package/dist/Model3DScene-LQBTZGVN.js.gz +0 -0
  103. package/dist/Model3DScene-SJGIK2TB.mjs.br +0 -0
  104. package/dist/Model3DScene-SJGIK2TB.mjs.gz +0 -0
  105. package/dist/OrbitControls-EXEHIXFI.js +0 -922
  106. package/dist/OrbitControls-EXEHIXFI.js.br +0 -0
  107. package/dist/OrbitControls-EXEHIXFI.js.gz +0 -0
  108. package/dist/OrbitControls-PZQ4CBVS.mjs +0 -920
  109. package/dist/OrbitControls-PZQ4CBVS.mjs.br +0 -0
  110. package/dist/OrbitControls-PZQ4CBVS.mjs.gz +0 -0
  111. package/dist/UTIF-6SHLXCNF.js.br +0 -0
  112. package/dist/UTIF-6SHLXCNF.js.gz +0 -0
  113. package/dist/UTIF-CNNXS5Z5.mjs.br +0 -0
  114. package/dist/UTIF-CNNXS5Z5.mjs.gz +0 -0
  115. package/dist/chunk-4VNS5WPM.js.br +0 -0
  116. package/dist/chunk-4VNS5WPM.js.gz +0 -0
  117. package/dist/chunk-6HMJTCFO.js +0 -4247
  118. package/dist/chunk-6HMJTCFO.js.br +0 -0
  119. package/dist/chunk-6HMJTCFO.js.gz +0 -0
  120. package/dist/chunk-DKMPRUXL.mjs +0 -22197
  121. package/dist/chunk-DKMPRUXL.mjs.br +0 -0
  122. package/dist/chunk-DKMPRUXL.mjs.gz +0 -0
  123. package/dist/chunk-K564H64A.mjs.br +0 -0
  124. package/dist/chunk-K564H64A.mjs.gz +0 -0
  125. package/dist/chunk-LCWNHXHZ.mjs.br +0 -0
  126. package/dist/chunk-LCWNHXHZ.mjs.gz +0 -0
  127. package/dist/chunk-NJYF5KTY.mjs.br +0 -0
  128. package/dist/chunk-NJYF5KTY.mjs.gz +0 -0
  129. package/dist/chunk-NWZKMLGC.js +0 -22241
  130. package/dist/chunk-NWZKMLGC.js.br +0 -0
  131. package/dist/chunk-NWZKMLGC.js.gz +0 -0
  132. package/dist/chunk-PW3YOZFA.js.br +0 -0
  133. package/dist/chunk-PW3YOZFA.js.gz +0 -0
  134. package/dist/chunk-QJNZZBVF.mjs.br +0 -0
  135. package/dist/chunk-QJNZZBVF.mjs.gz +0 -0
  136. package/dist/chunk-QS3GAPPA.js.br +0 -0
  137. package/dist/chunk-QS3GAPPA.js.gz +0 -0
  138. package/dist/chunk-UHW3R465.js.br +0 -0
  139. package/dist/chunk-UHW3R465.js.gz +0 -0
  140. package/dist/chunk-USJXG5TE.mjs +0 -3915
  141. package/dist/chunk-USJXG5TE.mjs.br +0 -0
  142. package/dist/chunk-USJXG5TE.mjs.gz +0 -0
  143. package/dist/chunk-VEVEP7VF.js +0 -3977
  144. package/dist/chunk-VEVEP7VF.js.br +0 -0
  145. package/dist/chunk-VEVEP7VF.js.gz +0 -0
  146. package/dist/chunk-XGB3TDIC.mjs.br +0 -0
  147. package/dist/chunk-XGB3TDIC.mjs.gz +0 -0
  148. package/dist/chunk-XLPQM7OJ.mjs +0 -4243
  149. package/dist/chunk-XLPQM7OJ.mjs.br +0 -0
  150. package/dist/chunk-XLPQM7OJ.mjs.gz +0 -0
  151. package/dist/chunk-ZW2WNQN7.js.br +0 -0
  152. package/dist/chunk-ZW2WNQN7.js.gz +0 -0
  153. package/dist/smartart-layouts-5T2QZGLG.js +0 -2494
  154. package/dist/smartart-layouts-5T2QZGLG.js.br +0 -0
  155. package/dist/smartart-layouts-5T2QZGLG.js.gz +0 -0
  156. package/dist/smartart-layouts-UCAFYVFW.mjs +0 -2487
  157. package/dist/smartart-layouts-UCAFYVFW.mjs.br +0 -0
  158. package/dist/smartart-layouts-UCAFYVFW.mjs.gz +0 -0
  159. package/dist/three.module-BLHG4FHZ.js +0 -1783
  160. package/dist/three.module-BLHG4FHZ.js.br +0 -0
  161. package/dist/three.module-BLHG4FHZ.js.gz +0 -0
  162. package/dist/three.module-ZSSMKKHW.mjs +0 -2
  163. package/dist/three.module-ZSSMKKHW.mjs.br +0 -0
  164. package/dist/three.module-ZSSMKKHW.mjs.gz +0 -0
  165. package/dist/y-webrtc-F2H7BRUK.js.br +0 -0
  166. package/dist/y-webrtc-F2H7BRUK.js.gz +0 -0
  167. package/dist/y-webrtc-GAHCEZSS.mjs.br +0 -0
  168. package/dist/y-webrtc-GAHCEZSS.mjs.gz +0 -0
  169. package/dist/y-websocket-FBMB63F4.js.br +0 -0
  170. package/dist/y-websocket-FBMB63F4.js.gz +0 -0
  171. package/dist/y-websocket-MAGDFVLN.mjs.br +0 -0
  172. package/dist/y-websocket-MAGDFVLN.mjs.gz +0 -0
@@ -1,3977 +0,0 @@
1
- 'use strict';
2
-
3
- var chunkUHW3R465_js = require('./chunk-UHW3R465.js');
4
- var chunk6HMJTCFO_js = require('./chunk-6HMJTCFO.js');
5
- var clsx = require('clsx');
6
- var tailwindMerge = require('tailwind-merge');
7
- var React8 = require('react');
8
- var lu = require('react-icons/lu');
9
- var jsxRuntime = require('react/jsx-runtime');
10
- var reactI18next = require('react-i18next');
11
-
12
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
-
14
- var React8__default = /*#__PURE__*/_interopDefault(React8);
15
-
16
- // src/viewer/utils/animation-effects.ts
17
- function getAnimationInitialStyle2(preset, nativeAnimation) {
18
- return chunkUHW3R465_js.getAnimationInitialStyle(preset, nativeAnimation);
19
- }
20
- function cn(...inputs) {
21
- return tailwindMerge.twMerge(clsx.clsx(inputs));
22
- }
23
-
24
- // src/viewer/utils/clone.ts
25
- function cloneHistorySnapshot2(snapshot) {
26
- return chunkUHW3R465_js.cloneHistorySnapshot(snapshot);
27
- }
28
-
29
- // src/viewer/constants/scalar.ts
30
- var DEFAULT_CANVAS_WIDTH = 1280;
31
- var DEFAULT_CANVAS_HEIGHT = 720;
32
- var MIN_ELEMENT_SIZE = 12;
33
- var EMU_PER_PX = 9525;
34
- var DEFAULT_BODY_INSET_TB_PX = 45720 / 9525;
35
- var DEFAULT_TEXT_COLOR = "#111827";
36
- var DEFAULT_FILL_COLOR = "#3b82f6";
37
- var DEFAULT_STROKE_COLOR = "#1f2937";
38
- var DEFAULT_FONT_FAMILY2 = '"Segoe UI", "Helvetica Neue", Arial, sans-serif';
39
- var DEFAULT_TEXT_FONT_SIZE = 24;
40
- var HYPERLINK_COLOR = "#0563C1";
41
- var DEFAULT_TABLE_ROWS = 3;
42
- var DEFAULT_TABLE_COLUMNS = 3;
43
- var ZOOM_TO_SELECTION_PADDING = 96;
44
- var GRID_SIZE = 8;
45
- var SLIDE_NAV_THUMBNAIL_WIDTH = 156;
46
- var UNGROUPED_SECTION_ID = "__ungrouped__";
47
- var DEFAULT_SECTION_GROUP_ID = "default";
48
-
49
- // src/viewer/constants/toolbar.ts
50
- var TOOLBAR_SECTIONS = [
51
- { id: "file", labelKey: "pptx.ribbon.tab.file" },
52
- { id: "home", labelKey: "pptx.ribbon.tab.home" },
53
- { id: "insert", labelKey: "pptx.ribbon.tab.insert" },
54
- { id: "draw", labelKey: "pptx.ribbon.tab.draw" },
55
- { id: "design", labelKey: "pptx.ribbon.tab.design" },
56
- { id: "transitions", labelKey: "pptx.ribbon.tab.transitions" },
57
- { id: "animations", labelKey: "pptx.ribbon.tab.animations" },
58
- { id: "slideShow", labelKey: "pptx.ribbon.tab.slideShow" },
59
- { id: "record", labelKey: "pptx.ribbon.tab.record" },
60
- { id: "review", labelKey: "pptx.ribbon.tab.review" },
61
- { id: "view", labelKey: "pptx.ribbon.tab.view" },
62
- { id: "help", labelKey: "pptx.ribbon.tab.help" }
63
- ];
64
- var SHORTCUT_REFERENCE_ITEMS = chunkUHW3R465_js.VIEWER_SHORTCUT_REFERENCE;
65
-
66
- // src/viewer/constants/transitions-animations.ts
67
- var ANIMATION_PRESET_OPTIONS = [
68
- { value: "fadeIn", label: "Fade In", i18nKey: "pptx.animation.preset.fadeIn" },
69
- { value: "flyIn", label: "Fly In", i18nKey: "pptx.animation.preset.flyIn" },
70
- { value: "zoomIn", label: "Zoom In", i18nKey: "pptx.animation.preset.zoomIn" },
71
- { value: "fadeOut", label: "Fade Out", i18nKey: "pptx.animation.preset.fadeOut" },
72
- { value: "flyOut", label: "Fly Out", i18nKey: "pptx.animation.preset.flyOut" },
73
- { value: "zoomOut", label: "Zoom Out", i18nKey: "pptx.animation.preset.zoomOut" },
74
- { value: "spin", label: "Spin", i18nKey: "pptx.animation.preset.spin" },
75
- { value: "pulse", label: "Pulse", i18nKey: "pptx.animation.preset.pulse" },
76
- { value: "colorWave", label: "Color Wave", i18nKey: "pptx.animation.preset.colorWave" },
77
- { value: "bounce", label: "Bounce", i18nKey: "pptx.animation.preset.bounce" },
78
- { value: "flash", label: "Flash", i18nKey: "pptx.animation.preset.flash" },
79
- { value: "growShrink", label: "Grow/Shrink", i18nKey: "pptx.animation.preset.growShrink" },
80
- { value: "teeter", label: "Teeter", i18nKey: "pptx.animation.preset.teeter" }
81
- ];
82
- var GLYPH_COMPONENTS = {
83
- square: lu.LuSquare,
84
- circle: lu.LuCircle,
85
- database: lu.LuDatabase,
86
- diamond: lu.LuDiamond,
87
- minus: lu.LuMinus,
88
- moveRight: lu.LuMoveRight,
89
- plus: lu.LuPlus,
90
- triangle: lu.LuTriangle
91
- };
92
- var SHAPE_PRESETS = chunkUHW3R465_js.SHAPE_PRESET_DEFS.map(
93
- (def) => ({
94
- type: def.type,
95
- label: def.label,
96
- i18nKey: def.i18nKey,
97
- icon: React8__default.default.createElement(GLYPH_COMPONENTS[def.glyph], {
98
- className: def.glyphClass ? `w-3.5 h-3.5 ${def.glyphClass}` : "w-3.5 h-3.5"
99
- })
100
- })
101
- );
102
-
103
- // src/viewer/constants/connectors-strokes.ts
104
- var CONNECTOR_ARROW_OPTIONS = [
105
- { value: "none", label: "None", i18nKey: "pptx.arrowhead.none" },
106
- { value: "triangle", label: "Triangle", i18nKey: "pptx.arrowhead.triangle" },
107
- { value: "stealth", label: "Stealth", i18nKey: "pptx.arrowhead.stealth" },
108
- { value: "diamond", label: "Diamond", i18nKey: "pptx.arrowhead.diamond" },
109
- { value: "oval", label: "Oval", i18nKey: "pptx.arrowhead.oval" },
110
- { value: "arrow", label: "Open Arrow", i18nKey: "pptx.arrowhead.openArrow" }
111
- ];
112
- var ARROW_SIZE_OPTIONS = [
113
- { value: "sm", label: "Small", i18nKey: "pptx.connectorOptions.sizeSmall" },
114
- { value: "med", label: "Medium", i18nKey: "pptx.connectorOptions.sizeMedium" },
115
- { value: "lg", label: "Large", i18nKey: "pptx.connectorOptions.sizeLarge" }
116
- ];
117
- var STROKE_DASH_OPTIONS2 = chunkUHW3R465_js.STROKE_DASH_OPTIONS;
118
-
119
- // src/viewer/utils/shape-types.tsx
120
- function getShapeType(shapeType) {
121
- if (!shapeType) {
122
- return "rect";
123
- }
124
- const normalized = shapeType.toLowerCase();
125
- if (normalized === "rect") {
126
- return "rect";
127
- }
128
- if (normalized === "roundrect") {
129
- return "roundRect";
130
- }
131
- if (normalized === "ellipse" || normalized === "oval") {
132
- return "ellipse";
133
- }
134
- if (normalized === "cylinder" || normalized === "can") {
135
- return "cylinder";
136
- }
137
- if (normalized === "triangle") {
138
- return "triangle";
139
- }
140
- if (normalized === "rttriangle") {
141
- return "rtTriangle";
142
- }
143
- if (normalized === "diamond") {
144
- return "diamond";
145
- }
146
- if (normalized === "line") {
147
- return "line";
148
- }
149
- if (normalized === "parallelogram") {
150
- return "parallelogram";
151
- }
152
- if (normalized === "trapezoid") {
153
- return "trapezoid";
154
- }
155
- if (normalized === "pentagon") {
156
- return "pentagon";
157
- }
158
- if (normalized === "hexagon") {
159
- return "hexagon";
160
- }
161
- if (normalized === "octagon") {
162
- return "octagon";
163
- }
164
- if (normalized === "chevron") {
165
- return "chevron";
166
- }
167
- if (normalized === "star5") {
168
- return "star5";
169
- }
170
- if (normalized === "star6") {
171
- return "star6";
172
- }
173
- if (normalized === "star8") {
174
- return "star8";
175
- }
176
- if (normalized === "plus") {
177
- return "plus";
178
- }
179
- if (normalized === "heart") {
180
- return "heart";
181
- }
182
- if (normalized === "cloud") {
183
- return "cloud";
184
- }
185
- if (normalized === "sun") {
186
- return "sun";
187
- }
188
- if (normalized === "moon") {
189
- return "moon";
190
- }
191
- if (normalized === "pie") {
192
- return "pie";
193
- }
194
- if (normalized === "plaque") {
195
- return "plaque";
196
- }
197
- if (normalized === "teardrop") {
198
- return "teardrop";
199
- }
200
- if (normalized === "rtarrow" || normalized === "rightarrow") {
201
- return "rtArrow";
202
- }
203
- if (normalized === "leftarrow") {
204
- return "leftArrow";
205
- }
206
- if (normalized === "uparrow") {
207
- return "upArrow";
208
- }
209
- if (normalized === "downarrow") {
210
- return "downArrow";
211
- }
212
- if (normalized.includes("connector")) {
213
- return "connector";
214
- }
215
- if (normalized === "connector") {
216
- return "connector";
217
- }
218
- return "rect";
219
- }
220
-
221
- // src/viewer/utils/element.ts
222
- function isConnectorOrLineElement(element) {
223
- if (element.type === "connector") {
224
- return true;
225
- }
226
- if (!chunkUHW3R465_js.hasShapeProperties(element)) {
227
- return false;
228
- }
229
- const st = getShapeType(element.shapeType);
230
- return st === "connector" || st === "line" || element.shapeType === "line";
231
- }
232
-
233
- // src/viewer/utils/image-style.ts
234
- function getImageMaskStyle(element) {
235
- if (!chunkUHW3R465_js.hasShapeProperties(element)) {
236
- return void 0;
237
- }
238
- const geometry = chunkUHW3R465_js.resolveShapeGeometry(element);
239
- if (geometry.kind === "borderRadius") {
240
- return { borderRadius: geometry.radius };
241
- }
242
- return geometry.kind === "clipPath" ? { clipPath: geometry.clipPath } : void 0;
243
- }
244
- function getImageRenderStyle(element) {
245
- const fit = chunkUHW3R465_js.getImageFitStyle(element);
246
- const counterTransform = chunkUHW3R465_js.getImageFillCounterTransform(element, Boolean(fit.transform));
247
- return {
248
- // A translated/scaled crop, or a rotWithShape=false counter-transform,
249
- // must be masked by the stationary wrapper, not by the moving/counter-
250
- // transformed bitmap itself.
251
- ...fit.transform || counterTransform ? {} : getImageMaskStyle(element) || {},
252
- ...fit,
253
- ...counterTransform ? { transform: counterTransform, transformOrigin: "center" } : {}
254
- };
255
- }
256
- function getImageSurfaceMaskStyle(element) {
257
- const mask = getImageMaskStyle(element);
258
- return {
259
- overflow: "hidden",
260
- borderRadius: mask?.borderRadius,
261
- clipPath: mask?.clipPath ?? getCropShapeClipPath2(element)
262
- };
263
- }
264
- function getImageSurfaceStyle(element) {
265
- const fill = chunkUHW3R465_js.hasShapeProperties(element) ? chunkUHW3R465_js.getComputedFillStyle(element) : void 0;
266
- return {
267
- position: "absolute",
268
- inset: 0,
269
- ...getImageSurfaceMaskStyle(element),
270
- backgroundColor: fill?.backgroundColor ?? "transparent",
271
- backgroundImage: fill?.backgroundImage,
272
- backgroundRepeat: fill?.backgroundRepeat,
273
- backgroundSize: fill?.backgroundSize,
274
- backgroundPosition: fill?.backgroundPosition
275
- };
276
- }
277
- function getCropShapeClipPath2(element) {
278
- if (!chunkUHW3R465_js.isImageLikeElement(element)) {
279
- return void 0;
280
- }
281
- return chunkUHW3R465_js.getCropShapeClipPath(element.cropShape, element.width, element.height);
282
- }
283
- function getImageTilingStyle2(element, nativeSize) {
284
- return chunkUHW3R465_js.getImageTilingStyle(element, nativeSize);
285
- }
286
-
287
- // src/viewer/utils/geometry-image.ts
288
- function shouldRenderFallbackLabel(element, isTextElement) {
289
- if (isTextElement) {
290
- return false;
291
- }
292
- if (element.type === "shape" || element.type === "connector") {
293
- return false;
294
- }
295
- if (element.type === "picture" || element.type === "image") {
296
- return false;
297
- }
298
- if (element.type === "table") {
299
- return false;
300
- }
301
- if (element.type === "media") {
302
- return false;
303
- }
304
- if (element.type === "contentPart") {
305
- return false;
306
- }
307
- if (element.type === "model3d") {
308
- return false;
309
- }
310
- if (element.type === "ole") {
311
- const previewData = element.previewImageData ?? element.previewImage;
312
- return !previewData;
313
- }
314
- return element.type === "chart" || element.type === "smartArt" || element.type === "unknown";
315
- }
316
- function ensureArrayValue(value) {
317
- if (!value) {
318
- return [];
319
- }
320
- return Array.isArray(value) ? value : [value];
321
- }
322
-
323
- // src/viewer/utils/media-persistent-audio.tsx
324
- function buildTrimFragment(element) {
325
- const start = element.trimStartMs;
326
- if (start === void 0 || start <= 0) {
327
- return "";
328
- }
329
- return `#t=${(start / 1e3).toFixed(3)}`;
330
- }
331
- function useMediaMetadataExtraction(mediaRef, element) {
332
- const [metadata, setMetadata] = React8.useState(element.metadata);
333
- React8.useEffect(() => {
334
- const el = mediaRef.current;
335
- if (!el) {
336
- return;
337
- }
338
- if (element.metadata?.duration !== void 0) {
339
- setMetadata(element.metadata);
340
- return;
341
- }
342
- const extract = () => {
343
- if (!Number.isFinite(el.duration) || el.duration === 0) {
344
- return;
345
- }
346
- const meta = {
347
- duration: el.duration
348
- };
349
- if (el instanceof HTMLVideoElement) {
350
- if (el.videoWidth > 0) {
351
- meta.videoWidth = el.videoWidth;
352
- }
353
- if (el.videoHeight > 0) {
354
- meta.videoHeight = el.videoHeight;
355
- }
356
- }
357
- const sourceEl = el.querySelector("source");
358
- if (sourceEl?.type) {
359
- meta.codecInfo = sourceEl.type;
360
- }
361
- element.metadata = meta;
362
- setMetadata(meta);
363
- };
364
- el.addEventListener("loadedmetadata", extract);
365
- if (el.readyState >= 1) {
366
- extract();
367
- }
368
- return () => {
369
- el.removeEventListener("loadedmetadata", extract);
370
- };
371
- }, [mediaRef, element]);
372
- return metadata;
373
- }
374
- function CaptionTrackRenderer({
375
- captionTracks
376
- }) {
377
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: captionTracks.map((track) => {
378
- const trackSrc = track.src ?? (track.content ? `data:text/vtt;charset=utf-8,${encodeURIComponent(track.content)}` : void 0);
379
- if (!trackSrc) {
380
- return null;
381
- }
382
- return /* @__PURE__ */ jsxRuntime.jsx(
383
- "track",
384
- {
385
- kind: track.kind,
386
- label: track.label,
387
- srcLang: track.language,
388
- src: trackSrc,
389
- default: track.isDefault
390
- },
391
- track.id
392
- );
393
- }) });
394
- }
395
- function VideoWithMetadata({
396
- element,
397
- mediaRef,
398
- onPlay,
399
- dataUrl,
400
- trimFragment,
401
- mediaMimeType,
402
- posterUrl,
403
- shouldLoop,
404
- shouldAutoPlay,
405
- isFullScreen,
406
- isPresentationMode,
407
- showTransport
408
- }) {
409
- useMediaMetadataExtraction(mediaRef, element);
410
- const captionTracks = element.captionTracks ?? [];
411
- return /* @__PURE__ */ jsxRuntime.jsxs(
412
- "video",
413
- {
414
- ref: mediaRef,
415
- className: "w-full h-full pointer-events-auto",
416
- style: isFullScreen ? { objectFit: "cover" } : chunkUHW3R465_js.getImageFitStyle(element),
417
- controls: showTransport,
418
- preload: "metadata",
419
- playsInline: true,
420
- autoPlay: shouldAutoPlay,
421
- muted: shouldAutoPlay && !isPresentationMode,
422
- poster: posterUrl,
423
- loop: shouldLoop,
424
- onPlay,
425
- crossOrigin: captionTracks.length > 0 ? "anonymous" : void 0,
426
- children: [
427
- /* @__PURE__ */ jsxRuntime.jsx("source", { src: `${dataUrl}${trimFragment}`, type: mediaMimeType || "video/mp4" }),
428
- captionTracks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(CaptionTrackRenderer, { captionTracks })
429
- ]
430
- }
431
- );
432
- }
433
- function AudioWithMetadata({
434
- element,
435
- mediaRef,
436
- onPlay,
437
- dataUrl,
438
- trimFragment,
439
- mediaMimeType,
440
- shouldLoop,
441
- shouldAutoPlay,
442
- showTransport
443
- }) {
444
- useMediaMetadataExtraction(mediaRef, element);
445
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center p-2 pointer-events-auto", children: /* @__PURE__ */ jsxRuntime.jsx(
446
- "audio",
447
- {
448
- ref: mediaRef,
449
- className: "w-full",
450
- controls: showTransport,
451
- preload: "metadata",
452
- autoPlay: shouldAutoPlay,
453
- loop: shouldLoop,
454
- onPlay,
455
- children: /* @__PURE__ */ jsxRuntime.jsx("source", { src: `${dataUrl}${trimFragment}`, type: mediaMimeType || "audio/mpeg" })
456
- }
457
- ) });
458
- }
459
- function PresentationMediaController({
460
- element,
461
- isPresentationMode,
462
- shouldAutoPlay,
463
- resolvedDataUrl,
464
- isFullScreen,
465
- onPlayStateChange,
466
- children
467
- }) {
468
- const { t } = reactI18next.useTranslation();
469
- const mediaRef = React8.useRef(null);
470
- const [isMediaPlaying, setIsMediaPlaying] = React8.useState(false);
471
- const trimStartSec = element.trimStartMs !== void 0 ? element.trimStartMs / 1e3 : 0;
472
- const hideWhenNotPlaying = isPresentationMode && element.hideWhenNotPlaying === true;
473
- const { volume: playbackVolume, playbackRate } = chunkUHW3R465_js.mediaPlaybackAttributes({
474
- loop: element.loop,
475
- volume: element.volume,
476
- playbackSpeed: element.playbackSpeed
477
- });
478
- React8.useEffect(() => {
479
- const el = mediaRef.current;
480
- if (el) {
481
- el.volume = playbackVolume;
482
- }
483
- }, [playbackVolume]);
484
- React8.useEffect(() => {
485
- const el = mediaRef.current;
486
- if (el) {
487
- el.playbackRate = playbackRate;
488
- }
489
- }, [playbackRate]);
490
- React8.useEffect(() => {
491
- const el = mediaRef.current;
492
- if (!el) {
493
- return;
494
- }
495
- const handlePlay = () => {
496
- setIsMediaPlaying(true);
497
- onPlayStateChange?.(true);
498
- };
499
- const handlePause = () => {
500
- setIsMediaPlaying(false);
501
- onPlayStateChange?.(false);
502
- };
503
- const handleEnded = () => {
504
- setIsMediaPlaying(false);
505
- onPlayStateChange?.(false);
506
- };
507
- el.addEventListener("play", handlePlay);
508
- el.addEventListener("pause", handlePause);
509
- el.addEventListener("ended", handleEnded);
510
- return () => {
511
- el.removeEventListener("play", handlePlay);
512
- el.removeEventListener("pause", handlePause);
513
- el.removeEventListener("ended", handleEnded);
514
- };
515
- }, [onPlayStateChange]);
516
- React8.useEffect(() => {
517
- const el = mediaRef.current;
518
- if (!el || !isPresentationMode) {
519
- return;
520
- }
521
- return chunkUHW3R465_js.scheduleMediaTrimAndFade(el, {
522
- trimStartMs: element.trimStartMs,
523
- trimEndMs: element.trimEndMs,
524
- fadeInDuration: element.fadeInDuration,
525
- fadeOutDuration: element.fadeOutDuration,
526
- volume: playbackVolume
527
- });
528
- }, [
529
- isPresentationMode,
530
- element.trimStartMs,
531
- element.trimEndMs,
532
- element.fadeInDuration,
533
- element.fadeOutDuration,
534
- playbackVolume
535
- ]);
536
- React8.useEffect(() => {
537
- if (!isPresentationMode || !shouldAutoPlay) {
538
- return;
539
- }
540
- if (element.playAcrossSlides && element.mediaType === "audio") {
541
- const dataUrl = element.mediaData ?? resolvedDataUrl;
542
- if (chunkUHW3R465_js.registerCrossSlideAudio(element, dataUrl)) {
543
- return;
544
- }
545
- }
546
- const el = mediaRef.current;
547
- if (!el) {
548
- return;
549
- }
550
- const timer = window.setTimeout(() => {
551
- if (trimStartSec > 0) {
552
- el.currentTime = trimStartSec;
553
- }
554
- void el.play().catch(() => {
555
- });
556
- }, 100);
557
- return () => window.clearTimeout(timer);
558
- }, [isPresentationMode, shouldAutoPlay, element, resolvedDataUrl, trimStartSec]);
559
- const wrapperStyle = hideWhenNotPlaying ? {
560
- opacity: isMediaPlaying ? 1 : 0,
561
- transition: "opacity 0.3s ease",
562
- pointerEvents: isMediaPlaying ? "auto" : "none"
563
- } : {};
564
- const handleStopFullScreen = React8.useCallback(() => {
565
- const el = mediaRef.current;
566
- if (el && !el.paused) {
567
- el.pause();
568
- }
569
- }, []);
570
- const noopOnPlay = React8.useCallback(() => {
571
- }, []);
572
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full h-full", style: wrapperStyle, children: [
573
- children({ mediaRef, onPlay: noopOnPlay, isMediaPlaying }),
574
- chunkUHW3R465_js.shouldShowMediaFullscreenStopButton({
575
- fullScreen: isFullScreen,
576
- presenting: isPresentationMode,
577
- playing: isMediaPlaying
578
- }) && /* @__PURE__ */ jsxRuntime.jsx(
579
- "button",
580
- {
581
- type: "button",
582
- className: "absolute bottom-3 right-3 z-30 rounded-full bg-black/50 hover:bg-black/70 text-white/80 hover:text-white p-2 transition-colors pointer-events-auto",
583
- onClick: handleStopFullScreen,
584
- "aria-label": t("pptx.media.stopFullscreenAria"),
585
- children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "currentColor", stroke: "none", children: /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1" }) })
586
- }
587
- )
588
- ] });
589
- }
590
- function label(key) {
591
- return key === void 0 ? void 0 : chunk6HMJTCFO_js.translationsEn[key];
592
- }
593
- function FallbackIcon({
594
- paths,
595
- size,
596
- className
597
- }) {
598
- if (paths.length === 0) {
599
- return null;
600
- }
601
- return /* @__PURE__ */ jsxRuntime.jsx(
602
- "svg",
603
- {
604
- width: size,
605
- height: size,
606
- viewBox: "0 0 24 24",
607
- fill: "none",
608
- stroke: "currentColor",
609
- strokeWidth: "1.5",
610
- className,
611
- children: paths.map((d) => /* @__PURE__ */ jsxRuntime.jsx("path", { d }, d))
612
- }
613
- );
614
- }
615
- function Badge({
616
- visual,
617
- element
618
- }) {
619
- if (visual.badge === "none") {
620
- return null;
621
- }
622
- const isMissing = visual.badge === "missing";
623
- return /* @__PURE__ */ jsxRuntime.jsxs(
624
- "div",
625
- {
626
- className: `absolute inset-0 flex flex-col items-center justify-center ${isMissing ? "gap-1" : ""}`,
627
- ...{ [chunkUHW3R465_js.MEDIA_CHROME_ATTRIBUTE]: visual.badge },
628
- children: [
629
- /* @__PURE__ */ jsxRuntime.jsx(
630
- FallbackIcon,
631
- {
632
- paths: chunkUHW3R465_js.mediaFallbackIcon(visual, element.mediaType),
633
- size: isMissing ? 32 : 48,
634
- className: isMissing ? "text-white/60" : "text-white/80 drop-shadow-md"
635
- }
636
- ),
637
- isMissing && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-white/60", children: label(chunkUHW3R465_js.mediaFallbackLabelKey(visual, element.mediaType)) })
638
- ]
639
- }
640
- );
641
- }
642
- function Placeholder({
643
- visual,
644
- element
645
- }) {
646
- if (visual.placeholder === "none") {
647
- return null;
648
- }
649
- const isMissing = visual.placeholder === "missing";
650
- return /* @__PURE__ */ jsxRuntime.jsxs(
651
- "div",
652
- {
653
- className: `w-full h-full flex flex-col items-center justify-center gap-1 pointer-events-none rounded ${isMissing ? "bg-black/30 border border-dashed border-white/20" : element.mediaType === "audio" ? "bg-black/10" : "bg-black/20"}`,
654
- ...{ [chunkUHW3R465_js.MEDIA_CHROME_ATTRIBUTE]: visual.placeholder },
655
- children: [
656
- /* @__PURE__ */ jsxRuntime.jsx(
657
- FallbackIcon,
658
- {
659
- paths: chunkUHW3R465_js.mediaFallbackIcon(visual, element.mediaType),
660
- size: isMissing ? 36 : element.mediaType === "audio" ? 24 : 32,
661
- className: isMissing ? "text-white/50" : "text-white/70"
662
- }
663
- ),
664
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-[10px] ${isMissing ? "text-white/50" : "text-white/70"}`, children: label(chunkUHW3R465_js.mediaFallbackLabelKey(visual, element.mediaType)) })
665
- ]
666
- }
667
- );
668
- }
669
- function renderMediaFallback({
670
- element,
671
- posterUrl,
672
- surface
673
- }) {
674
- const visual = chunkUHW3R465_js.mediaFallbackVisual(surface, {
675
- hasPoster: Boolean(posterUrl),
676
- missing: element.mediaMissing === true
677
- });
678
- if (visual.poster && posterUrl) {
679
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full h-full relative pointer-events-none", children: [
680
- /* @__PURE__ */ jsxRuntime.jsx(
681
- "img",
682
- {
683
- src: posterUrl,
684
- alt: visual.dimPoster ? chunk6HMJTCFO_js.translationsEn["pptx.media.posterAlt"] : chunk6HMJTCFO_js.translationsEn["pptx.media.videoPosterAlt"],
685
- className: `w-full h-full${visual.dimPoster ? " opacity-50" : ""}`,
686
- style: chunkUHW3R465_js.getImageFitStyle(element)
687
- }
688
- ),
689
- /* @__PURE__ */ jsxRuntime.jsx(Badge, { visual, element })
690
- ] });
691
- }
692
- return /* @__PURE__ */ jsxRuntime.jsx(Placeholder, { visual, element });
693
- }
694
- function renderMediaElement(element, mediaDataUrls, options) {
695
- if (element.type !== "media") {
696
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: chunk6HMJTCFO_js.translationsEn["pptx.media.title"] });
697
- }
698
- const mediaType = element.mediaType;
699
- const mediaPath = element.mediaPath;
700
- const mediaMimeType = element.mediaMimeType;
701
- const dataUrl = element.mediaData ?? (mediaPath ? mediaDataUrls.get(mediaPath) : void 0);
702
- const trimFragment = buildTrimFragment(element);
703
- const posterUrl = element.posterFrameData ?? void 0;
704
- const shouldLoop = chunkUHW3R465_js.mediaPlaybackAttributes(element).loop;
705
- const shouldAutoPlay = options?.autoPlay === true || element.autoPlay === true;
706
- const isFullScreen = options?.fullScreen === true;
707
- const isPresentationMode = options?.isPresentationMode === true;
708
- const showTransport = options?.showTransport ?? !isPresentationMode;
709
- const surface = {
710
- presenting: isPresentationMode,
711
- preview: options?.preview === true
712
- };
713
- if (element.mediaMissing) {
714
- return renderMediaFallback({ element, posterUrl, surface });
715
- }
716
- if (mediaType === "video") {
717
- const onlineVideo = chunkUHW3R465_js.getOnlineVideoEmbed(element);
718
- if (onlineVideo) {
719
- return /* @__PURE__ */ jsxRuntime.jsx(
720
- "iframe",
721
- {
722
- src: onlineVideo.embedUrl,
723
- title: chunk6HMJTCFO_js.translationsEn["pptx.media.onlineVideoTitle"],
724
- className: "w-full h-full border-0 pointer-events-auto",
725
- allow: chunkUHW3R465_js.ONLINE_VIDEO_IFRAME_ALLOW,
726
- allowFullScreen: true,
727
- sandbox: chunkUHW3R465_js.ONLINE_VIDEO_IFRAME_SANDBOX
728
- }
729
- );
730
- }
731
- if (dataUrl) {
732
- return /* @__PURE__ */ jsxRuntime.jsx(
733
- PresentationMediaController,
734
- {
735
- element,
736
- isPresentationMode,
737
- shouldAutoPlay,
738
- resolvedDataUrl: dataUrl,
739
- isFullScreen,
740
- onPlayStateChange: options?.onPlayStateChange,
741
- children: ({ mediaRef, onPlay }) => /* @__PURE__ */ jsxRuntime.jsx(
742
- VideoWithMetadata,
743
- {
744
- element,
745
- mediaRef,
746
- onPlay,
747
- dataUrl,
748
- trimFragment,
749
- mediaMimeType,
750
- posterUrl,
751
- shouldLoop,
752
- shouldAutoPlay,
753
- isFullScreen,
754
- isPresentationMode,
755
- showTransport
756
- }
757
- )
758
- }
759
- );
760
- }
761
- return renderMediaFallback({ element, posterUrl, surface });
762
- }
763
- if (mediaType === "audio") {
764
- if (dataUrl) {
765
- return /* @__PURE__ */ jsxRuntime.jsx(
766
- PresentationMediaController,
767
- {
768
- element,
769
- isPresentationMode,
770
- shouldAutoPlay,
771
- resolvedDataUrl: dataUrl,
772
- isFullScreen: false,
773
- onPlayStateChange: options?.onPlayStateChange,
774
- children: ({ mediaRef, onPlay }) => /* @__PURE__ */ jsxRuntime.jsx(
775
- AudioWithMetadata,
776
- {
777
- element,
778
- mediaRef,
779
- onPlay,
780
- dataUrl,
781
- trimFragment,
782
- mediaMimeType,
783
- shouldLoop,
784
- shouldAutoPlay,
785
- showTransport
786
- }
787
- )
788
- }
789
- );
790
- }
791
- return renderMediaFallback({ element, posterUrl, surface });
792
- }
793
- if (surface.presenting || surface.preview) {
794
- return null;
795
- }
796
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: chunk6HMJTCFO_js.translationsEn["pptx.media.title"] });
797
- }
798
-
799
- // src/viewer/utils/text-utils.tsx
800
- function getTextStyleForElement(element, fallbackColor) {
801
- return chunkUHW3R465_js.buildTextBlockStyle(element, { fallbackColor });
802
- }
803
-
804
- // src/viewer/utils/text-layout.tsx
805
- function getTextLayoutStyle(element) {
806
- if (!chunkUHW3R465_js.hasTextProperties(element)) {
807
- return {};
808
- }
809
- const writingMode = chunkUHW3R465_js.toCssWritingMode(element.textStyle?.textDirection);
810
- const textOrientation = chunkUHW3R465_js.toCssTextOrientation(element.textStyle?.textDirection);
811
- const verticalDirection = chunkUHW3R465_js.toCssVerticalDirection(element.textStyle?.textDirection);
812
- const textWrapNone = element.textStyle?.textWrap === "none";
813
- const shapeAutoFitTextBox = element.textStyle?.autoFitMode === "shrink" && (element.type === "text" || element.locks?.txBox === true);
814
- const hasParagraphIndents = chunkUHW3R465_js.hasTextProperties(element) && element.paragraphIndents && element.paragraphIndents.length > 0;
815
- const paragraphMarginLeft = element.textStyle?.paragraphMarginLeft;
816
- const paragraphIndent = element.textStyle?.paragraphIndent;
817
- const marginLeft = !hasParagraphIndents && typeof paragraphMarginLeft === "number" && paragraphMarginLeft !== 0 ? paragraphMarginLeft : void 0;
818
- const textIndent = !hasParagraphIndents && typeof paragraphIndent === "number" && paragraphIndent !== 0 ? paragraphIndent : void 0;
819
- const bodyTop = element.textStyle?.bodyInsetTop ?? DEFAULT_BODY_INSET_TB_PX;
820
- const bodyBottom = element.textStyle?.bodyInsetBottom ?? DEFAULT_BODY_INSET_TB_PX;
821
- const bodyLayoutStyle = chunkUHW3R465_js.buildTextBodyLayoutStyle(element);
822
- return {
823
- ...bodyLayoutStyle,
824
- // Body inset only. Paragraph spacing (spcBef/spcAft) is applied
825
- // per-paragraph by the paragraph renderer, not collapsed here.
826
- paddingTop: bodyTop,
827
- paddingBottom: bodyBottom,
828
- writingMode,
829
- textOrientation,
830
- direction: verticalDirection ?? bodyLayoutStyle.direction,
831
- marginLeft: marginLeft ?? bodyLayoutStyle.marginLeft,
832
- textIndent,
833
- ...shapeAutoFitTextBox ? {
834
- width: textWrapNone ? "max-content" : "100%",
835
- minWidth: "100%",
836
- height: "max-content",
837
- minHeight: "100%",
838
- whiteSpace: "pre-wrap",
839
- wordBreak: textWrapNone ? "normal" : "break-word",
840
- overflow: "visible"
841
- } : {},
842
- ...textWrapNone ? {
843
- whiteSpace: "nowrap",
844
- overflow: "visible"
845
- } : {}
846
- };
847
- }
848
-
849
- // src/viewer/utils/text-effects.tsx
850
- function buildTextBody3DSceneStyle2(textStyle, elementSize) {
851
- return chunkUHW3R465_js.buildTextBody3DSceneStyle(textStyle, elementSize);
852
- }
853
-
854
- // src/viewer/utils/text-warp-css.tsx
855
- function getTextWarpStyle(textStyle) {
856
- const preset = textStyle?.textWarpPreset;
857
- if (!preset || preset === "textNoShape" || preset === "textPlain") {
858
- return void 0;
859
- }
860
- switch (preset) {
861
- // Arch shapes
862
- case "textArchUp":
863
- case "textArchUpPour":
864
- return {
865
- transform: "perspective(400px) rotateX(-12deg)",
866
- transformOrigin: "center bottom"
867
- };
868
- case "textArchDown":
869
- case "textArchDownPour":
870
- return {
871
- transform: "perspective(400px) rotateX(12deg)",
872
- transformOrigin: "center top"
873
- };
874
- // Button shapes (concave/convex)
875
- case "textButton":
876
- case "textButtonPour":
877
- return {
878
- transform: "perspective(500px) rotateX(8deg)",
879
- transformOrigin: "center top"
880
- };
881
- // Chevron / arrow
882
- case "textChevron":
883
- case "textChevronInverted":
884
- return {
885
- transform: "perspective(600px) rotateY(6deg)",
886
- transformOrigin: "center center"
887
- };
888
- // Circle
889
- case "textCircle":
890
- case "textCirclePour":
891
- return {
892
- transform: "perspective(350px) rotateX(-5deg) rotateY(5deg)",
893
- borderRadius: "50%"
894
- };
895
- // Slant
896
- case "textSlantUp":
897
- return {
898
- transform: "perspective(500px) rotateY(8deg) skewY(-4deg)",
899
- transformOrigin: "left center"
900
- };
901
- case "textSlantDown":
902
- return {
903
- transform: "perspective(500px) rotateY(-8deg) skewY(4deg)",
904
- transformOrigin: "right center"
905
- };
906
- // Fade
907
- case "textFadeUp":
908
- return {
909
- transform: "perspective(400px) rotateX(-10deg)",
910
- transformOrigin: "center bottom"
911
- };
912
- case "textFadeDown":
913
- return {
914
- transform: "perspective(400px) rotateX(10deg)",
915
- transformOrigin: "center top"
916
- };
917
- case "textFadeLeft":
918
- return {
919
- transform: "perspective(400px) rotateY(10deg)",
920
- transformOrigin: "right center"
921
- };
922
- case "textFadeRight":
923
- return {
924
- transform: "perspective(400px) rotateY(-10deg)",
925
- transformOrigin: "left center"
926
- };
927
- // Inflate / Deflate
928
- case "textInflate":
929
- case "textInflateBottom":
930
- case "textInflateTop":
931
- return {
932
- transform: "scaleY(1.15) scaleX(1.05)",
933
- transformOrigin: "center center"
934
- };
935
- case "textDeflate":
936
- case "textDeflateBottom":
937
- case "textDeflateTop":
938
- return {
939
- transform: "scaleY(0.88) scaleX(0.95)",
940
- transformOrigin: "center center"
941
- };
942
- // Wave
943
- case "textWave1":
944
- case "textWave2":
945
- case "textWave4":
946
- return {
947
- transform: "perspective(600px) rotateX(-3deg) skewX(3deg)",
948
- transformOrigin: "center center"
949
- };
950
- case "textDoubleWave1":
951
- return {
952
- transform: "perspective(600px) rotateX(-2deg) skewX(4deg)",
953
- transformOrigin: "center center"
954
- };
955
- // Triangle / Trapezoid
956
- case "textTriangle":
957
- case "textTriangleInverted":
958
- return {
959
- transform: "perspective(500px) rotateX(-6deg)",
960
- transformOrigin: "center bottom"
961
- };
962
- // Ring
963
- case "textRingInside":
964
- case "textRingOutside":
965
- return {
966
- transform: "perspective(350px) rotateX(-4deg) rotateY(4deg)",
967
- transformOrigin: "center center"
968
- };
969
- // Can
970
- case "textCanUp":
971
- case "textCanDown":
972
- return {
973
- transform: "perspective(400px) rotateX(-6deg)",
974
- transformOrigin: "center center"
975
- };
976
- // Cascade
977
- case "textCascadeUp":
978
- return {
979
- transform: "skewY(-8deg)",
980
- transformOrigin: "left top"
981
- };
982
- case "textCascadeDown":
983
- return {
984
- transform: "skewY(8deg)",
985
- transformOrigin: "left top"
986
- };
987
- // Curve
988
- case "textCurveUp":
989
- return {
990
- transform: "perspective(500px) rotateX(-8deg)",
991
- transformOrigin: "center bottom"
992
- };
993
- case "textCurveDown":
994
- return {
995
- transform: "perspective(500px) rotateX(8deg)",
996
- transformOrigin: "center top"
997
- };
998
- // Inflate/Deflate compound variants
999
- case "textDeflateInflate":
1000
- return {
1001
- transform: "scaleY(0.92) scaleX(1.04)",
1002
- transformOrigin: "center center"
1003
- };
1004
- case "textDeflateInflateDeflate":
1005
- return {
1006
- transform: "scaleY(0.85) scaleX(1.06)",
1007
- transformOrigin: "center center"
1008
- };
1009
- // Stop / Octagon
1010
- case "textStop":
1011
- return {
1012
- transform: "scaleX(0.9) scaleY(0.9)",
1013
- transformOrigin: "center center"
1014
- };
1015
- default:
1016
- return void 0;
1017
- }
1018
- }
1019
- function buildAnimStyle(state) {
1020
- if (!state) {
1021
- return void 0;
1022
- }
1023
- const style = {};
1024
- if (state.visible === false) {
1025
- style.visibility = "hidden";
1026
- }
1027
- if (state.cssAnimation) {
1028
- style.animation = state.cssAnimation;
1029
- }
1030
- return Object.keys(style).length > 0 ? style : void 0;
1031
- }
1032
- function wrapWithTextBuildAnimation(elementId, paraIndex, renderedSegments, paraRuns, subElementAnimStates, renderPiece) {
1033
- if (!subElementAnimStates || subElementAnimStates.size === 0) {
1034
- return renderedSegments;
1035
- }
1036
- const paraKey = `${elementId}${chunkUHW3R465_js.TEXT_BUILD_ID_SEP}p${paraIndex}`;
1037
- const paraState = subElementAnimStates.get(paraKey);
1038
- if (paraState) {
1039
- const style = buildAnimStyle(paraState);
1040
- return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-anim-id": paraKey, style: { display: "inline", ...style }, children: renderedSegments }, paraKey);
1041
- }
1042
- const spec = chunkUHW3R465_js.buildTextBuildSpec(
1043
- elementId,
1044
- paraIndex,
1045
- paraRuns.map((run) => ({ text: run.text, style: run })),
1046
- subElementAnimStates
1047
- );
1048
- if (!spec?.spans) {
1049
- return renderedSegments;
1050
- }
1051
- return spec.spans.map((span, index) => {
1052
- const content = span.style && renderPiece ? renderPiece(span.style, span.text, String(index)) : span.text;
1053
- if (!span.animId) {
1054
- return /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: content }, `ws-${index}`);
1055
- }
1056
- return /* @__PURE__ */ jsxRuntime.jsx(
1057
- "span",
1058
- {
1059
- "data-anim-id": span.animId,
1060
- style: chunkUHW3R465_js.textBuildSpanStyle(span),
1061
- children: content
1062
- },
1063
- span.animId
1064
- );
1065
- });
1066
- }
1067
- function renderUnderlineWords(text, isUnderlineWords, wordDecoration, metric, keyPrefix, inner) {
1068
- if (!isUnderlineWords || !text) {
1069
- return inner(text, keyPrefix, metric);
1070
- }
1071
- const pieces = chunkUHW3R465_js.splitWordsForUnderline(text);
1072
- if (pieces.length === 0) {
1073
- return inner(text, keyPrefix, metric);
1074
- }
1075
- const gapMetric = metric ? {
1076
- ...metric,
1077
- nestedStyle: metric.nestedStyle ? chunkUHW3R465_js.stripUnderlineDecoration(metric.nestedStyle) : void 0
1078
- } : void 0;
1079
- return pieces.map((piece, i) => {
1080
- const key = `${keyPrefix}-u${i}`;
1081
- const following = chunkUHW3R465_js.followingText(pieces, i, metric?.following);
1082
- if (!piece.underline) {
1083
- return /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: inner(piece.text, key, gapMetric && { ...gapMetric, following }) }, key);
1084
- }
1085
- return /* @__PURE__ */ jsxRuntime.jsx("span", { style: wordDecoration, children: inner(piece.text, key, metric && { ...metric, following }) }, key);
1086
- });
1087
- }
1088
- function makeSegmentPieceRenderer(needsScriptFonts, scriptFonts, baseFontFamily, isUnderlineWords, wordDecoration, metric) {
1089
- return (text, key, following) => renderUnderlineWords(
1090
- text,
1091
- isUnderlineWords,
1092
- wordDecoration,
1093
- metric && { ...metric, following },
1094
- key,
1095
- (subText, subKey, subMetric) => renderMetricPieces(
1096
- subText,
1097
- subMetric,
1098
- subKey,
1099
- (pieceText, pieceKey) => renderScriptAwareText(
1100
- pieceText,
1101
- needsScriptFonts,
1102
- scriptFonts,
1103
- baseFontFamily,
1104
- pieceKey,
1105
- subMetric?.nestedStyle
1106
- )
1107
- )
1108
- );
1109
- }
1110
- function renderTabbedLine(line, ctx, keyPrefix, renderPiece, nestedStyle, underlineWords = false) {
1111
- const [lineLayout] = chunkUHW3R465_js.buildRunTabLines(
1112
- line,
1113
- ctx,
1114
- nestedStyle,
1115
- void 0,
1116
- underlineWords
1117
- );
1118
- return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { display: "inline-block", whiteSpace: "nowrap" }, children: lineLayout.pieces.map((piece, i) => {
1119
- const key = `${keyPrefix}-tab-${i}`;
1120
- return /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
1121
- piece.leaderStyle ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", style: piece.leaderStyle, children: piece.leaderText }) : null,
1122
- piece.words ? piece.words.map((word, w) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: word.style, children: renderPiece(word.text, `${key}-w${w}`) }, `${key}-w${w}`)) : /* @__PURE__ */ jsxRuntime.jsx("span", { style: piece.style, children: renderPiece(piece.text, key) })
1123
- ] }, key);
1124
- }) });
1125
- }
1126
- function renderEastAsianPieces(text, metric, keyPrefix, inner, baseStyle, following) {
1127
- const parts = chunkUHW3R465_js.splitEastAsianBreaks(text, metric.eastAsian, metric.font, following);
1128
- if (parts.length === 1 && !parts[0].style) {
1129
- return inner(parts[0].text, keyPrefix);
1130
- }
1131
- return parts.map((part, i) => {
1132
- const key = `${keyPrefix}-e${i}`;
1133
- return part.style ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...baseStyle ?? metric.nestedStyle, ...part.style }, children: inner(part.text, key) }, key) : /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: inner(part.text, key) }, key);
1134
- });
1135
- }
1136
- function renderMetricPieces(text, metric, keyPrefix, inner) {
1137
- if (!metric || !text) {
1138
- return inner(text, keyPrefix);
1139
- }
1140
- const pieces = chunkUHW3R465_js.splitRunForMetrics(text, metric.font);
1141
- if (pieces.length <= 1) {
1142
- return renderEastAsianPieces(text, metric, keyPrefix, inner, void 0, metric.following);
1143
- }
1144
- return pieces.map((piece, i) => {
1145
- const key = `${keyPrefix}-w${i}`;
1146
- const style = {
1147
- ...metric.nestedStyle,
1148
- letterSpacing: chunkUHW3R465_js.pieceLetterSpacing(metric.authoredPx, piece.tracking)
1149
- };
1150
- return /* @__PURE__ */ jsxRuntime.jsx("span", { style, children: renderEastAsianPieces(
1151
- piece.text,
1152
- metric,
1153
- key,
1154
- inner,
1155
- style,
1156
- chunkUHW3R465_js.followingText(pieces, i, metric.following)
1157
- ) }, key);
1158
- });
1159
- }
1160
- function renderScriptAwareText(text, needsScriptFonts, scriptFonts, baseFontFamily, keyPrefix, nestedStyle) {
1161
- if (!needsScriptFonts || !text) {
1162
- return text;
1163
- }
1164
- const pieces = chunkUHW3R465_js.splitRunByScriptFont(
1165
- text,
1166
- scriptFonts,
1167
- baseFontFamily,
1168
- nestedStyle
1169
- );
1170
- if (!pieces) {
1171
- return text;
1172
- }
1173
- return pieces.map(
1174
- (piece, i) => piece.style ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: piece.style, children: piece.text }, `${keyPrefix}-r${i}`) : /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: piece.text }, `${keyPrefix}-r${i}`)
1175
- );
1176
- }
1177
- function renderSegmentContent(elementId, segmentIndex, textValue, lines, needsScriptFonts, scriptFonts, baseFontFamily, findHighlights, tabContext, metric, isUnderlineWords = false, wordDecoration) {
1178
- const segHl = findHighlights?.get(segmentIndex);
1179
- const renderLeaf = makeSegmentPieceRenderer(
1180
- needsScriptFonts,
1181
- scriptFonts,
1182
- baseFontFamily,
1183
- isUnderlineWords,
1184
- wordDecoration,
1185
- metric
1186
- );
1187
- if (!segHl || segHl.length === 0) {
1188
- return lines.map((line, lineIndex) => {
1189
- const lineKey = `${elementId}-seg-${segmentIndex}-line-${lineIndex}`;
1190
- return /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
1191
- tabContext && line.includes(" ") ? renderTabbedLine(
1192
- line,
1193
- tabContext,
1194
- lineKey,
1195
- renderLeaf,
1196
- metric?.nestedStyle,
1197
- isUnderlineWords
1198
- ) : renderLeaf(line, lineKey, lineIndex < lines.length - 1 ? "\n" : metric?.following),
1199
- lineIndex < lines.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx("br", {}) : null
1200
- ] }, lineKey);
1201
- });
1202
- }
1203
- const sorted = [...segHl].sort((a, b) => a.startOffset - b.startOffset);
1204
- const chunks = [];
1205
- let cursor = 0;
1206
- for (const hl of sorted) {
1207
- if (hl.startOffset > cursor) {
1208
- chunks.push({
1209
- text: textValue.slice(cursor, hl.startOffset),
1210
- highlighted: false,
1211
- isCurrent: false
1212
- });
1213
- }
1214
- chunks.push({
1215
- text: textValue.slice(hl.startOffset, hl.startOffset + hl.length),
1216
- highlighted: true,
1217
- isCurrent: hl.isCurrent
1218
- });
1219
- cursor = hl.startOffset + hl.length;
1220
- }
1221
- if (cursor < textValue.length) {
1222
- chunks.push({
1223
- text: textValue.slice(cursor),
1224
- highlighted: false,
1225
- isCurrent: false
1226
- });
1227
- }
1228
- return chunks.map((chunk, ci) => {
1229
- const chunkKey = `${elementId}-seg-${segmentIndex}-hl-${ci}`;
1230
- return chunk.highlighted ? /* @__PURE__ */ jsxRuntime.jsx(
1231
- "mark",
1232
- {
1233
- style: {
1234
- ...metric?.nestedStyle,
1235
- backgroundColor: chunk.isCurrent ? "#f97316" : "#facc15",
1236
- color: "inherit",
1237
- borderRadius: 2
1238
- },
1239
- children: renderLeaf(chunk.text, chunkKey, chunkUHW3R465_js.followingText(chunks, ci, metric?.following))
1240
- },
1241
- chunkKey
1242
- ) : /* @__PURE__ */ jsxRuntime.jsx(React8__default.default.Fragment, { children: renderLeaf(chunk.text, chunkKey, chunkUHW3R465_js.followingText(chunks, ci, metric?.following)) }, chunkKey);
1243
- });
1244
- }
1245
- function renderEquationSegment(elementId, segmentIndex, equationXml, equationNumber, fontSize) {
1246
- const mathml = chunkUHW3R465_js.convertOmmlToMathMl(equationXml);
1247
- const safeMathml = mathml ? chunkUHW3R465_js.sanitizeMathMl(mathml) : "";
1248
- const equationContent = safeMathml ? /* @__PURE__ */ jsxRuntime.jsx(
1249
- "span",
1250
- {
1251
- className: "inline-block align-middle",
1252
- style: {
1253
- fontFamily: '"Cambria Math", "STIX Two Math", serif'
1254
- },
1255
- dangerouslySetInnerHTML: { __html: safeMathml }
1256
- }
1257
- ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block px-1 py-0.5 rounded text-xs bg-gray-200/20 text-gray-400 italic", children: chunk6HMJTCFO_js.translationsEn["pptx.textSegment.equationFallback"] });
1258
- if (equationNumber) {
1259
- return /* @__PURE__ */ jsxRuntime.jsxs(
1260
- "span",
1261
- {
1262
- style: {
1263
- display: "flex",
1264
- justifyContent: "space-between",
1265
- alignItems: "center",
1266
- width: "100%",
1267
- fontSize
1268
- },
1269
- children: [
1270
- /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { visibility: "hidden", whiteSpace: "nowrap" }, children: [
1271
- "(",
1272
- equationNumber,
1273
- ")"
1274
- ] }),
1275
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { textAlign: "center", flex: 1 }, children: equationContent }),
1276
- /* @__PURE__ */ jsxRuntime.jsxs(
1277
- "span",
1278
- {
1279
- style: {
1280
- whiteSpace: "nowrap",
1281
- fontFamily: '"Cambria Math", "STIX Two Math", serif'
1282
- },
1283
- children: [
1284
- "(",
1285
- equationNumber,
1286
- ")"
1287
- ]
1288
- }
1289
- )
1290
- ]
1291
- },
1292
- `${elementId}-seg-${segmentIndex}`
1293
- );
1294
- }
1295
- return /* @__PURE__ */ jsxRuntime.jsx("span", { style: fontSize ? { fontSize } : void 0, children: equationContent }, `${elementId}-seg-${segmentIndex}`);
1296
- }
1297
- function renderHyperlink(run, spanNode, key, ctx) {
1298
- const url = run.hyperlink?.url;
1299
- const onHyperlinkClick = ctx.onHyperlinkClick;
1300
- if (!url || !onHyperlinkClick) {
1301
- return spanNode;
1302
- }
1303
- const requireCtrlClick = ctx.requireCtrlClick;
1304
- const displayUrl = url.startsWith("ppaction://") ? url.replace(/^ppaction:\/\//u, "").split("?")[0] : url;
1305
- const targetFrame = run.hyperlink?.target;
1306
- const follow = (modified) => {
1307
- if (requireCtrlClick && !modified) {
1308
- return false;
1309
- }
1310
- onHyperlinkClick(url, targetFrame);
1311
- return true;
1312
- };
1313
- return /* @__PURE__ */ jsxRuntime.jsxs(
1314
- "span",
1315
- {
1316
- role: "link",
1317
- tabIndex: 0,
1318
- className: requireCtrlClick ? "group/link relative" : void 0,
1319
- style: { cursor: requireCtrlClick ? void 0 : "pointer", pointerEvents: "auto" },
1320
- title: run.hyperlink?.tooltip,
1321
- onClick: (e) => {
1322
- if (!follow(e.ctrlKey || e.metaKey)) {
1323
- return;
1324
- }
1325
- e.stopPropagation();
1326
- e.preventDefault();
1327
- },
1328
- onKeyDown: (e) => {
1329
- if (e.key !== "Enter" && e.key !== " ") {
1330
- return;
1331
- }
1332
- if (!follow(e.ctrlKey || e.metaKey)) {
1333
- return;
1334
- }
1335
- e.preventDefault();
1336
- e.stopPropagation();
1337
- },
1338
- children: [
1339
- spanNode,
1340
- requireCtrlClick && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none absolute left-0 top-full z-[9999] mt-1 max-w-64 opacity-0 transition-opacity duration-150 group-hover/link:opacity-100", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col rounded border border-border bg-popover px-2.5 py-1.5 shadow-lg", children: [
1341
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs text-foreground", children: displayUrl }),
1342
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mt-0.5 text-[10px] text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(FollowLinkHint, {}) })
1343
- ] }) })
1344
- ]
1345
- },
1346
- `${key}-link`
1347
- );
1348
- }
1349
- function FollowLinkHint() {
1350
- const { t } = reactI18next.useTranslation();
1351
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: t("pptx.linkTooltip.followLink") });
1352
- }
1353
- function wrapWithTextReflection(run, key, spanNode, spanStyle, baseContent) {
1354
- if (!run.reflection) {
1355
- return spanNode;
1356
- }
1357
- return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { position: "relative", display: "inline-block" }, children: [
1358
- spanNode,
1359
- /* @__PURE__ */ jsxRuntime.jsx(
1360
- "span",
1361
- {
1362
- "aria-hidden": "true",
1363
- className: "pptx-react-text-reflection",
1364
- style: run.reflection,
1365
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: spanStyle, children: baseContent })
1366
- }
1367
- )
1368
- ] }, `${key}-reflwrap`);
1369
- }
1370
- var BASELINE_FONT_SCALE = 0.65;
1371
- function renderParagraphRun(run, segment, ctx, keySuffix = "") {
1372
- const { element, fallbackColor, findHighlights, onHyperlinkClick } = ctx;
1373
- const segmentIndex = run.segmentIndex ?? 0;
1374
- const key = `${element.id}-seg-${segmentIndex}${keySuffix}`;
1375
- if (run.equation) {
1376
- return renderEquationSegment(
1377
- element.id,
1378
- segmentIndex,
1379
- run.equation.xml,
1380
- run.equation.number,
1381
- typeof run.style.fontSize === "string" ? run.style.fontSize : void 0
1382
- );
1383
- }
1384
- const segmentStyle = segment?.style ?? {};
1385
- const textValue = run.text;
1386
- const lines = textValue.split("\n");
1387
- const resolvedSegmentColor = chunkUHW3R465_js.normalizeHexColor(
1388
- segmentStyle.color || element.textStyle?.color,
1389
- run.hyperlink ? HYPERLINK_COLOR : fallbackColor
1390
- );
1391
- const rawBaseline = typeof segmentStyle.baseline === "number" ? segmentStyle.baseline : 0;
1392
- const baselineFraction = rawBaseline === 0 ? 0 : Math.abs(rawBaseline) >= 1e3 ? rawBaseline / 1e5 : rawBaseline / 100;
1393
- const baselineFontScale = baselineFraction !== 0 ? BASELINE_FONT_SCALE : 1;
1394
- const rawFontSize = segmentStyle.fontSize || element.textStyle?.fontSize || DEFAULT_TEXT_FONT_SIZE;
1395
- const baseFontSize = chunkUHW3R465_js.scaleFontSizeForAutoFit(
1396
- rawFontSize,
1397
- chunkUHW3R465_js.resolveAutoFitFontScale(element.textStyle)
1398
- );
1399
- const baselineShift = baselineFraction !== 0 ? `${baselineFraction * baseFontSize}px` : void 0;
1400
- const fontKerning = chunkUHW3R465_js.resolveFontKerning(segmentStyle.kerning, baseFontSize);
1401
- const scriptFallbackWins = Boolean(
1402
- segmentStyle.scriptFallbackFont && segmentStyle.fontFamilyIsCascadeDefault
1403
- );
1404
- const rawFontFamily = segmentStyle.fontFamily || element.textStyle?.fontFamily;
1405
- const baseFontFamily = scriptFallbackWins ? chunkUHW3R465_js.getSubstituteFontFamily(segmentStyle.scriptFallbackFont) : rawFontFamily ? chunkUHW3R465_js.getSubstituteFontFamily(
1406
- rawFontFamily,
1407
- chunkUHW3R465_js.parsePanoseString(segmentStyle.latinFontPanose ?? element.textStyle?.latinFontPanose)
1408
- ) : DEFAULT_FONT_FAMILY2;
1409
- const scriptFonts = chunkUHW3R465_js.resolveScriptFontSet(segmentStyle, element.textStyle, baseFontFamily);
1410
- const needsScriptFonts = chunkUHW3R465_js.hasDistinctScriptFonts(scriptFonts);
1411
- const authoredLetterSpacing = chunkUHW3R465_js.authoredLetterSpacingPx(segmentStyle);
1412
- const metricFont = {
1413
- fontFamily: baseFontFamily,
1414
- fontSizePx: baseFontSize * baselineFontScale,
1415
- bold: Boolean(segmentStyle.bold),
1416
- italic: Boolean(segmentStyle.italic)
1417
- };
1418
- const nestedStyle = chunkUHW3R465_js.nestedTextDecorationStyle(run.style);
1419
- const metricContext = {
1420
- font: metricFont,
1421
- authoredPx: authoredLetterSpacing,
1422
- nestedStyle,
1423
- eastAsian: ctx.eastAsianBreaks,
1424
- following: ctx.eastAsianFollowing
1425
- };
1426
- const spanStyle = { ...run.style };
1427
- spanStyle.color = resolvedSegmentColor;
1428
- spanStyle.fontSize = baseFontSize * baselineFontScale;
1429
- spanStyle.fontFamily = baseFontFamily;
1430
- spanStyle.verticalAlign = baselineShift;
1431
- spanStyle.fontKerning = fontKerning;
1432
- spanStyle.letterSpacing = chunkUHW3R465_js.pieceLetterSpacing(
1433
- authoredLetterSpacing,
1434
- chunkUHW3R465_js.resolveMetricTrackingPx(textValue, metricFont)
1435
- );
1436
- const hollow = chunkUHW3R465_js.hollowTextFillStyle(segmentStyle, {
1437
- color: resolvedSegmentColor,
1438
- textStroke: typeof spanStyle.WebkitTextStroke === "string" ? spanStyle.WebkitTextStroke : void 0
1439
- });
1440
- if (hollow) {
1441
- Object.assign(spanStyle, hollow);
1442
- }
1443
- const runRtl = segmentStyle.rtl;
1444
- if (runRtl !== void 0) {
1445
- spanStyle.direction = runRtl ? "rtl" : "ltr";
1446
- spanStyle.unicodeBidi = runRtl !== ctx.paragraphRtl ? "bidi-override" : "embed";
1447
- }
1448
- const isUnderlineWords = chunkUHW3R465_js.splitsUnderlineIntoWords(segmentStyle);
1449
- const wordDecoration = isUnderlineWords ? nestedStyle ?? run.underlineWordPieces?.find((piece) => piece.style)?.style : void 0;
1450
- if (isUnderlineWords) {
1451
- const stripped = chunkUHW3R465_js.stripUnderlineDecoration(spanStyle);
1452
- spanStyle.textDecoration = stripped.textDecoration;
1453
- delete spanStyle.textDecorationStyle;
1454
- delete spanStyle.textDecorationThickness;
1455
- delete spanStyle.textUnderlineOffset;
1456
- delete spanStyle.textDecorationColor;
1457
- }
1458
- const baseContent = renderSegmentContent(
1459
- element.id,
1460
- segmentIndex,
1461
- textValue,
1462
- lines,
1463
- needsScriptFonts,
1464
- scriptFonts,
1465
- baseFontFamily,
1466
- findHighlights,
1467
- chunkUHW3R465_js.buildTabContext(
1468
- element.textStyle?.tabStops,
1469
- element.textStyle?.defaultTabSize,
1470
- baseFontSize,
1471
- baseFontFamily,
1472
- Boolean(segmentStyle.bold),
1473
- Boolean(segmentStyle.italic),
1474
- { language: segmentStyle.language, rtl: ctx.paragraphRtl === true }
1475
- ),
1476
- metricContext,
1477
- isUnderlineWords,
1478
- wordDecoration
1479
- );
1480
- const spanNode = /* @__PURE__ */ jsxRuntime.jsx("span", { "data-seg-idx": segmentIndex, style: spanStyle, children: renderRubyOrText(run, baseContent) }, key);
1481
- const reflectedNode = wrapWithTextReflection(run, key, spanNode, spanStyle, baseContent);
1482
- return run.hyperlink && onHyperlinkClick ? renderHyperlink(run, reflectedNode, key, ctx) : reflectedNode;
1483
- }
1484
- function renderRubyOrText(run, baseContent) {
1485
- if (!run.ruby) {
1486
- return baseContent;
1487
- }
1488
- return /* @__PURE__ */ jsxRuntime.jsxs("ruby", { children: [
1489
- baseContent,
1490
- /* @__PURE__ */ jsxRuntime.jsx("rp", { children: "(" }),
1491
- /* @__PURE__ */ jsxRuntime.jsx("rt", { style: run.ruby.style, children: run.ruby.text }),
1492
- /* @__PURE__ */ jsxRuntime.jsx("rp", { children: ")" })
1493
- ] });
1494
- }
1495
- function renderSeededListRun(seed, runs, segments, context) {
1496
- const sourceRun = runs.find((candidate) => candidate.segmentIndex === seed.segmentIndex);
1497
- const segment = sourceRun ? segments[seed.segmentIndex] : { text: seed.text, style: seed.style };
1498
- const resolvedSegment = {
1499
- ...segment,
1500
- style: chunkUHW3R465_js.withInlineListDecorationDefaults(segment.style, context.element.textStyle)
1501
- };
1502
- const decorationCss = chunkUHW3R465_js.segmentStyleToCss(
1503
- resolvedSegment,
1504
- chunkUHW3R465_js.resolveAutoFitFontScale(context.element.textStyle)
1505
- );
1506
- chunkUHW3R465_js.applyUnderlineVariant(decorationCss, resolvedSegment);
1507
- const run = sourceRun ? { ...sourceRun, style: { ...sourceRun.style, ...chunkUHW3R465_js.nestedTextDecorationStyle(decorationCss) } } : {
1508
- text: seed.text,
1509
- style: decorationCss,
1510
- segmentIndex: seed.segmentIndex
1511
- };
1512
- const rendered = renderParagraphRun(run, resolvedSegment, context);
1513
- if (!React8__default.default.isValidElement(rendered)) {
1514
- return rendered;
1515
- }
1516
- return React8__default.default.cloneElement(rendered, {
1517
- "data-pptx-list-run": seed.token,
1518
- ...seed.text === "" ? { children: /* @__PURE__ */ jsxRuntime.jsx("br", {}) } : {}
1519
- });
1520
- }
1521
- function renderTextSegments(element, fallbackColor, emptyFallback, findHighlights, onHyperlinkClick, fieldContext, subElementAnimStates, segmentOverrides, requireCtrlClick, placeholderPrompt, inlineListSeed) {
1522
- if (!chunkUHW3R465_js.hasTextProperties(element)) {
1523
- return emptyFallback || null;
1524
- }
1525
- const segments = segmentOverrides ?? element.textSegments;
1526
- if (!segments || segments.length === 0) {
1527
- if (placeholderPrompt) {
1528
- return /* @__PURE__ */ jsxRuntime.jsx("span", { style: placeholderPrompt.style, children: placeholderPrompt.text });
1529
- }
1530
- return element.text || emptyFallback || "";
1531
- }
1532
- const paragraphs = chunkUHW3R465_js.buildParagraphs(element, fieldContext, segmentOverrides, {
1533
- preserveTrailingEmpty: inlineListSeed ? true : void 0,
1534
- eastAsianRunPieces: false
1535
- });
1536
- const ctx = {
1537
- element,
1538
- fallbackColor,
1539
- findHighlights,
1540
- onHyperlinkClick,
1541
- requireCtrlClick
1542
- };
1543
- return paragraphs.map(
1544
- (para, paraIndex) => renderParagraph(
1545
- para,
1546
- paraIndex,
1547
- paragraphs.length,
1548
- segments,
1549
- ctx,
1550
- subElementAnimStates,
1551
- inlineListSeed
1552
- )
1553
- );
1554
- }
1555
- function joinRunsBySegment(runs) {
1556
- const out = [];
1557
- for (const run of runs) {
1558
- const last = out[out.length - 1];
1559
- if (last && run.segmentIndex !== void 0 && last.segmentIndex === run.segmentIndex && !last.equation && !run.equation) {
1560
- last.text += run.text;
1561
- continue;
1562
- }
1563
- out.push({ ...run });
1564
- }
1565
- return out;
1566
- }
1567
- function renderParagraph(para, paraIndex, paraCount, segments, ctx, subElementAnimStates, inlineListSeed) {
1568
- const element = ctx.element;
1569
- const runCtx = {
1570
- ...ctx,
1571
- paragraphRtl: para.rtl,
1572
- eastAsianBreaks: para.eastAsianBreaks
1573
- };
1574
- const runs = joinRunsBySegment(para.runs);
1575
- const listParagraph = inlineListSeed?.paragraphs[paraIndex];
1576
- const renderedRuns = listParagraph ? listParagraph.runs.map((run) => renderSeededListRun(run, runs, segments, runCtx)) : runs.map(
1577
- (run, i) => renderParagraphRun(run, segments[run.segmentIndex ?? -1], {
1578
- ...runCtx,
1579
- eastAsianFollowing: para.eastAsianBreaks ? chunkUHW3R465_js.followingText(runs, i) : void 0
1580
- })
1581
- );
1582
- const paraStyle = {
1583
- // `text-align`, BiDi `direction` / `unicode-bidi` and the kinsoku
1584
- // line-break rules, resolved by shared from this paragraph's own `a:pPr`.
1585
- ...para.paragraphStyle
1586
- };
1587
- if (para.strutFontSizePx !== void 0) {
1588
- paraStyle.fontSize = para.strutFontSizePx;
1589
- }
1590
- if (para.spaceBeforePx !== void 0) {
1591
- paraStyle.marginTop = para.spaceBeforePx;
1592
- }
1593
- if (para.spaceAfterPx !== void 0) {
1594
- paraStyle.marginBottom = para.spaceAfterPx;
1595
- }
1596
- if (para.lineHeight !== void 0) {
1597
- paraStyle.lineHeight = para.lineHeight;
1598
- }
1599
- if (para.marginLeftPx !== void 0) {
1600
- if (para.rtl === true) {
1601
- paraStyle.marginRight = para.marginLeftPx;
1602
- } else {
1603
- paraStyle.marginLeft = para.marginLeftPx;
1604
- }
1605
- }
1606
- if (para.textIndentPx !== void 0) {
1607
- paraStyle.textIndent = para.textIndentPx;
1608
- }
1609
- const marker = renderBulletMarker(para, paraIndex, element.id);
1610
- const wrappedContent = wrapWithTextBuildAnimation(
1611
- element.id,
1612
- paraIndex,
1613
- renderedRuns,
1614
- runs,
1615
- subElementAnimStates,
1616
- // A staged build splits the paragraph but must not flatten it: each piece
1617
- // is re-rendered through the SAME run renderer, so it keeps its run's
1618
- // font, size, colour and decoration while it animates.
1619
- (run, text, pieceKey) => renderParagraphRun(
1620
- { ...run, text },
1621
- segments[run.segmentIndex ?? -1],
1622
- runCtx,
1623
- `-build-${pieceKey}`
1624
- )
1625
- );
1626
- const needsWrapper = Boolean(listParagraph) || Object.keys(paraStyle).length > 0 || marker !== null;
1627
- if (!needsWrapper) {
1628
- return /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
1629
- wrappedContent,
1630
- paraIndex < paraCount - 1 ? /* @__PURE__ */ jsxRuntime.jsx("br", {}) : null
1631
- ] }, `${element.id}-para-${paraIndex}`);
1632
- }
1633
- return /* @__PURE__ */ jsxRuntime.jsxs(
1634
- "div",
1635
- {
1636
- style: paraStyle,
1637
- "data-pptx-list-paragraph": listParagraph?.token,
1638
- children: [
1639
- marker,
1640
- para.isEmpty && !listParagraph ? /* @__PURE__ */ jsxRuntime.jsx("br", {}) : wrappedContent
1641
- ]
1642
- },
1643
- `${element.id}-para-${paraIndex}`
1644
- );
1645
- }
1646
- function renderBulletMarker(para, paraIndex, elementId) {
1647
- const picture = para.bulletPicture;
1648
- if (picture?.src) {
1649
- return /* @__PURE__ */ jsxRuntime.jsx(
1650
- "img",
1651
- {
1652
- "data-pptx-bullet-marker": true,
1653
- contentEditable: false,
1654
- src: picture.src,
1655
- alt: picture.accessibleLabel,
1656
- style: {
1657
- width: picture.sizePx,
1658
- height: picture.sizePx,
1659
- display: "inline-block",
1660
- verticalAlign: "middle",
1661
- marginInlineEnd: 4,
1662
- objectFit: "contain"
1663
- }
1664
- },
1665
- `${elementId}-para-${paraIndex}-bullet-img`
1666
- );
1667
- }
1668
- if (para.bulletMarker === void 0) {
1669
- return null;
1670
- }
1671
- return /* @__PURE__ */ jsxRuntime.jsx(
1672
- "span",
1673
- {
1674
- className: "pptx-bullet",
1675
- "data-pptx-bullet-marker": true,
1676
- contentEditable: false,
1677
- style: para.bulletStyle,
1678
- "aria-label": picture?.accessibleLabel,
1679
- children: para.bulletMarker
1680
- },
1681
- `${elementId}-para-${paraIndex}-bullet`
1682
- );
1683
- }
1684
- function getDuotoneColors(element) {
1685
- if (!chunkUHW3R465_js.isImageLikeElement(element)) {
1686
- return void 0;
1687
- }
1688
- return element.imageEffects?.duotone;
1689
- }
1690
- function buildLineShadowCss(element) {
1691
- if (!chunkUHW3R465_js.hasShapeProperties(element)) {
1692
- return void 0;
1693
- }
1694
- const ss = element.shapeStyle;
1695
- if (!ss?.lineShadowColor || ss.lineShadowColor === "transparent") {
1696
- return void 0;
1697
- }
1698
- const offsetX = typeof ss.lineShadowOffsetX === "number" ? ss.lineShadowOffsetX : 2;
1699
- const offsetY = typeof ss.lineShadowOffsetY === "number" ? ss.lineShadowOffsetY : 2;
1700
- const blur = typeof ss.lineShadowBlur === "number" ? Math.max(0, ss.lineShadowBlur) : 4;
1701
- const opacity = typeof ss.lineShadowOpacity === "number" ? Math.max(0, Math.min(1, ss.lineShadowOpacity)) : 0.35;
1702
- return `${Math.round(offsetX)}px ${Math.round(offsetY)}px ${Math.round(blur)}px ${chunkUHW3R465_js.colorWithOpacity(
1703
- chunkUHW3R465_js.normalizeHexColor(ss.lineShadowColor, "#000000"),
1704
- opacity
1705
- )}`;
1706
- }
1707
- function buildLineGlowFilter(element) {
1708
- if (!chunkUHW3R465_js.hasShapeProperties(element)) {
1709
- return void 0;
1710
- }
1711
- const ss = element.shapeStyle;
1712
- if (!ss?.lineGlowColor || ss.lineGlowColor === "transparent" || !ss.lineGlowRadius) {
1713
- return void 0;
1714
- }
1715
- const glowOpacity = typeof ss.lineGlowOpacity === "number" ? ss.lineGlowOpacity : 0.75;
1716
- const glowRad = Math.round(Math.max(0, ss.lineGlowRadius));
1717
- const glowCol = chunkUHW3R465_js.colorWithOpacity(chunkUHW3R465_js.normalizeHexColor(ss.lineGlowColor, "#ffff00"), glowOpacity);
1718
- return `drop-shadow(0 0 ${glowRad}px ${glowCol})`;
1719
- }
1720
- function getDagDuotoneFilterId(elementId) {
1721
- return `dag-duotone-${elementId}`;
1722
- }
1723
- function hasDagDuotoneEffect(element) {
1724
- if (!chunkUHW3R465_js.hasShapeProperties(element)) {
1725
- return false;
1726
- }
1727
- return Boolean(element.shapeStyle?.dagDuotone);
1728
- }
1729
- function renderDagDuotoneSvgFilter(elementId, color1, color2) {
1730
- const filterId = getDagDuotoneFilterId(elementId);
1731
- const c1 = chunkUHW3R465_js.hexToRgbUnit(color1);
1732
- const c2 = chunkUHW3R465_js.hexToRgbUnit(color2);
1733
- const grayscaleMatrix = [
1734
- 0.2126,
1735
- 0.7152,
1736
- 0.0722,
1737
- 0,
1738
- 0,
1739
- 0.2126,
1740
- 0.7152,
1741
- 0.0722,
1742
- 0,
1743
- 0,
1744
- 0.2126,
1745
- 0.7152,
1746
- 0.0722,
1747
- 0,
1748
- 0,
1749
- 0,
1750
- 0,
1751
- 0,
1752
- 1,
1753
- 0
1754
- ].join(" ");
1755
- return /* @__PURE__ */ jsxRuntime.jsx(
1756
- "svg",
1757
- {
1758
- width: 0,
1759
- height: 0,
1760
- style: { position: "absolute", overflow: "hidden" },
1761
- "aria-hidden": "true",
1762
- children: /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: filterId, colorInterpolationFilters: "sRGB", children: [
1763
- /* @__PURE__ */ jsxRuntime.jsx("feColorMatrix", { type: "matrix", values: grayscaleMatrix }),
1764
- /* @__PURE__ */ jsxRuntime.jsxs("feComponentTransfer", { children: [
1765
- /* @__PURE__ */ jsxRuntime.jsx("feFuncR", { type: "linear", slope: c2.r - c1.r, intercept: c1.r }),
1766
- /* @__PURE__ */ jsxRuntime.jsx("feFuncG", { type: "linear", slope: c2.g - c1.g, intercept: c1.g }),
1767
- /* @__PURE__ */ jsxRuntime.jsx("feFuncB", { type: "linear", slope: c2.b - c1.b, intercept: c1.b })
1768
- ] })
1769
- ] }) })
1770
- }
1771
- );
1772
- }
1773
-
1774
- // src/viewer/utils/shape-visual-3d.ts
1775
- function build3DExtrusionData2(shape3d, scene3d, fillColor, elementWidth, elementHeight) {
1776
- return chunkUHW3R465_js.build3DExtrusionData(
1777
- shape3d,
1778
- scene3d,
1779
- fillColor,
1780
- elementWidth,
1781
- elementHeight
1782
- );
1783
- }
1784
- function apply3dEffects2(base, scene3d, shape3d, fillColorFallback, elementSize, elementId) {
1785
- chunkUHW3R465_js.apply3dEffects(
1786
- base,
1787
- scene3d,
1788
- shape3d,
1789
- fillColorFallback,
1790
- elementSize,
1791
- elementId
1792
- );
1793
- }
1794
-
1795
- // src/viewer/utils/shape-visual-style.ts
1796
- function rendersCustomVectorPath(element) {
1797
- return (element.type === "shape" || element.type === "image" || element.type === "picture") && Boolean(element.pathData) && typeof element.pathWidth === "number" && element.pathWidth > 0 && typeof element.pathHeight === "number" && element.pathHeight > 0;
1798
- }
1799
- function rendersWedgeCalloutVector(element) {
1800
- return element.type === "shape" && chunkUHW3R465_js.isWedgeCalloutPresetShape(element.shapeType);
1801
- }
1802
- function getShapeVisualStyle(element, _hasFill, fillColor, _strokeWidth, _strokeColor, animatesFill, animatesStroke, parentGroupFill) {
1803
- if (element.type === "group") {
1804
- const fx2 = chunkUHW3R465_js.getComputedEffectStyle(element);
1805
- const groupStyle = {};
1806
- if (fx2.filter) {
1807
- groupStyle.filter = fx2.filter;
1808
- }
1809
- if (fx2.overflowVisible) {
1810
- groupStyle.overflow = "visible";
1811
- }
1812
- return groupStyle;
1813
- }
1814
- if (!chunkUHW3R465_js.hasShapeProperties(element)) {
1815
- return {};
1816
- }
1817
- const ss = element.shapeStyle;
1818
- const fill = animatesFill ? void 0 : chunkUHW3R465_js.getComputedFillStyle(element, parentGroupFill);
1819
- const fx = chunkUHW3R465_js.getComputedEffectStyle(element);
1820
- const stroke = chunkUHW3R465_js.getComputedStrokeStyle(element);
1821
- const base = {
1822
- // A gradient fill REPLACES the solid fill, it does not sit on top of it;
1823
- // the whole precedence lives in shared's `getComputedFillStyle`.
1824
- backgroundColor: fill?.backgroundColor ?? "transparent",
1825
- backgroundImage: fill?.backgroundImage,
1826
- backgroundRepeat: fill?.backgroundRepeat,
1827
- backgroundSize: fill?.backgroundSize,
1828
- backgroundPosition: fill?.backgroundPosition,
1829
- // The container always carries `box-sizing: border-box`, so the default
1830
- // `background-origin: padding-box` would size the paint 2px smaller than
1831
- // the shape and make a gradient tile wrap, painting a 1px sliver of its
1832
- // opposite end along the edge. Paint from the border box instead.
1833
- backgroundOrigin: "border-box",
1834
- boxShadow: fx.boxShadow,
1835
- // Reflection is no longer a single CSS property (`-webkit-box-reflect`
1836
- // never worked in Firefox): `ElementRenderer` renders a mirrored sibling
1837
- // node instead, using shared's `getReflectionWrapperStyle` directly (see
1838
- // `ReflectionOverlay`).
1839
- filter: fx.filter,
1840
- opacity: fx.opacity,
1841
- // Only proxy the DAG blend onto the whole element for the blend-only case:
1842
- // with an overlay colour, `ShapeEffectOverlay` paints a separate blended
1843
- // tint layer (shared decides which, and returns only one of the two).
1844
- mixBlendMode: fx.mixBlendMode,
1845
- // An unstroked element must occupy EXACTLY its authored box, so the
1846
- // selection/hover affordance is an `outline` (see `ElementRenderer`) and
1847
- // the border collapses to 0 rather than to a transparent 1px.
1848
- borderWidth: stroke.borderWidth,
1849
- borderColor: animatesStroke ? void 0 : stroke.borderColor,
1850
- borderStyle: stroke.borderStyle,
1851
- // Inherited SVG presentation properties: written on the container so the
1852
- // freeform `<path>` and the stroke overlay both pick them up.
1853
- strokeLinejoin: stroke.strokeLinejoin,
1854
- strokeMiterlimit: stroke.strokeMiterlimit,
1855
- strokeLinecap: stroke.strokeLinecap
1856
- };
1857
- Object.assign(
1858
- base,
1859
- chunkUHW3R465_js.getAnimationColorBaseStyle(element, {
1860
- animatesFill,
1861
- animatesStroke,
1862
- parentGroupFill
1863
- })
1864
- );
1865
- if (element.type === "image" || element.type === "picture") {
1866
- base.borderWidth = 0;
1867
- base.borderColor = void 0;
1868
- base.borderStyle = void 0;
1869
- }
1870
- apply3dEffects2(
1871
- base,
1872
- ss?.scene3d,
1873
- ss?.shape3d,
1874
- ss?.fillColor ?? fillColor,
1875
- {
1876
- width: element.width,
1877
- height: element.height
1878
- },
1879
- element.id
1880
- );
1881
- if (rendersCustomVectorPath(element) || rendersWedgeCalloutVector(element) || chunkUHW3R465_js.isStrokeOnlyPresetElement(element)) {
1882
- base.backgroundColor = "transparent";
1883
- base.backgroundImage = void 0;
1884
- base.borderWidth = void 0;
1885
- base.borderColor = void 0;
1886
- base.borderStyle = void 0;
1887
- }
1888
- if (animatesFill) {
1889
- base.backgroundColor = void 0;
1890
- base.backgroundImage = void 0;
1891
- }
1892
- if (rendersWedgeCalloutVector(element)) {
1893
- return base;
1894
- }
1895
- const geometry = chunkUHW3R465_js.resolveShapeGeometry(element);
1896
- switch (geometry.kind) {
1897
- case "bare":
1898
- return { backgroundColor: "transparent", borderWidth: 0, borderStyle: "none" };
1899
- case "strokeOnly":
1900
- return { ...base, backgroundColor: "transparent", backgroundImage: void 0 };
1901
- case "borderRadius":
1902
- return { ...base, borderRadius: geometry.radius };
1903
- case "clipPath":
1904
- return { ...base, clipPath: geometry.clipPath };
1905
- case "lineEdge":
1906
- return {
1907
- ...base,
1908
- backgroundColor: "transparent",
1909
- borderWidth: 0,
1910
- borderTopWidth: geometry.strokeWidth,
1911
- borderTopColor: stroke.borderColor,
1912
- borderTopStyle: stroke.borderStyle ?? "solid"
1913
- };
1914
- default:
1915
- return base;
1916
- }
1917
- }
1918
- function getConnectorPathGeometry2(element) {
1919
- return chunkUHW3R465_js.getConnectorPathGeometry(element);
1920
- }
1921
- var ARROW_SIZE_SCALE = {
1922
- sm: 0.6,
1923
- med: 1,
1924
- lg: 1.5
1925
- };
1926
- function renderConnectorMarker(markerId, arrowType, color, arrowWidth, arrowLength) {
1927
- if (!arrowType || arrowType === "none") {
1928
- return null;
1929
- }
1930
- const wScale = ARROW_SIZE_SCALE[arrowWidth || "med"] ?? 1;
1931
- const lScale = ARROW_SIZE_SCALE[arrowLength || "med"] ?? 1;
1932
- const mw = Math.round(8 * lScale);
1933
- const mh = Math.round(8 * wScale);
1934
- return /* @__PURE__ */ jsxRuntime.jsx(
1935
- "marker",
1936
- {
1937
- id: markerId,
1938
- markerWidth: mw,
1939
- markerHeight: mh,
1940
- refX: 8,
1941
- refY: 5,
1942
- orient: "auto-start-reverse",
1943
- viewBox: "0 0 10 10",
1944
- markerUnits: "strokeWidth",
1945
- children: arrowType === "triangle" ? /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "0,0 10,5 0,10", fill: color }) : arrowType === "stealth" ? /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "0,0 10,5 0,10 3.4,5", fill: color }) : arrowType === "diamond" ? /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "0,5 5,0 10,5 5,10", fill: color }) : arrowType === "oval" ? /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx: 5, cy: 5, rx: 4, ry: 3.3, fill: color }) : /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0 0 L10 5 L0 10", fill: "none", stroke: color, strokeWidth: 1.6 })
1946
- }
1947
- );
1948
- }
1949
- function renderSvgGradientDefs(gradient) {
1950
- if (!gradient) {
1951
- return null;
1952
- }
1953
- if (gradient.kind === "rectPath") {
1954
- return /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("pattern", { id: gradient.id, patternUnits: "objectBoundingBox", width: 1, height: 1, children: /* @__PURE__ */ jsxRuntime.jsx("image", { href: gradient.href, x: 0, y: 0, width: 1, height: 1, preserveAspectRatio: "none" }) }) });
1955
- }
1956
- const stops = gradient.stops.map((stop, index) => /* @__PURE__ */ jsxRuntime.jsx(
1957
- "stop",
1958
- {
1959
- offset: stop.offset,
1960
- stopColor: stop.color,
1961
- stopOpacity: typeof stop.opacity === "number" ? stop.opacity : void 0
1962
- },
1963
- index
1964
- ));
1965
- return /* @__PURE__ */ jsxRuntime.jsx("defs", { children: gradient.kind === "radial" ? /* @__PURE__ */ jsxRuntime.jsx("radialGradient", { id: gradient.id, cx: gradient.cx, cy: gradient.cy, r: gradient.r, children: stops }) : /* @__PURE__ */ jsxRuntime.jsx(
1966
- "linearGradient",
1967
- {
1968
- id: gradient.id,
1969
- x1: gradient.x1,
1970
- y1: gradient.y1,
1971
- x2: gradient.x2,
1972
- y2: gradient.y2,
1973
- children: stops
1974
- }
1975
- ) });
1976
- }
1977
- function joinStyle(shapeStyle) {
1978
- const lineJoin = shapeStyle?.lineJoin === "bevel" ? "bevel" : shapeStyle?.lineJoin === "miter" ? "miter" : "round";
1979
- const miterLimit = lineJoin === "miter" && typeof shapeStyle?.miterLimit === "number" ? Math.max(shapeStyle.miterLimit / 1e5, 1) : void 0;
1980
- return { lineJoin, miterLimit };
1981
- }
1982
- function strokeContext(shapeStyle, strokePaint, strokeWidth, dashArray) {
1983
- const { lineJoin, miterLimit } = joinStyle(shapeStyle);
1984
- return {
1985
- strokePaint,
1986
- strokeWidth,
1987
- dashArray,
1988
- lineCap: chunkUHW3R465_js.svgLineCap(shapeStyle?.lineCap),
1989
- lineJoin,
1990
- miterLimit,
1991
- offsets: chunkUHW3R465_js.getCompoundLineOffsets(shapeStyle?.compoundLine, strokeWidth),
1992
- widths: chunkUHW3R465_js.getCompoundLineWidths(shapeStyle?.compoundLine, strokeWidth)
1993
- };
1994
- }
1995
- function strokeStrands(d, keyBase, ctx) {
1996
- return ctx.offsets.map((offset, idx) => /* @__PURE__ */ jsxRuntime.jsx(
1997
- "path",
1998
- {
1999
- d,
2000
- fill: "none",
2001
- stroke: ctx.strokePaint,
2002
- strokeWidth: Math.max(ctx.widths[idx] ?? ctx.strokeWidth, 1),
2003
- strokeDasharray: ctx.dashArray,
2004
- strokeLinecap: ctx.lineCap,
2005
- strokeLinejoin: ctx.lineJoin,
2006
- strokeMiterlimit: ctx.miterLimit,
2007
- vectorEffect: "non-scaling-stroke",
2008
- style: offset !== 0 ? { transform: `translate(0, ${offset}px)` } : void 0
2009
- },
2010
- `${keyBase}-s${idx}`
2011
- ));
2012
- }
2013
- function renderCustomGeometryVector(pathData, pathWidth, pathHeight, structuredPaths, shapeStyle, hasFill, fillColor, fillOpacity, strokePaint, strokeWidth, dashArray, animatesFill = false, gradient) {
2014
- const ctx = strokeContext(shapeStyle, strokePaint, strokeWidth, dashArray);
2015
- const subpaths = structuredPaths && structuredPaths.length > 0 ? chunkUHW3R465_js.customGeometryPathsToSvgSubpaths(structuredPaths, pathWidth, pathHeight) : void 0;
2016
- const needsPerSubpath = subpaths !== void 0 && subpaths.some((sp) => sp.fillMode && sp.fillMode !== "norm" || sp.stroke === false);
2017
- const gradientPaint = gradient ? chunkUHW3R465_js.svgGradientFillRef(gradient) : void 0;
2018
- const nodes = [];
2019
- if (subpaths && needsPerSubpath) {
2020
- const paints = chunkUHW3R465_js.buildSubpathPaints(subpaths, hasFill, fillColor, fillOpacity);
2021
- paints.forEach((paint, idx) => {
2022
- if (paint.fill !== "none") {
2023
- const mode = subpaths[idx]?.fillMode;
2024
- const useGradient = gradientPaint && (mode === void 0 || mode === "norm");
2025
- nodes.push(
2026
- /* @__PURE__ */ jsxRuntime.jsx(
2027
- "path",
2028
- {
2029
- d: paint.d,
2030
- fill: animatesFill ? "inherit" : useGradient ? gradientPaint : paint.fill,
2031
- stroke: "none",
2032
- vectorEffect: "non-scaling-stroke"
2033
- },
2034
- `f${idx}`
2035
- )
2036
- );
2037
- }
2038
- if (paint.stroked && strokeWidth > 0) {
2039
- nodes.push(...strokeStrands(paint.d, `p${idx}`, ctx));
2040
- }
2041
- });
2042
- } else {
2043
- if (hasFill) {
2044
- nodes.push(
2045
- /* @__PURE__ */ jsxRuntime.jsx(
2046
- "path",
2047
- {
2048
- d: pathData,
2049
- fill: animatesFill ? "inherit" : gradientPaint ?? chunkUHW3R465_js.colorWithOpacity(fillColor, fillOpacity),
2050
- stroke: "none",
2051
- vectorEffect: "non-scaling-stroke"
2052
- },
2053
- "fill"
2054
- )
2055
- );
2056
- }
2057
- if (strokeWidth > 0) {
2058
- nodes.push(...strokeStrands(pathData, "agg", ctx));
2059
- }
2060
- }
2061
- return /* @__PURE__ */ jsxRuntime.jsxs(
2062
- "svg",
2063
- {
2064
- viewBox: `0 0 ${pathWidth} ${pathHeight}`,
2065
- className: "absolute inset-0 w-full h-full pointer-events-none",
2066
- preserveAspectRatio: "none",
2067
- children: [
2068
- animatesFill ? null : renderSvgGradientDefs(gradient),
2069
- nodes
2070
- ]
2071
- }
2072
- );
2073
- }
2074
- function renderVectorShape(element, hasFill, fillColor, strokeWidth, strokeColor, animatesFill, animatesStroke) {
2075
- if (!chunkUHW3R465_js.hasShapeProperties(element)) {
2076
- return null;
2077
- }
2078
- const normalizedType = (element.shapeType || "").toLowerCase();
2079
- const fillPaint = animatesFill ? "inherit" : chunkUHW3R465_js.colorWithOpacity(fillColor, element.shapeStyle?.fillOpacity);
2080
- const strokePaint = animatesStroke ? "inherit" : chunkUHW3R465_js.colorWithOpacity(strokeColor, element.shapeStyle?.strokeOpacity);
2081
- const dashType = chunkUHW3R465_js.normalizeStrokeDashType(element.shapeStyle?.strokeDash);
2082
- const dashArray = chunkUHW3R465_js.getSvgStrokeDasharray(
2083
- dashType,
2084
- Math.max(strokeWidth, 1),
2085
- element.shapeStyle?.customDashSegments
2086
- );
2087
- if (normalizedType === "can" || normalizedType === "cylinder") {
2088
- const width = Math.max(element.width, 1);
2089
- const height = Math.max(element.height, 1);
2090
- const rim = Math.max(Math.min(height * 0.16, 28), 6);
2091
- const stroke = Math.max(strokeWidth, 1);
2092
- return /* @__PURE__ */ jsxRuntime.jsxs(
2093
- "svg",
2094
- {
2095
- viewBox: `0 0 ${width} ${height}`,
2096
- className: "w-full h-full pointer-events-none",
2097
- preserveAspectRatio: "none",
2098
- children: [
2099
- /* @__PURE__ */ jsxRuntime.jsx(
2100
- "ellipse",
2101
- {
2102
- cx: width / 2,
2103
- cy: rim / 2,
2104
- rx: width / 2,
2105
- ry: rim / 2,
2106
- fill: hasFill ? fillPaint : "none",
2107
- stroke: strokeWidth > 0 ? strokePaint : "none",
2108
- strokeWidth: stroke,
2109
- strokeDasharray: dashArray,
2110
- vectorEffect: "non-scaling-stroke"
2111
- }
2112
- ),
2113
- /* @__PURE__ */ jsxRuntime.jsx(
2114
- "rect",
2115
- {
2116
- x: 0,
2117
- y: rim / 2,
2118
- width,
2119
- height: Math.max(height - rim, 1),
2120
- fill: hasFill ? fillPaint : "none",
2121
- stroke: strokeWidth > 0 ? strokePaint : "none",
2122
- strokeWidth: stroke,
2123
- strokeDasharray: dashArray,
2124
- vectorEffect: "non-scaling-stroke"
2125
- }
2126
- ),
2127
- /* @__PURE__ */ jsxRuntime.jsx(
2128
- "ellipse",
2129
- {
2130
- cx: width / 2,
2131
- cy: height - rim / 2,
2132
- rx: width / 2,
2133
- ry: rim / 2,
2134
- fill: hasFill ? fillPaint : "none",
2135
- stroke: strokeWidth > 0 ? strokePaint : "none",
2136
- strokeWidth: stroke,
2137
- strokeDasharray: dashArray,
2138
- vectorEffect: "non-scaling-stroke"
2139
- }
2140
- )
2141
- ]
2142
- }
2143
- );
2144
- }
2145
- if ((element.type === "shape" || element.type === "image" || element.type === "picture") && element.pathData && element.pathWidth && element.pathHeight && element.pathWidth > 0 && element.pathHeight > 0) {
2146
- return renderCustomGeometryVector(
2147
- element.pathData,
2148
- element.pathWidth,
2149
- element.pathHeight,
2150
- element.customGeometryPaths,
2151
- element.shapeStyle,
2152
- hasFill,
2153
- fillColor,
2154
- element.shapeStyle?.fillOpacity,
2155
- strokePaint,
2156
- strokeWidth,
2157
- dashArray,
2158
- Boolean(animatesFill),
2159
- // A freeform's `a:gradFill` needs a real SVG paint server: the
2160
- // container's `background-image` is suppressed for custom geometry, so
2161
- // without this the shape fell back to the parser's representative solid
2162
- // and lost every fade (issue #132).
2163
- chunkUHW3R465_js.buildSvgGradientDef(element.shapeStyle, element.id)
2164
- );
2165
- }
2166
- if ((element.type === "image" || element.type === "picture") && strokeWidth > 0 && !chunkUHW3R465_js.buildStrokeOutline(element)) {
2167
- const width = Math.max(element.width, 1);
2168
- const height = Math.max(element.height, 1);
2169
- const geometry = chunkUHW3R465_js.getPresetShapeVectorGeometry(
2170
- element.shapeType || "rect",
2171
- width,
2172
- height,
2173
- element.shapeAdjustments
2174
- );
2175
- if (geometry) {
2176
- return /* @__PURE__ */ jsxRuntime.jsx(
2177
- "svg",
2178
- {
2179
- viewBox: `${geometry.minX} ${geometry.minY} ${geometry.viewWidth} ${geometry.viewHeight}`,
2180
- className: "w-full h-full pointer-events-none",
2181
- preserveAspectRatio: "none",
2182
- children: /* @__PURE__ */ jsxRuntime.jsx(
2183
- "path",
2184
- {
2185
- d: geometry.d,
2186
- fill: "none",
2187
- stroke: strokePaint,
2188
- strokeWidth: strokeWidth * 2,
2189
- strokeDasharray: dashArray,
2190
- vectorEffect: "non-scaling-stroke"
2191
- }
2192
- )
2193
- }
2194
- );
2195
- }
2196
- }
2197
- if (element.type === "shape" && chunkUHW3R465_js.isWedgeCalloutPresetShape(element.shapeType)) {
2198
- const width = Math.max(element.width, 1);
2199
- const height = Math.max(element.height, 1);
2200
- const geometry = chunkUHW3R465_js.getPresetShapeVectorGeometry(
2201
- element.shapeType,
2202
- width,
2203
- height,
2204
- element.shapeAdjustments
2205
- );
2206
- if (geometry) {
2207
- const gradient = chunkUHW3R465_js.buildSvgGradientDef(element.shapeStyle, element.id);
2208
- const gradientPaint = gradient ? chunkUHW3R465_js.svgGradientFillRef(gradient) : void 0;
2209
- return /* @__PURE__ */ jsxRuntime.jsxs(
2210
- "svg",
2211
- {
2212
- viewBox: `${geometry.minX} ${geometry.minY} ${geometry.viewWidth} ${geometry.viewHeight}`,
2213
- className: "pointer-events-none",
2214
- preserveAspectRatio: "none",
2215
- style: {
2216
- position: "absolute",
2217
- left: geometry.minX,
2218
- top: geometry.minY,
2219
- width: geometry.viewWidth,
2220
- height: geometry.viewHeight,
2221
- overflow: "visible"
2222
- },
2223
- children: [
2224
- animatesFill ? null : renderSvgGradientDefs(gradient),
2225
- /* @__PURE__ */ jsxRuntime.jsx(
2226
- "path",
2227
- {
2228
- d: geometry.d,
2229
- fill: hasFill ? animatesFill ? "inherit" : gradientPaint ?? fillPaint : "none",
2230
- stroke: strokeWidth > 0 ? strokePaint : "none",
2231
- strokeWidth,
2232
- strokeDasharray: dashArray,
2233
- vectorEffect: "non-scaling-stroke"
2234
- }
2235
- )
2236
- ]
2237
- }
2238
- );
2239
- }
2240
- }
2241
- if (chunkUHW3R465_js.isCalloutShape(normalizedType)) {
2242
- const width = Math.max(element.width, 1);
2243
- const height = Math.max(element.height, 1);
2244
- const geometry = chunkUHW3R465_js.getCalloutLeaderLineGeometry(
2245
- normalizedType,
2246
- width,
2247
- height,
2248
- element.shapeAdjustments
2249
- );
2250
- if (geometry && geometry.points.length >= 2) {
2251
- const leaderPath = chunkUHW3R465_js.buildCalloutLeaderLineSvgPath(geometry);
2252
- const bounds = chunkUHW3R465_js.getCalloutViewBoxBounds(width, height, geometry);
2253
- const lineStroke = Math.max(strokeWidth, 1);
2254
- const offsetLeft = bounds.minX;
2255
- const offsetTop = bounds.minY;
2256
- return /* @__PURE__ */ jsxRuntime.jsxs(
2257
- "svg",
2258
- {
2259
- viewBox: `${bounds.minX} ${bounds.minY} ${bounds.viewWidth} ${bounds.viewHeight}`,
2260
- className: "pointer-events-none",
2261
- preserveAspectRatio: "none",
2262
- style: {
2263
- position: "absolute",
2264
- left: offsetLeft,
2265
- top: offsetTop,
2266
- width: bounds.viewWidth,
2267
- height: bounds.viewHeight,
2268
- overflow: "visible"
2269
- },
2270
- children: [
2271
- geometry.hasAccent && /* @__PURE__ */ jsxRuntime.jsx(
2272
- "line",
2273
- {
2274
- x1: 0,
2275
- y1: 0,
2276
- x2: width,
2277
- y2: 0,
2278
- stroke: strokePaint,
2279
- strokeWidth: lineStroke,
2280
- vectorEffect: "non-scaling-stroke"
2281
- }
2282
- ),
2283
- /* @__PURE__ */ jsxRuntime.jsx(
2284
- "path",
2285
- {
2286
- d: leaderPath,
2287
- fill: "none",
2288
- stroke: strokePaint,
2289
- strokeWidth: lineStroke,
2290
- strokeDasharray: dashArray,
2291
- strokeLinecap: "round",
2292
- strokeLinejoin: "round",
2293
- vectorEffect: "non-scaling-stroke"
2294
- }
2295
- )
2296
- ]
2297
- }
2298
- );
2299
- }
2300
- }
2301
- if (element.type === "connector" || getShapeType(element.shapeType) === "connector" || element.shapeType === "line") {
2302
- const viewWidth = Math.max(element.width, 1);
2303
- const viewHeight = Math.max(element.height, 1);
2304
- const { pathData } = getConnectorPathGeometry2(element);
2305
- const markerSeed = element.id.replace(/[^a-zA-Z0-9_-]/gu, "_");
2306
- const startMarkerId = `${markerSeed}-start-arrow`;
2307
- const endMarkerId = `${markerSeed}-end-arrow`;
2308
- const startArrow = element.shapeStyle?.connectorStartArrow;
2309
- const endArrow = element.shapeStyle?.connectorEndArrow;
2310
- const startArrowW = element.shapeStyle?.connectorStartArrowWidth;
2311
- const startArrowL = element.shapeStyle?.connectorStartArrowLength;
2312
- const endArrowW = element.shapeStyle?.connectorEndArrowWidth;
2313
- const endArrowL = element.shapeStyle?.connectorEndArrowLength;
2314
- const compoundLine = element.shapeStyle?.compoundLine;
2315
- const connectorLineCap = chunkUHW3R465_js.svgLineCap(element.shapeStyle?.lineCap);
2316
- const hitTargetWidth = Math.max(strokeWidth * 3, 12);
2317
- const offsets = chunkUHW3R465_js.getCompoundLineOffsets(compoundLine, strokeWidth);
2318
- const widths = chunkUHW3R465_js.getCompoundLineWidths(compoundLine, strokeWidth);
2319
- return /* @__PURE__ */ jsxRuntime.jsxs(
2320
- "svg",
2321
- {
2322
- viewBox: `0 0 ${viewWidth} ${viewHeight}`,
2323
- className: "w-full h-full",
2324
- preserveAspectRatio: "none",
2325
- style: { overflow: "visible", pointerEvents: "none" },
2326
- children: [
2327
- /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
2328
- renderConnectorMarker(startMarkerId, startArrow, strokePaint, startArrowW, startArrowL),
2329
- renderConnectorMarker(endMarkerId, endArrow, strokePaint, endArrowW, endArrowL)
2330
- ] }),
2331
- /* @__PURE__ */ jsxRuntime.jsx(
2332
- "path",
2333
- {
2334
- d: pathData,
2335
- fill: "none",
2336
- stroke: "transparent",
2337
- strokeWidth: hitTargetWidth,
2338
- strokeLinecap: "round",
2339
- strokeLinejoin: "round",
2340
- style: { pointerEvents: "stroke" }
2341
- }
2342
- ),
2343
- offsets.map((offset, idx) => /* @__PURE__ */ jsxRuntime.jsx(
2344
- "path",
2345
- {
2346
- d: pathData,
2347
- fill: "none",
2348
- stroke: strokePaint,
2349
- strokeWidth: Math.max(widths[idx] ?? strokeWidth, 1),
2350
- strokeDasharray: dashArray,
2351
- strokeLinecap: connectorLineCap,
2352
- strokeLinejoin: "round",
2353
- markerStart: idx === 0 && startArrow && startArrow !== "none" ? `url(#${startMarkerId})` : void 0,
2354
- markerEnd: idx === offsets.length - 1 && endArrow && endArrow !== "none" ? `url(#${endMarkerId})` : void 0,
2355
- vectorEffect: "non-scaling-stroke",
2356
- style: {
2357
- pointerEvents: "none",
2358
- ...offset !== 0 ? { transform: `translate(0, ${offset}px)` } : {}
2359
- }
2360
- },
2361
- idx
2362
- ))
2363
- ]
2364
- }
2365
- );
2366
- }
2367
- return null;
2368
- }
2369
-
2370
- // src/viewer/utils/table-cell-fill.tsx
2371
- function parseGradientFillCss(gradFill) {
2372
- if (!gradFill) {
2373
- return void 0;
2374
- }
2375
- const gsLstRaw = gradFill["a:gsLst"];
2376
- if (!gsLstRaw) {
2377
- return void 0;
2378
- }
2379
- const stops = ensureArrayValue(gsLstRaw["a:gs"]);
2380
- if (stops.length === 0) {
2381
- return void 0;
2382
- }
2383
- const rawStops = stops.map((gs) => {
2384
- const pos = Number.parseInt(String(gs["@_pos"] || "0"), 10) / 1e3;
2385
- const color = chunkUHW3R465_js.parseDrawingColor(gs) ?? "#888888";
2386
- const opacity = chunkUHW3R465_js.parseDrawingColorOpacity(gs);
2387
- return { position: pos, color, opacity };
2388
- }).sort((a, b) => a.position - b.position);
2389
- const stopStrings = rawStops.map((s) => `${chunkUHW3R465_js.colorWithOpacity(s.color, s.opacity)} ${s.position.toFixed(1)}%`).join(", ");
2390
- const lin = gradFill["a:lin"];
2391
- if (lin) {
2392
- const angRaw = Number.parseInt(String(lin["@_ang"] || "0"), 10);
2393
- const angleDeg = Math.round(chunkUHW3R465_js.ooxmlGradientAngleToCssDegrees(angRaw / 6e4));
2394
- return `linear-gradient(${angleDeg}deg, ${stopStrings})`;
2395
- }
2396
- const path = gradFill["a:path"];
2397
- if (path) {
2398
- const pathType = String(path["@_path"] || "circle");
2399
- const fillToRectXml = path["a:fillToRect"];
2400
- const fillToRect = fillToRectXml ? {
2401
- l: Number.parseInt(String(fillToRectXml["@_l"] || "0"), 10) / 1e5,
2402
- t: Number.parseInt(String(fillToRectXml["@_t"] || "0"), 10) / 1e5,
2403
- r: Number.parseInt(String(fillToRectXml["@_r"] || "0"), 10) / 1e5,
2404
- b: Number.parseInt(String(fillToRectXml["@_b"] || "0"), 10) / 1e5
2405
- } : void 0;
2406
- if (pathType === "rect") {
2407
- return chunkUHW3R465_js.buildRectPathGradient(rawStops, void 0, fillToRect);
2408
- }
2409
- let cx = 50;
2410
- let cy = 50;
2411
- if (fillToRect) {
2412
- const { l, t, r, b } = fillToRect;
2413
- cx = (l + (1 - r)) / 2 * 100;
2414
- cy = (t + (1 - b)) / 2 * 100;
2415
- }
2416
- const posX = `${Math.round(cx)}%`;
2417
- const posY = `${Math.round(cy)}%`;
2418
- if (pathType === "shape") {
2419
- return `radial-gradient(farthest-side at ${posX} ${posY}, ${stopStrings})`;
2420
- }
2421
- return `radial-gradient(circle at ${posX} ${posY}, ${stopStrings})`;
2422
- }
2423
- return `linear-gradient(180deg, ${stopStrings})`;
2424
- }
2425
- function parsePatternFillCss(pattFill) {
2426
- if (!pattFill) {
2427
- return void 0;
2428
- }
2429
- const fgColor = chunkUHW3R465_js.parseDrawingColor(pattFill["a:fgClr"]) ?? "#000000";
2430
- const bgColor = chunkUHW3R465_js.parseDrawingColor(pattFill["a:bgClr"]) ?? "#ffffff";
2431
- const preset = String(pattFill["@_prst"] || "ltDnDiag");
2432
- switch (preset) {
2433
- case "ltHorz":
2434
- case "horz":
2435
- case "narHorz":
2436
- case "dkHorz":
2437
- case "wdUpDiag":
2438
- return `repeating-linear-gradient(0deg, ${bgColor}, ${bgColor} 3px, ${fgColor} 3px, ${fgColor} 4px)`;
2439
- case "ltVert":
2440
- case "vert":
2441
- case "narVert":
2442
- case "dkVert":
2443
- case "wdDnDiag":
2444
- return `repeating-linear-gradient(90deg, ${bgColor}, ${bgColor} 3px, ${fgColor} 3px, ${fgColor} 4px)`;
2445
- case "ltDnDiag":
2446
- case "dnDiag":
2447
- case "dkDnDiag":
2448
- return `repeating-linear-gradient(135deg, ${bgColor}, ${bgColor} 3px, ${fgColor} 3px, ${fgColor} 4px)`;
2449
- case "ltUpDiag":
2450
- case "upDiag":
2451
- case "dkUpDiag":
2452
- return `repeating-linear-gradient(45deg, ${bgColor}, ${bgColor} 3px, ${fgColor} 3px, ${fgColor} 4px)`;
2453
- case "dashHorz":
2454
- case "dashVert":
2455
- case "dashDnDiag":
2456
- case "dashUpDiag":
2457
- return `repeating-linear-gradient(135deg, ${bgColor}, ${bgColor} 4px, ${fgColor} 4px, ${fgColor} 6px, ${bgColor} 6px, ${bgColor} 10px)`;
2458
- case "smCheck":
2459
- case "lgCheck":
2460
- return `repeating-conic-gradient(${fgColor} 0% 25%, ${bgColor} 0% 50%) 0 0 / 8px 8px`;
2461
- case "smGrid":
2462
- case "lgGrid":
2463
- return `repeating-linear-gradient(0deg, ${fgColor} 0px, ${fgColor} 1px, transparent 1px, transparent 6px), repeating-linear-gradient(90deg, ${fgColor} 0px, ${fgColor} 1px, transparent 1px, transparent 6px), ${bgColor}`;
2464
- case "dotGrid":
2465
- case "pct5":
2466
- case "pct10":
2467
- case "pct20":
2468
- case "pct25":
2469
- case "pct30":
2470
- case "pct40":
2471
- case "pct50":
2472
- case "pct60":
2473
- case "pct70":
2474
- case "pct75":
2475
- case "pct80":
2476
- case "pct90":
2477
- return `radial-gradient(${fgColor} 1px, ${bgColor} 1px) 0 0 / 4px 4px`;
2478
- case "smConfetti":
2479
- case "lgConfetti":
2480
- case "zigZag":
2481
- case "wave":
2482
- case "sphere":
2483
- case "divot":
2484
- case "shingle":
2485
- case "weave":
2486
- case "plaid":
2487
- case "trellis":
2488
- return `repeating-linear-gradient(45deg, ${bgColor}, ${bgColor} 2px, ${fgColor} 2px, ${fgColor} 3px)`;
2489
- case "solidDmnd":
2490
- case "openDmnd":
2491
- return `repeating-conic-gradient(${fgColor} 0% 25%, ${bgColor} 0% 50%) 0 0 / 10px 10px`;
2492
- default:
2493
- return `repeating-linear-gradient(135deg, ${bgColor}, ${bgColor} 3px, ${fgColor} 3px, ${fgColor} 4px)`;
2494
- }
2495
- }
2496
- function ooxmlDashToCss(dashVal) {
2497
- if (!dashVal) {
2498
- return "solid";
2499
- }
2500
- switch (dashVal) {
2501
- case "dot":
2502
- case "sysDot":
2503
- return "dotted";
2504
- case "dash":
2505
- case "sysDash":
2506
- case "lgDash":
2507
- return "dashed";
2508
- case "dashDot":
2509
- case "lgDashDot":
2510
- case "sysDashDot":
2511
- case "lgDashDotDot":
2512
- case "sysDashDotDot":
2513
- return "dashed";
2514
- case "solid":
2515
- return "solid";
2516
- default:
2517
- return "solid";
2518
- }
2519
- }
2520
- function parseCellBorders(cellProperties) {
2521
- if (!cellProperties) {
2522
- return {};
2523
- }
2524
- const borderStyle = {};
2525
- const edges = [
2526
- { xml: "a:lnL", prefix: "borderLeft" },
2527
- { xml: "a:lnR", prefix: "borderRight" },
2528
- { xml: "a:lnT", prefix: "borderTop" },
2529
- { xml: "a:lnB", prefix: "borderBottom" }
2530
- ];
2531
- for (const edge of edges) {
2532
- const ln = cellProperties[edge.xml];
2533
- if (!ln) {
2534
- continue;
2535
- }
2536
- const widthEmu = Number.parseInt(String(ln["@_w"] || "0"), 10);
2537
- const widthPx = Math.max(1, Math.round(widthEmu / 12700));
2538
- const prstDash = ln["a:prstDash"];
2539
- const dashVal = prstDash ? String(prstDash["@_val"] || "") : void 0;
2540
- const cssBorderStyle = ooxmlDashToCss(dashVal);
2541
- const color = chunkUHW3R465_js.parseDrawingColor(ln["a:solidFill"]);
2542
- if (color) {
2543
- const opacity = chunkUHW3R465_js.parseDrawingColorOpacity(ln["a:solidFill"]);
2544
- const key = `${edge.prefix}`;
2545
- borderStyle[key] = `${widthPx}px ${cssBorderStyle} ${chunkUHW3R465_js.colorWithOpacity(color, opacity)}`;
2546
- }
2547
- }
2548
- return borderStyle;
2549
- }
2550
- function parseCellTextEffects(runProps) {
2551
- const effectLst = runProps?.["a:effectLst"];
2552
- if (!effectLst) {
2553
- return void 0;
2554
- }
2555
- const textShadowParts = [];
2556
- const outerShdw = effectLst["a:outerShdw"];
2557
- if (outerShdw) {
2558
- const shdwColor = chunkUHW3R465_js.parseDrawingColor(outerShdw);
2559
- if (shdwColor) {
2560
- const blurRad = Number.parseInt(String(outerShdw["@_blurRad"] || "0"), 10);
2561
- const blurPx = blurRad > 0 ? Math.round(blurRad / 12700) : 0;
2562
- const distVal = Number.parseInt(String(outerShdw["@_dist"] || "0"), 10);
2563
- const dirVal = Number.parseInt(String(outerShdw["@_dir"] || "0"), 10);
2564
- let offX = 0;
2565
- let offY = 0;
2566
- if (distVal > 0) {
2567
- const angleRad = dirVal / 6e4 * (Math.PI / 180);
2568
- offX = Math.round(distVal * Math.cos(angleRad) / 12700);
2569
- offY = Math.round(distVal * Math.sin(angleRad) / 12700);
2570
- }
2571
- textShadowParts.push(`${offX}px ${offY}px ${blurPx}px ${shdwColor}`);
2572
- }
2573
- }
2574
- const glow = effectLst["a:glow"];
2575
- if (glow) {
2576
- const glowColor = chunkUHW3R465_js.parseDrawingColor(glow);
2577
- if (glowColor) {
2578
- const glowRad = Number.parseInt(String(glow["@_rad"] || "0"), 10);
2579
- const glowPx = glowRad > 0 ? Math.round(glowRad / 12700) : 2;
2580
- textShadowParts.push(`0px 0px ${glowPx}px ${glowColor}`);
2581
- }
2582
- }
2583
- return textShadowParts.length > 0 ? textShadowParts.join(", ") : void 0;
2584
- }
2585
-
2586
- // src/viewer/utils/table-cell-style.tsx
2587
- function extractCellText(cellXml) {
2588
- if (!cellXml) {
2589
- return "";
2590
- }
2591
- const txBody = cellXml["a:txBody"];
2592
- const paragraphs = ensureArrayValue(txBody?.["a:p"]);
2593
- const paragraphTexts = [];
2594
- paragraphs.forEach((paragraph) => {
2595
- const textParts = [];
2596
- const runs = ensureArrayValue(paragraph["a:r"]);
2597
- runs.forEach((run) => {
2598
- textParts.push(chunkUHW3R465_js.xmlText(run["a:t"]) ?? "");
2599
- });
2600
- const fields = ensureArrayValue(paragraph["a:fld"]);
2601
- fields.forEach((field) => {
2602
- textParts.push(chunkUHW3R465_js.xmlText(field["a:t"]) ?? "");
2603
- });
2604
- paragraphTexts.push(textParts.join(""));
2605
- });
2606
- return paragraphTexts.join("\n");
2607
- }
2608
- function parseParagraphAlignment(value) {
2609
- const alignment = String(value || "").toLowerCase();
2610
- if (alignment === "ctr") {
2611
- return "center";
2612
- }
2613
- if (alignment === "r") {
2614
- return "right";
2615
- }
2616
- if (alignment === "just" || alignment === "justify") {
2617
- return "justify";
2618
- }
2619
- return "left";
2620
- }
2621
- function extractTableCellStyle(cellXml, fallbackStyle, schemeColorOverrides) {
2622
- const { color: _fallbackColor, ...fallbackWithoutColor } = fallbackStyle;
2623
- const cellStyle = { ...fallbackWithoutColor };
2624
- const txBody = cellXml["a:txBody"];
2625
- const paragraphs = ensureArrayValue(txBody?.["a:p"]);
2626
- const firstParagraph = paragraphs[0];
2627
- const paragraphProperties = firstParagraph?.["a:pPr"];
2628
- const runs = ensureArrayValue(firstParagraph?.["a:r"]);
2629
- const firstRun = runs[0];
2630
- const runProps = firstRun?.["a:rPr"] || paragraphProperties?.["a:defRPr"];
2631
- if (runProps?.["@_sz"]) {
2632
- const pointSize = Number.parseInt(String(runProps["@_sz"]), 10) / 100;
2633
- if (Number.isFinite(pointSize) && pointSize > 0) {
2634
- cellStyle.fontSize = pointSize * (96 / 72);
2635
- }
2636
- }
2637
- if (runProps?.["@_b"] !== void 0) {
2638
- cellStyle.fontWeight = runProps["@_b"] === "1" ? 700 : 400;
2639
- }
2640
- if (runProps?.["@_i"] !== void 0) {
2641
- cellStyle.fontStyle = runProps["@_i"] === "1" ? "italic" : "normal";
2642
- }
2643
- if (runProps?.["@_u"] !== void 0) {
2644
- cellStyle.textDecorationLine = runProps["@_u"] === "sng" ? "underline" : "none";
2645
- }
2646
- const runColor = chunkUHW3R465_js.parseDrawingColor(runProps?.["a:solidFill"], schemeColorOverrides) || chunkUHW3R465_js.parseDrawingColor(runProps?.["a:highlight"], schemeColorOverrides);
2647
- if (runColor) {
2648
- const opacity = chunkUHW3R465_js.parseDrawingColorOpacity(runProps?.["a:solidFill"]);
2649
- cellStyle.color = chunkUHW3R465_js.colorWithOpacity(runColor, opacity);
2650
- }
2651
- const fontFamily = runProps?.["a:latin"]?.["@_typeface"] || runProps?.["a:ea"]?.["@_typeface"] || runProps?.["a:cs"]?.["@_typeface"];
2652
- if (fontFamily) {
2653
- cellStyle.fontFamily = fontFamily;
2654
- }
2655
- if (paragraphProperties?.["@_algn"]) {
2656
- cellStyle.textAlign = parseParagraphAlignment(paragraphProperties["@_algn"]);
2657
- }
2658
- const cellProperties = cellXml["a:tcPr"];
2659
- const cellFill = chunkUHW3R465_js.parseDrawingColor(
2660
- cellProperties?.["a:solidFill"],
2661
- schemeColorOverrides
2662
- );
2663
- if (cellFill) {
2664
- const opacity = chunkUHW3R465_js.parseDrawingColorOpacity(
2665
- cellProperties?.["a:solidFill"]
2666
- );
2667
- cellStyle.backgroundColor = chunkUHW3R465_js.colorWithOpacity(cellFill, opacity);
2668
- } else {
2669
- const gradCss = parseGradientFillCss(cellProperties?.["a:gradFill"]);
2670
- if (gradCss) {
2671
- cellStyle.background = gradCss;
2672
- } else {
2673
- const pattCss = parsePatternFillCss(cellProperties?.["a:pattFill"]);
2674
- if (pattCss) {
2675
- cellStyle.background = pattCss;
2676
- }
2677
- }
2678
- }
2679
- const edgeBorders = parseCellBorders(cellProperties);
2680
- Object.assign(cellStyle, edgeBorders);
2681
- if (!cellStyle.borderLeftColor && !cellStyle.borderRightColor && !cellStyle.borderTopColor && !cellStyle.borderBottomColor) {
2682
- const borderColor = chunkUHW3R465_js.parseDrawingColor(
2683
- cellProperties?.["a:lnL"]?.["a:solidFill"],
2684
- schemeColorOverrides
2685
- ) || chunkUHW3R465_js.parseDrawingColor(
2686
- cellProperties?.["a:lnR"]?.["a:solidFill"],
2687
- schemeColorOverrides
2688
- ) || chunkUHW3R465_js.parseDrawingColor(
2689
- cellProperties?.["a:lnT"]?.["a:solidFill"],
2690
- schemeColorOverrides
2691
- ) || chunkUHW3R465_js.parseDrawingColor(
2692
- cellProperties?.["a:lnB"]?.["a:solidFill"],
2693
- schemeColorOverrides
2694
- );
2695
- if (borderColor) {
2696
- cellStyle.borderColor = borderColor;
2697
- }
2698
- }
2699
- if (cellProperties) {
2700
- const marL = Number.parseInt(String(cellProperties["@_marL"] || ""), 10);
2701
- const marR = Number.parseInt(String(cellProperties["@_marR"] || ""), 10);
2702
- const marT = Number.parseInt(String(cellProperties["@_marT"] || ""), 10);
2703
- const marB = Number.parseInt(String(cellProperties["@_marB"] || ""), 10);
2704
- const toPx = (emu) => Math.round(emu / 12700);
2705
- if (Number.isFinite(marL) && marL > 0) {
2706
- cellStyle.paddingLeft = toPx(marL);
2707
- }
2708
- if (Number.isFinite(marR) && marR > 0) {
2709
- cellStyle.paddingRight = toPx(marR);
2710
- }
2711
- if (Number.isFinite(marT) && marT > 0) {
2712
- cellStyle.paddingTop = toPx(marT);
2713
- }
2714
- if (Number.isFinite(marB) && marB > 0) {
2715
- cellStyle.paddingBottom = toPx(marB);
2716
- }
2717
- }
2718
- if (cellProperties?.["@_anchor"]) {
2719
- const anchor = String(cellProperties["@_anchor"]);
2720
- if (anchor === "ctr") {
2721
- cellStyle.verticalAlign = "middle";
2722
- } else if (anchor === "b") {
2723
- cellStyle.verticalAlign = "bottom";
2724
- } else {
2725
- cellStyle.verticalAlign = "top";
2726
- }
2727
- }
2728
- if (cellProperties?.["@_vert"]) {
2729
- const vert = String(cellProperties["@_vert"]);
2730
- switch (vert) {
2731
- case "vert":
2732
- case "eaVert":
2733
- case "wordArtVert":
2734
- case "wordArtVertRtl":
2735
- cellStyle.writingMode = "vertical-rl";
2736
- break;
2737
- case "vert270":
2738
- case "mongolianVert":
2739
- cellStyle.writingMode = "vertical-lr";
2740
- break;
2741
- }
2742
- if (vert === "wordArtVert") {
2743
- cellStyle.textOrientation = "upright";
2744
- } else if (cellStyle.writingMode) {
2745
- cellStyle.textOrientation = "mixed";
2746
- }
2747
- if (vert === "wordArtVertRtl") {
2748
- cellStyle.direction = "rtl";
2749
- }
2750
- }
2751
- const textShadow = parseCellTextEffects(runProps);
2752
- if (textShadow) {
2753
- cellStyle.textShadow = textShadow;
2754
- }
2755
- return cellStyle;
2756
- }
2757
-
2758
- // src/viewer/utils/table-band-style.tsx
2759
- function getTableCellBandStyle2(element, rowIndex, cellIndex, rowCount, columnCount, styleCtx) {
2760
- if (element.type !== "table") {
2761
- return void 0;
2762
- }
2763
- return chunkUHW3R465_js.getTableCellBandStyle(element.tableData, rowIndex, cellIndex, rowCount, columnCount, {
2764
- tableStyleMap: styleCtx?.tableStyleMap,
2765
- colorScheme: styleCtx?.theme?.colorScheme,
2766
- fontScheme: styleCtx?.theme?.fontScheme
2767
- });
2768
- }
2769
-
2770
- // src/viewer/utils/table-data-parse.tsx
2771
- function getGraphicDataFromElement(element) {
2772
- return element.rawXml?.["a:graphic"]?.["a:graphicData"];
2773
- }
2774
- function getTableXmlFromElement(element) {
2775
- return getGraphicDataFromElement(element)?.["a:tbl"];
2776
- }
2777
- function parseTableElementData(element, fallbackTextStyle) {
2778
- const table = getTableXmlFromElement(element);
2779
- if (!table) {
2780
- return null;
2781
- }
2782
- const rows = ensureArrayValue(table["a:tr"]);
2783
- if (rows.length === 0) {
2784
- return null;
2785
- }
2786
- const tableGrid = table["a:tblGrid"];
2787
- const gridColumns = ensureArrayValue(
2788
- tableGrid?.["a:gridCol"]
2789
- );
2790
- const columnWidths = gridColumns.map((column) => {
2791
- const width = Number.parseInt(String(column?.["@_w"] || ""), 10);
2792
- return Number.isFinite(width) && width > 0 ? width : 0;
2793
- });
2794
- const totalColumnWidth = columnWidths.reduce((sum, width) => sum + width, 0);
2795
- let columnPercentages = totalColumnWidth > 0 ? columnWidths.map((width) => width / totalColumnWidth * 100) : [];
2796
- const modelWidths = element.type === "table" ? element.tableData?.columnWidths : void 0;
2797
- if (modelWidths?.length && modelWidths.length === gridColumns.length && modelWidths.every((width) => Number.isFinite(width) && width >= 0) && Math.abs(modelWidths.reduce((sum, width) => sum + width, 0) - 1) <= Number.EPSILON * modelWidths.length * 4) {
2798
- columnPercentages = modelWidths.map((width) => width * 100);
2799
- }
2800
- const cells = [];
2801
- rows.forEach((row, rowIndex) => {
2802
- const rowCells = ensureArrayValue(row["a:tc"]);
2803
- rowCells.forEach((cell, columnIndex) => {
2804
- cells.push({
2805
- rowIndex,
2806
- columnIndex,
2807
- text: extractCellText(cell),
2808
- style: extractTableCellStyle(cell, fallbackTextStyle),
2809
- rawCell: cell
2810
- });
2811
- });
2812
- });
2813
- const columnCount = Math.max(
2814
- columnPercentages.length,
2815
- rows.reduce((maxCount, row) => {
2816
- const rowCells = ensureArrayValue(row["a:tc"]);
2817
- return Math.max(maxCount, rowCells.length);
2818
- }, 0)
2819
- );
2820
- return {
2821
- rowCount: rows.length,
2822
- columnCount,
2823
- rows,
2824
- columnPercentages,
2825
- cells
2826
- };
2827
- }
2828
- function renderTableCellContent(cell, fallbackText) {
2829
- const runs = cell?.textRuns;
2830
- if (!runs || runs.length === 0) {
2831
- return fallbackText || "\xA0";
2832
- }
2833
- return runs.map((run, index) => {
2834
- if (run.isParagraphBreak) {
2835
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "block", height: 0 } }, `p-${index}`);
2836
- }
2837
- if (run.isLineBreak) {
2838
- return /* @__PURE__ */ jsxRuntime.jsx("br", {}, `br-${index}`);
2839
- }
2840
- return /* @__PURE__ */ jsxRuntime.jsx(
2841
- "span",
2842
- {
2843
- style: { position: "relative", ...chunkUHW3R465_js.cellRunStyle(run) },
2844
- children: run.text
2845
- },
2846
- `r-${index}`
2847
- );
2848
- });
2849
- }
2850
- function getCellDiagonalBorders2(style, tableData, pos, styleCtx) {
2851
- return chunkUHW3R465_js.getCellDiagonalBorders(style, tableData, pos, {
2852
- tableStyleMap: styleCtx?.tableStyleMap,
2853
- colorScheme: styleCtx?.theme?.colorScheme,
2854
- fontScheme: styleCtx?.theme?.fontScheme
2855
- });
2856
- }
2857
- function TableCellDiagonalBorders({
2858
- diag
2859
- }) {
2860
- const hasDown = Boolean(diag.diagDownColor && diag.diagDownWidth);
2861
- const hasUp = Boolean(diag.diagUpColor && diag.diagUpWidth);
2862
- if (!hasDown && !hasUp) {
2863
- return null;
2864
- }
2865
- return /* @__PURE__ */ jsxRuntime.jsxs(
2866
- "svg",
2867
- {
2868
- "aria-hidden": "true",
2869
- style: {
2870
- position: "absolute",
2871
- inset: 0,
2872
- width: "100%",
2873
- height: "100%",
2874
- pointerEvents: "none",
2875
- overflow: "visible"
2876
- },
2877
- children: [
2878
- hasDown && /* @__PURE__ */ jsxRuntime.jsx(
2879
- "line",
2880
- {
2881
- x1: "0",
2882
- y1: "0",
2883
- x2: "100%",
2884
- y2: "100%",
2885
- stroke: diag.diagDownColor,
2886
- strokeWidth: diag.diagDownWidth
2887
- }
2888
- ),
2889
- hasUp && /* @__PURE__ */ jsxRuntime.jsx(
2890
- "line",
2891
- {
2892
- x1: "0",
2893
- y1: "100%",
2894
- x2: "100%",
2895
- y2: "0",
2896
- stroke: diag.diagUpColor,
2897
- strokeWidth: diag.diagUpWidth
2898
- }
2899
- )
2900
- ]
2901
- }
2902
- );
2903
- }
2904
- function TableCellInput({
2905
- initialText,
2906
- style,
2907
- onCommit,
2908
- onCancel
2909
- }) {
2910
- const inputRef = React8.useRef(null);
2911
- const committedRef = React8.useRef(false);
2912
- const onCommitRef = React8.useRef(onCommit);
2913
- onCommitRef.current = onCommit;
2914
- React8.useEffect(() => {
2915
- const el = inputRef.current;
2916
- if (el) {
2917
- el.focus();
2918
- el.select();
2919
- }
2920
- }, []);
2921
- React8.useEffect(() => {
2922
- const input = inputRef.current;
2923
- return () => {
2924
- if (!committedRef.current && input) {
2925
- onCommitRef.current(input.value);
2926
- }
2927
- };
2928
- }, []);
2929
- const doCommit = (text) => {
2930
- if (committedRef.current) {
2931
- return;
2932
- }
2933
- committedRef.current = true;
2934
- onCommit(text);
2935
- };
2936
- const doCancel = () => {
2937
- committedRef.current = true;
2938
- onCancel();
2939
- };
2940
- return /* @__PURE__ */ jsxRuntime.jsx(
2941
- "input",
2942
- {
2943
- ref: inputRef,
2944
- type: "text",
2945
- defaultValue: initialText,
2946
- className: "w-full bg-transparent outline-none",
2947
- style: {
2948
- ...style,
2949
- padding: 0,
2950
- margin: 0,
2951
- border: "none"
2952
- },
2953
- onPointerDown: (e) => e.stopPropagation(),
2954
- onMouseDown: (e) => e.stopPropagation(),
2955
- onClick: (e) => e.stopPropagation(),
2956
- onDoubleClick: (e) => e.stopPropagation(),
2957
- onBlur: (e) => doCommit(e.currentTarget.value),
2958
- onKeyDown: (e) => {
2959
- e.stopPropagation();
2960
- if (e.key === "Escape") {
2961
- e.preventDefault();
2962
- doCancel();
2963
- } else if (e.key === "Enter") {
2964
- e.preventDefault();
2965
- doCommit(e.currentTarget.value);
2966
- } else if (e.key === "Tab") {
2967
- e.preventDefault();
2968
- doCommit(e.currentTarget.value);
2969
- }
2970
- }
2971
- }
2972
- );
2973
- }
2974
- function TableResizeOverlay({
2975
- children,
2976
- columnWidths,
2977
- editable,
2978
- onResizeColumns,
2979
- onResizeRow
2980
- }) {
2981
- const containerRef = React8.useRef(null);
2982
- const [rowBounds, setRowBounds] = React8.useState([]);
2983
- const dragRef = React8.useRef(null);
2984
- const colBoundaries = React8.useMemo(() => chunkUHW3R465_js.computeColumnBoundaries(columnWidths), [columnWidths]);
2985
- const measureRows = React8.useCallback(() => {
2986
- const container = containerRef.current;
2987
- if (!container) {
2988
- return;
2989
- }
2990
- const table = container.querySelector("table");
2991
- if (!table) {
2992
- return;
2993
- }
2994
- const trs = table.querySelectorAll("tbody > tr");
2995
- const bounds = [];
2996
- let cumHeight = 0;
2997
- trs.forEach((tr, i) => {
2998
- cumHeight += tr.offsetHeight;
2999
- if (i < trs.length - 1) {
3000
- bounds.push(cumHeight);
3001
- }
3002
- });
3003
- setRowBounds((prev) => {
3004
- if (prev.length === bounds.length && prev.every((v, i) => v === bounds[i])) {
3005
- return prev;
3006
- }
3007
- return bounds;
3008
- });
3009
- }, []);
3010
- React8.useLayoutEffect(() => {
3011
- measureRows();
3012
- });
3013
- React8.useEffect(() => {
3014
- const handleMouseMove = (e) => {
3015
- const drag = dragRef.current;
3016
- if (!drag) {
3017
- return;
3018
- }
3019
- e.preventDefault();
3020
- const delta = drag.type === "col" ? e.clientX - drag.startPos : e.clientY - drag.startPos;
3021
- drag.handleEl.style.transform = drag.type === "col" ? `translateX(${delta}px)` : `translateY(${delta}px)`;
3022
- };
3023
- const handleMouseUp = (e) => {
3024
- const drag = dragRef.current;
3025
- if (!drag || !containerRef.current) {
3026
- return;
3027
- }
3028
- const rect = containerRef.current.getBoundingClientRect();
3029
- if (e.clientX !== drag.startPos && drag.type === "col" && drag.initialWidths && onResizeColumns) {
3030
- const deltaProp = (e.clientX - drag.startPos) / rect.width;
3031
- onResizeColumns(chunkUHW3R465_js.computeResizedColumnWidths(drag.initialWidths, drag.index, deltaProp));
3032
- } else if (e.clientY !== drag.startPos && drag.type === "row" && onResizeRow) {
3033
- const deltaY = e.clientY - drag.startPos;
3034
- const newHeight = chunkUHW3R465_js.computeResizedRowHeight(
3035
- drag.initialRowHeight ?? chunkUHW3R465_js.DEFAULT_ROW_HEIGHT,
3036
- deltaY
3037
- );
3038
- onResizeRow(drag.index, newHeight);
3039
- }
3040
- drag.handleEl.style.transform = "";
3041
- document.body.style.cursor = "";
3042
- document.body.style.userSelect = "";
3043
- dragRef.current = null;
3044
- };
3045
- document.addEventListener("mousemove", handleMouseMove);
3046
- document.addEventListener("mouseup", handleMouseUp);
3047
- return () => {
3048
- document.removeEventListener("mousemove", handleMouseMove);
3049
- document.removeEventListener("mouseup", handleMouseUp);
3050
- };
3051
- }, [onResizeColumns, onResizeRow]);
3052
- if (!editable) {
3053
- return children;
3054
- }
3055
- const startColDrag = (e, index) => {
3056
- e.preventDefault();
3057
- e.stopPropagation();
3058
- document.body.style.cursor = "col-resize";
3059
- document.body.style.userSelect = "none";
3060
- dragRef.current = {
3061
- type: "col",
3062
- index,
3063
- startPos: e.clientX,
3064
- handleEl: e.currentTarget,
3065
- initialWidths: [...columnWidths]
3066
- };
3067
- };
3068
- const startRowDrag = (e, index) => {
3069
- e.preventDefault();
3070
- e.stopPropagation();
3071
- const table = containerRef.current?.querySelector("table");
3072
- const tr = table?.querySelectorAll("tbody > tr")[index];
3073
- const actualHeight = tr?.offsetHeight ?? chunkUHW3R465_js.DEFAULT_ROW_HEIGHT;
3074
- document.body.style.cursor = "row-resize";
3075
- document.body.style.userSelect = "none";
3076
- dragRef.current = {
3077
- type: "row",
3078
- index,
3079
- startPos: e.clientY,
3080
- handleEl: e.currentTarget,
3081
- initialRowHeight: actualHeight
3082
- };
3083
- };
3084
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: "relative w-full h-full", children: [
3085
- children,
3086
- colBoundaries.map((leftPct, i) => /* @__PURE__ */ jsxRuntime.jsx(
3087
- "div",
3088
- {
3089
- className: "absolute top-0 bottom-0 w-[6px] cursor-col-resize z-10 pointer-events-auto group",
3090
- style: { left: `calc(${leftPct}% - 3px)` },
3091
- onMouseDown: (e) => startColDrag(e, i),
3092
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-px h-full mx-auto bg-transparent group-hover:bg-blue-400/60 transition-colors" })
3093
- },
3094
- `col-h-${i}`
3095
- )),
3096
- rowBounds.map((topPx, i) => /* @__PURE__ */ jsxRuntime.jsx(
3097
- "div",
3098
- {
3099
- className: "absolute left-0 right-0 h-[6px] cursor-row-resize z-10 pointer-events-auto group",
3100
- style: { top: `${topPx - 3}px` },
3101
- onMouseDown: (e) => startRowDrag(e, i),
3102
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-px w-full my-auto bg-transparent group-hover:bg-blue-400/60 transition-colors" })
3103
- },
3104
- `row-h-${i}`
3105
- ))
3106
- ] });
3107
- }
3108
- function renderTableFromTableData(element, textStyle, options) {
3109
- const tableData = element.tableData;
3110
- const rowCount = tableData.rows.length;
3111
- const columnCount = tableData.columnWidths.length;
3112
- const selectedCell = options?.selectedCell || null;
3113
- const isEditable = Boolean(options?.editable) && chunkUHW3R465_js.canDrillDown(element);
3114
- const hasCellSelectionHandler = typeof options?.onSelectCell === "function";
3115
- const sharedCtx = {
3116
- tableStyleMap: options?.styleCtx?.tableStyleMap,
3117
- colorScheme: options?.styleCtx?.theme?.colorScheme,
3118
- fontScheme: options?.styleCtx?.theme?.fontScheme
3119
- };
3120
- const cellCss = (cell, rowIndex, cellIndex) => chunkUHW3R465_js.tableCellCss(
3121
- tableData,
3122
- cell,
3123
- { rowIndex, cellIndex, rowCount, columnCount },
3124
- sharedCtx,
3125
- textStyle
3126
- );
3127
- const selectionRect = (() => {
3128
- if (!selectedCell?.selectedCells || selectedCell.selectedCells.length < 2) {
3129
- return void 0;
3130
- }
3131
- const first = selectedCell.selectedCells[0];
3132
- const last = selectedCell.selectedCells[selectedCell.selectedCells.length - 1];
3133
- return chunkUHW3R465_js.computeSelectionRect(first.row, first.col, last.row, last.col, tableData);
3134
- })();
3135
- return /* @__PURE__ */ jsxRuntime.jsx(
3136
- TableResizeOverlay,
3137
- {
3138
- columnWidths: tableData.columnWidths,
3139
- editable: isEditable,
3140
- onResizeColumns: options?.onResizeColumns,
3141
- onResizeRow: options?.onResizeRow,
3142
- children: /* @__PURE__ */ jsxRuntime.jsx(
3143
- "div",
3144
- {
3145
- className: cn(
3146
- "w-full h-full overflow-hidden",
3147
- isEditable && hasCellSelectionHandler ? "pointer-events-auto" : "pointer-events-none"
3148
- ),
3149
- children: /* @__PURE__ */ jsxRuntime.jsxs(
3150
- "table",
3151
- {
3152
- className: "w-full h-full border-collapse table-fixed",
3153
- style: {
3154
- fontFamily: chunkUHW3R465_js.DEFAULT_FONT_FAMILY,
3155
- // `a:tblPr@rtl` mirrors the column order for RTL decks.
3156
- ...chunkUHW3R465_js.tableContainerCss(tableData)
3157
- },
3158
- children: [
3159
- tableData.columnWidths.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("colgroup", { children: tableData.columnWidths.map((w, ci) => /* @__PURE__ */ jsxRuntime.jsx(
3160
- "col",
3161
- {
3162
- style: { width: `${(w * 100).toFixed(2)}%` }
3163
- },
3164
- `${element.id}-col-${ci}`
3165
- )) }),
3166
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: tableData.rows.map((row, rowIndex) => /* @__PURE__ */ jsxRuntime.jsx(
3167
- "tr",
3168
- {
3169
- style: row.height ? { height: row.height } : void 0,
3170
- children: row.cells.map((cell, cellIndex) => {
3171
- if (cell.hMerge || cell.vMerge) {
3172
- return null;
3173
- }
3174
- const isCellSelected = selectedCell?.rowIndex === rowIndex && selectedCell?.columnIndex === cellIndex;
3175
- const isInMultiSelection = chunkUHW3R465_js.isCellInRect(rowIndex, cellIndex, selectionRect);
3176
- const isCellEditing = isCellSelected && selectedCell?.isEditing;
3177
- const diag = getCellDiagonalBorders2(
3178
- cell.style,
3179
- tableData,
3180
- { rowIndex, cellIndex, rowCount, columnCount },
3181
- options?.styleCtx
3182
- );
3183
- return /* @__PURE__ */ jsxRuntime.jsxs(
3184
- "td",
3185
- {
3186
- className: cn(
3187
- "px-1 py-0.5 align-top",
3188
- // No border of its own: a side the deck gives no border renders with
3189
- // none, as PowerPoint does. Editing keeps a faint grid.
3190
- isEditable && hasCellSelectionHandler ? "border border-blue-200/70 cursor-cell" : null,
3191
- isCellSelected ? "ring-1 ring-inset ring-blue-500" : null,
3192
- isInMultiSelection && !isCellSelected ? "bg-blue-500/15 ring-1 ring-inset ring-blue-400/50" : null
3193
- ),
3194
- colSpan: cell.gridSpan && cell.gridSpan > 1 ? cell.gridSpan : void 0,
3195
- rowSpan: cell.rowSpan && cell.rowSpan > 1 ? cell.rowSpan : void 0,
3196
- style: {
3197
- ...cellCss(cell, rowIndex, cellIndex),
3198
- ...diag ? { position: "relative" } : void 0
3199
- },
3200
- onClick: (event) => {
3201
- if (!isEditable || !hasCellSelectionHandler) {
3202
- return;
3203
- }
3204
- event.stopPropagation();
3205
- if (event.shiftKey && selectedCell) {
3206
- const rect = chunkUHW3R465_js.computeSelectionRect(
3207
- selectedCell.rowIndex,
3208
- selectedCell.columnIndex,
3209
- rowIndex,
3210
- cellIndex,
3211
- tableData
3212
- );
3213
- options?.onSelectCell?.({
3214
- rowIndex: selectedCell.rowIndex,
3215
- columnIndex: selectedCell.columnIndex,
3216
- selectedCells: chunkUHW3R465_js.rectToCells(rect)
3217
- });
3218
- } else {
3219
- options?.onSelectCell?.({
3220
- rowIndex,
3221
- columnIndex: cellIndex
3222
- });
3223
- }
3224
- },
3225
- onDoubleClick: (event) => {
3226
- if (!isEditable || !hasCellSelectionHandler) {
3227
- return;
3228
- }
3229
- event.stopPropagation();
3230
- options?.onSelectCell?.({
3231
- rowIndex,
3232
- columnIndex: cellIndex,
3233
- isEditing: true
3234
- });
3235
- },
3236
- children: [
3237
- diag ? /* @__PURE__ */ jsxRuntime.jsx(TableCellDiagonalBorders, { diag }) : null,
3238
- isCellEditing ? /* @__PURE__ */ jsxRuntime.jsx(
3239
- TableCellInput,
3240
- {
3241
- initialText: cell.text ?? "",
3242
- style: cellCss(cell, rowIndex, cellIndex),
3243
- onCommit: (text) => {
3244
- options?.onCommitCellEdit?.(rowIndex, cellIndex, text);
3245
- },
3246
- onCancel: () => {
3247
- options?.onSelectCell?.({
3248
- rowIndex,
3249
- columnIndex: cellIndex
3250
- });
3251
- }
3252
- }
3253
- ) : renderTableCellContent(cell, cell.text || "\xA0")
3254
- ]
3255
- },
3256
- `${element.id}-cell-${rowIndex}-${cellIndex}`
3257
- );
3258
- })
3259
- },
3260
- `${element.id}-row-${rowIndex}`
3261
- )) })
3262
- ]
3263
- }
3264
- )
3265
- }
3266
- )
3267
- }
3268
- );
3269
- }
3270
- function renderTableElement(element, textStyle, options) {
3271
- const parsedTable = parseTableElementData(element, textStyle);
3272
- if (!parsedTable) {
3273
- const tableEl2 = element;
3274
- if (tableEl2.tableData && tableEl2.tableData.rows.length > 0) {
3275
- return renderTableFromTableData(tableEl2, textStyle, options);
3276
- }
3277
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: chunk6HMJTCFO_js.translationsEn["pptx.table.title"] });
3278
- }
3279
- const selectedCell = options?.selectedCell || null;
3280
- const isEditable = Boolean(options?.editable) && chunkUHW3R465_js.canDrillDown(element);
3281
- const hasCellSelectionHandler = typeof options?.onSelectCell === "function";
3282
- const tableEl = element;
3283
- const xmlSelectionRect = (() => {
3284
- if (!selectedCell?.selectedCells || selectedCell.selectedCells.length < 2) {
3285
- return void 0;
3286
- }
3287
- if (!tableEl.tableData) {
3288
- return void 0;
3289
- }
3290
- const first = selectedCell.selectedCells[0];
3291
- const last = selectedCell.selectedCells[selectedCell.selectedCells.length - 1];
3292
- return chunkUHW3R465_js.computeSelectionRect(first.row, first.col, last.row, last.col, tableEl.tableData);
3293
- })();
3294
- const schemeOverrides = options?.styleCtx?.theme?.colorScheme ? options.styleCtx.theme.colorScheme : void 0;
3295
- return /* @__PURE__ */ jsxRuntime.jsx(
3296
- TableResizeOverlay,
3297
- {
3298
- columnWidths: parsedTable.columnPercentages.map((p) => p / 100),
3299
- editable: isEditable,
3300
- onResizeColumns: options?.onResizeColumns,
3301
- onResizeRow: options?.onResizeRow,
3302
- children: /* @__PURE__ */ jsxRuntime.jsx(
3303
- "div",
3304
- {
3305
- className: cn(
3306
- "w-full h-full overflow-hidden",
3307
- isEditable && hasCellSelectionHandler ? "pointer-events-auto" : "pointer-events-none"
3308
- ),
3309
- children: /* @__PURE__ */ jsxRuntime.jsxs(
3310
- "table",
3311
- {
3312
- className: "w-full h-full border-collapse table-fixed",
3313
- style: {
3314
- fontFamily: chunkUHW3R465_js.DEFAULT_FONT_FAMILY,
3315
- // `a:tblPr@rtl` mirrors the column order for RTL decks.
3316
- ...chunkUHW3R465_js.tableContainerCss(tableEl.tableData)
3317
- },
3318
- children: [
3319
- parsedTable.columnPercentages.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("colgroup", { children: parsedTable.columnPercentages.map((percentage, columnIndex) => /* @__PURE__ */ jsxRuntime.jsx(
3320
- "col",
3321
- {
3322
- style: { width: `${percentage.toFixed(2)}%` }
3323
- },
3324
- `${element.id}-col-${columnIndex}`
3325
- )) }) : null,
3326
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: parsedTable.rows.map((row, rowIndex) => {
3327
- const cells = ensureArrayValue(row["a:tc"]);
3328
- const rowHeightRaw = Number.parseInt(String(row["@_h"] || ""), 10);
3329
- const rowHeight = Number.isFinite(rowHeightRaw) && rowHeightRaw > 0 ? Math.max(16, rowHeightRaw / EMU_PER_PX) : void 0;
3330
- return /* @__PURE__ */ jsxRuntime.jsx(
3331
- "tr",
3332
- {
3333
- style: rowHeight ? { height: rowHeight } : void 0,
3334
- children: cells.map((cell, cellIndex) => {
3335
- const isHMerged = cell["@_hMerge"] === "1";
3336
- const isVMerged = cell["@_vMerge"] === "1";
3337
- if (isHMerged || isVMerged) {
3338
- return null;
3339
- }
3340
- const gridSpanRaw = Number.parseInt(String(cell["@_gridSpan"] || ""), 10);
3341
- const colSpan = Number.isFinite(gridSpanRaw) && gridSpanRaw > 1 ? gridSpanRaw : void 0;
3342
- const rowSpanRaw = Number.parseInt(String(cell["@_rowSpan"] || ""), 10);
3343
- const rSpan = Number.isFinite(rowSpanRaw) && rowSpanRaw > 1 ? rowSpanRaw : void 0;
3344
- const bandStyle = getTableCellBandStyle2(
3345
- element,
3346
- rowIndex,
3347
- cellIndex,
3348
- parsedTable.rowCount,
3349
- parsedTable.columnCount,
3350
- options?.styleCtx
3351
- );
3352
- const xmlCellStyle = extractTableCellStyle(cell, textStyle, schemeOverrides);
3353
- const tdCellOverride = tableEl.tableData?.rows[rowIndex]?.cells[cellIndex]?.style;
3354
- const diag = getCellDiagonalBorders2(
3355
- tdCellOverride,
3356
- tableEl.tableData,
3357
- {
3358
- rowIndex,
3359
- cellIndex,
3360
- rowCount: parsedTable.rowCount,
3361
- columnCount: parsedTable.columnCount
3362
- },
3363
- options?.styleCtx
3364
- );
3365
- const mergedStyle = {
3366
- // Lowest-priority fallback: `xmlCellStyle` never carries a
3367
- // `color` of its own (see `extractTableCellStyle`), so this
3368
- // is the only source when neither the table style band nor
3369
- // an explicit run/cell colour applies.
3370
- color: textStyle.color,
3371
- ...bandStyle,
3372
- ...xmlCellStyle,
3373
- ...tdCellOverride ? chunkUHW3R465_js.cellStyleToCss(tdCellOverride) : void 0,
3374
- ...diag ? { position: "relative" } : void 0
3375
- };
3376
- return /* @__PURE__ */ jsxRuntime.jsxs(
3377
- "td",
3378
- {
3379
- className: cn(
3380
- "px-1 py-0.5 align-top",
3381
- // No border of its own: a side the deck gives no border renders
3382
- // with none, as PowerPoint does. Editing keeps a faint grid.
3383
- isEditable && hasCellSelectionHandler ? "border border-blue-200/70 cursor-cell" : null,
3384
- selectedCell?.rowIndex === rowIndex && selectedCell?.columnIndex === cellIndex ? "ring-1 ring-inset ring-blue-500" : null,
3385
- chunkUHW3R465_js.isCellInRect(rowIndex, cellIndex, xmlSelectionRect) && !(selectedCell?.rowIndex === rowIndex && selectedCell?.columnIndex === cellIndex) ? "bg-blue-500/15 ring-1 ring-inset ring-blue-400/50" : null
3386
- ),
3387
- colSpan,
3388
- rowSpan: rSpan,
3389
- style: mergedStyle,
3390
- onClick: (event) => {
3391
- if (!isEditable || !hasCellSelectionHandler) {
3392
- return;
3393
- }
3394
- event.stopPropagation();
3395
- if (event.shiftKey && selectedCell && tableEl.tableData) {
3396
- const rect = chunkUHW3R465_js.computeSelectionRect(
3397
- selectedCell.rowIndex,
3398
- selectedCell.columnIndex,
3399
- rowIndex,
3400
- cellIndex,
3401
- tableEl.tableData
3402
- );
3403
- options?.onSelectCell?.({
3404
- rowIndex: selectedCell.rowIndex,
3405
- columnIndex: selectedCell.columnIndex,
3406
- selectedCells: chunkUHW3R465_js.rectToCells(rect)
3407
- });
3408
- } else {
3409
- options?.onSelectCell?.({
3410
- rowIndex,
3411
- columnIndex: cellIndex
3412
- });
3413
- }
3414
- },
3415
- onDoubleClick: (event) => {
3416
- if (!isEditable || !hasCellSelectionHandler) {
3417
- return;
3418
- }
3419
- event.stopPropagation();
3420
- options?.onSelectCell?.({
3421
- rowIndex,
3422
- columnIndex: cellIndex,
3423
- isEditing: true
3424
- });
3425
- },
3426
- children: [
3427
- diag ? /* @__PURE__ */ jsxRuntime.jsx(TableCellDiagonalBorders, { diag }) : null,
3428
- selectedCell?.rowIndex === rowIndex && selectedCell?.columnIndex === cellIndex && selectedCell?.isEditing ? /* @__PURE__ */ jsxRuntime.jsx(
3429
- TableCellInput,
3430
- {
3431
- initialText: extractCellText(cell) ?? "",
3432
- style: mergedStyle,
3433
- onCommit: (text) => {
3434
- options?.onCommitCellEdit?.(rowIndex, cellIndex, text);
3435
- },
3436
- onCancel: () => {
3437
- options?.onSelectCell?.({
3438
- rowIndex,
3439
- columnIndex: cellIndex
3440
- });
3441
- }
3442
- }
3443
- ) : renderTableCellContent(
3444
- tableEl.tableData?.rows[rowIndex]?.cells[cellIndex],
3445
- extractCellText(cell) || "\xA0"
3446
- )
3447
- ]
3448
- },
3449
- `${element.id}-cell-${rowIndex}-${cellIndex}`
3450
- );
3451
- })
3452
- },
3453
- `${element.id}-row-${rowIndex}`
3454
- );
3455
- }) })
3456
- ]
3457
- }
3458
- )
3459
- }
3460
- )
3461
- }
3462
- );
3463
- }
3464
- function renderGradientStops(stops) {
3465
- return stops.map((stop, i) => /* @__PURE__ */ jsxRuntime.jsx("stop", { offset: stop.offset, stopColor: stop.color, stopOpacity: stop.opacity }, i));
3466
- }
3467
- function partAttrs(part) {
3468
- return part ? chunkUHW3R465_js.chartPartToAttrs(part) : void 0;
3469
- }
3470
- function resolveReactPalette(chartData) {
3471
- if (chartData.colorPalette && chartData.colorPalette.length > 0) {
3472
- return chartData.colorPalette;
3473
- }
3474
- return [...chunkUHW3R465_js.getChartStylePalette(chartData.style?.styleId)];
3475
- }
3476
- function buildReactChartViewModel(element) {
3477
- if (element.type !== "chart" || !element.chartData) {
3478
- return chunkUHW3R465_js.buildChartViewModel(element);
3479
- }
3480
- const palette = resolveReactPalette(element.chartData), themedElement = {
3481
- ...element,
3482
- chartData: { ...element.chartData, colorPalette: palette }
3483
- };
3484
- return chunkUHW3R465_js.buildChartViewModel(themedElement);
3485
- }
3486
- function renderPrimitive(prim, key) {
3487
- switch (prim.kind) {
3488
- case "rect": {
3489
- const r = prim;
3490
- return /* @__PURE__ */ jsxRuntime.jsx(
3491
- "rect",
3492
- {
3493
- x: r.x,
3494
- y: r.y,
3495
- width: r.w,
3496
- height: r.h,
3497
- fill: r.fill,
3498
- rx: r.rx ?? 0,
3499
- opacity: r.opacity ?? 1,
3500
- ...partAttrs(r.part),
3501
- children: r.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: r.title }) : null
3502
- },
3503
- key
3504
- );
3505
- }
3506
- case "path": {
3507
- const p = prim;
3508
- return /* @__PURE__ */ jsxRuntime.jsx(
3509
- "path",
3510
- {
3511
- d: p.d,
3512
- fill: p.fill,
3513
- stroke: p.stroke ?? "none",
3514
- strokeWidth: p.strokeWidth ?? 0,
3515
- strokeDasharray: p.dashArray,
3516
- fillOpacity: p.opacity ?? 1,
3517
- ...partAttrs(p.part),
3518
- children: p.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: p.title }) : null
3519
- },
3520
- key
3521
- );
3522
- }
3523
- case "polyline": {
3524
- const p = prim;
3525
- return /* @__PURE__ */ jsxRuntime.jsx(
3526
- "polyline",
3527
- {
3528
- points: p.points,
3529
- stroke: p.stroke,
3530
- strokeWidth: p.strokeWidth,
3531
- fill: p.fill,
3532
- opacity: p.opacity ?? 1,
3533
- ...partAttrs(p.part),
3534
- children: p.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: p.title }) : null
3535
- },
3536
- key
3537
- );
3538
- }
3539
- case "circle": {
3540
- const c = prim;
3541
- return /* @__PURE__ */ jsxRuntime.jsx(
3542
- "circle",
3543
- {
3544
- cx: c.cx,
3545
- cy: c.cy,
3546
- r: c.r,
3547
- fill: c.fill,
3548
- opacity: c.opacity ?? 1,
3549
- ...partAttrs(c.part),
3550
- children: c.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: c.title }) : null
3551
- },
3552
- key
3553
- );
3554
- }
3555
- case "line": {
3556
- const l = prim;
3557
- return /* @__PURE__ */ jsxRuntime.jsx(
3558
- "line",
3559
- {
3560
- x1: l.x1,
3561
- y1: l.y1,
3562
- x2: l.x2,
3563
- y2: l.y2,
3564
- stroke: l.stroke,
3565
- strokeWidth: l.strokeWidth,
3566
- strokeDasharray: l.dashArray,
3567
- opacity: l.opacity ?? 1,
3568
- transform: l.transform,
3569
- children: l.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: l.title }) : null
3570
- },
3571
- key
3572
- );
3573
- }
3574
- case "polygon": {
3575
- const p = prim;
3576
- return /* @__PURE__ */ jsxRuntime.jsx(
3577
- "polygon",
3578
- {
3579
- points: p.points,
3580
- fill: p.fill,
3581
- stroke: p.stroke,
3582
- strokeWidth: p.strokeWidth,
3583
- opacity: p.opacity ?? 1,
3584
- strokeDasharray: p.dashArray,
3585
- transform: p.transform,
3586
- ...partAttrs(p.part),
3587
- children: p.title !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: p.title }) : null
3588
- },
3589
- key
3590
- );
3591
- }
3592
- case "text": {
3593
- const t = prim;
3594
- return /* @__PURE__ */ jsxRuntime.jsx(
3595
- "text",
3596
- {
3597
- x: t.x,
3598
- y: t.y,
3599
- textAnchor: t.textAnchor,
3600
- fontSize: t.fontSize,
3601
- fill: t.fill,
3602
- fontWeight: t.fontWeight ?? "normal",
3603
- dominantBaseline: t.dominantBaseline,
3604
- opacity: t.opacity ?? 1,
3605
- transform: t.transform,
3606
- children: t.text
3607
- },
3608
- key
3609
- );
3610
- }
3611
- default:
3612
- return null;
3613
- }
3614
- }
3615
- function renderText(t, key) {
3616
- return /* @__PURE__ */ jsxRuntime.jsx(
3617
- "text",
3618
- {
3619
- x: t.x,
3620
- y: t.y,
3621
- textAnchor: t.textAnchor,
3622
- fontSize: t.fontSize,
3623
- fill: t.fill,
3624
- fontWeight: t.fontWeight ?? "normal",
3625
- fontStyle: t.fontStyle ?? "normal",
3626
- fontFamily: t.fontFamily,
3627
- dominantBaseline: t.dominantBaseline,
3628
- opacity: t.opacity ?? 1,
3629
- transform: t.transform,
3630
- children: t.text
3631
- },
3632
- key
3633
- );
3634
- }
3635
- function renderChartViewModel(elementId, vm, preserveAspectRatio = "none") {
3636
- const legendItems = chunkUHW3R465_js.computeChartLegendLayout(vm);
3637
- return /* @__PURE__ */ jsxRuntime.jsxs(
3638
- "svg",
3639
- {
3640
- className: "w-full h-full pointer-events-none",
3641
- viewBox: `0 0 ${vm.svgWidth} ${vm.svgHeight}`,
3642
- preserveAspectRatio,
3643
- children: [
3644
- vm.defs && vm.defs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("defs", { children: vm.defs.map(
3645
- (def, i) => def.kind === "linearGradient" ? /* @__PURE__ */ jsxRuntime.jsx(
3646
- "linearGradient",
3647
- {
3648
- id: def.id,
3649
- x1: def.x1,
3650
- y1: def.y1,
3651
- x2: def.x2,
3652
- y2: def.y2,
3653
- children: renderGradientStops(def.stops)
3654
- },
3655
- `${elementId}-def-${i}`
3656
- ) : def.kind === "radialGradient" ? /* @__PURE__ */ jsxRuntime.jsx(
3657
- "radialGradient",
3658
- {
3659
- id: def.id,
3660
- cx: def.cx,
3661
- cy: def.cy,
3662
- r: def.r,
3663
- children: renderGradientStops(def.stops)
3664
- },
3665
- `${elementId}-def-${i}`
3666
- ) : /* @__PURE__ */ jsxRuntime.jsx(
3667
- "pattern",
3668
- {
3669
- id: def.id,
3670
- patternUnits: def.patternUnits,
3671
- x: def.x,
3672
- y: def.y,
3673
- width: def.width,
3674
- height: def.height,
3675
- children: /* @__PURE__ */ jsxRuntime.jsx(
3676
- "image",
3677
- {
3678
- href: def.href,
3679
- x: 0,
3680
- y: 0,
3681
- width: def.width,
3682
- height: def.height,
3683
- preserveAspectRatio: def.preserveAspectRatio
3684
- }
3685
- )
3686
- },
3687
- `${elementId}-def-${i}`
3688
- )
3689
- ) }),
3690
- vm.areaFill && /* @__PURE__ */ jsxRuntime.jsx(
3691
- "rect",
3692
- {
3693
- x: 0,
3694
- y: 0,
3695
- width: vm.svgWidth,
3696
- height: vm.svgHeight,
3697
- rx: vm.areaRadius,
3698
- fill: vm.areaFill
3699
- }
3700
- ),
3701
- vm.title && /* @__PURE__ */ jsxRuntime.jsx(
3702
- "text",
3703
- {
3704
- x: vm.titleX,
3705
- y: vm.titleY,
3706
- textAnchor: "middle",
3707
- fontSize: vm.titleStyle?.fontSize ?? 12,
3708
- fontWeight: vm.titleStyle?.fontWeight ?? 600,
3709
- fontFamily: vm.titleStyle?.fontFamily,
3710
- fill: vm.titleStyle?.fill ?? "#1e293b",
3711
- "data-chart-part": "title",
3712
- children: vm.titleRunSpans && vm.titleRunSpans.length > 0 ? vm.titleRunSpans.map((run, i) => /* @__PURE__ */ jsxRuntime.jsx(
3713
- "tspan",
3714
- {
3715
- fontSize: run.fontSize,
3716
- fontWeight: run.fontWeight,
3717
- fontStyle: run.fontStyle,
3718
- fontFamily: run.fontFamily,
3719
- fill: run.fill,
3720
- children: run.text
3721
- },
3722
- `${elementId}-title-run-${i}`
3723
- )) : vm.title
3724
- }
3725
- ),
3726
- vm.gridlines.map((gl, i) => /* @__PURE__ */ jsxRuntime.jsx(
3727
- "line",
3728
- {
3729
- x1: gl.x1,
3730
- y1: gl.y1,
3731
- x2: gl.x2,
3732
- y2: gl.y2,
3733
- stroke: gl.stroke,
3734
- strokeWidth: gl.strokeWidth
3735
- },
3736
- `${elementId}-gl-${i}`
3737
- )),
3738
- (vm.secondaryGridlines ?? []).map((gl, i) => /* @__PURE__ */ jsxRuntime.jsx(
3739
- "line",
3740
- {
3741
- x1: gl.x1,
3742
- y1: gl.y1,
3743
- x2: gl.x2,
3744
- y2: gl.y2,
3745
- stroke: gl.stroke,
3746
- strokeWidth: gl.strokeWidth,
3747
- strokeDasharray: gl.dashArray,
3748
- opacity: gl.opacity ?? 1
3749
- },
3750
- `${elementId}-sgl-${i}`
3751
- )),
3752
- vm.axisLabels.map((lbl, i) => renderText(lbl, `${elementId}-al-${i}`)),
3753
- (vm.secondaryAxisLabels ?? []).map((lbl, i) => renderText(lbl, `${elementId}-sal-${i}`)),
3754
- vm.zeroLine && /* @__PURE__ */ jsxRuntime.jsx(
3755
- "line",
3756
- {
3757
- x1: vm.zeroLine.x1,
3758
- y1: vm.zeroLine.y1,
3759
- x2: vm.zeroLine.x2,
3760
- y2: vm.zeroLine.y2,
3761
- stroke: vm.zeroLine.stroke,
3762
- strokeWidth: vm.zeroLine.strokeWidth
3763
- }
3764
- ),
3765
- vm.categoryLabels.map((lbl, i) => renderText(lbl, `${elementId}-cl-${i}`)),
3766
- vm.primitives.map((prim, i) => renderPrimitive(prim, `${elementId}-p-${i}`)),
3767
- vm.dataLabels.map((dl, i) => renderText(dl, `${elementId}-dl-${i}`)),
3768
- legendItems.map((item, i) => /* @__PURE__ */ jsxRuntime.jsxs(
3769
- "g",
3770
- {
3771
- transform: `translate(${item.x.toFixed(1)},${item.y.toFixed(1)})`,
3772
- children: [
3773
- item.lineSwatch ? item.lineSwatch.primitives.map(
3774
- (prim, si) => renderPrimitive(prim, `${elementId}-lg-${i}-sw-${si}`)
3775
- ) : /* @__PURE__ */ jsxRuntime.jsx("rect", { x: 0, y: -7, width: 10, height: 10, rx: 2, fill: item.color }),
3776
- /* @__PURE__ */ jsxRuntime.jsx(
3777
- "text",
3778
- {
3779
- x: 13,
3780
- y: 3,
3781
- fontSize: item.fontSize,
3782
- fill: item.fill,
3783
- fontWeight: item.fontWeight,
3784
- fontStyle: item.fontStyle,
3785
- fontFamily: item.fontFamily,
3786
- children: item.label
3787
- }
3788
- )
3789
- ]
3790
- },
3791
- `${elementId}-lg-${i}`
3792
- ))
3793
- ]
3794
- }
3795
- );
3796
- }
3797
- function renderChartElement(element) {
3798
- if (element.type !== "chart") {
3799
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: chunk6HMJTCFO_js.translationsEn["pptx.chart.heading"] });
3800
- }
3801
- const chartData = element.chartData;
3802
- if (!chartData || chartData.series.length === 0) {
3803
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-full flex items-center justify-center text-[11px] text-white/80 pointer-events-none", children: chunk6HMJTCFO_js.translationsEn["pptx.chart.heading"] });
3804
- }
3805
- const kind = chunkUHW3R465_js.resolveChartKind(chartData.chartType ?? "bar");
3806
- return renderChartViewModel(
3807
- element.id,
3808
- buildReactChartViewModel(element),
3809
- chunkUHW3R465_js.chartPreserveAspectRatio(kind)
3810
- );
3811
- }
3812
-
3813
- // src/viewer/utils/pdf-builder-notes-builder.ts
3814
- function buildNotesPdf(pages) {
3815
- const images = pages.map((page) => {
3816
- const dataUrl = page.canvas.toDataURL("image/jpeg", 0.92);
3817
- const base64 = dataUrl.split(",")[1] ?? "";
3818
- const raw = atob(base64);
3819
- const bytes2 = new Uint8Array(raw.length);
3820
- for (let i = 0; i < raw.length; i++) {
3821
- bytes2[i] = raw.charCodeAt(i);
3822
- }
3823
- return { bytes: bytes2, w: page.canvas.width, h: page.canvas.height };
3824
- });
3825
- const meta = pages.map((page) => ({
3826
- notes: page.notes,
3827
- slideNumber: page.slideNumber
3828
- }));
3829
- const bytes = chunkUHW3R465_js.buildNotesPdfBytes(images, meta);
3830
- const blob = new Blob([bytes], { type: "application/pdf" });
3831
- return URL.createObjectURL(blob);
3832
- }
3833
-
3834
- // src/viewer/utils/pdf-builder-slides.ts
3835
- function buildPdfFromTiledImageData(pages) {
3836
- const bytes = chunkUHW3R465_js.buildTiledSlidesPdfBytes(pages);
3837
- const blob = new Blob([bytes], { type: "application/pdf" });
3838
- return URL.createObjectURL(blob);
3839
- }
3840
-
3841
- // src/viewer/utils/animation-preview.ts
3842
- var activePreview = null;
3843
- function startPreviewAnimation(elementId, preset, options) {
3844
- stopPreviewAnimation();
3845
- const domEl = document.querySelector(`[data-element-id="${elementId}"]`);
3846
- const descriptor = chunkUHW3R465_js.buildPreviewAnimation(preset, {
3847
- ...options,
3848
- geometry: domEl ? chunkUHW3R465_js.measurePreviewGeometry(domEl) : void 0
3849
- });
3850
- if (!descriptor) {
3851
- return;
3852
- }
3853
- playDescriptor(elementId, descriptor);
3854
- }
3855
- function startMotionPathPreview(elementId, path, options) {
3856
- stopPreviewAnimation();
3857
- const domEl = document.querySelector(`[data-element-id="${elementId}"]`);
3858
- if (!domEl) {
3859
- return;
3860
- }
3861
- const stage = domEl.offsetParent;
3862
- const descriptor = chunkUHW3R465_js.buildMotionPathPreview({
3863
- path,
3864
- slideWidth: stage?.offsetWidth || DEFAULT_PREVIEW_SLIDE_WIDTH,
3865
- slideHeight: stage?.offsetHeight || DEFAULT_PREVIEW_SLIDE_HEIGHT,
3866
- durationMs: options?.durationMs,
3867
- delayMs: options?.delayMs,
3868
- timingCurve: options?.timingCurve
3869
- });
3870
- if (!descriptor) {
3871
- return;
3872
- }
3873
- playDescriptor(elementId, descriptor);
3874
- }
3875
- var DEFAULT_PREVIEW_SLIDE_WIDTH = 1280;
3876
- var DEFAULT_PREVIEW_SLIDE_HEIGHT = 720;
3877
- function playDescriptor(elementId, descriptor) {
3878
- const domEl = document.querySelector(`[data-element-id="${elementId}"]`);
3879
- if (!domEl) {
3880
- return;
3881
- }
3882
- const styleEl = document.createElement("style");
3883
- styleEl.textContent = descriptor.keyframesCss;
3884
- document.head.appendChild(styleEl);
3885
- const originalAnimation = domEl.style.animation;
3886
- const originalVisibility = domEl.style.visibility;
3887
- domEl.style.visibility = "visible";
3888
- domEl.style.animation = descriptor.cssAnimation;
3889
- const timeoutId = setTimeout(() => {
3890
- domEl.style.animation = originalAnimation;
3891
- domEl.style.visibility = originalVisibility;
3892
- styleEl.remove();
3893
- if (activePreview?.elementId === elementId) {
3894
- activePreview = null;
3895
- }
3896
- }, descriptor.durationMs + 100);
3897
- activePreview = {
3898
- elementId,
3899
- timeoutId,
3900
- styleEl,
3901
- originalAnimation,
3902
- originalVisibility
3903
- };
3904
- }
3905
- function stopPreviewAnimation() {
3906
- if (!activePreview) {
3907
- return;
3908
- }
3909
- clearTimeout(activePreview.timeoutId);
3910
- activePreview.styleEl.remove();
3911
- const domEl = document.querySelector(
3912
- `[data-element-id="${activePreview.elementId}"]`
3913
- );
3914
- if (domEl) {
3915
- domEl.style.animation = activePreview.originalAnimation;
3916
- domEl.style.visibility = activePreview.originalVisibility;
3917
- }
3918
- activePreview = null;
3919
- }
3920
-
3921
- exports.ANIMATION_PRESET_OPTIONS = ANIMATION_PRESET_OPTIONS;
3922
- exports.ARROW_SIZE_OPTIONS = ARROW_SIZE_OPTIONS;
3923
- exports.CONNECTOR_ARROW_OPTIONS = CONNECTOR_ARROW_OPTIONS;
3924
- exports.DEFAULT_CANVAS_HEIGHT = DEFAULT_CANVAS_HEIGHT;
3925
- exports.DEFAULT_CANVAS_WIDTH = DEFAULT_CANVAS_WIDTH;
3926
- exports.DEFAULT_FILL_COLOR = DEFAULT_FILL_COLOR;
3927
- exports.DEFAULT_FONT_FAMILY = DEFAULT_FONT_FAMILY2;
3928
- exports.DEFAULT_SECTION_GROUP_ID = DEFAULT_SECTION_GROUP_ID;
3929
- exports.DEFAULT_STROKE_COLOR = DEFAULT_STROKE_COLOR;
3930
- exports.DEFAULT_TABLE_COLUMNS = DEFAULT_TABLE_COLUMNS;
3931
- exports.DEFAULT_TABLE_ROWS = DEFAULT_TABLE_ROWS;
3932
- exports.DEFAULT_TEXT_COLOR = DEFAULT_TEXT_COLOR;
3933
- exports.DEFAULT_TEXT_FONT_SIZE = DEFAULT_TEXT_FONT_SIZE;
3934
- exports.GRID_SIZE = GRID_SIZE;
3935
- exports.HYPERLINK_COLOR = HYPERLINK_COLOR;
3936
- exports.MIN_ELEMENT_SIZE = MIN_ELEMENT_SIZE;
3937
- exports.SHAPE_PRESETS = SHAPE_PRESETS;
3938
- exports.SHORTCUT_REFERENCE_ITEMS = SHORTCUT_REFERENCE_ITEMS;
3939
- exports.SLIDE_NAV_THUMBNAIL_WIDTH = SLIDE_NAV_THUMBNAIL_WIDTH;
3940
- exports.STROKE_DASH_OPTIONS = STROKE_DASH_OPTIONS2;
3941
- exports.TOOLBAR_SECTIONS = TOOLBAR_SECTIONS;
3942
- exports.UNGROUPED_SECTION_ID = UNGROUPED_SECTION_ID;
3943
- exports.ZOOM_TO_SELECTION_PADDING = ZOOM_TO_SELECTION_PADDING;
3944
- exports.build3DExtrusionData = build3DExtrusionData2;
3945
- exports.buildLineGlowFilter = buildLineGlowFilter;
3946
- exports.buildLineShadowCss = buildLineShadowCss;
3947
- exports.buildNotesPdf = buildNotesPdf;
3948
- exports.buildPdfFromTiledImageData = buildPdfFromTiledImageData;
3949
- exports.buildReactChartViewModel = buildReactChartViewModel;
3950
- exports.buildTextBody3DSceneStyle = buildTextBody3DSceneStyle2;
3951
- exports.cloneHistorySnapshot = cloneHistorySnapshot2;
3952
- exports.cn = cn;
3953
- exports.getAnimationInitialStyle = getAnimationInitialStyle2;
3954
- exports.getConnectorPathGeometry = getConnectorPathGeometry2;
3955
- exports.getCropShapeClipPath = getCropShapeClipPath2;
3956
- exports.getDuotoneColors = getDuotoneColors;
3957
- exports.getImageRenderStyle = getImageRenderStyle;
3958
- exports.getImageSurfaceMaskStyle = getImageSurfaceMaskStyle;
3959
- exports.getImageSurfaceStyle = getImageSurfaceStyle;
3960
- exports.getImageTilingStyle = getImageTilingStyle2;
3961
- exports.getShapeVisualStyle = getShapeVisualStyle;
3962
- exports.getTextLayoutStyle = getTextLayoutStyle;
3963
- exports.getTextStyleForElement = getTextStyleForElement;
3964
- exports.getTextWarpStyle = getTextWarpStyle;
3965
- exports.hasDagDuotoneEffect = hasDagDuotoneEffect;
3966
- exports.isConnectorOrLineElement = isConnectorOrLineElement;
3967
- exports.renderChartElement = renderChartElement;
3968
- exports.renderConnectorMarker = renderConnectorMarker;
3969
- exports.renderDagDuotoneSvgFilter = renderDagDuotoneSvgFilter;
3970
- exports.renderMediaElement = renderMediaElement;
3971
- exports.renderTableElement = renderTableElement;
3972
- exports.renderTextSegments = renderTextSegments;
3973
- exports.renderVectorShape = renderVectorShape;
3974
- exports.shouldRenderFallbackLabel = shouldRenderFallbackLabel;
3975
- exports.startMotionPathPreview = startMotionPathPreview;
3976
- exports.startPreviewAnimation = startPreviewAnimation;
3977
- exports.stopPreviewAnimation = stopPreviewAnimation;