@web-ppt/edit-core 0.5.0-beta.2 → 0.5.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 (337) hide show
  1. package/CHANGELOG.md +183 -0
  2. package/README.md +164 -21
  3. package/dist/alt-text.d.ts +5 -0
  4. package/dist/appearance/index.d.ts +12 -0
  5. package/dist/appearance/materialize.d.ts +4 -0
  6. package/dist/appearance/types.d.ts +26 -0
  7. package/dist/appearance/values.d.ts +9 -0
  8. package/dist/appearance.js +301 -0
  9. package/dist/cfb/index.d.ts +5 -0
  10. package/dist/cfb/read.d.ts +16 -0
  11. package/dist/cfb/write.d.ts +3 -0
  12. package/dist/cfb.js +208 -0
  13. package/dist/change-classification.d.ts +3 -3
  14. package/dist/chart/category-binding.d.ts +4 -0
  15. package/dist/chart/category-commands.d.ts +23 -0
  16. package/dist/chart/category-levels.d.ts +14 -0
  17. package/dist/chart/category-matrix.d.ts +2 -0
  18. package/dist/chart/category-value.d.ts +2 -0
  19. package/dist/chart/category-workbook.d.ts +13 -0
  20. package/dist/chart/commands.d.ts +28 -0
  21. package/dist/chart/context.d.ts +12 -0
  22. package/dist/chart/dataset-merge.d.ts +5 -0
  23. package/dist/chart/formula.d.ts +13 -0
  24. package/dist/chart/identity-frames.d.ts +4 -0
  25. package/dist/chart/identity-scopes.d.ts +6 -0
  26. package/dist/chart/identity.d.ts +24 -0
  27. package/dist/chart/index.d.ts +8 -0
  28. package/dist/chart/limits.d.ts +6 -0
  29. package/dist/chart/locator.d.ts +4 -0
  30. package/dist/chart/materialize.d.ts +7 -0
  31. package/dist/chart/ordering.d.ts +9 -0
  32. package/dist/chart/part-graph.d.ts +5 -0
  33. package/dist/chart/patch-validation.d.ts +3 -0
  34. package/dist/chart/plot-kinds.d.ts +2 -0
  35. package/dist/chart/projection.d.ts +8 -0
  36. package/dist/chart/save.d.ts +4 -0
  37. package/dist/chart/shared-added-plan.d.ts +19 -0
  38. package/dist/chart/shared-added-records.d.ts +8 -0
  39. package/dist/chart/shared-address.d.ts +5 -0
  40. package/dist/chart/shared-allocate.d.ts +7 -0
  41. package/dist/chart/shared-cache-codec.d.ts +5 -0
  42. package/dist/chart/shared-cache-identities.d.ts +3 -0
  43. package/dist/chart/shared-cache-migration.d.ts +7 -0
  44. package/dist/chart/shared-cache-save.d.ts +3 -0
  45. package/dist/chart/shared-cache-scopes.d.ts +13 -0
  46. package/dist/chart/shared-cache.d.ts +11 -0
  47. package/dist/chart/shared-category.d.ts +4 -0
  48. package/dist/chart/shared-cell.d.ts +9 -0
  49. package/dist/chart/shared-family.d.ts +26 -0
  50. package/dist/chart/shared-fields.d.ts +18 -0
  51. package/dist/chart/shared-graph.d.ts +19 -0
  52. package/dist/chart/shared-growth-space.d.ts +5 -0
  53. package/dist/chart/shared-inserted-cells.d.ts +14 -0
  54. package/dist/chart/shared-inserted-command.d.ts +7 -0
  55. package/dist/chart/shared-inserted-layout.d.ts +16 -0
  56. package/dist/chart/shared-inserted-project.d.ts +14 -0
  57. package/dist/chart/shared-inserted-records.d.ts +16 -0
  58. package/dist/chart/shared-inserted-save.d.ts +6 -0
  59. package/dist/chart/shared-joint-command.d.ts +9 -0
  60. package/dist/chart/shared-joint-records.d.ts +9 -0
  61. package/dist/chart/shared-record-axis.d.ts +25 -0
  62. package/dist/chart/shared-record-remove.d.ts +13 -0
  63. package/dist/chart/shared-record-stage.d.ts +2 -0
  64. package/dist/chart/shared-records.d.ts +2 -0
  65. package/dist/chart/shared-rows.d.ts +17 -0
  66. package/dist/chart/shared-runtime.d.ts +19 -0
  67. package/dist/chart/shared-save-plan.d.ts +4 -0
  68. package/dist/chart/shared-save.d.ts +3 -0
  69. package/dist/chart/shared-series.d.ts +6 -0
  70. package/dist/chart/shared-source-cache.d.ts +4 -0
  71. package/dist/chart/shared-topology.d.ts +9 -0
  72. package/dist/chart/shared-unresolved.d.ts +3 -0
  73. package/dist/chart/shared-validation.d.ts +6 -0
  74. package/dist/chart/shared-workbook-source.d.ts +6 -0
  75. package/dist/chart/shared-xy-command.d.ts +7 -0
  76. package/dist/chart/shared-xy-family.d.ts +16 -0
  77. package/dist/chart/shared-xy-project.d.ts +6 -0
  78. package/dist/chart/shared-xy-records.d.ts +23 -0
  79. package/dist/chart/shared-xy-save.d.ts +5 -0
  80. package/dist/chart/shared-xy-source.d.ts +39 -0
  81. package/dist/chart/shared.d.ts +13 -0
  82. package/dist/chart/source.d.ts +11 -0
  83. package/dist/chart/types.d.ts +86 -0
  84. package/dist/chart/validation.d.ts +24 -0
  85. package/dist/chart/workbook-range.d.ts +16 -0
  86. package/dist/chart/workbook-read.d.ts +7 -0
  87. package/dist/chart/workbook-write.d.ts +9 -0
  88. package/dist/chart/workbook.d.ts +25 -0
  89. package/dist/chart/xml-data.d.ts +14 -0
  90. package/dist/chart/xml-namespaces.d.ts +16 -0
  91. package/dist/chart-design/index.d.ts +10 -0
  92. package/dist/chart-design/types.d.ts +11 -0
  93. package/dist/chart-design/xml.d.ts +2 -0
  94. package/dist/chart-design.js +361 -0
  95. package/dist/chart-ex/index.d.ts +15 -0
  96. package/dist/chart-ex/workbook.d.ts +6 -0
  97. package/dist/chart-ex/xml.d.ts +14 -0
  98. package/dist/chart-ex.js +457 -0
  99. package/dist/chart-shared/index.d.ts +12 -0
  100. package/dist/chart-shared.js +1 -0
  101. package/dist/chart.js +1 -0
  102. package/dist/clipboard-links-GuPtqr1z.js +778 -0
  103. package/dist/clipboard-package.d.ts +4 -0
  104. package/dist/clipboard-source.d.ts +6 -2
  105. package/dist/clipboard-trees.d.ts +9 -0
  106. package/dist/commands/add-slide-identity.d.ts +2 -0
  107. package/dist/commands/bullet-image-resource.d.ts +11 -0
  108. package/dist/commands/clear-format.d.ts +4 -0
  109. package/dist/commands/common-object-slide-patch.d.ts +4 -0
  110. package/dist/commands/common-object-slide-types.d.ts +68 -0
  111. package/dist/commands/direct-format-patches.d.ts +11 -5
  112. package/dist/commands/distribute-elements.d.ts +4 -0
  113. package/dist/commands/edit-table-grid.d.ts +10 -0
  114. package/dist/commands/element-alt-text.d.ts +8 -0
  115. package/dist/commands/element-arrangement.d.ts +17 -0
  116. package/dist/commands/element-effects.d.ts +1 -1
  117. package/dist/commands/element-fill.d.ts +1 -1
  118. package/dist/commands/element-geometry.d.ts +5 -2
  119. package/dist/commands/element-image-content.d.ts +2 -2
  120. package/dist/commands/element-link.d.ts +1 -1
  121. package/dist/commands/element-name.d.ts +1 -1
  122. package/dist/commands/element-stroke.d.ts +1 -1
  123. package/dist/commands/element-text.d.ts +1 -1
  124. package/dist/commands/element-transform.d.ts +2 -2
  125. package/dist/commands/geometry-types.d.ts +23 -1
  126. package/dist/commands/hierarchy-record.d.ts +5 -0
  127. package/dist/commands/image-resource.d.ts +8 -1
  128. package/dist/commands/insertion-host.d.ts +14 -1
  129. package/dist/commands/layout-property.d.ts +7 -0
  130. package/dist/commands/master-property.d.ts +5 -0
  131. package/dist/commands/master-text-style-types.d.ts +27 -0
  132. package/dist/commands/master-text-style.d.ts +7 -0
  133. package/dist/commands/paste-resources.d.ts +9 -5
  134. package/dist/commands/patch-apply.d.ts +3 -0
  135. package/dist/commands/patch-count.d.ts +1 -0
  136. package/dist/commands/patch-invalidation.d.ts +1 -1
  137. package/dist/commands/patch-stage.d.ts +4 -0
  138. package/dist/commands/record-override.d.ts +5 -0
  139. package/dist/commands/replace-image.d.ts +6 -1
  140. package/dist/commands/sections.d.ts +10 -0
  141. package/dist/commands/set-preset.d.ts +5 -0
  142. package/dist/commands/slide-property-types.d.ts +55 -5
  143. package/dist/commands/slide-size.d.ts +7 -0
  144. package/dist/commands/spid.d.ts +1 -1
  145. package/dist/commands/table-grid-patch.d.ts +12 -0
  146. package/dist/commands/text-target.d.ts +2 -2
  147. package/dist/commands/theme-types.d.ts +47 -0
  148. package/dist/commands/theme.d.ts +9 -0
  149. package/dist/commands/types.d.ts +194 -17
  150. package/dist/commands/ungroup-source.d.ts +3 -0
  151. package/dist/comments/index.d.ts +35 -0
  152. package/dist/comments/save.d.ts +3 -0
  153. package/dist/comments/state.d.ts +10 -0
  154. package/dist/comments/xml.d.ts +12 -0
  155. package/dist/comments.js +782 -0
  156. package/dist/common-object-slide-types.d.ts +34 -0
  157. package/dist/data-validation.d.ts +1 -1
  158. package/dist/describe/budget.d.ts +3 -0
  159. package/dist/describe/index.d.ts +5 -0
  160. package/dist/describe/read.d.ts +4 -0
  161. package/dist/describe/types.d.ts +103 -0
  162. package/dist/describe.js +192 -0
  163. package/dist/design-dependencies.d.ts +8 -0
  164. package/dist/design-projection-package.d.ts +10 -0
  165. package/dist/design-target.d.ts +10 -0
  166. package/dist/design.d.ts +3 -0
  167. package/dist/document-extensions.d.ts +9 -0
  168. package/dist/document.d.ts +1 -1
  169. package/dist/dynamic-projection.d.ts +6 -0
  170. package/dist/edit-core.js +5420 -4111
  171. package/dist/editor.d.ts +15 -3
  172. package/dist/element-source.d.ts +11 -0
  173. package/dist/element-spids.d.ts +4 -0
  174. package/dist/extension-address-journal.d.ts +9 -0
  175. package/dist/extension-address-remap.d.ts +14 -0
  176. package/dist/extension-addresses.d.ts +20 -0
  177. package/dist/extension-copy-history.d.ts +7 -0
  178. package/dist/extension-copy.d.ts +16 -0
  179. package/dist/extension-migration-receipt.d.ts +34 -0
  180. package/dist/extension-recovery-context.d.ts +5 -0
  181. package/dist/extension-runtime.d.ts +64 -0
  182. package/dist/generate/comments.d.ts +3 -0
  183. package/dist/generate/compatibility-parts.d.ts +14 -0
  184. package/dist/generate/compatibility-references.d.ts +3 -0
  185. package/dist/generate/compatibility.d.ts +4 -0
  186. package/dist/generate/index.d.ts +1 -0
  187. package/dist/generate/master-defaults.d.ts +4 -0
  188. package/dist/generate/materialize.d.ts +2 -2
  189. package/dist/generate/math.d.ts +3 -0
  190. package/dist/generate/portable-clipboard.d.ts +4 -0
  191. package/dist/generate/projection-tree.d.ts +8 -0
  192. package/dist/generate/template.d.ts +68 -1
  193. package/dist/generate/text-body.d.ts +2 -0
  194. package/dist/generate/text-effects.d.ts +5 -0
  195. package/dist/generate/text-override.d.ts +8 -0
  196. package/dist/generate/validation.d.ts +3 -0
  197. package/dist/generate/warp.d.ts +2 -0
  198. package/dist/generate.js +1232 -512
  199. package/dist/history.d.ts +11 -1
  200. package/dist/identities.d.ts +4 -0
  201. package/dist/image-content.d.ts +5 -2
  202. package/dist/image-resource-history.d.ts +2 -0
  203. package/dist/index-C2r7c6G6.js +714 -0
  204. package/dist/index-CYDvbiwF.js +1 -0
  205. package/dist/index.d.ts +35 -7
  206. package/dist/ink/index.d.ts +27 -0
  207. package/dist/ink/model.d.ts +4 -0
  208. package/dist/ink/save.d.ts +3 -0
  209. package/dist/ink/source.d.ts +7 -0
  210. package/dist/ink.js +324 -0
  211. package/dist/layout-assets.d.ts +3 -1
  212. package/dist/layout-projection.d.ts +17 -5
  213. package/dist/layout-state.d.ts +2 -0
  214. package/dist/layout-types.d.ts +42 -0
  215. package/dist/layout.d.ts +5 -0
  216. package/dist/lint/color.d.ts +5 -0
  217. package/dist/lint/index.d.ts +7 -0
  218. package/dist/lint/prompts.d.ts +3 -0
  219. package/dist/lint/report.d.ts +21 -0
  220. package/dist/lint/sampler-batch.d.ts +4 -0
  221. package/dist/lint/sampler-images.d.ts +2 -0
  222. package/dist/lint/sampler.d.ts +9 -0
  223. package/dist/lint/snapshot.d.ts +34 -0
  224. package/dist/lint/types.d.ts +67 -0
  225. package/dist/lint-sampler.js +187 -0
  226. package/dist/lint.js +659 -0
  227. package/dist/master-state.d.ts +3 -0
  228. package/dist/master-text-style-state.d.ts +3 -0
  229. package/dist/master-types.d.ts +55 -0
  230. package/dist/master.d.ts +5 -0
  231. package/dist/media/audio-icon.d.ts +2 -0
  232. package/dist/media/commands.d.ts +3 -0
  233. package/dist/media/index.d.ts +10 -0
  234. package/dist/media/markup.d.ts +10 -0
  235. package/dist/media/mp4-boxes.d.ts +12 -0
  236. package/dist/media/mp4-fragments.d.ts +8 -0
  237. package/dist/media/mp4-samples.d.ts +4 -0
  238. package/dist/media/mp4.d.ts +2 -0
  239. package/dist/media/poster.d.ts +2 -0
  240. package/dist/media/replace-poster.d.ts +3 -0
  241. package/dist/media/resource.d.ts +4 -0
  242. package/dist/media/source.d.ts +14 -0
  243. package/dist/media/types.d.ts +33 -0
  244. package/dist/media-properties.d.ts +4 -0
  245. package/dist/media.js +1630 -0
  246. package/dist/model-invariants-BM19JVxy.js +8980 -0
  247. package/dist/object-source.d.ts +11 -0
  248. package/dist/ole/container.d.ts +14 -0
  249. package/dist/ole/content.d.ts +94 -0
  250. package/dist/ole/index.d.ts +20 -0
  251. package/dist/ole/preview.d.ts +3 -0
  252. package/dist/ole/save.d.ts +2 -0
  253. package/dist/ole/state.d.ts +16 -0
  254. package/dist/ole.js +870 -0
  255. package/dist/opc.js +1 -1
  256. package/dist/paragraph-level.d.ts +2 -2
  257. package/dist/paragraph-property-schema.d.ts +4 -1
  258. package/dist/{patch-D7lZelRa.js → patch-BwhfBbYE.js} +10 -10
  259. package/dist/patch-events.d.ts +5 -1
  260. package/dist/ppt/appearance.d.ts +11 -0
  261. package/dist/ppt/binary.d.ts +20 -0
  262. package/dist/ppt/drawing.d.ts +18 -0
  263. package/dist/ppt/geometry.d.ts +4 -0
  264. package/dist/ppt/index.d.ts +12 -0
  265. package/dist/ppt/pictures.d.ts +11 -0
  266. package/dist/ppt/text.d.ts +9 -0
  267. package/dist/ppt.js +774 -0
  268. package/dist/preset-geometry.d.ts +6 -0
  269. package/dist/projection.d.ts +2 -0
  270. package/dist/query-BHLjWjnu.js +903 -0
  271. package/dist/recovery-identity.d.ts +1 -0
  272. package/dist/recovery-migrations.d.ts +3 -0
  273. package/dist/recovery.d.ts +3 -0
  274. package/dist/resize/index.d.ts +6 -0
  275. package/dist/resize/text.d.ts +4 -0
  276. package/dist/resize.js +5090 -0
  277. package/dist/retained-element-origins.d.ts +6 -0
  278. package/dist/run-property-fields.d.ts +12 -0
  279. package/dist/run-property-schema.d.ts +3 -1
  280. package/dist/run-style.d.ts +15 -0
  281. package/dist/save/alt-text.d.ts +4 -0
  282. package/dist/save/comments.d.ts +3 -0
  283. package/dist/save/effects.d.ts +2 -1
  284. package/dist/save/extension-availability.d.ts +3 -0
  285. package/dist/save/extension-elements.d.ts +26 -0
  286. package/dist/save/index.d.ts +6 -1
  287. package/dist/save/insertion.d.ts +6 -5
  288. package/dist/save/layout-properties.d.ts +4 -0
  289. package/dist/save/master-properties.d.ts +5 -0
  290. package/dist/save/paragraph-overrides.d.ts +3 -0
  291. package/dist/save/slide-parts.d.ts +1 -0
  292. package/dist/save/table.d.ts +2 -0
  293. package/dist/save/xfrm.d.ts +8 -2
  294. package/dist/save.js +493 -498
  295. package/dist/sections.d.ts +8 -0
  296. package/dist/session-assets.d.ts +4 -0
  297. package/dist/slide-parts-D0o_DDhi.js +1331 -0
  298. package/dist/slide-size.d.ts +6 -0
  299. package/dist/smartart/drawing.d.ts +3 -0
  300. package/dist/smartart/index.d.ts +16 -0
  301. package/dist/smartart/model.d.ts +18 -0
  302. package/dist/smartart/save.d.ts +3 -0
  303. package/dist/smartart.js +604 -0
  304. package/dist/source-retention.d.ts +7 -0
  305. package/dist/space.d.ts +37 -0
  306. package/dist/table-cell.d.ts +7 -1
  307. package/dist/table-grid-projection.d.ts +6 -0
  308. package/dist/table-grid.d.ts +45 -0
  309. package/dist/table-invariants.d.ts +4 -0
  310. package/dist/table-rows.d.ts +2 -1
  311. package/dist/table-scale.d.ts +4 -0
  312. package/dist/table-style.d.ts +5 -4
  313. package/dist/templates/index.d.ts +4 -0
  314. package/dist/templates/recipes.d.ts +5 -0
  315. package/dist/templates/types.d.ts +17 -0
  316. package/dist/templates.js +543 -0
  317. package/dist/text-flatten.d.ts +6 -0
  318. package/dist/text-fragment.d.ts +5 -0
  319. package/dist/text-model.d.ts +8 -8
  320. package/dist/text-override-validation.d.ts +6 -2
  321. package/dist/text-selection.d.ts +4 -0
  322. package/dist/theme-projection.d.ts +8 -0
  323. package/dist/theme-xml.d.ts +3 -0
  324. package/dist/theme.d.ts +14 -0
  325. package/dist/types.d.ts +174 -8
  326. package/dist/xml/index.d.ts +1 -1
  327. package/dist/xml/nodes.d.ts +2 -2
  328. package/dist/xml/shape-ids.d.ts +3 -0
  329. package/dist/xml.js +19 -16
  330. package/package.json +79 -5
  331. package/schemas/describe.schema.json +479 -0
  332. package/schemas/lint.schema.json +145 -0
  333. package/dist/document-B1jjN-QB.js +0 -274
  334. package/dist/image-resource-DbgJS9n-.js +0 -24
  335. package/dist/index-D2JizcOQ.js +0 -706
  336. package/dist/insertion-CGpb504L.js +0 -6152
  337. package/dist/table-style-part-DBtpxmuo.js +0 -1042
package/CHANGELOG.md CHANGED
@@ -4,6 +4,188 @@
4
4
 
5
5
  ## 未发布
6
6
 
7
+ ## 0.5.0 - 2026-10-29
8
+
9
+ 0.5.0 稳定版:`0.5.0-beta.7` 的全部内容转正到 `latest`,编辑线自此成为稳定能力——编辑文档模型与三层视图、模板/主题/母版/版式设计画布、图表数据与样式、批注、页面确保适合、SmartArt/OLE/墨迹内部编辑、高级渲染、PNG/SVG/批量 ZIP/可打印 HTML/图片 PDF 与实验性矢量 PDF/WebM 导出、原生 `.ppt` 生成保存、无来源富文本复制,以及 Agent `describe` 结构化读出与 `lint` 布局检查按需入口。相对 0.4.5 的逐项变化见下方 `0.5.0-beta.1` 至 `0.5.0-beta.7` 条目。
10
+
11
+ 破坏性变更核对:无 API 撤除;0.5 线新增能力均为增量或按需入口,唯一语义变化是 `elementFrameToSlideMatrix` / `elementParentToSlideMatrix` 改为沿渲染链求值(仅非等比组合内非 90° 整数倍旋转等场景结果不同,见 beta.7 条目)。
12
+
13
+ 安装:无版本号安装即得 0.5.0,八包必须同版本;`@next` 标签留给 0.6 线。
14
+
15
+ `@web-ppt/collab` 发布入口为 12.20KB gzip;排除 peer 的完整测试薄包为 14,333B gzip,两种口径分别核对。
16
+
17
+ Windows PowerPoint 真机验收经维护者决定延后,0.5.0 先行转正;四项自动门禁(含 LibreOffice 外部打开清单)全部通过,后续问题以 0.5.x 补丁版修复。
18
+
19
+ ## 0.5.0-beta.7 - 2026-10-26
20
+
21
+ ### 新增
22
+
23
+ - 新增按需 `@web-ppt/edit-core/lint` 七项布局检查与 `/lint/sampler` SVG 颜色采样协议:稳定元素定位、真实字体测量、显式资源错误、进度与取消,随包提供生成 Schema。
24
+ - 新增按需 `@web-ppt/edit-core/describe`:从当前 `EditDoc` 读出页面、设计来源、稳定元素 ID、页面外框和段落文字;支持完整 JSON 的字符 / token 预算及显式截断,随包发布由 TypeScript 类型生成的 JSON Schema。
25
+ - `presentationToVideo` 新增实验性 `videoOverlay`:导出时以 `<video>` 当前帧替代内嵌视频的海报帧,媒体起始时刻与音轨共用同一时间轴;默认关闭时产物不变。
26
+ - `savePpt` 原生写入首尾两色线性渐变(两端透明度分别保留)、十种预设虚线、五种默认尺寸箭头、图片四边矩形裁剪与形状名;图案填充、多色标或径向渐变、自定义虚线与非默认箭头尺寸仍以 `PptSaveError` 拒绝
27
+ - `@web-ppt/edit-core/ole` 新增 `setRun`(嵌入 DOCX 单个 run 改字,相邻格式保留)、`setCellStyle`(嵌入 XLSX 字体 / 填充 / 边框)与 `setCellRichText`(sharedStrings 富文本);`OleParagraph` 新增 `runs` 与表格行列 `table`,`OleCell` 新增 `styleIndex`、`style` 与 `richText`
28
+ - 实验性矢量 PDF 支持 dashed / dotted / double / wavy 文字装饰线,以及文字描边(描边轨在填色轨之下,等效 `paint-order:stroke`)。
29
+
30
+ ### 修复
31
+
32
+ - 编辑性能基准统一使用完整源码别名和同一个运行时,不再依赖尚未构建的 dist 或重复的会话 WeakMap;增加干净构建状态的真实回归。
33
+ - 组合同时带旋转与非等比缩放时不再拒绝解组:解组改按 `placeGroupChild` / `placeGroupFrame` 的渲染外框回填孩子 frame,旋转子元素的宽高按转角象限承接组缩放;非等比缩放下预设形状的渲染路径会固化为自由形状覆盖,保存写回 `custGeom`,箭头、圆角等依赖宽高比例的几何不再变形。只有需要改变旋转的框架对象(图表 / OLE 等)仍显式拒绝。
34
+ - 读取 `.ppt` 时线性渐变不再一律按竖向、前景色在上渲染:方向取自 fillAngle,首尾色按 fillAngle 的符号与 fillFocus 还原(与 LibreOffice 的 PowerPoint 兼容规则一致,焦点 40–60 为两侧对称渐变),终点透明度取自 fillBackOpacity;图片的 cropFrom* 裁剪与 wzName 形状名不再丢失。
35
+ - `presentationToVideo` 的 `videoOverlay`:内嵌视频加载失败或超时不再静默退回海报帧,改为经 `onWarning` 以稳定原因 `video-overlay-unavailable` 暴露(附页号与元素名),seek 超时或帧不可用报 `video-overlay-frame-unavailable`,导出均不中断;就绪条件改为首帧可画,避免只取到元数据时首帧停在海报上。未开启 `videoOverlay` 时产物不变。
36
+ - 修复 `.pptx` 媒体源解析只认经典 `a:audioFile` / `a:videoFile` 引用:PowerPoint 2010+ 内嵌 mp3 / mp4 等时把经典关系写成 `Target="NULL"` 外链、字节只挂在 `p14:media` 的 `r:embed` 上,此前 `MediaInfo.src` 为 `null`,player 模式不生成播放器、编辑生成保存会丢失媒体字节。现按经典引用 → `p14:media`(`r:link` 优先于 `r:embed`)逐个取第一个可解析目标:包内关系要求部件存在,外链关系要求是带 scheme 的 URL;正常文件的解析结果不变。
37
+ - 修正视频导出过期说明:`presentationToVideo` 已支持可选音轨;含内嵌媒体时 `mediaPosters: true` 在开启 `audio` / `videoOverlay` 时仍必需,拒绝信息与文档同步说明原因。
38
+ - 英语缩写中的弯撇号(`I’m`、`that’s`)不再按全角标点挤压半个 em,避免撇号与后一个字母重叠(#8)。中文句读的挤压规则不变。
39
+ - 对象动画「伸展」按 PowerPoint 子类型播放:水平展开(across)从中线向两侧长,自底部 / 顶部 / 左侧 / 右侧钉住对应边长出,不再一律从中心缩放并淡入;退场缩回同一条边。「挥舞」按 PowerPoint 的 `sin(2.5π·t)` 宽度(横向为高度)轨迹翻转并叠加淡入,中途会转到背面镜像,不再是一次 `rotateY`。
40
+ - 组合缩放只映射子元素外框:渲染时把 `chOff` / `chExt` 折算进子元素的位置、尺寸、路径与表格行列,不再对子树整体 `scale()`,描边、字号、内边距与效果半径保持物理尺寸(与 PowerPoint、LibreOffice 一致)。WPS 产出的归一化组合(子坐标空间不足 1px)不再出现千像素描边或逐字换行;普通缩放组合内的字号与描边也不再随组放大,非等比组合里的旋转子元素保持矩形。编辑器按同一份刚体外框工作:选择框、命中、框选、对齐 / 分布、吸附、裁剪、顶点与调节柄不再把非等比组合里的旋转子元素当成斜切的平行四边形;缩放与旋转在父组渲染坐标里计算后换算回模型,旋转跨过 45° 等边界时画面宽高保持不变(模型宽高随组缩放承接的轴向互换),粘贴进非等比组合同样按画面落位。`@web-ppt/core` 公开 `placeGroupChild`、`placeGroupFrame` 与 `unplaceGroupFrame`;`@web-ppt/edit-core` / `@web-ppt/editor` 公开 `renderedElement`、`renderedFrameToSlideMatrix`、`renderedContentToSlideMatrix`、`elementParentToRenderedParentMatrix`、`elementEditFrame`、`elementEditParentToSlideMatrix`、`slideToElementEditParentPoint` 与 `editFrameToModelFrame`(edit-core 另有 `groupEditChildrenToSlideMatrix`、`groupEditFrameToModelFrame`);`elementFrameToSlideMatrix` 与 `elementParentToSlideMatrix` 改为沿渲染链求值,只在非等比组合内的非 90° 整数倍旋转、或此类组合嵌套时结果不同(#7)。
41
+ - `wedgeRectCallout` / `wedgeRoundRectCallout` 按 ECMA-376 guide 求值:尾巴从尾尖所在一侧的边伸出,圆角取 `adj3`;此前底座固定在下边,尾尖朝上时尾巴穿过整个框只剩一条细线(#7 附件)。
42
+ - 非占位符形状 `p:style` 的 `fontRef` 颜色压过 presentation `defaultTextStyle` 的方案色,形状自身 `lstStyle` 与 `rPr` 仍优先;PowerPoint 默认形状里的白字不再渲染成黑字。
43
+ - 背景 `bgRef` 按 ST_StyleMatrixColumnIndex 取主题样式:`1001` 起对应 `bgFillStyleLst` 第 1 项、`1`–`999` 对应 `fillStyleLst`;此前 `idx="1001"` 被夹到列表末项,最常见的白色背景被画成主题第三档渐变。
44
+ - run 的字体栈只在文字含复杂文种(阿拉伯文、希伯来文、泰文、天城文等)时才纳入 `a:cs` 字体;此前拉丁字体缺席时 `cs`(如 WPS 常写的 Arial Black)会接管拉丁字母,标题被撑宽断行。新增公开函数 `textRunFontStack` 供编辑投影共用。
45
+ - 只写 `asvg:svgBlip`、`a:blip` 上没有位图兼容副本的图片(WPS 插入的图标)按 SVG 部件渲染,不再显示为不支持的对象。
46
+ - 有封面且源可用的音频不再叠加灰色播放标识(封面本身就是喇叭图标);`media: 'player'` 下音频不显示原生控件条,`Viewer` 点击封面播放 / 暂停,播放被拒绝时同样派发 `web-ppt-playback-error`。官网查看器改用 player 模式,放映中点击媒体不翻页。
47
+ - 等线缺席时西文改用合成字族:`local()` 引用系统 Arial 度量族,粗体 `size-adjust: 95.4%`、下划线 `74.6%`,只在页面出现等线时声明;`@web-ppt/fonts` 的替换路径对 Arimo 套用同一组参数。取代窄体回退与连续空格半字宽的处理;依据是 #8 附带的 PowerPoint 导出图逐词拟合,断行与填空线长度与 PowerPoint 一致。
48
+ - `Viewer` 执行动画时间线里的 `mediacall` 媒体调用(`playFrom` / `pause` / `stop` 等),`afterPrev` 等定时触发的音视频按时播放,切页或取消时暂停;`play()` 被浏览器拒绝时容器派发 `web-ppt-playback-error`。媒体调用步骤不再给图标留下强调动画的半透明终态(#7)。
49
+
50
+ `@web-ppt/collab` 发布入口为 12.20KB gzip;排除 peer 的完整测试薄包为 14,333B gzip,两种口径分别核对。
51
+
52
+ ## 0.5.0-beta.6 - 2026-10-10
53
+
54
+ ### 新增
55
+
56
+ - `presentationToVideo` 新增可选音轨:`audio: true` 时解析 timing 树媒体节点(`p:audio` 的音量 / 静音 / 循环 / 触发批次),按页时间轴确定性混音后以 Opus 48kHz 编码进 WebM 双轨;视频文件的 AAC 音轨同样提取混入,无音轨或解码失败经 `onWarning` 以稳定原因跳过、不阻断导出。无音频媒体时仍为无声视频,默认关闭时产物与上一版逐字节一致。公开 `WebmWriter` 音频轨与 `mixAudioClips` 混音核;`MediaInfo` 扩展 `spid` 与 `playback` 播放语义。
57
+ - 实验性矢量 PDF 的文字渐变原生支持(Pattern colorspace):任意轴线性渐变、同段多 run 各自分框(按字形墨迹范围)、下划线 / 删除线继承渐变。坐标口径经 MuPDF / poppler / CoreGraphics 三实现实测裁决;透明渐变因渲染层无输入语义暂按稳定原因回退。
58
+
59
+ ### 改进
60
+
61
+ - CJK 标点挤压补全 PowerPoint 完整规则:连续标点对、行首起始标点与行尾句读无条件收半格;断行判定仍按全角,与 PowerPoint 断行基线一致。
62
+ - 网络字体到货后的重排补齐数学布局缓存失效:`invalidateTextMeasureCaches` 公开导出,`Viewer.refresh()` 完整覆盖字体环境变化。
63
+ - 文档体系新增功能设计标准、分层依赖规范与 `.pptx` / `.ppt` 规范地图;依赖方向由 `check-architecture-boundary` 在 build 与 verify 机械审计。
64
+
65
+ ### 修复
66
+
67
+ - 修复矢量 PDF 跨页复用渐变 Pattern 时未在当前页注册资源导致的整段取色错误(单页导出不触发)。
68
+ - 修正 README 已知限制与能力矩阵的三处失真(EMF+ / OMML / 3D)及打开密码文件的能力描述。
69
+
70
+ `@web-ppt/collab` 发布入口为 12.20KB gzip;排除 peer 的完整测试薄包为 14,333B gzip,两种口径分别核对。
71
+
72
+ ## 0.5.0-beta.5 - 2026-09-10
73
+
74
+ ### 新增
75
+
76
+ - 高级文本生成保存与跨文稿复制支持公式、艺术字及已声明的高级文字效果;经典图表支持多级类别与共享工作簿同步,保留历史、恢复、协同和原生保存闭环。
77
+ - 新增实验性 `@web-ppt/core/pdf/vector` 及独立 browser 适配入口:支持范围内的文字可搜索,图形保留矢量,特殊效果按对象回退为图片并返回位置说明。
78
+ 编辑器导出窗口通过 Cordis 文件 / 字体服务提供入口,缺字体可定位并加载本机字体后重试;取消、换稿和退出等待实际资源消费结束。此版本不代表 005 整项验收完成;复杂文字效果、更多 SVG 组合、其他 PDF 阅读器及长文稿成本仍待收口。
79
+ - 新增 `@web-ppt/fonts/glyphs` 可选字体 Provider 及 HarfBuzz、Worker、FontFace 适配:验证原始容器与嵌入限制,返回定位字形、轮廓和 UTF-16 原文簇;整形器和字体字节由宿主提供。
80
+ 产品编辑器由 Cordis 文稿服务检查、应用和释放字体,提供中英文缺字诊断与本机替换;原始字体模式避免主线程重复解压,替换和安装失败会归还旧字体预算。当前字体资源用于预览及图片 / SVG / 实验性矢量 PDF 导出,不写入 PPTX。
81
+ - 可选 `@web-ppt/collab/migration` 入口为扩展字段保留带原 stamp 的 `set/del` 操作证据;来源元素或页面删除后仍可恢复。
82
+ 与默认入口共用协同会话和回滚,旧检查点缺少证据时保持未知;共享图表可按原操作裁决矛盾字段和删除,后续原操作可补齐缺失证据。
83
+ - 编辑核心可原子执行已裁决的扩展迁移凭据,保留来源操作、删除赢家和冷恢复语义;拒绝不完整来源及父子字段冲突。
84
+ 可选协同入口在远端接收和延迟消息消费时重新裁决,保留更晚本地操作;默认入口拒绝凭据,原始版本不会替换为运输消息的时钟。
85
+ 恢复日志在提交前准备声明,旧字段按原地址和顺序重放;解析器乱序释放不会复活旧实例。
86
+ - 包体积核对改为默认入口及全部相对静态分块逐文件 gzip 后求和,修正旧表漏算共享分块的问题;peer 与动态入口仍另计。
87
+ - 官网编辑产品层通过同一 Cordis 应用管理文稿、打开、新建、恢复、文件、业务工具与页面状态;页面插件持有模式、导航、历史和视口,入口仅保留启动及重试。
88
+ 新打开取消旧模板和图片选择,退出先停止页面与 SDK 编辑输入,再等待已提交文件交付,最后释放文稿、监听、观察器和弹窗;重建后命令不重复。发布 SDK 保持无框架依赖。
89
+ - 图片插入、替换和背景接口支持 `options.signal`;取消会释放待选入口,并在读取、解码及提交边界阻止迟到修改,
90
+ 避免应用退出等待文件交付期间旧工具继续写入文稿。
91
+ - 共享图表入口迁移独立数据区域的旧局部编辑,保留旧撤销历史、协同时钟及迟到消息;支持加载前复制页及
92
+ 多旧所有者/新旧数据的相等或不同字段合并。删除整张原页及中间副本后,幸存副本仍可编辑、保存和冷恢复。
93
+ 可选协同入口让复制快照继承可证明的原 set/del 版本,保留副本远端更新后的撤销重做,并裁决已加载共享入口的迟到复制。
94
+ 缺失原版本或同版本矛盾的字段、无来源记录及日志的旧裸模型、身份冲突仍保留只读,完整范围见迁移记录。
95
+
96
+ ### 验证与范围
97
+
98
+ - `@web-ppt/collab` 发布入口为 12.20KB gzip;包含相对静态分块。排除 peer 的完整测试薄包为 14,333B gzip,两种口径分别核对。
99
+ - 字体及 PDF 独立读取依赖固定版本并接入 CI / 发布环境;矢量 PDF 源码与产物契约纳入常规功能和一致性门禁。
100
+ - 保留 beta.4 的密码弹窗与 CI 稳定性修复。视频仍无音轨、内嵌视频合成和长尾格式扩展待后续;Windows PowerPoint 真机继续暂缓。
101
+ - 模块成果与下一步见[本轮交付说明](https://github.com/unStone/web-ppt/blob/master/docs/releases/0.5.0-beta.5.md)。
102
+
103
+ ## 0.5.0-beta.4 - 2026-09-09
104
+
105
+ ### 剩余功能收口
106
+
107
+ - 补齐四个产品入口的只读批注面板、PNG/SVG/ZIP 标记与打印正文;生成保存不再丢失批注,复制页独立分配批注部件和索引。
108
+ - 批注复制覆盖连续保存、撤销/重做、来源释放、外部补丁、恢复、最大索引及显式 Internal/未知 XML 扩展。
109
+ - 十页混合固件贯通七种原生现代布局、地图回退、经典数据、WAV/MP4、图片/立体和批注;新增包名产物契约及 0.8 功能完成度门禁。
110
+ - 新增按需图片效果和立体编辑,官网控件共用历史、恢复、协同与两条保存;双色调在 PNG/独立 SVG 中使用真实颜色。
111
+ - 官网与查看器遇到 ChartEx 自动按需启用原生解析,加载失败继续显示来源预览;SDK 默认行为不变。
112
+ - 新增可选画布读屏目录和 EditContext,真实 Chromium 覆盖预编辑、连续输入、撤销及加载失败回退。
113
+ - 修复经典图表系列标题与子节点顺序、零挤出重开及未加载扩展时双色调生成保存丢失。
114
+ - 补充混合内容保存旅程、公开 API 契约和迁移说明;Windows 真机按用户要求暂缓。
115
+
116
+ ### 新增
117
+
118
+ - 新增 `@web-ppt/core/chart-ex` 与显式解析 hook:树状图、旭日、直方图/Pareto、箱线、瀑布和漏斗输出原生 Schema;
119
+ 地图、歧义数据与不支持的来源保留 Office fallback。主题、母版与保存后继续沿用文稿打开时的解析配置。
120
+ SDK 默认入口不加载实现;官网按内容类型自动加载。其他类型真实 PPTX 和 Office 原生布局验收尚未完成。
121
+ - 官网增加中英文基础入口:三张页面输出静态英文镜像与双语 SEO,URL 优先于本机偏好和浏览器语言;
122
+ 原地切换保留文稿、选区和撤销历史,中文默认不下载英文词库。编辑页打开/保存/图片 ZIP、转换确认、
123
+ 模板选择、本机恢复、动态工具与无障碍文案均已接入;模板和恢复提示内可直接切换语言。
124
+ - 媒体按需入口支持 PCM WAV / MP4(含分片)、显式 HTTP(S) 外链、确定性音频图标和独立海报替换;
125
+ editor / React / Vue 和官网媒体工具转发同一 API,默认入口不加载媒体校验或图标。
126
+ 官网支持选中媒体试听、失效外链提示与按需媒体日志恢复,外链仅在点击播放时访问;切换文稿和关闭工具释放播放器。
127
+ - 经典图表新增按需数据编辑入口,支持系列、类别和数值增删改;稀疏覆盖贯通历史、恢复与协同,保存同时同步
128
+ 图表缓存和内嵌工作簿。官网数据检查器动态加载,默认入口不携带图表编辑实现。
129
+ - 主题、母版、版式与内置模板现已组成同一条公开编辑链:主题经 `exec`,母版与版式经 `execDesign`
130
+ 精确传播到依赖页,页面直设继续优先;三套模板共用历史、恢复、字段级协同与保存协议。
131
+ - 新增独立按需模板入口:极光、刊页、夜幕三套确定性配方各自物化主题、母版、五种常用版式和可编辑标题页;
132
+ 官网、无框架 editor 与 React/Vue 只转发同一目录,默认入口不加载配方或预览数据。
133
+ - 编辑模型补齐字符、自动编号和图片项目符号;结构化来源值、富文本剪贴板、格式刷、表格文字、恢复、协同
134
+ 以及补丁/生成保存使用同一套项目符号语义。
135
+ - 新增预设形状切换、DrawingML 调节值和独立 `@web-ppt/editor/adjustments` 拖柄入口;187 个预设中
136
+ 120 个含句柄的定义由固定规范源生成,未使用时不进入 editor 主包。
137
+ - 高级字符格式新增 17 种精确下划线、双删除线、高亮、字距、大小写与基线上下标;`ClearFormat` 删除
138
+ 来源直设并保留文字、动态字段、公式和链接身份。
139
+ - 新增按需入口 `@web-ppt/core/image-zip`:以稳定原页码命名批量导出动画终态 PNG,支持隐藏页策略、
140
+ 1–8 路有界并发、确定性 ZIP 元数据与逐页进度;任一页失败会携带页码原子拒绝,不返回半成品。
141
+ 它复用单页 data URI + `foreignObject` 光栅化与 `SecurityError` 原生文本回退,不引入第二套渲染器。
142
+ - 编辑模型、无框架 editor 与 React/Vue 类型入口补齐对象等距分布、替代文字、节管理和页面尺寸;四组能力
143
+ 贯通来源恢复、历史/恢复、字段级协同及保留型/生成式保存,页面尺寸采用不重排元素的“最大化”语义。
144
+ - 无框架 editor 新增仅触屏启用的细描边命中容差、双指缩放/平移和 500ms 长按上下文请求;导航结果经
145
+ adapter 与 React/Vue 公开 seam 交给宿主,不写模型、历史、恢复日志或保存内容,查看模式保留页面滚动。
146
+ - `EditorSession.toPresentation()` 公开当前编辑态只读投影,让官网可直接批量导出图片 ZIP,同时保持脏状态
147
+ 与保存点不变;资源生命周期仍由会话统一拥有。
148
+
149
+ ### 改进
150
+
151
+ - `@web-ppt/collab` 发布入口为 11.76KB gzip;契约测试使用的完整薄包在排除 peer 后为 14,288B gzip。
152
+
153
+ ### 修复
154
+
155
+ - 官网打开加密 `.pptx` / `.ppt` 时弹出密码对话框:错误密码可原地重试,正确后继续查看;core 暴露可识别的 `PasswordRequiredError`,避免界面依赖错误文案判断。
156
+ - 官网内联 CSS 后仅删除无引用产物,并等 Vite 生成预加载清单后再检查,避免共享样式缺失导致动态编辑模块打不开。
157
+ - 无封面媒体新增海报后可保存;兼容分支媒体继续保留整壳限制。生成保存不再重放旧海报关系。
158
+ - 公开 Patch 事件补齐图片资源闭包,修复接收端撤销回收后无法重做;提交及历史双向闭包超限在提交前原子拒绝,
159
+ 合并历史超限则保留独立撤销单元。
160
+ 无 OOXML 所属页的新建对象可恢复,仍被无来源海报引用的资源不可被远端删除。
161
+ - MC 兼容内容按声明命名空间与实际能力选择;真实 ChartEx 漏斗回退图恢复显示,编辑以完整兼容外壳为身份。
162
+ 移动、复制、层级、撤销与两条保存同步保留所有表示及原始数据;编辑会话保留兼容来源,原包释放后仍可生成保存,缺失或冲突的源依赖明确报错。
163
+ - 复制、外部补丁回放和恢复分配对象 ID 时计入未显示的兼容分支,避免新增形状撞 ID;OPC 写回不再因
164
+ Node Buffer 的切片共享内存而污染调用方输入。
165
+ - 0.7 集成验收打通“模板 → 主题 → 母版 → 版式 → 普通页面 → 保存重开”,并修复普通页面事务可绕过
166
+ 设计画布权限的问题;普通页面权限隔离现由唯一提交入口统一执行。
167
+ - LibreOffice 与 Windows PowerPoint 改为消费同一份 11 件 Office 清单;清单、产物字节和 PowerPoint
168
+ 报告均绑定当前提交,避免两套验收范围悄然分叉。
169
+ - 0.6 跨能力新建旅程打通表格、项目符号、预设形状、高级字符、等距分布、替代文字、节、页面尺寸、
170
+ 触屏与批量导出;恢复后分别走补丁和生成保存,再由 Chrome 与 LibreOffice 重开验证。
171
+ - 生成保存现在保留动态页码字段与替代文字;此前这些能力单独测试可用,但从空白文稿混合编辑后会拒绝
172
+ 动态字段或丢失 `cNvPr@title/@descr`。
173
+
174
+ ## 0.5.0-beta.3 - 2026-08-31
175
+
176
+ ### 新增
177
+
178
+ - `@web-ppt/edit-core` 新增稳定表格网格:任意位置插删行列、行高列宽、合并拆分与直接单元格格式都按
179
+ 稳定行列身份寻址,并通过公开 `queryTableGrid` 与纯数据命令进入历史、恢复和保存链路。
180
+ - 表格 tombstone 与完整合并真值让删除只改变可见投影;被合并覆盖的文字和格式休眠而不销毁,拆分、撤销及
181
+ 保存重开后仍恢复同一逻辑格。`@web-ppt/collab` 同步覆盖并发插删、合并和“至少保留一行一列”的确定性收敛;
182
+ 发布入口为 11.76KB gzip;契约测试使用的完整薄包在排除 peer 后为 14,288B gzip,两种口径不混用。
183
+
184
+ ### 改进
185
+
186
+ - 发布前一致性门禁统一核对版本、许可证、链接、断言数、快照数、包体积和发布包清单,并把 0.6 后续能力拆为
187
+ 可独立验收的 Wayfinder 票据。
188
+
7
189
  ## 0.5.0-beta.2 - 2026-08-30
8
190
 
9
191
  ### 新增
@@ -15,6 +197,7 @@
15
197
  - 新增可选的 `@web-ppt/collab`:字段级 LWW、分数序与确定性页序重物化把 `Editor` 补丁流接到
16
198
  可插拔 provider,支持离线幂等回放、remove-wins、远端历史 rebase 和 BroadcastChannel 双标签页。
17
199
  OOXML 元素身份由 provider 分配的副本 slot 精确分区;协同包不进入单机 `editor` 入口。
200
+ 发布入口为 10.70KB gzip;契约测试使用的完整薄包在排除 peer 后为 13,023B gzip,两种口径不混用。
18
201
 
19
202
  ### 改进
20
203
 
package/README.md CHANGED
@@ -6,13 +6,64 @@ The headless, framework-agnostic editing model for [Web-PPT](https://github.com/
6
6
  It keeps parsed source values separate from user overrides, assigns stable session identities, and projects
7
7
  an editable document back to the existing high-fidelity `Slide` schema. It has no DOM dependency.
8
8
 
9
+ `@web-ppt/edit-core/describe` reads the current document as deterministic JSON with stable element IDs,
10
+ slide geometry, placeholder ancestry, paragraphs, and explicit character/token budget truncation.
11
+ The opt-in entry and its published JSON Schema are documented in [Agent describe](https://github.com/unStone/web-ppt/blob/master/docs/api/agent-describe.md).
12
+
13
+ `@web-ppt/edit-core/lint` adds deterministic layout observations with host-supplied font measurements,
14
+ explicit resource failures and cancellation. Complex paint can use the opt-in SVG contrast sampler;
15
+ see [Layout lint](https://github.com/unStone/web-ppt/blob/master/docs/api/agent-layout-lint.md).
16
+
9
17
  ```bash
10
18
  npm i @web-ppt/core@next @web-ppt/edit-core@next
11
19
  ```
12
20
 
21
+ Built-in templates are a separate opt-in entry. The catalog is frozen pure data suitable for a custom picker;
22
+ generation needs no network, bundled font bytes, random values, or timestamps:
23
+
24
+ ```ts
25
+ import { createPptxFromTemplate, listBuiltinTemplates } from '@web-ppt/edit-core/templates';
26
+
27
+ const catalog = listBuiltinTemplates();
28
+ const bytes = createPptxFromTemplate('aurora', { width: 1280, height: 720 });
29
+ ```
30
+
31
+ `aurora`, `editorial`, and `midnight` each produce an editable theme, master, title/content/two-content/section/
32
+ blank layout set, and title slide. `createBlankPptx()` keeps its existing byte-compatible minimal output.
33
+
34
+ Classic chart data editing is also opt-in, so the default editor entry does not load the chart or SpreadsheetML
35
+ patcher:
36
+
37
+ ```ts
38
+ const charts = await import('@web-ppt/edit-core/chart');
39
+ const chart = charts.listEditableCharts(doc)[0];
40
+ const dataset = charts.queryChartData(doc, chart.id);
41
+ const dataEditor = charts.createChartDataEditor(editor);
42
+ dataEditor.setValue(chart.id, dataset.series[0].id, dataset.categories[0].id, 4096);
43
+ ```
44
+
45
+ `binding.mode` is explicit: `workbook` updates the chart cache, formulas, and embedded XLSX together; `cache`
46
+ updates only literal/cache data; `readonly` rejects edits when a workbook formula cannot be interpreted safely.
47
+
48
+ Use `@web-ppt/edit-core/chart-shared` with the same API when chart parts or embedded workbooks are shared.
49
+ Mixed charts can add and remove categories and XY points in independent data regions, including regions with different
50
+ orientations. Overlapping category/XY ranges with a common record axis share additions, removals, stable identities,
51
+ and scalar edits. Partial views and rebuilding after an empty save retain that connection. Dimensions across sheets,
52
+ directions, or record starts remain unsupported for structural edits.
53
+ Call `registerSharedChartEditing()` before mounting a restored document to migrate supported legacy local overrides.
54
+ Cache-only charts and independently owned workbook charts retain edits across copied pages when their source identity is
55
+ provable, including after the original page is deleted. Conflicting fields require original versioned operations through
56
+ `@web-ppt/collab/migration`; missing evidence or ambiguous identities preserve the overrides and reject shared saving.
57
+ When `binding.unresolved === true`, `reason` explains why current data is unavailable. Categories and series are empty,
58
+ the editor shows a failure placeholder, and `chartProjection()` rejects the request. This is not an empty dataset or a
59
+ successful restoration. Read-only charts with readable source data keep their normal preview.
60
+
13
61
  ```ts
14
62
  import { layoutText, parse, renderElementToSvg, renderSlideToSvg, renderTextBodyToHtml } from '@web-ppt/core';
15
- import { createDoc, Editor, querySelectionPane } from '@web-ppt/edit-core';
63
+ import {
64
+ createDoc, Editor, listLayouts, listMasters, listThemes, queryLayout, queryMaster,
65
+ querySelectionPane, queryTheme,
66
+ } from '@web-ppt/edit-core';
16
67
 
17
68
  const source = await parse(file, { edit: true, keepPackage: true, lazy: false });
18
69
  const doc = createDoc(source);
@@ -48,9 +99,34 @@ editor.exec({ type: 'MoveSlide', id: newSlideId, at: { after: null } });
48
99
  const duplicated = editor.exec({ type: 'DuplicateSlide', id: newSlideId });
49
100
  const duplicateSlideId = [...duplicated.createdSlides][0];
50
101
 
102
+ const theme = listThemes(doc)[0];
103
+ editor.exec({
104
+ type: 'SetTheme', id: theme.id,
105
+ clrScheme: { accent1: '#112233' },
106
+ fontScheme: { minor: { latin: 'Aptos' } },
107
+ });
108
+ const effectiveTheme = queryTheme(doc, theme.id); // source, effective value, and direct state
109
+
110
+ const layout = listLayouts(doc)[0];
111
+ const layoutState = queryLayout(doc, layout.target); // source, effective value, and direct state
112
+ editor.execDesign(layout.target, {
113
+ type: 'SetBackground', target: layout.target,
114
+ fill: { type: 'solid', color: '#112233' },
115
+ });
116
+ const layoutCanvas = editor.toDesignCanvas(layout.target); // same Slide schema as page rendering
117
+
118
+ const master = listMasters(doc)[0];
119
+ const masterState = queryMaster(doc, master.target); // background and title/body/other × 9 source/value/direct state
120
+ editor.execDesign(master.target, {
121
+ type: 'SetMasterTextStyle', target: master.target, category: 'body', level: 1,
122
+ paragraph: { align: 'right' }, run: { font: 'Aptos', size: 30 },
123
+ });
124
+ const masterCanvas = editor.toDesignCanvas(master.target);
125
+
51
126
  const slide = editor.toSlide(slideId);
52
127
  const svg = renderSlideToSvg(source, slide, { idPrefix: `${slideId}-` });
53
- const dirty = renderElementToSvg(editor.effectiveElement(elementId), {
128
+ // renderedElement folds ancestor group scaling into the frame, matching the full-slide render.
129
+ const dirty = renderElementToSvg(editor.renderedElement(elementId), {
54
130
  idPrefix: `${slideId}-${elementId}-`,
55
131
  });
56
132
  // Replace this element's `dirty.markup` and `dirty.defs` partitions together.
@@ -83,7 +159,7 @@ if (element.kind === 'shape' && element.text) {
83
159
  Commands and patches are plain JSON. A transaction validates and commits atomically, creates one local undo
84
160
  unit, and restores selection on undo/redo. Repeated edits with the same `mergeKey` merge for at most 500ms;
85
161
  remote `origin` values apply without entering local history. `isDirty()` compares the current state with the
86
- last `markSaved()` checkpoint. React, Vue, Web Components, or vanilla adapters only need `subscribe()` and
162
+ last confirmed checkpoint (`markSaved()` for immediate acknowledgement). React, Vue, Web Components, or vanilla adapters only need `subscribe()` and
87
163
  the two projection methods; none of their runtimes enter this package.
88
164
  Collaborative clients must pass a stable, client-unique `origin`; appended-row identities include it so two
89
165
  structured-cloned documents can merge concurrent appends without sharing a path.
@@ -157,6 +233,26 @@ flipped/non-uniformly scaled groups, and frame-only objects share the same world
157
233
  is one undo unit; already aligned targets create no empty history. A React, Vue, Web Component, or vanilla toolbar
158
234
  can map its six buttons directly to this JSON command without importing DOM internals.
159
235
 
236
+ `DistributeElements { ids, axis: 'horizontal' | 'vertical' }` keeps the first and last visual AABBs fixed and
237
+ spaces at least three movable top-level objects evenly. `SetAltText { id, title, descr }` edits the two
238
+ accessibility attributes independently from the selection-pane name; `null` restores either source value.
239
+ `listSections()` plus `AddSection`, `RenameSection`, `MoveSection`, and `RemoveSection` use stable `SlideId`
240
+ memberships, including duplicate/delete-page history and field-level collaboration. `SetSlideSize { w, h }`
241
+ changes the presentation canvas without silently moving or scaling any element; `null` restores the source size.
242
+ All four groups are one-command/one-undo-unit APIs and round-trip through retained and generated PPTX saves.
243
+
244
+ ```ts
245
+ import { listSections, queryElementAltText, querySlideSize } from '@web-ppt/edit-core';
246
+
247
+ editor.exec({ type: 'DistributeElements', ids: selectedIds, axis: 'horizontal' });
248
+ editor.exec({ type: 'SetAltText', id: elementId, title: 'Revenue chart', descr: 'Quarterly trend' });
249
+ const section = listSections(editor.doc)[0];
250
+ editor.exec({ type: 'RenameSection', id: section.id, name: 'Results' });
251
+ editor.exec({ type: 'SetSlideSize', w: 1600, h: 900 });
252
+ const size = querySlideSize(editor.doc);
253
+ const alt = queryElementAltText(editor.doc, elementId);
254
+ ```
255
+
160
256
  `SetFill { id, fill }` edits vector fills on shapes: explicit no-fill, solid color, linear/radial gradients,
161
257
  and renderer-supported DrawingML patterns. `SetStroke { id, stroke }` edits shape outlines and image borders,
162
258
  including color, pixel width, preset dash, cap, join, compound line, and line ends. Colors are normalized to the
@@ -287,10 +383,15 @@ through page reorder, undo/redo, save/reopen, and same/cross-document element co
287
383
  actions remain queryable and preserved as read-only source values.
288
384
 
289
385
  `SetRunProps` applies sparse character-format overrides to a half-open text range. It supports font family,
290
- font size in slide pixels, bold, italic, underline, and strike-through across run and paragraph boundaries.
386
+ font size in slide pixels, bold, italic, highlight, letter spacing, caps, baseline shift, all 18 DrawingML
387
+ underline values (`none` plus 17 styles), and single/double strike-through across run and paragraph boundaries.
291
388
  Use `null` to remove a direct override and reveal the inherited OOXML value; formulas remain indivisible,
292
389
  format-preserving atoms while dynamic fields retain their field identity on save. A collapsed headless range is intentionally a no-op—
293
390
  pending typing style belongs to the mounted input adapter, so the document never stores zero-width OOXML runs.
391
+ The legacy boolean `u` and `strike` inputs remain supported and map to `sng`/`none` and
392
+ `sngStrike`/`noStrike`; new code should use `underline` and `strikeType` for exact round trips.
393
+ `ClearFormat` removes every direct visual run property in the selected range while preserving text,
394
+ paragraph properties, hyperlinks, dynamic fields, and formula atoms.
294
395
 
295
396
  ```ts
296
397
  import { queryRunProps } from '@web-ppt/edit-core';
@@ -301,32 +402,45 @@ const range = {
301
402
  };
302
403
  editor.exec({
303
404
  type: 'SetRunProps', id: elementId, range,
304
- props: { font: 'Inter', size: 24, b: true },
405
+ props: {
406
+ font: 'Inter', size: 24, b: true, highlight: '#fff176', spacing: 2,
407
+ caps: 'small', baseline: 30, underline: 'wavyDbl', strikeType: 'dblStrike',
408
+ },
305
409
  });
306
410
  const state = queryRunProps(editor.doc, elementId, range);
307
411
  // state.b: { value: true, mixed: false }; each property reports mixed state independently.
412
+ editor.exec({ type: 'ClearFormat', id: elementId, range });
308
413
  ```
309
414
 
310
415
  `SetParaProps` applies paragraph formatting to every paragraph touched by a range, including empty paragraphs.
311
416
  A collapsed range formats its current paragraph immediately. The P0 property set is alignment, effective line-height
312
417
  multiplier, spacing before/after in slide pixels, left margin in slide pixels, and signed first-line indent in slide
313
- pixels. `null` removes only that direct `pPr` field and reveals its inherited level style; clearing a field that was
314
- never direct is a strict no-op. `queryParaProps` reports an independent `{ value, mixed }` state for every property.
418
+ pixels. Its `bullet` field supports explicit none, a Unicode character, every DrawingML auto-number scheme with
419
+ `startAt`, or uploaded PNG/JPEG/GIF/WebP bytes. Character, auto-number, and image bullets can carry an independent
420
+ font, color, and relative or absolute size. `bullet: null` removes the complete direct bullet group and reveals the
421
+ layout/master level value; `{ kind: 'none' }` explicitly blocks that inheritance. `queryParaProps` reports an
422
+ independent `{ value, mixed }` state for every property and retains structured bullet semantics rather than a
423
+ rendered marker string.
315
424
 
316
425
  ```ts
317
426
  import { queryParaProps } from '@web-ppt/edit-core';
318
427
 
319
428
  editor.exec({
320
429
  type: 'SetParaProps', id: elementId, range,
321
- props: { align: 'center', lineHeight: 1.5, spaceAfter: 8, indent: -12 },
430
+ props: {
431
+ align: 'center', lineHeight: 1.5, spaceAfter: 8, indent: -12,
432
+ bullet: { kind: 'autoNum', type: 'romanLcPeriod', startAt: 4 },
433
+ },
322
434
  });
323
435
  const paragraphState = queryParaProps(editor.doc, elementId, range);
324
436
  // paragraphState.align: { value: 'center', mixed: false }
437
+ // paragraphState.bullet.value: { kind: 'autoNum', type: 'romanLcPeriod', startAt: 4 }
325
438
  ```
326
439
 
327
440
  `EditText` also accepts `replaceFragment`, a JSON-only rich-text splice for clipboard adapters. A fragment contains
328
441
  paragraph strings and contiguous half-open marks with only the six P0 character properties; DOM nodes, CSS, and
329
- OOXML source identities cannot cross this boundary. Unspecified fields inherit the replaced range's starting
442
+ OOXML source identities cannot cross this boundary. A fully selected paragraph also carries its structured bullet,
443
+ including content-addressed image bytes; partial selections do not. Unspecified fields inherit the replaced range's starting
330
444
  style, blocks create paragraphs, and embedded `\n` values remain hard line breaks. `textFragmentFromRange()`
331
445
  creates the inverse transport shape for copy/cut without exposing preservation metadata.
332
446
 
@@ -344,16 +458,33 @@ editor.exec({
344
458
  `Editor.exec({ type: 'PasteElements', payload, at: { parentId, x, y } })`; the command allocates fresh session
345
459
  and OOXML identities, preserves nested groups in slide coordinates, and enters history as one atomic unit.
346
460
  Images are embedded as base64 plus SHA-256 and deduplicated against the destination package. Hyperlinks receive
347
- new relationships. Complex objects such as SmartArt can reuse a verified same-package OPC closure; a different
348
- package is rejected before any model identity is allocated instead of receiving a degraded preview.
349
-
350
- `InsertRow` intentionally exposes append-only table semantics for now, shared by last-cell Tab and an
351
- “add row at end” control. It does not accept an `at` value that would be unsafe across vertical merges. The new row
352
- keeps the former last row's height, direct/input formatting, and horizontal merge topology, clears its content,
353
- and recomputes `bandRow`, `lastRow`, and frame height. History stores one sparse stable-row patch, not a table copy.
461
+ new relationships. Complex objects such as SmartArt require an identical, verified OPC resource closure in the destination.
462
+ Classic charts compare the effective data and design at copy and paste time, including unsaved edits; obsolete resources are
463
+ rejected atomically. With `chart-shared` loaded, pasted frames immediately participate in shared queries, rendering, and editing.
464
+ Use `generate.copyPortableElements` after releasing the source package.
465
+
466
+ `queryTableGrid(doc, tableElementId)` exposes stable row/column identities, logical cell addresses, and merge
467
+ regions. Structural commands target those identities, so prepending rows or columns cannot retarget recovery or
468
+ collaboration patches. `InsertRow` / `InsertColumn` accept an identity-based `at` position and append when omitted;
469
+ `RemoveRow` / `RemoveColumn` retain at least one row and column. `MergeCells` stores only its anchor and span while
470
+ covered cell content remains dormant for `SplitCell`. `SetRowHeight`, `SetColumnWidth`, and `SetCellProps` update the
471
+ frame atomically, and banded/first/last styles are reprojected from the final order.
354
472
 
355
473
  ```ts
356
- editor.exec({ type: 'InsertRow', id: tableElementId });
474
+ const grid = queryTableGrid(editor.doc, tableElementId);
475
+ editor.exec({ type: 'InsertRow', id: tableElementId, at: { before: grid.rows[1].id } });
476
+ editor.exec({ type: 'InsertColumn', id: tableElementId, at: { before: grid.columns[1].id } });
477
+ const next = queryTableGrid(editor.doc, tableElementId);
478
+ editor.exec({
479
+ type: 'MergeCells', id: tableElementId,
480
+ from: { row: next.rows[0].id, column: next.columns[0].id },
481
+ to: { row: next.rows[0].id, column: next.columns[1].id },
482
+ });
483
+ editor.exec({
484
+ type: 'SetCellProps', id: tableElementId,
485
+ cell: { row: next.rows[0].id, column: next.columns[0].id },
486
+ props: { fill: { type: 'solid', color: '#DBEAFE' }, vAlign: 'middle' },
487
+ });
357
488
  ```
358
489
 
359
490
  `AddShape { slideId, preset, rect }` inserts a top-level DrawingML preset shape into an existing writable
@@ -416,7 +547,7 @@ Its `transform` maps logical coordinates for vertical text; pass `{ includeCaret
416
547
 
417
548
  `Editor.save()` is the normal API: it writes current transforms, layer order, text, character and paragraph formatting,
418
549
  appended table rows, new shapes/pages, page duplication/removals, speaker notes, placeholder clears, and element removals, refreshes `doc.package` for the
419
- next save, and advances the dirty checkpoint only after a successful write. For save diagnostics, use the
550
+ next save, and advances the dirty checkpoint after producing bytes, not after filesystem delivery. For save diagnostics, use the
420
551
  detailed method without changing lifecycle semantics:
421
552
 
422
553
  ```ts
@@ -425,6 +556,18 @@ const result = await editor.saveDetailed();
425
556
  // result.fallbackReason explains why a package had to be rebuilt.
426
557
  ```
427
558
 
559
+ For fallible delivery, use `serializeEditDoc(doc)` from `@web-ppt/edit-core/save`: it selects patch or generated
560
+ save without acknowledging delivery. Call `editor.captureSavepoint()` before serialization and invoke its
561
+ one-shot callback only after delivery succeeds. Discard the callback on failure. Changes during serialization
562
+ must cause the host to reject delivery and retry; changes during a subsequent write remain dirty unless undo/redo
563
+ returns to the captured version. Capture also prevents history merging across that version.
564
+ Release an independently generated `result.package` with `disposeOpcPackage`; do not dispose it when it is `doc.package`.
565
+ The host owns picker permissions, file handles, task serialization and UI refresh after acknowledgement.
566
+
567
+ Recovery v1 remains compatible: an acknowledgement of an older version uses an empty `transaction` frame with
568
+ the current dirty flag; `savepoint` still means the current version is clean. Recovery journals remain tied to
569
+ the original source-file fingerprint, not to a file handle or a subsequently overwritten file's new bytes.
570
+
428
571
  Load the lower-level preserving OOXML tree only when building another writer:
429
572
 
430
573
  ```ts
@@ -461,13 +604,13 @@ result outside an `EditDoc`, call `disposeOpcPackage(saved.package)` when it is
461
604
  Untouched declarations, comments, processing instructions, prefixes, attribute order, self-closing form,
462
605
  and `AlternateContent` remain lexical matches. `insertXmlInOrder` enforces OOXML sequence ordering, while
463
606
  `reorderXmlChildren` replaces only existing target slots. UTF-8 and UTF-16 byte order/BOM are retained.
464
- Measured Vite output, including each entry's static shared chunks, is 62.33 KB gzip for the editing entry,
465
- 8.07 KB for `xml`, and 4.38 KB for `opc`; calling save after the main entry adds 8.30 KB on demand. Clean local
607
+ The measured editing entry file is 80.57 KB gzip, excluding static shared chunks and peer dependencies.
608
+ The save implementation loads on demand. Clean local
466
609
  headers, extra fields, and compressed streams are copied byte-for-byte. ZIP64, descriptors, archive comments,
467
610
  and encrypted entries return an explicit reason and deterministically repack. Every entry is DOM-free.
468
611
 
469
612
  `doc.meta.readonly` is `true` when a `.pptx` was not parsed with the package and write-back metadata.
470
- Legacy `.ppt` documents remain editable through the future generated-save path; binary `.ppt` write-back is intentionally unsupported.
613
+ Legacy `.ppt` can be saved as `.pptx` or exported through `@web-ppt/edit-core/ppt` as an editable native PPT within its supported format matrix. `generate.copyPortableElements` supports copying objects without OOXML sources.
471
614
  For collaborative ordering, pass the new element's stable ULID as the third argument to
472
615
  `fractionalIndexBetween(lower, upper, ulid)`; single-user callers can omit it.
473
616
 
@@ -0,0 +1,5 @@
1
+ import type { EditDoc, ElementAltTextState, ElementId } from './types';
2
+ export declare const MAX_ALT_TEXT_LENGTH = 32767;
3
+ export declare function assertAltTextField(value: unknown, label: string): asserts value is string;
4
+ /** 替代文字与对象名称是两套 cNvPr 属性;查询不能用名称兜底。 */
5
+ export declare function queryElementAltText(doc: EditDoc, id: ElementId): ElementAltTextState;
@@ -0,0 +1,12 @@
1
+ import type { Shape3D } from '@web-ppt/core';
2
+ import type { Editor } from '../editor';
3
+ import type { EditDoc, ElementId } from '../types';
4
+ import type { AppearanceCommand, PictureFx } from './types';
5
+ export type { AppearanceCommand, SetPictureFxCommand, SetScene3DCommand, PictureFx } from './types';
6
+ export { SCENE_MATERIALS } from './values';
7
+ export declare function registerAppearanceEditing(): void;
8
+ export declare function createAppearanceEditor(editor: Pick<Editor, 'doc' | 'exec'>): {
9
+ exec(command: AppearanceCommand): import("@web-ppt/edit-core").TransactionResult;
10
+ };
11
+ export declare function queryPictureFx(doc: EditDoc, id: ElementId): PictureFx;
12
+ export declare function queryScene3D(doc: EditDoc, id: ElementId): Shape3D;
@@ -0,0 +1,4 @@
1
+ import type { EditElementXml } from '../save/extension-elements';
2
+ import type { XmlDocument } from '../xml/types';
3
+ import type { ElementRecord } from '../types';
4
+ export declare function materializeAppearance(tree: XmlDocument, record: ElementRecord, generated: boolean, xml: EditElementXml): void;
@@ -0,0 +1,26 @@
1
+ import type { Shape3D } from '@web-ppt/core';
2
+ import type { ElementId } from '../types';
3
+ export interface PictureFx {
4
+ /** 不透明度,0–1;省略为 1。 */
5
+ readonly alpha?: number;
6
+ readonly grayscale?: boolean;
7
+ /** 暗部、亮部颜色;使用不透明的 #RRGGBB 或 rgb()。 */
8
+ readonly duotone?: readonly [string, string];
9
+ }
10
+ export interface SetPictureFxCommand {
11
+ readonly type: 'SetPictureFx';
12
+ readonly id: ElementId;
13
+ /** null 恢复来源,{} 显式清除这三种效果。 */
14
+ readonly effects: PictureFx | null;
15
+ }
16
+ export interface SetScene3DCommand {
17
+ readonly type: 'SetScene3D';
18
+ readonly id: ElementId;
19
+ /** 挤出与斜角单位为 px,旋转为度;null 恢复来源,{} 清除立体效果。 */
20
+ readonly scene: Shape3D | null;
21
+ }
22
+ export type AppearanceCommand = SetPictureFxCommand | SetScene3DCommand;
23
+ export interface AppearanceState {
24
+ picture?: string;
25
+ scene?: string;
26
+ }
@@ -0,0 +1,9 @@
1
+ import type { ImageElement, Shape3D } from '@web-ppt/core';
2
+ import type { PictureFx } from './types';
3
+ export declare const SCENE_MATERIALS: readonly ["legacyMatte", "legacyPlastic", "legacyMetal", "legacyWireframe", "matte", "plastic", "metal", "warmMatte", "translucentPowder", "powder", "dkEdge", "softEdge", "clear", "flat", "softmetal"];
4
+ export declare function normalizePicture(value: unknown): PictureFx;
5
+ export declare function normalizeScene(value: unknown): Shape3D;
6
+ export declare function sceneProjection(scene: Shape3D): Shape3D | undefined;
7
+ export declare function sourceScene(scene: Shape3D | undefined): Shape3D;
8
+ export declare function pictureProjection(element: ImageElement, effects: PictureFx): ImageElement;
9
+ export declare function sourcePicture(element: ImageElement): PictureFx;