@ryanyahya/opendoc 0.4.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 (789) hide show
  1. package/.agents/skills/opendoc-apply-comments/SKILL.md +30 -0
  2. package/.agents/skills/opendoc-apply-comments/agents/openai.yaml +4 -0
  3. package/.agents/skills/opendoc-create/SKILL.md +63 -0
  4. package/.agents/skills/opendoc-create/agents/openai.yaml +6 -0
  5. package/.agents/skills/opendoc-create-template/SKILL.md +50 -0
  6. package/.agents/skills/opendoc-create-template/agents/openai.yaml +4 -0
  7. package/.agents/skills/opendoc-create-template/references/structured-reports.md +11 -0
  8. package/.agents/skills/opendoc-create-theme/SKILL.md +40 -0
  9. package/.agents/skills/opendoc-create-theme/agents/openai.yaml +4 -0
  10. package/.agents/skills/opendoc-current-document/SKILL.md +32 -0
  11. package/.agents/skills/opendoc-current-document/agents/openai.yaml +4 -0
  12. package/.agents/skills/opendoc-current-document/references/context-fields.md +20 -0
  13. package/.agents/skills/opendoc-review-document/SKILL.md +60 -0
  14. package/.agents/skills/opendoc-review-document/agents/openai.yaml +4 -0
  15. package/AGENTS.md +69 -0
  16. package/CONTRIBUTING.md +38 -0
  17. package/LICENSE +21 -0
  18. package/README.md +179 -0
  19. package/SECURITY.md +9 -0
  20. package/THIRD_PARTY.md +49 -0
  21. package/VALIDATION.md +99 -0
  22. package/bin/opendoc.mjs +6 -0
  23. package/dist/assets/Markdown-sNZyjJi7.js +29 -0
  24. package/dist/assets/OpenDocSerif-Regular-D3OXs9A9.ttf +0 -0
  25. package/dist/assets/OpenDocSerif-Semibold-CjL9oDRo.ttf +0 -0
  26. package/dist/assets/geist-latin-ext-wght-italic-XgKbg5n7.woff2 +0 -0
  27. package/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  28. package/dist/assets/geist-latin-wght-italic-dTnRTFFJ.woff2 +0 -0
  29. package/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  30. package/dist/assets/index-DdrZ6ozO.css +1 -0
  31. package/dist/assets/index-DgNBz7mL.js +39 -0
  32. package/dist/assets/pdf-B7Emtyld.js +54 -0
  33. package/dist/assets/pdf.worker.min-Dswkl-cV.mjs +29 -0
  34. package/dist/assets/wordmark-DsqLlZpb.png +0 -0
  35. package/dist/index.html +17 -0
  36. package/docs/APPEARANCE.md +21 -0
  37. package/docs/ASSETS.md +176 -0
  38. package/docs/AUTHORING.md +178 -0
  39. package/docs/HEADLESS.md +120 -0
  40. package/docs/MEDIA.md +112 -0
  41. package/docs/PROJECTS.md +55 -0
  42. package/docs/PROSE.md +15 -0
  43. package/docs/SELECTION.md +59 -0
  44. package/docs/TEMPLATES.md +55 -0
  45. package/docs/THEMES.md +106 -0
  46. package/node_modules/@formepdf/core/LICENSE +21 -0
  47. package/node_modules/@formepdf/core/README.md +53 -0
  48. package/node_modules/@formepdf/core/dist/attachments.d.ts +55 -0
  49. package/node_modules/@formepdf/core/dist/attachments.js +59 -0
  50. package/node_modules/@formepdf/core/dist/extract.d.ts +8 -0
  51. package/node_modules/@formepdf/core/dist/extract.js +56 -0
  52. package/node_modules/@formepdf/core/dist/index.d.ts +311 -0
  53. package/node_modules/@formepdf/core/dist/index.js +167 -0
  54. package/node_modules/@formepdf/core/dist/layout.d.ts +132 -0
  55. package/node_modules/@formepdf/core/dist/layout.js +240 -0
  56. package/node_modules/@formepdf/core/dist/shared/browserHelpers.d.ts +19 -0
  57. package/node_modules/@formepdf/core/dist/shared/browserHelpers.js +128 -0
  58. package/node_modules/@formepdf/core/package.json +35 -0
  59. package/node_modules/@formepdf/core/pkg-node/LICENSE +21 -0
  60. package/node_modules/@formepdf/core/pkg-node/README.md +84 -0
  61. package/node_modules/@formepdf/core/pkg-node/forme.d.ts +39 -0
  62. package/node_modules/@formepdf/core/pkg-node/forme.js +394 -0
  63. package/node_modules/@formepdf/core/pkg-node/forme_bg.wasm +0 -0
  64. package/node_modules/@formepdf/core/pkg-node/forme_bg.wasm.d.ts +21 -0
  65. package/node_modules/@formepdf/core/pkg-node/package.json +25 -0
  66. package/node_modules/@formepdf/react/README.md +70 -0
  67. package/node_modules/@formepdf/react/dist/charts.d.ts +72 -0
  68. package/node_modules/@formepdf/react/dist/charts.js +338 -0
  69. package/node_modules/@formepdf/react/dist/components.d.ts +533 -0
  70. package/node_modules/@formepdf/react/dist/components.js +608 -0
  71. package/node_modules/@formepdf/react/dist/expr.d.ts +20 -0
  72. package/node_modules/@formepdf/react/dist/expr.js +39 -0
  73. package/node_modules/@formepdf/react/dist/font.d.ts +2 -0
  74. package/node_modules/@formepdf/react/dist/font.js +1 -0
  75. package/node_modules/@formepdf/react/dist/index.d.ts +11 -0
  76. package/node_modules/@formepdf/react/dist/index.js +15 -0
  77. package/node_modules/@formepdf/react/dist/render.d.ts +12 -0
  78. package/node_modules/@formepdf/react/dist/render.js +15 -0
  79. package/node_modules/@formepdf/react/dist/serialize.d.ts +12 -0
  80. package/node_modules/@formepdf/react/dist/serialize.js +1470 -0
  81. package/node_modules/@formepdf/react/dist/stylesheet.d.ts +4 -0
  82. package/node_modules/@formepdf/react/dist/stylesheet.js +5 -0
  83. package/node_modules/@formepdf/react/dist/template-proxy.d.ts +38 -0
  84. package/node_modules/@formepdf/react/dist/template-proxy.js +100 -0
  85. package/node_modules/@formepdf/react/dist/types.d.ts +287 -0
  86. package/node_modules/@formepdf/react/dist/types.js +1 -0
  87. package/node_modules/@formepdf/react/package.json +41 -0
  88. package/node_modules/@formepdf/shared/README.md +7 -0
  89. package/node_modules/@formepdf/shared/dist/canvas.d.ts +6 -0
  90. package/node_modules/@formepdf/shared/dist/canvas.js +43 -0
  91. package/node_modules/@formepdf/shared/dist/charts.d.ts +100 -0
  92. package/node_modules/@formepdf/shared/dist/charts.js +98 -0
  93. package/node_modules/@formepdf/shared/dist/encode.d.ts +27 -0
  94. package/node_modules/@formepdf/shared/dist/encode.js +93 -0
  95. package/node_modules/@formepdf/shared/dist/font.d.ts +13 -0
  96. package/node_modules/@formepdf/shared/dist/font.js +52 -0
  97. package/node_modules/@formepdf/shared/dist/index.d.ts +10 -0
  98. package/node_modules/@formepdf/shared/dist/index.js +15 -0
  99. package/node_modules/@formepdf/shared/dist/parser.d.ts +30 -0
  100. package/node_modules/@formepdf/shared/dist/parser.js +756 -0
  101. package/node_modules/@formepdf/shared/dist/semantics.d.ts +15 -0
  102. package/node_modules/@formepdf/shared/dist/semantics.js +44 -0
  103. package/node_modules/@formepdf/shared/dist/style.d.ts +7 -0
  104. package/node_modules/@formepdf/shared/dist/style.js +1024 -0
  105. package/node_modules/@formepdf/shared/dist/types.d.ts +743 -0
  106. package/node_modules/@formepdf/shared/dist/types.js +2 -0
  107. package/node_modules/@formepdf/shared/package.json +35 -0
  108. package/node_modules/@types/node/LICENSE +21 -0
  109. package/node_modules/@types/node/README.md +15 -0
  110. package/node_modules/@types/node/assert/strict.d.ts +111 -0
  111. package/node_modules/@types/node/assert.d.ts +1078 -0
  112. package/node_modules/@types/node/async_hooks.d.ts +603 -0
  113. package/node_modules/@types/node/buffer.buffer.d.ts +472 -0
  114. package/node_modules/@types/node/buffer.d.ts +1934 -0
  115. package/node_modules/@types/node/child_process.d.ts +1476 -0
  116. package/node_modules/@types/node/cluster.d.ts +578 -0
  117. package/node_modules/@types/node/compatibility/disposable.d.ts +14 -0
  118. package/node_modules/@types/node/compatibility/index.d.ts +9 -0
  119. package/node_modules/@types/node/compatibility/indexable.d.ts +20 -0
  120. package/node_modules/@types/node/compatibility/iterators.d.ts +20 -0
  121. package/node_modules/@types/node/console.d.ts +452 -0
  122. package/node_modules/@types/node/constants.d.ts +21 -0
  123. package/node_modules/@types/node/crypto.d.ts +4545 -0
  124. package/node_modules/@types/node/dgram.d.ts +600 -0
  125. package/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
  126. package/node_modules/@types/node/dns/promises.d.ts +503 -0
  127. package/node_modules/@types/node/dns.d.ts +923 -0
  128. package/node_modules/@types/node/domain.d.ts +170 -0
  129. package/node_modules/@types/node/events.d.ts +976 -0
  130. package/node_modules/@types/node/fs/promises.d.ts +1306 -0
  131. package/node_modules/@types/node/fs.d.ts +4463 -0
  132. package/node_modules/@types/node/globals.d.ts +172 -0
  133. package/node_modules/@types/node/globals.typedarray.d.ts +38 -0
  134. package/node_modules/@types/node/http.d.ts +2097 -0
  135. package/node_modules/@types/node/http2.d.ts +2843 -0
  136. package/node_modules/@types/node/https.d.ts +579 -0
  137. package/node_modules/@types/node/index.d.ts +98 -0
  138. package/node_modules/@types/node/inspector.d.ts +253 -0
  139. package/node_modules/@types/node/inspector.generated.d.ts +4052 -0
  140. package/node_modules/@types/node/module.d.ts +891 -0
  141. package/node_modules/@types/node/net.d.ts +1076 -0
  142. package/node_modules/@types/node/os.d.ts +506 -0
  143. package/node_modules/@types/node/package.json +145 -0
  144. package/node_modules/@types/node/path.d.ts +200 -0
  145. package/node_modules/@types/node/perf_hooks.d.ts +968 -0
  146. package/node_modules/@types/node/process.d.ts +2084 -0
  147. package/node_modules/@types/node/punycode.d.ts +117 -0
  148. package/node_modules/@types/node/querystring.d.ts +152 -0
  149. package/node_modules/@types/node/readline/promises.d.ts +161 -0
  150. package/node_modules/@types/node/readline.d.ts +594 -0
  151. package/node_modules/@types/node/repl.d.ts +428 -0
  152. package/node_modules/@types/node/sea.d.ts +162 -0
  153. package/node_modules/@types/node/sqlite.d.ts +722 -0
  154. package/node_modules/@types/node/stream/consumers.d.ts +38 -0
  155. package/node_modules/@types/node/stream/promises.d.ts +90 -0
  156. package/node_modules/@types/node/stream/web.d.ts +573 -0
  157. package/node_modules/@types/node/stream.d.ts +1694 -0
  158. package/node_modules/@types/node/string_decoder.d.ts +67 -0
  159. package/node_modules/@types/node/test.d.ts +2265 -0
  160. package/node_modules/@types/node/timers/promises.d.ts +108 -0
  161. package/node_modules/@types/node/timers.d.ts +287 -0
  162. package/node_modules/@types/node/tls.d.ts +1319 -0
  163. package/node_modules/@types/node/trace_events.d.ts +197 -0
  164. package/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +468 -0
  165. package/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +34 -0
  166. package/node_modules/@types/node/ts5.6/index.d.ts +98 -0
  167. package/node_modules/@types/node/tty.d.ts +208 -0
  168. package/node_modules/@types/node/url.d.ts +984 -0
  169. package/node_modules/@types/node/util.d.ts +2606 -0
  170. package/node_modules/@types/node/v8.d.ts +920 -0
  171. package/node_modules/@types/node/vm.d.ts +1053 -0
  172. package/node_modules/@types/node/wasi.d.ts +181 -0
  173. package/node_modules/@types/node/web-globals/abortcontroller.d.ts +34 -0
  174. package/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
  175. package/node_modules/@types/node/web-globals/events.d.ts +97 -0
  176. package/node_modules/@types/node/web-globals/fetch.d.ts +55 -0
  177. package/node_modules/@types/node/web-globals/navigator.d.ts +22 -0
  178. package/node_modules/@types/node/web-globals/storage.d.ts +24 -0
  179. package/node_modules/@types/node/web-globals/streams.d.ts +22 -0
  180. package/node_modules/@types/node/worker_threads.d.ts +819 -0
  181. package/node_modules/@types/node/zlib.d.ts +747 -0
  182. package/node_modules/@types/react/LICENSE +21 -0
  183. package/node_modules/@types/react/README.md +15 -0
  184. package/node_modules/@types/react/canary.d.ts +129 -0
  185. package/node_modules/@types/react/compiler-runtime.d.ts +4 -0
  186. package/node_modules/@types/react/experimental.d.ts +184 -0
  187. package/node_modules/@types/react/global.d.ts +166 -0
  188. package/node_modules/@types/react/index.d.ts +4378 -0
  189. package/node_modules/@types/react/jsx-dev-runtime.d.ts +33 -0
  190. package/node_modules/@types/react/jsx-runtime.d.ts +24 -0
  191. package/node_modules/@types/react/package.json +210 -0
  192. package/node_modules/@types/react/ts5.0/canary.d.ts +129 -0
  193. package/node_modules/@types/react/ts5.0/experimental.d.ts +184 -0
  194. package/node_modules/@types/react/ts5.0/global.d.ts +166 -0
  195. package/node_modules/@types/react/ts5.0/index.d.ts +4365 -0
  196. package/node_modules/@types/react/ts5.0/jsx-dev-runtime.d.ts +33 -0
  197. package/node_modules/@types/react/ts5.0/jsx-runtime.d.ts +24 -0
  198. package/node_modules/csstype/LICENSE +19 -0
  199. package/node_modules/csstype/README.md +291 -0
  200. package/node_modules/csstype/index.d.ts +22569 -0
  201. package/node_modules/csstype/index.js.flow +6863 -0
  202. package/node_modules/csstype/package.json +70 -0
  203. package/node_modules/entities/LICENSE +11 -0
  204. package/node_modules/entities/decode.d.ts +1 -0
  205. package/node_modules/entities/decode.js +3 -0
  206. package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts +19 -0
  207. package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts.map +1 -0
  208. package/node_modules/entities/dist/commonjs/decode-codepoint.js +77 -0
  209. package/node_modules/entities/dist/commonjs/decode-codepoint.js.map +1 -0
  210. package/node_modules/entities/dist/commonjs/decode.d.ts +209 -0
  211. package/node_modules/entities/dist/commonjs/decode.d.ts.map +1 -0
  212. package/node_modules/entities/dist/commonjs/decode.js +511 -0
  213. package/node_modules/entities/dist/commonjs/decode.js.map +1 -0
  214. package/node_modules/entities/dist/commonjs/encode.d.ts +22 -0
  215. package/node_modules/entities/dist/commonjs/encode.d.ts.map +1 -0
  216. package/node_modules/entities/dist/commonjs/encode.js +73 -0
  217. package/node_modules/entities/dist/commonjs/encode.js.map +1 -0
  218. package/node_modules/entities/dist/commonjs/escape.d.ts +43 -0
  219. package/node_modules/entities/dist/commonjs/escape.d.ts.map +1 -0
  220. package/node_modules/entities/dist/commonjs/escape.js +121 -0
  221. package/node_modules/entities/dist/commonjs/escape.js.map +1 -0
  222. package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts +2 -0
  223. package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts.map +1 -0
  224. package/node_modules/entities/dist/commonjs/generated/decode-data-html.js +10 -0
  225. package/node_modules/entities/dist/commonjs/generated/decode-data-html.js.map +1 -0
  226. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts +2 -0
  227. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts.map +1 -0
  228. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js +10 -0
  229. package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js.map +1 -0
  230. package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts +8 -0
  231. package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts.map +1 -0
  232. package/node_modules/entities/dist/commonjs/generated/encode-html.js +13 -0
  233. package/node_modules/entities/dist/commonjs/generated/encode-html.js.map +1 -0
  234. package/node_modules/entities/dist/commonjs/index.d.ts +96 -0
  235. package/node_modules/entities/dist/commonjs/index.d.ts.map +1 -0
  236. package/node_modules/entities/dist/commonjs/index.js +131 -0
  237. package/node_modules/entities/dist/commonjs/index.js.map +1 -0
  238. package/node_modules/entities/dist/commonjs/package.json +3 -0
  239. package/node_modules/entities/dist/esm/decode-codepoint.d.ts +19 -0
  240. package/node_modules/entities/dist/esm/decode-codepoint.d.ts.map +1 -0
  241. package/node_modules/entities/dist/esm/decode-codepoint.js +72 -0
  242. package/node_modules/entities/dist/esm/decode-codepoint.js.map +1 -0
  243. package/node_modules/entities/dist/esm/decode.d.ts +209 -0
  244. package/node_modules/entities/dist/esm/decode.d.ts.map +1 -0
  245. package/node_modules/entities/dist/esm/decode.js +497 -0
  246. package/node_modules/entities/dist/esm/decode.js.map +1 -0
  247. package/node_modules/entities/dist/esm/encode.d.ts +22 -0
  248. package/node_modules/entities/dist/esm/encode.d.ts.map +1 -0
  249. package/node_modules/entities/dist/esm/encode.js +69 -0
  250. package/node_modules/entities/dist/esm/encode.js.map +1 -0
  251. package/node_modules/entities/dist/esm/escape.d.ts +43 -0
  252. package/node_modules/entities/dist/esm/escape.d.ts.map +1 -0
  253. package/node_modules/entities/dist/esm/escape.js +117 -0
  254. package/node_modules/entities/dist/esm/escape.js.map +1 -0
  255. package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts +2 -0
  256. package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts.map +1 -0
  257. package/node_modules/entities/dist/esm/generated/decode-data-html.js +7 -0
  258. package/node_modules/entities/dist/esm/generated/decode-data-html.js.map +1 -0
  259. package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts +2 -0
  260. package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts.map +1 -0
  261. package/node_modules/entities/dist/esm/generated/decode-data-xml.js +7 -0
  262. package/node_modules/entities/dist/esm/generated/decode-data-xml.js.map +1 -0
  263. package/node_modules/entities/dist/esm/generated/encode-html.d.ts +8 -0
  264. package/node_modules/entities/dist/esm/generated/encode-html.d.ts.map +1 -0
  265. package/node_modules/entities/dist/esm/generated/encode-html.js +10 -0
  266. package/node_modules/entities/dist/esm/generated/encode-html.js.map +1 -0
  267. package/node_modules/entities/dist/esm/index.d.ts +96 -0
  268. package/node_modules/entities/dist/esm/index.d.ts.map +1 -0
  269. package/node_modules/entities/dist/esm/index.js +107 -0
  270. package/node_modules/entities/dist/esm/index.js.map +1 -0
  271. package/node_modules/entities/dist/esm/package.json +3 -0
  272. package/node_modules/entities/escape.d.ts +1 -0
  273. package/node_modules/entities/escape.js +3 -0
  274. package/node_modules/entities/package.json +118 -0
  275. package/node_modules/entities/readme.md +122 -0
  276. package/node_modules/entities/src/decode-codepoint.ts +81 -0
  277. package/node_modules/entities/src/decode.spec.ts +320 -0
  278. package/node_modules/entities/src/decode.ts +620 -0
  279. package/node_modules/entities/src/encode.spec.ts +78 -0
  280. package/node_modules/entities/src/encode.ts +77 -0
  281. package/node_modules/entities/src/escape.spec.ts +14 -0
  282. package/node_modules/entities/src/escape.ts +148 -0
  283. package/node_modules/entities/src/generated/.eslintrc.json +10 -0
  284. package/node_modules/entities/src/generated/decode-data-html.ts +8 -0
  285. package/node_modules/entities/src/generated/decode-data-xml.ts +8 -0
  286. package/node_modules/entities/src/generated/encode-html.ts +17 -0
  287. package/node_modules/entities/src/index.spec.ts +125 -0
  288. package/node_modules/entities/src/index.ts +188 -0
  289. package/node_modules/parse5/LICENSE +19 -0
  290. package/node_modules/parse5/README.md +38 -0
  291. package/node_modules/parse5/dist/cjs/common/doctype.d.ts +4 -0
  292. package/node_modules/parse5/dist/cjs/common/doctype.js +118 -0
  293. package/node_modules/parse5/dist/cjs/common/error-codes.d.ts +67 -0
  294. package/node_modules/parse5/dist/cjs/common/error-codes.js +66 -0
  295. package/node_modules/parse5/dist/cjs/common/foreign-content.d.ts +9 -0
  296. package/node_modules/parse5/dist/cjs/common/foreign-content.js +237 -0
  297. package/node_modules/parse5/dist/cjs/common/html.d.ts +289 -0
  298. package/node_modules/parse5/dist/cjs/common/html.js +528 -0
  299. package/node_modules/parse5/dist/cjs/common/token.d.ts +84 -0
  300. package/node_modules/parse5/dist/cjs/common/token.js +24 -0
  301. package/node_modules/parse5/dist/cjs/common/unicode.d.ts +42 -0
  302. package/node_modules/parse5/dist/cjs/common/unicode.js +70 -0
  303. package/node_modules/parse5/dist/cjs/index.d.ts +71 -0
  304. package/node_modules/parse5/dist/cjs/index.js +54 -0
  305. package/node_modules/parse5/dist/cjs/package.json +1 -0
  306. package/node_modules/parse5/dist/cjs/parser/formatting-element-list.d.ts +36 -0
  307. package/node_modules/parse5/dist/cjs/parser/formatting-element-list.js +114 -0
  308. package/node_modules/parse5/dist/cjs/parser/index.d.ts +221 -0
  309. package/node_modules/parse5/dist/cjs/parser/index.js +3240 -0
  310. package/node_modules/parse5/dist/cjs/parser/open-element-stack.d.ts +53 -0
  311. package/node_modules/parse5/dist/cjs/parser/open-element-stack.js +328 -0
  312. package/node_modules/parse5/dist/cjs/serializer/index.d.ts +60 -0
  313. package/node_modules/parse5/dist/cjs/serializer/index.js +172 -0
  314. package/node_modules/parse5/dist/cjs/tokenizer/index.d.ts +247 -0
  315. package/node_modules/parse5/dist/cjs/tokenizer/index.js +2714 -0
  316. package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.d.ts +36 -0
  317. package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.js +200 -0
  318. package/node_modules/parse5/dist/cjs/tree-adapters/default.d.ts +84 -0
  319. package/node_modules/parse5/dist/cjs/tree-adapters/default.js +176 -0
  320. package/node_modules/parse5/dist/cjs/tree-adapters/interface.d.ts +255 -0
  321. package/node_modules/parse5/dist/cjs/tree-adapters/interface.js +2 -0
  322. package/node_modules/parse5/dist/common/doctype.d.ts +4 -0
  323. package/node_modules/parse5/dist/common/doctype.js +114 -0
  324. package/node_modules/parse5/dist/common/error-codes.d.ts +67 -0
  325. package/node_modules/parse5/dist/common/error-codes.js +63 -0
  326. package/node_modules/parse5/dist/common/foreign-content.d.ts +9 -0
  327. package/node_modules/parse5/dist/common/foreign-content.js +228 -0
  328. package/node_modules/parse5/dist/common/html.d.ts +289 -0
  329. package/node_modules/parse5/dist/common/html.js +523 -0
  330. package/node_modules/parse5/dist/common/token.d.ts +84 -0
  331. package/node_modules/parse5/dist/common/token.js +20 -0
  332. package/node_modules/parse5/dist/common/unicode.d.ts +42 -0
  333. package/node_modules/parse5/dist/common/unicode.js +62 -0
  334. package/node_modules/parse5/dist/index.d.ts +71 -0
  335. package/node_modules/parse5/dist/index.js +42 -0
  336. package/node_modules/parse5/dist/parser/formatting-element-list.d.ts +36 -0
  337. package/node_modules/parse5/dist/parser/formatting-element-list.js +110 -0
  338. package/node_modules/parse5/dist/parser/index.d.ts +221 -0
  339. package/node_modules/parse5/dist/parser/index.js +3245 -0
  340. package/node_modules/parse5/dist/parser/open-element-stack.d.ts +53 -0
  341. package/node_modules/parse5/dist/parser/open-element-stack.js +324 -0
  342. package/node_modules/parse5/dist/serializer/index.d.ts +60 -0
  343. package/node_modules/parse5/dist/serializer/index.js +168 -0
  344. package/node_modules/parse5/dist/tokenizer/index.d.ts +247 -0
  345. package/node_modules/parse5/dist/tokenizer/index.js +2710 -0
  346. package/node_modules/parse5/dist/tokenizer/preprocessor.d.ts +36 -0
  347. package/node_modules/parse5/dist/tokenizer/preprocessor.js +196 -0
  348. package/node_modules/parse5/dist/tree-adapters/default.d.ts +84 -0
  349. package/node_modules/parse5/dist/tree-adapters/default.js +173 -0
  350. package/node_modules/parse5/dist/tree-adapters/interface.d.ts +255 -0
  351. package/node_modules/parse5/dist/tree-adapters/interface.js +1 -0
  352. package/node_modules/parse5/package.json +50 -0
  353. package/node_modules/undici-types/LICENSE +21 -0
  354. package/node_modules/undici-types/README.md +6 -0
  355. package/node_modules/undici-types/agent.d.ts +31 -0
  356. package/node_modules/undici-types/api.d.ts +43 -0
  357. package/node_modules/undici-types/balanced-pool.d.ts +29 -0
  358. package/node_modules/undici-types/cache.d.ts +36 -0
  359. package/node_modules/undici-types/client.d.ts +108 -0
  360. package/node_modules/undici-types/connector.d.ts +34 -0
  361. package/node_modules/undici-types/content-type.d.ts +21 -0
  362. package/node_modules/undici-types/cookies.d.ts +28 -0
  363. package/node_modules/undici-types/diagnostics-channel.d.ts +66 -0
  364. package/node_modules/undici-types/dispatcher.d.ts +256 -0
  365. package/node_modules/undici-types/env-http-proxy-agent.d.ts +21 -0
  366. package/node_modules/undici-types/errors.d.ts +149 -0
  367. package/node_modules/undici-types/eventsource.d.ts +61 -0
  368. package/node_modules/undici-types/fetch.d.ts +209 -0
  369. package/node_modules/undici-types/file.d.ts +39 -0
  370. package/node_modules/undici-types/filereader.d.ts +54 -0
  371. package/node_modules/undici-types/formdata.d.ts +108 -0
  372. package/node_modules/undici-types/global-dispatcher.d.ts +9 -0
  373. package/node_modules/undici-types/global-origin.d.ts +7 -0
  374. package/node_modules/undici-types/handlers.d.ts +15 -0
  375. package/node_modules/undici-types/header.d.ts +4 -0
  376. package/node_modules/undici-types/index.d.ts +71 -0
  377. package/node_modules/undici-types/interceptors.d.ts +17 -0
  378. package/node_modules/undici-types/mock-agent.d.ts +50 -0
  379. package/node_modules/undici-types/mock-client.d.ts +25 -0
  380. package/node_modules/undici-types/mock-errors.d.ts +12 -0
  381. package/node_modules/undici-types/mock-interceptor.d.ts +93 -0
  382. package/node_modules/undici-types/mock-pool.d.ts +25 -0
  383. package/node_modules/undici-types/package.json +55 -0
  384. package/node_modules/undici-types/patch.d.ts +33 -0
  385. package/node_modules/undici-types/pool-stats.d.ts +19 -0
  386. package/node_modules/undici-types/pool.d.ts +39 -0
  387. package/node_modules/undici-types/proxy-agent.d.ts +28 -0
  388. package/node_modules/undici-types/readable.d.ts +65 -0
  389. package/node_modules/undici-types/retry-agent.d.ts +8 -0
  390. package/node_modules/undici-types/retry-handler.d.ts +116 -0
  391. package/node_modules/undici-types/util.d.ts +18 -0
  392. package/node_modules/undici-types/webidl.d.ts +228 -0
  393. package/node_modules/undici-types/websocket.d.ts +150 -0
  394. package/package.json +80 -0
  395. package/scripts/rebuild-forme.mjs +61 -0
  396. package/src/app/AppearanceControl.tsx +44 -0
  397. package/src/app/AssetThemeDefaults.tsx +87 -0
  398. package/src/app/AssetsBrowser.tsx +273 -0
  399. package/src/app/CommentDock.tsx +108 -0
  400. package/src/app/CreateDocumentDialog.tsx +51 -0
  401. package/src/app/DocumentActions.tsx +69 -0
  402. package/src/app/DocumentCard.tsx +50 -0
  403. package/src/app/DocumentViewControl.tsx +31 -0
  404. package/src/app/DocumentsBrowser.tsx +70 -0
  405. package/src/app/ExportHistoryDialog.tsx +86 -0
  406. package/src/app/ExportMenu.tsx +127 -0
  407. package/src/app/GuideDialog.tsx +80 -0
  408. package/src/app/InspectionLayer.tsx +77 -0
  409. package/src/app/LogoUploadDialog.tsx +92 -0
  410. package/src/app/Markdown.tsx +34 -0
  411. package/src/app/MaterialsBrowser.tsx +149 -0
  412. package/src/app/PageNumberInput.tsx +56 -0
  413. package/src/app/Pdf.tsx +561 -0
  414. package/src/app/ProjectDialogs.tsx +100 -0
  415. package/src/app/Reader.tsx +769 -0
  416. package/src/app/SearchField.tsx +13 -0
  417. package/src/app/Sidebar.tsx +86 -0
  418. package/src/app/SkillIndex.tsx +30 -0
  419. package/src/app/TemplatesBrowser.tsx +149 -0
  420. package/src/app/ThemesBrowser.tsx +159 -0
  421. package/src/app/api.ts +47 -0
  422. package/src/app/appearance.ts +35 -0
  423. package/src/app/assets.css +139 -0
  424. package/src/app/catalogPreview.ts +20 -0
  425. package/src/app/colors.css +167 -0
  426. package/src/app/comment-dock.css +53 -0
  427. package/src/app/commentDrafts.ts +67 -0
  428. package/src/app/componentCorrection.ts +17 -0
  429. package/src/app/edit-workbench.css +87 -0
  430. package/src/app/editSession.ts +238 -0
  431. package/src/app/editorRecovery.ts +25 -0
  432. package/src/app/export-history.css +31 -0
  433. package/src/app/export.css +17 -0
  434. package/src/app/guideLinks.ts +21 -0
  435. package/src/app/guides.css +40 -0
  436. package/src/app/main.tsx +221 -0
  437. package/src/app/materials.css +53 -0
  438. package/src/app/pdfLoading.ts +12 -0
  439. package/src/app/pdfSelection.ts +112 -0
  440. package/src/app/projects.css +63 -0
  441. package/src/app/reader-toolbar.css +65 -0
  442. package/src/app/selection.css +150 -0
  443. package/src/app/sidebar.css +60 -0
  444. package/src/app/skills.css +7 -0
  445. package/src/app/style.css +1061 -0
  446. package/src/app/templates.css +49 -0
  447. package/src/app/themes.css +80 -0
  448. package/src/app/ui/Icon.tsx +92 -0
  449. package/src/app/ui/README.md +27 -0
  450. package/src/app/ui/fonts.css +36 -0
  451. package/src/app/ui/index.tsx +223 -0
  452. package/src/app/ui/ui.css +388 -0
  453. package/src/app/useReaderPreview.ts +19 -0
  454. package/src/app/useTextEditing.ts +155 -0
  455. package/src/assets/adapter.ts +122 -0
  456. package/src/assets/files.ts +378 -0
  457. package/src/assets/import-worker.ts +294 -0
  458. package/src/assets/imports.ts +124 -0
  459. package/src/assets/index.ts +60 -0
  460. package/src/assets/store.ts +798 -0
  461. package/src/assets/usage.ts +118 -0
  462. package/src/cli/check.ts +25 -0
  463. package/src/cli/init.ts +119 -0
  464. package/src/cli/lock.ts +34 -0
  465. package/src/cli/main.ts +118 -0
  466. package/src/cli/process.ts +19 -0
  467. package/src/cli/start.ts +96 -0
  468. package/src/cli/update.ts +348 -0
  469. package/src/cli/workspace.ts +94 -0
  470. package/src/document/index.tsx +641 -0
  471. package/src/document/page.tsx +53 -0
  472. package/src/document/text-targets.tsx +162 -0
  473. package/src/media/files.ts +124 -0
  474. package/src/media/render.ts +63 -0
  475. package/src/rendering/resolve-sources.ts +84 -0
  476. package/src/runtime/jsx-dev-runtime.ts +2 -0
  477. package/src/runtime/jsx-runtime.ts +2 -0
  478. package/src/runtime/paths.ts +12 -0
  479. package/src/server/assets-cli.ts +162 -0
  480. package/src/server/assets-http.ts +100 -0
  481. package/src/server/client.ts +50 -0
  482. package/src/server/clipboard.ts +22 -0
  483. package/src/server/comments-cli.ts +64 -0
  484. package/src/server/comments.ts +130 -0
  485. package/src/server/create-cli.ts +33 -0
  486. package/src/server/create.ts +228 -0
  487. package/src/server/dependencies.ts +91 -0
  488. package/src/server/documents.ts +143 -0
  489. package/src/server/edits.ts +249 -0
  490. package/src/server/export-batch.ts +105 -0
  491. package/src/server/export-errors.ts +2 -0
  492. package/src/server/export-file.ts +57 -0
  493. package/src/server/export-inputs.ts +66 -0
  494. package/src/server/export-preview.ts +69 -0
  495. package/src/server/export.ts +32 -0
  496. package/src/server/exports.ts +283 -0
  497. package/src/server/files.ts +21 -0
  498. package/src/server/guides.ts +71 -0
  499. package/src/server/index.ts +432 -0
  500. package/src/server/materials.ts +39 -0
  501. package/src/server/media-cli.ts +73 -0
  502. package/src/server/media-mutations.ts +168 -0
  503. package/src/server/pptx.ts +160 -0
  504. package/src/server/preflight.ts +129 -0
  505. package/src/server/projects-cli.ts +29 -0
  506. package/src/server/projects.ts +187 -0
  507. package/src/server/render-error.ts +9 -0
  508. package/src/server/render-source.ts +24 -0
  509. package/src/server/render.ts +48 -0
  510. package/src/server/review-cli.ts +40 -0
  511. package/src/server/review.ts +161 -0
  512. package/src/server/selection.ts +23 -0
  513. package/src/server/source-overrides.ts +97 -0
  514. package/src/server/templates-cli.ts +51 -0
  515. package/src/server/templates.ts +186 -0
  516. package/src/server/text-layout.ts +41 -0
  517. package/src/server/text-source.ts +307 -0
  518. package/src/server/themes-cli.ts +59 -0
  519. package/src/server/themes.ts +215 -0
  520. package/src/server/ttf2eot.d.ts +3 -0
  521. package/src/server/worker.ts +166 -0
  522. package/src/server/workspace.ts +242 -0
  523. package/src/shared/anchors.ts +69 -0
  524. package/src/shared/assets.ts +154 -0
  525. package/src/shared/export.ts +34 -0
  526. package/src/shared/media.ts +33 -0
  527. package/src/shared/projects.ts +19 -0
  528. package/src/shared/selection.ts +94 -0
  529. package/src/shared/skill-index.ts +14 -0
  530. package/src/shared/starters.ts +19 -0
  531. package/src/shared/templates.ts +18 -0
  532. package/src/shared/themes.ts +24 -0
  533. package/src/shared/types.ts +39 -0
  534. package/src/template/index.ts +27 -0
  535. package/src/themes/index.ts +3 -0
  536. package/src/themes/neutral.ts +20 -0
  537. package/src/themes/types.ts +110 -0
  538. package/starter/assets/brand/wordmark.png +0 -0
  539. package/starter/assets/fonts/InterUI-LICENSE.txt +93 -0
  540. package/starter/assets/fonts/InterUI-Medium.ttf +0 -0
  541. package/starter/assets/fonts/InterUI-Regular.ttf +0 -0
  542. package/starter/assets/fonts/InterUI-source.json +19 -0
  543. package/starter/assets/fonts/OpenDocMono-Regular.ttf +0 -0
  544. package/starter/assets/fonts/OpenDocSans-Italic.ttf +0 -0
  545. package/starter/assets/fonts/OpenDocSans-Regular.ttf +0 -0
  546. package/starter/assets/fonts/OpenDocSans-Semibold.ttf +0 -0
  547. package/starter/assets/fonts/OpenDocSans-SemiboldItalic.ttf +0 -0
  548. package/starter/assets/fonts/OpenDocSerif-Italic.ttf +0 -0
  549. package/starter/assets/fonts/OpenDocSerif-Regular.ttf +0 -0
  550. package/starter/assets/fonts/OpenDocSerif-Semibold.ttf +0 -0
  551. package/starter/assets/fonts/OpenDocSerif-SemiboldItalic.ttf +0 -0
  552. package/starter/assets/fonts/SourceCode-LICENSE.md +93 -0
  553. package/starter/assets/fonts/SourceSans-LICENSE.md +93 -0
  554. package/starter/assets/fonts/SourceSerif-LICENSE.md +93 -0
  555. package/starter/assets/fonts/geist/OFL.txt +93 -0
  556. package/starter/assets/fonts/geist/asset.json +7 -0
  557. package/starter/assets/fonts/geist/files/1a9874b3be0fc168692a3d2327bccb4d28835653d3b91537a755296a467a83e3.ttf +0 -0
  558. package/starter/assets/fonts/geist/files/a8eefb873ba9c9020665f8a98302697ce1f3b79ab2deef6ee508c0ca6a82e876.ttf +0 -0
  559. package/starter/assets/fonts/geist/files/ccce59465ae5c61930ada5453834f60500fbd95084d85db63e0e65fad0125455.ttf +0 -0
  560. package/starter/assets/fonts/geist/files/f5e95110d70593672515080bee9148463ada0a7f77b89ed65a3d43cb2b0ff83a.pdf +0 -0
  561. package/starter/assets/fonts/geist/revisions/9a2bc12fb2f23cb27bc227087e63e1407bb804ee0586480bd6b7966ec69fb474.json +60 -0
  562. package/starter/assets/fonts/inter/OFL.txt +93 -0
  563. package/starter/assets/fonts/inter/asset.json +7 -0
  564. package/starter/assets/fonts/inter/files/1b08e7fc267a5c7e1d614100f604b83e7e8a0be241f0f288faa2b3ac93a683ba.ttf +0 -0
  565. package/starter/assets/fonts/inter/files/5b6f0c6f26e5c554a64cdcc3a9b5d802b7f9aec6206f1dbcfcdcad7b5860a2a9.ttf +0 -0
  566. package/starter/assets/fonts/inter/files/957db8560d510a198a7d0333fae7b6b444b00c20801581126273978d778eb3c3.pdf +0 -0
  567. package/starter/assets/fonts/inter/files/b37284b5701b6b168dfc770aa1a4ac492106422fd3ba76bc7641e37434e8019c.ttf +0 -0
  568. package/starter/assets/fonts/inter/files/c1811d32ac0f6eed1bbf57529f2ecdfc6c717d48a969dd864942436315a1b198.ttf +0 -0
  569. package/starter/assets/fonts/inter/files/e7a1aaf7eda9f2fad4131725fa556265ec75ca7b2d756260173a040363e8d4f7.ttf +0 -0
  570. package/starter/assets/fonts/inter/files/ef8f755d933b9310804cc9152f1f18cb2ac460d6b05054ec913d889c9f11f79e.ttf +0 -0
  571. package/starter/assets/fonts/inter/revisions/600391517c413963b71e278a57c26c40366c81fa3939a6b9755f446206766d12.json +99 -0
  572. package/starter/assets/fonts/inter/source.json +57 -0
  573. package/starter/assets/fonts/lato/OFL.txt +93 -0
  574. package/starter/assets/fonts/lato/asset.json +7 -0
  575. package/starter/assets/fonts/lato/files/4a6b566dbb28adb473a8789ce5169306f42f0c8a070ac92bae93636f36348b0d.pdf +0 -0
  576. package/starter/assets/fonts/lato/files/5adeb6b334d8fb99ef053bc052b952773d544315e0e1d668a12c0ce8bd51375c.ttf +0 -0
  577. package/starter/assets/fonts/lato/files/62c1b7f0d2e74b45960154c3520efc337b553db0961bfdc950d5618334596cc8.ttf +0 -0
  578. package/starter/assets/fonts/lato/files/71b8b7decbe75a881ed267be539d402bd1e9420b799658aada4e0d1bd5af803c.ttf +0 -0
  579. package/starter/assets/fonts/lato/files/8a0aace75d33794eece4b28187bfc1df0bbd2888b5d8a56e01788c8d65d16be1.ttf +0 -0
  580. package/starter/assets/fonts/lato/files/d636e4683231f931eda222d588e944d082bfd3bdba02f928bee461c0f185b251.ttf +0 -0
  581. package/starter/assets/fonts/lato/files/e399c44efe1387100531d26c7e4800c5d12251b890d6654a3098c7c679cb1786.ttf +0 -0
  582. package/starter/assets/fonts/lato/revisions/49ccb93400a9d466fab7d9843b1ecf8916ec6d47a475dd79a597a22eb39616bc.json +99 -0
  583. package/starter/assets/fonts/lato/source.json +57 -0
  584. package/starter/assets/fonts/merriweather/OFL.txt +93 -0
  585. package/starter/assets/fonts/merriweather/asset.json +7 -0
  586. package/starter/assets/fonts/merriweather/files/1c54f91b910454251c4c2b7bd4e472e1abf265fba7ca3c0ef2eee2f41324099e.ttf +0 -0
  587. package/starter/assets/fonts/merriweather/files/8bde8da2bb7f0265e27ba0481f70bb48d0f98a976c145f2f239c648ddd6532e0.pdf +0 -0
  588. package/starter/assets/fonts/merriweather/files/90b7db4460fcd1a5ca49575c2668a793f3cd6447664d312a068d690e1c01e6bc.ttf +0 -0
  589. package/starter/assets/fonts/merriweather/files/afff81272b7653417bb6f8bef57add055b1f9fda36f27eba5f32b40752bd08da.ttf +0 -0
  590. package/starter/assets/fonts/merriweather/files/e029d3b71e5bae3877c73f4f2b15af28db16593d49b0aed2a328d37ff7075846.ttf +0 -0
  591. package/starter/assets/fonts/merriweather/files/e9864a6790bf712a04e20f3662b206a1535186ed3e877fd859dd5fb9682335df.ttf +0 -0
  592. package/starter/assets/fonts/merriweather/files/fa71baebdd20a7d0de2e5e445a5922530fe9e1d740efbe791f113b682d3cb093.ttf +0 -0
  593. package/starter/assets/fonts/merriweather/revisions/1888e390b3e4f38a3d7cd2dc1bb805aeb6ce13f986a97656f0265fd436bc91d2.json +99 -0
  594. package/starter/assets/fonts/merriweather/source.json +57 -0
  595. package/starter/assets/fonts/open-sans/OFL.txt +92 -0
  596. package/starter/assets/fonts/open-sans/asset.json +7 -0
  597. package/starter/assets/fonts/open-sans/files/1bc0594a83762b2c25d38915a34464b7fec6088298ca22d151757bf98d6700ec.ttf +0 -0
  598. package/starter/assets/fonts/open-sans/files/47ed1cfaa7ffca04a04ab850b2938fd52c09d1b44cfa3e2980878e166b0cbd87.ttf +0 -0
  599. package/starter/assets/fonts/open-sans/files/574939af301f07df8e21cfff279465c5981dd9d9cf62086f7515897df951c6f5.pdf +0 -0
  600. package/starter/assets/fonts/open-sans/files/6d3884d0d57c1b67e9c50c54eca7b69c535c114e76bd7a9cfda0258588185553.ttf +0 -0
  601. package/starter/assets/fonts/open-sans/files/733eb93b167e6d45de09aa768f6c0355647c2c26f5416dbc7407a08ed41e81c6.ttf +0 -0
  602. package/starter/assets/fonts/open-sans/files/75367e6da7d914eaed87883ba51b2a2b5816b5cdbb39f96ec5c81a5b032bfd5a.ttf +0 -0
  603. package/starter/assets/fonts/open-sans/files/ff4fdc11204e0edd14e9a0bb6c374b847a9093b0ec2c16702e03afca79ac4ef7.ttf +0 -0
  604. package/starter/assets/fonts/open-sans/revisions/bbbe3a4915b9bccbc883c0decb4097511c43b6bd09ae22a1516aff128c219bc5.json +99 -0
  605. package/starter/assets/fonts/open-sans/source.json +57 -0
  606. package/starter/assets/fonts/roboto/OFL.txt +93 -0
  607. package/starter/assets/fonts/roboto/asset.json +7 -0
  608. package/starter/assets/fonts/roboto/files/22d45d989248a624252b8382067ac56550212fa675dcdbaf12f03d297dd87a58.pdf +0 -0
  609. package/starter/assets/fonts/roboto/files/35757eaa996b3359022f47f164a67ee9eac04971af24c5b8fbd4b89e844ff190.ttf +0 -0
  610. package/starter/assets/fonts/roboto/files/4d3035883c531846bd1ce2dc89f36d932e72dc114f56062c7e3a9cdd74f3d3ea.ttf +0 -0
  611. package/starter/assets/fonts/roboto/files/be7639306a4fc4a02ce2ae2ff59eb1335e4db4a7379dd0a384ed7cc053817789.ttf +0 -0
  612. package/starter/assets/fonts/roboto/files/d2920cbb1b60a3fd11fbf22049286e43a6baf522d37fdf1e7c89562319bcfea5.ttf +0 -0
  613. package/starter/assets/fonts/roboto/files/dece7c71bbe61710787f0839c722c65e87355dd2eb4a823e6b5488121ff81e4b.ttf +0 -0
  614. package/starter/assets/fonts/roboto/files/f478ba88b0292e685e487901dfbb1401457d32d6ebee4030cdfd5698235bffa8.ttf +0 -0
  615. package/starter/assets/fonts/roboto/revisions/bda5e2d84c17313373dd2dbf3e64fe0dd450c7e1b59e6929e69557e122fe976e.json +99 -0
  616. package/starter/assets/fonts/roboto/source.json +57 -0
  617. package/starter/assets/logos/opendoc/asset.json +6 -0
  618. package/starter/assets/logos/opendoc/files/831d5ccd9eb6709cc8439ea257c03d81452e81a28a3d1eedbd6a3b7daff687b6.png +0 -0
  619. package/starter/assets/logos/opendoc/revisions/834dde8926ddb81de687254195a168bb13bfb77803307f1257de1f2228be63b2.json +33 -0
  620. package/starter/assets/ui-fonts/geist/OFL.txt +93 -0
  621. package/starter/assets/ui-fonts/geist/geist-latin-ext-wght-italic.woff2 +0 -0
  622. package/starter/assets/ui-fonts/geist/geist-latin-ext-wght-normal.woff2 +0 -0
  623. package/starter/assets/ui-fonts/geist/geist-latin-wght-italic.woff2 +0 -0
  624. package/starter/assets/ui-fonts/geist/geist-latin-wght-normal.woff2 +0 -0
  625. package/starter/assets/ui-fonts/geist/source.json +26 -0
  626. package/starter/documents/welcome/assets.json +7 -0
  627. package/starter/documents/welcome/index.tsx +160 -0
  628. package/starter/documents/welcome/media/.gitkeep +0 -0
  629. package/starter/documents/welcome/media/paper-architecture/image.png +0 -0
  630. package/starter/documents/welcome/media/paper-architecture/meta.json +9 -0
  631. package/starter/documents/welcome/media/paper-architecture/prompt.txt +1 -0
  632. package/starter/documents/welcome/media/studio-rhythm/chart.svg +2343 -0
  633. package/starter/documents/welcome/media/studio-rhythm/data.json +234 -0
  634. package/starter/documents/welcome/media/studio-rhythm/generation.json +9 -0
  635. package/starter/documents/welcome/media/studio-rhythm/image.png +0 -0
  636. package/starter/documents/welcome/media/studio-rhythm/meta.json +11 -0
  637. package/starter/documents/welcome/media/studio-rhythm/recipe.py +79 -0
  638. package/starter/documents/welcome/theme.tsx +5 -0
  639. package/starter/documents/welcome-presentation/assets.json +7 -0
  640. package/starter/documents/welcome-presentation/index.tsx +166 -0
  641. package/starter/documents/welcome-presentation/media/.gitkeep +0 -0
  642. package/starter/documents/welcome-presentation/media/paper-architecture/image.png +0 -0
  643. package/starter/documents/welcome-presentation/media/paper-architecture/meta.json +9 -0
  644. package/starter/documents/welcome-presentation/media/paper-architecture/prompt.txt +1 -0
  645. package/starter/documents/welcome-presentation/media/studio-rhythm/chart.svg +1336 -0
  646. package/starter/documents/welcome-presentation/media/studio-rhythm/data.json +234 -0
  647. package/starter/documents/welcome-presentation/media/studio-rhythm/generation.json +9 -0
  648. package/starter/documents/welcome-presentation/media/studio-rhythm/image.png +0 -0
  649. package/starter/documents/welcome-presentation/media/studio-rhythm/meta.json +13 -0
  650. package/starter/documents/welcome-presentation/media/studio-rhythm/recipe.py +49 -0
  651. package/starter/documents/welcome-presentation/theme.tsx +5 -0
  652. package/starter/projects.json +17 -0
  653. package/starter/templates/AGENTS.md +9 -0
  654. package/starter/templates/_shared/BusinessLogo.tsx +14 -0
  655. package/starter/templates/_shared/Pricing.tsx +40 -0
  656. package/starter/templates/_shared/commerce.ts +93 -0
  657. package/starter/templates/brand-guidelines/AGENTS.md +32 -0
  658. package/starter/templates/brand-guidelines/index.tsx +62 -0
  659. package/starter/templates/brand-guidelines/preview.tsx +181 -0
  660. package/starter/templates/brand-guidelines/starter.tsx +179 -0
  661. package/starter/templates/brand-guidelines/template.json +15 -0
  662. package/starter/templates/business-proposal/AGENTS.md +13 -0
  663. package/starter/templates/business-proposal/README.md +36 -0
  664. package/starter/templates/business-proposal/data.json +37 -0
  665. package/starter/templates/business-proposal/examples/long.json +142 -0
  666. package/starter/templates/business-proposal/examples/sparse.json +17 -0
  667. package/starter/templates/business-proposal/examples/typical.json +37 -0
  668. package/starter/templates/business-proposal/index.tsx +59 -0
  669. package/starter/templates/business-proposal/preview.tsx +47 -0
  670. package/starter/templates/business-proposal/schema.ts +14 -0
  671. package/starter/templates/business-proposal/starter.tsx +18 -0
  672. package/starter/templates/business-proposal/template.json +11 -0
  673. package/starter/templates/company-profile/AGENTS.md +48 -0
  674. package/starter/templates/company-profile/index.tsx +69 -0
  675. package/starter/templates/company-profile/preview.tsx +185 -0
  676. package/starter/templates/company-profile/starter.tsx +186 -0
  677. package/starter/templates/company-profile/template.json +15 -0
  678. package/starter/templates/consulting-report/AGENTS.md +11 -0
  679. package/starter/templates/consulting-report/README.md +13 -0
  680. package/starter/templates/consulting-report/RESEARCH.md +10 -0
  681. package/starter/templates/consulting-report/index.tsx +44 -0
  682. package/starter/templates/consulting-report/preview.tsx +39 -0
  683. package/starter/templates/consulting-report/starter.tsx +15 -0
  684. package/starter/templates/consulting-report/template.json +11 -0
  685. package/starter/templates/editorial-essay/AGENTS.md +11 -0
  686. package/starter/templates/editorial-essay/README.md +11 -0
  687. package/starter/templates/editorial-essay/index.tsx +30 -0
  688. package/starter/templates/editorial-essay/preview.tsx +26 -0
  689. package/starter/templates/editorial-essay/starter.tsx +15 -0
  690. package/starter/templates/editorial-essay/template.json +11 -0
  691. package/starter/templates/executive-brief/AGENTS.md +9 -0
  692. package/starter/templates/executive-brief/README.md +11 -0
  693. package/starter/templates/executive-brief/index.tsx +33 -0
  694. package/starter/templates/executive-brief/preview.tsx +37 -0
  695. package/starter/templates/executive-brief/starter.tsx +11 -0
  696. package/starter/templates/executive-brief/template.json +11 -0
  697. package/starter/templates/image-story/AGENTS.md +37 -0
  698. package/starter/templates/image-story/index.tsx +106 -0
  699. package/starter/templates/image-story/preview.tsx +33 -0
  700. package/starter/templates/image-story/starter.tsx +24 -0
  701. package/starter/templates/image-story/template.json +13 -0
  702. package/starter/templates/invoice/AGENTS.md +13 -0
  703. package/starter/templates/invoice/README.md +40 -0
  704. package/starter/templates/invoice/data.json +61 -0
  705. package/starter/templates/invoice/examples/long.json +241 -0
  706. package/starter/templates/invoice/examples/sparse.json +33 -0
  707. package/starter/templates/invoice/examples/typical.json +61 -0
  708. package/starter/templates/invoice/index.tsx +57 -0
  709. package/starter/templates/invoice/preview.tsx +12 -0
  710. package/starter/templates/invoice/schema.ts +45 -0
  711. package/starter/templates/invoice/starter.tsx +12 -0
  712. package/starter/templates/invoice/template.json +11 -0
  713. package/starter/templates/literary-text/AGENTS.md +9 -0
  714. package/starter/templates/literary-text/README.md +11 -0
  715. package/starter/templates/literary-text/index.tsx +31 -0
  716. package/starter/templates/literary-text/preview.tsx +20 -0
  717. package/starter/templates/literary-text/starter.tsx +11 -0
  718. package/starter/templates/literary-text/template.json +11 -0
  719. package/starter/templates/magazine-feature/AGENTS.md +11 -0
  720. package/starter/templates/magazine-feature/README.md +13 -0
  721. package/starter/templates/magazine-feature/index.tsx +41 -0
  722. package/starter/templates/magazine-feature/preview.tsx +34 -0
  723. package/starter/templates/magazine-feature/starter.tsx +15 -0
  724. package/starter/templates/magazine-feature/template.json +11 -0
  725. package/starter/templates/monthly-report/AGENTS.md +11 -0
  726. package/starter/templates/monthly-report/README.md +24 -0
  727. package/starter/templates/monthly-report/data.json +131 -0
  728. package/starter/templates/monthly-report/examples/long.json +519 -0
  729. package/starter/templates/monthly-report/examples/sparse.json +20 -0
  730. package/starter/templates/monthly-report/examples/typical.json +37 -0
  731. package/starter/templates/monthly-report/index.tsx +92 -0
  732. package/starter/templates/monthly-report/preview.tsx +14 -0
  733. package/starter/templates/monthly-report/schema.ts +127 -0
  734. package/starter/templates/monthly-report/starter.tsx +13 -0
  735. package/starter/templates/monthly-report/template.json +11 -0
  736. package/starter/templates/pitch-deck/AGENTS.md +32 -0
  737. package/starter/templates/pitch-deck/index.tsx +46 -0
  738. package/starter/templates/pitch-deck/preview.tsx +142 -0
  739. package/starter/templates/pitch-deck/starter.tsx +140 -0
  740. package/starter/templates/pitch-deck/template.json +15 -0
  741. package/starter/templates/proposal-deck/AGENTS.md +25 -0
  742. package/starter/templates/proposal-deck/index.tsx +52 -0
  743. package/starter/templates/proposal-deck/preview.tsx +172 -0
  744. package/starter/templates/proposal-deck/starter.tsx +168 -0
  745. package/starter/templates/proposal-deck/template.json +7 -0
  746. package/starter/templates/quotation/AGENTS.md +13 -0
  747. package/starter/templates/quotation/README.md +42 -0
  748. package/starter/templates/quotation/data.json +64 -0
  749. package/starter/templates/quotation/examples/long.json +272 -0
  750. package/starter/templates/quotation/examples/sparse.json +31 -0
  751. package/starter/templates/quotation/examples/typical.json +64 -0
  752. package/starter/templates/quotation/index.tsx +51 -0
  753. package/starter/templates/quotation/preview.tsx +12 -0
  754. package/starter/templates/quotation/schema.ts +27 -0
  755. package/starter/templates/quotation/starter.tsx +12 -0
  756. package/starter/templates/quotation/template.json +11 -0
  757. package/starter/templates/scientific-paper/AGENTS.md +11 -0
  758. package/starter/templates/scientific-paper/README.md +13 -0
  759. package/starter/templates/scientific-paper/index.tsx +47 -0
  760. package/starter/templates/scientific-paper/preview.tsx +43 -0
  761. package/starter/templates/scientific-paper/starter.tsx +15 -0
  762. package/starter/templates/scientific-paper/template.json +11 -0
  763. package/starter/themes/Specimen.tsx +54 -0
  764. package/starter/themes/civic-spectrum/components.tsx +92 -0
  765. package/starter/themes/civic-spectrum/design.md +70 -0
  766. package/starter/themes/civic-spectrum/index.ts +57 -0
  767. package/starter/themes/civic-spectrum/preview.tsx +66 -0
  768. package/starter/themes/field-manual/components.tsx +106 -0
  769. package/starter/themes/field-manual/design.md +72 -0
  770. package/starter/themes/field-manual/index.ts +57 -0
  771. package/starter/themes/field-manual/preview.tsx +82 -0
  772. package/starter/themes/index.ts +3 -0
  773. package/starter/themes/mckinsey-consulting/components.tsx +69 -0
  774. package/starter/themes/mckinsey-consulting/design.md +68 -0
  775. package/starter/themes/mckinsey-consulting/index.ts +60 -0
  776. package/starter/themes/mckinsey-consulting/preview.tsx +53 -0
  777. package/starter/themes/neutral/design.md +35 -0
  778. package/starter/themes/neutral/index.ts +21 -0
  779. package/starter/themes/neutral/preview.tsx +4 -0
  780. package/starter/themes/opendoc-neutral/components.tsx +77 -0
  781. package/starter/themes/opendoc-neutral/design.md +70 -0
  782. package/starter/themes/opendoc-neutral/index.ts +54 -0
  783. package/starter/themes/opendoc-neutral/preview.tsx +43 -0
  784. package/starter/themes/types.ts +3 -0
  785. package/tsconfig.workspace.json +24 -0
  786. package/vendor/formepdf/LICENSE +21 -0
  787. package/vendor/formepdf/README.md +97 -0
  788. package/vendor/formepdf/font-subset.patch +228 -0
  789. package/vendor/formepdf/text-writer.patch +507 -0
@@ -0,0 +1,1470 @@
1
+ import { isValidElement, Children, Fragment } from 'react';
2
+ import { Document, Page, View, Text, H1, H2, H3, H4, H5, H6, OrderedList, UnorderedList, ListItem, Strong, Em, Code, Link, Image, Table, Row, Cell, Fixed, Svg, QrCode, Barcode, Canvas, Watermark, PageBreak, BarChart, LineChart, PieChart, AreaChart, DotPlot, TextField, Checkbox, Dropdown, RadioButton } from './components.js';
3
+ import { Font } from './font.js';
4
+ import { mapStyle, parseColor, expandEdges, mapColumnWidth, mergeFonts, recordCanvasOperations, mapListMarker, HEADING_DEFAULTS, STRONG_DEFAULTS, EM_DEFAULTS, CODE_DEFAULTS, LINK_DEFAULTS, buildBarChartKind, buildLineChartKind, buildPieChartKind, buildAreaChartKind, buildDotPlotKind } from '@formepdf/shared';
5
+ import { isRefMarker, getRefPath, isEachMarker, getEachPath, getEachTemplate, isExprMarker, getExpr, REF_SENTINEL, REF_SENTINEL_END, } from './template-proxy.js';
6
+ const VALID_PARENTS = {
7
+ Page: {
8
+ allowed: ['Document'],
9
+ suggestion: '<Page> must be a direct child of <Document>.',
10
+ },
11
+ Row: {
12
+ allowed: ['Table'],
13
+ suggestion: '<Row> must be inside a <Table>. Wrap it: <Table><Row>...</Row></Table>',
14
+ },
15
+ Cell: {
16
+ allowed: ['Row'],
17
+ suggestion: '<Cell> must be inside a <Row>. Wrap it: <Row><Cell>...</Cell></Row>',
18
+ },
19
+ };
20
+ function validateNesting(componentName, parent) {
21
+ const rule = VALID_PARENTS[componentName];
22
+ if (!rule)
23
+ return;
24
+ if (parent !== null && !rule.allowed.includes(parent)) {
25
+ throw new Error(`Invalid nesting: <${componentName}> found inside <${parent}>. ${rule.suggestion}`);
26
+ }
27
+ }
28
+ // ─── Source location extraction ─────────────────────────────────────
29
+ function extractSourceLocation(element) {
30
+ // Check globalThis.__formeSourceMap (populated by CLI dev server's JSX shim for React 19+)
31
+ const map = globalThis.__formeSourceMap;
32
+ if (map) {
33
+ const source = map.get(element);
34
+ if (source)
35
+ return source;
36
+ }
37
+ // Fallback to _source for React 18 and earlier
38
+ const s = element._source;
39
+ if (s && s.fileName) {
40
+ return { file: s.fileName, line: s.lineNumber, column: s.columnNumber };
41
+ }
42
+ return undefined;
43
+ }
44
+ // ─── Version-independent type checks ─────────────────────────────────
45
+ /**
46
+ * Check if a component type is `Document`, even across different package versions.
47
+ * Uses `__formeType` marker first (survives minification), then falls back to
48
+ * `displayName` / `name` for legacy builds without the marker.
49
+ */
50
+ function isDocumentType(type) {
51
+ if (type === Document)
52
+ return true;
53
+ if (typeof type === 'function') {
54
+ return type.__formeType === 'Document'
55
+ || type.displayName === 'Document'
56
+ || type.name === 'Document';
57
+ }
58
+ return false;
59
+ }
60
+ // ─── Component resolution ────────────────────────────────────────────
61
+ /**
62
+ * Resolve wrapper function components (e.g. `<MyReport data={...} />`) by
63
+ * calling them until we reach a Forme primitive like `<Document>`. This lets
64
+ * users pass custom components directly to `renderDocument()` /
65
+ * `serialize()` without manually invoking them first.
66
+ */
67
+ function resolveElement(element) {
68
+ let resolved = element;
69
+ for (let i = 0; i < 10 && typeof resolved.type === 'function' && !isDocumentType(resolved.type); i++) {
70
+ const result = callComponent(resolved.type, resolved.props);
71
+ if (!isValidElement(result))
72
+ break;
73
+ resolved = result;
74
+ }
75
+ return resolved;
76
+ }
77
+ /**
78
+ * Call a function component directly (outside React's render cycle).
79
+ * React Compiler injects `useMemoCache` hooks into compiled components,
80
+ * which throws when called outside a render context. We catch that and
81
+ * give a clear error message pointing to the `'use no memo'` directive.
82
+ */
83
+ function callComponent(fn, props) {
84
+ try {
85
+ return fn(props);
86
+ }
87
+ catch (err) {
88
+ if (err instanceof Error && /hook|useMemoCache|Invalid hook call/i.test(err.message)) {
89
+ const name = fn.displayName || fn.name || 'Unknown';
90
+ throw new Error(`Component "${name}" appears to be compiled by React Compiler, which injects hooks ` +
91
+ `that cannot run outside of React's render cycle. Forme's serialize() calls components ` +
92
+ `directly to walk the element tree.\n\n` +
93
+ `Fix: Add 'use no memo' at the top of the component to opt it out of React Compiler:\n\n` +
94
+ ` function ${name}(props) {\n` +
95
+ ` 'use no memo';\n` +
96
+ ` return <Document>...</Document>;\n` +
97
+ ` }\n\n` +
98
+ `Alternatively, call the component yourself before passing to renderDocument():\n\n` +
99
+ ` const element = <${name} data={data} />;\n` +
100
+ ` // becomes:\n` +
101
+ ` const element = ${name}({ data });\n` +
102
+ ` await renderDocument(element);`);
103
+ }
104
+ throw err;
105
+ }
106
+ }
107
+ // ─── Public API ──────────────────────────────────────────────────────
108
+ /**
109
+ * Serialize a React element tree into a Forme JSON document object.
110
+ * The top-level element must be a <Document> (or a component that returns one).
111
+ */
112
+ export function serialize(element) {
113
+ element = resolveElement(element);
114
+ if (!isDocumentType(element.type)) {
115
+ throw new Error('Top-level element must be <Document>');
116
+ }
117
+ const props = element.props;
118
+ const childElements = flattenChildren(props.children);
119
+ // Separate Page children from content children
120
+ const pageNodes = [];
121
+ const contentNodes = [];
122
+ for (const child of childElements) {
123
+ if (isValidElement(child) && child.type === Page) {
124
+ pageNodes.push(serializePage(child));
125
+ }
126
+ else {
127
+ const node = serializeChild(child, 'Document');
128
+ if (node)
129
+ contentNodes.push(node);
130
+ }
131
+ }
132
+ // If there are page nodes, use them. Otherwise wrap content in a default page.
133
+ let children;
134
+ if (pageNodes.length > 0) {
135
+ // Any loose content nodes get added to the last page's children
136
+ if (contentNodes.length > 0) {
137
+ const lastPage = pageNodes[pageNodes.length - 1];
138
+ lastPage.children.push(...contentNodes);
139
+ }
140
+ children = pageNodes;
141
+ }
142
+ else if (contentNodes.length > 0) {
143
+ children = contentNodes;
144
+ }
145
+ else {
146
+ children = [];
147
+ }
148
+ const metadata = {};
149
+ if (props.title !== undefined)
150
+ metadata.title = props.title;
151
+ if (props.author !== undefined)
152
+ metadata.author = props.author;
153
+ if (props.subject !== undefined)
154
+ metadata.subject = props.subject;
155
+ if (props.creator !== undefined)
156
+ metadata.creator = props.creator;
157
+ if (props.lang !== undefined)
158
+ metadata.lang = props.lang;
159
+ // Merge global + document fonts (document fonts override on conflict)
160
+ const mergedFonts = mergeFonts(Font.getRegistered(), props.fonts);
161
+ const result = {
162
+ children,
163
+ metadata,
164
+ defaultPage: {
165
+ size: 'A4',
166
+ margin: { top: 54, right: 54, bottom: 54, left: 54 },
167
+ wrap: true,
168
+ },
169
+ };
170
+ if (props.style)
171
+ result.defaultStyle = mapStyle(props.style);
172
+ if (props.tagged !== undefined)
173
+ result.tagged = props.tagged;
174
+ if (props.pdfa !== undefined)
175
+ result.pdfa = props.pdfa;
176
+ if (props.pdfUa)
177
+ result.pdfUa = true;
178
+ const cert = props.certification ?? props.signature;
179
+ if (cert) {
180
+ if (props.signature && !props.certification) {
181
+ console.warn('[Forme] The `signature` prop is deprecated. Use `certification` instead.');
182
+ }
183
+ result.certification = cert;
184
+ }
185
+ if (mergedFonts.length > 0) {
186
+ result.fonts = mergedFonts;
187
+ }
188
+ return result;
189
+ }
190
+ // ─── Page serialization ──────────────────────────────────────────────
191
+ function serializePage(element) {
192
+ const props = element.props;
193
+ let size = 'A4';
194
+ if (props.size !== undefined) {
195
+ if (typeof props.size === 'string') {
196
+ size = props.size;
197
+ }
198
+ else {
199
+ size = { Custom: { width: props.size.width, height: props.size.height } };
200
+ }
201
+ }
202
+ let margin = { top: 54, right: 54, bottom: 54, left: 54 };
203
+ if (props.margin !== undefined) {
204
+ margin = expandEdges(props.margin);
205
+ }
206
+ const config = { size, margin, wrap: true };
207
+ if (props.backgroundImage !== undefined)
208
+ config.backgroundImage = props.backgroundImage;
209
+ if (props.backgroundOpacity !== undefined)
210
+ config.backgroundOpacity = props.backgroundOpacity;
211
+ if (props.backgroundSize !== undefined)
212
+ config.backgroundSize = props.backgroundSize;
213
+ if (props.backgroundPosition !== undefined)
214
+ config.backgroundPosition = props.backgroundPosition;
215
+ const childElements = flattenChildren(props.children);
216
+ const children = serializeChildren(childElements, 'Page');
217
+ return {
218
+ kind: { type: 'Page', config },
219
+ style: props.style ? mapStyle(props.style) : {},
220
+ children,
221
+ sourceLocation: extractSourceLocation(element),
222
+ };
223
+ }
224
+ // ─── Node serialization ─────────────────────────────────────────────
225
+ function serializeChild(child, parent = null) {
226
+ if (child === null || child === undefined || typeof child === 'boolean') {
227
+ return null;
228
+ }
229
+ if (typeof child === 'string') {
230
+ return {
231
+ kind: { type: 'Text', content: child },
232
+ style: {},
233
+ children: [],
234
+ };
235
+ }
236
+ if (typeof child === 'number') {
237
+ return {
238
+ kind: { type: 'Text', content: String(child) },
239
+ style: {},
240
+ children: [],
241
+ };
242
+ }
243
+ if (!isValidElement(child)) {
244
+ // Detect HTML elements and give helpful suggestion
245
+ if (typeof child === 'object' && child !== null && 'type' in child) {
246
+ const t = child.type;
247
+ if (typeof t === 'string') {
248
+ const suggestions = {
249
+ div: 'View', span: 'Text', p: 'Text', h1: 'Text', h2: 'Text',
250
+ h3: 'Text', img: 'Image', table: 'Table', tr: 'Row', td: 'Cell',
251
+ };
252
+ const suggestion = suggestions[t];
253
+ if (suggestion) {
254
+ throw new Error(`HTML element <${t}> is not supported. Use <${suggestion}> instead.`);
255
+ }
256
+ }
257
+ }
258
+ return null;
259
+ }
260
+ const element = child;
261
+ if (element.type === View) {
262
+ return serializeView(element, parent);
263
+ }
264
+ if (element.type === Text) {
265
+ return serializeText(element);
266
+ }
267
+ if (element.type === H1)
268
+ return serializeHeading(element, 1);
269
+ if (element.type === H2)
270
+ return serializeHeading(element, 2);
271
+ if (element.type === H3)
272
+ return serializeHeading(element, 3);
273
+ if (element.type === H4)
274
+ return serializeHeading(element, 4);
275
+ if (element.type === H5)
276
+ return serializeHeading(element, 5);
277
+ if (element.type === H6)
278
+ return serializeHeading(element, 6);
279
+ if (element.type === OrderedList)
280
+ return serializeList(element, true);
281
+ if (element.type === UnorderedList)
282
+ return serializeList(element, false);
283
+ if (element.type === ListItem)
284
+ return serializeListItem(element);
285
+ if (element.type === Image) {
286
+ return serializeImage(element);
287
+ }
288
+ if (element.type === Table) {
289
+ return serializeTable(element, parent);
290
+ }
291
+ if (element.type === Row) {
292
+ validateNesting('Row', parent);
293
+ return serializeRow(element);
294
+ }
295
+ if (element.type === Cell) {
296
+ validateNesting('Cell', parent);
297
+ return serializeCell(element);
298
+ }
299
+ if (element.type === Fixed) {
300
+ return serializeFixed(element);
301
+ }
302
+ if (element.type === Svg) {
303
+ return serializeSvg(element);
304
+ }
305
+ if (element.type === QrCode) {
306
+ return serializeQrCode(element);
307
+ }
308
+ if (element.type === Barcode) {
309
+ return serializeBarcode(element);
310
+ }
311
+ if (element.type === TextField) {
312
+ return serializeTextField(element);
313
+ }
314
+ if (element.type === Checkbox) {
315
+ return serializeCheckbox(element);
316
+ }
317
+ if (element.type === Dropdown) {
318
+ return serializeDropdown(element);
319
+ }
320
+ if (element.type === RadioButton) {
321
+ return serializeRadioButton(element);
322
+ }
323
+ if (element.type === Canvas) {
324
+ return serializeCanvas(element);
325
+ }
326
+ if (element.type === Watermark) {
327
+ return serializeWatermark(element);
328
+ }
329
+ if (element.type === BarChart) {
330
+ return serializeBarChart(element);
331
+ }
332
+ if (element.type === LineChart) {
333
+ return serializeLineChart(element);
334
+ }
335
+ if (element.type === PieChart) {
336
+ return serializePieChart(element);
337
+ }
338
+ if (element.type === AreaChart) {
339
+ return serializeAreaChart(element);
340
+ }
341
+ if (element.type === DotPlot) {
342
+ return serializeDotPlot(element);
343
+ }
344
+ if (element.type === PageBreak) {
345
+ return {
346
+ kind: { type: 'PageBreak' },
347
+ style: {},
348
+ children: [],
349
+ sourceLocation: extractSourceLocation(element),
350
+ };
351
+ }
352
+ if (element.type === Page) {
353
+ validateNesting('Page', parent);
354
+ return serializePage(element);
355
+ }
356
+ if (isDocumentType(element.type)) {
357
+ // Nested Document — just serialize its children
358
+ const props = element.props;
359
+ const childElements = flattenChildren(props.children);
360
+ const nodes = serializeChildren(childElements, parent);
361
+ return nodes.length === 1 ? nodes[0] : {
362
+ kind: { type: 'View' },
363
+ style: {},
364
+ children: nodes,
365
+ };
366
+ }
367
+ // Unknown component — try to call it as a function component
368
+ if (typeof element.type === 'function') {
369
+ const result = callComponent(element.type, element.props);
370
+ if (isValidElement(result)) {
371
+ return serializeChild(result, parent);
372
+ }
373
+ return null;
374
+ }
375
+ return null;
376
+ }
377
+ function serializeView(element, _parent = null) {
378
+ const props = element.props;
379
+ const style = mapStyle(props.style);
380
+ if (props.wrap !== undefined) {
381
+ style.wrap = props.wrap;
382
+ }
383
+ const childElements = flattenChildren(props.children);
384
+ const children = serializeChildren(childElements, 'View');
385
+ const node = {
386
+ kind: { type: 'View' },
387
+ style,
388
+ children,
389
+ sourceLocation: extractSourceLocation(element),
390
+ };
391
+ if (props.bookmark)
392
+ node.bookmark = props.bookmark;
393
+ if (props.href)
394
+ node.href = props.href;
395
+ return node;
396
+ }
397
+ /** Return the component-default style for a recognized inline component,
398
+ * or `null` if the element isn't a recognized inline component.
399
+ * `Text` returns `{}` because it carries no defaults beyond the user's style. */
400
+ function inlineDefaults(type) {
401
+ switch (type) {
402
+ case Text: return {};
403
+ case Strong: return STRONG_DEFAULTS;
404
+ case Em: return EM_DEFAULTS;
405
+ case Code: return CODE_DEFAULTS;
406
+ case Link: return LINK_DEFAULTS;
407
+ default: return null;
408
+ }
409
+ }
410
+ /**
411
+ * Recursively flatten children of a `<Text>` into TextRuns, accumulating
412
+ * styles and href as we descend. Outer style is overlaid by each inline
413
+ * component's defaults, which are in turn overlaid by the user-supplied
414
+ * `style` on that element — so user style wins at every level while
415
+ * still inheriting whatever wasn't explicitly set.
416
+ *
417
+ * E.g. `<Strong><Em>both</Em></Strong>` produces a single run with
418
+ * `{ fontWeight: 700, fontStyle: 'italic' }`. A `<Link href>` nested in a
419
+ * `<Strong>` produces a bold underlined blue run with the href set.
420
+ */
421
+ function buildTextRuns(children, accStyle = {}, accHref = undefined) {
422
+ const out = [];
423
+ const elements = flattenChildren(children);
424
+ for (const child of elements) {
425
+ if (child === null || child === undefined || typeof child === 'boolean')
426
+ continue;
427
+ if (typeof child === 'string' || typeof child === 'number') {
428
+ const content = String(child);
429
+ if (content === '')
430
+ continue;
431
+ const run = { content };
432
+ if (Object.keys(accStyle).length > 0)
433
+ run.style = mapStyle(accStyle);
434
+ if (accHref)
435
+ run.href = accHref;
436
+ out.push(run);
437
+ continue;
438
+ }
439
+ if (!isValidElement(child))
440
+ continue;
441
+ const defaults = inlineDefaults(child.type);
442
+ if (defaults === null)
443
+ continue; // unknown element inside <Text> — skip
444
+ const childProps = child.props;
445
+ // Cascade: outer accumulated → this component's defaults → user style.
446
+ // Later spreads win, so user style overrides defaults and outer.
447
+ const nextStyle = { ...accStyle, ...defaults, ...(childProps.style || {}) };
448
+ const nextHref = childProps.href ?? accHref;
449
+ out.push(...buildTextRuns(childProps.children, nextStyle, nextHref));
450
+ }
451
+ return out;
452
+ }
453
+ function serializeText(element) {
454
+ const props = element.props;
455
+ const childElements = flattenChildren(props.children);
456
+ // Detect mixed content: any inline element child (<Text>, <Strong>, <Em>,
457
+ // <Code>, <Link>) means we need TextRuns rather than a flat content string.
458
+ const hasInlineChild = childElements.some(c => isValidElement(c) && inlineDefaults(c.type) !== null);
459
+ const kind = { type: 'Text', content: '' };
460
+ if (hasInlineChild) {
461
+ kind.runs = buildTextRuns(props.children);
462
+ }
463
+ else {
464
+ kind.content = flattenTextContent(props.children);
465
+ }
466
+ if (props.href)
467
+ kind.href = props.href;
468
+ const node = {
469
+ kind,
470
+ style: mapStyle(props.style),
471
+ children: [],
472
+ sourceLocation: extractSourceLocation(element),
473
+ };
474
+ if (props.bookmark)
475
+ node.bookmark = props.bookmark;
476
+ return node;
477
+ }
478
+ /**
479
+ * Serialize an H1-H6 element. Mirrors serializeText for the children
480
+ * machinery (mixed strings + inline-formatting components produce runs)
481
+ * but emits the engine's `Heading { level }` node kind so the tagged-PDF
482
+ * builder can pick up the semantic role. Default styles per level are
483
+ * merged BEFORE the user's `style` prop, so user values win.
484
+ */
485
+ function serializeHeading(element, level) {
486
+ const props = element.props;
487
+ const childElements = flattenChildren(props.children);
488
+ const hasInlineChild = childElements.some((c) => isValidElement(c) && inlineDefaults(c.type) !== null);
489
+ const kind = {
490
+ type: 'Heading',
491
+ level,
492
+ content: '',
493
+ };
494
+ if (hasInlineChild) {
495
+ kind.runs = buildTextRuns(props.children);
496
+ }
497
+ else {
498
+ kind.content = flattenTextContent(props.children);
499
+ }
500
+ if (props.href)
501
+ kind.href = props.href;
502
+ // Defaults underlay; user style wins on conflicting keys.
503
+ const mergedStyle = { ...HEADING_DEFAULTS[level], ...(props.style || {}) };
504
+ const node = {
505
+ kind,
506
+ style: mapStyle(mergedStyle),
507
+ children: [],
508
+ sourceLocation: extractSourceLocation(element),
509
+ };
510
+ if (props.bookmark)
511
+ node.bookmark = props.bookmark;
512
+ return node;
513
+ }
514
+ function serializeList(element, ordered) {
515
+ const props = element.props;
516
+ const markerType = ordered
517
+ ? mapListMarker(props.type, 'decimal')
518
+ : mapListMarker(props.marker, 'disc');
519
+ const start = typeof props.start === 'number' && props.start >= 1 ? props.start : 1;
520
+ // Children must be ListItems — anything else is silently dropped to
521
+ // keep the serializer tolerant. (We don't throw on stray content because
522
+ // a Fragment / null child in JSX is too common to be a real error.)
523
+ const childElements = flattenChildren(props.children).filter((c) => isValidElement(c) && c.type === ListItem);
524
+ const children = childElements.map((c) => serializeListItem(c));
525
+ const node = {
526
+ kind: { type: 'List', ordered, marker_type: markerType, start },
527
+ style: mapStyle(props.style),
528
+ children,
529
+ sourceLocation: extractSourceLocation(element),
530
+ };
531
+ if (props.bookmark)
532
+ node.bookmark = props.bookmark;
533
+ return node;
534
+ }
535
+ function serializeListItem(element) {
536
+ const props = element.props;
537
+ // ListItem content is layed out by the engine using layout_children, so
538
+ // we serialize whatever the user put inside as the node's children. This
539
+ // covers plain strings, JSX text, nested lists, formatted runs via
540
+ // <Text>, etc.
541
+ const rawChildren = flattenChildren(props.children);
542
+ const children = [];
543
+ for (const c of rawChildren) {
544
+ if (typeof c === 'string' || typeof c === 'number') {
545
+ // Auto-wrap raw strings in a Text node so the engine has something
546
+ // concrete to render. Matches the convention everywhere else.
547
+ children.push({
548
+ kind: { type: 'Text', content: String(c) },
549
+ style: {},
550
+ children: [],
551
+ });
552
+ }
553
+ else if (isValidElement(c)) {
554
+ const node = serializeChild(c, null);
555
+ if (node)
556
+ children.push(node);
557
+ }
558
+ }
559
+ return {
560
+ kind: { type: 'ListItem' },
561
+ style: mapStyle(props.style),
562
+ children,
563
+ sourceLocation: extractSourceLocation(element),
564
+ };
565
+ }
566
+ function serializeImage(element) {
567
+ const props = element.props;
568
+ const kind = { type: 'Image', src: props.src };
569
+ if (props.width !== undefined)
570
+ kind.width = props.width;
571
+ if (props.height !== undefined)
572
+ kind.height = props.height;
573
+ const node = {
574
+ kind,
575
+ style: mapStyle(props.style),
576
+ children: [],
577
+ sourceLocation: extractSourceLocation(element),
578
+ };
579
+ if (props.href)
580
+ node.href = props.href;
581
+ if (props.alt)
582
+ node.alt = props.alt;
583
+ return node;
584
+ }
585
+ function serializeTable(element, _parent = null) {
586
+ const props = element.props;
587
+ const columns = (props.columns ?? []).map(col => ({
588
+ width: mapColumnWidth(col.width),
589
+ }));
590
+ const childElements = flattenChildren(props.children);
591
+ const children = serializeChildren(childElements, 'Table');
592
+ return {
593
+ kind: { type: 'Table', columns },
594
+ style: mapStyle(props.style),
595
+ children,
596
+ sourceLocation: extractSourceLocation(element),
597
+ };
598
+ }
599
+ function serializeRow(element) {
600
+ const props = element.props;
601
+ const childElements = flattenChildren(props.children);
602
+ const children = serializeChildren(childElements, 'Row');
603
+ return {
604
+ kind: { type: 'TableRow', is_header: props.header ?? false },
605
+ style: mapStyle(props.style),
606
+ children,
607
+ sourceLocation: extractSourceLocation(element),
608
+ };
609
+ }
610
+ function serializeCell(element) {
611
+ const props = element.props;
612
+ const childElements = flattenChildren(props.children);
613
+ const children = serializeChildren(childElements, 'Cell');
614
+ return {
615
+ kind: { type: 'TableCell', col_span: props.colSpan ?? 1, row_span: props.rowSpan ?? 1 },
616
+ style: mapStyle(props.style),
617
+ children,
618
+ sourceLocation: extractSourceLocation(element),
619
+ };
620
+ }
621
+ function serializeFixed(element) {
622
+ const props = element.props;
623
+ const position = props.position === 'header' ? 'Header' : 'Footer';
624
+ const childElements = flattenChildren(props.children);
625
+ const children = serializeChildren(childElements, 'Fixed');
626
+ const node = {
627
+ kind: { type: 'Fixed', position },
628
+ style: mapStyle(props.style),
629
+ children,
630
+ sourceLocation: extractSourceLocation(element),
631
+ };
632
+ if (props.bookmark)
633
+ node.bookmark = props.bookmark;
634
+ return node;
635
+ }
636
+ function serializeSvg(element) {
637
+ const props = element.props;
638
+ const content = props.content ?? (props.children ? svgChildrenToString(props.children) : '');
639
+ const kind = {
640
+ type: 'Svg',
641
+ width: props.width,
642
+ height: props.height,
643
+ content,
644
+ };
645
+ if (props.viewBox)
646
+ kind.view_box = props.viewBox;
647
+ const node = {
648
+ kind,
649
+ style: mapStyle(props.style),
650
+ children: [],
651
+ sourceLocation: extractSourceLocation(element),
652
+ };
653
+ if (props.href)
654
+ node.href = props.href;
655
+ if (props.alt)
656
+ node.alt = props.alt;
657
+ return node;
658
+ }
659
+ /** Map camelCase SVG prop names to kebab-case attribute names. */
660
+ const svgCamelToKebab = {
661
+ strokeWidth: 'stroke-width',
662
+ strokeLinecap: 'stroke-linecap',
663
+ strokeLinejoin: 'stroke-linejoin',
664
+ strokeMiterlimit: 'stroke-miterlimit',
665
+ strokeDasharray: 'stroke-dasharray',
666
+ strokeDashoffset: 'stroke-dashoffset',
667
+ strokeOpacity: 'stroke-opacity',
668
+ fillOpacity: 'fill-opacity',
669
+ fillRule: 'fill-rule',
670
+ clipPath: 'clip-path',
671
+ clipRule: 'clip-rule',
672
+ };
673
+ function escapeXmlAttr(s) {
674
+ return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
675
+ }
676
+ function svgChildrenToString(children) {
677
+ let result = '';
678
+ Children.forEach(children, (child) => {
679
+ if (typeof child === 'string') {
680
+ result += child.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
681
+ return;
682
+ }
683
+ if (!isValidElement(child))
684
+ return;
685
+ const tag = typeof child.type === 'string' ? child.type : null;
686
+ if (!tag)
687
+ return;
688
+ const { children: nested, ...attrs } = child.props;
689
+ const attrStr = Object.entries(attrs)
690
+ .filter(([, v]) => v !== undefined && v !== null)
691
+ .map(([k, v]) => {
692
+ const name = svgCamelToKebab[k] ?? k;
693
+ return `${name}="${escapeXmlAttr(String(v))}"`;
694
+ })
695
+ .join(' ');
696
+ const open = attrStr ? `<${tag} ${attrStr}` : `<${tag}`;
697
+ if (nested) {
698
+ result += `${open}>${svgChildrenToString(nested)}</${tag}>`;
699
+ }
700
+ else {
701
+ result += `${open}/>`;
702
+ }
703
+ });
704
+ return result;
705
+ }
706
+ function serializeQrCode(element) {
707
+ const props = element.props;
708
+ const kind = { type: 'QrCode', data: props.data };
709
+ if (props.size !== undefined)
710
+ kind.size = props.size;
711
+ const style = mapStyle(props.style);
712
+ if (props.color)
713
+ style.color = parseColor(props.color);
714
+ return {
715
+ kind,
716
+ style,
717
+ children: [],
718
+ sourceLocation: extractSourceLocation(element),
719
+ };
720
+ }
721
+ function serializeBarcode(element) {
722
+ const props = element.props;
723
+ const kind = {
724
+ type: 'Barcode',
725
+ data: props.data,
726
+ format: props.format ?? 'Code128',
727
+ height: props.height ?? 60,
728
+ };
729
+ if (props.width !== undefined)
730
+ kind.width = props.width;
731
+ const style = mapStyle(props.style);
732
+ if (props.color)
733
+ style.color = parseColor(props.color);
734
+ return {
735
+ kind,
736
+ style,
737
+ children: [],
738
+ sourceLocation: extractSourceLocation(element),
739
+ };
740
+ }
741
+ function serializeTextField(element) {
742
+ const props = element.props;
743
+ const kind = {
744
+ type: 'TextField',
745
+ name: props.name,
746
+ width: props.width,
747
+ height: props.height ?? 24,
748
+ multiline: props.multiline ?? false,
749
+ password: props.password ?? false,
750
+ read_only: props.readOnly ?? false,
751
+ font_size: props.fontSize ?? 12,
752
+ };
753
+ if (props.value !== undefined)
754
+ kind.value = props.value;
755
+ if (props.placeholder !== undefined)
756
+ kind.placeholder = props.placeholder;
757
+ if (props.maxLength !== undefined)
758
+ kind.max_length = props.maxLength;
759
+ return {
760
+ kind,
761
+ style: mapStyle(props.style),
762
+ children: [],
763
+ sourceLocation: extractSourceLocation(element),
764
+ };
765
+ }
766
+ function serializeCheckbox(element) {
767
+ const props = element.props;
768
+ const kind = {
769
+ type: 'Checkbox',
770
+ name: props.name,
771
+ checked: props.checked ?? false,
772
+ width: props.width ?? 14,
773
+ height: props.height ?? 14,
774
+ read_only: props.readOnly ?? false,
775
+ };
776
+ return {
777
+ kind,
778
+ style: mapStyle(props.style),
779
+ children: [],
780
+ sourceLocation: extractSourceLocation(element),
781
+ };
782
+ }
783
+ function serializeDropdown(element) {
784
+ const props = element.props;
785
+ const kind = {
786
+ type: 'Dropdown',
787
+ name: props.name,
788
+ options: props.options,
789
+ width: props.width,
790
+ height: props.height ?? 24,
791
+ read_only: props.readOnly ?? false,
792
+ font_size: props.fontSize ?? 12,
793
+ };
794
+ if (props.value !== undefined)
795
+ kind.value = props.value;
796
+ return {
797
+ kind,
798
+ style: mapStyle(props.style),
799
+ children: [],
800
+ sourceLocation: extractSourceLocation(element),
801
+ };
802
+ }
803
+ function serializeRadioButton(element) {
804
+ const props = element.props;
805
+ const kind = {
806
+ type: 'RadioButton',
807
+ name: props.name,
808
+ value: props.value,
809
+ checked: props.checked ?? false,
810
+ width: props.width ?? 14,
811
+ height: props.height ?? 14,
812
+ read_only: props.readOnly ?? false,
813
+ };
814
+ return {
815
+ kind,
816
+ style: mapStyle(props.style),
817
+ children: [],
818
+ sourceLocation: extractSourceLocation(element),
819
+ };
820
+ }
821
+ function serializeCanvas(element) {
822
+ const props = element.props;
823
+ const operations = recordCanvasOperations(props.draw);
824
+ return {
825
+ kind: { type: 'Canvas', width: props.width, height: props.height, operations },
826
+ style: mapStyle(props.style),
827
+ children: [],
828
+ sourceLocation: extractSourceLocation(element),
829
+ };
830
+ }
831
+ function serializeWatermark(element) {
832
+ const props = element.props;
833
+ const fontSize = props.fontSize ?? 60;
834
+ const angle = props.angle ?? -45;
835
+ const colorStr = props.color ?? 'rgba(0,0,0,0.1)';
836
+ // Parse color — extract alpha for opacity
837
+ const parsedColor = parseColor(colorStr);
838
+ const style = mapStyle(props.style);
839
+ style.color = { r: parsedColor.r, g: parsedColor.g, b: parsedColor.b, a: 1 };
840
+ // Multiply color alpha with any existing opacity
841
+ const colorOpacity = parsedColor.a;
842
+ const styleOpacity = (style.opacity !== undefined) ? style.opacity : 1;
843
+ style.opacity = colorOpacity * styleOpacity;
844
+ style.fontSize = fontSize;
845
+ return {
846
+ kind: { type: 'Watermark', text: props.text, font_size: fontSize, angle },
847
+ style,
848
+ children: [],
849
+ sourceLocation: extractSourceLocation(element),
850
+ };
851
+ }
852
+ function serializeBarChart(element) {
853
+ const props = element.props;
854
+ return {
855
+ kind: buildBarChartKind(props),
856
+ style: mapStyle(props.style),
857
+ children: [],
858
+ sourceLocation: extractSourceLocation(element),
859
+ };
860
+ }
861
+ function serializeLineChart(element) {
862
+ const props = element.props;
863
+ return {
864
+ kind: buildLineChartKind(props),
865
+ style: mapStyle(props.style),
866
+ children: [],
867
+ sourceLocation: extractSourceLocation(element),
868
+ };
869
+ }
870
+ function serializePieChart(element) {
871
+ const props = element.props;
872
+ return {
873
+ kind: buildPieChartKind(props),
874
+ style: mapStyle(props.style),
875
+ children: [],
876
+ sourceLocation: extractSourceLocation(element),
877
+ };
878
+ }
879
+ function serializeAreaChart(element) {
880
+ const props = element.props;
881
+ return {
882
+ kind: buildAreaChartKind(props),
883
+ style: mapStyle(props.style),
884
+ children: [],
885
+ sourceLocation: extractSourceLocation(element),
886
+ };
887
+ }
888
+ function serializeDotPlot(element) {
889
+ const props = element.props;
890
+ return {
891
+ kind: buildDotPlotKind(props),
892
+ style: mapStyle(props.style),
893
+ children: [],
894
+ sourceLocation: extractSourceLocation(element),
895
+ };
896
+ }
897
+ // ─── Children helpers ────────────────────────────────────────────────
898
+ function flattenChildren(children) {
899
+ const result = [];
900
+ Children.forEach(children, child => {
901
+ if (Array.isArray(child)) {
902
+ result.push(...child.flatMap(c => flattenChildren(c)));
903
+ }
904
+ else if (isValidElement(child) && child.type === Fragment) {
905
+ const fragProps = child.props;
906
+ result.push(...flattenChildren(fragProps.children));
907
+ }
908
+ else {
909
+ result.push(child);
910
+ }
911
+ });
912
+ return result;
913
+ }
914
+ function serializeChildren(children, parent = null) {
915
+ const nodes = [];
916
+ for (const child of children) {
917
+ const node = serializeChild(child, parent);
918
+ if (node)
919
+ nodes.push(node);
920
+ }
921
+ return nodes;
922
+ }
923
+ /**
924
+ * Flatten all text content within a <Text> element to a single string.
925
+ * Nested <Text> children have their content extracted and concatenated.
926
+ */
927
+ function flattenTextContent(children) {
928
+ if (children === null || children === undefined)
929
+ return '';
930
+ if (typeof children === 'string')
931
+ return children;
932
+ if (typeof children === 'number')
933
+ return String(children);
934
+ if (typeof children === 'boolean')
935
+ return '';
936
+ if (Array.isArray(children)) {
937
+ return children.map(c => flattenTextContent(c)).join('');
938
+ }
939
+ if (isValidElement(children)) {
940
+ const element = children;
941
+ if (element.type === Text) {
942
+ const props = element.props;
943
+ return flattenTextContent(props.children);
944
+ }
945
+ // For other elements inside Text, try to extract text content
946
+ const props = element.props;
947
+ return flattenTextContent(props.children);
948
+ }
949
+ // React.Children.toArray for iterables
950
+ const arr = [];
951
+ Children.forEach(children, c => arr.push(c));
952
+ if (arr.length > 0) {
953
+ return arr.map(c => flattenTextContent(c)).join('');
954
+ }
955
+ return String(children);
956
+ }
957
+ // ─── Template serialization ─────────────────────────────────────────
958
+ //
959
+ // Parallel to `serialize()` but detects proxy markers and expr markers,
960
+ // converting them to `$ref`, `$each`, `$if`, and operator nodes.
961
+ /**
962
+ * Serialize a React element tree into a Forme template JSON document.
963
+ * Like `serialize()` but with expression marker detection for template compilation.
964
+ */
965
+ export function serializeTemplate(element) {
966
+ element = resolveElement(element);
967
+ if (!isDocumentType(element.type)) {
968
+ throw new Error('Top-level element must be <Document>');
969
+ }
970
+ const props = element.props;
971
+ const childElements = flattenTemplateChildren(props.children);
972
+ const pageNodes = [];
973
+ const contentNodes = [];
974
+ for (const child of childElements) {
975
+ if (isValidElement(child) && child.type === Page) {
976
+ pageNodes.push(serializeTemplatePage(child));
977
+ }
978
+ else {
979
+ const node = serializeTemplateChild(child, 'Document');
980
+ if (node !== null)
981
+ contentNodes.push(node);
982
+ }
983
+ }
984
+ let children;
985
+ if (pageNodes.length > 0) {
986
+ if (contentNodes.length > 0) {
987
+ const lastPage = pageNodes[pageNodes.length - 1];
988
+ lastPage.children.push(...contentNodes);
989
+ }
990
+ children = pageNodes;
991
+ }
992
+ else if (contentNodes.length > 0) {
993
+ children = contentNodes;
994
+ }
995
+ else {
996
+ children = [];
997
+ }
998
+ const metadata = {};
999
+ if (props.title !== undefined)
1000
+ metadata.title = processTemplateValue(props.title);
1001
+ if (props.author !== undefined)
1002
+ metadata.author = processTemplateValue(props.author);
1003
+ if (props.subject !== undefined)
1004
+ metadata.subject = processTemplateValue(props.subject);
1005
+ if (props.creator !== undefined)
1006
+ metadata.creator = processTemplateValue(props.creator);
1007
+ if (props.lang !== undefined)
1008
+ metadata.lang = processTemplateValue(props.lang);
1009
+ const mergedFonts = mergeFonts(Font.getRegistered(), props.fonts);
1010
+ const result = {
1011
+ children,
1012
+ metadata,
1013
+ defaultPage: {
1014
+ size: 'A4',
1015
+ margin: { top: 54, right: 54, bottom: 54, left: 54 },
1016
+ wrap: true,
1017
+ },
1018
+ };
1019
+ if (props.style)
1020
+ result.defaultStyle = mapStyle(props.style);
1021
+ if (props.tagged !== undefined)
1022
+ result.tagged = props.tagged;
1023
+ if (props.pdfa !== undefined)
1024
+ result.pdfa = props.pdfa;
1025
+ if (props.pdfUa)
1026
+ result.pdfUa = true;
1027
+ const cert = props.certification ?? props.signature;
1028
+ if (cert) {
1029
+ if (props.signature && !props.certification) {
1030
+ console.warn('[Forme] The `signature` prop is deprecated. Use `certification` instead.');
1031
+ }
1032
+ result.certification = cert;
1033
+ }
1034
+ if (mergedFonts.length > 0) {
1035
+ result.fonts = mergedFonts;
1036
+ }
1037
+ return result;
1038
+ }
1039
+ function serializeTemplatePage(element) {
1040
+ const props = element.props;
1041
+ let size = 'A4';
1042
+ if (props.size !== undefined) {
1043
+ if (typeof props.size === 'string') {
1044
+ size = props.size;
1045
+ }
1046
+ else {
1047
+ size = { Custom: { width: props.size.width, height: props.size.height } };
1048
+ }
1049
+ }
1050
+ let margin = { top: 54, right: 54, bottom: 54, left: 54 };
1051
+ if (props.margin !== undefined) {
1052
+ margin = expandEdges(props.margin);
1053
+ }
1054
+ const config = { size, margin, wrap: true };
1055
+ const childElements = flattenTemplateChildren(props.children);
1056
+ const children = serializeTemplateChildren(childElements, 'Page');
1057
+ return {
1058
+ kind: { type: 'Page', config },
1059
+ style: {},
1060
+ children,
1061
+ };
1062
+ }
1063
+ function serializeTemplateChild(child, parent = null) {
1064
+ if (child === null || child === undefined || typeof child === 'boolean') {
1065
+ return null;
1066
+ }
1067
+ // Check for each marker (from .map() on proxy)
1068
+ if (isEachMarker(child)) {
1069
+ const path = getEachPath(child);
1070
+ const template = getEachTemplate(child);
1071
+ // The template is the JSX element returned from the .map() callback
1072
+ const serializedTemplate = isValidElement(template)
1073
+ ? serializeTemplateChild(template, parent)
1074
+ : processTemplateValue(template);
1075
+ return {
1076
+ $each: { $ref: path },
1077
+ as: '$item',
1078
+ template: serializedTemplate,
1079
+ };
1080
+ }
1081
+ // Check for expr marker
1082
+ if (isExprMarker(child)) {
1083
+ return serializeExprValues(getExpr(child), parent);
1084
+ }
1085
+ // Check for ref sentinel strings
1086
+ if (typeof child === 'string') {
1087
+ const processed = processTemplateString(child);
1088
+ if (processed !== null)
1089
+ return processed;
1090
+ return {
1091
+ kind: { type: 'Text', content: child },
1092
+ style: {},
1093
+ children: [],
1094
+ };
1095
+ }
1096
+ if (typeof child === 'number') {
1097
+ return {
1098
+ kind: { type: 'Text', content: String(child) },
1099
+ style: {},
1100
+ children: [],
1101
+ };
1102
+ }
1103
+ if (!isValidElement(child))
1104
+ return null;
1105
+ const element = child;
1106
+ if (element.type === View)
1107
+ return serializeTemplateView(element, parent);
1108
+ if (element.type === Text)
1109
+ return serializeTemplateText(element);
1110
+ if (element.type === Image)
1111
+ return serializeTemplateImage(element);
1112
+ if (element.type === Table)
1113
+ return serializeTemplateTable(element, parent);
1114
+ if (element.type === Row) {
1115
+ validateNesting('Row', parent);
1116
+ return serializeTemplateRow(element);
1117
+ }
1118
+ if (element.type === Cell) {
1119
+ validateNesting('Cell', parent);
1120
+ return serializeTemplateCell(element);
1121
+ }
1122
+ if (element.type === Fixed)
1123
+ return serializeTemplateFixed(element);
1124
+ if (element.type === Svg)
1125
+ return serializeSvg(element);
1126
+ if (element.type === QrCode)
1127
+ return serializeQrCode(element);
1128
+ if (element.type === Barcode)
1129
+ return serializeBarcode(element);
1130
+ if (element.type === TextField)
1131
+ return serializeTextField(element);
1132
+ if (element.type === Checkbox)
1133
+ return serializeCheckbox(element);
1134
+ if (element.type === Dropdown)
1135
+ return serializeDropdown(element);
1136
+ if (element.type === RadioButton)
1137
+ return serializeRadioButton(element);
1138
+ if (element.type === Canvas)
1139
+ return serializeCanvas(element);
1140
+ if (element.type === Watermark)
1141
+ return serializeWatermark(element);
1142
+ if (element.type === BarChart)
1143
+ return serializeBarChart(element);
1144
+ if (element.type === LineChart)
1145
+ return serializeLineChart(element);
1146
+ if (element.type === PieChart)
1147
+ return serializePieChart(element);
1148
+ if (element.type === AreaChart)
1149
+ return serializeAreaChart(element);
1150
+ if (element.type === DotPlot)
1151
+ return serializeDotPlot(element);
1152
+ if (element.type === PageBreak) {
1153
+ return { kind: { type: 'PageBreak' }, style: {}, children: [] };
1154
+ }
1155
+ if (element.type === Page) {
1156
+ validateNesting('Page', parent);
1157
+ return serializeTemplatePage(element);
1158
+ }
1159
+ // Unknown function component — call it
1160
+ if (typeof element.type === 'function') {
1161
+ const result = callComponent(element.type, element.props);
1162
+ if (isValidElement(result)) {
1163
+ return serializeTemplateChild(result, parent);
1164
+ }
1165
+ return null;
1166
+ }
1167
+ return null;
1168
+ }
1169
+ function serializeTemplateView(element, _parent = null) {
1170
+ const props = element.props;
1171
+ const style = mapTemplateStyle(props.style);
1172
+ if (props.wrap !== undefined)
1173
+ style.wrap = props.wrap;
1174
+ const childElements = flattenTemplateChildren(props.children);
1175
+ const children = serializeTemplateChildren(childElements, 'View');
1176
+ const node = { kind: { type: 'View' }, style, children };
1177
+ if (props.bookmark)
1178
+ node.bookmark = props.bookmark;
1179
+ if (props.href)
1180
+ node.href = props.href;
1181
+ return node;
1182
+ }
1183
+ function serializeTemplateText(element) {
1184
+ const props = element.props;
1185
+ const childElements = flattenTemplateChildren(props.children);
1186
+ const hasTextChild = childElements.some(c => isValidElement(c) && c.type === Text);
1187
+ const kind = { type: 'Text', content: '' };
1188
+ if (hasTextChild) {
1189
+ const runs = [];
1190
+ for (const child of childElements) {
1191
+ if (typeof child === 'string' || typeof child === 'number') {
1192
+ const processed = typeof child === 'string' ? processTemplateString(child) : null;
1193
+ if (processed !== null) {
1194
+ runs.push({ content: processed });
1195
+ }
1196
+ else {
1197
+ runs.push({ content: String(child) });
1198
+ }
1199
+ }
1200
+ else if (isValidElement(child) && child.type === Text) {
1201
+ const childProps = child.props;
1202
+ const run = {
1203
+ content: flattenTemplateTextContent(childProps.children),
1204
+ };
1205
+ if (childProps.style)
1206
+ run.style = mapTemplateStyle(childProps.style);
1207
+ if (childProps.href)
1208
+ run.href = childProps.href;
1209
+ runs.push(run);
1210
+ }
1211
+ }
1212
+ kind.runs = runs;
1213
+ }
1214
+ else {
1215
+ kind.content = flattenTemplateTextContent(props.children);
1216
+ }
1217
+ if (props.href)
1218
+ kind.href = props.href;
1219
+ const node = {
1220
+ kind,
1221
+ style: mapTemplateStyle(props.style),
1222
+ children: [],
1223
+ };
1224
+ if (props.bookmark)
1225
+ node.bookmark = props.bookmark;
1226
+ return node;
1227
+ }
1228
+ function serializeTemplateImage(element) {
1229
+ const props = element.props;
1230
+ const kind = { type: 'Image', src: processTemplateValue(props.src) };
1231
+ if (props.width !== undefined)
1232
+ kind.width = processTemplateValue(props.width);
1233
+ if (props.height !== undefined)
1234
+ kind.height = processTemplateValue(props.height);
1235
+ return { kind, style: mapTemplateStyle(props.style), children: [] };
1236
+ }
1237
+ function serializeTemplateTable(element, _parent = null) {
1238
+ const props = element.props;
1239
+ const columns = (props.columns ?? []).map(col => ({
1240
+ width: mapColumnWidth(col.width),
1241
+ }));
1242
+ const childElements = flattenTemplateChildren(props.children);
1243
+ const children = serializeTemplateChildren(childElements, 'Table');
1244
+ return { kind: { type: 'Table', columns }, style: mapTemplateStyle(props.style), children };
1245
+ }
1246
+ function serializeTemplateRow(element) {
1247
+ const props = element.props;
1248
+ const childElements = flattenTemplateChildren(props.children);
1249
+ const children = serializeTemplateChildren(childElements, 'Row');
1250
+ return { kind: { type: 'TableRow', is_header: props.header ?? false }, style: mapTemplateStyle(props.style), children };
1251
+ }
1252
+ function serializeTemplateCell(element) {
1253
+ const props = element.props;
1254
+ const childElements = flattenTemplateChildren(props.children);
1255
+ const children = serializeTemplateChildren(childElements, 'Cell');
1256
+ return { kind: { type: 'TableCell', col_span: props.colSpan ?? 1, row_span: props.rowSpan ?? 1 }, style: mapTemplateStyle(props.style), children };
1257
+ }
1258
+ function serializeTemplateFixed(element) {
1259
+ const props = element.props;
1260
+ const position = props.position === 'header' ? 'Header' : 'Footer';
1261
+ const childElements = flattenTemplateChildren(props.children);
1262
+ const children = serializeTemplateChildren(childElements, 'Fixed');
1263
+ const node = { kind: { type: 'Fixed', position }, style: mapTemplateStyle(props.style), children };
1264
+ if (props.bookmark)
1265
+ node.bookmark = props.bookmark;
1266
+ return node;
1267
+ }
1268
+ function serializeTemplateChildren(children, parent = null) {
1269
+ const nodes = [];
1270
+ for (const child of children) {
1271
+ const node = serializeTemplateChild(child, parent);
1272
+ if (node !== null)
1273
+ nodes.push(node);
1274
+ }
1275
+ return nodes;
1276
+ }
1277
+ /**
1278
+ * Flatten children without using React.Children.forEach, which rejects
1279
+ * proxy objects and markers. Handles arrays, Fragments, and raw values.
1280
+ */
1281
+ function flattenTemplateChildren(children) {
1282
+ if (children === null || children === undefined)
1283
+ return [];
1284
+ const result = [];
1285
+ if (Array.isArray(children)) {
1286
+ for (const child of children) {
1287
+ result.push(...flattenTemplateChildren(child));
1288
+ }
1289
+ return result;
1290
+ }
1291
+ // Fragment unwrapping
1292
+ if (isValidElement(children) && children.type === Fragment) {
1293
+ const fragProps = children.props;
1294
+ return flattenTemplateChildren(fragProps.children);
1295
+ }
1296
+ result.push(children);
1297
+ return result;
1298
+ }
1299
+ // ─── Expression value serialization ─────────────────────────────────
1300
+ /**
1301
+ * Recursively process an expression object, serializing any React elements
1302
+ * found in its values (e.g. $if then/else branches).
1303
+ */
1304
+ function serializeExprValues(expr, parent) {
1305
+ const result = {};
1306
+ for (const [key, val] of Object.entries(expr)) {
1307
+ if (isValidElement(val)) {
1308
+ result[key] = serializeTemplateChild(val, parent);
1309
+ }
1310
+ else if (Array.isArray(val)) {
1311
+ result[key] = val.map(v => isValidElement(v) ? serializeTemplateChild(v, parent) : v);
1312
+ }
1313
+ else {
1314
+ result[key] = val;
1315
+ }
1316
+ }
1317
+ return result;
1318
+ }
1319
+ // ─── Template value processing ──────────────────────────────────────
1320
+ /**
1321
+ * Process a value that may contain ref markers, expr markers, or proxy objects.
1322
+ * Returns the expression form or the original value.
1323
+ */
1324
+ function processTemplateValue(v) {
1325
+ if (typeof v === 'string') {
1326
+ if (isRefMarker(v)) {
1327
+ return { $ref: getRefPath(v) };
1328
+ }
1329
+ // Check for embedded sentinels in longer strings
1330
+ if (v.includes(REF_SENTINEL)) {
1331
+ return processTemplateInterpolatedString(v);
1332
+ }
1333
+ return v;
1334
+ }
1335
+ if (isExprMarker(v)) {
1336
+ return getExpr(v);
1337
+ }
1338
+ if (isEachMarker(v)) {
1339
+ return {
1340
+ $each: { $ref: getEachPath(v) },
1341
+ as: '$item',
1342
+ template: processTemplateValue(getEachTemplate(v)),
1343
+ };
1344
+ }
1345
+ // Proxy objects with toPrimitive
1346
+ if (typeof v === 'object' && v !== null && Symbol.toPrimitive in v) {
1347
+ const str = String(v);
1348
+ if (isRefMarker(str)) {
1349
+ return { $ref: getRefPath(str) };
1350
+ }
1351
+ }
1352
+ return v;
1353
+ }
1354
+ /**
1355
+ * Process a string that contains interpolated ref sentinels.
1356
+ * e.g. "Hello \0FORME_REF:name\0!" → {$concat: ["Hello ", {$ref: "name"}, "!"]}
1357
+ */
1358
+ function processTemplateInterpolatedString(s) {
1359
+ const parts = [];
1360
+ let remaining = s;
1361
+ while (remaining.length > 0) {
1362
+ const startIdx = remaining.indexOf(REF_SENTINEL);
1363
+ if (startIdx === -1) {
1364
+ parts.push(remaining);
1365
+ break;
1366
+ }
1367
+ if (startIdx > 0) {
1368
+ parts.push(remaining.slice(0, startIdx));
1369
+ }
1370
+ const afterSentinel = remaining.slice(startIdx + REF_SENTINEL.length);
1371
+ const endIdx = afterSentinel.indexOf(REF_SENTINEL_END);
1372
+ if (endIdx === -1) {
1373
+ parts.push(remaining);
1374
+ break;
1375
+ }
1376
+ const path = afterSentinel.slice(0, endIdx);
1377
+ parts.push({ $ref: path });
1378
+ remaining = afterSentinel.slice(endIdx + REF_SENTINEL_END.length);
1379
+ }
1380
+ if (parts.length === 1)
1381
+ return parts[0];
1382
+ return { $concat: parts };
1383
+ }
1384
+ /**
1385
+ * Process a string that might be a pure ref sentinel.
1386
+ * Returns the $ref node if it's a pure ref, null otherwise.
1387
+ */
1388
+ function processTemplateString(s) {
1389
+ if (isRefMarker(s)) {
1390
+ return { $ref: getRefPath(s) };
1391
+ }
1392
+ if (s.includes(REF_SENTINEL)) {
1393
+ return processTemplateInterpolatedString(s);
1394
+ }
1395
+ return null;
1396
+ }
1397
+ /**
1398
+ * Flatten text content within a <Text> element, detecting ref markers.
1399
+ * Returns either a plain string or a $ref/$concat expression.
1400
+ */
1401
+ function flattenTemplateTextContent(children) {
1402
+ if (children === null || children === undefined)
1403
+ return '';
1404
+ if (typeof children === 'boolean')
1405
+ return '';
1406
+ if (typeof children === 'string') {
1407
+ if (isRefMarker(children))
1408
+ return { $ref: getRefPath(children) };
1409
+ if (children.includes(REF_SENTINEL))
1410
+ return processTemplateInterpolatedString(children);
1411
+ return children;
1412
+ }
1413
+ if (typeof children === 'number')
1414
+ return String(children);
1415
+ if (isExprMarker(children))
1416
+ return getExpr(children);
1417
+ // Proxy with toPrimitive
1418
+ if (typeof children === 'object' && children !== null && Symbol.toPrimitive in children) {
1419
+ const str = String(children);
1420
+ if (isRefMarker(str))
1421
+ return { $ref: getRefPath(str) };
1422
+ return str;
1423
+ }
1424
+ if (Array.isArray(children)) {
1425
+ const parts = children.map(c => flattenTemplateTextContent(c));
1426
+ // If all parts are strings, join them
1427
+ if (parts.every(p => typeof p === 'string')) {
1428
+ return parts.join('');
1429
+ }
1430
+ // Otherwise produce a $concat
1431
+ return { $concat: parts };
1432
+ }
1433
+ if (isValidElement(children)) {
1434
+ const element = children;
1435
+ if (element.type === Text) {
1436
+ const props = element.props;
1437
+ return flattenTemplateTextContent(props.children);
1438
+ }
1439
+ const props = element.props;
1440
+ return flattenTemplateTextContent(props.children);
1441
+ }
1442
+ const arr = [];
1443
+ Children.forEach(children, c => arr.push(c));
1444
+ if (arr.length > 0) {
1445
+ return flattenTemplateTextContent(arr);
1446
+ }
1447
+ return String(children);
1448
+ }
1449
+ /**
1450
+ * Map style, processing values that may contain template expressions.
1451
+ */
1452
+ function mapTemplateStyle(style) {
1453
+ if (!style)
1454
+ return {};
1455
+ // Use the regular mapStyle but then post-process values that contain markers
1456
+ const result = mapStyle(style);
1457
+ return processTemplateStyleValues(result);
1458
+ }
1459
+ function processTemplateStyleValues(obj) {
1460
+ const result = {};
1461
+ for (const [key, val] of Object.entries(obj)) {
1462
+ if (typeof val === 'object' && val !== null && !Array.isArray(val)) {
1463
+ result[key] = processTemplateStyleValues(val);
1464
+ }
1465
+ else {
1466
+ result[key] = processTemplateValue(val);
1467
+ }
1468
+ }
1469
+ return result;
1470
+ }