@koda-sl/baker-cli 0.531.0 → 0.532.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -10
- package/dist/account-2UXZ6CZJ.js +82 -0
- package/dist/account-HQD5P3AF.js +139 -0
- package/dist/account-OWMJG4IW.js +82 -0
- package/dist/account-assets-JRMYVXQP.js +290 -0
- package/dist/account-level-PEGLZQTI.js +611 -0
- package/dist/account-reads-W2GAN335.js +219 -0
- package/dist/account-users-WLTQNPL7.js +64 -0
- package/dist/account-writes-TNADUSHW.js +68 -0
- package/dist/accounts-D3SQTZB7.js +701 -0
- package/dist/accounts-HRQFOTBJ.js +80 -0
- package/dist/accounts-MQMEOGQD.js +114 -0
- package/dist/accounts-T6SRCZJQ.js +76 -0
- package/dist/accounts-Y2VWI3AA.js +115 -0
- package/dist/actions-VJXED57L.js +55 -0
- package/dist/active-entities-BOMM4YDF.js +103 -0
- package/dist/activecampaign-TNJIQA4C.js +938 -0
- package/dist/activities-YH4K4JAI.js +75 -0
- package/dist/ad-group-writes-7BGCZA3M.js +172 -0
- package/dist/ad-groups-A6GU6EW5.js +70 -0
- package/dist/ad-writes-CEMCUDU2.js +176 -0
- package/dist/add-2L2VQ5MU.js +80 -0
- package/dist/add-DRTKSLEQ.js +107 -0
- package/dist/add-LBHISK44.js +305 -0
- package/dist/add-PS36Q2S3.js +97 -0
- package/dist/add-RLMXZLLO.js +148 -0
- package/dist/add-Z2OTFSQO.js +81 -0
- package/dist/add-accounts-GXBE4ZR2.js +91 -0
- package/dist/ads-4EVKVAMR.js +48 -0
- package/dist/ads-OY455VCX.js +79 -0
- package/dist/ads-WYQYZ44U.js +128 -0
- package/dist/ads-ZEF5AU3D.js +120 -0
- package/dist/adsets-ZRS7AZIK.js +182 -0
- package/dist/advertisers-AAGUUSAX.js +125 -0
- package/dist/advertisers-G6DZRBOK.js +123 -0
- package/dist/analytics-ANG42PKM.js +2437 -0
- package/dist/analytics-UI4AKUSF.js +447 -0
- package/dist/animate-KCSICY2N.js +480 -0
- package/dist/approved-LHYBVDXH.js +73 -0
- package/dist/asset-writes-CUF25BLM.js +50 -0
- package/dist/assign-5DFH6HBV.js +80 -0
- package/dist/audience-size-P6WIXOB3.js +76 -0
- package/dist/audience-writes-L7SNU2SB.js +327 -0
- package/dist/audiences-4ASLCNOF.js +280 -0
- package/dist/audiences-A54MU63W.js +86 -0
- package/dist/audiences-SG2BBM7R.js +85 -0
- package/dist/audit-6K5FFV6K.js +88 -0
- package/dist/audit-LA4BSLXV.js +154 -0
- package/dist/autocomplete-XMG6E7TG.js +114 -0
- package/dist/avatars-4IFN4GZD.js +38 -0
- package/dist/bid-pricing-JEOG2Q3L.js +103 -0
- package/dist/brand-C6HUAK74.js +22 -0
- package/dist/brief-5BCPPBU3.js +543 -0
- package/dist/businesses-GQ5FOZDU.js +54 -0
- package/dist/campaign-groups-IYQZSICZ.js +99 -0
- package/dist/campaign-writes-CVOOPZ35.js +176 -0
- package/dist/campaign-writes-YXI5UOPH.js +168 -0
- package/dist/campaigns-FW4WVD25.js +113 -0
- package/dist/campaigns-QMFHNG3N.js +111 -0
- package/dist/campaigns-TX37WHVL.js +78 -0
- package/dist/campaigns-VZJMYETG.js +130 -0
- package/dist/canvas-G4QXNPPE.js +46 -0
- package/dist/capabilities-7643Y2HU.js +147 -0
- package/dist/cards-YHZFJ3US.js +85 -0
- package/dist/catalog-PTVQSATT.js +65 -0
- package/dist/catalogs-YNIUP2AH.js +130 -0
- package/dist/catalogs-ZHCLH43A.js +781 -0
- package/dist/changes-QUKBZVB3.js +135 -0
- package/dist/chatgpt-TIUBMATF.js +47 -0
- package/dist/chats-BGLAG4Q7.js +279 -0
- package/dist/check-MN5ZQ7RX.js +107 -0
- package/dist/chunk-23KN4NL4.js +45 -0
- package/dist/chunk-2UJ5ABI6.js +604 -0
- package/dist/chunk-2XRFWXSA.js +103 -0
- package/dist/chunk-3JV4T6XW.js +69 -0
- package/dist/chunk-3OSBCYKA.js +8954 -0
- package/dist/chunk-3QQHPRRB.js +89 -0
- package/dist/chunk-3WTCMBDC.js +1518 -0
- package/dist/chunk-4BTUF2AV.js +69 -0
- package/dist/chunk-4D37LCBS.js +111 -0
- package/dist/chunk-4QITYZUH.js +163 -0
- package/dist/chunk-4XNF52NU.js +429 -0
- package/dist/chunk-4Y7IJ2PU.js +5368 -0
- package/dist/chunk-53BTYIMJ.js +91 -0
- package/dist/chunk-5ITB24SC.js +544 -0
- package/dist/chunk-5N47LB7X.js +285 -0
- package/dist/chunk-5UBFYJHF.js +170 -0
- package/dist/chunk-6CQOHJZW.js +125 -0
- package/dist/chunk-6OXENBTF.js +74 -0
- package/dist/chunk-6PMJU7IU.js +169 -0
- package/dist/chunk-7GGLZOQN.js +91 -0
- package/dist/chunk-7I65KXU7.js +98 -0
- package/dist/chunk-7JFVMJZI.js +207 -0
- package/dist/chunk-A6VODUO3.js +166 -0
- package/dist/chunk-AGTA5FJX.js +139 -0
- package/dist/chunk-AGU4KGT6.js +84 -0
- package/dist/chunk-BXUUKRMM.js +46 -0
- package/dist/chunk-BZTAEZLT.js +51 -0
- package/dist/chunk-C7IOSSI4.js +58 -0
- package/dist/chunk-CIW3Q7B2.js +229 -0
- package/dist/chunk-CJQ77HO5.js +1646 -0
- package/dist/chunk-CNPYG4F3.js +75 -0
- package/dist/chunk-COS3TPHX.js +377 -0
- package/dist/chunk-CQ6HBFOB.js +23 -0
- package/dist/chunk-D7Y3UNWO.js +66 -0
- package/dist/chunk-DJTWY7GL.js +942 -0
- package/dist/chunk-DWW5QSUF.js +638 -0
- package/dist/chunk-E34YYDCE.js +35 -0
- package/dist/chunk-ENUCJ6AO.js +148 -0
- package/dist/chunk-ES3PWGS3.js +438 -0
- package/dist/chunk-ES3PWGS3.js.map +1 -0
- package/dist/chunk-FESQ5TXU.js +42 -0
- package/dist/chunk-FEUKUZRA.js +106 -0
- package/dist/chunk-FJDSL4O5.js +910 -0
- package/dist/chunk-FSTDWVXG.js +455 -0
- package/dist/chunk-FUR7R4D7.js +249 -0
- package/dist/chunk-GYMZCJX6.js +97 -0
- package/dist/chunk-HTT7RBRC.js +846 -0
- package/dist/chunk-HZPTQRX6.js +2441 -0
- package/dist/chunk-HZPTQRX6.js.map +1 -0
- package/dist/chunk-IQWFJEA3.js +217 -0
- package/dist/chunk-IU5K42Q3.js +831 -0
- package/dist/chunk-JARRF5VX.js +66 -0
- package/dist/chunk-JEUFRIYS.js +297 -0
- package/dist/chunk-JNSRQQDP.js +94 -0
- package/dist/chunk-KGAI4E2I.js +106 -0
- package/dist/chunk-KITVYLEX.js +843 -0
- package/dist/chunk-L5VVKIMB.js +203 -0
- package/dist/chunk-L763CNKH.js +333 -0
- package/dist/chunk-LO2MZJJP.js +225 -0
- package/dist/chunk-LV7EU6HM.js +324 -0
- package/dist/chunk-LXZ5E6AC.js +84 -0
- package/dist/chunk-LZRZVIEJ.js +191 -0
- package/dist/chunk-M2MJ52HS.js +676 -0
- package/dist/chunk-MBSAHNMJ.js +547 -0
- package/dist/chunk-MCKYNFPH.js +219 -0
- package/dist/chunk-MHZIOOT5.js +197 -0
- package/dist/chunk-MNOCC5AL.js +207 -0
- package/dist/chunk-MUEJVDHI.js +200 -0
- package/dist/chunk-N6WHUUFH.js +19 -0
- package/dist/chunk-NA5Q473J.js +3868 -0
- package/dist/chunk-NCO5NGBN.js +74 -0
- package/dist/chunk-NLW25WW3.js +52 -0
- package/dist/chunk-NYAFSC5V.js +287 -0
- package/dist/chunk-O7AMKMII.js +215 -0
- package/dist/chunk-OL3QHART.js +188 -0
- package/dist/chunk-OPUEQSKM.js +122 -0
- package/dist/chunk-OXLB5M5M.js +592 -0
- package/dist/chunk-OXYWSVOJ.js +100 -0
- package/dist/chunk-PE4ZP7MX.js +8914 -0
- package/dist/chunk-PG5R35QY.js +73 -0
- package/dist/chunk-PG5R35QY.js.map +1 -0
- package/dist/chunk-PHZOMTI6.js +97 -0
- package/dist/chunk-PIAG4UJT.js +274 -0
- package/dist/chunk-PYWIHAVD.js +64 -0
- package/dist/chunk-QKNPF6ZD.js +24026 -0
- package/dist/chunk-QOBA6PHB.js +131 -0
- package/dist/chunk-QPPQXU3U.js +98 -0
- package/dist/chunk-QTKNS2U2.js +149 -0
- package/dist/chunk-QTLIXCVN.js +46 -0
- package/dist/chunk-R5LRBDEM.js +136 -0
- package/dist/chunk-RRC7F3QQ.js +1919 -0
- package/dist/chunk-SEYCF446.js +191 -0
- package/dist/chunk-SF52UGHZ.js +225 -0
- package/dist/chunk-SVNH6P7O.js +1744 -0
- package/dist/chunk-SWFZJROM.js +64 -0
- package/dist/chunk-UCNIJ2IW.js +494 -0
- package/dist/chunk-UFUYTWEF.js +344 -0
- package/dist/chunk-ULW4EWAA.js +39 -0
- package/dist/chunk-UROKPFIS.js +142 -0
- package/dist/chunk-VCOIFNYH.js +714 -0
- package/dist/chunk-VPF5A7CM.js +476 -0
- package/dist/chunk-VV6FDIP5.js +224 -0
- package/dist/chunk-WRTG3KXU.js +156 -0
- package/dist/chunk-XAW5GL6B.js +76 -0
- package/dist/chunk-XRNJRQ6Q.js +26 -0
- package/dist/chunk-Y5GQO6CR.js +56 -0
- package/dist/chunk-YE4RCEEJ.js +167 -0
- package/dist/chunk-YJYKSMLF.js +296 -0
- package/dist/chunk-YO54MA7R.js +275 -0
- package/dist/chunk-Z6T6VDDA.js +76 -0
- package/dist/chunk-ZOH672S6.js +25 -0
- package/dist/claim-2JNNC66N.js +200 -0
- package/dist/cli.js +45 -45
- package/dist/client-YUVT3RZN.js +19 -0
- package/dist/code-LOOWLRUL.js +76 -0
- package/dist/companies-4NJU5TLU.js +198 -0
- package/dist/company-QOYWS4W6.js +308 -0
- package/dist/complete-7FX2K3PV.js +84 -0
- package/dist/config-AOF6ACIP.js +88 -0
- package/dist/connect-H2HSPMRT.js +45 -0
- package/dist/content-NCW5IJFR.js +85 -0
- package/dist/conversation-4M7YMQOL.js +96 -0
- package/dist/conversion-report-G5JMZNYV.js +127 -0
- package/dist/conversion-upload-command-43PZFYT7.js +439 -0
- package/dist/conversion-writes-JQQCCGPO.js +122 -0
- package/dist/conversions-UO4CQNF6.js +78 -0
- package/dist/conversions-Z7FW7CFT.js +140 -0
- package/dist/copy-writes-ONVSSBLJ.js +170 -0
- package/dist/countries-Q6TA42P7.js +82 -0
- package/dist/create-4SFO4AQZ.js +62 -0
- package/dist/create-D5MA64KL.js +239 -0
- package/dist/create-GJ4ZMY3A.js +210 -0
- package/dist/create-QVY6DSYM.js +135 -0
- package/dist/creatives-ADH6HCCA.js +58 -0
- package/dist/creatives-R3XILT6D.js +223 -0
- package/dist/creatives-S3EZCXUT.js +89 -0
- package/dist/credentials-EQRB6XGZ.js +290 -0
- package/dist/critique-4YRRUNAU.js +1451 -0
- package/dist/critique-JCU2ATT6.js +232 -0
- package/dist/crm-AF6XOOSF.js +323 -0
- package/dist/crm-LSMFGR6R.js +227 -0
- package/dist/crop-RDP7YCNV.js +113 -0
- package/dist/currency-4KNOOZUU.js +88 -0
- package/dist/custom-conversions-7MZFTHUM.js +128 -0
- package/dist/customers-MM3VIZNA.js +59 -0
- package/dist/decide-OPCCKAIT.js +199 -0
- package/dist/delete-CO2YBPTI.js +67 -0
- package/dist/delete-D7HTW32U.js +57 -0
- package/dist/delete-GKQTDOZF.js +69 -0
- package/dist/delete-JUPBYK3H.js +69 -0
- package/dist/delete-KZFI235B.js +85 -0
- package/dist/delete-KZFI235B.js.map +1 -0
- package/dist/delete-R3LXCKA4.js +71 -0
- package/dist/demographics-DK5JDY6M.js +141 -0
- package/dist/describe-537PPL7P.js +97 -0
- package/dist/describe-GIG46DT5.js +97 -0
- package/dist/dimensions-UXK7DMTF.js +101 -0
- package/dist/discard-DEJOM62Y.js +69 -0
- package/dist/discover-MKFDG6NK.js +93 -0
- package/dist/discover-U6YLVLTF.js +172 -0
- package/dist/domain-MBOMV3CQ.js +101 -0
- package/dist/download-KN2I55SA.js +172 -0
- package/dist/download-PRBLR6IQ.js +299 -0
- package/dist/draft-BMNBT37B.js +283 -0
- package/dist/draft-CGPVRRKC.js +335 -0
- package/dist/draft-F74OIT5O.js +310 -0
- package/dist/draft-FIEZWBIX.js +308 -0
- package/dist/draft-H5RVDTFD.js +240 -0
- package/dist/draft-HZ5T6NOI.js +220 -0
- package/dist/draft-UMPCOCP6.js +100 -0
- package/dist/draft-XEUHTUMR.js +103 -0
- package/dist/engine/index.js +13 -13
- package/dist/env-VBSATLEF.js +53 -0
- package/dist/experiment-2XR6MBE2.js +1397 -0
- package/dist/experiments-YNJZCMQM.js +236 -0
- package/dist/export-YCLJG5YP.js +168 -0
- package/dist/extract-E3CMEN5U.js +113 -0
- package/dist/facets-Y4OACBMC.js +117 -0
- package/dist/favorites-NSQX6HKB.js +178 -0
- package/dist/feed-TKMMYAEH.js +177 -0
- package/dist/feedback-MORAVN52.js +111 -0
- package/dist/feedback-record-M3RB7H2C.js +265 -0
- package/dist/fetch-EHP2FK6Y.js +139 -0
- package/dist/fetch-XU6QVWMS.js +179 -0
- package/dist/find-I7U3THF3.js +143 -0
- package/dist/fit-IHUUFCGI.js +65 -0
- package/dist/flows-WSCIMXQX.js +250 -0
- package/dist/follow-A46RAJEX.js +94 -0
- package/dist/follow-competitors-VU2L3KWF.js +112 -0
- package/dist/following-UOUNSU6P.js +113 -0
- package/dist/fonts-3QW7EDHE.js +39 -0
- package/dist/forecast-2WVHMSZP.js +169 -0
- package/dist/forecast-F25LSCM5.js +121 -0
- package/dist/funding-2VROIMLS.js +85 -0
- package/dist/funnel-35DYDBJH.js +397 -0
- package/dist/ga4-ULHKTF23.js +55 -0
- package/dist/generate-Z7AROAES.js +263 -0
- package/dist/get-4CAX33L2.js +59 -0
- package/dist/get-5E4YJKPO.js +66 -0
- package/dist/get-5E4YJKPO.js.map +1 -0
- package/dist/get-ABQZJ2VQ.js +38 -0
- package/dist/get-ASAW6TVF.js +62 -0
- package/dist/get-ASAW6TVF.js.map +1 -0
- package/dist/get-GXVAJZHM.js +56 -0
- package/dist/get-GXVAJZHM.js.map +1 -0
- package/dist/get-IF7KHMSI.js +92 -0
- package/dist/get-N7X75ZJO.js +82 -0
- package/dist/get-ZISAHMTQ.js +59 -0
- package/dist/gif-QLNWBFAH.js +102 -0
- package/dist/google-FDR55RRD.js +136 -0
- package/dist/google-M6XR7YGT.js +3267 -0
- package/dist/google-ads-NCSMNNND.js +198 -0
- package/dist/group-HAQM6P7M.js +43 -0
- package/dist/group-XVDH2ONO.js +43 -0
- package/dist/gsc-72AFO6B4.js +30 -0
- package/dist/history-FGQ2H7XH.js +69 -0
- package/dist/history-LTOFKBMJ.js +136 -0
- package/dist/history-VJ254UXF.js +102 -0
- package/dist/hubspot-W2NM75YK.js +782 -0
- package/dist/icon-F7AOOTFI.js +137 -0
- package/dist/ideas-54KFDNDM.js +45 -0
- package/dist/images-JOEVCCP6.js +92 -0
- package/dist/improve-LIKOER3S.js +86 -0
- package/dist/ingest-6R7XUL46.js +27 -0
- package/dist/ingest-VCIH5QDR.js +123 -0
- package/dist/ingest-VCIH5QDR.js.map +1 -0
- package/dist/insights-QNE6XCBA.js +439 -0
- package/dist/insights-UXUUOQB7.js +132 -0
- package/dist/inspect-MGOR77FP.js +192 -0
- package/dist/inspiration-VXNGKAJV.js +53 -0
- package/dist/instant-experiences-MT2XMQNH.js +260 -0
- package/dist/intent-FZWPRUCI.js +95 -0
- package/dist/job-TS34W4IU.js +202 -0
- package/dist/job-create-FXXDR2EE.js +109 -0
- package/dist/job-status-R2H4HNC5.js +74 -0
- package/dist/keep-YSU3XMW3.js +78 -0
- package/dist/keyword-gap-4ECYPWXJ.js +130 -0
- package/dist/keyword-metrics-SBIRN5KC.js +200 -0
- package/dist/keywords-for-site-TLNPJHT2.js +131 -0
- package/dist/knowledge-L3VLOVLG.js +195 -0
- package/dist/landing-ZICSVWKF.js +28 -0
- package/dist/landings-XTPNPTHN.js +151 -0
- package/dist/languages-DIKRMAYE.js +55 -0
- package/dist/languages-VNZQ5USL.js +40 -0
- package/dist/launches-5R7EUONQ.js +19 -0
- package/dist/layerize-Q2QWDARG.js +190 -0
- package/dist/lead-routes-IXUCGINI.js +733 -0
- package/dist/leads-JUQFNK55.js +115 -0
- package/dist/leads-UVG6VYAC.js +540 -0
- package/dist/learn-A6BT25LQ.js +207 -0
- package/dist/library-G5YAFLTR.js +211 -0
- package/dist/lighthouse-BCBV2XGP.js +75 -0
- package/dist/line-item-writes-NW7A6HNH.js +211 -0
- package/dist/line-items-OAG3QMDE.js +107 -0
- package/dist/link-4VJ7FSOA.js +67 -0
- package/dist/linkedin-CKOWKD4M.js +1328 -0
- package/dist/linkedin-person-C22IDK7S.js +139 -0
- package/dist/list-2DKLO6AO.js +67 -0
- package/dist/list-4SDJZVOL.js +93 -0
- package/dist/list-6YW4I4VG.js +65 -0
- package/dist/list-CDDXHMJQ.js +306 -0
- package/dist/list-GS42LK5C.js +51 -0
- package/dist/list-HWNHRWGB.js +57 -0
- package/dist/list-QSBEYU45.js +76 -0
- package/dist/list-ZFGOONWL.js +50 -0
- package/dist/list-ZORO7PFP.js +154 -0
- package/dist/locations-4RDUHKVR.js +69 -0
- package/dist/locations-HATR6PSC.js +40 -0
- package/dist/log-OSJHKHPV.js +95 -0
- package/dist/logo-ABO4HJRG.js +18 -0
- package/dist/lookup-SPNT3W3W.js +23 -0
- package/dist/make-7CIVNW77.js +1366 -0
- package/dist/map-PMGZDXAN.js +436 -0
- package/dist/mcp-MOOOTRYG.js +729 -0
- package/dist/media-CIJW2Q3I.js +89 -0
- package/dist/media-GZKW2PZB.js +18 -0
- package/dist/media-sources-5OYCKQ5J.js +35 -0
- package/dist/members-QG5IP5HM.js +47 -0
- package/dist/meme-BPWX7YQH.js +100 -0
- package/dist/meta-KVOSCSPJ.js +122 -0
- package/dist/metrics-R4YS2JL6.js +152 -0
- package/dist/models-RJMZV5SH.js +155 -0
- package/dist/normalize-LATTXSL3.js +144 -0
- package/dist/normalize-NMNOJ6Q5.js +806 -0
- package/dist/options-KALH5TB7.js +125 -0
- package/dist/organization-AGCF7DUJ.js +949 -0
- package/dist/output-34QMC3OU.js +24 -0
- package/dist/page-UDF3LJHP.js +105 -0
- package/dist/page-photos-FCBW5UZS.js +118 -0
- package/dist/pages-5W5G4MRB.js +67 -0
- package/dist/performance-SITVZQWX.js +5565 -0
- package/dist/performance-YNXPUSGJ.js +27 -0
- package/dist/pinterest-IABDXLF5.js +96 -0
- package/dist/pixels-4QAWLSEL.js +109 -0
- package/dist/pixels-TYJVE377.js +62 -0
- package/dist/plan-I6EFL7RC.js +208 -0
- package/dist/posts-SXQSLOFV.js +36 -0
- package/dist/preview-7Y5LE24E.js +218 -0
- package/dist/profile-R5VPOOJU.js +159 -0
- package/dist/promoted-tweet-writes-NAHPJ3VD.js +183 -0
- package/dist/promoted-tweets-2XQ4MWAC.js +119 -0
- package/dist/properties-2D2BIDGC.js +101 -0
- package/dist/publish-UITYPUBD.js +344 -0
- package/dist/query-LB5H7IRK.js +236 -0
- package/dist/query-NDOYOIHL.js +247 -0
- package/dist/query-RE7NB2BK.js +62 -0
- package/dist/questionnaire-U767HYDE.js +94 -0
- package/dist/read-3TCDDALC.js +141 -0
- package/dist/reddit-6XIARCTX.js +29 -0
- package/dist/refresh-6UCN7PDX.js +97 -0
- package/dist/refresh-GIB6QQZS.js +42 -0
- package/dist/release-IN65L23O.js +63 -0
- package/dist/relevant-pages-W7IM6YQW.js +99 -0
- package/dist/remove-LZQHDFZF.js +49 -0
- package/dist/remove-X3XWVE2M.js +53 -0
- package/dist/reopen-RMMQ55CH.js +66 -0
- package/dist/rerun-ON6YCJAL.js +95 -0
- package/dist/research-LZBPCXIW.js +72 -0
- package/dist/research-W5KUOBXZ.js +265 -0
- package/dist/reset-MUWXTLIB.js +57 -0
- package/dist/reset-VQNKXFAF.js +57 -0
- package/dist/resolve-DMGWLMTC.js +124 -0
- package/dist/retry-YI4YLYTQ.js +63 -0
- package/dist/retry-ZQUJPKQH.js +65 -0
- package/dist/retry-failed-PEAUXGNT.js +45 -0
- package/dist/revenue-6YZAOMF6.js +91 -0
- package/dist/rule-writes-G25O5JZS.js +525 -0
- package/dist/rules-FHVZEN4D.js +99 -0
- package/dist/rules-KSOAKEI3.js +217 -0
- package/dist/rules-add-7X46VTIJ.js +465 -0
- package/dist/run-TA6HYFKZ.js +69 -0
- package/dist/run-YORKHK6S.js +70 -0
- package/dist/scaffold-ad-RHSHBCVV.js +1512 -0
- package/dist/scaffold-static-ad-XNOGCMPF.js +1010 -0
- package/dist/scaffold-video-XEVJQ7QZ.js +884 -0
- package/dist/schedule-TMTLYULK.js +64 -0
- package/dist/schedule-TNF6M6UD.js +67 -0
- package/dist/scheduled-agents-TS3WLRCM.js +55 -0
- package/dist/schema-2YQAQVON.js +121 -0
- package/dist/schema-6S5ZEPBS.js +135 -0
- package/dist/scrape-FDBYU3TU.js +2241 -0
- package/dist/screenshot-QSRWL4J6.js +102 -0
- package/dist/search-BOCQFUM3.js +51 -0
- package/dist/search-CENPR7GA.js +224 -0
- package/dist/search-GEXDRTAQ.js +26 -0
- package/dist/search-LFTFNDMC.js +91 -0
- package/dist/search-LTUUAGZG.js +177 -0
- package/dist/search-PYLNVZXI.js +92 -0
- package/dist/search-copy-RLRRR3LB.js +168 -0
- package/dist/seeds-E2GLHJ2T.js +101 -0
- package/dist/select-BXBNFGVL.js +106 -0
- package/dist/sends-NBTGBZT7.js +349 -0
- package/dist/sequences-UOIHUOD3.js +146 -0
- package/dist/set-prompt-JJWBB23C.js +198 -0
- package/dist/setup-links-6ANVKZCE.js +144 -0
- package/dist/shared-IMDHTVSW.js +32 -0
- package/dist/shopify-6ISTKZCA.js +3958 -0
- package/dist/site-OIV55MGO.js +180 -0
- package/dist/sitemaps-6A6JFBV4.js +87 -0
- package/dist/sites-PZLE5FFV.js +101 -0
- package/dist/skills-FBIVWINH.js +47 -0
- package/dist/sources-5L4S5BQV.js +457 -0
- package/dist/sources-GLJWZFHZ.js +30 -0
- package/dist/stale-SK2SDGOT.js +76 -0
- package/dist/stats-2NLNQBRY.js +34 -0
- package/dist/status-TD7ISXC5.js +65 -0
- package/dist/sticker-4NKFAGEK.js +94 -0
- package/dist/stock-XOXZGGU3.js +179 -0
- package/dist/studies-C5IINK5Y.js +250 -0
- package/dist/studio-IDNM42JP.js +49 -0
- package/dist/study-writes-GJXLMM3D.js +470 -0
- package/dist/suggest-Z553OSYW.js +66 -0
- package/dist/sync-CIRDY55O.js +279 -0
- package/dist/sync-PVIFUXX3.js +57 -0
- package/dist/sync-UBOHNOXB.js +55 -0
- package/dist/sync-definition-7NBT6LTK.js +69 -0
- package/dist/tag-22TFBGDG.js +57 -0
- package/dist/tag-manager-QLZHU6NG.js +43 -0
- package/dist/tags-3HB7N5WB.js +23 -0
- package/dist/tags-DG3XQ4SF.js +227 -0
- package/dist/tags-T4EN6XYE.js +23 -0
- package/dist/tags-T6THTVNP.js +26 -0
- package/dist/tags-XY6R2VJ6.js +23 -0
- package/dist/targeting-GNEBULXU.js +762 -0
- package/dist/targeting-constants-GR6BVM2H.js +118 -0
- package/dist/targeting-criteria-CL472KJO.js +113 -0
- package/dist/targets-7AQMSO6H.js +106 -0
- package/dist/terms-LG7FYQOG.js +102 -0
- package/dist/testimonials-4QWVSEPU.js +32 -0
- package/dist/themes-ZTM4OVGK.js +95 -0
- package/dist/top-companies-PMFYOAFK.js +111 -0
- package/dist/transcript-YWFYNFWX.js +165 -0
- package/dist/translate-VMQHPX4B.js +600 -0
- package/dist/triggers-JKXISN45.js +144 -0
- package/dist/tweets-IF5FFFTH.js +123 -0
- package/dist/unfollow-CDUOZWM7.js +46 -0
- package/dist/unlink-IUAFDLBT.js +70 -0
- package/dist/unstage-OVOZE6DA.js +96 -0
- package/dist/unstage-ZYT5RNLK.js +88 -0
- package/dist/update-23Q4T2J5.js +155 -0
- package/dist/update-74VME6PN.js +66 -0
- package/dist/update-O22DAZVX.js +192 -0
- package/dist/update-Q3WJ3DQN.js +81 -0
- package/dist/update-QAWK3O7L.js +101 -0
- package/dist/upload-EAEILUQB.js +150 -0
- package/dist/upload-WASRCKS4.js +130 -0
- package/dist/upload-WASRCKS4.js.map +1 -0
- package/dist/upscale-HB6L6SZG.js +109 -0
- package/dist/url-options-M7RX2TD4.js +131 -0
- package/dist/url-params-E5ON6W2N.js +101 -0
- package/dist/use-HGX7ZRH5.js +111 -0
- package/dist/use-HGX7ZRH5.js.map +1 -0
- package/dist/validate-NB6PS5PF.js +122 -0
- package/dist/variant-O7LXOA2E.js +338 -0
- package/dist/videos-SS2Y6FJF.js +41 -0
- package/dist/view-ED636LWD.js +121 -0
- package/dist/viewer-check-CWS6OVM7.js +83 -0
- package/dist/web-HT22JFQR.js +143 -0
- package/dist/winners-ZG5SHNBS.js +113 -0
- package/dist/winning-ads-FXTP4PWZ.js +86 -0
- package/dist/write-commands-5YVQKO7E.js +1525 -0
- package/dist/write-commands-AIWR7NBO.js +713 -0
- package/dist/write-commands-UK6MKGHI.js +206 -0
- package/dist/write-commands-W3UN6F4Y.js +1172 -0
- package/dist/x-KEMAY75C.js +47 -0
- package/package.json +1 -1
- package/dist/account-2G3IT7J4.js +0 -82
- package/dist/account-CQJFUII3.js +0 -139
- package/dist/account-ULC5N7SI.js +0 -82
- package/dist/account-assets-IDVG4DGK.js +0 -290
- package/dist/account-level-GK7M2MMQ.js +0 -611
- package/dist/account-reads-FRFI6OHK.js +0 -219
- package/dist/account-users-PINZLBT7.js +0 -64
- package/dist/account-writes-WRGJC7VU.js +0 -68
- package/dist/accounts-2KFG33EX.js +0 -80
- package/dist/accounts-5754XUS3.js +0 -115
- package/dist/accounts-KRW3JNCW.js +0 -76
- package/dist/accounts-MHPNZW3W.js +0 -701
- package/dist/accounts-MTNBMXHD.js +0 -114
- package/dist/actions-33IZOT5C.js +0 -55
- package/dist/active-entities-JR5B32X2.js +0 -103
- package/dist/activecampaign-BV5GZFVR.js +0 -938
- package/dist/activities-2RAJXP3J.js +0 -75
- package/dist/ad-group-writes-W6RCMYLC.js +0 -172
- package/dist/ad-groups-XAI2Z62X.js +0 -70
- package/dist/ad-writes-IGWZRTXY.js +0 -176
- package/dist/add-4PJDIW2M.js +0 -148
- package/dist/add-DBCN33GH.js +0 -107
- package/dist/add-KB7O7NSB.js +0 -97
- package/dist/add-PRU32PQN.js +0 -81
- package/dist/add-UZDOQAJL.js +0 -80
- package/dist/add-WDX66JSM.js +0 -305
- package/dist/add-accounts-ZWXG6HLM.js +0 -91
- package/dist/ads-255V76SZ.js +0 -79
- package/dist/ads-7TEPA4KZ.js +0 -48
- package/dist/ads-I6I4MYQH.js +0 -128
- package/dist/ads-JVBLNTBF.js +0 -120
- package/dist/adsets-FN5ZWSYF.js +0 -182
- package/dist/advertisers-BPJWOY7I.js +0 -125
- package/dist/advertisers-SJO6JYIO.js +0 -123
- package/dist/analytics-TXPEXLPQ.js +0 -447
- package/dist/analytics-XDWBEY57.js +0 -2437
- package/dist/animate-425S4ZXS.js +0 -480
- package/dist/approved-KUVAJ5M7.js +0 -73
- package/dist/asset-writes-SSI3CO2A.js +0 -50
- package/dist/assign-CTV6LDEI.js +0 -80
- package/dist/audience-size-5QYI5PKH.js +0 -76
- package/dist/audience-writes-G64754LR.js +0 -327
- package/dist/audiences-JAVNJ5NC.js +0 -86
- package/dist/audiences-JZ6SCEUC.js +0 -280
- package/dist/audiences-OMLKMHEJ.js +0 -85
- package/dist/audit-2YFDJAKL.js +0 -88
- package/dist/audit-4UE6GFLG.js +0 -154
- package/dist/autocomplete-HTUV2UDS.js +0 -114
- package/dist/avatars-K7RBSMIJ.js +0 -38
- package/dist/bid-pricing-OWP4SZP5.js +0 -103
- package/dist/brand-GBP4OEJI.js +0 -22
- package/dist/brief-SLTB3EPO.js +0 -543
- package/dist/businesses-DXRDQIFP.js +0 -54
- package/dist/campaign-groups-LDOQU65Q.js +0 -99
- package/dist/campaign-writes-SHF3XZXV.js +0 -176
- package/dist/campaign-writes-SK55QLY5.js +0 -168
- package/dist/campaigns-6CAKRANC.js +0 -113
- package/dist/campaigns-EHV7J7PW.js +0 -111
- package/dist/campaigns-GG7LLI4X.js +0 -78
- package/dist/campaigns-GQWFSKGC.js +0 -130
- package/dist/canvas-2VRPGRND.js +0 -46
- package/dist/capabilities-BEZXR2FZ.js +0 -147
- package/dist/cards-J2PGFKEF.js +0 -85
- package/dist/catalog-XECCXRM6.js +0 -65
- package/dist/catalogs-P5KMIMC2.js +0 -130
- package/dist/catalogs-TBRONC2D.js +0 -781
- package/dist/changes-3COSIJLU.js +0 -135
- package/dist/chatgpt-S5EVEKYV.js +0 -47
- package/dist/chats-AN52YVBT.js +0 -279
- package/dist/check-AQO7CMDD.js +0 -107
- package/dist/chunk-2MXDSPUO.js +0 -76
- package/dist/chunk-2SGREP24.js +0 -76
- package/dist/chunk-34FVKJS2.js +0 -64
- package/dist/chunk-364TCROV.js +0 -207
- package/dist/chunk-3H5MJOG2.js +0 -91
- package/dist/chunk-3J3W23S4.js +0 -592
- package/dist/chunk-3KMYOPBI.js +0 -98
- package/dist/chunk-3WSJGYA3.js +0 -148
- package/dist/chunk-4745PLPI.js +0 -111
- package/dist/chunk-4JS2O2KV.js +0 -89
- package/dist/chunk-4ULRDQVD.js +0 -714
- package/dist/chunk-4VXQAJRU.js +0 -225
- package/dist/chunk-4XXA4WCS.js +0 -207
- package/dist/chunk-52IYZCRS.js +0 -476
- package/dist/chunk-5CTNSIWY.js +0 -69
- package/dist/chunk-5EF7ZLXA.js +0 -942
- package/dist/chunk-62QMJYML.js +0 -167
- package/dist/chunk-6B4KNOJZ.js +0 -75
- package/dist/chunk-6M77QNJ4.js +0 -69
- package/dist/chunk-7HH4F2KX.js +0 -188
- package/dist/chunk-7O4HFODK.js +0 -26
- package/dist/chunk-AFQF6ISC.js +0 -215
- package/dist/chunk-AXTOIHH2.js +0 -74
- package/dist/chunk-B4UVJCJ4.js +0 -229
- package/dist/chunk-BN4TDL5L.js +0 -217
- package/dist/chunk-C5UFKDAX.js +0 -377
- package/dist/chunk-CREEY2FS.js +0 -455
- package/dist/chunk-CSCHS3JG.js +0 -8954
- package/dist/chunk-DJWEQDBB.js +0 -98
- package/dist/chunk-DLNADMQV.js +0 -547
- package/dist/chunk-DNWP5DL6.js +0 -42
- package/dist/chunk-DW3OPKXI.js +0 -51
- package/dist/chunk-ECJIMIEJ.js +0 -142
- package/dist/chunk-EHIISZYD.js +0 -296
- package/dist/chunk-ERRTBCDW.js +0 -191
- package/dist/chunk-EZBZU6N7.js +0 -66
- package/dist/chunk-FBG3JDET.js +0 -97
- package/dist/chunk-FOWT6ENH.js +0 -170
- package/dist/chunk-FSGJSREN.js +0 -2437
- package/dist/chunk-FSGJSREN.js.map +0 -1
- package/dist/chunk-FVZL2YC5.js +0 -3868
- package/dist/chunk-GDQJG4BO.js +0 -91
- package/dist/chunk-GEFZVG4P.js +0 -219
- package/dist/chunk-GLCHD54W.js +0 -74
- package/dist/chunk-GT77XMOG.js +0 -23
- package/dist/chunk-GXPZJ2QN.js +0 -225
- package/dist/chunk-HAJYFRXL.js +0 -224
- package/dist/chunk-HPDGVK6R.js +0 -324
- package/dist/chunk-ILEJXJH2.js +0 -1518
- package/dist/chunk-J4ASA24X.js +0 -203
- package/dist/chunk-JCVPZ7CV.js +0 -638
- package/dist/chunk-KG7FPYM2.js +0 -64
- package/dist/chunk-KRQ2AXFW.js +0 -191
- package/dist/chunk-L5IYVZM2.js +0 -39
- package/dist/chunk-LHQ6GXNF.js +0 -46
- package/dist/chunk-LS2KEAYJ.js +0 -66
- package/dist/chunk-LURM3KKS.js +0 -94
- package/dist/chunk-MHH7SGLS.js +0 -106
- package/dist/chunk-MZIYRWXL.js +0 -285
- package/dist/chunk-NY5VYGTP.js +0 -97
- package/dist/chunk-O37YK4P6.js +0 -136
- package/dist/chunk-PGBZ73UZ.js +0 -429
- package/dist/chunk-PN72Z2W2.js +0 -56
- package/dist/chunk-QJ5TU5J6.js +0 -100
- package/dist/chunk-QNLPZOHV.js +0 -84
- package/dist/chunk-QNXDSNOQ.js +0 -544
- package/dist/chunk-QOC3JEUQ.js +0 -363
- package/dist/chunk-QOC3JEUQ.js.map +0 -1
- package/dist/chunk-R44B522K.js +0 -139
- package/dist/chunk-R5GGTLYE.js +0 -846
- package/dist/chunk-R6T25WTZ.js +0 -344
- package/dist/chunk-RUJS2NOA.js +0 -297
- package/dist/chunk-SDQLZYQG.js +0 -843
- package/dist/chunk-SEC6FPWC.js +0 -494
- package/dist/chunk-SJAUMPL3.js +0 -46
- package/dist/chunk-SNDHR5QA.js +0 -24026
- package/dist/chunk-SP5L7EYC.js +0 -125
- package/dist/chunk-SPBNAGIN.js +0 -1646
- package/dist/chunk-SWNCS2OD.js +0 -333
- package/dist/chunk-T37PAZT2.js +0 -274
- package/dist/chunk-T6PTG6VM.js +0 -5368
- package/dist/chunk-TE4ASZSC.js +0 -45
- package/dist/chunk-TEKML2NW.js +0 -35
- package/dist/chunk-TKDOVFO6.js +0 -287
- package/dist/chunk-TRMZQRVV.js +0 -1919
- package/dist/chunk-TTKDFRON.js +0 -149
- package/dist/chunk-U2BPZ27S.js +0 -910
- package/dist/chunk-UPDIBQUC.js +0 -106
- package/dist/chunk-V2XEX2YR.js +0 -84
- package/dist/chunk-V62ZWGCL.js +0 -103
- package/dist/chunk-VCUXAPLM.js +0 -169
- package/dist/chunk-W7C7HZFJ.js +0 -275
- package/dist/chunk-WPAW6EVY.js +0 -166
- package/dist/chunk-WPSLL3S2.js +0 -604
- package/dist/chunk-WW6JLISJ.js +0 -200
- package/dist/chunk-X3HPRECW.js +0 -52
- package/dist/chunk-XGX2WOV2.js +0 -8914
- package/dist/chunk-XJHUSJY6.js +0 -156
- package/dist/chunk-XPDUBDPL.js +0 -25
- package/dist/chunk-XRSRHAEU.js +0 -163
- package/dist/chunk-XVHR2NCG.js +0 -249
- package/dist/chunk-XWO6CXNG.js +0 -19
- package/dist/chunk-XZWBLUDV.js +0 -831
- package/dist/chunk-Y25HSPRJ.js +0 -122
- package/dist/chunk-YUCGCJKT.js +0 -676
- package/dist/chunk-ZBUIWVF3.js +0 -197
- package/dist/chunk-ZFJ2FQUH.js +0 -131
- package/dist/chunk-ZNXP3WNJ.js +0 -58
- package/dist/chunk-ZVXKWLLE.js +0 -1744
- package/dist/claim-NRNO4XCO.js +0 -200
- package/dist/client-463NKLRT.js +0 -19
- package/dist/code-R4JOQ27J.js +0 -76
- package/dist/companies-4TOBU44J.js +0 -198
- package/dist/company-RK34S3IA.js +0 -308
- package/dist/complete-7BNBQ5AI.js +0 -84
- package/dist/config-GDLHHBJZ.js +0 -88
- package/dist/connect-CRIRSXN3.js +0 -45
- package/dist/content-FCO6MGXW.js +0 -85
- package/dist/conversation-4CQG2B2C.js +0 -96
- package/dist/conversion-report-PDTQTRVB.js +0 -127
- package/dist/conversion-upload-command-MEO4WLZH.js +0 -439
- package/dist/conversion-writes-ZVBOXUIA.js +0 -122
- package/dist/conversions-BND5HYTL.js +0 -78
- package/dist/conversions-POBKTXQF.js +0 -140
- package/dist/copy-writes-EUFEVWDW.js +0 -170
- package/dist/countries-TKL5T5JL.js +0 -82
- package/dist/create-BJ7XBNY5.js +0 -62
- package/dist/create-PYP3QWTL.js +0 -135
- package/dist/create-XN4KVB5U.js +0 -210
- package/dist/create-YSGBH6Q4.js +0 -239
- package/dist/creatives-57XIJAEG.js +0 -223
- package/dist/creatives-6VJDUHEY.js +0 -89
- package/dist/creatives-ANTJUTIE.js +0 -58
- package/dist/credentials-KIH6ICDU.js +0 -290
- package/dist/critique-GWRXVXVG.js +0 -1451
- package/dist/critique-MZUTDK4V.js +0 -232
- package/dist/crm-QSHUYXTW.js +0 -323
- package/dist/crm-Y5QTZAHO.js +0 -227
- package/dist/crop-WKTW3EMP.js +0 -113
- package/dist/currency-PTOI5SPU.js +0 -88
- package/dist/custom-conversions-NDY5RHSM.js +0 -128
- package/dist/customers-2G32E6W7.js +0 -59
- package/dist/decide-X2UAKYXK.js +0 -199
- package/dist/delete-2ZTMTKYD.js +0 -69
- package/dist/delete-3H6YH4YK.js +0 -67
- package/dist/delete-FOSTK2RA.js +0 -71
- package/dist/delete-FOSTK2RA.js.map +0 -1
- package/dist/delete-HIAZHA56.js +0 -57
- package/dist/delete-I43JQH2E.js +0 -69
- package/dist/delete-RF44ILYE.js +0 -71
- package/dist/demographics-2UYQW6II.js +0 -141
- package/dist/describe-M6DYXNQC.js +0 -97
- package/dist/describe-OQ6R3EF7.js +0 -97
- package/dist/dimensions-DGYM5E5P.js +0 -101
- package/dist/discard-NKPQ73UM.js +0 -69
- package/dist/discover-XLIH7RCB.js +0 -93
- package/dist/discover-YKMBVSPF.js +0 -172
- package/dist/domain-LUDUZB3F.js +0 -101
- package/dist/download-LL6DL62N.js +0 -172
- package/dist/download-SFWMT7DL.js +0 -299
- package/dist/draft-374Z4MGY.js +0 -103
- package/dist/draft-736FJJWK.js +0 -310
- package/dist/draft-7LPUJZCF.js +0 -283
- package/dist/draft-G432FJ7N.js +0 -240
- package/dist/draft-MPWR47CG.js +0 -308
- package/dist/draft-R5ND5SWT.js +0 -100
- package/dist/draft-T7TWIFEX.js +0 -335
- package/dist/draft-XAAIGE6Q.js +0 -220
- package/dist/env-DQHY5ODN.js +0 -53
- package/dist/experiment-MO6MT6OJ.js +0 -1397
- package/dist/experiments-OGZV73W6.js +0 -236
- package/dist/export-6Z6QBU6V.js +0 -168
- package/dist/extract-YGOQBOQK.js +0 -113
- package/dist/facets-OLZ7JLFL.js +0 -117
- package/dist/favorites-R3JO4SJJ.js +0 -178
- package/dist/feed-IUMMHM3I.js +0 -177
- package/dist/feedback-TJRYTOR3.js +0 -111
- package/dist/feedback-record-7IAJI5IY.js +0 -265
- package/dist/fetch-AL44XS4Q.js +0 -139
- package/dist/fetch-K3NRT2L2.js +0 -179
- package/dist/find-ZFIGMRYQ.js +0 -143
- package/dist/fit-5NVXWXZV.js +0 -65
- package/dist/flows-LL5SPPIK.js +0 -250
- package/dist/follow-SS374QUW.js +0 -94
- package/dist/follow-competitors-3LTOTTBY.js +0 -112
- package/dist/following-YMA5O3LF.js +0 -113
- package/dist/fonts-E3CNWPD5.js +0 -39
- package/dist/forecast-KOBF5TKM.js +0 -169
- package/dist/forecast-PWGN4ETP.js +0 -121
- package/dist/funding-KLIZ73SS.js +0 -85
- package/dist/funnel-XIZROHV7.js +0 -397
- package/dist/ga4-XPCE4EK5.js +0 -55
- package/dist/generate-GHIXVLMY.js +0 -263
- package/dist/get-HCGFATFD.js +0 -38
- package/dist/get-JR2KZXW5.js +0 -63
- package/dist/get-JR2KZXW5.js.map +0 -1
- package/dist/get-RDTJSWSA.js +0 -92
- package/dist/get-SGNT4JG2.js +0 -59
- package/dist/get-TGFXZC5S.js +0 -61
- package/dist/get-TGFXZC5S.js.map +0 -1
- package/dist/get-WS744HAO.js +0 -59
- package/dist/get-XPJ4BZGP.js +0 -82
- package/dist/get-YD7GDMDR.js +0 -63
- package/dist/get-YD7GDMDR.js.map +0 -1
- package/dist/gif-YK5HJXRE.js +0 -102
- package/dist/google-5JV7OMOH.js +0 -3267
- package/dist/google-BI45CXMW.js +0 -136
- package/dist/google-ads-DYZGUM6W.js +0 -198
- package/dist/group-7OWIYAKJ.js +0 -43
- package/dist/group-H6ZYRPE6.js +0 -43
- package/dist/gsc-HI2KXDEU.js +0 -30
- package/dist/history-3EQQHYKT.js +0 -69
- package/dist/history-RD2YMNNL.js +0 -102
- package/dist/history-SQPJ7PPE.js +0 -136
- package/dist/hubspot-MYTV36SM.js +0 -782
- package/dist/icon-HLJCWTR3.js +0 -137
- package/dist/ideas-CVXHFVX7.js +0 -45
- package/dist/images-XP4TKE2F.js +0 -92
- package/dist/improve-BRC4R6MW.js +0 -86
- package/dist/ingest-4GNJ2PWL.js +0 -26
- package/dist/ingest-5NYBUZE2.js +0 -110
- package/dist/ingest-5NYBUZE2.js.map +0 -1
- package/dist/insights-CN3GUTT7.js +0 -132
- package/dist/insights-IVW6W5CP.js +0 -439
- package/dist/inspect-25IVRU45.js +0 -192
- package/dist/inspiration-D75DO3MD.js +0 -53
- package/dist/instant-experiences-6F6GXZ67.js +0 -260
- package/dist/intent-3GDLPKKN.js +0 -95
- package/dist/job-2JJNKUHT.js +0 -202
- package/dist/job-create-BNTNZCSP.js +0 -109
- package/dist/job-status-N7RWRDRO.js +0 -74
- package/dist/keep-Z2WH3CKU.js +0 -78
- package/dist/keyword-gap-B2WPVHOB.js +0 -130
- package/dist/keyword-metrics-UDGWN7BO.js +0 -200
- package/dist/keywords-for-site-GEG6AXD3.js +0 -131
- package/dist/knowledge-PKXPN4RV.js +0 -195
- package/dist/landing-O2ZUIUGE.js +0 -28
- package/dist/landings-7QRITXZ2.js +0 -151
- package/dist/languages-RZLMZR57.js +0 -55
- package/dist/languages-UJAOPTV2.js +0 -40
- package/dist/launches-4H6ANGTG.js +0 -19
- package/dist/layerize-P5LFIA4X.js +0 -190
- package/dist/lead-routes-WVXWVG62.js +0 -733
- package/dist/leads-CJKRKB2Q.js +0 -540
- package/dist/leads-MTTOYNPM.js +0 -115
- package/dist/learn-QPXZZIZZ.js +0 -207
- package/dist/library-VW27X75P.js +0 -211
- package/dist/lighthouse-FGUFJRGR.js +0 -75
- package/dist/line-item-writes-RVOAMJ5R.js +0 -211
- package/dist/line-items-POZRAJLC.js +0 -107
- package/dist/link-IXEZKRM7.js +0 -67
- package/dist/linkedin-5PYG5HEM.js +0 -1328
- package/dist/linkedin-person-EMJXEZYR.js +0 -139
- package/dist/list-4KS7WSUG.js +0 -306
- package/dist/list-7GDMM26I.js +0 -93
- package/dist/list-DVVOP6FM.js +0 -50
- package/dist/list-J5KWXHFO.js +0 -76
- package/dist/list-OZCU2T22.js +0 -67
- package/dist/list-PTK2HOUY.js +0 -51
- package/dist/list-Q5LVTPQP.js +0 -57
- package/dist/list-UG4V5AM2.js +0 -65
- package/dist/list-XOYU7UTX.js +0 -154
- package/dist/locations-EISZ6JOT.js +0 -40
- package/dist/locations-VJX64ZZR.js +0 -69
- package/dist/log-2F2N24DT.js +0 -95
- package/dist/logo-H2KHGLYD.js +0 -18
- package/dist/lookup-K57ITJWF.js +0 -23
- package/dist/make-T6HLXIYY.js +0 -1366
- package/dist/map-QGJZIC5N.js +0 -436
- package/dist/mcp-RSW7KAWP.js +0 -729
- package/dist/media-HDHZULQ7.js +0 -18
- package/dist/media-K5RJXLTN.js +0 -89
- package/dist/media-sources-7R7FO53Y.js +0 -35
- package/dist/members-B6TKGGT5.js +0 -47
- package/dist/meme-QMCUGXUE.js +0 -100
- package/dist/meta-MOSJVYIE.js +0 -122
- package/dist/metrics-PRIKXVYZ.js +0 -152
- package/dist/models-M3E4YFCT.js +0 -155
- package/dist/normalize-5B4EQLUX.js +0 -144
- package/dist/normalize-5QIGANTK.js +0 -806
- package/dist/options-K33CJOR6.js +0 -125
- package/dist/organization-A4NFWWWI.js +0 -949
- package/dist/output-U5ZV6PST.js +0 -24
- package/dist/page-XVOUD4VV.js +0 -105
- package/dist/page-photos-4JTIKXAW.js +0 -118
- package/dist/pages-BAUS7LQM.js +0 -67
- package/dist/performance-MHJDRLEK.js +0 -5565
- package/dist/performance-NVURSEZ6.js +0 -27
- package/dist/pinterest-NA6HGPMB.js +0 -96
- package/dist/pixels-QOSEYXCP.js +0 -109
- package/dist/pixels-THDQD3RF.js +0 -62
- package/dist/plan-JYSHKPZQ.js +0 -208
- package/dist/posts-ILAFADBW.js +0 -36
- package/dist/preview-X6EJGPAY.js +0 -218
- package/dist/profile-YHI65VGK.js +0 -159
- package/dist/promoted-tweet-writes-MXXVRLVQ.js +0 -183
- package/dist/promoted-tweets-HFLGXWX2.js +0 -119
- package/dist/properties-ZLY6NYVK.js +0 -101
- package/dist/publish-6ZXFUBGP.js +0 -344
- package/dist/query-ELD7WSFR.js +0 -247
- package/dist/query-HFHTLNDN.js +0 -236
- package/dist/query-WMEX73ZB.js +0 -62
- package/dist/questionnaire-Y37I64FO.js +0 -94
- package/dist/read-2HQEZIJW.js +0 -141
- package/dist/reddit-BIHGJPGP.js +0 -29
- package/dist/refresh-4O32S4YR.js +0 -97
- package/dist/refresh-LVV4SPLT.js +0 -42
- package/dist/release-VIPNSPQ5.js +0 -63
- package/dist/relevant-pages-B5SYN575.js +0 -99
- package/dist/remove-2E77743U.js +0 -53
- package/dist/remove-TPOWWFZ6.js +0 -49
- package/dist/reopen-UOBTJBMQ.js +0 -66
- package/dist/rerun-UPDIXTEL.js +0 -95
- package/dist/research-ELM3KHGE.js +0 -72
- package/dist/research-FOJIDMSE.js +0 -265
- package/dist/reset-FTLWUFZK.js +0 -57
- package/dist/reset-GIXXLPHQ.js +0 -57
- package/dist/resolve-QHR5JJTJ.js +0 -124
- package/dist/retry-HNWXJR5U.js +0 -65
- package/dist/retry-NY5KFEDA.js +0 -63
- package/dist/retry-failed-OAH7JQKD.js +0 -45
- package/dist/revenue-JFMUODJO.js +0 -91
- package/dist/rule-writes-A4BFYHPA.js +0 -525
- package/dist/rules-56E55SGC.js +0 -99
- package/dist/rules-HLREXY2M.js +0 -217
- package/dist/rules-add-ZOPOWJMY.js +0 -465
- package/dist/run-4UIPMCSN.js +0 -69
- package/dist/run-GACZDI6Q.js +0 -70
- package/dist/scaffold-ad-Z2HSN4PE.js +0 -1512
- package/dist/scaffold-static-ad-ODZGTIM5.js +0 -1010
- package/dist/scaffold-video-EHGAMEEP.js +0 -884
- package/dist/schedule-OFPSZVZ2.js +0 -67
- package/dist/schedule-ZATNBBWD.js +0 -64
- package/dist/scheduled-agents-4VY4CAA2.js +0 -55
- package/dist/schema-EYGPETLF.js +0 -121
- package/dist/schema-OGP4DUPP.js +0 -135
- package/dist/scrape-ZHL2BHS7.js +0 -2241
- package/dist/screenshot-ADMRDYWN.js +0 -102
- package/dist/search-6W4HXR2S.js +0 -91
- package/dist/search-6ZWI2NML.js +0 -92
- package/dist/search-CQUS7EOM.js +0 -51
- package/dist/search-HF5ECIYW.js +0 -26
- package/dist/search-MKVVMJ2Q.js +0 -224
- package/dist/search-QUF6LHQ5.js +0 -177
- package/dist/search-copy-O6FDX4HT.js +0 -168
- package/dist/seeds-5TM3O3K3.js +0 -101
- package/dist/select-FCQUYBKV.js +0 -106
- package/dist/sends-MZKHZZGJ.js +0 -349
- package/dist/sequences-3CEVHGHB.js +0 -146
- package/dist/set-prompt-IBAG6BDA.js +0 -198
- package/dist/setup-links-4STQ5B4P.js +0 -144
- package/dist/shared-I3SB77VH.js +0 -32
- package/dist/shopify-7LDHCWUQ.js +0 -3958
- package/dist/site-I3NFMPJB.js +0 -180
- package/dist/sitemaps-PLAWVXQL.js +0 -87
- package/dist/sites-WX2IBTZT.js +0 -101
- package/dist/skills-O6EQOAMQ.js +0 -47
- package/dist/sources-K2LILGTW.js +0 -30
- package/dist/sources-ZM7LEIMM.js +0 -457
- package/dist/stale-VR5QAYB6.js +0 -76
- package/dist/stats-QQRYOMZA.js +0 -34
- package/dist/status-5OMVGFCH.js +0 -65
- package/dist/sticker-654HS3K2.js +0 -94
- package/dist/stock-35LOO3YN.js +0 -179
- package/dist/studies-IGOCWM7F.js +0 -250
- package/dist/studio-3D42TUJX.js +0 -49
- package/dist/study-writes-Z5P2W7JH.js +0 -470
- package/dist/suggest-JASHCOL5.js +0 -66
- package/dist/sync-6AN67IX3.js +0 -55
- package/dist/sync-RCDODSOD.js +0 -57
- package/dist/sync-URIRLHTS.js +0 -279
- package/dist/sync-definition-MZUJOJYI.js +0 -69
- package/dist/tag-7YMFAZQQ.js +0 -57
- package/dist/tag-manager-LU4GAZ6R.js +0 -43
- package/dist/tags-6A7QOYBI.js +0 -23
- package/dist/tags-JHT3Q6VO.js +0 -227
- package/dist/tags-KSMLT4G2.js +0 -26
- package/dist/tags-MTVZJHCE.js +0 -23
- package/dist/tags-OU32R2SH.js +0 -23
- package/dist/targeting-7HXKBXWY.js +0 -762
- package/dist/targeting-constants-QIB3UZHM.js +0 -118
- package/dist/targeting-criteria-NUXZB7NP.js +0 -113
- package/dist/targets-LQ7HGI73.js +0 -106
- package/dist/terms-X4OJWTQH.js +0 -102
- package/dist/testimonials-Z2KOOMVH.js +0 -32
- package/dist/themes-6KVP3COR.js +0 -95
- package/dist/top-companies-WWNPUJ23.js +0 -111
- package/dist/transcript-P7HKVABU.js +0 -165
- package/dist/translate-II4JY2XW.js +0 -600
- package/dist/triggers-Z3LV3KJR.js +0 -144
- package/dist/tweets-X5PTAT6F.js +0 -123
- package/dist/unfollow-S5LHFLGW.js +0 -46
- package/dist/unlink-XTZA474P.js +0 -70
- package/dist/unstage-AVLORZLW.js +0 -96
- package/dist/unstage-QXOL5DXZ.js +0 -88
- package/dist/update-3NA6ABLW.js +0 -101
- package/dist/update-5ZNS2DKP.js +0 -66
- package/dist/update-DDKNKV6M.js +0 -81
- package/dist/update-MDVZ24VQ.js +0 -192
- package/dist/update-UE4XVBKL.js +0 -155
- package/dist/upload-IMP5CUY5.js +0 -129
- package/dist/upload-IMP5CUY5.js.map +0 -1
- package/dist/upload-SYFB2VTJ.js +0 -150
- package/dist/upscale-P5EYUVOZ.js +0 -109
- package/dist/url-options-DJZV3ADK.js +0 -131
- package/dist/url-params-Y5XQSDEF.js +0 -101
- package/dist/use-D3RBWLJO.js +0 -95
- package/dist/use-D3RBWLJO.js.map +0 -1
- package/dist/validate-BCK22BQL.js +0 -122
- package/dist/variant-JQVZUUA4.js +0 -338
- package/dist/videos-YCQVOOFE.js +0 -41
- package/dist/view-IKKRJ5YD.js +0 -121
- package/dist/viewer-check-5GREZIVJ.js +0 -83
- package/dist/web-7TPDDBI6.js +0 -143
- package/dist/winners-4PKEVMUC.js +0 -113
- package/dist/winning-ads-7X5EWSJX.js +0 -86
- package/dist/write-commands-CTLF2M6L.js +0 -713
- package/dist/write-commands-CY734U34.js +0 -1172
- package/dist/write-commands-FIS6Y2MN.js +0 -206
- package/dist/write-commands-V77MD5SC.js +0 -1525
- package/dist/x-EMLFCHSG.js +0 -47
- /package/dist/{account-2G3IT7J4.js.map → account-2UXZ6CZJ.js.map} +0 -0
- /package/dist/{account-CQJFUII3.js.map → account-HQD5P3AF.js.map} +0 -0
- /package/dist/{account-ULC5N7SI.js.map → account-OWMJG4IW.js.map} +0 -0
- /package/dist/{account-assets-IDVG4DGK.js.map → account-assets-JRMYVXQP.js.map} +0 -0
- /package/dist/{account-level-GK7M2MMQ.js.map → account-level-PEGLZQTI.js.map} +0 -0
- /package/dist/{account-reads-FRFI6OHK.js.map → account-reads-W2GAN335.js.map} +0 -0
- /package/dist/{account-users-PINZLBT7.js.map → account-users-WLTQNPL7.js.map} +0 -0
- /package/dist/{account-writes-WRGJC7VU.js.map → account-writes-TNADUSHW.js.map} +0 -0
- /package/dist/{accounts-MHPNZW3W.js.map → accounts-D3SQTZB7.js.map} +0 -0
- /package/dist/{accounts-2KFG33EX.js.map → accounts-HRQFOTBJ.js.map} +0 -0
- /package/dist/{accounts-MTNBMXHD.js.map → accounts-MQMEOGQD.js.map} +0 -0
- /package/dist/{accounts-KRW3JNCW.js.map → accounts-T6SRCZJQ.js.map} +0 -0
- /package/dist/{accounts-5754XUS3.js.map → accounts-Y2VWI3AA.js.map} +0 -0
- /package/dist/{actions-33IZOT5C.js.map → actions-VJXED57L.js.map} +0 -0
- /package/dist/{active-entities-JR5B32X2.js.map → active-entities-BOMM4YDF.js.map} +0 -0
- /package/dist/{activecampaign-BV5GZFVR.js.map → activecampaign-TNJIQA4C.js.map} +0 -0
- /package/dist/{activities-2RAJXP3J.js.map → activities-YH4K4JAI.js.map} +0 -0
- /package/dist/{ad-group-writes-W6RCMYLC.js.map → ad-group-writes-7BGCZA3M.js.map} +0 -0
- /package/dist/{ad-groups-XAI2Z62X.js.map → ad-groups-A6GU6EW5.js.map} +0 -0
- /package/dist/{ad-writes-IGWZRTXY.js.map → ad-writes-CEMCUDU2.js.map} +0 -0
- /package/dist/{add-UZDOQAJL.js.map → add-2L2VQ5MU.js.map} +0 -0
- /package/dist/{add-DBCN33GH.js.map → add-DRTKSLEQ.js.map} +0 -0
- /package/dist/{add-WDX66JSM.js.map → add-LBHISK44.js.map} +0 -0
- /package/dist/{add-KB7O7NSB.js.map → add-PS36Q2S3.js.map} +0 -0
- /package/dist/{add-4PJDIW2M.js.map → add-RLMXZLLO.js.map} +0 -0
- /package/dist/{add-PRU32PQN.js.map → add-Z2OTFSQO.js.map} +0 -0
- /package/dist/{add-accounts-ZWXG6HLM.js.map → add-accounts-GXBE4ZR2.js.map} +0 -0
- /package/dist/{ads-7TEPA4KZ.js.map → ads-4EVKVAMR.js.map} +0 -0
- /package/dist/{ads-255V76SZ.js.map → ads-OY455VCX.js.map} +0 -0
- /package/dist/{ads-I6I4MYQH.js.map → ads-WYQYZ44U.js.map} +0 -0
- /package/dist/{ads-JVBLNTBF.js.map → ads-ZEF5AU3D.js.map} +0 -0
- /package/dist/{adsets-FN5ZWSYF.js.map → adsets-ZRS7AZIK.js.map} +0 -0
- /package/dist/{advertisers-BPJWOY7I.js.map → advertisers-AAGUUSAX.js.map} +0 -0
- /package/dist/{advertisers-SJO6JYIO.js.map → advertisers-G6DZRBOK.js.map} +0 -0
- /package/dist/{analytics-XDWBEY57.js.map → analytics-ANG42PKM.js.map} +0 -0
- /package/dist/{analytics-TXPEXLPQ.js.map → analytics-UI4AKUSF.js.map} +0 -0
- /package/dist/{animate-425S4ZXS.js.map → animate-KCSICY2N.js.map} +0 -0
- /package/dist/{approved-KUVAJ5M7.js.map → approved-LHYBVDXH.js.map} +0 -0
- /package/dist/{asset-writes-SSI3CO2A.js.map → asset-writes-CUF25BLM.js.map} +0 -0
- /package/dist/{assign-CTV6LDEI.js.map → assign-5DFH6HBV.js.map} +0 -0
- /package/dist/{audience-size-5QYI5PKH.js.map → audience-size-P6WIXOB3.js.map} +0 -0
- /package/dist/{audience-writes-G64754LR.js.map → audience-writes-L7SNU2SB.js.map} +0 -0
- /package/dist/{audiences-JZ6SCEUC.js.map → audiences-4ASLCNOF.js.map} +0 -0
- /package/dist/{audiences-JAVNJ5NC.js.map → audiences-A54MU63W.js.map} +0 -0
- /package/dist/{audiences-OMLKMHEJ.js.map → audiences-SG2BBM7R.js.map} +0 -0
- /package/dist/{audit-2YFDJAKL.js.map → audit-6K5FFV6K.js.map} +0 -0
- /package/dist/{audit-4UE6GFLG.js.map → audit-LA4BSLXV.js.map} +0 -0
- /package/dist/{autocomplete-HTUV2UDS.js.map → autocomplete-XMG6E7TG.js.map} +0 -0
- /package/dist/{avatars-K7RBSMIJ.js.map → avatars-4IFN4GZD.js.map} +0 -0
- /package/dist/{bid-pricing-OWP4SZP5.js.map → bid-pricing-JEOG2Q3L.js.map} +0 -0
- /package/dist/{brand-GBP4OEJI.js.map → brand-C6HUAK74.js.map} +0 -0
- /package/dist/{brief-SLTB3EPO.js.map → brief-5BCPPBU3.js.map} +0 -0
- /package/dist/{businesses-DXRDQIFP.js.map → businesses-GQ5FOZDU.js.map} +0 -0
- /package/dist/{campaign-groups-LDOQU65Q.js.map → campaign-groups-IYQZSICZ.js.map} +0 -0
- /package/dist/{campaign-writes-SHF3XZXV.js.map → campaign-writes-CVOOPZ35.js.map} +0 -0
- /package/dist/{campaign-writes-SK55QLY5.js.map → campaign-writes-YXI5UOPH.js.map} +0 -0
- /package/dist/{campaigns-6CAKRANC.js.map → campaigns-FW4WVD25.js.map} +0 -0
- /package/dist/{campaigns-EHV7J7PW.js.map → campaigns-QMFHNG3N.js.map} +0 -0
- /package/dist/{campaigns-GG7LLI4X.js.map → campaigns-TX37WHVL.js.map} +0 -0
- /package/dist/{campaigns-GQWFSKGC.js.map → campaigns-VZJMYETG.js.map} +0 -0
- /package/dist/{canvas-2VRPGRND.js.map → canvas-G4QXNPPE.js.map} +0 -0
- /package/dist/{capabilities-BEZXR2FZ.js.map → capabilities-7643Y2HU.js.map} +0 -0
- /package/dist/{cards-J2PGFKEF.js.map → cards-YHZFJ3US.js.map} +0 -0
- /package/dist/{catalog-XECCXRM6.js.map → catalog-PTVQSATT.js.map} +0 -0
- /package/dist/{catalogs-P5KMIMC2.js.map → catalogs-YNIUP2AH.js.map} +0 -0
- /package/dist/{catalogs-TBRONC2D.js.map → catalogs-ZHCLH43A.js.map} +0 -0
- /package/dist/{changes-3COSIJLU.js.map → changes-QUKBZVB3.js.map} +0 -0
- /package/dist/{chatgpt-S5EVEKYV.js.map → chatgpt-TIUBMATF.js.map} +0 -0
- /package/dist/{chats-AN52YVBT.js.map → chats-BGLAG4Q7.js.map} +0 -0
- /package/dist/{check-AQO7CMDD.js.map → check-MN5ZQ7RX.js.map} +0 -0
- /package/dist/{chunk-TE4ASZSC.js.map → chunk-23KN4NL4.js.map} +0 -0
- /package/dist/{chunk-WPSLL3S2.js.map → chunk-2UJ5ABI6.js.map} +0 -0
- /package/dist/{chunk-V62ZWGCL.js.map → chunk-2XRFWXSA.js.map} +0 -0
- /package/dist/{chunk-6M77QNJ4.js.map → chunk-3JV4T6XW.js.map} +0 -0
- /package/dist/{chunk-CSCHS3JG.js.map → chunk-3OSBCYKA.js.map} +0 -0
- /package/dist/{chunk-4JS2O2KV.js.map → chunk-3QQHPRRB.js.map} +0 -0
- /package/dist/{chunk-ILEJXJH2.js.map → chunk-3WTCMBDC.js.map} +0 -0
- /package/dist/{chunk-5CTNSIWY.js.map → chunk-4BTUF2AV.js.map} +0 -0
- /package/dist/{chunk-4745PLPI.js.map → chunk-4D37LCBS.js.map} +0 -0
- /package/dist/{chunk-XRSRHAEU.js.map → chunk-4QITYZUH.js.map} +0 -0
- /package/dist/{chunk-PGBZ73UZ.js.map → chunk-4XNF52NU.js.map} +0 -0
- /package/dist/{chunk-T6PTG6VM.js.map → chunk-4Y7IJ2PU.js.map} +0 -0
- /package/dist/{chunk-GDQJG4BO.js.map → chunk-53BTYIMJ.js.map} +0 -0
- /package/dist/{chunk-QNXDSNOQ.js.map → chunk-5ITB24SC.js.map} +0 -0
- /package/dist/{chunk-MZIYRWXL.js.map → chunk-5N47LB7X.js.map} +0 -0
- /package/dist/{chunk-FOWT6ENH.js.map → chunk-5UBFYJHF.js.map} +0 -0
- /package/dist/{chunk-SP5L7EYC.js.map → chunk-6CQOHJZW.js.map} +0 -0
- /package/dist/{chunk-GLCHD54W.js.map → chunk-6OXENBTF.js.map} +0 -0
- /package/dist/{chunk-VCUXAPLM.js.map → chunk-6PMJU7IU.js.map} +0 -0
- /package/dist/{chunk-3H5MJOG2.js.map → chunk-7GGLZOQN.js.map} +0 -0
- /package/dist/{chunk-DJWEQDBB.js.map → chunk-7I65KXU7.js.map} +0 -0
- /package/dist/{chunk-4XXA4WCS.js.map → chunk-7JFVMJZI.js.map} +0 -0
- /package/dist/{chunk-WPAW6EVY.js.map → chunk-A6VODUO3.js.map} +0 -0
- /package/dist/{chunk-R44B522K.js.map → chunk-AGTA5FJX.js.map} +0 -0
- /package/dist/{chunk-V2XEX2YR.js.map → chunk-AGU4KGT6.js.map} +0 -0
- /package/dist/{chunk-LHQ6GXNF.js.map → chunk-BXUUKRMM.js.map} +0 -0
- /package/dist/{chunk-DW3OPKXI.js.map → chunk-BZTAEZLT.js.map} +0 -0
- /package/dist/{chunk-ZNXP3WNJ.js.map → chunk-C7IOSSI4.js.map} +0 -0
- /package/dist/{chunk-B4UVJCJ4.js.map → chunk-CIW3Q7B2.js.map} +0 -0
- /package/dist/{chunk-SPBNAGIN.js.map → chunk-CJQ77HO5.js.map} +0 -0
- /package/dist/{chunk-6B4KNOJZ.js.map → chunk-CNPYG4F3.js.map} +0 -0
- /package/dist/{chunk-C5UFKDAX.js.map → chunk-COS3TPHX.js.map} +0 -0
- /package/dist/{chunk-GT77XMOG.js.map → chunk-CQ6HBFOB.js.map} +0 -0
- /package/dist/{chunk-LS2KEAYJ.js.map → chunk-D7Y3UNWO.js.map} +0 -0
- /package/dist/{chunk-5EF7ZLXA.js.map → chunk-DJTWY7GL.js.map} +0 -0
- /package/dist/{chunk-JCVPZ7CV.js.map → chunk-DWW5QSUF.js.map} +0 -0
- /package/dist/{chunk-TEKML2NW.js.map → chunk-E34YYDCE.js.map} +0 -0
- /package/dist/{chunk-3WSJGYA3.js.map → chunk-ENUCJ6AO.js.map} +0 -0
- /package/dist/{chunk-DNWP5DL6.js.map → chunk-FESQ5TXU.js.map} +0 -0
- /package/dist/{chunk-UPDIBQUC.js.map → chunk-FEUKUZRA.js.map} +0 -0
- /package/dist/{chunk-U2BPZ27S.js.map → chunk-FJDSL4O5.js.map} +0 -0
- /package/dist/{chunk-CREEY2FS.js.map → chunk-FSTDWVXG.js.map} +0 -0
- /package/dist/{chunk-XVHR2NCG.js.map → chunk-FUR7R4D7.js.map} +0 -0
- /package/dist/{chunk-FBG3JDET.js.map → chunk-GYMZCJX6.js.map} +0 -0
- /package/dist/{chunk-R5GGTLYE.js.map → chunk-HTT7RBRC.js.map} +0 -0
- /package/dist/{chunk-BN4TDL5L.js.map → chunk-IQWFJEA3.js.map} +0 -0
- /package/dist/{chunk-XZWBLUDV.js.map → chunk-IU5K42Q3.js.map} +0 -0
- /package/dist/{chunk-EZBZU6N7.js.map → chunk-JARRF5VX.js.map} +0 -0
- /package/dist/{chunk-RUJS2NOA.js.map → chunk-JEUFRIYS.js.map} +0 -0
- /package/dist/{chunk-LURM3KKS.js.map → chunk-JNSRQQDP.js.map} +0 -0
- /package/dist/{chunk-MHH7SGLS.js.map → chunk-KGAI4E2I.js.map} +0 -0
- /package/dist/{chunk-SDQLZYQG.js.map → chunk-KITVYLEX.js.map} +0 -0
- /package/dist/{chunk-J4ASA24X.js.map → chunk-L5VVKIMB.js.map} +0 -0
- /package/dist/{chunk-SWNCS2OD.js.map → chunk-L763CNKH.js.map} +0 -0
- /package/dist/{chunk-4VXQAJRU.js.map → chunk-LO2MZJJP.js.map} +0 -0
- /package/dist/{chunk-HPDGVK6R.js.map → chunk-LV7EU6HM.js.map} +0 -0
- /package/dist/{chunk-QNLPZOHV.js.map → chunk-LXZ5E6AC.js.map} +0 -0
- /package/dist/{chunk-KRQ2AXFW.js.map → chunk-LZRZVIEJ.js.map} +0 -0
- /package/dist/{chunk-YUCGCJKT.js.map → chunk-M2MJ52HS.js.map} +0 -0
- /package/dist/{chunk-DLNADMQV.js.map → chunk-MBSAHNMJ.js.map} +0 -0
- /package/dist/{chunk-GEFZVG4P.js.map → chunk-MCKYNFPH.js.map} +0 -0
- /package/dist/{chunk-ZBUIWVF3.js.map → chunk-MHZIOOT5.js.map} +0 -0
- /package/dist/{chunk-364TCROV.js.map → chunk-MNOCC5AL.js.map} +0 -0
- /package/dist/{chunk-WW6JLISJ.js.map → chunk-MUEJVDHI.js.map} +0 -0
- /package/dist/{chunk-XWO6CXNG.js.map → chunk-N6WHUUFH.js.map} +0 -0
- /package/dist/{chunk-FVZL2YC5.js.map → chunk-NA5Q473J.js.map} +0 -0
- /package/dist/{chunk-AXTOIHH2.js.map → chunk-NCO5NGBN.js.map} +0 -0
- /package/dist/{chunk-X3HPRECW.js.map → chunk-NLW25WW3.js.map} +0 -0
- /package/dist/{chunk-TKDOVFO6.js.map → chunk-NYAFSC5V.js.map} +0 -0
- /package/dist/{chunk-AFQF6ISC.js.map → chunk-O7AMKMII.js.map} +0 -0
- /package/dist/{chunk-7HH4F2KX.js.map → chunk-OL3QHART.js.map} +0 -0
- /package/dist/{chunk-Y25HSPRJ.js.map → chunk-OPUEQSKM.js.map} +0 -0
- /package/dist/{chunk-3J3W23S4.js.map → chunk-OXLB5M5M.js.map} +0 -0
- /package/dist/{chunk-QJ5TU5J6.js.map → chunk-OXYWSVOJ.js.map} +0 -0
- /package/dist/{chunk-XGX2WOV2.js.map → chunk-PE4ZP7MX.js.map} +0 -0
- /package/dist/{chunk-NY5VYGTP.js.map → chunk-PHZOMTI6.js.map} +0 -0
- /package/dist/{chunk-T37PAZT2.js.map → chunk-PIAG4UJT.js.map} +0 -0
- /package/dist/{chunk-KG7FPYM2.js.map → chunk-PYWIHAVD.js.map} +0 -0
- /package/dist/{chunk-SNDHR5QA.js.map → chunk-QKNPF6ZD.js.map} +0 -0
- /package/dist/{chunk-ZFJ2FQUH.js.map → chunk-QOBA6PHB.js.map} +0 -0
- /package/dist/{chunk-3KMYOPBI.js.map → chunk-QPPQXU3U.js.map} +0 -0
- /package/dist/{chunk-TTKDFRON.js.map → chunk-QTKNS2U2.js.map} +0 -0
- /package/dist/{chunk-SJAUMPL3.js.map → chunk-QTLIXCVN.js.map} +0 -0
- /package/dist/{chunk-O37YK4P6.js.map → chunk-R5LRBDEM.js.map} +0 -0
- /package/dist/{chunk-TRMZQRVV.js.map → chunk-RRC7F3QQ.js.map} +0 -0
- /package/dist/{chunk-ERRTBCDW.js.map → chunk-SEYCF446.js.map} +0 -0
- /package/dist/{chunk-GXPZJ2QN.js.map → chunk-SF52UGHZ.js.map} +0 -0
- /package/dist/{chunk-ZVXKWLLE.js.map → chunk-SVNH6P7O.js.map} +0 -0
- /package/dist/{chunk-34FVKJS2.js.map → chunk-SWFZJROM.js.map} +0 -0
- /package/dist/{chunk-SEC6FPWC.js.map → chunk-UCNIJ2IW.js.map} +0 -0
- /package/dist/{chunk-R6T25WTZ.js.map → chunk-UFUYTWEF.js.map} +0 -0
- /package/dist/{chunk-L5IYVZM2.js.map → chunk-ULW4EWAA.js.map} +0 -0
- /package/dist/{chunk-ECJIMIEJ.js.map → chunk-UROKPFIS.js.map} +0 -0
- /package/dist/{chunk-4ULRDQVD.js.map → chunk-VCOIFNYH.js.map} +0 -0
- /package/dist/{chunk-52IYZCRS.js.map → chunk-VPF5A7CM.js.map} +0 -0
- /package/dist/{chunk-HAJYFRXL.js.map → chunk-VV6FDIP5.js.map} +0 -0
- /package/dist/{chunk-XJHUSJY6.js.map → chunk-WRTG3KXU.js.map} +0 -0
- /package/dist/{chunk-2SGREP24.js.map → chunk-XAW5GL6B.js.map} +0 -0
- /package/dist/{chunk-7O4HFODK.js.map → chunk-XRNJRQ6Q.js.map} +0 -0
- /package/dist/{chunk-PN72Z2W2.js.map → chunk-Y5GQO6CR.js.map} +0 -0
- /package/dist/{chunk-62QMJYML.js.map → chunk-YE4RCEEJ.js.map} +0 -0
- /package/dist/{chunk-EHIISZYD.js.map → chunk-YJYKSMLF.js.map} +0 -0
- /package/dist/{chunk-W7C7HZFJ.js.map → chunk-YO54MA7R.js.map} +0 -0
- /package/dist/{chunk-2MXDSPUO.js.map → chunk-Z6T6VDDA.js.map} +0 -0
- /package/dist/{chunk-XPDUBDPL.js.map → chunk-ZOH672S6.js.map} +0 -0
- /package/dist/{claim-NRNO4XCO.js.map → claim-2JNNC66N.js.map} +0 -0
- /package/dist/{client-463NKLRT.js.map → client-YUVT3RZN.js.map} +0 -0
- /package/dist/{code-R4JOQ27J.js.map → code-LOOWLRUL.js.map} +0 -0
- /package/dist/{companies-4TOBU44J.js.map → companies-4NJU5TLU.js.map} +0 -0
- /package/dist/{company-RK34S3IA.js.map → company-QOYWS4W6.js.map} +0 -0
- /package/dist/{complete-7BNBQ5AI.js.map → complete-7FX2K3PV.js.map} +0 -0
- /package/dist/{config-GDLHHBJZ.js.map → config-AOF6ACIP.js.map} +0 -0
- /package/dist/{connect-CRIRSXN3.js.map → connect-H2HSPMRT.js.map} +0 -0
- /package/dist/{content-FCO6MGXW.js.map → content-NCW5IJFR.js.map} +0 -0
- /package/dist/{conversation-4CQG2B2C.js.map → conversation-4M7YMQOL.js.map} +0 -0
- /package/dist/{conversion-report-PDTQTRVB.js.map → conversion-report-G5JMZNYV.js.map} +0 -0
- /package/dist/{conversion-upload-command-MEO4WLZH.js.map → conversion-upload-command-43PZFYT7.js.map} +0 -0
- /package/dist/{conversion-writes-ZVBOXUIA.js.map → conversion-writes-JQQCCGPO.js.map} +0 -0
- /package/dist/{conversions-BND5HYTL.js.map → conversions-UO4CQNF6.js.map} +0 -0
- /package/dist/{conversions-POBKTXQF.js.map → conversions-Z7FW7CFT.js.map} +0 -0
- /package/dist/{copy-writes-EUFEVWDW.js.map → copy-writes-ONVSSBLJ.js.map} +0 -0
- /package/dist/{countries-TKL5T5JL.js.map → countries-Q6TA42P7.js.map} +0 -0
- /package/dist/{create-BJ7XBNY5.js.map → create-4SFO4AQZ.js.map} +0 -0
- /package/dist/{create-YSGBH6Q4.js.map → create-D5MA64KL.js.map} +0 -0
- /package/dist/{create-XN4KVB5U.js.map → create-GJ4ZMY3A.js.map} +0 -0
- /package/dist/{create-PYP3QWTL.js.map → create-QVY6DSYM.js.map} +0 -0
- /package/dist/{creatives-ANTJUTIE.js.map → creatives-ADH6HCCA.js.map} +0 -0
- /package/dist/{creatives-57XIJAEG.js.map → creatives-R3XILT6D.js.map} +0 -0
- /package/dist/{creatives-6VJDUHEY.js.map → creatives-S3EZCXUT.js.map} +0 -0
- /package/dist/{credentials-KIH6ICDU.js.map → credentials-EQRB6XGZ.js.map} +0 -0
- /package/dist/{critique-GWRXVXVG.js.map → critique-4YRRUNAU.js.map} +0 -0
- /package/dist/{critique-MZUTDK4V.js.map → critique-JCU2ATT6.js.map} +0 -0
- /package/dist/{crm-QSHUYXTW.js.map → crm-AF6XOOSF.js.map} +0 -0
- /package/dist/{crm-Y5QTZAHO.js.map → crm-LSMFGR6R.js.map} +0 -0
- /package/dist/{crop-WKTW3EMP.js.map → crop-RDP7YCNV.js.map} +0 -0
- /package/dist/{currency-PTOI5SPU.js.map → currency-4KNOOZUU.js.map} +0 -0
- /package/dist/{custom-conversions-NDY5RHSM.js.map → custom-conversions-7MZFTHUM.js.map} +0 -0
- /package/dist/{customers-2G32E6W7.js.map → customers-MM3VIZNA.js.map} +0 -0
- /package/dist/{decide-X2UAKYXK.js.map → decide-OPCCKAIT.js.map} +0 -0
- /package/dist/{delete-3H6YH4YK.js.map → delete-CO2YBPTI.js.map} +0 -0
- /package/dist/{delete-HIAZHA56.js.map → delete-D7HTW32U.js.map} +0 -0
- /package/dist/{delete-2ZTMTKYD.js.map → delete-GKQTDOZF.js.map} +0 -0
- /package/dist/{delete-I43JQH2E.js.map → delete-JUPBYK3H.js.map} +0 -0
- /package/dist/{delete-RF44ILYE.js.map → delete-R3LXCKA4.js.map} +0 -0
- /package/dist/{demographics-2UYQW6II.js.map → demographics-DK5JDY6M.js.map} +0 -0
- /package/dist/{describe-M6DYXNQC.js.map → describe-537PPL7P.js.map} +0 -0
- /package/dist/{describe-OQ6R3EF7.js.map → describe-GIG46DT5.js.map} +0 -0
- /package/dist/{dimensions-DGYM5E5P.js.map → dimensions-UXK7DMTF.js.map} +0 -0
- /package/dist/{discard-NKPQ73UM.js.map → discard-DEJOM62Y.js.map} +0 -0
- /package/dist/{discover-XLIH7RCB.js.map → discover-MKFDG6NK.js.map} +0 -0
- /package/dist/{discover-YKMBVSPF.js.map → discover-U6YLVLTF.js.map} +0 -0
- /package/dist/{domain-LUDUZB3F.js.map → domain-MBOMV3CQ.js.map} +0 -0
- /package/dist/{download-LL6DL62N.js.map → download-KN2I55SA.js.map} +0 -0
- /package/dist/{download-SFWMT7DL.js.map → download-PRBLR6IQ.js.map} +0 -0
- /package/dist/{draft-7LPUJZCF.js.map → draft-BMNBT37B.js.map} +0 -0
- /package/dist/{draft-T7TWIFEX.js.map → draft-CGPVRRKC.js.map} +0 -0
- /package/dist/{draft-736FJJWK.js.map → draft-F74OIT5O.js.map} +0 -0
- /package/dist/{draft-MPWR47CG.js.map → draft-FIEZWBIX.js.map} +0 -0
- /package/dist/{draft-G432FJ7N.js.map → draft-H5RVDTFD.js.map} +0 -0
- /package/dist/{draft-XAAIGE6Q.js.map → draft-HZ5T6NOI.js.map} +0 -0
- /package/dist/{draft-R5ND5SWT.js.map → draft-UMPCOCP6.js.map} +0 -0
- /package/dist/{draft-374Z4MGY.js.map → draft-XEUHTUMR.js.map} +0 -0
- /package/dist/{env-DQHY5ODN.js.map → env-VBSATLEF.js.map} +0 -0
- /package/dist/{experiment-MO6MT6OJ.js.map → experiment-2XR6MBE2.js.map} +0 -0
- /package/dist/{experiments-OGZV73W6.js.map → experiments-YNJZCMQM.js.map} +0 -0
- /package/dist/{export-6Z6QBU6V.js.map → export-YCLJG5YP.js.map} +0 -0
- /package/dist/{extract-YGOQBOQK.js.map → extract-E3CMEN5U.js.map} +0 -0
- /package/dist/{facets-OLZ7JLFL.js.map → facets-Y4OACBMC.js.map} +0 -0
- /package/dist/{favorites-R3JO4SJJ.js.map → favorites-NSQX6HKB.js.map} +0 -0
- /package/dist/{feed-IUMMHM3I.js.map → feed-TKMMYAEH.js.map} +0 -0
- /package/dist/{feedback-TJRYTOR3.js.map → feedback-MORAVN52.js.map} +0 -0
- /package/dist/{feedback-record-7IAJI5IY.js.map → feedback-record-M3RB7H2C.js.map} +0 -0
- /package/dist/{fetch-AL44XS4Q.js.map → fetch-EHP2FK6Y.js.map} +0 -0
- /package/dist/{fetch-K3NRT2L2.js.map → fetch-XU6QVWMS.js.map} +0 -0
- /package/dist/{find-ZFIGMRYQ.js.map → find-I7U3THF3.js.map} +0 -0
- /package/dist/{fit-5NVXWXZV.js.map → fit-IHUUFCGI.js.map} +0 -0
- /package/dist/{flows-LL5SPPIK.js.map → flows-WSCIMXQX.js.map} +0 -0
- /package/dist/{follow-SS374QUW.js.map → follow-A46RAJEX.js.map} +0 -0
- /package/dist/{follow-competitors-3LTOTTBY.js.map → follow-competitors-VU2L3KWF.js.map} +0 -0
- /package/dist/{following-YMA5O3LF.js.map → following-UOUNSU6P.js.map} +0 -0
- /package/dist/{fonts-E3CNWPD5.js.map → fonts-3QW7EDHE.js.map} +0 -0
- /package/dist/{forecast-KOBF5TKM.js.map → forecast-2WVHMSZP.js.map} +0 -0
- /package/dist/{forecast-PWGN4ETP.js.map → forecast-F25LSCM5.js.map} +0 -0
- /package/dist/{funding-KLIZ73SS.js.map → funding-2VROIMLS.js.map} +0 -0
- /package/dist/{funnel-XIZROHV7.js.map → funnel-35DYDBJH.js.map} +0 -0
- /package/dist/{ga4-XPCE4EK5.js.map → ga4-ULHKTF23.js.map} +0 -0
- /package/dist/{generate-GHIXVLMY.js.map → generate-Z7AROAES.js.map} +0 -0
- /package/dist/{get-WS744HAO.js.map → get-4CAX33L2.js.map} +0 -0
- /package/dist/{get-HCGFATFD.js.map → get-ABQZJ2VQ.js.map} +0 -0
- /package/dist/{get-RDTJSWSA.js.map → get-IF7KHMSI.js.map} +0 -0
- /package/dist/{get-XPJ4BZGP.js.map → get-N7X75ZJO.js.map} +0 -0
- /package/dist/{get-SGNT4JG2.js.map → get-ZISAHMTQ.js.map} +0 -0
- /package/dist/{gif-YK5HJXRE.js.map → gif-QLNWBFAH.js.map} +0 -0
- /package/dist/{google-BI45CXMW.js.map → google-FDR55RRD.js.map} +0 -0
- /package/dist/{google-5JV7OMOH.js.map → google-M6XR7YGT.js.map} +0 -0
- /package/dist/{google-ads-DYZGUM6W.js.map → google-ads-NCSMNNND.js.map} +0 -0
- /package/dist/{group-7OWIYAKJ.js.map → group-HAQM6P7M.js.map} +0 -0
- /package/dist/{group-H6ZYRPE6.js.map → group-XVDH2ONO.js.map} +0 -0
- /package/dist/{gsc-HI2KXDEU.js.map → gsc-72AFO6B4.js.map} +0 -0
- /package/dist/{history-3EQQHYKT.js.map → history-FGQ2H7XH.js.map} +0 -0
- /package/dist/{history-SQPJ7PPE.js.map → history-LTOFKBMJ.js.map} +0 -0
- /package/dist/{history-RD2YMNNL.js.map → history-VJ254UXF.js.map} +0 -0
- /package/dist/{hubspot-MYTV36SM.js.map → hubspot-W2NM75YK.js.map} +0 -0
- /package/dist/{icon-HLJCWTR3.js.map → icon-F7AOOTFI.js.map} +0 -0
- /package/dist/{ideas-CVXHFVX7.js.map → ideas-54KFDNDM.js.map} +0 -0
- /package/dist/{images-XP4TKE2F.js.map → images-JOEVCCP6.js.map} +0 -0
- /package/dist/{improve-BRC4R6MW.js.map → improve-LIKOER3S.js.map} +0 -0
- /package/dist/{ingest-4GNJ2PWL.js.map → ingest-6R7XUL46.js.map} +0 -0
- /package/dist/{insights-IVW6W5CP.js.map → insights-QNE6XCBA.js.map} +0 -0
- /package/dist/{insights-CN3GUTT7.js.map → insights-UXUUOQB7.js.map} +0 -0
- /package/dist/{inspect-25IVRU45.js.map → inspect-MGOR77FP.js.map} +0 -0
- /package/dist/{inspiration-D75DO3MD.js.map → inspiration-VXNGKAJV.js.map} +0 -0
- /package/dist/{instant-experiences-6F6GXZ67.js.map → instant-experiences-MT2XMQNH.js.map} +0 -0
- /package/dist/{intent-3GDLPKKN.js.map → intent-FZWPRUCI.js.map} +0 -0
- /package/dist/{job-2JJNKUHT.js.map → job-TS34W4IU.js.map} +0 -0
- /package/dist/{job-create-BNTNZCSP.js.map → job-create-FXXDR2EE.js.map} +0 -0
- /package/dist/{job-status-N7RWRDRO.js.map → job-status-R2H4HNC5.js.map} +0 -0
- /package/dist/{keep-Z2WH3CKU.js.map → keep-YSU3XMW3.js.map} +0 -0
- /package/dist/{keyword-gap-B2WPVHOB.js.map → keyword-gap-4ECYPWXJ.js.map} +0 -0
- /package/dist/{keyword-metrics-UDGWN7BO.js.map → keyword-metrics-SBIRN5KC.js.map} +0 -0
- /package/dist/{keywords-for-site-GEG6AXD3.js.map → keywords-for-site-TLNPJHT2.js.map} +0 -0
- /package/dist/{knowledge-PKXPN4RV.js.map → knowledge-L3VLOVLG.js.map} +0 -0
- /package/dist/{landing-O2ZUIUGE.js.map → landing-ZICSVWKF.js.map} +0 -0
- /package/dist/{landings-7QRITXZ2.js.map → landings-XTPNPTHN.js.map} +0 -0
- /package/dist/{languages-RZLMZR57.js.map → languages-DIKRMAYE.js.map} +0 -0
- /package/dist/{languages-UJAOPTV2.js.map → languages-VNZQ5USL.js.map} +0 -0
- /package/dist/{launches-4H6ANGTG.js.map → launches-5R7EUONQ.js.map} +0 -0
- /package/dist/{layerize-P5LFIA4X.js.map → layerize-Q2QWDARG.js.map} +0 -0
- /package/dist/{lead-routes-WVXWVG62.js.map → lead-routes-IXUCGINI.js.map} +0 -0
- /package/dist/{leads-MTTOYNPM.js.map → leads-JUQFNK55.js.map} +0 -0
- /package/dist/{leads-CJKRKB2Q.js.map → leads-UVG6VYAC.js.map} +0 -0
- /package/dist/{learn-QPXZZIZZ.js.map → learn-A6BT25LQ.js.map} +0 -0
- /package/dist/{library-VW27X75P.js.map → library-G5YAFLTR.js.map} +0 -0
- /package/dist/{lighthouse-FGUFJRGR.js.map → lighthouse-BCBV2XGP.js.map} +0 -0
- /package/dist/{line-item-writes-RVOAMJ5R.js.map → line-item-writes-NW7A6HNH.js.map} +0 -0
- /package/dist/{line-items-POZRAJLC.js.map → line-items-OAG3QMDE.js.map} +0 -0
- /package/dist/{link-IXEZKRM7.js.map → link-4VJ7FSOA.js.map} +0 -0
- /package/dist/{linkedin-5PYG5HEM.js.map → linkedin-CKOWKD4M.js.map} +0 -0
- /package/dist/{linkedin-person-EMJXEZYR.js.map → linkedin-person-C22IDK7S.js.map} +0 -0
- /package/dist/{list-OZCU2T22.js.map → list-2DKLO6AO.js.map} +0 -0
- /package/dist/{list-7GDMM26I.js.map → list-4SDJZVOL.js.map} +0 -0
- /package/dist/{list-UG4V5AM2.js.map → list-6YW4I4VG.js.map} +0 -0
- /package/dist/{list-4KS7WSUG.js.map → list-CDDXHMJQ.js.map} +0 -0
- /package/dist/{list-PTK2HOUY.js.map → list-GS42LK5C.js.map} +0 -0
- /package/dist/{list-Q5LVTPQP.js.map → list-HWNHRWGB.js.map} +0 -0
- /package/dist/{list-J5KWXHFO.js.map → list-QSBEYU45.js.map} +0 -0
- /package/dist/{list-DVVOP6FM.js.map → list-ZFGOONWL.js.map} +0 -0
- /package/dist/{list-XOYU7UTX.js.map → list-ZORO7PFP.js.map} +0 -0
- /package/dist/{locations-VJX64ZZR.js.map → locations-4RDUHKVR.js.map} +0 -0
- /package/dist/{locations-EISZ6JOT.js.map → locations-HATR6PSC.js.map} +0 -0
- /package/dist/{log-2F2N24DT.js.map → log-OSJHKHPV.js.map} +0 -0
- /package/dist/{logo-H2KHGLYD.js.map → logo-ABO4HJRG.js.map} +0 -0
- /package/dist/{lookup-K57ITJWF.js.map → lookup-SPNT3W3W.js.map} +0 -0
- /package/dist/{make-T6HLXIYY.js.map → make-7CIVNW77.js.map} +0 -0
- /package/dist/{map-QGJZIC5N.js.map → map-PMGZDXAN.js.map} +0 -0
- /package/dist/{mcp-RSW7KAWP.js.map → mcp-MOOOTRYG.js.map} +0 -0
- /package/dist/{media-K5RJXLTN.js.map → media-CIJW2Q3I.js.map} +0 -0
- /package/dist/{media-HDHZULQ7.js.map → media-GZKW2PZB.js.map} +0 -0
- /package/dist/{media-sources-7R7FO53Y.js.map → media-sources-5OYCKQ5J.js.map} +0 -0
- /package/dist/{members-B6TKGGT5.js.map → members-QG5IP5HM.js.map} +0 -0
- /package/dist/{meme-QMCUGXUE.js.map → meme-BPWX7YQH.js.map} +0 -0
- /package/dist/{meta-MOSJVYIE.js.map → meta-KVOSCSPJ.js.map} +0 -0
- /package/dist/{metrics-PRIKXVYZ.js.map → metrics-R4YS2JL6.js.map} +0 -0
- /package/dist/{models-M3E4YFCT.js.map → models-RJMZV5SH.js.map} +0 -0
- /package/dist/{normalize-5B4EQLUX.js.map → normalize-LATTXSL3.js.map} +0 -0
- /package/dist/{normalize-5QIGANTK.js.map → normalize-NMNOJ6Q5.js.map} +0 -0
- /package/dist/{options-K33CJOR6.js.map → options-KALH5TB7.js.map} +0 -0
- /package/dist/{organization-A4NFWWWI.js.map → organization-AGCF7DUJ.js.map} +0 -0
- /package/dist/{output-U5ZV6PST.js.map → output-34QMC3OU.js.map} +0 -0
- /package/dist/{page-XVOUD4VV.js.map → page-UDF3LJHP.js.map} +0 -0
- /package/dist/{page-photos-4JTIKXAW.js.map → page-photos-FCBW5UZS.js.map} +0 -0
- /package/dist/{pages-BAUS7LQM.js.map → pages-5W5G4MRB.js.map} +0 -0
- /package/dist/{performance-MHJDRLEK.js.map → performance-SITVZQWX.js.map} +0 -0
- /package/dist/{performance-NVURSEZ6.js.map → performance-YNXPUSGJ.js.map} +0 -0
- /package/dist/{pinterest-NA6HGPMB.js.map → pinterest-IABDXLF5.js.map} +0 -0
- /package/dist/{pixels-QOSEYXCP.js.map → pixels-4QAWLSEL.js.map} +0 -0
- /package/dist/{pixels-THDQD3RF.js.map → pixels-TYJVE377.js.map} +0 -0
- /package/dist/{plan-JYSHKPZQ.js.map → plan-I6EFL7RC.js.map} +0 -0
- /package/dist/{posts-ILAFADBW.js.map → posts-SXQSLOFV.js.map} +0 -0
- /package/dist/{preview-X6EJGPAY.js.map → preview-7Y5LE24E.js.map} +0 -0
- /package/dist/{profile-YHI65VGK.js.map → profile-R5VPOOJU.js.map} +0 -0
- /package/dist/{promoted-tweet-writes-MXXVRLVQ.js.map → promoted-tweet-writes-NAHPJ3VD.js.map} +0 -0
- /package/dist/{promoted-tweets-HFLGXWX2.js.map → promoted-tweets-2XQ4MWAC.js.map} +0 -0
- /package/dist/{properties-ZLY6NYVK.js.map → properties-2D2BIDGC.js.map} +0 -0
- /package/dist/{publish-6ZXFUBGP.js.map → publish-UITYPUBD.js.map} +0 -0
- /package/dist/{query-HFHTLNDN.js.map → query-LB5H7IRK.js.map} +0 -0
- /package/dist/{query-ELD7WSFR.js.map → query-NDOYOIHL.js.map} +0 -0
- /package/dist/{query-WMEX73ZB.js.map → query-RE7NB2BK.js.map} +0 -0
- /package/dist/{questionnaire-Y37I64FO.js.map → questionnaire-U767HYDE.js.map} +0 -0
- /package/dist/{read-2HQEZIJW.js.map → read-3TCDDALC.js.map} +0 -0
- /package/dist/{reddit-BIHGJPGP.js.map → reddit-6XIARCTX.js.map} +0 -0
- /package/dist/{refresh-4O32S4YR.js.map → refresh-6UCN7PDX.js.map} +0 -0
- /package/dist/{refresh-LVV4SPLT.js.map → refresh-GIB6QQZS.js.map} +0 -0
- /package/dist/{release-VIPNSPQ5.js.map → release-IN65L23O.js.map} +0 -0
- /package/dist/{relevant-pages-B5SYN575.js.map → relevant-pages-W7IM6YQW.js.map} +0 -0
- /package/dist/{remove-TPOWWFZ6.js.map → remove-LZQHDFZF.js.map} +0 -0
- /package/dist/{remove-2E77743U.js.map → remove-X3XWVE2M.js.map} +0 -0
- /package/dist/{reopen-UOBTJBMQ.js.map → reopen-RMMQ55CH.js.map} +0 -0
- /package/dist/{rerun-UPDIXTEL.js.map → rerun-ON6YCJAL.js.map} +0 -0
- /package/dist/{research-ELM3KHGE.js.map → research-LZBPCXIW.js.map} +0 -0
- /package/dist/{research-FOJIDMSE.js.map → research-W5KUOBXZ.js.map} +0 -0
- /package/dist/{reset-FTLWUFZK.js.map → reset-MUWXTLIB.js.map} +0 -0
- /package/dist/{reset-GIXXLPHQ.js.map → reset-VQNKXFAF.js.map} +0 -0
- /package/dist/{resolve-QHR5JJTJ.js.map → resolve-DMGWLMTC.js.map} +0 -0
- /package/dist/{retry-NY5KFEDA.js.map → retry-YI4YLYTQ.js.map} +0 -0
- /package/dist/{retry-HNWXJR5U.js.map → retry-ZQUJPKQH.js.map} +0 -0
- /package/dist/{retry-failed-OAH7JQKD.js.map → retry-failed-PEAUXGNT.js.map} +0 -0
- /package/dist/{revenue-JFMUODJO.js.map → revenue-6YZAOMF6.js.map} +0 -0
- /package/dist/{rule-writes-A4BFYHPA.js.map → rule-writes-G25O5JZS.js.map} +0 -0
- /package/dist/{rules-56E55SGC.js.map → rules-FHVZEN4D.js.map} +0 -0
- /package/dist/{rules-HLREXY2M.js.map → rules-KSOAKEI3.js.map} +0 -0
- /package/dist/{rules-add-ZOPOWJMY.js.map → rules-add-7X46VTIJ.js.map} +0 -0
- /package/dist/{run-4UIPMCSN.js.map → run-TA6HYFKZ.js.map} +0 -0
- /package/dist/{run-GACZDI6Q.js.map → run-YORKHK6S.js.map} +0 -0
- /package/dist/{scaffold-ad-Z2HSN4PE.js.map → scaffold-ad-RHSHBCVV.js.map} +0 -0
- /package/dist/{scaffold-static-ad-ODZGTIM5.js.map → scaffold-static-ad-XNOGCMPF.js.map} +0 -0
- /package/dist/{scaffold-video-EHGAMEEP.js.map → scaffold-video-XEVJQ7QZ.js.map} +0 -0
- /package/dist/{schedule-ZATNBBWD.js.map → schedule-TMTLYULK.js.map} +0 -0
- /package/dist/{schedule-OFPSZVZ2.js.map → schedule-TNF6M6UD.js.map} +0 -0
- /package/dist/{scheduled-agents-4VY4CAA2.js.map → scheduled-agents-TS3WLRCM.js.map} +0 -0
- /package/dist/{schema-EYGPETLF.js.map → schema-2YQAQVON.js.map} +0 -0
- /package/dist/{schema-OGP4DUPP.js.map → schema-6S5ZEPBS.js.map} +0 -0
- /package/dist/{scrape-ZHL2BHS7.js.map → scrape-FDBYU3TU.js.map} +0 -0
- /package/dist/{screenshot-ADMRDYWN.js.map → screenshot-QSRWL4J6.js.map} +0 -0
- /package/dist/{search-CQUS7EOM.js.map → search-BOCQFUM3.js.map} +0 -0
- /package/dist/{search-MKVVMJ2Q.js.map → search-CENPR7GA.js.map} +0 -0
- /package/dist/{search-HF5ECIYW.js.map → search-GEXDRTAQ.js.map} +0 -0
- /package/dist/{search-6W4HXR2S.js.map → search-LFTFNDMC.js.map} +0 -0
- /package/dist/{search-QUF6LHQ5.js.map → search-LTUUAGZG.js.map} +0 -0
- /package/dist/{search-6ZWI2NML.js.map → search-PYLNVZXI.js.map} +0 -0
- /package/dist/{search-copy-O6FDX4HT.js.map → search-copy-RLRRR3LB.js.map} +0 -0
- /package/dist/{seeds-5TM3O3K3.js.map → seeds-E2GLHJ2T.js.map} +0 -0
- /package/dist/{select-FCQUYBKV.js.map → select-BXBNFGVL.js.map} +0 -0
- /package/dist/{sends-MZKHZZGJ.js.map → sends-NBTGBZT7.js.map} +0 -0
- /package/dist/{sequences-3CEVHGHB.js.map → sequences-UOIHUOD3.js.map} +0 -0
- /package/dist/{set-prompt-IBAG6BDA.js.map → set-prompt-JJWBB23C.js.map} +0 -0
- /package/dist/{setup-links-4STQ5B4P.js.map → setup-links-6ANVKZCE.js.map} +0 -0
- /package/dist/{shared-I3SB77VH.js.map → shared-IMDHTVSW.js.map} +0 -0
- /package/dist/{shopify-7LDHCWUQ.js.map → shopify-6ISTKZCA.js.map} +0 -0
- /package/dist/{site-I3NFMPJB.js.map → site-OIV55MGO.js.map} +0 -0
- /package/dist/{sitemaps-PLAWVXQL.js.map → sitemaps-6A6JFBV4.js.map} +0 -0
- /package/dist/{sites-WX2IBTZT.js.map → sites-PZLE5FFV.js.map} +0 -0
- /package/dist/{skills-O6EQOAMQ.js.map → skills-FBIVWINH.js.map} +0 -0
- /package/dist/{sources-ZM7LEIMM.js.map → sources-5L4S5BQV.js.map} +0 -0
- /package/dist/{sources-K2LILGTW.js.map → sources-GLJWZFHZ.js.map} +0 -0
- /package/dist/{stale-VR5QAYB6.js.map → stale-SK2SDGOT.js.map} +0 -0
- /package/dist/{stats-QQRYOMZA.js.map → stats-2NLNQBRY.js.map} +0 -0
- /package/dist/{status-5OMVGFCH.js.map → status-TD7ISXC5.js.map} +0 -0
- /package/dist/{sticker-654HS3K2.js.map → sticker-4NKFAGEK.js.map} +0 -0
- /package/dist/{stock-35LOO3YN.js.map → stock-XOXZGGU3.js.map} +0 -0
- /package/dist/{studies-IGOCWM7F.js.map → studies-C5IINK5Y.js.map} +0 -0
- /package/dist/{studio-3D42TUJX.js.map → studio-IDNM42JP.js.map} +0 -0
- /package/dist/{study-writes-Z5P2W7JH.js.map → study-writes-GJXLMM3D.js.map} +0 -0
- /package/dist/{suggest-JASHCOL5.js.map → suggest-Z553OSYW.js.map} +0 -0
- /package/dist/{sync-URIRLHTS.js.map → sync-CIRDY55O.js.map} +0 -0
- /package/dist/{sync-RCDODSOD.js.map → sync-PVIFUXX3.js.map} +0 -0
- /package/dist/{sync-6AN67IX3.js.map → sync-UBOHNOXB.js.map} +0 -0
- /package/dist/{sync-definition-MZUJOJYI.js.map → sync-definition-7NBT6LTK.js.map} +0 -0
- /package/dist/{tag-7YMFAZQQ.js.map → tag-22TFBGDG.js.map} +0 -0
- /package/dist/{tag-manager-LU4GAZ6R.js.map → tag-manager-QLZHU6NG.js.map} +0 -0
- /package/dist/{tags-6A7QOYBI.js.map → tags-3HB7N5WB.js.map} +0 -0
- /package/dist/{tags-JHT3Q6VO.js.map → tags-DG3XQ4SF.js.map} +0 -0
- /package/dist/{tags-MTVZJHCE.js.map → tags-T4EN6XYE.js.map} +0 -0
- /package/dist/{tags-KSMLT4G2.js.map → tags-T6THTVNP.js.map} +0 -0
- /package/dist/{tags-OU32R2SH.js.map → tags-XY6R2VJ6.js.map} +0 -0
- /package/dist/{targeting-7HXKBXWY.js.map → targeting-GNEBULXU.js.map} +0 -0
- /package/dist/{targeting-constants-QIB3UZHM.js.map → targeting-constants-GR6BVM2H.js.map} +0 -0
- /package/dist/{targeting-criteria-NUXZB7NP.js.map → targeting-criteria-CL472KJO.js.map} +0 -0
- /package/dist/{targets-LQ7HGI73.js.map → targets-7AQMSO6H.js.map} +0 -0
- /package/dist/{terms-X4OJWTQH.js.map → terms-LG7FYQOG.js.map} +0 -0
- /package/dist/{testimonials-Z2KOOMVH.js.map → testimonials-4QWVSEPU.js.map} +0 -0
- /package/dist/{themes-6KVP3COR.js.map → themes-ZTM4OVGK.js.map} +0 -0
- /package/dist/{top-companies-WWNPUJ23.js.map → top-companies-PMFYOAFK.js.map} +0 -0
- /package/dist/{transcript-P7HKVABU.js.map → transcript-YWFYNFWX.js.map} +0 -0
- /package/dist/{translate-II4JY2XW.js.map → translate-VMQHPX4B.js.map} +0 -0
- /package/dist/{triggers-Z3LV3KJR.js.map → triggers-JKXISN45.js.map} +0 -0
- /package/dist/{tweets-X5PTAT6F.js.map → tweets-IF5FFFTH.js.map} +0 -0
- /package/dist/{unfollow-S5LHFLGW.js.map → unfollow-CDUOZWM7.js.map} +0 -0
- /package/dist/{unlink-XTZA474P.js.map → unlink-IUAFDLBT.js.map} +0 -0
- /package/dist/{unstage-AVLORZLW.js.map → unstage-OVOZE6DA.js.map} +0 -0
- /package/dist/{unstage-QXOL5DXZ.js.map → unstage-ZYT5RNLK.js.map} +0 -0
- /package/dist/{update-UE4XVBKL.js.map → update-23Q4T2J5.js.map} +0 -0
- /package/dist/{update-5ZNS2DKP.js.map → update-74VME6PN.js.map} +0 -0
- /package/dist/{update-MDVZ24VQ.js.map → update-O22DAZVX.js.map} +0 -0
- /package/dist/{update-DDKNKV6M.js.map → update-Q3WJ3DQN.js.map} +0 -0
- /package/dist/{update-3NA6ABLW.js.map → update-QAWK3O7L.js.map} +0 -0
- /package/dist/{upload-SYFB2VTJ.js.map → upload-EAEILUQB.js.map} +0 -0
- /package/dist/{upscale-P5EYUVOZ.js.map → upscale-HB6L6SZG.js.map} +0 -0
- /package/dist/{url-options-DJZV3ADK.js.map → url-options-M7RX2TD4.js.map} +0 -0
- /package/dist/{url-params-Y5XQSDEF.js.map → url-params-E5ON6W2N.js.map} +0 -0
- /package/dist/{validate-BCK22BQL.js.map → validate-NB6PS5PF.js.map} +0 -0
- /package/dist/{variant-JQVZUUA4.js.map → variant-O7LXOA2E.js.map} +0 -0
- /package/dist/{videos-YCQVOOFE.js.map → videos-SS2Y6FJF.js.map} +0 -0
- /package/dist/{view-IKKRJ5YD.js.map → view-ED636LWD.js.map} +0 -0
- /package/dist/{viewer-check-5GREZIVJ.js.map → viewer-check-CWS6OVM7.js.map} +0 -0
- /package/dist/{web-7TPDDBI6.js.map → web-HT22JFQR.js.map} +0 -0
- /package/dist/{winners-4PKEVMUC.js.map → winners-ZG5SHNBS.js.map} +0 -0
- /package/dist/{winning-ads-7X5EWSJX.js.map → winning-ads-FXTP4PWZ.js.map} +0 -0
- /package/dist/{write-commands-V77MD5SC.js.map → write-commands-5YVQKO7E.js.map} +0 -0
- /package/dist/{write-commands-CTLF2M6L.js.map → write-commands-AIWR7NBO.js.map} +0 -0
- /package/dist/{write-commands-FIS6Y2MN.js.map → write-commands-UK6MKGHI.js.map} +0 -0
- /package/dist/{write-commands-CY734U34.js.map → write-commands-W3UN6F4Y.js.map} +0 -0
- /package/dist/{x-EMLFCHSG.js.map → x-KEMAY75C.js.map} +0 -0
|
@@ -0,0 +1,2241 @@
|
|
|
1
|
+
import {
|
|
2
|
+
INSPIRATION_HINTS
|
|
3
|
+
} from "./chunk-JNSRQQDP.js";
|
|
4
|
+
import {
|
|
5
|
+
perceptualHash
|
|
6
|
+
} from "./chunk-DGCUPJZD.js";
|
|
7
|
+
import "./chunk-CIW3Q7B2.js";
|
|
8
|
+
import "./chunk-O7AMKMII.js";
|
|
9
|
+
import {
|
|
10
|
+
captureBudgetMs,
|
|
11
|
+
captureProxyCredentials,
|
|
12
|
+
isProxyFailure,
|
|
13
|
+
nextPlannedRoute,
|
|
14
|
+
plannedRoutes,
|
|
15
|
+
refuseNonPublicUrl,
|
|
16
|
+
shouldEscalate
|
|
17
|
+
} from "./chunk-VPF5A7CM.js";
|
|
18
|
+
import {
|
|
19
|
+
registerSchema,
|
|
20
|
+
writeJson
|
|
21
|
+
} from "./chunk-HZPTQRX6.js";
|
|
22
|
+
import "./chunk-YQSBHWOI.js";
|
|
23
|
+
|
|
24
|
+
// src/commands/landing/inspiration/scrape.ts
|
|
25
|
+
import { defineCommand } from "citty";
|
|
26
|
+
|
|
27
|
+
// src/engine/landing-library/proxyFailure.ts
|
|
28
|
+
var PROXY_STATUS = 407;
|
|
29
|
+
var PROXY_NET_ERRORS = [
|
|
30
|
+
"ERR_TUNNEL_CONNECTION_FAILED",
|
|
31
|
+
"ERR_PROXY_CONNECTION_FAILED",
|
|
32
|
+
"ERR_PROXY_AUTH_REQUESTED",
|
|
33
|
+
"ERR_PROXY_CERTIFICATE_INVALID",
|
|
34
|
+
"ERR_UNEXPECTED_PROXY_AUTH",
|
|
35
|
+
"ERR_MANDATORY_PROXY_CONFIGURATION_FAILED",
|
|
36
|
+
"ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT"
|
|
37
|
+
];
|
|
38
|
+
var PROXY_UNAVAILABLE_MESSAGE = "We couldn't reach this page just now. Please try adding it again.";
|
|
39
|
+
function describeProxyFailure(error) {
|
|
40
|
+
const raw = error instanceof Error ? error.message : typeof error === "string" ? error : "";
|
|
41
|
+
if (!raw) return null;
|
|
42
|
+
const netError = /net::(ERR_[A-Z0-9_]+)/.exec(raw)?.[1];
|
|
43
|
+
if (!netError || !PROXY_NET_ERRORS.includes(netError)) return null;
|
|
44
|
+
return { code: "PROXY_UNAVAILABLE", message: PROXY_UNAVAILABLE_MESSAGE };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/engine/landing-library/unreachable.ts
|
|
48
|
+
var NET_ERROR_REASONS = [
|
|
49
|
+
{
|
|
50
|
+
prefixes: ["ERR_NAME_NOT_RESOLVED", "ERR_NAME_RESOLUTION_FAILED"],
|
|
51
|
+
message: "We couldn't find this site \u2014 check the address is spelled right."
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
prefixes: ["ERR_SSL_", "ERR_CERT_", "ERR_TLS_", "ERR_BAD_SSL_"],
|
|
55
|
+
message: "This site's secure connection is broken, so no browser can open it \u2014 including ours. That's a fault on their side, not something you can fix here."
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
prefixes: ["ERR_TOO_MANY_REDIRECTS"],
|
|
59
|
+
message: "This site kept redirecting us and never settled on a page."
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
prefixes: ["ERR_BLOCKED_BY_", "ERR_ACCESS_DENIED"],
|
|
63
|
+
message: "This site refused our visit, so we couldn't read the page."
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
prefixes: [
|
|
67
|
+
"ERR_CONNECTION_",
|
|
68
|
+
"ERR_ADDRESS_UNREACHABLE",
|
|
69
|
+
"ERR_EMPTY_RESPONSE",
|
|
70
|
+
"ERR_NETWORK_CHANGED",
|
|
71
|
+
"ERR_INTERNET_DISCONNECTED",
|
|
72
|
+
"ERR_SOCKET_NOT_CONNECTED",
|
|
73
|
+
"ERR_TIMED_OUT"
|
|
74
|
+
],
|
|
75
|
+
// No "try again later" here. This resolves to `SITE_UNREACHABLE`, which the
|
|
76
|
+
// corpus files as not worth re-running, so inviting a retry would promise
|
|
77
|
+
// something the retry surface then declines to do.
|
|
78
|
+
message: "This site didn't respond, so we couldn't read the page."
|
|
79
|
+
}
|
|
80
|
+
];
|
|
81
|
+
var GENERIC_UNREACHABLE = "We couldn't open this site, so there was no page to study.";
|
|
82
|
+
var TOO_SLOW = "This site took too long to load, so we stopped waiting. Try again later.";
|
|
83
|
+
function describeUnreachableSite(error) {
|
|
84
|
+
const raw = error instanceof Error ? error.message : typeof error === "string" ? error : "";
|
|
85
|
+
if (!raw) return null;
|
|
86
|
+
const netError = /net::(ERR_[A-Z0-9_]+)/.exec(raw)?.[1];
|
|
87
|
+
if (netError) {
|
|
88
|
+
const reason = NET_ERROR_REASONS.find(
|
|
89
|
+
(candidate) => candidate.prefixes.some((prefix) => netError.startsWith(prefix))
|
|
90
|
+
);
|
|
91
|
+
return { code: "SITE_UNREACHABLE", message: reason?.message ?? GENERIC_UNREACHABLE };
|
|
92
|
+
}
|
|
93
|
+
if (/Timeout \d+ms exceeded/.test(raw) || raw.includes("page.goto: Timeout")) {
|
|
94
|
+
return { code: "SITE_TOO_SLOW", message: TOO_SLOW };
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
function netErrorName(error) {
|
|
99
|
+
const raw = error instanceof Error ? error.message : typeof error === "string" ? error : "";
|
|
100
|
+
return raw ? /net::(ERR_[A-Z0-9_]+)/.exec(raw)?.[1] ?? null : null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// src/engine/landing-library/blocked.ts
|
|
104
|
+
var CHALLENGE_PHRASES = [
|
|
105
|
+
"just a moment",
|
|
106
|
+
"attention required",
|
|
107
|
+
"verify you are human",
|
|
108
|
+
"checking your browser",
|
|
109
|
+
"enable javascript and cookies to continue",
|
|
110
|
+
"unusual traffic",
|
|
111
|
+
"access denied",
|
|
112
|
+
"you have been blocked",
|
|
113
|
+
"request unsuccessful",
|
|
114
|
+
"are you a robot",
|
|
115
|
+
"security check",
|
|
116
|
+
"ddos protection",
|
|
117
|
+
"captcha"
|
|
118
|
+
];
|
|
119
|
+
var CHALLENGE_MARKERS = ["cf-browser-verification", "cf_chl_", "px-captcha", "_incapsula_", "distil_r_captcha"];
|
|
120
|
+
function detectBlockedPage(page) {
|
|
121
|
+
if (page.status === PROXY_STATUS) {
|
|
122
|
+
return { code: "PROXY_UNAVAILABLE", message: PROXY_UNAVAILABLE_MESSAGE };
|
|
123
|
+
}
|
|
124
|
+
if (page.status !== null && page.status >= 400) {
|
|
125
|
+
return {
|
|
126
|
+
code: "HTTP_ERROR",
|
|
127
|
+
message: `The site returned ${page.status} instead of the page \u2014 it may be blocking automated visits.`
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const haystack = `${page.title}
|
|
131
|
+
${page.bodyText.slice(0, 2e3)}`.toLowerCase();
|
|
132
|
+
const phrase = CHALLENGE_PHRASES.find((candidate) => haystack.includes(candidate));
|
|
133
|
+
if (phrase) {
|
|
134
|
+
return { code: "BOT_CHALLENGE", message: "The site showed a security check instead of the page." };
|
|
135
|
+
}
|
|
136
|
+
const html = page.html?.toLowerCase() ?? "";
|
|
137
|
+
if (CHALLENGE_MARKERS.some((marker) => html.includes(marker))) {
|
|
138
|
+
return { code: "BOT_CHALLENGE", message: "The site showed a security check instead of the page." };
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
var BlockedPageError = class extends Error {
|
|
143
|
+
code;
|
|
144
|
+
constructor(blocked) {
|
|
145
|
+
super(blocked.message);
|
|
146
|
+
this.name = "BlockedPageError";
|
|
147
|
+
this.code = blocked.code;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
var CaptureFailureError = class extends Error {
|
|
151
|
+
failure;
|
|
152
|
+
/**
|
|
153
|
+
* Which rungs were tried, and what each of them said.
|
|
154
|
+
*
|
|
155
|
+
* Carried out of the engine because nothing downstream could otherwise tell a
|
|
156
|
+
* page refused from three different addresses apart from one refused once —
|
|
157
|
+
* and those two call for opposite conclusions about whether to try again.
|
|
158
|
+
*
|
|
159
|
+
* It is also the only way to see the rollout fail silently. The E2B image
|
|
160
|
+
* installs the CLI at build time, so until the template is rebuilt a Runtime
|
|
161
|
+
* runs an older binary that ignores the credentials Convex hands it. That
|
|
162
|
+
* capture returns an envelope with **no rungs at all** — indistinguishable,
|
|
163
|
+
* from the outside, from a page that simply was not worth escalating.
|
|
164
|
+
*
|
|
165
|
+
* Deliberately thin: tier names and status codes only, so nothing here can
|
|
166
|
+
* carry a credential or the raw browser text that once reached a user.
|
|
167
|
+
*/
|
|
168
|
+
rungs;
|
|
169
|
+
constructor(failure, rungs = []) {
|
|
170
|
+
super(failure.message);
|
|
171
|
+
this.name = "CaptureFailureError";
|
|
172
|
+
this.failure = failure;
|
|
173
|
+
this.rungs = rungs;
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
var LOCAL_ADDRESS_REFUSAL = "That address only opens from inside your own network, so there is nothing there for us to read. A reference page has to be live on the web.";
|
|
177
|
+
var NODE_LEVEL_UNREACHABLE = ["econnrefused", "enotfound", "getaddrinfo"];
|
|
178
|
+
var UNREACHABLE_MESSAGE = "We couldn't reach this page \u2014 the site didn't answer, or its security certificate isn't one we can read.";
|
|
179
|
+
var TOO_SLOW_MESSAGE = "This page took too long to load, so we stopped waiting for it.";
|
|
180
|
+
var CAPTURE_FAILED_MESSAGE = "We couldn't read this page.";
|
|
181
|
+
function classifyCaptureFailure(error) {
|
|
182
|
+
if (error instanceof CaptureFailureError) return error.failure;
|
|
183
|
+
if (error instanceof BlockedPageError) {
|
|
184
|
+
return { code: error.code, message: error.message };
|
|
185
|
+
}
|
|
186
|
+
const proxyFailure = describeProxyFailure(error);
|
|
187
|
+
if (proxyFailure) return proxyFailure;
|
|
188
|
+
const unreachable = describeUnreachableSite(error);
|
|
189
|
+
if (unreachable) return unreachable;
|
|
190
|
+
const message = (error instanceof Error ? error.message : String(error)).toLowerCase();
|
|
191
|
+
if (NODE_LEVEL_UNREACHABLE.some((marker) => message.includes(marker))) {
|
|
192
|
+
return { code: "SITE_UNREACHABLE", message: UNREACHABLE_MESSAGE };
|
|
193
|
+
}
|
|
194
|
+
if (message.includes("timeout") && message.includes("exceeded")) {
|
|
195
|
+
return { code: "SITE_TOO_SLOW", message: TOO_SLOW_MESSAGE };
|
|
196
|
+
}
|
|
197
|
+
return { code: "CAPTURE_FAILED", message: CAPTURE_FAILED_MESSAGE };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/engine/landing-library/run.ts
|
|
201
|
+
import { mkdir, writeFile as writeFile2 } from "fs/promises";
|
|
202
|
+
import path2 from "path";
|
|
203
|
+
|
|
204
|
+
// ../proxy/src/preflight.ts
|
|
205
|
+
import http from "http";
|
|
206
|
+
function classifyPreflightStatus(status) {
|
|
207
|
+
if (status === 200) return { usable: true };
|
|
208
|
+
if (status === 407) return { usable: false, problem: "auth" };
|
|
209
|
+
return { usable: false, problem: "unreachable" };
|
|
210
|
+
}
|
|
211
|
+
async function preflightProxyRoute(route, options = {}) {
|
|
212
|
+
if (route.kind !== "proxy") return { usable: true };
|
|
213
|
+
const timeoutMs = options.timeoutMs ?? 8e3;
|
|
214
|
+
const target = options.target ?? "example.com:443";
|
|
215
|
+
const endpoint = new URL(route.server);
|
|
216
|
+
const auth = Buffer.from(`${route.username}:${route.password}`).toString("base64");
|
|
217
|
+
return await new Promise((resolve) => {
|
|
218
|
+
const settle = (result) => {
|
|
219
|
+
request.destroy();
|
|
220
|
+
resolve(result);
|
|
221
|
+
};
|
|
222
|
+
const request = http.request({
|
|
223
|
+
host: endpoint.hostname,
|
|
224
|
+
port: Number(endpoint.port),
|
|
225
|
+
method: "CONNECT",
|
|
226
|
+
path: target,
|
|
227
|
+
headers: { "Proxy-Authorization": `Basic ${auth}`, Host: target },
|
|
228
|
+
timeout: timeoutMs
|
|
229
|
+
});
|
|
230
|
+
request.on("connect", (response, socket) => {
|
|
231
|
+
socket.destroy();
|
|
232
|
+
settle(classifyPreflightStatus(response.statusCode));
|
|
233
|
+
});
|
|
234
|
+
request.on("response", (response) => {
|
|
235
|
+
response.destroy();
|
|
236
|
+
settle(classifyPreflightStatus(response.statusCode));
|
|
237
|
+
});
|
|
238
|
+
request.on("timeout", () => settle({ usable: false, problem: "timeout" }));
|
|
239
|
+
request.on("error", () => settle({ usable: false, problem: "unreachable" }));
|
|
240
|
+
request.end();
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// src/engine/landing-library/browser.ts
|
|
245
|
+
import { createRequire } from "module";
|
|
246
|
+
var require_ = createRequire(import.meta.url);
|
|
247
|
+
var pwSpecifier = ["play", "wright"].join("");
|
|
248
|
+
var DESKTOP_VIEWPORT = { width: 1440, height: 900 };
|
|
249
|
+
var MOBILE_VIEWPORT = { width: 390, height: 844 };
|
|
250
|
+
var DEVICE_SCALE_FACTOR = 2;
|
|
251
|
+
async function launchBrowser(route = { kind: "direct" }) {
|
|
252
|
+
const playwright = require_(pwSpecifier);
|
|
253
|
+
return await playwright.chromium.launch({
|
|
254
|
+
headless: true,
|
|
255
|
+
args: ["--hide-scrollbars", "--disable-blink-features=AutomationControlled", "--mute-audio"],
|
|
256
|
+
...route.kind === "proxy" ? { proxy: { server: route.server, username: route.username, password: route.password } } : {}
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
async function newPage(browser, viewport, opts = { motion: false }) {
|
|
260
|
+
const context = await browser.newContext({
|
|
261
|
+
viewport,
|
|
262
|
+
deviceScaleFactor: DEVICE_SCALE_FACTOR,
|
|
263
|
+
// We read third-party marketing pages and send them nothing — no cookies we
|
|
264
|
+
// own, no credentials, no form posts — so the usual reason to refuse a bad
|
|
265
|
+
// certificate (an attacker between us and a session we care about) does not
|
|
266
|
+
// apply. Refusing one instead makes a whole class of real sites permanently
|
|
267
|
+
// uncapturable: `growthspree.com` and `arcus.so` both fail the handshake,
|
|
268
|
+
// and `inspiration scrape` is the escalation the whole repo points agents at
|
|
269
|
+
// when `WebFetch` fails, so it inheriting the same blind spot means there is
|
|
270
|
+
// no route to those pages at all. Every capture therefore records that the
|
|
271
|
+
// certificate was not validated — see `PrepareResult.security`.
|
|
272
|
+
ignoreHTTPSErrors: true,
|
|
273
|
+
// Still captures freeze motion so screenshots are reproducible; the motion
|
|
274
|
+
// pass re-opens a context with animation enabled.
|
|
275
|
+
reducedMotion: opts.motion ? "no-preference" : "reduce",
|
|
276
|
+
userAgent: viewport.width < 500 ? "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"
|
|
277
|
+
});
|
|
278
|
+
const page = await context.newPage();
|
|
279
|
+
return { context, page };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// src/engine/landing-library/usedCss.ts
|
|
283
|
+
async function collectUsedCss(page, selector) {
|
|
284
|
+
const collected = await page.evaluate(inPageCollectUsedCss, selector);
|
|
285
|
+
const extra = [];
|
|
286
|
+
for (const href of collected.unreadableHrefs) {
|
|
287
|
+
const text = await fetchStylesheet(page, href);
|
|
288
|
+
if (text) extra.push(`/* ${href} */
|
|
289
|
+
${text}`);
|
|
290
|
+
}
|
|
291
|
+
return { ...collected, css: [collected.css, ...extra].filter(Boolean).join("\n\n") };
|
|
292
|
+
}
|
|
293
|
+
async function fetchStylesheet(page, href) {
|
|
294
|
+
try {
|
|
295
|
+
const response = await page.request.get(href, { timeout: 1e4 });
|
|
296
|
+
if (!response.ok()) return null;
|
|
297
|
+
return await response.text();
|
|
298
|
+
} catch {
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
var inPageCollectUsedCss = (selector) => {
|
|
303
|
+
const root = document.querySelector(selector);
|
|
304
|
+
const empty = {
|
|
305
|
+
css: "",
|
|
306
|
+
variables: "",
|
|
307
|
+
inheritedSeed: "",
|
|
308
|
+
unreadableHrefs: [],
|
|
309
|
+
stats: { totalRules: 0, keptRules: 0, fontFaces: 0, keyframes: 0 }
|
|
310
|
+
};
|
|
311
|
+
if (!root) return empty;
|
|
312
|
+
const INHERITED = [
|
|
313
|
+
"color",
|
|
314
|
+
"font-family",
|
|
315
|
+
"font-size",
|
|
316
|
+
"font-weight",
|
|
317
|
+
"line-height",
|
|
318
|
+
"letter-spacing",
|
|
319
|
+
"text-align",
|
|
320
|
+
"background-color",
|
|
321
|
+
"-webkit-font-smoothing"
|
|
322
|
+
];
|
|
323
|
+
const unreadableHrefs = [];
|
|
324
|
+
const kept = [];
|
|
325
|
+
const fontFaces = [];
|
|
326
|
+
const keyframesByName = /* @__PURE__ */ new Map();
|
|
327
|
+
let totalRules = 0;
|
|
328
|
+
let keptStyleRules = 0;
|
|
329
|
+
const matchesInSection = (selectorText) => {
|
|
330
|
+
for (const part of selectorText.split(",")) {
|
|
331
|
+
const base = part.replace(/::[a-zA-Z-]+(\([^)]*\))?/g, "").replace(/:(hover|focus|focus-visible|focus-within|active|visited|target|checked|disabled)\b/g, "").trim();
|
|
332
|
+
if (!base) continue;
|
|
333
|
+
try {
|
|
334
|
+
if (root.matches(base) || root.querySelector(base)) return true;
|
|
335
|
+
} catch {
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return false;
|
|
340
|
+
};
|
|
341
|
+
const walk = (rules, sink) => {
|
|
342
|
+
for (const rule of Array.from(rules)) {
|
|
343
|
+
totalRules++;
|
|
344
|
+
if (rule instanceof CSSStyleRule) {
|
|
345
|
+
if (matchesInSection(rule.selectorText)) {
|
|
346
|
+
sink.push(rule.cssText);
|
|
347
|
+
keptStyleRules++;
|
|
348
|
+
}
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (rule instanceof CSSFontFaceRule) {
|
|
352
|
+
fontFaces.push(rule.cssText);
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (rule instanceof CSSKeyframesRule) {
|
|
356
|
+
keyframesByName.set(rule.name, rule.cssText);
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
const grouping = rule instanceof CSSMediaRule || rule instanceof CSSSupportsRule || typeof CSSLayerBlockRule !== "undefined" && rule instanceof CSSLayerBlockRule || typeof CSSContainerRule !== "undefined" && rule instanceof CSSContainerRule;
|
|
360
|
+
if (grouping) {
|
|
361
|
+
const inner = [];
|
|
362
|
+
walk(rule.cssRules, inner);
|
|
363
|
+
if (inner.length === 0) continue;
|
|
364
|
+
const condition = rule.conditionText ?? "";
|
|
365
|
+
const prelude = rule instanceof CSSMediaRule ? `@media ${condition}` : rule.cssText.split("{")[0]?.trim();
|
|
366
|
+
sink.push(`${prelude} {
|
|
367
|
+
${inner.join("\n")}
|
|
368
|
+
}`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
for (const sheet of Array.from(document.styleSheets)) {
|
|
373
|
+
const owner = sheet.ownerNode;
|
|
374
|
+
if (owner?.hasAttribute?.("data-baker-freeze")) continue;
|
|
375
|
+
try {
|
|
376
|
+
walk(sheet.cssRules, kept);
|
|
377
|
+
} catch {
|
|
378
|
+
if (sheet.href) unreadableHrefs.push(sheet.href);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
const keptText = kept.join("\n");
|
|
382
|
+
const usedKeyframes = [];
|
|
383
|
+
for (const [name, text] of keyframesByName) {
|
|
384
|
+
if (new RegExp(`(^|[\\s:,])${name}([\\s;,}]|$)`).test(keptText)) usedKeyframes.push(text);
|
|
385
|
+
}
|
|
386
|
+
const rootStyle = getComputedStyle(root);
|
|
387
|
+
const variableDeclarations = [];
|
|
388
|
+
for (const property of Array.from(rootStyle)) {
|
|
389
|
+
if (!property.startsWith("--")) continue;
|
|
390
|
+
const value = rootStyle.getPropertyValue(property).trim();
|
|
391
|
+
if (value) variableDeclarations.push(` ${property}: ${value};`);
|
|
392
|
+
}
|
|
393
|
+
const seed = INHERITED.map((property) => ` ${property}: ${rootStyle.getPropertyValue(property)};`).join("\n");
|
|
394
|
+
return {
|
|
395
|
+
css: [...fontFaces, ...usedKeyframes, ...kept].join("\n"),
|
|
396
|
+
variables: variableDeclarations.length ? `:root {
|
|
397
|
+
${variableDeclarations.join("\n")}
|
|
398
|
+
}` : "",
|
|
399
|
+
inheritedSeed: seed,
|
|
400
|
+
unreadableHrefs,
|
|
401
|
+
stats: {
|
|
402
|
+
totalRules,
|
|
403
|
+
keptRules: keptStyleRules,
|
|
404
|
+
fontFaces: fontFaces.length,
|
|
405
|
+
keyframes: usedKeyframes.length
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
// src/engine/landing-library/bundle.ts
|
|
411
|
+
async function buildSectionBundle(page, selector, pageUrl) {
|
|
412
|
+
const used = await collectUsedCss(page, selector);
|
|
413
|
+
const extracted = await page.evaluate(inPageExtractMarkup, {
|
|
414
|
+
selector,
|
|
415
|
+
pageUrl,
|
|
416
|
+
rootAttribute: SECTION_ROOT_ATTRIBUTE
|
|
417
|
+
});
|
|
418
|
+
const css = [
|
|
419
|
+
"*, *::before, *::after { box-sizing: border-box; }",
|
|
420
|
+
"html, body { margin: 0; padding: 0; }",
|
|
421
|
+
used.variables,
|
|
422
|
+
`body {
|
|
423
|
+
${used.inheritedSeed}
|
|
424
|
+
}`,
|
|
425
|
+
used.css
|
|
426
|
+
].filter(Boolean).join("\n\n");
|
|
427
|
+
const html = `<!doctype html>
|
|
428
|
+
<html ${extracted.rootAttributes}>
|
|
429
|
+
<head>
|
|
430
|
+
<meta charset="utf-8">
|
|
431
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
432
|
+
<title>Section from ${escapeHtml(extracted.host)}</title>
|
|
433
|
+
<style>
|
|
434
|
+
${css}
|
|
435
|
+
</style>
|
|
436
|
+
</head>
|
|
437
|
+
<body ${extracted.bodyAttributes}>
|
|
438
|
+
${wrapInLayoutContext(extracted.html, extracted.layoutContext)}
|
|
439
|
+
</body>
|
|
440
|
+
</html>
|
|
441
|
+
`;
|
|
442
|
+
return { html, css, assetUrls: extracted.assetUrls, stats: used.stats };
|
|
443
|
+
}
|
|
444
|
+
function escapeHtml(value) {
|
|
445
|
+
return value.replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[c] ?? c);
|
|
446
|
+
}
|
|
447
|
+
var SECTION_ROOT_ATTRIBUTE = "data-baker-section-root";
|
|
448
|
+
function wrapInLayoutContext(html, context) {
|
|
449
|
+
let wrapped = context.width > 0 && context.width < context.viewportWidth ? `<div style="width:${context.width}px;margin:0 auto;">
|
|
450
|
+
${html}
|
|
451
|
+
</div>` : html;
|
|
452
|
+
for (const ancestor of [...context.ancestors].reverse()) {
|
|
453
|
+
const attributes = ancestor.attributes ? ` ${ancestor.attributes}` : "";
|
|
454
|
+
const container = ancestor.containerType && ancestor.containerType !== "normal" ? `container-type:${ancestor.containerType};${ancestor.containerName && ancestor.containerName !== "none" ? `container-name:${ancestor.containerName};` : ""}` : "";
|
|
455
|
+
wrapped = `<${ancestor.tag}${attributes} style="${NEUTRALIZED_ANCESTOR_STYLE}${container}">
|
|
456
|
+
${wrapped}
|
|
457
|
+
</${ancestor.tag}>`;
|
|
458
|
+
}
|
|
459
|
+
return wrapped;
|
|
460
|
+
}
|
|
461
|
+
var NEUTRALIZED_ANCESTOR_STYLE = [
|
|
462
|
+
"display:block !important",
|
|
463
|
+
"position:static !important",
|
|
464
|
+
"margin:0 !important",
|
|
465
|
+
"padding:0 !important",
|
|
466
|
+
"border:0 !important",
|
|
467
|
+
"width:auto !important",
|
|
468
|
+
"min-width:0 !important",
|
|
469
|
+
"max-width:none !important",
|
|
470
|
+
"height:auto !important",
|
|
471
|
+
"min-height:0 !important",
|
|
472
|
+
"max-height:none !important",
|
|
473
|
+
"transform:none !important",
|
|
474
|
+
"overflow:visible !important",
|
|
475
|
+
""
|
|
476
|
+
].join(";");
|
|
477
|
+
var inPageExtractMarkup = ({
|
|
478
|
+
selector,
|
|
479
|
+
pageUrl,
|
|
480
|
+
rootAttribute
|
|
481
|
+
}) => {
|
|
482
|
+
const root = document.querySelector(selector);
|
|
483
|
+
const emptyContext = { ancestors: [], width: 0, viewportWidth: 0 };
|
|
484
|
+
const serializeAttributes = (element) => {
|
|
485
|
+
if (!element) return "";
|
|
486
|
+
return Array.from(element.attributes).filter((attribute) => attribute.name !== "style").map((attribute) => `${attribute.name}="${attribute.value.replace(/"/g, """)}"`).join(" ");
|
|
487
|
+
};
|
|
488
|
+
const rootAttributes = serializeAttributes(document.documentElement) || 'lang="en"';
|
|
489
|
+
const bodyAttributes = serializeAttributes(document.body);
|
|
490
|
+
if (!root) {
|
|
491
|
+
return {
|
|
492
|
+
html: "",
|
|
493
|
+
assetUrls: [],
|
|
494
|
+
host: "",
|
|
495
|
+
layoutContext: emptyContext,
|
|
496
|
+
rootAttributes,
|
|
497
|
+
bodyAttributes
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
const ancestors = [];
|
|
501
|
+
for (let ancestor = root.parentElement; ancestor && ancestor !== document.body; ) {
|
|
502
|
+
const style = getComputedStyle(ancestor);
|
|
503
|
+
ancestors.unshift({
|
|
504
|
+
tag: /^[a-zA-Z][a-zA-Z0-9-]*$/.test(ancestor.tagName) ? ancestor.tagName.toLowerCase() : "div",
|
|
505
|
+
attributes: Array.from(ancestor.attributes).filter((a) => a.name === "class" || a.name === "id" || a.name.startsWith("data-")).map((a) => `${a.name}="${a.value.replace(/"/g, """)}"`).join(" "),
|
|
506
|
+
containerType: style.containerType,
|
|
507
|
+
containerName: style.containerName
|
|
508
|
+
});
|
|
509
|
+
ancestor = ancestor.parentElement;
|
|
510
|
+
}
|
|
511
|
+
const layoutContext = {
|
|
512
|
+
ancestors,
|
|
513
|
+
width: Math.round(root.getBoundingClientRect().width),
|
|
514
|
+
viewportWidth: window.innerWidth
|
|
515
|
+
};
|
|
516
|
+
const absolute = (value) => {
|
|
517
|
+
try {
|
|
518
|
+
return new URL(value, pageUrl).href;
|
|
519
|
+
} catch {
|
|
520
|
+
return value;
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
const clone = root.cloneNode(true);
|
|
524
|
+
clone.setAttribute(rootAttribute, "");
|
|
525
|
+
const assetUrls = /* @__PURE__ */ new Set();
|
|
526
|
+
for (const element of [clone, ...Array.from(clone.querySelectorAll("*"))]) {
|
|
527
|
+
for (const attribute of ["src", "href", "poster"]) {
|
|
528
|
+
const value = element.getAttribute(attribute);
|
|
529
|
+
if (!value || value.startsWith("data:") || value.startsWith("#")) continue;
|
|
530
|
+
const url = absolute(value);
|
|
531
|
+
element.setAttribute(attribute, url);
|
|
532
|
+
if (attribute !== "href" || element.tagName === "LINK") assetUrls.add(url);
|
|
533
|
+
}
|
|
534
|
+
const srcset = element.getAttribute("srcset");
|
|
535
|
+
if (srcset) {
|
|
536
|
+
element.setAttribute(
|
|
537
|
+
"srcset",
|
|
538
|
+
srcset.split(",").map((candidate) => {
|
|
539
|
+
const [url, descriptor] = candidate.trim().split(/\s+/, 2);
|
|
540
|
+
if (!url) return candidate;
|
|
541
|
+
const resolved = absolute(url);
|
|
542
|
+
assetUrls.add(resolved);
|
|
543
|
+
return descriptor ? `${resolved} ${descriptor}` : resolved;
|
|
544
|
+
}).join(", ")
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
const style = element.getAttribute("style");
|
|
548
|
+
if (style?.includes("url(")) {
|
|
549
|
+
element.setAttribute(
|
|
550
|
+
"style",
|
|
551
|
+
style.replace(/url\((['"]?)([^'")]+)\1\)/g, (_match, quote, url) => {
|
|
552
|
+
if (url.startsWith("data:")) return `url(${quote}${url}${quote})`;
|
|
553
|
+
const resolved = absolute(url);
|
|
554
|
+
assetUrls.add(resolved);
|
|
555
|
+
return `url(${quote}${resolved}${quote})`;
|
|
556
|
+
})
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
return {
|
|
561
|
+
html: clone.outerHTML,
|
|
562
|
+
assetUrls: Array.from(assetUrls),
|
|
563
|
+
host: location.host,
|
|
564
|
+
layoutContext,
|
|
565
|
+
rootAttributes,
|
|
566
|
+
bodyAttributes
|
|
567
|
+
};
|
|
568
|
+
};
|
|
569
|
+
|
|
570
|
+
// src/engine/landing-library/capture.ts
|
|
571
|
+
async function captureSection(page, section) {
|
|
572
|
+
const locator = page.locator(section.selector).first();
|
|
573
|
+
if (await locator.count().catch(() => 0)) {
|
|
574
|
+
const shot = await locator.screenshot({ type: "png", timeout: 15e3 }).catch(() => null);
|
|
575
|
+
if (shot) return shot;
|
|
576
|
+
}
|
|
577
|
+
const doc = await page.evaluate(() => ({
|
|
578
|
+
width: Math.max(document.documentElement.scrollWidth, document.body?.scrollWidth ?? 0),
|
|
579
|
+
height: Math.max(document.documentElement.scrollHeight, document.body?.scrollHeight ?? 0)
|
|
580
|
+
}));
|
|
581
|
+
const width = Math.min(section.rect.width, doc.width - section.rect.left);
|
|
582
|
+
const height = Math.min(section.rect.height, doc.height - section.rect.top);
|
|
583
|
+
if (width <= 0 || height <= 0) return null;
|
|
584
|
+
return await page.screenshot({
|
|
585
|
+
type: "png",
|
|
586
|
+
clip: { x: section.rect.left, y: section.rect.top, width, height },
|
|
587
|
+
timeout: 15e3
|
|
588
|
+
}).catch(() => null);
|
|
589
|
+
}
|
|
590
|
+
async function captureSectionOnMobile(page, section) {
|
|
591
|
+
const locator = page.locator(section.selector).first();
|
|
592
|
+
if (!await locator.count().catch(() => 0)) return null;
|
|
593
|
+
if (!await locator.isVisible().catch(() => false)) return null;
|
|
594
|
+
return await locator.screenshot({ type: "png", timeout: 15e3 }).catch(() => null);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// src/engine/landing-library/escalation.ts
|
|
598
|
+
var CAPTURE_RESERVE_MS = 18e4;
|
|
599
|
+
function attemptSignal(outcome) {
|
|
600
|
+
const code = outcome.failure.code;
|
|
601
|
+
return {
|
|
602
|
+
challenge: code === "BOT_CHALLENGE",
|
|
603
|
+
status: outcome.status,
|
|
604
|
+
netError: outcome.netError,
|
|
605
|
+
timedOut: code === "SITE_TOO_SLOW"
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
function ambiguousProxyTimeout(outcome) {
|
|
609
|
+
return outcome.route.kind === "proxy" && outcome.failure.code === "SITE_TOO_SLOW" && outcome.status === null && outcome.netError === null;
|
|
610
|
+
}
|
|
611
|
+
function asProxyFailure(outcome, problem) {
|
|
612
|
+
return {
|
|
613
|
+
...outcome,
|
|
614
|
+
failure: { code: "PROXY_UNAVAILABLE", message: PROXY_UNAVAILABLE_MESSAGE },
|
|
615
|
+
// Borrowing Chromium's own vocabulary so `isProxyFailure` recognises this
|
|
616
|
+
// without having to learn a second way of being told the same thing.
|
|
617
|
+
netError: problem === "auth" ? "ERR_PROXY_AUTH_REQUESTED" : "ERR_PROXY_CONNECTION_FAILED"
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
function nextRoute(args) {
|
|
621
|
+
const last = args.attempts[args.attempts.length - 1];
|
|
622
|
+
if (!last) return { next: null, reason: "ladder_exhausted" };
|
|
623
|
+
const brokenProxy = isProxyFailure(attemptSignal(last));
|
|
624
|
+
if (!brokenProxy && !shouldEscalate(attemptSignal(last))) {
|
|
625
|
+
return { next: null, reason: "site_fault_is_final" };
|
|
626
|
+
}
|
|
627
|
+
const next = nextPlannedRoute(
|
|
628
|
+
args.routes,
|
|
629
|
+
args.attempts.map((attempt) => ({
|
|
630
|
+
tier: attempt.route.kind === "proxy" ? attempt.route.tier : "direct",
|
|
631
|
+
proxyFailure: isProxyFailure(attemptSignal(attempt))
|
|
632
|
+
}))
|
|
633
|
+
);
|
|
634
|
+
if (!next) return { next: null, reason: args.routes.length === 1 ? "not_configured" : "ladder_exhausted" };
|
|
635
|
+
if (args.remainingMs < args.reserveMs + args.navTimeoutMs) {
|
|
636
|
+
return { next: null, reason: "out_of_budget" };
|
|
637
|
+
}
|
|
638
|
+
return { next, reason: "escalate" };
|
|
639
|
+
}
|
|
640
|
+
function reportableFailure(attempts) {
|
|
641
|
+
const siteVerdicts = attempts.filter((attempt) => !isProxyFailure(attemptSignal(attempt)));
|
|
642
|
+
const chosen = siteVerdicts.find((attempt) => attempt.status !== null) ?? siteVerdicts[siteVerdicts.length - 1] ?? attempts[attempts.length - 1];
|
|
643
|
+
if (!chosen) throw new Error("reportableFailure called with no attempts");
|
|
644
|
+
return chosen.failure;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// src/engine/landing-library/fidelity.ts
|
|
648
|
+
import sharp from "sharp";
|
|
649
|
+
var COMPARISON_SIZE = 32;
|
|
650
|
+
function pixelSimilarity(a, b) {
|
|
651
|
+
const length = Math.min(a.length, b.length);
|
|
652
|
+
if (length === 0) return 0;
|
|
653
|
+
let total = 0;
|
|
654
|
+
for (let i = 0; i < length; i++) {
|
|
655
|
+
total += Math.abs((a[i] ?? 0) - (b[i] ?? 0));
|
|
656
|
+
}
|
|
657
|
+
return 1 - total / (length * 255);
|
|
658
|
+
}
|
|
659
|
+
async function scoreFidelity(live, rendered) {
|
|
660
|
+
const [liveMeta, renderedMeta] = await Promise.all([sharp(live).metadata(), sharp(rendered).metadata()]);
|
|
661
|
+
const liveSize = { width: liveMeta.width ?? 0, height: liveMeta.height ?? 0 };
|
|
662
|
+
const renderedSize = { width: renderedMeta.width ?? 0, height: renderedMeta.height ?? 0 };
|
|
663
|
+
const [livePixels, renderedPixels] = await Promise.all([toGreyGrid(live), toGreyGrid(rendered)]);
|
|
664
|
+
const score = pixelSimilarity(livePixels, renderedPixels);
|
|
665
|
+
const heightRatio = liveSize.height > 0 && renderedSize.height > 0 ? Math.min(liveSize.height, renderedSize.height) / Math.max(liveSize.height, renderedSize.height) : 0;
|
|
666
|
+
return {
|
|
667
|
+
score,
|
|
668
|
+
liveSize,
|
|
669
|
+
renderedSize,
|
|
670
|
+
...heightRatio < 0.8 ? { note: `height differs by ${Math.round((1 - heightRatio) * 100)}% \u2014 the bundle reflowed` } : {}
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
async function toGreyGrid(image) {
|
|
674
|
+
const raw = await sharp(image).greyscale().resize(COMPARISON_SIZE, COMPARISON_SIZE, { fit: "fill" }).raw().toBuffer();
|
|
675
|
+
return new Uint8Array(raw);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// src/engine/landing-library/motion.ts
|
|
679
|
+
var EMPTY_MOTION = {
|
|
680
|
+
hasMotion: false,
|
|
681
|
+
// `none` rather than "no motion": it is the `MOTION_KINDS` member for this,
|
|
682
|
+
// so a section with no movement is findable by the same facet as everything
|
|
683
|
+
// else instead of being a special case only prose describes.
|
|
684
|
+
summary: "none",
|
|
685
|
+
entrance: [],
|
|
686
|
+
hover: [],
|
|
687
|
+
scroll: [],
|
|
688
|
+
loop: [],
|
|
689
|
+
libraries: [],
|
|
690
|
+
respectsReducedMotion: false
|
|
691
|
+
};
|
|
692
|
+
function isWorthFilming(motion) {
|
|
693
|
+
return motion.entrance.length + motion.scroll.length + motion.loop.length > 0;
|
|
694
|
+
}
|
|
695
|
+
async function collectMotion(page, selector) {
|
|
696
|
+
const raw = await page.evaluate(inPageCollectMotion, selector).catch(() => null);
|
|
697
|
+
if (!raw) return EMPTY_MOTION;
|
|
698
|
+
return { ...raw, summary: summarizeMotion(raw) };
|
|
699
|
+
}
|
|
700
|
+
var HOVER_TRANSFORMS = /* @__PURE__ */ new Set(["lift", "grow", "tilt", "shift", "spin", "shadow", "animate"]);
|
|
701
|
+
var KEYFRAME_PATTERNS = [
|
|
702
|
+
[/marquee|ticker|scroll(ing)?-?(x|left|right)/, "marquee"],
|
|
703
|
+
[/parallax/, "parallax"],
|
|
704
|
+
[/sticky|pin(ned)?/, "sticky-pin"],
|
|
705
|
+
[/count(er|up)/, "counter"],
|
|
706
|
+
[/zoom|scale|pulse|grow/, "zoom"],
|
|
707
|
+
[/fade|opacity|appear/, "fade"],
|
|
708
|
+
[/slide|translate|in-?(left|right|up|down)/, "slide-in"]
|
|
709
|
+
];
|
|
710
|
+
function toMotionKinds(kind, channel) {
|
|
711
|
+
if (channel === "hover") return [HOVER_TRANSFORMS.has(kind) ? "hover-lift" : "fade"];
|
|
712
|
+
const name = kind.toLowerCase();
|
|
713
|
+
const matched = KEYFRAME_PATTERNS.filter(([pattern]) => pattern.test(name)).map(([, motionKind]) => motionKind);
|
|
714
|
+
if (matched.length > 0) return matched;
|
|
715
|
+
return [channel === "loop" ? "marquee" : "scroll-reveal"];
|
|
716
|
+
}
|
|
717
|
+
function motionKindsOf(motion) {
|
|
718
|
+
const kinds = /* @__PURE__ */ new Set();
|
|
719
|
+
const collect = (effects, channel) => {
|
|
720
|
+
for (const effect of effects) {
|
|
721
|
+
for (const kind of toMotionKinds(effect.kind, channel)) kinds.add(kind);
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
collect(motion.entrance, "entrance");
|
|
725
|
+
collect(motion.hover, "hover");
|
|
726
|
+
collect(motion.scroll, "scroll");
|
|
727
|
+
collect(motion.loop, "loop");
|
|
728
|
+
const delays = new Set(motion.entrance.map((effect) => effect.delayMs ?? 0).filter((ms) => ms > 0));
|
|
729
|
+
if (delays.size > 1) kinds.add("stagger");
|
|
730
|
+
return [...kinds];
|
|
731
|
+
}
|
|
732
|
+
function summarizeMotion(motion) {
|
|
733
|
+
const kinds = motionKindsOf(motion);
|
|
734
|
+
if (kinds.length === 0 && motion.libraries.length === 0) return "none";
|
|
735
|
+
const parts = [...kinds];
|
|
736
|
+
if (motion.libraries.length > 0) parts.push(`via ${motion.libraries.join("/")}`);
|
|
737
|
+
return parts.join(", ") + (motion.respectsReducedMotion ? "" : " (ignores reduced-motion)");
|
|
738
|
+
}
|
|
739
|
+
var inPageCollectMotion = (selector) => {
|
|
740
|
+
const root = document.querySelector(selector);
|
|
741
|
+
const empty = {
|
|
742
|
+
hasMotion: false,
|
|
743
|
+
entrance: [],
|
|
744
|
+
hover: [],
|
|
745
|
+
scroll: [],
|
|
746
|
+
loop: [],
|
|
747
|
+
libraries: [],
|
|
748
|
+
respectsReducedMotion: false
|
|
749
|
+
};
|
|
750
|
+
if (!root) return empty;
|
|
751
|
+
const entrance = [];
|
|
752
|
+
const hover = [];
|
|
753
|
+
const scroll = [];
|
|
754
|
+
const loop = [];
|
|
755
|
+
const keyframesByName = /* @__PURE__ */ new Map();
|
|
756
|
+
let respectsReducedMotion = false;
|
|
757
|
+
const inSection = (selectorText) => {
|
|
758
|
+
for (const part of selectorText.split(",")) {
|
|
759
|
+
const base = part.replace(/::[a-zA-Z-]+(\([^)]*\))?/g, "").replace(/:(hover|focus|focus-visible|focus-within|active|visited|target|checked|disabled)\b/g, "").trim();
|
|
760
|
+
if (!base) continue;
|
|
761
|
+
try {
|
|
762
|
+
if (root.matches(base) || root.querySelector(base)) return true;
|
|
763
|
+
} catch {
|
|
764
|
+
return true;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
return false;
|
|
768
|
+
};
|
|
769
|
+
const toMs = (value) => {
|
|
770
|
+
const first = value.split(",")[0]?.trim() ?? "";
|
|
771
|
+
if (first.endsWith("ms")) return Number.parseFloat(first);
|
|
772
|
+
if (first.endsWith("s")) return Number.parseFloat(first) * 1e3;
|
|
773
|
+
return void 0;
|
|
774
|
+
};
|
|
775
|
+
const classifyKeyframes = (body) => {
|
|
776
|
+
const text = body.toLowerCase();
|
|
777
|
+
const fades = /opacity\s*:\s*0(\.0+)?\s*[;}]/.test(text);
|
|
778
|
+
if (/translatey\(\s*-?\d/.test(text)) {
|
|
779
|
+
const upward = /translatey\(\s*(\d|\.)/.test(text);
|
|
780
|
+
return fades ? upward ? "fade-up" : "fade-down" : upward ? "slide-up" : "slide-down";
|
|
781
|
+
}
|
|
782
|
+
if (/translatex\(\s*-?\d/.test(text)) return fades ? "fade-in-x" : "slide-in-x";
|
|
783
|
+
if (/scale\(/.test(text)) return fades ? "fade-zoom" : "zoom";
|
|
784
|
+
if (/rotate\(/.test(text)) return "spin";
|
|
785
|
+
if (fades) return "fade";
|
|
786
|
+
return "animate";
|
|
787
|
+
};
|
|
788
|
+
const classifyHover = (style) => {
|
|
789
|
+
const transform = style.transform ?? "";
|
|
790
|
+
if (/translatey\(\s*-/i.test(transform)) return "lift";
|
|
791
|
+
if (/scale\(\s*(1\.\d|[2-9])/i.test(transform)) return "grow";
|
|
792
|
+
if (/rotate\(/i.test(transform)) return "tilt";
|
|
793
|
+
if (transform && transform !== "none") return "shift";
|
|
794
|
+
if (style.boxShadow) return "shadow";
|
|
795
|
+
if (style.opacity) return "dim";
|
|
796
|
+
if (style.backgroundColor || style.color) return "recolor";
|
|
797
|
+
return null;
|
|
798
|
+
};
|
|
799
|
+
const readStyleRule = (rule, insideScrollTimeline) => {
|
|
800
|
+
const style = rule.style;
|
|
801
|
+
const isHover = /:hover\b/.test(rule.selectorText);
|
|
802
|
+
if (isHover) {
|
|
803
|
+
const kind = classifyHover(style);
|
|
804
|
+
if (!kind || !inSection(rule.selectorText)) return;
|
|
805
|
+
hover.push({
|
|
806
|
+
kind,
|
|
807
|
+
selector: rule.selectorText.slice(0, 120),
|
|
808
|
+
durationMs: toMs(style.transitionDuration ?? ""),
|
|
809
|
+
easing: style.transitionTimingFunction || void 0
|
|
810
|
+
});
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
const animationName = style.animationName;
|
|
814
|
+
if (!animationName || animationName === "none") return;
|
|
815
|
+
if (!inSection(rule.selectorText)) return;
|
|
816
|
+
const effect = {
|
|
817
|
+
kind: animationName,
|
|
818
|
+
selector: rule.selectorText.slice(0, 120),
|
|
819
|
+
durationMs: toMs(style.animationDuration ?? ""),
|
|
820
|
+
delayMs: toMs(style.animationDelay ?? ""),
|
|
821
|
+
easing: style.animationTimingFunction || void 0
|
|
822
|
+
};
|
|
823
|
+
const infinite = (style.animationIterationCount ?? "").includes("infinite");
|
|
824
|
+
const scrollDriven = insideScrollTimeline || Boolean(style.getPropertyValue("animation-timeline"));
|
|
825
|
+
if (scrollDriven) scroll.push(effect);
|
|
826
|
+
else if (infinite) loop.push(effect);
|
|
827
|
+
else entrance.push(effect);
|
|
828
|
+
};
|
|
829
|
+
const walk = (rules, insideScrollTimeline) => {
|
|
830
|
+
for (const rule of Array.from(rules)) {
|
|
831
|
+
if (rule instanceof CSSKeyframesRule) {
|
|
832
|
+
keyframesByName.set(rule.name, rule.cssText);
|
|
833
|
+
continue;
|
|
834
|
+
}
|
|
835
|
+
if (rule instanceof CSSStyleRule) {
|
|
836
|
+
try {
|
|
837
|
+
readStyleRule(rule, insideScrollTimeline);
|
|
838
|
+
} catch {
|
|
839
|
+
}
|
|
840
|
+
continue;
|
|
841
|
+
}
|
|
842
|
+
if (rule instanceof CSSMediaRule) {
|
|
843
|
+
if (rule.conditionText.includes("prefers-reduced-motion")) {
|
|
844
|
+
respectsReducedMotion = true;
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
walk(rule.cssRules, insideScrollTimeline);
|
|
848
|
+
continue;
|
|
849
|
+
}
|
|
850
|
+
const grouping = rule;
|
|
851
|
+
if (grouping.cssRules) walk(grouping.cssRules, insideScrollTimeline);
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
for (const sheet of Array.from(document.styleSheets)) {
|
|
855
|
+
if (sheet.ownerNode?.hasAttribute?.("data-baker-freeze")) continue;
|
|
856
|
+
try {
|
|
857
|
+
walk(sheet.cssRules, false);
|
|
858
|
+
} catch {
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
for (const effect of [...entrance, ...loop, ...scroll]) {
|
|
862
|
+
const body = keyframesByName.get(effect.kind);
|
|
863
|
+
if (!body) continue;
|
|
864
|
+
const classified = classifyKeyframes(body);
|
|
865
|
+
effect.kind = loop.includes(effect) && classified.startsWith("slide") ? "marquee" : classified;
|
|
866
|
+
}
|
|
867
|
+
const libraries = [];
|
|
868
|
+
const scoped = window ?? {};
|
|
869
|
+
if (scoped.gsap || document.querySelector("[data-gsap]")) libraries.push("gsap");
|
|
870
|
+
if (document.querySelector("[data-framer-name], [data-projection-id]")) libraries.push("framer-motion");
|
|
871
|
+
if (document.querySelector("[data-aos]")) libraries.push("aos");
|
|
872
|
+
if (scoped.Lenis || document.querySelector("[data-lenis]")) libraries.push("lenis");
|
|
873
|
+
if (document.querySelector("[data-scroll], [data-scroll-container]")) libraries.push("locomotive");
|
|
874
|
+
return {
|
|
875
|
+
hasMotion: entrance.length + hover.length + scroll.length + loop.length + libraries.length > 0,
|
|
876
|
+
entrance: entrance.slice(0, 12),
|
|
877
|
+
hover: hover.slice(0, 12),
|
|
878
|
+
scroll: scroll.slice(0, 12),
|
|
879
|
+
loop: loop.slice(0, 12),
|
|
880
|
+
libraries,
|
|
881
|
+
respectsReducedMotion
|
|
882
|
+
};
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
// src/engine/landing-library/motionTake.ts
|
|
886
|
+
import sharp2 from "sharp";
|
|
887
|
+
|
|
888
|
+
// src/engine/landing-library/certificate.ts
|
|
889
|
+
function formatDate(unixSeconds) {
|
|
890
|
+
return new Date(unixSeconds * 1e3).toLocaleDateString("en-GB", {
|
|
891
|
+
day: "numeric",
|
|
892
|
+
month: "long",
|
|
893
|
+
year: "numeric"
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
function describeCapturedCertificate(details, now = Date.now()) {
|
|
897
|
+
if (!details) {
|
|
898
|
+
return {
|
|
899
|
+
certificateValidated: false,
|
|
900
|
+
certificate: null,
|
|
901
|
+
certificateNotes: ["This page was served over an unencrypted connection, so nothing about it could be verified."]
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
const notes = [];
|
|
905
|
+
if (details.validTo !== void 0 && details.validTo * 1e3 < now) {
|
|
906
|
+
notes.push(`The site's security certificate expired on ${formatDate(details.validTo)}.`);
|
|
907
|
+
}
|
|
908
|
+
if (details.validFrom !== void 0 && details.validFrom * 1e3 > now) {
|
|
909
|
+
notes.push(`The site's security certificate is not valid until ${formatDate(details.validFrom)}.`);
|
|
910
|
+
}
|
|
911
|
+
return { certificateValidated: false, certificate: details, certificateNotes: notes };
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
// src/engine/landing-library/prepare.ts
|
|
915
|
+
function isNavigationTeardown(error) {
|
|
916
|
+
const message = error instanceof Error ? error.message : typeof error === "string" ? error : "";
|
|
917
|
+
return message.includes("Execution context was destroyed") || message.includes("Cannot find context with specified id") || message.includes("frame was detached") || message.includes("has been closed");
|
|
918
|
+
}
|
|
919
|
+
var CONSENT_SELECTORS = [
|
|
920
|
+
"#onetrust-accept-btn-handler",
|
|
921
|
+
"#CybotCookiebotDialogBodyLevelButtonLevelOptinAllowAll",
|
|
922
|
+
"button#didomi-notice-agree-button",
|
|
923
|
+
"[aria-label='Accept all']",
|
|
924
|
+
"[data-testid='uc-accept-all-button']",
|
|
925
|
+
".cc-allow",
|
|
926
|
+
".cookie-accept"
|
|
927
|
+
];
|
|
928
|
+
var CONSENT_TEXTS = ["Accept all", "Accept All", "Allow all", "I agree", "Got it", "Aceptar todo"];
|
|
929
|
+
var CONSENT_HOSTS = [
|
|
930
|
+
"transcend-cdn.com",
|
|
931
|
+
"cookielaw.org",
|
|
932
|
+
"onetrust.com",
|
|
933
|
+
"cookiebot.com",
|
|
934
|
+
"osano.com",
|
|
935
|
+
"trustarc.com",
|
|
936
|
+
"truste.com",
|
|
937
|
+
"usercentrics.eu",
|
|
938
|
+
"didomi.io",
|
|
939
|
+
"privacy-center.org",
|
|
940
|
+
"iubenda.com",
|
|
941
|
+
"termly.io",
|
|
942
|
+
"cookieyes.com",
|
|
943
|
+
"sp-prod.net",
|
|
944
|
+
"quantcast.com",
|
|
945
|
+
"consensu.org",
|
|
946
|
+
"ketch.com",
|
|
947
|
+
"secureprivacy.ai",
|
|
948
|
+
"civicuk.com"
|
|
949
|
+
];
|
|
950
|
+
async function blockConsentManagers(page) {
|
|
951
|
+
await page.route("**/*", (route) => {
|
|
952
|
+
let host = "";
|
|
953
|
+
try {
|
|
954
|
+
host = new URL(route.request().url()).host;
|
|
955
|
+
} catch {
|
|
956
|
+
return route.continue();
|
|
957
|
+
}
|
|
958
|
+
const isConsentVendor = CONSENT_HOSTS.some((vendor) => host === vendor || host.endsWith(`.${vendor}`));
|
|
959
|
+
return isConsentVendor ? route.abort() : route.continue();
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
var ignore = () => void 0;
|
|
963
|
+
async function preparePage(page, url, timeoutMs) {
|
|
964
|
+
const documentStatus = trackMainDocumentStatus(page);
|
|
965
|
+
try {
|
|
966
|
+
const response = await page.goto(url, { waitUntil: "domcontentloaded", timeout: timeoutMs });
|
|
967
|
+
await settleNavigation(page);
|
|
968
|
+
await page.waitForLoadState("networkidle", { timeout: 8e3 }).catch(ignore);
|
|
969
|
+
await dismissConsent(page, 4e3);
|
|
970
|
+
await scrollThroughPage(page);
|
|
971
|
+
await dismissConsent(page, 1e3);
|
|
972
|
+
await acrossNavigation(
|
|
973
|
+
page,
|
|
974
|
+
() => page.evaluate(async () => {
|
|
975
|
+
await document.fonts.ready;
|
|
976
|
+
})
|
|
977
|
+
);
|
|
978
|
+
await freezeMotion(page);
|
|
979
|
+
await unpinOverlays(page);
|
|
980
|
+
const measured = await acrossNavigation(
|
|
981
|
+
page,
|
|
982
|
+
() => page.evaluate(() => ({
|
|
983
|
+
finalUrl: location.href,
|
|
984
|
+
title: document.title,
|
|
985
|
+
documentHeight: Math.max(document.documentElement.scrollHeight, document.body?.scrollHeight ?? 0),
|
|
986
|
+
bodyText: (document.body?.innerText ?? "").slice(0, 2e3)
|
|
987
|
+
}))
|
|
988
|
+
);
|
|
989
|
+
const served = documentStatus.lastResponse() ?? response;
|
|
990
|
+
const certificate = await served?.securityDetails().catch(() => null);
|
|
991
|
+
return {
|
|
992
|
+
...measured,
|
|
993
|
+
status: documentStatus.last() ?? response?.status() ?? null,
|
|
994
|
+
security: describeCapturedCertificate(certificate)
|
|
995
|
+
};
|
|
996
|
+
} finally {
|
|
997
|
+
documentStatus.stop();
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
function trackMainDocumentStatus(page) {
|
|
1001
|
+
let status = null;
|
|
1002
|
+
let last = null;
|
|
1003
|
+
const onResponse = (response) => {
|
|
1004
|
+
const request = response.request();
|
|
1005
|
+
if (request.resourceType() !== "document" || request.frame() !== page.mainFrame()) return;
|
|
1006
|
+
const code = response.status();
|
|
1007
|
+
if (code >= 300 && code < 400) return;
|
|
1008
|
+
status = code;
|
|
1009
|
+
last = response;
|
|
1010
|
+
};
|
|
1011
|
+
page.on("response", onResponse);
|
|
1012
|
+
return { last: () => status, lastResponse: () => last, stop: () => page.off("response", onResponse) };
|
|
1013
|
+
}
|
|
1014
|
+
var NAVIGATION_QUIET_MS = 1500;
|
|
1015
|
+
var NAVIGATION_SETTLE_BUDGET_MS = 2e4;
|
|
1016
|
+
async function settleNavigation(page, budgetMs = NAVIGATION_SETTLE_BUDGET_MS) {
|
|
1017
|
+
let lastNavigatedAt = Date.now();
|
|
1018
|
+
const onNavigated = (frame) => {
|
|
1019
|
+
if (frame === page.mainFrame()) lastNavigatedAt = Date.now();
|
|
1020
|
+
};
|
|
1021
|
+
page.on("framenavigated", onNavigated);
|
|
1022
|
+
try {
|
|
1023
|
+
const deadline = Date.now() + budgetMs;
|
|
1024
|
+
while (Date.now() < deadline && Date.now() - lastNavigatedAt < NAVIGATION_QUIET_MS) {
|
|
1025
|
+
await page.waitForTimeout(250);
|
|
1026
|
+
}
|
|
1027
|
+
} finally {
|
|
1028
|
+
page.off("framenavigated", onNavigated);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
async function acrossNavigation(page, run) {
|
|
1032
|
+
try {
|
|
1033
|
+
return await run();
|
|
1034
|
+
} catch (error) {
|
|
1035
|
+
if (!isNavigationTeardown(error)) throw error;
|
|
1036
|
+
await settleNavigation(page);
|
|
1037
|
+
return await run();
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
async function settleConsent(page) {
|
|
1041
|
+
await dismissConsent(page, 4e3);
|
|
1042
|
+
await page.mouse.wheel(0, 400).catch(ignore);
|
|
1043
|
+
await page.waitForTimeout(1500);
|
|
1044
|
+
await dismissConsent(page, 2e3);
|
|
1045
|
+
await page.evaluate(() => window.scrollTo(0, 0)).catch(ignore);
|
|
1046
|
+
}
|
|
1047
|
+
async function dismissConsent(page, waitForBannerMs) {
|
|
1048
|
+
await page.locator(CONSENT_SELECTORS.join(", ")).first().waitFor({ state: "attached", timeout: waitForBannerMs }).catch(ignore);
|
|
1049
|
+
for (const selector of CONSENT_SELECTORS) {
|
|
1050
|
+
const found = page.locator(selector).first();
|
|
1051
|
+
if (!await found.count().catch(() => 0)) continue;
|
|
1052
|
+
await found.click({ timeout: 2e3, force: true }).catch(ignore);
|
|
1053
|
+
await page.waitForTimeout(400);
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
for (const text of CONSENT_TEXTS) {
|
|
1057
|
+
const button = page.getByRole("button", { name: text, exact: false }).first();
|
|
1058
|
+
if (!await button.count().catch(() => 0)) continue;
|
|
1059
|
+
if (!await button.isVisible().catch(() => false)) continue;
|
|
1060
|
+
await button.click({ timeout: 2e3, force: true }).catch(ignore);
|
|
1061
|
+
await page.waitForTimeout(400);
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
async function scrollThroughPage(page) {
|
|
1066
|
+
await acrossNavigation(
|
|
1067
|
+
page,
|
|
1068
|
+
() => page.evaluate(async () => {
|
|
1069
|
+
const step = 600;
|
|
1070
|
+
const pause = () => new Promise((resolve) => setTimeout(resolve, 250));
|
|
1071
|
+
for (let i = 0; i < 40; i++) {
|
|
1072
|
+
window.scrollBy(0, step);
|
|
1073
|
+
await pause();
|
|
1074
|
+
const reachedBottom = window.scrollY + window.innerHeight >= document.documentElement.scrollHeight - 2;
|
|
1075
|
+
if (reachedBottom) break;
|
|
1076
|
+
}
|
|
1077
|
+
window.scrollTo(0, 0);
|
|
1078
|
+
await pause();
|
|
1079
|
+
})
|
|
1080
|
+
);
|
|
1081
|
+
await page.waitForTimeout(500);
|
|
1082
|
+
}
|
|
1083
|
+
var MAX_HEADER_HEIGHT = 220;
|
|
1084
|
+
function inPageUnpinOverlays(maxHeaderHeight) {
|
|
1085
|
+
window.scrollTo(0, 0);
|
|
1086
|
+
for (const element of Array.from(document.querySelectorAll("*"))) {
|
|
1087
|
+
const position = getComputedStyle(element).position;
|
|
1088
|
+
if (position === "sticky") {
|
|
1089
|
+
element.style.setProperty("position", "static", "important");
|
|
1090
|
+
continue;
|
|
1091
|
+
}
|
|
1092
|
+
if (position !== "fixed") continue;
|
|
1093
|
+
const rect = element.getBoundingClientRect();
|
|
1094
|
+
const isTopAnchoredHeader = rect.top <= 8 && rect.height > 0 && rect.height <= maxHeaderHeight;
|
|
1095
|
+
if (isTopAnchoredHeader) {
|
|
1096
|
+
element.style.setProperty("position", "absolute", "important");
|
|
1097
|
+
element.style.setProperty("bottom", "auto", "important");
|
|
1098
|
+
} else {
|
|
1099
|
+
element.style.setProperty("display", "none", "important");
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
async function unpinOverlays(page) {
|
|
1104
|
+
await acrossNavigation(page, () => page.evaluate(inPageUnpinOverlays, MAX_HEADER_HEIGHT));
|
|
1105
|
+
await page.waitForTimeout(250);
|
|
1106
|
+
}
|
|
1107
|
+
async function freezeMotion(page) {
|
|
1108
|
+
await acrossNavigation(
|
|
1109
|
+
page,
|
|
1110
|
+
() => page.evaluate(() => {
|
|
1111
|
+
const highestTimer = window.setTimeout(() => void 0, 0);
|
|
1112
|
+
for (let id = 1; id <= highestTimer; id++) window.clearInterval(id);
|
|
1113
|
+
const style = document.createElement("style");
|
|
1114
|
+
style.setAttribute("data-baker-freeze", "true");
|
|
1115
|
+
style.textContent = `*, *::before, *::after {
|
|
1116
|
+
animation-play-state: paused !important;
|
|
1117
|
+
animation-delay: 0s !important;
|
|
1118
|
+
transition: none !important;
|
|
1119
|
+
}`;
|
|
1120
|
+
document.head.appendChild(style);
|
|
1121
|
+
for (const video of Array.from(document.querySelectorAll("video"))) {
|
|
1122
|
+
video.pause();
|
|
1123
|
+
}
|
|
1124
|
+
})
|
|
1125
|
+
);
|
|
1126
|
+
await page.waitForTimeout(250);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// src/engine/landing-library/geometry.ts
|
|
1130
|
+
function adaptiveGapThreshold(bands) {
|
|
1131
|
+
const sorted = [...bands].sort((a, b) => a.top - b.top);
|
|
1132
|
+
const gaps = [];
|
|
1133
|
+
for (let i = 0; i < sorted.length - 1; i++) {
|
|
1134
|
+
const current = sorted[i];
|
|
1135
|
+
const next = sorted[i + 1];
|
|
1136
|
+
if (!current || !next) continue;
|
|
1137
|
+
if (next.top > current.bottom) {
|
|
1138
|
+
const gap = next.top - current.bottom;
|
|
1139
|
+
if (gap < 200) gaps.push(gap);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
gaps.sort((a, b) => a - b);
|
|
1143
|
+
const p75 = gaps[Math.floor(gaps.length * 0.75)];
|
|
1144
|
+
if (p75 === void 0) return 15;
|
|
1145
|
+
return Math.max(10, Math.min(50, p75));
|
|
1146
|
+
}
|
|
1147
|
+
function bandsCollide(a, b, margin, maxGap) {
|
|
1148
|
+
const shrunkA = { top: a.top + margin, bottom: a.bottom - margin };
|
|
1149
|
+
const shrunkB = { top: b.top + margin, bottom: b.bottom - margin };
|
|
1150
|
+
const overlaps = shrunkA.top <= shrunkB.bottom && shrunkA.bottom >= shrunkB.top || shrunkB.top <= shrunkA.bottom && shrunkB.bottom >= shrunkA.top;
|
|
1151
|
+
if (overlaps) return true;
|
|
1152
|
+
const gap = Math.min(Math.abs(shrunkA.bottom - shrunkB.top), Math.abs(shrunkB.bottom - shrunkA.top));
|
|
1153
|
+
return gap <= maxGap;
|
|
1154
|
+
}
|
|
1155
|
+
function shouldPromoteToParent(group) {
|
|
1156
|
+
const isRunt = group.childCount < 3 || group.height < 80;
|
|
1157
|
+
return isRunt && group.parentHeight < 1600;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// src/engine/landing-library/segment.ts
|
|
1161
|
+
async function installPageRuntime(page) {
|
|
1162
|
+
await page.addInitScript({
|
|
1163
|
+
content: `
|
|
1164
|
+
window.__name = window.__name || function (target) { return target; };
|
|
1165
|
+
window.__bakerGeom = {
|
|
1166
|
+
adaptiveGapThreshold: ${adaptiveGapThreshold.toString()},
|
|
1167
|
+
bandsCollide: ${bandsCollide.toString()},
|
|
1168
|
+
shouldPromoteToParent: ${shouldPromoteToParent.toString()},
|
|
1169
|
+
};`
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
async function segmentPage(page, options) {
|
|
1173
|
+
return await page.evaluate(inPageSegment, options);
|
|
1174
|
+
}
|
|
1175
|
+
var inPageSegment = (options) => {
|
|
1176
|
+
const geom = window.__bakerGeom;
|
|
1177
|
+
const scrollX = window.scrollX;
|
|
1178
|
+
const scrollY = window.scrollY;
|
|
1179
|
+
const docWidth = Math.max(document.documentElement.scrollWidth, document.body?.scrollWidth ?? 0);
|
|
1180
|
+
const docHeight = Math.max(document.documentElement.scrollHeight, document.body?.scrollHeight ?? 0);
|
|
1181
|
+
const rectOf = (element) => {
|
|
1182
|
+
const r = element.getBoundingClientRect();
|
|
1183
|
+
const top = Math.max(0, Math.round(r.top + scrollY));
|
|
1184
|
+
const left = Math.max(0, Math.round(r.left + scrollX));
|
|
1185
|
+
return {
|
|
1186
|
+
top,
|
|
1187
|
+
left,
|
|
1188
|
+
bottom: Math.min(docHeight, Math.round(r.bottom + scrollY)),
|
|
1189
|
+
right: Math.min(docWidth, Math.round(r.right + scrollX))
|
|
1190
|
+
};
|
|
1191
|
+
};
|
|
1192
|
+
const syntheticRect = (element) => {
|
|
1193
|
+
const children = Array.from(element.children);
|
|
1194
|
+
if (children.length === 0) return null;
|
|
1195
|
+
let top = Number.POSITIVE_INFINITY;
|
|
1196
|
+
let left = Number.POSITIVE_INFINITY;
|
|
1197
|
+
let bottom = Number.NEGATIVE_INFINITY;
|
|
1198
|
+
let right = Number.NEGATIVE_INFINITY;
|
|
1199
|
+
for (const child of children) {
|
|
1200
|
+
const r = rectOf(child);
|
|
1201
|
+
if (r.bottom - r.top <= 0 && r.right - r.left <= 0) continue;
|
|
1202
|
+
top = Math.min(top, r.top);
|
|
1203
|
+
left = Math.min(left, r.left);
|
|
1204
|
+
bottom = Math.max(bottom, r.bottom);
|
|
1205
|
+
right = Math.max(right, r.right);
|
|
1206
|
+
}
|
|
1207
|
+
if (!Number.isFinite(top) || !Number.isFinite(bottom)) return null;
|
|
1208
|
+
return { top, left, bottom, right };
|
|
1209
|
+
};
|
|
1210
|
+
const boxOf = (element) => {
|
|
1211
|
+
const style = getComputedStyle(element);
|
|
1212
|
+
const r = style.display === "contents" ? syntheticRect(element) : rectOf(element);
|
|
1213
|
+
if (!r) return null;
|
|
1214
|
+
return { ...r, height: r.bottom - r.top, width: r.right - r.left };
|
|
1215
|
+
};
|
|
1216
|
+
const hasHiddenAncestor = (element) => {
|
|
1217
|
+
let current = element;
|
|
1218
|
+
while (current && current !== document.documentElement) {
|
|
1219
|
+
const style = getComputedStyle(current);
|
|
1220
|
+
if (style.display === "none" || style.visibility === "hidden" || Number(style.opacity) === 0) return true;
|
|
1221
|
+
current = current.parentElement;
|
|
1222
|
+
}
|
|
1223
|
+
return false;
|
|
1224
|
+
};
|
|
1225
|
+
const isClippedByAncestor = (element, box) => {
|
|
1226
|
+
let parent = element.parentElement;
|
|
1227
|
+
while (parent && parent !== document.documentElement) {
|
|
1228
|
+
const style = getComputedStyle(parent);
|
|
1229
|
+
const clips = style.overflow === "hidden" || style.overflowX === "hidden" || style.overflowY === "hidden" || style.overflow === "clip";
|
|
1230
|
+
if (clips) {
|
|
1231
|
+
const p = rectOf(parent);
|
|
1232
|
+
const intersects = box.left < p.right && box.right > p.left && box.top < p.bottom && box.bottom > p.top;
|
|
1233
|
+
if (!intersects) return true;
|
|
1234
|
+
}
|
|
1235
|
+
parent = parent.parentElement;
|
|
1236
|
+
}
|
|
1237
|
+
return false;
|
|
1238
|
+
};
|
|
1239
|
+
const directText = (element) => {
|
|
1240
|
+
let text = "";
|
|
1241
|
+
for (const node of Array.from(element.childNodes)) {
|
|
1242
|
+
if (node.nodeType === 3) text += node.textContent ?? "";
|
|
1243
|
+
}
|
|
1244
|
+
return text.trim();
|
|
1245
|
+
};
|
|
1246
|
+
const NON_COPY_TAGS = /* @__PURE__ */ new Set(["SCRIPT", "STYLE", "NOSCRIPT", "TEMPLATE"]);
|
|
1247
|
+
const visibleText = (root) => {
|
|
1248
|
+
let text = "";
|
|
1249
|
+
const hiddenCache = /* @__PURE__ */ new Map();
|
|
1250
|
+
const isHidden = (element) => {
|
|
1251
|
+
const cached = hiddenCache.get(element);
|
|
1252
|
+
if (cached !== void 0) return cached;
|
|
1253
|
+
const style = getComputedStyle(element);
|
|
1254
|
+
const hidden = style.display === "none" || style.visibility === "hidden";
|
|
1255
|
+
hiddenCache.set(element, hidden);
|
|
1256
|
+
return hidden;
|
|
1257
|
+
};
|
|
1258
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
|
|
1259
|
+
acceptNode: (node) => {
|
|
1260
|
+
let parent = node.parentElement;
|
|
1261
|
+
while (parent) {
|
|
1262
|
+
if (NON_COPY_TAGS.has(parent.tagName) || isHidden(parent)) return NodeFilter.FILTER_REJECT;
|
|
1263
|
+
if (parent === root) break;
|
|
1264
|
+
parent = parent.parentElement;
|
|
1265
|
+
}
|
|
1266
|
+
return NodeFilter.FILTER_ACCEPT;
|
|
1267
|
+
}
|
|
1268
|
+
});
|
|
1269
|
+
while (walker.nextNode() && text.length < 400) {
|
|
1270
|
+
text += ` ${walker.currentNode.textContent ?? ""}`;
|
|
1271
|
+
}
|
|
1272
|
+
return text.replace(/\s+/g, " ").trim();
|
|
1273
|
+
};
|
|
1274
|
+
const GRAPHIC_TAGS = /* @__PURE__ */ new Set(["img", "svg", "video", "picture", "canvas", "iframe"]);
|
|
1275
|
+
const hasBackgroundImage = (element) => {
|
|
1276
|
+
const bg = getComputedStyle(element).backgroundImage;
|
|
1277
|
+
return Boolean(bg) && bg !== "none" && bg.includes("url(");
|
|
1278
|
+
};
|
|
1279
|
+
const isContentLeaf = (element) => {
|
|
1280
|
+
const tag = element.tagName.toLowerCase();
|
|
1281
|
+
if (GRAPHIC_TAGS.has(tag)) return true;
|
|
1282
|
+
if (directText(element).length > 0) return true;
|
|
1283
|
+
return hasBackgroundImage(element);
|
|
1284
|
+
};
|
|
1285
|
+
const selectorFor = (element) => {
|
|
1286
|
+
const parts = [];
|
|
1287
|
+
let current = element;
|
|
1288
|
+
while (current && current !== document.documentElement) {
|
|
1289
|
+
const tag = current.tagName.toLowerCase();
|
|
1290
|
+
if (tag === "body") {
|
|
1291
|
+
parts.unshift("body");
|
|
1292
|
+
break;
|
|
1293
|
+
}
|
|
1294
|
+
const parent = current.parentElement;
|
|
1295
|
+
if (!parent) {
|
|
1296
|
+
parts.unshift(tag);
|
|
1297
|
+
break;
|
|
1298
|
+
}
|
|
1299
|
+
const sameTag = Array.from(parent.children).filter((c) => c.tagName === current?.tagName);
|
|
1300
|
+
const position = sameTag.indexOf(current) + 1;
|
|
1301
|
+
parts.unshift(sameTag.length > 1 ? `${tag}:nth-of-type(${position})` : tag);
|
|
1302
|
+
current = parent;
|
|
1303
|
+
}
|
|
1304
|
+
return parts.join(" > ");
|
|
1305
|
+
};
|
|
1306
|
+
const leaves = [];
|
|
1307
|
+
const all = document.querySelectorAll("*");
|
|
1308
|
+
const limit = Math.min(all.length, options.maxElements);
|
|
1309
|
+
for (let i = 0; i < limit; i++) {
|
|
1310
|
+
const element = all[i];
|
|
1311
|
+
if (!element) continue;
|
|
1312
|
+
const tag = element.tagName.toLowerCase();
|
|
1313
|
+
if (tag === "script" || tag === "style" || tag === "noscript" || tag === "link" || tag === "head") continue;
|
|
1314
|
+
if (!isContentLeaf(element)) continue;
|
|
1315
|
+
const box = boxOf(element);
|
|
1316
|
+
if (!box || box.height <= 0 || box.width <= 0) continue;
|
|
1317
|
+
if (box.height > options.maxSectionHeight) continue;
|
|
1318
|
+
if (hasHiddenAncestor(element)) continue;
|
|
1319
|
+
if (isClippedByAncestor(element, box)) continue;
|
|
1320
|
+
leaves.push({
|
|
1321
|
+
element,
|
|
1322
|
+
top: box.top,
|
|
1323
|
+
bottom: box.bottom,
|
|
1324
|
+
left: box.left,
|
|
1325
|
+
right: box.right,
|
|
1326
|
+
height: box.height
|
|
1327
|
+
});
|
|
1328
|
+
}
|
|
1329
|
+
if (leaves.length === 0) return [];
|
|
1330
|
+
const gapThreshold = geom.adaptiveGapThreshold(leaves.map((l) => ({ top: l.top, bottom: l.bottom })));
|
|
1331
|
+
const commonAncestor = (elements) => {
|
|
1332
|
+
let ancestor = elements[0] ?? null;
|
|
1333
|
+
while (ancestor && !elements.every((e) => ancestor?.contains(e))) {
|
|
1334
|
+
ancestor = ancestor.parentElement;
|
|
1335
|
+
}
|
|
1336
|
+
return ancestor;
|
|
1337
|
+
};
|
|
1338
|
+
const abandon = (members) => members.map((m) => ({ ...m, sealed: true }));
|
|
1339
|
+
const findCoveringAncestor = (start, bounds) => {
|
|
1340
|
+
let element = start;
|
|
1341
|
+
while (element) {
|
|
1342
|
+
const box = boxOf(element);
|
|
1343
|
+
if (!box) return null;
|
|
1344
|
+
if (box.height > options.maxSectionHeight) return null;
|
|
1345
|
+
const covers = box.top <= bounds.top && box.bottom >= bounds.bottom && box.left <= bounds.left && box.right >= bounds.right;
|
|
1346
|
+
if (covers) return { element, box };
|
|
1347
|
+
if (!element.parentElement || element.parentElement === document.documentElement) return null;
|
|
1348
|
+
element = element.parentElement;
|
|
1349
|
+
}
|
|
1350
|
+
return null;
|
|
1351
|
+
};
|
|
1352
|
+
const mergeBucket = (members) => {
|
|
1353
|
+
const bounds = {
|
|
1354
|
+
top: Math.min(...members.map((m) => m.top)),
|
|
1355
|
+
bottom: Math.max(...members.map((m) => m.bottom)),
|
|
1356
|
+
left: Math.min(...members.map((m) => m.left)),
|
|
1357
|
+
right: Math.max(...members.map((m) => m.right))
|
|
1358
|
+
};
|
|
1359
|
+
const covering = findCoveringAncestor(commonAncestor(members.map((m) => m.root)), bounds);
|
|
1360
|
+
if (!covering) return abandon(members);
|
|
1361
|
+
return [
|
|
1362
|
+
{
|
|
1363
|
+
root: covering.element,
|
|
1364
|
+
top: covering.box.top,
|
|
1365
|
+
bottom: covering.box.bottom,
|
|
1366
|
+
left: covering.box.left,
|
|
1367
|
+
right: covering.box.right,
|
|
1368
|
+
height: covering.box.height,
|
|
1369
|
+
leaves: members.flatMap((m) => m.leaves),
|
|
1370
|
+
sealed: false
|
|
1371
|
+
}
|
|
1372
|
+
];
|
|
1373
|
+
};
|
|
1374
|
+
const clusterOnce = (groups2) => {
|
|
1375
|
+
const buckets = [];
|
|
1376
|
+
for (const group of groups2) {
|
|
1377
|
+
if (group.sealed) {
|
|
1378
|
+
buckets.push([group]);
|
|
1379
|
+
continue;
|
|
1380
|
+
}
|
|
1381
|
+
const target = buckets.find(
|
|
1382
|
+
(bucket) => bucket.some(
|
|
1383
|
+
(member) => !member.sealed && geom.bandsCollide(
|
|
1384
|
+
{ top: member.top, bottom: member.bottom },
|
|
1385
|
+
{ top: group.top, bottom: group.bottom },
|
|
1386
|
+
options.collisionMargin,
|
|
1387
|
+
gapThreshold
|
|
1388
|
+
)
|
|
1389
|
+
)
|
|
1390
|
+
);
|
|
1391
|
+
if (target) target.push(group);
|
|
1392
|
+
else buckets.push([group]);
|
|
1393
|
+
}
|
|
1394
|
+
if (buckets.length === groups2.length) return groups2;
|
|
1395
|
+
return buckets.flatMap((bucket) => bucket.length === 1 ? [bucket[0]] : mergeBucket(bucket));
|
|
1396
|
+
};
|
|
1397
|
+
let groups = leaves.map((leaf) => ({
|
|
1398
|
+
root: leaf.element,
|
|
1399
|
+
top: leaf.top,
|
|
1400
|
+
bottom: leaf.bottom,
|
|
1401
|
+
left: leaf.left,
|
|
1402
|
+
right: leaf.right,
|
|
1403
|
+
height: leaf.height,
|
|
1404
|
+
leaves: [leaf],
|
|
1405
|
+
sealed: false
|
|
1406
|
+
}));
|
|
1407
|
+
for (let pass = 0; pass < 40; pass++) {
|
|
1408
|
+
const next = clusterOnce(groups);
|
|
1409
|
+
if (next.length === groups.length) break;
|
|
1410
|
+
groups = next;
|
|
1411
|
+
}
|
|
1412
|
+
for (let pass = 0; pass < 10; pass++) {
|
|
1413
|
+
let promoted = false;
|
|
1414
|
+
groups = groups.map((group) => {
|
|
1415
|
+
const parent = group.root.parentElement;
|
|
1416
|
+
if (!parent || parent === document.documentElement || parent === document.body) return group;
|
|
1417
|
+
const parentBox = boxOf(parent);
|
|
1418
|
+
if (!parentBox) return group;
|
|
1419
|
+
if (!geom.shouldPromoteToParent({
|
|
1420
|
+
childCount: group.leaves.length,
|
|
1421
|
+
height: group.height,
|
|
1422
|
+
parentHeight: parentBox.height
|
|
1423
|
+
})) {
|
|
1424
|
+
return group;
|
|
1425
|
+
}
|
|
1426
|
+
promoted = true;
|
|
1427
|
+
return {
|
|
1428
|
+
...group,
|
|
1429
|
+
root: parent,
|
|
1430
|
+
top: parentBox.top,
|
|
1431
|
+
bottom: parentBox.bottom,
|
|
1432
|
+
left: parentBox.left,
|
|
1433
|
+
right: parentBox.right,
|
|
1434
|
+
height: parentBox.height
|
|
1435
|
+
};
|
|
1436
|
+
});
|
|
1437
|
+
if (!promoted) break;
|
|
1438
|
+
groups = clusterOnce(groups);
|
|
1439
|
+
}
|
|
1440
|
+
const sameBox = (a, b) => Math.abs(a.top - b.top) <= 4 && Math.abs(a.bottom - b.bottom) <= 4 && Math.abs(a.left - b.left) <= 4 && Math.abs(a.right - b.right) <= 4;
|
|
1441
|
+
const containsBox = (outer, inner) => outer.top - 4 <= inner.top && outer.bottom + 4 >= inner.bottom && outer.left - 4 <= inner.left && outer.right + 4 >= inner.right;
|
|
1442
|
+
const deduped = [];
|
|
1443
|
+
const area = (g) => (g.right - g.left) * g.height;
|
|
1444
|
+
for (const group of groups.slice().sort((a, b) => area(b) - area(a) || b.leaves.length - a.leaves.length)) {
|
|
1445
|
+
const duplicate = deduped.some(
|
|
1446
|
+
(kept) => kept.root === group.root || kept.root.contains(group.root) || sameBox(kept, group) || containsBox(kept, group)
|
|
1447
|
+
);
|
|
1448
|
+
if (!duplicate) deduped.push(group);
|
|
1449
|
+
}
|
|
1450
|
+
return deduped.filter((group) => group.height > 0 && group.right - group.left > 0).sort((a, b) => a.top - b.top).map((group, index) => ({
|
|
1451
|
+
index,
|
|
1452
|
+
selector: selectorFor(group.root),
|
|
1453
|
+
rect: {
|
|
1454
|
+
top: group.top,
|
|
1455
|
+
left: group.left,
|
|
1456
|
+
width: group.right - group.left,
|
|
1457
|
+
height: group.height
|
|
1458
|
+
},
|
|
1459
|
+
leafCount: group.leaves.length,
|
|
1460
|
+
textPreview: visibleText(group.root).slice(0, 200)
|
|
1461
|
+
}));
|
|
1462
|
+
};
|
|
1463
|
+
|
|
1464
|
+
// src/engine/landing-library/motionTake.ts
|
|
1465
|
+
var FRAME_TIMES_MS = [0, 120, 260, 450, 800, 1400];
|
|
1466
|
+
var FRAME_WIDTH = 460;
|
|
1467
|
+
var GRID_COLUMNS = 3;
|
|
1468
|
+
var LABEL_HEIGHT = 22;
|
|
1469
|
+
var FRAME_MARGIN_PX = 16;
|
|
1470
|
+
function clampToViewport(box, viewport) {
|
|
1471
|
+
const left = Math.max(0, Math.min(box.left, viewport.width));
|
|
1472
|
+
const top = Math.max(0, Math.min(box.top, viewport.height));
|
|
1473
|
+
const width = Math.min(box.width - (left - box.left), viewport.width - left);
|
|
1474
|
+
const height = Math.min(box.height - (top - box.top), viewport.height - top);
|
|
1475
|
+
if (width < 1 || height < 1) return null;
|
|
1476
|
+
return { left, top, width, height };
|
|
1477
|
+
}
|
|
1478
|
+
async function captureMotionTake(browser, url, selector, timeoutMs = 45e3) {
|
|
1479
|
+
const { context, page } = await newPage(browser, DESKTOP_VIEWPORT, { motion: true });
|
|
1480
|
+
try {
|
|
1481
|
+
await blockConsentManagers(page);
|
|
1482
|
+
await installPageRuntime(page);
|
|
1483
|
+
await page.goto(url, { waitUntil: "domcontentloaded", timeout: timeoutMs });
|
|
1484
|
+
await settleNavigation(page);
|
|
1485
|
+
await page.waitForLoadState("networkidle", { timeout: 8e3 }).catch(() => void 0);
|
|
1486
|
+
await settleConsent(page);
|
|
1487
|
+
const target = page.locator(selector).first();
|
|
1488
|
+
if (!await target.count().catch(() => 0)) return null;
|
|
1489
|
+
await page.evaluate((sectionSelector) => {
|
|
1490
|
+
const element = document.querySelector(sectionSelector);
|
|
1491
|
+
if (!element) return;
|
|
1492
|
+
const top = element.getBoundingClientRect().top + window.scrollY;
|
|
1493
|
+
window.scrollTo({ top: Math.max(0, top - window.innerHeight - 200), behavior: "instant" });
|
|
1494
|
+
}, selector);
|
|
1495
|
+
await page.waitForTimeout(600);
|
|
1496
|
+
const clip = await aimAtSection(page, selector);
|
|
1497
|
+
if (!clip) return null;
|
|
1498
|
+
await hideFloatingFurniture(page, selector);
|
|
1499
|
+
const frames = [];
|
|
1500
|
+
let previous = 0;
|
|
1501
|
+
for (const time of FRAME_TIMES_MS) {
|
|
1502
|
+
await page.waitForTimeout(Math.max(0, time - previous));
|
|
1503
|
+
previous = time;
|
|
1504
|
+
const shot = await page.screenshot({
|
|
1505
|
+
type: "png",
|
|
1506
|
+
timeout: 1e4,
|
|
1507
|
+
clip: { x: clip.left, y: clip.top, width: clip.width, height: clip.height }
|
|
1508
|
+
}).catch(() => null);
|
|
1509
|
+
if (shot) frames.push(shot);
|
|
1510
|
+
}
|
|
1511
|
+
if (frames.length === 0) return null;
|
|
1512
|
+
return { filmstrip: await composeFilmstrip(frames), frameCount: frames.length };
|
|
1513
|
+
} catch {
|
|
1514
|
+
return null;
|
|
1515
|
+
} finally {
|
|
1516
|
+
await context.close();
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
async function aimAtSection(page, selector) {
|
|
1520
|
+
const box = await page.evaluate(
|
|
1521
|
+
([sectionSelector, margin]) => {
|
|
1522
|
+
const element = document.querySelector(sectionSelector);
|
|
1523
|
+
if (!element) return null;
|
|
1524
|
+
const before = element.getBoundingClientRect();
|
|
1525
|
+
window.scrollTo({ top: Math.max(0, before.top + window.scrollY - margin), behavior: "instant" });
|
|
1526
|
+
const after = element.getBoundingClientRect();
|
|
1527
|
+
return {
|
|
1528
|
+
left: after.left,
|
|
1529
|
+
top: after.top - margin,
|
|
1530
|
+
width: after.width,
|
|
1531
|
+
height: after.height + margin,
|
|
1532
|
+
viewport: { width: window.innerWidth, height: window.innerHeight }
|
|
1533
|
+
};
|
|
1534
|
+
},
|
|
1535
|
+
[selector, FRAME_MARGIN_PX]
|
|
1536
|
+
);
|
|
1537
|
+
if (!box) return null;
|
|
1538
|
+
return clampToViewport(box, box.viewport);
|
|
1539
|
+
}
|
|
1540
|
+
async function hideFloatingFurniture(page, selector) {
|
|
1541
|
+
await page.evaluate((sectionSelector) => {
|
|
1542
|
+
const target = document.querySelector(sectionSelector);
|
|
1543
|
+
if (!target) return;
|
|
1544
|
+
for (const element of Array.from(document.querySelectorAll("*"))) {
|
|
1545
|
+
const position = getComputedStyle(element).position;
|
|
1546
|
+
if (position !== "fixed" && position !== "sticky") continue;
|
|
1547
|
+
if (element.contains(target) || target.contains(element) || element === target) continue;
|
|
1548
|
+
element.style.setProperty("visibility", "hidden", "important");
|
|
1549
|
+
}
|
|
1550
|
+
}, selector);
|
|
1551
|
+
}
|
|
1552
|
+
async function composeFilmstrip(frames) {
|
|
1553
|
+
const scaled = await Promise.all(frames.map((frame) => sharp2(frame).resize({ width: FRAME_WIDTH }).png().toBuffer()));
|
|
1554
|
+
const first = await sharp2(scaled[0]).metadata();
|
|
1555
|
+
const frameHeight = first.height ?? 300;
|
|
1556
|
+
const cellHeight = frameHeight + LABEL_HEIGHT;
|
|
1557
|
+
const rows = Math.ceil(scaled.length / GRID_COLUMNS);
|
|
1558
|
+
const width = FRAME_WIDTH * Math.min(GRID_COLUMNS, scaled.length);
|
|
1559
|
+
const composites = scaled.flatMap((frame, index) => {
|
|
1560
|
+
const column = index % GRID_COLUMNS;
|
|
1561
|
+
const row = Math.floor(index / GRID_COLUMNS);
|
|
1562
|
+
const label = Buffer.from(
|
|
1563
|
+
`<svg width="${FRAME_WIDTH}" height="${LABEL_HEIGHT}">
|
|
1564
|
+
<rect width="100%" height="100%" fill="#111827"/>
|
|
1565
|
+
<text x="8" y="15" font-family="monospace" font-size="12" fill="#f9fafb">+${FRAME_TIMES_MS[index] ?? 0}ms</text>
|
|
1566
|
+
</svg>`
|
|
1567
|
+
);
|
|
1568
|
+
return [
|
|
1569
|
+
{ input: label, left: column * FRAME_WIDTH, top: row * cellHeight },
|
|
1570
|
+
{ input: frame, left: column * FRAME_WIDTH, top: row * cellHeight + LABEL_HEIGHT }
|
|
1571
|
+
];
|
|
1572
|
+
});
|
|
1573
|
+
return await sharp2({
|
|
1574
|
+
create: {
|
|
1575
|
+
width,
|
|
1576
|
+
height: cellHeight * rows,
|
|
1577
|
+
channels: 3,
|
|
1578
|
+
background: { r: 17, g: 24, b: 39 }
|
|
1579
|
+
}
|
|
1580
|
+
}).composite(composites).png().toBuffer();
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
// src/engine/landing-library/renderBundle.ts
|
|
1584
|
+
var SETTLE_ANIMATIONS_CSS = `*, *::before, *::after {
|
|
1585
|
+
animation-play-state: running !important;
|
|
1586
|
+
animation-delay: 0s !important;
|
|
1587
|
+
animation-duration: 1ms !important;
|
|
1588
|
+
animation-iteration-count: 1 !important;
|
|
1589
|
+
animation-fill-mode: forwards !important;
|
|
1590
|
+
transition: none !important;
|
|
1591
|
+
}`;
|
|
1592
|
+
async function renderBundleToPng(browser, html, viewportWidth, options = {}) {
|
|
1593
|
+
const { wholePage = false, timeoutMs = 2e4 } = options;
|
|
1594
|
+
const { context, page } = await newPage(browser, { width: viewportWidth, height: 900 });
|
|
1595
|
+
try {
|
|
1596
|
+
await page.setContent(html, { waitUntil: "load", timeout: timeoutMs });
|
|
1597
|
+
await page.addStyleTag({ content: SETTLE_ANIMATIONS_CSS });
|
|
1598
|
+
await page.evaluate(async () => {
|
|
1599
|
+
await document.fonts.ready;
|
|
1600
|
+
});
|
|
1601
|
+
await page.waitForTimeout(300);
|
|
1602
|
+
if (!wholePage) {
|
|
1603
|
+
for (const selector of [`[${SECTION_ROOT_ATTRIBUTE}]`, "body > *"]) {
|
|
1604
|
+
const target = page.locator(selector).first();
|
|
1605
|
+
if (!await target.count()) continue;
|
|
1606
|
+
const shot = await target.screenshot({ type: "png", timeout: timeoutMs }).catch(() => null);
|
|
1607
|
+
if (shot) return shot;
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
return await page.screenshot({ type: "png", fullPage: true }).catch(() => null);
|
|
1611
|
+
} catch {
|
|
1612
|
+
return null;
|
|
1613
|
+
} finally {
|
|
1614
|
+
await context.close();
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1618
|
+
// src/engine/landing-library/report.ts
|
|
1619
|
+
import { writeFile } from "fs/promises";
|
|
1620
|
+
import path from "path";
|
|
1621
|
+
async function writeCaptureReport(manifest, outDir) {
|
|
1622
|
+
const file = path.join(outDir, "report.html");
|
|
1623
|
+
await writeFile(file, renderReport(manifest));
|
|
1624
|
+
return file;
|
|
1625
|
+
}
|
|
1626
|
+
function escapeHtml2(value) {
|
|
1627
|
+
return value.replace(
|
|
1628
|
+
/[&<>"']/g,
|
|
1629
|
+
(character) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[character] ?? character
|
|
1630
|
+
);
|
|
1631
|
+
}
|
|
1632
|
+
function fidelityTone(fidelity) {
|
|
1633
|
+
if (fidelity === null) return "unknown";
|
|
1634
|
+
if (fidelity >= 0.95) return "good";
|
|
1635
|
+
if (fidelity >= 0.85) return "fair";
|
|
1636
|
+
return "poor";
|
|
1637
|
+
}
|
|
1638
|
+
function medianFidelity(sections) {
|
|
1639
|
+
const scored = sections.map((section) => section.fidelity).filter((value) => value !== null).sort((a, b) => a - b);
|
|
1640
|
+
return scored.length === 0 ? null : scored[Math.floor(scored.length / 2)] ?? null;
|
|
1641
|
+
}
|
|
1642
|
+
function formatFidelity(fidelity) {
|
|
1643
|
+
return fidelity === null ? "\u2014" : fidelity.toFixed(2);
|
|
1644
|
+
}
|
|
1645
|
+
function renderSection(section) {
|
|
1646
|
+
const tone = fidelityTone(section.fidelity);
|
|
1647
|
+
const rendered = section.bundle ? section.bundle.replace(/section\.html$/, "section-rendered.png") : null;
|
|
1648
|
+
const shot = (label, src, note) => {
|
|
1649
|
+
if (!src) return `<figure class="shot empty"><figcaption>${label} \u2014 none</figcaption></figure>`;
|
|
1650
|
+
return `<figure class="shot">
|
|
1651
|
+
<figcaption>${label}${note ? ` <span class="note">${escapeHtml2(note)}</span>` : ""}</figcaption>
|
|
1652
|
+
<a href="${escapeHtml2(src)}" target="_blank" rel="noopener"><img src="${escapeHtml2(src)}" alt="" loading="lazy"></a>
|
|
1653
|
+
</figure>`;
|
|
1654
|
+
};
|
|
1655
|
+
return `<section class="card">
|
|
1656
|
+
<header>
|
|
1657
|
+
<h2><span class="index">${String(section.index).padStart(2, "0")}</span> ${section.rect.width}\xD7${section.rect.height}</h2>
|
|
1658
|
+
<span class="badge ${tone}">fidelity ${formatFidelity(section.fidelity)}</span>
|
|
1659
|
+
${section.fidelityNote ? `<span class="badge warn">${escapeHtml2(section.fidelityNote)}</span>` : ""}
|
|
1660
|
+
${section.motion.hasMotion ? `<span class="badge motion">${escapeHtml2(section.motion.summary)}</span>` : ""}
|
|
1661
|
+
</header>
|
|
1662
|
+
<p class="preview">${escapeHtml2(section.textPreview.slice(0, 220)) || "<em>no text</em>"}</p>
|
|
1663
|
+
<div class="shots">
|
|
1664
|
+
${shot("Live", section.desktopShot)}
|
|
1665
|
+
${shot("Reproduction", rendered, "rendered from the extracted bundle")}
|
|
1666
|
+
${shot("Mobile", section.mobileShot)}
|
|
1667
|
+
</div>
|
|
1668
|
+
${section.motionFilmstrip ? `<div class="filmstrip">${shot("Motion \u2014 six frames, left to right", section.motionFilmstrip)}</div>` : ""}
|
|
1669
|
+
<footer>
|
|
1670
|
+
<code>${escapeHtml2(section.selector)}</code>
|
|
1671
|
+
${section.bundle ? `<a href="${escapeHtml2(section.bundle)}" target="_blank" rel="noopener">open the standalone bundle \u2192</a>` : ""}
|
|
1672
|
+
</footer>
|
|
1673
|
+
</section>`;
|
|
1674
|
+
}
|
|
1675
|
+
function renderReport(manifest) {
|
|
1676
|
+
const median = medianFidelity(manifest.sections);
|
|
1677
|
+
const moving = manifest.sections.filter((section) => section.motionFilmstrip !== null).length;
|
|
1678
|
+
return `<!doctype html>
|
|
1679
|
+
<html lang="en">
|
|
1680
|
+
<head>
|
|
1681
|
+
<meta charset="utf-8">
|
|
1682
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
1683
|
+
<title>Capture report \u2014 ${escapeHtml2(manifest.title || manifest.url)}</title>
|
|
1684
|
+
<style>
|
|
1685
|
+
:root { color-scheme: light dark; --line: #e5e7eb; --muted: #6b7280; --bg: #fafafa; --card: #fff; }
|
|
1686
|
+
@media (prefers-color-scheme: dark) {
|
|
1687
|
+
:root { --line: #27272a; --muted: #a1a1aa; --bg: #09090b; --card: #131316; }
|
|
1688
|
+
}
|
|
1689
|
+
* { box-sizing: border-box; }
|
|
1690
|
+
body { margin: 0; padding: 24px; background: var(--bg);
|
|
1691
|
+
font: 14px/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; }
|
|
1692
|
+
h1 { margin: 0 0 4px; font-size: 20px; }
|
|
1693
|
+
a { color: inherit; }
|
|
1694
|
+
.sub { color: var(--muted); margin: 0 0 20px; }
|
|
1695
|
+
.stats { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 24px; }
|
|
1696
|
+
.stat { border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px; background: var(--card); }
|
|
1697
|
+
.stat b { display: block; font-size: 18px; }
|
|
1698
|
+
.stat span { color: var(--muted); font-size: 12px; }
|
|
1699
|
+
.card { border: 1px solid var(--line); border-radius: 12px; background: var(--card);
|
|
1700
|
+
padding: 16px; margin-bottom: 16px; }
|
|
1701
|
+
.card header { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
|
|
1702
|
+
.card h2 { font-size: 15px; margin: 0; font-weight: 600; }
|
|
1703
|
+
.index { display: inline-block; min-width: 26px; color: var(--muted); }
|
|
1704
|
+
.badge { font-size: 12px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--line); }
|
|
1705
|
+
.badge.good { background: #dcfce7; color: #166534; border-color: #bbf7d0; }
|
|
1706
|
+
.badge.fair { background: #fef3c7; color: #92400e; border-color: #fde68a; }
|
|
1707
|
+
.badge.poor { background: #fee2e2; color: #991b1b; border-color: #fecaca; }
|
|
1708
|
+
.badge.warn { background: #fee2e2; color: #991b1b; border-color: #fecaca; }
|
|
1709
|
+
.badge.motion { background: #ede9fe; color: #5b21b6; border-color: #ddd6fe; }
|
|
1710
|
+
.preview { color: var(--muted); margin: 0 0 12px; font-size: 13px; }
|
|
1711
|
+
.shots { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; align-items: start; }
|
|
1712
|
+
.filmstrip { margin-top: 12px; }
|
|
1713
|
+
figure { margin: 0; }
|
|
1714
|
+
figcaption { font-size: 12px; color: var(--muted); margin-bottom: 4px; }
|
|
1715
|
+
figcaption .note { opacity: .75; }
|
|
1716
|
+
.shot img { width: 100%; height: auto; border: 1px solid var(--line); border-radius: 8px;
|
|
1717
|
+
background: #fff; display: block; }
|
|
1718
|
+
.shot.empty { border: 1px dashed var(--line); border-radius: 8px; padding: 20px; text-align: center; }
|
|
1719
|
+
.card footer { display: flex; justify-content: space-between; gap: 12px; margin-top: 12px;
|
|
1720
|
+
font-size: 12px; color: var(--muted); }
|
|
1721
|
+
code { font: 12px ui-monospace, SFMono-Regular, Menlo, monospace; word-break: break-all; }
|
|
1722
|
+
</style>
|
|
1723
|
+
</head>
|
|
1724
|
+
<body>
|
|
1725
|
+
<h1>${escapeHtml2(manifest.title || "Capture report")}</h1>
|
|
1726
|
+
<p class="sub"><a href="${escapeHtml2(manifest.finalUrl)}" target="_blank" rel="noopener">${escapeHtml2(manifest.finalUrl)}</a> \xB7 captured ${escapeHtml2(manifest.capturedAt)}</p>
|
|
1727
|
+
|
|
1728
|
+
<div class="stats">
|
|
1729
|
+
<div class="stat"><b>${manifest.sections.length}</b><span>sections</span></div>
|
|
1730
|
+
<div class="stat"><b>${formatFidelity(median)}</b><span>median fidelity</span></div>
|
|
1731
|
+
<div class="stat"><b>${formatFidelity(manifest.page.fidelity)}</b><span>whole page</span></div>
|
|
1732
|
+
<div class="stat"><b>${moving}</b><span>filmed moving</span></div>
|
|
1733
|
+
<div class="stat"><b>${manifest.documentHeight}px</b><span>page height</span></div>
|
|
1734
|
+
</div>
|
|
1735
|
+
|
|
1736
|
+
<section class="card">
|
|
1737
|
+
<header>
|
|
1738
|
+
<h2>Whole page</h2>
|
|
1739
|
+
<span class="badge ${fidelityTone(manifest.page.fidelity)}">fidelity ${formatFidelity(manifest.page.fidelity)}</span>
|
|
1740
|
+
</header>
|
|
1741
|
+
<p class="preview">The same extractor rooted at <body> \u2014 one standalone file that should render like the original.</p>
|
|
1742
|
+
<div class="shots">
|
|
1743
|
+
<figure class="shot"><figcaption>Live</figcaption><a href="full-page.png" target="_blank" rel="noopener"><img src="full-page.png" alt="" loading="lazy"></a></figure>
|
|
1744
|
+
${manifest.page.bundle ? `<figure class="shot"><figcaption>Reproduction <span class="note">from page.html</span></figcaption><a href="page-rendered.png" target="_blank" rel="noopener"><img src="page-rendered.png" alt="" loading="lazy"></a></figure>` : `<figure class="shot empty"><figcaption>Reproduction \u2014 none</figcaption></figure>`}
|
|
1745
|
+
</div>
|
|
1746
|
+
</section>
|
|
1747
|
+
|
|
1748
|
+
${manifest.sections.map(renderSection).join("\n")}
|
|
1749
|
+
</body>
|
|
1750
|
+
</html>
|
|
1751
|
+
`;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
// src/engine/landing-library/types.ts
|
|
1755
|
+
var DEFAULT_SEGMENT_OPTIONS = {
|
|
1756
|
+
maxSectionHeight: 2160,
|
|
1757
|
+
collisionMargin: 2,
|
|
1758
|
+
maxElements: 15e3
|
|
1759
|
+
};
|
|
1760
|
+
|
|
1761
|
+
// src/engine/landing-library/run.ts
|
|
1762
|
+
async function reproducePage(args) {
|
|
1763
|
+
const { browser, page, outDir, pageUrl, livePageShot } = args;
|
|
1764
|
+
const built = await buildSectionBundle(page, "body", pageUrl).catch(() => null);
|
|
1765
|
+
if (!built) return { bundle: null, fidelity: null };
|
|
1766
|
+
await writeFile2(path2.join(outDir, "page.html"), built.html);
|
|
1767
|
+
const rendered = await renderBundleToPng(browser, built.html, DESKTOP_VIEWPORT.width, {
|
|
1768
|
+
wholePage: true,
|
|
1769
|
+
timeoutMs: 6e4
|
|
1770
|
+
});
|
|
1771
|
+
if (!rendered || !livePageShot) return { bundle: "page.html", fidelity: null };
|
|
1772
|
+
await writeFile2(path2.join(outDir, "page-rendered.png"), rendered);
|
|
1773
|
+
const { score, note } = await scoreFidelity(livePageShot, rendered);
|
|
1774
|
+
return { bundle: "page.html", fidelity: score, ...note ? { fidelityNote: note } : {} };
|
|
1775
|
+
}
|
|
1776
|
+
async function captureOneSection(args) {
|
|
1777
|
+
const { browser, page, candidate, sectionsDir, outDir, pageUrl, withCode } = args;
|
|
1778
|
+
const dir = path2.join(sectionsDir, String(candidate.index).padStart(2, "0"));
|
|
1779
|
+
await mkdir(dir, { recursive: true });
|
|
1780
|
+
const desktop = await captureSection(page, candidate);
|
|
1781
|
+
if (desktop) await writeFile2(path2.join(dir, "desktop.png"), desktop);
|
|
1782
|
+
const visualHash = desktop ? await perceptualHash(desktop) : null;
|
|
1783
|
+
const motion = await collectMotion(page, candidate.selector);
|
|
1784
|
+
const built = withCode ? await buildSectionBundle(page, candidate.selector, pageUrl) : null;
|
|
1785
|
+
let fidelity = null;
|
|
1786
|
+
let fidelityNote;
|
|
1787
|
+
if (built) {
|
|
1788
|
+
await writeFile2(path2.join(dir, "section.html"), built.html);
|
|
1789
|
+
const rendered = await renderBundleToPng(browser, built.html, DESKTOP_VIEWPORT.width);
|
|
1790
|
+
if (rendered && desktop) {
|
|
1791
|
+
await writeFile2(path2.join(dir, "section-rendered.png"), rendered);
|
|
1792
|
+
const result = await scoreFidelity(desktop, rendered);
|
|
1793
|
+
fidelity = result.score;
|
|
1794
|
+
fidelityNote = result.note;
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
return {
|
|
1798
|
+
...candidate,
|
|
1799
|
+
desktopShot: desktop ? path2.relative(outDir, path2.join(dir, "desktop.png")) : null,
|
|
1800
|
+
mobileShot: null,
|
|
1801
|
+
bundle: built ? path2.relative(outDir, path2.join(dir, "section.html")) : null,
|
|
1802
|
+
fidelity,
|
|
1803
|
+
...fidelityNote ? { fidelityNote } : {},
|
|
1804
|
+
...built ? { cssStats: built.stats } : {},
|
|
1805
|
+
motion,
|
|
1806
|
+
motionFilmstrip: null,
|
|
1807
|
+
visualHash
|
|
1808
|
+
};
|
|
1809
|
+
}
|
|
1810
|
+
async function captureMobileShots(args) {
|
|
1811
|
+
const { browser, sections, sectionsDir, outDir, pageUrl, timeoutMs } = args;
|
|
1812
|
+
const mobile = await newPage(browser, MOBILE_VIEWPORT);
|
|
1813
|
+
try {
|
|
1814
|
+
await blockConsentManagers(mobile.page);
|
|
1815
|
+
await installPageRuntime(mobile.page);
|
|
1816
|
+
await preparePage(mobile.page, pageUrl, timeoutMs);
|
|
1817
|
+
for (const section of sections) {
|
|
1818
|
+
const shot = await captureSectionOnMobile(mobile.page, section);
|
|
1819
|
+
if (!shot) continue;
|
|
1820
|
+
const file = path2.join(sectionsDir, String(section.index).padStart(2, "0"), "mobile.png");
|
|
1821
|
+
await writeFile2(file, shot);
|
|
1822
|
+
section.mobileShot = path2.relative(outDir, file);
|
|
1823
|
+
}
|
|
1824
|
+
} finally {
|
|
1825
|
+
await mobile.context.close();
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
var MOTION_CONCURRENCY = 3;
|
|
1829
|
+
async function captureMotionTakes(args) {
|
|
1830
|
+
const { browser, sections, sectionsDir, outDir, pageUrl, log } = args;
|
|
1831
|
+
const moving = sections.filter((section) => isWorthFilming(section.motion));
|
|
1832
|
+
if (moving.length === 0) return;
|
|
1833
|
+
log(`filming ${moving.length} moving sections`);
|
|
1834
|
+
const filmOne = async (section) => {
|
|
1835
|
+
const take = await captureMotionTake(browser, pageUrl, section.selector).catch(() => null);
|
|
1836
|
+
if (!take) return;
|
|
1837
|
+
const dir = path2.join(sectionsDir, String(section.index).padStart(2, "0"));
|
|
1838
|
+
const file = path2.join(dir, "motion-filmstrip.png");
|
|
1839
|
+
await writeFile2(file, take.filmstrip);
|
|
1840
|
+
section.motionFilmstrip = path2.relative(outDir, file);
|
|
1841
|
+
log(` [${section.index}] ${section.motion.summary}`);
|
|
1842
|
+
};
|
|
1843
|
+
const queue = [...moving];
|
|
1844
|
+
await Promise.all(
|
|
1845
|
+
Array.from({ length: Math.min(MOTION_CONCURRENCY, queue.length) }, async () => {
|
|
1846
|
+
for (let next = queue.shift(); next; next = queue.shift()) {
|
|
1847
|
+
await filmOne(next);
|
|
1848
|
+
}
|
|
1849
|
+
})
|
|
1850
|
+
);
|
|
1851
|
+
}
|
|
1852
|
+
async function openPageVia(route, url, timeoutMs) {
|
|
1853
|
+
const startedAt = Date.now();
|
|
1854
|
+
const browser = await launchBrowser(route);
|
|
1855
|
+
let status = null;
|
|
1856
|
+
try {
|
|
1857
|
+
const { context, page } = await newPage(browser, DESKTOP_VIEWPORT);
|
|
1858
|
+
await blockConsentManagers(page);
|
|
1859
|
+
await installPageRuntime(page);
|
|
1860
|
+
const prepared = await preparePage(page, url, timeoutMs);
|
|
1861
|
+
status = prepared.status;
|
|
1862
|
+
const blocked = detectBlockedPage({
|
|
1863
|
+
status: prepared.status,
|
|
1864
|
+
title: prepared.title,
|
|
1865
|
+
bodyText: prepared.bodyText,
|
|
1866
|
+
html: await page.content().catch(() => "")
|
|
1867
|
+
});
|
|
1868
|
+
if (blocked) throw new BlockedPageError(blocked);
|
|
1869
|
+
return { ok: true, browser, context, page, prepared };
|
|
1870
|
+
} catch (error) {
|
|
1871
|
+
await browser.close().catch(() => void 0);
|
|
1872
|
+
return {
|
|
1873
|
+
ok: false,
|
|
1874
|
+
outcome: {
|
|
1875
|
+
route,
|
|
1876
|
+
failure: classifyCaptureFailure(error),
|
|
1877
|
+
status,
|
|
1878
|
+
netError: netErrorName(error),
|
|
1879
|
+
elapsedMs: Date.now() - startedAt
|
|
1880
|
+
}
|
|
1881
|
+
};
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
async function captureAlternateViews(args) {
|
|
1885
|
+
const { browser, sections, sectionsDir, outDir, pageUrl, timeoutMs, withMobile, withMotion, log } = args;
|
|
1886
|
+
if (withMobile) {
|
|
1887
|
+
log("capturing mobile");
|
|
1888
|
+
await captureMobileShots({ browser, sections, sectionsDir, outDir, pageUrl, timeoutMs });
|
|
1889
|
+
}
|
|
1890
|
+
if (withMotion) {
|
|
1891
|
+
await captureMotionTakes({ browser, sections, sectionsDir, outDir, pageUrl, log });
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
async function reproduceWholePage(args) {
|
|
1895
|
+
const { browser, page, outDir, pageUrl, withCode, log } = args;
|
|
1896
|
+
const fullPage = await page.screenshot({ type: "png", fullPage: true }).catch(() => null);
|
|
1897
|
+
if (fullPage) await writeFile2(path2.join(outDir, "full-page.png"), fullPage);
|
|
1898
|
+
if (!withCode) return { bundle: null, fidelity: null };
|
|
1899
|
+
const reproduction = await reproducePage({ browser, page, outDir, pageUrl, livePageShot: fullPage });
|
|
1900
|
+
log(`page reproduction: ${reproduction.fidelity === null ? "unavailable" : reproduction.fidelity.toFixed(2)}`);
|
|
1901
|
+
return reproduction;
|
|
1902
|
+
}
|
|
1903
|
+
async function captureSections(args) {
|
|
1904
|
+
const { browser, page, sectionsDir, outDir, pageUrl, withCode, log } = args;
|
|
1905
|
+
log("segmenting");
|
|
1906
|
+
const candidates = await segmentPage(page, DEFAULT_SEGMENT_OPTIONS);
|
|
1907
|
+
log(`found ${candidates.length} sections`);
|
|
1908
|
+
const sections = [];
|
|
1909
|
+
for (const candidate of candidates) {
|
|
1910
|
+
const section = await captureOneSection({
|
|
1911
|
+
browser,
|
|
1912
|
+
page,
|
|
1913
|
+
candidate,
|
|
1914
|
+
sectionsDir,
|
|
1915
|
+
outDir,
|
|
1916
|
+
pageUrl,
|
|
1917
|
+
withCode
|
|
1918
|
+
});
|
|
1919
|
+
sections.push(section);
|
|
1920
|
+
log(
|
|
1921
|
+
` [${candidate.index}] ${candidate.rect.width}x${candidate.rect.height}${section.fidelity === null ? "" : ` fidelity=${section.fidelity.toFixed(2)}`} \u2014 ${candidate.textPreview.slice(0, 50)}`
|
|
1922
|
+
);
|
|
1923
|
+
}
|
|
1924
|
+
return sections;
|
|
1925
|
+
}
|
|
1926
|
+
function rungReport(outcome) {
|
|
1927
|
+
return {
|
|
1928
|
+
tier: outcome.route.kind === "proxy" ? outcome.route.tier : "direct",
|
|
1929
|
+
code: outcome.failure.code,
|
|
1930
|
+
status: outcome.status
|
|
1931
|
+
};
|
|
1932
|
+
}
|
|
1933
|
+
async function resolveAmbiguousTimeout(outcome, log) {
|
|
1934
|
+
if (!ambiguousProxyTimeout(outcome)) return outcome;
|
|
1935
|
+
const verdict = await preflightProxyRoute(outcome.route).catch(() => null);
|
|
1936
|
+
if (!verdict || verdict.usable) return outcome;
|
|
1937
|
+
log(`that timeout was our own route, not the site (${verdict.problem}) \u2014 carrying on up the ladder`);
|
|
1938
|
+
return asProxyFailure(outcome, verdict.problem);
|
|
1939
|
+
}
|
|
1940
|
+
async function openViaLadder(args) {
|
|
1941
|
+
const { url, routes, timeoutMs, deadline, log } = args;
|
|
1942
|
+
const attempts = [];
|
|
1943
|
+
for (let route = routes[0] ?? { kind: "direct" }; route; ) {
|
|
1944
|
+
log(`loading ${url}${route.kind === "proxy" ? ` (retrying via ${route.tier})` : ""}`);
|
|
1945
|
+
const attempt = await openPageVia(route, url, timeoutMs);
|
|
1946
|
+
if (attempt.ok) {
|
|
1947
|
+
return { opened: attempt, attempts, tier: route.kind === "proxy" ? route.tier : "direct" };
|
|
1948
|
+
}
|
|
1949
|
+
attempts.push(await resolveAmbiguousTimeout(attempt.outcome, log));
|
|
1950
|
+
const decision = nextRoute({
|
|
1951
|
+
routes,
|
|
1952
|
+
attempts,
|
|
1953
|
+
remainingMs: deadline ? deadline - Date.now() : Number.POSITIVE_INFINITY,
|
|
1954
|
+
reserveMs: CAPTURE_RESERVE_MS,
|
|
1955
|
+
navTimeoutMs: timeoutMs
|
|
1956
|
+
});
|
|
1957
|
+
if (!decision.next) {
|
|
1958
|
+
log(`giving up after ${attempts.length} attempt(s) \u2014 ${decision.reason}`);
|
|
1959
|
+
break;
|
|
1960
|
+
}
|
|
1961
|
+
route = decision.next;
|
|
1962
|
+
}
|
|
1963
|
+
throw new CaptureFailureError(reportableFailure(attempts), attempts.map(rungReport));
|
|
1964
|
+
}
|
|
1965
|
+
async function scrapeLanding(options) {
|
|
1966
|
+
const timeoutMs = options.timeoutMs ?? 45e3;
|
|
1967
|
+
const log = options.onProgress ?? (() => void 0);
|
|
1968
|
+
const sectionsDir = path2.join(options.outDir, "sections");
|
|
1969
|
+
const nonPublic = refuseNonPublicUrl(options.url);
|
|
1970
|
+
if (nonPublic) {
|
|
1971
|
+
throw new BlockedPageError({
|
|
1972
|
+
code: "HTTP_ERROR",
|
|
1973
|
+
message: nonPublic === "unparseable" ? "That doesn't look like a web address we can open." : LOCAL_ADDRESS_REFUSAL
|
|
1974
|
+
});
|
|
1975
|
+
}
|
|
1976
|
+
const { opened, attempts, tier } = await openViaLadder({
|
|
1977
|
+
url: options.url,
|
|
1978
|
+
routes: plannedRoutes(options.url, options.proxyCredentials ?? {}),
|
|
1979
|
+
timeoutMs,
|
|
1980
|
+
deadline: options.budgetMs ? Date.now() + options.budgetMs : null,
|
|
1981
|
+
log
|
|
1982
|
+
});
|
|
1983
|
+
const { browser, context, page, prepared } = opened;
|
|
1984
|
+
const escalated = attempts.length > 0;
|
|
1985
|
+
const withMotion = options.motion !== false && !escalated;
|
|
1986
|
+
const renderBrowser = options.code === false ? null : await launchBrowser();
|
|
1987
|
+
try {
|
|
1988
|
+
await mkdir(sectionsDir, { recursive: true });
|
|
1989
|
+
const sections = await captureSections({
|
|
1990
|
+
browser: renderBrowser ?? browser,
|
|
1991
|
+
page,
|
|
1992
|
+
sectionsDir,
|
|
1993
|
+
outDir: options.outDir,
|
|
1994
|
+
pageUrl: prepared.finalUrl,
|
|
1995
|
+
withCode: options.code !== false,
|
|
1996
|
+
log
|
|
1997
|
+
});
|
|
1998
|
+
const reproduction = await reproduceWholePage({
|
|
1999
|
+
browser: renderBrowser ?? browser,
|
|
2000
|
+
page,
|
|
2001
|
+
outDir: options.outDir,
|
|
2002
|
+
pageUrl: prepared.finalUrl,
|
|
2003
|
+
withCode: options.code !== false,
|
|
2004
|
+
log
|
|
2005
|
+
});
|
|
2006
|
+
await context.close();
|
|
2007
|
+
await captureAlternateViews({
|
|
2008
|
+
browser,
|
|
2009
|
+
sections,
|
|
2010
|
+
sectionsDir,
|
|
2011
|
+
outDir: options.outDir,
|
|
2012
|
+
pageUrl: prepared.finalUrl,
|
|
2013
|
+
timeoutMs,
|
|
2014
|
+
withMobile: options.mobile !== false,
|
|
2015
|
+
withMotion,
|
|
2016
|
+
log
|
|
2017
|
+
});
|
|
2018
|
+
const manifest = {
|
|
2019
|
+
url: options.url,
|
|
2020
|
+
finalUrl: prepared.finalUrl,
|
|
2021
|
+
title: prepared.title,
|
|
2022
|
+
documentHeight: prepared.documentHeight,
|
|
2023
|
+
viewport: DESKTOP_VIEWPORT,
|
|
2024
|
+
capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2025
|
+
sections,
|
|
2026
|
+
page: reproduction,
|
|
2027
|
+
security: prepared.security,
|
|
2028
|
+
captureTier: tier
|
|
2029
|
+
};
|
|
2030
|
+
await writeFile2(path2.join(options.outDir, "manifest.json"), `${JSON.stringify(manifest, null, 2)}
|
|
2031
|
+
`);
|
|
2032
|
+
if (options.report !== false) {
|
|
2033
|
+
const reportPath = await writeCaptureReport(manifest, options.outDir);
|
|
2034
|
+
log(`report: ${reportPath}`);
|
|
2035
|
+
}
|
|
2036
|
+
return manifest;
|
|
2037
|
+
} finally {
|
|
2038
|
+
await browser.close();
|
|
2039
|
+
if (renderBrowser) await renderBrowser.close();
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
// src/commands/landing/inspiration/captureOut.ts
|
|
2044
|
+
import { existsSync } from "fs";
|
|
2045
|
+
import path3 from "path";
|
|
2046
|
+
var SCRATCH_DIR = ".baker";
|
|
2047
|
+
function isWithin(parent, target) {
|
|
2048
|
+
const relative = path3.relative(parent, target);
|
|
2049
|
+
return relative === "" || !relative.startsWith("..") && !path3.isAbsolute(relative);
|
|
2050
|
+
}
|
|
2051
|
+
function findRepoRoot(from) {
|
|
2052
|
+
let dir = path3.resolve(from);
|
|
2053
|
+
for (; ; ) {
|
|
2054
|
+
if (existsSync(path3.join(dir, ".git"))) return dir;
|
|
2055
|
+
const parent = path3.dirname(dir);
|
|
2056
|
+
if (parent === dir) return null;
|
|
2057
|
+
dir = parent;
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
function checkCaptureOut(out, options) {
|
|
2061
|
+
const { cwd, repoRoot } = options;
|
|
2062
|
+
const resolved = path3.resolve(cwd, out);
|
|
2063
|
+
if (repoRoot === null || !isWithin(repoRoot, resolved)) return { ok: true };
|
|
2064
|
+
const scratch = path3.join(repoRoot, SCRATCH_DIR);
|
|
2065
|
+
if (isWithin(scratch, resolved)) return { ok: true };
|
|
2066
|
+
const suggestion = path3.posix.join(SCRATCH_DIR, "teardowns", path3.basename(resolved) || "capture");
|
|
2067
|
+
return {
|
|
2068
|
+
ok: false,
|
|
2069
|
+
error: {
|
|
2070
|
+
code: "CAPTURE_OUT_NOT_SCRATCH",
|
|
2071
|
+
message: `A capture has to be written to ${SCRATCH_DIR}/ inside this workspace. It is reference material for this turn, and anywhere else it becomes a permanent part of the client's files.`,
|
|
2072
|
+
fix: {
|
|
2073
|
+
action: "retry_with_changes",
|
|
2074
|
+
explanation: `Re-run with --out ${suggestion}.`
|
|
2075
|
+
},
|
|
2076
|
+
retryable: false
|
|
2077
|
+
}
|
|
2078
|
+
};
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
// src/commands/landing/inspiration/scrape.ts
|
|
2082
|
+
var RETRYABLE_FAILURES = /* @__PURE__ */ new Set([
|
|
2083
|
+
"SITE_TOO_SLOW",
|
|
2084
|
+
"CAPTURE_FAILED",
|
|
2085
|
+
// Ours, not the site's. Filing it as final is exactly how a mistyped password
|
|
2086
|
+
// would blacklist a page that was never actually judged.
|
|
2087
|
+
"PROXY_UNAVAILABLE"
|
|
2088
|
+
]);
|
|
2089
|
+
function captureHints(args) {
|
|
2090
|
+
const { manifest, outDir, report } = args;
|
|
2091
|
+
const shots = manifest.sections.filter((section) => section.desktopShot !== null).length;
|
|
2092
|
+
const anyScored = manifest.sections.some((section) => section.fidelity !== null);
|
|
2093
|
+
const hints = [];
|
|
2094
|
+
if (manifest.security.certificateNotes.length > 0) {
|
|
2095
|
+
hints.push(
|
|
2096
|
+
`Captured anyway, but this site's certificate did not check out: ${manifest.security.certificateNotes.join(" ")} Treat the page as a design reference only \u2014 do not repeat its claims, prices or customer names.`
|
|
2097
|
+
);
|
|
2098
|
+
}
|
|
2099
|
+
if (shots === 0) {
|
|
2100
|
+
hints.push(
|
|
2101
|
+
`No section screenshots were produced, so there is nothing to look at in ${outDir}/sections/. Treat this capture as unusable rather than designing from the counts.`
|
|
2102
|
+
);
|
|
2103
|
+
} else {
|
|
2104
|
+
hints.push(
|
|
2105
|
+
report ? `Read ${outDir}/report.html \u2014 every section side by side${anyScored ? " with its fidelity score" : ""}.` : `Read the section screenshots in ${outDir}/sections/*/desktop.png before you design.`,
|
|
2106
|
+
`${shots} of ${manifest.sections.length} sections captured to ${outDir}/sections/ \u2014 look at them, then decide which the client's page actually needs.`
|
|
2107
|
+
);
|
|
2108
|
+
}
|
|
2109
|
+
hints.push(INSPIRATION_HINTS.structureNotCopy, INSPIRATION_HINTS.adapt);
|
|
2110
|
+
return hints;
|
|
2111
|
+
}
|
|
2112
|
+
registerSchema({
|
|
2113
|
+
command: "landing.inspiration.scrape",
|
|
2114
|
+
description: "Start here when the user points at a specific page and wants it now: capture one landing page into a directory of section screenshots, standalone HTML bundles, a whole-page reproduction and motion filmstrips. Returns when the capture is done, unlike `add`. Read the screenshots.",
|
|
2115
|
+
args: {
|
|
2116
|
+
url: { type: "string", description: "Page to capture", required: true },
|
|
2117
|
+
out: { type: "string", description: "Output directory under .baker/", required: true },
|
|
2118
|
+
mobile: { type: "boolean", description: "Phone-viewport pass. `--no-mobile` to skip", required: false },
|
|
2119
|
+
code: {
|
|
2120
|
+
type: "boolean",
|
|
2121
|
+
description: "Standalone HTML+CSS bundles and fidelity scores. `--no-code` to segment and screenshot only",
|
|
2122
|
+
required: false
|
|
2123
|
+
},
|
|
2124
|
+
motion: {
|
|
2125
|
+
type: "boolean",
|
|
2126
|
+
description: "Film sections that move. `--no-motion` to skip \u2014 the single biggest lever on runtime",
|
|
2127
|
+
required: false
|
|
2128
|
+
},
|
|
2129
|
+
report: { type: "boolean", description: "Write report.html. `--no-report` to skip", required: false }
|
|
2130
|
+
}
|
|
2131
|
+
});
|
|
2132
|
+
var scrapeCommand = defineCommand({
|
|
2133
|
+
meta: {
|
|
2134
|
+
name: "scrape",
|
|
2135
|
+
description: "Capture a landing page to a directory, now. Example: baker landing inspiration scrape https://linear.app --out .baker/inspiration/linear.app"
|
|
2136
|
+
},
|
|
2137
|
+
args: {
|
|
2138
|
+
url: { type: "positional", description: "Page to capture", required: true },
|
|
2139
|
+
out: { type: "string", description: "Output directory, under .baker/", required: true },
|
|
2140
|
+
mobile: {
|
|
2141
|
+
type: "boolean",
|
|
2142
|
+
description: "Phone-viewport pass (--no-mobile to skip)",
|
|
2143
|
+
required: false,
|
|
2144
|
+
default: true
|
|
2145
|
+
},
|
|
2146
|
+
code: { type: "boolean", description: "Bundles + fidelity (--no-code to skip)", required: false, default: true },
|
|
2147
|
+
motion: {
|
|
2148
|
+
type: "boolean",
|
|
2149
|
+
description: "Film moving sections (--no-motion to skip)",
|
|
2150
|
+
required: false,
|
|
2151
|
+
default: true
|
|
2152
|
+
},
|
|
2153
|
+
report: { type: "boolean", description: "Write report.html (--no-report to skip)", required: false, default: true }
|
|
2154
|
+
},
|
|
2155
|
+
run: async ({ args }) => {
|
|
2156
|
+
const location2 = checkCaptureOut(args.out, {
|
|
2157
|
+
cwd: process.cwd(),
|
|
2158
|
+
repoRoot: findRepoRoot(process.cwd())
|
|
2159
|
+
});
|
|
2160
|
+
if (!location2.ok) {
|
|
2161
|
+
writeJson({ ok: false, error: location2.error });
|
|
2162
|
+
process.exit(1);
|
|
2163
|
+
}
|
|
2164
|
+
try {
|
|
2165
|
+
const manifest = await scrapeLanding({
|
|
2166
|
+
url: args.url,
|
|
2167
|
+
outDir: args.out,
|
|
2168
|
+
mobile: args.mobile,
|
|
2169
|
+
code: args.code,
|
|
2170
|
+
motion: args.motion,
|
|
2171
|
+
report: args.report,
|
|
2172
|
+
// Both come from the environment, never from a flag — see their docs in
|
|
2173
|
+
// `src/env.ts`. Absent credentials this is the direct route only, which
|
|
2174
|
+
// is exactly the behaviour that shipped before the ladder existed.
|
|
2175
|
+
proxyCredentials: captureProxyCredentials(),
|
|
2176
|
+
budgetMs: captureBudgetMs() ?? void 0,
|
|
2177
|
+
// Progress goes to stderr so stdout stays a clean JSON envelope.
|
|
2178
|
+
onProgress: (message) => process.stderr.write(`${message}
|
|
2179
|
+
`)
|
|
2180
|
+
});
|
|
2181
|
+
const scored = manifest.sections.map((section) => section.fidelity).filter((value) => value !== null).sort((a, b) => a - b);
|
|
2182
|
+
writeJson({
|
|
2183
|
+
ok: true,
|
|
2184
|
+
data: {
|
|
2185
|
+
title: manifest.title,
|
|
2186
|
+
sections: manifest.sections.length,
|
|
2187
|
+
medianFidelity: scored.length > 0 ? scored[Math.floor(scored.length / 2)] : null,
|
|
2188
|
+
pageFidelity: manifest.page.fidelity,
|
|
2189
|
+
out: args.out,
|
|
2190
|
+
report: args.report ? `${args.out}/report.html` : null,
|
|
2191
|
+
// Never omitted, and that is the point: an envelope without it is a
|
|
2192
|
+
// capture that ran a build predating the ladder, which is otherwise
|
|
2193
|
+
// indistinguishable from one that took the direct route and is the
|
|
2194
|
+
// exact silence the E2B template rebuild is easy to forget about.
|
|
2195
|
+
capture_tier: manifest.captureTier,
|
|
2196
|
+
// Compact by default, but never omitted: a capture that could not
|
|
2197
|
+
// verify who served the page is worth less as evidence, and the
|
|
2198
|
+
// reader has to be told without going looking for it.
|
|
2199
|
+
certificate_verified: false,
|
|
2200
|
+
...manifest.security.certificateNotes.length > 0 ? { certificate_notes: manifest.security.certificateNotes } : {}
|
|
2201
|
+
},
|
|
2202
|
+
hints: captureHints({ manifest, outDir: args.out, report: args.report })
|
|
2203
|
+
});
|
|
2204
|
+
} catch (error) {
|
|
2205
|
+
const failure = classifyCaptureFailure(error);
|
|
2206
|
+
process.stderr.write(`[landing.inspiration.scrape] ${failure.code}: ${String(error)}
|
|
2207
|
+
`);
|
|
2208
|
+
writeJson({
|
|
2209
|
+
ok: false,
|
|
2210
|
+
error: {
|
|
2211
|
+
code: failure.code,
|
|
2212
|
+
message: failure.message,
|
|
2213
|
+
// Which addresses were tried and what each was told. One rung means
|
|
2214
|
+
// the failure was final wherever we stood; three mean the page turned
|
|
2215
|
+
// us away from three different places, which is a fact about the page.
|
|
2216
|
+
// **Absent** means this Runtime is running a CLI that predates the
|
|
2217
|
+
// ladder — the one way the rollout fails without anything looking
|
|
2218
|
+
// wrong.
|
|
2219
|
+
...error instanceof CaptureFailureError && error.rungs.length > 0 ? { rungs: error.rungs } : {},
|
|
2220
|
+
// Degrade, don't abort: one unreadable reference is never a reason to
|
|
2221
|
+
// abandon the job it was research for. `retryable` is the decision
|
|
2222
|
+
// the agent would otherwise have to guess at.
|
|
2223
|
+
fix: RETRYABLE_FAILURES.has(failure.code) ? {
|
|
2224
|
+
action: "Retry once with --no-motion, which is roughly half the work.",
|
|
2225
|
+
explanation: "This looks temporary. If the second attempt fails too, carry on with the references you can reach and tell the user this one page was unavailable.",
|
|
2226
|
+
retryable: true
|
|
2227
|
+
} : {
|
|
2228
|
+
action: "Do not retry this page \u2014 work from the references you can reach.",
|
|
2229
|
+
explanation: "This page cannot be read by an automated reader, and running it again will fail the same way. Tell the user this one page was unavailable and continue with the rest.",
|
|
2230
|
+
retryable: false
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
});
|
|
2234
|
+
process.exit(1);
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
});
|
|
2238
|
+
export {
|
|
2239
|
+
scrapeCommand
|
|
2240
|
+
};
|
|
2241
|
+
//# sourceMappingURL=scrape-FDBYU3TU.js.map
|