@koda-sl/baker-cli 0.513.0 → 0.514.0-dev.555f7007e
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.
- package/README.md +19 -2
- package/dist/account-QX4G4BJ7.js +82 -0
- package/dist/account-QX4G4BJ7.js.map +1 -0
- package/dist/account-UFYZS3K6.js +82 -0
- package/dist/account-UFYZS3K6.js.map +1 -0
- package/dist/account-assets-J5Z4URLQ.js +290 -0
- package/dist/account-level-4SBYYHRS.js +611 -0
- package/dist/account-level-4SBYYHRS.js.map +1 -0
- package/dist/account-reads-FOEVPWDP.js +219 -0
- package/dist/account-users-UTIF7MIT.js +64 -0
- package/dist/account-users-UTIF7MIT.js.map +1 -0
- package/dist/account-writes-QAQXRIEY.js +68 -0
- package/dist/account-writes-QAQXRIEY.js.map +1 -0
- package/dist/accounts-JK3OAS5U.js +701 -0
- package/dist/accounts-JK3OAS5U.js.map +1 -0
- package/dist/accounts-OE33CKWD.js +80 -0
- package/dist/accounts-OE33CKWD.js.map +1 -0
- package/dist/actions-QZDSLFFK.js +55 -0
- package/dist/activecampaign-U6TKRR45.js +938 -0
- package/dist/activecampaign-U6TKRR45.js.map +1 -0
- package/dist/ad-group-writes-XY5JYTKT.js +172 -0
- package/dist/ad-group-writes-XY5JYTKT.js.map +1 -0
- package/dist/ad-groups-YEO5ZS5U.js +70 -0
- package/dist/ad-groups-YEO5ZS5U.js.map +1 -0
- package/dist/ad-writes-XRCPK4SP.js +176 -0
- package/dist/ad-writes-XRCPK4SP.js.map +1 -0
- package/dist/add-2EF7S4NK.js +305 -0
- package/dist/add-2EF7S4NK.js.map +1 -0
- package/dist/add-YCJ6RXPG.js +107 -0
- package/dist/add-YCJ6RXPG.js.map +1 -0
- package/dist/ads-AYJAYLFR.js +48 -0
- package/dist/ads-H7H7H2CM.js +79 -0
- package/dist/ads-H7H7H2CM.js.map +1 -0
- package/dist/ads-MAOI7S6V.js +115 -0
- package/dist/adsets-QRKICEFD.js +182 -0
- package/dist/advertisers-JLSU3G35.js +123 -0
- package/dist/advertisers-JLSU3G35.js.map +1 -0
- package/dist/analytics-ADIWEM6G.js +2437 -0
- package/dist/analytics-ADIWEM6G.js.map +1 -0
- package/dist/analytics-XB6FRNVJ.js +447 -0
- package/dist/analytics-XB6FRNVJ.js.map +1 -0
- package/dist/animate-HRWFVE2N.js +480 -0
- package/dist/asset-writes-JLVUAVUZ.js +50 -0
- package/dist/assign-IWZ2OPFL.js +80 -0
- package/dist/assign-IWZ2OPFL.js.map +1 -0
- package/dist/audience-size-P5L6MZ4C.js +76 -0
- package/dist/audience-size-P5L6MZ4C.js.map +1 -0
- package/dist/audience-writes-CDKQB3SM.js +327 -0
- package/dist/audience-writes-CDKQB3SM.js.map +1 -0
- package/dist/audiences-CDDI5HR5.js +86 -0
- package/dist/audiences-XKERWKKE.js +280 -0
- package/dist/audiences-XKERWKKE.js.map +1 -0
- package/dist/audit-SEADLC6F.js +154 -0
- package/dist/audit-SEADLC6F.js.map +1 -0
- package/dist/autocomplete-AJQBJS5R.js +114 -0
- package/dist/autocomplete-AJQBJS5R.js.map +1 -0
- package/dist/avatars-4HCGWBOL.js +38 -0
- package/dist/bid-pricing-NWSUO3VM.js +103 -0
- package/dist/bid-pricing-NWSUO3VM.js.map +1 -0
- package/dist/brand-C6OB6Q4U.js +22 -0
- package/dist/brief-LCWWQ4OC.js +543 -0
- package/dist/brief-LCWWQ4OC.js.map +1 -0
- package/dist/campaign-groups-PH64UXZJ.js +99 -0
- package/dist/campaign-groups-PH64UXZJ.js.map +1 -0
- package/dist/campaign-writes-BN3EGDK5.js +168 -0
- package/dist/campaign-writes-BN3EGDK5.js.map +1 -0
- package/dist/campaign-writes-CLV5ZSUK.js +176 -0
- package/dist/campaign-writes-CLV5ZSUK.js.map +1 -0
- package/dist/campaigns-5XRY27JZ.js +78 -0
- package/dist/campaigns-5XRY27JZ.js.map +1 -0
- package/dist/campaigns-HES5MDUG.js +130 -0
- package/dist/campaigns-JF4TYYUP.js +113 -0
- package/dist/campaigns-JF4TYYUP.js.map +1 -0
- package/dist/campaigns-ZYU4BXDP.js +111 -0
- package/dist/canvas-AI34UBGU.js +46 -0
- package/dist/capabilities-TRHAPTUU.js +147 -0
- package/dist/capabilities-TRHAPTUU.js.map +1 -0
- package/dist/catalog-ZY3MFT55.js +65 -0
- package/dist/catalogs-6XLBWAUS.js +130 -0
- package/dist/catalogs-6XLBWAUS.js.map +1 -0
- package/dist/catalogs-TGLSJEK5.js +781 -0
- package/dist/catalogs-TGLSJEK5.js.map +1 -0
- package/dist/changes-OOUVQDBY.js +135 -0
- package/dist/chatgpt-NAXIFWXV.js +47 -0
- package/dist/chats-I5RHBRS5.js +279 -0
- package/dist/chats-I5RHBRS5.js.map +1 -0
- package/dist/check-3E64VBUE.js +107 -0
- package/dist/check-3E64VBUE.js.map +1 -0
- package/dist/chunk-3CHYJYSS.js +319 -0
- package/dist/chunk-3G3GC5N4.js +429 -0
- package/dist/chunk-3M45PYU7.js +274 -0
- package/dist/chunk-3QHXF3QI.js +23 -0
- package/dist/chunk-3XPHUMLJ.js +3868 -0
- package/dist/chunk-45EERHDB.js +783 -0
- package/dist/chunk-4FGTANFK.js +387 -0
- package/dist/chunk-4IHWT7PH.js +167 -0
- package/dist/chunk-4LF4AYPT.js +846 -0
- package/dist/chunk-4UQRXKYJ.js +219 -0
- package/dist/chunk-5JJD33Y2.js +455 -0
- package/dist/chunk-5K4QYYOJ.js +831 -0
- package/dist/chunk-5LJ6E4YU.js +163 -0
- package/dist/chunk-5T73MMBL.js +275 -0
- package/dist/chunk-64MAHLTK.js +363 -0
- package/dist/chunk-6OIKNJ7G.js +26 -0
- package/dist/chunk-6ZFSDYWV.js +131 -0
- package/dist/chunk-7BUIOP36.js +287 -0
- package/dist/chunk-7I6ZVBLM.js +358 -0
- package/dist/chunk-7I6ZVBLM.js.map +1 -0
- package/dist/chunk-AN4OEQXE.js +122 -0
- package/dist/chunk-AULSX5ZA.js +5368 -0
- package/dist/chunk-AVYUFJQQ.js +46 -0
- package/dist/chunk-B4YF7VQF.js +97 -0
- package/dist/chunk-BDOYNGUL.js +98 -0
- package/dist/chunk-BJOK7QD4.js +207 -0
- package/dist/chunk-CMCGFSUS.js +197 -0
- package/dist/chunk-DMJUIUAL.js +676 -0
- package/dist/chunk-DUCUOZLS.js +225 -0
- package/dist/chunk-EW7JSTRZ.js +24026 -0
- package/dist/chunk-EW7JSTRZ.js.map +1 -0
- package/dist/chunk-F3CZFUXZ.js +3187 -0
- package/dist/chunk-F3CZFUXZ.js.map +1 -0
- package/dist/chunk-FJZYOVSW.js +843 -0
- package/dist/chunk-FKP4ECJY.js +19 -0
- package/dist/chunk-G4FG5EQO.js +110 -0
- package/dist/chunk-G4FG5EQO.js.map +1 -0
- package/dist/chunk-GAYRBIEF.js +712 -0
- package/dist/chunk-GAYRBIEF.js.map +1 -0
- package/dist/chunk-GNMEOU46.js +8954 -0
- package/dist/chunk-GYKYXWUQ.js +156 -0
- package/dist/chunk-GYPLRU4Y.js +297 -0
- package/dist/chunk-I43ZEWJQ.js +285 -0
- package/dist/chunk-IZABTTW5.js +228 -0
- package/dist/chunk-JOE42ZW6.js +2984 -0
- package/dist/chunk-JOE42ZW6.js.map +1 -0
- package/dist/chunk-K7IE6UYV.js +1646 -0
- package/dist/chunk-KH5YHHJV.js +604 -0
- package/dist/chunk-KMY7AD3N.js +51 -0
- package/dist/chunk-KPCHWDJM.js +8914 -0
- package/dist/chunk-KTZCLJ2D.js +148 -0
- package/dist/chunk-MKUA54QE.js +638 -0
- package/dist/chunk-MTV2RSGY.js +63 -0
- package/dist/chunk-MUS2UTWU.js +4254 -0
- package/dist/chunk-MUS2UTWU.js.map +1 -0
- package/dist/chunk-N2QX57K3.js +392 -0
- package/dist/chunk-NB2FU6EZ.js +179 -0
- package/dist/chunk-NEYWS2DQ.js +479 -0
- package/dist/chunk-NKQWDEB7.js +115 -0
- package/dist/chunk-NKQWDEB7.js.map +1 -0
- package/dist/chunk-NWF2LRKO.js +188 -0
- package/dist/chunk-NZ34KM46.js +7211 -0
- package/dist/chunk-NZ34KM46.js.map +1 -0
- package/dist/chunk-OTC6UMJ2.js +191 -0
- package/dist/chunk-OUY2IAWL.js +224 -0
- package/dist/chunk-PJXNCRMR.js +344 -0
- package/dist/chunk-PYQ3GF7R.js +91 -0
- package/dist/chunk-Q3EIVZAR.js +170 -0
- package/dist/chunk-Q3GSVLE5.js +4274 -0
- package/dist/chunk-Q3GSVLE5.js.map +1 -0
- package/dist/chunk-QDQZ62FL.js +207 -0
- package/dist/chunk-QHZE62GP.js +1919 -0
- package/dist/chunk-RGR6TSTJ.js +103 -0
- package/dist/chunk-SAAXU7QR.js +203 -0
- package/dist/chunk-SHTKLRI6.js +66 -0
- package/dist/chunk-SIKCVWM3.js +76 -0
- package/dist/chunk-SOPVIIUW.js +68 -0
- package/dist/chunk-SOPVIIUW.js.map +1 -0
- package/dist/chunk-SSXG53CZ.js +89 -0
- package/dist/chunk-TBWAM577.js +547 -0
- package/dist/chunk-TGPGQTZA.js +169 -0
- package/dist/chunk-UMIX2BMM.js +1518 -0
- package/dist/chunk-URMAEVZO.js +150 -0
- package/dist/chunk-VBO3ZVUU.js +61 -0
- package/dist/chunk-VFLYMHTO.js +592 -0
- package/dist/chunk-VGYIVXIZ.js +249 -0
- package/dist/chunk-VIB7R533.js +57 -0
- package/dist/chunk-WLESMH4J.js +45 -0
- package/dist/chunk-WVWLPXBO.js +910 -0
- package/dist/chunk-XEH5XAP6.js +494 -0
- package/dist/chunk-XEOKVL4E.js +142 -0
- package/dist/chunk-XOGQJYXH.js +64 -0
- package/dist/chunk-XOQNM7I4.js +396 -0
- package/dist/chunk-XOQNM7I4.js.map +1 -0
- package/dist/chunk-XUXRA7IB.js +942 -0
- package/dist/claim-FIK2YTLM.js +200 -0
- package/dist/claim-FIK2YTLM.js.map +1 -0
- package/dist/cli.js +34 -33
- package/dist/cli.js.map +1 -1
- package/dist/companies-KMMV6EJW.js +198 -0
- package/dist/companies-KMMV6EJW.js.map +1 -0
- package/dist/company-B54URPJG.js +308 -0
- package/dist/company-B54URPJG.js.map +1 -0
- package/dist/complete-PPCWEXS3.js +84 -0
- package/dist/complete-PPCWEXS3.js.map +1 -0
- package/dist/connect-IAXSZPGA.js +45 -0
- package/dist/conversation-KHTZBGX2.js +96 -0
- package/dist/conversation-KHTZBGX2.js.map +1 -0
- package/dist/conversion-report-U66HW6JM.js +127 -0
- package/dist/conversion-report-U66HW6JM.js.map +1 -0
- package/dist/conversion-upload-command-IHFKVX2M.js +439 -0
- package/dist/conversion-writes-RSGDOAET.js +122 -0
- package/dist/conversion-writes-RSGDOAET.js.map +1 -0
- package/dist/conversions-BVOL43W4.js +78 -0
- package/dist/conversions-BVOL43W4.js.map +1 -0
- package/dist/conversions-SUMZAV2T.js +140 -0
- package/dist/conversions-SUMZAV2T.js.map +1 -0
- package/dist/copy-writes-CIHIFLY6.js +170 -0
- package/dist/copy-writes-CIHIFLY6.js.map +1 -0
- package/dist/create-732HQL3C.js +210 -0
- package/dist/create-732HQL3C.js.map +1 -0
- package/dist/create-TFR6R2KF.js +239 -0
- package/dist/create-TFR6R2KF.js.map +1 -0
- package/dist/create-UC57ULRL.js +62 -0
- package/dist/create-UC57ULRL.js.map +1 -0
- package/dist/create-UL2OYXOA.js +135 -0
- package/dist/create-UL2OYXOA.js.map +1 -0
- package/dist/creatives-BB6S2OF6.js +89 -0
- package/dist/creatives-BZEVJ6ER.js +58 -0
- package/dist/creatives-FU3YELGU.js +223 -0
- package/dist/creatives-FU3YELGU.js.map +1 -0
- package/dist/credentials-AYV5YQE4.js +290 -0
- package/dist/credentials-AYV5YQE4.js.map +1 -0
- package/dist/critique-FKIJB72I.js +1451 -0
- package/dist/critique-FKIJB72I.js.map +1 -0
- package/dist/critique-IQYNDXCN.js +232 -0
- package/dist/critique-IQYNDXCN.js.map +1 -0
- package/dist/crm-ILQMNJPX.js +323 -0
- package/dist/crm-ILQMNJPX.js.map +1 -0
- package/dist/crm-MQQRBITZ.js +227 -0
- package/dist/crm-MQQRBITZ.js.map +1 -0
- package/dist/currency-CGKO5GKH.js +88 -0
- package/dist/custom-conversions-HAGG72LF.js +128 -0
- package/dist/customers-NKKU6S7G.js +59 -0
- package/dist/delete-2TCCNRMH.js +57 -0
- package/dist/delete-2TCCNRMH.js.map +1 -0
- package/dist/delete-HCZTISBT.js +69 -0
- package/dist/delete-HCZTISBT.js.map +1 -0
- package/dist/delete-UIKB5ZXS.js +67 -0
- package/dist/delete-UIKB5ZXS.js.map +1 -0
- package/dist/demographics-ABZODD45.js +141 -0
- package/dist/demographics-ABZODD45.js.map +1 -0
- package/dist/discard-V3K5PZ4W.js +69 -0
- package/dist/discard-V3K5PZ4W.js.map +1 -0
- package/dist/discover-VM3O7CQM.js +172 -0
- package/dist/domain-A66DHOTQ.js +101 -0
- package/dist/domain-A66DHOTQ.js.map +1 -0
- package/dist/download-LSAZD5JO.js +172 -0
- package/dist/download-LSAZD5JO.js.map +1 -0
- package/dist/draft-5UUJC675.js +335 -0
- package/dist/draft-5UUJC675.js.map +1 -0
- package/dist/draft-BATA5CVI.js +283 -0
- package/dist/draft-BATA5CVI.js.map +1 -0
- package/dist/draft-CRDBU6LF.js +308 -0
- package/dist/draft-P7IDMXWR.js +310 -0
- package/dist/draft-P7IDMXWR.js.map +1 -0
- package/dist/draft-YBNL4ZZA.js +220 -0
- package/dist/draft-YBNL4ZZA.js.map +1 -0
- package/dist/engine/index.js +7 -7
- package/dist/experiments-MLLTHMMS.js +236 -0
- package/dist/experiments-MLLTHMMS.js.map +1 -0
- package/dist/facets-KSHR3MBE.js +117 -0
- package/dist/facets-KSHR3MBE.js.map +1 -0
- package/dist/feedback-4GCPXZSI.js +111 -0
- package/dist/feedback-4GCPXZSI.js.map +1 -0
- package/dist/feedback-record-VEFHUIUJ.js +265 -0
- package/dist/feedback-record-VEFHUIUJ.js.map +1 -0
- package/dist/fetch-42QL56JC.js +179 -0
- package/dist/fetch-42QL56JC.js.map +1 -0
- package/dist/fit-Q5GRVF2O.js +65 -0
- package/dist/flows-M3WBZQET.js +250 -0
- package/dist/flows-M3WBZQET.js.map +1 -0
- package/dist/fonts-GD4YRXQU.js +39 -0
- package/dist/forecast-HT46MFL4.js +121 -0
- package/dist/forecast-HT46MFL4.js.map +1 -0
- package/dist/forecast-ONVS2QAI.js +169 -0
- package/dist/funnel-76BAD64Q.js +397 -0
- package/dist/funnel-76BAD64Q.js.map +1 -0
- package/dist/generate-VBEY3N3L.js +263 -0
- package/dist/get-4KFAO475.js +82 -0
- package/dist/get-4KFAO475.js.map +1 -0
- package/dist/get-QV5NIADE.js +59 -0
- package/dist/get-QV5NIADE.js.map +1 -0
- package/dist/google-7EZP7I6J.js +3267 -0
- package/dist/google-ads-J7WHTJO4.js +198 -0
- package/dist/google-ads-J7WHTJO4.js.map +1 -0
- package/dist/history-EULKWQUS.js +136 -0
- package/dist/history-EULKWQUS.js.map +1 -0
- package/dist/history-FEBJHFHJ.js +69 -0
- package/dist/history-FEBJHFHJ.js.map +1 -0
- package/dist/history-RDVV7KBN.js +102 -0
- package/dist/history-RDVV7KBN.js.map +1 -0
- package/dist/hubspot-A3RQNMYN.js +782 -0
- package/dist/hubspot-A3RQNMYN.js.map +1 -0
- package/dist/ideas-WX7EBPSF.js +45 -0
- package/dist/images-4AXF4LAC.js +92 -0
- package/dist/ingest-AM5YDTRH.js +110 -0
- package/dist/ingest-AM5YDTRH.js.map +1 -0
- package/dist/ingest-C3M4GUO6.js +26 -0
- package/dist/insights-UTCMSWSC.js +132 -0
- package/dist/insights-UTCMSWSC.js.map +1 -0
- package/dist/insights-XZL2EM53.js +439 -0
- package/dist/insights-XZL2EM53.js.map +1 -0
- package/dist/inspect-DWCLRZGR.js +192 -0
- package/dist/inspect-DWCLRZGR.js.map +1 -0
- package/dist/instant-experiences-RM4MLJTL.js +260 -0
- package/dist/instant-experiences-RM4MLJTL.js.map +1 -0
- package/dist/intent-ZMYMFGB4.js +95 -0
- package/dist/keyword-gap-XSJO2R77.js +130 -0
- package/dist/keyword-metrics-M46FCTAS.js +200 -0
- package/dist/keyword-metrics-M46FCTAS.js.map +1 -0
- package/dist/keywords-for-site-XNSLX7EA.js +131 -0
- package/dist/keywords-for-site-XNSLX7EA.js.map +1 -0
- package/dist/landing-MUNYZQNA.js +28 -0
- package/dist/languages-DIQ3OG3E.js +40 -0
- package/dist/lead-routes-XBO2GOBL.js +608 -0
- package/dist/lead-routes-XBO2GOBL.js.map +1 -0
- package/dist/leads-LAATTW5G.js +115 -0
- package/dist/leads-LAATTW5G.js.map +1 -0
- package/dist/leads-ULYHTG22.js +540 -0
- package/dist/leads-ULYHTG22.js.map +1 -0
- package/dist/learn-3GLY4G3H.js +207 -0
- package/dist/learn-3GLY4G3H.js.map +1 -0
- package/dist/line-item-writes-XJTTA3X5.js +211 -0
- package/dist/line-item-writes-XJTTA3X5.js.map +1 -0
- package/dist/line-items-JR25T2C5.js +107 -0
- package/dist/link-7DSLIF3I.js +67 -0
- package/dist/link-7DSLIF3I.js.map +1 -0
- package/dist/linkedin-W5BJ6HEH.js +1316 -0
- package/dist/linkedin-W5BJ6HEH.js.map +1 -0
- package/dist/linkedin-person-2ZYSOHYR.js +139 -0
- package/dist/linkedin-person-2ZYSOHYR.js.map +1 -0
- package/dist/list-3653DIYB.js +67 -0
- package/dist/list-3653DIYB.js.map +1 -0
- package/dist/list-G66HVYCR.js +306 -0
- package/dist/list-G66HVYCR.js.map +1 -0
- package/dist/list-Z4M53MS5.js +154 -0
- package/dist/list-Z4M53MS5.js.map +1 -0
- package/dist/locations-HTVYJSDJ.js +40 -0
- package/dist/locations-M2B5XDU4.js +69 -0
- package/dist/locations-M2B5XDU4.js.map +1 -0
- package/dist/log-2RJU5BOW.js +95 -0
- package/dist/log-2RJU5BOW.js.map +1 -0
- package/dist/lookup-S5VG7AWH.js +23 -0
- package/dist/make-MJ6JMU5T.js +1370 -0
- package/dist/make-MJ6JMU5T.js.map +1 -0
- package/dist/map-27IPOBY6.js +436 -0
- package/dist/map-27IPOBY6.js.map +1 -0
- package/dist/mcp-TFQTME4P.js +717 -0
- package/dist/mcp-TFQTME4P.js.map +1 -0
- package/dist/media-P4T4ZBNS.js +18 -0
- package/dist/media-sources-P246GM7W.js +35 -0
- package/dist/members-KOKBTUC2.js +47 -0
- package/dist/members-KOKBTUC2.js.map +1 -0
- package/dist/meta-IPLWNYC7.js +122 -0
- package/dist/metrics-WYWUX6Y5.js +152 -0
- package/dist/models-HJ7Y55AH.js +155 -0
- package/dist/normalize-GXBUNTYJ.js +144 -0
- package/dist/normalize-GXBUNTYJ.js.map +1 -0
- package/dist/options-MA25RNXF.js +125 -0
- package/dist/options-MA25RNXF.js.map +1 -0
- package/dist/organization-NLEVNGKQ.js +949 -0
- package/dist/organization-NLEVNGKQ.js.map +1 -0
- package/dist/page-photos-OQ5QATQH.js +118 -0
- package/dist/page-photos-OQ5QATQH.js.map +1 -0
- package/dist/performance-34EUP5KL.js +5541 -0
- package/dist/performance-34EUP5KL.js.map +1 -0
- package/dist/performance-J3DLNI2W.js +27 -0
- package/dist/pixels-THEGYRXT.js +62 -0
- package/dist/pixels-THEGYRXT.js.map +1 -0
- package/dist/plan-7UF76Q6U.js +208 -0
- package/dist/plan-7UF76Q6U.js.map +1 -0
- package/dist/preview-LRJOQ7LM.js +218 -0
- package/dist/preview-LRJOQ7LM.js.map +1 -0
- package/dist/promoted-tweet-writes-SBXWKO23.js +183 -0
- package/dist/promoted-tweet-writes-SBXWKO23.js.map +1 -0
- package/dist/promoted-tweets-W42FNWS7.js +119 -0
- package/dist/publish-YG76GOA7.js +344 -0
- package/dist/publish-YG76GOA7.js.map +1 -0
- package/dist/query-IQICLABN.js +62 -0
- package/dist/questionnaire-DWEH5II4.js +94 -0
- package/dist/questionnaire-DWEH5II4.js.map +1 -0
- package/dist/reddit-X4CERXYF.js +29 -0
- package/dist/refresh-A36GA7JN.js +97 -0
- package/dist/refresh-A36GA7JN.js.map +1 -0
- package/dist/release-3NCMZIDI.js +63 -0
- package/dist/release-3NCMZIDI.js.map +1 -0
- package/dist/relevant-pages-UDDQOYLD.js +99 -0
- package/dist/remove-6LE3XNRG.js +53 -0
- package/dist/remove-6LE3XNRG.js.map +1 -0
- package/dist/reopen-XLADJ2UU.js +66 -0
- package/dist/reopen-XLADJ2UU.js.map +1 -0
- package/dist/rerun-QVMFJZA2.js +95 -0
- package/dist/rerun-QVMFJZA2.js.map +1 -0
- package/dist/research-D5UUJF74.js +72 -0
- package/dist/research-QCI5ISUE.js +265 -0
- package/dist/research-QCI5ISUE.js.map +1 -0
- package/dist/reset-DD37KDXQ.js +57 -0
- package/dist/reset-DD37KDXQ.js.map +1 -0
- package/dist/reset-FLZPKY2N.js +57 -0
- package/dist/reset-FLZPKY2N.js.map +1 -0
- package/dist/resolve-KRKIJKT7.js +124 -0
- package/dist/resolve-KRKIJKT7.js.map +1 -0
- package/dist/retry-ALXYEKFV.js +65 -0
- package/dist/retry-ALXYEKFV.js.map +1 -0
- package/dist/retry-MIXKW4EW.js +63 -0
- package/dist/retry-MIXKW4EW.js.map +1 -0
- package/dist/revenue-UBZUTSXN.js +91 -0
- package/dist/revenue-UBZUTSXN.js.map +1 -0
- package/dist/rule-writes-UAVWT4XS.js +525 -0
- package/dist/rule-writes-UAVWT4XS.js.map +1 -0
- package/dist/rules-SO6P44B6.js +99 -0
- package/dist/rules-SO6P44B6.js.map +1 -0
- package/dist/rules-ZVS2MWED.js +217 -0
- package/dist/rules-add-XN3BZKFO.js +465 -0
- package/dist/rules-add-XN3BZKFO.js.map +1 -0
- package/dist/run-K2DOMOAN.js +69 -0
- package/dist/run-K2DOMOAN.js.map +1 -0
- package/dist/run-T7XAH2W5.js +70 -0
- package/dist/scaffold-ad-TWIT7R4U.js +1516 -0
- package/dist/scaffold-ad-TWIT7R4U.js.map +1 -0
- package/dist/scaffold-static-ad-GPJKOGOI.js +1015 -0
- package/dist/scaffold-static-ad-GPJKOGOI.js.map +1 -0
- package/dist/scaffold-video-7BQNOJ4S.js +888 -0
- package/dist/scaffold-video-7BQNOJ4S.js.map +1 -0
- package/dist/schedule-UTRVEWPE.js +64 -0
- package/dist/schedule-UTRVEWPE.js.map +1 -0
- package/dist/scheduled-agents-ZGCUZ6SB.js +55 -0
- package/dist/schema-D6BMZAPB.js +69 -0
- package/dist/schema-DSMF6ELE.js +135 -0
- package/dist/schema-DSMF6ELE.js.map +1 -0
- package/dist/search-2P72GSKY.js +177 -0
- package/dist/search-2P72GSKY.js.map +1 -0
- package/dist/select-N7VWQ2ZQ.js +106 -0
- package/dist/select-N7VWQ2ZQ.js.map +1 -0
- package/dist/sends-LAY5C74B.js +349 -0
- package/dist/sends-LAY5C74B.js.map +1 -0
- package/dist/set-prompt-3N3HMHT6.js +198 -0
- package/dist/set-prompt-3N3HMHT6.js.map +1 -0
- package/dist/setup-links-I5RFZTS4.js +144 -0
- package/dist/setup-links-I5RFZTS4.js.map +1 -0
- package/dist/shopify-LXSR37XI.js +3958 -0
- package/dist/shopify-LXSR37XI.js.map +1 -0
- package/dist/site-AI3BFWRK.js +180 -0
- package/dist/site-AI3BFWRK.js.map +1 -0
- package/dist/sources-AOF2YDYX.js +457 -0
- package/dist/sources-AOF2YDYX.js.map +1 -0
- package/dist/sources-DVMJEXEX.js +30 -0
- package/dist/stale-P4GGOLIB.js +76 -0
- package/dist/stale-P4GGOLIB.js.map +1 -0
- package/dist/status-O25MXHU4.js +65 -0
- package/dist/status-O25MXHU4.js.map +1 -0
- package/dist/studies-EPO2AM4M.js +250 -0
- package/dist/studio-5Z4NMA4K.js +49 -0
- package/dist/study-writes-7FP443QQ.js +470 -0
- package/dist/study-writes-7FP443QQ.js.map +1 -0
- package/dist/sync-2AI7LKKN.js +57 -0
- package/dist/sync-2AI7LKKN.js.map +1 -0
- package/dist/sync-definition-F3CXG6KG.js +69 -0
- package/dist/tags-SEZ2CQJM.js +26 -0
- package/dist/tags-TJDZXOXS.js +227 -0
- package/dist/tags-TJDZXOXS.js.map +1 -0
- package/dist/tags-YSC7ZILI.js +23 -0
- package/dist/tags-YSC7ZILI.js.map +1 -0
- package/dist/tags-Z6EALYOS.js +23 -0
- package/dist/tags-Z6EALYOS.js.map +1 -0
- package/dist/tags-ZXSVW6XO.js +23 -0
- package/dist/tags-ZXSVW6XO.js.map +1 -0
- package/dist/targeting-NKZFEZD7.js +762 -0
- package/dist/targeting-NKZFEZD7.js.map +1 -0
- package/dist/targeting-criteria-AU5CSMAU.js +113 -0
- package/dist/targets-IOIH5JYS.js +106 -0
- package/dist/targets-IOIH5JYS.js.map +1 -0
- package/dist/testimonials-Y6PUV6AL.js +32 -0
- package/dist/themes-PGPIAKAO.js +95 -0
- package/dist/top-companies-FSITN3ZR.js +111 -0
- package/dist/top-companies-FSITN3ZR.js.map +1 -0
- package/dist/transcript-CGPX7Y37.js +165 -0
- package/dist/transcript-CGPX7Y37.js.map +1 -0
- package/dist/translate-QCBMGOKR.js +609 -0
- package/dist/translate-QCBMGOKR.js.map +1 -0
- package/dist/triggers-MONMZSKT.js +144 -0
- package/dist/triggers-MONMZSKT.js.map +1 -0
- package/dist/unlink-I7QFQQKO.js +70 -0
- package/dist/unlink-I7QFQQKO.js.map +1 -0
- package/dist/unstage-JXG5AU5Q.js +88 -0
- package/dist/unstage-JXG5AU5Q.js.map +1 -0
- package/dist/unstage-ZA3WQBEA.js +96 -0
- package/dist/unstage-ZA3WQBEA.js.map +1 -0
- package/dist/update-BVZGM54I.js +66 -0
- package/dist/update-BVZGM54I.js.map +1 -0
- package/dist/update-EI2BHUM2.js +101 -0
- package/dist/update-EI2BHUM2.js.map +1 -0
- package/dist/update-RZSV4NYP.js +155 -0
- package/dist/update-RZSV4NYP.js.map +1 -0
- package/dist/update-WLDNOZ5U.js +192 -0
- package/dist/update-WLDNOZ5U.js.map +1 -0
- package/dist/upload-BP3YEQSF.js +129 -0
- package/dist/upload-BP3YEQSF.js.map +1 -0
- package/dist/url-options-63DED6CR.js +131 -0
- package/dist/url-options-63DED6CR.js.map +1 -0
- package/dist/url-params-TRFI2PMD.js +101 -0
- package/dist/url-params-TRFI2PMD.js.map +1 -0
- package/dist/validate-SNCR25A7.js +122 -0
- package/dist/validate-SNCR25A7.js.map +1 -0
- package/dist/videos-SVZV5YYC.js +41 -0
- package/dist/viewer-check-LUAEGV6H.js +83 -0
- package/dist/web-MJQEK7BB.js +143 -0
- package/dist/web-MJQEK7BB.js.map +1 -0
- package/dist/winning-ads-KNLJHHCO.js +86 -0
- package/dist/write-commands-NVCX7IAU.js +1502 -0
- package/dist/write-commands-NVCX7IAU.js.map +1 -0
- package/dist/write-commands-OGVDWWBV.js +1172 -0
- package/dist/write-commands-OGVDWWBV.js.map +1 -0
- package/dist/x-ZQNHYIDU.js +47 -0
- package/package.json +1 -1
- package/dist/account-UUAEQWO3.js +0 -80
- package/dist/account-UUAEQWO3.js.map +0 -1
- package/dist/account-WLQBAQMD.js +0 -80
- package/dist/account-WLQBAQMD.js.map +0 -1
- package/dist/account-assets-O7IA37RE.js +0 -290
- package/dist/account-level-EU7BWCO7.js +0 -609
- package/dist/account-level-EU7BWCO7.js.map +0 -1
- package/dist/account-reads-SNOWDHHF.js +0 -219
- package/dist/account-users-NV37Z2XJ.js +0 -62
- package/dist/account-users-NV37Z2XJ.js.map +0 -1
- package/dist/account-writes-TU3WJRSI.js +0 -66
- package/dist/account-writes-TU3WJRSI.js.map +0 -1
- package/dist/accounts-MZ6SETJJ.js +0 -78
- package/dist/accounts-MZ6SETJJ.js.map +0 -1
- package/dist/accounts-U7ZBEAY6.js +0 -699
- package/dist/accounts-U7ZBEAY6.js.map +0 -1
- package/dist/actions-4JYHXRFH.js +0 -55
- package/dist/activecampaign-IDBV26HH.js +0 -936
- package/dist/activecampaign-IDBV26HH.js.map +0 -1
- package/dist/ad-group-writes-HLBWN4E4.js +0 -170
- package/dist/ad-group-writes-HLBWN4E4.js.map +0 -1
- package/dist/ad-groups-33NZD6J3.js +0 -68
- package/dist/ad-groups-33NZD6J3.js.map +0 -1
- package/dist/ad-writes-7ZDNDZ2E.js +0 -174
- package/dist/ad-writes-7ZDNDZ2E.js.map +0 -1
- package/dist/add-AF42LQQQ.js +0 -105
- package/dist/add-AF42LQQQ.js.map +0 -1
- package/dist/add-LJRZYJ7I.js +0 -303
- package/dist/add-LJRZYJ7I.js.map +0 -1
- package/dist/ads-KBE5JXCH.js +0 -115
- package/dist/ads-LXWXOQHX.js +0 -48
- package/dist/ads-X3AM6M7L.js +0 -77
- package/dist/ads-X3AM6M7L.js.map +0 -1
- package/dist/adsets-YWBJFPAZ.js +0 -182
- package/dist/advertisers-6FOCN2W3.js +0 -121
- package/dist/advertisers-6FOCN2W3.js.map +0 -1
- package/dist/analytics-64HBRJJE.js +0 -2435
- package/dist/analytics-64HBRJJE.js.map +0 -1
- package/dist/analytics-VY5NL2GL.js +0 -445
- package/dist/analytics-VY5NL2GL.js.map +0 -1
- package/dist/animate-2BMHZ4FM.js +0 -480
- package/dist/asset-writes-72DEVXGO.js +0 -48
- package/dist/assign-N2I2BM67.js +0 -78
- package/dist/assign-N2I2BM67.js.map +0 -1
- package/dist/audience-size-H5DEZXJN.js +0 -74
- package/dist/audience-size-H5DEZXJN.js.map +0 -1
- package/dist/audience-writes-KCHLNFSI.js +0 -325
- package/dist/audience-writes-KCHLNFSI.js.map +0 -1
- package/dist/audiences-QAH42HIM.js +0 -86
- package/dist/audiences-WCDWN64L.js +0 -268
- package/dist/audiences-WCDWN64L.js.map +0 -1
- package/dist/audit-2AAF6AOX.js +0 -152
- package/dist/audit-2AAF6AOX.js.map +0 -1
- package/dist/autocomplete-3GSKRNCZ.js +0 -112
- package/dist/autocomplete-3GSKRNCZ.js.map +0 -1
- package/dist/avatars-N6W6HUPP.js +0 -38
- package/dist/bid-pricing-IMITXHXN.js +0 -101
- package/dist/bid-pricing-IMITXHXN.js.map +0 -1
- package/dist/brand-ITWQVZD2.js +0 -22
- package/dist/brief-JJNEYPYB.js +0 -541
- package/dist/brief-JJNEYPYB.js.map +0 -1
- package/dist/campaign-groups-TTQLP32Q.js +0 -97
- package/dist/campaign-groups-TTQLP32Q.js.map +0 -1
- package/dist/campaign-writes-MAKPHQ3V.js +0 -166
- package/dist/campaign-writes-MAKPHQ3V.js.map +0 -1
- package/dist/campaign-writes-XO74BALZ.js +0 -174
- package/dist/campaign-writes-XO74BALZ.js.map +0 -1
- package/dist/campaigns-5BIDXYSR.js +0 -111
- package/dist/campaigns-LS65QM6W.js +0 -76
- package/dist/campaigns-LS65QM6W.js.map +0 -1
- package/dist/campaigns-XZOQ2VTK.js +0 -130
- package/dist/campaigns-XZPXCS7I.js +0 -111
- package/dist/campaigns-XZPXCS7I.js.map +0 -1
- package/dist/canvas-SL3RMOY5.js +0 -46
- package/dist/capabilities-LSR5GCE6.js +0 -145
- package/dist/capabilities-LSR5GCE6.js.map +0 -1
- package/dist/catalog-TZLU5NWI.js +0 -65
- package/dist/catalogs-JLCSFZYC.js +0 -779
- package/dist/catalogs-JLCSFZYC.js.map +0 -1
- package/dist/catalogs-T23RKYFC.js +0 -128
- package/dist/catalogs-T23RKYFC.js.map +0 -1
- package/dist/changes-36C754R4.js +0 -135
- package/dist/chatgpt-3WFOPURY.js +0 -47
- package/dist/chats-GGYTXNJS.js +0 -277
- package/dist/chats-GGYTXNJS.js.map +0 -1
- package/dist/check-P7UPBBG7.js +0 -105
- package/dist/check-P7UPBBG7.js.map +0 -1
- package/dist/chunk-2TOIY2WN.js +0 -4254
- package/dist/chunk-2TOIY2WN.js.map +0 -1
- package/dist/chunk-3YJNSUNF.js +0 -131
- package/dist/chunk-4D46PS6J.js +0 -344
- package/dist/chunk-4GAEB6NK.js +0 -228
- package/dist/chunk-5XTGG4PV.js +0 -274
- package/dist/chunk-6JCX3YLM.js +0 -249
- package/dist/chunk-6KWEF6HF.js +0 -8914
- package/dist/chunk-7HZSORAB.js +0 -843
- package/dist/chunk-7J3NZBPV.js +0 -2982
- package/dist/chunk-7J3NZBPV.js.map +0 -1
- package/dist/chunk-A3IQAONL.js +0 -638
- package/dist/chunk-ALMYGH5U.js +0 -479
- package/dist/chunk-AQKRSEBQ.js +0 -103
- package/dist/chunk-ASRS37QE.js +0 -710
- package/dist/chunk-ASRS37QE.js.map +0 -1
- package/dist/chunk-BL6RTOK3.js +0 -297
- package/dist/chunk-C6CBBZBO.js +0 -203
- package/dist/chunk-CCEDZTP7.js +0 -391
- package/dist/chunk-CCEDZTP7.js.map +0 -1
- package/dist/chunk-CKQTJ2LV.js +0 -89
- package/dist/chunk-D3KLDIPQ.js +0 -45
- package/dist/chunk-DL2UJNJ7.js +0 -8954
- package/dist/chunk-DQ54POZN.js +0 -363
- package/dist/chunk-EDLZGTGN.js +0 -216
- package/dist/chunk-EDLZGTGN.js.map +0 -1
- package/dist/chunk-EXSHBYNQ.js +0 -349
- package/dist/chunk-EXSHBYNQ.js.map +0 -1
- package/dist/chunk-F4YQ5PVR.js +0 -1518
- package/dist/chunk-FFFJBNHA.js +0 -63
- package/dist/chunk-FFG2OYVV.js +0 -64
- package/dist/chunk-FKQK22IX.js +0 -51
- package/dist/chunk-FLK6QHOY.js +0 -142
- package/dist/chunk-GACSA5A6.js +0 -1646
- package/dist/chunk-HJKYTNAZ.js +0 -61
- package/dist/chunk-HML3VQIW.js +0 -225
- package/dist/chunk-INUU3752.js +0 -392
- package/dist/chunk-IQHO2ABF.js +0 -197
- package/dist/chunk-J3UWMBOP.js +0 -547
- package/dist/chunk-JAC6JVCI.js +0 -26
- package/dist/chunk-JDR3HUEL.js +0 -191
- package/dist/chunk-JI77AKT6.js +0 -19
- package/dist/chunk-JNURZHZJ.js +0 -942
- package/dist/chunk-JSNMKTFM.js +0 -592
- package/dist/chunk-K4FLWDEX.js +0 -122
- package/dist/chunk-KBRJSPIM.js +0 -676
- package/dist/chunk-LAC6YHHX.js +0 -97
- package/dist/chunk-LRV6M2WB.js +0 -1919
- package/dist/chunk-M7HD42M6.js +0 -24017
- package/dist/chunk-M7HD42M6.js.map +0 -1
- package/dist/chunk-MCJ5I5LR.js +0 -3187
- package/dist/chunk-MCJ5I5LR.js.map +0 -1
- package/dist/chunk-MGYC2IRC.js +0 -783
- package/dist/chunk-MI4HXE7M.js +0 -23
- package/dist/chunk-MJ7RNDD4.js +0 -910
- package/dist/chunk-MVD7QIXI.js +0 -46
- package/dist/chunk-MZPS46OR.js +0 -76
- package/dist/chunk-OBJCNGZL.js +0 -207
- package/dist/chunk-OJGYYH6K.js +0 -179
- package/dist/chunk-OLBLXJNI.js +0 -224
- package/dist/chunk-PFTYKINE.js +0 -207
- package/dist/chunk-PLBITHV6.js +0 -846
- package/dist/chunk-PX3PUDK7.js +0 -167
- package/dist/chunk-Q6JMMBSQ.js +0 -831
- package/dist/chunk-RAQHUMKS.js +0 -169
- package/dist/chunk-SA22KXWT.js +0 -163
- package/dist/chunk-SIXU5PDF.js +0 -66
- package/dist/chunk-SWN6OHXG.js +0 -148
- package/dist/chunk-SXMK5AEJ.js +0 -494
- package/dist/chunk-TTLD66NI.js +0 -319
- package/dist/chunk-TVAIOC77.js +0 -287
- package/dist/chunk-TVTSA4EN.js +0 -188
- package/dist/chunk-TX7CQTD4.js +0 -5368
- package/dist/chunk-UKSSNYLU.js +0 -98
- package/dist/chunk-V5NHJU3M.js +0 -604
- package/dist/chunk-VIPKDXGU.js +0 -4229
- package/dist/chunk-VIPKDXGU.js.map +0 -1
- package/dist/chunk-W4D7C74B.js +0 -387
- package/dist/chunk-WF25CCLD.js +0 -170
- package/dist/chunk-WQPUX3BA.js +0 -275
- package/dist/chunk-WR3FR3K3.js +0 -156
- package/dist/chunk-XDNJC62G.js +0 -91
- package/dist/chunk-XE6N4SZI.js +0 -429
- package/dist/chunk-XGPU2VDU.js +0 -219
- package/dist/chunk-XUJZO7MZ.js +0 -57
- package/dist/chunk-Y67LUJBE.js +0 -455
- package/dist/chunk-Y7XSDJEA.js +0 -3868
- package/dist/chunk-YNYAT2TZ.js +0 -285
- package/dist/chunk-ZNNQK366.js +0 -7198
- package/dist/chunk-ZNNQK366.js.map +0 -1
- package/dist/chunk-ZNRGH4NS.js +0 -150
- package/dist/claim-4KUETSW3.js +0 -198
- package/dist/claim-4KUETSW3.js.map +0 -1
- package/dist/companies-XFO6WPVT.js +0 -196
- package/dist/companies-XFO6WPVT.js.map +0 -1
- package/dist/company-OJGISG7K.js +0 -306
- package/dist/company-OJGISG7K.js.map +0 -1
- package/dist/complete-CXOST5J3.js +0 -82
- package/dist/complete-CXOST5J3.js.map +0 -1
- package/dist/connect-HPQ32KGV.js +0 -43
- package/dist/conversation-D5HKCTDA.js +0 -94
- package/dist/conversation-D5HKCTDA.js.map +0 -1
- package/dist/conversion-report-DKXFHLLX.js +0 -125
- package/dist/conversion-report-DKXFHLLX.js.map +0 -1
- package/dist/conversion-upload-command-KTYAY7IG.js +0 -439
- package/dist/conversion-writes-7ODJDAUP.js +0 -120
- package/dist/conversion-writes-7ODJDAUP.js.map +0 -1
- package/dist/conversions-BKVGNNC6.js +0 -76
- package/dist/conversions-BKVGNNC6.js.map +0 -1
- package/dist/conversions-SYNDEB6D.js +0 -138
- package/dist/conversions-SYNDEB6D.js.map +0 -1
- package/dist/copy-writes-P4WK6OPM.js +0 -168
- package/dist/copy-writes-P4WK6OPM.js.map +0 -1
- package/dist/create-7D4VD4TC.js +0 -208
- package/dist/create-7D4VD4TC.js.map +0 -1
- package/dist/create-7QDEAWZS.js +0 -133
- package/dist/create-7QDEAWZS.js.map +0 -1
- package/dist/create-IQSYEC4M.js +0 -60
- package/dist/create-IQSYEC4M.js.map +0 -1
- package/dist/create-TQSCM7MG.js +0 -237
- package/dist/create-TQSCM7MG.js.map +0 -1
- package/dist/creatives-JPKA2RHU.js +0 -89
- package/dist/creatives-RNOL4F4E.js +0 -58
- package/dist/creatives-RXI27T2D.js +0 -221
- package/dist/creatives-RXI27T2D.js.map +0 -1
- package/dist/credentials-PYW55B52.js +0 -288
- package/dist/credentials-PYW55B52.js.map +0 -1
- package/dist/critique-2SYHNAW5.js +0 -1449
- package/dist/critique-2SYHNAW5.js.map +0 -1
- package/dist/critique-72GFZSHA.js +0 -230
- package/dist/critique-72GFZSHA.js.map +0 -1
- package/dist/crm-EATDSXXB.js +0 -225
- package/dist/crm-EATDSXXB.js.map +0 -1
- package/dist/crm-XXP3VBYD.js +0 -321
- package/dist/crm-XXP3VBYD.js.map +0 -1
- package/dist/currency-R4ORE2U3.js +0 -88
- package/dist/custom-conversions-5HJBB5XL.js +0 -128
- package/dist/customers-OFZTEXST.js +0 -57
- package/dist/delete-FGVZIK4R.js +0 -55
- package/dist/delete-FGVZIK4R.js.map +0 -1
- package/dist/delete-HBZZL4UA.js +0 -67
- package/dist/delete-HBZZL4UA.js.map +0 -1
- package/dist/delete-JOUXMRIX.js +0 -65
- package/dist/delete-JOUXMRIX.js.map +0 -1
- package/dist/demographics-SB7NBYOI.js +0 -139
- package/dist/demographics-SB7NBYOI.js.map +0 -1
- package/dist/discard-YYGIRDII.js +0 -67
- package/dist/discard-YYGIRDII.js.map +0 -1
- package/dist/discover-GSJRZUOC.js +0 -172
- package/dist/domain-3KRAJAUH.js +0 -99
- package/dist/domain-3KRAJAUH.js.map +0 -1
- package/dist/download-QCBKJ6OR.js +0 -170
- package/dist/download-QCBKJ6OR.js.map +0 -1
- package/dist/draft-7CGFFZTH.js +0 -333
- package/dist/draft-7CGFFZTH.js.map +0 -1
- package/dist/draft-BI4NW6AU.js +0 -308
- package/dist/draft-BI4NW6AU.js.map +0 -1
- package/dist/draft-LPVK6YHI.js +0 -281
- package/dist/draft-LPVK6YHI.js.map +0 -1
- package/dist/draft-QF5JEUTH.js +0 -218
- package/dist/draft-QF5JEUTH.js.map +0 -1
- package/dist/draft-WYDMLNYA.js +0 -308
- package/dist/experiments-ZCEYRP3H.js +0 -234
- package/dist/experiments-ZCEYRP3H.js.map +0 -1
- package/dist/facets-G7ZDPI5Q.js +0 -115
- package/dist/facets-G7ZDPI5Q.js.map +0 -1
- package/dist/feedback-3U3CL2VB.js +0 -109
- package/dist/feedback-3U3CL2VB.js.map +0 -1
- package/dist/feedback-record-4ZHPENIP.js +0 -263
- package/dist/feedback-record-4ZHPENIP.js.map +0 -1
- package/dist/fetch-PNVNNWTP.js +0 -177
- package/dist/fetch-PNVNNWTP.js.map +0 -1
- package/dist/fit-53DGYRFD.js +0 -63
- package/dist/flows-JXLQBP5Q.js +0 -248
- package/dist/flows-JXLQBP5Q.js.map +0 -1
- package/dist/fonts-LFMBUT4R.js +0 -37
- package/dist/forecast-4AG5F7YC.js +0 -169
- package/dist/forecast-VZAXI74O.js +0 -119
- package/dist/forecast-VZAXI74O.js.map +0 -1
- package/dist/funnel-EACC35UD.js +0 -395
- package/dist/funnel-EACC35UD.js.map +0 -1
- package/dist/generate-NWHPM2GQ.js +0 -263
- package/dist/get-AXBVYGAC.js +0 -57
- package/dist/get-AXBVYGAC.js.map +0 -1
- package/dist/get-D6A27Q4E.js +0 -80
- package/dist/get-D6A27Q4E.js.map +0 -1
- package/dist/google-NAA4BASO.js +0 -3267
- package/dist/google-ads-OIYUNDXQ.js +0 -196
- package/dist/google-ads-OIYUNDXQ.js.map +0 -1
- package/dist/history-5MRLNTCI.js +0 -67
- package/dist/history-5MRLNTCI.js.map +0 -1
- package/dist/history-IDYNIB6R.js +0 -134
- package/dist/history-IDYNIB6R.js.map +0 -1
- package/dist/history-IOUKN3WD.js +0 -100
- package/dist/history-IOUKN3WD.js.map +0 -1
- package/dist/hubspot-HL6WGC4G.js +0 -780
- package/dist/hubspot-HL6WGC4G.js.map +0 -1
- package/dist/ideas-NK3KQHAK.js +0 -43
- package/dist/images-2XS3JT7E.js +0 -92
- package/dist/ingest-DHXWZZX4.js +0 -24
- package/dist/ingest-FGTJRCWK.js +0 -108
- package/dist/ingest-FGTJRCWK.js.map +0 -1
- package/dist/insights-M3CYB22P.js +0 -437
- package/dist/insights-M3CYB22P.js.map +0 -1
- package/dist/insights-XCT3ONC7.js +0 -130
- package/dist/insights-XCT3ONC7.js.map +0 -1
- package/dist/inspect-53GGYRC4.js +0 -190
- package/dist/inspect-53GGYRC4.js.map +0 -1
- package/dist/instant-experiences-HT3HB4QZ.js +0 -258
- package/dist/instant-experiences-HT3HB4QZ.js.map +0 -1
- package/dist/intent-NSHW7EJT.js +0 -95
- package/dist/keyword-gap-ITTWKBWZ.js +0 -130
- package/dist/keyword-metrics-LWPE3HHW.js +0 -198
- package/dist/keyword-metrics-LWPE3HHW.js.map +0 -1
- package/dist/keywords-for-site-5K25VJ35.js +0 -129
- package/dist/keywords-for-site-5K25VJ35.js.map +0 -1
- package/dist/landing-QONUUP3C.js +0 -28
- package/dist/languages-MEFQQBJ2.js +0 -40
- package/dist/leads-FSSISJGL.js +0 -113
- package/dist/leads-FSSISJGL.js.map +0 -1
- package/dist/leads-SZOGCQFK.js +0 -538
- package/dist/leads-SZOGCQFK.js.map +0 -1
- package/dist/learn-FWWJWBDN.js +0 -205
- package/dist/learn-FWWJWBDN.js.map +0 -1
- package/dist/line-item-writes-A3UQ44NG.js +0 -209
- package/dist/line-item-writes-A3UQ44NG.js.map +0 -1
- package/dist/line-items-OH426JGT.js +0 -107
- package/dist/link-67E4NVEX.js +0 -65
- package/dist/link-67E4NVEX.js.map +0 -1
- package/dist/linkedin-CT2OSQ2I.js +0 -1314
- package/dist/linkedin-CT2OSQ2I.js.map +0 -1
- package/dist/linkedin-person-OSNLPLJJ.js +0 -137
- package/dist/linkedin-person-OSNLPLJJ.js.map +0 -1
- package/dist/list-J4OUXAKN.js +0 -65
- package/dist/list-J4OUXAKN.js.map +0 -1
- package/dist/list-L2OQK4W3.js +0 -304
- package/dist/list-L2OQK4W3.js.map +0 -1
- package/dist/list-LHMDAA2D.js +0 -152
- package/dist/list-LHMDAA2D.js.map +0 -1
- package/dist/locations-RLWAS6AC.js +0 -40
- package/dist/locations-UKBOT6SB.js +0 -67
- package/dist/locations-UKBOT6SB.js.map +0 -1
- package/dist/log-4EIV54V4.js +0 -93
- package/dist/log-4EIV54V4.js.map +0 -1
- package/dist/lookup-ZJIP2M4X.js +0 -22
- package/dist/make-MFU3CSN7.js +0 -1368
- package/dist/make-MFU3CSN7.js.map +0 -1
- package/dist/map-VWWWMQLK.js +0 -434
- package/dist/map-VWWWMQLK.js.map +0 -1
- package/dist/mcp-EKLO2VD7.js +0 -715
- package/dist/mcp-EKLO2VD7.js.map +0 -1
- package/dist/media-ZWN7E777.js +0 -18
- package/dist/media-sources-7L622UTF.js +0 -35
- package/dist/members-QK5M5NCJ.js +0 -45
- package/dist/members-QK5M5NCJ.js.map +0 -1
- package/dist/meta-EHKXH257.js +0 -122
- package/dist/metrics-K6FDCMK7.js +0 -152
- package/dist/models-JQEPSPNQ.js +0 -155
- package/dist/normalize-WI4OGKH5.js +0 -142
- package/dist/normalize-WI4OGKH5.js.map +0 -1
- package/dist/options-FKJ2QXI6.js +0 -123
- package/dist/options-FKJ2QXI6.js.map +0 -1
- package/dist/organization-7A7MPUDG.js +0 -947
- package/dist/organization-7A7MPUDG.js.map +0 -1
- package/dist/page-photos-HWKQOSCU.js +0 -116
- package/dist/page-photos-HWKQOSCU.js.map +0 -1
- package/dist/performance-K4VB6L6Z.js +0 -25
- package/dist/performance-LHAL53YO.js +0 -5539
- package/dist/performance-LHAL53YO.js.map +0 -1
- package/dist/pixels-Z7ZGXAGB.js +0 -60
- package/dist/pixels-Z7ZGXAGB.js.map +0 -1
- package/dist/plan-TVQSEKYL.js +0 -207
- package/dist/plan-TVQSEKYL.js.map +0 -1
- package/dist/preview-CWRGDFCP.js +0 -216
- package/dist/preview-CWRGDFCP.js.map +0 -1
- package/dist/promoted-tweet-writes-V4ZVJOJU.js +0 -181
- package/dist/promoted-tweet-writes-V4ZVJOJU.js.map +0 -1
- package/dist/promoted-tweets-KPG4IUVD.js +0 -119
- package/dist/publish-Y465CVUD.js +0 -342
- package/dist/publish-Y465CVUD.js.map +0 -1
- package/dist/query-QM7MBQD7.js +0 -62
- package/dist/questionnaire-LEZJLMAV.js +0 -93
- package/dist/questionnaire-LEZJLMAV.js.map +0 -1
- package/dist/reddit-Z7DOVIGR.js +0 -27
- package/dist/refresh-A6TW2Z2F.js +0 -95
- package/dist/refresh-A6TW2Z2F.js.map +0 -1
- package/dist/release-UFESJ4TM.js +0 -61
- package/dist/release-UFESJ4TM.js.map +0 -1
- package/dist/relevant-pages-VOICMQ7U.js +0 -99
- package/dist/remove-YONNYA4G.js +0 -51
- package/dist/remove-YONNYA4G.js.map +0 -1
- package/dist/reopen-FYJU2IPO.js +0 -64
- package/dist/reopen-FYJU2IPO.js.map +0 -1
- package/dist/rerun-B5SBG6ZE.js +0 -93
- package/dist/rerun-B5SBG6ZE.js.map +0 -1
- package/dist/research-HW4EVOZU.js +0 -72
- package/dist/research-OV53DIBX.js +0 -263
- package/dist/research-OV53DIBX.js.map +0 -1
- package/dist/reset-R4SIQXFH.js +0 -55
- package/dist/reset-R4SIQXFH.js.map +0 -1
- package/dist/reset-X6ODAKYH.js +0 -55
- package/dist/reset-X6ODAKYH.js.map +0 -1
- package/dist/resolve-DNRJCLCR.js +0 -122
- package/dist/resolve-DNRJCLCR.js.map +0 -1
- package/dist/retry-D5MKBHUB.js +0 -63
- package/dist/retry-D5MKBHUB.js.map +0 -1
- package/dist/retry-DVFLE7JY.js +0 -61
- package/dist/retry-DVFLE7JY.js.map +0 -1
- package/dist/revenue-QGI6XWSK.js +0 -89
- package/dist/revenue-QGI6XWSK.js.map +0 -1
- package/dist/rule-writes-S3RN47OG.js +0 -523
- package/dist/rule-writes-S3RN47OG.js.map +0 -1
- package/dist/rules-KTJ2ZZ62.js +0 -217
- package/dist/rules-TR6BAC23.js +0 -97
- package/dist/rules-TR6BAC23.js.map +0 -1
- package/dist/rules-add-T5ZO5RLR.js +0 -463
- package/dist/rules-add-T5ZO5RLR.js.map +0 -1
- package/dist/run-WZ5IXWA4.js +0 -67
- package/dist/run-WZ5IXWA4.js.map +0 -1
- package/dist/run-YRR3KOUU.js +0 -68
- package/dist/scaffold-ad-DNUCGCIH.js +0 -1514
- package/dist/scaffold-ad-DNUCGCIH.js.map +0 -1
- package/dist/scaffold-static-ad-VR65EZAG.js +0 -1013
- package/dist/scaffold-static-ad-VR65EZAG.js.map +0 -1
- package/dist/scaffold-video-JLMKCCWE.js +0 -886
- package/dist/scaffold-video-JLMKCCWE.js.map +0 -1
- package/dist/schedule-VRHCVBZA.js +0 -62
- package/dist/schedule-VRHCVBZA.js.map +0 -1
- package/dist/scheduled-agents-DG7FTCUZ.js +0 -55
- package/dist/schema-6Y3IXFDC.js +0 -69
- package/dist/schema-WZKDWF5N.js +0 -133
- package/dist/schema-WZKDWF5N.js.map +0 -1
- package/dist/search-MN66QIKJ.js +0 -175
- package/dist/search-MN66QIKJ.js.map +0 -1
- package/dist/select-IPSM2BF2.js +0 -104
- package/dist/select-IPSM2BF2.js.map +0 -1
- package/dist/sends-6FI7WELX.js +0 -348
- package/dist/sends-6FI7WELX.js.map +0 -1
- package/dist/set-prompt-N6BD3DME.js +0 -196
- package/dist/set-prompt-N6BD3DME.js.map +0 -1
- package/dist/setup-links-GTA2AROS.js +0 -142
- package/dist/setup-links-GTA2AROS.js.map +0 -1
- package/dist/shopify-S4TG6WJH.js +0 -3956
- package/dist/shopify-S4TG6WJH.js.map +0 -1
- package/dist/site-NY622E3H.js +0 -178
- package/dist/site-NY622E3H.js.map +0 -1
- package/dist/sources-4F2XO7Z6.js +0 -455
- package/dist/sources-4F2XO7Z6.js.map +0 -1
- package/dist/sources-562ITR77.js +0 -30
- package/dist/stale-JKM6MXJF.js +0 -74
- package/dist/stale-JKM6MXJF.js.map +0 -1
- package/dist/status-AUWMUDA4.js +0 -63
- package/dist/status-AUWMUDA4.js.map +0 -1
- package/dist/studies-ZOEUY6YP.js +0 -250
- package/dist/studio-T5L7UEX6.js +0 -49
- package/dist/study-writes-DTGMCNFP.js +0 -468
- package/dist/study-writes-DTGMCNFP.js.map +0 -1
- package/dist/sync-76MCGHX4.js +0 -55
- package/dist/sync-76MCGHX4.js.map +0 -1
- package/dist/sync-definition-NJPT6ABG.js +0 -67
- package/dist/tags-5KBOJJ5R.js +0 -26
- package/dist/tags-CSMLTHTU.js +0 -21
- package/dist/tags-CSMLTHTU.js.map +0 -1
- package/dist/tags-IFRZYM3G.js +0 -21
- package/dist/tags-IFRZYM3G.js.map +0 -1
- package/dist/tags-S44ADJ75.js +0 -21
- package/dist/tags-S44ADJ75.js.map +0 -1
- package/dist/tags-WR7IY3OT.js +0 -225
- package/dist/tags-WR7IY3OT.js.map +0 -1
- package/dist/targeting-VBQY3HUN.js +0 -760
- package/dist/targeting-VBQY3HUN.js.map +0 -1
- package/dist/targeting-criteria-FJWNK53T.js +0 -113
- package/dist/targets-2EHMMXD4.js +0 -104
- package/dist/targets-2EHMMXD4.js.map +0 -1
- package/dist/testimonials-WAPFIGFJ.js +0 -32
- package/dist/themes-B4LCQUXB.js +0 -95
- package/dist/top-companies-DJ2XQKMW.js +0 -109
- package/dist/top-companies-DJ2XQKMW.js.map +0 -1
- package/dist/transcript-J3LGOHCM.js +0 -163
- package/dist/transcript-J3LGOHCM.js.map +0 -1
- package/dist/translate-6RXO4C6Z.js +0 -607
- package/dist/translate-6RXO4C6Z.js.map +0 -1
- package/dist/triggers-CYXPNHQB.js +0 -142
- package/dist/triggers-CYXPNHQB.js.map +0 -1
- package/dist/unlink-5FJI7XZB.js +0 -68
- package/dist/unlink-5FJI7XZB.js.map +0 -1
- package/dist/unstage-54ZE2SZK.js +0 -86
- package/dist/unstage-54ZE2SZK.js.map +0 -1
- package/dist/unstage-MDSSPUKV.js +0 -95
- package/dist/unstage-MDSSPUKV.js.map +0 -1
- package/dist/update-BVBFNFMO.js +0 -99
- package/dist/update-BVBFNFMO.js.map +0 -1
- package/dist/update-GV3T7ZRC.js +0 -190
- package/dist/update-GV3T7ZRC.js.map +0 -1
- package/dist/update-PUQWUGPJ.js +0 -64
- package/dist/update-PUQWUGPJ.js.map +0 -1
- package/dist/update-YQBK6C3L.js +0 -153
- package/dist/update-YQBK6C3L.js.map +0 -1
- package/dist/upload-PXT5JAEV.js +0 -127
- package/dist/upload-PXT5JAEV.js.map +0 -1
- package/dist/url-options-IHL4OU4C.js +0 -130
- package/dist/url-options-IHL4OU4C.js.map +0 -1
- package/dist/url-params-IYUI6SFJ.js +0 -99
- package/dist/url-params-IYUI6SFJ.js.map +0 -1
- package/dist/validate-AD7F7LQ5.js +0 -120
- package/dist/validate-AD7F7LQ5.js.map +0 -1
- package/dist/videos-ZJCTODEB.js +0 -41
- package/dist/viewer-check-GWZNGWCO.js +0 -81
- package/dist/web-76CWAZNW.js +0 -141
- package/dist/web-76CWAZNW.js.map +0 -1
- package/dist/winning-ads-W7GTXTX7.js +0 -86
- package/dist/write-commands-K6M3RTVK.js +0 -1170
- package/dist/write-commands-K6M3RTVK.js.map +0 -1
- package/dist/write-commands-VPU53DLB.js +0 -1498
- package/dist/write-commands-VPU53DLB.js.map +0 -1
- package/dist/x-V4NNNWRU.js +0 -47
- /package/dist/{account-assets-O7IA37RE.js.map → account-assets-J5Z4URLQ.js.map} +0 -0
- /package/dist/{account-reads-SNOWDHHF.js.map → account-reads-FOEVPWDP.js.map} +0 -0
- /package/dist/{actions-4JYHXRFH.js.map → actions-QZDSLFFK.js.map} +0 -0
- /package/dist/{ads-LXWXOQHX.js.map → ads-AYJAYLFR.js.map} +0 -0
- /package/dist/{ads-KBE5JXCH.js.map → ads-MAOI7S6V.js.map} +0 -0
- /package/dist/{adsets-YWBJFPAZ.js.map → adsets-QRKICEFD.js.map} +0 -0
- /package/dist/{animate-2BMHZ4FM.js.map → animate-HRWFVE2N.js.map} +0 -0
- /package/dist/{asset-writes-72DEVXGO.js.map → asset-writes-JLVUAVUZ.js.map} +0 -0
- /package/dist/{audiences-QAH42HIM.js.map → audiences-CDDI5HR5.js.map} +0 -0
- /package/dist/{avatars-N6W6HUPP.js.map → avatars-4HCGWBOL.js.map} +0 -0
- /package/dist/{brand-ITWQVZD2.js.map → brand-C6OB6Q4U.js.map} +0 -0
- /package/dist/{campaigns-XZOQ2VTK.js.map → campaigns-HES5MDUG.js.map} +0 -0
- /package/dist/{campaigns-5BIDXYSR.js.map → campaigns-ZYU4BXDP.js.map} +0 -0
- /package/dist/{canvas-SL3RMOY5.js.map → canvas-AI34UBGU.js.map} +0 -0
- /package/dist/{catalog-TZLU5NWI.js.map → catalog-ZY3MFT55.js.map} +0 -0
- /package/dist/{changes-36C754R4.js.map → changes-OOUVQDBY.js.map} +0 -0
- /package/dist/{chatgpt-3WFOPURY.js.map → chatgpt-NAXIFWXV.js.map} +0 -0
- /package/dist/{chunk-TTLD66NI.js.map → chunk-3CHYJYSS.js.map} +0 -0
- /package/dist/{chunk-XE6N4SZI.js.map → chunk-3G3GC5N4.js.map} +0 -0
- /package/dist/{chunk-5XTGG4PV.js.map → chunk-3M45PYU7.js.map} +0 -0
- /package/dist/{chunk-MI4HXE7M.js.map → chunk-3QHXF3QI.js.map} +0 -0
- /package/dist/{chunk-Y7XSDJEA.js.map → chunk-3XPHUMLJ.js.map} +0 -0
- /package/dist/{chunk-MGYC2IRC.js.map → chunk-45EERHDB.js.map} +0 -0
- /package/dist/{chunk-W4D7C74B.js.map → chunk-4FGTANFK.js.map} +0 -0
- /package/dist/{chunk-PX3PUDK7.js.map → chunk-4IHWT7PH.js.map} +0 -0
- /package/dist/{chunk-PLBITHV6.js.map → chunk-4LF4AYPT.js.map} +0 -0
- /package/dist/{chunk-XGPU2VDU.js.map → chunk-4UQRXKYJ.js.map} +0 -0
- /package/dist/{chunk-Y67LUJBE.js.map → chunk-5JJD33Y2.js.map} +0 -0
- /package/dist/{chunk-Q6JMMBSQ.js.map → chunk-5K4QYYOJ.js.map} +0 -0
- /package/dist/{chunk-SA22KXWT.js.map → chunk-5LJ6E4YU.js.map} +0 -0
- /package/dist/{chunk-WQPUX3BA.js.map → chunk-5T73MMBL.js.map} +0 -0
- /package/dist/{chunk-DQ54POZN.js.map → chunk-64MAHLTK.js.map} +0 -0
- /package/dist/{chunk-JAC6JVCI.js.map → chunk-6OIKNJ7G.js.map} +0 -0
- /package/dist/{chunk-3YJNSUNF.js.map → chunk-6ZFSDYWV.js.map} +0 -0
- /package/dist/{chunk-TVAIOC77.js.map → chunk-7BUIOP36.js.map} +0 -0
- /package/dist/{chunk-K4FLWDEX.js.map → chunk-AN4OEQXE.js.map} +0 -0
- /package/dist/{chunk-TX7CQTD4.js.map → chunk-AULSX5ZA.js.map} +0 -0
- /package/dist/{chunk-MVD7QIXI.js.map → chunk-AVYUFJQQ.js.map} +0 -0
- /package/dist/{chunk-LAC6YHHX.js.map → chunk-B4YF7VQF.js.map} +0 -0
- /package/dist/{chunk-UKSSNYLU.js.map → chunk-BDOYNGUL.js.map} +0 -0
- /package/dist/{chunk-PFTYKINE.js.map → chunk-BJOK7QD4.js.map} +0 -0
- /package/dist/{chunk-IQHO2ABF.js.map → chunk-CMCGFSUS.js.map} +0 -0
- /package/dist/{chunk-KBRJSPIM.js.map → chunk-DMJUIUAL.js.map} +0 -0
- /package/dist/{chunk-HML3VQIW.js.map → chunk-DUCUOZLS.js.map} +0 -0
- /package/dist/{chunk-7HZSORAB.js.map → chunk-FJZYOVSW.js.map} +0 -0
- /package/dist/{chunk-JI77AKT6.js.map → chunk-FKP4ECJY.js.map} +0 -0
- /package/dist/{chunk-DL2UJNJ7.js.map → chunk-GNMEOU46.js.map} +0 -0
- /package/dist/{chunk-WR3FR3K3.js.map → chunk-GYKYXWUQ.js.map} +0 -0
- /package/dist/{chunk-BL6RTOK3.js.map → chunk-GYPLRU4Y.js.map} +0 -0
- /package/dist/{chunk-YNYAT2TZ.js.map → chunk-I43ZEWJQ.js.map} +0 -0
- /package/dist/{chunk-4GAEB6NK.js.map → chunk-IZABTTW5.js.map} +0 -0
- /package/dist/{chunk-GACSA5A6.js.map → chunk-K7IE6UYV.js.map} +0 -0
- /package/dist/{chunk-V5NHJU3M.js.map → chunk-KH5YHHJV.js.map} +0 -0
- /package/dist/{chunk-FKQK22IX.js.map → chunk-KMY7AD3N.js.map} +0 -0
- /package/dist/{chunk-6KWEF6HF.js.map → chunk-KPCHWDJM.js.map} +0 -0
- /package/dist/{chunk-SWN6OHXG.js.map → chunk-KTZCLJ2D.js.map} +0 -0
- /package/dist/{chunk-A3IQAONL.js.map → chunk-MKUA54QE.js.map} +0 -0
- /package/dist/{chunk-FFFJBNHA.js.map → chunk-MTV2RSGY.js.map} +0 -0
- /package/dist/{chunk-INUU3752.js.map → chunk-N2QX57K3.js.map} +0 -0
- /package/dist/{chunk-OJGYYH6K.js.map → chunk-NB2FU6EZ.js.map} +0 -0
- /package/dist/{chunk-ALMYGH5U.js.map → chunk-NEYWS2DQ.js.map} +0 -0
- /package/dist/{chunk-TVTSA4EN.js.map → chunk-NWF2LRKO.js.map} +0 -0
- /package/dist/{chunk-JDR3HUEL.js.map → chunk-OTC6UMJ2.js.map} +0 -0
- /package/dist/{chunk-OLBLXJNI.js.map → chunk-OUY2IAWL.js.map} +0 -0
- /package/dist/{chunk-4D46PS6J.js.map → chunk-PJXNCRMR.js.map} +0 -0
- /package/dist/{chunk-XDNJC62G.js.map → chunk-PYQ3GF7R.js.map} +0 -0
- /package/dist/{chunk-WF25CCLD.js.map → chunk-Q3EIVZAR.js.map} +0 -0
- /package/dist/{chunk-OBJCNGZL.js.map → chunk-QDQZ62FL.js.map} +0 -0
- /package/dist/{chunk-LRV6M2WB.js.map → chunk-QHZE62GP.js.map} +0 -0
- /package/dist/{chunk-AQKRSEBQ.js.map → chunk-RGR6TSTJ.js.map} +0 -0
- /package/dist/{chunk-C6CBBZBO.js.map → chunk-SAAXU7QR.js.map} +0 -0
- /package/dist/{chunk-SIXU5PDF.js.map → chunk-SHTKLRI6.js.map} +0 -0
- /package/dist/{chunk-MZPS46OR.js.map → chunk-SIKCVWM3.js.map} +0 -0
- /package/dist/{chunk-CKQTJ2LV.js.map → chunk-SSXG53CZ.js.map} +0 -0
- /package/dist/{chunk-J3UWMBOP.js.map → chunk-TBWAM577.js.map} +0 -0
- /package/dist/{chunk-RAQHUMKS.js.map → chunk-TGPGQTZA.js.map} +0 -0
- /package/dist/{chunk-F4YQ5PVR.js.map → chunk-UMIX2BMM.js.map} +0 -0
- /package/dist/{chunk-ZNRGH4NS.js.map → chunk-URMAEVZO.js.map} +0 -0
- /package/dist/{chunk-HJKYTNAZ.js.map → chunk-VBO3ZVUU.js.map} +0 -0
- /package/dist/{chunk-JSNMKTFM.js.map → chunk-VFLYMHTO.js.map} +0 -0
- /package/dist/{chunk-6JCX3YLM.js.map → chunk-VGYIVXIZ.js.map} +0 -0
- /package/dist/{chunk-XUJZO7MZ.js.map → chunk-VIB7R533.js.map} +0 -0
- /package/dist/{chunk-D3KLDIPQ.js.map → chunk-WLESMH4J.js.map} +0 -0
- /package/dist/{chunk-MJ7RNDD4.js.map → chunk-WVWLPXBO.js.map} +0 -0
- /package/dist/{chunk-SXMK5AEJ.js.map → chunk-XEH5XAP6.js.map} +0 -0
- /package/dist/{chunk-FLK6QHOY.js.map → chunk-XEOKVL4E.js.map} +0 -0
- /package/dist/{chunk-FFG2OYVV.js.map → chunk-XOGQJYXH.js.map} +0 -0
- /package/dist/{chunk-JNURZHZJ.js.map → chunk-XUXRA7IB.js.map} +0 -0
- /package/dist/{connect-HPQ32KGV.js.map → connect-IAXSZPGA.js.map} +0 -0
- /package/dist/{conversion-upload-command-KTYAY7IG.js.map → conversion-upload-command-IHFKVX2M.js.map} +0 -0
- /package/dist/{creatives-JPKA2RHU.js.map → creatives-BB6S2OF6.js.map} +0 -0
- /package/dist/{creatives-RNOL4F4E.js.map → creatives-BZEVJ6ER.js.map} +0 -0
- /package/dist/{currency-R4ORE2U3.js.map → currency-CGKO5GKH.js.map} +0 -0
- /package/dist/{custom-conversions-5HJBB5XL.js.map → custom-conversions-HAGG72LF.js.map} +0 -0
- /package/dist/{customers-OFZTEXST.js.map → customers-NKKU6S7G.js.map} +0 -0
- /package/dist/{discover-GSJRZUOC.js.map → discover-VM3O7CQM.js.map} +0 -0
- /package/dist/{draft-WYDMLNYA.js.map → draft-CRDBU6LF.js.map} +0 -0
- /package/dist/{fit-53DGYRFD.js.map → fit-Q5GRVF2O.js.map} +0 -0
- /package/dist/{fonts-LFMBUT4R.js.map → fonts-GD4YRXQU.js.map} +0 -0
- /package/dist/{forecast-4AG5F7YC.js.map → forecast-ONVS2QAI.js.map} +0 -0
- /package/dist/{generate-NWHPM2GQ.js.map → generate-VBEY3N3L.js.map} +0 -0
- /package/dist/{google-NAA4BASO.js.map → google-7EZP7I6J.js.map} +0 -0
- /package/dist/{ideas-NK3KQHAK.js.map → ideas-WX7EBPSF.js.map} +0 -0
- /package/dist/{images-2XS3JT7E.js.map → images-4AXF4LAC.js.map} +0 -0
- /package/dist/{ingest-DHXWZZX4.js.map → ingest-C3M4GUO6.js.map} +0 -0
- /package/dist/{intent-NSHW7EJT.js.map → intent-ZMYMFGB4.js.map} +0 -0
- /package/dist/{keyword-gap-ITTWKBWZ.js.map → keyword-gap-XSJO2R77.js.map} +0 -0
- /package/dist/{landing-QONUUP3C.js.map → landing-MUNYZQNA.js.map} +0 -0
- /package/dist/{languages-MEFQQBJ2.js.map → languages-DIQ3OG3E.js.map} +0 -0
- /package/dist/{line-items-OH426JGT.js.map → line-items-JR25T2C5.js.map} +0 -0
- /package/dist/{locations-RLWAS6AC.js.map → locations-HTVYJSDJ.js.map} +0 -0
- /package/dist/{lookup-ZJIP2M4X.js.map → lookup-S5VG7AWH.js.map} +0 -0
- /package/dist/{media-ZWN7E777.js.map → media-P4T4ZBNS.js.map} +0 -0
- /package/dist/{media-sources-7L622UTF.js.map → media-sources-P246GM7W.js.map} +0 -0
- /package/dist/{meta-EHKXH257.js.map → meta-IPLWNYC7.js.map} +0 -0
- /package/dist/{metrics-K6FDCMK7.js.map → metrics-WYWUX6Y5.js.map} +0 -0
- /package/dist/{models-JQEPSPNQ.js.map → models-HJ7Y55AH.js.map} +0 -0
- /package/dist/{performance-K4VB6L6Z.js.map → performance-J3DLNI2W.js.map} +0 -0
- /package/dist/{promoted-tweets-KPG4IUVD.js.map → promoted-tweets-W42FNWS7.js.map} +0 -0
- /package/dist/{query-QM7MBQD7.js.map → query-IQICLABN.js.map} +0 -0
- /package/dist/{reddit-Z7DOVIGR.js.map → reddit-X4CERXYF.js.map} +0 -0
- /package/dist/{relevant-pages-VOICMQ7U.js.map → relevant-pages-UDDQOYLD.js.map} +0 -0
- /package/dist/{research-HW4EVOZU.js.map → research-D5UUJF74.js.map} +0 -0
- /package/dist/{rules-KTJ2ZZ62.js.map → rules-ZVS2MWED.js.map} +0 -0
- /package/dist/{run-YRR3KOUU.js.map → run-T7XAH2W5.js.map} +0 -0
- /package/dist/{scheduled-agents-DG7FTCUZ.js.map → scheduled-agents-ZGCUZ6SB.js.map} +0 -0
- /package/dist/{schema-6Y3IXFDC.js.map → schema-D6BMZAPB.js.map} +0 -0
- /package/dist/{sources-562ITR77.js.map → sources-DVMJEXEX.js.map} +0 -0
- /package/dist/{studies-ZOEUY6YP.js.map → studies-EPO2AM4M.js.map} +0 -0
- /package/dist/{studio-T5L7UEX6.js.map → studio-5Z4NMA4K.js.map} +0 -0
- /package/dist/{sync-definition-NJPT6ABG.js.map → sync-definition-F3CXG6KG.js.map} +0 -0
- /package/dist/{tags-5KBOJJ5R.js.map → tags-SEZ2CQJM.js.map} +0 -0
- /package/dist/{targeting-criteria-FJWNK53T.js.map → targeting-criteria-AU5CSMAU.js.map} +0 -0
- /package/dist/{testimonials-WAPFIGFJ.js.map → testimonials-Y6PUV6AL.js.map} +0 -0
- /package/dist/{themes-B4LCQUXB.js.map → themes-PGPIAKAO.js.map} +0 -0
- /package/dist/{videos-ZJCTODEB.js.map → videos-SVZV5YYC.js.map} +0 -0
- /package/dist/{viewer-check-GWZNGWCO.js.map → viewer-check-LUAEGV6H.js.map} +0 -0
- /package/dist/{winning-ads-W7GTXTX7.js.map → winning-ads-KNLJHHCO.js.map} +0 -0
- /package/dist/{x-V4NNNWRU.js.map → x-ZQNHYIDU.js.map} +0 -0
package/dist/chunk-MCJ5I5LR.js
DELETED
|
@@ -1,3187 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__commonJS,
|
|
3
|
-
__toESM
|
|
4
|
-
} from "./chunk-YQSBHWOI.js";
|
|
5
|
-
|
|
6
|
-
// ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js
|
|
7
|
-
var require_safe_stable_stringify = __commonJS({
|
|
8
|
-
"../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js"(exports, module) {
|
|
9
|
-
"use strict";
|
|
10
|
-
var { hasOwnProperty } = Object.prototype;
|
|
11
|
-
var stringify = configure2();
|
|
12
|
-
stringify.configure = configure2;
|
|
13
|
-
stringify.stringify = stringify;
|
|
14
|
-
stringify.default = stringify;
|
|
15
|
-
exports.stringify = stringify;
|
|
16
|
-
exports.configure = configure2;
|
|
17
|
-
module.exports = stringify;
|
|
18
|
-
var strEscapeSequencesRegExp = /[\u0000-\u001f\u0022\u005c\ud800-\udfff]/;
|
|
19
|
-
function strEscape(str) {
|
|
20
|
-
if (str.length < 5e3 && !strEscapeSequencesRegExp.test(str)) {
|
|
21
|
-
return `"${str}"`;
|
|
22
|
-
}
|
|
23
|
-
return JSON.stringify(str);
|
|
24
|
-
}
|
|
25
|
-
function sort(array, comparator) {
|
|
26
|
-
if (array.length > 200 || comparator) {
|
|
27
|
-
return array.sort(comparator);
|
|
28
|
-
}
|
|
29
|
-
for (let i = 1; i < array.length; i++) {
|
|
30
|
-
const currentValue = array[i];
|
|
31
|
-
let position = i;
|
|
32
|
-
while (position !== 0 && array[position - 1] > currentValue) {
|
|
33
|
-
array[position] = array[position - 1];
|
|
34
|
-
position--;
|
|
35
|
-
}
|
|
36
|
-
array[position] = currentValue;
|
|
37
|
-
}
|
|
38
|
-
return array;
|
|
39
|
-
}
|
|
40
|
-
var typedArrayPrototypeGetSymbolToStringTag = Object.getOwnPropertyDescriptor(
|
|
41
|
-
Object.getPrototypeOf(
|
|
42
|
-
Object.getPrototypeOf(
|
|
43
|
-
new Int8Array()
|
|
44
|
-
)
|
|
45
|
-
),
|
|
46
|
-
Symbol.toStringTag
|
|
47
|
-
).get;
|
|
48
|
-
function isTypedArrayWithEntries(value) {
|
|
49
|
-
return typedArrayPrototypeGetSymbolToStringTag.call(value) !== void 0 && value.length !== 0;
|
|
50
|
-
}
|
|
51
|
-
function stringifyTypedArray(array, separator, maximumBreadth) {
|
|
52
|
-
if (array.length < maximumBreadth) {
|
|
53
|
-
maximumBreadth = array.length;
|
|
54
|
-
}
|
|
55
|
-
const whitespace = separator === "," ? "" : " ";
|
|
56
|
-
let res = `"0":${whitespace}${array[0]}`;
|
|
57
|
-
for (let i = 1; i < maximumBreadth; i++) {
|
|
58
|
-
res += `${separator}"${i}":${whitespace}${array[i]}`;
|
|
59
|
-
}
|
|
60
|
-
return res;
|
|
61
|
-
}
|
|
62
|
-
function getCircularValueOption(options) {
|
|
63
|
-
if (hasOwnProperty.call(options, "circularValue")) {
|
|
64
|
-
const circularValue = options.circularValue;
|
|
65
|
-
if (typeof circularValue === "string") {
|
|
66
|
-
return `"${circularValue}"`;
|
|
67
|
-
}
|
|
68
|
-
if (circularValue == null) {
|
|
69
|
-
return circularValue;
|
|
70
|
-
}
|
|
71
|
-
if (circularValue === Error || circularValue === TypeError) {
|
|
72
|
-
return {
|
|
73
|
-
toString() {
|
|
74
|
-
throw new TypeError("Converting circular structure to JSON");
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
throw new TypeError('The "circularValue" argument must be of type string or the value null or undefined');
|
|
79
|
-
}
|
|
80
|
-
return '"[Circular]"';
|
|
81
|
-
}
|
|
82
|
-
function getDeterministicOption(options) {
|
|
83
|
-
let value;
|
|
84
|
-
if (hasOwnProperty.call(options, "deterministic")) {
|
|
85
|
-
value = options.deterministic;
|
|
86
|
-
if (typeof value !== "boolean" && typeof value !== "function") {
|
|
87
|
-
throw new TypeError('The "deterministic" argument must be of type boolean or comparator function');
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return value === void 0 ? true : value;
|
|
91
|
-
}
|
|
92
|
-
function getBooleanOption(options, key) {
|
|
93
|
-
let value;
|
|
94
|
-
if (hasOwnProperty.call(options, key)) {
|
|
95
|
-
value = options[key];
|
|
96
|
-
if (typeof value !== "boolean") {
|
|
97
|
-
throw new TypeError(`The "${key}" argument must be of type boolean`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return value === void 0 ? true : value;
|
|
101
|
-
}
|
|
102
|
-
function getPositiveIntegerOption(options, key) {
|
|
103
|
-
let value;
|
|
104
|
-
if (hasOwnProperty.call(options, key)) {
|
|
105
|
-
value = options[key];
|
|
106
|
-
if (typeof value !== "number") {
|
|
107
|
-
throw new TypeError(`The "${key}" argument must be of type number`);
|
|
108
|
-
}
|
|
109
|
-
if (!Number.isInteger(value)) {
|
|
110
|
-
throw new TypeError(`The "${key}" argument must be an integer`);
|
|
111
|
-
}
|
|
112
|
-
if (value < 1) {
|
|
113
|
-
throw new RangeError(`The "${key}" argument must be >= 1`);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return value === void 0 ? Infinity : value;
|
|
117
|
-
}
|
|
118
|
-
function getItemCount(number) {
|
|
119
|
-
if (number === 1) {
|
|
120
|
-
return "1 item";
|
|
121
|
-
}
|
|
122
|
-
return `${number} items`;
|
|
123
|
-
}
|
|
124
|
-
function getUniqueReplacerSet(replacerArray) {
|
|
125
|
-
const replacerSet = /* @__PURE__ */ new Set();
|
|
126
|
-
for (const value of replacerArray) {
|
|
127
|
-
if (typeof value === "string" || typeof value === "number") {
|
|
128
|
-
replacerSet.add(String(value));
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return replacerSet;
|
|
132
|
-
}
|
|
133
|
-
function getStrictOption(options) {
|
|
134
|
-
if (hasOwnProperty.call(options, "strict")) {
|
|
135
|
-
const value = options.strict;
|
|
136
|
-
if (typeof value !== "boolean") {
|
|
137
|
-
throw new TypeError('The "strict" argument must be of type boolean');
|
|
138
|
-
}
|
|
139
|
-
if (value) {
|
|
140
|
-
return (value2) => {
|
|
141
|
-
let message = `Object can not safely be stringified. Received type ${typeof value2}`;
|
|
142
|
-
if (typeof value2 !== "function") message += ` (${value2.toString()})`;
|
|
143
|
-
throw new Error(message);
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
function configure2(options) {
|
|
149
|
-
options = { ...options };
|
|
150
|
-
const fail = getStrictOption(options);
|
|
151
|
-
if (fail) {
|
|
152
|
-
if (options.bigint === void 0) {
|
|
153
|
-
options.bigint = false;
|
|
154
|
-
}
|
|
155
|
-
if (!("circularValue" in options)) {
|
|
156
|
-
options.circularValue = Error;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
const circularValue = getCircularValueOption(options);
|
|
160
|
-
const bigint = getBooleanOption(options, "bigint");
|
|
161
|
-
const deterministic = getDeterministicOption(options);
|
|
162
|
-
const comparator = typeof deterministic === "function" ? deterministic : void 0;
|
|
163
|
-
const maximumDepth = getPositiveIntegerOption(options, "maximumDepth");
|
|
164
|
-
const maximumBreadth = getPositiveIntegerOption(options, "maximumBreadth");
|
|
165
|
-
function stringifyFnReplacer(key, parent, stack, replacer, spacer, indentation) {
|
|
166
|
-
let value = parent[key];
|
|
167
|
-
if (typeof value === "object" && value !== null && typeof value.toJSON === "function") {
|
|
168
|
-
value = value.toJSON(key);
|
|
169
|
-
}
|
|
170
|
-
value = replacer.call(parent, key, value);
|
|
171
|
-
switch (typeof value) {
|
|
172
|
-
case "string":
|
|
173
|
-
return strEscape(value);
|
|
174
|
-
case "object": {
|
|
175
|
-
if (value === null) {
|
|
176
|
-
return "null";
|
|
177
|
-
}
|
|
178
|
-
if (stack.indexOf(value) !== -1) {
|
|
179
|
-
return circularValue;
|
|
180
|
-
}
|
|
181
|
-
let res = "";
|
|
182
|
-
let join = ",";
|
|
183
|
-
const originalIndentation = indentation;
|
|
184
|
-
if (Array.isArray(value)) {
|
|
185
|
-
if (value.length === 0) {
|
|
186
|
-
return "[]";
|
|
187
|
-
}
|
|
188
|
-
if (maximumDepth < stack.length + 1) {
|
|
189
|
-
return '"[Array]"';
|
|
190
|
-
}
|
|
191
|
-
stack.push(value);
|
|
192
|
-
if (spacer !== "") {
|
|
193
|
-
indentation += spacer;
|
|
194
|
-
res += `
|
|
195
|
-
${indentation}`;
|
|
196
|
-
join = `,
|
|
197
|
-
${indentation}`;
|
|
198
|
-
}
|
|
199
|
-
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
200
|
-
let i = 0;
|
|
201
|
-
for (; i < maximumValuesToStringify - 1; i++) {
|
|
202
|
-
const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
203
|
-
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
204
|
-
res += join;
|
|
205
|
-
}
|
|
206
|
-
const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
|
|
207
|
-
res += tmp !== void 0 ? tmp : "null";
|
|
208
|
-
if (value.length - 1 > maximumBreadth) {
|
|
209
|
-
const removedKeys = value.length - maximumBreadth - 1;
|
|
210
|
-
res += `${join}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
211
|
-
}
|
|
212
|
-
if (spacer !== "") {
|
|
213
|
-
res += `
|
|
214
|
-
${originalIndentation}`;
|
|
215
|
-
}
|
|
216
|
-
stack.pop();
|
|
217
|
-
return `[${res}]`;
|
|
218
|
-
}
|
|
219
|
-
let keys = Object.keys(value);
|
|
220
|
-
const keyLength = keys.length;
|
|
221
|
-
if (keyLength === 0) {
|
|
222
|
-
return "{}";
|
|
223
|
-
}
|
|
224
|
-
if (maximumDepth < stack.length + 1) {
|
|
225
|
-
return '"[Object]"';
|
|
226
|
-
}
|
|
227
|
-
let whitespace = "";
|
|
228
|
-
let separator = "";
|
|
229
|
-
if (spacer !== "") {
|
|
230
|
-
indentation += spacer;
|
|
231
|
-
join = `,
|
|
232
|
-
${indentation}`;
|
|
233
|
-
whitespace = " ";
|
|
234
|
-
}
|
|
235
|
-
const maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
236
|
-
if (deterministic && !isTypedArrayWithEntries(value)) {
|
|
237
|
-
keys = sort(keys, comparator);
|
|
238
|
-
}
|
|
239
|
-
stack.push(value);
|
|
240
|
-
for (let i = 0; i < maximumPropertiesToStringify; i++) {
|
|
241
|
-
const key2 = keys[i];
|
|
242
|
-
const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
|
|
243
|
-
if (tmp !== void 0) {
|
|
244
|
-
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
245
|
-
separator = join;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
if (keyLength > maximumBreadth) {
|
|
249
|
-
const removedKeys = keyLength - maximumBreadth;
|
|
250
|
-
res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
|
|
251
|
-
separator = join;
|
|
252
|
-
}
|
|
253
|
-
if (spacer !== "" && separator.length > 1) {
|
|
254
|
-
res = `
|
|
255
|
-
${indentation}${res}
|
|
256
|
-
${originalIndentation}`;
|
|
257
|
-
}
|
|
258
|
-
stack.pop();
|
|
259
|
-
return `{${res}}`;
|
|
260
|
-
}
|
|
261
|
-
case "number":
|
|
262
|
-
return isFinite(value) ? String(value) : fail ? fail(value) : "null";
|
|
263
|
-
case "boolean":
|
|
264
|
-
return value === true ? "true" : "false";
|
|
265
|
-
case "undefined":
|
|
266
|
-
return void 0;
|
|
267
|
-
case "bigint":
|
|
268
|
-
if (bigint) {
|
|
269
|
-
return String(value);
|
|
270
|
-
}
|
|
271
|
-
// fallthrough
|
|
272
|
-
default:
|
|
273
|
-
return fail ? fail(value) : void 0;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
function stringifyArrayReplacer(key, value, stack, replacer, spacer, indentation) {
|
|
277
|
-
if (typeof value === "object" && value !== null && typeof value.toJSON === "function") {
|
|
278
|
-
value = value.toJSON(key);
|
|
279
|
-
}
|
|
280
|
-
switch (typeof value) {
|
|
281
|
-
case "string":
|
|
282
|
-
return strEscape(value);
|
|
283
|
-
case "object": {
|
|
284
|
-
if (value === null) {
|
|
285
|
-
return "null";
|
|
286
|
-
}
|
|
287
|
-
if (stack.indexOf(value) !== -1) {
|
|
288
|
-
return circularValue;
|
|
289
|
-
}
|
|
290
|
-
const originalIndentation = indentation;
|
|
291
|
-
let res = "";
|
|
292
|
-
let join = ",";
|
|
293
|
-
if (Array.isArray(value)) {
|
|
294
|
-
if (value.length === 0) {
|
|
295
|
-
return "[]";
|
|
296
|
-
}
|
|
297
|
-
if (maximumDepth < stack.length + 1) {
|
|
298
|
-
return '"[Array]"';
|
|
299
|
-
}
|
|
300
|
-
stack.push(value);
|
|
301
|
-
if (spacer !== "") {
|
|
302
|
-
indentation += spacer;
|
|
303
|
-
res += `
|
|
304
|
-
${indentation}`;
|
|
305
|
-
join = `,
|
|
306
|
-
${indentation}`;
|
|
307
|
-
}
|
|
308
|
-
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
309
|
-
let i = 0;
|
|
310
|
-
for (; i < maximumValuesToStringify - 1; i++) {
|
|
311
|
-
const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
312
|
-
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
313
|
-
res += join;
|
|
314
|
-
}
|
|
315
|
-
const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
|
|
316
|
-
res += tmp !== void 0 ? tmp : "null";
|
|
317
|
-
if (value.length - 1 > maximumBreadth) {
|
|
318
|
-
const removedKeys = value.length - maximumBreadth - 1;
|
|
319
|
-
res += `${join}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
320
|
-
}
|
|
321
|
-
if (spacer !== "") {
|
|
322
|
-
res += `
|
|
323
|
-
${originalIndentation}`;
|
|
324
|
-
}
|
|
325
|
-
stack.pop();
|
|
326
|
-
return `[${res}]`;
|
|
327
|
-
}
|
|
328
|
-
stack.push(value);
|
|
329
|
-
let whitespace = "";
|
|
330
|
-
if (spacer !== "") {
|
|
331
|
-
indentation += spacer;
|
|
332
|
-
join = `,
|
|
333
|
-
${indentation}`;
|
|
334
|
-
whitespace = " ";
|
|
335
|
-
}
|
|
336
|
-
let separator = "";
|
|
337
|
-
for (const key2 of replacer) {
|
|
338
|
-
const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
|
|
339
|
-
if (tmp !== void 0) {
|
|
340
|
-
res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
|
|
341
|
-
separator = join;
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
if (spacer !== "" && separator.length > 1) {
|
|
345
|
-
res = `
|
|
346
|
-
${indentation}${res}
|
|
347
|
-
${originalIndentation}`;
|
|
348
|
-
}
|
|
349
|
-
stack.pop();
|
|
350
|
-
return `{${res}}`;
|
|
351
|
-
}
|
|
352
|
-
case "number":
|
|
353
|
-
return isFinite(value) ? String(value) : fail ? fail(value) : "null";
|
|
354
|
-
case "boolean":
|
|
355
|
-
return value === true ? "true" : "false";
|
|
356
|
-
case "undefined":
|
|
357
|
-
return void 0;
|
|
358
|
-
case "bigint":
|
|
359
|
-
if (bigint) {
|
|
360
|
-
return String(value);
|
|
361
|
-
}
|
|
362
|
-
// fallthrough
|
|
363
|
-
default:
|
|
364
|
-
return fail ? fail(value) : void 0;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
function stringifyIndent(key, value, stack, spacer, indentation) {
|
|
368
|
-
switch (typeof value) {
|
|
369
|
-
case "string":
|
|
370
|
-
return strEscape(value);
|
|
371
|
-
case "object": {
|
|
372
|
-
if (value === null) {
|
|
373
|
-
return "null";
|
|
374
|
-
}
|
|
375
|
-
if (typeof value.toJSON === "function") {
|
|
376
|
-
value = value.toJSON(key);
|
|
377
|
-
if (typeof value !== "object") {
|
|
378
|
-
return stringifyIndent(key, value, stack, spacer, indentation);
|
|
379
|
-
}
|
|
380
|
-
if (value === null) {
|
|
381
|
-
return "null";
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
if (stack.indexOf(value) !== -1) {
|
|
385
|
-
return circularValue;
|
|
386
|
-
}
|
|
387
|
-
const originalIndentation = indentation;
|
|
388
|
-
if (Array.isArray(value)) {
|
|
389
|
-
if (value.length === 0) {
|
|
390
|
-
return "[]";
|
|
391
|
-
}
|
|
392
|
-
if (maximumDepth < stack.length + 1) {
|
|
393
|
-
return '"[Array]"';
|
|
394
|
-
}
|
|
395
|
-
stack.push(value);
|
|
396
|
-
indentation += spacer;
|
|
397
|
-
let res2 = `
|
|
398
|
-
${indentation}`;
|
|
399
|
-
const join2 = `,
|
|
400
|
-
${indentation}`;
|
|
401
|
-
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
402
|
-
let i = 0;
|
|
403
|
-
for (; i < maximumValuesToStringify - 1; i++) {
|
|
404
|
-
const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
405
|
-
res2 += tmp2 !== void 0 ? tmp2 : "null";
|
|
406
|
-
res2 += join2;
|
|
407
|
-
}
|
|
408
|
-
const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
|
|
409
|
-
res2 += tmp !== void 0 ? tmp : "null";
|
|
410
|
-
if (value.length - 1 > maximumBreadth) {
|
|
411
|
-
const removedKeys = value.length - maximumBreadth - 1;
|
|
412
|
-
res2 += `${join2}"... ${getItemCount(removedKeys)} not stringified"`;
|
|
413
|
-
}
|
|
414
|
-
res2 += `
|
|
415
|
-
${originalIndentation}`;
|
|
416
|
-
stack.pop();
|
|
417
|
-
return `[${res2}]`;
|
|
418
|
-
}
|
|
419
|
-
let keys = Object.keys(value);
|
|
420
|
-
const keyLength = keys.length;
|
|
421
|
-
if (keyLength === 0) {
|
|
422
|
-
return "{}";
|
|
423
|
-
}
|
|
424
|
-
if (maximumDepth < stack.length + 1) {
|
|
425
|
-
return '"[Object]"';
|
|
426
|
-
}
|
|
427
|
-
indentation += spacer;
|
|
428
|
-
const join = `,
|
|
429
|
-
${indentation}`;
|
|
430
|
-
let res = "";
|
|
431
|
-
let separator = "";
|
|
432
|
-
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
433
|
-
if (isTypedArrayWithEntries(value)) {
|
|
434
|
-
res += stringifyTypedArray(value, join, maximumBreadth);
|
|
435
|
-
keys = keys.slice(value.length);
|
|
436
|
-
maximumPropertiesToStringify -= value.length;
|
|
437
|
-
separator = join;
|
|
438
|
-
}
|
|
439
|
-
if (deterministic) {
|
|
440
|
-
keys = sort(keys, comparator);
|
|
441
|
-
}
|
|
442
|
-
stack.push(value);
|
|
443
|
-
for (let i = 0; i < maximumPropertiesToStringify; i++) {
|
|
444
|
-
const key2 = keys[i];
|
|
445
|
-
const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
|
|
446
|
-
if (tmp !== void 0) {
|
|
447
|
-
res += `${separator}${strEscape(key2)}: ${tmp}`;
|
|
448
|
-
separator = join;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
if (keyLength > maximumBreadth) {
|
|
452
|
-
const removedKeys = keyLength - maximumBreadth;
|
|
453
|
-
res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
|
|
454
|
-
separator = join;
|
|
455
|
-
}
|
|
456
|
-
if (separator !== "") {
|
|
457
|
-
res = `
|
|
458
|
-
${indentation}${res}
|
|
459
|
-
${originalIndentation}`;
|
|
460
|
-
}
|
|
461
|
-
stack.pop();
|
|
462
|
-
return `{${res}}`;
|
|
463
|
-
}
|
|
464
|
-
case "number":
|
|
465
|
-
return isFinite(value) ? String(value) : fail ? fail(value) : "null";
|
|
466
|
-
case "boolean":
|
|
467
|
-
return value === true ? "true" : "false";
|
|
468
|
-
case "undefined":
|
|
469
|
-
return void 0;
|
|
470
|
-
case "bigint":
|
|
471
|
-
if (bigint) {
|
|
472
|
-
return String(value);
|
|
473
|
-
}
|
|
474
|
-
// fallthrough
|
|
475
|
-
default:
|
|
476
|
-
return fail ? fail(value) : void 0;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
function stringifySimple(key, value, stack) {
|
|
480
|
-
switch (typeof value) {
|
|
481
|
-
case "string":
|
|
482
|
-
return strEscape(value);
|
|
483
|
-
case "object": {
|
|
484
|
-
if (value === null) {
|
|
485
|
-
return "null";
|
|
486
|
-
}
|
|
487
|
-
if (typeof value.toJSON === "function") {
|
|
488
|
-
value = value.toJSON(key);
|
|
489
|
-
if (typeof value !== "object") {
|
|
490
|
-
return stringifySimple(key, value, stack);
|
|
491
|
-
}
|
|
492
|
-
if (value === null) {
|
|
493
|
-
return "null";
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
if (stack.indexOf(value) !== -1) {
|
|
497
|
-
return circularValue;
|
|
498
|
-
}
|
|
499
|
-
let res = "";
|
|
500
|
-
const hasLength = value.length !== void 0;
|
|
501
|
-
if (hasLength && Array.isArray(value)) {
|
|
502
|
-
if (value.length === 0) {
|
|
503
|
-
return "[]";
|
|
504
|
-
}
|
|
505
|
-
if (maximumDepth < stack.length + 1) {
|
|
506
|
-
return '"[Array]"';
|
|
507
|
-
}
|
|
508
|
-
stack.push(value);
|
|
509
|
-
const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
|
|
510
|
-
let i = 0;
|
|
511
|
-
for (; i < maximumValuesToStringify - 1; i++) {
|
|
512
|
-
const tmp2 = stringifySimple(String(i), value[i], stack);
|
|
513
|
-
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
514
|
-
res += ",";
|
|
515
|
-
}
|
|
516
|
-
const tmp = stringifySimple(String(i), value[i], stack);
|
|
517
|
-
res += tmp !== void 0 ? tmp : "null";
|
|
518
|
-
if (value.length - 1 > maximumBreadth) {
|
|
519
|
-
const removedKeys = value.length - maximumBreadth - 1;
|
|
520
|
-
res += `,"... ${getItemCount(removedKeys)} not stringified"`;
|
|
521
|
-
}
|
|
522
|
-
stack.pop();
|
|
523
|
-
return `[${res}]`;
|
|
524
|
-
}
|
|
525
|
-
let keys = Object.keys(value);
|
|
526
|
-
const keyLength = keys.length;
|
|
527
|
-
if (keyLength === 0) {
|
|
528
|
-
return "{}";
|
|
529
|
-
}
|
|
530
|
-
if (maximumDepth < stack.length + 1) {
|
|
531
|
-
return '"[Object]"';
|
|
532
|
-
}
|
|
533
|
-
let separator = "";
|
|
534
|
-
let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
|
|
535
|
-
if (hasLength && isTypedArrayWithEntries(value)) {
|
|
536
|
-
res += stringifyTypedArray(value, ",", maximumBreadth);
|
|
537
|
-
keys = keys.slice(value.length);
|
|
538
|
-
maximumPropertiesToStringify -= value.length;
|
|
539
|
-
separator = ",";
|
|
540
|
-
}
|
|
541
|
-
if (deterministic) {
|
|
542
|
-
keys = sort(keys, comparator);
|
|
543
|
-
}
|
|
544
|
-
stack.push(value);
|
|
545
|
-
for (let i = 0; i < maximumPropertiesToStringify; i++) {
|
|
546
|
-
const key2 = keys[i];
|
|
547
|
-
const tmp = stringifySimple(key2, value[key2], stack);
|
|
548
|
-
if (tmp !== void 0) {
|
|
549
|
-
res += `${separator}${strEscape(key2)}:${tmp}`;
|
|
550
|
-
separator = ",";
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
if (keyLength > maximumBreadth) {
|
|
554
|
-
const removedKeys = keyLength - maximumBreadth;
|
|
555
|
-
res += `${separator}"...":"${getItemCount(removedKeys)} not stringified"`;
|
|
556
|
-
}
|
|
557
|
-
stack.pop();
|
|
558
|
-
return `{${res}}`;
|
|
559
|
-
}
|
|
560
|
-
case "number":
|
|
561
|
-
return isFinite(value) ? String(value) : fail ? fail(value) : "null";
|
|
562
|
-
case "boolean":
|
|
563
|
-
return value === true ? "true" : "false";
|
|
564
|
-
case "undefined":
|
|
565
|
-
return void 0;
|
|
566
|
-
case "bigint":
|
|
567
|
-
if (bigint) {
|
|
568
|
-
return String(value);
|
|
569
|
-
}
|
|
570
|
-
// fallthrough
|
|
571
|
-
default:
|
|
572
|
-
return fail ? fail(value) : void 0;
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
function stringify2(value, replacer, space) {
|
|
576
|
-
if (arguments.length > 1) {
|
|
577
|
-
let spacer = "";
|
|
578
|
-
if (typeof space === "number") {
|
|
579
|
-
spacer = " ".repeat(Math.min(space, 10));
|
|
580
|
-
} else if (typeof space === "string") {
|
|
581
|
-
spacer = space.slice(0, 10);
|
|
582
|
-
}
|
|
583
|
-
if (replacer != null) {
|
|
584
|
-
if (typeof replacer === "function") {
|
|
585
|
-
return stringifyFnReplacer("", { "": value }, [], replacer, spacer, "");
|
|
586
|
-
}
|
|
587
|
-
if (Array.isArray(replacer)) {
|
|
588
|
-
return stringifyArrayReplacer("", value, [], getUniqueReplacerSet(replacer), spacer, "");
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
if (spacer.length !== 0) {
|
|
592
|
-
return stringifyIndent("", value, [], spacer, "");
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
return stringifySimple("", value, []);
|
|
596
|
-
}
|
|
597
|
-
return stringify2;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
});
|
|
601
|
-
|
|
602
|
-
// ../canvas-contract/src/adPlacements.ts
|
|
603
|
-
var AD_PLATFORMS = [
|
|
604
|
-
"meta",
|
|
605
|
-
"google_display",
|
|
606
|
-
"google_pmax",
|
|
607
|
-
"google_demandgen",
|
|
608
|
-
"google_search",
|
|
609
|
-
"youtube",
|
|
610
|
-
"linkedin",
|
|
611
|
-
"tiktok",
|
|
612
|
-
"x",
|
|
613
|
-
"reddit",
|
|
614
|
-
"pinterest",
|
|
615
|
-
"snapchat",
|
|
616
|
-
"chatgpt"
|
|
617
|
-
];
|
|
618
|
-
var AD_PLATFORM_LEAD = {
|
|
619
|
-
meta: "4:5",
|
|
620
|
-
google_display: "1:1",
|
|
621
|
-
google_pmax: "1:1",
|
|
622
|
-
google_demandgen: "1:1",
|
|
623
|
-
google_search: "1:1",
|
|
624
|
-
youtube: "1.91:1",
|
|
625
|
-
linkedin: "1:1",
|
|
626
|
-
tiktok: "9:16",
|
|
627
|
-
x: "1.91:1",
|
|
628
|
-
reddit: "1:1",
|
|
629
|
-
pinterest: "2:3",
|
|
630
|
-
snapchat: "9:16",
|
|
631
|
-
chatgpt: "1:1"
|
|
632
|
-
};
|
|
633
|
-
var AD_PLATFORM_NAMES = {
|
|
634
|
-
meta: "Meta",
|
|
635
|
-
google_display: "Google Display",
|
|
636
|
-
google_pmax: "Performance Max",
|
|
637
|
-
google_demandgen: "Demand Gen",
|
|
638
|
-
google_search: "Google Search",
|
|
639
|
-
youtube: "YouTube",
|
|
640
|
-
linkedin: "LinkedIn",
|
|
641
|
-
tiktok: "TikTok",
|
|
642
|
-
x: "X",
|
|
643
|
-
reddit: "Reddit",
|
|
644
|
-
pinterest: "Pinterest",
|
|
645
|
-
snapchat: "Snapchat",
|
|
646
|
-
chatgpt: "ChatGPT"
|
|
647
|
-
};
|
|
648
|
-
var FEED_MARGIN = { top: 0.04, bottom: 0.04, left: 0.04, right: 0.04 };
|
|
649
|
-
var size = (width, height, required = true) => ({ width, height, required });
|
|
650
|
-
var AD_PLACEMENTS = [
|
|
651
|
-
{
|
|
652
|
-
id: "meta_feed",
|
|
653
|
-
platform: "meta",
|
|
654
|
-
name: "Facebook and Instagram feeds",
|
|
655
|
-
sizes: [size(1080, 1350), size(1080, 1080, false)],
|
|
656
|
-
safe: FEED_MARGIN,
|
|
657
|
-
source: "https://www.facebook.com/business/ads-guide/update/image/instagram-feed"
|
|
658
|
-
},
|
|
659
|
-
{
|
|
660
|
-
id: "meta_stories",
|
|
661
|
-
platform: "meta",
|
|
662
|
-
name: "Facebook and Instagram Stories",
|
|
663
|
-
sizes: [size(1080, 1920)],
|
|
664
|
-
safe: { top: 0.16, bottom: 0.22, left: 0.04, right: 0.04 },
|
|
665
|
-
cover: { top: 0.09, bottom: 0.15 },
|
|
666
|
-
source: "https://www.facebook.com/business/ads-guide/update/image/instagram-story"
|
|
667
|
-
},
|
|
668
|
-
{
|
|
669
|
-
id: "meta_reels",
|
|
670
|
-
platform: "meta",
|
|
671
|
-
name: "Facebook and Instagram Reels",
|
|
672
|
-
sizes: [size(1080, 1920)],
|
|
673
|
-
safe: { top: 0.16, bottom: 0.37, left: 0.04, right: 0.04 },
|
|
674
|
-
cover: { top: 0.09, bottom: 0.32, rail: { width: 0.08, from: 0.6 } },
|
|
675
|
-
railMargin: { width: 0.1, from: 0.55 },
|
|
676
|
-
source: "https://www.facebook.com/business/ads-guide/update/image/instagram-reels"
|
|
677
|
-
},
|
|
678
|
-
{
|
|
679
|
-
id: "meta_right_column",
|
|
680
|
-
platform: "meta",
|
|
681
|
-
name: "Facebook right column, Marketplace and search results",
|
|
682
|
-
sizes: [size(1080, 1080), size(1200, 628, false)],
|
|
683
|
-
safe: FEED_MARGIN,
|
|
684
|
-
optIn: true,
|
|
685
|
-
source: "https://www.facebook.com/business/ads-guide/update/image/facebook-right-column"
|
|
686
|
-
},
|
|
687
|
-
{
|
|
688
|
-
id: "google_display_responsive",
|
|
689
|
-
platform: "google_display",
|
|
690
|
-
name: "Responsive display ads (Google Display Network)",
|
|
691
|
-
sizes: [size(1200, 628), size(1200, 1200), size(900, 1600, false)],
|
|
692
|
-
safe: FEED_MARGIN,
|
|
693
|
-
rule: "Text may cover at most 20% of the image; Google crops up to 5% from each side.",
|
|
694
|
-
source: "https://support.google.com/google-ads/answer/9823397"
|
|
695
|
-
},
|
|
696
|
-
{
|
|
697
|
-
id: "google_display_banners",
|
|
698
|
-
platform: "google_display",
|
|
699
|
-
name: "Uploaded display banners",
|
|
700
|
-
sizes: [
|
|
701
|
-
size(300, 250),
|
|
702
|
-
size(728, 90),
|
|
703
|
-
size(320, 50),
|
|
704
|
-
size(336, 280, false),
|
|
705
|
-
size(300, 600, false),
|
|
706
|
-
size(160, 600, false),
|
|
707
|
-
size(320, 100, false),
|
|
708
|
-
size(970, 250, false)
|
|
709
|
-
],
|
|
710
|
-
safe: FEED_MARGIN,
|
|
711
|
-
rule: "Each banner is exactly its pixel size, 150 KB at most.",
|
|
712
|
-
source: "https://support.google.com/google-ads/answer/7031480"
|
|
713
|
-
},
|
|
714
|
-
{
|
|
715
|
-
id: "google_pmax",
|
|
716
|
-
platform: "google_pmax",
|
|
717
|
-
name: "Performance Max asset group",
|
|
718
|
-
sizes: [size(1200, 628), size(1200, 1200), size(960, 1200, false)],
|
|
719
|
-
safe: FEED_MARGIN,
|
|
720
|
-
rule: "Google crops up to 5% from each side; keep text and logos off the edges.",
|
|
721
|
-
source: "https://support.google.com/google-ads/answer/13676244"
|
|
722
|
-
},
|
|
723
|
-
{
|
|
724
|
-
id: "google_demandgen",
|
|
725
|
-
platform: "google_demandgen",
|
|
726
|
-
name: "Demand Gen (YouTube, Discover, Gmail)",
|
|
727
|
-
sizes: [size(1200, 628), size(1200, 1200), size(960, 1200, false)],
|
|
728
|
-
safe: FEED_MARGIN,
|
|
729
|
-
source: "https://support.google.com/google-ads/answer/13547298"
|
|
730
|
-
},
|
|
731
|
-
{
|
|
732
|
-
id: "google_search_images",
|
|
733
|
-
platform: "google_search",
|
|
734
|
-
name: "Image assets on Search ads",
|
|
735
|
-
sizes: [size(1200, 1200), size(1200, 628, false)],
|
|
736
|
-
safe: FEED_MARGIN,
|
|
737
|
-
rule: "No overlaid text, logos or buttons on the image.",
|
|
738
|
-
source: "https://support.google.com/google-ads/answer/12118270"
|
|
739
|
-
},
|
|
740
|
-
{
|
|
741
|
-
id: "youtube_feed",
|
|
742
|
-
platform: "youtube",
|
|
743
|
-
name: "YouTube home and watch-next feeds",
|
|
744
|
-
sizes: [size(1200, 628), size(1200, 1200, false)],
|
|
745
|
-
safe: FEED_MARGIN,
|
|
746
|
-
source: "https://support.google.com/google-ads/answer/13547298"
|
|
747
|
-
},
|
|
748
|
-
{
|
|
749
|
-
id: "youtube_shorts",
|
|
750
|
-
platform: "youtube",
|
|
751
|
-
name: "YouTube Shorts",
|
|
752
|
-
sizes: [size(1080, 1920)],
|
|
753
|
-
safe: { top: 0.12, bottom: 0.35, left: 0.05, right: 0.05 },
|
|
754
|
-
cover: { top: 0.08, bottom: 0.3, rail: { width: 0.14, from: 0.45 } },
|
|
755
|
-
railMargin: { width: 0.16, from: 0.4 },
|
|
756
|
-
source: "https://support.google.com/youtube/answer/10059070"
|
|
757
|
-
},
|
|
758
|
-
{
|
|
759
|
-
id: "linkedin_feed",
|
|
760
|
-
platform: "linkedin",
|
|
761
|
-
name: "LinkedIn feed (single image)",
|
|
762
|
-
sizes: [size(1200, 1200), size(1200, 627, false), size(720, 900, false)],
|
|
763
|
-
safe: FEED_MARGIN,
|
|
764
|
-
source: "https://www.linkedin.com/help/lms/answer/a426534"
|
|
765
|
-
},
|
|
766
|
-
{
|
|
767
|
-
id: "tiktok_feed",
|
|
768
|
-
platform: "tiktok",
|
|
769
|
-
name: "TikTok For You feed",
|
|
770
|
-
sizes: [size(1080, 1920)],
|
|
771
|
-
safe: { top: 0.1, bottom: 0.3, left: 0.06, right: 0.06 },
|
|
772
|
-
cover: { top: 0.07, bottom: 0.25, rail: { width: 0.13, from: 0.45 } },
|
|
773
|
-
railMargin: { width: 0.15, from: 0.4 },
|
|
774
|
-
source: "https://ads.tiktok.com/help/article/tiktok-ads-safe-zone"
|
|
775
|
-
},
|
|
776
|
-
{
|
|
777
|
-
id: "x_timeline",
|
|
778
|
-
platform: "x",
|
|
779
|
-
name: "X timeline (image and website card)",
|
|
780
|
-
sizes: [size(1200, 628), size(1200, 1200, false)],
|
|
781
|
-
safe: FEED_MARGIN,
|
|
782
|
-
source: "https://business.x.com/en/help/campaign-setup/creative-ad-specifications"
|
|
783
|
-
},
|
|
784
|
-
{
|
|
785
|
-
id: "reddit_feed",
|
|
786
|
-
platform: "reddit",
|
|
787
|
-
name: "Reddit feed and conversation pages",
|
|
788
|
-
sizes: [size(1080, 1080), size(1080, 1350, false), size(1200, 628, false)],
|
|
789
|
-
safe: FEED_MARGIN,
|
|
790
|
-
source: "https://business.reddithelp.com/s/article/image-ad-specs"
|
|
791
|
-
},
|
|
792
|
-
{
|
|
793
|
-
id: "pinterest_feed",
|
|
794
|
-
platform: "pinterest",
|
|
795
|
-
name: "Pinterest home feed and search (standard pin)",
|
|
796
|
-
sizes: [size(1e3, 1500), size(1e3, 1e3, false)],
|
|
797
|
-
safe: FEED_MARGIN,
|
|
798
|
-
source: "https://help.pinterest.com/en/business/article/pinterest-product-specs"
|
|
799
|
-
},
|
|
800
|
-
{
|
|
801
|
-
id: "snapchat_snap_ads",
|
|
802
|
-
platform: "snapchat",
|
|
803
|
-
name: "Snapchat Snap Ads",
|
|
804
|
-
sizes: [size(1080, 1920)],
|
|
805
|
-
safe: { top: 0.11, bottom: 0.21, left: 0.04, right: 0.04 },
|
|
806
|
-
cover: { top: 0.08, bottom: 0.18 },
|
|
807
|
-
source: "https://businesshelp.snapchat.com/s/article/single-image-video-specs"
|
|
808
|
-
},
|
|
809
|
-
{
|
|
810
|
-
id: "chatgpt_card",
|
|
811
|
-
platform: "chatgpt",
|
|
812
|
-
name: "ChatGPT sponsored card",
|
|
813
|
-
sizes: [size(1200, 1200)],
|
|
814
|
-
safe: FEED_MARGIN,
|
|
815
|
-
rule: "The card shows a square of the image; keep everything that matters inside it.",
|
|
816
|
-
source: "https://help.openai.com/en/articles/chatgpt-ads"
|
|
817
|
-
}
|
|
818
|
-
];
|
|
819
|
-
var RATIOS = [
|
|
820
|
-
["1:1", 1],
|
|
821
|
-
["4:5", 4 / 5],
|
|
822
|
-
["9:16", 9 / 16],
|
|
823
|
-
["16:9", 16 / 9],
|
|
824
|
-
["1.91:1", 1.91],
|
|
825
|
-
["2:3", 2 / 3],
|
|
826
|
-
["3:4", 3 / 4],
|
|
827
|
-
["4:3", 4 / 3]
|
|
828
|
-
];
|
|
829
|
-
function ratioLabel(width, height) {
|
|
830
|
-
const r = width / height;
|
|
831
|
-
const known = RATIOS.find(([, value]) => Math.abs(Math.log(r / value)) < 0.01);
|
|
832
|
-
return known ? known[0] : `${width}x${height}`;
|
|
833
|
-
}
|
|
834
|
-
function placementsFor(names) {
|
|
835
|
-
const placements = [];
|
|
836
|
-
const unknown = [];
|
|
837
|
-
for (const raw of names) {
|
|
838
|
-
const name = raw.trim().toLowerCase();
|
|
839
|
-
if (!name) continue;
|
|
840
|
-
const found = AD_PLACEMENTS.filter((p) => p.id === name || p.platform === name && !p.optIn);
|
|
841
|
-
if (found.length === 0) unknown.push(raw.trim());
|
|
842
|
-
for (const p of found) if (!placements.includes(p)) placements.push(p);
|
|
843
|
-
}
|
|
844
|
-
return { placements, unknown };
|
|
845
|
-
}
|
|
846
|
-
function addSize(into, format, size2, placement) {
|
|
847
|
-
const existing = into.find((f) => f.format === format);
|
|
848
|
-
if (!existing) {
|
|
849
|
-
into.push({ format, width: size2.width, height: size2.height, placements: [placement] });
|
|
850
|
-
return;
|
|
851
|
-
}
|
|
852
|
-
if (!existing.placements.includes(placement)) existing.placements.push(placement);
|
|
853
|
-
if (size2.width > existing.width) Object.assign(existing, { width: size2.width, height: size2.height });
|
|
854
|
-
}
|
|
855
|
-
function leadOf(names) {
|
|
856
|
-
for (const raw of names) {
|
|
857
|
-
const name = raw.trim().toLowerCase();
|
|
858
|
-
if (name in AD_PLATFORM_LEAD) return AD_PLATFORM_LEAD[name];
|
|
859
|
-
const placement = AD_PLACEMENTS.find((p) => p.id === name);
|
|
860
|
-
const first = placement?.sizes.find((s) => s.required);
|
|
861
|
-
if (first) return ratioLabel(first.width, first.height);
|
|
862
|
-
}
|
|
863
|
-
return void 0;
|
|
864
|
-
}
|
|
865
|
-
function leadFirst(formats, lead) {
|
|
866
|
-
const at = formats.findIndex((f) => f.format === lead);
|
|
867
|
-
return at <= 0 ? formats : [formats[at], ...formats.filter((_, i) => i !== at)];
|
|
868
|
-
}
|
|
869
|
-
function deliveryPlan(names, asked) {
|
|
870
|
-
const { placements, unknown } = placementsFor(names);
|
|
871
|
-
const { required, shown, banners } = sizesOf(placements);
|
|
872
|
-
const { formats, refused } = asked && asked.length > 0 ? askedSizes(asked, shown, placements) : { formats: required, refused: [] };
|
|
873
|
-
const platformLead = leadOf(names);
|
|
874
|
-
const lead = formats.some((f) => f.format === platformLead) ? platformLead : formats[0]?.format;
|
|
875
|
-
const delivered = leadFirst(formats, lead);
|
|
876
|
-
const served = new Set(delivered.flatMap((f) => f.placements));
|
|
877
|
-
return {
|
|
878
|
-
lead: lead ?? "",
|
|
879
|
-
formats: delivered,
|
|
880
|
-
banners,
|
|
881
|
-
placements: placements.map((p) => p.id).filter((id) => served.has(id)),
|
|
882
|
-
unknown,
|
|
883
|
-
refused,
|
|
884
|
-
cropped: placements.filter((p) => ratioSized(p) && !served.has(p.id)).map((p) => p.id)
|
|
885
|
-
};
|
|
886
|
-
}
|
|
887
|
-
function sizesOf(placements) {
|
|
888
|
-
const required = [];
|
|
889
|
-
const shown = [];
|
|
890
|
-
const banners = [];
|
|
891
|
-
for (const placement of placements) {
|
|
892
|
-
for (const s of placement.sizes) {
|
|
893
|
-
const format = ratioLabel(s.width, s.height);
|
|
894
|
-
if (isBanner(format)) {
|
|
895
|
-
if (s.required) addSize(banners, format, s, placement.id);
|
|
896
|
-
continue;
|
|
897
|
-
}
|
|
898
|
-
addSize(shown, format, s, placement.id);
|
|
899
|
-
if (s.required) addSize(required, format, s, placement.id);
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
return { required, shown, banners };
|
|
903
|
-
}
|
|
904
|
-
function askedSizes(asked, shown, placements) {
|
|
905
|
-
const where = [...new Set(placements.map((p) => AD_PLATFORM_NAMES[p.platform]))].join(" or ") || "No placement named";
|
|
906
|
-
const formats = [];
|
|
907
|
-
const refused = [];
|
|
908
|
-
for (const format of new Set(asked.map((f) => f.trim()))) {
|
|
909
|
-
const found = shown.find((f) => f.format === format);
|
|
910
|
-
if (found) formats.push(found);
|
|
911
|
-
else refused.push({ format, why: `${where} shows no ${format} picture` });
|
|
912
|
-
}
|
|
913
|
-
return { formats, refused };
|
|
914
|
-
}
|
|
915
|
-
var isBanner = (format) => format.includes("x");
|
|
916
|
-
var ratioSized = (p) => p.sizes.some((s) => s.required && !isBanner(ratioLabel(s.width, s.height)));
|
|
917
|
-
function verticalCover(placementIds) {
|
|
918
|
-
const covering = AD_PLACEMENTS.filter((p) => placementIds.includes(p.id) && p.cover);
|
|
919
|
-
if (covering.length === 0) return null;
|
|
920
|
-
const max = (pick) => Math.max(...covering.map((p) => pick(p) ?? 0));
|
|
921
|
-
const rails = covering.filter((p) => p.cover?.rail);
|
|
922
|
-
const margins = covering.filter((p) => p.railMargin);
|
|
923
|
-
return {
|
|
924
|
-
top: max((p) => p.cover?.top),
|
|
925
|
-
bottom: max((p) => p.cover?.bottom),
|
|
926
|
-
...rails.length > 0 ? {
|
|
927
|
-
rail: {
|
|
928
|
-
width: max((p) => p.cover?.rail?.width),
|
|
929
|
-
from: Math.min(...rails.map((p) => p.cover?.rail?.from ?? 1))
|
|
930
|
-
}
|
|
931
|
-
} : {},
|
|
932
|
-
...margins.length > 0 ? {
|
|
933
|
-
railMargin: {
|
|
934
|
-
width: max((p) => p.railMargin?.width),
|
|
935
|
-
from: Math.min(...margins.map((p) => p.railMargin?.from ?? 1))
|
|
936
|
-
}
|
|
937
|
-
} : {},
|
|
938
|
-
safe: {
|
|
939
|
-
top: max((p) => p.safe.top),
|
|
940
|
-
bottom: max((p) => p.safe.bottom),
|
|
941
|
-
left: max((p) => p.safe.left),
|
|
942
|
-
right: max((p) => p.safe.right)
|
|
943
|
-
}
|
|
944
|
-
};
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
// ../canvas-contract/src/adRead.ts
|
|
948
|
-
var AD_DESCRIBE_FOCUS = "FIRST, WHY THIS AD WINS, in layers, in `why_it_wins` { disguise (what it pretends to be: a note, a tweet, a newspaper, a chat, a plain ad), voice (who speaks, and how), trigger (the emotion or need it pulls: a free gift, a hidden loss, status, curiosity), attention (what stops the scroll), logic (why it convinces: reciprocity, social proof, a comparison, a price anchor) }, one short phrase each; and in `load_bearing` the 1-4 elements it stops working without (never decoration), each { element, needs: what it takes to carry it } (a free gift, a real peer's face, priced tiers, a native disguise). THEN the LAYOUT: the column/row grid, which region holds what (describe each by what fills it and where it sits, never by percentages or pixel figures), any panel splits, and for EVERY text block its string verbatim, its size relative to the other text (x_large | large | medium | small), weight, case, colour in words, and placement, including small bottom-corner fine print, and whether it is lettered on something in the scene (`surface`). Also: the EXPRESSION and emotion of every person/animal (capture exaggerated or AI-edited faces), the ad_intent, logos by brand, and all visible text verbatim. The TYPOGRAPHY as a first-class identity signal: for EVERY distinct typeface record a `fonts` entry (which text blocks use it, its classification, a best-guess family or close lookalike, its weight/case/styling), and whether the advertiser's LOGO appears in more than one lockup (a square/icon MARK and a horizontal WORDMARK are two assets: capture BOTH). Capture as a photographer would describe it in words (phone or studio, the height and angle, the light and its direction), never as lens or exposure figures. CRITICAL: name the MECHANISM, the one device that makes THIS ad work on a stranger rather than a generic ad (VERBAL: a rhyme, pun, repetition, antithesis; VISUAL: an unexpected crop or scale, a visual gag, a before/after or comparison, bold negative space; STRUCTURAL: an unusual hook, order or reveal). Record every device in `winning_mechanisms` as { kind: verbal|visual|structural, device, why_it_works } and the strongest one in `mechanism`. And read WHO the ad is for, in `audience`: the viewer it speaks to, their awareness stage, how warm they must already be, and whether the copy only works if they already know this brand or offer (`presumes_brand_knowledge`), so a rebuild for a different audience knows what to change";
|
|
949
|
-
var AD_SELECT_SYSTEM = 'You identify the MAIN, identity-critical visual elements of an advertisement from its JSON blueprint \u2014 the things a faithful reproduction must supply as REAL reference images instead of letting a model invent them. Output ONLY a JSON object of the form { "elements": [ ... ] }, no prose.';
|
|
950
|
-
var AD_SELECT_PROMPT = `AD BLUEPRINT (from image_describe):
|
|
951
|
-
{{blueprint}}
|
|
952
|
-
|
|
953
|
-
From this blueprint, list ONLY the elements that are prominent, important, and identity-bearing \u2014 the ones a reproduction must ground in a real asset:
|
|
954
|
-
- the brand logo/wordmark (from brands_logos with function_in_image = advertiser_brand) -> type "logo". A brand often ships its logo in TWO lockups \u2014 a square/icon MARK and a horizontal WORDMARK \u2014 and an ad may use both (e.g. an icon in a product mock plus the wordmark in the sign-off). When more than one distinct lockup of the SAME advertiser appears, emit a SEPARATE logo element for each (label them by lockup, e.g. LOGO_MARK and LOGO_WORDMARK) so the reproduction can drop the right file in each slot instead of stretching one logo to cover both.
|
|
955
|
-
- trust/rating/certification/app-store/review badges (brands_logos with function_in_image = trust_badge | review_platform | certification_or_seal | app_store_badge | payment_method) -> type "badge"
|
|
956
|
-
- a showcased/hero product or package (a foreground entry in subjects that the ad is selling) -> type "product"
|
|
957
|
-
- a foreground person (from people) \u2014 keep it when its identity matters OR it is the emotional/hero focal point of the ad, even a generic one with no brand identity -> type "person". Describe them as a castable, invented everyday person (age band, look, wardrobe, expression) \u2014 never the source person's identity: unless a company avatar is cast, the render draws this person from your words alone
|
|
958
|
-
- a foreground animal/character (from subjects) \u2014 keep it when it carries a specific expression OR it is the emotional/hero focal point, even a generic one -> type "animal"
|
|
959
|
-
(For an animal: a free-generated muzzle or teeth reads as AI and grows artifacts \u2014 malformed mouths, foam \u2014 so the emotional hero needs the STRONGEST real grounding, not the weakest; "it's just a generic dog/person" is never a reason to drop either.)
|
|
960
|
-
|
|
961
|
-
DROP background extras, decorative props, generic scenery, and anything small or incidental. Keep at most ~6. If there are none, return an empty list.
|
|
962
|
-
|
|
963
|
-
For each kept element return: { "type": one of logo|product|person|animal|badge, "label": a short UPPER_SNAKE_CASE name (e.g. LOGO, PRODUCT, HERO_DOG, TRUSTPILOT), "description": a concrete reusable description to source/shoot the real asset (include the exact expression for a living subject, and its castable attributes \u2014 breed/species for an animal, apparent age band, apparent origin/ethnicity, and wardrobe/setting for a person \u2014 so it can be recast to fit OUR audience/market), "expression": the facial expression for a living subject or null, "reason": why it is identity-critical, "locator": the blueprint entry this element came from as { "collection": one of "subjects" | "people" | "brands_logos", "index": its 0-based position in that array } (people -> people; logos/badges -> brands_logos; products/animals/objects -> subjects). Output ONLY the JSON object.`;
|
|
964
|
-
|
|
965
|
-
// ../canvas-contract/src/castName.ts
|
|
966
|
-
function withoutCastName(text, names) {
|
|
967
|
-
let out = text;
|
|
968
|
-
for (const name of names) {
|
|
969
|
-
const token = name.trim();
|
|
970
|
-
if (token.length < 3) continue;
|
|
971
|
-
const pattern = new RegExp(`(?<![\\p{L}\\p{N}])${escapeForPattern(token)}(?![\\p{L}\\p{N}])`, "giu");
|
|
972
|
-
out = out.replace(pattern, "the person in the reference");
|
|
973
|
-
}
|
|
974
|
-
return out;
|
|
975
|
-
}
|
|
976
|
-
function escapeForPattern(value) {
|
|
977
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
// ../canvas-contract/src/adPlatformFormats.ts
|
|
981
|
-
var AD_FORMAT_PLATFORMS = [
|
|
982
|
-
"meta_feed",
|
|
983
|
-
"meta_feed_stories",
|
|
984
|
-
"meta_all",
|
|
985
|
-
"linkedin",
|
|
986
|
-
"google_search",
|
|
987
|
-
"google_demandgen",
|
|
988
|
-
"tiktok",
|
|
989
|
-
"youtube"
|
|
990
|
-
];
|
|
991
|
-
var AD_PLATFORM_FORMAT_PRESETS = {
|
|
992
|
-
meta_feed: { formats: ["4:5"], note: "Meta/Instagram feed static." },
|
|
993
|
-
meta_feed_stories: { formats: ["4:5", "9:16"], note: "Meta feed + Stories/Reels." },
|
|
994
|
-
meta_all: { formats: ["4:5", "9:16", "1:1"], note: "Meta feed + Stories/Reels + square." },
|
|
995
|
-
linkedin: { formats: ["1:1"], note: "LinkedIn single-image feed (square)." },
|
|
996
|
-
google_search: {
|
|
997
|
-
// Search image assets: 1:1 is the required one, 1.91:1 the optional landscape.
|
|
998
|
-
// 16:9 is rendered only as the crop source for that landscape — Search never serves 16:9 itself.
|
|
999
|
-
formats: ["1:1", "16:9"],
|
|
1000
|
-
offGrid: ["1.91:1"],
|
|
1001
|
-
note: "Google Search image assets (the image extension on a text ad); 1:1 required, 1.91:1 landscape \u2014 crop that from the rendered 16:9. Stage 3+ per campaign."
|
|
1002
|
-
},
|
|
1003
|
-
google_demandgen: {
|
|
1004
|
-
// Renders 16:9 too so the off-grid 1.91:1 landscape has a native source to crop from.
|
|
1005
|
-
formats: ["1:1", "4:5", "16:9"],
|
|
1006
|
-
offGrid: ["1.91:1"],
|
|
1007
|
-
note: "Google Demand Gen; also wants 1.91:1 landscape \u2014 crop that from the rendered 16:9."
|
|
1008
|
-
},
|
|
1009
|
-
tiktok: { formats: ["9:16"], note: "TikTok full-screen vertical." },
|
|
1010
|
-
youtube: { formats: ["16:9"], note: "YouTube in-stream / companion display." }
|
|
1011
|
-
};
|
|
1012
|
-
function platformFormats(platform) {
|
|
1013
|
-
return AD_PLATFORM_FORMAT_PRESETS[platform].formats;
|
|
1014
|
-
}
|
|
1015
|
-
function resolveAdaptFormats(params) {
|
|
1016
|
-
if (params.platform) return platformFormats(params.platform);
|
|
1017
|
-
return params.formats ?? [];
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
// ../canvas-contract/src/registry.ts
|
|
1021
|
-
var OPENROUTER_ROUTE = { provider: "openrouter" };
|
|
1022
|
-
var USAGE_BILLED = { kind: "usage" };
|
|
1023
|
-
var MIN_BILLED_SECONDS = 5;
|
|
1024
|
-
var SEEDANCE_FACE_RECOVERY_ROUTE = {
|
|
1025
|
-
provider: "fal",
|
|
1026
|
-
wireModel: "bytedance/seedance-2.5/reference-to-video"
|
|
1027
|
-
};
|
|
1028
|
-
var OPENROUTER_IMAGE_AR = ["1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9"];
|
|
1029
|
-
var OPENROUTER_IMAGE_AR_EXTREME = [...OPENROUTER_IMAGE_AR, "1:4", "4:1", "1:8", "8:1"];
|
|
1030
|
-
var OPENROUTER_IMAGE_AR_GPT = ["1:1", "2:3", "3:2", "3:4", "4:3", "9:16", "16:9", "21:9"];
|
|
1031
|
-
var GPT_IMAGE_PROMPT_MAX = 32e3;
|
|
1032
|
-
var RECRAFT_PROMPT_MAX = 1e4;
|
|
1033
|
-
var SEEDANCE_PROMPT_MAX = 4e3;
|
|
1034
|
-
var KLING_PROMPT_MAX = 2500;
|
|
1035
|
-
var UINT32_MAX = 4294967295;
|
|
1036
|
-
var VEO_SEED_MAX = UINT32_MAX;
|
|
1037
|
-
var GPT_IMAGE_MAX_REFERENCES = 16;
|
|
1038
|
-
var GEMINI_IMAGE_MAX_REFERENCES = 14;
|
|
1039
|
-
var RECRAFT_MAX_REFERENCES = 1;
|
|
1040
|
-
var SEEDANCE_MAX_REFERENCES = 9;
|
|
1041
|
-
var OPENROUTER_IMAGE_SIZE = ["1K", "2K", "4K"];
|
|
1042
|
-
var OPENROUTER_IMAGE_SIZES = ["0.5K", ...OPENROUTER_IMAGE_SIZE];
|
|
1043
|
-
var OPENROUTER_IMAGE_SIZE_EXTENDED = OPENROUTER_IMAGE_SIZES;
|
|
1044
|
-
var GEMINI_LITE_IMAGE_SIZE = ["1K"];
|
|
1045
|
-
var OPENROUTER_IMAGE_QUALITY = ["auto", "low", "medium", "high"];
|
|
1046
|
-
var OPENROUTER_IMAGE_QUALITY_25 = ["auto", "low", "medium", "high", "xhigh", "max"];
|
|
1047
|
-
var OPENROUTER_IMAGE_N = { kind: "number", integer: true, min: 1, max: 10 };
|
|
1048
|
-
var RECRAFT_IMAGE_AR = ["1:1", "4:3", "3:4", "16:9", "9:16"];
|
|
1049
|
-
var SEEDANCE_DURATIONS = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
|
1050
|
-
var SEEDANCE_25_DURATIONS = [
|
|
1051
|
-
4,
|
|
1052
|
-
5,
|
|
1053
|
-
6,
|
|
1054
|
-
7,
|
|
1055
|
-
8,
|
|
1056
|
-
9,
|
|
1057
|
-
10,
|
|
1058
|
-
11,
|
|
1059
|
-
12,
|
|
1060
|
-
13,
|
|
1061
|
-
14,
|
|
1062
|
-
15,
|
|
1063
|
-
16,
|
|
1064
|
-
17,
|
|
1065
|
-
18,
|
|
1066
|
-
19,
|
|
1067
|
-
20,
|
|
1068
|
-
21,
|
|
1069
|
-
22,
|
|
1070
|
-
23,
|
|
1071
|
-
24,
|
|
1072
|
-
25,
|
|
1073
|
-
26,
|
|
1074
|
-
27,
|
|
1075
|
-
28,
|
|
1076
|
-
29,
|
|
1077
|
-
30
|
|
1078
|
-
];
|
|
1079
|
-
var SEEDANCE_25_ASPECT_RATIOS = ["1:1", "3:4", "9:16", "4:3", "16:9", "21:9"];
|
|
1080
|
-
var SEEDANCE_25_RESOLUTIONS = ["480p", "720p"];
|
|
1081
|
-
var SEEDANCE_25_MAX_IMAGE_REFERENCES = 30;
|
|
1082
|
-
var SEEDANCE_25_MAX_VIDEO_REFERENCES = 10;
|
|
1083
|
-
var SEEDANCE_25_MAX_AUDIO_REFERENCES = 10;
|
|
1084
|
-
var KLING_DURATIONS = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
|
1085
|
-
var GEMINI_OMNI_DURATIONS = [3, 4, 5, 6, 7, 8, 9, 10];
|
|
1086
|
-
var GEMINI_OMNI_ASPECT_RATIOS = ["16:9", "9:16"];
|
|
1087
|
-
var GEMINI_OMNI_RESOLUTIONS = ["360p", "720p", "1080p", "4k"];
|
|
1088
|
-
var GEMINI_OMNI_IMAGE_MIMES = ["image/png", "image/jpeg", "image/webp"];
|
|
1089
|
-
var GROK_IMAGINE_DURATIONS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
1090
|
-
var WAN_27_DURATIONS = [2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
1091
|
-
var HAPPYHORSE_DURATIONS = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
|
1092
|
-
var WAN_30_DURATIONS = [
|
|
1093
|
-
2,
|
|
1094
|
-
3,
|
|
1095
|
-
4,
|
|
1096
|
-
5,
|
|
1097
|
-
6,
|
|
1098
|
-
7,
|
|
1099
|
-
8,
|
|
1100
|
-
9,
|
|
1101
|
-
10,
|
|
1102
|
-
11,
|
|
1103
|
-
12,
|
|
1104
|
-
13,
|
|
1105
|
-
14,
|
|
1106
|
-
15,
|
|
1107
|
-
16,
|
|
1108
|
-
17,
|
|
1109
|
-
18,
|
|
1110
|
-
19,
|
|
1111
|
-
20,
|
|
1112
|
-
21,
|
|
1113
|
-
22,
|
|
1114
|
-
23,
|
|
1115
|
-
24,
|
|
1116
|
-
25,
|
|
1117
|
-
26,
|
|
1118
|
-
27,
|
|
1119
|
-
28,
|
|
1120
|
-
29,
|
|
1121
|
-
30
|
|
1122
|
-
];
|
|
1123
|
-
var GROK_IMAGINE_15_DURATIONS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
|
1124
|
-
var RUNWAY_45_DURATIONS = [2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
1125
|
-
var ELEVENLABS_OUTPUT_FORMATS = [
|
|
1126
|
-
"mp3_22050_32",
|
|
1127
|
-
"mp3_44100_32",
|
|
1128
|
-
"mp3_44100_64",
|
|
1129
|
-
"mp3_44100_96",
|
|
1130
|
-
"mp3_44100_128",
|
|
1131
|
-
"mp3_44100_192"
|
|
1132
|
-
];
|
|
1133
|
-
var ELEVENLABS_MAX_TEXT_CHARS = 45454;
|
|
1134
|
-
var ELEVENLABS_MAX_MUSIC_LENGTH_MS = 454545;
|
|
1135
|
-
var ELEVENLABS_MUSIC_ENGINE = "music_v2";
|
|
1136
|
-
var OPENROUTER_IMAGE_MIMES = ["image/png", "image/jpeg", "image/webp", "image/gif"];
|
|
1137
|
-
var OPENROUTER_VIDEO_REFERENCE_MIMES = ["video/mp4", "video/quicktime", "video/webm"];
|
|
1138
|
-
var OPENROUTER_AUDIO_REFERENCE_MIMES = ["audio/mpeg", "audio/mp3", "audio/wav"];
|
|
1139
|
-
var REPLICATE_IMAGE_MIMES = ["image/png", "image/jpeg", "image/webp"];
|
|
1140
|
-
var REPLICATE_VIDEO_MIMES = ["video/mp4", "video/webm", "video/quicktime"];
|
|
1141
|
-
var DECONSTRUCT_VIDEO_MIMES = ["video/mp4", "video/webm", "video/quicktime"];
|
|
1142
|
-
var REPLICATE_AUDIO_MIMES = ["audio/wav", "audio/mpeg", "audio/mp3"];
|
|
1143
|
-
var IMAGE_GENERATE_MODELS = [
|
|
1144
|
-
"openai/gpt-image-2.5-sunburst",
|
|
1145
|
-
"openai/gpt-image-2",
|
|
1146
|
-
"google/gemini-3.1-flash-image",
|
|
1147
|
-
"google/gemini-3.1-flash-lite-image",
|
|
1148
|
-
"google/gemini-3-pro-image",
|
|
1149
|
-
"recraft/recraft-v4.1-pro-vector"
|
|
1150
|
-
];
|
|
1151
|
-
var DEFAULT_IMAGE_GENERATE_MODEL = "google/gemini-3.1-flash-image";
|
|
1152
|
-
var IMAGE_PRICE_TIER = {
|
|
1153
|
-
"openai/gpt-image-2.5-sunburst": "standard",
|
|
1154
|
-
"openai/gpt-image-2": "standard",
|
|
1155
|
-
"google/gemini-3.1-flash-image": "standard",
|
|
1156
|
-
"google/gemini-3.1-flash-lite-image": "standard",
|
|
1157
|
-
"google/gemini-3-pro-image": "pro",
|
|
1158
|
-
"recraft/recraft-v4.1-pro-vector": "standard"
|
|
1159
|
-
};
|
|
1160
|
-
var IMAGE_TIER_CREDITS = { pro: 20, standard: 5 };
|
|
1161
|
-
function imagePictureCredits(model) {
|
|
1162
|
-
const tier = IMAGE_PRICE_TIER[canonicalModelId(model)] ?? "standard";
|
|
1163
|
-
return IMAGE_TIER_CREDITS[tier];
|
|
1164
|
-
}
|
|
1165
|
-
var VIDEO_GENERATE_MODELS = [
|
|
1166
|
-
"bytedance/seedance-2.0",
|
|
1167
|
-
"bytedance/seedance-2.5",
|
|
1168
|
-
"google/gemini-omni-1.1-flash",
|
|
1169
|
-
"google/gemini-omni-flash",
|
|
1170
|
-
"google/veo-3.1",
|
|
1171
|
-
"google/veo-3.1-fast",
|
|
1172
|
-
"google/veo-3.1-lite",
|
|
1173
|
-
"kwaivgi/kling-v3.0-pro",
|
|
1174
|
-
"x-ai/grok-imagine-video",
|
|
1175
|
-
"x-ai/grok-imagine-video-1.5",
|
|
1176
|
-
"alibaba/wan-2.7",
|
|
1177
|
-
"alibaba/wan-3.0",
|
|
1178
|
-
"runway/gen-4.5",
|
|
1179
|
-
"alibaba/happyhorse-1.1"
|
|
1180
|
-
];
|
|
1181
|
-
var DEFAULT_VIDEO_GENERATE_MODEL = "google/gemini-omni-1.1-flash";
|
|
1182
|
-
var REFERENCE_TO_VIDEO_MODELS = [
|
|
1183
|
-
"bytedance/seedance-2.0",
|
|
1184
|
-
"bytedance/seedance-2.5",
|
|
1185
|
-
"google/gemini-omni-1.1-flash",
|
|
1186
|
-
"google/gemini-omni-flash",
|
|
1187
|
-
"x-ai/grok-imagine-video",
|
|
1188
|
-
"alibaba/wan-2.7",
|
|
1189
|
-
"alibaba/happyhorse-1.1"
|
|
1190
|
-
];
|
|
1191
|
-
function supportsReferenceToVideo(model) {
|
|
1192
|
-
return REFERENCE_TO_VIDEO_MODELS.includes(model);
|
|
1193
|
-
}
|
|
1194
|
-
var DEFAULT_AVATAR_VIDEO_MODEL = "x-ai/grok-imagine-video";
|
|
1195
|
-
function isGeminiOmniModel(model) {
|
|
1196
|
-
return model.startsWith("google/gemini-omni");
|
|
1197
|
-
}
|
|
1198
|
-
var GEMINI_OMNI_PREVIEW_MODEL = "google/gemini-omni-flash";
|
|
1199
|
-
function isGeminiOmniPreviewModel(model) {
|
|
1200
|
-
return model === GEMINI_OMNI_PREVIEW_MODEL;
|
|
1201
|
-
}
|
|
1202
|
-
function isSeedance25Model(model) {
|
|
1203
|
-
return model === "bytedance/seedance-2.5";
|
|
1204
|
-
}
|
|
1205
|
-
var LAST_FRAME_TO_VIDEO_MODELS = [
|
|
1206
|
-
"bytedance/seedance-2.0",
|
|
1207
|
-
"bytedance/seedance-2.5",
|
|
1208
|
-
"google/veo-3.1",
|
|
1209
|
-
"google/veo-3.1-fast",
|
|
1210
|
-
"kwaivgi/kling-v3.0-pro"
|
|
1211
|
-
];
|
|
1212
|
-
function supportsLastFrame(model) {
|
|
1213
|
-
return LAST_FRAME_TO_VIDEO_MODELS.includes(model);
|
|
1214
|
-
}
|
|
1215
|
-
var MODEL_REGISTRY = {
|
|
1216
|
-
text_generate: {
|
|
1217
|
-
"~google/gemini-flash-latest": {
|
|
1218
|
-
label: "Google Gemini Flash (latest)",
|
|
1219
|
-
route: OPENROUTER_ROUTE,
|
|
1220
|
-
billing: USAGE_BILLED,
|
|
1221
|
-
inputs: [],
|
|
1222
|
-
required: ["prompt"],
|
|
1223
|
-
params: {
|
|
1224
|
-
prompt: { kind: "string" },
|
|
1225
|
-
system: { kind: "string" },
|
|
1226
|
-
response_format: { kind: "string", enum: ["text", "json_object"] },
|
|
1227
|
-
web_search: { kind: "boolean" },
|
|
1228
|
-
temperature: { kind: "number", min: 0, max: 2 },
|
|
1229
|
-
max_tokens: { kind: "number", min: 1 }
|
|
1230
|
-
}
|
|
1231
|
-
},
|
|
1232
|
-
"~google/gemini-pro-latest": {
|
|
1233
|
-
label: "Google Gemini Pro (latest)",
|
|
1234
|
-
route: OPENROUTER_ROUTE,
|
|
1235
|
-
billing: USAGE_BILLED,
|
|
1236
|
-
inputs: [],
|
|
1237
|
-
required: ["prompt"],
|
|
1238
|
-
params: {
|
|
1239
|
-
prompt: { kind: "string" },
|
|
1240
|
-
system: { kind: "string" },
|
|
1241
|
-
response_format: { kind: "string", enum: ["text", "json_object"] },
|
|
1242
|
-
web_search: { kind: "boolean" },
|
|
1243
|
-
temperature: { kind: "number", min: 0, max: 2 },
|
|
1244
|
-
max_tokens: { kind: "number", min: 1 }
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
},
|
|
1248
|
-
image_describe: {
|
|
1249
|
-
// Vision extraction — the Visual Architect system prompt lives on the
|
|
1250
|
-
// backend, so there is no `prompt` param; `focus` appends emphasis only.
|
|
1251
|
-
"~google/gemini-pro-latest": {
|
|
1252
|
-
label: "Google Gemini Pro (latest, Vision)",
|
|
1253
|
-
route: OPENROUTER_ROUTE,
|
|
1254
|
-
billing: USAGE_BILLED,
|
|
1255
|
-
inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1256
|
-
required: [],
|
|
1257
|
-
params: {
|
|
1258
|
-
focus: { kind: "string" },
|
|
1259
|
-
context: { kind: "string" },
|
|
1260
|
-
temperature: { kind: "number", min: 0, max: 2 },
|
|
1261
|
-
max_tokens: { kind: "number", min: 1 }
|
|
1262
|
-
}
|
|
1263
|
-
},
|
|
1264
|
-
"~google/gemini-flash-latest": {
|
|
1265
|
-
label: "Google Gemini Flash (latest, Vision)",
|
|
1266
|
-
route: OPENROUTER_ROUTE,
|
|
1267
|
-
billing: USAGE_BILLED,
|
|
1268
|
-
inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1269
|
-
required: [],
|
|
1270
|
-
params: {
|
|
1271
|
-
focus: { kind: "string" },
|
|
1272
|
-
context: { kind: "string" },
|
|
1273
|
-
temperature: { kind: "number", min: 0, max: 2 },
|
|
1274
|
-
max_tokens: { kind: "number", min: 1 }
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
},
|
|
1278
|
-
image_select: {
|
|
1279
|
-
// Vision judgement — the selection contract (numbered images, JSON
|
|
1280
|
-
// response) is baked into the backend prompt; `prompt` carries only the
|
|
1281
|
-
// selection criteria. `count` has an engine-side default of 1, so it is
|
|
1282
|
-
// not registry-required.
|
|
1283
|
-
"~google/gemini-flash-latest": {
|
|
1284
|
-
label: "Google Gemini Flash (latest, Vision)",
|
|
1285
|
-
route: OPENROUTER_ROUTE,
|
|
1286
|
-
billing: USAGE_BILLED,
|
|
1287
|
-
inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1288
|
-
required: ["prompt"],
|
|
1289
|
-
params: {
|
|
1290
|
-
prompt: { kind: "string" },
|
|
1291
|
-
count: { kind: "number", min: 1 },
|
|
1292
|
-
temperature: { kind: "number", min: 0, max: 2 },
|
|
1293
|
-
max_tokens: { kind: "number", min: 1 }
|
|
1294
|
-
}
|
|
1295
|
-
},
|
|
1296
|
-
"~google/gemini-pro-latest": {
|
|
1297
|
-
label: "Google Gemini Pro (latest, Vision)",
|
|
1298
|
-
route: OPENROUTER_ROUTE,
|
|
1299
|
-
billing: USAGE_BILLED,
|
|
1300
|
-
inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1301
|
-
required: ["prompt"],
|
|
1302
|
-
params: {
|
|
1303
|
-
prompt: { kind: "string" },
|
|
1304
|
-
count: { kind: "number", min: 1 },
|
|
1305
|
-
temperature: { kind: "number", min: 0, max: 2 },
|
|
1306
|
-
max_tokens: { kind: "number", min: 1 }
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
},
|
|
1310
|
-
image_generate: {
|
|
1311
|
-
// `seed` is omitted on every entry — OpenRouter's `image_config` schema
|
|
1312
|
-
// has no `seed` slot for image-gen (different from video-gen), so passing
|
|
1313
|
-
// it would be a silent no-op.
|
|
1314
|
-
// The direct image model, not the `gpt-5.4-image-2` chat model that emitted
|
|
1315
|
-
// images as a side effect. Notable capability gaps vs the Gemini entries:
|
|
1316
|
-
// no `image_size` (OpenAI picks the pixel dimensions from the ratio, and a
|
|
1317
|
-
// `resolution` is silently ignored) and the narrower `..._AR_GPT` ratio set.
|
|
1318
|
-
"openai/gpt-image-2.5-sunburst": {
|
|
1319
|
-
// Identical to the gpt-image-2 entry below except for the quality ladder and `n`
|
|
1320
|
-
// (several images from one call) — the ratio set, the 16-reference ceiling, the missing `image_size` and the reasons
|
|
1321
|
-
// `background` / `output_compression` stay undeclared all carry over unchanged.
|
|
1322
|
-
label: "OpenAI GPT Image 2.5",
|
|
1323
|
-
route: OPENROUTER_ROUTE,
|
|
1324
|
-
billing: USAGE_BILLED,
|
|
1325
|
-
inputs: [],
|
|
1326
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES, max: GPT_IMAGE_MAX_REFERENCES }],
|
|
1327
|
-
required: ["prompt"],
|
|
1328
|
-
params: {
|
|
1329
|
-
prompt: { kind: "string", maxLength: GPT_IMAGE_PROMPT_MAX },
|
|
1330
|
-
aspect_ratio: { kind: "string", enum: OPENROUTER_IMAGE_AR_GPT },
|
|
1331
|
-
quality: { kind: "string", enum: OPENROUTER_IMAGE_QUALITY_25 },
|
|
1332
|
-
n: OPENROUTER_IMAGE_N
|
|
1333
|
-
}
|
|
1334
|
-
},
|
|
1335
|
-
"openai/gpt-image-2": {
|
|
1336
|
-
// Its live endpoint also advertises `background` (auto|opaque) and
|
|
1337
|
-
// `output_compression` (0-100), which we deliberately do not declare. Not an
|
|
1338
|
-
// oversight: a registry param is a promise the whole system keeps — the
|
|
1339
|
-
// canvas node schema, the dashboard control, the CLI flag and the cost model
|
|
1340
|
-
// all have to carry it — and neither knob changes what the picture IS.
|
|
1341
|
-
// Declaring them would widen four surfaces to expose a file-size dial.
|
|
1342
|
-
label: "OpenAI GPT Image 2",
|
|
1343
|
-
route: OPENROUTER_ROUTE,
|
|
1344
|
-
billing: USAGE_BILLED,
|
|
1345
|
-
inputs: [],
|
|
1346
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES, max: GPT_IMAGE_MAX_REFERENCES }],
|
|
1347
|
-
required: ["prompt"],
|
|
1348
|
-
params: {
|
|
1349
|
-
prompt: { kind: "string", maxLength: GPT_IMAGE_PROMPT_MAX },
|
|
1350
|
-
aspect_ratio: { kind: "string", enum: OPENROUTER_IMAGE_AR_GPT },
|
|
1351
|
-
quality: { kind: "string", enum: OPENROUTER_IMAGE_QUALITY }
|
|
1352
|
-
}
|
|
1353
|
-
},
|
|
1354
|
-
// The GA Nano Banana ids (2026-06-18). Same surface as the preview ids they replace
|
|
1355
|
-
// — read off GET /api/v1/images/models/google/gemini-3.1-flash-image/endpoints and
|
|
1356
|
-
// .../gemini-3-pro-image/endpoints — which is why those ids are plain aliases of
|
|
1357
|
-
// these (`MODEL_ALIASES`): a canvas moves between them unchanged.
|
|
1358
|
-
"google/gemini-3.1-flash-image": {
|
|
1359
|
-
label: "Google Gemini 3.1 Flash Image (Nano Banana 2)",
|
|
1360
|
-
route: OPENROUTER_ROUTE,
|
|
1361
|
-
billing: USAGE_BILLED,
|
|
1362
|
-
inputs: [],
|
|
1363
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES, max: GEMINI_IMAGE_MAX_REFERENCES }],
|
|
1364
|
-
required: ["prompt"],
|
|
1365
|
-
params: {
|
|
1366
|
-
prompt: { kind: "string" },
|
|
1367
|
-
aspect_ratio: { kind: "string", enum: OPENROUTER_IMAGE_AR_EXTREME },
|
|
1368
|
-
image_size: { kind: "string", enum: OPENROUTER_IMAGE_SIZE_EXTENDED }
|
|
1369
|
-
}
|
|
1370
|
-
},
|
|
1371
|
-
"google/gemini-3-pro-image": {
|
|
1372
|
-
label: "Google Gemini 3 Pro Image (Nano Banana Pro)",
|
|
1373
|
-
route: OPENROUTER_ROUTE,
|
|
1374
|
-
billing: USAGE_BILLED,
|
|
1375
|
-
inputs: [],
|
|
1376
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES, max: GEMINI_IMAGE_MAX_REFERENCES }],
|
|
1377
|
-
required: ["prompt"],
|
|
1378
|
-
params: {
|
|
1379
|
-
prompt: { kind: "string" },
|
|
1380
|
-
aspect_ratio: { kind: "string", enum: OPENROUTER_IMAGE_AR },
|
|
1381
|
-
image_size: { kind: "string", enum: OPENROUTER_IMAGE_SIZE }
|
|
1382
|
-
// No `quality`: OpenRouter's per-endpoint schema lists it for gpt-image and for
|
|
1383
|
-
// NO Gemini image model, pro included. It is accepted-then-dropped, so declaring
|
|
1384
|
-
// it invites the scaffolder to emit a param that does nothing.
|
|
1385
|
-
}
|
|
1386
|
-
},
|
|
1387
|
-
"google/gemini-3.1-flash-lite-image": {
|
|
1388
|
-
// Nano Banana 2 Lite. Same Gemini image family as the flash tier — same
|
|
1389
|
-
// extreme aspect-ratio set, same reference editing — at HALF the output-token
|
|
1390
|
-
// price ($0.00003 vs $0.00006 per output image token), which makes it the
|
|
1391
|
-
// cheap-iteration tier for image work the way `veo-3.1-fast` is for video.
|
|
1392
|
-
//
|
|
1393
|
-
// The one thing it gives up is resolution: it renders 1K and nothing else.
|
|
1394
|
-
// That is a hard provider 400, not a soft clamp, so it is gated here rather
|
|
1395
|
-
// than discovered at dispatch. A 2K/4K hero frame belongs on the flash or pro
|
|
1396
|
-
// tier. Unlike gpt-image it keeps 4:5 and 5:4, so Meta/Instagram portrait
|
|
1397
|
-
// formats still come straight out of it.
|
|
1398
|
-
//
|
|
1399
|
-
// Reached through the normal OpenRouter image gateway (Google Vertex and
|
|
1400
|
-
// Google AI Studio both serve it) — no direct-provider exception needed.
|
|
1401
|
-
// Source: GET /api/v1/images/models/google/gemini-3.1-flash-lite-image/endpoints.
|
|
1402
|
-
label: "Google Gemini 3.1 Flash Lite Image",
|
|
1403
|
-
route: OPENROUTER_ROUTE,
|
|
1404
|
-
billing: USAGE_BILLED,
|
|
1405
|
-
inputs: [],
|
|
1406
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES, max: GEMINI_IMAGE_MAX_REFERENCES }],
|
|
1407
|
-
required: ["prompt"],
|
|
1408
|
-
params: {
|
|
1409
|
-
prompt: { kind: "string" },
|
|
1410
|
-
aspect_ratio: { kind: "string", enum: OPENROUTER_IMAGE_AR_EXTREME },
|
|
1411
|
-
image_size: { kind: "string", enum: GEMINI_LITE_IMAGE_SIZE }
|
|
1412
|
-
}
|
|
1413
|
-
},
|
|
1414
|
-
"recraft/recraft-v4.1-pro-vector": {
|
|
1415
|
-
// The vector/logo tier, and the odd one out of this roster in three ways.
|
|
1416
|
-
// All three are read off its live endpoint schema, and all three are the
|
|
1417
|
-
// kind of fact that only shows up as a billed 400 if it is guessed:
|
|
1418
|
-
// - it renders FIVE ratios (no 4:5 / 5:4 / 2:3 / 3:2 / 21:9), so portrait
|
|
1419
|
-
// ad shapes snap to 3:4 rather than being sent as-is;
|
|
1420
|
-
// - it has NO resolution knob (`supported_parameters` lists none), so
|
|
1421
|
-
// `image_size` is refused here instead of accepted and ignored;
|
|
1422
|
-
// - it takes exactly ONE reference image, against 14-16 everywhere else.
|
|
1423
|
-
// Its palette levers are real but arrive as provider passthrough
|
|
1424
|
-
// (`controls`), which is why they are `json` rather than typed enums; the
|
|
1425
|
-
// backend adapter builds that block in `buildImageGenBody`.
|
|
1426
|
-
label: "Recraft v4.1 Pro Vector",
|
|
1427
|
-
route: OPENROUTER_ROUTE,
|
|
1428
|
-
billing: USAGE_BILLED,
|
|
1429
|
-
inputs: [],
|
|
1430
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES, max: RECRAFT_MAX_REFERENCES }],
|
|
1431
|
-
required: ["prompt"],
|
|
1432
|
-
params: {
|
|
1433
|
-
prompt: { kind: "string", maxLength: RECRAFT_PROMPT_MAX },
|
|
1434
|
-
aspect_ratio: { kind: "string", enum: RECRAFT_IMAGE_AR },
|
|
1435
|
-
strength: { kind: "number", min: 0, max: 1 },
|
|
1436
|
-
rgb_colors: { kind: "json" },
|
|
1437
|
-
background_rgb_color: { kind: "json" }
|
|
1438
|
-
}
|
|
1439
|
-
}
|
|
1440
|
-
},
|
|
1441
|
-
image_reference_sheet: {
|
|
1442
|
-
// Multi-view subject reference sheets (turnaround grids). The sheet prompt
|
|
1443
|
-
// is baked into the backend handler — params here are semantic levers
|
|
1444
|
-
// only. Both models consume MULTIPLE reference images via the `references`
|
|
1445
|
-
// input slot (required: a sheet without source images is just image_generate).
|
|
1446
|
-
"google/gemini-3-pro-image": {
|
|
1447
|
-
label: "Google Gemini 3 Pro Image (Nano Banana Pro)",
|
|
1448
|
-
route: OPENROUTER_ROUTE,
|
|
1449
|
-
billing: USAGE_BILLED,
|
|
1450
|
-
inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1451
|
-
required: ["subject_description", "subject_type"],
|
|
1452
|
-
params: {
|
|
1453
|
-
subject_description: { kind: "string" },
|
|
1454
|
-
subject_type: { kind: "string", enum: ["character", "person", "product", "location"] },
|
|
1455
|
-
views: { kind: "json" },
|
|
1456
|
-
style: { kind: "string" },
|
|
1457
|
-
prompt_override: { kind: "string" },
|
|
1458
|
-
aspect_ratio: { kind: "string", enum: OPENROUTER_IMAGE_AR },
|
|
1459
|
-
image_size: { kind: "string", enum: OPENROUTER_IMAGE_SIZE }
|
|
1460
|
-
}
|
|
1461
|
-
},
|
|
1462
|
-
"google/gemini-3.1-flash-image": {
|
|
1463
|
-
label: "Google Gemini 3.1 Flash Image (Nano Banana 2)",
|
|
1464
|
-
route: OPENROUTER_ROUTE,
|
|
1465
|
-
billing: USAGE_BILLED,
|
|
1466
|
-
inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1467
|
-
required: ["subject_description", "subject_type"],
|
|
1468
|
-
params: {
|
|
1469
|
-
subject_description: { kind: "string" },
|
|
1470
|
-
subject_type: { kind: "string", enum: ["character", "person", "product", "location"] },
|
|
1471
|
-
views: { kind: "json" },
|
|
1472
|
-
style: { kind: "string" },
|
|
1473
|
-
prompt_override: { kind: "string" },
|
|
1474
|
-
aspect_ratio: { kind: "string", enum: OPENROUTER_IMAGE_AR_EXTREME },
|
|
1475
|
-
image_size: { kind: "string", enum: OPENROUTER_IMAGE_SIZE_EXTENDED }
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1478
|
-
},
|
|
1479
|
-
image_aspect_adapt: {
|
|
1480
|
-
// Multi-format adaptation of one creative. The recomposition prompt is
|
|
1481
|
-
// baked into the backend handler. The target ratios come from EITHER an
|
|
1482
|
-
// explicit `formats` list OR a `platform` preset that expands to the
|
|
1483
|
-
// canonical set; exactly one of the two is required — that "one of" gate,
|
|
1484
|
-
// and per-element ratio validation, live in the node's Zod schema (the
|
|
1485
|
-
// registry can't express "one of" or gate array elements), so `formats`
|
|
1486
|
-
// is not listed as registry-required. The source creative is a required
|
|
1487
|
-
// input slot. `copy` (the exact lines the ad carries) and `safe_areas` (per
|
|
1488
|
-
// format, the fractions each edge's interface covers) are set by the static
|
|
1489
|
-
// scaffold so the reframe keeps every word, once, where the platform shows it.
|
|
1490
|
-
"google/gemini-3-pro-image": {
|
|
1491
|
-
label: "Google Gemini 3 Pro Image (Nano Banana Pro)",
|
|
1492
|
-
route: OPENROUTER_ROUTE,
|
|
1493
|
-
billing: USAGE_BILLED,
|
|
1494
|
-
inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1495
|
-
required: [],
|
|
1496
|
-
params: {
|
|
1497
|
-
formats: { kind: "json" },
|
|
1498
|
-
platform: { kind: "string", enum: AD_FORMAT_PLATFORMS },
|
|
1499
|
-
guidance: { kind: "string" },
|
|
1500
|
-
copy: { kind: "json" },
|
|
1501
|
-
safe_areas: { kind: "json" },
|
|
1502
|
-
image_size: { kind: "string", enum: OPENROUTER_IMAGE_SIZE }
|
|
1503
|
-
}
|
|
1504
|
-
},
|
|
1505
|
-
"google/gemini-3.1-flash-image": {
|
|
1506
|
-
label: "Google Gemini 3.1 Flash Image (Nano Banana 2)",
|
|
1507
|
-
route: OPENROUTER_ROUTE,
|
|
1508
|
-
billing: USAGE_BILLED,
|
|
1509
|
-
inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1510
|
-
required: [],
|
|
1511
|
-
params: {
|
|
1512
|
-
formats: { kind: "json" },
|
|
1513
|
-
platform: { kind: "string", enum: AD_FORMAT_PLATFORMS },
|
|
1514
|
-
guidance: { kind: "string" },
|
|
1515
|
-
copy: { kind: "json" },
|
|
1516
|
-
safe_areas: { kind: "json" },
|
|
1517
|
-
image_size: { kind: "string", enum: OPENROUTER_IMAGE_SIZE_EXTENDED }
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
},
|
|
1521
|
-
video_generate: {
|
|
1522
|
-
"bytedance/seedance-2.0": {
|
|
1523
|
-
// Routed via Replicate's official `bytedance/seedance-2.0` model. NOTE:
|
|
1524
|
-
// ByteDance's upstream likeness filter blocks photoreal human faces on ANY
|
|
1525
|
-
// reseller, and it does NOT care whether the person is real: it classifies
|
|
1526
|
-
// pixels, so an AI-generated face that looks photographic is refused
|
|
1527
|
-
// exactly like a photograph (E005 / content_policy_blocked). Confirmed in
|
|
1528
|
-
// production against faces we generated ourselves. The only escape is Veo
|
|
1529
|
-
// — NOT a synthetic presenter, which an earlier version of this note
|
|
1530
|
-
// wrongly recommended and which sends you round the same loop.
|
|
1531
|
-
label: "ByteDance Seedance 2.0",
|
|
1532
|
-
route: { provider: "replicate" },
|
|
1533
|
-
billing: { kind: "formula", formula: "seedance-2.0" },
|
|
1534
|
-
inputs: [],
|
|
1535
|
-
optional_inputs: [{ kind: "image", mimes: REPLICATE_IMAGE_MIMES, max: SEEDANCE_MAX_REFERENCES }],
|
|
1536
|
-
required: ["prompt"],
|
|
1537
|
-
params: {
|
|
1538
|
-
// Replicate's Seedance wrapper hard-caps the prompt at 4000 chars; gate
|
|
1539
|
-
// it here so an over-length prompt fails validate (free) not the billed call.
|
|
1540
|
-
prompt: { kind: "string", maxLength: SEEDANCE_PROMPT_MAX },
|
|
1541
|
-
aspect_ratio: {
|
|
1542
|
-
kind: "string",
|
|
1543
|
-
enum: ["1:1", "3:4", "9:16", "4:3", "16:9", "21:9", "9:21"]
|
|
1544
|
-
},
|
|
1545
|
-
resolution: { kind: "string", enum: ["480p", "720p", "1080p", "4k"] },
|
|
1546
|
-
duration: { kind: "number", enum: SEEDANCE_DURATIONS },
|
|
1547
|
-
// Replicate types this `integer`, and a fractional seed is a schema
|
|
1548
|
-
// rejection rather than a rounded one. No range is advertised, so none is
|
|
1549
|
-
// invented — see `InputSpec.max` on why absent must stay ungated.
|
|
1550
|
-
seed: { kind: "number", integer: true },
|
|
1551
|
-
generate_audio: { kind: "boolean" }
|
|
1552
|
-
}
|
|
1553
|
-
},
|
|
1554
|
-
"bytedance/seedance-2.5": {
|
|
1555
|
-
// Seedance 2.5 — the LONG-FORM, MULTIMODAL tier, and the only curated video
|
|
1556
|
-
// model reached through OpenRouter that is not frame-only.
|
|
1557
|
-
//
|
|
1558
|
-
// Routed through OpenRouter's video gateway (provider `seed`), NOT through
|
|
1559
|
-
// Replicate like 2.0 — the gateway carries the multimodal reference surface
|
|
1560
|
-
// 2.5 exists for, and Replicate's 2.0 wrapper only has `reference_images`.
|
|
1561
|
-
// The backend branches on the exact 2.0 id for the Replicate path, so this
|
|
1562
|
-
// model must never be folded into a `startsWith("bytedance/seedance")`
|
|
1563
|
-
// routing test: that is one character away from sending 2.5 to a wrapper
|
|
1564
|
-
// that cannot express half of what it is being asked to do.
|
|
1565
|
-
//
|
|
1566
|
-
// Same upstream likeness filter as 2.0 — ByteDance classifies PIXELS, so an
|
|
1567
|
-
// AI-generated face that reads photographic is refused exactly like a
|
|
1568
|
-
// photograph (content_policy_blocked). A reference-guided clip refused that
|
|
1569
|
-
// way is re-rendered on fal, which serves the same model under a licence that
|
|
1570
|
-
// takes faces; a frame-started one is reported, never moved to another model.
|
|
1571
|
-
//
|
|
1572
|
-
// No published prompt cap on this route, so none is invented: OpenRouter's
|
|
1573
|
-
// request schema declares no `maxLength` and the model is sold on long,
|
|
1574
|
-
// multi-shot briefs. A ceiling we made up would refuse the exact prompts
|
|
1575
|
-
// this tier exists to render.
|
|
1576
|
-
label: "ByteDance Seedance 2.5",
|
|
1577
|
-
route: OPENROUTER_ROUTE,
|
|
1578
|
-
billing: { kind: "formula", formula: "seedance-2.5" },
|
|
1579
|
-
recoveryRoute: SEEDANCE_FACE_RECOVERY_ROUTE,
|
|
1580
|
-
inputs: [],
|
|
1581
|
-
optional_inputs: [
|
|
1582
|
-
{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES, max: SEEDANCE_25_MAX_IMAGE_REFERENCES },
|
|
1583
|
-
{ kind: "video", mimes: OPENROUTER_VIDEO_REFERENCE_MIMES, max: SEEDANCE_25_MAX_VIDEO_REFERENCES },
|
|
1584
|
-
{ kind: "audio", mimes: OPENROUTER_AUDIO_REFERENCE_MIMES, max: SEEDANCE_25_MAX_AUDIO_REFERENCES }
|
|
1585
|
-
],
|
|
1586
|
-
required: ["prompt"],
|
|
1587
|
-
params: {
|
|
1588
|
-
prompt: { kind: "string" },
|
|
1589
|
-
aspect_ratio: { kind: "string", enum: SEEDANCE_25_ASPECT_RATIOS },
|
|
1590
|
-
resolution: { kind: "string", enum: SEEDANCE_25_RESOLUTIONS },
|
|
1591
|
-
duration: { kind: "number", enum: SEEDANCE_25_DURATIONS },
|
|
1592
|
-
seed: { kind: "number", integer: true, min: 0, max: UINT32_MAX },
|
|
1593
|
-
generate_audio: { kind: "boolean" },
|
|
1594
|
-
// A visible AI watermark on an ad creative is a defect, and this is the
|
|
1595
|
-
// only curated model that lets us turn one off: `watermark` is named in
|
|
1596
|
-
// the model's own `allowed_passthrough_parameters`, so it rides as a
|
|
1597
|
-
// top-level body field exactly like Kling's `cfg_scale` does.
|
|
1598
|
-
watermark: { kind: "boolean" }
|
|
1599
|
-
}
|
|
1600
|
-
},
|
|
1601
|
-
"google/gemini-omni-1.1-flash": {
|
|
1602
|
-
// Google Gemini Omni 1.1 Flash — the DEFAULT video model. Natively
|
|
1603
|
-
// multimodal: it reasons over text + images and renders video WITH
|
|
1604
|
-
// synchronized audio in one call, and it is the only curated model that
|
|
1605
|
-
// takes reference images through its own first-party API (task
|
|
1606
|
-
// `reference_to_video`).
|
|
1607
|
-
//
|
|
1608
|
-
// It is a SEPARATE entry from `google/gemini-omni-flash` (the preview),
|
|
1609
|
-
// not a rolling upgrade of it, because the two do not render the same
|
|
1610
|
-
// things: 1.1 takes a `resolution` and the preview does not, and 1.1 bills
|
|
1611
|
-
// the seconds it renders where the preview bills its whole 10s window. One
|
|
1612
|
-
// shared key would have to promise the union of those, which means a canvas
|
|
1613
|
-
// could ask the preview for 360p and be quoted a third of what it charges.
|
|
1614
|
-
//
|
|
1615
|
-
// NOT on OpenRouter. `GET /api/v1/videos/models` lists 17 video models and
|
|
1616
|
-
// no Gemini Omni at either version, so this is the sanctioned direct-provider
|
|
1617
|
-
// exception (see `convex/lib/geminiOmni.ts`): Google's Interactions API,
|
|
1618
|
-
// `POST /v1beta/interactions`. Its own `generateContent` endpoint refuses it
|
|
1619
|
-
// ("This model only supports Interactions API"), so the Veo `predictLongRunning`
|
|
1620
|
-
// shape does not apply either.
|
|
1621
|
-
//
|
|
1622
|
-
// The param set below is deliberately short and was read off the live API,
|
|
1623
|
-
// not off the docs — the knobs absent here are rejected with a pre-dispatch
|
|
1624
|
-
// 400 (`Unknown parameter '<name>'`): no `seed`, no `negative_prompt`, no
|
|
1625
|
-
// `generate_audio`, no `person_generation` / `enhance_prompt` /
|
|
1626
|
-
// `conditioning_scale`. Audio is always on and cannot be turned off.
|
|
1627
|
-
// Widening this list does not widen the model; it just moves a free
|
|
1628
|
-
// validation error into a billed one.
|
|
1629
|
-
//
|
|
1630
|
-
// `duration` is the odd one out: Omni has no duration FIELD at any nesting
|
|
1631
|
-
// level, but it honours a length named in the prompt (3-10s), so the adapter
|
|
1632
|
-
// turns this param into a prompt directive. It is a real, billable knob.
|
|
1633
|
-
//
|
|
1634
|
-
// NO VIDEO INPUT SLOT, and that is a gate on our project rather than a gap
|
|
1635
|
-
// in the model or a mistake in how we ask. 1.1 advertises video references,
|
|
1636
|
-
// `edit` and `extend`, and every request carrying a video comes back 400
|
|
1637
|
-
// `content_blocked`.
|
|
1638
|
-
//
|
|
1639
|
-
// The controlled version, run through the shape Google's own docs use
|
|
1640
|
-
// (`{"type":"document","uri":<Files API uri>}`, no generation_config),
|
|
1641
|
-
// changing only the uploaded file: an IMAGE returns 200 and renders a clip;
|
|
1642
|
-
// a VIDEO returns `content_blocked`. Same route, same structure. So the
|
|
1643
|
-
// request shape is right and video input specifically is refused. Also
|
|
1644
|
-
// measured across inline base64, all three tasks, video AND text output,
|
|
1645
|
-
// synthetic clips, Omni's own output, real camera footage, and both our
|
|
1646
|
-
// keys. Full probe log: `.context/omni-1.1-measurements.md`.
|
|
1647
|
-
//
|
|
1648
|
-
// Adding `{ kind: "video", mimes: … }` below is the ONE line that turns the
|
|
1649
|
-
// whole feature on — the "Build on" control, the reference picker taking an
|
|
1650
|
-
// MP4, the drop target and the source-clip cost premium are all driven off
|
|
1651
|
-
// this slot. Add it the day the 400 stops, not before: until then it offers
|
|
1652
|
-
// a control whose every use is refused.
|
|
1653
|
-
label: "Google Gemini Omni 1.1 Flash",
|
|
1654
|
-
route: { provider: "google-interactions", wireModel: "gemini-omni-1.1-flash" },
|
|
1655
|
-
billing: { kind: "formula", formula: "gemini-omni" },
|
|
1656
|
-
inputs: [],
|
|
1657
|
-
optional_inputs: [{ kind: "image", mimes: GEMINI_OMNI_IMAGE_MIMES }],
|
|
1658
|
-
required: ["prompt"],
|
|
1659
|
-
params: {
|
|
1660
|
-
prompt: { kind: "string" },
|
|
1661
|
-
aspect_ratio: { kind: "string", enum: GEMINI_OMNI_ASPECT_RATIOS },
|
|
1662
|
-
resolution: { kind: "string", enum: GEMINI_OMNI_RESOLUTIONS },
|
|
1663
|
-
duration: { kind: "number", enum: GEMINI_OMNI_DURATIONS }
|
|
1664
|
-
}
|
|
1665
|
-
},
|
|
1666
|
-
"google/gemini-omni-flash": {
|
|
1667
|
-
// LEGACY — the Omni PREVIEW (`gemini-omni-flash-preview`), superseded by
|
|
1668
|
-
// `google/gemini-omni-1.1-flash` above. Kept so canvases authored before 1.1
|
|
1669
|
-
// still validate and re-run unchanged (`baker canvas run --slug` restores a
|
|
1670
|
-
// recorded canvas verbatim, so dropping this model would break every stored
|
|
1671
|
-
// creative that used it). Don't reach for it in new work.
|
|
1672
|
-
//
|
|
1673
|
-
// Its param surface is the ORIGINAL one on purpose, and the omission that
|
|
1674
|
-
// matters is `resolution`. This model renders 720p / 24fps and nothing else.
|
|
1675
|
-
//
|
|
1676
|
-
// It does NOT reject the field, which is the trap and the reason this is
|
|
1677
|
-
// enforced here rather than left to the provider: asked for `360p` it
|
|
1678
|
-
// returns HTTP 200, a 1280x720 clip, and a bill of 17,376 video tokens —
|
|
1679
|
-
// the 720p rate, three times the 5,793 that tier costs on 1.1. Accepted,
|
|
1680
|
-
// ignored, and charged for. Copying 1.1's enum across to make the two
|
|
1681
|
-
// entries match would hand a canvas a quality dial that does nothing and a
|
|
1682
|
-
// quote a third of the real charge.
|
|
1683
|
-
label: "Google Gemini Omni Flash (legacy preview)",
|
|
1684
|
-
route: { provider: "google-interactions", wireModel: "gemini-omni-flash-preview" },
|
|
1685
|
-
billing: { kind: "formula", formula: "gemini-omni" },
|
|
1686
|
-
inputs: [],
|
|
1687
|
-
optional_inputs: [{ kind: "image", mimes: GEMINI_OMNI_IMAGE_MIMES }],
|
|
1688
|
-
required: ["prompt"],
|
|
1689
|
-
params: {
|
|
1690
|
-
prompt: { kind: "string" },
|
|
1691
|
-
aspect_ratio: { kind: "string", enum: GEMINI_OMNI_ASPECT_RATIOS },
|
|
1692
|
-
duration: { kind: "number", enum: GEMINI_OMNI_DURATIONS }
|
|
1693
|
-
}
|
|
1694
|
-
},
|
|
1695
|
-
"google/veo-3.1": {
|
|
1696
|
-
// Photoreal CINE CEILING + the real-face fallback (Veo generates adult
|
|
1697
|
-
// humans from a keyframe, dodging ByteDance's real-person filter). Same
|
|
1698
|
-
// OpenRouter google-vertex routing as the fast tier; the quality dial is
|
|
1699
|
-
// `resolution: 1080p` + `generate_audio` + a real `negative_prompt`, not a
|
|
1700
|
-
// separate provider knob. Reach for this for hero beats and any clip that
|
|
1701
|
-
// must carry a real human likeness.
|
|
1702
|
-
label: "Google Veo 3.1",
|
|
1703
|
-
route: OPENROUTER_ROUTE,
|
|
1704
|
-
billing: {
|
|
1705
|
-
kind: "per_second",
|
|
1706
|
-
// Veo prices 4K far above the base tier, and 4K is a selectable resolution,
|
|
1707
|
-
// so folding it into the base rate under-quotes the dearest clip we can make.
|
|
1708
|
-
// A QUOTE only: the charge is the usage OpenRouter reports for the call.
|
|
1709
|
-
usd: { silent: 0.2, audio: 0.4, byResolution: { "4K": { silent: 0.4, audio: 0.6 } } }
|
|
1710
|
-
},
|
|
1711
|
-
inputs: [],
|
|
1712
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1713
|
-
required: ["prompt"],
|
|
1714
|
-
params: {
|
|
1715
|
-
prompt: { kind: "string" },
|
|
1716
|
-
negative_prompt: { kind: "string" },
|
|
1717
|
-
aspect_ratio: { kind: "string", enum: ["16:9", "9:16"] },
|
|
1718
|
-
resolution: { kind: "string", enum: ["720p", "1080p", "4K"] },
|
|
1719
|
-
duration: { kind: "number", enum: [4, 6, 8] },
|
|
1720
|
-
// Vertex declares `seed` a uint32: "accepted range 0-4294967295".
|
|
1721
|
-
seed: { kind: "number", integer: true, min: 0, max: VEO_SEED_MAX },
|
|
1722
|
-
generate_audio: { kind: "boolean" },
|
|
1723
|
-
person_generation: { kind: "string", enum: ["allow_all", "allow_adult"] },
|
|
1724
|
-
enhance_prompt: { kind: "boolean" },
|
|
1725
|
-
conditioning_scale: { kind: "number" }
|
|
1726
|
-
}
|
|
1727
|
-
},
|
|
1728
|
-
"kwaivgi/kling-v3.0-pro": {
|
|
1729
|
-
// Motion-transfer / dynamic multi-shot beats. Reachable through the default
|
|
1730
|
-
// OpenRouter gateway (generic video body — no google-vertex block), so it
|
|
1731
|
-
// needs no direct-provider exception. `cfg_scale` trades prompt adherence
|
|
1732
|
-
// vs motion freedom; higher = closer to prompt.
|
|
1733
|
-
//
|
|
1734
|
-
// Params below are the ones OpenRouter actually advertises for this model
|
|
1735
|
-
// (GET /api/v1/videos/models). Three were wrong before and each was a free
|
|
1736
|
-
// 400 or a silently unsupported knob: it renders 720p ONLY (1080p was
|
|
1737
|
-
// offered and rejected), it takes ANY duration from 3-15s (we allowed just
|
|
1738
|
-
// 5 and 10), and it does not support `seed` at all.
|
|
1739
|
-
label: "Kling 3.0",
|
|
1740
|
-
route: OPENROUTER_ROUTE,
|
|
1741
|
-
billing: {
|
|
1742
|
-
kind: "per_second",
|
|
1743
|
-
// One flat rate across every resolution and mode.
|
|
1744
|
-
usd: { silent: 0.112, audio: 0.168 }
|
|
1745
|
-
},
|
|
1746
|
-
inputs: [],
|
|
1747
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1748
|
-
required: ["prompt"],
|
|
1749
|
-
params: {
|
|
1750
|
-
// Kling caps the prompt shorter than Seedance; gate it here so an
|
|
1751
|
-
// over-length prompt fails validate (free) not the billed call. Its
|
|
1752
|
-
// negative prompt is a SEPARATE 2,500 budget, not a shared one.
|
|
1753
|
-
prompt: { kind: "string", maxLength: KLING_PROMPT_MAX },
|
|
1754
|
-
negative_prompt: { kind: "string", maxLength: KLING_PROMPT_MAX },
|
|
1755
|
-
aspect_ratio: { kind: "string", enum: ["16:9", "9:16", "1:1"] },
|
|
1756
|
-
resolution: { kind: "string", enum: ["720p"] },
|
|
1757
|
-
duration: { kind: "number", enum: KLING_DURATIONS },
|
|
1758
|
-
generate_audio: { kind: "boolean" },
|
|
1759
|
-
cfg_scale: { kind: "number", min: 0, max: 1 }
|
|
1760
|
-
}
|
|
1761
|
-
},
|
|
1762
|
-
"x-ai/grok-imagine-video": {
|
|
1763
|
-
// The avatar workhorse. Measured best of the reference-capable models on
|
|
1764
|
-
// identity retention AND aspect-ratio obedience, at the lowest rate of any
|
|
1765
|
-
// video model we carry ($0.05/s at 480p). No audio at all — `generate_audio`
|
|
1766
|
-
// is absent from its OpenRouter listing, so a talking head goes to Wan 2.7.
|
|
1767
|
-
// NOTE: `x-ai/grok-imagine-video-1.5` is NOT a drop-in upgrade — it is
|
|
1768
|
-
// described as plain image-to-video and drops the reference conditioning
|
|
1769
|
-
// this entry exists for.
|
|
1770
|
-
label: "Grok Imagine Video",
|
|
1771
|
-
route: OPENROUTER_ROUTE,
|
|
1772
|
-
billing: {
|
|
1773
|
-
kind: "per_second",
|
|
1774
|
-
usd: {
|
|
1775
|
-
silent: 0.07,
|
|
1776
|
-
audio: 0.07,
|
|
1777
|
-
byResolution: { "480p": { silent: 0.05, audio: 0.05 }, "720p": { silent: 0.07, audio: 0.07 } }
|
|
1778
|
-
}
|
|
1779
|
-
},
|
|
1780
|
-
inputs: [],
|
|
1781
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1782
|
-
required: ["prompt"],
|
|
1783
|
-
params: {
|
|
1784
|
-
prompt: { kind: "string" },
|
|
1785
|
-
aspect_ratio: { kind: "string", enum: ["16:9", "9:16", "1:1", "4:3", "3:4", "3:2", "2:3"] },
|
|
1786
|
-
resolution: { kind: "string", enum: ["480p", "720p"] },
|
|
1787
|
-
duration: { kind: "number", enum: GROK_IMAGINE_DURATIONS }
|
|
1788
|
-
}
|
|
1789
|
-
},
|
|
1790
|
-
"alibaba/wan-2.7": {
|
|
1791
|
-
// Reference-to-video AND native audio — the only model we carry with both,
|
|
1792
|
-
// which makes it the landscape talking-head option.
|
|
1793
|
-
//
|
|
1794
|
-
// LANDSCAPE ONLY, measured. It advertises 9:16, 1:1, 4:3 and 3:4, and
|
|
1795
|
-
// delivers 16:9 regardless: asked for vertical via `aspect_ratio: "9:16"`
|
|
1796
|
-
// it returned 1280x720, and asked again via an explicit
|
|
1797
|
-
// `size: "720x1280"` from its own `supported_sizes` it returned 1280x720
|
|
1798
|
-
// again. The enum below is therefore what it DOES, not what it claims, so
|
|
1799
|
-
// nobody pays for a vertical clip that comes back landscape. For a vertical
|
|
1800
|
-
// avatar clip use `x-ai/grok-imagine-video` (silent) or animate a generated
|
|
1801
|
-
// still with `google/veo-3.1-lite` (native audio, honours 9:16).
|
|
1802
|
-
label: "Alibaba Wan 2.7",
|
|
1803
|
-
route: OPENROUTER_ROUTE,
|
|
1804
|
-
billing: {
|
|
1805
|
-
kind: "per_second",
|
|
1806
|
-
// Flat $0.10/s across resolutions and modes, audio included.
|
|
1807
|
-
usd: { silent: 0.1, audio: 0.1 },
|
|
1808
|
-
minBilledSeconds: MIN_BILLED_SECONDS
|
|
1809
|
-
},
|
|
1810
|
-
inputs: [],
|
|
1811
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1812
|
-
required: ["prompt"],
|
|
1813
|
-
params: {
|
|
1814
|
-
prompt: { kind: "string" },
|
|
1815
|
-
negative_prompt: { kind: "string" },
|
|
1816
|
-
aspect_ratio: { kind: "string", enum: ["16:9"] },
|
|
1817
|
-
resolution: { kind: "string", enum: ["720p", "1080p"] },
|
|
1818
|
-
duration: { kind: "number", enum: WAN_27_DURATIONS },
|
|
1819
|
-
seed: { kind: "number" },
|
|
1820
|
-
generate_audio: { kind: "boolean" }
|
|
1821
|
-
}
|
|
1822
|
-
},
|
|
1823
|
-
"x-ai/grok-imagine-video-1.5": {
|
|
1824
|
-
// NOT a replacement for the entry above, and deliberately absent from
|
|
1825
|
-
// `AVATAR_VIDEO_MODELS` and `REFERENCE_TO_VIDEO_MODELS`: OpenRouter describes the
|
|
1826
|
-
// older Grok as "text-, image-, and reference-conditioned" and 1.5 as taking "an
|
|
1827
|
-
// optional starting image". Reference conditioning is the whole reason Grok carries
|
|
1828
|
-
// avatars — it is what holds a face from the identity sheet — so swapping them
|
|
1829
|
-
// would quietly cost every avatar clip its likeness.
|
|
1830
|
-
//
|
|
1831
|
-
// What it adds over the older one: 1080p, and 15s rather than 10.
|
|
1832
|
-
label: "Grok Imagine Video 1.5",
|
|
1833
|
-
route: OPENROUTER_ROUTE,
|
|
1834
|
-
billing: {
|
|
1835
|
-
kind: "per_second",
|
|
1836
|
-
// `cents_per_video_output_second_*`: 8c, 14c and 25c. No audio, so both
|
|
1837
|
-
// columns are the same rate rather than one being wrong.
|
|
1838
|
-
usd: {
|
|
1839
|
-
silent: 0.14,
|
|
1840
|
-
audio: 0.14,
|
|
1841
|
-
byResolution: {
|
|
1842
|
-
"480p": { silent: 0.08, audio: 0.08 },
|
|
1843
|
-
"720p": { silent: 0.14, audio: 0.14 },
|
|
1844
|
-
"1080p": { silent: 0.25, audio: 0.25 }
|
|
1845
|
-
}
|
|
1846
|
-
}
|
|
1847
|
-
},
|
|
1848
|
-
inputs: [],
|
|
1849
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1850
|
-
required: ["prompt"],
|
|
1851
|
-
params: {
|
|
1852
|
-
prompt: { kind: "string" },
|
|
1853
|
-
aspect_ratio: { kind: "string", enum: ["16:9", "9:16", "1:1", "4:3", "3:4", "3:2", "2:3"] },
|
|
1854
|
-
resolution: { kind: "string", enum: ["480p", "720p", "1080p"] },
|
|
1855
|
-
duration: { kind: "number", enum: GROK_IMAGINE_15_DURATIONS }
|
|
1856
|
-
}
|
|
1857
|
-
},
|
|
1858
|
-
"alibaba/wan-3.0": {
|
|
1859
|
-
// 2.7's successor on every axis that matters: 2–30s against 2–10, 1080p and 480p
|
|
1860
|
-
// as well as 720p, and it keeps the native audio that made 2.7 the landscape
|
|
1861
|
-
// talking-head option.
|
|
1862
|
-
//
|
|
1863
|
-
// The ratios are what it ADVERTISES. 2.7 advertised five and delivered 16:9 for
|
|
1864
|
-
// all of them — measured, twice, which is why its enum here is a single value. That
|
|
1865
|
-
// was a different model and this one is not gated on its predecessor's lie, but
|
|
1866
|
-
// the first vertical clip anyone renders here is worth looking at before a campaign
|
|
1867
|
-
// is built on it.
|
|
1868
|
-
//
|
|
1869
|
-
// No `last_frame`: 2.7 takes one and 3.0 does not, so a canvas that ends a shot on
|
|
1870
|
-
// a chosen frame stays on 2.7.
|
|
1871
|
-
label: "Alibaba Wan 3.0",
|
|
1872
|
-
route: OPENROUTER_ROUTE,
|
|
1873
|
-
billing: {
|
|
1874
|
-
kind: "per_second",
|
|
1875
|
-
// Priced per resolution where 2.7 was flat, and the rate still includes
|
|
1876
|
-
// audio: there is no separate audio SKU. `duration_seconds_480p|720p|1080p`.
|
|
1877
|
-
usd: {
|
|
1878
|
-
silent: 0.1,
|
|
1879
|
-
audio: 0.1,
|
|
1880
|
-
byResolution: {
|
|
1881
|
-
"480p": { silent: 0.05, audio: 0.05 },
|
|
1882
|
-
"720p": { silent: 0.1, audio: 0.1 },
|
|
1883
|
-
"1080p": { silent: 0.2, audio: 0.2 }
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
|
-
},
|
|
1887
|
-
inputs: [],
|
|
1888
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1889
|
-
required: ["prompt"],
|
|
1890
|
-
params: {
|
|
1891
|
-
prompt: { kind: "string" },
|
|
1892
|
-
aspect_ratio: { kind: "string", enum: ["16:9", "9:16", "1:1", "4:3", "3:4"] },
|
|
1893
|
-
resolution: { kind: "string", enum: ["480p", "720p", "1080p"] },
|
|
1894
|
-
duration: { kind: "number", enum: WAN_30_DURATIONS },
|
|
1895
|
-
seed: { kind: "number" },
|
|
1896
|
-
generate_audio: { kind: "boolean" }
|
|
1897
|
-
}
|
|
1898
|
-
},
|
|
1899
|
-
"runway/gen-4.5": {
|
|
1900
|
-
// One resolution, two shapes, and silent — `generate_audio: false` in its listing,
|
|
1901
|
-
// so a talking head belongs on Wan or Omni. First frame only, no reference.
|
|
1902
|
-
label: "Runway Gen-4.5",
|
|
1903
|
-
route: OPENROUTER_ROUTE,
|
|
1904
|
-
billing: {
|
|
1905
|
-
kind: "per_second",
|
|
1906
|
-
// One flat rate, one resolution: `cents_per_second_output: 12`. Silent.
|
|
1907
|
-
usd: { silent: 0.12, audio: 0.12 }
|
|
1908
|
-
},
|
|
1909
|
-
inputs: [],
|
|
1910
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1911
|
-
required: ["prompt"],
|
|
1912
|
-
params: {
|
|
1913
|
-
prompt: { kind: "string" },
|
|
1914
|
-
aspect_ratio: { kind: "string", enum: ["16:9", "9:16"] },
|
|
1915
|
-
resolution: { kind: "string", enum: ["720p"] },
|
|
1916
|
-
duration: { kind: "number", enum: RUNWAY_45_DURATIONS },
|
|
1917
|
-
seed: { kind: "number" }
|
|
1918
|
-
}
|
|
1919
|
-
},
|
|
1920
|
-
"alibaba/happyhorse-1.1": {
|
|
1921
|
-
// Third reference-capable option: strong identity, correct ratios, no audio.
|
|
1922
|
-
// First-frame only (no `last_frame`), so it cannot close a beat on a
|
|
1923
|
-
// specified end pose the way Wan and Veo can.
|
|
1924
|
-
label: "Alibaba HappyHorse 1.1",
|
|
1925
|
-
route: OPENROUTER_ROUTE,
|
|
1926
|
-
billing: {
|
|
1927
|
-
kind: "per_second",
|
|
1928
|
-
usd: { silent: 0.1278, audio: 0.1278, byResolution: { "720p": { silent: 0.0988, audio: 0.0988 } } },
|
|
1929
|
-
minBilledSeconds: MIN_BILLED_SECONDS
|
|
1930
|
-
},
|
|
1931
|
-
inputs: [],
|
|
1932
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1933
|
-
required: ["prompt"],
|
|
1934
|
-
params: {
|
|
1935
|
-
prompt: { kind: "string" },
|
|
1936
|
-
aspect_ratio: { kind: "string", enum: ["16:9", "9:16", "1:1", "4:3", "3:4", "21:9", "9:21"] },
|
|
1937
|
-
resolution: { kind: "string", enum: ["720p", "1080p"] },
|
|
1938
|
-
duration: { kind: "number", enum: HAPPYHORSE_DURATIONS },
|
|
1939
|
-
seed: { kind: "number" }
|
|
1940
|
-
}
|
|
1941
|
-
},
|
|
1942
|
-
"google/veo-3.1-lite": {
|
|
1943
|
-
// The cheapest way to animate a still that carries a real face: same Veo
|
|
1944
|
-
// family and the same escape from ByteDance's filter, at $0.05/s with audio
|
|
1945
|
-
// at 720p against Veo 3.1's $0.40. That 8x is the difference between an
|
|
1946
|
-
// avatar clip you iterate on and one you think twice about.
|
|
1947
|
-
label: "Google Veo 3.1 Lite",
|
|
1948
|
-
route: OPENROUTER_ROUTE,
|
|
1949
|
-
billing: {
|
|
1950
|
-
kind: "per_second",
|
|
1951
|
-
usd: { silent: 0.05, audio: 0.08, byResolution: { "720p": { silent: 0.03, audio: 0.05 } } }
|
|
1952
|
-
},
|
|
1953
|
-
inputs: [],
|
|
1954
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1955
|
-
required: ["prompt"],
|
|
1956
|
-
params: {
|
|
1957
|
-
prompt: { kind: "string" },
|
|
1958
|
-
negative_prompt: { kind: "string" },
|
|
1959
|
-
aspect_ratio: { kind: "string", enum: ["16:9", "9:16"] },
|
|
1960
|
-
resolution: { kind: "string", enum: ["720p", "1080p"] },
|
|
1961
|
-
duration: { kind: "number", enum: [4, 6, 8] },
|
|
1962
|
-
seed: { kind: "number" },
|
|
1963
|
-
generate_audio: { kind: "boolean" },
|
|
1964
|
-
person_generation: { kind: "string", enum: ["allow_all", "allow_adult"] },
|
|
1965
|
-
enhance_prompt: { kind: "boolean" },
|
|
1966
|
-
conditioning_scale: { kind: "number" }
|
|
1967
|
-
}
|
|
1968
|
-
},
|
|
1969
|
-
"google/veo-3.1-fast": {
|
|
1970
|
-
// Cheap test/iteration model. Forwarded by the backend via
|
|
1971
|
-
// `provider.options.google-vertex.parameters` (camelCased on the wire).
|
|
1972
|
-
label: "Google Veo 3.1 Fast",
|
|
1973
|
-
route: OPENROUTER_ROUTE,
|
|
1974
|
-
billing: {
|
|
1975
|
-
kind: "per_second",
|
|
1976
|
-
usd: {
|
|
1977
|
-
silent: 0.1,
|
|
1978
|
-
audio: 0.12,
|
|
1979
|
-
byResolution: { "720p": { silent: 0.08, audio: 0.1 }, "4K": { silent: 0.25, audio: 0.3 } }
|
|
1980
|
-
}
|
|
1981
|
-
},
|
|
1982
|
-
inputs: [],
|
|
1983
|
-
optional_inputs: [{ kind: "image", mimes: OPENROUTER_IMAGE_MIMES }],
|
|
1984
|
-
required: ["prompt"],
|
|
1985
|
-
params: {
|
|
1986
|
-
prompt: { kind: "string" },
|
|
1987
|
-
negative_prompt: { kind: "string" },
|
|
1988
|
-
aspect_ratio: { kind: "string", enum: ["16:9", "9:16"] },
|
|
1989
|
-
resolution: { kind: "string", enum: ["720p", "1080p", "4K"] },
|
|
1990
|
-
duration: { kind: "number", enum: [4, 6, 8] },
|
|
1991
|
-
seed: { kind: "number", integer: true, min: 0, max: VEO_SEED_MAX },
|
|
1992
|
-
generate_audio: { kind: "boolean" },
|
|
1993
|
-
// Image-to-video and EU/UK/CH/MENA regions cap this at `allow_adult`;
|
|
1994
|
-
// `allow_all` is text-to-video only. Allow both so an image-conditioned
|
|
1995
|
-
// Veo clip (the real-face fallback) validates.
|
|
1996
|
-
person_generation: { kind: "string", enum: ["allow_all", "allow_adult"] },
|
|
1997
|
-
enhance_prompt: { kind: "boolean" },
|
|
1998
|
-
conditioning_scale: { kind: "number" }
|
|
1999
|
-
}
|
|
2000
|
-
}
|
|
2001
|
-
},
|
|
2002
|
-
video_deconstruct: {
|
|
2003
|
-
// Replication-grade video extraction — the forensic system prompts live on
|
|
2004
|
-
// the backend; `focus` appends emphasis only. Frames ride on a throwaway
|
|
2005
|
-
// Mux asset; analysis runs on Gemini with the video as a file part.
|
|
2006
|
-
"~google/gemini-flash-latest": {
|
|
2007
|
-
label: "Google Gemini Flash (latest, Video)",
|
|
2008
|
-
route: OPENROUTER_ROUTE,
|
|
2009
|
-
billing: USAGE_BILLED,
|
|
2010
|
-
inputs: [{ kind: "video", mimes: DECONSTRUCT_VIDEO_MIMES }],
|
|
2011
|
-
required: [],
|
|
2012
|
-
params: {
|
|
2013
|
-
mode: { kind: "string", enum: ["full", "index"] },
|
|
2014
|
-
language: { kind: "string" },
|
|
2015
|
-
max_scenes: { kind: "number", min: 1, max: 60 },
|
|
2016
|
-
focus: { kind: "string" },
|
|
2017
|
-
start_s: { kind: "number", min: 0 },
|
|
2018
|
-
end_s: { kind: "number", min: 0 },
|
|
2019
|
-
max_clip_s: { kind: "number", min: 1, max: 60 },
|
|
2020
|
-
transcriber: { kind: "string", enum: ["groq", "deepgram"] },
|
|
2021
|
-
// Real visual shot-cut timestamps (seconds) from local PySceneDetect;
|
|
2022
|
-
// scene boundaries snap onto them so frames never straddle a hard cut.
|
|
2023
|
-
// Shape (number[]) is enforced by the node + backend Zod schemas.
|
|
2024
|
-
shot_cuts: { kind: "json" }
|
|
2025
|
-
}
|
|
2026
|
-
},
|
|
2027
|
-
"~google/gemini-pro-latest": {
|
|
2028
|
-
label: "Google Gemini Pro (latest, Video)",
|
|
2029
|
-
route: OPENROUTER_ROUTE,
|
|
2030
|
-
billing: USAGE_BILLED,
|
|
2031
|
-
inputs: [{ kind: "video", mimes: DECONSTRUCT_VIDEO_MIMES }],
|
|
2032
|
-
required: [],
|
|
2033
|
-
params: {
|
|
2034
|
-
mode: { kind: "string", enum: ["full", "index"] },
|
|
2035
|
-
language: { kind: "string" },
|
|
2036
|
-
max_scenes: { kind: "number", min: 1, max: 60 },
|
|
2037
|
-
focus: { kind: "string" },
|
|
2038
|
-
start_s: { kind: "number", min: 0 },
|
|
2039
|
-
end_s: { kind: "number", min: 0 },
|
|
2040
|
-
max_clip_s: { kind: "number", min: 1, max: 60 },
|
|
2041
|
-
transcriber: { kind: "string", enum: ["groq", "deepgram"] },
|
|
2042
|
-
// See gemini-flash-latest above — local PySceneDetect shot-cut timestamps.
|
|
2043
|
-
shot_cuts: { kind: "json" }
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
|
-
},
|
|
2047
|
-
video_lipsync: {
|
|
2048
|
-
// Formerly `fal/veed-lipsync`, which named a provider and a model it had stopped
|
|
2049
|
-
// running on; that id stays accepted through `MODEL_ALIASES`.
|
|
2050
|
-
"replicate/sync-lipsync-2": {
|
|
2051
|
-
label: "Sync Labs Lipsync 2 (Replicate)",
|
|
2052
|
-
route: { provider: "replicate", wireModel: "sync/lipsync-2" },
|
|
2053
|
-
billing: { kind: "formula", formula: "lipsync-minutes" },
|
|
2054
|
-
inputs: [
|
|
2055
|
-
{ kind: "video", mimes: REPLICATE_VIDEO_MIMES },
|
|
2056
|
-
{ kind: "audio", mimes: REPLICATE_AUDIO_MIMES }
|
|
2057
|
-
],
|
|
2058
|
-
required: [],
|
|
2059
|
-
params: {}
|
|
2060
|
-
}
|
|
2061
|
-
},
|
|
2062
|
-
tts: {
|
|
2063
|
-
"elevenlabs/eleven_v3": {
|
|
2064
|
-
// eleven_v3 does NOT yet support context stitching
|
|
2065
|
-
// (previous_text/next_text/*_request_ids). ElevenLabs returns a clean
|
|
2066
|
-
// `unsupported_model` 400 if you pass them.
|
|
2067
|
-
label: "ElevenLabs Eleven v3",
|
|
2068
|
-
route: { provider: "elevenlabs", wireModel: "eleven_v3" },
|
|
2069
|
-
billing: { kind: "formula", formula: "elevenlabs-characters" },
|
|
2070
|
-
inputs: [],
|
|
2071
|
-
required: ["text", "voice"],
|
|
2072
|
-
params: {
|
|
2073
|
-
text: { kind: "string", maxLength: ELEVENLABS_MAX_TEXT_CHARS },
|
|
2074
|
-
voice: { kind: "string" },
|
|
2075
|
-
language_code: { kind: "string" },
|
|
2076
|
-
stability: { kind: "number", min: 0, max: 1 },
|
|
2077
|
-
similarity_boost: { kind: "number", min: 0, max: 1 },
|
|
2078
|
-
voice_settings: { kind: "json" },
|
|
2079
|
-
seed: { kind: "number", min: 0, max: 4294967295 },
|
|
2080
|
-
pronunciation_dictionary_locators: { kind: "json" },
|
|
2081
|
-
apply_text_normalization: { kind: "string", enum: ["auto", "on", "off"] },
|
|
2082
|
-
apply_language_text_normalization: { kind: "boolean" },
|
|
2083
|
-
with_timestamps: { kind: "boolean" },
|
|
2084
|
-
output_format: { kind: "string", enum: ELEVENLABS_OUTPUT_FORMATS }
|
|
2085
|
-
}
|
|
2086
|
-
}
|
|
2087
|
-
},
|
|
2088
|
-
audio_voice_convert: {
|
|
2089
|
-
"elevenlabs/eleven_multilingual_sts_v2": {
|
|
2090
|
-
// Speech-to-speech / Voice Changer: re-voice an existing audio clip in the
|
|
2091
|
-
// TARGET voice, preserving timing/prosody. Used to normalize a talking-head
|
|
2092
|
-
// clip's native (generator-chosen) voice into ONE consistent brand voice.
|
|
2093
|
-
label: "ElevenLabs Voice Changer (multilingual STS v2)",
|
|
2094
|
-
route: { provider: "elevenlabs", wireModel: "eleven_multilingual_sts_v2" },
|
|
2095
|
-
billing: { kind: "formula", formula: "elevenlabs-voice-convert-minutes" },
|
|
2096
|
-
inputs: [{ kind: "audio", mimes: REPLICATE_AUDIO_MIMES }],
|
|
2097
|
-
required: ["voice"],
|
|
2098
|
-
params: {
|
|
2099
|
-
voice: { kind: "string" },
|
|
2100
|
-
output_format: { kind: "string", enum: ELEVENLABS_OUTPUT_FORMATS },
|
|
2101
|
-
remove_background_noise: { kind: "boolean" }
|
|
2102
|
-
}
|
|
2103
|
-
}
|
|
2104
|
-
},
|
|
2105
|
-
music: {
|
|
2106
|
-
"elevenlabs/music-v1": {
|
|
2107
|
-
label: "ElevenLabs Music v1 (Compose)",
|
|
2108
|
-
route: { provider: "elevenlabs", wireModel: ELEVENLABS_MUSIC_ENGINE },
|
|
2109
|
-
billing: { kind: "formula", formula: "elevenlabs-music-seconds" },
|
|
2110
|
-
inputs: [],
|
|
2111
|
-
required: [],
|
|
2112
|
-
params: {
|
|
2113
|
-
prompt: { kind: "string" },
|
|
2114
|
-
composition_plan: { kind: "json" },
|
|
2115
|
-
music_length_ms: { kind: "number", min: 3e3, max: ELEVENLABS_MAX_MUSIC_LENGTH_MS },
|
|
2116
|
-
seed: { kind: "number" },
|
|
2117
|
-
force_instrumental: { kind: "boolean" },
|
|
2118
|
-
respect_sections_durations: { kind: "boolean" },
|
|
2119
|
-
with_timestamps: { kind: "boolean" },
|
|
2120
|
-
output_format: { kind: "string", enum: ELEVENLABS_OUTPUT_FORMATS }
|
|
2121
|
-
}
|
|
2122
|
-
},
|
|
2123
|
-
"elevenlabs/video-background-music-v1": {
|
|
2124
|
-
label: "ElevenLabs Video Background Music v1",
|
|
2125
|
-
route: { provider: "elevenlabs", wireModel: ELEVENLABS_MUSIC_ENGINE },
|
|
2126
|
-
billing: { kind: "formula", formula: "elevenlabs-music-seconds" },
|
|
2127
|
-
inputs: [{ kind: "video", mimes: REPLICATE_VIDEO_MIMES }],
|
|
2128
|
-
required: [],
|
|
2129
|
-
params: {
|
|
2130
|
-
description: { kind: "string" },
|
|
2131
|
-
tags: { kind: "json" },
|
|
2132
|
-
output_format: { kind: "string", enum: ELEVENLABS_OUTPUT_FORMATS }
|
|
2133
|
-
}
|
|
2134
|
-
}
|
|
2135
|
-
},
|
|
2136
|
-
dialogue: {
|
|
2137
|
-
"elevenlabs/eleven_v3": {
|
|
2138
|
-
label: "ElevenLabs Eleven v3 (Dialogue)",
|
|
2139
|
-
route: { provider: "elevenlabs", wireModel: "eleven_v3" },
|
|
2140
|
-
billing: { kind: "formula", formula: "elevenlabs-characters" },
|
|
2141
|
-
inputs: [],
|
|
2142
|
-
required: ["inputs"],
|
|
2143
|
-
params: {
|
|
2144
|
-
inputs: { kind: "json" },
|
|
2145
|
-
language_code: { kind: "string" },
|
|
2146
|
-
settings: { kind: "json" },
|
|
2147
|
-
seed: { kind: "number", min: 0, max: 4294967295 },
|
|
2148
|
-
apply_text_normalization: { kind: "string", enum: ["auto", "on", "off"] },
|
|
2149
|
-
with_timestamps: { kind: "boolean" },
|
|
2150
|
-
output_format: { kind: "string", enum: ELEVENLABS_OUTPUT_FORMATS }
|
|
2151
|
-
}
|
|
2152
|
-
}
|
|
2153
|
-
},
|
|
2154
|
-
sound_effect: {
|
|
2155
|
-
"elevenlabs/eleven_text_to_sound_v2": {
|
|
2156
|
-
label: "ElevenLabs Text-to-Sound v2",
|
|
2157
|
-
route: { provider: "elevenlabs", wireModel: "eleven_text_to_sound_v2" },
|
|
2158
|
-
billing: { kind: "formula", formula: "elevenlabs-sound-effect-seconds" },
|
|
2159
|
-
inputs: [],
|
|
2160
|
-
required: ["text"],
|
|
2161
|
-
params: {
|
|
2162
|
-
text: { kind: "string" },
|
|
2163
|
-
duration_seconds: { kind: "number", min: 0.5, max: 30 },
|
|
2164
|
-
prompt_influence: { kind: "number", min: 0, max: 1 },
|
|
2165
|
-
loop: { kind: "boolean" },
|
|
2166
|
-
output_format: { kind: "string", enum: ELEVENLABS_OUTPUT_FORMATS }
|
|
2167
|
-
}
|
|
2168
|
-
}
|
|
2169
|
-
}
|
|
2170
|
-
};
|
|
2171
|
-
var MODEL_ALIASES = {
|
|
2172
|
-
"fal/veed-lipsync": "replicate/sync-lipsync-2",
|
|
2173
|
-
"fal/veed-video-background-removal": "replicate/birefnet-video",
|
|
2174
|
-
"fal/birefnet-v2": "replicate/birefnet",
|
|
2175
|
-
"google/gemini-3.1-flash-image-preview": "google/gemini-3.1-flash-image",
|
|
2176
|
-
"google/gemini-3-pro-image-preview": "google/gemini-3-pro-image",
|
|
2177
|
-
"openai/gpt-5.4-image-2": "openai/gpt-image-2.5-sunburst"
|
|
2178
|
-
};
|
|
2179
|
-
function canonicalModelId(model) {
|
|
2180
|
-
return Object.keys(MODEL_ALIASES).includes(model) ? MODEL_ALIASES[model] : model;
|
|
2181
|
-
}
|
|
2182
|
-
function modelIdsAccepted(canonical) {
|
|
2183
|
-
return [canonical, ...Object.keys(MODEL_ALIASES).filter((legacy) => MODEL_ALIASES[legacy] === canonical)];
|
|
2184
|
-
}
|
|
2185
|
-
function modelSpec(kind, model) {
|
|
2186
|
-
return MODEL_REGISTRY[kind]?.[canonicalModelId(model)];
|
|
2187
|
-
}
|
|
2188
|
-
var NARROWED_ALIASES = ["openai/gpt-5.4-image-2"];
|
|
2189
|
-
function canonicalModelParams(kind, params) {
|
|
2190
|
-
const model = params.model;
|
|
2191
|
-
if (typeof model !== "string" || canonicalModelId(model) === model) return params;
|
|
2192
|
-
const successor = canonicalModelId(model);
|
|
2193
|
-
if (!NARROWED_ALIASES.includes(model)) return { ...params, model: successor };
|
|
2194
|
-
const fitted = { ...params, model: successor };
|
|
2195
|
-
if (typeof fitted.aspect_ratio === "string") {
|
|
2196
|
-
fitted.aspect_ratio = nearestSupportedAspectRatio(kind, successor, fitted.aspect_ratio);
|
|
2197
|
-
}
|
|
2198
|
-
if (typeof fitted.image_size === "string") {
|
|
2199
|
-
fitted.image_size = supportsParam(kind, successor, "image_size") ? nearestSupportedImageSize(kind, successor, fitted.image_size) : void 0;
|
|
2200
|
-
}
|
|
2201
|
-
if (typeof fitted.quality === "string") {
|
|
2202
|
-
fitted.quality = bestSupportedQuality(kind, successor, fitted.quality);
|
|
2203
|
-
}
|
|
2204
|
-
return Object.fromEntries(Object.entries(fitted).filter(([, value]) => value !== void 0));
|
|
2205
|
-
}
|
|
2206
|
-
function perSecondBilling(model) {
|
|
2207
|
-
const billing = MODEL_REGISTRY.video_generate[model]?.billing;
|
|
2208
|
-
return billing?.kind === "per_second" ? billing : void 0;
|
|
2209
|
-
}
|
|
2210
|
-
var MODEL_ROLES = {
|
|
2211
|
-
/** Ad frames and static-ad plates: the most faithful text and identity reproduction. */
|
|
2212
|
-
adImage: { kind: "image_generate", model: "openai/gpt-image-2.5-sunburst" },
|
|
2213
|
-
/**
|
|
2214
|
-
* The multi-view reference sheet a recurring element is fused on. Gemini 3 Pro makes
|
|
2215
|
-
* the cleanest, best-labelled turnaround, worth it for the ONE reference every frame
|
|
2216
|
-
* of an ad grounds on.
|
|
2217
|
-
*/
|
|
2218
|
-
referenceSheet: { kind: "image_reference_sheet", model: "google/gemini-3-pro-image" },
|
|
2219
|
-
/** Re-framing a static ad whose copy is baked into the pixels. */
|
|
2220
|
-
aspectAdapt: { kind: "image_aspect_adapt", model: "google/gemini-3-pro-image" },
|
|
2221
|
-
/**
|
|
2222
|
-
* The judge comparing candidate plates. Flash, not Pro: Pro measured 5 credits for
|
|
2223
|
-
* one pick, a tenth of the render it judges.
|
|
2224
|
-
*/
|
|
2225
|
-
plateJudge: { kind: "image_select", model: "~google/gemini-flash-latest" },
|
|
2226
|
-
/**
|
|
2227
|
-
* The static-ad blueprint extraction, and the fit of a reference to a company (`winning-ads fit`).
|
|
2228
|
-
* Flash, not Pro: measured on 16 proven ads (dev, Oct 2026), Flash read as well, answered 11 describes
|
|
2229
|
-
* of 12 (Pro 8: its preview model stopped answers part-way) and 16 fits of 16 (Pro 15), at under half
|
|
2230
|
-
* the describe's cost and a fifth of the fit's; the fit kept or rejected the same ads 14 times of 15.
|
|
2231
|
-
* A describe takes ~10 s longer (40 s), a fit ~12 s less (10 s).
|
|
2232
|
-
*/
|
|
2233
|
-
adDescribe: { kind: "image_describe", model: "~google/gemini-flash-latest" },
|
|
2234
|
-
/** The element-selection and layout passes over a blueprint. */
|
|
2235
|
-
blueprintAnalysis: { kind: "text_generate", model: "~google/gemini-flash-latest" },
|
|
2236
|
-
/**
|
|
2237
|
-
* The viewer an ad reaches, played before a static ad renders (`baker canvas viewer-check`):
|
|
2238
|
-
* says from the copy and the scene what is offered, to whom, and what to do next. Text
|
|
2239
|
-
* only and asked once per ad and viewer, so Flash; the calibration set (E8) decides.
|
|
2240
|
-
*/
|
|
2241
|
-
viewerCheck: { kind: "text_generate", model: "~google/gemini-flash-latest" },
|
|
2242
|
-
/**
|
|
2243
|
-
* Picks the customer truths out of reviews, testimonials and threads (`baker research
|
|
2244
|
-
* customers`): returns exact spans the code then checks against the source. Text only and
|
|
2245
|
-
* one call per batch, so Flash.
|
|
2246
|
-
*/
|
|
2247
|
-
customerInsights: { kind: "text_generate", model: "~google/gemini-flash-latest" },
|
|
2248
|
-
/**
|
|
2249
|
-
* The same viewer shown the FINISHED static ad at phone size for about three seconds, with no
|
|
2250
|
-
* brand and no brief: what is sold, whether it is for them, what to do next, what stopped them
|
|
2251
|
-
* (`glance-check.ts`). One small picture per run, so Flash.
|
|
2252
|
-
*/
|
|
2253
|
-
glanceCheck: { kind: "image_describe", model: "~google/gemini-flash-latest" },
|
|
2254
|
-
/**
|
|
2255
|
-
* Reads every line of text and the logo of a finished static ad WITH its box, for the
|
|
2256
|
-
* copy and safe-area checks. Bench E10 (2026-09-30): word F1 0.994, box IoU 0.937, 4.3 s,
|
|
2257
|
-
* about $0.005 an image on `google/gemini-3.8-flash`, which this alias resolves to;
|
|
2258
|
-
* tesseract and PaddleOCR missed the 0.95 F1 gate.
|
|
2259
|
-
*/
|
|
2260
|
-
textBoxReader: { kind: "image_describe", model: "~google/gemini-flash-latest" },
|
|
2261
|
-
/**
|
|
2262
|
-
* Reads where every person, face, animal and product sits in a static ad's picture, WITH its
|
|
2263
|
-
* box, so each size is cut around them and its words kept off faces. The same reader and grid
|
|
2264
|
-
* as `textBoxReader` (Gemini's `box_2d`), asked once per chosen picture.
|
|
2265
|
-
*/
|
|
2266
|
-
subjectBoxReader: { kind: "image_describe", model: "~google/gemini-flash-latest" },
|
|
2267
|
-
/**
|
|
2268
|
-
* Compares one size of a finished static ad with its main size for what boxes cannot say: the
|
|
2269
|
-
* same product and people, nothing shown twice, nobody stretched, never the main picture boxed in
|
|
2270
|
-
* a bigger frame (`size-consistency.ts`). Flash: one small pair per drawn size; on 29 production
|
|
2271
|
-
* pairs asked twice it flagged none and named 4 of 4 planted defects (Oct 2026).
|
|
2272
|
-
*/
|
|
2273
|
-
sizeMatch: { kind: "image_describe", model: "~google/gemini-flash-latest" },
|
|
2274
|
-
/**
|
|
2275
|
-
* Scene-by-scene video extraction. Flash: ~2-3x faster per call than Pro, which keeps
|
|
2276
|
-
* each per-scene step inside the action time budget.
|
|
2277
|
-
*/
|
|
2278
|
-
videoDeconstruct: { kind: "video_deconstruct", model: "~google/gemini-flash-latest" },
|
|
2279
|
-
/** The backend `image_search` agent loop that picks search tools and queries. */
|
|
2280
|
-
imageSearch: { kind: "text_generate", model: "~google/gemini-flash-latest" },
|
|
2281
|
-
voiceover: { kind: "tts", model: "elevenlabs/eleven_v3" },
|
|
2282
|
-
soundEffect: { kind: "sound_effect", model: "elevenlabs/eleven_text_to_sound_v2" },
|
|
2283
|
-
musicBed: { kind: "music", model: "elevenlabs/music-v1" },
|
|
2284
|
-
/** Re-voices a talking clip's native audio into one consistent brand voice. */
|
|
2285
|
-
voiceConvert: { kind: "audio_voice_convert", model: "elevenlabs/eleven_multilingual_sts_v2" },
|
|
2286
|
-
/** The scored video router's candidates, one per job it can route to. */
|
|
2287
|
-
videoRouterWorkhorse: { kind: "video_generate", model: "bytedance/seedance-2.0" },
|
|
2288
|
-
videoRouterRealFace: { kind: "video_generate", model: "google/veo-3.1" },
|
|
2289
|
-
videoRouterRealFaceEconomy: { kind: "video_generate", model: "google/veo-3.1-fast" },
|
|
2290
|
-
videoRouterMotion: { kind: "video_generate", model: "kwaivgi/kling-v3.0-pro" },
|
|
2291
|
-
imageDefault: { kind: "image_generate", model: DEFAULT_IMAGE_GENERATE_MODEL },
|
|
2292
|
-
videoDefault: { kind: "video_generate", model: DEFAULT_VIDEO_GENERATE_MODEL },
|
|
2293
|
-
avatarVideo: { kind: "video_generate", model: DEFAULT_AVATAR_VIDEO_MODEL }
|
|
2294
|
-
};
|
|
2295
|
-
var AD_IMAGE_MODEL = MODEL_ROLES.adImage.model;
|
|
2296
|
-
var REFERENCE_SHEET_MODEL = MODEL_ROLES.referenceSheet.model;
|
|
2297
|
-
var ASPECT_ADAPT_MODEL = MODEL_ROLES.aspectAdapt.model;
|
|
2298
|
-
var PLATE_JUDGE_MODEL = MODEL_ROLES.plateJudge.model;
|
|
2299
|
-
var AD_DESCRIBE_MODEL = MODEL_ROLES.adDescribe.model;
|
|
2300
|
-
var BLUEPRINT_ANALYSIS_MODEL = MODEL_ROLES.blueprintAnalysis.model;
|
|
2301
|
-
var VIEWER_CHECK_MODEL = MODEL_ROLES.viewerCheck.model;
|
|
2302
|
-
var CUSTOMER_INSIGHTS_MODEL = MODEL_ROLES.customerInsights.model;
|
|
2303
|
-
var GLANCE_CHECK_MODEL = MODEL_ROLES.glanceCheck.model;
|
|
2304
|
-
var TEXT_BOX_READER_MODEL = MODEL_ROLES.textBoxReader.model;
|
|
2305
|
-
var SUBJECT_BOX_READER_MODEL = MODEL_ROLES.subjectBoxReader.model;
|
|
2306
|
-
var SIZE_MATCH_MODEL = MODEL_ROLES.sizeMatch.model;
|
|
2307
|
-
var VIDEO_DECONSTRUCT_MODEL = MODEL_ROLES.videoDeconstruct.model;
|
|
2308
|
-
var IMAGE_SEARCH_MODEL = MODEL_ROLES.imageSearch.model;
|
|
2309
|
-
var VOICEOVER_MODEL = MODEL_ROLES.voiceover.model;
|
|
2310
|
-
var SOUND_EFFECT_MODEL = MODEL_ROLES.soundEffect.model;
|
|
2311
|
-
var MUSIC_BED_MODEL = MODEL_ROLES.musicBed.model;
|
|
2312
|
-
var VOICE_CONVERT_MODEL = MODEL_ROLES.voiceConvert.model;
|
|
2313
|
-
function isRegisteredModel(kind, model) {
|
|
2314
|
-
return MODEL_REGISTRY[kind]?.[canonicalModelId(model)] !== void 0;
|
|
2315
|
-
}
|
|
2316
|
-
function imageGenerateAspectRatios() {
|
|
2317
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2318
|
-
for (const model of IMAGE_GENERATE_MODELS) {
|
|
2319
|
-
for (const ratio of supportedAspectRatios("image_generate", model) ?? []) seen.add(ratio);
|
|
2320
|
-
}
|
|
2321
|
-
return [...seen];
|
|
2322
|
-
}
|
|
2323
|
-
function supportsParam(kind, model, param) {
|
|
2324
|
-
return modelSpec(kind, model)?.params[param] !== void 0;
|
|
2325
|
-
}
|
|
2326
|
-
var DEFAULT_CLIP_DURATION_S = 5;
|
|
2327
|
-
var SPOKEN_WORDS_PER_SECOND = 2.5;
|
|
2328
|
-
var SPOKEN_LINE = new RegExp(`(?<![\\p{L}\\p{N}])['"\\u201c\\u201d\\u2018\\u2019]((?:[^'"\\u201c\\u201d\\u2018\\u2019]|(?<=\\p{L})['\\u2019](?=\\p{L})){8,})['"\\u201c\\u201d\\u2018\\u2019](?![\\p{L}\\p{N}])`, "gu");
|
|
2329
|
-
function spokenWordsIn(prompt) {
|
|
2330
|
-
if (!prompt) return 0;
|
|
2331
|
-
const quoted = [...prompt.matchAll(SPOKEN_LINE)].map((m) => m[1] ?? "");
|
|
2332
|
-
const text = quoted.join(" ").trim();
|
|
2333
|
-
return text ? text.split(/\s+/).filter(Boolean).length : 0;
|
|
2334
|
-
}
|
|
2335
|
-
var SPOKEN_CLIP_DURATION_S = 8;
|
|
2336
|
-
function nearestClipDuration(model, preferred) {
|
|
2337
|
-
const schema = MODEL_REGISTRY.video_generate[model]?.params.duration;
|
|
2338
|
-
const allowed = schema?.kind === "number" ? schema.enum : void 0;
|
|
2339
|
-
if (!allowed?.length || allowed.includes(preferred)) return preferred;
|
|
2340
|
-
return [...allowed].sort((a, b) => Math.abs(a - preferred) - Math.abs(b - preferred) || a - b)[0];
|
|
2341
|
-
}
|
|
2342
|
-
var SILENT_VIDEO_MODELS = /* @__PURE__ */ new Set([
|
|
2343
|
-
"runway/gen-4.5",
|
|
2344
|
-
"x-ai/grok-imagine-video",
|
|
2345
|
-
"x-ai/grok-imagine-video-1.5",
|
|
2346
|
-
"alibaba/happyhorse-1.1"
|
|
2347
|
-
]);
|
|
2348
|
-
function clipAudioMode(model) {
|
|
2349
|
-
if (supportsParam("video_generate", model, "generate_audio")) return "toggle";
|
|
2350
|
-
return SILENT_VIDEO_MODELS.has(model) ? "never" : "always";
|
|
2351
|
-
}
|
|
2352
|
-
function clipDurationsFor(model) {
|
|
2353
|
-
const schema = MODEL_REGISTRY.video_generate[model]?.params.duration;
|
|
2354
|
-
const allowed = schema?.kind === "number" ? schema.enum : void 0;
|
|
2355
|
-
return allowed?.length ? [...allowed].sort((a, b) => a - b) : void 0;
|
|
2356
|
-
}
|
|
2357
|
-
function maxClipSeconds(model) {
|
|
2358
|
-
const allowed = clipDurationsFor(model);
|
|
2359
|
-
return allowed ? allowed[allowed.length - 1] : void 0;
|
|
2360
|
-
}
|
|
2361
|
-
function splitScriptFor(words, model) {
|
|
2362
|
-
const maxSeconds = maxClipSeconds(model);
|
|
2363
|
-
if (!maxSeconds) return null;
|
|
2364
|
-
const perClip = Math.floor(maxSeconds * SPOKEN_WORDS_PER_SECOND);
|
|
2365
|
-
if (words <= perClip) return null;
|
|
2366
|
-
const clips = Math.ceil(words / perClip);
|
|
2367
|
-
return { clips, wordsPerClip: Math.ceil(words / clips), maxSeconds };
|
|
2368
|
-
}
|
|
2369
|
-
function promptMaxLength(kind, model) {
|
|
2370
|
-
const schema = modelSpec(kind, model)?.params.prompt;
|
|
2371
|
-
return schema?.kind === "string" ? schema.maxLength : void 0;
|
|
2372
|
-
}
|
|
2373
|
-
function inputSlot(kind, model, inputKind) {
|
|
2374
|
-
const spec = modelSpec(kind, model);
|
|
2375
|
-
return spec?.optional_inputs?.find((input) => input.kind === inputKind) ?? spec?.inputs.find((input) => input.kind === inputKind);
|
|
2376
|
-
}
|
|
2377
|
-
function maxInputSlot(kind, model, inputKind) {
|
|
2378
|
-
return inputSlot(kind, model, inputKind)?.max;
|
|
2379
|
-
}
|
|
2380
|
-
function maxInputReferences(kind, model) {
|
|
2381
|
-
return maxInputSlot(kind, model, "image");
|
|
2382
|
-
}
|
|
2383
|
-
function supportedQualities(kind, model) {
|
|
2384
|
-
const schema = modelSpec(kind, model)?.params.quality;
|
|
2385
|
-
return schema?.kind === "string" ? schema.enum : void 0;
|
|
2386
|
-
}
|
|
2387
|
-
function bestSupportedQuality(kind, model, want) {
|
|
2388
|
-
const supported = supportedQualities(kind, model);
|
|
2389
|
-
if (!supported) return void 0;
|
|
2390
|
-
if (supported.includes(want)) return want;
|
|
2391
|
-
const ladder = supported.filter((step) => step !== "auto");
|
|
2392
|
-
const ceiling = ladder.indexOf(want);
|
|
2393
|
-
const reachable = ceiling === -1 ? ladder : ladder.slice(0, ceiling);
|
|
2394
|
-
return reachable[reachable.length - 1];
|
|
2395
|
-
}
|
|
2396
|
-
function supportedAspectRatios(kind, model) {
|
|
2397
|
-
const schema = modelSpec(kind, model)?.params.aspect_ratio;
|
|
2398
|
-
return schema?.kind === "string" ? schema.enum : void 0;
|
|
2399
|
-
}
|
|
2400
|
-
function ratioValue(ratio) {
|
|
2401
|
-
const [w, h] = ratio.split(":").map(Number);
|
|
2402
|
-
if (!w || !h || !Number.isFinite(w) || !Number.isFinite(h)) return null;
|
|
2403
|
-
return w / h;
|
|
2404
|
-
}
|
|
2405
|
-
function nearestSupportedAspectRatio(kind, model, target) {
|
|
2406
|
-
const supported = supportedAspectRatios(kind, model);
|
|
2407
|
-
if (!supported || supported.includes(target)) return target;
|
|
2408
|
-
const wanted = ratioValue(target);
|
|
2409
|
-
if (wanted === null) return target;
|
|
2410
|
-
let best = target;
|
|
2411
|
-
let bestDistance = Number.POSITIVE_INFINITY;
|
|
2412
|
-
for (const candidate of supported) {
|
|
2413
|
-
const value = ratioValue(candidate);
|
|
2414
|
-
if (value === null) continue;
|
|
2415
|
-
const distance = Math.abs(Math.log(value / wanted));
|
|
2416
|
-
if (distance < bestDistance) {
|
|
2417
|
-
bestDistance = distance;
|
|
2418
|
-
best = candidate;
|
|
2419
|
-
}
|
|
2420
|
-
}
|
|
2421
|
-
return best;
|
|
2422
|
-
}
|
|
2423
|
-
function supportedImageSizes(kind, model) {
|
|
2424
|
-
const schema = modelSpec(kind, model)?.params.image_size;
|
|
2425
|
-
return schema?.kind === "string" ? schema.enum : void 0;
|
|
2426
|
-
}
|
|
2427
|
-
var IMAGE_SIZE_ORDER = ["0.5K", "1K", "2K", "4K"];
|
|
2428
|
-
function nearestSupportedImageSize(kind, model, target) {
|
|
2429
|
-
const supported = supportedImageSizes(kind, model);
|
|
2430
|
-
if (!supported || supported.includes(target)) return target;
|
|
2431
|
-
const wanted = IMAGE_SIZE_ORDER.indexOf(target);
|
|
2432
|
-
if (wanted < 0) return target;
|
|
2433
|
-
const ranked = supported.filter((s) => IMAGE_SIZE_ORDER.includes(s)).sort((a, b) => IMAGE_SIZE_ORDER.indexOf(a) - IMAGE_SIZE_ORDER.indexOf(b));
|
|
2434
|
-
if (ranked.length === 0) return target;
|
|
2435
|
-
const belowOrEqual = ranked.filter((s) => IMAGE_SIZE_ORDER.indexOf(s) <= wanted);
|
|
2436
|
-
return belowOrEqual.length > 0 ? belowOrEqual[belowOrEqual.length - 1] : ranked[0];
|
|
2437
|
-
}
|
|
2438
|
-
|
|
2439
|
-
// ../canvas-contract/src/credits.ts
|
|
2440
|
-
var CREDITS_PER_USD = 100;
|
|
2441
|
-
function usdToCredits(usd) {
|
|
2442
|
-
if (!(usd > 0)) return 0;
|
|
2443
|
-
return Math.ceil(Number((usd * CREDITS_PER_USD).toFixed(6)));
|
|
2444
|
-
}
|
|
2445
|
-
|
|
2446
|
-
// ../canvas-contract/src/videoCost.ts
|
|
2447
|
-
var OPENING_FRAME_CREDITS = usdToCredits(0.03);
|
|
2448
|
-
var SEEDANCE_USD_PER_SECOND = {
|
|
2449
|
-
"480p": 0.18,
|
|
2450
|
-
"720p": 0.5,
|
|
2451
|
-
"1080p": 0.62,
|
|
2452
|
-
"4k": 0.62
|
|
2453
|
-
};
|
|
2454
|
-
var DEFAULT_VIDEO_RESOLUTION = "720p";
|
|
2455
|
-
var DEFAULT_VIDEO_DURATION_S = 5;
|
|
2456
|
-
function isSeedanceModel(model) {
|
|
2457
|
-
return model.startsWith("bytedance/seedance");
|
|
2458
|
-
}
|
|
2459
|
-
var SEEDANCE_25_USD_PER_SECOND = {
|
|
2460
|
-
"480p": 0.1075,
|
|
2461
|
-
"720p": 0.2326
|
|
2462
|
-
};
|
|
2463
|
-
var SEEDANCE_25_FALLBACK_USD_PER_SECOND = 0.2326;
|
|
2464
|
-
function seedance25UsdPerSecond(resolution) {
|
|
2465
|
-
return SEEDANCE_25_USD_PER_SECOND[resolution ?? DEFAULT_VIDEO_RESOLUTION] ?? SEEDANCE_25_FALLBACK_USD_PER_SECOND;
|
|
2466
|
-
}
|
|
2467
|
-
var FALLBACK_USD_PER_SECOND = 0.5;
|
|
2468
|
-
function billedSeconds(model, duration) {
|
|
2469
|
-
const floor = perSecondBilling(model)?.minBilledSeconds;
|
|
2470
|
-
return floor === void 0 ? duration : Math.max(duration, floor);
|
|
2471
|
-
}
|
|
2472
|
-
function seedanceUsdPerSecond(resolution) {
|
|
2473
|
-
return SEEDANCE_USD_PER_SECOND[resolution ?? DEFAULT_VIDEO_RESOLUTION] ?? FALLBACK_USD_PER_SECOND;
|
|
2474
|
-
}
|
|
2475
|
-
var GEMINI_OMNI_USD_PER_1M_VIDEO_TOKENS = 17.5;
|
|
2476
|
-
var GEMINI_OMNI_VIDEO_TOKENS_PER_SECOND = 5792;
|
|
2477
|
-
var GEMINI_OMNI_RESOLUTION_MULTIPLIER = {
|
|
2478
|
-
"360p": 1 / 3,
|
|
2479
|
-
"720p": 1,
|
|
2480
|
-
"1080p": 1.5,
|
|
2481
|
-
"4k": 3
|
|
2482
|
-
};
|
|
2483
|
-
var GEMINI_OMNI_DEFAULT_RESOLUTION = "720p";
|
|
2484
|
-
var GEMINI_OMNI_OVERHEAD_TOKENS = 600;
|
|
2485
|
-
var GEMINI_OMNI_WINDOW_SECONDS = 10;
|
|
2486
|
-
var GEMINI_OMNI_USD_PER_SECOND = GEMINI_OMNI_VIDEO_TOKENS_PER_SECOND * GEMINI_OMNI_USD_PER_1M_VIDEO_TOKENS / 1e6;
|
|
2487
|
-
function geminiOmniUsdPerSecond(resolution) {
|
|
2488
|
-
const multiplier = GEMINI_OMNI_RESOLUTION_MULTIPLIER[resolution ?? GEMINI_OMNI_DEFAULT_RESOLUTION] ?? 1;
|
|
2489
|
-
return GEMINI_OMNI_USD_PER_SECOND * multiplier;
|
|
2490
|
-
}
|
|
2491
|
-
var VIDEO_SOURCE_COST_MULTIPLIER = 2.5;
|
|
2492
|
-
var FAL_SEEDANCE_USD_PER_1K_TOKENS = 0.0214;
|
|
2493
|
-
var SEEDANCE_SOURCE_CLIP_DISCOUNT = 0.6;
|
|
2494
|
-
var SEEDANCE_DEAREST_FRAME = {
|
|
2495
|
-
"480p": { width: 992, height: 432 },
|
|
2496
|
-
"720p": { width: 1112, height: 834 }
|
|
2497
|
-
};
|
|
2498
|
-
function falSeedanceUsdPerSecond(resolution, buildsOnSourceClip = false) {
|
|
2499
|
-
const frame = SEEDANCE_DEAREST_FRAME[resolution ?? DEFAULT_VIDEO_RESOLUTION] ?? SEEDANCE_DEAREST_FRAME["720p"];
|
|
2500
|
-
const tokensPerSecond = (frame?.width ?? 1112) * (frame?.height ?? 834) * 24 / 1024;
|
|
2501
|
-
const rate = tokensPerSecond * FAL_SEEDANCE_USD_PER_1K_TOKENS / 1e3;
|
|
2502
|
-
return buildsOnSourceClip ? rate * SEEDANCE_SOURCE_CLIP_DISCOUNT : rate;
|
|
2503
|
-
}
|
|
2504
|
-
function geminiOmniCostUsd(model, duration, resolution) {
|
|
2505
|
-
const tier = isGeminiOmniPreviewModel(model) ? GEMINI_OMNI_DEFAULT_RESOLUTION : resolution;
|
|
2506
|
-
const footage = geminiOmniUsdPerSecond(tier) * (duration ?? GEMINI_OMNI_WINDOW_SECONDS);
|
|
2507
|
-
return footage + GEMINI_OMNI_OVERHEAD_TOKENS * GEMINI_OMNI_USD_PER_1M_VIDEO_TOKENS / 1e6;
|
|
2508
|
-
}
|
|
2509
|
-
function seedance20CostUsd(resolution, seconds, mayRouteToFal) {
|
|
2510
|
-
const viaReplicate = seedanceUsdPerSecond(resolution) * seconds;
|
|
2511
|
-
if (!mayRouteToFal) return viaReplicate;
|
|
2512
|
-
const falTier = resolution === "480p" || resolution === "720p" ? resolution : void 0;
|
|
2513
|
-
return Math.max(viaReplicate, falSeedanceUsdPerSecond(falTier) * seconds);
|
|
2514
|
-
}
|
|
2515
|
-
function estimateVideoCostUsd(input) {
|
|
2516
|
-
const { model, duration, resolution, generateAudio, buildsOnSourceClip } = input;
|
|
2517
|
-
const seconds = billedSeconds(model, duration ?? DEFAULT_VIDEO_DURATION_S);
|
|
2518
|
-
const sourceClipPremium = buildsOnSourceClip ? VIDEO_SOURCE_COST_MULTIPLIER : 1;
|
|
2519
|
-
if (isGeminiOmniModel(model)) return geminiOmniCostUsd(model, duration, resolution);
|
|
2520
|
-
if (isSeedance25Model(model)) {
|
|
2521
|
-
const viaOpenRouter = seedance25UsdPerSecond(resolution) * seconds * sourceClipPremium;
|
|
2522
|
-
if (!input.mayRouteToFal) return viaOpenRouter;
|
|
2523
|
-
return Math.max(viaOpenRouter, falSeedanceUsdPerSecond(resolution, buildsOnSourceClip) * seconds);
|
|
2524
|
-
}
|
|
2525
|
-
if (isSeedanceModel(model)) return seedance20CostUsd(resolution, seconds, input.mayRouteToFal === true);
|
|
2526
|
-
const published = perSecondBilling(model)?.usd;
|
|
2527
|
-
if (published) {
|
|
2528
|
-
const rate = (resolution ? published.byResolution?.[resolution] : void 0) ?? published;
|
|
2529
|
-
return (generateAudio ? rate.audio : rate.silent) * seconds;
|
|
2530
|
-
}
|
|
2531
|
-
const dearestKnownRate = Math.max(...Object.values(SEEDANCE_USD_PER_SECOND));
|
|
2532
|
-
return dearestKnownRate * seconds;
|
|
2533
|
-
}
|
|
2534
|
-
function estimateVideoCredits(input) {
|
|
2535
|
-
return usdToCredits(estimateVideoCostUsd(input));
|
|
2536
|
-
}
|
|
2537
|
-
|
|
2538
|
-
// ../../node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/esm/wrapper.js
|
|
2539
|
-
var import__ = __toESM(require_safe_stable_stringify(), 1);
|
|
2540
|
-
var configure = import__.default.configure;
|
|
2541
|
-
var wrapper_default = import__.default;
|
|
2542
|
-
|
|
2543
|
-
// ../canvas-contract/src/canonical.ts
|
|
2544
|
-
function canonicalize(value) {
|
|
2545
|
-
const normalized = normalizeForCanonical(value);
|
|
2546
|
-
const out = wrapper_default(normalized);
|
|
2547
|
-
if (out === void 0) {
|
|
2548
|
-
throw new Error("canonicalize: value serialized to undefined (top-level undefined?)");
|
|
2549
|
-
}
|
|
2550
|
-
return out;
|
|
2551
|
-
}
|
|
2552
|
-
function normalizeForCanonical(value) {
|
|
2553
|
-
if (value === null) return null;
|
|
2554
|
-
if (typeof value === "string") return value.normalize("NFC");
|
|
2555
|
-
if (typeof value === "number") {
|
|
2556
|
-
if (!Number.isFinite(value)) {
|
|
2557
|
-
throw new Error(`canonicalize: non-finite number ${value}`);
|
|
2558
|
-
}
|
|
2559
|
-
return value;
|
|
2560
|
-
}
|
|
2561
|
-
if (typeof value === "boolean") return value;
|
|
2562
|
-
if (typeof value === "bigint") {
|
|
2563
|
-
throw new Error("canonicalize: bigint not supported");
|
|
2564
|
-
}
|
|
2565
|
-
if (Array.isArray(value)) {
|
|
2566
|
-
return value.map(normalizeForCanonical);
|
|
2567
|
-
}
|
|
2568
|
-
if (typeof value === "object") {
|
|
2569
|
-
const out = {};
|
|
2570
|
-
for (const [k, v] of Object.entries(value)) {
|
|
2571
|
-
if (v === void 0) continue;
|
|
2572
|
-
out[k.normalize("NFC")] = normalizeForCanonical(v);
|
|
2573
|
-
}
|
|
2574
|
-
return out;
|
|
2575
|
-
}
|
|
2576
|
-
return void 0;
|
|
2577
|
-
}
|
|
2578
|
-
|
|
2579
|
-
// ../canvas-contract/src/clipWeight.ts
|
|
2580
|
-
var MB_PER_SECOND_720P = 2.13;
|
|
2581
|
-
var RESOLUTION_WEIGHT = {
|
|
2582
|
-
"360p": 0.25,
|
|
2583
|
-
"480p": 0.44,
|
|
2584
|
-
"720p": 1,
|
|
2585
|
-
"1080p": 2.25,
|
|
2586
|
-
"4k": 9,
|
|
2587
|
-
"4K": 9
|
|
2588
|
-
};
|
|
2589
|
-
var MAX_CLIP_INGEST_MB = 120;
|
|
2590
|
-
function estimateClipMb(durationSeconds, resolution) {
|
|
2591
|
-
const weight = RESOLUTION_WEIGHT[resolution ?? "720p"] ?? 1;
|
|
2592
|
-
return durationSeconds * MB_PER_SECOND_720P * weight;
|
|
2593
|
-
}
|
|
2594
|
-
function clipTooHeavyToIngest(durationSeconds, resolution) {
|
|
2595
|
-
if (!durationSeconds) return null;
|
|
2596
|
-
const mb = estimateClipMb(durationSeconds, resolution);
|
|
2597
|
-
if (mb <= MAX_CLIP_INGEST_MB) return null;
|
|
2598
|
-
const fits = Math.floor(MAX_CLIP_INGEST_MB / (estimateClipMb(1, resolution) || 1));
|
|
2599
|
-
return `A ${durationSeconds}s clip at ${resolution ?? "720p"} comes to roughly ${Math.round(mb)} MB, more than the ${MAX_CLIP_INGEST_MB} MB we can take in \u2014 it would render, bill, and then fail on the way into the library. Shorten it to about ${fits}s at this resolution, or drop the resolution and keep the length.`;
|
|
2600
|
-
}
|
|
2601
|
-
|
|
2602
|
-
// ../canvas-contract/src/frameRealism.ts
|
|
2603
|
-
function frameRealismDirection(opts = {}) {
|
|
2604
|
-
return " Everything obeys real-world physics: paper, card and screens are OPAQUE with nothing showing through from behind, every object is at believable real-world scale next to the people handling it, and every object has its real-world form and construction \u2014 a phone has ONE screen and it is on the front." + // The worst of the three failures behind this, because the viewer reads the number: a
|
|
2605
|
-
// model invents one whenever a screen or a document is in shot, and it contradicts the
|
|
2606
|
-
// script it sits under. Frames simply do not get legible text; the captions carry the
|
|
2607
|
-
// numbers.
|
|
2608
|
-
//
|
|
2609
|
-
// Default ON, and asked for explicitly rather than inferred: an ad frame with no
|
|
2610
|
-
// person in it still sits under a script for an invented number to argue with. Only a
|
|
2611
|
-
// plain Studio picture opts out — it has no script, and it may BE the poster somebody
|
|
2612
|
-
// asked for, which the model picker sells GPT Image 2.5 on being able to render.
|
|
2613
|
-
(opts.readableText === "allowed" ? "" : " NO readable text or numbers anywhere in frame \u2014 phone screens, documents and signage stay illegible or out of focus, because any figure the model invents will contradict the script.") + // Measured: one finished ad reported malformed hands or limbs in 8 of 12 sampled frames;
|
|
2614
|
-
// another, a woman with an extra right arm and an unattached hand gripping a panel.
|
|
2615
|
-
// Fiddly work at close range is where a video model breaks, every time.
|
|
2616
|
-
" Hands are kept simple: no close-up of fingers manipulating small parts, no hand gripping the edge of an object, and each person has exactly TWO arms and TWO legs, all attached and all visible or all out of frame. Anyone working does so the way the trade actually does it: nobody stands or kneels on the equipment being installed, nothing is fitted overhanging an edge or floating unsupported, and every part rests on the structure that would really carry it." + // The newest clause, and the one no route had. A testimonial came back with the customer
|
|
2617
|
-
// repairing the panel herself: nothing said she was not the installer, so the model cast
|
|
2618
|
-
// her as one. Who someone IS in the picture has to be stated, or it is guessed.
|
|
2619
|
-
(opts.role ? ` The person on camera is ${opts.role} \u2014 they are shown as that and never doing somebody else's job.` : "") + (opts.currency ? ` If a currency is unavoidably visible it is ${opts.currency}.` : "");
|
|
2620
|
-
}
|
|
2621
|
-
|
|
2622
|
-
// ../canvas-contract/src/nodeCost.ts
|
|
2623
|
-
var ELEVENLABS_USD_PER_CHARACTER = 22e-5;
|
|
2624
|
-
var ELEVENLABS_MUSIC_USD_PER_SECOND = 0.022;
|
|
2625
|
-
var ELEVENLABS_SOUND_EFFECT_USD_PER_SECOND = 0.022;
|
|
2626
|
-
var ELEVENLABS_STS_USD_PER_MINUTE = 1e3 * ELEVENLABS_USD_PER_CHARACTER;
|
|
2627
|
-
var FALAI_LIPSYNC_PER_MIN_USD = 0.4;
|
|
2628
|
-
var FALAI_VIDEO_BG_REMOVE_REFINED_USD_PER_30_FRAMES = 0.012;
|
|
2629
|
-
var FALAI_VIDEO_BG_REMOVE_FAST_USD_PER_30_FRAMES = 8e-3;
|
|
2630
|
-
var FALAI_IMAGE_BG_REMOVE_USD_PER_CALL = 1e-3;
|
|
2631
|
-
var GROQ_WHISPER_COST_PER_HOUR = 0.04;
|
|
2632
|
-
var GROQ_WHISPER_MINIMUM_SECONDS = 10;
|
|
2633
|
-
var DEEPGRAM_NOVA3_COST_PER_MINUTE = 43e-4;
|
|
2634
|
-
var FIRECRAWL_COST_PER_SCRAPE = 1e-3;
|
|
2635
|
-
var DEFAULT_MUSIC_SECONDS = 30;
|
|
2636
|
-
var DEFAULT_SOUND_EFFECT_SECONDS = 5;
|
|
2637
|
-
var DEFAULT_BACKGROUND_REMOVE_SECONDS = 30;
|
|
2638
|
-
var DEFAULT_MEDIA_SECONDS = 60;
|
|
2639
|
-
function ttsCharactersUsd(characters) {
|
|
2640
|
-
return characters * ELEVENLABS_USD_PER_CHARACTER;
|
|
2641
|
-
}
|
|
2642
|
-
function musicSecondsUsd(seconds) {
|
|
2643
|
-
return seconds * ELEVENLABS_MUSIC_USD_PER_SECOND;
|
|
2644
|
-
}
|
|
2645
|
-
function soundEffectSecondsUsd(seconds) {
|
|
2646
|
-
return seconds * ELEVENLABS_SOUND_EFFECT_USD_PER_SECOND;
|
|
2647
|
-
}
|
|
2648
|
-
function voiceConvertMinutes(durationMs) {
|
|
2649
|
-
return Math.max(durationMs / 6e4, 0.1);
|
|
2650
|
-
}
|
|
2651
|
-
function voiceConvertUsd(minutes) {
|
|
2652
|
-
return minutes * ELEVENLABS_STS_USD_PER_MINUTE;
|
|
2653
|
-
}
|
|
2654
|
-
function lipsyncMinutes(audioMs, videoMs) {
|
|
2655
|
-
const durationMs = Math.max(audioMs ?? 0, videoMs ?? 0);
|
|
2656
|
-
return durationMs > 0 ? durationMs / 6e4 : 1;
|
|
2657
|
-
}
|
|
2658
|
-
function lipsyncUsd(minutes) {
|
|
2659
|
-
return minutes * FALAI_LIPSYNC_PER_MIN_USD;
|
|
2660
|
-
}
|
|
2661
|
-
function backgroundRemoveFrames(durationSeconds) {
|
|
2662
|
-
return Math.max(30, Math.ceil((durationSeconds ?? DEFAULT_BACKGROUND_REMOVE_SECONDS) * 30));
|
|
2663
|
-
}
|
|
2664
|
-
function videoBackgroundRemoveUsd(durationSeconds, edgeRefinement) {
|
|
2665
|
-
const unit = edgeRefinement ? FALAI_VIDEO_BG_REMOVE_REFINED_USD_PER_30_FRAMES : FALAI_VIDEO_BG_REMOVE_FAST_USD_PER_30_FRAMES;
|
|
2666
|
-
return backgroundRemoveFrames(durationSeconds) / 30 * unit;
|
|
2667
|
-
}
|
|
2668
|
-
function transcriptionUsd(transcriber, seconds) {
|
|
2669
|
-
if (seconds <= 0) return 0;
|
|
2670
|
-
if (transcriber === "deepgram") return seconds / 60 * DEEPGRAM_NOVA3_COST_PER_MINUTE;
|
|
2671
|
-
return Math.max(seconds, GROQ_WHISPER_MINIMUM_SECONDS) / 3600 * GROQ_WHISPER_COST_PER_HOUR;
|
|
2672
|
-
}
|
|
2673
|
-
function asBag(value) {
|
|
2674
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
2675
|
-
}
|
|
2676
|
-
function num(value) {
|
|
2677
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
2678
|
-
}
|
|
2679
|
-
function inputDurationMs(inputs, slot) {
|
|
2680
|
-
const ref = asBag(inputs[slot]);
|
|
2681
|
-
return num(ref.duration_ms) ?? num(asBag(ref.metadata).duration_ms);
|
|
2682
|
-
}
|
|
2683
|
-
function slotCount(inputs, slot) {
|
|
2684
|
-
const value = inputs[slot];
|
|
2685
|
-
if (Array.isArray(value)) return value.length;
|
|
2686
|
-
return value ? 1 : 0;
|
|
2687
|
-
}
|
|
2688
|
-
function textLength(value) {
|
|
2689
|
-
return typeof value === "string" ? value.length : 0;
|
|
2690
|
-
}
|
|
2691
|
-
function estimateVideoGenerateUsd(params, inputs, preferFal) {
|
|
2692
|
-
const model = params.model;
|
|
2693
|
-
if (typeof model !== "string") return null;
|
|
2694
|
-
const referenceOnly = slotCount(inputs, "references") > 0 && !inputs.first_frame;
|
|
2695
|
-
return estimateVideoCostUsd({
|
|
2696
|
-
model,
|
|
2697
|
-
duration: num(params.duration),
|
|
2698
|
-
resolution: typeof params.resolution === "string" ? params.resolution : void 0,
|
|
2699
|
-
generateAudio: typeof params.generate_audio === "boolean" ? params.generate_audio : void 0,
|
|
2700
|
-
buildsOnSourceClip: slotCount(inputs, "video_references") > 0,
|
|
2701
|
-
mayRouteToFal: isSeedanceModel(model) && (preferFal || referenceOnly)
|
|
2702
|
-
});
|
|
2703
|
-
}
|
|
2704
|
-
function estimateMusicUsd(params, inputs) {
|
|
2705
|
-
const pinnedMs = num(params.music_length_ms);
|
|
2706
|
-
const scoredMs = params.model === "elevenlabs/video-background-music-v1" ? inputDurationMs(inputs, "video") : void 0;
|
|
2707
|
-
const seconds = (pinnedMs ?? scoredMs ?? DEFAULT_MUSIC_SECONDS * 1e3) / 1e3;
|
|
2708
|
-
return musicSecondsUsd(seconds);
|
|
2709
|
-
}
|
|
2710
|
-
function estimateDialogueUsd(params) {
|
|
2711
|
-
if (!Array.isArray(params.inputs)) return null;
|
|
2712
|
-
const characters = params.inputs.reduce((sum, line) => sum + textLength(asBag(line).text), 0);
|
|
2713
|
-
return ttsCharactersUsd(characters);
|
|
2714
|
-
}
|
|
2715
|
-
function estimateNodeCostUsd(input) {
|
|
2716
|
-
const params = asBag(input.params);
|
|
2717
|
-
const inputs = asBag(input.inputs);
|
|
2718
|
-
switch (input.nodeType) {
|
|
2719
|
-
case "video_generate":
|
|
2720
|
-
return estimateVideoGenerateUsd(params, inputs, input.preferFal === true);
|
|
2721
|
-
case "tts":
|
|
2722
|
-
return typeof params.text === "string" ? ttsCharactersUsd(params.text.length) : null;
|
|
2723
|
-
case "dialogue":
|
|
2724
|
-
return estimateDialogueUsd(params);
|
|
2725
|
-
case "music":
|
|
2726
|
-
return estimateMusicUsd(params, inputs);
|
|
2727
|
-
case "sound_effect":
|
|
2728
|
-
return soundEffectSecondsUsd(num(params.duration_seconds) ?? DEFAULT_SOUND_EFFECT_SECONDS);
|
|
2729
|
-
case "audio_voice_convert": {
|
|
2730
|
-
const ms = inputDurationMs(inputs, "audio") ?? DEFAULT_MEDIA_SECONDS * 1e3;
|
|
2731
|
-
return voiceConvertUsd(voiceConvertMinutes(ms));
|
|
2732
|
-
}
|
|
2733
|
-
case "video_lipsync":
|
|
2734
|
-
return lipsyncUsd(lipsyncMinutes(inputDurationMs(inputs, "audio"), inputDurationMs(inputs, "video")));
|
|
2735
|
-
case "video_background_remove": {
|
|
2736
|
-
const ms = inputDurationMs(inputs, "video");
|
|
2737
|
-
return videoBackgroundRemoveUsd(ms === void 0 ? void 0 : ms / 1e3, params.edge_refinement !== false);
|
|
2738
|
-
}
|
|
2739
|
-
case "image_background_remove":
|
|
2740
|
-
return FALAI_IMAGE_BG_REMOVE_USD_PER_CALL;
|
|
2741
|
-
case "video_transcribe": {
|
|
2742
|
-
const ms = inputDurationMs(inputs, "video") ?? DEFAULT_MEDIA_SECONDS * 1e3;
|
|
2743
|
-
return transcriptionUsd(params.transcriber === "deepgram" ? "deepgram" : "groq", ms / 1e3);
|
|
2744
|
-
}
|
|
2745
|
-
case "ingest":
|
|
2746
|
-
return params.strategy === "firecrawl" ? FIRECRAWL_COST_PER_SCRAPE : 0;
|
|
2747
|
-
case "voice_select":
|
|
2748
|
-
case "load_artifact":
|
|
2749
|
-
case "save_artifact":
|
|
2750
|
-
case "resize":
|
|
2751
|
-
case "crop":
|
|
2752
|
-
return 0;
|
|
2753
|
-
default:
|
|
2754
|
-
return null;
|
|
2755
|
-
}
|
|
2756
|
-
}
|
|
2757
|
-
function estimateNodeCredits(input) {
|
|
2758
|
-
const usd = estimateNodeCostUsd(input);
|
|
2759
|
-
return usd === null ? null : usdToCredits(usd);
|
|
2760
|
-
}
|
|
2761
|
-
|
|
2762
|
-
// ../canvas-contract/src/personRealism.ts
|
|
2763
|
-
var PHONE_CAMERA = "Shot on a phone, an iPhone or a Samsung Galaxy, with the main camera in the default photo mode (not portrait mode): slightly wide angle, held by a friend about a metre away or at arm's length, the background mostly in focus the way phone photos are, the phone's own processing \u2014 HDR evening out a bright window, a touch of over-sharpening, smoothed noise in the shadows, punchy everyday colour. Slightly imperfect framing. Not a professional camera: no bokeh or creamy background blur, no lens compression, no studio or flash lighting, no colour grade.";
|
|
2764
|
-
var REAL_SKIN = "Real skin and a real face: visible pores, fine lines, uneven tone, small marks, stray hairs, slight asymmetry. Clothes with real creases.";
|
|
2765
|
-
var NOT_A_MODEL = "Not stock photography, not a model or an influencer: no beauty retouching, no glowing or plastic skin, no perfectly symmetrical features.";
|
|
2766
|
-
function candidPersonPortraitPrompt(p) {
|
|
2767
|
-
return [
|
|
2768
|
-
`An unretouched candid phone photo of one ordinary, real person: ${p.subject}`,
|
|
2769
|
-
p.wardrobe?.trim() ? `Wearing: ${p.wardrobe.trim()}` : null,
|
|
2770
|
-
`Where: ${p.setting?.trim() || "an everyday place that fits who they are, in daylight"}, available light only. They look toward the lens mid-conversation with a relaxed, unposed expression. Framed from the head to mid-torso, face clearly visible.`,
|
|
2771
|
-
PHONE_CAMERA,
|
|
2772
|
-
REAL_SKIN,
|
|
2773
|
-
NOT_A_MODEL,
|
|
2774
|
-
"No text, logos or watermarks. One person only."
|
|
2775
|
-
].filter((line) => line !== null).join("\n");
|
|
2776
|
-
}
|
|
2777
|
-
|
|
2778
|
-
// ../canvas-contract/src/validateParams.ts
|
|
2779
|
-
function isManagedNodeKind(nodeType) {
|
|
2780
|
-
return Object.keys(MODEL_REGISTRY).includes(nodeType);
|
|
2781
|
-
}
|
|
2782
|
-
function checkRequiredParams(spec, params, model) {
|
|
2783
|
-
const errors = [];
|
|
2784
|
-
for (const req of spec.required) {
|
|
2785
|
-
if (params[req] === void 0 || params[req] === null) {
|
|
2786
|
-
errors.push({
|
|
2787
|
-
code: "missing_required_param",
|
|
2788
|
-
param: req,
|
|
2789
|
-
message: `missing required param "${req}" for model "${model}"`
|
|
2790
|
-
});
|
|
2791
|
-
}
|
|
2792
|
-
}
|
|
2793
|
-
return errors;
|
|
2794
|
-
}
|
|
2795
|
-
function checkParamValues(spec, params, model) {
|
|
2796
|
-
const errors = [];
|
|
2797
|
-
for (const [key, value] of Object.entries(params)) {
|
|
2798
|
-
if (key === "model") continue;
|
|
2799
|
-
if (value === void 0) continue;
|
|
2800
|
-
const schema = spec.params[key];
|
|
2801
|
-
if (!schema) {
|
|
2802
|
-
errors.push({
|
|
2803
|
-
code: "unknown_param",
|
|
2804
|
-
param: key,
|
|
2805
|
-
message: `param "${key}" is not supported by model "${model}"`
|
|
2806
|
-
});
|
|
2807
|
-
continue;
|
|
2808
|
-
}
|
|
2809
|
-
const valueErr = validateValue(key, value, schema, model);
|
|
2810
|
-
if (valueErr) errors.push(valueErr);
|
|
2811
|
-
}
|
|
2812
|
-
return errors;
|
|
2813
|
-
}
|
|
2814
|
-
function validateModelParams(nodeType, model, params) {
|
|
2815
|
-
const spec = MODEL_REGISTRY[nodeType][canonicalModelId(model)];
|
|
2816
|
-
if (!spec) {
|
|
2817
|
-
return {
|
|
2818
|
-
ok: false,
|
|
2819
|
-
errors: [{ code: "unknown_model", message: `unknown model "${model}" for node "${nodeType}"` }]
|
|
2820
|
-
};
|
|
2821
|
-
}
|
|
2822
|
-
const fitted = canonicalModelParams(nodeType, { ...params, model });
|
|
2823
|
-
const errors = [...checkRequiredParams(spec, fitted, model), ...checkParamValues(spec, fitted, model)];
|
|
2824
|
-
if (errors.length > 0) return { ok: false, errors };
|
|
2825
|
-
if (nodeType === "video_generate") {
|
|
2826
|
-
const tooHeavy = clipTooHeavyToIngest(
|
|
2827
|
-
typeof params.duration === "number" ? params.duration : void 0,
|
|
2828
|
-
typeof params.resolution === "string" ? params.resolution : void 0
|
|
2829
|
-
);
|
|
2830
|
-
if (tooHeavy) return { ok: false, errors: [{ code: "clip_too_heavy", message: tooHeavy }] };
|
|
2831
|
-
}
|
|
2832
|
-
return { ok: true };
|
|
2833
|
-
}
|
|
2834
|
-
function validateModelInputs(nodeType, model, providedKinds) {
|
|
2835
|
-
const spec = MODEL_REGISTRY[nodeType][canonicalModelId(model)];
|
|
2836
|
-
if (!spec) {
|
|
2837
|
-
return {
|
|
2838
|
-
ok: false,
|
|
2839
|
-
errors: [{ code: "unknown_model", message: `unknown model "${model}" for node "${nodeType}"` }]
|
|
2840
|
-
};
|
|
2841
|
-
}
|
|
2842
|
-
const have = new Set(providedKinds);
|
|
2843
|
-
const errors = [];
|
|
2844
|
-
for (const inputSpec of spec.inputs) {
|
|
2845
|
-
if (!have.has(inputSpec.kind)) {
|
|
2846
|
-
errors.push({
|
|
2847
|
-
code: "missing_input",
|
|
2848
|
-
input: inputSpec.kind,
|
|
2849
|
-
message: `model "${model}" requires input of kind "${inputSpec.kind}"`
|
|
2850
|
-
});
|
|
2851
|
-
}
|
|
2852
|
-
}
|
|
2853
|
-
if (errors.length > 0) return { ok: false, errors };
|
|
2854
|
-
return { ok: true };
|
|
2855
|
-
}
|
|
2856
|
-
function validateStringValue(key, value, schema, model) {
|
|
2857
|
-
if (typeof value !== "string") {
|
|
2858
|
-
return { code: "invalid_value", param: key, message: `${key}: expected string, got ${typeof value}` };
|
|
2859
|
-
}
|
|
2860
|
-
if (schema.enum && !schema.enum.includes(value)) {
|
|
2861
|
-
return {
|
|
2862
|
-
code: "invalid_value",
|
|
2863
|
-
param: key,
|
|
2864
|
-
message: `${key}: "${value}" not allowed by "${model}" (allowed: ${schema.enum.join(", ")})`
|
|
2865
|
-
};
|
|
2866
|
-
}
|
|
2867
|
-
if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
|
|
2868
|
-
return {
|
|
2869
|
-
code: "invalid_value",
|
|
2870
|
-
param: key,
|
|
2871
|
-
message: `${key}: ${value.length} characters exceeds max ${schema.maxLength} for "${model}"`
|
|
2872
|
-
};
|
|
2873
|
-
}
|
|
2874
|
-
return null;
|
|
2875
|
-
}
|
|
2876
|
-
function validateNumberValue(key, value, schema, model) {
|
|
2877
|
-
if (typeof value !== "number" || Number.isNaN(value)) {
|
|
2878
|
-
return { code: "invalid_value", param: key, message: `${key}: expected number, got ${typeof value}` };
|
|
2879
|
-
}
|
|
2880
|
-
if (schema.enum && !schema.enum.includes(value)) {
|
|
2881
|
-
return {
|
|
2882
|
-
code: "invalid_value",
|
|
2883
|
-
param: key,
|
|
2884
|
-
message: `${key}: ${value} not allowed by "${model}" (allowed: ${schema.enum.join(", ")})`
|
|
2885
|
-
};
|
|
2886
|
-
}
|
|
2887
|
-
if (schema.integer && !Number.isInteger(value)) {
|
|
2888
|
-
return { code: "invalid_value", param: key, message: `${key}: ${value} must be a whole number` };
|
|
2889
|
-
}
|
|
2890
|
-
if (schema.min !== void 0 && value < schema.min) {
|
|
2891
|
-
return { code: "invalid_value", param: key, message: `${key}: ${value} below min ${schema.min}` };
|
|
2892
|
-
}
|
|
2893
|
-
if (schema.max !== void 0 && value > schema.max) {
|
|
2894
|
-
return { code: "invalid_value", param: key, message: `${key}: ${value} above max ${schema.max}` };
|
|
2895
|
-
}
|
|
2896
|
-
return null;
|
|
2897
|
-
}
|
|
2898
|
-
function validateValue(key, value, schema, model) {
|
|
2899
|
-
switch (schema.kind) {
|
|
2900
|
-
case "string":
|
|
2901
|
-
return validateStringValue(key, value, schema, model);
|
|
2902
|
-
case "number":
|
|
2903
|
-
return validateNumberValue(key, value, schema, model);
|
|
2904
|
-
case "boolean":
|
|
2905
|
-
if (typeof value !== "boolean") {
|
|
2906
|
-
return { code: "invalid_value", param: key, message: `${key}: expected boolean, got ${typeof value}` };
|
|
2907
|
-
}
|
|
2908
|
-
return null;
|
|
2909
|
-
case "json":
|
|
2910
|
-
return null;
|
|
2911
|
-
default: {
|
|
2912
|
-
const _exhaustive = schema;
|
|
2913
|
-
return _exhaustive;
|
|
2914
|
-
}
|
|
2915
|
-
}
|
|
2916
|
-
}
|
|
2917
|
-
|
|
2918
|
-
// ../canvas-contract/src/videoBlueprint.ts
|
|
2919
|
-
import { z } from "zod";
|
|
2920
|
-
var FrameAssetSchema = z.object({ url: z.string().optional() }).loose().optional();
|
|
2921
|
-
var BlueprintDialogueLineSchema = z.object({
|
|
2922
|
-
speaker: z.string().optional(),
|
|
2923
|
-
line: z.string().optional(),
|
|
2924
|
-
// Absolute seconds on the source timeline (the deconstruct emits both).
|
|
2925
|
-
start_s: z.number().optional(),
|
|
2926
|
-
end_s: z.number().optional(),
|
|
2927
|
-
delivery: z.string().optional(),
|
|
2928
|
-
voice_description: z.string().optional(),
|
|
2929
|
-
// DECON-supplied: is this speaker's FACE visibly speaking in THIS scene? Element
|
|
2930
|
-
// presence alone can't answer that — a founder pictured in a polaroid close-up is
|
|
2931
|
-
// "present" yet the line is voiceover, and treating it as on-camera produced a
|
|
2932
|
-
// native Seedance lip-sync clip of a still photograph. `false` pins the line to
|
|
2933
|
-
// the VO path; absent keeps the presence-based decision (old blueprints).
|
|
2934
|
-
on_camera: z.boolean().optional()
|
|
2935
|
-
}).loose();
|
|
2936
|
-
var SfxSchema = z.object({
|
|
2937
|
-
at_s: z.number().optional(),
|
|
2938
|
-
duration_s: z.number().optional(),
|
|
2939
|
-
sound_effect_prompt: z.string().optional(),
|
|
2940
|
-
description: z.string().optional()
|
|
2941
|
-
}).loose();
|
|
2942
|
-
var CompositionRegionSchema = z.object({
|
|
2943
|
-
// full | top | bottom | left | right | inset
|
|
2944
|
-
panel: z.string().optional(),
|
|
2945
|
-
// 9-grid anchor for an `inset` presenter box.
|
|
2946
|
-
position: z.string().optional(),
|
|
2947
|
-
is_presenter: z.boolean().optional(),
|
|
2948
|
-
// The cast id shown/speaking in this region (routes lip-sync + element refs).
|
|
2949
|
-
cast_ref: z.string().optional(),
|
|
2950
|
-
// What the region's content IS: camera | screen_capture | static_graphic |
|
|
2951
|
-
// generated. Authoritative for routing when present (regex-over-prose fallback
|
|
2952
|
-
// otherwise): screen_capture/static_graphic are rebuilt from REAL surfaces on the
|
|
2953
|
-
// overlay layer, never AI-generated.
|
|
2954
|
-
kind: z.string().optional(),
|
|
2955
|
-
// Opaque id naming the SPECIFIC on-screen document/note/app-state this
|
|
2956
|
-
// screen_capture region shows. Two scenes share it only when they show the SAME
|
|
2957
|
-
// recording continuing (scrolling/typing/waiting within it) — a genuinely
|
|
2958
|
-
// DIFFERENT document/note/recording (a source video splicing two screen captures)
|
|
2959
|
-
// gets a different id. Breaks a persistent-layout run into separate surface stubs
|
|
2960
|
-
// instead of asking the operator for one screenshot that can't cover both.
|
|
2961
|
-
surface_id: z.string().optional(),
|
|
2962
|
-
// Camera bubble(s)/inset(s) embedded INSIDE this region's surface (a Loom-style
|
|
2963
|
-
// presenter bubble inside a screen recording) — video-in-video the reproduction
|
|
2964
|
-
// must re-composite, not paint into the surface.
|
|
2965
|
-
nested: z.array(z.object({}).loose()).optional(),
|
|
2966
|
-
summary: z.string().optional(),
|
|
2967
|
-
frame_prompt: z.string().optional(),
|
|
2968
|
-
motion_prompt: z.string().optional()
|
|
2969
|
-
}).loose();
|
|
2970
|
-
var SceneCompositionSchema = z.object({
|
|
2971
|
-
// full_frame (default) | split_screen | pip | keyed_overlay
|
|
2972
|
-
layout: z.string().optional(),
|
|
2973
|
-
// split_screen only: vertical (top/bottom) | horizontal (left/right).
|
|
2974
|
-
split_axis: z.string().optional(),
|
|
2975
|
-
regions: z.array(CompositionRegionSchema).optional()
|
|
2976
|
-
}).loose();
|
|
2977
|
-
var CameraMotionSchema = z.object({ movement: z.string().optional(), detail: z.string().optional() }).loose();
|
|
2978
|
-
var TranscriptWordSchema = z.object({ text: z.string().optional() }).loose();
|
|
2979
|
-
var SCENE_ROUTE_HINTS = ["brand_card"];
|
|
2980
|
-
var VideoSceneSchema = z.object({
|
|
2981
|
-
start_s: z.number().optional(),
|
|
2982
|
-
end_s: z.number().optional(),
|
|
2983
|
-
duration_s: z.number().optional(),
|
|
2984
|
-
summary: z.string().optional(),
|
|
2985
|
-
action_detail: z.string().optional(),
|
|
2986
|
-
// The scene's spatial layout. Absent/full_frame ⇒ one uncut shot (default path).
|
|
2987
|
-
// A layered layout (split_screen/pip/keyed_overlay) with regions ⇒ the scaffold
|
|
2988
|
-
// builds one clip per region and stacks/overlays them into the scene picture.
|
|
2989
|
-
composition: SceneCompositionSchema.optional(),
|
|
2990
|
-
// The capture "look" for this scene — selected from the ad-native shoot-mode
|
|
2991
|
-
// grammar (the CLI's scaffold/lib/shoot-modes.ts). When absent the scaffold
|
|
2992
|
-
// auto-derives a UGC/product mode; a human can override per scene by setting this.
|
|
2993
|
-
shoot_mode: z.string().optional(),
|
|
2994
|
-
// Diegetic ambient the clip's native audio should carry (no music). When
|
|
2995
|
-
// absent the scene falls back to its shoot mode's default ambience.
|
|
2996
|
-
ambient: z.string().optional(),
|
|
2997
|
-
camera_motion: CameraMotionSchema.optional(),
|
|
2998
|
-
start_frame_prompt: z.string().optional(),
|
|
2999
|
-
end_frame_prompt: z.string().optional(),
|
|
3000
|
-
motion_prompt: z.string().optional(),
|
|
3001
|
-
// The scene's role in the ad's persuasion arc (DECON-supplied); drives the
|
|
3002
|
-
// script re-craft checklist. Inferred from position when absent.
|
|
3003
|
-
narrative_role: z.string().optional(),
|
|
3004
|
-
// See `SceneRouteHint`.
|
|
3005
|
-
route_hint: z.enum(SCENE_ROUTE_HINTS).optional(),
|
|
3006
|
-
// DECON-supplied on the HOOK scene: the engineered physical/emotional state that
|
|
3007
|
-
// makes the first frame stop the scroll (sweaty/breathless/urgent …). Injected
|
|
3008
|
-
// into the hook's start-frame description so the generator renders that state,
|
|
3009
|
-
// not a calm influencer (CCA-11).
|
|
3010
|
-
hook_mechanic: z.object({ mechanic: z.string().optional(), why_it_stops_scroll: z.string().optional() }).loose().optional(),
|
|
3011
|
-
// DECON-supplied per-scene location (so a gym hook isn't flattened to "home").
|
|
3012
|
-
scene_setting: z.string().optional(),
|
|
3013
|
-
// How this scene cuts to the next (DECON-supplied). A recognized non-cut type
|
|
3014
|
-
// (fade/whip/zoom/dissolve/swipe) is reproduced as an ffmpeg xfade at the
|
|
3015
|
-
// boundary; cut/match_cut/none/other stay hard cuts. The last scene's value is
|
|
3016
|
-
// ignored (nothing follows it).
|
|
3017
|
-
transition_out: z.object({ type: z.string().optional(), description: z.string().optional() }).loose().optional(),
|
|
3018
|
-
dialogue: z.array(BlueprintDialogueLineSchema).optional(),
|
|
3019
|
-
sfx: z.array(SfxSchema).optional(),
|
|
3020
|
-
// Parsed element by element where they are read (`BlueprintOverlaySchema`,
|
|
3021
|
-
// `BlueprintFloatingElementSchema`), so one malformed graphic never rejects the scene.
|
|
3022
|
-
overlays: z.array(z.unknown()).optional(),
|
|
3023
|
-
floating_elements: z.array(z.unknown()).optional(),
|
|
3024
|
-
// DECON-supplied: how much the picture itself moves within the shot. Gates the
|
|
3025
|
-
// flash-hold optimization — a sub-2s b-roll flash with REAL subject motion
|
|
3026
|
-
// (pouring, spreading, hands working) must stay a real clip; freezing it turns
|
|
3027
|
-
// a montage into a slideshow. Absent (old blueprints) keeps the cheap still.
|
|
3028
|
-
motion_level: z.enum(["static", "subtle", "dynamic"]).optional(),
|
|
3029
|
-
transcript_slice: z.array(TranscriptWordSchema).optional(),
|
|
3030
|
-
start_frame_asset: FrameAssetSchema,
|
|
3031
|
-
end_frame_asset: FrameAssetSchema,
|
|
3032
|
-
// DECON-supplied: true when this scene is a length-split CONTINUATION of the
|
|
3033
|
-
// previous one (the SAME physical shot, broken up only because it exceeded the
|
|
3034
|
-
// clip ceiling). The scaffold then shares the splice keyframe — this scene's
|
|
3035
|
-
// start frame IS the previous scene's end frame — so the join is seamless.
|
|
3036
|
-
continues_previous: z.boolean().optional()
|
|
3037
|
-
}).loose();
|
|
3038
|
-
var VideoBlueprintSchema = z.object({
|
|
3039
|
-
source: z.object({ aspect_ratio: z.string().optional(), duration_s: z.number().optional() }).loose().optional(),
|
|
3040
|
-
global: z.object({
|
|
3041
|
-
music: z.object({
|
|
3042
|
-
present: z.boolean().optional(),
|
|
3043
|
-
music_prompt: z.string().optional(),
|
|
3044
|
-
// Absolute second the music enters in the reference (the bed often
|
|
3045
|
-
// kicks in mid-ad, after the hook). We start the regenerated track here
|
|
3046
|
-
// instead of at 0 so the timing matches.
|
|
3047
|
-
starts_at_s: z.number().optional(),
|
|
3048
|
-
// Populated by the deconstruct when AudD (Shazam-style) recognizes the
|
|
3049
|
-
// reference track. We never reuse it — only style the regenerated bed.
|
|
3050
|
-
identified_track: z.object({ title: z.string().optional(), artist: z.string().optional() }).loose().nullish()
|
|
3051
|
-
}).loose().optional(),
|
|
3052
|
-
cast: z.array(
|
|
3053
|
-
z.object({
|
|
3054
|
-
id: z.string().optional(),
|
|
3055
|
-
description: z.string().optional(),
|
|
3056
|
-
// The deconstruct's note on the target-market localization (e.g. "native
|
|
3057
|
-
// French speaker") — read to derive the spoken-track language code.
|
|
3058
|
-
market_localization_note: z.string().optional()
|
|
3059
|
-
}).loose()
|
|
3060
|
-
).optional(),
|
|
3061
|
-
voiceover: z.object({
|
|
3062
|
-
// on_camera | mixed → mouths are on screen (lip-sync candidates);
|
|
3063
|
-
// voiceover | none → narration over the picture (no lip-sync).
|
|
3064
|
-
mode: z.string().optional(),
|
|
3065
|
-
// Which variety of the language the speech is in. Stated because the model
|
|
3066
|
-
// picks one otherwise: ads set in Spain came back in Latin American Spanish,
|
|
3067
|
-
// and the pinned peninsular voice could not undo it — the re-voicing is
|
|
3068
|
-
// speech-to-speech, so it carries the accent across and swaps only the timbre.
|
|
3069
|
-
accent: z.string().optional(),
|
|
3070
|
-
voice_description: z.string().optional(),
|
|
3071
|
-
persona: z.string().optional()
|
|
3072
|
-
}).loose().optional(),
|
|
3073
|
-
// Visual palette — read only to colour a clean brand-card/CTA plate (the
|
|
3074
|
-
// first hex is the dominant brand colour); never to drive frame generation.
|
|
3075
|
-
style: z.object({ palette: z.array(z.object({ hex: z.string().optional() }).loose()).optional() }).loose().optional(),
|
|
3076
|
-
// Written by `scaffold-ad` (the deconstruct names its own fields, e.g. `branding.brand_name`):
|
|
3077
|
-
// the whole script as one string, where the ad is set, and the brand it closes on.
|
|
3078
|
-
transcript: z.string().optional(),
|
|
3079
|
-
market: z.string().optional(),
|
|
3080
|
-
branding: z.object({ name: z.string().optional(), logo_path: z.string().optional() }).loose().optional()
|
|
3081
|
-
}).loose().optional(),
|
|
3082
|
-
// Written by `scaffold-ad`: what the beats add up to, so a short ad is caught before it renders.
|
|
3083
|
-
estimated_duration_s: z.number().optional(),
|
|
3084
|
-
scenes: z.array(VideoSceneSchema).min(1)
|
|
3085
|
-
}).loose();
|
|
3086
|
-
var OverlayStyleSchema = z.object({ color_hex: z.string().optional(), background: z.string().optional(), size: z.string().optional() }).loose();
|
|
3087
|
-
var BlueprintOverlaySchema = z.object({
|
|
3088
|
-
text: z.string().optional(),
|
|
3089
|
-
appears_at_s: z.number().optional(),
|
|
3090
|
-
duration_s: z.number().optional(),
|
|
3091
|
-
position: z.string().optional(),
|
|
3092
|
-
role: z.string().optional(),
|
|
3093
|
-
animation: z.string().optional(),
|
|
3094
|
-
animation_detail: z.string().optional(),
|
|
3095
|
-
style: OverlayStyleSchema.optional()
|
|
3096
|
-
}).loose();
|
|
3097
|
-
var BlueprintFloatingElementSchema = z.object({
|
|
3098
|
-
kind: z.string().optional(),
|
|
3099
|
-
description: z.string().optional(),
|
|
3100
|
-
brand_name: z.string().nullish(),
|
|
3101
|
-
what_it_represents: z.string().optional(),
|
|
3102
|
-
appears_at_s: z.number().optional(),
|
|
3103
|
-
duration_s: z.number().optional(),
|
|
3104
|
-
position: z.string().optional()
|
|
3105
|
-
}).loose();
|
|
3106
|
-
|
|
3107
|
-
export {
|
|
3108
|
-
AD_PLATFORMS,
|
|
3109
|
-
AD_PLATFORM_LEAD,
|
|
3110
|
-
AD_PLACEMENTS,
|
|
3111
|
-
deliveryPlan,
|
|
3112
|
-
verticalCover,
|
|
3113
|
-
AD_FORMAT_PLATFORMS,
|
|
3114
|
-
platformFormats,
|
|
3115
|
-
resolveAdaptFormats,
|
|
3116
|
-
AD_DESCRIBE_FOCUS,
|
|
3117
|
-
AD_SELECT_SYSTEM,
|
|
3118
|
-
AD_SELECT_PROMPT,
|
|
3119
|
-
canonicalize,
|
|
3120
|
-
withoutCastName,
|
|
3121
|
-
frameRealismDirection,
|
|
3122
|
-
OPENROUTER_IMAGE_SIZES,
|
|
3123
|
-
SEEDANCE_DURATIONS,
|
|
3124
|
-
ELEVENLABS_OUTPUT_FORMATS,
|
|
3125
|
-
ELEVENLABS_MAX_TEXT_CHARS,
|
|
3126
|
-
ELEVENLABS_MAX_MUSIC_LENGTH_MS,
|
|
3127
|
-
IMAGE_GENERATE_MODELS,
|
|
3128
|
-
DEFAULT_IMAGE_GENERATE_MODEL,
|
|
3129
|
-
IMAGE_TIER_CREDITS,
|
|
3130
|
-
imagePictureCredits,
|
|
3131
|
-
VIDEO_GENERATE_MODELS,
|
|
3132
|
-
DEFAULT_VIDEO_GENERATE_MODEL,
|
|
3133
|
-
supportsReferenceToVideo,
|
|
3134
|
-
supportsLastFrame,
|
|
3135
|
-
MODEL_REGISTRY,
|
|
3136
|
-
canonicalModelId,
|
|
3137
|
-
modelIdsAccepted,
|
|
3138
|
-
MODEL_ROLES,
|
|
3139
|
-
AD_IMAGE_MODEL,
|
|
3140
|
-
REFERENCE_SHEET_MODEL,
|
|
3141
|
-
ASPECT_ADAPT_MODEL,
|
|
3142
|
-
PLATE_JUDGE_MODEL,
|
|
3143
|
-
AD_DESCRIBE_MODEL,
|
|
3144
|
-
BLUEPRINT_ANALYSIS_MODEL,
|
|
3145
|
-
VIEWER_CHECK_MODEL,
|
|
3146
|
-
CUSTOMER_INSIGHTS_MODEL,
|
|
3147
|
-
GLANCE_CHECK_MODEL,
|
|
3148
|
-
TEXT_BOX_READER_MODEL,
|
|
3149
|
-
SUBJECT_BOX_READER_MODEL,
|
|
3150
|
-
SIZE_MATCH_MODEL,
|
|
3151
|
-
VIDEO_DECONSTRUCT_MODEL,
|
|
3152
|
-
VOICEOVER_MODEL,
|
|
3153
|
-
SOUND_EFFECT_MODEL,
|
|
3154
|
-
MUSIC_BED_MODEL,
|
|
3155
|
-
VOICE_CONVERT_MODEL,
|
|
3156
|
-
isRegisteredModel,
|
|
3157
|
-
imageGenerateAspectRatios,
|
|
3158
|
-
supportsParam,
|
|
3159
|
-
DEFAULT_CLIP_DURATION_S,
|
|
3160
|
-
SPOKEN_WORDS_PER_SECOND,
|
|
3161
|
-
spokenWordsIn,
|
|
3162
|
-
SPOKEN_CLIP_DURATION_S,
|
|
3163
|
-
nearestClipDuration,
|
|
3164
|
-
clipAudioMode,
|
|
3165
|
-
clipDurationsFor,
|
|
3166
|
-
maxClipSeconds,
|
|
3167
|
-
splitScriptFor,
|
|
3168
|
-
promptMaxLength,
|
|
3169
|
-
maxInputSlot,
|
|
3170
|
-
maxInputReferences,
|
|
3171
|
-
bestSupportedQuality,
|
|
3172
|
-
supportedAspectRatios,
|
|
3173
|
-
nearestSupportedAspectRatio,
|
|
3174
|
-
nearestSupportedImageSize,
|
|
3175
|
-
estimateVideoCredits,
|
|
3176
|
-
DEFAULT_MUSIC_SECONDS,
|
|
3177
|
-
DEFAULT_SOUND_EFFECT_SECONDS,
|
|
3178
|
-
estimateNodeCredits,
|
|
3179
|
-
candidPersonPortraitPrompt,
|
|
3180
|
-
isManagedNodeKind,
|
|
3181
|
-
validateModelParams,
|
|
3182
|
-
validateModelInputs,
|
|
3183
|
-
VideoBlueprintSchema,
|
|
3184
|
-
BlueprintOverlaySchema,
|
|
3185
|
-
BlueprintFloatingElementSchema
|
|
3186
|
-
};
|
|
3187
|
-
//# sourceMappingURL=chunk-MCJ5I5LR.js.map
|