@koda-sl/baker-cli 0.532.0 → 0.534.0-dev.911a80433

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 (863) hide show
  1. package/README.md +1 -1
  2. package/dist/account-BRRFMDXZ.js +82 -0
  3. package/dist/account-MQI7EZBH.js +82 -0
  4. package/dist/account-reads-K6YDAOHX.js +219 -0
  5. package/dist/account-users-QS54ZEOD.js +64 -0
  6. package/dist/account-writes-PGGGP26M.js +68 -0
  7. package/dist/accounts-H3U7LARM.js +80 -0
  8. package/dist/accounts-IW62WBX5.js +701 -0
  9. package/dist/actions-2CUQFZNA.js +55 -0
  10. package/dist/activecampaign-WAMDVBUO.js +938 -0
  11. package/dist/ad-group-writes-ROUU6BHU.js +172 -0
  12. package/dist/ad-groups-Y2BSRLIN.js +70 -0
  13. package/dist/ad-writes-NF4LCGVP.js +176 -0
  14. package/dist/add-4P3CUHAN.js +305 -0
  15. package/dist/add-UHWRBSFE.js +107 -0
  16. package/dist/ads-CPMX3L4A.js +79 -0
  17. package/dist/ads-TDN7OYSU.js +48 -0
  18. package/dist/advertisers-6CHV5N2V.js +123 -0
  19. package/dist/analytics-4GTUW42V.js +2437 -0
  20. package/dist/analytics-MV2RQ6KR.js +447 -0
  21. package/dist/animate-EOSLSA7F.js +480 -0
  22. package/dist/assign-RN5DGDS2.js +80 -0
  23. package/dist/audience-size-7DYMCXDM.js +76 -0
  24. package/dist/audiences-VMGB2JZG.js +280 -0
  25. package/dist/audit-7U7G2JKS.js +154 -0
  26. package/dist/autocomplete-E6YHJ3HH.js +114 -0
  27. package/dist/avatars-6JHVTSXH.js +38 -0
  28. package/dist/bid-pricing-J3OJK4J3.js +103 -0
  29. package/dist/brand-3EAQFDYN.js +22 -0
  30. package/dist/brief-ADGCGC3H.js +543 -0
  31. package/dist/campaign-groups-GN7D5UXE.js +99 -0
  32. package/dist/campaign-writes-HKWI6GYU.js +168 -0
  33. package/dist/campaign-writes-UORRIIWY.js +176 -0
  34. package/dist/campaigns-5I76AV7F.js +113 -0
  35. package/dist/campaigns-BEXDLBT3.js +111 -0
  36. package/dist/campaigns-GONROKTU.js +78 -0
  37. package/dist/canvas-CHV34G62.js +46 -0
  38. package/dist/capabilities-VKBIQ2BR.js +147 -0
  39. package/dist/catalog-VXANSX2O.js +66 -0
  40. package/dist/catalog-VXANSX2O.js.map +1 -0
  41. package/dist/catalogs-LXEM7NNC.js +130 -0
  42. package/dist/changes-4OYC4NMW.js +135 -0
  43. package/dist/chatgpt-XV6CVKLN.js +47 -0
  44. package/dist/chats-W35ZPZEW.js +279 -0
  45. package/dist/check-3D63D4ZT.js +107 -0
  46. package/dist/chunk-2PC26XRF.js +592 -0
  47. package/dist/chunk-2UZHRLLO.js +148 -0
  48. package/dist/chunk-45EERHDB.js +783 -0
  49. package/dist/chunk-55B4AJY3.js +249 -0
  50. package/dist/chunk-56UWXQEN.js +392 -0
  51. package/dist/chunk-5G5QFFJY.js +275 -0
  52. package/dist/chunk-5GHKZLID.js +438 -0
  53. package/dist/chunk-5HGAO4ZI.js +89 -0
  54. package/dist/chunk-5YN53OAA.js +61 -0
  55. package/dist/chunk-6CCEEVXJ.js +285 -0
  56. package/dist/chunk-6HGLQJ6A.js +638 -0
  57. package/dist/chunk-6OIKNJ7G.js +26 -0
  58. package/dist/chunk-6QGBBX7F.js +46 -0
  59. package/dist/chunk-6RTZPBAT.js +19 -0
  60. package/dist/chunk-7MY3QHGA.js +203 -0
  61. package/dist/chunk-AH6TDWYS.js +3510 -0
  62. package/dist/chunk-AH6TDWYS.js.map +1 -0
  63. package/dist/chunk-BKOUVU6X.js +547 -0
  64. package/dist/chunk-CBQPKCFE.js +170 -0
  65. package/dist/chunk-CWZ2ODJQ.js +57 -0
  66. package/dist/chunk-DBPPTM3W.js +24026 -0
  67. package/dist/chunk-DBPPTM3W.js.map +1 -0
  68. package/dist/chunk-DGZYZWMK.js +843 -0
  69. package/dist/chunk-DMA67YC3.js +344 -0
  70. package/dist/chunk-DT3V5EGL.js +2209 -0
  71. package/dist/chunk-DT3V5EGL.js.map +1 -0
  72. package/dist/chunk-DYOUJERF.js +7234 -0
  73. package/dist/chunk-E3FMS5DA.js +297 -0
  74. package/dist/chunk-EIRGJD3Q.js +167 -0
  75. package/dist/chunk-F3CZFUXZ.js +3187 -0
  76. package/dist/chunk-F3CZFUXZ.js.map +1 -0
  77. package/dist/chunk-G3MEYGXC.js +1518 -0
  78. package/dist/chunk-G3MN4HIX.js +831 -0
  79. package/dist/chunk-G53CUQZV.js +207 -0
  80. package/dist/chunk-GPZVYXJZ.js +455 -0
  81. package/dist/chunk-HGHVNUJT.js +156 -0
  82. package/dist/chunk-IZABTTW5.js +228 -0
  83. package/dist/chunk-J3HA4RFY.js +51 -0
  84. package/dist/chunk-JGOYO7I2.js +103 -0
  85. package/dist/chunk-JUF6Q5X7.js +8954 -0
  86. package/dist/chunk-KAAYVKBH.js +479 -0
  87. package/dist/chunk-KUM36NSV.js +429 -0
  88. package/dist/chunk-MHSVWQK6.js +91 -0
  89. package/dist/chunk-MTV2RSGY.js +63 -0
  90. package/dist/chunk-MUS2UTWU.js +4254 -0
  91. package/dist/chunk-MUS2UTWU.js.map +1 -0
  92. package/dist/chunk-N4BK6OKX.js +91 -0
  93. package/dist/chunk-NP3FPCPN.js +377 -0
  94. package/dist/chunk-OAXQPLTG.js +604 -0
  95. package/dist/chunk-OI2CKYAQ.js +846 -0
  96. package/dist/chunk-QUYDMAQN.js +169 -0
  97. package/dist/chunk-RIA5RXPL.js +387 -0
  98. package/dist/chunk-S556LOAP.js +930 -0
  99. package/dist/chunk-S556LOAP.js.map +1 -0
  100. package/dist/chunk-SIKCVWM3.js +76 -0
  101. package/dist/chunk-SOS4QFLE.js +5471 -0
  102. package/dist/chunk-SOS4QFLE.js.map +1 -0
  103. package/dist/chunk-T65Y7N7H.js +225 -0
  104. package/dist/chunk-T75WL56Z.js +224 -0
  105. package/dist/chunk-TGCDXZ5X.js +910 -0
  106. package/dist/chunk-TOUF5ME6.js +1646 -0
  107. package/dist/chunk-TWCS6FSC.js +191 -0
  108. package/dist/chunk-UPXPBA4W.js +676 -0
  109. package/dist/chunk-URMAEVZO.js +150 -0
  110. package/dist/chunk-UUWUJ64R.js +197 -0
  111. package/dist/chunk-VGUGFRWF.js +494 -0
  112. package/dist/chunk-VYJLS64A.js +1902 -0
  113. package/dist/chunk-VYJLS64A.js.map +1 -0
  114. package/dist/chunk-WEQZ563U.js +319 -0
  115. package/dist/chunk-WUCTGDV7.js +163 -0
  116. package/dist/chunk-XCRYRVKK.js +5368 -0
  117. package/dist/chunk-XJ5TX772.js +131 -0
  118. package/dist/chunk-XPIBSDG4.js +274 -0
  119. package/dist/chunk-Y6MLSN6W.js +1919 -0
  120. package/dist/chunk-YBFZJ5EB.js +66 -0
  121. package/dist/chunk-YR3OPPUE.js +142 -0
  122. package/dist/chunk-YXQFCQX2.js +64 -0
  123. package/dist/chunk-Z3Y67AH6.js +98 -0
  124. package/dist/chunk-ZKRRYVDG.js +23 -0
  125. package/dist/claim-DWGPEVJN.js +200 -0
  126. package/dist/cli.js +31 -31
  127. package/dist/companies-3VT7OJAA.js +198 -0
  128. package/dist/company-XEPW45AT.js +308 -0
  129. package/dist/complete-AEX34ICU.js +84 -0
  130. package/dist/connect-TF4FCXDV.js +45 -0
  131. package/dist/conversation-6WWZMPAB.js +96 -0
  132. package/dist/conversion-report-I6R2FDCD.js +127 -0
  133. package/dist/conversion-upload-command-QD6MGLY4.js +439 -0
  134. package/dist/conversion-writes-H2JOAORW.js +122 -0
  135. package/dist/conversions-D46PQRWF.js +140 -0
  136. package/dist/conversions-WGW43FUE.js +78 -0
  137. package/dist/create-7WV7XWZV.js +62 -0
  138. package/dist/create-OUZZLPQK.js +210 -0
  139. package/dist/create-QRT6O5PN.js +135 -0
  140. package/dist/create-WSEYNFTP.js +239 -0
  141. package/dist/creatives-BSZY7VDQ.js +223 -0
  142. package/dist/creatives-DBDFDHX7.js +58 -0
  143. package/dist/credentials-P7GQYIE3.js +290 -0
  144. package/dist/critique-6F4FWQN5.js +232 -0
  145. package/dist/critique-X2YDOMON.js +1451 -0
  146. package/dist/crm-O6YG6777.js +227 -0
  147. package/dist/crm-VNAUSVC5.js +323 -0
  148. package/dist/currency-UVT3HEZT.js +88 -0
  149. package/dist/customers-VJ3TXILQ.js +59 -0
  150. package/dist/delete-3H377GOM.js +67 -0
  151. package/dist/delete-EH3XL26Z.js +57 -0
  152. package/dist/delete-QYSOAVP4.js +69 -0
  153. package/dist/demographics-GKJZ5PV2.js +141 -0
  154. package/dist/discard-46RALLBO.js +69 -0
  155. package/dist/discover-C4TG7JP7.js +172 -0
  156. package/dist/domain-JNNWJNQE.js +101 -0
  157. package/dist/download-3R5IHN5F.js +172 -0
  158. package/dist/draft-3L4SNDGO.js +283 -0
  159. package/dist/draft-EADHX7XL.js +335 -0
  160. package/dist/draft-TAM7IUPH.js +220 -0
  161. package/dist/draft-VSXBSXSX.js +308 -0
  162. package/dist/draft-XCYSZWA6.js +310 -0
  163. package/dist/engine/index.js +8 -7
  164. package/dist/experiments-JVGAKWFA.js +236 -0
  165. package/dist/facets-JG44XXAT.js +117 -0
  166. package/dist/feedback-3JCNU6MT.js +115 -0
  167. package/dist/feedback-3JCNU6MT.js.map +1 -0
  168. package/dist/feedback-record-7WXGKXNS.js +269 -0
  169. package/dist/feedback-record-7WXGKXNS.js.map +1 -0
  170. package/dist/fetch-SLDDORH4.js +179 -0
  171. package/dist/fit-GNQHRKP7.js +65 -0
  172. package/dist/flows-NRPABVUJ.js +250 -0
  173. package/dist/fonts-VN2QXPAQ.js +39 -0
  174. package/dist/forecast-SIX6AAVX.js +121 -0
  175. package/dist/forecast-ZXOSLITM.js +169 -0
  176. package/dist/funnel-QEZWKSFR.js +397 -0
  177. package/dist/generate-HOMLLUCN.js +263 -0
  178. package/dist/get-BXMLPLIC.js +82 -0
  179. package/dist/get-NF3SPPVX.js +59 -0
  180. package/dist/google-XVSL3XAB.js +3267 -0
  181. package/dist/google-ads-5NBAMFPB.js +198 -0
  182. package/dist/history-2U5OXDV7.js +102 -0
  183. package/dist/history-A6KMJRPZ.js +69 -0
  184. package/dist/history-IDVWUSYU.js +136 -0
  185. package/dist/hubspot-YPBNNVHC.js +782 -0
  186. package/dist/ideas-4Q7YBUGC.js +45 -0
  187. package/dist/images-BRBSRYEX.js +92 -0
  188. package/dist/ingest-AIOFOAQE.js +27 -0
  189. package/dist/ingest-HPEBFXCP.js +123 -0
  190. package/dist/insights-TR5EQAMA.js +132 -0
  191. package/dist/inspect-ITKB2QT3.js +192 -0
  192. package/dist/intent-E6HKRMNE.js +95 -0
  193. package/dist/keyword-gap-D4WAEJAH.js +130 -0
  194. package/dist/keyword-metrics-4UDT5GNW.js +200 -0
  195. package/dist/keywords-for-site-YQAQQIHJ.js +131 -0
  196. package/dist/landing-6JAIZH4H.js +28 -0
  197. package/dist/languages-AUAZIVL4.js +40 -0
  198. package/dist/leads-6XZRTPJL.js +115 -0
  199. package/dist/learn-VQGATNB4.js +207 -0
  200. package/dist/line-item-writes-TRTDQ55N.js +211 -0
  201. package/dist/line-items-SC73GQLQ.js +107 -0
  202. package/dist/link-ODLNZTZC.js +67 -0
  203. package/dist/linkedin-HPZP4MGS.js +1328 -0
  204. package/dist/linkedin-person-ELEPEST5.js +139 -0
  205. package/dist/list-26EOYW37.js +154 -0
  206. package/dist/list-GLN62MRB.js +67 -0
  207. package/dist/list-YLPOXOCI.js +306 -0
  208. package/dist/locations-D5N75BUK.js +69 -0
  209. package/dist/locations-P5PTCRSF.js +40 -0
  210. package/dist/log-66XLWNCD.js +95 -0
  211. package/dist/make-3ADCSNFC.js +1367 -0
  212. package/dist/make-3ADCSNFC.js.map +1 -0
  213. package/dist/map-3SGKGWSY.js +436 -0
  214. package/dist/mcp-ZSPJE3Y6.js +729 -0
  215. package/dist/media-sources-UBQCVRGK.js +35 -0
  216. package/dist/members-76XFDSMX.js +47 -0
  217. package/dist/metrics-XCD3IJSM.js +152 -0
  218. package/dist/models-WNK7Z6TR.js +155 -0
  219. package/dist/normalize-VC7HUODA.js +144 -0
  220. package/dist/options-5BPPM5N3.js +125 -0
  221. package/dist/organization-PXND43LQ.js +949 -0
  222. package/dist/performance-DDZOJ5GD.js +5565 -0
  223. package/dist/performance-Q25RDNM6.js +27 -0
  224. package/dist/pixels-KRK2B7M3.js +62 -0
  225. package/dist/promoted-tweet-writes-LIFJFF7N.js +183 -0
  226. package/dist/promoted-tweets-H5RMRQD2.js +119 -0
  227. package/dist/publish-LBHYEZW3.js +344 -0
  228. package/dist/query-A53T6QJF.js +62 -0
  229. package/dist/reddit-H4R23K27.js +29 -0
  230. package/dist/refresh-3QKUSERK.js +97 -0
  231. package/dist/release-JMYTQZLK.js +63 -0
  232. package/dist/relevant-pages-DOCKQEMZ.js +99 -0
  233. package/dist/remove-F7GEZMKB.js +53 -0
  234. package/dist/reopen-Y557X6IX.js +66 -0
  235. package/dist/rerun-RWBKQGVF.js +96 -0
  236. package/dist/rerun-RWBKQGVF.js.map +1 -0
  237. package/dist/research-3OJ5UZER.js +265 -0
  238. package/dist/research-AYO522XS.js +72 -0
  239. package/dist/reset-BL7M4LL7.js +57 -0
  240. package/dist/reset-PMVUQTYU.js +57 -0
  241. package/dist/resolve-CSWSGGK6.js +124 -0
  242. package/dist/retry-MVOPE2O2.js +65 -0
  243. package/dist/retry-WT46B5SC.js +63 -0
  244. package/dist/revenue-ZLE645Z5.js +91 -0
  245. package/dist/rules-Q6HWHFVU.js +99 -0
  246. package/dist/rules-add-7EPXWSQV.js +465 -0
  247. package/dist/run-4DE5XUVB.js +71 -0
  248. package/dist/run-PAND6N4V.js +69 -0
  249. package/dist/scaffold-ad-44INCR5V.js +1513 -0
  250. package/dist/scaffold-ad-44INCR5V.js.map +1 -0
  251. package/dist/scaffold-static-ad-ATXP44TE.js +1011 -0
  252. package/dist/scaffold-static-ad-ATXP44TE.js.map +1 -0
  253. package/dist/scaffold-video-L4FQWQ5A.js +885 -0
  254. package/dist/scaffold-video-L4FQWQ5A.js.map +1 -0
  255. package/dist/schedule-CSE2XFFF.js +64 -0
  256. package/dist/scheduled-agents-NXHXQZBO.js +55 -0
  257. package/dist/schema-QITMY7ZE.js +135 -0
  258. package/dist/search-HOYOSX2H.js +177 -0
  259. package/dist/select-E5TP7JR6.js +110 -0
  260. package/dist/select-E5TP7JR6.js.map +1 -0
  261. package/dist/set-prompt-QGV3IUIP.js +199 -0
  262. package/dist/set-prompt-QGV3IUIP.js.map +1 -0
  263. package/dist/setup-links-HQ6WVKEP.js +144 -0
  264. package/dist/shopify-6MLRXSC2.js +3958 -0
  265. package/dist/site-5B44TV46.js +180 -0
  266. package/dist/sources-OMINR6RG.js +30 -0
  267. package/dist/sources-PNEWSEBG.js +457 -0
  268. package/dist/stale-G2BPCBYZ.js +90 -0
  269. package/dist/stale-G2BPCBYZ.js.map +1 -0
  270. package/dist/status-QNXQNAKH.js +65 -0
  271. package/dist/studio-BNYFU6ZH.js +49 -0
  272. package/dist/sync-OYOS7HQL.js +57 -0
  273. package/dist/sync-definition-2VEFGHYK.js +70 -0
  274. package/dist/tags-56H6O7ZL.js +26 -0
  275. package/dist/tags-CYR2IPEJ.js +23 -0
  276. package/dist/tags-RBUYBAA6.js +227 -0
  277. package/dist/tags-WVJNOATS.js +23 -0
  278. package/dist/tags-ZTVOZOYP.js +23 -0
  279. package/dist/targeting-criteria-EZNZOUAE.js +113 -0
  280. package/dist/targets-CU7IUPV2.js +106 -0
  281. package/dist/testimonials-THJJYQ42.js +32 -0
  282. package/dist/themes-TSEMQ4EJ.js +95 -0
  283. package/dist/top-companies-W6DA3MZQ.js +111 -0
  284. package/dist/transcript-KZ74PK23.js +165 -0
  285. package/dist/translate-FQOYDETZ.js +603 -0
  286. package/dist/translate-FQOYDETZ.js.map +1 -0
  287. package/dist/triggers-OJKTDJSV.js +144 -0
  288. package/dist/unlink-ZE7464NK.js +70 -0
  289. package/dist/unstage-RGIPGM3E.js +88 -0
  290. package/dist/update-2VYVJCY2.js +192 -0
  291. package/dist/update-63MMKPHI.js +155 -0
  292. package/dist/update-JHWPEJN7.js +66 -0
  293. package/dist/update-WHHAH4IE.js +101 -0
  294. package/dist/upload-7XG5LU7C.js +130 -0
  295. package/dist/url-options-2BGF2D5E.js +131 -0
  296. package/dist/url-params-FBDTXQGY.js +101 -0
  297. package/dist/validate-Z3SRQKSO.js +125 -0
  298. package/dist/validate-Z3SRQKSO.js.map +1 -0
  299. package/dist/videos-4TLBI3E3.js +41 -0
  300. package/dist/viewer-check-ELVSS3DM.js +83 -0
  301. package/dist/web-LDR6HO5M.js +143 -0
  302. package/dist/winning-ads-7SWUVUDA.js +86 -0
  303. package/dist/write-commands-24FRMQW4.js +1525 -0
  304. package/dist/x-UOGRWXET.js +47 -0
  305. package/package.json +1 -1
  306. package/dist/account-2UXZ6CZJ.js +0 -82
  307. package/dist/account-OWMJG4IW.js +0 -82
  308. package/dist/account-reads-W2GAN335.js +0 -219
  309. package/dist/account-users-WLTQNPL7.js +0 -64
  310. package/dist/account-writes-TNADUSHW.js +0 -68
  311. package/dist/accounts-D3SQTZB7.js +0 -701
  312. package/dist/accounts-HRQFOTBJ.js +0 -80
  313. package/dist/actions-VJXED57L.js +0 -55
  314. package/dist/activecampaign-TNJIQA4C.js +0 -938
  315. package/dist/ad-group-writes-7BGCZA3M.js +0 -172
  316. package/dist/ad-groups-A6GU6EW5.js +0 -70
  317. package/dist/ad-writes-CEMCUDU2.js +0 -176
  318. package/dist/add-DRTKSLEQ.js +0 -107
  319. package/dist/add-LBHISK44.js +0 -305
  320. package/dist/ads-4EVKVAMR.js +0 -48
  321. package/dist/ads-OY455VCX.js +0 -79
  322. package/dist/advertisers-G6DZRBOK.js +0 -123
  323. package/dist/analytics-ANG42PKM.js +0 -2437
  324. package/dist/analytics-UI4AKUSF.js +0 -447
  325. package/dist/animate-KCSICY2N.js +0 -480
  326. package/dist/assign-5DFH6HBV.js +0 -80
  327. package/dist/audience-size-P6WIXOB3.js +0 -76
  328. package/dist/audiences-4ASLCNOF.js +0 -280
  329. package/dist/audit-LA4BSLXV.js +0 -154
  330. package/dist/autocomplete-XMG6E7TG.js +0 -114
  331. package/dist/avatars-4IFN4GZD.js +0 -38
  332. package/dist/bid-pricing-JEOG2Q3L.js +0 -103
  333. package/dist/brand-C6HUAK74.js +0 -22
  334. package/dist/brief-5BCPPBU3.js +0 -543
  335. package/dist/campaign-groups-IYQZSICZ.js +0 -99
  336. package/dist/campaign-writes-CVOOPZ35.js +0 -176
  337. package/dist/campaign-writes-YXI5UOPH.js +0 -168
  338. package/dist/campaigns-FW4WVD25.js +0 -113
  339. package/dist/campaigns-QMFHNG3N.js +0 -111
  340. package/dist/campaigns-TX37WHVL.js +0 -78
  341. package/dist/canvas-G4QXNPPE.js +0 -46
  342. package/dist/capabilities-7643Y2HU.js +0 -147
  343. package/dist/catalog-PTVQSATT.js +0 -65
  344. package/dist/catalog-PTVQSATT.js.map +0 -1
  345. package/dist/catalogs-YNIUP2AH.js +0 -130
  346. package/dist/changes-QUKBZVB3.js +0 -135
  347. package/dist/chatgpt-TIUBMATF.js +0 -47
  348. package/dist/chats-BGLAG4Q7.js +0 -279
  349. package/dist/check-MN5ZQ7RX.js +0 -107
  350. package/dist/chunk-2UJ5ABI6.js +0 -604
  351. package/dist/chunk-2XRFWXSA.js +0 -103
  352. package/dist/chunk-3OSBCYKA.js +0 -8954
  353. package/dist/chunk-3QQHPRRB.js +0 -89
  354. package/dist/chunk-3WTCMBDC.js +0 -1518
  355. package/dist/chunk-44ZRCSR7.js +0 -228
  356. package/dist/chunk-46YLDIQG.js +0 -4254
  357. package/dist/chunk-46YLDIQG.js.map +0 -1
  358. package/dist/chunk-4QITYZUH.js +0 -163
  359. package/dist/chunk-4XNF52NU.js +0 -429
  360. package/dist/chunk-4Y7IJ2PU.js +0 -5368
  361. package/dist/chunk-53BTYIMJ.js +0 -91
  362. package/dist/chunk-56OEYUJU.js +0 -61
  363. package/dist/chunk-5N47LB7X.js +0 -285
  364. package/dist/chunk-5UBFYJHF.js +0 -170
  365. package/dist/chunk-6PMJU7IU.js +0 -169
  366. package/dist/chunk-7GGLZOQN.js +0 -91
  367. package/dist/chunk-7I65KXU7.js +0 -98
  368. package/dist/chunk-BXUUKRMM.js +0 -46
  369. package/dist/chunk-BZTAEZLT.js +0 -51
  370. package/dist/chunk-CJQ77HO5.js +0 -1646
  371. package/dist/chunk-CKTVRR3D.js +0 -57
  372. package/dist/chunk-COS3TPHX.js +0 -377
  373. package/dist/chunk-CQ6HBFOB.js +0 -23
  374. package/dist/chunk-DJTWY7GL.js +0 -942
  375. package/dist/chunk-DJTWY7GL.js.map +0 -1
  376. package/dist/chunk-DWW5QSUF.js +0 -638
  377. package/dist/chunk-ENUCJ6AO.js +0 -148
  378. package/dist/chunk-ES3PWGS3.js +0 -438
  379. package/dist/chunk-FJDSL4O5.js +0 -910
  380. package/dist/chunk-FSTDWVXG.js +0 -455
  381. package/dist/chunk-FUR7R4D7.js +0 -249
  382. package/dist/chunk-HTT7RBRC.js +0 -846
  383. package/dist/chunk-HVJJEQDQ.js +0 -7234
  384. package/dist/chunk-I7AYMJZA.js +0 -783
  385. package/dist/chunk-IU5K42Q3.js +0 -831
  386. package/dist/chunk-JAC6JVCI.js +0 -26
  387. package/dist/chunk-JARRF5VX.js +0 -66
  388. package/dist/chunk-JEUFRIYS.js +0 -297
  389. package/dist/chunk-KITVYLEX.js +0 -843
  390. package/dist/chunk-L5VVKIMB.js +0 -203
  391. package/dist/chunk-M2MJ52HS.js +0 -676
  392. package/dist/chunk-MBSAHNMJ.js +0 -547
  393. package/dist/chunk-MCJ5I5LR.js +0 -3187
  394. package/dist/chunk-MCJ5I5LR.js.map +0 -1
  395. package/dist/chunk-MHZIOOT5.js +0 -197
  396. package/dist/chunk-MNOCC5AL.js +0 -207
  397. package/dist/chunk-MZPS46OR.js +0 -76
  398. package/dist/chunk-N6WHUUFH.js +0 -19
  399. package/dist/chunk-NA5Q473J.js +0 -3868
  400. package/dist/chunk-NA5Q473J.js.map +0 -1
  401. package/dist/chunk-OPUEQSKM.js +0 -122
  402. package/dist/chunk-OPUEQSKM.js.map +0 -1
  403. package/dist/chunk-OXLB5M5M.js +0 -592
  404. package/dist/chunk-OYNBUT5X.js +0 -479
  405. package/dist/chunk-PE4ZP7MX.js +0 -8914
  406. package/dist/chunk-PE4ZP7MX.js.map +0 -1
  407. package/dist/chunk-PIAG4UJT.js +0 -274
  408. package/dist/chunk-QKNPF6ZD.js +0 -24026
  409. package/dist/chunk-QKNPF6ZD.js.map +0 -1
  410. package/dist/chunk-QOBA6PHB.js +0 -131
  411. package/dist/chunk-RRC7F3QQ.js +0 -1919
  412. package/dist/chunk-S6VFDNSQ.js +0 -63
  413. package/dist/chunk-SEYCF446.js +0 -191
  414. package/dist/chunk-SF52UGHZ.js +0 -225
  415. package/dist/chunk-SG2TDQEE.js +0 -150
  416. package/dist/chunk-SWFZJROM.js +0 -64
  417. package/dist/chunk-UBDY5RE4.js +0 -387
  418. package/dist/chunk-UCNIJ2IW.js +0 -494
  419. package/dist/chunk-UFUYTWEF.js +0 -344
  420. package/dist/chunk-UROKPFIS.js +0 -142
  421. package/dist/chunk-VP4PO7FW.js +0 -392
  422. package/dist/chunk-VV6FDIP5.js +0 -224
  423. package/dist/chunk-WRTG3KXU.js +0 -156
  424. package/dist/chunk-WWLZ5RRU.js +0 -319
  425. package/dist/chunk-YE4RCEEJ.js +0 -167
  426. package/dist/chunk-YO54MA7R.js +0 -275
  427. package/dist/claim-2JNNC66N.js +0 -200
  428. package/dist/companies-4NJU5TLU.js +0 -198
  429. package/dist/company-QOYWS4W6.js +0 -308
  430. package/dist/complete-7FX2K3PV.js +0 -84
  431. package/dist/connect-H2HSPMRT.js +0 -45
  432. package/dist/conversation-4M7YMQOL.js +0 -96
  433. package/dist/conversion-report-G5JMZNYV.js +0 -127
  434. package/dist/conversion-upload-command-43PZFYT7.js +0 -439
  435. package/dist/conversion-writes-JQQCCGPO.js +0 -122
  436. package/dist/conversions-UO4CQNF6.js +0 -78
  437. package/dist/conversions-Z7FW7CFT.js +0 -140
  438. package/dist/create-4SFO4AQZ.js +0 -62
  439. package/dist/create-D5MA64KL.js +0 -239
  440. package/dist/create-GJ4ZMY3A.js +0 -210
  441. package/dist/create-QVY6DSYM.js +0 -135
  442. package/dist/creatives-ADH6HCCA.js +0 -58
  443. package/dist/creatives-R3XILT6D.js +0 -223
  444. package/dist/credentials-EQRB6XGZ.js +0 -290
  445. package/dist/critique-4YRRUNAU.js +0 -1451
  446. package/dist/critique-JCU2ATT6.js +0 -232
  447. package/dist/crm-AF6XOOSF.js +0 -323
  448. package/dist/crm-LSMFGR6R.js +0 -227
  449. package/dist/currency-4KNOOZUU.js +0 -88
  450. package/dist/customers-MM3VIZNA.js +0 -59
  451. package/dist/delete-CO2YBPTI.js +0 -67
  452. package/dist/delete-D7HTW32U.js +0 -57
  453. package/dist/delete-JUPBYK3H.js +0 -69
  454. package/dist/demographics-DK5JDY6M.js +0 -141
  455. package/dist/discard-DEJOM62Y.js +0 -69
  456. package/dist/discover-U6YLVLTF.js +0 -172
  457. package/dist/domain-MBOMV3CQ.js +0 -101
  458. package/dist/download-KN2I55SA.js +0 -172
  459. package/dist/draft-BMNBT37B.js +0 -283
  460. package/dist/draft-CGPVRRKC.js +0 -335
  461. package/dist/draft-F74OIT5O.js +0 -310
  462. package/dist/draft-FIEZWBIX.js +0 -308
  463. package/dist/draft-HZ5T6NOI.js +0 -220
  464. package/dist/experiments-YNJZCMQM.js +0 -236
  465. package/dist/facets-Y4OACBMC.js +0 -117
  466. package/dist/feedback-MORAVN52.js +0 -111
  467. package/dist/feedback-MORAVN52.js.map +0 -1
  468. package/dist/feedback-record-M3RB7H2C.js +0 -265
  469. package/dist/feedback-record-M3RB7H2C.js.map +0 -1
  470. package/dist/fetch-XU6QVWMS.js +0 -179
  471. package/dist/fit-IHUUFCGI.js +0 -65
  472. package/dist/flows-WSCIMXQX.js +0 -250
  473. package/dist/fonts-3QW7EDHE.js +0 -39
  474. package/dist/forecast-2WVHMSZP.js +0 -169
  475. package/dist/forecast-F25LSCM5.js +0 -121
  476. package/dist/funnel-35DYDBJH.js +0 -397
  477. package/dist/generate-Z7AROAES.js +0 -263
  478. package/dist/get-4CAX33L2.js +0 -59
  479. package/dist/get-N7X75ZJO.js +0 -82
  480. package/dist/google-M6XR7YGT.js +0 -3267
  481. package/dist/google-ads-NCSMNNND.js +0 -198
  482. package/dist/history-FGQ2H7XH.js +0 -69
  483. package/dist/history-LTOFKBMJ.js +0 -136
  484. package/dist/history-VJ254UXF.js +0 -102
  485. package/dist/hubspot-W2NM75YK.js +0 -782
  486. package/dist/ideas-54KFDNDM.js +0 -45
  487. package/dist/images-JOEVCCP6.js +0 -92
  488. package/dist/ingest-6R7XUL46.js +0 -27
  489. package/dist/ingest-VCIH5QDR.js +0 -123
  490. package/dist/insights-UXUUOQB7.js +0 -132
  491. package/dist/inspect-MGOR77FP.js +0 -192
  492. package/dist/intent-FZWPRUCI.js +0 -95
  493. package/dist/keyword-gap-4ECYPWXJ.js +0 -130
  494. package/dist/keyword-metrics-SBIRN5KC.js +0 -200
  495. package/dist/keywords-for-site-TLNPJHT2.js +0 -131
  496. package/dist/landing-ZICSVWKF.js +0 -28
  497. package/dist/languages-VNZQ5USL.js +0 -40
  498. package/dist/leads-JUQFNK55.js +0 -115
  499. package/dist/learn-A6BT25LQ.js +0 -207
  500. package/dist/line-item-writes-NW7A6HNH.js +0 -211
  501. package/dist/line-items-OAG3QMDE.js +0 -107
  502. package/dist/link-4VJ7FSOA.js +0 -67
  503. package/dist/linkedin-CKOWKD4M.js +0 -1328
  504. package/dist/linkedin-person-C22IDK7S.js +0 -139
  505. package/dist/list-2DKLO6AO.js +0 -67
  506. package/dist/list-CDDXHMJQ.js +0 -306
  507. package/dist/list-ZORO7PFP.js +0 -154
  508. package/dist/locations-4RDUHKVR.js +0 -69
  509. package/dist/locations-HATR6PSC.js +0 -40
  510. package/dist/log-OSJHKHPV.js +0 -95
  511. package/dist/make-7CIVNW77.js +0 -1366
  512. package/dist/make-7CIVNW77.js.map +0 -1
  513. package/dist/map-PMGZDXAN.js +0 -436
  514. package/dist/mcp-MOOOTRYG.js +0 -729
  515. package/dist/media-sources-5OYCKQ5J.js +0 -35
  516. package/dist/members-QG5IP5HM.js +0 -47
  517. package/dist/metrics-R4YS2JL6.js +0 -152
  518. package/dist/models-RJMZV5SH.js +0 -155
  519. package/dist/normalize-LATTXSL3.js +0 -144
  520. package/dist/options-KALH5TB7.js +0 -125
  521. package/dist/organization-AGCF7DUJ.js +0 -949
  522. package/dist/performance-SITVZQWX.js +0 -5565
  523. package/dist/performance-YNXPUSGJ.js +0 -27
  524. package/dist/pixels-TYJVE377.js +0 -62
  525. package/dist/promoted-tweet-writes-NAHPJ3VD.js +0 -183
  526. package/dist/promoted-tweets-2XQ4MWAC.js +0 -119
  527. package/dist/publish-UITYPUBD.js +0 -344
  528. package/dist/query-RE7NB2BK.js +0 -62
  529. package/dist/reddit-6XIARCTX.js +0 -29
  530. package/dist/refresh-6UCN7PDX.js +0 -97
  531. package/dist/release-IN65L23O.js +0 -63
  532. package/dist/relevant-pages-W7IM6YQW.js +0 -99
  533. package/dist/remove-X3XWVE2M.js +0 -53
  534. package/dist/reopen-RMMQ55CH.js +0 -66
  535. package/dist/rerun-ON6YCJAL.js +0 -95
  536. package/dist/rerun-ON6YCJAL.js.map +0 -1
  537. package/dist/research-LZBPCXIW.js +0 -72
  538. package/dist/research-W5KUOBXZ.js +0 -265
  539. package/dist/reset-MUWXTLIB.js +0 -57
  540. package/dist/reset-VQNKXFAF.js +0 -57
  541. package/dist/resolve-DMGWLMTC.js +0 -124
  542. package/dist/retry-YI4YLYTQ.js +0 -63
  543. package/dist/retry-ZQUJPKQH.js +0 -65
  544. package/dist/revenue-6YZAOMF6.js +0 -91
  545. package/dist/rules-FHVZEN4D.js +0 -99
  546. package/dist/rules-add-7X46VTIJ.js +0 -465
  547. package/dist/run-TA6HYFKZ.js +0 -69
  548. package/dist/run-YORKHK6S.js +0 -70
  549. package/dist/scaffold-ad-RHSHBCVV.js +0 -1512
  550. package/dist/scaffold-ad-RHSHBCVV.js.map +0 -1
  551. package/dist/scaffold-static-ad-XNOGCMPF.js +0 -1010
  552. package/dist/scaffold-static-ad-XNOGCMPF.js.map +0 -1
  553. package/dist/scaffold-video-XEVJQ7QZ.js +0 -884
  554. package/dist/scaffold-video-XEVJQ7QZ.js.map +0 -1
  555. package/dist/schedule-TMTLYULK.js +0 -64
  556. package/dist/scheduled-agents-TS3WLRCM.js +0 -55
  557. package/dist/schema-6S5ZEPBS.js +0 -135
  558. package/dist/search-LTUUAGZG.js +0 -177
  559. package/dist/select-BXBNFGVL.js +0 -106
  560. package/dist/select-BXBNFGVL.js.map +0 -1
  561. package/dist/set-prompt-JJWBB23C.js +0 -198
  562. package/dist/set-prompt-JJWBB23C.js.map +0 -1
  563. package/dist/setup-links-6ANVKZCE.js +0 -144
  564. package/dist/shopify-6ISTKZCA.js +0 -3958
  565. package/dist/site-OIV55MGO.js +0 -180
  566. package/dist/sources-5L4S5BQV.js +0 -457
  567. package/dist/sources-GLJWZFHZ.js +0 -30
  568. package/dist/stale-SK2SDGOT.js +0 -76
  569. package/dist/stale-SK2SDGOT.js.map +0 -1
  570. package/dist/status-TD7ISXC5.js +0 -65
  571. package/dist/studio-IDNM42JP.js +0 -49
  572. package/dist/sync-PVIFUXX3.js +0 -57
  573. package/dist/sync-definition-7NBT6LTK.js +0 -69
  574. package/dist/tags-3HB7N5WB.js +0 -23
  575. package/dist/tags-DG3XQ4SF.js +0 -227
  576. package/dist/tags-T4EN6XYE.js +0 -23
  577. package/dist/tags-T6THTVNP.js +0 -26
  578. package/dist/tags-XY6R2VJ6.js +0 -23
  579. package/dist/targeting-criteria-CL472KJO.js +0 -113
  580. package/dist/targets-7AQMSO6H.js +0 -106
  581. package/dist/testimonials-4QWVSEPU.js +0 -32
  582. package/dist/themes-ZTM4OVGK.js +0 -95
  583. package/dist/top-companies-PMFYOAFK.js +0 -111
  584. package/dist/transcript-YWFYNFWX.js +0 -165
  585. package/dist/translate-VMQHPX4B.js +0 -600
  586. package/dist/translate-VMQHPX4B.js.map +0 -1
  587. package/dist/triggers-JKXISN45.js +0 -144
  588. package/dist/unlink-IUAFDLBT.js +0 -70
  589. package/dist/unstage-ZYT5RNLK.js +0 -88
  590. package/dist/update-23Q4T2J5.js +0 -155
  591. package/dist/update-74VME6PN.js +0 -66
  592. package/dist/update-O22DAZVX.js +0 -192
  593. package/dist/update-QAWK3O7L.js +0 -101
  594. package/dist/upload-WASRCKS4.js +0 -130
  595. package/dist/url-options-M7RX2TD4.js +0 -131
  596. package/dist/url-params-E5ON6W2N.js +0 -101
  597. package/dist/validate-NB6PS5PF.js +0 -122
  598. package/dist/validate-NB6PS5PF.js.map +0 -1
  599. package/dist/videos-SS2Y6FJF.js +0 -41
  600. package/dist/viewer-check-CWS6OVM7.js +0 -83
  601. package/dist/web-HT22JFQR.js +0 -143
  602. package/dist/winning-ads-FXTP4PWZ.js +0 -86
  603. package/dist/write-commands-5YVQKO7E.js +0 -1525
  604. package/dist/x-KEMAY75C.js +0 -47
  605. /package/dist/{account-2UXZ6CZJ.js.map → account-BRRFMDXZ.js.map} +0 -0
  606. /package/dist/{account-OWMJG4IW.js.map → account-MQI7EZBH.js.map} +0 -0
  607. /package/dist/{account-reads-W2GAN335.js.map → account-reads-K6YDAOHX.js.map} +0 -0
  608. /package/dist/{account-users-WLTQNPL7.js.map → account-users-QS54ZEOD.js.map} +0 -0
  609. /package/dist/{account-writes-TNADUSHW.js.map → account-writes-PGGGP26M.js.map} +0 -0
  610. /package/dist/{accounts-HRQFOTBJ.js.map → accounts-H3U7LARM.js.map} +0 -0
  611. /package/dist/{accounts-D3SQTZB7.js.map → accounts-IW62WBX5.js.map} +0 -0
  612. /package/dist/{actions-VJXED57L.js.map → actions-2CUQFZNA.js.map} +0 -0
  613. /package/dist/{activecampaign-TNJIQA4C.js.map → activecampaign-WAMDVBUO.js.map} +0 -0
  614. /package/dist/{ad-group-writes-7BGCZA3M.js.map → ad-group-writes-ROUU6BHU.js.map} +0 -0
  615. /package/dist/{ad-groups-A6GU6EW5.js.map → ad-groups-Y2BSRLIN.js.map} +0 -0
  616. /package/dist/{ad-writes-CEMCUDU2.js.map → ad-writes-NF4LCGVP.js.map} +0 -0
  617. /package/dist/{add-LBHISK44.js.map → add-4P3CUHAN.js.map} +0 -0
  618. /package/dist/{add-DRTKSLEQ.js.map → add-UHWRBSFE.js.map} +0 -0
  619. /package/dist/{ads-OY455VCX.js.map → ads-CPMX3L4A.js.map} +0 -0
  620. /package/dist/{ads-4EVKVAMR.js.map → ads-TDN7OYSU.js.map} +0 -0
  621. /package/dist/{advertisers-G6DZRBOK.js.map → advertisers-6CHV5N2V.js.map} +0 -0
  622. /package/dist/{analytics-ANG42PKM.js.map → analytics-4GTUW42V.js.map} +0 -0
  623. /package/dist/{analytics-UI4AKUSF.js.map → analytics-MV2RQ6KR.js.map} +0 -0
  624. /package/dist/{animate-KCSICY2N.js.map → animate-EOSLSA7F.js.map} +0 -0
  625. /package/dist/{assign-5DFH6HBV.js.map → assign-RN5DGDS2.js.map} +0 -0
  626. /package/dist/{audience-size-P6WIXOB3.js.map → audience-size-7DYMCXDM.js.map} +0 -0
  627. /package/dist/{audiences-4ASLCNOF.js.map → audiences-VMGB2JZG.js.map} +0 -0
  628. /package/dist/{audit-LA4BSLXV.js.map → audit-7U7G2JKS.js.map} +0 -0
  629. /package/dist/{autocomplete-XMG6E7TG.js.map → autocomplete-E6YHJ3HH.js.map} +0 -0
  630. /package/dist/{avatars-4IFN4GZD.js.map → avatars-6JHVTSXH.js.map} +0 -0
  631. /package/dist/{bid-pricing-JEOG2Q3L.js.map → bid-pricing-J3OJK4J3.js.map} +0 -0
  632. /package/dist/{brand-C6HUAK74.js.map → brand-3EAQFDYN.js.map} +0 -0
  633. /package/dist/{brief-5BCPPBU3.js.map → brief-ADGCGC3H.js.map} +0 -0
  634. /package/dist/{campaign-groups-IYQZSICZ.js.map → campaign-groups-GN7D5UXE.js.map} +0 -0
  635. /package/dist/{campaign-writes-YXI5UOPH.js.map → campaign-writes-HKWI6GYU.js.map} +0 -0
  636. /package/dist/{campaign-writes-CVOOPZ35.js.map → campaign-writes-UORRIIWY.js.map} +0 -0
  637. /package/dist/{campaigns-FW4WVD25.js.map → campaigns-5I76AV7F.js.map} +0 -0
  638. /package/dist/{campaigns-QMFHNG3N.js.map → campaigns-BEXDLBT3.js.map} +0 -0
  639. /package/dist/{campaigns-TX37WHVL.js.map → campaigns-GONROKTU.js.map} +0 -0
  640. /package/dist/{canvas-G4QXNPPE.js.map → canvas-CHV34G62.js.map} +0 -0
  641. /package/dist/{capabilities-7643Y2HU.js.map → capabilities-VKBIQ2BR.js.map} +0 -0
  642. /package/dist/{catalogs-YNIUP2AH.js.map → catalogs-LXEM7NNC.js.map} +0 -0
  643. /package/dist/{changes-QUKBZVB3.js.map → changes-4OYC4NMW.js.map} +0 -0
  644. /package/dist/{chatgpt-TIUBMATF.js.map → chatgpt-XV6CVKLN.js.map} +0 -0
  645. /package/dist/{chats-BGLAG4Q7.js.map → chats-W35ZPZEW.js.map} +0 -0
  646. /package/dist/{check-MN5ZQ7RX.js.map → check-3D63D4ZT.js.map} +0 -0
  647. /package/dist/{chunk-OXLB5M5M.js.map → chunk-2PC26XRF.js.map} +0 -0
  648. /package/dist/{chunk-ENUCJ6AO.js.map → chunk-2UZHRLLO.js.map} +0 -0
  649. /package/dist/{chunk-I7AYMJZA.js.map → chunk-45EERHDB.js.map} +0 -0
  650. /package/dist/{chunk-FUR7R4D7.js.map → chunk-55B4AJY3.js.map} +0 -0
  651. /package/dist/{chunk-VP4PO7FW.js.map → chunk-56UWXQEN.js.map} +0 -0
  652. /package/dist/{chunk-YO54MA7R.js.map → chunk-5G5QFFJY.js.map} +0 -0
  653. /package/dist/{chunk-ES3PWGS3.js.map → chunk-5GHKZLID.js.map} +0 -0
  654. /package/dist/{chunk-3QQHPRRB.js.map → chunk-5HGAO4ZI.js.map} +0 -0
  655. /package/dist/{chunk-56OEYUJU.js.map → chunk-5YN53OAA.js.map} +0 -0
  656. /package/dist/{chunk-5N47LB7X.js.map → chunk-6CCEEVXJ.js.map} +0 -0
  657. /package/dist/{chunk-DWW5QSUF.js.map → chunk-6HGLQJ6A.js.map} +0 -0
  658. /package/dist/{chunk-JAC6JVCI.js.map → chunk-6OIKNJ7G.js.map} +0 -0
  659. /package/dist/{chunk-BXUUKRMM.js.map → chunk-6QGBBX7F.js.map} +0 -0
  660. /package/dist/{chunk-N6WHUUFH.js.map → chunk-6RTZPBAT.js.map} +0 -0
  661. /package/dist/{chunk-L5VVKIMB.js.map → chunk-7MY3QHGA.js.map} +0 -0
  662. /package/dist/{chunk-MBSAHNMJ.js.map → chunk-BKOUVU6X.js.map} +0 -0
  663. /package/dist/{chunk-5UBFYJHF.js.map → chunk-CBQPKCFE.js.map} +0 -0
  664. /package/dist/{chunk-CKTVRR3D.js.map → chunk-CWZ2ODJQ.js.map} +0 -0
  665. /package/dist/{chunk-KITVYLEX.js.map → chunk-DGZYZWMK.js.map} +0 -0
  666. /package/dist/{chunk-UFUYTWEF.js.map → chunk-DMA67YC3.js.map} +0 -0
  667. /package/dist/{chunk-HVJJEQDQ.js.map → chunk-DYOUJERF.js.map} +0 -0
  668. /package/dist/{chunk-JEUFRIYS.js.map → chunk-E3FMS5DA.js.map} +0 -0
  669. /package/dist/{chunk-YE4RCEEJ.js.map → chunk-EIRGJD3Q.js.map} +0 -0
  670. /package/dist/{chunk-3WTCMBDC.js.map → chunk-G3MEYGXC.js.map} +0 -0
  671. /package/dist/{chunk-IU5K42Q3.js.map → chunk-G3MN4HIX.js.map} +0 -0
  672. /package/dist/{chunk-MNOCC5AL.js.map → chunk-G53CUQZV.js.map} +0 -0
  673. /package/dist/{chunk-FSTDWVXG.js.map → chunk-GPZVYXJZ.js.map} +0 -0
  674. /package/dist/{chunk-WRTG3KXU.js.map → chunk-HGHVNUJT.js.map} +0 -0
  675. /package/dist/{chunk-44ZRCSR7.js.map → chunk-IZABTTW5.js.map} +0 -0
  676. /package/dist/{chunk-BZTAEZLT.js.map → chunk-J3HA4RFY.js.map} +0 -0
  677. /package/dist/{chunk-2XRFWXSA.js.map → chunk-JGOYO7I2.js.map} +0 -0
  678. /package/dist/{chunk-3OSBCYKA.js.map → chunk-JUF6Q5X7.js.map} +0 -0
  679. /package/dist/{chunk-OYNBUT5X.js.map → chunk-KAAYVKBH.js.map} +0 -0
  680. /package/dist/{chunk-4XNF52NU.js.map → chunk-KUM36NSV.js.map} +0 -0
  681. /package/dist/{chunk-53BTYIMJ.js.map → chunk-MHSVWQK6.js.map} +0 -0
  682. /package/dist/{chunk-S6VFDNSQ.js.map → chunk-MTV2RSGY.js.map} +0 -0
  683. /package/dist/{chunk-7GGLZOQN.js.map → chunk-N4BK6OKX.js.map} +0 -0
  684. /package/dist/{chunk-COS3TPHX.js.map → chunk-NP3FPCPN.js.map} +0 -0
  685. /package/dist/{chunk-2UJ5ABI6.js.map → chunk-OAXQPLTG.js.map} +0 -0
  686. /package/dist/{chunk-HTT7RBRC.js.map → chunk-OI2CKYAQ.js.map} +0 -0
  687. /package/dist/{chunk-6PMJU7IU.js.map → chunk-QUYDMAQN.js.map} +0 -0
  688. /package/dist/{chunk-UBDY5RE4.js.map → chunk-RIA5RXPL.js.map} +0 -0
  689. /package/dist/{chunk-MZPS46OR.js.map → chunk-SIKCVWM3.js.map} +0 -0
  690. /package/dist/{chunk-SF52UGHZ.js.map → chunk-T65Y7N7H.js.map} +0 -0
  691. /package/dist/{chunk-VV6FDIP5.js.map → chunk-T75WL56Z.js.map} +0 -0
  692. /package/dist/{chunk-FJDSL4O5.js.map → chunk-TGCDXZ5X.js.map} +0 -0
  693. /package/dist/{chunk-CJQ77HO5.js.map → chunk-TOUF5ME6.js.map} +0 -0
  694. /package/dist/{chunk-SEYCF446.js.map → chunk-TWCS6FSC.js.map} +0 -0
  695. /package/dist/{chunk-M2MJ52HS.js.map → chunk-UPXPBA4W.js.map} +0 -0
  696. /package/dist/{chunk-SG2TDQEE.js.map → chunk-URMAEVZO.js.map} +0 -0
  697. /package/dist/{chunk-MHZIOOT5.js.map → chunk-UUWUJ64R.js.map} +0 -0
  698. /package/dist/{chunk-UCNIJ2IW.js.map → chunk-VGUGFRWF.js.map} +0 -0
  699. /package/dist/{chunk-WWLZ5RRU.js.map → chunk-WEQZ563U.js.map} +0 -0
  700. /package/dist/{chunk-4QITYZUH.js.map → chunk-WUCTGDV7.js.map} +0 -0
  701. /package/dist/{chunk-4Y7IJ2PU.js.map → chunk-XCRYRVKK.js.map} +0 -0
  702. /package/dist/{chunk-QOBA6PHB.js.map → chunk-XJ5TX772.js.map} +0 -0
  703. /package/dist/{chunk-PIAG4UJT.js.map → chunk-XPIBSDG4.js.map} +0 -0
  704. /package/dist/{chunk-RRC7F3QQ.js.map → chunk-Y6MLSN6W.js.map} +0 -0
  705. /package/dist/{chunk-JARRF5VX.js.map → chunk-YBFZJ5EB.js.map} +0 -0
  706. /package/dist/{chunk-UROKPFIS.js.map → chunk-YR3OPPUE.js.map} +0 -0
  707. /package/dist/{chunk-SWFZJROM.js.map → chunk-YXQFCQX2.js.map} +0 -0
  708. /package/dist/{chunk-7I65KXU7.js.map → chunk-Z3Y67AH6.js.map} +0 -0
  709. /package/dist/{chunk-CQ6HBFOB.js.map → chunk-ZKRRYVDG.js.map} +0 -0
  710. /package/dist/{claim-2JNNC66N.js.map → claim-DWGPEVJN.js.map} +0 -0
  711. /package/dist/{companies-4NJU5TLU.js.map → companies-3VT7OJAA.js.map} +0 -0
  712. /package/dist/{company-QOYWS4W6.js.map → company-XEPW45AT.js.map} +0 -0
  713. /package/dist/{complete-7FX2K3PV.js.map → complete-AEX34ICU.js.map} +0 -0
  714. /package/dist/{connect-H2HSPMRT.js.map → connect-TF4FCXDV.js.map} +0 -0
  715. /package/dist/{conversation-4M7YMQOL.js.map → conversation-6WWZMPAB.js.map} +0 -0
  716. /package/dist/{conversion-report-G5JMZNYV.js.map → conversion-report-I6R2FDCD.js.map} +0 -0
  717. /package/dist/{conversion-upload-command-43PZFYT7.js.map → conversion-upload-command-QD6MGLY4.js.map} +0 -0
  718. /package/dist/{conversion-writes-JQQCCGPO.js.map → conversion-writes-H2JOAORW.js.map} +0 -0
  719. /package/dist/{conversions-Z7FW7CFT.js.map → conversions-D46PQRWF.js.map} +0 -0
  720. /package/dist/{conversions-UO4CQNF6.js.map → conversions-WGW43FUE.js.map} +0 -0
  721. /package/dist/{create-4SFO4AQZ.js.map → create-7WV7XWZV.js.map} +0 -0
  722. /package/dist/{create-GJ4ZMY3A.js.map → create-OUZZLPQK.js.map} +0 -0
  723. /package/dist/{create-QVY6DSYM.js.map → create-QRT6O5PN.js.map} +0 -0
  724. /package/dist/{create-D5MA64KL.js.map → create-WSEYNFTP.js.map} +0 -0
  725. /package/dist/{creatives-R3XILT6D.js.map → creatives-BSZY7VDQ.js.map} +0 -0
  726. /package/dist/{creatives-ADH6HCCA.js.map → creatives-DBDFDHX7.js.map} +0 -0
  727. /package/dist/{credentials-EQRB6XGZ.js.map → credentials-P7GQYIE3.js.map} +0 -0
  728. /package/dist/{critique-JCU2ATT6.js.map → critique-6F4FWQN5.js.map} +0 -0
  729. /package/dist/{critique-4YRRUNAU.js.map → critique-X2YDOMON.js.map} +0 -0
  730. /package/dist/{crm-LSMFGR6R.js.map → crm-O6YG6777.js.map} +0 -0
  731. /package/dist/{crm-AF6XOOSF.js.map → crm-VNAUSVC5.js.map} +0 -0
  732. /package/dist/{currency-4KNOOZUU.js.map → currency-UVT3HEZT.js.map} +0 -0
  733. /package/dist/{customers-MM3VIZNA.js.map → customers-VJ3TXILQ.js.map} +0 -0
  734. /package/dist/{delete-CO2YBPTI.js.map → delete-3H377GOM.js.map} +0 -0
  735. /package/dist/{delete-D7HTW32U.js.map → delete-EH3XL26Z.js.map} +0 -0
  736. /package/dist/{delete-JUPBYK3H.js.map → delete-QYSOAVP4.js.map} +0 -0
  737. /package/dist/{demographics-DK5JDY6M.js.map → demographics-GKJZ5PV2.js.map} +0 -0
  738. /package/dist/{discard-DEJOM62Y.js.map → discard-46RALLBO.js.map} +0 -0
  739. /package/dist/{discover-U6YLVLTF.js.map → discover-C4TG7JP7.js.map} +0 -0
  740. /package/dist/{domain-MBOMV3CQ.js.map → domain-JNNWJNQE.js.map} +0 -0
  741. /package/dist/{download-KN2I55SA.js.map → download-3R5IHN5F.js.map} +0 -0
  742. /package/dist/{draft-BMNBT37B.js.map → draft-3L4SNDGO.js.map} +0 -0
  743. /package/dist/{draft-CGPVRRKC.js.map → draft-EADHX7XL.js.map} +0 -0
  744. /package/dist/{draft-HZ5T6NOI.js.map → draft-TAM7IUPH.js.map} +0 -0
  745. /package/dist/{draft-FIEZWBIX.js.map → draft-VSXBSXSX.js.map} +0 -0
  746. /package/dist/{draft-F74OIT5O.js.map → draft-XCYSZWA6.js.map} +0 -0
  747. /package/dist/{experiments-YNJZCMQM.js.map → experiments-JVGAKWFA.js.map} +0 -0
  748. /package/dist/{facets-Y4OACBMC.js.map → facets-JG44XXAT.js.map} +0 -0
  749. /package/dist/{fetch-XU6QVWMS.js.map → fetch-SLDDORH4.js.map} +0 -0
  750. /package/dist/{fit-IHUUFCGI.js.map → fit-GNQHRKP7.js.map} +0 -0
  751. /package/dist/{flows-WSCIMXQX.js.map → flows-NRPABVUJ.js.map} +0 -0
  752. /package/dist/{fonts-3QW7EDHE.js.map → fonts-VN2QXPAQ.js.map} +0 -0
  753. /package/dist/{forecast-F25LSCM5.js.map → forecast-SIX6AAVX.js.map} +0 -0
  754. /package/dist/{forecast-2WVHMSZP.js.map → forecast-ZXOSLITM.js.map} +0 -0
  755. /package/dist/{funnel-35DYDBJH.js.map → funnel-QEZWKSFR.js.map} +0 -0
  756. /package/dist/{generate-Z7AROAES.js.map → generate-HOMLLUCN.js.map} +0 -0
  757. /package/dist/{get-N7X75ZJO.js.map → get-BXMLPLIC.js.map} +0 -0
  758. /package/dist/{get-4CAX33L2.js.map → get-NF3SPPVX.js.map} +0 -0
  759. /package/dist/{google-M6XR7YGT.js.map → google-XVSL3XAB.js.map} +0 -0
  760. /package/dist/{google-ads-NCSMNNND.js.map → google-ads-5NBAMFPB.js.map} +0 -0
  761. /package/dist/{history-VJ254UXF.js.map → history-2U5OXDV7.js.map} +0 -0
  762. /package/dist/{history-FGQ2H7XH.js.map → history-A6KMJRPZ.js.map} +0 -0
  763. /package/dist/{history-LTOFKBMJ.js.map → history-IDVWUSYU.js.map} +0 -0
  764. /package/dist/{hubspot-W2NM75YK.js.map → hubspot-YPBNNVHC.js.map} +0 -0
  765. /package/dist/{ideas-54KFDNDM.js.map → ideas-4Q7YBUGC.js.map} +0 -0
  766. /package/dist/{images-JOEVCCP6.js.map → images-BRBSRYEX.js.map} +0 -0
  767. /package/dist/{ingest-6R7XUL46.js.map → ingest-AIOFOAQE.js.map} +0 -0
  768. /package/dist/{ingest-VCIH5QDR.js.map → ingest-HPEBFXCP.js.map} +0 -0
  769. /package/dist/{insights-UXUUOQB7.js.map → insights-TR5EQAMA.js.map} +0 -0
  770. /package/dist/{inspect-MGOR77FP.js.map → inspect-ITKB2QT3.js.map} +0 -0
  771. /package/dist/{intent-FZWPRUCI.js.map → intent-E6HKRMNE.js.map} +0 -0
  772. /package/dist/{keyword-gap-4ECYPWXJ.js.map → keyword-gap-D4WAEJAH.js.map} +0 -0
  773. /package/dist/{keyword-metrics-SBIRN5KC.js.map → keyword-metrics-4UDT5GNW.js.map} +0 -0
  774. /package/dist/{keywords-for-site-TLNPJHT2.js.map → keywords-for-site-YQAQQIHJ.js.map} +0 -0
  775. /package/dist/{landing-ZICSVWKF.js.map → landing-6JAIZH4H.js.map} +0 -0
  776. /package/dist/{languages-VNZQ5USL.js.map → languages-AUAZIVL4.js.map} +0 -0
  777. /package/dist/{leads-JUQFNK55.js.map → leads-6XZRTPJL.js.map} +0 -0
  778. /package/dist/{learn-A6BT25LQ.js.map → learn-VQGATNB4.js.map} +0 -0
  779. /package/dist/{line-item-writes-NW7A6HNH.js.map → line-item-writes-TRTDQ55N.js.map} +0 -0
  780. /package/dist/{line-items-OAG3QMDE.js.map → line-items-SC73GQLQ.js.map} +0 -0
  781. /package/dist/{link-4VJ7FSOA.js.map → link-ODLNZTZC.js.map} +0 -0
  782. /package/dist/{linkedin-CKOWKD4M.js.map → linkedin-HPZP4MGS.js.map} +0 -0
  783. /package/dist/{linkedin-person-C22IDK7S.js.map → linkedin-person-ELEPEST5.js.map} +0 -0
  784. /package/dist/{list-ZORO7PFP.js.map → list-26EOYW37.js.map} +0 -0
  785. /package/dist/{list-2DKLO6AO.js.map → list-GLN62MRB.js.map} +0 -0
  786. /package/dist/{list-CDDXHMJQ.js.map → list-YLPOXOCI.js.map} +0 -0
  787. /package/dist/{locations-4RDUHKVR.js.map → locations-D5N75BUK.js.map} +0 -0
  788. /package/dist/{locations-HATR6PSC.js.map → locations-P5PTCRSF.js.map} +0 -0
  789. /package/dist/{log-OSJHKHPV.js.map → log-66XLWNCD.js.map} +0 -0
  790. /package/dist/{map-PMGZDXAN.js.map → map-3SGKGWSY.js.map} +0 -0
  791. /package/dist/{mcp-MOOOTRYG.js.map → mcp-ZSPJE3Y6.js.map} +0 -0
  792. /package/dist/{media-sources-5OYCKQ5J.js.map → media-sources-UBQCVRGK.js.map} +0 -0
  793. /package/dist/{members-QG5IP5HM.js.map → members-76XFDSMX.js.map} +0 -0
  794. /package/dist/{metrics-R4YS2JL6.js.map → metrics-XCD3IJSM.js.map} +0 -0
  795. /package/dist/{models-RJMZV5SH.js.map → models-WNK7Z6TR.js.map} +0 -0
  796. /package/dist/{normalize-LATTXSL3.js.map → normalize-VC7HUODA.js.map} +0 -0
  797. /package/dist/{options-KALH5TB7.js.map → options-5BPPM5N3.js.map} +0 -0
  798. /package/dist/{organization-AGCF7DUJ.js.map → organization-PXND43LQ.js.map} +0 -0
  799. /package/dist/{performance-SITVZQWX.js.map → performance-DDZOJ5GD.js.map} +0 -0
  800. /package/dist/{performance-YNXPUSGJ.js.map → performance-Q25RDNM6.js.map} +0 -0
  801. /package/dist/{pixels-TYJVE377.js.map → pixels-KRK2B7M3.js.map} +0 -0
  802. /package/dist/{promoted-tweet-writes-NAHPJ3VD.js.map → promoted-tweet-writes-LIFJFF7N.js.map} +0 -0
  803. /package/dist/{promoted-tweets-2XQ4MWAC.js.map → promoted-tweets-H5RMRQD2.js.map} +0 -0
  804. /package/dist/{publish-UITYPUBD.js.map → publish-LBHYEZW3.js.map} +0 -0
  805. /package/dist/{query-RE7NB2BK.js.map → query-A53T6QJF.js.map} +0 -0
  806. /package/dist/{reddit-6XIARCTX.js.map → reddit-H4R23K27.js.map} +0 -0
  807. /package/dist/{refresh-6UCN7PDX.js.map → refresh-3QKUSERK.js.map} +0 -0
  808. /package/dist/{release-IN65L23O.js.map → release-JMYTQZLK.js.map} +0 -0
  809. /package/dist/{relevant-pages-W7IM6YQW.js.map → relevant-pages-DOCKQEMZ.js.map} +0 -0
  810. /package/dist/{remove-X3XWVE2M.js.map → remove-F7GEZMKB.js.map} +0 -0
  811. /package/dist/{reopen-RMMQ55CH.js.map → reopen-Y557X6IX.js.map} +0 -0
  812. /package/dist/{research-W5KUOBXZ.js.map → research-3OJ5UZER.js.map} +0 -0
  813. /package/dist/{research-LZBPCXIW.js.map → research-AYO522XS.js.map} +0 -0
  814. /package/dist/{reset-MUWXTLIB.js.map → reset-BL7M4LL7.js.map} +0 -0
  815. /package/dist/{reset-VQNKXFAF.js.map → reset-PMVUQTYU.js.map} +0 -0
  816. /package/dist/{resolve-DMGWLMTC.js.map → resolve-CSWSGGK6.js.map} +0 -0
  817. /package/dist/{retry-ZQUJPKQH.js.map → retry-MVOPE2O2.js.map} +0 -0
  818. /package/dist/{retry-YI4YLYTQ.js.map → retry-WT46B5SC.js.map} +0 -0
  819. /package/dist/{revenue-6YZAOMF6.js.map → revenue-ZLE645Z5.js.map} +0 -0
  820. /package/dist/{rules-FHVZEN4D.js.map → rules-Q6HWHFVU.js.map} +0 -0
  821. /package/dist/{rules-add-7X46VTIJ.js.map → rules-add-7EPXWSQV.js.map} +0 -0
  822. /package/dist/{run-YORKHK6S.js.map → run-4DE5XUVB.js.map} +0 -0
  823. /package/dist/{run-TA6HYFKZ.js.map → run-PAND6N4V.js.map} +0 -0
  824. /package/dist/{schedule-TMTLYULK.js.map → schedule-CSE2XFFF.js.map} +0 -0
  825. /package/dist/{scheduled-agents-TS3WLRCM.js.map → scheduled-agents-NXHXQZBO.js.map} +0 -0
  826. /package/dist/{schema-6S5ZEPBS.js.map → schema-QITMY7ZE.js.map} +0 -0
  827. /package/dist/{search-LTUUAGZG.js.map → search-HOYOSX2H.js.map} +0 -0
  828. /package/dist/{setup-links-6ANVKZCE.js.map → setup-links-HQ6WVKEP.js.map} +0 -0
  829. /package/dist/{shopify-6ISTKZCA.js.map → shopify-6MLRXSC2.js.map} +0 -0
  830. /package/dist/{site-OIV55MGO.js.map → site-5B44TV46.js.map} +0 -0
  831. /package/dist/{sources-GLJWZFHZ.js.map → sources-OMINR6RG.js.map} +0 -0
  832. /package/dist/{sources-5L4S5BQV.js.map → sources-PNEWSEBG.js.map} +0 -0
  833. /package/dist/{status-TD7ISXC5.js.map → status-QNXQNAKH.js.map} +0 -0
  834. /package/dist/{studio-IDNM42JP.js.map → studio-BNYFU6ZH.js.map} +0 -0
  835. /package/dist/{sync-PVIFUXX3.js.map → sync-OYOS7HQL.js.map} +0 -0
  836. /package/dist/{sync-definition-7NBT6LTK.js.map → sync-definition-2VEFGHYK.js.map} +0 -0
  837. /package/dist/{tags-T6THTVNP.js.map → tags-56H6O7ZL.js.map} +0 -0
  838. /package/dist/{tags-3HB7N5WB.js.map → tags-CYR2IPEJ.js.map} +0 -0
  839. /package/dist/{tags-DG3XQ4SF.js.map → tags-RBUYBAA6.js.map} +0 -0
  840. /package/dist/{tags-XY6R2VJ6.js.map → tags-WVJNOATS.js.map} +0 -0
  841. /package/dist/{tags-T4EN6XYE.js.map → tags-ZTVOZOYP.js.map} +0 -0
  842. /package/dist/{targeting-criteria-CL472KJO.js.map → targeting-criteria-EZNZOUAE.js.map} +0 -0
  843. /package/dist/{targets-7AQMSO6H.js.map → targets-CU7IUPV2.js.map} +0 -0
  844. /package/dist/{testimonials-4QWVSEPU.js.map → testimonials-THJJYQ42.js.map} +0 -0
  845. /package/dist/{themes-ZTM4OVGK.js.map → themes-TSEMQ4EJ.js.map} +0 -0
  846. /package/dist/{top-companies-PMFYOAFK.js.map → top-companies-W6DA3MZQ.js.map} +0 -0
  847. /package/dist/{transcript-YWFYNFWX.js.map → transcript-KZ74PK23.js.map} +0 -0
  848. /package/dist/{triggers-JKXISN45.js.map → triggers-OJKTDJSV.js.map} +0 -0
  849. /package/dist/{unlink-IUAFDLBT.js.map → unlink-ZE7464NK.js.map} +0 -0
  850. /package/dist/{unstage-ZYT5RNLK.js.map → unstage-RGIPGM3E.js.map} +0 -0
  851. /package/dist/{update-O22DAZVX.js.map → update-2VYVJCY2.js.map} +0 -0
  852. /package/dist/{update-23Q4T2J5.js.map → update-63MMKPHI.js.map} +0 -0
  853. /package/dist/{update-74VME6PN.js.map → update-JHWPEJN7.js.map} +0 -0
  854. /package/dist/{update-QAWK3O7L.js.map → update-WHHAH4IE.js.map} +0 -0
  855. /package/dist/{upload-WASRCKS4.js.map → upload-7XG5LU7C.js.map} +0 -0
  856. /package/dist/{url-options-M7RX2TD4.js.map → url-options-2BGF2D5E.js.map} +0 -0
  857. /package/dist/{url-params-E5ON6W2N.js.map → url-params-FBDTXQGY.js.map} +0 -0
  858. /package/dist/{videos-SS2Y6FJF.js.map → videos-4TLBI3E3.js.map} +0 -0
  859. /package/dist/{viewer-check-CWS6OVM7.js.map → viewer-check-ELVSS3DM.js.map} +0 -0
  860. /package/dist/{web-HT22JFQR.js.map → web-LDR6HO5M.js.map} +0 -0
  861. /package/dist/{winning-ads-FXTP4PWZ.js.map → winning-ads-7SWUVUDA.js.map} +0 -0
  862. /package/dist/{write-commands-5YVQKO7E.js.map → write-commands-24FRMQW4.js.map} +0 -0
  863. /package/dist/{x-KEMAY75C.js.map → x-UOGRWXET.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/engine/index.ts","../src/engine/engine/executor.ts","../src/engine/lib/concurrency.ts","../src/engine/lib/ulid.ts","../src/engine/storage/output-writer.ts","../src/engine/engine/cache-key.ts","../src/engine/engine/refs.ts","../src/engine/engine/step-cache.ts","../src/engine/engine/registry.ts","../src/engine/nodes/local/audioTimeline.ts","../src/engine/nodes/local/lib/cli-runner.ts","../src/engine/nodes/local/avMux.ts","../src/engine/nodes/local/collect.ts","../src/engine/nodes/local/ffmpeg.ts","../src/engine/nodes/local/fontSpecimen.ts","../src/engine/nodes/local/lib/assets.ts","../src/engine/nodes/local/hyperframe.ts","../src/engine/engine/composition-hash.ts","../src/engine/engine/composition-meta.ts","../src/engine/nodes/local/lib/composition-stage.ts","../src/engine/nodes/local/lib/composition-static-check.ts","../src/engine/nodes/local/lib/hyperframe-check.ts","../src/engine/nodes/local/lib/caption-style.ts","../src/engine/nodes/local/lib/hyperframe-meta.ts","../src/engine/nodes/local/lib/templating.ts","../src/engine/nodes/local/lib/hyperframe-errors.ts","../src/engine/nodes/local/hyperframe-snapshot.ts","../src/engine/nodes/local/imagemagick.ts","../src/engine/nodes/local/staticFormat.ts","../src/engine/nodes/remote/image.ts","../src/engine/nodes/remote/registry-params.ts","../src/engine/nodes/local/lib/node-steps.ts","../src/engine/nodes/local/lib/subject-boxes.ts","../src/engine/nodes/local/lib/plate-panels.ts","../src/engine/nodes/local/lib/subject-crop.ts","../src/engine/nodes/local/lib/picture-memo.ts","../src/engine/nodes/local/lib/words-band.ts","../src/engine/nodes/local/lib/safe-fit.ts","../src/engine/nodes/local/lib/words-layer.ts","../src/engine/nodes/local/lib/whole-render.ts","../src/engine/nodes/local/staticLogo.ts","../src/engine/nodes/local/staticNative.ts","../src/engine/nodes/local/lib/native-assets.ts","../src/engine/nodes/local/staticPlace.ts","../src/engine/nodes/local/lib/extend-fit.ts","../src/engine/nodes/local/staticPlate.ts","../src/engine/nodes/local/lib/plate-extend.ts","../src/engine/nodes/local/lib/size-consistency.ts","../src/engine/nodes/local/staticPrefilter.ts","../src/engine/nodes/local/staticSafeFit.ts","../src/engine/nodes/local/text.ts","../src/engine/nodes/local/videoConcat.ts","../src/engine/nodes/remote/audioVoiceConvert.ts","../src/engine/nodes/remote/dialogue.ts","../src/engine/nodes/remote/imageAspectAdapt.ts","../src/engine/nodes/remote/imageBackgroundRemove.ts","../src/engine/nodes/remote/imageDescribe.ts","../src/engine/nodes/remote/imageLayerize.ts","../src/engine/nodes/remote/imageReferenceSheet.ts","../src/engine/nodes/remote/imageSearch.ts","../src/engine/nodes/remote/imageSelect.ts","../src/engine/nodes/remote/music.ts","../src/engine/nodes/remote/soundEffect.ts","../src/engine/nodes/remote/textGenerate.ts","../src/engine/nodes/remote/tts.ts","../src/engine/nodes/remote/video.ts","../src/engine/nodes/remote/videoBackgroundRemove.ts","../src/engine/nodes/remote/videoDeconstruct.ts","../src/engine/nodes/remote/videoLipsync.ts","../src/engine/nodes/remote/videoTranscribe.ts","../src/engine/nodes/local/lib/ffmpeg.ts","../src/engine/nodes/local/lib/script-word-timing.ts","../src/engine/nodes/remote/voiceSelect.ts","../src/engine/schema/catalog.ts","../src/engine/storage/cache-store.ts"],"sourcesContent":["import path from \"node:path\";\nimport { requireConnection } from \"../env.ts\";\nimport { BackendClient as _BackendClient } from \"./client/backend-client.ts\";\nimport { remoteCacheEnabledFromEnv } from \"./client/env.ts\";\nimport type { AnyNodeDefinition } from \"./engine/define.ts\";\nimport { ValidationError as _ValidationError } from \"./engine/errors.ts\";\nimport { Engine as _Engine } from \"./engine/executor.ts\";\nimport { NodeRegistry } from \"./engine/registry.ts\";\nimport { validateCanvasDeep as _validateCanvasDeep } from \"./engine/validator.ts\";\nimport { ingestNode } from \"./nodes/ingest.ts\";\nimport { audioTimelineNode } from \"./nodes/local/audioTimeline.ts\";\nimport { avMuxNode } from \"./nodes/local/avMux.ts\";\nimport { collectNode } from \"./nodes/local/collect.ts\";\nimport { ffmpegNode } from \"./nodes/local/ffmpeg.ts\";\nimport { fontSpecimenNode } from \"./nodes/local/fontSpecimen.ts\";\nimport { hyperframeRenderNode } from \"./nodes/local/hyperframe.ts\";\nimport { hyperframeSnapshotNode } from \"./nodes/local/hyperframe-snapshot.ts\";\nimport { imagemagickNode } from \"./nodes/local/imagemagick.ts\";\nimport { staticFormatNode } from \"./nodes/local/staticFormat.ts\";\nimport { staticLogoNode } from \"./nodes/local/staticLogo.ts\";\nimport { staticNativeNode } from \"./nodes/local/staticNative.ts\";\nimport { staticExtendMergeNode, staticPlaceNode } from \"./nodes/local/staticPlace.ts\";\nimport { staticPlateNode } from \"./nodes/local/staticPlate.ts\";\nimport { staticPrefilterNode } from \"./nodes/local/staticPrefilter.ts\";\nimport { staticSafeFitNode } from \"./nodes/local/staticSafeFit.ts\";\nimport { textNode } from \"./nodes/local/text.ts\";\nimport { videoConcatNode } from \"./nodes/local/videoConcat.ts\";\nimport { audioVoiceConvertNode } from \"./nodes/remote/audioVoiceConvert.ts\";\nimport { dialogueNode } from \"./nodes/remote/dialogue.ts\";\nimport { imageGenerateNode } from \"./nodes/remote/image.ts\";\nimport { imageAspectAdaptNode } from \"./nodes/remote/imageAspectAdapt.ts\";\nimport { imageBackgroundRemoveNode } from \"./nodes/remote/imageBackgroundRemove.ts\";\nimport { imageDescribeNode } from \"./nodes/remote/imageDescribe.ts\";\nimport { imageLayerizeNode } from \"./nodes/remote/imageLayerize.ts\";\nimport { imageReferenceSheetNode } from \"./nodes/remote/imageReferenceSheet.ts\";\nimport { imageSearchNode } from \"./nodes/remote/imageSearch.ts\";\nimport { imageSelectNode } from \"./nodes/remote/imageSelect.ts\";\nimport { musicNode } from \"./nodes/remote/music.ts\";\nimport { soundEffectNode } from \"./nodes/remote/soundEffect.ts\";\nimport { textGenerateNode } from \"./nodes/remote/textGenerate.ts\";\nimport { ttsNode } from \"./nodes/remote/tts.ts\";\nimport { videoGenerateNode } from \"./nodes/remote/video.ts\";\nimport { videoBackgroundRemoveNode } from \"./nodes/remote/videoBackgroundRemove.ts\";\nimport { videoDeconstructNode } from \"./nodes/remote/videoDeconstruct.ts\";\nimport { videoLipsyncNode } from \"./nodes/remote/videoLipsync.ts\";\nimport { videoTranscribeNode } from \"./nodes/remote/videoTranscribe.ts\";\nimport { voiceSelectNode } from \"./nodes/remote/voiceSelect.ts\";\nimport { generateCatalog as _generateCatalog } from \"./schema/catalog.ts\";\nimport { LocalAssetStore as _LocalAssetStore } from \"./storage/asset-store.ts\";\nimport { LocalCacheStore as _LocalCacheStore } from \"./storage/cache-store.ts\";\nimport { LayeredCacheStore, RemoteCacheStore } from \"./storage/remote-cache-store.ts\";\n\nexport const BackendClient = _BackendClient;\nexport const Engine = _Engine;\nexport const LocalAssetStore = _LocalAssetStore;\nexport const LocalCacheStore = _LocalCacheStore;\nexport const validateCanvasDeep = _validateCanvasDeep;\nexport const generateCatalog = _generateCatalog;\nexport const ValidationError = _ValidationError;\n\nconst LOCAL_NODES: readonly AnyNodeDefinition[] = [\n textNode,\n ingestNode,\n hyperframeRenderNode,\n hyperframeSnapshotNode,\n ffmpegNode,\n imagemagickNode,\n videoTranscribeNode,\n fontSpecimenNode,\n audioTimelineNode,\n videoConcatNode,\n avMuxNode,\n collectNode,\n staticPrefilterNode,\n staticNativeNode,\n staticSafeFitNode,\n staticLogoNode,\n staticPlaceNode,\n staticExtendMergeNode,\n staticFormatNode,\n staticPlateNode,\n];\n\nconst REMOTE_NODES: readonly AnyNodeDefinition[] = [\n textGenerateNode,\n imageGenerateNode,\n imageAspectAdaptNode,\n imageDescribeNode,\n imageReferenceSheetNode,\n imageSearchNode,\n imageSelectNode,\n videoGenerateNode,\n ttsNode,\n audioVoiceConvertNode,\n musicNode,\n dialogueNode,\n soundEffectNode,\n videoLipsyncNode,\n videoBackgroundRemoveNode,\n videoDeconstructNode,\n voiceSelectNode,\n imageBackgroundRemoveNode,\n imageLayerizeNode,\n];\n\n/** Convenience: registry pre-loaded with every node ships with the engine. */\nexport function defaultRegistry(): NodeRegistry {\n const r = new NodeRegistry();\n for (const n of LOCAL_NODES) r.register(n);\n for (const n of REMOTE_NODES) r.register(n);\n return r;\n}\n\n/** Build a ready-to-run engine using env vars + the project cwd. */\nexport function createEngineFromEnv(\n opts: {\n cwd?: string;\n cacheDir?: string;\n outputsDir?: string;\n log?: (line: string) => void;\n /**\n * Layer the company-scoped remote cache over the local one (and stamp\n * durable asset URLs onto fresh outputs) so a fresh sandbox re-runs an\n * already-computed canvas at zero credits. Defaults to on; disable with\n * `remoteCache: false` or env BAKER_CANVAS_REMOTE_CACHE=off.\n */\n remoteCache?: boolean;\n } = {},\n): _Engine {\n const cwd = opts.cwd ?? process.cwd();\n const cacheDir = opts.cacheDir ?? path.join(cwd, \"canvas\", \".cache\");\n const outputsDir = opts.outputsDir ?? path.join(cwd, \"canvas\");\n const connection = requireConnection();\n const client = new _BackendClient({ baseUrl: connection.BAKER_API_URL, apiKey: connection.BAKER_API_KEY });\n const assets = new _LocalAssetStore(path.join(cacheDir, \"assets\"));\n const localCache = new _LocalCacheStore(path.join(cacheDir, \"index\"));\n const remoteCacheEnabled = opts.remoteCache ?? remoteCacheEnabledFromEnv();\n const cache = remoteCacheEnabled\n ? new LayeredCacheStore({\n local: localCache,\n remote: new RemoteCacheStore(client, opts.log),\n assets,\n log: opts.log,\n })\n : localCache;\n return new _Engine({\n registry: defaultRegistry(),\n client,\n assets,\n cache,\n outputsDir,\n log: opts.log,\n persistAssets: remoteCacheEnabled,\n });\n}\n","import { existsSync } from \"node:fs\";\nimport { canonicalize } from \"@baker/canvas-contract\";\nimport type { BackendClient } from \"../client/backend-client.ts\";\nimport { resolveConcurrency } from \"../lib/concurrency.ts\";\nimport { forEachObject, mapObjects, mapObjectsAsync, mapStrings } from \"../lib/json-walk.ts\";\nimport { ulid } from \"../lib/ulid.ts\";\nimport { persistOutputAssetUrls } from \"../nodes/remote/upload.ts\";\nimport type { Canvas, NodeDecl } from \"../schema/canvas.ts\";\nimport { renderTemplate } from \"../schema/prompts.ts\";\nimport { type AssetRef, contentShaOf, isAssetRef, isAssetRefArray, isUrlOnlyRef } from \"../schema/refs.ts\";\nimport type { AssetStore } from \"../storage/asset-store.ts\";\nimport type { CacheStore } from \"../storage/cache-store.ts\";\nimport { OutputWriter } from \"../storage/output-writer.ts\";\nimport { computeCacheKey } from \"./cache-key.ts\";\nimport type { CachePolicy, ExecCtx, LogFn } from \"./context.ts\";\nimport { estimateNodeCredits, sumCredits } from \"./credits.ts\";\nimport type { AnyNodeDefinition } from \"./define.ts\";\nimport {\n failureDetail,\n LayerExecutionError,\n type LayerFailure,\n NodeExecutionError,\n type NodeFailureDetail,\n RunAbortedError,\n ValidationError,\n} from \"./errors.ts\";\nimport { buildDependencyGraph } from \"./graph.ts\";\nimport { renderedPromptOverLimit } from \"./prompt-limit.ts\";\nimport { type AllOutputs, resolveRefs } from \"./refs.ts\";\nimport type { NodeRegistry } from \"./registry.ts\";\nimport { reachableNodes, subgraph, topologicalLayers } from \"./scheduler.ts\";\nimport { stepRunner } from \"./step-cache.ts\";\nimport { validateCanvas, validateCanvasDeep } from \"./validator.ts\";\n\nexport type RunResult = {\n run_id: string;\n output: AssetRef | AssetRef[] | unknown;\n outputs_by_node: Record<string, Record<string, unknown>>;\n stats: { total_nodes: number; cached_nodes: number; total_credits: number; duration_ms: number };\n outputs_dir: string;\n node_runs: NodeRunRecord[];\n};\n\nexport type NodeRunRecord = {\n node_id: string;\n node_type: string;\n cached: boolean;\n duration_ms: number;\n credits: number;\n};\n\n/**\n * Live run telemetry: the plan (post-prune node list + dependency edges) fires\n * once before any node executes, then start/settled/failed per node. Consumers\n * stream these into run-history progress snapshots; a throwing consumer is\n * swallowed — telemetry must never fail a paid run.\n */\nexport type RunProgressEvent =\n | {\n kind: \"plan\";\n nodes: Array<{ node_id: string; node_type: string; deps: string[]; params: unknown; role?: string }>;\n }\n | { kind: \"node_start\"; node_id: string }\n | { kind: \"node_settled\"; run: NodeRunRecord; outputs: Record<string, unknown> }\n | { kind: \"node_failed\"; node_id: string; error: NodeFailureDetail };\n\ntype RunOptions = {\n signal?: AbortSignal;\n run_id?: string;\n cache_policy?: CachePolicy;\n /** Max nodes in flight at once; invalid or missing → 8 (DEFAULT_CONCURRENCY). */\n concurrency?: number;\n /**\n * Node ids to force fresh for THIS run only (the `--regenerate` flag). Folds\n * the run id into each named node's cache key so it re-renders regardless of\n * the content cache, without editing the canvas. Persistent regeneration uses\n * the per-node `regenerate` field instead.\n */\n regenerate?: ReadonlySet<string>;\n /**\n * Node types to stop BEFORE, leaving the run resumable.\n *\n * Every defect in a finished ad was caught at the end, after every clip had been paid\n * for — while the frames that carry the look land minutes earlier and cost a fraction of\n * them. This is what lets someone see those first: the run settles everything cheap and\n * stops on the doorstep of the expensive half.\n *\n * It raises `RunAbortedError`, the completed\n * nodes are already cached, and continuing is re-running the same `--run-id`, which pays\n * for none of them twice.\n */\n stop_before_kinds?: ReadonlySet<string>;\n /**\n * Outputs an earlier run already made, by node id: those nodes are never executed (nor looked\n * up in the cache), their outputs passed on as a free, cached step. A version grown from the\n * one before it keeps that version's renders in its graph this way, whatever has changed in\n * the inputs they were made from since (`static-history.ts`).\n */\n pinned?: Readonly<Record<string, Record<string, unknown>>>;\n onProgress?: (event: RunProgressEvent) => void;\n};\n\ntype EngineOptions = {\n registry: NodeRegistry;\n client: BackendClient;\n assets: AssetStore;\n cache: CacheStore;\n outputsDir: string;\n log?: LogFn;\n /**\n * Stamp durable canvas-assets URLs onto fresh node outputs before they are\n * cached — the precondition for remote cache portability and run-history\n * records. Best-effort: a failed upload logs a warning and keeps the entry\n * local-only, never fails the node.\n */\n persistAssets?: boolean;\n};\n\n/**\n * Why a run that settled everything it could did not finish, thrown: an abort first (the signal\n * is why it ended), then the failures, then a checkpoint. Nothing when it finished.\n */\nfunction throwRunOutcome(\n signal: AbortSignal | undefined,\n failures: readonly LayerFailure[],\n held: readonly string[],\n): void {\n if (signal?.aborted) throw new RunAbortedError(\"signal\", \"run aborted by signal\");\n if (failures.length === 1 && failures[0]) throw failures[0].reason;\n if (failures.length > 1) throw new LayerExecutionError([...failures]);\n if (held.length > 0) {\n throw new RunAbortedError(\n \"checkpoint\",\n `stopped before ${held.join(\", \")} — everything up to here is done and cached, so continuing this run id pays for none of it again`,\n );\n }\n}\n\n/**\n * The nodes in this layer the caller asked to stop before, if any.\n *\n * Per LAYER rather than per node so the stop is clean: a half-dispatched layer would bill\n * some of exactly what the caller asked not to run. Pulled out of the loop because the loop\n * was already at the complexity ceiling, and a stop condition is easier to read named.\n */\nfunction heldByCheckpoint(\n canvas: { nodes: { id: string; type: string }[] },\n layer: readonly string[],\n kinds: ReadonlySet<string> | undefined,\n): string[] {\n if (!kinds?.size) return [];\n return layer.filter((id) => {\n const type = canvas.nodes.find((n) => n.id === id)?.type;\n return type !== undefined && kinds.has(type);\n });\n}\n\nexport class Engine {\n private readonly registry: NodeRegistry;\n private readonly client: BackendClient;\n private readonly assets: AssetStore;\n private readonly cache: CacheStore;\n private readonly outputsDir: string;\n private readonly log: LogFn;\n private readonly persistAssets: boolean;\n\n constructor(opts: EngineOptions) {\n this.registry = opts.registry;\n this.client = opts.client;\n this.assets = opts.assets;\n this.cache = opts.cache;\n this.outputsDir = opts.outputsDir;\n this.log = opts.log ?? (() => undefined);\n this.persistAssets = opts.persistAssets ?? false;\n }\n\n validate(canvas: unknown) {\n return validateCanvas(canvas, this.registry);\n }\n\n /** Async variant — runs every node's `validateExtra` hook in addition to the shallow checks. */\n validateDeep(canvas: unknown) {\n return validateCanvasDeep(canvas, this.registry);\n }\n\n async run(input: unknown, opts: RunOptions = {}): Promise<RunResult> {\n // Always run the deep validator before any node executes. This catches\n // composition-meta mistakes (bad param shape, missing required param,\n // unknown @baker composition) upfront — before paying for any remote node.\n // Without this, a typo in the final hyperframe_render call would only\n // surface after all 14 video_generate clips had spent credits.\n const validation = await this.validateDeep(input);\n if (!validation.ok) throw new ValidationError(validation.issues);\n const canvas = validation.canvas;\n\n const runId = opts.run_id ?? `r_${ulid()}`;\n const writer = new OutputWriter({ outputsDir: this.outputsDir, runId });\n await writer.ensure();\n\n // A pinned node never runs, so it is never spent on (a grown version's kept renders).\n const estimate = opts.pinned\n ? sumCredits((validation.perNodeCredits ?? []).filter((n) => !opts.pinned?.[n.node_id]))\n : validation.estimatedCredits;\n this.log(`[validate] ok (${canvas.nodes.length} nodes, est. ${estimate} credits)`);\n // Advisory warnings never block the run, but a billed render should still print\n // them (a missing element reference, a scene span past the model's cap) so the\n // operator sees them without a separate `validate` pass.\n for (const w of validation.warnings ?? []) {\n this.log(`[warn ] ${w.code}${w.node_id ? ` (${w.node_id})` : \"\"}: ${w.message}`);\n }\n\n const t0 = Date.now();\n const outputs: AllOutputs = {};\n const counters = { cachedNodes: 0, totalCredits: 0 };\n const nodeRuns: NodeRunRecord[] = [];\n\n const graph = this.pruneToOutput(canvas, buildDependencyGraph(canvas));\n const needsBytes = computeNeedsLocalBytes(canvas, graph, this.registry);\n this.emitProgress(opts, {\n kind: \"plan\",\n nodes: [...graph.entries()].map(([id, deps]) => {\n const node = canvas.nodes.find((n) => n.id === id);\n const role = node?.tags?.role;\n return {\n node_id: id,\n node_type: node?.type ?? \"unknown\",\n deps: [...deps],\n params: node?.params,\n ...(role !== undefined ? { role } : {}),\n };\n }),\n });\n\n await this.runLayers(canvas, graph, outputs, runId, writer, opts, counters, nodeRuns, needsBytes);\n\n const output = pickFinalOutput(canvas, outputs);\n const stats = {\n total_nodes: canvas.nodes.length,\n cached_nodes: counters.cachedNodes,\n total_credits: counters.totalCredits,\n duration_ms: Date.now() - t0,\n };\n\n await writer.writeManifest(\"manifest\", {\n run_id: runId,\n canvas,\n outputs_by_node: outputs,\n output,\n stats,\n node_runs: nodeRuns,\n started_at: t0,\n completed_at: t0 + stats.duration_ms,\n });\n await this.writeFinal(writer, output);\n\n this.log(\n `[done ] ${stats.cached_nodes}/${stats.total_nodes} cached, ${stats.total_credits} credits, ${stats.duration_ms}ms`,\n );\n this.log(`outputs in: ${writer.runDir}`);\n\n return { run_id: runId, output, outputs_by_node: outputs, stats, outputs_dir: writer.runDir, node_runs: nodeRuns };\n }\n\n private async runLayers(\n canvas: Canvas,\n graph: Map<string, Set<string>>,\n outputs: AllOutputs,\n runId: string,\n writer: OutputWriter,\n opts: RunOptions,\n counters: { cachedNodes: number; totalCredits: number },\n nodeRuns: NodeRunRecord[],\n needsBytes: ReadonlySet<string>,\n ): Promise<void> {\n // Each node starts the moment its own inputs are done, never when a whole layer is: in an\n // autofix round the 9:16's one-second resize waited 55 s for the 4:5's margin paint, only\n // because the two shared a layer (dev, Oct 2026). Kahn's order still breaks ties and finds cycles.\n const order = topologicalLayers(graph).flat();\n const limit = resolveConcurrency(opts.concurrency);\n if (opts.signal?.aborted) throw new RunAbortedError(\"signal\", \"run aborted before dispatch\");\n const waitingOn = new Map(order.map((id) => [id, new Set(graph.get(id) ?? [])]));\n const running = new Map<string, Promise<void>>();\n const failures: LayerFailure[] = [];\n const held: string[] = [];\n const dispatch = (nodeId: string): void => {\n waitingOn.delete(nodeId);\n this.emitProgress(opts, { kind: \"node_start\", node_id: nodeId });\n const settled = this.executeOne(canvas, nodeId, outputs, runId, writer, opts, needsBytes.has(nodeId)).then(\n (r) => {\n this.recordRun(canvas, nodeId, r, counters, nodeRuns, outputs, opts);\n for (const deps of waitingOn.values()) deps.delete(nodeId);\n },\n (reason: unknown) => {\n // A failure holds back only what depends on it: every other branch still runs and caches,\n // so repeated runs of a canvas with several flaky nodes converge.\n failures.push({ nodeId, reason });\n this.emitProgress(opts, { kind: \"node_failed\", node_id: nodeId, error: failureDetail(reason) });\n },\n );\n running.set(\n nodeId,\n settled.finally(() => running.delete(nodeId)),\n );\n };\n const isHeld = (nodeId: string) => heldByCheckpoint(canvas, [nodeId], opts.stop_before_kinds).length > 0;\n for (;;) {\n // A signal stops DISPATCHING; already-running nodes still settle so their cache writes land.\n // Skipped nodes never start (no node_start / node_failed): they stay pending for a resume.\n const ready = opts.signal?.aborted ? [] : order.filter((id) => waitingOn.get(id)?.size === 0);\n for (const nodeId of ready) {\n if (running.size >= limit) break;\n // Stop on the doorstep of the expensive kind: it never dispatches, nor anything after it.\n if (isHeld(nodeId)) {\n waitingOn.delete(nodeId);\n held.push(nodeId);\n } else dispatch(nodeId);\n }\n if (running.size === 0) break;\n await Promise.race(running.values());\n }\n // Failures land in the order they settle; they are named in the graph's order, whatever the load.\n const rank = new Map(order.map((id, i) => [id, i]));\n failures.sort((a, b) => (rank.get(a.nodeId) ?? 0) - (rank.get(b.nodeId) ?? 0));\n throwRunOutcome(opts.signal, failures, held);\n }\n\n /** A settled node counted, recorded and announced. */\n private recordRun(\n canvas: Canvas,\n nodeId: string,\n r: { cached: boolean; credits: number; durationMs: number },\n counters: { cachedNodes: number; totalCredits: number },\n nodeRuns: NodeRunRecord[],\n outputs: AllOutputs,\n opts: RunOptions,\n ): void {\n if (r.cached) counters.cachedNodes++;\n counters.totalCredits += r.credits;\n const node = canvas.nodes.find((n) => n.id === nodeId);\n if (!node) return;\n const run: NodeRunRecord = {\n node_id: nodeId,\n node_type: node.type,\n cached: r.cached,\n duration_ms: r.durationMs,\n credits: r.credits,\n };\n nodeRuns.push(run);\n this.emitProgress(opts, { kind: \"node_settled\", run, outputs: outputs[nodeId] ?? {} });\n }\n\n /** Progress consumers are observers only — an exception there must never fail the run. */\n private emitProgress(opts: RunOptions, event: RunProgressEvent): void {\n if (!opts.onProgress) return;\n try {\n opts.onProgress(event);\n } catch {\n // deliberately swallowed\n }\n }\n\n /**\n * Dead-node elimination: when the canvas declares an `output`, execute only the\n * nodes that output transitively depends on. Orphaned nodes (left by an edit or\n * a rewire) otherwise still run, bill, and abort the run on their own failure.\n * No declared output ⇒ intent is ambiguous, so run everything (back-compat).\n */\n private pruneToOutput(canvas: Canvas, graph: Map<string, Set<string>>): Map<string, Set<string>> {\n const rootId = canvas.output?.node;\n if (!rootId || !graph.has(rootId)) return graph;\n const keep = reachableNodes(graph, [rootId]);\n if (keep.size === graph.size) return graph;\n const dropped = [...graph.keys()].filter((id) => !keep.has(id));\n this.log(`[prune ] skipping ${dropped.length} node(s) unreachable from output: ${dropped.join(\", \")}`);\n return subgraph(graph, keep);\n }\n\n private async writeFinal(writer: OutputWriter, output: unknown): Promise<void> {\n if (output === undefined) return;\n if (isAssetRefArray(output)) {\n for (let i = 0; i < output.length; i++) {\n const ref = output[i];\n if (ref) await writer.writeAsset(`_final__${i}`, ref);\n }\n return;\n }\n if (isAssetRef(output)) {\n await writer.writeAsset(\"_final\", output);\n return;\n }\n await writer.writeManifest(\"_final\", output);\n }\n\n private async executeOne(\n canvas: Canvas,\n nodeId: string,\n outputs: AllOutputs,\n runId: string,\n writer: OutputWriter,\n opts: RunOptions,\n downloadOutputs: boolean,\n ): Promise<{ cached: boolean; credits: number; durationMs: number }> {\n const node = canvas.nodes.find((n) => n.id === nodeId);\n if (!node) throw new Error(`executor: missing node ${nodeId}`);\n const def = this.registry.get(node.type);\n if (!def) throw new Error(`executor: missing registry entry for type ${node.type}`);\n\n const pinned = opts.pinned?.[node.id];\n if (pinned) return this.replayPinned(node, pinned, outputs, writer, downloadOutputs);\n\n const regenerateToken = resolveRegenerateToken(node, opts.regenerate, runId);\n const prepared = await prepareForExecution(node, outputs, def, canvas.cache_salt, regenerateToken, this.assets);\n const policy = opts.cache_policy ?? \"read_write\";\n\n if (policy !== \"bypass\") {\n const hit = await this.replayCached(node, prepared.cacheKey, outputs, writer);\n if (hit) return hit;\n }\n assertPromptsFitModel(node, prepared.renderedParams);\n\n const t0 = Date.now();\n let charged: number | undefined;\n const ctx: ExecCtx = {\n canvasRunId: runId,\n nodeId: node.id,\n nodeType: node.type,\n cacheKey: prepared.cacheKey,\n downloadOutputs,\n client: this.client,\n assets: this.assets,\n log: this.log,\n signal: opts.signal,\n reportCharge: (c) => {\n charged = (charged ?? 0) + c;\n },\n steps: stepRunner({\n cache: this.cache,\n nodeType: node.type,\n regenerateToken,\n cacheSalt: canvas.cache_salt,\n policy,\n }),\n };\n // Fail-safe: a local node needs its input bytes on disk. `computeNeedsLocalBytes`\n // guarantees its producers were downloaded, but if an edge was missed\n // (e.g. an unrecognized ref shape), materialize any URL-only input on demand\n // rather than letting the local runner throw on the missing path. A\n // passthrough-ref node (collect) never reads bytes, so it stays URL-only.\n const preparedForExec = needsLocalMaterialization(def)\n ? { ...prepared, resolvedInputs: await this.materializeLocalInputs(prepared.resolvedInputs) }\n : prepared;\n const { parsedInputs, parsedParams } = parseNodeArgs(def, preparedForExec, node.id, node.type);\n const result = await invokeExecute(def, parsedInputs, parsedParams, ctx, node.id, node.type);\n const elapsed = Date.now() - t0;\n // What the backend charged is the spend; a node it never billed (a local one,\n // or an old backend that does not report) falls back to its own estimate, unless\n // it reports every charge itself: then nothing reported is nothing spent.\n const credits =\n charged ?? (def.billing === \"reported\" ? 0 : estimateNodeCredits(def, preparedForExec.renderedParams));\n const outputsObj = result as Record<string, unknown>;\n outputs[node.id] = outputsObj;\n\n // Stamp durable URLs BEFORE the cache write so the entry (and the run\n // record built from outputs_by_node) is rehydratable in any sandbox.\n // URL-only stamping never changes cache keys (inputs hash by sha256,\n // params are normalized to content identity).\n if (this.persistAssets) await this.persistOutputs(node.id, outputsObj, ctx);\n\n if (policy === \"read_write\") {\n await this.cache.put({\n cacheKey: prepared.cacheKey,\n nodeType: node.type,\n nodeVersion: def.version,\n outputs: outputsObj,\n refs: collectShas(outputsObj),\n createdAt: Date.now(),\n });\n }\n await this.materializeNodeOutputs(node.id, outputsObj, writer);\n this.log(`[exec ] ${node.id.padEnd(20)} ${node.type.padEnd(20)} fresh (${(elapsed / 1000).toFixed(1)}s)`);\n this.logOutputWarnings(node.id, outputsObj);\n return { cached: false, credits, durationMs: elapsed };\n }\n\n /** A cache hit replayed as this node's result: its outputs written, and free. */\n private async replayCached(\n node: NodeDecl,\n cacheKey: string,\n outputs: AllOutputs,\n writer: OutputWriter,\n ): Promise<{ cached: boolean; credits: number; durationMs: number } | null> {\n const cacheT0 = Date.now();\n const hit = await this.cache.get(cacheKey);\n if (!hit) return null;\n outputs[node.id] = hit.outputs;\n await this.materializeNodeOutputs(node.id, hit.outputs, writer);\n this.log(`[exec ] ${node.id.padEnd(20)} ${node.type.padEnd(20)} cached`);\n this.logOutputWarnings(node.id, hit.outputs);\n return { cached: true, credits: 0, durationMs: Date.now() - cacheT0 };\n }\n\n /**\n * An earlier run's outputs replayed as this node's result: free, and never rendered again. A\n * local file that is gone falls back to the durable URL, downloaded when a local node needs it.\n */\n private async replayPinned(\n node: NodeDecl,\n pinned: Record<string, unknown>,\n outputs: AllOutputs,\n writer: OutputWriter,\n downloadOutputs: boolean,\n ): Promise<{ cached: boolean; credits: number; durationMs: number }> {\n const t0 = Date.now();\n const replayed = (await mapObjectsAsync(pinned, (v) => {\n if (!isAssetRef(v) || typeof v.url !== \"string\") return undefined;\n if (typeof v.path === \"string\" && existsSync(v.path)) return Promise.resolve(v);\n const { path: _gone, ...urlOnly } = v;\n if (!downloadOutputs) return Promise.resolve(urlOnly);\n const url = v.url;\n return this.assets\n .ingestRemote({ kind: v.kind, url, sha256: v.sha256, mime: v.mime, metadata: v.metadata })\n .then((local) => ({ ...urlOnly, path: local.path }));\n })) as Record<string, unknown>;\n outputs[node.id] = replayed;\n await this.materializeNodeOutputs(node.id, replayed, writer);\n this.log(`[exec ] ${node.id.padEnd(20)} ${node.type.padEnd(20)} kept from the version before`);\n return { cached: true, credits: 0, durationMs: Date.now() - t0 };\n }\n\n /** Best-effort: a failed upload keeps the outputs local-only, never fails the node. */\n private async persistOutputs(nodeId: string, outputs: Record<string, unknown>, ctx: ExecCtx): Promise<void> {\n try {\n await persistOutputAssetUrls(outputs, ctx);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n this.log(`[warn ] ${nodeId}: asset persistence failed (${msg}) — outputs stay local-only`);\n }\n }\n\n /**\n * Print the warnings a node left on its outputs' metadata — a `voice_select` that\n * could not honor the requested gender, say. Left in the metadata alone they were\n * read only after the render was paid for and somebody listened. Printed on a\n * cached replay too: the output still carries the compromise.\n */\n private logOutputWarnings(nodeId: string, outputs: Record<string, unknown>): void {\n for (const warning of outputWarnings(outputs)) this.log(`[warn ] ${nodeId}: ${warning}`);\n }\n\n private async materializeNodeOutputs(\n nodeId: string,\n outputs: Record<string, unknown>,\n writer: OutputWriter,\n ): Promise<void> {\n for (const [name, value] of Object.entries(outputs)) {\n if (isAssetRef(value)) {\n await writer.writeAsset(`${nodeId}__${name}`, value);\n } else if (isAssetRefArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const ref = value[i];\n if (ref) await writer.writeAsset(`${nodeId}__${name}__${i}`, ref);\n }\n } else {\n await writer.writeManifest(`${nodeId}__${name}`, value);\n }\n }\n }\n\n /**\n * Download any URL-only asset ref reachable in a local node's inputs so the\n * bytes are on disk before the local runner stages them. Returns a copy —\n * refs are replaced, never mutated in place, so the producer's cached output\n * (shared object) keeps its URL-only shape.\n */\n private async materializeLocalInputs(inputs: Record<string, unknown>): Promise<Record<string, unknown>> {\n return (await mapObjectsAsync(inputs, (v) => {\n if (!isUrlOnlyRef(v)) return undefined;\n this.log(`[warn ] materializing URL-only input on demand (${v.kind}/${v.mime}) — missed graph edge`);\n return this.assets.ingestRemote({\n kind: v.kind,\n url: v.url,\n sha256: v.sha256,\n mime: v.mime,\n metadata: v.metadata as Record<string, unknown> | undefined,\n });\n })) as Record<string, unknown>;\n }\n}\n\n/** The `metadata.warnings` strings on one asset ref. */\nfunction refWarnings(ref: unknown): string[] {\n if (!isAssetRef(ref)) return [];\n const warnings = ref.metadata?.warnings;\n if (!Array.isArray(warnings)) return [];\n return warnings.filter((w): w is string => typeof w === \"string\" && w.length > 0);\n}\n\n/** The distinct `metadata.warnings` strings on a node's output asset refs. */\nfunction outputWarnings(outputs: Record<string, unknown>): string[] {\n const refs = Object.values(outputs).flatMap((value) => (Array.isArray(value) ? value : [value]));\n return [...new Set(refs.flatMap(refWarnings))];\n}\n\ntype Prepared = {\n resolvedInputs: Record<string, unknown>;\n renderedParams: unknown;\n cacheKey: string;\n};\n\n/**\n * The cache-busting token for a node, or undefined to leave its content-addressed\n * key untouched. The one-shot `--regenerate` flag wins and folds the run id (fresh\n * every run); otherwise the persistent per-node `regenerate` field is used. Both\n * flow into the cache key as an `extras` entry, so ONLY targeted nodes change keys\n * — every other node keeps its exact prior key and cache hit.\n */\nexport function resolveRegenerateToken(\n node: NodeDecl,\n forced: ReadonlySet<string> | undefined,\n runId: string,\n): string | undefined {\n if (forced?.has(node.id)) return `run:${runId}`;\n if (node.regenerate !== undefined) return `node:${String(node.regenerate)}`;\n return undefined;\n}\n\nasync function prepareForExecution(\n node: NodeDecl,\n outputs: AllOutputs,\n def: AnyNodeDefinition,\n cacheSalt: string | undefined,\n regenerateToken: string | undefined,\n assets: AssetStore,\n): Promise<Prepared> {\n const resolvedInputs = (resolveRefs(node.inputs ?? {}, { outputs }) ?? {}) as Record<string, unknown>;\n const resolvedParams = (resolveRefs(node.params ?? {}, { outputs }) ?? {}) as Record<string, unknown>;\n const slotValues = await hydrateTextSlots(resolvedInputs, assets, node.id, node.type);\n const renderedParams = renderPromptSlotsInValue(resolvedParams, slotValues);\n // Nodes may declare a cacheKeyExtras hook to fold external content into the\n // cache key (e.g. hyperframe_render hashes the composition directory so\n // composition edits invalidate cached renders automatically). A failing hook\n // fails the node: falling back to a params-only key would cache results that\n // ignore external content and silently serve stale outputs later.\n let extras: Record<string, string> | undefined;\n if (def.cacheKeyExtras) {\n try {\n extras = await def.cacheKeyExtras({ params: renderedParams });\n } catch (e) {\n throw new NodeExecutionError(node.id, node.type, { kind: \"local\", cause: e });\n }\n }\n // Fold the regenerate token in as an extra ONLY when present, so nodes without\n // one keep byte-identical cache keys (no mass invalidation on rollout).\n if (regenerateToken !== undefined) {\n extras = { ...(extras ?? {}), __regenerate__: regenerateToken };\n }\n const cacheKey = computeCacheKey({\n node_id: node.type,\n node_version: def.version,\n params: normalizeParamsForCacheKey(renderedParams),\n input_hashes: hashInputs(resolvedInputs),\n cache_salt: cacheSalt,\n extras,\n });\n return { resolvedInputs, renderedParams, cacheKey };\n}\n\n/**\n * Slots are filled only at run time, from what upstream nodes produced, so this is\n * the first moment the prompt the model will receive exists. Refuse it here rather\n * than send it for the backend to refuse.\n */\nfunction assertPromptsFitModel(node: NodeDecl, renderedParams: unknown): void {\n const overLimit = renderedPromptOverLimit(node.id, node.type, renderedParams);\n if (overLimit.length > 0) {\n throw new NodeExecutionError(node.id, node.type, { kind: \"local\", cause: new Error(overLimit.join(\"; \")) });\n }\n}\n\nfunction parseNodeArgs(\n def: AnyNodeDefinition,\n prepared: Prepared,\n nodeId: string,\n nodeType: string,\n): { parsedInputs: unknown; parsedParams: unknown } {\n try {\n return {\n parsedInputs: def.inputs.parse(prepared.resolvedInputs),\n parsedParams: def.params.parse(prepared.renderedParams),\n };\n } catch (e) {\n throw new NodeExecutionError(nodeId, nodeType, { kind: \"local\", cause: e });\n }\n}\n\nasync function invokeExecute(\n def: AnyNodeDefinition,\n parsedInputs: unknown,\n parsedParams: unknown,\n ctx: ExecCtx,\n nodeId: string,\n nodeType: string,\n): Promise<unknown> {\n try {\n return await def.execute({ inputs: parsedInputs, params: parsedParams, ctx });\n } catch (e) {\n if (e instanceof NodeExecutionError) throw e;\n throw new NodeExecutionError(nodeId, nodeType, { kind: \"local\", cause: e });\n }\n}\n\n/** A local node needs its input bytes on disk unless it only forwards refs (collect). */\nfunction needsLocalMaterialization(def: AnyNodeDefinition): boolean {\n return def.location === \"local\" && !def.passthroughRefs;\n}\n\nfunction pickFinalOutput(canvas: Canvas, outputs: AllOutputs): unknown {\n if (canvas.output) {\n const node = outputs[canvas.output.node];\n return node ? node[canvas.output.output] : undefined;\n }\n const last = canvas.nodes[canvas.nodes.length - 1];\n if (!last) return undefined;\n const lastOut = outputs[last.id];\n return lastOut ? Object.values(lastOut)[0] : undefined;\n}\n\n/**\n * Node ids whose outputs a LOCAL (ffmpeg/magick) node consumes and therefore\n * needs on disk. A node NOT in this set can stay URL-only after remote exec —\n * the backend already persisted its bytes to R2 with a durable sha256 URL, so\n * the redundant R2→sandbox download is skipped. `graph` maps node → its upstream\n * deps, so a local node's deps are exactly its byte-needing producers. The run's\n * final output (canvas.output) is a ref pointer, not a graph consumer, so being\n * the final output never forces a download.\n */\nexport function computeNeedsLocalBytes(\n canvas: Canvas,\n graph: Map<string, Set<string>>,\n registry: NodeRegistry,\n): Set<string> {\n const typeById = new Map(canvas.nodes.map((n) => [n.id, n.type]));\n const needs = new Set<string>();\n for (const [consumerId, deps] of graph) {\n const def = registry.get(typeById.get(consumerId) ?? \"\");\n if (def?.location !== \"local\" || def.passthroughRefs) continue;\n for (const dep of deps) needs.add(dep);\n }\n return needs;\n}\n\n/**\n * Reduce each resolved input to a stable identity for the cache key: a ref → its\n * sha256; anything else → a canonical literal with any NESTED refs reduced to\n * `{sha256,kind,mime}` first. Without that normalization, a ref buried inside an\n * object/array input folds its volatile `url`/`path`/`metadata.ingested_at` into\n * the key — the node either never caches (key churns every run) or keeps a stale\n * key when content changes under an unchanged url. Flat inputs (top-level refs,\n * scalars, ref-free literals) key byte-identically to before. Exported for tests.\n */\nexport function hashInputs(inputs: Record<string, unknown>): Record<string, string | string[]> {\n const out: Record<string, string | string[]> = {};\n for (const [k, v] of Object.entries(inputs)) {\n if (Array.isArray(v)) {\n // Preserve every element (and its position): dropping non-asset literals\n // would let two canvases differing only in an array literal share a key.\n out[k] = v.map((el) => contentShaOf(el) ?? canonicalLiteral(normalizeParamsForCacheKey(el)));\n } else {\n const s = contentShaOf(v);\n if (s !== null) out[k] = s;\n else out[k] = canonicalLiteral(normalizeParamsForCacheKey(v));\n }\n }\n return out;\n}\n\n// Params may carry AssetRefs resolved from `$ref:` (e.g. a composition `image`\n// param wired to an upstream asset). Unlike inputs — which `hashInputs` reduces\n// to sha256 — params are folded into the cache key whole, so the AssetRef's\n// volatile fields (`url`, `path`, `metadata.ingested_at`) would change the key\n// every run and defeat caching. Reduce any embedded AssetRef to its stable\n// content identity before keying; the full object is kept for execution.\nexport function normalizeParamsForCacheKey(v: unknown): unknown {\n return mapObjects(v, (o) => {\n if (contentShaOf(o) === null) return undefined;\n return { sha256: o.sha256, kind: o.kind, mime: o.mime };\n });\n}\n\nfunction canonicalLiteral(v: unknown): string {\n if (v === undefined) return \"u\";\n if (v === null) return \"n\";\n if (typeof v === \"string\") return `s:${v}`;\n if (typeof v === \"number\") return `f:${v}`;\n if (typeof v === \"boolean\") return `b:${v}`;\n // Objects/arrays go through canonicalize (sorted keys, NFC) so the key is\n // stable regardless of property order — raw JSON.stringify is order-dependent.\n return `j:${canonicalize(v)}`;\n}\n\nfunction collectShas(outputs: Record<string, unknown>): string[] {\n const out: string[] = [];\n forEachObject(outputs, (o) => {\n const sha = contentShaOf(o);\n if (sha !== null) out.push(sha);\n });\n return [...new Set(out)];\n}\n\nfunction renderPromptSlotsInValue(value: unknown, slots: Record<string, unknown>): unknown {\n const values = stringifySlots(slots);\n return mapStrings(value, (s) => renderTemplate(s, values));\n}\n\n/**\n * Hard cap on text/json content inlined into a prompt slot. Provider prompts\n * comfortably fit hundreds of KB; anything larger is almost certainly a wiring\n * mistake (e.g. pointing a slot at a transcript dump) and would silently eat\n * the model's context, so the node fails instead of truncating.\n */\nconst MAX_INLINE_TEXT_BYTES = 256 * 1024;\n\n/**\n * Replace text/json asset refs in prompt slots with their actual content so\n * `{{slot}}` injects what the upstream node produced. Without this, refs\n * render as compact `[text: <sha8>]` placeholders — fine for binary kinds\n * (image/video/audio), useless for text meant to feed the next prompt.\n */\nasync function hydrateTextSlots(\n slots: Record<string, unknown>,\n assets: AssetStore,\n nodeId: string,\n nodeType: string,\n): Promise<Record<string, unknown>> {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(slots)) {\n out[k] = await hydrateSlotValue(v, assets, nodeId, nodeType);\n }\n return out;\n}\n\nasync function hydrateSlotValue(\n value: unknown,\n assets: AssetStore,\n nodeId: string,\n nodeType: string,\n): Promise<unknown> {\n if (Array.isArray(value)) {\n const out: unknown[] = [];\n for (const v of value) out.push(await hydrateSlotValue(v, assets, nodeId, nodeType));\n return out;\n }\n if (!isAssetRef(value) || (value.kind !== \"text\" && value.kind !== \"json\")) return value;\n let bytes: Buffer;\n try {\n bytes = await assets.readBytes(value.sha256, value.mime);\n } catch (e) {\n // A text/json prompt slot is hydrated by reading its bytes locally, so its\n // producer needs them on disk even when the consumer is a remote node (the\n // `needsLocalBytes` graph rule only tracks local ffmpeg/magick consumers).\n // If the producer was kept URL-only, fetch it on demand — these assets are\n // tiny, so the transfer is cheap.\n if (value.url) {\n try {\n await assets.ingestRemote({ kind: value.kind, url: value.url, sha256: value.sha256, mime: value.mime });\n bytes = await assets.readBytes(value.sha256, value.mime);\n } catch (e2) {\n throw new NodeExecutionError(nodeId, nodeType, { kind: \"local\", cause: e2 });\n }\n } else {\n throw new NodeExecutionError(nodeId, nodeType, { kind: \"local\", cause: e });\n }\n }\n if (bytes.length > MAX_INLINE_TEXT_BYTES) {\n throw new NodeExecutionError(nodeId, nodeType, {\n kind: \"local\",\n cause: new Error(\n `slot asset ${value.sha256.slice(0, 8)} is ${bytes.length} bytes, over the ${MAX_INLINE_TEXT_BYTES}-byte inline prompt limit`,\n ),\n });\n }\n return bytes.toString(\"utf8\");\n}\n\nfunction stringifySlots(slots: Record<string, unknown>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(slots)) {\n out[k] = stringForSlot(v);\n }\n return out;\n}\n\nfunction stringForSlot(v: unknown): string {\n if (typeof v === \"string\") return v;\n if (isAssetRef(v)) {\n const ref = v;\n if (ref.kind === \"image\" && \"width\" in ref && \"height\" in ref && ref.width && ref.height) {\n return `[image: ${ref.width}x${ref.height}]`;\n }\n return `[${ref.kind}: ${ref.sha256.slice(0, 8)}]`;\n }\n if (Array.isArray(v)) return v.map(stringForSlot).join(\", \");\n return JSON.stringify(v);\n}\n","// Max nodes running at once. Video canvases fan out many\n// `video_generate` clips into one layer, and each worker blocks on a\n// multi-minute poll — so a low bound serializes clips into slow waves. 8 keeps\n// multi-clip renders moving while staying well under the backend job workpool\n// (maxParallelism 32) and typical provider rate limits. Raise per-run with\n// `--parallel`/`--concurrency` or `BAKER_CANVAS_CONCURRENCY`.\nexport const DEFAULT_CONCURRENCY = 8;\n\n/**\n * Pick the node-execution concurrency limit from ordered candidates (e.g.\n * CLI flag, then env var). A candidate counts only if it parses to a finite\n * number >= 1; otherwise the default applies.\n */\nexport function resolveConcurrency(...candidates: Array<string | number | undefined>): number {\n for (const candidate of candidates) {\n if (candidate === undefined || candidate === \"\") continue;\n const n = typeof candidate === \"number\" ? candidate : Number(candidate);\n if (Number.isFinite(n) && n >= 1) return Math.floor(n);\n }\n return DEFAULT_CONCURRENCY;\n}\n","import { randomBytes } from \"node:crypto\";\n\nconst ENCODING = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\n/** A minimal monotonic-ish ULID (Crockford base32). Sufficient for run ids. */\nexport function ulid(now: number = Date.now()): string {\n const time = encodeTime(now);\n const rand = encodeRandom();\n return time + rand;\n}\n\nfunction encodeTime(now: number): string {\n let n = now;\n let out = \"\";\n for (let i = 0; i < 10; i++) {\n const mod = n % 32;\n out = ENCODING[mod] + out;\n n = (n - mod) / 32;\n }\n return out;\n}\n\nfunction encodeRandom(): string {\n const bytes = randomBytes(10);\n let out = \"\";\n for (let i = 0; i < 16; i++) {\n // 16 chars * 5 bits = 80 bits = 10 bytes\n const bitIndex = i * 5;\n const byteIndex = Math.floor(bitIndex / 8);\n const bitOffset = bitIndex % 8;\n const high = bytes[byteIndex] ?? 0;\n const low = bytes[byteIndex + 1] ?? 0;\n const combined = ((high << 8) | low) & 0xffff;\n const shift = 11 - bitOffset;\n const value = (combined >> shift) & 0x1f;\n out += ENCODING[value];\n }\n return out;\n}\n","import { copyFile, link, mkdir, unlink, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { AssetRef } from \"../schema/refs.ts\";\nimport { extForMime } from \"./asset-store.ts\";\n\ntype OutputWriterOpts = {\n outputsDir: string;\n runId: string;\n};\n\n/**\n * Writes per-run human-readable filenames pointing at content-addressed cache assets.\n * Tries hardlink, falls back to copy.\n */\nexport class OutputWriter {\n readonly runDir: string;\n\n constructor(opts: OutputWriterOpts) {\n this.runDir = path.join(opts.outputsDir, opts.runId);\n }\n\n async ensure(): Promise<void> {\n await mkdir(this.runDir, { recursive: true });\n }\n\n async writeAsset(name: string, ref: AssetRef): Promise<string> {\n await this.ensure();\n const ext = extForMime(ref.mime);\n const dest = path.join(this.runDir, `${name}.${ext}`);\n if (!ref.path) {\n // No on-disk bytes — write a JSON pointer.\n const pointer = path.join(this.runDir, `${name}.json`);\n await writeFile(pointer, JSON.stringify(ref, null, 2));\n return pointer;\n }\n await safeReplace(ref.path, dest);\n return dest;\n }\n\n async writeManifest(name: string, value: unknown): Promise<string> {\n await this.ensure();\n const dest = path.join(this.runDir, `${name}.json`);\n await writeFile(dest, JSON.stringify(value, null, 2));\n return dest;\n }\n}\n\nasync function safeReplace(src: string, dest: string): Promise<void> {\n try {\n await unlink(dest);\n } catch {\n // ignore — likely doesn't exist\n }\n try {\n await link(src, dest);\n return;\n } catch {\n // fall back to copy\n }\n await copyFile(src, dest);\n}\n","import { canonicalize } from \"@baker/canvas-contract\";\nimport { sha256Hex } from \"../storage/sha256.ts\";\n\ntype CacheKeyInputs = {\n node_id: string;\n node_version: string;\n params: unknown;\n input_hashes: Record<string, string | string[]>;\n cache_salt?: string;\n /**\n * Extra string fields folded into the cache key alongside `params`. Used\n * by nodes whose output depends on external content not captured by params\n * — e.g. `hyperframe_render` adds `composition_content_sha` so editing a\n * composition's HTML or CSS invalidates the cache automatically.\n *\n * Keys are sorted before hashing to keep the key stable.\n */\n extras?: Record<string, string>;\n};\n\nexport function computeCacheKey(inputs: CacheKeyInputs): string {\n // Sort the input_hashes keys explicitly — canonicalize sorts, but we also\n // freeze the input shape so callers can pass any record without surprises.\n const sortedInputs: Record<string, string | string[]> = {};\n for (const key of Object.keys(inputs.input_hashes).sort()) {\n const v = inputs.input_hashes[key];\n if (v === undefined) continue;\n sortedInputs[key] = Array.isArray(v) ? [...v] : v;\n }\n let sortedExtras: Record<string, string> | undefined;\n if (inputs.extras && Object.keys(inputs.extras).length > 0) {\n sortedExtras = {};\n for (const key of Object.keys(inputs.extras).sort()) {\n const v = inputs.extras[key];\n if (v === undefined) continue;\n sortedExtras[key] = v;\n }\n }\n const payload = {\n node_id: inputs.node_id,\n node_version: inputs.node_version,\n params: inputs.params,\n input_hashes: sortedInputs,\n cache_salt: inputs.cache_salt,\n extras: sortedExtras,\n };\n return sha256Hex(canonicalize(payload));\n}\n","import { mapStrings } from \"../lib/json-walk.ts\";\nimport { parseRefExpr, type RefExpr } from \"../schema/canvas.ts\";\n\nexport type NodeOutputs = Record<string, unknown>;\nexport type AllOutputs = Record<string, NodeOutputs>;\n\ntype ResolveDeps = {\n outputs: AllOutputs;\n};\n\n/**\n * Resolves every `$ref:` string in any JSON-like input against upstream node\n * outputs. Strings that are not refs are passed through unchanged.\n */\nexport function resolveRefs(value: unknown, deps: ResolveDeps): unknown {\n return mapStrings(value, (s) => {\n const expr = parseRefExpr(s);\n return expr ? resolveExpr(expr, deps) : s;\n });\n}\n\nfunction resolveExpr(expr: RefExpr, deps: ResolveDeps): unknown {\n return resolveNodeRef(expr.nodeId, expr.output, expr.index, deps);\n}\n\nfunction resolveNodeRef(nodeId: string, output: string, index: number | undefined, deps: ResolveDeps): unknown {\n const node = deps.outputs[nodeId];\n if (!node) throw new Error(`ref: unknown node \"${nodeId}\"`);\n if (!(output in node)) throw new Error(`ref: node \"${nodeId}\" has no output \"${output}\"`);\n const value = node[output];\n if (index === undefined) return value;\n if (!Array.isArray(value)) {\n throw new Error(`ref: ${nodeId}.${output} is not a list (cannot index #${index})`);\n }\n if (index >= value.length) {\n throw new Error(`ref: index #${index} out of bounds for ${nodeId}.${output} (length ${value.length})`);\n }\n return value[index];\n}\n","/**\n * A node's own cache of the paid steps inside one execution.\n *\n * A node that makes a paid call among free work (a size's words call between its cut and its\n * compose) is cached whole by the executor, keyed on its version and every param. A change to a\n * free step, or a bump of the node's version, would then pay for the call again for every client.\n * So the node runs that call as a step, keyed only on what the call depends on: its result is\n * replayed while that key holds, unless the step says the result is not worth replaying (`keep`: a\n * reading the reader could not make is asked again). `--regenerate` (the node's regenerate token) and the canvas's\n * cache salt are folded into every key, and the run's cache policy is kept.\n */\nimport { canonicalize } from \"@baker/canvas-contract\";\nimport type { CacheStore } from \"../storage/cache-store.ts\";\nimport { collectAssetRefLikes } from \"../storage/remote-cache-store.ts\";\nimport { sha256Hex } from \"../storage/sha256.ts\";\nimport type { CachePolicy, ExecSteps } from \"./context.ts\";\n\nexport function stepRunner(opts: {\n cache: CacheStore;\n nodeType: string;\n regenerateToken?: string;\n cacheSalt?: string;\n policy?: CachePolicy;\n}): ExecSteps {\n const policy = opts.policy ?? \"read_write\";\n return {\n async run(name, key, fn, stepOpts) {\n const stepKey = sha256Hex(\n canonicalize({\n node_type: opts.nodeType,\n step: name,\n key,\n regenerate: opts.regenerateToken,\n cache_salt: opts.cacheSalt,\n }),\n );\n if (policy !== \"bypass\") {\n const hit = await opts.cache.get(stepKey);\n if (hit && \"value\" in hit.outputs) return { value: hit.outputs.value as never, cached: true };\n }\n const value = await fn(`${name}:${stepKey.slice(0, 16)}`);\n if (policy === \"read_write\" && (stepOpts?.keep?.(value) ?? true)) {\n await opts.cache.put({\n cacheKey: stepKey,\n nodeType: `${opts.nodeType}#${name}`,\n nodeVersion: \"step\",\n outputs: { value },\n refs: collectAssetRefLikes(value).map((r) => r.sha256),\n createdAt: Date.now(),\n });\n }\n return { value, cached: false };\n },\n };\n}\n","import type { AnyNodeDefinition } from \"./define.ts\";\n\nexport class NodeRegistry {\n private readonly byId = new Map<string, AnyNodeDefinition>();\n\n register(def: AnyNodeDefinition): void {\n if (this.byId.has(def.id)) {\n throw new Error(`NodeRegistry: duplicate node id \"${def.id}\"`);\n }\n this.byId.set(def.id, def);\n }\n\n registerAll(defs: readonly AnyNodeDefinition[]): void {\n for (const d of defs) this.register(d);\n }\n\n get(id: string): AnyNodeDefinition | undefined {\n return this.byId.get(id);\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n\n ids(): string[] {\n return [...this.byId.keys()].sort();\n }\n\n all(): AnyNodeDefinition[] {\n return [...this.byId.values()];\n }\n}\n","import { z } from \"zod\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport type { AssetRef } from \"../../schema/refs.ts\";\nimport { getToolVersion, runCli } from \"./lib/cli-runner.ts\";\n\nconst FFMPEG_BIN = \"ffmpeg\";\n\nconst FORMAT_EXT = { mp3: \"mp3\", wav: \"wav\", m4a: \"m4a\" } as const;\nconst FORMAT_CODEC = { mp3: \"libmp3lame\", wav: \"pcm_s16le\", m4a: \"aac\" } as const;\n\nconst Track = z\n .object({\n /** Input slot name (must match a wired `inputs.<slot>` audio ref). */\n slot: z.string().min(1),\n /** When this track starts on the timeline, seconds from 0. */\n start_s: z.number().min(0),\n /**\n * Optional hard cap on this track's length, seconds. The clip is trimmed BEFORE\n * placement, so a source that runs long (an over-long voice extract, a converted\n * track that came back oversized) cannot bleed into the next track's window.\n */\n duration_s: z.number().positive().optional(),\n /**\n * Level adjustment in dB — negative attenuates. A MUSIC BED under speech\n * belongs at −20 dB (see the `describe` text: this number is a settled\n * decision, not a per-cut judgement).\n */\n gain_db: z\n .number()\n .optional()\n .describe(\n \"Level adjustment in dB (negative attenuates, 0 = untouched). A music bed under speech sits at −20 dB \" +\n \"and is sidechain-ducked as well; −12 dB crowded the voice and −13 dB was rejected by the client as \" +\n \"too loud. If a silent tail (an end card, a logo plate) sounds empty, do NOT raise the bed — wire the \" +\n \"same bed as a SECOND track windowed over the tail with its own higher gain. Measuring loudness across \" +\n \"a window that includes the silent tail is what makes a correct bed look quiet.\",\n ),\n })\n .strict();\n\n/**\n * Sidechain-duck one track (a music bed) under one or more key tracks (the voice):\n * whenever the key tracks carry signal, the ducked track's level drops, then recovers\n * in the gaps. Makes a music bed sit *dynamically* under speech instead of at a flat\n * level. `threshold` is linear 0–1 (lower = ducks more readily), `ratio` the\n * compression amount, `attack`/`release` in ms.\n */\nconst DuckSpec = z\n .object({\n track: z.string().min(1).describe(\"Slot to duck — the music bed.\"),\n against: z.array(z.string().min(1)).min(1).describe(\"Key slots whose signal ducks it — the voice tracks.\"),\n threshold: z\n .number()\n .min(0)\n .max(1)\n .optional()\n .describe(\"Linear 0–1, not dB. Lower ducks more readily. Default 0.03.\"),\n ratio: z.number().min(1).max(20).optional().describe(\"How hard it ducks. Default 8; 12 for a firm hold.\"),\n // MILLISECONDS is spelled out because a canvas shipped `attack: 0.05,\n // release: 0.45` — read as seconds — which is a 0.45 ms release: the bed\n // snapped back to full level between syllables and the client heard the\n // music as \"too loud\" at a level that measured correct.\n attack: z\n .number()\n .min(0.01)\n .optional()\n .describe(\"MILLISECONDS (not seconds). Typical 5–50; default 5. A value below 0.5 is a unit mistake.\"),\n release: z\n .number()\n .min(0.01)\n .optional()\n .describe(\n \"MILLISECONDS (not seconds). Typical 200–800; default 300. Anything under ~10 makes the bed pump back \" +\n \"up between words and is a unit mistake.\",\n ),\n })\n .strict();\n\nconst AudioTimelineParams = z\n .object({\n tracks: z.array(Track).min(1),\n /** Final track length in ms — pads short / trims long. Defaults to the natural mix length. */\n total_ms: z.number().int().positive().optional(),\n output_format: z.enum([\"mp3\", \"wav\", \"m4a\"]).optional(),\n /** Optional sidechain duck of one track under others (e.g. music under voice). */\n duck: DuckSpec.optional(),\n })\n .strict();\n\ntype AudioTimelineParamsT = z.infer<typeof AudioTimelineParams>;\n\nconst AudioTimelineInputs = z.record(z.string(), z.unknown());\nconst AudioTimelineOutputs = z.object({ audio: z.custom<AssetRef>() }).strict();\n\n/**\n * Build the ffmpeg argv for an audio timeline: one `-i` per track (in order,\n * so track i is ffmpeg input i), an `adelay` (+ optional `volume`) per track\n * to place it, an `amix` to combine them (`normalize=0` preserves the relative\n * levels set via `gain_db`), and an optional `apad`+`atrim` to pin the final\n * length. Pure + deterministic so it unit-tests without ffmpeg.\n */\n/**\n * Sidechain-duck `duck.track` under `duck.against` IN PLACE: split each key label into a\n * mix-copy + key-copy, combine the keys, and compress the ducked track against them.\n * Rewrites the relevant `labelFor` entries (music → ducked, each key → its mix-copy) and\n * appends to `filterChains`. No-op when the named slots aren't present (validated upstream).\n */\nfunction applyDuck(params: AudioTimelineParamsT, labelFor: string[], filterChains: string[]): void {\n const duck = params.duck;\n if (!duck) return;\n const trackIdx = params.tracks.findIndex((t) => t.slot === duck.track);\n const keyIdxs = duck.against.map((s) => params.tracks.findIndex((t) => t.slot === s)).filter((i) => i >= 0);\n if (trackIdx < 0 || keyIdxs.length === 0) return;\n\n const keyLabels: string[] = [];\n for (const ki of keyIdxs) {\n const base = labelFor[ki];\n filterChains.push(`[${base}]asplit=2[${base}m][${base}k]`);\n labelFor[ki] = `${base}m`;\n keyLabels.push(`[${base}k]`);\n }\n let keyOut = keyLabels[0] as string;\n if (keyLabels.length > 1) {\n filterChains.push(`${keyLabels.join(\"\")}amix=inputs=${keyLabels.length}:normalize=0[duckkey]`);\n keyOut = \"[duckkey]\";\n }\n const th = duck.threshold ?? 0.03;\n const ra = duck.ratio ?? 8;\n const at = duck.attack ?? 5;\n const re = duck.release ?? 300;\n filterChains.push(\n `[${labelFor[trackIdx]}]${keyOut}sidechaincompress=threshold=${th}:ratio=${ra}:attack=${at}:release=${re}[ducked]`,\n );\n labelFor[trackIdx] = \"ducked\";\n}\n\nexport function buildAudioTimelineArgs(params: AudioTimelineParamsT): string[] {\n const fmt = params.output_format ?? \"mp3\";\n const inputArgs: string[] = [];\n const filterChains: string[] = [];\n // track index → the filter label that carries it into the final amix. Sidechain\n // ducking rewrites a couple of these (the music label → its ducked copy, each key\n // label → its split mix-copy) without changing the per-track placement chains.\n const labelFor: string[] = [];\n params.tracks.forEach((track, i) => {\n inputArgs.push(\"-i\", `{{in.${track.slot}}}`);\n const delayMs = Math.round(track.start_s * 1000);\n // The cap trims BEFORE the delay so it bounds the clip itself, not the timeline.\n const steps = [\n ...(track.duration_s !== undefined ? [`atrim=0:${track.duration_s}`] : []),\n `adelay=${delayMs}:all=1`,\n ];\n if (track.gain_db !== undefined) steps.push(`volume=${track.gain_db}dB`);\n const label = `a${i}`;\n filterChains.push(`[${i}:a]${steps.join(\",\")}[${label}]`);\n labelFor[i] = label;\n });\n\n applyDuck(params, labelFor, filterChains);\n\n const mixLabels = labelFor.map((l) => `[${l}]`);\n let graph = `${filterChains.join(\";\")};${mixLabels.join(\"\")}amix=inputs=${params.tracks.length}:normalize=0`;\n if (params.total_ms !== undefined) {\n const totalS = params.total_ms / 1000;\n graph += `[mixed];[mixed]apad,atrim=0:${totalS}`;\n }\n graph += \"[out]\";\n\n return [...inputArgs, \"-filter_complex\", graph, \"-map\", \"[out]\", \"-c:a\", FORMAT_CODEC[fmt], \"{{out.audio}}\"];\n}\n\nexport const audioTimelineNode = defineNode({\n id: \"audio_timeline\",\n version: \"1.2.0\",\n category: \"audio\",\n location: \"local\",\n summary:\n \"Place and mix several audio clips onto one timeline: each track starts at a given second (optionally level-adjusted in dB), then they're combined into a single track. Built for laying a music bed plus timed voiceover lines and sound effects under a video.\",\n when_to_use:\n \"Use to assemble a full audio bed from separately-generated clips — e.g. a `music` bed at 0 (ducked via `gain_db: -12`), each scene's `tts` voiceover at its scene start, and `sound_effect` hits at their timestamps. Wire each clip as `inputs.<slot>` (audio AssetRef) and list it in `params.tracks` with `{slot, start_s, duration_s?, gain_db?}` (`duration_s` hard-caps a clip so it can't bleed into the next track's window). Set `total_ms` to pin the final length to the video. Requires `ffmpeg` on PATH.\",\n inputs: AudioTimelineInputs,\n params: AudioTimelineParams,\n outputs: AudioTimelineOutputs,\n // The mixed timeline is an audio asset — declare it so strictly-typed consumers\n // (e.g. audio_voice_convert reading a merged per-speaker track) resolve its kind.\n outputKinds: { audio: \"audio\" },\n cost: () => ({ credits: 0, seconds_estimate: 10 }),\n\n validateExtra({ rawParams, rawInputs }) {\n const issues: Array<{ path: string; message: string }> = [];\n const parsed = AudioTimelineParams.safeParse(rawParams ?? {});\n if (!parsed.success) return issues; // shape errors already surfaced by the param validator\n const inputKeys = new Set(Object.keys((rawInputs as Record<string, unknown>) ?? {}));\n parsed.data.tracks.forEach((track, i) => {\n if (!inputKeys.has(track.slot)) {\n issues.push({\n path: `params.tracks[${i}].slot`,\n message: `track slot \"${track.slot}\" has no matching wired input — add inputs.${track.slot}`,\n });\n }\n });\n const duck = parsed.data.duck;\n if (duck) {\n const slots = new Set(parsed.data.tracks.map((t) => t.slot));\n if (!slots.has(duck.track)) {\n issues.push({ path: \"params.duck.track\", message: `duck.track \"${duck.track}\" is not one of the tracks` });\n }\n duck.against.forEach((s, k) => {\n if (!slots.has(s)) {\n issues.push({ path: `params.duck.against[${k}]`, message: `duck.against \"${s}\" is not one of the tracks` });\n }\n if (s === duck.track) {\n issues.push({ path: `params.duck.against[${k}]`, message: \"a track cannot duck against itself\" });\n }\n });\n }\n return issues;\n },\n\n async cacheKeyExtras() {\n return { ffmpeg_version: await getToolVersion(FFMPEG_BIN) };\n },\n\n async execute({ inputs, params, ctx }) {\n return await runCli({\n bin: FFMPEG_BIN,\n args: buildAudioTimelineArgs(params),\n inputs: inputs as Record<string, AssetRef | AssetRef[]>,\n outputs: { audio: { kind: \"audio\", ext: FORMAT_EXT[params.output_format ?? \"mp3\"] } },\n ctx,\n });\n },\n});\n","import { execFile as execFileCb, spawn } from \"node:child_process\";\nimport { copyFile, mkdtemp, readFile, rm, stat } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport type { ExecCtx } from \"../../../engine/context.ts\";\nimport type { AssetKind, AssetRef } from \"../../../schema/refs.ts\";\n\nconst execFile = promisify(execFileCb);\n\ntype CliOutputSpec = {\n kind: AssetKind;\n ext: string;\n};\n\ntype RunCliArgs = {\n /** Binary to spawn (must be on PATH). */\n bin: string;\n /** argv list with `{{in.<slot>}}` and `{{out.<name>}}` placeholders. */\n args: readonly string[];\n /** Input slots — each becomes `{{in.<slot>}}` (single asset) or `{{in.<slot>.<index>}}` (array). */\n inputs: Record<string, AssetRef | AssetRef[]>;\n /** Output declarations — each becomes `{{out.<name>}}`; engine allocates the path. */\n outputs: Record<string, CliOutputSpec>;\n ctx: ExecCtx;\n /** Process timeout. Default: 10 minutes. */\n timeoutMs?: number;\n};\n\nconst DEFAULT_TIMEOUT_MS = 10 * 60 * 1000;\n\nconst URL_SCHEME_RE = /^[a-zA-Z][a-zA-Z0-9+.-]*:\\/\\//;\n\nconst MIME_BY_EXT: Record<string, string> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n webp: \"image/webp\",\n gif: \"image/gif\",\n avif: \"image/avif\",\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n mov: \"video/quicktime\",\n mp3: \"audio/mpeg\",\n wav: \"audio/wav\",\n m4a: \"audio/mp4\",\n ogg: \"audio/ogg\",\n flac: \"audio/flac\",\n};\n\nfunction mimeForExt(ext: string): string {\n const clean = ext.startsWith(\".\") ? ext.slice(1) : ext;\n return MIME_BY_EXT[clean.toLowerCase()] ?? \"application/octet-stream\";\n}\n\nfunction extForAssetRef(ref: AssetRef): string {\n // Prefer the on-disk extension if we have a local path; fall back to mime.\n if (ref.path) {\n const e = path.extname(ref.path);\n if (e) return e;\n }\n const reverse: Record<string, string> = {\n \"image/png\": \".png\",\n \"image/jpeg\": \".jpg\",\n \"image/webp\": \".webp\",\n \"video/mp4\": \".mp4\",\n \"video/webm\": \".webm\",\n \"video/quicktime\": \".mov\",\n \"audio/mpeg\": \".mp3\",\n \"audio/wav\": \".wav\",\n \"audio/mp4\": \".m4a\",\n \"audio/ogg\": \".ogg\",\n };\n return reverse[ref.mime] ?? \".bin\";\n}\n\n/**\n * Build the placeholder → absolute-path lookup table for one node invocation.\n * - Single AssetRef inputs register as `in.<slot>`.\n * - Array AssetRef inputs register each element as `in.<slot>.<index>`.\n * - Declared outputs register as `out.<name>`.\n *\n * Returns the lookup table plus the list of staged input paths and allocated\n * output paths so the caller can copy/read them.\n */\ntype Placeholders = {\n lookup: Map<string, string>;\n stagedInputs: { srcPath: string; destPath: string }[];\n outputPaths: { name: string; absPath: string; spec: CliOutputSpec }[];\n};\n\nfunction planArrayInputSlot(\n tmpDir: string,\n slot: string,\n values: AssetRef[],\n lookup: Map<string, string>,\n stagedInputs: Placeholders[\"stagedInputs\"],\n): void {\n for (let i = 0; i < values.length; i++) {\n const ref = values[i];\n if (!ref) continue;\n if (!ref.path) throw new Error(`cli-runner: inputs.${slot}[${i}] has no local path`);\n const dest = path.join(tmpDir, `in_${slot}_${i}${extForAssetRef(ref)}`);\n stagedInputs.push({ srcPath: ref.path, destPath: dest });\n lookup.set(`in.${slot}.${i}`, dest);\n }\n}\n\nfunction planSingleInputSlot(\n tmpDir: string,\n slot: string,\n ref: AssetRef,\n lookup: Map<string, string>,\n stagedInputs: Placeholders[\"stagedInputs\"],\n): void {\n if (!ref.path) throw new Error(`cli-runner: inputs.${slot} has no local path`);\n const dest = path.join(tmpDir, `in_${slot}${extForAssetRef(ref)}`);\n stagedInputs.push({ srcPath: ref.path, destPath: dest });\n lookup.set(`in.${slot}`, dest);\n}\n\nfunction planOutputs(\n tmpDir: string,\n outputs: Record<string, CliOutputSpec>,\n lookup: Map<string, string>,\n): Placeholders[\"outputPaths\"] {\n const outputPaths: Placeholders[\"outputPaths\"] = [];\n for (const [name, spec] of Object.entries(outputs)) {\n const ext = spec.ext.startsWith(\".\") ? spec.ext : `.${spec.ext}`;\n const absPath = path.join(tmpDir, `out_${name}${ext}`);\n outputPaths.push({ name, absPath, spec });\n lookup.set(`out.${name}`, absPath);\n }\n return outputPaths;\n}\n\nfunction planPlaceholders(\n tmpDir: string,\n inputs: Record<string, AssetRef | AssetRef[]>,\n outputs: Record<string, CliOutputSpec>,\n): Placeholders {\n const lookup = new Map<string, string>();\n const stagedInputs: Placeholders[\"stagedInputs\"] = [];\n\n for (const [slot, value] of Object.entries(inputs)) {\n if (Array.isArray(value)) {\n planArrayInputSlot(tmpDir, slot, value, lookup, stagedInputs);\n } else {\n planSingleInputSlot(tmpDir, slot, value, lookup, stagedInputs);\n }\n }\n\n const outputPaths = planOutputs(tmpDir, outputs, lookup);\n return { lookup, stagedInputs, outputPaths };\n}\n\nconst PLACEHOLDER_RE = /\\{\\{\\s*([a-zA-Z0-9_.]+)\\s*\\}\\}/g;\n\n/**\n * Substitute `{{in.X}}` / `{{out.Y}}` placeholders in a single arg string.\n * Returns the new string and the set of placeholder keys it consumed.\n * Throws if a placeholder isn't in the lookup.\n */\nfunction substituteArg(arg: string, lookup: Map<string, string>): string {\n return arg.replace(PLACEHOLDER_RE, (_match, key: string) => {\n const value = lookup.get(key);\n if (value === undefined) {\n throw new Error(\n `cli-runner: unknown placeholder \"{{${key}}}\" — declared inputs/outputs: ${[...lookup.keys()].join(\", \")}`,\n );\n }\n return value;\n });\n}\n\n/**\n * After substitution, reject arg strings that look like raw filesystem paths\n * outside our staging dir, or URL inputs. The threat model is \"trusted local\n * canvas shouldn't accidentally reach outside the engine's content-addressed\n * world.\" Args that resolve to staging-dir paths via placeholders pass cleanly.\n */\nfunction rejectRawPaths(substituted: string, original: string, stagingDir: string): void {\n // URL schemes — block ffmpeg/magick from fetching arbitrary http/file/data inputs.\n if (URL_SCHEME_RE.test(substituted)) {\n throw new Error(\n `cli-runner: URL-style arg \"${original}\" not allowed — ingest the asset upstream (e.g. via the ingest node) and wire it as an input slot.`,\n );\n }\n // Home-relative — never allow.\n if (substituted.startsWith(\"~/\") || substituted === \"~\") {\n throw new Error(`cli-runner: home-relative path \"${original}\" not allowed in args.`);\n }\n // Absolute paths must live under the staging dir.\n if (substituted.startsWith(\"/\")) {\n const resolved = path.resolve(substituted);\n if (!resolved.startsWith(`${stagingDir}${path.sep}`) && resolved !== stagingDir) {\n throw new Error(\n `cli-runner: raw filesystem path \"${original}\" not allowed — declare an input slot and use {{in.<slot>}} instead.`,\n );\n }\n }\n // Relative path tokens — `./foo`, `../foo` — block.\n if (substituted.startsWith(\"./\") || substituted.startsWith(\"../\")) {\n throw new Error(`cli-runner: relative path \"${original}\" not allowed in args.`);\n }\n}\n\nasync function stageInputs(staged: Placeholders[\"stagedInputs\"]): Promise<void> {\n for (const { srcPath, destPath } of staged) {\n await copyFile(srcPath, destPath);\n }\n}\n\ntype SpawnResult = { code: number; stderr: string };\n\nfunction spawnAndWait(bin: string, args: readonly string[], timeoutMs: number): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(bin, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n const stderrChunks: Buffer[] = [];\n let stderrLen = 0;\n const MAX_STDERR = 256 * 1024;\n\n child.stdout.on(\"data\", () => {\n // Discard stdout — large CLI tools can flood it; we surface stderr on failure.\n });\n child.stderr.on(\"data\", (chunk: Buffer) => {\n if (stderrLen < MAX_STDERR) {\n stderrChunks.push(chunk);\n stderrLen += chunk.length;\n }\n });\n\n const timer = setTimeout(() => {\n child.kill(\"SIGKILL\");\n reject(new Error(`cli-runner: ${bin} timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n child.on(\"error\", (err) => {\n clearTimeout(timer);\n reject(new Error(`cli-runner: failed to spawn \"${bin}\" — ${err.message}`));\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n const stderr = Buffer.concat(stderrChunks).toString(\"utf8\");\n resolve({ code: code ?? -1, stderr });\n });\n });\n}\n\nfunction tailLines(text: string, maxLines: number): string {\n const lines = text.split(\"\\n\");\n return lines.slice(-maxLines).join(\"\\n\");\n}\n\n/**\n * Run a local CLI binary with engine-staged inputs and engine-allocated outputs.\n *\n * Contract:\n * - `args` are passed as argv (no shell). `{{in.<slot>}}` / `{{out.<name>}}`\n * placeholders are substituted with absolute paths under a per-node tmp dir.\n * - After substitution, raw filesystem paths and URL-style inputs are rejected.\n * - Every declared `outputs` entry must exist and be non-empty after exit.\n * - Outputs are ingested into the asset store as the declared `kind`.\n * - Tmp dir is removed in `finally`.\n */\nexport async function runCli(opts: RunCliArgs): Promise<Record<string, AssetRef>> {\n const { bin, args, inputs, outputs, ctx, timeoutMs = DEFAULT_TIMEOUT_MS } = opts;\n\n const tmpDir = await mkdtemp(path.join(tmpdir(), `cli-${bin.replace(/[^a-z0-9]/gi, \"\")}-`));\n try {\n const { lookup, stagedInputs, outputPaths } = planPlaceholders(tmpDir, inputs, outputs);\n await stageInputs(stagedInputs);\n ctx.log(`staged ${stagedInputs.length} inputs in ${tmpDir}`);\n\n const substituted = args.map((arg) => {\n const next = substituteArg(arg, lookup);\n rejectRawPaths(next, arg, tmpDir);\n return next;\n });\n\n ctx.log(`running ${bin} (${substituted.length} args)`);\n const { code, stderr } = await spawnAndWait(bin, substituted, timeoutMs);\n if (code !== 0) {\n throw new Error(`cli-runner: ${bin} exited ${code}\\n${tailLines(stderr, 40)}`);\n }\n\n const result: Record<string, AssetRef> = {};\n for (const { name, absPath, spec } of outputPaths) {\n const s = await stat(absPath).catch(() => null);\n if (!s?.isFile() || s.size === 0) {\n throw new Error(`cli-runner: declared output \"${name}\" missing or empty at ${absPath}`);\n }\n const bytes = await readFile(absPath);\n const ref = await ctx.assets.ingestBytes({\n bytes: Buffer.from(bytes),\n kind: spec.kind,\n mime: mimeForExt(spec.ext),\n });\n result[name] = ref;\n }\n return result;\n } finally {\n await rm(tmpDir, { recursive: true, force: true }).catch((e) => {\n ctx.log(`cli-runner: tmp cleanup failed (${(e as Error).message})`);\n });\n }\n}\n\n/**\n * Capture the binary's `-version` first line for cache-key inclusion.\n * Memoized per-binary per-process. Bumping the host CLI busts cache automatically.\n */\nconst VERSION_CACHE = new Map<string, string>();\n\nexport async function getToolVersion(bin: string): Promise<string> {\n const cached = VERSION_CACHE.get(bin);\n if (cached !== undefined) return cached;\n try {\n const { stdout } = await execFile(bin, [\"-version\"], { encoding: \"utf-8\", maxBuffer: 1024 * 1024 });\n const firstLine = stdout.split(\"\\n\")[0]?.trim() ?? \"\";\n VERSION_CACHE.set(bin, firstLine);\n return firstLine;\n } catch {\n // Don't fail the run on version probe issues; cache key folds in a stable marker.\n const fallback = `${bin}:unknown`;\n VERSION_CACHE.set(bin, fallback);\n return fallback;\n }\n}\n\n// Exported for tests.\nexport const _internal = {\n planPlaceholders,\n substituteArg,\n rejectRawPaths,\n mimeForExt,\n extForAssetRef,\n};\n","import { z } from \"zod\";\nimport { defineNode, type StaticTiming } from \"../../engine/define.ts\";\nimport type { AssetRef } from \"../../schema/refs.ts\";\nimport { getToolVersion, runCli } from \"./lib/cli-runner.ts\";\n\nconst FFMPEG_BIN = \"ffmpeg\";\n\nconst Loudnorm = z\n .object({\n i: z.number().default(-14).describe(\"Integrated loudness target, LUFS. -14 is the social/streaming target.\"),\n tp: z.number().default(-1.5).describe(\"True-peak ceiling, dBTP.\"),\n lra: z.number().default(11).describe(\"Loudness range target, LU.\"),\n })\n .strict();\n\nexport const AvMuxParams = z\n .object({\n loudnorm: z\n .union([z.literal(false), Loudnorm])\n .default({ i: -14, tp: -1.5, lra: 11 })\n .describe(\n \"Loudness normalization of the soundtrack (EBU R128). The raw mix is a quiet track that reads as \" +\n '\"no sound\" in casual players, so it is on by default at -14 LUFS / -1.5 dBTP. `false` keeps the mix level.',\n ),\n audio_bitrate: z\n .string()\n .regex(/^\\d+k$/, 'a bitrate like \"192k\"')\n .default(\"192k\")\n .describe(\"AAC bitrate of the delivered soundtrack.\"),\n sample_rate: z.number().int().positive().default(48000).describe(\"Delivered sample rate, Hz.\"),\n length: z\n .union([z.literal(\"shortest\"), z.object({ total_s: z.number().positive() }).strict()])\n .default(\"shortest\")\n .describe(\n \"`shortest` ends the file with the shorter stream, so a picture and mix pinned to the same timeline \" +\n \"come out exact (a longer one is silently cut: `canvas validate` checks both against the timeline). \" +\n \"`{ total_s }` cuts both streams at that second; they must each run at least that long.\",\n ),\n })\n .strict();\nexport type AvMuxParamsT = z.infer<typeof AvMuxParams>;\n\nconst AvMuxInputs = z\n .object({\n video: z.custom<AssetRef>().describe(\"The finished picture (its own audio, if any, is dropped).\"),\n audio: z.custom<AssetRef>().describe(\"The mixed soundtrack, usually an `audio_timeline`.\"),\n })\n .strict();\nconst AvMuxOutputs = z.object({ video: z.custom<AssetRef>() }).strict();\n\n/** The audio filter: optional loudness normalization, always an upmix to stereo. */\nfunction audioFilter(params: AvMuxParamsT): string {\n const stereo = \"aformat=channel_layouts=stereo\";\n if (params.loudnorm === false) return stereo;\n const { i, tp, lra } = params.loudnorm;\n return `loudnorm=I=${i}:TP=${tp}:LRA=${lra},${stereo}`;\n}\n\n/**\n * The ffmpeg argv the node runs: the picture stream-copied (no generational loss),\n * the soundtrack normalized and encoded, the length decided by `params.length`.\n */\nexport function compileAvMuxArgs(params: AvMuxParamsT): string[] {\n return [\n \"-i\",\n \"{{in.video}}\",\n \"-i\",\n \"{{in.audio}}\",\n \"-map\",\n \"0:v:0\",\n \"-map\",\n \"1:a:0\",\n \"-c:v\",\n \"copy\",\n \"-af\",\n audioFilter(params),\n \"-c:a\",\n \"aac\",\n \"-b:a\",\n params.audio_bitrate,\n \"-ar\",\n String(params.sample_rate),\n ...(params.length === \"shortest\" ? [\"-shortest\"] : [\"-t\", params.length.total_s.toFixed(3)]),\n \"{{out.video}}\",\n ];\n}\n\n/** The delivered length and raster, before anything runs. */\nexport function avMuxTiming(\n params: AvMuxParamsT,\n inputs: Readonly<Record<string, StaticTiming | undefined>>,\n): StaticTiming {\n const { width, height } = inputs.video ?? {};\n const raster = { ...(width !== undefined ? { width } : {}), ...(height !== undefined ? { height } : {}) };\n if (params.length !== \"shortest\") return { ...raster, duration_s: params.length.total_s };\n const video = inputs.video?.duration_s;\n const audio = inputs.audio?.duration_s;\n if (video === undefined || audio === undefined) return raster;\n return { ...raster, duration_s: Math.min(video, audio) };\n}\n\nexport const avMuxNode = defineNode({\n id: \"av_mux\",\n version: \"1.0.0\",\n category: \"video\",\n location: \"local\",\n summary:\n \"Put a soundtrack under a finished picture: the video is stream-copied, the audio loudness-normalized (-14 LUFS by default), upmixed to stereo and encoded to AAC, and the file's length follows an explicit policy (the shorter stream, or a pinned total).\",\n when_to_use:\n \"Use as the last step of a video canvas (the scaffold's `final`). Start here: \" +\n '`{ \"type\": \"av_mux\", \"inputs\": { \"video\": \"$ref:overlaid.video\", \"audio\": \"$ref:audio_mix.audio\" }, ' +\n '\"params\": { \"length\": \"shortest\" } }`. Keep the default loudness unless a client asks for a quieter ' +\n \"master. Use `length: { total_s }` only when the picture and mix are deliberately longer than the cut. \" +\n \"Reach for a raw `ffmpeg` node only for a mux this cannot express (several audio tracks, burned subtitles).\",\n inputs: AvMuxInputs,\n params: AvMuxParams,\n outputs: AvMuxOutputs,\n outputKinds: { video: \"video\" },\n cost: () => ({ credits: 0, seconds_estimate: 10 }),\n staticTiming: ({ params, inputs }) => avMuxTiming(params, inputs),\n\n async cacheKeyExtras() {\n return { ffmpeg_version: await getToolVersion(FFMPEG_BIN) };\n },\n\n async execute({ inputs, params, ctx }) {\n return (await runCli({\n bin: FFMPEG_BIN,\n args: compileAvMuxArgs(params),\n inputs: { video: inputs.video, audio: inputs.audio },\n outputs: { video: { kind: \"video\", ext: \"mp4\" } },\n ctx,\n })) as { video: AssetRef };\n },\n});\n","import { z } from \"zod\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport { ImageRef } from \"../../schema/refs.ts\";\n\nexport const collectNode = defineNode({\n id: \"collect\",\n version: \"1.0.0\",\n category: \"data\",\n location: \"local\",\n passthroughRefs: true,\n summary:\n \"Gather images from multiple upstream nodes into one ordered array — the standard terminal for multi-variant canvases whose final output is several images.\",\n when_to_use:\n \"Point the canvas `output` at this node when several independent branches (e.g. one image_generate per scene/variant) must ALL be finals. Wire `inputs.images` as an array of refs like `$ref:gen_billboard_03.images#0` — each final inherits its producer node id as its label (or set `params.labels` to override), so variants stay identifiable in the dashboard and selection.\",\n inputs: z.object({ images: z.array(ImageRef).min(1) }).strict(),\n params: z.object({ labels: z.array(z.string().min(1)).min(1).optional() }).strict(),\n outputs: z.object({ images: z.array(ImageRef).min(1) }).strict(),\n outputKinds: { images: \"image\" },\n cost: () => ({ credits: 0, seconds_estimate: 0 }),\n // Arity is only knowable at validate time when `images` is a literal array;\n // a single `$ref:` string to an upstream array output defers to runtime.\n validateExtra: ({ rawParams, rawInputs }) => {\n const labels = (rawParams as { labels?: unknown } | undefined)?.labels;\n if (!Array.isArray(labels)) return [];\n if (new Set(labels).size !== labels.length) {\n return [{ path: \"params.labels\", message: \"labels must be unique — each names one output variant\" }];\n }\n const images = (rawInputs as { images?: unknown } | undefined)?.images;\n if (Array.isArray(images) && labels.length !== images.length) {\n return [\n {\n path: \"params.labels\",\n message: `labels has ${labels.length} entries but ${images.length} images are wired — provide one label per image`,\n },\n ];\n }\n return [];\n },\n execute: ({ inputs }) => Promise.resolve({ images: inputs.images }),\n});\n","import { z } from \"zod\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport type { AssetRef } from \"../../schema/refs.ts\";\nimport { getToolVersion, runCli } from \"./lib/cli-runner.ts\";\n\nconst FFMPEG_BIN = \"ffmpeg\";\n\nconst OutputDecl = z\n .object({\n kind: z.enum([\"image\", \"video\", \"audio\"]),\n ext: z.string().min(1).max(8),\n })\n .strict();\n\nconst FfmpegParams = z\n .object({\n args: z.array(z.string()).min(1),\n outputs: z.record(z.string(), OutputDecl).default({}),\n })\n .strict();\n\n// Inputs are open — every canvas names its own slots. The cli-runner stages\n// any AssetRef-shaped value (or array of them) into the tmp dir keyed by slot.\nconst FfmpegInputs = z.record(z.string(), z.unknown());\n\n// Outputs are also open — keyed by the same names the canvas declared under\n// `params.outputs`. Each entry is an AssetRef.\nconst FfmpegOutputs = z.record(z.string(), z.custom<AssetRef>());\n\nexport const ffmpegNode = defineNode({\n id: \"ffmpeg\",\n version: \"2.0.0\",\n category: \"video\",\n location: \"local\",\n summary:\n \"Local ffmpeg passthrough. Declare inputs, declare outputs, write the argv you'd type on the command line. Inputs are staged into a tmp dir and reached via `{{in.<slot>}}`; declared outputs are allocated at `{{out.<name>}}` and ingested as assets when the run completes.\",\n when_to_use:\n \"Use whenever you'd reach for ffmpeg on the command line: trim, concat, scale, overlay, extract audio, generate thumbnails, mux/demux. Pass the full argv as `params.args` (no shell — argv array, no string interpolation). \" +\n \"Wire input files via `inputs.<slot>` (single AssetRef) or `inputs.<slot>: [...]` (array, addressed as `{{in.<slot>.0}}`, `{{in.<slot>.1}}`). \" +\n \"Declare every output file under `params.outputs` (name → {kind, ext}); the engine allocates the path, you reference it with `{{out.<name>}}`. \" +\n \"Requires `ffmpeg` on PATH. URL-style inputs (http://, file://) and raw filesystem paths in args are rejected — keep everything in the engine's asset model.\",\n inputs: FfmpegInputs,\n params: FfmpegParams,\n outputs: FfmpegOutputs,\n cost: () => ({ credits: 0, seconds_estimate: 15 }),\n\n async cacheKeyExtras() {\n return { ffmpeg_version: await getToolVersion(FFMPEG_BIN) };\n },\n\n async execute({ inputs, params, ctx }) {\n return await runCli({\n bin: FFMPEG_BIN,\n args: params.args,\n inputs: inputs as Record<string, AssetRef | AssetRef[]>,\n outputs: params.outputs,\n ctx,\n });\n },\n});\n","import { mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport { NodeExecutionError } from \"../../engine/errors.ts\";\nimport { FontRef, ImageRef } from \"../../schema/refs.ts\";\nimport { extForMime } from \"../../storage/asset-store.ts\";\nimport { uploadAndIngest } from \"../ingest.ts\";\nimport { stageAsset } from \"./lib/assets.ts\";\n\nconst require_ = createRequire(import.meta.url);\n\nexport const DEFAULT_SPECIMEN = [\n \"The quick brown fox jumps over the lazy dog\",\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\",\n \"abcdefghijklmnopqrstuvwxyz\",\n \"0123456789 !?&@#$%().,:;'\\\"-\",\n].join(\"\\n\");\n\nconst FontSpecimenParams = z\n .object({\n text: z.string().min(1).max(2000).optional().default(DEFAULT_SPECIMEN),\n font_size: z.number().int().min(8).max(512).optional().default(72),\n padding: z.number().int().min(0).max(512).optional().default(64),\n line_height: z.number().min(0.8).max(3).optional().default(1.35),\n max_width: z.number().int().min(256).max(4096).optional(),\n })\n .strict();\n\ntype Params = z.infer<typeof FontSpecimenParams>;\n\n// `.loose()` so the exact copy that will appear in the ad can be wired in from\n// an upstream node (e.g. text_generate) and referenced via `{{slot}}` in the\n// `text` param — render the specimen on the real headline, not placeholder text.\nconst FontSpecimenInputs = z.object({ font: FontRef }).loose();\nconst FontSpecimenOutputs = z.object({ image: ImageRef }).strict();\n\n// Retina export, consistent with hyperframe_snapshot.\nconst DEVICE_SCALE_FACTOR = 2;\nconst PAGE_TIMEOUT_MS = 30_000;\n\nfunction escapeHtml(text: string): string {\n return text\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll('\"', \"&quot;\")\n .replaceAll(\"'\", \"&#39;\");\n}\n\n/**\n * Self-contained specimen page: the staged font is the ONLY family declared,\n * so a load failure is detectable instead of silently falling back to a\n * system font (which would defeat the node's purpose).\n */\nfunction buildSpecimenHtml(params: Params, fontFilename: string): string {\n const widthRule = params.max_width === undefined ? \"width: max-content;\" : `max-width: ${params.max_width}px;`;\n return `<!doctype html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<style>\n @font-face {\n font-family: 'SpecimenFont';\n src: url('${fontFilename}');\n }\n html, body { margin: 0; background: #fff; }\n #specimen {\n font-family: 'SpecimenFont';\n color: #000;\n background: #fff;\n font-size: ${params.font_size}px;\n line-height: ${params.line_height};\n padding: ${params.padding}px;\n white-space: pre-wrap;\n overflow-wrap: break-word;\n ${widthRule}\n }\n</style>\n</head>\n<body><div id=\"specimen\">${escapeHtml(params.text)}</div></body>\n</html>\n`;\n}\n\nexport const fontSpecimenNode = defineNode({\n id: \"font_specimen\",\n version: \"1.1.0\",\n category: \"image\",\n location: \"local\",\n summary:\n \"Render specimen text in a given font file to a PNG — black text on a white background — via headless Chromium. \" +\n \"Produces a typeface reference image an image model can replicate.\",\n when_to_use:\n \"Use when a generated image must contain text in a specific brand font: wire `image` into `image_generate`'s `reference` input so the model copies the typeface. \" +\n 'Input is a `font` asset (ttf/otf/woff/woff2) — get one via `ingest` with `expect: \"font\"`. ' +\n \"Default specimen covers a pangram, both alphabets, digits and punctuation; override with `params.text` (e.g. the exact headline to render).\",\n inputs: FontSpecimenInputs,\n params: FontSpecimenParams,\n outputs: FontSpecimenOutputs,\n outputKinds: { image: \"image\" },\n cost: () => ({ credits: 0, seconds_estimate: 5 }),\n\n async execute({ inputs, params, ctx }) {\n const tmp = await mkdtemp(path.join(tmpdir(), \"font-specimen-\"));\n try {\n const fontFilename = `font.${extForMime(inputs.font.mime)}`;\n await stageAsset(inputs.font, tmp, fontFilename);\n\n const entryPath = path.join(tmp, \"index.html\");\n await writeFile(entryPath, buildSpecimenHtml(params, fontFilename), \"utf-8\");\n\n ctx.log(`rendering specimen (${params.font_size}px, ${params.text.split(\"\\n\").length} lines)`);\n\n const pwSpecifier = [\"play\", \"wright\"].join(\"\");\n const playwright = require_(pwSpecifier) as typeof import(\"playwright\");\n const browser = await playwright.chromium.launch({ headless: true });\n try {\n const context = await browser.newContext({\n viewport: { width: 1280, height: 720 },\n deviceScaleFactor: DEVICE_SCALE_FACTOR,\n });\n const page = await context.newPage();\n await page.goto(`file://${entryPath}`, { waitUntil: \"load\", timeout: PAGE_TIMEOUT_MS });\n\n // Fail loudly when Chromium can't parse the font — the page declares\n // no fallback family, but a broken file would otherwise still render\n // with the browser's last-resort font and silently lie downstream.\n const loaded = await page\n .evaluate(async () => {\n const faces = await document.fonts.load(\"16px 'SpecimenFont'\");\n await document.fonts.ready;\n return faces.length;\n })\n .catch(() => 0);\n if (loaded === 0) {\n throw new NodeExecutionError(ctx.nodeId, ctx.nodeType, {\n kind: \"local\",\n cause: new Error(\n `font_specimen: Chromium could not load the font (${inputs.font.mime}) — is the file a valid ttf/otf/woff/woff2?`,\n ),\n });\n }\n\n // A font can load yet cover none of the specimen's characters (e.g. a\n // script-subset woff2 with no Latin glyphs) — Chromium then falls back\n // per character and the specimen would silently show a system font.\n // Detection: a covered char measures identically under both fallback\n // stacks (the font itself renders it); an uncovered char differs\n // (monospace vs serif fallback metrics diverge).\n const { covered, missing } = await page.evaluate((text: string) => {\n const chars = [...new Set(text.replace(/\\s/g, \"\"))];\n const c = document.createElement(\"canvas\").getContext(\"2d\");\n if (!c) return { covered: chars.length, missing: [] as string[] };\n const missingChars: string[] = [];\n for (const ch of chars) {\n c.font = \"64px 'SpecimenFont', monospace\";\n const a = c.measureText(ch).width;\n c.font = \"64px 'SpecimenFont', serif\";\n const b = c.measureText(ch).width;\n if (a !== b) missingChars.push(ch);\n }\n return { covered: chars.length - missingChars.length, missing: missingChars };\n }, params.text);\n if (covered === 0) {\n throw new NodeExecutionError(ctx.nodeId, ctx.nodeType, {\n kind: \"local\",\n cause: new Error(\n \"font_specimen: the font loaded but provides no glyphs for the specimen text — is it a subset for another script? Use a full (e.g. latin) build of the font, or change params.text.\",\n ),\n });\n }\n if (missing.length > 0) {\n ctx.log(`warning: font has no glyphs for ${missing.length} character(s): ${missing.join(\" \")}`);\n }\n\n const specimen = page.locator(\"#specimen\");\n const box = await specimen.boundingBox();\n const bytes = await specimen.screenshot({ type: \"png\", timeout: PAGE_TIMEOUT_MS });\n ctx.log(`captured ${bytes.length} bytes`);\n\n const metadata: Record<string, unknown> = {\n font_sha256: inputs.font.sha256,\n font_mime: inputs.font.mime,\n };\n if (box) {\n metadata.width = Math.round(box.width * DEVICE_SCALE_FACTOR);\n metadata.height = Math.round(box.height * DEVICE_SCALE_FACTOR);\n }\n\n // Upload to R2 (not just the local store): downstream remote nodes\n // (image_generate reference) receive only `url` — see stripLocalRefs.\n const ref = await uploadAndIngest({\n bytes: Buffer.from(bytes),\n kind: \"image\",\n mime: \"image/png\",\n metadata,\n ctx,\n });\n return { image: ref as z.infer<typeof ImageRef> };\n } finally {\n await browser.close();\n }\n } finally {\n await rm(tmp, { recursive: true, force: true }).catch((cleanupErr) => {\n ctx.log(`warning: tmp cleanup failed (${(cleanupErr as Error).message})`);\n });\n }\n },\n});\n\n// Exported for unit tests.\nexport const _internal = {\n FontSpecimenParams,\n buildSpecimenHtml,\n};\n","import { copyFile, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { AssetRef } from \"../../../schema/refs.ts\";\n\n// Shape we accept: any AssetRef-ish value with at least a kind+mime and either\n// path or url. We don't import the Zod refs here so this helper stays usable\n// from anywhere without circulars.\nexport type StageableRef = { kind: string; mime: string; path?: string; url?: string };\n\n/**\n * Copy a local asset into `destDir` under `filename` (or, when `filename` is\n * omitted, `<key><ext>` derived from the ref's mime). Throws if the ref has no\n * local path — callers must materialise upstream assets before staging.\n */\nexport async function stageAsset(ref: StageableRef, destDir: string, filename: string): Promise<string> {\n if (!ref.path) {\n throw new Error(`stageAsset: ref (${ref.kind}/${ref.mime}) has no local path`);\n }\n const dest = path.join(destDir, filename);\n await copyFile(ref.path, dest);\n return dest;\n}\n\n/**\n * Returns an AssetRef as a URL string browser code can consume.\n * Prefers `ref.url`; falls back to a base64 `data:` URL built from `ref.path`.\n */\nexport async function refToUrl(ref: Pick<AssetRef, \"mime\" | \"path\" | \"url\">): Promise<string> {\n if (ref.url) return ref.url;\n if (!ref.path) {\n throw new Error(\"refToUrl: AssetRef has neither url nor path\");\n }\n const bytes = await readFile(ref.path);\n return `data:${ref.mime};base64,${bytes.toString(\"base64\")}`;\n}\n","import { execFile } from \"node:child_process\";\nimport { mkdtemp, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { cpus, tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { z } from \"zod\";\nimport { hashCompositionDir } from \"../../engine/composition-hash.ts\";\nimport {\n buildParamsSchema,\n type CompositionMeta,\n defaultFilenameForInput,\n loadCompositionMeta,\n} from \"../../engine/composition-meta.ts\";\nimport type { ExecCtx } from \"../../engine/context.ts\";\nimport { defineNode, type ValidateExtraFn } from \"../../engine/define.ts\";\nimport { type AssetRef, isStageableRef } from \"../../schema/refs.ts\";\nimport { refToUrl, type StageableRef, stageAsset } from \"./lib/assets.ts\";\nimport { copyComposition, vendorGsap } from \"./lib/composition-stage.ts\";\nimport { staticCompositionIssues } from \"./lib/composition-static-check.ts\";\nimport { runHyperframesCheck } from \"./lib/hyperframe-check.ts\";\nimport { mapKnownHyperframesError } from \"./lib/hyperframe-errors.ts\";\nimport { ensureHyperframesMetaJson } from \"./lib/hyperframe-meta.ts\";\nimport { substituteVariables } from \"./lib/templating.ts\";\n\nconst execFileAsync = promisify(execFile);\n\n// Runtime knobs are owned by the canvas-engine — we always render at max\n// quality, mp4, on the controlled E2B sandbox (see\n// `packages/e2b-template/src/template.ts`). The composition's own params\n// (`words_per_group`, `transcript`, etc.) ride alongside via `.catchall` and\n// are validated against the composition's meta.json by `validateExtra`.\nconst HyperframeParams = z\n .object({\n composition: z.string().min(1),\n // Output container. mp4 (default) for delivery; webm/mov render WITH\n // transparency (alpha) when the composition background is transparent —\n // use for motion-graphic overlays dropped into Premiere/AE/Nuke.\n format: z.enum([\"mp4\", \"webm\", \"mov\"]).optional().default(\"mp4\"),\n timeout_ms: z\n .number()\n .int()\n .positive()\n .optional()\n .default(10 * 60 * 1000),\n })\n .catchall(z.unknown());\n\n// Inputs are dynamic — meta.json declares which keys this composition\n// expects. The node accepts any keyed AssetRef and validates against meta\n// at execute time.\nconst HyperframeInputs = z.record(z.string(), z.custom<AssetRef>()).optional().default({});\n\nconst HyperframeOutputs = z\n .object({\n video: z.custom<AssetRef>(),\n })\n .strict();\n\nconst NODE_OWNED_PARAM_KEYS = new Set([\"composition\", \"format\", \"timeout_ms\"]);\n\nconst MIME_BY_FORMAT: Record<\"mp4\" | \"webm\" | \"mov\", string> = {\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n mov: \"video/quicktime\",\n};\n\n// Engine-injected: the substitution pass fills these from input asset duration\n// (and the composition's default_duration). Authors must not declare them.\nconst ENGINE_INJECTED_TOKENS = new Set([\"duration\"]);\n\ntype Params = z.infer<typeof HyperframeParams>;\n\nexport const hyperframeRenderNode = defineNode({\n id: \"hyperframe_render\",\n version: \"6.1.0\",\n category: \"video\",\n location: \"local\",\n summary:\n \"Render an mp4 by composing an HTML/CSS/GSAP composition over upstream assets. Point `params.composition` at a directory containing `index.html` + `meta.json`. All variables are passed as primitives in `params` and substituted into the composition before render.\",\n when_to_use:\n \"Use to add captions, lower-thirds, branded overlays, title cards, or any HTML-driven graphic over a video. \" +\n \"Point `params.composition` at a directory containing `index.html` + `meta.json`. \" +\n \"Inputs are keyed by the composition's `meta.json.inputs` map — wire `inputs.<key> = $ref:<node>.<output>`. \" +\n \"Output resolution/fps come from the composition's `meta.json`; quality and worker count are fixed by the engine. \" +\n \"Set `params.format` to `webm` or `mov` for a transparent (alpha) overlay to composite in another editor; defaults to `mp4`. \" +\n \"Runs a pre-render `hyperframes lint`/`inspect` gate (overflow/structural errors block; contrast warns).\",\n inputs: HyperframeInputs,\n params: HyperframeParams,\n outputs: HyperframeOutputs,\n cost: () => ({ credits: 0, seconds_estimate: 30 }),\n\n validateExtra: (args) => validateCompositionNode(args, NODE_OWNED_PARAM_KEYS),\n\n cacheKeyExtras: async ({ params }) => {\n const out: Record<string, string> = {};\n const composition = (params as { composition?: unknown }).composition;\n if (typeof composition !== \"string\") return out;\n const dir = await resolveCompositionDir(composition).catch(() => null);\n if (!dir) return out;\n out.composition_content_sha = await hashCompositionDir(dir);\n return out;\n },\n\n async execute({ inputs, params, ctx }) {\n const compositionDir = await resolveCompositionDir(params.composition);\n const meta = await loadCompositionMeta(compositionDir);\n const compositionParams = validateAndParseDynamicParams(meta, params);\n\n const tmp = await mkdtemp(path.join(tmpdir(), \"hf-render-\"));\n try {\n await copyComposition(compositionDir, tmp);\n await vendorGsap(tmp, ctx);\n\n const stagedDuration = await stageInputs(tmp, inputs, meta, ctx);\n const duration = stagedDuration ?? meta.default_duration;\n\n const substitutionValues = await buildSubstitutionValues(compositionParams, meta, duration);\n await substituteCompositionFiles(tmp, substitutionValues);\n await ensureHyperframesMetaJson(tmp, ctx.nodeId, meta, duration);\n\n // Pre-render quality gate on the SUBSTITUTED composition: lint + inspect.\n // Overflow/structural errors block; contrast + deferred-asset advisories\n // only warn. Degrades gracefully if the tool is unavailable.\n await runHyperframesCheck({ dir: tmp, nodeId: \"hyperframe_render\", ctx, timeoutMs: params.timeout_ms });\n\n const outputPath = path.join(tmp, `output.${params.format}`);\n\n await runRender({ tmp, outputPath, params, meta, ctx });\n\n const bytes = await readFile(outputPath);\n ctx.log(`rendered ${bytes.length} bytes`);\n const ref = await ctx.assets.ingestBytes({\n bytes: Buffer.from(bytes),\n kind: \"video\",\n mime: MIME_BY_FORMAT[params.format],\n metadata: {\n width: meta.width,\n height: meta.height,\n fps: meta.fps,\n duration_ms: Math.round(duration * 1000),\n },\n });\n return { video: ref };\n } finally {\n await rm(tmp, { recursive: true, force: true }).catch((e) => {\n ctx.log(`warning: tmp cleanup failed (${(e as Error).message})`);\n });\n }\n },\n});\n\n// ---------------------------------------------------------------------------\n// Composition resolution + dynamic param validation\n// ---------------------------------------------------------------------------\n\nexport async function resolveCompositionDir(composition: string): Promise<string> {\n const compositionPath = path.isAbsolute(composition) ? composition : path.resolve(process.cwd(), composition);\n const s = await stat(compositionPath);\n if (s.isDirectory()) return compositionPath;\n return path.dirname(compositionPath);\n}\n\n/**\n * `validateExtra` hook shared by both hyperframe nodes: meta-param validation PLUS\n * every refusal the render would make that the canvas already determines: an\n * unfilled `{{token}}`, a required input left unwired or wired to the wrong kind,\n * and the pre-render gate's lint (degrades gracefully when the binary is absent).\n * Each of these aborted a real run after it had paid for every clip upstream.\n */\nexport async function validateCompositionNode(\n args: Parameters<ValidateExtraFn>[0],\n ownedKeys: ReadonlySet<string>,\n): Promise<{ path: string; message: string }[]> {\n const issues = await validateCompositionParams(args.rawParams, ownedKeys);\n const params = (args.rawParams ?? {}) as Record<string, unknown>;\n if (typeof params.composition !== \"string\") return issues;\n const dir = await resolveCompositionDir(params.composition).catch(() => null);\n const meta = dir ? await loadCompositionMeta(dir).catch(() => null) : null;\n if (!dir || !meta) return issues; // validateCompositionParams reported why\n const compositionParams = Object.fromEntries(Object.entries(params).filter(([k]) => !ownedKeys.has(k)));\n issues.push(\n ...(await staticCompositionIssues({\n nodeId: args.nodeId,\n dir,\n meta,\n compositionParams,\n rawInputs: args.rawInputs,\n inputKindOf: args.inputKindOf,\n inputSourceOf: args.inputSourceOf,\n lintTimeoutMs: 20_000,\n })),\n );\n return issues;\n}\n\n/**\n * Validate raw params against the composition's meta.json.\n * Returns issue list (empty = ok). Used by `validateExtra` so canvas\n * validate catches bad params before any render runs.\n */\nexport async function validateCompositionParams(\n rawParams: unknown,\n ownedKeys: ReadonlySet<string> = NODE_OWNED_PARAM_KEYS,\n): Promise<{ path: string; message: string }[]> {\n const issues: { path: string; message: string }[] = [];\n if (!rawParams || typeof rawParams !== \"object\") return issues;\n const params = rawParams as Record<string, unknown>;\n const composition = params.composition;\n if (typeof composition !== \"string\") return issues; // static schema will have flagged it\n\n let dir: string;\n try {\n dir = await resolveCompositionDir(composition);\n } catch (e) {\n issues.push({ path: \"params.composition\", message: (e as Error).message });\n return issues;\n }\n\n let meta: CompositionMeta;\n try {\n meta = await loadCompositionMeta(dir);\n } catch (e) {\n issues.push({ path: \"params.composition\", message: (e as Error).message });\n return issues;\n }\n\n // Pick out only the dynamic (composition-declared) params for the meta-schema check.\n const dynamic: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(params)) {\n if (ownedKeys.has(k)) continue;\n dynamic[k] = v;\n }\n for (const key of Object.keys(dynamic)) {\n if (ENGINE_INJECTED_TOKENS.has(key)) {\n issues.push({\n path: `params.${key}`,\n message: `\"${key}\" is reserved (auto-injected by the renderer from input duration); remove from params`,\n });\n }\n }\n const schema = buildParamsSchema(meta);\n const parsed = schema.safeParse(dynamic);\n if (!parsed.success) {\n for (const issue of parsed.error.issues) {\n const tail = issue.path.join(\".\");\n issues.push({\n path: `params.${tail}`,\n message: issue.message,\n });\n }\n }\n return issues;\n}\n\nfunction validateAndParseDynamicParams(meta: CompositionMeta, params: Params): Record<string, unknown> {\n const dynamic: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(params)) {\n if (NODE_OWNED_PARAM_KEYS.has(k)) continue;\n dynamic[k] = v;\n }\n const schema = buildParamsSchema(meta);\n const parsed = schema.safeParse(dynamic);\n if (!parsed.success) {\n const summary = parsed.error.issues.map((i) => `params.${i.path.join(\".\")}: ${i.message}`).join(\"; \");\n throw new Error(`hyperframe_render: composition param validation failed — ${summary}`);\n }\n return parsed.data;\n}\n\n// ---------------------------------------------------------------------------\n// Asset staging\n// ---------------------------------------------------------------------------\n\n/**\n * Stage every input referenced in canvas `inputs` against the composition's\n * declared `meta.inputs` map. Throws on:\n * - missing required input\n * - input kind mismatch (canvas passes an image where video is declared)\n * - undeclared input key\n *\n * Returns the duration of the primary input asset (when a video) so the\n * engine can substitute `{{duration}}`. Falls back to meta.default_duration.\n */\nasync function stageInputs(\n tmp: string,\n inputs: Record<string, AssetRef>,\n meta: CompositionMeta,\n ctx: ExecCtx,\n): Promise<number | null> {\n assertInputsMatchMeta(inputs, meta, \"hyperframe_render\");\n let primaryDuration: number | null = null;\n for (const [key, ref] of Object.entries(inputs ?? {})) {\n const spec = meta.inputs[key];\n if (!spec) continue;\n const filename = spec.staged_as ?? defaultFilenameForInput(key, spec.kind);\n await stageAsset(ref as StageableRef, tmp, filename);\n ctx.log(`staged ${spec.kind} → ${filename}`);\n if (spec.kind === \"video\" && primaryDuration === null) {\n primaryDuration = await probeDurationSeconds(path.join(tmp, filename));\n }\n }\n return primaryDuration;\n}\n\n/**\n * Shared input-vs-meta check used by both hyperframe nodes. Throws on:\n * - undeclared input keys (typo / stale canvas)\n * - missing required inputs\n * - kind mismatch (canvas passes an image where video is declared)\n */\nexport function assertInputsMatchMeta(\n inputs: Record<string, AssetRef> | undefined,\n meta: CompositionMeta,\n nodeId: string,\n): void {\n const declaredKeys = new Set(Object.keys(meta.inputs));\n const providedKeys = new Set(Object.keys(inputs ?? {}));\n for (const key of providedKeys) {\n if (!declaredKeys.has(key)) {\n const declared = [...declaredKeys].join(\", \") || \"<none>\";\n throw new Error(`${nodeId}: inputs.${key} is not declared in composition meta.json (declares: ${declared})`);\n }\n }\n for (const [key, spec] of Object.entries(meta.inputs)) {\n if (spec.required && !providedKeys.has(key)) {\n throw new Error(`${nodeId}: inputs.${key} is required (kind=${spec.kind})`);\n }\n }\n for (const [key, ref] of Object.entries(inputs ?? {})) {\n const spec = meta.inputs[key];\n if (!spec) continue;\n if (ref.kind !== spec.kind) {\n throw new Error(`${nodeId}: inputs.${key} expected kind \"${spec.kind}\", got \"${ref.kind}\"`);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Substitution\n// ---------------------------------------------------------------------------\n\nasync function buildSubstitutionValues(\n compositionParams: Record<string, unknown>,\n meta: CompositionMeta,\n duration: number,\n): Promise<Record<string, unknown>> {\n const out: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(compositionParams)) {\n const spec = meta.params[name];\n if (spec?.kind === \"image\") {\n out[name] = await coerceImageParam(value);\n continue;\n }\n out[name] = value;\n }\n out.duration = duration.toFixed(3);\n return out;\n}\n\nfunction coerceImageParam(value: unknown): Promise<string> {\n if (typeof value === \"string\") return Promise.resolve(value);\n if (isStageableRef(value)) return refToUrl(value);\n throw new Error(\"hyperframe_render: image param must be a URL string or AssetRef\");\n}\n\nasync function substituteCompositionFiles(tmp: string, values: Record<string, unknown>): Promise<void> {\n // Substitute in index.html (the only file Hyperframes loads). Embedded\n // <style>/<script> live inside index.html so a single pass handles all of them.\n const entryPath = path.join(tmp, \"index.html\");\n const original = await readFile(entryPath, \"utf-8\");\n const { output, missing } = substituteVariables(original, values);\n if (missing.length > 0) {\n throw new Error(\n `hyperframe_render: composition references undefined variables: ${missing.map((m) => `{{${m}}}`).join(\", \")}. ` +\n `Add to params or to meta.json's params with a default.`,\n );\n }\n await writeFile(entryPath, output, \"utf-8\");\n}\n\n// ---------------------------------------------------------------------------\n// Render shell-out\n// ---------------------------------------------------------------------------\n\n// One headless Chrome per worker, so this is bounded by the box, not by taste.\n//\n// It used to be a flat 4, on the stated grounds that \"the e2b instance is typically a\n// 4-vCPU box\". It is not, and had not been for three months when that was written: the\n// template asks for 8 vCPU and 8 GB (`packages/e2b-template/src/build.ts`, raised in March\n// with the message \"Increase cpu count we are maxing it\"), and `nproc` inside a live\n// sandbox reports 8. So the slowest node in an ad's graph — the caption render, measured at\n// 55.6s, 39% of the critical path — was using half the machine it had been given.\n//\n// One core is left for everything else on the box: the bridge, the supervisor and the\n// ffmpeg the render shells out to. The 8 cap keeps this honest if it ever runs somewhere\n// larger, where Chrome's memory would bind long before the cores did — measured in a live\n// sandbox, 5.8 GB of the 8 were free at render time.\n//\n// Whether this actually helps is recorded, not assumed: every run writes each node's\n// duration to `canvasRuns`, so the next ad's `hyperframe_render` is directly comparable\n// against the 55.6s above. If it does not improve, this is one line to put back.\nconst MAX_WORKERS = 8;\n\nfunction workerCount(): number {\n return Math.max(1, Math.min(MAX_WORKERS, cpus().length - 1));\n}\n\nasync function runRender(opts: {\n tmp: string;\n outputPath: string;\n params: Params;\n meta: CompositionMeta;\n ctx: ExecCtx;\n}): Promise<void> {\n const { tmp, outputPath, params, meta, ctx } = opts;\n const args = buildRenderArgs(tmp, outputPath, meta, params.format);\n ctx.log(`rendering ${meta.width}x${meta.height}@${meta.fps}fps ${params.format} from ${path.basename(tmp)}`);\n try {\n await execFileAsync(\"npx\", args, { timeout: params.timeout_ms, maxBuffer: 64 * 1024 * 1024 });\n } catch (e) {\n const stderr = (e as { stderr?: string }).stderr ?? \"\";\n const stdout = (e as { stdout?: string }).stdout ?? \"\";\n const detail = stderr || stdout || (e as Error).message;\n const friendly = mapKnownHyperframesError(detail);\n throw new Error(`hyperframe_render: render failed\\n${friendly ?? detail.slice(0, 4000)}`);\n }\n}\n\nexport function buildRenderArgs(tmp: string, outputPath: string, meta: CompositionMeta, format: string): string[] {\n return [\n \"hyperframes\",\n \"render\",\n tmp,\n \"--output\",\n outputPath,\n \"--fps\",\n String(meta.fps),\n \"--quality\",\n \"high\",\n \"--format\",\n format,\n \"--workers\",\n String(workerCount()),\n ];\n}\n\nasync function probeDurationSeconds(filePath: string): Promise<number> {\n const { stdout } = await execFileAsync(\n \"ffprobe\",\n [\"-v\", \"error\", \"-show_entries\", \"format=duration\", \"-of\", \"csv=p=0\", filePath],\n { encoding: \"utf-8\" },\n );\n const seconds = Number.parseFloat(stdout.trim());\n if (!Number.isFinite(seconds)) {\n throw new Error(`hyperframe_render: ffprobe returned invalid duration: ${stdout}`);\n }\n return seconds;\n}\n","import { readdir, readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { sha256Hex } from \"../storage/sha256.ts\";\n\n// Skip transient/build artefacts when hashing — these aren't part of the\n// composition's source-of-truth and would either thrash the cache (.cache,\n// node_modules) or pollute the hash with editor noise (.DS_Store, .swp).\nconst SKIP_DIRS: ReadonlySet<string> = new Set([\".cache\", \".git\", \"node_modules\", \"dist\", \"build\", \".next\", \".turbo\"]);\n\nfunction isSkippedName(name: string): boolean {\n if (name.startsWith(\".\")) return true; // .DS_Store, dotfiles\n return SKIP_DIRS.has(name);\n}\n\ntype FileEntry = { relPath: string; contentSha: string };\n\n/**\n * Compute a deterministic content-addressed hash of every relevant file under\n * `dir`. Hash layout:\n *\n * sha256(\"<rel/path>\\0<file-sha256>\\n<rel/path>\\0<file-sha256>\\n...\")\n *\n * Entries are sorted by relative path so the result is stable regardless of\n * filesystem-walk order. Returns a hex sha256 string.\n *\n * Used by the executor to fold composition content into the cache key — any\n * edit to a tracked file invalidates the hyperframe_render cache entry.\n */\nexport async function hashCompositionDir(dir: string): Promise<string> {\n const entries = await collectFiles(dir, dir);\n entries.sort((a, b) => a.relPath.localeCompare(b.relPath));\n const manifest = entries.map((e) => `${e.relPath}\\0${e.contentSha}`).join(\"\\n\");\n return sha256Hex(manifest);\n}\n\nasync function collectFiles(root: string, current: string): Promise<FileEntry[]> {\n const out: FileEntry[] = [];\n const names = await readdir(current);\n for (const name of names) {\n if (isSkippedName(name)) continue;\n const abs = path.join(current, name);\n const s = await stat(abs);\n if (s.isDirectory()) {\n out.push(...(await collectFiles(root, abs)));\n continue;\n }\n if (!s.isFile()) continue;\n const bytes = await readFile(abs);\n const relPath = path.relative(root, abs).split(path.sep).join(\"/\");\n out.push({ relPath, contentSha: sha256Hex(bytes) });\n }\n return out;\n}\n","import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\n\n// One source of truth per composition: meta.json.\n//\n// The composition declares its inputs (videos/images/audios it expects staged\n// into the render directory) and params (everything you can pass via {{var}}).\n// The hyperframe_render and hyperframe_snapshot nodes load this file, build a\n// per-call Zod schema, and validate the canvas's `params` against it.\n\nconst InputKind = z.enum([\"video\", \"image\", \"audio\", \"json\", \"font\"]);\n\nconst InputSpec = z\n .object({\n kind: InputKind,\n required: z.boolean().optional().default(false),\n // Filename the composition's HTML references (e.g. `input.mp4`, `logo.png`).\n // Defaults to `<key><ext>` derived from the kind.\n staged_as: z.string().min(1).optional(),\n description: z.string().optional(),\n })\n .strict();\n\nconst ParamSpecBase = {\n required: z.boolean().optional().default(false),\n description: z.string().optional(),\n};\n\nconst StringParam = z\n .object({\n ...ParamSpecBase,\n kind: z.literal(\"string\"),\n default: z.string().optional(),\n enum: z.array(z.string()).optional(),\n })\n .strict();\n\nconst IntegerParam = z\n .object({\n ...ParamSpecBase,\n kind: z.literal(\"integer\"),\n default: z.number().int().optional(),\n min: z.number().int().optional(),\n max: z.number().int().optional(),\n })\n .strict();\n\nconst NumberParam = z\n .object({\n ...ParamSpecBase,\n kind: z.literal(\"number\"),\n default: z.number().optional(),\n min: z.number().optional(),\n max: z.number().optional(),\n })\n .strict();\n\nconst BooleanParam = z\n .object({\n ...ParamSpecBase,\n kind: z.literal(\"boolean\"),\n default: z.boolean().optional(),\n })\n .strict();\n\nconst ColorParam = z\n .object({\n ...ParamSpecBase,\n kind: z.literal(\"color\"),\n default: z.string().optional(),\n })\n .strict();\n\nconst ImageParam = z\n .object({\n ...ParamSpecBase,\n kind: z.literal(\"image\"),\n default: z.string().optional(),\n })\n .strict();\n\nconst JsonParam = z\n .object({\n ...ParamSpecBase,\n kind: z.literal(\"json\"),\n schema: z.unknown().optional(),\n default: z.unknown().optional(),\n })\n .strict();\n\nconst ParamSpec = z.discriminatedUnion(\"kind\", [\n StringParam,\n IntegerParam,\n NumberParam,\n BooleanParam,\n ColorParam,\n ImageParam,\n JsonParam,\n]);\n\ntype ParamSpec = z.infer<typeof ParamSpec>;\n\nexport const CompositionMetaSchema = z\n .object({\n id: z.string().min(1),\n title: z.string().min(1),\n description: z.string().optional(),\n width: z.number().int().positive(),\n height: z.number().int().positive(),\n fps: z.number().int().positive().default(30),\n default_duration: z.number().positive().default(10),\n inputs: z.record(z.string(), InputSpec).default({}),\n params: z.record(z.string(), ParamSpec).default({}),\n /**\n * The page reads its own staged files (a picture's pixels), so a snapshot opens it with\n * file access. Off by default: Chromium grants it for every file:// path, not just these.\n */\n reads_staged_files: z.boolean().optional(),\n })\n .strict();\n\nexport type CompositionMeta = z.infer<typeof CompositionMetaSchema>;\n\nexport async function loadCompositionMeta(compositionDir: string): Promise<CompositionMeta> {\n const metaPath = path.join(compositionDir, \"meta.json\");\n let raw: string;\n try {\n raw = await readFile(metaPath, \"utf-8\");\n } catch (e) {\n throw new Error(`composition meta: cannot read ${metaPath} (${(e as Error).message})`);\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (e) {\n throw new Error(`composition meta: ${metaPath} is not valid JSON (${(e as Error).message})`);\n }\n const result = CompositionMetaSchema.safeParse(parsed);\n if (!result.success) {\n const summary = result.error.issues.map((i) => `${i.path.join(\".\")}: ${i.message}`).join(\"; \");\n throw new Error(`composition meta: ${metaPath} schema error — ${summary}`);\n }\n return result.data;\n}\n\n/**\n * Build a Zod schema for the params declared in `meta.json`. Used to validate\n * the canvas's `params` payload at validate-time and execute-time.\n *\n * Output schema is a `z.object().strict()` — unknown keys are rejected so\n * typos surface immediately. Params with a `default` are made optional and\n * Zod fills the default; required params without defaults must be provided.\n */\nexport function buildParamsSchema(meta: CompositionMeta): z.ZodObject {\n const shape: Record<string, z.ZodType> = {};\n for (const [name, spec] of Object.entries(meta.params)) {\n shape[name] = buildParamFieldSchema(name, spec);\n }\n return z.object(shape).strict();\n}\n\nfunction buildParamFieldSchema(name: string, spec: ParamSpec): z.ZodType {\n switch (spec.kind) {\n case \"string\": {\n const s: z.ZodType = spec.enum && spec.enum.length > 0 ? z.enum(spec.enum as [string, ...string[]]) : z.string();\n return finalize(s, spec.default, spec.required);\n }\n case \"integer\": {\n let s: z.ZodNumber = z.number().int();\n if (spec.min !== undefined) s = s.min(spec.min);\n if (spec.max !== undefined) s = s.max(spec.max);\n return finalize(s, spec.default, spec.required);\n }\n case \"number\": {\n let s: z.ZodNumber = z.number();\n if (spec.min !== undefined) s = s.min(spec.min);\n if (spec.max !== undefined) s = s.max(spec.max);\n return finalize(s, spec.default, spec.required);\n }\n case \"boolean\":\n return finalize(z.boolean(), spec.default, spec.required);\n case \"color\": {\n const s = z.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/, {\n message: `param \"${name}\": must be a 3/6/8-digit hex color (e.g. \"#ff0066\")`,\n });\n return finalize(s, spec.default, spec.required);\n }\n case \"image\":\n // Accept a URL string or an AssetRef-shaped object — node coerces to URL\n // string before substitution.\n return finalize(z.union([z.string().min(1), z.record(z.string(), z.unknown())]), spec.default, spec.required);\n case \"json\":\n return finalize(\n z.unknown().refine((v) => v !== undefined, { message: `param \"${name}\" is required` }),\n spec.default,\n spec.required,\n );\n default: {\n const _exhaustive: never = spec;\n throw new Error(`buildParamFieldSchema: unknown kind ${(_exhaustive as { kind: string }).kind}`);\n }\n }\n}\n\nfunction finalize(schema: z.ZodType, dflt: unknown, required: boolean | undefined): z.ZodType {\n if (dflt !== undefined) return schema.optional().default(dflt as never);\n if (required === false) return schema.optional();\n return schema;\n}\n\n/** Default filename for an input — the composition can override via `staged_as`. */\nexport function defaultFilenameForInput(key: string, kind: \"video\" | \"image\" | \"audio\" | \"json\" | \"font\"): string {\n if (kind === \"video\") return `${key}.mp4`;\n // The browser reads a font's format off its bytes, so one name fits ttf/otf/woff/woff2.\n if (kind === \"font\") return `${key}.font`;\n if (kind === \"audio\") return `${key}.mp3`;\n if (kind === \"json\") return `${key}.json`;\n return `${key}.png`;\n}\n","import { copyFile, cp } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\n\nconst require_ = createRequire(import.meta.url);\n\n/** Copy a composition dir to a scratch dir, leaving caches and VCS metadata behind. */\nexport async function copyComposition(srcDir: string, destDir: string): Promise<void> {\n await cp(srcDir, destDir, {\n recursive: true,\n filter: (src) => {\n const name = path.basename(src);\n if (name === \".cache\" || name === \"node_modules\" || name === \".git\") return false;\n return true;\n },\n });\n}\n\n/** Put the engine's own `gsap.min.js` next to index.html, which compositions load as `./gsap.min.js`. */\nexport async function vendorGsap(dir: string, ctx: { log: (s: string) => void }): Promise<void> {\n try {\n const gsapMin = require_.resolve(\"gsap/dist/gsap.min.js\");\n await copyFile(gsapMin, path.join(dir, \"gsap.min.js\"));\n } catch (e) {\n ctx.log(`warning: could not vendor gsap.min.js (${(e as Error).message}); compositions must self-supply`);\n }\n}\n","import { mkdtemp, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { fetchExternalBytes } from \"../../../../lib/externalFetch.ts\";\nimport { type CompositionMeta, defaultFilenameForInput } from \"../../../engine/composition-meta.ts\";\nimport type { InputSource, StaticInputKind } from \"../../../engine/define.ts\";\nimport { REF_PREFIX } from \"../../../schema/canvas.ts\";\nimport { renderTemplate } from \"../../../schema/prompts.ts\";\nimport { copyComposition, vendorGsap } from \"./composition-stage.ts\";\nimport { isHyperframesAvailable, lintPreparedComposition } from \"./hyperframe-check.ts\";\nimport { ensureHyperframesMetaJson } from \"./hyperframe-meta.ts\";\nimport { extractReferencedTokens, substituteVariables } from \"./templating.ts\";\n\n// What a hyperframe node's run would refuse, decided before the run. Each check\n// here mirrors one the node makes at render time (the input staging, the `{{token}}`\n// substitution, the pre-render lint gate), and each was watched failing a real run\n// after every clip upstream of it had been paid for.\n\ntype Issue = { path: string; message: string };\n\ntype StaticCheckArgs = {\n nodeId?: string;\n dir: string;\n meta: CompositionMeta;\n /** The node's params minus its own keys: what the composition's meta.json declares. */\n compositionParams: Record<string, unknown>;\n rawInputs: unknown;\n inputKindOf?: (value: unknown) => StaticInputKind;\n /** Where an input's file comes from before the run; undefined for one a node generates. */\n inputSourceOf?: (value: unknown) => InputSource | undefined;\n lintTimeoutMs: number;\n};\n\nexport async function staticCompositionIssues(args: StaticCheckArgs): Promise<Issue[]> {\n const html = await readFile(path.join(args.dir, \"index.html\"), \"utf-8\").catch(() => null);\n const issues = inputIssues(args.meta, args.rawInputs, args.inputKindOf);\n if (html === null) return issues;\n issues.push(...undefinedVariableIssues(html, args.meta, args.compositionParams));\n issues.push(...(await gateIssues(args)));\n return issues;\n}\n\n/** The values `{{tokens}}` will be filled with, as far as they are known before the run. */\nfunction substitutionValues(\n meta: CompositionMeta,\n compositionParams: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(compositionParams)) {\n const kind = meta.params[name]?.kind;\n const wired = typeof value === \"string\" && value.startsWith(REF_PREFIX);\n // An image param given as an asset becomes its URL at run time.\n const imageAsset = kind === \"image\" && typeof value !== \"string\";\n out[name] = wired || imageAsset ? placeholderFor(kind) : value;\n }\n for (const [name, spec] of Object.entries(meta.params)) {\n if (!Object.hasOwn(out, name) && spec.default !== undefined) out[name] = spec.default;\n }\n // The engine fills `{{duration}}` itself, from the staged video or the default.\n out.duration = meta.default_duration.toFixed(3);\n return out;\n}\n\n/** A stand-in with the right JS shape for a value only the run will produce. */\nfunction placeholderFor(kind: string | undefined): unknown {\n if (kind === \"json\") return null;\n if (kind === \"integer\" || kind === \"number\") return 0;\n if (kind === \"boolean\") return false;\n return \"\";\n}\n\nfunction undefinedVariableIssues(\n html: string,\n meta: CompositionMeta,\n compositionParams: Record<string, unknown>,\n): Issue[] {\n const known = substitutionValues(meta, compositionParams);\n const missing = extractReferencedTokens(html).filter((token) => !Object.hasOwn(known, token));\n if (missing.length === 0) return [];\n return [\n {\n path: \"params.composition\",\n message:\n `composition references undefined variables: ${missing.map((m) => `{{${m}}}`).join(\", \")}. ` +\n \"Add to params or to meta.json's params with a default.\",\n },\n ];\n}\n\n/** The inputs against meta.json: the same three refusals the node makes when it stages them. */\nfunction inputIssues(\n meta: CompositionMeta,\n rawInputs: unknown,\n inputKindOf: ((value: unknown) => StaticInputKind) | undefined,\n): Issue[] {\n const inputs = (rawInputs && typeof rawInputs === \"object\" ? rawInputs : {}) as Record<string, unknown>;\n const issues: Issue[] = [];\n const declared = Object.keys(meta.inputs);\n for (const key of Object.keys(inputs)) {\n if (Object.hasOwn(meta.inputs, key)) continue;\n issues.push({\n path: `inputs.${key}`,\n message: `inputs.${key} is not declared in composition meta.json (declares: ${declared.join(\", \") || \"<none>\"})`,\n });\n }\n for (const [key, spec] of Object.entries(meta.inputs)) {\n if (!Object.hasOwn(inputs, key)) {\n if (spec.required)\n issues.push({ path: `inputs.${key}`, message: `inputs.${key} is required (kind=${spec.kind})` });\n continue;\n }\n const got = inputKindOf?.(inputs[key]) ?? \"unknown\";\n const mismatch = kindMismatch(spec.kind, got);\n if (mismatch)\n issues.push({ path: `inputs.${key}`, message: `inputs.${key} expected kind \"${spec.kind}\", ${mismatch}` });\n }\n return issues;\n}\n\nfunction kindMismatch(expected: string, got: StaticInputKind): string | null {\n if (got === \"unknown\" || got === expected) return null;\n if (got === \"list\") return \"got a list; wire one element of it (`$ref:<node>.<output>#0`)\";\n if (got === \"value\") return \"got a plain value, not an asset\";\n return `got \"${got}\"`;\n}\n\n/**\n * The render gate's lint, run on a copy prepared the way the render prepares it: gsap\n * vendored, wired inputs present, `{{tokens}}` and param slots filled. Runs only where\n * the `hyperframes` binary is installed.\n */\nasync function gateIssues(args: StaticCheckArgs): Promise<Issue[]> {\n if (!(await isHyperframesAvailable())) return [];\n const tmp = await mkdtemp(path.join(tmpdir(), \"hf-validate-\"));\n try {\n await prepareForGate(tmp, args);\n const lint = await lintPreparedComposition(tmp, args.lintTimeoutMs);\n return lint.map((b) => ({\n path: \"params.composition\",\n message: `pre-render gate would fail: [${b.code}] ${b.message}`,\n }));\n } finally {\n await rm(tmp, { recursive: true, force: true }).catch(() => undefined);\n }\n}\n\n/** Fonts and logos are small; the cap only guards against a wrong URL. */\nconst MAX_INPUT_BYTES = 20 * 1024 * 1024;\n\n/** A 1x1 PNG: the stand-in for a picture a node will generate. */\nconst STAND_IN_PICTURE = Buffer.from(\n \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=\",\n \"base64\",\n);\n\nasync function readSource(source: InputSource): Promise<Buffer | null> {\n try {\n if (\"path\" in source) {\n // Sized before it is read: validate must never buffer a huge or special file.\n const info = await stat(source.path);\n return info.isFile() && info.size <= MAX_INPUT_BYTES ? await readFile(source.path) : null;\n }\n return (await fetchExternalBytes(source.url, { maxBytes: MAX_INPUT_BYTES, timeoutMs: 15_000 })).buffer;\n } catch {\n return null;\n }\n}\n\n/** What stands in for an input only the run produces. */\nfunction standIn(kind: string): Buffer | string {\n if (kind === \"image\") return STAND_IN_PICTURE;\n return kind === \"json\" ? \"{}\" : \"\";\n}\n\n/**\n * Prepare `target` as the render prepares its composition: every input known before the\n * run (a workspace file or a URL an `ingest` reads) staged for real, a stand-in for what a\n * node generates, and each param slot filled from the file wired to it. `faithful` says\n * the copy, fonts and marks are exactly what the render will draw; only the picture under\n * them is a stand-in. A slot only the run fills becomes an empty value of its kind, never\n * a raw `{{slot}}` the lint would read as broken script.\n */\nexport async function prepareForGate(\n target: string,\n args: Omit<StaticCheckArgs, \"lintTimeoutMs\" | \"nodeId\">,\n): Promise<{ faithful: boolean }> {\n await copyComposition(args.dir, target);\n await vendorGsap(target, { log: () => undefined });\n const staged = await stageGateInputs(target, args);\n const filled = fillParamSlots(args.meta, args.compositionParams, staged.slotTexts);\n const entry = path.join(target, \"index.html\");\n const html = await readFile(entry, \"utf-8\");\n await writeFile(entry, substituteVariables(html, substitutionValues(args.meta, filled.params)).output);\n await ensureHyperframesMetaJson(target, args.meta.id, args.meta, args.meta.default_duration);\n return { faithful: staged.faithful && filled.faithful };\n}\n\n/** Each wired input staged under the name the render stages it as; json ones also kept as slot text. */\nasync function stageGateInputs(\n target: string,\n args: Pick<StaticCheckArgs, \"meta\" | \"rawInputs\" | \"inputSourceOf\">,\n): Promise<{ faithful: boolean; slotTexts: Record<string, string> }> {\n const inputs = (args.rawInputs && typeof args.rawInputs === \"object\" ? args.rawInputs : {}) as Record<\n string,\n unknown\n >;\n const wired = Object.entries(args.meta.inputs).filter(([key]) => Object.hasOwn(inputs, key));\n // In parallel: each input has its own file, and a slow font URL must not wait on another.\n const staged = await Promise.all(\n wired.map(async ([key, spec]) => {\n const filename = path.join(target, spec.staged_as ?? defaultFilenameForInput(key, spec.kind));\n const source = args.inputSourceOf?.(inputs[key]);\n const bytes = source ? await readSource(source) : null;\n await writeFile(filename, bytes ?? standIn(spec.kind));\n // Only a generated picture has a faithful stand-in: it sits under the copy.\n const faithful = bytes !== null || (!source && spec.kind === \"image\");\n return { key, faithful, text: bytes && spec.kind === \"json\" ? bytes.toString(\"utf8\") : null };\n }),\n );\n const slotTexts: Record<string, string> = {};\n for (const { key, text } of staged) if (text !== null) slotTexts[key] = text;\n return { faithful: staged.every((s) => s.faithful), slotTexts };\n}\n\n/** The params with each `{{slot}}` filled from its staged file, or an empty value of the param's kind. */\nfunction fillParamSlots(\n meta: CompositionMeta,\n compositionParams: Record<string, unknown>,\n slotTexts: Record<string, string>,\n): { faithful: boolean; params: Record<string, unknown> } {\n let faithful = true;\n const params: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(compositionParams)) {\n const slots = typeof value === \"string\" ? extractReferencedTokens(value) : [];\n if (typeof value !== \"string\" || slots.length === 0) {\n params[name] = value;\n } else if (slots.every((slot) => Object.hasOwn(slotTexts, slot))) {\n params[name] = renderTemplate(value, slotTexts);\n } else {\n faithful = false;\n params[name] = placeholderFor(meta.params[name]?.kind);\n }\n }\n return { faithful, params };\n}\n","import { execFile } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { hasFrameVisionKey } from \"../../../../env.ts\";\nimport { captionTextsFrom, fragmentedCaptions } from \"./caption-style.ts\";\n\n// Pre-render quality gate. Runs Hyperframes' own `lint` (composition mistakes:\n// missing ids, undeclared variables, bad structure, low contrast, …) and\n// `inspect` (text/container overflow across the timeline) on the SUBSTITUTED\n// composition in the tmp render dir, before the billable render.\n//\n// Severity policy (see the plan): overflow + structural lint errors HARD-BLOCK;\n// contrast and deferred-asset advisories WARN ONLY (low contrast can be a valid\n// brand choice; the agent drops brand fonts/assets after scaffolding). If the\n// `hyperframes` binary or these subcommands are unavailable, the gate degrades\n// gracefully — it logs and lets the render proceed rather than failing a valid\n// render on a missing tool.\n\nconst execFileAsync = promisify(execFile);\n\n// Internal-only types — exported functions return them by inference, so they\n// don't need to be exported themselves (keeps knip's unused-export gate clean).\ntype CheckSeverity = \"blocking\" | \"warning\";\ntype CheckFinding = {\n source: \"lint\" | \"inspect\" | GateSection;\n code: string;\n message: string;\n severity: CheckSeverity;\n};\ntype CheckResult = { blocking: CheckFinding[]; warnings: CheckFinding[] };\n\n// Advisory in Baker's deferred-asset pipeline — never hard-block on these even\n// at lint severity \"error\". The agent supplies brand fonts/assets and tunes\n// contrast AFTER scaffolding, so blocking here would fail legitimate creative.\n// Add a code/keyword here to downgrade a finding from blocking to warning.\n//\n// • contrast / wcag / missing_local_asset / font-* — deferred-asset advisories.\n// • transcript_not_inline — our caption track legitimately reads the transcript\n// from a STAGED `transcript.json` input (a real file at render time); the\n// gate's inline-array preference is a Studio-editing nicety, not a render\n// requirement, so fetch() works and must not block.\n// • text_occluded — the static check can't run GSAP, so it reads every\n// animate-in caption/overlay (hidden until its beat by design) as occluded.\n// A genuine occlusion still surfaces as a warning + on read-the-output-back.\nconst NEVER_BLOCK: RegExp[] = [\n /contrast/i,\n /\\bwcag\\b/i,\n /missing_local_asset/i,\n /font[_-]?family/i,\n /font[_-]?face/i,\n /transcript[_-]?not[_-]?inline/i,\n /text[_-]?occluded/i,\n];\n\n// Stderr/message fragments that mean the command itself could not run (vs. the\n// command running and reporting findings). These degrade gracefully.\nconst UNAVAILABLE = /unknown command|command not found|not found|Did you mean|Unknown argument|ENOENT/i;\n\nfunction isAdvisory(code: string, message: string): boolean {\n const hay = `${code} ${message}`;\n return NEVER_BLOCK.some((re) => re.test(hay));\n}\n\n/** Parse JSON that may be preceded by non-JSON guard lines (e.g. `[StaticGuard] …`). */\nexport function parseCheckJson(raw: string): unknown {\n if (!raw) return null;\n const trimmed = raw.trim();\n try {\n return JSON.parse(trimmed);\n } catch {\n // fall through to brace extraction\n }\n const start = trimmed.indexOf(\"{\");\n const end = trimmed.lastIndexOf(\"}\");\n if (start >= 0 && end > start) {\n try {\n return JSON.parse(trimmed.slice(start, end + 1));\n } catch {\n return null;\n }\n }\n return null;\n}\n\nexport function classifyLint(json: unknown): CheckFinding[] {\n const out: CheckFinding[] = [];\n const findings = (json as { findings?: unknown })?.findings;\n if (!Array.isArray(findings)) return out;\n for (const f of findings) {\n const rec = f as { code?: unknown; message?: unknown; severity?: unknown };\n const code = String(rec?.code ?? \"\");\n const message = String(rec?.message ?? \"\");\n const severity = String(rec?.severity ?? \"info\");\n const blocking = severity === \"error\" && !isAdvisory(code, message);\n out.push({ source: \"lint\", code, message, severity: blocking ? \"blocking\" : \"warning\" });\n }\n return out;\n}\n\nexport function classifyInspect(json: unknown): CheckFinding[] {\n const out: CheckFinding[] = [];\n const obj = json as { issues?: unknown; ok?: unknown };\n const issues = obj?.issues;\n if (!Array.isArray(issues)) return out;\n for (const iss of issues) {\n const rec = iss as { code?: unknown; type?: unknown; message?: unknown; detail?: unknown; severity?: unknown };\n const code = String(rec?.code ?? rec?.type ?? \"overflow\");\n const message = String(rec?.message ?? rec?.detail ?? JSON.stringify(iss));\n // Overflow clips/clobbers the creative → block on errors. Lesser severities\n // (or unscored issues when the run as a whole passed) only warn.\n const severity = rec?.severity ? String(rec.severity) : obj?.ok === false ? \"error\" : \"warning\";\n out.push({ source: \"inspect\", code, message, severity: severity === \"error\" ? \"blocking\" : \"warning\" });\n }\n return out;\n}\n\nexport function classifyCheckOutput(lintRaw: string, inspectRaw: string): CheckResult {\n const findings = [...classifyLint(parseCheckJson(lintRaw)), ...classifyInspect(parseCheckJson(inspectRaw))];\n return {\n blocking: findings.filter((f) => f.severity === \"blocking\"),\n warnings: findings.filter((f) => f.severity === \"warning\"),\n };\n}\n\n/** The sections `hyperframes check` reports, each with its own findings array. */\nconst GATE_SECTIONS = [\"lint\", \"runtime\", \"layout\", \"motion\", \"contrast\"] as const;\ntype GateSection = (typeof GATE_SECTIONS)[number];\n\n/**\n * The 0.8 gate: one browser session instead of two static passes.\n *\n * `check` runs lint, runtime, layout, motion and WCAG contrast together, and the\n * runtime half is signal the static passes could not produce at all — measured on\n * a real project, `lint` came back clean while the browser reported `GSAP target\n * #a-roll not found`, an animation pointed at an element that does not exist and\n * therefore silently never plays. That is the defect that makes a finished video\n * look static, and nothing in `lint`/`inspect` can see it.\n *\n * `--at-transitions` samples the tween boundaries as well as segment midpoints.\n * A caption that only collides with a lower-third while the two cross is invisible\n * to midpoint sampling, and it is exactly the kind of flaw that reads as amateur.\n */\nexport function buildCheckArgs(dir: string, samples: number): string[] {\n return [\"hyperframes\", \"check\", dir, \"--json\", \"--samples\", String(samples), \"--at-transitions\"];\n}\n\n/**\n * Findings that LOOK advisory, or merely advisory, and are actually fatal.\n *\n * HyperFrames reports a tween whose target does not exist as a console warning,\n * because from its side nothing threw. From ours the animation simply never\n * happens: measured on their own warm-grain example, six `GSAP target #a-roll\n * not found` warnings — with lint, runtime, layout and motion all green —\n * rendered an almost entirely blank 10s video. The render still billed.\n *\n * `NEVER_BLOCK` downgrades every font finding, deliberately: a missing brand `.otf` is\n * a deferred asset and the composition falls back. But a font family the compiler\n * cannot MAP is a different animal — it aborts the render outright. A closing card\n * styled `font-family: 'BrandFont', …` killed a whole ad with\n * `No deterministic font mapping for: BrandFont`, after every clip had been paid for.\n *\n * Read off the gate's own message rather than re-derived here. Answering it ourselves\n * needs the set of families the renderer bundles, which we would have to copy and keep\n * in step — and a family we wrongly believed unsupported is a refusal we invented,\n * which is worse than the limit we never had. The gate already knows, runs before a\n * single clip is billed, and says so by name.\n */\nconst PROMOTE_TO_BLOCKING = /GSAP target [^ ]+ not found|no deterministic font mapping/i;\n\nfunction toGateFinding(section: GateSection, entry: unknown): CheckFinding {\n const f = entry as { code?: unknown; severity?: unknown; message?: unknown };\n const code = typeof f.code === \"string\" ? f.code : \"unknown\";\n const message = typeof f.message === \"string\" ? f.message : \"\";\n const isError = f.severity === \"error\" || PROMOTE_TO_BLOCKING.test(message);\n // The promotion wins over the advisory downgrade: an unmapped font reads as a font\n // finding, and font findings are advisory by default, so the two rules met and the\n // fatal one lost.\n const fatal = PROMOTE_TO_BLOCKING.test(message);\n return {\n source: section,\n code,\n message,\n severity: fatal || (isError && !isAdvisory(code, message)) ? \"blocking\" : \"warning\",\n };\n}\n\n/**\n * Classify `check --json` under OUR severity policy, not the tool's verdict.\n *\n * The top-level `ok` is deliberately ignored: it goes false on a contrast finding,\n * and low contrast is a brand choice the agent tunes after scaffolding. What blocks\n * is an error the render cannot survive, minus the advisories in `NEVER_BLOCK`.\n */\nexport function classifyGateOutput(raw: string): CheckResult {\n const parsed = parseCheckJson(raw) as Record<string, unknown> | null;\n const findings = GATE_SECTIONS.flatMap((section) => {\n const block = parsed?.[section] as { findings?: unknown } | undefined;\n const entries = Array.isArray(block?.findings) ? block.findings : [];\n return entries.map((entry) => toGateFinding(section, entry));\n });\n return {\n blocking: findings.filter((f) => f.severity === \"blocking\"),\n warnings: findings.filter((f) => f.severity === \"warning\"),\n };\n}\n\n/**\n * One line per warning CODE, not per occurrence.\n *\n * A real project's gate came back with 62 warnings, 53 of them the same layout\n * code. Printed one per line that is a wall nobody reads, and a gate whose output\n * is skipped is a gate that does not exist. The count is what tells the agent\n * whether it is one stray element or the whole layout, and the first message is\n * enough to know which.\n */\nexport function summariseWarnings(warnings: CheckFinding[]): string[] {\n const groups = new Map<string, { count: number; message: string }>();\n for (const w of warnings) {\n const key = `${w.source}/${w.code}`;\n const seen = groups.get(key);\n if (seen) seen.count += 1;\n else groups.set(key, { count: 1, message: w.message });\n }\n return [...groups.entries()]\n .sort((a, b) => b[1].count - a[1].count)\n .map(([key, g]) => `${g.count}× [${key}] ${g.message}`);\n}\n\n/**\n * Baker's own reading of the gate's highest-value codes.\n *\n * The tool states what it observed; the agent needs what to DO. These are the\n * findings where the raw message is accurate and still leaves someone staring at\n * it — every one of them was watched costing a real, billed render.\n */\nconst FINDING_ADVICE: Record<string, string> = {\n sweep_static:\n \"the timeline never advanced, so this renders as a STILL IMAGE while billing like a video — and every other green verdict in this run is unreliable. Check the composition registers a paused timeline on `window.__timelines[<composition-id>]` and that the tweens target elements that exist.\",\n console_error: \"the composition threw in the browser, so whatever that script was driving did not happen.\",\n page_error: \"a script failed to evaluate — animations and any JS-driven layout in this composition did not run.\",\n http_error: \"an asset 404ed at render time; it will be missing from the frame, not substituted.\",\n content_overlap:\n \"two text blocks collide. Make one smaller, shorten it, or move it, in the composition's HTML or the param that sets it; nothing generated needs to be paid for again.\",\n console_warning:\n \"if this names a GSAP target, the element it animates does not exist, so that tween is a no-op and whatever it was meant to reveal never appears. Fix the selector or add the element before rendering.\",\n};\n\n/** The message the agent reads, with Baker's advice appended when we have any. */\nexport function explainGateFinding(finding: CheckFinding): string {\n const advice = FINDING_ADVICE[finding.code];\n return advice ? `${finding.message} — ${advice}` : finding.message;\n}\n\n/**\n * What Gemini saw, one line per frame.\n *\n * `snapshot --describe` writes a markdown file with a preamble and a `## <frame>`\n * heading per shot. The preamble is the tool talking to itself; the agent needs\n * the verdicts, and needs them in the node log rather than in a file it would\n * have to know to open.\n */\nexport function condenseFrameDescriptions(markdown: string): string[] {\n const lines: string[] = [];\n let frame: string | null = null;\n for (const line of markdown.split(\"\\n\")) {\n const heading = line.match(/^## (.+)$/);\n if (heading) {\n frame = heading[1] ?? null;\n continue;\n }\n const text = line.trim();\n if (frame && text) {\n lines.push(`${frame}: ${text}`);\n frame = null;\n }\n }\n return lines;\n}\n\nexport function buildLintArgs(dir: string): string[] {\n return [\"hyperframes\", \"lint\", dir, \"--json\"];\n}\n\n// Validate runs OUTSIDE the render (no billed clips yet) and on dev boxes that\n// have no `hyperframes` binary. `--no-install` makes npx fast-fail (ENOENT →\n// degrade) instead of attempting a network download, so validate stays free and\n// flake-proof; in the e2b sandbox the globally-pinned binary still resolves.\nfunction buildLintArgsNoInstall(dir: string): string[] {\n return [\"--no-install\", \"hyperframes\", \"lint\", dir, \"--json\"];\n}\n\n/**\n * The lint findings the render gate would block on, under the gate's own policy:\n * every error except the deferred-asset advisories in `NEVER_BLOCK`. Validate used\n * to keep only two structural codes, because it linted the composition as authored,\n * before `{{tokens}}` were filled, and a script full of tokens is a syntax error.\n * It now lints the composition prepared the way the render prepares it, so the\n * gate's verdict and validate's are the same verdict, reached before anything bills.\n */\nexport function lintBlockers(lintRaw: string): { code: string; message: string }[] {\n return classifyLint(parseCheckJson(lintRaw))\n .filter((f) => f.severity === \"blocking\")\n .map((f) => ({ code: f.code, message: f.message }));\n}\n\n// Memoized per process. The predictive validate lint should run only where\n// `hyperframes` is a first-class INSTALLED tool — i.e. the e2b render sandbox,\n// where the template installs it globally (on PATH). We probe the bare binary on\n// PATH (not `npx`, which on a dev box may resolve it from an incidental package\n// cache and then spend ~1.3s PER node linting fixtures during plain validate).\n// Off-sandbox the probe is an instant ENOENT, so validate stays free and the\n// gate degrades to a no-op exactly as the execute-time check does.\nlet hyperframesAvailable: boolean | null = null;\nexport async function isHyperframesAvailable(): Promise<boolean> {\n if (hyperframesAvailable !== null) return hyperframesAvailable;\n try {\n await execFileAsync(\"hyperframes\", [\"--version\"], { timeout: 10_000 });\n hyperframesAvailable = true;\n } catch {\n hyperframesAvailable = false;\n }\n return hyperframesAvailable;\n}\n\n/**\n * Validate-time predictive lint of a PREPARED composition dir (see\n * `composition-static-check.ts`). Returns `[]` when the tool is unavailable\n * (degrade gracefully, same as the execute-time gate) — so validate never blocks\n * a valid canvas just because the binary is absent off-sandbox.\n */\nexport async function lintPreparedComposition(\n dir: string,\n timeoutMs: number,\n): Promise<{ code: string; message: string }[]> {\n const lintRaw = await runOne(buildLintArgsNoInstall(dir), timeoutMs);\n return lintRaw === null ? [] : lintBlockers(lintRaw);\n}\n\nexport function buildInspectArgs(dir: string, samples: number): string[] {\n return [\"hyperframes\", \"inspect\", dir, \"--json\", \"--samples\", String(samples)];\n}\n\n/**\n * The nested-composition smoke test, and — with a key — the only check that can\n * see an EMPTY frame.\n *\n * Exiting 0 is what a blank render does too, so the command succeeding never\n * answered the question this check exists for. The question asks about physical\n * plausibility as well as emptiness, because the defect that reads loudest as\n * \"AI-generated\" is not a missing element — it is a present one at the wrong\n * size. Observed: a solar panel roughly five metres tall being lifted onto a\n * roof by one person, in a frame that was otherwise well lit, on brief and\n * perfectly legible. `--describe` sends the captured\n * frames to Gemini and writes back what is actually in them; measured against a\n * real render, it named the blank frames and the single visible element on its\n * own, unprompted by anything but the question.\n *\n * Without a key it stays exactly what it was: no network, no analysis, just proof\n * the render path completed. The deployment ships `GEMINI_API_KEY` by omission,\n * so this degrades rather than fails.\n */\nexport function buildSnapshotArgs(dir: string, frames: number, vision: boolean): string[] {\n const base = [\"hyperframes\", \"snapshot\", dir, \"--frames\", String(frames)];\n return vision\n ? [\n ...base,\n \"--describe\",\n \"Answer four things about this frame. (1) Is it empty or near-empty? Name every element actually visible. \" +\n \"(2) Could what is shown physically happen — object sizes, human scale, and whether every object has its \" +\n \"real-world form (a phone has ONE screen, on its front). Say so plainly if something is impossible. \" +\n \"(3) Read out every number, currency symbol and word visible INSIDE the picture — phone screens, documents, \" +\n \"signage — and say whether any of it contradicts the caption on this frame. \" +\n \"(4) Is the caption legible against what is behind it?\",\n ]\n : [...base, \"--describe\", \"false\"];\n}\n\n// A composition that EMBEDS another (a catalog block wired via data-composition-src)\n// can fail in ways lint + inspect + the studio preview ALL miss — the sub-comp's\n// <style>/<script> landing outside its <template>, a host/internal/timeline id\n// mismatch (a ~45s stall, then no animation), or styling the sub-comp root by class\n// instead of #root. Only an actual render exposes these, so when the host wires a\n// LIVE nested block we additionally run `snapshot` (a real headless render of a few\n// frames) as a smoke test. Comments are stripped first so the seeded EXAMPLE slot\n// (a commented-out data-composition-src) never trips it — only an uncommented,\n// wired embed does.\nexport function usesNestedCompositions(indexHtml: string): boolean {\n const withoutComments = indexHtml.replace(/<!--[\\s\\S]*?-->/g, \"\");\n return /data-composition-src\\s*=/.test(withoutComments);\n}\n\n/**\n * Returns the command's stdout (even on a non-zero exit — `lint`/`inspect` exit\n * non-zero when they FIND issues but still print JSON to stdout), or `null` when\n * the command itself is unavailable/failed to run.\n */\nasync function runOne(args: string[], timeoutMs: number): Promise<string | null> {\n try {\n const { stdout } = await execFileAsync(\"npx\", args, { timeout: timeoutMs, maxBuffer: 64 * 1024 * 1024 });\n return stdout;\n } catch (e) {\n const err = e as { stdout?: string; stderr?: string; message?: string };\n if (err.stdout?.includes(\"{\")) return err.stdout; // findings present, JSON on stdout\n const blob = `${err.stderr ?? \"\"} ${err.message ?? \"\"}`;\n if (UNAVAILABLE.test(blob)) return null; // tool missing → degrade gracefully\n return null; // ran but produced nothing parseable → don't block a valid render\n }\n}\n\n/**\n * Run `snapshot` as a render-path smoke test. Unlike lint/inspect it emits no\n * findings JSON — success is exit 0, failure is a throw. We distinguish the tool\n * being absent (degrade gracefully) from the render actually failing (block).\n */\nasync function runSnapshotSmoke(\n args: string[],\n timeoutMs: number,\n): Promise<{ ok: boolean; unavailable: boolean; message: string }> {\n try {\n await execFileAsync(\"npx\", args, { timeout: timeoutMs, maxBuffer: 64 * 1024 * 1024 });\n return { ok: true, unavailable: false, message: \"\" };\n } catch (e) {\n const err = e as { stderr?: string; stdout?: string; message?: string };\n const blob = `${err.stderr ?? \"\"} ${err.message ?? \"\"}`;\n if (UNAVAILABLE.test(blob)) return { ok: false, unavailable: true, message: blob };\n return { ok: false, unavailable: false, message: (err.stderr || err.message || \"snapshot failed\").slice(0, 800) };\n }\n}\n\n/**\n * The extra gate a composition that EMBEDS another needs.\n *\n * `check` and the studio preview both miss a broken embed — the sub-comp's\n * <style>/<script> landing outside its <template>, a host/internal id mismatch,\n * styling the sub-comp root by class instead of #root. Only a real render exposes\n * those, so this runs one when a live `data-composition-src` is wired.\n */\nasync function runNestedCompositionSmoke(opts: {\n dir: string;\n nodeId: string;\n ctx: { log: (s: string) => void };\n timeoutMs: number;\n samples: number;\n}): Promise<void> {\n const { dir, nodeId, ctx, timeoutMs, samples } = opts;\n const indexHtml = await readFile(path.join(dir, \"index.html\"), \"utf-8\").catch(() => \"\");\n if (!indexHtml || !usesNestedCompositions(indexHtml)) return;\n\n // A real headless render, orders of magnitude slower than the gate that just\n // ran, so it gets its own generous budget: a slow runner timing out is not an\n // UNAVAILABLE signal and would otherwise hard-block a valid composition.\n const snap = await runSnapshotSmoke(\n buildSnapshotArgs(dir, Math.min(samples, 3), hasFrameVisionKey()),\n Math.max(timeoutMs, 120_000),\n );\n\n if (snap.unavailable) {\n ctx.log(`${nodeId}: hyperframes snapshot unavailable — skipping nested-composition smoke test`);\n return;\n }\n if (!snap.ok) {\n throw new Error(\n `${nodeId}: nested-composition smoke test failed — an embedded block did not render. ` +\n `Check the host\\u2194block id match, that the block's <style>/<script> live inside its <template>, ` +\n `and that it styles #root (not a class).\\n${snap.message}`,\n );\n }\n\n // Read back rather than trusted: exiting 0 is what a blank render does too.\n const described = await readFile(path.join(dir, \"snapshots\", \"descriptions.md\"), \"utf-8\").catch(() => \"\");\n for (const line of condenseFrameDescriptions(described)) {\n ctx.log(`${nodeId}: frame check \\u2014 ${line}`);\n }\n ctx.log(`${nodeId}: nested-composition smoke test passed`);\n}\n\n/**\n * The gate, preferring 0.8's single browser session.\n *\n * Falls back to the two static passes when the installed binary predates\n * `check`, so a sandbox pinned to an older version still gets the gate it had,\n * and returns null only when neither shape is available at all.\n */\nasync function runGate(dir: string, timeoutMs: number, samples: number): Promise<CheckResult | null> {\n const checkRaw = await runOne(buildCheckArgs(dir, samples), timeoutMs);\n if (checkRaw !== null) return classifyGateOutput(checkRaw);\n const [lintRaw, inspectRaw] = await Promise.all([\n runOne(buildLintArgs(dir), timeoutMs),\n runOne(buildInspectArgs(dir, samples), timeoutMs),\n ]);\n if (lintRaw === null && inspectRaw === null) return null;\n return classifyCheckOutput(lintRaw ?? \"\", inspectRaw ?? \"\");\n}\n\nexport async function runHyperframesCheck(opts: {\n dir: string;\n nodeId: string;\n ctx: { log: (s: string) => void };\n timeoutMs: number;\n samples?: number;\n}): Promise<void> {\n const { dir, nodeId, ctx, timeoutMs, samples = 5 } = opts;\n\n const gate = await runGate(dir, timeoutMs, samples);\n if (gate === null) {\n ctx.log(`${nodeId}: hyperframes check/lint/inspect unavailable — skipping pre-render check`);\n return;\n }\n const { blocking, warnings } = gate;\n for (const line of summariseWarnings(warnings)) {\n ctx.log(`${nodeId}: hyperframe check warning ${line}`);\n }\n if (blocking.length > 0) {\n // Grouped like the warnings: one dead GSAP target reported six times is one\n // thing to fix, and six identical bullets buries what else is wrong with it.\n const seen = new Map<string, CheckFinding>();\n for (const b of blocking) seen.set(`${b.source}/${b.code}/${b.message}`, b);\n const detail = [...seen.values()].map((b) => `• [${b.source}/${b.code}] ${explainGateFinding(b)}`).join(\"\\n\");\n throw new Error(\n `${nodeId}: pre-render check failed (${blocking.length} blocking, ${seen.size} distinct)\\n${detail}`,\n );\n }\n\n // Extra gate for nested compositions: lint/inspect/preview can't see a broken\n // embed, only a real render can (see usesNestedCompositions). Runs after the\n // cheap static checks pass, and only when a live data-composition-src is wired.\n // Whether the caption cards are whole clauses. Not something the browser gate\n // can see: a card cut mid-sentence renders perfectly.\n const composition = await readFile(path.join(dir, \"index.html\"), \"utf-8\").catch(() => \"\");\n const captionComplaint = fragmentedCaptions(captionTextsFrom(composition));\n if (captionComplaint) {\n ctx.log(`${nodeId}: caption style — ${captionComplaint}`);\n }\n\n await runNestedCompositionSmoke({ dir, nodeId, ctx, timeoutMs, samples });\n\n ctx.log(`${nodeId}: pre-render check passed (${warnings.length} warning${warnings.length === 1 ? \"\" : \"s\"})`);\n}\n","/**\n * A caption card is a whole clause, not a slice of one.\n *\n * The defect this catches was reported twice, and the second report corrected the\n * first. A finished ad had some cards ending in a full stop and others not, which\n * reads as a mistake — but the fix is not to strip the punctuation. Stripped, the\n * cards are consistent and still wrong: \"En solo nueve días tu casa\" is not a\n * thing anyone wrote, it is a sentence cut in half by a timing decision.\n *\n * What makes captions read correctly is splitting ONLY where the script already\n * punctuates. Every card is then a clause carrying its own mark, which is\n * grammatical — and consistent as a by-product, because a clause always ends in\n * something. A card that ends bare is the tell that a split landed mid-thought.\n *\n * Checked rather than rewritten. The text is the creative's, and silently\n * re-cutting someone's copy at render time is worse than telling them where it\n * was cut badly.\n */\n\n/** Terminal marks a clause can legitimately end on. */\nconst TERMINAL = /[.,;:!?…]$/;\n\n/** The rendered text of each caption card, in composition order. */\nexport function captionTextsFrom(html: string): string[] {\n const cards = html.match(/<div[^>]*class=\"[^\"]*\\bcaption\\b[^\"]*\"[\\s\\S]*?<\\/div>/g) ?? [];\n return cards\n .map((card) =>\n card\n .replace(/<[^>]+>/g, \"\")\n .replace(/\\s+/g, \" \")\n .trim(),\n )\n .filter((text) => text.length > 0);\n}\n\n/**\n * The complaint, or null when every card closes a clause.\n *\n * The last card is exempt: a composition may legitimately end on a bare CTA.\n */\nexport function fragmentedCaptions(texts: string[]): string | null {\n if (texts.length < 2) return null;\n const fragments = texts.slice(0, -1).filter((t) => !TERMINAL.test(t));\n if (fragments.length === 0) return null;\n const example = fragments[0];\n return (\n `${fragments.length} of ${texts.length} caption cards end mid-clause, e.g. \"${example}\". ` +\n `Split captions where the script punctuates, not on a word count — a card that ends bare is a sentence ` +\n `cut in half by a timing decision, and it reads as one.`\n );\n}\n","import { writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { CompositionMeta } from \"../../../engine/composition-meta.ts\";\n\n/**\n * Write the top-level `meta.json` Hyperframes itself reads (next to index.html)\n * with {id,name,duration,width,height,fps}. We always overwrite with the\n * engine's values so Hyperframes' interpretation matches ours. Shared by\n * `hyperframe_render` (before render) and `hyperframe_snapshot` (before the\n * pre-render `lint`/`inspect` gate, which reads this file).\n */\nexport async function ensureHyperframesMetaJson(\n tmp: string,\n nodeId: string,\n meta: CompositionMeta,\n duration: number,\n): Promise<void> {\n const metaPath = path.join(tmp, \"meta.json\");\n await writeFile(\n metaPath,\n JSON.stringify(\n {\n id: nodeId,\n name: meta.id,\n duration,\n width: meta.width,\n height: meta.height,\n fps: meta.fps,\n },\n null,\n 2,\n ),\n \"utf-8\",\n );\n}\n","// Single-substitution model used by the composition pipeline.\n//\n// {{var}} in HTML, embedded <style>, embedded <script>\n// ─────► replaced before render by `substituteVariables`\n//\n// String values are inlined as JS-safe literals (`JSON.stringify`-style for\n// numbers, booleans, null, and complex structures; raw text in HTML attribute\n// or text contexts). The engine does the safe stringify — composition authors\n// never call `JSON.parse` again.\n\nconst PATTERN = /\\{\\{\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*\\}\\}/g;\n\n/**\n * Replace every `{{name}}` token in `source` with the JS literal form of\n * `values[name]`. Strings render as their plain text (no surrounding quotes\n * — convenient for both `font-size: {{size_px}}px` and `var X = {{name}};`).\n *\n * Complex values (arrays/objects/numbers/booleans) render via JSON.stringify\n * so the result is a syntactically valid JS literal **and** valid JSON.\n *\n * Missing keys are reported in the returned `missing` array; the engine\n * collects these and surfaces a single aggregated error.\n */\nexport function substituteVariables(\n source: string,\n values: Record<string, unknown>,\n): { output: string; missing: string[]; replaced: string[] } {\n const missing: string[] = [];\n const replaced: string[] = [];\n const seenMissing = new Set<string>();\n const seenReplaced = new Set<string>();\n\n const output = source.replace(PATTERN, (_full, name: string) => {\n if (!Object.hasOwn(values, name)) {\n if (!seenMissing.has(name)) {\n missing.push(name);\n seenMissing.add(name);\n }\n return `{{${name}}}`;\n }\n if (!seenReplaced.has(name)) {\n replaced.push(name);\n seenReplaced.add(name);\n }\n return literalize(values[name]);\n });\n\n return { output, missing, replaced };\n}\n\n/**\n * Render a value as a JS-safe literal embeddable in source code.\n *\n * string → plain text (no quotes — embed inside `\"…\"` if you need a string literal)\n * number → toString() (NaN/Infinity → \"0\")\n * boolean → \"true\" / \"false\"\n * null → \"null\"\n * array/object → JSON.stringify (also valid JS literal)\n * undefined → \"null\"\n *\n * The plain-text behavior for strings is deliberate: most composition uses\n * are HTML attributes or CSS values where surrounding quotes are author-supplied.\n * Authors who need a JS string literal write `\"{{name}}\"` themselves.\n */\nfunction literalize(value: unknown): string {\n if (value === undefined || value === null) return \"null\";\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) return \"0\";\n return String(value);\n }\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n // Arrays, objects: JSON.stringify produces valid JS *and* JSON.\n return JSON.stringify(value);\n}\n\n/**\n * List every `{{name}}` token referenced in `source`. Used by validators to\n * cross-check declared params vs. tokens actually present in the composition.\n */\nexport function extractReferencedTokens(source: string): string[] {\n const out = new Set<string>();\n for (const m of source.matchAll(PATTERN)) {\n const name = m[1];\n if (name) out.add(name);\n }\n return [...out];\n}\n","// Map noisy Hyperframes/ffmpeg/Chromium stderr into actionable messages.\n// Each entry's `match` is tested in order — first hit wins. The matcher\n// returns the friendly message (with a suggested next step) or null when\n// no pattern applies; callers fall back to raw stderr.\n//\n// New patterns: add an entry; the engine doesn't need updating.\n\ntype Pattern = {\n match: RegExp;\n message: (m: RegExpMatchArray) => string;\n};\n\nconst KNOWN_ERROR_PATTERNS: Pattern[] = [\n {\n match: /Variable issue[^\\n]*\\bduration\\b[^\\n]*not declared/i,\n message: () =>\n `Variable \"duration\" cannot be passed in params or declared in the composition — the engine injects it from the input video's duration. Remove \"duration\" from params.`,\n },\n {\n match: /BeginFrame auto-worker calibration timed out/i,\n message: () =>\n `Hyperframes' renderer is overloaded calibrating its frame workers. Try params.quality = \"draft\", params.workers = 2, or split the composition into smaller pieces.`,\n },\n {\n match: /media_missing_id:\\s*<audio>/i,\n message: () =>\n `A <audio> element in the composition is missing an \"id\" attribute. Add id=\"…\" (e.g. id=\"bg-audio\") so Hyperframes can discover it.`,\n },\n {\n match: /media_missing_id:\\s*<video>/i,\n message: () =>\n `A <video> element in the composition is missing an \"id\" attribute. Add id=\"…\" (e.g. id=\"bg\") so Hyperframes can discover it.`,\n },\n {\n match: /Overlapping clips? detected/i,\n message: () =>\n `Two clip elements overlap in time. Shave 1 ms off the previous clip's data-duration to introduce a sub-frame gap, or re-stitch upstream with the ffmpeg node.`,\n },\n {\n match: /ENOENT[^\\n]*gsap\\.min\\.js/i,\n message: () =>\n `Composition references ./gsap.min.js but the file wasn't found in the render directory. The engine vendors gsap from node_modules; ensure 'gsap' is installed in the CLI package, or self-supply gsap.min.js inside your composition directory.`,\n },\n {\n match: /chromium.*could not be launched|Executable doesn't exist/i,\n message: () =>\n `Headless Chrome is missing. Install Playwright Chromium (\\`pnpm exec playwright install chromium\\`) or run with params.docker = true for a sandboxed render.`,\n },\n];\n\nexport function mapKnownHyperframesError(stderr: string): string | null {\n if (!stderr) return null;\n for (const pattern of KNOWN_ERROR_PATTERNS) {\n const m = stderr.match(pattern.match);\n if (m) return `${pattern.message(m)}\\n\\n--- raw output ---\\n${stderr.slice(0, 1500)}`;\n }\n return null;\n}\n","import { execFile } from \"node:child_process\";\nimport { mkdtemp, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { z } from \"zod\";\nimport { hashCompositionDir } from \"../../engine/composition-hash.ts\";\nimport {\n buildParamsSchema,\n type CompositionMeta,\n defaultFilenameForInput,\n loadCompositionMeta,\n} from \"../../engine/composition-meta.ts\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport { type AssetRef, isStageableRef } from \"../../schema/refs.ts\";\nimport { assertInputsMatchMeta, resolveCompositionDir, validateCompositionNode } from \"./hyperframe.ts\";\nimport { refToUrl, type StageableRef, stageAsset } from \"./lib/assets.ts\";\nimport { copyComposition, vendorGsap } from \"./lib/composition-stage.ts\";\nimport { runHyperframesCheck } from \"./lib/hyperframe-check.ts\";\nimport { mapKnownHyperframesError } from \"./lib/hyperframe-errors.ts\";\nimport { ensureHyperframesMetaJson } from \"./lib/hyperframe-meta.ts\";\nimport { substituteVariables } from \"./lib/templating.ts\";\n\nconst _execFileAsync = promisify(execFile);\nconst require_ = createRequire(import.meta.url);\n\nconst WaitForSpec = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"auto\") }),\n z.object({ kind: z.literal(\"selector\"), value: z.string().min(1) }),\n z.object({ kind: z.literal(\"function\"), value: z.string().min(1) }),\n z.object({ kind: z.literal(\"timeout\"), ms: z.number().int().min(0).max(60_000) }),\n]);\n\n// Output is always rendered at the composition's declared width/height at 2x\n// device-scale (retina) for ad delivery. No knobs for full-page or transparent\n// background — composition controls the canvas size and background.\nconst HyperframeSnapshotParams = z\n .object({\n composition: z.string().min(1),\n wait_for: WaitForSpec.optional().default({ kind: \"auto\" }),\n timeout_ms: z.number().int().positive().optional().default(60_000),\n })\n .catchall(z.unknown());\n\nconst HyperframeSnapshotInputs = z.record(z.string(), z.custom<AssetRef>()).optional().default({});\n\nconst HyperframeSnapshotOutputs = z\n .object({\n image: z.custom<AssetRef>(),\n })\n .strict();\n\nconst NODE_OWNED_PARAM_KEYS = new Set([\"composition\", \"wait_for\", \"timeout_ms\"]);\n\n// Retina export — fixed for ad-creative delivery.\nconst DEVICE_SCALE_FACTOR = 2;\n\ntype Params = z.infer<typeof HyperframeSnapshotParams>;\n\nexport const hyperframeSnapshotNode = defineNode({\n id: \"hyperframe_snapshot\",\n version: \"4.1.0\",\n category: \"image\",\n location: \"local\",\n summary:\n \"Render an HTML/CSS composition to a static PNG via headless Chromium at 2x device-scale (retina). Same composition model as `hyperframe_render` — point `params.composition` at a directory containing `index.html` + `meta.json`.\",\n when_to_use:\n \"Use for static visuals composed from HTML/CSS: UI mockups, branded social posts, text overlays, multi-image grids. \" +\n \"Point `params.composition` at a directory containing `index.html` + `meta.json`. \" +\n \"Inputs are keyed by `meta.json.inputs`. \" +\n \"Output size: composition `meta.json` width/height × 2 (retina). \" +\n '`wait_for` defaults to `\"auto\"` which waits for page `load` + all `<img>` decoded + web fonts ready.',\n inputs: HyperframeSnapshotInputs,\n params: HyperframeSnapshotParams,\n outputs: HyperframeSnapshotOutputs,\n cost: () => ({ credits: 0, seconds_estimate: 3 }),\n\n // The snapshot's own keys (`wait_for`) are not composition params: checked against the\n // render node's key set, a canvas that waited on a selector failed validate every time.\n validateExtra: (args) => validateCompositionNode(args, NODE_OWNED_PARAM_KEYS),\n\n cacheKeyExtras: async ({ params }) => {\n const out: Record<string, string> = {};\n const composition = (params as { composition?: unknown }).composition;\n if (typeof composition !== \"string\") return out;\n const dir = await resolveCompositionDir(composition).catch(() => null);\n if (!dir) return out;\n out.composition_content_sha = await hashCompositionDir(dir);\n return out;\n },\n\n async execute({ inputs, params, ctx }) {\n const compositionDir = await resolveCompositionDir(params.composition);\n const meta = await loadCompositionMeta(compositionDir);\n const compositionParams = validateAndParseDynamicParams(meta, params);\n\n const tmp = await mkdtemp(path.join(tmpdir(), \"hf-snap-\"));\n try {\n await copyComposition(compositionDir, tmp);\n await vendorGsap(tmp, ctx);\n await stageInputs(tmp, inputs, meta, ctx);\n\n const substitutionValues = await buildSubstitutionValues(compositionParams, meta);\n await substituteCompositionFiles(tmp, substitutionValues);\n\n // Pre-render quality gate on the SUBSTITUTED composition: lint + inspect.\n // `inspect` reads the top-level meta.json, so write it first. One sample\n // is enough for a still. Overflow/structural errors block; contrast +\n // deferred-asset advisories only warn; missing tool degrades gracefully.\n await ensureHyperframesMetaJson(tmp, ctx.nodeId, meta, meta.default_duration);\n await runHyperframesCheck({\n dir: tmp,\n nodeId: \"hyperframe_snapshot\",\n ctx,\n timeoutMs: params.timeout_ms,\n samples: 1,\n });\n\n const entryPath = path.join(tmp, \"index.html\");\n const entryUrl = `file://${entryPath}`;\n ctx.log(`snapshotting ${meta.width}x${meta.height}@${DEVICE_SCALE_FACTOR}x wait=${params.wait_for.kind}`);\n\n const pwSpecifier = [\"play\", \"wright\"].join(\"\");\n const playwright = require_(pwSpecifier) as typeof import(\"playwright\");\n const { chromium } = playwright;\n const browser = await chromium.launch({ headless: true, args: chromiumArgsFor(meta) });\n try {\n const context = await browser.newContext({\n viewport: { width: meta.width, height: meta.height },\n deviceScaleFactor: DEVICE_SCALE_FACTOR,\n });\n const page = await context.newPage();\n await page.goto(entryUrl, { waitUntil: \"load\", timeout: params.timeout_ms });\n\n await waitForReady(page, params.wait_for, params.timeout_ms);\n\n const bytes = await page.screenshot({ type: \"png\" });\n\n ctx.log(`captured ${bytes.length} bytes`);\n const ref = await ctx.assets.ingestBytes({\n bytes: Buffer.from(bytes),\n kind: \"image\",\n mime: \"image/png\",\n metadata: {\n width: meta.width * DEVICE_SCALE_FACTOR,\n height: meta.height * DEVICE_SCALE_FACTOR,\n },\n });\n return { image: ref };\n } finally {\n await browser.close();\n }\n } catch (e) {\n const detail = (e as Error).message;\n const friendly = mapKnownHyperframesError(detail);\n if (friendly) throw new Error(`hyperframe_snapshot: ${friendly}`);\n throw e;\n } finally {\n await rm(tmp, { recursive: true, force: true }).catch((cleanupErr) => {\n ctx.log(`warning: tmp cleanup failed (${(cleanupErr as Error).message})`);\n });\n }\n },\n});\n\n/**\n * The flags a composition's page is opened with. File access lets a page read its own staged\n * files (the static ad reads its picture's pixels to place the copy; without it a file://\n * canvas is tainted), but Chromium grants it for every file:// path the Runtime can reach, so\n * only a composition whose meta.json declares `reads_staged_files` gets it.\n */\nexport function chromiumArgsFor(meta: Pick<CompositionMeta, \"reads_staged_files\">): string[] {\n return meta.reads_staged_files ? [\"--allow-file-access-from-files\"] : [];\n}\n\nfunction validateAndParseDynamicParams(meta: CompositionMeta, params: Params): Record<string, unknown> {\n const dynamic: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(params)) {\n if (NODE_OWNED_PARAM_KEYS.has(k)) continue;\n dynamic[k] = v;\n }\n const schema = buildParamsSchema(meta);\n const parsed = schema.safeParse(dynamic);\n if (!parsed.success) {\n const summary = parsed.error.issues.map((i) => `params.${i.path.join(\".\")}: ${i.message}`).join(\"; \");\n throw new Error(`hyperframe_snapshot: composition param validation failed — ${summary}`);\n }\n return parsed.data;\n}\n\nasync function stageInputs(\n tmp: string,\n inputs: Record<string, AssetRef>,\n meta: CompositionMeta,\n ctx: { log: (s: string) => void },\n): Promise<void> {\n assertInputsMatchMeta(inputs, meta, \"hyperframe_snapshot\");\n for (const [key, ref] of Object.entries(inputs ?? {})) {\n const spec = meta.inputs[key];\n if (!spec) continue;\n const filename = spec.staged_as ?? defaultFilenameForInput(key, spec.kind);\n await stageAsset(ref as StageableRef, tmp, filename);\n ctx.log(`staged ${spec.kind} → ${filename}`);\n }\n}\n\nasync function buildSubstitutionValues(\n compositionParams: Record<string, unknown>,\n meta: CompositionMeta,\n): Promise<Record<string, unknown>> {\n const out: Record<string, unknown> = {};\n for (const [name, value] of Object.entries(compositionParams)) {\n const spec = meta.params[name];\n if (spec?.kind === \"image\") {\n out[name] = await coerceImageParam(value);\n continue;\n }\n out[name] = value;\n }\n // Snapshots have no real duration; expose a sensible value for compositions\n // shared with hyperframe_render that reference {{duration}}.\n out.duration = meta.default_duration.toFixed(3);\n return out;\n}\n\nfunction coerceImageParam(value: unknown): Promise<string> {\n if (typeof value === \"string\") return Promise.resolve(value);\n if (isStageableRef(value)) return refToUrl(value);\n throw new Error(\"hyperframe_snapshot: image param must be a URL string or AssetRef\");\n}\n\nasync function substituteCompositionFiles(tmp: string, values: Record<string, unknown>): Promise<void> {\n const entryPath = path.join(tmp, \"index.html\");\n const original = await readFile(entryPath, \"utf-8\");\n const { output, missing } = substituteVariables(original, values);\n if (missing.length > 0) {\n throw new Error(\n `hyperframe_snapshot: composition references undefined variables: ${missing.map((m) => `{{${m}}}`).join(\", \")}.`,\n );\n }\n await writeFile(entryPath, output, \"utf-8\");\n}\n\nasync function waitForReady(\n page: import(\"playwright\").Page,\n waitFor: Params[\"wait_for\"],\n timeoutMs: number,\n): Promise<void> {\n switch (waitFor.kind) {\n case \"auto\":\n await page.evaluate(async () => {\n const imgs = Array.from(document.images);\n await Promise.all(\n imgs.map((img) =>\n img.complete && img.naturalWidth > 0 ? Promise.resolve() : img.decode().catch(() => undefined),\n ),\n );\n if (document.fonts && typeof document.fonts.ready?.then === \"function\") {\n await document.fonts.ready;\n }\n });\n return;\n case \"selector\":\n await page.waitForSelector(waitFor.value, { timeout: timeoutMs });\n return;\n case \"function\":\n await page.waitForFunction(waitFor.value, undefined, { timeout: timeoutMs });\n return;\n case \"timeout\":\n await page.waitForTimeout(waitFor.ms);\n return;\n default: {\n const _exhaustive: never = waitFor;\n throw new Error(`hyperframe_snapshot: unknown wait_for kind ${(_exhaustive as { kind: string }).kind}`);\n }\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { z } from \"zod\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport type { AssetRef } from \"../../schema/refs.ts\";\nimport { getToolVersion, runCli } from \"./lib/cli-runner.ts\";\n\nconst execFileAsync = promisify(execFile);\n\nconst OutputDecl = z\n .object({\n kind: z.enum([\"image\", \"video\", \"audio\"]),\n ext: z.string().min(1).max(8),\n })\n .strict();\n\nconst ImageMagickParams = z\n .object({\n args: z.array(z.string()).min(1),\n outputs: z.record(z.string(), OutputDecl).default({}),\n })\n .strict();\n\nconst ImageMagickInputs = z.record(z.string(), z.unknown());\n\nconst ImageMagickOutputs = z.record(z.string(), z.custom<AssetRef>());\n\n/**\n * Resolve which ImageMagick binary to use. Prefer `magick` (v7+); fall back to\n * `convert` (v6). Memoized per process; if neither is on PATH we fail at\n * execute time with a clear message.\n */\nlet resolvedBin: string | undefined;\nasync function resolveBin(): Promise<string> {\n if (resolvedBin) return resolvedBin;\n for (const candidate of [\"magick\", \"convert\"] as const) {\n try {\n await execFileAsync(candidate, [\"-version\"], { encoding: \"utf-8\" });\n resolvedBin = candidate;\n return candidate;\n } catch {\n // try next candidate\n }\n }\n throw new Error(\"imagemagick: neither `magick` nor `convert` found on PATH\");\n}\n\nexport const imagemagickNode = defineNode({\n id: \"imagemagick\",\n version: \"1.0.0\",\n category: \"image\",\n location: \"local\",\n summary:\n \"Local ImageMagick passthrough. Declare inputs, declare outputs, write the argv you'd type on the command line. Inputs are staged into a tmp dir and reached via `{{in.<slot>}}`; declared outputs are allocated at `{{out.<name>}}` and ingested as assets when the run completes.\",\n when_to_use:\n \"Use whenever you'd reach for ImageMagick on the command line: resize, crop, composite, convert formats, annotate, montage, fx. Pass the full argv as `params.args` (no shell — argv array, no string interpolation). \" +\n \"Wire input images via `inputs.<slot>` (single AssetRef) or `inputs.<slot>: [...]` (array, addressed as `{{in.<slot>.0}}`, …). \" +\n \"Declare every output file under `params.outputs` (name → {kind, ext}); the engine allocates the path, you reference it with `{{out.<name>}}`. \" +\n \"Requires `magick` (v7+) or `convert` (v6) on PATH. URL-style inputs and raw filesystem paths in args are rejected — keep everything in the engine's asset model.\",\n inputs: ImageMagickInputs,\n params: ImageMagickParams,\n outputs: ImageMagickOutputs,\n cost: () => ({ credits: 0, seconds_estimate: 3 }),\n\n async cacheKeyExtras() {\n const bin = await resolveBin().catch(() => \"imagemagick:unavailable\");\n return { imagemagick_version: await getToolVersion(bin) };\n },\n\n async execute({ inputs, params, ctx }) {\n const bin = await resolveBin();\n return await runCli({\n bin,\n args: params.args,\n inputs: inputs as Record<string, AssetRef | AssetRef[]>,\n outputs: params.outputs,\n ctx,\n });\n },\n});\n","import { supportedAspectRatios } from \"@baker/canvas-contract\";\nimport sharp from \"sharp\";\nimport { z } from \"zod\";\nimport type { ExecCtx } from \"../../engine/context.ts\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport { blockingArea } from \"../../scaffold/platform-safe-area.ts\";\nimport {\n chooseLogoSpot,\n designerSpots,\n type GreyTable,\n greyTable,\n LOGO_POSITIONS,\n type LogoSlot,\n logoSlotLine,\n spreadUnder,\n straightEdgeIn,\n} from \"../../scaffold/static-logo.ts\";\nimport { deliveredSize } from \"../../scaffold/static-sizes.ts\";\nimport { ImageRef } from \"../../schema/refs.ts\";\nimport { callBackendExec } from \"../remote/delegate.ts\";\nimport { imageGenerateNode } from \"../remote/image.ts\";\nimport { boxesOfLine, buttonShape, type CopyLine, isButtonLine, withWordmark } from \"./lib/must-show.ts\";\nimport { imageOf, isRead, pngOf, rawOf, type StepRun, subjectsStep, timedStep } from \"./lib/node-steps.ts\";\nimport { platePanels } from \"./lib/plate-panels.ts\";\nimport type { ReviewUsage } from \"./lib/render-review.ts\";\nimport { type SubjectBox, SubjectBoxSchema } from \"./lib/subject-boxes.ts\";\nimport { type PixelRect, type SubjectCrop, subjectCrop } from \"./lib/subject-crop.ts\";\nimport { readTextBoxes, type TextBox, type TextBoxReading } from \"./lib/text-boxes.ts\";\nimport { cropRaw, takeWhole, WHOLE_PROBLEMS, type WholeProblem, type WholeTake } from \"./lib/whole-render.ts\";\nimport {\n compose,\n coveredSubjects,\n cropLayer,\n identityOutside,\n moveLayer,\n planWordsShift,\n protectFaces,\n type Raw,\n registerToSource,\n type Span,\n type WordsMove,\n warpToCut,\n wordsLayer,\n} from \"./lib/words-layer.ts\";\n\nconst Usage = z\n .object({ model: z.string(), inputTokens: z.number(), outputTokens: z.number(), costUsd: z.number() })\n .strict();\nconst Unit = z.number().min(0).max(1);\nconst SpanSchema = z.object({ x0: Unit, y0: Unit, x1: Unit, y1: Unit }).strict();\nconst Copy = z.array(z.object({ text: z.string().min(1), role: z.string().optional() }).strict());\nconst Rect = z.object({ x: z.number(), y: z.number(), width: z.number(), height: z.number() }).strict();\n\nconst REASONS = [\n \"band_too_far\",\n \"words_over_face\",\n \"subject_covered\",\n \"subject_cut\",\n \"words_misaligned\",\n \"words_not_read\",\n \"not_read\",\n] as const;\n\n/** What a size node did, small enough for the run record (`facts`): the dashboard explains a size from it. */\nexport const FormatFacts = z\n .object({\n format: z.string(),\n lead: z.boolean(),\n plate: z.object({ width: z.number(), height: z.number() }).strict(),\n crop: Rect,\n render_ratio: z.string(),\n upscale: z.number(),\n /** Each block of words code moved (into the band, off a face): its scale and shift, fractions of the size. */\n moves: z.array(z.object({ scale: z.number(), dx: z.number(), dy: z.number() }).strict()),\n /** How far the words render sat from the cut once lined up (RMS grey levels): the spike's calibration of `MISALIGNED`. */\n residual: z.number().optional(),\n reason: z.enum(REASONS).optional(),\n /** `subject_covered`: the products and animals the words hide most of in this size, as the reader names them. */\n covered: z.array(z.string()).optional(),\n /**\n * How the words were laid: `whole`, the words model's whole render, its redrawn subjects put back\n * from the picture; `masked`, only what it changed at the words, on the picture (when its render\n * could not be taken whole twice). Absent when no words were set (`subject_cut`).\n */\n words_mode: z.enum([\"whole\", \"masked\"]).optional(),\n /** `whole`: the share of the picture's detail the render kept where it was (`keptShare`). */\n kept: z.number().optional(),\n /** `whole`: the people, faces and products put back from the picture where the render redrew them. */\n restored: z.array(z.string()).optional(),\n /** Why the first render could not be taken whole, so the words were set a second time. */\n retried: z.enum(WHOLE_PROBLEMS).optional(),\n /** `masked`: why the second render could not be taken whole either. */\n refused: z.enum(WHOLE_PROBLEMS).optional(),\n reverted: z.number(),\n /** `masked`: the mean difference from the cut outside the words layer, 0 by construction. */\n identity: z.number().optional(),\n steps: z.array(\n z\n .object({\n name: z.enum([\"subjects\", \"words\", \"words_again\", \"boxes\"]),\n cached: z.boolean(),\n credits: z.number(),\n ms: z.number(),\n })\n .strict(),\n ),\n })\n .strict();\nexport type FormatFacts = z.infer<typeof FormatFacts>;\n\nconst Words = z\n .object({\n model: z.string().min(1),\n quality: z.string().optional(),\n prompt: z.string().min(1),\n /** A change to the words of this size (`--reword`, an autofix): the previous render (`inputs.previous`) leads. */\n edit: z\n .object({ instruction: z.string().min(1) })\n .strict()\n .optional(),\n })\n .strict();\n\n/** The registration residual (grey levels, RMS) past which the render is not the cut redrawn: only the words' boxes are taken. */\nexport const MISALIGNED = 40;\n\nconst FormatParamsSchema = z\n .object({\n format: z.string().regex(/^\\d+(?:\\.\\d+)?:\\d+(?:\\.\\d+)?$/),\n lead: z.boolean().optional(),\n placements: z.array(z.string().min(1)).optional(),\n words: Words,\n copy: Copy.optional(),\n in_scene: z.array(z.string().min(1)).optional(),\n /** The plan's subject zone, fractions of the plate: what the cut centres on when no subject was read. */\n core: SpanSchema.optional(),\n band_min_scale: z.number().min(0.5).max(1).optional(),\n /**\n * The other sizes cut from the same picture (a variant's lead is checked against them): when\n * one would cut a face, a product or a head, no words are paid for (`subject_cut`).\n */\n check_formats: z.array(z.string().regex(/^\\d+(?:\\.\\d+)?:\\d+(?:\\.\\d+)?$/)).optional(),\n /**\n * The brand's logo file is placed on this size afterwards (`static_logo`): the words draw no logo\n * and keep its slot empty, planned here inside the size's safe area off every face and product,\n * from the logo's shape (`aspect`, width over height) and where the concept puts it (`position`).\n */\n logo_slot: z\n .object({ aspect: z.number().positive(), position: z.enum(LOGO_POSITIONS).optional() })\n .strict()\n .optional(),\n })\n .strict();\n\nexport const staticFormatNode = defineNode({\n id: \"static_format\",\n version: \"1.9.0\",\n category: \"image\",\n location: \"local\",\n billing: \"reported\",\n summary:\n \"One delivered size of a static ad, from the ad's picture (`plate`): cuts the size at one scale around the people and products (`subjects`), and around the cards the picture draws for its words when it can, has the image model set the ad's designed words, logo and button on the cut (`params.words`, one paid call), and takes its whole render, lined up with the cut, putting back from the picture each person, face and product it redrew (soft-edged, in the render's light). Words the frame cuts, the app covers or a face sits under are moved by code on the render, with the band, card or pill they sit on. A render that moved the picture or redrew a subject, or whose words no move clears, is set again once; when that one moved or redrew too, only what it changed at the words is kept on the picture, and when its words are out of place twice, it stays whole and says where they are. Outputs the size (`image`), the cut it was set on (`cut`), the model's render (`words_raw`), where the words were laid when only they were kept (`words_alpha`) and what it did (`facts`).\",\n when_to_use:\n \"One per delivered size of a static ad built on one picture (`format_<size>`, role `static_format`). One image call at the words model's price (two when the first cannot be taken whole), kept apart from the free cut and compose: changing only the band, the placements or the node's version never pays for it again; `--regenerate format_<size>` does.\",\n inputs: z\n .object({\n plate: ImageRef,\n subjects: z.array(SubjectBoxSchema).optional(),\n logo: ImageRef.optional(),\n type: ImageRef.optional(),\n style: ImageRef.optional(),\n refs: z.array(ImageRef).optional(),\n previous: ImageRef.optional(),\n })\n .strict(),\n params: FormatParamsSchema,\n outputs: z\n .object({\n image: ImageRef,\n cut: ImageRef,\n words_raw: ImageRef.optional(),\n words_alpha: ImageRef.optional(),\n /** The slot the words left empty for the logo file, in the size's pixels (`params.logo_slot`). */\n logo_slot: Rect.optional(),\n facts: FormatFacts,\n usage: z.array(Usage).optional(),\n })\n .strict(),\n outputKinds: { image: \"image\", cut: \"image\", words_raw: \"image\", words_alpha: \"image\" },\n cost: ({ params }) =>\n imageGenerateNode.cost?.({ params: wordsCallParams(params.words, \"1:1\") as never }) ?? {\n credits: 0,\n seconds_estimate: 60,\n },\n async execute({ inputs, params, ctx }) {\n return await formatSize(inputs, params, ctx);\n },\n});\n\ntype FormatInputs = {\n plate: ImageRef;\n subjects?: SubjectBox[];\n logo?: ImageRef;\n type?: ImageRef;\n style?: ImageRef;\n refs?: ImageRef[];\n previous?: ImageRef;\n};\ntype FormatParams = z.infer<typeof FormatParamsSchema>;\ntype Step = FormatFacts[\"steps\"][number];\n\n/** The image call's params: the words model at the render rectangle's ratio. */\nfunction wordsCallParams(words: z.infer<typeof Words>, ratio: string): Record<string, unknown> {\n const prompt = words.edit ? `Edit: ${words.edit.instruction}\\n\\n${words.prompt}` : words.prompt;\n return { model: words.model, prompt, aspect_ratio: ratio, ...(words.quality ? { quality: words.quality } : {}) };\n}\n\nconst percent = (v: number) => Math.round(Math.max(0, Math.min(1, v)) * 100);\n\n/**\n * The runtime line the words prompt ends with: where the faces in this size sit, for the words\n * to keep off. Empty when no face is in the frame. Pure.\n */\nexport function wordsAvoid(faces: readonly Span[]): string {\n if (faces.length === 0) return \"\";\n const where = faces.map(\n (f) => `a face ${percent(f.y0)}-${percent(f.y1)}% down, ${percent(f.x0)}-${percent(f.x1)}% across`,\n );\n return `Keep every word, the logo and the button off ${where.join(\"; \")}.`;\n}\n\n/** One axis's strips cut away, as the words line says them (\"a strip 3% deep at its top and 3% at its bottom\"). */\nfunction stripsOf(before: number, after: number, sides: [string, string], depth: string): string[] {\n const cut = [\n ...(percent(before) >= 1 ? [{ share: percent(before), side: sides[0] }] : []),\n ...(percent(after) >= 1 ? [{ share: percent(after), side: sides[1] }] : []),\n ];\n return cut.map((s, i) =>\n i === 0 ? `a strip ${s.share}% ${depth} at its ${s.side}` : `${s.share}% at its ${s.side}`,\n );\n}\n\n/**\n * The runtime line the words prompt ends with when the model draws more than the size: which\n * strips of its frame the size cuts away, for the words to keep clear of (GPT draws no 4:5, and\n * its 3:4 is cut). Empty when the size is the whole frame drawn. Pure.\n */\nexport function wordsFrame(frame: PixelRect, work: { width: number; height: number }, format: string): string {\n const down = stripsOf(frame.y / work.height, 1 - (frame.y + frame.height) / work.height, [\"top\", \"bottom\"], \"deep\");\n const across = stripsOf(frame.x / work.width, 1 - (frame.x + frame.width) / work.width, [\"left\", \"right\"], \"wide\");\n const strips = [down.join(\" and \"), across.join(\" and \")].filter(Boolean);\n if (strips.length === 0) return \"\";\n const many = down.length + across.length > 1;\n return `This picture is cut to ${format} afterwards: ${strips.join(\", and \")} ${many ? \"are\" : \"is\"} cut away, so no word, logo or button comes near ${many ? \"them\" : \"it\"}.`;\n}\n\n/**\n * The boxes read on the words render, split: `inScene` are the lines that are part of the\n * picture (a screen's chat, a label: they stay the picture's), `designed` everything else read\n * (the copy, the logo, and a button's whole shape). Pure.\n */\nexport function splitWordBoxes(\n boxes: readonly TextBox[],\n copy: readonly CopyLine[],\n inScene: readonly string[],\n): { designed: TextBox[]; inScene: TextBox[] } {\n const logoWords = copy.filter((l) => /logo/i.test(l.role ?? \"\")).map((l) => l.text);\n const read = withWordmark(boxes, logoWords);\n const lines = copy.filter((l) => !/logo/i.test(l.role ?? \"\"));\n const ours = new Set(lines.flatMap((line) => boxesOfLine(line, read)));\n // A line the copy does not name is the picture's (a phone's \"9:41\", a sign): lifted, it was pasted twice.\n const unnamed = (b: TextBox) => lines.length > 0 && b.kind === \"text\" && !ours.has(b);\n const scene = new Set([...inScene.flatMap((text) => boxesOfLine({ text }, read)), ...read.filter(unnamed)]);\n const buttons = new Set(copy.filter(isButtonLine).flatMap((line) => boxesOfLine(line, read)));\n return {\n designed: read.filter((b) => !scene.has(b)).map((b) => (buttons.has(b) ? buttonShape(b) : b)),\n inScene: read.filter((b) => scene.has(b)),\n };\n}\n\n/** A box on the render rectangle, as fractions of the size's own frame inside it. */\nfunction toFrame<T extends Span>(b: T, frame: PixelRect, work: { width: number; height: number }): T {\n return {\n ...b,\n x0: (b.x0 * work.width - frame.x) / frame.width,\n y0: (b.y0 * work.height - frame.y) / frame.height,\n x1: (b.x1 * work.width - frame.x) / frame.width,\n y1: (b.y1 * work.height - frame.y) / frame.height,\n };\n}\n\n/** A subject box of the plate, as fractions of the pixel rectangle `rect` of it. */\nfunction subjectIn(b: SubjectBox, rect: PixelRect, plate: { width: number; height: number }): SubjectBox {\n return {\n ...b,\n x0: (b.x0 * plate.width - rect.x) / rect.width,\n y0: (b.y0 * plate.height - rect.y) / rect.height,\n x1: (b.x1 * plate.width - rect.x) / rect.width,\n y1: (b.y1 * plate.height - rect.y) / rect.height,\n };\n}\n\nconst visible = (b: Span) => b.x1 > 0 && b.y1 > 0 && b.x0 < 1 && b.y0 < 1;\n\n/** The size's frame: the render rectangle at delivered scale, and the size inside it. */\ntype Framing = {\n upscale: number;\n work: { width: number; height: number };\n frame: PixelRect;\n /** The render rectangle of the plate, at `work` pixels: what the words model is shown. */\n renderCut: Raw;\n /** The size's own cut, at delivered pixels. */\n cutFrame: Raw;\n};\n\nasync function frameSize(plateBytes: Buffer, crop: SubjectCrop, format: string): Promise<Framing> {\n const delivered = deliveredSize(format);\n const upscale = delivered.width / crop.rect.width;\n const work = { width: Math.round(crop.render.width * upscale), height: Math.round(crop.render.height * upscale) };\n const frame = {\n x: Math.min(work.width - delivered.width, Math.max(0, Math.round((crop.rect.x - crop.render.x) * upscale))),\n y: Math.min(work.height - delivered.height, Math.max(0, Math.round((crop.rect.y - crop.render.y) * upscale))),\n width: delivered.width,\n height: delivered.height,\n };\n const region = { left: crop.render.x, top: crop.render.y, width: crop.render.width, height: crop.render.height };\n const renderCut = await rawOf(await sharp(plateBytes).extract(region).toBuffer(), work);\n return { upscale, work, frame, renderCut, cutFrame: cropRaw(renderCut, frame) };\n}\n\n/** What the words model is shown: the render rectangle of the cut, its ratio, the faces in it and the size's frame inside it. */\ntype Shown = {\n cut: ImageRef;\n ratio: string;\n faces: readonly Span[];\n frame: PixelRect;\n work: { width: number; height: number };\n /** The slot kept empty for the logo file, in the size's pixels. */\n logo?: LogoSlot;\n};\n\n/** A rectangle of the size's frame stated as fractions of the render rectangle the model draws. */\nfunction slotOnWork(rect: PixelRect, frame: PixelRect, work: { width: number; height: number }): Span {\n return {\n x0: (frame.x + rect.x) / work.width,\n y0: (frame.y + rect.y) / work.height,\n x1: (frame.x + rect.x + rect.width) / work.width,\n y1: (frame.y + rect.y + rect.height) / work.height,\n };\n}\n\n/** The kinds of subject a logo, plate and all, never sits on or crowds: as the composite keeps it. */\nconst LOGO_AVOIDS = new Set([\"person\", \"face\", \"product\", \"animal\"]);\n\n/** The spread of the grey level (0-255) under a slot up to which the picture counts as plain ground: as the composite reads it. */\nconst PLAIN_GROUND_SPREAD = 18;\n\n/**\n * The slot the logo file is placed in on this size, chosen by the function the composite places it\n * with (`chooseLogoSpot`), before any word is set: a designer's place inside the safe area, its clear\n * space off every person, face, product and animal of the cut (`subjects`, fractions of the render\n * rectangle), on the cut's plain ground and through no edge when the cut is given (`picture`, the\n * size's frame); the concept's corner when no place is clean.\n */\nexport function sizeLogoSlot(\n params: Pick<FormatParams, \"format\" | \"placements\" | \"logo_slot\">,\n frame: PixelRect,\n work: { width: number; height: number },\n subjects: readonly SubjectBox[],\n picture?: GreyTable,\n): LogoSlot | undefined {\n if (!params.logo_slot) return undefined;\n const avoid = subjects\n .filter((s) => LOGO_AVOIDS.has(s.kind))\n .map((s) => ({\n x: Math.round(s.x0 * work.width - frame.x),\n y: Math.round(s.y0 * work.height - frame.y),\n width: Math.round((s.x1 - s.x0) * work.width),\n height: Math.round((s.y1 - s.y0) * work.height),\n }));\n const size = { width: frame.width, height: frame.height };\n const safe = blockingArea(params.format, params.placements);\n const shape = {\n aspect: params.logo_slot.aspect,\n ...(params.logo_slot.position ? { position: params.logo_slot.position } : {}),\n };\n const spot = chooseLogoSpot(size, safe, {\n ...shape,\n subjects: avoid,\n ...(picture\n ? {\n calm: (r: PixelRect) => spreadUnder(picture, r) <= PLAIN_GROUND_SPREAD,\n crossesEdge: (r: PixelRect) => straightEdgeIn(picture, r),\n }\n : {}),\n });\n return spot?.slot ?? designerSpots(size, safe, shape)[0];\n}\n\n/**\n * The paid call: the words model sets the words on the render rectangle; `again` says what the\n * last render did wrong, when they are set a second time. A step, so a re-run replays it.\n */\nasync function setWords(\n inputs: FormatInputs,\n params: FormatParams,\n run: StepRun<Step[\"name\"]>,\n shown: Shown,\n again?: string,\n): Promise<ImageRef> {\n const callParams = wordsCallParams(params.words, shown.ratio);\n const prompt = [\n callParams.prompt,\n wordsAvoid(shown.faces),\n wordsFrame(shown.frame, shown.work, params.format),\n shown.logo ? logoSlotLine(slotOnWork(shown.logo.clear, shown.frame, shown.work), shown.logo.position) : \"\",\n again,\n ]\n .filter(Boolean)\n .join(\"\\n\\n\");\n const references = [\n ...(inputs.previous && params.words.edit ? [inputs.previous] : []),\n shown.cut,\n ...[inputs.logo, inputs.type, inputs.style].filter((r): r is ImageRef => r !== undefined),\n ...(inputs.refs ?? []),\n ];\n const call = { ...callParams, prompt };\n return await timedStep(\n run,\n again ? \"words_again\" : \"words\",\n { params: call, references: references.map((r) => r.sha256) },\n async (suffix, stepCtx) => {\n const out = await callBackendExec({\n nodeType: imageGenerateNode.id,\n nodeVersion: imageGenerateNode.version,\n params: imageGenerateNode.params.parse(call),\n inputs: { reference: references },\n outputKinds: { images: \"image\" },\n ctx: stepCtx,\n idempotencySuffix: suffix,\n });\n const first = Array.isArray(out.images) ? (out.images[0] as ImageRef | undefined) : undefined;\n if (!first) throw new Error(\"static_format: the words call returned no picture\");\n return first;\n },\n );\n}\n\n/** Where the words were read on the render, split from what the scene prints; the whole frame when nothing could read it. */\nfunction wordsRead(reading: TextBoxReading, params: FormatParams): { designed: TextBox[]; inScene: TextBox[] } {\n if (reading.status === \"read\") return splitWordBoxes(reading.boxes, params.copy ?? [], params.in_scene ?? []);\n return { designed: [{ text: \"\", kind: \"text\", x0: 0, y0: 0, x1: 1, y1: 1 }], inScene: [] };\n}\n\ntype Lifted = {\n out: Raw;\n alpha: Float32Array;\n moves: WordsMove[];\n residual: number;\n reverted: number;\n /** The products and animals the words hide most of. */\n covered: string[];\n reason?: FormatFacts[\"reason\"];\n};\n\n/**\n * The words lifted off the render and laid on the size's cut: lined up, kept only at the words,\n * cut to the size, moved inside its band when they reach past it.\n */\nfunction liftWords(\n render: Raw,\n framing: Framing,\n words: { designed: TextBox[]; inScene: TextBox[]; read: boolean },\n subjects: readonly SubjectBox[],\n params: FormatParams,\n keepOut: readonly Span[] = [],\n): Lifted {\n const faces = subjects.filter((b) => b.kind === \"face\");\n const fit = registerToSource(render, framing.renderCut, words.read ? words.designed : []);\n const misaligned = fit.residual > MISALIGNED;\n const aligned = misaligned ? render : warpToCut(render, fit);\n const { layer, reverted } = wordsLayer(aligned, framing.renderCut, words.designed, {\n subjects,\n keepOut: words.inScene,\n boxesOnly: misaligned,\n });\n const sized = cropLayer(layer, framing.frame);\n const inFrame = <T extends Span>(b: T): T => toFrame(b, framing.frame, framing.work);\n const frameFaces = faces.map(inFrame).filter(visible);\n const frameWords = words.designed.map(inFrame).filter(visible);\n // Words nobody could place are never moved: the whole frame stands in for them, and moving it shrinks the picture.\n const plan = words.read\n ? planWordsShift(frameWords, params.format, {\n ...(params.placements ? { placements: params.placements } : {}),\n ...(params.band_min_scale !== undefined ? { minScale: params.band_min_scale } : {}),\n // A move never takes words into the slot kept for the logo, nor is made for it: moving a block\n // out of it cut its band through the letters (Cubicup 4:5, round 6); the logo goes elsewhere.\n faces: frameFaces,\n keepOut,\n })\n : { moves: [] };\n // A word never lands on a face, wherever the model set it or the move took it: the face shows.\n const { layer: placed, covered } = protectFaces(\n plan.moves.length > 0 ? moveLayer(sized, plan.moves) : sized,\n frameFaces,\n );\n // The size shows the product the others show: words that hide most of it are set again elsewhere.\n const hidden = coveredSubjects(placed, subjects.map(inFrame).filter(visible));\n const reason =\n (words.read ? undefined : \"words_not_read\") ??\n plan.reason ??\n (misaligned ? \"words_misaligned\" : undefined) ??\n (covered > 0 ? \"words_over_face\" : undefined) ??\n (hidden.length > 0 ? \"subject_covered\" : undefined);\n return {\n out: compose(framing.cutFrame, placed),\n alpha: placed.alpha,\n moves: plan.moves,\n residual: fit.residual,\n reverted,\n covered: hidden,\n ...(reason ? { reason } : {}),\n };\n}\n\nasync function alphaPng(alpha: Float32Array, width: number, height: number): Promise<Buffer> {\n return await sharp(Buffer.from(alpha.map((a) => Math.round(a * 255))), { raw: { width, height, channels: 1 } })\n .png()\n .toBuffer();\n}\n\nconst round3 = (v: number) => Math.round(v * 1000) / 1000;\nconst round1 = (v: number) => Math.round(v * 10) / 10;\n\n/** What every size's facts start from: where it was cut and how much it was enlarged. */\ntype SizeBase = Pick<FormatFacts, \"format\" | \"lead\" | \"plate\" | \"crop\" | \"render_ratio\" | \"upscale\">;\n\n/** What a size's run kept beside its output: its step records, whether its subjects were read, its spend. */\ntype SizeRun = StepRun<Step[\"name\"]> & {\n subjectsRead: boolean;\n cut: ImageRef;\n framing: Framing;\n /** The slot kept for the logo with its clear space, fractions of the size: no word may sit there. */\n keepOut: Span[];\n};\n\n/** The facts of a size whose words were laid on the picture alone (`masked`). */\nfunction liftedFacts(base: SizeBase, lifted: Lifted, run: { identity: number; steps: Step[]; subjectsRead: boolean }) {\n const reason = lifted.reason ?? (run.subjectsRead ? undefined : \"not_read\");\n return {\n ...base,\n ...(reason ? { reason } : {}),\n ...(lifted.covered.length > 0 ? { covered: lifted.covered } : {}),\n moves: lifted.moves.map(({ fit }) => ({ scale: round3(fit.scale), dx: round3(fit.dx), dy: round3(fit.dy) })),\n residual: round1(lifted.residual),\n reverted: round3(lifted.reverted),\n identity: run.identity,\n steps: run.steps,\n } satisfies Omit<FormatFacts, \"words_mode\">;\n}\n\n/** One words call and what was read on it: its render at the work pixels, and where its words sit. */\ntype WordsTry = { ref: ImageRef; render: Raw; reading: TextBoxReading };\n\nasync function wordsTry(\n inputs: FormatInputs,\n params: FormatParams,\n run: SizeRun,\n shown: Shown,\n again?: string,\n): Promise<WordsTry> {\n const ref = await setWords(inputs, params, run, shown, again);\n const { bytes } = await imageOf(ref, \"static_format\");\n const reading = await timedStep<Step[\"name\"], TextBoxReading>(\n run,\n \"boxes\",\n { render: ref.sha256 },\n () => readTextBoxes(bytes, { onSpend: (u) => run.usage.push(u) }),\n { keep: isRead },\n );\n return { ref, render: await rawOf(bytes, run.framing.work), reading };\n}\n\n/** A words render taken whole (`takeWhole`), its words as read on it. */\nfunction takeOf(t: WordsTry, run: SizeRun, subjects: readonly SubjectBox[], params: FormatParams): WholeTake {\n const { framing } = run;\n return takeWhole({\n render: t.render,\n cut: framing.renderCut,\n frame: framing.frame,\n words:\n t.reading.status === \"read\" ? splitWordBoxes(t.reading.boxes, params.copy ?? [], params.in_scene ?? []) : null,\n subjects,\n format: params.format,\n ...(params.placements ? { placements: params.placements } : {}),\n ...(params.band_min_scale !== undefined ? { minScale: params.band_min_scale } : {}),\n ...(run.keepOut.length > 0 ? { keepOut: run.keepOut } : {}),\n });\n}\n\nconst quoted = (what: readonly string[]) => what.map((w) => `\"${w}\"`).join(\", \");\n\n/**\n * What the second words call is told of the first render: what it did wrong, said as what to do.\n * Appended to the words prompt. Pure.\n */\nexport function setAgain(problem: WholeProblem, what: readonly string[]): string {\n const said: Record<WholeProblem, string> = {\n picture_moved:\n \"Your last version moved or resized the picture to make room for the words. Keep Image 1 exactly where it is, at its size and framing; lay any band or card over its edge instead.\",\n subject_redrawn: `Your last version drew ${what.join(\" and \") || \"a person\"} again, elsewhere or in another pose. Keep them exactly as Image 1 shows them, where they are, and set the words around them.`,\n words_lost: `Your last version set ${quoted(what) || \"words\"} where this size is cut, the app's buttons cover them or the logo goes. Keep every word and the button inside the zones and out of the place kept plain for the logo.`,\n words_over_face:\n \"Your last version set words over a face. Keep every word, the logo and the button off every face.\",\n };\n return said[problem];\n}\n\n/** What a size taken whole delivers: the render with the picture put back, and what code moved. */\ntype Taken = { out: Raw; restored: string[]; covered: string[]; moves: WordsMove[]; kept: number; residual: number };\n\n/** Why a size taken whole still has its words out of place, as the review blocks it. */\nconst MISPLACED: Partial<Record<WholeProblem, FormatFacts[\"reason\"]>> = {\n words_lost: \"band_too_far\",\n words_over_face: \"words_over_face\",\n};\n\n/**\n * The size as the words render taken whole: its facts say what was put back, why the words were\n * set again (`retried`), and, when they are still out of place (`misplaced`), where, as the review\n * blocks it, so they are set again then.\n */\nasync function wholeSize(\n take: Taken,\n t: WordsTry,\n run: SizeRun,\n base: SizeBase,\n why: { retried?: WholeProblem; misplaced?: WholeProblem } = {},\n) {\n const { retried } = why;\n const image = (await run.ctx.assets.ingestBytes({\n bytes: await pngOf(take.out),\n kind: \"image\",\n mime: \"image/png\",\n })) as ImageRef;\n const reason =\n (t.reading.status === \"read\" ? undefined : \"words_not_read\") ??\n (why.misplaced ? MISPLACED[why.misplaced] : undefined) ??\n (take.covered.length > 0 ? \"subject_covered\" : undefined) ??\n (run.subjectsRead ? undefined : \"not_read\");\n const facts: FormatFacts = {\n ...base,\n ...(reason ? { reason } : {}),\n ...(take.covered.length > 0 ? { covered: take.covered } : {}),\n words_mode: \"whole\",\n kept: round3(take.kept),\n ...(take.restored.length > 0 ? { restored: take.restored } : {}),\n ...(retried ? { retried } : {}),\n moves: take.moves.map(({ fit }) => ({ scale: round3(fit.scale), dx: round3(fit.dx), dy: round3(fit.dy) })),\n residual: round1(take.residual),\n reverted: 0,\n steps: run.steps,\n };\n run.ctx.log(\n `${base.format}: cut ${base.crop.width}x${base.crop.height} (x${base.upscale}), words whole${take.moves.length > 0 ? \", moved\" : \"\"}${take.restored.length > 0 ? `, ${take.restored.join(\", \")} put back` : \"\"}${retried ? ` (set again: ${retried})` : \"\"}${reason ? `, ${reason}` : \"\"}`,\n );\n return { image, cut: run.cut, words_raw: t.ref, facts };\n}\n\n/** The size with only what a words render changed at the words laid on the picture: the last resort. */\nasync function maskedSize(\n t: WordsTry,\n run: SizeRun,\n base: SizeBase,\n subjects: readonly SubjectBox[],\n params: FormatParams,\n why: { retried: WholeProblem; refused: WholeProblem },\n) {\n const { framing } = run;\n const lifted = liftWords(\n t.render,\n framing,\n { ...wordsRead(t.reading, params), read: t.reading.status === \"read\" },\n subjects,\n params,\n run.keepOut,\n );\n const identity = identityOutside(lifted.out, framing.cutFrame, lifted.alpha);\n if (identity !== 0) throw new Error(`static_format: the picture outside the words changed (${identity})`);\n const [image, alpha] = await Promise.all([\n run.ctx.assets.ingestBytes({ bytes: await pngOf(lifted.out), kind: \"image\", mime: \"image/png\" }),\n run.ctx.assets.ingestBytes({\n bytes: await alphaPng(lifted.alpha, framing.frame.width, framing.frame.height),\n kind: \"image\",\n mime: \"image/png\",\n }),\n ]);\n const facts: FormatFacts = {\n ...liftedFacts(base, lifted, { identity, steps: run.steps, subjectsRead: run.subjectsRead }),\n words_mode: \"masked\",\n retried: why.retried,\n refused: why.refused,\n };\n run.ctx.log(\n `${base.format}: cut ${base.crop.width}x${base.crop.height} (x${base.upscale}), words set twice (${why.retried}, then ${why.refused}), only the words kept${lifted.moves.length > 0 ? \", moved\" : \"\"}${facts.reason ? `, ${facts.reason}` : \"\"}`,\n );\n return { image: image as ImageRef, cut: run.cut, words_raw: t.ref, words_alpha: alpha as ImageRef, facts };\n}\n\nasync function formatSize(inputs: FormatInputs, params: FormatParams, ctx: ExecCtx) {\n const { bytes: plateBytes, size: plate } = await imageOf(inputs.plate, \"static_format\");\n const steps: Step[] = [];\n const usage: ReviewUsage[] = [];\n const spend = () => (usage.length > 0 ? { usage } : {});\n const subjects = inputs.subjects ?? (await subjectsStep({ ctx, steps, usage }, inputs.plate, plateBytes));\n const ratios = supportedAspectRatios(\"image_generate\", params.words.model);\n // The cards the picture draws for its words are cut whole when the cut can: the words go in them.\n const panels = platePanels(await rawOf(plateBytes, plate));\n const crop = subjectCrop(plate, params.format, subjects, {\n ...(params.core ? { core: params.core } : {}),\n ...(ratios ? { renderRatios: ratios } : {}),\n ...(panels.length > 0 ? { panels } : {}),\n });\n const framing = await frameSize(plateBytes, crop, params.format);\n const cutRef = (await ctx.assets.ingestBytes({\n bytes: await pngOf(framing.cutFrame),\n kind: \"image\",\n mime: \"image/png\",\n })) as ImageRef;\n const base: SizeBase = {\n format: params.format,\n lead: params.lead ?? false,\n plate,\n crop: crop.rect,\n render_ratio: crop.render.ratio,\n upscale: round3(framing.upscale),\n };\n const shownSubjects = (subjects ?? []).map((s) => subjectIn(s, crop.render, plate)).filter(visible);\n // The logo file is placed afterwards: its slot, chosen as the composite chooses it, is kept empty by the words.\n const logo = sizeLogoSlot(params, framing.frame, framing.work, shownSubjects, greyTable(framing.cutFrame));\n const slotOut = logo ? { logo_slot: logo.rect } : {};\n // A variant's picture that cannot give every size it is cut to is set aside before its words are paid for.\n const elsewhere = (params.check_formats ?? [])\n .filter((f) => f !== params.format)\n .map((f) => ({ format: f, crop: subjectCrop(plate, f, subjects, params.core ? { core: params.core } : {}) }))\n .find((c) => !c.crop.fits);\n if (!crop.fits || elsewhere) {\n const lost = crop.fits && elsewhere ? `${elsewhere.format}: ${elsewhere.crop.cut.join(\", \")}` : crop.cut.join(\", \");\n ctx.log(`${params.format}: no cut keeps ${lost} whole; the words were not set`);\n const facts: FormatFacts = { ...base, reason: \"subject_cut\", moves: [], reverted: 0, identity: 0, steps };\n return { image: cutRef, cut: cutRef, facts, ...slotOut, ...spend() };\n }\n const shownCut = await ctx.assets.ingestBytes({\n bytes: await pngOf(framing.renderCut),\n kind: \"image\",\n mime: \"image/png\",\n });\n const keepOut = logo\n ? [\n {\n x0: logo.clear.x / framing.frame.width,\n y0: logo.clear.y / framing.frame.height,\n x1: (logo.clear.x + logo.clear.width) / framing.frame.width,\n y1: (logo.clear.y + logo.clear.height) / framing.frame.height,\n },\n ]\n : [];\n const run: SizeRun = { ctx, steps, usage, subjectsRead: subjects !== null, cut: cutRef, framing, keepOut };\n const shown: Shown = {\n cut: shownCut as ImageRef,\n ratio: crop.render.ratio,\n faces: shownSubjects.filter((s) => s.kind === \"face\"),\n frame: framing.frame,\n work: framing.work,\n ...(logo ? { logo } : {}),\n };\n return { ...(await letter({ inputs, params, run, shown, base, subjects: shownSubjects })), ...slotOut, ...spend() };\n}\n\n/** What lettering one size works from: the node's inputs and params, its run, what the model is shown, its facts so far. */\ntype Lettering = {\n inputs: FormatInputs;\n params: FormatParams;\n run: SizeRun;\n shown: Shown;\n base: SizeBase;\n subjects: readonly SubjectBox[];\n};\n\n/**\n * The size's words: the render taken whole; else set again once, told what went wrong; twice out of\n * place only, it stays whole and says so; twice no lettering of the picture, only the words are kept.\n */\nasync function letter(l: Lettering) {\n const { inputs, params, run, shown, base, subjects } = l;\n const first = await wordsTry(inputs, params, run, shown);\n const firstTake = takeOf(first, run, subjects, params);\n if (firstTake.ok) return await wholeSize(firstTake, first, run, base);\n // A render that is no lettering of the picture is set again once, told what went wrong.\n const second = await wordsTry(inputs, params, run, shown, setAgain(firstTake.problem, firstTake.what));\n const secondTake = takeOf(second, run, subjects, params);\n const retried = firstTake.problem;\n if (secondTake.ok) return await wholeSize(secondTake, second, run, base, { retried });\n // Twice its words out of place, the picture right: it stays whole, and says where its words are.\n const placed = [\n { take: secondTake, t: second },\n { take: firstTake, t: first },\n ].find((p) => p.take.whole);\n const whole = placed?.take.whole;\n if (placed && whole) {\n const taken = { ...whole, moves: [], kept: placed.take.kept, residual: placed.take.residual };\n return await wholeSize(taken, placed.t, run, base, { retried, misplaced: placed.take.problem });\n }\n // Twice refused: only the words are kept, off the render that kept more of the picture.\n const kept = secondTake.kept >= firstTake.kept ? second : first;\n return await maskedSize(kept, run, base, subjects, params, { retried, refused: secondTake.problem });\n}\n","import {\n IMAGE_GENERATE_MODELS,\n IMAGE_TIER_CREDITS,\n imagePictureCredits,\n modelIdsAccepted,\n} from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { ImageRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\nimport { registryParamShape } from \"./registry-params.ts\";\n\n// Imported, never re-listed. This used to be a local copy of the roster, which\n// silently went stale the moment a model was added to the contract: the registry\n// priced and validated the new model while this enum still rejected it, so every\n// canvas using it failed with a confusing `INVALID_PARAMS` naming the OLD set.\n// The video node has always imported its roster; this now matches. A superseded id\n// (`MODEL_ALIASES`) stays accepted and is kept as written, so a recorded canvas and its\n// cache key never change; the backend runs it on its successor.\nconst imageModelEnum = z.enum(IMAGE_GENERATE_MODELS.flatMap(modelIdsAccepted) as [string, ...string[]]);\n\n// Permissive union of every param accepted by any curated model, derived from the\n// registry (`registryParamShape`), which is also the strict per-model gate: it rejects\n// params a specific model doesn't support and validates enum values. Spelled out here,\n// the `quality` list once stopped at `high` while gpt-image-2.5 grew `xhigh` and `max`,\n// and every ad `scaffold-ad` wrote failed validation before a single node ran.\nconst ImageGenerateParams = z\n .object({\n model: imageModelEnum,\n ...registryParamShape(\"image_generate\", {\n prompt: z.string().min(1),\n // Recraft v4 vector controls, sent as the provider's own `controls` block. The\n // registry types them as JSON; this is their shape.\n rgb_colors: z.array(z.array(z.number().int().min(0).max(255))),\n background_rgb_color: z.array(z.number().int().min(0).max(255)),\n }),\n })\n .strict();\n\n/**\n * A picture asked at the top quality step bills about what Nano Banana Pro's does: bench E5\n * measured gpt-image-2.5 at `max`, with the chosen ad and the logo as references, at $0.14 (9:16)\n * to $0.21 (3:4) a picture (.context/static-review/BENCH.md § \"E5 — true per-format adaptation\").\n */\nconst PRO_QUALITY = \"max\";\n\n/** The quote of one picture: the Pro image models and the top quality step at Pro's rate, the rest at the plain rate. */\nfunction creditsPerImage(params: { model?: unknown; quality?: unknown }): number {\n return params.quality === PRO_QUALITY ? IMAGE_TIER_CREDITS.pro : imagePictureCredits(String(params.model));\n}\n\n/** The `n` a node asks for. The registry-derived shape types it only as one of many params. */\nfunction imagesPerCall(params: object): number {\n return \"n\" in params && typeof params.n === \"number\" ? params.n : 1;\n}\n\nexport const imageGenerateNode = delegated({\n id: \"image_generate\",\n version: \"2.2.0\",\n category: \"image\",\n summary:\n \"Generate images for ad creatives. Curated model set: GPT Image 2.5, Gemini 3.1 Flash Image, Gemini 3 Pro Image, Recraft v4.1 Pro Vector. Per-model param support comes from the canvas-engine model registry.\",\n when_to_use:\n \"Use for hero shots, product photography, illustrations, and vector logos. `recraft/recraft-v4.1-pro-vector` for crisp vector / logo work; `openai/gpt-image-2` for photorealistic and in-image text (NOTE: it has no `image_size`, and no 4:5 / 5:4 — route portrait ad formats through Gemini or `image_aspect_adapt`); Gemini variants for fast iteration, extreme ratios, and editing via the `reference` input. `reference` accepts ONE image or an ARRAY of images — wire several to combine references in a single generation (e.g. a subject sheet + a font specimen + the original ad). Every reference is forwarded to the model in array order. `n` (only on models that declare it, e.g. `openai/gpt-image-2.5-sunburst`) returns several candidates of the same brief from one call, billed per image like separate calls; wire the whole `images` array into `image_select` to keep the best.\",\n // `reference` is one image or an ordered array of images. The backend forwards\n // each as a separate `image_url` to the provider (OpenRouter accepts many).\n inputs: z.object({ reference: z.union([ImageRef, z.array(ImageRef).min(1)]).optional() }).loose(),\n params: ImageGenerateParams,\n outputs: z.object({ images: z.array(ImageRef).min(1) }).strict(),\n outputKinds: { images: \"image\" },\n // Per image: `n` asks one call for several, and the provider bills each (measured: n=3\n // cost exactly 3x n=1, prompt tokens included). Usage-billed, so this is only the pre-run\n // quote; the charge is the provider's reported cost.\n cost: ({ params }) => ({\n credits: creditsPerImage(params) * imagesPerCall(params),\n seconds_estimate: 10,\n }),\n});\n","import { MODEL_REGISTRY, type NodeKind, type ParamSchema } from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\n\n/**\n * A managed node's param schema, derived from the model registry rather than listed\n * by hand: the PERMISSIVE union of every param any model of `kind` declares. It\n * answers \"is this a param at all, and of the right shape\"; which model takes which\n * param, and which enum value, stays the registry validator's job\n * (`validateModelParams`), because a node schema cannot branch on the model.\n *\n * Listed by hand, this drifted: Seedance 2.5 declared `watermark` and the backend\n * forwarded it, while the node's strict schema refused it before it left the CLI.\n *\n * `overrides` replaces the derived schema for a param, for shapes the registry types\n * as `json` (the registry only knows it is JSON) or where the node wants a stricter\n * floor than the union (a non-empty prompt). A param is required only when every\n * model requires it.\n */\nexport function registryParamShape(\n kind: NodeKind,\n overrides: Readonly<Record<string, z.ZodType>> = {},\n): Record<string, z.ZodType> {\n const specs = Object.values(MODEL_REGISTRY[kind]);\n const byParam = new Map<string, ParamSchema[]>();\n for (const spec of specs) {\n for (const [name, schema] of Object.entries(spec.params)) {\n byParam.set(name, [...(byParam.get(name) ?? []), schema]);\n }\n }\n const shape: Record<string, z.ZodType> = {};\n for (const [name, schemas] of byParam) {\n const type = overrides[name] ?? unionOf(schemas);\n const requiredByAll = specs.every((spec) => spec.required.includes(name));\n shape[name] = requiredByAll ? type : type.optional();\n }\n return shape;\n}\n\nfunction unionOf(schemas: readonly ParamSchema[]): z.ZodType {\n const kinds = [...new Set(schemas.map((schema) => schema.kind))];\n if (kinds.length > 1) {\n const [first, second, ...rest] = kinds.map((k) => unionOf(schemas.filter((s) => s.kind === k)));\n return z.union([first as z.ZodType, second as z.ZodType, ...rest]);\n }\n switch (kinds[0]) {\n case \"string\":\n return stringUnion(schemas as Extract<ParamSchema, { kind: \"string\" }>[]);\n case \"number\":\n return numberUnion(schemas as Extract<ParamSchema, { kind: \"number\" }>[]);\n case \"boolean\":\n return z.boolean();\n default:\n return z.unknown();\n }\n}\n\n/** Every value some model enumerates, or any string once one model leaves it open. */\nfunction stringUnion(schemas: Extract<ParamSchema, { kind: \"string\" }>[]): z.ZodType {\n if (schemas.some((schema) => !schema.enum)) return z.string();\n const values = [...new Set(schemas.flatMap((schema) => schema.enum ?? []))];\n return z.enum(values as [string, ...string[]]);\n}\n\n/** Every value some model enumerates, or any number once one model leaves it open. */\nfunction numberUnion(schemas: Extract<ParamSchema, { kind: \"number\" }>[]): z.ZodType {\n if (schemas.some((schema) => !schema.enum)) return z.number();\n const values = [...new Set(schemas.flatMap((schema) => schema.enum ?? []))].sort((a, b) => a - b);\n return z.literal(values);\n}\n","/**\n * What the static ad's picture nodes (`static_format`, `static_plate`) share: their paid and read\n * steps, kept in the node's step cache and timed for its facts, and the raw-pixel reads and writes\n * their pure geometry works on.\n */\nimport sharp from \"sharp\";\nimport type { ExecCtx, StepOptions } from \"../../../engine/context.ts\";\nimport type { ImageRef } from \"../../../schema/refs.ts\";\nimport type { ReviewUsage } from \"./render-review.ts\";\nimport { bytesOf } from \"./static-review.ts\";\nimport { readSubjectBoxes, type SubjectBox } from \"./subject-boxes.ts\";\nimport type { Size } from \"./subject-crop.ts\";\nimport type { Raw } from \"./words-layer.ts\";\n\n/** One step of a node's run, for its facts: whether it was replayed, what the backend charged, how long it took. */\nexport type StepRecord<N extends string> = { name: N; cached: boolean; credits: number; ms: number };\n\n/** What a node's steps write to: its context, its step records and the reader spend it relays. */\nexport type StepRun<N extends string> = { ctx: ExecCtx; steps: StepRecord<N>[]; usage: ReviewUsage[] };\n\n/**\n * Runs `fn` as the node's step `name` (replayed from the step cache while `key` holds), timing it\n * and counting what the backend charged inside it. `fn` gets the step's idempotency suffix and a\n * context whose charges count toward the step. `keep` says which results are replayed: a reading\n * the reader could not make is asked again on the next run.\n */\nexport async function timedStep<N extends string, T>(\n run: StepRun<N>,\n name: N,\n key: unknown,\n fn: (suffix: string, stepCtx: ExecCtx) => Promise<T>,\n opts: StepOptions<T> = {},\n): Promise<T> {\n const t0 = Date.now();\n let credits = 0;\n const stepCtx: ExecCtx = {\n ...run.ctx,\n reportCharge: (c) => {\n credits += c;\n run.ctx.reportCharge?.(c);\n },\n };\n const go = (suffix: string) => fn(suffix, stepCtx);\n const { value, cached } = run.ctx.steps\n ? await run.ctx.steps.run(name, key, go, opts)\n : { value: await go(name), cached: false };\n run.steps.push({ name, cached, credits, ms: Date.now() - t0 });\n return value;\n}\n\n/** Whether a reader's answer was read: only a reading is replayed, a failure is asked again. */\nexport const isRead = (reading: { status: string }): boolean => reading.status === \"read\";\n\n/** The picture's subjects, read once (a step: free on a re-run); null when the reader could not say. */\nexport async function subjectsStep<N extends string>(\n run: StepRun<N | \"subjects\">,\n image: ImageRef,\n bytes: Buffer,\n): Promise<SubjectBox[] | null> {\n const read = await timedStep(\n run,\n \"subjects\",\n { image: image.sha256 },\n () => readSubjectBoxes(bytes, { onSpend: (u) => run.usage.push(u) }),\n { keep: isRead },\n );\n return read.status === \"read\" ? read.boxes : null;\n}\n\n/** An image's bytes and pixel size. */\nexport async function imageOf(ref: ImageRef, node: string): Promise<{ bytes: Buffer; size: Size }> {\n const at = ref.path ?? ref.url;\n if (!at) throw new Error(`${node}: a picture it was given has no file`);\n const bytes = await bytesOf(at);\n const meta = await sharp(bytes).metadata();\n return { bytes, size: { width: meta.width ?? 0, height: meta.height ?? 0 } };\n}\n\n/** `bytes` decoded to RGB at `size` (Lanczos when it resizes). */\nexport async function rawOf(bytes: Buffer, size: Size): Promise<Raw> {\n const { data, info } = await sharp(bytes)\n .removeAlpha()\n .resize(size.width, size.height, { fit: \"fill\", kernel: \"lanczos3\" })\n .raw()\n .toBuffer({ resolveWithObject: true });\n return { data, width: size.width, height: size.height, channels: info.channels };\n}\n\nexport function pngOf(raw: Raw): Promise<Buffer> {\n return sharp(raw.data, { raw: { width: raw.width, height: raw.height, channels: raw.channels as 3 } })\n .png()\n .toBuffer();\n}\n","/**\n * Where every person, face, animal and product sits in a static ad's picture, read by the same\n * vision model and grid as `text-boxes.ts`. Each size is cut around these boxes (`subject-crop.ts`)\n * and its words kept off the faces (`words-layer.ts`).\n *\n * One box shape leaves this module: the subject's kind, a short label, and its rectangle as\n * fractions of the frame, origin top-left.\n */\nimport { SUBJECT_BOX_READER_MODEL } from \"@baker/canvas-contract\";\nimport sharp from \"sharp\";\nimport { z } from \"zod\";\nimport { askAboutImages, type ReviewUsage } from \"./render-review.ts\";\n\nexport const SUBJECT_KINDS = [\"person\", \"face\", \"animal\", \"product\"] as const;\nexport type SubjectKind = (typeof SUBJECT_KINDS)[number];\n\nexport const SubjectBoxSchema = z\n .object({\n kind: z.enum(SUBJECT_KINDS),\n label: z.string(),\n x0: z.number().min(0).max(1),\n y0: z.number().min(0).max(1),\n x1: z.number().min(0).max(1),\n y1: z.number().min(0).max(1),\n })\n .strict();\nexport type SubjectBox = z.infer<typeof SubjectBoxSchema>;\n\n/** Gemini's `box_2d` is [ymin, xmin, ymax, xmax] on a 0-1000 grid over the whole image. */\nconst GRID = 1000;\n\nconst ReaderAnswer = z.object({\n items: z.array(z.object({ kind: z.enum(SUBJECT_KINDS), label: z.string(), box_2d: z.array(z.number()).length(4) })),\n});\n\nconst fraction = (value: number) => Math.min(1, Math.max(0, value / GRID));\n\n/** The reader's answer as boxes; null when it is not the shape asked for (\"not read\", never \"no subject\"). Pure. */\nexport function subjectBoxesFromReader(answer: unknown): SubjectBox[] | null {\n const parsed = ReaderAnswer.safeParse(answer);\n if (!parsed.success) return null;\n return parsed.data.items.map(({ kind, label, box_2d }) => {\n const [ymin = 0, xmin = 0, ymax = 0, xmax = 0] = box_2d;\n return {\n kind,\n label,\n x0: fraction(Math.min(xmin, xmax)),\n y0: fraction(Math.min(ymin, ymax)),\n x1: fraction(Math.max(xmin, xmax)),\n y1: fraction(Math.max(ymin, ymax)),\n };\n });\n}\n\nexport const SUBJECT_BOX_PROMPT = [\n \"Find every person, every face, every animal and every product or object the ad is selling in this image.\",\n \"For each, return: `kind` person, face, animal or product; `label` two or three words naming it; `box_2d` the tight box around all of it as [ymin, xmin, ymax, xmax] on a 0-1000 grid over the whole image.\",\n \"A person is the whole body that is visible, a face is the head from the hair to the chin; a person and their face are two entries. A product is the thing sold or shown in use (a phone, a box, a dish), not furniture or background. Text and logos are not subjects. Nothing of the kind: an empty list.\",\n 'Reply with only this JSON: {\"items\":[{\"kind\":\"person|face|animal|product\",\"label\":\"...\",\"box_2d\":[ymin,xmin,ymax,xmax]}]}',\n].join(\"\\n\");\n\n/** Longest edge the reader is sent; boxes are fractions, so any size reads the same frame. */\nconst READ_EDGE = 1536;\n\nexport type SubjectBoxReading = { status: \"read\"; boxes: SubjectBox[] } | { status: \"not_checked\" };\n\n/**\n * Every subject in `image`, with its box. `not_checked` when no reader could answer (no gateway\n * key, an outage, an answer out of shape, twice): a cut then centres on the plan's subject zone.\n */\nexport async function readSubjectBoxes(\n image: Buffer,\n opts: { onSpend?: (usage: ReviewUsage) => void } = {},\n): Promise<SubjectBoxReading> {\n let jpeg: string;\n try {\n const resized = await sharp(image)\n .resize(READ_EDGE, READ_EDGE, { fit: \"inside\", withoutEnlargement: true })\n .jpeg({ quality: 90 })\n .toBuffer();\n jpeg = resized.toString(\"base64\");\n } catch {\n return { status: \"not_checked\" };\n }\n for (let attempt = 0; attempt < 2; attempt++) {\n const answer = await askAboutImages(SUBJECT_BOX_READER_MODEL, [jpeg], SUBJECT_BOX_PROMPT, opts.onSpend, 60_000, {\n effort: \"minimal\",\n });\n const boxes = subjectBoxesFromReader(answer);\n if (boxes) return { status: \"read\", boxes };\n }\n return { status: \"not_checked\" };\n}\n","/**\n * The cards, panels and buttons a static ad's picture draws for its words: each one flat colour,\n * inside the picture. A size's cut keeps them whole when it can (`subject-crop.ts`): the words\n * model sets the words in them where the picture drew them, so a cut through one cuts the words'\n * card (dev, Oct 2026: Zernio's 4:5 cut the top off the quote card its picture drew empty).\n *\n * Pure: a raw RGB picture in, rectangles as fractions of it out.\n */\nimport type { Raw, Span } from \"./words-layer.ts\";\n\n/** The width a picture is read at: a card is tens of pixels across there, and the read stays cheap. */\nconst READ_WIDTH = 288;\n/** The 5×5 spread of grey (levels) under which the picture is flat there: a card, never a photo's grain. */\nconst FLAT = 2;\n/** How far (levels, each channel) one pixel of a card is from the next: past it, an edge. */\nconst STEP = 3;\n/** The most a card's colour ranges over it (levels, each channel): a soft glow runs on far past it. */\nconst RANGE = 12;\n/** The least of the picture a card covers: a patch smaller holds no line of words. */\nconst MIN_AREA = 0.015;\n/** The least of its box a card fills: a round photo or a divider on it leaves holes, a ring of wall is no card. */\nconst MIN_FILL = 0.6;\n\n/** The mean of channel `c` of `img` over the `f`×`f` block whose corner is (`x`, `y`). */\nfunction blockMean(img: Raw, x: number, y: number, f: number, c: number): number {\n let sum = 0;\n for (let dy = 0; dy < f; dy++) {\n for (let dx = 0; dx < f; dx++) sum += img.data[((y + dy) * img.width + x + dx) * img.channels + c] ?? 0;\n }\n return sum / (f * f);\n}\n\n/** `img` averaged down by `f` on each side, as three channels. */\nfunction shrunk(img: Raw, f: number): Raw {\n const width = Math.floor(img.width / f);\n const height = Math.floor(img.height / f);\n const data = Buffer.alloc(width * height * 3);\n for (let i = 0; i < width * height; i++) {\n const x = i % width;\n const y = (i - x) / width;\n for (let c = 0; c < 3; c++) data[i * 3 + c] = Math.round(blockMean(img, x * f, y * f, f, c));\n }\n return { data, width, height, channels: 3 };\n}\n\n/** The spread (standard deviation) of `grey` over the 5×5 window around (`x`, `y`). */\nfunction spreadAt(grey: Float32Array, width: number, x: number, y: number): number {\n let sum = 0;\n let squares = 0;\n for (let dy = -2; dy <= 2; dy++) {\n for (let dx = -2; dx <= 2; dx++) {\n const v = grey[(y + dy) * width + x + dx] ?? 0;\n sum += v;\n squares += v * v;\n }\n }\n const mean = sum / 25;\n return Math.sqrt(Math.max(0, squares / 25 - mean * mean));\n}\n\n/** Where `img` (three channels) is flat: the 5×5 spread of its grey under `FLAT`; its two-pixel rim is unread. */\nfunction flatOf(img: Raw): Uint8Array {\n const { width, height } = img;\n const grey = new Float32Array(width * height);\n for (let i = 0; i < grey.length; i++)\n grey[i] = 0.299 * (img.data[i * 3] ?? 0) + 0.587 * (img.data[i * 3 + 1] ?? 0) + 0.114 * (img.data[i * 3 + 2] ?? 0);\n const flat = new Uint8Array(width * height);\n for (let y = 2; y < height - 2; y++) {\n for (let x = 2; x < width - 2; x++) flat[y * width + x] = spreadAt(grey, width, x, y) < FLAT ? 1 : 0;\n }\n return flat;\n}\n\n/** What one region of the flat picture is: its box (pixels, inclusive), how many pixels, how far its colour ranges. */\ntype Region = { x0: number; y0: number; x1: number; y1: number; count: number; range: number };\n\n/** A region being grown: its box and count so far, and the lowest and highest of each channel met. */\ntype Growing = Region & { lo: number[]; hi: number[] };\n\n/** Takes pixel `i` (at `x`, `y`) of `img` into `r`. */\nfunction take(r: Growing, img: Raw, i: number, x: number, y: number): void {\n r.count++;\n r.x0 = Math.min(r.x0, x);\n r.x1 = Math.max(r.x1, x);\n r.y0 = Math.min(r.y0, y);\n r.y1 = Math.max(r.y1, y);\n for (let c = 0; c < 3; c++) {\n const v = img.data[i * 3 + c] ?? 0;\n r.lo[c] = Math.min(r.lo[c] ?? 255, v);\n r.hi[c] = Math.max(r.hi[c] ?? 0, v);\n }\n}\n\n/** The four neighbours of pixel `i` (at `x`) inside a `width`×`height` picture. */\nconst neighbours = (i: number, x: number, width: number, height: number): number[] =>\n [x > 0 ? i - 1 : -1, x < width - 1 ? i + 1 : -1, i - width, i + width].filter((j) => j >= 0 && j < width * height);\n\n/** The flat region grown from pixel `seed` through neighbours within `STEP` of each other, labelled in `seen`. */\nfunction regionFrom(img: Raw, flat: Uint8Array, seen: Uint8Array, seed: number): Region {\n const { width, height } = img;\n const r: Growing = { x0: width, y0: height, x1: -1, y1: -1, count: 0, range: 0, lo: [255, 255, 255], hi: [0, 0, 0] };\n const near = (a: number, b: number) =>\n [0, 1, 2].every((c) => Math.abs((img.data[a * 3 + c] ?? 0) - (img.data[b * 3 + c] ?? 0)) <= STEP);\n seen[seed] = 1;\n const stack = [seed];\n for (let i = stack.pop(); i !== undefined; i = stack.pop()) {\n const x = i % width;\n take(r, img, i, x, (i - x) / width);\n for (const j of neighbours(i, x, width, height)) {\n if (!flat[j] || seen[j] || !near(i, j)) continue;\n seen[j] = 1;\n stack.push(j);\n }\n }\n const range = Math.max(...[0, 1, 2].map((c) => (r.hi[c] ?? 0) - (r.lo[c] ?? 0)));\n return { x0: r.x0, y0: r.y0, x1: r.x1, y1: r.y1, count: r.count, range };\n}\n\n/** Whether `r` is a card: inside the picture (a ground the picture runs off is none), large, filled, one colour. */\nfunction isPanel(r: Region, width: number, height: number): boolean {\n // The 5×5 read leaves a two-pixel rim unread: a region reaching it runs off the picture.\n const inside = r.x0 > 2 && r.y0 > 2 && r.x1 < width - 3 && r.y1 < height - 3;\n const box = (r.x1 - r.x0 + 1) * (r.y1 - r.y0 + 1);\n return inside && box >= MIN_AREA * width * height && r.count >= MIN_FILL * box && r.range <= RANGE;\n}\n\n/** The cards, panels and buttons `img` draws (fractions of it), largest first. Pure. */\nexport function platePanels(img: Raw): Span[] {\n const f = Math.max(1, Math.round(img.width / READ_WIDTH));\n const small = f > 1 || img.channels !== 3 ? shrunk(img, f) : img;\n const flat = flatOf(small);\n const seen = new Uint8Array(flat.length);\n const panels: Array<Span & { area: number }> = [];\n for (let i = 0; i < flat.length; i++) {\n if (!flat[i] || seen[i]) continue;\n const r = regionFrom(small, flat, seen, i);\n if (!isPanel(r, small.width, small.height)) continue;\n panels.push({\n x0: r.x0 / small.width,\n y0: r.y0 / small.height,\n x1: (r.x1 + 1) / small.width,\n y1: (r.y1 + 1) / small.height,\n area: (r.x1 - r.x0 + 1) * (r.y1 - r.y0 + 1),\n });\n }\n return panels.sort((a, b) => b.area - a.area).map(({ area: _area, ...span }) => span);\n}\n","/**\n * Where a size is cut from a static ad's picture: the largest crop of the size's shape, at one\n * scale, placed so every face, animal and product stays whole and a person is cut only at the\n * bottom (feet before heads). Pure: sizes and boxes in, pixel rectangles out.\n *\n * The words model renders only its own ratios (GPT has no 4:5), so the cut also names the\n * smallest `render` rectangle of one of those ratios that holds the size: the model is shown\n * that, and the size is cut back out of what it returns.\n */\nimport type { SubjectBox } from \"./subject-boxes.ts\";\n\nexport type Size = { width: number; height: number };\nexport type PixelRect = { x: number; y: number; width: number; height: number };\n/** A rectangle as fractions of the frame, origin top-left. */\nexport type Span = { x0: number; y0: number; x1: number; y1: number };\n\nexport type SubjectCrop = {\n /** The size's crop of the picture, in its pixels. */\n rect: PixelRect;\n /** The rectangle the words model is shown: `rect` or a larger one of a ratio it renders, holding `rect`. */\n render: PixelRect & { ratio: string };\n /** False when no crop keeps every face, animal, product and the top of every person. */\n fits: boolean;\n /** The labels of what the crop cuts that must stay whole. */\n cut: string[];\n};\n\n/** Room kept around what must stay whole, as a share of the picture's side: a head never touches the edge. */\nconst SUBJECT_PAD = 0.02;\n\nfunction ratioOf(ratio: string): number {\n const [w, h] = ratio.split(\":\").map(Number);\n if (!w || !h || !Number.isFinite(w) || !Number.isFinite(h)) throw new Error(`not a W:H ratio: \"${ratio}\"`);\n return w / h;\n}\n\ntype Interval = { from: number; to: number };\n\nconst unionOf = (spans: readonly Interval[]): Interval | null =>\n spans.length === 0 ? null : { from: Math.min(...spans.map((s) => s.from)), to: Math.max(...spans.map((s) => s.to)) };\n\n/**\n * One axis: where a window of `length` starts in `full`, keeping `hard` inside it (padded when it\n * can be), the whole `soft` span when it fits and otherwise its start (what is lost goes at the\n * end: the feet). With nothing to keep it centres on `core`.\n */\nfunction placeAxis(\n full: number,\n length: number,\n hard: Interval | null,\n soft: Interval | null,\n core: Interval,\n): { at: number; fits: boolean } {\n const clampFull = (v: number) => Math.min(full - length, Math.max(0, v));\n const want = soft\n ? soft.to - soft.from <= length\n ? (soft.from + soft.to) / 2 - length / 2\n : soft.from - SUBJECT_PAD * full\n : (core.from + core.to) / 2 - length / 2;\n if (!hard) return { at: Math.round(clampFull(want)), fits: true };\n const pad = SUBJECT_PAD * full;\n for (const p of [pad, 0]) {\n const lo = Math.max(0, hard.to + p - length);\n const hi = Math.min(full - length, hard.from - p);\n if (lo <= hi + 1e-6) return { at: Math.round(Math.min(hi, Math.max(lo, want))), fits: true };\n }\n return { at: Math.round(clampFull((hard.from + hard.to) / 2 - length / 2)), fits: false };\n}\n\n/**\n * The size `format` cut from a picture of `plate` pixels around `subjects` (null or empty: centred\n * on `core`, the plan's subject zone, or the middle), and around the cards the picture draws for its\n * words (`panels`, fractions: `plate-panels.ts`) when a cut can keep them whole too; a card is never\n * what refuses a size. `renderRatios` are the ratios the words model renders; without them the render\n * rectangle is the crop.\n */\nexport function subjectCrop(\n plate: Size,\n format: string,\n subjects: readonly SubjectBox[] | null,\n opts: { core?: Span; renderRatios?: readonly string[]; panels?: readonly Span[] } = {},\n): SubjectCrop {\n const cards = (opts.panels ?? []).map((p): SubjectBox => ({ kind: \"product\", label: \"card\", ...p }));\n if (cards.length > 0) {\n const withCards = cropAround(plate, format, [...(subjects ?? []), ...cards], opts);\n if (withCards.fits) return withCards;\n }\n return cropAround(plate, format, subjects, opts);\n}\n\nfunction cropAround(\n plate: Size,\n format: string,\n subjects: readonly SubjectBox[] | null,\n opts: { core?: Span; renderRatios?: readonly string[] },\n): SubjectCrop {\n const r = ratioOf(format);\n let width = plate.width;\n let height = Math.round(plate.width / r);\n if (height > plate.height) {\n height = plate.height;\n width = Math.round(plate.height * r);\n }\n const boxes = subjects ?? [];\n const px = (b: SubjectBox): Interval => ({ from: b.x0 * plate.width, to: b.x1 * plate.width });\n const py = (b: SubjectBox): Interval => ({ from: b.y0 * plate.height, to: b.y1 * plate.height });\n // A person may lose their feet, never their head: only the top of their box must stay.\n const hardY = boxes.map((b) => (b.kind === \"person\" ? { from: py(b).from, to: py(b).from } : py(b)));\n const core = opts.core ?? { x0: 0, y0: 0, x1: 1, y1: 1 };\n const x = placeAxis(plate.width, width, unionOf(boxes.map(px)), unionOf(boxes.map(px)), {\n from: core.x0 * plate.width,\n to: core.x1 * plate.width,\n });\n const y = placeAxis(plate.height, height, unionOf(hardY), unionOf(boxes.map(py)), {\n from: core.y0 * plate.height,\n to: core.y1 * plate.height,\n });\n const rect = { x: x.at, y: y.at, width, height };\n const cut = boxes\n .filter((b, i) => {\n const hy = hardY[i] ?? py(b);\n return (\n px(b).from < rect.x - 0.5 ||\n px(b).to > rect.x + rect.width + 0.5 ||\n hy.from < rect.y - 0.5 ||\n hy.to > rect.y + rect.height + 0.5\n );\n })\n .map((b) => b.label);\n return { rect, render: renderRect(plate, rect, format, opts.renderRatios), fits: cut.length === 0, cut };\n}\n\n/**\n * The smallest rectangle of one of `ratios` that holds `rect` inside the picture, centred on it;\n * `rect` itself when its own ratio renders, when no ratio is given, or when none fits.\n */\nfunction renderRect(\n plate: Size,\n rect: PixelRect,\n format: string,\n ratios: readonly string[] | undefined,\n): PixelRect & { ratio: string } {\n if (!ratios || ratios.includes(format)) return { ...rect, ratio: format };\n const r = rect.width / rect.height;\n let best: (PixelRect & { ratio: string }) | null = null;\n for (const ratio of ratios) {\n const c = ratioOf(ratio);\n const width = c <= r ? rect.width : Math.round(rect.height * c);\n const height = c <= r ? Math.round(rect.width / c) : rect.height;\n if (width > plate.width || height > plate.height) continue;\n const place = (from: number, length: number, inner: number, full: number) =>\n Math.min(\n Math.min(from, full - length),\n Math.max(Math.max(0, from + inner - length), from - (length - inner) / 2),\n );\n const candidate = {\n x: Math.round(place(rect.x, width, rect.width, plate.width)),\n y: Math.round(place(rect.y, height, rect.height, plate.height)),\n width,\n height,\n ratio,\n };\n if (!best || width * height < best.width * best.height) best = candidate;\n }\n return best ?? { ...rect, ratio: format };\n}\n","/**\n * What was read off a picture, kept with it while it lives.\n *\n * A size's cut is judged against every render the words model makes for it, and a render refused\n * whole is lined up again to lift its words: the same reading of the same pixels, each time. The\n * pictures are never written to, so a reading is kept by the picture's identity and dropped with it.\n */\n\nconst ids = new WeakMap<object, number>();\nlet nextId = 0;\n\n/** A number standing for `picture` while it lives: the same picture, the same number. */\nexport function pictureId(picture: object): number {\n const known = ids.get(picture);\n if (known !== undefined) return known;\n const id = nextId++;\n ids.set(picture, id);\n return id;\n}\n\n/** A reading kept per picture and per `what` (everything else it depends on, spelled out). */\nexport function remembered<V>(): (picture: object, what: string, read: () => V) => V {\n const readings = new WeakMap<object, Map<string, V>>();\n return (picture, what, read) => {\n const known = readings.get(picture) ?? new Map<string, V>();\n readings.set(picture, known);\n const kept = known.get(what);\n if (kept !== undefined) return kept;\n const value = read();\n known.set(what, value);\n return value;\n };\n}\n","/**\n * The band or card a block of words sits on, as the words model laid it over the picture, and\n * that band moved with its words.\n *\n * Words the size's frame cuts or its app covers are moved by code on the words render\n * (`whole-render.ts`). Lifted off alone, words on a band left the band in pieces and the picture\n * showing through it (dev, Oct 2026). So a block on a band moves with its band, whole: where the\n * band was shows the picture again, or, along an edge of the frame the band ran to, more of the\n * band in its own look.\n *\n * Pure: raw RGB buffers and fractions in, buffers and fractions out.\n */\nimport type { Raw, Span } from \"./words-layer.ts\";\n\n/** How far around a block of words its ground is read, as a share of the frame's side. */\nconst GROUND_REACH = 0.06;\n/** A grey difference (levels) past which the render laid something over the picture there. */\nconst LAID = 24;\n/** A line of pixels laid over the picture past this share still runs across the band. */\nconst BAND_EDGE = 0.5;\n/** Past a band's edge the picture shows again at once: laid under this share (a soft glow fades out over it). */\nconst BAND_CLEAR = 0.1;\n/** How much of a band, card or pill is laid over the picture: a line of words alone covers far less of its box. */\nconst SOLID = 0.7;\n/** How deep past a band's edge the picture must show, as a share of the frame's longer side. */\nconst RING = 0.01;\n/** How deep a strip of the band along the edge it leaves shows its look, as a share of its depth. */\nconst LOOK_STRIP = 0.1;\n\n/** Where the render (lined up with the cut) laid something over the picture: 1 a pixel. */\nexport type LaidMap = { laid: Uint8Array; width: number; height: number };\n\n/** A half-open rectangle of pixels. */\ntype Rect = { x0: number; y0: number; x1: number; y1: number };\n\nconst greyAt = (img: Raw, i: number) =>\n 0.299 * (img.data[i * img.channels] ?? 0) +\n 0.587 * (img.data[i * img.channels + 1] ?? 0) +\n 0.114 * (img.data[i * img.channels + 2] ?? 0);\n\n/**\n * Where `aligned` is not `cut` in plain grey, no light taken out (a frosted band reads as light\n * otherwise): what the render laid over the picture. Pure.\n */\nexport function laidMap(aligned: Raw, cut: Raw): LaidMap {\n const { width, height } = cut;\n const laid = new Uint8Array(width * height);\n for (let i = 0; i < laid.length; i++) laid[i] = Math.abs(greyAt(aligned, i) - greyAt(cut, i)) > LAID ? 1 : 0;\n return { laid, width, height };\n}\n\nconst rectOf = (s: Span, width: number, height: number): Rect => ({\n x0: Math.floor(s.x0 * width),\n y0: Math.floor(s.y0 * height),\n x1: Math.ceil(s.x1 * width),\n y1: Math.ceil(s.y1 * height),\n});\n\n/** `r` inside a `width`×`height` frame. */\nconst clipped = (r: Rect, width: number, height: number): Rect => ({\n x0: Math.max(0, r.x0),\n y0: Math.max(0, r.y0),\n x1: Math.min(width, r.x1),\n y1: Math.min(height, r.y1),\n});\n\nconst holds = (r: Rect, x: number, y: number) => x >= r.x0 && x < r.x1 && y >= r.y0 && y < r.y1;\n\n/** How many pixels of `r` (inside the frame) are laid, of how many. */\nfunction laidIn(m: LaidMap, r: Rect): { laid: number; area: number } {\n const c = clipped(r, m.width, m.height);\n let laid = 0;\n for (let y = c.y0; y < c.y1; y++) for (let x = c.x0; x < c.x1; x++) laid += m.laid[y * m.width + x] ?? 0;\n return { laid, area: Math.max(0, c.x1 - c.x0) * Math.max(0, c.y1 - c.y0) };\n}\n\n/** The share of `r` laid over the picture; 0 for a rectangle outside the frame. */\nfunction share(m: LaidMap, r: Rect): number {\n const { laid, area } = laidIn(m, r);\n return area > 0 ? laid / area : 0;\n}\n\n/**\n * The share of the ring around the block `box` (fractions), out to `GROUND_REACH` past it, the\n * render laid something over: high for words on a band or card (opaque or frosted), a few\n * hundredths for words on a soft glow, none for words set on the picture itself. Pure.\n */\nexport function laidAround(m: LaidMap, box: Span): number {\n const reach = {\n x0: box.x0 - GROUND_REACH,\n y0: box.y0 - GROUND_REACH,\n x1: box.x1 + GROUND_REACH,\n y1: box.y1 + GROUND_REACH,\n };\n const outer = laidIn(m, rectOf(reach, m.width, m.height));\n const inner = laidIn(m, rectOf(box, m.width, m.height));\n const ring = outer.area - inner.area;\n return ring > 0 ? (outer.laid - inner.laid) / ring : 0;\n}\n\n/** The line of pixels just past side `side` of `r`, `depth` deep. */\nfunction past(r: Rect, side: number, depth: number): Rect {\n if (side === 0) return { ...r, y0: r.y0 - depth, y1: r.y0 };\n if (side === 1) return { ...r, y0: r.y1, y1: r.y1 + depth };\n if (side === 2) return { ...r, x0: r.x0 - depth, x1: r.x0 };\n return { ...r, x0: r.x1, x1: r.x1 + depth };\n}\n\n/** `r` one pixel larger on `side`. */\nfunction grown(r: Rect, side: number): Rect {\n if (side === 0) return { ...r, y0: r.y0 - 1 };\n if (side === 1) return { ...r, y1: r.y1 + 1 };\n if (side === 2) return { ...r, x0: r.x0 - 1 };\n return { ...r, x1: r.x1 + 1 };\n}\n\nconst atFrameEdge = (m: LaidMap, r: Rect, side: number) =>\n side === 0 ? r.y0 <= 0 : side === 1 ? r.y1 >= m.height : side === 2 ? r.x0 <= 0 : r.x1 >= m.width;\n\n/**\n * The band, card or pill (fractions) the block `box` sits on: grown out of the block while the\n * line past each side is laid over the picture. Null when nothing surrounds the block (words set\n * on the picture itself: no side grew short of the frame's edge), or when the picture does not\n * show again past every edge inside the frame, as nobody can tell where the band ends. Pure.\n */\nexport function bandUnder(m: LaidMap, box: Span): Span | null {\n const block = clipped(rectOf(box, m.width, m.height), m.width, m.height);\n // Grown from the middle of the line: a button's box is drawn past its words, and can reach past its pill.\n const inset = Math.min(Math.floor((block.y1 - block.y0) / 4), Math.floor((block.x1 - block.x0 - 1) / 2));\n const start = { x0: block.x0 + inset, y0: block.y0 + inset, x1: block.x1 - inset, y1: block.y1 - inset };\n let r = start;\n for (let grew = true; grew; ) {\n grew = false;\n for (let side = 0; side < 4; side++) {\n if (atFrameEdge(m, r, side) || share(m, past(r, side, 1)) < BAND_EDGE) continue;\n r = grown(r, side);\n grew = true;\n }\n }\n const outgrown = [r.y0 < start.y0, r.y1 > start.y1, r.x0 < start.x0, r.x1 > start.x1];\n const depth = Math.max(2, Math.round(RING * Math.max(m.width, m.height)));\n for (let side = 0; side < 4; side++) {\n if (!(outgrown[side] || atFrameEdge(m, r, side)) || share(m, past(r, side, depth)) >= BAND_CLEAR) return null;\n }\n // A line of words alone covers far less of its box than a band, card or pill does.\n if (share(m, r) < SOLID) return null;\n return { x0: r.x0 / m.width, y0: r.y0 / m.height, x1: r.x1 / m.width, y1: r.y1 / m.height };\n}\n\n/** A band (fractions of the render), how far it moves (fractions), and the lines it carries. */\nexport type BandMove = { band: Span; dx: number; dy: number; words: readonly Span[] };\n\n/** What a band is moved on: the render lined up, the cut, and the size so far. */\nexport type BandGround = { aligned: Raw; cut: Raw; out: Raw };\n\n/** A band's look on one channel, as a tone of the picture under it: `a` times the picture plus `b`. */\ntype Tone = { a: number; b: number };\n\n/** Sums for a line fit of the render's channel `ch` on the picture's, over `strip` outside `skip`. */\nfunction sumsOf(g: BandGround, strip: Rect, skip: readonly Rect[], ch: number) {\n const { width } = g.cut;\n const sums = { n: 0, x: 0, y: 0, xx: 0, xy: 0 };\n for (let y = strip.y0; y < strip.y1; y++) {\n for (let x = strip.x0; x < strip.x1; x++) {\n if (skip.some((r) => holds(r, x, y))) continue;\n const i = y * width + x;\n const u = g.cut.data[i * g.cut.channels + ch] ?? 0;\n const v = g.aligned.data[i * g.aligned.channels + ch] ?? 0;\n sums.n++;\n sums.x += u;\n sums.y += v;\n sums.xx += u * u;\n sums.xy += u * v;\n }\n }\n return sums;\n}\n\n/**\n * The tone that best gives the band's pixels in `strip` from the picture's under them (least\n * squares, per channel), its words (`skip`) left out: flat for a solid band, a faint picture for a\n * frosted one.\n */\nfunction toneOf(g: BandGround, strip: Rect, skip: readonly Rect[]): Tone[] {\n const c = clipped(strip, g.cut.width, g.cut.height);\n return [0, 1, 2].map((ch) => {\n const s = sumsOf(g, c, skip, ch);\n if (s.n === 0) return { a: 0, b: 0 };\n const spread = s.xx - (s.x * s.x) / s.n;\n const a = spread > s.n ? Math.min(1, Math.max(0, (s.xy - (s.x * s.y) / s.n) / spread)) : 0;\n return { a, b: (s.y - a * s.x) / s.n };\n });\n}\n\n/** How deep past a band the render's light is read, as a share of the frame's height. */\nconst LIGHT_DEPTH = 0.02;\n\n/** The picture just past `r` on the side it leaves when it moves by (`dx`, `dy`) pixels. */\nfunction ringPast(r: Rect, dx: number, dy: number, depth: number): Rect {\n if (dy < 0) return { ...r, y0: r.y1, y1: r.y1 + depth };\n if (dy > 0) return { ...r, y0: r.y0 - depth, y1: r.y0 };\n if (dx < 0) return { ...r, x0: r.x1, x1: r.x1 + depth };\n return { ...r, x0: r.x0 - depth, x1: r.x0 };\n}\n\n/**\n * The render's light over the picture's on `ring`, per channel (the median ratio): read on the\n * picture beside a band, since under it the band is all there is to read.\n */\nfunction lightOn(g: BandGround, ring: Rect): number[] {\n const { width, height } = g.cut;\n const c = clipped(ring, width, height);\n return [0, 1, 2].map((ch) => {\n const ratios: number[] = [];\n for (let y = c.y0; y < c.y1; y++) {\n for (let x = c.x0; x < c.x1; x++) {\n const i = y * width + x;\n const under = g.cut.data[i * g.cut.channels + ch] ?? 0;\n if (under >= 16) ratios.push((g.aligned.data[i * g.aligned.channels + ch] ?? 0) / under);\n }\n }\n ratios.sort((a, b) => a - b);\n return Math.min(2, Math.max(0.5, ratios[Math.floor(ratios.length / 2)] ?? 1));\n });\n}\n\n/**\n * Along the side the band leaves when it moves by (`dx`, `dy`) pixels, when it ran to the frame's\n * edge there across the whole frame: `strip`, the band's own pixels along that edge, whose look is\n * laid on `zone`, what it leaves. Null when the band leaves no edge of the frame behind.\n */\nfunction edgeLeft(r: Rect, dx: number, dy: number, width: number, height: number): { strip: Rect; zone: Rect } | null {\n const deep = Math.max(1, Math.round(LOOK_STRIP * (r.y1 - r.y0)));\n const wide = Math.max(1, Math.round(LOOK_STRIP * (r.x1 - r.x0)));\n // Two pixels short of the edge is on it: the band is found on half the pixels. A card the frame\n // cut is no band running off it: where it was shows the picture.\n const across = r.x0 <= 2 && r.x1 >= width - 2;\n const down = r.y0 <= 2 && r.y1 >= height - 2;\n if (dy < 0 && across && r.y1 >= height - 2)\n return { strip: { ...r, y0: r.y1 - deep }, zone: { ...r, y0: r.y1 + dy } };\n if (dy > 0 && across && r.y0 <= 2) return { strip: { ...r, y1: r.y0 + deep }, zone: { ...r, y1: r.y0 + dy } };\n if (dx < 0 && down && r.x1 >= width - 2) return { strip: { ...r, x0: r.x1 - wide }, zone: { ...r, x0: r.x1 + dx } };\n if (dx > 0 && down && r.x0 <= 2) return { strip: { ...r, x1: r.x0 + wide }, zone: { ...r, x1: r.x0 + dx } };\n return null;\n}\n\n/** How far into a band's corner its rounding is looked for, as a share of its shorter side. */\nconst CORNER = 0.5;\n\n/** A corner of a band's box: where it is (box pixels), which way the box runs from it, and whether it can be rounded. */\ntype Corner = { x: number; y: number; sx: number; sy: number; open: boolean };\n\n/** Takes out of `shape` (`w` wide) the bare pixels (`bare`) reached from corner `c`, within `reach` of it. */\nfunction floodCorner(shape: Uint8Array, w: number, c: Corner, reach: number, bare: (x: number, y: number) => boolean) {\n const near = (x: number, y: number) =>\n (x - c.x) * c.sx >= 0 && (x - c.x) * c.sx < reach && (y - c.y) * c.sy >= 0 && (y - c.y) * c.sy < reach;\n shape[c.y * w + c.x] = 0;\n const stack = [c.y * w + c.x];\n for (let at = stack.pop(); at !== undefined; at = stack.pop()) {\n const x = at % w;\n const y = (at - x) / w;\n for (const [nx, ny] of [\n [x + 1, y],\n [x - 1, y],\n [x, y + 1],\n [x, y - 1],\n ] as const) {\n if (!near(nx, ny) || shape[ny * w + nx] === 0 || !bare(nx, ny)) continue;\n shape[ny * w + nx] = 0;\n stack.push(ny * w + nx);\n }\n }\n}\n\n/**\n * Which pixels of `r` (1 a pixel, row by row) are the band: all but what its rounded corners leave\n * of the picture, the pixels the render laid nothing over reached from a corner without crossing\n * the band. A corner on the frame's edge is no corner: the band runs on past it.\n */\nfunction shapeOf(g: BandGround, r: Rect): Uint8Array {\n const w = r.x1 - r.x0;\n const h = r.y1 - r.y0;\n const shape = new Uint8Array(Math.max(0, w * h)).fill(1);\n if (w <= 0 || h <= 0) return shape;\n const reach = Math.floor(CORNER * Math.min(w, h));\n const bare = (x: number, y: number) => {\n const i = (r.y0 + y) * g.cut.width + r.x0 + x;\n return Math.abs(greyAt(g.aligned, i) - greyAt(g.cut, i)) <= LAID;\n };\n const corners: Corner[] = [\n { x: 0, y: 0, sx: 1, sy: 1, open: r.x0 > 0 && r.y0 > 0 },\n { x: w - 1, y: 0, sx: -1, sy: 1, open: r.x1 < g.cut.width && r.y0 > 0 },\n { x: 0, y: h - 1, sx: 1, sy: -1, open: r.x0 > 0 && r.y1 < g.cut.height },\n { x: w - 1, y: h - 1, sx: -1, sy: -1, open: r.x1 < g.cut.width && r.y1 < g.cut.height },\n ];\n for (const c of corners) if (c.open && bare(c.x, c.y)) floodCorner(shape, w, c, reach, bare);\n return shape;\n}\n\n/** Each pixel (`x`, `y`) of `r` that `shape` marks as the band. */\nfunction eachOf(r: Rect, shape: Uint8Array, at: (x: number, y: number) => void): void {\n const w = r.x1 - r.x0;\n for (let k = 0; k < shape.length; k++) if (shape[k]) at(r.x0 + (k % w), r.y0 + Math.floor(k / w));\n}\n\n/** How far past a band's box its soft edge reaches (the antialiased line the box stops short of), as a share of the frame's longer side. */\nconst SOFT_EDGE = 0.003;\n\n/** Each pixel (`x`, `y`) of `r`. */\nfunction eachIn(r: Rect, at: (x: number, y: number) => void): void {\n for (let y = r.y0; y < r.y1; y++) for (let x = r.x0; x < r.x1; x++) at(x, y);\n}\n\n/**\n * `g.out` with the band `move.band` moved by (`move.dx`, `move.dy`), the words on it with it: the\n * band's pixels are the render's (its rounded corners leave the picture beside them where it is,\n * `shapeOf`), and where it was and is no longer, its soft edge and corners included, shows the\n * picture under it in the render's light read beside it (`lightOn`), or, when the band ran to an\n * edge of the frame it now leaves, more of the band in its own look (a tone of the picture under it,\n * so a frosted band stays frosted). Pure.\n */\nexport function moveBand(g: BandGround, move: BandMove): Raw {\n const { width, height } = g.cut;\n const r = clipped(rectOf(move.band, width, height), width, height);\n const soft = Math.max(1, Math.round(SOFT_EDGE * Math.max(width, height)));\n const left = clipped({ x0: r.x0 - soft, y0: r.y0 - soft, x1: r.x1 + soft, y1: r.y1 + soft }, width, height);\n const dx = Math.round(move.dx * width);\n const dy = Math.round(move.dy * height);\n const data = Buffer.alloc(width * height * 3);\n if (g.out.channels === 3) g.out.data.copy(data, 0, 0, width * height * 3);\n else\n for (let i = 0; i < width * height; i++) g.out.data.copy(data, i * 3, i * g.out.channels, i * g.out.channels + 3);\n const shape = shapeOf(g, r);\n const edge = edgeLeft(r, dx, dy, width, height);\n const tone = edge\n ? toneOf(\n g,\n edge.strip,\n move.words.map((w) => rectOf(w, width, height)),\n )\n : [];\n const light = lightOn(g, ringPast(left, dx, dy, Math.max(4, Math.round(LIGHT_DEPTH * height))));\n eachIn(left, (x, y) => {\n const i = y * width + x;\n const band = edge !== null && holds(edge.zone, x, y);\n for (let ch = 0; ch < 3; ch++) {\n const under = g.cut.data[i * g.cut.channels + ch] ?? 0;\n const t = tone[ch] ?? { a: 0, b: 0 };\n const v = band ? t.a * under + t.b : under * (light[ch] ?? 1);\n data[i * 3 + ch] = Math.max(0, Math.min(255, Math.round(v)));\n }\n });\n eachOf(r, shape, (x, y) => {\n const to = { x: x + dx, y: y + dy };\n if (to.x < 0 || to.y < 0 || to.x >= width || to.y >= height) return;\n const from = y * width + x;\n g.aligned.data.copy(data, (to.y * width + to.x) * 3, from * g.aligned.channels, from * g.aligned.channels + 3);\n });\n return { data, width, height, channels: 3 };\n}\n","/**\n * The correction that brings a finished 9:16's words and logo inside the band Stories and\n * Reels leave clear, without asking the image model again: shrink the whole picture a little\n * and shift it, then carry its plain edge into the uncovered margin (never a busy one).\n *\n * Why here and not in a re-render: the image model cannot move an element by a few points on\n * request (a `--fix` asking for \"8% up\" moved it about 1%), and agents looped 2-17 renders on\n * it. `planSafeFit` is pure; `fitPicture` only transforms bytes.\n */\nimport sharp from \"sharp\";\nimport {\n blockingArea,\n blockingPlacements,\n type RightRail,\n type SafeArea,\n} from \"../../../scaffold/platform-safe-area.ts\";\nimport { bandViolations, FRAME_CUT } from \"./band-check.ts\";\nimport {\n boxesOfLine,\n buttonShape,\n type CopyLine,\n isButtonLine,\n roleKey,\n shownBoxes,\n withWordmark,\n} from \"./must-show.ts\";\nimport type { TextBox } from \"./text-boxes.ts\";\n\n/**\n * How far inside the band the fit aims, on every side: the reader draws its boxes a little\n * differently on each read, and the run review reads the fitted picture again.\n */\nexport const FIT_HEADROOM = 0.01;\n\n/**\n * The smallest scale a fit takes. Measured on the 20 cached bench 9:16s: a shrink to 0.85 or\n * more, its margin filled from the picture's own edge under a feathered seam, still looked like\n * the picture as rendered; below it the filled edges show. 19 of 20 cleared\n * the Reels band at 0.82 or more, most at 0.93 or more.\n */\nexport const MIN_FIT_SCALE = 0.85;\n\n/**\n * The smallest scale a fit takes on a flat ground (`minFitScale`). Prod, Oct 2026: of 40 9:16s in\n * one Session, 33 needed more than `MIN_FIT_SCALE`; flat-cream ones laid out from 12% to 94% of the\n * height cleared Reels at 0.70, their margins carried from the edge the ad's own ground with no\n * seam to see. 0.65 leaves room for the reader drawing its boxes a little looser on another read.\n */\nexport const MIN_FLAT_FIT_SCALE = 0.65;\n\n/** Where the shrunk picture goes: its scale, and its top-left corner as fractions of the frame. */\nexport type SafeFit = { scale: number; x: number; y: number };\n\n/**\n * The boxes a fit moves the ad for. Given the ad's copy, only its logo and the copy that must be\n * seen (`must-show.ts`): never what the scene prints, a line printed again in it, or a supporting\n * line an interface covers (one the frame cuts is placed). Without it (a canvas from before), every box read.\n */\nexport function boxesToPlace(\n boxes: readonly TextBox[],\n format: string,\n opts: { placements?: readonly string[]; copy?: readonly CopyLine[] } = {},\n): TextBox[] {\n if (!opts.copy) return [...boxes];\n const placements = blockingPlacements(opts.placements);\n const past = (box: TextBox) => bandViolations([box], format, { placements })[0];\n // A supporting line the frame cuts is lost all the same: the review blocks it, so it is placed.\n const cut = (box: TextBox) => (past(box)?.clearance ?? 1) <= FRAME_CUT;\n const logoWords = opts.copy.filter((l) => roleKey(l.role) === \"logo\").map((l) => l.text);\n const read = withWordmark(boxes, logoWords);\n // A button is placed by its shape, as the review judges it: its words alone can stand clear of an edge it sits on.\n const buttons = new Set(opts.copy.filter(isButtonLine).flatMap((line) => boxesOfLine(line, read)));\n return shownBoxes(read, opts.copy, (box) => !past(box))\n .filter((shown) => !shown.supporting || cut(shown.box))\n .map((shown) => (buttons.has(shown.box) ? buttonShape(shown.box) : shown.box));\n}\n\n/**\n * Where a fit lands the boxes: inside what the placements' interfaces really draw over (`covered`,\n * Reels' buttons included), the line the review blocks at, and the band's margin at the sides. A\n * feed size, which nothing covers, keeps its band.\n */\nfunction targetArea(format: string, placements?: readonly string[]): SafeArea & { rail?: RightRail } {\n const area = blockingArea(format, placements);\n const covered = area.covered;\n if (!covered) return area;\n return { ...area, top: covered.top, bottom: covered.bottom, ...(covered.rail ? { rail: covered.rail } : {}) };\n}\n\n/**\n * The fit that clears `format`'s band for `placements`, or null when nothing reaches past it or\n * clearing it would take a shrink below `minScale` (`MIN_FIT_SCALE` unless given: a fit whose\n * margins are painted, not carried from the edge, may go further).\n */\nexport function planSafeFit(\n boxes: readonly TextBox[],\n format: string,\n opts: { placements?: readonly string[]; minScale?: number; contain?: boolean } = {},\n): SafeFit | null {\n const area = targetArea(format, opts.placements);\n // Checked as the review checks it: only what an interface draws over, or the frame cuts, blocks.\n const violations = bandViolations(boxes, format, { placements: blockingPlacements(opts.placements) });\n if (!violations.some((v) => v.covered || v.clearance <= FRAME_CUT)) return null;\n // A line that reaches down beside the buttons keeps clear of them: the whole picture is fitted inside.\n const rail = area.rail && boxes.some((b) => b.y1 > (area.rail?.from ?? 1)) ? area.rail.width : 0;\n const union = {\n x0: Math.min(...boxes.map((b) => b.x0)),\n y0: Math.min(...boxes.map((b) => b.y0)),\n x1: Math.max(...boxes.map((b) => b.x1)),\n y1: Math.max(...boxes.map((b) => b.y1)),\n };\n const band = {\n x0: area.left + FIT_HEADROOM,\n y0: area.top + FIT_HEADROOM,\n x1: 1 - Math.max(area.right, rail) - FIT_HEADROOM,\n y1: 1 - area.bottom - FIT_HEADROOM,\n };\n const scale = Math.min(1, (band.y1 - band.y0) / (union.y1 - union.y0), (band.x1 - band.x0) / (union.x1 - union.x0));\n if (opts.contain) return containedFit(union, band, opts.minScale ?? MIN_FIT_SCALE, scale);\n if (scale < (opts.minScale ?? MIN_FIT_SCALE)) return null;\n return {\n scale,\n x: offset(scale, union.x0, union.x1, band.x0, band.x1),\n y: offset(scale, union.y0, union.y1, band.y0, band.y1),\n };\n}\n\n/** How finely `containedFit` steps the scale down. */\nconst CONTAIN_STEP = 0.005;\n\ntype Span = { x0: number; y0: number; x1: number; y1: number };\n\n/**\n * The largest fit, from `from` down to `minScale`, that lands the boxes' `union` inside `band`\n * with the whole picture inside the frame: nothing of it shifted off an edge, its margins all\n * painted. Each axis starts where the picture moves least from where it was. Null when none does.\n */\nfunction containedFit(union: Span, band: Span, minScale: number, from: number): SafeFit | null {\n const start = (scale: number, lo0: number, hi0: number, b0: number, b1: number): number | null => {\n const lo = Math.max(0, b0 - scale * lo0);\n const hi = Math.min(1 - scale, b1 - scale * hi0);\n if (lo > hi + 1e-9) return null;\n // Anchored where it was when it can be (an edge-to-edge picture keeps its top), else nearest.\n return Math.min(hi, Math.max(lo, 0));\n };\n for (let scale = Math.min(1, from); scale >= minScale - 1e-9; scale -= CONTAIN_STEP) {\n const x = start(scale, union.x0, union.x1, band.x0, band.x1);\n const y = start(scale, union.y0, union.y1, band.y0, band.y1);\n if (x !== null && y !== null) {\n // Centred across: a picture shrunk on both sides reads as the same picture, not pushed aside.\n const cx = Math.min(\n Math.min(1 - scale, band.x1 - scale * union.x1),\n Math.max(Math.max(0, band.x0 - scale * union.x0), (1 - scale) / 2),\n );\n return { scale, x: cx, y };\n }\n }\n return null;\n}\n\n/**\n * Where the shrunk picture starts on one axis: centred, unless that leaves the boxes' span\n * outside the band, then the nearest start that puts it inside (the middle of the range when\n * no start does).\n */\nfunction offset(scale: number, from: number, to: number, bandFrom: number, bandTo: number): number {\n const lo = bandFrom - scale * from;\n const hi = bandTo - scale * to;\n if (lo > hi) return (lo + hi) / 2;\n return Math.min(hi, Math.max(lo, (1 - scale) / 2));\n}\n\n/** How deep into the picture an edge must stay the same to be carried on, as a share of the frame's side. */\nconst PLAIN_DEPTH = 0.03;\n/** The most a pixel may differ from the one at the edge, over that depth, summed over its channels. */\nconst PLAIN_DEPTH_STEP = 36;\n/** A jump along the edge this large (summed over channels) is one thing's border crossing it. */\nconst PLAIN_JUMP = 60;\n/** The most borders an edge may cross and still read as plain ground: a two-tone split, never a row of cards. */\nconst PLAIN_JUMPS = 2;\n\nexport type Raw = { data: Buffer; width: number; height: number; channels: number };\n\ntype Side = \"top\" | \"bottom\" | \"left\" | \"right\";\n\n/**\n * How many borders cross the picture's `side`, or null when it does not look the same\n * `PLAIN_DEPTH` in as at the edge. Pure.\n */\nfunction edgeBorders(img: Raw, side: Side): number | null {\n const along = side === \"top\" || side === \"bottom\" ? img.width : img.height;\n const across = side === \"top\" || side === \"bottom\" ? img.height : img.width;\n const depth = Math.max(1, Math.round(PLAIN_DEPTH * across));\n const at = (i: number, d: number) => {\n const inward = side === \"top\" || side === \"left\" ? d : across - 1 - d;\n const [x, y] = side === \"top\" || side === \"bottom\" ? [i, inward] : [inward, i];\n return (y * img.width + x) * img.channels;\n };\n const step = (a: number, b: number) => {\n let sum = 0;\n for (let c = 0; c < Math.min(3, img.channels); c++)\n sum += Math.abs((img.data[a + c] ?? 0) - (img.data[b + c] ?? 0));\n return sum;\n };\n let jumps = 0;\n for (let i = 0; i < along; i++) {\n for (let d = 1; d <= depth; d++) if (step(at(i, 0), at(i, d)) > PLAIN_DEPTH_STEP) return null;\n if (i > 0 && step(at(i - 1, 0), at(i, 0)) > PLAIN_JUMP) jumps++;\n }\n return jumps;\n}\n\n/**\n * Whether the picture's `side` is plain ground that can be carried outward unchanged: it looks\n * the same `PLAIN_DEPTH` in as at the edge, and at most `PLAIN_JUMPS` borders cross it. Pure.\n */\nexport function plainEdge(img: Raw, side: Side): boolean {\n const borders = edgeBorders(img, side);\n return borders !== null && borders <= PLAIN_JUMPS;\n}\n\n/**\n * The smallest scale a fit of `image` takes: `MIN_FLAT_FIT_SCALE` when every edge is one flat\n * ground no border crosses, so whatever margin the shrink uncovers is that same ground;\n * `MIN_FIT_SCALE` otherwise.\n */\nexport async function minFitScale(image: Buffer): Promise<number> {\n const { data, info } = await sharp(image).removeAlpha().raw().toBuffer({ resolveWithObject: true });\n const raw: Raw = { data, width: info.width, height: info.height, channels: info.channels };\n const flat = ([\"top\", \"bottom\", \"left\", \"right\"] as const).every((side) => edgeBorders(raw, side) === 0);\n return flat ? MIN_FLAT_FIT_SCALE : MIN_FIT_SCALE;\n}\n\n/**\n * `image` with `fit` applied, at the same pixel size: the picture shrunk (Lanczos) and set\n * with its top-left at (`x`, `y`) of the frame, what falls off the frame cut, and each margin\n * it uncovers filled by carrying its edge on, or null when an edge it would carry is not plain\n * ground. Tier 1, Oct 2026: a margin filled from a busy edge, mirrored and blurred, read as \"a\n * blurred duplicate\" and \"the faded thing at the bottom\", worse than a line Reels covers. PNG out.\n */\nexport async function fitPicture(image: Buffer, fit: SafeFit): Promise<Buffer | null> {\n const { width = 0, height = 0 } = await sharp(image).metadata();\n const sw = Math.max(1, Math.round(width * fit.scale));\n const sh = Math.max(1, Math.round(height * fit.scale));\n const px = Math.round(fit.x * width);\n const py = Math.round(fit.y * height);\n // The part of the shrunk picture that lands on the frame.\n const left = Math.max(0, -px);\n const top = Math.max(0, -py);\n const w = Math.min(sw, width - px) - left;\n const h = Math.min(sh, height - py) - top;\n const shrunk = await sharp(image)\n .removeAlpha()\n .resize(sw, sh, { fit: \"fill\", kernel: \"lanczos3\" })\n .extract({ left, top, width: w, height: h })\n .raw()\n .toBuffer({ resolveWithObject: true });\n const pad = { left: Math.max(0, px), top: Math.max(0, py) };\n const extend = { ...pad, right: width - pad.left - w, bottom: height - pad.top - h };\n const raw: Raw = { data: shrunk.data, width: w, height: h, channels: shrunk.info.channels };\n const sides = ([\"top\", \"bottom\", \"left\", \"right\"] as const).filter((side) => extend[side] > 0);\n if (!sides.every((side) => plainEdge(raw, side))) return null;\n return sharp(shrunk.data, { raw: { width: w, height: h, channels: shrunk.info.channels } })\n .extend({ ...extend, extendWith: \"copy\" })\n .png()\n .toBuffer();\n}\n","/**\n * The words a size's edit set, lifted off the model's render and laid on the size's cut of the\n * picture, with nothing else of the render kept.\n *\n * The words model redraws the whole frame, a few pixels off and a little different everywhere.\n * So code lines the render up with the cut (`registerToSource`), keeps only what changed at the\n * designed words, logo and button (`wordsLayer`), and composes that on the cut (`compose`): the\n * rest of the size is the picture's own pixels, which `identityOutside` proves. A face is never\n * replaced by the model's pixels; a scrim or card over it only darkens or tints it (a gain).\n *\n * Pure: raw RGB buffers and fractions in, buffers and numbers out.\n */\nimport { blockingArea, blockingPlacements } from \"../../../scaffold/platform-safe-area.ts\";\nimport { bandViolations } from \"./band-check.ts\";\nimport { pictureId, remembered } from \"./picture-memo.ts\";\nimport { FIT_HEADROOM } from \"./safe-fit.ts\";\nimport type { TextBox } from \"./text-boxes.ts\";\n\nexport type Raw = { data: Buffer; width: number; height: number; channels: number };\n/** A rectangle as fractions of the frame, origin top-left. */\nexport type Span = { x0: number; y0: number; x1: number; y1: number };\ntype Rect = { x: number; y: number; width: number; height: number };\n\n/** How the render maps onto the cut: render(c + scale·(p − c) + d) is the cut's p, `c` the frame's centre, d in pixels. */\nexport type Registration = { scale: number; dx: number; dy: number; residual: number };\n\n/** A grey picture; `flat`, where it has no texture of its own (a band, a card laid over the picture). */\ntype Gray = { data: Float32Array; width: number; height: number; flat?: Uint8Array };\n\nconst inSpans = (spans: readonly Span[], fx: number, fy: number) =>\n spans.some((s) => fx >= s.x0 && fx <= s.x1 && fy >= s.y0 && fy <= s.y1);\n\n/** Which of `size` pixels along one axis have their centre in [lo, hi], as `inSpans` reads it (1). */\nfunction centresIn(lo: number, hi: number, size: number): Uint8Array {\n const inside = new Uint8Array(size);\n for (let t = 0; t < size; t++) {\n const f = (t + 0.5) / size;\n inside[t] = f >= lo && f <= hi ? 1 : 0;\n }\n return inside;\n}\n\n/** The pixels of a `width`×`height` frame whose centre `inSpans` puts in one of `spans` (1), row-major. */\nfunction spanMask(spans: readonly Span[], width: number, height: number): Uint8Array {\n const mask = new Uint8Array(width * height);\n for (const s of spans) {\n const across = centresIn(s.x0, s.x1, width);\n const down = centresIn(s.y0, s.y1, height);\n for (let y = 0; y < height; y++) {\n if (down[y]) for (let x = 0; x < width; x++) mask[y * width + x] ||= across[x] ?? 0;\n }\n }\n return mask;\n}\n\n/** The four pixels around (u, v), clamped inside a `width`×`height` frame, and their bilinear weights. */\nfunction taps(u: number, v: number, width: number, height: number): { at: number[]; w: number[] } {\n const x = Math.min(width - 1, Math.max(0, u));\n const y = Math.min(height - 1, Math.max(0, v));\n const x0 = Math.floor(x);\n const y0 = Math.floor(y);\n const x1 = Math.min(width - 1, x0 + 1);\n const y1 = Math.min(height - 1, y0 + 1);\n const fx = x - x0;\n const fy = y - y0;\n return {\n at: [y0 * width + x0, y0 * width + x1, y1 * width + x0, y1 * width + x1],\n w: [(1 - fx) * (1 - fy), fx * (1 - fy), (1 - fx) * fy, fx * fy],\n };\n}\n\n/** The weighted sum of `values` at `t`'s pixels, `stride` values a pixel, channel `c`. */\nfunction tapped(values: ArrayLike<number>, t: { at: number[]; w: number[] }, stride = 1, c = 0, missing = 0): number {\n let sum = 0;\n for (let k = 0; k < 4; k++) sum += (t.w[k] ?? 0) * (values[(t.at[k] ?? 0) * stride + c] ?? missing);\n return sum;\n}\n\nfunction grayOf(img: Raw): Gray {\n const data = new Float32Array(img.width * img.height);\n for (let i = 0; i < data.length; i++) {\n const o = i * img.channels;\n data[i] = 0.299 * (img.data[o] ?? 0) + 0.587 * (img.data[o + 1] ?? 0) + 0.114 * (img.data[o + 2] ?? 0);\n }\n return { data, width: img.width, height: img.height };\n}\n\n/** `g` averaged down by a whole factor so its long edge is at most `edge`. */\nfunction shrink(g: Gray, edge: number): Gray {\n const f = Math.max(1, Math.ceil(Math.max(g.width, g.height) / edge));\n if (f === 1) return g;\n const width = Math.floor(g.width / f);\n const height = Math.floor(g.height / f);\n const data = new Float32Array(width * height);\n for (let i = 0; i < width * height; i++) {\n const x = (i % width) * f;\n const y = Math.floor(i / width) * f;\n let sum = 0;\n for (let j = 0; j < f; j++) {\n const row = (y + j) * g.width + x;\n for (let k = 0; k < f; k++) sum += g.data[row + k] ?? 0;\n }\n data[i] = sum / (f * f);\n }\n return { data, width, height };\n}\n\ntype Candidate = { scale: number; dx: number; dy: number };\n\n/** The most pixels a level is judged on: past it every other row and column, which lines up as well. */\nconst JUDGED_MAX = 20_000;\n\n/** The pixels a level is judged on, row by row: each with its column, and where each row's run starts (`rows`, then `starts`). */\ntype Judged = { at: Int32Array; xs: Int32Array; rows: Int32Array; starts: Int32Array };\n\n/** The pixels a level is judged on: off the edges a shift may reach into, and outside `exclude`. */\nfunction judgedPixels(g: Gray, exclude: readonly Span[]): Judged {\n const mx = Math.ceil(g.width * 0.04);\n const my = Math.ceil(g.height * 0.04);\n const step = g.width * g.height > JUDGED_MAX ? 2 : 1;\n const out: number[] = [];\n for (let i = 0; i < g.width * g.height; i++) {\n const x = i % g.width;\n const y = Math.floor(i / g.width);\n if (x % step !== 0 || y % step !== 0) continue;\n if (x < mx || y < my || x >= g.width - mx || y >= g.height - my) continue;\n if (!inSpans(exclude, x / g.width, y / g.height)) out.push(i);\n }\n const rows: number[] = [];\n const starts: number[] = [];\n out.forEach((i, j) => {\n const y = Math.floor(i / g.width);\n if (rows[rows.length - 1] === y) return;\n rows.push(y);\n starts.push(j);\n });\n starts.push(out.length);\n return {\n at: Int32Array.from(out),\n xs: Int32Array.from(out, (i) => i % g.width),\n rows: Int32Array.from(rows),\n starts: Int32Array.from(starts),\n };\n}\n\n/**\n * Where each of `count` cut pixels along one axis lands on a render `size` long, mapped to\n * `origin + scale·t`: the nearest render pixel, and the pixel before it and how far past it for a\n * bilinear read clamped inside the render. One axis at a time, since a candidate maps each column\n * and each row on its own.\n */\ntype Axis = { near: Int32Array; at: Int32Array; frac: Float64Array };\n\nfunction axisOf(origin: number, scale: number, count: number, size: number): Axis {\n const near = new Int32Array(count);\n const at = new Int32Array(count);\n const frac = new Float64Array(count);\n for (let t = 0; t < count; t++) {\n const p = origin + scale * t;\n near[t] = Math.min(size - 1, Math.max(0, Math.round(p)));\n const q = Math.min(size - 1.001, Math.max(0, p));\n at[t] = q | 0;\n frac[t] = q - (at[t] ?? 0);\n }\n return { near, at, frac };\n}\n\n/**\n * A pixel's difference counts up to this (grey levels) in the line-up: past it, something was laid\n * there (a card, a pill's edge), and how far off it is says nothing about where the picture sits.\n */\nconst MISFIT_CAP = 40;\n/** The 3×3 spread (grey levels) under which a render's pixel is flat: no texture to line up on. */\nconst LINEUP_FLAT = 1.5;\n\n/** `g` with where it is flat: a band or card laid over the picture fits every shift alike, and is left out. */\nfunction withFlat(g: Gray): Gray {\n const flat = new Uint8Array(g.width * g.height);\n for (let i = 0; i < flat.length; i++) {\n const x = i % g.width;\n const y = (i - x) / g.width;\n if (x === 0 || y === 0 || x === g.width - 1 || y === g.height - 1) continue;\n let sum = 0;\n let square = 0;\n for (let k = 0; k < 9; k++) {\n const v = g.data[(y + Math.floor(k / 3) - 1) * g.width + x + (k % 3) - 1] ?? 0;\n sum += v;\n square += v * v;\n }\n flat[i] = Math.sqrt(Math.max(0, square / 9 - (sum / 9) ** 2)) < LINEUP_FLAT ? 1 : 0;\n }\n return { ...g, flat };\n}\n\n/**\n * Mean squared difference of the cut and the render mapped by `c` (shift in full pixels, `k` level\n * pixels each), each pixel's capped at `cap` grey levels, over the pixels that land on texture of\n * the render (`render.flat` left out). Infinite once it cannot come in under `beat`, or must\n * come in over `above`, checked at each row: every pixel still to read adds at least nothing to the\n * sum and at most one to the count.\n */\nfunction misfit(\n cut: Gray,\n render: Gray,\n judged: Judged,\n k: number,\n c: Candidate,\n cap = MISFIT_CAP,\n beat = Number.POSITIVE_INFINITY,\n above = Number.POSITIVE_INFINITY,\n): number {\n const cx = cut.width / 2;\n const cy = cut.height / 2;\n const ox = cx - c.scale * cx + c.dx * k;\n const oy = cy - c.scale * cy + c.dy * k;\n const cols = axisOf(ox, c.scale, cut.width, render.width);\n const rows = axisOf(oy, c.scale, cut.height, render.height);\n const look: Sampling = { cut, render, judged, cols, most: cap * cap };\n const count = judged.at.length;\n const acc = { sum: 0, n: 0 };\n for (let r = 0; r < judged.rows.length; r++) {\n const from = judged.starts[r] ?? 0;\n const least = acc.sum / (acc.n + count - from);\n if (least >= beat || least > above) return Number.POSITIVE_INFINITY;\n rowMisfit(look, rows, judged.rows[r] ?? 0, from, judged.starts[r + 1] ?? count, acc);\n }\n return acc.n > 0 ? acc.sum / acc.n : Number.POSITIVE_INFINITY;\n}\n\n/** `data` (a frame `width` wide) between pixel `i`, its right, lower and lower-right neighbours, `fx` across and `fy` down. */\nfunction bilinear(data: Float32Array, i: number, width: number, fx: number, fy: number): number {\n const top = (data[i] ?? 0) * (1 - fx) + (data[i + 1] ?? 0) * fx;\n const bottom = (data[i + width] ?? 0) * (1 - fx) + (data[i + width + 1] ?? 0) * fx;\n return top * (1 - fy) + bottom * fy;\n}\n\n/** What `rowMisfit` reads for one candidate: both pictures, the judged pixels, where each column lands, the cap squared. */\ntype Sampling = { cut: Gray; render: Gray; judged: Judged; cols: Axis; most: number };\n\n/** `misfit` over the judged pixels `from`-`to` of cut row `y`, added to `acc` in order. */\nfunction rowMisfit(\n s: Sampling,\n rows: Axis,\n y: number,\n from: number,\n to: number,\n acc: { sum: number; n: number },\n): void {\n const { width, data, flat } = s.render;\n const { near, at, frac } = s.cols;\n const flatRow = (rows.near[y] ?? 0) * width;\n const row = (rows.at[y] ?? 0) * width;\n const fy = rows.frac[y] ?? 0;\n for (let j = from; j < to; j++) {\n const x = s.judged.xs[j] ?? 0;\n if (flat?.[flatRow + (near[x] ?? 0)]) continue;\n const d = (s.cut.data[s.judged.at[j] ?? 0] ?? 0) - bilinear(data, row + (at[x] ?? 0), width, frac[x] ?? 0, fy);\n acc.sum += Math.min(d * d, s.most);\n acc.n++;\n }\n}\n\n/** The farthest the render is searched from the cut: its own drift measured a few pixels; 3% is room. */\nconst MAX_SHIFT = 0.03;\nconst MAX_SCALE_OFF = 0.03;\n\ntype Level = { edge: number; scales: number[]; reach: number | null };\n\n/** The search pyramid: every scale and shift up to 3% on a coarse frame, then twice refined around the best. */\nconst LEVELS: readonly Level[] = [\n { edge: 128, scales: [-0.03, -0.02, -0.01, 0, 0.01, 0.02, 0.03], reach: null },\n { edge: 256, scales: [-0.005, 0, 0.005], reach: 2 },\n { edge: 512, scales: [-0.0025, 0, 0.0025], reach: 1 },\n];\n\n/** The best candidate on one level of the pyramid, around `centre`. */\nfunction searchLevel(\n cut: Gray,\n render: Gray,\n k: number,\n level: Level,\n centre: Candidate,\n exclude: readonly Span[],\n): { best: Candidate; score: number } {\n const judged = judgedPixels(cut, exclude);\n const reach = level.reach ?? Math.ceil(MAX_SHIFT * Math.max(cut.width, cut.height));\n let best = centre;\n let score = Number.POSITIVE_INFINITY;\n // The centre is read first only to bound the rest: a candidate sure to fit worse is dropped early.\n const atCentre = misfit(cut, render, judged, k, centre);\n const side = 2 * reach + 1;\n for (const ds of level.scales) {\n const scale = centre.scale + ds;\n if (Math.abs(scale - 1) > MAX_SCALE_OFF + 1e-9) continue;\n for (let s = 0; s < side * side; s++) {\n const c = { scale, dx: centre.dx + ((s % side) - reach) / k, dy: centre.dy + (Math.floor(s / side) - reach) / k };\n const m = misfit(cut, render, judged, k, c, MISFIT_CAP, score, atCentre);\n if (m < score) {\n score = m;\n best = c;\n }\n }\n }\n return { best, score };\n}\n\n/**\n * How `render` (the words model's frame, resized to the cut's pixels) lines up with `cut`:\n * a coarse-to-fine search of scale (0.97-1.03) and shift (±3%), minimising the squared\n * difference outside `exclude` (where the words were set, which differ on purpose) and off what\n * the render laid flat (a band, a card), each pixel's capped (`MISFIT_CAP`), so nothing laid over\n * the picture pulls it. `residual` is the root-mean-square difference left there, uncapped, in\n * grey levels.\n */\nexport function registerToSource(render: Raw, cut: Raw, exclude: readonly Span[]): Registration {\n return lineUps(render, `${pictureId(cut)} ${JSON.stringify(exclude)}`, () => lineUp(render, cut, exclude));\n}\n\n/** A render refused whole is lined up again to lift its words: the same render, cut and words, the same line-up. */\nconst lineUps = remembered<Registration>();\nconst warps = remembered<Raw>();\n\nfunction lineUp(render: Raw, cut: Raw, exclude: readonly Span[]): Registration {\n const full = { cut: grayOf(cut), render: grayOf(render) };\n let best: Candidate = { scale: 1, dx: 0, dy: 0 };\n let finest = { cut: full.cut, render: full.render, k: 1 };\n for (const level of LEVELS) {\n const c = shrink(full.cut, level.edge);\n const r = withFlat(shrink(full.render, level.edge));\n const k = c.width / cut.width;\n best = searchLevel(c, r, k, level, best, exclude).best;\n finest = { cut: c, render: r, k };\n }\n const judged = judgedPixels(finest.cut, exclude);\n const residual = misfit(finest.cut, finest.render, judged, finest.k, best, Number.POSITIVE_INFINITY);\n return { ...best, residual: Math.sqrt(residual) };\n}\n\n/** `taps` along one axis of a frame `size` long, for every pixel `t` mapped to `centre + scale·(t − centre) + shift`. */\nfunction bilinearAxis(centre: number, scale: number, shift: number, size: number) {\n const lo = new Int32Array(size);\n const hi = new Int32Array(size);\n const frac = new Float64Array(size);\n for (let t = 0; t < size; t++) {\n const p = Math.min(size - 1, Math.max(0, centre + scale * (t - centre) + shift));\n lo[t] = Math.floor(p);\n hi[t] = Math.min(size - 1, (lo[t] ?? 0) + 1);\n frac[t] = p - (lo[t] ?? 0);\n }\n return { lo, hi, frac };\n}\n\n/** `render` mapped onto the cut's frame by `fit` (bilinear, edges carried), at its own pixel size, RGB. */\nexport function warpToCut(render: Raw, fit: Pick<Registration, \"scale\" | \"dx\" | \"dy\">): Raw {\n return warps(render, `${fit.scale} ${fit.dx} ${fit.dy}`, () => warped(render, fit));\n}\n\nfunction warped(render: Raw, fit: Pick<Registration, \"scale\" | \"dx\" | \"dy\">): Raw {\n const { width, height } = render;\n const out = Buffer.alloc(width * height * 3);\n const cols = bilinearAxis(width / 2, fit.scale, fit.dx, width);\n const rows = bilinearAxis(height / 2, fit.scale, fit.dy, height);\n for (let y = 0; y < height; y++) {\n const row = { y, top: (rows.lo[y] ?? 0) * width, bottom: (rows.hi[y] ?? 0) * width, fy: rows.frac[y] ?? 0 };\n warpRow(render, out, cols, row);\n }\n return { data: out, width, height, channels: 3 };\n}\n\n/** Row `row.y` of `warped`: each pixel the four render pixels around where it lands, weighed, RGB. */\nfunction warpRow(\n render: Raw,\n out: Buffer,\n cols: ReturnType<typeof bilinearAxis>,\n row: { y: number; top: number; bottom: number; fy: number },\n): void {\n const { width, channels, data } = render;\n const { fy } = row;\n for (let x = 0; x < width; x++) {\n const fx = cols.frac[x] ?? 0;\n const w = [(1 - fx) * (1 - fy), fx * (1 - fy), (1 - fx) * fy, fx * fy] as const;\n const lo = cols.lo[x] ?? 0;\n const hi = cols.hi[x] ?? 0;\n const a = [\n (row.top + lo) * channels,\n (row.top + hi) * channels,\n (row.bottom + lo) * channels,\n (row.bottom + hi) * channels,\n ] as const;\n const o = (row.y * width + x) * 3;\n for (let c = 0; c < 3; c++) {\n out[o + c] = Math.round(\n w[0] * (data[a[0] + c] ?? 0) +\n w[1] * (data[a[1] + c] ?? 0) +\n w[2] * (data[a[2] + c] ?? 0) +\n w[3] * (data[a[3] + c] ?? 0),\n );\n }\n }\n}\n\n/**\n * The words layer: what of the model's (aligned) render is laid on the cut, per pixel.\n * `alpha` how much of the layer a pixel takes; `ink` how much of that is the model's own pixel\n * (`pixels`), the rest the cut's pixel times `gain` (the model's low-frequency tone change: a\n * scrim, a card's shadow). Row-major; `pixels` and `gain` have three values a pixel.\n */\nexport type WordsLayer = {\n width: number;\n height: number;\n alpha: Float32Array;\n ink: Float32Array;\n pixels: Buffer;\n gain: Float32Array;\n};\n\nfunction emptyLayer(width: number, height: number): WordsLayer {\n return {\n width,\n height,\n alpha: new Float32Array(width * height),\n ink: new Float32Array(width * height),\n pixels: Buffer.alloc(width * height * 3),\n gain: new Float32Array(width * height * 3).fill(1),\n };\n}\n\n/** The grid the change is read on, in pixels a cell. */\nconst CELL = 8;\n/** A cell whose mean largest-channel difference is at least this changed (grey levels). */\nconst CHANGED = 14;\n/** A pixel inside a words box is the model's from this difference, fully from `MATTE_HI`. */\nconst MATTE_LO = 8;\nconst MATTE_HI = 32;\n/** How far past a words box the model's pixels are taken, as a share of the box's height (anti-aliasing, a pill's edge). */\nconst BOX_PAD = 0.3;\n/** How far a change may sit from a words box and still be the words' (a card, a scrim), as a share of the frame's width. */\nconst TOUCH = 0.02;\n/** The gain a tone change may apply, either way: past it, it is not a tone. */\nconst GAIN_MAX = 4;\n/** A cell with fewer pixels outside the words than this takes its tone from the cells around it. */\nconst TONE_MIN_PIXELS = (CELL * CELL) / 4;\n\n/** `b` padded by `BOX_PAD` of its height on every side (the same pixels across as down): a line with its anti-aliasing and a pill's edge. */\nexport const padded = (b: Span, width: number, height: number): Span => {\n const pad = BOX_PAD * (b.y1 - b.y0);\n const padX = (pad * height) / width;\n return { x0: b.x0 - padX, y0: b.y0 - pad, x1: b.x1 + padX, y1: b.y1 + pad };\n};\n\ntype Grid = { gw: number; gh: number; cell: (x: number, y: number) => number; span: (g: number) => Span };\n\nfunction gridOf(width: number, height: number): Grid {\n const gw = Math.ceil(width / CELL);\n const gh = Math.ceil(height / CELL);\n return {\n gw,\n gh,\n cell: (x, y) => Math.floor(y / CELL) * gw + Math.floor(x / CELL),\n span: (g) => {\n const gx = g % gw;\n const gy = Math.floor(g / gw);\n return {\n x0: (gx * CELL) / width,\n y0: (gy * CELL) / height,\n x1: ((gx + 1) * CELL) / width,\n y1: ((gy + 1) * CELL) / height,\n };\n },\n };\n}\n\n/** The 8 cells around `g` on the grid. */\nfunction neighbours(g: number, grid: Grid): number[] {\n const gx = g % grid.gw;\n const gy = Math.floor(g / grid.gw);\n const out: number[] = [];\n for (let k = 0; k < 9; k++) {\n const nx = gx + (k % 3) - 1;\n const ny = gy + Math.floor(k / 3) - 1;\n if (k !== 4 && nx >= 0 && ny >= 0 && nx < grid.gw && ny < grid.gh) out.push(ny * grid.gw + nx);\n }\n return out;\n}\n\ntype CellStats = {\n /** Each cell's mean largest-channel difference. */\n diff: Float32Array;\n /** Each pixel's largest-channel difference. */\n pixelDiff: Float32Array;\n /** Each cell's mean colour, render and cut, read off its pixels outside the words only. */\n meanA: Float32Array;\n meanC: Float32Array;\n toneCount: Float32Array;\n};\n\n/** Adds pixel `i` (at cell `g`) of the render and the cut to `s`; its colour only when `tone`. */\nfunction addPixel(s: CellStats, aligned: Raw, cut: Raw, i: number, g: number, tone: boolean): number {\n let d = 0;\n for (let c = 0; c < 3; c++) {\n const a = aligned.data[i * aligned.channels + c] ?? 0;\n const b = cut.data[i * cut.channels + c] ?? 0;\n d = Math.max(d, Math.abs(a - b));\n if (!tone) continue;\n s.meanA[g * 3 + c] = (s.meanA[g * 3 + c] ?? 0) + a;\n s.meanC[g * 3 + c] = (s.meanC[g * 3 + c] ?? 0) + b;\n }\n return d;\n}\n\n/** How much each cell and pixel changed, and each cell's colour outside the words. */\nfunction cellStats(aligned: Raw, cut: Raw, words: Uint8Array, grid: Grid): CellStats {\n const cells = grid.gw * grid.gh;\n const s: CellStats = {\n diff: new Float32Array(cells),\n pixelDiff: new Float32Array(cut.width * cut.height),\n meanA: new Float32Array(cells * 3),\n meanC: new Float32Array(cells * 3),\n toneCount: new Float32Array(cells),\n };\n const count = new Float32Array(cells);\n for (let i = 0; i < cut.width * cut.height; i++) {\n const x = i % cut.width;\n const y = Math.floor(i / cut.width);\n const g = grid.cell(x, y);\n // The tone is read only off what is not words: a white headline is not a lighter scrim.\n const tone = !words[i];\n const d = addPixel(s, aligned, cut, i, g, tone);\n s.pixelDiff[i] = d;\n s.diff[g] = (s.diff[g] ?? 0) + d;\n count[g] = (count[g] ?? 0) + 1;\n if (tone) s.toneCount[g] = (s.toneCount[g] ?? 0) + 1;\n }\n for (let k = 0; k < cells * 3; k++) {\n const g = Math.floor(k / 3);\n if (k % 3 === 0) s.diff[g] = (s.diff[g] ?? 0) / (count[g] || 1);\n s.meanA[k] = (s.meanA[k] ?? 0) / (s.toneCount[g] || 1);\n s.meanC[k] = (s.meanC[k] ?? 0) / (s.toneCount[g] || 1);\n }\n return s;\n}\n\nconst isChanged = (diff: Float32Array, g: number) => (diff[g] ?? 0) >= CHANGED;\n\n/** Marks every changed cell connected to `start` (8-connected) as region `id`. */\nfunction flood(start: number, id: number, diff: Float32Array, region: Int32Array, grid: Grid): void {\n region[start] = id;\n const stack = [start];\n while (stack.length > 0) {\n const g = stack.pop() ?? 0;\n const next = neighbours(g, grid).filter((n) => isChanged(diff, n) && (region[n] ?? -1) < 0);\n for (const n of next) region[n] = id;\n stack.push(...next);\n }\n}\n\n/** Each changed cell's region (8-connected), -1 for an unchanged cell, and how many regions there are. */\nfunction changedRegions(diff: Float32Array, grid: Grid): { region: Int32Array; count: number } {\n const region = new Int32Array(diff.length).fill(-1);\n let count = 0;\n for (let start = 0; start < diff.length; start++) {\n if (!isChanged(diff, start) || (region[start] ?? -1) >= 0) continue;\n flood(start, count, diff, region, grid);\n count++;\n }\n return { region, count };\n}\n\n/** Each cell's tone change (the render's mean over the cut's, per channel, kept within `GAIN_MAX`), or null when it is mostly words. */\nfunction cellGain(s: CellStats, g: number): number[] | null {\n if ((s.toneCount[g] ?? 0) < TONE_MIN_PIXELS) return null;\n return [0, 1, 2].map((c) => {\n const ratio = ((s.meanA[g * 3 + c] ?? 0) + 8) / ((s.meanC[g * 3 + c] ?? 0) + 8);\n return Math.min(GAIN_MAX, Math.max(1 / GAIN_MAX, ratio));\n });\n}\n\n/** The mean of the known gains around `g`, or null when none is known yet. */\nfunction neighbourGain(gain: Float32Array, known: Uint8Array, g: number, grid: Grid): number[] | null {\n const around = neighbours(g, grid).filter((n) => known[n]);\n if (around.length === 0) return null;\n return [0, 1, 2].map((c) => around.reduce((sum, n) => sum + (gain[n * 3 + c] ?? 1), 0) / around.length);\n}\n\n/** One pass of the spread: every unknown cell next to a known one takes their mean. How many it filled. */\nfunction spreadGains(gain: Float32Array, known: Uint8Array, grid: Grid): number {\n const filled: Array<[number, number[]]> = [];\n for (let g = 0; g < known.length; g++) {\n const from = known[g] ? null : neighbourGain(gain, known, g, grid);\n if (from) filled.push([g, from]);\n }\n for (const [g, value] of filled) {\n gain.set(value, g * 3);\n known[g] = 1;\n }\n return filled.length;\n}\n\n/** Every cell's tone gain; a cell mostly words takes its neighbours', spreading inward until every cell has one. */\nfunction toneGains(s: CellStats, grid: Grid): Float32Array {\n const cells = grid.gw * grid.gh;\n const gain = new Float32Array(cells * 3).fill(1);\n const known = new Uint8Array(cells);\n for (let g = 0; g < cells; g++) {\n const own = cellGain(s, g);\n if (!own) continue;\n gain.set(own, g * 3);\n known[g] = 1;\n }\n let spread = 1;\n while (spread > 0) spread = spreadGains(gain, known, grid);\n return gain;\n}\n\n/**\n * The gains averaged over each cell and its neighbours: a scrim or a card's shade is smooth across\n * cells, and a cell whose own gain is far from its neighbours' is something drawn again, which the\n * tone check then finds.\n */\nfunction smoothGains(gains: Float32Array, grid: Grid): Float32Array {\n const out = new Float32Array(gains.length);\n for (let g = 0; g < grid.gw * grid.gh; g++) {\n const around = [g, ...neighbours(g, grid)];\n for (let c = 0; c < 3; c++) {\n out[g * 3 + c] = around.reduce((sum, n) => sum + (gains[n * 3 + c] ?? 1), 0) / around.length;\n }\n }\n return out;\n}\n\n/** The most a cell may still differ from the cut times its gain (mean largest-channel, grey levels) and be a tone. */\nconst STRUCTURAL = 16;\n\n/** Each cell's mean largest-channel difference between the render and the cut times the cell's gain, outside the words. */\nfunction toneMisfit(aligned: Raw, cut: Raw, gains: Float32Array, words: Uint8Array, grid: Grid): Float32Array {\n const sum = new Float32Array(grid.gw * grid.gh);\n const count = new Float32Array(grid.gw * grid.gh);\n for (let i = 0; i < cut.width * cut.height; i++) {\n const x = i % cut.width;\n const y = (i - x) / cut.width;\n if (words[i]) continue;\n const g = grid.cell(x, y);\n let d = 0;\n for (let c = 0; c < 3; c++) {\n const want = Math.min(255, (cut.data[i * cut.channels + c] ?? 0) * (gains[g * 3 + c] ?? 1));\n d = Math.max(d, Math.abs((aligned.data[i * aligned.channels + c] ?? 0) - want));\n }\n sum[g] = (sum[g] ?? 0) + d;\n count[g] = (count[g] ?? 0) + 1;\n }\n return sum.map((v, g) => (count[g] ? v / (count[g] ?? 1) : 0));\n}\n\n/** The cell centres around a pixel and their bilinear weights, to read a per-cell value there. */\nfunction cellTaps(grid: Grid, x: number, y: number): { at: number[]; w: number[] } {\n return taps((x + 0.5) / CELL - 0.5, (y + 0.5) / CELL - 0.5, grid.gw, grid.gh);\n}\n\n/**\n * The words layer of `aligned` (the render, lined up with the cut) over `cut`, for the `designed`\n * words, logo and button boxes. A change is kept only when it touches one: inside a box padded by\n * `BOX_PAD` the model's pixels, matted by how much they changed; in the rest of a kept change its\n * tone as a gain on the cut. On a person, face or product (`subjects`) only the box itself takes the\n * model's pixels, never its padding (the model may have drawn the subject elsewhere); `keepOut`\n * (text that is part of the scene) takes nothing; `boxesOnly` takes no tone, only the boxes.\n * `reverted`: the share of the frame the model changed that was put back to the cut. Pure.\n */\nexport function wordsLayer(\n aligned: Raw,\n cut: Raw,\n designed: readonly Span[],\n opts: { subjects?: readonly Span[]; keepOut?: readonly Span[]; boxesOnly?: boolean } = {},\n): { layer: WordsLayer; reverted: number } {\n const { width, height } = cut;\n const grid = gridOf(width, height);\n const boxes = designed.map((b) => padded(b, width, height));\n const tight = designed.map((b) => ({ ...b }));\n const inBoxes = spanMask(boxes, width, height);\n const stats = cellStats(aligned, cut, inBoxes, grid);\n const kept = keptChange(stats.diff, boxes, grid, (TOUCH * width) / height);\n const gains = smoothGains(toneGains(stats, grid), grid);\n // A tone is only what a gain explains (a scrim, a card on plain ground). A change it does not\n // explain is something drawn again (a person moved, a lamp added) and goes back to the cut; without\n // a trusted alignment no tone is taken at all, only the boxes.\n const misfit = opts.boxesOnly ? null : toneMisfit(aligned, cut, gains, inBoxes, grid);\n const tone = kept.tone.map((t, g) => (t > 0 && misfit && (misfit[g] ?? 0) < STRUCTURAL ? 1 : 0));\n const dropped = kept.tone.reduce((n, t, g) => n + (t > 0 && !tone[g] ? 1 : 0), 0);\n const reverted = kept.reverted + dropped / kept.tone.length;\n const look: PixelLook = {\n aligned,\n stats,\n grid,\n boxes: inBoxes,\n tone,\n gains,\n tight: spanMask(tight, width, height),\n subjects: spanMask(opts.subjects ?? [], width, height),\n keepOut: spanMask(opts.keepOut ?? [], width, height),\n };\n const layer = emptyLayer(width, height);\n for (let i = 0; i < width * height; i++) setLayerPixel(layer, look, i);\n return { layer, reverted };\n}\n\nconst overlaps = (a: Span, b: Span) => a.x0 < b.x1 && a.x1 > b.x0 && a.y0 < b.y1 && a.y1 > b.y0;\n\n/**\n * Which cells' change is the words' (1 in `tone`): every cell of a changed region touching a words\n * box (`boxes` grown by `TOUCH`, `touchY` of the height down). `reverted`: the share of cells\n * changed in a region that touches none, outside the boxes, which the cut takes back.\n */\nfunction keptChange(\n diff: Float32Array,\n boxes: readonly Span[],\n grid: Grid,\n touchY: number,\n): { tone: Float32Array; reverted: number } {\n const { region, count } = changedRegions(diff, grid);\n const near = boxes.map((b) => ({ x0: b.x0 - TOUCH, y0: b.y0 - touchY, x1: b.x1 + TOUCH, y1: b.y1 + touchY }));\n const kept = new Uint8Array(count);\n for (let g = 0; g < region.length; g++) {\n const id = region[g] ?? -1;\n if (id >= 0 && near.some((b) => overlaps(grid.span(g), b))) kept[id] = 1;\n }\n const tone = new Float32Array(region.length);\n let reverted = 0;\n for (let g = 0; g < region.length; g++) {\n const id = region[g] ?? -1;\n if (id < 0) continue;\n if (kept[id]) tone[g] = 1;\n else if (!boxes.some((b) => overlaps(grid.span(g), b))) reverted++;\n }\n return { tone, reverted: reverted / region.length };\n}\n\n/** What `setLayerPixel` reads: the render, the change, the kept tone and its gains, and what it must leave alone. */\ntype PixelLook = {\n aligned: Raw;\n stats: CellStats;\n grid: Grid;\n /** The pixels in a padded words box (1); `tight`, `subjects` and `keepOut` the same for theirs. */\n boxes: Uint8Array;\n tone: Float32Array;\n gains: Float32Array;\n /** The boxes as read, without padding: all a box takes on a subject. */\n tight: Uint8Array;\n subjects: Uint8Array;\n keepOut: Uint8Array;\n};\n\n/** Pixel `i` of the layer: the model's pixel matted inside a words box (only the box as read, on a subject), the tone in the rest of a kept change. */\nfunction setLayerPixel(layer: WordsLayer, look: PixelLook, i: number): void {\n const x = i % layer.width;\n const y = Math.floor(i / layer.width);\n const onSubject = look.subjects[i] === 1;\n const inBox = (onSubject ? look.tight : look.boxes)[i] === 1;\n if (!inBox && look.keepOut[i]) return;\n // Only within a kept change: a tone is never read off a change that was put back.\n const near = look.tone[look.grid.cell(x, y)] ? cellTaps(look.grid, x, y) : undefined;\n const toned = near ? tapped(look.tone, near, 1, 0, 1) : 0;\n const changed = ((look.stats.pixelDiff[i] ?? 0) - MATTE_LO) / (MATTE_HI - MATTE_LO);\n const matte = inBox ? Math.min(1, Math.max(0, changed)) : 0;\n const a = Math.max(matte, toned);\n if (a <= 0) return;\n layer.alpha[i] = a;\n layer.ink[i] = inBox ? 1 : 0;\n const cells = near ?? cellTaps(look.grid, x, y);\n for (let c = 0; c < 3; c++) {\n layer.pixels[i * 3 + c] = look.aligned.data[i * look.aligned.channels + c] ?? 0;\n layer.gain[i * 3 + c] = tapped(look.gains, cells, 3, c, 1);\n }\n}\n\n/**\n * The layer with no word on a face (fractions of the layer's frame): where a model pixel would land\n * on one, the face shows instead; a tone over it stays. `covered`: the share of the faces' pixels\n * a word was taken off. Pure.\n */\nexport function protectFaces(layer: WordsLayer, faces: readonly Span[]): { layer: WordsLayer; covered: number } {\n if (faces.length === 0) return { layer, covered: 0 };\n const alpha = Float32Array.from(layer.alpha);\n const ink = Float32Array.from(layer.ink);\n let onFace = 0;\n let covered = 0;\n for (let i = 0; i < alpha.length; i++) {\n const fx = ((i % layer.width) + 0.5) / layer.width;\n const fy = (Math.floor(i / layer.width) + 0.5) / layer.height;\n if (!inSpans(faces, fx, fy)) continue;\n onFace++;\n const k = ink[i] ?? 0;\n if (k <= 0 || (alpha[i] ?? 0) <= 0) continue;\n covered++;\n alpha[i] = (alpha[i] ?? 0) * (1 - k);\n ink[i] = 0;\n }\n return { layer: { ...layer, alpha, ink }, covered: onFace > 0 ? covered / onFace : 0 };\n}\n\n/** A subject is hidden by the words when they cover this share of its box. */\nconst HIDDEN = 0.5;\n\n/**\n * The products and animals (`subjects`, fractions of the layer's frame) whose box the words cover\n * over `HIDDEN` of (alpha at least one half): the size no longer shows what the others do. Faces\n * are kept by `protectFaces`; a person's body under a headline is an ordinary layout. Pure.\n */\nexport function coveredSubjects(\n layer: WordsLayer,\n subjects: ReadonlyArray<Span & { kind: string; label: string }>,\n): string[] {\n return subjects\n .filter((b) => b.kind === \"product\" || b.kind === \"animal\")\n .filter((b) => {\n const x0 = Math.max(0, Math.floor(b.x0 * layer.width));\n const x1 = Math.min(layer.width, Math.ceil(b.x1 * layer.width));\n const y0 = Math.max(0, Math.floor(b.y0 * layer.height));\n const y1 = Math.min(layer.height, Math.ceil(b.y1 * layer.height));\n let covered = 0;\n for (let y = y0; y < y1; y++) {\n for (let x = x0; x < x1; x++) if ((layer.alpha[y * layer.width + x] ?? 0) >= 0.5) covered++;\n }\n const all = (x1 - x0) * (y1 - y0);\n return all > 0 && covered / all > HIDDEN;\n })\n .map((b) => b.label);\n}\n\n/** The layer laid on the cut: a pixel the layer does not take is the cut's, exactly. */\nexport function compose(cut: Raw, layer: WordsLayer): Raw {\n const { width, height } = cut;\n const out = Buffer.alloc(width * height * 3);\n for (let k = 0; k < width * height * 3; k++) {\n const i = Math.floor(k / 3);\n const c = k % 3;\n const base = cut.data[i * cut.channels + c] ?? 0;\n const a = layer.alpha[i] ?? 0;\n if (a <= 0) {\n out[k] = base;\n continue;\n }\n const ink = layer.ink[i] ?? 0;\n const toned = Math.min(255, base * (layer.gain[k] ?? 1));\n out[k] = Math.round(base * (1 - a) + (ink * (layer.pixels[k] ?? 0) + (1 - ink) * toned) * a);\n }\n return { data: out, width, height, channels: 3 };\n}\n\n/** The mean difference between `out` and `cut` where the layer takes nothing: 0 when the picture outside the words is the cut's own. */\nexport function identityOutside(out: Raw, cut: Raw, alpha: Float32Array): number {\n let sum = 0;\n let n = 0;\n for (let k = 0; k < cut.width * cut.height * 3; k++) {\n const i = Math.floor(k / 3);\n if ((alpha[i] ?? 0) > 0) continue;\n sum += Math.abs((out.data[i * out.channels + (k % 3)] ?? 0) - (cut.data[i * cut.channels + (k % 3)] ?? 0));\n n++;\n }\n return n > 0 ? sum / n : 0;\n}\n\n/** The smallest scale a words move takes before the size's words are set again instead. */\nexport const MIN_WORDS_SCALE = 0.8;\n/** The farthest a group of words is moved off a face, as a share of the frame's height: past it, its words are set again. */\nexport const MAX_WORDS_MOVE = 0.12;\n/**\n * The farthest a group of words past the band is moved out from under the interface. A Meta 9:16 keeps\n * clear of Reels' caption as well as Stories' reply bar (`blockingArea`), the bottom 32%: a button GPT\n * sets at 86-93% of the height is up to a quarter of the frame from clear.\n */\nexport const MAX_BAND_MOVE = 0.25;\n/** Lines closer than this (a share of the height) move together, as one block. */\nconst GROUP_GAP = 0.04;\n/** How finely a move's scale and place are searched. */\nconst SCALE_STEP = 0.05;\nconst MOVE_STEP = 0.005;\n\n/** A move of words: scaled by `scale` about (`cx`, `cy`), then shifted by (`dx`, `dy`); fractions of the frame. */\nexport type WordsShift = { scale: number; cx: number; cy: number; dx: number; dy: number };\n/** One block of words (`group`, the area its layer takes) and its move. */\nexport type WordsMove = { group: Span; fit: WordsShift };\nexport type WordsShiftPlan = { moves: WordsMove[]; reason?: \"band_too_far\" | \"words_over_face\" };\n\n/** How far to move [from, to] to land it inside [lo, hi] (it fits). */\nconst into = (from: number, to: number, lo: number, hi: number) => Math.max(lo - from, 0) + Math.min(hi - to, 0);\n\nconst unionOf = (boxes: readonly Span[]): Span => ({\n x0: Math.min(...boxes.map((b) => b.x0)),\n y0: Math.min(...boxes.map((b) => b.y0)),\n x1: Math.max(...boxes.map((b) => b.x1)),\n y1: Math.max(...boxes.map((b) => b.y1)),\n});\n\nconst overlap = (a: Span, b: Span) => a.x0 < b.x1 && a.x1 > b.x0 && a.y0 < b.y1 && a.y1 > b.y0;\n\n/**\n * Where a block reaching down to `bottom` may be set, first choice first, with the fit's headroom:\n * the band `format`'s placements leave clear, then, where an interface draws over less than the\n * band keeps clear (Stories' header and reply bar), clear of what it draws: the review blocks only\n * words it covers.\n */\nfunction clearAreas(format: string, placements: readonly string[] | undefined, bottom: number): Span[] {\n const area = blockingArea(format, placements);\n // A line that reaches down beside Reels' buttons keeps clear of them.\n const rail = area.rail && bottom > area.rail.from ? area.rail.width : 0;\n const band = {\n x0: area.left + FIT_HEADROOM,\n y0: area.top + FIT_HEADROOM,\n x1: 1 - Math.max(area.right, rail) - FIT_HEADROOM,\n y1: 1 - area.bottom - FIT_HEADROOM,\n };\n const covered = area.covered;\n if (!covered) return [band];\n const drawn = covered.rail && bottom > covered.rail.from ? covered.rail.width : 0;\n return [\n band,\n {\n x0: band.x0,\n y0: covered.top + FIT_HEADROOM,\n x1: 1 - Math.max(area.right, drawn) - FIT_HEADROOM,\n y1: 1 - covered.bottom - FIT_HEADROOM,\n },\n ];\n}\n\n/** The words in blocks, top to bottom: lines less than `GROUP_GAP` apart are one block. */\nfunction wordGroups(words: readonly TextBox[]): TextBox[][] {\n const sorted = [...words].sort((a, b) => a.y0 - b.y0);\n const groups: TextBox[][] = [];\n for (const box of sorted) {\n const last = groups.at(-1);\n if (last && box.y0 - Math.max(...last.map((b) => b.y1)) < GROUP_GAP) last.push(box);\n else groups.push([box]);\n }\n return groups;\n}\n\ntype Placing = {\n areas: readonly Span[];\n faces: readonly Span[];\n others: readonly Span[];\n minScale: number;\n /** How far the block may move (`MAX_WORDS_MOVE`, or `MAX_BAND_MOVE` for one past the band). */\n reach: number;\n};\n\n/** Whether the block's union, moved by `fit`, sits in `area`, off every face and off the other blocks. */\nfunction placed(union: Span, fit: WordsShift, area: Span, p: Placing, withFaces: boolean): boolean {\n const m = movedSpan(union, fit);\n const inArea = m.x0 >= area.x0 - 1e-9 && m.x1 <= area.x1 + 1e-9 && m.y0 >= area.y0 - 1e-9 && m.y1 <= area.y1 + 1e-9;\n return inArea && !p.others.some((o) => overlap(m, o)) && !(withFaces && p.faces.some((f) => overlap(m, f)));\n}\n\n/** The smallest shift of the block at `at`'s scale (the place nearest where it was, within `p.reach`) that sets it in `area`. */\nfunction shiftInto(\n union: Span,\n at: { scale: number; cx: number; cy: number },\n area: Span,\n p: Placing,\n withFaces: boolean,\n): WordsShift | null {\n const half = (at.scale * (union.x1 - union.x0)) / 2;\n const dx = into(at.cx - half, at.cx + half, area.x0, area.x1);\n const steps = Math.round(p.reach / MOVE_STEP);\n for (let k = 0; k <= 2 * steps; k++) {\n const dy = (k % 2 === 0 ? 1 : -1) * Math.ceil(k / 2) * MOVE_STEP;\n const fit = { ...at, dx, dy };\n if (placed(union, fit, area, p, withFaces)) return fit;\n }\n return null;\n}\n\n/**\n * The smallest move of one block that sets it in one of `p.areas`, off the faces and the other\n * blocks: largest scale first, and at each scale the first area that takes it; null when none does.\n */\nfunction blockMove(union: Span, p: Placing, withFaces: boolean): WordsShift | null {\n const cx = (union.x0 + union.x1) / 2;\n const cy = (union.y0 + union.y1) / 2;\n for (let scale = 1; scale >= p.minScale - 1e-9; scale -= SCALE_STEP) {\n for (const area of p.areas) {\n const fit = shiftInto(union, { scale, cx, cy }, area, p, withFaces);\n if (fit) return fit;\n }\n }\n return null;\n}\n\nconst unmoved = (fit: WordsShift) => fit.scale === 1 && fit.dx === 0 && fit.dy === 0;\n\n/** `area` as wide as `union` at least: a block clear of the band's sides moves up or down only, at its own size. */\nconst across = (area: Span, union: Span): Span => ({\n ...area,\n x0: Math.min(area.x0, union.x0),\n x1: Math.max(area.x1, union.x1),\n});\n\n/**\n * How the words move so each block of `words` (the designed words, logo and button, read in the\n * size's frame) sits inside the band `format`'s placements leave clear and off every face: each\n * block on its own, shifted first and scaled (down to `minScale`) only when shifting cannot, never\n * further than `MAX_WORDS_MOVE` off a face (`MAX_BAND_MOVE` out from under the interface). A block already clear stays. `reason` names a block no move\n * clears: `band_too_far`, or `words_over_face` when only a face is in the way. Pure.\n */\nexport function planWordsShift(\n words: readonly TextBox[],\n format: string,\n opts: {\n placements?: readonly string[];\n minScale?: number;\n faces?: readonly Span[];\n /** Places no move may take words into (the logo's slot), though words already there are not moved for them. */\n keepOut?: readonly Span[];\n } = {},\n): WordsShiftPlan {\n const faces = opts.faces ?? [];\n const obstacles = [...faces, ...(opts.keepOut ?? [])];\n const groups = wordGroups(words).map((g) => ({ boxes: g, union: unionOf(g) }));\n const moves: WordsMove[] = [];\n let reason: WordsShiftPlan[\"reason\"];\n for (const [i, group] of groups.entries()) {\n const violations = bandViolations(group.boxes, format, { placements: blockingPlacements(opts.placements) });\n const past = violations.length > 0;\n const onFace = faces.some((f) => overlap(group.union, f));\n if (!past && !onFace) continue;\n const sideways = violations.some((v) => v.edges.includes(\"left\") || v.edges.includes(\"right\"));\n const p: Placing = {\n areas: clearAreas(format, opts.placements, group.union.y1).map((a) => (sideways ? a : across(a, group.union))),\n faces: obstacles,\n others: groups.filter((_, j) => j !== i).map((g) => g.union),\n minScale: opts.minScale ?? MIN_WORDS_SCALE,\n reach: past ? MAX_BAND_MOVE : MAX_WORDS_MOVE,\n };\n const step = stepOf(group.union, past, p);\n if (typeof step === \"string\") reason ??= step;\n else if (step) moves.push({ group: group.union, fit: step });\n }\n return reason ? { moves, reason } : { moves };\n}\n\n/**\n * One block's move into `p.areas`, null when it already sits in one; else why no move clears it:\n * `words_over_face` when only a face is in the way.\n */\nfunction stepOf(union: Span, past: boolean, p: Placing): WordsShift | null | \"band_too_far\" | \"words_over_face\" {\n const fit = blockMove(union, p, true);\n if (fit) return unmoved(fit) ? null : fit;\n return blockMove(union, p, false) || !past ? \"words_over_face\" : \"band_too_far\";\n}\n\n/** Where `fit` takes a box. Pure. */\nexport function movedSpan<T extends Span>(b: T, fit: WordsShift): T {\n const at = (v: number, c: number, d: number) => c + fit.scale * (v - c) + d;\n return {\n ...b,\n x0: at(b.x0, fit.cx, fit.dx),\n y0: at(b.y0, fit.cy, fit.dy),\n x1: at(b.x1, fit.cx, fit.dx),\n y1: at(b.y1, fit.cy, fit.dy),\n };\n}\n\n/** How far past a block the layer it takes reaches (a card, a pill's shadow), as a share of the frame's side. */\nconst GROUP_REACH = 0.03;\n\n/** The block whose area (grown by `GROUP_REACH`) holds pixel `i`, or -1. */\nfunction blockAt(layer: WordsLayer, moves: readonly WordsMove[], i: number): number {\n const fx = ((i % layer.width) + 0.5) / layer.width;\n const fy = (Math.floor(i / layer.width) + 0.5) / layer.height;\n return moves.findIndex(\n (m) =>\n fx >= m.group.x0 - GROUP_REACH &&\n fx <= m.group.x1 + GROUP_REACH &&\n fy >= m.group.y0 - GROUP_REACH &&\n fy <= m.group.y1 + GROUP_REACH,\n );\n}\n\n/**\n * Which move owns each layer pixel: a pixel in a block's area (grown by `GROUP_REACH`), and every\n * layer pixel touching one, since a button's pill or a card reaches past the words read on it;\n * -1 for none.\n */\nfunction owners(layer: WordsLayer, moves: readonly WordsMove[]): Int16Array {\n const { width } = layer;\n const own = new Int16Array(width * layer.height).fill(-1);\n for (let i = 0; i < own.length; i++) if ((layer.alpha[i] ?? 0) > 0) own[i] = blockAt(layer, moves, i);\n spreadOwners(own, layer.alpha, width);\n return own;\n}\n\n/**\n * Each owned pixel's owner spread to the layer pixels it touches, depth first from the last owned\n * pixel. Every pixel enters the stack once: as a seed, or as it is claimed.\n */\nfunction spreadOwners(own: Int16Array, alpha: Float32Array, width: number): void {\n const { stack, seeds } = seedsOf(own);\n let top = seeds;\n const free = (n: number) => n >= 0 && n < own.length && (own[n] ?? -1) < 0 && (alpha[n] ?? 0) > 0;\n while (top > 0) {\n const i = stack[--top] ?? 0;\n const block = own[i] ?? -1;\n for (const n of touching(i, width)) {\n if (!free(n)) continue;\n own[n] = block;\n stack[top++] = n;\n }\n }\n}\n\n/** A stack with room for every pixel, the owned ones first, in order. */\nfunction seedsOf(own: Int16Array): { stack: Int32Array; seeds: number } {\n const stack = new Int32Array(own.length);\n let seeds = 0;\n for (let i = 0; i < own.length; i++) if ((own[i] ?? -1) >= 0) stack[seeds++] = i;\n return { stack, seeds };\n}\n\n/** Pixel `i`'s left, right, upper and lower neighbours in a frame `width` wide; -1 past a side edge. */\nfunction touching(i: number, width: number): number[] {\n const x = i % width;\n return [x > 0 ? i - 1 : -1, x < width - 1 ? i + 1 : -1, i - width, i + width];\n}\n\n/** Copies pixel `from` of `layer` to pixel `to` of `out`, when it takes more of the layer there than what `out` has. */\nfunction takePixel(out: WordsLayer, to: number, layer: WordsLayer, t: { at: number[]; w: number[] }): void {\n const a = tapped(layer.alpha, t);\n if (a <= (out.alpha[to] ?? 0)) return;\n out.alpha[to] = a;\n out.ink[to] = tapped(layer.ink, t);\n for (let c = 0; c < 3; c++) {\n out.pixels[to * 3 + c] = Math.round(tapped(layer.pixels, t, 3, c));\n out.gain[to * 3 + c] = tapped(layer.gain, t, 3, c, 1);\n }\n}\n\n/** Lays block `k` of `layer` (its pixels by `own`) onto `out`, moved by `fit`. */\nfunction moveBlock(out: WordsLayer, layer: WordsLayer, own: Int16Array, k: number, fit: WordsShift): void {\n const { width, height } = layer;\n const back = (p: number, c: number, d: number, size: number) =>\n c * size + (p + 0.5 - c * size - d * size) / fit.scale - 0.5;\n for (let i = 0; i < width * height; i++) {\n const u = back(i % width, fit.cx, fit.dx, width);\n const v = back(Math.floor(i / width), fit.cy, fit.dy, height);\n const inside = u >= 0 && v >= 0 && u <= width - 1 && v <= height - 1;\n if (inside && own[Math.round(v) * width + Math.round(u)] === k) takePixel(out, i, layer, taps(u, v, width, height));\n }\n}\n\n/**\n * The part of `layer` the blocks of `moves` own (`owners`): what a move takes with it, nothing\n * else of the layer. Its `alpha` is where the moved words were. Pure.\n */\nexport function movedPart(layer: WordsLayer, moves: readonly WordsMove[]): WordsLayer {\n const own = owners(layer, moves);\n const out = emptyLayer(layer.width, layer.height);\n for (let i = 0; i < own.length; i++) {\n if ((own[i] ?? -1) >= 0) takePixel(out, i, layer, { at: [i, i, i, i], w: [1, 0, 0, 0] });\n }\n return out;\n}\n\n/** The layer with each block moved by its own fit (bilinear): what a block leaves takes nothing, what no move owns stays. */\nexport function moveLayer(layer: WordsLayer, moves: readonly WordsMove[]): WordsLayer {\n const own = owners(layer, moves);\n const out = emptyLayer(layer.width, layer.height);\n for (let i = 0; i < own.length; i++) {\n if ((own[i] ?? -1) < 0 && (layer.alpha[i] ?? 0) > 0)\n takePixel(out, i, layer, { at: [i, i, i, i], w: [1, 0, 0, 0] });\n }\n for (const [k, { fit }] of moves.entries()) moveBlock(out, layer, own, k, fit);\n return out;\n}\n\n/** The part of `layer` inside the pixel rectangle `rect`. */\nexport function cropLayer(layer: WordsLayer, rect: Rect): WordsLayer {\n const out = emptyLayer(rect.width, rect.height);\n for (let y = 0; y < rect.height; y++) {\n const from = (rect.y + y) * layer.width + rect.x;\n const to = y * rect.width;\n out.alpha.set(layer.alpha.subarray(from, from + rect.width), to);\n out.ink.set(layer.ink.subarray(from, from + rect.width), to);\n out.gain.set(layer.gain.subarray(from * 3, (from + rect.width) * 3), to * 3);\n layer.pixels.copy(out.pixels, to * 3, from * 3, (from + rect.width) * 3);\n }\n return out;\n}\n","/**\n * The words model's render taken whole as a size of a static ad on one picture.\n *\n * Lettering a picture that already has its frame is what the model does well: its type, cards,\n * bands and pills come back clean. Keeping only what it changed at the words (`words-layer.ts`)\n * left their seams on the ad as boxes and smears. So the size is the model's render, lined up with\n * the cut, and only what must not change is put back from the picture: each person, face and\n * product (and the scene's own words) where the model redrew them, through a soft mask, toned to\n * the render's light. A render that moved the picture or redrew a subject is no lettering of the\n * picture; it is refused, and the size's words are set again.\n *\n * Pure: raw RGB buffers and fractions in, buffers and numbers out.\n */\nimport { blockingPlacements } from \"../../../scaffold/platform-safe-area.ts\";\nimport { bandViolations } from \"./band-check.ts\";\nimport { remembered } from \"./picture-memo.ts\";\nimport type { SubjectBox } from \"./subject-boxes.ts\";\nimport type { PixelRect } from \"./subject-crop.ts\";\nimport type { TextBox } from \"./text-boxes.ts\";\nimport { type BandMove, bandUnder, type LaidMap, laidAround, laidMap, moveBand } from \"./words-band.ts\";\nimport {\n compose,\n movedPart,\n movedSpan,\n moveLayer,\n padded,\n planWordsShift,\n type Raw,\n type Registration,\n registerToSource,\n type Span,\n type WordsMove,\n warpToCut,\n wordsLayer,\n} from \"./words-layer.ts\";\n\n/**\n * How the render (lined up) differs from the cut, per pixel. `structure`: the low-pass difference\n * once the render's own light is taken out (a scrim is a tone, a moved arm is not); `detail`: the\n * same, lightly blurred (what a redrawn face changes); `flat`: the render has no texture there;\n * `surface`: a flat card, band or pill the words sit on, laid over the picture, where it changed\n * it; `ground`: the same card to its edges, also where it hides the picture's texture without\n * changing its tone (a white card over a white shirt); `gain`: the render's light over the cut's,\n * three values a pixel.\n */\nexport type RenderDiff = {\n width: number;\n height: number;\n structure: Float32Array;\n detail: Float32Array;\n flat: Uint8Array;\n surface: Uint8Array;\n /** The cards, bands and pills the words sit on, to their edges: never put back from the picture. */\n readonly ground: Uint8Array;\n gain: Float32Array;\n};\n\nconst inSpans = (spans: readonly Span[], fx: number, fy: number) =>\n spans.some((s) => fx >= s.x0 && fx <= s.x1 && fy >= s.y0 && fy <= s.y1);\n\n/** One line of `src` (`n` values from `start`, `step` apart) averaged over 2r+1 values into `out`, its edges carried. */\nfunction blurLine(src: Float32Array, out: Float32Array, start: number, step: number, n: number, r: number): void {\n const last = start + (n - 1) * step;\n let acc = 0;\n for (let k = -r; k <= r; k++) acc += src[k <= 0 ? start : k >= n - 1 ? last : start + k * step] ?? 0;\n for (let k = 0; k < n; k++) {\n out[start + k * step] = acc / (2 * r + 1);\n const enter = k + r + 1;\n const leave = k - r;\n acc +=\n (src[enter >= n - 1 ? last : start + enter * step] ?? 0) - (src[leave <= 0 ? start : start + leave * step] ?? 0);\n }\n}\n\n/**\n * `blurLine` down every column of `src` at once, row by row: each column's running sum takes the\n * same values in the same order, read along the rows the frame is stored in.\n */\nfunction blurColumns(src: Float32Array, out: Float32Array, width: number, height: number, r: number): void {\n const acc = new Float64Array(width);\n const row = (k: number) => (k <= 0 ? 0 : k >= height - 1 ? height - 1 : k) * width;\n for (let k = -r; k <= r; k++) {\n const from = row(k);\n for (let x = 0; x < width; x++) acc[x] = (acc[x] ?? 0) + (src[from + x] ?? 0);\n }\n for (let k = 0; k < height; k++) {\n const to = k * width;\n const enter = row(k + r + 1);\n const leave = row(k - r);\n for (let x = 0; x < width; x++) {\n out[to + x] = (acc[x] ?? 0) / (2 * r + 1);\n acc[x] = (acc[x] ?? 0) + ((src[enter + x] ?? 0) - (src[leave + x] ?? 0));\n }\n }\n}\n\n/** `src` averaged over a (2r+1)² box, edges carried: rows, then columns, of running sums. */\nfunction boxBlur(src: Float32Array, width: number, height: number, r: number): Float32Array {\n if (r < 1) return Float32Array.from(src);\n const along = new Float32Array(width * height);\n for (let y = 0; y < height; y++) blurLine(src, along, y * width, 1, width, r);\n const out = new Float32Array(width * height);\n blurColumns(along, out, width, height, r);\n return out;\n}\n\n/** Two box passes: a tent, smooth enough for a tone or a mask. */\nconst soften = (src: Float32Array, width: number, height: number, r: number) =>\n boxBlur(boxBlur(src, width, height, r), width, height, r);\n\nfunction channelOf(img: Raw, c: number): Float32Array {\n const out = new Float32Array(img.width * img.height);\n for (let i = 0; i < out.length; i++) out[i] = img.data[i * img.channels + c] ?? 0;\n return out;\n}\n\n/** The radius structure is read at, as a share of the frame's width: a hand's width, never a strand of hair. */\nconst STRUCTURE_RADIUS = 0.008;\n/** The gain the render's light may apply either way: past it, it is not light but something else drawn there. */\nconst GAIN_MAX = 2.5;\n/** The local spread (grey levels) under which the render is flat there: a card, a band, a pill. */\nconst FLAT = 2.5;\n/** Structure differences under this (grey levels) are the same thing drawn again; over `MOVED`, something else. */\nexport const STILL = 14;\nexport const MOVED = 28;\n\n/** Where the render has no texture of its own (5×5 spread of its grey under `FLAT`). */\nfunction flatOf(img: Raw): Uint8Array {\n const { width, height } = img;\n const grey = new Float32Array(width * height);\n for (let i = 0; i < grey.length; i++) {\n const o = i * img.channels;\n grey[i] = 0.299 * (img.data[o] ?? 0) + 0.587 * (img.data[o + 1] ?? 0) + 0.114 * (img.data[o + 2] ?? 0);\n }\n const squares = new Float32Array(grey.length);\n for (let i = 0; i < grey.length; i++) squares[i] = (grey[i] ?? 0) * (grey[i] ?? 0);\n const mean = boxBlur(grey, width, height, 2);\n const square = boxBlur(squares, width, height, 2);\n const flat = new Uint8Array(mean.length);\n for (let i = 0; i < mean.length; i++) {\n const m = mean[i] ?? 0;\n flat[i] = Math.sqrt(Math.max(0, (square[i] ?? 0) - m * m)) < FLAT ? 1 : 0;\n }\n return flat;\n}\n\n/** A grid of square cells over a frame, `size` pixels a side. */\ntype CellGrid = { size: number; gw: number; gh: number };\n\nconst gridOver = (width: number, height: number, size: number): CellGrid => ({\n size,\n gw: Math.ceil(width / size),\n gh: Math.ceil(height / size),\n});\n\n/** The cell pixel `i` of a `width`-wide frame falls in. */\nfunction cellOf(grid: CellGrid, i: number, width: number): number {\n const x = i % width;\n return Math.floor((i - x) / width / grid.size) * grid.gw + Math.floor(x / grid.size);\n}\n\n/** The cells within `reach` of `g` (itself included), clipped to the grid. */\nfunction cellsNear(grid: CellGrid, g: number, reach: number): number[] {\n const gx = g % grid.gw;\n const gy = (g - gx) / grid.gw;\n const out: number[] = [];\n for (let ny = Math.max(0, gy - reach); ny <= Math.min(grid.gh - 1, gy + reach); ny++) {\n for (let nx = Math.max(0, gx - reach); nx <= Math.min(grid.gw - 1, gx + reach); nx++) out.push(ny * grid.gw + nx);\n }\n return out;\n}\n\n/** The grid a laid surface is followed on, in pixels a cell. */\nconst SURFACE_CELL = 8;\n\n/** The cells mostly flat in the render where the picture changed (1), as a laid card or band is. */\nfunction laidCells(flat: Uint8Array, structure: Float32Array, width: number, grid: CellGrid): Uint8Array {\n const laid = new Float32Array(grid.gw * grid.gh);\n const count = new Float32Array(grid.gw * grid.gh);\n for (let i = 0; i < flat.length; i++) {\n const g = cellOf(grid, i, width);\n count[g] = (count[g] ?? 0) + 1;\n if (flat[i] && (structure[i] ?? 0) > MOVED) laid[g] = (laid[g] ?? 0) + 1;\n }\n return Uint8Array.from(laid, (n, g) => (n >= (count[g] ?? 1) / 2 ? 1 : 0));\n}\n\n/** The cells a words box (fractions) reaches into. */\nfunction wordCells(words: readonly Span[], width: number, height: number, grid: CellGrid): number[] {\n const out: number[] = [];\n for (let g = 0; g < grid.gw * grid.gh; g++) {\n const gx = g % grid.gw;\n const gy = (g - gx) / grid.gw;\n const x0 = (gx * grid.size) / width;\n const y0 = (gy * grid.size) / height;\n const x1 = ((gx + 1) * grid.size) / width;\n const y1 = ((gy + 1) * grid.size) / height;\n if (words.some((w) => w.x0 < x1 && w.x1 > x0 && w.y0 < y1 && w.y1 > y0)) out.push(g);\n }\n return out;\n}\n\n/** Every cell reached from `seeds` through the cells `open` lets through (8-connected). */\nfunction flood(seeds: readonly number[], open: Uint8Array, grid: CellGrid): Uint8Array {\n const reached = new Uint8Array(grid.gw * grid.gh);\n for (const g of seeds) reached[g] = 1;\n const stack = [...seeds];\n while (stack.length > 0) {\n const next = cellsNear(grid, stack.pop() ?? 0, 1).filter((n) => !reached[n] && open[n]);\n for (const n of next) reached[n] = 1;\n stack.push(...next);\n }\n return reached;\n}\n\n/**\n * The cards, bands and pills the words sit on: flat in the render where the picture changed, and\n * joined to the words (a cell grid flooded from the words' boxes through cells mostly flat and\n * changed). A plain wall a moved subject left behind is flat too, but touches no words.\n */\nfunction surfaceOf(flat: Uint8Array, structure: Float32Array, width: number, height: number, words: readonly Span[]) {\n const grid = gridOver(width, height, SURFACE_CELL);\n const reached = flood(wordCells(words, width, height, grid), laidCells(flat, structure, width, grid), grid);\n const surface = new Uint8Array(structure.length);\n for (let y = 0; y < height; y++) {\n const row = Math.floor(y / grid.size) * grid.gw;\n for (let x = 0; x < width; x++) {\n const i = y * width + x;\n surface[i] = reached[row + Math.floor(x / grid.size)] && (structure[i] ?? 0) > MOVED ? 1 : 0;\n }\n }\n return surface;\n}\n\n/** How far (judged pixels) past a card's colour its own lines are: a hairline, a divider, its edge. */\nconst GROUND_LINE = 3;\n/** How close (levels, each channel) a pixel's colour is to a card's to be the card. */\nconst CARD_TONE = 16;\n/** The share of the line past a card's edge in its colour for the card to run on there. */\nconst CARD_RUN = 0.6;\n\n/** A half-open rectangle of pixels. */\ntype PxRect = { x0: number; y0: number; x1: number; y1: number };\n\n/** Whether pixel `i` of `img` is within `CARD_TONE` of `tone` on every channel. */\nconst inTone = (img: Raw, i: number, tone: readonly number[]) =>\n [0, 1, 2].every((c) => Math.abs((img.data[i * img.channels + c] ?? 0) - (tone[c] ?? 0)) <= CARD_TONE);\n\n/** The pixels of `r` inside the frame. */\nfunction* pixelsOf(r: PxRect, width: number, height: number): Generator<number> {\n for (let y = Math.max(0, r.y0); y < Math.min(height, r.y1); y++) {\n for (let x = Math.max(0, r.x0); x < Math.min(width, r.x1); x++) yield y * width + x;\n }\n}\n\n/** The four strips `depth` deep just past the sides of `r`: above, below, left, right. */\nconst stripsPast = (r: PxRect, depth: number): PxRect[] => [\n { ...r, y0: r.y0 - depth, y1: r.y0 },\n { ...r, y0: r.y1, y1: r.y1 + depth },\n { ...r, x0: r.x0 - depth, x1: r.x0 },\n { ...r, x0: r.x1, x1: r.x1 + depth },\n];\n\n/** Whether pixel `i` of a `width`-wide frame lies in one of `boxes`. */\nconst inBoxes = (boxes: readonly PxRect[], i: number, width: number) => {\n const x = i % width;\n const y = (i - x) / width;\n return boxes.some((b) => x >= b.x0 && x < b.x1 && y >= b.y0 && y < b.y1);\n};\n\n/**\n * The colour of the card a line of words sits on: the median of the flat pixels just around its\n * box, each channel, leaving out what lies in the other lines' boxes (a line set tight between two\n * others has their letters just above and below it). Null when too few of them are flat: words set\n * on the picture itself.\n */\nfunction cardTone(img: Raw, flat: Uint8Array, box: PxRect, others: readonly PxRect[] = []): number[] | null {\n const { width, height } = img;\n const around = stripsPast(box, GROUND_LINE)\n .flatMap((s) => [...pixelsOf(s, width, height)])\n .filter((i) => !inBoxes(others, i, width));\n const flatOnes = around.filter((i) => flat[i]);\n if (around.length === 0 || flatOnes.length < around.length / 2) return null;\n return [0, 1, 2].map((c) => {\n const values = flatOnes.map((i) => img.data[i * img.channels + c] ?? 0).sort((a, b) => a - b);\n return values[Math.floor(values.length / 2)] ?? 0;\n });\n}\n\n/** `r` grown by `by` pixels on side `side` (above, below, left, right). */\nconst grownBy = (r: PxRect, side: number, by: number): PxRect =>\n side === 0\n ? { ...r, y0: r.y0 - by }\n : side === 1\n ? { ...r, y1: r.y1 + by }\n : side === 2\n ? { ...r, x0: r.x0 - by }\n : { ...r, x1: r.x1 + by };\n\n/**\n * The card of colour `tone` around `box`: grown while a line just past each side is mostly that\n * colour, across a hairline or divider up to `GROUND_LINE` thick.\n */\nfunction cardAround(img: Raw, box: PxRect, tone: readonly number[]): PxRect {\n const { width, height } = img;\n const share = (s: PxRect) => {\n const px = [...pixelsOf(s, width, height)];\n return px.length > 0 ? px.filter((i) => inTone(img, i, tone)).length / px.length : 0;\n };\n // How far past side `side` of `r` the card runs on: the nearest line in its colour, else 0.\n const runs = (r: PxRect, side: number) => {\n for (let by = 1; by <= GROUND_LINE + 1; by++)\n if (share(stripsPast(grownBy(r, side, by - 1), 1)[side] ?? r) >= CARD_RUN) return by;\n return 0;\n };\n let r = box;\n for (let grew = true; grew; ) {\n grew = false;\n for (let side = 0; side < 4; side++) {\n const by = runs(r, side);\n if (by === 0) continue;\n r = grownBy(r, side, by);\n grew = true;\n }\n }\n return r;\n}\n\n/**\n * The cards, bands and pills the words sit on, to their edges (`RenderDiff.ground`): around each\n * line, the rectangle of its card's colour, and in it every pixel of that colour or within\n * `GROUND_LINE` of it (the card's hairlines and dividers), never a photo set on the card. A white\n * card over a white shirt changes little of its tone, but hides its folds.\n */\nfunction groundOf(aligned: Raw, flat: Uint8Array, words: readonly Span[]): Uint8Array {\n const { width, height } = aligned;\n const toned = new Float32Array(width * height);\n const inCard = new Uint8Array(width * height);\n const boxes = words.map((w) => ({\n x0: Math.max(0, Math.floor(w.x0 * width)),\n y0: Math.max(0, Math.floor(w.y0 * height)),\n x1: Math.min(width, Math.ceil(w.x1 * width)),\n y1: Math.min(height, Math.ceil(w.y1 * height)),\n }));\n for (const box of boxes) {\n const tone = cardTone(\n aligned,\n flat,\n box,\n boxes.filter((b) => b !== box),\n );\n if (!tone) continue;\n for (const i of pixelsOf(cardAround(aligned, box, tone), width, height)) {\n inCard[i] = 1;\n if (inTone(aligned, i, tone)) toned[i] = 1;\n }\n }\n const near = boxBlur(toned, width, height, GROUND_LINE);\n return Uint8Array.from(near, (v, i) => (v > 0 && inCard[i] ? 1 : 0));\n}\n\n/** Where the light is read from: everywhere but the words, which differ on purpose. */\nfunction trustOf(width: number, height: number, words: readonly Span[]): Float32Array {\n const trust = new Float32Array(width * height);\n for (let i = 0; i < trust.length; i++) {\n const x = i % width;\n trust[i] = inSpans(words, (x + 0.5) / width, ((i - x) / width + 0.5) / height) ? 0 : 1;\n }\n return trust;\n}\n\n/** One picture's three channels: as they are, low-passed (structure) and lightly blurred (detail). */\ntype Planes = { own: Float32Array[]; low: Float32Array[]; fine: Float32Array[] };\n\n/** A size's cut is judged against every render made for it: its planes and its shrunk pixels are read once. */\nconst cutPlanes = remembered<Planes>();\nconst shrunkCuts = remembered<Raw>();\n\nfunction planesOf(img: Raw, r1: number): Planes {\n const own = [0, 1, 2].map((c) => channelOf(img, c));\n return {\n own,\n low: own.map((p) => soften(p, img.width, img.height, r1)),\n fine: own.map((p) => boxBlur(p, img.width, img.height, 1)),\n };\n}\n\n/** The grid the render's light is read on, as a share of the frame's width (16 px at 1080). */\nconst LIGHT_CELL = 0.015;\n/** How many cells each way the light's median reaches: past a card's width, short of a scene's. */\nconst LIGHT_REACH = 3;\n\n/** Each cell's sums over the pixels `open` keeps: the render's three channels, the cut's three, and their count. */\nfunction cellSums(a: Planes, b: Planes, open: Float32Array, width: number, grid: CellGrid): Float32Array {\n const sums = new Float32Array(grid.gw * grid.gh * 7);\n const own = [...a.own, ...b.own];\n for (let i = 0; i < open.length; i++) {\n if (!open[i]) continue;\n const g = cellOf(grid, i, width) * 7;\n for (let c = 0; c < 6; c++) sums[g + c] = (sums[g + c] ?? 0) + (own[c]?.[i] ?? 0);\n sums[g + 6] = (sums[g + 6] ?? 0) + 1;\n }\n return sums;\n}\n\n/** Each cell's light ratio, per channel, over the pixels `open` keeps; NaN where too few are kept. */\nfunction cellRatios(a: Planes, b: Planes, open: Float32Array, width: number, grid: CellGrid): Float32Array {\n const sums = cellSums(a, b, open, width, grid);\n const ratio = new Float32Array(grid.gw * grid.gh * 3).fill(Number.NaN);\n for (let g = 0; g < grid.gw * grid.gh; g++) {\n const n = sums[g * 7 + 6] ?? 0;\n if (n < (grid.size * grid.size) / 4) continue;\n for (let c = 0; c < 3; c++) {\n ratio[g * 3 + c] = ((sums[g * 7 + c] ?? 0) / n + 8) / ((sums[g * 7 + 3 + c] ?? 0) / n + 8);\n }\n }\n return ratio;\n}\n\n/** The median of the known values (three a cell) in cells `near`, channel `c`, sorted in `scratch`; 1 when none is known. */\nfunction medianNear(values: Float32Array, near: readonly number[], c: number, scratch: Float64Array): number {\n let known = 0;\n for (const n of near) {\n const v = values[n * 3 + c] ?? Number.NaN;\n if (!Number.isNaN(v)) scratch[known++] = v;\n }\n if (known === 0) return 1;\n const sorted = scratch.subarray(0, known).sort();\n return sorted[Math.floor(known / 2)] ?? 1;\n}\n\n/** The median of the known values around each cell, per channel (1 where none is known), then a 3×3 mean. */\nfunction medianLight(ratio: Float32Array, grid: CellGrid): Float32Array {\n const cells = grid.gw * grid.gh;\n const median = new Float32Array(cells * 3);\n const scratch = new Float64Array((2 * LIGHT_REACH + 1) ** 2);\n for (let g = 0; g < cells; g++) {\n const near = cellsNear(grid, g, LIGHT_REACH);\n for (let c = 0; c < 3; c++) median[g * 3 + c] = medianNear(ratio, near, c, scratch);\n }\n const smooth = new Float32Array(cells * 3);\n for (let k = 0; k < cells * 3; k++) {\n const near = cellsNear(grid, Math.floor(k / 3), 1);\n smooth[k] = near.reduce((sum, n) => sum + (median[n * 3 + (k % 3)] ?? 1), 0) / near.length;\n }\n return smooth;\n}\n\n/**\n * The render's light over the cut's, per pixel and channel: each cell's ratio over the pixels\n * `open` keeps, the median of the cells around it (a card or a redrawn arm is a minority, a scrim\n * or a warmer grade is not), drawn smoothly between cell centres, kept within `GAIN_MAX`.\n */\nfunction lightOf(a: Planes, b: Planes, open: Float32Array, width: number, height: number): Float32Array {\n const grid = gridOver(width, height, Math.max(8, Math.round(width * LIGHT_CELL)));\n const light = medianLight(cellRatios(a, b, open, width, grid), grid);\n const gain = enlarge(light, { width: grid.gw, height: grid.gh }, { width, height }, 3);\n const kept = new Float32Array(gain.length);\n for (let i = 0; i < gain.length; i++) kept[i] = Math.min(GAIN_MAX, Math.max(1 / GAIN_MAX, gain[i] ?? 0));\n return kept;\n}\n\n/** The structure and detail differences of the render from the cut in `gain`'s light, largest channel. */\nfunction compared(a: Planes, b: Planes, gain: Float32Array, n: number) {\n const structure = new Float32Array(n);\n const detail = new Float32Array(n);\n for (let c = 0; c < 3; c++) {\n const [aLow, bLow, aFine, bFine] = [a.low[c], b.low[c], a.fine[c], b.fine[c]];\n for (let i = 0; i < n; i++) {\n const g = gain[i * 3 + c] ?? 1;\n structure[i] = Math.max(structure[i] ?? 0, Math.abs((aLow?.[i] ?? 0) - g * (bLow?.[i] ?? 0)));\n detail[i] = Math.max(detail[i] ?? 0, Math.abs((aFine?.[i] ?? 0) - g * (bFine?.[i] ?? 0)));\n }\n }\n return { structure, detail };\n}\n\n/**\n * How `aligned` (the words render, lined up with the cut) differs from `cut`, in the render's\n * light, read off everything but `words` (padded boxes, fractions). Pure.\n */\nexport function renderDiff(aligned: Raw, cut: Raw, words: readonly Span[]): RenderDiff {\n const { width, height } = cut;\n const r1 = Math.max(2, Math.round(width * STRUCTURE_RADIUS));\n const a = planesOf(aligned, r1);\n const b = cutPlanes(cut, String(r1), () => planesOf(cut, r1));\n const gain = lightOf(a, b, trustOf(width, height, words), width, height);\n const { structure, detail } = compared(a, b, gain, width * height);\n const flat = flatOf(aligned);\n const surface = surfaceOf(flat, structure, width, height, words);\n let ground: Uint8Array | undefined;\n return {\n width,\n height,\n structure,\n detail,\n flat,\n surface,\n gain,\n // Read only to put a subject back: a render refused is never read for it.\n get ground() {\n ground ??= groundOf(aligned, flat, words);\n return ground;\n },\n };\n}\n\n/**\n * How a subject fared in the render: `shown`, the share of its box neither under the words\n * (`words`, padded boxes) nor under a card or band laid over it; `moved`, the share of what the\n * words leave of it whose structure changed with no surface there (it moved, or was drawn in\n * another pose); `drift`, the mean detail difference where its structure held (a face drawn\n * again). Pure.\n */\nexport function subjectDrift(\n diff: RenderDiff,\n subject: Span,\n words: readonly Span[],\n): { shown: number; moved: number; drift: number } {\n const { width, height } = diff;\n const x0 = Math.max(0, Math.floor(subject.x0 * width));\n const x1 = Math.min(width, Math.ceil(subject.x1 * width));\n const y0 = Math.max(0, Math.floor(subject.y0 * height));\n const y1 = Math.min(height, Math.ceil(subject.y1 * height));\n const n = { all: 0, open: 0, covered: 0, moved: 0, drift: 0, held: 0 };\n for (let y = y0; y < y1; y++) {\n for (let x = x0; x < x1; x++) {\n n.all++;\n if (!inSpans(words, (x + 0.5) / width, (y + 0.5) / height)) countDrift(n, diff, y * width + x);\n }\n }\n return {\n shown: n.all > 0 ? (n.open - n.covered) / n.all : 0,\n moved: n.open > 0 ? n.moved / n.open : 0,\n drift: n.held > 0 ? n.drift / n.held : 0,\n };\n}\n\n/** Counts pixel `i`, off the words, as held (and how far its detail drifted), covered by a surface, or moved. */\nfunction countDrift(\n n: { open: number; covered: number; moved: number; drift: number; held: number },\n diff: RenderDiff,\n i: number,\n): void {\n n.open++;\n if ((diff.structure[i] ?? 0) <= MOVED) {\n n.drift += diff.detail[i] ?? 0;\n n.held++;\n } else if (diff.surface[i]) n.covered++;\n else n.moved++;\n}\n\n/**\n * A subject whose detail drifted more than this (mean grey levels, judged at half a delivered\n * size's pixels) is put back from the picture. Dev, Oct 2026: faces GPT lettered around drifted\n * 3.0-5.5, a round photo it drew again in place 20-22; under 3 nobody tells the two apart.\n */\nconst DRIFTED = 3;\n/**\n * The least `keptShare` of a render that lettered the picture. Dev, Oct 2026 (16 words renders on\n * two companies, judged at half their pixels): every render that kept the picture in place kept\n * 0.83 or more, every one that shrank or moved it 0.69 or less.\n */\nconst MIN_KEPT = 0.75;\n/** The most of the frame's side the line-up may bring in from past the render's edge: a few pixels of carried edge. */\nconst MAX_CARRIED = 0.005;\n/**\n * The share of a subject (`subjectDrift` `moved`) past which the model drew it elsewhere or in\n * another pose. Dev, Oct 2026: subjects lettered around moved 0.14 or less; a head turned, or a\n * round photo moved inside its card, 0.36 or more.\n */\nconst REDRAWN = 0.2;\n\n/** What was read of one render taken whole: what it kept, and what became of its subjects and its words. */\nexport type WholeReading = {\n /** `keptShare`. */\n kept: number;\n /** How much of the size's frame the line-up brings in from past the render's edge, a share of its side. */\n carried: number;\n subjects: ReadonlyArray<{ label: string; moved: number; drift: number; shown: number }>;\n /** `wordsLost`. */\n lost: readonly string[];\n /** `wordsOnFaces`. */\n onFace: readonly string[];\n};\n\n/** Why a render cannot be the size as it is. */\nexport const WHOLE_PROBLEMS = [\"picture_moved\", \"subject_redrawn\", \"words_lost\", \"words_over_face\"] as const;\nexport type WholeProblem = (typeof WHOLE_PROBLEMS)[number];\n\nexport type WholeVerdict = { ok: true; restore: string[] } | { ok: false; problem: WholeProblem; what: string[] };\n\n/**\n * Whether a render can be the size as it is: taken, with the subjects it drew again put back\n * (`restore`, by label), or refused with what was wrong. Pure.\n */\nexport function wholeVerdict(r: WholeReading): WholeVerdict {\n if (r.kept < MIN_KEPT || r.carried > MAX_CARRIED) return { ok: false, problem: \"picture_moved\", what: [] };\n const redrawn = r.subjects.filter((s) => s.moved > REDRAWN).map((s) => s.label);\n if (redrawn.length > 0) return { ok: false, problem: \"subject_redrawn\", what: redrawn };\n if (r.lost.length > 0) return { ok: false, problem: \"words_lost\", what: [...r.lost] };\n if (r.onFace.length > 0) return { ok: false, problem: \"words_over_face\", what: [...r.onFace] };\n return { ok: true, restore: r.subjects.filter((s) => s.drift > DRIFTED).map((s) => s.label) };\n}\n\n/** A grey picture, `width` × `height`. */\ntype Grey = { data: Float32Array; width: number; height: number };\n\n/** `img` in grey, averaged down by a whole factor `f`. */\nfunction greyOf(img: Raw, f: number): Grey {\n const width = Math.max(1, Math.floor(img.width / f));\n const height = Math.max(1, Math.floor(img.height / f));\n const data = new Float32Array(width * height);\n for (let i = 0; i < width * height; i++) {\n const x = (i % width) * f;\n const y = Math.floor(i / width) * f;\n let sum = 0;\n for (let j = 0; j < f; j++) {\n for (let k = 0; k < f; k++) {\n const o = ((y + j) * img.width + x + k) * img.channels;\n sum += 0.299 * (img.data[o] ?? 0) + 0.587 * (img.data[o + 1] ?? 0) + 0.114 * (img.data[o + 2] ?? 0);\n }\n }\n data[i] = sum / (f * f);\n }\n return { data, width, height };\n}\n\n/** A candidate place for a subject: moved by (dx, dy) pixels, scaled by `scale` about its centre. */\ntype Place = { dx: number; dy: number; scale: number };\n\n/**\n * How alike the cut's patch (`box`, pixels of `cut`) and the render are once the patch is put at\n * `place`: normalized cross-correlation, -1 when the patch would leave the render.\n */\nfunction likeness(render: Grey, cut: Grey, box: PixelRect, place: Place): number {\n const cx = box.x + box.width / 2;\n const cy = box.y + box.height / 2;\n const n = { count: 0, a: 0, c: 0, aa: 0, cc: 0, ac: 0 };\n for (let y = box.y; y < box.y + box.height; y++) {\n for (let x = box.x; x < box.x + box.width; x++) {\n const u = Math.round(cx + place.scale * (x - cx) + place.dx);\n const v = Math.round(cy + place.scale * (y - cy) + place.dy);\n if (u < 0 || v < 0 || u >= render.width || v >= render.height) return -1;\n const a = render.data[v * render.width + u] ?? 0;\n const c = cut.data[y * cut.width + x] ?? 0;\n n.count++;\n n.a += a;\n n.c += c;\n n.aa += a * a;\n n.cc += c * c;\n n.ac += a * c;\n }\n }\n const va = n.aa - (n.a * n.a) / n.count;\n const vc = n.cc - (n.c * n.c) / n.count;\n return va > 1e-6 && vc > 1e-6 ? (n.ac - (n.a * n.c) / n.count) / Math.sqrt(va * vc) : -1;\n}\n\n/** The pixel box of `s` inside a `g`, without `inset` of its size on each side (the background at its corners). */\nfunction boxIn(s: Span, g: Grey, inset: number): PixelRect {\n const w = (s.x1 - s.x0) * g.width;\n const h = (s.y1 - s.y0) * g.height;\n const x = Math.max(0, Math.round(s.x0 * g.width + inset * w));\n const y = Math.max(0, Math.round(s.y0 * g.height + inset * h));\n return {\n x,\n y,\n width: Math.max(1, Math.min(g.width - x, Math.round(w * (1 - 2 * inset)))),\n height: Math.max(1, Math.min(g.height - y, Math.round(h * (1 - 2 * inset)))),\n };\n}\n\n/** The best place among `places` for the cut's patch in the render. */\nfunction bestPlace(render: Grey, cut: Grey, box: PixelRect, places: Iterable<Place>): Place & { score: number } {\n let best = { dx: 0, dy: 0, scale: 1, score: -2 };\n for (const place of places) {\n const score = likeness(render, cut, box, place);\n if (score > best.score) best = { ...place, score };\n }\n return best;\n}\n\n/** How far a subject is looked for, as a share of the frame each way, and at which sizes. */\nconst TRACK_REACH = 0.25;\nconst TRACK_SCALES = [0.85, 0.92, 1, 1.08, 1.15];\n/** The frame's width the search first runs at, in pixels. */\nconst TRACK_WIDTH = 180;\n\n/** Every place within `reach` pixels each way of `around`, at each of `scales`. */\nfunction* placesNear(around: Place, reach: number, scales: readonly number[]): Generator<Place> {\n for (const scale of scales) {\n for (let dy = -reach; dy <= reach; dy++) {\n for (let dx = -reach; dx <= reach; dx++) yield { dx: around.dx + dx, dy: around.dy + dy, scale };\n }\n }\n}\n\n/**\n * Where `subject` (a box of the cut, fractions) went in the render: the shift (fractions of the\n * frame) and scale at which the cut's own patch matches the render best, and how well (`score`,\n * normalized cross-correlation: near 1 for the same photo moved, low for one drawn again). Searched\n * coarse, a quarter of the frame each way, then refined at the given pixels. Pure.\n */\nexport function tracked(\n aligned: Raw,\n cut: Raw,\n subject: Span,\n): { dx: number; dy: number; scale: number; score: number } {\n const f = Math.max(1, Math.round(cut.width / TRACK_WIDTH));\n const coarse = { render: greyOf(aligned, f), cut: greyOf(cut, f) };\n const reach = Math.round(TRACK_REACH * coarse.cut.width);\n const found = bestPlace(\n coarse.render,\n coarse.cut,\n boxIn(subject, coarse.cut, 0.1),\n placesNear({ dx: 0, dy: 0, scale: 1 }, reach, TRACK_SCALES),\n );\n const fine = { render: greyOf(aligned, 1), cut: greyOf(cut, 1) };\n const near = [found.scale - 0.03, found.scale, found.scale + 0.03];\n const refined = bestPlace(\n fine.render,\n fine.cut,\n boxIn(subject, fine.cut, 0.1),\n placesNear({ dx: found.dx * f, dy: found.dy * f, scale: 1 }, f, near),\n );\n return {\n dx: refined.dx / cut.width,\n dy: refined.dy / cut.height,\n scale: refined.scale,\n score: refined.score,\n };\n}\n\n/** How much of a face's box, on each side, is its edge (hair, ears, the background at its corners) rather than the face. */\nconst FACE_EDGE = 0.15;\n\n/**\n * The faces (fractions of the render) whose middle a designed line covers: the box without its\n * edges, so a line that reaches the hair beside a face hides nothing. Pure.\n */\nexport function wordsOnFaces(words: readonly Span[], faces: ReadonlyArray<Span & { label: string }>): string[] {\n return facesUnder(words, faces).map((f) => f.label);\n}\n\n/** The faces whose middle a designed line covers (`wordsOnFaces`), themselves. */\nfunction facesUnder<T extends Span>(words: readonly Span[], faces: readonly T[]): T[] {\n return faces.filter((f) => {\n const dx = FACE_EDGE * (f.x1 - f.x0);\n const dy = FACE_EDGE * (f.y1 - f.y0);\n return words.some((w) => w.x0 < f.x1 - dx && w.x1 > f.x0 + dx && w.y0 < f.y1 - dy && w.y1 > f.y0 + dy);\n });\n}\n\n/**\n * How close to the size's frame a line may come (a share of its side) and not read as cut by it:\n * the review called a 4:5's headline 0.7% from its top cut, and its button's pill 0.1% past its\n * bottom clipped (dev, Oct 2026).\n */\nconst FRAME_MARGIN = 0.01;\n\n/**\n * The designed lines (fractions of the size's frame) the size loses: cut by its frame or so close\n * to it they read as cut, or under the interface its placements draw (`blockingPlacements`, as the\n * review blocks). A line only near that interface is kept, as the review keeps it. Pure.\n */\nexport function wordsLost(\n words: readonly TextBox[],\n format: string,\n placements?: readonly string[],\n keepOut: readonly Span[] = [],\n): string[] {\n const cut = words.filter(\n (b) =>\n b.x0 < FRAME_MARGIN ||\n b.y0 < FRAME_MARGIN ||\n b.x1 > 1 - FRAME_MARGIN ||\n b.y1 > 1 - FRAME_MARGIN ||\n keepOut.some((k) => overlaps(b, k)),\n );\n const covered = bandViolations(\n words.filter((b) => !cut.includes(b)),\n format,\n { placements: blockingPlacements(placements) },\n ).filter((v) => v.covered);\n return [...cut.map((b) => b.text), ...covered.map((v) => v.text)];\n}\n\n/** How far past a subject's box its restore fades out, as a share of the box's longer side: hair and shoulders reach past a box. */\nconst ZONE_MARGIN = 0.12;\n/** The feather of the restore's own edge, as a share of the frame's width. */\nconst FEATHER = 0.004;\n\n/** 1 inside `zone`, falling smoothly to 0 over its margin past it, the corners round; added into `into` as a maximum. */\nfunction addZone(into: Float32Array, zone: Span, width: number, height: number): void {\n const x0 = zone.x0 * width;\n const x1 = zone.x1 * width;\n const y0 = zone.y0 * height;\n const y1 = zone.y1 * height;\n const margin = Math.max(4, ZONE_MARGIN * Math.max(x1 - x0, y1 - y0));\n for (let y = Math.max(0, Math.floor(y0 - margin)); y < Math.min(height, Math.ceil(y1 + margin)); y++) {\n for (let x = Math.max(0, Math.floor(x0 - margin)); x < Math.min(width, Math.ceil(x1 + margin)); x++) {\n const dx = Math.max(0, x0 - (x + 0.5), x + 0.5 - x1);\n const dy = Math.max(0, y0 - (y + 0.5), y + 0.5 - y1);\n const t = 1 - Math.min(1, Math.sqrt(dx * dx + dy * dy) / margin);\n const i = y * width + x;\n into[i] = Math.max(into[i] ?? 0, t * t * (3 - 2 * t));\n }\n }\n}\n\n/**\n * Where the picture goes back over the render, 0 to 1 a pixel: each zone (a subject to put back,\n * fractions) fading out past its box, as far as its structure still matches the render's (`STILL`\n * to `MOVED`: a card laid over it stays the render's), feathered, and never on the words (padded\n * boxes). No edge of it is a rectangle. Pure.\n */\nexport function restoreMask(diff: RenderDiff, zones: readonly Span[], words: readonly Span[]): Float32Array {\n const { width, height } = diff;\n const zone = new Float32Array(width * height);\n for (const z of zones) addZone(zone, z, width, height);\n // What the render laid flat over the picture (a card, a band, a pill) stays the render's to its last pixel.\n const laid = boxBlur(\n Float32Array.from(diff.flat, (f, i) => ((f && (diff.detail[i] ?? 0) > KEPT_DETAIL) || diff.ground[i] ? 1 : 0)),\n width,\n height,\n 1,\n );\n const off = trustOf(width, height, words).map((t, i) => (t > 0 && (laid[i] ?? 0) === 0 ? 0 : 1));\n const held = zone.map((z, i) =>\n z > 0 && !off[i] ? z * Math.min(1, Math.max(0, (MOVED - (diff.structure[i] ?? 0)) / (MOVED - STILL))) : 0,\n );\n const feathered = soften(held, width, height, Math.max(2, Math.round(width * FEATHER)));\n return feathered.map((m, i) => (off[i] ? 0 : m));\n}\n\n/**\n * The render with the cut put back under `mask`, each put-back pixel the cut's in the render's\n * light (`gain`, three values a pixel: `RenderDiff.gain`), so a subject comes back as the picture\n * drew it and lit as the render is: no edge where the two meet. Where the mask is 0 the pixel is\n * the render's own. Pure.\n */\nexport function restoreSubjects(aligned: Raw, cut: Raw, gain: Float32Array, mask: Float32Array): Raw {\n const { width, height } = cut;\n const out = Buffer.alloc(width * height * 3);\n for (let i = 0; i < width * height; i++) {\n const m = mask[i] ?? 0;\n for (let c = 0; c < 3; c++) {\n const own = aligned.data[i * aligned.channels + c] ?? 0;\n if (m <= 0) {\n out[i * 3 + c] = own;\n continue;\n }\n const back = Math.min(255, (cut.data[i * cut.channels + c] ?? 0) * (gain[i * 3 + c] ?? 1));\n out[i * 3 + c] = Math.round(own * (1 - m) + back * m);\n }\n }\n return { data: out, width, height, channels: 3 };\n}\n\n/** A detail difference under this (grey levels) is the picture's own pixel drawn again in place. */\nconst KEPT_DETAIL = 24;\n\n/**\n * The share of the picture's textured pixels (outside `words` and the surfaces laid for them) the\n * render kept where they were: near 1 when the model lettered the picture, low when it shrank,\n * moved or reframed it. Pure.\n */\nexport function keptShare(diff: RenderDiff, words: readonly Span[]): number {\n const { width, height } = diff;\n let textured = 0;\n let kept = 0;\n for (let i = 0; i < width * height; i++) {\n if (diff.flat[i] || diff.surface[i]) continue;\n const x = i % width;\n if (inSpans(words, (x + 0.5) / width, ((i - x) / width + 0.5) / height)) continue;\n textured++;\n if ((diff.detail[i] ?? 0) < KEPT_DETAIL) kept++;\n }\n return textured > 0 ? kept / textured : 1;\n}\n\n/** The pixel rectangle `rect` of `img`, as RGB. */\nexport function cropRaw(img: Raw, rect: PixelRect): Raw {\n const data = Buffer.alloc(rect.width * rect.height * 3);\n for (let y = 0; y < rect.height; y++) {\n const from = ((rect.y + y) * img.width + rect.x) * img.channels;\n if (img.channels === 3) {\n img.data.copy(data, y * rect.width * 3, from, from + rect.width * 3);\n continue;\n }\n for (let x = 0; x < rect.width; x++) {\n for (let c = 0; c < 3; c++) data[(y * rect.width + x) * 3 + c] = img.data[from + x * img.channels + c] ?? 0;\n }\n }\n return { data, width: rect.width, height: rect.height, channels: 3 };\n}\n\n/** How much of `frame` (inside a `width`×`height` render) `fit` brings in from past the render's edge, a share of its side. */\nfunction carriedBy(fit: Registration, frame: PixelRect, width: number, height: number): number {\n const at = (x: number, y: number) => [\n width / 2 + fit.scale * (x - width / 2) + fit.dx,\n height / 2 + fit.scale * (y - height / 2) + fit.dy,\n ];\n const [left = 0, top = 0] = at(frame.x, frame.y);\n const [right = 0, bottom = 0] = at(frame.x + frame.width, frame.y + frame.height);\n return Math.max(\n 0,\n -left / frame.width,\n -top / frame.height,\n (right - width) / frame.width,\n (bottom - height) / frame.height,\n );\n}\n\n/** A subject is hidden by the words when less than this share of its box shows. */\nconst SHOWN_MIN = 0.5;\n/** The widest frame a render is judged at: a delivered size is judged at half its pixels, and put back at full. */\nconst JUDGED_WIDTH = 720;\n\n/** `img` averaged down by a whole factor `f`. */\nfunction shrinkRaw(img: Raw, f: number): Raw {\n const width = Math.floor(img.width / f);\n const height = Math.floor(img.height / f);\n const data = Buffer.alloc(width * height * 3);\n for (let i = 0; i < width * height; i++) {\n const x = (i % width) * f;\n const y = Math.floor(i / width) * f;\n for (let c = 0; c < 3; c++) {\n let sum = 0;\n for (let j = 0; j < f; j++) {\n const row = ((y + j) * img.width + x) * img.channels + c;\n for (let k = 0; k < f; k++) sum += img.data[row + k * img.channels] ?? 0;\n }\n data[i * 3 + c] = Math.round(sum / (f * f));\n }\n }\n return { data, width, height, channels: 3 };\n}\n\n/** For each position along one axis, the two it falls between and how far past the first. */\ntype Taps = { near: Int32Array; far: Int32Array; t: Float32Array };\n\n/** For each of `to` positions along one axis, the two of `from` it falls between and how far past the first. */\nfunction axisTaps(from: number, to: number): Taps {\n const near = new Int32Array(to);\n const far = new Int32Array(to);\n const t = new Float32Array(to);\n for (let k = 0; k < to; k++) {\n const u = Math.min(from - 1, Math.max(0, ((k + 0.5) * from) / to - 0.5));\n near[k] = Math.floor(u);\n far[k] = Math.min(from - 1, Math.floor(u) + 1);\n t[k] = u - Math.floor(u);\n }\n return { near, far, t };\n}\n\n/** Output row `y` of `enlarge`, from input rows `top` and `bottom` (pixel offsets), `fy` between them. */\nfunction enlargeRow(\n values: Float32Array,\n out: Float32Array,\n xs: Taps,\n row: { y: number; top: number; bottom: number; fy: number; width: number },\n stride: number,\n): void {\n const { top, bottom, fy } = row;\n for (let x = 0; x < row.width; x++) {\n const left = xs.near[x] ?? 0;\n const right = xs.far[x] ?? 0;\n const fx = xs.t[x] ?? 0;\n const o = (row.y * row.width + x) * stride;\n for (let c = 0; c < stride; c++) {\n const upper =\n (values[(top + left) * stride + c] ?? 0) * (1 - fx) + (values[(top + right) * stride + c] ?? 0) * fx;\n const lower =\n (values[(bottom + left) * stride + c] ?? 0) * (1 - fx) + (values[(bottom + right) * stride + c] ?? 0) * fx;\n out[o + c] = upper * (1 - fy) + lower * fy;\n }\n }\n}\n\n/** `values` (`stride` a pixel, `from` pixels) drawn at `to` pixels, bilinear. */\nfunction enlarge(\n values: Float32Array,\n from: { width: number; height: number },\n to: { width: number; height: number },\n stride: number,\n): Float32Array {\n if (from.width === to.width && from.height === to.height) return values;\n const xs = axisTaps(from.width, to.width);\n const ys = axisTaps(from.height, to.height);\n const out = new Float32Array(to.width * to.height * stride);\n for (let y = 0; y < to.height; y++) {\n const top = (ys.near[y] ?? 0) * from.width;\n const bottom = (ys.far[y] ?? 0) * from.width;\n enlargeRow(values, out, xs, { y, top, bottom, fy: ys.t[y] ?? 0, width: to.width }, stride);\n }\n return out;\n}\n\n/** What a size's words render is taken whole with: the render, the cut it lettered, and what was read on both. */\nexport type WholeInput = {\n /** The words model's render and the cut it was shown, at the same (work) pixels. */\n render: Raw;\n cut: Raw;\n /** The size's own frame inside them. */\n frame: PixelRect;\n /** The render's designed words and the scene's own lines, as read on it (fractions); null when nobody could read them. */\n words: { designed: readonly TextBox[]; inScene: readonly TextBox[] } | null;\n /** The people, faces, animals and products of the cut (fractions). */\n subjects: readonly SubjectBox[];\n format: string;\n placements?: readonly string[];\n /** The smallest scale a block of words is moved at (`planWordsShift`). */\n minScale?: number;\n /** Where no word may sit (the slot kept for the logo file), fractions of the size's frame. */\n keepOut?: readonly Span[];\n};\n\n/**\n * The render taken whole: `out`, the size (its frame, lined up with the cut), with the subjects\n * it redrew put back (`restored`) and each block of words code moved (`moves`, fractions of the\n * size); `covered`, the products and animals its words hide most of. Refused with `problem` when\n * it cannot be the size as it is.\n */\nexport type WholeTake =\n | {\n ok: true;\n out: Raw;\n restored: string[];\n covered: string[];\n moves: WordsMove[];\n kept: number;\n residual: number;\n }\n | {\n ok: false;\n problem: WholeProblem;\n what: string[];\n kept: number;\n residual: number;\n /** When only where its words sit is wrong: the render as it is, its subjects put back. */\n whole?: { out: Raw; restored: string[]; covered: string[] };\n };\n\n/** A move planned on the size's frame, as fractions of the whole render the frame sits in. */\nfunction moveOnRender(m: WordsMove, frame: PixelRect, width: number, height: number): WordsMove {\n const x = (v: number) => (frame.x + v * frame.width) / width;\n const y = (v: number) => (frame.y + v * frame.height) / height;\n return {\n group: { x0: x(m.group.x0), y0: y(m.group.y0), x1: x(m.group.x1), y1: y(m.group.y1) },\n fit: {\n scale: m.fit.scale,\n cx: x(m.fit.cx),\n cy: y(m.fit.cy),\n dx: (m.fit.dx * frame.width) / width,\n dy: (m.fit.dy * frame.height) / height,\n },\n };\n}\n\n/** What `placeWords` is given: the render lined up, the cut, the size so far, the light, and where the words sit. */\ntype Placing = {\n aligned: Raw;\n cut: Raw;\n out: Raw;\n gain: Float32Array;\n /** The render lined up and the cut, at the pixels they are judged at: what lies around each block. */\n judged: { aligned: Raw; cut: Raw };\n frame: PixelRect;\n words: { designed: readonly TextBox[]; inScene: readonly TextBox[] };\n subjects: readonly SubjectBox[];\n format: string;\n placements?: readonly string[];\n minScale?: number;\n keepOut?: readonly Span[];\n};\n\n/** Two spans overlap. */\nconst overlaps = (a: Span, b: Span) => a.x0 < b.x1 && a.x1 > b.x0 && a.y0 < b.y1 && a.y1 > b.y0;\n\n/** `box` moved by (`dx`, `dy`). */\nconst shifted = <T extends Span>(box: T, dx: number, dy: number): T => ({\n ...box,\n x0: box.x0 + dx,\n y0: box.y0 + dy,\n x1: box.x1 + dx,\n y1: box.y1 + dy,\n});\n\n/** The block of `moves` that holds `box` (its middle inside the block), if any. */\nconst moveOf = (box: Span, moves: readonly WordsMove[]) =>\n moves.find((m) => inSpans([m.group], (box.x0 + box.x1) / 2, (box.y0 + box.y1) / 2));\n\n/** The smallest span holding `a` and `b`. */\nconst hull = (a: Span, b: Span): Span => ({\n x0: Math.min(a.x0, b.x0),\n y0: Math.min(a.y0, b.y0),\n x1: Math.max(a.x1, b.x1),\n y1: Math.max(a.y1, b.y1),\n});\n\n/**\n * Words are lifted off the render alone only where it laid nothing around them past this share:\n * a quote on a soft glow (3-6% of its ring) came off with squares of the glow (dev, Oct 2026).\n */\nconst BARE = 0.02;\n\n/** The size's frame, as fractions of the `width`×`height` render it sits in. */\nconst frameSpan = (frame: PixelRect, width: number, height: number): Span => ({\n x0: frame.x / width,\n y0: frame.y / height,\n x1: (frame.x + frame.width) / width,\n y1: (frame.y + frame.height) / height,\n});\n\n/** How far past the frame's edge (a share of its side) a card runs before the frame cuts it. */\nconst CARD_CUT = 0.005;\n\n/**\n * Whether `band` (render fractions) is a card the frame `f` cuts: it runs past an edge, and is no\n * band spanning the frame from side to side across that edge (a band runs off the frame by design).\n */\nfunction cardCut(band: Span, f: Span): boolean {\n const w = f.x1 - f.x0;\n const h = f.y1 - f.y0;\n const across = band.x0 <= f.x0 + FRAME_MARGIN * w && band.x1 >= f.x1 - FRAME_MARGIN * w;\n const down = band.y0 <= f.y0 + FRAME_MARGIN * h && band.y1 >= f.y1 - FRAME_MARGIN * h;\n const pastY = band.y0 < f.y0 - CARD_CUT * h || band.y1 > f.y1 + CARD_CUT * h;\n const pastX = band.x0 < f.x0 - CARD_CUT * w || band.x1 > f.x1 + CARD_CUT * w;\n return (pastY && !across) || (pastX && !down);\n}\n\n/** The card (render fractions) a designed line sits on when the size's frame cuts it, else null. */\nfunction cutCardOf(laid: LaidMap, line: Span, f: Span): Span | null {\n const band = bandUnder(laid, line);\n return band && cardCut(band, f) ? band : null;\n}\n\n/** The boxes, one for each place (lines placed as one card are one box). */\nconst unique = (boxes: readonly TextBox[]): TextBox[] =>\n boxes.filter(\n (b, i) => boxes.findIndex((o) => o.x0 === b.x0 && o.y0 === b.y0 && o.x1 === b.x1 && o.y1 === b.y1) === i,\n );\n\n/** The spans, those that overlap merged into one. */\nfunction merged(spans: readonly Span[]): Span[] {\n const out: Span[] = [];\n for (const s of spans) {\n let joined = s;\n for (let i = out.length - 1; i >= 0; i--) {\n const o = out[i];\n if (o && overlaps(o, joined)) {\n joined = hull(o, joined);\n out.splice(i, 1);\n }\n }\n out.push(joined);\n }\n return out;\n}\n\n/**\n * What the lines of block `m` sit on: the bands, cards and pills (render fractions, one for lines\n * on the same), `picture` when every line sits on the picture itself, `mixed` when only some do.\n */\nfunction carriersOf(m: WordsMove, laid: LaidMap, designed: readonly TextBox[]): Span[] | \"picture\" | \"mixed\" {\n const lines = designed.filter((b) => inSpans([m.group], (b.x0 + b.x1) / 2, (b.y0 + b.y1) / 2));\n const bands = lines.flatMap((b) => {\n const band = bandUnder(laid, b);\n return band ? [band] : [];\n });\n if (bands.length === 0) return \"picture\";\n return bands.length < lines.length ? \"mixed\" : merged(bands);\n}\n\n/**\n * Each block of `banded` (blocks of `moves` on a band, card or pill) as that band moved with it\n * (render fractions): never scaled, never landing on a face, every line it carries still clear\n * of the frame and the app where it lands, and every other line, where it ends up, clear of where\n * the band was and goes. Null when a band cannot be found or moved so: the words are set again.\n */\nfunction bandMoves(\n banded: ReadonlyArray<{ move: WordsMove; band: Span }>,\n moves: readonly WordsMove[],\n p: Placing,\n at: { inFrame: (b: TextBox) => TextBox; extent: (b: TextBox) => Span },\n): BandMove[] | null {\n const faces = p.subjects.filter((s) => s.kind === \"face\");\n const out: BandMove[] = [];\n for (const { move: m, band } of banded) {\n if (m.fit.scale < 1 - 1e-9 || out.some((o) => overlaps(o.band, band))) return null;\n const { dx, dy } = m.fit;\n const landing = shifted(band, dx, dy);\n const carried = p.words.designed.filter((b) => inSpans([band], (b.x0 + b.x1) / 2, (b.y0 + b.y1) / 2));\n const others = p.words.designed.filter((b) => !carried.includes(b));\n // Where another line ends up, with the pill or card it sits on.\n const ends = (b: TextBox) => {\n const own = moveOf(b, moves);\n return own ? movedSpan(at.extent(b), own.fit) : at.extent(b);\n };\n const lost = wordsLost(\n carried.map((b) => at.inFrame(shifted(b, dx, dy))),\n p.format,\n p.placements,\n );\n const crossed =\n carried.some((b) => (moveOf(b, moves) ?? m) !== m) || others.some((b) => overlaps(ends(b), hull(band, landing)));\n if (lost.length > 0 || crossed || facesUnder([landing], faces).length > 0) return null;\n out.push({ band, dx, dy, words: carried });\n }\n return out;\n}\n\n/**\n * `out` with the blocks of `moves`, set on the picture itself, lifted off the render (`wordsLayer`,\n * `movedPart`), the picture put back where they were in the render's light, and set down where\n * they move.\n */\nfunction wordsMoved(p: Placing, out: Raw, moves: readonly WordsMove[]): Raw {\n const { layer } = wordsLayer(p.aligned, p.cut, p.words.designed, {\n subjects: p.subjects,\n keepOut: p.words.inScene,\n });\n const part = movedPart(layer, moves);\n const left = soften(\n part.alpha.map((a) => (a > 0 ? 1 : 0)),\n p.cut.width,\n p.cut.height,\n 2,\n ).map((a, i) => Math.max(a, part.alpha[i] ?? 0));\n return compose(restoreSubjects(out, p.cut, p.gain, left), moveLayer(part, moves));\n}\n\n/**\n * The render's words that the size's frame cuts, its app covers or a face sits under, moved by\n * code (`planWordsShift`) on the render's own picture: a block set on the picture itself on its\n * own (`wordsMoved`), a block on a band or card with its band (`moveBand`). Null when no move\n * clears them: the words are set again. Moved on the whole render, so a button half past the\n * frame's edge comes in whole.\n */\nfunction placeWords(p: Placing): { out: Raw; moves: WordsMove[] } | null {\n const { width, height } = p.cut;\n const inFrame = <T extends Span>(b: T): T => ({\n ...b,\n x0: (b.x0 * width - p.frame.x) / p.frame.width,\n x1: (b.x1 * width - p.frame.x) / p.frame.width,\n y0: (b.y0 * height - p.frame.y) / p.frame.height,\n y1: (b.y1 * height - p.frame.y) / p.frame.height,\n });\n const showing = (b: Span) => b.x1 > 0 && b.y1 > 0 && b.x0 < 1 && b.y0 < 1;\n const laid = laidMap(p.judged.aligned, p.judged.cut);\n const f = frameSpan(p.frame, width, height);\n // A line on a card the frame cuts is placed as its card, so the whole card comes inside.\n const placed = p.words.designed.map((b) => {\n const card = cutCardOf(laid, b, f);\n return card ? { ...b, ...card } : b;\n });\n const plan = planWordsShift(unique(placed).map(inFrame).filter(showing), p.format, {\n ...(p.placements ? { placements: p.placements } : {}),\n ...(p.minScale !== undefined ? { minScale: p.minScale } : {}),\n faces: p.subjects\n .filter((s) => s.kind === \"face\")\n .map(inFrame)\n .filter(showing),\n // Never into the logo's slot, nor out of it: a block moved out of it had its band cut through the letters.\n ...(p.keepOut ? { keepOut: p.keepOut } : {}),\n });\n if (plan.reason || plan.moves.length === 0) return null;\n const moves = plan.moves.map((m) => moveOnRender(m, p.frame, width, height));\n const under = moves.map((move) => ({ move, on: carriersOf(move, laid, p.words.designed) }));\n // Lifted off alone, words take squares of what lies around them: a band nobody can tell the edges\n // of, a soft glow, the other part of a block only partly on a band. Those words are set again.\n const unsure = (u: (typeof under)[number]) =>\n u.on === \"mixed\" || (u.on === \"picture\" && laidAround(laid, u.move.group) > BARE);\n if (under.some(unsure)) return null;\n const banded = under.flatMap((u) => (Array.isArray(u.on) ? u.on.map((band) => ({ move: u.move, band })) : []));\n const bands = bandMoves(banded, moves, p, { inFrame, extent: (b) => bandUnder(laid, b) ?? b });\n if (!bands) return null;\n const loose = under.flatMap((u) => (u.on === \"picture\" ? [u.move] : []));\n let out = loose.length > 0 ? wordsMoved(p, p.out, loose) : p.out;\n for (const band of bands) out = moveBand({ aligned: p.aligned, cut: p.cut, out }, band);\n return { out, moves: plan.moves };\n}\n\n/**\n * A size's words render taken whole: lined up with the cut (`registerToSource`), judged\n * (`wholeVerdict`), and its redrawn subjects and the scene's own lines put back from the cut\n * (`restoreMask`, `restoreSubjects`). With its words unread, the render is the size as it is and\n * nothing is put back: nobody knows where its words sit. Pure.\n */\nexport function takeWhole(input: WholeInput): WholeTake {\n const { render, cut, frame } = input;\n const fit = registerToSource(render, cut, input.words?.designed ?? []);\n const aligned = warpToCut(render, fit);\n if (!input.words) {\n const out = cropRaw(aligned, frame);\n return { ok: true, out, restored: [], covered: [], moves: [], kept: 1, residual: fit.residual };\n }\n const judging = judge(input, input.words, fit, aligned);\n const { verdict, kept } = judging;\n // Words only out of place are moved by code below; anything else is the render's own fault.\n const misplaced = !verdict.ok && (verdict.problem === \"words_lost\" || verdict.problem === \"words_over_face\");\n if (!verdict.ok && !misplaced) return { ...verdict, kept, residual: fit.residual };\n const { out, gain, taken } = putBack(input, input.words, aligned, judging);\n const done = { ...taken, kept, residual: fit.residual };\n if (verdict.ok) return { ok: true, out: cropRaw(out, frame), moves: [], ...done };\n const placed = placeWords({\n aligned,\n cut,\n out,\n gain: gain(),\n judged: judging.judged,\n frame,\n words: input.words,\n subjects: input.subjects,\n format: input.format,\n ...(input.placements ? { placements: input.placements } : {}),\n ...(input.minScale !== undefined ? { minScale: input.minScale } : {}),\n ...(input.keepOut ? { keepOut: input.keepOut } : {}),\n });\n if (!placed) return { ...verdict, kept, residual: fit.residual, whole: { out: cropRaw(out, frame), ...taken } };\n return { ok: true, out: cropRaw(placed.out, frame), moves: placed.moves, ...done };\n}\n\n/** What `judge` found: the verdict, what was read for it, and the subjects the model only moved. */\ntype Judging = {\n verdict: WholeVerdict;\n reading: WholeReading;\n kept: number;\n diff: RenderDiff;\n judged: { aligned: Raw; cut: Raw };\n words: Span[];\n drifts: Array<{ subject: SubjectBox; shown: number }>;\n relocated: Relocation[];\n};\n\n/** The render lined up, read and judged (`wholeVerdict`), a small subject the model only moved followed where it went. */\nfunction judge(\n input: WholeInput,\n read: { designed: readonly TextBox[]; inScene: readonly TextBox[] },\n fit: Registration,\n aligned: Raw,\n): Judging {\n const { cut, frame } = input;\n const { width, height } = cut;\n const words = read.designed.map((b) => padded(b, width, height));\n // Judged at half its pixels: what is read is shapes and shares, and a delivered size is 1080 wide.\n const shrink = Math.max(1, Math.round(width / JUDGED_WIDTH));\n const judged =\n shrink > 1\n ? { aligned: shrinkRaw(aligned, shrink), cut: shrunkCuts(cut, String(shrink), () => shrinkRaw(cut, shrink)) }\n : { aligned, cut };\n const diff = renderDiff(judged.aligned, judged.cut, words);\n const drifts = input.subjects.map((s) => ({ subject: s, ...subjectDrift(diff, s, words) }));\n const inFrame = (b: TextBox): TextBox => ({\n ...b,\n x0: (b.x0 * width - frame.x) / frame.width,\n x1: (b.x1 * width - frame.x) / frame.width,\n y0: (b.y0 * height - frame.y) / frame.height,\n y1: (b.y1 * height - frame.y) / frame.height,\n });\n const kept = keptShare(diff, words);\n const gone = new Set<SubjectBox>();\n const laid = laidMap(judged.aligned, judged.cut);\n const f = frameSpan(frame, width, height);\n // A line whose card the frame cuts is cut with it, the review reads: its card moves inside.\n const carded = read.designed.filter((b) => cutCardOf(laid, b, f)).map((b) => b.text);\n const lost = wordsLost(read.designed.map(inFrame), input.format, input.placements, input.keepOut);\n const base = {\n kept,\n carried: carriedBy(fit, frame, width, height),\n lost: [...lost, ...carded.filter((t) => !lost.includes(t))],\n };\n const faces = () => input.subjects.filter((s) => s.kind === \"face\" && !gone.has(s));\n const readingNow = (): WholeReading => ({\n ...base,\n subjects: drifts\n .filter((d) => !gone.has(d.subject))\n .map((d) => ({ label: d.subject.label, moved: d.moved, drift: d.drift, shown: d.shown })),\n onFace: wordsOnFaces(read.designed, faces()),\n });\n let verdict = wholeVerdict(readingNow());\n const relocated: Relocation[] = [];\n // A small photo the model moved (its words then sit where it was) is followed where it went, twice at most.\n for (let round = 0; round < 2 && !verdict.ok && FOLLOWED.has(verdict.problem); round++) {\n const suspects =\n verdict.problem === \"subject_redrawn\"\n ? drifts.filter((d) => !gone.has(d.subject) && d.moved > REDRAWN).map((d) => d.subject)\n : facesUnder(read.designed, faces());\n const found = relocations(withTheirPeople(suspects, input.subjects), judged);\n if (!found) break;\n relocated.push(...found);\n for (const r of found) gone.add(r.subject);\n verdict = wholeVerdict(readingNow());\n }\n return { verdict, reading: readingNow(), kept, diff, judged, words, drifts, relocated };\n}\n\n/** Each subject with the person around a face of it (the same label, holding the face): they move together. */\nfunction withTheirPeople(suspects: readonly SubjectBox[], subjects: readonly SubjectBox[]): SubjectBox[] {\n const holds = (outer: SubjectBox, inner: SubjectBox) =>\n outer.x0 <= inner.x0 + 0.01 &&\n outer.y0 <= inner.y0 + 0.01 &&\n outer.x1 >= inner.x1 - 0.01 &&\n outer.y1 >= inner.y1 - 0.01;\n const people = subjects.filter(\n (p) => p.kind === \"person\" && suspects.some((f) => f.kind === \"face\" && f.label === p.label && holds(p, f)),\n );\n return [...new Set([...suspects, ...people])];\n}\n\n/** The refusals a small subject the model only moved explains: it is not redrawn, and words over where it was are over nothing. */\nconst FOLLOWED: ReadonlySet<WholeProblem> = new Set([\"subject_redrawn\", \"words_over_face\"]);\n\n/** The render with the picture put back: each subject it redrew where it was, each it moved where it went, the scene's own lines. */\nfunction putBack(\n input: WholeInput,\n read: { designed: readonly TextBox[]; inScene: readonly TextBox[] },\n aligned: Raw,\n j: Judging,\n): { out: Raw; gain: () => Float32Array; taken: { restored: string[]; covered: string[] } } {\n const { cut } = input;\n const full = { width: cut.width, height: cut.height };\n const settled = j.verdict.ok ? j.verdict : wholeVerdict({ ...j.reading, lost: [], onFace: [] });\n const restored = settled.ok ? settled.restore : [];\n const back = input.subjects.filter((s) => restored.includes(s.label));\n const zones = [...back, ...read.inScene.map((b) => padded(b, full.width, full.height))];\n const covered = j.drifts\n .filter((d) => (d.subject.kind === \"product\" || d.subject.kind === \"animal\") && d.shown < SHOWN_MIN)\n .map((d) => d.subject.label);\n // At full pixels only when a subject is put back or the words are moved: a render taken as it is never reads it.\n let enlarged: Float32Array | undefined;\n const gain = () => {\n enlarged ??= enlarge(j.diff.gain, j.diff, full, 3);\n return enlarged;\n };\n let out =\n zones.length === 0\n ? aligned\n : restoreSubjects(aligned, cut, gain(), enlarge(restoreMask(j.diff, zones, j.words), j.diff, full, 1));\n for (const r of j.relocated) out = putMoved(out, cut, r, j);\n const moved = j.relocated.map((r) => r.subject.label);\n return { out, gain, taken: { restored: [...new Set([...restored, ...moved])], covered } };\n}\n\n/** A small subject the words model moved whole (`tracked`), and the place it moved it to. */\ntype Relocation = { subject: SubjectBox; place: { dx: number; dy: number; scale: number } };\n\n/** The most of the frame a subject may cover and still be followed where the model moved it: a round photo, a thumbnail. */\nconst TRACK_MAX_AREA = 0.06;\n/** The likeness (`tracked` score) from which a subject the model moved is the same subject, not one drawn again. */\nconst RELOCATED = 0.8;\n/** A subject found less than this far from where it was (a share of the frame) stayed where it was. */\nconst STAYED = 0.005;\n\n/**\n * Where each of `subjects` went, each small and only moved; null when any was too large to follow,\n * was drawn again or did not move. Dev, Oct 2026: GPT moved a quote card's round photo 2-3% to\n * fit the attribution, the same photo (likeness 0.87-0.99). Pure.\n */\nfunction relocations(subjects: readonly SubjectBox[], judged: { aligned: Raw; cut: Raw }): Relocation[] | null {\n if (subjects.length === 0) return null;\n const out: Relocation[] = [];\n for (const subject of subjects) {\n if ((subject.x1 - subject.x0) * (subject.y1 - subject.y0) > TRACK_MAX_AREA) return null;\n const place = tracked(judged.aligned, judged.cut, subject);\n // Found where it was, it did not move: what is wrong with it is not where it went.\n const stayed = Math.hypot(place.dx, place.dy) < STAYED && Math.abs(place.scale - 1) < 0.02;\n if (place.score < RELOCATED || stayed) return null;\n out.push({ subject, place });\n }\n return out;\n}\n\n/** `box` (fractions) moved by `place` about its centre. */\nfunction movedBox(box: Span, place: Relocation[\"place\"]): Span {\n const cx = (box.x0 + box.x1) / 2;\n const cy = (box.y0 + box.y1) / 2;\n return {\n x0: cx + place.dx + place.scale * (box.x0 - cx),\n y0: cy + place.dy + place.scale * (box.y0 - cy),\n x1: cx + place.dx + place.scale * (box.x1 - cx),\n y1: cy + place.dy + place.scale * (box.y1 - cy),\n };\n}\n\n/** The cut with the patch around `box` drawn where `place` takes it (bilinear); the rest the cut as it is. */\nfunction cutMoved(cut: Raw, box: Span, place: Relocation[\"place\"]): Raw {\n const { width, height } = cut;\n const out = Buffer.alloc(width * height * 3);\n if (cut.channels === 3) cut.data.copy(out, 0, 0, width * height * 3);\n else for (let i = 0; i < width * height; i++) cut.data.copy(out, i * 3, i * cut.channels, i * cut.channels + 3);\n const to = movedBox(box, place);\n const margin = (ZONE_MARGIN + FEATHER) * Math.max((to.x1 - to.x0) * width, (to.y1 - to.y0) * height) + 4;\n const cx = ((box.x0 + box.x1) / 2) * width;\n const cy = ((box.y0 + box.y1) / 2) * height;\n for (let y = Math.max(0, Math.floor(to.y0 * height - margin)); y < Math.min(height, to.y1 * height + margin); y++) {\n for (let x = Math.max(0, Math.floor(to.x0 * width - margin)); x < Math.min(width, to.x1 * width + margin); x++) {\n const u = Math.min(width - 1.001, Math.max(0, cx + (x - cx - place.dx * width) / place.scale));\n const v = Math.min(height - 1.001, Math.max(0, cy + (y - cy - place.dy * height) / place.scale));\n const x0 = Math.floor(u);\n const y0 = Math.floor(v);\n const fx = u - x0;\n const fy = v - y0;\n for (let c = 0; c < 3; c++) {\n const at = (px: number, py: number) => cut.data[(py * width + px) * cut.channels + c] ?? 0;\n const top = at(x0, y0) * (1 - fx) + at(x0 + 1, y0) * fx;\n const bottom = at(x0, y0 + 1) * (1 - fx) + at(x0 + 1, y0 + 1) * fx;\n out[(y * width + x) * 3 + c] = Math.round(top * (1 - fy) + bottom * fy);\n }\n }\n }\n return { data: out, width, height, channels: 3 };\n}\n\n/** `out` with a subject the model moved put back as the picture drew it, where the model set it. */\nfunction putMoved(out: Raw, cut: Raw, r: Relocation, j: Judging): Raw {\n const full = { width: cut.width, height: cut.height };\n const moved = cutMoved(cut, r.subject, r.place);\n const judgedMoved =\n j.judged.cut.width === cut.width ? moved : shrinkRaw(moved, Math.round(cut.width / j.judged.cut.width));\n const diff = renderDiff(j.judged.aligned, judgedMoved, j.words);\n const mask = restoreMask(diff, [movedBox(r.subject, r.place)], j.words);\n return restoreSubjects(out, moved, enlarge(diff.gain, diff, full, 3), enlarge(mask, diff, full, 1));\n}\n","import sharp from \"sharp\";\nimport { z } from \"zod\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport { hexLuma, inkLuma } from \"../../scaffold/ad-brand-source.ts\";\nimport { blockingArea } from \"../../scaffold/platform-safe-area.ts\";\nimport {\n chooseLogoSpot,\n contrastRatio,\n designerSpots,\n type GreyTable,\n greyTable,\n inflatedWords,\n LOGO_POSITIONS,\n type LogoPosition,\n type LogoScene,\n type LogoSlot,\n legibleShare,\n logoBoxOn,\n logoSpotClean,\n MIN_LEGIBLE_SHARE,\n PLACEMENT_DEFECTS,\n PLACEMENT_EDGES,\n PLACEMENT_ELEMENTS,\n pickLogoVariant,\n placeInSlot,\n placementProblems,\n plateColour,\n slotAround,\n spreadUnder,\n straightEdgeIn,\n} from \"../../scaffold/static-logo.ts\";\nimport { ImageRef } from \"../../schema/refs.ts\";\nimport type { Rgba } from \"./lib/logo-match.ts\";\nimport { fitArtwork, logoArtwork, textColourSource, usesTextColour } from \"./lib/logo-raster.ts\";\nimport { boxesOfLine, headlineBox, withWordmark } from \"./lib/must-show.ts\";\nimport { imageOf } from \"./lib/node-steps.ts\";\nimport type { ReviewUsage } from \"./lib/render-review.ts\";\nimport { readSubjectBoxes } from \"./lib/subject-boxes.ts\";\nimport { readTextBoxes, type TextBox } from \"./lib/text-boxes.ts\";\n\nconst Usage = z\n .object({ model: z.string(), inputTokens: z.number(), outputTokens: z.number(), costUsd: z.number() })\n .strict();\nconst Rect = z\n .object({\n x: z.number().int(),\n y: z.number().int(),\n width: z.number().int().positive(),\n height: z.number().int().positive(),\n })\n .strict();\nconst Copy = z.array(z.object({ text: z.string().min(1), role: z.string().optional() }).strict());\n\n/** What the composite did and what its check found, small enough for the run record: the review blocks on `problems`. */\nexport const LogoFacts = z\n .object({\n format: z.string(),\n /** Where the logo file was placed, in the size's pixels. */\n box: Rect,\n /** The slot it was placed in. */\n slot: Rect,\n /** Which of the logo's files (`inputs.logos`) was placed: the one that reads on the ground. */\n variant: z.number().int().nonnegative(),\n /** The colour a file inked in the text colour (`currentColor`) was drawn in, of `params.inks`. */\n ink: z.string().optional(),\n /** The grey level (0-255) of the ground under the logo, and the contrast of the placed file's ink on it. */\n ground: z.number(),\n contrast: z.number(),\n /** The share (0-1) of the logo's solid pixels whose own ground it stands out from; the review blocks under 0.9. */\n legible: z.number().default(1),\n /** Set when no plain ground held the logo and it sits on a plate of its own: the plate's colour. */\n plate: z.object({ colour: z.string() }).strict().optional(),\n /** The headline's box as read on the size; null when the ad has no copy or it was not read. */\n headline: Rect.nullable(),\n /** Whether the size's words were read for the check. */\n read: z.boolean(),\n problems: z.array(\n z\n .object({\n element: z.enum(PLACEMENT_ELEMENTS),\n defect: z.enum(PLACEMENT_DEFECTS),\n edges: z.array(z.enum(PLACEMENT_EDGES)),\n })\n .strict(),\n ),\n })\n .strict();\nexport type LogoFacts = z.infer<typeof LogoFacts>;\n\nconst LogoParams = z\n .object({\n format: z.string().regex(/^\\d+(?:\\.\\d+)?:\\d+(?:\\.\\d+)?$/),\n placements: z.array(z.string().min(1)).optional(),\n /** Where the concept places the logo (`logo_position`, read by `placedLogoPosition`). */\n position: z.enum(LOGO_POSITIONS).optional(),\n /** The logo's shape the slot was planned with (width over height), as the size's brief reserved it; else the file's own. */\n aspect: z.number().positive().optional(),\n /** The ad's copy (prompt.json's lines and their roles): the check finds the headline among them. */\n copy: Copy.optional(),\n /** The colours a logo inked in the text colour (`currentColor`) may be drawn in: the brand's, and white. */\n inks: z\n .array(z.string().regex(/^#[0-9a-fA-F]{6}$/))\n .min(1)\n .optional(),\n /** The brand's colours a plate behind the logo may take, when no plain ground holds it. */\n plates: z.array(z.string().regex(/^#[0-9a-fA-F]{6}$/)).optional(),\n })\n .strict();\n\n/** The logo's own file: the SVG the ingest read when it is inked in the text colour, else the picture given. */\nasync function logoFileOf(logo: z.infer<typeof ImageRef>): Promise<Buffer> {\n return (await textColourSource(logo.metadata)) ?? (await imageOf(logo, \"static_logo\")).bytes;\n}\n\n/** The colours a logo inked in the text colour is tried in when the brand names none. */\nconst DEFAULT_INKS = [\"#000000\", \"#FFFFFF\"];\n\n/** One way the logo can be placed: a file, and the colour it is drawn in when the file takes the text colour. */\ntype Candidate = { file: number; ink?: string; art: Rgba };\n\n/** Every way the logo can be placed: each file as it is, a file inked in the text colour once per colour. */\nasync function candidatesOf(files: readonly Buffer[], inks: readonly string[] | undefined): Promise<Candidate[]> {\n const each = await Promise.all(\n files.map(async (bytes, file): Promise<Candidate[]> => {\n if (!usesTextColour(bytes)) return [{ file, art: await logoArtwork(bytes) }];\n return await Promise.all(\n (inks ?? DEFAULT_INKS).map(async (ink) => ({\n file,\n ink,\n art: await logoArtwork(bytes, { currentColor: ink }),\n })),\n );\n }),\n );\n return each.flat();\n}\n\nexport const staticLogoNode = defineNode({\n id: \"static_logo\",\n version: \"1.4.0\",\n category: \"image\",\n location: \"local\",\n summary:\n \"Place the brand's own logo file on one delivered size of a static ad, pixel for pixel, never drawn by a model, only where a designer sets one: a top corner or the top centre just inside the safe area, a bottom corner at the safe area's foot, or beside the button on its row (`chooseLogoSpot`, the same function the size's brief reserved its slot with). It keeps the reserved slot (`inputs.slot`) while it is still clean; else it takes the first such place whose whole box (logo, clear space, plate) is off every words box, keeps its clear space off every person, face and product, and has no straight edge (a card's, a window's, a phone's) through it, on plain ground where the logo reads, else smaller, else on a small plate in a brand colour. With no clean place it stamps nothing and flags the size (`no_room`) for its words to be set again with the corner kept clear. Of the logo's files (`inputs.logos`, the same artwork in its colours) it places the one that reads best. Then checks the size: the logo and the headline each wholly inside the frame and the safe area, no words under the logo, and the logo legible (`facts.problems`, blocking in the review).\",\n when_to_use:\n \"Scaffolded by `baker canvas scaffold-static-ad` as the last step of every size (`logo_<size>`, role `logo_composite`) when the brand has a logo file. Free, besides two box-reader calls, the words and the people and products (about $0.01, carried on the run record's review spend).\",\n inputs: z.object({ image: ImageRef, logos: z.array(ImageRef).min(1), slot: Rect.optional() }).strict(),\n params: LogoParams,\n outputs: z.object({ image: ImageRef, facts: LogoFacts, usage: z.array(Usage).optional() }).strict(),\n outputKinds: { image: \"image\" },\n cost: () => ({ credits: 0, seconds_estimate: 5 }),\n async execute({ inputs, params, ctx }) {\n const { bytes, size } = await imageOf(inputs.image, \"static_logo\");\n const files = await Promise.all(inputs.logos.map(logoFileOf));\n const candidates = await candidatesOf(files, params.inks);\n const arts = candidates.map((c) => c.art);\n const position: LogoPosition = params.position ?? \"top_left\";\n const safe = blockingArea(params.format, params.placements);\n const aspect = params.aspect ?? (arts[0] as Rgba).width / (arts[0] as Rgba).height;\n const copy = params.copy ?? [];\n const { read, usage } = await wordsBefore(bytes, copy.length > 0 || !inputs.slot);\n const inks = arts.map((art) => inkLuma(art.data));\n const where = await whereLogoGoes(\n { bytes, size, safe, aspect, position, words: wordsOf(read, copy, size), usage },\n { reserved: inputs.slot, arts, inks, plates: params.plates },\n );\n const { image, table, home, plate } = where;\n\n const fitted = await Promise.all(arts.map((art) => fitArtwork(art, home)));\n const grounds = fitted.map((art) => groundUnder(image, art, placeInSlot(home, art, where.at)));\n const shares = fitted.map((art, i) => legibleShare(table, art, placeInSlot(home, art, where.at), inks[i] ?? null));\n const chosen = plate ? plate.variant : pickLogoVariant(shares);\n const placed = fitted[chosen] as Rgba;\n const { file: variant, ink } = candidates[chosen] as Candidate;\n const at = placeInSlot(home, placed, where.at);\n const box = { x: at.x, y: at.y, width: placed.width, height: placed.height };\n // With no clean place, nothing is stamped: the size's words are set again with the corner kept clear.\n const out = where.noRoom\n ? await sharp(bytes).png().toBuffer()\n : await sharp(bytes)\n .composite(await layersOf(placed, at, plate))\n .png()\n .toBuffer();\n\n const legible = plate ? 1 : (shares[chosen] ?? 1);\n const ground = plate ? plate.luma : (grounds[chosen] ?? 255);\n const { headline, problems } = checkSize(\n read,\n { size, safe, box, legible, plated: plate !== null, noRoom: where.noRoom },\n copy,\n );\n const facts: LogoFacts = {\n format: params.format,\n box,\n slot: home,\n variant,\n ...(ink ? { ink } : {}),\n ...(plate ? { plate: { colour: plate.colour } } : {}),\n ground: Math.round(ground),\n contrast: Math.round(contrastRatio(ground, inks[chosen] ?? 0) * 10) / 10,\n legible: Math.round(legible * 100) / 100,\n headline,\n read: read !== null && copy.length > 0,\n problems,\n };\n ctx.log(logLine(facts, files.length));\n const ingested = await ctx.assets.ingestBytes({ bytes: out, kind: \"image\", mime: \"image/png\" });\n return { image: ingested as z.infer<typeof ImageRef>, facts, ...(usage.length > 0 ? { usage } : {}) };\n },\n});\n\n/** What the composite did, in one line for the run log. */\nfunction logLine(facts: LogoFacts, files: number): string {\n const { box, ink, plate, problems } = facts;\n const found = problems.length > 0 ? `; ${problems.map((p) => `${p.element} ${p.defect}`).join(\", \")}` : \"\";\n return `${facts.format}: logo file ${facts.variant + 1} of ${files}${ink ? ` in ${ink}` : \"\"}${plate ? ` on a ${plate.colour} plate` : \"\"} placed at ${box.x},${box.y} ${box.width}x${box.height} (contrast ${facts.contrast}, legible ${facts.legible})${found}`;\n}\n\ntype Plate = { rect: Box; radius: number; colour: string; luma: number; variant: number };\n\n/** Where the logo goes on a size, and the corner its slot sits in; `noRoom` when no designer's place is clean, and nothing is stamped. */\ntype Where = { image: Rgba; table: GreyTable; home: Box; at: LogoPosition; plate: Plate | null; noRoom: boolean };\n\n/**\n * Where the logo goes on a size, by the same function the size's brief reserved its slot with\n * (`chooseLogoSpot`): the reserved slot when it is still clean, plain and legible; else the first\n * designer's place clean of the words, the people and products and any edge, on plain ground, else on\n * a plate of its own; else no room, and the size's words are set again with the corner kept clear.\n */\nasync function whereLogoGoes(\n at: {\n bytes: Buffer;\n size: Size;\n safe: Safe;\n aspect: number;\n position: LogoPosition;\n words: readonly Word[];\n usage: ReviewUsage[];\n },\n logo: {\n reserved: Box | undefined;\n arts: readonly Rgba[];\n inks: ReadonlyArray<number | null>;\n plates: readonly string[] | undefined;\n },\n): Promise<Where> {\n const { bytes, size, safe, aspect, position } = at;\n const picture = await sharp(bytes).ensureAlpha().raw().toBuffer({ resolveWithObject: true });\n const image: Rgba = { data: picture.data, width: picture.info.width, height: picture.info.height };\n const table = greyTable(image);\n const planned = await Promise.all(logo.arts.map((art) => fitArtwork(art, logoBoxOn(size, aspect))));\n const legible = (rect: Box) =>\n planned.some(\n (art, i) =>\n legibleShare(table, art, placeInSlot(rect, art, position), logo.inks[i] ?? null, 2) >= MIN_LEGIBLE_SHARE,\n );\n const subjects = await readSubjects(bytes, size, at.usage);\n const scene: LogoScene = {\n words: inflatedWords(at.words),\n subjects: boxesOfKinds(subjects, LOGO_AVOIDS),\n cta: buttonOf(at.words),\n crossesEdge: (r) => straightEdgeIn(table, r),\n calm: (r) => spreadUnder(table, r) <= PLAIN_GROUND_SPREAD,\n legible,\n };\n const reserved = logo.reserved ? slotAround(logo.reserved, position) : null;\n if (reserved && logoSpotClean(reserved, scene) && scene.calm?.(reserved.clear) && legible(reserved.rect)) {\n return { image, table, home: reserved.rect, at: position, plate: null, noRoom: false };\n }\n const spot = chooseLogoSpot(size, safe, { aspect, position, ...scene });\n const plate = spot?.plate ? plateOf(spot.slot.clear, spot.slot.rect, logo) : null;\n if (spot && (!spot.plate || plate)) {\n return { image, table, home: spot.slot.rect, at: spot.slot.position, plate, noRoom: false };\n }\n const corner = reserved ?? (designerSpots(size, safe, { aspect, position })[0] as LogoSlot);\n return { image, table, home: corner.rect, at: corner.position, plate: null, noRoom: true };\n}\n\n/** The plate under a logo set at `rect`, over its clear space `clear`: the brand colour the file stands out from most; null when none can be read. */\nfunction plateOf(\n clear: Box,\n rect: Box,\n from: { plates: readonly string[] | undefined; inks: ReadonlyArray<number | null> },\n): Plate | null {\n const chosen = plateColour(plateOptions(from.plates), from.inks);\n if (!chosen) return null;\n const luma = hexLuma(chosen.colour) ?? 0;\n return {\n rect: clear,\n radius: Math.round(rect.height * PLATE_RADIUS),\n colour: chosen.colour,\n luma,\n variant: chosen.variant,\n };\n}\n\n/** A plate's corners are rounded to this share of the logo's height. */\nconst PLATE_RADIUS = 0.25;\n\n/** The button's box among the words read, the union of its lines; null when none was read. */\nfunction buttonOf(words: readonly Word[]): Box | null {\n const boxes = words.filter((w) => w.cta).map((w) => w.box);\n if (boxes.length === 0) return null;\n const x = Math.min(...boxes.map((b) => b.x));\n const y = Math.min(...boxes.map((b) => b.y));\n const right = Math.max(...boxes.map((b) => b.x + b.width));\n const bottom = Math.max(...boxes.map((b) => b.y + b.height));\n return { x, y, width: right - x, height: bottom - y };\n}\n\ntype Box = { x: number; y: number; width: number; height: number };\ntype Size = { width: number; height: number };\ntype Safe = ReturnType<typeof blockingArea>;\ntype Word = { box: Box; cta: boolean };\ntype Subject = { kind: string; box: Box };\n\n/** The layers the logo goes on with: its plate when it has one, then the file itself. */\nasync function layersOf(\n placed: Rgba,\n at: { x: number; y: number },\n plate: { rect: Box; radius: number; colour: string } | null,\n): Promise<sharp.OverlayOptions[]> {\n const art = await sharp(placed.data, { raw: { width: placed.width, height: placed.height, channels: 4 } })\n .png()\n .toBuffer();\n const layers: sharp.OverlayOptions[] = [{ input: art, left: at.x, top: at.y }];\n if (!plate) return layers;\n const { rect, radius, colour } = plate;\n const svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${rect.width}\" height=\"${rect.height}\"><rect width=\"${rect.width}\" height=\"${rect.height}\" rx=\"${radius}\" ry=\"${radius}\" fill=\"${colour}\"/></svg>`;\n return [{ input: Buffer.from(svg), left: rect.x, top: rect.y }, ...layers];\n}\n\n/**\n * The size's words, read before the logo goes on (so a line the logo would cover is still read),\n * and what reading them cost; none when `wanted` is false or nobody could read them.\n */\nasync function wordsBefore(bytes: Buffer, wanted: boolean): Promise<{ read: TextBox[] | null; usage: ReviewUsage[] }> {\n const usage: ReviewUsage[] = [];\n if (!wanted) return { read: null, usage };\n const reading = await readTextBoxes(bytes, { onSpend: (u) => usage.push(u) });\n return { read: reading.status === \"read\" ? reading.boxes : null, usage };\n}\n\n/** Every box read on the size, in its pixels, a button's line (a copy line of role cta or button) marked. */\nfunction wordsOf(read: readonly TextBox[] | null, copy: z.infer<typeof Copy>, size: Size): Word[] {\n const boxes = read ?? [];\n const buttons = new Set(copy.filter((l) => /cta|button/i.test(l.role ?? \"\")).flatMap((l) => boxesOfLine(l, boxes)));\n return boxes.map((b) => ({ box: pxOf(b, size), cta: buttons.has(b) }));\n}\n\n/** The kinds of subject a logo, plate and all, never sits on or crowds. */\nconst LOGO_AVOIDS = new Set([\"person\", \"face\", \"product\", \"animal\"]);\n\n/** The spread of the grey level (0-255) under a logo's clear space up to which the ground counts as plain. */\nconst PLAIN_GROUND_SPREAD = 18;\n\n/** The picture's people, faces and products, read once. */\nasync function readSubjects(bytes: Buffer, size: Size, usage: ReviewUsage[]): Promise<Subject[]> {\n const r = await readSubjectBoxes(bytes, { onSpend: (u) => usage.push(u) });\n return r.status === \"read\" ? r.boxes.map((b) => ({ kind: b.kind, box: pxOf(b, size) })) : [];\n}\n\nconst boxesOfKinds = (subjects: readonly Subject[], kinds: ReadonlySet<string>): Box[] =>\n subjects.filter((s) => kinds.has(s.kind)).map((s) => s.box);\n\n/** The brand colours a plate may take, with how light each is. */\nfunction plateOptions(hexes: readonly string[] | undefined): Array<{ colour: string; luma: number }> {\n return (hexes ?? []).flatMap((colour) => {\n const luma = hexLuma(colour);\n return luma === null ? [] : [{ colour, luma }];\n });\n}\n\n/** A box read as fractions of a size, in its pixels. */\nfunction pxOf(b: { x0: number; y0: number; x1: number; y1: number }, size: Size): Box {\n return {\n x: Math.round(b.x0 * size.width),\n y: Math.round(b.y0 * size.height),\n width: Math.max(1, Math.round((b.x1 - b.x0) * size.width)),\n height: Math.max(1, Math.round((b.y1 - b.y0) * size.height)),\n };\n}\n\n/**\n * The size's check on its words as read before the logo went on (`read`, null when nobody could\n * read them): the logo's box and the headline's each inside the frame and its safe area, no words\n * of any kind under the logo, the logo legible or on its plate, and room found for it at all.\n */\nfunction checkSize(\n read: readonly TextBox[] | null,\n at: { size: Size; safe: Safe; box: Box; legible: number; plated: boolean; noRoom: boolean },\n copy: z.infer<typeof Copy>,\n): { headline: Box | null; problems: LogoFacts[\"problems\"] } {\n const lines = read && copy.length > 0 ? copyBoxes(read, copy) : null;\n const headline = lines?.headline ? pxOf(lines.headline, at.size) : null;\n const inHeadline = (b: Box) =>\n headline !== null &&\n b.x >= headline.x &&\n b.y >= headline.y &&\n b.x + b.width <= headline.x + headline.width &&\n b.y + b.height <= headline.y + headline.height;\n const words = (read ?? [])\n .filter((b) => b.kind === \"text\")\n .map((b) => pxOf(b, at.size))\n .filter((b) => !inHeadline(b));\n const problems = placementProblems({\n frame: at.size,\n safe: at.safe,\n // With no room nothing was stamped: only the headline is checked.\n logo: at.noRoom ? null : at.box,\n headline,\n copy: (lines?.others ?? []).map((b) => pxOf(b, at.size)),\n words,\n legible: at.legible,\n plated: at.plated,\n });\n const noRoom = at.noRoom ? [{ element: \"logo\" as const, defect: \"no_room\" as const, edges: [] }] : [];\n return { headline, problems: [...problems, ...noRoom] };\n}\n\n/** The mean grey level of the picture under the artwork's solid pixels, placed at `at`. */\nfunction groundUnder(image: Rgba, art: Rgba, at: { x: number; y: number }): number {\n let sum = 0;\n let n = 0;\n for (let j = 0; j < art.height; j++) {\n for (let i = 0; i < art.width; i++) {\n if ((art.data[(j * art.width + i) * 4 + 3] ?? 0) < 128) continue;\n const u = at.x + i;\n const v = at.y + j;\n if (u < 0 || v < 0 || u >= image.width || v >= image.height) continue;\n const o = (v * image.width + u) * 4;\n sum += 0.2126 * (image.data[o] ?? 0) + 0.7152 * (image.data[o + 1] ?? 0) + 0.0722 * (image.data[o + 2] ?? 0);\n n++;\n }\n }\n return n === 0 ? 255 : sum / n;\n}\n\n/** The copy as read: the headline's block, and the boxes of the other lines. */\nfunction copyBoxes(\n read: readonly TextBox[],\n copy: z.infer<typeof Copy>,\n): { headline: ReturnType<typeof headlineBox>; others: TextBox[] } {\n const logoWords = copy.filter((l) => /logo/i.test(l.role ?? \"\")).map((l) => l.text);\n const boxes = withWordmark(read, logoWords);\n const lines = copy.filter((l) => !/logo/i.test(l.role ?? \"\"));\n const headline = headlineBox(lines, boxes);\n const all = lines.flatMap((l) => boxesOfLine(l, boxes));\n const inHeadline = (b: TextBox) =>\n headline !== null && b.x0 >= headline.x0 && b.y0 >= headline.y0 && b.x1 <= headline.x1 && b.y1 <= headline.y1;\n return { headline, others: all.filter((b) => !inHeadline(b)) };\n}\n","import { createRequire } from \"node:module\";\nimport { z } from \"zod\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport {\n frameGround,\n type NativeAssets,\n nativeSurfaceHtml,\n readInterfaceWords,\n} from \"../../scaffold/native-surface.ts\";\nimport { nativeLayoutInsets } from \"../../scaffold/platform-safe-area.ts\";\nimport { readAdSpec } from \"../../scaffold/static-ad-spec.ts\";\nimport { deliveredSize } from \"../../scaffold/static-sizes.ts\";\nimport { FontRef, ImageRef, JsonRef } from \"../../schema/refs.ts\";\nimport { dataUrl, inkLightness, logoFor, markOfLockup, wholeLogos } from \"./lib/native-assets.ts\";\nimport { bytesOf } from \"./lib/static-review.ts\";\n\nconst require_ = createRequire(import.meta.url);\n\n/** How long the page may take to load its fonts and pictures, and then to lay itself out. */\nconst LOAD_TIMEOUT_MS = 25_000;\n/** How long the screenshot itself may take once the page is ready. */\nconst SCREENSHOT_TIMEOUT_MS = 30_000;\n/** The longest one screen may take, browser start to picture: past it the render is stopped. */\nconst RENDER_DEADLINE_MS = 90_000;\n\n/** A screen that did not finish drawing in time: the run fails with it rather than hanging. */\nexport class NativeRenderTimeoutError extends Error {\n readonly code = \"native_render_timeout\";\n readonly stage: string;\n readonly ms: number;\n constructor(stage: string, ms: number) {\n super(\n `static_native: the screen was still ${stage} after ${Math.round(ms / 1000)}s, so it was stopped. Nothing is billed for this node: run the canvas again. If it stalls again, the computer is short of CPU or network right now; prompt.json is not the cause.`,\n );\n this.name = \"NativeRenderTimeoutError\";\n this.stage = stage;\n this.ms = ms;\n }\n}\n\n/** How long the font host may take to answer one request before the page draws in its fallback face. */\nconst FONT_REQUEST_MS = 8_000;\n\n/** The requests a screen makes to the web-font host. */\nconst WEB_FONT_HOSTS = /^https:\\/\\/fonts\\.(googleapis|gstatic)\\.com\\//;\n\ntype WebFontRoute<R> = {\n fetch(options: { timeout: number }): Promise<R>;\n fulfill(options: { response: R }): Promise<void>;\n abort(errorCode?: string): Promise<void>;\n};\n\n/**\n * Pass one web-font request through, or fail it once the host has taken `timeoutMs`: a slow or\n * unreachable font host then costs a fallback face, never a hung page (the browser would wait on\n * the stylesheet, and the screenshot on the fonts, as long as the host keeps the socket open).\n */\nexport async function serveWebFont<R>(route: WebFontRoute<R>, timeoutMs: number): Promise<void> {\n const response = await route.fetch({ timeout: timeoutMs }).catch(() => null);\n // The page may be gone by now (the render stopped): nothing is waiting on the answer then.\n if (response === null) await route.abort(\"timedout\").catch(() => undefined);\n else await route.fulfill({ response }).catch(() => undefined);\n}\n\n/** `work`, or the error `expire` makes once `ms` pass without it settling. */\nexport function withDeadline<T>(work: Promise<T>, ms: number, expire: () => Error): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(expire()), ms);\n });\n return Promise.race([work, deadline]).finally(() => clearTimeout(timer));\n}\n\ntype Asset = { path?: string | undefined; url?: string | undefined };\n\nconst sourceOf = (asset: Asset | undefined): string | undefined => asset?.path ?? asset?.url;\n\nasync function fileOf(asset: Asset | undefined): Promise<{ bytes: Buffer; name: string } | undefined> {\n const source = sourceOf(asset);\n if (!source) return undefined;\n return { bytes: await bytesOf(source), name: source };\n}\n\n/** Whether a hex colour is dark enough to need light type and a light logo. */\nfunction darkHex(hex: string): boolean {\n const n = Number.parseInt(hex.slice(1), 16);\n return 0.2126 * ((n >> 16) & 255) + 0.7152 * ((n >> 8) & 255) + 0.0722 * (n & 255) < 140;\n}\n\nexport const staticNativeNode = defineNode({\n id: \"static_native\",\n version: \"1.0.0\",\n category: \"image\",\n location: \"local\",\n summary:\n \"Draw a static ad that is a screen people know (a post on X, a WhatsApp or iMessage chat, a wall of Trustpilot or Google reviews, a note, a Slack message) exactly, from HTML, at one delivered size: the `native` block of the ad spec (prompt.json) is laid out in the platform's own layout, type and colours, with the brand's real logo and the photos given, fitted inside the size's safe area. Free and deterministic.\",\n when_to_use:\n \"Scaffolded by `baker canvas scaffold-static-ad` for an ad spec with a `native` block, one node per size (`native_<size>`, role `static_native`). Edit prompt.json's `native` and run again: nothing is billed but the photos whose description changed.\",\n inputs: z\n .object({\n spec: JsonRef,\n /** The brand's logo files (every variant the brand has): the one that reads on the screen is used. */\n logos: z.array(ImageRef).optional(),\n /** The brand's square mark, for an avatar; else cut from the logo's lockup. */\n mark: ImageRef.optional(),\n /** The brand's face, for the frame's headline. */\n font: FontRef.optional(),\n /** The photos the screen shows, in `params.photo_ids` order. */\n photos: z.array(ImageRef).optional(),\n })\n .strict(),\n params: z\n .object({\n format: z.string().min(1),\n placements: z.array(z.string().min(1)).optional(),\n photo_ids: z.array(z.string().regex(/^PHOTO_\\d+$/)).default([]),\n /** The interface's own words written for the viewer's language, when no checked ones exist (`needsInterfaceWords`). */\n interface_words: z.record(z.string(), z.string()).optional(),\n })\n .strict(),\n outputs: z\n .object({\n image: ImageRef,\n // A chat's earliest lines this size scrolled up under its header to keep the rest readable.\n scrolled: z.array(z.string()).optional(),\n })\n .strict(),\n outputKinds: { image: \"image\" },\n cost: () => ({ credits: 0, seconds_estimate: 4 }),\n async execute({ inputs, params, ctx }) {\n const specSource = sourceOf(inputs.spec);\n if (!specSource) throw new Error(\"static_native: the ad spec (prompt.json) has no file to read\");\n const spec = readAdSpec(JSON.parse((await bytesOf(specSource)).toString(\"utf8\")));\n if (!spec.native) throw new Error(\"static_native: prompt.json has no `native` block to draw\");\n const files = {\n logos: (await Promise.all((inputs.logos ?? []).map(fileOf))).filter((f) => f !== undefined),\n mark: await fileOf(inputs.mark),\n font: await fileOf(inputs.font),\n photos: await Promise.all((inputs.photos ?? []).map(fileOf)),\n };\n const html = await nativePage(spec, files, params);\n const size = deliveredSize(params.format);\n const { png, scrolled } = await screenshot(html, size, ctx.log);\n const image = await ctx.assets.ingestBytes({\n bytes: png,\n kind: \"image\",\n mime: \"image/png\",\n metadata: { width: size.width, height: size.height },\n });\n return { image: image as z.infer<typeof ImageRef>, ...(scrolled.length > 0 ? { scrolled } : {}) };\n },\n});\n\ntype File = { bytes: Buffer; name: string };\n\n/** The pictures as the page loads them: the logo that reads on a card and the one on the ground, the mark, the photos by id. */\nasync function pageAssets(\n files: { logos: File[]; mark?: File | undefined; font?: File | undefined; photos: Array<File | undefined> },\n photoIds: readonly string[],\n ground: string,\n): Promise<NativeAssets> {\n // A logo file cropped through its letters gives way to a whole one, the brand's mark last.\n const whole = await wholeLogos(files.mark ? [...files.logos, files.mark] : files.logos);\n const wholeOfLogos = whole.filter((l) => files.logos.includes(l));\n const logos = wholeOfLogos.length > 0 ? wholeOfLogos : whole;\n const logo = await logoFor(logos, false);\n // The frame's own logo sits on the colour the frame is drawn on.\n const frameLogo = await logoFor(logos, darkHex(ground));\n const cut = !files.mark && logo ? await markOfLockup(logo.bytes).catch(() => null) : null;\n const mark = files.mark ? dataUrl(files.mark.bytes, files.mark.name) : cut ? dataUrl(cut, \"mark.png\") : undefined;\n const photos: Record<string, string> = {};\n photoIds.forEach((id, i) => {\n const file = files.photos[i];\n if (file) photos[id] = dataUrl(file.bytes, file.name);\n });\n // A brand with only a white logo: it is inked dark where it sits on a light ground.\n const light = await Promise.all(\n [logo, frameLogo].map(async (l) =>\n l && ((await inkLightness(l.bytes).catch(() => null)) ?? 0) > 200 ? dataUrl(l.bytes, l.name) : null,\n ),\n );\n const lightLogos = light.filter((u): u is string => u !== null);\n return {\n ...(lightLogos.length > 0 ? { lightLogos } : {}),\n ...(logo ? { logo: dataUrl(logo.bytes, logo.name) } : {}),\n ...(frameLogo ? { frameLogo: dataUrl(frameLogo.bytes, frameLogo.name) } : {}),\n ...(mark ? { mark } : {}),\n ...(files.font ? { font: dataUrl(files.font.bytes, files.font.name) } : {}),\n photos,\n };\n}\n\n/** The page for one size: the spec's screen, its pictures as data URLs, the brand's logo that reads on it. */\nexport async function nativePage(\n spec: ReturnType<typeof readAdSpec>,\n files: { logos: File[]; mark?: File | undefined; font?: File | undefined; photos: Array<File | undefined> },\n params: {\n format: string;\n placements?: string[] | undefined;\n photo_ids: string[];\n interface_words?: Record<string, string> | undefined;\n },\n): Promise<string> {\n const native = spec.native;\n if (!native) throw new Error(\"static_native: prompt.json has no `native` block to draw\");\n const size = deliveredSize(params.format);\n const words = readInterfaceWords(params.interface_words);\n // The frame's logo is picked for the colour it is drawn on at this size.\n const assets = await pageAssets(\n files,\n params.photo_ids,\n frameGround(native, spec.brand?.ground ? { ground: spec.brand.ground } : {}, size),\n );\n return nativeSurfaceHtml(native, assets, {\n width: size.width,\n height: size.height,\n safe: nativeLayoutInsets(params.format, params.placements),\n brand: {\n ...(spec.brand?.name ? { name: spec.brand.name } : {}),\n ...(spec.brand?.ground ? { ground: spec.brand.ground } : {}),\n ...(spec.brand?.ink ? { ink: spec.brand.ink } : {}),\n ...(spec.brand?.accent ? { accent: spec.brand.accent } : {}),\n },\n ...(spec.viewer?.market?.language ? { language: spec.viewer.market.language } : {}),\n ...(words ? { words } : {}),\n });\n}\n\nasync function screenshot(\n html: string,\n size: { width: number; height: number },\n log: (s: string) => void,\n): Promise<{ png: Buffer; scrolled: string[] }> {\n const playwright = require_([\"play\", \"wright\"].join(\"\")) as typeof import(\"playwright\");\n let stage = \"starting the browser\";\n const held: { browser?: import(\"playwright\").Browser; stopped?: true } = {};\n const draw = async (): Promise<{ png: Buffer; scrolled: string[] }> => {\n const browser = await playwright.chromium.launch({ headless: true });\n held.browser = browser;\n // A browser that started only after the deadline is closed by nobody else.\n if (held.stopped) await browser.close().catch(() => undefined);\n const context = await browser.newContext({\n viewport: { width: size.width / 2, height: size.height / 2 },\n deviceScaleFactor: 2,\n });\n const page = await context.newPage();\n await page.route(WEB_FONT_HOSTS, (route) => serveWebFont(route, FONT_REQUEST_MS));\n stage = \"loading its fonts and pictures\";\n // Fonts load from the web; a page that cannot reach them still draws, in the fallback face.\n await page\n .setContent(html, { waitUntil: \"load\", timeout: LOAD_TIMEOUT_MS })\n .catch((e: Error) => log(`load: ${e.message}`));\n stage = \"laying the screen out\";\n await page.waitForSelector(\"body[data-ready]\", { timeout: LOAD_TIMEOUT_MS });\n stage = \"taking the picture\";\n const png = Buffer.from(await page.screenshot({ type: \"png\", timeout: SCREENSHOT_TIMEOUT_MS }));\n const hidden = await page.evaluate(() => document.body.dataset.hidden ?? \"[]\");\n const scrolled = JSON.parse(hidden) as unknown;\n return { png, scrolled: Array.isArray(scrolled) ? scrolled.filter((t): t is string => typeof t === \"string\") : [] };\n };\n try {\n return await withDeadline(\n draw(),\n RENDER_DEADLINE_MS,\n () => new NativeRenderTimeoutError(stage, RENDER_DEADLINE_MS),\n );\n } finally {\n // Closed on a stall too, so the stopped page cannot keep the run alive.\n held.stopped = true;\n await held.browser?.close().catch(() => undefined);\n }\n}\n","/**\n * The pictures a native surface is drawn with, made ready for the page: the brand's logo in the\n * variant that reads on the screen's colour, its square mark for an avatar, and every picture as a\n * data URL the page loads without a server.\n */\nimport sharp from \"sharp\";\n\nconst MIME: Record<string, string> = {\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n woff2: \"font/woff2\",\n woff: \"font/woff\",\n ttf: \"font/ttf\",\n otf: \"font/otf\",\n};\n\n/** A file's bytes as a data URL, its type read off its name. */\nexport function dataUrl(bytes: Buffer, name: string): string {\n const ext = name.split(/[?#]/)[0]?.split(\".\").pop()?.toLowerCase() ?? \"png\";\n return `data:${MIME[ext] ?? \"application/octet-stream\"};base64,${bytes.toString(\"base64\")}`;\n}\n\n/** How light a picture's drawn pixels are (0 black, 255 white), ignoring what is transparent; null when nothing is drawn. */\nexport async function inkLightness(bytes: Buffer): Promise<number | null> {\n const { data, info } = await sharp(bytes)\n .resize({ width: 200, height: 200, fit: \"inside\" })\n .ensureAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true });\n let sum = 0;\n let n = 0;\n for (let i = 0; i < data.length; i += info.channels) {\n const alpha = data[i + 3] ?? 0;\n if (alpha < 128) continue;\n sum += 0.2126 * (data[i] ?? 0) + 0.7152 * (data[i + 1] ?? 0) + 0.0722 * (data[i + 2] ?? 0);\n n++;\n }\n return n === 0 ? null : sum / n;\n}\n\n/**\n * Of the brand's logo files, the one that reads on a background: on a light one the darker ink,\n * on a dark one the lighter. Audited Oct 2026: a white wordmark on the white review card showed\n * only the icon. The first when none can be read.\n */\nexport async function logoFor<T extends { bytes: Buffer }>(\n logos: readonly T[],\n backgroundIsDark: boolean,\n): Promise<T | undefined> {\n if (logos.length <= 1) return logos[0];\n const scored = await Promise.all(logos.map(async (l) => ({ l, ink: await inkLightness(l.bytes).catch(() => null) })));\n const read = scored.filter((s): s is { l: T; ink: number } => s.ink !== null);\n if (read.length === 0) return logos[0];\n read.sort((a, b) => (backgroundIsDark ? b.ink - a.ink : a.ink - b.ink));\n return read[0]?.l;\n}\n\n/**\n * Whether a logo file's drawing runs off its own edge: a file cropped through its letters. Ink is\n * what is opaque and unlike the file's corner (its background, transparent or not).\n */\nasync function runsOffEdge(bytes: Buffer): Promise<boolean> {\n const { data, info } = await sharp(bytes)\n .resize({ width: 400, height: 400, fit: \"inside\" })\n .ensureAlpha()\n .raw()\n .toBuffer({ resolveWithObject: true });\n const { width, height, channels } = info;\n const at = (x: number, y: number) => (y * width + x) * channels;\n const corner = [0, 1, 2, 3].map((c) => data[c] ?? 0);\n const ink = (x: number, y: number) => {\n const i = at(x, y);\n if ((data[i + 3] ?? 0) <= 40) return false;\n return (corner[3] ?? 0) <= 40 || [0, 1, 2].some((c) => Math.abs((data[i + c] ?? 0) - (corner[c] ?? 0)) > 60);\n };\n const share = (n: number, hit: (i: number) => boolean) => {\n let k = 0;\n for (let i = 0; i < n; i++) if (hit(i)) k++;\n return k / n;\n };\n const edges = [\n share(width, (x) => ink(x, 0)),\n share(width, (x) => ink(x, height - 1)),\n share(height, (y) => ink(0, y)),\n share(height, (y) => ink(width - 1, y)),\n ];\n return edges.some((e) => e > 0.02);\n}\n\n/** The brand's logo files whose drawing is whole, or every file when none is (a cropped one is better than none). */\nexport async function wholeLogos<T extends { bytes: Buffer }>(logos: readonly T[]): Promise<T[]> {\n const cut = await Promise.all(logos.map((l) => runsOffEdge(l.bytes).catch(() => false)));\n const whole = logos.filter((_, i) => !cut[i]);\n return whole.length > 0 ? whole : [...logos];\n}\n\n/**\n * The square mark at the head of a lockup (an icon, then a gap, then the wordmark), for an avatar:\n * a lockup in a circle is a line of letters too small to read. Null when the logo is not such a\n * lockup (a wordmark alone, a stacked logo): the avatar then shows the whole logo, contained.\n */\nexport async function markOfLockup(bytes: Buffer): Promise<Buffer | null> {\n const { data, info } = await sharp(bytes).ensureAlpha().raw().toBuffer({ resolveWithObject: true });\n const alpha = (x: number, y: number) => (data[(y * info.width + x) * info.channels + 3] ?? 0) > 40;\n const box = drawnBox(alpha, info.width, info.height);\n if (!box || box.width / box.height < 1.8) return null;\n const mark = leadingMark(alpha, box);\n return mark ? await sharp(bytes).extract(mark).png().toBuffer() : null;\n}\n\ntype Box = { left: number; top: number; width: number; height: number };\ntype Opaque = (x: number, y: number) => boolean;\n\nfunction anyIn(from: number, to: number, hit: (i: number) => boolean): boolean {\n for (let i = from; i <= to; i++) if (hit(i)) return true;\n return false;\n}\n\n/** The box the logo is drawn in, past the file's own transparent margin; null when nothing is drawn. */\nfunction drawnBox(opaque: Opaque, width: number, height: number): Box | null {\n const row = (y: number) => anyIn(0, width - 1, (x) => opaque(x, y));\n let top = 0;\n while (top < height && !row(top)) top++;\n if (top >= height) return null;\n let bottom = height - 1;\n while (bottom > top && !row(bottom)) bottom--;\n const column = (x: number) => anyIn(top, bottom, (y) => opaque(x, y));\n let left = 0;\n while (left < width && !column(left)) left++;\n let right = width - 1;\n while (right > left && !column(right)) right--;\n return { left, top, width: right - left + 1, height: bottom - top + 1 };\n}\n\n/**\n * The mark at the head of a lockup: the first run of drawn columns, roughly square, spanning the\n * lockup's height (a wordmark's first letter, a \"p\", leaves the ascenders' top), then a gap.\n */\nfunction leadingMark(opaque: Opaque, box: Box): Box | null {\n const bottom = box.top + box.height - 1;\n const right = box.left + box.width - 1;\n const column = (x: number) => anyIn(box.top, bottom, (y) => opaque(x, y));\n let x = box.left;\n while (x <= right && column(x)) x++;\n let gap = x;\n while (gap <= right && !column(gap)) gap++;\n const width = x - box.left;\n const ratio = width / box.height;\n if (gap > right || gap - x < box.height * 0.05 || ratio < 0.75 || ratio > 1.4) return null;\n const row = (y: number) => anyIn(box.left, x - 1, (cx) => opaque(cx, y));\n let markTop = box.top;\n while (markTop < bottom && !row(markTop)) markTop++;\n let markBottom = bottom;\n while (markBottom > markTop && !row(markBottom)) markBottom--;\n if ((markBottom - markTop + 1) / box.height < 0.85) return null;\n return { left: box.left, top: box.top, width, height: box.height };\n}\n","import { z } from \"zod\";\nimport type { ExecCtx } from \"../../engine/context.ts\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport { ImageRef } from \"../../schema/refs.ts\";\nimport { callBackendExec } from \"../remote/delegate.ts\";\nimport { imageGenerateNode } from \"../remote/image.ts\";\nimport { MIN_EXTEND_SCALE, mergeExtended, placeForExtend } from \"./lib/extend-fit.ts\";\nimport type { ReviewUsage } from \"./lib/render-review.ts\";\nimport { boxesToPlace, planSafeFit, type SafeFit } from \"./lib/safe-fit.ts\";\nimport { bytesOf } from \"./lib/static-review.ts\";\nimport { readTextBoxes, type TextBox } from \"./lib/text-boxes.ts\";\n\nconst Usage = z\n .object({ model: z.string(), inputTokens: z.number(), outputTokens: z.number(), costUsd: z.number() })\n .strict();\nconst Fit = z.object({ scale: z.number(), x: z.number(), y: z.number() }).strict();\nconst Unit = z.number().min(0).max(1);\n/** A box as fractions of the frame, origin top-left. */\nconst Span = z.object({ x0: Unit, y0: Unit, x1: Unit, y1: Unit }).strict();\n/** The image model's render shape, which the grey canvas it paints is made in (\"9:16\", \"3:4\"). */\nconst RenderRatio = z.string().regex(/^\\d+(?:\\.\\d+)?:\\d+(?:\\.\\d+)?$/);\n/** The ad's copy (prompt.json's lines and their roles): the fit moves the ad for these and its logo only. */\nconst Copy = z.array(z.object({ text: z.string().min(1), role: z.string().optional() }).strict());\n\nexport const staticPlaceNode = defineNode({\n id: \"static_place\",\n version: \"1.1.0\",\n category: \"image\",\n location: \"local\",\n summary:\n \"Place a finished static ad's words and logo where no interface covers them and nothing runs off the frame, for an image model to paint the margins: reads where every line and the logo sit, shrinks the ad (to 60% at most) and sets it inside the size's safe area. `placed` keeps the margins clear (for `static_extend_merge`); `shown` is the same inside the model's render shape with grey margins, to paint; `keep` is where every line, the logo and the buttons read sit in `placed`, all the merge lays back of the ad's own pixels. `fit` is null, and both are the ad unchanged, when nothing sits outside.\",\n when_to_use:\n \"Added by a static ad's autofix round (place-and-extend) before an `image_generate` that paints the margins and a `static_extend_merge`; never scaffolded. One box-reader call (about $0.005).\",\n inputs: z.object({ image: ImageRef }).strict(),\n params: z\n .object({\n format: z.string().min(1),\n placements: z.array(z.string().min(1)).optional(),\n render_ratio: RenderRatio,\n copy: Copy.optional(),\n })\n .strict(),\n outputs: z\n .object({\n placed: ImageRef,\n shown: ImageRef,\n fit: Fit.nullable(),\n /** Where the words, logo and buttons read sit in `placed`: all the merge lays back of the ad's own pixels. */\n keep: z.array(Span).optional(),\n reason: z.enum([\"not_read\", \"inside_band\", \"too_far\"]).optional(),\n usage: z.array(Usage).optional(),\n })\n .strict(),\n outputKinds: { placed: \"image\", shown: \"image\" },\n cost: () => ({ credits: 0, seconds_estimate: 5 }),\n async execute({ inputs, params, ctx }) {\n const unchanged = { placed: inputs.image, shown: inputs.image, fit: null, keep: [] };\n const source = inputs.image.path ?? inputs.image.url;\n if (!source) return { ...unchanged, reason: \"not_read\" as const };\n const bytes = await bytesOf(source);\n const usage: ReviewUsage[] = [];\n const reading = await readTextBoxes(bytes, { onSpend: (u) => usage.push(u) });\n const spend = usage.length > 0 ? { usage } : {};\n if (reading.status !== \"read\") return { ...unchanged, reason: \"not_read\" as const, ...spend };\n const boxes = boxesToPlace(reading.boxes, params.format, {\n ...(params.placements ? { placements: params.placements } : {}),\n ...(params.copy ? { copy: params.copy } : {}),\n });\n const fit = planSafeFit(boxes, params.format, {\n ...(params.placements ? { placements: params.placements } : {}),\n minScale: MIN_EXTEND_SCALE,\n contain: true,\n });\n if (!fit) {\n // Inside the band already, or too far past it for a shrink to clear: the size is laid out again instead.\n const loose = planSafeFit(boxes, params.format, {\n ...(params.placements ? { placements: params.placements } : {}),\n minScale: 0,\n });\n return { ...unchanged, reason: loose ? (\"too_far\" as const) : (\"inside_band\" as const), ...spend };\n }\n const { placed, shown } = await placeForExtend(bytes, fit, params.render_ratio);\n ctx.log(\n `placed ${params.format} at scale ${fit.scale.toFixed(3)}, offset ${fit.x.toFixed(3)}, ${fit.y.toFixed(3)}`,\n );\n const [placedRef, shownRef] = await Promise.all([\n ctx.assets.ingestBytes({ bytes: placed, kind: \"image\", mime: \"image/png\" }),\n ctx.assets.ingestBytes({ bytes: shown, kind: \"image\", mime: \"image/png\" }),\n ]);\n return {\n placed: placedRef as z.infer<typeof ImageRef>,\n shown: shownRef as z.infer<typeof ImageRef>,\n fit,\n keep: keptBoxes([...reading.boxes, ...boxes.filter((b) => !reading.boxes.includes(b))], fit),\n ...spend,\n };\n },\n});\n\n/** Each box as `fit` set it in the placed frame (shrunk, then offset), kept inside the frame. Pure. */\nfunction keptBoxes(boxes: readonly TextBox[], fit: SafeFit): Array<z.infer<typeof Span>> {\n const at = (offset: number, v: number) => Math.min(1, Math.max(0, offset + fit.scale * v));\n return boxes.map((b) => ({ x0: at(fit.x, b.x0), y0: at(fit.y, b.y0), x1: at(fit.x, b.x1), y1: at(fit.y, b.y1) }));\n}\n\nexport const staticExtendMergeNode = defineNode({\n id: \"static_extend_merge\",\n version: \"1.2.0\",\n category: \"image\",\n location: \"local\",\n // A size never placed paints nothing and reaches no backend: its record says 0, not a paint's estimate.\n billing: \"reported\",\n summary:\n \"Have the image model paint a placed static ad's margins (`static_place`'s `shown`, with `paint`, an `image_generate`'s params) and lay the ad's own pixels back over the painting only in `keep` (`static_place`'s boxes of the words, logo and buttons, padded and feathered): the painting is the rest of the frame, one picture with no edge where the shrunk ad was. Without `keep`, or when the painting moved the words, the whole ad (`placed`) is laid back, the painting only in the margins, blended at their seam. Same pixel size as the ad. An ad that was never placed (`shown` is `placed`) passes on as it is, and nothing is painted or billed. A painting already made can be wired as `image` instead of `paint`.\",\n when_to_use:\n \"Added by a static ad's autofix round after a `static_place`; never scaffolded. One picture at the painter's price, only for a size that was placed.\",\n inputs: z\n .object({\n placed: ImageRef,\n shown: ImageRef.optional(),\n image: ImageRef.optional(),\n keep: z.array(Span).optional(),\n })\n .strict(),\n params: z.object({ render_ratio: RenderRatio, paint: z.record(z.string(), z.unknown()).optional() }).strict(),\n outputs: z.object({ image: ImageRef }).strict(),\n outputKinds: { image: \"image\" },\n cost: ({ params }) =>\n params.paint ? (imageGenerateNode.cost?.({ params: params.paint as never }) ?? NO_COST) : NO_COST,\n async execute({ inputs, params, ctx }) {\n const painting = inputs.image ?? (await paintMargins(inputs, params.paint, ctx));\n const painted = painting?.path ?? painting?.url;\n const placed = inputs.placed.path ?? inputs.placed.url;\n if (!painted || !placed) return { image: inputs.placed };\n // Only the words, logo and buttons are laid back; a product, person or illustration is the painting's.\n // Bench, Oct 2026 (28 prod paintings): a painting that kept the words in place kept the scene's subjects\n // too (faces, phones, products redrawn where they were), and protecting them would bring the rectangle's edge back.\n const merged = await mergeExtended(await bytesOf(painted), await bytesOf(placed), params.render_ratio, inputs.keep);\n const image = await ctx.assets.ingestBytes({ bytes: merged, kind: \"image\", mime: \"image/png\" });\n return { image: image as z.infer<typeof ImageRef> };\n },\n});\n\nconst NO_COST = { credits: 0, seconds_estimate: 2 };\n\n/** The painter's picture of the margins `shown` leaves, or null for an ad that was never placed. */\nasync function paintMargins(\n inputs: { placed: z.infer<typeof ImageRef>; shown?: z.infer<typeof ImageRef> },\n paint: Record<string, unknown> | undefined,\n ctx: ExecCtx,\n): Promise<z.infer<typeof ImageRef> | null> {\n const { shown, placed } = inputs;\n if (!paint || !shown || shown.sha256 === placed.sha256) return null;\n const params = imageGenerateNode.params.parse(paint);\n const out = await callBackendExec({\n nodeType: imageGenerateNode.id,\n nodeVersion: imageGenerateNode.version,\n params,\n inputs: { reference: [shown] },\n outputKinds: { images: \"image\" },\n ctx,\n });\n const images = out.images;\n return Array.isArray(images) ? ((images[0] as z.infer<typeof ImageRef> | undefined) ?? null) : null;\n}\n","/**\n * The autofix's place-and-extend: when a size's words or logo sit where an interface covers them\n * (Reels' footer) or run off its edge, code shrinks and places the finished ad where nothing covers\n * it (`planSafeFit` with `MIN_EXTEND_SCALE`), the image model paints only the margins that leaves,\n * and code lays the ad's own pixels back over its painting. Why: told to move a button above 72%\n * of the height, the model moved it from 91% to 86% in two rounds (Oct 2026 bench); it keeps what\n * is there well, and moves it badly. `placeForExtend` and `mergeExtended` only transform bytes.\n */\nimport sharp from \"sharp\";\nimport { plainEdge, type Raw, type SafeFit } from \"./safe-fit.ts\";\n\n/**\n * The smallest scale place-and-extend takes: the words stay readable at a glance and the ad stays\n * the ad; past it the size is laid out again instead. Bench, Oct 2026: a re-laid 9:16 fills its\n * height (3%-93%), and clearing Reels took 0.65-0.67; its type is set larger than the 4:5's, so at\n * 0.6 its words are still the 4:5's size.\n */\nexport const MIN_EXTEND_SCALE = 0.6;\n\n/** The margins the model is asked to paint, in a grey nothing in an ad is. */\nconst GREY_LEVEL = 128;\nconst GREY = { r: GREY_LEVEL, g: GREY_LEVEL, b: GREY_LEVEL };\n\n/** How far into the ad its edge blends into the painting, as a share of the frame's width. */\nconst FEATHER = 0.012;\n\n/** How far past a kept box the ad's own pixels reach, as a share of the box's height. */\nconst KEEP_PAD = 0.3;\n/** How far past that a kept box fades into the painting, as a share of the frame's width. */\nconst KEEP_FEATHER = 0.03;\n/**\n * The most a painting may differ from the ad inside its kept boxes (the median box's mean, summed\n * over channels) and still have kept the words where they were. Bench, Oct 2026, 28 prod paintings:\n * 24 that kept the ad in place read 15-61, 4 that re-laid it 218-296, its words then laid back twice.\n */\nconst MOVED = 120;\n\ntype Box = { width: number; height: number; left: number; top: number };\n\nfunction ratioOf(ratio: string): number {\n const [w = 1, h = 1] = ratio.split(\":\").map(Number);\n return w / h;\n}\n\n/** The model's render shape around a frame: the frame centred in it, the rest to paint. */\nfunction renderCanvas(frame: { width: number; height: number }, ratio: string): Box {\n const r = ratioOf(ratio);\n const f = frame.width / frame.height;\n if (Math.abs(r - f) < 1e-3) return { width: frame.width, height: frame.height, left: 0, top: 0 };\n if (r < f) {\n const height = Math.round(frame.width / r);\n return { width: frame.width, height, left: 0, top: Math.round((height - frame.height) / 2) };\n }\n const width = Math.round(frame.height * r);\n return { width, height: frame.height, left: Math.round((width - frame.width) / 2), top: 0 };\n}\n\n/**\n * The ad shrunk and set as `fit` says, at its own pixel size: `placed` with clear margins, for the\n * merge; `shown`, the same inside the model's render shape (`ratio`) with grey margins, to paint.\n */\nexport async function placeForExtend(\n image: Buffer,\n fit: SafeFit,\n ratio: string,\n): Promise<{ placed: Buffer; shown: Buffer }> {\n const { width = 0, height = 0 } = await sharp(image).metadata();\n const sw = Math.max(1, Math.round(width * fit.scale));\n const sh = Math.max(1, Math.round(height * fit.scale));\n const px = Math.round(fit.x * width);\n const py = Math.round(fit.y * height);\n const left = Math.max(0, -px);\n const top = Math.max(0, -py);\n const w = Math.min(sw, width - px) - left;\n const h = Math.min(sh, height - py) - top;\n const shrunk = await sharp(image)\n .removeAlpha()\n .resize(sw, sh, { fit: \"fill\", kernel: \"lanczos3\" })\n .extract({ left, top, width: w, height: h })\n .raw()\n .toBuffer({ resolveWithObject: true });\n const raw: Raw = { data: shrunk.data, width: w, height: h, channels: shrunk.info.channels };\n const margin = { left: Math.max(0, px), top: Math.max(0, py), right: 0, bottom: 0 };\n margin.right = width - margin.left - w;\n margin.bottom = height - margin.top - h;\n const carried = await sharp(shrunk.data, { raw: { width: w, height: h, channels: shrunk.info.channels } })\n .extend({ ...margin, extendWith: \"copy\" })\n .ensureAlpha()\n .raw()\n .toBuffer();\n const shownPixels = clearBusyMargins(carried, { width, height }, keptBox(raw, margin, { width, height }));\n const placed = await sharp(carried, { raw: { width, height, channels: 4 } })\n .png()\n .toBuffer();\n const canvas = renderCanvas({ width, height }, ratio);\n const frame = await sharp(shownPixels, { raw: { width, height, channels: 3 } })\n .png()\n .toBuffer();\n const shown = await sharp({ create: { width: canvas.width, height: canvas.height, channels: 3, background: GREY } })\n .composite([{ input: frame, left: canvas.left, top: canvas.top }])\n .png()\n .toBuffer();\n return { placed, shown };\n}\n\ntype Margins = { left: number; top: number; right: number; bottom: number };\n\n/**\n * What of the frame stays as placed: the ad, and each margin whose edge is plain ground, carried\n * on by code exactly; a margin beside a scene's edge is left to paint.\n */\nfunction keptBox(ad: Raw, margin: Margins, frame: { width: number; height: number }): Bounds {\n const plain = (side: keyof Margins) => margin[side] === 0 || plainEdge(ad, side);\n return {\n x0: plain(\"left\") ? 0 : margin.left,\n y0: plain(\"top\") ? 0 : margin.top,\n x1: plain(\"right\") ? frame.width - 1 : margin.left + ad.width - 1,\n y1: plain(\"bottom\") ? frame.height - 1 : margin.top + ad.height - 1,\n };\n}\n\n/** `rgba` cleared (alpha 0) outside `keep`, and the picture the model is shown: the same, grey where cleared. */\nfunction clearBusyMargins(rgba: Buffer, frame: { width: number; height: number }, keep: Bounds): Buffer {\n const shown = Buffer.alloc(frame.width * frame.height * 3, GREY_LEVEL);\n for (let y = keep.y0; y <= keep.y1; y++) {\n for (let x = keep.x0; x <= keep.x1; x++) {\n const i = y * frame.width + x;\n rgba.copy(shown, i * 3, i * 4, i * 4 + 3);\n }\n }\n for (let i = 0; i < frame.width * frame.height; i++) {\n const x = i % frame.width;\n const y = Math.floor(i / frame.width);\n rgba[i * 4 + 3] = x >= keep.x0 && x <= keep.x1 && y >= keep.y0 && y <= keep.y1 ? 255 : 0;\n }\n return shown;\n}\n\n/** A rectangle as fractions of the frame, origin top-left. */\nexport type Span = { x0: number; y0: number; x1: number; y1: number };\n\n/**\n * The model's painting (`extended`, of the `shown` canvas) with the ad's own pixels (`placed`)\n * laid back. Given `keep` (the words', logo's and buttons' boxes in the placed frame), only those,\n * each padded by `KEEP_PAD` and feathered over `KEEP_FEATHER`: the painting is the rest of the\n * frame, one picture with no edge where the ad's rectangle was. Without, the whole ad, the painting\n * only where `placed` is clear, blended over `FEATHER` at the ad's edges inside the frame. `placed`\n * with no clear pixel was never placed, and passes on as it is.\n */\nexport async function mergeExtended(\n extended: Buffer,\n placed: Buffer,\n ratio: string,\n keep: readonly Span[] = [],\n): Promise<Buffer> {\n const ad = await sharp(placed).ensureAlpha().raw().toBuffer({ resolveWithObject: true });\n const { width, height } = ad.info;\n const bounds = placedBounds(ad.data, width, height);\n if (!bounds) return sharp(placed).removeAlpha().png().toBuffer();\n const canvas = renderCanvas({ width, height }, ratio);\n const paint = await sharp(extended)\n .removeAlpha()\n .resize(canvas.width, canvas.height, { fit: \"fill\" })\n .extract({ left: canvas.left, top: canvas.top, width, height })\n .raw()\n .toBuffer();\n const edge = edgeWeight(bounds, width, height, Math.max(1, Math.round(FEATHER * width)));\n const boxes =\n keep.length > 0 && keptInPlace(keep, ad.data, paint, width, height) ? keptWeights(keep, width, height) : null;\n const weight = boxes ? (x: number, y: number) => Math.min(edge(x, y), boxes[y * width + x] ?? 0) : edge;\n const out = Buffer.alloc(width * height * 3);\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const i = y * width + x;\n const w = weight(x, y);\n for (let c = 0; c < 3; c++) {\n out[i * 3 + c] = Math.round((ad.data[i * 4 + c] ?? 0) * w + (paint[i * 3 + c] ?? 0) * (1 - w));\n }\n }\n }\n return sharp(out, { raw: { width, height, channels: 3 } })\n .png()\n .toBuffer();\n}\n\ntype Bounds = Span;\n\n/** Where the placed ad's pixels are (its opaque box), or null when nothing of the frame is clear: it was never placed. */\nfunction placedBounds(rgba: Buffer, width: number, height: number): Bounds | null {\n const box: Bounds = { x0: width, y0: height, x1: -1, y1: -1 };\n let clear = false;\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n if ((rgba[(y * width + x) * 4 + 3] ?? 0) === 0) {\n clear = true;\n continue;\n }\n box.x0 = Math.min(box.x0, x);\n box.y0 = Math.min(box.y0, y);\n box.x1 = Math.max(box.x1, x);\n box.y1 = Math.max(box.y1, y);\n }\n }\n return clear && box.x1 >= 0 ? box : null;\n}\n\n/**\n * How much of the ad a pixel takes: 1 inside it, 0 in the margins, rising over `feather` pixels at\n * an edge of the ad inside the frame (one on the frame's own edge has nothing to meet).\n */\nfunction edgeWeight(b: Bounds, width: number, height: number, feather: number): (x: number, y: number) => number {\n const ramp = (d: number, onFrame: boolean) => (onFrame ? 1 : Math.min(1, (d + 1) / feather));\n return (x, y) =>\n x < b.x0 || x > b.x1 || y < b.y0 || y > b.y1\n ? 0\n : Math.min(\n ramp(x - b.x0, b.x0 === 0),\n ramp(b.x1 - x, b.x1 === width - 1),\n ramp(y - b.y0, b.y0 === 0),\n ramp(b.y1 - y, b.y1 === height - 1),\n );\n}\n\n/**\n * How much of the ad each pixel takes, given the boxes kept: 1 inside a box padded by `KEEP_PAD`\n * of its height, easing to 0 over `KEEP_FEATHER` of the frame's width outside it. Row-major.\n */\nfunction keptWeights(keep: readonly Span[], width: number, height: number): Float32Array {\n const out = new Float32Array(width * height);\n const feather = Math.max(1, KEEP_FEATHER * width);\n for (const box of keep) {\n const pad = KEEP_PAD * (box.y1 - box.y0) * height;\n const x0 = box.x0 * width - pad;\n const x1 = box.x1 * width + pad;\n const y0 = box.y0 * height - pad;\n const y1 = box.y1 * height + pad;\n const ys = Math.max(0, Math.floor(y0 - feather));\n const ye = Math.min(height - 1, Math.ceil(y1 + feather));\n const xs = Math.max(0, Math.floor(x0 - feather));\n const xe = Math.min(width - 1, Math.ceil(x1 + feather));\n for (let y = ys; y <= ye; y++) {\n const dy = Math.max(0, y0 - y, y - y1);\n for (let x = xs; x <= xe; x++) {\n const dx = Math.max(0, x0 - x, x - x1);\n const t = Math.max(0, 1 - Math.hypot(dx, dy) / feather);\n const w = t * t * (3 - 2 * t);\n const i = y * width + x;\n if (w > (out[i] ?? 0)) out[i] = w;\n }\n }\n }\n return out;\n}\n\n/**\n * Whether the painting kept the ad's words where they were: the median kept box, read where the ad\n * has pixels, differs from the ad by at most `MOVED`. A painting that re-laid the ad fails it.\n */\nfunction keptInPlace(keep: readonly Span[], ad: Buffer, paint: Buffer, width: number, height: number): boolean {\n const diffs = keep\n .map((box) => boxDiff(box, ad, paint, width, height))\n .filter((d): d is number => d !== null)\n .sort((a, b) => a - b);\n return (diffs[Math.floor(diffs.length / 2)] ?? Number.POSITIVE_INFINITY) <= MOVED;\n}\n\n/** How far the painting is from the ad inside `box`, per pixel the ad has, summed over channels; null when it has none. */\nfunction boxDiff(box: Span, ad: Buffer, paint: Buffer, width: number, height: number): number | null {\n let sum = 0;\n let n = 0;\n const xs = Math.floor(box.x0 * width);\n const xe = Math.min(width - 1, Math.ceil(box.x1 * width));\n for (let y = Math.floor(box.y0 * height); y <= Math.min(height - 1, Math.ceil(box.y1 * height)); y++) {\n for (let x = xs; x <= xe; x++) {\n const i = y * width + x;\n if ((ad[i * 4 + 3] ?? 0) === 0) continue;\n for (let c = 0; c < 3; c++) sum += Math.abs((ad[i * 4 + c] ?? 0) - (paint[i * 3 + c] ?? 0));\n n++;\n }\n }\n return n > 0 ? sum / n : null;\n}\n","import { nearestSupportedAspectRatio } from \"@baker/canvas-contract\";\nimport sharp from \"sharp\";\nimport { z } from \"zod\";\nimport type { ExecCtx } from \"../../engine/context.ts\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport { ImageRef } from \"../../schema/refs.ts\";\nimport { callBackendExec } from \"../remote/delegate.ts\";\nimport { imageGenerateNode } from \"../remote/image.ts\";\nimport { imageOf, isRead, pngOf, rawOf, type StepRun, subjectsStep, timedStep } from \"./lib/node-steps.ts\";\nimport {\n FROM_AD_MAX_EXTENSION,\n frameExtension,\n keepWeights,\n keptRegion,\n mergePlate,\n type PlateMode,\n plateFrame,\n spanOnPlate,\n} from \"./lib/plate-extend.ts\";\nimport type { ReviewUsage } from \"./lib/render-review.ts\";\nimport { paintedSubjects, readTwice, type SubjectReads } from \"./lib/size-consistency.ts\";\nimport { type SubjectBox, SubjectBoxSchema } from \"./lib/subject-boxes.ts\";\nimport type { PixelRect, Size } from \"./lib/subject-crop.ts\";\nimport { readTextBoxes, type TextBoxReading } from \"./lib/text-boxes.ts\";\nimport { type Raw, registerToSource, type Span, warpToCut } from \"./lib/words-layer.ts\";\nimport { splitWordBoxes } from \"./staticFormat.ts\";\n\nconst Usage = z\n .object({ model: z.string(), inputTokens: z.number(), outputTokens: z.number(), costUsd: z.number() })\n .strict();\nconst Copy = z.array(z.object({ text: z.string().min(1), role: z.string().optional() }).strict());\nconst Rect = z.object({ x: z.number(), y: z.number(), width: z.number(), height: z.number() }).strict();\nconst Dims = z.object({ width: z.number(), height: z.number() }).strict();\n\n/** What a plate node did, small enough for the run record (`facts`). */\nexport const PlateFacts = z\n .object({\n mode: z.enum([\"widen\", \"from_ad\"]),\n source: Dims,\n plate: Dims,\n /** The part of the source kept pixel for pixel, in its pixels, and where it sits on the plate. */\n kept: Rect,\n at: Rect,\n /** The share of the plate the model painted (margins, cleared words, the seam's blend). */\n painted: z.number(),\n /** How many word, logo and button boxes were painted out. */\n cleared: z.number(),\n /** `subject_added`: a person, face, animal or repeated product stands where only painting was (`added`). */\n reason: z.enum([\"not_read\", \"misaligned\", \"subject_added\"]).optional(),\n /** What the painting added that the picture it was painted from does not show, as the reader names it. */\n added: z.array(z.string()).optional(),\n identity: z.number(),\n steps: z.array(\n z\n .object({\n name: z.enum([\"subjects\", \"boxes\", \"paint\", \"check\"]),\n cached: z.boolean(),\n credits: z.number(),\n ms: z.number(),\n })\n .strict(),\n ),\n })\n .strict();\nexport type PlateFacts = z.infer<typeof PlateFacts>;\n\n/** The instruction every painting gets, by what is painted; the canvas may add the scene's own words after it. */\nexport const PLATE_PAINT_PROMPT: Readonly<Record<PlateMode, string>> = {\n widen:\n \"Image 1 is a picture with plain grey bands at its sides. Paint only the grey bands, so the scene continues naturally past the picture's edges: the same place, light, colours, perspective and depth of field. Keep everything that is not grey exactly as it is, pixel for pixel. Put no new people, faces or products in the bands, and no text, letters, logos or buttons anywhere.\",\n from_ad:\n \"Image 1 is an ad's picture with plain grey areas: where its words, logo and button were, and any grey band at its edges. Paint only the grey areas, so the picture continues naturally: the scene behind where the words were, and the scene past its edges, with the same light, colours and perspective. Keep everything that is not grey exactly as it is, pixel for pixel. Put no text, letters, logos, buttons or new people anywhere.\",\n};\n\n/** The grey the model is asked to paint over, a level nothing in an ad is. */\nconst GREY = 128;\n/** The registration residual (grey levels, RMS) past which the painting is not the shown picture kept in place. */\nconst MISALIGNED = 40;\n\nconst PlateParams = z\n .object({\n mode: z.enum([\"widen\", \"from_ad\"]),\n /** The plate's shape: the one the sizes are cut from. */\n aspect_ratio: z.string().regex(/^\\d+(?:\\.\\d+)?:\\d+(?:\\.\\d+)?$/),\n paint: z\n .object({ model: z.string().min(1), quality: z.string().optional(), prompt: z.string().optional() })\n .strict(),\n /** `from_ad`: the ad's designed lines, painted out. */\n copy: Copy.optional(),\n /** `from_ad`: lines that are part of the scene (a screen, a label), which stay. */\n in_scene: z.array(z.string().min(1)).optional(),\n })\n .strict();\ntype PlateParams = z.infer<typeof PlateParams>;\n\nexport const staticPlateNode = defineNode({\n id: \"static_plate\",\n version: \"1.0.0\",\n category: \"image\",\n location: \"local\",\n billing: \"reported\",\n summary:\n \"A static ad's picture (a plate the sizes are cut from) made from a picture that exists, kept pixel for pixel, the image model painting only what is missing. `widen`: the chosen picture extended sideways to a wide shape (16:9, 21:9), its people and products the tall sizes' own pixels. `from_ad`: an approved ad from before plates, its words, logo and button painted out and its frame extended to the plate's shape. Outputs the plate (`image`), what the model was shown (`shown`), its painting (`painted`), the subjects on the plate (`subjects`) and what it did (`facts`).\",\n when_to_use:\n \"Next to a static ad's chosen picture when its set has wide sizes beside tall ones (`plate_wide`), and once for an approved ad made before plates when one picture is asked for it (refused when more than a quarter of its frame would be painted). One picture at the painter's price, kept apart from the free merge; nothing is painted (and nothing billed) when a plain cut already gives the shape.\",\n inputs: z.object({ image: ImageRef, subjects: z.array(SubjectBoxSchema).optional() }).strict(),\n params: PlateParams,\n outputs: z\n .object({\n image: ImageRef,\n shown: ImageRef.optional(),\n painted: ImageRef.optional(),\n subjects: z.array(SubjectBoxSchema).optional(),\n facts: PlateFacts,\n usage: z.array(Usage).optional(),\n })\n .strict(),\n outputKinds: { image: \"image\", shown: \"image\", painted: \"image\" },\n cost: ({ params }) =>\n imageGenerateNode.cost?.({ params: paintParams(params) as never }) ?? { credits: 0, seconds_estimate: 60 },\n async execute({ inputs, params, ctx }) {\n return await makePlate(inputs, params, ctx);\n },\n});\n\ntype Step = PlateFacts[\"steps\"][number];\n\nfunction paintParams(params: PlateParams): Record<string, unknown> {\n const prompt = [PLATE_PAINT_PROMPT[params.mode], params.paint.prompt].filter(Boolean).join(\"\\n\\n\");\n return {\n model: params.paint.model,\n prompt,\n aspect_ratio: nearestSupportedAspectRatio(\"image_generate\", params.paint.model, params.aspect_ratio),\n ...(params.paint.quality ? { quality: params.paint.quality } : {}),\n };\n}\n\n/** What the model is shown: the kept picture on a grey plate, each cleared box grey too. */\nfunction shownPlate(kept: Raw, size: Size, at: PixelRect, weights: Float32Array): Raw {\n const data = Buffer.alloc(size.width * size.height * 3, GREY);\n for (let i = 0; i < size.width * size.height; i++) {\n if ((weights[i] ?? 0) <= 0) continue;\n const x = (i % size.width) - at.x;\n const y = (i - (i % size.width)) / size.width - at.y;\n const from = (y * kept.width + x) * kept.channels;\n kept.data.copy(data, i * 3, from, from + 3);\n }\n return { data, width: size.width, height: size.height, channels: 3 };\n}\n\n/** The plate's areas the model paints, as fractions: the margins around `at`, and the cleared boxes. */\nfunction paintedSpans(size: Size, at: PixelRect, cleared: readonly Span[]): Span[] {\n const f = (x: number, y: number, x1: number, y1: number): Span => ({\n x0: x / size.width,\n y0: y / size.height,\n x1: x1 / size.width,\n y1: y1 / size.height,\n });\n const margins = [\n f(0, 0, at.x, size.height),\n f(at.x + at.width, 0, size.width, size.height),\n f(0, 0, size.width, at.y),\n f(0, at.y + at.height, size.width, size.height),\n ].filter((s) => s.x1 > s.x0 && s.y1 > s.y0);\n return [...margins, ...cleared];\n}\n\n/** The mean difference between the plate and the kept picture where the plate takes the picture whole: 0 by construction. */\nfunction keptIdentity(plate: Raw, kept: Raw, at: PixelRect, weights: Float32Array): number {\n let sum = 0;\n let n = 0;\n for (let i = 0; i < plate.width * plate.height; i++) {\n if ((weights[i] ?? 0) < 1) continue;\n const x = (i % plate.width) - at.x;\n const y = (i - (i % plate.width)) / plate.width - at.y;\n for (let c = 0; c < 3; c++) {\n sum += Math.abs((plate.data[i * 3 + c] ?? 0) - (kept.data[(y * kept.width + x) * kept.channels + c] ?? 0));\n }\n n += 3;\n }\n return n > 0 ? sum / n : 0;\n}\n\n/** The ad's designed words, logo and button, read once (a step), as fractions of the plate. */\nasync function clearedBoxes(\n source: { bytes: Buffer; ref: ImageRef; size: Size },\n kept: PixelRect,\n frame: { size: Size; at: PixelRect },\n params: PlateParams,\n run: StepRun<Step[\"name\"]>,\n): Promise<Span[]> {\n const reading = await timedStep<Step[\"name\"], TextBoxReading>(\n run,\n \"boxes\",\n { image: source.ref.sha256 },\n () => readTextBoxes(source.bytes, { onSpend: (u) => run.usage.push(u) }),\n { keep: isRead },\n );\n // A plate that kept the ad's words would carry them into every size twice: never guessed.\n if (reading.status !== \"read\") throw new Error(\"static_plate: could not read where the ad's words sit; run it again\");\n const { designed } = splitWordBoxes(reading.boxes, params.copy ?? [], params.in_scene ?? []);\n return designed.map((b) => spanOnPlate(b, source.size, kept, frame.size, frame.at));\n}\n\n/** The one paid call: the painting of the grey areas. A step, so a re-run replays it. */\nasync function paint(shown: ImageRef, params: PlateParams, run: StepRun<Step[\"name\"]>): Promise<ImageRef> {\n const call = paintParams(params);\n return await timedStep(run, \"paint\", { params: call, shown: shown.sha256 }, async (suffix, stepCtx) => {\n const out = await callBackendExec({\n nodeType: imageGenerateNode.id,\n nodeVersion: imageGenerateNode.version,\n params: imageGenerateNode.params.parse(call),\n inputs: { reference: [shown] },\n outputKinds: { images: \"image\" },\n ctx: stepCtx,\n idempotencySuffix: suffix,\n });\n const first = Array.isArray(out.images) ? (out.images[0] as ImageRef | undefined) : undefined;\n if (!first) throw new Error(\"static_plate: the painting call returned no picture\");\n return first;\n });\n}\n\n/** The share of `box` (fractions of the plate) the model painted: its pixels whose keep weight is under 1. Pure. */\nexport function paintedShareOf(box: Span, size: Size, weights: Float32Array): number {\n const x0 = Math.max(0, Math.floor(box.x0 * size.width));\n const x1 = Math.min(size.width, Math.ceil(box.x1 * size.width));\n const y0 = Math.max(0, Math.floor(box.y0 * size.height));\n const y1 = Math.min(size.height, Math.ceil(box.y1 * size.height));\n let painted = 0;\n let all = 0;\n for (let y = y0; y < y1; y++) {\n for (let x = x0; x < x1; x++) {\n all++;\n if ((weights[y * size.width + x] ?? 1) < 1) painted++;\n }\n }\n return all > 0 ? painted / all : 0;\n}\n\n/**\n * What the painting added: the plate read twice (a step, so a re-run replays it) and every subject\n * standing where only painting was (`paintedSubjects`). None when the reader could not say.\n */\nasync function paintedCheck(\n plate: { ref: ImageRef; bytes: Buffer },\n size: Size,\n weights: Float32Array,\n run: StepRun<Step[\"name\"]>,\n): Promise<string[]> {\n const reads = await timedStep<Step[\"name\"], SubjectReads | null>(\n run,\n \"check\",\n { image: plate.ref.sha256 },\n () => readTwice(plate.bytes, (u) => run.usage.push(u)),\n { keep: (read) => read !== null },\n );\n return reads ? paintedSubjects(reads, (box) => paintedShareOf(box, size, weights)) : [];\n}\n\nasync function makePlate(inputs: { image: ImageRef; subjects?: SubjectBox[] }, params: PlateParams, ctx: ExecCtx) {\n const { bytes, size: source } = await imageOf(inputs.image, \"static_plate\");\n // The whole approved ad is kept: refused before anything is read or painted when its frame would be mostly invented.\n const extension = frameExtension(source, params.aspect_ratio);\n if (params.mode === \"from_ad\" && extension > FROM_AD_MAX_EXTENSION)\n throw new Error(\n `static_plate: moving this approved ad onto one picture would paint ${Math.round(extension * 100)}% of its frame (more than ${FROM_AD_MAX_EXTENSION * 100}%), inventing what the ad never showed. It stays on its own shape: scaffold it again with --master-shape relayout, or make it again for new pictures.`,\n );\n const steps: Step[] = [];\n const usage: ReviewUsage[] = [];\n const spend = () => (usage.length > 0 ? { usage } : {});\n const run = { ctx, steps, usage };\n const subjects = inputs.subjects ?? (await subjectsStep(run, inputs.image, bytes));\n const kept = keptRegion(source, params.aspect_ratio, subjects, params.mode);\n const frame = plateFrame(kept, params.aspect_ratio);\n const keptRaw = await rawOf(\n await sharp(bytes).extract({ left: kept.x, top: kept.y, width: kept.width, height: kept.height }).toBuffer(),\n kept,\n );\n const cleared =\n params.mode === \"from_ad\"\n ? await clearedBoxes({ bytes, ref: inputs.image, size: source }, kept, frame, params, run)\n : [];\n const onPlate = (subjects ?? [])\n .map((b) => spanOnPlate(b, source, kept, frame.size, frame.at))\n .filter((b) => b.x1 > 0 && b.y1 > 0 && b.x0 < 1 && b.y0 < 1);\n const base = { mode: params.mode, source, plate: frame.size, kept, at: frame.at, cleared: cleared.length };\n const weights = keepWeights(frame.size, frame.at, cleared);\n const untouched = frame.size.width === kept.width && frame.size.height === kept.height && cleared.length === 0;\n if (untouched) {\n const image = await ctx.assets.ingestBytes({ bytes: await pngOf(keptRaw), kind: \"image\", mime: \"image/png\" });\n const facts: PlateFacts = { ...base, painted: 0, identity: 0, steps, ...(subjects ? {} : { reason: \"not_read\" }) };\n return { image: image as ImageRef, subjects: onPlate, facts, ...spend() };\n }\n const shownRaw = shownPlate(keptRaw, frame.size, frame.at, weights);\n const shown = (await ctx.assets.ingestBytes({\n bytes: await pngOf(shownRaw),\n kind: \"image\",\n mime: \"image/png\",\n })) as ImageRef;\n const painted = await paint(shown, params, run);\n const painting = await rawOf((await imageOf(painted, \"static_plate\")).bytes, frame.size);\n const fit = registerToSource(painting, shownRaw, paintedSpans(frame.size, frame.at, cleared));\n const misaligned = fit.residual > MISALIGNED;\n const plate = mergePlate(keptRaw, frame.at, misaligned ? painting : warpToCut(painting, fit), weights);\n const identity = keptIdentity(plate, keptRaw, frame.at, weights);\n if (identity !== 0) throw new Error(`static_plate: the kept picture changed (${identity})`);\n const plateBytes = await pngOf(plate);\n const image = (await ctx.assets.ingestBytes({ bytes: plateBytes, kind: \"image\", mime: \"image/png\" })) as ImageRef;\n const added = await paintedCheck({ ref: image, bytes: plateBytes }, frame.size, weights, run);\n const facts = paintedFacts(base, { weights, identity, steps, added, misaligned, read: subjects !== null });\n ctx.log(\n `plate ${params.mode}: ${frame.size.width}x${frame.size.height}, ${Math.round(facts.painted * 100)}% painted${facts.reason ? `, ${facts.reason}` : \"\"}${added.length > 0 ? ` (${added.join(\", \")})` : \"\"}`,\n );\n return { image, shown, painted, subjects: onPlate, facts, ...spend() };\n}\n\n/** The facts of a plate the model painted: how much, and what fell short (what it added first). */\nfunction paintedFacts(\n base: Pick<PlateFacts, \"mode\" | \"source\" | \"plate\" | \"kept\" | \"at\" | \"cleared\">,\n run: { weights: Float32Array; identity: number; steps: Step[]; added: string[]; misaligned: boolean; read: boolean },\n): PlateFacts {\n const reason =\n run.added.length > 0 ? \"subject_added\" : run.misaligned ? \"misaligned\" : run.read ? undefined : \"not_read\";\n return {\n ...base,\n painted: Math.round((run.weights.reduce((n, w) => n + (w < 1 ? 1 : 0), 0) / run.weights.length) * 1000) / 1000,\n identity: run.identity,\n steps: run.steps,\n ...(reason ? { reason } : {}),\n ...(run.added.length > 0 ? { added: run.added } : {}),\n };\n}\n","/**\n * A plate made from a picture that exists: the picture kept pixel for pixel, and the image model\n * painting only what is missing. Two uses:\n *\n * - `widen`: a set with wide sizes next to tall ones extends the chosen picture sideways, so the\n * people and the product of the wide sizes are the tall ones' own pixels (owner, Oct 2026);\n * - `from_ad`: an approved ad made before plates, when one picture is asked for it, gets its picture back once: its words, logo and\n * button painted out and its frame extended to the plate's shape, everything else its own pixels.\n *\n * Pure: sizes, boxes and raw buffers in, rectangles, weights and buffers out.\n */\nimport type { SubjectBox } from \"./subject-boxes.ts\";\nimport { type PixelRect, type Size, subjectCrop } from \"./subject-crop.ts\";\nimport type { Raw, Span } from \"./words-layer.ts\";\n\nexport type PlateMode = \"widen\" | \"from_ad\";\n\nfunction ratioOf(ratio: string): number {\n const [w, h] = ratio.split(\":\").map(Number);\n if (!w || !h || !Number.isFinite(w) || !Number.isFinite(h)) throw new Error(`not a W:H ratio: \"${ratio}\"`);\n return w / h;\n}\n\n/** Room kept above and below the subjects of a widened band, as a share of the picture's height. */\nconst BAND_PAD = 0.04;\n\n/**\n * The part of `source` the plate keeps as it is. `from_ad`: all of it. `widen`: a picture already\n * as wide as `ratio` is cut to it (nothing painted); a taller one keeps a full-width band holding\n * every subject whole (padded by `BAND_PAD`), no shorter than a plain cut to `ratio` (then nothing\n * is painted either); with no subject read, its middle square.\n */\nexport function keptRegion(\n source: Size,\n ratio: string,\n subjects: readonly SubjectBox[] | null,\n mode: PlateMode,\n): PixelRect {\n if (mode === \"from_ad\") return { x: 0, y: 0, width: source.width, height: source.height };\n const r = ratioOf(ratio);\n if (source.width / source.height >= r) return subjectCrop(source, ratio, subjects).rect;\n if (!subjects || subjects.length === 0) {\n const side = Math.min(source.width, source.height);\n return { x: 0, y: Math.round((source.height - side) / 2), width: source.width, height: side };\n }\n const top = Math.max(0, (Math.min(...subjects.map((s) => s.y0)) - BAND_PAD) * source.height);\n const bottom = Math.min(source.height, (Math.max(...subjects.map((s) => s.y1)) + BAND_PAD) * source.height);\n const height = Math.min(source.height, Math.round(Math.max(bottom - top, Math.min(source.height, source.width / r))));\n const y = Math.round(Math.min(source.height - height, Math.max(0, (top + bottom) / 2 - height / 2)));\n return { x: 0, y, width: source.width, height };\n}\n\n/** The plate around a kept region of `kept` pixels: its size at `ratio`, and where the region sits in it (centred). */\nexport function plateFrame(kept: Size, ratio: string): { size: Size; at: PixelRect } {\n const r = ratioOf(ratio);\n const { width, height } = kept;\n if (Math.abs(width / height - r) < 1e-3) return { size: { width, height }, at: { x: 0, y: 0, width, height } };\n if (width / height < r) {\n const wide = Math.round(height * r);\n return { size: { width: wide, height }, at: { x: Math.round((wide - width) / 2), y: 0, width, height } };\n }\n const tall = Math.round(width / r);\n return { size: { width, height: tall }, at: { x: 0, y: Math.round((tall - height) / 2), width, height } };\n}\n\n/**\n * The most of its plate an approved ad's frame is extended by (`from_ad`): past it the painting\n * invents what the ad never showed (review, Oct 2026: a 4:5 extended to 9:16 had 30% painted).\n */\nexport const FROM_AD_MAX_EXTENSION = 0.25;\n\n/** The share of the plate painted around a kept region of `kept` pixels to reach `ratio`: 0 when it is already that shape. */\nexport function frameExtension(kept: Size, ratio: string): number {\n const { size } = plateFrame(kept, ratio);\n return 1 - (kept.width * kept.height) / (size.width * size.height);\n}\n\n/** How far into the kept picture its edge blends into the painting, as a share of the plate's long side. */\nexport const SEAM = 0.012;\n/** How far past a cleared word box the painting reaches, as a share of the box's height. */\nconst CLEAR_PAD = 0.3;\n\n/**\n * How much of the kept picture each plate pixel takes (row-major): 1 inside `at`, easing to 0 over\n * `SEAM` toward an edge of it inside the plate (one on the plate's own edge has nothing to meet), 0\n * in the margins and inside each `cleared` box (plate fractions, padded by `CLEAR_PAD`), eased the\n * same way around it.\n */\nexport function keepWeights(size: Size, at: PixelRect, cleared: readonly Span[] = []): Float32Array {\n const seam = Math.max(1, Math.round(SEAM * Math.max(size.width, size.height)));\n const ramp = (d: number, onFrame: boolean) => (onFrame ? 1 : Math.min(1, (d + 1) / seam));\n const holes = cleared.map((b) => {\n const pad = CLEAR_PAD * (b.y1 - b.y0) * size.height;\n return {\n x0: b.x0 * size.width - pad,\n y0: b.y0 * size.height - pad,\n x1: b.x1 * size.width + pad,\n y1: b.y1 * size.height + pad,\n };\n });\n const out = new Float32Array(size.width * size.height);\n for (let i = 0; i < out.length; i++) {\n const x = i % size.width;\n const y = (i - x) / size.width;\n if (x < at.x || y < at.y || x >= at.x + at.width || y >= at.y + at.height) continue;\n const edge = Math.min(\n ramp(x - at.x, at.x === 0),\n ramp(at.x + at.width - 1 - x, at.x + at.width === size.width),\n ramp(y - at.y, at.y === 0),\n ramp(at.y + at.height - 1 - y, at.y + at.height === size.height),\n );\n const away = holes.reduce((w, h) => {\n const d = Math.max(h.x0 - x, x - h.x1, h.y0 - y, y - h.y1);\n return Math.min(w, d < 0 ? 0 : Math.min(1, d / seam));\n }, 1);\n out[i] = Math.min(edge, away);\n }\n return out;\n}\n\n/** The plate: the kept picture (`kept`, placed at `at`) over the painting, by `weights`. A weight of 1 is the picture's pixel, exactly. */\nexport function mergePlate(kept: Raw, at: PixelRect, painting: Raw, weights: Float32Array): Raw {\n const { width, height } = painting;\n const out = Buffer.alloc(width * height * 3);\n for (let k = 0; k < width * height * 3; k++) {\n const i = (k - (k % 3)) / 3;\n const c = k % 3;\n const paint = painting.data[i * painting.channels + c] ?? 0;\n const w = weights[i] ?? 0;\n if (w <= 0) {\n out[k] = paint;\n continue;\n }\n const x = (i % width) - at.x;\n const y = (i - (i % width)) / width - at.y;\n const own = kept.data[(y * kept.width + x) * kept.channels + c] ?? 0;\n out[k] = w >= 1 ? own : Math.round(own * w + paint * (1 - w));\n }\n return { data: out, width, height, channels: 3 };\n}\n\n/** A box of the source (a subject, a word), as fractions of the plate the kept region `kept` of it sits in at `at`. */\nexport function spanOnPlate<T extends Span>(b: T, source: Size, kept: PixelRect, plate: Size, at: PixelRect): T {\n const x = (v: number) => (v * source.width - kept.x + at.x) / plate.width;\n const y = (v: number) => (v * source.height - kept.y + at.y) / plate.height;\n return { ...b, x0: x(b.x0), y0: y(b.y0), x1: x(b.x1), y1: y(b.y1) };\n}\n","/**\n * Whether one size of a static ad shows what its main size shows: the same people, the same\n * product, nothing twice, nobody stretched, never the main picture boxed inside a bigger frame.\n *\n * Box-based where boxes can say it (`boxDifferences`, on `subject-boxes.ts` reads): how many\n * people, faces and animals each size shows. The rest is the vision comparison's\n * (`SIZE_MATCH_PROMPT`): the product, who the people are, anything twice, anything stretched,\n * the main picture boxed in a bigger frame.\n *\n * Calibration (Oct 2026, 29 production size pairs of 20 relayout creatives, each image read twice):\n * - people, faces and animals counted as below flagged none of the 29 pairs; product counts flapped\n * on 4 (a laptop, a box, a court listed on one read and not the other), so products are not counted;\n * - a face's shape is not measured on boxes: one picture cut to 4:5 and 9:16 (the same pixels), read\n * 4 times each, gave the man's face 0.69-0.73 wide for its height on the 4:5 and 0.78-0.84 on the\n * 9:16, as wide a gap as a 25% squeeze makes.\n */\nimport { SIZE_MATCH_MODEL } from \"@baker/canvas-contract\";\nimport sharp from \"sharp\";\nimport { z } from \"zod\";\nimport { askAboutImages, type RenderFinding, type ReviewUsage } from \"./render-review.ts\";\nimport { bytesOf } from \"./static-review.ts\";\nimport { readSubjectBoxes, type SubjectBox, type SubjectKind } from \"./subject-boxes.ts\";\nimport type { Size } from \"./subject-crop.ts\";\n\n/** One image's subjects as the reader read them, one list per read (two reads tell a subject from a misread). */\nexport type SubjectReads = { size: Size; reads: SubjectBox[][] };\n\nexport type SizeDifference = {\n kind: \"added\" | \"missing\" | \"stretched\" | \"other_people\" | \"other_product\" | \"no_product\" | \"duplicated\" | \"framed\";\n /** What differs, in the words the agent acts on, without the size. */\n what: string;\n};\n\n/** A subject counted as shown: its box holds at least this share of the frame (a crowd's faces do not). */\nconst SHOWN_AREA = 0.01;\n/** A subject counted as possibly shown, on the side a difference is measured against: a third of `SHOWN_AREA`. */\nconst SEEN_AREA = SHOWN_AREA / 3;\n/** Two reads' boxes are one subject when they overlap this much (intersection over union). */\nconst SAME_BOX = 0.3;\n\nconst COUNTED: ReadonlyArray<{ kind: SubjectKind; name: string }> = [\n { kind: \"person\", name: \"people\" },\n { kind: \"face\", name: \"faces\" },\n { kind: \"animal\", name: \"animals\" },\n];\n\nconst area = (b: SubjectBox) => Math.max(0, b.x1 - b.x0) * Math.max(0, b.y1 - b.y0);\n\nfunction overlap(a: SubjectBox, b: SubjectBox): number {\n const ix = Math.max(0, Math.min(a.x1, b.x1) - Math.max(a.x0, b.x0));\n const iy = Math.max(0, Math.min(a.y1, b.y1) - Math.max(a.y0, b.y0));\n const union = area(a) + area(b) - ix * iy;\n return union > 0 ? (ix * iy) / union : 0;\n}\n\n/** Subjects of `kind` every read found, each a shown one: what the image certainly shows. */\nfunction surely(image: SubjectReads, kind: SubjectKind): SubjectBox[] {\n const [first = [], ...rest] = image.reads.map((r) => r.filter((b) => b.kind === kind));\n return first.filter((b) => area(b) >= SHOWN_AREA && rest.every((r) => r.some((o) => overlap(b, o) >= SAME_BOX)));\n}\n\n/** The most subjects of `kind` any read found, small ones included: what the image may show. */\nfunction atMost(image: SubjectReads, kind: SubjectKind): number {\n return Math.max(0, ...image.reads.map((r) => r.filter((b) => b.kind === kind && area(b) >= SEEN_AREA).length));\n}\n\n/**\n * How `size` differs from `master` by its subjects' boxes: more people, faces or animals than the\n * main size shows at most, or fewer than it surely shows. A count is surely-shown on one side\n * against may-be-shown on the other, so neither a misread nor a subject at the edge of counting\n * flags. Pure.\n */\nexport function boxDifferences(master: SubjectReads, size: SubjectReads): SizeDifference[] {\n return COUNTED.flatMap(({ kind, name }): SizeDifference[] => {\n const shown = surely(size, kind).length;\n const shownBefore = atMost(master, kind);\n if (shown > shownBefore) {\n return [{ kind: \"added\", what: `shows ${shown} ${name} where the main size shows ${shownBefore}` }];\n }\n const before = surely(master, kind).length;\n const now = atMost(size, kind);\n if (before > now) return [{ kind: \"missing\", what: `shows ${now} ${name} where the main size shows ${before}` }];\n return [];\n });\n}\n\n/** A subject is in what was painted when this share of its box was painted. */\nconst PAINTED = 0.6;\n\n/**\n * The subjects of a picture painted from another (`static_plate`) that every read finds mostly in\n * what was painted (`paintedShare` of a box, 0-1): a person, face or animal is one the picture it\n * was painted from does not show; a product only when it repeats one the kept part shows (its label\n * shares a word with it), since a painted scene may well hold things the reader calls products. Pure.\n */\nexport function paintedSubjects(plate: SubjectReads, paintedShare: (box: SubjectBox) => number): string[] {\n const words = (label: string) => label.toLowerCase().match(/\\p{L}{3,}/gu) ?? [];\n const keptProducts = new Set(\n surely(plate, \"product\")\n .filter((b) => paintedShare(b) < PAINTED)\n .flatMap((b) => words(b.label)),\n );\n return ([\"person\", \"face\", \"animal\", \"product\"] as const).flatMap((kind) =>\n surely(plate, kind)\n .filter((b) => paintedShare(b) >= PAINTED)\n .filter((b) => kind !== \"product\" || words(b.label).some((w) => keptProducts.has(w)))\n .map((b) => b.label),\n );\n}\n\n/**\n * The comparison of one size with the main size, for what boxes cannot say: whether the product\n * and the people are the same ones, shown once, unstretched, and not the main picture boxed in a\n * bigger frame. Calibration (Oct 2026): on the 29 production pairs, asked twice each, it flagged\n * none; it named a size squeezed into another shape, the main picture shrunk onto a blurred 9:16,\n * a man shown twice, and another product (4 of 4 twice, a 25% squeeze once of two).\n */\nexport const SIZE_MATCH_PROMPT = [\n \"Image 1 is the main size of one static ad. Image 2 is the same ad made in another size. Image 2 may show more or less of the scene and lay the words out differently: that is expected and never a finding. Compare only the people, animals and products the two pictures show:\",\n \"- people: Image 2 shows a different number of the ad's people than Image 1, or a different person where Image 1 has one (another face, age, gender or clothing).\",\n \"- product: the product the ad is about (the thing sold or shown in use) is a different object in Image 2 (another model, shape, colour or label), or is missing from it.\",\n \"- duplicated: Image 2 shows the same person, animal or product twice where Image 1 shows it once.\",\n \"- stretched: a person, face or product in Image 2 is visibly stretched or squashed compared with Image 1 (wider or taller than it is).\",\n \"- framed: Image 2 holds Image 1's picture as a smaller rectangle inside a bigger frame, with a visible edge, border or seam around it.\",\n \"Someone in the far background, a crowd, and a prop a bigger frame shows more of are never findings. Say only what you see clearly at phone size; when unsure, it is the same.\",\n 'Reply with only this JSON: {\"people\":\"same|different\",\"product\":\"same|different|missing|none\",\"duplicated\":\"<what is shown twice>|null\",\"stretched\":\"<who or what>|null\",\"framed\":true|false,\"what\":\"<one short sentence naming what differs, or empty>\"}',\n].join(\"\\n\");\n\nconst SizeMatchAnswer = z.object({\n people: z.enum([\"same\", \"different\"]),\n product: z.enum([\"same\", \"different\", \"missing\", \"none\"]),\n duplicated: z.string().nullable().optional(),\n stretched: z.string().nullable().optional(),\n framed: z.boolean(),\n});\n\nconst named = (text: string | null | undefined): string | null => {\n const t = text?.trim();\n return t && t.toLowerCase() !== \"null\" ? t : null;\n};\n\n/** The comparison's answer as differences; null when it is not the shape asked for (\"not compared\", never \"the same\"). Pure. */\nexport function sizeMatchFromAnswer(answer: unknown): SizeDifference[] | null {\n const parsed = SizeMatchAnswer.safeParse(answer);\n if (!parsed.success) return null;\n const a = parsed.data;\n const twice = named(a.duplicated);\n const stretched = named(a.stretched);\n return [\n ...(a.people === \"different\"\n ? [{ kind: \"other_people\" as const, what: \"shows other people than the main size\" }]\n : []),\n ...(a.product === \"different\"\n ? [{ kind: \"other_product\" as const, what: \"shows another product than the main size\" }]\n : a.product === \"missing\"\n ? [{ kind: \"no_product\" as const, what: \"no longer shows the product the main size shows\" }]\n : []),\n ...(twice ? [{ kind: \"duplicated\" as const, what: `shows ${twice} twice` }] : []),\n ...(stretched ? [{ kind: \"stretched\" as const, what: `shows ${stretched} stretched or squashed` }] : []),\n ...(a.framed\n ? [{ kind: \"framed\" as const, what: \"shows the main size's picture boxed inside a bigger frame\" }]\n : []),\n ];\n}\n\n/** One delivered size of the ad, on disk or at a URL. */\nexport type SizeImage = { path: string; format: string };\n\n/** What comparing one size with the main size found; `compared` false when neither the boxes nor the comparison could be read. */\nexport type SizeComparison = { format: string; compared: boolean; differences: SizeDifference[] };\n\n/** Reads of each picture: two tell a subject from a misread (`surely`). */\nconst READS = 2;\n/** Longest edge the comparison is sent: the size it judges at, as a phone shows the ad. */\nconst MATCH_EDGE = 1024;\n\n/** A picture's subjects read twice (`READS`); null when a read did not answer. */\nexport async function readTwice(bytes: Buffer, onSpend?: (usage: ReviewUsage) => void): Promise<SubjectReads | null> {\n const meta = await sharp(bytes).metadata();\n const reads = await Promise.all(Array.from({ length: READS }, () => readSubjectBoxes(bytes, { onSpend })));\n const boxes = reads.flatMap((r) => (r.status === \"read\" ? [r.boxes] : []));\n return boxes.length === READS ? { size: { width: meta.width ?? 0, height: meta.height ?? 0 }, reads: boxes } : null;\n}\n\nconst matchJpeg = async (bytes: Buffer) =>\n (\n await sharp(bytes)\n .resize(MATCH_EDGE, MATCH_EDGE, { fit: \"inside\", withoutEnlargement: true })\n .jpeg({ quality: 88 })\n .toBuffer()\n ).toString(\"base64\");\n\n/** One differences list per kind, each said once: the boxes and the comparison may both name a person added. */\nconst unique = (diffs: readonly SizeDifference[]) =>\n diffs.filter((d, i) => diffs.findIndex((o) => o.what === d.what) === i);\n\n/**\n * Each of `sizes` compared with the main size `master`: its people, faces and animals read twice\n * and counted against the main size's (`boxDifferences`), and the pair shown to the comparison model\n * once (`SIZE_MATCH_PROMPT`). Everything is asked at once.\n */\nexport async function compareSizes(\n master: SizeImage,\n sizes: readonly SizeImage[],\n opts: { onSpend?: (usage: ReviewUsage) => void } = {},\n): Promise<SizeComparison[]> {\n const masterBytes = await bytesOf(master.path);\n const [masterReads, masterJpeg] = await Promise.all([readTwice(masterBytes, opts.onSpend), matchJpeg(masterBytes)]);\n return await Promise.all(\n sizes.map(async (size): Promise<SizeComparison> => {\n const bytes = await bytesOf(size.path);\n const [reads, answer] = await Promise.all([\n readTwice(bytes, opts.onSpend),\n matchJpeg(bytes).then((jpeg) =>\n askAboutImages(SIZE_MATCH_MODEL, [masterJpeg, jpeg], SIZE_MATCH_PROMPT, opts.onSpend, 60_000, {\n effort: \"low\",\n }),\n ),\n ]);\n const boxed = masterReads && reads ? boxDifferences(masterReads, reads) : null;\n const seen = sizeMatchFromAnswer(answer);\n return {\n format: size.format,\n compared: boxed !== null || seen !== null,\n differences: unique([...(boxed ?? []), ...(seen ?? [])]),\n };\n }),\n );\n}\n\n/**\n * One size's differences as the review's blocking finding on it (\"9:16: …\"), typed as the sizes\n * item: autofix makes that size again from the main one, never the main picture. Pure.\n */\nexport function sizeDifferenceFinding(format: string, differences: readonly SizeDifference[]): RenderFinding {\n const missing = differences.some((d) => d.kind === \"missing\" || d.kind === \"no_product\");\n return {\n severity: \"blocking\",\n what: `${format}: ${differences.map((d) => d.what).join(\"; \")}. It must show the main size's people and product, once each, at their own proportions.`,\n kind: { item: \"sizes\", element: \"picture\", defect: missing ? \"missing\" : \"other\", edges: [] },\n };\n}\n","import { readFile } from \"node:fs/promises\";\nimport { z } from \"zod\";\nimport type { ExecCtx } from \"../../engine/context.ts\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport { MASTER_SHAPES, type Size } from \"../../scaffold/static-sizes.ts\";\nimport { ImageRef, JsonRef } from \"../../schema/refs.ts\";\nimport type { ReviewUsage } from \"./lib/render-review.ts\";\nimport { bytesOf } from \"./lib/static-review.ts\";\nimport { cutToFrame, type Frame, judgeTie, type PrefilterResult, prefilterVariants } from \"./lib/variant-prefilter.ts\";\n\nconst Dropped = z.object({ index: z.number().int().min(0), reasons: z.array(z.string()) }).strict();\nconst Usage = z\n .object({ model: z.string(), inputTokens: z.number(), outputTokens: z.number(), costUsd: z.number() })\n .strict();\n\nasync function readSpec(ref: { path?: string } | undefined): Promise<unknown> {\n if (!ref?.path) return null;\n try {\n return JSON.parse(await readFile(ref.path, \"utf8\"));\n } catch {\n return null;\n }\n}\n\nexport const staticPrefilterNode = defineNode({\n id: \"static_prefilter\",\n version: \"1.1.0\",\n category: \"image\",\n location: \"local\",\n // Reads each variant's pixels itself, from its file or its durable URL, so the variants\n // are not downloaded for it.\n passthroughRefs: true,\n summary:\n \"Rank a static ad's variants before the judge by the deterministic checks (blocking defects, copy read back, the brand's logo found, the button's words, words inside the safe area) and pass on only the best-ranked, so the judge only breaks an exact tie. Outputs them in an order seeded by the pictures (never the render order), `order` (which variant each one is) and `dropped` with each set-aside variant's reasons.\",\n when_to_use:\n \"Scaffolded by `baker canvas scaffold-static-ad` between the variants and the judge; wire the variants' whole `images` list and the ad spec (`$ref:prompt.asset`). Never leaves the judge empty: when every variant fails, the one with the fewest defects passes as `flagged`, and the review names what is wrong. A variant the reader could not read passes unchecked.\",\n inputs: z\n .object({\n images: z.array(ImageRef).min(1),\n spec: JsonRef.optional(),\n // Master shape `plate`: each variant's picture (no designed words), in the order of `images`,\n // and what its lead's size node did (`facts`): a variant whose picture cannot give every size is set aside.\n plates: z.array(ImageRef).optional(),\n facts: z.array(z.unknown()).optional(),\n })\n .strict(),\n // `master_shape` and `placements` are the ones the canvas's sizes were planned with, so the\n // band the variants are checked against is the band every size is cut to keep.\n params: z\n .object({\n formats: z.array(z.string().min(1)).min(1),\n master_shape: z.enum(MASTER_SHAPES).optional(),\n placements: z.array(z.string().min(1)).optional(),\n // The size its platform designs first, when one was named: the master the variants are checked at.\n lead: z.string().min(1).optional(),\n // The platforms the sizes were planned for: read back to re-plan them when the definition names others.\n platforms: z.array(z.string().min(1)).optional(),\n // The judge, asked only on a real tie: its model, and the criteria compiled from prompt.json.\n judge_model: z.string().min(1).optional(),\n judge_prompt: z.string().min(1).optional(),\n // What the checks read of prompt.json, projected on every run (`staticChecksOf`); without it, the `spec` input.\n checks: z\n .object({\n kind: z.literal(\"static_checks\"),\n lines: z.array(\n z.object({ text: z.string(), lettering: z.string(), role: z.string().optional() }).passthrough(),\n ),\n buttons: z.array(z.string()),\n brand: z.string().optional(),\n logo: z.boolean(),\n logo_slot: z.object({ x0: z.number(), y0: z.number(), x1: z.number(), y1: z.number() }).strict().optional(),\n })\n .optional(),\n })\n .strict(),\n outputs: z\n .object({\n images: z.array(ImageRef).min(1),\n // Which variant (its place among the inputs) each of `images` is, so the judge's \"Image k\" maps back.\n order: z.array(z.number().int().min(0)).optional(),\n // The picture every size is made from: the checks' first, or on a tie the judge's. Cut to the\n // master's frame where every word stays whole when its centre would cut one, else as rendered.\n image: ImageRef.optional(),\n // Which variant it is (its place among the inputs).\n chosen: z.number().int().min(0).optional(),\n // Master shape `plate`: the chosen variant's picture, every other size is cut from.\n plate: ImageRef.optional(),\n // The judge's ranking lines, when a tie was put to it.\n reasoning: z.string().optional(),\n dropped: z.array(Dropped),\n flagged: Dropped.optional(),\n // What the reader's calls cost, as the gateway reported it (the run record carries it home).\n usage: z.array(Usage).optional(),\n })\n .strict(),\n outputKinds: { images: \"image\", image: \"image\", plate: \"image\" },\n cost: () => ({ credits: 0, seconds_estimate: 1 }),\n async execute({ inputs, params, ctx }) {\n const variants = inputs.images.map((image, index) => ({\n index,\n sha256: image.sha256,\n ...(image.path ? { path: image.path } : {}),\n ...(image.url ? { url: image.url } : {}),\n }));\n const usage: ReviewUsage[] = [];\n const checked = await prefilterVariants(variants, params.checks ?? (await readSpec(inputs.spec)), params.formats, {\n ...(params.master_shape ? { masterShape: params.master_shape } : {}),\n ...(params.placements ? { placements: params.placements } : {}),\n ...(params.lead ? { lead: params.lead } : {}),\n onSpend: (u) => usage.push(u),\n });\n const plateShape = params.master_shape === \"plate\";\n const result = setAsideShort(checked, shortVariants(params.master_shape, inputs.facts), inputs.images.length);\n const order = result.kept.filter((i) => inputs.images[i] !== undefined);\n const kept = order.flatMap((i) => (inputs.images[i] ? [inputs.images[i]] : []));\n const shown = kept.length > 0 ? order : inputs.images.map((_, i) => i);\n const tie =\n shown.length > 1 && params.judge_model && params.judge_prompt\n ? await judgeTie(\n shown.map((index) => ({ index, ...variants[index] })),\n { model: params.judge_model, prompt: params.judge_prompt, onSpend: (u) => usage.push(u) },\n )\n : null;\n const chosen = tie?.chosen ?? shown[0] ?? 0;\n // A variant's lead is already its delivered size: it is passed on as it is, never re-framed.\n const frame = plateShape ? undefined : result.frames?.[chosen];\n const image = await framed(inputs.images[chosen], frame, result.masterSize, ctx);\n const plate = inputs.plates?.[chosen];\n return {\n images: kept.length > 0 ? kept : inputs.images,\n order: shown,\n ...(image ? { image } : {}),\n chosen,\n ...(plate ? { plate } : {}),\n ...(tie ? { reasoning: tie.reasoning } : {}),\n dropped: result.dropped,\n ...(result.flagged ? { flagged: result.flagged } : {}),\n ...(usage.length > 0 ? { usage } : {}),\n };\n },\n});\n\n/**\n * What an option set aside on the plate shape is told, in product words, by its lead's `facts.reason`:\n * a picture that cannot give every size, or words that came out short of what every size must show.\n */\nconst SHORT_LEAD: Readonly<Record<string, string>> = {\n subject_cut: \"Its picture cannot give every size: one size would cut a person's head, a face or the product.\",\n words_misaligned:\n \"Its words came with a patch of redrawn picture around them (the words call moved the picture): it would show as a box.\",\n words_not_read: \"Where its words sit could not be read, so the picture around them may have been redrawn with them.\",\n words_over_face: \"Its words were set over a face.\",\n subject_covered: \"Its words hide most of the product.\",\n band_too_far: \"Its words reach too far past the part of the frame the app leaves clear.\",\n};\n\n/**\n * The checks' outcome with every option its lead found short (`short`, by index: why) set aside;\n * when that is all of them, the checks' first goes on, flagged with its reason, so the round still\n * has something to show. Pure.\n */\nexport function setAsideShort(\n result: PrefilterResult,\n short: ReadonlyMap<number, string>,\n count: number,\n): PrefilterResult {\n if (short.size === 0) return result;\n const exists = (i: number) => i >= 0 && i < count;\n const kept = result.kept.filter((i) => exists(i) && !short.has(i));\n const others = result.dropped.filter((d) => !short.has(d.index));\n const first = kept.length > 0 ? undefined : (result.kept.find(exists) ?? [...short.keys()][0]);\n const setAside = [...short].filter(([i]) => i !== first).map(([index, reason]) => ({ index, reasons: [reason] }));\n if (first === undefined) return { ...result, kept, dropped: [...others, ...setAside] };\n const before = result.flagged?.index === first ? result.flagged.reasons : [];\n return {\n ...result,\n kept: [first],\n dropped: [...others, ...setAside],\n flagged: { index: first, reasons: [short.get(first) ?? \"\", ...before].filter(Boolean) },\n };\n}\n\n/** On the plate shape, the options whose lead came out short (`SHORT_LEAD`), each with why. */\nfunction shortVariants(shape: string | undefined, facts: readonly unknown[] | undefined): Map<number, string> {\n const out = new Map<number, string>();\n if (shape !== \"plate\") return out;\n (facts ?? []).forEach((f, i) => {\n const reason = (f as { reason?: unknown } | null)?.reason;\n const said = typeof reason === \"string\" ? SHORT_LEAD[reason] : undefined;\n if (said) out.set(i, said);\n });\n return out;\n}\n\n/**\n * The chosen picture as the master cuts it: where every word stays whole when its centre would\n * cut one (a 3:4 render's button at the foot of a 4:5), else as it is (the master cuts its centre).\n */\nasync function framed(\n picture: z.infer<typeof ImageRef> | undefined,\n frame: Frame | undefined,\n size: Size | undefined,\n ctx: ExecCtx,\n): Promise<z.infer<typeof ImageRef> | undefined> {\n const source = picture?.path ?? picture?.url;\n if (!picture || !frame || !size || !source) return picture;\n const bytes = await cutToFrame(await bytesOf(source), frame, size);\n return (await ctx.assets.ingestBytes({ bytes, kind: \"image\", mime: \"image/png\" })) as z.infer<typeof ImageRef>;\n}\n","import { z } from \"zod\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport { ImageRef } from \"../../schema/refs.ts\";\nimport type { ReviewUsage } from \"./lib/render-review.ts\";\nimport { boxesToPlace, fitPicture, minFitScale, planSafeFit } from \"./lib/safe-fit.ts\";\nimport { bytesOf } from \"./lib/static-review.ts\";\nimport { readTextBoxes } from \"./lib/text-boxes.ts\";\n\nconst Usage = z\n .object({ model: z.string(), inputTokens: z.number(), outputTokens: z.number(), costUsd: z.number() })\n .strict();\nconst Fit = z.object({ scale: z.number(), x: z.number(), y: z.number() }).strict();\n/** The ad's copy (prompt.json's lines and their roles): the fit moves the ad for these and its logo only. */\nconst Copy = z.array(z.object({ text: z.string().min(1), role: z.string().optional() }).strict());\n\nexport const staticSafeFitNode = defineNode({\n id: \"static_safe_fit\",\n version: \"1.0.0\",\n category: \"image\",\n location: \"local\",\n summary:\n \"Bring a finished static ad's words and logo inside the band its placement leaves clear (the Stories header, the Reels footer) without rendering again: reads where every line and the logo sit, then shrinks the picture a little (to 85%, or 65% on one flat ground) and shifts it, carrying its plain edge into the uncovered margin. Outputs the same pixel size; `fit` is the scale and position used, or null with `reason` when the picture is passed on unchanged.\",\n when_to_use:\n \"Scaffolded by `baker canvas scaffold-static-ad` after every 9:16 size (`safe_<size>`, role `static_safe_fit`). Free, besides one box-reader call (about $0.005, carried on the run record's review spend). A layout too tall or wide for the band at that scale, or whose edge is busy (cards, leaves, a scene that would smear), is passed on unchanged: the review still names what Reels or Stories covers, and the layout itself has to change (shorter copy, fewer lines).\",\n inputs: z.object({ image: ImageRef }).strict(),\n // `placements` are the ones the canvas's sizes were planned with (the ad set's), so the band\n // the fit clears is the one the review holds the size to.\n params: z\n .object({ format: z.string().min(1), placements: z.array(z.string().min(1)).optional(), copy: Copy.optional() })\n .strict(),\n outputs: z\n .object({\n image: ImageRef,\n fit: Fit.nullable(),\n // Why the picture passed unchanged: the reader could not read it, nothing was outside the\n // band, clearing it needed more than the smallest shrink that still looks native, or the\n // edge it would carry outward is not plain ground.\n reason: z.enum([\"not_read\", \"inside_band\", \"too_far\", \"busy_edge\"]).optional(),\n // What the reader's call cost, as the gateway reported it (the run record carries it home).\n usage: z.array(Usage).optional(),\n })\n .strict(),\n outputKinds: { image: \"image\" },\n cost: () => ({ credits: 0, seconds_estimate: 5 }),\n async execute({ inputs, params, ctx }) {\n const source = inputs.image.path ?? inputs.image.url;\n if (!source) return { image: inputs.image, fit: null, reason: \"not_read\" as const };\n const bytes = await bytesOf(source);\n const usage: ReviewUsage[] = [];\n const reading = await readTextBoxes(bytes, { onSpend: (u) => usage.push(u) });\n const spend = usage.length > 0 ? { usage } : {};\n if (reading.status !== \"read\") return { image: inputs.image, fit: null, reason: \"not_read\" as const, ...spend };\n const placements = params.placements ? { placements: params.placements } : {};\n const boxes = boxesToPlace(reading.boxes, params.format, {\n ...placements,\n ...(params.copy ? { copy: params.copy } : {}),\n });\n const fit = planSafeFit(boxes, params.format, { ...placements, minScale: await minFitScale(bytes) });\n if (!fit) {\n // Inside what the review blocks on already, or too far past it for a shrink that still looks native.\n const outside = planSafeFit(boxes, params.format, { ...placements, minScale: 0 }) !== null;\n return {\n image: inputs.image,\n fit: null,\n reason: outside ? (\"too_far\" as const) : (\"inside_band\" as const),\n ...spend,\n };\n }\n const fitted = await fitPicture(bytes, fit);\n if (!fitted) return { image: inputs.image, fit: null, reason: \"busy_edge\" as const, ...spend };\n ctx.log(`fit ${params.format} at scale ${fit.scale.toFixed(3)}, offset ${fit.x.toFixed(3)}, ${fit.y.toFixed(3)}`);\n const image = await ctx.assets.ingestBytes({ bytes: fitted, kind: \"image\", mime: \"image/png\" });\n return { image: image as z.infer<typeof ImageRef>, fit, ...spend };\n },\n});\n","import { z } from \"zod\";\nimport { defineNode } from \"../../engine/define.ts\";\n\nexport const textNode = defineNode({\n id: \"text\",\n version: \"1.0.0\",\n category: \"data\",\n location: \"local\",\n summary: \"A literal text value. Use for prompts, descriptions, copy.\",\n inputs: z.object({}).strict(),\n params: z.object({ value: z.string() }).strict(),\n outputs: z.object({ text: z.string() }).strict(),\n cost: () => ({ credits: 0, seconds_estimate: 0 }),\n execute: ({ params }) => Promise.resolve({ text: params.value }),\n});\n","import { z } from \"zod\";\nimport { defineNode, type StaticTiming } from \"../../engine/define.ts\";\nimport type { AssetRef } from \"../../schema/refs.ts\";\nimport { getToolVersion, runCli } from \"./lib/cli-runner.ts\";\n\nconst FFMPEG_BIN = \"ffmpeg\";\n\nconst evenPixels = (axis: string) =>\n z\n .number()\n .int()\n .positive()\n .refine((n) => n % 2 === 0, `${axis} must be even: libx264 yuv420p rejects odd sizes`);\n\nconst Transition = z\n .object({\n type: z\n .string()\n .regex(/^[a-z]+$/, \"an ffmpeg xfade transition name, e.g. fade, dissolve, zoomin, slideleft\")\n .describe(\"ffmpeg xfade transition name: fade, dissolve, zoomin, wipeleft, slideleft, …\"),\n duration_s: z.number().positive().describe(\"Overlap length in seconds (0.4 is the scaffold default).\"),\n })\n .strict();\n\nconst ConcatClip = z\n .object({\n duration_s: z\n .number()\n .positive()\n .describe(\n \"Seconds this clip occupies on the timeline. A clip with a `transition` must carry that much EXTRA \" +\n \"footage past it (the overlap eats it), so the joined length is the sum of the clip durations.\",\n ),\n length: z\n .enum([\"source\", \"trim\", \"still\"])\n .default(\"source\")\n .describe(\n \"How the clip gets its length. `source`: play the input as rendered (it must already be duration_s \" +\n \"long, plus the transition tail). `trim`: cut duration_s (+ tail) out of a longer input, starting at \" +\n \"`offset_s`. `still`: the input is an IMAGE held on screen for duration_s (+ tail).\",\n ),\n offset_s: z.number().min(0).optional().describe(\"`trim` only: where the window starts in the input, seconds.\"),\n fit: z\n .enum([\"fill\", \"pad\"])\n .default(\"fill\")\n .describe(\n \"`fill` scales to cover the frame and center-crops (footage). `pad` fits inside and letterboxes in \" +\n \"black (a real screenshot or designed graphic, whose edges must never be cropped).\",\n ),\n transition: Transition.optional().describe(\n \"The transition OUT of this clip into the next one. Absent = a hard cut.\",\n ),\n continues_frame: z\n .boolean()\n .optional()\n .describe(\n \"True when this clip's first frame repeats the previous clip's last frame (a long shot split in \" +\n \"two). `seam_dedup` drops the duplicate without shortening the timeline.\",\n ),\n })\n .strict()\n .refine((c) => c.offset_s === undefined || c.length === \"trim\", {\n message: \"offset_s only applies to a `trim` clip\",\n path: [\"offset_s\"],\n });\n\nexport const VideoConcatParams = z\n .object({\n width: evenPixels(\"width\").describe(\"Output width in pixels (even). Every clip is normalized onto it.\"),\n height: evenPixels(\"height\").describe(\"Output height in pixels (even).\"),\n fps: z.number().int().min(1).max(120).default(30).describe(\"Output frame rate every clip is resampled to.\"),\n seam_dedup: z\n .enum([\"head\", \"tail\", \"off\"])\n .default(\"head\")\n .describe(\n \"Which copy of a repeated splice frame survives on a `continues_frame` clip: `head` drops the \" +\n \"continuing clip's first frame, `tail` drops the previous clip's last frame, `off` keeps both.\",\n ),\n clips: z.array(ConcatClip).min(1).describe(\"The clips in timeline order; clip i is wired as `inputs.c<i>`.\"),\n })\n .strict();\nexport type VideoConcatParamsT = z.infer<typeof VideoConcatParams>;\n/** One clip as a canvas writes it (defaults unfilled). */\nexport type VideoConcatClipInput = z.input<typeof ConcatClip>;\ntype ConcatClipT = VideoConcatParamsT[\"clips\"][number];\n\nconst VideoConcatInputs = z.record(z.string(), z.custom<AssetRef>());\nconst VideoConcatOutputs = z.object({ video: z.custom<AssetRef>() }).strict();\n\n/** Seconds of input footage a clip consumes: its timeline length plus any transition tail. */\nfunction inputLengthS(clip: ConcatClipT): number {\n return clip.duration_s + (clip.transition?.duration_s ?? 0);\n}\n\n/** True when any boundary blends, which switches the join from one concat to a fold of xfades. */\nfunction blends(params: VideoConcatParamsT): boolean {\n return params.clips.length > 1 && params.clips.some((c) => c.transition);\n}\n\n/**\n * The per-input normalize → length chain. Normalizing forces ONE raster before the\n * join (concat hard-fails on size/SAR mismatches and silently mis-times on fps or\n * timebase mismatches); the length cut runs AFTER normalize so seam-dedup's\n * frame-indexed ops always see the output frame rate.\n */\nfunction clipOps(clip: ConcatClipT, params: VideoConcatParamsT): string {\n const { width: w, height: h, fps } = params;\n const scale =\n clip.fit === \"pad\"\n ? `scale=${w}:${h}:force_original_aspect_ratio=decrease,pad=${w}:${h}:(ow-iw)/2:(oh-ih)/2:color=black`\n : `scale=${w}:${h}:force_original_aspect_ratio=increase,crop=${w}:${h}`;\n const normalize = `${scale},format=yuv420p,fps=${fps},setsar=1,settb=AVTB`;\n const len = inputLengthS(clip).toFixed(3);\n if (clip.length === \"trim\") {\n const offset = clip.offset_s ?? 0;\n const start = offset > 0 ? `start=${offset.toFixed(3)}:` : \"\";\n return `${normalize},trim=${start}duration=${len},setpts=PTS-STARTPTS`;\n }\n if (clip.length === \"still\") return `${normalize},trim=duration=${len}`;\n return normalize;\n}\n\n/**\n * The ops that drop a duplicated splice frame for clip `i`, or null. Either way the\n * clip's last frame is clone-padded one frame so its timeline length is unchanged:\n * the audio and overlays are placed at absolute seconds and must never slide.\n */\nfunction seamOps(params: VideoConcatParamsT, i: number): string | null {\n const pad = `tpad=stop_mode=clone:stop_duration=${(1 / params.fps).toFixed(6)}`;\n if (params.seam_dedup === \"head\" && i > 0 && params.clips[i]?.continues_frame)\n return `trim=start_frame=1,setpts=PTS-STARTPTS,${pad}`;\n if (params.seam_dedup === \"tail\" && params.clips[i + 1]?.continues_frame)\n return `reverse,trim=start_frame=1,setpts=PTS-STARTPTS,reverse,${pad}`;\n return null;\n}\n\nfunction inputChain(params: VideoConcatParamsT, i: number): string {\n const seam = seamOps(params, i);\n return `[${i}:v]${clipOps(params.clips[i] as ConcatClipT, params)}${seam ? `,${seam}` : \"\"}[c${i}]`;\n}\n\n/** Input flags placed before a clip's `-i`: a still loops, decoding exactly its length. */\nfunction inputFlags(clip: ConcatClipT): string[] {\n return clip.length === \"still\" ? [\"-loop\", \"1\", \"-t\", inputLengthS(clip).toFixed(3)] : [];\n}\n\n/**\n * Fold the clips left: a blended boundary becomes an `xfade` whose offset lands where\n * the overlap eats the outgoing clip's extra tail, a hard cut a two-input concat.\n */\nfunction blendedJoins(params: VideoConcatParamsT): string[] {\n const { clips } = params;\n const joins: string[] = [];\n let cur = \"c0\";\n let accLen = inputLengthS(clips[0] as ConcatClipT);\n for (let k = 0; k < clips.length - 1; k++) {\n const transition = (clips[k] as ConcatClipT).transition;\n const next = `c${k + 1}`;\n const out = k === clips.length - 2 ? \"v\" : `j${k + 1}`;\n const nextLen = inputLengthS(clips[k + 1] as ConcatClipT);\n if (transition) {\n const offset = Math.max(0, accLen - transition.duration_s);\n joins.push(\n `[${cur}][${next}]xfade=transition=${transition.type}:duration=${transition.duration_s.toFixed(3)}:offset=${offset.toFixed(3)}[${out}]`,\n );\n accLen = accLen - transition.duration_s + nextLen;\n } else {\n joins.push(`[${cur}][${next}]concat=n=2:v=1[${out}]`);\n accLen += nextLen;\n }\n cur = out;\n }\n return joins;\n}\n\n/**\n * The ffmpeg argv the node runs. Pure and deterministic, so the scaffold's timeline\n * and this compilation can be checked without ffmpeg.\n */\nexport function compileVideoConcatArgs(params: VideoConcatParamsT): string[] {\n const inputs = params.clips.flatMap((clip, i) => [...inputFlags(clip), \"-i\", `{{in.c${i}}}`]);\n const chains = params.clips.map((_, i) => inputChain(params, i));\n const joins = blends(params)\n ? blendedJoins(params)\n : [`${params.clips.map((_, i) => `[c${i}]`).join(\"\")}concat=n=${params.clips.length}:v=1:a=0[v]`];\n return [\n ...inputs,\n \"-filter_complex\",\n [...chains, ...joins].join(\";\"),\n \"-map\",\n \"[v]\",\n \"-r\",\n String(params.fps),\n \"-c:v\",\n \"libx264\",\n \"-crf\",\n \"18\",\n \"-preset\",\n \"slow\",\n \"-pix_fmt\",\n \"yuv420p\",\n \"{{out.video}}\",\n ];\n}\n\n/**\n * The joined length and raster, before anything runs. A `trim` or `still` clip's\n * footage is exactly its input length; a `source` clip is as long as what is wired\n * in, so an unsized input leaves the total unknown rather than guessed. Each blended\n * boundary then overlaps by its transition.\n */\nexport function videoConcatTiming(\n params: VideoConcatParamsT,\n inputs: Readonly<Record<string, StaticTiming | undefined>>,\n): StaticTiming {\n const raster = { width: params.width, height: params.height };\n let total = 0;\n for (const [i, clip] of params.clips.entries()) {\n const len = clip.length === \"source\" ? inputs[`c${i}`]?.duration_s : inputLengthS(clip);\n if (len === undefined) return raster;\n total += len;\n }\n if (blends(params)) {\n for (const clip of params.clips.slice(0, -1)) total -= clip.transition?.duration_s ?? 0;\n }\n return { ...raster, duration_s: Math.round(total * 1000) / 1000 };\n}\n\n/** The wired slots a clip list needs, in order: `c0`, `c1`, … */\nfunction expectedSlots(params: VideoConcatParamsT): string[] {\n return params.clips.map((_, i) => `c${i}`);\n}\n\nexport const videoConcatNode = defineNode({\n id: \"video_concat\",\n version: \"1.0.0\",\n category: \"video\",\n location: \"local\",\n summary:\n \"Join clips and stills into one continuous video: every input is normalized onto one raster (size, frame rate, square pixels, pixel format), cut or held to its timeline length, and joined with hard cuts or xfade transitions. The output's length and size are known before it runs.\",\n when_to_use:\n \"Use to assemble a video's picture from its per-scene clips (the scaffold's `spine`). Start here: \" +\n '`{ \"type\": \"video_concat\", \"inputs\": { \"c0\": \"$ref:s0_clip.video\", \"c1\": \"$ref:s1_start.images#0\" }, ' +\n '\"params\": { \"width\": 1080, \"height\": 1920, \"clips\": [ { \"duration_s\": 3.2, \"length\": \"trim\", ' +\n '\"transition\": { \"type\": \"fade\", \"duration_s\": 0.4 } }, { \"duration_s\": 1.5, \"length\": \"still\" } ] } }`. ' +\n \"Wire clip i as `inputs.c<i>`. `length: trim` cuts a longer generated clip to its scene (optionally from \" +\n \"`offset_s`), `still` holds an image, `source` plays the input as rendered. `fit: pad` letterboxes a \" +\n \"screenshot instead of cropping it. `canvas validate` checks the summed length against the timeline, so \" +\n \"edit `duration_s` here, never an ffmpeg argv. Reach for a raw `ffmpeg` node only for a join this cannot express.\",\n inputs: VideoConcatInputs,\n params: VideoConcatParams,\n outputs: VideoConcatOutputs,\n outputKinds: { video: \"video\" },\n cost: () => ({ credits: 0, seconds_estimate: 30 }),\n staticTiming: ({ params, inputs }) => videoConcatTiming(params, inputs),\n\n validateExtra({ rawParams, rawInputs }) {\n const parsed = VideoConcatParams.safeParse(rawParams ?? {});\n if (!parsed.success) return []; // shape errors already surfaced by the param validator\n const wired = Object.keys((rawInputs as Record<string, unknown>) ?? {});\n const expected = expectedSlots(parsed.data);\n const missing = expected.filter((slot) => !wired.includes(slot));\n const extra = wired.filter((slot) => !expected.includes(slot));\n if (missing.length === 0 && extra.length === 0) return [];\n return [\n {\n path: \"inputs\",\n message: `wire exactly one input per clip (${expected.join(\", \")})${missing.length > 0 ? `; missing ${missing.join(\", \")}` : \"\"}${extra.length > 0 ? `; not a clip: ${extra.join(\", \")}` : \"\"}`,\n },\n ];\n },\n\n async cacheKeyExtras() {\n return { ffmpeg_version: await getToolVersion(FFMPEG_BIN) };\n },\n\n async execute({ inputs, params, ctx }) {\n const missing = expectedSlots(params).filter((slot) => !inputs[slot]);\n if (missing.length > 0) throw new Error(`video_concat: no input wired for ${missing.join(\", \")}`);\n return (await runCli({\n bin: FFMPEG_BIN,\n args: compileVideoConcatArgs(params),\n inputs: inputs as Record<string, AssetRef>,\n outputs: { video: { kind: \"video\", ext: \"mp4\" } },\n ctx,\n })) as { video: AssetRef };\n },\n});\n","import { estimateNodeCredits } from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { AudioRef, TextRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst AudioVoiceConvertParams = z\n .object({\n model: z.literal(\"elevenlabs/eleven_multilingual_sts_v2\"),\n /** Target voice id. Splice an upstream `voice_select` via `\"{{voice_ref}}\"`. */\n voice: z.string().min(1),\n output_format: z.string().optional(),\n /** Strip the source clip's background noise before re-voicing. */\n remove_background_noise: z.boolean().optional(),\n })\n .strict();\n\nexport const audioVoiceConvertNode = delegated({\n id: \"audio_voice_convert\",\n version: \"1.0.0\",\n category: \"audio\",\n summary:\n \"Voice Changer / speech-to-speech via ElevenLabs (eleven_multilingual_sts_v2). Re-voices an existing audio clip in a TARGET voice while preserving timing/prosody.\",\n when_to_use:\n 'Use to normalize a generator-chosen voice (e.g. a Seedance talking-head clip\\'s native audio) into ONE consistent brand voice across every scene — the cadence is preserved so any lip-sync stays valid. Wire `inputs.voice_ref: $ref:<voice_select>.voice_id` and set `params.voice: \"{{voice_ref}}\"`.',\n inputs: z\n .object({\n audio: AudioRef,\n voice_ref: TextRef.optional(),\n })\n .strict(),\n params: AudioVoiceConvertParams,\n outputs: z.object({ audio: AudioRef }).strict(),\n outputKinds: { audio: \"audio\" },\n // Priced by the shared contract per minute of source audio. The quote cannot see\n // the clip's length, so it assumes one minute; the charge uses the real length.\n cost: ({ params }) => ({\n credits: estimateNodeCredits({ nodeType: \"audio_voice_convert\", params }) ?? 1,\n seconds_estimate: 20,\n }),\n});\n","import { ELEVENLABS_MAX_TEXT_CHARS, ELEVENLABS_OUTPUT_FORMATS, estimateNodeCredits } from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { AudioRef, JsonRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst DialogueInput = z.object({\n text: z.string().min(1),\n voice_id: z.string().min(1),\n});\n\nconst DIALOGUE_MODELS = [\"elevenlabs/eleven_v3\"] as const;\n\nconst DialogueParams = z\n .object({\n model: z.enum(DIALOGUE_MODELS),\n /**\n * Ordered list of lines, each tagged with the voice that should speak it.\n * Up to 10 unique voice_ids; total text across all lines should stay under\n * ~2000 characters for best quality (ElevenLabs guidance).\n */\n inputs: z.array(DialogueInput).min(1).max(50),\n language_code: z.string().optional(),\n /** ElevenLabs voice/model settings passthrough (e.g. `{ stability: 0.5 }`). */\n settings: z.record(z.string(), z.unknown()).optional(),\n seed: z.number().int().min(0).max(4_294_967_295).optional(),\n apply_text_normalization: z.enum([\"auto\", \"on\", \"off\"]).optional(),\n /**\n * When true, hits `/v1/text-to-dialogue/with-timestamps` and emits a\n * separate `timestamps` output — character-level alignment plus\n * per-voice segment markers usable for captions, lipsync, or\n * beat-matched cuts in ad creatives.\n */\n with_timestamps: z.boolean().optional(),\n output_format: z.enum(ELEVENLABS_OUTPUT_FORMATS).optional(),\n })\n .strict()\n // Above this the backend's $10 cost cap always rejects at dispatch.\n .refine((p) => p.inputs.reduce((sum, line) => sum + line.text.length, 0) <= ELEVENLABS_MAX_TEXT_CHARS, {\n message: `total dialogue text exceeds ${ELEVENLABS_MAX_TEXT_CHARS} characters`,\n path: [\"inputs\"],\n });\n\nexport const dialogueNode = delegated({\n id: \"dialogue\",\n version: \"1.1.0\",\n category: \"audio\",\n summary:\n \"Multi-voice dialogue / VO with ElevenLabs Eleven v3. Each line is tagged with a `voice_id`, so you can render two-character scripts (e.g. ad VO + customer testimonial reaction) in a single call. Setting `with_timestamps: true` adds character-level alignment for caption rendering and lipsync-friendly cuts.\",\n when_to_use:\n \"Use for any ad creative or website video VO that needs more than narration — interviews, two-actor scripts, character ads, testimonial reads. For single-voice flat reads the existing `tts` node is cheaper and simpler; reach for `dialogue` when you need multiple speakers in one stitched track or word-level timing for downstream lipsync / captions.\",\n inputs: z.object({}).loose(),\n params: DialogueParams,\n outputs: z.object({ audio: AudioRef, timestamps: JsonRef.optional() }).strict(),\n outputKinds: { audio: \"audio\", timestamps: \"json\" },\n // Priced by the shared contract, the same per-character rate the backend charges.\n cost: ({ params }) => ({ credits: estimateNodeCredits({ nodeType: \"dialogue\", params }) ?? 1, seconds_estimate: 8 }),\n});\n","import {\n AD_FORMAT_PLATFORMS,\n type AdFormatPlatform,\n imagePictureCredits,\n modelIdsAccepted,\n OPENROUTER_IMAGE_SIZES,\n resolveAdaptFormats,\n} from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { ASPECT_ADAPT_FORMATS } from \"../../scaffold/static-sizes.ts\";\nimport { ImageRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\n// The GA ids, plus the preview ids they superseded (`MODEL_ALIASES`) so canvases written\n// with them re-run; the backend runs a preview id on its GA model.\nconst ASPECT_ADAPT_MODELS = [\"google/gemini-3-pro-image\", \"google/gemini-3.1-flash-image\"].flatMap(\n modelIdsAccepted,\n) as [string, ...string[]];\n\n// The adaptation prompt is baked into the backend handler (consistency-first,\n// direction-aware recomposition); `guidance` appends hints, never replaces it.\n// Targets come from EITHER an explicit `formats` list OR a `platform` preset\n// (Meta / LinkedIn / Google / TikTok / YouTube) that expands to the canonical\n// on-grid set — exactly one of the two, enforced here (the registry can't).\nconst ImageAspectAdaptParams = z\n .object({\n model: z.enum(ASPECT_ADAPT_MODELS),\n formats: z\n .array(z.enum(ASPECT_ADAPT_FORMATS))\n .min(1)\n .max(6)\n .refine((formats) => new Set(formats).size === formats.length, { message: \"formats must be unique\" })\n .optional(),\n platform: z.enum(AD_FORMAT_PLATFORMS).optional(),\n guidance: z.string().min(1).optional(),\n // The exact lines the ad carries: the reframe keeps each, spelled as given, once.\n copy: z.array(z.string().min(1)).min(1).max(20).optional(),\n // Per target format, the fractions of each edge the platform's interface covers: words,\n // logo and button stay inside. The static scaffold sets both from prompt.json and `staticSafeArea`.\n safe_areas: z\n .record(\n z.string(),\n z.object({ top: z.number(), bottom: z.number(), left: z.number(), right: z.number() }).strict(),\n )\n .optional(),\n image_size: z.enum(OPENROUTER_IMAGE_SIZES).optional(),\n })\n .strict()\n .refine((p) => (p.formats === undefined) !== (p.platform === undefined), {\n message: \"provide exactly one of `formats` (explicit ratios) or `platform` (a placement preset)\",\n path: [\"formats\"],\n });\n\nexport const imageAspectAdaptNode = delegated({\n id: \"image_aspect_adapt\",\n version: \"1.0.0\",\n category: \"image\",\n summary:\n \"Adapt ONE creative into multiple aspect ratios (Meta: 9:16 stories, 1:1 feed, 4:5, 16:9…) in a single step. Give it either an explicit `formats` list OR a `platform` preset (meta_feed, meta_feed_stories, meta_all, linkedin, google_demandgen, tiktok, youtube) that expands to that platform's canonical set. AI recomposes the layout per format — identical subject, text, logos, colors, and style; the scene is extended/restructured, never stretched or cropped. Formats that already match the source ratio pass through unchanged at zero cost. Outputs are ordered exactly as the resolved format list.\",\n when_to_use:\n \"Use after a hero creative exists (image_generate, ingest, image_search) to fan it out to every placement format — wire the creative into `source` and set EITHER `formats` (exact ratios) OR `platform` (e.g. `meta_feed_stories`). Cost is estimated per format; formats matching the source ratio are free pass-throughs. Off-grid platform targets (e.g. Google 1.91:1) are not rendered here — crop them from the nearest ratio with `baker images crop`. Pick `google/gemini-3.1-flash-image` (Nano Banana 2) while iterating, `google/gemini-3-pro-image` (Nano Banana Pro) for final-quality adaptation.\",\n inputs: z.object({ source: ImageRef }).loose(),\n params: ImageAspectAdaptParams,\n outputs: z.object({ images: z.array(ImageRef).min(1) }).strict(),\n outputKinds: { images: \"image\" },\n cost: ({ params }) => {\n const p = params as { model?: string; formats?: string[]; platform?: AdFormatPlatform } | undefined;\n const count = Math.max(1, resolveAdaptFormats(p ?? {}).length);\n return {\n credits: count * imagePictureCredits(String(p?.model)),\n seconds_estimate: 30 + 30 * count,\n };\n },\n});\n","import { estimateNodeCredits, modelIdsAccepted } from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { ImageRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst ImageBackgroundRemoveParams = z\n .object({\n // `fal/birefnet-v2` is the legacy id stored canvases carry. It stays the default for one\n // release: every backend accepts it, while `replicate/birefnet` needs the backend that ships with\n // this CLI, and the two deploy independently.\n model: z.enum(modelIdsAccepted(\"replicate/birefnet\")).optional().default(\"fal/birefnet-v2\"),\n operating_resolution: z.enum([\"1024x1024\", \"2048x2048\", \"2304x2304\"]).optional(),\n // DEPRECATED, accepted so stored canvases still parse, and ignored: the model this\n // node runs (`men1scus/birefnet`) takes only an image and a resolution, has no\n // variant and returns no mask. `mask_only: true` still returns the cutout.\n model_variant: z\n .enum([\"General Use (Light)\", \"General Use (Heavy)\", \"Matting\", \"Portrait\", \"DIS\", \"HRSOD\", \"COD\"])\n .optional()\n .meta({ deprecated: true, description: \"Ignored: the model has no variants.\" }),\n mask_only: z\n .boolean()\n .optional()\n .meta({ deprecated: true, description: \"Ignored: the model returns the cutout only, never a mask.\" }),\n })\n .strict();\n\nexport const imageBackgroundRemoveNode = delegated({\n id: \"image_background_remove\",\n version: \"1.0.0\",\n category: \"image\",\n summary:\n \"Remove the background from an image and return a transparent PNG. Powered by BiRefNet (`men1scus/birefnet` on Replicate).\",\n when_to_use:\n \"Use to extract subjects from photos for use as overlays in hyperframe compositions, product shots, or compositing pipelines. \" +\n \"It returns the alpha-cut image only; there is no mask output and no model variant to pick.\",\n inputs: z\n .object({\n image: ImageRef,\n })\n .strict(),\n params: ImageBackgroundRemoveParams,\n outputs: z.object({ image: ImageRef }).strict(),\n outputKinds: { image: \"image\" },\n cost: ({ params }) => ({\n credits: estimateNodeCredits({ nodeType: \"image_background_remove\", params }) ?? 1,\n seconds_estimate: 5,\n }),\n});\n","import { z } from \"zod\";\nimport { ImageRef, JsonRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst IMAGE_DESCRIBE_MODELS = [\"~google/gemini-pro-latest\", \"~google/gemini-flash-latest\"] as const;\n\nexport const imageDescribeNode = delegated({\n id: \"image_describe\",\n version: \"1.4.0\",\n category: \"vision\",\n summary:\n \"Reverse-engineer an image into an exhaustive, replication-grade JSON description: who the advertiser is and what they sell (source_context), composition, non-person subjects with expression/treatment, deeply detailed people, brand-identified logos (named by brand, not appearance), camera optics, lighting, color palette WITH per-color brand-ownership (brand vs borrowed-functional) and purpose, materials, visible text, ad signals (proof badges/CTA/price), the persuasion engine (ad_intent), style, post-processing.\",\n when_to_use:\n 'Use to turn a reference image into a structured blueprint you can inject into downstream prompts via `{{slot}}` — e.g. restyle a competitor ad onto your own product, lock a look across a series, or feed exact palette/lighting into image_generate. Purpose-built for market adaptation: logos are identified by brand (\"Trustpilot\", never \"green star\"), people and animals carry expression/emotion/intent detail, and each color is tagged brand vs borrowed-functional so a recolor can keep the reds/yellows that do a job. The extraction prompt is baked in; use `focus` to emphasise aspects and `context` to pass known provenance (advertiser, category, market) so source_context and color ownership are grounded. Pick `~google/gemini-pro-latest` for the densest extraction (recommended for ad / market-adaptation passes), `~google/gemini-flash-latest` for cheap/fast passes. The output is rich — raise `max_tokens` (e.g. 8000+) for dense ads so the JSON isn\\'t truncated.',\n inputs: z.object({ image: ImageRef }).loose(),\n params: z\n .object({\n model: z.enum(IMAGE_DESCRIBE_MODELS),\n focus: z.string().optional(),\n context: z.string().optional(),\n temperature: z.number().min(0).max(2).optional(),\n max_tokens: z.number().int().positive().optional(),\n })\n .strict(),\n outputs: z.object({ description: JsonRef }).strict(),\n outputKinds: { description: \"json\" },\n cost: () => ({ credits: 2, seconds_estimate: 10 }),\n});\n","import { z } from \"zod\";\nimport { ImageRef, JsonRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst ImageLayerizeParams = z\n .object({\n /**\n * What to separate. Read as extraction instructions, not as a generation\n * prompt — \"keep the bottle and its shadow as one layer\", not \"make it blue\".\n */\n instructions: z.string().max(600).optional(),\n })\n .strict();\n\n/**\n * Three outputs rather than one, because the useful thing here is plural.\n *\n * `layers` is the answer to \"give me this picture in layers\": an array of\n * transparent PNGs, bottom to top, each placeable on its own. `base` is the flat\n * picture kept underneath, so a composition of the layers always covers the\n * frame — the model separates what was VISIBLE and does not repaint what sat\n * behind a subject, so the cutouts alone leave gaps. `manifest` carries what the\n * pixels cannot: each layer's box, and for recovered copy its exact wording,\n * font, size and colour, which is what a hyperframe composition needs to place a\n * layer or re-set a headline in the original's type.\n *\n * Shaped after `video_deconstruct`, which emits a frames array plus a transcript\n * JSON for the same reason.\n */\nexport const imageLayerizeNode = delegated({\n id: \"image_layerize\",\n version: \"1.0.0\",\n category: \"image\",\n summary:\n \"Split an image into editable layers: a transparent PNG per element, plus any copy baked into the picture recovered as real text with its typography. Powered by Seedream 5.0 Pro Layerize, with Ideogram lifting the text off first.\",\n when_to_use:\n \"Use when you need ONE element of a picture on its own (a product with no background, a logo lockup), or when a shot is right but its copy is wrong and regenerating would change the picture too. \" +\n \"The manifest gives you each layer's box and, for text, its exact wording, font, size and colour — enough to re-set a headline in the original's type. \" +\n \"For a plain subject cutout with no text involved, `image_background_remove` is cheaper and one call.\",\n inputs: z\n .object({\n image: ImageRef,\n })\n .strict(),\n params: ImageLayerizeParams,\n outputs: z\n .object({\n layers: z.array(ImageRef),\n base: ImageRef,\n manifest: JsonRef,\n })\n .strict(),\n outputKinds: { layers: \"image\", base: \"image\", manifest: \"json\" },\n // Billed per returned layer (2-17) plus an optional text pass; the backend\n // charges the real count on completion. This is the pre-run estimate.\n cost: () => ({ credits: 30, seconds_estimate: 100 }),\n});\n","import { imagePictureCredits, modelIdsAccepted, OPENROUTER_IMAGE_SIZES } from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { ImageRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\n// The GA ids, plus the preview ids they superseded (`MODEL_ALIASES`) so canvases written\n// with them re-run; the backend runs a preview id on its GA model.\nconst REFERENCE_SHEET_MODELS = [\"google/gemini-3-pro-image\", \"google/gemini-3.1-flash-image\"].flatMap(\n modelIdsAccepted,\n) as [string, ...string[]];\n\n// Permissive union of every param accepted by any curated model. The model\n// registry (`@baker/canvas-contract`) is the strict per-model gate. The sheet\n// prompt itself is baked into the backend handler — `prompt_override` is the\n// only full-bypass lever.\nconst ImageReferenceSheetParams = z\n .object({\n model: z.enum(REFERENCE_SHEET_MODELS),\n subject_description: z.string().min(1),\n // `location` = a set/room shown from several camera ANGLES (not a rotated subject),\n // so a multi-scene shoot keeps one consistent set.\n subject_type: z.enum([\"character\", \"person\", \"product\", \"location\"]),\n views: z.array(z.string().min(1)).min(2).max(8).optional(),\n style: z.string().optional(),\n prompt_override: z.string().min(1).optional(),\n aspect_ratio: z\n .enum([\"1:1\", \"16:9\", \"9:16\", \"4:3\", \"3:4\", \"3:2\", \"2:3\", \"4:5\", \"5:4\", \"21:9\", \"1:4\", \"4:1\", \"1:8\", \"8:1\"])\n .optional(),\n image_size: z.enum(OPENROUTER_IMAGE_SIZES).optional(),\n })\n .strict();\n\nexport const imageReferenceSheetNode = delegated({\n id: \"image_reference_sheet\",\n version: \"1.0.0\",\n category: \"image\",\n summary:\n \"Fuse 1–6 images of a single subject (person, character, product, or location/set) into ONE multi-view reference sheet — a labeled grid in consistent style and lighting: a turnaround (FRONT / SIDE / BACK…) for a person/character/product, or several camera angles of the same room (WIDE / REVERSE / DETAIL…) for a location. Curated models: Gemini 3 Pro Image (best fusion + labels), Gemini 3.1 Flash Image (cheap iteration).\",\n when_to_use:\n \"Use before image_generate / video_generate when a subject must stay consistent across many creatives — wire the `sheet` output into their `reference` input instead of re-describing the subject per prompt. `subject_description` should be the exact wording you reuse downstream. Pick `google/gemini-3-pro-image` for final 6-view sheets at 2K+, `google/gemini-3.1-flash-image` while iterating.\",\n inputs: z.object({ references: z.array(ImageRef).min(1).max(6) }).loose(),\n params: ImageReferenceSheetParams,\n outputs: z.object({ sheet: ImageRef }).strict(),\n outputKinds: { sheet: \"image\" },\n cost: ({ params }) => ({\n credits: imagePictureCredits(String((params as { model?: string } | undefined)?.model)),\n seconds_estimate: 30,\n }),\n});\n","import { z } from \"zod\";\nimport { ImageRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst ImageSearchParams = z\n .object({\n prompt: z.string().min(1),\n count: z.number().int().min(1).max(20).default(5),\n })\n .strict();\n\nexport const imageSearchNode = delegated({\n id: \"image_search\",\n version: \"1.0.0\",\n category: \"image\",\n summary:\n \"Agentic image search across Google Images, free stock photography (Pexels and Pixabay), and Pinterest. An LLM agent picks the search tools and queries, selects the best matches, and the results are downloaded into canvas assets.\",\n when_to_use:\n \"Use to gather real-world reference or inspiration images for a prompt (e.g. several photos of an australian shepherd) so a later step or the user can pick the best one. Not for creating new imagery — use image_generate for that.\",\n inputs: z.object({}).loose(),\n params: ImageSearchParams,\n outputs: z.object({ images: z.array(ImageRef).min(1) }).strict(),\n outputKinds: { images: \"image\" },\n cost: ({ params }) => ({ credits: Math.ceil(2 + params.count / 2), seconds_estimate: 30 }),\n});\n","import { z } from \"zod\";\nimport { ImageRef, TextRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst IMAGE_SELECT_MODELS = [\"~google/gemini-flash-latest\", \"~google/gemini-pro-latest\"] as const;\n\nexport const imageSelectNode = delegated({\n id: \"image_select\",\n version: \"1.0.0\",\n category: \"vision\",\n summary:\n \"Pick the best `count` images out of the candidates with a vision LLM, judged against a prompt. Outputs a passthrough subset of the input refs (no new pixels) plus the model's comparative reasoning. A single candidate passes through unjudged, free and without reasoning.\",\n when_to_use:\n \"Use after an image_generate run with `n` > 1 (wire its whole `images` array), several image_generate variants, or any pool of images, to keep only the strongest before expensive downstream steps — video generation, reference sheets, final delivery. `count` fixes the output size, so `images#0`…`images#count-1` are always safe to wire. Pick `~google/gemini-flash-latest` for cheap/fast picks and `~google/gemini-pro-latest` for harder aesthetic judgement.\",\n inputs: z.object({ images: z.array(ImageRef).min(1) }).loose(),\n params: z\n .object({\n model: z.enum(IMAGE_SELECT_MODELS),\n prompt: z.string().min(1),\n count: z.number().int().min(1).default(1),\n temperature: z.number().min(0).max(2).optional(),\n max_tokens: z.number().int().positive().optional(),\n })\n .strict(),\n // No `reasoning` when a lone candidate passed through: there was no judgement to explain.\n outputs: z.object({ images: z.array(ImageRef).min(1), reasoning: TextRef.optional() }).strict(),\n outputKinds: { images: \"image\", reasoning: \"text\" },\n cost: () => ({ credits: 1, seconds_estimate: 5 }),\n // Arity is only knowable at validate time when `images` is a literal array\n // of refs; a single `$ref:` string to an upstream array output is deferred\n // to the runtime Zod parse and the backend's own arity check.\n validateExtra: ({ rawParams, rawInputs }) => {\n const issues: Array<{ path: string; message: string }> = [];\n const images = (rawInputs as { images?: unknown } | undefined)?.images;\n if (!Array.isArray(images)) return issues;\n if (images.length === 0) {\n issues.push({ path: \"inputs.images\", message: \"image_select needs at least 1 image wired\" });\n }\n const count = (rawParams as { count?: unknown } | undefined)?.count;\n if (typeof count === \"number\" && count > images.length) {\n issues.push({\n path: \"params.count\",\n message: `count ${count} exceeds the ${images.length} images wired into \\`images\\``,\n });\n }\n return issues;\n },\n});\n","import {\n DEFAULT_MUSIC_SECONDS,\n ELEVENLABS_MAX_MUSIC_LENGTH_MS,\n ELEVENLABS_OUTPUT_FORMATS,\n estimateNodeCredits,\n} from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { AudioRef, JsonRef, VideoRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst MUSIC_MODELS = [\"elevenlabs/music-v1\", \"elevenlabs/video-background-music-v1\"] as const;\n\nconst MusicParams = z\n .object({\n model: z.enum(MUSIC_MODELS),\n /** Free-form prompt. Used by `elevenlabs/music-v1` (compose-detailed). */\n prompt: z.string().optional(),\n /**\n * Structured composition plan (intro / hook / verse / outro sections with\n * per-section styles + durations). Mutually exclusive with `prompt`.\n */\n composition_plan: z.record(z.string(), z.unknown()).optional(),\n /** Target length when using `prompt`. 3000–454545ms (capped by the $10 per-node cost limit). */\n music_length_ms: z.number().int().min(3000).max(ELEVENLABS_MAX_MUSIC_LENGTH_MS).optional(),\n seed: z.number().int().optional(),\n /** Prompt mode only — forces an instrumental (no vocals) track. */\n force_instrumental: z.boolean().optional(),\n /** composition_plan only — honor exact section durations. */\n respect_sections_durations: z.boolean().optional(),\n /** Emit word-level timestamps alongside the audio. */\n with_timestamps: z.boolean().optional(),\n /**\n * video-to-music only — short description of the desired score\n * (\"upbeat synth, fast cuts, 80s\") used to bias the model.\n *\n * The `describe` text below is the one piece of craft this node can enforce\n * nowhere else: a bed under somebody talking must be ONE steady character.\n * A description that narrated the speaker's emotional arc (\"quiet and tense\n * while she is overwhelmed, opening as she walks, resolving warm and\n * confident\") came back as a film score and the client's verdict was \"la\n * musica que has elegido es muy dramática\".\n */\n description: z\n .string()\n .max(1000)\n .optional()\n .describe(\n \"The score you want, in sound (instruments, tempo, texture) — not in feelings. Under speech, name ONE \" +\n \"steady character and forbid movement: no build, no drop, no climax, no key change, nothing that \" +\n \"'follows the arc'. This model WATCHES the cut, so it will score the footage's emotion unless told \" +\n \"not to — asking it to track a speaker's emotional arc is how a testimonial bed comes back dramatic. \" +\n \"A bed is furniture; the voice carries the story.\",\n ),\n /** video-to-music only — up to 10 style tags. */\n tags: z\n .array(z.string())\n .max(10)\n .optional()\n .describe(\n \"Style tags. Under speech, prefer tags that hold it still (instrumental, understated, steady, no drums) \" +\n \"over tags that move it (cinematic, epic, building, resolving, trailer).\",\n ),\n output_format: z.enum(ELEVENLABS_OUTPUT_FORMATS).optional(),\n })\n .strict();\n\nexport const musicNode = delegated({\n id: \"music\",\n // 1.2.0: the ElevenLabs engine moved to `music_v2` (ELEVENLABS_MUSIC_ENGINE).\n // The bump is not cosmetic — nodeVersion is part of the canvas cache key, so\n // without it a re-run would serve the v1 bed the switch was made to replace.\n version: \"1.2.0\",\n category: \"audio\",\n summary:\n \"Generate music for ad creatives and website video content. `elevenlabs/music-v1` composes from a text prompt or structured composition plan; `elevenlabs/video-background-music-v1` scores an existing video clip provided via `inputs.video`.\",\n when_to_use:\n \"Use to produce background music or a full score for video ads, hero-section reels, or any motion content. Prefer the video-to-music model when you already have a cut and want music timed to it; use compose-detailed when you have only a brief or want section-level control (intro / hook / outro). Pair the resulting audio with `video_generate` or `video_lipsync` at compose time.\",\n inputs: z.object({ video: VideoRef.optional() }).loose(),\n params: MusicParams,\n outputs: z.object({ audio: AudioRef, timestamps: JsonRef.optional() }).strict(),\n outputKinds: { audio: \"audio\", timestamps: \"json\" },\n // Priced by the shared contract: per second of audio, 30s when no length is pinned.\n cost: ({ params }) => {\n const seconds = params.music_length_ms ? Math.ceil(params.music_length_ms / 1000) : DEFAULT_MUSIC_SECONDS;\n return { credits: estimateNodeCredits({ nodeType: \"music\", params }) ?? 1, seconds_estimate: seconds + 15 };\n },\n // Per-model semantics the registry can't express: compose needs exactly one\n // of prompt/composition_plan, and a video wired into compose is dead weight.\n validateExtra: ({ rawParams, rawInputs }) => {\n const issues: Array<{ path: string; message: string }> = [];\n const params = (rawParams ?? {}) as { model?: unknown; prompt?: unknown; composition_plan?: unknown };\n if (params.model !== \"elevenlabs/music-v1\") return issues;\n const hasPrompt = params.prompt !== undefined;\n const hasPlan = params.composition_plan !== undefined;\n if (hasPrompt === hasPlan) {\n issues.push({\n path: \"params\",\n message: \"elevenlabs/music-v1 needs exactly one of `prompt` or `composition_plan`\",\n });\n }\n if ((rawInputs as { video?: unknown } | undefined)?.video !== undefined) {\n issues.push({\n path: \"inputs.video\",\n message:\n \"elevenlabs/music-v1 ignores `inputs.video` — use elevenlabs/video-background-music-v1 to score a video\",\n });\n }\n return issues;\n },\n});\n","import { DEFAULT_SOUND_EFFECT_SECONDS, ELEVENLABS_OUTPUT_FORMATS, estimateNodeCredits } from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { AudioRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst SOUND_EFFECT_MODELS = [\"elevenlabs/eleven_text_to_sound_v2\"] as const;\n\nconst SoundEffectParams = z\n .object({\n model: z.enum(SOUND_EFFECT_MODELS),\n /** Prompt describing the SFX (\"metal door slam\", \"soft UI tap\", \"ocean waves\"). */\n text: z.string().min(1),\n /**\n * Target length in seconds. 0.5–30. Leave unset to let the model pick the\n * natural length for the described effect.\n */\n duration_seconds: z.number().min(0.5).max(30).optional(),\n /**\n * 0–1. Higher = stick closer to the prompt at the cost of variety; lower\n * = let the model interpret more freely. Defaults to 0.3 on the provider.\n */\n prompt_influence: z.number().min(0).max(1).optional(),\n /** Only valid on `eleven_text_to_sound_v2` — produce a seamless loop. */\n loop: z.boolean().optional(),\n output_format: z.enum(ELEVENLABS_OUTPUT_FORMATS).optional(),\n })\n .strict();\n\nexport const soundEffectNode = delegated({\n id: \"sound_effect\",\n version: \"1.1.0\",\n category: \"audio\",\n summary:\n \"Generate short sound effects from a text prompt via ElevenLabs Text-to-Sound. Use for whooshes, impacts, UI clicks, ambient beds, or signature stingers in ad creatives and product videos.\",\n when_to_use:\n \"Reach for this when you need a punch-in SFX layered against `video_generate` or `hyperframe_render` output — e.g. a logo whoosh on a hero shot, a click on a CTA cut, a swelling ambient bed under VO. Set `loop: true` for atmospheric beds that need to tile under longer footage; leave `duration_seconds` unset and the model picks a natural length.\",\n inputs: z.object({}).loose(),\n params: SoundEffectParams,\n outputs: z.object({ audio: AudioRef }).strict(),\n outputKinds: { audio: \"audio\" },\n // Priced by the shared contract: per second of audio, 5s when the model picks the length.\n cost: ({ params }) => {\n const seconds = params.duration_seconds ?? DEFAULT_SOUND_EFFECT_SECONDS;\n return { credits: estimateNodeCredits({ nodeType: \"sound_effect\", params }) ?? 1, seconds_estimate: seconds + 5 };\n },\n});\n","import { z } from \"zod\";\nimport { TextRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst TEXT_GENERATE_MODELS = [\"~google/gemini-flash-latest\", \"~google/gemini-pro-latest\"] as const;\n\nexport const textGenerateNode = delegated({\n id: \"text_generate\",\n version: \"2.2.0\",\n category: \"language\",\n summary: \"Single-turn LLM text generation via OpenRouter. Returns a text response.\",\n when_to_use:\n 'Use for any short text generation step in a canvas — ad copy, hooks, headlines, JSON outputs for downstream nodes. Pick `~google/gemini-flash-latest` for cheap/fast work and `~google/gemini-pro-latest` for harder reasoning. When the output must be JSON for a downstream `{{slot}}` (e.g. the ad-blueprint transform), set `response_format: \"json_object\"` so the model returns clean JSON with no markdown fences or prose. Set `web_search: true` to let the model search the live web first (OpenRouter `:online`) — useful when the transform must adapt copy to the target brand\\'s real facts (current pricing, the trust signals it actually has) rather than guess.',\n inputs: z.object({}).loose(),\n params: z\n .object({\n model: z.enum(TEXT_GENERATE_MODELS),\n prompt: z.string().min(1),\n system: z.string().optional(),\n response_format: z.enum([\"text\", \"json_object\"]).optional(),\n web_search: z.boolean().optional(),\n temperature: z.number().min(0).max(2).optional(),\n max_tokens: z.number().int().positive().optional(),\n })\n .strict(),\n outputs: z.object({ text: TextRef }).strict(),\n outputKinds: { text: \"text\" },\n cost: () => ({ credits: 1, seconds_estimate: 3 }),\n});\n","import { ELEVENLABS_MAX_TEXT_CHARS, ELEVENLABS_OUTPUT_FORMATS, estimateNodeCredits } from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { AudioRef, JsonRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst TTS_MODELS = [\"elevenlabs/eleven_v3\"] as const;\n\n/**\n * ElevenLabs voice settings passthrough. Mirrors the provider's\n * `voice_settings` object.\n */\nconst TtsVoiceSettings = z\n .object({\n stability: z.number().min(0).max(1).optional(),\n similarity_boost: z.number().min(0).max(1).optional(),\n style: z.number().min(0).max(1).optional(),\n use_speaker_boost: z.boolean().optional(),\n speed: z.number().min(0.25).max(4.0).optional(),\n })\n .strict();\n\nconst TtsPronunciationLocator = z\n .object({\n pronunciation_dictionary_id: z.string().min(1),\n version_id: z.string().nullable().optional(),\n })\n .strict();\n\nconst TtsParams = z\n .object({\n model: z.enum(TTS_MODELS),\n text: z.string().min(1).max(ELEVENLABS_MAX_TEXT_CHARS),\n voice: z.string().min(1),\n\n /** Provider output_format (mp3 family only — assets are stored as audio/mpeg). */\n output_format: z.enum(ELEVENLABS_OUTPUT_FORMATS).optional(),\n seed: z.number().int().min(0).max(4_294_967_295).optional(),\n\n // Top-level shortcuts; structured form is `voice_settings`.\n stability: z.number().min(0).max(1).optional(),\n similarity_boost: z.number().min(0).max(1).optional(),\n voice_settings: TtsVoiceSettings.optional(),\n\n /** ISO 639-1 language code. eleven_v3 supports language hints. */\n language_code: z.string().optional(),\n pronunciation_dictionary_locators: z.array(TtsPronunciationLocator).max(3).optional(),\n apply_text_normalization: z.enum([\"auto\", \"on\", \"off\"]).optional(),\n /** Currently Japanese-only. Adds latency. */\n apply_language_text_normalization: z.boolean().optional(),\n\n /**\n * When true, hits `/v1/text-to-speech/{voice_id}/with-timestamps` and\n * adds a `timestamps` output (character-level alignment) for caption\n * rendering, lipsync, and beat-matched cuts.\n */\n with_timestamps: z.boolean().optional(),\n })\n .strict();\n\nexport const ttsNode = delegated({\n id: \"tts\",\n version: \"2.0.0\",\n category: \"audio\",\n summary:\n \"Single-voice text-to-speech via ElevenLabs Eleven v3. Optional character-level timestamps for caption rendering and beat-matched cuts.\",\n when_to_use:\n \"Use for single-speaker VO — ad reads, hero-section narration, product walkthroughs. Reach for `dialogue` when you need multiple voices in one stitched track. Set `with_timestamps: true` when downstream needs character-level alignment (captions, lipsync).\",\n inputs: z.object({}).loose(),\n params: TtsParams,\n outputs: z.object({ audio: AudioRef, timestamps: JsonRef.optional() }).strict(),\n outputKinds: { audio: \"audio\", timestamps: \"json\" },\n // Priced by the shared contract, the same per-character rate the backend charges.\n cost: ({ params }) => ({\n credits: estimateNodeCredits({ nodeType: \"tts\", params }) ?? 1,\n seconds_estimate: params.with_timestamps ? 7 : 5,\n }),\n});\n","import { estimateNodeCredits, VIDEO_GENERATE_MODELS } from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { ImageRef, VideoRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\nimport { registryParamShape } from \"./registry-params.ts\";\n\n// The accepted model set is the canonical curated roster from the contract — kept\n// in one place so this node schema can never drift from `MODEL_REGISTRY` (which is\n// exactly the drift that let a registered model fail this schema before it).\nconst videoModelEnum = z.enum(VIDEO_GENERATE_MODELS as unknown as [string, ...string[]]);\n\n// Permissive union of every param accepted by any curated model, derived from the\n// registry (`registryParamShape`). The registry gates per-model: e.g. Seedance rejects\n// `negative_prompt`, Veo accepts it, Kling takes `cfg_scale`, only Seedance 2.5 takes\n// `watermark`. Enum values for `duration`/`resolution` are also gated there.\nconst VideoGenerateParams = z\n .object({\n model: videoModelEnum,\n ...registryParamShape(\"video_generate\", { prompt: z.string().min(1) }),\n })\n .strict();\n\nexport const videoGenerateNode = delegated({\n id: \"video_generate\",\n version: \"2.0.0\",\n category: \"video\",\n summary:\n \"Generate video for ad creatives. Curated roster: `google/gemini-omni-1.1-flash` (DEFAULT — native audio + reference images in one call, 360p-4k, 3-10s), `bytedance/seedance-2.0` (identity/product workhorse, NO photoreal human faces), `google/veo-3.1` (photoreal cine ceiling + the human-face model), `google/veo-3.1-fast` (cheap Veo iteration), `kwaivgi/kling-v3.0-pro` (motion-transfer/dynamic). Async with polling.\",\n when_to_use:\n \"`google/gemini-omni-1.1-flash` is the DEFAULT: it renders picture and synchronized audio in one call, and is the only model here that takes reference images alongside a prompt. SET `duration` (3-10s) to the length the beat actually needs — it bills PER SECOND, so leaving it out renders the 10s default and charges for ten seconds of a beat that may need three. SET `resolution` too: `360p` bills a THIRD of `720p` ($0.034 vs $0.101 per second) and is the right tier while you are still choosing between takes — render the drafts at 360p, then re-render the keeper at `720p` (default), `1080p` ($0.152/s) or `4k` ($0.304/s). It accepts only `16:9` or `9:16`, and takes NO `seed`, `negative_prompt` or `generate_audio` param — sending one fails validation, and it always renders audio. Keep the default for ordinary beats; move off it only when a beat needs a length outside 3-10s or a 1:1 frame. Use `bytedance/seedance-2.0` for identity/product output WITHOUT a photoreal human face on camera. Any clip whose frame shows a photoreal human face — a UGC creator, presenter, or testimonial speaker, REAL OR AI-GENERATED — must use `google/veo-3.1`: ByteDance's filter rejects photoreal human faces on Seedance (content_policy_blocked/E005), and a synthetic AI face does NOT clear it. Use `google/veo-3.1-fast` while iterating to keep cost low; `kwaivgi/kling-v3.0-pro` for motion-transfer/hyper-dynamic beats. `baker canvas scaffold-video` auto-routes a photoreal cast to Veo. A Seedance clip that is refused for a face at runtime is NOT moved to another model: one guided only by reference images is re-rendered on the same model through a second route that accepts faces (about twice the price), and one that starts from a frame comes back as content_policy_blocked — re-run that clip on `google/veo-3.1`. Each model gates its own durations, resolutions and aspect ratios in the registry: `baker studio models --kind video --model <id>` shows them.\",\n inputs: z\n .object({\n first_frame: ImageRef.optional(),\n last_frame: ImageRef.optional(),\n reference: ImageRef.optional(),\n /**\n * Reference-to-video: several images the model uses as visual guidance\n * (this person, this product) instead of an exact opening frame. Mutually\n * exclusive with `first_frame` — OpenRouter treats a request carrying both\n * as image-to-video and ignores these, so wire one or the other.\n */\n references: z.array(ImageRef).optional(),\n })\n .loose(),\n params: VideoGenerateParams,\n outputs: z.object({ video: VideoRef }).strict(),\n outputKinds: { video: \"video\" },\n // Priced from the shared contract, so `validate`'s quote and the charge the\n // backend applies come from ONE table. A flat number here under-quoted a\n // 1080p 8s clip by ~10x, and the agent reads this out to the user as \"this\n // will cost N\" before spending it.\n // Reads model, duration, resolution and generate_audio (audio bills at a separate,\n // higher rate on every model that offers it, so omitting it quotes half the cost).\n cost: ({ params }) => ({\n credits: estimateNodeCredits({ nodeType: \"video_generate\", params }) ?? 1,\n seconds_estimate: 120,\n }),\n});\n","import { estimateNodeCredits, modelIdsAccepted } from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { VideoRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst VideoBackgroundRemoveParams = z\n .object({\n // `fal/veed-video-background-removal` is the legacy id stored canvases carry. It stays the default for one\n // release: every backend accepts it, while `replicate/birefnet-video` needs the backend that ships with\n // this CLI, and the two deploy independently.\n model: z.enum(modelIdsAccepted(\"replicate/birefnet-video\")).optional().default(\"fal/veed-video-background-removal\"),\n // Refines the matte's soft edges against background bleed (the model's `refine_fg`).\n edge_refinement: z.boolean().optional().default(true),\n output_codec: z.enum([\"vp9\", \"h264\"]).optional().default(\"vp9\"),\n })\n .strict();\n\nexport const videoBackgroundRemoveNode = delegated({\n id: \"video_background_remove\",\n version: \"1.0.0\",\n category: \"video\",\n summary:\n \"Remove the background from a video and return a transparent VP9-with-alpha WebM (or H264 RGB+alpha pair). Drops directly into a hyperframe composition as `<video src='...'>` for chroma-keyed picture-in-picture overlays. Powered by BiRefNet Video (`sprited/birefnet-video` on Replicate).\",\n when_to_use:\n \"Use when you need a talking-head or subject to float over a custom background in a hyperframe composition. Pair with hyperframe_render(composition: screencast-with-talker) for screencast-with-narrator videos. \" +\n \"Output is `video/webm` with alpha — feed straight into `<video src>` in a composition.\",\n inputs: z\n .object({\n video: VideoRef,\n })\n .strict(),\n params: VideoBackgroundRemoveParams,\n outputs: z.object({ video: VideoRef }).strict(),\n outputKinds: { video: \"video\" },\n // Priced by the shared contract per 30 frames; the quote assumes the same 30s of\n // footage the charge falls back to when the clip carries no duration.\n cost: ({ params }) => ({\n credits: estimateNodeCredits({ nodeType: \"video_background_remove\", params }) ?? 1,\n seconds_estimate: 60,\n }),\n});\n","import { z } from \"zod\";\nimport { ImageRef, JsonRef, VideoRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nconst VIDEO_DECONSTRUCT_MODELS = [\"~google/gemini-flash-latest\", \"~google/gemini-pro-latest\"] as const;\n\nexport const videoDeconstructNode = delegated({\n id: \"video_deconstruct\",\n version: \"1.4.0\",\n category: \"video\",\n summary:\n 'Deconstruct a video into a replication-grade blueprint: scene boundaries, the real start/end frame of every scene (extracted from the video as images), and an exhaustive JSON analysis — per-scene action detail, camera motion, generation-ready frame/motion prompts, overlay text with full typographic style, floating elements, deeply detailed cast (perceived demographics, ethnicity/skin-tone, styling, market-recasting notes), brand-identified logos (named by brand and what they signal, not by appearance, with on-screen timestamps), dialogue with voice descriptions, music spec, SFX list, plus a word-level transcript. `mode:\"index\"` is the cheap structure-first pass: scene boundaries + global blueprint only (one LLM call, no frames).',\n when_to_use:\n 'Use to reverse-engineer a reference video (e.g. a competitor ad) so a new canvas can reproduce or remix it scene by scene. Agent loop: (1) optionally run `mode:\"index\"` to see the structure cheaply (scene count, boundaries, transcript) before planning; (2) run the full deconstruct; (3) read `analysis` and author the reproduction canvas. The blueprint maps 1:1 onto generation nodes: `analysis.scenes[i]` aligns positionally with `start_frames#i`/`end_frames#i`; per scene, `start_frame_prompt`/`end_frame_prompt` feed image_generate (overlay text is excluded from them by contract — recomposite it from `overlays`), `motion_prompt` + the two frames feed video_generate (first_frame/last_frame), `dialogue[].voice_description` casts tts/dialogue voices, `global.music.music_prompt` feeds music, `sfx[].sound_effect_prompt` feeds sound_effect, and `overlays`/`floating_elements` drive an ffmpeg/hyperframe overlay pass. Long videos (over ~8 min single-shot): run `mode:\"index\"` first, then several full nodes IN PARALLEL each with a `start_s`/`end_s` window (≤480s, snap edges to index scene boundaries), and merge by concatenating `analysis.scenes`; over-length errors include suggested windows. Inject fields into downstream prompts via `{{slot}}`. Pick `~google/gemini-pro-latest` for the densest extraction, `~google/gemini-flash-latest` for cheap/fast passes.',\n inputs: z.object({ video: VideoRef }).loose(),\n params: z\n .object({\n model: z.enum(VIDEO_DECONSTRUCT_MODELS),\n mode: z.enum([\"full\", \"index\"]).optional(),\n language: z.string().min(2).max(8).optional(),\n max_scenes: z.number().int().min(1).max(60).optional(),\n focus: z.string().optional(),\n start_s: z.number().min(0).optional(),\n end_s: z.number().positive().optional(),\n // Real visual shot-cut timestamps (absolute seconds), detected locally with\n // ffmpeg before the deconstruct. The backend SNAPS its LLM scene boundaries\n // onto these and SPLITS any scene that spans one, so a scene's frames never\n // straddle a hard cut. `scaffold-video` populates this; omit for LLM-only cuts.\n shot_cuts: z.array(z.number().min(0)).max(200).optional(),\n // The video model's per-clip ceiling (seconds). A shot longer than this is\n // split into seamless continuation sub-scenes (shared splice frame), so long\n // shots reproduce in full instead of being truncated. `scaffold-video` sets\n // the Seedance ceiling (15); omit to disable length splitting.\n max_clip_s: z.number().positive().max(60).optional(),\n // Transcript provider for the blueprint's dialogue/transcript. Default\n // Groq Whisper; \"deepgram\" routes to Nova-3 so words carry punctuation.\n transcriber: z.enum([\"groq\", \"deepgram\"]).optional(),\n })\n .strict(),\n outputs: z\n .object({\n analysis: JsonRef,\n // Absent in mode:\"index\" (structure only, no Mux frame extraction).\n start_frames: z.array(ImageRef).min(1).optional(),\n end_frames: z.array(ImageRef).min(1).optional(),\n transcript: JsonRef,\n })\n .strict(),\n outputKinds: { analysis: \"json\", start_frames: \"image\", end_frames: \"image\", transcript: \"json\" },\n cost: ({ params }) =>\n (params as { mode?: string }).mode === \"index\"\n ? { credits: 3, seconds_estimate: 60 }\n : { credits: 15, seconds_estimate: 300 },\n});\n","import { estimateNodeCredits, modelIdsAccepted } from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport { AudioRef, VideoRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\n// `fal/veed-lipsync` is the legacy id stored canvases carry; it is accepted as is\n// and the backend resolves it to the registered id it stands for.\nconst VideoLipsyncParams = z\n .object({\n model: z.enum(modelIdsAccepted(\"replicate/sync-lipsync-2\")),\n })\n .strict();\n\nexport const videoLipsyncNode = delegated({\n id: \"video_lipsync\",\n version: \"1.0.0\",\n category: \"video\",\n summary:\n \"Lip-sync a video to an audio track (`replicate/sync-lipsync-2`: Sync Labs lipsync-2 on Replicate; the legacy id `fal/veed-lipsync` still runs). Billed at $0.40 per minute of the longer input. Runs as a background job.\",\n inputs: z\n .object({\n video: VideoRef,\n audio: AudioRef,\n })\n .strict(),\n params: VideoLipsyncParams,\n outputs: z.object({ video: VideoRef }).strict(),\n outputKinds: { video: \"video\" },\n // Priced by the shared contract per minute of output; the quote cannot see the\n // clips' lengths, so it assumes the same one minute the charge falls back to.\n cost: ({ params }) => ({\n credits: estimateNodeCredits({ nodeType: \"video_lipsync\", params }) ?? 1,\n seconds_estimate: 120,\n }),\n});\n","import { mkdtemp, readFile, rm } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { estimateNodeCredits } from \"@baker/canvas-contract\";\nimport { z } from \"zod\";\nimport type { ExecCtx } from \"../../engine/context.ts\";\nimport { defineNode } from \"../../engine/define.ts\";\nimport type { AssetRef } from \"../../schema/refs.ts\";\nimport { AudioRef, VideoRef } from \"../../schema/refs.ts\";\nimport { sha256Hex } from \"../../storage/sha256.ts\";\nimport { uploadAndIngest } from \"../ingest.ts\";\nimport { probeVideo, runFfmpeg } from \"../local/lib/ffmpeg.ts\";\nimport { timeScriptWords } from \"../local/lib/script-word-timing.ts\";\nimport { callBackendExec } from \"./delegate.ts\";\n\nconst VideoTranscribeParams = z\n .object({\n language: z.string().min(2).max(8).optional(),\n // Provider choice is explicit (no env-based silent branching). Default Groq\n // Whisper; \"deepgram\" routes to Deepgram Nova-3, which additionally emits a\n // `rich` JSON output with punctuated words + paragraph/sentence grouping.\n transcriber: z.enum([\"groq\", \"deepgram\"]).optional(),\n keyterms: z\n .array(z.string().min(2).max(60))\n .max(30)\n .optional()\n .describe(\n \"Names the recogniser must not mangle — a product, a person, a phrase the script coins. \" +\n \"The COMPANY'S OWN NAME is always applied server-side, so you never list it: this is for the rest. \" +\n \"Every term is biased into the request AND its spelling enforced on the way out, because a caption \" +\n \"prints a mishearing at full size over the ad (a real cut shipped with the brand name spelled wrong). \" +\n \"Never patch a misspelling inside a caption composition — that fix dies with that one creative.\",\n ),\n script: z\n .string()\n .min(1)\n .optional()\n .describe(\n \"The words the track was asked to say, when there is a script: the transcript's words are then the \" +\n \"script's, spelled as written, at the times the recogniser heard them. A misheard word stops being a \" +\n \"typo on screen, and a word the recogniser added (a filler) is never printed. Aligned locally, never sent.\",\n ),\n })\n .strict();\n\nconst VideoTranscribeInputs = z\n .object({\n // A video (audio auto-extracted locally) OR a bare audio track. The key stays\n // `video` for back-compat; the backend already accepts audio-kind refs on it —\n // the local extraction path has been shipping one for every video input.\n video: z.union([VideoRef, AudioRef]),\n })\n .strict();\n\nconst VideoTranscribeOutputs = z\n .object({\n transcript: z.custom<AssetRef>(),\n // Only emitted by the Deepgram path: full punctuated words + paragraph /\n // sentence grouping with speaker indices. Absent for the default Groq path.\n rich: z.custom<AssetRef>().optional(),\n })\n .strict();\n\ntype Inputs = z.infer<typeof VideoTranscribeInputs>;\ntype Params = z.infer<typeof VideoTranscribeParams>;\ntype Outputs = z.infer<typeof VideoTranscribeOutputs>;\n\nconst AUDIO_EXTRACT_TIMEOUT_MS = 60_000;\n\nexport const videoTranscribeNode = defineNode<Inputs, Params, Outputs>({\n id: \"video_transcribe\",\n version: \"2.4.0\",\n category: \"language\",\n location: \"local\",\n summary:\n 'Transcribe a video or audio track to a word-level JSON transcript. Default `transcriber:\"groq\"` uses ' +\n 'Groq Whisper Large v3 Turbo ($0.04/hr, 10s min); `transcriber:\"deepgram\"` uses Deepgram Nova-3 ' +\n \"($0.0043/min) and additionally emits a `rich` JSON output with punctuated words + paragraph/sentence \" +\n \"grouping (and speaker indices). \" +\n \"Automatically extracts audio locally (mono 16 kHz MP3) before uploading — reduces payload ~100× \" +\n \"and lifts the effective duration limit well beyond Groq's 100 MB file cap. \" +\n \"The `transcript` output is always an array of {text, start, end} entries ready to feed Hyperframes \" +\n \"caption compositions (Deepgram prefers the punctuated word form). Known names are spelled the way the \" +\n \"brand spells them: the company's own name is biased into the request and enforced on the output \" +\n \"automatically, and `keyterms` adds any other name the script depends on.\",\n when_to_use:\n \"Use to generate burned-in captions for a stitched video. Pair with `hyperframe_render` and a captions composition (e.g. `tiktok-captions`) by passing the transcript JSON through `params.variables.transcript`. \" +\n 'Pick `params.language` to filter out non-target speech (e.g. \"es\" for Spanish). ' +\n 'Pick `transcriber:\"deepgram\"` when you want punctuation/paragraphs (read them from the `rich` output) or speaker grouping. ' +\n \"Requires ffmpeg on PATH for audio extraction (falls back to full video upload if unavailable).\",\n inputs: VideoTranscribeInputs,\n params: VideoTranscribeParams,\n outputs: VideoTranscribeOutputs,\n outputKinds: { transcript: \"json\", rich: \"json\" },\n // Priced by the shared contract for the chosen transcriber, assuming a minute of audio.\n cost: ({ params }) => ({\n credits: estimateNodeCredits({ nodeType: \"video_transcribe\", params }) ?? 1,\n seconds_estimate: 30,\n }),\n\n async execute({ inputs, params, ctx }) {\n const audioInput = await tryExtractAudio(inputs, ctx);\n const effectiveInputs = audioInput ?? inputs;\n const { script, ...recogniserParams } = params;\n\n const outputs = (await callBackendExec({\n nodeType: \"video_transcribe\",\n nodeVersion: \"2.4.0\",\n params: recogniserParams,\n inputs: effectiveInputs,\n outputKinds: { transcript: \"json\", rich: \"json\" },\n ctx,\n })) as Outputs;\n if (!script) return outputs;\n return { ...outputs, transcript: await scriptTranscript(outputs.transcript, script, params.language, ctx) };\n },\n});\n\n/**\n * The transcript with the script's words at the recogniser's times (`timeScriptWords`).\n * Read from the recogniser's own output, so what it heard stays on record beside it.\n */\nasync function scriptTranscript(\n heardRef: AssetRef,\n script: string,\n language: string | undefined,\n ctx: ExecCtx,\n): Promise<AssetRef> {\n const local = heardRef.path\n ? heardRef\n : await ctx.assets.ingestRemote({\n kind: \"json\",\n url: String(heardRef.url),\n sha256: heardRef.sha256,\n mime: heardRef.mime,\n });\n const heard = JSON.parse(await readFile(String(local.path), \"utf8\")) as unknown;\n const words = Array.isArray(heard) ? heard.filter(isTimedWord) : [];\n const timed = timeScriptWords(script, words, language);\n ctx.log(`video_transcribe: ${timed.length} script words timed off ${words.length} heard`);\n const bytes = Buffer.from(JSON.stringify(timed));\n const metadata = { ...heardRef.metadata, text_of_record: \"script\", heard_sha256: heardRef.sha256 };\n // Uploaded like the recogniser's own output, so a remote reader can fetch it too; a\n // failed upload still leaves the local file every local renderer reads.\n return uploadAndIngest({ bytes, kind: \"json\", mime: \"application/json\", metadata, ctx }).catch(() =>\n ctx.assets.ingestBytes({ bytes, kind: \"json\", mime: \"application/json\", metadata }),\n );\n}\n\nfunction isTimedWord(value: unknown): value is { text: string; start: number; end: number } {\n const w = value as { text?: unknown; start?: unknown; end?: unknown } | null;\n return Boolean(w) && typeof w?.start === \"number\" && typeof w?.end === \"number\" && w?.text !== undefined;\n}\n\nasync function tryExtractAudio(inputs: Inputs, ctx: ExecCtx): Promise<{ video: AssetRef } | null> {\n const video = inputs.video;\n // A bare audio input is already the small transcribable payload — send it as-is.\n if (!video.path || !video.mime?.startsWith(\"video/\")) return null;\n\n let tmpDir: string | undefined;\n try {\n const probe = await probeVideo(video.path);\n if (!probe.has_audio) {\n ctx.log(\"video_transcribe: no audio track detected, sending full video\");\n return null;\n }\n\n tmpDir = await mkdtemp(path.join(tmpdir(), \"vtx-\"));\n const audioPath = path.join(tmpDir, \"audio.mp3\");\n\n ctx.log(\"video_transcribe: extracting audio (mono 16kHz mp3)\");\n await runFfmpeg(\n [\"-i\", video.path, \"-vn\", \"-ac\", \"1\", \"-ar\", \"16000\", \"-b:a\", \"64k\", \"-f\", \"mp3\", \"-y\", audioPath],\n { timeout_ms: AUDIO_EXTRACT_TIMEOUT_MS },\n );\n\n const bytes = await readFile(audioPath);\n if (bytes.byteLength === 0) {\n ctx.log(\"video_transcribe: extracted audio is empty, sending full video\");\n return null;\n }\n\n const sha = sha256Hex(bytes);\n const mime = \"audio/mpeg\";\n const { putUrl, publicUrl } = await ctx.client.presignAssetUpload(sha, mime, ctx.signal);\n\n const putRes = await fetch(putUrl, {\n method: \"PUT\",\n body: new Uint8Array(bytes),\n headers: { \"Content-Type\": mime },\n signal: ctx.signal,\n });\n if (!putRes.ok) {\n ctx.log(`video_transcribe: audio upload failed (${putRes.status}), sending full video`);\n return null;\n }\n\n const localRef = await ctx.assets.ingestBytes({\n bytes,\n kind: \"audio\",\n mime,\n metadata: { extracted_from: video.sha256 },\n });\n\n const sizeMb = (bytes.byteLength / (1024 * 1024)).toFixed(1);\n ctx.log(`video_transcribe: audio extracted (${sizeMb} MB), uploading`);\n\n return {\n video: { ...localRef, url: publicUrl } as AssetRef,\n };\n } catch (e) {\n ctx.log(`video_transcribe: audio extraction failed, sending full video: ${(e as Error).message}`);\n return null;\n } finally {\n if (tmpDir) {\n await rm(tmpDir, { recursive: true, force: true }).catch((_e) => undefined);\n }\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\ntype VideoProbe = {\n duration_seconds: number;\n codec_name: string;\n profile: string | null;\n level: number | null;\n width: number;\n height: number;\n pix_fmt: string | null;\n fps_num: number;\n fps_den: number;\n has_audio: boolean;\n audio_codec: string | null;\n sample_rate: number | null;\n channels: number | null;\n};\n\ntype FfprobeStream = {\n codec_type?: string;\n codec_name?: string;\n profile?: string;\n level?: number;\n width?: number;\n height?: number;\n pix_fmt?: string;\n r_frame_rate?: string;\n avg_frame_rate?: string;\n sample_rate?: string;\n channels?: number;\n};\n\ntype FfprobeFormat = {\n duration?: string;\n};\n\ntype FfprobeJson = {\n streams?: FfprobeStream[];\n format?: FfprobeFormat;\n};\n\nexport async function probeVideo(filePath: string): Promise<VideoProbe> {\n const { stdout } = await execFileAsync(\n \"ffprobe\",\n [\"-v\", \"error\", \"-show_streams\", \"-show_format\", \"-of\", \"json\", filePath],\n { encoding: \"utf-8\", maxBuffer: 8 * 1024 * 1024 },\n );\n return parseProbeJson(stdout, filePath);\n}\n\nfunction parseProbeJson(stdout: string, filePath: string): VideoProbe {\n let parsed: FfprobeJson;\n try {\n parsed = JSON.parse(stdout) as FfprobeJson;\n } catch {\n throw new Error(`ffprobe: unparseable JSON output for ${filePath}`);\n }\n\n const streams = parsed.streams ?? [];\n const video = streams.find((s) => s.codec_type === \"video\");\n if (!video) throw new Error(`ffprobe: no video stream found in ${filePath}`);\n if (typeof video.width !== \"number\" || typeof video.height !== \"number\") {\n throw new Error(`ffprobe: missing video dimensions for ${filePath}`);\n }\n\n const duration = Number.parseFloat(parsed.format?.duration ?? \"\");\n if (!Number.isFinite(duration) || duration <= 0) {\n throw new Error(`ffprobe: invalid duration for ${filePath}: ${parsed.format?.duration}`);\n }\n\n const audio = streams.find((s) => s.codec_type === \"audio\");\n return buildVideoProbe(video, video.width, video.height, audio, duration);\n}\n\nfunction buildVideoProbe(\n video: FfprobeStream,\n width: number,\n height: number,\n audio: FfprobeStream | undefined,\n duration: number,\n): VideoProbe {\n const fps = parseFrameRate(video.r_frame_rate ?? video.avg_frame_rate ?? \"30/1\");\n return {\n duration_seconds: duration,\n codec_name: video.codec_name ?? \"unknown\",\n profile: video.profile ?? null,\n level: typeof video.level === \"number\" ? video.level : null,\n width,\n height,\n pix_fmt: video.pix_fmt ?? null,\n fps_num: fps.num,\n fps_den: fps.den,\n has_audio: audio !== undefined,\n audio_codec: audio?.codec_name ?? null,\n sample_rate: audio?.sample_rate ? Number.parseInt(audio.sample_rate, 10) : null,\n channels: typeof audio?.channels === \"number\" ? audio.channels : null,\n };\n}\n\nfunction parseFrameRate(rate: string): { num: number; den: number } {\n const match = rate.match(/^(\\d+)\\/(\\d+)$/);\n if (match) {\n const num = Number.parseInt(match[1] ?? \"0\", 10);\n const den = Number.parseInt(match[2] ?? \"0\", 10);\n if (den > 0) return { num, den };\n }\n const flat = Number.parseFloat(rate);\n if (Number.isFinite(flat) && flat > 0) return { num: Math.round(flat * 1000), den: 1000 };\n return { num: 30, den: 1 };\n}\n\ntype RunFfmpegOpts = {\n timeout_ms: number;\n log?: (msg: string) => void;\n};\n\nexport async function runFfmpeg(args: readonly string[], opts: RunFfmpegOpts): Promise<void> {\n try {\n await execFileAsync(\"ffmpeg\", args, {\n timeout: opts.timeout_ms,\n maxBuffer: 64 * 1024 * 1024,\n });\n } catch (e) {\n const stderr = (e as { stderr?: string }).stderr ?? \"\";\n const stdout = (e as { stdout?: string }).stdout ?? \"\";\n const detail = stderr || stdout || (e as Error).message;\n throw new Error(`ffmpeg failed:\\n${detail.slice(-4000)}`);\n }\n}\n","/**\n * Captions that say the script, timed by the voice that read it.\n *\n * A spoken ad's captions came straight from transcribing its rendered voice track, so a\n * misheard word (\"llueve\" for \"nueve\", a brand name bent into a common word) became a typo\n * burned into the ad at full size. The script is what the voice was asked to say and what\n * the viewer should read; the transcript only knows WHEN each word was said.\n *\n * So the script is the text of record and the transcript is the clock: the two word\n * sequences are aligned (a global alignment, tolerant of misrecognitions, case, accents,\n * punctuation and numbers spoken as words), each script word takes the timestamps of the\n * transcript words it lines up with, and a script word nothing lines up with (the\n * recogniser dropped it) is placed between its neighbours. Words the recogniser added\n * (a filler, a stutter) are never printed.\n *\n * Pure: script and transcript in, timed words out.\n */\nimport { spellNumber } from \"../../../lib/spell-number.ts\";\nimport type { CaptionWord } from \"./caption-groups.ts\";\n\n/** How long a word is taken to last when there is no neighbour on one side to bound it. */\nconst UNBOUNDED_WORD_S = 0.3;\n\n/** Alignment scores: an exact word, a near one, a different one in the same place, a skip. */\nconst EXACT = 3;\nconst NEAR = 2;\nconst SUBSTITUTE = -1;\nconst SKIP = -2;\n/** How alike two words must be to count as the same word heard slightly wrong. */\nconst NEAR_SIMILARITY = 0.7;\n\n/** One comparable token and the word it came from. */\ntype Token = { key: string; word: number };\n\n/** Lower-case, accents and punctuation stripped: \"Días.\" and \"dias\" compare equal. */\nfunction normalize(word: string): string {\n return word\n .normalize(\"NFD\")\n .replace(/\\p{M}/gu, \"\")\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}]/gu, \"\");\n}\n\n/**\n * The tokens a word is compared by. A plain integer is compared as the words it is spoken\n * as, so \"9\" in the script lines up with \"nueve\" in the transcript, and the other way round.\n */\nfunction tokensOf(word: string, index: number, language: string | undefined): Token[] {\n const key = normalize(word);\n if (!key) return [];\n if (language && /^\\d{1,9}$/.test(key)) {\n const spoken = spellNumber(language, Number.parseInt(key, 10));\n if (spoken !== key) {\n const parts = spoken\n .split(/[\\s-]+/)\n .map(normalize)\n .filter(Boolean);\n if (parts.length > 0) return parts.map((part) => ({ key: part, word: index }));\n }\n }\n return [{ key, word: index }];\n}\n\n/** Levenshtein similarity in [0, 1]. */\nfunction similarity(a: string, b: string): number {\n if (a === b) return 1;\n const longest = Math.max(a.length, b.length);\n if (longest === 0) return 1;\n let prev = Array.from({ length: b.length + 1 }, (_, j) => j);\n for (let i = 1; i <= a.length; i++) {\n const row = [i];\n for (let j = 1; j <= b.length; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n row[j] = Math.min((prev[j] ?? 0) + 1, (row[j - 1] ?? 0) + 1, (prev[j - 1] ?? 0) + cost);\n }\n prev = row;\n }\n return 1 - (prev[b.length] ?? longest) / longest;\n}\n\nfunction pairScore(a: string, b: string): number {\n if (a === b) return EXACT;\n return similarity(a, b) >= NEAR_SIMILARITY ? NEAR : SUBSTITUTE;\n}\n\ntype Grid = number[][];\n\nconst at = (grid: Grid, i: number, j: number): number => grid[i]?.[j] ?? 0;\n\n/** The diagonal step's score: script token `i` lined up with transcript token `j` (1-based). */\nfunction diagonal(grid: Grid, script: Token[], transcript: Token[], i: number, j: number): number {\n return at(grid, i - 1, j - 1) + pairScore(script[i - 1]?.key ?? \"\", transcript[j - 1]?.key ?? \"\");\n}\n\n/** Needleman-Wunsch's score grid over the two token sequences. */\nfunction scoreGrid(script: Token[], transcript: Token[]): Grid {\n const grid: Grid = Array.from({ length: script.length + 1 }, (_, i) =>\n Array.from({ length: transcript.length + 1 }, (_, j) => (i === 0 ? j * SKIP : i * SKIP)),\n );\n for (let i = 1; i <= script.length; i++) {\n const row = grid[i] as number[];\n for (let j = 1; j <= transcript.length; j++) {\n row[j] = Math.max(diagonal(grid, script, transcript, i, j), at(grid, i - 1, j) + SKIP, at(grid, i, j - 1) + SKIP);\n }\n }\n return grid;\n}\n\n/**\n * For each script token, the transcript token it lines up with (a match or a substitution),\n * or -1 when it is skipped.\n */\nfunction align(script: Token[], transcript: Token[]): number[] {\n const grid = scoreGrid(script, transcript);\n const pairs = new Array<number>(script.length).fill(-1);\n let i = script.length;\n let j = transcript.length;\n while (i > 0 && j > 0) {\n const here = at(grid, i, j);\n if (here === diagonal(grid, script, transcript, i, j)) {\n pairs[i - 1] = j - 1;\n i--;\n j--;\n } else if (here === at(grid, i - 1, j) + SKIP) {\n i--;\n } else {\n j--;\n }\n }\n return pairs;\n}\n\ntype Span = { start: number; end: number };\n\nconst round = (s: number): number => Math.round(s * 1000) / 1000;\n\n/** Each script word's span: from the first to the last transcript word its tokens lined up with. */\nfunction pairedSpans(\n wordCount: number,\n scriptTokens: Token[],\n heardTokens: Token[],\n pairs: number[],\n transcript: readonly CaptionWord[],\n): Array<Span | null> {\n const spans: Array<Span | null> = new Array(wordCount).fill(null);\n pairs.forEach((heardIndex, t) => {\n const token = scriptTokens[t];\n const said = heardIndex >= 0 ? transcript[heardTokens[heardIndex]?.word ?? -1] : undefined;\n if (!token || !said) return;\n const current = spans[token.word];\n spans[token.word] = current\n ? { start: Math.min(current.start, said.start), end: Math.max(current.end, said.end) }\n : { start: said.start, end: said.end };\n });\n return spans;\n}\n\n/** Spread the run of untimed words `[first, end)` across the gap their neighbours leave. */\nfunction fillRun(spans: Array<Span | null>, first: number, end: number): void {\n const before = first > 0 ? spans[first - 1] : null;\n const after = end < spans.length ? spans[end] : null;\n const count = end - first;\n const from = before ? before.end : Math.max(0, (after?.start ?? 0) - count * UNBOUNDED_WORD_S);\n const to = after ? Math.max(after.start, from) : from + count * UNBOUNDED_WORD_S;\n const each = (to - from) / count;\n for (let w = first; w < end; w++) spans[w] = { start: from + (w - first) * each, end: from + (w - first + 1) * each };\n}\n\n/**\n * A word the recogniser dropped sits between the neighbours it was said between, a run of\n * them sharing that gap evenly. At either end it takes a nominal length past its neighbour.\n */\nfunction fillDropped(spans: Array<Span | null>): Span[] {\n const filled = [...spans];\n let i = 0;\n while (i < filled.length) {\n let end = i;\n while (end < filled.length && !filled[end]) end++;\n if (end > i) fillRun(filled, i, end);\n i = end + 1;\n }\n return filled.map((span) => span ?? { start: 0, end: 0 });\n}\n\n/**\n * The script's words, each timed off the transcript. `language` (ISO 639-1) lets a numeral\n * on either side line up with the same number spoken as words. An empty transcript (nothing\n * was heard) gives no captions, as it did before.\n */\nexport function timeScriptWords(script: string, transcript: readonly CaptionWord[], language?: string): CaptionWord[] {\n const words = script.split(/\\s+/).filter(Boolean);\n if (words.length === 0 || transcript.length === 0) return [];\n const scriptTokens = words.flatMap((word, i) => tokensOf(word, i, language));\n const heardTokens = transcript.flatMap((w, i) => tokensOf(String(w.text ?? \"\"), i, language));\n const pairs = align(scriptTokens, heardTokens);\n const spans = fillDropped(pairedSpans(words.length, scriptTokens, heardTokens, pairs, transcript));\n return words.map((text, i) => ({ text, start: round(spans[i]?.start ?? 0), end: round(spans[i]?.end ?? 0) }));\n}\n","import { z } from \"zod\";\nimport { JsonRef, TextRef } from \"../../schema/refs.ts\";\nimport { delegated } from \"./delegate.ts\";\n\nexport const voiceSelectNode = delegated({\n id: \"voice_select\",\n // 1.1.0: a pinned voice used to come back as an inline `{ kind, text }` with no sha256\n // and no mime, which every consumer taking the id as an INPUT rejected —\n // `audio_voice_convert` died on `voice_ref.sha256: expected string, received undefined`.\n // The backend now uploads it as a real asset like the ranked branch, and the version has\n // to move with it: the cache key is built from this string, so entries written under\n // 1.0.0 kept replaying the broken shape long after the fix was deployed. A node whose\n // OUTPUT shape changes has to bump, not only one whose behaviour does.\n // 1.2.0: `language` is a hard constraint — a language no voice on the account speaks\n // fails the node instead of casting a voice of another language, and a gender nobody\n // in the language has is relaxed with a printed warning. Bumped so a 1.1.0 cache entry\n // holding a wrong-language cast stops replaying.\n version: \"1.2.0\",\n category: \"audio\",\n summary:\n 'Cast an ElevenLabs voice from a natural-language description (e.g. \"warm, authoritative female narrator, American accent\"). Lists the account\\'s voices and ranks them against the brief, emitting the best `voice_id` as a bare-string text asset plus a ranked `candidates` JSON.',\n when_to_use:\n 'Use to turn a voice description (e.g. from a `video_deconstruct` blueprint\\'s `voice_description`) into a usable ElevenLabs voice id, then feed it into a `tts` node by wiring `inputs.voice_ref: $ref:<this>.voice_id` and setting `params.voice: \"{{voice_ref}}\"` — the engine splices the id in at run time. Review `candidates` (json) to pick a different voice. Optional `gender`/`age`/`accent`/`language` hints sharpen the ranking. `language` is strict: when no voice on the account speaks it the node fails before anything is voiced (add a voice in that language, or pass its `voice_id`). A `gender` nobody in that language has is dropped and `baker canvas run` prints a `[warn]` naming the voice cast instead.',\n inputs: z.object({}).loose(),\n params: z\n .object({\n description: z.string().min(1),\n gender: z.string().optional(),\n age: z.string().optional(),\n accent: z.string().optional(),\n language: z.string().optional(),\n /**\n * A voice already chosen — an Avatar's pinned one. Given, nothing is cast: the\n * ranking is skipped and this id is emitted as-is.\n */\n voice_id: z.string().min(1).max(120).optional(),\n limit: z.number().int().min(1).max(20).optional(),\n })\n .strict(),\n outputs: z.object({ voice_id: TextRef, candidates: JsonRef }).strict(),\n outputKinds: { voice_id: \"text\", candidates: \"json\" },\n cost: () => ({ credits: 0, seconds_estimate: 5 }),\n});\n","import { z } from \"zod\";\nimport { priceNode } from \"../engine/credits.ts\";\nimport type { AnyNodeDefinition } from \"../engine/define.ts\";\nimport type { NodeRegistry } from \"../engine/registry.ts\";\n\ntype CatalogEntry = {\n id: string;\n version: string;\n category: string;\n summary: string;\n when_to_use?: string;\n location: \"local\" | \"remote\";\n inputs: unknown;\n params: unknown;\n outputs: unknown;\n cost_estimate_credits?: number;\n runtime_estimate_seconds?: number;\n};\n\nexport type Catalog = {\n schema: \"baker-canvas-catalog/2\";\n generated_at: string;\n categories: Record<string, string[]>;\n entries: CatalogEntry[];\n};\n\nexport function generateCatalog(registry: NodeRegistry, opts: { generatedAt?: string } = {}): Catalog {\n const entries: CatalogEntry[] = registry\n .all()\n .map((def) => {\n const cost = catalogCost(def);\n return {\n id: def.id,\n version: def.version,\n category: def.category,\n summary: def.summary,\n when_to_use: def.when_to_use,\n location: def.location,\n inputs: z.toJSONSchema(def.inputs, { unrepresentable: \"any\" }),\n params: z.toJSONSchema(def.params, { unrepresentable: \"any\" }),\n outputs: z.toJSONSchema(def.outputs, { unrepresentable: \"any\" }),\n cost_estimate_credits: cost?.credits,\n runtime_estimate_seconds: cost?.seconds_estimate,\n };\n })\n .sort((a, b) => a.id.localeCompare(b.id));\n\n return {\n schema: \"baker-canvas-catalog/2\",\n generated_at: opts.generatedAt ?? new Date().toISOString(),\n categories: groupIds(entries),\n entries,\n };\n}\n\n/** How much of the catalog to print: an index by default, full schemas on request. */\nexport type CatalogViewOptions = {\n node?: string;\n category?: string;\n full?: boolean;\n};\n\ntype CatalogIndex = {\n ok: true;\n schema: Catalog[\"schema\"];\n categories: Record<string, string[]>;\n nodes: Record<string, string>;\n hints: string[];\n};\n\ntype CatalogSchemas = {\n ok: true;\n schema: Catalog[\"schema\"];\n categories: Record<string, string[]>;\n entries: CatalogEntry[];\n};\n\ntype CatalogRefusal = {\n ok: false;\n error: { code: \"NOT_FOUND\" | \"VALIDATION_ERROR\"; message: string; fix: string };\n};\n\nexport type CatalogView = CatalogIndex | CatalogSchemas | CatalogRefusal;\n\nconst INDEX_SUMMARY_MAX = 160;\nconst sentences = new Intl.Segmenter(\"en\", { granularity: \"sentence\" });\n\n/**\n * One line that says what a node is for: its summary's first sentence, cut at a\n * word when that sentence runs long. The index exists to pick a node, and the\n * rest of the summary travels with the node's full schema.\n */\nfunction oneLine(summary: string): string {\n const first = sentences.segment(summary)[Symbol.iterator]().next().value?.segment.trim() ?? summary;\n if (first.length <= INDEX_SUMMARY_MAX) return first;\n const cut = first.slice(0, INDEX_SUMMARY_MAX);\n const lastSpace = cut.lastIndexOf(\" \");\n return `${(lastSpace > 0 ? cut.slice(0, lastSpace) : cut).replace(/[\\s,;:—-]+$/u, \"\")}…`;\n}\n\nfunction listIds(value: string | undefined): string[] {\n return (value ?? \"\")\n .split(\",\")\n .map((id) => id.trim())\n .filter((id) => id.length > 0);\n}\n\n/**\n * The part of the catalog a caller asked for.\n *\n * Every node's full JSON Schema is ~160 KB and grows with the registry, while a\n * caller almost always wants one node. So the default is an index — each node's\n * id and one line, grouped by category — and the schemas come by name\n * (`node`), by category with `full`, or all at once with `full` alone.\n */\nexport function catalogView(catalog: Catalog, opts: CatalogViewOptions): CatalogView {\n const knownIds = catalog.entries.map((e) => e.id);\n const knownCategories = Object.keys(catalog.categories);\n\n if (opts.category !== undefined && !knownCategories.includes(opts.category)) {\n return {\n ok: false,\n error: {\n code: \"NOT_FOUND\",\n message: `No node category \"${opts.category}\".`,\n fix: `Pass one of: ${knownCategories.join(\", \")}.`,\n },\n };\n }\n\n const requestedIds = listIds(opts.node);\n if (opts.node !== undefined && requestedIds.length === 0) {\n return {\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: \"--node needs a node id.\",\n fix: \"Run `baker canvas catalog` for the ids, then pass one (or several, comma-separated).\",\n },\n };\n }\n const unknownIds = requestedIds.filter((id) => !knownIds.includes(id));\n if (unknownIds.length > 0) {\n return {\n ok: false,\n error: {\n code: \"NOT_FOUND\",\n message: `No node named ${unknownIds.map((id) => `\"${id}\"`).join(\", \")}.`,\n fix: `Pass one of: ${knownIds.join(\", \")}.`,\n },\n };\n }\n\n const inCategory = (e: CatalogEntry) => opts.category === undefined || e.category === opts.category;\n const categories =\n opts.category === undefined ? catalog.categories : { [opts.category]: catalog.categories[opts.category] ?? [] };\n\n if (requestedIds.length > 0) {\n const entries = catalog.entries.filter((e) => requestedIds.includes(e.id));\n return { ok: true, schema: catalog.schema, categories: groupIds(entries), entries };\n }\n\n if (opts.full) {\n return { ok: true, schema: catalog.schema, categories, entries: catalog.entries.filter(inCategory) };\n }\n\n const nodes: Record<string, string> = {};\n for (const e of catalog.entries.filter(inCategory)) nodes[e.id] = oneLine(e.summary);\n return {\n ok: true,\n schema: catalog.schema,\n categories,\n nodes,\n hints: [\n \"One node's params, inputs, outputs, models and when to use it: baker canvas catalog --node <id> (comma-separate several).\",\n \"Every schema in a category: --category <name> --full. Every node: --full (large; prefer --node).\",\n ],\n };\n}\n\nfunction groupIds(entries: CatalogEntry[]): Record<string, string[]> {\n const categories: Record<string, string[]> = {};\n for (const e of entries) {\n let bucket = categories[e.category];\n if (!bucket) {\n bucket = [];\n categories[e.category] = bucket;\n }\n bucket.push(e.id);\n }\n return categories;\n}\n\n/**\n * A node type's price with no canvas to read: its params' defaults when they parse\n * from nothing, else no params at all. Only a finite number is advertised.\n */\nfunction catalogCost(def: AnyNodeDefinition): ReturnType<typeof priceNode> {\n const defaults = def.params.safeParse({});\n return priceNode(def, defaults.success ? defaults.data : {});\n}\n","import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nexport type CacheEntry = {\n cacheKey: string;\n nodeType: string;\n nodeVersion: string;\n outputs: Record<string, unknown>;\n refs: string[]; // sha256s referenced (for GC later)\n createdAt: number;\n};\n\nexport interface CacheStore {\n rootDir: string;\n get(cacheKey: string): Promise<CacheEntry | null>;\n put(entry: CacheEntry): Promise<void>;\n}\n\nexport class LocalCacheStore implements CacheStore {\n rootDir: string;\n constructor(rootDir: string) {\n this.rootDir = rootDir;\n }\n\n private filePath(cacheKey: string): string {\n return path.join(this.rootDir, `${cacheKey}.json`);\n }\n\n async get(cacheKey: string): Promise<CacheEntry | null> {\n try {\n const buf = await readFile(this.filePath(cacheKey), \"utf8\");\n return JSON.parse(buf) as CacheEntry;\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw e;\n }\n }\n\n async put(entry: CacheEntry): Promise<void> {\n const dest = this.filePath(entry.cacheKey);\n await mkdir(path.dirname(dest), { recursive: true });\n const tmp = `${dest}.tmp-${process.pid}-${randomUUID()}`;\n await writeFile(tmp, JSON.stringify(entry, null, 0));\n await rename(tmp, dest);\n }\n}\n"],"mappings":"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","names":["path","estimateNodeCredits","copyFile","path","at","z","FFMPEG_BIN","z","z","z","z","FFMPEG_BIN","z","mkdtemp","rm","writeFile","tmpdir","path","z","copyFile","readFile","path","z","mkdtemp","path","tmpdir","writeFile","rm","execFile","mkdtemp","readFile","rm","stat","writeFile","tmpdir","path","promisify","z","readFile","stat","path","path","stat","readFile","readFile","path","z","copyFile","createRequire","path","require_","mkdtemp","readFile","rm","stat","writeFile","tmpdir","path","execFile","readFile","path","promisify","promisify","execFile","readFile","path","writeFile","path","readFile","path","mkdtemp","tmpdir","rm","stat","writeFile","execFileAsync","promisify","execFile","z","mkdtemp","path","tmpdir","stageInputs","substitutionValues","readFile","rm","stat","writeFile","execFile","mkdtemp","readFile","rm","writeFile","createRequire","tmpdir","path","promisify","z","promisify","execFile","require_","createRequire","z","NODE_OWNED_PARAM_KEYS","DEVICE_SCALE_FACTOR","validateAndParseDynamicParams","mkdtemp","path","tmpdir","stageInputs","substitutionValues","buildSubstitutionValues","substituteCompositionFiles","rm","coerceImageParam","readFile","writeFile","execFile","promisify","z","execFileAsync","promisify","execFile","OutputDecl","z","sharp","z","z","z","z","sharp","z","z","at","sharp","unionOf","area","across","at","sharp","past","area","across","at","sharp","shrunk","across","at","neighbours","inBoxes","misfit","unionOf","area","past","inSpans","GAIN_MAX","FLAT","flatOf","flood","share","r","overlaps","into","z","at","across","placed","out","shrink","round","holds","z","across","sharp","placed","take","sharp","z","Usage","z","Rect","Copy","placed","at","sharp","LOGO_AVOIDS","PLAIN_GROUND_SPREAD","createRequire","z","sharp","at","share","x","require_","createRequire","z","z","sharp","FEATHER","MOVED","ratioOf","sharp","shrunk","placed","paint","Usage","z","Unit","Copy","placed","at","offset","merged","paint","sharp","z","ratioOf","at","paint","sharp","z","overlap","z","sharp","unique","Usage","z","Copy","Rect","GREY","MISALIGNED","at","sharp","image","facts","readFile","z","z","Usage","readFile","image","z","Usage","z","Fit","Copy","z","z","z","FFMPEG_BIN","z","normalize","offset","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","z","mkdtemp","readFile","rm","tmpdir","path","z","execFile","promisify","execFileAsync","_","z","readFile","mkdtemp","path","tmpdir","rm","z","z","z","z","mkdir","readFile","writeFile","path","BackendClient","Engine","LocalAssetStore","LocalCacheStore","validateCanvasDeep","generateCatalog","ValidationError","path"]}