@koda-sl/baker-cli 0.567.0 → 0.569.0-dev.1b455b3fe

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 (1188) hide show
  1. package/README.md +10 -9
  2. package/dist/account-JREYXYNE.js +82 -0
  3. package/dist/account-OUKPRB7C.js +139 -0
  4. package/dist/account-WN5MJ5QN.js +82 -0
  5. package/dist/account-assets-IWJWYNQ3.js +290 -0
  6. package/dist/account-level-SHZBOMVV.js +612 -0
  7. package/dist/account-level-SHZBOMVV.js.map +1 -0
  8. package/dist/account-reads-GF3T25HX.js +220 -0
  9. package/dist/account-reads-GF3T25HX.js.map +1 -0
  10. package/dist/account-users-7NKBUVYA.js +65 -0
  11. package/dist/account-users-7NKBUVYA.js.map +1 -0
  12. package/dist/account-writes-IUIXIVRC.js +68 -0
  13. package/dist/accounts-4YRDRLHX.js +80 -0
  14. package/dist/accounts-HEGADQ6E.js +119 -0
  15. package/dist/accounts-OSVXKNSI.js +76 -0
  16. package/dist/accounts-SJOO4MQX.js +115 -0
  17. package/dist/accounts-V7EOUTNL.js +713 -0
  18. package/dist/actions-5LYJ3U6G.js +55 -0
  19. package/dist/active-entities-4KQQSMRZ.js +103 -0
  20. package/dist/activecampaign-CZHLHGT4.js +938 -0
  21. package/dist/activities-FRA33VZZ.js +75 -0
  22. package/dist/ad-group-writes-YQXBUA3Q.js +172 -0
  23. package/dist/ad-groups-NJR4ILEN.js +70 -0
  24. package/dist/ad-writes-TZV64CC2.js +176 -0
  25. package/dist/add-MZUSKY2L.js +305 -0
  26. package/dist/add-NAUSQKRS.js +107 -0
  27. package/dist/ads-A2FXTQES.js +120 -0
  28. package/dist/ads-PYTK3LJE.js +48 -0
  29. package/dist/ads-Q7DD5VXU.js +79 -0
  30. package/dist/adsets-ZHEVFOK4.js +182 -0
  31. package/dist/advertisers-HSTND4HE.js +123 -0
  32. package/dist/analytics-63Q3FJN4.js +447 -0
  33. package/dist/analytics-GLJODEIM.js +2437 -0
  34. package/dist/animate-EI6AYBDI.js +480 -0
  35. package/dist/asset-writes-MS45UKJ3.js +51 -0
  36. package/dist/assign-7HT3XSSN.js +80 -0
  37. package/dist/audience-size-DG7544D2.js +76 -0
  38. package/dist/audience-writes-IL64HQBS.js +328 -0
  39. package/dist/audience-writes-IL64HQBS.js.map +1 -0
  40. package/dist/audiences-2IVVS3SJ.js +280 -0
  41. package/dist/audiences-RN745R53.js +85 -0
  42. package/dist/audiences-Z2TQT35L.js +106 -0
  43. package/dist/audit-BIHMDO5K.js +88 -0
  44. package/dist/audit-ZYST7KCO.js +154 -0
  45. package/dist/autocomplete-5BKEMOQ3.js +114 -0
  46. package/dist/avatars-FQOCDWLW.js +38 -0
  47. package/dist/bid-pricing-JEW7T2VR.js +103 -0
  48. package/dist/brand-FR6BKWXN.js +22 -0
  49. package/dist/brief-32IXDJ4J.js +543 -0
  50. package/dist/businesses-HECSW3EL.js +54 -0
  51. package/dist/campaign-groups-LYPVIZT5.js +99 -0
  52. package/dist/campaign-writes-D5MM5LUH.js +168 -0
  53. package/dist/campaign-writes-S7A6W5V3.js +176 -0
  54. package/dist/campaigns-CMDF3P7Y.js +111 -0
  55. package/dist/campaigns-LIICP5JU.js +113 -0
  56. package/dist/campaigns-N72TOUQX.js +130 -0
  57. package/dist/campaigns-ZWJKBF3L.js +78 -0
  58. package/dist/canvas-3SNC3UUV.js +46 -0
  59. package/dist/capabilities-GL7P3SWY.js +147 -0
  60. package/dist/cards-RYQN5JLR.js +85 -0
  61. package/dist/catalog-PWAWDK42.js +66 -0
  62. package/dist/catalogs-2R5RV4L7.js +783 -0
  63. package/dist/catalogs-2R5RV4L7.js.map +1 -0
  64. package/dist/catalogs-SLPYHA7D.js +130 -0
  65. package/dist/changes-WOD4EOSN.js +167 -0
  66. package/dist/chatgpt-3GX4I6NH.js +47 -0
  67. package/dist/chats-K2WUFVCG.js +584 -0
  68. package/dist/chats-K2WUFVCG.js.map +1 -0
  69. package/dist/check-ZSQ4EIFB.js +154 -0
  70. package/dist/check-ZSQ4EIFB.js.map +1 -0
  71. package/dist/chunk-34ARMQNL.js +197 -0
  72. package/dist/chunk-34MZGC2Y.js +207 -0
  73. package/dist/chunk-3JOGDGGP.js +24026 -0
  74. package/dist/chunk-3JOGDGGP.js.map +1 -0
  75. package/dist/chunk-46DHUWMV.js +642 -0
  76. package/dist/chunk-46DHUWMV.js.map +1 -0
  77. package/dist/chunk-4KBTW5NE.js +494 -0
  78. package/dist/chunk-4PAGS7QH.js +76 -0
  79. package/dist/chunk-53KV66ZZ.js +163 -0
  80. package/dist/chunk-55AX6DOP.js +86 -0
  81. package/dist/chunk-55AX6DOP.js.map +1 -0
  82. package/dist/chunk-5C4RRCKM.js +69 -0
  83. package/dist/chunk-5I6XOSNI.js +709 -0
  84. package/dist/chunk-5OE4Z7TP.js +287 -0
  85. package/dist/chunk-6OIKNJ7G.js +26 -0
  86. package/dist/chunk-6S4B67KP.js +962 -0
  87. package/dist/chunk-77LXZAX2.js +930 -0
  88. package/dist/chunk-7TVVYP7K.js +217 -0
  89. package/dist/chunk-7URHRPC7.js +3510 -0
  90. package/dist/chunk-7YMQEAGA.js +399 -0
  91. package/dist/chunk-A4O3JL6D.js +26 -0
  92. package/dist/chunk-ANRTDNPQ.js +115 -0
  93. package/dist/chunk-AQNTVM6S.js +1518 -0
  94. package/dist/chunk-BPDIY5CF.js +274 -0
  95. package/dist/chunk-CKHF7UXS.js +831 -0
  96. package/dist/chunk-CUTTTFAU.js +783 -0
  97. package/dist/chunk-D32EWSMB.js +150 -0
  98. package/dist/chunk-D55MN5IH.js +547 -0
  99. package/dist/chunk-DRQI2CJJ.js +138 -0
  100. package/dist/chunk-ESSA3AWR.js +133 -0
  101. package/dist/chunk-ESSA3AWR.js.map +1 -0
  102. package/dist/chunk-ETI6DGR2.js +312 -0
  103. package/dist/chunk-F3CZFUXZ.js +3187 -0
  104. package/dist/chunk-F3CZFUXZ.js.map +1 -0
  105. package/dist/chunk-FFTD7XDA.js +91 -0
  106. package/dist/chunk-FTKUHGTC.js +224 -0
  107. package/dist/chunk-GFYGVIT3.js +392 -0
  108. package/dist/chunk-GGXPO4NQ.js +225 -0
  109. package/dist/chunk-H56UJRLV.js +170 -0
  110. package/dist/chunk-HDMD6LXS.js +142 -0
  111. package/dist/chunk-HFZZKYUX.js +1320 -0
  112. package/dist/chunk-IAYJKH4R.js +5471 -0
  113. package/dist/chunk-IEPCI2EB.js +479 -0
  114. package/dist/chunk-IKADYUXK.js +344 -0
  115. package/dist/chunk-IMS53EQU.js +4277 -0
  116. package/dist/chunk-IMS53EQU.js.map +1 -0
  117. package/dist/chunk-IUX2LBW4.js +86 -0
  118. package/dist/chunk-IUX2LBW4.js.map +1 -0
  119. package/dist/chunk-J32CYEIH.js +74 -0
  120. package/dist/chunk-J5I3GYSJ.js +156 -0
  121. package/dist/chunk-JCVXKHVB.js +285 -0
  122. package/dist/chunk-JESSFI7R.js +468 -0
  123. package/dist/chunk-K4QPBXV7.js +61 -0
  124. package/dist/chunk-KJ3J2DYM.js +1919 -0
  125. package/dist/chunk-L43B2YGZ.js +2209 -0
  126. package/dist/chunk-L7UD57TV.js +219 -0
  127. package/dist/chunk-LJYXGUQ3.js +430 -0
  128. package/dist/chunk-LNYM4PQS.js +203 -0
  129. package/dist/chunk-LZR7LSYO.js +180 -0
  130. package/dist/chunk-LZR7LSYO.js.map +1 -0
  131. package/dist/chunk-MIXUMGJE.js +66 -0
  132. package/dist/chunk-MK4HCMEA.js +325 -0
  133. package/dist/chunk-MK4HCMEA.js.map +1 -0
  134. package/dist/chunk-MTFAG6E3.js +853 -0
  135. package/dist/chunk-MTFAG6E3.js.map +1 -0
  136. package/dist/chunk-MWJ6BCZJ.js +455 -0
  137. package/dist/chunk-MX5NQAK6.js +54 -0
  138. package/dist/chunk-MX5NQAK6.js.map +1 -0
  139. package/dist/chunk-O7WRA3JU.js +1902 -0
  140. package/dist/chunk-OADMSHME.js +334 -0
  141. package/dist/chunk-OLPABGH3.js +152 -0
  142. package/dist/chunk-ONGZKI5J.js +57 -0
  143. package/dist/chunk-OSZOUSK5.js +23 -0
  144. package/dist/chunk-PK7YNQ2T.js +454 -0
  145. package/dist/chunk-PN3CHL5W.js +98 -0
  146. package/dist/chunk-QMQSI4WA.js +89 -0
  147. package/dist/chunk-QUSDGZFS.js +188 -0
  148. package/dist/chunk-QXRSFH6M.js +604 -0
  149. package/dist/chunk-QZ4YHQLW.js +63 -0
  150. package/dist/chunk-RF3TP643.js +288 -0
  151. package/dist/chunk-RIRSFFWA.js +191 -0
  152. package/dist/chunk-ROHICQPK.js +8954 -0
  153. package/dist/chunk-RP3PC54R.js +169 -0
  154. package/dist/chunk-SIKCVWM3.js +76 -0
  155. package/dist/chunk-SOM4OTR5.js +167 -0
  156. package/dist/chunk-SYDPUGF5.js +126 -0
  157. package/dist/chunk-SYDPUGF5.js.map +1 -0
  158. package/dist/chunk-SZZ7BBED.js +148 -0
  159. package/dist/chunk-TAGJYHVI.js +191 -0
  160. package/dist/chunk-TB5JZTLN.js +19 -0
  161. package/dist/chunk-TQJLEVLA.js +131 -0
  162. package/dist/chunk-TW57RTKN.js +5368 -0
  163. package/dist/chunk-TXJOYQE2.js +1065 -0
  164. package/dist/chunk-TXJOYQE2.js.map +1 -0
  165. package/dist/chunk-UGIF56NZ.js +1254 -0
  166. package/dist/chunk-UGIF56NZ.js.map +1 -0
  167. package/dist/chunk-V3ANSXCB.js +51 -0
  168. package/dist/chunk-WSG4K2TR.js +103 -0
  169. package/dist/chunk-WXSRSMY3.js +64 -0
  170. package/dist/chunk-WZXMZFVB.js +238 -0
  171. package/dist/chunk-X3L5HYQM.js +91 -0
  172. package/dist/chunk-Y2TOB4N5.js +46 -0
  173. package/dist/chunk-YOHGEF2N.js +7899 -0
  174. package/dist/chunk-YOHGEF2N.js.map +1 -0
  175. package/dist/chunk-Z2LPYAN4.js +297 -0
  176. package/dist/chunk-ZICB4OI5.js +106 -0
  177. package/dist/chunk-ZOCAGPS5.js +225 -0
  178. package/dist/chunk-ZZWZUTEP.js +685 -0
  179. package/dist/claim-QHYA5UTF.js +200 -0
  180. package/dist/cli.js +36 -36
  181. package/dist/companies-BNMAOQUQ.js +198 -0
  182. package/dist/company-YANP3G62.js +308 -0
  183. package/dist/complete-ICZCBO6M.js +84 -0
  184. package/dist/config-GIETKZGS.js +88 -0
  185. package/dist/connect-ZXGEFS53.js +45 -0
  186. package/dist/conversation-YIWZIUIK.js +96 -0
  187. package/dist/conversion-report-E35RCZU7.js +127 -0
  188. package/dist/conversion-upload-command-QN33HEVV.js +440 -0
  189. package/dist/conversion-upload-command-QN33HEVV.js.map +1 -0
  190. package/dist/conversion-writes-MUD7WJDH.js +122 -0
  191. package/dist/conversions-B7HR6JMC.js +140 -0
  192. package/dist/conversions-WU7DNFF7.js +78 -0
  193. package/dist/copy-writes-R7VYSZXC.js +171 -0
  194. package/dist/copy-writes-R7VYSZXC.js.map +1 -0
  195. package/dist/create-EL47XN73.js +135 -0
  196. package/dist/create-GU5MUZ7U.js +62 -0
  197. package/dist/create-IKQ7A47F.js +239 -0
  198. package/dist/create-TKQDLX7M.js +218 -0
  199. package/dist/creatives-PW6HB4JB.js +58 -0
  200. package/dist/creatives-S4EGN44U.js +118 -0
  201. package/dist/creatives-VBD4T6C7.js +229 -0
  202. package/dist/credentials-57U2UQ7G.js +290 -0
  203. package/dist/critique-JTHSIXUF.js +233 -0
  204. package/dist/critique-JTHSIXUF.js.map +1 -0
  205. package/dist/critique-KAOJTSPQ.js +420 -0
  206. package/dist/critique-KAOJTSPQ.js.map +1 -0
  207. package/dist/crm-JCYLJQ7K.js +323 -0
  208. package/dist/crm-LQTYPDMZ.js +229 -0
  209. package/dist/currency-5NYTOLEL.js +88 -0
  210. package/dist/custom-conversions-NT7ONTEX.js +128 -0
  211. package/dist/customers-LP6I7POL.js +65 -0
  212. package/dist/delete-PZ6GP7J6.js +57 -0
  213. package/dist/delete-WW4JYQMX.js +69 -0
  214. package/dist/delete-XZNY426Q.js +67 -0
  215. package/dist/demographics-HZY2JEYQ.js +141 -0
  216. package/dist/discard-NRTGRVXR.js +69 -0
  217. package/dist/discover-5ZFAAPNG.js +172 -0
  218. package/dist/domain-YGKFTN6D.js +101 -0
  219. package/dist/download-XERSDEN3.js +172 -0
  220. package/dist/draft-2EVXU5XB.js +134 -0
  221. package/dist/draft-CQWYTMSS.js +138 -0
  222. package/dist/draft-EL74RDAG.js +374 -0
  223. package/dist/draft-EWB4A3FG.js +579 -0
  224. package/dist/draft-EWB4A3FG.js.map +1 -0
  225. package/dist/draft-GFZ3KMRX.js +315 -0
  226. package/dist/draft-JYZA3BFD.js +260 -0
  227. package/dist/draft-RBLMOZIL.js +333 -0
  228. package/dist/draft-RBLMOZIL.js.map +1 -0
  229. package/dist/draft-UNPTTHP4.js +220 -0
  230. package/dist/engine/index.js +8 -8
  231. package/dist/experiment-YAX26BOO.js +1397 -0
  232. package/dist/experiments-ERXZYY5E.js +237 -0
  233. package/dist/experiments-ERXZYY5E.js.map +1 -0
  234. package/dist/extract-QMY6WPTV.js +143 -0
  235. package/dist/facets-QHM2IQ3E.js +117 -0
  236. package/dist/feedback-NLPTKWOH.js +114 -0
  237. package/dist/feedback-X5FNVHKU.js +116 -0
  238. package/dist/feedback-X5FNVHKU.js.map +1 -0
  239. package/dist/feedback-record-7QCQTF26.js +270 -0
  240. package/dist/feedback-record-7QCQTF26.js.map +1 -0
  241. package/dist/fetch-72ZILZHO.js +204 -0
  242. package/dist/fit-AURKFPAY.js +65 -0
  243. package/dist/flows-CZPXHOZW.js +340 -0
  244. package/dist/fonts-NA26RQ4C.js +40 -0
  245. package/dist/forecast-ARIHRQAX.js +121 -0
  246. package/dist/forecast-BU22ZMOW.js +170 -0
  247. package/dist/forecast-BU22ZMOW.js.map +1 -0
  248. package/dist/funding-QDKFNQI2.js +85 -0
  249. package/dist/funnel-4VQB3T3M.js +397 -0
  250. package/dist/ga4-N6EBLN2W.js +55 -0
  251. package/dist/generate-IJLMJC4S.js +263 -0
  252. package/dist/get-LOEUOTG3.js +82 -0
  253. package/dist/get-W3VJIQBN.js +62 -0
  254. package/dist/google-5RKO3DND.js +3301 -0
  255. package/dist/google-5RKO3DND.js.map +1 -0
  256. package/dist/google-7VEPEBFV.js +163 -0
  257. package/dist/google-ads-YBOJ3XXK.js +198 -0
  258. package/dist/gsc-FILOUFCG.js +30 -0
  259. package/dist/history-6LLGAK7B.js +69 -0
  260. package/dist/history-H2SHADAM.js +153 -0
  261. package/dist/history-LJG64M6P.js +102 -0
  262. package/dist/hubspot-6JDARLIU.js +814 -0
  263. package/dist/ideas-MTWJDRRK.js +45 -0
  264. package/dist/images-RIFC6D3H.js +92 -0
  265. package/dist/ingest-K45T4OLM.js +131 -0
  266. package/dist/ingest-MSS52UO5.js +28 -0
  267. package/dist/insights-AVNMRFQ4.js +658 -0
  268. package/dist/insights-TBIT6DTF.js +132 -0
  269. package/dist/inspect-EBGYJOZ3.js +192 -0
  270. package/dist/instant-experiences-EEMQJ7H5.js +265 -0
  271. package/dist/instant-experiences-EEMQJ7H5.js.map +1 -0
  272. package/dist/intent-URHTU4AK.js +95 -0
  273. package/dist/job-OJB6KIDV.js +202 -0
  274. package/dist/job-create-C6FGCDW4.js +109 -0
  275. package/dist/job-status-4RJHESID.js +74 -0
  276. package/dist/keyword-gap-WXM6SN6A.js +130 -0
  277. package/dist/keyword-metrics-57MUTYMH.js +200 -0
  278. package/dist/keywords-for-site-ABZS7O5B.js +131 -0
  279. package/dist/landing-AXCYLUQZ.js +28 -0
  280. package/dist/languages-6XTVTFZC.js +40 -0
  281. package/dist/leads-C5BUBBLZ.js +115 -0
  282. package/dist/leads-IXF647ZC.js +542 -0
  283. package/dist/leads-IXF647ZC.js.map +1 -0
  284. package/dist/learn-M64GVGPX.js +207 -0
  285. package/dist/line-item-writes-HYLWBQTM.js +211 -0
  286. package/dist/line-items-Y4THDHSE.js +107 -0
  287. package/dist/link-BU7YCL2M.js +67 -0
  288. package/dist/linkedin-2SUTGGII.js +1345 -0
  289. package/dist/linkedin-2SUTGGII.js.map +1 -0
  290. package/dist/linkedin-person-FEIY7FYQ.js +139 -0
  291. package/dist/list-BKIL7O4G.js +306 -0
  292. package/dist/list-H3C345WG.js +154 -0
  293. package/dist/list-UGTDZ7YI.js +67 -0
  294. package/dist/locations-F4365X4S.js +40 -0
  295. package/dist/locations-HOI7AUZ2.js +69 -0
  296. package/dist/log-54SJV6MW.js +95 -0
  297. package/dist/lookup-QNLX2535.js +23 -0
  298. package/dist/make-AQ43J5LH.js +1368 -0
  299. package/dist/make-AQ43J5LH.js.map +1 -0
  300. package/dist/map-BPPGQGDV.js +445 -0
  301. package/dist/mcp-EXOMBMYL.js +729 -0
  302. package/dist/media-MITWBYVZ.js +18 -0
  303. package/dist/media-WGIEUEZW.js +89 -0
  304. package/dist/media-sources-XEC72K7X.js +35 -0
  305. package/dist/members-VDON57BE.js +47 -0
  306. package/dist/meta-NUBBKE2V.js +124 -0
  307. package/dist/metrics-V6FAZO5A.js +152 -0
  308. package/dist/models-TSMFIOZU.js +155 -0
  309. package/dist/normalize-632DD2HJ.js +144 -0
  310. package/dist/options-TZYZQZ3M.js +125 -0
  311. package/dist/organization-FYRXSGB4.js +949 -0
  312. package/dist/output-HZW7LNUL.js +24 -0
  313. package/dist/page-photos-4DNBQZUL.js +119 -0
  314. package/dist/page-photos-4DNBQZUL.js.map +1 -0
  315. package/dist/pages-UH6XEZBO.js +67 -0
  316. package/dist/performance-JKXHQIAV.js +27 -0
  317. package/dist/performance-OF3N43OP.js +5565 -0
  318. package/dist/pixels-KXA6R3G3.js +62 -0
  319. package/dist/pixels-PYNK73UG.js +109 -0
  320. package/dist/plan-4OYUV2EF.js +208 -0
  321. package/dist/preview-7E4E3QPT.js +245 -0
  322. package/dist/preview-FPBM75L2.js +101 -0
  323. package/dist/promoted-tweet-writes-IJRBFK7W.js +183 -0
  324. package/dist/promoted-tweets-7PYH3RPV.js +119 -0
  325. package/dist/properties-RDOGNY2O.js +101 -0
  326. package/dist/publish-MNSDFPEQ.js +350 -0
  327. package/dist/query-GMGWJW3X.js +62 -0
  328. package/dist/query-K7R5GQ4E.js +236 -0
  329. package/dist/query-PO3RT7BR.js +231 -0
  330. package/dist/questionnaire-4OH6K2BF.js +94 -0
  331. package/dist/read-MU5XGWMK.js +141 -0
  332. package/dist/reddit-JFFMZLJS.js +29 -0
  333. package/dist/refresh-EJ7WKW3H.js +97 -0
  334. package/dist/release-AFRLCZWB.js +63 -0
  335. package/dist/relevant-pages-4YGN3I2U.js +99 -0
  336. package/dist/remove-QD4PITBL.js +53 -0
  337. package/dist/reopen-JSC6AVJC.js +66 -0
  338. package/dist/rerun-QIAUVJX6.js +98 -0
  339. package/dist/rerun-QIAUVJX6.js.map +1 -0
  340. package/dist/research-MMFUFZGS.js +265 -0
  341. package/dist/research-SRISCVBM.js +75 -0
  342. package/dist/reset-752CNET3.js +57 -0
  343. package/dist/reset-R3TQAHRU.js +57 -0
  344. package/dist/resolve-EWHSJNBX.js +124 -0
  345. package/dist/retry-DVHDVHVP.js +65 -0
  346. package/dist/retry-PVULTONO.js +63 -0
  347. package/dist/revenue-B4N6QJM3.js +92 -0
  348. package/dist/revenue-B4N6QJM3.js.map +1 -0
  349. package/dist/rule-writes-YXK7HNLR.js +531 -0
  350. package/dist/rule-writes-YXK7HNLR.js.map +1 -0
  351. package/dist/rules-4YTY57FM.js +217 -0
  352. package/dist/rules-LRFDZFF6.js +108 -0
  353. package/dist/rules-LRFDZFF6.js.map +1 -0
  354. package/dist/rules-add-XVOGYHQO.js +497 -0
  355. package/dist/rules-add-XVOGYHQO.js.map +1 -0
  356. package/dist/run-PCZRYL42.js +69 -0
  357. package/dist/run-PRSAUWAJ.js +73 -0
  358. package/dist/scaffold-ad-A6SROV4X.js +1514 -0
  359. package/dist/scaffold-ad-A6SROV4X.js.map +1 -0
  360. package/dist/scaffold-static-ad-CRN5XZIZ.js +1013 -0
  361. package/dist/scaffold-static-ad-CRN5XZIZ.js.map +1 -0
  362. package/dist/scaffold-video-3F5JVFFR.js +886 -0
  363. package/dist/scaffold-video-3F5JVFFR.js.map +1 -0
  364. package/dist/schedule-6YTZBCZA.js +64 -0
  365. package/dist/scheduled-agents-XCPU57LU.js +55 -0
  366. package/dist/schema-4PS5BDG3.js +135 -0
  367. package/dist/search-IMZD5RGD.js +177 -0
  368. package/dist/select-GSO4BEIL.js +111 -0
  369. package/dist/select-GSO4BEIL.js.map +1 -0
  370. package/dist/sends-I2B6F5NW.js +349 -0
  371. package/dist/set-prompt-D32XJNWM.js +200 -0
  372. package/dist/set-prompt-D32XJNWM.js.map +1 -0
  373. package/dist/setup-links-PTL6RF2J.js +144 -0
  374. package/dist/shared-Z7INVKCZ.js +32 -0
  375. package/dist/shopify-SDZZ5HTA.js +4009 -0
  376. package/dist/site-NGQ7K6UD.js +180 -0
  377. package/dist/sitemaps-EOMSRKOD.js +77 -0
  378. package/dist/sites-6M73AONG.js +97 -0
  379. package/dist/sources-NKFSCI6M.js +30 -0
  380. package/dist/sources-O4CQ5KSX.js +457 -0
  381. package/dist/stale-CEZJ53RO.js +91 -0
  382. package/dist/stale-CEZJ53RO.js.map +1 -0
  383. package/dist/stats-MFEH2TSW.js +34 -0
  384. package/dist/status-DLYRPGFS.js +65 -0
  385. package/dist/stock-RDCDVBHX.js +212 -0
  386. package/dist/studies-SSA3SR2L.js +250 -0
  387. package/dist/studio-MBHPDGMN.js +49 -0
  388. package/dist/study-writes-EDV6OH7I.js +472 -0
  389. package/dist/study-writes-EDV6OH7I.js.map +1 -0
  390. package/dist/sync-BEW3TZP7.js +57 -0
  391. package/dist/sync-SI25TKY5.js +279 -0
  392. package/dist/sync-definition-RECCA3QH.js +71 -0
  393. package/dist/tag-manager-JFC6YYVP.js +43 -0
  394. package/dist/tags-IJIGZYR3.js +23 -0
  395. package/dist/tags-K4HIKHNU.js +26 -0
  396. package/dist/tags-OTA55BQ6.js +23 -0
  397. package/dist/tags-QF2V4B3M.js +23 -0
  398. package/dist/tags-SK7WXMBS.js +227 -0
  399. package/dist/targeting-NPNBPEHW.js +763 -0
  400. package/dist/targeting-NPNBPEHW.js.map +1 -0
  401. package/dist/targeting-constants-RF2732EW.js +118 -0
  402. package/dist/targeting-criteria-7BUUYDYC.js +113 -0
  403. package/dist/targets-7V3NCQSD.js +106 -0
  404. package/dist/terms-XFL6QO7A.js +102 -0
  405. package/dist/testimonials-XYD5DLBJ.js +32 -0
  406. package/dist/themes-HYDGH4GM.js +96 -0
  407. package/dist/themes-HYDGH4GM.js.map +1 -0
  408. package/dist/top-companies-LI26TONY.js +111 -0
  409. package/dist/transcript-FTHDWMGU.js +165 -0
  410. package/dist/translate-YATYKOEX.js +604 -0
  411. package/dist/translate-YATYKOEX.js.map +1 -0
  412. package/dist/triggers-3LHJVK5P.js +144 -0
  413. package/dist/tweets-6PQHJXJC.js +123 -0
  414. package/dist/unlink-BMOUBGWO.js +70 -0
  415. package/dist/unstage-O23ILHCY.js +96 -0
  416. package/dist/unstage-YEW5KXJL.js +88 -0
  417. package/dist/update-2IWZA5UU.js +101 -0
  418. package/dist/update-G7YZICSU.js +155 -0
  419. package/dist/update-T5INCQJZ.js +192 -0
  420. package/dist/update-UTQVTG45.js +66 -0
  421. package/dist/upload-UXYJDA2U.js +137 -0
  422. package/dist/url-options-Y7I5EL55.js +131 -0
  423. package/dist/url-params-PE4XAQNH.js +101 -0
  424. package/dist/validate-MMHBTNWU.js +126 -0
  425. package/dist/validate-MMHBTNWU.js.map +1 -0
  426. package/dist/videos-AHOLXU42.js +146 -0
  427. package/dist/videos-EVPJHY3B.js +41 -0
  428. package/dist/viewer-check-NA4TMNY4.js +83 -0
  429. package/dist/web-7EODEH25.js +173 -0
  430. package/dist/winning-ads-5UKX6QV7.js +86 -0
  431. package/dist/write-commands-HFP5KLYZ.js +1525 -0
  432. package/dist/write-commands-HFP5KLYZ.js.map +1 -0
  433. package/dist/write-commands-KVOMOYME.js +1170 -0
  434. package/dist/write-commands-KVOMOYME.js.map +1 -0
  435. package/dist/write-commands-LHEJESKL.js +206 -0
  436. package/dist/write-commands-SD6DXVNK.js +721 -0
  437. package/dist/x-R72UTFQT.js +47 -0
  438. package/package.json +1 -1
  439. package/dist/account-OCFXNHG7.js +0 -139
  440. package/dist/account-U6DFMD2V.js +0 -82
  441. package/dist/account-UE6DOQXK.js +0 -82
  442. package/dist/account-assets-W7K2PUYB.js +0 -290
  443. package/dist/account-level-Z2JEIJ3X.js +0 -611
  444. package/dist/account-level-Z2JEIJ3X.js.map +0 -1
  445. package/dist/account-reads-WPKD2LPB.js +0 -219
  446. package/dist/account-reads-WPKD2LPB.js.map +0 -1
  447. package/dist/account-users-USGCCE6I.js +0 -64
  448. package/dist/account-users-USGCCE6I.js.map +0 -1
  449. package/dist/account-writes-QSJ74QFR.js +0 -68
  450. package/dist/accounts-3DS67RX7.js +0 -119
  451. package/dist/accounts-55PDBEDN.js +0 -76
  452. package/dist/accounts-AK4QIG24.js +0 -115
  453. package/dist/accounts-FZCQNX3B.js +0 -713
  454. package/dist/accounts-PVMTLDJU.js +0 -80
  455. package/dist/actions-EG23YFYB.js +0 -55
  456. package/dist/active-entities-HR7NJJLU.js +0 -103
  457. package/dist/activecampaign-GPT5R647.js +0 -938
  458. package/dist/activities-DEWHKBID.js +0 -75
  459. package/dist/ad-group-writes-QBHOPTT5.js +0 -172
  460. package/dist/ad-groups-JZDUFT6J.js +0 -70
  461. package/dist/ad-writes-QYJO4IB3.js +0 -176
  462. package/dist/add-IH6GAMK4.js +0 -107
  463. package/dist/add-UWTWG4VO.js +0 -305
  464. package/dist/ads-F3VUMSEV.js +0 -48
  465. package/dist/ads-QKVNPHBH.js +0 -120
  466. package/dist/ads-UMSWEI5X.js +0 -79
  467. package/dist/adsets-FEVYHKAQ.js +0 -182
  468. package/dist/advertisers-AJNDC3AX.js +0 -123
  469. package/dist/analytics-PEGA46W5.js +0 -447
  470. package/dist/analytics-XCQ3G5PM.js +0 -2437
  471. package/dist/animate-WS63CZ3Y.js +0 -480
  472. package/dist/asset-writes-7RFZZYU7.js +0 -50
  473. package/dist/assign-2CZ5C43W.js +0 -80
  474. package/dist/audience-size-FUHDVYLN.js +0 -76
  475. package/dist/audience-writes-RUGU6KEC.js +0 -327
  476. package/dist/audience-writes-RUGU6KEC.js.map +0 -1
  477. package/dist/audiences-6GVUZUCN.js +0 -106
  478. package/dist/audiences-7OS2ZJYO.js +0 -85
  479. package/dist/audiences-RSAUXKHR.js +0 -280
  480. package/dist/audit-4L7IKIRY.js +0 -88
  481. package/dist/audit-DECB5PP5.js +0 -154
  482. package/dist/autocomplete-6XSIFXDA.js +0 -114
  483. package/dist/avatars-LTV2TSO2.js +0 -38
  484. package/dist/bid-pricing-GC6YU3LW.js +0 -103
  485. package/dist/brand-B4QKPCEC.js +0 -22
  486. package/dist/brief-RYNGM4GX.js +0 -543
  487. package/dist/businesses-42NZP6FP.js +0 -54
  488. package/dist/campaign-groups-FHV5A3EC.js +0 -99
  489. package/dist/campaign-writes-4B7DCAP2.js +0 -168
  490. package/dist/campaign-writes-GKNH2EHV.js +0 -176
  491. package/dist/campaigns-7RV65SXR.js +0 -78
  492. package/dist/campaigns-TL37AY5Y.js +0 -113
  493. package/dist/campaigns-TO74Z7UH.js +0 -130
  494. package/dist/campaigns-VNBJV5QD.js +0 -111
  495. package/dist/canvas-6XSA3VZE.js +0 -46
  496. package/dist/capabilities-6MOMJZFW.js +0 -147
  497. package/dist/cards-CAOGPPG4.js +0 -85
  498. package/dist/catalog-URTZYAPU.js +0 -66
  499. package/dist/catalogs-5LWEXG5X.js +0 -130
  500. package/dist/catalogs-7IEXGLSR.js +0 -782
  501. package/dist/catalogs-7IEXGLSR.js.map +0 -1
  502. package/dist/changes-WWZYTLC6.js +0 -167
  503. package/dist/chatgpt-ZI4GWP6S.js +0 -47
  504. package/dist/chats-GRS6RCDL.js +0 -449
  505. package/dist/chats-GRS6RCDL.js.map +0 -1
  506. package/dist/check-VIRAMFKC.js +0 -107
  507. package/dist/check-VIRAMFKC.js.map +0 -1
  508. package/dist/chunk-22RM3UOO.js +0 -63
  509. package/dist/chunk-2DAWUWA4.js +0 -115
  510. package/dist/chunk-2GFJN2TR.js +0 -163
  511. package/dist/chunk-2LBQNTTH.js +0 -76
  512. package/dist/chunk-3D5ABNNW.js +0 -156
  513. package/dist/chunk-3E74OM2E.js +0 -288
  514. package/dist/chunk-3GKAVXR3.js +0 -23
  515. package/dist/chunk-4NZ47VXO.js +0 -137
  516. package/dist/chunk-4NZ47VXO.js.map +0 -1
  517. package/dist/chunk-5H6N36LS.js +0 -217
  518. package/dist/chunk-5T6DUP7V.js +0 -207
  519. package/dist/chunk-6IR7IQPV.js +0 -69
  520. package/dist/chunk-6IRB3MHG.js +0 -430
  521. package/dist/chunk-6MX37ZQZ.js +0 -454
  522. package/dist/chunk-6QINKM6T.js +0 -46
  523. package/dist/chunk-7M6GZI5B.js +0 -479
  524. package/dist/chunk-AE5S5B2S.js +0 -249
  525. package/dist/chunk-AE5S5B2S.js.map +0 -1
  526. package/dist/chunk-ARPT74DG.js +0 -312
  527. package/dist/chunk-B42CHCXX.js +0 -962
  528. package/dist/chunk-B47TRSMB.js +0 -8954
  529. package/dist/chunk-BHEOF2MF.js +0 -2209
  530. package/dist/chunk-BMMXYR7A.js +0 -238
  531. package/dist/chunk-BRPSY35A.js +0 -468
  532. package/dist/chunk-C3EX5OKN.js +0 -188
  533. package/dist/chunk-CDPM6OE6.js +0 -61
  534. package/dist/chunk-CDTAKCJR.js +0 -178
  535. package/dist/chunk-CDTAKCJR.js.map +0 -1
  536. package/dist/chunk-D6YLVDVN.js +0 -103
  537. package/dist/chunk-DLM5OSHM.js +0 -843
  538. package/dist/chunk-DLM5OSHM.js.map +0 -1
  539. package/dist/chunk-DWPOAU4Z.js +0 -5471
  540. package/dist/chunk-EJBLF2LI.js +0 -167
  541. package/dist/chunk-FHWYQSMY.js +0 -930
  542. package/dist/chunk-FWHEAR7F.js +0 -138
  543. package/dist/chunk-GNTI4KST.js +0 -494
  544. package/dist/chunk-GR2BPVLX.js +0 -142
  545. package/dist/chunk-GWLP45WQ.js +0 -1518
  546. package/dist/chunk-GXAI3EII.js +0 -399
  547. package/dist/chunk-H3HA22Z3.js +0 -1919
  548. package/dist/chunk-H3PD2KOF.js +0 -203
  549. package/dist/chunk-HBRXFQQV.js +0 -3510
  550. package/dist/chunk-IGCS3X4F.js +0 -150
  551. package/dist/chunk-ILGRC7LJ.js +0 -287
  552. package/dist/chunk-IXVVTPG6.js +0 -831
  553. package/dist/chunk-JAC6JVCI.js +0 -26
  554. package/dist/chunk-JBABLH5C.js +0 -547
  555. package/dist/chunk-JHS5PE5Y.js +0 -1246
  556. package/dist/chunk-JHS5PE5Y.js.map +0 -1
  557. package/dist/chunk-JTIWQLY5.js +0 -98
  558. package/dist/chunk-KDAINT54.js +0 -131
  559. package/dist/chunk-KICGV4JB.js +0 -170
  560. package/dist/chunk-LDYI7BIQ.js +0 -334
  561. package/dist/chunk-LXOTNL65.js +0 -7888
  562. package/dist/chunk-LXOTNL65.js.map +0 -1
  563. package/dist/chunk-M45SOKI5.js +0 -91
  564. package/dist/chunk-MCJ5I5LR.js +0 -3187
  565. package/dist/chunk-MCJ5I5LR.js.map +0 -1
  566. package/dist/chunk-ME3K6XIS.js +0 -685
  567. package/dist/chunk-MKG57P2E.js +0 -783
  568. package/dist/chunk-MU2TTM6Z.js +0 -197
  569. package/dist/chunk-MZPS46OR.js +0 -76
  570. package/dist/chunk-N2MGR7HT.js +0 -1902
  571. package/dist/chunk-N2TXADL7.js +0 -1320
  572. package/dist/chunk-NTFNLVZG.js +0 -26
  573. package/dist/chunk-O43QFUOG.js +0 -51
  574. package/dist/chunk-OASXBRXQ.js +0 -24026
  575. package/dist/chunk-OASXBRXQ.js.map +0 -1
  576. package/dist/chunk-ORQ3WBM6.js +0 -225
  577. package/dist/chunk-OSQTSS27.js +0 -74
  578. package/dist/chunk-OTRKBCUB.js +0 -219
  579. package/dist/chunk-P6KTCPJG.js +0 -604
  580. package/dist/chunk-Q5DFEVLE.js +0 -148
  581. package/dist/chunk-QVQKCVP7.js +0 -85
  582. package/dist/chunk-QVQKCVP7.js.map +0 -1
  583. package/dist/chunk-R4RWQ6YX.js +0 -152
  584. package/dist/chunk-RBB3UUYP.js +0 -297
  585. package/dist/chunk-RBCO3C3Q.js +0 -324
  586. package/dist/chunk-RBCO3C3Q.js.map +0 -1
  587. package/dist/chunk-RJIFEHEG.js +0 -392
  588. package/dist/chunk-RYYRGQMM.js +0 -191
  589. package/dist/chunk-S3ZW3KTX.js +0 -89
  590. package/dist/chunk-SZET6NTF.js +0 -57
  591. package/dist/chunk-T4YD5W33.js +0 -66
  592. package/dist/chunk-TPGFX47R.js +0 -709
  593. package/dist/chunk-U5LSGCT3.js +0 -455
  594. package/dist/chunk-UKZKLXTE.js +0 -638
  595. package/dist/chunk-UKZKLXTE.js.map +0 -1
  596. package/dist/chunk-ULIQNJ5J.js +0 -274
  597. package/dist/chunk-URKOGN5B.js +0 -19
  598. package/dist/chunk-UYZ4FUC7.js +0 -225
  599. package/dist/chunk-V6TZRCAS.js +0 -169
  600. package/dist/chunk-WBWEKZQ2.js +0 -191
  601. package/dist/chunk-X3GWGFZP.js +0 -5368
  602. package/dist/chunk-X3YYZLBH.js +0 -285
  603. package/dist/chunk-XHWHBGKX.js +0 -4277
  604. package/dist/chunk-XHWHBGKX.js.map +0 -1
  605. package/dist/chunk-XRR5NN2V.js +0 -91
  606. package/dist/chunk-XZAVBONI.js +0 -64
  607. package/dist/chunk-YD6OZSSY.js +0 -106
  608. package/dist/chunk-YXZV6YKH.js +0 -224
  609. package/dist/chunk-ZREKNWIE.js +0 -344
  610. package/dist/claim-YCK2XQUL.js +0 -200
  611. package/dist/companies-SWGL3MQT.js +0 -198
  612. package/dist/company-XKEQKWPO.js +0 -308
  613. package/dist/complete-CHEZWF5R.js +0 -84
  614. package/dist/config-NDL2YP37.js +0 -88
  615. package/dist/connect-GWLVOOU7.js +0 -45
  616. package/dist/conversation-QD4UJZ7S.js +0 -96
  617. package/dist/conversion-report-76S5JOVT.js +0 -127
  618. package/dist/conversion-upload-command-5OILW65U.js +0 -439
  619. package/dist/conversion-upload-command-5OILW65U.js.map +0 -1
  620. package/dist/conversion-writes-6HX665JT.js +0 -122
  621. package/dist/conversions-BECU3XD2.js +0 -140
  622. package/dist/conversions-QZJRF4WN.js +0 -78
  623. package/dist/copy-writes-X2LM5I4Z.js +0 -170
  624. package/dist/copy-writes-X2LM5I4Z.js.map +0 -1
  625. package/dist/create-4OA5DOSO.js +0 -239
  626. package/dist/create-5QPEESSZ.js +0 -135
  627. package/dist/create-ET3VCGQT.js +0 -62
  628. package/dist/create-IJSH2LHP.js +0 -218
  629. package/dist/creatives-AIRQ3FGH.js +0 -229
  630. package/dist/creatives-L3XSN34M.js +0 -58
  631. package/dist/creatives-SFPNXJ6Z.js +0 -118
  632. package/dist/credentials-Q2FM4DP3.js +0 -290
  633. package/dist/critique-A5FVPC5K.js +0 -1451
  634. package/dist/critique-A5FVPC5K.js.map +0 -1
  635. package/dist/critique-RSU7N2NV.js +0 -232
  636. package/dist/critique-RSU7N2NV.js.map +0 -1
  637. package/dist/crm-7GTTSEHH.js +0 -229
  638. package/dist/crm-PQREUPOU.js +0 -323
  639. package/dist/currency-BZUNQ4XJ.js +0 -88
  640. package/dist/custom-conversions-UHRBVUD2.js +0 -128
  641. package/dist/customers-BYNADWKU.js +0 -65
  642. package/dist/delete-2RAKL577.js +0 -69
  643. package/dist/delete-EZ525EJV.js +0 -57
  644. package/dist/delete-ZBYPC5AL.js +0 -67
  645. package/dist/demographics-5XMZ2TBB.js +0 -141
  646. package/dist/discard-Q7R5VJ7I.js +0 -69
  647. package/dist/discover-PDSEJR2P.js +0 -172
  648. package/dist/domain-MS3BKUYW.js +0 -101
  649. package/dist/download-F56SAC2G.js +0 -172
  650. package/dist/draft-44KTLX4P.js +0 -134
  651. package/dist/draft-4EM4TL25.js +0 -332
  652. package/dist/draft-4EM4TL25.js.map +0 -1
  653. package/dist/draft-CKFSZDVI.js +0 -260
  654. package/dist/draft-JBLWUO3J.js +0 -220
  655. package/dist/draft-L6XXU2I6.js +0 -374
  656. package/dist/draft-RSKZSUOS.js +0 -138
  657. package/dist/draft-WOE7KQ7T.js +0 -315
  658. package/dist/draft-XOPS4EZW.js +0 -569
  659. package/dist/draft-XOPS4EZW.js.map +0 -1
  660. package/dist/experiment-AZUKJ7ZO.js +0 -1397
  661. package/dist/experiments-34NEL75V.js +0 -236
  662. package/dist/experiments-34NEL75V.js.map +0 -1
  663. package/dist/extract-2PG5JB2C.js +0 -143
  664. package/dist/facets-5CGKHFDQ.js +0 -117
  665. package/dist/feedback-C7THFXTE.js +0 -114
  666. package/dist/feedback-SWNIEXMA.js +0 -115
  667. package/dist/feedback-SWNIEXMA.js.map +0 -1
  668. package/dist/feedback-record-BNDFZRYJ.js +0 -269
  669. package/dist/feedback-record-BNDFZRYJ.js.map +0 -1
  670. package/dist/fetch-LMEYFSM5.js +0 -204
  671. package/dist/fit-DBA7FD3M.js +0 -65
  672. package/dist/flows-TQASOYQP.js +0 -340
  673. package/dist/fonts-MPDK2DXR.js +0 -39
  674. package/dist/forecast-3KMAJJWJ.js +0 -169
  675. package/dist/forecast-3KMAJJWJ.js.map +0 -1
  676. package/dist/forecast-OP2ECNM2.js +0 -121
  677. package/dist/funding-BSAHWU35.js +0 -85
  678. package/dist/funnel-BLRQAZ65.js +0 -397
  679. package/dist/ga4-YVKA3V4V.js +0 -55
  680. package/dist/generate-VGGXTZBP.js +0 -263
  681. package/dist/get-DEELBPMG.js +0 -82
  682. package/dist/get-YATZI6GN.js +0 -62
  683. package/dist/google-REFD3W2R.js +0 -3300
  684. package/dist/google-REFD3W2R.js.map +0 -1
  685. package/dist/google-ULLPGAXN.js +0 -163
  686. package/dist/google-ads-IEQJEICD.js +0 -198
  687. package/dist/gsc-OJDMSP6H.js +0 -30
  688. package/dist/history-2LE4ELLB.js +0 -102
  689. package/dist/history-FPXZOUHT.js +0 -153
  690. package/dist/history-LXRFZNW7.js +0 -69
  691. package/dist/hubspot-MNREQEVI.js +0 -814
  692. package/dist/ideas-4N7WMX3P.js +0 -45
  693. package/dist/images-KVMFKQX5.js +0 -92
  694. package/dist/ingest-GUJNPD6S.js +0 -28
  695. package/dist/ingest-VG4YGXB2.js +0 -131
  696. package/dist/insights-H6M6VI43.js +0 -132
  697. package/dist/insights-LZJZGNJZ.js +0 -658
  698. package/dist/inspect-VODWKUQY.js +0 -192
  699. package/dist/instant-experiences-J4GSS3Y6.js +0 -264
  700. package/dist/instant-experiences-J4GSS3Y6.js.map +0 -1
  701. package/dist/intent-HXRSLFIO.js +0 -95
  702. package/dist/job-UFGGBDG7.js +0 -202
  703. package/dist/job-create-XM4NH322.js +0 -109
  704. package/dist/job-status-47L5Z57J.js +0 -74
  705. package/dist/keyword-gap-WUHMSTNR.js +0 -130
  706. package/dist/keyword-metrics-LOLNR24U.js +0 -200
  707. package/dist/keywords-for-site-PLTJBXVN.js +0 -131
  708. package/dist/landing-JMH3WIK2.js +0 -28
  709. package/dist/languages-SVTYYYOC.js +0 -40
  710. package/dist/leads-SEEJ3KRR.js +0 -541
  711. package/dist/leads-SEEJ3KRR.js.map +0 -1
  712. package/dist/leads-XPIBMZI7.js +0 -115
  713. package/dist/learn-MOHK6DHI.js +0 -207
  714. package/dist/line-item-writes-5RVCYHHH.js +0 -211
  715. package/dist/line-items-OESD2IJ6.js +0 -107
  716. package/dist/link-PURCDO7A.js +0 -67
  717. package/dist/linkedin-YWLXEPLB.js +0 -1344
  718. package/dist/linkedin-YWLXEPLB.js.map +0 -1
  719. package/dist/linkedin-person-L22XA5LG.js +0 -139
  720. package/dist/list-KE6PQV2U.js +0 -154
  721. package/dist/list-L5VZ35AO.js +0 -306
  722. package/dist/list-T5ZVVC4L.js +0 -67
  723. package/dist/locations-5SLLGWZO.js +0 -69
  724. package/dist/locations-7EBZ6KRH.js +0 -40
  725. package/dist/log-D3WU36FX.js +0 -95
  726. package/dist/lookup-OU6CLATK.js +0 -23
  727. package/dist/make-QPE6H3NT.js +0 -1367
  728. package/dist/make-QPE6H3NT.js.map +0 -1
  729. package/dist/map-PT7JJYQR.js +0 -445
  730. package/dist/mcp-62MSONPH.js +0 -729
  731. package/dist/media-DGV2AMZI.js +0 -89
  732. package/dist/media-YKCCMLXL.js +0 -18
  733. package/dist/media-sources-DGVR3YPL.js +0 -35
  734. package/dist/members-DAHPS3MB.js +0 -47
  735. package/dist/meta-5TRG7RTQ.js +0 -124
  736. package/dist/metrics-WRERNMRK.js +0 -152
  737. package/dist/models-SITHUNAA.js +0 -155
  738. package/dist/normalize-ZOJ4YROH.js +0 -144
  739. package/dist/options-DTB2NYBL.js +0 -125
  740. package/dist/organization-5JHFNUOD.js +0 -949
  741. package/dist/output-7X5WPPCA.js +0 -24
  742. package/dist/page-photos-VYJU4RNQ.js +0 -118
  743. package/dist/page-photos-VYJU4RNQ.js.map +0 -1
  744. package/dist/pages-6YMPZDEY.js +0 -67
  745. package/dist/performance-VFDK5PHT.js +0 -5565
  746. package/dist/performance-W6CJEUHR.js +0 -27
  747. package/dist/pixels-DZDVNIVL.js +0 -109
  748. package/dist/pixels-WTTLC4O5.js +0 -62
  749. package/dist/plan-JAWESWJN.js +0 -208
  750. package/dist/preview-JZXGR4KN.js +0 -245
  751. package/dist/preview-PUF62HJU.js +0 -101
  752. package/dist/promoted-tweet-writes-FW4BAA5O.js +0 -183
  753. package/dist/promoted-tweets-LYHKCVNV.js +0 -119
  754. package/dist/properties-Z5S3LRJ5.js +0 -101
  755. package/dist/publish-S2KD5PCN.js +0 -350
  756. package/dist/query-3QFT42PG.js +0 -62
  757. package/dist/query-KKXCMH3Q.js +0 -236
  758. package/dist/query-QXKGVHZL.js +0 -231
  759. package/dist/questionnaire-U7UYICEA.js +0 -94
  760. package/dist/read-ENUS7P3L.js +0 -141
  761. package/dist/reddit-AF2PPR3K.js +0 -29
  762. package/dist/refresh-UC7OTPXS.js +0 -97
  763. package/dist/release-FQOJ2FJ5.js +0 -63
  764. package/dist/relevant-pages-OFKZYWR3.js +0 -99
  765. package/dist/remove-H3SU4GJK.js +0 -53
  766. package/dist/reopen-M2PZEHKF.js +0 -66
  767. package/dist/rerun-M63ZAYAV.js +0 -97
  768. package/dist/rerun-M63ZAYAV.js.map +0 -1
  769. package/dist/research-2N5HAFSB.js +0 -75
  770. package/dist/research-ILZZTO6Q.js +0 -265
  771. package/dist/reset-JN437DOZ.js +0 -57
  772. package/dist/reset-XAKAEDPH.js +0 -57
  773. package/dist/resolve-WVE6D7CP.js +0 -124
  774. package/dist/retry-ILL2ZATG.js +0 -63
  775. package/dist/retry-PMJ22IN4.js +0 -65
  776. package/dist/revenue-UWU3ACGP.js +0 -91
  777. package/dist/revenue-UWU3ACGP.js.map +0 -1
  778. package/dist/rule-writes-WT6DQZZE.js +0 -530
  779. package/dist/rule-writes-WT6DQZZE.js.map +0 -1
  780. package/dist/rules-BOOFGKJA.js +0 -99
  781. package/dist/rules-BOOFGKJA.js.map +0 -1
  782. package/dist/rules-Y75KR2PC.js +0 -217
  783. package/dist/rules-add-7K5ESEZQ.js +0 -465
  784. package/dist/rules-add-7K5ESEZQ.js.map +0 -1
  785. package/dist/run-2AIXS3KE.js +0 -72
  786. package/dist/run-OCCY7JHY.js +0 -69
  787. package/dist/scaffold-ad-JQIOCLDU.js +0 -1513
  788. package/dist/scaffold-ad-JQIOCLDU.js.map +0 -1
  789. package/dist/scaffold-static-ad-BW56MVIV.js +0 -1012
  790. package/dist/scaffold-static-ad-BW56MVIV.js.map +0 -1
  791. package/dist/scaffold-video-OGPMQO5D.js +0 -885
  792. package/dist/scaffold-video-OGPMQO5D.js.map +0 -1
  793. package/dist/schedule-WV6NZ4CK.js +0 -64
  794. package/dist/scheduled-agents-MZZMHN3T.js +0 -55
  795. package/dist/schema-ADRFE3AV.js +0 -135
  796. package/dist/search-GGWTLVG7.js +0 -177
  797. package/dist/select-HYZ5JYO7.js +0 -110
  798. package/dist/select-HYZ5JYO7.js.map +0 -1
  799. package/dist/sends-4ZO6BNZ4.js +0 -349
  800. package/dist/set-prompt-FMJ32YNG.js +0 -199
  801. package/dist/set-prompt-FMJ32YNG.js.map +0 -1
  802. package/dist/setup-links-76AJJR5Z.js +0 -144
  803. package/dist/shared-UPMEBTVP.js +0 -32
  804. package/dist/shopify-Q3XMCPHI.js +0 -4009
  805. package/dist/site-I4HFMTE5.js +0 -180
  806. package/dist/sitemaps-P3K5Z4TW.js +0 -77
  807. package/dist/sites-TURWC53D.js +0 -97
  808. package/dist/sources-GGLP5NQU.js +0 -30
  809. package/dist/sources-ORL5AEH5.js +0 -457
  810. package/dist/stale-GVPIUPBX.js +0 -90
  811. package/dist/stale-GVPIUPBX.js.map +0 -1
  812. package/dist/stats-XNKAJD2Z.js +0 -34
  813. package/dist/status-LSHCACMZ.js +0 -65
  814. package/dist/stock-RZH4SEGS.js +0 -212
  815. package/dist/studies-5G67ODR2.js +0 -250
  816. package/dist/studio-D2OMFCZZ.js +0 -49
  817. package/dist/study-writes-34BJFZAZ.js +0 -471
  818. package/dist/study-writes-34BJFZAZ.js.map +0 -1
  819. package/dist/sync-MK7JTH3U.js +0 -57
  820. package/dist/sync-QVEUQKU5.js +0 -279
  821. package/dist/sync-definition-EFAJ744M.js +0 -70
  822. package/dist/tag-manager-3GIW6BPB.js +0 -43
  823. package/dist/tags-5HX7TDJN.js +0 -23
  824. package/dist/tags-BE6L5NLG.js +0 -23
  825. package/dist/tags-EOIC4EQK.js +0 -26
  826. package/dist/tags-G4HMOLZF.js +0 -23
  827. package/dist/tags-PF6UJWCF.js +0 -227
  828. package/dist/targeting-TVZPIUUI.js +0 -762
  829. package/dist/targeting-TVZPIUUI.js.map +0 -1
  830. package/dist/targeting-constants-RJS2STR5.js +0 -118
  831. package/dist/targeting-criteria-DOHSND62.js +0 -113
  832. package/dist/targets-7AL4HPAW.js +0 -106
  833. package/dist/terms-AATAGKPT.js +0 -102
  834. package/dist/testimonials-BNYHKXD2.js +0 -32
  835. package/dist/themes-5HKRO5RR.js +0 -95
  836. package/dist/themes-5HKRO5RR.js.map +0 -1
  837. package/dist/top-companies-ASSEFHI3.js +0 -111
  838. package/dist/transcript-OTAKTTSA.js +0 -165
  839. package/dist/translate-ATGQD733.js +0 -603
  840. package/dist/translate-ATGQD733.js.map +0 -1
  841. package/dist/triggers-JQYC4JLT.js +0 -144
  842. package/dist/tweets-MLDLLLDB.js +0 -123
  843. package/dist/unlink-FVHHULLC.js +0 -70
  844. package/dist/unstage-65DUBYNZ.js +0 -96
  845. package/dist/unstage-FIRVPNRC.js +0 -88
  846. package/dist/update-EO5LVV34.js +0 -101
  847. package/dist/update-G7RMT4OC.js +0 -192
  848. package/dist/update-OD75FSPH.js +0 -66
  849. package/dist/update-RA6TX5NV.js +0 -155
  850. package/dist/upload-X33VIDOB.js +0 -137
  851. package/dist/url-options-4J3FRXHO.js +0 -131
  852. package/dist/url-params-IBE4HUKK.js +0 -101
  853. package/dist/validate-ZKQN55FV.js +0 -125
  854. package/dist/validate-ZKQN55FV.js.map +0 -1
  855. package/dist/videos-NITQKILV.js +0 -146
  856. package/dist/videos-RGCF3EAE.js +0 -41
  857. package/dist/viewer-check-AKVX3XFW.js +0 -83
  858. package/dist/web-QVR2EQ7X.js +0 -173
  859. package/dist/winning-ads-3R4RU3FL.js +0 -86
  860. package/dist/write-commands-OBQPQUIE.js +0 -721
  861. package/dist/write-commands-QQFBJBYD.js +0 -1524
  862. package/dist/write-commands-QQFBJBYD.js.map +0 -1
  863. package/dist/write-commands-SIOVTRHH.js +0 -1169
  864. package/dist/write-commands-SIOVTRHH.js.map +0 -1
  865. package/dist/write-commands-XLZCRVTU.js +0 -206
  866. package/dist/x-747NTJKH.js +0 -47
  867. /package/dist/{account-U6DFMD2V.js.map → account-JREYXYNE.js.map} +0 -0
  868. /package/dist/{account-OCFXNHG7.js.map → account-OUKPRB7C.js.map} +0 -0
  869. /package/dist/{account-UE6DOQXK.js.map → account-WN5MJ5QN.js.map} +0 -0
  870. /package/dist/{account-assets-W7K2PUYB.js.map → account-assets-IWJWYNQ3.js.map} +0 -0
  871. /package/dist/{account-writes-QSJ74QFR.js.map → account-writes-IUIXIVRC.js.map} +0 -0
  872. /package/dist/{accounts-PVMTLDJU.js.map → accounts-4YRDRLHX.js.map} +0 -0
  873. /package/dist/{accounts-3DS67RX7.js.map → accounts-HEGADQ6E.js.map} +0 -0
  874. /package/dist/{accounts-55PDBEDN.js.map → accounts-OSVXKNSI.js.map} +0 -0
  875. /package/dist/{accounts-AK4QIG24.js.map → accounts-SJOO4MQX.js.map} +0 -0
  876. /package/dist/{accounts-FZCQNX3B.js.map → accounts-V7EOUTNL.js.map} +0 -0
  877. /package/dist/{actions-EG23YFYB.js.map → actions-5LYJ3U6G.js.map} +0 -0
  878. /package/dist/{active-entities-HR7NJJLU.js.map → active-entities-4KQQSMRZ.js.map} +0 -0
  879. /package/dist/{activecampaign-GPT5R647.js.map → activecampaign-CZHLHGT4.js.map} +0 -0
  880. /package/dist/{activities-DEWHKBID.js.map → activities-FRA33VZZ.js.map} +0 -0
  881. /package/dist/{ad-group-writes-QBHOPTT5.js.map → ad-group-writes-YQXBUA3Q.js.map} +0 -0
  882. /package/dist/{ad-groups-JZDUFT6J.js.map → ad-groups-NJR4ILEN.js.map} +0 -0
  883. /package/dist/{ad-writes-QYJO4IB3.js.map → ad-writes-TZV64CC2.js.map} +0 -0
  884. /package/dist/{add-UWTWG4VO.js.map → add-MZUSKY2L.js.map} +0 -0
  885. /package/dist/{add-IH6GAMK4.js.map → add-NAUSQKRS.js.map} +0 -0
  886. /package/dist/{ads-QKVNPHBH.js.map → ads-A2FXTQES.js.map} +0 -0
  887. /package/dist/{ads-F3VUMSEV.js.map → ads-PYTK3LJE.js.map} +0 -0
  888. /package/dist/{ads-UMSWEI5X.js.map → ads-Q7DD5VXU.js.map} +0 -0
  889. /package/dist/{adsets-FEVYHKAQ.js.map → adsets-ZHEVFOK4.js.map} +0 -0
  890. /package/dist/{advertisers-AJNDC3AX.js.map → advertisers-HSTND4HE.js.map} +0 -0
  891. /package/dist/{analytics-PEGA46W5.js.map → analytics-63Q3FJN4.js.map} +0 -0
  892. /package/dist/{analytics-XCQ3G5PM.js.map → analytics-GLJODEIM.js.map} +0 -0
  893. /package/dist/{animate-WS63CZ3Y.js.map → animate-EI6AYBDI.js.map} +0 -0
  894. /package/dist/{asset-writes-7RFZZYU7.js.map → asset-writes-MS45UKJ3.js.map} +0 -0
  895. /package/dist/{assign-2CZ5C43W.js.map → assign-7HT3XSSN.js.map} +0 -0
  896. /package/dist/{audience-size-FUHDVYLN.js.map → audience-size-DG7544D2.js.map} +0 -0
  897. /package/dist/{audiences-RSAUXKHR.js.map → audiences-2IVVS3SJ.js.map} +0 -0
  898. /package/dist/{audiences-7OS2ZJYO.js.map → audiences-RN745R53.js.map} +0 -0
  899. /package/dist/{audiences-6GVUZUCN.js.map → audiences-Z2TQT35L.js.map} +0 -0
  900. /package/dist/{audit-4L7IKIRY.js.map → audit-BIHMDO5K.js.map} +0 -0
  901. /package/dist/{audit-DECB5PP5.js.map → audit-ZYST7KCO.js.map} +0 -0
  902. /package/dist/{autocomplete-6XSIFXDA.js.map → autocomplete-5BKEMOQ3.js.map} +0 -0
  903. /package/dist/{avatars-LTV2TSO2.js.map → avatars-FQOCDWLW.js.map} +0 -0
  904. /package/dist/{bid-pricing-GC6YU3LW.js.map → bid-pricing-JEW7T2VR.js.map} +0 -0
  905. /package/dist/{brand-B4QKPCEC.js.map → brand-FR6BKWXN.js.map} +0 -0
  906. /package/dist/{brief-RYNGM4GX.js.map → brief-32IXDJ4J.js.map} +0 -0
  907. /package/dist/{businesses-42NZP6FP.js.map → businesses-HECSW3EL.js.map} +0 -0
  908. /package/dist/{campaign-groups-FHV5A3EC.js.map → campaign-groups-LYPVIZT5.js.map} +0 -0
  909. /package/dist/{campaign-writes-4B7DCAP2.js.map → campaign-writes-D5MM5LUH.js.map} +0 -0
  910. /package/dist/{campaign-writes-GKNH2EHV.js.map → campaign-writes-S7A6W5V3.js.map} +0 -0
  911. /package/dist/{campaigns-VNBJV5QD.js.map → campaigns-CMDF3P7Y.js.map} +0 -0
  912. /package/dist/{campaigns-TL37AY5Y.js.map → campaigns-LIICP5JU.js.map} +0 -0
  913. /package/dist/{campaigns-TO74Z7UH.js.map → campaigns-N72TOUQX.js.map} +0 -0
  914. /package/dist/{campaigns-7RV65SXR.js.map → campaigns-ZWJKBF3L.js.map} +0 -0
  915. /package/dist/{canvas-6XSA3VZE.js.map → canvas-3SNC3UUV.js.map} +0 -0
  916. /package/dist/{capabilities-6MOMJZFW.js.map → capabilities-GL7P3SWY.js.map} +0 -0
  917. /package/dist/{cards-CAOGPPG4.js.map → cards-RYQN5JLR.js.map} +0 -0
  918. /package/dist/{catalog-URTZYAPU.js.map → catalog-PWAWDK42.js.map} +0 -0
  919. /package/dist/{catalogs-5LWEXG5X.js.map → catalogs-SLPYHA7D.js.map} +0 -0
  920. /package/dist/{changes-WWZYTLC6.js.map → changes-WOD4EOSN.js.map} +0 -0
  921. /package/dist/{chatgpt-ZI4GWP6S.js.map → chatgpt-3GX4I6NH.js.map} +0 -0
  922. /package/dist/{chunk-MU2TTM6Z.js.map → chunk-34ARMQNL.js.map} +0 -0
  923. /package/dist/{chunk-5T6DUP7V.js.map → chunk-34MZGC2Y.js.map} +0 -0
  924. /package/dist/{chunk-GNTI4KST.js.map → chunk-4KBTW5NE.js.map} +0 -0
  925. /package/dist/{chunk-2LBQNTTH.js.map → chunk-4PAGS7QH.js.map} +0 -0
  926. /package/dist/{chunk-2GFJN2TR.js.map → chunk-53KV66ZZ.js.map} +0 -0
  927. /package/dist/{chunk-6IR7IQPV.js.map → chunk-5C4RRCKM.js.map} +0 -0
  928. /package/dist/{chunk-TPGFX47R.js.map → chunk-5I6XOSNI.js.map} +0 -0
  929. /package/dist/{chunk-ILGRC7LJ.js.map → chunk-5OE4Z7TP.js.map} +0 -0
  930. /package/dist/{chunk-JAC6JVCI.js.map → chunk-6OIKNJ7G.js.map} +0 -0
  931. /package/dist/{chunk-B42CHCXX.js.map → chunk-6S4B67KP.js.map} +0 -0
  932. /package/dist/{chunk-FHWYQSMY.js.map → chunk-77LXZAX2.js.map} +0 -0
  933. /package/dist/{chunk-5H6N36LS.js.map → chunk-7TVVYP7K.js.map} +0 -0
  934. /package/dist/{chunk-HBRXFQQV.js.map → chunk-7URHRPC7.js.map} +0 -0
  935. /package/dist/{chunk-GXAI3EII.js.map → chunk-7YMQEAGA.js.map} +0 -0
  936. /package/dist/{chunk-NTFNLVZG.js.map → chunk-A4O3JL6D.js.map} +0 -0
  937. /package/dist/{chunk-2DAWUWA4.js.map → chunk-ANRTDNPQ.js.map} +0 -0
  938. /package/dist/{chunk-GWLP45WQ.js.map → chunk-AQNTVM6S.js.map} +0 -0
  939. /package/dist/{chunk-ULIQNJ5J.js.map → chunk-BPDIY5CF.js.map} +0 -0
  940. /package/dist/{chunk-IXVVTPG6.js.map → chunk-CKHF7UXS.js.map} +0 -0
  941. /package/dist/{chunk-MKG57P2E.js.map → chunk-CUTTTFAU.js.map} +0 -0
  942. /package/dist/{chunk-IGCS3X4F.js.map → chunk-D32EWSMB.js.map} +0 -0
  943. /package/dist/{chunk-JBABLH5C.js.map → chunk-D55MN5IH.js.map} +0 -0
  944. /package/dist/{chunk-FWHEAR7F.js.map → chunk-DRQI2CJJ.js.map} +0 -0
  945. /package/dist/{chunk-ARPT74DG.js.map → chunk-ETI6DGR2.js.map} +0 -0
  946. /package/dist/{chunk-XRR5NN2V.js.map → chunk-FFTD7XDA.js.map} +0 -0
  947. /package/dist/{chunk-YXZV6YKH.js.map → chunk-FTKUHGTC.js.map} +0 -0
  948. /package/dist/{chunk-RJIFEHEG.js.map → chunk-GFYGVIT3.js.map} +0 -0
  949. /package/dist/{chunk-ORQ3WBM6.js.map → chunk-GGXPO4NQ.js.map} +0 -0
  950. /package/dist/{chunk-KICGV4JB.js.map → chunk-H56UJRLV.js.map} +0 -0
  951. /package/dist/{chunk-GR2BPVLX.js.map → chunk-HDMD6LXS.js.map} +0 -0
  952. /package/dist/{chunk-N2TXADL7.js.map → chunk-HFZZKYUX.js.map} +0 -0
  953. /package/dist/{chunk-DWPOAU4Z.js.map → chunk-IAYJKH4R.js.map} +0 -0
  954. /package/dist/{chunk-7M6GZI5B.js.map → chunk-IEPCI2EB.js.map} +0 -0
  955. /package/dist/{chunk-ZREKNWIE.js.map → chunk-IKADYUXK.js.map} +0 -0
  956. /package/dist/{chunk-OSQTSS27.js.map → chunk-J32CYEIH.js.map} +0 -0
  957. /package/dist/{chunk-3D5ABNNW.js.map → chunk-J5I3GYSJ.js.map} +0 -0
  958. /package/dist/{chunk-X3YYZLBH.js.map → chunk-JCVXKHVB.js.map} +0 -0
  959. /package/dist/{chunk-BRPSY35A.js.map → chunk-JESSFI7R.js.map} +0 -0
  960. /package/dist/{chunk-CDPM6OE6.js.map → chunk-K4QPBXV7.js.map} +0 -0
  961. /package/dist/{chunk-H3HA22Z3.js.map → chunk-KJ3J2DYM.js.map} +0 -0
  962. /package/dist/{chunk-BHEOF2MF.js.map → chunk-L43B2YGZ.js.map} +0 -0
  963. /package/dist/{chunk-OTRKBCUB.js.map → chunk-L7UD57TV.js.map} +0 -0
  964. /package/dist/{chunk-6IRB3MHG.js.map → chunk-LJYXGUQ3.js.map} +0 -0
  965. /package/dist/{chunk-H3PD2KOF.js.map → chunk-LNYM4PQS.js.map} +0 -0
  966. /package/dist/{chunk-T4YD5W33.js.map → chunk-MIXUMGJE.js.map} +0 -0
  967. /package/dist/{chunk-U5LSGCT3.js.map → chunk-MWJ6BCZJ.js.map} +0 -0
  968. /package/dist/{chunk-N2MGR7HT.js.map → chunk-O7WRA3JU.js.map} +0 -0
  969. /package/dist/{chunk-LDYI7BIQ.js.map → chunk-OADMSHME.js.map} +0 -0
  970. /package/dist/{chunk-R4RWQ6YX.js.map → chunk-OLPABGH3.js.map} +0 -0
  971. /package/dist/{chunk-SZET6NTF.js.map → chunk-ONGZKI5J.js.map} +0 -0
  972. /package/dist/{chunk-3GKAVXR3.js.map → chunk-OSZOUSK5.js.map} +0 -0
  973. /package/dist/{chunk-6MX37ZQZ.js.map → chunk-PK7YNQ2T.js.map} +0 -0
  974. /package/dist/{chunk-JTIWQLY5.js.map → chunk-PN3CHL5W.js.map} +0 -0
  975. /package/dist/{chunk-S3ZW3KTX.js.map → chunk-QMQSI4WA.js.map} +0 -0
  976. /package/dist/{chunk-C3EX5OKN.js.map → chunk-QUSDGZFS.js.map} +0 -0
  977. /package/dist/{chunk-P6KTCPJG.js.map → chunk-QXRSFH6M.js.map} +0 -0
  978. /package/dist/{chunk-22RM3UOO.js.map → chunk-QZ4YHQLW.js.map} +0 -0
  979. /package/dist/{chunk-3E74OM2E.js.map → chunk-RF3TP643.js.map} +0 -0
  980. /package/dist/{chunk-WBWEKZQ2.js.map → chunk-RIRSFFWA.js.map} +0 -0
  981. /package/dist/{chunk-B47TRSMB.js.map → chunk-ROHICQPK.js.map} +0 -0
  982. /package/dist/{chunk-V6TZRCAS.js.map → chunk-RP3PC54R.js.map} +0 -0
  983. /package/dist/{chunk-MZPS46OR.js.map → chunk-SIKCVWM3.js.map} +0 -0
  984. /package/dist/{chunk-EJBLF2LI.js.map → chunk-SOM4OTR5.js.map} +0 -0
  985. /package/dist/{chunk-Q5DFEVLE.js.map → chunk-SZZ7BBED.js.map} +0 -0
  986. /package/dist/{chunk-RYYRGQMM.js.map → chunk-TAGJYHVI.js.map} +0 -0
  987. /package/dist/{chunk-URKOGN5B.js.map → chunk-TB5JZTLN.js.map} +0 -0
  988. /package/dist/{chunk-KDAINT54.js.map → chunk-TQJLEVLA.js.map} +0 -0
  989. /package/dist/{chunk-X3GWGFZP.js.map → chunk-TW57RTKN.js.map} +0 -0
  990. /package/dist/{chunk-O43QFUOG.js.map → chunk-V3ANSXCB.js.map} +0 -0
  991. /package/dist/{chunk-D6YLVDVN.js.map → chunk-WSG4K2TR.js.map} +0 -0
  992. /package/dist/{chunk-XZAVBONI.js.map → chunk-WXSRSMY3.js.map} +0 -0
  993. /package/dist/{chunk-BMMXYR7A.js.map → chunk-WZXMZFVB.js.map} +0 -0
  994. /package/dist/{chunk-M45SOKI5.js.map → chunk-X3L5HYQM.js.map} +0 -0
  995. /package/dist/{chunk-6QINKM6T.js.map → chunk-Y2TOB4N5.js.map} +0 -0
  996. /package/dist/{chunk-RBB3UUYP.js.map → chunk-Z2LPYAN4.js.map} +0 -0
  997. /package/dist/{chunk-YD6OZSSY.js.map → chunk-ZICB4OI5.js.map} +0 -0
  998. /package/dist/{chunk-UYZ4FUC7.js.map → chunk-ZOCAGPS5.js.map} +0 -0
  999. /package/dist/{chunk-ME3K6XIS.js.map → chunk-ZZWZUTEP.js.map} +0 -0
  1000. /package/dist/{claim-YCK2XQUL.js.map → claim-QHYA5UTF.js.map} +0 -0
  1001. /package/dist/{companies-SWGL3MQT.js.map → companies-BNMAOQUQ.js.map} +0 -0
  1002. /package/dist/{company-XKEQKWPO.js.map → company-YANP3G62.js.map} +0 -0
  1003. /package/dist/{complete-CHEZWF5R.js.map → complete-ICZCBO6M.js.map} +0 -0
  1004. /package/dist/{config-NDL2YP37.js.map → config-GIETKZGS.js.map} +0 -0
  1005. /package/dist/{connect-GWLVOOU7.js.map → connect-ZXGEFS53.js.map} +0 -0
  1006. /package/dist/{conversation-QD4UJZ7S.js.map → conversation-YIWZIUIK.js.map} +0 -0
  1007. /package/dist/{conversion-report-76S5JOVT.js.map → conversion-report-E35RCZU7.js.map} +0 -0
  1008. /package/dist/{conversion-writes-6HX665JT.js.map → conversion-writes-MUD7WJDH.js.map} +0 -0
  1009. /package/dist/{conversions-BECU3XD2.js.map → conversions-B7HR6JMC.js.map} +0 -0
  1010. /package/dist/{conversions-QZJRF4WN.js.map → conversions-WU7DNFF7.js.map} +0 -0
  1011. /package/dist/{create-5QPEESSZ.js.map → create-EL47XN73.js.map} +0 -0
  1012. /package/dist/{create-ET3VCGQT.js.map → create-GU5MUZ7U.js.map} +0 -0
  1013. /package/dist/{create-4OA5DOSO.js.map → create-IKQ7A47F.js.map} +0 -0
  1014. /package/dist/{create-IJSH2LHP.js.map → create-TKQDLX7M.js.map} +0 -0
  1015. /package/dist/{creatives-L3XSN34M.js.map → creatives-PW6HB4JB.js.map} +0 -0
  1016. /package/dist/{creatives-SFPNXJ6Z.js.map → creatives-S4EGN44U.js.map} +0 -0
  1017. /package/dist/{creatives-AIRQ3FGH.js.map → creatives-VBD4T6C7.js.map} +0 -0
  1018. /package/dist/{credentials-Q2FM4DP3.js.map → credentials-57U2UQ7G.js.map} +0 -0
  1019. /package/dist/{crm-PQREUPOU.js.map → crm-JCYLJQ7K.js.map} +0 -0
  1020. /package/dist/{crm-7GTTSEHH.js.map → crm-LQTYPDMZ.js.map} +0 -0
  1021. /package/dist/{currency-BZUNQ4XJ.js.map → currency-5NYTOLEL.js.map} +0 -0
  1022. /package/dist/{custom-conversions-UHRBVUD2.js.map → custom-conversions-NT7ONTEX.js.map} +0 -0
  1023. /package/dist/{customers-BYNADWKU.js.map → customers-LP6I7POL.js.map} +0 -0
  1024. /package/dist/{delete-EZ525EJV.js.map → delete-PZ6GP7J6.js.map} +0 -0
  1025. /package/dist/{delete-2RAKL577.js.map → delete-WW4JYQMX.js.map} +0 -0
  1026. /package/dist/{delete-ZBYPC5AL.js.map → delete-XZNY426Q.js.map} +0 -0
  1027. /package/dist/{demographics-5XMZ2TBB.js.map → demographics-HZY2JEYQ.js.map} +0 -0
  1028. /package/dist/{discard-Q7R5VJ7I.js.map → discard-NRTGRVXR.js.map} +0 -0
  1029. /package/dist/{discover-PDSEJR2P.js.map → discover-5ZFAAPNG.js.map} +0 -0
  1030. /package/dist/{domain-MS3BKUYW.js.map → domain-YGKFTN6D.js.map} +0 -0
  1031. /package/dist/{download-F56SAC2G.js.map → download-XERSDEN3.js.map} +0 -0
  1032. /package/dist/{draft-44KTLX4P.js.map → draft-2EVXU5XB.js.map} +0 -0
  1033. /package/dist/{draft-RSKZSUOS.js.map → draft-CQWYTMSS.js.map} +0 -0
  1034. /package/dist/{draft-L6XXU2I6.js.map → draft-EL74RDAG.js.map} +0 -0
  1035. /package/dist/{draft-WOE7KQ7T.js.map → draft-GFZ3KMRX.js.map} +0 -0
  1036. /package/dist/{draft-CKFSZDVI.js.map → draft-JYZA3BFD.js.map} +0 -0
  1037. /package/dist/{draft-JBLWUO3J.js.map → draft-UNPTTHP4.js.map} +0 -0
  1038. /package/dist/{experiment-AZUKJ7ZO.js.map → experiment-YAX26BOO.js.map} +0 -0
  1039. /package/dist/{extract-2PG5JB2C.js.map → extract-QMY6WPTV.js.map} +0 -0
  1040. /package/dist/{facets-5CGKHFDQ.js.map → facets-QHM2IQ3E.js.map} +0 -0
  1041. /package/dist/{feedback-C7THFXTE.js.map → feedback-NLPTKWOH.js.map} +0 -0
  1042. /package/dist/{fetch-LMEYFSM5.js.map → fetch-72ZILZHO.js.map} +0 -0
  1043. /package/dist/{fit-DBA7FD3M.js.map → fit-AURKFPAY.js.map} +0 -0
  1044. /package/dist/{flows-TQASOYQP.js.map → flows-CZPXHOZW.js.map} +0 -0
  1045. /package/dist/{fonts-MPDK2DXR.js.map → fonts-NA26RQ4C.js.map} +0 -0
  1046. /package/dist/{forecast-OP2ECNM2.js.map → forecast-ARIHRQAX.js.map} +0 -0
  1047. /package/dist/{funding-BSAHWU35.js.map → funding-QDKFNQI2.js.map} +0 -0
  1048. /package/dist/{funnel-BLRQAZ65.js.map → funnel-4VQB3T3M.js.map} +0 -0
  1049. /package/dist/{ga4-YVKA3V4V.js.map → ga4-N6EBLN2W.js.map} +0 -0
  1050. /package/dist/{generate-VGGXTZBP.js.map → generate-IJLMJC4S.js.map} +0 -0
  1051. /package/dist/{get-DEELBPMG.js.map → get-LOEUOTG3.js.map} +0 -0
  1052. /package/dist/{get-YATZI6GN.js.map → get-W3VJIQBN.js.map} +0 -0
  1053. /package/dist/{google-ULLPGAXN.js.map → google-7VEPEBFV.js.map} +0 -0
  1054. /package/dist/{google-ads-IEQJEICD.js.map → google-ads-YBOJ3XXK.js.map} +0 -0
  1055. /package/dist/{gsc-OJDMSP6H.js.map → gsc-FILOUFCG.js.map} +0 -0
  1056. /package/dist/{history-LXRFZNW7.js.map → history-6LLGAK7B.js.map} +0 -0
  1057. /package/dist/{history-FPXZOUHT.js.map → history-H2SHADAM.js.map} +0 -0
  1058. /package/dist/{history-2LE4ELLB.js.map → history-LJG64M6P.js.map} +0 -0
  1059. /package/dist/{hubspot-MNREQEVI.js.map → hubspot-6JDARLIU.js.map} +0 -0
  1060. /package/dist/{ideas-4N7WMX3P.js.map → ideas-MTWJDRRK.js.map} +0 -0
  1061. /package/dist/{images-KVMFKQX5.js.map → images-RIFC6D3H.js.map} +0 -0
  1062. /package/dist/{ingest-VG4YGXB2.js.map → ingest-K45T4OLM.js.map} +0 -0
  1063. /package/dist/{ingest-GUJNPD6S.js.map → ingest-MSS52UO5.js.map} +0 -0
  1064. /package/dist/{insights-LZJZGNJZ.js.map → insights-AVNMRFQ4.js.map} +0 -0
  1065. /package/dist/{insights-H6M6VI43.js.map → insights-TBIT6DTF.js.map} +0 -0
  1066. /package/dist/{inspect-VODWKUQY.js.map → inspect-EBGYJOZ3.js.map} +0 -0
  1067. /package/dist/{intent-HXRSLFIO.js.map → intent-URHTU4AK.js.map} +0 -0
  1068. /package/dist/{job-UFGGBDG7.js.map → job-OJB6KIDV.js.map} +0 -0
  1069. /package/dist/{job-create-XM4NH322.js.map → job-create-C6FGCDW4.js.map} +0 -0
  1070. /package/dist/{job-status-47L5Z57J.js.map → job-status-4RJHESID.js.map} +0 -0
  1071. /package/dist/{keyword-gap-WUHMSTNR.js.map → keyword-gap-WXM6SN6A.js.map} +0 -0
  1072. /package/dist/{keyword-metrics-LOLNR24U.js.map → keyword-metrics-57MUTYMH.js.map} +0 -0
  1073. /package/dist/{keywords-for-site-PLTJBXVN.js.map → keywords-for-site-ABZS7O5B.js.map} +0 -0
  1074. /package/dist/{landing-JMH3WIK2.js.map → landing-AXCYLUQZ.js.map} +0 -0
  1075. /package/dist/{languages-SVTYYYOC.js.map → languages-6XTVTFZC.js.map} +0 -0
  1076. /package/dist/{leads-XPIBMZI7.js.map → leads-C5BUBBLZ.js.map} +0 -0
  1077. /package/dist/{learn-MOHK6DHI.js.map → learn-M64GVGPX.js.map} +0 -0
  1078. /package/dist/{line-item-writes-5RVCYHHH.js.map → line-item-writes-HYLWBQTM.js.map} +0 -0
  1079. /package/dist/{line-items-OESD2IJ6.js.map → line-items-Y4THDHSE.js.map} +0 -0
  1080. /package/dist/{link-PURCDO7A.js.map → link-BU7YCL2M.js.map} +0 -0
  1081. /package/dist/{linkedin-person-L22XA5LG.js.map → linkedin-person-FEIY7FYQ.js.map} +0 -0
  1082. /package/dist/{list-L5VZ35AO.js.map → list-BKIL7O4G.js.map} +0 -0
  1083. /package/dist/{list-KE6PQV2U.js.map → list-H3C345WG.js.map} +0 -0
  1084. /package/dist/{list-T5ZVVC4L.js.map → list-UGTDZ7YI.js.map} +0 -0
  1085. /package/dist/{locations-7EBZ6KRH.js.map → locations-F4365X4S.js.map} +0 -0
  1086. /package/dist/{locations-5SLLGWZO.js.map → locations-HOI7AUZ2.js.map} +0 -0
  1087. /package/dist/{log-D3WU36FX.js.map → log-54SJV6MW.js.map} +0 -0
  1088. /package/dist/{lookup-OU6CLATK.js.map → lookup-QNLX2535.js.map} +0 -0
  1089. /package/dist/{map-PT7JJYQR.js.map → map-BPPGQGDV.js.map} +0 -0
  1090. /package/dist/{mcp-62MSONPH.js.map → mcp-EXOMBMYL.js.map} +0 -0
  1091. /package/dist/{media-YKCCMLXL.js.map → media-MITWBYVZ.js.map} +0 -0
  1092. /package/dist/{media-DGV2AMZI.js.map → media-WGIEUEZW.js.map} +0 -0
  1093. /package/dist/{media-sources-DGVR3YPL.js.map → media-sources-XEC72K7X.js.map} +0 -0
  1094. /package/dist/{members-DAHPS3MB.js.map → members-VDON57BE.js.map} +0 -0
  1095. /package/dist/{meta-5TRG7RTQ.js.map → meta-NUBBKE2V.js.map} +0 -0
  1096. /package/dist/{metrics-WRERNMRK.js.map → metrics-V6FAZO5A.js.map} +0 -0
  1097. /package/dist/{models-SITHUNAA.js.map → models-TSMFIOZU.js.map} +0 -0
  1098. /package/dist/{normalize-ZOJ4YROH.js.map → normalize-632DD2HJ.js.map} +0 -0
  1099. /package/dist/{options-DTB2NYBL.js.map → options-TZYZQZ3M.js.map} +0 -0
  1100. /package/dist/{organization-5JHFNUOD.js.map → organization-FYRXSGB4.js.map} +0 -0
  1101. /package/dist/{output-7X5WPPCA.js.map → output-HZW7LNUL.js.map} +0 -0
  1102. /package/dist/{pages-6YMPZDEY.js.map → pages-UH6XEZBO.js.map} +0 -0
  1103. /package/dist/{performance-W6CJEUHR.js.map → performance-JKXHQIAV.js.map} +0 -0
  1104. /package/dist/{performance-VFDK5PHT.js.map → performance-OF3N43OP.js.map} +0 -0
  1105. /package/dist/{pixels-WTTLC4O5.js.map → pixels-KXA6R3G3.js.map} +0 -0
  1106. /package/dist/{pixels-DZDVNIVL.js.map → pixels-PYNK73UG.js.map} +0 -0
  1107. /package/dist/{plan-JAWESWJN.js.map → plan-4OYUV2EF.js.map} +0 -0
  1108. /package/dist/{preview-JZXGR4KN.js.map → preview-7E4E3QPT.js.map} +0 -0
  1109. /package/dist/{preview-PUF62HJU.js.map → preview-FPBM75L2.js.map} +0 -0
  1110. /package/dist/{promoted-tweet-writes-FW4BAA5O.js.map → promoted-tweet-writes-IJRBFK7W.js.map} +0 -0
  1111. /package/dist/{promoted-tweets-LYHKCVNV.js.map → promoted-tweets-7PYH3RPV.js.map} +0 -0
  1112. /package/dist/{properties-Z5S3LRJ5.js.map → properties-RDOGNY2O.js.map} +0 -0
  1113. /package/dist/{publish-S2KD5PCN.js.map → publish-MNSDFPEQ.js.map} +0 -0
  1114. /package/dist/{query-3QFT42PG.js.map → query-GMGWJW3X.js.map} +0 -0
  1115. /package/dist/{query-KKXCMH3Q.js.map → query-K7R5GQ4E.js.map} +0 -0
  1116. /package/dist/{query-QXKGVHZL.js.map → query-PO3RT7BR.js.map} +0 -0
  1117. /package/dist/{questionnaire-U7UYICEA.js.map → questionnaire-4OH6K2BF.js.map} +0 -0
  1118. /package/dist/{read-ENUS7P3L.js.map → read-MU5XGWMK.js.map} +0 -0
  1119. /package/dist/{reddit-AF2PPR3K.js.map → reddit-JFFMZLJS.js.map} +0 -0
  1120. /package/dist/{refresh-UC7OTPXS.js.map → refresh-EJ7WKW3H.js.map} +0 -0
  1121. /package/dist/{release-FQOJ2FJ5.js.map → release-AFRLCZWB.js.map} +0 -0
  1122. /package/dist/{relevant-pages-OFKZYWR3.js.map → relevant-pages-4YGN3I2U.js.map} +0 -0
  1123. /package/dist/{remove-H3SU4GJK.js.map → remove-QD4PITBL.js.map} +0 -0
  1124. /package/dist/{reopen-M2PZEHKF.js.map → reopen-JSC6AVJC.js.map} +0 -0
  1125. /package/dist/{research-ILZZTO6Q.js.map → research-MMFUFZGS.js.map} +0 -0
  1126. /package/dist/{research-2N5HAFSB.js.map → research-SRISCVBM.js.map} +0 -0
  1127. /package/dist/{reset-XAKAEDPH.js.map → reset-752CNET3.js.map} +0 -0
  1128. /package/dist/{reset-JN437DOZ.js.map → reset-R3TQAHRU.js.map} +0 -0
  1129. /package/dist/{resolve-WVE6D7CP.js.map → resolve-EWHSJNBX.js.map} +0 -0
  1130. /package/dist/{retry-PMJ22IN4.js.map → retry-DVHDVHVP.js.map} +0 -0
  1131. /package/dist/{retry-ILL2ZATG.js.map → retry-PVULTONO.js.map} +0 -0
  1132. /package/dist/{rules-Y75KR2PC.js.map → rules-4YTY57FM.js.map} +0 -0
  1133. /package/dist/{run-OCCY7JHY.js.map → run-PCZRYL42.js.map} +0 -0
  1134. /package/dist/{run-2AIXS3KE.js.map → run-PRSAUWAJ.js.map} +0 -0
  1135. /package/dist/{schedule-WV6NZ4CK.js.map → schedule-6YTZBCZA.js.map} +0 -0
  1136. /package/dist/{scheduled-agents-MZZMHN3T.js.map → scheduled-agents-XCPU57LU.js.map} +0 -0
  1137. /package/dist/{schema-ADRFE3AV.js.map → schema-4PS5BDG3.js.map} +0 -0
  1138. /package/dist/{search-GGWTLVG7.js.map → search-IMZD5RGD.js.map} +0 -0
  1139. /package/dist/{sends-4ZO6BNZ4.js.map → sends-I2B6F5NW.js.map} +0 -0
  1140. /package/dist/{setup-links-76AJJR5Z.js.map → setup-links-PTL6RF2J.js.map} +0 -0
  1141. /package/dist/{shared-UPMEBTVP.js.map → shared-Z7INVKCZ.js.map} +0 -0
  1142. /package/dist/{shopify-Q3XMCPHI.js.map → shopify-SDZZ5HTA.js.map} +0 -0
  1143. /package/dist/{site-I4HFMTE5.js.map → site-NGQ7K6UD.js.map} +0 -0
  1144. /package/dist/{sitemaps-P3K5Z4TW.js.map → sitemaps-EOMSRKOD.js.map} +0 -0
  1145. /package/dist/{sites-TURWC53D.js.map → sites-6M73AONG.js.map} +0 -0
  1146. /package/dist/{sources-GGLP5NQU.js.map → sources-NKFSCI6M.js.map} +0 -0
  1147. /package/dist/{sources-ORL5AEH5.js.map → sources-O4CQ5KSX.js.map} +0 -0
  1148. /package/dist/{stats-XNKAJD2Z.js.map → stats-MFEH2TSW.js.map} +0 -0
  1149. /package/dist/{status-LSHCACMZ.js.map → status-DLYRPGFS.js.map} +0 -0
  1150. /package/dist/{stock-RZH4SEGS.js.map → stock-RDCDVBHX.js.map} +0 -0
  1151. /package/dist/{studies-5G67ODR2.js.map → studies-SSA3SR2L.js.map} +0 -0
  1152. /package/dist/{studio-D2OMFCZZ.js.map → studio-MBHPDGMN.js.map} +0 -0
  1153. /package/dist/{sync-MK7JTH3U.js.map → sync-BEW3TZP7.js.map} +0 -0
  1154. /package/dist/{sync-QVEUQKU5.js.map → sync-SI25TKY5.js.map} +0 -0
  1155. /package/dist/{sync-definition-EFAJ744M.js.map → sync-definition-RECCA3QH.js.map} +0 -0
  1156. /package/dist/{tag-manager-3GIW6BPB.js.map → tag-manager-JFC6YYVP.js.map} +0 -0
  1157. /package/dist/{tags-5HX7TDJN.js.map → tags-IJIGZYR3.js.map} +0 -0
  1158. /package/dist/{tags-EOIC4EQK.js.map → tags-K4HIKHNU.js.map} +0 -0
  1159. /package/dist/{tags-G4HMOLZF.js.map → tags-OTA55BQ6.js.map} +0 -0
  1160. /package/dist/{tags-BE6L5NLG.js.map → tags-QF2V4B3M.js.map} +0 -0
  1161. /package/dist/{tags-PF6UJWCF.js.map → tags-SK7WXMBS.js.map} +0 -0
  1162. /package/dist/{targeting-constants-RJS2STR5.js.map → targeting-constants-RF2732EW.js.map} +0 -0
  1163. /package/dist/{targeting-criteria-DOHSND62.js.map → targeting-criteria-7BUUYDYC.js.map} +0 -0
  1164. /package/dist/{targets-7AL4HPAW.js.map → targets-7V3NCQSD.js.map} +0 -0
  1165. /package/dist/{terms-AATAGKPT.js.map → terms-XFL6QO7A.js.map} +0 -0
  1166. /package/dist/{testimonials-BNYHKXD2.js.map → testimonials-XYD5DLBJ.js.map} +0 -0
  1167. /package/dist/{top-companies-ASSEFHI3.js.map → top-companies-LI26TONY.js.map} +0 -0
  1168. /package/dist/{transcript-OTAKTTSA.js.map → transcript-FTHDWMGU.js.map} +0 -0
  1169. /package/dist/{triggers-JQYC4JLT.js.map → triggers-3LHJVK5P.js.map} +0 -0
  1170. /package/dist/{tweets-MLDLLLDB.js.map → tweets-6PQHJXJC.js.map} +0 -0
  1171. /package/dist/{unlink-FVHHULLC.js.map → unlink-BMOUBGWO.js.map} +0 -0
  1172. /package/dist/{unstage-65DUBYNZ.js.map → unstage-O23ILHCY.js.map} +0 -0
  1173. /package/dist/{unstage-FIRVPNRC.js.map → unstage-YEW5KXJL.js.map} +0 -0
  1174. /package/dist/{update-EO5LVV34.js.map → update-2IWZA5UU.js.map} +0 -0
  1175. /package/dist/{update-RA6TX5NV.js.map → update-G7YZICSU.js.map} +0 -0
  1176. /package/dist/{update-G7RMT4OC.js.map → update-T5INCQJZ.js.map} +0 -0
  1177. /package/dist/{update-OD75FSPH.js.map → update-UTQVTG45.js.map} +0 -0
  1178. /package/dist/{upload-X33VIDOB.js.map → upload-UXYJDA2U.js.map} +0 -0
  1179. /package/dist/{url-options-4J3FRXHO.js.map → url-options-Y7I5EL55.js.map} +0 -0
  1180. /package/dist/{url-params-IBE4HUKK.js.map → url-params-PE4XAQNH.js.map} +0 -0
  1181. /package/dist/{videos-NITQKILV.js.map → videos-AHOLXU42.js.map} +0 -0
  1182. /package/dist/{videos-RGCF3EAE.js.map → videos-EVPJHY3B.js.map} +0 -0
  1183. /package/dist/{viewer-check-AKVX3XFW.js.map → viewer-check-NA4TMNY4.js.map} +0 -0
  1184. /package/dist/{web-QVR2EQ7X.js.map → web-7EODEH25.js.map} +0 -0
  1185. /package/dist/{winning-ads-3R4RU3FL.js.map → winning-ads-5UKX6QV7.js.map} +0 -0
  1186. /package/dist/{write-commands-XLZCRVTU.js.map → write-commands-LHEJESKL.js.map} +0 -0
  1187. /package/dist/{write-commands-OBQPQUIE.js.map → write-commands-SD6DXVNK.js.map} +0 -0
  1188. /package/dist/{x-747NTJKH.js.map → x-R72UTFQT.js.map} +0 -0
@@ -1,3510 +0,0 @@
1
- import {
2
- LOGO_POSITIONS,
3
- MIN_LEGIBLE_SHARE,
4
- PLACEMENT_DEFECTS,
5
- PLACEMENT_EDGES,
6
- PLACEMENT_ELEMENTS,
7
- chooseLogoSpot,
8
- contrastRatio,
9
- deliveredSize,
10
- designerSpots,
11
- fitArtwork,
12
- greyTable,
13
- hexLuma,
14
- inflatedWords,
15
- inkLuma,
16
- legibleShare,
17
- logoArtwork,
18
- logoBoxOn,
19
- logoSlotLine,
20
- logoSpotClean,
21
- pickLogoVariant,
22
- placeInSlot,
23
- placementProblems,
24
- plateColour,
25
- slotAround,
26
- spreadUnder,
27
- straightEdgeIn,
28
- textColourSource,
29
- usesTextColour
30
- } from "./chunk-X3GWGFZP.js";
31
- import {
32
- FRAME_CUT,
33
- bandViolations,
34
- blockingArea,
35
- blockingPlacements,
36
- boxesOfLine,
37
- buttonShape,
38
- bytesOf,
39
- headlineBox,
40
- isButtonLine,
41
- readTextBoxes,
42
- roleKey,
43
- shownBoxes,
44
- withWordmark
45
- } from "./chunk-GWLP45WQ.js";
46
- import {
47
- askAboutImages
48
- } from "./chunk-DLM5OSHM.js";
49
- import {
50
- IMAGE_GENERATE_MODELS,
51
- IMAGE_TIER_CREDITS,
52
- MODEL_REGISTRY,
53
- SIZE_MATCH_MODEL,
54
- SUBJECT_BOX_READER_MODEL,
55
- imagePictureCredits,
56
- modelIdsAccepted,
57
- supportedAspectRatios
58
- } from "./chunk-MCJ5I5LR.js";
59
- import {
60
- ImageRef,
61
- callBackendExec,
62
- defineNode,
63
- delegated
64
- } from "./chunk-EL3TDR5S.js";
65
-
66
- // src/engine/nodes/remote/image.ts
67
- import { z as z2 } from "zod";
68
-
69
- // src/engine/nodes/remote/registry-params.ts
70
- import { z } from "zod";
71
- function registryParamShape(kind, overrides = {}) {
72
- const specs = Object.values(MODEL_REGISTRY[kind]);
73
- const byParam = /* @__PURE__ */ new Map();
74
- for (const spec of specs) {
75
- for (const [name, schema] of Object.entries(spec.params)) {
76
- byParam.set(name, [...byParam.get(name) ?? [], schema]);
77
- }
78
- }
79
- const shape = {};
80
- for (const [name, schemas] of byParam) {
81
- const type = overrides[name] ?? unionOf(schemas);
82
- const requiredByAll = specs.every((spec) => spec.required.includes(name));
83
- shape[name] = requiredByAll ? type : type.optional();
84
- }
85
- return shape;
86
- }
87
- function unionOf(schemas) {
88
- const kinds = [...new Set(schemas.map((schema) => schema.kind))];
89
- if (kinds.length > 1) {
90
- const [first, second, ...rest] = kinds.map((k) => unionOf(schemas.filter((s) => s.kind === k)));
91
- return z.union([first, second, ...rest]);
92
- }
93
- switch (kinds[0]) {
94
- case "string":
95
- return stringUnion(schemas);
96
- case "number":
97
- return numberUnion(schemas);
98
- case "boolean":
99
- return z.boolean();
100
- default:
101
- return z.unknown();
102
- }
103
- }
104
- function stringUnion(schemas) {
105
- if (schemas.some((schema) => !schema.enum)) return z.string();
106
- const values = [...new Set(schemas.flatMap((schema) => schema.enum ?? []))];
107
- return z.enum(values);
108
- }
109
- function numberUnion(schemas) {
110
- if (schemas.some((schema) => !schema.enum)) return z.number();
111
- const values = [...new Set(schemas.flatMap((schema) => schema.enum ?? []))].sort((a, b) => a - b);
112
- return z.literal(values);
113
- }
114
-
115
- // src/engine/nodes/remote/image.ts
116
- var imageModelEnum = z2.enum(IMAGE_GENERATE_MODELS.flatMap(modelIdsAccepted));
117
- var ImageGenerateParams = z2.object({
118
- model: imageModelEnum,
119
- ...registryParamShape("image_generate", {
120
- prompt: z2.string().min(1),
121
- // Recraft v4 vector controls, sent as the provider's own `controls` block. The
122
- // registry types them as JSON; this is their shape.
123
- rgb_colors: z2.array(z2.array(z2.number().int().min(0).max(255))),
124
- background_rgb_color: z2.array(z2.number().int().min(0).max(255))
125
- })
126
- }).strict();
127
- var PRO_QUALITY = "max";
128
- function creditsPerImage(params) {
129
- return params.quality === PRO_QUALITY ? IMAGE_TIER_CREDITS.pro : imagePictureCredits(String(params.model));
130
- }
131
- function imagesPerCall(params) {
132
- return "n" in params && typeof params.n === "number" ? params.n : 1;
133
- }
134
- var imageGenerateNode = delegated({
135
- id: "image_generate",
136
- version: "2.2.0",
137
- category: "image",
138
- summary: "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.",
139
- when_to_use: "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 \u2014 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 \u2014 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.",
140
- // `reference` is one image or an ordered array of images. The backend forwards
141
- // each as a separate `image_url` to the provider (OpenRouter accepts many).
142
- inputs: z2.object({ reference: z2.union([ImageRef, z2.array(ImageRef).min(1)]).optional() }).loose(),
143
- params: ImageGenerateParams,
144
- outputs: z2.object({ images: z2.array(ImageRef).min(1) }).strict(),
145
- outputKinds: { images: "image" },
146
- // Per image: `n` asks one call for several, and the provider bills each (measured: n=3
147
- // cost exactly 3x n=1, prompt tokens included). Usage-billed, so this is only the pre-run
148
- // quote; the charge is the provider's reported cost.
149
- cost: ({ params }) => ({
150
- credits: creditsPerImage(params) * imagesPerCall(params),
151
- seconds_estimate: 10
152
- })
153
- });
154
-
155
- // src/engine/nodes/local/staticFormat.ts
156
- import sharp4 from "sharp";
157
- import { z as z4 } from "zod";
158
-
159
- // src/engine/nodes/local/lib/node-steps.ts
160
- import sharp2 from "sharp";
161
-
162
- // src/engine/nodes/local/lib/subject-boxes.ts
163
- import sharp from "sharp";
164
- import { z as z3 } from "zod";
165
- var SUBJECT_KINDS = ["person", "face", "animal", "product"];
166
- var SubjectBoxSchema = z3.object({
167
- kind: z3.enum(SUBJECT_KINDS),
168
- label: z3.string(),
169
- x0: z3.number().min(0).max(1),
170
- y0: z3.number().min(0).max(1),
171
- x1: z3.number().min(0).max(1),
172
- y1: z3.number().min(0).max(1)
173
- }).strict();
174
- var GRID = 1e3;
175
- var ReaderAnswer = z3.object({
176
- items: z3.array(z3.object({ kind: z3.enum(SUBJECT_KINDS), label: z3.string(), box_2d: z3.array(z3.number()).length(4) }))
177
- });
178
- var fraction = (value) => Math.min(1, Math.max(0, value / GRID));
179
- function subjectBoxesFromReader(answer) {
180
- const parsed = ReaderAnswer.safeParse(answer);
181
- if (!parsed.success) return null;
182
- return parsed.data.items.map(({ kind, label, box_2d }) => {
183
- const [ymin = 0, xmin = 0, ymax = 0, xmax = 0] = box_2d;
184
- return {
185
- kind,
186
- label,
187
- x0: fraction(Math.min(xmin, xmax)),
188
- y0: fraction(Math.min(ymin, ymax)),
189
- x1: fraction(Math.max(xmin, xmax)),
190
- y1: fraction(Math.max(ymin, ymax))
191
- };
192
- });
193
- }
194
- var SUBJECT_BOX_PROMPT = [
195
- "Find every person, every face, every animal and every product or object the ad is selling in this image.",
196
- "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.",
197
- "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.",
198
- 'Reply with only this JSON: {"items":[{"kind":"person|face|animal|product","label":"...","box_2d":[ymin,xmin,ymax,xmax]}]}'
199
- ].join("\n");
200
- var READ_EDGE = 1536;
201
- async function readSubjectBoxes(image, opts = {}) {
202
- let jpeg;
203
- try {
204
- const resized = await sharp(image).resize(READ_EDGE, READ_EDGE, { fit: "inside", withoutEnlargement: true }).jpeg({ quality: 90 }).toBuffer();
205
- jpeg = resized.toString("base64");
206
- } catch {
207
- return { status: "not_checked" };
208
- }
209
- for (let attempt = 0; attempt < 2; attempt++) {
210
- const answer = await askAboutImages(SUBJECT_BOX_READER_MODEL, [jpeg], SUBJECT_BOX_PROMPT, opts.onSpend, 6e4, {
211
- effort: "minimal"
212
- });
213
- const boxes = subjectBoxesFromReader(answer);
214
- if (boxes) return { status: "read", boxes };
215
- }
216
- return { status: "not_checked" };
217
- }
218
-
219
- // src/engine/nodes/local/lib/node-steps.ts
220
- async function timedStep(run, name, key, fn, opts = {}) {
221
- const t0 = Date.now();
222
- let credits = 0;
223
- const stepCtx = {
224
- ...run.ctx,
225
- reportCharge: (c) => {
226
- credits += c;
227
- run.ctx.reportCharge?.(c);
228
- }
229
- };
230
- const go = (suffix) => fn(suffix, stepCtx);
231
- const { value, cached } = run.ctx.steps ? await run.ctx.steps.run(name, key, go, opts) : { value: await go(name), cached: false };
232
- run.steps.push({ name, cached, credits, ms: Date.now() - t0 });
233
- return value;
234
- }
235
- var isRead = (reading) => reading.status === "read";
236
- async function subjectsStep(run, image, bytes) {
237
- const read = await timedStep(
238
- run,
239
- "subjects",
240
- { image: image.sha256 },
241
- () => readSubjectBoxes(bytes, { onSpend: (u) => run.usage.push(u) }),
242
- { keep: isRead }
243
- );
244
- return read.status === "read" ? read.boxes : null;
245
- }
246
- async function imageOf(ref, node) {
247
- const at = ref.path ?? ref.url;
248
- if (!at) throw new Error(`${node}: a picture it was given has no file`);
249
- const bytes = await bytesOf(at);
250
- const meta = await sharp2(bytes).metadata();
251
- return { bytes, size: { width: meta.width ?? 0, height: meta.height ?? 0 } };
252
- }
253
- async function rawOf(bytes, size) {
254
- const { data, info } = await sharp2(bytes).removeAlpha().resize(size.width, size.height, { fit: "fill", kernel: "lanczos3" }).raw().toBuffer({ resolveWithObject: true });
255
- return { data, width: size.width, height: size.height, channels: info.channels };
256
- }
257
- function pngOf(raw) {
258
- return sharp2(raw.data, { raw: { width: raw.width, height: raw.height, channels: raw.channels } }).png().toBuffer();
259
- }
260
-
261
- // src/engine/nodes/local/lib/plate-panels.ts
262
- var READ_WIDTH = 288;
263
- var FLAT = 2;
264
- var STEP = 3;
265
- var RANGE = 12;
266
- var MIN_AREA = 0.015;
267
- var MIN_FILL = 0.6;
268
- function blockMean(img, x, y, f, c) {
269
- let sum = 0;
270
- for (let dy = 0; dy < f; dy++) {
271
- for (let dx = 0; dx < f; dx++) sum += img.data[((y + dy) * img.width + x + dx) * img.channels + c] ?? 0;
272
- }
273
- return sum / (f * f);
274
- }
275
- function shrunk(img, f) {
276
- const width = Math.floor(img.width / f);
277
- const height = Math.floor(img.height / f);
278
- const data = Buffer.alloc(width * height * 3);
279
- for (let i = 0; i < width * height; i++) {
280
- const x = i % width;
281
- const y = (i - x) / width;
282
- for (let c = 0; c < 3; c++) data[i * 3 + c] = Math.round(blockMean(img, x * f, y * f, f, c));
283
- }
284
- return { data, width, height, channels: 3 };
285
- }
286
- function spreadAt(grey, width, x, y) {
287
- let sum = 0;
288
- let squares = 0;
289
- for (let dy = -2; dy <= 2; dy++) {
290
- for (let dx = -2; dx <= 2; dx++) {
291
- const v = grey[(y + dy) * width + x + dx] ?? 0;
292
- sum += v;
293
- squares += v * v;
294
- }
295
- }
296
- const mean = sum / 25;
297
- return Math.sqrt(Math.max(0, squares / 25 - mean * mean));
298
- }
299
- function flatOf(img) {
300
- const { width, height } = img;
301
- const grey = new Float32Array(width * height);
302
- for (let i = 0; i < grey.length; i++)
303
- 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);
304
- const flat = new Uint8Array(width * height);
305
- for (let y = 2; y < height - 2; y++) {
306
- for (let x = 2; x < width - 2; x++) flat[y * width + x] = spreadAt(grey, width, x, y) < FLAT ? 1 : 0;
307
- }
308
- return flat;
309
- }
310
- function take(r, img, i, x, y) {
311
- r.count++;
312
- r.x0 = Math.min(r.x0, x);
313
- r.x1 = Math.max(r.x1, x);
314
- r.y0 = Math.min(r.y0, y);
315
- r.y1 = Math.max(r.y1, y);
316
- for (let c = 0; c < 3; c++) {
317
- const v = img.data[i * 3 + c] ?? 0;
318
- r.lo[c] = Math.min(r.lo[c] ?? 255, v);
319
- r.hi[c] = Math.max(r.hi[c] ?? 0, v);
320
- }
321
- }
322
- var neighbours = (i, x, width, height) => [x > 0 ? i - 1 : -1, x < width - 1 ? i + 1 : -1, i - width, i + width].filter((j) => j >= 0 && j < width * height);
323
- function regionFrom(img, flat, seen, seed) {
324
- const { width, height } = img;
325
- const r = { x0: width, y0: height, x1: -1, y1: -1, count: 0, range: 0, lo: [255, 255, 255], hi: [0, 0, 0] };
326
- const near = (a, b) => [0, 1, 2].every((c) => Math.abs((img.data[a * 3 + c] ?? 0) - (img.data[b * 3 + c] ?? 0)) <= STEP);
327
- seen[seed] = 1;
328
- const stack = [seed];
329
- for (let i = stack.pop(); i !== void 0; i = stack.pop()) {
330
- const x = i % width;
331
- take(r, img, i, x, (i - x) / width);
332
- for (const j of neighbours(i, x, width, height)) {
333
- if (!flat[j] || seen[j] || !near(i, j)) continue;
334
- seen[j] = 1;
335
- stack.push(j);
336
- }
337
- }
338
- const range = Math.max(...[0, 1, 2].map((c) => (r.hi[c] ?? 0) - (r.lo[c] ?? 0)));
339
- return { x0: r.x0, y0: r.y0, x1: r.x1, y1: r.y1, count: r.count, range };
340
- }
341
- function isPanel(r, width, height) {
342
- const inside = r.x0 > 2 && r.y0 > 2 && r.x1 < width - 3 && r.y1 < height - 3;
343
- const box = (r.x1 - r.x0 + 1) * (r.y1 - r.y0 + 1);
344
- return inside && box >= MIN_AREA * width * height && r.count >= MIN_FILL * box && r.range <= RANGE;
345
- }
346
- function platePanels(img) {
347
- const f = Math.max(1, Math.round(img.width / READ_WIDTH));
348
- const small = f > 1 || img.channels !== 3 ? shrunk(img, f) : img;
349
- const flat = flatOf(small);
350
- const seen = new Uint8Array(flat.length);
351
- const panels = [];
352
- for (let i = 0; i < flat.length; i++) {
353
- if (!flat[i] || seen[i]) continue;
354
- const r = regionFrom(small, flat, seen, i);
355
- if (!isPanel(r, small.width, small.height)) continue;
356
- panels.push({
357
- x0: r.x0 / small.width,
358
- y0: r.y0 / small.height,
359
- x1: (r.x1 + 1) / small.width,
360
- y1: (r.y1 + 1) / small.height,
361
- area: (r.x1 - r.x0 + 1) * (r.y1 - r.y0 + 1)
362
- });
363
- }
364
- return panels.sort((a, b) => b.area - a.area).map(({ area: _area, ...span }) => span);
365
- }
366
-
367
- // src/engine/nodes/local/lib/subject-crop.ts
368
- var SUBJECT_PAD = 0.02;
369
- function ratioOf(ratio) {
370
- const [w, h] = ratio.split(":").map(Number);
371
- if (!w || !h || !Number.isFinite(w) || !Number.isFinite(h)) throw new Error(`not a W:H ratio: "${ratio}"`);
372
- return w / h;
373
- }
374
- var unionOf2 = (spans) => spans.length === 0 ? null : { from: Math.min(...spans.map((s) => s.from)), to: Math.max(...spans.map((s) => s.to)) };
375
- function placeAxis(full, length, hard, soft, core) {
376
- const clampFull = (v) => Math.min(full - length, Math.max(0, v));
377
- const want = soft ? soft.to - soft.from <= length ? (soft.from + soft.to) / 2 - length / 2 : soft.from - SUBJECT_PAD * full : (core.from + core.to) / 2 - length / 2;
378
- if (!hard) return { at: Math.round(clampFull(want)), fits: true };
379
- const pad = SUBJECT_PAD * full;
380
- for (const p of [pad, 0]) {
381
- const lo = Math.max(0, hard.to + p - length);
382
- const hi = Math.min(full - length, hard.from - p);
383
- if (lo <= hi + 1e-6) return { at: Math.round(Math.min(hi, Math.max(lo, want))), fits: true };
384
- }
385
- return { at: Math.round(clampFull((hard.from + hard.to) / 2 - length / 2)), fits: false };
386
- }
387
- function subjectCrop(plate, format, subjects, opts = {}) {
388
- const cards = (opts.panels ?? []).map((p) => ({ kind: "product", label: "card", ...p }));
389
- if (cards.length > 0) {
390
- const withCards = cropAround(plate, format, [...subjects ?? [], ...cards], opts);
391
- if (withCards.fits) return withCards;
392
- }
393
- return cropAround(plate, format, subjects, opts);
394
- }
395
- function cropAround(plate, format, subjects, opts) {
396
- const r = ratioOf(format);
397
- let width = plate.width;
398
- let height = Math.round(plate.width / r);
399
- if (height > plate.height) {
400
- height = plate.height;
401
- width = Math.round(plate.height * r);
402
- }
403
- const boxes = subjects ?? [];
404
- const px = (b) => ({ from: b.x0 * plate.width, to: b.x1 * plate.width });
405
- const py = (b) => ({ from: b.y0 * plate.height, to: b.y1 * plate.height });
406
- const hardY = boxes.map((b) => b.kind === "person" ? { from: py(b).from, to: py(b).from } : py(b));
407
- const core = opts.core ?? { x0: 0, y0: 0, x1: 1, y1: 1 };
408
- const x = placeAxis(plate.width, width, unionOf2(boxes.map(px)), unionOf2(boxes.map(px)), {
409
- from: core.x0 * plate.width,
410
- to: core.x1 * plate.width
411
- });
412
- const y = placeAxis(plate.height, height, unionOf2(hardY), unionOf2(boxes.map(py)), {
413
- from: core.y0 * plate.height,
414
- to: core.y1 * plate.height
415
- });
416
- const rect = { x: x.at, y: y.at, width, height };
417
- const cut = boxes.filter((b, i) => {
418
- const hy = hardY[i] ?? py(b);
419
- return px(b).from < rect.x - 0.5 || px(b).to > rect.x + rect.width + 0.5 || hy.from < rect.y - 0.5 || hy.to > rect.y + rect.height + 0.5;
420
- }).map((b) => b.label);
421
- return { rect, render: renderRect(plate, rect, format, opts.renderRatios), fits: cut.length === 0, cut };
422
- }
423
- function renderRect(plate, rect, format, ratios) {
424
- if (!ratios || ratios.includes(format)) return { ...rect, ratio: format };
425
- const r = rect.width / rect.height;
426
- let best = null;
427
- for (const ratio of ratios) {
428
- const c = ratioOf(ratio);
429
- const width = c <= r ? rect.width : Math.round(rect.height * c);
430
- const height = c <= r ? Math.round(rect.width / c) : rect.height;
431
- if (width > plate.width || height > plate.height) continue;
432
- const place = (from, length, inner, full) => Math.min(
433
- Math.min(from, full - length),
434
- Math.max(Math.max(0, from + inner - length), from - (length - inner) / 2)
435
- );
436
- const candidate = {
437
- x: Math.round(place(rect.x, width, rect.width, plate.width)),
438
- y: Math.round(place(rect.y, height, rect.height, plate.height)),
439
- width,
440
- height,
441
- ratio
442
- };
443
- if (!best || width * height < best.width * best.height) best = candidate;
444
- }
445
- return best ?? { ...rect, ratio: format };
446
- }
447
-
448
- // src/engine/nodes/local/lib/picture-memo.ts
449
- var ids = /* @__PURE__ */ new WeakMap();
450
- var nextId = 0;
451
- function pictureId(picture) {
452
- const known = ids.get(picture);
453
- if (known !== void 0) return known;
454
- const id = nextId++;
455
- ids.set(picture, id);
456
- return id;
457
- }
458
- function remembered() {
459
- const readings = /* @__PURE__ */ new WeakMap();
460
- return (picture, what, read) => {
461
- const known = readings.get(picture) ?? /* @__PURE__ */ new Map();
462
- readings.set(picture, known);
463
- const kept = known.get(what);
464
- if (kept !== void 0) return kept;
465
- const value = read();
466
- known.set(what, value);
467
- return value;
468
- };
469
- }
470
-
471
- // src/engine/nodes/local/lib/words-band.ts
472
- var GROUND_REACH = 0.06;
473
- var LAID = 24;
474
- var BAND_EDGE = 0.5;
475
- var BAND_CLEAR = 0.1;
476
- var SOLID = 0.7;
477
- var RING = 0.01;
478
- var LOOK_STRIP = 0.1;
479
- var greyAt = (img, i) => 0.299 * (img.data[i * img.channels] ?? 0) + 0.587 * (img.data[i * img.channels + 1] ?? 0) + 0.114 * (img.data[i * img.channels + 2] ?? 0);
480
- function laidMap(aligned, cut) {
481
- const { width, height } = cut;
482
- const laid = new Uint8Array(width * height);
483
- for (let i = 0; i < laid.length; i++) laid[i] = Math.abs(greyAt(aligned, i) - greyAt(cut, i)) > LAID ? 1 : 0;
484
- return { laid, width, height };
485
- }
486
- var rectOf = (s, width, height) => ({
487
- x0: Math.floor(s.x0 * width),
488
- y0: Math.floor(s.y0 * height),
489
- x1: Math.ceil(s.x1 * width),
490
- y1: Math.ceil(s.y1 * height)
491
- });
492
- var clipped = (r, width, height) => ({
493
- x0: Math.max(0, r.x0),
494
- y0: Math.max(0, r.y0),
495
- x1: Math.min(width, r.x1),
496
- y1: Math.min(height, r.y1)
497
- });
498
- var holds = (r, x, y) => x >= r.x0 && x < r.x1 && y >= r.y0 && y < r.y1;
499
- function laidIn(m, r) {
500
- const c = clipped(r, m.width, m.height);
501
- let laid = 0;
502
- 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;
503
- return { laid, area: Math.max(0, c.x1 - c.x0) * Math.max(0, c.y1 - c.y0) };
504
- }
505
- function share(m, r) {
506
- const { laid, area: area2 } = laidIn(m, r);
507
- return area2 > 0 ? laid / area2 : 0;
508
- }
509
- function laidAround(m, box) {
510
- const reach = {
511
- x0: box.x0 - GROUND_REACH,
512
- y0: box.y0 - GROUND_REACH,
513
- x1: box.x1 + GROUND_REACH,
514
- y1: box.y1 + GROUND_REACH
515
- };
516
- const outer = laidIn(m, rectOf(reach, m.width, m.height));
517
- const inner = laidIn(m, rectOf(box, m.width, m.height));
518
- const ring = outer.area - inner.area;
519
- return ring > 0 ? (outer.laid - inner.laid) / ring : 0;
520
- }
521
- function past(r, side, depth) {
522
- if (side === 0) return { ...r, y0: r.y0 - depth, y1: r.y0 };
523
- if (side === 1) return { ...r, y0: r.y1, y1: r.y1 + depth };
524
- if (side === 2) return { ...r, x0: r.x0 - depth, x1: r.x0 };
525
- return { ...r, x0: r.x1, x1: r.x1 + depth };
526
- }
527
- function grown(r, side) {
528
- if (side === 0) return { ...r, y0: r.y0 - 1 };
529
- if (side === 1) return { ...r, y1: r.y1 + 1 };
530
- if (side === 2) return { ...r, x0: r.x0 - 1 };
531
- return { ...r, x1: r.x1 + 1 };
532
- }
533
- var atFrameEdge = (m, r, side) => side === 0 ? r.y0 <= 0 : side === 1 ? r.y1 >= m.height : side === 2 ? r.x0 <= 0 : r.x1 >= m.width;
534
- function bandUnder(m, box) {
535
- const block = clipped(rectOf(box, m.width, m.height), m.width, m.height);
536
- const inset = Math.min(Math.floor((block.y1 - block.y0) / 4), Math.floor((block.x1 - block.x0 - 1) / 2));
537
- const start = { x0: block.x0 + inset, y0: block.y0 + inset, x1: block.x1 - inset, y1: block.y1 - inset };
538
- let r = start;
539
- for (let grew = true; grew; ) {
540
- grew = false;
541
- for (let side = 0; side < 4; side++) {
542
- if (atFrameEdge(m, r, side) || share(m, past(r, side, 1)) < BAND_EDGE) continue;
543
- r = grown(r, side);
544
- grew = true;
545
- }
546
- }
547
- const outgrown = [r.y0 < start.y0, r.y1 > start.y1, r.x0 < start.x0, r.x1 > start.x1];
548
- const depth = Math.max(2, Math.round(RING * Math.max(m.width, m.height)));
549
- for (let side = 0; side < 4; side++) {
550
- if (!(outgrown[side] || atFrameEdge(m, r, side)) || share(m, past(r, side, depth)) >= BAND_CLEAR) return null;
551
- }
552
- if (share(m, r) < SOLID) return null;
553
- return { x0: r.x0 / m.width, y0: r.y0 / m.height, x1: r.x1 / m.width, y1: r.y1 / m.height };
554
- }
555
- function sumsOf(g, strip, skip, ch) {
556
- const { width } = g.cut;
557
- const sums = { n: 0, x: 0, y: 0, xx: 0, xy: 0 };
558
- for (let y = strip.y0; y < strip.y1; y++) {
559
- for (let x = strip.x0; x < strip.x1; x++) {
560
- if (skip.some((r) => holds(r, x, y))) continue;
561
- const i = y * width + x;
562
- const u = g.cut.data[i * g.cut.channels + ch] ?? 0;
563
- const v = g.aligned.data[i * g.aligned.channels + ch] ?? 0;
564
- sums.n++;
565
- sums.x += u;
566
- sums.y += v;
567
- sums.xx += u * u;
568
- sums.xy += u * v;
569
- }
570
- }
571
- return sums;
572
- }
573
- function toneOf(g, strip, skip) {
574
- const c = clipped(strip, g.cut.width, g.cut.height);
575
- return [0, 1, 2].map((ch) => {
576
- const s = sumsOf(g, c, skip, ch);
577
- if (s.n === 0) return { a: 0, b: 0 };
578
- const spread = s.xx - s.x * s.x / s.n;
579
- const a = spread > s.n ? Math.min(1, Math.max(0, (s.xy - s.x * s.y / s.n) / spread)) : 0;
580
- return { a, b: (s.y - a * s.x) / s.n };
581
- });
582
- }
583
- var LIGHT_DEPTH = 0.02;
584
- function ringPast(r, dx, dy, depth) {
585
- if (dy < 0) return { ...r, y0: r.y1, y1: r.y1 + depth };
586
- if (dy > 0) return { ...r, y0: r.y0 - depth, y1: r.y0 };
587
- if (dx < 0) return { ...r, x0: r.x1, x1: r.x1 + depth };
588
- return { ...r, x0: r.x0 - depth, x1: r.x0 };
589
- }
590
- function lightOn(g, ring) {
591
- const { width, height } = g.cut;
592
- const c = clipped(ring, width, height);
593
- return [0, 1, 2].map((ch) => {
594
- const ratios = [];
595
- for (let y = c.y0; y < c.y1; y++) {
596
- for (let x = c.x0; x < c.x1; x++) {
597
- const i = y * width + x;
598
- const under = g.cut.data[i * g.cut.channels + ch] ?? 0;
599
- if (under >= 16) ratios.push((g.aligned.data[i * g.aligned.channels + ch] ?? 0) / under);
600
- }
601
- }
602
- ratios.sort((a, b) => a - b);
603
- return Math.min(2, Math.max(0.5, ratios[Math.floor(ratios.length / 2)] ?? 1));
604
- });
605
- }
606
- function edgeLeft(r, dx, dy, width, height) {
607
- const deep = Math.max(1, Math.round(LOOK_STRIP * (r.y1 - r.y0)));
608
- const wide = Math.max(1, Math.round(LOOK_STRIP * (r.x1 - r.x0)));
609
- const across2 = r.x0 <= 2 && r.x1 >= width - 2;
610
- const down = r.y0 <= 2 && r.y1 >= height - 2;
611
- if (dy < 0 && across2 && r.y1 >= height - 2)
612
- return { strip: { ...r, y0: r.y1 - deep }, zone: { ...r, y0: r.y1 + dy } };
613
- if (dy > 0 && across2 && r.y0 <= 2) return { strip: { ...r, y1: r.y0 + deep }, zone: { ...r, y1: r.y0 + dy } };
614
- if (dx < 0 && down && r.x1 >= width - 2) return { strip: { ...r, x0: r.x1 - wide }, zone: { ...r, x0: r.x1 + dx } };
615
- if (dx > 0 && down && r.x0 <= 2) return { strip: { ...r, x1: r.x0 + wide }, zone: { ...r, x1: r.x0 + dx } };
616
- return null;
617
- }
618
- var CORNER = 0.5;
619
- function floodCorner(shape, w, c, reach, bare) {
620
- const near = (x, y) => (x - c.x) * c.sx >= 0 && (x - c.x) * c.sx < reach && (y - c.y) * c.sy >= 0 && (y - c.y) * c.sy < reach;
621
- shape[c.y * w + c.x] = 0;
622
- const stack = [c.y * w + c.x];
623
- for (let at = stack.pop(); at !== void 0; at = stack.pop()) {
624
- const x = at % w;
625
- const y = (at - x) / w;
626
- for (const [nx, ny] of [
627
- [x + 1, y],
628
- [x - 1, y],
629
- [x, y + 1],
630
- [x, y - 1]
631
- ]) {
632
- if (!near(nx, ny) || shape[ny * w + nx] === 0 || !bare(nx, ny)) continue;
633
- shape[ny * w + nx] = 0;
634
- stack.push(ny * w + nx);
635
- }
636
- }
637
- }
638
- function shapeOf(g, r) {
639
- const w = r.x1 - r.x0;
640
- const h = r.y1 - r.y0;
641
- const shape = new Uint8Array(Math.max(0, w * h)).fill(1);
642
- if (w <= 0 || h <= 0) return shape;
643
- const reach = Math.floor(CORNER * Math.min(w, h));
644
- const bare = (x, y) => {
645
- const i = (r.y0 + y) * g.cut.width + r.x0 + x;
646
- return Math.abs(greyAt(g.aligned, i) - greyAt(g.cut, i)) <= LAID;
647
- };
648
- const corners = [
649
- { x: 0, y: 0, sx: 1, sy: 1, open: r.x0 > 0 && r.y0 > 0 },
650
- { x: w - 1, y: 0, sx: -1, sy: 1, open: r.x1 < g.cut.width && r.y0 > 0 },
651
- { x: 0, y: h - 1, sx: 1, sy: -1, open: r.x0 > 0 && r.y1 < g.cut.height },
652
- { x: w - 1, y: h - 1, sx: -1, sy: -1, open: r.x1 < g.cut.width && r.y1 < g.cut.height }
653
- ];
654
- for (const c of corners) if (c.open && bare(c.x, c.y)) floodCorner(shape, w, c, reach, bare);
655
- return shape;
656
- }
657
- function eachOf(r, shape, at) {
658
- const w = r.x1 - r.x0;
659
- for (let k = 0; k < shape.length; k++) if (shape[k]) at(r.x0 + k % w, r.y0 + Math.floor(k / w));
660
- }
661
- var SOFT_EDGE = 3e-3;
662
- function eachIn(r, at) {
663
- for (let y = r.y0; y < r.y1; y++) for (let x = r.x0; x < r.x1; x++) at(x, y);
664
- }
665
- function moveBand(g, move) {
666
- const { width, height } = g.cut;
667
- const r = clipped(rectOf(move.band, width, height), width, height);
668
- const soft = Math.max(1, Math.round(SOFT_EDGE * Math.max(width, height)));
669
- const left = clipped({ x0: r.x0 - soft, y0: r.y0 - soft, x1: r.x1 + soft, y1: r.y1 + soft }, width, height);
670
- const dx = Math.round(move.dx * width);
671
- const dy = Math.round(move.dy * height);
672
- const data = Buffer.alloc(width * height * 3);
673
- if (g.out.channels === 3) g.out.data.copy(data, 0, 0, width * height * 3);
674
- else
675
- for (let i = 0; i < width * height; i++) g.out.data.copy(data, i * 3, i * g.out.channels, i * g.out.channels + 3);
676
- const shape = shapeOf(g, r);
677
- const edge = edgeLeft(r, dx, dy, width, height);
678
- const tone = edge ? toneOf(
679
- g,
680
- edge.strip,
681
- move.words.map((w) => rectOf(w, width, height))
682
- ) : [];
683
- const light = lightOn(g, ringPast(left, dx, dy, Math.max(4, Math.round(LIGHT_DEPTH * height))));
684
- eachIn(left, (x, y) => {
685
- const i = y * width + x;
686
- const band = edge !== null && holds(edge.zone, x, y);
687
- for (let ch = 0; ch < 3; ch++) {
688
- const under = g.cut.data[i * g.cut.channels + ch] ?? 0;
689
- const t = tone[ch] ?? { a: 0, b: 0 };
690
- const v = band ? t.a * under + t.b : under * (light[ch] ?? 1);
691
- data[i * 3 + ch] = Math.max(0, Math.min(255, Math.round(v)));
692
- }
693
- });
694
- eachOf(r, shape, (x, y) => {
695
- const to = { x: x + dx, y: y + dy };
696
- if (to.x < 0 || to.y < 0 || to.x >= width || to.y >= height) return;
697
- const from = y * width + x;
698
- g.aligned.data.copy(data, (to.y * width + to.x) * 3, from * g.aligned.channels, from * g.aligned.channels + 3);
699
- });
700
- return { data, width, height, channels: 3 };
701
- }
702
-
703
- // src/engine/nodes/local/lib/safe-fit.ts
704
- import sharp3 from "sharp";
705
- var FIT_HEADROOM = 0.01;
706
- var MIN_FIT_SCALE = 0.85;
707
- var MIN_FLAT_FIT_SCALE = 0.65;
708
- function boxesToPlace(boxes, format, opts = {}) {
709
- if (!opts.copy) return [...boxes];
710
- const placements = blockingPlacements(opts.placements);
711
- const past2 = (box) => bandViolations([box], format, { placements })[0];
712
- const cut = (box) => (past2(box)?.clearance ?? 1) <= FRAME_CUT;
713
- const logoWords = opts.copy.filter((l) => roleKey(l.role) === "logo").map((l) => l.text);
714
- const read = withWordmark(boxes, logoWords);
715
- const buttons = new Set(opts.copy.filter(isButtonLine).flatMap((line) => boxesOfLine(line, read)));
716
- return shownBoxes(read, opts.copy, (box) => !past2(box)).filter((shown) => !shown.supporting || cut(shown.box)).map((shown) => buttons.has(shown.box) ? buttonShape(shown.box) : shown.box);
717
- }
718
- function targetArea(format, placements) {
719
- const area2 = blockingArea(format, placements);
720
- const covered = area2.covered;
721
- if (!covered) return area2;
722
- return { ...area2, top: covered.top, bottom: covered.bottom, ...covered.rail ? { rail: covered.rail } : {} };
723
- }
724
- function planSafeFit(boxes, format, opts = {}) {
725
- const area2 = targetArea(format, opts.placements);
726
- const violations = bandViolations(boxes, format, { placements: blockingPlacements(opts.placements) });
727
- if (!violations.some((v) => v.covered || v.clearance <= FRAME_CUT)) return null;
728
- const rail = area2.rail && boxes.some((b) => b.y1 > (area2.rail?.from ?? 1)) ? area2.rail.width : 0;
729
- const union = {
730
- x0: Math.min(...boxes.map((b) => b.x0)),
731
- y0: Math.min(...boxes.map((b) => b.y0)),
732
- x1: Math.max(...boxes.map((b) => b.x1)),
733
- y1: Math.max(...boxes.map((b) => b.y1))
734
- };
735
- const band = {
736
- x0: area2.left + FIT_HEADROOM,
737
- y0: area2.top + FIT_HEADROOM,
738
- x1: 1 - Math.max(area2.right, rail) - FIT_HEADROOM,
739
- y1: 1 - area2.bottom - FIT_HEADROOM
740
- };
741
- const scale = Math.min(1, (band.y1 - band.y0) / (union.y1 - union.y0), (band.x1 - band.x0) / (union.x1 - union.x0));
742
- if (opts.contain) return containedFit(union, band, opts.minScale ?? MIN_FIT_SCALE, scale);
743
- if (scale < (opts.minScale ?? MIN_FIT_SCALE)) return null;
744
- return {
745
- scale,
746
- x: offset(scale, union.x0, union.x1, band.x0, band.x1),
747
- y: offset(scale, union.y0, union.y1, band.y0, band.y1)
748
- };
749
- }
750
- var CONTAIN_STEP = 5e-3;
751
- function containedFit(union, band, minScale, from) {
752
- const start = (scale, lo0, hi0, b0, b1) => {
753
- const lo = Math.max(0, b0 - scale * lo0);
754
- const hi = Math.min(1 - scale, b1 - scale * hi0);
755
- if (lo > hi + 1e-9) return null;
756
- return Math.min(hi, Math.max(lo, 0));
757
- };
758
- for (let scale = Math.min(1, from); scale >= minScale - 1e-9; scale -= CONTAIN_STEP) {
759
- const x = start(scale, union.x0, union.x1, band.x0, band.x1);
760
- const y = start(scale, union.y0, union.y1, band.y0, band.y1);
761
- if (x !== null && y !== null) {
762
- const cx = Math.min(
763
- Math.min(1 - scale, band.x1 - scale * union.x1),
764
- Math.max(Math.max(0, band.x0 - scale * union.x0), (1 - scale) / 2)
765
- );
766
- return { scale, x: cx, y };
767
- }
768
- }
769
- return null;
770
- }
771
- function offset(scale, from, to, bandFrom, bandTo) {
772
- const lo = bandFrom - scale * from;
773
- const hi = bandTo - scale * to;
774
- if (lo > hi) return (lo + hi) / 2;
775
- return Math.min(hi, Math.max(lo, (1 - scale) / 2));
776
- }
777
- var PLAIN_DEPTH = 0.03;
778
- var PLAIN_DEPTH_STEP = 36;
779
- var PLAIN_JUMP = 60;
780
- var PLAIN_JUMPS = 2;
781
- function edgeBorders(img, side) {
782
- const along = side === "top" || side === "bottom" ? img.width : img.height;
783
- const across2 = side === "top" || side === "bottom" ? img.height : img.width;
784
- const depth = Math.max(1, Math.round(PLAIN_DEPTH * across2));
785
- const at = (i, d) => {
786
- const inward = side === "top" || side === "left" ? d : across2 - 1 - d;
787
- const [x, y] = side === "top" || side === "bottom" ? [i, inward] : [inward, i];
788
- return (y * img.width + x) * img.channels;
789
- };
790
- const step = (a, b) => {
791
- let sum = 0;
792
- for (let c = 0; c < Math.min(3, img.channels); c++)
793
- sum += Math.abs((img.data[a + c] ?? 0) - (img.data[b + c] ?? 0));
794
- return sum;
795
- };
796
- let jumps = 0;
797
- for (let i = 0; i < along; i++) {
798
- for (let d = 1; d <= depth; d++) if (step(at(i, 0), at(i, d)) > PLAIN_DEPTH_STEP) return null;
799
- if (i > 0 && step(at(i - 1, 0), at(i, 0)) > PLAIN_JUMP) jumps++;
800
- }
801
- return jumps;
802
- }
803
- function plainEdge(img, side) {
804
- const borders = edgeBorders(img, side);
805
- return borders !== null && borders <= PLAIN_JUMPS;
806
- }
807
- async function minFitScale(image) {
808
- const { data, info } = await sharp3(image).removeAlpha().raw().toBuffer({ resolveWithObject: true });
809
- const raw = { data, width: info.width, height: info.height, channels: info.channels };
810
- const flat = ["top", "bottom", "left", "right"].every((side) => edgeBorders(raw, side) === 0);
811
- return flat ? MIN_FLAT_FIT_SCALE : MIN_FIT_SCALE;
812
- }
813
- async function fitPicture(image, fit) {
814
- const { width = 0, height = 0 } = await sharp3(image).metadata();
815
- const sw = Math.max(1, Math.round(width * fit.scale));
816
- const sh = Math.max(1, Math.round(height * fit.scale));
817
- const px = Math.round(fit.x * width);
818
- const py = Math.round(fit.y * height);
819
- const left = Math.max(0, -px);
820
- const top = Math.max(0, -py);
821
- const w = Math.min(sw, width - px) - left;
822
- const h = Math.min(sh, height - py) - top;
823
- const shrunk2 = await sharp3(image).removeAlpha().resize(sw, sh, { fit: "fill", kernel: "lanczos3" }).extract({ left, top, width: w, height: h }).raw().toBuffer({ resolveWithObject: true });
824
- const pad = { left: Math.max(0, px), top: Math.max(0, py) };
825
- const extend = { ...pad, right: width - pad.left - w, bottom: height - pad.top - h };
826
- const raw = { data: shrunk2.data, width: w, height: h, channels: shrunk2.info.channels };
827
- const sides = ["top", "bottom", "left", "right"].filter((side) => extend[side] > 0);
828
- if (!sides.every((side) => plainEdge(raw, side))) return null;
829
- return sharp3(shrunk2.data, { raw: { width: w, height: h, channels: shrunk2.info.channels } }).extend({ ...extend, extendWith: "copy" }).png().toBuffer();
830
- }
831
-
832
- // src/engine/nodes/local/lib/words-layer.ts
833
- var inSpans = (spans, fx, fy) => spans.some((s) => fx >= s.x0 && fx <= s.x1 && fy >= s.y0 && fy <= s.y1);
834
- function centresIn(lo, hi, size) {
835
- const inside = new Uint8Array(size);
836
- for (let t = 0; t < size; t++) {
837
- const f = (t + 0.5) / size;
838
- inside[t] = f >= lo && f <= hi ? 1 : 0;
839
- }
840
- return inside;
841
- }
842
- function spanMask(spans, width, height) {
843
- const mask = new Uint8Array(width * height);
844
- for (const s of spans) {
845
- const across2 = centresIn(s.x0, s.x1, width);
846
- const down = centresIn(s.y0, s.y1, height);
847
- for (let y = 0; y < height; y++) {
848
- if (down[y]) for (let x = 0; x < width; x++) mask[y * width + x] ||= across2[x] ?? 0;
849
- }
850
- }
851
- return mask;
852
- }
853
- function taps(u, v, width, height) {
854
- const x = Math.min(width - 1, Math.max(0, u));
855
- const y = Math.min(height - 1, Math.max(0, v));
856
- const x0 = Math.floor(x);
857
- const y0 = Math.floor(y);
858
- const x1 = Math.min(width - 1, x0 + 1);
859
- const y1 = Math.min(height - 1, y0 + 1);
860
- const fx = x - x0;
861
- const fy = y - y0;
862
- return {
863
- at: [y0 * width + x0, y0 * width + x1, y1 * width + x0, y1 * width + x1],
864
- w: [(1 - fx) * (1 - fy), fx * (1 - fy), (1 - fx) * fy, fx * fy]
865
- };
866
- }
867
- function tapped(values, t, stride = 1, c = 0, missing = 0) {
868
- let sum = 0;
869
- for (let k = 0; k < 4; k++) sum += (t.w[k] ?? 0) * (values[(t.at[k] ?? 0) * stride + c] ?? missing);
870
- return sum;
871
- }
872
- function grayOf(img) {
873
- const data = new Float32Array(img.width * img.height);
874
- for (let i = 0; i < data.length; i++) {
875
- const o = i * img.channels;
876
- data[i] = 0.299 * (img.data[o] ?? 0) + 0.587 * (img.data[o + 1] ?? 0) + 0.114 * (img.data[o + 2] ?? 0);
877
- }
878
- return { data, width: img.width, height: img.height };
879
- }
880
- function shrink(g, edge) {
881
- const f = Math.max(1, Math.ceil(Math.max(g.width, g.height) / edge));
882
- if (f === 1) return g;
883
- const width = Math.floor(g.width / f);
884
- const height = Math.floor(g.height / f);
885
- const data = new Float32Array(width * height);
886
- for (let i = 0; i < width * height; i++) {
887
- const x = i % width * f;
888
- const y = Math.floor(i / width) * f;
889
- let sum = 0;
890
- for (let j = 0; j < f; j++) {
891
- const row = (y + j) * g.width + x;
892
- for (let k = 0; k < f; k++) sum += g.data[row + k] ?? 0;
893
- }
894
- data[i] = sum / (f * f);
895
- }
896
- return { data, width, height };
897
- }
898
- var JUDGED_MAX = 2e4;
899
- function judgedPixels(g, exclude) {
900
- const mx = Math.ceil(g.width * 0.04);
901
- const my = Math.ceil(g.height * 0.04);
902
- const step = g.width * g.height > JUDGED_MAX ? 2 : 1;
903
- const out = [];
904
- for (let i = 0; i < g.width * g.height; i++) {
905
- const x = i % g.width;
906
- const y = Math.floor(i / g.width);
907
- if (x % step !== 0 || y % step !== 0) continue;
908
- if (x < mx || y < my || x >= g.width - mx || y >= g.height - my) continue;
909
- if (!inSpans(exclude, x / g.width, y / g.height)) out.push(i);
910
- }
911
- const rows = [];
912
- const starts = [];
913
- out.forEach((i, j) => {
914
- const y = Math.floor(i / g.width);
915
- if (rows[rows.length - 1] === y) return;
916
- rows.push(y);
917
- starts.push(j);
918
- });
919
- starts.push(out.length);
920
- return {
921
- at: Int32Array.from(out),
922
- xs: Int32Array.from(out, (i) => i % g.width),
923
- rows: Int32Array.from(rows),
924
- starts: Int32Array.from(starts)
925
- };
926
- }
927
- function axisOf(origin, scale, count, size) {
928
- const near = new Int32Array(count);
929
- const at = new Int32Array(count);
930
- const frac = new Float64Array(count);
931
- for (let t = 0; t < count; t++) {
932
- const p = origin + scale * t;
933
- near[t] = Math.min(size - 1, Math.max(0, Math.round(p)));
934
- const q = Math.min(size - 1.001, Math.max(0, p));
935
- at[t] = q | 0;
936
- frac[t] = q - (at[t] ?? 0);
937
- }
938
- return { near, at, frac };
939
- }
940
- var MISFIT_CAP = 40;
941
- var LINEUP_FLAT = 1.5;
942
- function withFlat(g) {
943
- const flat = new Uint8Array(g.width * g.height);
944
- for (let i = 0; i < flat.length; i++) {
945
- const x = i % g.width;
946
- const y = (i - x) / g.width;
947
- if (x === 0 || y === 0 || x === g.width - 1 || y === g.height - 1) continue;
948
- let sum = 0;
949
- let square = 0;
950
- for (let k = 0; k < 9; k++) {
951
- const v = g.data[(y + Math.floor(k / 3) - 1) * g.width + x + k % 3 - 1] ?? 0;
952
- sum += v;
953
- square += v * v;
954
- }
955
- flat[i] = Math.sqrt(Math.max(0, square / 9 - (sum / 9) ** 2)) < LINEUP_FLAT ? 1 : 0;
956
- }
957
- return { ...g, flat };
958
- }
959
- function misfit(cut, render, judged, k, c, cap = MISFIT_CAP, beat = Number.POSITIVE_INFINITY, above = Number.POSITIVE_INFINITY) {
960
- const cx = cut.width / 2;
961
- const cy = cut.height / 2;
962
- const ox = cx - c.scale * cx + c.dx * k;
963
- const oy = cy - c.scale * cy + c.dy * k;
964
- const cols = axisOf(ox, c.scale, cut.width, render.width);
965
- const rows = axisOf(oy, c.scale, cut.height, render.height);
966
- const look = { cut, render, judged, cols, most: cap * cap };
967
- const count = judged.at.length;
968
- const acc = { sum: 0, n: 0 };
969
- for (let r = 0; r < judged.rows.length; r++) {
970
- const from = judged.starts[r] ?? 0;
971
- const least = acc.sum / (acc.n + count - from);
972
- if (least >= beat || least > above) return Number.POSITIVE_INFINITY;
973
- rowMisfit(look, rows, judged.rows[r] ?? 0, from, judged.starts[r + 1] ?? count, acc);
974
- }
975
- return acc.n > 0 ? acc.sum / acc.n : Number.POSITIVE_INFINITY;
976
- }
977
- function bilinear(data, i, width, fx, fy) {
978
- const top = (data[i] ?? 0) * (1 - fx) + (data[i + 1] ?? 0) * fx;
979
- const bottom = (data[i + width] ?? 0) * (1 - fx) + (data[i + width + 1] ?? 0) * fx;
980
- return top * (1 - fy) + bottom * fy;
981
- }
982
- function rowMisfit(s, rows, y, from, to, acc) {
983
- const { width, data, flat } = s.render;
984
- const { near, at, frac } = s.cols;
985
- const flatRow = (rows.near[y] ?? 0) * width;
986
- const row = (rows.at[y] ?? 0) * width;
987
- const fy = rows.frac[y] ?? 0;
988
- for (let j = from; j < to; j++) {
989
- const x = s.judged.xs[j] ?? 0;
990
- if (flat?.[flatRow + (near[x] ?? 0)]) continue;
991
- const d = (s.cut.data[s.judged.at[j] ?? 0] ?? 0) - bilinear(data, row + (at[x] ?? 0), width, frac[x] ?? 0, fy);
992
- acc.sum += Math.min(d * d, s.most);
993
- acc.n++;
994
- }
995
- }
996
- var MAX_SHIFT = 0.03;
997
- var MAX_SCALE_OFF = 0.03;
998
- var LEVELS = [
999
- { edge: 128, scales: [-0.03, -0.02, -0.01, 0, 0.01, 0.02, 0.03], reach: null },
1000
- { edge: 256, scales: [-5e-3, 0, 5e-3], reach: 2 },
1001
- { edge: 512, scales: [-25e-4, 0, 25e-4], reach: 1 }
1002
- ];
1003
- function searchLevel(cut, render, k, level, centre, exclude) {
1004
- const judged = judgedPixels(cut, exclude);
1005
- const reach = level.reach ?? Math.ceil(MAX_SHIFT * Math.max(cut.width, cut.height));
1006
- let best = centre;
1007
- let score = Number.POSITIVE_INFINITY;
1008
- const atCentre = misfit(cut, render, judged, k, centre);
1009
- const side = 2 * reach + 1;
1010
- for (const ds of level.scales) {
1011
- const scale = centre.scale + ds;
1012
- if (Math.abs(scale - 1) > MAX_SCALE_OFF + 1e-9) continue;
1013
- for (let s = 0; s < side * side; s++) {
1014
- const c = { scale, dx: centre.dx + (s % side - reach) / k, dy: centre.dy + (Math.floor(s / side) - reach) / k };
1015
- const m = misfit(cut, render, judged, k, c, MISFIT_CAP, score, atCentre);
1016
- if (m < score) {
1017
- score = m;
1018
- best = c;
1019
- }
1020
- }
1021
- }
1022
- return { best, score };
1023
- }
1024
- function registerToSource(render, cut, exclude) {
1025
- return lineUps(render, `${pictureId(cut)} ${JSON.stringify(exclude)}`, () => lineUp(render, cut, exclude));
1026
- }
1027
- var lineUps = remembered();
1028
- var warps = remembered();
1029
- function lineUp(render, cut, exclude) {
1030
- const full = { cut: grayOf(cut), render: grayOf(render) };
1031
- let best = { scale: 1, dx: 0, dy: 0 };
1032
- let finest = { cut: full.cut, render: full.render, k: 1 };
1033
- for (const level of LEVELS) {
1034
- const c = shrink(full.cut, level.edge);
1035
- const r = withFlat(shrink(full.render, level.edge));
1036
- const k = c.width / cut.width;
1037
- best = searchLevel(c, r, k, level, best, exclude).best;
1038
- finest = { cut: c, render: r, k };
1039
- }
1040
- const judged = judgedPixels(finest.cut, exclude);
1041
- const residual = misfit(finest.cut, finest.render, judged, finest.k, best, Number.POSITIVE_INFINITY);
1042
- return { ...best, residual: Math.sqrt(residual) };
1043
- }
1044
- function bilinearAxis(centre, scale, shift, size) {
1045
- const lo = new Int32Array(size);
1046
- const hi = new Int32Array(size);
1047
- const frac = new Float64Array(size);
1048
- for (let t = 0; t < size; t++) {
1049
- const p = Math.min(size - 1, Math.max(0, centre + scale * (t - centre) + shift));
1050
- lo[t] = Math.floor(p);
1051
- hi[t] = Math.min(size - 1, (lo[t] ?? 0) + 1);
1052
- frac[t] = p - (lo[t] ?? 0);
1053
- }
1054
- return { lo, hi, frac };
1055
- }
1056
- function warpToCut(render, fit) {
1057
- return warps(render, `${fit.scale} ${fit.dx} ${fit.dy}`, () => warped(render, fit));
1058
- }
1059
- function warped(render, fit) {
1060
- const { width, height } = render;
1061
- const out = Buffer.alloc(width * height * 3);
1062
- const cols = bilinearAxis(width / 2, fit.scale, fit.dx, width);
1063
- const rows = bilinearAxis(height / 2, fit.scale, fit.dy, height);
1064
- for (let y = 0; y < height; y++) {
1065
- const row = { y, top: (rows.lo[y] ?? 0) * width, bottom: (rows.hi[y] ?? 0) * width, fy: rows.frac[y] ?? 0 };
1066
- warpRow(render, out, cols, row);
1067
- }
1068
- return { data: out, width, height, channels: 3 };
1069
- }
1070
- function warpRow(render, out, cols, row) {
1071
- const { width, channels, data } = render;
1072
- const { fy } = row;
1073
- for (let x = 0; x < width; x++) {
1074
- const fx = cols.frac[x] ?? 0;
1075
- const w = [(1 - fx) * (1 - fy), fx * (1 - fy), (1 - fx) * fy, fx * fy];
1076
- const lo = cols.lo[x] ?? 0;
1077
- const hi = cols.hi[x] ?? 0;
1078
- const a = [
1079
- (row.top + lo) * channels,
1080
- (row.top + hi) * channels,
1081
- (row.bottom + lo) * channels,
1082
- (row.bottom + hi) * channels
1083
- ];
1084
- const o = (row.y * width + x) * 3;
1085
- for (let c = 0; c < 3; c++) {
1086
- out[o + c] = Math.round(
1087
- w[0] * (data[a[0] + c] ?? 0) + w[1] * (data[a[1] + c] ?? 0) + w[2] * (data[a[2] + c] ?? 0) + w[3] * (data[a[3] + c] ?? 0)
1088
- );
1089
- }
1090
- }
1091
- }
1092
- function emptyLayer(width, height) {
1093
- return {
1094
- width,
1095
- height,
1096
- alpha: new Float32Array(width * height),
1097
- ink: new Float32Array(width * height),
1098
- pixels: Buffer.alloc(width * height * 3),
1099
- gain: new Float32Array(width * height * 3).fill(1)
1100
- };
1101
- }
1102
- var CELL = 8;
1103
- var CHANGED = 14;
1104
- var MATTE_LO = 8;
1105
- var MATTE_HI = 32;
1106
- var BOX_PAD = 0.3;
1107
- var TOUCH = 0.02;
1108
- var GAIN_MAX = 4;
1109
- var TONE_MIN_PIXELS = CELL * CELL / 4;
1110
- var padded = (b, width, height) => {
1111
- const pad = BOX_PAD * (b.y1 - b.y0);
1112
- const padX = pad * height / width;
1113
- return { x0: b.x0 - padX, y0: b.y0 - pad, x1: b.x1 + padX, y1: b.y1 + pad };
1114
- };
1115
- function gridOf(width, height) {
1116
- const gw = Math.ceil(width / CELL);
1117
- const gh = Math.ceil(height / CELL);
1118
- return {
1119
- gw,
1120
- gh,
1121
- cell: (x, y) => Math.floor(y / CELL) * gw + Math.floor(x / CELL),
1122
- span: (g) => {
1123
- const gx = g % gw;
1124
- const gy = Math.floor(g / gw);
1125
- return {
1126
- x0: gx * CELL / width,
1127
- y0: gy * CELL / height,
1128
- x1: (gx + 1) * CELL / width,
1129
- y1: (gy + 1) * CELL / height
1130
- };
1131
- }
1132
- };
1133
- }
1134
- function neighbours2(g, grid) {
1135
- const gx = g % grid.gw;
1136
- const gy = Math.floor(g / grid.gw);
1137
- const out = [];
1138
- for (let k = 0; k < 9; k++) {
1139
- const nx = gx + k % 3 - 1;
1140
- const ny = gy + Math.floor(k / 3) - 1;
1141
- if (k !== 4 && nx >= 0 && ny >= 0 && nx < grid.gw && ny < grid.gh) out.push(ny * grid.gw + nx);
1142
- }
1143
- return out;
1144
- }
1145
- function addPixel(s, aligned, cut, i, g, tone) {
1146
- let d = 0;
1147
- for (let c = 0; c < 3; c++) {
1148
- const a = aligned.data[i * aligned.channels + c] ?? 0;
1149
- const b = cut.data[i * cut.channels + c] ?? 0;
1150
- d = Math.max(d, Math.abs(a - b));
1151
- if (!tone) continue;
1152
- s.meanA[g * 3 + c] = (s.meanA[g * 3 + c] ?? 0) + a;
1153
- s.meanC[g * 3 + c] = (s.meanC[g * 3 + c] ?? 0) + b;
1154
- }
1155
- return d;
1156
- }
1157
- function cellStats(aligned, cut, words, grid) {
1158
- const cells = grid.gw * grid.gh;
1159
- const s = {
1160
- diff: new Float32Array(cells),
1161
- pixelDiff: new Float32Array(cut.width * cut.height),
1162
- meanA: new Float32Array(cells * 3),
1163
- meanC: new Float32Array(cells * 3),
1164
- toneCount: new Float32Array(cells)
1165
- };
1166
- const count = new Float32Array(cells);
1167
- for (let i = 0; i < cut.width * cut.height; i++) {
1168
- const x = i % cut.width;
1169
- const y = Math.floor(i / cut.width);
1170
- const g = grid.cell(x, y);
1171
- const tone = !words[i];
1172
- const d = addPixel(s, aligned, cut, i, g, tone);
1173
- s.pixelDiff[i] = d;
1174
- s.diff[g] = (s.diff[g] ?? 0) + d;
1175
- count[g] = (count[g] ?? 0) + 1;
1176
- if (tone) s.toneCount[g] = (s.toneCount[g] ?? 0) + 1;
1177
- }
1178
- for (let k = 0; k < cells * 3; k++) {
1179
- const g = Math.floor(k / 3);
1180
- if (k % 3 === 0) s.diff[g] = (s.diff[g] ?? 0) / (count[g] || 1);
1181
- s.meanA[k] = (s.meanA[k] ?? 0) / (s.toneCount[g] || 1);
1182
- s.meanC[k] = (s.meanC[k] ?? 0) / (s.toneCount[g] || 1);
1183
- }
1184
- return s;
1185
- }
1186
- var isChanged = (diff, g) => (diff[g] ?? 0) >= CHANGED;
1187
- function flood(start, id, diff, region, grid) {
1188
- region[start] = id;
1189
- const stack = [start];
1190
- while (stack.length > 0) {
1191
- const g = stack.pop() ?? 0;
1192
- const next = neighbours2(g, grid).filter((n) => isChanged(diff, n) && (region[n] ?? -1) < 0);
1193
- for (const n of next) region[n] = id;
1194
- stack.push(...next);
1195
- }
1196
- }
1197
- function changedRegions(diff, grid) {
1198
- const region = new Int32Array(diff.length).fill(-1);
1199
- let count = 0;
1200
- for (let start = 0; start < diff.length; start++) {
1201
- if (!isChanged(diff, start) || (region[start] ?? -1) >= 0) continue;
1202
- flood(start, count, diff, region, grid);
1203
- count++;
1204
- }
1205
- return { region, count };
1206
- }
1207
- function cellGain(s, g) {
1208
- if ((s.toneCount[g] ?? 0) < TONE_MIN_PIXELS) return null;
1209
- return [0, 1, 2].map((c) => {
1210
- const ratio = ((s.meanA[g * 3 + c] ?? 0) + 8) / ((s.meanC[g * 3 + c] ?? 0) + 8);
1211
- return Math.min(GAIN_MAX, Math.max(1 / GAIN_MAX, ratio));
1212
- });
1213
- }
1214
- function neighbourGain(gain, known, g, grid) {
1215
- const around = neighbours2(g, grid).filter((n) => known[n]);
1216
- if (around.length === 0) return null;
1217
- return [0, 1, 2].map((c) => around.reduce((sum, n) => sum + (gain[n * 3 + c] ?? 1), 0) / around.length);
1218
- }
1219
- function spreadGains(gain, known, grid) {
1220
- const filled = [];
1221
- for (let g = 0; g < known.length; g++) {
1222
- const from = known[g] ? null : neighbourGain(gain, known, g, grid);
1223
- if (from) filled.push([g, from]);
1224
- }
1225
- for (const [g, value] of filled) {
1226
- gain.set(value, g * 3);
1227
- known[g] = 1;
1228
- }
1229
- return filled.length;
1230
- }
1231
- function toneGains(s, grid) {
1232
- const cells = grid.gw * grid.gh;
1233
- const gain = new Float32Array(cells * 3).fill(1);
1234
- const known = new Uint8Array(cells);
1235
- for (let g = 0; g < cells; g++) {
1236
- const own = cellGain(s, g);
1237
- if (!own) continue;
1238
- gain.set(own, g * 3);
1239
- known[g] = 1;
1240
- }
1241
- let spread = 1;
1242
- while (spread > 0) spread = spreadGains(gain, known, grid);
1243
- return gain;
1244
- }
1245
- function smoothGains(gains, grid) {
1246
- const out = new Float32Array(gains.length);
1247
- for (let g = 0; g < grid.gw * grid.gh; g++) {
1248
- const around = [g, ...neighbours2(g, grid)];
1249
- for (let c = 0; c < 3; c++) {
1250
- out[g * 3 + c] = around.reduce((sum, n) => sum + (gains[n * 3 + c] ?? 1), 0) / around.length;
1251
- }
1252
- }
1253
- return out;
1254
- }
1255
- var STRUCTURAL = 16;
1256
- function toneMisfit(aligned, cut, gains, words, grid) {
1257
- const sum = new Float32Array(grid.gw * grid.gh);
1258
- const count = new Float32Array(grid.gw * grid.gh);
1259
- for (let i = 0; i < cut.width * cut.height; i++) {
1260
- const x = i % cut.width;
1261
- const y = (i - x) / cut.width;
1262
- if (words[i]) continue;
1263
- const g = grid.cell(x, y);
1264
- let d = 0;
1265
- for (let c = 0; c < 3; c++) {
1266
- const want = Math.min(255, (cut.data[i * cut.channels + c] ?? 0) * (gains[g * 3 + c] ?? 1));
1267
- d = Math.max(d, Math.abs((aligned.data[i * aligned.channels + c] ?? 0) - want));
1268
- }
1269
- sum[g] = (sum[g] ?? 0) + d;
1270
- count[g] = (count[g] ?? 0) + 1;
1271
- }
1272
- return sum.map((v, g) => count[g] ? v / (count[g] ?? 1) : 0);
1273
- }
1274
- function cellTaps(grid, x, y) {
1275
- return taps((x + 0.5) / CELL - 0.5, (y + 0.5) / CELL - 0.5, grid.gw, grid.gh);
1276
- }
1277
- function wordsLayer(aligned, cut, designed, opts = {}) {
1278
- const { width, height } = cut;
1279
- const grid = gridOf(width, height);
1280
- const boxes = designed.map((b) => padded(b, width, height));
1281
- const tight = designed.map((b) => ({ ...b }));
1282
- const inBoxes2 = spanMask(boxes, width, height);
1283
- const stats = cellStats(aligned, cut, inBoxes2, grid);
1284
- const kept = keptChange(stats.diff, boxes, grid, TOUCH * width / height);
1285
- const gains = smoothGains(toneGains(stats, grid), grid);
1286
- const misfit2 = opts.boxesOnly ? null : toneMisfit(aligned, cut, gains, inBoxes2, grid);
1287
- const tone = kept.tone.map((t, g) => t > 0 && misfit2 && (misfit2[g] ?? 0) < STRUCTURAL ? 1 : 0);
1288
- const dropped = kept.tone.reduce((n, t, g) => n + (t > 0 && !tone[g] ? 1 : 0), 0);
1289
- const reverted = kept.reverted + dropped / kept.tone.length;
1290
- const look = {
1291
- aligned,
1292
- stats,
1293
- grid,
1294
- boxes: inBoxes2,
1295
- tone,
1296
- gains,
1297
- tight: spanMask(tight, width, height),
1298
- subjects: spanMask(opts.subjects ?? [], width, height),
1299
- keepOut: spanMask(opts.keepOut ?? [], width, height)
1300
- };
1301
- const layer = emptyLayer(width, height);
1302
- for (let i = 0; i < width * height; i++) setLayerPixel(layer, look, i);
1303
- return { layer, reverted };
1304
- }
1305
- var overlaps = (a, b) => a.x0 < b.x1 && a.x1 > b.x0 && a.y0 < b.y1 && a.y1 > b.y0;
1306
- function keptChange(diff, boxes, grid, touchY) {
1307
- const { region, count } = changedRegions(diff, grid);
1308
- const near = boxes.map((b) => ({ x0: b.x0 - TOUCH, y0: b.y0 - touchY, x1: b.x1 + TOUCH, y1: b.y1 + touchY }));
1309
- const kept = new Uint8Array(count);
1310
- for (let g = 0; g < region.length; g++) {
1311
- const id = region[g] ?? -1;
1312
- if (id >= 0 && near.some((b) => overlaps(grid.span(g), b))) kept[id] = 1;
1313
- }
1314
- const tone = new Float32Array(region.length);
1315
- let reverted = 0;
1316
- for (let g = 0; g < region.length; g++) {
1317
- const id = region[g] ?? -1;
1318
- if (id < 0) continue;
1319
- if (kept[id]) tone[g] = 1;
1320
- else if (!boxes.some((b) => overlaps(grid.span(g), b))) reverted++;
1321
- }
1322
- return { tone, reverted: reverted / region.length };
1323
- }
1324
- function setLayerPixel(layer, look, i) {
1325
- const x = i % layer.width;
1326
- const y = Math.floor(i / layer.width);
1327
- const onSubject = look.subjects[i] === 1;
1328
- const inBox = (onSubject ? look.tight : look.boxes)[i] === 1;
1329
- if (!inBox && look.keepOut[i]) return;
1330
- const near = look.tone[look.grid.cell(x, y)] ? cellTaps(look.grid, x, y) : void 0;
1331
- const toned = near ? tapped(look.tone, near, 1, 0, 1) : 0;
1332
- const changed = ((look.stats.pixelDiff[i] ?? 0) - MATTE_LO) / (MATTE_HI - MATTE_LO);
1333
- const matte = inBox ? Math.min(1, Math.max(0, changed)) : 0;
1334
- const a = Math.max(matte, toned);
1335
- if (a <= 0) return;
1336
- layer.alpha[i] = a;
1337
- layer.ink[i] = inBox ? 1 : 0;
1338
- const cells = near ?? cellTaps(look.grid, x, y);
1339
- for (let c = 0; c < 3; c++) {
1340
- layer.pixels[i * 3 + c] = look.aligned.data[i * look.aligned.channels + c] ?? 0;
1341
- layer.gain[i * 3 + c] = tapped(look.gains, cells, 3, c, 1);
1342
- }
1343
- }
1344
- function protectFaces(layer, faces) {
1345
- if (faces.length === 0) return { layer, covered: 0 };
1346
- const alpha = Float32Array.from(layer.alpha);
1347
- const ink = Float32Array.from(layer.ink);
1348
- let onFace = 0;
1349
- let covered = 0;
1350
- for (let i = 0; i < alpha.length; i++) {
1351
- const fx = (i % layer.width + 0.5) / layer.width;
1352
- const fy = (Math.floor(i / layer.width) + 0.5) / layer.height;
1353
- if (!inSpans(faces, fx, fy)) continue;
1354
- onFace++;
1355
- const k = ink[i] ?? 0;
1356
- if (k <= 0 || (alpha[i] ?? 0) <= 0) continue;
1357
- covered++;
1358
- alpha[i] = (alpha[i] ?? 0) * (1 - k);
1359
- ink[i] = 0;
1360
- }
1361
- return { layer: { ...layer, alpha, ink }, covered: onFace > 0 ? covered / onFace : 0 };
1362
- }
1363
- var HIDDEN = 0.5;
1364
- function coveredSubjects(layer, subjects) {
1365
- return subjects.filter((b) => b.kind === "product" || b.kind === "animal").filter((b) => {
1366
- const x0 = Math.max(0, Math.floor(b.x0 * layer.width));
1367
- const x1 = Math.min(layer.width, Math.ceil(b.x1 * layer.width));
1368
- const y0 = Math.max(0, Math.floor(b.y0 * layer.height));
1369
- const y1 = Math.min(layer.height, Math.ceil(b.y1 * layer.height));
1370
- let covered = 0;
1371
- for (let y = y0; y < y1; y++) {
1372
- for (let x = x0; x < x1; x++) if ((layer.alpha[y * layer.width + x] ?? 0) >= 0.5) covered++;
1373
- }
1374
- const all = (x1 - x0) * (y1 - y0);
1375
- return all > 0 && covered / all > HIDDEN;
1376
- }).map((b) => b.label);
1377
- }
1378
- function compose(cut, layer) {
1379
- const { width, height } = cut;
1380
- const out = Buffer.alloc(width * height * 3);
1381
- for (let k = 0; k < width * height * 3; k++) {
1382
- const i = Math.floor(k / 3);
1383
- const c = k % 3;
1384
- const base = cut.data[i * cut.channels + c] ?? 0;
1385
- const a = layer.alpha[i] ?? 0;
1386
- if (a <= 0) {
1387
- out[k] = base;
1388
- continue;
1389
- }
1390
- const ink = layer.ink[i] ?? 0;
1391
- const toned = Math.min(255, base * (layer.gain[k] ?? 1));
1392
- out[k] = Math.round(base * (1 - a) + (ink * (layer.pixels[k] ?? 0) + (1 - ink) * toned) * a);
1393
- }
1394
- return { data: out, width, height, channels: 3 };
1395
- }
1396
- function identityOutside(out, cut, alpha) {
1397
- let sum = 0;
1398
- let n = 0;
1399
- for (let k = 0; k < cut.width * cut.height * 3; k++) {
1400
- const i = Math.floor(k / 3);
1401
- if ((alpha[i] ?? 0) > 0) continue;
1402
- sum += Math.abs((out.data[i * out.channels + k % 3] ?? 0) - (cut.data[i * cut.channels + k % 3] ?? 0));
1403
- n++;
1404
- }
1405
- return n > 0 ? sum / n : 0;
1406
- }
1407
- var MIN_WORDS_SCALE = 0.8;
1408
- var MAX_WORDS_MOVE = 0.12;
1409
- var MAX_BAND_MOVE = 0.25;
1410
- var GROUP_GAP = 0.04;
1411
- var SCALE_STEP = 0.05;
1412
- var MOVE_STEP = 5e-3;
1413
- var into = (from, to, lo, hi) => Math.max(lo - from, 0) + Math.min(hi - to, 0);
1414
- var unionOf3 = (boxes) => ({
1415
- x0: Math.min(...boxes.map((b) => b.x0)),
1416
- y0: Math.min(...boxes.map((b) => b.y0)),
1417
- x1: Math.max(...boxes.map((b) => b.x1)),
1418
- y1: Math.max(...boxes.map((b) => b.y1))
1419
- });
1420
- var overlap = (a, b) => a.x0 < b.x1 && a.x1 > b.x0 && a.y0 < b.y1 && a.y1 > b.y0;
1421
- function clearAreas(format, placements, bottom) {
1422
- const area2 = blockingArea(format, placements);
1423
- const rail = area2.rail && bottom > area2.rail.from ? area2.rail.width : 0;
1424
- const band = {
1425
- x0: area2.left + FIT_HEADROOM,
1426
- y0: area2.top + FIT_HEADROOM,
1427
- x1: 1 - Math.max(area2.right, rail) - FIT_HEADROOM,
1428
- y1: 1 - area2.bottom - FIT_HEADROOM
1429
- };
1430
- const covered = area2.covered;
1431
- if (!covered) return [band];
1432
- const drawn = covered.rail && bottom > covered.rail.from ? covered.rail.width : 0;
1433
- return [
1434
- band,
1435
- {
1436
- x0: band.x0,
1437
- y0: covered.top + FIT_HEADROOM,
1438
- x1: 1 - Math.max(area2.right, drawn) - FIT_HEADROOM,
1439
- y1: 1 - covered.bottom - FIT_HEADROOM
1440
- }
1441
- ];
1442
- }
1443
- function wordGroups(words) {
1444
- const sorted = [...words].sort((a, b) => a.y0 - b.y0);
1445
- const groups = [];
1446
- for (const box of sorted) {
1447
- const last = groups.at(-1);
1448
- if (last && box.y0 - Math.max(...last.map((b) => b.y1)) < GROUP_GAP) last.push(box);
1449
- else groups.push([box]);
1450
- }
1451
- return groups;
1452
- }
1453
- function placed(union, fit, area2, p, withFaces) {
1454
- const m = movedSpan(union, fit);
1455
- const inArea = m.x0 >= area2.x0 - 1e-9 && m.x1 <= area2.x1 + 1e-9 && m.y0 >= area2.y0 - 1e-9 && m.y1 <= area2.y1 + 1e-9;
1456
- return inArea && !p.others.some((o) => overlap(m, o)) && !(withFaces && p.faces.some((f) => overlap(m, f)));
1457
- }
1458
- function shiftInto(union, at, area2, p, withFaces) {
1459
- const half = at.scale * (union.x1 - union.x0) / 2;
1460
- const dx = into(at.cx - half, at.cx + half, area2.x0, area2.x1);
1461
- const steps = Math.round(p.reach / MOVE_STEP);
1462
- for (let k = 0; k <= 2 * steps; k++) {
1463
- const dy = (k % 2 === 0 ? 1 : -1) * Math.ceil(k / 2) * MOVE_STEP;
1464
- const fit = { ...at, dx, dy };
1465
- if (placed(union, fit, area2, p, withFaces)) return fit;
1466
- }
1467
- return null;
1468
- }
1469
- function blockMove(union, p, withFaces) {
1470
- const cx = (union.x0 + union.x1) / 2;
1471
- const cy = (union.y0 + union.y1) / 2;
1472
- for (let scale = 1; scale >= p.minScale - 1e-9; scale -= SCALE_STEP) {
1473
- for (const area2 of p.areas) {
1474
- const fit = shiftInto(union, { scale, cx, cy }, area2, p, withFaces);
1475
- if (fit) return fit;
1476
- }
1477
- }
1478
- return null;
1479
- }
1480
- var unmoved = (fit) => fit.scale === 1 && fit.dx === 0 && fit.dy === 0;
1481
- var across = (area2, union) => ({
1482
- ...area2,
1483
- x0: Math.min(area2.x0, union.x0),
1484
- x1: Math.max(area2.x1, union.x1)
1485
- });
1486
- function planWordsShift(words, format, opts = {}) {
1487
- const faces = opts.faces ?? [];
1488
- const obstacles = [...faces, ...opts.keepOut ?? []];
1489
- const groups = wordGroups(words).map((g) => ({ boxes: g, union: unionOf3(g) }));
1490
- const moves = [];
1491
- let reason;
1492
- for (const [i, group] of groups.entries()) {
1493
- const violations = bandViolations(group.boxes, format, { placements: blockingPlacements(opts.placements) });
1494
- const past2 = violations.length > 0;
1495
- const onFace = faces.some((f) => overlap(group.union, f));
1496
- if (!past2 && !onFace) continue;
1497
- const sideways = violations.some((v) => v.edges.includes("left") || v.edges.includes("right"));
1498
- const p = {
1499
- areas: clearAreas(format, opts.placements, group.union.y1).map((a) => sideways ? a : across(a, group.union)),
1500
- faces: obstacles,
1501
- others: groups.filter((_, j) => j !== i).map((g) => g.union),
1502
- minScale: opts.minScale ?? MIN_WORDS_SCALE,
1503
- reach: past2 ? MAX_BAND_MOVE : MAX_WORDS_MOVE
1504
- };
1505
- const step = stepOf(group.union, past2, p);
1506
- if (typeof step === "string") reason ??= step;
1507
- else if (step) moves.push({ group: group.union, fit: step });
1508
- }
1509
- return reason ? { moves, reason } : { moves };
1510
- }
1511
- function stepOf(union, past2, p) {
1512
- const fit = blockMove(union, p, true);
1513
- if (fit) return unmoved(fit) ? null : fit;
1514
- return blockMove(union, p, false) || !past2 ? "words_over_face" : "band_too_far";
1515
- }
1516
- function movedSpan(b, fit) {
1517
- const at = (v, c, d) => c + fit.scale * (v - c) + d;
1518
- return {
1519
- ...b,
1520
- x0: at(b.x0, fit.cx, fit.dx),
1521
- y0: at(b.y0, fit.cy, fit.dy),
1522
- x1: at(b.x1, fit.cx, fit.dx),
1523
- y1: at(b.y1, fit.cy, fit.dy)
1524
- };
1525
- }
1526
- var GROUP_REACH = 0.03;
1527
- function blockAt(layer, moves, i) {
1528
- const fx = (i % layer.width + 0.5) / layer.width;
1529
- const fy = (Math.floor(i / layer.width) + 0.5) / layer.height;
1530
- return moves.findIndex(
1531
- (m) => fx >= m.group.x0 - GROUP_REACH && fx <= m.group.x1 + GROUP_REACH && fy >= m.group.y0 - GROUP_REACH && fy <= m.group.y1 + GROUP_REACH
1532
- );
1533
- }
1534
- function owners(layer, moves) {
1535
- const { width } = layer;
1536
- const own = new Int16Array(width * layer.height).fill(-1);
1537
- for (let i = 0; i < own.length; i++) if ((layer.alpha[i] ?? 0) > 0) own[i] = blockAt(layer, moves, i);
1538
- spreadOwners(own, layer.alpha, width);
1539
- return own;
1540
- }
1541
- function spreadOwners(own, alpha, width) {
1542
- const { stack, seeds } = seedsOf(own);
1543
- let top = seeds;
1544
- const free = (n) => n >= 0 && n < own.length && (own[n] ?? -1) < 0 && (alpha[n] ?? 0) > 0;
1545
- while (top > 0) {
1546
- const i = stack[--top] ?? 0;
1547
- const block = own[i] ?? -1;
1548
- for (const n of touching(i, width)) {
1549
- if (!free(n)) continue;
1550
- own[n] = block;
1551
- stack[top++] = n;
1552
- }
1553
- }
1554
- }
1555
- function seedsOf(own) {
1556
- const stack = new Int32Array(own.length);
1557
- let seeds = 0;
1558
- for (let i = 0; i < own.length; i++) if ((own[i] ?? -1) >= 0) stack[seeds++] = i;
1559
- return { stack, seeds };
1560
- }
1561
- function touching(i, width) {
1562
- const x = i % width;
1563
- return [x > 0 ? i - 1 : -1, x < width - 1 ? i + 1 : -1, i - width, i + width];
1564
- }
1565
- function takePixel(out, to, layer, t) {
1566
- const a = tapped(layer.alpha, t);
1567
- if (a <= (out.alpha[to] ?? 0)) return;
1568
- out.alpha[to] = a;
1569
- out.ink[to] = tapped(layer.ink, t);
1570
- for (let c = 0; c < 3; c++) {
1571
- out.pixels[to * 3 + c] = Math.round(tapped(layer.pixels, t, 3, c));
1572
- out.gain[to * 3 + c] = tapped(layer.gain, t, 3, c, 1);
1573
- }
1574
- }
1575
- function moveBlock(out, layer, own, k, fit) {
1576
- const { width, height } = layer;
1577
- const back = (p, c, d, size) => c * size + (p + 0.5 - c * size - d * size) / fit.scale - 0.5;
1578
- for (let i = 0; i < width * height; i++) {
1579
- const u = back(i % width, fit.cx, fit.dx, width);
1580
- const v = back(Math.floor(i / width), fit.cy, fit.dy, height);
1581
- const inside = u >= 0 && v >= 0 && u <= width - 1 && v <= height - 1;
1582
- if (inside && own[Math.round(v) * width + Math.round(u)] === k) takePixel(out, i, layer, taps(u, v, width, height));
1583
- }
1584
- }
1585
- function movedPart(layer, moves) {
1586
- const own = owners(layer, moves);
1587
- const out = emptyLayer(layer.width, layer.height);
1588
- for (let i = 0; i < own.length; i++) {
1589
- if ((own[i] ?? -1) >= 0) takePixel(out, i, layer, { at: [i, i, i, i], w: [1, 0, 0, 0] });
1590
- }
1591
- return out;
1592
- }
1593
- function moveLayer(layer, moves) {
1594
- const own = owners(layer, moves);
1595
- const out = emptyLayer(layer.width, layer.height);
1596
- for (let i = 0; i < own.length; i++) {
1597
- if ((own[i] ?? -1) < 0 && (layer.alpha[i] ?? 0) > 0)
1598
- takePixel(out, i, layer, { at: [i, i, i, i], w: [1, 0, 0, 0] });
1599
- }
1600
- for (const [k, { fit }] of moves.entries()) moveBlock(out, layer, own, k, fit);
1601
- return out;
1602
- }
1603
- function cropLayer(layer, rect) {
1604
- const out = emptyLayer(rect.width, rect.height);
1605
- for (let y = 0; y < rect.height; y++) {
1606
- const from = (rect.y + y) * layer.width + rect.x;
1607
- const to = y * rect.width;
1608
- out.alpha.set(layer.alpha.subarray(from, from + rect.width), to);
1609
- out.ink.set(layer.ink.subarray(from, from + rect.width), to);
1610
- out.gain.set(layer.gain.subarray(from * 3, (from + rect.width) * 3), to * 3);
1611
- layer.pixels.copy(out.pixels, to * 3, from * 3, (from + rect.width) * 3);
1612
- }
1613
- return out;
1614
- }
1615
-
1616
- // src/engine/nodes/local/lib/whole-render.ts
1617
- var inSpans2 = (spans, fx, fy) => spans.some((s) => fx >= s.x0 && fx <= s.x1 && fy >= s.y0 && fy <= s.y1);
1618
- function blurLine(src, out, start, step, n, r) {
1619
- const last = start + (n - 1) * step;
1620
- let acc = 0;
1621
- for (let k = -r; k <= r; k++) acc += src[k <= 0 ? start : k >= n - 1 ? last : start + k * step] ?? 0;
1622
- for (let k = 0; k < n; k++) {
1623
- out[start + k * step] = acc / (2 * r + 1);
1624
- const enter = k + r + 1;
1625
- const leave = k - r;
1626
- acc += (src[enter >= n - 1 ? last : start + enter * step] ?? 0) - (src[leave <= 0 ? start : start + leave * step] ?? 0);
1627
- }
1628
- }
1629
- function blurColumns(src, out, width, height, r) {
1630
- const acc = new Float64Array(width);
1631
- const row = (k) => (k <= 0 ? 0 : k >= height - 1 ? height - 1 : k) * width;
1632
- for (let k = -r; k <= r; k++) {
1633
- const from = row(k);
1634
- for (let x = 0; x < width; x++) acc[x] = (acc[x] ?? 0) + (src[from + x] ?? 0);
1635
- }
1636
- for (let k = 0; k < height; k++) {
1637
- const to = k * width;
1638
- const enter = row(k + r + 1);
1639
- const leave = row(k - r);
1640
- for (let x = 0; x < width; x++) {
1641
- out[to + x] = (acc[x] ?? 0) / (2 * r + 1);
1642
- acc[x] = (acc[x] ?? 0) + ((src[enter + x] ?? 0) - (src[leave + x] ?? 0));
1643
- }
1644
- }
1645
- }
1646
- function boxBlur(src, width, height, r) {
1647
- if (r < 1) return Float32Array.from(src);
1648
- const along = new Float32Array(width * height);
1649
- for (let y = 0; y < height; y++) blurLine(src, along, y * width, 1, width, r);
1650
- const out = new Float32Array(width * height);
1651
- blurColumns(along, out, width, height, r);
1652
- return out;
1653
- }
1654
- var soften = (src, width, height, r) => boxBlur(boxBlur(src, width, height, r), width, height, r);
1655
- function channelOf(img, c) {
1656
- const out = new Float32Array(img.width * img.height);
1657
- for (let i = 0; i < out.length; i++) out[i] = img.data[i * img.channels + c] ?? 0;
1658
- return out;
1659
- }
1660
- var STRUCTURE_RADIUS = 8e-3;
1661
- var GAIN_MAX2 = 2.5;
1662
- var FLAT2 = 2.5;
1663
- var STILL = 14;
1664
- var MOVED = 28;
1665
- function flatOf2(img) {
1666
- const { width, height } = img;
1667
- const grey = new Float32Array(width * height);
1668
- for (let i = 0; i < grey.length; i++) {
1669
- const o = i * img.channels;
1670
- grey[i] = 0.299 * (img.data[o] ?? 0) + 0.587 * (img.data[o + 1] ?? 0) + 0.114 * (img.data[o + 2] ?? 0);
1671
- }
1672
- const squares = new Float32Array(grey.length);
1673
- for (let i = 0; i < grey.length; i++) squares[i] = (grey[i] ?? 0) * (grey[i] ?? 0);
1674
- const mean = boxBlur(grey, width, height, 2);
1675
- const square = boxBlur(squares, width, height, 2);
1676
- const flat = new Uint8Array(mean.length);
1677
- for (let i = 0; i < mean.length; i++) {
1678
- const m = mean[i] ?? 0;
1679
- flat[i] = Math.sqrt(Math.max(0, (square[i] ?? 0) - m * m)) < FLAT2 ? 1 : 0;
1680
- }
1681
- return flat;
1682
- }
1683
- var gridOver = (width, height, size) => ({
1684
- size,
1685
- gw: Math.ceil(width / size),
1686
- gh: Math.ceil(height / size)
1687
- });
1688
- function cellOf(grid, i, width) {
1689
- const x = i % width;
1690
- return Math.floor((i - x) / width / grid.size) * grid.gw + Math.floor(x / grid.size);
1691
- }
1692
- function cellsNear(grid, g, reach) {
1693
- const gx = g % grid.gw;
1694
- const gy = (g - gx) / grid.gw;
1695
- const out = [];
1696
- for (let ny = Math.max(0, gy - reach); ny <= Math.min(grid.gh - 1, gy + reach); ny++) {
1697
- for (let nx = Math.max(0, gx - reach); nx <= Math.min(grid.gw - 1, gx + reach); nx++) out.push(ny * grid.gw + nx);
1698
- }
1699
- return out;
1700
- }
1701
- var SURFACE_CELL = 8;
1702
- function laidCells(flat, structure, width, grid) {
1703
- const laid = new Float32Array(grid.gw * grid.gh);
1704
- const count = new Float32Array(grid.gw * grid.gh);
1705
- for (let i = 0; i < flat.length; i++) {
1706
- const g = cellOf(grid, i, width);
1707
- count[g] = (count[g] ?? 0) + 1;
1708
- if (flat[i] && (structure[i] ?? 0) > MOVED) laid[g] = (laid[g] ?? 0) + 1;
1709
- }
1710
- return Uint8Array.from(laid, (n, g) => n >= (count[g] ?? 1) / 2 ? 1 : 0);
1711
- }
1712
- function wordCells(words, width, height, grid) {
1713
- const out = [];
1714
- for (let g = 0; g < grid.gw * grid.gh; g++) {
1715
- const gx = g % grid.gw;
1716
- const gy = (g - gx) / grid.gw;
1717
- const x0 = gx * grid.size / width;
1718
- const y0 = gy * grid.size / height;
1719
- const x1 = (gx + 1) * grid.size / width;
1720
- const y1 = (gy + 1) * grid.size / height;
1721
- if (words.some((w) => w.x0 < x1 && w.x1 > x0 && w.y0 < y1 && w.y1 > y0)) out.push(g);
1722
- }
1723
- return out;
1724
- }
1725
- function flood2(seeds, open, grid) {
1726
- const reached = new Uint8Array(grid.gw * grid.gh);
1727
- for (const g of seeds) reached[g] = 1;
1728
- const stack = [...seeds];
1729
- while (stack.length > 0) {
1730
- const next = cellsNear(grid, stack.pop() ?? 0, 1).filter((n) => !reached[n] && open[n]);
1731
- for (const n of next) reached[n] = 1;
1732
- stack.push(...next);
1733
- }
1734
- return reached;
1735
- }
1736
- function surfaceOf(flat, structure, width, height, words) {
1737
- const grid = gridOver(width, height, SURFACE_CELL);
1738
- const reached = flood2(wordCells(words, width, height, grid), laidCells(flat, structure, width, grid), grid);
1739
- const surface = new Uint8Array(structure.length);
1740
- for (let y = 0; y < height; y++) {
1741
- const row = Math.floor(y / grid.size) * grid.gw;
1742
- for (let x = 0; x < width; x++) {
1743
- const i = y * width + x;
1744
- surface[i] = reached[row + Math.floor(x / grid.size)] && (structure[i] ?? 0) > MOVED ? 1 : 0;
1745
- }
1746
- }
1747
- return surface;
1748
- }
1749
- var GROUND_LINE = 3;
1750
- var CARD_TONE = 16;
1751
- var CARD_RUN = 0.6;
1752
- var inTone = (img, i, tone) => [0, 1, 2].every((c) => Math.abs((img.data[i * img.channels + c] ?? 0) - (tone[c] ?? 0)) <= CARD_TONE);
1753
- function* pixelsOf(r, width, height) {
1754
- for (let y = Math.max(0, r.y0); y < Math.min(height, r.y1); y++) {
1755
- for (let x = Math.max(0, r.x0); x < Math.min(width, r.x1); x++) yield y * width + x;
1756
- }
1757
- }
1758
- var stripsPast = (r, depth) => [
1759
- { ...r, y0: r.y0 - depth, y1: r.y0 },
1760
- { ...r, y0: r.y1, y1: r.y1 + depth },
1761
- { ...r, x0: r.x0 - depth, x1: r.x0 },
1762
- { ...r, x0: r.x1, x1: r.x1 + depth }
1763
- ];
1764
- var inBoxes = (boxes, i, width) => {
1765
- const x = i % width;
1766
- const y = (i - x) / width;
1767
- return boxes.some((b) => x >= b.x0 && x < b.x1 && y >= b.y0 && y < b.y1);
1768
- };
1769
- function cardTone(img, flat, box, others = []) {
1770
- const { width, height } = img;
1771
- const around = stripsPast(box, GROUND_LINE).flatMap((s) => [...pixelsOf(s, width, height)]).filter((i) => !inBoxes(others, i, width));
1772
- const flatOnes = around.filter((i) => flat[i]);
1773
- if (around.length === 0 || flatOnes.length < around.length / 2) return null;
1774
- return [0, 1, 2].map((c) => {
1775
- const values = flatOnes.map((i) => img.data[i * img.channels + c] ?? 0).sort((a, b) => a - b);
1776
- return values[Math.floor(values.length / 2)] ?? 0;
1777
- });
1778
- }
1779
- var grownBy = (r, side, by) => side === 0 ? { ...r, y0: r.y0 - by } : side === 1 ? { ...r, y1: r.y1 + by } : side === 2 ? { ...r, x0: r.x0 - by } : { ...r, x1: r.x1 + by };
1780
- function cardAround(img, box, tone) {
1781
- const { width, height } = img;
1782
- const share2 = (s) => {
1783
- const px = [...pixelsOf(s, width, height)];
1784
- return px.length > 0 ? px.filter((i) => inTone(img, i, tone)).length / px.length : 0;
1785
- };
1786
- const runs = (r2, side) => {
1787
- for (let by = 1; by <= GROUND_LINE + 1; by++)
1788
- if (share2(stripsPast(grownBy(r2, side, by - 1), 1)[side] ?? r2) >= CARD_RUN) return by;
1789
- return 0;
1790
- };
1791
- let r = box;
1792
- for (let grew = true; grew; ) {
1793
- grew = false;
1794
- for (let side = 0; side < 4; side++) {
1795
- const by = runs(r, side);
1796
- if (by === 0) continue;
1797
- r = grownBy(r, side, by);
1798
- grew = true;
1799
- }
1800
- }
1801
- return r;
1802
- }
1803
- function groundOf(aligned, flat, words) {
1804
- const { width, height } = aligned;
1805
- const toned = new Float32Array(width * height);
1806
- const inCard = new Uint8Array(width * height);
1807
- const boxes = words.map((w) => ({
1808
- x0: Math.max(0, Math.floor(w.x0 * width)),
1809
- y0: Math.max(0, Math.floor(w.y0 * height)),
1810
- x1: Math.min(width, Math.ceil(w.x1 * width)),
1811
- y1: Math.min(height, Math.ceil(w.y1 * height))
1812
- }));
1813
- for (const box of boxes) {
1814
- const tone = cardTone(
1815
- aligned,
1816
- flat,
1817
- box,
1818
- boxes.filter((b) => b !== box)
1819
- );
1820
- if (!tone) continue;
1821
- for (const i of pixelsOf(cardAround(aligned, box, tone), width, height)) {
1822
- inCard[i] = 1;
1823
- if (inTone(aligned, i, tone)) toned[i] = 1;
1824
- }
1825
- }
1826
- const near = boxBlur(toned, width, height, GROUND_LINE);
1827
- return Uint8Array.from(near, (v, i) => v > 0 && inCard[i] ? 1 : 0);
1828
- }
1829
- function trustOf(width, height, words) {
1830
- const trust = new Float32Array(width * height);
1831
- for (let i = 0; i < trust.length; i++) {
1832
- const x = i % width;
1833
- trust[i] = inSpans2(words, (x + 0.5) / width, ((i - x) / width + 0.5) / height) ? 0 : 1;
1834
- }
1835
- return trust;
1836
- }
1837
- var cutPlanes = remembered();
1838
- var shrunkCuts = remembered();
1839
- function planesOf(img, r1) {
1840
- const own = [0, 1, 2].map((c) => channelOf(img, c));
1841
- return {
1842
- own,
1843
- low: own.map((p) => soften(p, img.width, img.height, r1)),
1844
- fine: own.map((p) => boxBlur(p, img.width, img.height, 1))
1845
- };
1846
- }
1847
- var LIGHT_CELL = 0.015;
1848
- var LIGHT_REACH = 3;
1849
- function cellSums(a, b, open, width, grid) {
1850
- const sums = new Float32Array(grid.gw * grid.gh * 7);
1851
- const own = [...a.own, ...b.own];
1852
- for (let i = 0; i < open.length; i++) {
1853
- if (!open[i]) continue;
1854
- const g = cellOf(grid, i, width) * 7;
1855
- for (let c = 0; c < 6; c++) sums[g + c] = (sums[g + c] ?? 0) + (own[c]?.[i] ?? 0);
1856
- sums[g + 6] = (sums[g + 6] ?? 0) + 1;
1857
- }
1858
- return sums;
1859
- }
1860
- function cellRatios(a, b, open, width, grid) {
1861
- const sums = cellSums(a, b, open, width, grid);
1862
- const ratio = new Float32Array(grid.gw * grid.gh * 3).fill(Number.NaN);
1863
- for (let g = 0; g < grid.gw * grid.gh; g++) {
1864
- const n = sums[g * 7 + 6] ?? 0;
1865
- if (n < grid.size * grid.size / 4) continue;
1866
- for (let c = 0; c < 3; c++) {
1867
- ratio[g * 3 + c] = ((sums[g * 7 + c] ?? 0) / n + 8) / ((sums[g * 7 + 3 + c] ?? 0) / n + 8);
1868
- }
1869
- }
1870
- return ratio;
1871
- }
1872
- function medianNear(values, near, c, scratch) {
1873
- let known = 0;
1874
- for (const n of near) {
1875
- const v = values[n * 3 + c] ?? Number.NaN;
1876
- if (!Number.isNaN(v)) scratch[known++] = v;
1877
- }
1878
- if (known === 0) return 1;
1879
- const sorted = scratch.subarray(0, known).sort();
1880
- return sorted[Math.floor(known / 2)] ?? 1;
1881
- }
1882
- function medianLight(ratio, grid) {
1883
- const cells = grid.gw * grid.gh;
1884
- const median = new Float32Array(cells * 3);
1885
- const scratch = new Float64Array((2 * LIGHT_REACH + 1) ** 2);
1886
- for (let g = 0; g < cells; g++) {
1887
- const near = cellsNear(grid, g, LIGHT_REACH);
1888
- for (let c = 0; c < 3; c++) median[g * 3 + c] = medianNear(ratio, near, c, scratch);
1889
- }
1890
- const smooth = new Float32Array(cells * 3);
1891
- for (let k = 0; k < cells * 3; k++) {
1892
- const near = cellsNear(grid, Math.floor(k / 3), 1);
1893
- smooth[k] = near.reduce((sum, n) => sum + (median[n * 3 + k % 3] ?? 1), 0) / near.length;
1894
- }
1895
- return smooth;
1896
- }
1897
- function lightOf(a, b, open, width, height) {
1898
- const grid = gridOver(width, height, Math.max(8, Math.round(width * LIGHT_CELL)));
1899
- const light = medianLight(cellRatios(a, b, open, width, grid), grid);
1900
- const gain = enlarge(light, { width: grid.gw, height: grid.gh }, { width, height }, 3);
1901
- const kept = new Float32Array(gain.length);
1902
- for (let i = 0; i < gain.length; i++) kept[i] = Math.min(GAIN_MAX2, Math.max(1 / GAIN_MAX2, gain[i] ?? 0));
1903
- return kept;
1904
- }
1905
- function compared(a, b, gain, n) {
1906
- const structure = new Float32Array(n);
1907
- const detail = new Float32Array(n);
1908
- for (let c = 0; c < 3; c++) {
1909
- const [aLow, bLow, aFine, bFine] = [a.low[c], b.low[c], a.fine[c], b.fine[c]];
1910
- for (let i = 0; i < n; i++) {
1911
- const g = gain[i * 3 + c] ?? 1;
1912
- structure[i] = Math.max(structure[i] ?? 0, Math.abs((aLow?.[i] ?? 0) - g * (bLow?.[i] ?? 0)));
1913
- detail[i] = Math.max(detail[i] ?? 0, Math.abs((aFine?.[i] ?? 0) - g * (bFine?.[i] ?? 0)));
1914
- }
1915
- }
1916
- return { structure, detail };
1917
- }
1918
- function renderDiff(aligned, cut, words) {
1919
- const { width, height } = cut;
1920
- const r1 = Math.max(2, Math.round(width * STRUCTURE_RADIUS));
1921
- const a = planesOf(aligned, r1);
1922
- const b = cutPlanes(cut, String(r1), () => planesOf(cut, r1));
1923
- const gain = lightOf(a, b, trustOf(width, height, words), width, height);
1924
- const { structure, detail } = compared(a, b, gain, width * height);
1925
- const flat = flatOf2(aligned);
1926
- const surface = surfaceOf(flat, structure, width, height, words);
1927
- let ground;
1928
- return {
1929
- width,
1930
- height,
1931
- structure,
1932
- detail,
1933
- flat,
1934
- surface,
1935
- gain,
1936
- // Read only to put a subject back: a render refused is never read for it.
1937
- get ground() {
1938
- ground ??= groundOf(aligned, flat, words);
1939
- return ground;
1940
- }
1941
- };
1942
- }
1943
- function subjectDrift(diff, subject, words) {
1944
- const { width, height } = diff;
1945
- const x0 = Math.max(0, Math.floor(subject.x0 * width));
1946
- const x1 = Math.min(width, Math.ceil(subject.x1 * width));
1947
- const y0 = Math.max(0, Math.floor(subject.y0 * height));
1948
- const y1 = Math.min(height, Math.ceil(subject.y1 * height));
1949
- const n = { all: 0, open: 0, covered: 0, moved: 0, drift: 0, held: 0 };
1950
- for (let y = y0; y < y1; y++) {
1951
- for (let x = x0; x < x1; x++) {
1952
- n.all++;
1953
- if (!inSpans2(words, (x + 0.5) / width, (y + 0.5) / height)) countDrift(n, diff, y * width + x);
1954
- }
1955
- }
1956
- return {
1957
- shown: n.all > 0 ? (n.open - n.covered) / n.all : 0,
1958
- moved: n.open > 0 ? n.moved / n.open : 0,
1959
- drift: n.held > 0 ? n.drift / n.held : 0
1960
- };
1961
- }
1962
- function countDrift(n, diff, i) {
1963
- n.open++;
1964
- if ((diff.structure[i] ?? 0) <= MOVED) {
1965
- n.drift += diff.detail[i] ?? 0;
1966
- n.held++;
1967
- } else if (diff.surface[i]) n.covered++;
1968
- else n.moved++;
1969
- }
1970
- var DRIFTED = 3;
1971
- var MIN_KEPT = 0.75;
1972
- var MAX_CARRIED = 5e-3;
1973
- var REDRAWN = 0.2;
1974
- var WHOLE_PROBLEMS = ["picture_moved", "subject_redrawn", "words_lost", "words_over_face"];
1975
- function wholeVerdict(r) {
1976
- if (r.kept < MIN_KEPT || r.carried > MAX_CARRIED) return { ok: false, problem: "picture_moved", what: [] };
1977
- const redrawn = r.subjects.filter((s) => s.moved > REDRAWN).map((s) => s.label);
1978
- if (redrawn.length > 0) return { ok: false, problem: "subject_redrawn", what: redrawn };
1979
- if (r.lost.length > 0) return { ok: false, problem: "words_lost", what: [...r.lost] };
1980
- if (r.onFace.length > 0) return { ok: false, problem: "words_over_face", what: [...r.onFace] };
1981
- return { ok: true, restore: r.subjects.filter((s) => s.drift > DRIFTED).map((s) => s.label) };
1982
- }
1983
- function greyOf(img, f) {
1984
- const width = Math.max(1, Math.floor(img.width / f));
1985
- const height = Math.max(1, Math.floor(img.height / f));
1986
- const data = new Float32Array(width * height);
1987
- for (let i = 0; i < width * height; i++) {
1988
- const x = i % width * f;
1989
- const y = Math.floor(i / width) * f;
1990
- let sum = 0;
1991
- for (let j = 0; j < f; j++) {
1992
- for (let k = 0; k < f; k++) {
1993
- const o = ((y + j) * img.width + x + k) * img.channels;
1994
- sum += 0.299 * (img.data[o] ?? 0) + 0.587 * (img.data[o + 1] ?? 0) + 0.114 * (img.data[o + 2] ?? 0);
1995
- }
1996
- }
1997
- data[i] = sum / (f * f);
1998
- }
1999
- return { data, width, height };
2000
- }
2001
- function likeness(render, cut, box, place) {
2002
- const cx = box.x + box.width / 2;
2003
- const cy = box.y + box.height / 2;
2004
- const n = { count: 0, a: 0, c: 0, aa: 0, cc: 0, ac: 0 };
2005
- for (let y = box.y; y < box.y + box.height; y++) {
2006
- for (let x = box.x; x < box.x + box.width; x++) {
2007
- const u = Math.round(cx + place.scale * (x - cx) + place.dx);
2008
- const v = Math.round(cy + place.scale * (y - cy) + place.dy);
2009
- if (u < 0 || v < 0 || u >= render.width || v >= render.height) return -1;
2010
- const a = render.data[v * render.width + u] ?? 0;
2011
- const c = cut.data[y * cut.width + x] ?? 0;
2012
- n.count++;
2013
- n.a += a;
2014
- n.c += c;
2015
- n.aa += a * a;
2016
- n.cc += c * c;
2017
- n.ac += a * c;
2018
- }
2019
- }
2020
- const va = n.aa - n.a * n.a / n.count;
2021
- const vc = n.cc - n.c * n.c / n.count;
2022
- return va > 1e-6 && vc > 1e-6 ? (n.ac - n.a * n.c / n.count) / Math.sqrt(va * vc) : -1;
2023
- }
2024
- function boxIn(s, g, inset) {
2025
- const w = (s.x1 - s.x0) * g.width;
2026
- const h = (s.y1 - s.y0) * g.height;
2027
- const x = Math.max(0, Math.round(s.x0 * g.width + inset * w));
2028
- const y = Math.max(0, Math.round(s.y0 * g.height + inset * h));
2029
- return {
2030
- x,
2031
- y,
2032
- width: Math.max(1, Math.min(g.width - x, Math.round(w * (1 - 2 * inset)))),
2033
- height: Math.max(1, Math.min(g.height - y, Math.round(h * (1 - 2 * inset))))
2034
- };
2035
- }
2036
- function bestPlace(render, cut, box, places) {
2037
- let best = { dx: 0, dy: 0, scale: 1, score: -2 };
2038
- for (const place of places) {
2039
- const score = likeness(render, cut, box, place);
2040
- if (score > best.score) best = { ...place, score };
2041
- }
2042
- return best;
2043
- }
2044
- var TRACK_REACH = 0.25;
2045
- var TRACK_SCALES = [0.85, 0.92, 1, 1.08, 1.15];
2046
- var TRACK_WIDTH = 180;
2047
- function* placesNear(around, reach, scales) {
2048
- for (const scale of scales) {
2049
- for (let dy = -reach; dy <= reach; dy++) {
2050
- for (let dx = -reach; dx <= reach; dx++) yield { dx: around.dx + dx, dy: around.dy + dy, scale };
2051
- }
2052
- }
2053
- }
2054
- function tracked(aligned, cut, subject) {
2055
- const f = Math.max(1, Math.round(cut.width / TRACK_WIDTH));
2056
- const coarse = { render: greyOf(aligned, f), cut: greyOf(cut, f) };
2057
- const reach = Math.round(TRACK_REACH * coarse.cut.width);
2058
- const found = bestPlace(
2059
- coarse.render,
2060
- coarse.cut,
2061
- boxIn(subject, coarse.cut, 0.1),
2062
- placesNear({ dx: 0, dy: 0, scale: 1 }, reach, TRACK_SCALES)
2063
- );
2064
- const fine = { render: greyOf(aligned, 1), cut: greyOf(cut, 1) };
2065
- const near = [found.scale - 0.03, found.scale, found.scale + 0.03];
2066
- const refined = bestPlace(
2067
- fine.render,
2068
- fine.cut,
2069
- boxIn(subject, fine.cut, 0.1),
2070
- placesNear({ dx: found.dx * f, dy: found.dy * f, scale: 1 }, f, near)
2071
- );
2072
- return {
2073
- dx: refined.dx / cut.width,
2074
- dy: refined.dy / cut.height,
2075
- scale: refined.scale,
2076
- score: refined.score
2077
- };
2078
- }
2079
- var FACE_EDGE = 0.15;
2080
- function wordsOnFaces(words, faces) {
2081
- return facesUnder(words, faces).map((f) => f.label);
2082
- }
2083
- function facesUnder(words, faces) {
2084
- return faces.filter((f) => {
2085
- const dx = FACE_EDGE * (f.x1 - f.x0);
2086
- const dy = FACE_EDGE * (f.y1 - f.y0);
2087
- return words.some((w) => w.x0 < f.x1 - dx && w.x1 > f.x0 + dx && w.y0 < f.y1 - dy && w.y1 > f.y0 + dy);
2088
- });
2089
- }
2090
- var FRAME_MARGIN = 0.01;
2091
- function wordsLost(words, format, placements, keepOut = []) {
2092
- const cut = words.filter(
2093
- (b) => b.x0 < FRAME_MARGIN || b.y0 < FRAME_MARGIN || b.x1 > 1 - FRAME_MARGIN || b.y1 > 1 - FRAME_MARGIN || keepOut.some((k) => overlaps2(b, k))
2094
- );
2095
- const covered = bandViolations(
2096
- words.filter((b) => !cut.includes(b)),
2097
- format,
2098
- { placements: blockingPlacements(placements) }
2099
- ).filter((v) => v.covered);
2100
- return [...cut.map((b) => b.text), ...covered.map((v) => v.text)];
2101
- }
2102
- var ZONE_MARGIN = 0.12;
2103
- var FEATHER = 4e-3;
2104
- function addZone(into2, zone, width, height) {
2105
- const x0 = zone.x0 * width;
2106
- const x1 = zone.x1 * width;
2107
- const y0 = zone.y0 * height;
2108
- const y1 = zone.y1 * height;
2109
- const margin = Math.max(4, ZONE_MARGIN * Math.max(x1 - x0, y1 - y0));
2110
- for (let y = Math.max(0, Math.floor(y0 - margin)); y < Math.min(height, Math.ceil(y1 + margin)); y++) {
2111
- for (let x = Math.max(0, Math.floor(x0 - margin)); x < Math.min(width, Math.ceil(x1 + margin)); x++) {
2112
- const dx = Math.max(0, x0 - (x + 0.5), x + 0.5 - x1);
2113
- const dy = Math.max(0, y0 - (y + 0.5), y + 0.5 - y1);
2114
- const t = 1 - Math.min(1, Math.sqrt(dx * dx + dy * dy) / margin);
2115
- const i = y * width + x;
2116
- into2[i] = Math.max(into2[i] ?? 0, t * t * (3 - 2 * t));
2117
- }
2118
- }
2119
- }
2120
- function restoreMask(diff, zones, words) {
2121
- const { width, height } = diff;
2122
- const zone = new Float32Array(width * height);
2123
- for (const z7 of zones) addZone(zone, z7, width, height);
2124
- const laid = boxBlur(
2125
- Float32Array.from(diff.flat, (f, i) => f && (diff.detail[i] ?? 0) > KEPT_DETAIL || diff.ground[i] ? 1 : 0),
2126
- width,
2127
- height,
2128
- 1
2129
- );
2130
- const off = trustOf(width, height, words).map((t, i) => t > 0 && (laid[i] ?? 0) === 0 ? 0 : 1);
2131
- const held = zone.map(
2132
- (z7, i) => z7 > 0 && !off[i] ? z7 * Math.min(1, Math.max(0, (MOVED - (diff.structure[i] ?? 0)) / (MOVED - STILL))) : 0
2133
- );
2134
- const feathered = soften(held, width, height, Math.max(2, Math.round(width * FEATHER)));
2135
- return feathered.map((m, i) => off[i] ? 0 : m);
2136
- }
2137
- function restoreSubjects(aligned, cut, gain, mask) {
2138
- const { width, height } = cut;
2139
- const out = Buffer.alloc(width * height * 3);
2140
- for (let i = 0; i < width * height; i++) {
2141
- const m = mask[i] ?? 0;
2142
- for (let c = 0; c < 3; c++) {
2143
- const own = aligned.data[i * aligned.channels + c] ?? 0;
2144
- if (m <= 0) {
2145
- out[i * 3 + c] = own;
2146
- continue;
2147
- }
2148
- const back = Math.min(255, (cut.data[i * cut.channels + c] ?? 0) * (gain[i * 3 + c] ?? 1));
2149
- out[i * 3 + c] = Math.round(own * (1 - m) + back * m);
2150
- }
2151
- }
2152
- return { data: out, width, height, channels: 3 };
2153
- }
2154
- var KEPT_DETAIL = 24;
2155
- function keptShare(diff, words) {
2156
- const { width, height } = diff;
2157
- let textured = 0;
2158
- let kept = 0;
2159
- for (let i = 0; i < width * height; i++) {
2160
- if (diff.flat[i] || diff.surface[i]) continue;
2161
- const x = i % width;
2162
- if (inSpans2(words, (x + 0.5) / width, ((i - x) / width + 0.5) / height)) continue;
2163
- textured++;
2164
- if ((diff.detail[i] ?? 0) < KEPT_DETAIL) kept++;
2165
- }
2166
- return textured > 0 ? kept / textured : 1;
2167
- }
2168
- function cropRaw(img, rect) {
2169
- const data = Buffer.alloc(rect.width * rect.height * 3);
2170
- for (let y = 0; y < rect.height; y++) {
2171
- const from = ((rect.y + y) * img.width + rect.x) * img.channels;
2172
- if (img.channels === 3) {
2173
- img.data.copy(data, y * rect.width * 3, from, from + rect.width * 3);
2174
- continue;
2175
- }
2176
- for (let x = 0; x < rect.width; x++) {
2177
- for (let c = 0; c < 3; c++) data[(y * rect.width + x) * 3 + c] = img.data[from + x * img.channels + c] ?? 0;
2178
- }
2179
- }
2180
- return { data, width: rect.width, height: rect.height, channels: 3 };
2181
- }
2182
- function carriedBy(fit, frame, width, height) {
2183
- const at = (x, y) => [
2184
- width / 2 + fit.scale * (x - width / 2) + fit.dx,
2185
- height / 2 + fit.scale * (y - height / 2) + fit.dy
2186
- ];
2187
- const [left = 0, top = 0] = at(frame.x, frame.y);
2188
- const [right = 0, bottom = 0] = at(frame.x + frame.width, frame.y + frame.height);
2189
- return Math.max(
2190
- 0,
2191
- -left / frame.width,
2192
- -top / frame.height,
2193
- (right - width) / frame.width,
2194
- (bottom - height) / frame.height
2195
- );
2196
- }
2197
- var SHOWN_MIN = 0.5;
2198
- var JUDGED_WIDTH = 720;
2199
- function shrinkRaw(img, f) {
2200
- const width = Math.floor(img.width / f);
2201
- const height = Math.floor(img.height / f);
2202
- const data = Buffer.alloc(width * height * 3);
2203
- for (let i = 0; i < width * height; i++) {
2204
- const x = i % width * f;
2205
- const y = Math.floor(i / width) * f;
2206
- for (let c = 0; c < 3; c++) {
2207
- let sum = 0;
2208
- for (let j = 0; j < f; j++) {
2209
- const row = ((y + j) * img.width + x) * img.channels + c;
2210
- for (let k = 0; k < f; k++) sum += img.data[row + k * img.channels] ?? 0;
2211
- }
2212
- data[i * 3 + c] = Math.round(sum / (f * f));
2213
- }
2214
- }
2215
- return { data, width, height, channels: 3 };
2216
- }
2217
- function axisTaps(from, to) {
2218
- const near = new Int32Array(to);
2219
- const far = new Int32Array(to);
2220
- const t = new Float32Array(to);
2221
- for (let k = 0; k < to; k++) {
2222
- const u = Math.min(from - 1, Math.max(0, (k + 0.5) * from / to - 0.5));
2223
- near[k] = Math.floor(u);
2224
- far[k] = Math.min(from - 1, Math.floor(u) + 1);
2225
- t[k] = u - Math.floor(u);
2226
- }
2227
- return { near, far, t };
2228
- }
2229
- function enlargeRow(values, out, xs, row, stride) {
2230
- const { top, bottom, fy } = row;
2231
- for (let x = 0; x < row.width; x++) {
2232
- const left = xs.near[x] ?? 0;
2233
- const right = xs.far[x] ?? 0;
2234
- const fx = xs.t[x] ?? 0;
2235
- const o = (row.y * row.width + x) * stride;
2236
- for (let c = 0; c < stride; c++) {
2237
- const upper = (values[(top + left) * stride + c] ?? 0) * (1 - fx) + (values[(top + right) * stride + c] ?? 0) * fx;
2238
- const lower = (values[(bottom + left) * stride + c] ?? 0) * (1 - fx) + (values[(bottom + right) * stride + c] ?? 0) * fx;
2239
- out[o + c] = upper * (1 - fy) + lower * fy;
2240
- }
2241
- }
2242
- }
2243
- function enlarge(values, from, to, stride) {
2244
- if (from.width === to.width && from.height === to.height) return values;
2245
- const xs = axisTaps(from.width, to.width);
2246
- const ys = axisTaps(from.height, to.height);
2247
- const out = new Float32Array(to.width * to.height * stride);
2248
- for (let y = 0; y < to.height; y++) {
2249
- const top = (ys.near[y] ?? 0) * from.width;
2250
- const bottom = (ys.far[y] ?? 0) * from.width;
2251
- enlargeRow(values, out, xs, { y, top, bottom, fy: ys.t[y] ?? 0, width: to.width }, stride);
2252
- }
2253
- return out;
2254
- }
2255
- function moveOnRender(m, frame, width, height) {
2256
- const x = (v) => (frame.x + v * frame.width) / width;
2257
- const y = (v) => (frame.y + v * frame.height) / height;
2258
- return {
2259
- group: { x0: x(m.group.x0), y0: y(m.group.y0), x1: x(m.group.x1), y1: y(m.group.y1) },
2260
- fit: {
2261
- scale: m.fit.scale,
2262
- cx: x(m.fit.cx),
2263
- cy: y(m.fit.cy),
2264
- dx: m.fit.dx * frame.width / width,
2265
- dy: m.fit.dy * frame.height / height
2266
- }
2267
- };
2268
- }
2269
- var overlaps2 = (a, b) => a.x0 < b.x1 && a.x1 > b.x0 && a.y0 < b.y1 && a.y1 > b.y0;
2270
- var shifted = (box, dx, dy) => ({
2271
- ...box,
2272
- x0: box.x0 + dx,
2273
- y0: box.y0 + dy,
2274
- x1: box.x1 + dx,
2275
- y1: box.y1 + dy
2276
- });
2277
- var moveOf = (box, moves) => moves.find((m) => inSpans2([m.group], (box.x0 + box.x1) / 2, (box.y0 + box.y1) / 2));
2278
- var hull = (a, b) => ({
2279
- x0: Math.min(a.x0, b.x0),
2280
- y0: Math.min(a.y0, b.y0),
2281
- x1: Math.max(a.x1, b.x1),
2282
- y1: Math.max(a.y1, b.y1)
2283
- });
2284
- var BARE = 0.02;
2285
- var frameSpan = (frame, width, height) => ({
2286
- x0: frame.x / width,
2287
- y0: frame.y / height,
2288
- x1: (frame.x + frame.width) / width,
2289
- y1: (frame.y + frame.height) / height
2290
- });
2291
- var CARD_CUT = 5e-3;
2292
- function cardCut(band, f) {
2293
- const w = f.x1 - f.x0;
2294
- const h = f.y1 - f.y0;
2295
- const across2 = band.x0 <= f.x0 + FRAME_MARGIN * w && band.x1 >= f.x1 - FRAME_MARGIN * w;
2296
- const down = band.y0 <= f.y0 + FRAME_MARGIN * h && band.y1 >= f.y1 - FRAME_MARGIN * h;
2297
- const pastY = band.y0 < f.y0 - CARD_CUT * h || band.y1 > f.y1 + CARD_CUT * h;
2298
- const pastX = band.x0 < f.x0 - CARD_CUT * w || band.x1 > f.x1 + CARD_CUT * w;
2299
- return pastY && !across2 || pastX && !down;
2300
- }
2301
- function cutCardOf(laid, line, f) {
2302
- const band = bandUnder(laid, line);
2303
- return band && cardCut(band, f) ? band : null;
2304
- }
2305
- var unique = (boxes) => boxes.filter(
2306
- (b, i) => boxes.findIndex((o) => o.x0 === b.x0 && o.y0 === b.y0 && o.x1 === b.x1 && o.y1 === b.y1) === i
2307
- );
2308
- function merged(spans) {
2309
- const out = [];
2310
- for (const s of spans) {
2311
- let joined = s;
2312
- for (let i = out.length - 1; i >= 0; i--) {
2313
- const o = out[i];
2314
- if (o && overlaps2(o, joined)) {
2315
- joined = hull(o, joined);
2316
- out.splice(i, 1);
2317
- }
2318
- }
2319
- out.push(joined);
2320
- }
2321
- return out;
2322
- }
2323
- function carriersOf(m, laid, designed) {
2324
- const lines = designed.filter((b) => inSpans2([m.group], (b.x0 + b.x1) / 2, (b.y0 + b.y1) / 2));
2325
- const bands = lines.flatMap((b) => {
2326
- const band = bandUnder(laid, b);
2327
- return band ? [band] : [];
2328
- });
2329
- if (bands.length === 0) return "picture";
2330
- return bands.length < lines.length ? "mixed" : merged(bands);
2331
- }
2332
- function bandMoves(banded, moves, p, at) {
2333
- const faces = p.subjects.filter((s) => s.kind === "face");
2334
- const out = [];
2335
- for (const { move: m, band } of banded) {
2336
- if (m.fit.scale < 1 - 1e-9 || out.some((o) => overlaps2(o.band, band))) return null;
2337
- const { dx, dy } = m.fit;
2338
- const landing = shifted(band, dx, dy);
2339
- const carried = p.words.designed.filter((b) => inSpans2([band], (b.x0 + b.x1) / 2, (b.y0 + b.y1) / 2));
2340
- const others = p.words.designed.filter((b) => !carried.includes(b));
2341
- const ends = (b) => {
2342
- const own = moveOf(b, moves);
2343
- return own ? movedSpan(at.extent(b), own.fit) : at.extent(b);
2344
- };
2345
- const lost = wordsLost(
2346
- carried.map((b) => at.inFrame(shifted(b, dx, dy))),
2347
- p.format,
2348
- p.placements
2349
- );
2350
- const crossed = carried.some((b) => (moveOf(b, moves) ?? m) !== m) || others.some((b) => overlaps2(ends(b), hull(band, landing)));
2351
- if (lost.length > 0 || crossed || facesUnder([landing], faces).length > 0) return null;
2352
- out.push({ band, dx, dy, words: carried });
2353
- }
2354
- return out;
2355
- }
2356
- function wordsMoved(p, out, moves) {
2357
- const { layer } = wordsLayer(p.aligned, p.cut, p.words.designed, {
2358
- subjects: p.subjects,
2359
- keepOut: p.words.inScene
2360
- });
2361
- const part = movedPart(layer, moves);
2362
- const left = soften(
2363
- part.alpha.map((a) => a > 0 ? 1 : 0),
2364
- p.cut.width,
2365
- p.cut.height,
2366
- 2
2367
- ).map((a, i) => Math.max(a, part.alpha[i] ?? 0));
2368
- return compose(restoreSubjects(out, p.cut, p.gain, left), moveLayer(part, moves));
2369
- }
2370
- function placeWords(p) {
2371
- const { width, height } = p.cut;
2372
- const inFrame = (b) => ({
2373
- ...b,
2374
- x0: (b.x0 * width - p.frame.x) / p.frame.width,
2375
- x1: (b.x1 * width - p.frame.x) / p.frame.width,
2376
- y0: (b.y0 * height - p.frame.y) / p.frame.height,
2377
- y1: (b.y1 * height - p.frame.y) / p.frame.height
2378
- });
2379
- const showing = (b) => b.x1 > 0 && b.y1 > 0 && b.x0 < 1 && b.y0 < 1;
2380
- const laid = laidMap(p.judged.aligned, p.judged.cut);
2381
- const f = frameSpan(p.frame, width, height);
2382
- const placed2 = p.words.designed.map((b) => {
2383
- const card = cutCardOf(laid, b, f);
2384
- return card ? { ...b, ...card } : b;
2385
- });
2386
- const plan = planWordsShift(unique(placed2).map(inFrame).filter(showing), p.format, {
2387
- ...p.placements ? { placements: p.placements } : {},
2388
- ...p.minScale !== void 0 ? { minScale: p.minScale } : {},
2389
- faces: p.subjects.filter((s) => s.kind === "face").map(inFrame).filter(showing),
2390
- // Never into the logo's slot, nor out of it: a block moved out of it had its band cut through the letters.
2391
- ...p.keepOut ? { keepOut: p.keepOut } : {}
2392
- });
2393
- if (plan.reason || plan.moves.length === 0) return null;
2394
- const moves = plan.moves.map((m) => moveOnRender(m, p.frame, width, height));
2395
- const under = moves.map((move) => ({ move, on: carriersOf(move, laid, p.words.designed) }));
2396
- const unsure = (u) => u.on === "mixed" || u.on === "picture" && laidAround(laid, u.move.group) > BARE;
2397
- if (under.some(unsure)) return null;
2398
- const banded = under.flatMap((u) => Array.isArray(u.on) ? u.on.map((band) => ({ move: u.move, band })) : []);
2399
- const bands = bandMoves(banded, moves, p, { inFrame, extent: (b) => bandUnder(laid, b) ?? b });
2400
- if (!bands) return null;
2401
- const loose = under.flatMap((u) => u.on === "picture" ? [u.move] : []);
2402
- let out = loose.length > 0 ? wordsMoved(p, p.out, loose) : p.out;
2403
- for (const band of bands) out = moveBand({ aligned: p.aligned, cut: p.cut, out }, band);
2404
- return { out, moves: plan.moves };
2405
- }
2406
- function takeWhole(input) {
2407
- const { render, cut, frame } = input;
2408
- const fit = registerToSource(render, cut, input.words?.designed ?? []);
2409
- const aligned = warpToCut(render, fit);
2410
- if (!input.words) {
2411
- const out2 = cropRaw(aligned, frame);
2412
- return { ok: true, out: out2, restored: [], covered: [], moves: [], kept: 1, residual: fit.residual };
2413
- }
2414
- const judging = judge(input, input.words, fit, aligned);
2415
- const { verdict, kept } = judging;
2416
- const misplaced = !verdict.ok && (verdict.problem === "words_lost" || verdict.problem === "words_over_face");
2417
- if (!verdict.ok && !misplaced) return { ...verdict, kept, residual: fit.residual };
2418
- const { out, gain, taken } = putBack(input, input.words, aligned, judging);
2419
- const done = { ...taken, kept, residual: fit.residual };
2420
- if (verdict.ok) return { ok: true, out: cropRaw(out, frame), moves: [], ...done };
2421
- const placed2 = placeWords({
2422
- aligned,
2423
- cut,
2424
- out,
2425
- gain: gain(),
2426
- judged: judging.judged,
2427
- frame,
2428
- words: input.words,
2429
- subjects: input.subjects,
2430
- format: input.format,
2431
- ...input.placements ? { placements: input.placements } : {},
2432
- ...input.minScale !== void 0 ? { minScale: input.minScale } : {},
2433
- ...input.keepOut ? { keepOut: input.keepOut } : {}
2434
- });
2435
- if (!placed2) return { ...verdict, kept, residual: fit.residual, whole: { out: cropRaw(out, frame), ...taken } };
2436
- return { ok: true, out: cropRaw(placed2.out, frame), moves: placed2.moves, ...done };
2437
- }
2438
- function judge(input, read, fit, aligned) {
2439
- const { cut, frame } = input;
2440
- const { width, height } = cut;
2441
- const words = read.designed.map((b) => padded(b, width, height));
2442
- const shrink2 = Math.max(1, Math.round(width / JUDGED_WIDTH));
2443
- const judged = shrink2 > 1 ? { aligned: shrinkRaw(aligned, shrink2), cut: shrunkCuts(cut, String(shrink2), () => shrinkRaw(cut, shrink2)) } : { aligned, cut };
2444
- const diff = renderDiff(judged.aligned, judged.cut, words);
2445
- const drifts = input.subjects.map((s) => ({ subject: s, ...subjectDrift(diff, s, words) }));
2446
- const inFrame = (b) => ({
2447
- ...b,
2448
- x0: (b.x0 * width - frame.x) / frame.width,
2449
- x1: (b.x1 * width - frame.x) / frame.width,
2450
- y0: (b.y0 * height - frame.y) / frame.height,
2451
- y1: (b.y1 * height - frame.y) / frame.height
2452
- });
2453
- const kept = keptShare(diff, words);
2454
- const gone = /* @__PURE__ */ new Set();
2455
- const laid = laidMap(judged.aligned, judged.cut);
2456
- const f = frameSpan(frame, width, height);
2457
- const carded = read.designed.filter((b) => cutCardOf(laid, b, f)).map((b) => b.text);
2458
- const lost = wordsLost(read.designed.map(inFrame), input.format, input.placements, input.keepOut);
2459
- const base = {
2460
- kept,
2461
- carried: carriedBy(fit, frame, width, height),
2462
- lost: [...lost, ...carded.filter((t) => !lost.includes(t))]
2463
- };
2464
- const faces = () => input.subjects.filter((s) => s.kind === "face" && !gone.has(s));
2465
- const readingNow = () => ({
2466
- ...base,
2467
- subjects: drifts.filter((d) => !gone.has(d.subject)).map((d) => ({ label: d.subject.label, moved: d.moved, drift: d.drift, shown: d.shown })),
2468
- onFace: wordsOnFaces(read.designed, faces())
2469
- });
2470
- let verdict = wholeVerdict(readingNow());
2471
- const relocated = [];
2472
- for (let round = 0; round < 2 && !verdict.ok && FOLLOWED.has(verdict.problem); round++) {
2473
- const suspects = verdict.problem === "subject_redrawn" ? drifts.filter((d) => !gone.has(d.subject) && d.moved > REDRAWN).map((d) => d.subject) : facesUnder(read.designed, faces());
2474
- const found = relocations(withTheirPeople(suspects, input.subjects), judged);
2475
- if (!found) break;
2476
- relocated.push(...found);
2477
- for (const r of found) gone.add(r.subject);
2478
- verdict = wholeVerdict(readingNow());
2479
- }
2480
- return { verdict, reading: readingNow(), kept, diff, judged, words, drifts, relocated };
2481
- }
2482
- function withTheirPeople(suspects, subjects) {
2483
- const holds2 = (outer, inner) => outer.x0 <= inner.x0 + 0.01 && outer.y0 <= inner.y0 + 0.01 && outer.x1 >= inner.x1 - 0.01 && outer.y1 >= inner.y1 - 0.01;
2484
- const people = subjects.filter(
2485
- (p) => p.kind === "person" && suspects.some((f) => f.kind === "face" && f.label === p.label && holds2(p, f))
2486
- );
2487
- return [.../* @__PURE__ */ new Set([...suspects, ...people])];
2488
- }
2489
- var FOLLOWED = /* @__PURE__ */ new Set(["subject_redrawn", "words_over_face"]);
2490
- function putBack(input, read, aligned, j) {
2491
- const { cut } = input;
2492
- const full = { width: cut.width, height: cut.height };
2493
- const settled = j.verdict.ok ? j.verdict : wholeVerdict({ ...j.reading, lost: [], onFace: [] });
2494
- const restored = settled.ok ? settled.restore : [];
2495
- const back = input.subjects.filter((s) => restored.includes(s.label));
2496
- const zones = [...back, ...read.inScene.map((b) => padded(b, full.width, full.height))];
2497
- const covered = j.drifts.filter((d) => (d.subject.kind === "product" || d.subject.kind === "animal") && d.shown < SHOWN_MIN).map((d) => d.subject.label);
2498
- let enlarged;
2499
- const gain = () => {
2500
- enlarged ??= enlarge(j.diff.gain, j.diff, full, 3);
2501
- return enlarged;
2502
- };
2503
- let out = zones.length === 0 ? aligned : restoreSubjects(aligned, cut, gain(), enlarge(restoreMask(j.diff, zones, j.words), j.diff, full, 1));
2504
- for (const r of j.relocated) out = putMoved(out, cut, r, j);
2505
- const moved = j.relocated.map((r) => r.subject.label);
2506
- return { out, gain, taken: { restored: [.../* @__PURE__ */ new Set([...restored, ...moved])], covered } };
2507
- }
2508
- var TRACK_MAX_AREA = 0.06;
2509
- var RELOCATED = 0.8;
2510
- var STAYED = 5e-3;
2511
- function relocations(subjects, judged) {
2512
- if (subjects.length === 0) return null;
2513
- const out = [];
2514
- for (const subject of subjects) {
2515
- if ((subject.x1 - subject.x0) * (subject.y1 - subject.y0) > TRACK_MAX_AREA) return null;
2516
- const place = tracked(judged.aligned, judged.cut, subject);
2517
- const stayed = Math.hypot(place.dx, place.dy) < STAYED && Math.abs(place.scale - 1) < 0.02;
2518
- if (place.score < RELOCATED || stayed) return null;
2519
- out.push({ subject, place });
2520
- }
2521
- return out;
2522
- }
2523
- function movedBox(box, place) {
2524
- const cx = (box.x0 + box.x1) / 2;
2525
- const cy = (box.y0 + box.y1) / 2;
2526
- return {
2527
- x0: cx + place.dx + place.scale * (box.x0 - cx),
2528
- y0: cy + place.dy + place.scale * (box.y0 - cy),
2529
- x1: cx + place.dx + place.scale * (box.x1 - cx),
2530
- y1: cy + place.dy + place.scale * (box.y1 - cy)
2531
- };
2532
- }
2533
- function cutMoved(cut, box, place) {
2534
- const { width, height } = cut;
2535
- const out = Buffer.alloc(width * height * 3);
2536
- if (cut.channels === 3) cut.data.copy(out, 0, 0, width * height * 3);
2537
- else for (let i = 0; i < width * height; i++) cut.data.copy(out, i * 3, i * cut.channels, i * cut.channels + 3);
2538
- const to = movedBox(box, place);
2539
- const margin = (ZONE_MARGIN + FEATHER) * Math.max((to.x1 - to.x0) * width, (to.y1 - to.y0) * height) + 4;
2540
- const cx = (box.x0 + box.x1) / 2 * width;
2541
- const cy = (box.y0 + box.y1) / 2 * height;
2542
- for (let y = Math.max(0, Math.floor(to.y0 * height - margin)); y < Math.min(height, to.y1 * height + margin); y++) {
2543
- for (let x = Math.max(0, Math.floor(to.x0 * width - margin)); x < Math.min(width, to.x1 * width + margin); x++) {
2544
- const u = Math.min(width - 1.001, Math.max(0, cx + (x - cx - place.dx * width) / place.scale));
2545
- const v = Math.min(height - 1.001, Math.max(0, cy + (y - cy - place.dy * height) / place.scale));
2546
- const x0 = Math.floor(u);
2547
- const y0 = Math.floor(v);
2548
- const fx = u - x0;
2549
- const fy = v - y0;
2550
- for (let c = 0; c < 3; c++) {
2551
- const at = (px, py) => cut.data[(py * width + px) * cut.channels + c] ?? 0;
2552
- const top = at(x0, y0) * (1 - fx) + at(x0 + 1, y0) * fx;
2553
- const bottom = at(x0, y0 + 1) * (1 - fx) + at(x0 + 1, y0 + 1) * fx;
2554
- out[(y * width + x) * 3 + c] = Math.round(top * (1 - fy) + bottom * fy);
2555
- }
2556
- }
2557
- }
2558
- return { data: out, width, height, channels: 3 };
2559
- }
2560
- function putMoved(out, cut, r, j) {
2561
- const full = { width: cut.width, height: cut.height };
2562
- const moved = cutMoved(cut, r.subject, r.place);
2563
- const judgedMoved = j.judged.cut.width === cut.width ? moved : shrinkRaw(moved, Math.round(cut.width / j.judged.cut.width));
2564
- const diff = renderDiff(j.judged.aligned, judgedMoved, j.words);
2565
- const mask = restoreMask(diff, [movedBox(r.subject, r.place)], j.words);
2566
- return restoreSubjects(out, moved, enlarge(diff.gain, diff, full, 3), enlarge(mask, diff, full, 1));
2567
- }
2568
-
2569
- // src/engine/nodes/local/staticFormat.ts
2570
- var Usage = z4.object({ model: z4.string(), inputTokens: z4.number(), outputTokens: z4.number(), costUsd: z4.number() }).strict();
2571
- var Unit = z4.number().min(0).max(1);
2572
- var SpanSchema = z4.object({ x0: Unit, y0: Unit, x1: Unit, y1: Unit }).strict();
2573
- var Copy = z4.array(z4.object({ text: z4.string().min(1), role: z4.string().optional() }).strict());
2574
- var Rect = z4.object({ x: z4.number(), y: z4.number(), width: z4.number(), height: z4.number() }).strict();
2575
- var REASONS = [
2576
- "band_too_far",
2577
- "words_over_face",
2578
- "subject_covered",
2579
- "subject_cut",
2580
- "words_misaligned",
2581
- "words_not_read",
2582
- "not_read"
2583
- ];
2584
- var FormatFacts = z4.object({
2585
- format: z4.string(),
2586
- lead: z4.boolean(),
2587
- plate: z4.object({ width: z4.number(), height: z4.number() }).strict(),
2588
- crop: Rect,
2589
- render_ratio: z4.string(),
2590
- upscale: z4.number(),
2591
- /** Each block of words code moved (into the band, off a face): its scale and shift, fractions of the size. */
2592
- moves: z4.array(z4.object({ scale: z4.number(), dx: z4.number(), dy: z4.number() }).strict()),
2593
- /** How far the words render sat from the cut once lined up (RMS grey levels): the spike's calibration of `MISALIGNED`. */
2594
- residual: z4.number().optional(),
2595
- reason: z4.enum(REASONS).optional(),
2596
- /** `subject_covered`: the products and animals the words hide most of in this size, as the reader names them. */
2597
- covered: z4.array(z4.string()).optional(),
2598
- /**
2599
- * How the words were laid: `whole`, the words model's whole render, its redrawn subjects put back
2600
- * from the picture; `masked`, only what it changed at the words, on the picture (when its render
2601
- * could not be taken whole twice). Absent when no words were set (`subject_cut`).
2602
- */
2603
- words_mode: z4.enum(["whole", "masked"]).optional(),
2604
- /** `whole`: the share of the picture's detail the render kept where it was (`keptShare`). */
2605
- kept: z4.number().optional(),
2606
- /** `whole`: the people, faces and products put back from the picture where the render redrew them. */
2607
- restored: z4.array(z4.string()).optional(),
2608
- /** Why the first render could not be taken whole, so the words were set a second time. */
2609
- retried: z4.enum(WHOLE_PROBLEMS).optional(),
2610
- /** `masked`: why the second render could not be taken whole either. */
2611
- refused: z4.enum(WHOLE_PROBLEMS).optional(),
2612
- reverted: z4.number(),
2613
- /** `masked`: the mean difference from the cut outside the words layer, 0 by construction. */
2614
- identity: z4.number().optional(),
2615
- steps: z4.array(
2616
- z4.object({
2617
- name: z4.enum(["subjects", "words", "words_again", "boxes"]),
2618
- cached: z4.boolean(),
2619
- credits: z4.number(),
2620
- ms: z4.number()
2621
- }).strict()
2622
- )
2623
- }).strict();
2624
- var Words = z4.object({
2625
- model: z4.string().min(1),
2626
- quality: z4.string().optional(),
2627
- prompt: z4.string().min(1),
2628
- /** A change to the words of this size (`--reword`, an autofix): the previous render (`inputs.previous`) leads. */
2629
- edit: z4.object({ instruction: z4.string().min(1) }).strict().optional()
2630
- }).strict();
2631
- var MISALIGNED = 40;
2632
- var FormatParamsSchema = z4.object({
2633
- format: z4.string().regex(/^\d+(?:\.\d+)?:\d+(?:\.\d+)?$/),
2634
- lead: z4.boolean().optional(),
2635
- placements: z4.array(z4.string().min(1)).optional(),
2636
- words: Words,
2637
- copy: Copy.optional(),
2638
- in_scene: z4.array(z4.string().min(1)).optional(),
2639
- /** The plan's subject zone, fractions of the plate: what the cut centres on when no subject was read. */
2640
- core: SpanSchema.optional(),
2641
- band_min_scale: z4.number().min(0.5).max(1).optional(),
2642
- /**
2643
- * The other sizes cut from the same picture (a variant's lead is checked against them): when
2644
- * one would cut a face, a product or a head, no words are paid for (`subject_cut`).
2645
- */
2646
- check_formats: z4.array(z4.string().regex(/^\d+(?:\.\d+)?:\d+(?:\.\d+)?$/)).optional(),
2647
- /**
2648
- * The brand's logo file is placed on this size afterwards (`static_logo`): the words draw no logo
2649
- * and keep its slot empty, planned here inside the size's safe area off every face and product,
2650
- * from the logo's shape (`aspect`, width over height) and where the concept puts it (`position`).
2651
- */
2652
- logo_slot: z4.object({ aspect: z4.number().positive(), position: z4.enum(LOGO_POSITIONS).optional() }).strict().optional()
2653
- }).strict();
2654
- var staticFormatNode = defineNode({
2655
- id: "static_format",
2656
- version: "1.9.0",
2657
- category: "image",
2658
- location: "local",
2659
- billing: "reported",
2660
- summary: "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`).",
2661
- when_to_use: "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.",
2662
- inputs: z4.object({
2663
- plate: ImageRef,
2664
- subjects: z4.array(SubjectBoxSchema).optional(),
2665
- logo: ImageRef.optional(),
2666
- type: ImageRef.optional(),
2667
- style: ImageRef.optional(),
2668
- refs: z4.array(ImageRef).optional(),
2669
- previous: ImageRef.optional()
2670
- }).strict(),
2671
- params: FormatParamsSchema,
2672
- outputs: z4.object({
2673
- image: ImageRef,
2674
- cut: ImageRef,
2675
- words_raw: ImageRef.optional(),
2676
- words_alpha: ImageRef.optional(),
2677
- /** The slot the words left empty for the logo file, in the size's pixels (`params.logo_slot`). */
2678
- logo_slot: Rect.optional(),
2679
- facts: FormatFacts,
2680
- usage: z4.array(Usage).optional()
2681
- }).strict(),
2682
- outputKinds: { image: "image", cut: "image", words_raw: "image", words_alpha: "image" },
2683
- cost: ({ params }) => imageGenerateNode.cost?.({ params: wordsCallParams(params.words, "1:1") }) ?? {
2684
- credits: 0,
2685
- seconds_estimate: 60
2686
- },
2687
- async execute({ inputs, params, ctx }) {
2688
- return await formatSize(inputs, params, ctx);
2689
- }
2690
- });
2691
- function wordsCallParams(words, ratio) {
2692
- const prompt = words.edit ? `Edit: ${words.edit.instruction}
2693
-
2694
- ${words.prompt}` : words.prompt;
2695
- return { model: words.model, prompt, aspect_ratio: ratio, ...words.quality ? { quality: words.quality } : {} };
2696
- }
2697
- var percent = (v) => Math.round(Math.max(0, Math.min(1, v)) * 100);
2698
- function wordsAvoid(faces) {
2699
- if (faces.length === 0) return "";
2700
- const where = faces.map(
2701
- (f) => `a face ${percent(f.y0)}-${percent(f.y1)}% down, ${percent(f.x0)}-${percent(f.x1)}% across`
2702
- );
2703
- return `Keep every word, the logo and the button off ${where.join("; ")}.`;
2704
- }
2705
- function stripsOf(before, after, sides, depth) {
2706
- const cut = [
2707
- ...percent(before) >= 1 ? [{ share: percent(before), side: sides[0] }] : [],
2708
- ...percent(after) >= 1 ? [{ share: percent(after), side: sides[1] }] : []
2709
- ];
2710
- return cut.map(
2711
- (s, i) => i === 0 ? `a strip ${s.share}% ${depth} at its ${s.side}` : `${s.share}% at its ${s.side}`
2712
- );
2713
- }
2714
- function wordsFrame(frame, work, format) {
2715
- const down = stripsOf(frame.y / work.height, 1 - (frame.y + frame.height) / work.height, ["top", "bottom"], "deep");
2716
- const across2 = stripsOf(frame.x / work.width, 1 - (frame.x + frame.width) / work.width, ["left", "right"], "wide");
2717
- const strips = [down.join(" and "), across2.join(" and ")].filter(Boolean);
2718
- if (strips.length === 0) return "";
2719
- const many = down.length + across2.length > 1;
2720
- 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"}.`;
2721
- }
2722
- function splitWordBoxes(boxes, copy, inScene) {
2723
- const logoWords = copy.filter((l) => /logo/i.test(l.role ?? "")).map((l) => l.text);
2724
- const read = withWordmark(boxes, logoWords);
2725
- const lines = copy.filter((l) => !/logo/i.test(l.role ?? ""));
2726
- const ours = new Set(lines.flatMap((line) => boxesOfLine(line, read)));
2727
- const unnamed = (b) => lines.length > 0 && b.kind === "text" && !ours.has(b);
2728
- const scene = /* @__PURE__ */ new Set([...inScene.flatMap((text) => boxesOfLine({ text }, read)), ...read.filter(unnamed)]);
2729
- const buttons = new Set(copy.filter(isButtonLine).flatMap((line) => boxesOfLine(line, read)));
2730
- return {
2731
- designed: read.filter((b) => !scene.has(b)).map((b) => buttons.has(b) ? buttonShape(b) : b),
2732
- inScene: read.filter((b) => scene.has(b))
2733
- };
2734
- }
2735
- function toFrame(b, frame, work) {
2736
- return {
2737
- ...b,
2738
- x0: (b.x0 * work.width - frame.x) / frame.width,
2739
- y0: (b.y0 * work.height - frame.y) / frame.height,
2740
- x1: (b.x1 * work.width - frame.x) / frame.width,
2741
- y1: (b.y1 * work.height - frame.y) / frame.height
2742
- };
2743
- }
2744
- function subjectIn(b, rect, plate) {
2745
- return {
2746
- ...b,
2747
- x0: (b.x0 * plate.width - rect.x) / rect.width,
2748
- y0: (b.y0 * plate.height - rect.y) / rect.height,
2749
- x1: (b.x1 * plate.width - rect.x) / rect.width,
2750
- y1: (b.y1 * plate.height - rect.y) / rect.height
2751
- };
2752
- }
2753
- var visible = (b) => b.x1 > 0 && b.y1 > 0 && b.x0 < 1 && b.y0 < 1;
2754
- async function frameSize(plateBytes, crop, format) {
2755
- const delivered = deliveredSize(format);
2756
- const upscale = delivered.width / crop.rect.width;
2757
- const work = { width: Math.round(crop.render.width * upscale), height: Math.round(crop.render.height * upscale) };
2758
- const frame = {
2759
- x: Math.min(work.width - delivered.width, Math.max(0, Math.round((crop.rect.x - crop.render.x) * upscale))),
2760
- y: Math.min(work.height - delivered.height, Math.max(0, Math.round((crop.rect.y - crop.render.y) * upscale))),
2761
- width: delivered.width,
2762
- height: delivered.height
2763
- };
2764
- const region = { left: crop.render.x, top: crop.render.y, width: crop.render.width, height: crop.render.height };
2765
- const renderCut = await rawOf(await sharp4(plateBytes).extract(region).toBuffer(), work);
2766
- return { upscale, work, frame, renderCut, cutFrame: cropRaw(renderCut, frame) };
2767
- }
2768
- function slotOnWork(rect, frame, work) {
2769
- return {
2770
- x0: (frame.x + rect.x) / work.width,
2771
- y0: (frame.y + rect.y) / work.height,
2772
- x1: (frame.x + rect.x + rect.width) / work.width,
2773
- y1: (frame.y + rect.y + rect.height) / work.height
2774
- };
2775
- }
2776
- var LOGO_AVOIDS = /* @__PURE__ */ new Set(["person", "face", "product", "animal"]);
2777
- var PLAIN_GROUND_SPREAD = 18;
2778
- function sizeLogoSlot(params, frame, work, subjects, picture) {
2779
- if (!params.logo_slot) return void 0;
2780
- const avoid = subjects.filter((s) => LOGO_AVOIDS.has(s.kind)).map((s) => ({
2781
- x: Math.round(s.x0 * work.width - frame.x),
2782
- y: Math.round(s.y0 * work.height - frame.y),
2783
- width: Math.round((s.x1 - s.x0) * work.width),
2784
- height: Math.round((s.y1 - s.y0) * work.height)
2785
- }));
2786
- const size = { width: frame.width, height: frame.height };
2787
- const safe = blockingArea(params.format, params.placements);
2788
- const shape = {
2789
- aspect: params.logo_slot.aspect,
2790
- ...params.logo_slot.position ? { position: params.logo_slot.position } : {}
2791
- };
2792
- const spot = chooseLogoSpot(size, safe, {
2793
- ...shape,
2794
- subjects: avoid,
2795
- ...picture ? {
2796
- calm: (r) => spreadUnder(picture, r) <= PLAIN_GROUND_SPREAD,
2797
- crossesEdge: (r) => straightEdgeIn(picture, r)
2798
- } : {}
2799
- });
2800
- return spot?.slot ?? designerSpots(size, safe, shape)[0];
2801
- }
2802
- async function setWords(inputs, params, run, shown, again) {
2803
- const callParams = wordsCallParams(params.words, shown.ratio);
2804
- const prompt = [
2805
- callParams.prompt,
2806
- wordsAvoid(shown.faces),
2807
- wordsFrame(shown.frame, shown.work, params.format),
2808
- shown.logo ? logoSlotLine(slotOnWork(shown.logo.clear, shown.frame, shown.work), shown.logo.position) : "",
2809
- again
2810
- ].filter(Boolean).join("\n\n");
2811
- const references = [
2812
- ...inputs.previous && params.words.edit ? [inputs.previous] : [],
2813
- shown.cut,
2814
- ...[inputs.logo, inputs.type, inputs.style].filter((r) => r !== void 0),
2815
- ...inputs.refs ?? []
2816
- ];
2817
- const call = { ...callParams, prompt };
2818
- return await timedStep(
2819
- run,
2820
- again ? "words_again" : "words",
2821
- { params: call, references: references.map((r) => r.sha256) },
2822
- async (suffix, stepCtx) => {
2823
- const out = await callBackendExec({
2824
- nodeType: imageGenerateNode.id,
2825
- nodeVersion: imageGenerateNode.version,
2826
- params: imageGenerateNode.params.parse(call),
2827
- inputs: { reference: references },
2828
- outputKinds: { images: "image" },
2829
- ctx: stepCtx,
2830
- idempotencySuffix: suffix
2831
- });
2832
- const first = Array.isArray(out.images) ? out.images[0] : void 0;
2833
- if (!first) throw new Error("static_format: the words call returned no picture");
2834
- return first;
2835
- }
2836
- );
2837
- }
2838
- function wordsRead(reading, params) {
2839
- if (reading.status === "read") return splitWordBoxes(reading.boxes, params.copy ?? [], params.in_scene ?? []);
2840
- return { designed: [{ text: "", kind: "text", x0: 0, y0: 0, x1: 1, y1: 1 }], inScene: [] };
2841
- }
2842
- function liftWords(render, framing, words, subjects, params, keepOut = []) {
2843
- const faces = subjects.filter((b) => b.kind === "face");
2844
- const fit = registerToSource(render, framing.renderCut, words.read ? words.designed : []);
2845
- const misaligned = fit.residual > MISALIGNED;
2846
- const aligned = misaligned ? render : warpToCut(render, fit);
2847
- const { layer, reverted } = wordsLayer(aligned, framing.renderCut, words.designed, {
2848
- subjects,
2849
- keepOut: words.inScene,
2850
- boxesOnly: misaligned
2851
- });
2852
- const sized = cropLayer(layer, framing.frame);
2853
- const inFrame = (b) => toFrame(b, framing.frame, framing.work);
2854
- const frameFaces = faces.map(inFrame).filter(visible);
2855
- const frameWords = words.designed.map(inFrame).filter(visible);
2856
- const plan = words.read ? planWordsShift(frameWords, params.format, {
2857
- ...params.placements ? { placements: params.placements } : {},
2858
- ...params.band_min_scale !== void 0 ? { minScale: params.band_min_scale } : {},
2859
- // A move never takes words into the slot kept for the logo, nor is made for it: moving a block
2860
- // out of it cut its band through the letters (Cubicup 4:5, round 6); the logo goes elsewhere.
2861
- faces: frameFaces,
2862
- keepOut
2863
- }) : { moves: [] };
2864
- const { layer: placed2, covered } = protectFaces(
2865
- plan.moves.length > 0 ? moveLayer(sized, plan.moves) : sized,
2866
- frameFaces
2867
- );
2868
- const hidden = coveredSubjects(placed2, subjects.map(inFrame).filter(visible));
2869
- const reason = (words.read ? void 0 : "words_not_read") ?? plan.reason ?? (misaligned ? "words_misaligned" : void 0) ?? (covered > 0 ? "words_over_face" : void 0) ?? (hidden.length > 0 ? "subject_covered" : void 0);
2870
- return {
2871
- out: compose(framing.cutFrame, placed2),
2872
- alpha: placed2.alpha,
2873
- moves: plan.moves,
2874
- residual: fit.residual,
2875
- reverted,
2876
- covered: hidden,
2877
- ...reason ? { reason } : {}
2878
- };
2879
- }
2880
- async function alphaPng(alpha, width, height) {
2881
- return await sharp4(Buffer.from(alpha.map((a) => Math.round(a * 255))), { raw: { width, height, channels: 1 } }).png().toBuffer();
2882
- }
2883
- var round3 = (v) => Math.round(v * 1e3) / 1e3;
2884
- var round1 = (v) => Math.round(v * 10) / 10;
2885
- function liftedFacts(base, lifted, run) {
2886
- const reason = lifted.reason ?? (run.subjectsRead ? void 0 : "not_read");
2887
- return {
2888
- ...base,
2889
- ...reason ? { reason } : {},
2890
- ...lifted.covered.length > 0 ? { covered: lifted.covered } : {},
2891
- moves: lifted.moves.map(({ fit }) => ({ scale: round3(fit.scale), dx: round3(fit.dx), dy: round3(fit.dy) })),
2892
- residual: round1(lifted.residual),
2893
- reverted: round3(lifted.reverted),
2894
- identity: run.identity,
2895
- steps: run.steps
2896
- };
2897
- }
2898
- async function wordsTry(inputs, params, run, shown, again) {
2899
- const ref = await setWords(inputs, params, run, shown, again);
2900
- const { bytes } = await imageOf(ref, "static_format");
2901
- const reading = await timedStep(
2902
- run,
2903
- "boxes",
2904
- { render: ref.sha256 },
2905
- () => readTextBoxes(bytes, { onSpend: (u) => run.usage.push(u) }),
2906
- { keep: isRead }
2907
- );
2908
- return { ref, render: await rawOf(bytes, run.framing.work), reading };
2909
- }
2910
- function takeOf(t, run, subjects, params) {
2911
- const { framing } = run;
2912
- return takeWhole({
2913
- render: t.render,
2914
- cut: framing.renderCut,
2915
- frame: framing.frame,
2916
- words: t.reading.status === "read" ? splitWordBoxes(t.reading.boxes, params.copy ?? [], params.in_scene ?? []) : null,
2917
- subjects,
2918
- format: params.format,
2919
- ...params.placements ? { placements: params.placements } : {},
2920
- ...params.band_min_scale !== void 0 ? { minScale: params.band_min_scale } : {},
2921
- ...run.keepOut.length > 0 ? { keepOut: run.keepOut } : {}
2922
- });
2923
- }
2924
- var quoted = (what) => what.map((w) => `"${w}"`).join(", ");
2925
- function setAgain(problem, what) {
2926
- const said = {
2927
- picture_moved: "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.",
2928
- 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.`,
2929
- 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.`,
2930
- words_over_face: "Your last version set words over a face. Keep every word, the logo and the button off every face."
2931
- };
2932
- return said[problem];
2933
- }
2934
- var MISPLACED = {
2935
- words_lost: "band_too_far",
2936
- words_over_face: "words_over_face"
2937
- };
2938
- async function wholeSize(take2, t, run, base, why = {}) {
2939
- const { retried } = why;
2940
- const image = await run.ctx.assets.ingestBytes({
2941
- bytes: await pngOf(take2.out),
2942
- kind: "image",
2943
- mime: "image/png"
2944
- });
2945
- const reason = (t.reading.status === "read" ? void 0 : "words_not_read") ?? (why.misplaced ? MISPLACED[why.misplaced] : void 0) ?? (take2.covered.length > 0 ? "subject_covered" : void 0) ?? (run.subjectsRead ? void 0 : "not_read");
2946
- const facts = {
2947
- ...base,
2948
- ...reason ? { reason } : {},
2949
- ...take2.covered.length > 0 ? { covered: take2.covered } : {},
2950
- words_mode: "whole",
2951
- kept: round3(take2.kept),
2952
- ...take2.restored.length > 0 ? { restored: take2.restored } : {},
2953
- ...retried ? { retried } : {},
2954
- moves: take2.moves.map(({ fit }) => ({ scale: round3(fit.scale), dx: round3(fit.dx), dy: round3(fit.dy) })),
2955
- residual: round1(take2.residual),
2956
- reverted: 0,
2957
- steps: run.steps
2958
- };
2959
- run.ctx.log(
2960
- `${base.format}: cut ${base.crop.width}x${base.crop.height} (x${base.upscale}), words whole${take2.moves.length > 0 ? ", moved" : ""}${take2.restored.length > 0 ? `, ${take2.restored.join(", ")} put back` : ""}${retried ? ` (set again: ${retried})` : ""}${reason ? `, ${reason}` : ""}`
2961
- );
2962
- return { image, cut: run.cut, words_raw: t.ref, facts };
2963
- }
2964
- async function maskedSize(t, run, base, subjects, params, why) {
2965
- const { framing } = run;
2966
- const lifted = liftWords(
2967
- t.render,
2968
- framing,
2969
- { ...wordsRead(t.reading, params), read: t.reading.status === "read" },
2970
- subjects,
2971
- params,
2972
- run.keepOut
2973
- );
2974
- const identity = identityOutside(lifted.out, framing.cutFrame, lifted.alpha);
2975
- if (identity !== 0) throw new Error(`static_format: the picture outside the words changed (${identity})`);
2976
- const [image, alpha] = await Promise.all([
2977
- run.ctx.assets.ingestBytes({ bytes: await pngOf(lifted.out), kind: "image", mime: "image/png" }),
2978
- run.ctx.assets.ingestBytes({
2979
- bytes: await alphaPng(lifted.alpha, framing.frame.width, framing.frame.height),
2980
- kind: "image",
2981
- mime: "image/png"
2982
- })
2983
- ]);
2984
- const facts = {
2985
- ...liftedFacts(base, lifted, { identity, steps: run.steps, subjectsRead: run.subjectsRead }),
2986
- words_mode: "masked",
2987
- retried: why.retried,
2988
- refused: why.refused
2989
- };
2990
- run.ctx.log(
2991
- `${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}` : ""}`
2992
- );
2993
- return { image, cut: run.cut, words_raw: t.ref, words_alpha: alpha, facts };
2994
- }
2995
- async function formatSize(inputs, params, ctx) {
2996
- const { bytes: plateBytes, size: plate } = await imageOf(inputs.plate, "static_format");
2997
- const steps = [];
2998
- const usage = [];
2999
- const spend = () => usage.length > 0 ? { usage } : {};
3000
- const subjects = inputs.subjects ?? await subjectsStep({ ctx, steps, usage }, inputs.plate, plateBytes);
3001
- const ratios = supportedAspectRatios("image_generate", params.words.model);
3002
- const panels = platePanels(await rawOf(plateBytes, plate));
3003
- const crop = subjectCrop(plate, params.format, subjects, {
3004
- ...params.core ? { core: params.core } : {},
3005
- ...ratios ? { renderRatios: ratios } : {},
3006
- ...panels.length > 0 ? { panels } : {}
3007
- });
3008
- const framing = await frameSize(plateBytes, crop, params.format);
3009
- const cutRef = await ctx.assets.ingestBytes({
3010
- bytes: await pngOf(framing.cutFrame),
3011
- kind: "image",
3012
- mime: "image/png"
3013
- });
3014
- const base = {
3015
- format: params.format,
3016
- lead: params.lead ?? false,
3017
- plate,
3018
- crop: crop.rect,
3019
- render_ratio: crop.render.ratio,
3020
- upscale: round3(framing.upscale)
3021
- };
3022
- const shownSubjects = (subjects ?? []).map((s) => subjectIn(s, crop.render, plate)).filter(visible);
3023
- const logo = sizeLogoSlot(params, framing.frame, framing.work, shownSubjects, greyTable(framing.cutFrame));
3024
- const slotOut = logo ? { logo_slot: logo.rect } : {};
3025
- const elsewhere = (params.check_formats ?? []).filter((f) => f !== params.format).map((f) => ({ format: f, crop: subjectCrop(plate, f, subjects, params.core ? { core: params.core } : {}) })).find((c) => !c.crop.fits);
3026
- if (!crop.fits || elsewhere) {
3027
- const lost = crop.fits && elsewhere ? `${elsewhere.format}: ${elsewhere.crop.cut.join(", ")}` : crop.cut.join(", ");
3028
- ctx.log(`${params.format}: no cut keeps ${lost} whole; the words were not set`);
3029
- const facts = { ...base, reason: "subject_cut", moves: [], reverted: 0, identity: 0, steps };
3030
- return { image: cutRef, cut: cutRef, facts, ...slotOut, ...spend() };
3031
- }
3032
- const shownCut = await ctx.assets.ingestBytes({
3033
- bytes: await pngOf(framing.renderCut),
3034
- kind: "image",
3035
- mime: "image/png"
3036
- });
3037
- const keepOut = logo ? [
3038
- {
3039
- x0: logo.clear.x / framing.frame.width,
3040
- y0: logo.clear.y / framing.frame.height,
3041
- x1: (logo.clear.x + logo.clear.width) / framing.frame.width,
3042
- y1: (logo.clear.y + logo.clear.height) / framing.frame.height
3043
- }
3044
- ] : [];
3045
- const run = { ctx, steps, usage, subjectsRead: subjects !== null, cut: cutRef, framing, keepOut };
3046
- const shown = {
3047
- cut: shownCut,
3048
- ratio: crop.render.ratio,
3049
- faces: shownSubjects.filter((s) => s.kind === "face"),
3050
- frame: framing.frame,
3051
- work: framing.work,
3052
- ...logo ? { logo } : {}
3053
- };
3054
- return { ...await letter({ inputs, params, run, shown, base, subjects: shownSubjects }), ...slotOut, ...spend() };
3055
- }
3056
- async function letter(l) {
3057
- const { inputs, params, run, shown, base, subjects } = l;
3058
- const first = await wordsTry(inputs, params, run, shown);
3059
- const firstTake = takeOf(first, run, subjects, params);
3060
- if (firstTake.ok) return await wholeSize(firstTake, first, run, base);
3061
- const second = await wordsTry(inputs, params, run, shown, setAgain(firstTake.problem, firstTake.what));
3062
- const secondTake = takeOf(second, run, subjects, params);
3063
- const retried = firstTake.problem;
3064
- if (secondTake.ok) return await wholeSize(secondTake, second, run, base, { retried });
3065
- const placed2 = [
3066
- { take: secondTake, t: second },
3067
- { take: firstTake, t: first }
3068
- ].find((p) => p.take.whole);
3069
- const whole = placed2?.take.whole;
3070
- if (placed2 && whole) {
3071
- const taken = { ...whole, moves: [], kept: placed2.take.kept, residual: placed2.take.residual };
3072
- return await wholeSize(taken, placed2.t, run, base, { retried, misplaced: placed2.take.problem });
3073
- }
3074
- const kept = secondTake.kept >= firstTake.kept ? second : first;
3075
- return await maskedSize(kept, run, base, subjects, params, { retried, refused: secondTake.problem });
3076
- }
3077
-
3078
- // src/engine/nodes/local/staticLogo.ts
3079
- import sharp5 from "sharp";
3080
- import { z as z5 } from "zod";
3081
- var Usage2 = z5.object({ model: z5.string(), inputTokens: z5.number(), outputTokens: z5.number(), costUsd: z5.number() }).strict();
3082
- var Rect2 = z5.object({
3083
- x: z5.number().int(),
3084
- y: z5.number().int(),
3085
- width: z5.number().int().positive(),
3086
- height: z5.number().int().positive()
3087
- }).strict();
3088
- var Copy2 = z5.array(z5.object({ text: z5.string().min(1), role: z5.string().optional() }).strict());
3089
- var LogoFacts = z5.object({
3090
- format: z5.string(),
3091
- /** Where the logo file was placed, in the size's pixels. */
3092
- box: Rect2,
3093
- /** The slot it was placed in. */
3094
- slot: Rect2,
3095
- /** Which of the logo's files (`inputs.logos`) was placed: the one that reads on the ground. */
3096
- variant: z5.number().int().nonnegative(),
3097
- /** The colour a file inked in the text colour (`currentColor`) was drawn in, of `params.inks`. */
3098
- ink: z5.string().optional(),
3099
- /** The grey level (0-255) of the ground under the logo, and the contrast of the placed file's ink on it. */
3100
- ground: z5.number(),
3101
- contrast: z5.number(),
3102
- /** The share (0-1) of the logo's solid pixels whose own ground it stands out from; the review blocks under 0.9. */
3103
- legible: z5.number().default(1),
3104
- /** Set when no plain ground held the logo and it sits on a plate of its own: the plate's colour. */
3105
- plate: z5.object({ colour: z5.string() }).strict().optional(),
3106
- /** The headline's box as read on the size; null when the ad has no copy or it was not read. */
3107
- headline: Rect2.nullable(),
3108
- /** Whether the size's words were read for the check. */
3109
- read: z5.boolean(),
3110
- problems: z5.array(
3111
- z5.object({
3112
- element: z5.enum(PLACEMENT_ELEMENTS),
3113
- defect: z5.enum(PLACEMENT_DEFECTS),
3114
- edges: z5.array(z5.enum(PLACEMENT_EDGES))
3115
- }).strict()
3116
- )
3117
- }).strict();
3118
- var LogoParams = z5.object({
3119
- format: z5.string().regex(/^\d+(?:\.\d+)?:\d+(?:\.\d+)?$/),
3120
- placements: z5.array(z5.string().min(1)).optional(),
3121
- /** Where the concept places the logo (`logo_position`, read by `placedLogoPosition`). */
3122
- position: z5.enum(LOGO_POSITIONS).optional(),
3123
- /** The logo's shape the slot was planned with (width over height), as the size's brief reserved it; else the file's own. */
3124
- aspect: z5.number().positive().optional(),
3125
- /** The ad's copy (prompt.json's lines and their roles): the check finds the headline among them. */
3126
- copy: Copy2.optional(),
3127
- /** The colours a logo inked in the text colour (`currentColor`) may be drawn in: the brand's, and white. */
3128
- inks: z5.array(z5.string().regex(/^#[0-9a-fA-F]{6}$/)).min(1).optional(),
3129
- /** The brand's colours a plate behind the logo may take, when no plain ground holds it. */
3130
- plates: z5.array(z5.string().regex(/^#[0-9a-fA-F]{6}$/)).optional()
3131
- }).strict();
3132
- async function logoFileOf(logo) {
3133
- return await textColourSource(logo.metadata) ?? (await imageOf(logo, "static_logo")).bytes;
3134
- }
3135
- var DEFAULT_INKS = ["#000000", "#FFFFFF"];
3136
- async function candidatesOf(files, inks) {
3137
- const each = await Promise.all(
3138
- files.map(async (bytes, file) => {
3139
- if (!usesTextColour(bytes)) return [{ file, art: await logoArtwork(bytes) }];
3140
- return await Promise.all(
3141
- (inks ?? DEFAULT_INKS).map(async (ink) => ({
3142
- file,
3143
- ink,
3144
- art: await logoArtwork(bytes, { currentColor: ink })
3145
- }))
3146
- );
3147
- })
3148
- );
3149
- return each.flat();
3150
- }
3151
- var staticLogoNode = defineNode({
3152
- id: "static_logo",
3153
- version: "1.4.0",
3154
- category: "image",
3155
- location: "local",
3156
- summary: "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).",
3157
- when_to_use: "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).",
3158
- inputs: z5.object({ image: ImageRef, logos: z5.array(ImageRef).min(1), slot: Rect2.optional() }).strict(),
3159
- params: LogoParams,
3160
- outputs: z5.object({ image: ImageRef, facts: LogoFacts, usage: z5.array(Usage2).optional() }).strict(),
3161
- outputKinds: { image: "image" },
3162
- cost: () => ({ credits: 0, seconds_estimate: 5 }),
3163
- async execute({ inputs, params, ctx }) {
3164
- const { bytes, size } = await imageOf(inputs.image, "static_logo");
3165
- const files = await Promise.all(inputs.logos.map(logoFileOf));
3166
- const candidates = await candidatesOf(files, params.inks);
3167
- const arts = candidates.map((c) => c.art);
3168
- const position = params.position ?? "top_left";
3169
- const safe = blockingArea(params.format, params.placements);
3170
- const aspect = params.aspect ?? arts[0].width / arts[0].height;
3171
- const copy = params.copy ?? [];
3172
- const { read, usage } = await wordsBefore(bytes, copy.length > 0 || !inputs.slot);
3173
- const inks = arts.map((art) => inkLuma(art.data));
3174
- const where = await whereLogoGoes(
3175
- { bytes, size, safe, aspect, position, words: wordsOf(read, copy, size), usage },
3176
- { reserved: inputs.slot, arts, inks, plates: params.plates }
3177
- );
3178
- const { image, table, home, plate } = where;
3179
- const fitted = await Promise.all(arts.map((art) => fitArtwork(art, home)));
3180
- const grounds = fitted.map((art) => groundUnder(image, art, placeInSlot(home, art, where.at)));
3181
- const shares = fitted.map((art, i) => legibleShare(table, art, placeInSlot(home, art, where.at), inks[i] ?? null));
3182
- const chosen = plate ? plate.variant : pickLogoVariant(shares);
3183
- const placed2 = fitted[chosen];
3184
- const { file: variant, ink } = candidates[chosen];
3185
- const at = placeInSlot(home, placed2, where.at);
3186
- const box = { x: at.x, y: at.y, width: placed2.width, height: placed2.height };
3187
- const out = where.noRoom ? await sharp5(bytes).png().toBuffer() : await sharp5(bytes).composite(await layersOf(placed2, at, plate)).png().toBuffer();
3188
- const legible = plate ? 1 : shares[chosen] ?? 1;
3189
- const ground = plate ? plate.luma : grounds[chosen] ?? 255;
3190
- const { headline, problems } = checkSize(
3191
- read,
3192
- { size, safe, box, legible, plated: plate !== null, noRoom: where.noRoom },
3193
- copy
3194
- );
3195
- const facts = {
3196
- format: params.format,
3197
- box,
3198
- slot: home,
3199
- variant,
3200
- ...ink ? { ink } : {},
3201
- ...plate ? { plate: { colour: plate.colour } } : {},
3202
- ground: Math.round(ground),
3203
- contrast: Math.round(contrastRatio(ground, inks[chosen] ?? 0) * 10) / 10,
3204
- legible: Math.round(legible * 100) / 100,
3205
- headline,
3206
- read: read !== null && copy.length > 0,
3207
- problems
3208
- };
3209
- ctx.log(logLine(facts, files.length));
3210
- const ingested = await ctx.assets.ingestBytes({ bytes: out, kind: "image", mime: "image/png" });
3211
- return { image: ingested, facts, ...usage.length > 0 ? { usage } : {} };
3212
- }
3213
- });
3214
- function logLine(facts, files) {
3215
- const { box, ink, plate, problems } = facts;
3216
- const found = problems.length > 0 ? `; ${problems.map((p) => `${p.element} ${p.defect}`).join(", ")}` : "";
3217
- 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}`;
3218
- }
3219
- async function whereLogoGoes(at, logo) {
3220
- const { bytes, size, safe, aspect, position } = at;
3221
- const picture = await sharp5(bytes).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
3222
- const image = { data: picture.data, width: picture.info.width, height: picture.info.height };
3223
- const table = greyTable(image);
3224
- const planned = await Promise.all(logo.arts.map((art) => fitArtwork(art, logoBoxOn(size, aspect))));
3225
- const legible = (rect) => planned.some(
3226
- (art, i) => legibleShare(table, art, placeInSlot(rect, art, position), logo.inks[i] ?? null, 2) >= MIN_LEGIBLE_SHARE
3227
- );
3228
- const subjects = await readSubjects(bytes, size, at.usage);
3229
- const scene = {
3230
- words: inflatedWords(at.words),
3231
- subjects: boxesOfKinds(subjects, LOGO_AVOIDS2),
3232
- cta: buttonOf(at.words),
3233
- crossesEdge: (r) => straightEdgeIn(table, r),
3234
- calm: (r) => spreadUnder(table, r) <= PLAIN_GROUND_SPREAD2,
3235
- legible
3236
- };
3237
- const reserved = logo.reserved ? slotAround(logo.reserved, position) : null;
3238
- if (reserved && logoSpotClean(reserved, scene) && scene.calm?.(reserved.clear) && legible(reserved.rect)) {
3239
- return { image, table, home: reserved.rect, at: position, plate: null, noRoom: false };
3240
- }
3241
- const spot = chooseLogoSpot(size, safe, { aspect, position, ...scene });
3242
- const plate = spot?.plate ? plateOf(spot.slot.clear, spot.slot.rect, logo) : null;
3243
- if (spot && (!spot.plate || plate)) {
3244
- return { image, table, home: spot.slot.rect, at: spot.slot.position, plate, noRoom: false };
3245
- }
3246
- const corner = reserved ?? designerSpots(size, safe, { aspect, position })[0];
3247
- return { image, table, home: corner.rect, at: corner.position, plate: null, noRoom: true };
3248
- }
3249
- function plateOf(clear, rect, from) {
3250
- const chosen = plateColour(plateOptions(from.plates), from.inks);
3251
- if (!chosen) return null;
3252
- const luma = hexLuma(chosen.colour) ?? 0;
3253
- return {
3254
- rect: clear,
3255
- radius: Math.round(rect.height * PLATE_RADIUS),
3256
- colour: chosen.colour,
3257
- luma,
3258
- variant: chosen.variant
3259
- };
3260
- }
3261
- var PLATE_RADIUS = 0.25;
3262
- function buttonOf(words) {
3263
- const boxes = words.filter((w) => w.cta).map((w) => w.box);
3264
- if (boxes.length === 0) return null;
3265
- const x = Math.min(...boxes.map((b) => b.x));
3266
- const y = Math.min(...boxes.map((b) => b.y));
3267
- const right = Math.max(...boxes.map((b) => b.x + b.width));
3268
- const bottom = Math.max(...boxes.map((b) => b.y + b.height));
3269
- return { x, y, width: right - x, height: bottom - y };
3270
- }
3271
- async function layersOf(placed2, at, plate) {
3272
- const art = await sharp5(placed2.data, { raw: { width: placed2.width, height: placed2.height, channels: 4 } }).png().toBuffer();
3273
- const layers = [{ input: art, left: at.x, top: at.y }];
3274
- if (!plate) return layers;
3275
- const { rect, radius, colour } = plate;
3276
- 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>`;
3277
- return [{ input: Buffer.from(svg), left: rect.x, top: rect.y }, ...layers];
3278
- }
3279
- async function wordsBefore(bytes, wanted) {
3280
- const usage = [];
3281
- if (!wanted) return { read: null, usage };
3282
- const reading = await readTextBoxes(bytes, { onSpend: (u) => usage.push(u) });
3283
- return { read: reading.status === "read" ? reading.boxes : null, usage };
3284
- }
3285
- function wordsOf(read, copy, size) {
3286
- const boxes = read ?? [];
3287
- const buttons = new Set(copy.filter((l) => /cta|button/i.test(l.role ?? "")).flatMap((l) => boxesOfLine(l, boxes)));
3288
- return boxes.map((b) => ({ box: pxOf(b, size), cta: buttons.has(b) }));
3289
- }
3290
- var LOGO_AVOIDS2 = /* @__PURE__ */ new Set(["person", "face", "product", "animal"]);
3291
- var PLAIN_GROUND_SPREAD2 = 18;
3292
- async function readSubjects(bytes, size, usage) {
3293
- const r = await readSubjectBoxes(bytes, { onSpend: (u) => usage.push(u) });
3294
- return r.status === "read" ? r.boxes.map((b) => ({ kind: b.kind, box: pxOf(b, size) })) : [];
3295
- }
3296
- var boxesOfKinds = (subjects, kinds) => subjects.filter((s) => kinds.has(s.kind)).map((s) => s.box);
3297
- function plateOptions(hexes) {
3298
- return (hexes ?? []).flatMap((colour) => {
3299
- const luma = hexLuma(colour);
3300
- return luma === null ? [] : [{ colour, luma }];
3301
- });
3302
- }
3303
- function pxOf(b, size) {
3304
- return {
3305
- x: Math.round(b.x0 * size.width),
3306
- y: Math.round(b.y0 * size.height),
3307
- width: Math.max(1, Math.round((b.x1 - b.x0) * size.width)),
3308
- height: Math.max(1, Math.round((b.y1 - b.y0) * size.height))
3309
- };
3310
- }
3311
- function checkSize(read, at, copy) {
3312
- const lines = read && copy.length > 0 ? copyBoxes(read, copy) : null;
3313
- const headline = lines?.headline ? pxOf(lines.headline, at.size) : null;
3314
- const inHeadline = (b) => headline !== null && b.x >= headline.x && b.y >= headline.y && b.x + b.width <= headline.x + headline.width && b.y + b.height <= headline.y + headline.height;
3315
- const words = (read ?? []).filter((b) => b.kind === "text").map((b) => pxOf(b, at.size)).filter((b) => !inHeadline(b));
3316
- const problems = placementProblems({
3317
- frame: at.size,
3318
- safe: at.safe,
3319
- // With no room nothing was stamped: only the headline is checked.
3320
- logo: at.noRoom ? null : at.box,
3321
- headline,
3322
- copy: (lines?.others ?? []).map((b) => pxOf(b, at.size)),
3323
- words,
3324
- legible: at.legible,
3325
- plated: at.plated
3326
- });
3327
- const noRoom = at.noRoom ? [{ element: "logo", defect: "no_room", edges: [] }] : [];
3328
- return { headline, problems: [...problems, ...noRoom] };
3329
- }
3330
- function groundUnder(image, art, at) {
3331
- let sum = 0;
3332
- let n = 0;
3333
- for (let j = 0; j < art.height; j++) {
3334
- for (let i = 0; i < art.width; i++) {
3335
- if ((art.data[(j * art.width + i) * 4 + 3] ?? 0) < 128) continue;
3336
- const u = at.x + i;
3337
- const v = at.y + j;
3338
- if (u < 0 || v < 0 || u >= image.width || v >= image.height) continue;
3339
- const o = (v * image.width + u) * 4;
3340
- sum += 0.2126 * (image.data[o] ?? 0) + 0.7152 * (image.data[o + 1] ?? 0) + 0.0722 * (image.data[o + 2] ?? 0);
3341
- n++;
3342
- }
3343
- }
3344
- return n === 0 ? 255 : sum / n;
3345
- }
3346
- function copyBoxes(read, copy) {
3347
- const logoWords = copy.filter((l) => /logo/i.test(l.role ?? "")).map((l) => l.text);
3348
- const boxes = withWordmark(read, logoWords);
3349
- const lines = copy.filter((l) => !/logo/i.test(l.role ?? ""));
3350
- const headline = headlineBox(lines, boxes);
3351
- const all = lines.flatMap((l) => boxesOfLine(l, boxes));
3352
- const inHeadline = (b) => headline !== null && b.x0 >= headline.x0 && b.y0 >= headline.y0 && b.x1 <= headline.x1 && b.y1 <= headline.y1;
3353
- return { headline, others: all.filter((b) => !inHeadline(b)) };
3354
- }
3355
-
3356
- // src/engine/nodes/local/lib/size-consistency.ts
3357
- import sharp6 from "sharp";
3358
- import { z as z6 } from "zod";
3359
- var SHOWN_AREA = 0.01;
3360
- var SEEN_AREA = SHOWN_AREA / 3;
3361
- var SAME_BOX = 0.3;
3362
- var COUNTED = [
3363
- { kind: "person", name: "people" },
3364
- { kind: "face", name: "faces" },
3365
- { kind: "animal", name: "animals" }
3366
- ];
3367
- var area = (b) => Math.max(0, b.x1 - b.x0) * Math.max(0, b.y1 - b.y0);
3368
- function overlap2(a, b) {
3369
- const ix = Math.max(0, Math.min(a.x1, b.x1) - Math.max(a.x0, b.x0));
3370
- const iy = Math.max(0, Math.min(a.y1, b.y1) - Math.max(a.y0, b.y0));
3371
- const union = area(a) + area(b) - ix * iy;
3372
- return union > 0 ? ix * iy / union : 0;
3373
- }
3374
- function surely(image, kind) {
3375
- const [first = [], ...rest] = image.reads.map((r) => r.filter((b) => b.kind === kind));
3376
- return first.filter((b) => area(b) >= SHOWN_AREA && rest.every((r) => r.some((o) => overlap2(b, o) >= SAME_BOX)));
3377
- }
3378
- function atMost(image, kind) {
3379
- return Math.max(0, ...image.reads.map((r) => r.filter((b) => b.kind === kind && area(b) >= SEEN_AREA).length));
3380
- }
3381
- function boxDifferences(master, size) {
3382
- return COUNTED.flatMap(({ kind, name }) => {
3383
- const shown = surely(size, kind).length;
3384
- const shownBefore = atMost(master, kind);
3385
- if (shown > shownBefore) {
3386
- return [{ kind: "added", what: `shows ${shown} ${name} where the main size shows ${shownBefore}` }];
3387
- }
3388
- const before = surely(master, kind).length;
3389
- const now = atMost(size, kind);
3390
- if (before > now) return [{ kind: "missing", what: `shows ${now} ${name} where the main size shows ${before}` }];
3391
- return [];
3392
- });
3393
- }
3394
- var PAINTED = 0.6;
3395
- function paintedSubjects(plate, paintedShare) {
3396
- const words = (label) => label.toLowerCase().match(new RegExp("\\p{L}{3,}", "gu")) ?? [];
3397
- const keptProducts = new Set(
3398
- surely(plate, "product").filter((b) => paintedShare(b) < PAINTED).flatMap((b) => words(b.label))
3399
- );
3400
- return ["person", "face", "animal", "product"].flatMap(
3401
- (kind) => surely(plate, kind).filter((b) => paintedShare(b) >= PAINTED).filter((b) => kind !== "product" || words(b.label).some((w) => keptProducts.has(w))).map((b) => b.label)
3402
- );
3403
- }
3404
- var SIZE_MATCH_PROMPT = [
3405
- "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:",
3406
- "- 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).",
3407
- "- 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.",
3408
- "- duplicated: Image 2 shows the same person, animal or product twice where Image 1 shows it once.",
3409
- "- stretched: a person, face or product in Image 2 is visibly stretched or squashed compared with Image 1 (wider or taller than it is).",
3410
- "- 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.",
3411
- "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.",
3412
- '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>"}'
3413
- ].join("\n");
3414
- var SizeMatchAnswer = z6.object({
3415
- people: z6.enum(["same", "different"]),
3416
- product: z6.enum(["same", "different", "missing", "none"]),
3417
- duplicated: z6.string().nullable().optional(),
3418
- stretched: z6.string().nullable().optional(),
3419
- framed: z6.boolean()
3420
- });
3421
- var named = (text) => {
3422
- const t = text?.trim();
3423
- return t && t.toLowerCase() !== "null" ? t : null;
3424
- };
3425
- function sizeMatchFromAnswer(answer) {
3426
- const parsed = SizeMatchAnswer.safeParse(answer);
3427
- if (!parsed.success) return null;
3428
- const a = parsed.data;
3429
- const twice = named(a.duplicated);
3430
- const stretched = named(a.stretched);
3431
- return [
3432
- ...a.people === "different" ? [{ kind: "other_people", what: "shows other people than the main size" }] : [],
3433
- ...a.product === "different" ? [{ kind: "other_product", what: "shows another product than the main size" }] : a.product === "missing" ? [{ kind: "no_product", what: "no longer shows the product the main size shows" }] : [],
3434
- ...twice ? [{ kind: "duplicated", what: `shows ${twice} twice` }] : [],
3435
- ...stretched ? [{ kind: "stretched", what: `shows ${stretched} stretched or squashed` }] : [],
3436
- ...a.framed ? [{ kind: "framed", what: "shows the main size's picture boxed inside a bigger frame" }] : []
3437
- ];
3438
- }
3439
- var READS = 2;
3440
- var MATCH_EDGE = 1024;
3441
- async function readTwice(bytes, onSpend) {
3442
- const meta = await sharp6(bytes).metadata();
3443
- const reads = await Promise.all(Array.from({ length: READS }, () => readSubjectBoxes(bytes, { onSpend })));
3444
- const boxes = reads.flatMap((r) => r.status === "read" ? [r.boxes] : []);
3445
- return boxes.length === READS ? { size: { width: meta.width ?? 0, height: meta.height ?? 0 }, reads: boxes } : null;
3446
- }
3447
- var matchJpeg = async (bytes) => (await sharp6(bytes).resize(MATCH_EDGE, MATCH_EDGE, { fit: "inside", withoutEnlargement: true }).jpeg({ quality: 88 }).toBuffer()).toString("base64");
3448
- var unique2 = (diffs) => diffs.filter((d, i) => diffs.findIndex((o) => o.what === d.what) === i);
3449
- async function compareSizes(master, sizes, opts = {}) {
3450
- const masterBytes = await bytesOf(master.path);
3451
- const [masterReads, masterJpeg] = await Promise.all([readTwice(masterBytes, opts.onSpend), matchJpeg(masterBytes)]);
3452
- return await Promise.all(
3453
- sizes.map(async (size) => {
3454
- const bytes = await bytesOf(size.path);
3455
- const [reads, answer] = await Promise.all([
3456
- readTwice(bytes, opts.onSpend),
3457
- matchJpeg(bytes).then(
3458
- (jpeg) => askAboutImages(SIZE_MATCH_MODEL, [masterJpeg, jpeg], SIZE_MATCH_PROMPT, opts.onSpend, 6e4, {
3459
- effort: "low"
3460
- })
3461
- )
3462
- ]);
3463
- const boxed = masterReads && reads ? boxDifferences(masterReads, reads) : null;
3464
- const seen = sizeMatchFromAnswer(answer);
3465
- return {
3466
- format: size.format,
3467
- compared: boxed !== null || seen !== null,
3468
- differences: unique2([...boxed ?? [], ...seen ?? []])
3469
- };
3470
- })
3471
- );
3472
- }
3473
- function sizeDifferenceFinding(format, differences) {
3474
- const missing = differences.some((d) => d.kind === "missing" || d.kind === "no_product");
3475
- return {
3476
- severity: "blocking",
3477
- what: `${format}: ${differences.map((d) => d.what).join("; ")}. It must show the main size's people and product, once each, at their own proportions.`,
3478
- kind: { item: "sizes", element: "picture", defect: missing ? "missing" : "other", edges: [] }
3479
- };
3480
- }
3481
-
3482
- export {
3483
- SubjectBoxSchema,
3484
- paintedSubjects,
3485
- readTwice,
3486
- compareSizes,
3487
- sizeDifferenceFinding,
3488
- registryParamShape,
3489
- imageGenerateNode,
3490
- timedStep,
3491
- isRead,
3492
- subjectsStep,
3493
- imageOf,
3494
- rawOf,
3495
- pngOf,
3496
- subjectCrop,
3497
- boxesToPlace,
3498
- planSafeFit,
3499
- plainEdge,
3500
- minFitScale,
3501
- fitPicture,
3502
- registerToSource,
3503
- warpToCut,
3504
- MISALIGNED,
3505
- staticFormatNode,
3506
- splitWordBoxes,
3507
- LogoFacts,
3508
- staticLogoNode
3509
- };
3510
- //# sourceMappingURL=chunk-HBRXFQQV.js.map